pax_global_header00006660000000000000000000000064145667654120014532gustar00rootroot0000000000000052 comment=7e05474619f7212df16ebc0e9a294d130366a8af pygopherd-3.0.1/000077500000000000000000000000001456676541200135345ustar00rootroot00000000000000pygopherd-3.0.1/.github/000077500000000000000000000000001456676541200150745ustar00rootroot00000000000000pygopherd-3.0.1/.github/workflows/000077500000000000000000000000001456676541200171315ustar00rootroot00000000000000pygopherd-3.0.1/.github/workflows/test.yml000066400000000000000000000010631456676541200206330ustar00rootroot00000000000000name: Test on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] os: [ubuntu-latest] steps: - name: Check out repository uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Run tests run: python runtests.py -vpygopherd-3.0.1/.gitignore000066400000000000000000000001151456676541200155210ustar00rootroot00000000000000testdata/.cache* *.cache* __pycache__ .idea .DS_Store *.egg-info/ build dist pygopherd-3.0.1/CHANGELOG.md000066400000000000000000000047551456676541200153600ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased ## v3.0.1 (2024-02-25) ### Added - Added support for python 3.10, 3.11. ### Fixed - Fixed not escaping the URL string when generating HTML responses to hURL: requests. ## v3.0.0 (2022-11-25) ### Added - A new handler to support the spartan:// protocol (https://portal.mozz.us/gemini/spartan.mozz.us/). ### Changed - Fixed unhandled OS errors when the server is unable to access a file. - Fixed error in the mailbox handler when a message subject contains invalid bytes. - Changed the HTTP link for "find gopher browsers" to Wikipedia, which contains a more complete and up-to-date list. - Fixed "Numb=" parameter not being respected for real files in .names listings. - Disabled directory caching for the local pygopherd configuration. - Removed the directory heading from the top of gemini:// pages. - Fixed error when serving directories with trailing slashes in gemini and spartan. - Removed the debian/ directory (it will now be handled in Debian itself, not here). - Added an example systemd service file and updated the default pygopherd.conf accordingly. ## v3.0.0b2 (2020-02-12) ### Added - Support for establishing TLS connections by checking the first byte of the request for a TLS handshake. This allows for both plaintext and encrypted communication to be made over the same port. A TLS section has been added to the default pygopherd configuration file. - Several protocols which take advantage of the new TLS connections. - rfc1436.SecureGopherProtocol (gopher + TLS). - gopherp.SecureGopherPlusProtocol (gopher plus + TLS). - http.HTTPSProtocol (http + TLS). - gemini.GeminiProtocol (https://gemini.circumlunar.space/). - Display server version with ``pygopherd --version``. ### Changed - Gracefully handle OS errors when calling ``setpgrp()``. - Refactored the socket server classes and added additional test cases. ## v3.0.0b1 (2020-01-18) ### Added - Support for python 3.7+. - Additional test coverage and type hints. - Published package to PyPI (https://pypi.org/project/pygopherd/). ### Changed - Significant sprucing up of the codebase. - Numerous minor bugs were discovered and fixed. ### Removed - Support for python 2. ## Previous versions See [CHANGELOG.old](CHANGELOG.old) for older versions. pygopherd-3.0.1/CHANGELOG.old000066400000000000000000004522141456676541200155330ustar00rootroot00000000000000commit 7e72d16dddc03f87c224e385531252836caf73ce Author: John Goerzen Date: Thu Apr 10 08:55:27 2008 -0500 Added Homepage and VCS lines M debian/control commit 8d47815ee9c090a402dbc28c17f5073ada561293 Author: John Goerzen Date: Thu Apr 10 08:53:09 2008 -0500 Prepping 2.0.18 M debian/changelog M debian/copyright M pygopherd/version.py commit 94f54dcd30bc5dec43c2403d725dc766b6f8a241 Author: John Goerzen Date: Thu Apr 10 08:52:27 2008 -0500 Now generate ChangeLog from Git M Makefile commit e023605125acc6533aea01cf23a05c6432d6931c Author: John Goerzen Date: Thu Apr 10 00:23:26 2008 -0500 Move #DEBHELPER# section to end of postinst so that adduser gets run first. Fixes a bug introduced in 2.0.17. Closes: #475247. M debian/postinst commit 5697f2243c1bbdbeb10a6c09e690d30fe00f3cda Author: John Goerzen Date: Thu Apr 10 00:20:48 2008 -0500 Removed weird stuff from source tree D _darcs/current/COPYING D _darcs/current/ChangeLog D _darcs/current/Makefile D _darcs/current/README D _darcs/current/README.windows D _darcs/current/TODO D _darcs/current/bin/pygopherd D _darcs/current/conf/mime.types D _darcs/current/conf/pygopherd.conf D _darcs/current/debian/changelog D _darcs/current/debian/conffiles D _darcs/current/debian/control D _darcs/current/debian/copyright D _darcs/current/debian/dirs D _darcs/current/debian/docs D _darcs/current/debian/ex.package.doc-base D _darcs/current/debian/examples D _darcs/current/debian/init.d D _darcs/current/debian/postinst D _darcs/current/debian/postrm D _darcs/current/debian/pycompat D _darcs/current/debian/pygfarm.README.Debian D _darcs/current/debian/pygfarm.dirs D _darcs/current/debian/rules D _darcs/current/doc/book.sgml D _darcs/current/doc/manpage.sgml D _darcs/current/doc/pygopherd.8 D _darcs/current/doc/pygopherd.html D _darcs/current/doc/pygopherd.pdf D _darcs/current/doc/pygopherd.ps D _darcs/current/doc/pygopherd.sgml D _darcs/current/doc/pygopherd.txt D _darcs/current/doc/quickstart.sgml D _darcs/current/doc/standards/Gopher+.txt D _darcs/current/doc/standards/gophermap.txt D _darcs/current/doc/standards/rfc1436.txt D _darcs/current/doc/standards/url.txt D _darcs/current/examples/gophermap D _darcs/current/examples/talsample.html.tal D _darcs/current/local.dsl D _darcs/current/printlocal.dsl D _darcs/current/pygfarm/dict.pyg D _darcs/current/pygopherd/GopherExceptions.py D _darcs/current/pygopherd/GopherExceptionsTest.py D _darcs/current/pygopherd/__init__.py D _darcs/current/pygopherd/fileext.py D _darcs/current/pygopherd/fileextTest.py D _darcs/current/pygopherd/gopherentry.py D _darcs/current/pygopherd/gopherentryTest.py D _darcs/current/pygopherd/handlers/HandlerMultiplexer.py D _darcs/current/pygopherd/handlers/UMN.py D _darcs/current/pygopherd/handlers/ZIP.py D _darcs/current/pygopherd/handlers/__init__.py D _darcs/current/pygopherd/handlers/base.py D _darcs/current/pygopherd/handlers/dir.py D _darcs/current/pygopherd/handlers/file.py D _darcs/current/pygopherd/handlers/gophermap.py D _darcs/current/pygopherd/handlers/html.py D _darcs/current/pygopherd/handlers/mbox.py D _darcs/current/pygopherd/handlers/pyg.py D _darcs/current/pygopherd/handlers/scriptexec.py D _darcs/current/pygopherd/handlers/tal.py D _darcs/current/pygopherd/handlers/url.py D _darcs/current/pygopherd/handlers/virtual.py D _darcs/current/pygopherd/initialization.py D _darcs/current/pygopherd/initializationTest.py D _darcs/current/pygopherd/logger.py D _darcs/current/pygopherd/loggerTest.py D _darcs/current/pygopherd/pipe.py D _darcs/current/pygopherd/pipeTest.py D _darcs/current/pygopherd/protocols/ProtocolMultiplexer.py D _darcs/current/pygopherd/protocols/ProtocolMultiplexerTest.py D _darcs/current/pygopherd/protocols/__init__.py D _darcs/current/pygopherd/protocols/base.py D _darcs/current/pygopherd/protocols/baseTest.py D _darcs/current/pygopherd/protocols/enhanced.py D _darcs/current/pygopherd/protocols/gopherp.py D _darcs/current/pygopherd/protocols/http.py D _darcs/current/pygopherd/protocols/rfc1436.py D _darcs/current/pygopherd/protocols/rfc1436Test.py D _darcs/current/pygopherd/protocols/wap.py D _darcs/current/pygopherd/sighandlers.py D _darcs/current/pygopherd/testutil.py D _darcs/current/pygopherd/version.py D _darcs/current/pygopherd/zipfile.py D _darcs/current/runtests.py D _darcs/current/runtestsgui.py D _darcs/current/setup.py D _darcs/current/testdata/.abstract D _darcs/current/testdata/README D _darcs/current/testdata/pygopherd/pipetest.sh D _darcs/current/testdata/pygopherd/pipetestdata D _darcs/current/testdata/symlinktest.zip D _darcs/current/testdata/testarchive.tar D _darcs/current/testdata/testarchive.tar.gz D _darcs/current/testdata/testarchive.tgz D _darcs/current/testdata/testdata.zip D _darcs/current/testdata/testdata2.zip D _darcs/current/testdata/testfile.txt D _darcs/current/testdata/testfile.txt.gz D _darcs/current/testdata/testfile.txt.gz.abstract D _darcs/current/testdata/ziptorture.zip D _darcs/inventories/20050416164836-c2a52-faaa46e043b957fa7c33db1a90c3f43df219aa78.gz D _darcs/inventory D _darcs/patches/20020325202914-a5eff-469b21deb5260890fde51aa8f7a85233ce1e0a2c.gz D _darcs/patches/20020325205511-a5eff-d2458f249f2a1300835074aa6bd597965bc1fb95.gz D _darcs/patches/20020325210811-a5eff-d201e4421abe1803abe746eda719db7567b268da.gz D _darcs/patches/20020325212953-a5eff-95dc54d7be5cb5160a9a54bcb46d9c66d8f4e79f.gz D _darcs/patches/20020325221758-a5eff-180e17ea4e4f6fbd90239fc9bd81fcbc9113ddbd.gz D _darcs/patches/20020325232109-a5eff-c135432007cf15c3dd1518dae92c383dffc4e857.gz D _darcs/patches/20020325232741-a5eff-b61771df7f56e413a0d1dd7109e54d5f57a48dc1.gz D _darcs/patches/20020326022726-a5eff-01f7c7497719d2afafc454fab7c45a8c837d7b9a.gz D _darcs/patches/20020326024707-a5eff-16fec0d96b3f96c53a33e2ba4d36310dc08c2a1b.gz D _darcs/patches/20020326050158-a5eff-1a7123df197f25a05f25c393889f8a831769ed21.gz D _darcs/patches/20020326053202-a5eff-74e09c227715f89a42e1b81688f57ba87be80b36.gz D _darcs/patches/20020326192415-a5eff-0bf3a1d864fe8ff70084c10614eafe255478e3cb.gz D _darcs/patches/20020326200939-a5eff-c713741dbaf918f83611dea3aa4cd010f30bd011.gz D _darcs/patches/20020326202920-a5eff-ecad96bef17db83ecd6695f0fffd19caf4dc98e7.gz D _darcs/patches/20020326203450-a5eff-b1be3ff1de77f0247c2acb04bee21c1bdd74f099.gz D _darcs/patches/20020326210905-a5eff-51463402eac0e91f169ded8ea3257ef99d9eed08.gz D _darcs/patches/20020326211756-a5eff-d2de10a539680344e148d89fa2c77bd46dc79b75.gz D _darcs/patches/20020326212556-a5eff-90d215033625fad3f6550dd94412542f1d0f89b6.gz D _darcs/patches/20020326213422-a5eff-a5b9205dd3ef3d9c5562d69a33f63ac10aca0463.gz D _darcs/patches/20020326214636-a5eff-dec84991cc2d3f025c79cdd91c5bc29184d986a7.gz D _darcs/patches/20020326221231-a5eff-8f6b65cb5dfead50da838d0ac4e349e50eb1c10c.gz D _darcs/patches/20020326221932-a5eff-dcbd08557f5a8a8e8f38d936f5a22de1fe765b11.gz D _darcs/patches/20020326222458-a5eff-4c24bdfb9beb0be7c0cfc5a56ebf3a56ce274c9c.gz D _darcs/patches/20020326224542-a5eff-e39b65a5550447254f554660fd2c7eb83a481091.gz D _darcs/patches/20020326235911-a5eff-f1070972b8ef7cc13410d279308071ecafbc8bff.gz D _darcs/patches/20020327001727-a5eff-62a29c13ecd4b744a0a57046e0b1eaeb9ef299b7.gz D _darcs/patches/20020327003014-a5eff-c403c16b158475f088ab641e71452b4def4c9023.gz D _darcs/patches/20020327005258-a5eff-12a2c875852c01bba497e5d4e102016202e15306.gz D _darcs/patches/20020327012727-a5eff-77d1113b2a9be98b5934b56966ccfe6173bbab7a.gz D _darcs/patches/20020327021001-a5eff-bf7515e1c6938bf2c4e70e03fe27385f55860502.gz D _darcs/patches/20020327021714-a5eff-db912f25f3270d64f5608f8b1835ae51de2bf9be.gz D _darcs/patches/20020327024416-a5eff-c7410d98e4969dc185754391fdc926b753367b72.gz D _darcs/patches/20020327054147-a5eff-268d18315b3a596fa656bde29ef4c04f5211c07c.gz D _darcs/patches/20020327181900-a5eff-be4fda24666184846acfb094437ff6b63475e196.gz D _darcs/patches/20020327191617-a5eff-286e984ed14c5d1bf5638db5332ed91f668c110c.gz D _darcs/patches/20020327212458-a5eff-a23cc6eed1df086b2308481ab6bad6362f594f45.gz D _darcs/patches/20020327214053-a5eff-517521ec150f3729a4cdd87bdc5bf339ab47b6b6.gz D _darcs/patches/20020404204103-a5eff-3b2e93caf3e6351a12605b5ab015949ea69af5da.gz D _darcs/patches/20020404225112-a5eff-f12a228d86b1f3d7014b2d4d4b8ce18586bbeb65.gz D _darcs/patches/20020404231239-a5eff-f630dffa16818eec1f4ff518669e7282e5b12327.gz D _darcs/patches/20020404232956-a5eff-969ee772649fb14c71e67cd0f7d677eb1bc5eaa2.gz D _darcs/patches/20020404233902-a5eff-7ccd50bacaa7007b09a03faf1cdff19e50700e47.gz D _darcs/patches/20020405002757-a5eff-45af4edb9447aba3f6d43ef134e95bdc8ad38f86.gz D _darcs/patches/20020405003737-a5eff-8a2d403efa9f483de21676114bd929616afbbe5b.gz D _darcs/patches/20020405005148-a5eff-548766135b69ddd9a276d6e1312addb448ddd51c.gz D _darcs/patches/20020405012027-a5eff-172bc1f33a515516dec6980f82f847434c4ba3c4.gz D _darcs/patches/20020405013658-a5eff-42796131b4ec90d54900ede52976a12e48b6d5a2.gz D _darcs/patches/20020405014951-a5eff-322191bd68465724c1a03affc342bcc12e74e523.gz D _darcs/patches/20020405015557-a5eff-60f1a192439e7eba117913273f9cafa0862b7d89.gz D _darcs/patches/20020405020522-a5eff-2a36bb811f7c7e35138a3f4dcd99ab807e4bb5b2.gz D _darcs/patches/20020405202733-a5eff-0da872724d34110d0598f665b9d6f89a16b0c69a.gz D _darcs/patches/20020405203239-a5eff-ab70f912dbf4073da928c23f2e69731347b573e7.gz D _darcs/patches/20020405211249-a5eff-f48c67fcf106fd12d08891ac1563434bdde09908.gz D _darcs/patches/20020405215159-a5eff-c57b0f35b90f55cb4932247ab46db5ed390214bf.gz D _darcs/patches/20020405215830-a5eff-fc51a78e1fcfee797a664710c1e6d80a2bb1c7c7.gz D _darcs/patches/20020405224300-a5eff-fb72449173e807a0b77d51142c0bf227e60a490f.gz D _darcs/patches/20020406001352-a5eff-88fe9e25b997740a213924599f58a86be545b441.gz D _darcs/patches/20020406002411-a5eff-6975ebde7182126cb4d1c8c2542923d38850fe1c.gz D _darcs/patches/20020406003906-a5eff-ab9a32f5a69b1af53fe64d89915c046264efe391.gz D _darcs/patches/20020406005130-a5eff-0eb500d5029cdc779b383e46534f478b1471adba.gz D _darcs/patches/20020406010958-a5eff-2be2466b2fd50b91bb8ff005bc7db09850543950.gz D _darcs/patches/20020406015956-a5eff-406ac734fa7db46aa3e547318a5df16dbb674ff9.gz D _darcs/patches/20020406022355-a5eff-2450fffbe97cb812f188698f94534898cbec8a20.gz D _darcs/patches/20020406045550-a5eff-2cf3255fe3170b7d5c176a5075f19cb7c1b26349.gz D _darcs/patches/20020406082526-a5eff-5b9466830c142eddf737eef61bebc83a2c80ff06.gz D _darcs/patches/20020407013106-a5eff-9bddb324cad47698ef8e100a978f842e406647c8.gz D _darcs/patches/20020407020821-a5eff-6578e20bf3b1532d74e20a46a6ab7fb94dd80f49.gz D _darcs/patches/20020409002212-a5eff-dee1d9715754831f03217ca6a2e91cef8eed6448.gz D _darcs/patches/20020409013627-a5eff-094871358e209d420412327ef842fa85b7e17efd.gz D _darcs/patches/20020410004552-a5eff-a2b2da5253ed26e38a5664b7838fb075f2a0c243.gz D _darcs/patches/20020410011855-a5eff-065eeed224b3bccbed1eeb7c1fd5589a30f54ac7.gz D _darcs/patches/20020410014231-a5eff-4e7438c48e4640be33c27a67c722dd0dd6eeed93.gz D _darcs/patches/20020410020948-a5eff-ac66fb95408570d306a6e69cca68a5809a5fabb1.gz D _darcs/patches/20020410022641-a5eff-8e095e7ef65a1404088d4ac977b5009d84e0de50.gz D _darcs/patches/20020410074434-a5eff-7fa62126adc35d5e8a512f694c029135d8b3d318.gz D _darcs/patches/20020410083115-a5eff-b95fbd84f61b0632d0c0fe864eb99e8a17d1100b.gz D _darcs/patches/20020410185714-a5eff-fa47451a29079766703ae1e146d282465369445f.gz D _darcs/patches/20020410191058-a5eff-f8db157a65a91d0ab5f41571372aa02540da7618.gz D _darcs/patches/20020410201316-a5eff-c387879fbc7be8c6dff173477292bab672bd5d87.gz D _darcs/patches/20020410202043-a5eff-88e802d73b423e149360200474f6c0028f3ce8b5.gz D _darcs/patches/20020410202703-a5eff-e67959ed5de56a69b126bde412b83596980a7ec5.gz D _darcs/patches/20020410204153-a5eff-56e47055b4889537f7f2b1e34b3471e5294e8399.gz D _darcs/patches/20020410210715-a5eff-64607913769a8a6f9113ed159814c7a57a337607.gz D _darcs/patches/20020410212739-a5eff-b6a69e3dcb68b05ff347b2a688fba5272581fa17.gz D _darcs/patches/20020410220336-a5eff-2d8790f6b8835722941a08e6d4bed92da36dcc9e.gz D _darcs/patches/20020410221522-a5eff-f21935e6266ff13528d62448ff4b7aeda195fbdf.gz D _darcs/patches/20020410233824-a5eff-6ad551a5f9abf472dc2a2abb54cdf4ae39b1dddf.gz D _darcs/patches/20020411001916-a5eff-b44c1e9573d4955ac328b44f7e0f016cb2445a55.gz D _darcs/patches/20020411002650-a5eff-01e88f9713e63459645fde825e6bb9f439424937.gz D _darcs/patches/20020411004309-a5eff-a69170bfbd7fbd9824670ac534eed34b11763d0b.gz D _darcs/patches/20020411010513-a5eff-930432050ce7b66791da6a3d54d8614142efcdef.gz D _darcs/patches/20020411011316-a5eff-877ebbafd872ce74c2f8aa1d59a6135d6ec8d712.gz D _darcs/patches/20020411012228-a5eff-dd92c87b0d122f40704c654ed8fac6af2ce42774.gz D _darcs/patches/20020411013953-a5eff-b82eb4f0db3dc0191ad7c8a589d0d6221057a596.gz D _darcs/patches/20020411015645-a5eff-ee029e0036d85d2e43429e65d5c9332960ce1cfc.gz D _darcs/patches/20020411020231-a5eff-1b141f77eedf6df96361ad7d15767fa4a73842f8.gz D _darcs/patches/20020411023011-a5eff-272691bd954f9f0d53bb0ea232b2981de0ac1272.gz D _darcs/patches/20020411052339-a5eff-e79c116de04e8317bb683f47cfbddb6736780682.gz D _darcs/patches/20020411052958-a5eff-06b499e5c09da4ea6bb785e97288a523ac2beaef.gz D _darcs/patches/20020411072324-a5eff-794ca8cbcc0bad1c0a5b25dca3754d7e2de0d43a.gz D _darcs/patches/20020411081229-a5eff-f5e496043c13246cd6df405452c4b7602d7c1b5d.gz D _darcs/patches/20020411083144-a5eff-32e014788eee412bccedb14cc4177db4cd090f9e.gz D _darcs/patches/20020411090505-a5eff-6d41bfafd1721e09a4646ef3df2424d9b31baa64.gz D _darcs/patches/20020411190728-a5eff-7903c3c88136ecaea8b1169bdc30eed064513e35.gz D _darcs/patches/20020411194956-a5eff-81538c514c3b7cb035bd9bc7527114c972252c62.gz D _darcs/patches/20020411195806-a5eff-95b390b24eb06fd6b85f94c1436fe19594b84566.gz D _darcs/patches/20020411204714-a5eff-55842016cab41f63d02c203591ece5677f15f976.gz D _darcs/patches/20020411213345-a5eff-96db56de785a284d66fa8fd5d5ece83fcba43e4a.gz D _darcs/patches/20020411214105-a5eff-e71a3784e2dbf2cdebd83b9fd05c41647f600d30.gz D _darcs/patches/20020411224236-a5eff-7a68ee2595c3f8f6002cf44dad91d2c1ab9b6d70.gz D _darcs/patches/20020411230104-a5eff-58048126e4aa9d482717db04a5a15fdc718c18e2.gz D _darcs/patches/20020411232524-a5eff-41dabf1cb3fb0ee664666b4dd4cd7936d93401e9.gz D _darcs/patches/20020412002259-a5eff-4013c763fb694648c82d7b1e34752ecaf2f97eb5.gz D _darcs/patches/20020412003237-a5eff-9eeb2e43f655901c66bc5c1ee829303c18403a6a.gz D _darcs/patches/20020412021659-a5eff-b68c308623977cabe1f8402df825174f5928a94a.gz D _darcs/patches/20020412022421-a5eff-2eda36f8c6d1b6378ad24d9dd47e5f6f1c52a640.gz D _darcs/patches/20020412024140-a5eff-3e9ebf9b49429b0bdf5c3063b67fe9a06977d30f.gz D _darcs/patches/20020412080752-a5eff-827507b8f83a4035eb4f507c70a8fa0faf846577.gz D _darcs/patches/20020412081333-a5eff-b2405669dd2aa13ca43e80414f5982a27c74059c.gz D _darcs/patches/20020412213956-a5eff-0566e2d20798193ac634ba75f165ea5901c091b4.gz D _darcs/patches/20020412214654-a5eff-852f00deabfc8ecd0df9cadbc0a115a64d440163.gz D _darcs/patches/20020413012646-a5eff-9cc7a42a9c4587eddef30b5feb7b6a75b137c2ae.gz D _darcs/patches/20020415083453-a5eff-fab325147afcc81b5350e719597952ae8478ed6e.gz D _darcs/patches/20020415085913-a5eff-0ef54548d42c273ad9013cb5bb8b8bc3cc32f614.gz D _darcs/patches/20020415193722-a5eff-7852b9e89e8be0bf36f150432bb79d6e3620269e.gz D _darcs/patches/20020415202109-a5eff-b2c4b42d4299ca8d9afe2e279cbf219284b83ea4.gz D _darcs/patches/20020415225519-a5eff-08d61f019ab46c74e725eddd3284869ad934c7a4.gz D _darcs/patches/20020416000301-a5eff-ab57df7baa36d26bda00cd719c38c5b0526ffc67.gz D _darcs/patches/20020416000948-a5eff-3121eee68890b812629328a2af9a97e97db02178.gz D _darcs/patches/20020416004453-a5eff-ece4ddcbb05048e6118861d62e119ad6138a4b11.gz D _darcs/patches/20020416005816-a5eff-4d642d716799ca7c6771a7823dbaad5e0e8b6c2a.gz D _darcs/patches/20020416012057-a5eff-19f95f4f30146073fac974f2b19b3b30d1ad8f14.gz D _darcs/patches/20020416013708-a5eff-f57c9844396315102c60aa0c30d8808a7bbce0a2.gz D _darcs/patches/20020416020835-a5eff-be68edf596d8fe9abf773dababee16c1f9772ace.gz D _darcs/patches/20020416052101-a5eff-275519ffb304b63a25dcebe920da7aa270328b6e.gz D _darcs/patches/20020416194520-a5eff-249c263b9ee93d9520c7bd121a75ca0fb1e51dc1.gz D _darcs/patches/20020416200642-a5eff-adbc7e4a59dc53d78cbdebd5dc732734c367d11c.gz D _darcs/patches/20020416201159-a5eff-aadf9c3fbec44c5633a91610f4b4df46a62a6cd6.gz D _darcs/patches/20020416233241-a5eff-447c91a2618e7b826be981052adb09c966feaa37.gz D _darcs/patches/20020416233743-a5eff-2d17b0fe10cfd36fc38ca55dd2255c43efb6de5f.gz D _darcs/patches/20020417192657-a5eff-2802455b9d9573effd6dbdd1f3d3c6906ae43bbf.gz D _darcs/patches/20020418002035-a5eff-fdf051cd4a4679e3e8e909899682e04c93b131a4.gz D _darcs/patches/20020418003125-a5eff-78ca09dad11749c492d0938c081cdc6583d4cf43.gz D _darcs/patches/20020418030811-a5eff-d186e36665a1cc2253a5b437851a0ae0c82f6ee8.gz D _darcs/patches/20020418072229-a5eff-216aa34e9cca278fec294576314fe04aefd87c4e.gz D _darcs/patches/20020418073121-a5eff-1b6bde4c5c785272bbfe2ac3e7d07206dbfb0f96.gz D _darcs/patches/20020418204249-a5eff-d4aca4ff4c9862a4f8c7878f91a6c8e8a738be20.gz D _darcs/patches/20020418205102-a5eff-f0f0b0e0bc65a1f90a08316aa24030ccdc69cc17.gz D _darcs/patches/20020418210020-a5eff-ea1a65db83d736f3d03c3011ffd5ca9a52b006ca.gz D _darcs/patches/20020418211230-a5eff-363faa2cf4650aaa30f89c70e8e687d041036643.gz D _darcs/patches/20020418214952-a5eff-57e8440b773724f73a55b0dc59f4af5dc94e7f7a.gz D _darcs/patches/20020418215733-a5eff-b6bb482db8434a8ffc9694e5b8864b67069c7801.gz D _darcs/patches/20020418221329-a5eff-712a0183e642f6589c61b754748189ee38336e9f.gz D _darcs/patches/20020418222238-a5eff-36364b141208d562e0af0bbab58a8ec1de88e865.gz D _darcs/patches/20020418230131-a5eff-1ce2822fb7838f50cddca9336ea4b5d4b661b036.gz D _darcs/patches/20020419043929-a5eff-014c395bd1ee597453688453e042be6dcf2ec9cc.gz D _darcs/patches/20020426201810-a5eff-257f04b77b8872eb449ef90b4056e6080779d017.gz D _darcs/patches/20020501214547-a5eff-48f6a984bb38e9a88270be8c91fc5c5d6b0642b6.gz D _darcs/patches/20020502201345-a5eff-aea6cfe42605ad39ea12a305e0cc41da119dc9ef.gz D _darcs/patches/20020502202441-a5eff-d440081729785fc9b349bf3058b37574a15227ad.gz D _darcs/patches/20020702210406-a5eff-374d24c5aee0addabd572b373669dd89fe5a3756.gz D _darcs/patches/20020702213402-a5eff-83fadd364ebf39d3843bbd7ac2280bcd54a39d6d.gz D _darcs/patches/20020702234305-a5eff-476a2b383dc18201ab52e5330cc2b1e8a0b6e449.gz D _darcs/patches/20020718002816-a5eff-a107973a643098bf9bba7c07aa13743c5b22f29e.gz D _darcs/patches/20020718003307-a5eff-fd9b8a0ad6e38cf15296327ecb4a82799001b91c.gz D _darcs/patches/20020718010505-a5eff-7d07ac27fe667359df58e87162a68c9db51e8057.gz D _darcs/patches/20020718160550-a5eff-ff78dd172ec1c922855fc044878441410e727f03.gz D _darcs/patches/20020718161420-a5eff-130a9f40dba94a7e5548f9ed958168094cff43e3.gz D _darcs/patches/20020718161513-a5eff-6dbfff7e0fc50dba18a8cb159685d30fc1b5d16b.gz D _darcs/patches/20020718161635-a5eff-6cc31c95b3a61df8507cc0ebc02fbe858811b43c.gz D _darcs/patches/20020718162609-a5eff-b15c52c4d68d5699b728567681e58d0f883adc7a.gz D _darcs/patches/20020722131722-a5eff-6ec3eff44dfa7de990babfd60d800af13675f313.gz D _darcs/patches/20020723130437-a5eff-bbf31fd492c908dfb43e26626093faced9c0aab2.gz D _darcs/patches/20020808042425-a5eff-b0984c61b26974e929964f631b557b64efb9ede3.gz D _darcs/patches/20020808164615-a5eff-3378ed39b317ca98840ae136bc78c3e6c6f4aa69.gz D _darcs/patches/20020808175754-a5eff-a172baf78aaa410e355d5ff6bd182cc1bbd3936b.gz D _darcs/patches/20020808180953-a5eff-4510c9e22527b099ec7796a4093a56cf1ffa7f3d.gz D _darcs/patches/20020808181350-a5eff-9b133b4fbb2976a085efdb2ee8ba03d93e24c741.gz D _darcs/patches/20020808183205-a5eff-d361fea5a57c9b3052db22f6bccdd94f0e432067.gz D _darcs/patches/20020808193257-a5eff-1ee4a438b53f19e0730a6137aeba5ab2e7150713.gz D _darcs/patches/20020808213910-a5eff-a8d28c644cef7d408575a2f31751016a06fb9f26.gz D _darcs/patches/20020808214508-a5eff-f235307a0978c468d840cdc64833544b67ed2b0a.gz D _darcs/patches/20030221211446-a5eff-0d2e7b89cc1038254686dcfe8e92967ac63d10ff.gz D _darcs/patches/20030221211509-a5eff-07881765d7044a110ac464ae4fcba3dadf3fc085.gz D _darcs/patches/20030221230552-a5eff-c836d15002151de0cbab9ebc070007a533069017.gz D _darcs/patches/20030304204627-a5eff-d0903d10b71a042164de95784563a39eebe8cd9a.gz D _darcs/patches/20030305225106-a5eff-df4049b954666ca5b359828204955078cbc90d50.gz D _darcs/patches/20030306040214-a5eff-a6c89071648ffa3d229c61b227fefb1b9bb9d49a.gz D _darcs/patches/20030306040537-a5eff-6f7949b3cf89287ba9c4744de0e7377349811597.gz D _darcs/patches/20030306042519-a5eff-92a3061758e43e16824954cf687ab9f119a06304.gz D _darcs/patches/20030306042631-a5eff-460dc3af3cbf8f7dad0718adc1a5fd1f80308378.gz D _darcs/patches/20030306043414-a5eff-366bfac9d3b55ac57d4a9bb16853f9e9ab4c6b5d.gz D _darcs/patches/20030306055548-a5eff-b0ae7f6ecece45ebe4ac23261fd575f819036f51.gz D _darcs/patches/20030306055621-a5eff-d82dd33142e887cd05a06fbb67c2abe858c0bbaa.gz D _darcs/patches/20030306055843-a5eff-66d1567437a2f3085cf296d3a53037b5f03c9093.gz D _darcs/patches/20030306160414-a5eff-6c928740b3d5d4d108f5c2efa48e309b91086c16.gz D _darcs/patches/20030306164316-a5eff-2128979318056d46975aa58c0952e6bf04623210.gz D _darcs/patches/20030306170801-a5eff-8ba7e3cc86eb6195627bda1153ea750354265420.gz D _darcs/patches/20030306171013-a5eff-04b09ec76fd8c488113af101a680d5fb7503894e.gz D _darcs/patches/20030306200340-a5eff-10436feaf07416ec4f4e3e45dbbf052ef8faa1fa.gz D _darcs/patches/20030306210816-a5eff-90d19a6568ff583ef2fea79c9bafbcc13a736238.gz D _darcs/patches/20030306210959-a5eff-fc885ff8847d06e07c49734be9f46171c4cb2443.gz D _darcs/patches/20030306230304-a5eff-b9205ad7ddd816b3fe83faf334569f7c106127d7.gz D _darcs/patches/20030307013221-a5eff-5d910d6f8c95024777657acc978c1353892f0645.gz D _darcs/patches/20030307014915-a5eff-02458fd7df3fe192742df6a8e4a9029f4614a3b3.gz D _darcs/patches/20030307032511-a5eff-5a9106342f0555e6db52d41d4daecc2af1fc4b5a.gz D _darcs/patches/20030307035413-a5eff-37f15a3f2e64c11f73d24bfe47e89f98e2f01662.gz D _darcs/patches/20030307035442-a5eff-00f480dd4899bf32c81a8cb901355d520e9185ee.gz D _darcs/patches/20030307041336-a5eff-e0efdbc12004db0be19f9611bcb28f0bf2e51ef1.gz D _darcs/patches/20030307044436-a5eff-507cdeff4db0fe522cbc4c58f6e4665b2081dbfb.gz D _darcs/patches/20030307045759-a5eff-fba70f9bc9242322eec457f2f2304375efe48667.gz D _darcs/patches/20030307050511-a5eff-3c01b434da0da39f13ec522a7e72c8496d594f56.gz D _darcs/patches/20030307051240-a5eff-70ab69eee97c3117420a75ac5955da2985221e0a.gz D _darcs/patches/20030307055339-a5eff-b7913f6ded9149d5e7fe20de9f8e1f7590877a15.gz D _darcs/patches/20030307162902-a5eff-a40428bab400c5d8e600b65c2e8fb188cce61d31.gz D _darcs/patches/20030307172316-a5eff-ddc2758392c9d6319625a17e1474b4041794d44a.gz D _darcs/patches/20030307220139-a5eff-ca969df71187113dde3e9a87c21502f5272d656d.gz D _darcs/patches/20030312213307-a5eff-18bba9a0bb4ce6762761ae2187f23f83f5e26392.gz D _darcs/patches/20030312213727-a5eff-604147c028da91352c0d35d3a639160079df6d40.gz D _darcs/patches/20030312222019-a5eff-8b746be6656eca1d5250d15763355373dda61d09.gz D _darcs/patches/20030312225549-a5eff-75e0e2391f38067f047ae20d536fd972fbb23be9.gz D _darcs/patches/20030313002835-a5eff-28cdb7698191ef7b97d57ce8cc7785735bd5f360.gz D _darcs/patches/20030313003248-a5eff-2b91a942a04f7761ba96b88bd9ea7fed7f81faeb.gz D _darcs/patches/20030313005626-a5eff-b40042071be7786ac8fb83bba22bc22fbdd9a9aa.gz D _darcs/patches/20030313010249-a5eff-d1399caf7a5e3dc5f92889a87ef12e6553c0f7ff.gz D _darcs/patches/20030313012001-a5eff-b69bf58734985b49e79c01e92084b23a4b26ce87.gz D _darcs/patches/20030313012033-a5eff-b2f9e77e063c7c7b3e8c83cb6423825fabf2ce8b.gz D _darcs/patches/20030313145854-a5eff-189c9701752f59d33efc5582acee3b5db09eb64f.gz D _darcs/patches/20030313154856-a5eff-add85aabb2539130cbfa075672c090e89576d4fc.gz D _darcs/patches/20030313155247-a5eff-9431d6df041a2724c42c9ab978dd40cd8c848057.gz D _darcs/patches/20030313155311-a5eff-4c2af7d2f62d1e3ff02193bf49ef439022096a9d.gz D _darcs/patches/20030823170149-a5eff-483e1782531b68d4d0fb767ff29fc98ea2693b98.gz D _darcs/patches/20030823181322-a5eff-c10e1e7eef7222b8e8853c5362c9916e6e197a57.gz D _darcs/patches/20030823181737-a5eff-51e2840392e79f038ca0cbdc2959f78a729e0684.gz D _darcs/patches/20030823181823-a5eff-9c9aebefed0050da3944cb8c9a7462a54fc12c13.gz D _darcs/patches/20030823181902-a5eff-404bb4edf6dda6b7d7966a25fcfe0f0d1daa559f.gz D _darcs/patches/20030823182610-a5eff-63dcfb6aaddad0efb4aedb896bf9142acc0fcaeb.gz D _darcs/patches/20030823182650-a5eff-b0889aa78a4f588dd36b27a9c8772f3a68e94d12.gz D _darcs/patches/20030823184929-a5eff-af75a5ede358815bb36b4fb69084ed57eacb5d6a.gz D _darcs/patches/20030823185118-a5eff-f8c5a5a5cff16655837d6c6aecfe1fde25ce5f85.gz D _darcs/patches/20030823185431-a5eff-e39a03f173931cda9985c3c99ba83614a1fe4e3d.gz D _darcs/patches/20030823194113-a5eff-42f0151333bf1af5e2ae2ef78d534b0cec982b8d.gz D _darcs/patches/20030823194312-a5eff-f2afee3713af9a5880f2c868b5972d9a51d6aea2.gz D _darcs/patches/20030823195318-a5eff-6a7cf50a194233e8cc7293e8056b661703179967.gz D _darcs/patches/20030823195650-a5eff-0ceeedf4fd8798af31e87b55f2ec6ca57610765d.gz D _darcs/patches/20030823221319-a5eff-e12699a0a11f0c82970ec759842c2a8f149c7e2f.gz D _darcs/patches/20030823222016-a5eff-beb5c444c9793f6d92672e403e8078fe436516fe.gz D _darcs/patches/20030823222215-a5eff-a0afa8a04804f5a3b1f21ff179cd62569331b1f3.gz D _darcs/patches/20030823222338-a5eff-ec7e41de792ece83aabd13fe3e8912175b41ce25.gz D _darcs/patches/20030823222556-a5eff-096f4ff408108366195109e48793aff642669a6c.gz D _darcs/patches/20030823223440-a5eff-f151c6fcd3d05a7b20477fda6051d731279bd2f6.gz D _darcs/patches/20030823223947-a5eff-8b25bb61eba34b65ee9349a055fddebd9f05ca8e.gz D _darcs/patches/20030824223010-a5eff-d3a2fd3dd07e29ad016ba0e5c859aecd242caa65.gz D _darcs/patches/20030824223416-a5eff-3fa2c4fa4423415c00dfd2d87b55425474ff4af0.gz D _darcs/patches/20030824231720-a5eff-695ff3d338954c46636ca4e99d5beec102f34a5e.gz D _darcs/patches/20030825013833-a5eff-df1709e55b40b975523ad9df172644372ffb2247.gz D _darcs/patches/20030825153158-a5eff-e61917e656b41e72b7d2ffbf2bf0a59d81359652.gz D _darcs/patches/20030825184740-a5eff-fff174dbb0a2ec4942f95d1d03c70cfbc9671310.gz D _darcs/patches/20030825201558-a5eff-7a26b663499c0349a92d50e884e1900de4433423.gz D _darcs/patches/20030825201736-a5eff-6d36a9cf6358ca7a42fe0aa8572e8f2dd738fce7.gz D _darcs/patches/20030825211038-a5eff-05ca5457d8aa667f33acf3d963e39f1d32e8e3c6.gz D _darcs/patches/20030825211452-a5eff-477c31c309f787d124b65470c73b2b4e2e70e7b3.gz D _darcs/patches/20030825211723-a5eff-270d94d7754949fd34aa9c0d6704551082b60371.gz D _darcs/patches/20030825211738-a5eff-7e2e57ca57f9b799b0a84feb03ed8cd75ee0c85d.gz D _darcs/patches/20030825220138-a5eff-570a77a8da4e8eec616514e6d239e82e1be3b280.gz D _darcs/patches/20030825235615-a5eff-a1316387f00ed294afcb8305880568aa2f4ae654.gz D _darcs/patches/20030826014214-a5eff-9bda55c73d42545bdd7bd221330624a2ddf7dd32.gz D _darcs/patches/20030826032952-a5eff-3994986f7625529e6020e7f6459fe06d8777236a.gz D _darcs/patches/20031009161133-a5eff-2aef155954b3bf44adb20c33c1017cb2e6cb5ebf.gz D _darcs/patches/20031009214813-a5eff-ecd9106d0de8ea16195b1f385edacdc9db36383b.gz D _darcs/patches/20031217142030-a5eff-43801f5b608cedc0380f4cb1bf16c24279f2b88e.gz D _darcs/patches/20031217142733-a5eff-96b00afb2de192464493a108379c5ebfcb87eb70.gz D _darcs/patches/20031217144411-a5eff-df8b4ef99665e145b6f0ee1344aca79b81486a26.gz D _darcs/patches/20031217152032-a5eff-8d634550d0e315a803eeeeef2c4b9dbe33bc9126.gz D _darcs/patches/20031217152042-a5eff-ab3e5d849fa64591a809829e55247911bc025d8d.gz D _darcs/patches/20031217172643-a5eff-405a63088b9aa82801df513677c8f7e7b5f6b6f5.gz D _darcs/patches/20031217172906-a5eff-8a0fbe5341ffc660764b57d22e0563dea5605ac0.gz D _darcs/patches/20040827154312-a5eff-cacdbe01b5b47a3a16aadb0c00f024a169f381f9.gz D _darcs/patches/20040830195017-a5eff-9892df0950e8ab70d4eb54f05efdba0b84534582.gz D _darcs/patches/20040830195147-a5eff-ab9eaad868659c9f54654db7d472326d1cd79f0b.gz D _darcs/patches/20050114153553-c2a52-7e2dd54a7331be14f9d2b4a311a0c7eb3fd27ea7.gz D _darcs/patches/20050115212415-c2a52-b2b1af62d6829cc9420ad803bfd252f1ed134153.gz D _darcs/patches/20050115212935-c2a52-c14780d8355ff1cb44937be7e583ea694c31d8cd.gz D _darcs/patches/20050115213152-c2a52-51d99e2c5ffa098a71179ee3ae559ff7e491a471.gz D _darcs/patches/20050219180649-c2a52-d186e639339d83b04203f8a066e24ec21eb89ac6.gz D _darcs/patches/20050219180920-c2a52-d4e17ca6e3077803d442e36a65eb6a1993b5b2bc.gz D _darcs/patches/20050416103354-6793f-6a6e76509681d8556bfbae8015a5df0689aac271.gz D _darcs/patches/20050416154059-c2a52-a0a5feef0ee2dab3e1e3770d804d32ed2eafefc9.gz D _darcs/patches/20050416154132-c2a52-6a0f9f2b060ebb04911e79a6cffdc6320b295090.gz D _darcs/patches/20050416154211-c2a52-16192abc7c016b043a1cacb1dbe3158925cc6ccd.gz D _darcs/patches/20050416164256-c2a52-dc017162179bcc0ec299bf1d33618ddb830f3fd4.gz D _darcs/patches/20050416164809-c2a52-59ac9a6837e24de663ff3a8e44ce3bd5018a64a5.gz D _darcs/patches/20050416164836-c2a52-faaa46e043b957fa7c33db1a90c3f43df219aa78.gz D _darcs/patches/20050913191948-c2a52-1cbd6f03c05dbf487c405494e1f25eb5ee3470e6.gz D _darcs/patches/20050922123724-c2a52-2b6100be48abd345d402473d1fca263177f1e608.gz D _darcs/patches/20050922124716-c2a52-4025c3a1e2c23d1b63ae3abf79c1df5c7f702b3f.gz D _darcs/patches/20050922124809-c2a52-072ef7ecbc14dc5c2732954bbe4040dcb1d8bb3e.gz D _darcs/patches/20050922124819-c2a52-27c76e9af547fbb4876dbeffb9e32fd7119d91c6.gz D _darcs/patches/20050922124952-c2a52-24b58a0d85beda836e3faba9585d822cc36c7eec.gz D _darcs/patches/20050922130235-c2a52-910657f419cac65e7358c9b021aeeba0b4703175.gz D _darcs/patches/20060509154502-c2a52-4570f27e588fa890c6a642f6b2670a5e8b36b853.gz D _darcs/patches/20060509154524-c2a52-76af4b03a81b2f593159130b7406b4b9a79ed94d.gz D _darcs/patches/20060509154643-c2a52-e9c0e0019212038a3d957011da50e3e2654466e5.gz D _darcs/patches/20060911135005-c2a52-82ab81db3e567d758e50a42cb5106e4e729e07a6.gz D _darcs/patches/20060911135017-c2a52-7f665cdb36c7f963d43870aaa9d3d8b17e79ee65.gz D _darcs/patches/20060911135413-c2a52-23bdd6be0421b90c0b7834c6cd1937a1928b48ab.gz D _darcs/patches/20060911135510-c2a52-5469317c0b6e35028b79cf4ef6644a49069a3367.gz D _darcs/patches/20060911135518-c2a52-212ed02e3b6a5376b389ed7520e6451959ab04fd.gz D _darcs/patches/20060911140109-c2a52-7d49457c5f34b22d4dc3c09c0f9860a42f143072.gz D _darcs/patches/20060911140826-c2a52-65e0d9a82dc0ba72ed360eac594599922fc647b0.gz D _darcs/patches/20060911141036-c2a52-2ecda3bfa57b30b7d5b8c9c8bd272ce82c0edf77.gz D _darcs/patches/20060911141137-c2a52-84672717218a955c9ea320d1ad90ed09f9d56a65.gz D _darcs/patches/20060915190102-c2a52-75273e4724ca8c46a4d9334692e4fd32c6c7155a.gz D _darcs/patches/20060915190214-c2a52-92a9c9f45285d44363ff1e7b99de9d253abfba9a.gz D _darcs/patches/20060915190246-c2a52-26dd5e4724f439f1dab6d095ab1cb60a9c7ab05c.gz D _darcs/patches/pending D _darcs/prefs/binaries D _darcs/prefs/boring D _darcs/prefs/defaultrepo D _darcs/prefs/motd D _darcs/prefs/repos D build/scripts-2.4/pygopherd commit 0d02f465202ce3173257441ff2b7fdd6a6e46dbd Author: John Goerzen Date: Thu Apr 10 00:19:41 2008 -0500 Imported pygopherd-2.0.17 Summary: Imported pygopherd-2.0.17 Keywords: Imported pygopherd-2.0.17 into Git repository M debian/changelog M debian/init.d commit 0935e653664ac802236e522799afc24b5425fe92 Author: John Goerzen Date: Thu Apr 10 00:18:45 2008 -0500 Imported Debian version 2.0.17 C100 COPYING _darcs/current/COPYING C100 ChangeLog _darcs/current/ChangeLog C100 Makefile _darcs/current/Makefile C100 README _darcs/current/README C100 README.windows _darcs/current/README.windows C100 TODO _darcs/current/TODO C100 bin/pygopherd _darcs/current/bin/pygopherd C100 conf/mime.types _darcs/current/conf/mime.types C100 conf/pygopherd.conf _darcs/current/conf/pygopherd.conf C100 debian/changelog _darcs/current/debian/changelog C100 debian/conffiles _darcs/current/debian/conffiles C100 debian/control _darcs/current/debian/control C100 debian/copyright _darcs/current/debian/copyright C100 debian/dirs _darcs/current/debian/dirs C100 debian/docs _darcs/current/debian/docs C100 debian/ex.package.doc-base _darcs/current/debian/ex.package.doc-base C100 debian/examples _darcs/current/debian/examples C100 debian/init.d _darcs/current/debian/init.d C100 debian/postinst _darcs/current/debian/postinst C100 debian/postrm _darcs/current/debian/postrm C100 debian/pycompat _darcs/current/debian/pycompat C100 debian/pygfarm.README.Debian _darcs/current/debian/pygfarm.README.Debian C100 debian/pygfarm.dirs _darcs/current/debian/pygfarm.dirs C100 debian/rules _darcs/current/debian/rules C100 doc/book.sgml _darcs/current/doc/book.sgml C100 doc/manpage.sgml _darcs/current/doc/manpage.sgml C100 doc/pygopherd.8 _darcs/current/doc/pygopherd.8 C100 doc/pygopherd.html _darcs/current/doc/pygopherd.html C100 doc/pygopherd.pdf _darcs/current/doc/pygopherd.pdf C100 doc/pygopherd.ps _darcs/current/doc/pygopherd.ps C100 doc/pygopherd.sgml _darcs/current/doc/pygopherd.sgml C100 doc/pygopherd.txt _darcs/current/doc/pygopherd.txt C100 doc/quickstart.sgml _darcs/current/doc/quickstart.sgml C100 doc/standards/Gopher+.txt _darcs/current/doc/standards/Gopher+.txt C100 doc/standards/gophermap.txt _darcs/current/doc/standards/gophermap.txt C100 doc/standards/rfc1436.txt _darcs/current/doc/standards/rfc1436.txt C100 doc/standards/url.txt _darcs/current/doc/standards/url.txt C100 examples/gophermap _darcs/current/examples/gophermap C100 examples/talsample.html.tal _darcs/current/examples/talsample.html.tal C100 local.dsl _darcs/current/local.dsl C100 printlocal.dsl _darcs/current/printlocal.dsl C100 pygfarm/dict.pyg _darcs/current/pygfarm/dict.pyg C100 pygopherd/GopherExceptions.py _darcs/current/pygopherd/GopherExceptions.py C100 pygopherd/GopherExceptionsTest.py _darcs/current/pygopherd/GopherExceptionsTest.py C100 pygopherd/__init__.py _darcs/current/pygopherd/__init__.py C100 pygopherd/fileext.py _darcs/current/pygopherd/fileext.py C100 pygopherd/fileextTest.py _darcs/current/pygopherd/fileextTest.py C100 pygopherd/gopherentry.py _darcs/current/pygopherd/gopherentry.py C100 pygopherd/gopherentryTest.py _darcs/current/pygopherd/gopherentryTest.py C100 pygopherd/handlers/HandlerMultiplexer.py _darcs/current/pygopherd/handlers/HandlerMultiplexer.py C100 pygopherd/handlers/UMN.py _darcs/current/pygopherd/handlers/UMN.py C100 pygopherd/handlers/ZIP.py _darcs/current/pygopherd/handlers/ZIP.py C100 pygopherd/handlers/__init__.py _darcs/current/pygopherd/handlers/__init__.py C100 pygopherd/handlers/base.py _darcs/current/pygopherd/handlers/base.py C100 pygopherd/handlers/dir.py _darcs/current/pygopherd/handlers/dir.py C100 pygopherd/handlers/file.py _darcs/current/pygopherd/handlers/file.py C100 pygopherd/handlers/gophermap.py _darcs/current/pygopherd/handlers/gophermap.py C100 pygopherd/handlers/html.py _darcs/current/pygopherd/handlers/html.py C100 pygopherd/handlers/mbox.py _darcs/current/pygopherd/handlers/mbox.py C100 pygopherd/handlers/pyg.py _darcs/current/pygopherd/handlers/pyg.py C100 pygopherd/handlers/scriptexec.py _darcs/current/pygopherd/handlers/scriptexec.py C100 pygopherd/handlers/tal.py _darcs/current/pygopherd/handlers/tal.py C100 pygopherd/handlers/url.py _darcs/current/pygopherd/handlers/url.py C100 pygopherd/handlers/virtual.py _darcs/current/pygopherd/handlers/virtual.py C100 pygopherd/initialization.py _darcs/current/pygopherd/initialization.py C100 pygopherd/initializationTest.py _darcs/current/pygopherd/initializationTest.py C100 pygopherd/logger.py _darcs/current/pygopherd/logger.py C100 pygopherd/loggerTest.py _darcs/current/pygopherd/loggerTest.py C100 pygopherd/pipe.py _darcs/current/pygopherd/pipe.py C100 pygopherd/pipeTest.py _darcs/current/pygopherd/pipeTest.py C100 pygopherd/protocols/ProtocolMultiplexer.py _darcs/current/pygopherd/protocols/ProtocolMultiplexer.py C100 pygopherd/protocols/ProtocolMultiplexerTest.py _darcs/current/pygopherd/protocols/ProtocolMultiplexerTest.py C100 pygopherd/protocols/__init__.py _darcs/current/pygopherd/protocols/__init__.py C100 pygopherd/protocols/base.py _darcs/current/pygopherd/protocols/base.py C100 pygopherd/protocols/baseTest.py _darcs/current/pygopherd/protocols/baseTest.py C100 pygopherd/protocols/enhanced.py _darcs/current/pygopherd/protocols/enhanced.py C100 pygopherd/protocols/gopherp.py _darcs/current/pygopherd/protocols/gopherp.py C100 pygopherd/protocols/http.py _darcs/current/pygopherd/protocols/http.py C100 pygopherd/protocols/rfc1436.py _darcs/current/pygopherd/protocols/rfc1436.py C100 pygopherd/protocols/rfc1436Test.py _darcs/current/pygopherd/protocols/rfc1436Test.py C100 pygopherd/protocols/wap.py _darcs/current/pygopherd/protocols/wap.py C100 pygopherd/sighandlers.py _darcs/current/pygopherd/sighandlers.py C100 pygopherd/testutil.py _darcs/current/pygopherd/testutil.py C100 pygopherd/version.py _darcs/current/pygopherd/version.py C100 pygopherd/zipfile.py _darcs/current/pygopherd/zipfile.py C100 runtests.py _darcs/current/runtests.py C100 runtestsgui.py _darcs/current/runtestsgui.py C100 setup.py _darcs/current/setup.py C100 testdata/.abstract _darcs/current/testdata/.abstract C100 testdata/README _darcs/current/testdata/README C100 testdata/pygopherd/pipetest.sh _darcs/current/testdata/pygopherd/pipetest.sh C100 testdata/pygopherd/pipetestdata _darcs/current/testdata/pygopherd/pipetestdata C100 testdata/symlinktest.zip _darcs/current/testdata/symlinktest.zip C100 testdata/testarchive.tar _darcs/current/testdata/testarchive.tar C100 testdata/testarchive.tar.gz _darcs/current/testdata/testarchive.tar.gz C100 testdata/testarchive.tgz _darcs/current/testdata/testarchive.tgz C100 testdata/testdata.zip _darcs/current/testdata/testdata.zip C100 testdata/testdata2.zip _darcs/current/testdata/testdata2.zip C100 testdata/testfile.txt _darcs/current/testdata/testfile.txt C100 testdata/testfile.txt.gz _darcs/current/testdata/testfile.txt.gz C100 testdata/testfile.txt.gz.abstract _darcs/current/testdata/testfile.txt.gz.abstract C100 testdata/ziptorture.zip _darcs/current/testdata/ziptorture.zip A _darcs/inventories/20050416164836-c2a52-faaa46e043b957fa7c33db1a90c3f43df219aa78.gz A _darcs/inventory A _darcs/patches/20020325202914-a5eff-469b21deb5260890fde51aa8f7a85233ce1e0a2c.gz A _darcs/patches/20020325205511-a5eff-d2458f249f2a1300835074aa6bd597965bc1fb95.gz A _darcs/patches/20020325210811-a5eff-d201e4421abe1803abe746eda719db7567b268da.gz A _darcs/patches/20020325212953-a5eff-95dc54d7be5cb5160a9a54bcb46d9c66d8f4e79f.gz A _darcs/patches/20020325221758-a5eff-180e17ea4e4f6fbd90239fc9bd81fcbc9113ddbd.gz A _darcs/patches/20020325232109-a5eff-c135432007cf15c3dd1518dae92c383dffc4e857.gz A _darcs/patches/20020325232741-a5eff-b61771df7f56e413a0d1dd7109e54d5f57a48dc1.gz A _darcs/patches/20020326022726-a5eff-01f7c7497719d2afafc454fab7c45a8c837d7b9a.gz A _darcs/patches/20020326024707-a5eff-16fec0d96b3f96c53a33e2ba4d36310dc08c2a1b.gz A _darcs/patches/20020326050158-a5eff-1a7123df197f25a05f25c393889f8a831769ed21.gz A _darcs/patches/20020326053202-a5eff-74e09c227715f89a42e1b81688f57ba87be80b36.gz A _darcs/patches/20020326192415-a5eff-0bf3a1d864fe8ff70084c10614eafe255478e3cb.gz A _darcs/patches/20020326200939-a5eff-c713741dbaf918f83611dea3aa4cd010f30bd011.gz A _darcs/patches/20020326202920-a5eff-ecad96bef17db83ecd6695f0fffd19caf4dc98e7.gz A _darcs/patches/20020326203450-a5eff-b1be3ff1de77f0247c2acb04bee21c1bdd74f099.gz A _darcs/patches/20020326210905-a5eff-51463402eac0e91f169ded8ea3257ef99d9eed08.gz A _darcs/patches/20020326211756-a5eff-d2de10a539680344e148d89fa2c77bd46dc79b75.gz A _darcs/patches/20020326212556-a5eff-90d215033625fad3f6550dd94412542f1d0f89b6.gz A _darcs/patches/20020326213422-a5eff-a5b9205dd3ef3d9c5562d69a33f63ac10aca0463.gz A _darcs/patches/20020326214636-a5eff-dec84991cc2d3f025c79cdd91c5bc29184d986a7.gz A _darcs/patches/20020326221231-a5eff-8f6b65cb5dfead50da838d0ac4e349e50eb1c10c.gz A _darcs/patches/20020326221932-a5eff-dcbd08557f5a8a8e8f38d936f5a22de1fe765b11.gz A _darcs/patches/20020326222458-a5eff-4c24bdfb9beb0be7c0cfc5a56ebf3a56ce274c9c.gz A _darcs/patches/20020326224542-a5eff-e39b65a5550447254f554660fd2c7eb83a481091.gz A _darcs/patches/20020326235911-a5eff-f1070972b8ef7cc13410d279308071ecafbc8bff.gz A _darcs/patches/20020327001727-a5eff-62a29c13ecd4b744a0a57046e0b1eaeb9ef299b7.gz A _darcs/patches/20020327003014-a5eff-c403c16b158475f088ab641e71452b4def4c9023.gz A _darcs/patches/20020327005258-a5eff-12a2c875852c01bba497e5d4e102016202e15306.gz A _darcs/patches/20020327012727-a5eff-77d1113b2a9be98b5934b56966ccfe6173bbab7a.gz A _darcs/patches/20020327021001-a5eff-bf7515e1c6938bf2c4e70e03fe27385f55860502.gz A _darcs/patches/20020327021714-a5eff-db912f25f3270d64f5608f8b1835ae51de2bf9be.gz A _darcs/patches/20020327024416-a5eff-c7410d98e4969dc185754391fdc926b753367b72.gz A _darcs/patches/20020327054147-a5eff-268d18315b3a596fa656bde29ef4c04f5211c07c.gz A _darcs/patches/20020327181900-a5eff-be4fda24666184846acfb094437ff6b63475e196.gz A _darcs/patches/20020327191617-a5eff-286e984ed14c5d1bf5638db5332ed91f668c110c.gz A _darcs/patches/20020327212458-a5eff-a23cc6eed1df086b2308481ab6bad6362f594f45.gz A _darcs/patches/20020327214053-a5eff-517521ec150f3729a4cdd87bdc5bf339ab47b6b6.gz A _darcs/patches/20020404204103-a5eff-3b2e93caf3e6351a12605b5ab015949ea69af5da.gz A _darcs/patches/20020404225112-a5eff-f12a228d86b1f3d7014b2d4d4b8ce18586bbeb65.gz A _darcs/patches/20020404231239-a5eff-f630dffa16818eec1f4ff518669e7282e5b12327.gz A _darcs/patches/20020404232956-a5eff-969ee772649fb14c71e67cd0f7d677eb1bc5eaa2.gz A _darcs/patches/20020404233902-a5eff-7ccd50bacaa7007b09a03faf1cdff19e50700e47.gz A _darcs/patches/20020405002757-a5eff-45af4edb9447aba3f6d43ef134e95bdc8ad38f86.gz A _darcs/patches/20020405003737-a5eff-8a2d403efa9f483de21676114bd929616afbbe5b.gz A _darcs/patches/20020405005148-a5eff-548766135b69ddd9a276d6e1312addb448ddd51c.gz A _darcs/patches/20020405012027-a5eff-172bc1f33a515516dec6980f82f847434c4ba3c4.gz A _darcs/patches/20020405013658-a5eff-42796131b4ec90d54900ede52976a12e48b6d5a2.gz A _darcs/patches/20020405014951-a5eff-322191bd68465724c1a03affc342bcc12e74e523.gz A _darcs/patches/20020405015557-a5eff-60f1a192439e7eba117913273f9cafa0862b7d89.gz A _darcs/patches/20020405020522-a5eff-2a36bb811f7c7e35138a3f4dcd99ab807e4bb5b2.gz A _darcs/patches/20020405202733-a5eff-0da872724d34110d0598f665b9d6f89a16b0c69a.gz A _darcs/patches/20020405203239-a5eff-ab70f912dbf4073da928c23f2e69731347b573e7.gz A _darcs/patches/20020405211249-a5eff-f48c67fcf106fd12d08891ac1563434bdde09908.gz A _darcs/patches/20020405215159-a5eff-c57b0f35b90f55cb4932247ab46db5ed390214bf.gz A _darcs/patches/20020405215830-a5eff-fc51a78e1fcfee797a664710c1e6d80a2bb1c7c7.gz A _darcs/patches/20020405224300-a5eff-fb72449173e807a0b77d51142c0bf227e60a490f.gz A _darcs/patches/20020406001352-a5eff-88fe9e25b997740a213924599f58a86be545b441.gz A _darcs/patches/20020406002411-a5eff-6975ebde7182126cb4d1c8c2542923d38850fe1c.gz A _darcs/patches/20020406003906-a5eff-ab9a32f5a69b1af53fe64d89915c046264efe391.gz A _darcs/patches/20020406005130-a5eff-0eb500d5029cdc779b383e46534f478b1471adba.gz A _darcs/patches/20020406010958-a5eff-2be2466b2fd50b91bb8ff005bc7db09850543950.gz A _darcs/patches/20020406015956-a5eff-406ac734fa7db46aa3e547318a5df16dbb674ff9.gz A _darcs/patches/20020406022355-a5eff-2450fffbe97cb812f188698f94534898cbec8a20.gz A _darcs/patches/20020406045550-a5eff-2cf3255fe3170b7d5c176a5075f19cb7c1b26349.gz A _darcs/patches/20020406082526-a5eff-5b9466830c142eddf737eef61bebc83a2c80ff06.gz A _darcs/patches/20020407013106-a5eff-9bddb324cad47698ef8e100a978f842e406647c8.gz A _darcs/patches/20020407020821-a5eff-6578e20bf3b1532d74e20a46a6ab7fb94dd80f49.gz A _darcs/patches/20020409002212-a5eff-dee1d9715754831f03217ca6a2e91cef8eed6448.gz A _darcs/patches/20020409013627-a5eff-094871358e209d420412327ef842fa85b7e17efd.gz A _darcs/patches/20020410004552-a5eff-a2b2da5253ed26e38a5664b7838fb075f2a0c243.gz A _darcs/patches/20020410011855-a5eff-065eeed224b3bccbed1eeb7c1fd5589a30f54ac7.gz A _darcs/patches/20020410014231-a5eff-4e7438c48e4640be33c27a67c722dd0dd6eeed93.gz A _darcs/patches/20020410020948-a5eff-ac66fb95408570d306a6e69cca68a5809a5fabb1.gz A _darcs/patches/20020410022641-a5eff-8e095e7ef65a1404088d4ac977b5009d84e0de50.gz A _darcs/patches/20020410074434-a5eff-7fa62126adc35d5e8a512f694c029135d8b3d318.gz A _darcs/patches/20020410083115-a5eff-b95fbd84f61b0632d0c0fe864eb99e8a17d1100b.gz A _darcs/patches/20020410185714-a5eff-fa47451a29079766703ae1e146d282465369445f.gz A _darcs/patches/20020410191058-a5eff-f8db157a65a91d0ab5f41571372aa02540da7618.gz A _darcs/patches/20020410201316-a5eff-c387879fbc7be8c6dff173477292bab672bd5d87.gz A _darcs/patches/20020410202043-a5eff-88e802d73b423e149360200474f6c0028f3ce8b5.gz A _darcs/patches/20020410202703-a5eff-e67959ed5de56a69b126bde412b83596980a7ec5.gz A _darcs/patches/20020410204153-a5eff-56e47055b4889537f7f2b1e34b3471e5294e8399.gz A _darcs/patches/20020410210715-a5eff-64607913769a8a6f9113ed159814c7a57a337607.gz A _darcs/patches/20020410212739-a5eff-b6a69e3dcb68b05ff347b2a688fba5272581fa17.gz A _darcs/patches/20020410220336-a5eff-2d8790f6b8835722941a08e6d4bed92da36dcc9e.gz A _darcs/patches/20020410221522-a5eff-f21935e6266ff13528d62448ff4b7aeda195fbdf.gz A _darcs/patches/20020410233824-a5eff-6ad551a5f9abf472dc2a2abb54cdf4ae39b1dddf.gz A _darcs/patches/20020411001916-a5eff-b44c1e9573d4955ac328b44f7e0f016cb2445a55.gz A _darcs/patches/20020411002650-a5eff-01e88f9713e63459645fde825e6bb9f439424937.gz A _darcs/patches/20020411004309-a5eff-a69170bfbd7fbd9824670ac534eed34b11763d0b.gz A _darcs/patches/20020411010513-a5eff-930432050ce7b66791da6a3d54d8614142efcdef.gz A _darcs/patches/20020411011316-a5eff-877ebbafd872ce74c2f8aa1d59a6135d6ec8d712.gz A _darcs/patches/20020411012228-a5eff-dd92c87b0d122f40704c654ed8fac6af2ce42774.gz A _darcs/patches/20020411013953-a5eff-b82eb4f0db3dc0191ad7c8a589d0d6221057a596.gz A _darcs/patches/20020411015645-a5eff-ee029e0036d85d2e43429e65d5c9332960ce1cfc.gz A _darcs/patches/20020411020231-a5eff-1b141f77eedf6df96361ad7d15767fa4a73842f8.gz A _darcs/patches/20020411023011-a5eff-272691bd954f9f0d53bb0ea232b2981de0ac1272.gz A _darcs/patches/20020411052339-a5eff-e79c116de04e8317bb683f47cfbddb6736780682.gz A _darcs/patches/20020411052958-a5eff-06b499e5c09da4ea6bb785e97288a523ac2beaef.gz A _darcs/patches/20020411072324-a5eff-794ca8cbcc0bad1c0a5b25dca3754d7e2de0d43a.gz A _darcs/patches/20020411081229-a5eff-f5e496043c13246cd6df405452c4b7602d7c1b5d.gz A _darcs/patches/20020411083144-a5eff-32e014788eee412bccedb14cc4177db4cd090f9e.gz A _darcs/patches/20020411090505-a5eff-6d41bfafd1721e09a4646ef3df2424d9b31baa64.gz A _darcs/patches/20020411190728-a5eff-7903c3c88136ecaea8b1169bdc30eed064513e35.gz A _darcs/patches/20020411194956-a5eff-81538c514c3b7cb035bd9bc7527114c972252c62.gz A _darcs/patches/20020411195806-a5eff-95b390b24eb06fd6b85f94c1436fe19594b84566.gz A _darcs/patches/20020411204714-a5eff-55842016cab41f63d02c203591ece5677f15f976.gz A _darcs/patches/20020411213345-a5eff-96db56de785a284d66fa8fd5d5ece83fcba43e4a.gz A _darcs/patches/20020411214105-a5eff-e71a3784e2dbf2cdebd83b9fd05c41647f600d30.gz A _darcs/patches/20020411224236-a5eff-7a68ee2595c3f8f6002cf44dad91d2c1ab9b6d70.gz A _darcs/patches/20020411230104-a5eff-58048126e4aa9d482717db04a5a15fdc718c18e2.gz A _darcs/patches/20020411232524-a5eff-41dabf1cb3fb0ee664666b4dd4cd7936d93401e9.gz A _darcs/patches/20020412002259-a5eff-4013c763fb694648c82d7b1e34752ecaf2f97eb5.gz A _darcs/patches/20020412003237-a5eff-9eeb2e43f655901c66bc5c1ee829303c18403a6a.gz A _darcs/patches/20020412021659-a5eff-b68c308623977cabe1f8402df825174f5928a94a.gz A _darcs/patches/20020412022421-a5eff-2eda36f8c6d1b6378ad24d9dd47e5f6f1c52a640.gz A _darcs/patches/20020412024140-a5eff-3e9ebf9b49429b0bdf5c3063b67fe9a06977d30f.gz A _darcs/patches/20020412080752-a5eff-827507b8f83a4035eb4f507c70a8fa0faf846577.gz A _darcs/patches/20020412081333-a5eff-b2405669dd2aa13ca43e80414f5982a27c74059c.gz A _darcs/patches/20020412213956-a5eff-0566e2d20798193ac634ba75f165ea5901c091b4.gz A _darcs/patches/20020412214654-a5eff-852f00deabfc8ecd0df9cadbc0a115a64d440163.gz A _darcs/patches/20020413012646-a5eff-9cc7a42a9c4587eddef30b5feb7b6a75b137c2ae.gz A _darcs/patches/20020415083453-a5eff-fab325147afcc81b5350e719597952ae8478ed6e.gz A _darcs/patches/20020415085913-a5eff-0ef54548d42c273ad9013cb5bb8b8bc3cc32f614.gz A _darcs/patches/20020415193722-a5eff-7852b9e89e8be0bf36f150432bb79d6e3620269e.gz A _darcs/patches/20020415202109-a5eff-b2c4b42d4299ca8d9afe2e279cbf219284b83ea4.gz A _darcs/patches/20020415225519-a5eff-08d61f019ab46c74e725eddd3284869ad934c7a4.gz A _darcs/patches/20020416000301-a5eff-ab57df7baa36d26bda00cd719c38c5b0526ffc67.gz A _darcs/patches/20020416000948-a5eff-3121eee68890b812629328a2af9a97e97db02178.gz A _darcs/patches/20020416004453-a5eff-ece4ddcbb05048e6118861d62e119ad6138a4b11.gz A _darcs/patches/20020416005816-a5eff-4d642d716799ca7c6771a7823dbaad5e0e8b6c2a.gz A _darcs/patches/20020416012057-a5eff-19f95f4f30146073fac974f2b19b3b30d1ad8f14.gz A _darcs/patches/20020416013708-a5eff-f57c9844396315102c60aa0c30d8808a7bbce0a2.gz A _darcs/patches/20020416020835-a5eff-be68edf596d8fe9abf773dababee16c1f9772ace.gz A _darcs/patches/20020416052101-a5eff-275519ffb304b63a25dcebe920da7aa270328b6e.gz A _darcs/patches/20020416194520-a5eff-249c263b9ee93d9520c7bd121a75ca0fb1e51dc1.gz A _darcs/patches/20020416200642-a5eff-adbc7e4a59dc53d78cbdebd5dc732734c367d11c.gz A _darcs/patches/20020416201159-a5eff-aadf9c3fbec44c5633a91610f4b4df46a62a6cd6.gz A _darcs/patches/20020416233241-a5eff-447c91a2618e7b826be981052adb09c966feaa37.gz A _darcs/patches/20020416233743-a5eff-2d17b0fe10cfd36fc38ca55dd2255c43efb6de5f.gz A _darcs/patches/20020417192657-a5eff-2802455b9d9573effd6dbdd1f3d3c6906ae43bbf.gz A _darcs/patches/20020418002035-a5eff-fdf051cd4a4679e3e8e909899682e04c93b131a4.gz A _darcs/patches/20020418003125-a5eff-78ca09dad11749c492d0938c081cdc6583d4cf43.gz A _darcs/patches/20020418030811-a5eff-d186e36665a1cc2253a5b437851a0ae0c82f6ee8.gz A _darcs/patches/20020418072229-a5eff-216aa34e9cca278fec294576314fe04aefd87c4e.gz A _darcs/patches/20020418073121-a5eff-1b6bde4c5c785272bbfe2ac3e7d07206dbfb0f96.gz A _darcs/patches/20020418204249-a5eff-d4aca4ff4c9862a4f8c7878f91a6c8e8a738be20.gz A _darcs/patches/20020418205102-a5eff-f0f0b0e0bc65a1f90a08316aa24030ccdc69cc17.gz A _darcs/patches/20020418210020-a5eff-ea1a65db83d736f3d03c3011ffd5ca9a52b006ca.gz A _darcs/patches/20020418211230-a5eff-363faa2cf4650aaa30f89c70e8e687d041036643.gz A _darcs/patches/20020418214952-a5eff-57e8440b773724f73a55b0dc59f4af5dc94e7f7a.gz A _darcs/patches/20020418215733-a5eff-b6bb482db8434a8ffc9694e5b8864b67069c7801.gz A _darcs/patches/20020418221329-a5eff-712a0183e642f6589c61b754748189ee38336e9f.gz A _darcs/patches/20020418222238-a5eff-36364b141208d562e0af0bbab58a8ec1de88e865.gz A _darcs/patches/20020418230131-a5eff-1ce2822fb7838f50cddca9336ea4b5d4b661b036.gz A _darcs/patches/20020419043929-a5eff-014c395bd1ee597453688453e042be6dcf2ec9cc.gz A _darcs/patches/20020426201810-a5eff-257f04b77b8872eb449ef90b4056e6080779d017.gz A _darcs/patches/20020501214547-a5eff-48f6a984bb38e9a88270be8c91fc5c5d6b0642b6.gz A _darcs/patches/20020502201345-a5eff-aea6cfe42605ad39ea12a305e0cc41da119dc9ef.gz A _darcs/patches/20020502202441-a5eff-d440081729785fc9b349bf3058b37574a15227ad.gz A _darcs/patches/20020702210406-a5eff-374d24c5aee0addabd572b373669dd89fe5a3756.gz A _darcs/patches/20020702213402-a5eff-83fadd364ebf39d3843bbd7ac2280bcd54a39d6d.gz A _darcs/patches/20020702234305-a5eff-476a2b383dc18201ab52e5330cc2b1e8a0b6e449.gz A _darcs/patches/20020718002816-a5eff-a107973a643098bf9bba7c07aa13743c5b22f29e.gz A _darcs/patches/20020718003307-a5eff-fd9b8a0ad6e38cf15296327ecb4a82799001b91c.gz A _darcs/patches/20020718010505-a5eff-7d07ac27fe667359df58e87162a68c9db51e8057.gz A _darcs/patches/20020718160550-a5eff-ff78dd172ec1c922855fc044878441410e727f03.gz A _darcs/patches/20020718161420-a5eff-130a9f40dba94a7e5548f9ed958168094cff43e3.gz A _darcs/patches/20020718161513-a5eff-6dbfff7e0fc50dba18a8cb159685d30fc1b5d16b.gz A _darcs/patches/20020718161635-a5eff-6cc31c95b3a61df8507cc0ebc02fbe858811b43c.gz A _darcs/patches/20020718162609-a5eff-b15c52c4d68d5699b728567681e58d0f883adc7a.gz A _darcs/patches/20020722131722-a5eff-6ec3eff44dfa7de990babfd60d800af13675f313.gz A _darcs/patches/20020723130437-a5eff-bbf31fd492c908dfb43e26626093faced9c0aab2.gz A _darcs/patches/20020808042425-a5eff-b0984c61b26974e929964f631b557b64efb9ede3.gz A _darcs/patches/20020808164615-a5eff-3378ed39b317ca98840ae136bc78c3e6c6f4aa69.gz A _darcs/patches/20020808175754-a5eff-a172baf78aaa410e355d5ff6bd182cc1bbd3936b.gz A _darcs/patches/20020808180953-a5eff-4510c9e22527b099ec7796a4093a56cf1ffa7f3d.gz A _darcs/patches/20020808181350-a5eff-9b133b4fbb2976a085efdb2ee8ba03d93e24c741.gz A _darcs/patches/20020808183205-a5eff-d361fea5a57c9b3052db22f6bccdd94f0e432067.gz A _darcs/patches/20020808193257-a5eff-1ee4a438b53f19e0730a6137aeba5ab2e7150713.gz A _darcs/patches/20020808213910-a5eff-a8d28c644cef7d408575a2f31751016a06fb9f26.gz A _darcs/patches/20020808214508-a5eff-f235307a0978c468d840cdc64833544b67ed2b0a.gz A _darcs/patches/20030221211446-a5eff-0d2e7b89cc1038254686dcfe8e92967ac63d10ff.gz A _darcs/patches/20030221211509-a5eff-07881765d7044a110ac464ae4fcba3dadf3fc085.gz A _darcs/patches/20030221230552-a5eff-c836d15002151de0cbab9ebc070007a533069017.gz A _darcs/patches/20030304204627-a5eff-d0903d10b71a042164de95784563a39eebe8cd9a.gz A _darcs/patches/20030305225106-a5eff-df4049b954666ca5b359828204955078cbc90d50.gz A _darcs/patches/20030306040214-a5eff-a6c89071648ffa3d229c61b227fefb1b9bb9d49a.gz A _darcs/patches/20030306040537-a5eff-6f7949b3cf89287ba9c4744de0e7377349811597.gz A _darcs/patches/20030306042519-a5eff-92a3061758e43e16824954cf687ab9f119a06304.gz A _darcs/patches/20030306042631-a5eff-460dc3af3cbf8f7dad0718adc1a5fd1f80308378.gz A _darcs/patches/20030306043414-a5eff-366bfac9d3b55ac57d4a9bb16853f9e9ab4c6b5d.gz A _darcs/patches/20030306055548-a5eff-b0ae7f6ecece45ebe4ac23261fd575f819036f51.gz A _darcs/patches/20030306055621-a5eff-d82dd33142e887cd05a06fbb67c2abe858c0bbaa.gz A _darcs/patches/20030306055843-a5eff-66d1567437a2f3085cf296d3a53037b5f03c9093.gz A _darcs/patches/20030306160414-a5eff-6c928740b3d5d4d108f5c2efa48e309b91086c16.gz A _darcs/patches/20030306164316-a5eff-2128979318056d46975aa58c0952e6bf04623210.gz A _darcs/patches/20030306170801-a5eff-8ba7e3cc86eb6195627bda1153ea750354265420.gz A _darcs/patches/20030306171013-a5eff-04b09ec76fd8c488113af101a680d5fb7503894e.gz A _darcs/patches/20030306200340-a5eff-10436feaf07416ec4f4e3e45dbbf052ef8faa1fa.gz A _darcs/patches/20030306210816-a5eff-90d19a6568ff583ef2fea79c9bafbcc13a736238.gz A _darcs/patches/20030306210959-a5eff-fc885ff8847d06e07c49734be9f46171c4cb2443.gz A _darcs/patches/20030306230304-a5eff-b9205ad7ddd816b3fe83faf334569f7c106127d7.gz A _darcs/patches/20030307013221-a5eff-5d910d6f8c95024777657acc978c1353892f0645.gz A _darcs/patches/20030307014915-a5eff-02458fd7df3fe192742df6a8e4a9029f4614a3b3.gz A _darcs/patches/20030307032511-a5eff-5a9106342f0555e6db52d41d4daecc2af1fc4b5a.gz A _darcs/patches/20030307035413-a5eff-37f15a3f2e64c11f73d24bfe47e89f98e2f01662.gz A _darcs/patches/20030307035442-a5eff-00f480dd4899bf32c81a8cb901355d520e9185ee.gz A _darcs/patches/20030307041336-a5eff-e0efdbc12004db0be19f9611bcb28f0bf2e51ef1.gz A _darcs/patches/20030307044436-a5eff-507cdeff4db0fe522cbc4c58f6e4665b2081dbfb.gz A _darcs/patches/20030307045759-a5eff-fba70f9bc9242322eec457f2f2304375efe48667.gz A _darcs/patches/20030307050511-a5eff-3c01b434da0da39f13ec522a7e72c8496d594f56.gz A _darcs/patches/20030307051240-a5eff-70ab69eee97c3117420a75ac5955da2985221e0a.gz A _darcs/patches/20030307055339-a5eff-b7913f6ded9149d5e7fe20de9f8e1f7590877a15.gz A _darcs/patches/20030307162902-a5eff-a40428bab400c5d8e600b65c2e8fb188cce61d31.gz A _darcs/patches/20030307172316-a5eff-ddc2758392c9d6319625a17e1474b4041794d44a.gz A _darcs/patches/20030307220139-a5eff-ca969df71187113dde3e9a87c21502f5272d656d.gz A _darcs/patches/20030312213307-a5eff-18bba9a0bb4ce6762761ae2187f23f83f5e26392.gz A _darcs/patches/20030312213727-a5eff-604147c028da91352c0d35d3a639160079df6d40.gz A _darcs/patches/20030312222019-a5eff-8b746be6656eca1d5250d15763355373dda61d09.gz A _darcs/patches/20030312225549-a5eff-75e0e2391f38067f047ae20d536fd972fbb23be9.gz A _darcs/patches/20030313002835-a5eff-28cdb7698191ef7b97d57ce8cc7785735bd5f360.gz A _darcs/patches/20030313003248-a5eff-2b91a942a04f7761ba96b88bd9ea7fed7f81faeb.gz A _darcs/patches/20030313005626-a5eff-b40042071be7786ac8fb83bba22bc22fbdd9a9aa.gz A _darcs/patches/20030313010249-a5eff-d1399caf7a5e3dc5f92889a87ef12e6553c0f7ff.gz A _darcs/patches/20030313012001-a5eff-b69bf58734985b49e79c01e92084b23a4b26ce87.gz A _darcs/patches/20030313012033-a5eff-b2f9e77e063c7c7b3e8c83cb6423825fabf2ce8b.gz A _darcs/patches/20030313145854-a5eff-189c9701752f59d33efc5582acee3b5db09eb64f.gz A _darcs/patches/20030313154856-a5eff-add85aabb2539130cbfa075672c090e89576d4fc.gz A _darcs/patches/20030313155247-a5eff-9431d6df041a2724c42c9ab978dd40cd8c848057.gz A _darcs/patches/20030313155311-a5eff-4c2af7d2f62d1e3ff02193bf49ef439022096a9d.gz A _darcs/patches/20030823170149-a5eff-483e1782531b68d4d0fb767ff29fc98ea2693b98.gz A _darcs/patches/20030823181322-a5eff-c10e1e7eef7222b8e8853c5362c9916e6e197a57.gz A _darcs/patches/20030823181737-a5eff-51e2840392e79f038ca0cbdc2959f78a729e0684.gz A _darcs/patches/20030823181823-a5eff-9c9aebefed0050da3944cb8c9a7462a54fc12c13.gz A _darcs/patches/20030823181902-a5eff-404bb4edf6dda6b7d7966a25fcfe0f0d1daa559f.gz A _darcs/patches/20030823182610-a5eff-63dcfb6aaddad0efb4aedb896bf9142acc0fcaeb.gz A _darcs/patches/20030823182650-a5eff-b0889aa78a4f588dd36b27a9c8772f3a68e94d12.gz A _darcs/patches/20030823184929-a5eff-af75a5ede358815bb36b4fb69084ed57eacb5d6a.gz A _darcs/patches/20030823185118-a5eff-f8c5a5a5cff16655837d6c6aecfe1fde25ce5f85.gz A _darcs/patches/20030823185431-a5eff-e39a03f173931cda9985c3c99ba83614a1fe4e3d.gz A _darcs/patches/20030823194113-a5eff-42f0151333bf1af5e2ae2ef78d534b0cec982b8d.gz A _darcs/patches/20030823194312-a5eff-f2afee3713af9a5880f2c868b5972d9a51d6aea2.gz A _darcs/patches/20030823195318-a5eff-6a7cf50a194233e8cc7293e8056b661703179967.gz A _darcs/patches/20030823195650-a5eff-0ceeedf4fd8798af31e87b55f2ec6ca57610765d.gz A _darcs/patches/20030823221319-a5eff-e12699a0a11f0c82970ec759842c2a8f149c7e2f.gz A _darcs/patches/20030823222016-a5eff-beb5c444c9793f6d92672e403e8078fe436516fe.gz A _darcs/patches/20030823222215-a5eff-a0afa8a04804f5a3b1f21ff179cd62569331b1f3.gz A _darcs/patches/20030823222338-a5eff-ec7e41de792ece83aabd13fe3e8912175b41ce25.gz A _darcs/patches/20030823222556-a5eff-096f4ff408108366195109e48793aff642669a6c.gz A _darcs/patches/20030823223440-a5eff-f151c6fcd3d05a7b20477fda6051d731279bd2f6.gz A _darcs/patches/20030823223947-a5eff-8b25bb61eba34b65ee9349a055fddebd9f05ca8e.gz A _darcs/patches/20030824223010-a5eff-d3a2fd3dd07e29ad016ba0e5c859aecd242caa65.gz A _darcs/patches/20030824223416-a5eff-3fa2c4fa4423415c00dfd2d87b55425474ff4af0.gz A _darcs/patches/20030824231720-a5eff-695ff3d338954c46636ca4e99d5beec102f34a5e.gz A _darcs/patches/20030825013833-a5eff-df1709e55b40b975523ad9df172644372ffb2247.gz A _darcs/patches/20030825153158-a5eff-e61917e656b41e72b7d2ffbf2bf0a59d81359652.gz A _darcs/patches/20030825184740-a5eff-fff174dbb0a2ec4942f95d1d03c70cfbc9671310.gz A _darcs/patches/20030825201558-a5eff-7a26b663499c0349a92d50e884e1900de4433423.gz A _darcs/patches/20030825201736-a5eff-6d36a9cf6358ca7a42fe0aa8572e8f2dd738fce7.gz A _darcs/patches/20030825211038-a5eff-05ca5457d8aa667f33acf3d963e39f1d32e8e3c6.gz A _darcs/patches/20030825211452-a5eff-477c31c309f787d124b65470c73b2b4e2e70e7b3.gz A _darcs/patches/20030825211723-a5eff-270d94d7754949fd34aa9c0d6704551082b60371.gz A _darcs/patches/20030825211738-a5eff-7e2e57ca57f9b799b0a84feb03ed8cd75ee0c85d.gz A _darcs/patches/20030825220138-a5eff-570a77a8da4e8eec616514e6d239e82e1be3b280.gz A _darcs/patches/20030825235615-a5eff-a1316387f00ed294afcb8305880568aa2f4ae654.gz A _darcs/patches/20030826014214-a5eff-9bda55c73d42545bdd7bd221330624a2ddf7dd32.gz A _darcs/patches/20030826032952-a5eff-3994986f7625529e6020e7f6459fe06d8777236a.gz A _darcs/patches/20031009161133-a5eff-2aef155954b3bf44adb20c33c1017cb2e6cb5ebf.gz A _darcs/patches/20031009214813-a5eff-ecd9106d0de8ea16195b1f385edacdc9db36383b.gz A _darcs/patches/20031217142030-a5eff-43801f5b608cedc0380f4cb1bf16c24279f2b88e.gz A _darcs/patches/20031217142733-a5eff-96b00afb2de192464493a108379c5ebfcb87eb70.gz A _darcs/patches/20031217144411-a5eff-df8b4ef99665e145b6f0ee1344aca79b81486a26.gz A _darcs/patches/20031217152032-a5eff-8d634550d0e315a803eeeeef2c4b9dbe33bc9126.gz A _darcs/patches/20031217152042-a5eff-ab3e5d849fa64591a809829e55247911bc025d8d.gz A _darcs/patches/20031217172643-a5eff-405a63088b9aa82801df513677c8f7e7b5f6b6f5.gz A _darcs/patches/20031217172906-a5eff-8a0fbe5341ffc660764b57d22e0563dea5605ac0.gz A _darcs/patches/20040827154312-a5eff-cacdbe01b5b47a3a16aadb0c00f024a169f381f9.gz A _darcs/patches/20040830195017-a5eff-9892df0950e8ab70d4eb54f05efdba0b84534582.gz A _darcs/patches/20040830195147-a5eff-ab9eaad868659c9f54654db7d472326d1cd79f0b.gz A _darcs/patches/20050114153553-c2a52-7e2dd54a7331be14f9d2b4a311a0c7eb3fd27ea7.gz A _darcs/patches/20050115212415-c2a52-b2b1af62d6829cc9420ad803bfd252f1ed134153.gz A _darcs/patches/20050115212935-c2a52-c14780d8355ff1cb44937be7e583ea694c31d8cd.gz A _darcs/patches/20050115213152-c2a52-51d99e2c5ffa098a71179ee3ae559ff7e491a471.gz A _darcs/patches/20050219180649-c2a52-d186e639339d83b04203f8a066e24ec21eb89ac6.gz A _darcs/patches/20050219180920-c2a52-d4e17ca6e3077803d442e36a65eb6a1993b5b2bc.gz A _darcs/patches/20050416103354-6793f-6a6e76509681d8556bfbae8015a5df0689aac271.gz A _darcs/patches/20050416154059-c2a52-a0a5feef0ee2dab3e1e3770d804d32ed2eafefc9.gz A _darcs/patches/20050416154132-c2a52-6a0f9f2b060ebb04911e79a6cffdc6320b295090.gz A _darcs/patches/20050416154211-c2a52-16192abc7c016b043a1cacb1dbe3158925cc6ccd.gz A _darcs/patches/20050416164256-c2a52-dc017162179bcc0ec299bf1d33618ddb830f3fd4.gz A _darcs/patches/20050416164809-c2a52-59ac9a6837e24de663ff3a8e44ce3bd5018a64a5.gz A _darcs/patches/20050416164836-c2a52-faaa46e043b957fa7c33db1a90c3f43df219aa78.gz A _darcs/patches/20050913191948-c2a52-1cbd6f03c05dbf487c405494e1f25eb5ee3470e6.gz A _darcs/patches/20050922123724-c2a52-2b6100be48abd345d402473d1fca263177f1e608.gz A _darcs/patches/20050922124716-c2a52-4025c3a1e2c23d1b63ae3abf79c1df5c7f702b3f.gz A _darcs/patches/20050922124809-c2a52-072ef7ecbc14dc5c2732954bbe4040dcb1d8bb3e.gz A _darcs/patches/20050922124819-c2a52-27c76e9af547fbb4876dbeffb9e32fd7119d91c6.gz A _darcs/patches/20050922124952-c2a52-24b58a0d85beda836e3faba9585d822cc36c7eec.gz A _darcs/patches/20050922130235-c2a52-910657f419cac65e7358c9b021aeeba0b4703175.gz A _darcs/patches/20060509154502-c2a52-4570f27e588fa890c6a642f6b2670a5e8b36b853.gz A _darcs/patches/20060509154524-c2a52-76af4b03a81b2f593159130b7406b4b9a79ed94d.gz A _darcs/patches/20060509154643-c2a52-e9c0e0019212038a3d957011da50e3e2654466e5.gz A _darcs/patches/20060911135005-c2a52-82ab81db3e567d758e50a42cb5106e4e729e07a6.gz A _darcs/patches/20060911135017-c2a52-7f665cdb36c7f963d43870aaa9d3d8b17e79ee65.gz A _darcs/patches/20060911135413-c2a52-23bdd6be0421b90c0b7834c6cd1937a1928b48ab.gz A _darcs/patches/20060911135510-c2a52-5469317c0b6e35028b79cf4ef6644a49069a3367.gz A _darcs/patches/20060911135518-c2a52-212ed02e3b6a5376b389ed7520e6451959ab04fd.gz A _darcs/patches/20060911140109-c2a52-7d49457c5f34b22d4dc3c09c0f9860a42f143072.gz A _darcs/patches/20060911140826-c2a52-65e0d9a82dc0ba72ed360eac594599922fc647b0.gz A _darcs/patches/20060911141036-c2a52-2ecda3bfa57b30b7d5b8c9c8bd272ce82c0edf77.gz A _darcs/patches/20060911141137-c2a52-84672717218a955c9ea320d1ad90ed09f9d56a65.gz A _darcs/patches/20060915190102-c2a52-75273e4724ca8c46a4d9334692e4fd32c6c7155a.gz A _darcs/patches/20060915190214-c2a52-92a9c9f45285d44363ff1e7b99de9d253abfba9a.gz A _darcs/patches/20060915190246-c2a52-26dd5e4724f439f1dab6d095ab1cb60a9c7ab05c.gz A _darcs/patches/pending A _darcs/prefs/binaries A _darcs/prefs/boring A _darcs/prefs/defaultrepo A _darcs/prefs/motd A _darcs/prefs/repos A build/scripts-2.4/pygopherd M debian/rules commit 4131d410033e1d63742ea3f60e16e9227ba3a80e Author: John Goerzen Date: Sat Sep 16 01:02:46 2006 +0100 Update urgency M debian/changelog commit 31bc95f4d6a6ecabc6d53dad3abb61edeb88308a Author: John Goerzen Date: Sat Sep 16 01:02:14 2006 +0100 Update changelog M debian/changelog commit 0e28bf27cdc276eea3065bb559d3678b53653c37 Author: John Goerzen Date: Sat Sep 16 01:01:02 2006 +0100 Move around python stuff to fix install The system was trying to start pygopherd before python-central had a chance to do its thing. debian #387663 M debian/postinst M debian/postrm M debian/rules commit 4c22cb21947e9ee0f5d90d216508e83668662067 Author: John Goerzen Date: Mon Sep 11 20:11:37 2006 +0100 TAG DEBIAN_pygopherd_2.0.16 commit e89598794a22799ad343787fb3e92b53e95f9b6d Author: John Goerzen Date: Mon Sep 11 20:10:36 2006 +0100 Note closure of python transition bug in changelog M debian/changelog commit 0ac4aade6bdc3e7724b4d704ded05d46da2a92f9 Author: John Goerzen Date: Mon Sep 11 20:08:26 2006 +0100 Fix timeout code M pygopherd/initialization.py commit 9937e6b42336923d05cdf2b2309863047cc2332d Author: John Goerzen Date: Mon Sep 11 20:01:09 2006 +0100 Removed python2.2 in bang paths M pygopherd/GopherExceptionsTest.py M pygopherd/fileextTest.py M pygopherd/gopherentryTest.py M pygopherd/initializationTest.py M pygopherd/testutil.py M runtests.py M runtestsgui.py commit f12b9f25a2cb3dfd8784c3d26723042986a886bd Author: John Goerzen Date: Mon Sep 11 19:55:18 2006 +0100 Update control M debian/control commit 4f7929fe9d69dcb0ba6191f77f19df0de7bbe2bc Author: John Goerzen Date: Mon Sep 11 19:55:10 2006 +0100 Update changelog M debian/changelog commit d5d637888abb81461aa7afc2bdb41f36db0b7cc5 Author: John Goerzen Date: Mon Sep 11 19:54:13 2006 +0100 Changes for Debian python migration M debian/control A debian/pycompat M debian/rules commit b84510b6cea3b70266626877d8f944d678ecd5c6 Author: John Goerzen Date: Mon Sep 11 19:50:17 2006 +0100 Document timeouts in example config file M conf/pygopherd.conf commit 30552ee9941a29d33a1987ef53f8e921ace71ddb Author: John Goerzen Date: Mon Sep 11 19:50:05 2006 +0100 First attempt at setting socket timeouts M pygopherd/initialization.py commit 6d50bd2642db0af0013b31c9faa5314d73f7afc4 Author: John Goerzen Date: Tue May 9 21:46:43 2006 +0100 TAG DEBIAN_pygopherd_2.0.15 commit f8262fc5e752e23c82869944b14e15b7642b9d78 Author: John Goerzen Date: Tue May 9 21:45:24 2006 +0100 Prepping for 2.0.15 M debian/changelog M pygopherd/version.py commit b243236880fde21f51ecdb346b16dc55451deaa4 Author: John Goerzen Date: Tue May 9 21:45:02 2006 +0100 Fix handling of interface config option Debian #357315, #361435 M pygopherd/initialization.py commit ad03579cf56779f6698c3532e7121708fdd60eec Author: John Goerzen Date: Thu Sep 22 19:02:35 2005 +0100 TAG DEBIAN_pygopherd_2.0.14 commit 4f1ac16745726ea559411a2e679dd5eb4112eb7e Author: John Goerzen Date: Thu Sep 22 18:49:52 2005 +0100 More ChangeLog updates M ChangeLog commit a11ecd887ad5c3d386c0dc6b545dc8d8ca5129dc Author: John Goerzen Date: Thu Sep 22 18:48:19 2005 +0100 ChangeLog is now generated from Darcs. M Makefile commit 026d722fdc206cdbbc5ba60edb794750e213c15d Author: John Goerzen Date: Thu Sep 22 18:48:09 2005 +0100 Updated metadata for 2.0.14 M debian/changelog M pygopherd/version.py commit ced6711b133c891524191d433fb6f6bf54132fab Author: John Goerzen Date: Thu Sep 22 18:47:16 2005 +0100 Updated ChangeLog (it hadn't been updated since 2003, eep.) M ChangeLog commit 01ac0d289ab66f499c3f882c8ac915a0ecfeb729 Author: John Goerzen Date: Thu Sep 22 18:37:24 2005 +0100 Fixed a bug where no subject line would crash the handler M pygopherd/handlers/mbox.py commit c0c5b6433e4376f0b8ca6f800cc5709c5535b00a Author: John Goerzen Date: Wed Sep 14 01:19:48 2005 +0100 Don't strip leading whitespace from abstract files M pygopherd/gopherentry.py commit 01139580eeace48a67f26d732534c0ad4a07f1db Author: John Goerzen Date: Sat Apr 16 22:48:36 2005 +0100 TAG Last Arch revision commit 370007e7e0d7c45733975874b624a227b088e8c6 Author: John Goerzen Date: Sat Apr 16 22:48:09 2005 +0100 TAG Last Subversion revision commit 2f2a4f04ec400647b89b78e279df68818108ac13 Author: John Goerzen Date: Sun Feb 20 01:09:20 2005 +0100 Minor touchups for 2.0.13 Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-6) M README M TODO M pygopherd/version.py commit 96d53f15b391e7f5d6291835e62fed93d49a89be Author: John Goerzen Date: Sun Feb 20 01:06:49 2005 +0100 Minor updates Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-5) M debian/changelog M debian/rules M doc/pygopherd.sgml commit 829a24d556d2f41f7b6eb44982fc5c587d059067 Author: John Goerzen Date: Sun Jan 16 04:31:52 2005 +0100 Another silly fix Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-4) M pygopherd/initialization.py commit 736f171ff8ffa8571a57a8d21340ba49ae50e922 Author: John Goerzen Date: Sun Jan 16 04:29:35 2005 +0100 Syntax error fix Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-3) M pygopherd/initialization.py commit 59d3a4f73cfb69dfa58a70f1d968fa5b721b8b5d Author: John Goerzen Date: Sun Jan 16 04:24:15 2005 +0100 Cleaner handling of connection reset by peer Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-2) M debian/changelog M pygopherd/initialization.py commit d23e003ddd37a0d1b17ffafc4bed21680f5646e3 Author: John Goerzen Date: Fri Jan 14 22:35:53 2005 +0100 Add small bugfix Keywords: (jgoerzen@complete.org--projects/pygopherd--head--1.0--patch-1) M debian/changelog M pygopherd/protocols/rfc1436.py commit 7e2e96514836ef225eb7637ddeabe23b3d31cbcf Author: John Goerzen Date: Sat Apr 16 22:42:56 2005 +0100 Noted removal of pygopherd.py from r204 D pygopherd.py commit 8e81becf9b5fbea75c3e640900e0f623500db55a Author: John Goerzen Date: Sat Apr 16 21:42:11 2005 +0100 TAG REL1.99.5 commit f0d7bddc12c5f3047d3f55005af203a655ad3e3a Author: John Goerzen Date: Sat Apr 16 21:41:32 2005 +0100 TAG SVN tag BEFORE-ZIPFILE-REWRITE commit f01a55f5173cad4248d11d5ba6721d4141bb2564 Author: John Goerzen Date: Sat Apr 16 21:40:59 2005 +0100 TAG REL1.0.0 commit defa6ff630c9e351351a57bbc1403aa0d2d9824c Author: jgoerzen Date: Tue Aug 31 01:51:47 2004 +0100 /pygopherd/head: changeset 309 A README.windows commit c6dea769fcb609fa8f6a56521b80a628e2ca5e71 Author: jgoerzen Date: Tue Aug 31 01:50:17 2004 +0100 /pygopherd/head: changeset 308 Make more Windows-friendly M debian/changelog M pygopherd/handlers/tal.py M pygopherd/initialization.py M pygopherd/sighandlers.py commit f11284050e285467a737fc135082713ee3e811cb Author: jgoerzen Date: Fri Aug 27 21:43:12 2004 +0100 /pygopherd/head: changeset 307 Removed extra reference to ZIP.py M pygopherd/handlers/ZIP.py commit 234fa58d0250b65e4b23b5151d41ae4175d7fcdd Author: jgoerzen Date: Thu Dec 18 00:29:06 2003 +0100 /pygopherd/head: changeset 306 Fixed indentation M pygopherd/handlers/tal.py commit 8a9f7bebd9855abf81ec0f54a4fee7635d0678ad Author: jgoerzen Date: Thu Dec 18 00:26:43 2003 +0100 /pygopherd/head: changeset 305 Don't crash if tal is unavailable. M debian/changelog M pygopherd/handlers/tal.py commit 164d308d363a3665f9b8aee8c4d5d39464dedc73 Author: jgoerzen Date: Wed Dec 17 22:20:42 2003 +0100 /pygopherd/head: changeset 304 Updated the ChangeLog M ChangeLog commit d401c56b3d1637d44dcc8f45e067e41a8fe393f0 Author: jgoerzen Date: Wed Dec 17 22:20:32 2003 +0100 /pygopherd/head: changeset 303 Fixed the earlier fix... M pygopherd/handlers/UMN.py commit 6e80c54b203fef4cdb7db0ccfbce17940def3c5d Author: jgoerzen Date: Wed Dec 17 21:44:11 2003 +0100 /pygopherd/head: changeset 302 Fixed a logic error in the Numb handling fix. M debian/changelog M pygopherd/handlers/UMN.py commit d0c8d4fa6c83204d2bc312f60422371a37a529c5 Author: jgoerzen Date: Wed Dec 17 21:27:33 2003 +0100 /pygopherd/head: changeset 301 Fixed UMN.py to properly handle Numb=. M debian/changelog M pygopherd/handlers/UMN.py commit ba34c2c24775cae52f6459a20a3f906a47b44b61 Author: jgoerzen Date: Wed Dec 17 21:20:30 2003 +0100 /pygopherd/head: changeset 300 Generic TAL support M pygopherd/handlers/tal.py commit dbf102e7280651e2c7caf47e5ad37902275b1ec3 Author: jgoerzen Date: Fri Oct 10 03:48:13 2003 +0100 /pygopherd/head: changeset 299 Updated debian/docs M debian/changelog M debian/docs commit 1bd83e4b2f10c500ddf05a55b1f0763333798426 Author: jgoerzen Date: Thu Oct 9 22:11:33 2003 +0100 /pygopherd/head: changeset 298 Added build-dep on python2.3-dev M debian/changelog commit 17cc71cbcccb69efdd7f51c1e69ee6c4842ccb65 Author: jgoerzen Date: Tue Aug 26 09:29:52 2003 +0100 /pygopherd/head: changeset 297 Added missing docs Misc. tal stuff A doc/book.sgml A doc/manpage.sgml A doc/quickstart.sgml M pygopherd/handlers/tal.py commit 85c15b4f5a585fcb95d0cddf9934c23d01c0c6f5 Author: jgoerzen Date: Tue Aug 26 07:42:14 2003 +0100 /pygopherd/head: changeset 296 Added dir, macro capability to tal.py Some work on the manual -- splitting up into sections M Makefile M doc/pygopherd.ps M doc/pygopherd.sgml M local.dsl M pygopherd/handlers/tal.py commit 44ec1cdd1cd0dc48a2958839e83f9d1d1e109eeb Author: jgoerzen Date: Tue Aug 26 05:56:15 2003 +0100 /pygopherd/head: changeset 295 Make is a little more aggressive about cleaning... ... added stylesheets. M Makefile A local.dsl A printlocal.dsl commit d8bc256c16e3313fe1b8cf06e6d0971f7f109d74 Author: jgoerzen Date: Tue Aug 26 04:01:38 2003 +0100 /pygopherd/head: changeset 294 Doc updates M Makefile M doc/pygopherd.8 M doc/pygopherd.html M doc/pygopherd.pdf M doc/pygopherd.ps commit f06ac4aeb77fe0a464b9129a765c851dad7411fc Author: jgoerzen Date: Tue Aug 26 03:17:38 2003 +0100 /pygopherd/head: changeset 293 Finalizing the document renaming R100 doc/manual.ps doc/pygopherd.ps commit 172e5acf3fed657a10b08ebe014de2b15e805a4c Author: jgoerzen Date: Tue Aug 26 03:17:23 2003 +0100 /pygopherd/head: changeset 292 More document renaming R100 doc/manual.html doc/pygopherd.html R100 doc/manual.pdf doc/pygopherd.pdf R100 doc/manual.txt doc/pygopherd.txt commit 3be9fa66deba868b8711c8a08ba6008a6731c95d Author: jgoerzen Date: Tue Aug 26 03:14:52 2003 +0100 /pygopherd/head: changeset 291 M Makefile R100 manual.html doc/manual.html R100 manual.pdf doc/manual.pdf R100 manual.ps doc/manual.ps R100 manual.txt doc/manual.txt R100 pygopherd.8 doc/pygopherd.8 R099 pygopherd.sgml doc/pygopherd.sgml commit ffa7616d004ffeb21dc43e7897b88df883b26d58 Author: jgoerzen Date: Tue Aug 26 03:10:38 2003 +0100 /pygopherd/head: changeset 290 Fixed up Python2.3 support -- and added dep on simpletal M debian/control commit d274afdd22aae4e3709404db376add2a76f307b4 Author: jgoerzen Date: Tue Aug 26 02:17:36 2003 +0100 /pygopherd/head: changeset 289 Added a TAL example A examples/talsample.html.tal commit a8c75ad67c28a2ce82831d8b9f2df67c93541e8b Author: jgoerzen Date: Tue Aug 26 02:15:58 2003 +0100 /pygopherd/head: changeset 288 Added beginnings of TAL support. More to come. M bin/pygopherd M conf/pygopherd.conf M pygopherd/handlers/__init__.py A pygopherd/handlers/tal.py M setup.py commit 9e203dee34b48176c5206ecf1cf654983975f85b Author: jgoerzen Date: Tue Aug 26 00:47:40 2003 +0100 /pygopherd/head: changeset 287 Documented the ZIP handler M manual.html M manual.pdf M manual.ps M manual.txt M pygopherd.8 M pygopherd.sgml M pygopherd/handlers/ZIP.py commit b016e47e9ab677f23603fa076eddc0405cd4cbae Author: jgoerzen Date: Mon Aug 25 21:31:58 2003 +0100 /pygopherd/head: changeset 286 Work on documenting the handlers M pygopherd.sgml commit 577bb5e0527fc6c3d35f10293fe7e6226a1a18f6 Author: jgoerzen Date: Mon Aug 25 07:38:33 2003 +0100 /pygopherd/head: changeset 285 Some work on the docs M manual.html M manual.pdf M manual.ps M manual.txt M pygopherd.8 M pygopherd.sgml commit 3a302de42a50d5d63d7baf9c5c532f6da828450f Author: jgoerzen Date: Mon Aug 25 05:17:20 2003 +0100 /pygopherd/head: changeset 284 Updated M manual.html M manual.pdf M manual.ps M manual.txt M pygopherd.8 M pygopherd.sgml commit 932ddd97cc235f29668a373def0dc3854d8755cd Author: jgoerzen Date: Mon Aug 25 04:34:16 2003 +0100 /pygopherd/head: changeset 283 Added SGML docs. M Makefile A pygopherd.sgml commit 145ae50b79fc3265e2c288c4750489baeac8e789 Author: jgoerzen Date: Mon Aug 25 04:30:10 2003 +0100 /pygopherd/head: changeset 282 M debian/changelog M pygopherd/initialization.py M pygopherd/protocols/wap.py commit 78a74e57c499abb9bb15e7843be4e1adeb8692cb Author: jgoerzen Date: Sun Aug 24 04:39:47 2003 +0100 /pygopherd/head: changeset 281 Updated WAP error handling M pygopherd/protocols/wap.py commit 234d01a697839b4b74a8ad0aa9bd4bcd983c7fa9 Author: jgoerzen Date: Sun Aug 24 04:34:40 2003 +0100 /pygopherd/head: changeset 280 Fixed File Not Found code. M debian/changelog M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit f53b8777b3667d33c621ca5b8c0f3ab8211bed9f Author: jgoerzen Date: Sun Aug 24 04:25:56 2003 +0100 /pygopherd/head: changeset 279 Store slurp data elsewhere M pygopherd/protocols/http.py commit 391b8923acb6154cfc535431abb5721bd57db5b3 Author: jgoerzen Date: Sun Aug 24 04:23:38 2003 +0100 /pygopherd/head: changeset 278 Fixed another bug in headerslurp M pygopherd/protocols/http.py commit 479635052dfcbfc18e2b1bd5ac9d04664305db67 Author: jgoerzen Date: Sun Aug 24 04:22:15 2003 +0100 /pygopherd/head: changeset 277 Replaced a missing return M pygopherd/protocols/http.py commit 14f068a8b17e5df30a8d06980b12e76b7592c5f1 Author: jgoerzen Date: Sun Aug 24 04:20:16 2003 +0100 /pygopherd/head: changeset 276 Experimental new header slurping mechanism M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit 34bbf7f0245620dc6742ef48ac21ea6252873d30 Author: jgoerzen Date: Sun Aug 24 04:13:19 2003 +0100 /pygopherd/head: changeset 275 Added wap auto-detection. M conf/pygopherd.conf M debian/changelog M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit a8737d418429a1514b6ac049fae81315187a4d72 Author: jgoerzen Date: Sun Aug 24 01:56:50 2003 +0100 /pygopherd/head: changeset 274 Fixed a tyop M pygopherd/protocols/wap.py commit a790046c9dc3d6097a0c0eb7209516c0e73fc940 Author: jgoerzen Date: Sun Aug 24 01:53:18 2003 +0100 /pygopherd/head: changeset 273 Added text file conversion to WAP M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit 6b151d14f94ae9d600877ddcf0d3b6543aacee2c Author: jgoerzen Date: Sun Aug 24 01:43:12 2003 +0100 /pygopherd/head: changeset 272 Virtual: now use | for selector sep (keep ? for legacy) for WAP compatibility. M debian/changelog M pygopherd/handlers/virtual.py commit 9022f8c29143aef6346bf50102229122df123f07 Author: jgoerzen Date: Sun Aug 24 01:41:13 2003 +0100 /pygopherd/head: changeset 271 Some updates M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit 408f6456e6f28bdfe4386bc5db304e93a04c6f48 Author: jgoerzen Date: Sun Aug 24 00:54:31 2003 +0100 /pygopherd/head: changeset 270 Add the waptop in front of generated URLs M pygopherd/protocols/wap.py commit e3485ab2e6f68b9197580517562fcfa9200af190 Author: jgoerzen Date: Sun Aug 24 00:51:18 2003 +0100 /pygopherd/head: changeset 269 Minor WAP bugfixes M pygopherd/protocols/wap.py commit 88eb735f888fb6e2907a27d1475a8188bdefe7f1 Author: jgoerzen Date: Sun Aug 24 00:49:29 2003 +0100 /pygopherd/head: changeset 268 Updated for Python 2.3 -- and added some more WAP code (for searches) M debian/changelog M debian/control M debian/rules M pygopherd/protocols/wap.py commit c5273c08c371aa8377f2d7b036d8ee9ed2342c7e Author: jgoerzen Date: Sun Aug 24 00:26:50 2003 +0100 /pygopherd/head: changeset 267 Braino M pygopherd/protocols/wap.py commit acd68ab71d324ec13233c446ec943820f4c300a6 Author: jgoerzen Date: Sun Aug 24 00:26:10 2003 +0100 /pygopherd/head: changeset 266 More updates M pygopherd/protocols/wap.py commit 9bc514db6dfbe320ca823acb805e339572dae9ff Author: jgoerzen Date: Sun Aug 24 00:19:02 2003 +0100 /pygopherd/head: changeset 265 Another braino M pygopherd/protocols/wap.py commit c4107c400aed2aa87295464f3e315e60d7c27a70 Author: jgoerzen Date: Sun Aug 24 00:18:23 2003 +0100 /pygopherd/head: changeset 264 Oops, little braino here M pygopherd/protocols/wap.py commit 8c7b89b5da9e42599e23265ea7c8c0393505a604 Author: jgoerzen Date: Sun Aug 24 00:17:37 2003 +0100 /pygopherd/head: changeset 263 Removed debugging code and added accesskey support M pygopherd/protocols/wap.py commit af0794cb1fd7d697f95e86746b993c18e4b99407 Author: jgoerzen Date: Sun Aug 24 00:13:22 2003 +0100 /pygopherd/head: changeset 262 Wap now works! M debian/changelog M pygopherd/protocols/http.py M pygopherd/protocols/wap.py commit abeec36b6ec6ac2769387a9c2fab534e5ee31167 Author: jgoerzen Date: Sat Aug 23 23:01:49 2003 +0100 /pygopherd/head: changeset 261 First attempt at new feature: WAP support! M conf/pygopherd.conf M debian/changelog M pygopherd/protocols/__init__.py M pygopherd/protocols/http.py A pygopherd/protocols/wap.py commit 1aa2486d7eb5ee73682b0fd5a019919d4567a8f8 Author: jgoerzen Date: Thu Mar 13 22:53:11 2003 +0100 /pygopherd/head: changeset 259 Updated for 1.99.5 M ChangeLog commit 8f29f3b8a3981de519f68ad6421e09529bc63b1e Author: jgoerzen Date: Thu Mar 13 22:52:47 2003 +0100 /pygopherd/head: changeset 258 Introduced new "inode-like" caching system for ZIP files. Now, the first time a ZIP file is accessed, it will be scanned. Links will be resolved immediately. A dictionary tree is built up; values being either file offsets in the ZIP file or dictionaries (for subdirectories). This dictionary is then cached on-disk using a binary database and marshal algorithm derived from Python's shelve module. We do not need to use pickle for this task since we are saving only simple structures. The performance gain for large ZIP files using this method is tremendous. The only time a ZIP file's central directory structure must be scanned now is the very first time it is ever accessed. M debian/changelog commit 19e6dc712dca463873a6c9d8d9a861fb93036810 Author: jgoerzen Date: Thu Mar 13 22:48:56 2003 +0100 /pygopherd/head: changeset 257 Removed the needschain tests Optimized the gophermap isrequestforme handler M pygopherd/handlers/ZIP.py M pygopherd/handlers/gophermap.py commit 77c51e1e39e03d4937b4c85d2adac9ae1460c1ac Author: jgoerzen Date: Thu Mar 13 21:58:54 2003 +0100 /pygopherd/head: changeset 256 Converted to using marshal for a performance gain M pygopherd/handlers/ZIP.py commit 56c594e7dd3ecb10b616392bc909d911716f324c Author: jgoerzen Date: Thu Mar 13 08:20:33 2003 +0100 /pygopherd/head: changeset 255 Removed debug code M pygopherd/handlers/ZIP.py commit 780f4f741763a700abfcc43e9a3ad8d24fbe18de Author: jgoerzen Date: Thu Mar 13 08:20:01 2003 +0100 /pygopherd/head: changeset 254 Passes all ZIP tests. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 09e91cddbbe736e0e14578c408ec890e4761bf33 Author: jgoerzen Date: Thu Mar 13 08:02:49 2003 +0100 /pygopherd/head: changeset 253 Removed debug code M pygopherd/handlers/ZIP.py commit 29713893818b0ca657cec8b6fdf1c9e0c0f01f2b Author: jgoerzen Date: Thu Mar 13 07:56:26 2003 +0100 /pygopherd/head: changeset 252 Think I've nailed the caching problem M pygopherd/handlers/ZIP.py commit 6ccbc2d686f629f769409fb0474b30c432de2c49 Author: jgoerzen Date: Thu Mar 13 07:32:48 2003 +0100 /pygopherd/head: changeset 251 All tests are passing, but caching doesn't seem to be working. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 2528294324ba357903c22321706db02bb6e13f78 Author: jgoerzen Date: Thu Mar 13 07:28:35 2003 +0100 /pygopherd/head: changeset 250 Strating to fix errors as part of testing M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 926305ee47959817bfca455dba00946613ce78e3 Author: jgoerzen Date: Thu Mar 13 05:55:49 2003 +0100 /pygopherd/head: changeset 249 Making more progress -- we now have this to the point of being ready for testing, I believe. M ChangeLog M debian/changelog M pygopherd/handlers/ZIP.py commit edc6de8cd175970ac2fb24f8b4a44e38e917261f Author: jgoerzen Date: Thu Mar 13 05:20:19 2003 +0100 /pygopherd/head: changeset 248 Checkpointing my progress -- initial efforts to rewrite the caching to use an inode system complete. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit d067f006964c1e8e1f6c5f98519c5a145e11c5c6 Author: jgoerzen Date: Thu Mar 13 04:37:27 2003 +0100 /pygopherd/head: changeset 247 Merged back in bugfix to islinkattr from ZIP.py prior to this rev. M pygopherd/handlers/ZIP.py commit c100afe7a874a384b95dd2ede9ac73826f46d727 Author: jgoerzen Date: Thu Mar 13 04:33:07 2003 +0100 /pygopherd/head: changeset 246 Reverted to ZIP.py from revision 229 when pickling was present. Will try to re-do this more efficiently with the new zipfile and anydbm. M pygopherd/handlers/ZIP.py commit 931ac1b6b8030bb30669a12ff05d9b54b60f16e9 Author: jgoerzen Date: Sat Mar 8 05:01:39 2003 +0100 /pygopherd/head: changeset 245 Added additional optimizations, tested working. M pygopherd/handlers/ZIP.py M pygopherd/handlers/dir.py commit f8d8a818b2c365ef96c6ff096874f8daee6d7531 Author: jgoerzen Date: Fri Mar 7 12:53:39 2003 +0100 /pygopherd/head: changeset 244 Fixed an excessive stating problem. M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/ZIP.py M pygopherd/handlers/dir.py M pygopherd/zipfile.py commit 56c18a4059d18773fb59692a76ac736d3bed0281 Author: jgoerzen Date: Fri Mar 7 12:12:40 2003 +0100 /pygopherd/head: changeset 243 Significant optimizations noted in output from zip stuff. M pygopherd/handlers/ZIP.py commit 0b390e39f724d342b161048662116475fcabcbd7 Author: jgoerzen Date: Fri Mar 7 12:05:11 2003 +0100 /pygopherd/head: changeset 242 Tests now pass. Time to see how this optimization fares. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 399bacc58a4e38c8a2d4a16b661e77c291c360ee Author: jgoerzen Date: Fri Mar 7 11:57:59 2003 +0100 /pygopherd/head: changeset 241 In the middle of some optimizing. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 88ad0bd5d3b9d755cbb1ba30275b2b5fd31f8586 Author: jgoerzen Date: Fri Mar 7 11:44:36 2003 +0100 /pygopherd/head: changeset 240 Some feeble optimization attempts. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 642135246b7cc9f4dbbc26ce520ac8961c1d0062 Author: jgoerzen Date: Fri Mar 7 11:13:36 2003 +0100 /pygopherd/head: changeset 239 Tests are all passing! M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 07352ca1964aeb1586fa9ee84c954c2eb4dcd5fe Author: jgoerzen Date: Fri Mar 7 10:54:42 2003 +0100 /pygopherd/head: changeset 238 Removed _resolvelink debug code M pygopherd/handlers/ZIP.py commit 7c5a3c724a2b2770dad7991cbfbcef63462bd555 Author: jgoerzen Date: Fri Mar 7 10:54:13 2003 +0100 /pygopherd/head: changeset 237 Fixed _resolvelink M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py commit 85caec588203111e871012e344185ae26c96c902 Author: jgoerzen Date: Sat Mar 8 00:23:16 2003 +0100 /pygopherd/head: changeset 236 Ready to test. M pygopherd/handlers/ZIP.py M pygopherd/handlers/base.py M pygopherd/handlers/file.py M pygopherd/zipfile.py commit 6e356bbd34a0495bc8c1c7cd1fc4e0df2e3d7506 Author: jgoerzen Date: Fri Mar 7 23:29:02 2003 +0100 /pygopherd/head: changeset 235 Completed initial work on the new zipfile.py. M pygopherd/handlers/ZIP.py M pygopherd/zipfile.py M runtests.py commit 52051ac9b25ef66652661fff89469b6182e34e04 Author: jgoerzen Date: Fri Mar 7 10:25:11 2003 +0100 /pygopherd/head: changeset 233 Added from upstream CVS A pygopherd/zipfile.py commit 9ce927dacb175bed1159b79eb3e27400b7cb921e Author: jgoerzen Date: Fri Mar 7 08:49:15 2003 +0100 /pygopherd/head: changeset 232 Made great strides here. M pygopherd/handlers/ZIP.py commit b9647e3d3ca723c7297e63a18f1174b89b5dab9b Author: jgoerzen Date: Fri Mar 7 08:32:21 2003 +0100 /pygopherd/head: changeset 231 Reworking the symlink stuff. M pygopherd/handlers/ZIP.py commit fa120e2d42a6ef7b763ea5f1344771b6e9134ba8 Author: jgoerzen Date: Fri Mar 7 06:03:04 2003 +0100 /pygopherd/head: changeset 230 M debian/changelog M pygopherd/handlers/ZIP.py commit b1af614fc4c157cd57c49a3c683163530f02cb74 Author: jgoerzen Date: Fri Mar 7 04:09:59 2003 +0100 /pygopherd/head: changeset 229 All tests now pass! M pygopherd/handlers/ZIP.py commit f0349d4d5a6b92e0a0ea9acb720820ce4f86dabb Author: jgoerzen Date: Fri Mar 7 04:08:16 2003 +0100 /pygopherd/head: changeset 228 Making progress on ironing out bugs. M pygopherd/handlers/ZIP.py M pygopherd/handlers/base.py M testdata/symlinktest.zip commit 0d0d1585f3fc2f4b49103da54f4b7f2429eb460b Author: jgoerzen Date: Fri Mar 7 03:03:40 2003 +0100 /pygopherd/head: changeset 227 Checkpointing M debian/changelog M pygopherd/handlers/ZIP.py M pygopherd/handlers/html.py M runtests.py commit d1518fcf1f6590591c80b4c34771932c71eb9048 Author: jgoerzen Date: Fri Mar 7 00:10:13 2003 +0100 /pygopherd/head: changeset 226 Updated the changelog M debian/changelog commit 43c015d5f09e32ec823b2bc01de6e2237d827b6f Author: jgoerzen Date: Fri Mar 7 00:08:01 2003 +0100 /pygopherd/head: changeset 225 Refined directory handling. Greatly expanded tests. Added a full symlink test battery. listdir() now raises OSError when called on an invalid directory. open() now raises IOError when called on a directory. M pygopherd/handlers/ZIP.py commit 2e20670cb205ecc190164df5818b027069dbe05a Author: jgoerzen Date: Thu Mar 6 23:43:16 2003 +0100 /pygopherd/head: changeset 224 Directory symlinking now seems to work. M pygopherd/handlers/ZIP.py M testdata/symlinktest.zip commit 8a40c1eed4f3339ab4ba74ccb588d5f6ef3afbf8 Author: jgoerzen Date: Thu Mar 6 23:04:14 2003 +0100 /pygopherd/head: changeset 223 M testdata/symlinktest.zip commit ec5d102c7f121c54eac880cf365872c4b15ad4e6 Author: jgoerzen Date: Thu Mar 6 12:58:43 2003 +0100 /pygopherd/head: changeset 222 Fixed up tests to take note of new file symlinktest.zip M pygopherd/protocols/rfc1436Test.py A testdata/symlinktest.zip commit f36757f7722f57b1fbaa87ef5188a5f06e0f6376 Author: jgoerzen Date: Thu Mar 6 12:56:21 2003 +0100 /pygopherd/head: changeset 221 Removed debug code M pygopherd/handlers/ZIP.py M pygopherd/handlers/dir.py commit 8c289bd71404291e984d2188ccd5837149b1e1f7 Author: jgoerzen Date: Thu Mar 6 12:55:48 2003 +0100 /pygopherd/head: changeset 220 Added symlink capabilities to ZIP.py M pygopherd/handlers/ZIP.py M pygopherd/handlers/dir.py commit 9a02cba410953502abf591efb5dab52aa33a1188 Author: jgoerzen Date: Thu Mar 6 11:34:14 2003 +0100 /pygopherd/head: changeset 219 Added this. A testdata/ziptorture.zip commit 0f31a3a67498623cab629d94944a6414d60ddbaa Author: jgoerzen Date: Thu Mar 6 11:26:31 2003 +0100 /pygopherd/head: changeset 218 Noted recent changes M debian/changelog commit 0a43331d410b66a298c0db6344848cf5e4034f8b Author: jgoerzen Date: Thu Mar 6 11:25:19 2003 +0100 /pygopherd/head: changeset 217 All tests pass! M pygopherd/gopherentry.py M pygopherd/gopherentryTest.py M pygopherd/handlers/gophermap.py M pygopherd/protocols/rfc1436Test.py commit 4a04cd50c8eb6014b355f0810eea71be697bb26c Author: jgoerzen Date: Thu Mar 6 11:05:37 2003 +0100 /pygopherd/head: changeset 216 Removed some debug code M pygopherd/gopherentry.py commit d04e4895d7de65b2d6bc716d42cc432985394294 Author: jgoerzen Date: Thu Mar 6 11:02:14 2003 +0100 /pygopherd/head: changeset 215 More progress -- basic ZIP file now working! M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/ZIP.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/protocols/rfc1436Test.py M testdata/testdata.zip commit 5f5ca2d2254139a0e14c9b5db71e049c6973e436 Author: jgoerzen Date: Thu Mar 6 05:51:06 2003 +0100 /pygopherd/head: changeset 214 - This is the beginning of work to add a VFS system to PyGopherd. Changes: - Added runtestsgui, updated runtests - Modified all handlers to be VFS-aware - Implemented VFS_Real in base.py - Implemented VFS_ZIP in ZIP.py - Added ZIPHandler in ZIP.py - Updated HandlerMultiplexer to use VFS TODO: - Make ZIPHandler re-run handlermultiplexer and call it with all subsequent calls - Genericize ZIPHandler M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py A pygopherd/handlers/ZIP.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/html.py M pygopherd/handlers/mbox.py M pygopherd/handlers/pyg.py M pygopherd/handlers/scriptexec.py M pygopherd/handlers/virtual.py M pygopherd/protocols/rfc1436Test.py M runtests.py C080 pygopherd/protocols/__init__.py runtestsgui.py A testdata/testdata.zip A testdata/testdata2.zip commit 6c4854e65da3875c477e8925ceb063ee6404836b Author: jgoerzen Date: Wed Mar 5 03:46:27 2003 +0100 /pygopherd/head: changeset 213 Clarified license terms M Makefile M bin/pygopherd M debian/copyright M pygopherd.8 M pygopherd/GopherExceptions.py M pygopherd/GopherExceptionsTest.py M pygopherd/__init__.py M pygopherd/fileext.py M pygopherd/fileextTest.py M pygopherd/gopherentry.py M pygopherd/gopherentryTest.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/html.py M pygopherd/handlers/mbox.py M pygopherd/handlers/scriptexec.py M pygopherd/handlers/url.py M pygopherd/initialization.py M pygopherd/initializationTest.py M pygopherd/pipe.py M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/__init__.py M pygopherd/protocols/base.py M pygopherd/protocols/enhanced.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py M pygopherd/protocols/rfc1436.py M pygopherd/sighandlers.py M pygopherd/testutil.py M pygopherd/version.py M runtests.py M setup.py commit 73c7b37e33d962f3be49d5e4ae713d563090fd93 Author: jgoerzen Date: Sat Feb 22 06:05:52 2003 +0100 /pygopherd/head: changeset 212 Fixed gopherentry object for .gophermap files M pygopherd/handlers/gophermap.py commit ab6e6cb14196b3a1d1301da37e75f17de4c666bd Author: jgoerzen Date: Sat Feb 22 04:15:09 2003 +0100 /pygopherd/head: changeset 211 Added A TODO commit 1e2d37c0b9a540fc4b96665ac9319e5f01ebe166 Author: jgoerzen Date: Sat Feb 22 04:14:46 2003 +0100 /pygopherd/head: changeset 210 Added ability to serve up files ending in .gophermap as Gophermap files. M debian/changelog M pygopherd/handlers/gophermap.py commit d081b5f3b45593ad7ed29318c15b6075cf0617a8 Author: jgoerzen Date: Fri Aug 9 03:45:08 2002 +0100 /pygopherd/head: changeset 209 Preparing for 1.1.0 M debian/changelog M pygopherd/handlers/UMN.py M pygopherd/version.py commit 94ac1662359e3ae2d803c9d2ece527b14ea76f7d Author: jgoerzen Date: Fri Aug 9 03:39:10 2002 +0100 /pygopherd/head: changeset 208 Committed initial draft of the manual. A manual.html A manual.pdf A manual.ps A manual.txt M pygopherd.8 commit 93ceb617d7777dbbb64f2c5c9f210afd535a5f6d Author: jgoerzen Date: Fri Aug 9 01:32:57 2002 +0100 /pygopherd/head: changeset 207 Initial draft of manual. M pygopherd.8 commit d3e262ff42bd9474a403bf6dc8195ec1c616f70b Author: jgoerzen Date: Fri Aug 9 00:32:05 2002 +0100 /pygopherd/head: changeset 206 Began new manual that already incorporates the entire content of the old LyX one, so removed it. D doc/manual.lyx M pygopherd.8 commit 15bc6dad4726d4e7bf677f6d7b07010c5adb93cf Author: jgoerzen Date: Fri Aug 9 00:13:50 2002 +0100 /pygopherd/head: changeset 205 First stab at a manpage/manual -- initially imported from OfflineIMAP. M Makefile M debian/changelog M debian/docs A pygopherd.8 commit 7f5783955d4b08ee078eb477bb80ab113bd4783d Author: jgoerzen Date: Fri Aug 9 00:09:53 2002 +0100 /pygopherd/head: changeset 204 Moved pygopherd.py to bin and adjusted other files to reflect this C100 pygopherd.py bin/pygopherd M debian/rules M setup.py commit bb623c6d9e8ad013b5fb66cdfba75d1cb8e43b4a Author: jgoerzen Date: Thu Aug 8 23:57:54 2002 +0100 /pygopherd/head: changeset 203 Removed TODO file (now kept in bug-tracking system) D TODO M debian/changelog commit f73796c81d6aea17ca7f4408f8b27cc054b65f7c Author: jgoerzen Date: Thu Aug 8 22:46:15 2002 +0100 /pygopherd/head: changeset 202 Clarified relationship between ignorepatt and UMNDirHandler M conf/pygopherd.conf commit f2bd4c0edb19cae72154a0c20524e321d51d01cb Author: jgoerzen Date: Thu Aug 8 10:24:25 2002 +0100 /pygopherd/head: changeset 201 Commiting old changes M debian/changelog commit 3ac917054d9db54d7e3336ccc1c59d9151ad45f0 Author: jgoerzen Date: Tue Jul 23 19:04:37 2002 +0100 /pygopherd/head: changeset 200 Paranoia: chdir to our root. M pygopherd/initialization.py commit 83e43d3b904a1ce158319cf7f700cacf177b8076 Author: jgoerzen Date: Mon Jul 22 19:17:22 2002 +0100 /pygopherd/head: changeset 199 Added "advertisedport" feature. M conf/pygopherd.conf M pygopherd/initialization.py commit 13c1fa7cb16d4b3f800e68f28268a38f1c9598b3 Author: jgoerzen Date: Thu Jul 18 22:26:09 2002 +0100 /pygopherd/head: changeset 197 Updated for 1.0.0 release. M ChangeLog commit 13a2c1dbbd43d24c0e711c51ebb3766ad00e58f2 Author: jgoerzen Date: Thu Jul 18 22:16:35 2002 +0100 /pygopherd/head: changeset 196 Removed old .ex files. Set rules to install examples/* into Debian package. D debian/cron.d.ex D debian/emacsen-install.ex D debian/emacsen-remove.ex D debian/emacsen-startup.ex D debian/manpage.1.ex D debian/manpage.sgml.ex D debian/menu.ex D debian/preinst.ex D debian/prerm.ex M debian/rules D debian/watch.ex commit f9a4fb235e27d9b2e89c8aa577c3c6fc823f90dd Author: jgoerzen Date: Thu Jul 18 22:15:13 2002 +0100 /pygopherd/head: changeset 195 Fixed tests to work with Subversion, and made sure things that need to be set executable, are. M debian/changelog M pygopherd/GopherExceptionsTest.py M pygopherd/protocols/baseTest.py M pygopherd/protocols/rfc1436Test.py commit 99759f8fc643a380781b5ac188acafb18ad8ba03 Author: jgoerzen Date: Thu Jul 18 22:14:20 2002 +0100 /pygopherd/head: changeset 194 Fixed to keep dot directories out of the list. M pygopherd/handlers/UMN.py commit 6dbd396f414efc555dbbe05aeb9a37a209a1daa5 Author: jgoerzen Date: Thu Jul 18 22:05:50 2002 +0100 /pygopherd/head: changeset 193 A few last-minute tweaks M ChangeLog M Makefile M debian/changelog commit 745c3c3c1056fe61cd7b8da464c0279fb00b007b Author: jgoerzen Date: Thu Jul 18 07:05:05 2002 +0100 /pygopherd/head: changeset 192 Added URL type rewriter. Modified handler importing scheme to work nicer. Preparing for 1.0.0 release. M conf/pygopherd.conf M debian/changelog M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/html.py M pygopherd/handlers/mbox.py M pygopherd/handlers/pyg.py M pygopherd/handlers/scriptexec.py M pygopherd/handlers/url.py M pygopherd/version.py commit 61dc2d3e08e91eb17cce31ee6d792e58d2e86ad0 Author: jgoerzen Date: Thu Jul 18 06:33:07 2002 +0100 /pygopherd/head: changeset 191 Fixed gophermap info-only lines that have no tabs M debian/changelog M pygopherd/handlers/gophermap.py commit c705f5396f17360d66d81781e9cb5e4333ff63e1 Author: jgoerzen Date: Thu Jul 18 06:28:16 2002 +0100 /pygopherd/head: changeset 190 Initial move over to Subversion: mark appropriate files executable, new way of generating the ChangeLog. M ChangeLog M Makefile commit 4a9a82c2032693e5860cab526e8a7cc6a9403504 Author: jgoerzen Date: Wed Jul 3 05:43:05 2002 +0100 /pygopherd/head: changeset 188 Version 0.9.14 M ChangeLog M debian/changelog M pygopherd/initialization.py M pygopherd/version.py commit bfe20acb3277518f07480365c9e7cb61a79259f0 Author: jgoerzen Date: Wed Jul 3 03:34:02 2002 +0100 /pygopherd/head: changeset 187 Fixed a bug with HTML processing M debian/changelog M debian/rules M pygopherd/GopherExceptions.py M pygopherd/handlers/html.py M pygopherd/version.py commit 921bb2a2cff968753538da3f80b4701b4cd77b5a Author: jgoerzen Date: Wed Jul 3 03:04:06 2002 +0100 /pygopherd/head: changeset 186 Added signal handler mechanisms to foster orderly shutdowns. M ChangeLog M pygopherd/initialization.py A pygopherd/sighandlers.py commit bb0b4286dc9e41d117532807252403e7b850d0b7 Author: jgoerzen Date: Fri May 3 02:24:41 2002 +0100 /pygopherd/head: changeset 185 Amplified the exitfunc. M ChangeLog M pygopherd/initialization.py commit 8bf5f9667e660a4e3fbe237dade41c09482c1500 Author: jgoerzen Date: Fri May 3 02:13:45 2002 +0100 /pygopherd/head: changeset 184 Added support for detached operation and pidfile writing. M README M conf/pygopherd.conf M debian/changelog M debian/init.d M pygopherd/initialization.py M pygopherd/version.py commit cbe9fb538ee5960bda30a90669da00ee88e3c063 Author: jgoerzen Date: Thu May 2 03:45:47 2002 +0100 /pygopherd/head: changeset 183 Added a dep on a non-buggy python2.2 M ChangeLog M debian/control commit 6fe03454a778c83296111d75ce8431abfbb414b7 Author: jgoerzen Date: Sat Apr 27 02:18:10 2002 +0100 /pygopherd/head: changeset 182 HTTP protocol wasn't normalizing incoming selectors. Fixed. M pygopherd/protocols/base.py M pygopherd/protocols/http.py commit 70421fc9fa13ec53ba6299650fa4edcc6ada6b06 Author: jgoerzen Date: Fri Apr 19 10:39:29 2002 +0100 /pygopherd/head: changeset 181 Nicer display, sorted M pygfarm/dict.pyg commit 6f0b78ad0403767dfabad908435beed8c7d82193 Author: jgoerzen Date: Fri Apr 19 05:01:31 2002 +0100 /pygopherd/head: changeset 180 *** empty log message *** M debian/changelog M debian/control M pygfarm/dict.pyg M pygopherd/version.py commit a6f2d651c7c1effcd7c3d23fad7d762403fb529c Author: jgoerzen Date: Fri Apr 19 04:22:38 2002 +0100 /pygopherd/head: changeset 179 Added pygfarm package for Debian. M Makefile D debian/README.Debian M debian/control A debian/pygfarm.README.Debian A debian/pygfarm.dirs M debian/rules D pygfarm/foo.py commit 396b0196eccf875d0dce58cadb5013dd87b28433 Author: jgoerzen Date: Fri Apr 19 04:13:29 2002 +0100 /pygopherd/head: changeset 178 Added support to HTTP for search requests. M conf/pygopherd.conf M pygopherd/protocols/http.py commit f503004d8f0f748189a4b909bc4f815acf67b6f0 Author: jgoerzen Date: Fri Apr 19 03:57:33 2002 +0100 /pygopherd/head: changeset 177 Fixed gopher-dir to gopher-menu M pygfarm/dict.pyg M pygopherd/protocols/http.py commit 09335ca91c880df0d44b2b9f922c7ecc2c47da3e Author: jgoerzen Date: Fri Apr 19 03:49:52 2002 +0100 /pygopherd/head: changeset 176 Updated. M pygfarm/dict.pyg commit 3d09219c8511208698ff716fdec8dc71b8ca545f Author: jgoerzen Date: Fri Apr 19 03:12:30 2002 +0100 /pygopherd/head: changeset 175 All except DBINFO working now. M pygfarm/dict.pyg commit 1bf57c4157a8c7cc4a0426b3da873302bfc370fa Author: jgoerzen Date: Fri Apr 19 03:00:20 2002 +0100 /pygopherd/head: changeset 174 Updated -- more features and bugfixes M pygfarm/dict.pyg commit f8cee63225dc1d851df27a39aaf472a864683183 Author: jgoerzen Date: Fri Apr 19 02:51:02 2002 +0100 /pygopherd/head: changeset 173 All except Match is now working. M pygfarm/dict.pyg commit ed87ca140c9fc1ac54b7e92f4951e0765bd845ae Author: jgoerzen Date: Fri Apr 19 02:42:49 2002 +0100 /pygopherd/head: changeset 172 Some various bugfixes M pygfarm/dict.pyg commit 3d7a07fa02cd90f39179257fb4c1ba7a53438e51 Author: jgoerzen Date: Thu Apr 18 13:31:21 2002 +0100 /pygopherd/head: changeset 171 *** empty log message *** M pygfarm/dict.pyg commit 039d820eaa01cbbd235ea302ed88410209d1b697 Author: jgoerzen Date: Thu Apr 18 13:22:29 2002 +0100 /pygopherd/head: changeset 170 Updated, working better. M pygfarm/dict.pyg commit e7d1f2920597c2507e5e018c4be2aad968da3ce0 Author: jgoerzen Date: Thu Apr 18 09:08:11 2002 +0100 /pygopherd/head: changeset 169 Updated. M pygfarm/dict.pyg A pygfarm/foo.py commit 19d28a4119c90d89047d793e8ad10eac6a70fedf Author: jgoerzen Date: Thu Apr 18 06:31:25 2002 +0100 /pygopherd/head: changeset 168 *** empty log message *** M pygfarm/dict.pyg commit db1d3778d807ef85c932fe5a75bebfeeeb4f0f42 Author: jgoerzen Date: Thu Apr 18 06:20:35 2002 +0100 /pygopherd/head: changeset 167 *** empty log message *** A pygfarm/dict.pyg commit eecfa67abb6ddffa3d82036bc770614c013de28d Author: jgoerzen Date: Thu Apr 18 01:26:57 2002 +0100 /pygopherd/head: changeset 166 Updated -- use normpath for relative links. M pygopherd/handlers/UMN.py commit a1b03bc72a5792bf571f2e5bfc12775fa4ee3a66 Author: jgoerzen Date: Wed Apr 17 05:37:43 2002 +0100 /pygopherd/head: changeset 165 Made sure noabstract stuff works. M pygopherd/protocols/rfc1436Test.py commit 5ebfe213bbb3616a17a37b8f5454adde89ccf257 Author: jgoerzen Date: Wed Apr 17 05:32:41 2002 +0100 /pygopherd/head: changeset 164 Enhanced. M pygopherd/protocols/rfc1436Test.py commit 56334912d5d73d634718555f8b875715d554ed30 Author: jgoerzen Date: Wed Apr 17 02:11:59 2002 +0100 /pygopherd/head: changeset 163 Fixed entries handling after new prepare. M pygopherd/handlers/gophermap.py commit 03b852be6ad20c0a325a22f8c623680faf6afe4d Author: jgoerzen Date: Wed Apr 17 02:06:42 2002 +0100 /pygopherd/head: changeset 162 A test fix. M pygopherd/protocols/rfc1436Test.py commit 427a9b7813fef330e2f8ced30baa26fa060b6a23 Author: jgoerzen Date: Wed Apr 17 01:45:20 2002 +0100 /pygopherd/head: changeset 161 Fixed a bug in HTTP handler that was adding an extra (reported by Robert Hahn) Fixed a bug in mbox.py affecting both mailbox handlers -- after the new directory architecture, the prepare in the child classes was not properly updated. M pygopherd/handlers/UMN.py M pygopherd/handlers/mbox.py M pygopherd/protocols/http.py commit 8d094d3c8b82dfe3e35aa7d29018dfb598edeb0a Author: jgoerzen Date: Tue Apr 16 11:21:01 2002 +0100 /pygopherd/head: changeset 160 Updated. M ChangeLog M debian/changelog A pygopherd/protocols/rfc1436Test.py M pygopherd/version.py M runtests.py commit b87048525a968741bd74d288e6df3bd06123ef95 Author: jgoerzen Date: Tue Apr 16 08:08:35 2002 +0100 /pygopherd/head: changeset 159 Finished baseTest and passes all tests. M pygopherd/GopherExceptionsTest.py M pygopherd/protocols/base.py M pygopherd/protocols/baseTest.py M pygopherd/testutil.py commit 886bf95df37a01fd26d5d6cf9184e6d045145ef4 Author: jgoerzen Date: Tue Apr 16 07:37:08 2002 +0100 /pygopherd/head: changeset 158 Beginnings of baseTest. M pygopherd/protocols/__init__.py M pygopherd/protocols/base.py A pygopherd/protocols/baseTest.py M runtests.py commit 52b7e81071ec8fa48baf41931d13ef0d8f8e303a Author: jgoerzen Date: Tue Apr 16 07:20:57 2002 +0100 /pygopherd/head: changeset 157 Added ProtocolMultiplexerTest M Makefile M pygopherd/protocols/ProtocolMultiplexerTest.py M pygopherd/testutil.py commit f7084528c83e04bdb031f76ef7f567418a61361b Author: jgoerzen Date: Tue Apr 16 06:58:16 2002 +0100 /pygopherd/head: changeset 156 Added ProtocolMultiplexerTest A pygopherd/protocols/ProtocolMultiplexerTest.py M pygopherd/protocols/__init__.py M runtests.py commit 5880e0591344159e3220723ac3d8c23d444b3138 Author: jgoerzen Date: Tue Apr 16 06:44:53 2002 +0100 /pygopherd/head: changeset 155 Added pipeTest. M pygopherd/__init__.py M pygopherd/gopherentryTest.py M pygopherd/pipe.py A pygopherd/pipeTest.py M runtests.py A testdata/pygopherd/pipetest.sh A testdata/pygopherd/pipetestdata commit be2e1d6455d3fcb7abe8afde4a51499214d9b5a7 Author: jgoerzen Date: Tue Apr 16 06:09:48 2002 +0100 /pygopherd/head: changeset 154 Updated for new abstract tests A testdata/.abstract A testdata/testfile.txt.gz.abstract commit 7e7c6e4b66db635d10ea4fd210b635278548378f Author: jgoerzen Date: Tue Apr 16 06:03:01 2002 +0100 /pygopherd/head: changeset 153 Many updates to abstract support M conf/pygopherd.conf M pygopherd/GopherExceptionsTest.py M pygopherd/gopherentry.py M pygopherd/handlers/gophermap.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py commit de40dedcfd26782bb6cce4fd445603ee0d6a8438 Author: jgoerzen Date: Tue Apr 16 04:55:19 2002 +0100 /pygopherd/head: changeset 152 Added the ability to read block contents from the filesystem. M conf/pygopherd.conf M pygopherd/gopherentry.py commit 6af0ab9a492a73de4f8d6287b19fe107405ba143 Author: jgoerzen Date: Tue Apr 16 02:21:09 2002 +0100 /pygopherd/head: changeset 151 Added beginnings of support for Abstract and other info. M pygopherd/handlers/UMN.py M pygopherd/protocols/gopherp.py commit 376ea5d394b5d2f1522d00a31b74d7c952ee4242 Author: jgoerzen Date: Tue Apr 16 01:37:22 2002 +0100 /pygopherd/head: changeset 150 Redid the directory handling mechanism. Now, handlers define isdir() and getdirlist(). Protocols ask for a list of all entries in the directory, rather than having the handler do a callback for each entry. M pygopherd/gopherentry.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/mbox.py M pygopherd/handlers/pyg.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py commit 48ad427df6a2a3f2f55a98bd3e73996a331bef5a Author: jgoerzen Date: Mon Apr 15 14:59:13 2002 +0100 /pygopherd/head: changeset 149 Updated. M ChangeLog commit 876843f75893ab9a820dba3499c2a2388d132a8b Author: jgoerzen Date: Mon Apr 15 14:34:53 2002 +0100 /pygopherd/head: changeset 148 Fixed a bug with handling empty Path= lines. Thanks to David Allen for identifying this one. M pygopherd/handlers/UMN.py commit 7cc8033071c465629bf20b2ba46899cf637f6959 Author: jgoerzen Date: Sat Apr 13 07:26:46 2002 +0100 /pygopherd/head: changeset 147 Miscellany comments and stuff M pygopherd/handlers/base.py commit 1c8d8f0d382e98db4b8c981e284b73f5908a714e Author: jgoerzen Date: Sat Apr 13 03:46:54 2002 +0100 /pygopherd/head: changeset 146 Updated for 0.9.4 M debian/changelog M pygopherd/version.py commit f7db78da7a0dbc43c899de58eb9fc037abb51a2d Author: jgoerzen Date: Sat Apr 13 03:39:56 2002 +0100 /pygopherd/head: changeset 145 Updated. M ChangeLog M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/base.py M pygopherd/handlers/file.py M pygopherd/handlers/pyg.py M pygopherd/handlers/url.py M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/http.py commit 18f5205023c7e1ceaf17e6237d1ac2ad558deec1 Author: jgoerzen Date: Fri Apr 12 14:13:33 2002 +0100 /pygopherd/head: changeset 144 Fixed bug with rendering URLs. M pygopherd/protocols/http.py commit d6fe569b24b8504e1c606f80074c6dd1b99c7af1 Author: jgoerzen Date: Fri Apr 12 14:07:52 2002 +0100 /pygopherd/head: changeset 143 Forgot to call renderdirstart and renderdirend. M pygopherd/handlers/gophermap.py commit f70aeb995c742f11684a137315c92e5669ea6e69 Author: jgoerzen Date: Fri Apr 12 08:41:40 2002 +0100 /pygopherd/head: changeset 142 More bugfixes. M ChangeLog M debian/changelog M pygopherd/protocols/http.py M pygopherd/version.py commit d652cf49e8b52b51c0f3d017f796ebc82476f6ee Author: jgoerzen Date: Fri Apr 12 08:24:21 2002 +0100 /pygopherd/head: changeset 141 Fixed an initialization problem in testutil that could prevent the system from starting up properly. Fixed URL to gopher downloads in pygopherd.conf. M conf/pygopherd.conf M pygopherd/testutil.py commit 85e9d4b953d7f093d60472e428484da671543f4d Author: jgoerzen Date: Fri Apr 12 08:16:59 2002 +0100 /pygopherd/head: changeset 140 Added the ability to http to put a configurable spiel at the top of each page. Added version.py for stuff to find info about the software. M ChangeLog M Makefile M conf/pygopherd.conf M debian/changelog M debian/control M pygopherd/__init__.py A pygopherd/loggerTest.py M pygopherd/protocols/http.py C055 debian/copyright pygopherd/version.py M runtests.py M setup.py commit 6465d3963b04a1ba0721b403276f63294415e128 Author: jgoerzen Date: Fri Apr 12 06:32:37 2002 +0100 /pygopherd/head: changeset 139 Geturl now handles URL: patterns M pygopherd/gopherentry.py M pygopherd/gopherentryTest.py M pygopherd/handlers/url.py commit b0b2e582d6a92a56a9d593fd85c02549a6f931c8 Author: jgoerzen Date: Fri Apr 12 06:22:59 2002 +0100 /pygopherd/head: changeset 138 Gopherentrytest almost finished. Fixed some bugs that test illuminated. Updated testutil. M pygopherd/gopherentry.py M pygopherd/gopherentryTest.py commit 0f76fd71df5aa423b77d65758fe9154b009a99ed Author: jgoerzen Date: Fri Apr 12 05:25:24 2002 +0100 /pygopherd/head: changeset 137 Added an encoded file. A testdata/README A testdata/testarchive.tar A testdata/testarchive.tar.gz A testdata/testarchive.tgz A testdata/testfile.txt.gz commit fb0df0f1ef32a6ad9ed5aadadfd19eab7579c748 Author: jgoerzen Date: Fri Apr 12 05:01:04 2002 +0100 /pygopherd/head: changeset 136 Initial add of the gopherentryTest M pygopherd/__init__.py A pygopherd/gopherentryTest.py M pygopherd/testutil.py M runtests.py commit 4b0715190513bbd9b3ac4786252dda2fda53c39a Author: jgoerzen Date: Fri Apr 12 04:42:36 2002 +0100 /pygopherd/head: changeset 135 Always set the root to testroot M Makefile M pygopherd/testutil.py A testdata/testfile.txt commit e4dbb3b57c5353f46750add2771cfedcf5d37754 Author: jgoerzen Date: Fri Apr 12 03:41:05 2002 +0100 /pygopherd/head: changeset 134 Added the fileext test. M conf/pygopherd.conf M pygopherd/GopherExceptionsTest.py M pygopherd/__init__.py C061 runtests.py pygopherd/fileextTest.py M pygopherd/initializationTest.py M pygopherd/testutil.py M runtests.py commit 3ea39205e7a49085bb7518b9a6b5d74b1db515ff Author: jgoerzen Date: Fri Apr 12 03:33:45 2002 +0100 /pygopherd/head: changeset 133 Added more tests, test utilities, etc. M pygopherd/GopherExceptionsTest.py M pygopherd/__init__.py M pygopherd/initialization.py M pygopherd/initializationTest.py A pygopherd/testutil.py commit bed2ecf42e696fd2d1330c7baffb8e110ad03807 Author: jgoerzen Date: Fri Apr 12 02:47:14 2002 +0100 /pygopherd/head: changeset 132 Added more tests. Made logger capable of logging to non-stdout sources. M conf/pygopherd.conf M pygopherd/GopherExceptions.py A pygopherd/GopherExceptionsTest.py M pygopherd/__init__.py M pygopherd/logger.py M runtests.py commit a9eb4966c5212e2fba39f23491653d88aaf0f8ec Author: jgoerzen Date: Fri Apr 12 01:58:06 2002 +0100 /pygopherd/head: changeset 131 Added a sanity check to HandlerMultiplexer. Handle a special interface bind request in initialization.py and conf/pygopherd.conf. M conf/pygopherd.conf M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/initialization.py commit 2a187f13854509e34adabe5a76de51bec662c376 Author: jgoerzen Date: Fri Apr 12 01:49:56 2002 +0100 /pygopherd/head: changeset 130 Security: block ./ and ../ M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/base.py commit adcffb1bef981ffc50f43c3dbe21666fa3e5d0d6 Author: jgoerzen Date: Fri Apr 12 01:07:28 2002 +0100 /pygopherd/head: changeset 129 Added. A pygopherd/initializationTest.py commit 5fefac21744fb50e577d438e5ab12f0223a055f2 Author: jgoerzen Date: Thu Apr 11 15:05:05 2002 +0100 /pygopherd/head: changeset 128 Added real tests. M pygopherd/initialization.py commit c2e4b3203b5fd4a7f223270925b5bda225c5e9db Author: jgoerzen Date: Thu Apr 11 14:31:44 2002 +0100 /pygopherd/head: changeset 127 Added initial testing infrastructure. M pygopherd.py M pygopherd/__init__.py C073 pygopherd.py runtests.py commit 08ffd9920a7bef034e11da4ca475e0af4b9c8126 Author: jgoerzen Date: Thu Apr 11 14:12:29 2002 +0100 /pygopherd/head: changeset 126 Redid initialization system -- makes it easier for tests. M conf/pygopherd.conf M pygopherd.py M pygopherd/__init__.py A pygopherd/initialization.py commit ecd353721c15e98514bc59f7f261119007a70c8b Author: jgoerzen Date: Thu Apr 11 13:23:24 2002 +0100 /pygopherd/head: changeset 125 Updated M ChangeLog M debian/changelog commit 7c8424b43ef85cc10adfc9ae6f64a4bc70a45cb7 Author: jgoerzen Date: Thu Apr 11 11:29:58 2002 +0100 /pygopherd/head: changeset 124 Added the ability to log backtraces in more situations. Fixed a bug in mbox preventing folders from working. M conf/pygopherd.conf M pygopherd.py M pygopherd/GopherExceptions.py M pygopherd/handlers/mbox.py commit 25375c05e872baa2a5f1f66a1b8b17982e5125f7 Author: jgoerzen Date: Thu Apr 11 11:23:39 2002 +0100 /pygopherd/head: changeset 123 Fixed a software bug. M pygopherd/handlers/UMN.py commit 41d7d6092552e860c84c073c7be2da5720ce49a9 Author: jgoerzen Date: Thu Apr 11 08:30:11 2002 +0100 /pygopherd/head: changeset 122 VERSION 0.9.0 RELEASED M ChangeLog commit a91a974330516993ea41219e458319df030d9007 Author: jgoerzen Date: Thu Apr 11 08:02:31 2002 +0100 /pygopherd/head: changeset 121 Fixed some more bugs: don't crash if we have no perms to create a cache file, handle relative Path= lines correctly. M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit 06c505cf16d48dc731449d915308b0025a10daa5 Author: jgoerzen Date: Thu Apr 11 07:56:45 2002 +0100 /pygopherd/head: changeset 120 Fixed a bug with type=X M pygopherd/handlers/UMN.py commit 66530b99ce64e77e15095470c8e0e5d8fbe385c0 Author: jgoerzen Date: Thu Apr 11 07:39:53 2002 +0100 /pygopherd/head: changeset 119 Additional bugfixes and enhancements M pygopherd.py M pygopherd/gopherentry.py M pygopherd/handlers/file.py commit 2d420ff8f6d95e36e07f9218f081be9fa281a895 Author: jgoerzen Date: Thu Apr 11 07:22:28 2002 +0100 /pygopherd/head: changeset 118 Added decompresspatt support. M conf/pygopherd.conf M pygopherd/handlers/file.py commit 7da23d3b2c3fd4420c964f0e38e8ee8e34182a84 Author: jgoerzen Date: Thu Apr 11 07:13:16 2002 +0100 /pygopherd/head: changeset 117 Additional fixes for extension and encoding support. M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/file.py commit 62b0069a7a93f87ec2b8c2309a012dcc3f4b4447 Author: jgoerzen Date: Thu Apr 11 07:05:13 2002 +0100 /pygopherd/head: changeset 116 More updates and features with extensions and stuff. M conf/pygopherd.conf M pygopherd/fileext.py M pygopherd/handlers/UMN.py M pygopherd/handlers/file.py M pygopherd/protocols/rfc1436.py commit 689f4e9622b40cea7cababa059f800edd34e1f2b Author: jgoerzen Date: Thu Apr 11 06:43:09 2002 +0100 /pygopherd/head: changeset 115 Modified encoding handling: default is to now set application/octet- stream of there is any encoding UNLESS the CompressedFileHandler is used. M pygopherd/gopherentry.py M pygopherd/handlers/file.py commit 27bba8e6d685f5beec3020bd7b38a91c1d3431ca Author: jgoerzen Date: Thu Apr 11 06:26:50 2002 +0100 /pygopherd/head: changeset 114 Renamed changelog target M Makefile commit 966c35203f7220d06e54cba1eb06d1bfea1a9503 Author: jgoerzen Date: Thu Apr 11 06:19:16 2002 +0100 /pygopherd/head: changeset 113 Added many features: The CompressedFileHandler Pipe support etc M ChangeLog M conf/pygopherd.conf M pygopherd/__init__.py M pygopherd/handlers/file.py M pygopherd/handlers/scriptexec.py C052 pygopherd/protocols/ProtocolMultiplexer.py pygopherd/pipe.py commit 621b251f5f7a228d74771e949e2a6acc18afc826 Author: jgoerzen Date: Thu Apr 11 05:38:24 2002 +0100 /pygopherd/head: changeset 112 Added smart file extension stripping for UMN dir. M conf/pygopherd.conf M pygopherd.py M pygopherd/__init__.py A pygopherd/fileext.py M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit 4d8748e8e9eaf009740e8b67a7fe6d8219500631 Author: jgoerzen Date: Thu Apr 11 04:15:22 2002 +0100 /pygopherd/head: changeset 111 Added code to strip off an extension in UMN Dirhandler. Other Debian enhancements. M debian/changelog A debian/examples M debian/postinst R075 debian/postrm.ex debian/postrm M pygopherd/handlers/UMN.py commit 86690f0e62e58f9720acfa84a5ebf7b038230c59 Author: jgoerzen Date: Thu Apr 11 04:03:36 2002 +0100 /pygopherd/head: changeset 110 Updated pygopher'd path. A examples/gophermap commit edcec50f296d88b8f4c5c4d1040b5a442edd25a0 Author: jgoerzen Date: Thu Apr 11 03:27:39 2002 +0100 /pygopherd/head: changeset 109 Miscellaneous other fixes. M debian/control M debian/init.d M pygopherd.py M pygopherd/handlers/gophermap.py commit fec771028cfc79461e53753ad11e4f98d099897f Author: jgoerzen Date: Thu Apr 11 03:07:15 2002 +0100 /pygopherd/head: changeset 108 Modified to do some more checking, to permit colon-separated MIME types, etc. M ChangeLog M conf/pygopherd.conf M debian/init.d M debian/postinst M debian/rules M pygopherd.py commit 22e316ff1638a53d8904bba47550cd09c81940c1 Author: jgoerzen Date: Thu Apr 11 02:41:53 2002 +0100 /pygopherd/head: changeset 107 Made setup.py include handlers and protocols too. Updated debian code. M ChangeLog M Makefile M debian/copyright M debian/docs M debian/rules M setup.py commit 1c0f8d50af3b57f7f4ee255373b919d8689fb2b9 Author: jgoerzen Date: Thu Apr 11 02:27:03 2002 +0100 /pygopherd/head: changeset 106 Updated. M README M debian/control M debian/rules M setup.py commit a04cba99b1685b7d67fdf30fa888b3a7ba75d8cc Author: jgoerzen Date: Thu Apr 11 02:20:43 2002 +0100 /pygopherd/head: changeset 105 Added ability to specify aliased server name. M conf/pygopherd.conf M pygopherd.py commit 423c46296d0ea40a09673b6ea57f07321598f4b9 Author: jgoerzen Date: Thu Apr 11 02:13:16 2002 +0100 /pygopherd/head: changeset 104 Many modifications to permit system-wide installations, Debian package support, etc. A ChangeLog M Makefile A README M TODO M conf/pygopherd.conf M debian/changelog A debian/conffiles D debian/conffiles.ex M debian/control M debian/copyright R088 debian/init.d.ex debian/init.d A debian/postinst D debian/postinst.ex M debian/rules M setup.py commit 0b0b921a4a8728e9189814bf14a19ea7b1a862f4 Author: jgoerzen Date: Thu Apr 11 01:10:58 2002 +0100 /pygopherd/head: changeset 103 Imported debian/ directory. A debian/README.Debian A debian/changelog A debian/conffiles.ex A debian/control A debian/copyright A debian/cron.d.ex A debian/dirs A debian/docs A debian/emacsen-install.ex A debian/emacsen-remove.ex A debian/emacsen-startup.ex A debian/ex.package.doc-base A debian/init.d.ex A debian/manpage.1.ex A debian/manpage.sgml.ex A debian/menu.ex A debian/postinst.ex A debian/postrm.ex A debian/preinst.ex A debian/prerm.ex A debian/rules A debian/watch.ex C062 pygopherd/__init__.py setup.py commit f6cb2b1a28b128c9a19be31987f21e56d90b0101 Author: jgoerzen Date: Thu Apr 11 00:57:14 2002 +0100 /pygopherd/head: changeset 102 Now cleans up jython .class files M Makefile commit 6ecaeb5a3ef188231ed424078dabbec1cbb7f7fe Author: jgoerzen Date: Wed Apr 10 14:31:15 2002 +0100 /pygopherd/head: changeset 101 More security enhancements and stuff. M conf/pygopherd.conf M pygopherd.py M pygopherd/handlers/scriptexec.py commit 44bceb83aaca69e6a0c7d275d14fe5f474866a4d Author: jgoerzen Date: Wed Apr 10 13:44:34 2002 +0100 /pygopherd/head: changeset 100 Added logging support M conf/pygopherd.conf M pygopherd.py M pygopherd/GopherExceptions.py M pygopherd/__init__.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/mbox.py A pygopherd/logger.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py commit 50ff42109585edc361a9b658455bc694803a92ca Author: jgoerzen Date: Wed Apr 10 08:26:41 2002 +0100 /pygopherd/head: changeset 99 Fixed an error with searchrequest support. M conf/pygopherd.conf M pygopherd/handlers/pyg.py commit 56714a0b090edf421d44bd472fb596e79008c001 Author: jgoerzen Date: Wed Apr 10 08:09:48 2002 +0100 /pygopherd/head: changeset 98 Removed outdated import of "signal" M pygopherd.py commit 4502b7f99693c97eb6d1a97f1de15ef0136f6c0d Author: jgoerzen Date: Wed Apr 10 07:42:31 2002 +0100 /pygopherd/head: changeset 97 Added searchrequest capabilities. M conf/pygopherd.conf M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/scriptexec.py M pygopherd/handlers/virtual.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/rfc1436.py commit c8ae7d8fd69e745a5f7b6343f9d414f48a85e96d Author: jgoerzen Date: Wed Apr 10 07:18:55 2002 +0100 /pygopherd/head: changeset 96 More updates for vfolder rename. Added scriptexec capability. M conf/pygopherd.conf M pygopherd.py M pygopherd/handlers/__init__.py M pygopherd/handlers/mbox.py M pygopherd/handlers/pyg.py A pygopherd/handlers/scriptexec.py M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/base.py commit a497992c8c00bd81b14e87ca2e8fcd3fd537516f Author: jgoerzen Date: Wed Apr 10 06:45:52 2002 +0100 /pygopherd/head: changeset 95 Renamed vfolder to virtual M pygopherd/handlers/__init__.py M pygopherd/handlers/mbox.py M pygopherd/handlers/pyg.py R097 pygopherd/handlers/vfolder.py pygopherd/handlers/virtual.py commit 3e7986e6294b8f5d4c151c465ebf522f406a59cd Author: jgoerzen Date: Tue Apr 9 07:36:27 2002 +0100 /pygopherd/head: changeset 94 Updates. M conf/pygopherd.conf M pygopherd/handlers/__init__.py M pygopherd/handlers/mbox.py A pygopherd/handlers/pyg.py M pygopherd/handlers/vfolder.py commit d503a0b27b5b7e20184c1b945db9ee81f0fbf871 Author: jgoerzen Date: Tue Apr 9 06:22:12 2002 +0100 /pygopherd/head: changeset 93 Updates with the vfolder. M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/mbox.py A pygopherd/handlers/vfolder.py commit 552489ea9aab2bba5b9941cf901c5289981b768f Author: jgoerzen Date: Sun Apr 7 09:08:21 2002 +0100 /pygopherd/head: changeset 92 Updated for module moving. M pygopherd.py C089 pygopherd/protocols/__init__.py pygopherd/__init__.py M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/html.py M pygopherd/handlers/mbox.py M pygopherd/handlers/url.py M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/base.py M pygopherd/protocols/enhanced.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py M pygopherd/protocols/rfc1436.py commit a770ca62ac2f98e087ebe47643efa7bbb48610f6 Author: jgoerzen Date: Sun Apr 7 08:31:06 2002 +0100 /pygopherd/head: changeset 91 Added. A Makefile commit 9a97c2dd8e0095fbc41825a5a1b54039021344e5 Author: jgoerzen Date: Sat Apr 6 15:25:26 2002 +0100 /pygopherd/head: changeset 90 *** empty log message *** M doc/manual.lyx commit be201ffdf1badc37b65fbc6f14a141b215571000 Author: jgoerzen Date: Sat Apr 6 11:55:50 2002 +0100 /pygopherd/head: changeset 89 Added. A doc/manual.lyx commit 05c63a51abdaff1532d1d9568afdb53d0b0f2c45 Author: jgoerzen Date: Sat Apr 6 09:23:55 2002 +0100 /pygopherd/head: changeset 88 Added directory caching ability. M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py commit 077327ebd6fac0f7c4348eaf14a7fb73a75a2efa Author: jgoerzen Date: Sat Apr 6 08:59:56 2002 +0100 /pygopherd/head: changeset 87 Performance enhancements after profiling M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/html.py M pygopherd/handlers/mbox.py commit bcb2b1db8223460aa7238746f2a23e0bed1e5e7c Author: jgoerzen Date: Sat Apr 6 08:09:58 2002 +0100 /pygopherd/head: changeset 86 Performance: made mapping a module instead of a class variable. M pygopherd/gopherentry.py commit f971e2458f7e782ec3671169f6b7f3ed69da2944 Author: jgoerzen Date: Sat Apr 6 07:51:30 2002 +0100 /pygopherd/head: changeset 85 Typo fix M pygopherd/handlers/base.py commit f8aea11dec632a789109eee21f5a7341c2b73979 Author: jgoerzen Date: Sat Apr 6 07:39:06 2002 +0100 /pygopherd/head: changeset 84 *** empty log message *** M pygopherd/handlers/base.py M pygopherd/handlers/mbox.py commit 15a20750a5c18fba5a9f6a2ad3fd6182ba7bff1f Author: jgoerzen Date: Sat Apr 6 07:24:11 2002 +0100 /pygopherd/head: changeset 83 More work on the mbox handler. Say that we don't support gopher+ because UMN hates size-less stuff. Bah. Reverted gopherp : behavior. It was right before, UMN is fussy. M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/__init__.py M pygopherd/handlers/html.py A pygopherd/handlers/mbox.py M pygopherd/protocols/gopherp.py commit d1fa31a0619d62d3a11ce77b1c826959c2ce71f8 Author: jgoerzen Date: Sat Apr 6 07:13:52 2002 +0100 /pygopherd/head: changeset 82 Only put colon on a VIEWS line if there is size information coming. M pygopherd/protocols/gopherp.py commit 3ff687792e48d0f915419597bd108f58ed9024d5 Author: jgoerzen Date: Sat Apr 6 05:43:00 2002 +0100 /pygopherd/head: changeset 81 Split HTML title handler out of UMN.py into html.py M conf/pygopherd.conf M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/__init__.py A pygopherd/handlers/html.py commit f850185e72a8b2ac7b3c8cbb98cf07c47b9fc35a Author: jgoerzen Date: Sat Apr 6 04:58:30 2002 +0100 /pygopherd/head: changeset 80 Added copyright notices to all files. M pygopherd/GopherExceptions.py M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/url.py M pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/__init__.py M pygopherd/protocols/base.py M pygopherd/protocols/enhanced.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/http.py M pygopherd/protocols/rfc1436.py commit aec6b4997a404b26c4558fb76fccbef6d1e7e38f Author: jgoerzen Date: Sat Apr 6 04:51:59 2002 +0100 /pygopherd/head: changeset 79 Added HTML handler support. M conf/pygopherd.conf M pygopherd/handlers/UMN.py commit db2fbc3805db43622dfdcd2e03d02a5e0ba60955 Author: jgoerzen Date: Sat Apr 6 04:12:49 2002 +0100 /pygopherd/head: changeset 78 Added some comments and moved miscellaneous functions into the UMNDirHandler. M pygopherd/handlers/UMN.py commit a96aa81b468a70fd663cf68de4e6a7580f1ee721 Author: jgoerzen Date: Sat Apr 6 03:32:39 2002 +0100 /pygopherd/head: changeset 77 Removed \t+ adding to gopher0 dirstrings. This is done in the rfc module already. M pygopherd/protocols/gopherp.py commit 140f35ef33990ee15921be6c33be5c74499c8b2c Author: jgoerzen Date: Sat Apr 6 03:27:33 2002 +0100 /pygopherd/head: changeset 76 Modified to use the getentry() from each handler in the dirhandler. Modified to indicate in each entry whether gopher+ is supported by that entry. Modified rfc1436 to only indicate + for those entries where this is true. M conf/pygopherd.conf M pygopherd/gopherentry.py M pygopherd/handlers/dir.py M pygopherd/protocols/rfc1436.py commit 509c114b3fd6cee518d0bf748cffc4b14cdbb3e8 Author: jgoerzen Date: Fri Apr 5 09:05:22 2002 +0100 /pygopherd/head: changeset 75 Added code to strip off trailing slashes in links. M pygopherd/handlers/UMN.py commit f560110b1588aef53b7bf27993e53fb12754d606 Author: jgoerzen Date: Fri Apr 5 08:55:57 2002 +0100 /pygopherd/head: changeset 74 Added handling of UMN type X M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit 0540391f946abe36ca6f265ba4cd24860f90fb47 Author: jgoerzen Date: Fri Apr 5 08:49:51 2002 +0100 /pygopherd/head: changeset 73 More HTTP updates. M conf/pygopherd.conf M pygopherd/protocols/http.py commit 453aa2103912c47053d73160c48a7adafec4ff0b Author: jgoerzen Date: Fri Apr 5 08:36:58 2002 +0100 /pygopherd/head: changeset 72 Added icon support to HTTP protocol. M conf/pygopherd.conf M pygopherd/handlers/__init__.py M pygopherd/protocols/http.py commit 9dd2ddbcd16a2668c6fc03678768dc67ace464a2 Author: jgoerzen Date: Fri Apr 5 08:20:27 2002 +0100 /pygopherd/head: changeset 71 Updated. M conf/pygopherd.conf M pygopherd/handlers/__init__.py M pygopherd/protocols/http.py commit 5e878746e47a8d6ef58fb85fe59790e23775e15a Author: jgoerzen Date: Fri Apr 5 07:51:48 2002 +0100 /pygopherd/head: changeset 70 Added .cap file handling. M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit e75fdd4173e20b13d3626bef585f1a9eb4c3d2b3 Author: jgoerzen Date: Fri Apr 5 07:37:37 2002 +0100 /pygopherd/head: changeset 69 UMN seems to be working now! M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit 704e6b1c0257e93e65794a81eab12481d2718151 Author: jgoerzen Date: Fri Apr 5 07:27:57 2002 +0100 /pygopherd/head: changeset 68 Various runtime fixes! M conf/pygopherd.conf M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/UMN.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py commit 0ad4be40b0a4ca93830532d4a254e6c973c82345 Author: jgoerzen Date: Fri Apr 5 06:39:02 2002 +0100 /pygopherd/head: changeset 67 Updated. M pygopherd/handlers/UMN.py M pygopherd/handlers/dir.py commit c393aaedb5a57b72e56751790f465da3916ddd1e Author: jgoerzen Date: Fri Apr 5 06:29:56 2002 +0100 /pygopherd/head: changeset 66 More updates. M pygopherd/handlers/UMN.py commit bdfbc40a23342984e3a9b2ba5d6d893a067a3375 Author: jgoerzen Date: Fri Apr 5 06:12:39 2002 +0100 /pygopherd/head: changeset 65 Updates -- safer populatefromfs(), etc. M pygopherd/gopherentry.py commit 04e0a83078aacca532564edadfec9d75afa94851 Author: jgoerzen Date: Fri Apr 5 05:51:12 2002 +0100 /pygopherd/head: changeset 64 Initial writing. M pygopherd/handlers/UMN.py commit e6d39b91670cfb64354dc39bf5f92982f7767dc0 Author: jgoerzen Date: Fri Apr 5 03:41:03 2002 +0100 /pygopherd/head: changeset 63 Added from dir.py C100 pygopherd/handlers/dir.py pygopherd/handlers/UMN.py commit 7cf46da4f162539cc6d6e0b1574da80039a516e5 Author: jgoerzen Date: Thu Mar 28 04:40:53 2002 +0100 /pygopherd/head: changeset 62 Added experimental URLGopherPlus protocol. M pygopherd/gopherentry.py M pygopherd/protocols/gopherp.py commit 4ff8548d3c942e4bc96d6d42acf9464a39992208 Author: jgoerzen Date: Thu Mar 28 04:24:58 2002 +0100 /pygopherd/head: changeset 61 Modified to make more extensible. M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py commit d6b9f4718db6cb6d224f17dc3f2accb4b8e31cab Author: jgoerzen Date: Thu Mar 28 02:16:17 2002 +0100 /pygopherd/head: changeset 60 Moved to and fixes in prepare() M pygopherd/handlers/gophermap.py commit b125e3fc88e28c7d9a5af5514fbf9e8f0fe3c5ab Author: jgoerzen Date: Thu Mar 28 01:19:00 2002 +0100 /pygopherd/head: changeset 59 Added error handling M pygopherd/protocols/http.py commit 3a922005db7ecb25c9ba2f4be98c2b66b1668d39 Author: jgoerzen Date: Wed Mar 27 12:41:47 2002 +0100 /pygopherd/head: changeset 58 HTTP support now nominally working. M conf/pygopherd.conf M pygopherd/handlers/dir.py M pygopherd/protocols/base.py M pygopherd/protocols/http.py commit daed65af2e8b59d507bee36a9686e655dc5849be Author: jgoerzen Date: Wed Mar 27 09:44:16 2002 +0100 /pygopherd/head: changeset 57 More work on http M pygopherd/protocols/http.py commit b514b10182266712649f137a109a399c7a727d26 Author: jgoerzen Date: Wed Mar 27 09:17:14 2002 +0100 /pygopherd/head: changeset 56 Added some bugfixes for time handling. M pygopherd/protocols/gopherp.py commit ae6667c8013c76641b3cf4b485ce6d0ae4e17187 Author: jgoerzen Date: Wed Mar 27 09:10:01 2002 +0100 /pygopherd/head: changeset 55 Added error handling. M conf/pygopherd.conf A pygopherd/GopherExceptions.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/handlers/gophermap.py M pygopherd/handlers/url.py M pygopherd/protocols/__init__.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py C100 pygopherd/protocols/rfc1436.py pygopherd/protocols/http.py commit 8b49696bb5438d61b7240059200ff4ff3acdb20a Author: jgoerzen Date: Wed Mar 27 08:27:27 2002 +0100 /pygopherd/head: changeset 54 Added gophermap capabilities. M conf/pygopherd.conf A doc/standards/Gopher+.txt M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/__init__.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py A pygopherd/handlers/gophermap.py M pygopherd/handlers/url.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py commit e50dbee7fd3f70f6336541bb2ac2c3f806b01b64 Author: jgoerzen Date: Wed Mar 27 07:52:58 2002 +0100 /pygopherd/head: changeset 53 Added from gopher://gopher.floodgap.com:70/0/buck/dbrowse%3Ffaquse%201 A doc/standards/gophermap.txt commit 2137bb9e700c36774a9077b8db9c5d475ae7e23f Author: jgoerzen Date: Wed Mar 27 07:30:14 2002 +0100 /pygopherd/head: changeset 52 Added from http://www.complete.org/mailinglists/archives/gopher- 200202/msg00033.html A doc/standards/url.txt commit 843d8576246dfbc6f5b98065c07d07603c8ea700 Author: jgoerzen Date: Wed Mar 27 07:17:27 2002 +0100 /pygopherd/head: changeset 51 Added url.py -- a URL: handler. M conf/pygopherd.conf M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/__init__.py A pygopherd/handlers/url.py commit 600dbecbb9a371b4ee9edf5c3713d100d892e7df Author: jgoerzen Date: Wed Mar 27 06:59:11 2002 +0100 /pygopherd/head: changeset 50 Updated to use new multiplexers, more configurability, some renaming M conf/pygopherd.conf M pygopherd.py M pygopherd/gopherentry.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py A pygopherd/protocols/ProtocolMultiplexer.py M pygopherd/protocols/enhanced.py commit 9d1fa06aa0345281011862242b4b3e407eb71dd9 Author: jgoerzen Date: Wed Mar 27 05:45:42 2002 +0100 /pygopherd/head: changeset 49 Updated. M TODO M conf/pygopherd.conf M pygopherd.py M pygopherd/gopherentry.py commit 3136e6df79464f1a969c11fd2ae98d95560bf644 Author: jgoerzen Date: Wed Mar 27 05:24:58 2002 +0100 /pygopherd/head: changeset 48 More bugfixes M pygopherd/protocols/gopherp.py M pygopherd/protocols/rfc1436.py commit 21c18a724d5bb458b2680bc323924a1c9d66de87 Author: jgoerzen Date: Wed Mar 27 05:19:32 2002 +0100 /pygopherd/head: changeset 47 renamed entry to gopherentry R100 entry.py pygopherd/gopherentry.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/protocols/gopherp.py commit eec2bf3c19bba4262b758a3a0485ead9e4fec00b Author: jgoerzen Date: Wed Mar 27 05:12:31 2002 +0100 /pygopherd/head: changeset 46 Basic execution fixes. M entry.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/protocols/base.py commit d4d6670dcfe93711f926f0732ef6beb0ab216afa Author: jgoerzen Date: Wed Mar 27 04:46:36 2002 +0100 /pygopherd/head: changeset 45 Bugfixes M pygopherd.py M pygopherd/handlers/HandlerMultiplexer.py M pygopherd/handlers/base.py M pygopherd/handlers/dir.py M pygopherd/handlers/file.py M pygopherd/protocols/base.py M pygopherd/protocols/gopherp.py M pygopherd/protocols/rfc1436.py commit 61ceb8cc85e18e6e2ebb2a3b4f50e37b4757f6e0 Author: jgoerzen Date: Wed Mar 27 04:34:22 2002 +0100 /pygopherd/head: changeset 44 *** empty log message *** M pygopherd.py A pygopherd/handlers/HandlerMultiplexer.py A pygopherd/handlers/__init__.py M pygopherd/protocols/__init__.py commit f0ef60b5a2a034bf46e40853fa05e93668009671 Author: jgoerzen Date: Wed Mar 27 04:25:56 2002 +0100 /pygopherd/head: changeset 43 *** empty log message *** A conf/mime.types A entry.py M pygopherd/protocols/gopherp.py commit 9715adb7d04397b556bfa187f13a38e630c25522 Author: jgoerzen Date: Wed Mar 27 04:17:56 2002 +0100 /pygopherd/head: changeset 42 *** empty log message *** D handlers.py M pygopherd.py M pygopherd/handlers/base.py A pygopherd/handlers/dir.py M pygopherd/protocols/base.py commit 0c3900805943a5bdaac25099a17e7bd572ff8479 Author: jgoerzen Date: Wed Mar 27 04:09:05 2002 +0100 /pygopherd/head: changeset 41 Updated M conf/pygopherd.conf M handlers.py M pygopherd/handlers/base.py M pygopherd/handlers/file.py M pygopherd/protocols/base.py commit 2ca399a6f2457100667dd925aaad18223541f80f Author: jgoerzen Date: Wed Mar 27 03:34:50 2002 +0100 /pygopherd/head: changeset 40 Updated. A TODO A pygopherd/handlers/base.py A pygopherd/handlers/file.py M pygopherd/protocols/base.py commit 83856edc1d326c93902e2673b6b589c58da6e9b8 Author: jgoerzen Date: Wed Mar 27 03:29:20 2002 +0100 /pygopherd/head: changeset 39 Removed some code moved to the base protocol. M handlers.py commit b56019672cf462aab4220c6c1e747be2edd59059 Author: jgoerzen Date: Wed Mar 27 03:09:39 2002 +0100 /pygopherd/head: changeset 38 First stab at protocols.py -> protocols/* conversion. D protocols.py A pygopherd/protocols/__init__.py A pygopherd/protocols/base.py A pygopherd/protocols/enhanced.py A pygopherd/protocols/gopherp.py A pygopherd/protocols/rfc1436.py commit ec2c0f975dff8eae5bcca3ba012bba14d52c84f1 Author: jgoerzen Date: Wed Mar 27 02:24:15 2002 +0100 /pygopherd/head: changeset 37 Added. A doc/standards/rfc1436.txt commit fc5b9dd470ea63446e94c417dfc5ca5556c5dd6c Author: jgoerzen Date: Tue Mar 26 12:32:02 2002 +0100 /pygopherd/head: changeset 36 Updates for pre-http redir support. M handlers.py M protocols.py commit f8cd0056eee395d961be2dd704910d7be203b539 Author: jgoerzen Date: Tue Mar 26 12:01:58 2002 +0100 /pygopherd/head: changeset 35 Rearranged code -- split rhandler.py into handlers.py and protocols.py A handlers.py A protocols.py M pygopherd.py D rhandler.py commit 908854158fce68fbecbbf200a4f41abed9e03212 Author: jgoerzen Date: Tue Mar 26 09:47:07 2002 +0100 /pygopherd/head: changeset 34 bug fixes M rhandler.py commit a54ee417764f77618a2c6b8cad1d0ceab8e696fa Author: jgoerzen Date: Tue Mar 26 09:27:26 2002 +0100 /pygopherd/head: changeset 33 Rewrite in progress. M conf/pygopherd.conf M rhandler.py commit 90a55a0c097406dffe8367b022f1aa0572e38394 Author: jgoerzen Date: Tue Mar 26 06:27:41 2002 +0100 /pygopherd/head: changeset 32 More updates. M rhandler.py commit a74cc88ac2007f828bd0dbca706b14cf3060a5f1 Author: jgoerzen Date: Tue Mar 26 06:21:09 2002 +0100 /pygopherd/head: changeset 31 Basic functionality is working. M conf/pygopherd.conf M pygopherd.py M rhandler.py commit a6bb3b6b6c6aeb7a09cb73cbca686bfa16e73fa4 Author: jgoerzen Date: Tue Mar 26 05:17:58 2002 +0100 /pygopherd/head: changeset 30 Updated. A conf/pygopherd.conf M pygopherd.py A rhandler.py commit f3d4fe0deadb12cb9b708ee9131cd3dad1454628 Author: jgoerzen Date: Tue Mar 26 04:29:53 2002 +0100 /pygopherd/head: changeset 29 Updated. M pygopherd.py commit e244f6dfe404254b0104e5511102223dbd3bbd85 Author: jgoerzen Date: Tue Mar 26 04:08:11 2002 +0100 /pygopherd/head: changeset 28 This version. M pygopherd.py commit 9eb409f3ed072797a640058e6313dd057aab8a1a Author: jgoerzen Date: Tue Mar 26 03:55:11 2002 +0100 /pygopherd/head: changeset 27 Working prototype. M pygopherd.py commit 1b320ecafa7c705232e042b1a5cc6bc555637ba5 Author: jgoerzen Date: Tue Mar 26 03:29:14 2002 +0100 /pygopherd/head: changeset 26 Skeletal work A pygopherd.py commit f1028498801c1a8e404dad0d022102d2adc931b8 Author: tailor Date: Sat Apr 16 16:33:54 2005 +0100 Tailorization of /pygopherd/head Import of the upstream sources from the repository file:///tmp/darcsconv/t/gopher-py as of revision 25 A COPYING pygopherd-3.0.1/COPYING000066400000000000000000000431101456676541200145660ustar00rootroot00000000000000 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. Copyright (C) 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. , 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. pygopherd-3.0.1/Makefile000066400000000000000000000037731456676541200152060ustar00rootroot00000000000000# Copyright (C) 2002, 2003 John Goerzen # # # 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; version 2 of the License. # # 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 clean: -python2.3 setup.py clean --all -rm -f `find . -name "*~"` -rm -f `find . -name "*.pyc"` -rm -f `find . -name "*.pygc"` -rm -f `find . -name "*.class"` -rm -f `find . -name "*.bak"` -rm -f `find . -name ".cache*"` -rm -f *.log *.aux *.dvi *.out *.jtex jadetex.cfg -find . -name auth -exec rm -vf {}/password {}/username \; -rm -rf build changelog: git log -M -C --find-copies-harder --name-status > ChangeLog docs: doc/pygopherd.8 doc/pygopherd.ps \ doc/pygopherd.pdf doc/pygopherd.txt doc/pygopherd.html doc/pygopherd.8: doc/pygopherd.sgml doc/book.sgml docbook2man doc/book.sgml docbook2man doc/book.sgml -rm manpage.links manpage.refs mv pygopherd.8 doc #doc/pygopherd.html: doc/pygopherd.sgml # docbook2html -u doc/pygopherd.sgml # mv pygopherd.html doc doc/pygopherd.html: doc/pygopherd.sgml doc/book.sgml docbook2html -u doc/book.sgml mv book.html doc/pygopherd.html #doc/pygopherd.ps: doc/pygopherd.8 # man -t -l doc/pygopherd.8 > doc/pygopherd.ps doc/pygopherd.ps: doc/pygopherd.sgml doc/book.sgml doc/manpage.sgml docbook2ps \ doc/book.sgml mv book.ps doc/pygopherd.ps doc/pygopherd.pdf: doc/pygopherd.ps ps2pdf doc/pygopherd.ps mv pygopherd.pdf doc doc/pygopherd.txt: groff -Tascii -man doc/pygopherd.8 | sed $$'s/.\b//g' > doc/pygopherd.txt pygopherd-3.0.1/README.md000066400000000000000000000022601456676541200150130ustar00rootroot00000000000000[![Build](https://github.com/michael-lazar/pygopherd/workflows/Test/badge.svg)](https://github.com/michael-lazar/pygopherd/actions) [![license GPLv2](https://img.shields.io/github/license/michael-lazar/pygopherd)](https://www.gnu.org/licenses/gpl-2.0.en.html) # PyGopherd PyGopherd is a multiprotocol (gopher, gopher+, http, wap) information server. [PyGopherd Online User Manual](https://michael-lazar.github.io/pygopherd/doc/pygopherd.html) ## History This repo is a fork of [jgoerzen/pygopherd](https://github.com/jgoerzen/pygopherd) that adds support for Python 3. If you're upgrading from an old version of PyGopherd, see the [upgrade notes](UPGRADING.md). ## Quickstart ### Debian Use the .deb: ``` dpkg -i pygopherd.deb ``` or ``` apt-get install pygopherd ``` ### Non-Debian First, download and install Python 3.7 or higher. You can run pygopherd either in-place (as a regular user account) or as a system-wide daemon. For running in-place, do this: ``` PYTHONPATH=. bin/pygopherd conf/local.conf ``` For installing, ``` python3 setup.py install ``` Make sure that the ``/etc/pygopherd/pygopherd.conf`` names valid users (setuid, setgid) and valid document root (root). pygopherd-3.0.1/README.windows000066400000000000000000000016671456676541200161170ustar00rootroot00000000000000Submitted by Grant D. Watson: ---------------------------------------------------------- Windows Installation: Download the tar.gz version of the package from the website. Make sure you have Python 2.2 or above installed; if not, download and install it from http://www.python.org/. Unzip the package in "C:\Program Files" (or another suitable directory). In WordPad (_not_ Notepad) open "C:\Program Files\pygopherd\conf\pygopherd.conf". Modify the file as follows: - Set detach = no - Comment out the pidfile line - Set servertype = ThreadingTCPServer - Set usechroot = no - Comment out the setuid and setgid lines - Set root to something appropriate - Set mimetypes = conf/mime.types - Set logmethod = none To run the server, open a DOS prompt and type the following commands: c: cd "\Program Files\pygopherd" python bin\pygopherd conf\pygopherd.conf To end the server you must press Ctrl-Alt-Del and tell Windows to end the task. pygopherd-3.0.1/TODO000066400000000000000000000000411456676541200142170ustar00rootroot00000000000000 * Document new .gophermap files pygopherd-3.0.1/UPGRADING.md000066400000000000000000000040371456676541200154020ustar00rootroot00000000000000# Upgrading to PyGopherd v3.0 Notes for updating an existing PyGopherd server deployment to run on python 3. ## Server Version Install PyGopherd v3.0+ from [michael-lazar/pygopherd](https://github.com/michael-lazar/pygopherd) or another dependable source. ## Cached Files PyGopherd will create cache files that start with ``.cache.pygopherd.*`` in your gopher root directory. These files are used to index directories and zip files for faster loading. Before launching the new server, clear out any existing PyGopherd cache files from your system. ``` find /var/gopher -type f -name '.cache.pygopherd.*' -delete ``` ## /etc/pygopherd/pygopherd.conf Because the PyGopherd config file format uses evaluated python code, you will need to make sure your config file is python 3 compatible. There is one known spot where the default config file needed to be updated. ``` encoding = mimetypes.encodings_map.items() + \ {'.bz2' : 'bzip2', '.tal': 'tal.TALFileHandler' }.items() ``` must be changed to ``` encoding = list(mimetypes.encodings_map.items()) + \ list({'.bz2' : 'bzip2', '.tal': 'tal.TALFileHandler' }.items()) ``` ## PYG files PyGopherd supports ``*.pyg`` files which use a special file handler to execute python code directly. If you have written any custom PYG files for your server, you will need to make sure that they are compatible with python 3. The internal API has not changed, but some methods now expect bytes instead of strings. An example PYG file is shown [here](testdata/testfile.pyg). #### Before ``` def write(self, wfile): wfile.write(self.definition) ``` #### After ``` def write(self, wfile): wfile.write(self.definition.encode()) ``` ## Other Handlers Some handler classes required major refactoring to support python 3. Notably the ``mbox`` and ``ZIP`` handlers were significantly changed. Effort was made to preserve the old behavior as closely as possible. If you're using any of these handlers on your server, test them out and report back with any issues! pygopherd-3.0.1/bin/000077500000000000000000000000001456676541200143045ustar00rootroot00000000000000pygopherd-3.0.1/bin/pygopherd000077500000000000000000000026001456676541200162310ustar00rootroot00000000000000#!/usr/bin/env python3 # Python-based gopher server # COPYRIGHT # # Copyright (C) 2021 Michael Lazar # Copyright (C) 2002-2019 John Goerzen # # 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; version 2 of the License. # # 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 # END OF COPYRIGHT # import argparse from pygopherd import initialization, __version__ parser = argparse.ArgumentParser( prog="pygopherd", description="A multiprotocol gopher information server", formatter_class=argparse.ArgumentDefaultsHelpFormatter, ) parser.add_argument( "config", nargs="?", default="/etc/pygopherd/pygopherd.conf", help="pygopherd config", ) parser.add_argument( "-V", "--version", action="version", version="pygopherd " + __version__ ) args = parser.parse_args() s = initialization.initialize(args.config) s.serve_forever() pygopherd-3.0.1/conf/000077500000000000000000000000001456676541200144615ustar00rootroot00000000000000pygopherd-3.0.1/conf/local.conf000066400000000000000000000412771456676541200164350ustar00rootroot00000000000000###################################################################### # LOCAL DEVELOPMENT QUICKSTART SETTINGS ###################################################################### [pygopherd] ################################################## # Operating System / Overall Behavior ################################################## # Set this to true if you want the server to "detach" itself; that is, # to go into the background after it starts. detach = no # If you want gopherd to write a PID file, set this to the location # where you want it. Otherwise, comment out this line. # pidfile = /var/run/pygopherd.pid ################################################## # Network ################################################## # The server name to present to the world. If you do not specify it # here, Pygopherd will attempt to figure it out automatically. # This is used only to present to clients. It does not control # where the server listens. # servername = localhost # The interface on which to listen. It should be an IP address or # a domain name. If specified, pygopherd will attempt to listen to # the specified port on only this interface -- useful if you are doing # virtual hosting. If not specified, pygopherd will listen on all # interfaces the OS provides. If in doubt, do not specify this. # # interface = gopher.example.com # What port to listen on. If not running as root, this must be # greater than 1024. port = 7070 # Type of server to run. Valid options are ForkingTCPServer # and ThreadingTCPServer. ForkingTCPServer is highly recommended # for now. servertype = ThreadingTCPServer # What port to *say* we're listening on. Most people should NOT # specify this. You might want to if you are using firewalling or # port forwarding and the port number is different to the world than # it is locally. # advertisedport = 70 # Do we timeout on client conections? HIGHLY RECOMMENDED! # Value is given in seconds. If given, any read or write that makes # no progress in this number of seconds will time out. timeout = 60 ################################################## # Data Handling ################################################## # You can add a header to every directory by creating a # .abstract file in that directory and filling it with the # information you like. This will then be rendered as a header # for the directory. This option controls this feature. Note: # for this to work, you must define a mapping to ABSTRACT in eaexts # below. abstract_headers = on # Individual files and folders can also have abstracts. You can # choose to have pygopherd render these abstracts in the directory # listing itself -- they'll appear beneath the menu name for the file. # You can set this option to any of three values: # # always -- always render these abstracts. # unsupported -- render them only for protocols that do not natively # support abstracts. Gopher+ is the only protocol that natively # supports them currently. # never -- never render these abstracts. abstract_entries = always ################################################## # Error handling ################################################## # If there is an error, you can decide whether or not to log a full # backtrace. A full backtrace will usually be needed to find the # problem. tracebacks = yes ################################################## # Security ################################################## ## Whether or not to use chroot. # This option is only valid if you are running pygopherd as root! usechroot = no ## Username and groupname to setreuid/setregid to. Valid only if ## starting pygopherd as root. Comment out if you don't want this ## functionality. NOTE: DO NOT RUN AS ROOT UNLESS YOU USE THESE! BAD BAD BAD! # setuid = gopher # setgid = gopher ################################################## # TLS ################################################## # Enable TLS by sniffing the first byte of the client request for the start of # a TLS handshake. This allows both TLS and plaintext requests to be served # over the same port. enable_tls = yes # File paths to the server certificate and keyfile in PEM format. These are # required if TLS is enabled. When using chroot, the certificates will be # loaded while root privileges are still active. tls_certfile = ./testdata/demo.crt tls_keyfile = ./testdata/demo.key ################################################## # Filesystem and MIME ################################################## # Where the documents are stored. root = ./testdata # Location of a file to use to figure out MIME types. You can # specify multiple files here -- just separate them with a colon. # ALL of them that are found will be read. mimetypes = ./conf/mime.types:/etc/pygopherd/mime.types:/etc/mime.types # Encodings. You can use the default with the following syntax. The # mimetypex.encodings_map is {'.Z': 'compress', '.gz': 'gzip'}. # # For ease of use in the config file, we specify this as a list of # tuples. You can convert any hash to a list of tuples by using .items() # encoding = mimetypes.encodings_map.items() # You can override the default entirely (ie, to remove those) like this: # encoding = {'.bz2' : 'bzip2', '.gz' : 'gzip'}.items() # Or the same thing: # encoding = [('.bz2', 'bzip2'), ('.gz', 'gzip')] # Or, you can extend the default like so: encoding = list(mimetypes.encodings_map.items()) + \ list({'.bz2' : 'bzip2', '.tal': 'tal.TALFileHandler' }.items()) ###################################################################### # Logging ###################################################################### [logger] # Log method to use. One of: # syslog -- use Unix syslog facility # file -- log to standard output (future capability for logging to other # files) # none -- no logging logmethod = file # If you enable syslog, you will need to define these as well: # priority -- one of the following (listed in order of high to low): # LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, # LOG_INFO, LOG_DEBUG priority = LOG_INFO # Facility -- one of the following: # LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_LPR, LOG_NEWS, # LOG_UUCP, LOG_CRON, LOG_LOCAL0 - LOG_LOCAL7 facility = LOG_LOCAL3 ###################################################################### # GOPHER OBJECTS ###################################################################### # Settings for gopher objects [GopherEntry] # Use this MIME type if no other type is found. defaultmimetype = text/plain # Mapping from MIME types to gopher0 single-character types. # This is a list of lists. The first entry in each list is a # regexp to match and the second is the result. # # Please have a .* at the end to map all unknown types to a certain # character. For best results, that character should be nicely # corresponding to the defaultmimetype. mapping = [['text/html', 'h'], ['text/.+', '0'], ['application/mac-binhex40', '4'], ['audio/.+', 's'], ['image/gif', 'g'], ['image/.+', 'I'], ['application/gopher-menu', '1'], ['application/gopher\\+-menu', '1'], ['multipart/mixed', 'M'], ['application/.+', '9'], ['.*', '0'] ] # This is used by the system to generate Extended Attribute (EA), aka # Gopher+ blocks for a file. Basically, with the setup shown below, # you can create "filename.txt.abstract" to define the abstract # property for filename.txt. If you do that, you will probably want # to add these properties to ignorepatt below. The list is a mapping # from an extension to a block name. # # Sample for UMN compatibility: # eaexts = {'.abstract' : 'ABSTRACT', '.keywords' : 'KEYWORDS', '.ask' : 'ASK', '.3d' : '3D'} # # If you want to disable this capability, use this: # # eaexts = {} ###################################################################### # HANDLERS ###################################################################### ################################################## # Handler multiplexer ################################################## [handlers.HandlerMultiplexer] # A list of the handlers to consider. The handlers # are tried in the order listed. # # ### Suggested settings: # Note: the UMNDirHandler will handle all directories, even if they # do not have UMN-specific files, so you do not need to list the # dirhandler in this case. # # Warning: scriptexec and pyg can execute arbitrary code stored in # your path. Don't enable unless you know what you're doing! # # For UMN emulation: (full UMN featureset excluding scriptexec, no others) # # handlers = [url.HTMLURLHandler, UMN.UMNDirHandler, # html.HTMLFileTitleHandler, # mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, # file.CompressedFileHandler, file.FileHandler] # # For Bucktooth emulation: (full Buck featureset excluding scriptexec) # #handlers = [gophermap.BuckGophermapHandler, url.HTMLURLHandler, # file.FileHandler, dir.DirHandler] # # For full Pygopherd featureset excluding scripts, compression, and PYG. # Supports both UMN and Bucktooth featuresets. This is the default # configuration for Pygopherd because it is secure yet versatile. # # handlers = [url.HTMLURLHandler, gophermap.BuckGophermapHandler, # mbox.MaildirFolderHandler, mbox.MaildirMessageHandler, # UMN.UMNDirHandler, html.HTMLFileTitleHandler, # mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, # file.FileHandler] # For full Pygopherd featureset including scripts and PYG. Same as # above but adds scripts, decompression, and PYG execution. handlers = [url.HTMLURLHandler, gophermap.BuckGophermapHandler, mbox.MaildirFolderHandler, mbox.MaildirMessageHandler, UMN.UMNDirHandler, tal.TALFileHandler, html.HTMLFileTitleHandler, mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, pyg.PYGHandler, scriptexec.ExecHandler, ZIP.ZIPHandler, file.CompressedFileHandler, file.FileHandler, url.URLTypeRewriter] ################################################## # Decompressing file handler ################################################## [handlers.file.CompressedFileHandler] # Decompressors is a map from an encoding (as specified in the # pygopherd section above) to a decompression program. # The decompression program must # accept the input in its stdin and write the decompressed output # to stdout. # # If you do not want to decompress things automatically for your # clients, you might wish to NOT use this handler. # # Note: this feature is probably NOT compatible with chroot unless # you take extra precautions. # We enable no decompressors by default... you'll need to do that. # decompressors = {} decompressors = {'bzip2': 'bzcat', 'gzip' : 'zcat', 'compress' : 'zcat'} # Regexp to match against filenames pending decompression. # The default will let ALL files be decompressed. decompresspatt = .* # You can be more restrictive: # decompresspatt = \.txt\.(bz2|gz|Z)$ ################################################## # Directory handler ################################################## [handlers.dir.DirHandler] # A regular expression of files to ignore. These files # will not be presented in lists of files to clients, # but if clients know the exact path to the files, they can # still be requested. # # This pattern is matched against the requested selector. # Selectors are guaranteed to begin with a slash by this point. # and never end with a slash unless they consist solely of a slash. # # By default, we ignore files starting with a period, gophermap # files, and files ending with a tilde. # # The default emulates UMN's default plus buck. Please note: # UMNDirHandler implicitly will keep all files starting with a dot out of # directory listings. If you exclude these files explicitly in ignorepatt, # then not only will they not show up, but the handler will also not scan # them for links and the like. # # A buck-only server might like: # # ignorepatt = ~$|/\.|/gophermap$ ignorepatt = /.cap$|/lost\+found$|/lib$|/bin$|/etc$|/dev$|~$|/\.cache|/\.forward$|/\.message$|/\.hushlogin$|/\.kermrc$|/\.notar$|/\.where$|/veronica.ctl$|/robots.txt$|/nohup.out$|/gophermap$|\.abstract$|\.keyboards$|\.ask|\.3d$|~$ # Expiration time, in seconds, for the cache. # Set to 0 to disable caching entirely. cachetime = 0 # Name of the cahe file. Must be set to something even if the cachetime # is zero. In that case, this filename will not be used but for the conf # file to parse, it must still be set. cachefile = .cache.pygopherd.dir ################################################## # UMN Directory Handler ################################################## [handlers.UMN.UMNDirHandler] # Extension stripping behavior. When a file from a directory # is presented in a menu, and no name is given, what to do? # For instance, given a file Welcome.txt and pygopherd.tar.gz: # # If extstrip is none, present Welcome.txt and pygopherd.tar.gz in the # menu. # # If extstrip is nonencoded, modify only those files that do not # have encodings. (If CompressedFileHandler is used, modify only # those files that to not have *HANDLED* encodings.) # If gzip is NOT a handled encoding, you'd get names Welcome and # pygopherd.tar.gz. If gzip IS a handled encoding, you'd get # Welcome and pygopherd. # # If extstrip is full, modify all modifyable names. Welcome.txt -> # Welcome and pygopherd.tar.gz -> pygopherd. # extstrip = none extstrip = nonencoded # extstrip = full [handlers.ZIP.ZIPHandler] ################################################## # ZIP file handler ################################################## # Even if it's listed in the available handlers, it's disabled here by # default. enabled = true pattern = \.zip$ ###################################################################### # PROTOCOLS ###################################################################### ################################################## # Protocol Multiplexer ################################################## [protocols.ProtocolMultiplexer] # A list of the protocols to consider for each request. # The protocols are tried in the order listed. protocols = [wap.WAPProtocol, gemini.GeminiProtocol, http.HTTPProtocol, http.HTTPSProtocol, spartan.SpartanProtocol, gopherp.GopherPlusProtocol, gopherp.SecureGopherPlusProtocol, rfc1436.GopherProtocol, rfc1436.SecureGopherProtocol] ################################################## # Gopher+ Protocol ################################################## [protocols.gopherp.GopherPlusProtocol] # The name and e-mail of the administrator admin = Unconfigured Pygopherd Admin ################################################## # HTTP Protocol ################################################## [protocols.http.HTTPProtocol] iconmapping = {'h' : 'text.gif', '0' : 'text.gif', '4' : 'binhex.gif', 's' : 'sound1.gif', 'g' : 'image3.gif', 'I' : 'image3.gif', 'M' : 'text.gif', '9' : 'binary.gif', '1' : 'folder.gif', '7' : 'folder.gif', 'i' : 'blank.gif'} # You can use this option to put something at the top of each HTML # page generated. # # The following tokens will be interpolated: # # GOPHERURL -- the Gopher URL for this page. # pagetopper = Welcome to Gopherspace! You are browsing Gopher through a Web interface right now. You can use most browsers or Gopher clients to browse Gopher natively. If your browser supports it, try clicking here to see this page in Gopher directly. To find Gopher browsers, click here.
################################################## # WAP Protocol ################################################## [protocols.wap.WAPProtocol] # waptop is the URL to access with WAP devices. The default, /wap, means # that accessing http://sitename.com/wap will bring up your site in WAP # mode. # # PyGopherd can autodetect WAP from some phones, so this is not always # necessary. waptop = /wap ################################################## # Gemini Protocol ################################################## [protocols.gemini.GeminiProtocol] # Note that the gemini protocol *requires* the TLS section to also be enabled. footer = => https://www.github.com/michael-lazar/pygopherd Generated by PyGopherd ################################################## # Spartan Protocol ################################################## [protocols.gemini.SpartanProtocol] footer = => https://www.github.com/michael-lazar/pygopherd Generated by PyGopherdpygopherd-3.0.1/conf/mime.types000066400000000000000000000357751456676541200165170ustar00rootroot00000000000000############################################################################### # # MIME-TYPES and the extensions that represent them # # This file is part of the "mime-support" package. Please send email (not a # bug report) to mime-support@packages.debian.org if you would like new types # and/or extensions to be added. # # Note: Compression schemes like "gzip", "bzip", and "compress" are not # actually "mime-types". They are "encodings" and hence must _not_ have # entries in this file to map their extensions. The "mime-type" of an # encoded file refers to the type of data that has been encoded, not the # type of the encoding. # ############################################################################### application/activemessage application/andrew-inset ez application/applefile application/atomicmail application/batch-SMTP application/beep+xml application/cals-1840 application/commonground application/cu-seeme csm cu application/cybercash application/dca-rft application/dec-dx application/dsptype tsp application/dvcs application/EDI-Consent application/EDIFACT application/EDI-X12 application/eshop application/font-tdpfr application/futuresplash spl application/ghostview application/http application/hyperstudio application/iges application/index application/index.cmd application/index.obj application/index.response application/index.vnd application/iotp application/ipp application/isup application/mac-compactpro cpt application/marc application/mac-binhex40 hqx application/macwriteii application/mathematica nb application/mathematica-old application/msaccess mdb application/msword doc dot application/news-message-id application/news-transmission application/octet-stream bin application/ocsp-request application/ocsp-response application/oda oda application/parityfec application/pgp-encrypted application/pgp-keys application/pdf pdf application/pgp-signature pgp application/pkcs10 application/pkcs7-mime application/pkcs7-signature application/pkix-cert application/pkixcmp application/pkix-crl application/postscript ps ai eps application/prs.alvestrand.titrax-sheet application/prs.cww application/prs.nprend application/qsig application/riscos application/remote-printing application/rtf rtf application/sdp application/set-payment application/set-payment-initiation application/set-registration application/set-registration-initiation application/sgml application/sgml-open-catalog application/sieve application/slate application/smil smi smil application/timestamp-query application/timestamp-reply application/vemmi application/vnd.3M.Post-it-Notes application/vnd.accpac.simply.aso application/vnd.accpac.simply.imp application/vnd.acucobol application/vnd.aether.imp application/vnd.anser-web-certificate-issue-initiation application/vnd.anser-web-funds-transfer-initiation application/vnd.audiograph application/vnd.bmi application/vnd.businessobjects application/vnd.canon-cpdl application/vnd.canon-lips application/vnd.claymore application/vnd.commerce-battelle application/vnd.commonspace application/vnd.comsocaller application/vnd.contact.cmsg application/vnd.cosmocaller application/vnd.ctc-posml application/vnd.cups-postscript application/vnd.cups-raster application/vnd.cups-raw application/vnd.cybank application/vnd.dna application/vnd.dpgraph application/vnd.dxr application/vnd.ecdis-update application/vnd.ecowin.chart application/vnd.ecowin.filerequest application/vnd.ecowin.fileupdate application/vnd.ecowin.series application/vnd.ecowin.seriesrequest application/vnd.ecowin.seriesupdate application/vnd.enliven application/vnd.epson.esf application/vnd.epson.msf application/vnd.epson.quickanime application/vnd.epson.salt application/vnd.epson.ssf application/vnd.ericsson.quickcall application/vnd.eudora.data application/vnd.fdf application/vnd.ffsns application/vnd.FloGraphIt application/vnd.framemaker application/vnd.fsc.weblaunch application/vnd.fujitsu.oasys application/vnd.fujitsu.oasys2 application/vnd.fujitsu.oasys3 application/vnd.fujitsu.oasysgp application/vnd.fujitsu.oasysprs application/vnd.fujixerox.ddd application/vnd.fujixerox.docuworks application/vnd.fujixerox.docuworks.binder application/vnd.fut-misnet application/vnd.grafeq application/vnd.groove-account application/vnd.groove-identity-message application/vnd.groove-injector application/vnd.groove-tool-message application/vnd.groove-tool-template application/vnd.groove-vcard application/vnd.hhe.lesson-player application/vnd.hp-HPGL application/vnd.hp-hpid application/vnd.hp-hps application/vnd.hp-PCL application/vnd.hp-PCLXL application/vnd.httphone application/vnd.hzn-3d-crossword application/vnd.ibm.afplinedata application/vnd.ibm.MiniPay application/vnd.ibm.modcap application/vnd.informix-visionary application/vnd.intercon.formnet application/vnd.intertrust.digibox application/vnd.intertrust.nncp application/vnd.intu.qbo application/vnd.intu.qfx application/vnd.irepository.package+xml application/vnd.is-xpr application/vnd.japannet-directory-service application/vnd.japannet-jpnstore-wakeup application/vnd.japannet-payment-wakeup application/vnd.japannet-registration application/vnd.japannet-registration-wakeup application/vnd.japannet-setstore-wakeup application/vnd.japannet-verification application/vnd.japannet-verification-wakeup application/vnd.koan application/vnd.lotus-1-2-3 application/vnd.lotus-approach application/vnd.lotus-freelance application/vnd.lotus-notes application/vnd.lotus-organizer application/vnd.lotus-screencam application/vnd.lotus-wordpro application/vnd.mcd application/vnd.mediastation.cdkey application/vnd.meridian-slingshot application/vnd.mif mif application/vnd.minisoft-hp3000-save application/vnd.mitsubishi.misty-guard.trustweb application/vnd.mobius.daf application/vnd.mobius.dis application/vnd.mobius.msl application/vnd.mobius.plc application/vnd.mobius.txf application/vnd.motorola.flexsuite application/vnd.motorola.flexsuite.adsi application/vnd.motorola.flexsuite.fis application/vnd.motorola.flexsuite.gotap application/vnd.motorola.flexsuite.kmr application/vnd.motorola.flexsuite.ttc application/vnd.motorola.flexsuite.wem application/vnd.mozilla.xul+xml application/vnd.ms-artgalry application/vnd.ms-asf application/vnd.mseq application/vnd.ms-excel xls xlb application/vnd.msign application/vnd.ms-lrm application/vnd.ms-powerpoint ppt pps pot application/vnd.ms-project application/vnd.ms-tnef application/vnd.ms-works application/vnd.musician application/vnd.music-niff application/vnd.netfpx application/vnd.noblenet-directory application/vnd.noblenet-sealer application/vnd.noblenet-web application/vnd.novadigm.EDM application/vnd.novadigm.EDX application/vnd.novadigm.EXT application/vnd.osa.netdeploy application/vnd.palm application/vnd.pg.format application/vnd.pg.osasli application/vnd.powerbuilder6 application/vnd.powerbuilder6-s application/vnd.powerbuilder7 application/vnd.powerbuilder75 application/vnd.powerbuilder75-s application/vnd.powerbuilder7-s application/vnd.previewsystems.box application/vnd.publishare-delta-tree application/vnd.pvi.ptid1 application/vnd.pwg-xhtml-print+xml application/vnd.rapid application/vnd.s3sms application/vnd.seemail application/vnd.shana.informed.formdata application/vnd.shana.informed.formtemplate application/vnd.shana.informed.interchange application/vnd.shana.informed.package application/vnd.sss-cod application/vnd.sss-dtf application/vnd.sss-ntf application/vnd.street-stream application/vnd.svd application/vnd.swiftview-ics application/vnd.triscape.mxs application/vnd.trueapp application/vnd.truedoc application/vnd.tve-trigger application/vnd.ufdl application/vnd.uplanet.alert application/vnd.uplanet.alert-wbxml application/vnd.uplanet.bearer-choice application/vnd.uplanet.bearer-choice-wbxml application/vnd.uplanet.cacheop application/vnd.uplanet.cacheop-wbxml application/vnd.uplanet.channel application/vnd.uplanet.channel-wbxml application/vnd.uplanet.list application/vnd.uplanet.listcmd application/vnd.uplanet.listcmd-wbxml application/vnd.uplanet.list-wbxml application/vnd.uplanet.signal application/vnd.vcx application/vnd.vectorworks application/vnd.vidsoft.vidconference application/vnd.visio application/vnd.vividence.scriptfile application/vnd.wap.sic application/vnd.wap.slc application/vnd.wap.wbxml wbxml application/vnd.wap.wmlc wmlc application/vnd.wap.wmlscriptc wmlsc application/vnd.webturbo application/vnd.wrq-hp3000-labelled application/vnd.wt.stf application/vnd.xara application/vnd.xfdl application/vnd.yellowriver-custom-menu application/whoispp-query application/whoispp-response application/wita application/wordperfect5.1 wp5 application/zip zip application/x-123 wk application/x400-bp application/x-bcpio bcpio application/x-cdlink vcd application/x-chess-pgn pgn application/x-core application/x-cpio cpio application/x-csh csh application/x-debian-package deb application/x-director dcr dir dxr application/x-doom wad application/x-dms dms application/x-dvi dvi application/x-executable application/x-font pfa pfb gsf pcf pcf.Z application/x-futuresplash spl application/x-gnumeric gnumeric application/x-gtar gtar tgz taz application/x-hdf hdf application/x-httpd-php phtml pht php application/x-httpd-php3 php3 application/x-httpd-php3-source phps application/x-httpd-php3-preprocessed php3p application/x-httpd-php4 php4 application/x-ica ica application/x-java-applet application/x-java-archive jar application/x-java-bean application/x-java-jnlp-file jnlp application/x-java-serialized-object ser application/x-java-vm class application/x-javascript js application/x-kdelnk application/x-kchart chrt application/x-killustrator kil application/x-kpresenter kpr kpt application/x-koan skp skd skt skm application/x-kspread ksp application/x-kword kwd kwt application/x-latex latex application/x-lha lha application/x-lzh lzh application/x-lzx lzx application/x-maker frm maker frame fm fb book fbdoc application/x-mif mif application/xml application/xml-dtd application/xml-external-parsed-entity application/x-msdos-program com exe bat dll application/x-msi msi application/x-netcdf nc cdf application/x-ns-proxy-autoconfig pac application/x-object o application/x-ogg ogg application/x-oz-application oza application/x-perl pl pm application/x-pkcs7-crl crl application/x-redhat-package-manager rpm application/x-rx application/x-sh application/x-shar shar application/x-shellscript application/x-shockwave-flash swf swfl application/x-sh sh application/x-star-office sdd sda application/x-stuffit sit application/x-sv4cpio sv4cpio application/x-sv4crc sv4crc application/x-tar tar application/x-tcl tcl application/x-tex tex application/x-tex-gf gf application/x-tex-pk pk application/x-texinfo texinfo texi application/x-trash ~ % bak old sik application/x-troff t tr roff application/x-troff-man man application/x-troff-me me application/x-troff-ms ms application/x-ustar ustar application/x-wais-source src application/x-wingz wz application/x-x509-ca-cert crt application/x-xfig fig audio/32kadpcm audio/basic au snd audio/g.722.1 audio/l16 audio/midi mid midi kar audio/mp4a-latm audio/mpa-robust audio/mpeg mpga mpega mp2 mp3 audio/mpegurl m3u audio/parityfec audio/prs.sid sid audio/telephone-event audio/tone audio/vnd.cisco.nse audio/vnd.cns.anp1 audio/vnd.cns.inf1 audio/vnd.digital-winds audio/vnd.everad.plj audio/vnd.lucent.voice audio/vnd.nortel.vbk audio/vnd.nuera.ecelp4800 audio/vnd.nuera.ecelp7470 audio/vnd.nuera.ecelp9600 audio/vnd.octel.sbc audio/vnd.qcelp audio/vnd.rhetorex.32kadpcm audio/vnd.vmx.cvsd audio/x-aiff aif aiff aifc audio/x-gsm gsm audio/x-mpegurl m3u audio/x-pn-realaudio-plugin rpm audio/x-pn-realaudio ra rm ram audio/x-realaudio ra audio/x-scpls pls audio/x-wav wav chemical/x-pdb pdb chemical/x-xyz xyz image/bmp bmp image/cgm image/g3fax image/gif gif image/ief ief image/jpeg jpeg jpg jpe image/naplps image/pcx pcx image/png png image/prs.btif image/prs.pti image/tiff tiff tif image/vnd.cns.inf2 image/vnd.dwg image/vnd.dxf image/vnd.fastbidsheet image/vnd.fpx image/vnd.fst image/vnd.fujixerox.edmics-mmr image/vnd.fujixerox.edmics-rlc image/vnd.mix image/vnd.net-fpx image/vnd.svf image/vnd.wap.wbmp wbmp image/vnd.xiff image/x-cmu-raster ras image/x-coreldraw cdr image/x-coreldrawpattern pat image/x-coreldrawtemplate cdt image/x-corelphotopaint cpt image/x-djvu djvu djv image/x-jng jng image/x-ms-bmp bmp image/x-portable-anymap pnm image/x-portable-bitmap pbm image/x-portable-graymap pgm image/x-portable-pixmap ppm image/x-rgb rgb image/x-xbitmap xbm image/x-xpixmap xpm image/x-xwindowdump xwd inode/chardevice inode/blockdevice inode/directory-locked inode/directory inode/fifo inode/socket message/delivery-status message/disposition-notification message/external-body message/http message/s-http message/news message/partial message/rfc822 model/iges igs iges model/mesh msh mesh silo model/vnd.dwf model/vnd.flatland.3dml model/vnd.gdl model/vnd.gs-gdl model/vnd.gtw model/vnd.mts model/vnd.vtu model/vrml wrl vrml multipart/alternative multipart/appledouble multipart/byteranges multipart/digest multipart/encrypted multipart/form-data multipart/header-set multipart/mixed multipart/parallel multipart/related multipart/report multipart/signed multipart/voice-message text/calendar text/comma-separated-values csv text/css css text/directory text/english text/enriched text/gemini gmi gemini text/html htm html xhtml text/mathml mml text/parityfec text/plain asc txt text diff text/prs.lines.tag text/rfc822-headers text/richtext rtx text/rtf rtf text/t140 text/tab-separated-values tsv text/uri-list text/vnd.abc text/vnd.curl text/vnd.DMClientScript text/vnd.flatland.3dml text/vnd.fly text/vnd.fmi.flexstor text/vnd.in3d.3dml text/vnd.in3d.spot text/vnd.IPTC.NewsML text/vnd.IPTC.NITF text/vnd.latex-z text/vnd.motorola.reflex text/vnd.ms-mediapackage text/vnd.wap.si text/vnd.wap.sl text/vnd.wap.wml wml text/vnd.wap.wmlscript wmls text/xml xml xsl text/x-c++hdr h++ hpp hxx hh text/x-c++src c++ cpp cxx cc text/x-chdr h text/x-crontab text/x-csh csh text/x-csrc c text/x-java java text/x-makefile text/xml-external-parsed-entity text/x-moc moc text/x-pascal p pas text/x-setext etx text/x-sh sh text/x-tcl tcl tk text/x-tex tex ltx sty cls text/x-vcalendar vcs text/x-vcard vcf video/dl dl video/fli fli video/gl gl video/mpeg mpeg mpg mpe video/quicktime qt mov video/mp4v-es video/parityfec video/pointer video/vnd.fvt video/vnd.motorola.video video/vnd.motorola.videop video/vnd.mpegurl mxu video/vnd.mts video/vnd.nokia.interleaved-multimedia video/vnd.vivo video/x-mng mng video/x-ms-asf asf asx video/x-msvideo avi video/x-sgi-movie movie x-conference/x-cooltalk ice x-world/x-vrml vrm vrml wrl pygopherd-3.0.1/conf/pygopherd.conf000066400000000000000000000412171456676541200173360ustar00rootroot00000000000000###################################################################### # OVERALL SETTINGS FOR PYGOPHERD ###################################################################### [pygopherd] ################################################## # Operating System / Overall Behavior ################################################## # Set this to true if you want the server to "detach" itself; that is, # to go into the background after it starts. detach = no # If you want gopherd to write a PID file, set this to the location # where you want it. Otherwise, comment out this line. pidfile = /var/run/pygopherd/pygopherd.pid ################################################## # Network ################################################## # The server name to present to the world. If you do not specify it # here, Pygopherd will attempt to figure it out automatically. # This is used only to present to clients. It does not control # where the server listens. # # servername = gopher.example.com # The interface on which to listen. It should be an IP address or # a domain name. If specified, pygopherd will attempt to listen to # the specified port on only this interface -- useful if you are doing # virtual hosting. If not specified, pygopherd will listen on all # interfaces the OS provides. If in doubt, do not specify this. # # interface = gopher.example.com # What port to listen on. If not running as root, this must be # greater than 1024. port = 70 # Type of server to run. Valid options are ForkingTCPServer # and ThreadingTCPServer. ForkingTCPServer is highly recommended # for now. servertype = ForkingTCPServer # What port to *say* we're listening on. Most people should NOT # specify this. You might want to if you are using firewalling or # port forwarding and the port number is different to the world than # it is locally. # advertisedport = 70 # Do we timeout on client conections? HIGHLY RECOMMENDED! # Value is given in seconds. If given, any read or write that makes # no progress in this number of seconds will time out. timeout = 60 ################################################## # Data Handling ################################################## # You can add a header to every directory by creating a # .abstract file in that directory and filling it with the # information you like. This will then be rendered as a header # for the directory. This option controls this feature. Note: # for this to work, you must define a mapping to ABSTRACT in eaexts # below. abstract_headers = on # Individual files and folders can also have abstracts. You can # choose to have pygopherd render these abstracts in the directory # listing itself -- they'll appear beneath the menu name for the file. # You can set this option to any of three values: # # always -- always render these abstracts. # unsupported -- render them only for protocols that do not natively # support abstracts. Gopher+ is the only protocol that natively # supports them currently. # never -- never render these abstracts. abstract_entries = always ################################################## # Error handling ################################################## # If there is an error, you can decide whether or not to log a full # backtrace. A full backtrace will usually be needed to find the # problem. tracebacks = yes ################################################## # Security ################################################## ## Whether or not to use chroot. # This option is only valid if you are running pygopherd as root! usechroot = yes ## Username and groupname to setreuid/setregid to. Valid only if ## starting pygopherd as root. Comment out if you don't want this ## functionality. NOTE: DO NOT RUN AS ROOT UNLESS YOU USE THESE! BAD BAD BAD! #setuid = gopher #setgid = gopher ################################################## # TLS ################################################## # Enable TLS by sniffing the first byte of the client request for the start of # a TLS handshake. This allows both TLS and plaintext requests to be served # over the same port. enable_tls = no # File paths to the server certificate and keyfile in PEM format. These are # required if TLS is enabled. When using chroot, the certificates will be # loaded while root privileges are still active. # # tls_certfile = # tls_keyfile = ################################################## # Filesystem and MIME ################################################## # Where the documents are stored. root = /var/gopher # Location of a file to use to figure out MIME types. You can # specify multiple files here -- just separate them with a colon. # ALL of them that are found will be read. mimetypes = ./conf/mime.types:/etc/pygopherd/mime.types:/etc/mime.types # Encodings. You can use the default with the following syntax. The # mimetypex.encodings_map is {'.Z': 'compress', '.gz': 'gzip'}. # # For ease of use in the config file, we specify this as a list of # tuples. You can convert any hash to a list of tuples by using .items() # encoding = mimetypes.encodings_map.items() # You can override the default entirely (ie, to remove those) like this: # encoding = {'.bz2' : 'bzip2', '.gz' : 'gzip'}.items() # Or the same thing: # encoding = [('.bz2', 'bzip2'), ('.gz', 'gzip')] # Or, you can extend the default like so: encoding = list(mimetypes.encodings_map.items()) + \ list({'.bz2' : 'bzip2', '.tal': 'tal.TALFileHandler' }.items()) ###################################################################### # Logging ###################################################################### [logger] # Log method to use. One of: # syslog -- use Unix syslog facility # file -- log to standard output (future capability for logging to other # files) # none -- no logging logmethod = syslog # If you enable syslog, you will need to define these as well: # priority -- one of the following (listed in order of high to low): # LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, # LOG_INFO, LOG_DEBUG priority = LOG_INFO # Facility -- one of the following: # LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_LPR, LOG_NEWS, # LOG_UUCP, LOG_CRON, LOG_LOCAL0 - LOG_LOCAL7 facility = LOG_LOCAL3 ###################################################################### # GOPHER OBJECTS ###################################################################### # Settings for gopher objects [GopherEntry] # Use this MIME type if no other type is found. defaultmimetype = text/plain # Mapping from MIME types to gopher0 single-character types. # This is a list of lists. The first entry in each list is a # regexp to match and the second is the result. # # Please have a .* at the end to map all unknown types to a certain # character. For best results, that character should be nicely # corresponding to the defaultmimetype. mapping = [['text/html', 'h'], ['text/.+', '0'], ['application/mac-binhex40', '4'], ['audio/.+', 's'], ['image/gif', 'g'], ['image/.+', 'I'], ['application/gopher-menu', '1'], ['application/gopher\\+-menu', '1'], ['multipart/mixed', 'M'], ['application/.+', '9'], ['.*', '0'] ] # This is used by the system to generate Extended Attribute (EA), aka # Gopher+ blocks for a file. Basically, with the setup shown below, # you can create "filename.txt.abstract" to define the abstract # property for filename.txt. If you do that, you will probably want # to add these properties to ignorepatt below. The list is a mapping # from an extension to a block name. # # Sample for UMN compatibility: # eaexts = {'.abstract' : 'ABSTRACT', '.keywords' : 'KEYWORDS', '.ask' : 'ASK', '.3d' : '3D'} # # If you want to disable this capability, use this: # # eaexts = {} ###################################################################### # HANDLERS ###################################################################### ################################################## # Handler multiplexer ################################################## [handlers.HandlerMultiplexer] # A list of the handlers to consider. The handlers # are tried in the order listed. # # ### Suggested settings: # Note: the UMNDirHandler will handle all directories, even if they # do not have UMN-specific files, so you do not need to list the # dirhandler in this case. # # Warning: scriptexec and pyg can execute arbitrary code stored in # your path. Don't enable unless you know what you're doing! # # For UMN emulation: (full UMN featureset excluding scriptexec, no others) # # handlers = [url.HTMLURLHandler, UMN.UMNDirHandler, # html.HTMLFileTitleHandler, # mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, # file.CompressedFileHandler, file.FileHandler] # # For Bucktooth emulation: (full Buck featureset excluding scriptexec) # #handlers = [gophermap.BuckGophermapHandler, url.HTMLURLHandler, # file.FileHandler, dir.DirHandler] # # For full Pygopherd featureset excluding scripts, compression, and PYG. # Supports both UMN and Bucktooth featuresets. This is the default # configuration for Pygopherd because it is secure yet versatile. # handlers = [url.HTMLURLHandler, gophermap.BuckGophermapHandler, mbox.MaildirFolderHandler, mbox.MaildirMessageHandler, UMN.UMNDirHandler, html.HTMLFileTitleHandler, mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, file.FileHandler] # For full Pygopherd featureset including scripts and PYG. Same as # above but adds scripts, decompression, and PYG execution. #handlers = [url.HTMLURLHandler, gophermap.BuckGophermapHandler, # mbox.MaildirFolderHandler, mbox.MaildirMessageHandler, # UMN.UMNDirHandler, # tal.TALFileHandler, # html.HTMLFileTitleHandler, # mbox.MBoxMessageHandler, mbox.MBoxFolderHandler, # pyg.PYGHandler, scriptexec.ExecHandler, # file.CompressedFileHandler, file.FileHandler, # url.URLTypeRewriter] ################################################## # Decompressing file handler ################################################## [handlers.file.CompressedFileHandler] # Decompressors is a map from an encoding (as specified in the # pygopherd section above) to a decompression program. # The decompression program must # accept the input in its stdin and write the decompressed output # to stdout. # # If you do not want to decompress things automatically for your # clients, you might wish to NOT use this handler. # # Note: this feature is probably NOT compatible with chroot unless # you take extra precautions. # We enable no decompressors by default... you'll need to do that. decompressors = {} #decompressors = {'bzip2': 'bzcat', # 'gzip' : 'zcat', # 'compress' : 'zcat'} # Regexp to match against filenames pending decompression. # The default will let ALL files be decompressed. decompresspatt = .* # You can be more restrictive: # decompresspatt = \.txt\.(bz2|gz|Z)$ ################################################## # Directory handler ################################################## [handlers.dir.DirHandler] # A regular expression of files to ignore. These files # will not be presented in lists of files to clients, # but if clients know the exact path to the files, they can # still be requested. # # This pattern is matched against the requested selector. # Selectors are guaranteed to begin with a slash by this point. # and never end with a slash unless they consist solely of a slash. # # By default, we ignore files starting with a period, gophermap # files, and files ending with a tilde. # # The default emulates UMN's default plus buck. Please note: # UMNDirHandler implicitly will keep all files starting with a dot out of # directory listings. If you exclude these files explicitly in ignorepatt, # then not only will they not show up, but the handler will also not scan # them for links and the like. # # A buck-only server might like: # # ignorepatt = ~$|/\.|/gophermap$ ignorepatt = /.cap$|/lost\+found$|/lib$|/bin$|/etc$|/dev$|~$|/\.cache|/\.forward$|/\.message$|/\.hushlogin$|/\.kermrc$|/\.notar$|/\.where$|/veronica.ctl$|/robots.txt$|/nohup.out$|/gophermap$|\.abstract$|\.keyboards$|\.ask|\.3d$|~$ # Expiration time, in seconds, for the cache. # Set to 0 to disable caching entirely. cachetime = 180 # Name of the cahe file. Must be set to something even if the cachetime # is zero. In that case, this filename will not be used but for the conf # file to parse, it must still be set. cachefile = .cache.pygopherd.dir ################################################## # UMN Directory Handler ################################################## [handlers.UMN.UMNDirHandler] # Extension stripping behavior. When a file from a directory # is presented in a menu, and no name is given, what to do? # For instance, given a file Welcome.txt and pygopherd.tar.gz: # # If extstrip is none, present Welcome.txt and pygopherd.tar.gz in the # menu. # # If extstrip is nonencoded, modify only those files that do not # have encodings. (If CompressedFileHandler is used, modify only # those files that to not have *HANDLED* encodings.) # If gzip is NOT a handled encoding, you'd get names Welcome and # pygopherd.tar.gz. If gzip IS a handled encoding, you'd get # Welcome and pygopherd. # # If extstrip is full, modify all modifyable names. Welcome.txt -> # Welcome and pygopherd.tar.gz -> pygopherd. # extstrip = none extstrip = nonencoded # extstrip = full [handlers.ZIP.ZIPHandler] ################################################## # ZIP file handler ################################################## # Even if it's listed in the available handlers, it's disabled here by # default. enabled = false pattern = \.zip$ ###################################################################### # PROTOCOLS ###################################################################### ################################################## # Protocol Multiplexer ################################################## [protocols.ProtocolMultiplexer] # A list of the protocols to consider for each request. # The protocols are tried in the order listed. protocols = [wap.WAPProtocol, gemini.GeminiProtocol, http.HTTPProtocol, http.HTTPSProtocol, spartan.SpartanProtocol, gopherp.GopherPlusProtocol, gopherp.SecureGopherPlusProtocol, rfc1436.GopherProtocol, rfc1436.SecureGopherProtocol] ################################################## # Gopher+ Protocol ################################################## [protocols.gopherp.GopherPlusProtocol] # The name and e-mail of the administrator admin = Unconfigured Pygopherd Admin ################################################## # HTTP Protocol ################################################## [protocols.http.HTTPProtocol] iconmapping = {'h' : 'text.gif', '0' : 'text.gif', '4' : 'binhex.gif', 's' : 'sound1.gif', 'g' : 'image3.gif', 'I' : 'image3.gif', 'M' : 'text.gif', '9' : 'binary.gif', '1' : 'folder.gif', '7' : 'folder.gif', 'i' : 'blank.gif'} # You can use this option to put something at the top of each HTML # page generated. # # The following tokens will be interpolated: # # GOPHERURL -- the Gopher URL for this page. # pagetopper = Welcome to Gopherspace! You are browsing Gopher through a Web interface right now. You can use most browsers or Gopher clients to browse Gopher natively. If your browser supports it, try clicking here to see this page in Gopher directly. To find Gopher browsers, click here.
################################################## # WAP Protocol ################################################## [protocols.wap.WAPProtocol] # waptop is the URL to access with WAP devices. The default, /wap, means # that accessing http://sitename.com/wap will bring up your site in WAP # mode. # # PyGopherd can autodetect WAP from some phones, so this is not always # necessary. waptop = /wap ################################################## # Gemini Protocol ################################################## [protocols.gemini.GeminiProtocol] # Note that the gemini protocol *requires* the TLS section to also be enabled. footer = => https://www.github.com/michael-lazar/pygopherd Generated by PyGopherd ################################################## # Spartan Protocol ################################################## [protocols.gemini.SpartanProtocol] footer = => https://www.github.com/michael-lazar/pygopherd Generated by PyGopherd pygopherd-3.0.1/doc/000077500000000000000000000000001456676541200143015ustar00rootroot00000000000000pygopherd-3.0.1/doc/book.sgml000066400000000000000000000005601456676541200161200ustar00rootroot00000000000000PyGopherd"> ]> PyGopherd Manual</> </bookinfo> &maindoc; &manpage; </book> ������������������������������������������������������������������������������������������������������������������������������������������������pygopherd-3.0.1/doc/manpage.sgml��������������������������������������������������������������������0000664�0000000�0000000�00000016264�14566765412�0016606�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!-- <!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ <!ENTITY PyGopherd "<application>PyGopherd</application>"> <!ENTITY OfflineIMAP "<application>OfflineIMAP</application>"> ]> --> <!-- "file:///usr/share/sgml/docbook/dtd/xml/4.2/docbookx.dtd"> --> <reference id="pygopherd.man"> <title>PyGopherd Manpage
jgoerzen@complete.org
JohnGoerzen
pygopherd 8 John Goerzen PyGopherd Multiprotocol Information Server pygopherd configfile Description Welcome to &PyGopherd;. In a nutshell, &PyGopherd; is a modern dynamic multi-protocol hierarchical information server with a pluggable modularized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for standardized yet extensible per-document metadata. Whew! Read on for information on this what all these buzzwords mean. Quick Start &quickstart; Options All &PyGopherd; configuratoin is done via the configuration file. Therefore, the program has only one command-line option: configfile This option argument specifies the location of the configuration file that &PyGopherd; is to use. Conforming To The Internet Gopher Protocol as specified in RFC1436 The Gopher+ upward-compatible enhancements to the Internet Gopher Protocol from the University of Minnesota as laid out at . The gophermap file format as originally implemented in the Bucktooth gopher server and described at . The Links to URL specification as laid out by John Goerzen at . The UMN format for specifying object attributes and links with .cap, .Links, .abstract, and similar files as specified elsewhere in this document and implemented by UMN gopherd. The PYG format for extensible Python gopher objects as created for &PyGopherd;. Hypertext Transfer Protocol HTTP/1.0 as specified in RFC1945 Hypertext Markup Language (HTML) 3.2 and 4.0 Transitional as specified in RFC1866 and RFC2854. Maildir as specified in and . The mbox mail storage format as specified in . Registered MIME media types as specified in RFC2048. Script execution conforming to both UMN standards as laid out in UMN gopherd(1) and Bucktooth standards as specified at , so far as each can be implemented consistent with secure design principles. Standard Python 2.2.1 or above as implemented on POSIX-compliant systems. WAP/WML as defined by the WAP Forum. Bugs Reports of bugs should be sent via e-mail to the &PyGopherd; issue tracker at . The Web site also lists all current bugs, where you can check their status or contribute to fixing them. Copyright &PyGopherd; is Copyright (C) 2002-2019 John Goerzen, 2021 Michael Lazar. 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; version 2 of the License. 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: Free Software Foundation, Inc. 59 Temple Place Suite 330 Boston, MA 02111-1307 USA Author &PyGopherd;, its libraries, documentation, and all included files (except where noted) was written by John Goerzen jgoerzen@complete.org and copyright is held as stated in the Copyright section. Portions of this manual (specifically relating to certian UMN gopherd features and characteristics that PyGopherd emulates) are modified versions of the original gopherd(1) manpage accompanying the UMN gopher distribution. That document is distributed under the same terms as this, and bears the following copyright notices: Copyright (C) 1991-2000 University of Minnesota Copyright (C) 2000-2002 John Goerzen and other developers &PyGopherd; may be downloaded, and information found, from its homepage: See Also python (1).
pygopherd-3.0.1/doc/pygopherd.8000066400000000000000000000141221456676541200163730ustar00rootroot00000000000000.\" This manpage has been automatically generated by docbook2man .\" from a DocBook document. This tool can be found at: .\" .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng . .TH "PYGOPHERD" "8" "26 November 2022" "John Goerzen" "PyGopherd Manpage" .SH NAME PyGopherd \- Multiprotocol Information Server .SH SYNOPSIS \fBpygopherd\fR [ \fB\fIconfigfile\fB\fR ] .SH "DESCRIPTION" .PP Welcome to \fBPyGopherd\fR\&. In a nutshell, \fBPyGopherd\fR is a modern dynamic multi-protocol hierarchical information server with a pluggable modularized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for standardized yet extensible per-document metadata. Whew! Read on for information on this what all these buzzwords mean. .SH "QUICK START" .PP If you have already installed \fBPyGopherd\fR system-wide, or your administrator has done that for you, your task for setting up \fBPyGopherd\fR for the first time is quite simple. You just need to set up your configuration file, make your folder directory, and run it! .PP You can quickly set up your configuration file. The distribution includes two files of interest: \fIconf/pygopherd.conf\fR and \fIconf/mime.types\fR\&. Debian users will find the configuration file pre-installed in \fI/etc/pygopherd/pygopherd.conf\fR and the \fImime.types\fR file provided by the system already. .PP Open up \fIpygopherd.conf\fR in your editor and adjust to suit. The file is heavily commented and you can refer to it for detailed information. Some settings to take a look at include: \fIdetach\fR, \fIpidfile\fR, \fIport\fR, \fIusechroot\fR, \fIsetuid\fR, \fIsetgid\fR, and \fIroot\fR\&. These may or may not work at their defaults for you. The remaining ones should be fine for a basic setup. .PP Invoke \fBPyGopherd\fR with \fBpygopherd path/to/configfile\fR (or \fB/etc/init.d/pygopherd start\fR on Debian). Place some files in the location specified by the \fIroot\fR directive in the config file and you're ready to run! .SH "OPTIONS" .PP All \fBPyGopherd\fR configuratoin is done via the configuration file. Therefore, the program has only one command-line option: .TP \fB\fIconfigfile\fB\fR This option argument specifies the location of the configuration file that \fBPyGopherd\fR is to use. .SH "CONFORMING TO" .TP 0.2i \(bu The Internet Gopher Protocol as specified in RFC1436 .TP 0.2i \(bu The Gopher+ upward-compatible enhancements to the Internet Gopher Protocol from the University of Minnesota as laid out at \&. .TP 0.2i \(bu The gophermap file format as originally implemented in the Bucktooth gopher server and described at \&. .TP 0.2i \(bu The Links to URL specification as laid out by John Goerzen at \&. .TP 0.2i \(bu The UMN format for specifying object attributes and links with .cap, .Links, .abstract, and similar files as specified elsewhere in this document and implemented by UMN gopherd. .TP 0.2i \(bu The PYG format for extensible Python gopher objects as created for \fBPyGopherd\fR\&. .TP 0.2i \(bu Hypertext Transfer Protocol HTTP/1.0 as specified in RFC1945 .TP 0.2i \(bu Hypertext Markup Language (HTML) 3.2 and 4.0 Transitional as specified in RFC1866 and RFC2854. .TP 0.2i \(bu Maildir as specified in and \&. .TP 0.2i \(bu The mbox mail storage format as specified in \&. .TP 0.2i \(bu Registered MIME media types as specified in RFC2048. .TP 0.2i \(bu Script execution conforming to both UMN standards as laid out in UMN gopherd(1) and Bucktooth standards as specified at , so far as each can be implemented consistent with secure design principles. .TP 0.2i \(bu Standard Python 2.2.1 or above as implemented on POSIX-compliant systems. .TP 0.2i \(bu WAP/WML as defined by the WAP Forum. .SH "BUGS" .PP Reports of bugs should be sent via e-mail to the \fBPyGopherd\fR issue tracker at \&. .PP The Web site also lists all current bugs, where you can check their status or contribute to fixing them. .SH "COPYRIGHT" .PP \fBPyGopherd\fR is Copyright (C) 2002-2019 John Goerzen, 2021 Michael Lazar. .PP 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; version 2 of the License. .PP 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. .PP You should have received a copy of the GNU General Public License along with this program; if not, write to: .nf Free Software Foundation, Inc. 59 Temple Place Suite 330 Boston, MA 02111-1307 USA .fi .SH "AUTHOR" .PP \fBPyGopherd\fR, its libraries, documentation, and all included files (except where noted) was written by John Goerzen and copyright is held as stated in the Copyright section. .PP Portions of this manual (specifically relating to certian UMN gopherd features and characteristics that PyGopherd emulates) are modified versions of the original gopherd(1) manpage accompanying the UMN gopher distribution. That document is distributed under the same terms as this, and bears the following copyright notices: .nf Copyright (C) 1991-2000 University of Minnesota Copyright (C) 2000-2002 John Goerzen and other developers .fi .PP \fBPyGopherd\fR may be downloaded, and information found, from its homepage: .PP .PP .SH "SEE ALSO" .PP python (1). pygopherd-3.0.1/doc/pygopherd.html000066400000000000000000001412561456676541200172010ustar00rootroot00000000000000 PyGopherd Manual

Chapter 1. Introduction to PyGopherd

Welcome to PyGopherd. In a nutshell, PyGopherd is a modern dynamic multi-protocol hierarchical information server with a pluggable modularized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for standardized yet extensible per-document metadata. Whew! Read on for information on what all these buzzwords mean.


1.1. Features

Here are some of PyGopherd's features:

  • Provides built-in support for multiple protocols: HTTP (Web), Gopher+, Gopher (RFC1436), Enhanced Gopher0, Gemini, Spartan, and WAP (mobile phones). Protocols can be enabled or disabled as desired.

  • Provides protocol autodetection. That is, PyGopherd can listen for all the above protocols on a single port and will automatically respond using the protocol it detects the client is using. Practical effects of this are that you can, for instance, give out a single URL and have it viewable normally on desktop Web browsers and in WAP mode on mobile phones -- and appropriately in various Gopher browsers.

  • Metadata and site links can be entered in a variety of formats, including full UMN dotfile metadata formats as well as Bucktooth gophermap files. Moreover, gophermap files are not limited to Gopher protocols, and can be used for all protocols.

  • Support for inter-protocol linking (linking from Gopher sites to web sites)

  • Virtual folder system lets you serve up anything as if it were regular files and directories. PyGopherd comes with the following virtual folder systems built in:

    • Can present any Unix MBOX, MMDF box, MH directory, Maildir directory, or Babyl mailbox as a virtual folder, the contents of which are the messages in the mailbox.

    • Can use a configurable separator to split a file into multiple parts, the first line of each becoming the name for the virtual folder.

    • Can peek inside a ZIP file and serve it up as first-class site citizens -- metadata can even be stored in the ZIP files.

    • Can serve up the contents of a dictd server as a filesystem.

  • Modular, extensible design: you can use PyGopherd's own PYG extension format, or UMN- or Bucktooth-style executables.

  • Runs on any platform supported by Python 2.2, 2.3, or 2.4. This includes virtually every past and current flavor of Unix (Linux, *BSD, Solaris, SunOS), Windows, MacOS 9.x and X, and more. Some features may not be available on non-Unix platforms.

  • Runs on any platform supported by Java 1.1 via the Jython Python implementation.

  • Tunable server types via configuration directive -- forking or threading.

  • Secure design with support for chrooted execution.

  • Feature-complete, full implementations of: Gopher0 (RFC1435), Gopher+, HTTP, and WAP.

  • Support for automatically finding the titles of HTML documents for presentation in a directory.

  • Versatile configuration file format is both extensible and nicely complementary of the module system.

  • Protocol-independent, handler-dependent caching. This increases performance by letting handlers cache dynamically-generated information -- currently used by the directory handlers. This can improve performance of directories by several orders of magnitude. Because this is a handler cache only, all protocols share the single cache. Since the processing time for the protocols is negligible, this works out very well.

  • Autosensing of MIME types and gopher0 item types. Both are completely configurable. MIME type detection is done using a standard mime.types file, and gopher0 types are calculated by using a configurable regexp-based MIME-to-gophertype map.

  • Heavy support of regular expressions in configuration.

  • ProtocolMultiplexer and HandlerMultiplexer let you choose only those protocols and handlers that you wish your server to support and the order in which they are tried when a request comes in.

  • Full logging via syslog.


1.2. About Gopher

PyGopherd started life as a server for the Gopher Internet protocol. With Gopher, you can mount a filesystem (viewing files and folders as if they were local), browse Gopherspace with a web browser, download files, and be interactive with searching.

But this is only part of the story. The world of Gopher is more expansive than this. There are two major gopher protocols: Gopher0 (also known as RFC1436) and Gopher+. Gopher0 is a small, simple, lightweight protocol that is very functional yet also extremely easy to implement. Gopher0 clients can be easily placed in small embedded devices or in massive environments like a modern web browser.

Gopher+ is based on Gopher0 but extends it by providing document metadata such as file size and MIME type. Gopher+ allows all sorts of neat features, such as configurable metadata (serving up a bunch of photos? Add a Subject field to your metadata to let a customized photo browser display who is pictured) and multiple views of a file (let the user select to view your photos as PNG or JPEG).


Chapter 2. Quick Start

If you have already installed PyGopherd system-wide, or your administrator has done that for you, your task for setting up PyGopherd for the first time is quite simple. You just need to set up your configuration file, make your folder directory, and run it!

You can quickly set up your configuration file. The distribution includes two files of interest: conf/pygopherd.conf and conf/mime.types. Debian users will find the configuration file pre-installed in /etc/pygopherd/pygopherd.conf and the mime.types file provided by the system already.

Open up pygopherd.conf in your editor and adjust to suit. The file is heavily commented and you can refer to it for detailed information. Some settings to take a look at include: detach, pidfile, port, usechroot, setuid, setgid, and root. These may or may not work at their defaults for you. The remaining ones should be fine for a basic setup.

Invoke PyGopherd with pygopherd path/to/configfile (or /etc/init.d/pygopherd start on Debian). Place some files in the location specified by the root directive in the config file and you're ready to run!


Chapter 3. Installation

If you are reading this document via the "man" command, it is likely that you have no installation tasks to perform; your system administrator has already installed PyGopherd. If you need to install it yourself, you have three options: a system-wide installation with Debian, system-wide installation with other systems, and a single-user installation. You can download the latest version of PyGopherd from https://github.com/michael-lazar/pygopherd


3.1. Debian System-Wide Installation

You may install PyGopherd by simply running this command as root:

apt-get install pygopherd


3.2. Other System-Wide Installation

Download the tar.gz version of the package from the website. Make sure you have Python 3.7 or above installed; if not, download and install it from http://www.python.org/. Then run these commands:

      tar -zxvf pygopherd-x.y.z.tar.gz
      cd pygopherd-x.y.z
      python3 setup.py
    

Next, proceed to configuration. Make sure that the /etc/pygopherd/pygopherd.conf file names valid users (setuid and setgid options) and a valid document root (root option).

You will type pygopherd to invoke the program.


3.3. Single-Account Installation

Download the tar.gz version of the package from the website. Make sure you have Python 2.2 or above installed; if now, download and install it from http://www.python.org/. Then run these commands:

      tar -zxvf pygopherd-z.y.z.tar.gz
      cd pygopherd-x.y.z
    

Modify conf/pygopherd.conf as follows:

  • Set usechroot = no

  • Set root to something appropriate.

  • Set port to a number greater than 1024.

When you want to run PyGopherd, you will issue the cd command as above and then type PYTHONPATH=. bin/pygopherd. There is no installation step necessary.


Chapter 4. Configuration

PyGopherd is regulated by a configuration file normally stored in /etc/pygopherd/pygopherd.conf. You can specify an alternate configuration file on the command line. The PyGopherd distribution ships with a sample pygopherd.conf file that thoroughly documents the configuration file options and settings.


Chapter 5. Handlers

PyGopherd defines several handlers which are responsible for finding data on your server and presenting it to the user. The handlers are used to generate things like links to other documents and directory listings. They are also responsible for serving up regular files and even virtual folders.

Handlers are specified with the handlers option in pygopherd.conf. This option is a list of handlers to use. For each request that arrives, PyGopherd will ask each handler in turn whether or not it can handle the request, and will handle the request according to the first handler that is capable of doing so. If no handlers can handle the request, a file not found error is generated. See the example configuration file for an example.

The remaining parts of this section describe the different handlers that ship with PyGopherd.


5.1. dir.DirHandler

This handler is a basic one that generates menus based on the contents of a directory. It is used for directories that contain neither a gophermap file nor UMN-style links files, or situations where you have no need for either of those.

This handler simply reads the contents of your on-disk directory, determines the appropriate types of each file, and sends the result to the client. The descriptions of each item are usually set to the filename, but the html.HTMLFileTitleHandler may override that.


5.2. gophermap.BuckGophermapHandler

This handler is used to generate directory listings based on gophermap files. It will not read the directory on-disk, instead serving content from the gophermap file only. Gophermaps are useful if you want to present a directory in which the files do not frequently change and there is general information to present. Overall, if you only wish to present information particular to certain files, you should consider using the abstract feature of UMN.UMNDirHandler.

The gophermap files contain two types of lines, which are described here using the same convention normally used for command line arguments. In this section, the symbol \t will be used to indicate a tab character, Control-I.

full line of informational text

gophertypeDESCRIPTION [\tselector [\thost [\tport]]]

Note: spaces shown above are for clarity only and should not actually be present in your file.

The informational text must not contain any tab characters, but may contain spaces. Informational text will be rendered with gopher type i, which will cause it to be displayed on a client's screen at its particular position in the file.

The second type of line represents a link to a file or directory. It begins with a single-character Gopher type (see Gopher Item Types below) followed immediately by a description and a tab character. There is no space or other separator between the gopher type and the description. The description may contain spaces but not tabs.

The remaining arguments are optional, but only to the extent that arguments may be omitted only if all arguments after them are also omitted. These arguments are:

selector

The selector is the name of the file on the server. If it begins with a slash, it is an absolute path; otherwise, it is interpreted relative to the directory that the gophermap file is in. If no selector is specified, the description is also used as the selector.

host

The host specifies the host on which this resource is located. If not specified, defaults to the current server.

port

The port specifies the port on which the resource is located. If not specified, defaults to the port the current server is listening on.

An example of a gophermap to help illustrate the concept is included with the PyGopherd distribution in the file examples/gophermap.


5.3. file.CompressedFileHandler

In order to save space, you might want to store documents on-disk in a compressed format. But then clients would ordinarily have to decompress the files themselves. It would be nice to have the server automatically decompress the files on the fly, sending that result to the client. That's where file.CompressedFileHandler comes in.

This handler will take compressed files, pipe them through your chosen decompression program, and send the result directly to clients -- completely transparently.

To use this handler, set the decompressors option in the configuration file. This option defines a mapping from MIME encodings (as defined with the encoding option) to decompression programs. Files that are not encoded, or which have an encoding that does not occur in the decompressors map, will not be decompressed by this handler.

Please see the sample configuration file for more examples and details about the configuration of this handler.


5.4. file.FileHandler

The file.FileHandler is just that -- its duty is to serve up regular files to clients.


5.5. html.HTMLFileTitleHandler

This handler is used when generating directories and will set the description of HTML files to the HTML title defined in them rather than let it be the default filename. Other than that, it has no effect. UMN gopherd implements a similar policy.


5.6. mbox handlers

There are four mailbox handlers:

  • mbox.MaildirFolderHandler

  • mbox.MaildirMessageHandler

  • mbox.MBoxMessageHandler

  • mbox.MBoxFolderHandler

These four handlers provide a unique "virtual folder" service. They allow you to present mailboxes as if they were folders, the items of the folders being the messages in the mailbox, organized by subject. This is useful for presenting mail archives or just making e-mail accessible in a nice and easy fashion.

To use these handlers, all you have to do is enable them in your handlers section. They will automatically detect requests for mailboxes and handle them appropriately.

The different handlers are for traditional Unix mbox mailboxes (all messages in a single file) and new qmail-stype Maildir mailboxes. You can enable only the two handlers for the specific mailbox type that you use, if desired.


5.7. pyg.PYGHandler

PYG (short for PYGopherd) is a mechanism that provides a tremendous amount of flexibility. Rather than just letting you execute a script like other Gopher or HTTP servers, PYGs are actually loaded up into PyGopherd and become fully-capable first-class virtual handlers. Yet they need not be known ahead of time, and are loaded dynamically.

With a PYG handler, you can generate gopher directories, handle searches, generate files, and more on the fly. You can create entire virtual directory trees (for instance, to interface with NNTP servers or with DICT servers), and access them all using the standard Gopher protocol. All of this without having to modify even one line of PyGopherd code.

If enabled, the pyg.PYGHandler will look for files with the extension .pyg that are marked executable. If found, they will be loaded and run as PYGs.

Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it.

See the virtual.Virtual handler for more information about passing data to your scripts at runtime.

At present, documentation on writing PYGs is not provided, but you may find examples in the pygfarm directory included with the PyGopherd distribution.


5.8. scriptexec.ExecHandler

This handler implements "old-style" script execution; that is, executing arbitrary programs and piping the result to the client. It is, for the most part, compatible with both scripts written for UMN gopherd and the Bucktooth gopher server. If enabled, it will execute any file that is marked executable in the filesystem. It will normally list scripts as returning plain text, but you may create a custom link to the script that defines it as returning whatever kind of file you desire. Unlike PYGs, this type must be known in advance.

The scriptexec.ExecHandler will set environment variables for your scripts to use. They are as follows:

SERVER_NAME

The name of this server as defined in the configuration file or detected from the operating system.

SERVER_PORT

The port this server is listening on.

REMOTE_ADDR

The IP address of the client.

REMOTE_PORT

The port number of the client.

REMOTE_HOST

The same value as REMOTE_ADDR

SELECTOR

The file that was requested; that is, the relative path to this script. If the selector included additional parameters after a |, they will be included in this string as well.

REQUEST

The "base" part of the selector; that is, the part leading up to the |.

SEARCHREQUEST

Included only if the client specified search data, this is used if the client is searching for something.

See the virtual.Virtual handler for more information about passing data to your scripts at runtime.

Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it.


5.9. UMN.UMNDirHandler

This is one of the most powerful workhorse handlers in PyGopherd. It is designed to emulate most of the ways in which the UMN gopherd distribution generates directories, even going so far as to be bug-compatible in some cases. Generating directories with this handler is often the best general-purpose way to make nice directories in gopherspace.

The remainder of the description of the UMN.UMNDirHandler, except for the Abstracts and Info section, is lifted directly from the original UMN gopherd documentation, with light editing, because this handler implements it so exactly that there was no point in rewriting all that documentation :-)


5.9.1. Links

You can override the default view of a directory as generated by dir.DirHandler by creating what are known as Links in the data tree.

The ability to make links to other hosts is how gopher distributes itself among multiple hosts. There are two different ways to make a link. The first and simplest is to create a link file that contains the data needed by the server. By default all files in the gopher data directory starting with a period are taken to be link files. A link file can contain multiple links. To define a link you need to put five lines in a link file that define the needed characteristics for the document. Here is an example of a link.

Name=Cheese Ball Recipes
Numb=1
Type=1
Port=150
Path=1/Moo/Cheesy
Host=zippy.micro.umn.edu
      

The Name= line is what the user will see when cruising through the database. In this case the name is "Cheese Ball Recipes". The "Type=" defines what kind of document this object is. For a list of all defined types, see Gopher Item Types below. For Gopher+ and HTTP, a MIME type is also used, which is determined automatically based on the type you specify.

The "Path=" line contains the selector string that the client will use to retrieve the actual document. The Numb= specifies that this entry should be presented first in the directory list (instead of being alphabetized). The "Numb=" line is optional. If it is present it cannot be the last line of the link. The "Host=" and "Port=" lines specify a fully qualified domain name (FQDN) and a port respectively. You may substitute a plus '+' for these two parameters if you wish. The server will insert the current hostname and the current port when it sees a plus in either of these two fields.

An easy way to retrieve links is to use the Curses Gopher Client. By pressing '=' You can get information suitable for inclusion in a link file.


5.9.2. Overriding Defaults

The server looks for a directory called .cap when parsing a directory. The server then checks to see if the .cap directory contains a file with the same name as the file it's parsing. If this file exists then the server will open it for reading. The server parses this file just like a link file. However, instead of making a new object, the parameters inside the .cap/ file are used to override any of the server supplied default values.

For instance, say you wanted to change the Title of a text file for gopher, but don't want to change the filename. You also don't want it alphabetized, instead you want it second in the directory listing. You could make a set-aside file in the .cap directory with the same filename that contained the following lines:

Name=New Long Cool Name
Numb=2
      

An alternative to .cap files are extended link files. They work just the same as the files described in Links above, but have a somewhat abbreviated format. As an example, if the name of the file was file-to-change, then you could create a file called .names with the following contents:

Path=./file-to-change
Name=New Long Cool Name
Numb=2
      

5.9.3. Adding Cool Links

One cool thing you can do with .Links is to add neato services to your gopher server. Adding a link like this:

Name=Cool ftp directory
Type=h
Path=/URL:ftp://hostname/path/
Host=+
Port=+
 
Name=Cool web site
Type=h
Path=/URL:http://hostname/
Host=+
Port=+
      

Will allow you to link in any FTP or Web site to your gopher. (See url.URLHandler for more details.)

You can easily add a finger site to your gopher server thusly:

Name=Finger information
Type=0
Path=lindner
Host=mudhoney.micro.umn.edu
Port=79
      

5.9.4. Hiding an Entry

This kind of trick may be necessary in some cases, and thus for object "fred", the overriding .names file entry would be:

Type=X
Path=./fred
      

by overriding default type to be "X". This may be useful, when for some reason there are symlinks (or whatever) in the directory at which PyGopherd looks, and those entries are not desired to be shown at all.


5.9.5. Abstracts and Info

Many modern gopher server maintainers like to intersperse gopher directory listings with other information -- often, additional information about the contents of files in the directory. The gophermap system provides one way to do that, and abstracts used with UMN gopher directories provides another.

Subject to the abstract_headers and abstract_entries configuration file options, this feature allows you to define that extra information. You can do that by simply creating a file named filename.abstract right alongside the regular file in your directory. The file will be interpreted as the abstract. For a directory, create a file named .abstract in the directory. Simple as that!


5.10. url.HTMLURLHandler

PyGopherd provides ways for you to link to pages outside Gopherspace -- that is, web pages, FTP sites, and the like. This is accomplished according to the Links to URL specification (see Conforming To below for details). In order to link to a URL (EXCEPT gopher URLs) from a menu, you create a link of type h (regardless of the actual type of the resource that you are linking to) in your gophermap or .Links file that looks like this:

/URL:http://www.complete.org/
    

Modern Gopher clients that follow the Links to URL specification will automatically follow that link when you select it. The rest need some help, and that's where this handler comes in.

For Gopher clients that do not follow the Links to URL specification, the url.HTMLURLHandler will automatically generate an HTML document for them on the fly. This document includes a refresh code that will send them to the proper page. You should not disable this handler.


5.11. url.URLTypeRewriter

Some people wish to serve HTML documents from their Gopher server. One problem with that is that links in Gopherspace include an extra type character at the beginning, whereas links in HTTP do not. This handler will remove the extra type character from HTTP requests that come in, allowing a single relative-to-root link to work for both.


5.12. virtual.Virtual

This handler is not intended to ever be used directly, but is used by many other handlers such as the mbox support, PYG handlers, and others. It is used to generate virtual entries in the directory hierarchy -- that is, entries that look normal to a client, but do not actually correspond to a file on disk.

One special feature of the virtual.Virtual handler is that you can send information to it at runtime in a manner similar to a CGI script on the web. You do this by adding a question mark after the regular selector, followed by any arbitrary data that you wish to have sent to the virtual request handler.


5.13. ZIP.ZIPHandler

Using zip.ZIPHandler, you can save space on your server by converting part or all of your site into a ZIP file. PyGopherd can use the contents of that ZIP file as the contents of your site -- completely transparently.

The ZIP file handler must be enabled in the configuration file for this to work.


Chapter 6. Gopher Item Types

When you construct links to files via .Links or gophermap files, or modify the mapping in the configuration file, you will need to know these. Items bearing the "not implemented" text are not served up by PyGopherd as it ships, generally due to requirements of customized per-site software, but may be served up via PYG extension modules or other gopher servers.

This list was prepared based on RFC1436, the UMN gopherd(1) manpage, and best current practices.

0

Plain text file

1

Directory

2

CSO phone book server (not implemented by PyGopherd)

3

Error condition; text that follows is plain text

4

Macintosh file, BinHex format

5

DOS binary archive (not implemented by PyGopherd; use type 9 instead)

6

uuencoded file; not directly generated by PyGopherd automatically, but can be linked to manually. Most gopher clients will handle this better as type 1.

7

Search

8

Telnet link

9

Binary file

+

Redundant server (not implemented by PyGopherd)

c

Calendar (not implemented by PyGopherd)

e

Event (not implemented by PyGopherd)

g

GIF-format graphic

h

HTML file

I

Any kind of graphic file other than GIF

i

Informational text included in a directory that is displayed but does not link to any actual file.

M

MIME multipart/mixed file

s

Any kind of sound file

T

tn3270 link

X, -

UMN-specific -- signifies that this entry should not be displayed in a directory entry, but may be accessed via a direct link. This value is never transmitted in any Gopher protocol.

I. PyGopherd Manpage

Table of Contents
pygopherd -- Multiprotocol Information Server

pygopherd

Name

PyGopherd -- Multiprotocol Information Server

Synopsis

pygopherd [configfile]

Description

Welcome to PyGopherd. In a nutshell, PyGopherd is a modern dynamic multi-protocol hierarchical information server with a pluggable modularized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for standardized yet extensible per-document metadata. Whew! Read on for information on this what all these buzzwords mean.

Quick Start

If you have already installed PyGopherd system-wide, or your administrator has done that for you, your task for setting up PyGopherd for the first time is quite simple. You just need to set up your configuration file, make your folder directory, and run it!

You can quickly set up your configuration file. The distribution includes two files of interest: conf/pygopherd.conf and conf/mime.types. Debian users will find the configuration file pre-installed in /etc/pygopherd/pygopherd.conf and the mime.types file provided by the system already.

Open up pygopherd.conf in your editor and adjust to suit. The file is heavily commented and you can refer to it for detailed information. Some settings to take a look at include: detach, pidfile, port, usechroot, setuid, setgid, and root. These may or may not work at their defaults for you. The remaining ones should be fine for a basic setup.

Invoke PyGopherd with pygopherd path/to/configfile (or /etc/init.d/pygopherd start on Debian). Place some files in the location specified by the root directive in the config file and you're ready to run!

Options

All PyGopherd configuratoin is done via the configuration file. Therefore, the program has only one command-line option:

configfile

This option argument specifies the location of the configuration file that PyGopherd is to use.

Conforming To

Bugs

Reports of bugs should be sent via e-mail to the PyGopherd issue tracker at https://github.com/michael-lazar/pygopherd/issues.

The Web site also lists all current bugs, where you can check their status or contribute to fixing them.

Copyright

PyGopherd is Copyright (C) 2002-2019 John Goerzen, 2021 Michael Lazar.

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; version 2 of the License.

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:

Free Software Foundation, Inc.
59 Temple Place
Suite 330
Boston, MA  02111-1307
USA
      

Author

PyGopherd, its libraries, documentation, and all included files (except where noted) was written by John Goerzen and copyright is held as stated in the Copyright section.

Portions of this manual (specifically relating to certian UMN gopherd features and characteristics that PyGopherd emulates) are modified versions of the original gopherd(1) manpage accompanying the UMN gopher distribution. That document is distributed under the same terms as this, and bears the following copyright notices:

Copyright (C) 1991-2000  University of Minnesota
Copyright (C) 2000-2002  John Goerzen and other developers
      

PyGopherd may be downloaded, and information found, from its homepage:

https://github.com/michael-lazar/pygopherd

See Also

python (1).

pygopherd-3.0.1/doc/pygopherd.pdf000066400000000000000000006002371456676541200170050ustar00rootroot00000000000000%PDF-1.4 %쏢 %%Invocation: path/gs -P- -dSAFER -dCompatibilityLevel=1.4 -q -P- -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=? -sOutputFile=? -P- -dSAFER -dCompatibilityLevel=1.4 ? 53 0 obj <> stream xEL; @ Wd Iz* *@ЪrT!30 rIH\Bf3(&g#/IIDfRȭVBy؊)D[;Wqlϑ]FvO^Vm1Qhq S f7wyaf٬{|tV5endstream endobj 54 0 obj 169 endobj 61 0 obj <> stream xENMB1 W^M6 "xW<}ea&\ P0Wa.." &ph|TK`A)hs/YG26eNz*'%bO*n?t\J1^=W*|(%Yo +.Wb5ӳ|3Eqs=B6endstream endobj 62 0 obj 180 endobj 66 0 obj <> stream xKܶǫ|O#yіRʎ%yTa%J^p&$9gQ:" A?vi~ysQ Ż?/H,s! Z/HW)i0CwyYi8VI1+_T"i8-W 4DU#.X"kDTbGv"\ipo-<kƛD?˿_|wywpaTrx$h!DD.T 6v3ebHyv]YpD}w}k/^}H ێqj䪹V2 42 ?HLZ_ƸgnbNi(#9Q[|R2m^o2c@w@J>V,Ba 4^7BJLV+ 3Y:tXG < gymC. 1teře. Ģ7>x2xF"fwĊO x?뛉,=a_?3]ENI:,X1 @{~Ui_سWp>_?ëV5$$%ں i~~Ҕr~Ҕlɥ` XkuZ;a7eOH‹ DF HK7xi<ZwdX Ѥv8E\ Md6|^@|85'hL,4am2lA=nW@Xyr[zq,6FޱẌ́=V<'F]9IA, <һloA\-~)Ȑ q[מ#k(Xf@aE`\&Ћ`]3X^q]j=7зx* O/l3q^ۃɓ,$ym85 c/΍0πl R@;g[a}L MhX0g ?]X#cJ.KO]fJV1KSG0:EKgv1}~ ,|VwKꄑp-gb'BBi*7eҾC~),;G&@ekѰIa<6(PF[E!㮕?!BXs/옉:if>K'P3;fmK5Бq]X[\; ׬8vBXk4ga&iriJ}[9ds~"`&s RSAR].KLʟQCec%`7biwdr3%cs3%`e0hmagIFh8Zs!]8@@b U@8gd嬂޿|r*f, S#Yo͟zw_K?bЂK-D \R_22R n #{:BPe, F}_Ջbjeb'ncB,[),Z4`ӝ/B Xrrtf=R}D/,U.Ky2 |0D6uËoYI38]D4%K3\A%{)$2-g%M/4sNng'>m.(4?Aљ `QNnךRj9IR}zCRE`-akV/-ҽZeC0J trX, E'6hA}m ~<ǛiAȭ U+ȍҀ4Q|eMqf⹦xf 3'T`Æx ֨1 \|]p5GRN;8vhl äԗ$jJ.K*%0t{(B'2D]cO"1]dmBHÑEJMq)s$oatla=2*7X[;/$ep99^_-i)y6_s񧴦HR0룈ԗN/Tzy0,+C_X_] uX`s_0( M&>"L]MyUQ8/M|h~t{ t@3k22t*ڣ(I+])[3@8~A^?2a & g: C>YF<]FՙJSserif}r90*؀:fd=Lqyq"n>ok)25[Wp 7)sOpKS2M9J`]t^ :)\Pۊ8oV{ 6)r+=k 8U 0e$RKBU{z/N C" sb&7g*M/ʸGzNiq_\Xj; ޼oHz#^Y{^:Bo眙 nVg9Z-8fQ|M4do,l霼DH 1 :n-/D㶫uC Z< {uP`.8is/i"!K^ ҙtrcJL.㘀:{R0J))bR 㣻0]2endstream endobj 67 0 obj 3050 endobj 141 0 obj <> stream x\Isuoݲ\W3h$K>9@p8p0C׹痙 U|^_扝_շ/Ÿg틿`9xJ3>OZ- 7l2zgf?;şw_]f]yaB.6i9 {gvwγ7vڱ:V1-|r̴}33q~-_?f} zd&#wy֋=^FHi|8PY~in&}+G~#d5ғ_]NQe\"ӻoN)ҒCe1o9Yt+9)Y Q/ԭ^YuMjr]}*yiL gfڌ{FSttdkmZ8nR.b6 /1ڬņb suLweUARμ:/ʊr0}1ɤ.k+)U3efa}}nEj Է¶Jh`뤃 43T<?onD ,huMBddPe mZλ@1{M14u7 bQ#J>,'A bAjjiUWUX_^&'BXTAqJQ)T#tS*|/Њd+\"u\FexB_NDֺlr=k G'G F:eǝw/]dr2L:Nnl?$waW+G:qZN{l'^8!Ŝ$7yLE) ܲFQ#cʽ{yFKcqbA>Se㸚+:(מys#Ɛ.%S!< gp V C={nm37!2bo~iaŢ3Tι޷ iϾ+#^'{ƚ8_ӓ3(UԂNtO& -Wq*23V{`o`{Hva#Wƌ6?o3kIYJ\Feɵ T>ũF 86]W|#L}t*炿F+[|gg/ ܎JS/:T?^e_}\wNp2b.čzI[x7(XsZep4H'3QXJD}dJHF?;1Xm#ud48Wz4373%oNdz%]v/]q-;G\3WXgFq ? _VFqR%qSJ- ]F^\ԫxx EzU\kIϱŨI/jgS *aJLI}:H>sP)c~FVuT:g2|W$Qm#ݣ #y90Wm DR>ty ofTķɧ\'.&<oOs&!)Sn#DAH !Qz-ǟMiwQGL;& s![(t{)1x FDXIePve@6E T58fm^&9 zǾ=J'>t1:g:aDupXͨ]ٿ5#O?brp|wEQvZ_^DH{):3@}Qwz8&"p$mO Z^x3&FѰ|CCR[eرI *P js< l%/I1-sĄQtP}#/sN/,1\#V Mm?J8lh fO< 6VFݐ ٕ #@Qq-~_߱j^Fb\H=%Ò?E3*0+|O)э¢I"8 HO :KtZt(. kk2b֟[W e#}SJgO*dGFWt[@?]-u4hLTz]h5IcfZKOy[^sjL4_(-Yj8 O)Xyzo#yq 7v^dݣ.mRLE:]iàӦO1,jBw#)%oVUw5t)d9F@-ȒSrd)k11ZhcQ >t tFÿq>9s2">tF lY@K|b mO ]>#XϽԫgT]s>ET\ T P\Lh[&*02:,cn{ƈt^聒Ӥ8 &R-vm%pH5?p4gC{6{6zr|(hh S=}EfLW|ꆵWhLPv.גbGo!@6fjey1]3)'L5iGk`zߡt]RF0̈`%Ӕ-݌kAYcQ;4aLVnnQy @oP߅8F 5I}WSx*:D }0`YcYHgH7aX) tuت͌߼_J96@X,5WY}^ C <%M)rN\IH [Ž$ {9 z YVNG(,+OtQ9wЁ$Ihj~F\|0KpQUi_S Y2X+ϥD"l% 18/Meqمcҙ<0&Jөt㯠ч2}և9l$Ky:)ݐ8v$-sTG rAb#fEQb^K#Y.o^F] T{>9lkw[Y)jebc"ې0V*{J xq *នnOrOBSȖnNw[hLlG "x9pg3v&:D ^ӆzPLH)7ǪgqeӘ>?^*P[+} S?c"-98{{bn+d]MFVߓ;M"erI.i7F=[#,orThs?Rƚ H|qqV* (UO+_ :`ꫩ$"% ]E:H6F2KJ Q;ٝs 賂~;L YZKk=7$D,@R~hT$mtT(t:~8un Ƈ4'euO'8IOOdOW s(O Yoe&DnG--me}U[w G6cӢzxI Q@UU3q+?Cxcntm="J .gă":G'SmVFI"gHwѨ'"H_j0ֽM?;endstream endobj 142 0 obj 4918 endobj 185 0 obj <> stream x\rR_ewf"#.'8xag!ci<#G7x$eM*{(p_{ǁg?~?}^W^0ϳ]_i*_|bl|`RJ̻z߱`J1jA|2㼻+cMgv zbmiu?(9O#{82wR6l nfveOq8j>g͸ae BsǘÁiNck+}:?s?Gس6$3gدDc^%&ia &5*3Mmf"T%&vnf`}K}h'Emob$[K TA@0=^Eu8Yݿj`Jح;A!RVouV29Mԕ$Oד)=,?A^K*n=䋠gep6|R"I֍|+\fm \eҗNvD圧{y` w1GT>蹾!gz,U1Um~_1yYVY zK 6lYNIa` ٭,(WxC킲`p r"^aӥal2E ng*2A`(*wv `<]hR~@Pk>1?WOR99?EE^wι4؃}VL˙_G? hpWMLsj_ ٓ8\;swnNiy'&4*6X=nCY wuP`=mW4?2;L{Z8C :|?iD·[Dќ=_U-BVBf;OCukߍy}w!_v 3z62{ӜL0-{h9g ϐP})i$[Ux~b*iulXjdHazH'Nܧv~lRZMC,iGl6\,/{W?y^Vt4P&p W/c.h_$6u-$| }r ېs3g-%3_aLm24Ȏ:&lŽ{A̢ۨp$c H\V%5Ր [xY2]; E}t,H j]h4z%m]/C080k XY@h(&]M(W[N q-ԑQue }so(Mu1ڰ|d:X^*6ĽЇ4v4G֕S{CIosb%AJ"bQK^^|r|b6/,ZH F9j xI]N.J@2hu-lV{v;:Ճ4mhH"X)n /_g^;]w } c& "J@,@m!M6MONucypk^.(swe]N-!_u=76hBT>B0C@iU//Ӌ{XCRH58Ȥ9v)E%u _"h]s]lv5cbk⌁ТdG5I'9l(Br zMIҰҳvr?efM"&6θhJnRR Y>l5Y  bQtu jؘ&LU @[8f4ݐ툇M([aGh.TZ\#3ʊ})I{_)dC4 rO=96' GFX-LEVy2@xn{1W"seP#v(it@R^{^-V@Lpx< fYidk>٧n̩K'~URNy[[㪹PĶ@79vK+h;PNli/:qY2馣 7٦aC<}ԡTNj`r7Ϭ1>M\9#؃UY0bs/+, Ć:70>ciH*"qBxukn'g F X`GS?ğoOJFi%)#nxU~(?ek.)Jɞ`? 2ݥ.2,"h[tJB,%&[mPcr_OvlATiIΓ Op|++N}ʡJ,.$4 J:-ZÞ9BM<5.0}۩Pn5G 5]aآn6Ò%zPoj-p z `d\YelhS|\*#z~ࡾ"Ȏu5C"܍|UL ꪌʾm)Y>W@QfVbݮh&Cw:@݄@ypܒ1֍)WTo6tuTm6GpB(5 tZ6"ꌉ>?ױ'jjuU+ǫGtļ anVY>"Э31){$6ڽ5BZeR'L48%rE.T.M%v%n)w߭ ЧI;,LDI f"Zh.7^tm}Dg﬙,9kw;68c)Y^eQ2f 5vg:?^#kDEw}#I UVSr. r>hkGs&mt?f& ]F❸]5Yk3C21!< ybی٘as16/ XqyFk, =(ҍG; c2edz"#`ܦh`VkϱdNS˩$Imqdw$+ \%cT \s@ܫ&UI&iQ~GbB5>_>2n!tPF_5^w4vjZ 1#BY|'W4C`!lҦ?cfWq>\nzʹgz}P0 6O7 M[X>72#@6A&WM=7OeL_Wr~ib*yXoXC$R\?8)t:j_2jo{Fm;aJ߶NǃCW{_14f=-c]3hI],{,:i3?%[0l+:94OqH|(+vT0pyÒSC% 6Ju >Q dEӛPk+M ˩/u<]b|B> stream xZIo%|ԯx>;Gq_|̂ Aر.Fۓ43 "0KX_WqG Q/$c',AݟNNSUF|g |w31itL|3%bz ԨZRǧӼk/Xn=%pbzYgt13EU|$zޯE.mRͩ{8;GZsKCrvK8$\S1]ÎR:91=A<)3DJ6WZL/H,ˡ4DG[|Xފ#`-~ u6EŽ +y:86 zIh0K+[@>ɈVHi>XbG ȫɨknQn8_{slԎ٧3Nv#$=TT2xev]p` Qsqa0LgO -"Wo%U6+!U 0Umz>^`i}C VEV'4<ьG?3*y?bMT7z)[@q`#|tJ!ڝƪzJn_"!*eٱW&pppC%8ۡ窪I8p\"s:.ɝR5q;[jh!;&"r :a.jYzcj/3cS!E‘"BN9$#&JrVxO]aZ:Mi.~g&eRP Vy]T)Xp14PW6/kE6j4Gi<`5Ҫ1TAPޫ$\HQR }> ́J w&d#cVreV5L$[)(L7|F0;׎<5i2ߗqQ8iT;TIhm0Nœw:spew3 {SnvCRgMC6Zf 0{8nq4q9MJ4^|;@[!̸<:cb;޲Ϩrhky\.:>4rS3ƦQbF FC7+-%IZ-W>bGl{qޥI 5n+Lq$cS;RʌŀDmY=\:=,0ުKz"J. 7$ Z2w̮ToG D7ŀփlBj"uXwdhMis׼5(#D0Y!ޏ_[ws)j6ERto#}a[P^Z\No/#NWg˛ϭZrz~%cEa[ ڭXTNw}yɁ}y<]䲋ٌqSZ4ng!I]^}Ҩ#)A gD$RVZkrhl g5xs"<ensAM:o> stream xZ[o\_!iRyj"h{EYayȲcw)u~{9|3|/ڗf/_}ý;nr{<^ oYv cʆiqJ o14([܀zqB?_/W:D![8jĤ+ T-6mlV9W`oeYMq2ыW˶M}GQDE{ Da k0j,Na vrbbɛ"LUmGk Nw-`}γN6"AE̤r-igTyEoqUQf#:Ϋ:ڨj4Y,ojdH m0G-~;.:_5i!Qm$%p/gj wM_f"D[-:̜Kt#팀]_/PA4mq`&bZWU.fF3V09-I xFO rܰYI*%(y2\E:rCLߒy V|԰RH4R[]P ʛ+~;zsF+c3֝e{ »1׶$m~Nb3;,aFuz*֨g7ﱼ ymϦ6p]7,1'gGM>C%xὡIהr.?;Ys ܙߍܦ)­*(O-V \) xKU]NCm s] 4@d8VƱ[ogAvf&ma,eh-c.:`{4|E,RgZ |"nF8Lvs+K7C ڊ4/x6lb/PXZ[k]uǕ3s殯j2A8>]F`e;|uV<;PBL6E1!fVi^팽0.IZnfJùI𰶍a@CqXW8Vo@O7L_A롭RE8[Q.a [͖73Θ7z*CyG&1R:J (HbJhb@=pU=7nZOjuV'2[rЃ\<9<9A=酽11!&mHUxN '`+N)[˕F7CbsR+3k9%tN]> stream xVKo1W+ozxJ!mSDCwqjKCg7Ј_/ 47 H?Dl^OLxd7NIzl57R9Vmgvr&͍w_|WvOs ϞydBEXׇM]f$9->R-.;%5<>t>OmW#z}{endstream endobj 289 0 obj 893 endobj 306 0 obj <> stream xVK#5_G^ʏ+!q BvdL{n:1$4⶿z*ԃuU~z}uU?lV?%=D6O+]-WfJ3l^Wo׸]HEmNY+eQDIdĞ>GTUW&2Ĥ8dsC׆c.iՑ Qmǎ3mf"!w9.)MTlv3ʉzcJV|}J3c)ѡNaAETF?pաqL mݯ%yhW/t|Jz)$?6e^2qFKbK\SIE۩-->W5G G )ŀsB´f AUxVW>pWO\Bơ3SJeGBǛS͡!7&X)FmdW>"ơ-!Wx!% t 3LC;֊k{ow%mH5x. iul^vת X=G LUS[:*F\L(I*BV$NUSӳ1gyG|*T{?iQ)EKd8CX Mx~ y"2mT1 \XGlv8m#7Ms-a`#hv텬X:JB`cU]]#gҚ'OϜT ˢJF֘Y!/=uNƹTG}10VgI}ɱD龍>=4 0&[m!LlKv;~ \.M2ǻiBaTS&Ƌ?Hm6KYo]8HnN\7/i}rE*L@_[X<5W451ݙ_6/ˑendstream endobj 307 0 obj 991 endobj 318 0 obj <> stream x\Ksʑb)o ~;؎͜lEV\J,$%') ُn͊ |O?W| O`է'Q`ѣ^^5L,X>y?ʎkb#j}(&.>dV}1v 뵆Cx*QK2ei6[6|tvoᯧ+jgQaVqna~q?9Ka8:'_sFAzj6hnR ~[!`#ʰߥoi)CSZ;O%ݸ}cn}ZOw' ҢIߍ4SI6oւwz>el4 p;tp梼q -꬝ <ѱuqוK;bDBKr0eʛ2n2^OK]m8hBBYI6hSpTS?ENUe4M,ʌ>BJA10;J]b #xO_t+|[)Ҡk0>~;&К{A=ZZQ7փ6I4w tråG6{ &xKzWكV;vT!(5o6~>c? rqdz ٠VCzfI]rh0W8V }F)~Yl#t-4( ;UYX^E5:ۍ$qd(0ʭ)GV /ơV'AKN8Q`I }(pzCLySֿ!z]C5G:Aٹm5,@%Uxcv"k=Xl"aP+:֝;P t1-4/,rUvʬ3΃I;FQf|s40&u^$PH%6!ʞQDUsaӵHaGCpEW+ůx Nۆx68`}Walje9dŌ9ϺbZ>D~'yI&q:=4'F?E  6ɭlQX$z hTp$yI( )&R 4q$XxjѶt旽{Գ8 (t0cNA SEd-5Ѝi,*^L2ב؊ jWlܵt,!4k^=Vq'(=Oe`!M{al?D WY9kӬeM6$6z 4tRm;%]v-NKأM2l>\6Q P7|c+aW}(F[ #(ʨ$΁%;~Y Gu tV#9tAB xTRp /dxBtK Te uTQR[tY Il;h^Cpg[{_&1z@<ݧ{7̭G x[  ^+<%y(i־*T6Miz2)-$jߞJI޻&|<(>բ$=0rU pFg _uE+<wΗ(gxgAs \I&(nZsק[B΍l{y3*޹ UԐnAJRYvvّnࠎys:CS"q Հc2ytBdkdykh[h~~AwHKEл5ιV;$-XJ^5RX@f{ ?>\ha2I T[IP贛yB{"dšKrV$my.Ϙ5G DiC.Ь Vf/#c#_VdzE =PQh!|.S"qyQe蛋EYz\ AeC 7Vf<*eGxHG/D` *yjcӐKSO!"> Wjh R hoJ 2 jBq<wUM7мa~m\G0WHEC,,džQP#Wvdϡ4g?@]rof6`liuI!^;G#^PDKZy> stream x\ro 4д.d)9l0H wY3RFOw/_.?;gsv3ӏ__}&ԹZ_)i7/ݴ 'Čs b6lXÇ4nA`G,-6A@ܓ<,NGoܸ~? s0GI'xX-zWey;LV\Xe%K﷈9Ԃ=Svn0Z*ZZ11n6mkI39>ʓnZb<,3kv݉[i(yʺf~ ,f+7+7I]ϫ*h`O7#yo~+i#}=lX@n[]RJ4m_Uh]$ U} j=5j|Q0<+ؕ@>pQE:}5_U.iݵk̚j~ 4e{Kj}?f;o'x,&HB]gA̿G;cNFA^rdjo. 9;uhhX`7~X)4Es6Z@az(oagTE |?75,V,W)K@!VAdxlJ#MYZ+䤙7vVV FJTF]0 kRs)|uz2@v:S!qeQ]Z֠.qu{"ՅF @TkN"-3`[vE!MZElpYIE@Q 3ş&LK-| 6e ?";̹Ktа`h`Hch;:} |́ COKD Ĝe6'fX-t T+EIp%ewϟ9%ɓR?Q<(ZPD @\H^KNQp ApRjdf=,Kߒ4wy3֧ZO _ZV|S^V9PF:G06f%Ɯi*+@'ŕs QӆwT |7zaiFH@ Tuf$v[6pYu(y[1$)J[pICr\>@V8hiju8eQ1ApAfղ4vM<6`LJ] r.ܴ-\WI:]36>"YO%Ѥ҇ R hi^IXfiþ0 O-KۗfdiCY)VMTGJ+:wC+G;U.c(GAWS6+?S(Ĥy a K`YRS玄wz X^xB VCZEXqc0`,ģ`oI$0PIA(onB[-`T C2ƜGQc&6_xC44ia{z?U#%5>*Qj^j=]v=[s̠4V,uU¼yJuEg}سæ@,ap;rGzPNRx;'ITW;*IZ',e-%0OԈۯh]~Ĉ.ob\vO*"Yr/K Z2:CSGBufE0  S7G_ΨJ!#5cEJKK3n)'AMDz=E,҇?ԑbI*(ͯWjj2JC}Ti Yӝ/ B"gї@lucZ0&hO:MK|#灣 )@<]cAdṛC, Z[DuS r"i@DPB!x7i &'c;(Xu  y *x|0ãT V}D>i>J: 8Q#k'\ &%tP}I?&IKߋ*JRiYJYpēBQdH4qB:ĻjQE4/8=M\Wڀu.W S.Ĺ򵂓8&(972X$ΣJY5~MhV\7:qtfAˁͪ{wPzpuNӷMn j Brxm"'Z/CK58 \|(Z[쩟U(ҞpGS[/LCǞt+,ᵠz db8BujE~vm(RN*[ZcGإ+^?P> stream x[r_1ӌCSګ|C! )":kϪΞAZ2_|UxL' W'Ka̹9xvi!^sgLzbrX.>gRn1x$sfb&g8lC. 53B;ɴ\L*R&Ffz9r{~>Y÷灌HOee>O~ rϬ`"|a7Rg{7aFk˸aF8 n@ "XL#cN2}Da(4++`;9ZjҢ>@hR?[7-]bUxgo y>)YyӦz<Hh CxDoi+ FUi_t>Z"'OE1pՙѯ{`g+4VpAəޣCyp9l``} vɐtQ53ZX&c/"18=},T6`j噴f?/AEW4s `}7__wO*w"lX}Y @І’{+:@C=hKu_f_jy=zԐEqhܶpl {jZ__Ĥ~'~RBLtH Bf28~n5q<,C.~ףa7DHg=}=ŋe#@? z|Fϼ }D.մw]z}X@Ji1fLPR'.͆[&N\FYfð{.]QUǞPd@z{,, `hAMBHM;"=kO޴ga"\N8Q|zz\8NRFșTեW K?%d@ecFP`°ҔNh^ 6r k"!(О6TlhʵoXƁ ᲢO--fBV@s% "0AUC(2uJkEV%->DJ;xHXlƖ=*^|J"&WNq4rrC)UpUP$z#Niw48&s(j)]+r!!68P`z57NuN*N~[ڃ=вP߄/T-eޗ؋Τ%ĥJ:,ޱ(B,NEO!R UmKtU_y MN,9k%p4*q[L cu:YA b7.ROJ`HꂜkY pkĢmyhλ_ >.CRIz$(ZPtJ9("B+'uQʼn;|L>4$D1XEAD]L*{+}U"EԬ"$[ݻ)Y |hɚT:S `U1Af_ωhK*QqźPF vA/v8ZMYv_,tȩ/9)cjP/tHDϙ,U'ӿP}G''t?qRHIohgCo=-->C]XcHrsV WAݎR뾚.jipeķ#' w;$E(ExgU~xcđxɥ>?Ĥ~!5")qUGCӍ ЪfAF8"Ie8&О-E^2RS i}cQ-Y\.1 c\C<>ʮtvaA!R'G]Jʆ͒b<ǽiZ?[8MDBUb_ ?mH6[ã΁&*ucĭ -pMښZcKm:#)+~P.J"ž34椕/ "](|W|J/Gri@BǩG&%m*E {kOH0]fS g^"AI$}6,!` g]7AƜ1~M"& Lν#vA9$٥,V5.Wyu/w$J)]o҇ç;B%5}qbQ$]R*h$(⏾T\W&+G^h$}zCb鴺"Sj )Ԡ&Y2sU? }$5 ΕAeq'şh.[P C5}CcdjA9>7{ 3ZMec*8ϣl*6GfseF4w7CKs-~j[k[ОH>./cJ(dzv]!jJD!~vbvzǞPDt4?#w̆B6:FI|.3?%EUr$ > &㽦oh WEfN9( XQwWJ) ݚRo mF{cO4Rז 8Io߿68endstream endobj 396 0 obj 3027 endobj 427 0 obj <> stream x\[s\7 O)}aBi#>J- }V. #7?nw16Uԫڼۮ3|bc6>_U?[՛lwbj۽gד.Z4vV,J {W,0˝rax˜s'g0An~PbBoLs} -cbs[m6x+4汿˴>MNlI_Y.b[h?4,-B.d[*b;veqlqj8-Tnf 0 ƚv:ew_dJC0ԗQy庶Ur3N_8}If~8[Vˊa06e}*azƷ8KnusZ>ϑ`,-~'k G@6U-϶[˭LoޗhVgԲ2 cTHкlW ,/IZ׽.W{]&[/+}Yz/ ((}wP-L^`$ pRMyN}]/]dnjB P'y#H _]Zyh$LE{ 5lW߽VM`y |QzxXy׮ڛk:cY"|T]c}4gk<;I;ЂTVE𬱯tjlS6@`$2FcV ./Ǯ8/.̂ EL4fpa`Guz`g{1׻l1U m|F3D1 V7vbI8hXH1#Tb\Ưs :vt6J0wFU$C#+v)\j)<ۭeUAE6tX5o >sj.M6a"Sê&tğkhH $5Z72iX֜~4x 3HP߼=@ GND85̉DqӓC`\73i ZC&Z} 6~>bÆ!3U*`-Jtu1r bc; }P}"Z~'%ɮQ$fB^ZyQCO;$ 4G4"y & Kr h=/C!wXߠibYK0M=/Iȭh~ܽ}<x a'~z!Tℜ56w@/re{}VQ,ӁC`6LAzi.vFO>a. 7V՛hMs<9hASd&,!4moDxsJ< RH?B"hIo}4&#" d8*3í#e,0Ļ%WVfEXWb&Qb,r&CARۏNV!V^K0^zfC/sDb6dz*ȚpV^!u&#{b9`L|P,[G'j-.ɮw?P7,HIdm} FSĄ.s7@LFT0FeZxk+-ߣ浼B l¬% LL5b?-"BSEϡ׃<c$iiKhlbwZpf,!6 * 9ITfm{ -<a3\A{`DZo0oB6$qTW%=Mc~h}TL7pSUh!08gFd@#ՎOt* iuf}O˺9/ax~Unv_9\F,67l1&޽Y&J<?؇PE<)Vx>H_6Dr HҙX zrkV+! ^߹ ~F5Ocй;}cxʇIq XuD5%)Z:56AH9b:1Ewq/ @0%3M]!@sZ yJm4˙h1{nj.k>*EY^,B]ӳgƱėĔ5/fVTG["HqHUHt.#&NIgr:e0FlPN)4$s_]bHcEUk Ru r 0)1\bKkKc0R ~-5 X[_bxνzH=|%VU0TX.f<ܽcI>\zJIc᠁~TE&>P tq9 y(哰*o7h$DFB(s2TcOɏ$Y s[i2:JsH>;Dj"L{ݽ׷dyN@@108..:'%ֶvq'שX.,.|ReZCa!* SkFTZQGhx{ˊPwZ N L8K Nm?➖ |'xuSbxߨ{w,]CJ(0@C'Z (cқ[+߳6/E):A+R3yyӱl zfO ̾J-t/U5uX1' K&~ UZSLН2zN2~&TE G$]RLtW\sHe $]S>1kQQ Wo& -\=wo}k]KɆ'gz+(yԦĻ킟4&Y: #GxnՐpPBU,jj㒑btunODO7\Ӳ{%f  f8lRziv+k&H>$E tir*/ǝr$`Gww<#I`&f T\QO5t kmlF&a(5s(g=0J"N4nV3u`|\[^P5_.5"֪v$!r"<G:Z,.Q~)b[qkZ>n(ĎGI>3Ww`쑋$;_(q0Бy8'?KןH7? etG*Q3QNEP̎ul޸6&1oAԃ'ދ}8aQ6MOؓ?"gI  V(렅8p?2󇟜˨ZɃ{M^$}muQPtjH>Ƭͯ .R_Ql d'㈵,?]#6> stream x[moQBȧ"Yɧ$N8J-Keö,˖]û,|Ùyfx^?G,/?9!Ns-OTj>[ѿ6rV\9=l[ǘՏW^v,ffmf BIf*lt]f,V39> NO?nbN;ӛX`ȿobI:ݩ6&g~ݰqg9<Ki`x-g~j Ŝ;2gv F.9(9\}U?q"`fUdM긔i0VL}l^/5=P3<ay}tYJ/2ջжU;ޭh~^vqcfyn[pHꏪV;ȩ݆ٙ/hI8[ˬzouV Vѭ*"vDl>]=8l Oxʀ\2-FQTEvE n2#vn#/M7/dɾЎzxF|4F:._w>r/: T/HF+3sYX~Ht Mav }WxCf䟬9c~Q/tJ M=zoEmх1DgęHJB6ү~Q5}85ko y}sz Jn*;G'wKr͋h) w'sqYSZf j|6by(o=ց nk({%Jp#!xT$Z`!U ~%z|E[JgƏTA+^%U&הdCx@i Avר!# S4f*ZePYXl2kOw$T4`vh:׈25t}Z]ocYxLsEduK:ZǛ6'P5kW\;۔s<%9z:C8@)ZLb+?7졀WKBn̙%qX ;V"#gJ)w5٠&{)aVD #ZDXChzM*FAK~h( >M`$7cNTL +Id}b[k |E:řT9Byv2Laښ˪>HxSCWz&udsÓh( mBS)_-wzً~^DBԎ–@ę -i@l̀x&",˜zrenFD _|%z5][-z|>t_+V&r. r>zU[| C+-r[:&&\tWqUkc(S\z#\DC$4 [OdEQ.V O@uWhU!z}e6́\/4J[i$jSN!qMkq\QFS=}]*!n`)[2 WRvfёKt#Z*}%r𢆪A U\X-KinjkT=c-Ɩ1DhPWltiF7/ sz}to); k\K3m؇}m\3>w/z0<SjPd[W]St_R!F8- P%~4G@ ! "ujr5g'.ms `|)_O7^k36T OS/ a)"+k:] =Y?E*Qg"ץ9^KH ^j33Zҟ&!8>O()Tz>.AA8G%;sЉu"-XT@E%yދ,x֮w!ќrP v tH}u}U=jsc[gEawО &;0Ѻ}Ԭ0%OGx2JqJCv}O%3sYn+u!]jhjPxa#ЏH.6NwC苿!}(.ѱ}H|9rC3#RToN{b _P񐸡41f=Y6Sok^-Qz#$qIq"έ~1NqRs_D"SUvsjwmr,RЇwJRTVL*d}{l8'&C̱JDh-{ɬFj֥1\Y'G2endstream endobj 461 0 obj 3726 endobj 495 0 obj <> stream x\IsʑK`RVRbxI9ġ_bP1:iÛlIPr{d5ͮ4BSbn;OF͜LR7#݈dr6iy='5ZMi!^ b-dvU1&'&WF޵1uI9ba )%Ҽ)^wO[2Ff?8;~Np(l6_$Sd$6+'-9-BS2k_mI ;ݕWS㓲y=ⓡڛ {-͓H}:wz0o5fˆ[ z҉'*7g?+ D )k(m6S@BlNBWz~ |F,O旭LtvmE)=iuӼۣ* mQ܁#Bm_3 (rY$r ғAM;~b0B7g[ g,Y5kzz̒G0 9",\6mfXTIe%CVY X6ۨLѐP䄝II^^v(O Jl%!3g'-Vb枡RMiUi^&7PjRwD~]5!Vv<-ͫҼC}6w+<48Ai@r::.?>1+?ޖ}i[whKV':]mZtlxvϭ9:%^˴{vpB4OM-CLPoJ}ph}^_$d5\ijIO@s PT5+0*ի FTi2FJTnh3lHkWi¨@:!YϪo8L5ΎoA=ff\(Ԕz Caxza%?䘞Yä~}n1&GP|椞 p:kMinټ! ]/2g8C}*6—qYhy]Äh*d+*g"DQ>w=1 NP Q=T x0a,vx{! f5(þ OtT^<롻S2Niafrx&7l 88Vr-Bkv[&"nmlKd)n /|,XϧP9OQoi| zH͠E0wsJ|dI/ Bd}=Yf)hI:^$!aQraҰ^fj avtr27PmSC O.LbFuzU]"+v#Iz1g6x1ΐ &|YƄCQx8#Qd|"2}ZP%ɫr>]4?cvxʝ)<{ʜ"qޚ"l1&{`P:=^)q & `xzx jK4+Nj\Yy"oɬ&".efG3Vᓧ0ջŽA0 |p0$y\o([C~"B<_LLZHYlnfqh@BMdEA8?ȨdUiK` rl~OQ~~khq.>΁gT @hPŊ[L,o!6.4L^6UeBXjο̩;1]q8e[g`ʧ60DUx\3 PwQ$\*PZQ9ÄũɶB%ur\*" 3I`ڢ;<3zC#jUr/;l _Y^8-d \)6GVϳ'gᙚ#Z~EI2f=.:Iq.tj:=|(yW|JW"A0in~LVU ;aNU %."&{y \|Įb&|m2QY(us> 9U4E &_?lsEOg2z_"z.:+emG3?k)2%O(@\01>-t xmb*NlD|&GP ʠA]yF2ɜvME-1Hܷ&uw! h(>ᵦ `\ǽqWq\/Lx341=5)bM_bZ'BuǃQ-P kͧmV针z#'ٓCD)`lriI7>VTInmKliˑJ4 &{T.IOC\_ekT5 meV9&Ii +WĨ: N o]nXV?H?xw4"fO<[-S eM9 X#ZLN/3 Z$>>dAl7r欳kj `8hTfGPd,ؘ%yƏ yyy0)LWArº6?T;X/Ff!== .3 Itt6bk=CUu'@ ‹]f@h'x *,_6ApZb9>3+d;îNc V7Ӯsx59I+X-G%}u@@" I2qtU1 %s1.' oYm+MTK[+ƙ[KA+??s܈%] wjqF_-y¥+gd-Ӝl΁wTF4W `C:7sҚOiH8*z /|UAb.el bp0(tK>"Q#teP.\.q@ؖbAm Lkbּ_RL@B6(Ng;hM0,Ph,Eu8g-%߫6۫b!c쇉\. YnX}u4@Dqc yG9.sr4Qyëv*겠UgpثZșQS{I՚sfyk~j@: ^X dv-pr@0\nZ~]:E1Ɉy* F4$hbhG!/ɓOt!`E)i^Y UnbaD N+gza갡 "hqh@,SˊKO:gw{q 5P| ;?*OBw5,^`(pNPg } [> stream xZoЧݶG/}hF)>HϕtX rɝެrBqIǡ~Y BS~_\?Wruyˉ, ϧ'^JmWQDY:eVZO~J{5|R ɷ#~0Ju~-R]B[Y\&`h\_CpGr,XH+2鵰NKӿJU5I͵NhW"N+y?")|I߽7H^!Err;.3$HFr; R :w?u߳_ſOȜ>!E)w2{$_׹k67oFȫ:sům߳ڞڪ]ʺ4BG9pGbQ uO/!.b4ZtStAx3h txc=x>;=B!Z%Vp<ӄ-IJ{CsFaU0v1:]c78zQp"$4! CJQ!AMd:mp6g IC1FL49 nL i-Te%$x4jfyJbUB&_V}%f&;SU BBy3[P5IGja |WDTpGm_? :fBD*URRMUbQ?||Ʃv53)iiPr*W8_vYR.̽LRɓk iSRL0̲ljd++}fY"Z+ rŲ;Tz˖ ~^=FH!GIa Ec2s9"!faJpCEx.eeeՠYDr*N df_A t>ca-}/?0/OOshL@*c٩\Q $vN=2.%w60awK2zob83l. íL _ pSDRk$A%@;£LN0 )VA`hk-X-ÎYjmKrxP9>QVzDžAFd.7I_{wTADJ}&i *> stream x\Yo7 )w4}w)Q( I$H+ίO]Sd!Ѓ3}V1 Gǜ^&ԱZYx'[9).\mw16yzV<93K7an`$ߨ:lRLVo>̳ {]uW%4vf+&:3Sc&'!5 'w\Mq`V HbڸMwnbZo哖3ؘ)࠭ EeV rb: [@-Շk]齼I/]d8*Ng^&+Z?Փnui=Ժ]+.e+myQfnzvdOV9m:ͻJ*,uLQ(<׋I~+Tgʂxm8-=w;a#тU0B"Tm^c r>+ssU\B[^"6ԈtbBmS.w#Q> L?aA#juw6LVaPI<]eorY/p(ؠ3hIt';o>"Ct,{JpJUm^umkD}Voj6'Q}`NTe:ʸ bIa|k 68@!=?qDv#4')71f$֢)٘0T ;Ūw'w'TEEA^$Q0ZJvh;jo'Npr`x+{᭠_PwO[~ΈSXh\#݇uDA5%uTᤏ2' <~$w[ӊ{k*sF16W ]?ƨ~;EpooU3 gz d\I8`+,˜z96pM$gP,lpϔq l<8b1̀B&~}p5)g dNȑ#V:<2)厑CF^BjA`Ad5k@Wpu ExF* b:W Rg%"Nq 7؂ !]b)ʜyά&3- GZMY-ZZsk% D.SCC"OBif-[ !]u# q}o<'*SdY5B%q!IŒZ| ]Jr o@`# ֋2F!"z:mĘ9@X幼KuLD(4r.#95q8 kMvSQ=^pb4*'rB@ui^ iՇAOIoBZƖ6 Lk$b5t/Q 5ւc%=J IgQ,ywY69䭼̄R6p0yb$}͠mzvO3p'|6 >`.$h\,ϟ >X&sot4' ҵܷyv+75 KF7"9[ͼw.]@k//CN͑s6j6M9f C-mC%ts[S]qm|I6Ɋg[<_5&"C8V \B48R"n EOk yw$a۵&iMm">M:_yG>yQT6e41f(lA ,ZrommNVv]X?H5q9`f>h|ave:p)+ֹ/ zQlTHe( @kep֯qhg}&tSSCa|O^jT^RyJ,I5HZ I̚/0 G::J櫯j@6>ibƈ7s4lDiyUx%DK;i-KփJ=|$s6lzL%'5 @f뚋E3GQ%OhΧ;H T8h%f>g0&{n,Ւ:b )fLǢJ3f̫e@3M^V 4&\$DƲ8`X@TUQ"'g},n$#|gjZm4٠PkFU|9g[@?f/JmQ]x{4YiQ]\W>;`!a9 xMIv`{ VyDAp#Hty,A 33K|u?U:tcH6[]cWE˳dˉKG6"נ+Cz\NDAȁܕ ;IVuuz^D> stream xZn6Gme;ڢHRhZfmvR;PNcDÙ9gGY<ÃR E0w(?Zqjfb5>?} 1p^v.>nJ^+1]b]DG.y%pGأ)4b{2`\1o A|JrwE|9 ^Վ9-"RZ1p}Az дz+8H 7*t)XBusopd U~S$IS|Sa`DP;,4N ;}\#=p6Ύ)f8V:(d(2pj܄V"fNi1q5psQ񊥓vxd)su'v$3NtM/;,v&ssRq^nY6ԾUi^kCxx9uoX遢!*NWW9#)"6+7 ǵpd1r _:CWbs~^t0eZm@>]*HI *wKK^1I"}ܹ@b#lw  kQZME+Йe%FI*~;K(M,bya{ۅ.Ԏ[lBLA3kǷe??=endstream endobj 564 0 obj 2194 endobj 578 0 obj <> stream xZY7b1!$ &"՞ l~}nC\UWGzX' s!D?.n?1v!9ƛՁ`rp\1X<-aNhcq/6˕`Vs4ɝ(pd~\I8b^rřr]g OFKr{ )i%cJ|UuYD WQJpMOV!RjS\R.o=ه}k$,{JtF& 1$ȊgJf/m )[/1*;~J;$7 L*!TK˄sRgFK$A sR>bPT]pC2a~guVC ML-?CޔǸ|d )P0nu2dFz$?jE)}K6GS pZ%l EV8YZ o*~h†q)QBm#9mq6Jj%/oss%Rimz,hJ%{N*^Un>#.D.c7y*p Z]#7#I8Q?%i3}G4W]u]ZnE\wyBx8ڧ ^xFK ǡh+MX h|u!s ? >reo/c41lTr`$RF0)#Q+#L#6Ԍ{%RwBwB. MGWΥR̀D,}zXvMH\m܄l N~ly [=c"1ёٴEY/KVҐZ'?WviK2DUO٢J*)?"1D!Pll*SNd@vhSmřRp.4eIzĤ3iaR멪jpq ЛƝE@1!~)fNo+gSFw&EN|PN"&É_.S;"v3cB/~e|ٙ %!^7Gt<ǎ}G@V; )(H6:u4 [/rJ%'d>_'aZ;{.F: &fYk%YP}N>VPP7|tm=//G4jP5=ǤN mB'~`$k ʯ?u$妝mzۀ&2Cji|[(ﰨ#v/cQ\cZWLp^Rj) i鼐Y]»C5蝹Tzw%s6ZWdOiZY;}|jPwڮo?Tm{xL(%MIlŸ'}endstream endobj 579 0 obj 2205 endobj 629 0 obj <> stream xXYo7 bgxlum$}خ𱉏 43M(`H~]Ùhx7Ja CMqRg]/uB8SF1Պy9νn!7/Aj+ SIk&M~#y;b֨v9D}urSX%_1)` 9ـL)`daEM/<@B8{T޵(EOEaLz&-W㩸wÇ]{SAx٠(@Jfo:9ۿ Oy['XP89ZFC<^}t p2H p58l] }gpԼ5/瘸w&9?3nmgٔd HPTLп+ j^&WE#/1E8H\1O5/*Sk߾^*P %0U |K49LirP-3$Fz)\* $ߤ>DYQ gf 9'%TxIa>9#(r0MFpl?d^T'aReqV쒉9*g^B+dFB?d+'"vKY0!zGDal]á ш'`DB6 ]1L,3!kB=vUǎRC$Uti՘&,/R X!8i[z47x3â* \5I=#odez.{H]@4E-@=[.R4.r͛zΥUFJ.c, #XCCYs8ɳz2̲A;K> kfbNUzbǟw$%Ӥ)[R4F'ڍGhxI"雚In޽^p‹9 ǻ48PC}fJH~,GXM&רY=CеYiGp9G*} 8;VX8P ^J{~{ЊuF]rOEZaC.C > =7! /$B\@WQnqE˚6 aؽ-C#`yVC ML:JId+V!"HekN/)1c- ZTtC0M*%$frXI=?N0&_ݻjbY;j?3 _6 XA*n]׫{y~Hendstream endobj 630 0 obj 1365 endobj 667 0 obj <> stream x]NJCA W=de7ׂBb[R{g %d&ÜI1))Lxaz4LY~~3(̤ЎaQ"AK%qb> stream x[n$7})3{7 \|,jc?MZEvnvRlXԩ"J r%g/?WrusH՟Nn%AIkV'G2??atBF1N^}~H9Xf+V F@}niO6[׏sWG>9*rqʣY;)0ZQ*Mal)ͤ_+Vs/ڰ';xE=6ϱ͟{3vܗ|-;6I{l>b6%: J=T31Zܐs"3h#Z`%ߨѻF^OA[};Ei 6luף}2ɩlcWzfF xC]sZ'JUo+]XsiYONmFf4i+C=E56o9a]+S_m l:Y%Jug=Gjc'`d;)g'ocĿpKjF?fIjMq'r^ @vǸaRq.`2wU rһ G;vqzU|"PF1/e3L&GBn8~\(( 9^,}DD4Rz NF@@x3ݡcC 1h?£]V47I'1qlnY坰vC=Fa*yG&['I%J"LBAt3oR:8F@ B22ԺM\ 7X+r2ÞEې燭`rQˏ{O@pE1 (3M8{?$_[6T N۝\JKxNHF?c2Q++Oxw Gp$.N0T9!4J!15юgyϞX͂ F>+X4׬fgN >XG"$=34}ߐ~^#e .`$9%Q G #vZ:2"sL~.ؒ9D,'_.a {R1ȡ~6U@@M1+U@>J&4sD k.׈AoqZa;Œ[mT#g&|Ӎq뇫.|?Ѵ9m YLrs_2:GA} c4TE?dH}w),565+f$b2FdRC2W]U~!:BB 5EL_GG P?\A5Jz'|K"UWY[D0[H)9;?`Y] iAf&hfmi3>3 5h!uk uZ*;phޅ|@, IyyOTj|>Tz~ܜkT #?P&jfМHRnXIWHɥ`8wã{)(T䠬t'v":33ڋ/nmdV߼˹16ɍrޗ#^a3qa^ً"`8ҁjk:*͗xSb|1#WkZaXp N|M w% $ BsJB\L8}ig+$!HEr 9fmj|*Ә+HNXy,ɳW,3 _kIFI'ہ Қ%N`k CT:H A)ke j,љ=Ѐf3D~bC`)Wm E|Crr1%vC3!&>!A@ $.r?1]EQ2X4.>_ˊ?1 bK-:It88t zt D<λ0+ ^(#tIħ$ƒJ$#slޞe4peM" VTpuo[Ujw=)6wz𐟸5VkI.eC˼_G_%ݲRQḧ́4LiPrͦV2DZ~=MZx`@|ʝ$)Nu@'4fz>r߷')ZO"; \5(CT}hwDG˾NUH7 gu ̈0%3z?uM;Gt'g*gڵԕ 0j*ʅw/6c16޽wdϚ'xŗ i P>L=xgq?(^e39"r8.h ʑϋorR^%`zEIs ̜x0ƱWֆKw-B+rO= sG~$^J&bƏ1T%32-݈WʁQya1] )K˪:Gu~l J~aǙZAժw rLe׬3OcZe0k$1t14 mSctrX3QLpb~Rr!6Xg- %W!uX~W'i s@H%t̸$55-A"~NLf~G}o$CI$U˝_ z c0{o}LaVS>߾ހNz_i柔 J"{Ne'49?(~ Nq /+}A̮Dn#6͏;6> stream x\YsE7 l´ή ΰm!ɖE-lݬ3gdI!xug~z?b _1޽2~VZp'rm`V߭7jizވZfqtV.38/Y=l>&!j`더ƐkoIS';;ŽX=GuY:fЃVmRiqCҷqfT08(7 W8IkV"o՟/b*Z ^iIӳ gFp?>';ʬ`o&90wa2%F6WsK|逝a|7zFV;/,X¡֓~Qc '.ಾz/_lX`EnJq0 q@ZKi~fz^ڎ_'8^AzAdajpJ)èR\Yyz?:+|ڲf~@Iu1!vC t B D}^аt.bN8M>捐0(izqV֥elxdD0Hp ں~Ύ0SݸϏ v0w`nfQJ'<Zקg|T8y=\ĔQ2\Du=adE4ő%Wyifo%@T ,A]&NTSHcs@GB3 횝P+=yn[]lH`2 ` VkN DTdaU4Wo}",j1U,$'SȠ F Md`>A Y&4Hz,?]9щ͓צ!BqBi`_ +c"lLfm;=RLy@*>LF!"^ra(\ R$HW/X`iT "Zd?Tjp"\ٮD&CÌN/>נo>u+WC[rR)W.] w/XsZA)}YBx;'6 Q}Iu4<3sGpLJ"(hݻ N#;OӑP\{CShM)D7.t50d$ yZB ;y&͟ a"B}h&uK̉Uzv NQʸ0 q$9nVlQ((R:![LJ=[?xS4R8VqD=,=i ꌁCL94@峞C͗͘L{"grz?&J(͓MU`}~C=v2#s.V*zWe >D{C˺<Gg09\krŽz2d+;jeM7y­&%"!>K"Շ3q_Vi tѧ* KKyP% _kCˤK)akYn_kY&_YDTzZ1|eqW?"`R9C@O O{o3B-6O8JOtp>A1[<;QxЖ!L| ,nc}t^7Ϝ0i(MpL6Ǻ;81  wY?cnx1䯋L6aej&I' >o2=6(+i4۝GA~ S`ʘ'7.N;(Zr|Vڻ?ܴM>זJ9 y?TqCN Nd 5FcUĢugO Lf*.:J74>dW=Hq#?pL1:gǥ7i4* U-R u;XqG1`) ;ͱhĢi?ڼG(%c0з!cX>zEgl![ ɼij|\n¹X՘:F$Zl3fqe L?mS, 6#F^>_C:pGkP6 Tw+3JQG^HNkT}uW_(-m; b6W˃$p\;:>9Ҡ;֐Z*y $E`zߑ)iQf;`?M$?쥅[[ LM "0T؍Vؖ6* H>@ViU&APv\ j7c{_'x%v'(P},5W.PWS$WF*]I% NL?OՋǕMyAyIpq4 %2.bDHBTW( "Hռ:'AYp XgYi@`2%!ݱ: 4:S|^6mӌ%W\ ,`TP-> Aۤ=y嚹5QQp‰[tNx1#|8 Ƨ}nۀ&{litIX>8\$ g|&._^_l)%M&*/4TD%2Aul*F^GfNEv:fuYMo&=YOy3Lj؏M.T^Ǯsfr|Вcl]*"]dSwnmj *sM4:8<- a`M [RiwY4ն;c׸#?W6}WW€R,/sR0 „<ƎHxq֋"N8~B2>W yYʛUî0'3sh[c?։tT<<$TMZOYL+Z5q.F")*=_$m0q | §s}/B8T}(6|~n]lJno\2תvۥ.ɗG'IU/ #[2Y?F؝>}ZneQ*HlNqS?Ha u!OKhغsÿy2Ȉ'}L@ә3ij npgd~%r dwSαcq¥7V\ia+_ZGSO$_*Ef;Go*jSҟtRi baO\}%euάJn}(5Ս}o$Y-Yw}φnY˶еE#]PiOg*ϑ"rJ5iJjw擦]{< =DVďFo,ٟe .5${,gTy]%\ß} 9^)݌d1k0*(x$_:Ӕ066S)F&$J"zU[?S6Q7[s=dQ"Xꂃ3V/~PdwuGTGY/8!slʻg6`J?;/_endstream endobj 726 0 obj 3993 endobj 780 0 obj <> stream x[[o_q)rKr]EHv:2 탬ȒbKq_!|ܝՑ<ù~3Cjj?Wj{*M?=z];ɞJtV7Vz~xfkέo7[8̰f6}N/7[ ^)[z^6[5/6VެƏ\k(j}ZFDž?YR]c:նƘVwM_ѕlt޻ͦm+~eacOc7wȪU{qj:+aKCx3xoۮѮ5k:ʻNG 'b\zBl>Oy7:Rme?[G)tT^z'EGVX׺DV^J?/e,nohN:;rBY~^[e@bՉmq2~8/gTj4WmLwjIVfևMPmi@3GBőC>F QQWǯ!DViF@Mx9Pϲr=C3q[8ƴ:% +g?ߍ. g7z˳pຊ+e`RXp"n۷MP(8nPʒlGk> ᆴ[7@_NwDsKjm/Q"ۮ գ`s(j ^)RR#w.mX6;AH{Lnt1sCPp jj<ӂǪcÀg62lǚ}xS4׺|NmF$cgm8O f;-8> :A|*vZ\ۻMIٕcAR,xяHn }1#ZEFİ4׾񣜩 71娮Ҕ'} '2ؑOɇ-w\S7 #H'ALpUN+bU<qdmLLJ(1ucuh 2:a5\"HkV9B_kjyl dDԕa 8ȚSUal̠{:!=e'(魫J#(l͐$8F]2M'2a `ɞuzlLts !Wf24&fpw(=h4Qhxēh^"SND;UZ;z0%0[e%UriKn 0C )4ӉdaKgL5[9h庣oYc~KAZ?PMQR0܊-MhW|'}W\v\ [|1jLigSo(BJxK󛵌ྔ'{YJɠ!r(VnZb;igr?:ys$*D@乵^WQ W\0GP4VFgE_]c\N-Z jz 86Чب#e1vX[*uQHoC\>T\HmF/* CUqւK(?ش?!W-lKuO=`QW,w $GK '&Rqkv>ȭ/LeV Q6">4rXSMLJZ_N;cV]봿R=V ~*k&Q|ub$* \IJ*GnWx)7DWr}pv”lzmc90}#r;H1OD~o^^ASUeJ~iz^j0{(&3z܋Cz-;;/w0_.18;ұW_{bii9lbUv2jo]N,ΊWBy۱XdiA~]W.XpZQt}p:& .i Ѕuzv+]S >F";_g 3]25l`QuߡaGxLZi*@}fkɡ4<S/W?Ly{191G;\1nwh~#Bh-gfy\H~ 67Cz pg/`|QEY3`.$HɘUqY4T̴|+&P6R2+!i8.D\z`(^XoJ mNPEL! ~ՀR X|zu=B^rBh> E1$g"Vi_(eI\Tyx d]:8v$.u\yt?;ZBjjۻƕz{endstream endobj 781 0 obj 3469 endobj 804 0 obj <> stream xuUn0 +|E@Qh.%=$I&hRח=3‡i鑏|7ocp~1}C}lpx|y ,$p/z 9!@I}ЃhL !eD4s]EI=hrF҃1OHtWQOu &\֏#sNRsU +9L#,U.6j)l}vG9u8 uPUaӘ2ߢзK0C*ikj?U;ZDvU\%p1FO"+@dZO{ %%OTggav}gP*'h 'SyEB;䁨jy,@ > /Contents 53 0 R >> endobj 59 0 obj <> /Contents 61 0 R >> endobj 64 0 obj <> /Annots[69 0 R 72 0 R 73 0 R 76 0 R 77 0 R 78 0 R 79 0 R 80 0 R 81 0 R 82 0 R 83 0 R 84 0 R 85 0 R 86 0 R 87 0 R 88 0 R 89 0 R 90 0 R 91 0 R 92 0 R 93 0 R 94 0 R 95 0 R 96 0 R 97 0 R 98 0 R 99 0 R 100 0 R 101 0 R 102 0 R 103 0 R 104 0 R 105 0 R 106 0 R 107 0 R 108 0 R 109 0 R 110 0 R 111 0 R 112 0 R 113 0 R 114 0 R 115 0 R 116 0 R 117 0 R 118 0 R 119 0 R 120 0 R 121 0 R 122 0 R 123 0 R 124 0 R 125 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R 133 0 R 134 0 R]/Contents 66 0 R >> endobj 138 0 obj <> /Contents 141 0 R >> endobj 183 0 obj <> /Contents 185 0 R >> endobj 211 0 obj <> /Contents 214 0 R >> endobj 242 0 obj <> /Contents 245 0 R >> endobj 286 0 obj <> /Contents 288 0 R >> endobj 303 0 obj <> /Contents 306 0 R >> endobj 315 0 obj <> /Contents 318 0 R >> endobj 358 0 obj <> /Contents 360 0 R >> endobj 393 0 obj <> /Contents 395 0 R >> endobj 424 0 obj <> /Contents 427 0 R >> endobj 457 0 obj <> /Contents 460 0 R >> endobj 493 0 obj <> /Contents 495 0 R >> endobj 514 0 obj <> /Contents 516 0 R >> endobj 533 0 obj <> /Contents 535 0 R >> endobj 561 0 obj <> /Contents 563 0 R >> endobj 575 0 obj <> /Contents 578 0 R >> endobj 627 0 obj <> /Contents 629 0 R >> endobj 664 0 obj <> /Contents 667 0 R >> endobj 671 0 obj <> /Contents 674 0 R >> endobj 722 0 obj <> /Contents 725 0 R >> endobj 777 0 obj <> /Contents 780 0 R >> endobj 802 0 obj <> /Contents 804 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 59 0 R 64 0 R 138 0 R 183 0 R 211 0 R 242 0 R 286 0 R 303 0 R 315 0 R 358 0 R 393 0 R 424 0 R 457 0 R 493 0 R 514 0 R 533 0 R 561 0 R 575 0 R 627 0 R 664 0 R 671 0 R 722 0 R 777 0 R 802 0 R ] /Count 25 >> endobj 7 0 obj << /Count 9 /First 8 0 R /Last 39 0 R >> endobj 1 0 obj <> >> /OpenAction [4 0 R /Fit] /PageMode/UseOutlines /PageLabels<< /Nums [0 << /P (1) >> 1 << /P (2) >> 2 << /P (iii) >> 3 << /P (1) >> 4 << /P (2) >> 5 << /P (3) >> 6 << /P (4) >> 7 << /P (5) >> 8 << /P (6) >> 9 << /P (7) >> 10 << /P (8) >> 11 << /P (9) >> 12 << /P (10) >> 13 << /P (11) >> 14 << /P (12) >> 15 << /P (13) >> 16 << /P (14) >> 17 << /P (15) >> 18 << /P (16) >> 19 << /P (17) >> 20 << /P (18) >> 21 << /P (19) >> 22 << /P (20) >> 23 << /P (21) >> 24 << /P (22) >>] >> /Metadata 823 0 R >> endobj 6 0 obj <>endobj 8 0 obj << /Title(PyGopherd Manual) /Dest(1.0) /Parent 7 0 R /Next 9 0 R >> endobj 9 0 obj << /Title(Table of Contents) /Dest(2.0) /Parent 7 0 R /Prev 8 0 R /Next 10 0 R >> endobj 11 0 obj << /Title(1.1. Features) /Dest(3.1.1) /Parent 10 0 R /Next 12 0 R >> endobj 12 0 obj << /Title(1.2. About Gopher) /Dest(3.2.1) /Parent 10 0 R /Prev 11 0 R >> endobj 10 0 obj << /Title(Chapter 1. Introduction to PyGopherd) /Dest(3.0) /Count -2 /Parent 7 0 R /Prev 9 0 R /Next 13 0 R /First 11 0 R /Last 12 0 R >> endobj 13 0 obj << /Title(Chapter 2. Quick Start) /Dest(4.0) /Parent 7 0 R /Prev 10 0 R /Next 14 0 R >> endobj 15 0 obj << /Title(3.1. Debian SystemWide Installation) /Dest(5.3.1) /Parent 14 0 R /Next 16 0 R >> endobj 16 0 obj << /Title(3.2. Other SystemWide Installation) /Dest(5.4.1) /Parent 14 0 R /Prev 15 0 R /Next 17 0 R >> endobj 17 0 obj << /Title(3.3. SingleAccount Installation) /Dest(5.5.1) /Parent 14 0 R /Prev 16 0 R >> endobj 14 0 obj << /Title(Chapter 3. Installation) /Dest(5.0) /Count -3 /Parent 7 0 R /Prev 13 0 R /Next 18 0 R /First 15 0 R /Last 17 0 R >> endobj 18 0 obj << /Title(Chapter 4. Configuration) /Dest(6.0) /Parent 7 0 R /Prev 14 0 R /Next 19 0 R >> endobj 20 0 obj << /Title(5.1. dir.DirHandler) /Dest(7.6.1) /Parent 19 0 R /Next 21 0 R >> endobj 21 0 obj << /Title(5.2. gophermap.BuckGophermapHandler) /Dest(7.7.1) /Parent 19 0 R /Prev 20 0 R /Next 22 0 R >> endobj 22 0 obj << /Title(5.3. file.CompressedFileHandler) /Dest(7.8.1) /Parent 19 0 R /Prev 21 0 R /Next 23 0 R >> endobj 23 0 obj << /Title(5.4. file.FileHandler) /Dest(7.9.1) /Parent 19 0 R /Prev 22 0 R /Next 24 0 R >> endobj 24 0 obj << /Title(5.5. html.HTMLFileTitleHandler) /Dest(7.10.1) /Parent 19 0 R /Prev 23 0 R /Next 25 0 R >> endobj 25 0 obj << /Title(5.6. mbox handlers) /Dest(7.11.1) /Parent 19 0 R /Prev 24 0 R /Next 26 0 R >> endobj 26 0 obj << /Title(5.7. pyg.PYGHandler) /Dest(7.12.1) /Parent 19 0 R /Prev 25 0 R /Next 27 0 R >> endobj 27 0 obj << /Title(5.8. scriptexec.ExecHandler) /Dest(7.13.1) /Parent 19 0 R /Prev 26 0 R /Next 28 0 R >> endobj 29 0 obj << /Title(5.9.1. Links) /Dest(7.14.1.2) /Parent 28 0 R /Next 30 0 R >> endobj 30 0 obj << /Title(5.9.2. Overriding Defaults) /Dest(7.14.2.2) /Parent 28 0 R /Prev 29 0 R /Next 31 0 R >> endobj 31 0 obj << /Title(5.9.3. Adding Cool Links) /Dest(7.14.3.2) /Parent 28 0 R /Prev 30 0 R /Next 32 0 R >> endobj 32 0 obj << /Title(5.9.4. Hiding an Entry) /Dest(7.14.4.2) /Parent 28 0 R /Prev 31 0 R /Next 33 0 R >> endobj 33 0 obj << /Title(5.9.5. Abstracts and Info) /Dest(7.14.5.2) /Parent 28 0 R /Prev 32 0 R >> endobj 28 0 obj << /Title(5.9. UMN.UMNDirHandler) /Dest(7.14.1) /Count -5 /Parent 19 0 R /Prev 27 0 R /Next 34 0 R /First 29 0 R /Last 33 0 R >> endobj 34 0 obj << /Title(5.10. url.HTMLURLHandler) /Dest(7.15.1) /Parent 19 0 R /Prev 28 0 R /Next 35 0 R >> endobj 35 0 obj << /Title(5.11. url.URLTypeRewriter) /Dest(7.16.1) /Parent 19 0 R /Prev 34 0 R /Next 36 0 R >> endobj 36 0 obj << /Title(5.12. virtual.Virtual) /Dest(7.17.1) /Parent 19 0 R /Prev 35 0 R /Next 37 0 R >> endobj 37 0 obj << /Title(5.13. ZIP.ZIPHandler) /Dest(7.18.1) /Parent 19 0 R /Prev 36 0 R >> endobj 19 0 obj << /Title(Chapter 5. Handlers) /Dest(7.0) /Count -13 /Parent 7 0 R /Prev 18 0 R /Next 38 0 R /First 20 0 R /Last 37 0 R >> endobj 38 0 obj << /Title(Chapter 6. Gopher Item Types) /Dest(8.0) /Parent 7 0 R /Prev 19 0 R /Next 39 0 R >> endobj 41 0 obj << /Title(Name) /Dest(9.19.6.2) /Parent 40 0 R /Next 42 0 R >> endobj 42 0 obj << /Title(Synopsis) /Dest(9.19.7.2) /Parent 40 0 R /Prev 41 0 R /Next 43 0 R >> endobj 43 0 obj << /Title(Description) /Dest(9.19.8.2) /Parent 40 0 R /Prev 42 0 R /Next 44 0 R >> endobj 44 0 obj << /Title(Quick Start) /Dest(9.19.9.2) /Parent 40 0 R /Prev 43 0 R /Next 45 0 R >> endobj 45 0 obj << /Title(Options) /Dest(9.19.10.2) /Parent 40 0 R /Prev 44 0 R /Next 46 0 R >> endobj 46 0 obj << /Title(Conforming To) /Dest(9.19.11.2) /Parent 40 0 R /Prev 45 0 R /Next 47 0 R >> endobj 47 0 obj << /Title(Bugs) /Dest(9.19.12.2) /Parent 40 0 R /Prev 46 0 R /Next 48 0 R >> endobj 48 0 obj << /Title(Copyright) /Dest(9.19.13.2) /Parent 40 0 R /Prev 47 0 R /Next 49 0 R >> endobj 49 0 obj << /Title(Author) /Dest(9.19.14.2) /Parent 40 0 R /Prev 48 0 R /Next 50 0 R >> endobj 50 0 obj << /Title(See Also) /Dest(9.19.15.2) /Parent 40 0 R /Prev 49 0 R >> endobj 40 0 obj << /Title(pygopherd) /Dest(9.19.1) /Count -10 /Parent 39 0 R /First 41 0 R /Last 50 0 R >> endobj 51 0 obj <>endobj 52 0 obj <>endobj 55 0 obj <>endobj 58 0 obj <> endobj 60 0 obj <>endobj 63 0 obj <> endobj 65 0 obj <>endobj 68 0 obj <>endobj 69 0 obj <>endobj 72 0 obj <>endobj 73 0 obj <>endobj 76 0 obj <>endobj 77 0 obj <>endobj 78 0 obj <>endobj 79 0 obj <>endobj 80 0 obj <>endobj 81 0 obj <>endobj 82 0 obj <>endobj 83 0 obj <>endobj 84 0 obj <>endobj 85 0 obj <>endobj 86 0 obj <>endobj 87 0 obj <>endobj 88 0 obj <>endobj 89 0 obj <>endobj 90 0 obj <>endobj 91 0 obj <>endobj 92 0 obj <>endobj 93 0 obj <>endobj 94 0 obj <>endobj 95 0 obj <>endobj 96 0 obj <>endobj 97 0 obj <>endobj 98 0 obj <>endobj 99 0 obj <>endobj 100 0 obj <>endobj 101 0 obj <>endobj 102 0 obj <>endobj 103 0 obj <>endobj 104 0 obj <>endobj 105 0 obj <>endobj 106 0 obj <>endobj 107 0 obj <>endobj 108 0 obj <>endobj 109 0 obj <>endobj 110 0 obj <>endobj 111 0 obj <>endobj 112 0 obj <>endobj 113 0 obj <>endobj 114 0 obj <>endobj 115 0 obj <>endobj 116 0 obj <>endobj 117 0 obj <>endobj 118 0 obj <>endobj 119 0 obj <>endobj 120 0 obj <>endobj 121 0 obj <>endobj 122 0 obj <>endobj 123 0 obj <>endobj 124 0 obj <>endobj 125 0 obj <>endobj 126 0 obj <>endobj 127 0 obj <>endobj 128 0 obj <>endobj 129 0 obj <>endobj 130 0 obj <>endobj 131 0 obj <>endobj 132 0 obj <>endobj 133 0 obj <>endobj 134 0 obj <>endobj 137 0 obj <> endobj 139 0 obj <>endobj 140 0 obj <>endobj 143 0 obj <>endobj 144 0 obj <>endobj 145 0 obj <>endobj 146 0 obj <>endobj 147 0 obj <>endobj 148 0 obj <>endobj 149 0 obj <>endobj 150 0 obj <>endobj 151 0 obj <>endobj 152 0 obj <>endobj 153 0 obj <>endobj 154 0 obj <>endobj 155 0 obj <>endobj 156 0 obj <>endobj 157 0 obj <>endobj 158 0 obj <>endobj 159 0 obj <>endobj 160 0 obj <>endobj 161 0 obj <>endobj 162 0 obj <>endobj 163 0 obj <>endobj 164 0 obj <>endobj 165 0 obj <>endobj 166 0 obj <>endobj 167 0 obj <>endobj 168 0 obj <>endobj 169 0 obj <>endobj 170 0 obj <>endobj 171 0 obj <>endobj 172 0 obj <>endobj 173 0 obj <>endobj 174 0 obj <>endobj 175 0 obj <>endobj 176 0 obj <>endobj 177 0 obj <>endobj 178 0 obj <>endobj 179 0 obj <>endobj 180 0 obj <>endobj 181 0 obj <>endobj 182 0 obj <> endobj 184 0 obj <>endobj 187 0 obj <>endobj 188 0 obj <>endobj 189 0 obj <>endobj 190 0 obj <>endobj 191 0 obj <>endobj 192 0 obj <>endobj 193 0 obj <>endobj 194 0 obj <>endobj 195 0 obj <>endobj 196 0 obj <>endobj 197 0 obj <>endobj 198 0 obj <>endobj 199 0 obj <>endobj 200 0 obj <>endobj 201 0 obj <>endobj 202 0 obj <>endobj 203 0 obj <>endobj 204 0 obj <>endobj 205 0 obj <>endobj 206 0 obj <>endobj 207 0 obj <>endobj 208 0 obj <>endobj 209 0 obj <>endobj 210 0 obj <> endobj 212 0 obj <>endobj 213 0 obj <>endobj 216 0 obj <>endobj 217 0 obj <>endobj 218 0 obj <>endobj 219 0 obj <>endobj 220 0 obj <>endobj 221 0 obj <>endobj 224 0 obj <>endobj 225 0 obj <>endobj 226 0 obj <>endobj 227 0 obj <>endobj 228 0 obj <>endobj 229 0 obj <>endobj 230 0 obj <>endobj 231 0 obj <>endobj 232 0 obj <>endobj 233 0 obj <>endobj 234 0 obj <>endobj 235 0 obj <>endobj 236 0 obj <>endobj 237 0 obj <>endobj 238 0 obj <>endobj 239 0 obj <>endobj 240 0 obj <>endobj 241 0 obj <> endobj 243 0 obj <>endobj 244 0 obj <>endobj 247 0 obj <>endobj 248 0 obj <>endobj 249 0 obj <>endobj 250 0 obj <>endobj 251 0 obj <>endobj 252 0 obj <>endobj 253 0 obj <>endobj 254 0 obj <>endobj 255 0 obj <>endobj 256 0 obj <>endobj 257 0 obj <>endobj 258 0 obj <>endobj 259 0 obj <>endobj 260 0 obj <>endobj 261 0 obj <>endobj 262 0 obj <>endobj 263 0 obj <>endobj 266 0 obj <>endobj 267 0 obj <>endobj 268 0 obj <>endobj 269 0 obj <>endobj 270 0 obj <>endobj 271 0 obj <>endobj 272 0 obj <>endobj 273 0 obj <>endobj 274 0 obj <>endobj 275 0 obj <>endobj 276 0 obj <>endobj 277 0 obj <>endobj 278 0 obj <>endobj 279 0 obj <>endobj 280 0 obj <>endobj 281 0 obj <>endobj 282 0 obj <>endobj 283 0 obj <>endobj 284 0 obj <>endobj 285 0 obj <> endobj 287 0 obj <>endobj 290 0 obj <>endobj 291 0 obj <>endobj 292 0 obj <>endobj 293 0 obj <>endobj 294 0 obj <>endobj 295 0 obj <>endobj 296 0 obj <>endobj 297 0 obj <>endobj 298 0 obj <>endobj 299 0 obj <>endobj 300 0 obj <>endobj 301 0 obj <>endobj 302 0 obj <> endobj 304 0 obj <>endobj 305 0 obj <>endobj 308 0 obj <>endobj 309 0 obj <>endobj 310 0 obj <>endobj 311 0 obj <>endobj 312 0 obj <>endobj 313 0 obj <>endobj 314 0 obj <> endobj 316 0 obj <>endobj 317 0 obj <>endobj 320 0 obj <>endobj 321 0 obj <>endobj 322 0 obj <>endobj 323 0 obj <>endobj 324 0 obj <>endobj 325 0 obj <>endobj 326 0 obj <>endobj 327 0 obj <>endobj 328 0 obj <>endobj 329 0 obj <>endobj 330 0 obj <>endobj 331 0 obj <>endobj 332 0 obj <>endobj 333 0 obj <>endobj 334 0 obj <>endobj 335 0 obj <>endobj 336 0 obj <>endobj 337 0 obj <>endobj 338 0 obj <>endobj 339 0 obj <>endobj 340 0 obj <>endobj 341 0 obj <>endobj 342 0 obj <>endobj 343 0 obj <>endobj 344 0 obj <>endobj 345 0 obj <>endobj 346 0 obj <>endobj 347 0 obj <>endobj 350 0 obj <>endobj 351 0 obj <>endobj 352 0 obj <>endobj 353 0 obj <>endobj 354 0 obj <>endobj 355 0 obj <>endobj 356 0 obj <>endobj 357 0 obj <> endobj 359 0 obj <>endobj 362 0 obj <>endobj 363 0 obj <>endobj 364 0 obj <>endobj 365 0 obj <>endobj 366 0 obj <>endobj 367 0 obj <>endobj 368 0 obj <>endobj 369 0 obj <>endobj 370 0 obj <>endobj 371 0 obj <>endobj 372 0 obj <>endobj 373 0 obj <>endobj 374 0 obj <>endobj 375 0 obj <>endobj 376 0 obj <>endobj 377 0 obj <>endobj 378 0 obj <>endobj 379 0 obj <>endobj 380 0 obj <>endobj 381 0 obj <>endobj 382 0 obj <>endobj 383 0 obj <>endobj 384 0 obj <>endobj 385 0 obj <>endobj 386 0 obj <>endobj 387 0 obj <>endobj 388 0 obj <>endobj 389 0 obj <>endobj 390 0 obj <>endobj 391 0 obj <>endobj 392 0 obj <> endobj 394 0 obj <>endobj 397 0 obj <>endobj 398 0 obj <>endobj 399 0 obj <>endobj 400 0 obj <>endobj 401 0 obj <>endobj 402 0 obj <>endobj 403 0 obj <>endobj 404 0 obj <>endobj 405 0 obj <>endobj 406 0 obj <>endobj 407 0 obj <>endobj 408 0 obj <>endobj 409 0 obj <>endobj 410 0 obj <>endobj 411 0 obj <>endobj 412 0 obj <>endobj 413 0 obj <>endobj 414 0 obj <>endobj 415 0 obj <>endobj 416 0 obj <>endobj 417 0 obj <>endobj 418 0 obj <>endobj 419 0 obj <>endobj 420 0 obj <>endobj 421 0 obj <>endobj 422 0 obj <>endobj 423 0 obj <> endobj 425 0 obj <>endobj 426 0 obj <>endobj 429 0 obj <>endobj 430 0 obj <>endobj 431 0 obj <>endobj 432 0 obj <>endobj 433 0 obj <>endobj 434 0 obj <>endobj 435 0 obj <>endobj 436 0 obj <>endobj 437 0 obj <>endobj 438 0 obj <>endobj 439 0 obj <>endobj 440 0 obj <>endobj 441 0 obj <>endobj 442 0 obj <>endobj 443 0 obj <>endobj 444 0 obj <>endobj 445 0 obj <>endobj 446 0 obj <>endobj 447 0 obj <>endobj 448 0 obj <>endobj 449 0 obj <>endobj 450 0 obj <>endobj 451 0 obj <>endobj 452 0 obj <>endobj 453 0 obj <>endobj 454 0 obj <>endobj 455 0 obj <>endobj 456 0 obj <> endobj 458 0 obj <>endobj 459 0 obj <>endobj 462 0 obj <>endobj 463 0 obj <>endobj 464 0 obj <>endobj 465 0 obj <>endobj 466 0 obj <>endobj 467 0 obj <>endobj 468 0 obj <>endobj 469 0 obj <>endobj 470 0 obj <>endobj 471 0 obj <>endobj 472 0 obj <>endobj 473 0 obj <>endobj 474 0 obj <>endobj 475 0 obj <>endobj 476 0 obj <>endobj 477 0 obj <>endobj 478 0 obj <>endobj 479 0 obj <>endobj 480 0 obj <>endobj 481 0 obj <>endobj 482 0 obj <>endobj 483 0 obj <>endobj 484 0 obj <>endobj 485 0 obj <>endobj 486 0 obj <>endobj 487 0 obj <>endobj 488 0 obj <>endobj 489 0 obj <>endobj 490 0 obj <>endobj 491 0 obj <>endobj 492 0 obj <> endobj 494 0 obj <>endobj 497 0 obj <>endobj 498 0 obj <>endobj 499 0 obj <>endobj 500 0 obj <>endobj 501 0 obj <>endobj 502 0 obj <>endobj 503 0 obj <>endobj 504 0 obj <>endobj 505 0 obj <>endobj 506 0 obj <>endobj 507 0 obj <>endobj 508 0 obj <>endobj 509 0 obj <>endobj 510 0 obj <>endobj 511 0 obj <>endobj 512 0 obj <>endobj 513 0 obj <> endobj 515 0 obj <>endobj 518 0 obj <>endobj 519 0 obj <>endobj 520 0 obj <>endobj 521 0 obj <>endobj 522 0 obj <>endobj 523 0 obj <>endobj 524 0 obj <>endobj 525 0 obj <>endobj 526 0 obj <>endobj 527 0 obj <>endobj 528 0 obj <>endobj 529 0 obj <>endobj 530 0 obj <>endobj 531 0 obj <>endobj 532 0 obj <> endobj 534 0 obj <>endobj 537 0 obj <>endobj 538 0 obj <>endobj 539 0 obj <>endobj 540 0 obj <>endobj 541 0 obj <>endobj 542 0 obj <>endobj 543 0 obj <>endobj 544 0 obj <>endobj 545 0 obj <>endobj 546 0 obj <>endobj 547 0 obj <>endobj 548 0 obj <>endobj 549 0 obj <>endobj 550 0 obj <>endobj 551 0 obj <>endobj 552 0 obj <>endobj 553 0 obj <>endobj 554 0 obj <>endobj 555 0 obj <>endobj 556 0 obj <>endobj 557 0 obj <>endobj 558 0 obj <>endobj 559 0 obj <>endobj 560 0 obj <> endobj 562 0 obj <>endobj 565 0 obj <>endobj 566 0 obj <>endobj 567 0 obj <>endobj 568 0 obj <>endobj 569 0 obj <>endobj 570 0 obj <>endobj 571 0 obj <>endobj 572 0 obj <>endobj 573 0 obj <>endobj 574 0 obj <> endobj 576 0 obj <>endobj 577 0 obj <>endobj 580 0 obj <>endobj 581 0 obj <>endobj 582 0 obj <>endobj 583 0 obj <>endobj 584 0 obj <>endobj 585 0 obj <>endobj 586 0 obj <>endobj 587 0 obj <>endobj 588 0 obj <>endobj 589 0 obj <>endobj 590 0 obj <>endobj 591 0 obj <>endobj 592 0 obj <>endobj 593 0 obj <>endobj 594 0 obj <>endobj 595 0 obj <>endobj 596 0 obj <>endobj 597 0 obj <>endobj 598 0 obj <>endobj 599 0 obj <>endobj 600 0 obj <>endobj 601 0 obj <>endobj 602 0 obj <>endobj 603 0 obj <>endobj 604 0 obj <>endobj 605 0 obj <>endobj 606 0 obj <>endobj 607 0 obj <>endobj 608 0 obj <>endobj 609 0 obj <>endobj 610 0 obj <>endobj 611 0 obj <>endobj 612 0 obj <>endobj 613 0 obj <>endobj 614 0 obj <>endobj 615 0 obj <>endobj 616 0 obj <>endobj 617 0 obj <>endobj 618 0 obj <>endobj 619 0 obj <>endobj 620 0 obj <>endobj 621 0 obj <>endobj 622 0 obj <>endobj 623 0 obj <>endobj 624 0 obj <>endobj 625 0 obj <>endobj 626 0 obj <> endobj 628 0 obj <>endobj 631 0 obj <>endobj 632 0 obj <>endobj 633 0 obj <>endobj 634 0 obj <>endobj 635 0 obj <>endobj 636 0 obj <>endobj 637 0 obj <>endobj 638 0 obj <>endobj 639 0 obj <>endobj 640 0 obj <>endobj 641 0 obj <>endobj 642 0 obj <>endobj 643 0 obj <>endobj 644 0 obj <>endobj 645 0 obj <>endobj 646 0 obj <>endobj 647 0 obj <>endobj 648 0 obj <>endobj 649 0 obj <>endobj 650 0 obj <>endobj 651 0 obj <>endobj 652 0 obj <>endobj 653 0 obj <>endobj 654 0 obj <>endobj 655 0 obj <>endobj 656 0 obj <>endobj 657 0 obj <>endobj 658 0 obj <>endobj 659 0 obj <>endobj 660 0 obj <>endobj 661 0 obj <>endobj 662 0 obj <>endobj 663 0 obj <> endobj 665 0 obj <>endobj 666 0 obj <>endobj 669 0 obj <>endobj 670 0 obj <> endobj 672 0 obj <>endobj 673 0 obj <>endobj 676 0 obj <>endobj 677 0 obj <>endobj 678 0 obj <>endobj 679 0 obj <>endobj 680 0 obj <>endobj 681 0 obj <>endobj 682 0 obj <>endobj 683 0 obj <>endobj 684 0 obj <>endobj 685 0 obj <>endobj 686 0 obj <>endobj 687 0 obj <>endobj 688 0 obj <>endobj 689 0 obj <>endobj 690 0 obj <>endobj 691 0 obj <>endobj 692 0 obj <>endobj 693 0 obj <>endobj 694 0 obj <>endobj 695 0 obj <>endobj 696 0 obj <>endobj 697 0 obj <>endobj 698 0 obj <>endobj 699 0 obj <>endobj 700 0 obj <>endobj 701 0 obj <>endobj 702 0 obj <>endobj 703 0 obj <>endobj 704 0 obj <>endobj 705 0 obj <>endobj 706 0 obj <>endobj 707 0 obj <>endobj 708 0 obj <>endobj 709 0 obj <>endobj 710 0 obj <>endobj 711 0 obj <>endobj 712 0 obj <>endobj 713 0 obj <>endobj 714 0 obj <>endobj 715 0 obj <>endobj 716 0 obj <>endobj 717 0 obj <>endobj 718 0 obj <>endobj 719 0 obj <>endobj 720 0 obj <>endobj 721 0 obj <> endobj 723 0 obj <>endobj 724 0 obj <>endobj 727 0 obj <>endobj 728 0 obj <>endobj 729 0 obj <>endobj 730 0 obj <>endobj 731 0 obj <>endobj 732 0 obj <>endobj 733 0 obj <>endobj 734 0 obj <>endobj 735 0 obj <>endobj 736 0 obj <>endobj 737 0 obj <>endobj 738 0 obj <>endobj 739 0 obj <>endobj 740 0 obj <>endobj 741 0 obj <>endobj 742 0 obj <>endobj 743 0 obj <>endobj 744 0 obj <>endobj 745 0 obj <>endobj 746 0 obj <>endobj 747 0 obj <>endobj 748 0 obj <>endobj 749 0 obj <>endobj 750 0 obj <>endobj 751 0 obj <>endobj 752 0 obj <>endobj 753 0 obj <>endobj 754 0 obj <>endobj 755 0 obj <>endobj 756 0 obj <>endobj 757 0 obj <>endobj 758 0 obj <>endobj 759 0 obj <>endobj 760 0 obj <>endobj 761 0 obj <>endobj 762 0 obj <>endobj 763 0 obj <>endobj 764 0 obj <>endobj 765 0 obj <>endobj 766 0 obj <>endobj 767 0 obj <>endobj 768 0 obj <>endobj 769 0 obj <>endobj 770 0 obj <>endobj 771 0 obj <>endobj 772 0 obj <>endobj 773 0 obj <>endobj 774 0 obj <>endobj 775 0 obj <>endobj 776 0 obj <> endobj 778 0 obj <>endobj 779 0 obj <>endobj 782 0 obj <>endobj 783 0 obj <>endobj 784 0 obj <>endobj 785 0 obj <>endobj 786 0 obj <>endobj 787 0 obj <>endobj 788 0 obj <>endobj 789 0 obj <>endobj 790 0 obj <>endobj 791 0 obj <>endobj 792 0 obj <>endobj 793 0 obj <>endobj 794 0 obj <>endobj 795 0 obj <>endobj 796 0 obj <>endobj 797 0 obj <>endobj 798 0 obj <>endobj 799 0 obj <>endobj 800 0 obj <>endobj 801 0 obj <> endobj 803 0 obj <>endobj 806 0 obj <>endobj 807 0 obj <>endobj 808 0 obj <>endobj 809 0 obj <>endobj 810 0 obj <>endobj 811 0 obj <>endobj 812 0 obj <> endobj 56 0 obj <> endobj 820 0 obj <> endobj 348 0 obj <> endobj 264 0 obj <> endobj 222 0 obj <> endobj 135 0 obj <> endobj 74 0 obj <> endobj 821 0 obj <> endobj 70 0 obj <> endobj 822 0 obj <> endobj 57 0 obj <> endobj 813 0 obj <>stream xWyTEQ1δ ( OEVY ;̠`(Ba\@V\#*`H"?&&ۤ&G{R"ʴ%Rb34scRœ?X֋b/,1/7 27=Yj͖ݖ}lDD q uZV*1Iˍswwb[Q%rvd\NKQjJ%MRr d%7cV袀?n_HLU$sɪ8.HL(u:lԩ*JqkNSq4aa4LOQi4d̩4\bzLVi՜*5.9#^OԩZ.-]MS 9*TjUiZH 5M r5*̩xu\`͇5m*UiZANWiҒc\rTZʠBFQh.]Ph1iiYՆ]䫴erѫq GFQ^E3½}}5~Z+b2cCBg'Q͝4,y~ƻL8ͽE fQéPʃAͦ&S5IͣFQa=5rP )/j5r)oʙPXʏGSʅIM&RA$*rB(7/eIYQ2?Rj 5R()IJRӨ/.Jr֫~&&LL M }ڜN77$C$$$S>|k>||bEtz_۾%}wr (v'  u0Z'H3Nc"',U`9KKy@:Z(ZJV_I>;$ m׎. 'd_І%^i2$x"{6yҪF0bm5<K+NeFF9} :{2rahp,합aR}ؕƖGޭZ\~4[ bĢD]@3vX}kLuCx"َsCLvW1HLxW(a >J=i=4lԓpՂ '̽7?5 # `&*:ߙla^ LW0PtXQbwfnŪun `r@Ҵg25ty޾. Fx qޟVs+wV{G+JYB>]]U7>q<_F{3LЉ<wQr|t!m/͸xAp<0$`ϱg}FڇzP'A|]r!M>1v!BUUYPv}YaG'P{N/)ݲ\J&gW`:Goi_(8Z^P.CiތE8y2bB%`bMsKp}whyL8ytRD3î^O.PT.ZљM 6-ixhMIPJBmmAƵcHQas^lNBϭJ|5᪡ڌMqb(8ūw ,WFǧ/DqhG6rkIȉ)H=Rtm#I/L_bo_i+ ՟mS|m]N]kW轲+=p4/ U0b]5ђ.RK.ryvG%A# ~$3kmXFCO'0X:ړHKwQ;Ԛ՘P\/EPt=鿘`?`O 9jYF<,+nL"EI L:a'a率ay0Jsj:(dnX9um,}? BoC)ad5KFEAІ?ZgyppЭeK\"c"kl,%Ƚx٨˞l} 3!a]~5l.4vџƓ/k 43@v'['9-z}V1X37F|0ecQyLDQTkqy=ɜ.a1_'CpLHĂ`'!q ؑי{Iv`Yw;\;/s,C?XX@-תu 1mn2bӓȊ L=sשIơ.Zyr h=G &||.lAp6կ&%c$+KIv;H9Zt CPXr;Y]XU{|8;|笕M }׫'D6 pvHYWgE ȐĪ3:{>H G͓O)d?ު9p\!~qruҚ(%9UۋvW R*;6M0|cet+W͠#~wO`ᒱ2`VX^Az}'*m‰nQ }BT7 nDoސ|h;;w',}SOΩ =w +##hK*d\f)S#F5}#U*س$wtt$̪G;gbG]`%?72cK &wك{ws:tLJxMGPe]Q0Wl 09> endobj 814 0 obj <>stream xWkPS>!U-i0lQUZUUA|D@QkWR<7sBHxFGQA:KVl:NZmq6s$hbq%{Zַ>^{E*LҪ*̎i%e!\ Ž]O=!9O ,z EKjyxy0(>nS̙<<-]Ä.\IcvZ?rd e,K:^&c42&U!cż-bL,KJ`b8df(=cgCzѮ,WN3 S7tD`Uv{ "o Aݛ]9@ v-Ҳ2IHM-utxszq?4oR֑ *e"l zP̵M:]^#O$e 'X4Fx1 `B B蓙72P'@1-=Xq K+#WJa6,2-Q ֝}H΢sZ ސd5RRPЧNm<#2׶;n")=! rZNNmI ..*i ^Lwm+p:U~M Yf[ֶ:A8`l[1th:uHx ~ξrG4%.j]XT7:ǝ"*4D`."NϤr f;XV_H(cM pR=]m֘fk l lT"TvηW NL^5U5zP/-MkQRIȻ_|펢;Z֙߱Úcͷ7zt%] *2De.ۚ]̫ &;/.ݙS)9xbkmb#ZP>ޢϏ]0sqcu,1Ԃ:L`7悏Xo} C\hUЁ2v\ОҚ2P*;%9xyC.+h7eU5m?Vh0Yh'11ӿQ?8[[-ΏDTԄJ-&"8lVf')^'tKwsB<#F#Tơ D҈)M=:">w}!V)SEٹir _g[ zIcFFoɬ H,'Szq\~5q0/uOǍ !CI;FfB Q@0v)B E:5E _Dj ۢrbr~1h:=NQ]Mq\isƴK__ z۳m򔇁-,ͦ㮜|&8?azBMBA_x|e~<}ľێjYJ}$&!,{[{#}t鋇^pdw~n_&JҊ۲7іs:*ʃcЛk'<`d3S\Rg‹.퓻 ˩\22j ]]儽y~_]h* D$A޷BӒΖܬIv D}~, {~׹BܢjP z,aE܈梕(oB_΁+a<.(Z$b䅍،@1 gL3 zK`% تU'jܸ\aMX0X*zӍ{w Z1Rık@Y _OX54FtۜIOAXG`jmKB#L1op0rBg8$2z G2rg 7D~{t/ `[}s nfQ(\)LD!n=?~&A F*[!ӇX¡쫁_up~Uզ.ITV\Ɲ{wŻݽnX&FаuZ3n*[0N\oXwk"\DTFlwL: %MTÜl ;4hST fv̆xLL%JA򂋚_9*.Wγ1駊ӵ&hϝ<7{;rz%&{Ng乣GsjaBװgy]k1Y|2ԜwHJ{Y-?qoǣN㎍g?! endstream endobj 265 0 obj <> endobj 815 0 obj <>stream xVip^X-F@4%:@&M3I#c8@dYג:|h-2,Y-[/̍CB&ɔɐsB %IS"IO$|AtC~߾<,.xfХZvFmFF^~2^豘/c8Q0 !.y C|;sW>2ԩb /@'&.RPO9,(4] )PRZ.^ޑZ9c7YDr*S[ 6Z,Q%+))?QQWSԔR+%b$Kყ(DUJ7E"HRb0=2 T1 SZhB37Ec4ajS,dp6gPSI&@Bj\C~)UӊOQ*IHU(#vèGZTuwȭiF-KWGY ; Ei RhE:P"-*^v2,lr\l#6a+X-a Ũv81b=qdX[牖yi>z,%~/P`^֪hzW:+[odY=c:ͮ>@8mNGj^gSI_<7_vu@ZG{xmgnS⡒> hc^k® T^ 7C9n$-a C=NH|~-sgM{Ï]DF8Q}g ( /B(x6GmD{ȳWv&iCerV? :eptz:eum~dl#\ 1G 1Õ|I`]RPB=﹵t v ' \LMA ]È!npXc7:Nzgˀy&W60oob>)xӟ|}od8۫a{{:ͮr/)\`_1ʗ0`Llh|WzXt:]v Yseur_CHanUTl-rBv)CWMUu&+ D ml34tu7hmjsh2cx}dWܶ޹a9Xlh19v /c<{0y5XhHIy-[n;Q*{";焘6q#*k؆:VXV^PiQԋ[2O89c 8Q_tZZnqtdl `;tvo:^; y8{Bi7E*aUA"Jqn#f˷a_}cXvݿw: l};C0 _?JCCm k`fWyJ@U*A>a*FA3?0pQ6n޼|(bp+'h?ypt <ԮGXkkԪ`-h)hcuD[ a4RXS*鵂K; ]V@{{^9E ;אҽ|l_.+Z]a9#h}1ouh0E:-]-ᒿIK/n'ҒB7V!ƧߓnǏ*#|ve[}W'?"V(A(FiNca^uHv-3kgkV90 UުC5&u514 {kY6> endobj 816 0 obj <>stream xXgTgQ1;A,XX0)*" "eU`XB,QQDcKKД{rr.c=;O\ucFX#̆C5E(#5XΌяǜE>'Ix%Z;FY{`!f;6&`rqS&ǩ"&(&Ϝ9SQ)U1De:6ZW* kUR1oobOC RjBTaE0eLASD?apUJpW(ca*I&+bqѪx[WDƅ$( j*&,J.\#1 853(_u|B|X*6Aous7ژ6$A7^2\KQ+I =JE*>6*$ߋSLīb"MW)#C£sSJ6UVݯJWFE8iU+)FĽ6h7 ]cƹ{$xj|(9;%GvQю'M4mYqp7~AG,&f# _bGRb @8ˈrbH%ybF8+D &D,  i"›!C5A-b8aGȉ]’DX1` "ѬYiA27opx"ɐ|G*RZ)=EQO뿿??`݀~j9RmyaЬAUV#3xfjȩCw :zuڙΠ6W올fM`ݶl/,pf !{2YKO+00)-'3$ F4mI"n$J44δc6 (d(Z$q՗lvp\LWѣ`2gth0O)e펰]Nc)Ī&kLUPL~6ENzI~ )-3{ұ*mQ2M5hZ&j1Ӊiŧ$xtXI("0LN-ZiEJOtR9PbiYhG5'70m?;Ğ^+GE$2P s~> {[ 6'ԭe#)o 7988'Ch05h~+Xm+ƄZ1g9ˮS0[Wk}Y8Ė~U͋wykV> )h0riw)g*2<$CykN0p;K%O^oR+XBJѕɂȇUV`<6/~fj)S( [ER0O0 Oѐ9A pRXGg1<;2!<|/Ȕjz4duYIEeVI <`IO~M;] źb(-()Ib6iJc@vq: 2a8w3yt0\$[)QZ`4⺃4t/3nkidM!*I ,$~} ۹f[zdk\U]ԧ:٣,lK+C-bievi!q3R\J7D=r$ߝ۔Y#ܧة4'_SE{+2?vnݳ1bƄi6z #acj4WRVEK{[&AcI kcrF0l[ClGhA`^JQveϥO>$Ns0xi2ʕu\hʟaWjz,Z39sPҾS@Wiv:ʟ2mY֦- n),j!VڇטĚ9RD._φռf,E\h'([<[e‰ ӪHA&B_B;疤-9[E͋D{}~/Njgg[9vTe82`Dg[wL_q260p"Eq\HDHrUt8"ݖ#3pf98S"k gk ڐcٸ+,Ff{|ԋӤ;=J$4T2nKxB=z| OQ7knYwpƅ-Oy.J%oyuXT9GfQڲ]EYu+7E ;s./vg/0^89ڃ)@-0YR{D 4l$-o.$LG".ъB<&LDo.><4DTa Ӆ+ h1K[ƬyO?qQu,_tP2bc 7 ܿvoHY32tSW 3O4tkD j҄3JbihwD/ T9$PrVBjZhG8\_xKYq[hڵڦ3L*ӖflΖ/_?4VȲ&?H'zIa=c |(SRҭq ҇=Q ]1ݽkJH@ ~1x5p_BgH~ G R8$2)>2f+np8Vk_/;Ŧ7)ϥJXx)<;rF)^8h6oAa$I%ŪA‡p;`,fjX)c[D~|f6#lvODS9[7阰s5,"X?(΢槎 /lITo}]W'B%tsӵ#[쑟a|APTglc+Yjes'Sy9ir%lUJagft kϢ R-`\pd*/ؘoE,-H' QƃowQH&X!ǚtIfU7j_(z?UJ#L[XXϺ8:`=y5nA[U6ekPBW^ǂ:ΤݟTn0h" bk*h$Dp8ۛ a.K=}@7%:-:lI*pFnc>2mu!R`z*ϫ߭-Cޱ*Gש$ݵV;O6W'.84WB_zoS>@Ӡ9q3VƎ]X6קT_;u~$3׶s甤@ 0*gߋ*-n8p,|W|T]W+}ï]:ޥnA_af!0hۆIa~[c+Vx02镫5^q,M`cp`Nd''50k44D/{"M}mpּ':5<{B #+-x0` "1iC^INwF}ʮșqQn4$gfw'󝦸|"'1kgU#^,~V ."O#OI-0E5ԈHgZIUXMd׸om8E /42i:%VۯM6mNK kN߹h6&YR9 ,].O{$-ʲJpEHѷ,ڬn~; BeUB6rI*)T]Ns@|"7`w`~"G?= dۤO^njmi|+#Il2⺼@W7Xu$ˬb)˿6HiopyO.Ieyyy݇ϲ\_.OLMK*>T[^-LT9młuxH2R)YjÏ,?na,6+2@ sV}"K]7V]p?cs0с8K25SMM/іUȏ/^<W2bUZmfFuSW X˃Gh sky3B/ess-o㞥p{%Wϑ&^Ǎ!#p+wĜW?]xUs$6y[VavMذlmfcWn f0v}w[?937 K`K}k7OlӲE GÏ/& Zxi|C{ kWX}鱊b[E<#l>qɜ_9(RbPpԟgGyIvFfTyYiyAnBDdb{;XGU]Ta%sfnۚ6 2O5YmݔLR\Z~ ouxEa,Y!܎Z9r v8hs+g3 ɣ}l0^KYRwF.77+ILXkkbD7g/R0U o]yƩUy>tBZQ-i,tc %n؞5ey`S }anZH_&P#j() Ľ/J'Z% ,() endstream endobj 136 0 obj <> endobj 817 0 obj <>stream xWyXSWڿ&umD;ZU#V[#".KH6A’@ (".j n]کyq߹[nt|||OwC^hX8YcQ1s$Qhi9F5] <#Ix _zk#IoLD>-7vv 63!~gY%i %~TT?Y ?ZK3@$e$@WfiBjsk3& $yJ S1D!x&ESTR(("*I|L">d9|@.*3_˓$JA*_) %)"Uj=>M*Qer).V(SqRR"ʔ|c\W1*3! !̗Q;S)P6\S& % R IS (ICL—!BIo$yHxi7o%$Ly*QZ&IT1PEIr~”ᷲ aػ*\VN>)F)U!ܖ)G~0-Ò( یaӱ-Vl6KǶc\lEb5|lۀ-bMX,6 { XdM"0Ŧb3(aaGf9&qwa?3OQn|+֎:N:7M.@Oq,*H}D&iȑ#A8ÚđYl}V5g UdhڃdkW&$ޑ=OfZG5:fY~3]Ta5U*qerFI!#d8/kW;8a4{ &W?b4(p(8 KMܴ3"\YPr8,\ؚVyϮNb[!~GĠ0xVh#ޑ߳1.ʭ@ r6^23E\? W>+ځ&r4[lf.?sSu{Cel@&ݎlW~ƒ\/he%n/*NEoP9O="Xd%8;6su*6?eģy6ޕ8ͻ3-e"঒oH۸̣*+q[(vXaz OuLL[8+Q\ir7~GuHf~FTBE^./m͜ꋞP~ 7:;@ W=w"X'T8lV`j/z'pQXVv 96ô%=@ EhWo7j~*G6N2vk>UȄZ 3}玾Bt_oYIJ1’%̋pmvI*Y~7ClȽAO"?2#(S|tvE>yZQ0zhήkDY&Ze M^}pV4_:e1t[ bN{M䱀\|1}69[a ++ݾݜ28rTqN|ͷ_RU/ cYyμ| a38m+|k}G3sm{)%~E|H}?jFh18lJ`5|)_r]9w;T3CMQ,c՜F{U ryG?kK,%T+J[_rq(i=ENM)0dl-=T'1Dگ=yŜtF;ewz@ .{n~=*XSbfEwvD)ѩJU!4 3c%%&8Z1Oh<į55w4Irr= ̹iUq"5:>oTgz|wh>B_\! >3)E9"1!,RS gGzgUZ@Eja;l[)؝~fLi^!8eegat߀/z[σK+΢xKj=M8j5`ؠܻ?KMnm- ZXe]|8 EX乭%e Q'"R4@ ^cM ^|}.=|9 n7pJW)Yǯ{`]2?׃]R\–?s* K}+INcw(d ꒡\j65O4xa0R@rZey S08wS7DGFxr[^Cm2CMʒZos))\\ M-΃0Hgo\΃FCÐ#.YU3Od?0( "f5ZKEz=e>O  =n/f»lG:NVΞE Ogu<SlYRYn75+2"$GI(:,ڪ\'MmmWQgj n;H)4PQX^zd =`} אW}=?ۙN/!$ 8՘4ǟ۷- ҭ e^i 2qVɡ/\@yC/oܖk 7|5R6 ]!ssp]4*{CF?g(-z#C9t_|-362oQ)$뙿ۍڝ`;hKߟxk%*~dd:^FXުj]\(ga?oLn$>F8n΍7d8= n߬.e삄+y(W_:~< endstream endobj 75 0 obj <> endobj 818 0 obj <>stream xxyXS19JMZZ[qpFDd! !aڌaJ$<^21:2JtʕnGnydёnodX"Q"hm^{߶g6Q(1TtD&v$'q ćGˣ%nenn2(,?$R΅wܤĸh _E"Cp7-:>L!I%x=WyIdrYXbTw:i<*TW$pIXӛCenrB-b|c,ywr\5k筛 N93xA%+ /bM&$|}<—O'&b!Ol""" A]b+F,%ˈ{Nb9x$> v+=;"xID0!xE)` Wb&^%E7y5b 1#Ӊxb1EAL%D=tSOɼ2,U} )Bx?_H~yӚtgTQ❗v|cBӸj+3_93sV,ŬY?Vvy_:׮9sx|ՁWo $.uc}>x׾`Gs}3"ӯ9c~v|CiG_ᥰQnzKW@;bi*ϷZ9K @tJq-,B6A 5fYF>xĬrKsT\5FHu9`yhMy;F;HDO*yS ,ԕ *ɧ!6U Ƽ@e7?.JSdWHB^=eܦ\UWCB@yh)ڿ쵌LLNz(A-껇 p>[X |L5Dd}Ή ;W.=|F| QQ6]`Wtӏvz3,΂Jl'Ǧ eFj܋Z,!]m8R;+NYK)?N]vmD_p]jyYcl?9LkC 5C} }1dV2۔Ki@. (>Vwn-EίE?? ~J)6zs|OqwD%L ><*9OkwR5WR8C=G0,NF *$ Ja6G^e8o`9TEnՖ)쌩3 >5 ߄/mb!)orWŇ 6p[u Y( ܰOW` Ay =}$YbPM{gk.)vTV6^Ż%wG:?g42fqr .جӮ$]|х^;ֲ9sCcINgY;ɕ#+V-T'VM%]\G8j8N7ƕ7\7eO/m8>$DX)خ[Ib0@Ms.ej I4ۜ|\(rk p`x6#µ\ ;eu@Iف h.p1i-T-T#jFf.즢Fte|QW.Yux ,eԷhԛ `\`{4ӳr@՗Q> ]:̂F-_e)D h,*0 *4e& lMɎhz<_y~IZ/}E`*;@V+իo:M/t>翘~Oӷ]Ll 4VpMSP._o9mpdz87ai̛|0 )NeqRRA /tTʀ+[jZy*-ͥyg f⚪455fV'd{HR֦-jcA6=s,EJ`VyVy-HS2vt3Z1ឧM_ F.7^7ER!Cղa$+mR(5RCCɃo7n8%;8!$XnPH̀S6 @q?Ř87ނ4'$0ҌLXo43fls4:^rHOݩv,9QeHuBKrĞ(i82ߞsϘP3'UVvߌUA7扸0:j'7i-xo+{ #䂏^U|bв vlXCHNUnґ@Ib]c;J!gY B{+,wY}Uvw}lI!d Z݊ɞ2? nO{jyT= O\lAq0=mY6PC!0ބ%&k&Uf̧l_Md oig7)ҋ@0[lex|ܒM?6l[+} n}ZS0h0.9Ac*7  w g ;iul0 M2t)J䭀r05ecflf,;fEr ͇RPj6P]ѷbM(Ŗ܋Q`*|3(,^@~oCe8sչt(*We%7Z'ϩfu]Ram ;Rj599favIN10Sm5}#{Hx*()E b(PPQr*ߵكлi:F (IǠY> 0plcAJx yiƖ\ -S-٥&:]R8äSjS4d@,j1b%d ж|!6Zw`6R+m!|+V`3̘l%X#!#W&\4YdQn0$-T8^A|y:|qy{#S~S{uzpb-AV8T[G'$w)1U4r**WMڢN!GVBލ8G^ <79<D✓8GEZjf)(\ LL˄~0@G4dCfX(nk tjeSIHRh  fU 'IJ,-qs3B~VVZw&-̨Ϥ%ܠ-2k?iEQ*,J*T)^{n˱)G!m` ^y2Uv p/R3~]0*P??஦Ӯm*]mnZ,wD@| LyĄp)VYLǴJ}*ʰKO%s@1K Gh )jx^N98!܅r*0u2%(wO5r鑃~N;Ҝ8{oY䴞KגRib-8iU {4$З8Vz{XRIlɱ{0dΨ߀mb@wn8^cl(;9-+G`%EH AG(urɣ]bt`c\2xQے3 _ ΁n0Ǿ7Vt-POʮ3zxiHKT%QQ~ j=0Q#5g5)&8U"=VC|"P Z{UmWH~aBHzdjjegl6;b 6}Kkp9)j ~Luw1< ٕ9 8S:Xwk\isE8+*ٜJL饆tzd%W;'GL'Om4o, @d&7O.`=Ucz MML:q{ב)xJ1'BoܼijQt5FP*Uxm HA=S6.ؘE<P흍%9|`϶ngkmlou9VF!lnjFzGj͖B bSpk*BPU ©}Q{C|c/%c=.bZuKWpߝ=_Mh|'d ݲ.Aoh[M1_5paQ϶El Vt-ǿq6c?oCǪ/j< #'Rw`P'#Q ަbpA䯡gVy y2#?Z//u6|X<Ҽb]d(O]?;S3uyv(?4Ekƶ8 ͢~gZ59GR= κou_E$sy0 lxTVg^8( 94R!N2-ve NnvSRc+ϳ~̤&f~P 6rGazs7Hrh̕II^GӚ$.7@ONͺSC2;S׫[#"c]UL|X CT[SGE%d oZy-(Uxs˭6WWH~| M C uvEd5֚P0>:܌|/HĜ_k˳~m EJԧ t PYUՔ⦫T%)BOc(XU`@3֮1;Ezwg+ M *< f(Jo NzLfvܞ>qB] ᤦGWHӕpd+('ӘGL;Ơ][t[p<5Z FzJY~=xl1y`ͪ H5Juqh8¯bnحC\Pͮ Ge0g|gcDBòXiql^=xz:vz.ג_Jpd`{0WI݅(>F|F&i@/!y'x(G7!@q<EW͟$;qjdA M  !|]VO6A-= 甦un_sC z*sj>oV'3lEpxj||5~ MO.;pܸq|}bskC}skBCı o^0lg#?3hØK;hYh\_'B$@hGrRv]@  ]_CY GG!QaQ|",֛x'L8T<ۗ4dyaYAA^bu:V14u&+f&7aO ]==:8ѵkձ;{t Wm!Glz|M=H FcUuԣ>+/^L"owo#n\i;{]Zt.[EfqnEsEP]v9lV(M1ETfܡ$G &}|aC1 8z,5FQb8o>3] QF ꄤL^Hudb0.N&6Ἇxi1LI{ѵqo.؁VhG\ddC#9mipc&A… PofV'21"6b 9 QUg qz7O-ܳam\'y8^K}t 82S8i3:_2i X  77rFv 㗞| M"2$(6…p*$ A''6*g{wO79l֒ΉFoaq^h^e*Yql8 FeaŜ}zpLe?hI;(/YYYP) 3e⸚ښYDjf45 I;u͗!ƪKv}W+f/x W=)P}.v:s|T3pᘀs>wمapp![}$|D,2Лa67s}J.f~J.S(婶+ W+h61Zf^L©#/J-fZG tC$P"ゔ4}Df@hs2a.d2:?Y tH@˧z{cD=%KpbjE"'* @kq)=V?BC?r;ZwTeLr&4=[Xn94sq[G+:;ϴ PE;XnO[dO6AalX #sSƾV@/a 2x\-"zq2x.F!S&`4dg!4`_C/S8ǀXP N9%dF^z>Sg+4i Յ`$Hz$q QluKti#-if -p=fq""(?bV,7B0 K0CrFs@_/OjtqGJ endstream endobj 71 0 obj <> endobj 819 0 obj <>stream xWyT׶b$ߧ *i 8$i:T{mP'&:2I̓ $ID-֡U飓޶v[|Pۻ{뽵⟐}ۿ;R.Ϗ0kR_F_6mio:s9?kJS׺z,0x4iI{zN_2=y3^L=3oBh4r0! p~ G+RK,_=Dc5jF7z| Iй&%dsfla2(dp+; yqz}[8LC L$c dY:RKfNJFxqׅHp͇UdI+3kYJ{. G=ق6vm a,C ax~y qa(At!,LJnHh΃6 4hE#yHL(>ҏU"ʯFLS]ͅf];>x!6Zk==tk*2G uR_KD&%.W#.͐RƇ!a}>q׵qY'ȈZM( $U;VD >8GBU}Yd1i2;*A6p뿡Uš5VH쬃ٌ4B[#XfG# M6YC_8J] (o#ow?yzXB}X]s񄻖~އ 5rZ nߡw=3b}upF2Z{%w4)ƛ0#[Fn@ZF]õÚhtn{qzexisn&p{ BS36䐓חzmS?kLGNhv/ O0U23 IȩIK߷!ʩ?<[k Pj _kJ6=@J>R"z~z_CmgOxU.!b@:ٳ6Jkg [ְN*H'=?r.|?E ^F)%'mѶXcLv.];|ȵbҞ59ȀYY8gEj*]GmE>N\leeYh`Q `@Uuu88l, nL/k3̘FAfZ+DL D8J"@`^!0[\F bs-n8@Up#ϩm'a/:loPnfŜbL5ۣ jyZGAyjBNG~8rvT~~73\/u \ HC!cgZٻt*R~(!mf5CCUm±#cnG~Wt?zl`Vjc4͑P[?5֗3+j.8il aRnqS=Yu2E-"Lrv+;7cAb3i&,+<ܠ'LB7G'D,W_ܾ!#5 ,¥HWWmr"U&hMJeI/?VG4`C l'X@u'FǾSĊv*h&G -2Sh}kced.,g*n컟y)X/v!o]џk:N{mڤ 2ĊMΠzz̷2QZ,8ާ$;j= 'ޚu7~ 垒3Ϯ{goOnT-/g_޾,h/v"<&j0.QObp 9 S'>} t#Ysg~mgB""Brqd611=b50!\HZjl \age"1rEܾxfn}W+LÓ@D*`_NkpGd4'5t%`OX!}W,_x[cnz<<,D/ +%2Vsq^C/:T藒&G51_N:-G)Y 7'>꺺 O- gvG\ZEfZrI|Zz||ga]1 uxL endstream endobj 39 0 obj << /Title(I. PyGopherd Manpage) /Dest(9.0) /Count -1 /Parent 7 0 R /Prev 38 0 R /First 40 0 R /Last 40 0 R >> endobj 5 0 obj << /Limits [ (0:10) (page.iii) ] /Names [ (0:10) 149 0 R (0:100) 256 0 R (0:103) 259 0 R (0:104) 260 0 R (0:105) 261 0 R (0:106) 262 0 R (0:107) 263 0 R (0:108) 266 0 R (0:109) 267 0 R (0:11) 150 0 R (0:110) 268 0 R (0:111) 269 0 R (0:112) 270 0 R (0:113) 271 0 R (0:114) 272 0 R (0:115) 273 0 R (0:118) 276 0 R (0:119) 277 0 R (0:12) 151 0 R (0:120) 278 0 R (0:121) 279 0 R (0:122) 280 0 R (0:123) 281 0 R (0:124) 282 0 R (0:125) 283 0 R (0:126) 284 0 R (0:127) 290 0 R (0:128) 291 0 R (0:129) 292 0 R (0:13) 152 0 R (0:130) 293 0 R (0:131) 294 0 R (0:132) 295 0 R (0:133) 296 0 R (0:134) 297 0 R (0:135) 298 0 R (0:136) 299 0 R (0:137) 300 0 R (0:138) 301 0 R (0:14) 153 0 R (0:141) 309 0 R (0:142) 310 0 R (0:143) 311 0 R (0:144) 312 0 R (0:145) 313 0 R (0:148) 321 0 R (0:149) 322 0 R (0:15) 154 0 R (0:150) 323 0 R (0:151) 324 0 R (0:152) 325 0 R (0:153) 326 0 R (0:154) 327 0 R (0:155) 328 0 R (0:158) 331 0 R (0:159) 332 0 R (0:16) 155 0 R (0:160) 333 0 R (0:161) 334 0 R (0:164) 337 0 R (0:165) 338 0 R (0:166) 339 0 R (0:167) 340 0 R (0:168) 341 0 R (0:169) 342 0 R (0:17) 156 0 R (0:170) 343 0 R (0:171) 344 0 R (0:172) 345 0 R (0:173) 346 0 R (0:174) 347 0 R (0:175) 350 0 R (0:176) 351 0 R (0:177) 352 0 R (0:178) 353 0 R (0:179) 354 0 R (0:18) 157 0 R (0:180) 355 0 R (0:181) 362 0 R (0:182) 356 0 R (0:184) 363 0 R (0:185) 364 0 R (0:186) 365 0 R (0:188) 366 0 R (0:189) 367 0 R (0:19) 158 0 R (0:190) 368 0 R (0:191) 369 0 R (0:192) 370 0 R (0:194) 371 0 R (0:195) 372 0 R (0:196) 373 0 R (0:197) 374 0 R (0:198) 375 0 R (0:20) 159 0 R (0:200) 376 0 R (0:201) 377 0 R (0:202) 378 0 R (0:203) 379 0 R (0:204) 380 0 R (0:205) 381 0 R (0:206) 382 0 R (0:207) 383 0 R (0:21) 160 0 R (0:210) 386 0 R (0:211) 387 0 R (0:212) 388 0 R (0:213) 389 0 R (0:214) 390 0 R (0:215) 391 0 R (0:216) 397 0 R (0:217) 398 0 R (0:22) 161 0 R (0:220) 401 0 R (0:221) 402 0 R (0:224) 405 0 R (0:227) 408 0 R (0:228) 409 0 R (0:229) 410 0 R (0:23) 162 0 R (0:230) 411 0 R (0:231) 412 0 R (0:232) 413 0 R (0:233) 414 0 R (0:234) 415 0 R (0:235) 416 0 R (0:236) 417 0 R (0:237) 418 0 R (0:238) 419 0 R (0:239) 420 0 R (0:24) 163 0 R (0:240) 421 0 R (0:243) 430 0 R (0:244) 431 0 R (0:245) 432 0 R (0:246) 433 0 R (0:247) 434 0 R (0:248) 435 0 R (0:249) 436 0 R (0:25) 164 0 R (0:250) 437 0 R (0:251) 438 0 R (0:252) 439 0 R (0:253) 440 0 R (0:256) 443 0 R (0:257) 444 0 R (0:258) 445 0 R (0:259) 446 0 R (0:26) 165 0 R (0:261) 447 0 R (0:262) 448 0 R (0:263) 449 0 R (0:265) 450 0 R (0:266) 451 0 R (0:267) 452 0 R (0:269) 453 0 R (0:27) 166 0 R (0:270) 454 0 R (0:271) 455 0 R (0:273) 462 0 R (0:274) 463 0 R (0:275) 464 0 R (0:277) 426 0 R (0:278) 465 0 R (0:279) 466 0 R (0:28) 167 0 R (0:280) 467 0 R (0:282) 468 0 R (0:283) 469 0 R (0:284) 470 0 R (0:286) 471 0 R (0:287) 472 0 R (0:288) 473 0 R (0:29) 168 0 R (0:290) 474 0 R (0:291) 475 0 R (0:292) 476 0 R (0:293) 477 0 R (0:294) 478 0 R (0:295) 479 0 R (0:298) 482 0 R (0:299) 483 0 R (0:30) 169 0 R (0:300) 484 0 R (0:301) 485 0 R (0:304) 488 0 R (0:305) 489 0 R (0:306) 490 0 R (0:307) 491 0 R (0:308) 459 0 R (0:309) 497 0 R (0:31) 170 0 R (0:310) 498 0 R (0:311) 499 0 R (0:314) 502 0 R (0:315) 503 0 R (0:316) 504 0 R (0:317) 505 0 R (0:318) 506 0 R (0:319) 507 0 R (0:32) 171 0 R (0:320) 508 0 R (0:321) 509 0 R (0:322) 510 0 R (0:323) 511 0 R (0:324) 512 0 R (0:325) 518 0 R (0:328) 521 0 R (0:329) 522 0 R (0:33) 172 0 R (0:330) 523 0 R (0:331) 524 0 R (0:332) 525 0 R (0:335) 528 0 R (0:336) 529 0 R (0:337) 530 0 R (0:338) 531 0 R (0:34) 173 0 R (0:341) 539 0 R (0:342) 540 0 R (0:343) 541 0 R (0:344) 542 0 R (0:345) 543 0 R (0:346) 544 0 R (0:349) 547 0 R (0:35) 174 0 R (0:350) 548 0 R (0:351) 549 0 R (0:352) 550 0 R (0:353) 551 0 R (0:354) 552 0 R (0:355) 553 0 R (0:356) 554 0 R (0:357) 555 0 R (0:36) 175 0 R (0:360) 558 0 R (0:363) 566 0 R (0:364) 567 0 R (0:365) 568 0 R (0:368) 571 0 R (0:369) 572 0 R (0:37) 176 0 R (0:370) 573 0 R (0:373) 581 0 R (0:374) 582 0 R (0:375) 583 0 R (0:376) 584 0 R (0:377) 585 0 R (0:378) 586 0 R (0:379) 587 0 R (0:38) 177 0 R (0:381) 588 0 R (0:382) 589 0 R (0:383) 590 0 R (0:385) 591 0 R (0:386) 592 0 R (0:387) 593 0 R (0:389) 594 0 R (0:39) 178 0 R (0:390) 595 0 R (0:391) 596 0 R (0:392) 597 0 R (0:394) 598 0 R (0:395) 599 0 R (0:396) 600 0 R (0:398) 601 0 R (0:399) 602 0 R (0:40) 179 0 R (0:400) 603 0 R (0:402) 604 0 R (0:403) 605 0 R (0:404) 606 0 R (0:405) 607 0 R (0:407) 608 0 R (0:408) 609 0 R (0:409) 610 0 R (0:41) 180 0 R (0:410) 611 0 R (0:412) 612 0 R (0:413) 613 0 R (0:414) 614 0 R (0:416) 615 0 R (0:417) 616 0 R (0:418) 617 0 R (0:42) 181 0 R (0:420) 618 0 R (0:421) 619 0 R (0:422) 620 0 R (0:424) 621 0 R (0:425) 622 0 R (0:426) 623 0 R (0:427) 624 0 R (0:429) 631 0 R (0:43) 187 0 R (0:430) 632 0 R (0:431) 633 0 R (0:432) 634 0 R (0:434) 625 0 R (0:435) 635 0 R (0:436) 636 0 R (0:437) 637 0 R (0:439) 638 0 R (0:44) 188 0 R (0:440) 639 0 R (0:441) 640 0 R (0:443) 641 0 R (0:444) 642 0 R (0:445) 643 0 R (0:447) 644 0 R (0:448) 645 0 R (0:449) 646 0 R (0:45) 189 0 R (0:451) 647 0 R (0:452) 648 0 R (0:453) 649 0 R (0:455) 650 0 R (0:456) 651 0 R (0:457) 652 0 R (0:459) 653 0 R (0:46) 190 0 R (0:460) 654 0 R (0:461) 655 0 R (0:463) 656 0 R (0:464) 657 0 R (0:465) 658 0 R (0:467) 659 0 R (0:468) 660 0 R (0:469) 661 0 R (0:47) 191 0 R (0:470) 662 0 R (0:473) 673 0 R (0:474) 677 0 R (0:475) 678 0 R (0:476) 679 0 R (0:477) 680 0 R (0:48) 192 0 R (0:484) 681 0 R (0:485) 682 0 R (0:486) 684 0 R (0:487) 685 0 R (0:488) 687 0 R (0:489) 688 0 R (0:49) 193 0 R (0:490) 689 0 R (0:491) 690 0 R (0:494) 693 0 R (0:495) 694 0 R (0:496) 695 0 R (0:499) 698 0 R (0:5) 144 0 R (0:50) 194 0 R (0:500) 699 0 R (0:501) 700 0 R (0:502) 701 0 R (0:503) 702 0 R (0:504) 703 0 R (0:505) 704 0 R (0:506) 705 0 R (0:507) 706 0 R (0:508) 707 0 R (0:509) 708 0 R (0:51) 195 0 R (0:510) 709 0 R (0:511) 710 0 R (0:512) 711 0 R (0:513) 712 0 R (0:514) 713 0 R (0:515) 714 0 R (0:516) 715 0 R (0:517) 716 0 R (0:518) 717 0 R (0:519) 718 0 R (0:52) 196 0 R (0:520) 719 0 R (0:523) 728 0 R (0:524) 729 0 R (0:525) 730 0 R (0:527) 731 0 R (0:528) 732 0 R (0:529) 733 0 R (0:53) 197 0 R (0:530) 734 0 R (0:531) 735 0 R (0:534) 738 0 R (0:535) 739 0 R (0:536) 740 0 R (0:537) 741 0 R (0:538) 742 0 R (0:539) 743 0 R (0:54) 198 0 R (0:540) 744 0 R (0:541) 745 0 R (0:542) 746 0 R (0:543) 747 0 R (0:544) 748 0 R (0:545) 749 0 R (0:546) 750 0 R (0:547) 751 0 R (0:548) 752 0 R (0:549) 753 0 R (0:55) 199 0 R (0:550) 754 0 R (0:551) 755 0 R (0:552) 756 0 R (0:553) 757 0 R (0:554) 758 0 R (0:555) 759 0 R (0:556) 760 0 R (0:557) 761 0 R (0:558) 762 0 R (0:559) 763 0 R (0:56) 200 0 R (0:560) 764 0 R (0:561) 765 0 R (0:562) 766 0 R (0:563) 767 0 R (0:564) 768 0 R (0:565) 769 0 R (0:566) 770 0 R (0:567) 771 0 R (0:568) 772 0 R (0:569) 773 0 R (0:57) 201 0 R (0:570) 774 0 R (0:573) 783 0 R (0:574) 784 0 R (0:575) 785 0 R (0:576) 724 0 R (0:579) 788 0 R (0:58) 202 0 R (0:580) 789 0 R (0:581) 790 0 R (0:582) 791 0 R (0:583) 792 0 R (0:584) 793 0 R (0:587) 796 0 R (0:588) 797 0 R (0:589) 798 0 R (0:59) 203 0 R (0:590) 799 0 R (0:591) 800 0 R (0:592) 806 0 R (0:593) 807 0 R (0:594) 779 0 R (0:596) 808 0 R (0:597) 809 0 R (0:599) 811 0 R (0:6) 145 0 R (0:62) 206 0 R (0:63) 207 0 R (0:64) 208 0 R (0:65) 209 0 R (0:68) 217 0 R (0:69) 218 0 R (0:7) 146 0 R (0:70) 219 0 R (0:71) 220 0 R (0:72) 221 0 R (0:73) 224 0 R (0:74) 225 0 R (0:75) 226 0 R (0:76) 227 0 R (0:77) 228 0 R (0:78) 229 0 R (0:79) 230 0 R (0:80) 231 0 R (0:81) 232 0 R (0:82) 233 0 R (0:83) 234 0 R (0:84) 235 0 R (0:85) 236 0 R (0:86) 237 0 R (0:87) 238 0 R (0:88) 239 0 R (0:89) 240 0 R (0:92) 248 0 R (0:93) 249 0 R (0:94) 250 0 R (0:97) 253 0 R (0:98) 254 0 R (0:99) 255 0 R (0:ABOUTGOPHER) 204 0 R (0:AUTHOR) 794 0 R (0:BUGS) 775 0 R (0:CONFIGURATION) 305 0 R (0:CONFORMING) 736 0 R (0:COPYRIGHT) 786 0 R (0:FEATURES) 147 0 R (0:HANDLERS) 317 0 R (0:HANDLERS.BUCKGOPHERMAP) 335 0 R (0:HANDLERS.COMPRESSEDFILEHANDLER) 384 0 R (0:HANDLERS.DIRHANDLER) 329 0 R (0:HANDLERS.EXECHANDLER) 441 0 R (0:HANDLERS.FILEHANDLER) 399 0 R (0:HANDLERS.HTMLFILETITLEHANDLER) 403 0 R (0:HANDLERS.HTMLURLHANDLER) 545 0 R (0:HANDLERS.MAILBOXES) 406 0 R (0:HANDLERS.PYGHANDLER) 422 0 R (0:HANDLERS.UMN) 480 0 R (0:HANDLERS.UMN.ABSTRACTS) 537 0 R (0:HANDLERS.UMN.COOL) 519 0 R (0:HANDLERS.UMN.HIDING) 526 0 R (0:HANDLERS.UMN.LINKS) 486 0 R (0:HANDLERS.UMN.OVERRIDING) 500 0 R (0:HANDLERS.URLTYPEREWRITER) 556 0 R (0:HANDLERS.VIRTUAL) 559 0 R (0:HANDLERS.ZIP) 569 0 R (0:INSTALLATION) 244 0 R (0:INSTALLATION.DEBIAN) 251 0 R (0:INSTALLATION.OTHER) 257 0 R (0:INSTALLATION.SINGLE) 274 0 R (0:MAN.DESCRIPTION) 691 0 R (0:MANPAGE.QUICKSTART) 696 0 R (0:OPTIONS) 720 0 R (0:PYGOPHERD) 52 0 R (0:PYGOPHERD.INTRO) 140 0 R (0:PYGOPHERD.MAN) 666 0 R (0:QUICKSTART) 213 0 R (0:TYPES) 577 0 R (1.0) 55 0 R (2.0) 68 0 R (3.0) 143 0 R (3.1.1) 148 0 R (3.2.1) 205 0 R (4.0) 216 0 R (5.0) 247 0 R (5.3.1) 252 0 R (5.4.1) 258 0 R (5.5.1) 275 0 R (6.0) 308 0 R (7.0) 320 0 R (7.10.1) 404 0 R (7.11.1) 407 0 R (7.12.1) 429 0 R (7.13.1) 442 0 R (7.14.1) 481 0 R (7.14.1.2) 487 0 R (7.14.2.2) 501 0 R (7.14.3.2) 520 0 R (7.14.4.2) 527 0 R (7.14.5.2) 538 0 R (7.15.1) 546 0 R (7.16.1) 557 0 R (7.17.1) 565 0 R (7.18.1) 570 0 R (7.6.1) 330 0 R (7.7.1) 336 0 R (7.8.1) 385 0 R (7.9.1) 400 0 R (8.0) 580 0 R (9.0) 669 0 R (9.19.1) 676 0 R (9.19.10.2) 727 0 R (9.19.11.2) 737 0 R (9.19.12.2) 782 0 R (9.19.13.2) 787 0 R (9.19.14.2) 795 0 R (9.19.15.2) 810 0 R (9.19.6.2) 683 0 R (9.19.7.2) 686 0 R (9.19.8.2) 692 0 R (9.19.9.2) 697 0 R (Doc-Start) 51 0 R (page.1) 139 0 R (page.10) 425 0 R (page.11) 458 0 R (page.12) 494 0 R (page.13) 515 0 R (page.14) 534 0 R (page.15) 562 0 R (page.16) 576 0 R (page.17) 628 0 R (page.18) 665 0 R (page.19) 672 0 R (page.2) 184 0 R (page.20) 723 0 R (page.21) 778 0 R (page.22) 803 0 R (page.3) 212 0 R (page.4) 243 0 R (page.5) 287 0 R (page.6) 304 0 R (page.7) 316 0 R (page.8) 359 0 R (page.9) 394 0 R (page.iii) 65 0 R] >> endobj 823 0 obj <>stream GPL Ghostscript 9.53.3 2022-11-26T15:02:48-06:00 2022-11-26T15:02:48-06:00 LaTeX with hyperref endstream endobj 2 0 obj <>endobj xref 0 824 0000000000 65535 f 0000074833 00000 n 0000179933 00000 n 0000074527 00000 n 0000070384 00000 n 0000168561 00000 n 0000075430 00000 n 0000074777 00000 n 0000075492 00000 n 0000075575 00000 n 0000075846 00000 n 0000075672 00000 n 0000075757 00000 n 0000076000 00000 n 0000076433 00000 n 0000076104 00000 n 0000076211 00000 n 0000076330 00000 n 0000076575 00000 n 0000078641 00000 n 0000076681 00000 n 0000076772 00000 n 0000076892 00000 n 0000077008 00000 n 0000077114 00000 n 0000077230 00000 n 0000077334 00000 n 0000077439 00000 n 0000078075 00000 n 0000077552 00000 n 0000077639 00000 n 0000077753 00000 n 0000077865 00000 n 0000077975 00000 n 0000078220 00000 n 0000078330 00000 n 0000078441 00000 n 0000078548 00000 n 0000078780 00000 n 0000168435 00000 n 0000079831 00000 n 0000078890 00000 n 0000078969 00000 n 0000079065 00000 n 0000079164 00000 n 0000079263 00000 n 0000079359 00000 n 0000079461 00000 n 0000079554 00000 n 0000079652 00000 n 0000079747 00000 n 0000079938 00000 n 0000080000 00000 n 0000000182 00000 n 0000000423 00000 n 0000080062 00000 n 0000128403 00000 n 0000131838 00000 n 0000080123 00000 n 0000070527 00000 n 0000080155 00000 n 0000000443 00000 n 0000000695 00000 n 0000080219 00000 n 0000070671 00000 n 0000080251 00000 n 0000000715 00000 n 0000003837 00000 n 0000080315 00000 n 0000080378 00000 n 0000131269 00000 n 0000163323 00000 n 0000080519 00000 n 0000080660 00000 n 0000130534 00000 n 0000153839 00000 n 0000080794 00000 n 0000080928 00000 n 0000081064 00000 n 0000081201 00000 n 0000081337 00000 n 0000081473 00000 n 0000081611 00000 n 0000081749 00000 n 0000081894 00000 n 0000082039 00000 n 0000082182 00000 n 0000082326 00000 n 0000082471 00000 n 0000082616 00000 n 0000082755 00000 n 0000082894 00000 n 0000083028 00000 n 0000083162 00000 n 0000083306 00000 n 0000083451 00000 n 0000083599 00000 n 0000083747 00000 n 0000083903 00000 n 0000084059 00000 n 0000084205 00000 n 0000084352 00000 n 0000084508 00000 n 0000084664 00000 n 0000084809 00000 n 0000084954 00000 n 0000085100 00000 n 0000085246 00000 n 0000085393 00000 n 0000085540 00000 n 0000085678 00000 n 0000085817 00000 n 0000085962 00000 n 0000086107 00000 n 0000086257 00000 n 0000086407 00000 n 0000086551 00000 n 0000086695 00000 n 0000086841 00000 n 0000086987 00000 n 0000087136 00000 n 0000087285 00000 n 0000087435 00000 n 0000087585 00000 n 0000087736 00000 n 0000087887 00000 n 0000088030 00000 n 0000088173 00000 n 0000088312 00000 n 0000088451 00000 n 0000088582 00000 n 0000088714 00000 n 0000088854 00000 n 0000088994 00000 n 0000089124 00000 n 0000130138 00000 n 0000148737 00000 n 0000089254 00000 n 0000071293 00000 n 0000089322 00000 n 0000089388 00000 n 0000003858 00000 n 0000008850 00000 n 0000089453 00000 n 0000089518 00000 n 0000089583 00000 n 0000089648 00000 n 0000089713 00000 n 0000089778 00000 n 0000089843 00000 n 0000089908 00000 n 0000089973 00000 n 0000090038 00000 n 0000090103 00000 n 0000090168 00000 n 0000090233 00000 n 0000090298 00000 n 0000090363 00000 n 0000090427 00000 n 0000090492 00000 n 0000090557 00000 n 0000090622 00000 n 0000090687 00000 n 0000090751 00000 n 0000090816 00000 n 0000090878 00000 n 0000090940 00000 n 0000091005 00000 n 0000091070 00000 n 0000091135 00000 n 0000091200 00000 n 0000091265 00000 n 0000091330 00000 n 0000091395 00000 n 0000091459 00000 n 0000091524 00000 n 0000091589 00000 n 0000091654 00000 n 0000091719 00000 n 0000091784 00000 n 0000091849 00000 n 0000091912 00000 n 0000091977 00000 n 0000071440 00000 n 0000092034 00000 n 0000008872 00000 n 0000013429 00000 n 0000092100 00000 n 0000092165 00000 n 0000092230 00000 n 0000092294 00000 n 0000092359 00000 n 0000092424 00000 n 0000092489 00000 n 0000092554 00000 n 0000092619 00000 n 0000092682 00000 n 0000092747 00000 n 0000092812 00000 n 0000092877 00000 n 0000092942 00000 n 0000093007 00000 n 0000093072 00000 n 0000093136 00000 n 0000093201 00000 n 0000093266 00000 n 0000093331 00000 n 0000093396 00000 n 0000093461 00000 n 0000093526 00000 n 0000093590 00000 n 0000071587 00000 n 0000093647 00000 n 0000093713 00000 n 0000013451 00000 n 0000016063 00000 n 0000093778 00000 n 0000093843 00000 n 0000093908 00000 n 0000093973 00000 n 0000094038 00000 n 0000094102 00000 n 0000129691 00000 n 0000143299 00000 n 0000094167 00000 n 0000094231 00000 n 0000094296 00000 n 0000094361 00000 n 0000094425 00000 n 0000094490 00000 n 0000094554 00000 n 0000094618 00000 n 0000094682 00000 n 0000094747 00000 n 0000094812 00000 n 0000094877 00000 n 0000094942 00000 n 0000095007 00000 n 0000095072 00000 n 0000095137 00000 n 0000095202 00000 n 0000095267 00000 n 0000071734 00000 n 0000095348 00000 n 0000095414 00000 n 0000016085 00000 n 0000018975 00000 n 0000095479 00000 n 0000095544 00000 n 0000095609 00000 n 0000095674 00000 n 0000095737 00000 n 0000095802 00000 n 0000095867 00000 n 0000095928 00000 n 0000095993 00000 n 0000096058 00000 n 0000096123 00000 n 0000096185 00000 n 0000096243 00000 n 0000096307 00000 n 0000096371 00000 n 0000096436 00000 n 0000096501 00000 n 0000129330 00000 n 0000140249 00000 n 0000096565 00000 n 0000096630 00000 n 0000096695 00000 n 0000096758 00000 n 0000096819 00000 n 0000096881 00000 n 0000096945 00000 n 0000097010 00000 n 0000097074 00000 n 0000097139 00000 n 0000097204 00000 n 0000097269 00000 n 0000097333 00000 n 0000097398 00000 n 0000097463 00000 n 0000097528 00000 n 0000097593 00000 n 0000097658 00000 n 0000097723 00000 n 0000097788 00000 n 0000071881 00000 n 0000097882 00000 n 0000018997 00000 n 0000019964 00000 n 0000097948 00000 n 0000098013 00000 n 0000098078 00000 n 0000098143 00000 n 0000098207 00000 n 0000098271 00000 n 0000098336 00000 n 0000098401 00000 n 0000098466 00000 n 0000098531 00000 n 0000098596 00000 n 0000098661 00000 n 0000098726 00000 n 0000072028 00000 n 0000098783 00000 n 0000098849 00000 n 0000019985 00000 n 0000021050 00000 n 0000098914 00000 n 0000098979 00000 n 0000099044 00000 n 0000099109 00000 n 0000099174 00000 n 0000099239 00000 n 0000099304 00000 n 0000072175 00000 n 0000099374 00000 n 0000099440 00000 n 0000021071 00000 n 0000025190 00000 n 0000099505 00000 n 0000099569 00000 n 0000099634 00000 n 0000099699 00000 n 0000099763 00000 n 0000099828 00000 n 0000099892 00000 n 0000099957 00000 n 0000100022 00000 n 0000100086 00000 n 0000100151 00000 n 0000100216 00000 n 0000100281 00000 n 0000100346 00000 n 0000100410 00000 n 0000100475 00000 n 0000100540 00000 n 0000100605 00000 n 0000100670 00000 n 0000100734 00000 n 0000100799 00000 n 0000100863 00000 n 0000100928 00000 n 0000100993 00000 n 0000101058 00000 n 0000101123 00000 n 0000101188 00000 n 0000101253 00000 n 0000128997 00000 n 0000136712 00000 n 0000101318 00000 n 0000101383 00000 n 0000101448 00000 n 0000101513 00000 n 0000101578 00000 n 0000101643 00000 n 0000101708 00000 n 0000101773 00000 n 0000072322 00000 n 0000101856 00000 n 0000025212 00000 n 0000029332 00000 n 0000101922 00000 n 0000101987 00000 n 0000102052 00000 n 0000102117 00000 n 0000102181 00000 n 0000102246 00000 n 0000102311 00000 n 0000102376 00000 n 0000102441 00000 n 0000102506 00000 n 0000102571 00000 n 0000102636 00000 n 0000102701 00000 n 0000102766 00000 n 0000102831 00000 n 0000102895 00000 n 0000102959 00000 n 0000103024 00000 n 0000103089 00000 n 0000103154 00000 n 0000103219 00000 n 0000103284 00000 n 0000103349 00000 n 0000103414 00000 n 0000103479 00000 n 0000103544 00000 n 0000103609 00000 n 0000103674 00000 n 0000103739 00000 n 0000103804 00000 n 0000103869 00000 n 0000072469 00000 n 0000103952 00000 n 0000029354 00000 n 0000032455 00000 n 0000104018 00000 n 0000104083 00000 n 0000104148 00000 n 0000104213 00000 n 0000104278 00000 n 0000104343 00000 n 0000104408 00000 n 0000104473 00000 n 0000104535 00000 n 0000104599 00000 n 0000104664 00000 n 0000104729 00000 n 0000104794 00000 n 0000104859 00000 n 0000104924 00000 n 0000104989 00000 n 0000105054 00000 n 0000105118 00000 n 0000105183 00000 n 0000105248 00000 n 0000105313 00000 n 0000105378 00000 n 0000105442 00000 n 0000105507 00000 n 0000105571 00000 n 0000105636 00000 n 0000105701 00000 n 0000072616 00000 n 0000105758 00000 n 0000105824 00000 n 0000032477 00000 n 0000036760 00000 n 0000105889 00000 n 0000105954 00000 n 0000106019 00000 n 0000106084 00000 n 0000106149 00000 n 0000106214 00000 n 0000106279 00000 n 0000106344 00000 n 0000106409 00000 n 0000106471 00000 n 0000106536 00000 n 0000106601 00000 n 0000106666 00000 n 0000106731 00000 n 0000106796 00000 n 0000106861 00000 n 0000106926 00000 n 0000106991 00000 n 0000107056 00000 n 0000107120 00000 n 0000107185 00000 n 0000107250 00000 n 0000107315 00000 n 0000107380 00000 n 0000107445 00000 n 0000107510 00000 n 0000107575 00000 n 0000107640 00000 n 0000072763 00000 n 0000107697 00000 n 0000107763 00000 n 0000036782 00000 n 0000040582 00000 n 0000107828 00000 n 0000107893 00000 n 0000107958 00000 n 0000108022 00000 n 0000108087 00000 n 0000108152 00000 n 0000108217 00000 n 0000108282 00000 n 0000108347 00000 n 0000108411 00000 n 0000108476 00000 n 0000108541 00000 n 0000108606 00000 n 0000108671 00000 n 0000108736 00000 n 0000108801 00000 n 0000108866 00000 n 0000108931 00000 n 0000108996 00000 n 0000109061 00000 n 0000109125 00000 n 0000109190 00000 n 0000109255 00000 n 0000109320 00000 n 0000109385 00000 n 0000109450 00000 n 0000109512 00000 n 0000109577 00000 n 0000109639 00000 n 0000109703 00000 n 0000109768 00000 n 0000072910 00000 n 0000109825 00000 n 0000040604 00000 n 0000045360 00000 n 0000109891 00000 n 0000109956 00000 n 0000110021 00000 n 0000110086 00000 n 0000110151 00000 n 0000110216 00000 n 0000110281 00000 n 0000110346 00000 n 0000110411 00000 n 0000110476 00000 n 0000110541 00000 n 0000110606 00000 n 0000110671 00000 n 0000110736 00000 n 0000110801 00000 n 0000110866 00000 n 0000110931 00000 n 0000073057 00000 n 0000111001 00000 n 0000045382 00000 n 0000047639 00000 n 0000111067 00000 n 0000111132 00000 n 0000111192 00000 n 0000111257 00000 n 0000111322 00000 n 0000111387 00000 n 0000111452 00000 n 0000111517 00000 n 0000111582 00000 n 0000111647 00000 n 0000111712 00000 n 0000111777 00000 n 0000111841 00000 n 0000111906 00000 n 0000111969 00000 n 0000073204 00000 n 0000112039 00000 n 0000047661 00000 n 0000051922 00000 n 0000112105 00000 n 0000112170 00000 n 0000112235 00000 n 0000112300 00000 n 0000112365 00000 n 0000112430 00000 n 0000112495 00000 n 0000112560 00000 n 0000112625 00000 n 0000112690 00000 n 0000112755 00000 n 0000112820 00000 n 0000112885 00000 n 0000112950 00000 n 0000113015 00000 n 0000113080 00000 n 0000113145 00000 n 0000113210 00000 n 0000113275 00000 n 0000113339 00000 n 0000113404 00000 n 0000113469 00000 n 0000113534 00000 n 0000113599 00000 n 0000073351 00000 n 0000113669 00000 n 0000051944 00000 n 0000054212 00000 n 0000113735 00000 n 0000113800 00000 n 0000113865 00000 n 0000113930 00000 n 0000113992 00000 n 0000114057 00000 n 0000114122 00000 n 0000114187 00000 n 0000114252 00000 n 0000114317 00000 n 0000073498 00000 n 0000114374 00000 n 0000114440 00000 n 0000054234 00000 n 0000056513 00000 n 0000114505 00000 n 0000114570 00000 n 0000114635 00000 n 0000114699 00000 n 0000114764 00000 n 0000114829 00000 n 0000114894 00000 n 0000114959 00000 n 0000115024 00000 n 0000115089 00000 n 0000115154 00000 n 0000115218 00000 n 0000115283 00000 n 0000115347 00000 n 0000115412 00000 n 0000115477 00000 n 0000115542 00000 n 0000115607 00000 n 0000115672 00000 n 0000115737 00000 n 0000115802 00000 n 0000115867 00000 n 0000115931 00000 n 0000115996 00000 n 0000116061 00000 n 0000116126 00000 n 0000116190 00000 n 0000116255 00000 n 0000116319 00000 n 0000116384 00000 n 0000116449 00000 n 0000116514 00000 n 0000116579 00000 n 0000116644 00000 n 0000116709 00000 n 0000116774 00000 n 0000116839 00000 n 0000116904 00000 n 0000116969 00000 n 0000117034 00000 n 0000117099 00000 n 0000117164 00000 n 0000117229 00000 n 0000117294 00000 n 0000117359 00000 n 0000117424 00000 n 0000117489 00000 n 0000073645 00000 n 0000117559 00000 n 0000056535 00000 n 0000057974 00000 n 0000117625 00000 n 0000117690 00000 n 0000117755 00000 n 0000117819 00000 n 0000117883 00000 n 0000117948 00000 n 0000118013 00000 n 0000118078 00000 n 0000118141 00000 n 0000118206 00000 n 0000118270 00000 n 0000118335 00000 n 0000118399 00000 n 0000118464 00000 n 0000118526 00000 n 0000118591 00000 n 0000118656 00000 n 0000118721 00000 n 0000118786 00000 n 0000118851 00000 n 0000118916 00000 n 0000118981 00000 n 0000119046 00000 n 0000119110 00000 n 0000119175 00000 n 0000119239 00000 n 0000119304 00000 n 0000119368 00000 n 0000119433 00000 n 0000119497 00000 n 0000119562 00000 n 0000119627 00000 n 0000119692 00000 n 0000073792 00000 n 0000119738 00000 n 0000119804 00000 n 0000057996 00000 n 0000058260 00000 n 0000119869 00000 n 0000119934 00000 n 0000073939 00000 n 0000119967 00000 n 0000120033 00000 n 0000058281 00000 n 0000061949 00000 n 0000120098 00000 n 0000120163 00000 n 0000120228 00000 n 0000120293 00000 n 0000120358 00000 n 0000120422 00000 n 0000120487 00000 n 0000120552 00000 n 0000120614 00000 n 0000120679 00000 n 0000120743 00000 n 0000120808 00000 n 0000120870 00000 n 0000120935 00000 n 0000120996 00000 n 0000121061 00000 n 0000121126 00000 n 0000121191 00000 n 0000121256 00000 n 0000121321 00000 n 0000121386 00000 n 0000121451 00000 n 0000121515 00000 n 0000121580 00000 n 0000121645 00000 n 0000121710 00000 n 0000121775 00000 n 0000121840 00000 n 0000121904 00000 n 0000121969 00000 n 0000122034 00000 n 0000122099 00000 n 0000122164 00000 n 0000122229 00000 n 0000122294 00000 n 0000122359 00000 n 0000122424 00000 n 0000122489 00000 n 0000122554 00000 n 0000122619 00000 n 0000122684 00000 n 0000122749 00000 n 0000122814 00000 n 0000122879 00000 n 0000122944 00000 n 0000123009 00000 n 0000074086 00000 n 0000123103 00000 n 0000123169 00000 n 0000061971 00000 n 0000066038 00000 n 0000123234 00000 n 0000123299 00000 n 0000123361 00000 n 0000123426 00000 n 0000123491 00000 n 0000123556 00000 n 0000123621 00000 n 0000123686 00000 n 0000123751 00000 n 0000123816 00000 n 0000123881 00000 n 0000123943 00000 n 0000124008 00000 n 0000124073 00000 n 0000124135 00000 n 0000124200 00000 n 0000124265 00000 n 0000124330 00000 n 0000124395 00000 n 0000124460 00000 n 0000124525 00000 n 0000124590 00000 n 0000124655 00000 n 0000124717 00000 n 0000124782 00000 n 0000124846 00000 n 0000124911 00000 n 0000124976 00000 n 0000125041 00000 n 0000125106 00000 n 0000125171 00000 n 0000125236 00000 n 0000125301 00000 n 0000125366 00000 n 0000125431 00000 n 0000125493 00000 n 0000125558 00000 n 0000125623 00000 n 0000125688 00000 n 0000125753 00000 n 0000125818 00000 n 0000125883 00000 n 0000125948 00000 n 0000126013 00000 n 0000126075 00000 n 0000126140 00000 n 0000126205 00000 n 0000126270 00000 n 0000126335 00000 n 0000126400 00000 n 0000074233 00000 n 0000126470 00000 n 0000126536 00000 n 0000066060 00000 n 0000069603 00000 n 0000126601 00000 n 0000126664 00000 n 0000126726 00000 n 0000126791 00000 n 0000126856 00000 n 0000126917 00000 n 0000126982 00000 n 0000127047 00000 n 0000127112 00000 n 0000127177 00000 n 0000127242 00000 n 0000127307 00000 n 0000127371 00000 n 0000127436 00000 n 0000127499 00000 n 0000127562 00000 n 0000127625 00000 n 0000127690 00000 n 0000127755 00000 n 0000127820 00000 n 0000074380 00000 n 0000127890 00000 n 0000069625 00000 n 0000070363 00000 n 0000127956 00000 n 0000128021 00000 n 0000128086 00000 n 0000128151 00000 n 0000128216 00000 n 0000128281 00000 n 0000128346 00000 n 0000132230 00000 n 0000137037 00000 n 0000140568 00000 n 0000143748 00000 n 0000149090 00000 n 0000154443 00000 n 0000163694 00000 n 0000128913 00000 n 0000131168 00000 n 0000131754 00000 n 0000178468 00000 n trailer << /Size 824 /Root 1 0 R /Info 2 0 R /ID [<00C6BD2F38DD206193957592C0F36E10><00C6BD2F38DD206193957592C0F36E10>] >> startxref 180130 %%EOF pygopherd-3.0.1/doc/pygopherd.ps000066400000000000000000016004011456676541200166500ustar00rootroot00000000000000%!PS-Adobe-2.0 %%Creator: dvips(k) 2020.1 Copyright 2020 Radical Eye Software %%Title: book.dvi %%CreationDate: Sat Nov 26 21:02:48 2022 %%Pages: 25 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: NimbusSanL-Bold NimbusRomNo9L-Medi NimbusRomNo9L-Regu %%+ NimbusRomNo9L-ReguItal NimbusMonL-Regu NimbusMonL-Bold %%+ NimbusMonL-ReguObli %%DocumentPaperSizes: Letter %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -R -q -t letter book.dvi -o book.ps %DVIPSParameters: dpi=600 %DVIPSSource: TeX output 2022.11.26:1502 %%BeginProcSet: tex.pro 0 0 %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S /BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3 def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse} forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{ BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat {BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B /M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M} B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{ 0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc 0 0 % File 8r.enc TeX Base 1 Encoding Revision 2.0 2002-10-30 % % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, % W. Schmidt, P. Lehman", % version = "2.0", % date = "27nov06", % filename = "8r.enc", % email = "tex-fonts@@tug.org", % docstring = "This is the encoding vector for Type1 and TrueType % fonts to be used with TeX. This file is part of the % PSNFSS bundle, version 9" % @} % % The idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard encoding, ISO Latin 1, Windows ANSI including the euro symbol, % MacRoman, and some extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % These are /dotlessj /ff /ffi /ffl. % % (4) hyphen appears twice for compatibility with both ASCII and Windows. % % (5) /Euro was assigned to 128, as in Windows ANSI % % (6) Missing characters from MacRoman encoding incorporated as follows: % % PostScript MacRoman TeXBase1 % -------------- -------------- -------------- % /notequal 173 0x16 % /infinity 176 0x17 % /lessequal 178 0x18 % /greaterequal 179 0x19 % /partialdiff 182 0x1A % /summation 183 0x1B % /product 184 0x1C % /pi 185 0x1D % /integral 186 0x81 % /Omega 189 0x8D % /radical 195 0x8E % /approxequal 197 0x8F % /Delta 198 0x9D % /lozenge 215 0x9E % /TeXBase1Encoding [ % 0x00 /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef /Zcaron /zcaron % 0x10 /caron /dotlessi /dotlessj /ff /ffi /ffl /notequal /infinity /lessequal /greaterequal /partialdiff /summation /product /pi /grave /quotesingle % 0x20 /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % 0x80 /Euro /integral /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /Omega /radical /approxequal % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /Delta /lozenge /Ydieresis % 0xA0 /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron % 0xB0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro 0 0 %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type /nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro 0 0 %! TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N /vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N /rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N /@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ /hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B /@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ /urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known {userdict/md get type/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale }if 0 setgray}N/@beginspecial{SDict begin/SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup} ifelse scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if/showpage{}N /erasepage{}N/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{ count ocount sub{pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N /@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X /yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet %%BeginProcSet: color.pro 0 0 %! TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll }repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def /TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ /currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC /Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC /Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC /Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ 0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ 0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC /Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC /Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ 0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ 0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC /BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC /CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC /Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC /PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ 0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end %%EndProcSet TeXDict begin @defspecial systemdict /pdfmark known{userdict /?pdfmark systemdict /exec get put}{userdict /?pdfmark systemdict /pop get put userdict /pdfmark systemdict /cleartomark get put}ifelse /DvipsToPDF{72.27 mul Resolution div} def/PDFToDvips{72.27 div Resolution mul} def/BPToDvips{72 div Resolution mul}def product (Ghostscript) search {pop pop pop revision 927 gt}{pop false} ifelse{/BorderArrayPatch{} def}{/BorderArrayPatch{[exch{dup dup type/integertype eq exch type/realtype eq or{BPToDvips}if}forall]}def} ifelse /HyperBorder {1 PDFToDvips} def/H.V {pdf@hoff pdf@voff null} def/H.B {/Rect[pdf@llx pdf@lly pdf@urx pdf@ury]} def/H.S {currentpoint HyperBorder add /pdf@lly exch def dup DvipsToPDF 72 add /pdf@hoff exch def HyperBorder sub /pdf@llx exch def} def/H.L {2 sub dup/HyperBasePt exch def PDFToDvips /HyperBaseDvips exch def currentpoint HyperBaseDvips sub /pdf@ury exch def/pdf@urx exch def} def/H.A {H.L currentpoint exch pop vsize 72 sub exch DvipsToPDF HyperBasePt sub sub /pdf@voff exch def} def/H.R {currentpoint HyperBorder sub /pdf@ury exch def HyperBorder add /pdf@urx exch def currentpoint exch pop vsize 72 sub exch DvipsToPDF sub /pdf@voff exch def} def @fedspecial end %%BeginFont: NimbusMonL-Regu %!PS-AdobeFont-1.0: NimbusMonL-Regu 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Mono L Regular) readonly def /FamilyName (Nimbus Mono L) readonly def /Weight (Regular) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusMonL-Regu def /PaintType 0 def /WMode 0 def /FontBBox {-12 -237 650 811} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B89290699B50C1BF1BAEFFE 1F57BE7B5EA025241A248A6D4CFA5067A1DA6EBA4CFC940599BA3F3C934D7248 B8E4AC5816F0D2CE8B3C4193CE39D19FFFDB75254573173CB51CCD83C2F2D06B 2483CF9B07B21EC6F502F028C273887BB06DAE2AFAC10E9FD3C7CF51BCA7B277 B706E425302DC78975AC0E43B87073257A5CD7424B6865FCA89D886E8F95C4F6 D457623DBBC0D16BAFEB4C649F5D72B09B18502EEAB687E915E9B536A361B4F1 44C3CD4CC683B5F05A4ECB4823A5EB5179BB7EEE8B76C21B2491A97808F6318B 585B0BAD98F42FB4A755BCB74CD354F794C8BEA5B90FB9681BD5849D45247E39 930C882490230E1662D39CCA875BFFEAC3E79A78DE6E1298ABE9817AE98675C4 16220AD0D3A36580EE2F2A17AAA1246C416D58A4C52FBB26AAF3B6F75833AF8E 3AA996218DAFA571FBC7CAD90ECE9C883C813D8F168C5E86BBFA0F0A5CB36E35 2DE4CAA0F8D3227F72C5056BFB5BCA6BF9C60E037A0E44670A8D3CBC9A19F379 CA8DB30B711F518A8C7569211AC70C46EED2AF62A37F238BD0BD12D60332E673 C6E784B3EBA3F2E71E9993B97E8A38F85048937E958F1CD8FC6E661048546135 56B810FA1FF611B96495081C04542DF7FEF085DEC619DC8C84CC57683D212813 9D14728AA32723E1D15F2AF8F03422CFAFDA40AD7B3E210B6381F66B94E11294 C2F1B93134816B1E636AA6B9622E4CCE6CF2AFC17C9B0307562905FC6C24D60B 21819E209EFB56C1D3F76DDCA2C605FE1895D30F6D027E15D5EB486CD83DB85E B304CE5F3E5A4AE2D89D3D075A1CF750ACCD72489207B74CC4C42DDC9F77A4F5 62BAE67A549B42F8CA5FD54390651864399E2644A5C4611CD948F30F54D3578D 30FB21EB332B42303407ED04A2DBF7939A6DAD24B421704E199451558DFB9773 E32A54B0E4E823849A8E64E46E5505F7E9F8B8C28B59EFFF0F66A68804C48F78 15F13C9EC80BE488D9E56F8A5548A700906BB11B07EB2F973F781295D3CCBEAE 4738CBFF3A3A64098F6535171BBD9C49089848B600B3975941C73FEFA3D9E13F D38FAE1FD869366B61D37AD7EE82D83626E0D8D0C105CB6FC5F610237BB3C6E2 42E5E50529E1F15174DF4AE9067EC4E67725672D6540C890618A9B5B66A7E7AF 6435290BB20178DA4F052590B8245254972A9E4781FCBAA506BD9D7CE361FA6A 5239CDFD85C441C0D7A174C40F2366A89977662F591E190166720490A124A76A 808841FE81D39359DFA90C2D7D25073BF52A79FE5CFEBD81172C3E68D48786D4 A2227B717D3E2A53E09A4EFE530A666EE9AE06FA11C842F9C4C039F8EA5B13A3 A9554E4F789CFE3F1DDC0C2D9D95F7E82180B767328BFC532CCF26068A7D34B0 40A99FBA99942BD86CE4B46FF5C69BABCA7A30E44365D3319C2134B46322F7EB 16708D2BE2CA0038E7290B89B4B8E897B8A153D3E586060B914B6395A9702402 7E6C43C2C194C9E4428FA690CDA94A29FD6343D8C28B243B40EF4F3BF7A94E61 085ED3B40BF8F7774D9D4BDBBC9C444F4504E9183A562D7A8C97E9BD2D935B87 67084537266E296CFF2AB83B18A6B7CECE224EAE232E47B389BD3D96E005EC3A 6CA5FA4C73237D47218805D8BE2EBA9EB95AA7F1A51A31503098828EFA74A81F 09F0C1348220813CCE9C986B51BBB0B9AE3FFDEBF429BC031A2C13F9378B2845 75E450B7F57CAEDEF605478BE7072158B4B2D351B12EF08399B1453DFBEF7F6D A3D81E94B79A2965D63753EA5B10491A203C9E372A5B98281323C7EB5A6A1BB8 4E58E792C362F03A9E7EF0C7F3D7E4BD97877E18A14D48B578ADC22A95ACC3B1 F0D7F17F9CB1AECA3ADEEE18BF378D181BBC260387B025179C6C7BCBBB8D9714 249A9A7C328D7C2962591F159EB60B490854F94FB62D0B2C30C2F83D4231765C E08C1F7C77D61A9DE10664F4BF13E2B8059467F3B6901294A6FA251F64B7353A 6EBFF04C43B13F73298B289C42A534F596509833B6D91A262BCB22913D2392F9 01807F804BB694A22ABE3FBC8272FF827EF33073413EC6C03F4A6F2F81492C38 CA09D407156E04E062D47506D2F6B527531444A6E1907062FB3BA362B2DFA2DF 8C9DEBF7C3147C1214225DAFE89F45C149DF8D5CB26E31B026664AA72348AA66 104BF95D0638B91D04567D107EEF4F75A3E1061D3D59CD72B3EAC1C73CE1EBDC 48B12001ADEA2D8DC1B003BB9C4928AEA96A82AE79CF7351B900701D49E5A394 5D14DED9EEE37DE8E494FFE5027AEF12607BDD139BCD1518E887457710049027 3FFDA792F9F51AFC6FE1597DE17FAEA07DB10BC5CFC2D589E81C694786D78220 18AF93CD0EA3AB64C4135DED86556BC4CF7C8A50843AC232C34E63A64949A7BD 674FD3C767C7530A1BE5182B4F953405D4C8D558571E3549E37C3C551DA08889 24FC8A29DED3ED07778DE2F6295803945F286AEEB2E9AB5552EBD0DC775D67E9 147BF83ABDE553CEFBDDFAAFEAE4B255C836DE4A3A83FC97B62C9CCD8C80913B 2FB57E330F5B8766034A9C158C703702D7D06B9B67C32A231E90C4F19A0999B9 4057D963E344878221BC52368F640CDB75CF9291DB3E354B958CE0944CCEC434 910D8AEAA2E7FC92041DB492A77FD9ED9FC0909B8FA6D02491C9025C6970AD8F 5E73BEF356C215C83B1D3AEBBFE34344FFFB62B986F18C4C37A0FF355E452FEE 0DA0C9D8FD5058AC4D24808941E5C6CB0504D9C77E08FCF101D33E908A71B94B 57A71E9FEC5E5FCA9C45F47ACBA52FAC5337E9C92A7C28E1AA2CFB4E46B9A908 E48303B890ADF0EA86B45CC9E0049D0EA6D735BFEE82799CF60EF343DFBC20CC 7E88A660686049CEC77DFE6ED773A57576C8B912E58ADBB12D16D133E6F42EA9 0B25C15A5557D54CB4FBAF183B36B728DAD44287FAC7D8E6484BCC46FE2E737B 8BE26D6FA458BF4DFC3167AE905BAD900F413C028BB971C0E1B61A0C3AD8F9FA E74BC7836855F555961A47656DC98CB112889DD3B16E3C2BF4191D7947DD3A94 6371622A202A3062F218582C59B4973E4E9FB1DCAC381113CCEB7B316717EE85 9D7C2DA83F003A14195494058453ACC41C860B70833B924B9FA84E05FE0971E7 67A2F4E2A12748D4647CB8A689FF7104DEEC4C3583CB47508D578234BDC46124 0CD8BEBEBA301024523234ABA47A23BB37928AA3EAAADC208C16AC72DC8E78DB 3870DCB830D8898F8DB8518A5662ABD55D01A27FEDE4BC698150C0B32AB7C5E0 3F7D58A6DB69A129A128F70463E839A0815C1743D851AD75573E2DFD9AA8BB6F 7C00A0408DA6407DE184925A554473A53BF48C6C2A7307698A855B9B3D4F8C62 05B891B45CE8CA0C36C164A03C4F2F94069E17417F403ADD5B2C9DEE3518898E FD2472B10CEB411895BA5BB9B2C0FB7DE85515E29848E2322EFC48770E5301DE 62C46683A81AE2BA833E7D89491BEF6A21D559394110030E18F7DDF279CBD799 9449BDD74166B19F73946720663BE2274161BB8BBA7FB6CF55796CFFF55D0CD7 49CF2A2FBC012BE5E4044BBA0F729D7A4C251FC7EAF498657E2B7436368B0530 DA38723108E848B5EF659F1892A83B949B4C6A6B20C9C7CFA26912EA2C1B0D9C 8DE2665AB55F545C4BB445FEFEBB1E3DE80DE376F18BA2748D470CBD3FD6102F F8B3523F405EFD299495653DB168A306F9C3CF605397060D4F6FDBC9700E8E46 583A8A921655DFB2051F5BC69A9FD9E59F238FF926E0909E7D76DD639811B7A3 E290E5C016B7755DECE70897ACD4E10F0B4C53F4D609CF9861CFE882880FCCD5 ABBDBFAF417BF055D8E9F87AE4AE393E682EA6EFBCDF807E4F6F7C37CA9F85C7 608848E88CF4134AAAD0FC647837B33B9B6145012A52B6CFFA302632B11CA88C 8BB032EE8131C8292AB3B5C40381C6EE18A70AEFFCB3DC8DE39690B59B9ECAD8 F848007099ADD8776C15B57643B5BAB4968CB4D1D07C190A30D72F4DC185613B 31DF5DDE27133C804504450958CBC3FD7EF6D0B586320E85CF476D0A63B39759 687455A5C06FA9FE14859EBC3FFD5B41822E02AD18A3AAEE6A9DCBF62276D697 116E1C3FDB669E2104FF418653FEF4115DF9457824EDF1A950E0B29189A81A8E 0B52DB40D39281A1EED44E947ABF5F5A9FFE35571D9C8D3FE93BF58203A2D3CB 658837E3E18A151A84769B1E1C7EC6A728DB432612800302C43AD7389ABE6AB6 0356E4F0C52B06785600D9FF31D2810C18F80CC5CD2EBE89FC02E869EF63AA91 AA60CE1A23079F7FE475A6A860D2CC6F72F941660A1794768ADE83338DEC2A61 92FB1F74A9DC1E4C22F4F04A76C01EA3E8617146EA11B3080E5FC9D94538770D 04006EBAC96D34E80777D5C8B58FE69FA54D5CD3E74A18503A25AB0B511DCFE9 B7253F0B921E415C963AAFB5F145D01D566943FF87EAF14699937EC5E60FFB3A 13AC9FCE3CC664E461FA45EF0CCFC2AEA3B4E47F70BA2D5AEE9FFAE55F364BD9 A0170CC19568A0E08CE6352CB79629CB55B4E04FA3DA82088F2191103AD4C2D4 7E952C56DBC242A084B4B9AB0A69C94BB35D55EEFC72CB446B6A381995EA7C74 A64966DD2F49858BC351519FC213A14759ED8EACB1D8A253BDAC2DA7BBE8EC82 7B9FA2A1C49A324BDC963EB1AFD6F14F0C146E0F13B03E76B3898E1F257E6989 B76A91534C2564B0516C18C9EB0B1AFBF9584C45FFAF36266EDDB105E9352268 F38C2598C907266B07C910A9CAFB467B0187BE466247945EF7C98A2EFCA1A117 13BDAEE75AEE43858B1B32E65C3B1B7137A124D6368499B19687E5008A50CB35 3E981166F8F5DA8E0BB61C839ABCCCF7FBA48B668D770904DC05F805DDD68FAF F1AF62A48BE2A105D9CD456EF3CCE1D38B515EC309F87C520180CB4672BB42EB EA62ADD591C2D666E59704020724D70180C0F8ABAFF127C0314C0B8F354E0760 F77DB2AD36AFD1DDDC956F5BA637037E351F0021A70AAEA686F10EA058232502 31B68004CE6510FC26DD7CAD026EE5CCEE1BC4101B22B0A78E168671559AFB1E F56095B7F43D0891601D7D6A73B3B452D342855F726C0CD8F599CE250D3D0703 5943FB6D98F640DE24BA3C6FFBB79AB8B63A98817292BC9145A0C22C1C1B6C43 EDDB37864049CBAB6CF4D29FFADA86B2C55B5FB14C7F4FB795EC4D0857AA5D66 20C95021DF41F048BD83227FB5AC66CDC561DBB0BB5600EA629EE2DDADB96778 0F749B4F38ACDF82AA399585EDFCD485CF5FC0149B514B077E49CE66A190B6B9 0B72719B354523B22BDB9302337CD98D1F23ECC02D3B718F41E7158B5A92D990 338D4C681FB09230305F7B0D57E5EE905C449BBA27465BCD7F113C9C1B931168 DE5DECF919FB1F8FE0F68B5D42751BD72D5E24F5809F58BF1F5FA211C77BDED2 B8F8AF3E78EFEBAFDC88074933F8A9B12A72EA85547426FB8DCA85CED8C179E8 DA15A0868FBAE1D9711F4E4088D6466B65753C25713CF4D68371C577BC8C1DED C1B91AE582EFF2AD2B9B2D6D0977E239A5974177626618AA5E29B8E8EC7CEA91 51BB35889978622CDD235325B07090D8770796F7E1B4665F9A69CA824B117CD9 9334626049A9AD892D4D317647862452E29ED51D2A2202D730FD20B2707BEE78 91A0F5ECF322A641F48C23BED908642E064EAF9ACF91A25FF02E328B3D78A8DE B2C230B9405D75FC53A982A7A78D7EB24C3AB77F1708B05E8F31B235ACCD286D 62E43A210FA5A3DB23CE4C1EF173BA2523CF8124C7839258EAF3D5B22266B8F3 D4FD6E33403985137CDEBB743252CCCC0E72B807FAD0073E622800B77394D23A C3DC6BD6762DCC3E9640F457954587BD5C9174B75942BE95B0F219563A6CE00E 7B383B9083A9D6AD475211DA39F2E97C0A4332541A96105BE1A2257B4D7C74F6 EBE32208A0F2639157F082AE2BDE83E736F2993D8C048393BD80BD24E1B77757 E92EA2F51BF07A285E26A452F417D27E5A7824D1893DF52D57BD6C1A1B711B1E B110A9E597550898981D09EEC541D4EDCABA25574158A5588CD8075647C14174 088120ADBB3234D1915DD98821EC3E23B9A2E6C8D1BF759930EA2C1B375042A5 69A11ED316CF1AC2A9216443B54D852799049730D9ACA237F708485F21DC12BA 218786577EBF18B5568AA9C68C085E87C356004C5E73D502DF5E8D4A2CF57CA2 0A2F4A4332E049362522AFEFE9E2DCF6FF7B8407FA034BF232367A8F87F0D220 FA0D04865F46867B5F5C76A505947C9C13DC333C303DE1766813DD06EE617B79 3DFA31906281EB16824799F27072EE709C447076C627A0468BF1D5E5C5CBF39A 4A9368AB9156F50DF5D18AB9CB355D532DADD1F5F5B6639DE2A67C5E621A22CE 51BFB2182F91382A83DC20215D1BA03B796A0A76858D65B37ACD6745664AA06C 3F9047FBBF7959F507F74E231EFCBDD4AFB595E8C3F0E8CAE46EB09C72D1482B E6F8EDE15B5BA0C07B0DEA1E9A73B8B5DEA4C6E230CC48F8B90151A0FFFF4C92 DD2C3848D655AAE8E0FD165B63823475E51EEAC17A8A7ACA8DF970F512E723C1 FA2A33FF0F3584D3F7B9B1F76FB6B37AA93FF7087810892ECFFD88E7C70943E7 94F20BE00667FF0501A72939BEC63A589E396A985E88B9A6DDA668C586795965 DDCB43F23B5BE8837EA00B30C0BC7FF11AE673803E8E6874DA391270D637D76C 3E3EF666F43AC62F2AB8F810EB45B1BECAA904DB2D800A71ECAF48A292015938 C80CBC84FAC0EDDC71FA7E47C27ADF5D22A29EC37851E81414B37E92B6FB4771 75D39632511F622B812C79685B50CC82EC5429D0B85AE0768375E5AEE848E611 2C26849E3AA9935F77AB14169547EE2CDA7B0AA835652BBC7781181EAD3F0210 13615F7AABAEA8AA9C694FB5C7083A8BF1BD462D923F06F6115F7A69C34E1BCF 5B686990BA88D7629C532B938F70FCE180655F7D3E9366D8F4E81C0FAA358EF3 7818BD6ABC6C89E4DE740B9CBBBDA90BF104F28060AD6DC3CB7993387458275B 32E8F813D27D6CFC29E0A741BEE6076BD4A0EE99F207DF6DE1EB4FCDBF512FEB F5F75E15DE0D430CDE476DAD69B99AB5CAA58D28B409CF6594DE83253092A879 7D47AC5FA508AB44D5C268C0054F02FC735FB1196C1091B7A2E9FEA46483AB34 BE8D382E8CE5E639B50D8F4EEC242E1F04204D895014DD676B0A17EACCECA256 F6E83DDB2534F3F4FE164145DB59021EB5125A9D357C79A3DA3854AD3E061E3D A7AE134145C93F11917101C8C58FF467A3D2D0058E0576018C746B29CD3D2FE8 6C72A3EF8A138E86C489B4CB96FCAB89421C5F6DAC3CB08CCBCC4A4279907FC4 DA060462A206EC4F8D684C14DF0C1FC3D95FDC96858343228E63F7AA98AA8A48 DFC202EE0846D8CACA5F0DCD4EDFBA0D785D8C70DDE2672DE82B9F3BEA0EE8B6 53A1719825D5A3B40DACFBED48C8A398B35BFB5F541EEA1A556FB3BBA754CD77 5D439D8A07384243DE36FE9034E573034979363E19A43962570D5254727BCF7B 02A08A0BDE73DFB8C1895E7AABA5660096EAB8417CE8898A19A9E80184CDEA6D 5B8FF5A0735192B97A90BC21265C047DCB885D6B4F591F29BB999ADFEEE148AC C764FF2BE0068E9BEA3D405B8225EA2DB73C206CECA6179DC38EB6D65A0247BC 15BD925E3D731F5728B297CF64EF228C627D0BAB8ABAF7EBE8C1A19551B8AE42 CC7A33B4E0D9F55C04F22C631D4ADEF22256F53D5E305BFFBA43632B1488ED86 79B6B183B36139C9EFAA1DA71D750C12AB6BF04D14AE7011BD488B425F36FCCB 5D76A7D4F9DA10C46B2399943E3FD64FB5BC1BBD0E9B8E88EEA0CA70F49B2106 F7BA7B77948AC0E4A900EE153204C3EA77541646B4524C99C59DA6483A5FD23A 432721E9CE1B8631455C38E4FF83FADBF89E5CDC6835D1058AD7A49C0618EBB3 EB268CEA6C518472EFADE1DC86A2E39185AC4ACB590448108727FD7C001FC637 8865A82A1D003242430EB6FF1DBE8C3D96F2BAFCE5AC26464364F6E7523E6288 AD18BEAEE2454670C0F8902725F6D3B703CCF8812EE1C199ED76A7C8F911AEDE 793A43AC83F7B9A64CA3FD370327D9E02ED93D0A3C04AA6C0F58F90C7382C8BF A25B8AC3E554F89727898A2CF5040875B9609ABE6ADB722F7F53410AFC866167 E963EC7A45C23AB89207E0AF13E677A40349484A9ACF377269E3F7992244C44E BB31FED363FD6AD843BABAAA9A5D1A3F2EFDFB35B7B10584D6A03D959C0E2669 CCE08C11595CF8B589A69FF46242277FFDD25F5477D0C820F110E170E86F742C 3B5D9451D520D303E11235AACE241260C19B8F62344E371AF8C49D3C7D2C85C2 4F3941A673793E8920362CC02A3C065BE73F13AF1481A2A856D76B3DA2DC72C4 124EC0212C697D91FA63D665D140CE81D61227838F07649456956B785277917D 878B9D7C8DFF1A287DA34ECDF2D0E726DDD0E137E76CF2DB914227F8217212BE C218993E94ADA9E7CF174EB3D74860197A25B0C216514C35D8F7CB93684734AB 75C30DEC81BFA93A179FF623A60202B4062B5C79341EE6746E969CDF1ACC1D8F 1EA1564F1EC6F3C18C832859934DADB7DEA139D53992AABF702F72E8A1CEE94E BF65E14F2B66209CFA1A1320583D720E2603296C6F44A315ACC066B3F992B90E E92008D75DAA8C2315AD78F96FC764D24B4D10532DA50B5E04FFC5FC5A22A61D 59EE4793F61CD2BBBF324C7AE5D07D35DDF317F948B7E3E61FCCEB3E6DEBBE5E 3F111EDCBB5966D4394720A1A5C942A1180E65DAC4462559634799CCB7D4757F 0124F260A954E3FE510748774D27585AFBEF65B7E8FDBADAA91915CF0903BBE1 54000771D4803AC15DB2DCEC906D60AA544131665605860264D6A5A8DB1CD294 95FCB31162FEE22B4088D4779DF1D884B36A67F024A5C4D40921647370CD5D38 A45E59D1D51E5A9451673584B72D2FC664DF6C62CC1A8B3F0047C7A6B6CB3E66 0DBDA3BFCC39248D4348467E222EAA84086235D66D8D8B66300E526DD0A176F7 0E02EA82DEEB74DC151E7033D86AAF362D1732ED1158F7DCCACFAF832C89D1A0 23DA7B79FC43F63BBF45067A4001260DB9FE0411387AE2BF71BC06486B1A343C D8E7A601E8C160B04369AC0E70EEA3FE181C13ACE08EB422EDB9CFD6D966FF05 9F314A704EB7E47D99AECE7684E54BD40194D3526B2F54E709871CD0E00966C9 8130FECF80044F5542DF47BC7BBAD663340721C5D4FD2A2EE813B63D1634A1E6 16F64C0DFF921A3FBF1CD010AA577ED3D559023DB59CBD2E3D57AB5E34F05EA9 F578D59D82867AF3F04E9C256FA52B462D224E09E013B011A11D2BAD1162BB93 E536C8B5BE0CCA924BBA8774A11BBC421E83FA81E9F50FDFC3270BABE4B1B534 005818F36C5172A9F8360E845D2995DD5940120CEF7CD17624F0E2A5424919DB 4838218A92A3400EADDFA49A7BAAB17F1EA3ABCECDB82301A46EDD3DCE6FD282 FFD9F56B78618AD756015084D8BF715E80C510F2B238DDC5D2ADFB60F7442011 D347433E2116A6F95F40966FCA28F246961439FA44736247CBAA25036B545F1A 631FAE7C7B24EA082C8B2FBE471FC70812E8B9CD0EE418F274469DA00A7E559D 3CE4A73E1F9E538D493AE278164759CE64825FE16C36728921BDDF33D16DBFE7 8AE0D358C7B17E90C22E00A770C58C02F0F055C8DE14EB350CC501706965D4CF 5EB79BF039C33F2D8951E145D7AD4E89BC3CB86DC9661DC67A13DD35C2FDDD87 DF24A6C88FB707765230557FA2D3AFACFF85D6D77817EA9D226D8EB21CB89DBB EE8B49A71DD7B1B7EE52C5427D06D2F8C0210A261DAF3BCD9AD4C1403EA94C9B 96CCA1D82BFD2C36DCEAFA5A256BDF8AE6BC24026DD7218F61EFDE1D5F1D2637 473717457C4B6A877D22980638468BC23D0F4720085C5ED91C143A8ADC78D79F 32D0BC5FCFF7B9589EF18E1A4A35F047300D6074771B1F687B853840CC0A296F 593060E9CF41D2B8DC10DBEEE52A465C923E04993FDFDC22CC0F2E5D49FE7F59 1AA05BEA42D36684819EEEEFF1853D62F7C833905E727194144093EA55D35713 E2E9EDC8FA4A0FCBBF5411078CB4A7975A24E2614F15FFB64115D733D37296CE E11103889D961C59B4E77F1EF31B6A2912F8B4B4C033E07E8CBB2A8E34B52BFD 3C100E7A657599BB5E1BF530F1407860C1B85A9CD7FDA612D6CDE03DDBE2A93A 986667537462AB0B27E20C1D618452659798EA3F908C90ED841585547A8B0AC5 16FC0179CD59703066736CA653CE57E8C02D605AA216F72C2AC61D534984F47D 5EE66CD704CAE98ED56675F3C2702A3B614302FB0EF3A3F0C535358667CFB1EA 8D7C0C3DA53774BD244FCFA1C9B0ED8917B61E1713E223F3FA9899060FD18503 6C5FDF2D6B78DCC90C777303919DA00AEDC478EAD8CCEA9804B5830648DA618E EE8C4D79AFC77EEF266ADE09D777066D056B8A2CE09F689D31F2C0FA8BEE27FA D83E7FA6E0F0FB85AA51B692CDC3A239402546DB208EFC3CE2DA145B6B40DA1D F5E918975CA058592675FF83CAF282CE1420D724648387F15AC091CEC297B61F 93876FEB436C6A5EB19872F089F8466300F41CA70C6034C319BEB9D85084AA21 B81AF837A2026DB6905ACE2A941B65D5B197DF0A09C675E4537957B965D7F036 B7A36FEBD489C0E4B284FFA332B3D433EC9737D82DBB324C90207B01A0753986 6A1DB7839361A2A122C3C86B1BB2D743E29506A6B2A612239DF389F76DBE7284 5E3CE0E1F146F40795CAEEC95753D8F90EA0F63BAEA7B8744351564FD4E82BFB 94A1F6C35E1C0A7E857CAEE0DADA17371D616CC087DBA8854E4A1372610EF8FD AC10E6C52BCD44A4F9A2E41B30E5C948FAB0C8D1C3822961939CA66F3375B5C3 CC39D9560C010A1363F72690D71A7208C46AEE9AE963718BAECBCD412C2BC6BC 6BA33871DD10CE126E4E5478A19B2ED5FBD147B0AC825545C17683C7175D9456 CE5563DCB2642830EF891F673A3B8B0A7A4042768A1BBDEB384109616551C0A1 B9EC82F2DF5F97152B7E9F7C4C327FD70BF97AF5CED09CF717D58EAAF7421912 E0DA94AC46733F6D4B2E9C167ADCEAAB1EDFA06DE196CDE1258B37171A5423AD 9B384D6CADDC1978B4EEFED02B5F0678DC863F8D27CD99A8AEBAF74FF120E81A 816FAC2E1EBC886707FB6BD8B95A118E8F4F7B4A8B1106D9E42E1BD39B118AC6 AC36D35161B3EB6C40450AC97FA1B532C484A139066E0D76093CF9D2C94655B5 AFA1C372D442C1ABE20E5CE0FB43E820AABFDAC3A2CBA73420ECCECEF9A10245 671F92837B1EDAC168727C8FB6F97E2E104143923BF6B9A6DF426C24BF874EEF F9C10A9ACBEFEA24A21A41A2E09D3828C661CA704DD18F8884A6D39F94985137 37464BF39A73B421C67E51AE6A476D9F330A54BDACAD222C0120DBF1AA6CF489 84E07F357E760576551DC347BCB10B9AF497E9A10644AE194FA8603F8F370AC3 6262608FDCF6026700181C9B6C37B955E7936A451696F16310888CBBB932D5E6 A03F95FB173D0923223F1B4CC020F38573DD0C593B834ABE8989263FE700A2C1 8163288281B538DCAAE19EACBD6441E93378D82EB7903268006A9B665FA29465 267586592927BB426DAFE81F5CB7EAB17DFC2B2F1A5A367ACF03E9891D2F5383 200FD0D3A406BA3A705E8B12852FC4944FE2759BDF3F0A3A6DD8D354F6E4AF1A 437A205CE2E6191528FBD2780E3A78CC0F6EB56F1F0B59755F2233737A12EAD6 A9A8FD82508EC480AD837EEEC9D30D7D4EC07FCD6CF9DD7FCEB28D8EE54457D4 78C5E61BFC595A6436BB6907872D6E9C4D7C81EE337093F5C8B64FD2E096E2DE 72A040C5F8B1AADC5626277E9B6D734A5F593658420614F792804C8C32AF1316 5D47FEF1D6AA91940B4B54B2D0CB4106B105B825722A1A0FBA8E217CDBFAD4B5 3D0EF9EFD1011B373B255A74797B2ED2CEC60E12637791672C10FF6AF70D58A4 D75A42765B460EA23FCBD3DDD23A92F67E852DB3FA36EEA39B8FF07CEC6D1BB1 499E93088CDE1323C6040FB8F2D23C0B2B9E0DFC9F87A4D412C50B246A7DC70C 99B7DBFADA1E01B81749EE49A701F4A70A31D55BBFDA0D8B20CACB9241F5F460 C5467D0EE01ECF0F89A85BC37B8C10FF3F7C0A84FB8D0F4A7893D3E97DA91E40 0957B7C1496B634DFA9A68FFF20ABB5C62C043DE844726A222F8E7690F4294AF E8B5E7C4926E4F05803F4C580F80546B2D997B174FD53FA4041B0B9C5CE7DC09 12EAC8754AE29EAE5AC87616C0C26855C6EEE64BEE398F16E09681886CD62761 0737CB42966EA067F42D64499E6F41E0452EA291471F6AE12C9B18AE15EF340C DF22BCACAC6B2846EE200539F53F833F072778E70882B69761753A0961785426 C9747ED2E87194C3CF6BF670D117ED792DA48B7BFFA5A599A06DFDA767967A43 B3A68C5B8EEBF8047E01AE6D486DCC04348C8AE66743AA7E12ACF55ED5957424 18A5E828ED6EBC00C5801F0776D2CB9B8526D4B826791A0B179B384F3EF50DBA AF4D8B1B920CEFE2CE5B221661AB89D1B6509BBFD0271287EF1EEC573F299B04 F87CF8EB48C7FA897B487D4EF560A598E01A8EA7A266C030E753D09294839A15 C8881D0CB1BF33B3DEA519C618677BE824A4EAD400E1622ED8680D4F8AA30E39 841B4BD956BF8B7A3DD8BB0E7F59603843F3F49138DE986FF73F4AF61A7079AD 90359F4F85E6FAA390ECBE375C95A215036AA1FFFB0DD68E9931117D907F2F20 839A766D3D740EC4ED0C1D9747C1AB9ECCB45055EAF79FAC5D74D10EB5BBDE6B 09BD84A20F5CDDB9287E173791620B7EEBDAC70FDBC0DDC5ACE95A878698EFCE 7EE6D8A9503EEFABE17D6E37724247B18E361ABB6CD1E394BE669369DAD4B343 FBE075F70DEF305395919F296FFD50BAFC3E5FD3FED238F3FBFA173217D92A83 46E3D89D87EA2EDBCA1D5B7573E29C4588A711DBCD798E7AFC0836DE311B826A 771F78A5DAEC9030AFD58E8400B41D72BE4D8E8322FF0EEC28346A6783E17822 B767BC792A4B7B8F9ECB96B741D45ADC14178B61206A62375C3C1F37E763A7A3 C7FCC312733F4BACFBD370CEBCE3730D3AC8B2C9AF7C67021A76ADA55F303884 E78CA15A338F3DE4D9B1B97A1FA3C9201DB10A701ABBB0E4E150B2862C66A18C A97E7DBC6D5F62C8ABDDC56E6661EDBB3F6338B55EC23AB9F52071DE40999D3D 971105678E9694769DBD540E848A51F1DC8B0DF1EF0F5BBD0F8B61A45CB72F4D 8BF2C9544DBC551573E28B56DEE714CABE0625603C073E511DA0C7E58910998F CF1C4EDCD6DEC6805FAD4C72846252E31F5F6078AC6D3F91C962BC4851A9ACC9 9D10B232D2026548F675505CB8C32CD05A4A80C2FC2BBA69E7E1E722BDBB6E6B BAB0E40AF3A3997500BC92274F6E65F35C92EFB11436758BDBF8F74D31C0D258 D16F7158BDA3DAB4152DFCA7FB683311B93790065586C1906890F0D462C4DCCF 17C398923752AA3B16EB12391514FB97D9103C958A2761EB717EA309F952774F C022BBAAB6E37BB7F8E3799875819DDF023FF06A9ED690CBB693DC305271CBAF B1B6EBC663FB617F37EE9B5AAF17B17F5FA640EE8D706A4A516A31045C1E1403 7B05AB03E36B85D4E366FB6873485CDE6CB7DB6603D3D64DE7C2FE5059E89890 A8C72707216A125624DD4D1D89C8944070BD1408F05F3EB5D7C6DF49499B96DA 6FC4EA97970575CE12B3CC8C5A36B85EDE1C76995A360B6AC14024BD71BE348D 287B409E00C9859FADAF0926DAFAC48F94225CFAF387ED25E37855B3F9D45E31 1033DA4DD056986E06541A91BB942FF755C00BE85D46015F1ADC7836596ABB29 874546338E5CF4F936B049CC836C9758CD17A98C30DF1C11F951CD0D3BB1B122 BEC7844F49353C220299CF5567FE456C1065DC70EA7616F107BC4CBF00DEE0B6 199D1F0C61AED4BD951FF80486E737429DC02A7663D0C888E51B8EF8D7722152 0EE59DF91460D9C2879FC7DE1DCDD16281CE4C345846D95D1030F29792406B1F 05E7FCF83C37EE9A79EC3F5887DF39454391741FBB07B34AD55604A8DE369F0B BC079468B37F88D864C6956D018B63888E095FF58C3EC60DC97B0C33B7F31536 739276D25B1F67A7740E7A4E8EE0ADE40F44C09981DC24E163A6C3A237B76793 1A59090525486B59189A9B3FE3F0DDDF58BE6085D2DF34D50BC68AEB68EAB2BC F10CA218180D697B98A27C3014EE583501D8178C5C2EAF99ED6128DE24AB026E 0C32BADFA41F505A01623C236489AC0736CB6A5C11A042D13CD8EAF9728A6A2D ADAC21BBE514A667648EF369FB5B22FB981ACE4ACC89AC76ADA1B7517D860F85 76CE7E96BB3423833775966C85528784C2DECFBCA5E2D1BA186A175307839BE2 34FD6EAEDCDB902E2BD000F28B1F200C1EE03140A6BD04C81F54EDD90B14B851 9E3D6F389ED343B750BD762CCF96CDB21B6C976164FCEA4E235A0DF33C12DF0F C3C0A61C47256A0DFC9F7AD3A85C53DC3E9A25C97054CB1D365C18356204F2A0 31807EC30085957855D827778955560089087CA2D259962E809C55F4F5C7AAD4 E8B55F19B7CA05379A42DAED44D899C7353B87D44C61D7C3BA76AAF11BF8B17E 1BEF12349459D32F700D7DF525D737CF92044F579766FE4FAEE52843977942DF 1D47269AD8CF4040C4F5898084F89C65122A009F11E59F3D6A9869C097DED865 041464BC79DBC96CB34EAB3A7A62E7433B530634261106A3A6335582D1D15159 64B4D13ACD1C929EB55C222B9F36136F007915E5B0EB7FE41BA71D46999CC806 5ADB2F21332F72C6609252A14F5CC143B10465D1B1AC212C711CA0D01367D8A8 4C84F5BD56BDB601372A4462F2FE5FA1CEF0CC8E8F6F9A755C433D4E18A02ABA C7A94A0E87E25C3F7CB5348CFA37D671EEE5C276717A40D22A83161269563961 F385DC2C40F074F3F4F3C689A6A9D6C53E734949BD4131D480289B12F6064E98 9D12E823EA33D740C888EACFBB267DC1DB35EFF5D8E7FF1D56AB1ECC20BDF1B7 10ABE27C111B3DE5271FCBCF3CDC417E24F5C3966C8D0620086B1DCF58434AC9 0AF50111F63FE8D011333C03FB1F312DE7DEF9F45899891F471A24F3D1D4E9A6 59AC89BAE15BA0C868F776DE51765BA6FBFAE1FEB947789E7D2802803032748E 5A2349A3CDAB29FC93C52410A7D4ABA9EA5C00DBB542257387EEEB9DF08566B5 74A822FD8D1AB0BB5C291D692AFFE1FACF5933714B8F47C1DB132445F4B84E6F 817232ABDC3B842E9D79177E24BCC78D63292665AF77426504D5B186DDB03E7A 08C651ADBD751F0B414CAAEFA302CE2A66C0DB03FFDACEC968A0EA1C0FC72E2D 9798548B7F035EB17A87988AB23551F7881E19BDE936DCED30187C7B5BDCA4FD A8B5221AB4F1DB90346C97C86EC1F53415DE697B03FA463954B52644F240A899 D23B6787A224C506D670FF6B50B627D10EAB96ECFEBF355CF26890CD53801E4F 02265A91086C5D40EE2E567EEA59C3921130F006DCBA3C90A54CCE2633375E0B 9E13B07B4DC4023ABFFA516D638D1CA36F1537B93B6EAD4B584FF7FD56A72165 85C31323D81CE20EB7A8844762532D40E1FADB3F1A8FADBA0B803B5B0A120626 8514EB3333BE07159398746101D836BEE95E8FA99881E919B43ADF16A5E33580 5A8B62045EA007C675C287908E151114E6A4F4573083204D28FB2C9692A2D34A 9458A3E5B42E290BE84B679A4B2D038384C2435FDDADC5FBF9D8FCD680D89B3F 3FFDBE12FB048CD69AB6F539560F9E101888BEB8300963FD175E6701AE0E7223 87A5AD696CE41283C231458BAB0E0918073E9D4928EE6869E1F6955567DF3248 76231EB54343AAEB2F960B299CD13B184E92DC1A2488AE82D60054E767184397 F08FCFCA50407C6F2C1245CBF8EE490DB5316C5A724E4EFCE36C3BD8592E2CA8 C82467FD8BB29E311170E960206EE99A516F0A2322E23A138B3FA5A8D5B6637B EC0A66DB68C2CD6D9FE1A42BF0149D10BDC9A47B5026F71AB84F0B4DA80B4904 347BD724DC14BBD818214E2622F728140721DCEABA052F052FC3CED228E9C0E4 84D4C7797575C9D3197EBF0488FD478A2C924C42A958FAD9BD5913EB9056DCD1 DEBBAF4CAFC20B57732280569352CE0F64D7C0B26A57E68BF15C850C7F96763B DE041CB8AE33E9C8D193642B1AB9EB060EBB63EBAB767485E1033F4279E11F12 5958571B51EC34A008D4FFA462A7F04EA6303084B0012910D2F4EEB260952098 9AF63913792F6ED1B266AA9C392A402D388259C8ABBE5B3472BC9816FF6B4A08 B2C235843F3ACC389E726FD857AB078C93DA736BE83C8ED2BCA7F58BBBF8B519 D2136FDE13D812A50565638378387F5B3F92997A8F0CE71807698DC90EA5D1A2 5FF58595F1AADE8B282ED5317B9E5F086A4A265CB2FC65A13155DCBB875E379F 4A7EDE97DB94583BA166B29F8DF2EC42FBF1276EEA9952DE98382E76FC648EDD 54A1BE9C8A58AA349F447D60CCB9D0806B7041B5F99766737C58D84F5B6C609E 1FD66B020C9186E119BEF59E2A4BF1E262AAF1F3C1B62A22DD1EB75B3FD96138 6F3C0BEB0BB3A82550666222CE4C2687FB521564E3AD315E1EAA27239C939D85 16182CA55248F3F4245396BED3B38715A8E15FEDC0BD9D33D06EA1126536D871 55DCF7B10AB492B903B6A3E917F05C7CB35E46433B8E4DF983C178A5CD65D2B3 E5CD7560E48DF8EC00C50A3F6363C9E3C903BEFDA72A15B3AA0F8A4BEAA4A14E 398B60E23BF0F792BE5DB4DE1CA906436802C19C1B8442B4F9858E00CA94533E 9A61202AF63EDD69838AFA07C24899187BA59ED468B370876E060ECD191A656B DA5D8288AAB19F06F7675566174A610E7A96059D856FB2DFBDB2234369EEAE15 002ECBFF6591496649A05EF9C0294DF44D242BD487E95EA7B96D7F9861A24721 AD53D4198D16044BBA7966787CA889F92F8F5F668E2D517C0B54C9654437AAC8 D02CAEDAA60CFF6B215FD1FFBBF8FD3A20270D4A49D9D2E420F8BC84A26C5D96 1739288B5F36437B6F1C44F409C810D591068BA757CE30843D84F89AC964B55A 13CAC93D0A5F9008226F480555289CF21C8C714F3BF3A07C0970B607731B91F7 75F80912A53A1B069F75DF0961AE31EA7E5BD016A2D4AD4F09FE242D26CF0347 9D3329D739F56F59E52DABA0EE8DBB0B42EC1EBF4021070738838BE7E8450802 1F7A4BB222733BCCF4051334610419E9BE469A9F1E1BDD616AAA66BFA72F5CEB 996BAC89DD9C0A0FFA2D193D797925B03E43F0388845A1A5FA8A32C70F2B0F25 16A82DBA3BADFAAD695750ECF4B49902E209772436A024B612D0CFD32E77CFFF 668D9D65A81DE10E61E505B9C111D3386714450D5E03C072A6E0F284A33ECEFD 0D2ACC3671D3B5D93651E66308CD5D28C896C10544CC99C08FE80BD706FE0D5C 04B3D2B64E52412AA04E12ABBB4ACC2C6DE93C9A93333A5CB4016A81311D6C2E E423A2A2A69035492EBBF45D774D79897858B54664E8633815BA808AC8180551 D8B05D37FF2EC7E91C1A575EE3D22EE373EBCA3664024A6248A07FCD69F9129C 7D0184818D43B873AC8F91ACBC5478A8FC62C1555AD8E55A2BDB5D71BAC861C4 EF819F07488FC4F2C6DA1BF602A2FB59122B22CD4665A32E67172FA3E94FD2A6 D05533606B50E59CCC9E1F1D234FF8C8DED7EBCA211D13544D265E57564D81CF 71C7F861CEF5BD065C008F6E6F28C4513AD81A733904CEC58284F3B2717AB9B5 B049435A08E1DF6FB2CB709560B55633BD65A058B7EBA540F44AC1B31A473CE9 97F56F608626A34CBC8A2541E00CA19568B1D2054BBA770CD839981E40896ED7 3A155066FFCD976E8B376759DE21B442D5EDDAB2377AD5332ECD561B1F9B8C3B F3F152BA297A8C4C8985FB5FE78F1E32AFD4C04786860CDAD45C00988F920B7F 4E741D75D2BDE128F5FB218DAD57FC3A8D8E3C1D0287CCE25ECE1D0D14BB0AE1 CBC98C0A985A4FA9CFA06310089A426A7784335F7B2597043D42AE6D537527EF 94B4EFA9D3F7A27E8E87EB460D926ACAFD9E2BBAABCE274F8D7C81B131534013 C3E6314CE199412D49965C085D781392F8C85695284D39C0F9F9D3E2FB425159 3576AF626D7C63B19D25ADDF1996B833BB5B8BCEBB24817AF06F446BC8279F49 598C76E32090734DB0DA0C83204E6488CB9300F4C06367AD40A39BFBD242F6EA 1F3DE6A857E980A957D9DD0F3A8D493F2AC101FBC2944D214A6B213F348668DD F726DF5DAA3BA5EBA6C10CF9DFA3009E4E3EB743A681A8BAB8F92C7CB3927682 3635F566671669431B70DDE46B16D7CCFCE2BEB458F1722FCD4F43CF9B353CD9 390BD1AA52DA465576B6F9541E05E393B76109FAEB41AEFD15F0A15108826152 7B82A32F27106CCA55222D1D6CBEFDA25A7A37AC526B04E5AED41BEBA87C7035 CFAB68114978D3B639FEF54C7D4C4A54B6DDBC5995C83DE525BE70B9E678EF80 5C154EBBC2BAC4B591482B79396A4CA810A6506DD44D52E98B6742EFD30B80A3 37C5D4B13D399335417E0F25E43B4A08523CBD85BB585481C295E834794966DE 45C14FC7FD0FE7C3D0B19FA89E954661383FDE9C4D6CC34C394B6ED207B1128B 2193AC631791A1CF0CFA0CACEEC83758B05A887C494EE541D6B64C1E0576A599 AE87EE75E9C5BA90265C33626CBBECE41BC4F228C16DFF95FF12DE99EE28143F F17F167F6936221DF6633A1493628F9C999BDDBC9B82F35051BCE22237A8156C 791BAD538F4A464EF0678F1AD81FC3F2A647991FE4523E35F76D247B761C55E2 3AB6BED0218889A6B36DF2A56DFDBD44C07A1DE9FF18C0C945B4A8A698FB5898 BBF759EF49385CD34ABA7B9F0F0CF97C3A982A0E7B513852ECDFB3C3E469A678 F5DEEBAF7D374339CCF73F95F7271512805315235E987609654967288B5D8A81 F4160A167FE69024115401DBE7D04C6F5E5CADD371CEA4BA03B3861D75BC8B8A DBC80DD7B03EBCE5D8E8EB108C5D710287789109E5C7EB22A1D1C4860C6DE79A 5BE5BD37D0A86C9B977A707D158309E1757FD48111E679F6A8A0D572E3D66B47 44D7DD9BF5667E4CEB586EED59B12C0B848D9BB19483ABA2F3D28E1769238410 4938E3F897DB61F94B4B442BC9523F544AAFA7676CFF237E533E08618C13F238 B25DF83FFF58130DD935150A1F98C6AC7708061FAC0F2122BD1CA96ED849AD21 6A8038C1C0874E18CE4F60F8C290ECFC41EC379C48B246156122A538748CD2D1 5A23A7B89381AFD00A1FA27470F2A228CC863AB196E7C8D0FDE509AEF6303C5F 984C7A9FBD0B279849FCFFEEC66B7AF8A7ED76C59AD484C046976B919A99C980 B4DDF530330DDA55957C4D9A6D9C07EE6D7E2332C7CAE7B2FD86557D6D41F5A0 DE889900B26190686B0C9A17D263A87AB332CD9274262621B40827E650E36D14 978B20AE2761EE07C1CF4AA30FF9D15C4AC6A11C7B9B3DA3A53BCE476B0BCC30 3E34F8D16B7718D7C2DB814803155E32BC60ACFF5CBF39A2F988285210BE24D8 4E24EC707824738D2E07A707A5B09F0E57F75D8C4AFF7295A771BF55589350AF 276F41772FC234AB239928E0FAFAB20B3E4F6CB536EEFC3F9E038BE267E3A915 BAE3D5D092F4665E8BCD58694479B9AE56B280E60B2A402E770A037C4FB109F3 E8337A1E2C7236CB68DB4B90C7E5A20D2003476610755FC91D5CD31221F1AB14 DDFAFEE9823DA2F0DEB850A93C5BAE961772CD720257346B33E286A86797F523 1AEBB942E96FC20753BB24A71B15D09CB780E18F647B755C826D7F0392187DD1 39AF2F6874B3FF610B3A1023A78ECCFC72181DD236A2C9C4F70875CBC9F2C169 13889B45B05EDD9BC48219F12BB58B2B274F8E9A395D28F059FDD9726E5C54CA B4EC41026B5A58CD7BC2D4AEA2AE6B9E1AFF44AE11FBBCC13503CA6621E24724 A6C35E568EDEE884D1307117D29B071C1FB183D5E8ADEC29A41574CBE5ABDB7D 2EB0663CF14281084C2CCB9E527D3B31FDA8A5242D1AB534C0D39BA91458E6CA F8EA06FCC61131A5DD44B05B63CE0F9832AE90C6A6849745C5195AE3B9F0F0EA 66DD928A009889A169292D9727E783CE3088D7B488077F700324783B7861B128 77DF398784421832A15ADDCA04ECE803E710E32DF141B56D2844E9F0A53767D9 7E1CF48A4E3CC395F4C118CA7E081AA78DC68E06FCC509017FABB432E92C 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusSanL-Bold %!PS-AdobeFont-1.0: NimbusSanL-Bold 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Sans L Bold) readonly def /FamilyName (Nimbus Sans L) readonly def /Weight (Bold) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -155 def /UnderlineThickness 69 def end readonly def /FontName /NimbusSanL-Bold def /PaintType 0 def /WMode 0 def /FontBBox {-173 -307 1003 949} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8D62A63193C4AE94C086C1 552833DDD8F116B5DF33205AE709B3AA63DA7BEBB165B67281827B48FB5EDBED 02A1A5C0784FC57D3487DAA59520BADA1BE3FB9795669924321CE4F466CD8E3F 7E8EC2494AEE80E2DD7A48A6861AF5B9F0CCAA4A2FE2B03498EACACD6B9C39C6 A8F2E39E06BBB061CF2EC380A32EFAD0B790974BB5CC3DAF0992471456967362 77DE34813F27ABE99302F86BB4D293A37F84667E7F3DFEE4CFE9D1A676A5728C AEB5222FF50DA97E74B2CDEBF725FBCA7015A188891C8A376B9DD8A642C4B184 B1BBF3F376A6D6E31EF1C8354DDF8039CB20FAABCB34D4749B3C8C8D6972CEB1 06B8A5AAE3AE40A91F1F2B1155681A9CC933F87528C99A2B0268B43A3E829E7F 3BD863CB52950773BD9B0731DC4992541D7DE7A055CA65DDD2317F1705C20D1F 93291BCC254CBABA425C032B3B15050D41DA14FFE1B3D684EEA428095A01E931 98D4F849B239AD9D79F4502F0271AFFB0C297F2F347BFB9C137782646F648F77 0076B85F5A929FCDEA2703333F6918B8F125627F8B505C688E30F258DED1AECF 2C86EDCD88C29249A8081731737195FAB7ADBB54743BD66511194DEE2516959B A20701E2D97342248297425491F6C9471EC9A98E630D734DAC19721F0B324432 C8D7A0B751453F89F7008BA37BC48E0831EE3ECBD8A0A292D63CFC890B28F695 9E29AC3B4DDB78A6883B9272CE34A012A82ADEC0B6B641E3940A438A098CCFBF C50544B94FACFD9D7AE09AD0632015F81D2F77FC6D80A42EC11D67D8A91C376C 13C8E3444CDFDE4D2A1ED021410F4D6A4E97804AE949BD913094D23108C9D384 56F11025E2D24939114B6BCF579A0315C52F3CA1BCC2860FC1A0B9FB8A37AE2F C20C0FD44D215FC2AF737FD0339B070D54E664021240071C665DE4170DFA182D 4E385685FB41A2D85888B1149E9A766CB4F309B4E2BAA28CF1F8CC12C4B19E33 F046CE97B53DEB549FEA96CF6CE66357C4904B7932F5B1CE03CFE3A10C976B9C C9AD11D7A02816F8E11666CA8B3EE1411DF2CA94172659BAD929E3E3E5248F48 0690CEC6D8F7061608CF2672F65ABDC96B4FCA84D5C847440CF9523D3BF23F6B D4365582E4B187B6A1A0282ED323BF221EDD0A4CE11CE7EDA738D1AF48B2E19F EB3DA1664DE99C447C35DFD45069FDED1FCD70B4A6855E91FFBD7146EFE88012 0BFF1D6D1ACB53D5E07FB5795F561A4A3E953BBA7C03A9762ADAE18E58DCE6B3 B1A703122EF3B16963AC7CB9682CE60E17947E7E675D19901C7E8272CE4C9FDF 536ABDFFA429B820A82AEE9A73D7DCF77DDE4D8E251CB3B3A5B0A91C0FCD7FBB EAD7A812FF194FD049F28B82F4C2D73E41CC73C1C9F668931A2C7EBA5400A1B9 0902EFE6792F207136E1E16B41794E6CBF7316889A602D35C37EF36DEC95AF26 E9BB0900456F2EBF2705ECCE7B2ED90343D23E006ECB282D4B3629BB0C3892F3 FF9C17FE6C5FAB68358E1CD44AFF021948AC9FB8410A3DE22E0A01E367C52470 2A8CFD284CF9E8F505D5DBD7BBE242FE071FEA0094A55ED1CD7C9BE6B7C56C98 16AD1985FB7624F5E48CF6C0C2ED85B466F64C52F017B20CDABB85D24452E086 3942362E764A2BDA0F6C1B24426E302DDC4403A087EFB2850CF3275C7B24275A AE270F212831F4C4A5D95DEAB61923CA126E587E8F5ED4F2D5738F06E8C4F911 B346B8ECDAC481DEDD2F546305A7CD63CB67D40093C618FBBDF498C8D7EAD8C7 1F5F022D0BBCFAA8670E3B3B999A1697C947AF38D7E1A360E3F0825A9AA77840 D7A9DFD575CE2F04D308F7C553EBF569AC84F2C12AA0869CE107C713A3CCE624 5059BFB3F5AA27D10E337086144AB09286BE3825A3482C5422454C6A9CBBF205 833316780EB88302796FC427A0FB9E53A7BF24577FEB3FA5D85CB6344F908007 183522D3C760C11FC7DA8D14BB5DD800576A6B4D1B991C1BF3DB0F9CA2AC5D22 91079A199F2F6E6DC68213D33EA893B74F6AFF30ED1B51F8B53A015FFD4D2076 B71F73225B151CFCF11E2A2917CF1B3F60E2B4D442307C394E1625F7E60EB12A F2EB9CA7B17B082F1664D09CB7A3F38AEA99A13F659089426126F47FAD5B6DC7 64101CD437DA3C22BC43E7A8DE07253EB371470EE1E4E42A5D1FA2C4DB5565AD 79D6271AE28E8FDE5D4CB24064C145DE44ED486A1E7DF2DF921F2B1BE5FDB120 D8B781C3655EA72DC22A2A2D37579F0AF60B42320AB25C8D769124352448A154 7A381B388A4D9A54E82F199BA35F1A3981823AB698E3F87D38D32ADDD4F13832 77FCC9ACEE7FBD3285F689A85B76D0FEB9E70F09BAD0CE144770A6CC203CE40E 15912DE0E3465DBC7918E3EA49ADE57EE8C48C75937F5D25498C45170693067E 6902937C9B43AB6080111663D5DC6D88F72A39C5E7BAD677229498323A3E7A22 2FE2552B00CB91CE2848A1A53538B7AF2503A3671903E10DF0E9641DBB70577A E828DD3CAE98FA9E1A74F4377F908D3CD79461408ED29832BC4C9865550CCB00 45359282255057A4BD4859915CF1E45ECDB7329F90BBF63E0A22A54B05C5ACD1 9C7C4DFC25482A27A20C7AB908546C3577E87ADE93EA46436314A0A7C524B892 4B012239E77CD65AE2949BBF7E46A5A2269B7FFB1CF8A5BC7EEA1944D2B0BF37 BFC36ADAD9A599FA133F77935F24EF518819D054345DF144731DD2332B0F7F5E 84C46AF486941CF1293E86EE719C9BAB6263470C7009C3933F1857B0A863E36C 288D37E6AC85E6A1B4E6E91C0A9FE367BEC427EA3713E8D1F0523ECFF6067717 244CA21C177968583815F023420A660F7AA4CDC8BF25AC3B3E429942B9F5123D 84234C186D9226487C76DFEF5D26165771C0E75F0ACE7E3882E49DE831B46C12 E30DC37395241D7619C05ABC40F5A36F8042B461FB6C3A5181F77B14E9E6D978 37356B4B31FAC3850DF1869063724316104C799B6A2F42C361A375E4D29EBA7F 850FE29EFBC2CEF627A25DB549A4D4C48F9FC9A2F32FA50C1CE6B5A545A95F7E BF2E9ED710AE91ACE1281A44E49AEE4133CCC04926A6DBA24B721C21188C89A5 2A49745501CFAA4364CF49E3EC2A59D9EE46F33362634F9758827B199FD07DBA 939BD7387124656831862F70A97C5A05959572C74865F5902E95093FECDBEA3B BBA9B47DACE807262DE0C7EF04843259F58A323471237CD573298C5D0A0650AD 2ACABD71CB44C63675192845E3D01B3B28AF871F347D4A460CC28D9E94409443 30E893D27B06132063AB727A38F447A2A4633D29ADAC01BDCCC7634E64DFDC55 9141F69E1202C4A0FD48479B0ED95A7605C94901373E1100A6CBFC113FCCE445 E0317CC94A8507DD637C37676954B9D34C6727AACF17285876DB16DD0E11384C 2B996E85E82FD8FD2B8F9B83BCCB398B997364F0DDB71E60CCC50CDD5D122EEC C36B86A89FBBB5BFB227FBA3A7B7DE7C907E58780FC276C24FF066982691A97A 50D14362D27D790375A47162DECC53C5C11E8A7499788DFD86AEFFFE7E674AED 26706E2D079E9A571C6A32ACCC8C0DCF23508F58477D05F9A1FC679C0DA64254 27AE33293D02C9ECA01DAF2D0A1B07E5515D36E18CAA3AB1B6C5736DFDEFE384 DBCD244F0C11087A873C4501C6DE2A5A57E346FD3F92A0451E63FFF6B99C6DFC 64ED8673DC54EF6509D0D043925BCE39072FC64DDF2C49B8602D1A51EE822F19 D7B2135AA84626BFE3FF321A6BEC3A003AD97E7699CFA34BF41F9C2B38DF4794 CB5AE36C95F42B44212DE67A96CA9D047587998636673A031C4EB03CF1A55326 F5D94DDE75086B44F095EDE0068FB6B9D256759041CDA04ECACBD8D7784159AF AE31A9C637D9A5C0C6840DD9E30EACC66D4D6FD6F12A603AA2DB3E9866693070 0D69CDDC416D4B76CF6B835C7BEBF914816B87EDCD5A24E346EBA2DDED30F5A0 DC033E93B040A6EE7F8AB3C44C61017C758C11C2E2FE3C4F18996287A48FA9F8 FD068C42D0D3384FF27C5A88EF630125562663EA48538CED34E669A162640CC4 A632B58E06954CF4C713ABB3BF00C64CCBC7EE25616CC076DC72794F25FFC373 2EBBA3D975C45DF75498814A7D567E49D4349B9C00118800FDE92A222F063821 36D3019843A99EA3280D9F3320A3FAFBE5AC5CA9E7D404FD4CF14F0E2EBBEC84 C9D839CF9231D4DE942B7951DF1804D445F8F69CA4B90D34988C1C1AE72CE581 E82E6EFDA1CCC13DF9EDB3667682F641A47FDA675076CA5532740F1B29DCC967 F20665B07B4CC78B48040A2C2ACA998C1290727A9E2960C608C0E9A1EE967B95 EFBA8D4FBCE1948C26408408F057A1FFAFD8F888DD8506A3ADE9B1DC3D808BE2 1E0AF2D8AE8F680D6D31CA80EC2FEA91C4C9ACFA21C3B3455207441C61E2F8CD 9C8094C6CAD3DDC8F62CB7380CF85C81072A15D625085D58577326F749B31D76 445E0FD00F787A42CE05103F175B50D6A3CF35E245421CA66C872132CD1D83FA A84A87831760DB16119AE1D5A586BC8FA88F65F0B5513003748CEBC81EB48383 1302DDE72463B5E650D89D7C4A65C99F9B7B23D999BBB2B1C56089589E70132E 7B17568FEDA1A74438EFDB0BAB5655BC02EDC17DE7F35C96771D32D380D3E921 2C270F9B0307562905FC6B02CA8A2F7A801C7AFACD58F93FCD83DCF3EF58FE4B 1FEA2B28A2CC54B4C09D2633D0ADDAF128E4E336E36C01A14005F524A46A9757 D94335F9AA9F42C1330C865DAFA62094DDF19E30DAE8C45602051A73839EA6FC 778B3132C7499FE4278E1D36A434FAC6E77F6A0C488C70016EEACAFAE4B8CDF5 BD7760399F1F08F98CE07E4DF116E24E0B2C3DACF2BB4D4F11C5FE4243E2934B FED808777D2040627AFC82897B554DE510D2AEA5675B53D3C3462AE5E27D8718 0B64478D3ED7AAEF59A8D0AC986594E4C39B51275186AC69DD79D334CD046AC5 0CDCC67FDA475E13240445D46726A6D4518AC8C6717F5D94FBA532977DE47215 20D9476D3BBCBC7C144FD3EE6ECB3F8B59115379A09AEAB66EF7165ACA9BADC9 59191023377A30F571CDC08FDF0D8C9D97A80B61462B24EF50E7F23B3A40D4F5 4D068752D950E2646B724F592966850033FB8A4E13429B748E7A25075ECBBD30 FD95E0E86F2574122A61E2463C2F91CBC8672C7BC13E30C1050E4C3D8795A190 308134295C79417C906E6FCF4CB3E65C1F2895057F1AECF43F4EB9EDC15EC6EC BB7011BCBE5D5C08C85264A5B9DA9DF5CD463BCA4DE70B28065DD758D68A7734 2E3803B231D1B1F0306CF03B4E047387F19D2AB6FD30228B50AFAC3AF61C5C66 3B538878A5901F6164B55496236714DF74EB6C8B2CC6285B08739CE16C5B1B83 2A08E098E76F162B61781995A19F186A8B97AA218F88BCB2D6DFC9FB6A370ACF 0769D7740B1573117185D5BFE746D3AA5E74610495094F1CAB1D1645E399B200 90DBB60D0B3F5EA1A13FB288A58CB5CCCCD5FD1F4EFDE44CD22214DD1C4B36E9 D26F69E3E36899685BA8DD4359D2ED36A4EC53FD71AAF5966AF5A0DC2601FC4F 93A836C81AEEA48D466E40C5FEFE671CA0DCAB61797C45A7DCE37BF2DB2B748F 854B463965C83BFA958686FF16A50B6E6DC1C36237A3DD889DD0A88D77B85344 3A15BF1771E198D5D18FD7EECD986EE3252AE33F66EB1A66F12E37A14494BC6C 520261C374C903950906197FEDCE1D3AA2FA4194F8B38CCB84AB125ADED1FD16 6E096F4B23E203839C340D85BC939DC3B2F7E23DF36325C38CCA699BCEED8D80 AEA5451BDA10CBF197D55CE63FE2E08E2C3E6E012C3D633E21637D98B28CEC37 CD409C87B7E6436114846D197A3263A8A2FC43AC60378CB8297C73680FE39035 459FEC271E9EBB8959F9555BA4A774C8D2911B78B1D68FEB30324406C40B5FB3 22DC28600211FC33F4740495D324F9BDD27EE62B7EC1E492FFB838F8C053BEFB FC89016761E78E09A1370FA0EFA52C9A4ACFF158F5BE582A8D23D2F880D5C68D 884E15ACA3B2D56578E6450E260A19C6A63993F8E10D744176653A67D7F16A70 43460436FE0FFF031CE20930C273EA55E8886C5417DA88F96BD9BD67E0A5EBCE C560B2C8876B8FED3435D44599050728042FE2E4B0CFA3B945D3228EAB7D701C 071BAF5F0B6BB5B9C979E696CCC57988D3477503DF1A8ADEF9EB29AD801F7A6C FE211D85AC1BAC0017407AC6A0DDA1E7FDE154403408E3F88F30C5DAA4F97418 5755B25332C4F2AFC5F8AA0E5043B5B8E77B8D164BAFC3954356D1FDCDDAB27A 55B784B75E0634F53846F45871E0864410133A75A76C52EC37CB7F1019C3187D 14F2488C85F6C40E2D604224E142F3A04CE89652249E15456C72C9D5D05347D6 25850714E0248AABDD2A0656A51E372F440BA7B98CFD8D78F997EFD28E104AB7 4889E1041AE01CE87C9FE1E8BD33A83F82632F10BEF90ED75BF798663E50D8FE 495105F39A429DC2211A4327B622387908B46B8EABDC43A4FB940C739BD247EB 1ECF9807710498752E19BD089AC7A6761639E638CE9D89340BB592DCEAB7AE49 A8636DE3847F95B388AE13AA5561B3C70E003D64F5A293DA068D520AEE852551 8B033EADF85F096734ECA4BAED330DC07B877EF44F84284B838EDEA3A326B77B 817ADBF1E5A669A87C3886435AD51AB823765DE44A9357BDF8B274BA5A120E3F 92FE2AB936FD5E82207840D6DD0F833F8C180D56CE314E86EEAC33E4D23223B9 F432C2733CA2832C00FBD73BC06D8744E45D609DFE019466013FF3A31BC8D51B 81D4B080E615C5B593CA786F52C4AF92DE125ED051D38CDE37A960A4B631DFAC 29EE994640B581B1BF8A5CB37F915D85C3BD388CE50C34C4EA71D5786A4FF79A 515CBDC127185FD6AC790E9CBE5D473ACDFBF26043F1A39E0E690272AE187DB2 A7865413A76070C7CBD302ACB9F8A814746FF629B932BE72EB27F2CBBA7E1908 A8311020464C6144C2E7C1EE9442889AD251E7EF8194CD4B2FE3E2C2F0E37C21 FCC6ACE88F713D6C9BD2CBDF9F1D65B3C2F5F29F78686EC20368378774CE4B9A E677B90B3497FA5B76ABE33A047668E855E62558B6FBB9D92F1D24C929247500 793A40223384B2126A7FADB1F4722D7696E591A6C2E89E4A20405DE919DD93AB 4F793B6E3C4C94241E49355A59CC5E5309F961EB13C3AB22FB3F3EF644B5B47D ACE807262DE5CCE578D7CB46A02F9EC1E7C10945EC34DCAF6612217D29E99108 8DE2895A696AAEF0EB18A4275481004A2F27793ECA0A23603F2267173A80A4B9 676F3B6F5E02523C7F04ABE55A528801786DDB15527FCE5735C49D04A25972C2 3930689A3B480E111CE5932B95D379CB0EBC4054025C94A83943854D3B4F0032 2DD2CFBA62ABF2CCFDFF1672485B80A6C5183D455A147FA6BD18D564F591DDD2 F50FD22C951CAAC66B2B249C695BC19B22B67252560FE97B8E99A1D9E74946E3 4C009688D40201FC0D57183EB17DEBC28B7ABB2CE492A0762380CFBA0E37A595 A13176C6B082C4E071620735C9C7C11C216529843948A77677BC93550072D0BE 0D8610EA3E032867CDD3187B1C219AF235617D0F86C64F328339EED2EDBF5425 F82E60EA2C3B016D0E901721B0659906582A1FB979C2D2BA1FED37811DE15ACC A82695A6F04F911ABF56B40DFD4C50B6A35E119CDB30684FA3F3A62AED785232 C74B7B97CCFF7FD0FC8962530A98376BD26C39075D9EC1A987BA3D19D84E223D 306718D250574E4602EC0964E1E28AF3B3244172AD5A4A4D0E8CEDA9F2CB3699 402576CBDF6A0585192E2BC0FE74616331609D6DD131325357A24634E2521105 05BF29411E0A908DB4E1BCAEF75C34B1C0A4991646FBA64F7FFA5DE7B0DD361B 0FE87C86AB484AA6D840B4B690D788D9F51231B5C571B9544451DED49EC8F5DA 5FF887B04542997D490AFFB4F63E4085C4D274B81FFA36E1209C55ABF26C0FB0 4A50BBC0CAFD38817220C75A20AA65A6D8B102ED586302931052608603E1CAF7 88648D74B078ED0D75074BFF0EAD54D62A75A2E230F9A250F75CC7893C80D479 CE950FE60DF0A794FC19FD095BA2CA9F4E9ADC320F080F0782EA3B1142C76B36 4D2D85AF83BDA04D531EEBAE612BCCE43458A6735454808004710523E454308C 51E0E8811A1506AE38F13A4407E66CEF10819E7BBE82827CDDFBEF79999598E5 7464E82D184CF76BE6CC57F2CDBECCC7305AF0A4793504B223376B60F8D136DB 14C5D3AF5E66DD36A22E617F623F6C6E718F9F65C65C8422B70525EAE5D636CF 5FFBF50DFC651E5CB431C0BB2A9EEC29AE3D59645CE99CB2DC8231B416B80F90 0598681314F96CC4399BD0031A3CADEB6E7E27F9F5AB7D81B729A46F342BB595 1F55E64983F696515565EE4529FE1DA01E3B2BA991BB58DCC55A53D1F2AA5BD8 DFF8B5821AC9F204AB4F96BFAA2C8A8C89D44EAEA1A45BB6EC900FE5572A4861 7925D741D0F7B8131D16AE6F4FD3280C1877D69C2C483F0D2B4266B025DF0C80 782B325A0B3CF637602C55C7E5688D0EBEACFF4924E2DEB93A1DD1AE514B4673 C8A00F2E6AA28DCBF3BAE847E16F123A62C0F96D37EF1BBF7B9EDE353AB8DECC BAD4E0A3C3356C5A1D660790FB32F537522D515DAAC7537361082FD035A20324 2AEE9A73D7DCF774888249DAA4ADB83E0DBC4880639A5CFAE60C5A52EF797FB3 8339DEE85CE619109DC5B0CBA8EAA63129ACF3AA75AB62A0C11DA4175B9F6383 2FEDB75A7C3C1703746609A426D1C9DD766FD65D3A9CD4503AF4114D06702D21 C1305E493D7A642A63F8C286FC69F1DE5A80C4C8B98876589E8E46AE9BC294D1 647DAF9233EC198B785F96E4836A47C10CDE73950A2DBF81F7C3B10A749A1436 FEB3E1BC9B2A0BD76D2FE72FBCF8374E8332B98D6953FFD8CC5D89728758241D 75D2E3989C3BD46A0E19F9B46BBAADC19E0DBF89A8CFE1BD96B21DEE6CE42A0C CEA28A697FA54C418CF7A41109F51861B7F03F530456D6A60F957DCC5B62AAE4 7E6B8FB0144A861E53B3DFC6938DB3C141D0082658D35A251EA07539866A1DB7 839361A2A2ED0E89CC3F8A6ED17FEEB5A6C529652A5264052764D4A9FF1BE531 C35D42045E5CEEBD1C5EFA18A053C5266654D1AA1FA2FDB95B739A3D59B1D78B F490786EE34E67F5D983D0EC16CB0B28F80FBB4E27047287E1C7A9263975B998 4B2827524985106AED7E8DEFFAB3DA446A1EBF8FEC02DA8602434555D99F2E2F 99CFDC1A365D300A475AA9F5F739C575EAE327CBB0AD50D29F8EF3B832E1D767 81C1079C1C4EC2D66D117F2902630E781A016DBF884B17C6980B003A81646E95 FECB6D77DD06B702B54252391E088BC290B756CD6AE2E4447480B542B229509E C665C8613E14D78063FEFE20B255297AF1467F5B5B0508D0717C6BF11130F38E B822AA061BA11FE940615A6EC2BD441374416D765F51337F582BD63F34769274 39E899D26E40EE538AD3C0E3C1CEBAC3158ECB3111A319DFDDF8717ACC9DAF92 003F8EAFEB034F369E992B6B60B00C4A71D09DD4CBA8E90521D7993FC786BFDD 8F86960443F70D81330F516007D88775EE1BA2124CA1FB8498F8375A8302644B D18DE60B7CCEF7377FDF0DCDA3C005836D4C4F15E365A9E89412B8E2E366B433 50CEDB9CB4C0CA56DE46B057C8B70808B8D586177DB01478C83A92919DF0863A 0F0077E4328395B8211DA6DF070745A4FA25CDB9A82BB8B17632C25FE7D55783 F326089B2B13CE0400018C74B3E2FD37524BD6ED0A38F4B28E776935BB6971B2 78D77E294D77EF61C3DF6B704C9F53EFFC8F979E1FC2453BFE4B99489D954875 63A7E640BDCA6D89452F5EC32C12C959CD261B5EE00CAE37F2545D6BE569D6D7 6A3A03B05BABE27139D714E89DE1CF740BE6D85F8F6F420BA6D79014ADB8F2A1 41A88E07F017913C70FD0E657E7620588B3012FF1B03D493C530B676081A3E6F C68AFAD08929F1AD50CD0CAF3AE126484B4EB58D07F77B3290FB4D8117F21047 9FB8939749A381C62843B4E0203051DCD18C87E3E281F1134DD74CDEFFA85187 9974333AE8E7462065D0F2428F92F40E05DAC4E06974052DD4FB1238AE9DFB95 E1EA1AEC746CA267CC3A3C306D1B3DF87ABAC0CE9E2089E07A5A3803CA71AD47 988E351A24AAF56E95C57BA0A152C3DF8E6290B094BBFD267DD841E28870E2A9 38BA48F6D05D350B0E9C853CF60A7F0F4CA6431FCA495E00862A548DE99D83C0 04918EAACF40CA55B55D495127C71CACC4485ED96466AE0CCF90E8EE06C390C0 72D34B37A35D7B38CA5B8884D8E037A93B715EB8116997922900BECC86FE79BD 42939AF1C617333EA28E501B40EA72A11F660ECCED39F7DA2AD26DEFC42A4E93 D308B2D3BB6D66104467F53FE3AC4933DA5013598DCCCBC9BC042B525F2B4F36 D00CFB7CEA6CFACC55DFED40A50FAD6E4718E6302C0AC1C7CA42A63C0396F711 8AC6FFD023CED8A67B43BCBBCB875A8D104EC44F9FF5790B4991E4EE2C71CFC4 B086B5C5EF1FC3D01E1F7F4B81D9977CFD6A7E8DC8A38D6B2E43B7C056AF0BBB FD10547D76D36FF94357B139AAC10CD0FDB82D4FB9F9078FC7599BE10F0B5099 131DDC44973A32A35A75D1B10A98277A64E05BFAEF53121BA569DB0A55774C2A FDB5777E7F410F7EE9B5EFBA480627C39C2D01215C3D5881681C0AB6ECC59BD4 743AB61ED8C5BA5DB0D817D3F6D51D65318915741ACC4F28122498DA6B3B2645 C663E6C4071B8CBEFD53A56FE4CD66605026EB86E43589FBE5F12B5982867F7A 5120E79E212A2A5B6BC6BC5BFF4FA2FC171509AB76F51518A9FEA11682ACC62F BEDC3F3D1AC1D2AF7F8A14A61F257F6F7A9C6ACC9AA5480AB6B2475E33EF0694 8C892C6C862774BBBA689688A9F82A200505917317D65939864B0FDF064AF607 F10F868F5484EAB27763E3332590D2881C1A85A24745FD6DC3DD2968B9D71DE4 3E3F19DF4EFDD6C1BA6F1D11E28EAF575DC2FBE21136F76BF1E1A5224DB2D1AF 39629AE45201790933011B58FF4D054AD15786921CF6538D1BB294B5C97D8D1D 41CEDBAB50E8856CC100E1BB27FB2A7A34A0AEA21D2A485E14A2F96BFBDF7B1B D351ED48EE381E926B5891593BB6FBC0A1788B0A8CEEFFA428D0897C44E7FE2B 5A29D9D23775D661DADB9028E864889FC5377F0B6C61AE98F982913AB4829713 C61E70D9748EB94265EAB49E242CDE936BE8C9B9E50DD18D9102C2ECEAC68B08 C7138B9C695990EDA8752B919B3291D12C682631E3FE268A999E9BD3D843F55D EAB9E49AB7891ECF5BD7B4E9183841E1AF2C234B9128F1DDDC4B04A4D0757047 C62255699490EF6C927B65657F836D87D2B718FE74FF0E3D59D5942E327A4386 86FE0044BC4D6F73FDE348E5F3D76A3631D962CD61D263CFD5200C04BDD5550F 8E596DC52D6B9FEF5249AF97CDF33B1E7F5B867F51CB1CC58265CCC16E25ECAB 193C45F75C84C0AC61D5BAA3F407A66239E930C9ADB0609BED398734FD2CD70E A22F69C0C67543145C2E1F5BAC8936A5AC5A94AF2F92622051C3CCF9E5C37A14 C2DDD71ED9E1EAE5B5E1479ECEC22950BBF0BD3DD8BC6C9EAF4122283CA1349A 3915AF8AE7A24A5B547FEDA198BD54DCAFB39BA07D97873523346BD5A991D0CE 337B1F761FABB13720638F147FD9D781E98E211ABD6F4DE15D06C2CE90CCD4A9 2DEDEDC52C66C05F48E6469DEE81941616B5BF9D2BF99E221B1A6B07C23DD39D A0F1586BBF70AA56E13A381DA056DEA443D201B22B43C98F50943734F3D60312 CDD1E0E54E7D0AA3C8F8A044262B2EF16EE5E861DC7FB6100228186EE500A227 730669F017212A4083545C20BE663A27F0C49E3C7D3FA7C5048C28AA5DC7970A 6C1CF559C515EF48C2BCE25C0A75AC59CCE091DDAA50DCA2C922D9DF9FC0D4DF 3E4AFB32361ACA741C70119E1AC58D9E849CF9F110B7A76A652BD631F83E6E1B B09FBB191A024C0920610E0ED8E25AFD336203A0A149064BA105310B34C4AA73 5DCC84FA5B1A5E6D37E8F1CA31AFB4F9D16C1D634F98664576C8ABEC457B4C21 F3338C74AA44DF2CD9254D234DE3A10DB5632DE7B98CCB732B3BF27F8D1E18CD 3BEA6159F13B829BD19954D9B1D49DC94707E6A9FB6FEEA874432CED392505AD 4150B81EF86E043BA6DADC99FE33F7A054692F9F32B4E6ED1E3FB812CB75015D 977312E1C47065A091232BBA1C539DE3B2A056DA3F9634D3C67DBD9D8A468910 5D427C247448E107CCC21DCE943E45E6E935E7A8EA49E8A5839CEF56BE3BA6CE 0D9DF50AFE4490726F849732DD3983E4F42EB0250210C21E82CC9B6602BA1691 9A2657C0E1FBAABFB882A3C79B7C3080DA48DA790CD403C54E85651581330184 47AC55657F7E49CFD9F3DEAC2A07E63C5F584ACC79231CDC073850363E74947E 1E25C98E9297934169E65F69A2B4C3566D860B0809D44D83156CAB2E6B2259AB 0CCC303901019D5EEF85CC4B1A0EBD3F6D2167CBE2D3060EFEA399AEC0D5C3C6 8A43310AB1C248303730D7486EB994D07B241CBAE136730AF0E74EEB033DFBE2 E387A024267961BBEE77D72F15D65D1485FBA058174EB46F7CA6B74FF64283F1 5EAAC3F2F60CC359E5416F5360DE2DF4C233C75502627D0E9A8A1AE1503B7DC9 3E2AA885D61F57F038E97CF5D848B34447EEBFE80F86531E771C74DDAC24C41E C2260B2778BEB0A8AB841445928C1B5C51F4C3E025E0F082EB8B2BCEDD103F55 1E8F18054C3D410642CE281FFA488575E403078E7D55007485E659139E2D2E22 8A0408DEC3E57CF0E7EE20721CE59AEB58166C443AB58E688A6F0784A1E92B4D 3F85614E94F009273A81D51275D68111CBA41E2A4D0B5904571AF5AE36ABF778 E1EC07C491BCD6E30EE389918C8C94EB36923F31341B9D66FCAAE4DB9EBFE89C 283F7CEDAD18F1471BA56777CC254302E8BEC14C5256B9940F9749A12D6588F9 4F625AC3BC554836848E08C82040E798CFDE82C0360758587FF0894A44454765 853096E98B398ABCC9E291A9904B9B3951914BDB1245350370B6A24A21536DC7 72C62A37DA6C814F126319F361036D01373332B52C5B9F8520DDE9D8B4969C8C 65B08506B86D98D96850D98F2474D44EAFDA32299A1CED650810BD7C466F5F43 FA4B5C893E94488548B309EFCCA9B55FC673327F578EAE2333D832389EEE01D3 FDD9F11ED6CCE522D64AE4FBC10487ACF8DF97A0DBEDBCEC5599C6EF818CC3F8 34D08B084E838E05EB2FEB5C99B30DE26DFE2C39EC2B71342414C36CECE9299C 88F664692171B58FED8D8EA3483598EAD39D3FB5469A0382F69262665FE879E0 999A3F43DDF85B735D87988B0B46860D92C546D25F4D85400F8E4205C8461C35 51D39039D64FE5BB8CF7EB6A7DFBA26BC2521F9AB5BBFA9DD49D23698F715FA7 ECC067033F4F2B22817E55601C6CE3C3D08C5AE67496572A2DD7531F6253DB1F B8F695F3646083EE27FECB4579F0B7298FC0B91BC2DD130D3FE6DB1BA5760444 4D1ED6D99A23805F3B98DDD17E7F91E6D40845DB0D5BF795C3C7B0A3815613E8 A256A01F80B0F35230DF5A949DCAE7CB6B6009F77AC29FB4596873C1BBD54D9D 5578A67FE49DB2AED8488727A1C7CB19B7BBAD9265B6D4AE9A5651A1E87DD454 279888F1BC25F61DFA76F62397163D69F9E96C2C839B4D480E5895A84EB8BA4A 04B32ACA23E286287C37E5B7EB7D55766A3A7CBD9F59EF52D6B78149C13C7A08 005363295ABA635BB842D1B97D14324923423648D4EE7DFCAF83AF24A91623FB 24A00399DA22E00D493501645ED369686A8DF2B46E2DE4C28D9C7868F60FEA11 4D3E3850822483381542DBE9370D44711E76E327FB92FD094419C1AB2C8CEE21 D5066B8BB87965378B1C65C345AC00F9A3EC59ED87BAD48727F473E2F8D59DF7 FB3860109F27B6038B071C53193CC5352E4F73985CFA9C6FBE932C790B16AA9C 79BB534F6FB9717990CCFA4F82F67586C982ADBFA65772B08954F3609A159646 DD9A2894B0175B5BB01BC2F4EEE229C49E2E229FDF499220FAAD783D769133E4 3EBBF737307C975ACE10F87CA721DDD94810D7B26AB6B01CE3EAC4E9316BF3CC 2EA6A1DF1B376B1882E4C6371DA99130C816598334B2A27ABE2EBFE80A272DF2 7E5243063566A7796FE8005B69B29620BEBF01FDDBCB67C4CA7966444C776333 FBC3A6DE75BCF6AEA6C7FBFE77F4FAC8C36E321C9DE219805E47AA51529BC7CE 05CF7916583264FE27B5716A0D2F0606AAF29975BB167D18FB079B8073AD9798 77DCDAEB57388BDFCEFD28A5D2623FEAA38A71C0CDA15AB08A53486FA3100535 84E424B32AD84826619FADAA9F9EF99AE736DC562257C550A653F4B492EC8AAA 201DDA36B50948D4CBF5F642FAF27E4102D29EE43BFDB5BC1669C794279A8DD6 079EF44AD8F776A9B6594F46EED95B83BC0B00CA0FF1F97ED85C5A4FAA3E7653 EA6CEAD7415079AAA5492C6977DD4800DD20BAD0F519DDC21C44D5083F32FF38 8E7E4D4CD15A21957D8445426A63C938720155E3C8BB6F122FE26CCE7BEA8110 F7C0298DBE0DEFA873F20363D6FF5051FF21A27E8508E3D7DC44FE8E9BBCA069 0EDE60FAD43A26EAA8FE5BB71DA8048CDFAFA38F580C0914C831EA9789B997DE C54A45C9FDB4E35BAB3A25EE848923A5D41AD3E61B61CFD70B44A29A51C2B4B4 62AFC11452A641458E97E0ACD62A9B82B286139E56B6303421FAC6FBCDB48D3D 38605507C9CD35480A41C63216A3900185AA725B453FE330202D64F17F06412D 29321180D398D157D31F04C195C0CC90D24D8BEAF66230665BEA222F64B85113 FE6AF4785AE3CAABEDD6939A9FC3D9F3A95C2C0296A128909DEDE5F4F07CB903 E26CB7D66664BB8581956EFAE34D6B21F18C457522FE6AA00AB18F8CA55E7017 1F4B100A6CA16203F292625FF4B6FFA1F990A45B5F5C1EC421708599B066A5D2 982505B2C994A91A57197218BB672645EF781E7573800A1C9DC60944D82C0439 03CBED807628BEF20E2CC48B7F40219245A021BCD6B69015ED655EBD14597ADD 588C7F815F7B3A65E990A7A8C93857EEBBA631A61C5CC3283D2A60E34FA226F8 FD06A34D8AC23FA8D462290B22D52061149D00E2F436B97AB3E17DC70A734F4C 2D2021ED9831AB4181F356FA86843ABD38DEBE39E1F791DE3C51C6AF6FDDA26E 758FCF9A696168830BD6F11329CDB5A33090AC76FF84FE668C91AE5BA6D1D124 02910D21302A6FAA5A3129B223E44E3C5EF75B2050E93EB14C51B7B5EC5EE90A F76B5F2481DD7FE5BB53B5A4416427EFB71C1B 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusMonL-ReguObli %!PS-AdobeFont-1.0: NimbusMonL-ReguObli 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Mono L Regular Oblique) readonly def /FamilyName (Nimbus Mono L) readonly def /Weight (Regular) readonly def /ItalicAngle -12.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusMonL-ReguObli def /PaintType 0 def /WMode 0 def /FontBBox {-61 -237 774 811} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B892BE302B1E51F8EC1929F 36611266EE46F9958416CD8198D4AAA0516D5554F2367EBC9E7C9C4B3703A695 BD52E708A65EF59D6A15BB9B1841F38AAF7AC4E225A07B1C6A14F0B66C37E82B 40E5CEA94D45A9FD083F35037D97FF4FE2DA17F59DB502F5FD9BFD67AA74C5BB E38B5D9118E344A99380FB171B4B5175CE37E765FA13B934379B5DF1E22568D5 27C507C9E85A93C768C684B18B68DE27F4C2EAC41E8BE6026FE6DE5779B03C08 9E0B896CA7B912CF84BE709339E77FBB7F0A23FEA14397FCA694BC21F68D6E89 DA45C1CFB64CF3AEB180237717618E3BF29253834A6A99F1623AA0179AE945B9 DE7A442440BBA99D4C2DE04C649C3B087B1072E291D3AF959FE4DB7377D25F25 38843829F4B3ABC912131083410B6385914AB05524D776F05282BBDE831B89B1 BF79333F291C98E542997F98B35721F629E466C190BAEB6DC88F11FD425E044D 6DDB0A533241F3DA09D6132C40179A438E08D2F7E6E97E554F01EB2CA3D13EAF 278691B1C179E7DBC40B69D406E3F3A2B457F0D7D20905F3C30913CF36ED0D27 1FF6DF7CF98AF85C06468331CB07B99DF7CDFFB71C6A3E627008271139C90471 AF5A35F2786836D0DA235FBC4D86AF490740C22BEE82842873B432E4B388D09E 0779BFA45E31726954F76C3D7DD5147C1F1E1171B71F8CCD1DF2EFBC6037E56E 7977789B19EE83C5396311E47902EAE14FC1B70A027BB01514BD9E7EFBB1BC59 192EBC1F52A9984EE0C0F39131695A11CC6AD33EDE58928B59A875DA56BBFD90 861B59C7003CEA2AAD829C756090F8D5F3B09A2C264ED8900D17D9626372A863 F05EA4BFEEBD5DEDA74B52C8EB0BA711E2CDEE9BEE0507016F7651418558D452 E731374EA597B04EDF4539D429AE594C7B889D256FF8721DEB0F94AEB1E31138 1ACC86D0856C90A91D904C9AD315680CF31200B31AE146E5363352A2D4AFAF56 F3FBB2E6D45D87AF79C754F223D3795482F7EF56B8EECBD9D75C25B1DE870FB5 47D657B91139CE999BED72DA0DAA2167BC2938EDC71452E0B76532F18572472C 5AA2F385A84BB64B27DA576A7BD8350C2860940DC7F8C598D226227FA8C178C1 0D90A2F26A639CF3BB4376F0FE0ED9B64F9EED0F38A1E10FB1DFCBA97F9BF4F7 DE5EC45B64A1F4E00781FD35244A1AEEBF746F5EC828B8AF1030129D8B1F0011 9286FE0113374FA78B8F974BCC4320169FCC87B9A07F243E62B43E1907F1586D 00E290DC70E3B82CBED7AD5E789C344007621D0014B47F693FDA6F5C286DBD67 0E5E3C0F08A10B5643BE5A79BC8BB4FC19F32CEEAE059740F726C741D658DD17 1E75A031507C65659CF678AEBBC7999CBB53FF83C1BD845592F1BA39189020BD 70938D9A7AD492FBFC7626571C28B104E59689F2589154CAFF8C7447D7B7FDA8 C70A3BC591BF0A62660E18994E437B2E30906C34FAC40779F6125AC8AB538565 E06699AE5D68759A52096B795DBB3A07E3301C9311BBCE073B2DE109950CB748 A753CC72530F1B3B617E06110DEBDECDF0CE2482BDFF964A0D656206B02DFCEA 240654E68C7BDB7C99432BCD6F5C94180FFCF424DD1AE0B9DD0593110D6B77C2 C3D456CE66329FE0FF4D0760E8F0C86D4E2D3072B69D667CBD37EC2E81D1E4A5 B11E8ED4EEA345417F3C1D74B5F81A49D6A0C248846256C18098CC1F6591BACC B95446CC0210DCE05E325D7B85B1A781ADCE73A0EDF015A1A791FC4FB181FF44 4FB242D9CC7970154AB80C5A40BA8C83F87229073CFAC939FDF750CDAA28B29A 743EA86900B8B64ED6A90E2F3D3BEA16DA942605CF0AD8103A71F72FEE8FC8C6 26CDE6D21E422468E9175D8A35E26E0D3679154EB5B4476CEA74EDB75A3C391F 54A2659094840EBDD347266E8977795304A52A8E66477D8FB61F1ED9FF61A147 B9F3C0599A75ABB18B9FC8130D88382F72B294904633DE2CB995987DD62E6D94 EAF7C06E95848F51683EFB2AD4A89FC82FFEDFC82ECA82B8CC60A0156706987C 7D0DB913F1BBF8A7B2C5757CF9FAD6765476339E4E87983023D5A21A2943A791 E4A62D5AF6B69ABD9CFCCAE361770F7112D35430B779E11299E7A4D9E7D8D370 CFC9EAA5658F702DF110D3F0F5070C44375E9508D28368D77C3D743973E0CB58 F43AF3E02DFAAFF16D3F31F3606D7C96AE95282EAEB4A2D6E3193A23345340BF A11A106FDA33030881F29D90E8AB09664CEA6286649646B3654E4E2A3C03EB80 9C8E0CB455FDEA90F05FC24000D7F53716002C18B21A22BD7FCFC2E0392F8C5B 53F84D2FD3A389EC51A2326F5D32DDAA06862E0BFB5C0D788E57D2FAB457DAD3 CF25A37159C81527B9512C40DDC92C489AE31BC9A983B14D2773BA052B475D09 EB09469D2BB86F7BC232B843F51137667331B98B6E645E4CAF177E39995BF7AF CA9296677E02D47DB24D4967158F415484BF9D6A2AF6CCDE9F860E04C1EE1075 55A639DF2BE162286795AC4DEA821CC5FE7DC83A9F8B91C0C01CBAA10C003214 7121E8F9A1695CAEBFA7F4D5EF8FEDC734A06EAA63C669CF8917D0D9D071A909 4E8F0C453403C5C5097A251E386FC73A4279A4922D84636DB47757B9D6E72D56 D56076695B3F7D8629EE88DD05245964CAEE809F401F28D7E106537679E33313 0317D9A43FB5693683A648FE00A5F7EBD0A7DEDAE31FC31E956BDBB3917C5921 C82E33A5E82E52DB5332AF659ACF8C9CAFFA4BC15B304C8495B8E31E8D64EBED C7339BED0B048364379E4C2A5A98C3E3587FAACE3B9B023DF549228E03A058F4 150EA4E3B57786CFF8F2AF6E5E01D85921ACE99968B3979515106D5E9BBB0A87 0C3BC2C325DCB7C07A9FD4973CA9936C7CEBD55EB56E42525CD809BC0852326D E98A17CAE12F8D6F6B3DEC1D580A2AA6150CB2985592C3247B8CDF4E261489C3 6B8615BCD0E6CFFE078A7771A64287B1F7436AF9EE08A4AB3B3931D47954F88C 6B23B50A78D96E4BD16B9ED58161C43CD999A6352EC32A6338340054D45917F8 7FECE363ACDCD6A460D11D82E88177F6A0C99EE5FD1235E8F9DB8690092DD8D5 24BF88E726156D587942467949FA963551C22A4B3C32BF8CF0AACDE199C59BD0 DA9C906401F7E48C59C3949FF9CB12318E51E4D4E389CAD9A1E681A5F3EE5616 50146460DE396ACCE7AE960B692CD097005D15003FD327AF34C024417F09A85C B31F758C0B8E4213A3C765901513D317665645D840EE59973D991DFF975EAC6B 6BB81B8364B0C2E1AE0093867B097C172DBDD39B54D8663208775445A86B39F2 D3A78733A2F86EFA9CA18600157CE3971CAB365904DA22349A847ABE04D7ECFD 07827A80C3C14FAA7E72A41C2EDD34B6BE236F25681B594EDCA6007E3E9FBD49 18D9BCC81E0A4F1BD5DC233E61235724858469D7DE960201CBF9AED1515952CC 60523B24E8701CCE68C660A1EC3C0AC3850535557E4F2708A973977CA46B3689 F15C5E3A93EA77D721DE70D8BFA87D96AD491F20519ED62677E6149798A8D232 28F2BAEEEE369F151E3B4A777C23635C8F1C4932CA417A31DEA279295E962856 79E6C26C66420D5EAB8D6DBB58FF2DBD5E48423365907B3F17D7C1A6B0BBD18F D362B717AC355F59FB007719BE1558E0D5ADFEB523ED7576A156523A2D809B41 F2AFB4702CC44DB0E6F223CEA5C7C8987EF784B325D6173595FB81007E5F5103 551007B7F34BB57C79B09AC4F26D73AF263680D2143B36A5A5EAD300984DFFD9 7C21A534C827CCBDC5F0B1DD344AF65A0115C8184493FC6CD3ECA9FE07CD3088 9F575471AAEC8F7F4A477868FF1D9C002206A525FFF9B8267762FA402528950D DB3815053821665FC7322604BE1BCF684438383E439EF8522546674E0290754B 5E1E09CA25841C1B484FC95AD02464F519A03A3409EABF741787FE179EBE379D 14B706E53FD5FF67159EFD4D3E0EA0D3749FB56DEA2A20AF3E21DCC21A2152B0 BC021DB1879BE95E67A44FBFAE4339270B8C5D86B3E13562E68C1D259FCACD70 F0CCF12E488A3F223A179B35B4AEB6B72F30468065D1A2ABF1AD34324CF1F6FD 754ADCB4B3957E1B8A795D720A30B7DE482DFA28919122800171B474419D914D DFDEFA36EDF8594EEE545CF34C15E337E74DD4026EA56FA92178834CCE38AC1B 4EA21D07C4D7BBA3AB19B14F1490E5EFDC805A056E01C1A481E945FD890AA237 45900DF0B0C18453C718FB751B46C7972BDAE3C044E0BBD0FFCFB0E66C73037A DCD10E8F00818EE88AD2EA98D6B7F1EE7933309B022629167664E7533AEEF54C 6A6DEC9D5D61A942ECC89A0DF5B059DF6AFF2341463990EEBC4C7F7C6B25CA5E 7F2A6AE9C67EB7F32BA17242A416716C7998264D9C9D22F16E40184A3697C368 E4E09A0E2156F4BEC7486D6B0646AFBEE897C62EF3331556A7B67C18F1A5A717 BE3F8971BC235CF3B47F7BA4DB3B5F797EF349A0EB76D9523D6F2420B489A720 734AE9C63F9284F658F5DCE58DFEDC7481630EC3129072DE99062758C60AED48 BBC9C855AD23E6B81735AB30E65B373B4A050A6E071D6710FD81A524159B1673 352A01EC150FA65415AE66EF79C6D099AB29DC28B2813D48ED7243E329777677 D01D29B98D64E53A8F2B1C55E2782EF876BB23AADE2E98BDF6B2F9F46418721A 92DE1F019D7EAD1DED9159B65E13E3FE32263067FF54998ECA04BA885D65725C C9C5C92067F0B56C48CCE4C5594410A57C51B0236192B5FD5096BAF3C670233D C5DE1866958E14648B1211118E8E3DEFAF2ECE08BBD9573C7E26FB4BE67A1833 D36D09829FA03EE7D559D5AA9871BB392E75FD9BEA16B3FD22EBFB9D13E7D7EB 59D754FD44E44FB47949643896ADFF67741FF8F24D7ADE3FF48AE7B07F30FC4E 9EEC8EDC1A4916452575C7B3F123E4E3C0CDE38FB5E7950A37326A09C2311705 AC37E2DF50FBB44FF8C272FC1493F1A99DDB2E1FFE7A6765758887D672CBCA21 9D2B5841538FE1B0FE8490E0821E71F5A2332D9A7C14479025FBC64489304F69 499F2C4BF760EF7ED4B9FC5330FBF72C20FD2D8D13A2E245DD1BE65EBB4F6F2A C454F58EDCC6B7AB68072C2CDFE1A33C46EC274A77BC378592AFA76E50241080 C78275CC1D909407C938F5FD0A618B23E421A9436CCB7ECAD7A88196A2BE3A0F DB1AE200E2FA007001967A819A6AFE696782CCC9D163BFEFA921541345A94A2D 539C96D0BFCCA97136C8F5C80F089ABA0067315A92A5C1AF82C25A7FD33EC6F9 E4B6A38DEAC7076D7139E4F9D972EA58C00B7E7F2AE3015B8CAF7F6311393E78 3B3D78AEE3FBD31EA2CCD126A0E3E3780964408480575AE205B0E635E6727E46 F2F67774D1EF49261ECBF98C5D4181DFF39C8855DB4A0BE69517196CF1BECF1D 09D628A1F005953EB28BEF26A9BE5C6B9AA0D1E9EE8B39ACA25558EEAAB08B10 DC15E662E4E766AE5F6AD0EDD34E1F949C17FC99EB384DC7963F4C8B22DB6903 CBAFE412FE1AC1AC380F35CB7D1A99103E110E0CDDFD0FECF3DF1F7018376F68 D27AC36660F8B1F03444A2DD3A1798A1A62A0A6F8E820ECB5FE4ACA6A493180E 07053CC134930B868DD9FC36A722247FA31962915388B4101F93D4D5A6D539C1 1187DE78BD21561425B67DAB1C390DE24773607EE2AF66BA82F846986F1BB036 5E00B10CDE9BF8F8AC548AFD8F4148A5AA5EBABA3EBDFA308546A20CE7556074 4DAE82DB7EC7822D425230FA756406669E34C6A01D9E08D8493C66FE0B9BCE3A 395FDD517ACBEE3E10844CC72306BA961017498E585574F6F7A9308199BEBB86 33A7B09F6C4369040DD974868B311B8B99B05A6445AD180C8AC5BBC2B7075370 2B2789FCA365103EC1A2C868B224D0B6C00CA58E7A0F8C033F2369A0D6D4D226 EAF21AC7E214FC46936F3F2E2072523E9772E366F3A3B5DE53FE74A224D2F07E 49AE6A3099DD0CFDD297A8FDE7CC9A639F2EE9C0FA9671E43CB524D6BD1C2CA7 9CAD7FFC472C5FBD1538211D8FF2CE1C8897DA20B22C49DBB6803FD753A9E4B8 6BB80DA78900697BB5E15992C1EF09AE2E4F3A9942D7BA355E1549DDFA2C16F4 C03D04A56897F295BD68E4884A34B21DD08B10A738DDC4A4CE3671CFD7A213CF 273B804C27938039C1CD1E405E26D192BF4044DD4C04229F18A5CDEA0C53AD47 C30B0B80CE7F4220C3890D98A8F6C7BB98142B4950E77E1DD5A7962F22FE3863 F4CF00D0E4212FB92B4F39A2958A7619BDEF65577B24972EFA84B2220A70AA85 4F3A1D83C9FDB65106198A972823DFD0AA1DF822BB91C547733B18DBB01E4B30 2DE1067D627362649D82A5C3A57DC5041B1A13FD271E83A9484E5545FF91A279 1276736A3E4B4E6604677D0C7A5EB1A946719C3AAC9B2E347B5A6E2F52109B8E 26AFDCE6B7EE1DF3161695D2DE1F75BCF0E819F3F03D01BD28293A205D596139 7C7769B006136B06681999719AA8FA4C7D08E8238130FFECDA4E06E8BAE603C3 31CD7A43C0A67EA4676D0F49DEFA299DA33070980C95CCC8786F8081DD2A2449 15F60EA95A74CA35DAF31BDEF13875B55A6EA073080381352B13A323C4E07116 C6D5B5321EE18DD2A0B115B5166E2C1515EDF379D2F029584A3A5AB294BE6F09 3CF14E53DB93F7C579D51EDAC5622D6354A63F9C9C2BEB888D95EA70C398B39F CA4FC8E16EBBA6DE57B469AC5428EA9F3CBFD052F08A039009E39B84CA91C19B 60E01E19FC80AB99D7CD37B500E34A2C65778625A0E2277C3C0C422BF9F210CD B6CAB51E0224B555EE04A0D4803508542862A2242A4B2892449525BD879F6DB0 CCB55876580610905847A649944653406A23A1A7C3117DEE57BE09E913862F1F FD1ED143FC4FDD2B030F6670C4C2F1EDDF862F5680349FDEB029DD952FAD643B 5ACADA6BDB55DA0DA4A6D29DB3AEF260F7E92EF9C3DDA3B7E39EF6B9959CF67F 4B4CE679E3910BBC35EF490709C1B95D1D16340FF23C257DF68FD0DA482FE338 FF7162B38E70ED0FA6771E3D28A8B10837FB24143DD7851B55B98424148A3360 EB5DC9195EA582B58AF925C5AB39244F7A69BD5CFBB2CF51D1DD9426E7A7D188 0678BE305CC58F1C5EB09A9F44D24930FDC1AB837A24756316C426E5A97E0DFC 7B2BE0D3028381278306191B10DBA1FD3E6DCCA69799AB99458A9DC2023FC594 92352FF3B3F139D00801DC2871E45DD6E381C3CBEA35C0176F220BDF0B61924A 479088BFAC303E02417074061A2A39ABE0AED59109D62757C29F9269C98BEDFB 7743B5F73E9DD9F517AA80896E629F88B515468781E89CEE677E5DEDB8D88A50 8778BDDF177525292BBDA77EDB85657F4A3558D429692F351EF34E7EAD8F8ABA 681BE6914BF35145019FE5D77B1FA2AE07135CBB70B81D3D26760766EAF49E92 85814CC6228AD1E71520E0E455072620FCEB4B41A1A63D7A4862690938F4CB67 D969CDDBB9255EFA919322D2FDF6C7D793F21BCD82B75E06463312D485846B27 42A1697987BAEFCE9E6DFDE27EFB247849815998508CA48B2D86B6CE48080330 2D9A63C945C63FBF146886A8E5B26CA9895911EF8969A3B39D2398C00D200332 1D42AA66C11C6BBDDA984AB5DF28287061ADCB1449376C5AE9A9C08B3D126113 92D98075E44F1F5F3C6688051D6FFF31B59509CD1D6289EE6819D3F90CD24524 1A109F2F093E464D2E5A2874D62B72FFB6DE7A89757351FAB45E3D434C073D3C 007CAE526A774AF0CC6F8F8F93EA94FA37CD53936F02B3D5E922DDE89D43337B A1D41764BA866D42F0F6F1A396753C0897930B5919EB06402BC943E2B3E91617 CB520EF85B456DE5AC2D9F186CD60B16C94CF8AC326817CC906885AB05948B30 EC33AFD5287FA97D0495E28CC80A53D3B596B869D6E0633071CEF2E476DA325E F015926AF6ABCAB93618499582A93468F29AF90E02F29760DAA9E62563E72EAC 4BB7431A29A8162E3D720F73836FDBF297838249039AC6E44FE955F32A57D803 C7B937D5B42334B35989231A774A5DB191BF108758A1448F31C6C9788F4753D1 C98C533C29307B32105DE7FBFD6BF51B7E596B7F7D5CA0D1BDB75594A3BC0815 7D81A30458494447C87FC9D02DB9F8C32D77B3CBD60811DA542E1CB8C3EE85E9 5C4345F0826B322CEE48BAA1A71A96F1A3279EB02F2BC5EDE1BC9D3352E68C7B A7BB06637104915F869555D53B115D445AE37748E164B739D8950B75AF0B6BED 219D96EF8E372ECC6D6A145E47B26EB0AE57CB24BA84CD5A37182824A3A72C5D 2967FB0450612D92D3944DA4A0C2D679105997B989E2ED40B451F176BF0BCF90 7A40CF618250C4AF4D70A1EB5AEF5B8BC70ACE36ED752D6B933D4F3ADEFEB881 9A8CBDB047B45B3FFF6C9F82982E6D29BDD2AEA6587F3F7C7EB89C7E140F2E8F 262DE87F2A80388707177AF767B83F22F1251B243D5AD4D5EDC4E9475B2491C6 FF7F103B0121155B82405190090F5989C7677983ACDC2D2F02720E62C682F924 741F0459445EE2C4949DFFA3F94A596E2593B6DA6EC65AC6C7345728F9A57CB7 F790F7911F6890B641099C7164344F44207122003F99B9043C9CDD6580673715 926B5BD85069A0026E766C707E72810B8B6F400D1C76C7380715F55C73EAA083 3F06BEEF46DE2D939D0341D6E57F80881B3E58F3B8CCCB4C1E7696D16531A5EE D36C30AA15C66D57D654F9849D5B7ED1DAC77D33CA607154E6B8741330E08F43 DD5B7AC8BECC962105575D61683862D5E4C2CF8ECBB6DBA1DA800EBDB8202AD3 44BBA3031C1634BCD70F78DC113D19B43A4F31EC8856A7DECEE7309C0D148696 A604DEFE0B9279975DC15BC1DB4D67B315C4556EA67882AF448B9CAFFA4BC15B 304C7446A71A59F056B37F07C284699FB8123DED9709A875B020943BFAFAC56D CBE3F17BF80A06360EF0D88095025D7A154E7FAA68EBE498B14BC893D942C145 C2204CFCD6A5C69FEFC25B60E412CCEE9028680D64EA62CEF40A7A7AEB4FA346 EC850785B8F96109D35395BA3AF8EBDC1AB68631E2F7D960BF5E9207ADCBADBC 2933C1D0DAC1035A5A6B41BE612088E21787D586DBA09EF291CC2E8D8CB43805 2AC2992420B6F59810B3DC2CB89CCCC1B5422EFDC6FEAFE0B4AC15EBF58F5BAB 8C8140D3216482B9A54D6571B27DF932D9ACE5DBC63F228C049E1A64E6558C93 AC71A4C6A5E8C3D6B62ECC6CAD9D6A335B2B51F5B245A07420142F724B435B8E 2B0613F8A2B93C8FF5A2D3DC3D55944102B6F95CBE4980F020AA8273318EBC07 9696DBC8C870B8D33E71410F7719765A4C28040B982EBF822CD636877767FE35 66CBF4EA7F21411A9A3634D6F3B089045489489D680E106361680EC48EBE6F4E EB32E98EE883E8F853786F01C7DA9C846205E5934ED45105CBF80F51C80A53C2 24A2B8CE228B5A645286F0126AB25A5CA27B6091E381294FF80BC79CD9534CE2 E0DD6B628C23970D922A1A33659371366317715CC626F7E831BF74CE3D35F1B9 81F7EE3EA4E271DF33205912189E5C397C52BC4C2BB5B4E3C126E86A5B74DCFE D01B3D386D8E0239BC3C5A5CC0D198B681A857C780B0D62D7513C2149D3C1C89 5E6017174226F878E5F875A758E7D6F9D3F001C43597D9249C2E632BC441B09F 4E4A0507E01E1DFF70CC5AA7C93A953918F663F9EFCD5967B38A35A14781A547 B3621158AB21AD17EA383CF89D623B21D6EAE6345E8017074753A895EAE1AAD4 837C0FA6EC22C046AC5C032AF63C16F1DB1FA5920EF8D3E69B7A2004DF26B7CD 0B70148474D02C65585EF70DFB0678EB8A48D63F327DBF79CDCF08E40D3B58D8 D43AF001ACCCFE5364B691AEAB39C99B759BDE724C0391BA2C660B9285AAD4C7 82B78A352DB531CB99395AE14170C310DBAAFDB86C980036D506CCE3DD6D2642 91E30B06117300ABE9AE26AF4F1B26EFF1D3C9B71F7FFE245816C4E27B8AC068 813DA0D89AD945C5068FEF16B3FCA4DB97E7217A04BD2173993A968DB1C85BA7 A57E89901212F404683CBE55515C2C346EDC7EC9FC69881FBE22B9B5EC496B1E ED375C200DEADFE6A2A582D7F549EB288DBA3F827D1EBB4DA8748D24F4C490BC 023B072C4DF0E7F33EA682DEE29FF11B35E53503F2876CC364DB19482AF3DE8D EA633AA4AE7E992EE31264CBA9A1AEA5A7CEF4E1DDC0B20323AEF50A76B8FACC 469D0CA99E86FA6AB41C7C8C88212BC44A5923D43279785B68AD93761378B14B 925830DB4668BDF25447197390B8B4EA4BD5D79CF87BF6B51365B7A19451930B BE55D51282AE795B4E344E6366BF720AF3379FB6EFF57BD45891E1BAD974D615 F3EF785ED398A59FF54611067623E6D7C3405F68F960AFF627CAEC15B50A0923 FF134852A91EC280EFC39E5C64D41E1AEB438DA3B27C6B5AA7546849576D2D36 FA25B42144AFF29AF83BCFB9579E1A1555DF1B07904CEBE893D9BBABB5D51C7F A81737EC5A26A3FF7A6BC848320FBA6055354AAEDA4D20E6B1D535C35615126B 6450D5D43C08932DAFA03AC72BBE4155099B7DA7995B50D141ED146BAF2BB186 BD9576D4B713AC68C61FC62EC3F91690CA689C385C26946471FF28FF88D02FEE FF030A06557CFA2C948EB0A205D07FC56BB538164DF12A5A110E2A139E34F332 D53B3D4404D913F35AB9B9F693FB477AE05038AD5E0902B89089B79CF9E490FB 98EC17C2D3C6662F5AEC5B3E6BBA269C7E1EB46F8331FCE6CB806EA656657442 F1FE5E2C95CE7B4A3F2022BE0C32404923FC2D76239AF774A17DF19F138E34C0 1E49A439CAAEE31D8D1D06B122EA3EE1ED3C9DDE337E246DB857658E3B5D0975 1B70A9AFF6A95A2D2ECEAA065E8C2C776008BB6305E78E0353432660561DF5A8 23BD9E85160C3CF60CE4166A76736A4F4C09062CCE74B123758431C01D8FEB4B 7EB6933D825F5FFB9E1EBB7B937CE3B60DD1470666A51C2EFD57B613E84579C3 BCD3541692A7655F344A26AD621CF96833C4E93599B817A3031BEAF016845FC5 8B4B2ECD374433C9F4434DF80662D863A0B3A7779551E50522A21F77C572B978 001A259176CF2326907C6AF3DCBF506FCCF791D0A11D77C07385C9C279F564E3 B87953672D93098A5351072B1DCC65151721810CC0CC45369642389072C45B32 4469658F5F923E46C6ED966207F7E440E58F04E375C827FED0B88A6CB7727ACA 3B7646C4C5A67A40EBDB52A2F8AEDDAA6FBD95C1F4E4567E1C4027B38A5AA975 964DE0CCC2C5625330A99E3D0167DDBB9A123E18FEC08AE30D6E479BACFDBBE8 518A313B8657E3F9202484FEF8A2887C2D3DB18F18FED14621DA0B0C1A92470E 3AD7F12590C5C568833CE90E52D447D8590B042156AF591FED0E2CE64D636D0B DEF95C724DAD9EB649304AE6A12EAF79A76074A23B3A259D50B2B54A972B3583 04812979B655082C54177A55FB95FEAADE45D17FFA1070ED3923E8C364FA7130 1D510600914596EB37F25BE56C023CDF022FDAB725C5C3A4C199288E5767D688 1C64BEB83454D1A9C030D3519A41D1E848CE9B462C6FFA3F772296306843471F C520F7B41A800B5EF6D1EB067757A77EA5974782E28EC0D66A5C66CB955AECD9 22315173DD7B4C3EF93CC74AAFB110CA417A25F88602204C51DF6630354AF0CD 347690822B5170C86F29CD533D78CA1FC133A1ACD03250D84F5DAA9A96475635 A4354846F255BB3F5463FE2F88924A3A613A5CEBBFEA874A25E88B62CAC3BBB3 918A5FA98D62FB990E89CC3F8A6ED17FEEB5A6100B7A8F96E859013F470A42C0 1E16E21ED33D4F5C97B678EC5888484D874A723D1CAC0E6D24657CA378211027 A99C8C64D4ED6D8494113785DCA65CA4B9ADF0D14B8B04E7D394539A95009FA2 31CC5820A8AD3498FE4F21A08AB543ACA356EC3DEEF4E7EBC4E3FE30552AF20C D3475E9AFECF67E9886066E6231587E971579D55A00AD65DF8A01E03B674AAFB A0CD527A 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusMonL-Bold %!PS-AdobeFont-1.0: NimbusMonL-Bold 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Mono L Bold) readonly def /FamilyName (Nimbus Mono L) readonly def /Weight (Bold) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusMonL-Bold def /PaintType 0 def /WMode 0 def /FontBBox {-43 -278 681 871} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B892AD5E69ACACC6C1640EB 3067BFC64938F41636DB8831883BDDABC6777DEE17F2E84F1D530BC76F51C621 75EC6B727A82C193D1C0801AC492BBE281B46626BD21F2ADBBFD144793EF754A EA5F1CDA3310E83D78A098160C66D6B0C68D4976898D9DC1A08D01740AC3E7F6 8D3CE0A7E109104248CB86318400BD82EF894EFD9C9456E97055286C144D3EFC D2625110F1AE76241079BEC19939AC962E0BA813359C15B07C74D5E9868E2167 EA1199D21CA8827CDDF1BE8357261BD32E79FEA6BC475577C5F6848345BCE58D F5435281572AE6B33B53607EBEE6F862D4C752AEE43C00CDBFD258C7765B1358 5D6165EE034E5815DE79CC26C4A720607BAFA6049710EE3782BC2CD84FE2473F 1335D20A3B6E9E8355AF36673CDBE63C27D4F0E183FEDAB10031B1EE33B9573A 2E1961B7C6BAA41F7C3EE707FE86071EDE5756A00D7B3BF0A21B7C3CF41093CD 66ECCCCC22F4534912CB900B08E69574B07F246305DCBC238780278AEB8C9E55 3D096A944EC7AA9F697F354AA137DF90A9547EFEC1CBD568CB999979F5AEC6AF A84EDAEE1564D178541CF4631081781608FD38964257CF89B1C8E0120B3F6AF0 793597AD553CEE5CCCD5C4F09CB0B4E998E6E76243191AF7E93833D067833F0E 53670D7E996ED67CFE6699A6E3815932AD272AF4829C2EE087ADCF0907563885 2FD80B579D06B438D930F7F724A305C4DBFE50356A9055C9BEDCE1EFEFA7221C FBE92AAFAC5B771D1E94A2691739B88E4F2F81EFE21209DD13BB4B1D54F50134 66FE35AA58A7EB7157A76465686B6D30A4F44EE43CD621EC0332FA04C6D0B87B 60DC612AFEA9165CAEAD2464D8D80FF6C61F4410BE7699FF1E4AB640AE74B8D9 24E48E8EEA7BAB1F7EF9D23EC0FE8FBD210694BA937FC0B4D6B53B53B9E8A4E7 8DD7D1AC997867EB021731B3080974204043938E7E96EBDB545806ED3373D164 87801F7A6CFE211D85B983726F9ECA5C9BABFA49E8217131544D9B05B28DE2EC 78B6AE37A5F519398B89ED671BAA88D51C54E3CD0B91088F3DE113E86442C14C 4F16926330A6CF2BDA9D6BD6808FBBF4CA6EE6C43A7088F1EB02875C24A736A8 94F1EBAEAC18CB4B7D1983C85DEA0EFAB41D60A63F3A1388DF56F8DF22245977 66D01BD59A8F5949B30ADA383485030AEE93AFBABB827D996E563D1247008C87 1F77FE5B882AC9B443AF67DCE9D17E2903955C1F1B0F125261DA0D2F7312CE5B 3F3A1DF65E961E7CF1B65135F07EAF54D944AAB77B61B0A7EB459068D1748639 DAD902F9BFE6EE602DCBF09A3BCBD763A3306EC5B8DFD78A27E926494D5F4D94 DFCE0A75DA6D466F2D1A2E8D3BBFE5B60766FC706C4DF71BA32EED20A96E8F44 30344988EB94048545A761892E4FF024F40B331D853D2C54E5123E5E2F843602 DCE3A8C8C5E9A92F5BD3EBFA4DE86C497987700E9FA4FE375230B7008EA14C41 EBA75D41C7B997E60ADA11E5359FC00B753618A374051DF4097191C6BBC815C3 DB9614C69F0ABD2C8E0CD7C390086369D35D3E5A083C3DDDAF5EE41814285EDE C18B272C7113B1118FD1A2803784CCB5E4C8DFEC0195E99B6E47CBE1D39D1688 196552256E113EBA77A94CC74507B84868330F7D9D1CAA950F8A1F66D4720DDB EDC0E0857B057D019BB4C214C50AA3FECF8A05B094AF75E2869314AA2F33B098 683FC2E8D8E14D1017DC8428791C900E377B7845994F9B4238067509B89C71E9 B881551E150BAE5EAA9E286AD172CF9DD1B8DC9E23D1751721FA293BE262D473 68244A2EBBB9310ACA9EF05193524C4E85AAA0DF5604D7FC78F584294508A53A 987160E858F76C4FCC9C8A286C4E76A6B2EAEDFE2FDB17FF267D0F21C3590DAC A10EF2A46B53BE1C1A79DBAC9CB39A6BC253A90835725506113918E5F29C3C66 2800E45BF5E62E68BF117158A4FBAC084708A6D5BAD32AE7178C9A6EA49B0C46 BAEABE84B14ECB5C44029F31424206734017DB13083516551E7BDF1BFBB7DCA0 07DBB44F3C4C440108084AC2A4D0FD15EFFAE30AF47621948723B39286131BDA E14851CB30670CC5682A54583836894DF1690AE3200CD9B5E64328E0B31D43DA 5529BB528DAC73139A757CA11233A368C666168D45B8D27B59565E840B519F7B 53237A6BF0906A6DFF38E77DCACD3AC07E4CF5EA532AA886EC057F20839E4DDE D60F0FB052D103AAF94D5FA688675B55D40FA43C6D97741D9FE300890DE811B5 C40572093246905931BBFB2A882A3A2D7BD88388082E54DEA0654438F36357E8 2DD0F837E312FE1AC1AC380F35CB7D1A99103E110E0CDDFD026A098EA2EB484D 0FF08E196EFC5F2CE715B765EEB781E48446027A7574E504F98DB9D52D84304E D2773DDDDE31DA02F9E80970020F8C4C9D94ECB95428EA04B2222963DBAACBD0 71C3701EEB814F06635F9B5BE17A8D7B70BABC5FFD5F430DA7E226941D3C4B6C 268F761F7478509623114B059BDE45E06DBAAB8396B4742C489676BF3970EAF0 3D028CE2F1E9211460C2E733150577295F4A4A6E8ACC3C497A4BAE5D53523C33 5E8150C8F0E2D45F0CB63CA557B037EEEDF2AC2B228F3794DA6FFA490EDBEEC6 62169655F6D78125EE5498BE8740A816C9CC7B59EEB58335FCDB592821C7797C 11747443630B04990EE1BE9DB5764A580222B273359DC00B278B799FD5FBC004 0B0DB844ACE08F8DE270F25B5BA2F0E744ACCF23EAB3C9E0437A2F11AADC4469 6486E4E0A6FC3A0C6CD24600D6CFD67F9DA4FF1632143F902DCCDBA5432CFA52 75860C2440A9240317F636D7E4A8BE49E509096D398C0EE0905FD38191E4665B F15540DD278DF03F8DF9BD23ECEE958D62F8509483DAD08F4679197E3EFBF171 15FDFEBDFAFBDC2860F931703DB69BE8119178A26529778A11B5243BD888E71A 3DB2197C5FBAF0676FB8745EA91D546F69182F57C4688224C73B748FA9792731 843C27A2C18B8582B6FF2D1080DAB1E06770AB96F6075CBAE6BAD816F86A708A 6A1EE728AC6AE892537F41372D59A602F1DF94547D93CE0280FBE20D5E9A6F1C ABC65C37C9CCBD19191AE54B4834E8B55716126FFDF105C58835BE44E626825A C8C9C71DA39EAF84D2D148E1843D354DE9CA3C036D6D31BE6393730E9182A7E9 846B0C9C8DBDEADC479C6184CDF4A61030C82BA7876E382568846FD52110999B 1647582D91BA6FA0CFA8861BE3814E034C1BDD06BC0ACBF3400DB1C8C3FDC65A 218FE065BE0A0933C19F36D5557E8CDE9B86BB0D7806B03A4DBA015AE5681A99 559451496988B1682D6B23ACE310EFCE2D56E237004932B232540B46F2B1C7D7 9DC60131AFAA4B92B0A965BEA31B1EC7035C2A626853C90F574E443CE79BEBA9 7AE481AD4AB1DC86D8BDB89DADAC3DFC754BF88042FD98C3040855DE8339B25C 51257639CCA1BE7B257D8041C6E9DEBE123998F90487692E7AF0FD34FE48E2FF 716005C8EC1F5C7AF9C9E0F8623B96E4A38C1576C9EE90FE9E0A9F5EC4928A31 B81CC919BDE36680C8AD10A56C33C4B06DCFF17C02E3125F06F30EE2F085B06B FE3AE025A0542F0D7F681BFE20E27C1C9239E6AACB28D629AE862774434D8A97 585B1BCDD3C0D1DB8D8AAAB5B44E508D27568E1C088F279A4CF85ACDBE004538 375B022A9EFFF696142E685E60F5E2308D1D584FB2338FFF33C78D24ADAEB9D7 A27E777AEC84C29DCAF67983001324392443C7ACDF51F295B43B59663064EF6B F5609842135D353A4310AC11ADF1C2952D9F6DBE67B70FD2FABE8EA2BAD6CFD4 77828664530D6B1C8C0A3AC9AF6F6FC107FDA53F0A3C3BC38D8E1567DA508BC2 3AA4D559F45CD67EB8BB33418E2837BA0015BC64ED1C8DB6CAFE569E7AA5B9A9 AA4522C68513F331B7C82C17C2806104EF6C23FE114747EB3CFAC37400E73847 502BF4A104BCC46E8B432A9F7AFD0177246FCE4473932308A1DF7647D2A06E4E 746EE98B9667BEA5A1A92891F1DCC94DBC73BD829BBD0AD78231C6071779F13D FBC5409DABBA86EDF474B96AE5E394295C40ECD7DBC270B2AED052F92520349B 7BCA23D2A8BDC53ED456183BECDB5D4FCB3EE3F5EFB92E5719D8D72DD3CC336B C012FD2695838AD55D44525B61A9471C73F6DC14A50AD3B022E789F4B44AA426 49375B491D30137B064FD8C1D6A0083DD74053B223C0D79C3C0FD804C49181C1 5906F4563F955795B8B5F0761C9A4B03098C2181BBBD6ADBC17D34BC852D40C5 718C0DB10075221D97D381CA4F1835F2E219E018AD7F5201105C7598C05EE79B 8E27D971F759FCAE6E68EB03C5BFC7FF76F7FB54DAAE8B85A4D197C24C3FA4FF 19023917B221968166601DC3B65ED9D80267F2464903F6A734644F465B0561DB 21FBC04199F3BD85D9A1C88BFDD3053341108789CB7623E70D5006C951178E6B A35114D0B8D5DBFA2F1CA5C38629390622627FC6453EA292BBC6F33628CE825E 163FEA3BE751DD38581BF331B7C82C17C2806104EF6C23FE114747EB3CFACBE7 8A7B2FFB41C4992C8CA30CE5024BC62C59AE5DA0444AA91EBD84A394F47883D0 4366386D92945935DA0D3397A5688E0D0D7CD1CEFF5E355D691E098D1FB67D78 9776AF6F6BECAFED14399A3C93C0738186FC3EDAB2C857D92A39F57DD65F6A27 4994CC43FCAB6673C3E93DD73B6963AB72C91960A0116D9BF13B795EB83BD496 5D6AC9C1B17CA669CFA370BF3B0E995D1CF1303443289AB00DE52711A9771E23 090E29A1A2540624E7DC863C06EE313FA36E4A165BA63356A5C3102849C816F4 58C0AD3A1DCB20A2A2E1AC8F388EAD5A58B78390642461B8FA0F4D50C9591175 3A604969ABD53C4AD2F363F244F1DA5B705DC193EFF1482CC65C325C044D4487 13020348511A7BDEF3B4D27C52F562E349EB58BD913DCEE9903CDAB1B27E3E7D 339072CA12B6CA1EDE84216CBFA6B5B288851F2D12981CDBE72253A1931F9E94 A3D96A0CACA7DC16114AA6AF916D59437C10F28C43761EDC0E66A5E026E1AEC1 807C0C1036B2DD83C5BB5CC6161D7722B3ECAD7CAF35696A65792B16720DAEAC 440C578B2E507397E65DA26332D6A5222834D8F7A8138941F7BE5AC33FBD8E3A 9C325FAD8EEE7DEE035EF7522B4AD4AAEC591A79A531C932BF2926A25D967349 244C6287785704BAC84D45763B67768AC526ED5A2A542DE097FB34A24BAA312C 984C3EE67D79B034885DA04574FFD7E34E12305CC55CCC31B40CD0DB336FF5D1 07D503357E7CE3A8E35F8701BA5BE8ED3B3DC028E66C752EE4D03A6FCEC59387 A057AA11C9B137D6546D59F7194A035070FD4D4810458092A483DF90C8F47192 C5B768A517BB819BE4767526F2C79272E398A48E5761D90A4188DD342E52260F 8C995A4F0A8B99E733AA64B7810BB0CB3A7A28773303177691D73FB9346B8845 C28BF3A203377F7D1E8BE50312DAC1A92F21FB94C2D83DB824E49C4FF7CC1E3E 8E55CF3737E212795A6B8A84F750E48780082EE331FD89672692156822C6575C B3F071AEACB70CCDACD219818E10E8D94B7395700D209642DFD171DE8593128E C7BD38BDDBF2B0B946BCA17B62F4CEF83483B3FDFBA5EF6B5D41BDE563D565B9 3E7F3FD95ECF5F8B0878117ECB3A9FA8B2A1FFE29587104BD72D34682E686B99 704A0A51E40E36A1B0B4C0D84FA358A322E9A3E55C6B67D57177A3FE64646554 D9ED35244CCC8904BD693E1516A9A531AFC767732BC332DFD034609578A9B650 1AF7F5566575D149F9AAD8241B5A21BDB7FDC3A51346BB86D33CD66D069C246A CA3E18F44C5C03589E48F4201BD56CB9B806CEA6ECB70AF28F4A298A85DB26E6 5E843A7788CEECE0E7F191044398B2985ED21DD12BEFDC74E9E66A8D28369D13 CE6922640CEFC8EB611BEA563CD0AA32D2F11842647A8E3F5A9D126E57D9C953 20DE6071CD9AD7F45BCEEA1B4284E82E7FDD2FAF68E9CFB737842DCEB6FA4AD4 F3BE09128359867B0C4E17129ED3385378A87BEC7BD5DF0D2257CC2A9EA95141 D812A26AF3E3161B78A67E528170335FA82DD91187D441F2AA90E1FF232FA95D 10FAA84DFFE90A240EF474ACBB9E6B0448978D05F212248D02EA353EA83494AC C967043A5047B5617E6F68AF3D52C8AE387F1D4C1748C24CCDBE96848EF811B4 AA5D156AA329BFC8D884ADAF7DDD9537C53AA22BC69286E8CA573EF0DAEC4968 A4CACCC2CF6333DDE1601899ECE72F0AA5A878C2C9FBFA5976717495A9A038BC 0F31BAC5CAC95B70F00BE91A3491F07418C2F1DECF0B8DF4EBF738F6A4505220 2C1D6D0F7186B0B6CB9AC90791E46ADBC8B30C50283D339EE6A62E1787045C73 AE79942264B3DB31B4D4445F541EE267B888C20A59AE40E7A72C6BFCA71F03F5 7477344E2682F728CC9A59F07D8323942DBF20ED6CA129B7D6E1F0DE2B16E6E0 32349C0D2F9DACF4F219F12B9931C6F3D1FFA10D2E2C2F89541AA2BE9686B619 49627CF2FCBBD87D4FED2F9CDB63D62341E7AA507D55F78B1EB8C11886B05918 95F99CF8D1BA2E5965A8945EEB08AB56F00AA67B272198929DC0BB161417E85A 6483529EF19A0BC4AD940D0B1BCE7153E7CA0981CA190014322469DA7084FE04 F00CC3E02E668D5AC0718735E56AC68D11114CB06100B29A393700A4995CA8DA 80AFD216C7B7A8109CE85DEE91D8D773E5CD3EFE666EFB25BD7912C28440E44E D3AF0A323F4ADB043F9AE5B2041597A8A57730469F0A0A343AFEC737F3F93C72 D013048390B9FA2D934D3A34B84AB40F842029F8E3BE77EC191BE38A96248857 1DCA9D8435FF66D32632221E099CF9616188C20F1B99D7F5FB79D85CFFCD1899 9799F0203CE0E63BE2711921CBB57D3E04F4E26656DD8A36663CADE529CE687B A6EA70083D55975E726F288711EF040EDBF409DD9C7CAC85CA83885CB990B382 8622C2F9D5B4B9175F909F53FC7EF3CC9F9523C68EF42D9B07CDB54CAEB3CB9A E549CEABE1F0D295576968D4C3764FB747A00869D5F64B3A974F4E7D45E1CAC7 CEDD67AA0554045FAA636D4FECCB448C4666146A7EB6F4BA4629AAB2D6F3D8B9 583D878584AC3BEB8434125B03AD986D52BAC5224210E44AF59BFFAE1D9476D1 CA0D372D92B60B2F1E47D583FA95455CD20C7B2F95CF6510E7FEE3FD78B94FF9 8D6287FB8AE0613C0947FCF0BDBA0F1368D3E38954279E5FBC1F34E9CBDC74E8 7B613542F58DBCA1007FF58CD1A3FC79B87E579DA191A63FAB427A45CE4DB5FB 80350DBBB1002AA8E5846FA9259C25AAF35857B18A048DE4026A986B661B06A8 8A03A5801002B9022163FB04B2037459954EE58F36CCB4227621D3749DFF8289 8E01228F3224D86DF9657327D41340F9D2987CF9462B74259F19F9A26A6A3912 B2C93802BDE85EADD4486E9CF37BFFDF8A7932DDB61688839B0C980422DA618C BFC03A7AA614FAD29F64228CE7AF43956360D95D5DAC9009FAF1D1CAEDF7D879 DAC6A93A6C0E4A2AE7B930B69005A3A2C1225FF0F0D1DC4059D79CEF1D6C55B3 F1ED51C694C79F3FF3AC98F05C39563FF74AB96D945E03481E0640B8DD548160 E58A8887E0028B00C438969C2EB8C4646E484F7A53A2BBEEB284125E634C71F8 4A9BE9E92B7D3A40B4134415BD7C7E21C17A3DADA085369937EC131E405546F4 2C884FC509B07EED26EC0AFF52F658087D5C67D702AEBF0B8C4A7458CD969A7D 3CB2390AAEAD3C15E072DE0A84250A834EB69F42B4D0A858F8A3B763760ED716 A244008383491A7DB7178BD882E77D1781093F956E26F8437E9BC6D5A633B1C2 4238BB910C11D2A8024C89FB5DC745489AA05C4DA0D6440478134FACBCE4B996 1FC5AF117044D0636FC32C2FCEE435745272FFE8FE3D126BBC92804717481702 9518A84A313834E9E3C9722947CE7159296450F6131422FFDE5BBC3AF8BC50F0 EE6AF1B93250698AA65A35C691E3688E6A0EC0E65F5063436840DBA437589601 A9B654E3827BB71922BC9474D03BC93FED60C90211141C728F397A677D32DEED 9B4896E372CFEBBCFC66C585CCD484E59CDF6ED7F482F6056F4864EAC69C5886 09A55801D9477A7DAC80AF7C8244917DA635EEFA010F64668CDB67E8ACBA7603 ACDF0BB64DC77FA78F87D3790E0DC1C9D2C6BF444FE9559A1CD46A71E1847119 E030D5FA52F1AC6564A3371420EA9EABD2A144F20F58EB4D6574CDE4FFCDC2F3 625DBCE62375D1DF3471D83495B1933747CED2C31FD08731E0A3A099F8070976 D75485DC48C26721979A92FBEB7B5DD5CBB13A886B8BDEAAFFD173F605562033 0912C3096974CD5B1B05957074DA4CE5903CE48ED9CAF70948A4492B9886712F 81E03850B816E8ACB88C7F755D67838B8E8B5A35E6BF9BF3098535D75847D944 B30D7A3FDC11F99AAFC2907180C659E171B0BC0CB9863FCB2BC115437316194F 2583C296668F5541C5814E5A085D4DEDA1E64E8F09431633C3E5A1C1BACFF9A7 E0BABF3DD73B968D7E025311BEA11FD3D09B4505AD39075705610F6394B36FB5 8D6D2AA14D81F492A56951769B91EF96425FFD14913CF80C1C63381CAE11715F D667E6155DBA5E300663BFF1B1FE9F4AE58671187FC428E20FDB4DDD3E54A6FC 00F6B83D33DAA908377AA57FA1AFC32EF9EB9AD584935A58676976DDD2B6E118 FD1D4640256B973F431065DD2EC6BC689D4B4F105C8F95567C26320128E6EA1F BF971CCAE4F84C16417C62E58916066D25C0685B03F604B930772A4D52CF1E34 80229AE0840FFB590D96D0908022518338243E2958069A906E35BDA6777D0326 90907A7C3E858F279C4F87B0EF573AFFAAD4B99FED6B1659F5CD2BF401D5C2B7 B77EDEAA2C9BDAB21C5E32BF12661459A29C833ADA714806275E20FF09B8D0FF F0DE2E1B4DA03CD62554647D9EFED063634B5C883A007A90DD46CA11F88B6ED0 44C2A8E384D0AC7E47DD770719649BEDA46A751D0908C955B4459C6F41B3B4EE 5BA9AF0870C866A1D41FE2EB7ED33EC5304779F0016396B6A2FFB0FFC63B7D9F B5909F6698FB9C43E661DE5A7465E96A2D015EA60D423845781983CCC5CB67D8 068D2E9E40D6BC23502E3D58DECA9AB6850753E64E1DB38FB4E7E2D0C8610568 4A4C4E9DE8DDD6546FE1A7C015DF2111B1F9D3FF161CBD33C342E2F74CA0021F E1F9F7827AA2CCEEE526D038E5D31A91509A5E120BED19581CC6262BA89CFEE8 4725E1C7F88B62B7170D9E98F32DD24A68D268FC84E43E3ABE22480074A5781B 3FB0B2315A2F09E5E3530A3AC0DE780CEB041E36DE8729E005E640631B2A7713 E923F5A167265C920201768703BCA23243205F6C7A1F1D0C79BA57ED3645DAD9 EDD408E629D39B45C59BB43DAD790B83A021B9E3E55B3A621157BDABAFA3FE86 AE63F99E850A5350447FCE2955C3269ADEE067845C05D7FB8EC0EE9C548BB3E5 7258789C00669394A8C2805369F4740BF0B9F3753808AFD0615AECE57A4FBA52 3F6CB203E596EDAB4F000D0963D5516FA27440AA6678E29181DE570F454697DB AE5E1337983681D1A3C97E8814C708465EAF87A3807726601E44E043AB4F3C6D 4BDE9E891FAC24865BA36CFAD3C4F20C45EFE393C4380B98972ABCBE89B0BD5C 17D6EBB60F44ED5BD6BE2F6AEAD3B8C40F1A99931810A7C88943344A37D5EA2D 83045F6B6D509C534A5315B270DCA401EDAFBE8A3F9F20B7B4A96D6DFA544A42 3B23E5266E8325A6B0CB5A26BE8D345869D96C57CA6FC8E5FEF5413288208B4C 39FF9D042A9873F374E66895B1C08FC9B62D6CD9449DF982FD660CEF70945119 77DE4667467B9E1F9D64F5D42DACF4C8C15266E99539BF12262045EB754C9E83 67A766C2EE5D2C7A81BD99B530FC2C1875A1E6C0C9EFF512FF50CD97A8773303 AA1EACECA34151359AACFD8F0FA25E4EE035D7F0B1E88F6EE400C38821DF2A31 9A5F6C13F909F7763FBC29D8ACF4FF60CEDD9F82828BCEC0A50FAAAAE4E8C417 96D93B2C31D8962FC168CC19F9D9448BF5D534FAF63ADEF3C8FCC742F5142132 B35E64C60E8EFC830B38FF447820EC9DBD0E34C819443E05145748ADBA785D94 7F0F840E68ACF691393EC3076DFD9A270FD869FA82505D780889DF9627029027 937E48C950802CC70CB487212F0F24AF6696EF42BEE11C18B73AC3F8BCFB8597 8800CB1EECA4A9775F04E861777588A2CD3A4D48D9017D5C73922E197EA47FEE 4F47EACE75DC9EDB483A3B964A46398552803A5A91904FE5DC78C113AB5CA243 CAF2405F43444695BD6FF94F71066DB482CE6E42E304008ADFF1C64EE25D7812 1586B3613903D3E8F0629E05E8425E62D53ABFB6C657D451E1F77DC830FEF2E7 E913BE9AA33514D13CB1203C636FDECC07B597918A0893F8342A0759368F1226 789A4488EC4A4842249083B7D936B9FCA174D9A3345202C66B11F3C54B70B338 7BE2AC3091B5AF8A151C0BAA2769C5D8294524EDEC0CE342EF13A8997BBAB9B6 A1A4599E14615E279DC7A19128E52B35B0114BE3C40B270A4A948FA6C536D97C A38084E19EC3FC1A4878FEAD0491C550A3CC926AE3C26F7D15FFFF76ED5DFCAD 3B0FAFD46F0BD228E7A2BB94F6AC0283724352768C84FAFAD2E391D8D8ACA1B6 0FD4E7DEABA9F26660856C27F6FDC7C6C97E9739FDE2F4123065129711D3BA7C 52C08E079052739F72078AC0363690F690D86AB12D1B84BF8E3C657A07C88AA8 BC7312B8591A8CD60E7B642D5E1E10513747C26222C1EBA89417B994AE6D4C73 71A763BB59A6053A8247118679FE3965A0135186D3267978BBA80C36A7A61710 1215FE163F993A81DE62BCCC89BE96CB7DDB3DE223C90DA54EDDE49A31B31DFC 791970EB59FCC59E348D8A6129CB2E34170FF589E9DBAB94AB432C0E4CEE847F 47D523E20371C958FA65ED2BE7B4C6F5538E7F57DECDD353583F2D723E541F14 3D0C1C43AABE77C4E6550738C9F45E1515D088CBFAE0D00A39074DCA541D9B73 8D055225CD6C0A9A30EF55F31C966A34E90AFBB90DBC32EE98D973EBCA004DCB 8B4F155D8CC8E37CAFD31E41F9E0A86E4CC84EA109A44F84AD783606C20E6ED6 80BA35C1F7D2E5967F49CBD302A69EB7C36945D45EA2AA928E15E32ED01AF868 01430B9E7630EC17A0434EF6C44BD878D369A5C2BC4D3EADCD65803A5316624C 34AECD4BEC97DB3C6F5E67F5D752E5786C996DB165C47ADC294518EF2E922D73 5F52A12DC081BB2B2CCFD7F3AA612E0FDDA646C82D3523D062A57B8E6B02AB55 DF2BDAA1696CB797550697204AE4DCF7A673A7D79567E24D34CC1783193152D8 CE922F79443F16E947426E2668063A416ACB955079C7F24FF68FBCD7526CBC7D 58FA8ACBE3A0F0EFE6D62891A3D23DBBBDF76DBD4EE51326F42414A3B2F09390 75C297D75E50849A911D249B2C73F81DF9B738507DF9C6D0483C8BB42182A1BD 35B76A463AC9C8F3994CA3EB5B7C6AA5248B0F5F4ECF6C02BB7D630CB71805EA FE2FA8B77714202D245A862C26B065507E524B65BCC37EEDFA2C60E880E6113D 936E5B68D2688EACF4F511F766B49771E6C1C72B51B4661FF9C5AE0682363550 78F0655CFFFBBCE45AD9E8EDA04753DDFDCD26CC3743ACBD0DEA052F129DA6A4 4A2A21C4F293D54CD182E82C1F2545AADCF90989BE006375B07CA1E80B373386 131444D51C1D6AC063E2B8EEA19E7D3C14EF9FAA19BE598B76A2F9B51DB30D16 133FE5EF068DB62097BB8146FFC53BF273EDD93F25E507CCCB8D8AFF8381747E D6A5B81EEB5AE4B187B01DF67B02E97A221945D582D4E48C028627A1C0CBBFCC ED89D3209870737ED84987BADFA131CC9E70D32AAE93BB7C5ABF7E9FE757E44B 181FBF2F94F7735A1F1ACF02452EEFBCD2378965FAC5298B252C2D470BF4C59A 639B0B7B5F2D04BD84FDC979C5AF305979E9DC87ADAD53D3BE3483D09E0C634B 0BC872F1B09C9EB5DAB3923505B28959FFC970E085C4245C6080 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusRomNo9L-Regu %!PS-AdobeFont-1.0: NimbusRomNo9L-Regu 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Regular) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Regular) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-Regu def /PaintType 0 def /WMode 0 def /FontBBox {-168 -281 1000 924} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E152A40E590419249F2E4 C36159F8E54B532468E36965A38646781AB0B7F6A3E851FD10CAA49ADFC1E546 2FD2EC6150DC6E19523050F6148348A561AD8D2E2721EFF8A570CB33460A745B 926C889304C09753C2D78FB0CA95DC6DE5B8C524752C83601E7E9F73DF660674 F05AD83A166DA9BE89F22FEABD4B2665960F6FB5BC32928E1230C212E5D69CEE 0B3311A1738A11747AE263106916D8E95F25B25B4BC6AFB03B79ABB95DDA518B 41A49458111D2A1433C043627EF9460D324FFE22935F4F6DA88B8B91AE95B34E 08408A34EC8EAC3F65B6AE3E3E2524867EE9D29068F81E4372F4470BEEB4D6BE EE4DF956BECC0CB77F8490117B22B2FB75C938ED0A5E208D88BC38B2AB8B9CFB F1D53084B6F43DF336481ECA0AA2D5317BC83FC0E1D4DB01D0B7707EEF217E94 A7F985102DED27D8E8B009F7EF6DB91B91E78BFAE7BD688E10B3DC9AC77CDEE8 47AA4DC8EC78241E593D26EC7A60696151A2AE5325D736E99E01BDCBDE69579F 92EEEC224B6757EEDC64A75455BB665DF42A0E4CE7B99BF3E7D66F8FFC8C13F9 D7A1FF7A9D5FF7AC43396779F11C9B008C33A2043D48B61B88B03104B1425F09 675B559CA4302C001EE80D2B739CC0FD1023BF4F1FF9C01E892E59CCA7C26011 B8E0B6D29CC29FC72792FDA5E7D5D88EF98F9DBA960C96534C399C54865EAB86 0FA2E0D6C7C44B553EAC1574D55E7970744D4792FFFBDCE6FB4365BDBC2965BB 2E9EDAD9E0EBF0B620DB415AD98297F5AE83D9C710436657E74D26E83957C745 89834337035A7501803947F6880B70E56A3A404C62D57B849D28804CBE0F5884 435A0E12DCC9BA414ABB732BFBAE237001F557DEA5E972BA0838A3C7C9EB75AA 4A050DA0A529BDFFBF9011C360564FD17A02C18860AF6B86EFD4E2C125686C9A 5E114E95C71FC89A5DE9C589BFE5AC0480CFF716345265D2435EDAE67CFC4801 5BC08E7A48D683ACDB91E05F469C0C8919D73A5D07A1CCB173E30E76680ACB09 02A40A3E11916198BD69F1A26E88330F50692D0D5917E99E7A01B327413E24AA E98EA484E45897E6AE4D6997B6E8BBF61C9406E916D56985CB2BD297E8ACFC6E CF2D2281AD84696B7C6CB584BD85CC20BA14ADD3BC3E25DB91124C0ACF22E902 3CFBF04CC40DE331991E9075D22AB5EE0E849B340050E6C417C664A782D05549 DB2EF572F193B1C12B4635C2B358747046DE5858EC32B3B2E79D42750657977F ACDD2EE5A7C9320D907438DBA63AA05ED410FC7000F53549091BE71BE45DA4AB A315F95B724A60F17C70833E889CFE7EA206A7ABC4393CB6EF47BE3700BA5638 6831391809EF8384AEA8C22735E8062A9F9101ADD125A321FB65399CBCD9C9E6 0F46FBF271B2B1EC80832CC054BAB5CA80D4561DA0A380D56D5CB3D90AE89A19 48CD824EB1E7AC6127A6DBA3E8EA40F00ADD89749D77EC0EEBE26FD6EA5D8CCE F7239681B3D94898236AE92FF3912E0AFE84B6C7E08134C158B640B4AECAB5F2 A90028E67D33DF31B461A2846F83D90979BB22618E2A17C5D159FB59D5177E12 EDF1320F596E7A4C379329ADB367F92BF2869A9A97398E0C20F5F017CA9DB7BA B3BAB72B87A7B6BF4FEBD03132F9075C271F2054078396DF8403DC91461325F6 12CF1421F3099CCD799C2C099492C4F071336D985C0C360B2F5A5877FD00B6F9 2E5911DDDFB31D17A60124EE8DA6CBDA94196D7ED42804610E4F730DAF2F2D5A B767C320C62543E26534314FACAE006BA2064623902C8AC479EEEBB609E8C3E4 1516CE412CB410BD026231E22A9CD0F664D769E4E45CBB75B7341F06D8E37285 BEAA9AB71AABE3CBFE5A348681AA246047CA29CA6B442FEADE254C7582D32D3C 71B5E645C82E92F057EB5F859BEE23DAA95C575EDAAF9896D6C10980A09DB34E 084C8A754E31B618C6991BAA856CB86877044E10C2F189B284E3195A2DB6B910 2574E2461D2FAE65B7321C0093A2A34996C0B77123503E9EDC623DD02C44FB76 3C550840BDF969582D226510EBF89944E59684EB2E2C463E69702266FBCF8D1D 4C0BE400495E227B9CB21C8086F328782CA7294DCF3ECDC1A62714143A4C1B98 E5DE1DD554FBA60571188A58F0354A6B9EF580689B78A0C8515CA05A35832616 7E0A90F68F3C306AB60AAB20872FB167673F41E8E87FF0111F579CBD0DA68B56 3E35D2EBF9F28B104082E36187373EFC7A33F62D3FE4A390B63A76E9B2531871 6BD59861F51B561DCC115192A6FC22D15A5AF03BA09CDFA66B660CF4288E9D79 26E797256659B0FF64BB5D900990C3CB588E1E18810BCB009A91E5F4F8D9DB1A F2A063BDABD9C3332F4BDB701BB94B4FD24570B440AE74B8D924E48E7C2DEFB0 53A19E5B4DF39ABF4F6FC6160B5FCCA00608422A3091CD03E726B1EA1D203B3F C44173460B490498EDA3121881EBD21CB5B571D21A6228CC0A1B035EBE97F26B 0B58179BD22AC950EC3A98458051A874297CD6BFE731C5B413819503111F1F6E EBFB5628C955F5FCAED76F2402CE351F77E471D1C9821DAD627FF25131590577 5FF9335DD28D85A11BF155765632B34A3AA1DF9C01134BD8FE927E0064319951 E2C1D374C9ACFC30932712A5C3E0FE3C7E355E3356E9135A143F1B4E2738E208 8F44633DD9300BAFC770625A64B2BD20D4F672701310E5D1D5B2DD502802539A 65344601924C473B7618F9B87BF6EB49474FE62891097B9B381DFC9DD22F6CEB 340EFD950B74E614A2908EEA7B0D395E15943D0A9072E2C0E6C91D9141C84281 6A59F02111333723DB78C2C287675D73152EE3C63397F5EA6203C707568137E0 12438B86EAD16D71A0A56D00E6ACE9D80AFF646B05D829DCF08DCE2FED1A17D3 83A7C9E7C2A5CAEB38BDA802E6696BAB17A5D1E5D6C51B6371C642D5588A2945 1F3C8B0CD56806531579F7C0D10A9FBE254EA910522D955C86DDD693B8660BBD 17B2B23FEA57AF15B1720E42C6DE537074C071C50C114AC54C45BA2FEE00D13A 2573BB9243648A1BE2569CF68FF78E4CACACDB34DAD918A30005C31F17781633 6B74AF8B9931BEC0C1892780020C1A92470E3AD7F1BB6EF26C835F13A9C56DED 51DF4A7847C993B88B9FDA9A8955D8BDBF6BA773D06645E292CE26D9DF4BBD4F 3D20F52161853827837C837F33425990818B958ADCC3AE79B5791FF04DAA32FE 54050AA9D34606F16C7763DE770CC33C9ACB60E5354D5A27A687CA6E0FD74A4B 5CFFEADF6AD0BA87B906C09201FF65CE6C3F620BBFAACCBE54DA884B87E906B5 F5285D3841ECF78F0A1EE4A80724DA3A4FD49FFBAA66BE3402A2480A6F8FC164 343A369E2B8947FD5F58A4697234C742685421CE3D57398C5ED6F6B049FDF39F 6870236751D9EF2210E680B4D8A6DAAB758BD7FA7DA9680604E5BF85D1826611 2CA08E8922A1D46AC853F4BDCA37F7FE80D2D27854012E4A8F70BD854EA4C189 EA6939096B56168AEB971AAAFE1BCA667137A76761CBA2FBFFCEAFE3E98D5590 DB3DBC44B3F9D4EF0419CAE23086898BB25A222EEA19C1A760389672933EA7C2 8B31025619BD108B79D51D54E23F401F42165F0D513BB2409CE66BA3E83FC000 4372873EB8B4405A8F5BD88CC2F21D2D60FA4024707869C5FD40D94028ED13B2 5762CC7924D100D3CE0DD32CFCA124EC1FCE4CCE8C137070A18F05CD73809449 BCDEB0AC24DCF63679D46AA8B3A4A5D0DBFA9342716619CD3683DFA7A9D6683E 5A7A03DDB47833FDFF8935F2F004F58EDE6447ADCE4FDA1B734C75C52D16C406 9428CDF68855946014584F7FE49B03F896E0054CFFFF5DA4728BF4CE1D892052 701B48B81F58F5EA344E8EBFE13BAA70CB43CE4A979D8225ED78417648672E61 07EB7B31F81CF52B4136288200E640654E83534EADF05301FAF2F3A859772C3A 545FC20429119FF00C259AA582AF4E3CDE1C99769F4E433D9B178EDCECF142AD FFAA6DA004A90F53E70048AA8D15A26BFCF7B02ED70BC262D165E99F87CA7424 0EB98F3D7FC0D4926AE43C8D322BB9ECA24A4C45F7DBB0FEAA9A900E3521D6B3 87B52A30ACB29C914B06793F19A1EFBE3BE7D0B8E20CAD99D292C315B12376D5 655121189A833132715762CA7118685814F71AAA08B89E466C7468BCA01BD98B 63EC7CC3AC41DD06C5BBDA86227AFCC1F7796B5F878946C135BFA75A98DB1B57 0F38C49770AE23986FFAEDBF6644DF58A252C29AC821F4584B96B5DDAFA9B3A1 AA0EF6D17FC1E75916753BC8C799497E1279EC783EA86DF307CD54B58C2B3EBB FD722006D127834B089670E5F1E7BA8BC4A0F6181BB4EFBB8F99E4475181449F 2FCB255DA4233F7AB097EF0108BA3FC12CDA0618870EACB9FE4195DFAB182242 BAE0956D09E388D10DA2F940186E25C9926886E9806C70105DC75259FB1E5DA2 675E4E114F84862E6B822A10A9D364B1CD13DCA3D385B83499C715ECD7598766 B215910F002358D592FC36D0BD482EE9CC338378EA1566839526A5783F250818 078B97D73B1D62A1AAD3D5A9753BFEF23F7B3E6D5BD318C463AA04490B9063A0 E83E3E68109B182720D2B1C13B498F8F495661C0F4E6455B96A6A92FF806F1CB 3B1C6EAC82D9A687B83C572C42DF22BEAE31D1239719186F14EF637FE4E7C7B1 FE8F4F1BD8367D76D467BE95C394A818198D922BCAEEEE371FE17E396B27CEC5 F0554778587FC7D78ACDF317A8EFDFC82C2F57B6411B3AB68F96E3E7CD321A6D 4783435056AB5A0095726435BE6885BF2784FB2CBEFFC0F8248DCD594D34B21C 98E67DE50B6876C3D6D4D4CA7CE0B9013EBE754B104DCFC0719A10CDD9985E19 2CDF4E88876C2DD4E79E23AFA70AB5B4758AF32EE87B8415B881AC15C5C3E1BC D17A5B961EFB3A8DC987DEDED6F28A240D66F004AD05CE1C551E29B45668DB2B 305C9B1AF5CD5388A0802D80F18E0F4BC8065BAF393FFAB9A4D674312C2033D2 7C78B5E9461FB09B9B2CAAAB70CEB3AFA574C89BC620328211C85656F63A8DDD 97C827297327B7980C2FE0ACB1C34866AA3C5D7408E257EBA3C53DE8338BDF96 CB7BA55FE31BDDBF7807148C0A132BDBBE8A2C21A23E11889DA13E429914F7F5 7132936359A0CC65E5993CAF52902F76F75D6CB46DD20A3C0BE80D45F2C746BF 236733462080FBDC8C5C1DBE9781F45ABA74AF8033A6EF2BDB16F7B0930D6B6E 7CA7FAC8CFB2DFAB8C063D961077585D24E8FBB5E0B0BEE9C4509B23361DD06A DD25767833B9A770780B311F608CAE7ADDE000297A2672211F0DE8CF7F5FBC62 78FABA25D035FE3A7CC3A4743C0EFE1C4A5E9CADF1E05BC7982648D5C9FB2992 4A9EE1570BA2AB068CCE168552299361D62A2BC2C0DA48EE94D1CEDF1E2D29BB 43864AB5B770A14C98A432AB76C17998904F052A50EF845100533BA5CFB24C84 DA53581EC4F2201CA9FDAE76EF365515188ACE4CFC939AD6D193413CA7EE225B 0137F4637F09952213BE725CC7AEC579B2FE85F7C6AF18D70C4FDA0557567E64 D430F09ACA7BF28984977BA0F5849A5A86729D5640BBE4C30B17AB03262A02BD 8EE077EAD7FDAEFD37AF16007D83714ACA07FCF882ADC4792583AABB279579DF 6741F637CDF8598FB5827528771444B0AA82DD5E00E70EDEFA7405A1D8A7797B EF021A53BA68C7FF6780C94F1393D1745AB1FD7C728C6112766A3C2E21DFF002 9E45A5C5668F8B084F22CD6A6CFB056CF0F402A73B2C02118259352EFF6D680B 877CE3024C37D532C186F3D4A97603704CC0DDB25CAC00AEB4CF601F6FB45655 8939AB962CB9E16A2400938D226056535EBE5707CF0A8678B54E6E3A103B2EFF 0BB7306D7C7C3F523B2AEC267A5F1E3F99208D8EC9AB27D658C26F635C2984AB 5A4D214768C6DC775BCC616838159AA10D5BD93CFC8B2D836EAE5ED480FB6DDB 24253A62A1B798BFA51B068B6888B76D2233B6FB11794F166254CB3AC8CFB650 429866DBEB8D09E6D03889899A4E8BFC9A855EA4660F928D0AAE8247EEC1668C 8E798398D53E52A5684CAA59C47CB38C8F1009A8AA12A269A587593874C2DC78 0BA989078910F3D70211147751E9F7264D6E64F1B05410ED3427BB7D0704443E F2BAEB0FB9E3F1C1C14B178E716FEB4644240447A3F02211350E36E1A586A042 9AB336C6B44C0D2977294E704E8695B6DAF079BCA033B6BD3485EB7A78582FB9 373716136C63EADBAB3A2577738F553F81135829F9118F4BFE20CD51190BD7C5 17035EBE97F26B0B58973EA9B5E0D111D9EACF2FA54B223C4F40C139AB891A41 C7D5BA5338BFD58090EA727C3FD9D0C0217C05798787881D07CEFE019518CCD9 786F929BFAF65B9F093F66AE0198DB15A1ED3E634BB7968281E22133A947416D A2238038CC147C647D03BAFAD3E1E05C7DDA07E50E59869E5B0C4A783A671F15 F022D8221F23B7C33CF45D6B24DFD843E6E80330277D9AC57FF5F50FE2CC4450 13B686FBEC34A6F9E744EE9446E5322FECD2F1FF8545BD7695FEE8BC5114BB96 1A47B29E51AAAF87021D37130180B89DC4F46FF9AB09C065A99C7319768BEEF1 1FCD5EC238F9647263DD3F8C686D3DA1F50B8E4CA961A47F88BECAEFADB8F79C 33A49A6F686D7D9025A54581CAFB8CEC5E0DD266C51BB9F6C36D6C36517F1089 1CFE4890B82CC0A919AE02E4E10BE091EA0707826F7E9DD32640F4B960765CB5 6137AD1A1F9FC4636C9EA81ED82C4E17F732959FCC68BB543DC2228A053F74BA C3DDDB04ABA713697AE8D96B977914DD0532EC273091C93C1F5C98FA17205DAC 811704CCDAD13B48D9F986A11C57A2DCDEEFB6522BC1AF670304BB3A0CE945C5 162F46B6BB94082FFFBCEDB0E2DEF7ACE895397DFAF366B982B1E79685E5F85D 01EAD4897E07633CD81079013A159A4D522225C461BDFAE1AD42E8AB26F4FB68 8CC3ACC6E5F3B572ECFAAADAFEE78E1D8D2B9E94AF57AE0A20570004AB101F8D 4793C4204D7D421367224D757CECF55C43CDF8C15CC8E2D85D38C5429ECDE1FD BFC2A74E407AABB4B1D3C81E84BCC37EA8D0F63BE49DBC2B875AEE9957104759 BEA0F7D0201F342B0E531BF23E9A71B32B87A7B6BF4FEBD03132F9075C271F20 54078397F96291162167E3044463FEA836F9BE6691B79CE69E884D63AD365F82 0FE2A7FC7D4B5DAD9D90CFE0F89E21ACEEEF8DC018E388F3C9F683C1D32DBFBC D3D648B8C4C63057D7B7DE7FF432BBC34345C13693EC4D99B1A26EB30141D235 8C0C3F47AFF734D51390E769CA258DDC0144E7C1BB169635270568E060AD7BF2 2130727DF1D47DE4897284B2FFF95A8A508A19C3281F49B46E49C5309ECFE3DE 89D2D073D5DB53EF9B564606B5A3EDA543C0DB4273AC81C68EBC2B8D9E9906F4 B5E57FE7CA658D97F61DD7C7EE5F015B1B24D651FA60B385CC7B9F05360AA384 A8CDF19D5913AFEFFAF9D2796A8A1FBBAF2C8F0688EB46B5F65AE72502C9B441 71CCED24128FE9248DE67E5585C11D5A36F9749AEE2109C535CFC0F90067E6AE FBC4DB63694E0915E74EE6EE3634EEBF2C6A6E8D08D74F1FC58B0EDB03CDD965 56DDCECA2AEF866BDC2078EBCC757D2D2A95344A9BC70F400C8112DE7DC23675 23A4591B0964FA2672D57B22AFF5724FEBC52FA0649E775C9F45B52530E836BC E007543861D33316DC695FE32CD586CD70A54455C7A30C0D839B036AAE212BD7 2336D40BEE67CF5E402D7C68A0072B6DECDDBFE7915C116808FE818DADF9D048 F961680E8CBF2596C912B350BE00D71FE9B7BBDF4364F3B020EAF19DD1B42AC8 09F93972B1D43657BD88A87A913FF957EA600F6C6104BDE5BA732A6D3062F7CE 92F292EAE34280FFDF00356EF030CB53B5DC3F8B6FD755E01F99F67C6942EB75 D3A720A714F9F644E3DAED6390ABE1CBB68FA80D3BE4430E9C9FFF5747D4203F F67EC9FCE378C4940303BBD456FD31D028BBB5671B1D226B820F201E3B2C79E9 20984B4A273A0DC810CDE42344CBFD02AA25E4E527FC4C187C612AD64EBB14C9 F19FCED92A62373DD6589DDEAA94314C0BCB4D31C0285C24569F8D4B65C98ABB 45651E064E4359101B1E9DE992428003665D5EF35B71743DCC7C1BB6D4DAAC6C D88C4BDB2887577152F83D09A4412FD06B72937BABB146EF196B4625AF98AAA0 49AB16CCDC7322B6D8D15EBFFC5673FBD1F0E09303F8F6B664400BF66F468B75 0A7C0B3985DEBF30B126ED6B243CBD6E332DFCFB8D3CE6C95CDC583E9B1D4467 AF2CD0AE958C1EA072FB59BCE787CF886E74A4C4A3AB05918672D681C3D2178C 9C31A1313341CA1C24DBAA7BE7AA07EE13581654E8D61CA6D9DFB3AD6B010356 E45CC4D536F1381C76E3276BA0E9205DAB60581FD0251A60026966D36FC0F55D 21E609973643C35EB4377D45DE1A569ACF6FB224078C6BB520C4ABF8AF55499B 521573B4A0DC8558A012B71EB831FF1021375FD7F904F3F1094D519E7B583B45 B898C3F4D42436DF5CB6C9C8838F07325637B345B5CE456DD3478F1F1EF1BA86 7FFA866E27E1D47E3B0E601E22F1DFF867C1778EB9BAA424960C12735AE6F343 F45F92896B3AFD089E484829B8746B24C4F502E4EB6021343A1B5D69C1D5C2AA DF0E960552D2FE27E75213E3B02786EA9362A11AA9B3D13D06C96DDE3F4C9C56 E6C9F4C2E9DA7550D3CE0DC86DA1645B9163C671A8E071FDCD66FE4A531F6535 236B0918468956B622D768B9D93D60AE5B120F163C048F100C2BCD583F640582 8CA85A4B8645D10CA81C7CCF639EACB8E703816FF9BFDC8936B7FA07E149ED15 FF0590E8A1EFF0942DBB2AAD5CA84F9BC52A7196C804DE221A21C15AE0743E17 8A6BEF204500CDDF5BACCB90E7FA344B2082CFB0BD9034DA8FDCB70F9BC85B6A ED675BC3A0C53C1189C068C7968AD16ECCED96B3228E6BB8AE42237F3AFEBB64 AA6DD9ADFD27118D99E97EE4FF71A56397D4E083C8DB4BB361ACBBE03207E2D0 2D9B3861EEF21EBB382B264D19B071DCE2A851F2813789B767BAA6C03324BEB9 CD00E41E8914B48B8B194687BBA75B2591A3C54A655B0791E1B13569ED522FF4 EA9DCE4045E3BBF77C6C32B88FF37B03B0497EE755C524B4A674411AEAF800BC 86CA8D7266BEFF5C0F6B50891C94A4B2B51C73F1284CB33AC025E5F5DCF57C8F 6C61E36B876AE742558077194CC59147565591A4B668CCDE7C19772E0E565E18 ACEB902E1F81A6F7DE63A86E6A5F90EF8F66AA926CFE9EE621CAF76F5326E1E7 5531FFED9C3415BC6E4D05AE962133C1B8776815DBD7F7BC33B34BF3EB64D8B4 1E63A28E978DEBFE26FE453790D3075902142022563BE218842CF244E1CB27BB 8D4514BD26F04292AC454210DCDE61AEAC6DBB9FCDD1912FB0DC4B8702C49448 6AF8D3C66EB85C14A9A395260561D1CCF5CD187E634512573F589D3F83F7B48D 69C0447D891BFF05F925B6DDAF58EE50372EDEBD74C7554E710504A418E4A290 168E82454B51DE40E0BD1891D0726A99C3F1DE84B96AEAA2F3E76C51D541D23F 9D26C04FFC3E473528423839969E5A8D0C3299FD377340FD9FC82F707B0F5B54 914B7A190558171469E07D83B461BCEA7000C98BF402E498D91F46022BD9EED4 A8E707FDD5EC677574374DE3841B2E360244AD0244E7A83AE348056EE9F791AF FD0B6C3C0914ABD96806E181B425092F91892FE4CCDAEC977F6E7846D73F00AD 25465DDABC48CC05727B71581FD8AE8C51F90C48E6D918DDCE99BA2937E22D54 5E92F5B477E639DA2D3518C1FC782EAFD94FD93A0D26873B269C35F6F5E691A5 E2DF64275D90715678760FCAB9F84AF3CD59E249D15984F46F2854C2AF90B3D6 1708452E8CEABABD200D493C336EBC9CFDDE6F3472C424B2AFD4EB3F7290531D 3E26D85BFC66DDAAF85290A8ED59ED2D5AB35C03A442511D48741A1611421652 6198CC60C84CA731795B795162EFBA43A214842D1606270E0774DF45A0B3BCD6 478ED664774225E83D3E036A99EA811ABFDA775D909B05A0FB959AB1146098A7 CC2A625A053966DE70AB169B30BF30074B701B39665F4BF41625970941C1C8C5 CFBEE735D796E365A1B0F60BB4CF2800C4ADC5693A284FD65AE53BC897EC7BA6 446656F2A9BF3CD6A1DD200D31F6BA872ACBEBA94F1FE5920A18A45A8B13E980 B20CE24ED96E7EE72A3AD5AC654B29BE5C5E3E5C968FA7D88916E879A232B795 39667BC689CB2FC3D6B473AD59D579D8C717B8A4B1118A27D78EBF7C09C1539E 9AE349A5475C5C985C74F870397640B13B0C575326C279472DD56B4A6C740BA8 46DA5D0505010956C520A7F3FA5DE8640DA19BD70782CA46984C25754199F1CA FF5584E66D6D8DFF77C62F8D923A4F20D7E538F97635A06B7C74B7991E1640D4 C87B6CADAB6EE86CC5EF576B1DE985A8C338AE82915579D18F5FC90B50FFBD74 1F3D951920DFBF4A09051622392288265FC988B078925944108F2014FC1B3784 3EEEF5121484E732F9A70AE8167B455772B0C316F6BCCA5DF3E5AD4AD746AC40 42202D637E25CBD47E8C4F8ECFF0BEAD9F92C75C0895B1ED23C0EC6DF8A42F9D 50184C56855B655BF1110C7F67602959BD3A9763A87D91E95AF7AEECFF74568E FE8509CD8D79180FA0E1CDCB4C538D6F8ED27A0446E0A67EBAA9F9D310AA8795 8073AD979877DCDAB1A5DEABC7DE8F03262B6E5DECB746573F2DD0A51FF7BF54 5CC64E6C0E8246944CEBBF7EB4D7E523554191AA7BB25535CB6B53F459DDD7E4 436347E14310DF908BC0C9863358ED7DC485209C235D101C616003E9BBC99DC9 4FD6F58C8FE54CAD745C54C7BA074142005FBF1FD215D8512481026B138CD349 43E4FA12B31435009396E6A2C5AA7A2799F1C34A459425115A04C23C0C736414 3056AE166988C561EECA7732A29F37A088B24022F2F6AFE7EA35D1F3E05CD2EC 75CF05B1FF80829EAFA3B246D720E27B5CAFA34FA8732BBF7D642A2A3DB0A4F2 F8B635DA35423FE34B993E847E2B0EF859D44C7A50D7B1910D311804686C70E9 E3DAEFB95A56702C9EAED6CEE20A92C1A755D2754C770B6E9D37EE909680E472 B6ECA873AE11EBD9FB9C5A32E9E18AE23BB8E79E9BC116EB408B571E39D1A96C CF6E5D49B468826E97FC91A0A25F4DB38887EBA723E2BA8B320825191A69B88C B3D35AE625B7C348A2EEF756679298209D124EEBAABB4ADF5F78F6D0325E4044 04B0B30700253C6C5D87F9C357CA8EAEADF362979D20C090C0B87CD839087BE2 8F05ED1A34FBF47829655EEBD4881A6239D04118C166BE43B6484CC91F0F12F5 1EBA2EDE877EEE98EC4AF631111A6D43D71931044D8127242020D4C079F0FA95 468DE880F42639F87277C98CF0F2AEB30F91A431A2357AB81DE2630223944903 43D8A37F9BE88FDDAB026252AC56B46DDF4B459E476E71B416FBBF32288F1F1E 3D829920F6FE6620D69DE53DDE8F81C142E70727135017B39A5A1AFBA562AA96 B86F1D8DAA61F415A48B0F77F4A231F76CF009FC101B4F7E62FE229E16DE8D00 8A4CCC3C71EC8F498BE9DF2A8FAB9DCBD7E32C0027AD3F0E0323B1D5902FC0E9 67F6DECAE14CC044125E6A0EE2FD434FA432A730E0B3254D5A83B7B4CA2B1BCE D5FBD93BC35AEEEF6E2217F4BF8FFFC94E671043A4CE7840886904AFD2BD4325 6BAE6B862CFFBFE0608FE1314D64000BC98C6E0FED11A494DECD53BCF483C693 57CED5B0C00D1629D41B1AA1141FF728297AAD2CC590F2CD8C14CE38CA70E37B 424BC346485F6122ECE97060DBD0DD2CC40F868359F15830A27634962313F418 199D867934452BE352D18C95C6F3F033B3535A024461616399CBF25B7DED110B D00B18235356314F81AA06B640C28151E5E60EEA4DBF6D7855B8849431DA4E0D 14DE737964EB1ED7D967074624917E378761B501217E0852031A7D7F33294D44 6F2F5B45FF242DA4932B973139F328E7E9282BC20773B6292B78A04A801592C0 0A3F5FCDE4C0AFC7998E101A331B3E883E490A8B71BAD600D899D91052FD830C 7944785EC754C8C57735031B7A58D1CC858BC7B4D317E1708F4737959B2B8597 37ECA0E6AEEEF942FC33E59CCFECC62720B27A31F79DE69649CA9EC65AC5DDBD F92F17958A6F1BB73771F35000FB9EA55A132F9B151BEC329F36EF3B2B65D787 32C40F1FCBD3C31600D4F451AE8EE9FEE7BF7CAFA994FB4A0185E3855D6893A4 D5D154340F46D0F308373A4602E5480BDAC1A528DE0C48192562C322C1454CBE 8533496069D3951D8F9ECEF9727337BFDF811E0C31D030BB2F680574589860CF 5D251306294297A2831C28C870512F628D990EBCCEFEF4786B023A83E63BCFBD 18138A77AF9F935651D38E49E1617294056D90F65DF04C59B7256F84B557CF7F 42391D263A1EF811BAA904267AA05073F5C14EA5A2269B7FFB1CF8D585D8AEF0 4F95BE4A9F83B988E05DAA433B9C6D4683C51517922B00E77FC5F480C8F3030F 3F5830FA1D33781BAF6F7ADBE65A0C11A417D465D5680554B3903AC5625B55A0 E9FBCE5C690F672C02340A44A9ED2CF558219C6DC4A459F4A259331020107A09 852707B51EA42C0BCBF43D12C109FA7F552936DABEA59F7560C3711FCAAEA964 460A284B639F7019092925C3991D7DBD228759702CC5B12BD66CF5E8CCDBAE59 4A91222775300DDF7F463EA60EDCE62116ECCD472791C6986506ECC1BE902996 49817AB7DE0588C855D2ED2740216D4AC5F199ED0192910E15539B07CFA88C80 D53B83F5581E8F42C1DDCEDAC02652AD32B78F7531B739265953B4A8BCF98679 477C990194DFF8D61E8EBF0F483C687BCB5D36849122443B06C8391D3EB6485B 96819968D02209A560A1C2900D93C7D84334DDC6B6B7F51C9ED656D11929E44C 07D03436CB49F934EAD47B45692A4919691411DDF5E0293E70BA00EE3AFBF1EC 125FC8E450D32713AB4829EF58D62DF6C4CD5658D8DEE558D56E17FB2C55C2E6 3280E403235E68356D619E21233154962E4ADCEE42A4AF78B13304C40EB55CF3 1782D8B0F853975AC25A96919B0623C444D9B31C5EBF439E824CB2A1AC2FB6CE AE06A3A0C730A82EF6E7FB1ECE49B03A90C684FFA97B830B6A457FCD407E92C1 63638E4D91AEDB312FAD20A33D1D92E0F97C2B24596611775FB929B32F483856 0072351D5E77005A2504832C6D92AB98F34769762AE27BEBE445DD11FF240B19 06D839255194B6D95AD09F89136730DB446DAFF09C0F7D604CB845DE20E5D852 6D9F2407B7A0D14B76B58C9F90C924CE038E944DCE2D32C2686DDBFDB838F67B 097BE600F6AEEC28BB8508B137772858D1A89AD21A4DAD367B21D4B71BCD8C3E 857C6FC2C1E3CB2BB26E7000AC331BA4ABC51566A29A861E14FB8153C749EF0D E6EC83878CE9C39699EC055C601038EB4640358CD2D6FCBD70A3B06ABE5A809E 2F74A14F78753371F19D3574418A09AF6F4FCC0823D6022BAC23C2866945E469 81F9406B6E4F61160966A90DDB771098E450E41549B3753CC1F24D29708F686B C7992E0DA2E5894BB6597DE3C2184F39927E4A94A814D5D7B755921322A7D4AE D6B344CC9F5D849CD8A96771CD533AFD248825AA609538E62266525677BFF0D5 3B70F08FEA8D98D380C84A718FE331DA2377FC5BF663BDA292D5A19A37D37011 B46093BFE6CFE63C166D03FECA2FD19111336A88C54AC06B816315F6D63DC236 11FF7B6FFDBB1D6B72C77967AA05FA6E12600DA8B0094D7548BD0A4FEBCD4ED0 1809E0CFB48BDC0E5BD7E1DF61135BA3E5397F55A95BBEB358A4FFE9BE804CA0 7B9C75F2C99248D71F2EDA6B5C945F0D1E677AF88B009C499B3797BCF9925D29 8E778DBDC255A5C48AF26AC8063E5B22F497F0BA95B2A29E90BB3EBA4D6BFFC8 624D3BDB44B1B70CDC3CBDEDCD86C7C8529159915D7C41F8215E8ED4A289BA91 5D1FECB13997E25D07232DF346A7D4BD3D43D4B26034F3FE69DDE14DB1462E4F 9859384B15882C6B0E2212B64B3ABD2C9AB90C293E955B2445DB79C0255C80F2 EA4A2ACB1347610D835EFECA02E3020C4114F3764154D32CAB053B7B143C3488 E373FFEBB6941EB9F43E42D7228B17FEFE5493FBEA5FB1D26743416B6D20BA81 7AB49AF3D86013FFB560C6B96CCC5ACF55B7175117B32C3268967543D5331E93 5F94F2A58AA9394588881EF3502D264D5CBB12AD2F26505C43586781380C6CD4 0DDC242AE02F9564E06F05A15D7857A1679207C76C99990314DC69E7B4F34BA5 AE45421B52AA302709FFC093041C6BF0D15CEBFDCB13452CFCC106165EA950EB 7286B7B7F959A7A5E71CF9EA41C7E5BBBA99921B2E3E7D31A1FA570B4AA4A2C0 4E1AFDFF193F07F110C7917C71E98D9B788C0A30ED0723F60DE42388CDC82B32 E829D10EA968E2E1F60883F13152D70D8C76E0BB114F84862E6B822DBC33151C D82DDFA79D31F0B4A0485F51334BDF5CD5EF3BE696271D1C73675BC4DEBA558D 53A63F9F1D30B9BF61151B4451A9ACC99D10B2322E42089693DA081DC875FF9F 77520327CCB89B0EB07AE1EC07FD93D19F9C0A689E3FA12D0216F822CBAED265 7A1913E3C0A21FC6671749F554203496AAD69A05A3349349C965D9025A5318E3 BE770748064D77BF335721FFFB55A4D879BB5CBE06D4C15D449DE217BCB2A266 AC3EC923BD42E241747085C3059DA99C844C8D9CBF8588E301FED6BF2A11F540 F8F25827C65646C143BB2DB967508D12B19E0C3BC9B56AAA74550106E9D6DE9A 99B7DF7107BE1612B01FCD9E123116687E13849033C774350BFE9160EF09B04F E67BA3892D4A6D49F020525240BC5E61901AE90C61C7BB0BD60BAEB18A4E1559 1C0E784F387ABDF77281ADF83C3380A5EF6871CC7FF4A8DE74C625DE3CD9C3E6 97EA13C451BA373B8BAFE9DE406C426A595F1BDEA4D2626A0AD63FC287C53428 8972EA88D9A6D340BFDCBAAA5E39F23ED0046C3861AF304CD78E8B4AD264351D ABB7512B0C01935C590257F4F2D842D49AC56BD95CBD6A63F3CB3D55421CF3C9 96993FF175FCB21B529FA349BB5801C9FCFBABBA6DBF7CB85FDD0F071ED2C74A 6F0E5D3989A76B4C8B8AA627D7740AD3EE88B7643F0EF407E648B5321A6396A6 9836D76D228AB4AFBBF7AD5BA2B45120A151D317565948AEF03B458102F1A977 DD6AE21621F9641D166555007FE6C5895D6B3828CA6373C3373A8A960E8CE876 814BF29BDEF311BC2654459B4D4DC65E49676DB3ED09E78F5E840C0BAEA5EF65 42C4ADEAA065ED4B8F195BC826E5FFD17B54DD4571D14B7A4B29845586E3E2EC 973FE55C6EFD0741366AAE4C5C10CBBDED66F6E6D04CAF632259E6390F359CF1 1886B48059213D20B2E3B4A149058AEF1646D6B3A1D63F10B5C5F2598FD25A1D 6F5455BE6074B47678BBF129E56FC21889459AF243506E5BB1E2DD21789A6F4E 1751823625DC1A242579345AE4EA74522900E0787B4641ACBE50EFA6A1DD189D 6E6BA16E385C2C6A7FEE62B73803413A89EF7FF61C0A2545DA81C017089EA28E A6E6ADA67B65B1A8E0C53E05F4FB75DCB1014FEABC3E134DE66E5156EC8AB40C F2F3731FA26A8073AB6F3F319F9C72A2FEE4BE514F2503AC3B5A7EA4A0B24EE1 69F9BCC4C9A12FA864424304A1FA55ADC6F61EADA686DF87BCB533865380A85E BD72DFD472303FBF5831E48A22CAE1BBABBFC82C68A2D816331DC7E4A38C042B 4A03E4A35AD1474C0583AF57A573CCFE928E9213210812DBA7E56F4FFB020AAB 5653BC3F8451B1B6AB3CC9A167EF4F5587DDE44FAEE24440961CCCFDB88BB5FF 8BA26C1EE335C7D0B6E4642AB9CAA2074ABD5879B1F23BDAE0A0D10D2B2CEE7C 2CBB882F57FA554D0A92AFBB0AD090C56AB8BB0C33AD2AF154D471A65186BF0C C52804FBDA663C3FCA1E2107F74C379BDB424A81B33B496D14D7E4953191B9CC FCA458EE52A3A9687D148D5F2D986AB3E66D3C78C799F437E74F0E18FA626AC8 2551051EA8AF5709CE0CA791D3A65C13AFDCDA19D38E452C6038C79F71C137C6 6CB2DBF738FEDB0E8F8A7F08F2CECE6134D1B355E0D568C800586491738F40D3 8E173BAE5DBED11BFDD6A4817A3957DFE5D8C800B9CDD8E05A16B3999C4D8284 69187C6DB2650F737BF728F3783E48C600C0B365973A48C755D06DC4CAF8520C B9CE25D0F1E8D7584943D7D7D2B4DEF74957786555FA50F80FE67D3BB25E14FE C8C7A51A13BB796482EDA4C7B9E7AA036CC709433BB8980654335DEF45D44E60 E5D6F4B708541FC94B29A0A824AC0CE8968DC2E5188501347EBE2486678A3B3F DF172937F30AAE19986738AFFA6D60CAE92B684461C7F424647759759C58AECC C1E2577EDD9ACA01227701E3F807D641CBA963DC2FE1190CC0CFCA418F4F4309 6BFBE13259B46203086BFFDB8FDE34A318A85799D220ED9946F338523CE9A9C0 EC5F680EE5801665EF4919F3AA1774012D7B23FA0B803A1A98D7150E5B592749 31058109FBE3E9941F237A97D566131F49CAFF212E6089DDF15006508537495B D509EA9B7E4036C45E1C8540AC0FB82CDDB697B2398669D00550A7027B7AC1E1 E6519B0B2B815F4AD7FF95E24922B079863CF23001C82F3197B0750BADC80BA1 99323FB4EB0AF8B3599F4F212478EE5CB1BE74CE9522C0F46C42F9DFC26EA05C 1CE9402164F7D1FEAFCDAA7136589B1EB8917C87CBE81CA162406CCD22D6EE1B EB94AE70D0A1782043B4047854CB47132679FB3B30D6446D4002201A14580A2F CD7CE027EB698B5FD3A35F216F69D9BED074DEBBB7E8403FB15DFB079AB99889 954746B23C4EADF6E42B5D187C69368608C43C8D74B86F0CC24A86502E464E1A 34CE0CC3B2296E173384C46EFC553A39C7C9AC2DE764A6963C309397689F86D6 995D3AD35937BC05FE45FC857013F909B54D86272458FEFB20E873DC8B0A1575 5CD8C5976037B0E60210DB694DDA7044E0146ACC81230AE5D5B31D7EA25383F2 E50C0CF5D5150F595E55A2DB7D24DD07DAF9E3627814F7DC6384F9A8E6E9C26D 0217CF2690D2A70B52D8C72F0C54B77BB080376CE9703E96C87BC43CC92A879C A7496C196C1685E318C996226B37C83F01F197BE42817572160B00E722057187 F26D5FE6A0A91652B226868F1A46778B381F9421C088F838D2AAA36ECC1A476A A4C4F4EF7EA531C3F0C4E6EAFB17492198F35CB09852E1E6C3690F1315FC7B1B 48AC9FB8410A3DE2B997C02256390F9EEE47B34D9454920C87BFD7C5DF2D559B AD27D3C5659927DDAEBAEDEA1A046D74B27A64663142513EBC737181448D5B0F 13DCD5FA5304176DEFDD9104E5143562D84DCCC40F59D43A7E09E014F82B805C 373C1CBB3F51A92625DFFAC5D1B3727E7CDB3693EDAFFF6D7975C3D2EDC2E7C2 656438BC1DE7233DBB505F7067CE84CC381BF27AB024E47914F786820BEC98B0 A96506242498F4A01A23E93983249A2376BC46CE26BFF63F0C9730E9845A31DA D2A6C29F5E1456242529A2B9731F537CBED33DE2B20885F17C53A685F7F4ACD9 E26A1BB3E53D58FE6BB2D210ED00D307DDBF52E27B75E3FF659B3B1E676C3CD9 3D82E88E010A3E542414766DDB2FEF48E8A2B7FCE289672BAB32447C5DBBFA8A 009DD2989AB2214ACB6202532F86848582AF607563960DC258BD19A434B086F5 F0ACBC177EA0E6C50E02E35764959394495E8CA50742D69B62D427BA7C5FA085 184889C3CB2B7D8BE6A1F840D6C96492B09839D830328842BE57B558BC7AD789 0932D6C91904FE768E07C1C3119E039F1544F1906A8A31458EC2E66878767EDE 855B520ADF3E02E01ADC6371A563CEBB9CD0A1981F0734BF0C694F7CDBB3AAA7 15D5D1673DAE975C88F305DDCC38F56DDAAEFF18A0BE740AC17B9403C2B35E82 53CAF3645C497D91D91AAA79C90CCC44137AE942A6017180B0F1F0230E370908 F716978AB96CA565D7D10C61F3BD5406698F3B7BCFF880CD5C25F4D1D6624EBE 0B4BE7E25FCD33147A95873E229ED015679DA2D3C2ECFAE24ACF8234F8AD0F9D F758FC11BEF85D619405711F92E0BBC87686F4C997AFA0F554DE104B311F7453 25FF863E1BB7649AA9AE390BE44ABBE75EC92A6C4AC88617907D68E37513CF5C 9EE13C298F74007F3FAE006852CF4760A653E8F627DB696BF869E0FD82A04759 D4ADD7B913F444A411978CEF2975C256CA73346C1673FEE9DD385505F1A58948 C2A50C331FE5EDB35042E9E7DF8984CF7443D3C155BEAB4AC9DE729FF07FD310 6A73DF22BA8AF237B0BC7DF2386462462DE25B7576F7F1B343CD73F4A0FEFA28 21EDEEF54E8AED21BDB4CF8ADAD35FC9FB1E7A811152F3B14D2EFF258D1326CE 027E25C6E1BFD37A21D8B207233EDEFF1595E95D0E66F187034F7254D208AF49 1021E07466D04CF2D07841BA31265CB2B7870AE7F5774E79757158F81374B989 50AB7A3705D3DE28EFE833E11465E9D8BDAC9197ECE52E5FEC4F97C426B3A916 C1B8D033C1A3CEF1D156456A62492833B69725F533636E4095A0CD1F58C95E80 8C21E4EF170AF5B2E4A83B51E225385F0FEA7BB2C3140005AFFFDFF7B698A87D 7A86EDECB90D7B1391B39F44394EBE3C7AD1C6512699CBC5507447DCBE762E9C 7E3E9ECDA6FCB934A26AF2D17FE897F905DF697B0E631F6AAD99800F2FC8A368 C1B8C9B93267298064236D2FE0966D5DD6FD949F35E8295FE22A09CD9B68518E 623A9E956E1812D8BF1556690375E46460F6DBAAB3ED1453B8AAEC1461F20399 30471CC1121C148DC4F98A7211F51B4B834DD41A4A52FEF5BF46D841D1EB8019 45F4B9A15837657A91AB5CE8FDABD9F2E57040F86980B42F985C1A72F25025CA 86E569C31CC567E1DE5CC2C3810A2F5D3B87A558547DFEAAB3A122DAB76256B7 271AA6BDA0009365356D42F10C059653FBA268396ECD874BCA466D34DC781A35 3267B2BE5B8178E62734679AD00E0657C46A223F113C73DC0437FCCBCA55BC13 BFA7FCD9FA6010F75D2D00CC2A3047B16F127A15DA229C73473EFF6CEC0A7444 65DF354C7E69CAC6E1228CEEB2CD5C7CCE51129F1587B9F2EBE70F95726315CA 74B593F8D690A19406F3C50158906519E338B1F4157C963E51ED22439948E325 1D1E7E2E27FADCF60D8C71CBC072AC39748FD767C5C1CBEF46BCD6B45A5E135B 781685744B1FA436673537C773E798A0E26D52847BD83B4F4DFDFB38CDE2C7B5 8D12B2F4EE7AAE65E2DAB3082A449B54C1482A48E56A1B2E40EAE222E33D4EF4 CB90ED7AADE2B106EBC195AA03A94FF5F9EC7EEE8D0F36A765D522586075135E E495A62B909D9BCD0DB505ACB6B259411C9568C0F98AF3BBAF1B248BDF58FDD0 67B76D9BDE43104BB45771EBBF3BB48B12B80D3CC68C2CFB83F50F647650E99B 8EFC9D3FEA4260640A863525D5A29DF29BFD28E4D40CB697E519444446F0E262 D5FD5B9273FA4249623C7A03D5AD30E8B771DA863F30C910A58F5DE271CDD3B5 3C15BD574542AA2B6B19315E38F1009ABD6C10BD934A4FE54387C1F6D599D51A 249ABA2EAD279C47BBD78ADAFCF75FDCF5F02BB9D4819EF9E2001CD68597FD5E F41580A342B14CA74F71EEA33F5035E7A3EC51C1ADFB67C8CF9A92B93E0A9492 C560700825CB23D7317E8DB9229105583278AEEA13D7CD8DFEDEFE97B34C2B7A D0FC1964834BB0E644AF12C59385B2387D58BDA3CDBDD5A5DC5460177C5A7967 46232DFA2E5C8576B0078199492AF5DF45A95ADE1F4B7B0682C7320CA4D8681D E276E5B36405D800A965E58A757590E26B6EF99E5F81038852D9A6EA744651F1 05BAE218F875081B00EBAF3DE4F3A23250C816256350C36A205E44C6B02A6FF9 BC88495F3F3C8BFE4F3E270165D4769BE450155CA9F90DA2044681785434C248 72E4FA285A6BC1AF30920E017C8E490E00665CA98CB41C20261F5BBCE1D18D4B 843C5B4612DBCE350A2CB7B9C1A44141A374FB149F3D45E62ECB4C8D010AEC7E F8EA6AE0B1F8491A49150EBFB06D7A2E9168B9D3E5AD1080ED74EF87B5066F6C FDB480209CB6EE89E5316C4643295F769C4BFAFD4E807303993FE43C52D14BB9 07D85F9A708CC602171CE3EF18180EEF5F801A2F6DDE9B3B33394B467EC36B01 78287E7A63155CD732690016191503DC7507D5756F29C6D461D9319477A0A231 742733509841579D31002C6DEA0102808CE18CE6AC158B605C37FCAC9ABEEE1B 56735C51E48E8BEEFD4436939DA7FAC7DE18AFE09791784AABCFE61E8278CF74 EE0D2E625F74FE3D6DE742A698979258FC88AED292D36CC5FDD37B3BA53B8263 DB3008495EA592BFA0F8530A2FCF108AEF984940BA332D6C1984CC1C9B6F05E3 79B7CB2D4A8BE86436AAA3C6C13F9576BC8CA567EE6DCDD571031114493A791C 718300DF5C6DC3DB806386060D9FA3E0FB439C25DAA00DE1595466BE33CA53EF A7EAD4BE2133004BB7CCB2A3C88F25B2C9D7A795A1FFBFD4F7B2CE353341117A 712A3BE4CB947F93F704E8400C340823736B478A18284060FA2BFB0646DA20CC 28504C1D63A6FC10DCFAB174A6E61620B1C8E3DD17E62EEB07011C52DF5807BF ABB2A19B470AF43B7FD1BEE0759AAF6B285352D12400CB34F11BC670A07819B9 5B2A0B19A87911950FD65E9048B64B50386A0D5B8391F41F0D9893F7A2BFA1F0 44CC2F26B62CAE0A31A72B67955A68F540F89AB31C80B619EB77BC60229A0D59 648EB068E5AB37B4BCC9BD8A5E802A3DE6697FB66A62C19F942AD783EF373749 61F005C97AE9A450131E4D8C53DC057196D171AD61110A95424DB5BFE7AF1344 A5C715807112B3BF75607784F6E63915224FE341310761D87FD49C4B8F0BB0E5 2804EF600725D98236A9565B4AE3B342A06581B86FC8077C39F16A838C286102 9C9FB50CE54B7EFA25795BB291622BE7A84DA0077E8DFFB248A3CF18C790C628 522C7A4B2B2EAE2B6A16ACE9E446A68AA1A2162585F99E4D40652071C421E257 594994DEB73B0499AA67F37FDCFAEE644AB898D9FF5A6F28886CD380230B4423 4C8062AA159B4BA6CA1C1081F0420DC02FB7E568F136FD3422EBB9A190AE3156 08269CB0372703B1F0C629806D66CEF69FE69016CFCFB4E866AD6700C4316D6B A806F2CEF31E95154074F8F138A72BFE460751C04ADD2B189B18A6A4FE7D6620 027FB6AAFD9FCE32C7A1AFA0E2383B1E220AA648F5E0E431D692B33998A292C3 5482BBD3A10D0F103F8CD85242F3B9301CF8749939BA747C43B4C92A1215072F 8323A779BF6DADD0D0C43FCFD9E25145D995C7B38EE2963ADAA5F0433A3F509E 88846EC629763B20985F41FA9FFAA4379EAC242F82EFF802890249B7AC2023F8 D044C8C5880906B57B3FF1ACCF2280A9BD52748AA09ACD8FAC27B921E08DADC2 77E5FA90268F8AA8F5A9EF8CEB5CC8221CF435CD8F598DF4F655538EC35D2F51 2B676A8E12062D492FC3D73A8396CB37034787DE7B1D4F57A626B0166B936E62 AF79692B989B81B1D0CE53029758CF514BC9AA6C67BAD088531A7A874DFB11A5 517C75EEC317621536732055B21AFDF3A4DD0927A636E818CDAF769D0B6FB808 AB6C25737058191CD4823ED8DB4C24472856FF337B0D18F10896E001C26ABA0B 78D384A7EDDDF94E9F5975BF897659CC78C694027DE8919D3A49393F2D3DF025 241D4D14DF9FE975D8EE69577A81E06BF7128A2E547496B608900E662C07E71D 7918F50338F0CE14B247729FECEE98CD355B90258CF05A98953361C4D11EE7A8 97F84DFE8FC85EC0BC5891B9D0C9CEC51FBE20B989D12F786958C4800584BF81 5DA24CED9FFD18EC45E8628EED63F5281ED9CE9CA1941185F7B9ABDF74B6433C CB567E016958F5911ABC211A397A6C107E15DA7FC262A5C2130BB342EB0C546A F8B756176610CF29F3A11B72A14ECBC55773DFACCA380D4A94FB8EFB1C09131B 6C05BAFF1730DE6B52681595941B70A7808D103A46B3719D7280A9ACE8634F1E 10EF857C25109B8402339F0ECF8262888FC6B10E1E3AA1EC7C3940B2AC1C89F2 66620FE2B1F880DE41E5D5C6DE6EE8559BD9EC266D40CF39F5F92663916D4993 829B328C9111553E277F743525F5B4171840E2F6866A72C329CD5D5DC5A204A2 401F2981F7DB7082031E91E29D6A6A7C4C828B1F3239868E7B0BC12C7B9E7D12 79CBA2DBC8B945AC537AB742FD92F136F3CD77EA42FE8B1AFF615A9E93E3F8D5 5508CF323E83F2F444AB10C9EDD7BA6F7AD9987A3A3D813AC677D6F8DD05E464 C80A134F1D2B1EEC83290754FB904DFF33D67B8F44776ECCDC781029CD95A1E9 789EC29F2ACF64A15B096160F9DA3A3FFE07829651C63EA5D69B98F3552533E6 F0B6F2B073D68418D9EA2B7B8E68F77DF3DAF8A1294161574B862A563F68C1C2 F019F3774AE71BE0AF51E0C647A11E3FF5185BB0CAAE8AC61DE96CCC172475B4 C261614E7082C7F8EFC5D053B1647B1AA2AD2312A33E79EE0C76105F5E575E1E 89FEF169DB0F972E8FAA7C68C81057C0C60CA5F45604B30B0236502358BACF89 100FEE0BABE09B32DBBED1108E4E9B8670BE91F124829DAF7109C59FA4AA1E75 51F2818F680436627F004032DC72964ED507CD835B35154A96823387C01AF25B C89AED80497381BB07A99929F21E641F373BD094005AD1FA879EC134424F46AF 9DF0CAF84F6AA5B1C10EA523808E7D2308A82C361B8DFC032EB931610A72302A 9583CB7FE0313777D6AA1F0718C340A089EDF6E38B2FC86360DF3B3C7434FFA7 F7D35588CBD1BD21CC72512B7716B1430D62A0E908B4D211A1862FB6C639CB6C 58B8520AF1D37927A0C13144EA0068B24BE140C66DA8E7BBF026F29A621FD2B7 90F55D85ADA8B173B18F55FE6650F7F201474081C16823F1C75C32CE1FB7AE31 20BBFD419733980EA725B6D3AB20786526AAFBB5F07A5DCD5267A0336352A8ED 8541291B5F7CBE31E3BA8B2BAD7C2F670B4D3E90453D3CE9FE541D7058C51E95 0EED9A0708590B51D6F9DC1B2ED256D4D7C7C4C646CF33FC06F4EA8AE9EFB911 261175D8B1F80E94FAA3F98F87C22C8B194D7B7F4FDE7B73CD64B96718240EB7 66FF6D9B05CC95DEA580764D8304FCFAD1C56EB7C53907E908577C51661753DF 4C4C0E1CA7F268FB69D7EBBF2F54EECC1F1D14F62DBB037C52079634D82AC765 B7E7DF1BFF8B92BDD111882EA4A27A6C77D8D34E8A4037D759576C7A9BBCC0DA 5A043DD49879CB1FCB2B2CBDB8CA5C2593C632675CD0A63683C0D436D055FFBC F241FE910529E2FD28104BA8B90078A1D2A6A2B8C2477DA8DE369F362035BBF3 A838DEC3CBDA4D42D0F58CBE83D0FE8B16EFDA3E07C2D06664C59EAFDC9C5981 AD3F7ECD0A247A54C4F73B22E4CEB323A42116573A1A9E449D1AC8DD96F31CC4 BCC10D35417FB5D7B66FBF90FAB530D171582B23BCE358433AEF8B55690DB84E 3D69F54C1E697D373DC2ED4B2B2209F4ED6C15DBFDB31ADF14434F695820E4E0 AF8C69AE77C0EBC6A8C3ADFA1A0C5446B866F4E666EEE16F92A7519178716993 C0E98CC0307A2B4E56EAEA257932F254BA8DB5B993AB10A91C6897DB7C66020F E533D6879BA348E929661DD51A21E6A05C14097E2E33C2909FD60C2620980E11 2F4EC765A16AA1ACDBBE5E039F7D0FF3797E9DB7C062F688595B223D137E2393 414DEB8EF551C973F9632D47F094C4585A1A98E665339B839947E1E27BD91029 A0E9CAC9FF01EA36089B60B4C7EC01181C46B00874FF13F519E7D90ECEEAAD84 0E7DF23C60B1D885EAC2D786CB4E75B9CE063259902D1767CBADAD85142BFA2E 568EC8A031CD622BB5FD276CE7F16EA0F056E69CFF98BE4B7F05F3A182504454 D11D640D94730D99642AB62D92886A4A8A5AF8ABC1D473D7070F91CCB247CFE8 AC2F2FF4A56C4143C9D2CCA44D639AE341181712AB7F3AAD105CEDF8569F795F D8C0F16C9E31CFC0EA069AD08C6623FF0EAAA0EF89BB7E0A3D10FF30C36136BB 7EDFBE6C5A4C41BF25531C03EF5482C1F6C0E74311B125AF5FCFACBB314A699E F69BF956077ADB3B3D389F221A05A606BCB8A64BC9DF0821936CD07DBA4785E6 8CE4BB75AC2E707C3261C10B491436BE1DF3BA9C60003B142C47CD4FEEF36981 6B57022B09FDCEDEA1AF467BE0932296164E49A9C3940C72EE30A0A6446CE0DA 9F6645FB13613425F391938A0FDECA53513AD4429B17A15DAC03F1BCBE13C43C 501D531A16E6DC1FAA2CF0168803A5DCE6A49117B0B754B2B52C08BD4BDEABEB A165CED275DB74CDDBE4718EFD1ACEC59F47EF3846939BFAADB1DE35BBC8E42B C97B7AB1E9DC5D41C459581F99EBF0BB08B2379D67893C6F42EE3723A0E482C1 7F089EE47BECB1E561D7CF94B12B8D7355C153109FC3C8FC7641AA375205EFA3 04BCCD7BA0C17D3350B66D5BC8CC5096F060113ED02CA3D45A8150B26D645636 1171A1A366236228087599BCC3280F313B68E1CB12F7CA8083BCA3EB5099758B 07D335B5DA120C768A3180ED1C2426C11EA93D0DB75C97D3DD33EBE93CDFA881 8AD01D64C9FDC607F5C2883B3C5C85BCB132117C24E153C72686E8D374A01DEB CAB16ED0117BA0ACFA701EDC55072A7B012DFC9CF8175E23674F0C9238154DAE 75A0E91D39A856F11B6B526FCE03CFFB227B609C62773784DE499225BE3EBE93 8800A3C335AE4D1216559F5D1BE8D1D01F95ED92B36E27C5070359A91AA6E879 ADD992B27FBA6C2B7A70EBFAD6CE838BE193266BA1CA10E085B42BBCECF68FF9 D34A41EA24E7229F701DA3A8B721AC8650B72D51988D3AF540D08529A119FC75 28DF2703AFCE1BB5DB1DA19F0B7113FD5061B9F984745E18F11BC984E22DB580 D881A7D5EEF289C747BCACFD8796E8925A90BE006DDB589C89CA671CE43576C6 D6A62F146F2E9FDD113D502608B1DB4B1A424B809495320C459C44EBF7078278 845C4A136610EB55AFE3183AFFD55CEC6EEF0AAC299B0A3174D3888E5DD4E5CE 22DEAE199F6B3C2FB9AC6B17CCE52D6E73B406AA41CEA6FCE578F87275D17F91 CC6F5DEA8A5E17133628ECD1E2F75322F3CA931D11C9A30FB755EDE7C0144D62 B747CD4F0059B339176917FE7E68F1E2F6CD9D605596B5D29CC1C594B0AFA172 887001082F3713D11D4950AAB0921EC683871CC578C61A00099BA29397A8A2FE 21CCD7857FB02991B3809547D8380CD5B584318BA1385FF6FABC0C9915560061 5011671275309A92BD39DCAEFBBB053622F74ACA707911C458049FF97DCC6A6E 8B3958595469659FC27B108BEBFA56A47A049077316889D63403B016C271F76D 0AF178911950EFD0122B2FF8837BD2CC6B225E00D4DA958B0C7EE9E6BD7B58CC 5BBFCD36531937E1422D74EEF075812F1E1DED96E9D75AEF0703695D9ECD77D3 B9C5F315A6801A5816672C850D1587CF2DAB10CDB3A13832FAA6430680F023F7 4C39A915B1A3EE89725E5AEB17384E0D116AD6A2627D07F8D51A24F08D252B42 4FD95138F53D8348E161263D5548B20DC7B89DCE1BB16A7A6D0EDD9A1B97B2CF 5866CCFF61F454D138CA336698C09BF84D6D7A3ABFD51EFE525057A485682F1B E25A034BD603879EC3B8F8FA14CEC763D5DD4DCD486F63C0749036574B6B8C74 A78D9E74F5CA7D972E0411DFFB4A54CBEC53F7858038637DE5D3BB8D864359D3 D43F8A74AEB892963053F62AA4C2A937A380A67AD03D460FB0FC949D067CD31B C5677193A821B0B3E6CBCDC3FF63DAA1668FF4FA87CD19B345CC9344AAD949D0 9D325D1204D07C0232EE762115BA5B1DEFC02FA738F7C8245A54E4664590DAF8 01D7AF378B9ED74BB5ED3E78E99882A8EF61A382876660D00180015EA8214C58 798B56C16F183E9E658A4394A6DCCA907DCF5450066FBE44BC4BBB93D96A9711 883D1296AC06A63BE5985F1DB1548DC6CA94078DEE3A5311E979C70A055A2423 14BDF4F80DD51F03EF123678A924C4172FC47AE194F8950A39156565A8DC198C 3943B6B4A5FB081952F004C10B38A519FD83384DF9C67622BB95BBB8038F2711 F391948E5BD56AE504C774F45A88D0065DD6705DD4A80C05724DBB32E2734295 026E8DC1AD6D0448DA75B3F536D2EAC29248289510B73141E68DC4D340BD6686 17D687FCC72F67BA165011DE120D9930AC58F0FCFC8B2B80C7CC3BDA1745EE69 41FF7C49A6B00784138003C36BC63039510418FF1EC6115F2360F0AA9EDD18AE 8C1C6F83B372C846A62AFA0ADAFC495478D2B16C92D3DC9D80E7BC03A0FA58A4 E9E25A122EED371B949707ECEAC0F78B8AF59DE9B25CD59F144CC29259E7C951 192FE0A8EC540A73E8BE7AC610486C161F3FC4290E2A64F6574AF9C0E96A2BEC 069187F54DB7B296915DFE96FFDB42D75B7A8A8B15CC15F866548E56D28185DA A478C46CCB21887744A46872272745D693D042EFC391B58E26F688D55AB9A633 9D5B4AFAE166BFDD84FC08DFCFCA9EA4E599A208ABBC92F06FFC0DFF237D3F60 4DE0995A310115BC3B113D75A0BFDEF746168AB5D6241E43A841D86C87892983 31C08558982604E0928FAC8A0D4357ED8E0E8DDDF9C548ABA8ABB72FC0D50D68 828871C1F182F74715F117EBA932CA1FA40E3D2B4387FFE5325D2AE5B1EE1DB8 018C1F71E9D4BCD8BB79ABA826BD41C8020297A8C34EEF063A17B4E99650C135 C7451D2FCD64B90925D21BDD50EEEFB792CAE6CF25F4D2CFAD6D393B09522401 D0574D0AF0966BA4EF11C42D8BF6011DA8D2E4BB89E0EB4C3DA0BB5D0C7E63B7 42469A1B6BFFA45B04ED88FF8AB4232EDF018FB964A78DA21F71D1DF4CD437A2 FD0E94D338B7609422E5946DB7716B0D99AE132C006CA0B68A55ADC1B1670F93 23A7FC35370D660B17F2B63275A108DFD3EB5DDA68763F6C6194E3209928C87B 6678EC90DC79DFFA9CB28DF1E6EBE1DD26EB372F9AB87DBA2E55F00C34B2BAD3 2277A2F9E94C9F7E337D6AD6DA38B71DE303E9A0FEAAB0B02EF494A246BCB026 AE40D35CA15C50CD05B54F691D22082E9C66E34393F6923BC5681BE2AB46CAA5 4626855C705DF4CA8A4C4FD99D35E4413D3EF2F9D2CE5A85658788C172FB9EA5 EC6467DB0CEC935C7532E67CE07649A0E76D309495D76A50AA3D1CB9D70B2DFF 546E556383FA07ABD62F68A75FF2AA16F25C489849DD1847905B052D0DA6D924 68D7ED1115547EC2D1A12549648C0C498C089A62D0FB3322757B272E8BA81244 170A972678A8E983152A2FE30BC16A271B52E0B6EBCE6FCB96ED9BFB2E4E4C99 C93500550678F121CA1DD616C7F861BF45F263BDDBC1A6B6B8371E23402A2A40 5F59BC5417C0C69B1F259E54B9AA2596C004786CF745B61DF62839B6005F3ACC 052801AD871E6A8C8A74776D9E8691770506A17B623CDA53C63CEDA83C9D6299 CC92F94B3178F889AA4D36C3192A2C0FCF4817FA270E096FDD8292CAC4EBBDAE 451173BA1A96D3D62EE29A140D80DD951CA3E10AFF54D51C8F9B80664BAA55C0 7F1D980A52C3B4F483087DB51F6F594D7A3E272C8C86A0FE6BA8FB47F54A6400 C1EE164D2CFEB61AAA6AF67B361624B55F3C91B00CD043DB4582FEBA153E85FC A1E73D524B4BF95F 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusRomNo9L-ReguItal %!PS-AdobeFont-1.0: NimbusRomNo9L-ReguItal 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Regular Italic) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Regular) readonly def /ItalicAngle -15.5 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-ReguItal def /PaintType 0 def /WMode 0 def /FontBBox {-169 -270 1010 924} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E134D4CB5ABCED39AC635 DA001E9934C198A7F9B9ED0028A85E9AE00421DFD8EAA3BB3B4B4CE45D209303 237BD51809FE4D880900B1EEB236ACA87B9FF6EBE6B994A60AF5D67CCC42BD56 77295C346EB4C62BDC1EF22EE07DAAD928DFB73455F091F32408ED6430B97417 683AF27A03718A156E3F6E7B6E4F2E8177503CD82DDBF4557A3CCFF4C858AE7A F7EFED6CC521A28342436B953E4650B5792BE85EA2F989EB6D986905A61FA38B 96E1BBC830B74469150FB0B598A794FD80D10870084A877273A9502C3456E5EF 74350E6E3BE5863E8BA185EB59FB87B36566AF71200B6ED389D1287D4E925E33 B2383ED05D87D48586E698FBC5D562ED9D8A09EC3EAA1B1F300224AF20C23F26 A2EADC74562571DA84B3914D1D80B127C6FF4706C7046BBB372A0013E0AB94F0 C27946583871D272BF4F20FA84E89D745DE7BBA885CC09BA72E0F530ED4EF7D1 864B3C67007ED98800284235372F0A70C912E21E851AFBF812165B8DF912CD1A 013E271F0B347967876C68AE4C4107EF8AD1F170916210034C66394A9D971B68 FBFC1131E37FC178EB97C1B2A0F573ADD9D7C0BF944E6529734DF8A7EF54485B A3375CC30E9E328943733CBD352BC15B06C85BFB4A96994291C72A0EAE84FB01 0F1B24D0125FB8C16D60561DF8BB7AA7DDFE9549AFB70C1E89424214609FDE41 9A142892E30F02754FD234CEB3C59A2A04C06BAB7AE40E8FDEC50559B8347684 391C750987802D5452C47C1E0B5F222DE9A0EEAFEE19D796FF375A1E1EF0AEED 1BCAC4F485FCAEE18AEC585D1A9D80F41871DDA45FEF1EAE82C5893118987BEB 4D9E345C27C7419FE65E4853B40537D822E34FF1E0BD2819D21EF607981259E8 9F1040A2D708D7463858AA5381759AC49DF4DDDEB209A278FE60BD2508ACA0F4 6A249A05B652E4C7BF1B676943CDC463B30D42094D13856D56DD2B434C587169 707B01BCBBB9B720B45EBE7CD48FF2634E40285442310F2FE0596A73150F2254 5CFE3285AFED58991E9EC284449842FE797BA4507DFFBEACADF4491AF8D5C56E B94A0606D6661334764F62EB1227A0123488E56195DE76712A4948AEFCFB8C14 1457531E7E800C56BA3B85B8984CD86C95BA2C884669AE0C0DB079050609754C BBBC246B3B52C32FBAC82F0954D1DD57FEEEC115BD914914177238955795B8B5 F0761CF5F602D773170B7EF673785476660078A3C0362C87214B6C5205D7B59E 09B5431392AE9068155217146338DE3D4C65A183134E6D92B811D773B475C03A 372183C536651BCD254A17F66105F277E5B6745FF4A5CB0EE90FA42E15294557 DCC240976600A90CEEC68D8D1040036F2E0E500DBFB351FC50EDE8D18A56D8A7 0386B64579036F45302147B93FE85F460F1ED1372A84A1AE47BF09D6A0EDC57E 1B2EDE3B4418CD44C3FC0CA87635FF92F1140B7DA97CC8C165D47371FC14E56A AAB01F70AD759643506034C9C7D5C18FE5C273C0C08E671CDD80A6E1F7C2A82C BC29FEDEE39359C351BA8960636ADF062E97DF8A0E5E6E64364A9C461F89F7C6 B348D3DE0EA4B0C6F516FE87B119E547047F439B0B0F034B2086C1D7F5DAFBE1 2E081339CDBD43F5DC231ACA34CE544502ABC9E92F8890C25D2B5CA62ACFDAAC A41DE62051E7B246582CCF44D5D5895E86039A785B83C70C455079F11247B69C CF44035DC3B43B66E3E5679F63FAFAEBF21A4828C579BF25022C49D81F0EA4F0 37E39990B91C977661577637381DEDD4AF87E81FB5B8D5C702136A228EF0C0B8 703123FB2153DED6B9D4555BE6678EB5AD40A04BA972EC6DC7C9E4ADEB7E4004 5F10F38D45365B42246117A5BF1DEEF73D15FF20CC36B4125F60F41A27623712 B626E7C8B5F8709BC9CC5164A734E594E86464719934B4342C86ED7BAAA66B45 7B4C36F8A55091EC4E2B95858E61EDD3D283D44C3BAFE9D8032BA499D11820D3 75EB9335A59ECC10EEC509BFF2A817CEA931713A2B05D654E490867BB833A437 B84830885DC5F1A7C0109B7AA83451905809C8EE3A56893F8FB2177EF403A143 712C54BD17331C8BEB676B6512E5FB788C79A481D76BF1F8E60E7182368E8803 334CF3587AB339435B76BBDE64BA17833F63F2806EDF081CA5DD2170B3C48949 865C984DC350DD54BE0A5A785EA7E3C6521F194E665AFD6EFA179815724E2EBF C3EF435F439E8496469B85E2902E805BEE7149F2BE93A57A85CC583FC5F19EF1 FCA0E3E26DB60A6132CD2BDCB2FF190C5218268A847D88EC1D76AF72118C624D A5307D3FD79DD7A1E3A7D87373B3B9C612F1FFAD8A9B979A1F519B1419C8AF8C 99B6EC8D5EAB959850EFE857BC9F9721CCAF6C9DAB7A566F745EEAE117ADA35B 71A77A4529D29FEC0AEECB394AED48794765B91A8DFAE56EF85B5AD1D0ED0575 082F7BBA6259BD22437E5DC65D2FC8CB2949498A322855CA07277DAFB8BC1543 CCEE23552906FAB7215DBBD0428CF60F70B874C9672DE056845DEBDBBD9E5EF7 EA133EFCEC2D2EAF2A829614B74D3142EF9549356ECB3B50BF7D5A8456CDCE72 C8D96DF1353709EE2A562A993E920582C02F669D786D8E6FF03E9C4C1F3630EF 10C079981B1AB12F9D212615B7D1235C3D58DDF5DEF3AED93DB4833D4DE82386 676CAE2D18BC9AB32F209ADBC81A3F255D199A354F4D28DC5CD519282D20D6BD E27B65F9176558D8B65362F61FD87D987432CAC2D5487DDBDC27DCAA73799D93 08C7344ECA004178A03A3D1129C1204E95D0F19C0E9A42DF896B3EA3AE935126 E72E876B043B371F75F8E4BC40BA7A19DA316992058FC36C23CC8E7F505F0AC9 317680A45DE4728D195114A9B35634AC999453690C2945D12F423ED09D98769F 099C8FF9B12A99BB88B018D3A3F843609C13D0B931DD6FA82AD59F2493F1D943 B4F4CF99B32F209ADBC81A3F255D199A354F4D28DC5CD51E11A6C348A2EEF756 679298AAE244A925FD7DD45F40E15BFDBD9D1711C55D85517389B468FAEA7A34 B37E4779B9E29AA08A9A1D1C8ACB7BB7DDF90F0B10B970438112ED925C55E4B0 DF0E5BEE4B29E5DA8177D46E3FCFD52BD31FABB9681E652107B00238E9CFFAB6 DE9A64E9BBAB13EA9337A2DC9078DA819E0EB14EE53FB4704DF3C05477D512DE B8C1371FD414D9825342D852A319133D5AB7AD555619E1481BECBEE8959D855D 05D00E2B67197BDA7C0CBBB59357D19D0CB7D0DD09A03B3EC06B976B2543168C 893E48D5396E874DA0E4AB11C078B4B343DE608AA42A1678786D34C701AA0836 863119C73B0E298404F601199BD3D3486FA04EA2DEE42F8446F209EC09603635 1451AE7425A26CDC319A31BDE48CE8D3E9122482F87852C2F3EF87B7F506B8CD 728DD49C2FE559C757A92D105F0E30BBD698EEB9576115104C5AD87BC27392D7 A101E273541B8FFD8A9F88AF428E5C1B3331DFA06E332B681A450A2957916CC7 BB080B616E07D44AB5D1CCBA8DBAD9ECC6FFB3FCCBF4787885B0C1A6D5250933 CAFBC2CBC707BB968B61EEE7C7995CCFF49B3E7509D2D26DB780F725B6914E2C 54EB39EB3C7C9EAEB3D47348C47D928BC883B8E7606992F553C59AD3E6B3AB0C EC0EE7A7FE3B0A082C4C416C07AD4AF6F96A9D4A07A4A5D2F08797F62FE16213 BC27789639EA7B25D40C5828035C63D3F6F0C3EF0B66A09EDAD183703D498EB3 0FBE4BD9534DC9D288CC912B2DDD2E4242739C4749DDC98D71E19DE41DB1CAB7 0F0E305D09C4C38D16727A288103EE6022F29DB2C352800139312C2CA31724ED 8C9FF44C183A1FCA5708A9C6CAF4EA33D8870293F8EE30FF8FBA36CFD0946773 82BF55A4200130A8F4064117378E4A9C6ABC1CBBFA24A6271C9D938C8B2991EE DBE271EE03DADECC06717BCFA74016245773A46886375ED6196311D0AD6CF85E 077BCB048EFDE8E563E3DD35EC84FB7B149FCFB33B35E3732BD2CC59E7FF7D4C 8EA02D8B1C6FC8DEED28D66CE0D3D5B4171074B0B21AE18BE393984499418AFF E576DA5C7B54C834E05C08BB18374623A45C5EB8C4C98AC161A48059A0463B17 F3DFE8A73B46E913B99D25313E2FA52F65CB925BDA5C98E98C7BA5E25EE152FB E42E23DB94A0D96E085BCDACC4CCAAC9DE3F669EC03B0B4E320CB26E2BD241B9 93D1925C487FCE04C40D2CCFB9D2FE13E54BC833576A95C2262EAE7BF29421DE FB89904AA737169B00CFE54FB18E1D3B530E8F75C795C8183E89A7FA85A0C12A 52763634899F898B874ADC35209300AE63A15A7D983219EB991B300213F412BB 8B5B9215BEAF72F041F17D55B49B81F3D1279BB697212048EDF14479D008ABE5 E434897E2C25C96D717DBD0A6B4CDE1903873187DA86D2C1B5D227166488A642 299C4149A5AE4E4FAC9D0702671BE7D9FC266B4DDD168E78817B72CDDF15B11F 1F4383D669A546C86409D12E90D1BBBB4BD84130D816DB1255CB2544AE8046E8 532AF543E46B58881A512884C04147E59CD8508A5A15CC47672C9708445369CB 732A7910A22ECEF46F449E19B977BFF9ADFBA70A0B3C69FABEBA84F509932A56 268AF2DCA5E992ABD2F8AF10C7214EDFCAB06D285A20A33D2D349E92B03933A4 B520E6A884E5955709CBA0C3FCCD7B4B3C2F8B5E025F354C8979CD55B5940624 6C2D4F191E9966E0371B1299058FA860DB97262983DABA4741F3670147BB833B 0D91A874F95B68C0CAAAC8FAEBA2626CE55D377D3EC454B9E8E4E4B789738723 4F730A1D27A042BAC9F13D51C894D53C875ADD40D104BA8874AA1FCC8C5F6489 36244D75CE65F2069A0ECD2AB701F16FFAC44FAD2FDE08373F54CCB8CC1E26BD C5ABDA5E20918DB32E32E2EDF90AA077E3000E29C2693CA6F47CE7B2CAF88917 F450648A58E5FED7DEC2B996C9CCDDD789D38C3A38302364ECBA6FCEEFC6ED10 796E860F5395FC172DC2C44FD40C93B853936472C436E0BA184BFD2B8B3D0A32 B04CD789F5E9FE83D88908F2B124DA1337603726E2D2B0518D9655C818F697F5 D313A472ADB56C2DD22F8929D1AFD344B772DDB2ABC5AE5ECAAE11836CAE0376 89FC27FCB82EEF127C096A622A2417D1B1F755ED5D6170BDD9D010C5E76E844A 969D2F9F45C69148A3457D6EBB833F55F67AA649123F4B18C5C81A4E75F8EFAA 784D02E65604DC7FF738CDD6EB1B5BF1F8E8CF8E714580AB02B561FF49E6D9BC 9858A3ED3CAA1D77C3E31A0F8CF4004C27DB20FEF9D0B000F6337B5192A10628 6D66A1D329D3CE861D48CFAC4F43D6A8D8A9F924028ED7797FAB9461A840706C 85F79D491064BFA07541575AF7617E58F950A597C4A08180C4BE32AAC31F6F64 99A47EB669E678E49B86843B79F2198884EE6D77CA7231E752A72AE2F9871E19 212ED8167BFD6EB578924709F82A1A10272B574698BC8D4E3743B86366406AE8 9584C3B69E74BD5CA1B86671E256BE84B29E29699E63A013EBB169D8282C93CC 66B2D01D6DC874B434C63F45E3AE2BD7E3D16CCF5DC3E85AF7F296FAE91C9F8F C0E892576552117FE414C3E87C7F867A717D4C91824F27BF24E714939095AA1E 3FD028AEB72127B770666021CD197B4C7B75947D5B503C142F0B0017EF0570C3 6D7F9B6FC017F1BB5B309AA45DB0FDF9B94F09E0E45129F9A9915064E7EE6935 C1AC106ABEAA8B4C00DBCD9A86E3A09876829442E4762C4EE8FF48CC39F01872 9770CFC63A6A36475154CACD25A0397FE3E22672D30E1A91DAA29EA1EA50EDE8 78B0D7C05DD7BFA6482EAB3BAAC35FE1107E37630CDF2BBC34BBDEECFFCF92B0 A5F150B9094D944299D44CE5AE452E6892BF98EB5FB571CA910616EA9129BCB4 890E47593E769F6DC0B44E6E0B0FE2A4811186C88A0003A4F9AEAD63B8936334 C65103B82C76EFFC8DA574224082BE8181758E98B9CC40006FCF8902A126D044 C1ABECD3D31928B23178D2A33EB10CD4337BC72C2ED9207A9FFB3120D562C01C DDE960B6BEAD814FE31D664782D53A36C672779DADF227F773230806FFD56A8F B6F7CB455A6628F76883D50E1375DC1FA05A1E1676F3D23805CB9620828E3A3B 42E9FC445974401351EE28B1A347A6DE47C5FF27622AD08A33AE6C255C3DE3F2 6C9041485C16FE9005D865F680319DA302AA75A05B627AA1D8C2624995152679 4E5ED0F7B504E5F72C027C1611FC07A67C1B47DBB3181134CB88476E3253FF67 E0B3D2A4E23151BA43336614744181C7C90336B339EC76EAD2F1E8C1579ADEB8 FE368265C0620C7F12E5ED0B14EF86A7E9A228898ED04E2DD76ADAAB42D2BBDA 6418FA4FD7012A9FA8043258021181E785A5A6984A139AA6D4E7C9DDE93F20FC DA4896CF035A3B45ED6ADC04F2DA8031CB102350FF15E63363B41F13C01541C5 43254285B55E7E81A66D84EE55183573CBE31864D228C0003B675E824449F661 AD4B5F57EBA80472D3FF98894E3762B9A549F444CD0172E0F081562A4D800E22 9F3D10612D27E471DE8A603B1C3297208D49575CA94D8E6E8E632F5B8E571BA6 2054C5DDEAD99AD9FD5A37B0D5BCC15DF7F74A65872E1302006029F2B7FC3D9C 7560F8BDACADD8DC587EBE6B69E71581F673300EBA41FD8958DC4D7B66A3B9BF FCBFA5F053592FEA873BA5D41152ADA8E91FD587F64366AD5D6EAF9A0440D5CA FA2336AACFA4BEFD781FD469998D817921CA09D9CCF310AD4D01FD28CEB2C4E5 93B7C388E2CD1A4A0166B3AE067027758BF94CCA7E8892BBF6CCD4A19618D260 CCF95A7F7AF1734DCB57959FA16EBBC7164EC284B5C602B1EB2CCE2D70A82A73 959730B60381CAEAFA39C23954234EEC0B46EE91AE7003DD54CFEC7930A3D306 3D2F9AAD31FC7E82E7239CCA7AA7696198E3EB5DC4F08EF7B9088DC4EAEA6DC2 4F469D50D7A80844A6EE4DF702C8BC2D3D65765B7C55B503E5F7DEF09F937900 03E163A166902C80C452E642F01CAAE307ABC484370405639C15783DB8643038 F9AF712AE8C0CF1861AFE3978C9970034C9B90AF909648A0320DA6B8939E3854 4B1639810F0E024464F87517B4C0116C21B456F3E5251758116E2C8FA362B003 B8C13A0DBD370CA7A7ED454FAF1DD1284405905281F663989B6931EBD535CCD5 4244EDD7B57FACCA4C0BA6F013A1311B164058C498043AEA92760A0AB2119B9F 7A2CD1D1AAC54C1438CD7A796C8AC88C292CD50D2527E7469A5283A557A996D0 EA601D70FC5548C66F40C6765781DABB3BB5D9F6B4F7FCE1163D43118ED30D3D 908BB01F7C97E769B0014F43AA2DC1F275562C2E450B9BF525AF14A0353874F6 2F6E7E4DB197E85C7EE03DF4CD14BF53B9CD02D709420B491E8DD418556CF518 EE6B939CBCCA1BAE5C122CFAC2705541D0221BE8AB3B3D020683696B7E01E645 A80BDCF89F81127D86DAD32E1DE544321E7529D3593887D50E0E5EF27B3F1FB1 72F50F9F230EBFEA8992E482A274261BF1A5D84EE6B75620BCC3E0D18CD8C90E 567CE524B1EB4FF37627F897EB702FC0412642C873E35AE44EE396FFBC862403 1CCCEF1F81485B990FF42E8B1E967355304F26CCA4462764EE6CEE9883FF0E1F 692D86992580BBDD40D1DC6AD196CEEC0B54D7E5149709F3CEB3FCB4C49827D8 9164B12BD8BEBDC3D8F52122B8BBB73BDC31C477A7F1FC73B49906DFB5D9BE91 1519B9438692C501C7D747DDBEB3A84CC4F1BCE8B6B9B0696721776A78C59F75 7D4563DFA8FDC296D3B58CBF6096194C97614275626178528869451927014B7F DFC677387219484DCF488F11559E31516605600FAE7D4D65FB006D3E55E1FFA7 45302659092DCD7BE3BAFB7BC998425BEEA7ED27447C9B2207174E1240014407 181B68D3BCDF4B792E1AD79609938FB6D5EA1F736466EF878BCF4C7C1D3FA86A EF4D1EAD98A2ADDDA93AD70316FD49009D1DCDD4EC14DE67DCD13586013B10BB E91BC55A81CC8976A67EAE92EA71FBEBA505846416D1F2FF4693372BF29695F2 BD2E6A9AF02684614ED9A3B3C36B701FB1D136C5772C30918BEBD96204FD6EC1 7012B1BD55EC09503BF1AFD8CE88751C2E7886A9E36DEDC923E8207D34AD6401 70B2B2EAF9D353E8BDD6617F52E76F317EF20F427798E139DC9F0E390213DBE1 8DFFBE764E79DB9077ADB7BA86FAFB1F0602630C08EC8EF6000B063A9D4BF448 96A6D43F341289EB7EAFA7F16E56403F723870202DADF5BFC2A807E3185609D2 C1E3B2CA9C1F7A77E059D7D2F04555ED64B891A1D2DD8DF9819A79849C45FA34 D3B0BF4DA2612F4F154D279841D354416A9003B66D13B9545377CB8FD3FD9F1E FFA26EB6DF216A9A060A1CFD932A7A89547C777FE5B14C7533EF1A78B3E1970B 4AAFB3A0850793D13D9860ECC8C5CEA4EFCFF4936C2BF11A7EB8839EFE7A6825 7D2D51247D4693765AEC0F8FD39ECAB9842BF5CF0FF1FF4E848E0C391B60AF52 8C05CB6C4DA49C435BB003EA4BAA7A060BDE8C59B0511C453BD5043D03240811 E8D4DE2F4D59C421D80F6C64897B0D939061E984E522558DE71283D89AB85AF4 C89238759C2647B40726EADDFB8CD80703CA14D651689B02E2D40285049242AE B0F7B210A16F187998265FAABEC625523524D79B67169F1FE7A3D115E94D8312 6336DCB8867A795FA539346580F53F51C9B08071227756C4EF1AE31F8C52AA2C 250384F710A002921B4C4B63F25AE01A4F8BA05BFD2C17C1E63CD0B7F53872A0 94C4C437D31470F038E8AF13D029A153C721060702EE124D86D16BE33DCD967D 167E9901856FDC0617F568608C6A8E353342277338184CF0E9003195F95F3CB9 C15E7D96112FBE6F32DCF32E79CEFF2993AA07310DB142CEC27A7505FBB08C74 CA5909D21566729EDD74E69547945BE7CF691288201F64D8356CF89D69D10EE2 E0C20B0862280F2C96ED7993E2CC509745CAFA7A50A28B33E4B1B0926313EBA3 45AD5ED46CC777FCCBCD890930441C1535527AE955DA4CACA869232783DB075A 69EAD7D13927A8F8E14A7959731A74DC4B215D7EC095EBE86A3FC971CD595A8C E0E93D45BF7F6098953C01ADE80BA8715842A02E05B02D4C6603B5D62633D4DC 6CE91B83AFF682A76FD3A7F768D29951166E7842CC737495F33CA4157845973E 31253DAD08488B1C71AA6F08A5FE3F6222AE69EE77F3D11D7F08293CDEB52C95 B6B66A2DF1FBE19CB9E0EDCF91BD788D8F261962B43870D5928D160218ABD791 E544643B9C3417305B2906D26756132ABB51B16E17DECCEA1AB910FF57513810 E439B5705D8987D32CB302AA6BECFF82024F043B8A1F226BDB844639C5C1AAB5 A0C76F831A69254A546B6DA8EECA492D56B2F9F55B30583CD2107D819094CD8E 14744B571776B1D9BC9C5446020F72243748F7A097529B9C4495A1F67111358F 429B52AAE139B7F8AD86350958A9E78A56DFE34182AAF632FE7370551A6A96E9 5B783B19DF63C68E548B2CF2EDE51F8138AF9512DF8EED368F9D432FD94E38E1 E69E02FE363C31913AEEC4DAC639B43E079AA71F5C35E4F45762EBD6D3636C16 2FA2E8C6DC5C92D22B2474AEA49E3667EE9AEE7129E393BFAA2284F02BD11FDE 0E5BA107C68B49F80BC01C52F79711F44C1487A8A062B0E7D307423CF2852AD0 5433AB9A259683BA62A5132CF549382EFA09C29290665D43E8957D5ECB3BE140 10F61DF82876C748C4A12ACA14DCA386815826A0132FCFD809E2BC34AED85936 859171F9209860CD9A02E15428867CA41ECC3FE33D8C93D241A9E50F407C2D4D A38EA432F0E7A6D8221F23B7C33CFD987E00FB8A600F088414D8992ECDA0ACC3 9AB210921BA8AE748C7FD8CC83AA4C7C9C61A51649E73416E15ECEDC01725150 6608A2FE4693A2B9B3D435499D35A59EBA205EB9DAB558FC69B86672F40041DD B160BE6CC01F8060BAB27C68931A0C4C0DDF292C1402A990D44D61AC1D150BF8 D6639843D08FBCAFE02A4FABFE9E13B8BC0F4ABF214F34DBE9C6E0F4BA355E17 CF325E5CA01FC85E5588692E74DA5ED29F290C37D03C0EFFE15D0917BB65C8DB 6244961FB27ADFE350321D534CD3E87B84F8ACD636123E5C5B0E4EC4A6B774FF C5ADDE0A3FEF127DB53383AA2F75D08BBF739C50143CDF7064C9838CE3915653 2BF42FD90FCF38782A18FA9A988246B093CEA97B891D5241D5D65C62AA7FC86D AD17CD3297D788550F44397233F7C54CEF25313CD7BFA0E1407002BF9383048D 2E0C74E7DBBD30614472B8F48AA09E64CC0DC2E0B1B424BC8772734CEDFA7D81 7DCE5BDA73CE5E87C037248711FB08AF2B416E2AC5663D02A3008D95849AB497 EFECE67236324E648A7B82003053834D344601156666C7005ED5F44F35D27A1C D9D7E1E9B018650F8D7ADA833BB4F418F9B69774AB6AC34E2BFF89ED99E6E260 9318FC8BFB37B0E1ACAC8D6120F25E5D7AE3A78D97EB326BE8CE321B6B99FA8C 60A20B9B2C0BA4B3829A603DA9C4DE48BBA970275064A769B0245AF37ECEB55D 8A760931640ED09CBEBA8F9960EB7DB076BA5AA64FFAFAF854B340F8DD4DA90B E2B9CD6468492FE89F47B9751338BFCE5A648267B080E4C2F1F24C78894B03DF B1EA3203E3A961D00FA0FA72A866F5C3473CEA633B1E7D28E666E537C6070EC3 3A86602F8ACA1551A47537FB35E3299476D3DE85779AD38CE90A030C095DD9EE E981CFAB40DBAB63E68ADE13FDA369B098B4D1ED0367BF3D24504FFC767916EB B69F1EAF891E3B72AC53EF5453D3C99D6DE84152212E819D5BF4A77F965AFF95 60142B9FE5114F6767789D5544A8FB1588D047EF5BEFEEDDB60E2439A9CB1F76 2D780C010FD675EA49C24BC1B835346BFB33DC5053B0E67730F768D7109DA39C 9367E533DEABFE66ACD75238ED6ED28BF8FEC566053AEA71A5AD3A0F2482F640 7FB2EC9C872EECE3001C9DA8AAFDA759A481F38A96F05955670370784F6D4255 98D75455EC7C44539F1AA106C63148475002412C3B32A143AC570E86B81A582D 21779D399FB98A28CE462CD1C240F63834BE3D1BAA81883CE0E95C99D96F2DD4 54FD6192C8ACE989832CB51936ACD28F1A1553E4A1B2C61BC28F0E5D1452FDA1 BE05A77BAC3487E06AD648A280D52E31A189DF317DF39F5046A8640D63BBB1E1 DEB0B07937678DC9C7F6A80E57A0CECC8646BA826572834A4D5B93CFE438B6D8 006526E7AC4B60E8C93CA8F686B89D3342B4768F0519AFAD823BEF7DA8C97CFD 6B7FA2EEFAC1BFFD97ED37503F9DCEF9942BD5D0EFFF4CEA127335272E7F8A00 510D541FAD6D36F03B9ABEAD539047CC48E4D8481022EA9EABD50E1879107580 39BFA3D29755533F3453C12CF1579079A213CF090BC879F9A66CEFC95F07DE6F 36C35D03C8645181F28D2C0108BFE6D5109FDE9B405E36FA15BCDEA92A149BB9 F963FA6AA8FFE2288525D0DEB8AF4EE6BC02215D515EF83CD0F2A54E63E111CA E85876A54347801CE16474ED24B70A451B58DB917F06238251DF36C3CA8365F4 252EE5D343AF31826D1462CC9A6425C605D0CB47C963FD4C2E7CE12B778FDA34 3D7629447DCE008C966BBAEC3D2D2D275F706AD6E2481D44994A133ED4DDF1AD 1AADC28A0F837462FF07E58C37DC27A05931C9CAA1EEE8E34C276E37A0630189 CF79A78190BA4B70B8AB3980C5722F2A1CCE63E625E068F9DBEABCBCD3ED163F 302954A51CEC664C42569313D400C251B3B77E37F195245B836F98064ABDABF0 9152DB04DBDA14114FAD3B750716CE4D3C814AE66DBAE2938AFE41A971F82FEE 3CD3289B3EF70C0909BDD88B773E7C08DA5AFB74FF6439CA7A02577F99076C3C 123BEA6C4F455C701F5B910DF730F6EF0E149DAF9C0E0C0D1C77AC1ABEDCF4DB 3A9575030616A40D809D56796BB0C1992F91199AAC56B38FEA3462130707B7CF 942BA00CCA0747095C6792362F26086FBE51E5581D5890728A0633A1F15D1190 9FAE6B8AC894D3DE5A07D6EA8EADB33D3CDB60C504416E5AA3F13BE4BB765C90 A523BF48C20DCB99FD2B164831312A127AFC7086AC62A837C8A4FCFD089904C9 9A359039CD693DBE121218EDF214CA25F85326332426FF25A40F9DC9EF956E51 1F1B161E6D8C92A653E880558F4B51B86DC499909BEF41DF1849EDC455AA36F1 CDDCBFD3A1AC8A4E7EF34D6496552C5DFD46655B77C9884E8B8CA3B69B5257E8 D71764FFF9A3FD7C4E4A547AA14F3376BBD3C82B4149ED5B84940F6D22F78BCC C5AD8BA3FC2D73EA44FFE4F1D81F7350597A49C4FBFFE996AA0E070A5AAEF47D D9EF2A577C9B6EFB86A42F32A4A5E5B96A4FAEEEE399828FA04B7283F5DAB0ED 53388ACBBA1BB55C9C55AF54E35C53155299D225D574773D291E90A9A9C3D7FE D6B67CC2EE5C31890064918074694AA90418DC10C2B831FAC8B35A707936099E 38178476E4E2596BE3709C046CE0FC5675868937F6022D698727E70E45C54DEC 0D3BFCA2A3524A13318A096833C4E92B89A921FDB931673B3FFABDD2AC7714C1 734B38CEE8E97079BFDDD8DF6D8D92C966EC3CE1DE87A2C36409EB65541743D7 4B688D9B27FBADFA944B9CBFF16626F3D82AB6C4FF2E66780351245100CBC6DE 59949D2AEC383B656C67F8AEE89DD2E82A67EE397DC62EBF653210656C987C29 2B04098FE2A423DD2F5FF90356115A336AD9F3AD1D9B6212892B7E62EC587FE4 665302D3D648C6023BCB4A74CE174706F898832D56BFD6D13FAF8BC4DA24D653 5D3CECCA54FC046B1E4B816E28837E0D059552532404ABC0F0A01F38329A5422 08E8C3DFCCE08060F6E30E65A6BEA77E8D19260E8053E972297FF428050631B7 9D5685197AE082F8DCA2D865BE9F11C8D330F0AD6E391695E9622B5A2E7DD0BD 036DBE0444FCBCB4D2DC361FD06A7A70D59AB73CA6887318D5FEF234A2D14228 7D260EBC2CCD24622B35133264D47759D92D9231A7CF02D2664B3079EBAB3A25 FE2C3BDC2BCBC831D1E46FD07580FE07FB21FD4553D59D213D760F3909609C68 9D3D285B81C73F1DA547E2D1A5B673F8C21BA46E833E6CBA130B79B5DCF5549A D8100B5131B46BA6548668B861B7E3625D32CBD460D83E9516F39D8DE2EF4F11 7C977F68F24569C311F34E37B841DC240A2AB2605899A754483B1133A8CABFC6 C0178BC6F96FF3E36BB068B7E77362233760ABF2A93C23E1C87E7375F9096F77 C12B6A0B39DD68E089CFB8CCBAF4109DC855D30CB37230AE9012BE124B67A33E F76CF21FD30D0F8E44FA91E74989D6108E518EB6B8295C60F2DB628E7F056B4B 6C1BD3326982CB64ED5DB34C4281B7D8D2EBF3733EB0FD5B78AA2AE6E53A54C9 AFFEBD71524ADADC155DF0EA14671A0C59E0FE65453772D938DF380E1A4D407E F0B50D8256A034E48C58588B2C085534EB3177C3E59F16715CB699C46D13EBED A21B50388AE7945B3358699A6EC3274B83E7626F1665AC1B61E3045CF92950EB 6EAB1D87E6F9E403AE1746B814352B132A76A7C0AEE53C01747E0B84710B24DB 8DCCF0C2956C3D6901F47B1F0F1E50CC6E2DFD8E65906CA9E6FBCA9F1CC6C45B 53A3691F36B7DFEE4F0A2B9413348790752AA43D0E7324E68CD5FC4F2C8DB5C6 0FA8D0661680A3215CE21806BF0BA84017F190A2E91E74C705700F52E648C359 432FAFA2D83E4B006774D22BAC8B5786F0FC1A216491BF1846ACB9D95B2894FC 628095615F015D0152FBA08C7311564A0D44B83867E65DAFB249D12D0ABAFA81 48BF8FA3A102A429B94BBA2C35FF673E3F5CB0AB5E37EACC59619DD32B83709C F168CDEB7984D2AC4CCF96E7C709F9F17FB7A563B58D637BB716750A37B3A3E9 91B99F78E74E890947B776E92EBBD42058183CB1B6D3522B92198E9F6AE8181D 82C6829C4260068A5167FEDB1BDE5E3475D5DAEBA46FF404CCADA410185C1BB8 8B318541396E7E9B67293891B562C8296AE640EC99E3F73DDA540EFE387158A4 48FC502A8DBF2FEE80678360A14EB89263D34AC44E4DCB529340FF155E0939D4 6ADB6084CD05EF49060EE3638AD075DF4BE5227485FD42EC392C2C6C9E678D0E 998879CC935B3E2AA91EFF5B6680FBC42E7000768CCDF723FD46932D30FBB82C 402BD075B9E7456C97C1128678A6DCD831D4C68FB447A87A5701AA1C645591DF F1F8C95C80869288E070F19F92DB79AB8AD9D7A6AC1A896380F2AB9C34998278 4F2B4E5D0513ECC954CAD7661FAB430B3AA3DD72138941AA64AC94AEA332D3EF C8BBCE5A0D07A68E6E93B069AD5FC39161294C540AE59978F8B3A34569ABD981 15930EE4D1F062A9664645144A2152D8C3D44EB5FE5FEFC245BFBE83148F9104 9C0AD899ABABDE3E84470DB0D675EC5825BDE2DEC92262A787A546AA1DF64AC9 E652CF451462D643B36E6ACA1C256E58A15D1A9F067D587E67056E9399A81A78 500FB9F368E56BBD8D27BFFE019CD5610E82C7B07853012B7FDC5B1F81F31392 5149F4AF4DE64B89563ADC92C4737A649AD38EF83F2E10FEA91DA094C422E084 3D8A95A7A25178184C4F63546D3E99827EE0574698DF8ECA6DB71CFFD93AC5AF AE015252171C713B12F1B73F0110F343BABB803C3ACFFC49D96A531F2EDED166 7E6B63B647FEF7F672F81903EFB5ABC082911EA9AC13DA3D0853140621C7870A 9A4CBD520FA1A19E9AD24C6249A7B3EBCA55B60969B04FF4F3897B881A8B92F7 DD6A2781573D4FA0E4857F800A995556C3082C5DA8353BDDC87601477E53A432 30AF19140CC6640558E6BA4AF4954152EAC58816A867807070E122663B82E254 4A6F4C517F304E71D24CAFF5685601ED7A31E4E61D31DFFADBE50DB6500F33A7 89B1D75C32101FC95B9F0A234772509C665EDB5E48DE0035B7D484D31FDF070C 31A7C9F18F34D2D33BE8EAB97CE43B28BC72192363339BCB24A25D3825870462 0C6AA7247B24058349AB4A20D683C85CB002C272020F151FC5DCA8ECE2B73748 27AEBB1FEC43315C90610A487D611E743DD6E017D500FD6B1E5147E5334294B2 F57C7BE7EF6A266B6A4C6CA87F86BEF99CFBED73EBD70DE1C80C7A3E51E0DCB4 9A112560FDC438C66EE811CB4CE3E19679F69F04CA3910C61ED9453F9EAC1B77 29676E7C68C48BBCECA8B93963148E71B6BEBA58EAAA57E454F52695AFE900B4 0192F957626B87B9E95472A96BF5E589CD02A71388226A675D4C746647D40F7F ED535848 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: NimbusRomNo9L-Medi %!PS-AdobeFont-1.0: NimbusRomNo9L-Medi 1.05 %%CreationDate: Wed Dec 22 1999 % Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development % (URW)++,Copyright 1999 by (URW)++ Design & Development % See the file COPYING (GNU General Public License) for license conditions. % As a special exception, permission is granted to include this font % program in a Postscript or PDF file that consists of a document that % contains text to be displayed or printed using this font, regardless % of the conditions or license applying to the document itself. 12 dict begin /FontInfo 10 dict dup begin /version (1.05) readonly def /Notice ((URW)++,Copyright 1999 by (URW)++ Design & Development. See the file COPYING (GNU General Public License) for license conditions. As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of the conditions or license applying to the document itself.) readonly def /Copyright (Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development) readonly def /FullName (Nimbus Roman No9 L Medium) readonly def /FamilyName (Nimbus Roman No9 L) readonly def /Weight (Bold) readonly def /ItalicAngle 0.0 def /isFixedPitch false def /UnderlinePosition -100 def /UnderlineThickness 50 def end readonly def /FontName /NimbusRomNo9L-Medi def /PaintType 0 def /WMode 0 def /FontBBox {-168 -341 1000 960} readonly def /FontType 1 def /FontMatrix [0.001 0.0 0.0 0.001 0.0 0.0] readonly def /Encoding StandardEncoding def currentdict end currentfile eexec D9D66F633B846A989B9974B0179FC6CC445BC2C03103C68570A7B354A4A280AE 6FBF7F9888E039AB60FCAF852EB4CE3AFEB979D5EA70FDE44A2AE5C8C0166C27 BF9665EEA11C7D2329C1A211DD26BB372BE5822F5EA70D99EB578C7BEFD44CDF 045A363056E5E1CC51525EA6FC061DCEBB337208EFF729802376A2801424F670 0E7E6397B28F15BC10B40012B0A3EAEB2693E8F7F627C4C9C7C6C5BFF105C1E4 1B2B9E8F09253B76040D268B80719E1B3F5A55AB7B8E178732AD0E135F772215 EA7EB7EA7641D31502E1BB9661E7B0E875AEE90400138F2AAF4A8686C73EAA44 E5CAB467770A3D12E9807BAC97B24A8EFB0E276760F4F51EC7123C43BC6F8DCF 9A2F496A9172813FB461FD870763306B45670653A9780FF409B734CFA74C12CD 150B03344295918C4ED893FB620A9499404B83C71152BF2F2DBF769000D116D5 EE264C016EE3E1241018F59544CCE53E5AEC124CF6C59A4D7D7D511ECC9AFD49 6608ADDD237358D7CF8B4D1C5BD1158CDF2D6469D9BD6E6D9762ECF34D1C3C27 5F69900E0D12AF9B21F153585742E999870BEE3DFF6309CD82968EBB40D9C269 CD4306654AAB6734151132DE4194072485FD082FBB6DFCB3FDFF9E1FC88D9483 8AA64B5825293978C70C9EC095B18352BFDC34B4BE9C939384E3281BCC6B1808 A6B61EC4E47BB6AC14B105FFA7ED6AE99A1CA0B360D1A5C24E0FBB55C66F5811 A5CD0625654654651979A8C4C3612054181CD300CD42D1D9CAAA589118D6C7CD 5EA8A9A0C639D5539430D40318F4B739DA281ABF2BE2765D44F45B218BB192E1 9EFBDDF7777E8730FA7DC0651BCD5D68EB743C51D9CED55403021D45F77CAB5E 7E892B3D1F875DA86C030A2387487DBAC8795749E849EC93439C9E22EB20D11D 07DA0F09EE9356D55B8D0D8555F1B0EC98C72863B376D3436E10DE2FB1AB9453 DADA019DCB64F6D059AB3A95B28B94435004C9A8BD3FB80E2B9DE0E330D03622 3AD965B4283E6DC880A2130185CDABC053C52693CE3F50557F524D7CCA9BE05B FF9597ADF5D1C432C00C0B0D8EC2CA8436685B4BF3E2105B89FA6CC787B77637 248796C2F43872B3BFC8011159C22EDB7149AD8932360A88A223CC638BED257E 04908032ADA750F17279F7331189C322CB5ED9B66E502945BEB1EC68B1C7BCC0 2322EFD669C229B28CE1D0CBC0005FF967D0A4383E29538AFA13D41D484D739E 487D497DEAD8F661847A5D82D77D91219ACF666E565292384728E58E1A489054 8C3E34B413A6A550C499218E7FCF43694CBEAD016119CE85515F5EDAE3CD483B A0F32743E7A189708AF0CB6FBAB22AC8F23604FFECE038C838472CA40ADEBF08 47AB1D450E07F9D51828D25DDCA679E3FAE54634A37AE1A5A778365C5A2C8A27 64085AC775AC132CCF27CA164C4721F67B63D52E388B17122F15E5DF391674CC B6C9EDE307D79E390068970FE0AB210337558544E8CA59BD8BAFDAE0AA6B50EF 8231DD2AF57730FA7EABD3D44DE5C2197CA778FFC85BDDAD152563B5FDC3F629 8C4728C9DE9761D7779EEDD1B150262BDF03C3F60D09B87E6267D7E5E43705D3 D364B37D06E4C153BC0F8F8B032E5F26D2DE7CCC0E927EF7D853D4E937863F0F CCE5F79063649DFE6A9C36877D0B777E6FD7DB119677C74E3D0B1335C6106BB2 2253EE29D6495AFABC530EAA092BB709FCF1D2F4A32810A3DBCED812EE19D10B 0E690DB204C2CA3B5A07FB9A6A1768CEADEE7B507844B55E4CEA9D3179759BD2 0CF8F5B58D1394CE6906BD2ADF6260EB9A2A59A536E483B745488A5A82E16393 CBC17F406328F383F2BBE3B3B2A6AA6A1FEB26D4A1B4461A009DF7C2666CBFBD B5B9834EC15C047FDCB4E0CC99AC20DC2E5181FA219E49C2F4D2C8EC80D9E187 F9E15825F5721D388B5A56C9FF8C4D4EC2F469549C5E2F6230337A4F7893FDDE E3C61F3EBFDD15A822138A17ED1C6B430CFE77568235A193F57FD51F202DE629 4C204F576397053840C0109C325E5820D3C9EF826C2CABED7C5D4C7454D57F36 70A11457E550B1E5EB5E4E06836768591BD979D642FD47D7677CAD5B82B4548B CFE806EBDD7A96133B2E41002B812F8E1AE5C8B8A9DDBFF5124566BC16EC1798 9C1052F8E184590223348E583C314D27C43C08B7B723B9BC4EB7C9538A2F8957 45068B89BFFBB595EE95F8BE4F058CCF35A29367992E5E5777F048D317210A67 91D432094998B144BC6FC564BA50B10D8896713764599CD8634344DD66EF6667 3C1CAA75ED1BC7113F02639546C046271577CDBF8AA7BB7B42666551A0531739 7690661D7B3C6CD036635AC005964C989FAAD34A1C94F15DA238A58F1FB3061D B6B3DDAF549AEC049112F2D95DC0D89B3135BDF2BD8ED2281DE318DCB1B5A6C7 99895F16D274E277A7FB8BFA6DF104F63B78774431E6906CD36EAED81B0BDE7E 973C70180E1D12848546C36223A3B17A6E2AD43C7E98803D291EA326071309DE 0BB4DCAE71AF8F73F774021371EDC57DCD18653DE577BF1807023E0429655F8F 25C89E65074A52CC6047885F4105DE2B2A410A7CC021A3B60D1D8504A693DE5A 28210BA74885A1164A287A8C8C869CE3BAB8C4891D68A761DA5C6E8298B2DAA8 B794E35F00BC8B61D90C52DA56A247746D5D8AD88303969340CC4B05D9F5DF57 D97EF456B2A440F4EE508D19B02F0212351ADEA2BCE9E77850E34897555E4185 6D173CED91E77A8626A29B22DE355351F930853B1D8F89835127E6D5BE96DA47 CE4982B8D87F1908F94927BFD060CC594E01D7232A2F3A575BCB1430713B9889 16487ACE0AAF272EAB35BE27FC3A7CDD94B41EB70093103CEF6011DA0DABE16F 250B2EE77D2B50E9CD42D35B30B867919B7C253141067FE48817E2A2F71D467F F06037D7DB93BA0D91FD67DDE92C54006A33ECD04ABE20ABE7639D25C0B96760 DC8950341BCA426F292EDAD2D22662336ECA47D288AA19F0405179908AF6C3D4 D9D30A0F27C1ABD9945DDEBB232DE5501CD8905DF1725546E9650C979F444F72 437241027EC41707744080250DA0360C9C49FE426FB1C196F1781BA4CD3A2F9D 47D33B693F074E58FFB1B0CBBDD1263A9AEDB29E4CEAA6EC288842FA5714AFF9 E57597F090706017AAF0106FE155F74CD2351AF96D587E604917283ACFA0B0B5 1B26D9F092709834A07411CE17996F9E4CAC058C12E7F9A218C298FEF2118458 EABEEA47AD875170EACF4225F0E287BDE472CCDAE5AE3841D406AB2BE566E420 A2B0A885D3236982543BA9F60E401BDD06BC0ACBF3400DB1C8C3FDC65A218FE0 65BD5E6A9E36799C7822398C82C22A635BAB5D9FB381741D79F3D0618B20A0D5 1077ACDE9DA732031E629832A68E052072B433E5041DF32C69E0D4F050660F51 63EB00951944E8205963AD84F305C99A04E9DE6CF33CCC4A1745011BD76FF848 996427FA0B2750D5A624CA5BC7B5B6508DC34AC3670368299F1E89B8BFAD90EC 607C7859E3395E8F192A0E11966D1363ABDE38928EE81AEFECB5313AB7F47BFE 8C552BBFF0F845A224F972A0F5526D26A44ED894B04F1907F907CC0043CCE52D ABD8855AD4B5611E3DCF6958D89A315B388F0358CB49A7FFC17CB4197CFCFF43 1068DFDCDE8EC87817C77942175BD081E238259068836250F3CE87E014A84377 451080076C4788FC2B6D4481AA22D6E859602372F85C77D38104DBDB654603AF 56254A8A71F70C8A1656500599D71BF8873C220337864B1C6A19C516607B10D8 3B17A6597B37D25EE0B8035A24B73AB4746AF69416066CE14CC917974373B87D 1B39CD6FFD418D40ED23EFB96CF9379BE05C9885E63E222AD6956DF7C9EF9D1F 2ACE6E53FF0236DAC9F6A3D650579C2FC6D6C73ED842B33A939688F93CE376FD D5BBC9D27F6D857C35FD568C4B2107EF0086D064B69A9D0C7BE6E9DDBB45E069 C587FA522B77B09CDA782DA7DA169A703543F9E8685749426E9EF4F2414ACE57 162F9F96CED4305F6E30A982C30AAE0B18E9F53E59EC7A1AF42EE98794AE7F05 658A0A3D5600886E42F253A60B2B187AAB2F7EA3B2AB1294CC34A4E8E3BAA555 489D49345056202A1F78EB70F9C7441B786CFE74A43FB501C634B479D89DC565 746F1262A206B1C37F599DEC0F3D8D82933ABDEF0A1518AE95E898C535716051 763C76597C9D0FDCCFBEEFA51C640A83C52232915AA1ECAF2C2E7F7D71C085BD 81CE2E60B647BC2A722E90AC2D137D2DBD690A40F5B635C01F3923270EC598B0 A5F1E2ABA407B78FBF12026F59BFAD2B1F3C62AA37CB864D8CF320956F7FA932 DB9C40D0B562F79BC7C4EE44284CBC78515FF07EE0E5C96EC30F9E531A6803BB 592982AA0303DB98DBC7FEA6FC0C4C86F21D98814DA3AC4400AEF9585BF828FA 3BA2E3A3157F27A86C80AFA565A64E200CAFFB4E0DB4C05C4A18F2DFC14A25AA FF389346BE44271A793A02F917F82E22063763A8A6DB2BA76973D42EF0A42583 5C51B2A0FEF70398F8480D9ABD6C81A2AD70B36288B0D7A90FCFE5F24B5C807C 156A9D060D4353F271E3FE9A22D7934595BD999C3A31DA2377FC5BF667F6DBC8 748EB0D26D527A7665DBD5CFD0399338CB02E09EEBEEDEFB26726886A756D08D 3085727F11F0E035CEC4B7722259218D7B8DB86082EFED2146237C1D110D4A10 E155492E04693A74358A0B46162B3E5562C43A67675CFB5E5AFC539A1FEE3052 242BE421BCE108A931CEC5D26B9AC125431411E96E977D72984380C75B7F9B9B 9BA248850809639C7F505F6F773BE2A5E3D088B3B48D0A59B15E0445A1379C10 FE3E63C79B0CC03B6645A93774AA24852DE71501DEDC26DBFE8BC6D819708103 BB963F6F0BDA611B948CBECC014001A032465003A5310E04016C3AE50698C63E 37A975E6B7DA0D48A6C441560EBF2842E7C6E6AB5697D00FB44C63EAACAD82CB 34C3725DA52A528B5F2D4659479685AA9AE8DF53A2A21D951A60E73E67169DC7 A82B393C1329F91FF6E05E273B5DB89549315DD15922ED83336504E06A82A194 C7BD042EE90B6808E24755419BC99C0B233ADAE39DC533F1D10843067264DD5F CD2FC18D64411A41FB44D01EC29A9D62DAC64B58DD5BF7AB37C3350C83B7284D C6FB28441ED978AD4C9E1AEC05523B382B800D1F4E8BBCF939486DD6F5AAD8CE F6A8D68261CADF4A73B5826903A8F7ED93B5EA54B51CBB5EF191ED9B208BB0C9 C1E7DDB04462598DF2022D2AF7541156EE0BD6BD5423B54E622C1B44E4EFE86A 53305FA9BA725F66CA83F985492FD5FCDEC5684F0DC7DCC00D9A576888A73DCA 909724223CDB4A548A565C370879F4711556B8DE0579DC3B40060ACAD4E985DB EDAF57471CD3AEDC80622BD3A3DB6B79F0B9F1F4343A2E757160C12DE8AEC3E8 CB701ADA03B631F1A8FDD93CA3428135E3A06484507992F7B287E0A7ADB0E9F8 9D6B04A1E44900A010808AE069322D42C893A30E079DD72B814A8C332C88E383 24BBD2D4042E32532843F1A672DA6A04C28C460DA2A483E9826D881332614491 F2111DB1AAB1889FB06BEAA1E0A05C5B34B731FABBA92158C3CD36EE89D88A6A E6A070411208FBCA7F60CDD700F88C4C679CE7730367475C40ED58FFDEA843C1 0F8DECD8B6327AE6B4CFD16C32B42CF90839DADDDF82939669A03C2A9AFA9544 CC0C8E8B145BC7742866D180AE2A7514B8F663BDF359978196223BB6B7B41504 242E9A5E28527E36E301C4F2F5A518F7E33DE1E3C2855DC776AE87C783986BE3 01803D8541DA350D363438EDB94D25B85B2FFA06BEE4B4866CCD6F9A016CCCF8 AE794B156F8A765F5298B12F09026095FBD4C4C6CBD815B95655FC8D6A14F7BE 3E2111BF0E3A8EC81D16316F21015487644B55DDA2E1146AA3C18489691C1EA9 42403339023DBC4A50793CC443112791218F726809BA1644C7BFCB667D8A6123 F3B3A1C79B8C355B9C64259AB1F7B4D8ECB6B595AD378B8998105597B855AA0B C6B258247C17FDF85AE053A92B95B480D155DDD3547A2737D83A151820434301 FA530E9C399C82316EDB48CB3E86371450BF16918CFCF3B01FD4508C0EBB7924 91DE1C9754C170C357A23A9EA2D9D5BF637F7CFB0EBF601D0946F840023C0958 4AA0F2F3C2F479FA651F01F72A57705673E627FDF8CA3B4957E3D3D80C06EFA0 CBEFF1940AC8A50B4DAE0FEA37F88FE9764AABDA0AEC760A3704F53CA8D9C923 50948641625F5C1C0C6A40509AD9DAA228DF7DB9236510842D561974DE717BB7 3FB3CF46D297EE6D21CD197B4C7B75943F5A5C91D8DBB2DD778FDFBB8FDC1F8C 7E233AC5CB463E99FDEB083FA9FAE548FCF16B70C65965B2798561CB82FB0E5C AA2DB337252C2D1A5F4DB4D498ECF614C844C1F9F8B97E9BFA3470F06DE0D6CF C93D2ECBE6C6E8E00F0D30AC5AF67EC4C0A058F4BB2990F2EB0936A8DCBBBEC9 1194E2A4F97458AA54360FDA3DC799FD07482666F47C17D8A5BAD6EFA470C839 176E9F7B3ACC64DBAEF3FDCD3A80C0AB907DC58C2A7BEFF8A0D27FEF34B674CE FCF7DB48FAC76E8CB1EF67CD2C1D8D6A456095283BBAB18DEB2BA9A1B4B8D885 2A396FA57D2FB62B32D08B5C91FCB4422AB033F8A0F0C363AE15CDA3EB231175 201712BAD66DE09E108B21875BDC55A84C15AC6307A7C697C8D32E47D36FCE42 6400E2AAAB70DA144EC3D0CF46A5491CBE714A6A27B99016052939BB55D84E02 F4D625AAE6D74B6A4FBFAF7245D8F075ED7497FA4DC7720DB762890DCEB7B93C CD6D4F2407F325690E7737C1D13AD2FD184E97804AF7B4B7C863D22426F200FB 8824E28D830A6704A0B11385D63C944E0D6340ACCB5A6171DC767335712B4541 2C4E491DC98B1D5BC0A9F9A1E07F1AC6EF42850700BE1F35F017C34DE7A9D57B C71F2CCD831AFCD61C03E32FF6A0AD62A658BCC2E72B7679DCDCE61EBDF289D4 D53166A76A83AC6A6EC6A0F5A9E5DEF03CDB67F67FE96048CD2218FB71DEE78B FE668564D4B86D07F61AE220FCB9A54BD9D94D77F38BDBA73A9BCF43682E90A4 A5DD22B90C000ED5DF8134162397415F2ABE85195555A73D1C2CDDC7898DE5BA 43091340BAC6F45915A4B333324F63A5120767D12DBAFD22D5B99CA63DEF267E A777FE9279830F6ADF8FDF27B88DD1479FD908AFB02B79B7719E604E0D6DC9F0 8835CE4B952FBF0C1C2662A287F61BAC49753FEC04B631C91E595ACE54AEC23D F417E0CD36CF0C52B8D1E84DDBBF79C4E208453AE3D84B26A38EBDC5E218BB69 EFAE6CA52D19759206E2998385FB46B920A4AE05A210CD5199777BD864F9A1E0 90F88E5ABA7778727A4204BD90A2D4C2D55644E2B3F5A49DA6FBD72B7C0D2864 8D3EE495794E22F8FB669C5D3FE82CAFAE41116BDFF19CA58E98F8DFD32DEABA 293EEC31F20B555625DD74ACAA44FEFF11F36BDE0E2B1BDA5E2511E44A1BB675 8AB06E34EF8E87528FE146C23041CA1880C7724296419D91D7204489394054D1 FC534C1F04B3AAC0D2322E7BA4F23F9497ED65425F77FFB8E38949B6FA33951F C4064D8B66422B242A2C1545FDA84738BE165A90C6C7F8978C72D9964C243B76 D97C26715F541A5B4C5ECB2B7FCFA42BCA680EEFAB287A654D597FE93D3F8464 717EBDEDD0F01B02982895820AB4FDF2F59832277AB06F45A115870D3DF53143 92158E21E5FF549DAA0AA09518F846A805E5115DF29AAF461FD58AEE42F6B435 1CA714FFFBC953E0080C2F6E3D426AB81B7BC5B5EAB9F109C36C91D24CA4C9D4 A71CA2D3A50280020927DF3E4258EEF8A9F8662A890E3BBB28D63E8987727859 C5106C2DCD52257601FE3CB74990BC43C85A55DE8C58A8A8B20A22D3B9A6F202 F80131DB3C938561B1731127A155B0BDD80536D47328DAB956ECAACA32F1A6C2 C56B12F53EFA612882BF41514C61396B5BB42FD60FD32FA1999CB88ED0033131 FDCD51892263E2F150971EE1CD195D82AB304A5266C4B3C31E010655DED219AE 758BAA04846F7D998F5F82D8C4C2C5CCA8539E9CC6C4950AE927F19E353E1CF1 C06347687794810B187FA8A839F7B9501BEF95A6714231F3718C6BCB69D1D954 12A61ECB712DA3C2C89F64B7426E0DDEC4F73789601E45AA1ADE6DF7060981C0 BA3D2AF8649CE52A56B0618B2C381398196D162BEBE54D643F7C2A0AE8C6A113 AB4D160B857AFF1F394078788557F70B800367915D4EEBE9B174A0D70BE8703F 7B55B6097E73A510477CBAF110B996B1A2972E78DFB1CB230AB884AB4DABB9CD A007323DA6BA8A4029F639F82B8E702EA2D0B699626821C00879ECF9D2996B79 48BB669EB5C261AED993436E0B3537775E618508EE88F1C0ED98F682BA1B10FD 88E772B73F5DA33F3CEE75F1CE4473166C72F115B5FDC4367FF7AFD4CAAFC041 8E2745359AE31AE52230F3CE532B92469D4BC8FF30DF9EAC8C6C2692767B1909 15D24071DE06C9372A211EF8D1289515CC4A5D0F956A7EAE45C3E8BAD43380D8 AFA7CBF7C6D69FB08F417B2BDC7275014006783D0BA0D36A90DED2C39E5B26CE 60EB6F6F93DF32DA5C5543FADBC0E674C69A64B20C90D45992F97FB1F8F073E1 B00730C1D7BA03F63A70B2857442946008A2AFCEF83EAE696FD1F5E6870C14F3 56FEF1BE1FA788335EF0647D47D0E9415E01B9D7B6B60A83CFDAC57BCE423DAD CDB7C3931096D7A36F1B014E62DCC8BBCCB2D9FC908CA3F44FA3A4689087C333 97E63243D3B6187D4A3CA906A3233BE96301815C5B5497FD0900DECA87E24DE3 14B9A42AAB079C478E09CCF5961E95C2924BB46EEE858F69148135A883BF18DF 0810D36F85C02ECB1F39167F654D0D0868C34828C7CA0F7922FF9CD0D525D970 F0F7F33F7CDE5E2B79D47C68D1A556E8237AE5EC959AC8E633CCE10221D294DA 44154E3E95EDBDB8E0AF74A8E2713DFDD10D15F301B732CE51B49AEBB0B61DAD B95DDCE3E09D38317A31B5CF413C5A9B1D6CF19900DC9FC79A67A1B4E9C6F899 B491DC1188CDAA7FE14A41E5A2F473A7FB096DA21E639CE5019E84E46DC8DA34 37C98684A92CDE9E1E91B6BB516CDC343270A1DA30B48D940268DE8B8F4DB2D5 631A2BAC4FCA0D41C87D5D02A4B559D4AE0A8114F4D805FF479AE8DAFBB6C794 24127BE966CE3F157F30EFF131719DDB98870F6E8849DD393D585599D5EE071C A9BA0426862681ACD6B44FFE04B74FE5E1AC5F0C46FC5E30D6210B3BA3C8B222 8B4610EF33F894F4D6E2D83CD8447B926452AFF608EE55FE5E327737A97C2ECA D3A7A81AD20E8FCD66328F497DDFE297ACBE318A732D964EFA444DE41B5C8582 5B0B7414CDF690D35E7ECA4DC756B61D69BD45526B01DF438E79CE752F2D3CF7 66AFA9569ACB8683D452CF438D20231085ACA668EE0A0B04799E6861FF0D67B7 23FB11A76564AF0344BB9A35801512BA57C31BEC077085DACDBCB470A3042A36 55DE10DB1455F0BD5FFC7BF4304713942BCE511A8D1D753C4231765CE08C1F7C 77D61A9DE10664F4BF13E2B80648A0022DB642D018A730FF2D47C51657BC9913 58D5D184D01B11F9E2C94E6710CD2ACCD6D779BF27F1D1A6D28C2DFD7F104869 F845C57D200A8918137BFAC92A9C3D1624344E4155A94947FA84AC2AC3C4F8DB FFA285621DEB9CEF64AC87148AF12309FAE95853BE0E43C464B1D6B386FD229D E9FA3076EA6D40B209998B52D274B34EE05C99AF9775CC94CB97ADA69BF180F0 AA9A0256D6146DE64AC88838733DDC1DC179C6D007A7E3CB7207E56E71C3E3BC 827BD2A3DD5EBD003CCD1AD26D23BEFCB709973B3F945CE6DC91D4F8B7800A05 DECB300CD7A8C38D774C107B8D7F27643D015A4423506A9A2A9E1CFFF120534D 9FC1C3C3F9B01526D9D71A74984522CAFBAF6CD275B5E015B16A1777CCA3D56A 827CA6E2FB8EBBA30BA2F91F8A1BC4E76ED59F3EA547541714D6C5511CC846D0 05897329B3D0CAA5E0F1B44EC9D73D7DFF931F6A90B7405689BA3239EA4B42BD 9BDF1CFE6774250E026264EA6B19CFF9188543AF0DC2B02F2934B97EBB13A8BE A26BEBEF0AE41ECEDB5E0C03AE37BD7ECB937DF74507591F8506ED657D079DB0 0F337979DA04BBD485BD56300DA794EACC67DEE6F4059B764CABE282BCF201A0 0C06829558B48F1AC334743CAD6846D687D10793469295248AB86E022B069E2D 335864AF9CB99114E73DDD3B411E6F286FE25A8AA3F115026A285C6EEBDD696E E046192FE84EF86DDBDBBB387CAE57AB427F2B196F5BA65829D9109E395A486D 4AD48D6DB15E5E095DCFF46884A1AD7C81AD55FEE036634EFB88A1876A253EFB 7750933EB3D2690B9A9B887E2E8D782D8F07D84D88904AD23D3FFBF1AFBF1164 062F545BE743C40189CD090D42036444FD4729538BA939C3A82BFDB44E5262B0 3210F3BF96D6BF08F38611A67040608203A5C3D09817BEE8EE8CCB1DA1A85215 2D4BB72DCA67ADF52E28508BF856A56DAC25572C3165258B512B98701285BCA4 CDF9A5DC0B4586C3992FC53F1ED102E969CCE27E8DF46A8D61E25B73FD1A9E54 BADE8F858094DF755F2C36A5A7386E569A88B18A0488879A1FD4F01B8FB3F8FA 0090C3F065C1B4FFC8004CF5A4D2116DB1E64C8257C7F2467F91334762A700EE 46CCFF0F8222069A239E9C090F9EBCD1D1B0D502750247BB25006F466250647F 37A368E2628C0FDDAC48A9CD70475B33AEB5CB4BDFAE35CD5CB7C71FF9ED9A99 0B727C6C702071B81039AA6136BC2F0A34C19D43BBB5D88A9CBE69D2B6F6009E 16958A21EC955C2532B1A884523A0634F67D863035B9AAD1DD401C0106DED8EE 779CE5E4EA3E4B39AEDB07533CAA490CC2C6A16372EE5C173CBE0974F6F726B8 CE1FAD7E682E12E3AC1F8D85468BD6C30C897F2106FFB9330BA42EE47CFAA89C E01362B900C8E4F951BB2A1044B616C6A55E220A30DEC1ECBF3C046110D88BE4 6F46232CEED670D8328CA207AAF68E4DB2C2EB171CCD22DCB473B862D85990A9 3C7CA21B1FECCF5E58702F948CA67F79A9DD91E97228E7E635744692A959C7B4 919DEC77FA5012A3CB883F9D62C55E71761462FE9F1C24F12DA53F9865CCE54B DACFA0C44A978A37EC78DBD79E13596918CBA39D1A792D7286D91C9FA2FE4F84 BD87FBB390B65362AD2B23E4F794055D1F1BDC06C89A7EF1AB04C8E0875032E1 59EA0429ECCE5E9CC4B52E97089790D08FFEEA7D143DCC7C06FF6EBF727A6A21 2D64423CD27DCC76148BCD2C4821508AEE3A4373691772A120BEE77098BB898B AD2174937D091D85400F9AC9F012CCB5C8C16086B89FE4BB8470C933F4284FCC 328B413F11A3960D1B0BC20593F3D5F2B587A5907123AC302DE4C6A3C312BCE1 CB7C2B07416DEA1A884F4989C120FABD61EE17CCC5F11D52AE8F60B449E8FEE0 AD1803E4DCADDBA121E96EC75C62DFE05AC99BC40880EFCEB8D91A7661AD8134 E3C94FE80AA5AC83F8885E335A3E0F3980CE20FB2C68043EBD3CCF91D7BB6208 D8A985E03B45448F557D54FD32ADE7CDC58067B818C06C54ECF3801E5C254525 5C91458D3251ACCC0EA7228A8074BA8776C012FADBA91D178265379ED8DE9A5A D574419B284556AA437BAD036E99E8A5B597AF0E9465FDC9814952EE4CF17B7C 8CA86C9C89D9B9246E2EACE37E2507EDD79BF25B98DFD30B2C3EB70AFAD43709 981A5A5319392DFEB682C3C75A985394A4D8E3E31F9952F450564F73E6B4B193 490770DF83AF846B7DE86BC6E21AEED1C09E800B20ECEE20918391589B431E90 D4225C2CCE9F4ED3BBF39559A253FD63374682480A438A388C5A3EC14A6D44E7 F7DA63836A920948FD8A4C42D4443FFDCED9F8CB90724909C1F4A2CFE4ED67A0 98AD0ABB7A00994F543BFDBC1A27A9E873CCAEB4CC03C9135C7D83829CA8EA52 25E6EA1FBF971CCAE44F5BDA0F8FF06687EDD38AA5E014CC1D51AF6D8D7461E1 CFE159231A026D81713FF19653624D6B4572C01EA64997C416F5A617B5BD8C18 0322714B666A844D6918AD5788A91CD970220D643CE99BA0C073835F770E18E8 1F705B2C5B496CDE8E9B8DF89CC38ED5CA43794C56EF307041A53F7742BBE22F 59720C46FCB25D450AAA8006C4476FE8E4C266CF20B954EA6D769D9CBA2EC1F7 AFF7BDE9D35D4DCDE7A4FE10DDA818D1EEE5D070932A96CA3D804F83FDB6BD43 988223A74B39389FE0A8105BB02AF55CCF1F491094D5451662B0E22E6C9C9E07 588860236F061B804FDB13927BD75AB794811E76266B15CC8303BEB8B7056AFD 6E0A67983E418E05256AD7A9B795CFD4C3798DC10D952F8CE8FB59C254038816 CCDAE998F2F744DC41A8425BEF676A447D1930EDFE4E06450F83A00FB202BACA 6BA2829881550035600D98850705677C6820C1A8CAB4BDA72CA0B861CC074DF0 8A47E160922F78329C2D28B66A037CC884BD98EE991B95766A5359F69BD8BF8D 23D9CF65541633733D066850F7CDC8B3655C09711E92B1883D0CB9B0A0DF61A8 99BA18D4D78BC4460020412C096317372C6BD1D4330F9AE23905DA8960309A86 FFE4CAB3C8B91C8FEC781384377B85308D7D01554E5466E030C54AA92F83E4E3 34E769E773D29669332004A2E5EEDBEF13E0A4DA18D9424E87ED10D0C76AE036 D0DE8FA81DF0F1E81A512A40FC403186A8DA01BE89D535495EA920958A52832F 218CA0DCBB13C611BD1DD52B0242E6452FD35A35F142308ED771E743768EDA2D A56551E17AFBD53ECAD351F0474E4C6D3256DE7A2C9A124900DD2AF1FACA5151 50FD5ACF9F285637B14EA1BD47AE661845BA2F0C74802DBC0AFC493EC4CA95A6 656CF76FF15B0073F755475AEED715CAFC1AE1DA7E1D5791533F63F82D15562B 432A614B656AFAC9EAD0982DC7C49B5CE25C0E95478AA915DF288ABECDAA2AE5 4D89B7B6B1D13971A840E945A5676CBCB2DE40925A5C33210A00EC251756589B 1885785D3CAF6799B38A7AD45148C4C50BBB2AAB4C19769E10ED4BA30809EA81 F96681C8BB7FD75146720FE628042288BF3E611B1E0F730CAA3C97DD6640CAA6 F371A8C25B3B1BF1AEA50CAA28D91BC4266D006C28AB05F68D80C54177E7D853 A7BB5A501DDCCE0DB784990604BEA10100D323CA2DF6F013108405DF82E07C2F 9AEEDB5A295575B5549830949293366428D6155CD3409002CAE1C904CE5C0274 BAF8F24C7BF238B0A7DA356C12308E14F6AA6BEAAAB92C14A402B751742A53C9 36659A50231CC072AAF9BE278969B4ADF8A7AD2F411F83191F24C984AF291AD1 B09A3E3424B9A1AD8FCD28F8DA066311590CA37F5A43EDEC5DD3B93C92B183DF 7D8E0A87651924F3D710CF1BC9F899FA98E9FC6346779A8D2BD767EED096490E A45AA9BBE33FDBABFB6CC290A76A55B20FBDC8F02455EBF38CE5EEBE95E3A6EE B1D34626F0AED1CFDF995F020A0BC9F89533B0D0158DE9E75B69820DFF8B8281 574D8F7335D1FB96555F5D7A0EFD906B6FCFE80AD08DC303CE011B06670B6DC6 9BEC4AFA6EB9BB1B112A60ECC73EA9759995EE7F5224743F8DF8F4A7F5B37BB0 1B0453F439E13E391855ED510FAA369BA14AC0DF1CD03E89848A2A003BD3BADC F629767E340A58AA46625A17DB9C28AF8176AEB412DC0C25E885B787F6EB6DD5 9FABE65896361E4DD611E2E146905B0190613C7E40C5022089A956077840DA58 4585AEC3E7B973937DE4A81A159C8ECA2822DC5EC44CC58C519739BE3029B530 3BD7171C002D570E8FE2C6EE4E44F93BA5D58A5C2681959D5C58166F434649AD D8F0BC3388D694961C46D8271ECB41564883C2EDA4042316BFC5554904D06329 13DCA9D6D68F025BBEDC33FCCD87C44EDF3221DFE27C9442CF606C3215610A25 BECB25DA3CEB51643BA4EAB4D57D768391F3E333287BAF5D7592639F02002B9B F3C58CD0EF1F2C43A16031B8D11FEDD10E2F4FF80B4AE6CBC336D4FC7BFEB926 0F5014AD7323B3C59EB4E7A37299C66DA33C8B4835D6F76621BF47C6466618AE 27DBA3A8A55F68786704C8156366F017264C4791FD745BB8B65371844D614AD1 D5C1CCF9B4DCA43130E783538CEACECD98B3DA658CBBF3E665AD2D8EA9DC1A63 919575FB2C09F5C7D5D63303F130BF6A765234ACBA27CAA99893A328C9D60966 FE122332D9273722501A4306F597DABB574C9E6A632996C6CFB64F06A0F4C23C B2FAB0C3D5D24805787401653FCBEB90D46967E5B2048A5E021AB0D2374A9C59 3D0B09CCE0CC16EEB11DECA7C2977F3B4288774B1F4E42D9F7A2C4DC7A3644C7 DE5F26AB8FC019FA8DDEF2E3EE90E4FACD5CA85E06DBB43941AC07841E37E8CF 76159FC0311D5249F43F8E66072DAA3A6491D7EBFFF2FDCC6F424A1CE47BE155 3A2C71F469930F29F21737C9A30D008C10B77F99943899B368DD7EACC1B6CA14 188E552A8B15A074B445F27B2099D7D76DDCB3474ED36DEBD38C0464C9F88B07 B47E9AC04CF30777BFB0FDB0C850C06C9CC83556D34C9BA73AB0E9924639EF18 BCC0EE527657D6901B3768B7E40B41A30EA709010AF3769D1F1929B8435BA294 CEE14B82D34B4AEE58B329BD0B6468C15680894E8045C2DE8198425247944029 9688C2FDD57CF3793E36D5273403E0F9621B41A27CB8FE4B8F1E5956901C3954 CA0E2BB68040FD561793DAC161B0BB55223C56908D0019343FEAB1EF1F894AE1 5037D86062BD9A1DF8546E4DB3ADF228980ECFB1E999F474D97C71A22D40C47B 7871672605CA1CECEDAE9899DCFA066154C198C0600BA3E381FC3EB42ED9B8A8 0BB06E3E923DA44D5B050B4E68265DE87B1FF6DBD93F91408E9A55389DF55C8B 825DF6347BDCDBAFBD05F60BA44D3D59BC11D4DFE8EFBAE6D2227551AA9B68EB 3EE4AF0407E1AD080211A18105F662EFCAC25A40C08799871B619B855AE34D08 26FA9FA81E633F21F75988272D336C77D9F7532C1ED15BAC59194C650A9ADF70 C006C1F93ED40249AB566E63BFF9B8B9A7EC9FF08CB211C716B029BF9F0C768C 8191075B7BADDB644C430E7A651C2EB4E233D387D217E3D4EDCFBB0F8EF1D73B 3188B22965645DDC55A05D0B037C0821E0B3B6BABDD7A7280A9F1F24BB31026C 9A6D4C413CE898C783B4444EBC76A06A19A7C99A0C9920CE6B426DCECD77736A 1A772EDD19E96A3C87FAB62DA8BDC57BA47733A8A0E78F1D3A7F409D95DDF5BB FB521AE1997D7ECC5C81D7BB5154956D2B1002BD9DE8DDD251767BB9C6D0E02B DEB6762EE826727EEC11B20093B6E38F0138C5AC4CD200494B8AE9CB3BF878E4 263925F4EDECB39B6E3D684C323A3FDB160C4CDD6618E3823927A391D611011F F6873E2FF4ED9996AE0415AF4800B64C1100A031E1C991ABABFDFF3C12D5F77D 9EA7BB0453A22D654D6EBAB18C4C5579B63F25767E5813D9F79F42A8009B0A4D 5E592B28B3A2E6524710239EFB65597A9CD88B66D31DE299DB7E724683722331 6D9B9508201DB62FD80664EACDE23FC76EE89E55527DA984C6D0929E0E20D6B1 0881C0F451C005BD52F1EADD737701573E3B4AFC52435AFB8A981BB47812B2BC 99D59CBDA183F1921DD45BBB42A524CE4FAB72A79602B0496EE583B87D0BA3CE 71A3640EFF3E0D809DAAAA54E82E9249AE929E93A68BF87A7801BC01BDC7F4DE DA103E1B8C1EFE21C03FD90BEFA1602B6BCE5FD819F167879F795CAF81E05B5C D74D647D3426CED4BE9E4C308E2360B53A40B1D7720E7F1D5D22C2BD827E8373 CB8A5B08131B39F9CDA49153CFF099BC4DF6FDDB80F59509A32392DF306B6E2B F973C7C05554D92BF4F1ACDFE5CFD39486BA8AB0D0069766FAB6FFC1D40F4C07 CBDC04704A69C041E4EA404C00FDC0A34F0E6637812FB523E2DFE40551602C9D 664A96B77B849B5D3107597AACC65465BC6C09ADBB915E67DC63FCAC0EAA5C0F E6F1D9A7ACC09B861928C87CF7FE5A0092EE093F73046094F52581EC4853F98A F84595BF45580CE30C210ECF0641F82A71F77AFE7BCE15B1C39E4E2A55B1C405 AFC93F8811F4A84F595AF7EC453A8E735D338B3AC3633441DC58C56E9C9B84F9 54B2BA3D899FD7D929F7D0A7D3F9452F141E1A6A68BA4CA103B5DC94F63AB61A 2AB2A04DD3F014B0D7F871654B963406F7B296F9B7FE3F6A0D0B2258C29FF318 E1960049ACA3411F82D9544F167925D4163ED9380494446A67FCFA4DE1E23DAE C50339EE7AB1F4291BEF16432F68EB3088A7F294814A0A179570954DFF7C27EC 8BC2EA77377CB197770BCE78D444610101A80698E28263C41EDBC6F825B4562C 65B2009F9087ACF99A709B3D5AAB2ED22A94C3A622CC98FBCE9E7F8F18FED151 890D53C0560D0C2C969C7BB7463204E9C30C63EFD51F408562C29267E38EA661 8316B2A7DD52046D27DFC76C02AC615674E0D85282A61ECBA2C2D4BB6153A409 070F7F0ABF6B23C7B06942AFBEFD708FC39A034BC82F21EA78C512735C89181B B6EDA640A892E64A7E490F528FBA76F10BFFF4DE1294E2CDD35A3419A1661145 2465A18A5DE0DAD151733C48A64DF80C6DB5BB72FD67F1CD176B4F2E463000C5 490C5C999E90BBB4CF6D16094E09C7F5990E1235ACFB8A5BEBE21F58A0945F0C 36A7FECC771106BCED529CCCFA3A7CC05B23BC2770A5FE9EB75D65B337663A4C FBF12FDE6A049829984800F1AA76A57F5728622BB6E78C3695295292CCEE2F16 03D3D0A1AAE72CF4C5FF78C5EA22D3870F87357B2A6609409F1F85CB9F46F884 6B77E64E503D45F5314F648AAFD0B1B69578C909359FB08680D403EBB6BE9231 940E27D7E0CA5A862205456759FCA18583CBBB49DEF654D42DAF400AA41C552F EBC2FE3F3FF3C101C885211B2ED2A7CCDFFDCF0BABA621DB4418CF481079AB83 4CC9CB9492CE101BFB448742CD7CF1E41F60C30563D081F110CBB17D112E7A62 CD9DDCA12FBADA3096BC9A2DCAD56AB9BBD12A2C1532B43F1867C22DB3F55E87 752A1C25073ED8AC7E6930C332A41BB3806E41802F25705FF22E51D3A56849A3 A9981CAD6B925D75299B5BF843AFCF792AAAF569CA37C6A4967214DB6934E202 0E188EB7BC6EC4 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont TeXDict begin 40108032 51904512 1000 600 600 (book.dvi) @start /Fa 134[50 6[50 1[50 50 6[50 2[50 50 19[50 8[50 71[{ TeXBase1Encoding ReEncodeFont }9 83.022 /NimbusMonL-Regu rf /Fb 134[66 2[66 73 40 66 47 1[73 73 73 106 33 66 1[33 73 73 40 66 73 66 73 66 12[73 80 1[93 1[93 86 1[73 2[33 86 2[80 86 86 86 86 7[66 3[66 66 66 66 66 2[33 46[{ TeXBase1Encoding ReEncodeFont }41 119.552 /NimbusSanL-Bold rf /Fc 134[45 45 2[45 45 45 45 1[45 45 45 45 45 2[45 45 45 45 45 1[45 1[45 12[45 45 45 1[45 45 45 4[45 3[45 45 45 67[{ TeXBase1Encoding ReEncodeFont }28 74.7198 /NimbusMonL-ReguObli rf /Fd 133[45 45 45 1[45 45 45 45 45 1[45 45 45 5[45 45 45 45 45 45 1[45 45[45 4[45 45 45[{ TeXBase1Encoding ReEncodeFont }21 74.7198 /NimbusMonL-Bold rf /Fe 133[45 45 45 45 45 45 45 45 45 1[45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 8[45 2[45 45 45 45 1[45 1[45 45 45 1[45 45 45 45 45 2[45 45 45 45 2[45 2[45 45 1[45 1[45 1[45 45 45 45 45 45 45 45 45 1[45 45 40[{ TeXBase1Encoding ReEncodeFont }59 74.7198 /NimbusMonL-Regu rf /Ff 106[21 149[{ TeXBase1Encoding ReEncodeFont }1 59.7758 /NimbusRomNo9L-Regu rf /Fg 106[23 149[{ TeXBase1Encoding ReEncodeFont }1 66.4176 /NimbusRomNo9L-Regu rf /Fh 134[80 80 112 80 88 48 80 56 1[88 88 88 128 40 80 1[40 88 88 1[80 88 80 88 80 6[88 96 1[135 96 104 88 96 104 1[96 112 104 120 88 2[40 104 112 88 96 104 104 104 104 7[80 80 80 80 80 80 80 80 80 80 1[40 48 42[88 2[{ TeXBase1Encoding ReEncodeFont }57 143.462 /NimbusSanL-Bold rf /Fi 134[37 3[42 23 32 32 1[42 42 42 60 23 37 1[23 42 42 1[37 42 37 1[42 12[46 3[51 2[69 46 2[28 60 60 3[55 9[42 42 42 42 42 42 42 42 42 42 1[21 46[{ TeXBase1Encoding ReEncodeFont }37 83.022 /NimbusRomNo9L-ReguItal rf /Fj 104[83 26[17 1[37 42 42 60 42 42 23 32 28 42 42 42 42 65 23 42 23 23 42 42 28 37 42 37 42 37 1[42 1[28 23 28 51 60 60 78 60 60 51 46 55 60 46 60 60 74 51 1[32 28 60 60 46 51 60 55 55 60 76 37 47 47 47 23 23 42 42 42 42 42 42 42 42 42 42 23 21 28 21 47 42 28 28 28 1[69 2[34 28 29[46 46 2[{ TeXBase1Encoding ReEncodeFont }88 83.022 /NimbusRomNo9L-Regu rf /Fk 134[42 3[46 28 32 37 1[46 42 46 69 23 46 1[23 46 42 1[37 46 37 46 42 7[60 4[55 46 1[65 51 65 60 78 3[32 65 65 3[60 1[60 3[47 4[42 42 42 42 42 42 42 42 1[23 21 28 42[46 2[{ TeXBase1Encoding ReEncodeFont }45 83.022 /NimbusRomNo9L-Medi rf /Fl 134[96 3[105 57 96 67 1[105 105 105 153 48 96 1[48 105 105 57 96 105 96 105 96 12[105 115 1[134 115 6[48 124 134 3[124 12[96 96 96 96 96 96 2[48 43[105 2[{ TeXBase1Encoding ReEncodeFont }36 172.154 /NimbusSanL-Bold rf /Fm 134[46 3[51 2[32 1[51 51 51 1[23 3[51 2[46 51 2[46 16[55 2[69 5[65 71[{ TeXBase1Encoding ReEncodeFont }14 83.022 /NimbusSanL-Bold rf /Fn 134[115 3[126 2[80 1[126 126 126 1[57 3[126 126 1[115 126 2[115 16[138 2[172 3[57 1[161 24[57 46[{ TeXBase1Encoding ReEncodeFont }17 206.584 /NimbusSanL-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter /setpagedevice where { pop << /PageSize [612 792] >> setpagedevice } { /letter where { pop letter } if } ifelse %%EndPaperSize end %%EndSetup %%Page: 1 1 TeXDict begin 1 0 bop -600 -600 a SDict begin [/Producer (dvips + Distiller)/Title ()/Subject ()/Creator (LaTeX with hyperref)/Author ()/Keywords () /DOCINFO pdfmark end -600 -600 a -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.1) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin [/Count -0/Dest (1.0) cvn/Title (PyGopherd Manual) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (2.0) cvn/Title (Table of Contents) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -2/Dest (3.0) cvn/Title (Chapter 1. Introduction to PyGopherd) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (3.1.1) cvn/Title (1.1. Features) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (3.2.1) cvn/Title (1.2. About Gopher) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (4.0) cvn/Title (Chapter 2. Quick Start) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -3/Dest (5.0) cvn/Title (Chapter 3. Installation) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (5.3.1) cvn/Title (3.1. Debian SystemWide Installation) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (5.4.1) cvn/Title (3.2. Other SystemWide Installation) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (5.5.1) cvn/Title (3.3. SingleAccount Installation) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (6.0) cvn/Title (Chapter 4. Configuration) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -13/Dest (7.0) cvn/Title (Chapter 5. Handlers) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.6.1) cvn/Title (5.1. dir.DirHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.7.1) cvn/Title (5.2. gophermap.BuckGophermapHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.8.1) cvn/Title (5.3. file.CompressedFileHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.9.1) cvn/Title (5.4. file.FileHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.10.1) cvn/Title (5.5. html.HTMLFileTitleHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.11.1) cvn/Title (5.6. mbox handlers) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.12.1) cvn/Title (5.7. pyg.PYGHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.13.1) cvn/Title (5.8. scriptexec.ExecHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -5/Dest (7.14.1) cvn/Title (5.9. UMN.UMNDirHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.14.1.2) cvn/Title (5.9.1. Links) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.14.2.2) cvn/Title (5.9.2. Overriding Defaults) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.14.3.2) cvn/Title (5.9.3. Adding Cool Links) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.14.4.2) cvn/Title (5.9.4. Hiding an Entry) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.14.5.2) cvn/Title (5.9.5. Abstracts and Info) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.15.1) cvn/Title (5.10. url.HTMLURLHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.16.1) cvn/Title (5.11. url.URLTypeRewriter) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.17.1) cvn/Title (5.12. virtual.Virtual) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (7.18.1) cvn/Title (5.13. ZIP.ZIPHandler) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (8.0) cvn/Title (Chapter 6. Gopher Item Types) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -1/Dest (9.0) cvn/Title (I. PyGopherd Manpage) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -10/Dest (9.19.1) cvn/Title (pygopherd) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.6.2) cvn/Title (Name) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.7.2) cvn/Title (Synopsis) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.8.2) cvn/Title (Description) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.9.2) cvn/Title (Quick Start) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.10.2) cvn/Title (Options) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.11.2) cvn/Title (Conforming To) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.12.2) cvn/Title (Bugs) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.13.2) cvn/Title (Copyright) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.14.2) cvn/Title (Author) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/Count -0/Dest (9.19.15.2) cvn/Title (See Also) /OUT pdfmark end -2 -11 a -2 -11 a SDict begin [/PageMode /UseOutlines/Page 1/View [/Fit] /DOCVIEW pdfmark end -2 -11 a -2 -11 a SDict begin [ {Catalog}<<>> /PUT pdfmark end -2 -11 a -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 12 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (Doc-Start) cvn /DEST pdfmark end -2 -11 a -2 -11 a SDict begin [ {Catalog} <>1<>2<>3<>4<>5<>6<>7<>8<>9<>10<>11<>12<>13<>14<>15<>16<>17<>18<>19<>20<>21<>22<>23<>24<>]>>>> /PUT pdfmark end -2 -11 a -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 12 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:PYGOPHERD) cvn /DEST pdfmark end -2 -11 a 1002 140 a Fn(PyGopher)l(d)58 b(Man)n(ual)2878 140 y SDict begin H.S end 2878 140 a 2878 140 a SDict begin 32.348 H.A end 2878 140 a 2878 140 a SDict begin [/View [/XYZ H.V]/Dest (1.0) cvn /DEST pdfmark end 2878 140 a Black Black eop end %%Page: 2 2 TeXDict begin 2 1 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.2) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 72 a Fm(PyGopher)n(d)23 b(Man)o(ual)p Black Black eop end %%Page: 3 3 TeXDict begin 3 2 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.iii) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 115 a Fl(T)-14 b(ab)n(le)48 b(of)g(Contents)1435 115 y SDict begin H.S end 1435 115 a 1435 115 a SDict begin 26.957 H.A end 1435 115 a 1435 115 a SDict begin [/View [/XYZ H.V]/Dest (2.0) cvn /DEST pdfmark end 1435 115 a 0 TeXcolorgray 396 257 a SDict begin H.S end 396 257 a Fk(1.)20 b(Intr)o(oduction)g(to)g(PyGopherd)1453 257 y SDict begin 13 H.L end 1453 257 a 1453 257 a SDict begin [/Subtype /Link/Dest (0:PYGOPHERD.INTRO) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1453 257 a Black Black 18 w Fk(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 257 a SDict begin H.S end 3842 257 a Fk(1)3884 257 y SDict begin 13 H.L end 3884 257 a 3884 257 a SDict begin [/Subtype /Link/Dest (0:PYGOPHERD.INTRO) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 257 a Black 0 TeXcolorgray 596 385 a SDict begin H.S end 596 385 a Fj(1.1.)f(Features)1023 385 y SDict begin 13 H.L end 1023 385 a 1023 385 a SDict begin [/Subtype /Link/Dest (0:FEATURES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1023 385 a Black Black 13 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 385 a SDict begin H.S end 3842 385 a Fj(1)3884 385 y SDict begin 13 H.L end 3884 385 a 3884 385 a SDict begin [/Subtype /Link/Dest (0:FEATURES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 385 a Black 0 TeXcolorgray 596 493 a SDict begin H.S end 596 493 a Fj(1.2.)g(About)g(Gopher)1220 493 y SDict begin 13 H.L end 1220 493 a 1220 493 a SDict begin [/Subtype /Link/Dest (0:ABOUTGOPHER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1220 493 a Black Black 2 w Fj(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 493 a SDict begin H.S end 3842 493 a Fj(2)3884 493 y SDict begin 13 H.L end 3884 493 a 3884 493 a SDict begin [/Subtype /Link/Dest (0:ABOUTGOPHER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 493 a Black 0 TeXcolorgray 396 621 a SDict begin H.S end 396 621 a Fk(2.)h(Quick)h(Start)898 621 y SDict begin 13 H.L end 898 621 a 898 621 a SDict begin [/Subtype /Link/Dest (0:QUICKSTART) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 898 621 a Black Black 13 w Fk(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 621 a SDict begin H.S end 3842 621 a Fk(3)3884 621 y SDict begin 13 H.L end 3884 621 a 3884 621 a SDict begin [/Subtype /Link/Dest (0:QUICKSTART) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 621 a Black 0 TeXcolorgray 396 749 a SDict begin H.S end 396 749 a Fk(3.)f(Installation)886 749 y SDict begin 13 H.L end 886 749 a 886 749 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 886 749 a Black Black 4 w Fk(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 749 a SDict begin H.S end 3842 749 a Fk(4)3884 749 y SDict begin 13 H.L end 3884 749 a 3884 749 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 749 a Black 0 TeXcolorgray 596 877 a SDict begin H.S end 596 877 a Fj(3.1.)f(Debian)g(System-W)m(ide)h(Installation)1846 877 y SDict begin 13 H.L end 1846 877 a 1846 877 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.DEBIAN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1846 877 a Black Black -1 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 877 a SDict begin H.S end 3842 877 a Fj(4)3884 877 y SDict begin 13 H.L end 3884 877 a 3884 877 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.DEBIAN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 877 a Black 0 TeXcolorgray 596 985 a SDict begin H.S end 596 985 a Fj(3.2.)f(Other)h(System-W)m(ide)f(Installation)1795 985 y SDict begin 13 H.L end 1795 985 a 1795 985 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.OTHER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1795 985 a Black Black 8 w Fj(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 985 a SDict begin H.S end 3842 985 a Fj(4)3884 985 y SDict begin 13 H.L end 3884 985 a 3884 985 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.OTHER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 985 a Black 0 TeXcolorgray 596 1093 a SDict begin H.S end 596 1093 a Fj(3.3.)g(Single-Account)f (Installation)1658 1093 y SDict begin 13 H.L end 1658 1093 a 1658 1093 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.SINGLE) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1658 1093 a Black Black Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1093 a SDict begin H.S end 3842 1093 a Fj(4)3884 1093 y SDict begin 13 H.L end 3884 1093 a 3884 1093 a SDict begin [/Subtype /Link/Dest (0:INSTALLATION.SINGLE) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1093 a Black 0 TeXcolorgray 396 1220 a SDict begin H.S end 396 1220 a Fk(4.)i(Con\002guration)979 1220 y SDict begin 13 H.L end 979 1220 a 979 1220 a SDict begin [/Subtype /Link/Dest (0:CONFIGURATION) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 979 1220 a Black Black 15 w Fk(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1220 a SDict begin H.S end 3842 1220 a Fk(6)3884 1220 y SDict begin 13 H.L end 3884 1220 a 3884 1220 a SDict begin [/Subtype /Link/Dest (0:CONFIGURATION) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1220 a Black 0 TeXcolorgray 396 1348 a SDict begin H.S end 396 1348 a Fk(5.)g(Handlers)807 1348 y SDict begin 13 H.L end 807 1348 a 807 1348 a SDict begin [/Subtype /Link/Dest (0:HANDLERS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 807 1348 a Black Black Fk(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1348 a SDict begin H.S end 3842 1348 a Fk(7)3884 1348 y SDict begin 13 H.L end 3884 1348 a 3884 1348 a SDict begin [/Subtype /Link/Dest (0:HANDLERS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1348 a Black 0 TeXcolorgray 596 1476 a SDict begin H.S end 596 1476 a Fj(5.1.)f(dir)-5 b(.DirHandler)1230 1476 y SDict begin 13 H.L end 1230 1476 a 1230 1476 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.DIRHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1230 1476 a Black Black 13 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1476 a SDict begin H.S end 3842 1476 a Fj(7)3884 1476 y SDict begin 13 H.L end 3884 1476 a 3884 1476 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.DIRHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1476 a Black 0 TeXcolorgray 596 1584 a SDict begin H.S end 596 1584 a Fj(5.2.)19 b(gophermap.BuckGopher)o(map)o(Hand)o (ler)1976 1584 y SDict begin 13 H.L end 1976 1584 a 1976 1584 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.BUCKGOPHERMAP) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1976 1584 a Black Black 14 w Fj(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1584 a SDict begin H.S end 3842 1584 a Fj(7)3884 1584 y SDict begin 13 H.L end 3884 1584 a 3884 1584 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.BUCKGOPHERMAP) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1584 a Black 0 TeXcolorgray 596 1692 a SDict begin H.S end 596 1692 a Fj(5.3.)g(\002le.CompressedFileHandler)1678 1692 y SDict begin 13 H.L end 1678 1692 a 1678 1692 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.COMPRESSEDFILEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1678 1692 a Black Black 1 w Fj(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1692 a SDict begin H.S end 3842 1692 a Fj(8)3884 1692 y SDict begin 13 H.L end 3884 1692 a 3884 1692 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.COMPRESSEDFILEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1692 a Black 0 TeXcolorgray 596 1800 a SDict begin H.S end 596 1800 a Fj(5.4.)g (\002le.FileHandler)1266 1800 y SDict begin 13 H.L end 1266 1800 a 1266 1800 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.FILEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1266 1800 a Black Black 19 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1800 a SDict begin H.S end 3842 1800 a Fj(9)3884 1800 y SDict begin 13 H.L end 3884 1800 a 3884 1800 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.FILEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1800 a Black 0 TeXcolorgray 596 1908 a SDict begin H.S end 596 1908 a Fj(5.5.)g(html.HTMLFileT)m(itleHandler)1703 1908 y SDict begin 13 H.L end 1703 1908 a 1703 1908 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.HTMLFILETITLEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1703 1908 a Black Black -3 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 1908 a SDict begin H.S end 3842 1908 a Fj(9)3884 1908 y SDict begin 13 H.L end 3884 1908 a 3884 1908 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.HTMLFILETITLEHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 1908 a Black 0 TeXcolorgray 596 2016 a SDict begin H.S end 596 2016 a Fj(5.6.)g(mbox)g(handlers)1234 2016 y SDict begin 13 H.L end 1234 2016 a 1234 2016 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.MAILBOXES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1234 2016 a Black Black 9 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 2016 a SDict begin H.S end 3842 2016 a Fj(9)3884 2016 y SDict begin 13 H.L end 3884 2016 a 3884 2016 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.MAILBOXES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2016 a Black 0 TeXcolorgray 596 2124 a SDict begin H.S end 596 2124 a Fj(5.7.)g(p)o(yg.PYGHandler)1322 2124 y SDict begin 13 H.L end 1322 2124 a 1322 2124 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.PYGHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1322 2124 a Black Black 4 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black 0 TeXcolorgray 3842 2124 a SDict begin H.S end 3842 2124 a Fj(9)3884 2124 y SDict begin 13 H.L end 3884 2124 a 3884 2124 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.PYGHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2124 a Black 0 TeXcolorgray 596 2232 a SDict begin H.S end 596 2232 a Fj(5.8.)g(scripte)o(x)o(ec.Ex)o(ecHandler)1533 2232 y SDict begin 13 H.L end 1533 2232 a 1533 2232 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.EXECHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1533 2232 a Black Black 1 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2232 a SDict begin H.S end 3800 2232 a Fj(10)3884 2232 y SDict begin 13 H.L end 3884 2232 a 3884 2232 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.EXECHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2232 a Black 0 TeXcolorgray 596 2340 a SDict begin H.S end 596 2340 a Fj(5.9.)g(UMN.UMNDirHandler)1530 2340 y SDict begin 13 H.L end 1530 2340 a 1530 2340 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1530 2340 a Black Black 4 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2340 a SDict begin H.S end 3800 2340 a Fj(11)3884 2340 y SDict begin 13 H.L end 3884 2340 a 3884 2340 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2340 a Black 0 TeXcolorgray 795 2448 a SDict begin H.S end 795 2448 a Fj(5.9.1.)f(Links)1192 2448 y SDict begin 13 H.L end 1192 2448 a 1192 2448 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.LINKS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1192 2448 a Black Black 10 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2448 a SDict begin H.S end 3800 2448 a Fj(11)3884 2448 y SDict begin 13 H.L end 3884 2448 a 3884 2448 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.LINKS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2448 a Black 0 TeXcolorgray 795 2555 a SDict begin H.S end 795 2555 a Fj(5.9.2.)g(Ov)o(erriding)g(Def)o(aults)1667 2555 y SDict begin 13 H.L end 1667 2555 a 1667 2555 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.OVERRIDING) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1667 2555 a Black Black 12 w Fj(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2555 a SDict begin H.S end 3800 2555 a Fj(12)3884 2555 y SDict begin 13 H.L end 3884 2555 a 3884 2555 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.OVERRIDING) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2555 a Black 0 TeXcolorgray 795 2663 a SDict begin H.S end 795 2663 a Fj(5.9.3.)g(Adding)h(Cool)h(Links)1644 2663 y SDict begin 13 H.L end 1644 2663 a 1644 2663 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.COOL) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1644 2663 a Black Black 14 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2663 a SDict begin H.S end 3800 2663 a Fj(13)3884 2663 y SDict begin 13 H.L end 3884 2663 a 3884 2663 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.COOL) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2663 a Black 0 TeXcolorgray 795 2771 a SDict begin H.S end 795 2771 a Fj(5.9.4.)e(Hiding)i(an)g(Entry)1539 2771 y SDict begin 13 H.L end 1539 2771 a 1539 2771 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.HIDING) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1539 2771 a Black Black 15 w Fj(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2771 a SDict begin H.S end 3800 2771 a Fj(13)3884 2771 y SDict begin 13 H.L end 3884 2771 a 3884 2771 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.HIDING) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2771 a Black 0 TeXcolorgray 795 2879 a SDict begin H.S end 795 2879 a Fj(5.9.5.)e(Abstracts)j(and)e(Info)1617 2879 y SDict begin 13 H.L end 1617 2879 a 1617 2879 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.ABSTRACTS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1617 2879 a Black Black Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2879 a SDict begin H.S end 3800 2879 a Fj(14)3884 2879 y SDict begin 13 H.L end 3884 2879 a 3884 2879 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.UMN.ABSTRACTS) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2879 a Black 0 TeXcolorgray 596 2987 a SDict begin H.S end 596 2987 a Fj(5.10.)f (url.HTMLURLHandler)1567 2987 y SDict begin 13 H.L end 1567 2987 a 1567 2987 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.HTMLURLHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1567 2987 a Black Black 8 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 2987 a SDict begin H.S end 3800 2987 a Fj(14)3884 2987 y SDict begin 13 H.L end 3884 2987 a 3884 2987 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.HTMLURLHANDLER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 2987 a Black 0 TeXcolorgray 596 3095 a SDict begin H.S end 596 3095 a Fj(5.11.)g(url.URL)-8 b(T)h(ypeRe)n(writer)1508 3095 y SDict begin 13 H.L end 1508 3095 a 1508 3095 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.URLTYPEREWRITER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1508 3095 a Black Black 5 w Fj(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3095 a SDict begin H.S end 3800 3095 a Fj(14)3884 3095 y SDict begin 13 H.L end 3884 3095 a 3884 3095 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.URLTYPEREWRITER) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3095 a Black 0 TeXcolorgray 596 3203 a SDict begin H.S end 596 3203 a Fj(5.12.)18 b(virtual.V)-5 b(irtual)1252 3203 y SDict begin 13 H.L end 1252 3203 a 1252 3203 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.VIRTUAL) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1252 3203 a Black Black 12 w Fj(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3203 a SDict begin H.S end 3800 3203 a Fj(14)3884 3203 y SDict begin 13 H.L end 3884 3203 a 3884 3203 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.VIRTUAL) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3203 a Black 0 TeXcolorgray 596 3311 a SDict begin H.S end 596 3311 a Fj(5.13.)18 b(ZIP)-9 b(.ZIPHandler)1313 3311 y SDict begin 13 H.L end 1313 3311 a 1313 3311 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.ZIP) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1313 3311 a Black Black 13 w Fj(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3311 a SDict begin H.S end 3800 3311 a Fj(15)3884 3311 y SDict begin 13 H.L end 3884 3311 a 3884 3311 a SDict begin [/Subtype /Link/Dest (0:HANDLERS.ZIP) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3311 a Black 0 TeXcolorgray 396 3439 a SDict begin H.S end 396 3439 a Fk(6.)20 b(Gopher)g(Item)h(T)-6 b(ypes)1165 3439 y SDict begin 13 H.L end 1165 3439 a 1165 3439 a SDict begin [/Subtype /Link/Dest (0:TYPES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1165 3439 a Black Black 16 w Fk(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3439 a SDict begin H.S end 3800 3439 a Fk(16)3884 3439 y SDict begin 13 H.L end 3884 3439 a 3884 3439 a SDict begin [/Subtype /Link/Dest (0:TYPES) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3439 a Black 0 TeXcolorgray 396 3567 a SDict begin H.S end 396 3567 a Fk(I.)21 b(PyGopherd)e(Manpage)1234 3567 y SDict begin 13 H.L end 1234 3567 a 1234 3567 a SDict begin [/Subtype /Link/Dest (0:PYGOPHERD.MAN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 1234 3567 a Black Black 9 w Fk(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3567 a SDict begin H.S end 3800 3567 a Fk(18)3884 3567 y SDict begin 13 H.L end 3884 3567 a 3884 3567 a SDict begin [/Subtype /Link/Dest (0:PYGOPHERD.MAN) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3567 a Black 0 TeXcolorgray 596 3695 a SDict begin H.S end 596 3695 a Fj(p)o(ygopherd)954 3695 y SDict begin 13 H.L end 954 3695 a 954 3695 a SDict begin [/Subtype /Link/Dest (0:473) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 954 3695 a Black Black -1 w Fj(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black(.)p Black Black -1 w(.)p Black 0 TeXcolorgray 3800 3695 a SDict begin H.S end 3800 3695 a Fj(19)3884 3695 y SDict begin 13 H.L end 3884 3695 a 3884 3695 a SDict begin [/Subtype /Link/Dest (0:473) cvn/H /I/Border [0 0 0]BorderArrayPatch/Color [1 0 0] H.B /ANN pdfmark end 3884 3695 a Black Black 3814 5569 a Fi(iii)p Black eop end %%Page: 1 4 TeXDict begin 1 3 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.1) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:PYGOPHERD.INTRO) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(1.)f(Intr)m(oduction)i(to)f(PyGopher)m(d)3071 115 y SDict begin H.S end 3071 115 a 3071 115 a SDict begin 26.957 H.A end 3071 115 a 3071 115 a SDict begin [/View [/XYZ H.V]/Dest (3.0) cvn /DEST pdfmark end 3071 115 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:5) cvn /DEST pdfmark end -2 371 a 396 443 a Fj(W)-7 b(elcome)21 b(to)814 443 y SDict begin H.S end 814 443 a 814 443 a SDict begin 13 H.A end 814 443 a 814 443 a SDict begin [/View [/XYZ H.V]/Dest (0:6) cvn /DEST pdfmark end 814 443 a Fj(PyGopherd.)d(In)h(a)i (nutshell,)1686 443 y SDict begin H.S end 1686 443 a 1686 443 a SDict begin 13 H.A end 1686 443 a 1686 443 a SDict begin [/View [/XYZ H.V]/Dest (0:7) cvn /DEST pdfmark end 1686 443 a Fj(PyGopherd)c(is)22 b(a)e(modern)f(dynamic)f (multi-protocol)g(hierarchical)396 551 y(information)g(serv)o(er)h (with)i(a)f(pluggable)e(modularized)g(e)o(xtension)h(system,)h(full)g (\003e)o(xible)f(caching,)g(virtual)h(\002les)h(and)396 659 y(folders,)e(and)h(autodetection)e(of)i(\002le)h(types)f(--)g(all)h (with)f(support)f(for)g(standardized)g(yet)h(e)o(xtensible)f(per)n (-document)396 767 y(metadata.)g(Whe)n(w!)h(Read)h(on)f(for)f (information)f(on)i(what)g(all)h(these)f(b)n(uzzw)o(ords)f(mean.)-2 768 y SDict begin H.S end -2 768 a -2 768 a SDict begin 13 H.A end -2 768 a -2 768 a SDict begin [/View [/XYZ H.V]/Dest (0:FEATURES) cvn /DEST pdfmark end -2 768 a 376 x Fh(1.1.)39 b(Features)877 1144 y SDict begin H.S end 877 1144 a 877 1144 a SDict begin 22.464 H.A end 877 1144 a 877 1144 a SDict begin [/View [/XYZ H.V]/Dest (3.1.1) cvn /DEST pdfmark end 877 1144 a -2 1312 a SDict begin H.S end -2 1312 a -2 1312 a SDict begin 13 H.A end -2 1312 a -2 1312 a SDict begin [/View [/XYZ H.V]/Dest (0:10) cvn /DEST pdfmark end -2 1312 a 396 1418 a Fj(Here)20 b(are)g(some)g(of)986 1418 y SDict begin H.S end 986 1418 a 986 1418 a SDict begin 13 H.A end 986 1418 a 986 1418 a SDict begin [/View [/XYZ H.V]/Dest (0:11) cvn /DEST pdfmark end 986 1418 a Fj(PyGopherd')-5 b(s)19 b(features:)-2 1436 y SDict begin H.S end -2 1436 a -2 1436 a SDict begin 13 H.A end -2 1436 a -2 1436 a SDict begin [/View [/XYZ H.V]/Dest (0:12) cvn /DEST pdfmark end -2 1436 a -2 1446 a SDict begin H.S end -2 1446 a -2 1446 a SDict begin 13 H.A end -2 1446 a -2 1446 a SDict begin [/View [/XYZ H.V]/Dest (0:13) cvn /DEST pdfmark end -2 1446 a Black 396 1588 a Fg(\225)p Black 479 1588 a SDict begin H.S end 479 1588 a 479 1588 a SDict begin 13 H.A end 479 1588 a 479 1588 a SDict begin [/View [/XYZ H.V]/Dest (0:14) cvn /DEST pdfmark end 479 1588 a Fj(Pro)o(vides)g(b)n(uilt-in)h(support)f(for)g (multiple)h(protocols:)f(HTTP)h(\(W)-7 b(eb\),)20 b(Gopher+,)e(Gopher)h (\(RFC1436\),)479 1696 y(Enhanced)f(Gopher0,)g(Gemini,)i(Spartan,)f (and)h(W)-10 b(AP)21 b(\(mobile)e(phones\).)f(Protocols)i(can)g(be)g (enabled)f(or)h(disabled)479 1804 y(as)h(desired.)-2 1805 y SDict begin H.S end -2 1805 a -2 1805 a SDict begin 13 H.A end -2 1805 a -2 1805 a SDict begin [/View [/XYZ H.V]/Dest (0:15) cvn /DEST pdfmark end -2 1805 a Black 396 1953 a Fg(\225)p Black 479 1953 a SDict begin H.S end 479 1953 a 479 1953 a SDict begin 13 H.A end 479 1953 a 479 1953 a SDict begin [/View [/XYZ H.V]/Dest (0:16) cvn /DEST pdfmark end 479 1953 a Fj(Pro)o(vides)e (protocol)g(autodetection.)f(That)i(is,)1845 1953 y SDict begin H.S end 1845 1953 a 1845 1953 a SDict begin 13 H.A end 1845 1953 a 1845 1953 a SDict begin [/View [/XYZ H.V]/Dest (0:17) cvn /DEST pdfmark end 1845 1953 a Fj(PyGopherd)e(can)i(listen)h(for)f(all)g(the)h(abo)o(v)o(e)d (protocols)3471 1953 y SDict begin H.S end 3471 1953 a 3471 1953 a SDict begin 13 H.A end 3471 1953 a 3471 1953 a SDict begin [/View [/XYZ H.V]/Dest (0:18) cvn /DEST pdfmark end 3471 1953 a Fi(on)i(a)g(single)479 2061 y(port)i Fj(and)e(will)h(automatically)d(respond)h(using)g(the)i (protocol)d(it)j(detects)f(the)h(client)f(is)h(using.)e(Practical)i(ef) n(fects)f(of)479 2169 y(this)h(are)f(that)g(you)g(can,)f(for)h (instance,)g(gi)n(v)o(e)f(out)h(a)g(single)h(URL)f(and)g(ha)n(v)o(e)g (it)g(vie)n(w)o(able)g(normally)f(on)g(desktop)479 2277 y(W)-7 b(eb)21 b(bro)n(wsers)f(and)f(in)i(W)-10 b(AP)21 b(mode)e(on)h(mobile)f(phones)g(--)h(and)g(appropriately)d(in)k(v)n (arious)e(Gopher)f(bro)n(wsers.)-2 2295 y SDict begin H.S end -2 2295 a -2 2295 a SDict begin 13 H.A end -2 2295 a -2 2295 a SDict begin [/View [/XYZ H.V]/Dest (0:19) cvn /DEST pdfmark end -2 2295 a Black 396 2426 a Fg(\225)p Black 479 2426 a SDict begin H.S end 479 2426 a 479 2426 a SDict begin 13 H.A end 479 2426 a 479 2426 a SDict begin [/View [/XYZ H.V]/Dest (0:20) cvn /DEST pdfmark end 479 2426 a Fj(Metadata)i(and)g(site)h(links)f(can)g (be)g(entered)f(in)h(a)h(v)n(ariety)e(of)h(formats,)f(including)g(full) h(UMN)g(dot\002le)g(metadata)479 2534 y(formats)g(as)h(well)f(as)h (Bucktooth)e(gophermap)e(\002les.)k(Moreo)o(v)o(er)m(,)c(gophermap)g (\002les)22 b(are)e(not)g(limited)g(to)g(Gopher)479 2642 y(protocols,)f(and)g(can)h(be)h(used)e(for)h(all)h(protocols.)-2 2660 y SDict begin H.S end -2 2660 a -2 2660 a SDict begin 13 H.A end -2 2660 a -2 2660 a SDict begin [/View [/XYZ H.V]/Dest (0:21) cvn /DEST pdfmark end -2 2660 a Black 396 2792 a Fg(\225)p Black 479 2792 a SDict begin H.S end 479 2792 a 479 2792 a SDict begin 13 H.A end 479 2792 a 479 2792 a SDict begin [/View [/XYZ H.V]/Dest (0:22) cvn /DEST pdfmark end 479 2792 a Fj(Support)e(for)h(inter) n(-protocol)d(linking)i(\(linking)g(from)g(Gopher)g(sites)i(to)f(web)h (sites\))-2 2810 y SDict begin H.S end -2 2810 a -2 2810 a SDict begin 13 H.A end -2 2810 a -2 2810 a SDict begin [/View [/XYZ H.V]/Dest (0:23) cvn /DEST pdfmark end -2 2810 a Black 396 2941 a Fg(\225)p Black 479 2941 a SDict begin H.S end 479 2941 a 479 2941 a SDict begin 13 H.A end 479 2941 a 479 2941 a SDict begin [/View [/XYZ H.V]/Dest (0:24) cvn /DEST pdfmark end 479 2941 a Fj(V)-5 b(irtual)20 b(folder)f(system)i(lets)g(you)e(serv)o(e)h(up)f (an)o(ything)g(as)h(if)h(it)g(were)f(re)o(gular)f(\002les)i(and)e (directories.)g(PyGopherd)479 3049 y(comes)h(with)h(the)f(follo)n(wing) e(virtual)i(folder)f(systems)h(b)n(uilt)h(in:)-2 3067 y SDict begin H.S end -2 3067 a -2 3067 a SDict begin 13 H.A end -2 3067 a -2 3067 a SDict begin [/View [/XYZ H.V]/Dest (0:25) cvn /DEST pdfmark end -2 3067 a -2 3067 a SDict begin H.S end -2 3067 a -2 3067 a SDict begin 13 H.A end -2 3067 a -2 3067 a SDict begin [/View [/XYZ H.V]/Dest (0:26) cvn /DEST pdfmark end -2 3067 a Black 479 3199 a Ff(\225)p Black 562 3199 a SDict begin H.S end 562 3199 a 562 3199 a SDict begin 13 H.A end 562 3199 a 562 3199 a SDict begin [/View [/XYZ H.V]/Dest (0:27) cvn /DEST pdfmark end 562 3199 a Fj(Can)g(present)e(an)o (y)h(Unix)g(MBO)m(X,)g(MMDF)g(box,)f(MH)i(directory)-5 b(,)18 b(Maildir)h(directory)-5 b(,)18 b(or)i(Babyl)g(mailbox)f(as)i(a) 562 3306 y(virtual)f(folder)m(,)e(the)i(contents)g(of)g(which)g(are)g (the)g(messages)g(in)h(the)f(mailbox.)-2 3324 y SDict begin H.S end -2 3324 a -2 3324 a SDict begin 13 H.A end -2 3324 a -2 3324 a SDict begin [/View [/XYZ H.V]/Dest (0:28) cvn /DEST pdfmark end -2 3324 a Black 479 3456 a Ff(\225)p Black 562 3456 a SDict begin H.S end 562 3456 a 562 3456 a SDict begin 13 H.A end 562 3456 a 562 3456 a SDict begin [/View [/XYZ H.V]/Dest (0:29) cvn /DEST pdfmark end 562 3456 a Fj(Can)h(use)f(a)h(con\002gurable)d (separator)h(to)h(split)h(a)f(\002le)h(into)f(multiple)g(parts,)g(the)g (\002rst)h(line)f(of)g(each)g(becoming)e(the)562 3564 y(name)i(for)f(the)i(virtual)e(folder)-5 b(.)-2 3565 y SDict begin H.S end -2 3565 a -2 3565 a SDict begin 13 H.A end -2 3565 a -2 3565 a SDict begin [/View [/XYZ H.V]/Dest (0:30) cvn /DEST pdfmark end -2 3565 a Black 479 3713 a Ff(\225)p Black 562 3713 a SDict begin H.S end 562 3713 a 562 3713 a SDict begin 13 H.A end 562 3713 a 562 3713 a SDict begin [/View [/XYZ H.V]/Dest (0:31) cvn /DEST pdfmark end 562 3713 a Fj(Can)21 b(peek)e(inside)h(a)h (ZIP)f(\002le)h(and)f(serv)o(e)f(it)i(up)f(as)h(\002rst-class)g(site)g (citizens)g(--)f(metadata)f(can)h(e)n(v)o(en)f(be)h(stored)g(in)562 3821 y(the)h(ZIP)f(\002les.)-2 3822 y SDict begin H.S end -2 3822 a -2 3822 a SDict begin 13 H.A end -2 3822 a -2 3822 a SDict begin [/View [/XYZ H.V]/Dest (0:32) cvn /DEST pdfmark end -2 3822 a Black 479 3971 a Ff(\225)p Black 562 3971 a SDict begin H.S end 562 3971 a 562 3971 a SDict begin 13 H.A end 562 3971 a 562 3971 a SDict begin [/View [/XYZ H.V]/Dest (0:33) cvn /DEST pdfmark end 562 3971 a Fj(Can)h(serv)o(e)e(up)h(the)g(contents)g(of)g(a)g (dictd)g(serv)o(er)g(as)h(a)f(\002lesystem.)39 4120 y SDict begin H.S end 39 4120 a 39 4120 a SDict begin 13 H.A end 39 4120 a 39 4120 a SDict begin [/View [/XYZ H.V]/Dest (0:34) cvn /DEST pdfmark end 39 4120 a Black 396 4269 a Fg(\225)p Black 479 4269 a SDict begin H.S end 479 4269 a 479 4269 a SDict begin 13 H.A end 479 4269 a 479 4269 a SDict begin [/View [/XYZ H.V]/Dest (0:35) cvn /DEST pdfmark end 479 4269 a Fj(Modular)m(,)e(e)o(xtensible) i(design:)f(you)g(can)h(use)h(PyGopherd')-5 b(s)18 b(o)n(wn)i(PYG)h(e)o (xtension)d(format,)h(or)h(UMN-)g(or)479 4377 y(Bucktooth-style)e(e)o (x)o(ecutables.)-2 4395 y SDict begin H.S end -2 4395 a -2 4395 a SDict begin 13 H.A end -2 4395 a -2 4395 a SDict begin [/View [/XYZ H.V]/Dest (0:36) cvn /DEST pdfmark end -2 4395 a Black 396 4527 a Fg(\225)p Black 479 4527 a SDict begin H.S end 479 4527 a 479 4527 a SDict begin 13 H.A end 479 4527 a 479 4527 a SDict begin [/View [/XYZ H.V]/Dest (0:37) cvn /DEST pdfmark end 479 4527 a Fj(Runs)j(on)f(an)o(y)f(platform)g(supported)f(by)i (Python)f(2.2,)g(2.3,)g(or)h(2.4.)f(This)i(includes)e(virtually)g(e)n (v)o(ery)g(past)i(and)479 4635 y(current)e(\003a)n(v)n(or)h(of)g(Unix)g (\(Linux,)e(*BSD,)j(Solaris,)f(SunOS\),)g(W)m(indo)n(ws,)f(MacOS)h(9.x) g(and)f(X,)i(and)f(more.)f(Some)479 4743 y(features)h(may)g(not)f(be)i (a)n(v)n(ailable)e(on)h(non-Unix)e(platforms.)-2 4761 y SDict begin H.S end -2 4761 a -2 4761 a SDict begin 13 H.A end -2 4761 a -2 4761 a SDict begin [/View [/XYZ H.V]/Dest (0:38) cvn /DEST pdfmark end -2 4761 a Black 396 4892 a Fg(\225)p Black 479 4892 a SDict begin H.S end 479 4892 a 479 4892 a SDict begin 13 H.A end 479 4892 a 479 4892 a SDict begin [/View [/XYZ H.V]/Dest (0:39) cvn /DEST pdfmark end 479 4892 a Fj(Runs)j(on)f(an)o(y)f (platform)g(supported)f(by)i(Ja)n(v)n(a)g(1.1)g(via)g(the)g(Jython)f (Python)g(implementation.)-2 4910 y SDict begin H.S end -2 4910 a -2 4910 a SDict begin 13 H.A end -2 4910 a -2 4910 a SDict begin [/View [/XYZ H.V]/Dest (0:40) cvn /DEST pdfmark end -2 4910 a Black 396 5042 a Fg(\225)p Black 479 5042 a SDict begin H.S end 479 5042 a 479 5042 a SDict begin 13 H.A end 479 5042 a 479 5042 a SDict begin [/View [/XYZ H.V]/Dest (0:41) cvn /DEST pdfmark end 479 5042 a Fj(T)l(unable)g(serv)o(er)h(types)g(via)g (con\002guration)d(directi)n(v)o(e)i(--)h(forking)f(or)g(threading.)-2 5060 y SDict begin H.S end -2 5060 a -2 5060 a SDict begin 13 H.A end -2 5060 a -2 5060 a SDict begin [/View [/XYZ H.V]/Dest (0:42) cvn /DEST pdfmark end -2 5060 a Black 3842 5569 a Fi(1)p Black eop end %%Page: 2 5 TeXDict begin 2 4 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.2) cvn /DEST pdfmark end -611 -810 a Black Black 2608 -132 a Fi(Chapter)20 b(1.)g(Intr)l(oduction)e(to)i(PyGopher)m(d)p Black Black 396 72 a Fg(\225)p Black 479 72 a SDict begin H.S end 479 72 a 479 72 a SDict begin 13 H.A end 479 72 a 479 72 a SDict begin [/View [/XYZ H.V]/Dest (0:43) cvn /DEST pdfmark end 479 72 a Fj(Secure)g(design)f(with)i(support)e(for)g (chrooted)f(e)o(x)o(ecution.)-2 90 y SDict begin H.S end -2 90 a -2 90 a SDict begin 13 H.A end -2 90 a -2 90 a SDict begin [/View [/XYZ H.V]/Dest (0:44) cvn /DEST pdfmark end -2 90 a Black 396 222 a Fg(\225)p Black 479 222 a SDict begin H.S end 479 222 a 479 222 a SDict begin 13 H.A end 479 222 a 479 222 a SDict begin [/View [/XYZ H.V]/Dest (0:45) cvn /DEST pdfmark end 479 222 a Fj(Feature-complete,)g(full)i(implementations)e(of:)i(Gopher0)e (\(RFC1435\),)h(Gopher+,)f(HTTP)-9 b(,)20 b(and)g(W)-10 b(AP)h(.)-2 240 y SDict begin H.S end -2 240 a -2 240 a SDict begin 13 H.A end -2 240 a -2 240 a SDict begin [/View [/XYZ H.V]/Dest (0:46) cvn /DEST pdfmark end -2 240 a Black 396 371 a Fg(\225)p Black 479 371 a SDict begin H.S end 479 371 a 479 371 a SDict begin 13 H.A end 479 371 a 479 371 a SDict begin [/View [/XYZ H.V]/Dest (0:47) cvn /DEST pdfmark end 479 371 a Fj(Support)19 b(for)h(automatically)e(\002nding)h(the)h(titles)i(of)e(HTML)g (documents)e(for)i(presentation)e(in)j(a)f(directory)-5 b(.)-2 389 y SDict begin H.S end -2 389 a -2 389 a SDict begin 13 H.A end -2 389 a -2 389 a SDict begin [/View [/XYZ H.V]/Dest (0:48) cvn /DEST pdfmark end -2 389 a Black 396 521 a Fg(\225)p Black 479 521 a SDict begin H.S end 479 521 a 479 521 a SDict begin 13 H.A end 479 521 a 479 521 a SDict begin [/View [/XYZ H.V]/Dest (0:49) cvn /DEST pdfmark end 479 521 a Fj(V)c(ersatile)21 b(con\002guration)c(\002le)k(format)e(is)i(both)e(e)o(xtensible)h(and)f (nicely)h(complementary)d(of)j(the)g(module)f(system.)-2 539 y SDict begin H.S end -2 539 a -2 539 a SDict begin 13 H.A end -2 539 a -2 539 a SDict begin [/View [/XYZ H.V]/Dest (0:50) cvn /DEST pdfmark end -2 539 a Black 396 670 a Fg(\225)p Black 479 670 a SDict begin H.S end 479 670 a 479 670 a SDict begin 13 H.A end 479 670 a 479 670 a SDict begin [/View [/XYZ H.V]/Dest (0:51) cvn /DEST pdfmark end 479 670 a Fj(Protocol-independent,)d(handler)n (-dependent)g(caching.)i(This)j(increases)f(performance)d(by)j(letting) g(handlers)479 778 y(cache)g(dynamically-generated)c(information)h(--)j (currently)f(used)h(by)g(the)g(directory)e(handlers.)h(This)h(can)479 886 y(impro)o(v)o(e)e(performance)g(of)h(directories)h(by)f(se)n(v)o (eral)h(orders)f(of)h(magnitude.)e(Because)i(this)h(is)g(a)g(handler)e (cache)479 994 y(only)-5 b(,)19 b(all)i(protocols)e(share)g(the)i (single)f(cache.)f(Since)h(the)h(processing)e(time)h(for)f(the)i (protocols)d(is)k(ne)o(gligible,)c(this)479 1102 y(w)o(orks)i(out)g(v)o (ery)f(well.)-2 1120 y SDict begin H.S end -2 1120 a -2 1120 a SDict begin 13 H.A end -2 1120 a -2 1120 a SDict begin [/View [/XYZ H.V]/Dest (0:52) cvn /DEST pdfmark end -2 1120 a Black 396 1251 a Fg(\225)p Black 479 1251 a SDict begin H.S end 479 1251 a 479 1251 a SDict begin 13 H.A end 479 1251 a 479 1251 a SDict begin [/View [/XYZ H.V]/Dest (0:53) cvn /DEST pdfmark end 479 1251 a Fj(Autosensing)g(of)h(MIME)g(types)g(and)f(gopher0)f(item) j(types.)e(Both)i(are)f(completely)e(con\002gurable.)g(MIME)i(type)479 1359 y(detection)f(is)j(done)d(using)g(a)i(standard)e(mime.types)g (\002le,)h(and)g(gopher0)e(types)i(are)g(calculated)f(by)h(using)g(a) 479 1467 y(con\002gurable)e(re)o(ge)o(xp-based)f(MIME-to-gophertype)e (map.)-2 1485 y SDict begin H.S end -2 1485 a -2 1485 a SDict begin 13 H.A end -2 1485 a -2 1485 a SDict begin [/View [/XYZ H.V]/Dest (0:54) cvn /DEST pdfmark end -2 1485 a Black 396 1617 a Fg(\225)p Black 479 1617 a SDict begin H.S end 479 1617 a 479 1617 a SDict begin 13 H.A end 479 1617 a 479 1617 a SDict begin [/View [/XYZ H.V]/Dest (0:55) cvn /DEST pdfmark end 479 1617 a Fj(Hea)n(vy)20 b(support)f(of)h(re)o(gular)e(e)o(xpressions)h(in)i (con\002guration.)-2 1635 y SDict begin H.S end -2 1635 a -2 1635 a SDict begin 13 H.A end -2 1635 a -2 1635 a SDict begin [/View [/XYZ H.V]/Dest (0:56) cvn /DEST pdfmark end -2 1635 a Black 396 1766 a Fg(\225)p Black 479 1766 a SDict begin H.S end 479 1766 a 479 1766 a SDict begin 13 H.A end 479 1766 a 479 1766 a SDict begin [/View [/XYZ H.V]/Dest (0:57) cvn /DEST pdfmark end 479 1766 a Fj(ProtocolMultiple)o(x)o(er)c(and)j(HandlerMultiple)o(x)o (er)c(let)21 b(you)e(choose)h(only)f(those)h(protocols)f(and)g (handlers)g(that)479 1874 y(you)h(wish)g(your)f(serv)o(er)g(to)i (support)e(and)g(the)h(order)f(in)i(which)e(the)o(y)h(are)g(tried)g (when)f(a)i(request)f(comes)f(in.)-2 1892 y SDict begin H.S end -2 1892 a -2 1892 a SDict begin 13 H.A end -2 1892 a -2 1892 a SDict begin [/View [/XYZ H.V]/Dest (0:58) cvn /DEST pdfmark end -2 1892 a Black 396 2023 a Fg(\225)p Black 479 2023 a SDict begin H.S end 479 2023 a 479 2023 a SDict begin 13 H.A end 479 2023 a 479 2023 a SDict begin [/View [/XYZ H.V]/Dest (0:59) cvn /DEST pdfmark end 479 2023 a Fj(Full)i(logging)d(via)j(syslog.)-2 2083 y SDict begin H.S end -2 2083 a -2 2083 a SDict begin 13 H.A end -2 2083 a -2 2083 a SDict begin [/View [/XYZ H.V]/Dest (0:ABOUTGOPHER) cvn /DEST pdfmark end -2 2083 a 359 x Fh(1.2.)39 b(About)f(Gopher)1243 2442 y SDict begin H.S end 1243 2442 a 1243 2442 a SDict begin 22.464 H.A end 1243 2442 a 1243 2442 a SDict begin [/View [/XYZ H.V]/Dest (3.2.1) cvn /DEST pdfmark end 1243 2442 a -2 2638 a SDict begin H.S end -2 2638 a -2 2638 a SDict begin 13 H.A end -2 2638 a -2 2638 a SDict begin [/View [/XYZ H.V]/Dest (0:62) cvn /DEST pdfmark end -2 2638 a -2 2638 a SDict begin H.S end -2 2638 a -2 2638 a SDict begin 13 H.A end -2 2638 a -2 2638 a SDict begin [/View [/XYZ H.V]/Dest (0:63) cvn /DEST pdfmark end -2 2638 a 396 2716 a Fj(PyGopherd)18 b(started)i(life)h(as)g(a)f (serv)o(er)g(for)f(the)h(Gopher)f(Internet)g(protocol.)f(W)m(ith)j (Gopher)m(,)d(you)h(can)h(mount)f(a)396 2824 y(\002lesystem)i(\(vie)n (wing)e(\002les)i(and)e(folders)h(as)h(if)f(the)o(y)g(were)g(local\),)f (bro)n(wse)h(Gopherspace)e(with)i(a)h(web)f(bro)n(wser)m(,)396 2932 y(do)n(wnload)e(\002les,)j(and)f(be)g(interacti)n(v)o(e)f(with)h (searching.)-2 3116 y SDict begin H.S end -2 3116 a -2 3116 a SDict begin 13 H.A end -2 3116 a -2 3116 a SDict begin [/View [/XYZ H.V]/Dest (0:64) cvn /DEST pdfmark end -2 3116 a 396 3206 a Fj(But)h(this)g(is)g(only)e(part)h(of)g (the)g(story)-5 b(.)19 b(The)h(w)o(orld)g(of)g(Gopher)e(is)k(more)d(e)o (xpansi)n(v)o(e)f(than)i(this.)g(There)g(are)g(tw)o(o)g(major)396 3314 y(gopher)f(protocols:)f(Gopher0)h(\(also)h(kno)n(wn)e(as)j (RFC1436\))f(and)f(Gopher+.)g(Gopher0)f(is)j(a)g(small,)f(simple,)396 3422 y(lightweight)f(protocol)g(that)h(is)h(v)o(ery)e(functional)g(yet) h(also)g(e)o(xtremely)f(easy)h(to)g(implement.)f(Gopher0)f(clients)j (can)f(be)396 3530 y(easily)h(placed)e(in)h(small)h(embedded)d(de)n (vices)i(or)g(in)g(massi)n(v)o(e)g(en)m(vironments)d(lik)o(e)k(a)f (modern)f(web)h(bro)n(wser)-5 b(.)-2 3714 y SDict begin H.S end -2 3714 a -2 3714 a SDict begin 13 H.A end -2 3714 a -2 3714 a SDict begin [/View [/XYZ H.V]/Dest (0:65) cvn /DEST pdfmark end -2 3714 a 396 3804 a Fj(Gopher+)19 b(is)i(based)f(on)g(Gopher0)e(b)n(ut)i(e)o(xtends)f(it)i(by)f(pro)o (viding)d(document)h(metadata)i(such)g(as)h(\002le)g(size)f(and)396 3912 y(MIME)g(type.)f(Gopher+)f(allo)n(ws)i(all)h(sorts)f(of)f(neat)h (features,)f(such)h(as)g(con\002gurable)e(metadata)h(\(serving)f(up)i (a)g(b)n(unch)396 4020 y(of)g(photos?)f(Add)h(a)h(Subject)e(\002eld)i (to)f(your)f(metadata)g(to)i(let)g(a)f(customized)f(photo)g(bro)n(wser) g(display)h(who)f(is)396 4127 y(pictured\))g(and)g(multiple)h(vie)n(ws) g(of)g(a)h(\002le)g(\(let)f(the)g(user)g(select)h(to)f(vie)n(w)h(your)e (photos)g(as)i(PNG)f(or)g(JPEG\).)p Black 3842 5569 a Fi(2)p Black eop end %%Page: 3 6 TeXDict begin 3 5 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.3) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:QUICKSTART) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(2.)f(Quic)m(k)g(Star)s(t)1805 115 y SDict begin H.S end 1805 115 a 1805 115 a SDict begin 26.957 H.A end 1805 115 a 1805 115 a SDict begin [/View [/XYZ H.V]/Dest (4.0) cvn /DEST pdfmark end 1805 115 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:68) cvn /DEST pdfmark end -2 371 a 396 443 a Fj(If)20 b(you)g(ha)n(v)o(e)f(already)g(installed)1359 443 y SDict begin H.S end 1359 443 a 1359 443 a SDict begin 13 H.A end 1359 443 a 1359 443 a SDict begin [/View [/XYZ H.V]/Dest (0:69) cvn /DEST pdfmark end 1359 443 a Fj(PyGopherd)f (system-wide,)h(or)h(your)f(administrator)g(has)h(done)f(that)i(for)e (you,)g(your)396 551 y(task)i(for)e(setting)h(up)1013 551 y SDict begin H.S end 1013 551 a 1013 551 a SDict begin 13 H.A end 1013 551 a 1013 551 a SDict begin [/View [/XYZ H.V]/Dest (0:70) cvn /DEST pdfmark end 1013 551 a Fj(PyGopherd)e(for)h(the)h(\002rst)h(time)f(is)h(quite)f(simple.) f(Y)-9 b(ou)20 b(just)g(need)f(to)h(set)h(up)f(your)e(con\002guration) 396 659 y(\002le,)j(mak)o(e)f(your)f(folder)g(directory)-5 b(,)17 b(and)j(run)f(it!)-2 843 y SDict begin H.S end -2 843 a -2 843 a SDict begin 13 H.A end -2 843 a -2 843 a SDict begin [/View [/XYZ H.V]/Dest (0:71) cvn /DEST pdfmark end -2 843 a 396 933 a Fj(Y)-9 b(ou)20 b(can)g(quickly)f (set)i(up)e(your)g(con\002guration)f(\002le.)i(The)g(distrib)n(ution)f (includes)h(tw)o(o)g(\002les)h(of)f(interest:)396 1041 y SDict begin H.S end 396 1041 a 396 1041 a SDict begin 13 H.A end 396 1041 a 396 1041 a SDict begin [/View [/XYZ H.V]/Dest (0:72) cvn /DEST pdfmark end 396 1041 a Fe(conf/pygopherd.conf)e Fj(and)1409 1041 y SDict begin H.S end 1409 1041 a 1409 1041 a SDict begin 13 H.A end 1409 1041 a 1409 1041 a SDict begin [/View [/XYZ H.V]/Dest (0:73) cvn /DEST pdfmark end 1409 1041 a Fe(conf/mime.types)p Fj(.)g(Debian)i(users)g(will)h(\002nd)f(the)g(con\002guration)e(\002le) 396 1149 y(pre-installed)h(in)917 1149 y SDict begin H.S end 917 1149 a 917 1149 a SDict begin 13 H.A end 917 1149 a 917 1149 a SDict begin [/View [/XYZ H.V]/Dest (0:74) cvn /DEST pdfmark end 917 1149 a Fe (/etc/pygopherd/pygopherd.conf)d Fj(and)k(the)2501 1149 y SDict begin H.S end 2501 1149 a 2501 1149 a SDict begin 13 H.A end 2501 1149 a 2501 1149 a SDict begin [/View [/XYZ H.V]/Dest (0:75) cvn /DEST pdfmark end 2501 1149 a Fe(mime.types)f Fj(\002le)i(pro)o(vided)d(by)h(the)i(system)396 1256 y(already)-5 b(.)-2 1440 y SDict begin H.S end -2 1440 a -2 1440 a SDict begin 13 H.A end -2 1440 a -2 1440 a SDict begin [/View [/XYZ H.V]/Dest (0:76) cvn /DEST pdfmark end -2 1440 a 396 1530 a Fj(Open)20 b(up)701 1530 y SDict begin H.S end 701 1530 a 701 1530 a SDict begin 13 H.A end 701 1530 a 701 1530 a SDict begin [/View [/XYZ H.V]/Dest (0:77) cvn /DEST pdfmark end 701 1530 a Fe(pygopherd.conf)e Fj(in)i(your)f(editor)h(and)f(adjust)h(to)h (suit.)f(The)g(\002le)h(is)g(hea)n(vily)f(commented)e(and)h(you)h(can) 396 1638 y(refer)g(to)g(it)h(for)e(detailed)h(information.)e(Some)i (settings)g(to)g(tak)o(e)h(a)f(look)g(at)g(include:)2883 1638 y SDict begin H.S end 2883 1638 a 2883 1638 a SDict begin 13 H.A end 2883 1638 a 2883 1638 a SDict begin [/View [/XYZ H.V]/Dest (0:78) cvn /DEST pdfmark end 2883 1638 a Fj(detach,)3142 1638 y SDict begin H.S end 3142 1638 a 3142 1638 a SDict begin 13 H.A end 3142 1638 a 3142 1638 a SDict begin [/View [/XYZ H.V]/Dest (0:79) cvn /DEST pdfmark end 3142 1638 a Fj(pid\002le,)3395 1638 y SDict begin H.S end 3395 1638 a 3395 1638 a SDict begin 13 H.A end 3395 1638 a 3395 1638 a SDict begin [/View [/XYZ H.V]/Dest (0:80) cvn /DEST pdfmark end 3395 1638 a Fj(port,)396 1746 y SDict begin H.S end 396 1746 a 396 1746 a SDict begin 13 H.A end 396 1746 a 396 1746 a SDict begin [/View [/XYZ H.V]/Dest (0:81) cvn /DEST pdfmark end 396 1746 a Fj(usechroot,)761 1746 y SDict begin H.S end 761 1746 a 761 1746 a SDict begin 13 H.A end 761 1746 a 761 1746 a SDict begin [/View [/XYZ H.V]/Dest (0:82) cvn /DEST pdfmark end 761 1746 a Fj(setuid,)1000 1746 y SDict begin H.S end 1000 1746 a 1000 1746 a SDict begin 13 H.A end 1000 1746 a 1000 1746 a SDict begin [/View [/XYZ H.V]/Dest (0:83) cvn /DEST pdfmark end 1000 1746 a Fj(setgid,)g(and)1381 1746 y SDict begin H.S end 1381 1746 a 1381 1746 a SDict begin 13 H.A end 1381 1746 a 1381 1746 a SDict begin [/View [/XYZ H.V]/Dest (0:84) cvn /DEST pdfmark end 1381 1746 a Fj(root.)f(These)h(may)g(or)g(may)g(not)f(w)o(ork)h(at)h (their)f(def)o(aults)f(for)h(you.)f(The)h(remaining)396 1854 y(ones)g(should)f(be)h(\002ne)h(for)e(a)i(basic)f(setup.)-2 2038 y SDict begin H.S end -2 2038 a -2 2038 a SDict begin 13 H.A end -2 2038 a -2 2038 a SDict begin [/View [/XYZ H.V]/Dest (0:85) cvn /DEST pdfmark end -2 2038 a 396 2128 a Fj(In)m(v)n(ok)o(e)641 2128 y SDict begin H.S end 641 2128 a 641 2128 a SDict begin 13 H.A end 641 2128 a 641 2128 a SDict begin [/View [/XYZ H.V]/Dest (0:86) cvn /DEST pdfmark end 641 2128 a Fj(PyGopherd)e(with)1208 2128 y SDict begin H.S end 1208 2128 a 1208 2128 a SDict begin 13 H.A end 1208 2128 a 1208 2128 a SDict begin [/View [/XYZ H.V]/Dest (0:87) cvn /DEST pdfmark end 1208 2128 a Fk(pygopherd)h(path/to/con\002g\002le)g Fj(\(or)2344 2128 y SDict begin H.S end 2344 2128 a 2344 2128 a SDict begin 13 H.A end 2344 2128 a 2344 2128 a SDict begin [/View [/XYZ H.V]/Dest (0:88) cvn /DEST pdfmark end 2344 2128 a Fk(/etc/init.d/pygopherd)g(start)g Fj(on)h(Debian\).)e(Place)396 2236 y(some)i(\002les)h(in)g(the)f (location)f(speci\002ed)h(by)g(the)1789 2236 y SDict begin H.S end 1789 2236 a 1789 2236 a SDict begin 13 H.A end 1789 2236 a 1789 2236 a SDict begin [/View [/XYZ H.V]/Dest (0:89) cvn /DEST pdfmark end 1789 2236 a Fj(root)g(directi)n (v)o(e)f(in)h(the)g(con\002g)f(\002le)i(and)f(you')l(re)e(ready)h(to)i (run!)p Black 3842 5569 a Fi(3)p Black eop end %%Page: 4 7 TeXDict begin 4 6 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.4) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:INSTALLATION) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(3.)f(Installation)1796 115 y SDict begin H.S end 1796 115 a 1796 115 a SDict begin 26.957 H.A end 1796 115 a 1796 115 a SDict begin [/View [/XYZ H.V]/Dest (5.0) cvn /DEST pdfmark end 1796 115 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:92) cvn /DEST pdfmark end -2 371 a 396 443 a Fj(If)20 b(you)g(are)g (reading)e(this)j(document)d(via)j(the)f("man")f(command,)f(it)j(is)g (lik)o(ely)f(that)h(you)e(ha)n(v)o(e)g(no)h(installation)g(tasks)396 551 y(to)h(perform;)d(your)h(system)h(administrator)f(has)h(already)f (installed)2379 551 y SDict begin H.S end 2379 551 a 2379 551 a SDict begin 13 H.A end 2379 551 a 2379 551 a SDict begin [/View [/XYZ H.V]/Dest (0:93) cvn /DEST pdfmark end 2379 551 a Fj(PyGopherd.)f(If)i(you)f(need)h(to)g(install) h(it)g(yourself,)396 659 y(you)f(ha)n(v)o(e)f(three)h(options:)f(a)i (system-wide)e(installation)h(with)g(Debian,)g(system-wide)f (installation)h(with)g(other)396 767 y(systems,)h(and)e(a)i (single-user)e(installation.)h(Y)-9 b(ou)19 b(can)h(do)n(wnload)e(the)i (latest)h(v)o(ersion)e(of)h(PyGopherd)e(from)396 875 y SDict begin H.S end 396 875 a 396 875 a SDict begin 13 H.A end 396 875 a 396 875 a SDict begin [/View [/XYZ H.V]/Dest (0:94) cvn /DEST pdfmark end 396 875 a Fj(https://github)m (.com/michael-lazar/p)o(yg)o(op)o(her)o(d)-2 893 y SDict begin H.S end -2 893 a -2 893 a SDict begin 13 H.A end -2 893 a -2 893 a SDict begin [/View [/XYZ H.V]/Dest (0:INSTALLATION.DEBIAN) cvn /DEST pdfmark end -2 893 a 359 x Fh(3.1.)39 b(Debian)f(System-Wide)g(Installation)2496 1252 y SDict begin H.S end 2496 1252 a 2496 1252 a SDict begin 22.464 H.A end 2496 1252 a 2496 1252 a SDict begin [/View [/XYZ H.V]/Dest (5.3.1) cvn /DEST pdfmark end 2496 1252 a -2 1447 a SDict begin H.S end -2 1447 a -2 1447 a SDict begin 13 H.A end -2 1447 a -2 1447 a SDict begin [/View [/XYZ H.V]/Dest (0:97) cvn /DEST pdfmark end -2 1447 a 396 1526 a Fj(Y)-9 b(ou)20 b(may)g(install)938 1526 y SDict begin H.S end 938 1526 a 938 1526 a SDict begin 13 H.A end 938 1526 a 938 1526 a SDict begin [/View [/XYZ H.V]/Dest (0:98) cvn /DEST pdfmark end 938 1526 a Fj(PyGopherd)e(by)i(simply)g(running)e(this)j(command)d(as)j (root:)-2 1710 y SDict begin H.S end -2 1710 a -2 1710 a SDict begin 13 H.A end -2 1710 a -2 1710 a SDict begin [/View [/XYZ H.V]/Dest (0:99) cvn /DEST pdfmark end -2 1710 a -2 1710 a SDict begin H.S end -2 1710 a -2 1710 a SDict begin 13 H.A end -2 1710 a -2 1710 a SDict begin [/View [/XYZ H.V]/Dest (0:100) cvn /DEST pdfmark end -2 1710 a 396 1800 a Fk(apt-get)e(install)i(pygopherd)-2 1827 y SDict begin H.S end -2 1827 a -2 1827 a SDict begin 13 H.A end -2 1827 a -2 1827 a SDict begin [/View [/XYZ H.V]/Dest (0:INSTALLATION.OTHER) cvn /DEST pdfmark end -2 1827 a 360 x Fh(3.2.)39 b(Other)f(System-Wide)g(Installation)2400 2187 y SDict begin H.S end 2400 2187 a 2400 2187 a SDict begin 22.464 H.A end 2400 2187 a 2400 2187 a SDict begin [/View [/XYZ H.V]/Dest (5.4.1) cvn /DEST pdfmark end 2400 2187 a -2 2383 a SDict begin H.S end -2 2383 a -2 2383 a SDict begin 13 H.A end -2 2383 a -2 2383 a SDict begin [/View [/XYZ H.V]/Dest (0:103) cvn /DEST pdfmark end -2 2383 a 396 2461 a Fj(Do)n(wnload)19 b(the)h(tar)-5 b(.gz)20 b(v)o(ersion)f(of)h(the)g(package)f(from)g(the)h(website.)g (Mak)o(e)g(sure)g(you)g(ha)n(v)o(e)f(Python)g(3.7)h(or)g(abo)o(v)o(e) 396 2569 y(installed;)g(if)h(not,)f(do)n(wnload)e(and)h(install)i(it)g (from)1900 2569 y SDict begin H.S end 1900 2569 a 1900 2569 a SDict begin 13 H.A end 1900 2569 a 1900 2569 a SDict begin [/View [/XYZ H.V]/Dest (0:104) cvn /DEST pdfmark end 1900 2569 a Fj(http://www)-5 b(.p)o(ython.or)o(g/.)15 b(Then)k(run)h(these)g(commands:)-2 2670 y SDict begin H.S end -2 2670 a -2 2670 a SDict begin 11.7 H.A end -2 2670 a -2 2670 a SDict begin [/View [/XYZ H.V]/Dest (0:105) cvn /DEST pdfmark end -2 2670 a 665 2749 a SDict begin H.S end 665 2749 a 665 2749 a SDict begin 11.7 H.A end 665 2749 a 665 2749 a SDict begin [/View [/XYZ H.V]/Dest (0:106) cvn /DEST pdfmark end 665 2749 a Fd(tar)45 b(-zxvf)f(pygopherd-x.y.z.tar.gz)665 2846 y SDict begin H.S end 665 2846 a 665 2846 a SDict begin 11.7 H.A end 665 2846 a 665 2846 a SDict begin [/View [/XYZ H.V]/Dest (0:107) cvn /DEST pdfmark end 665 2846 a Fd(cd)h(pygopherd-x.y.z) 665 2943 y SDict begin H.S end 665 2943 a 665 2943 a SDict begin 11.7 H.A end 665 2943 a 665 2943 a SDict begin [/View [/XYZ H.V]/Dest (0:108) cvn /DEST pdfmark end 665 2943 a Fd(python3)f(setup.py)-2 3207 y SDict begin H.S end -2 3207 a -2 3207 a SDict begin 13 H.A end -2 3207 a -2 3207 a SDict begin [/View [/XYZ H.V]/Dest (0:109) cvn /DEST pdfmark end -2 3207 a 396 3315 a Fj(Ne)o(xt,)20 b(proceed)e(to)j(con\002guration.)c(Mak)o(e)j(sure)g (that)g(the)2087 3315 y SDict begin H.S end 2087 3315 a 2087 3315 a SDict begin 13 H.A end 2087 3315 a 2087 3315 a SDict begin [/View [/XYZ H.V]/Dest (0:110) cvn /DEST pdfmark end 2087 3315 a Fe(/etc/pygopherd/pygopherd.conf)15 b Fj(\002le)21 b(names)396 3422 y(v)n(alid)f(users)g(\()800 3422 y SDict begin H.S end 800 3422 a 800 3422 a SDict begin 13 H.A end 800 3422 a 800 3422 a SDict begin [/View [/XYZ H.V]/Dest (0:111) cvn /DEST pdfmark end 800 3422 a Fj(setuid)g(and)1160 3422 y SDict begin H.S end 1160 3422 a 1160 3422 a SDict begin 13 H.A end 1160 3422 a 1160 3422 a SDict begin [/View [/XYZ H.V]/Dest (0:112) cvn /DEST pdfmark end 1160 3422 a Fj(setgid)g(options\))f(and)g(a)i (v)n(alid)f(document)e(root)h(\()2585 3422 y SDict begin H.S end 2585 3422 a 2585 3422 a SDict begin 13 H.A end 2585 3422 a 2585 3422 a SDict begin [/View [/XYZ H.V]/Dest (0:113) cvn /DEST pdfmark end 2585 3422 a Fj(root)h(option\).) -2 3606 y SDict begin H.S end -2 3606 a -2 3606 a SDict begin 13 H.A end -2 3606 a -2 3606 a SDict begin [/View [/XYZ H.V]/Dest (0:114) cvn /DEST pdfmark end -2 3606 a 396 3696 a Fj(Y)-9 b(ou)20 b(will)h(type)865 3696 y SDict begin H.S end 865 3696 a 865 3696 a SDict begin 13 H.A end 865 3696 a 865 3696 a SDict begin [/View [/XYZ H.V]/Dest (0:115) cvn /DEST pdfmark end 865 3696 a Fe(pygopherd)e Fj(to)h(in)m(v)n(ok)o(e)f(the)h(program.)-2 3725 y SDict begin H.S end -2 3725 a -2 3725 a SDict begin 13 H.A end -2 3725 a -2 3725 a SDict begin [/View [/XYZ H.V]/Dest (0:INSTALLATION.SINGLE) cvn /DEST pdfmark end -2 3725 a 359 x Fh(3.3.)39 b(Single-Account)d(Installation)2129 4084 y SDict begin H.S end 2129 4084 a 2129 4084 a SDict begin 22.464 H.A end 2129 4084 a 2129 4084 a SDict begin [/View [/XYZ H.V]/Dest (5.5.1) cvn /DEST pdfmark end 2129 4084 a -2 4282 a SDict begin H.S end -2 4282 a -2 4282 a SDict begin 13 H.A end -2 4282 a -2 4282 a SDict begin [/View [/XYZ H.V]/Dest (0:118) cvn /DEST pdfmark end -2 4282 a 396 4358 a Fj(Do)n(wnload)19 b(the)h(tar)-5 b(.gz)20 b(v)o(ersion)f(of)h(the)g(package)f(from)g(the)h(website.)g (Mak)o(e)g(sure)g(you)g(ha)n(v)o(e)f(Python)g(2.2)h(or)g(abo)o(v)o(e) 396 4466 y(installed;)g(if)h(no)n(w)-5 b(,)19 b(do)n(wnload)f(and)i (install)g(it)h(from)1929 4466 y SDict begin H.S end 1929 4466 a 1929 4466 a SDict begin 13 H.A end 1929 4466 a 1929 4466 a SDict begin [/View [/XYZ H.V]/Dest (0:119) cvn /DEST pdfmark end 1929 4466 a Fj(http://www)-5 b(.p)o(ython.or)o(g/.)15 b(Then)20 b(run)f(these)i(commands:)-2 4567 y SDict begin H.S end -2 4567 a -2 4567 a SDict begin 11.7 H.A end -2 4567 a -2 4567 a SDict begin [/View [/XYZ H.V]/Dest (0:120) cvn /DEST pdfmark end -2 4567 a 665 4646 a SDict begin H.S end 665 4646 a 665 4646 a SDict begin 11.7 H.A end 665 4646 a 665 4646 a SDict begin [/View [/XYZ H.V]/Dest (0:121) cvn /DEST pdfmark end 665 4646 a Fd(tar)45 b(-zxvf)f(pygopherd-z.y.z.tar.gz)665 4743 y SDict begin H.S end 665 4743 a 665 4743 a SDict begin 11.7 H.A end 665 4743 a 665 4743 a SDict begin [/View [/XYZ H.V]/Dest (0:122) cvn /DEST pdfmark end 665 4743 a Fd(cd)h(pygopherd-x.y.z)-2 5006 y SDict begin H.S end -2 5006 a -2 5006 a SDict begin 13 H.A end -2 5006 a -2 5006 a SDict begin [/View [/XYZ H.V]/Dest (0:123) cvn /DEST pdfmark end -2 5006 a 396 5114 a Fj(Modify)666 5114 y SDict begin H.S end 666 5114 a 666 5114 a SDict begin 13 H.A end 666 5114 a 666 5114 a SDict begin [/View [/XYZ H.V]/Dest (0:124) cvn /DEST pdfmark end 666 5114 a Fe(conf/pygopherd.conf)18 b Fj(as)j(follo)n(ws:)-2 5132 y SDict begin H.S end -2 5132 a -2 5132 a SDict begin 13 H.A end -2 5132 a -2 5132 a SDict begin [/View [/XYZ H.V]/Dest (0:125) cvn /DEST pdfmark end -2 5132 a -2 5142 a SDict begin H.S end -2 5142 a -2 5142 a SDict begin 13 H.A end -2 5142 a -2 5142 a SDict begin [/View [/XYZ H.V]/Dest (0:126) cvn /DEST pdfmark end -2 5142 a Black 3842 5569 a Fi(4)p Black eop end %%Page: 5 8 TeXDict begin 5 7 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.5) cvn /DEST pdfmark end -611 -810 a Black Black 3124 -132 a Fi(Chapter)20 b(3.)g(Installation)p Black Black 396 72 a Fg(\225)p Black 479 72 a SDict begin H.S end 479 72 a 479 72 a SDict begin 13 H.A end 479 72 a 479 72 a SDict begin [/View [/XYZ H.V]/Dest (0:127) cvn /DEST pdfmark end 479 72 a Fj(Set)606 72 y SDict begin H.S end 606 72 a 606 72 a SDict begin 13 H.A end 606 72 a 606 72 a SDict begin [/View [/XYZ H.V]/Dest (0:128) cvn /DEST pdfmark end 606 72 a Fj(usechroot)f(=)h(no)-2 73 y SDict begin H.S end -2 73 a -2 73 a SDict begin 13 H.A end -2 73 a -2 73 a SDict begin [/View [/XYZ H.V]/Dest (0:129) cvn /DEST pdfmark end -2 73 a Black 396 222 a Fg(\225)p Black 479 222 a SDict begin H.S end 479 222 a 479 222 a SDict begin 13 H.A end 479 222 a 479 222 a SDict begin [/View [/XYZ H.V]/Dest (0:130) cvn /DEST pdfmark end 479 222 a Fj(Set)606 222 y SDict begin H.S end 606 222 a 606 222 a SDict begin 13 H.A end 606 222 a 606 222 a SDict begin [/View [/XYZ H.V]/Dest (0:131) cvn /DEST pdfmark end 606 222 a Fj(root)g(to)g(something)f(appropriate.)-2 240 y SDict begin H.S end -2 240 a -2 240 a SDict begin 13 H.A end -2 240 a -2 240 a SDict begin [/View [/XYZ H.V]/Dest (0:132) cvn /DEST pdfmark end -2 240 a Black 396 371 a Fg(\225)p Black 479 371 a SDict begin H.S end 479 371 a 479 371 a SDict begin 13 H.A end 479 371 a 479 371 a SDict begin [/View [/XYZ H.V]/Dest (0:133) cvn /DEST pdfmark end 479 371 a Fj(Set)606 371 y SDict begin H.S end 606 371 a 606 371 a SDict begin 13 H.A end 606 371 a 606 371 a SDict begin [/View [/XYZ H.V]/Dest (0:134) cvn /DEST pdfmark end 606 371 a Fj(port)h(to)g(a)h (number)d(greater)h(than)h(1024.)-2 555 y SDict begin H.S end -2 555 a -2 555 a SDict begin 13 H.A end -2 555 a -2 555 a SDict begin [/View [/XYZ H.V]/Dest (0:135) cvn /DEST pdfmark end -2 555 a 396 645 a Fj(When)g(you)g(w)o(ant)g (to)g(run)1159 645 y SDict begin H.S end 1159 645 a 1159 645 a SDict begin 13 H.A end 1159 645 a 1159 645 a SDict begin [/View [/XYZ H.V]/Dest (0:136) cvn /DEST pdfmark end 1159 645 a Fj(PyGopherd,)d(you)j(will)h(issue)f(the)2183 645 y SDict begin H.S end 2183 645 a 2183 645 a SDict begin 13 H.A end 2183 645 a 2183 645 a SDict begin [/View [/XYZ H.V]/Dest (0:137) cvn /DEST pdfmark end 2183 645 a Fk(cd)g Fj(command)f(as)h(abo)o(v)o(e)f(and)h(then)f(type)396 753 y SDict begin H.S end 396 753 a 396 753 a SDict begin 13 H.A end 396 753 a 396 753 a SDict begin [/View [/XYZ H.V]/Dest (0:138) cvn /DEST pdfmark end 396 753 a Fk(PYTHONP)-6 b(A)e(TH=.)20 b(bin/pygopherd)p Fj(.)g(There)f(is)i(no) f(installation)g(step)g(necessary)-5 b(.)p Black 3842 5569 a Fi(5)p Black eop end %%Page: 6 9 TeXDict begin 6 8 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.6) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:CONFIGURATION) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(4.)f(Con\002guration)2014 115 y SDict begin H.S end 2014 115 a 2014 115 a SDict begin 26.957 H.A end 2014 115 a 2014 115 a SDict begin [/View [/XYZ H.V]/Dest (6.0) cvn /DEST pdfmark end 2014 115 a -2 373 a SDict begin H.S end -2 373 a -2 373 a SDict begin 13 H.A end -2 373 a -2 373 a SDict begin [/View [/XYZ H.V]/Dest (0:141) cvn /DEST pdfmark end -2 373 a -2 373 a SDict begin H.S end -2 373 a -2 373 a SDict begin 13 H.A end -2 373 a -2 373 a SDict begin [/View [/XYZ H.V]/Dest (0:142) cvn /DEST pdfmark end -2 373 a 396 443 a Fj(PyGopherd)18 b(is)j(re)o(gulated)e(by)h(a)g(con\002guration)e(\002le)j(normally)d (stored)i(in)396 551 y SDict begin H.S end 396 551 a 396 551 a SDict begin 13 H.A end 396 551 a 396 551 a SDict begin [/View [/XYZ H.V]/Dest (0:143) cvn /DEST pdfmark end 396 551 a Fe(/etc/pygopherd/pygopherd.conf)p Fj(.)c(Y)-9 b(ou)19 b(can)h(specify)g(an)g(alternate)g(con\002guration) d(\002le)k(on)f(the)g(command)396 659 y(line.)g(The)712 659 y SDict begin H.S end 712 659 a 712 659 a SDict begin 13 H.A end 712 659 a 712 659 a SDict begin [/View [/XYZ H.V]/Dest (0:144) cvn /DEST pdfmark end 712 659 a Fj(PyGopherd)e(distrib)n(ution)h(ships)i(with)f(a)g(sample)2186 659 y SDict begin H.S end 2186 659 a 2186 659 a SDict begin 13 H.A end 2186 659 a 2186 659 a SDict begin [/View [/XYZ H.V]/Dest (0:145) cvn /DEST pdfmark end 2186 659 a Fe(pygopherd.conf)f Fj(\002le)i(that)f(thoroughly)d(documents)396 767 y(the)j(con\002guration)e(\002le)j(options)e(and)h(settings.)p Black 3840 5569 a Fi(6)p Black eop end %%Page: 7 10 TeXDict begin 7 9 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.7) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(5.)f(Handler)m(s)1621 115 y SDict begin H.S end 1621 115 a 1621 115 a SDict begin 26.957 H.A end 1621 115 a 1621 115 a SDict begin [/View [/XYZ H.V]/Dest (7.0) cvn /DEST pdfmark end 1621 115 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:148) cvn /DEST pdfmark end -2 371 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:149) cvn /DEST pdfmark end -2 371 a 396 443 a Fj(PyGopherd)18 b(de\002nes)i(se)n(v)o(eral)g(handlers)f(which)g(are)i(responsible)d (for)i(\002nding)f(data)h(on)g(your)f(serv)o(er)g(and)h(presenting)396 551 y(it)h(to)g(the)f(user)-5 b(.)20 b(The)g(handlers)f(are)h(used)g (to)g(generate)f(things)h(lik)o(e)g(links)h(to)f(other)f(documents)g (and)g(directory)396 659 y(listings.)i(The)o(y)e(are)h(also)g (responsible)f(for)h(serving)f(up)h(re)o(gular)e(\002les)k(and)d(e)n(v) o(en)g(virtual)h(folders.)-2 843 y SDict begin H.S end -2 843 a -2 843 a SDict begin 13 H.A end -2 843 a -2 843 a SDict begin [/View [/XYZ H.V]/Dest (0:150) cvn /DEST pdfmark end -2 843 a 396 933 a Fj(Handlers)g(are)g(speci\002ed)g (with)g(the)1445 933 y SDict begin H.S end 1445 933 a 1445 933 a SDict begin 13 H.A end 1445 933 a 1445 933 a SDict begin [/View [/XYZ H.V]/Dest (0:151) cvn /DEST pdfmark end 1445 933 a Fj(handlers)f(option)g(in)2066 933 y SDict begin H.S end 2066 933 a 2066 933 a SDict begin 13 H.A end 2066 933 a 2066 933 a SDict begin [/View [/XYZ H.V]/Dest (0:152) cvn /DEST pdfmark end 2066 933 a Fe(pygopherd.conf)p Fj(.)f(This)i(option)f(is)i(a)g(list)g(of)f (handlers)f(to)396 1041 y(use.)h(F)o(or)g(each)g(request)g(that)g(arri) n(v)o(es,)1526 1041 y SDict begin H.S end 1526 1041 a 1526 1041 a SDict begin 13 H.A end 1526 1041 a 1526 1041 a SDict begin [/View [/XYZ H.V]/Dest (0:153) cvn /DEST pdfmark end 1526 1041 a Fj(PyGopherd)e(will)j(ask)f(each)g(handler)f (in)h(turn)g(whether)f(or)h(not)g(it)h(can)f(handle)396 1149 y(the)g(request,)g(and)f(will)i(handle)e(the)i(request)e (according)f(to)j(the)f(\002rst)h(handler)d(that)j(is)g(capable)e(of)h (doing)f(so.)h(If)g(no)396 1256 y(handlers)f(can)h(handle)f(the)i (request,)e(a)h(\002le)h(not)f(found)f(error)g(is)i(generated.)d(See)j (the)f(e)o(xample)f(con\002guration)e(\002le)k(for)396 1364 y(an)f(e)o(xample.)-2 1548 y SDict begin H.S end -2 1548 a -2 1548 a SDict begin 13 H.A end -2 1548 a -2 1548 a SDict begin [/View [/XYZ H.V]/Dest (0:154) cvn /DEST pdfmark end -2 1548 a 396 1638 a Fj(The)g(remaining)f(parts)h (of)g(this)g(section)g(describe)g(the)g(dif)n(ferent)e(handlers)h(that) i(ship)f(with)3071 1638 y SDict begin H.S end 3071 1638 a 3071 1638 a SDict begin 13 H.A end 3071 1638 a 3071 1638 a SDict begin [/View [/XYZ H.V]/Dest (0:155) cvn /DEST pdfmark end 3071 1638 a Fj(PyGopherd.)-2 1656 y SDict begin H.S end -2 1656 a -2 1656 a SDict begin 13 H.A end -2 1656 a -2 1656 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.DIRHANDLER) cvn /DEST pdfmark end -2 1656 a 359 x Fh(5.1.)39 b(dir)-9 b(.DirHandler)1228 2015 y SDict begin H.S end 1228 2015 a 1228 2015 a SDict begin 22.464 H.A end 1228 2015 a 1228 2015 a SDict begin [/View [/XYZ H.V]/Dest (7.6.1) cvn /DEST pdfmark end 1228 2015 a -2 2183 a SDict begin H.S end -2 2183 a -2 2183 a SDict begin 13 H.A end -2 2183 a -2 2183 a SDict begin [/View [/XYZ H.V]/Dest (0:158) cvn /DEST pdfmark end -2 2183 a 396 2289 a Fj(This)21 b(handler)d(is)j(a)g(basic)f(one)g(that)g (generates)g(menus)f(based)h(on)g(the)g(contents)f(of)h(a)h(directory) -5 b(.)18 b(It)i(is)h(used)f(for)396 2397 y(directories)f(that)i (contain)e(neither)g(a)1487 2397 y SDict begin H.S end 1487 2397 a 1487 2397 a SDict begin 13 H.A end 1487 2397 a 1487 2397 a SDict begin [/View [/XYZ H.V]/Dest (0:159) cvn /DEST pdfmark end 1487 2397 a Fe(gophermap)g Fj(\002le)i(nor)e(UMN-style)h(links)g(\002les,)h(or)f(situations)g (where)g(you)f(ha)n(v)o(e)396 2505 y(no)h(need)g(for)f(either)h(of)g (those.)-2 2672 y SDict begin H.S end -2 2672 a -2 2672 a SDict begin 13 H.A end -2 2672 a -2 2672 a SDict begin [/View [/XYZ H.V]/Dest (0:160) cvn /DEST pdfmark end -2 2672 a 396 2779 a Fj(This)h(handler)d(simply)i(reads)g(the)g (contents)g(of)g(your)f(on-disk)f(directory)-5 b(,)18 b(determines)h(the)i(appropriate)c(types)j(of)396 2887 y(each)g(\002le,)h(and)e(sends)i(the)f(result)g(to)g(the)h(client.)f (The)f(descriptions)g(of)h(each)g(item)h(are)f(usually)f(set)i(to)g (the)f(\002lename,)396 2995 y(b)n(ut)g(the)644 2995 y SDict begin H.S end 644 2995 a 644 2995 a SDict begin 13 H.A end 644 2995 a 644 2995 a SDict begin [/View [/XYZ H.V]/Dest (0:161) cvn /DEST pdfmark end 644 2995 a Fj(html.HTMLFileT)m(itleHandler)d(may)j(o)o(v)o(erride)e(that.)-2 3023 y SDict begin H.S end -2 3023 a -2 3023 a SDict begin 13 H.A end -2 3023 a -2 3023 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.BUCKGOPHERMAP) cvn /DEST pdfmark end -2 3023 a 360 x Fh(5.2.)39 b(gophermap.Buc)m(kGopherma)o(pHa)o(ndl)o(er)2791 3383 y SDict begin H.S end 2791 3383 a 2791 3383 a SDict begin 22.464 H.A end 2791 3383 a 2791 3383 a SDict begin [/View [/XYZ H.V]/Dest (7.7.1) cvn /DEST pdfmark end 2791 3383 a -2 3581 a SDict begin H.S end -2 3581 a -2 3581 a SDict begin 13 H.A end -2 3581 a -2 3581 a SDict begin [/View [/XYZ H.V]/Dest (0:164) cvn /DEST pdfmark end -2 3581 a 396 3657 a Fj(This)21 b(handler)d(is)j(used)f(to)h (generate)e(directory)f(listings)j(based)f(on)2365 3657 y SDict begin H.S end 2365 3657 a 2365 3657 a SDict begin 13 H.A end 2365 3657 a 2365 3657 a SDict begin [/View [/XYZ H.V]/Dest (0:165) cvn /DEST pdfmark end 2365 3657 a Fe(gophermap)g Fj(\002les.)h(It)f(will)h(not)f(read)f(the)396 3765 y(directory)g(on-disk,)f(instead)i(serving)f(content)h(from)f(the) 2098 3765 y SDict begin H.S end 2098 3765 a 2098 3765 a SDict begin 13 H.A end 2098 3765 a 2098 3765 a SDict begin [/View [/XYZ H.V]/Dest (0:166) cvn /DEST pdfmark end 2098 3765 a Fe(gophermap)g Fj(\002le)i(only)-5 b(.)19 b(Gophermaps)f(are)i(useful)g(if)g(you)396 3872 y(w)o(ant)g(to)h(present)e(a)h(directory)f(in)h(which)f(the)h(\002les)h (do)f(not)g(frequently)d(change)i(and)h(there)f(is)i(general)e (information)f(to)396 3980 y(present.)i(Ov)o(erall,)f(if)h(you)g(only)f (wish)i(to)f(present)f(information)f(particular)h(to)h(certain)g (\002les,)h(you)e(should)g(consider)396 4088 y(using)h(the)g(abstract)g (feature)f(of)h(UMN.UMNDirHandler)-5 b(.)-2 4272 y SDict begin H.S end -2 4272 a -2 4272 a SDict begin 13 H.A end -2 4272 a -2 4272 a SDict begin [/View [/XYZ H.V]/Dest (0:167) cvn /DEST pdfmark end -2 4272 a 396 4362 a Fj(The)546 4362 y SDict begin H.S end 546 4362 a 546 4362 a SDict begin 13 H.A end 546 4362 a 546 4362 a SDict begin [/View [/XYZ H.V]/Dest (0:168) cvn /DEST pdfmark end 546 4362 a Fe(gophermap)19 b Fj(\002les)j(contain)d(tw)o(o)h (types)g(of)g(lines,)g(which)g(are)g(described)f(here)h(using)f(the)i (same)f(con)m(v)o(ention)396 4470 y(normally)f(used)h(for)f(command)f (line)j(ar)o(guments.)d(In)i(this)g(section,)g(the)g(symbol)f(\\t)i (will)g(be)f(used)g(to)h(indicate)e(a)i(tab)396 4578 y(character)m(,)e(Control-I.)-2 4590 y SDict begin H.S end -2 4590 a -2 4590 a SDict begin 13 H.A end -2 4590 a -2 4590 a SDict begin [/View [/XYZ H.V]/Dest (0:169) cvn /DEST pdfmark end -2 4590 a -2 4684 a SDict begin H.S end -2 4684 a -2 4684 a SDict begin 13 H.A end -2 4684 a -2 4684 a SDict begin [/View [/XYZ H.V]/Dest (0:170) cvn /DEST pdfmark end -2 4684 a -2 4684 a SDict begin H.S end -2 4684 a -2 4684 a SDict begin 13 H.A end -2 4684 a -2 4684 a SDict begin [/View [/XYZ H.V]/Dest (0:171) cvn /DEST pdfmark end -2 4684 a 396 4779 a Fc(full)44 b(line)h(of)f(informational)f(text)-2 4780 y SDict begin H.S end -2 4780 a -2 4780 a SDict begin 13 H.A end -2 4780 a -2 4780 a SDict begin [/View [/XYZ H.V]/Dest (0:172) cvn /DEST pdfmark end -2 4780 a -2 4947 a SDict begin H.S end -2 4947 a -2 4947 a SDict begin 13 H.A end -2 4947 a -2 4947 a SDict begin [/View [/XYZ H.V]/Dest (0:173) cvn /DEST pdfmark end -2 4947 a -2 4947 a SDict begin H.S end -2 4947 a -2 4947 a SDict begin 13 H.A end -2 4947 a -2 4947 a SDict begin [/View [/XYZ H.V]/Dest (0:174) cvn /DEST pdfmark end -2 4947 a 396 5053 a Fc(gophertypeDESCRIPTION)1367 5053 y SDict begin H.S end 1367 5053 a 1367 5053 a SDict begin 13 H.A end 1367 5053 a 1367 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:175) cvn /DEST pdfmark end 1367 5053 a 21 w Fj([\\t)1462 5053 y SDict begin H.S end 1462 5053 a 1462 5053 a SDict begin 13 H.A end 1462 5053 a 1462 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:176) cvn /DEST pdfmark end 1462 5053 a Fc(selector)1825 5053 y SDict begin H.S end 1825 5053 a 1825 5053 a SDict begin 13 H.A end 1825 5053 a 1825 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:177) cvn /DEST pdfmark end 1825 5053 a 19 w Fj([\\t)1918 5053 y SDict begin H.S end 1918 5053 a 1918 5053 a SDict begin 13 H.A end 1918 5053 a 1918 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:178) cvn /DEST pdfmark end 1918 5053 a Fc(host)2098 5053 y SDict begin H.S end 2098 5053 a 2098 5053 a SDict begin 13 H.A end 2098 5053 a 2098 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:179) cvn /DEST pdfmark end 2098 5053 a 19 w Fj([\\t)2191 5053 y SDict begin H.S end 2191 5053 a 2191 5053 a SDict begin 13 H.A end 2191 5053 a 2191 5053 a SDict begin [/View [/XYZ H.V]/Dest (0:180) cvn /DEST pdfmark end 2191 5053 a Fc(port)p Fj(]]])p Black -2 5569 a SDict begin H.S end -2 5569 a -2 5569 a SDict begin 13 H.A end -2 5569 a -2 5569 a SDict begin [/View [/XYZ H.V]/Dest (0:182) cvn /DEST pdfmark end -2 5569 a 3839 5638 a Fi(7)p Black eop end %%Page: 8 11 TeXDict begin 8 10 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.8) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:181) cvn /DEST pdfmark end -2 -11 a 396 72 a Fj(Note:)g(spaces)h(sho)n(wn)e(abo) o(v)o(e)g(are)h(for)g(clarity)f(only)h(and)f(should)h(not)f(actually)h (be)g(present)g(in)g(your)f(\002le.)396 346 y(The)h(informational)e(te) o(xt)i(must)g(not)g(contain)f(an)o(y)h(tab)g(characters,)f(b)n(ut)h (may)g(contain)f(spaces.)h(Informational)d(te)o(xt)396 454 y(will)k(be)f(rendered)e(with)j(gopher)d(type)i(i,)g(which)g(will)h (cause)f(it)h(to)f(be)h(displayed)e(on)g(a)i(client')-5 b(s)21 b(screen)e(at)i(its)396 562 y(particular)e(position)g(in)i(the)f (\002le.)-2 746 y SDict begin H.S end -2 746 a -2 746 a SDict begin 13 H.A end -2 746 a -2 746 a SDict begin [/View [/XYZ H.V]/Dest (0:184) cvn /DEST pdfmark end -2 746 a 396 836 a Fj(The)g(second)f(type)h(of)g(line)g(represents)g(a) g(link)g(to)h(a)f(\002le)h(or)f(directory)-5 b(.)18 b(It)i(be)o(gins)g (with)g(a)h(single-character)c(Gopher)396 944 y(type)j(\(see)g(Gopher)f (Item)h(T)-7 b(ypes)20 b(belo)n(w\))f(follo)n(wed)g(immediately)g(by)h (a)g(description)f(and)h(a)g(tab)h(character)-5 b(.)19 b(There)g(is)396 1052 y(no)h(space)g(or)g(other)f(separator)g(between)h (the)g(gopher)e(type)i(and)g(the)g(description.)e(The)i(description)f (may)h(contain)396 1160 y(spaces)h(b)n(ut)f(not)g(tabs.)-2 1344 y SDict begin H.S end -2 1344 a -2 1344 a SDict begin 13 H.A end -2 1344 a -2 1344 a SDict begin [/View [/XYZ H.V]/Dest (0:185) cvn /DEST pdfmark end -2 1344 a 396 1434 a Fj(The)g(remaining)f(ar)o(guments)f(are)i(optional,)e(b)n (ut)j(only)e(to)h(the)h(e)o(xtent)e(that)h(ar)o(guments)e(may)i(be)g (omitted)g(only)f(if)i(all)396 1542 y(ar)o(guments)d(after)i(them)g (are)g(also)h(omitted.)e(These)h(ar)o(guments)e(are:)-2 1560 y SDict begin H.S end -2 1560 a -2 1560 a SDict begin 13 H.A end -2 1560 a -2 1560 a SDict begin [/View [/XYZ H.V]/Dest (0:186) cvn /DEST pdfmark end -2 1560 a -2 1684 a SDict begin H.S end -2 1684 a -2 1684 a SDict begin 13 H.A end -2 1684 a -2 1684 a SDict begin [/View [/XYZ H.V]/Dest (0:188) cvn /DEST pdfmark end -2 1684 a -2 1684 a SDict begin H.S end -2 1684 a -2 1684 a SDict begin 13 H.A end -2 1684 a -2 1684 a SDict begin [/View [/XYZ H.V]/Dest (0:189) cvn /DEST pdfmark end -2 1684 a 396 1774 a Fc(selector)-2 1775 y SDict begin H.S end -2 1775 a -2 1775 a SDict begin 13 H.A end -2 1775 a -2 1775 a SDict begin [/View [/XYZ H.V]/Dest (0:190) cvn /DEST pdfmark end -2 1775 a Black Black 562 1924 a SDict begin H.S end 562 1924 a 562 1924 a SDict begin 13 H.A end 562 1924 a 562 1924 a SDict begin [/View [/XYZ H.V]/Dest (0:191) cvn /DEST pdfmark end 562 1924 a Fj(The)712 1924 y SDict begin H.S end 712 1924 a 712 1924 a SDict begin 13 H.A end 712 1924 a 712 1924 a SDict begin [/View [/XYZ H.V]/Dest (0:192) cvn /DEST pdfmark end 712 1924 a Fj(selector)i(is)h(the)f(name)g(of)g (the)g(\002le)h(on)f(the)g(serv)o(er)-5 b(.)20 b(If)g(it)g(be)o(gins)g (with)g(a)h(slash,)f(it)h(is)g(an)f(absolute)g(path;)562 2032 y(otherwise,)g(it)h(is)g(interpreted)d(relati)n(v)o(e)h(to)i(the)f (directory)e(that)j(the)f(gophermap)d(\002le)k(is)g(in.)f(If)g(no)g (selector)g(is)562 2140 y(speci\002ed,)g(the)g(description)f(is)i(also) f(used)g(as)h(the)g(selector)-5 b(.)-2 2241 y SDict begin H.S end -2 2241 a -2 2241 a SDict begin 13 H.A end -2 2241 a -2 2241 a SDict begin [/View [/XYZ H.V]/Dest (0:194) cvn /DEST pdfmark end -2 2241 a -2 2241 a SDict begin H.S end -2 2241 a -2 2241 a SDict begin 13 H.A end -2 2241 a -2 2241 a SDict begin [/View [/XYZ H.V]/Dest (0:195) cvn /DEST pdfmark end -2 2241 a 396 2331 a Fc(host)-2 2332 y SDict begin H.S end -2 2332 a -2 2332 a SDict begin 13 H.A end -2 2332 a -2 2332 a SDict begin [/View [/XYZ H.V]/Dest (0:196) cvn /DEST pdfmark end -2 2332 a Black Black 562 2480 a SDict begin H.S end 562 2480 a 562 2480 a SDict begin 13 H.A end 562 2480 a 562 2480 a SDict begin [/View [/XYZ H.V]/Dest (0:197) cvn /DEST pdfmark end 562 2480 a Fj(The)712 2480 y SDict begin H.S end 712 2480 a 712 2480 a SDict begin 13 H.A end 712 2480 a 712 2480 a SDict begin [/View [/XYZ H.V]/Dest (0:198) cvn /DEST pdfmark end 712 2480 a Fj(host)20 b(speci\002es)h(the)f(host)g(on)g(which)g(this)h(resource) d(is)k(located.)d(If)h(not)g(speci\002ed,)f(def)o(aults)h(to)h(the)f (current)562 2588 y(serv)o(er)-5 b(.)-2 2672 y SDict begin H.S end -2 2672 a -2 2672 a SDict begin 13 H.A end -2 2672 a -2 2672 a SDict begin [/View [/XYZ H.V]/Dest (0:200) cvn /DEST pdfmark end -2 2672 a -2 2672 a SDict begin H.S end -2 2672 a -2 2672 a SDict begin 13 H.A end -2 2672 a -2 2672 a SDict begin [/View [/XYZ H.V]/Dest (0:201) cvn /DEST pdfmark end -2 2672 a 396 2779 a Fc(port)-2 2791 y SDict begin H.S end -2 2791 a -2 2791 a SDict begin 13 H.A end -2 2791 a -2 2791 a SDict begin [/View [/XYZ H.V]/Dest (0:202) cvn /DEST pdfmark end -2 2791 a Black Black 562 2928 a SDict begin H.S end 562 2928 a 562 2928 a SDict begin 13 H.A end 562 2928 a 562 2928 a SDict begin [/View [/XYZ H.V]/Dest (0:203) cvn /DEST pdfmark end 562 2928 a Fj(The)712 2928 y SDict begin H.S end 712 2928 a 712 2928 a SDict begin 13 H.A end 712 2928 a 712 2928 a SDict begin [/View [/XYZ H.V]/Dest (0:204) cvn /DEST pdfmark end 712 2928 a Fj(port)20 b(speci\002es)g(the)h(port)e(on)h(which)f(the)i(resource)e (is)i(located.)e(If)h(not)g(speci\002ed,)g(def)o(aults)f(to)i(the)f (port)f(the)562 3036 y(current)g(serv)o(er)h(is)h(listening)e(on.)-2 3220 y SDict begin H.S end -2 3220 a -2 3220 a SDict begin 13 H.A end -2 3220 a -2 3220 a SDict begin [/View [/XYZ H.V]/Dest (0:205) cvn /DEST pdfmark end -2 3220 a 396 3310 a Fj(An)h(e)o(xample)f(of)h(a)h(gophermap)c(to)j(help)g (illustrate)g(the)h(concept)e(is)i(included)d(with)j(the)2996 3310 y SDict begin H.S end 2996 3310 a 2996 3310 a SDict begin 13 H.A end 2996 3310 a 2996 3310 a SDict begin [/View [/XYZ H.V]/Dest (0:206) cvn /DEST pdfmark end 2996 3310 a Fj(PyGopherd)d(distrib)n(ution)h(in)396 3418 y(the)h(\002le)645 3418 y SDict begin H.S end 645 3418 a 645 3418 a SDict begin 13 H.A end 645 3418 a 645 3418 a SDict begin [/View [/XYZ H.V]/Dest (0:207) cvn /DEST pdfmark end 645 3418 a Fe(examples/gophermap)p Fj(.)-2 3440 y SDict begin H.S end -2 3440 a -2 3440 a SDict begin 13 H.A end -2 3440 a -2 3440 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.COMPRESSEDFILEHANDLER) cvn /DEST pdfmark end -2 3440 a 366 x Fh(5.3.)39 b(\002le)s(.CompressedFileHandle)o(r)2183 3806 y SDict begin H.S end 2183 3806 a 2183 3806 a SDict begin 22.464 H.A end 2183 3806 a 2183 3806 a SDict begin [/View [/XYZ H.V]/Dest (7.8.1) cvn /DEST pdfmark end 2183 3806 a -2 4002 a SDict begin H.S end -2 4002 a -2 4002 a SDict begin 13 H.A end -2 4002 a -2 4002 a SDict begin [/View [/XYZ H.V]/Dest (0:210) cvn /DEST pdfmark end -2 4002 a 396 4080 a Fj(In)20 b(order)f(to)h(sa)n(v)o(e)h (space,)f(you)f(might)h(w)o(ant)g(to)g(store)g(documents)f(on-disk)g (in)h(a)h(compressed)d(format.)h(But)i(then)396 4188 y(clients)g(w)o(ould)e(ordinarily)f(ha)n(v)o(e)i(to)g(decompress)f(the) h(\002les)h(themselv)o(es.)f(It)g(w)o(ould)g(be)g(nice)g(to)g(ha)n(v)o (e)g(the)g(serv)o(er)396 4296 y(automatically)f(decompress)g(the)h (\002les)h(on)f(the)g(\003y)-5 b(,)20 b(sending)f(that)h(result)g(to)h (the)f(client.)g(That')-5 b(s)20 b(where)396 4404 y SDict begin H.S end 396 4404 a 396 4404 a SDict begin 13 H.A end 396 4404 a 396 4404 a SDict begin [/View [/XYZ H.V]/Dest (0:211) cvn /DEST pdfmark end 396 4404 a Fj (\002le.CompressedFileHandler)e(comes)i(in.)-2 4588 y SDict begin H.S end -2 4588 a -2 4588 a SDict begin 13 H.A end -2 4588 a -2 4588 a SDict begin [/View [/XYZ H.V]/Dest (0:212) cvn /DEST pdfmark end -2 4588 a 396 4677 a Fj(This)h(handler)d(will)j(tak)o(e)g(compressed)d(\002les,)j (pipe)f(them)g(through)e(your)h(chosen)g(decompression)f(program,)g (and)396 4785 y(send)i(the)g(result)h(directly)e(to)h(clients)h(--)f (completely)f(transparently)-5 b(.)-2 4969 y SDict begin H.S end -2 4969 a -2 4969 a SDict begin 13 H.A end -2 4969 a -2 4969 a SDict begin [/View [/XYZ H.V]/Dest (0:213) cvn /DEST pdfmark end -2 4969 a 396 5059 a Fj(T)e(o)21 b(use)f(this)h(handler)m(,)d(set)j(the)1297 5059 y SDict begin H.S end 1297 5059 a 1297 5059 a SDict begin 13 H.A end 1297 5059 a 1297 5059 a SDict begin [/View [/XYZ H.V]/Dest (0:214) cvn /DEST pdfmark end 1297 5059 a Fj(decompressors)d(option)h(in)i(the)f(con\002guration)d (\002le.)k(This)f(option)f(de\002nes)h(a)h(mapping)396 5167 y(from)e(MIME)h(encodings)f(\(as)h(de\002ned)f(with)i(the)1856 5167 y SDict begin H.S end 1856 5167 a 1856 5167 a SDict begin 13 H.A end 1856 5167 a 1856 5167 a SDict begin [/View [/XYZ H.V]/Dest (0:215) cvn /DEST pdfmark end 1856 5167 a Fj(encoding)d(option\))h(to)h(decompression)e(programs.)g (Files)j(that)f(are)p Black 3842 5569 a Fi(8)p Black eop end %%Page: 9 12 TeXDict begin 9 11 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.9) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black 396 72 a Fj(not)g(encoded,)e(or)i(which)g (ha)n(v)o(e)f(an)i(encoding)d(that)i(does)g(not)g(occur)f(in)h(the)2611 72 y SDict begin H.S end 2611 72 a 2611 72 a SDict begin 13 H.A end 2611 72 a 2611 72 a SDict begin [/View [/XYZ H.V]/Dest (0:216) cvn /DEST pdfmark end 2611 72 a Fj(decompressors)f(map,)g(will)i(not)f(be)396 180 y(decompressed)e (by)i(this)h(handler)-5 b(.)-2 364 y SDict begin H.S end -2 364 a -2 364 a SDict begin 13 H.A end -2 364 a -2 364 a SDict begin [/View [/XYZ H.V]/Dest (0:217) cvn /DEST pdfmark end -2 364 a 396 454 a Fj(Please)21 b(see)g(the)f (sample)g(con\002guration)e(\002le)i(for)g(more)f(e)o(xamples)g(and)h (details)h(about)e(the)h(con\002guration)e(of)h(this)396 562 y(handler)-5 b(.)-2 573 y SDict begin H.S end -2 573 a -2 573 a SDict begin 13 H.A end -2 573 a -2 573 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.FILEHANDLER) cvn /DEST pdfmark end -2 573 a 377 x Fh(5.4.)39 b(\002le)s(.FileHandler)1312 950 y SDict begin H.S end 1312 950 a 1312 950 a SDict begin 22.464 H.A end 1312 950 a 1312 950 a SDict begin [/View [/XYZ H.V]/Dest (7.9.1) cvn /DEST pdfmark end 1312 950 a -2 1118 a SDict begin H.S end -2 1118 a -2 1118 a SDict begin 13 H.A end -2 1118 a -2 1118 a SDict begin [/View [/XYZ H.V]/Dest (0:220) cvn /DEST pdfmark end -2 1118 a 396 1224 a Fj(The)546 1224 y SDict begin H.S end 546 1224 a 546 1224 a SDict begin 13 H.A end 546 1224 a 546 1224 a SDict begin [/View [/XYZ H.V]/Dest (0:221) cvn /DEST pdfmark end 546 1224 a Fj(\002le.FileHandler)19 b(is)i(just)g(that)f(--)h(its)g(duty)e(is)i(to)g(serv)o(e)e(up)h(re)o (gular)f(\002les)i(to)f(clients.)-2 1252 y SDict begin H.S end -2 1252 a -2 1252 a SDict begin 13 H.A end -2 1252 a -2 1252 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.HTMLFILETITLEHANDLER) cvn /DEST pdfmark end -2 1252 a 359 x Fh(5.5.)39 b(html.HTMLFileTitleHandle)o(r)2100 1611 y SDict begin H.S end 2100 1611 a 2100 1611 a SDict begin 22.464 H.A end 2100 1611 a 2100 1611 a SDict begin [/View [/XYZ H.V]/Dest (7.10.1) cvn /DEST pdfmark end 2100 1611 a -2 1779 a SDict begin H.S end -2 1779 a -2 1779 a SDict begin 13 H.A end -2 1779 a -2 1779 a SDict begin [/View [/XYZ H.V]/Dest (0:224) cvn /DEST pdfmark end -2 1779 a 396 1885 a Fj(This)20 b(handler)f(is)h(used)g(when)f(generating)f (directories)h(and)g(will)i(set)f(the)g(description)e(of)i(HTML)f (\002les)i(to)f(the)g(HTML)396 1993 y(title)h(de\002ned)e(in)i(them)f (rather)f(than)h(let)g(it)h(be)f(the)h(def)o(ault)e(\002lename.)h (Other)f(than)h(that,)g(it)h(has)f(no)g(ef)n(fect.)g(UMN)396 2101 y(gopherd)e(implements)h(a)i(similar)f(polic)o(y)-5 b(.)-2 2129 y SDict begin H.S end -2 2129 a -2 2129 a SDict begin 13 H.A end -2 2129 a -2 2129 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.MAILBOXES) cvn /DEST pdfmark end -2 2129 a 360 x Fh(5.6.)39 b(mbo)l(x)f(handler)n(s)1293 2489 y SDict begin H.S end 1293 2489 a 1293 2489 a SDict begin 22.464 H.A end 1293 2489 a 1293 2489 a SDict begin [/View [/XYZ H.V]/Dest (7.11.1) cvn /DEST pdfmark end 1293 2489 a -2 2656 a SDict begin H.S end -2 2656 a -2 2656 a SDict begin 13 H.A end -2 2656 a -2 2656 a SDict begin [/View [/XYZ H.V]/Dest (0:227) cvn /DEST pdfmark end -2 2656 a 396 2763 a Fj(There)20 b(are)g(four)f(mailbox)g (handlers:)-2 2764 y SDict begin H.S end -2 2764 a -2 2764 a SDict begin 13 H.A end -2 2764 a -2 2764 a SDict begin [/View [/XYZ H.V]/Dest (0:228) cvn /DEST pdfmark end -2 2764 a -2 2774 a SDict begin H.S end -2 2774 a -2 2774 a SDict begin 13 H.A end -2 2774 a -2 2774 a SDict begin [/View [/XYZ H.V]/Dest (0:229) cvn /DEST pdfmark end -2 2774 a Black 396 2933 a Fg(\225)p Black 479 2933 a SDict begin H.S end 479 2933 a 479 2933 a SDict begin 13 H.A end 479 2933 a 479 2933 a SDict begin [/View [/XYZ H.V]/Dest (0:230) cvn /DEST pdfmark end 479 2933 a Fj(mbox.MaildirF)o(olderHandler)-2 2934 y SDict begin H.S end -2 2934 a -2 2934 a SDict begin 13 H.A end -2 2934 a -2 2934 a SDict begin [/View [/XYZ H.V]/Dest (0:231) cvn /DEST pdfmark end -2 2934 a Black 396 3082 a Fg(\225)p Black 479 3082 a SDict begin H.S end 479 3082 a 479 3082 a SDict begin 13 H.A end 479 3082 a 479 3082 a SDict begin [/View [/XYZ H.V]/Dest (0:232) cvn /DEST pdfmark end 479 3082 a Fj(mbox.MaildirMessageHandler) -2 3100 y SDict begin H.S end -2 3100 a -2 3100 a SDict begin 13 H.A end -2 3100 a -2 3100 a SDict begin [/View [/XYZ H.V]/Dest (0:233) cvn /DEST pdfmark end -2 3100 a Black 396 3232 a Fg(\225)p Black 479 3232 a SDict begin H.S end 479 3232 a 479 3232 a SDict begin 13 H.A end 479 3232 a 479 3232 a SDict begin [/View [/XYZ H.V]/Dest (0:234) cvn /DEST pdfmark end 479 3232 a Fj (mbox.MBoxMessageHandler)-2 3250 y SDict begin H.S end -2 3250 a -2 3250 a SDict begin 13 H.A end -2 3250 a -2 3250 a SDict begin [/View [/XYZ H.V]/Dest (0:235) cvn /DEST pdfmark end -2 3250 a Black 396 3381 a Fg(\225)p Black 479 3381 a SDict begin H.S end 479 3381 a 479 3381 a SDict begin 13 H.A end 479 3381 a 479 3381 a SDict begin [/View [/XYZ H.V]/Dest (0:236) cvn /DEST pdfmark end 479 3381 a Fj(mbox.MBoxF)o(olderHandler)-2 3548 y SDict begin H.S end -2 3548 a -2 3548 a SDict begin 13 H.A end -2 3548 a -2 3548 a SDict begin [/View [/XYZ H.V]/Dest (0:237) cvn /DEST pdfmark end -2 3548 a 396 3655 a Fj(These)h(four)f(handlers)g(pro)o(vide)g(a)h(unique)f("virtual) g(folder")g(service.)h(The)o(y)f(allo)n(w)h(you)f(to)i(present)e (mailbox)o(es)g(as)i(if)396 3763 y(the)o(y)f(were)g(folders,)f(the)h (items)h(of)f(the)g(folders)f(being)g(the)i(messages)f(in)g(the)g (mailbox,)f(or)o(ganized)e(by)j(subject.)g(This)396 3871 y(is)h(useful)f(for)g(presenting)e(mail)j(archi)n(v)o(es)e(or)h(just)g (making)f(e-mail)h(accessible)g(in)h(a)f(nice)g(and)g(easy)g(f)o (ashion.)-2 4055 y SDict begin H.S end -2 4055 a -2 4055 a SDict begin 13 H.A end -2 4055 a -2 4055 a SDict begin [/View [/XYZ H.V]/Dest (0:238) cvn /DEST pdfmark end -2 4055 a 396 4145 a Fj(T)-7 b(o)20 b(use)g(these)g(handlers,)f(all)h (you)f(ha)n(v)o(e)g(to)h(do)f(is)i(enable)e(them)h(in)f(your)2514 4145 y SDict begin H.S end 2514 4145 a 2514 4145 a SDict begin 13 H.A end 2514 4145 a 2514 4145 a SDict begin [/View [/XYZ H.V]/Dest (0:239) cvn /DEST pdfmark end 2514 4145 a Fj(handlers)g(section.)g(The)o(y)g(will)h(automatically) 396 4253 y(detect)g(requests)g(for)g(mailbox)o(es)e(and)i(handle)f (them)h(appropriately)-5 b(.)-2 4437 y SDict begin H.S end -2 4437 a -2 4437 a SDict begin 13 H.A end -2 4437 a -2 4437 a SDict begin [/View [/XYZ H.V]/Dest (0:240) cvn /DEST pdfmark end -2 4437 a 396 4527 a Fj(The)20 b(dif)n(ferent)f(handlers)g(are)h(for)f(traditional)g(Unix)h(mbox)f (mailbox)o(es)g(\(all)h(messages)h(in)f(a)h(single)f(\002le\))g(and)g (ne)n(w)396 4635 y(qmail-stype)f(Maildir)h(mailbox)o(es.)e(Y)-9 b(ou)20 b(can)g(enable)f(only)h(the)g(tw)o(o)g(handlers)g(for)f(the)h (speci\002c)h(mailbox)e(type)g(that)396 4743 y(you)h(use,)g(if)g (desired.)-2 4771 y SDict begin H.S end -2 4771 a -2 4771 a SDict begin 13 H.A end -2 4771 a -2 4771 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.PYGHANDLER) cvn /DEST pdfmark end -2 4771 a Black 3842 5569 a Fi(9)p Black eop end %%Page: 10 13 TeXDict begin 10 12 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.10) cvn /DEST pdfmark end -611 -810 a Black Black -2 -201 a SDict begin H.S end -2 -201 a -2 -201 a SDict begin 13 H.A end -2 -201 a -2 -201 a SDict begin [/View [/XYZ H.V]/Dest (0:277) cvn /DEST pdfmark end -2 -201 a 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 94 a Fh(5.7.)39 b(p)n(yg.PYGHandler)1411 94 y SDict begin H.S end 1411 94 a 1411 94 a SDict begin 22.464 H.A end 1411 94 a 1411 94 a SDict begin [/View [/XYZ H.V]/Dest (7.12.1) cvn /DEST pdfmark end 1411 94 a -2 292 a SDict begin H.S end -2 292 a -2 292 a SDict begin 13 H.A end -2 292 a -2 292 a SDict begin [/View [/XYZ H.V]/Dest (0:243) cvn /DEST pdfmark end -2 292 a 396 368 a Fj(PYG)21 b(\(short)f(for)f(PYGopherd\))f(is)j(a)g (mechanism)e(that)h(pro)o(vides)e(a)j(tremendous)d(amount)h(of)h(\003e) o(xibility)-5 b(.)19 b(Rather)396 476 y(than)h(just)h(letting)f(you)f (e)o(x)o(ecute)g(a)h(script)h(lik)o(e)f(other)f(Gopher)g(or)h(HTTP)g (serv)o(ers,)g(PYGs)h(are)f(actually)g(loaded)f(up)396 584 y(into)h(PyGopherd)e(and)i(become)f(fully-capable)e(\002rst-class)k (virtual)f(handlers.)f(Y)-8 b(et)20 b(the)o(y)g(need)f(not)h(be)g(kno)n (wn)f(ahead)396 692 y(of)h(time,)g(and)g(are)g(loaded)f(dynamically)-5 b(.)-2 876 y SDict begin H.S end -2 876 a -2 876 a SDict begin 13 H.A end -2 876 a -2 876 a SDict begin [/View [/XYZ H.V]/Dest (0:244) cvn /DEST pdfmark end -2 876 a 396 966 a Fj(W)m(ith)21 b(a)f(PYG)h(handler)m(,)d(you)i(can)g (generate)f(gopher)f(directories,)h(handle)g(searches,)h(generate)f (\002les,)h(and)g(more)f(on)396 1074 y(the)h(\003y)-5 b(.)20 b(Y)-9 b(ou)20 b(can)g(create)g(entire)g(virtual)f(directory)g (trees)h(\(for)f(instance,)h(to)g(interf)o(ace)f(with)i(NNTP)f(serv)o (ers)g(or)g(with)396 1182 y(DICT)h(serv)o(ers\),)e(and)g(access)i(them) f(all)h(using)e(the)i(standard)e(Gopher)f(protocol.)h(All)h(of)g(this)h (without)f(ha)n(ving)f(to)396 1290 y(modify)g(e)n(v)o(en)g(one)h(line)g (of)1207 1290 y SDict begin H.S end 1207 1290 a 1207 1290 a SDict begin 13 H.A end 1207 1290 a 1207 1290 a SDict begin [/View [/XYZ H.V]/Dest (0:245) cvn /DEST pdfmark end 1207 1290 a Fj(PyGopherd)e(code.)-2 1474 y SDict begin H.S end -2 1474 a -2 1474 a SDict begin 13 H.A end -2 1474 a -2 1474 a SDict begin [/View [/XYZ H.V]/Dest (0:246) cvn /DEST pdfmark end -2 1474 a 396 1564 a Fj(If)i(enabled,)f(the)894 1564 y SDict begin H.S end 894 1564 a 894 1564 a SDict begin 13 H.A end 894 1564 a 894 1564 a SDict begin [/View [/XYZ H.V]/Dest (0:247) cvn /DEST pdfmark end 894 1564 a Fj(p)o(yg.PYGHandler)f(will)j(look)e (for)h(\002les)h(with)f(the)g(e)o(xtension)f(.p)o(yg)g(that)i(are)f (mark)o(ed)f(e)o(x)o(ecutable.)f(If)396 1672 y(found,)g(the)o(y)i(will) h(be)f(loaded)f(and)h(run)f(as)i(PYGs.)-2 1856 y SDict begin H.S end -2 1856 a -2 1856 a SDict begin 13 H.A end -2 1856 a -2 1856 a SDict begin [/View [/XYZ H.V]/Dest (0:248) cvn /DEST pdfmark end -2 1856 a 396 1946 a Fj(Please)g(note:)f(this)h(module)d(pro)o(vides)h(the)h(capability)f (to)i(e)o(x)o(ecute)d(arbitrary)h(code.)g(Please)i(consider)e(the)h (security)396 2053 y(rami\002cations)g(of)f(that)i(before)e(enabling)f (it.)-2 2237 y SDict begin H.S end -2 2237 a -2 2237 a SDict begin 13 H.A end -2 2237 a -2 2237 a SDict begin [/View [/XYZ H.V]/Dest (0:249) cvn /DEST pdfmark end -2 2237 a 396 2327 a Fj(See)j(the)659 2327 y SDict begin H.S end 659 2327 a 659 2327 a SDict begin 13 H.A end 659 2327 a 659 2327 a SDict begin [/View [/XYZ H.V]/Dest (0:250) cvn /DEST pdfmark end 659 2327 a Fj(virtual.V)-5 b(irtual)19 b(handler)f(for)i(more)f(information)f(about)h(passing)h (data)g(to)h(your)d(scripts)j(at)g(runtime.)-2 2511 y SDict begin H.S end -2 2511 a -2 2511 a SDict begin 13 H.A end -2 2511 a -2 2511 a SDict begin [/View [/XYZ H.V]/Dest (0:251) cvn /DEST pdfmark end -2 2511 a 396 2601 a Fj(At)g(present,)e(documentation)f(on)h(writing)h(PYGs)h(is)g (not)f(pro)o(vided,)d(b)n(ut)k(you)e(may)h(\002nd)g(e)o(xamples)f(in)h (the)3542 2601 y SDict begin H.S end 3542 2601 a 3542 2601 a SDict begin 13 H.A end 3542 2601 a 3542 2601 a SDict begin [/View [/XYZ H.V]/Dest (0:252) cvn /DEST pdfmark end 3542 2601 a Fj(p)o(ygf)o(arm)396 2709 y(directory)f (included)f(with)j(the)1314 2709 y SDict begin H.S end 1314 2709 a 1314 2709 a SDict begin 13 H.A end 1314 2709 a 1314 2709 a SDict begin [/View [/XYZ H.V]/Dest (0:253) cvn /DEST pdfmark end 1314 2709 a Fj(PyGopherd)d(distrib)n(ution.) -2 2738 y SDict begin H.S end -2 2738 a -2 2738 a SDict begin 13 H.A end -2 2738 a -2 2738 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.EXECHANDLER) cvn /DEST pdfmark end -2 2738 a 359 x Fh(5.8.)39 b(scripte)n(x)o(ec.Ex)o(ecHandler)1897 3097 y SDict begin H.S end 1897 3097 a 1897 3097 a SDict begin 22.464 H.A end 1897 3097 a 1897 3097 a SDict begin [/View [/XYZ H.V]/Dest (7.13.1) cvn /DEST pdfmark end 1897 3097 a -2 3293 a SDict begin H.S end -2 3293 a -2 3293 a SDict begin 13 H.A end -2 3293 a -2 3293 a SDict begin [/View [/XYZ H.V]/Dest (0:256) cvn /DEST pdfmark end -2 3293 a 396 3371 a Fj(This)20 b(handler)e(implements)h ("old-style")f(script)i(e)o(x)o(ecution;)e(that)i(is,)g(e)o(x)o (ecuting)d(arbitrary)h(programs)g(and)h(piping)g(the)396 3479 y(result)h(to)h(the)f(client.)g(It)h(is,)f(for)g(the)g(most)g (part,)g(compatible)f(with)h(both)f(scripts)i(written)f(for)f(UMN)i (gopherd)d(and)h(the)396 3587 y(Bucktooth)g(gopher)f(serv)o(er)-5 b(.)20 b(If)g(enabled,)e(it)j(will)g(e)o(x)o(ecute)e(an)o(y)g(\002le)i (that)g(is)g(mark)o(ed)d(e)o(x)o(ecutable)h(in)h(the)g(\002lesystem.)g (It)396 3695 y(will)g(normally)d(list)j(scripts)f(as)h(returning)d (plain)h(te)o(xt,)h(b)n(ut)g(you)f(may)g(create)h(a)g(custom)f(link)h (to)g(the)g(script)g(that)g(de\002nes)396 3802 y(it)i(as)g(returning)d (whate)n(v)o(er)h(kind)g(of)h(\002le)h(you)e(desire.)h(Unlik)o(e)g (PYGs,)h(this)g(type)e(must)i(be)f(kno)n(wn)e(in)j(adv)n(ance.)-2 3987 y SDict begin H.S end -2 3987 a -2 3987 a SDict begin 13 H.A end -2 3987 a -2 3987 a SDict begin [/View [/XYZ H.V]/Dest (0:257) cvn /DEST pdfmark end -2 3987 a 396 4076 a Fj(The)546 4076 y SDict begin H.S end 546 4076 a 546 4076 a SDict begin 13 H.A end 546 4076 a 546 4076 a SDict begin [/View [/XYZ H.V]/Dest (0:258) cvn /DEST pdfmark end 546 4076 a Fj(scripte)o(x)o(ec.Ex)o(ecHandler)16 b(will)21 b(set)g(en)m(vironment)c(v)n(ariables)i(for)h(your)f(scripts) h(to)h(use.)f(The)o(y)f(are)h(as)h(follo)n(ws:)-2 4094 y SDict begin H.S end -2 4094 a -2 4094 a SDict begin 13 H.A end -2 4094 a -2 4094 a SDict begin [/View [/XYZ H.V]/Dest (0:259) cvn /DEST pdfmark end -2 4094 a -2 4219 a SDict begin H.S end -2 4219 a -2 4219 a SDict begin 13 H.A end -2 4219 a -2 4219 a SDict begin [/View [/XYZ H.V]/Dest (0:261) cvn /DEST pdfmark end -2 4219 a 396 4309 a Fj(SER)-7 b(VER_N)m(AME)-2 4319 y SDict begin H.S end -2 4319 a -2 4319 a SDict begin 13 H.A end -2 4319 a -2 4319 a SDict begin [/View [/XYZ H.V]/Dest (0:262) cvn /DEST pdfmark end -2 4319 a Black Black 562 4458 a SDict begin H.S end 562 4458 a 562 4458 a SDict begin 13 H.A end 562 4458 a 562 4458 a SDict begin [/View [/XYZ H.V]/Dest (0:263) cvn /DEST pdfmark end 562 4458 a Fj(The)20 b(name)g(of)g(this)g(serv)o(er)g(as)h(de\002ned) e(in)h(the)g(con\002guration)e(\002le)j(or)f(detected)f(from)g(the)h (operating)f(system.)-2 4559 y SDict begin H.S end -2 4559 a -2 4559 a SDict begin 13 H.A end -2 4559 a -2 4559 a SDict begin [/View [/XYZ H.V]/Dest (0:265) cvn /DEST pdfmark end -2 4559 a 396 4649 a Fj(SER)-7 b(VER_POR)i(T)-2 4659 y SDict begin H.S end -2 4659 a -2 4659 a SDict begin 13 H.A end -2 4659 a -2 4659 a SDict begin [/View [/XYZ H.V]/Dest (0:266) cvn /DEST pdfmark end -2 4659 a Black Black 562 4799 a SDict begin H.S end 562 4799 a 562 4799 a SDict begin 13 H.A end 562 4799 a 562 4799 a SDict begin [/View [/XYZ H.V]/Dest (0:267) cvn /DEST pdfmark end 562 4799 a Fj(The)20 b(port)g(this)g(serv)o(er)g(is)h (listening)f(on.)-2 4900 y SDict begin H.S end -2 4900 a -2 4900 a SDict begin 13 H.A end -2 4900 a -2 4900 a SDict begin [/View [/XYZ H.V]/Dest (0:269) cvn /DEST pdfmark end -2 4900 a 396 4990 a Fj(REMO)m(TE_ADDR)-2 5000 y SDict begin H.S end -2 5000 a -2 5000 a SDict begin 13 H.A end -2 5000 a -2 5000 a SDict begin [/View [/XYZ H.V]/Dest (0:270) cvn /DEST pdfmark end -2 5000 a Black Black 562 5139 a SDict begin H.S end 562 5139 a 562 5139 a SDict begin 13 H.A end 562 5139 a 562 5139 a SDict begin [/View [/XYZ H.V]/Dest (0:271) cvn /DEST pdfmark end 562 5139 a Fj(The)g(IP)h(address)e(of)h(the)h(client.)p Black 3800 5569 a Fi(10)p Black eop end %%Page: 11 14 TeXDict begin 11 13 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.11) cvn /DEST pdfmark end -611 -810 a Black Black -2 -201 a SDict begin H.S end -2 -201 a -2 -201 a SDict begin 13 H.A end -2 -201 a -2 -201 a SDict begin [/View [/XYZ H.V]/Dest (0:308) cvn /DEST pdfmark end -2 -201 a 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:273) cvn /DEST pdfmark end -2 -11 a 396 72 a Fj(REMO)m(TE_POR)-5 b(T)-2 82 y SDict begin H.S end -2 82 a -2 82 a SDict begin 13 H.A end -2 82 a -2 82 a SDict begin [/View [/XYZ H.V]/Dest (0:274) cvn /DEST pdfmark end -2 82 a Black Black 562 222 a SDict begin H.S end 562 222 a 562 222 a SDict begin 13 H.A end 562 222 a 562 222 a SDict begin [/View [/XYZ H.V]/Dest (0:275) cvn /DEST pdfmark end 562 222 a Fj(The)20 b(port)g(number)e(of)i(the)g(client.)396 413 y(REMO)m(TE_HOST)-2 423 y SDict begin H.S end -2 423 a -2 423 a SDict begin 13 H.A end -2 423 a -2 423 a SDict begin [/View [/XYZ H.V]/Dest (0:278) cvn /DEST pdfmark end -2 423 a Black Black 562 562 a SDict begin H.S end 562 562 a 562 562 a SDict begin 13 H.A end 562 562 a 562 562 a SDict begin [/View [/XYZ H.V]/Dest (0:279) cvn /DEST pdfmark end 562 562 a Fj(The)g(same)h(v)n(alue)e(as)1192 562 y SDict begin H.S end 1192 562 a 1192 562 a SDict begin 13 H.A end 1192 562 a 1192 562 a SDict begin [/View [/XYZ H.V]/Dest (0:280) cvn /DEST pdfmark end 1192 562 a Fj(REMO)m(TE_ADDR)-2 655 y SDict begin H.S end -2 655 a -2 655 a SDict begin 13 H.A end -2 655 a -2 655 a SDict begin [/View [/XYZ H.V]/Dest (0:282) cvn /DEST pdfmark end -2 655 a 396 753 a Fj(SELECT)o(OR)-2 754 y SDict begin H.S end -2 754 a -2 754 a SDict begin 13 H.A end -2 754 a -2 754 a SDict begin [/View [/XYZ H.V]/Dest (0:283) cvn /DEST pdfmark end -2 754 a Black Black 562 903 a SDict begin H.S end 562 903 a 562 903 a SDict begin 13 H.A end 562 903 a 562 903 a SDict begin [/View [/XYZ H.V]/Dest (0:284) cvn /DEST pdfmark end 562 903 a Fj(The)h(\002le)h(that)f(w)o(as)h(requested;)e(that)i(is,)f (the)h(relati)n(v)o(e)e(path)h(to)g(this)h(script.)f(If)g(the)g (selector)g(included)f(additional)562 1011 y(parameters)g(after)h(a)h (|,)f(the)o(y)f(will)i(be)f(included)f(in)h(this)h(string)f(as)h(well.) -2 1112 y SDict begin H.S end -2 1112 a -2 1112 a SDict begin 13 H.A end -2 1112 a -2 1112 a SDict begin [/View [/XYZ H.V]/Dest (0:286) cvn /DEST pdfmark end -2 1112 a 396 1202 a Fj(REQ)o(UEST)-2 1217 y SDict begin H.S end -2 1217 a -2 1217 a SDict begin 13 H.A end -2 1217 a -2 1217 a SDict begin [/View [/XYZ H.V]/Dest (0:287) cvn /DEST pdfmark end -2 1217 a Black Black 562 1351 a SDict begin H.S end 562 1351 a 562 1351 a SDict begin 13 H.A end 562 1351 a 562 1351 a SDict begin [/View [/XYZ H.V]/Dest (0:288) cvn /DEST pdfmark end 562 1351 a Fj(The)f("base")g(part)g(of)g(the)g(selector;)g(that)g(is,)h (the)g(part)e(leading)h(up)f(to)i(the)f(|.)-2 1452 y SDict begin H.S end -2 1452 a -2 1452 a SDict begin 13 H.A end -2 1452 a -2 1452 a SDict begin [/View [/XYZ H.V]/Dest (0:290) cvn /DEST pdfmark end -2 1452 a 396 1542 a Fj(SEARCHREQ)o(UEST)-2 1557 y SDict begin H.S end -2 1557 a -2 1557 a SDict begin 13 H.A end -2 1557 a -2 1557 a SDict begin [/View [/XYZ H.V]/Dest (0:291) cvn /DEST pdfmark end -2 1557 a Black Black 562 1691 a SDict begin H.S end 562 1691 a 562 1691 a SDict begin 13 H.A end 562 1691 a 562 1691 a SDict begin [/View [/XYZ H.V]/Dest (0:292) cvn /DEST pdfmark end 562 1691 a Fj(Included)f(only)g(if)h(the)h(client)f(speci\002ed)g(search)g (data,)f(this)i(is)g(used)f(if)h(the)f(client)g(is)h(searching)e(for)h (something.)-2 1875 y SDict begin H.S end -2 1875 a -2 1875 a SDict begin 13 H.A end -2 1875 a -2 1875 a SDict begin [/View [/XYZ H.V]/Dest (0:293) cvn /DEST pdfmark end -2 1875 a 396 1965 a Fj(See)h(the)659 1965 y SDict begin H.S end 659 1965 a 659 1965 a SDict begin 13 H.A end 659 1965 a 659 1965 a SDict begin [/View [/XYZ H.V]/Dest (0:294) cvn /DEST pdfmark end 659 1965 a Fj(virtual.V)-5 b(irtual)19 b(handler)f(for)i(more)f(information)f(about)h(passing)h (data)g(to)h(your)d(scripts)j(at)g(runtime.)-2 2149 y SDict begin H.S end -2 2149 a -2 2149 a SDict begin 13 H.A end -2 2149 a -2 2149 a SDict begin [/View [/XYZ H.V]/Dest (0:295) cvn /DEST pdfmark end -2 2149 a 396 2239 a Fj(Please)g(note:)f(this)h(module)d(pro)o(vides)h(the)h (capability)f(to)i(e)o(x)o(ecute)d(arbitrary)h(code.)g(Please)i (consider)e(the)h(security)396 2347 y(rami\002cations)g(of)f(that)i (before)e(enabling)f(it.)-2 2376 y SDict begin H.S end -2 2376 a -2 2376 a SDict begin 13 H.A end -2 2376 a -2 2376 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN) cvn /DEST pdfmark end -2 2376 a 359 x Fh(5.9.)39 b(UMN.UMNDirHandler) 1709 2735 y SDict begin H.S end 1709 2735 a 1709 2735 a SDict begin 22.464 H.A end 1709 2735 a 1709 2735 a SDict begin [/View [/XYZ H.V]/Dest (7.14.1) cvn /DEST pdfmark end 1709 2735 a -2 2903 a SDict begin H.S end -2 2903 a -2 2903 a SDict begin 13 H.A end -2 2903 a -2 2903 a SDict begin [/View [/XYZ H.V]/Dest (0:298) cvn /DEST pdfmark end -2 2903 a 396 3009 a Fj(This)21 b(is)g(one)e(of)h(the)h (most)f(po)n(werful)e(w)o(orkhorse)g(handlers)i(in)2252 3009 y SDict begin H.S end 2252 3009 a 2252 3009 a SDict begin 13 H.A end 2252 3009 a 2252 3009 a SDict begin [/View [/XYZ H.V]/Dest (0:299) cvn /DEST pdfmark end 2252 3009 a Fj(PyGopherd.)e(It)i(is)h(designed)e(to)h(emulate)g(most) g(of)g(the)396 3117 y(w)o(ays)h(in)f(which)g(the)g(UMN)g(gopherd)e (distrib)n(ution)h(generates)h(directories,)e(e)n(v)o(en)i(going)f(so)h (f)o(ar)g(as)h(to)f(be)396 3225 y(b)n(ug-compatible)d(in)k(some)f (cases.)h(Generating)d(directories)h(with)i(this)f(handler)f(is)i (often)f(the)g(best)g(general-purpose)396 3333 y(w)o(ay)h(to)f(mak)o(e) g(nice)g(directories)f(in)h(gopherspace.)-2 3517 y SDict begin H.S end -2 3517 a -2 3517 a SDict begin 13 H.A end -2 3517 a -2 3517 a SDict begin [/View [/XYZ H.V]/Dest (0:300) cvn /DEST pdfmark end -2 3517 a 396 3607 a Fj(The)g(remainder)e(of)i(the)h(description)d(of)i(the)1717 3607 y SDict begin H.S end 1717 3607 a 1717 3607 a SDict begin 13 H.A end 1717 3607 a 1717 3607 a SDict begin [/View [/XYZ H.V]/Dest (0:301) cvn /DEST pdfmark end 1717 3607 a Fj(UMN.UMNDirHandler,)e(e)o(xcept)h(for)h(the)g (Abstracts)g(and)g(Info)396 3714 y(section,)g(is)h(lifted)f(directly)f (from)h(the)g(original)f(UMN)h(gopherd)e(documentation,)f(with)k(light) f(editing,)f(because)g(this)396 3822 y(handler)g(implements)g(it)i(so)g (e)o(xactly)e(that)h(there)g(w)o(as)h(no)f(point)f(in)i(re)n(writing)e (all)h(that)h(documentation)c(:-\))-2 3840 y SDict begin H.S end -2 3840 a -2 3840 a SDict begin 13 H.A end -2 3840 a -2 3840 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN.LINKS) cvn /DEST pdfmark end -2 3840 a 396 4150 a Fb(5.9.1.)36 b(Links)1040 4150 y SDict begin H.S end 1040 4150 a 1040 4150 a SDict begin 18.72 H.A end 1040 4150 a 1040 4150 a SDict begin [/View [/XYZ H.V]/Dest (7.14.1.2) cvn /DEST pdfmark end 1040 4150 a -2 4318 a SDict begin H.S end -2 4318 a -2 4318 a SDict begin 13 H.A end -2 4318 a -2 4318 a SDict begin [/View [/XYZ H.V]/Dest (0:304) cvn /DEST pdfmark end -2 4318 a 396 4424 a Fj(Y)-9 b(ou)20 b(can)g(o)o(v)o(erride)e(the)i(def)o(ault)f(vie)n(w)h (of)g(a)h(directory)d(as)j(generated)e(by)2540 4424 y SDict begin H.S end 2540 4424 a 2540 4424 a SDict begin 13 H.A end 2540 4424 a 2540 4424 a SDict begin [/View [/XYZ H.V]/Dest (0:305) cvn /DEST pdfmark end 2540 4424 a Fj(dir)-5 b(.DirHandler)18 b(by)i(creating)f(what)h(are)396 4532 y(kno)n(wn)f(as)731 4532 y SDict begin H.S end 731 4532 a 731 4532 a SDict begin 13 H.A end 731 4532 a 731 4532 a SDict begin [/View [/XYZ H.V]/Dest (0:306) cvn /DEST pdfmark end 731 4532 a Fi(Links)i Fj(in)f(the)g(data)g(tree.) -2 4699 y SDict begin H.S end -2 4699 a -2 4699 a SDict begin 13 H.A end -2 4699 a -2 4699 a SDict begin [/View [/XYZ H.V]/Dest (0:307) cvn /DEST pdfmark end -2 4699 a 396 4806 a Fj(The)g(ability)g(to)g(mak)o(e)g(links)g(to)h(other) e(hosts)i(is)g(ho)n(w)e(gopher)g(distrib)n(utes)h(itself)g(among)f (multiple)h(hosts.)g(There)f(are)396 4914 y(tw)o(o)i(dif)n(ferent)d(w)o (ays)j(to)f(mak)o(e)g(a)g(link.)g(The)g(\002rst)h(and)f(simplest)g(is)h (to)g(create)f(a)g(link)g(\002le)h(that)f(contains)g(the)g(data)396 5022 y(needed)f(by)h(the)g(serv)o(er)-5 b(.)20 b(By)g(def)o(ault)g(all) h(\002les)g(in)f(the)g(gopher)f(data)h(directory)e(starting)i(with)g(a) h(period)e(are)h(tak)o(en)g(to)p Black 3800 5569 a Fi(11)p Black eop end %%Page: 12 15 TeXDict begin 12 14 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.12) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black 396 72 a Fj(be)g(link)g(\002les.)h(A)g(link) f(\002le)h(can)f(contain)f(multiple)g(links.)h(T)-7 b(o)21 b(de\002ne)e(a)i(link)f(you)f(need)h(to)g(put)g(\002)n(v)o(e)g(lines)h (in)f(a)g(link)g(\002le)396 180 y(that)h(de\002ne)e(the)h(needed)f (characteristics)h(for)f(the)i(document.)d(Here)i(is)h(an)f(e)o(xample) f(of)h(a)g(link.)396 361 y Fe(Name=Cheese)43 b(Ball)h(Recipes)396 458 y(Numb=1)396 555 y(Type=1)396 652 y(Port=150)396 749 y(Path=1/Moo/Cheesy)396 846 y(Host=zippy.micro.umn.edu)-2 1109 y SDict begin H.S end -2 1109 a -2 1109 a SDict begin 13 H.A end -2 1109 a -2 1109 a SDict begin [/View [/XYZ H.V]/Dest (0:309) cvn /DEST pdfmark end -2 1109 a 396 1217 a Fj(The)20 b(Name=)g(line)g(is)h(what)g(the)f(user)g(will)h (see)f(when)g(cruising)f(through)f(the)j(database.)e(In)h(this)h(case)f (the)g(name)g(is)396 1325 y("Cheese)g(Ball)g(Recipes".)g(The)f("T)-7 b(ype=")19 b(de\002nes)g(what)g(kind)g(of)g(document)f(this)i(object)f (is.)h(F)o(or)f(a)h(list)g(of)g(all)g(de\002ned)396 1433 y(types,)g(see)h(Gopher)e(Item)g(T)-7 b(ypes)20 b(belo)n(w)-5 b(.)19 b(F)o(or)h(Gopher+)f(and)g(HTTP)-9 b(,)20 b(a)h(MIME)f(type)f (is)j(also)e(used,)g(which)f(is)396 1541 y(determined)g(automatically)f (based)i(on)g(the)g(type)g(you)f(specify)-5 b(.)-2 1725 y SDict begin H.S end -2 1725 a -2 1725 a SDict begin 13 H.A end -2 1725 a -2 1725 a SDict begin [/View [/XYZ H.V]/Dest (0:310) cvn /DEST pdfmark end -2 1725 a 396 1815 a Fj(The)20 b("P)o(ath=")g(line)g(contains)g(the)g(selector)g (string)g(that)g(the)g(client)g(will)h(use)g(to)f(retrie)n(v)o(e)f(the) h(actual)g(document.)e(The)396 1923 y(Numb=)h(speci\002es)i(that)f (this)h(entry)e(should)h(be)g(presented)f(\002rst)i(in)f(the)g (directory)f(list)i(\(instead)e(of)h(being)396 2031 y(alphabetized\).)e (The)i("Numb=")f(line)h(is)h(optional.)e(If)h(it)h(is)g(present)e(it)i (cannot)e(be)i(the)f(last)h(line)f(of)g(the)g(link.)g(The)396 2139 y("Host=")g(and)g("Port=")g(lines)g(specify)g(a)g(fully)g (quali\002ed)f(domain)g(name)h(\(FQDN\))g(and)f(a)i(port)f(respecti)n (v)o(ely)-5 b(.)18 b(Y)-9 b(ou)396 2247 y(may)20 b(substitute)g(a)h (plus)f('+')g(for)f(these)i(tw)o(o)f(parameters)f(if)i(you)e(wish.)h (The)g(serv)o(er)f(will)i(insert)f(the)h(current)396 2355 y(hostname)e(and)h(the)g(current)f(port)g(when)h(it)h(sees)g(a)g (plus)f(in)g(either)g(of)g(these)g(tw)o(o)h(\002elds.)-2 2539 y SDict begin H.S end -2 2539 a -2 2539 a SDict begin 13 H.A end -2 2539 a -2 2539 a SDict begin [/View [/XYZ H.V]/Dest (0:311) cvn /DEST pdfmark end -2 2539 a 396 2629 a Fj(An)f(easy)h(w)o(ay)f(to)g(retrie)n(v)o(e)f(links)i(is)g (to)f(use)g(the)h(Curses)f(Gopher)f(Client.)i(By)f(pressing)g('=')g(Y) -9 b(ou)19 b(can)h(get)396 2737 y(information)e(suitable)i(for)g (inclusion)f(in)h(a)h(link)f(\002le.)-2 2748 y SDict begin H.S end -2 2748 a -2 2748 a SDict begin 13 H.A end -2 2748 a -2 2748 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN.OVERRIDING) cvn /DEST pdfmark end -2 2748 a 396 3075 a Fb(5.9.2.)36 b(Overriding)d(Defaults)1836 3075 y SDict begin H.S end 1836 3075 a 1836 3075 a SDict begin 18.72 H.A end 1836 3075 a 1836 3075 a SDict begin [/View [/XYZ H.V]/Dest (7.14.2.2) cvn /DEST pdfmark end 1836 3075 a -2 3268 a SDict begin H.S end -2 3268 a -2 3268 a SDict begin 13 H.A end -2 3268 a -2 3268 a SDict begin [/View [/XYZ H.V]/Dest (0:314) cvn /DEST pdfmark end -2 3268 a 396 3349 a Fj(The)19 b(serv)o(er)f(looks)g(for)g(a)h(directory)e (called)1674 3349 y SDict begin H.S end 1674 3349 a 1674 3349 a SDict begin 13 H.A end 1674 3349 a 1674 3349 a SDict begin [/View [/XYZ H.V]/Dest (0:315) cvn /DEST pdfmark end 1674 3349 a Fe(.cap)h Fj(when)g(parsing)g(a)h(directory) -5 b(.)17 b(The)h(serv)o(er)g(then)g(checks)g(to)h(see)h(if)f(the)396 3457 y SDict begin H.S end 396 3457 a 396 3457 a SDict begin 13 H.A end 396 3457 a 396 3457 a SDict begin [/View [/XYZ H.V]/Dest (0:316) cvn /DEST pdfmark end 396 3457 a Fe(.cap)h Fj(directory)f(contains)g(a)i(\002le)g(with)f(the)g (same)h(name)e(as)i(the)f(\002le)h(it')-5 b(s)22 b(parsing.)c(If)i (this)h(\002le)g(e)o(xists)g(then)e(the)i(serv)o(er)396 3565 y(will)g(open)e(it)i(for)f(reading.)e(The)i(serv)o(er)f(parses)i (this)f(\002le)h(just)g(lik)o(e)f(a)h(link)f(\002le.)h(Ho)n(we)n(v)o (er)m(,)d(instead)i(of)g(making)e(a)j(ne)n(w)396 3673 y(object,)e(the)h(parameters)e(inside)i(the)1486 3673 y SDict begin H.S end 1486 3673 a 1486 3673 a SDict begin 13 H.A end 1486 3673 a 1486 3673 a SDict begin [/View [/XYZ H.V]/Dest (0:317) cvn /DEST pdfmark end 1486 3673 a Fe(.cap/)f Fj(\002le)i(are)e(used)h(to)f(o)o(v)o(erride)f(an)o (y)g(of)i(the)f(serv)o(er)g(supplied)g(def)o(ault)f(v)n(alues.)-2 3857 y SDict begin H.S end -2 3857 a -2 3857 a SDict begin 13 H.A end -2 3857 a -2 3857 a SDict begin [/View [/XYZ H.V]/Dest (0:318) cvn /DEST pdfmark end -2 3857 a 396 3947 a Fj(F)o(or)i(instance,)g(say)g(you)f(w)o(anted)h(to)g (change)f(the)h(T)m(itle)h(of)f(a)h(te)o(xt)f(\002le)h(for)e(gopher)m (,)f(b)n(ut)i(don')o(t)f(w)o(ant)h(to)g(change)f(the)396 4055 y(\002lename.)h(Y)-9 b(ou)19 b(also)i(don')o(t)d(w)o(ant)j(it)g (alphabetized,)d(instead)i(you)f(w)o(ant)h(it)h(second)e(in)i(the)f (directory)e(listing.)j(Y)-9 b(ou)396 4163 y(could)19 b(mak)o(e)h(a)h(set-aside)f(\002le)h(in)f(the)1505 4163 y SDict begin H.S end 1505 4163 a 1505 4163 a SDict begin 13 H.A end 1505 4163 a 1505 4163 a SDict begin [/View [/XYZ H.V]/Dest (0:319) cvn /DEST pdfmark end 1505 4163 a Fe(.cap)g Fj(directory)e(with)i(the)h(same)f(\002lename)g(that)g (contained)e(the)j(follo)n(wing)396 4271 y(lines:)-2 4355 y SDict begin H.S end -2 4355 a -2 4355 a SDict begin 11.7 H.A end -2 4355 a -2 4355 a SDict begin [/View [/XYZ H.V]/Dest (0:320) cvn /DEST pdfmark end -2 4355 a 396 4451 a Fe(Name=New)44 b(Long)g(Cool)g(Name)396 4548 y(Numb=2)-2 4811 y SDict begin H.S end -2 4811 a -2 4811 a SDict begin 13 H.A end -2 4811 a -2 4811 a SDict begin [/View [/XYZ H.V]/Dest (0:321) cvn /DEST pdfmark end -2 4811 a 396 4919 a Fj(An)20 b(alternati)n(v)o(e)f(to)972 4919 y SDict begin H.S end 972 4919 a 972 4919 a SDict begin 13 H.A end 972 4919 a 972 4919 a SDict begin [/View [/XYZ H.V]/Dest (0:322) cvn /DEST pdfmark end 972 4919 a Fe(.cap)h Fj(\002les)h(are)f(e)o(xtended)e(link)i(\002les.)h (The)o(y)e(w)o(ork)h(just)g(the)h(same)f(as)h(the)f(\002les)h (described)e(in)396 5027 y(Links)h(abo)o(v)o(e,)e(b)n(ut)j(ha)n(v)o(e)e (a)i(some)n(what)e(abbre)n(viated)f(format.)h(As)i(an)f(e)o(xample,)f (if)h(the)g(name)g(of)g(the)g(\002le)h(w)o(as)396 5135 y SDict begin H.S end 396 5135 a 396 5135 a SDict begin 13 H.A end 396 5135 a 396 5135 a SDict begin [/View [/XYZ H.V]/Dest (0:323) cvn /DEST pdfmark end 396 5135 a Fe(file-to-change)p Fj(,)d(then)i(you)f(could)h(create)g(a)g(\002le)h (called)2202 5135 y SDict begin H.S end 2202 5135 a 2202 5135 a SDict begin 13 H.A end 2202 5135 a 2202 5135 a SDict begin [/View [/XYZ H.V]/Dest (0:324) cvn /DEST pdfmark end 2202 5135 a Fe(.names)f Fj(with)g(the)g(follo)n(wing)f (contents:)p Black 3800 5569 a Fi(12)p Black eop end %%Page: 13 16 TeXDict begin 13 15 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.13) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 11.7 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:325) cvn /DEST pdfmark end -2 -11 a 396 72 a Fe(Path=./file-to-change)396 170 y(Name=New)44 b(Long)g(Cool)g(Name)396 267 y(Numb=2)-2 447 y SDict begin H.S end -2 447 a -2 447 a SDict begin 13 H.A end -2 447 a -2 447 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN.COOL) cvn /DEST pdfmark end -2 447 a 396 775 a Fb(5.9.3.)36 b(Ad)o(ding)d(Cool)h(Links)1782 775 y SDict begin H.S end 1782 775 a 1782 775 a SDict begin 18.72 H.A end 1782 775 a 1782 775 a SDict begin [/View [/XYZ H.V]/Dest (7.14.3.2) cvn /DEST pdfmark end 1782 775 a -2 968 a SDict begin H.S end -2 968 a -2 968 a SDict begin 13 H.A end -2 968 a -2 968 a SDict begin [/View [/XYZ H.V]/Dest (0:328) cvn /DEST pdfmark end -2 968 a 396 1049 a Fj(One)20 b(cool)g(thing)f(you)h(can)g(do)g(with)g(.Links) g(is)h(to)f(add)g(neato)f(services)h(to)h(your)e(gopher)f(serv)o(er)-5 b(.)20 b(Adding)e(a)j(link)f(lik)o(e)396 1157 y(this:)-2 1241 y SDict begin H.S end -2 1241 a -2 1241 a SDict begin 11.7 H.A end -2 1241 a -2 1241 a SDict begin [/View [/XYZ H.V]/Dest (0:329) cvn /DEST pdfmark end -2 1241 a 396 1337 a Fe(Name=Cool)44 b(ftp)g(directory)396 1434 y(Type=h)396 1531 y(Path=/URL:ftp://hostname/path/)396 1628 y(Host=+)396 1726 y(Port=+)396 1920 y(Name=Cool)g(web)g(site)396 2017 y(Type=h)396 2114 y(Path=/URL:http://hostname/)396 2211 y(Host=+)396 2308 y(Port=+)-2 2572 y SDict begin H.S end -2 2572 a -2 2572 a SDict begin 13 H.A end -2 2572 a -2 2572 a SDict begin [/View [/XYZ H.V]/Dest (0:330) cvn /DEST pdfmark end -2 2572 a 396 2680 a Fj(W)m(ill)21 b(allo)n(w)f(you)g(to)g(link)g(in)g(an)o(y)g(FTP)h(or)e(W)-7 b(eb)21 b(site)g(to)g(your)e(gopher)-5 b(.)18 b(\(See)i(url.URLHandler) f(for)g(more)h(details.\))-2 2864 y SDict begin H.S end -2 2864 a -2 2864 a SDict begin 13 H.A end -2 2864 a -2 2864 a SDict begin [/View [/XYZ H.V]/Dest (0:331) cvn /DEST pdfmark end -2 2864 a 396 2954 a Fj(Y)-9 b(ou)20 b(can)g(easily)g(add)g(a)h(\002nger)e(site)i(to)f(your)f(gopher)g(serv) o(er)g(thusly:)-2 3055 y SDict begin H.S end -2 3055 a -2 3055 a SDict begin 11.7 H.A end -2 3055 a -2 3055 a SDict begin [/View [/XYZ H.V]/Dest (0:332) cvn /DEST pdfmark end -2 3055 a 396 3134 a Fe(Name=Finger)43 b(information)396 3231 y(Type=0)396 3328 y(Path=lindner)396 3425 y (Host=mudhoney.micro.umn.edu)396 3522 y(Port=79)-2 3702 y SDict begin H.S end -2 3702 a -2 3702 a SDict begin 13 H.A end -2 3702 a -2 3702 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN.HIDING) cvn /DEST pdfmark end -2 3702 a 396 4030 a Fb(5.9.4.)36 b(Hiding)e(an)g(Entr)q(y)1614 4030 y SDict begin H.S end 1614 4030 a 1614 4030 a SDict begin 18.72 H.A end 1614 4030 a 1614 4030 a SDict begin [/View [/XYZ H.V]/Dest (7.14.4.2) cvn /DEST pdfmark end 1614 4030 a -2 4223 a SDict begin H.S end -2 4223 a -2 4223 a SDict begin 13 H.A end -2 4223 a -2 4223 a SDict begin [/View [/XYZ H.V]/Dest (0:335) cvn /DEST pdfmark end -2 4223 a 396 4304 a Fj(This)21 b(kind)e(of)h(trick)g(may)g(be)g (necessary)f(in)h(some)h(cases,)f(and)g(thus)g(for)g(object)f("fred",)g (the)h(o)o(v)o(erriding)d(.names)j(\002le)396 4412 y(entry)g(w)o(ould)f (be:)-2 4513 y SDict begin H.S end -2 4513 a -2 4513 a SDict begin 11.7 H.A end -2 4513 a -2 4513 a SDict begin [/View [/XYZ H.V]/Dest (0:336) cvn /DEST pdfmark end -2 4513 a 396 4593 a Fe(Type=X)396 4690 y(Path=./fred)-2 4953 y SDict begin H.S end -2 4953 a -2 4953 a SDict begin 13 H.A end -2 4953 a -2 4953 a SDict begin [/View [/XYZ H.V]/Dest (0:337) cvn /DEST pdfmark end -2 4953 a 396 5061 a Fj(by)h(o)o(v)o(erriding)d(def)o(ault)j(type)f(to)i(be)f ("X".)g(This)g(may)g(be)g(useful,)g(when)f(for)h(some)g(reason)f(there) h(are)g(symlinks)g(\(or)396 5169 y(whate)n(v)o(er\))e(in)i(the)g (directory)e(at)i(which)1575 5169 y SDict begin H.S end 1575 5169 a 1575 5169 a SDict begin 13 H.A end 1575 5169 a 1575 5169 a SDict begin [/View [/XYZ H.V]/Dest (0:338) cvn /DEST pdfmark end 1575 5169 a Fj(PyGopherd)e(looks,)h(and) g(those)h(entries)f(are)h(not)f(desired)h(to)f(be)h(sho)n(wn)f(at)h (all.)p Black 3800 5569 a Fi(13)p Black eop end %%Page: 14 17 TeXDict begin 14 16 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.14) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.UMN.ABSTRACTS) cvn /DEST pdfmark end -2 -11 a 396 77 a Fb(5.9.5.)36 b(Abstracts)e(and)g (Inf)n(o)1776 77 y SDict begin H.S end 1776 77 a 1776 77 a SDict begin 18.72 H.A end 1776 77 a 1776 77 a SDict begin [/View [/XYZ H.V]/Dest (7.14.5.2) cvn /DEST pdfmark end 1776 77 a -2 244 a SDict begin H.S end -2 244 a -2 244 a SDict begin 13 H.A end -2 244 a -2 244 a SDict begin [/View [/XYZ H.V]/Dest (0:341) cvn /DEST pdfmark end -2 244 a 396 351 a Fj(Man)o(y)19 b(modern)g(gopher)f(serv)o(er)h (maintainers)h(lik)o(e)g(to)g(intersperse)g(gopher)e(directory)h (listings)h(with)h(other)396 459 y(information)d(--)i(often,)f (additional)g(information)f(about)h(the)h(contents)g(of)g(\002les)h(in) f(the)g(directory)-5 b(.)18 b(The)i(gophermap)396 566 y(system)h(pro)o(vides)d(one)i(w)o(ay)g(to)g(do)g(that,)g(and)g (abstracts)g(used)g(with)g(UMN)h(gopher)d(directories)h(pro)o(vides)g (another)-5 b(.)-2 751 y SDict begin H.S end -2 751 a -2 751 a SDict begin 13 H.A end -2 751 a -2 751 a SDict begin [/View [/XYZ H.V]/Dest (0:342) cvn /DEST pdfmark end -2 751 a 396 840 a Fj(Subject)20 b(to)g(the)874 840 y SDict begin H.S end 874 840 a 874 840 a SDict begin 13 H.A end 874 840 a 874 840 a SDict begin [/View [/XYZ H.V]/Dest (0:343) cvn /DEST pdfmark end 874 840 a Fj(abstract_headers)e(and)1588 840 y SDict begin H.S end 1588 840 a 1588 840 a SDict begin 13 H.A end 1588 840 a 1588 840 a SDict begin [/View [/XYZ H.V]/Dest (0:344) cvn /DEST pdfmark end 1588 840 a Fj(abstract_entries)h (con\002guration)f(\002le)i(options,)f(this)i(feature)e(allo)n(ws)i (you)e(to)396 948 y(de\002ne)h(that)g(e)o(xtra)g(information.)d(Y)-9 b(ou)20 b(can)g(do)g(that)g(by)g(simply)f(creating)h(a)g(\002le)h (named)2989 948 y SDict begin H.S end 2989 948 a 2989 948 a SDict begin 13 H.A end 2989 948 a 2989 948 a SDict begin [/View [/XYZ H.V]/Dest (0:345) cvn /DEST pdfmark end 2989 948 a Fe(filename.abstract)396 1056 y Fj(right)f(alongside)f (the)h(re)o(gular)f(\002le)i(in)f(your)f(directory)-5 b(.)18 b(The)h(\002le)i(will)g(be)f(interpreted)f(as)i(the)f(abstract.) g(F)o(or)f(a)396 1164 y(directory)-5 b(,)18 b(create)i(a)h(\002le)f (named)1378 1164 y SDict begin H.S end 1378 1164 a 1378 1164 a SDict begin 13 H.A end 1378 1164 a 1378 1164 a SDict begin [/View [/XYZ H.V]/Dest (0:346) cvn /DEST pdfmark end 1378 1164 a Fe(.abstract)f Fj(in)h(the)g(directory)-5 b(.)18 b(Simple)i(as)h(that!)-2 1276 y SDict begin H.S end -2 1276 a -2 1276 a SDict begin 13 H.A end -2 1276 a -2 1276 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.HTMLURLHANDLER) cvn /DEST pdfmark end -2 1276 a 359 x Fh(5.10.)39 b(url.HTMLURLHandler) 1813 1635 y SDict begin H.S end 1813 1635 a 1813 1635 a SDict begin 22.464 H.A end 1813 1635 a 1813 1635 a SDict begin [/View [/XYZ H.V]/Dest (7.15.1) cvn /DEST pdfmark end 1813 1635 a -2 1803 a SDict begin H.S end -2 1803 a -2 1803 a SDict begin 13 H.A end -2 1803 a -2 1803 a SDict begin [/View [/XYZ H.V]/Dest (0:349) cvn /DEST pdfmark end -2 1803 a -2 1803 a SDict begin H.S end -2 1803 a -2 1803 a SDict begin 13 H.A end -2 1803 a -2 1803 a SDict begin [/View [/XYZ H.V]/Dest (0:350) cvn /DEST pdfmark end -2 1803 a 396 1909 a Fj(PyGopherd)18 b(pro)o(vides)h(w)o(ays)h(for)g(you)f(to)h(link)g(to)h(pages)e(outside) h(Gopherspace)e(--)i(that)g(is,)h(web)f(pages,)g(FTP)h(sites,)396 2017 y(and)f(the)g(lik)o(e.)g(This)h(is)g(accomplished)d(according)g (to)j(the)2102 2017 y SDict begin H.S end 2102 2017 a 2102 2017 a SDict begin 13 H.A end 2102 2017 a 2102 2017 a SDict begin [/View [/XYZ H.V]/Dest (0:351) cvn /DEST pdfmark end 2102 2017 a Fj(Links)f(to)g(URL)396 2125 y(\(http://lists.complete.or)o(g/gopher@com)o(plete.)o(or)n(g/2)o(00)o (2/0)o(2/m)o(sg00)o(03)o(3.h)o(tml.g)o(z\))14 b(speci\002cation)20 b(\(see)396 2233 y(Conforming)e(T)-7 b(o)20 b(belo)n(w)g(for)f (details\).)h(In)g(order)f(to)i(link)e(to)i(a)f(URL)h(\(EXCEPT)f (gopher)f(URLs\))h(from)f(a)i(menu,)e(you)396 2340 y(create)h(a)h(link) f(of)g(type)f(h)i(\(re)o(gardless)d(of)i(the)g(actual)g(type)g(of)g (the)g(resource)f(that)h(you)f(are)i(linking)e(to\))h(in)g(your)396 2448 y SDict begin H.S end 396 2448 a 396 2448 a SDict begin 13 H.A end 396 2448 a 396 2448 a SDict begin [/View [/XYZ H.V]/Dest (0:352) cvn /DEST pdfmark end 396 2448 a Fe(gophermap)g Fj(or)910 2448 y SDict begin H.S end 910 2448 a 910 2448 a SDict begin 13 H.A end 910 2448 a 910 2448 a SDict begin [/View [/XYZ H.V]/Dest (0:353) cvn /DEST pdfmark end 910 2448 a Fe(.Links)g Fj(\002le)h(that)f (looks)g(lik)o(e)g(this:)-2 2543 y SDict begin H.S end -2 2543 a -2 2543 a SDict begin 11.7 H.A end -2 2543 a -2 2543 a SDict begin [/View [/XYZ H.V]/Dest (0:354) cvn /DEST pdfmark end -2 2543 a 396 2629 a Fe (/URL:http://www.complete.org/)-2 2892 y SDict begin H.S end -2 2892 a -2 2892 a SDict begin 13 H.A end -2 2892 a -2 2892 a SDict begin [/View [/XYZ H.V]/Dest (0:355) cvn /DEST pdfmark end -2 2892 a 396 3000 a Fj(Modern)f(Gopher)g (clients)h(that)g(follo)n(w)g(the)g(Links)g(to)g(URL)h(speci\002cation) f(will)g(automatically)f(follo)n(w)h(that)g(link)396 3108 y(when)g(you)f(select)i(it.)g(The)e(rest)i(need)f(some)g(help,)f (and)h(that')-5 b(s)20 b(where)g(this)h(handler)d(comes)i(in.)-2 3292 y SDict begin H.S end -2 3292 a -2 3292 a SDict begin 13 H.A end -2 3292 a -2 3292 a SDict begin [/View [/XYZ H.V]/Dest (0:356) cvn /DEST pdfmark end -2 3292 a 396 3382 a Fj(F)o(or)g(Gopher)f(clients)h(that)h(do)e(not)h(follo)n (w)g(the)g(Links)g(to)g(URL)h(speci\002cation,)e(the)2837 3382 y SDict begin H.S end 2837 3382 a 2837 3382 a SDict begin 13 H.A end 2837 3382 a 2837 3382 a SDict begin [/View [/XYZ H.V]/Dest (0:357) cvn /DEST pdfmark end 2837 3382 a Fj(url.HTMLURLHandler)f(will)396 3489 y(automatically)h (generate)g(an)h(HTML)g(document)e(for)i(them)g(on)f(the)i(\003y)-5 b(.)19 b(This)i(document)d(includes)h(a)i(refresh)e(code)396 3597 y(that)i(will)f(send)g(them)g(to)h(the)f(proper)e(page.)h(Y)-9 b(ou)20 b(should)f(not)h(disable)g(this)h(handler)-5 b(.)-2 3626 y SDict begin H.S end -2 3626 a -2 3626 a SDict begin 13 H.A end -2 3626 a -2 3626 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.URLTYPEREWRITER) cvn /DEST pdfmark end -2 3626 a 359 x Fh(5.11.)39 b(url.URL)-13 b(T)k(ypeRe)n(writer)1765 3985 y SDict begin H.S end 1765 3985 a 1765 3985 a SDict begin 22.464 H.A end 1765 3985 a 1765 3985 a SDict begin [/View [/XYZ H.V]/Dest (7.16.1) cvn /DEST pdfmark end 1765 3985 a -2 4181 a SDict begin H.S end -2 4181 a -2 4181 a SDict begin 13 H.A end -2 4181 a -2 4181 a SDict begin [/View [/XYZ H.V]/Dest (0:360) cvn /DEST pdfmark end -2 4181 a 396 4259 a Fj(Some)20 b(people)f(wish)i(to)f(serv)o (e)g(HTML)g(documents)e(from)h(their)h(Gopher)f(serv)o(er)-5 b(.)20 b(One)g(problem)e(with)j(that)f(is)h(that)396 4367 y(links)f(in)h(Gopherspace)d(include)h(an)h(e)o(xtra)g(type)f (character)g(at)i(the)f(be)o(ginning,)e(whereas)h(links)i(in)f(HTTP)g (do)g(not.)396 4475 y(This)h(handler)d(will)j(remo)o(v)o(e)e(the)h(e)o (xtra)f(type)h(character)f(from)g(HTTP)h(requests)g(that)g(come)g(in,)g (allo)n(wing)f(a)i(single)396 4583 y(relati)n(v)o(e-to-root)c(link)j (to)h(w)o(ork)e(for)h(both.)-2 4594 y SDict begin H.S end -2 4594 a -2 4594 a SDict begin 13 H.A end -2 4594 a -2 4594 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.VIRTUAL) cvn /DEST pdfmark end -2 4594 a Black 3800 5569 a Fi(14)p Black eop end %%Page: 15 18 TeXDict begin 15 17 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.15) cvn /DEST pdfmark end -611 -810 a Black Black 3199 -132 a Fi(Chapter)20 b(5.)g(Handler)o(s)p Black -2 94 a Fh(5.12.)39 b(vir)s(tual.Vir)s(tual) 1283 94 y SDict begin H.S end 1283 94 a 1283 94 a SDict begin 22.464 H.A end 1283 94 a 1283 94 a SDict begin [/View [/XYZ H.V]/Dest (7.17.1) cvn /DEST pdfmark end 1283 94 a -2 262 a SDict begin H.S end -2 262 a -2 262 a SDict begin 13 H.A end -2 262 a -2 262 a SDict begin [/View [/XYZ H.V]/Dest (0:363) cvn /DEST pdfmark end -2 262 a 396 368 a Fj(This)21 b(handler)d(is)j(not)f(intended)f(to)h(e)n (v)o(er)g(be)g(used)g(directly)-5 b(,)18 b(b)n(ut)j(is)g(used)f(by)g (man)o(y)f(other)g(handlers)g(such)h(as)h(the)396 476 y(mbox)d(support,)g(PYG)i(handlers,)e(and)h(others.)g(It)h(is)g(used)f (to)h(generate)e(virtual)h(entries)g(in)h(the)f(directory)f(hierarchy)f (--)396 584 y(that)k(is,)f(entries)h(that)f(look)f(normal)g(to)h(a)h (client,)f(b)n(ut)g(do)g(not)g(actually)g(correspond)d(to)j(a)h(\002le) g(on)f(disk.)-2 768 y SDict begin H.S end -2 768 a -2 768 a SDict begin 13 H.A end -2 768 a -2 768 a SDict begin [/View [/XYZ H.V]/Dest (0:364) cvn /DEST pdfmark end -2 768 a 396 858 a Fj(One)g(special)h(feature)e(of)h(the)1270 858 y SDict begin H.S end 1270 858 a 1270 858 a SDict begin 13 H.A end 1270 858 a 1270 858 a SDict begin [/View [/XYZ H.V]/Dest (0:365) cvn /DEST pdfmark end 1270 858 a Fj(virtual.V)-5 b(irtual)18 b(handler)h(is)i(that)g(you)e(can)h (send)g(information)e(to)i(it)h(at)g(runtime)e(in)h(a)396 966 y(manner)f(similar)h(to)h(a)f(CGI)h(script)f(on)g(the)g(web)m(.)g (Y)-9 b(ou)19 b(do)h(this)h(by)f(adding)e(a)j(question)e(mark)g(after)h (the)h(re)o(gular)396 1074 y(selector)m(,)f(follo)n(wed)e(by)i(an)o(y)g (arbitrary)e(data)i(that)h(you)e(wish)h(to)h(ha)n(v)o(e)e(sent)i(to)f (the)g(virtual)g(request)g(handler)-5 b(.)-2 1102 y SDict begin H.S end -2 1102 a -2 1102 a SDict begin 13 H.A end -2 1102 a -2 1102 a SDict begin [/View [/XYZ H.V]/Dest (0:HANDLERS.ZIP) cvn /DEST pdfmark end -2 1102 a 359 x Fh(5.13.)39 b(ZIP)-17 b(.ZIPHandler)1364 1461 y SDict begin H.S end 1364 1461 a 1364 1461 a SDict begin 22.464 H.A end 1364 1461 a 1364 1461 a SDict begin [/View [/XYZ H.V]/Dest (7.18.1) cvn /DEST pdfmark end 1364 1461 a -2 1629 a SDict begin H.S end -2 1629 a -2 1629 a SDict begin 13 H.A end -2 1629 a -2 1629 a SDict begin [/View [/XYZ H.V]/Dest (0:368) cvn /DEST pdfmark end -2 1629 a 396 1735 a Fj(Using)20 b(zip.ZIPHandler)m(,)e(you)h(can)h(sa)n (v)o(e)g(space)h(on)e(your)g(serv)o(er)h(by)f(con)m(v)o(erting)f(part)h (or)h(all)h(of)f(your)f(site)i(into)f(a)h(ZIP)396 1843 y(\002le.)544 1843 y SDict begin H.S end 544 1843 a 544 1843 a SDict begin 13 H.A end 544 1843 a 544 1843 a SDict begin [/View [/XYZ H.V]/Dest (0:369) cvn /DEST pdfmark end 544 1843 a Fj(PyGopherd)d(can)i(use)g(the)g(contents)g(of)g (that)g(ZIP)g(\002le)h(as)g(the)f(contents)g(of)g(your)f(site)i(--)f (completely)396 1951 y(transparently)-5 b(.)-2 2135 y SDict begin H.S end -2 2135 a -2 2135 a SDict begin 13 H.A end -2 2135 a -2 2135 a SDict begin [/View [/XYZ H.V]/Dest (0:370) cvn /DEST pdfmark end -2 2135 a 396 2225 a Fj(The)20 b(ZIP)g(\002le)h(handler)e(must)h(be)g(enabled)f(in)i (the)f(con\002guration)d(\002le)k(for)f(this)h(to)f(w)o(ork.)p Black 3800 5569 a Fi(15)p Black eop end %%Page: 16 19 TeXDict begin 16 18 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.16) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:TYPES) cvn /DEST pdfmark end -2 -11 a 126 x Fl(Chapter)48 b(6.)f(Gopher)h(Item)g(T)-10 b(ypes)2437 115 y SDict begin H.S end 2437 115 a 2437 115 a SDict begin 26.957 H.A end 2437 115 a 2437 115 a SDict begin [/View [/XYZ H.V]/Dest (8.0) cvn /DEST pdfmark end 2437 115 a -2 371 a SDict begin H.S end -2 371 a -2 371 a SDict begin 13 H.A end -2 371 a -2 371 a SDict begin [/View [/XYZ H.V]/Dest (0:373) cvn /DEST pdfmark end -2 371 a 396 443 a Fj(When)20 b(you)g(construct)f(links)h(to)g(\002les)h(via)1635 443 y SDict begin H.S end 1635 443 a 1635 443 a SDict begin 13 H.A end 1635 443 a 1635 443 a SDict begin [/View [/XYZ H.V]/Dest (0:374) cvn /DEST pdfmark end 1635 443 a Fe(.Links)e Fj(or)2014 443 y SDict begin H.S end 2014 443 a 2014 443 a SDict begin 13 H.A end 2014 443 a 2014 443 a SDict begin [/View [/XYZ H.V]/Dest (0:375) cvn /DEST pdfmark end 2014 443 a Fe(gophermap)h Fj(\002les,)g(or)g (modify)f(the)3091 443 y SDict begin H.S end 3091 443 a 3091 443 a SDict begin 13 H.A end 3091 443 a 3091 443 a SDict begin [/View [/XYZ H.V]/Dest (0:376) cvn /DEST pdfmark end 3091 443 a Fj(mapping)f(in)j(the)396 551 y(con\002guration)d(\002le,)i(you)g(will)h(need)e(to)h(kno)n(w)g (these.)g(Items)g(bearing)f(the)h("not)g(implemented")e(te)o(xt)i(are)g (not)g(serv)o(ed)396 659 y(up)g(by)604 659 y SDict begin H.S end 604 659 a 604 659 a SDict begin 13 H.A end 604 659 a 604 659 a SDict begin [/View [/XYZ H.V]/Dest (0:377) cvn /DEST pdfmark end 604 659 a Fj(PyGopherd)e(as)j(it)g (ships,)f(generally)e(due)i(to)g(requirements)f(of)h(customized)e(per)n (-site)j(softw)o(are,)e(b)n(ut)h(may)g(be)396 767 y(serv)o(ed)f(up)h (via)g(PYG)h(e)o(xtension)e(modules)g(or)h(other)f(gopher)g(serv)o (ers.)-2 951 y SDict begin H.S end -2 951 a -2 951 a SDict begin 13 H.A end -2 951 a -2 951 a SDict begin [/View [/XYZ H.V]/Dest (0:378) cvn /DEST pdfmark end -2 951 a 396 1041 a Fj(This)i(list)g(w)o(as)g(prepared)d(based)i(on)g (RFC1436,)f(the)h(UMN)h(gopherd\(1\))16 b(manpage,)j(and)g(best)i (current)e(practices.)-2 1059 y SDict begin H.S end -2 1059 a -2 1059 a SDict begin 13 H.A end -2 1059 a -2 1059 a SDict begin [/View [/XYZ H.V]/Dest (0:379) cvn /DEST pdfmark end -2 1059 a -2 1183 a SDict begin H.S end -2 1183 a -2 1183 a SDict begin 13 H.A end -2 1183 a -2 1183 a SDict begin [/View [/XYZ H.V]/Dest (0:381) cvn /DEST pdfmark end -2 1183 a 396 1273 a Fj(0)-2 1274 y SDict begin H.S end -2 1274 a -2 1274 a SDict begin 13 H.A end -2 1274 a -2 1274 a SDict begin [/View [/XYZ H.V]/Dest (0:382) cvn /DEST pdfmark end -2 1274 a Black Black 562 1422 a SDict begin H.S end 562 1422 a 562 1422 a SDict begin 13 H.A end 562 1422 a 562 1422 a SDict begin [/View [/XYZ H.V]/Dest (0:383) cvn /DEST pdfmark end 562 1422 a Fj(Plain)i(te)o(xt)f(\002le)-2 1506 y SDict begin H.S end -2 1506 a -2 1506 a SDict begin 13 H.A end -2 1506 a -2 1506 a SDict begin [/View [/XYZ H.V]/Dest (0:385) cvn /DEST pdfmark end -2 1506 a 396 1613 a Fj(1)-2 1613 y SDict begin H.S end -2 1613 a -2 1613 a SDict begin 13 H.A end -2 1613 a -2 1613 a SDict begin [/View [/XYZ H.V]/Dest (0:386) cvn /DEST pdfmark end -2 1613 a Black Black 562 1763 a SDict begin H.S end 562 1763 a 562 1763 a SDict begin 13 H.A end 562 1763 a 562 1763 a SDict begin [/View [/XYZ H.V]/Dest (0:387) cvn /DEST pdfmark end 562 1763 a Fj(Directory)-2 1864 y SDict begin H.S end -2 1864 a -2 1864 a SDict begin 13 H.A end -2 1864 a -2 1864 a SDict begin [/View [/XYZ H.V]/Dest (0:389) cvn /DEST pdfmark end -2 1864 a 396 1954 a Fj(2)-2 1954 y SDict begin H.S end -2 1954 a -2 1954 a SDict begin 13 H.A end -2 1954 a -2 1954 a SDict begin [/View [/XYZ H.V]/Dest (0:390) cvn /DEST pdfmark end -2 1954 a Black Black 562 2103 a SDict begin H.S end 562 2103 a 562 2103 a SDict begin 13 H.A end 562 2103 a 562 2103 a SDict begin [/View [/XYZ H.V]/Dest (0:391) cvn /DEST pdfmark end 562 2103 a Fj(CSO)i(phone)c(book)h (serv)o(er)g(\(not)h(implemented)e(by)2090 2103 y SDict begin H.S end 2090 2103 a 2090 2103 a SDict begin 13 H.A end 2090 2103 a 2090 2103 a SDict begin [/View [/XYZ H.V]/Dest (0:392) cvn /DEST pdfmark end 2090 2103 a Fj(PyGopherd\))-2 2204 y SDict begin H.S end -2 2204 a -2 2204 a SDict begin 13 H.A end -2 2204 a -2 2204 a SDict begin [/View [/XYZ H.V]/Dest (0:394) cvn /DEST pdfmark end -2 2204 a 396 2294 a Fj(3)-2 2295 y SDict begin H.S end -2 2295 a -2 2295 a SDict begin 13 H.A end -2 2295 a -2 2295 a SDict begin [/View [/XYZ H.V]/Dest (0:395) cvn /DEST pdfmark end -2 2295 a Black Black 562 2444 a SDict begin H.S end 562 2444 a 562 2444 a SDict begin 13 H.A end 562 2444 a 562 2444 a SDict begin [/View [/XYZ H.V]/Dest (0:396) cvn /DEST pdfmark end 562 2444 a Fj(Error)h(condition;)g(te)o(xt)h(that)g(follo)n(ws)g(is)h (plain)f(te)o(xt)-2 2545 y SDict begin H.S end -2 2545 a -2 2545 a SDict begin 13 H.A end -2 2545 a -2 2545 a SDict begin [/View [/XYZ H.V]/Dest (0:398) cvn /DEST pdfmark end -2 2545 a 396 2635 a Fj(4)-2 2635 y SDict begin H.S end -2 2635 a -2 2635 a SDict begin 13 H.A end -2 2635 a -2 2635 a SDict begin [/View [/XYZ H.V]/Dest (0:399) cvn /DEST pdfmark end -2 2635 a Black Black 562 2784 a SDict begin H.S end 562 2784 a 562 2784 a SDict begin 13 H.A end 562 2784 a 562 2784 a SDict begin [/View [/XYZ H.V]/Dest (0:400) cvn /DEST pdfmark end 562 2784 a Fj(Macintosh)g(\002le,)g(BinHe)o(x)g(format)-2 2879 y SDict begin H.S end -2 2879 a -2 2879 a SDict begin 13 H.A end -2 2879 a -2 2879 a SDict begin [/View [/XYZ H.V]/Dest (0:402) cvn /DEST pdfmark end -2 2879 a 396 2975 a Fj(5)-2 2976 y SDict begin H.S end -2 2976 a -2 2976 a SDict begin 13 H.A end -2 2976 a -2 2976 a SDict begin [/View [/XYZ H.V]/Dest (0:403) cvn /DEST pdfmark end -2 2976 a Black Black 562 3124 a SDict begin H.S end 562 3124 a 562 3124 a SDict begin 13 H.A end 562 3124 a 562 3124 a SDict begin [/View [/XYZ H.V]/Dest (0:404) cvn /DEST pdfmark end 562 3124 a Fj(DOS)h(binary)e(archi)n (v)o(e)g(\(not)g(implemented)g(by)1956 3124 y SDict begin H.S end 1956 3124 a 1956 3124 a SDict begin 13 H.A end 1956 3124 a 1956 3124 a SDict begin [/View [/XYZ H.V]/Dest (0:405) cvn /DEST pdfmark end 1956 3124 a Fj(PyGopherd;)f(use)j (type)e(9)i(instead\))-2 3225 y SDict begin H.S end -2 3225 a -2 3225 a SDict begin 13 H.A end -2 3225 a -2 3225 a SDict begin [/View [/XYZ H.V]/Dest (0:407) cvn /DEST pdfmark end -2 3225 a 396 3315 a Fj(6)-2 3316 y SDict begin H.S end -2 3316 a -2 3316 a SDict begin 13 H.A end -2 3316 a -2 3316 a SDict begin [/View [/XYZ H.V]/Dest (0:408) cvn /DEST pdfmark end -2 3316 a Black Black 562 3465 a SDict begin H.S end 562 3465 a 562 3465 a SDict begin 13 H.A end 562 3465 a 562 3465 a SDict begin [/View [/XYZ H.V]/Dest (0:409) cvn /DEST pdfmark end 562 3465 a Fj(uuencoded)d(\002le;)j(not)f(directly)f(generated)f (by)1941 3465 y SDict begin H.S end 1941 3465 a 1941 3465 a SDict begin 13 H.A end 1941 3465 a 1941 3465 a SDict begin [/View [/XYZ H.V]/Dest (0:410) cvn /DEST pdfmark end 1941 3465 a Fj(PyGopherd)g(automatically)-5 b(,)18 b(b)n(ut)i(can)g(be)g(link)o(ed)g(to)g(manually)-5 b(.)562 3573 y(Most)21 b(gopher)d(clients)j(will)g(handle)e(this)h(better)g(as) h(type)f(1.)-2 3674 y SDict begin H.S end -2 3674 a -2 3674 a SDict begin 13 H.A end -2 3674 a -2 3674 a SDict begin [/View [/XYZ H.V]/Dest (0:412) cvn /DEST pdfmark end -2 3674 a 396 3764 a Fj(7)-2 3765 y SDict begin H.S end -2 3765 a -2 3765 a SDict begin 13 H.A end -2 3765 a -2 3765 a SDict begin [/View [/XYZ H.V]/Dest (0:413) cvn /DEST pdfmark end -2 3765 a Black Black 562 3913 a SDict begin H.S end 562 3913 a 562 3913 a SDict begin 13 H.A end 562 3913 a 562 3913 a SDict begin [/View [/XYZ H.V]/Dest (0:414) cvn /DEST pdfmark end 562 3913 a Fj(Search)-2 3997 y SDict begin H.S end -2 3997 a -2 3997 a SDict begin 13 H.A end -2 3997 a -2 3997 a SDict begin [/View [/XYZ H.V]/Dest (0:416) cvn /DEST pdfmark end -2 3997 a 396 4104 a Fj(8)-2 4105 y SDict begin H.S end -2 4105 a -2 4105 a SDict begin 13 H.A end -2 4105 a -2 4105 a SDict begin [/View [/XYZ H.V]/Dest (0:417) cvn /DEST pdfmark end -2 4105 a Black Black 562 4254 a SDict begin H.S end 562 4254 a 562 4254 a SDict begin 13 H.A end 562 4254 a 562 4254 a SDict begin [/View [/XYZ H.V]/Dest (0:418) cvn /DEST pdfmark end 562 4254 a Fj(T)-6 b(elnet)20 b(link)-2 4337 y SDict begin H.S end -2 4337 a -2 4337 a SDict begin 13 H.A end -2 4337 a -2 4337 a SDict begin [/View [/XYZ H.V]/Dest (0:420) cvn /DEST pdfmark end -2 4337 a 396 4444 a Fj(9)-2 4446 y SDict begin H.S end -2 4446 a -2 4446 a SDict begin 13 H.A end -2 4446 a -2 4446 a SDict begin [/View [/XYZ H.V]/Dest (0:421) cvn /DEST pdfmark end -2 4446 a Black Black 562 4594 a SDict begin H.S end 562 4594 a 562 4594 a SDict begin 13 H.A end 562 4594 a 562 4594 a SDict begin [/View [/XYZ H.V]/Dest (0:422) cvn /DEST pdfmark end 562 4594 a Fj(Binary)g(\002le)-2 4695 y SDict begin H.S end -2 4695 a -2 4695 a SDict begin 13 H.A end -2 4695 a -2 4695 a SDict begin [/View [/XYZ H.V]/Dest (0:424) cvn /DEST pdfmark end -2 4695 a 396 4785 a Fj(+)-2 4785 y SDict begin H.S end -2 4785 a -2 4785 a SDict begin 13 H.A end -2 4785 a -2 4785 a SDict begin [/View [/XYZ H.V]/Dest (0:425) cvn /DEST pdfmark end -2 4785 a Black Black 562 4934 a SDict begin H.S end 562 4934 a 562 4934 a SDict begin 13 H.A end 562 4934 a 562 4934 a SDict begin [/View [/XYZ H.V]/Dest (0:426) cvn /DEST pdfmark end 562 4934 a Fj(Redundant)f(serv)o(er) g(\(not)h(implemented)e(by)1878 4934 y SDict begin H.S end 1878 4934 a 1878 4934 a SDict begin 13 H.A end 1878 4934 a 1878 4934 a SDict begin [/View [/XYZ H.V]/Dest (0:427) cvn /DEST pdfmark end 1878 4934 a Fj(PyGopherd\))p Black -2 5569 a SDict begin H.S end -2 5569 a -2 5569 a SDict begin 13 H.A end -2 5569 a -2 5569 a SDict begin [/View [/XYZ H.V]/Dest (0:434) cvn /DEST pdfmark end -2 5569 a 3798 5638 a Fi(16)p Black eop end %%Page: 17 20 TeXDict begin 17 19 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.17) cvn /DEST pdfmark end -611 -810 a Black Black 2877 -132 a Fi(Chapter)20 b(6.)g(Gopher)f(Item)i(T)-6 b(ypes)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:429) cvn /DEST pdfmark end -2 -11 a 396 72 a Fj(c)-2 73 y SDict begin H.S end -2 73 a -2 73 a SDict begin 13 H.A end -2 73 a -2 73 a SDict begin [/View [/XYZ H.V]/Dest (0:430) cvn /DEST pdfmark end -2 73 a Black Black 562 222 a SDict begin H.S end 562 222 a 562 222 a SDict begin 13 H.A end 562 222 a 562 222 a SDict begin [/View [/XYZ H.V]/Dest (0:431) cvn /DEST pdfmark end 562 222 a Fj(Calendar)20 b(\(not)f(implemented)g(by)1595 222 y SDict begin H.S end 1595 222 a 1595 222 a SDict begin 13 H.A end 1595 222 a 1595 222 a SDict begin [/View [/XYZ H.V]/Dest (0:432) cvn /DEST pdfmark end 1595 222 a Fj(PyGopherd\))396 413 y(e)-2 414 y SDict begin H.S end -2 414 a -2 414 a SDict begin 13 H.A end -2 414 a -2 414 a SDict begin [/View [/XYZ H.V]/Dest (0:435) cvn /DEST pdfmark end -2 414 a Black Black 562 562 a SDict begin H.S end 562 562 a 562 562 a SDict begin 13 H.A end 562 562 a 562 562 a SDict begin [/View [/XYZ H.V]/Dest (0:436) cvn /DEST pdfmark end 562 562 a Fj(Ev)o(ent)h (\(not)f(implemented)f(by)1488 562 y SDict begin H.S end 1488 562 a 1488 562 a SDict begin 13 H.A end 1488 562 a 1488 562 a SDict begin [/View [/XYZ H.V]/Dest (0:437) cvn /DEST pdfmark end 1488 562 a Fj(PyGopherd\))-2 663 y SDict begin H.S end -2 663 a -2 663 a SDict begin 13 H.A end -2 663 a -2 663 a SDict begin [/View [/XYZ H.V]/Dest (0:439) cvn /DEST pdfmark end -2 663 a 396 753 a Fj(g)-2 771 y SDict begin H.S end -2 771 a -2 771 a SDict begin 13 H.A end -2 771 a -2 771 a SDict begin [/View [/XYZ H.V]/Dest (0:440) cvn /DEST pdfmark end -2 771 a Black Black 562 903 a SDict begin H.S end 562 903 a 562 903 a SDict begin 13 H.A end 562 903 a 562 903 a SDict begin [/View [/XYZ H.V]/Dest (0:441) cvn /DEST pdfmark end 562 903 a Fj(GIF-format)h(graphic)-2 1004 y SDict begin H.S end -2 1004 a -2 1004 a SDict begin 13 H.A end -2 1004 a -2 1004 a SDict begin [/View [/XYZ H.V]/Dest (0:443) cvn /DEST pdfmark end -2 1004 a 396 1094 a Fj(h)-2 1094 y SDict begin H.S end -2 1094 a -2 1094 a SDict begin 13 H.A end -2 1094 a -2 1094 a SDict begin [/View [/XYZ H.V]/Dest (0:444) cvn /DEST pdfmark end -2 1094 a Black Black 562 1243 a SDict begin H.S end 562 1243 a 562 1243 a SDict begin 13 H.A end 562 1243 a 562 1243 a SDict begin [/View [/XYZ H.V]/Dest (0:445) cvn /DEST pdfmark end 562 1243 a Fj(HTML)h(\002le)-2 1327 y SDict begin H.S end -2 1327 a -2 1327 a SDict begin 13 H.A end -2 1327 a -2 1327 a SDict begin [/View [/XYZ H.V]/Dest (0:447) cvn /DEST pdfmark end -2 1327 a 396 1434 a Fj(I)-2 1434 y SDict begin H.S end -2 1434 a -2 1434 a SDict begin 13 H.A end -2 1434 a -2 1434 a SDict begin [/View [/XYZ H.V]/Dest (0:448) cvn /DEST pdfmark end -2 1434 a Black Black 562 1583 a SDict begin H.S end 562 1583 a 562 1583 a SDict begin 13 H.A end 562 1583 a 562 1583 a SDict begin [/View [/XYZ H.V]/Dest (0:449) cvn /DEST pdfmark end 562 1583 a Fj(An)o(y)g(kind)f(of)h (graphic)f(\002le)i(other)e(than)h(GIF)-2 1684 y SDict begin H.S end -2 1684 a -2 1684 a SDict begin 13 H.A end -2 1684 a -2 1684 a SDict begin [/View [/XYZ H.V]/Dest (0:451) cvn /DEST pdfmark end -2 1684 a 396 1774 a Fj(i)-2 1774 y SDict begin H.S end -2 1774 a -2 1774 a SDict begin 13 H.A end -2 1774 a -2 1774 a SDict begin [/View [/XYZ H.V]/Dest (0:452) cvn /DEST pdfmark end -2 1774 a Black Black 562 1924 a SDict begin H.S end 562 1924 a 562 1924 a SDict begin 13 H.A end 562 1924 a 562 1924 a SDict begin [/View [/XYZ H.V]/Dest (0:453) cvn /DEST pdfmark end 562 1924 a Fj(Informational)e(te)o(xt)i (included)e(in)j(a)f(directory)f(that)h(is)h(displayed)e(b)n(ut)h(does) g(not)g(link)g(to)g(an)o(y)g(actual)g(\002le.)-2 2025 y SDict begin H.S end -2 2025 a -2 2025 a SDict begin 13 H.A end -2 2025 a -2 2025 a SDict begin [/View [/XYZ H.V]/Dest (0:455) cvn /DEST pdfmark end -2 2025 a 396 2115 a Fj(M)-2 2115 y SDict begin H.S end -2 2115 a -2 2115 a SDict begin 13 H.A end -2 2115 a -2 2115 a SDict begin [/View [/XYZ H.V]/Dest (0:456) cvn /DEST pdfmark end -2 2115 a Black Black 562 2264 a SDict begin H.S end 562 2264 a 562 2264 a SDict begin 13 H.A end 562 2264 a 562 2264 a SDict begin [/View [/XYZ H.V]/Dest (0:457) cvn /DEST pdfmark end 562 2264 a Fj(MIME)g(multipart/mix)o(ed)e (\002le)-2 2365 y SDict begin H.S end -2 2365 a -2 2365 a SDict begin 13 H.A end -2 2365 a -2 2365 a SDict begin [/View [/XYZ H.V]/Dest (0:459) cvn /DEST pdfmark end -2 2365 a 396 2455 a Fj(s)-2 2456 y SDict begin H.S end -2 2456 a -2 2456 a SDict begin 13 H.A end -2 2456 a -2 2456 a SDict begin [/View [/XYZ H.V]/Dest (0:460) cvn /DEST pdfmark end -2 2456 a Black Black 562 2605 a SDict begin H.S end 562 2605 a 562 2605 a SDict begin 13 H.A end 562 2605 a 562 2605 a SDict begin [/View [/XYZ H.V]/Dest (0:461) cvn /DEST pdfmark end 562 2605 a Fj(An)o(y)i(kind)f(of)h(sound)f(\002le)-2 2706 y SDict begin H.S end -2 2706 a -2 2706 a SDict begin 13 H.A end -2 2706 a -2 2706 a SDict begin [/View [/XYZ H.V]/Dest (0:463) cvn /DEST pdfmark end -2 2706 a 396 2796 a Fj(T)-2 2796 y SDict begin H.S end -2 2796 a -2 2796 a SDict begin 13 H.A end -2 2796 a -2 2796 a SDict begin [/View [/XYZ H.V]/Dest (0:464) cvn /DEST pdfmark end -2 2796 a Black Black 562 2945 a SDict begin H.S end 562 2945 a 562 2945 a SDict begin 13 H.A end 562 2945 a 562 2945 a SDict begin [/View [/XYZ H.V]/Dest (0:465) cvn /DEST pdfmark end 562 2945 a Fj(tn3270)g(link)-2 3029 y SDict begin H.S end -2 3029 a -2 3029 a SDict begin 13 H.A end -2 3029 a -2 3029 a SDict begin [/View [/XYZ H.V]/Dest (0:467) cvn /DEST pdfmark end -2 3029 a 396 3136 a Fj(X)-2 3136 y SDict begin H.S end -2 3136 a -2 3136 a SDict begin 13 H.A end -2 3136 a -2 3136 a SDict begin [/View [/XYZ H.V]/Dest (0:468) cvn /DEST pdfmark end -2 3136 a 396 3244 a Fj(-)-2 3244 y SDict begin H.S end -2 3244 a -2 3244 a SDict begin 13 H.A end -2 3244 a -2 3244 a SDict begin [/View [/XYZ H.V]/Dest (0:469) cvn /DEST pdfmark end -2 3244 a Black Black 562 3393 a SDict begin H.S end 562 3393 a 562 3393 a SDict begin 13 H.A end 562 3393 a 562 3393 a SDict begin [/View [/XYZ H.V]/Dest (0:470) cvn /DEST pdfmark end 562 3393 a Fj(UMN-speci\002c)h(--)g(signi\002es)h(that)f(this)h (entry)e(should)g(not)h(be)g(displayed)f(in)h(a)h(directory)e(entry)-5 b(,)18 b(b)n(ut)i(may)g(be)562 3501 y(accessed)g(via)h(a)f(direct)g (link.)g(This)g(v)n(alue)g(is)h(ne)n(v)o(er)e(transmitted)g(in)h(an)o (y)g(Gopher)e(protocol.)p Black 3797 5569 a Fi(17)p Black eop end %%Page: 18 21 TeXDict begin 18 20 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.18) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:PYGOPHERD.MAN) cvn /DEST pdfmark end -2 -11 a 1023 140 a Fn(I.)58 b(PyGopher)l(d)g(Manpa)n(g)r(e)3257 140 y SDict begin H.S end 3257 140 a 3257 140 a SDict begin 32.348 H.A end 3257 140 a 3257 140 a SDict begin [/View [/XYZ H.V]/Dest (9.0) cvn /DEST pdfmark end 3257 140 a Black Black eop end %%Page: 19 22 TeXDict begin 19 21 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.19) cvn /DEST pdfmark end -611 -810 a Black Black Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:473) cvn /DEST pdfmark end -2 -11 a 102 x Fh(p)n(ygopher)m(d)737 91 y SDict begin H.S end 737 91 a 737 91 a SDict begin 22.464 H.A end 737 91 a 737 91 a SDict begin [/View [/XYZ H.V]/Dest (9.19.1) cvn /DEST pdfmark end 737 91 a 1 0 0 TeXcolorrgb -2 206 a SDict begin H.S end -2 206 a -2 206 a SDict begin 13 H.A end -2 206 a -2 206 a SDict begin [/View [/XYZ H.V]/Dest (0:474) cvn /DEST pdfmark end -2 206 a 1 0 0 TeXcolorrgb -2 289 a SDict begin H.S end -2 289 a -2 289 a SDict begin 13 H.A end -2 289 a -2 289 a SDict begin [/View [/XYZ H.V]/Dest (0:475) cvn /DEST pdfmark end -2 289 a 1 0 0 TeXcolorrgb -2 289 a SDict begin H.S end -2 289 a -2 289 a SDict begin 13 H.A end -2 289 a -2 289 a SDict begin [/View [/XYZ H.V]/Dest (0:476) cvn /DEST pdfmark end -2 289 a 396 365 a Fj(<)p 1 0 0 TeXcolorrgb Fe(jgoerzen@complete.org)p 1 0 0 TeXcolorrgb Fj(>)p 1 0 0 TeXcolorrgb 1 0 0 TeXcolorrgb 1 0 0 TeXcolorrgb -2 377 a SDict begin H.S end -2 377 a -2 377 a SDict begin 13 H.A end -2 377 a -2 377 a SDict begin [/View [/XYZ H.V]/Dest (0:477) cvn /DEST pdfmark end -2 377 a 1 0 0 TeXcolorrgb Black -2 460 a SDict begin H.S end -2 460 a -2 460 a SDict begin 13 H.A end -2 460 a -2 460 a SDict begin [/View [/XYZ H.V]/Dest (0:484) cvn /DEST pdfmark end -2 460 a -2 460 a SDict begin H.S end -2 460 a -2 460 a SDict begin 13 H.A end -2 460 a -2 460 a SDict begin [/View [/XYZ H.V]/Dest (0:485) cvn /DEST pdfmark end -2 460 a 396 693 a Fb(Name)720 693 y SDict begin H.S end 720 693 a 720 693 a SDict begin 18.72 H.A end 720 693 a 720 693 a SDict begin [/View [/XYZ H.V]/Dest (9.19.6.2) cvn /DEST pdfmark end 720 693 a 396 825 a Fa(PyGopherd)846 825 y SDict begin H.S end 846 825 a 846 825 a SDict begin 13 H.A end 846 825 a 846 825 a SDict begin [/View [/XYZ H.V]/Dest (0:486) cvn /DEST pdfmark end 846 825 a 19 w Fj(\227)21 b(Multiprotocol)d(Information)f(Serv)o(er)-2 843 y SDict begin H.S end -2 843 a -2 843 a SDict begin 13 H.A end -2 843 a -2 843 a SDict begin [/View [/XYZ H.V]/Dest (0:487) cvn /DEST pdfmark end -2 843 a 396 1153 a Fb(Synopsis)926 1153 y SDict begin H.S end 926 1153 a 926 1153 a SDict begin 18.72 H.A end 926 1153 a 926 1153 a SDict begin [/View [/XYZ H.V]/Dest (9.19.7.2) cvn /DEST pdfmark end 926 1153 a -2 1178 a SDict begin H.S end -2 1178 a -2 1178 a SDict begin 13 H.A end -2 1178 a -2 1178 a SDict begin [/View [/XYZ H.V]/Dest (0:488) cvn /DEST pdfmark end -2 1178 a -2 1285 a SDict begin H.S end -2 1285 a -2 1285 a SDict begin 13 H.A end -2 1285 a -2 1285 a SDict begin [/View [/XYZ H.V]/Dest (0:489) cvn /DEST pdfmark end -2 1285 a 396 1368 a Fk(pygopherd)800 1368 y SDict begin H.S end 800 1368 a 800 1368 a SDict begin 13 H.A end 800 1368 a 800 1368 a SDict begin [/View [/XYZ H.V]/Dest (0:490) cvn /DEST pdfmark end 800 1368 a 21 w Fj([)849 1368 y SDict begin H.S end 849 1368 a 849 1368 a SDict begin 13 H.A end 849 1368 a 849 1368 a SDict begin [/View [/XYZ H.V]/Dest (0:491) cvn /DEST pdfmark end 849 1368 a Fc(configfile)p Fj(])-2 1468 y SDict begin H.S end -2 1468 a -2 1468 a SDict begin 13 H.A end -2 1468 a -2 1468 a SDict begin [/View [/XYZ H.V]/Dest (0:MAN.DESCRIPTION) cvn /DEST pdfmark end -2 1468 a 396 1779 a Fb(Description)1052 1779 y SDict begin H.S end 1052 1779 a 1052 1779 a SDict begin 18.72 H.A end 1052 1779 a 1052 1779 a SDict begin [/View [/XYZ H.V]/Dest (9.19.8.2) cvn /DEST pdfmark end 1052 1779 a -2 1970 a SDict begin H.S end -2 1970 a -2 1970 a SDict begin 13 H.A end -2 1970 a -2 1970 a SDict begin [/View [/XYZ H.V]/Dest (0:494) cvn /DEST pdfmark end -2 1970 a 396 2053 a Fj(W)-7 b(elcome)21 b(to)814 2053 y SDict begin H.S end 814 2053 a 814 2053 a SDict begin 13 H.A end 814 2053 a 814 2053 a SDict begin [/View [/XYZ H.V]/Dest (0:495) cvn /DEST pdfmark end 814 2053 a Fj(PyGopherd.)d(In)h(a)i (nutshell,)1686 2053 y SDict begin H.S end 1686 2053 a 1686 2053 a SDict begin 13 H.A end 1686 2053 a 1686 2053 a SDict begin [/View [/XYZ H.V]/Dest (0:496) cvn /DEST pdfmark end 1686 2053 a Fj(PyGopherd)c(is)22 b(a)e(modern)f(dynamic)f (multi-protocol)g(hierarchical)396 2161 y(information)g(serv)o(er)h (with)i(a)f(pluggable)e(modularized)g(e)o(xtension)h(system,)h(full)g (\003e)o(xible)f(caching,)g(virtual)h(\002les)h(and)396 2269 y(folders,)e(and)h(autodetection)e(of)i(\002le)h(types)f(--)g(all) h(with)f(support)f(for)g(standardized)g(yet)h(e)o(xtensible)f(per)n (-document)396 2377 y(metadata.)g(Whe)n(w!)h(Read)h(on)f(for)f (information)f(on)i(this)g(what)h(all)f(these)h(b)n(uzzw)o(ords)e (mean.)-2 2388 y SDict begin H.S end -2 2388 a -2 2388 a SDict begin 13 H.A end -2 2388 a -2 2388 a SDict begin [/View [/XYZ H.V]/Dest (0:MANPAGE.QUICKSTART) cvn /DEST pdfmark end -2 2388 a 396 2715 a Fb(Quic)n(k)34 b(Star)r(t)1034 2715 y SDict begin H.S end 1034 2715 a 1034 2715 a SDict begin 18.72 H.A end 1034 2715 a 1034 2715 a SDict begin [/View [/XYZ H.V]/Dest (9.19.9.2) cvn /DEST pdfmark end 1034 2715 a -2 2888 a SDict begin H.S end -2 2888 a -2 2888 a SDict begin 13 H.A end -2 2888 a -2 2888 a SDict begin [/View [/XYZ H.V]/Dest (0:499) cvn /DEST pdfmark end -2 2888 a 396 2989 a Fj(If)20 b(you)g(ha)n(v)o(e)f(already)g (installed)1359 2989 y SDict begin H.S end 1359 2989 a 1359 2989 a SDict begin 13 H.A end 1359 2989 a 1359 2989 a SDict begin [/View [/XYZ H.V]/Dest (0:500) cvn /DEST pdfmark end 1359 2989 a Fj(PyGopherd)f(system-wide,)h(or)h(your)f (administrator)g(has)h(done)f(that)i(for)e(you,)g(your)396 3097 y(task)i(for)e(setting)h(up)1013 3097 y SDict begin H.S end 1013 3097 a 1013 3097 a SDict begin 13 H.A end 1013 3097 a 1013 3097 a SDict begin [/View [/XYZ H.V]/Dest (0:501) cvn /DEST pdfmark end 1013 3097 a Fj(PyGopherd)e(for)h (the)h(\002rst)h(time)f(is)h(quite)f(simple.)f(Y)-9 b(ou)20 b(just)g(need)f(to)h(set)h(up)f(your)e(con\002guration)396 3205 y(\002le,)j(mak)o(e)f(your)f(folder)g(directory)-5 b(,)17 b(and)j(run)f(it!)-2 3389 y SDict begin H.S end -2 3389 a -2 3389 a SDict begin 13 H.A end -2 3389 a -2 3389 a SDict begin [/View [/XYZ H.V]/Dest (0:502) cvn /DEST pdfmark end -2 3389 a 396 3479 a Fj(Y)-9 b(ou)20 b(can)g(quickly)f(set)i(up)e(your)g(con\002guration)f(\002le.)i(The)g (distrib)n(ution)f(includes)h(tw)o(o)g(\002les)h(of)f(interest:)396 3587 y SDict begin H.S end 396 3587 a 396 3587 a SDict begin 13 H.A end 396 3587 a 396 3587 a SDict begin [/View [/XYZ H.V]/Dest (0:503) cvn /DEST pdfmark end 396 3587 a Fe(conf/pygopherd.conf)e Fj(and)1409 3587 y SDict begin H.S end 1409 3587 a 1409 3587 a SDict begin 13 H.A end 1409 3587 a 1409 3587 a SDict begin [/View [/XYZ H.V]/Dest (0:504) cvn /DEST pdfmark end 1409 3587 a Fe(conf/mime.types)p Fj(.)g(Debian)i(users)g(will)h(\002nd)f(the)g (con\002guration)e(\002le)396 3695 y(pre-installed)h(in)917 3695 y SDict begin H.S end 917 3695 a 917 3695 a SDict begin 13 H.A end 917 3695 a 917 3695 a SDict begin [/View [/XYZ H.V]/Dest (0:505) cvn /DEST pdfmark end 917 3695 a Fe(/etc/pygopherd/pygopherd.conf)d Fj(and)k(the)2501 3695 y SDict begin H.S end 2501 3695 a 2501 3695 a SDict begin 13 H.A end 2501 3695 a 2501 3695 a SDict begin [/View [/XYZ H.V]/Dest (0:506) cvn /DEST pdfmark end 2501 3695 a Fe(mime.types)f Fj(\002le)i(pro)o(vided)d(by)h(the)i (system)396 3803 y(already)-5 b(.)-2 3987 y SDict begin H.S end -2 3987 a -2 3987 a SDict begin 13 H.A end -2 3987 a -2 3987 a SDict begin [/View [/XYZ H.V]/Dest (0:507) cvn /DEST pdfmark end -2 3987 a 396 4077 a Fj(Open)20 b(up)701 4077 y SDict begin H.S end 701 4077 a 701 4077 a SDict begin 13 H.A end 701 4077 a 701 4077 a SDict begin [/View [/XYZ H.V]/Dest (0:508) cvn /DEST pdfmark end 701 4077 a Fe(pygopherd.conf)e Fj(in)i(your)f(editor)h(and)f (adjust)h(to)h(suit.)f(The)g(\002le)h(is)g(hea)n(vily)f(commented)e (and)h(you)h(can)396 4185 y(refer)g(to)g(it)h(for)e(detailed)h (information.)e(Some)i(settings)g(to)g(tak)o(e)h(a)f(look)g(at)g (include:)2883 4185 y SDict begin H.S end 2883 4185 a 2883 4185 a SDict begin 13 H.A end 2883 4185 a 2883 4185 a SDict begin [/View [/XYZ H.V]/Dest (0:509) cvn /DEST pdfmark end 2883 4185 a Fj(detach,)3142 4185 y SDict begin H.S end 3142 4185 a 3142 4185 a SDict begin 13 H.A end 3142 4185 a 3142 4185 a SDict begin [/View [/XYZ H.V]/Dest (0:510) cvn /DEST pdfmark end 3142 4185 a Fj(pid\002le,)3395 4185 y SDict begin H.S end 3395 4185 a 3395 4185 a SDict begin 13 H.A end 3395 4185 a 3395 4185 a SDict begin [/View [/XYZ H.V]/Dest (0:511) cvn /DEST pdfmark end 3395 4185 a Fj(port,)396 4293 y SDict begin H.S end 396 4293 a 396 4293 a SDict begin 13 H.A end 396 4293 a 396 4293 a SDict begin [/View [/XYZ H.V]/Dest (0:512) cvn /DEST pdfmark end 396 4293 a Fj(usechroot,)761 4293 y SDict begin H.S end 761 4293 a 761 4293 a SDict begin 13 H.A end 761 4293 a 761 4293 a SDict begin [/View [/XYZ H.V]/Dest (0:513) cvn /DEST pdfmark end 761 4293 a Fj(setuid,)1000 4293 y SDict begin H.S end 1000 4293 a 1000 4293 a SDict begin 13 H.A end 1000 4293 a 1000 4293 a SDict begin [/View [/XYZ H.V]/Dest (0:514) cvn /DEST pdfmark end 1000 4293 a Fj(setgid,)g(and)1381 4293 y SDict begin H.S end 1381 4293 a 1381 4293 a SDict begin 13 H.A end 1381 4293 a 1381 4293 a SDict begin [/View [/XYZ H.V]/Dest (0:515) cvn /DEST pdfmark end 1381 4293 a Fj(root.)f(These)h(may)g(or)g(may)g(not)f(w)o(ork)h(at)h (their)f(def)o(aults)f(for)h(you.)f(The)h(remaining)396 4401 y(ones)g(should)f(be)h(\002ne)h(for)e(a)i(basic)f(setup.)-2 4585 y SDict begin H.S end -2 4585 a -2 4585 a SDict begin 13 H.A end -2 4585 a -2 4585 a SDict begin [/View [/XYZ H.V]/Dest (0:516) cvn /DEST pdfmark end -2 4585 a 396 4675 a Fj(In)m(v)n(ok)o(e)641 4675 y SDict begin H.S end 641 4675 a 641 4675 a SDict begin 13 H.A end 641 4675 a 641 4675 a SDict begin [/View [/XYZ H.V]/Dest (0:517) cvn /DEST pdfmark end 641 4675 a Fj(PyGopherd)e(with)1208 4675 y SDict begin H.S end 1208 4675 a 1208 4675 a SDict begin 13 H.A end 1208 4675 a 1208 4675 a SDict begin [/View [/XYZ H.V]/Dest (0:518) cvn /DEST pdfmark end 1208 4675 a Fk(pygopherd)h(path/to/con\002g\002le)g Fj(\(or)2344 4675 y SDict begin H.S end 2344 4675 a 2344 4675 a SDict begin 13 H.A end 2344 4675 a 2344 4675 a SDict begin [/View [/XYZ H.V]/Dest (0:519) cvn /DEST pdfmark end 2344 4675 a Fk(/etc/init.d/pygopherd)g(start)g Fj(on)h(Debian\).)e(Place)396 4783 y(some)i(\002les)h(in)g(the)f (location)f(speci\002ed)h(by)g(the)1789 4783 y SDict begin H.S end 1789 4783 a 1789 4783 a SDict begin 13 H.A end 1789 4783 a 1789 4783 a SDict begin [/View [/XYZ H.V]/Dest (0:520) cvn /DEST pdfmark end 1789 4783 a Fj(root)g(directi)n (v)o(e)f(in)h(the)g(con\002g)f(\002le)i(and)f(you')l(re)e(ready)h(to)i (run!)-2 4811 y SDict begin H.S end -2 4811 a -2 4811 a SDict begin 13 H.A end -2 4811 a -2 4811 a SDict begin [/View [/XYZ H.V]/Dest (0:OPTIONS) cvn /DEST pdfmark end -2 4811 a Black 3800 5569 a Fi(19)p Black eop end %%Page: 20 23 TeXDict begin 20 22 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.20) cvn /DEST pdfmark end -611 -810 a Black Black -2 -201 a SDict begin H.S end -2 -201 a -2 -201 a SDict begin 13 H.A end -2 -201 a -2 -201 a SDict begin [/View [/XYZ H.V]/Dest (0:576) cvn /DEST pdfmark end -2 -201 a 3171 -132 a Fi(PyGopher)m(d)18 b(Manpa)o(g)o(e)p Black 396 77 a Fb(Options)847 77 y SDict begin H.S end 847 77 a 847 77 a SDict begin 18.72 H.A end 847 77 a 847 77 a SDict begin [/View [/XYZ H.V]/Dest (9.19.10.2) cvn /DEST pdfmark end 847 77 a -2 267 a SDict begin H.S end -2 267 a -2 267 a SDict begin 13 H.A end -2 267 a -2 267 a SDict begin [/View [/XYZ H.V]/Dest (0:523) cvn /DEST pdfmark end -2 267 a 396 351 a Fj(All)523 351 y SDict begin H.S end 523 351 a 523 351 a SDict begin 13 H.A end 523 351 a 523 351 a SDict begin [/View [/XYZ H.V]/Dest (0:524) cvn /DEST pdfmark end 523 351 a Fj(PyGopherd)g(con\002guratoin)g(is)j(done)e(via)h(the) g(con\002guration)e(\002le.)i(Therefore,)e(the)i(program)e(has)j(only)e (one)396 459 y(command-line)f(option:)-2 477 y SDict begin H.S end -2 477 a -2 477 a SDict begin 13 H.A end -2 477 a -2 477 a SDict begin [/View [/XYZ H.V]/Dest (0:525) cvn /DEST pdfmark end -2 477 a -2 601 a SDict begin H.S end -2 601 a -2 601 a SDict begin 13 H.A end -2 601 a -2 601 a SDict begin [/View [/XYZ H.V]/Dest (0:527) cvn /DEST pdfmark end -2 601 a -2 601 a SDict begin H.S end -2 601 a -2 601 a SDict begin 13 H.A end -2 601 a -2 601 a SDict begin [/View [/XYZ H.V]/Dest (0:528) cvn /DEST pdfmark end -2 601 a 396 691 a Fc(configfile)-2 703 y SDict begin H.S end -2 703 a -2 703 a SDict begin 13 H.A end -2 703 a -2 703 a SDict begin [/View [/XYZ H.V]/Dest (0:529) cvn /DEST pdfmark end -2 703 a Black Black 562 840 a SDict begin H.S end 562 840 a 562 840 a SDict begin 13 H.A end 562 840 a 562 840 a SDict begin [/View [/XYZ H.V]/Dest (0:530) cvn /DEST pdfmark end 562 840 a Fj(This)j(option)e(ar)o(gument)e(speci\002es)k(the)f (location)g(of)g(the)g(con\002guration)d(\002le)k(that)2961 840 y SDict begin H.S end 2961 840 a 2961 840 a SDict begin 13 H.A end 2961 840 a 2961 840 a SDict begin [/View [/XYZ H.V]/Dest (0:531) cvn /DEST pdfmark end 2961 840 a Fj(PyGopherd)d(is)j(to)g(use.)-2 900 y SDict begin H.S end -2 900 a -2 900 a SDict begin 13 H.A end -2 900 a -2 900 a SDict begin [/View [/XYZ H.V]/Dest (0:CONFORMING) cvn /DEST pdfmark end -2 900 a 396 1210 a Fb(Conf)n(orming)33 b(T)-10 b(o)1240 1210 y SDict begin H.S end 1240 1210 a 1240 1210 a SDict begin 18.72 H.A end 1240 1210 a 1240 1210 a SDict begin [/View [/XYZ H.V]/Dest (9.19.11.2) cvn /DEST pdfmark end 1240 1210 a -2 1237 a SDict begin H.S end -2 1237 a -2 1237 a SDict begin 13 H.A end -2 1237 a -2 1237 a SDict begin [/View [/XYZ H.V]/Dest (0:534) cvn /DEST pdfmark end -2 1237 a -2 1261 a SDict begin H.S end -2 1261 a -2 1261 a SDict begin 13 H.A end -2 1261 a -2 1261 a SDict begin [/View [/XYZ H.V]/Dest (0:535) cvn /DEST pdfmark end -2 1261 a Black 396 1407 a Fg(\225)p Black 479 1407 a SDict begin H.S end 479 1407 a 479 1407 a SDict begin 13 H.A end 479 1407 a 479 1407 a SDict begin [/View [/XYZ H.V]/Dest (0:536) cvn /DEST pdfmark end 479 1407 a Fj(The)20 b(Internet)f(Gopher)g(Protocol)g (as)i(speci\002ed)f(in)g(RFC1436)-2 1425 y SDict begin H.S end -2 1425 a -2 1425 a SDict begin 13 H.A end -2 1425 a -2 1425 a SDict begin [/View [/XYZ H.V]/Dest (0:537) cvn /DEST pdfmark end -2 1425 a Black 396 1557 a Fg(\225)p Black 479 1557 a SDict begin H.S end 479 1557 a 479 1557 a SDict begin 13 H.A end 479 1557 a 479 1557 a SDict begin [/View [/XYZ H.V]/Dest (0:538) cvn /DEST pdfmark end 479 1557 a Fj(The)g(Gopher+)f(upw)o(ard-compatible)d (enhancements)i(to)j(the)f(Internet)f(Gopher)g(Protocol)g(from)g(the)h (Uni)n(v)o(ersity)479 1665 y(of)g(Minnesota)f(as)i(laid)g(out)f(at)1383 1665 y SDict begin H.S end 1383 1665 a 1383 1665 a SDict begin 13 H.A end 1383 1665 a 1383 1665 a SDict begin [/View [/XYZ H.V]/Dest (0:539) cvn /DEST pdfmark end 1383 1665 a Fj(go-)479 1773 y(pher://gopher)-5 b(.quux.or)n(g/0)o (/Arch)o(i)n(v)o(es/m)o(irro)o(rs/bo)o(omb)o(ox)o(.m)o(icro)o(.um)o (n.e)o(du/p)o(ub)o(/go)o(ph)o(er/g)o(op)o(her)o(_p)o(roto)o(col/Go)o (ph)o(er+)o(/Goph)o(er+)o(.txt.)-2 1791 y SDict begin H.S end -2 1791 a -2 1791 a SDict begin 13 H.A end -2 1791 a -2 1791 a SDict begin [/View [/XYZ H.V]/Dest (0:540) cvn /DEST pdfmark end -2 1791 a Black 396 1922 a Fg(\225)p Black 479 1922 a SDict begin H.S end 479 1922 a 479 1922 a SDict begin 13 H.A end 479 1922 a 479 1922 a SDict begin [/View [/XYZ H.V]/Dest (0:541) cvn /DEST pdfmark end 479 1922 a Fj(The)20 b(gophermap)d(\002le)k(format)e (as)i(originally)e(implemented)f(in)j(the)f(Bucktooth)e(gopher)h(serv)o (er)g(and)h(described)f(at)479 2030 y SDict begin H.S end 479 2030 a 479 2030 a SDict begin 13 H.A end 479 2030 a 479 2030 a SDict begin [/View [/XYZ H.V]/Dest (0:542) cvn /DEST pdfmark end 479 2030 a Fj(gopher://gopher)-5 b(.\003oodga)o(p.co)o(m/0)o(/b)n(uck)o(/db)o(ro)m(wse\0453Ff)o(aq)o (use\04520)o(1.)-2 2048 y SDict begin H.S end -2 2048 a -2 2048 a SDict begin 13 H.A end -2 2048 a -2 2048 a SDict begin [/View [/XYZ H.V]/Dest (0:543) cvn /DEST pdfmark end -2 2048 a Black 396 2179 a Fg(\225)p Black 479 2179 a SDict begin H.S end 479 2179 a 479 2179 a SDict begin 13 H.A end 479 2179 a 479 2179 a SDict begin [/View [/XYZ H.V]/Dest (0:544) cvn /DEST pdfmark end 479 2179 a Fj(The)20 b(Links)g(to)g(URL)h(speci\002cation)f(as)g (laid)h(out)f(by)f(John)h(Goerzen)f(at)479 2287 y SDict begin H.S end 479 2287 a 479 2287 a SDict begin 13 H.A end 479 2287 a 479 2287 a SDict begin [/View [/XYZ H.V]/Dest (0:545) cvn /DEST pdfmark end 479 2287 a Fj(gopher://gopher) -5 b(.quux.o)o(r)n(g/0)o(/Arch)o(i)n(v)o(es/Mailin)o(g\04520)o (Lists/gop)o(he)o(r/go)o(ph)o(er)g(.2)o(00)o(2-0)o(2\0453)o(f/MBO)m(X-) 479 2395 y(MESSA)m(GE/34.)-2 2396 y SDict begin H.S end -2 2396 a -2 2396 a SDict begin 13 H.A end -2 2396 a -2 2396 a SDict begin [/View [/XYZ H.V]/Dest (0:546) cvn /DEST pdfmark end -2 2396 a Black 396 2545 a Fg(\225)p Black 479 2545 a SDict begin H.S end 479 2545 a 479 2545 a SDict begin 13 H.A end 479 2545 a 479 2545 a SDict begin [/View [/XYZ H.V]/Dest (0:547) cvn /DEST pdfmark end 479 2545 a Fj(The)20 b(UMN)f(format)g(for)g(specifying)f(object) h(attrib)n(utes)g(and)g(links)h(with)g(.cap,)e(.Links,)h(.abstract,)g (and)g(similar)h(\002les)479 2653 y(as)h(speci\002ed)f(else)n(where)g (in)g(this)h(document)d(and)i(implemented)e(by)i(UMN)g(gopherd.)-2 2671 y SDict begin H.S end -2 2671 a -2 2671 a SDict begin 13 H.A end -2 2671 a -2 2671 a SDict begin [/View [/XYZ H.V]/Dest (0:548) cvn /DEST pdfmark end -2 2671 a Black 396 2802 a Fg(\225)p Black 479 2802 a SDict begin H.S end 479 2802 a 479 2802 a SDict begin 13 H.A end 479 2802 a 479 2802 a SDict begin [/View [/XYZ H.V]/Dest (0:549) cvn /DEST pdfmark end 479 2802 a Fj(The)g(PYG)h(format)e (for)h(e)o(xtensible)f(Python)g(gopher)f(objects)i(as)h(created)e(for) 2763 2802 y SDict begin H.S end 2763 2802 a 2763 2802 a SDict begin 13 H.A end 2763 2802 a 2763 2802 a SDict begin [/View [/XYZ H.V]/Dest (0:550) cvn /DEST pdfmark end 2763 2802 a Fj(PyGopherd.)-2 2820 y SDict begin H.S end -2 2820 a -2 2820 a SDict begin 13 H.A end -2 2820 a -2 2820 a SDict begin [/View [/XYZ H.V]/Dest (0:551) cvn /DEST pdfmark end -2 2820 a Black 396 2952 a Fg(\225)p Black 479 2952 a SDict begin H.S end 479 2952 a 479 2952 a SDict begin 13 H.A end 479 2952 a 479 2952 a SDict begin [/View [/XYZ H.V]/Dest (0:552) cvn /DEST pdfmark end 479 2952 a Fj(Hyperte)o(xt)g(T)m(ransfer)g(Protocol)g (HTTP/1.0)g(as)i(speci\002ed)f(in)g(RFC1945)-2 2970 y SDict begin H.S end -2 2970 a -2 2970 a SDict begin 13 H.A end -2 2970 a -2 2970 a SDict begin [/View [/XYZ H.V]/Dest (0:553) cvn /DEST pdfmark end -2 2970 a Black 396 3101 a Fg(\225)p Black 479 3101 a SDict begin H.S end 479 3101 a 479 3101 a SDict begin 13 H.A end 479 3101 a 479 3101 a SDict begin [/View [/XYZ H.V]/Dest (0:554) cvn /DEST pdfmark end 479 3101 a Fj(Hyperte)o(xt)d(Markup)h (Language)e(\(HTML\))i(3.2)g(and)g(4.0)g(T)m(ransitional)g(as)i (speci\002ed)e(in)h(RFC1866)f(and)g(RFC2854.)-2 3119 y SDict begin H.S end -2 3119 a -2 3119 a SDict begin 13 H.A end -2 3119 a -2 3119 a SDict begin [/View [/XYZ H.V]/Dest (0:555) cvn /DEST pdfmark end -2 3119 a Black 396 3250 a Fg(\225)p Black 479 3250 a SDict begin H.S end 479 3250 a 479 3250 a SDict begin 13 H.A end 479 3250 a 479 3250 a SDict begin [/View [/XYZ H.V]/Dest (0:556) cvn /DEST pdfmark end 479 3250 a Fj(Maildir)i(as)h(speci\002ed)f (in)1240 3250 y SDict begin H.S end 1240 3250 a 1240 3250 a SDict begin 13 H.A end 1240 3250 a 1240 3250 a SDict begin [/View [/XYZ H.V]/Dest (0:557) cvn /DEST pdfmark end 1240 3250 a Fj(http://www)-5 b(.qmail.or)o(g/qmail-manu)o(al-h)o (tml/man)o(5/m)o(aildir)g(.h)o(tml)15 b(and)479 3358 y SDict begin H.S end 479 3358 a 479 3358 a SDict begin 13 H.A end 479 3358 a 479 3358 a SDict begin [/View [/XYZ H.V]/Dest (0:558) cvn /DEST pdfmark end 479 3358 a Fj(http://cr)-5 b(.yp.to/proto/maildir)g(.html.)-2 3376 y SDict begin H.S end -2 3376 a -2 3376 a SDict begin 13 H.A end -2 3376 a -2 3376 a SDict begin [/View [/XYZ H.V]/Dest (0:559) cvn /DEST pdfmark end -2 3376 a Black 396 3508 a Fg(\225)p Black 479 3508 a SDict begin H.S end 479 3508 a 479 3508 a SDict begin 13 H.A end 479 3508 a 479 3508 a SDict begin [/View [/XYZ H.V]/Dest (0:560) cvn /DEST pdfmark end 479 3508 a Fj(The)20 b(mbox)f(mail)h(storage)g(format)f(as)i(speci\002ed)f(in)479 3616 y SDict begin H.S end 479 3616 a 479 3616 a SDict begin 13 H.A end 479 3616 a 479 3616 a SDict begin [/View [/XYZ H.V]/Dest (0:561) cvn /DEST pdfmark end 479 3616 a Fj(http://www)-5 b(.qmail.or)o(g/qmail-manu)o(al-h)o(tml/man)o (5/m)o(bo)o(x.h)o(tml.)-2 3634 y SDict begin H.S end -2 3634 a -2 3634 a SDict begin 13 H.A end -2 3634 a -2 3634 a SDict begin [/View [/XYZ H.V]/Dest (0:562) cvn /DEST pdfmark end -2 3634 a Black 396 3765 a Fg(\225)p Black 479 3765 a SDict begin H.S end 479 3765 a 479 3765 a SDict begin 13 H.A end 479 3765 a 479 3765 a SDict begin [/View [/XYZ H.V]/Dest (0:563) cvn /DEST pdfmark end 479 3765 a Fj(Re)o(gistered)20 b(MIME)g(media)f(types)h(as)h (speci\002ed)f(in)g(RFC2048.)-2 3783 y SDict begin H.S end -2 3783 a -2 3783 a SDict begin 13 H.A end -2 3783 a -2 3783 a SDict begin [/View [/XYZ H.V]/Dest (0:564) cvn /DEST pdfmark end -2 3783 a Black 396 3915 a Fg(\225)p Black 479 3915 a SDict begin H.S end 479 3915 a 479 3915 a SDict begin 13 H.A end 479 3915 a 479 3915 a SDict begin [/View [/XYZ H.V]/Dest (0:565) cvn /DEST pdfmark end 479 3915 a Fj(Script)g(e)o(x)o(ecution)e(conforming)g(to)i(both) f(UMN)i(standards)e(as)i(laid)f(out)g(in)g(UMN)h(gopherd\(1\))c(and)i (Bucktooth)479 4023 y(standards)h(as)h(speci\002ed)e(at)1300 4023 y SDict begin H.S end 1300 4023 a 1300 4023 a SDict begin 13 H.A end 1300 4023 a 1300 4023 a SDict begin [/View [/XYZ H.V]/Dest (0:566) cvn /DEST pdfmark end 1300 4023 a Fj(gopher://gopher)-5 b(.\003oodg)o(ap.c)o(om:7)o(0/0)o (/b)n(uck)o(/db)o(ro)m(wse\0453f)n(f)n(aqu)o(se\045202)o(,)15 b(so)20 b(f)o(ar)g(as)479 4130 y(each)g(can)g(be)g(implemented)f (consistent)g(with)i(secure)f(design)f(principles.)-2 4148 y SDict begin H.S end -2 4148 a -2 4148 a SDict begin 13 H.A end -2 4148 a -2 4148 a SDict begin [/View [/XYZ H.V]/Dest (0:567) cvn /DEST pdfmark end -2 4148 a Black 396 4280 a Fg(\225)p Black 479 4280 a SDict begin H.S end 479 4280 a 479 4280 a SDict begin 13 H.A end 479 4280 a 479 4280 a SDict begin [/View [/XYZ H.V]/Dest (0:568) cvn /DEST pdfmark end 479 4280 a Fj(Standard)g(Python)g (2.2.1)g(or)h(abo)o(v)o(e)e(as)j(implemented)e(on)g(POSIX-compliant)g (systems.)-2 4298 y SDict begin H.S end -2 4298 a -2 4298 a SDict begin 13 H.A end -2 4298 a -2 4298 a SDict begin [/View [/XYZ H.V]/Dest (0:569) cvn /DEST pdfmark end -2 4298 a Black 396 4429 a Fg(\225)p Black 479 4429 a SDict begin H.S end 479 4429 a 479 4429 a SDict begin 13 H.A end 479 4429 a 479 4429 a SDict begin [/View [/XYZ H.V]/Dest (0:570) cvn /DEST pdfmark end 479 4429 a Fj(W)-10 b(AP/WML)22 b(as)e(de\002ned)g(by)f(the)i(W)-10 b(AP)21 b(F)o(orum.)-2 4489 y SDict begin H.S end -2 4489 a -2 4489 a SDict begin 13 H.A end -2 4489 a -2 4489 a SDict begin [/View [/XYZ H.V]/Dest (0:BUGS) cvn /DEST pdfmark end -2 4489 a Black 3800 5569 a Fi(20)p Black eop end %%Page: 21 24 TeXDict begin 21 23 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.21) cvn /DEST pdfmark end -611 -810 a Black Black -2 -201 a SDict begin H.S end -2 -201 a -2 -201 a SDict begin 13 H.A end -2 -201 a -2 -201 a SDict begin [/View [/XYZ H.V]/Dest (0:594) cvn /DEST pdfmark end -2 -201 a 3171 -132 a Fi(PyGopher)m(d)18 b(Manpa)o(g)o(e)p Black 396 74 a Fb(Bugs)694 74 y SDict begin H.S end 694 74 a 694 74 a SDict begin 18.72 H.A end 694 74 a 694 74 a SDict begin [/View [/XYZ H.V]/Dest (9.19.12.2) cvn /DEST pdfmark end 694 74 a -2 267 a SDict begin H.S end -2 267 a -2 267 a SDict begin 13 H.A end -2 267 a -2 267 a SDict begin [/View [/XYZ H.V]/Dest (0:573) cvn /DEST pdfmark end -2 267 a 396 348 a Fj(Reports)i(of)g (b)n(ugs)g(should)f(be)h(sent)h(via)f(e-mail)g(to)g(the)2000 348 y SDict begin H.S end 2000 348 a 2000 348 a SDict begin 13 H.A end 2000 348 a 2000 348 a SDict begin [/View [/XYZ H.V]/Dest (0:574) cvn /DEST pdfmark end 2000 348 a Fj(PyGopherd)d(issue)k(track)o(er)f(at)396 456 y SDict begin H.S end 396 456 a 396 456 a SDict begin 13 H.A end 396 456 a 396 456 a SDict begin [/View [/XYZ H.V]/Dest (0:575) cvn /DEST pdfmark end 396 456 a Fj(https://github)m (.com/michael-lazar/p)o(yg)o(op)o(her)o(d/issues.)396 730 y(The)g(W)-7 b(eb)21 b(site)g(also)g(lists)g(all)g(current)e(b)n (ugs,)g(where)h(you)f(can)h(check)g(their)g(status)g(or)g(contrib)n (ute)f(to)h(\002xing)g(them.)-2 758 y SDict begin H.S end -2 758 a -2 758 a SDict begin 13 H.A end -2 758 a -2 758 a SDict begin [/View [/XYZ H.V]/Dest (0:COPYRIGHT) cvn /DEST pdfmark end -2 758 a 396 1068 a Fb(Cop)n(yright)958 1068 y SDict begin H.S end 958 1068 a 958 1068 a SDict begin 18.72 H.A end 958 1068 a 958 1068 a SDict begin [/View [/XYZ H.V]/Dest (9.19.13.2) cvn /DEST pdfmark end 958 1068 a -2 1261 a SDict begin H.S end -2 1261 a -2 1261 a SDict begin 13 H.A end -2 1261 a -2 1261 a SDict begin [/View [/XYZ H.V]/Dest (0:579) cvn /DEST pdfmark end -2 1261 a -2 1261 a SDict begin H.S end -2 1261 a -2 1261 a SDict begin 13 H.A end -2 1261 a -2 1261 a SDict begin [/View [/XYZ H.V]/Dest (0:580) cvn /DEST pdfmark end -2 1261 a 396 1342 a Fj(PyGopherd)e(is)j(Cop)o(yright)e(\(C\))h (2002-2019)d(John)i(Goerzen,)g(2021)g(Michael)h(Lazar)-5 b(.)-2 1526 y SDict begin H.S end -2 1526 a -2 1526 a SDict begin 13 H.A end -2 1526 a -2 1526 a SDict begin [/View [/XYZ H.V]/Dest (0:581) cvn /DEST pdfmark end -2 1526 a 396 1616 a Fj(This)21 b(program)d(is)j(free)f(softw)o(are;)f (you)h(can)g(redistrib)n(ute)f(it)i(and/or)e(modify)f(it)j(under)e(the) h(terms)g(of)g(the)h(GNU)396 1724 y(General)f(Public)g(License)g(as)h (published)d(by)i(the)g(Free)g(Softw)o(are)g(F)o(oundation;)e(v)o (ersion)h(2)h(of)g(the)g(License.)-2 1908 y SDict begin H.S end -2 1908 a -2 1908 a SDict begin 13 H.A end -2 1908 a -2 1908 a SDict begin [/View [/XYZ H.V]/Dest (0:582) cvn /DEST pdfmark end -2 1908 a 396 1998 a Fj(This)h(program)d (is)j(distrib)n(uted)e(in)h(the)h(hope)e(that)h(it)h(will)g(be)f (useful,)f(b)n(ut)i(WITHOUT)f(ANY)g(W)-10 b(ARRANTY)i(;)396 2106 y(without)20 b(e)n(v)o(en)f(the)h(implied)g(w)o(arranty)f(of)g (MERCHANT)-8 b(ABILITY)20 b(or)g(FITNESS)h(FOR)g(A)f(P)-8 b(AR)j(TICULAR)396 2214 y(PURPOSE.)21 b(See)g(the)f(GNU)h(General)e (Public)h(License)g(for)g(more)f(details.)-2 2381 y SDict begin H.S end -2 2381 a -2 2381 a SDict begin 13 H.A end -2 2381 a -2 2381 a SDict begin [/View [/XYZ H.V]/Dest (0:583) cvn /DEST pdfmark end -2 2381 a 396 2488 a Fj(Y)-9 b(ou)20 b(should)f(ha)n(v)o(e)h(recei)n(v)o(ed)e(a)j(cop)o(y) e(of)h(the)g(GNU)h(General)e(Public)h(License)g(along)g(with)g(this)h (program;)d(if)i(not,)396 2596 y(write)h(to:)-2 2680 y SDict begin H.S end -2 2680 a -2 2680 a SDict begin 11.7 H.A end -2 2680 a -2 2680 a SDict begin [/View [/XYZ H.V]/Dest (0:584) cvn /DEST pdfmark end -2 2680 a 396 2776 a Fe(Free)44 b(Software)g(Foundation,)f(Inc.)396 2873 y(59)i(Temple)f(Place)396 2970 y(Suite)g(330)396 3068 y(Boston,)g(MA)89 b(02111-1307)396 3165 y(USA)-2 3345 y SDict begin H.S end -2 3345 a -2 3345 a SDict begin 13 H.A end -2 3345 a -2 3345 a SDict begin [/View [/XYZ H.V]/Dest (0:AUTHOR) cvn /DEST pdfmark end -2 3345 a 396 3673 a Fb(A)l(uthor)784 3673 y SDict begin H.S end 784 3673 a 784 3673 a SDict begin 18.72 H.A end 784 3673 a 784 3673 a SDict begin [/View [/XYZ H.V]/Dest (9.19.14.2) cvn /DEST pdfmark end 784 3673 a -2 3841 a SDict begin H.S end -2 3841 a -2 3841 a SDict begin 13 H.A end -2 3841 a -2 3841 a SDict begin [/View [/XYZ H.V]/Dest (0:587) cvn /DEST pdfmark end -2 3841 a -2 3841 a SDict begin H.S end -2 3841 a -2 3841 a SDict begin 13 H.A end -2 3841 a -2 3841 a SDict begin [/View [/XYZ H.V]/Dest (0:588) cvn /DEST pdfmark end -2 3841 a 396 3947 a Fj(PyGopherd,)18 b(its)j(libraries,)f(documentation,)d(and)i(all)i (included)e(\002les)i(\(e)o(xcept)e(where)g(noted\))g(w)o(as)i(written) f(by)g(John)396 4055 y(Goerzen)698 4055 y SDict begin H.S end 698 4055 a 698 4055 a SDict begin 13 H.A end 698 4055 a 698 4055 a SDict begin [/View [/XYZ H.V]/Dest (0:589) cvn /DEST pdfmark end 698 4055 a Fj(<)p Fe (jgoerzen@complete.org)p Fj(>)d(and)j(cop)o(yright)e(is)j(held)f(as)h (stated)f(in)g(the)h(Cop)o(yright)d(section.)-2 4239 y SDict begin H.S end -2 4239 a -2 4239 a SDict begin 13 H.A end -2 4239 a -2 4239 a SDict begin [/View [/XYZ H.V]/Dest (0:590) cvn /DEST pdfmark end -2 4239 a 396 4329 a Fj(Portions)i(of)g(this)g(manual)g(\(speci\002cally)f(relating)h (to)g(certian)g(UMN)g(gopherd)e(features)h(and)h(characteristics)g (that)396 4437 y(PyGopherd)e(emulates\))i(are)g(modi\002ed)f(v)o (ersions)g(of)h(the)g(original)f(gopherd\(1\))e(manpage)h(accompan)o (ying)f(the)396 4545 y(UMN)k(gopher)d(distrib)n(ution.)h(That)h (document)e(is)j(distrib)n(uted)e(under)g(the)h(same)h(terms)f(as)h (this,)f(and)g(bears)g(the)396 4653 y(follo)n(wing)f(cop)o(yright)f (notices:)-2 4754 y SDict begin H.S end -2 4754 a -2 4754 a SDict begin 11.7 H.A end -2 4754 a -2 4754 a SDict begin [/View [/XYZ H.V]/Dest (0:591) cvn /DEST pdfmark end -2 4754 a 396 4833 a Fe(Copyright)44 b(\(C\))g(1991-2000)88 b(University)43 b(of)i(Minnesota)396 4930 y(Copyright)f(\(C\))g (2000-2002)88 b(John)44 b(Goerzen)g(and)g(other)g(developers)p Black 3800 5569 a Fi(21)p Black eop end %%Page: 22 25 TeXDict begin 22 24 bop -600 -600 a SDict begin /product where{pop product(Distiller)search{pop pop pop version(.)search{exch pop exch pop(3011)eq{gsave newpath 0 0 moveto closepath clip/Courier findfont 10 scalefont setfont 72 72 moveto(.)show grestore}if}{pop}ifelse}{pop}ifelse}if end -600 -600 a 0 TeXcolorgray -611 -810 a SDict begin H.S end -611 -810 a -611 -810 a SDict begin H.R end -611 -810 a -611 -810 a SDict begin [/View [/XYZ H.V]/Dest (page.22) cvn /DEST pdfmark end -611 -810 a Black Black 3171 -132 a Fi(PyGopher)m(d)18 b(Manpa)o(g)o(e)p Black -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:592) cvn /DEST pdfmark end -2 -11 a -2 -11 a SDict begin H.S end -2 -11 a -2 -11 a SDict begin 13 H.A end -2 -11 a -2 -11 a SDict begin [/View [/XYZ H.V]/Dest (0:593) cvn /DEST pdfmark end -2 -11 a 396 72 a Fj(PyGopherd)g(may)i(be)g(do)n (wnloaded,)d(and)j(information)e(found,)g(from)h(its)i(homepage:)396 346 y(https://github)m(.com/michael-lazar/p)o(yg)o(op)o(her)o(d)-2 530 y SDict begin H.S end -2 530 a -2 530 a SDict begin 13 H.A end -2 530 a -2 530 a SDict begin [/View [/XYZ H.V]/Dest (0:596) cvn /DEST pdfmark end -2 530 a -2 540 a SDict begin H.S end -2 540 a -2 540 a SDict begin 13 H.A end -2 540 a -2 540 a SDict begin [/View [/XYZ H.V]/Dest (0:597) cvn /DEST pdfmark end -2 540 a 396 851 a Fb(See)34 b(Also)900 851 y SDict begin H.S end 900 851 a 900 851 a SDict begin 18.72 H.A end 900 851 a 900 851 a SDict begin [/View [/XYZ H.V]/Dest (9.19.15.2) cvn /DEST pdfmark end 900 851 a -2 1019 a SDict begin H.S end -2 1019 a -2 1019 a SDict begin 13 H.A end -2 1019 a -2 1019 a SDict begin [/View [/XYZ H.V]/Dest (0:599) cvn /DEST pdfmark end -2 1019 a 396 1125 a Fj(p)o(ython)19 b(\(1\).)p Black 3800 5569 a Fi(22)p Black eop end %%Trailer userdict /end-hook known{end-hook}if %%EOF pygopherd-3.0.1/doc/pygopherd.sgml000066400000000000000000001117301456676541200171710ustar00rootroot00000000000000 Introduction to PyGopherd Welcome to &PyGopherd;. In a nutshell, &PyGopherd; is a modern dynamic multi-protocol hierarchical information server with a pluggable modularized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for standardized yet extensible per-document metadata. Whew! Read on for information on what all these buzzwords mean. Features Here are some of &PyGopherd;'s features: Provides built-in support for multiple protocols: HTTP (Web), Gopher+, Gopher (RFC1436), Enhanced Gopher0, Gemini, Spartan, and WAP (mobile phones). Protocols can be enabled or disabled as desired. Provides protocol autodetection. That is, &PyGopherd; can listen for all the above protocols on a single port and will automatically respond using the protocol it detects the client is using. Practical effects of this are that you can, for instance, give out a single URL and have it viewable normally on desktop Web browsers and in WAP mode on mobile phones -- and appropriately in various Gopher browsers. Metadata and site links can be entered in a variety of formats, including full UMN dotfile metadata formats as well as Bucktooth gophermap files. Moreover, gophermap files are not limited to Gopher protocols, and can be used for all protocols. Support for inter-protocol linking (linking from Gopher sites to web sites) Virtual folder system lets you serve up anything as if it were regular files and directories. PyGopherd comes with the following virtual folder systems built in: Can present any Unix MBOX, MMDF box, MH directory, Maildir directory, or Babyl mailbox as a virtual folder, the contents of which are the messages in the mailbox. Can use a configurable separator to split a file into multiple parts, the first line of each becoming the name for the virtual folder. Can peek inside a ZIP file and serve it up as first-class site citizens -- metadata can even be stored in the ZIP files. Can serve up the contents of a dictd server as a filesystem. Modular, extensible design: you can use PyGopherd's own PYG extension format, or UMN- or Bucktooth-style executables. Runs on any platform supported by Python 2.2, 2.3, or 2.4. This includes virtually every past and current flavor of Unix (Linux, *BSD, Solaris, SunOS), Windows, MacOS 9.x and X, and more. Some features may not be available on non-Unix platforms. Runs on any platform supported by Java 1.1 via the Jython Python implementation. Tunable server types via configuration directive -- forking or threading. Secure design with support for chrooted execution. Feature-complete, full implementations of: Gopher0 (RFC1435), Gopher+, HTTP, and WAP. Support for automatically finding the titles of HTML documents for presentation in a directory. Versatile configuration file format is both extensible and nicely complementary of the module system. Protocol-independent, handler-dependent caching. This increases performance by letting handlers cache dynamically-generated information -- currently used by the directory handlers. This can improve performance of directories by several orders of magnitude. Because this is a handler cache only, all protocols share the single cache. Since the processing time for the protocols is negligible, this works out very well. Autosensing of MIME types and gopher0 item types. Both are completely configurable. MIME type detection is done using a standard mime.types file, and gopher0 types are calculated by using a configurable regexp-based MIME-to-gophertype map. Heavy support of regular expressions in configuration. ProtocolMultiplexer and HandlerMultiplexer let you choose only those protocols and handlers that you wish your server to support and the order in which they are tried when a request comes in. Full logging via syslog. About Gopher &PyGopherd; started life as a server for the Gopher Internet protocol. With Gopher, you can mount a filesystem (viewing files and folders as if they were local), browse Gopherspace with a web browser, download files, and be interactive with searching. But this is only part of the story. The world of Gopher is more expansive than this. There are two major gopher protocols: Gopher0 (also known as RFC1436) and Gopher+. Gopher0 is a small, simple, lightweight protocol that is very functional yet also extremely easy to implement. Gopher0 clients can be easily placed in small embedded devices or in massive environments like a modern web browser. Gopher+ is based on Gopher0 but extends it by providing document metadata such as file size and MIME type. Gopher+ allows all sorts of neat features, such as configurable metadata (serving up a bunch of photos? Add a Subject field to your metadata to let a customized photo browser display who is pictured) and multiple views of a file (let the user select to view your photos as PNG or JPEG). Quick Start &quickstart; Installation If you are reading this document via the "man" command, it is likely that you have no installation tasks to perform; your system administrator has already installed &PyGopherd;. If you need to install it yourself, you have three options: a system-wide installation with Debian, system-wide installation with other systems, and a single-user installation. You can download the latest version of PyGopherd from Debian System-Wide Installation You may install &PyGopherd; by simply running this command as root: apt-get install pygopherd Other System-Wide Installation Download the tar.gz version of the package from the website. Make sure you have Python 3.7 or above installed; if not, download and install it from . Then run these commands: tar -zxvf pygopherd-x.y.z.tar.gz cd pygopherd-x.y.z python3 setup.py Next, proceed to configuration. Make sure that the /etc/pygopherd/pygopherd.conf file names valid users (setuid and setgid options) and a valid document root (root option). You will type pygopherd to invoke the program. Single-Account Installation Download the tar.gz version of the package from the website. Make sure you have Python 2.2 or above installed; if now, download and install it from . Then run these commands: tar -zxvf pygopherd-z.y.z.tar.gz cd pygopherd-x.y.z Modify conf/pygopherd.conf as follows: Set usechroot = no Set root to something appropriate. Set port to a number greater than 1024. When you want to run &PyGopherd;, you will issue the cd command as above and then type PYTHONPATH=. bin/pygopherd. There is no installation step necessary. Configuration &PyGopherd; is regulated by a configuration file normally stored in /etc/pygopherd/pygopherd.conf. You can specify an alternate configuration file on the command line. The &PyGopherd; distribution ships with a sample pygopherd.conf file that thoroughly documents the configuration file options and settings. Handlers &PyGopherd; defines several handlers which are responsible for finding data on your server and presenting it to the user. The handlers are used to generate things like links to other documents and directory listings. They are also responsible for serving up regular files and even virtual folders. Handlers are specified with the handlers option in pygopherd.conf. This option is a list of handlers to use. For each request that arrives, &PyGopherd; will ask each handler in turn whether or not it can handle the request, and will handle the request according to the first handler that is capable of doing so. If no handlers can handle the request, a file not found error is generated. See the example configuration file for an example. The remaining parts of this section describe the different handlers that ship with &PyGopherd;. dir.DirHandler This handler is a basic one that generates menus based on the contents of a directory. It is used for directories that contain neither a gophermap file nor UMN-style links files, or situations where you have no need for either of those. This handler simply reads the contents of your on-disk directory, determines the appropriate types of each file, and sends the result to the client. The descriptions of each item are usually set to the filename, but the html.HTMLFileTitleHandler may override that. gophermap.BuckGophermapHandler This handler is used to generate directory listings based on gophermap files. It will not read the directory on-disk, instead serving content from the gophermap file only. Gophermaps are useful if you want to present a directory in which the files do not frequently change and there is general information to present. Overall, if you only wish to present information particular to certain files, you should consider using the abstract feature of UMN.UMNDirHandler. The gophermap files contain two types of lines, which are described here using the same convention normally used for command line arguments. In this section, the symbol \t will be used to indicate a tab character, Control-I. full line of informational text gophertypeDESCRIPTION\tselector\thost\tport Note: spaces shown above are for clarity only and should not actually be present in your file. The informational text must not contain any tab characters, but may contain spaces. Informational text will be rendered with gopher type i, which will cause it to be displayed on a client's screen at its particular position in the file. The second type of line represents a link to a file or directory. It begins with a single-character Gopher type (see Gopher Item Types below) followed immediately by a description and a tab character. There is no space or other separator between the gopher type and the description. The description may contain spaces but not tabs. The remaining arguments are optional, but only to the extent that arguments may be omitted only if all arguments after them are also omitted. These arguments are: selector The selector is the name of the file on the server. If it begins with a slash, it is an absolute path; otherwise, it is interpreted relative to the directory that the gophermap file is in. If no selector is specified, the description is also used as the selector. host The host specifies the host on which this resource is located. If not specified, defaults to the current server. port The port specifies the port on which the resource is located. If not specified, defaults to the port the current server is listening on. An example of a gophermap to help illustrate the concept is included with the &PyGopherd; distribution in the file examples/gophermap. file.CompressedFileHandler In order to save space, you might want to store documents on-disk in a compressed format. But then clients would ordinarily have to decompress the files themselves. It would be nice to have the server automatically decompress the files on the fly, sending that result to the client. That's where file.CompressedFileHandler comes in. This handler will take compressed files, pipe them through your chosen decompression program, and send the result directly to clients -- completely transparently. To use this handler, set the decompressors option in the configuration file. This option defines a mapping from MIME encodings (as defined with the encoding option) to decompression programs. Files that are not encoded, or which have an encoding that does not occur in the decompressors map, will not be decompressed by this handler. Please see the sample configuration file for more examples and details about the configuration of this handler. file.FileHandler The file.FileHandler is just that -- its duty is to serve up regular files to clients. html.HTMLFileTitleHandler This handler is used when generating directories and will set the description of HTML files to the HTML title defined in them rather than let it be the default filename. Other than that, it has no effect. UMN gopherd implements a similar policy. mbox handlers There are four mailbox handlers: mbox.MaildirFolderHandler mbox.MaildirMessageHandler mbox.MBoxMessageHandler mbox.MBoxFolderHandler These four handlers provide a unique "virtual folder" service. They allow you to present mailboxes as if they were folders, the items of the folders being the messages in the mailbox, organized by subject. This is useful for presenting mail archives or just making e-mail accessible in a nice and easy fashion. To use these handlers, all you have to do is enable them in your handlers section. They will automatically detect requests for mailboxes and handle them appropriately. The different handlers are for traditional Unix mbox mailboxes (all messages in a single file) and new qmail-stype Maildir mailboxes. You can enable only the two handlers for the specific mailbox type that you use, if desired. pyg.PYGHandler PYG (short for PYGopherd) is a mechanism that provides a tremendous amount of flexibility. Rather than just letting you execute a script like other Gopher or HTTP servers, PYGs are actually loaded up into PyGopherd and become fully-capable first-class virtual handlers. Yet they need not be known ahead of time, and are loaded dynamically. With a PYG handler, you can generate gopher directories, handle searches, generate files, and more on the fly. You can create entire virtual directory trees (for instance, to interface with NNTP servers or with DICT servers), and access them all using the standard Gopher protocol. All of this without having to modify even one line of &PyGopherd; code. If enabled, the pyg.PYGHandler will look for files with the extension .pyg that are marked executable. If found, they will be loaded and run as PYGs. Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it. See the virtual.Virtual handler for more information about passing data to your scripts at runtime. At present, documentation on writing PYGs is not provided, but you may find examples in the pygfarm directory included with the &PyGopherd; distribution. scriptexec.ExecHandler</> <para> This handler implements "old-style" script execution; that is, executing arbitrary programs and piping the result to the client. It is, for the most part, compatible with both scripts written for UMN gopherd and the Bucktooth gopher server. If enabled, it will execute any file that is marked executable in the filesystem. It will normally list scripts as returning plain text, but you may create a custom link to the script that defines it as returning whatever kind of file you desire. Unlike PYGs, this type must be known in advance. </para> <para> The <property>scriptexec.ExecHandler</property> will set environment variables for your scripts to use. They are as follows: </para> <variablelist> <varlistentry> <term>SERVER_NAME</term> <listitem><para>The name of this server as defined in the configuration file or detected from the operating system.</para> </listitem> </varlistentry> <varlistentry> <term>SERVER_PORT</term> <listitem><para>The port this server is listening on.</para> </listitem> </varlistentry> <varlistentry> <term>REMOTE_ADDR</term> <listitem><para>The IP address of the client.</para> </listitem> </varlistentry> <varlistentry> <term>REMOTE_PORT</term> <listitem><para>The port number of the client.</para> </listitem> </varlistentry> <varlistentry> <term>REMOTE_HOST</term> <listitem><para>The same value as <property>REMOTE_ADDR</property></para> </listitem> </varlistentry> <varlistentry> <term>SELECTOR</term> <listitem><para>The file that was requested; that is, the relative path to this script. If the selector included additional parameters after a |, they will be included in this string as well. </para> </listitem> </varlistentry> <varlistentry> <term>REQUEST</term> <listitem><para>The "base" part of the selector; that is, the part leading up to the |.</para> </listitem> </varlistentry> <varlistentry> <term>SEARCHREQUEST</term> <listitem><para>Included only if the client specified search data, this is used if the client is searching for something. </para> </listitem> </varlistentry> </variablelist> <para> See the <property>virtual.Virtual</property> handler for more information about passing data to your scripts at runtime. </para> <para> Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it. </para> </sect1> <sect1 id="handlers.umn"> <title>UMN.UMNDirHandler This is one of the most powerful workhorse handlers in &PyGopherd;. It is designed to emulate most of the ways in which the UMN gopherd distribution generates directories, even going so far as to be bug-compatible in some cases. Generating directories with this handler is often the best general-purpose way to make nice directories in gopherspace. The remainder of the description of the UMN.UMNDirHandler, except for the Abstracts and Info section, is lifted directly from the original UMN gopherd documentation, with light editing, because this handler implements it so exactly that there was no point in rewriting all that documentation :-) Links You can override the default view of a directory as generated by dir.DirHandler by creating what are known as Links in the data tree. The ability to make links to other hosts is how gopher distributes itself among multiple hosts. There are two different ways to make a link. The first and simplest is to create a link file that contains the data needed by the server. By default all files in the gopher data directory starting with a period are taken to be link files. A link file can contain multiple links. To define a link you need to put five lines in a link file that define the needed characteristics for the document. Here is an example of a link. Name=Cheese Ball Recipes Numb=1 Type=1 Port=150 Path=1/Moo/Cheesy Host=zippy.micro.umn.edu The Name= line is what the user will see when cruising through the database. In this case the name is "Cheese Ball Recipes". The "Type=" defines what kind of document this object is. For a list of all defined types, see Gopher Item Types below. For Gopher+ and HTTP, a MIME type is also used, which is determined automatically based on the type you specify. The "Path=" line contains the selector string that the client will use to retrieve the actual document. The Numb= specifies that this entry should be presented first in the directory list (instead of being alphabetized). The "Numb=" line is optional. If it is present it cannot be the last line of the link. The "Host=" and "Port=" lines specify a fully qualified domain name (FQDN) and a port respectively. You may substitute a plus '+' for these two parameters if you wish. The server will insert the current hostname and the current port when it sees a plus in either of these two fields. An easy way to retrieve links is to use the Curses Gopher Client. By pressing '=' You can get information suitable for inclusion in a link file. Overriding Defaults The server looks for a directory called .cap when parsing a directory. The server then checks to see if the .cap directory contains a file with the same name as the file it's parsing. If this file exists then the server will open it for reading. The server parses this file just like a link file. However, instead of making a new object, the parameters inside the .cap/ file are used to override any of the server supplied default values. For instance, say you wanted to change the Title of a text file for gopher, but don't want to change the filename. You also don't want it alphabetized, instead you want it second in the directory listing. You could make a set-aside file in the .cap directory with the same filename that contained the following lines: Name=New Long Cool Name Numb=2 An alternative to .cap files are extended link files. They work just the same as the files described in Links above, but have a somewhat abbreviated format. As an example, if the name of the file was file-to-change, then you could create a file called .names with the following contents: Path=./file-to-change Name=New Long Cool Name Numb=2 Adding Cool Links One cool thing you can do with .Links is to add neato services to your gopher server. Adding a link like this: Name=Cool ftp directory Type=h Path=/URL:ftp://hostname/path/ Host=+ Port=+ Name=Cool web site Type=h Path=/URL:http://hostname/ Host=+ Port=+ Will allow you to link in any FTP or Web site to your gopher. (See url.URLHandler for more details.) You can easily add a finger site to your gopher server thusly: Name=Finger information Type=0 Path=lindner Host=mudhoney.micro.umn.edu Port=79 Hiding an Entry This kind of trick may be necessary in some cases, and thus for object "fred", the overriding .names file entry would be: Type=X Path=./fred by overriding default type to be "X". This may be useful, when for some reason there are symlinks (or whatever) in the directory at which &PyGopherd; looks, and those entries are not desired to be shown at all. Abstracts and Info Many modern gopher server maintainers like to intersperse gopher directory listings with other information -- often, additional information about the contents of files in the directory. The gophermap system provides one way to do that, and abstracts used with UMN gopher directories provides another. Subject to the abstract_headers and abstract_entries configuration file options, this feature allows you to define that extra information. You can do that by simply creating a file named filename.abstract right alongside the regular file in your directory. The file will be interpreted as the abstract. For a directory, create a file named .abstract in the directory. Simple as that! url.HTMLURLHandler &PyGopherd; provides ways for you to link to pages outside Gopherspace -- that is, web pages, FTP sites, and the like. This is accomplished according to the Links to URL specification (see Conforming To below for details). In order to link to a URL (EXCEPT gopher URLs) from a menu, you create a link of type h (regardless of the actual type of the resource that you are linking to) in your gophermap or .Links file that looks like this: /URL:http://www.complete.org/ Modern Gopher clients that follow the Links to URL specification will automatically follow that link when you select it. The rest need some help, and that's where this handler comes in. For Gopher clients that do not follow the Links to URL specification, the url.HTMLURLHandler will automatically generate an HTML document for them on the fly. This document includes a refresh code that will send them to the proper page. You should not disable this handler. url.URLTypeRewriter Some people wish to serve HTML documents from their Gopher server. One problem with that is that links in Gopherspace include an extra type character at the beginning, whereas links in HTTP do not. This handler will remove the extra type character from HTTP requests that come in, allowing a single relative-to-root link to work for both. virtual.Virtual This handler is not intended to ever be used directly, but is used by many other handlers such as the mbox support, PYG handlers, and others. It is used to generate virtual entries in the directory hierarchy -- that is, entries that look normal to a client, but do not actually correspond to a file on disk. One special feature of the virtual.Virtual handler is that you can send information to it at runtime in a manner similar to a CGI script on the web. You do this by adding a question mark after the regular selector, followed by any arbitrary data that you wish to have sent to the virtual request handler. ZIP.ZIPHandler Using zip.ZIPHandler, you can save space on your server by converting part or all of your site into a ZIP file. &PyGopherd; can use the contents of that ZIP file as the contents of your site -- completely transparently. The ZIP file handler must be enabled in the configuration file for this to work. Gopher Item Types When you construct links to files via .Links or gophermap files, or modify the mapping in the configuration file, you will need to know these. Items bearing the "not implemented" text are not served up by &PyGopherd; as it ships, generally due to requirements of customized per-site software, but may be served up via PYG extension modules or other gopher servers. This list was prepared based on RFC1436, the UMN gopherd(1) manpage, and best current practices. 0 Plain text file 1 Directory 2 CSO phone book server (not implemented by &PyGopherd;) 3 Error condition; text that follows is plain text 4 Macintosh file, BinHex format 5 DOS binary archive (not implemented by &PyGopherd;; use type 9 instead) 6 uuencoded file; not directly generated by &PyGopherd; automatically, but can be linked to manually. Most gopher clients will handle this better as type 1. 7 Search 8 Telnet link 9 Binary file + Redundant server (not implemented by &PyGopherd;) c Calendar (not implemented by &PyGopherd;) e Event (not implemented by &PyGopherd;) g GIF-format graphic h HTML file I Any kind of graphic file other than GIF i Informational text included in a directory that is displayed but does not link to any actual file. M MIME multipart/mixed file s Any kind of sound file T tn3270 link X- UMN-specific -- signifies that this entry should not be displayed in a directory entry, but may be accessed via a direct link. This value is never transmitted in any Gopher protocol. pygopherd-3.0.1/doc/pygopherd.txt000066400000000000000000001063161456676541200170520ustar00rootroot00000000000000PYGOPHERD(8) PyGopherd Manual PYGOPHERD(8) NAME PyGopherd - Multiprotocol Information Server SYNOPSIS pygopherd [ configfile ] DESCRIPTION Welcome to PyGopherd. In a nutshell, PyGopherd is a modern dynamic multi-protocol hierarchical information server with a pluggable modu- larized extension system, full flexible caching, virtual files and folders, and autodetection of file types -- all with support for stan- dardized yet extensible per-document metadata. Whew! Read on for infor- mation on this what all these buzzwords mean. FEATURES Here are some of PyGopherd's features: o Provides built-in support for multiple protocols: HTTP (Web), Gopher+, Gopher (RFC1436), Enhanced Gopher0, and WAP (mobile phones). Protocols can be enabled or disabled as desired. o Provides protocol autodetection. That is, PyGopherd can listen for all the above protocols on a single port and will automatically respond using the protocol it detects the client is using. Practical effects of this are that you can, for instance, give out a single URL and have it viewable normally on desktop Web browsers and in WAP mode on mobile phones -- and appropriately in various Gopher browsers. o Metadata and site links can be entered in a variety of formats, including full UMN dotfile metadata formats as well as Bucktooth gophermap files. Moreover, gophermap files are not limited to Gopher protocols, and can be used for all protocols. o Support for inter-protocol linking (linking from Gopher sites to web sites) o Virtual folder system lets you serve up anything as if it were regu- lar files and directories. PyGopherd comes with the following vir- tual folder systems built in: o Can present any Unix MBOX, MMDF box, MH directory, Maildir direc- tory, or Babyl mailbox as a virtual folder, the contents of which are the messages in the mailbox. o Can use a configurable separator to split a file into multiple parts, the first line of each becoming the name for the virtual folder. o Can peek inside a ZIP file and serve it up as first-class site cit- izens -- metadata can even be stored in the ZIP files. o Can serve up the contents of a dictd server as a filesystem. o Modular, extensible design: you can use PyGopherd's own PYG extension format, or UMN- or Bucktooth-style executables. o Runs on any platform supported by Python 2.2 or 2.3. This includes virtually every past and current flavor of Unix (Linux, *BSD, Solaris, SunOS), Windows, MacOS 9.x and X, and more. Some features may not be available on non-Unix platforms. o Runs on any platform supported by Java 1.1 via the Jython Python implementation. o Tunable server types via configuration directive -- forking or threading. o Secure design with support for chrooted execution. o Feature-complete, full implementations of: Gopher0 (RFC1435), Gopher+, HTTP, and WAP. o Support for automatically finding the titles of HTML documents for presentation in a directory. o Versatile configuration file format is both extensible and nicely complementary of the module system. o Protocol-independant, handler-dependant caching. This increases per- formance by letting handlers cache dynamically-generated information -- currently used by the directory handlers. This can improve per- formance of directories by several orders of magnitude. Because this is a handler cache only, all protococls share the single cache. Since the processing time for the protocols is negligable, this works out very well. o Autosensing of MIME types and gopher0 item types. Both are com- pletely configurable. MIME type detection is done using a standard mime.types file, and gopher0 types are calculated by using a config- urable regexp-based MIME-to-gophertype map. o Heavy support of regular expressions in configuration. o ProtocolMultiplexer and HandlerMultiplexer let you choose only those protocols and handlers that you wish your server to support and the order in which they are tried when a request comes in. o Full logging via syslog. ABOUT GOPHER PyGopherd started life as a server for the Gopher Internet protocol. With Gopher, you can mount a filesystem (viewing files and folders as if they were local), browse Gopherspace with a web browser, download files, and be interactive with searching. But this is only part of the story. The world of Gopher is more expan- sive than this. There are two major gopher protocols: Gopher0 (also known as RFC1436) and Gopher+. Gopher0 is a small, simple, lightweight protocol that is very functional yet also extremely easy to implement. Gopher0 clients can be easily places in small embedded devices or in massive environments like a modern web browser. Gopher+ is based on Gopher0 but extends it by providing document meta- data such as file size and MIME type. Gopher+ allows all sorts of neat features, such as configurable metadata (serving up a bunch of photos? Add a Subject field to your metadata to let a customized photo browser display who is pictured) and multiple views of a file (let the user select to view your photos as PNG or JPEG). QUICK START If you have already installed PyGopherd system-wide, or your adminis- trator has done that for you, your task for setting up PyGopherd for the first time is quite simple. You just need to set up your configu- ration file, make your folder directory, and run it! You can quickly set up your configuration file. The distribution includes two files of interest: conf/pygopherd.conf and conf/mime.types. Debian users will find the configuration file pre- installed in /etc/pygopherd/pygopherd.conf and the mime.types file pro- vided by the system already. Open up pygopherd.conf in your editor and adjust to suit. The file is heavily commented and you can refer to it for detailed information. Some settings to take a look at include: detach, pidfile, port, usech- root, setuid, setgid, and root. These may or may not work at their defaults for you. The remaining ones should be fine for a basic setup. Invoke PyGopherd with pygopherd path/to/configfile (or /etc/init.d/pygopherd start on Debian). Place some files in the loca- tion specified by the root directive in the config file and you're ready to run! INSTALLATION If you are reading this document via the "man" command, it is likely that you have no installation tasks to perform; your system administra- tor has already installed PyGopherd. If you need to install it your- self, you have three options: a system-wide installation with Debian, system-wide installation with other systems, and a single-user installation. You can download the latest version of PyGopherd from DEBIAN SYSTEM-WIDE INSTALLATION If you are tracking Debian unstable, you may install PyGopherd by sim- ply running this command as root: apt-get install pygopherd If you are not tracking Debian unstable, download the .deb package from the PyGopherd website and then run dpkg -i to install the downloaded package. Then, skip to the configuration section below. You will use /etc/init.d/pygopherd start to start the program. OTHER SYSTEM-WIDE INSTALLATION Download the tar.gz version of the package from the website. Make sure you have Python 2.2 or above installed; if now, download and install it from . Then run these commands: tar -zxvf pygopherd-x.y.z.tar.gz cd pygopherd-x.y.z python2.2 setup.py Some systems will use python or python2.3 in place of python2.2. Next, proceed to configuration. Make sure that the /etc/pygo- pherd/pygopherd.conf file names valid users (setuid and setgid options) and a valid document root (root option). You will type pygopherd to invoke the program. SINGLE-ACCOUNT INSTALLATION Download the tar.gz version of the package from the website. Make sure you have Python 2.2 or above installed; if now, download and install it from . Then run these commands: tar -zxvf pygopherd-z.y.z.tar.gz cd pygopherd-x.y.z Modify conf/pygopherd.conf as follows: o Set usechroot = no o Comment out (add a # sign to the start of the line) the pidfile, setuid, and setgid lines. o Set root to osomething appropriate. o Set port to a number greater than 1024. When you want to run PyGopherd, you will issue the cd command as above and then type PYTHONPATH=. bin/pygopherd. There is no installation step necessary. CONFIGURATION PyGopherd is regulated by a configuratoin file normally stored in /etc/pygopherd/pygopherd.conf. You can specify an alternate configura- tion file on the command line. The PyGopherd distribution ships with a sample pygopherd.conf file that thoroughly documents the configuration file options and settings. OPTIONS All PyGopherd configuratoin is done via the configuration file. There- fore, the program has only one command-line option: configfile This option argument specifies the location of the configuration file that PyGopherd is to use. HANDLERS PyGopherd defines several handlers which are responsible for finding data on your server and presenting it to the user. The handlers are used to generate things like links to other documents and directory listings. They are also responsible for serving up regular files and even virtual folders. Handlers are specified with the handlers option in pygopherd.conf. This option is a list of handlers to use. For each request that arrives, PyGopherd will ask each handler in turn whether or not it can handle the request, and will handle the request according to the first handler that is capable of doing so. If no handlers can handle the request, a file not found error is generated. See the example configu- ration file for an example. The remaining parts of this section describe the different handlers that ship with PyGopherd. Please note that some versions of this man- ual may show the handlers in all caps; however, their names are not all caps and are case-sensitive. DIR.DIRHANDLER This handler is a basic one that generates menus based on the contents of a directory. It is used for directories that contain neither a gophermap file nor UMN-style links files, or situations where you have no need for either of those. This handler simply reads the contents of your on-disk directory, determines the appropriate types of each file, and sends the result to the client. The descriptions of each item are usually set to the file- name, but the html.HTMLFileTitleHandler may override that. GOPHERMAP.BUCKGOPHERMAPHANDLER This handler is used to generate directory listings based on gophermap files. It will not read the directory on-disk, instead serving content from the gophermap file only. Gophermaps are useful if you want to present a directory in which the files do not frequently change and there is general information to present. Overall, if you only wish to present information particular to certain files, you should consider using the abstract feature of UMN.UMNDirHandler. The gophermap files contain two types of lines, which are described here using the same convention normally used for command line argu- ments. In this section, the symbol \t will be used to indicate a tab character, Control-I. full line of informational text gophertypeDESCRIPTION [ \tselector [ \thost [ \tport ] ] ] Note: spaces shown above are for clarity only and should not actually be present in your file. The informational text must not contain any tab characters, but may contain spaces. Informational text will be rendered with gopher type i, which will cause it to be displayed on a client's screen at its par- ticular position in the file. The second type of line represents a link to a file or directory. It begins with a single-character Gopher type (see Gopher Item Types below) followed immediately by a description and a tab character. There is no space or other separator between the gopher type and the description. The description may contain spaces but not tabs. The remaining arguments are optional, but only to the extent that argu- ments may be omitted only if all arguments after them are also omitted. These arguments are: selector The selector is the name of the file on the server. If it begins with a slash, it is an absolute path; otherwise, it is interpreted relative to the directory that the gophermap file is in. If no selector is specified, the description is also used as the selector. host The host specifies the host on which this resource is located. If not specified, defaults to the current server. port The port specifies the port on which the resource is located. If not specified, defaults to the port the current server is listening on. An example of a gophermap to help illustrate the concept is included with the PyGopherd distribution in the file examples/gophermap. FILE.COMPRESSEDFILEHANDLER In order to save space, you might want to store documents on-disk in a compressed format. But then clients would ordinarily have to decom- press the files themselves. It would be nice to have the server auto- matically decompress the files on the fly, sending that result to the client. That's where file.CompressedFileHandler comes in. This handler will take compressed files, pipe them through your chosen decompression program, and send the result directly to clients -- com- pletely transparently. To use this handler, set the decompressors option in the configuration file. This option defines a mapping from MIME encodings (as defined with the encoding option) to decompression programs. Files that are not encoded, or which have an encoding that does not occur in the decompressors map, will not be decompressed by this handler. Please see the sample configuration file for more examples and details about the configuration of this handler. FILE.FILEHANDLER The file.FileHandler is just that -- its duty is to serve up regular files to clients. HTML.HTMLFILETITLEHANDLER This handler is used when generating directories and will set the description of HTML files to the HTML title defined in them rather than let it be the default filename. Other than that, it has no effect. UMN gopherd implements a similar policy. MBOX HANDLERS There are four mailbox handlers: o mbox.MaildirFolderHandler o mbox.MaildirMessageHandler o mbox.MBoxMessageHandler o mbox.MBoxFolderHandler These four handlers provide a unique "virtual folder" service. They allow you to present mailboxes as if they were folders, the items of the folders being the messages in the mailbox, organized by subject. This is useful for presenting mail archives or just making e-mail accessible in a nice and easy fashion. To use these handlers, all you have to do is enable them in your han- dlers section. They will automatically detect requests for mailboxes and handle them appropriately. The different handlers are for traditional Unix mbox mailboxes (all messages in a single file) and new qmail-stype Maildir mailboxes. You can enable only the two handlers for the specific mailbox type that you use, if desired. PYG.PYGHANDLER PYG (short for PYGopherd) is a mechanism that provides a tremendous amount of flexibility. Rather than just letting you execute a script like other Gopher or HTTP servers, PYGs are actually loaded up into PyGopherd and become fully-capable first-class virtual handlers. Yet they need not be known ahead of time, and are loaded dynamically. With a PYG handler, you can generate gopher directories, handle searches, generate files, and more on the fly. You can create entire virtual directory trees (for instance, to interface with NNTP servers or with DICT servers), and access them all using the standard Gopher protocol. All of this without having to modify even one line of PyGo- pherd code. If enabled, the pyg.PYGHandler will look for files with the extension .pyg that are marked executable. If found, they will be loaded and run as PYGs. Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it. See the virtual.Virtual handler for more information about passing data to your scripts at runtime. At present, documentation on writing PYGs is not provides, but you may find examples in the pygfarm directory included with the PyGopherd dis- tribution. SCRIPTEXEC.EXECHANDLER This handler implements "old-style" script execution; that is, execut- ing arbitrary programs and piping the result to the client. It is, for the most part, compatible with both scripts written for UMN gopherd and the Bucktooth gopher server. If enabled, it will execute any file that is marked executable in the filesystem. It will normally list scripts as returning plain text, but you may create a custom link to the script that defines it as returning whatever kind of file you desire. Unlike PYGs, this type must be known in advance. The scriptexec.ExecHandler will set environment variables for your scripts to use. They are as follows: SERVER_NAME The name of this server as defined in the configuration file or detected from the operating system. SERVER_PORT The port this server is listening on. REMOTE_ADDR The IP address of the client. REMOTE_PORT The port number of the client. REMOTE_HOST The same value as REMOTE_ADDR SELECTOR The file that was requested; that is, the relative path to this script. If the selector included additional parameters after a |, they will be included in this string as well. REQUEST The "base" part of the selector; that is, the part leading up to the |. SEARCHREQUEST Included only if the client specified search data, this is used if the client is searching for something. See the virtual.Virtual handler for more information about passing data to your scripts at runtime. Please note: this module provides the capability to execute arbitrary code. Please consider the security ramifications of that before enabling it. UMN.UMNDIRHANDLER This is one of the most powerful workhorse handlers in PyGopherd. It is designed to emulate most of the ways in which the UMN gopherd dis- tribution generates directories, even going so far as to be bug-compat- ible in some cases. Generating directories with this handler is often the best general-purpose way to make nice directories in gopherspace. The remainder of the description of the UMN.UMNDirHandler, except for the Abstracts and Info section, is lifted directly from the original UMN gopherd documentation, with light editing, because this handler implements it so exactly that there was no point in rewriting all that documentation :-) LINKS You can override the default view of a directory as generated by dir.DirHandler by creating what are known as Links in the data tree. The ability to make links to other hosts is how gopher distributes itself among multiple hosts. There are two different ways to make a link. The first and simplest is to create a link file that contains the data needed by the server. By default all files in the gopher data directory starting with a period are taken to be link files. A link file can contain multiple links. To define a link you need to put five lines in a link file that define the needed characteristics for the document. Here is an example of a link. Name=Cheese Ball Recipes Numb=1 Type=1 Port=150 Path=1/Moo/Cheesy Host=zippy.micro.umn.edu The Name= line is what the user will see when cruising through the database. In this case the name is "Cheese Ball Recipes". The "Type=" defines what kind of document this object is. For a list of all defined types, see Gopher Item Types below. For Gopher+ and HTTP, a MIME type is also used, which is determined automatically based on the type you specify. The "Path=" line contains the selector string that the client will use to retrieve the actual document. The Numb= specifies that this entry should be presented first in the directory list (instead of being alphabetized). The "Numb=" line is optional. If it is present it can- not be the last line of the link. The "Port=" and "Host=" lines spec- ify a fully qualified domain name (FQDN) and a port respectively. You may substitute a plus '+' for these two parameters if you wish. The server will insert the current hostname and the current port when it sees a plus in either of these two fields. An easy way to retrieve links is to use the Curses Gopher Client. By pressing '=' You can get information suitable for inclusion in a link file. OVERRIDING DEFAULTS The server looks for a directory called .cap when parsing a directory. The server then checks to see if the .cap directory contains a file with the same name as the file it's parsing. If this file exists then the server will open it for reading. The server parses this file just like a link file. However, instead of making a new object, the parame- ters inside the .cap/ file are used to override any of the server sup- plied default values. For instance, say you wanted to change the Title of a text file for gopher, but don't want to change the filename. You also don't want it alphabetized, instead you want it second in the directory listing. You could make a set-aside file in the .cap directory with the same file- name that contained the following lines: Name=New Long Cool Name Numb=2 An alternative to .cap files are extended link files. They work just the same as the files described in Links above, but have a somewhat abbreviated format. As an example, if the name of the file was file- to-change, then you could create a file called .names with the follow- ing contents: Path=./file-to-change Name=New Long Cool Name Numb=2 ADDING COOL LINKS One cool thing you can do with .Links is to add neato services to your gopher server. Adding a link like this: Name=Cool ftp directory Type=h Path=/URL:ftp://hostname/path/ Host=+ Port=+ Name=Cool web site Type=h Path=/URL:http://hostname/ Host=+ Port=+ Will allow you to link in any FTP or Web site to your gopher. (See url.URLHandler for more details.) You can easily add a finger site to your gopher server thusly: Name=Finger information Type=0 Path=lindner Host=mudhoney.micro.umn.edu Port=79 HIDING AN ENTRY This kind of trick may be necessary in some cases, and thus for object "fred", the overriding .names file entry would be: Type=X Path=./fred by overriding default type to be "X". This kind of hideouts may be usefull, when for some reason there are symlinks (or whatever) in the directory at which PyGopherd looks at, and those entries are not desired to be shown at all. ABSTRACTS AND INFO Many modern gopher server maintainers like to intersperse gopher direc- tory listings with other information -- often, additional information about the contents of files in the directory. The gophermap system provides one way to do that, and abstracts used with UMN gopher direc- tories provides another. Subject to the abstract_headers and abstract_entries configuration file options, this feature allows you to define that extra information. You can do that by simply creating a file named filename.abstract right alongside the regular file in your directory. The file will be inter- preted as the abstract. For a directory, create a file named .abstract in the directory. Simple as that! URL.HTMLURLHANDLER PyGopherd provides ways for you to link to pages outside Gopherspace -- that is, web pages, FTP sites, and the like. This is accomplished according to the Links to URL specification (see Conforming To below for details). In order to link to a URL (EXCEPT gopher URLs) from a menu, you create a link of type h (regard- less of the actual type of the resource that you are linking to) in your gophermap or .Links file that looks like this: /URL:http://www.complete.org/ Modern Gopher clients that follow the Links to URL specification will automatically follow that link when you select it. The rest need some help, and that's where this handler comes in. For Gopher clients that do not follow the Links to URL specification, the url.HTMLURLHandler will automatically generate an HTML document for them on the fly. This document includes a refresh code that will send them to the proper page. You should not disable this handler. URL.URLTYPEREWRITER Some people wish to serve HTML documents from their Gopher server. One problem with that is that links in Gopherspace include an extra type character at the beginning, whereas links in HTTP do not. This handler will remove the extra type character from HTTP requests that come in, allowing a single relative-to-root link to work for both. VIRTUAL.VIRTUAL This handler is not intended to ever be used directly, but is used by many other handlers such as the mbox support, PYG handlers, and others. It is used to generate virtual entries in the directory hierarchy -- that is, entries that look normal to a client, but do not actually cor- respond to a file on disk. One special feature of the virtual.Virtual handler is that you can send information to it at runtime in a manner similar to a CGI script on the web. You do this by adding a question mark after the regular selector, followed by any arbitrary data that you wish to have sent to the vir- tual request handler. GOPHER ITEM TYPES When you construct links to files via .Links or gophermap files, or modify the mapping in the configuration file, you will need to know these. Items bearing the "not implemented" text are not served up by PyGopherd as it ships, generally due to requirements of customized per- site software, but may be served up via PYG extension modules or other gopher servers. This list was prepared based on RFC1436, the UMN gopherd(1) manpage, and best current practices. 0 Plain text file 1 Directory 2 CSO phone book server (not implemented by PyGopherd) 3 Error condition; text that follows is plain text 4 Macintosh file, BinHex format 5 DOS binary archive (not implemented by PyGopherd; use type 9 instead) 6 uuencoded file; not directly generated by PyGopherd automati- cally, but can be linked to manually. Most gopher clients will handle this better as type 1. 7 Search 8 Telnet link 9 Binary file + Redundant server (not implemented by PyGopherd) c Calendar (not implemented by PyGopherd) e Event (not implemented by PyGopherd) g GIF-format graphic h HTML file I Any kind of graphic file other than GIF i Informational text included in a directory that is displayed but does not link to any actual file. M MIME multipart/mixed file s Any kind of sound file T tn3270 link X - UMN-specific -- signifies that this entry should not be dis- played in a directory entry, but may be accessed via a direct link. This value is never transmitted in any Gopher protocol. CONFORMING TO o The Internet Gopher Protocol as specified in RFC1436 o The Gopher+ upward-compatible enhancements to the Internet Gopher Protocol from the University of Minnesota as laid out at . o The gophermap file format as originally implemented in the Bucktooth gopher server and described at . o The Links to URL specification as laid out by John Goerzen at . o The UMN format for specifying object attributes and links with .cap, .Links, .abstract, and similar files as specified elsewhere in this document and implemented by UMN gopherd. o The PYG format for extensible Python gopher objects as created for PyGopherd. o Hypertext Transfer Protocol HTTP/1.0 as specified in RFC1945 o Hypertext Markup Language (HTML) 3.2 and 4.0 Transitional as speci- fied in RFC1866 and RFC2854. o Maildir as specified in and . o The mbox mail storage format as specified in . o Registered MIME media types as specified in RFC2048. o Script execution conforming to both UMN standards as laid out in UMN gopherd(1) and Bucktooth standards as specified at , so far as each can be implemented consistent with secure design prin- ciples. o Standard Python 2.2.1 or above as implemented on POSIX-compliant sys- tems. o WAP/WML as defined by the WAP Forum. BUGS Reports of bugs should be sent via e-mail to the PyGopherd bug-tracking system (BTS) at or submitted online using the Web interface at . The Web site also lists all current bugs, where you can check their status or contribute to fixing them. COPYRIGHT PyGopherd is Copyright (C) 2002, 2003 John Goerzen. 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; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MER- CHANTABILITY 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: Free Software Foundation, Inc. 59 Temple Place Suite 330 Boston, MA 02111-1307 USA AUTHOR PyGopherd, its libraries, documentation, and all included files (except where noted) was written by John Goerzen and copyright is held as stated in the Copyright section. Portions of this manual (specifically relating to certian UMN gopherd features and characteristics that PyGopherd emulates) are modified ver- sions of the original gopherd(1) manpage accompanying the UMN gopher distribution. That document is distributed under the same terms as this, and bears the following copyright notices: Copyright (C) 1991-2000 University of Minnesota Copyright (C) 2000-2002 John Goerzen and other developers PyGopherd may be downloaded, and information found, from its homepage via either Gopher or HTTP: PyGopherd may also be downloaded using Subversion. Additionally, the distributed tar.gz may be updated with a simple "svn update" command; it is ready to go. For information on getting PyGopherd with Subver- sion, please visit . SEE ALSO python (1). John Goerzen 25 August 2003 PYGOPHERD(8) pygopherd-3.0.1/doc/quickstart.sgml000066400000000000000000000030361456676541200173610ustar00rootroot00000000000000 If you have already installed &PyGopherd; system-wide, or your administrator has done that for you, your task for setting up &PyGopherd; for the first time is quite simple. You just need to set up your configuration file, make your folder directory, and run it! You can quickly set up your configuration file. The distribution includes two files of interest: conf/pygopherd.conf and conf/mime.types. Debian users will find the configuration file pre-installed in /etc/pygopherd/pygopherd.conf and the mime.types file provided by the system already. Open up pygopherd.conf in your editor and adjust to suit. The file is heavily commented and you can refer to it for detailed information. Some settings to take a look at include: detach, pidfile, port, usechroot, setuid, setgid, and root. These may or may not work at their defaults for you. The remaining ones should be fine for a basic setup. Invoke &PyGopherd; with pygopherd path/to/configfile (or /etc/init.d/pygopherd start on Debian). Place some files in the location specified by the root directive in the config file and you're ready to run! pygopherd-3.0.1/doc/standards/000077500000000000000000000000001456676541200162645ustar00rootroot00000000000000pygopherd-3.0.1/doc/standards/Gopher+.txt000066400000000000000000001051651456676541200203340ustar00rootroot00000000000000 Gopher+ upward compatible enhancements to the Internet Gopher protocol Farhad Anklesaria, Paul Lindner, Mark P. McCahill, Daniel Torrey, David Johnson, Bob Alberti Microcomputer and Workstation Networks Center / Computer and Information Systems University of Minnesota July 30, 1993 gopher+ n. 1. Hardier strains of mammals of the family Geomyidae. 2. (Amer. colloq.) Native or inhabitant of Minnesota, the Gopher state, in full winter regalia (see PARKA). 3. (Amer. colloq.) Executive secretary. 4. (computer tech.) Software following a simple protocol for burrowing through a TCP/IP internet, made more powerful by simple enhancements (see CREEPING FEATURISM). Abstract The internet Gopher protocol was designed for distributed document search and retrieval. The documents "The internet Gopher protocol: a distributed document search and retrieval protocol" and internet RFC 1436 describe the basic protocol and has an overview of how to implement new client and server applications. This document describes a set of enhancements to the syntax, semantics and functionality of the original Gopher protocol. Distribution of this document is unlimited. Please send comments to the Gopher development team: . Implementation of the mechanisms described here is encouraged. 1. Introduction The Internet Gopher protocol was designed primarily to act as a distributed document delivery system. It has enjoyed increasing popularity, and is being used for purposes that were not visualized when the protocol was first outlined. The rest of this document describes the Gopher+ enhancements in a non- rigorous but easily read and understood way. There is a short BNF-like section at the end for exact syntax descriptions. Throughout the document, "F" stands for the ASCII TAB character. There is an implicit carriage return and linefeed at the ends of lines; these will only be explicitly mentioned where necessary to avoid confusion. To understand this document, you really must be familiar with the basic Gopher protocol. Servers and clients understanding the Gopher+ extensions will transmit extra information at the ends of list and request lines. Old, basic gopher clients ignore such information. New Gopher+ aware servers continue to work at their old level with unenhanced clients. The extra information that can be communicated by Gopher+ clients may be used to summon new capabilities to bridge the most keenly felt shortcomings of the venerable old Gopher. 2. How does Gopher+ work? Gopher+ enhancements rely on transmitting an "extra" tab delimited fields beyond what regular (old) Gopher servers and clients now use. If most existing (old) clients were to encounter extra stuff beyond the "port" field in a list (directory), most would ignore it. Gopher+ servers will return item descriptions in this form: 1Display stringFselector stringFhostFportFextra stuff If an existing (old) client has problems with additional information beyond the port, it should not take much more than a simple tweak to have it discard unneeded stuff. 2.1 Advisory issued to client maintainers. If it does not do this already, your existing client should be modified as soon as possible to ignore extra fields beyond what it expects to find. This will ensure thatyour clients does not break when it encounters Gopher+ servers in gopherspace. All the regular Gopher protocol info remains intact except for: (1) Instead of just a CRLF after the port field in any item of a list (directory) there may be an optional TAB followed by extra stuff as noted above (explanation to follow). (2) In the original Gopher protocol, there was provision for a date-time descriptor (sec 3.6) to be sent after the selector (for use by autoindexer beasts). As far as we know, while the descriptor is implemented in the Mac server, it is not in any other server and no clients or daemons use it. This is a good time to withdraw this feature. The basic gopher protocol has been revised for the final time and will be frozen. 2.2 Gopher+ item lists. Gopher servers that can utilize the Gopher+ enhancements will send some additional stuff (frequently the character "+") after the port field describing any list item. eg: 1Some old directoryFfoo selectorFhost1Fport1 1Some new directoryFbar selectorFhost1Fport1F+ 0Some file or otherFmoo selectorFhost2Fport2F+ The first line is the regular old gopher item description. The second line is new Gopher+ item description. The third line is a Gopher+ description of a document. Old gopher clients can request the latter two items using old format gopher selector strings and retrieve the items. New, Gopher+ savvy clients will notice the trailing + and know that they can do extra things with these kinds of items. 2.3 Gopher+ data transfer. If a client sends out a Gopher+ type request to a server (by tagging on a tab and a "+" to the request): bar selectorF+ The server may return the response in one of three ways; examples below: +5340 +-1. +-2 The first response means: I am going to send exactly 5340 bytes at you and they will begin right after this line. The second response means: I have no idea how many bytes I have to send (or I am lazy), but I will send a period on a line by itself when I am done. The third means: I really have no idea how many bytes I have to send, and what's more, they COULD contain the . pattern, so just read until I close the connection. The first character of a response to a Gopher+ query denotes success (+) or failure (-). Following that is a token to be interpreted as a decimal number. If the number is >= 0, it describes the length of the dataBlock. If = -1, it means the data is period terminated. If = -2, it means the data ends when the connection closes. The server may return an error also, as in: --1. The (short!) error message will be in ASCII text in the data part. The first token on the first line of the error text (data) contains an error-code (an integer). It is recommended that the first line also contain the e-mail address of the administrator of the server (in angle brackets). Both the error-code and the email address may easily be extracted by the client. Subsequent lines contain a short error message that may be displayed to the user. Basic error codes are: 1 Item is not available. 2 Try again later ("eg. My load is too high right now.") 3 Item has moved. Following the error-code is the gopher descriptor of where it now lives. More error codes may be defined as the need arises. This should be obvious: if the client sends out an "old" Gopher kind of request: bar selector the server will know that it is talking to an old client and will respond in the old way. This means that old gopher clients can still access information on Gopher+ servers. 2.4 Gopher+ client requests. Clients can send requests to retrieve the contents of an item in this form: selectorstringF+[representation][FdataFlag][dat ablock] If dataFlag is '0', or nonexistent, then the client will not send any data besides the selector string. If the dataFlag is '1' then a block of data will follow in the same format as Section 2.3. The client can send a large amount of data to the server in the dataBlock. Representations or alternative views of an item's contents may be discovered by interrogating the server about the item's attribute information; this is explained below. Note that in the original Gopher protocol, a query submitted to an index server might have a selector string followed by a TAB and the words for which the index server was being asked to search. In Gopher+, the extra TAB and Gopher+ information follow the words for which the server is being asked to search. Gopher+ client have to be smart enough to know that in the case of a type 7 item (an index server) they append the Gopher+ information after the words being searched for. 2.5 Gopher+ Item Attribute Information. The most basic enhancement of Gopher+ items is the ability to associate information about an item such as size, alternative views, the administrator, an abstract, etc. with the item. To get Attribute Information, a client can send out a request to the gopher server that looks like this: selector stringF! (think of "!" as an upside-down i for "information"). To the server this means "Instead of returning the contents of the item, return the item's Attribute Information". The Attribute Information is returned as an ASCII text stream containing blocks of information.For example, a server might return: +INFO: 0Some file or otherFmoo selectorFhost2Fport2F+ +ADMIN: Admin: Frodo Gophermeister Mod-Date: Wed Jul 28 17:02:01 1993 <19930728170201> +VIEWS: Text/plain: <10k> application/postscript: <100k> Text/plain De_DE: <15k> application/MacWriteII: <45K> +ABSTRACT: This is a short (but multi-line) abstract about the item. Two or three lines ought to be enough The beginning of a block of information is denoted by a "+" in column 1 of a line. Another way to think of it is: the name of each block begins with a + and the rest of the name cannot contain a +. Each line of information within a block begins with a space so that it is easy to locate the beginning of a block. There can be multiple blocks of information about an item, but the first block must be the one-line +INFO block containing the keyword +INFO followed by the gopher item description. This is done to make it easy to associate informational attributes with the gopher items to which they refer (see section 2.7 for some good reasons for doing this). The very first line of Attribute Information for an item contains a one-line +INFO block containing the gopher descriptor for the item. All Gopher+ servers must return an "+INFO" block for all items listed by the server. Also present may be an +ADMIN block that can be many lines long. The server must also send an +ADMIN block when asked to send all the item's attributes (as in the example above). The +ADMIN block must contain at least an Admin attribute and Mod-Date attributes, though there may be many other administrative items also present in the +ADMIN block. The Admin (the administrator of the item) and Date (the date of the item's last modification) attributes are required to be returned by the server, and other optional attributes may be returned as well. In this example, there are two pieces of information within the +ADMIN block (Admin and Mod-Date). The Admin attribute must contain the e-mail address of an administrator inside angle brackets. The Admin line might also contain the administrator's name and phone number. The Date line must contain the modification date in angle brackets. The format of the date is where YYYY is year, MM is month, DD is day, hh is hours, mm is minutes, and ss is seconds. The third block in the example is the +VIEWS block. This block lists different formats in which the document can be retrieved. The first format listed is what the server believes to be the preferred format. A gopher client might display the list of possible view labels of the item to the user and let the user select the view they prefer. Alternatively, a smart client might look at the content of the labels and preferentially retrieve Postscript views of items. Note that the view labels are structured. View labels specify a Content-Type (application/Postscript, Text/plain, etc.), an optional language (En_US, De_DE, etc.) and an optional size. Note that the View labels for content type use the MIME content types to specify names of the variious views. The optional language descriptors use the ISO-639 codes for representing languages to name the language. Smart clients might want to translate these rather cryptic codes into something mere mortals can read and understand. The client software can pick off the size of each view IF there are any angle brackets on the line. There might not be a size that the server cares to tell you about. Also this might NOT be the exact size that the server will wind up delivering to you if you ask for it... but it should be reasonably close. This information makes it possible for clever clients to select views based on size, data representation, or language. See section 2.6 for how alternate representations (views) are retrieved. The next block in the example is an (optional) +ABSTRACT. Here the block consists of lines of text that might be displayed to the user. Other blocks of information can defined and added as the need arises. For instance, a Neuromancer-esque 3-D cyberspace attribute might be accommodated by including a 3D-ICON block (with an image to display in 3-space) and a 3D-COORDINATE block (with y,x, and z coordinates). More immediate needs can also addressed by defining other information blocks. For instance, a SCRIPT block would be a natural place to put information for scripting telnet sessions. Information blocks give us an extensible way of adding attributes (or what Macintosh programmers call resources) to gopher items. Some of the really cool ideas we have for information attributes may require sending large amounts of data, some of which may not be easily represented as ASCII text, but the idea of the attributes information is that it is a relatively compact list of attributes. These somewhat conflicting desires can be reconciled by allowing references to gopher items in an attribute. For example, an +ABSTRACT block might be returned this way: +ABSTRACT: 0long abstractFselectorFhost2Fport2F+ In this example, the abstract is a document that resides on a gopher server. By allowing references to to gopher items, we can also accommodate data that must be sent in an 8-bit clear stream by using the Gopher+ methods for retrieving binary data. If both a reference to an attribute and an explicit value for the attribute are present in an attribute list, the preferred version is the explicit value. In the example below, the preferred version is "the short abstract goes here". +ABSTRACT: 0long abstractFselectorFhost2Fport2F+ the short abstract goes here Note that if you want to have several views of (for example) an +ABSTRACT this is possible by using a reference to a item residing on a gopher server because the item can have its own attributes. Attributes names are case sensitive (easier to match and more of them). There is no need to "preregister" all possible attributes since we cannot anticipate all possible future needs. However it would be reasonable to maintain a registry for implementors and administrators so duplication can be avoided. Server implementors or administrators can request that new attributes be included in the attribute registry. Dream on: What gets us excited are alternate representations for directory lists. Sure, the standard representation for a gopher directory list is known to us all. But isn't hypertext (in a WWW sense) an alternate kind of directory list? We also envisioned a "geographical view" (GView?) mapping servers onto a map of the world (throw up a gif picture and then overlay dots based on latitude and longitude or xy coordinates). OK. Dream off. Note that interested parties outside gopherspace have long and complex wish-lists for "attributes" that all well-dressed Internet citizens should have. We don't want to comment on the use or value of these laundry- lists. Suffice it to say that nothing precludes server administrators from including whatever attributes they see fit to include. Certainly IAFA blocks are desirable, bearing UDIs, URL's or whatever else is desired. The gopher community will probably arrive at a list of "recommended" attributes that server administrators should try to support. Because not every server administrator sees advantage to cluttering Attribute Info files with information their primary users will never need, it does not seem fair to "force" folks to include them; most will just ignore the harsh protocol guideline and the value of the protocol will be diminished. We want to mandate as little as we possibly can. 2.6 Using Attribute Info: Alternate representations (+VIEWS). The user may locate a document and wonder if there are representations of it besides, say, the standard Text. Using the appropriate client incantation (Option Double-Click? or whatever) the user indicates a wish to see what's available. The client retrieves the Attribute Information, displays the list of views to the user in some kind of scrolling list dialog. User selects a line and client now requests the document in say, Postscript representation: the selectorF+application/Postscript Smart clients are not precluded from doing things like "Always get Postscript if you can" or "Always get Postscript if that is less than 700K in size." etc. And the "smarter" you make it, the hairier your client will become - unless you are a user interface wizard of awesome proportions. While the example above is of fetching a document's postscript view, there is nothing precluding having different views for directories. In the dream sequence earlier, we imagined a geographic view of a directory. For a client to fetch that view, it would say this: the selectorF+GView 2.7 Getting attributes for all items in a directory in one transaction. Heavyweight/clever/special-purpose clients may want to know all the attributes of items in a given directory in one transaction. The "$" command is used to request all the attributes of a directory at once. For instance, a client might sent the request: selector stringF$ and the server might return this: +INFO: 0Salmon dogsFsome selectorFhost2Fport2F+ +ADMIN: Admin: Frodo Gophermeister Mod-Date: August 15, 1992 <19920815185503> +VIEWS: Text/plain: <10k> application/Postscript De_DE: <100k> +ABSTRACT: A great recipe for making salmon +INFO: 0Hot pupsFother selectorFhost3Fport3F+ +ADMIN: Admin: Bilbo Gophernovice Date: <19910101080003> In this example, the server returned the attribute lists for two items because there were only two items in the directory.. The client software can easily separate the attributes for the items since each attribute list starts with "+INFO". It is also easy for the client to use the "$" command to get directory listings since the gopher item descriptor is on the +INFO line for each item. Note that the $ command is the only way to find the administrator of a remote link. To get the full attribute information for a link on another machine may require asking the master machine for the item information. It is possible to append which attributes you are interested in retrieving after the $, eg: some directory selectorF$+VIEWS or other directory selectorF$+VIEWS+ABSTRACT The $ command makes it possible for a client that does not mind burning bandwidth to get attribute information for all items as the user navigates gopherspace. Clients using 2400 bps SLIP links will probably not use this method... but clients on Ethernet may not mind. This command may also be useful for building smart indexes of items in gopherspace. Note that the specific requested attributes are only suggestions to the server that the client would like less than a full set of attributes. The server may choose to ignore the request (if it is not capable of extracting the required attributes) and return the client the full set anyway. Other caveats: even if the attributes requested are not available, the server WILL NOT return an error, but will send whatever IS available. It is the client's responsibility inspect the returned attributes. Analogous to use of the $ command, the ! command can also be used to request certain attribute blocks. 2.8 Gopher+ Interactive Query items. The principle here is based on Roland Schemer's "Q/q" type ideas. We're calling it the Interactive Query enhancements... The server may list items that have a "?" following the port field: 0A fileFfile selectorFhostFportF? 1A directoryFdir selectorFhostFportF? Now the fact that there's something after the port field means that these are Gopher+ items. Old clients will still be able to show such items in lists, but if they simply send the old style plain selector string to retrieve them, the server will respond with an old style error telling them to get an updated client. New clients will know that before getting one of these items, it will be necessary to retrieve questions from the server, have the user answer them, and then feed the answers back to the server along with the selector. The questions to be asked of the user are retrieved from the server by looking at the +ASK attribute in the item's attribute information. When the user selects a query item, the client quickly connects to the server and requests the Attribute Information for the item. Then the client extracts the information in the +ASK attribute block. Here's an example: +INFO: 0inquisitiveFmoo moo selectorFhost2Fport2F+ +ADMIN Admin: Frank Gophermeister Mod-Date: August 15, 1992 <19920815185503> +ASK: Ask: How many volts? Choose: Deliver electric shock to administrator now?FYesFNot! The client will use all lines in the order they appear in the +ASK attribute block. The content will be presented to the user as questions or prompts or dialogs or something like that. The "Ask" presents the user with a question, supplies a default text answer if it exists and allows the user to enter a one-line responce. The "AskP" presents the user with a question, and bullets out the responce typed in by the user so that someone watching over the user's sholder cannot read the responce. The "AskL" presents the user with a question, and ideally should allo the user to enter several lines of responce. The "AskF" requests the user for a new local filename, presumably for stashing the response returned by the server. It may supply a default filename. The "Select" presents the user with a set of options from which the use can select one or many. This is equivalent to Macintosh check boxes. The "Choose" presents the user with a few short choices only one of which may be selected at a time. This is equivalent to Macintosh radio buttons. The "ChooseF" requests that the user select an existing local file, presumably for sending to the server. On some systems, the client writer or administrator might want to restrict the selection of such files to the current directory (ie. not allow paths in the filename to prevent sending things like password files). The n responses harvested from the user are sent on to the server as the first n lines in the dataBlock. There can only be one file sent, and it will be the remainder of the dataBlock if any. If there is an AskL the responce is returned with a count of the number of lines entered by the user on a line by itself, followed by the lines entered by the user. Gopher was originally designed as an essentially anonymous document retrieval protocol to facilitate easy access to information rather than limited access. Various kinds of restrictive mechanisms have been implemented at the server end (for example, access restriction by source IP address); however if you have sensitive information, we emphasize that putting it under a Gopher's nose is not a good idea. The folks with a hirsute tendency will have noticed that all these interactions are static rather than truly dynamic and interactive. In other words, the server cannot ask different questions in response to different answers. +ASK does not constitute a scripting language by any means. To do "true" scripting, we have to do one of two things 1. Write a full language parser/interpreter into clients. The server loads a whole script into the client's brain, and the client "runs" it. This rather grossly violates the spirit of simplicity in cross-platform gopher implementation. However, when and if a standard scripting language is adopted, there will be room for it in a SCRIPT attribute block. 2. Client enters a complex back-and-forth transaction with the server. This requires the server, client, or both to save rather a lot of state. NOPE! Server saving state means holding open a connection or (worse) the server retaining tokens between connections. Client saving state means the server has an even worse job to do. As Opus the Penguin would say: a Hairball. 2.9 Gopher+ Pictures, Sounds, Movies. A lot of folks need ability to retrieve and display pictures, but there is no real consensus on ONE format for these pictures. We don't want to define a type character for every oddball picture type. Gopher+ handles Pictures, Movies, and Sounds by defining three item types: ":" for bitmap images, ";" for movies, and "<" for sounds (originally I, M, and S were suggested, but they were informally in use in other ways; the only thing magic about ":", ";", and "<", is that they are the first characters after '9') Note that there is NO default format for Pictures, Movies and Sounds; the specific format of the image, movie, or sound must be gleaned from the +VIEWS information for the item (eg. Gif, PICT, TIFF, etc.). Appendix I Required attributes and suggested attributes. A1.0 The +INFO attribute block The +INFO atttribute block is sent whenever an item's attributes are requested. It is required that the Attribute Information list for an item must contain a one-line +INFO attribute, and the +INFO attribute must contain the gopher+ descriptor for the item. +INFO: 1Nice stuffF/selectorFhostFportF+ A2.0 The +ADMIN attribute A Gopher+ server is required to have an +ADMIN block for every item and the +ADMIN block must contain Admin and a Mod-Date lines: +ADMIN: Admin: [comments] Mod-Date: [comments] In addition to the required lines, we recommend that the +ADMIN attribute of items returned by a full-text search engine contain a SCORE attribute. The SCORE attribute should contain the relevance ranking (an integer) of the item. Score: relevance-ranking We recommend that the +ADMIN attribute of a full-text search engine contain a Score-Range attribute. This attribute is used to specify the range of values taken on by the relevance ranking scores of items returned by the search engine. The Score-Range makes it possible to normalize scores from different search engine technologies. The first number is the lower bound, the second number is the upper bound. Score-range: lower-bound upper-bound We also recommend that the +ADMIN attribute for the root of the server (i.e. what you get back when you ask for the attributes of the item with the empty selector string) also contain these fields: Site: the name of the site Org: organization or group owning the site Loc: city, state, country Geog: latitude longitude TZ: timezone as gmt-offset Other useful attributes might include: Provider: who provided this item Author: who wrote this item Creation-Date: when it was born Expiration-Date: when it expires A3.0 The +VIEWS attribute The +VIEWS attribute is used to specify alternative representations of an item. The form of the +VIEWS attribute is: +VIEWS: [gopher descriptor] Content-Type[ viewLanguage]: [<56K>] Content-Type[ viewLanguage]: [<93K>] Content-Type[ viewLanguage]: [<77K>] Some values for Content-Type are Text/plain, application/Postscript, image/Gif, image/jpeg, Content Types are defined by the Internet Assigned Numbers Authority (IANA). To register a new content type send e-mail to IANA@isi.edu. For a comprehensive list, consult the most up-to-date MIME Request for Comments (RFC). A list of currently defined views may be retrieved by anonymous ftp from isi.edu in the directory /pub/in-notes/MIME/mime-types All gopher servers must support the Text/plain view for readable documents and the application/gopher- menu view (the basic Gopher+ directory list) for directories. These are the views that must be returned by default. If all a server supports is the default views, then it may omit the +VIEWS attribute block (although we suggest that it not do so). The viewLanguage is defined as a concatanation of two ISO standard values, the ISO 639 language code and the ISO-3166 country code. Some values for viewLanguage are: En_US, De_DE, Es_ES, Se_SE A4.0 The +ABSTRACT attribute The +ABSTRACT attribute is used to specify a short abstract for the item. The form of the +ABSTRACT attribute is: +ABSTRACT: [gopher reference] A line of text another line of text still another line of text. We recommend that a description of the sorts of information at the site, a postal address, a phone number, and the administrator name for the site be included in the +ABSTRACT attribute for the server root (i.e. what you get when you ask for the attribute list of the server with no selector string). Appendix II Paul's NQBNF (Not Quite BNF) for the Gopher+ Enhancements. Note: This is modified BNF (as used by the Pascal people) with a few English modifiers thrown in. Stuff enclosed in '{}' can be repeated zero or more times. Stuff in '[]' denotes a set of items. The '- ' operator denotes set subtraction. This section is not quite solid yet. Please send us information on any errors you might notice. Directory Entity CR-LF ::= Carriage Return Character followed by Line Feed character. Tab ::= ASCII Tab character NUL ::= ASCII NUL character PLUS ::= ASCII '+' character LEFT ::= ASCII '<' character RIGHT ::= ASCII '>' character OCTET ::= $00 -> $ff UNASCII ::= OCTET - [Tab CR-LF NUL] UNASCIINOPLUS ::= UNASCII - [PLUS] UNASCIINOANGLE ::= UNASCII - [LEFT, RIGHT] Lastline ::= '.'CR-LF TextBlock ::= Block of ASCII text not containing Lastline pattern. Type ::= UNASCII DisplayString ::= {UNASCII} Selector ::= {UNASCII} Otherflds ::= {UNASCII + TAB} Host ::= {{UNASCII - ['.']} '.'} {UNASCII - ['.']} Note: This is a Fully Qualified Domain Name as defined in RFC 830. (e.g. gopher.micro.umn.edu) Hosts that have a CR-LF TAB or NUL in their name get what they deserve. Digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' DigitSeq ::= digit {digit}. Port ::= DigitSeq. Note: Port corresponds the the TCP Port Number, its value should be in the range [0..65535]; port 70 is officially assigned to gopher. Bool ::= '0' | '1' G+Field ::= '+' | '?' Success ::= '+' | '-'. Transfer ::= DigitSeq | '-1' | '-2' DataHead ::= Success Transfer CR-LF DataBlock ::= DataHead {OCTET} G1DirEntity ::= Type DisplayString Tab Selector Tab Host Tab Port Tab Otherflds CR-LF G+DirEntity ::= Type DisplayString Tab Selector Tab Host Tab Port Tab G+Field CR-LF Notes: It is *highly* recommended that the DisplayString field contain only printable characters, since many different clients will be using it. However if eight bit characters are used, the characters should conform with the ISO-Latin1 Character Set. The length of the User displayable line should be less than 70 Characters; longer lines may not fit across some screens. Warning! The Selector string can be longer than 255 characters. Menu Entity Menu ::= DataHead {G+DirEntity}. Continues ::= Bool Representation ::= 'Text' | 'List' | 'Postscript' | 'MacWriteII' | 'RTF' |{UNASCII} Retrieving a document/menu/etc.: C: Opens Connection S: Accepts Connection C: Sends Selector String Tab '+' Representation [Tab DataFlag] C: [Optional] Client sends a DataBlock depending on value of DataFlag. S: Sends DataBlock Connection is closed by either client or server (typically server). Spaceline ::= ' ' {UNASCII} CR-LF Blockname ::= '+' {UNASCIINOPLUS} Attrblock ::= Blockname ' ' [G+Direntry] CR-LF {Spaceline} Attrval ::= SPACE {UNASCII} CR-LF E-Mail ::= {UNASCII} s.t. it conforms to RFC 822 Adminval ::= ' Admin:' {UNASCII} '<' E-Mailaddr '>' CR-LF Dateval ::= ' Mod-Date:' {UNASCII} '<' YYYYMMDDhhmmss '>' CR-LF AdminReq ::= AdminVal Dateval Infoblock ::= '+INFO: ' G+Direntry CR-LF AdminBlock ::= '+ADMIN: ' {G+Direntry} CR-LF AdminReq {Attrval} Language ::= 'English' | 'French' | 'German' | {UNASCII} ViewVal ::= ' ' Representation [' ' Language] ":" ASCIINOANGLE '<' Size 'k>' CR-LF ViewBlock ::= '+VIEWS: ' {G+Direntry} CR-LF {ViewVal} AttrBlocks ::= InfoBlock ViewBlock {AttrBlock} Retrieving item Information. For non-index server (non-type 7 items) C: Opens Connection S: Accepts Connection C: Sends Selector String Tab '!' {BlockName}CR-LF S: Sends DataBlock with data in AttrrBlocks format. Connection is closed by either client or server (typically server). For index server (type 7 items) the client asks the search engine to so a search for nothing (i.e. the client does not provide any words to search for) and appends a TAB and a "!" after the null- search: C: Opens Connection S: Accepts Connection C: Sends Selector String Tab Tab '!' {BlockName}CR-LF S: Sends DataBlock with data in AttrrBlocks format. Connection is closed by either client or server (typically server). Attributes ::= {AttrBlocks} Retrieving all Item Information entries for a directory. C: Opens Connection S: Accepts Connection C: Sends Selector String Tab '$'{BlockName} CR-LF S: Sends DataBlock with data in Attributes format. Connection is closed by either client or server (typically server). pygopherd-3.0.1/doc/standards/gophermap.txt000066400000000000000000000061111456676541200210060ustar00rootroot00000000000000Serving files and the gophermap file ------------------------------------ The gophermap file is responsible for the look of a gopher menu. Unlike the UMN gopherd-style map files, which are somewhat cumbersome and can get rather large, Bucktooth encourages a slimline approach, or you can have none at all. This is not too secure since it will happily serve any and every file in its mountpoint to a greedy user, but if that's really what you want, congratulations. You can stop reading this now, since that's exactly what it will do when you install it with no gophermap files. Only gophermap, ., and .. are not served to the user. Assuming you want to do a little more customisation than that, you can edit the gophermap file (one per directory) with any text editor and follow a few simple rules to gopher goodness. (A sample file is in stuff/ for your enjoyment.) Bucktooth sends any RFC-1436 compliant line to the client. In other words, 1gopher.ptloma.edu homegopher.ptloma.edu70 where , is of course, the tab (CTRL-I, 0x09) character, generates a link to "null" selector on gopher.ptloma.edu 70 with an itemtype of 1 and a display string of "gopher.ptloma.edu home". You don't even have to enter valid selectors, although this will not endear you much to your users. If you are not well-versed in RFC-1436, it breaks down to the first character being the itemtype (0 = text, 1 = gopher menu, 5 = zip file, 9 = generic binary, 7 = search server, I = generic image, g = gif image; others are also supported by some clients), then the string shown by the client up to the first tab ("display string"); then the full path to the resource ("selector"); the hostname of the server; and the port. Since this would be a drag to always have to type things out in full, Bucktooth allows the following shortcuts: * If you don't specify a port, Bucktooth provides the one your server is using (almost always 70). * If you don't specify a host, Bucktooth provides your server's hostname. * If you only specify a relative selector and not an absolute path, Bucktooth sticks on the path they're browsing. So, if your server is gopher.somenetwork.com and your server's port is 7070, and this gophermap is inside of /lotsa, then 1Lots of stuffstuff is expanded out to 1Lots of stuff/lotsa/stuffgopher.somenetwork.com7070 If you don't specify a selector, two things can happen. Putting a at the end, like 1src explicitly tells Bucktooth you aren't specifying a selector, so Bucktooth uses your display string as the selector, adds on the host and port, and gives the client that. Otherwise, Bucktooth sees it as a description, and has the client display it as text. This allows you to add text descriptions to your menus. However, don't use the character anywhere in your text description or Bucktooth will try to interpret it as an RFC-1436 resource, which will yield possibly hilarious and definitely erroneous results. One last warning: keep display strings at 67 characters or less -- some clients may abnormally wrap them or display them in a way you didn't intend. . pygopherd-3.0.1/doc/standards/url.txt000066400000000000000000000157141456676541200176370ustar00rootroot00000000000000 John Goerzen on Tue, 12 Feb 2002 14:19:47 -0500 (EST) [[1]Date Prev] [[2]Date Next] [[3]Thread Prev] [[4]Thread Next] [[5]Date Index] [[6]Thread Index] [gopher] Links to URL * To: [7]gopher AT complete SEP org * Subject: [gopher] Links to URL * From: John Goerzen <[8]jgoerzen AT complete SEP org> * Date: 12 Feb 2002 14:19:46 -0500 * In-reply-to: <[9]200202120132.RAA11190@stockholm.ptloma.edu> * List-archive: <[10]http://www.complete.org/mailinglists/archives/> * List-help: <[11]mailto:listar@complete.org?Subject=help> * List-owner: <[12]mailto:jgoerzen@complete.org> * List-post: <[13]mailto:gopher@complete.org> * List-software: Listar version 1.0.0 * List-subscribe: <[14]mailto:gopher-request@complete.org?Subject=subscribe> * List-unsubscribe: <[15]mailto:gopher-request@complete.org?Subject=unsubscribe> * References: <[16]200202120132.RAA11190@stockholm.ptloma.edu> * Reply-to: [17]gopher AT complete SEP org * Sender: [18]gopher-bounce AT complete SEP org * User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Common Lisp) _________________________________________________________________ I think it is best to start small with modifications to the protocol. Therefore, I propose the following: Method to link to URLs from Gopherspace --------------------------------------- 1. Protocol issues Links to URLs from a gopher directory shall be defined as follows: Type -- the appropriate character corresponding to the type of the document on the remote end; h if HTML. Path -- the full URL, preceeded by "URL:". For instance: URL:[19]http://www.complete.org/ Host, Port -- pointing back to the gopher server that provided the directory for compatibility reasons. Name -- as usual for a Gopher directory entry. 2. Conforming client requirements A client adhering to this specification will, when it sees a Gopher selector with a path starting with URL:, interpret the path as a URL. It will ignore the host and port components of the Gopher selector, using those components from the URL instead (if applicable). 3. Conforming server requirements A server with Gopher URL support will not, in most cases, need to take extra steps to provide this support beyond those outlined in Compatibility below. Servers not implementing those steps outlined in Compatibility will be deemed to be not in compliance. 4. Authoring compliance The use of URL: selectors should be avoided wherever possible. In particular, it should be avoided when pre-existing gopher facilities exist for the type of content linked. The following URL types are explicitly prohibited by this specification: gopher telnet tn3270 Authors should avoid links to any document not of HTML type whenever possible. Linking to non-HTML documents will break compatibility with Gopher browsers that do not implement this specification. The ranks of these browsers include most Web browsers, so that is a significant audience. 5. Compatibility Links to HTML pages may be accomodated even for non-comforming browsers by providing additional capabilities in the server. When a non-conforming browser is instructed to follow a link to a URL, it will contact the Gopher server that provided the menu (since these are specified per section 1). When a conforming Gopher server receives a request whose path begins with URL:, it will write out a HTML document that will send the non-compliant browser to the appropriate place. One such conforming document is: You are following a link from gopher to a web site. You will be automatically taken to the web site shortly. If you do not get sent there, please click here to go to the web site.

The URL linked is:

[23]http://www.acm.org/classics/< /A>

Thanks for using gopher! This document may be any desired by the server authors, but must adhere to these requirements: * It must provide a refresh of a duration of 10 seconds or less * It must not use IMG tags, frames, or have any reference whatsoever to content outside that particular file -- other than the link to the real destination. * It must not use JavaScript. * It must adhere to the W3C HTML 3.2 standard. When a non-conforming Gopher client finds a reference to a HTML file (type h), it will open up the file via Gopher (getting the redirect document) but using a web browser. The web browser will then be redirected to the actual link destination. Conforming clients will follow the link directly. END Comments? _________________________________________________________________ * References: + [24][gopher] Re: Gopher wishlist o From: Cameron Kaiser * Prev by Date: [25][gopher] Re: UMN Gopher on Mac OSX * Next by Date: [26][gopher] Re: Gopher wishlist * Previous by thread: [27][gopher] Re: Gopher wishlist * Next by thread: [28][gopher] Bug * Index(es): + [29]Date + [30]Thread References 1. http://www.complete.org/mailinglists/archives/gopher-200202/msg00032.html 2. http://www.complete.org/mailinglists/archives/gopher-200202/msg00034.html 3. http://www.complete.org/mailinglists/archives/gopher-200202/msg00076.html 4. http://www.complete.org/mailinglists/archives/gopher-200202/msg00021.html 5. http://www.complete.org/mailinglists/archives/gopher-200202/maillist.html#00033 6. http://www.complete.org/mailinglists/archives/gopher-200202/threads.html#00033 7. mailto:gopher@DOMAIN.HIDDEN 8. mailto:jgoerzen@DOMAIN.HIDDEN 9. http://www.complete.org/mailinglists/archives/gopher-200202/msg00026.html 10. http://www.complete.org/mailinglists/archives/ 11. mailto:listar@complete.org?Subject=help 12. mailto:jgoerzen@complete.org 13. mailto:gopher@complete.org 14. mailto:gopher-request@complete.org?Subject=subscribe 15. mailto:gopher-request@complete.org?Subject=unsubscribe 16. http://www.complete.org/mailinglists/archives/gopher-200202/msg00026.html 17. mailto:gopher@DOMAIN.HIDDEN 18. mailto:gopher-bounce@DOMAIN.HIDDEN 19. http://www.complete.org/ 20. http://www.acm.org/classics/" 21. http://www.acm.org/classics/" 22. http://www.acm.org/classics/" 23. http://www.acm.org/classics/ 24. http://www.complete.org/mailinglists/archives/gopher-200202/msg00026.html 25. http://www.complete.org/mailinglists/archives/gopher-200202/msg00032.html 26. http://www.complete.org/mailinglists/archives/gopher-200202/msg00034.html 27. http://www.complete.org/mailinglists/archives/gopher-200202/msg00076.html 28. http://www.complete.org/mailinglists/archives/gopher-200202/msg00021.html 29. http://www.complete.org/mailinglists/archives/gopher-200202/maillist.html#00033 30. http://www.complete.org/mailinglists/archives/gopher-200202/threads.html#00033 pygopherd-3.0.1/examples/000077500000000000000000000000001456676541200153525ustar00rootroot00000000000000pygopherd-3.0.1/examples/gophermap000066400000000000000000000010761456676541200172630ustar00rootroot00000000000000Welcome to Pygopherd! You can place your documents in /var/gopher for future use. You can remove the gophermap file there to get rid of this message, or you can edit it to use other things. (You'll need to do at least one of these two things in order to get your own data to show up!) Some links to get you started: 1Pygopherd Home /devel/gopher/pygopherd gopher.quux.org 70 1Quux.Org Mega Server / gopher.quux.org 70 1The Gopher Project /Software/Gopher gopher.quux.org 70 1Traditional UMN Home Gopher / gopher.tc.umn.edu 70 Welcome to the world of Gopher and enjoy! pygopherd-3.0.1/examples/pygopherd.service000066400000000000000000000010051456676541200207310ustar00rootroot00000000000000[Unit] Description=Pygopherd Server Wants=network-online.target After=network-online.target [Service] User=gopher Group=gopher ProtectHome=true ProtectSystem=strict NoNewPrivileges=true RuntimeDirectory=pygopherd ReadWritePaths=/var/run/pygopherd /run/pygopherd /var/gopher SyslogIdentifier=pygopherd CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SYS_CHROOT AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_SYS_CHROOT ExecStart=/usr/sbin/pygopherd Restart=always TimeoutStopSec=5 [Install] WantedBy=multi-user.target pygopherd-3.0.1/examples/talsample.html.tal000066400000000000000000000011641456676541200210030ustar00rootroot00000000000000 TAL Test My selector is: selector
My MIME type is: foo/bar
Another way of getting that is: foo/bar
Gopher type is: X
My handler is: handlername
My protocol is: protocol
Python path enabling status: 123
My vfs is: vfs
Math: 5 pygopherd-3.0.1/local.dsl000066400000000000000000000020411456676541200153270ustar00rootroot00000000000000 ]> (define (toc-depth nd) (if (string=? (gi nd) (normalize "book")) 1 1)) (define %generate-article-toc% #t) ;; Don't split up the doc as much. (define (chunk-element-list) (list (normalize "preface") (normalize "chapter") (normalize "appendix") (normalize "article") (normalize "glossary") (normalize "bibliography") (normalize "index") (normalize "colophon") (normalize "setindex") (normalize "reference") (normalize "refentry") (normalize "part") (normalize "book") ;; just in case nothing else matches... (normalize "set") ;; sets are definitely chunks... )) pygopherd-3.0.1/printlocal.dsl000066400000000000000000000007371456676541200164160ustar00rootroot00000000000000 ]> (define tex-backend #t) (define bop-footnotes #t) (define %two-side% #t) (define %footnote-ulinks% #t) pygopherd-3.0.1/pygfarm/000077500000000000000000000000001456676541200152015ustar00rootroot00000000000000pygopherd-3.0.1/pygfarm/dict.pyg000066400000000000000000000310261456676541200166470ustar00rootroot00000000000000# -*-Python-*- import sys, string from pygopherd.handlers.pyg import PYGBase from pygopherd.gopherentry import GopherEntry, getinfoentry import dictclient def matchsort(x, y): return cmp(x.lower(), y.lower()) class PYGMain(PYGBase): def canhandlerequest(self): arglist = [] if self.selectorargs: arglist = self.selectorargs.split("/") self.dbname = None self.dbcommand = None self.commandargs = [] if len(arglist) >= 2: self.dbname = arglist[1] if len(arglist) >= 3: self.dbcommand = arglist[2] if len(arglist) >= 4: self.commandargs = arglist[3:] if self.searchrequest: self.commandargs.append(self.searchrequest) if self.dbcommand == 'DEFINE': self.__class__ = DefineMenu elif self.dbcommand == 'DEFINITION': self.__class__ = Definition elif self.dbcommand == 'MATCH': self.__class__ = Match elif self.dbcommand == 'MATCHMENU': self.__class__ = MatchMenu elif self.dbcommand == 'DBINFO': self.__class__ = DBInfo elif self.dbname: self.__class__ = Browse else: self.__class__ = TopMenu return 1 class TopMenu(PYGMain): def prepare(self): self.db = dictclient.Connection() self.entries = [] intro = ["Welcome to the dictionary server!", " ", "To do a quick lookup, use the following search:", " "] for item in intro: self.entries.append(getinfoentry(item, self.config)) selector = self.genargsselector("/*/DEFINE") entry = GopherEntry(selector, self.config) entry.type = '7' entry.mimetype = 'application/gopher-menu' entry.name = 'Definition Lookup -- All Databases' self.entries.append(entry) selector = self.genargsselector("/*/MATCHMENU") entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Advanced Search -- All Databases' self.entries.append(entry) intro = [" ", "Use the following links to search a particular", "database or to browse ALL the definitions", "in a database!", " "] for item in intro: self.entries.append(getinfoentry(item, self.config)) items = self.db.getdbdescs().items() items.sort(lambda x, y: cmp(x[1], y[1])) for name, desc in items: selector = self.genargsselector("/%s" % name) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = desc self.entries.append(entry) def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Dictionary Search' return entry def isdir(self): return 1 def getdirlist(self): return self.entries class Browse(PYGMain): def prepare(self): self.entries = [] intro = ["You can browse the entries in the database by", "selecting the first letter of the item you want.", " "] for item in intro: self.entries.append(getinfoentry(item, self.config)) selector = self.genargsselector("/%s/DEFINE" % self.dbname) entry = GopherEntry(selector, self.config) entry.type = '7' entry.mimetype = 'application/gopher-menu' entry.name = 'Search This Database' self.entries.append(entry) selector = self.genargsselector("/%s/MATCHMENU" % self.dbname) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Advanced Search for This Database' self.entries.append(entry) if self.dbname != '*': selector = self.genargsselector("/%s/DBINFO" % self.dbname) entry = GopherEntry(selector, self.config) entry.type = '0' entry.mimetype = 'text/plain' dictconn = dictclient.Connection() entry.name = 'About ' + \ dictclient.Database(dictconn, self.dbname).getdescription() self.entries.append(entry) selector = self.genargsselector("/%s/MATCH/re/^[^a-zA-Z]" % \ self.dbname) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = "Items that do not begin with a letter" self.entries.append(entry) for letter in string.ascii_uppercase: selector = self.genargsselector("/%s/MATCH/re/^[%s%s]" % \ (self.dbname, letter, letter.lower())) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = letter self.entries.append(entry) def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Dictionary Database Browse' return entry def isdir(self): return 1 def getdirlist(self): return self.entries class DefineMenu(PYGMain): def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Definition Menu for %s' % self.commandargs[0] return entry def prepare(self): self.db = dictclient.Connection() self.entries = [] entry = getinfoentry("Definitions for '%s' in database '%s'" % \ (self.commandargs[0], self.dbname), self.config) self.entries.append(entry) defs = self.db.define(self.dbname, self.commandargs[0]) if len(defs): selector = self.genargsselector("/%s/DEFINITION/%s" % (self.dbname, self.commandargs[0])) entry = GopherEntry(selector, self.config) entry.type = '0' entry.mimetype = 'text/plain' entry.name = 'All %d definitions on a single page' % len(defs) self.entries.append(entry) else: entry = getinfoentry("No definitions found.", self.config) self.entries.append(entry) for i in range(len(defs)): selector = self.genargsselector("/%s/DEFINITION/%s" % \ (defs[i].getdb().getname(), defs[i].getword())) entry = GopherEntry(selector, self.config) entry.type = '0' entry.mimetype = 'text/plain' entry.name = "'%s' in %s" % (defs[i].getword(), defs[i].getdb().getdescription()) self.entries.append(entry) self.entries.append(getinfoentry(" ", self.config)) self.entries.append(getinfoentry("Definitions for similar words:", self.config)) matches = self.db.match(self.dbname, 'lev', self.commandargs[0]) matchlist = unique([x.getword() for x in matches]) matchlist.sort(matchsort) if not len(matchlist): self.entries.append(getinfoentry("No similar definitions found.", self.config)) for matchword in matchlist: selector = self.genargsselector("/%s/DEFINE/%s" % \ (self.dbname, matchword)) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = matchword self.entries.append(entry) def isdir(self): return 1 def getdirlist(self): return self.entries class Definition(PYGMain): def prepare(self): self.db = dictclient.Connection() self.definition = "" defs = self.db.define(self.dbname, self.commandargs[0]) if not len(defs): self.definition = "No definition found." return for d in defs: self.definition += "DEFINITION of '%s'\nFrom %s\n\n" % \ (d.getword(), d.getdb().getdescription()) self.definition += d.getdefstr() self.definition += "\n" + ('-' * 60) + "\n" self.definition += "Generated by dict.pyg for Pygopherd by John Goerzen \n" self.definition += "dict.pyg and Pygopherd licensed under the GPL.\n" def write(self, wfile): wfile.write(self.definition) def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '0' entry.mimetype = 'text/plain' entry.name = 'Definition for %s' % self.commandargs[0] return entry class Match(PYGMain): def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Match menu for %s' % self.commandargs[1] return entry def prepare(self): self.conn = dictclient.Connection() self.entries = [] matches = self.conn.match(self.dbname, self.commandargs[0], self.commandargs[1]) if not len(matches): self.entries.append(getinfoentry("No matches.", self.config)) return matchlist = unique([x.getword() for x in matches]) matchlist.sort(matchsort) self.entries.append(getinfoentry("%d matches for '%s' (%s)" % \ (len(matchlist), self.commandargs[1], self.commandargs[0]), self.config)) for matchword in matchlist: selector = self.genargsselector("/%s/DEFINE/%s" % \ (self.dbname, matchword)) entry = GopherEntry(selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = matchword self.entries.append(entry) def isdir(self): return 1 def getdirlist(self): return self.entries class MatchMenu(PYGMain): def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '1' entry.mimetype = 'application/gopher-menu' entry.name = 'Advanced Search Options for %s' % self.dbname return entry def prepare(self): self.conn = dictclient.Connection() self.entries = [] self.entries.append(getinfoentry("Advanced Search: " + self.dbname, self.config)) for name, desc in self.conn.getstratdescs().items(): selector = self.genargsselector("/%s/MATCH/%s" % \ (self.dbname, name)) entry = GopherEntry(selector, self.config) entry.type = '7' entry.mimetype = 'application/gopher-menu' entry.name = 'Search with %s (%s)' % (name, desc) self.entries.append(entry) def isdir(self): return 1 def getdirlist(self): return self.entries class DBInfo(PYGMain): def prepare(self): self.conn = dictclient.Connection() self.conn.getdbdescs() self.db = self.conn.getdbobj(self.dbname) self.infotext = self.db.getinfo() def write(self, wfile): wfile.write("About %s (%s):\n\n" % (self.dbname, self.db.getdescription())) wfile.write(self.infotext) def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = '0' entry.mimetype = 'text/plain' entry.name = 'Information for %s' % self.dbname return entry def unique(input): """Return a list of the elements in input, but without duplicates. Performs a case-insensitive check.""" retval = [] check = {} for item in input: if not check.has_key(item.lower()): retval.append(item) check[item.lower()] = 1 return retval pygopherd-3.0.1/pygopherd/000077500000000000000000000000001456676541200155355ustar00rootroot00000000000000pygopherd-3.0.1/pygopherd/GopherExceptions.py000066400000000000000000000027551456676541200214060ustar00rootroot00000000000000from __future__ import annotations import typing from pygopherd import logger if typing.TYPE_CHECKING: from pygopherd.handlers.base import BaseHandler from pygopherd.protocols.base import BaseGopherProtocol tracebacks = 0 def log( exception: Exception, protocol: typing.Optional[BaseGopherProtocol] = None, handler: typing.Optional[BaseHandler] = None, ): """Logs an exception. It will try to generate a nice-looking string based on the arguments passed in.""" protostr = "None" handlerstr = "None" ipaddr = "unknown-address" exceptionclass = type(exception).__name__ if protocol: protostr = type(protocol).__name__ ipaddr = protocol.requesthandler.client_address[0] if handler: handlerstr = type(handler).__name__ logger.log( "%s [%s/%s] EXCEPTION %s: %s" % (ipaddr, protostr, handlerstr, exceptionclass, str(exception)) ) def init(backtraceenabled): global tracebacks tracebacks = backtraceenabled class FileNotFound(Exception): def __init__( self, selector: str, comments: str = "", protocol: typing.Optional[BaseGopherProtocol] = None, ): self.selector = selector self.comments = comments self.protocol = protocol log(self, self.protocol, None) def __str__(self): retval = "'%s' does not exist" % self.selector if self.comments: retval += " (%s)" % self.comments return retval pygopherd-3.0.1/pygopherd/__init__.py000066400000000000000000000003021456676541200176410ustar00rootroot00000000000000__version__ = "3.0.1" __all__ = [ "handlers", "protocols", "GopherExceptions", "gopherentry", "logger", "fileext", "initialization", "testutil", "server", ] pygopherd-3.0.1/pygopherd/fileext.py000066400000000000000000000026571456676541200175610ustar00rootroot00000000000000import functools import mimetypes import typing typemap: typing.Dict[str, typing.List[str]] = {} def extcmp(x, y): if x.count(".") > y.count("."): return 1 if x.count(".") < y.count("."): return -1 if len(x) > len(y): return 1 if len(x) < len(y): return -1 return (x > y) - (y < x) extkey = functools.cmp_to_key(extcmp) def extstrip(file, filetype): """Strips off the extension from file given type and returns the result. Returns file unmodified if no action is possible.""" if not (filetype and filetype in typemap): return file for possible in typemap[filetype]: if file.endswith(possible): extindex = file.rfind(possible) return file[0:extindex] return file def init(): for fileext, filetype in list(mimetypes.types_map.items()): extlist = [] if filetype in typemap: extlist = typemap[filetype] baselist = [] # Add the basic extension. baselist.append(fileext) # Add it in all encoding flavors. baselist.extend([fileext + enc for enc in list(mimetypes.encodings_map.keys())]) for shortsuff, longsuff in list(mimetypes.suffix_map.items()): if longsuff in baselist: baselist.append(shortsuff) extlist.extend(baselist) extlist.sort(key=extkey) extlist.reverse() typemap[filetype] = extlist pygopherd-3.0.1/pygopherd/gopherentry.py000066400000000000000000000271471456676541200204700ustar00rootroot00000000000000from __future__ import annotations import configparser import mimetypes import os import os.path import re import stat import typing import urllib.error import urllib.parse import urllib.request from typing import Optional mapping = None eaexts = None if typing.TYPE_CHECKING: from pygopherd.handlers.base import VFS_Real class GopherEntry: """The entry object for Gopher. It holds information about each Gopher object.""" fspath: typing.Optional[str] type: typing.Optional[str] name: typing.Optional[str] host: typing.Optional[str] port: typing.Optional[int] mimetype: typing.Optional[str] encodedmimetype: typing.Optional[str] size: typing.Optional[int] encoding: typing.Optional[str] populated: int language: typing.Optional[str] ctime: typing.Optional[int] mtime: typing.Optional[int] num: int gopherpsupport: int ea: typing.Dict[str, str] def __init__(self, selector: str, config: configparser.ConfigParser): """Initialize object based on a selector and config.""" self.selector = selector # Gopher path to file self.config = config # Our config object self.fspath = None # Path to the obj in filesystem self.type = None # Gopher0 type char self.name = None # Menu name self.host = None # Hostname self.port = None # Port number (an int) self.mimetype = None # MIME type self.encodedmimetype = None # Real MIME type if encoded. self.size = None # Size self.encoding = None # Encoding type self.populated = 0 # Whether or not it's been populated self.language = None # Language self.ctime = None # Creation date self.mtime = None # Modification date self.num = 0 # Number in menu self.gopherpsupport = 0 # Supports gopher+ self.ea = {} # Extended attributes -- Gopher+ # Abstract, etc. def populatefromvfs(self, vfs: VFS_Real, selector: str) -> None: self.populatefromfs(selector, statval=vfs.stat(selector), vfs=vfs) def populatefromfs( self, fspath: str, statval: Optional[os.stat_result] = None, vfs: Optional[VFS_Real] = None, ) -> None: """Fills in self with data gleaned from the filesystem. The argument fspath specifies where in the filesystem it will search. statval, if present, will be used instead of calling stat() itself so as to cut down on the number of system calls. The overall idea of this function is to set only those values that are not already set and to do so only if a definitive answer for them can be obtained from the operating system. The rest of this information describes the details of how it does this. If populatefromfs has already been called or self.populated is true, this function will note the fspath and the return without modifying anything else. If either gethost() or getport() return anything other than None, the same thing will happen. If there is no statval and os.stat returns an error, again, the same thing will happen. Assuming these tests pass, then: self.gopherpsupport will be set to true for any file or directory. The remaining values will be set only if they are not set already: For both files and directories, the creation and modification times will be noted, the name will be set to the filename (as returned by os.path.basename on the selector). For directories only, the type will be set to 1 and the mimetype to application/gopher-menu. Gopher+ protocols may wish to indicate application/gopher+-menu is available as well, but that is outside the scope of this function. For files only, the size will be noted. An attempt will be made to ascertain a mimetype and an encoding. If only a mimetype is found, it will be noted in self.mimetype. If both a mimetype and an encoding is found, self.mimetype will be application/octet-stream, self.encoding will note the encoding, and self.encodedmimetype will note the type of the encoded data. If no mimetype can be found, it will be set to the default from the config file. If no gopher0 type character is already present, self.guesstype() will be called to set it.""" self.fspath = fspath if vfs is None: from pygopherd.handlers.base import VFS_Real vfs = VFS_Real(self.config) if self.populated: return # Just let the stat catch the OSError rather than testing # for existence here. Help cut down on the number of syscalls. if not (self.gethost() is None and self.getport() is None): return if not statval: try: statval = vfs.stat(self.fspath) except OSError: return self.populated = 1 self.gopherpsupport = 1 # Indicate gopher+ support for locals. # All this "or" stuff means that we only modify it if it's not already # set. self.ctime = self.ctime or statval[9] self.mtime = self.mtime or statval[8] self.name = self.name or os.path.basename(self.selector) if stat.S_ISDIR(statval[0]): self.type = self.type or "1" self.mimetype = self.mimetype or "application/gopher-menu" self.handleeaext(self.fspath + "/", vfs) # Add the / so we get /.abs return self.handleeaext(self.fspath, vfs) self.size = self.size or statval[6] mimetype, encoding = mimetypes.guess_type(self.selector, strict=False) if encoding: self.mimetype = self.mimetype or "application/octet-stream" self.encoding = self.encoding or encoding self.encodedmimetype = self.encodedmimetype or mimetype else: self.mimetype = self.mimetype or mimetype # Did we get no mime type at all? Fall back to a default. if not self.mimetype: self.mimetype = self.config.get("GopherEntry", "defaultmimetype") self.type = self.type or self.guesstype() def guesstype(self) -> str: global mapping if not mapping: mapping = eval(self.config.get("GopherEntry", "mapping")) for maprule in mapping: if re.match(maprule[0], self.mimetype): return maprule[1] return "0" def handleeaext(self, selector: str, vfs: Optional[VFS_Real]) -> None: """Handle getting extended attributes from the filesystem.""" global eaexts if eaexts is None: eaexts = eval(self.config.get("GopherEntry", "eaexts")) if vfs is None: from pygopherd.handlers.base import VFS_Real vfs = VFS_Real(self.config) for extension, blockname in list(eaexts.items()): if blockname in self.ea: continue try: with vfs.open( selector + extension, "r", errors="surrogateescape" ) as rfile: self.setea( blockname, "\n".join([x.rstrip() for x in rfile.readlines(20480)]), ) except IOError: pass def getselector(self, default=None) -> str: if self.selector is None: return default return self.selector def setselector(self, arg: str) -> None: self.selector = arg def getconfig( self, default: Optional[configparser.ConfigParser] = None ) -> Optional[configparser.ConfigParser]: return self.config or default def setconfig(self, arg: configparser.ConfigParser) -> None: self.config = arg def getfspath(self, default: Optional[str] = None) -> Optional[str]: if self.fspath is None: return default return self.fspath def gettype(self, default: Optional[str] = None) -> Optional[str]: if self.type is None: return default return self.type def settype(self, arg: str) -> None: self.type = arg def getname(self, default: Optional[str] = None) -> Optional[str]: if self.name is None: return default return self.name def setname(self, arg: str) -> None: self.name = arg def gethost(self, default: Optional[str] = None) -> Optional[str]: if self.host is None: return default return self.host def sethost(self, arg: str) -> None: self.host = arg def getport(self, default: Optional[int] = None) -> Optional[int]: if self.port is None: return default return self.port def setport(self, arg: int) -> None: self.port = arg def getmimetype(self, default: Optional[str] = None) -> Optional[str]: if self.mimetype is None: return default return self.mimetype def getencodedmimetype(self, default: Optional[str] = None) -> Optional[str]: if self.encodedmimetype is None: return default return self.encodedmimetype def setmimetype(self, arg: str) -> None: self.mimetype = arg def getsize(self, default: Optional[int] = None) -> Optional[int]: if self.size is None: return default return self.size def getencoding(self, default: Optional[str] = None) -> Optional[str]: if self.encoding is None: return default return self.encoding def getlanguage(self, default: Optional[str] = None) -> Optional[str]: if self.language is None: return default return self.language def getctime(self, default: Optional[int] = None) -> Optional[int]: if self.ctime is None: return default return self.ctime def getmtime(self, default: Optional[int] = None) -> Optional[int]: if self.mtime is None: return default return self.mtime def geturl(self, defaulthost: str = "MISSINGHOST", defaultport: int = 70) -> str: """If this selector is a URL: one, then we just return the rest of it. Otherwise, generate a gopher:// URL and quote it.""" if re.search("^(/|)URL:.+://", self.selector): if self.selector[0] == "/": return self.selector[5:] else: return self.selector[4:] retval = "gopher://{}:{}/".format( self.gethost(defaulthost), self.getport(defaultport), ) retval += urllib.parse.quote( "{}{}".format(self.gettype(), self.getselector()), errors="surrogateescape" ) return retval def getnum(self, default=None): if self.num is not None: return self.num return default def setnum(self, arg): self.num = arg def getgopherpsupport(self, default=None): if self.gopherpsupport is not None: return self.gopherpsupport return default def setgopherpsupport(self, arg): self.gopherpsupport = arg def getea(self, name: str, default: Optional[str] = None): if name in self.ea: return self.ea[name] return default def geteadict(self) -> typing.Dict[str, str]: return self.ea def setea(self, name: str, value: str): self.ea[name] = value def getinfoentry(text: str, config: configparser.ConfigParser) -> GopherEntry: entry = GopherEntry("fake", config) entry.name = text entry.host = "(NULL)" entry.port = 0 entry.type = "i" return entry pygopherd-3.0.1/pygopherd/handlers/000077500000000000000000000000001456676541200173355ustar00rootroot00000000000000pygopherd-3.0.1/pygopherd/handlers/HandlerMultiplexer.py000066400000000000000000000040401456676541200235150ustar00rootroot00000000000000from __future__ import annotations import configparser import typing from pygopherd import GopherExceptions # Running eval() when loading the configuration requires all of the handlers to # be in the module namespace from pygopherd.handlers import * # noqa from pygopherd.handlers.base import BaseHandler, VFS_Real if typing.TYPE_CHECKING: from pygopherd.protocols.base import BaseGopherProtocol handlers: typing.Optional[typing.List[BaseHandler]] = None rootpath: typing.Optional[str] = None def init_default_handlers(config: configparser.ConfigParser) -> None: global handlers, rootpath if not handlers: handlers = eval(config.get("handlers.HandlerMultiplexer", "handlers")) rootpath = config.get("pygopherd", "root") def getHandler( selector: str, searchrequest: str, protocol: BaseGopherProtocol, config: configparser.ConfigParser, handlerlist: typing.Optional[typing.List[BaseHandler]] = None, vfs: typing.Optional[VFS_Real] = None, ): """Called without handlerlist specified, uses the default as listed in config.""" global handlers, rootpath init_default_handlers(config) if vfs is None: vfs = VFS_Real(config) if handlerlist is None: handlerlist = handlers typing.cast(handlers, typing.List[BaseHandler]) typing.cast(rootpath, str) # SECURITY: assert that our absolute path is within the absolute # path of the site root. # if not os.path.abspath(rootpath + '/' + selector). \ # startswith(os.path.abspath(rootpath)): # raise GopherExceptions.FileNotFound, \ # [selector, "Requested document is outside the server root", # protocol] statresult = None try: statresult = vfs.stat(selector) except OSError: pass for handler in handlerlist: htry = handler(selector, searchrequest, protocol, config, statresult, vfs) if htry.isrequestforme(): return htry.gethandler() raise GopherExceptions.FileNotFound(selector, "no handler found", protocol) pygopherd-3.0.1/pygopherd/handlers/UMN.py000066400000000000000000000246301456676541200203530ustar00rootroot00000000000000import configparser import functools import os.path import typing import pygopherd.fileext from pygopherd.gopherentry import GopherEntry from pygopherd.handlers.base import BaseHandler from pygopherd.handlers.dir import DirHandler from pygopherd.handlers.file import FileHandler extstrip = None class LinkEntry(GopherEntry): def __init__(self, selector: str, config: configparser.ConfigParser): super().__init__(selector, config) self.needsmerge = False self.needsabspath = False def getneedsmerge(self) -> bool: return self.needsmerge def getneedsabspath(self) -> bool: return self.needsabspath def setneedsmerge(self, arg: bool) -> None: self.needsmerge = arg def setneedsabspath(self, arg: bool) -> None: self.needsabspath = arg class UMNDirHandler(DirHandler): """This module strives to be bug-compatible with UMN gopherd.""" linkentries: typing.List[LinkEntry] def prepare(self) -> None: """Override parent to do a few more things and override sort order.""" # Initialize. self.linkentries = [] # Let the parent do the directory walking for us. Will call # prep_initfiles_canaddfile and prep_entriesappend. if super().prepare(): # Returns 1 if it didn't load from the cache. # Merge and sort. self.MergeLinkFiles() self.fileentries.sort(key=functools.cmp_to_key(self.entrycmp)) def prep_initfiles_canaddfile(self, ignorepatt, pattern, file) -> bool: """Override the parent to process dotfiles and keep them out of the list.""" if super().prep_initfiles_canaddfile(ignorepatt, pattern, file): # If the parent says it's OK, then let's see if it's # a link file. If yes, process it and return false. if file[0] == ".": if not self.vfs.isdir(self.selectorbase + "/" + file): self.linkentries.extend( self.processLinkFile(self.selectorbase + "/" + file) ) return False else: return False # A "dot dir" -- ignore. return True # Not a dot file -- return true else: return False # Parent returned 0, do the same. def prep_entriesappend( self, file: str, handler: BaseHandler, fileentry: GopherEntry ) -> None: """Overridden to process .cap files and modify extensions. This is called by the parent's prepare to append an entry to the list. Here, we check to see if there's a .cap file right before adding it.""" global extstrip if extstrip is None: extstrip = self.config.get("handlers.UMN.UMNDirHandler", "extstrip") if extstrip != "none" and isinstance(handler, FileHandler): if extstrip == "full" or ( extstrip == "nonencoded" and not fileentry.getencoding() ): # If it's a file, has a MIME type, and we know about it.. fileentry.setname( pygopherd.fileext.extstrip( file, fileentry.getencodedmimetype() or fileentry.getmimetype() ) ) capfilename = self.selectorbase + "/.cap/" + file try: capinfo = self.processLinkFile(capfilename, fileentry.getselector()) if len(capinfo) >= 1: # We handle one and only one entry. if capinfo[0].gettype() == "X" or capinfo[0].gettype() == "-": return # Type X -- don't append. else: self.mergeentries(fileentry, capinfo[0]) except IOError: # Ignore no capfile situation pass super().prep_entriesappend(file, handler, fileentry) def MergeLinkFiles(self) -> None: """Called to merge the files from .Links and .names into the objects obtained by walking the directory. According to UMN code, we ONLY merge if the Path starts with ./ or ~/ in the file. This is set in the getneedsmerge() attribute. If that attribute is not set, don't even bother with it -- just add.""" # For faster matching, make a dictionary out of the list. fileentriesdict = {} for entry in self.fileentries: fileentriesdict[entry.selector] = entry for linkentry in self.linkentries: if not linkentry.getneedsmerge(): self.fileentries.append(linkentry) continue if linkentry.selector in fileentriesdict: if linkentry.gettype() == "X": # It's special code to hide something. self.fileentries.remove(fileentriesdict[linkentry.selector]) else: self.mergeentries(fileentriesdict[linkentry.selector], linkentry) else: self.fileentries.append(linkentry) def mergeentries(self, old: GopherEntry, new: GopherEntry) -> None: """Takes the set fields from new and modifies old to have their value.""" for field in ["selector", "type", "name", "host", "port", "num"]: if getattr(new, field) is not None: setattr(old, field, getattr(new, field)) for field in list(new.geteadict().keys()): old.setea(field, new.getea(field)) def processLinkFile( self, filename: str, capfilepath: typing.Optional[str] = None ) -> typing.List[LinkEntry]: """Processes a link file. If capfilepath is set, it should be the equivolent of the Path= in a .names file.""" linkentries = [] with self.vfs.open(filename, "r", errors="surrogateescape") as fd: while True: nextstep, entry = self.getLinkItem(fd, capfilepath) if entry: linkentries.append(entry) if nextstep == "stop": break return linkentries def getLinkItem( self, fd: typing.IO, capfilepath: typing.Optional[str] = None ) -> typing.Tuple[str, typing.Optional[LinkEntry]]: """This is an almost exact clone of UMN's GSfromLink function.""" entry = LinkEntry(self.getentry().selector, self.config) nextstep = "continue" done = {"path": 0, "type": 0, "name": 0, "host": 0, "port": 0} if capfilepath is not None: entry.setselector(capfilepath) done["path"] = 1 while 1: line = fd.readline() if not line: nextstep = "stop" break line = line.strip() # Empty. if len(line) == 0: break # Comment. if line[0] == "#": if done["path"]: break else: continue # Type. if line[0:5] == "Type=": entry.settype(line[5]) # FIXME: handle if line[6] is + or ? done["type"] = 1 elif line[0:5] == "Name=": entry.setname(line[5:]) done["name"] = 1 elif line[0:5] == "Path=": pathname = line[5:] if len(pathname) and pathname[-1] == "/": pathname = pathname[0:-1] if len(line) >= 7 and (line[5:7] == "./" or line[5:7] == "~/"): # Handle ./: make full path. entry.setselector(self.selectorbase + "/" + pathname[2:]) entry.setneedsmerge(True) elif len(pathname) and pathname[0] != "/" and pathname[0:4] != "URL:": entry.setselector(pathname) entry.setneedsabspath(True) else: entry.setselector(pathname) done["path"] = 1 elif line[0:5] == "Host=": if line[5:] != "+": entry.sethost(line[5:]) done["host"] = 1 elif line[0:5] == "Port=": if line[5:] != "+": entry.setport(int(line[5:])) done["port"] = 1 elif line[0:5] == "Numb=": try: # Don't crash if we can't parse the number entry.setnum(int(line[5:])) except: pass elif line[0:9] == "Abstract=": abstractstr = "" abstractline = line[9:] while len(abstractline) and abstractline[-1] == "\\": abstractstr += abstractline[0:-1] + "\n" abstractline = fd.readline().strip() abstractstr += abstractline if abstractstr: entry.setea("ABSTRACT", abstractstr) elif line[0:6] == "Admin=" or line[0:4] == "URL=" or line[0:4] == "TTL=": pass else: break # FIXME: Handle Admin, URL, TTL if done["path"]: if ( entry.getneedsabspath() and entry.gethost() is None and entry.getport() is None ): entry.setselector( os.path.normpath(self.selectorbase + "/" + entry.getselector()) ) return nextstep, entry return nextstep, None def sgn(self, a: int) -> int: """Returns -1 if less than 0, 1 if greater than 0, and 0 if equal to zero.""" if a == 0: return 0 if a < 0: return -1 return 1 def entrycmp(self, entry1: GopherEntry, entry2: GopherEntry) -> int: """This function implements an exact replica of UMN behavior GSqsortcmp() behavior.""" if entry1.name is None: return 1 if entry2.name is None: return -1 e1num = entry1.getnum(0) e2num = entry2.getnum(0) # Equal numbers or no numbers: sort by title. if e1num == e2num: return cmp(entry1.name, entry2.name) # Same signs: use plain numeric comparison. if self.sgn(e1num) == self.sgn(e2num): return cmp(e1num, e2num) # Different signs: other comparison. if e1num > e2num: return -1 else: return 1 # For Python 3 compat # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons def cmp(a, b): return (a > b) - (a < b) pygopherd-3.0.1/pygopherd/handlers/ZIP.py000066400000000000000000000340241456676541200203540ustar00rootroot00000000000000from __future__ import annotations import codecs import configparser import os.path import re import shelve import stat import time import typing import zipfile from pygopherd.handlers.base import BaseHandler, VFS_Real CacheData = typing.Dict[str, typing.Any] class VFSZip(VFS_Real): # See docstring in populate_cache() for details dircache: CacheData # Contains filenames that were not found in the zipfile, to prevent extra # lookups if the same invalid path is repeatedly requested. invalid_paths: typing.Set[str] # For efficient lookup of the inode for a file without needing to # recursively traverse the dircache for each path segment. # entrycache[directory_name][filename] = inode for that file entrycache: typing.Dict[str, typing.Dict[str, str]] def __init__( self, config: configparser.ConfigParser, chain: VFS_Real, zipfilename: str ): super().__init__(config, chain) self.zipfilename = zipfilename self.zipfd = self.chain.open(self.zipfilename, mode="rb") self.zip = zipfile.ZipFile(self.zipfd) self.invalid_paths = set() self.entrycache = {} self.init_cache() def __del__(self): if hasattr(self, "zipfd"): self.zipfd.close() def get_cache_filename(self) -> str: (dir_, file) = os.path.split(self.zipfilename) return os.path.join(dir_, ".cache.pygopherd.zip3." + file) def save_cache(self) -> bool: cache_filename = self.get_cache_filename() cache_fspath = self.chain.getfspath(cache_filename) try: with shelve.open(cache_fspath, "n") as db: for (key, value) in self.dircache.items(): db[key] = value except OSError: return False else: return True def init_cache(self) -> None: cache_filename = self.get_cache_filename() zipfile_mtime = self.chain.stat(self.zipfilename)[stat.ST_MTIME] try: cache_mtime = self.chain.stat(cache_filename)[stat.ST_MTIME] except OSError: # Couldn't stat the cache, attempt to rebuild it self.populate_cache() self.save_cache() return if zipfile_mtime > cache_mtime: # The zipfile has been modified since the cache was generated, # rebuild the cache. self.populate_cache() self.save_cache() return cache_fspath = self.chain.getfspath(cache_filename) try: self.dircache = shelve.open(cache_fspath, "r") except Exception: self.populate_cache() self.save_cache() def _isentryincache(self, fspath: str) -> bool: try: self._getcacheentry(fspath) return True except KeyError: return False def _getcacheentry(self, fspath: str) -> typing.Union[dict, str]: return self.dircache[self._getcacheinode(fspath)] def _getcacheinode(self, fspath: str) -> str: inode = "0" if fspath == "": return inode (dir_, file) = os.path.split(fspath) if dir_ in self.entrycache: return self.entrycache[dir_][file] elif dir_ in self.invalid_paths: raise KeyError("Call for %s: directory %s non-existant" % (fspath, dir_)) workingdir = "" for item in fspath.split("/"): # right now, directory holds the directory from the *last* iteration. directory = self.dircache[inode] if type(directory) != dict: raise KeyError("Call for %s: couldn't find %s" % (fspath, item)) self.entrycache[workingdir] = directory workingdir = os.path.join(workingdir, item) try: # Now, inode holds the inode number. inode = directory[item] except KeyError: self.invalid_paths.add(workingdir) raise KeyError("Call for %s: Couldn't find %s" % (fspath, item)) return inode def populate_cache(self): """ Build a dictionary that will be used to represent the zipfile structure. - Keys are inodes (string integers, like "0", "1", ...) - Values can be either strings or dicts - If the value is a string, it points to the filename in the zipfile. - If the value is a dict, it's a recursive cache for that directory. The "0" inode is always the root directory. To lookup a path, split it into segments and traverse the cache one segment at a time. E.g. / /hello.txt /some_directory/goodbye.txt { '0': {'hello.txt': '1', 'some_directory': '2'}, '1': 'hello.txt', '2': {'goodbye.txt': '3'}, '3': '/some_directory/goodbye.txt' } """ symlinkinodes = [] nextinode = 1 self.dircache = {"0": {}} for info in self.zip.infolist(): # Python 3 will automatically decode zip filenames assuming the # charset is either UTF-8 (if the flag bit 11 is set) or otherwise # cp437. This is *technically* valid from the zip spec but it's # debatable given that zip(1) doesn't follow this on POSIX and just # treats filenames as bytes without an associated encoding. So we # reverse python's attempt by transcoding from cp437 back to an # encoding that contains surrogate escapes. This allows the original # bytes from the zip filenames to be preserved without any mojibake # caused by assuming the encoding. # # Note that this "fix" only changes the filename that PyGopherd will # display to clients. The python Zipfile object still keeps track of # the filename as either cp437 or utf-8, so that's what you need to # use when calling self.zip.read(filename) and related methods. This # is why we still store the original info.filename as the value # inside of the dircache. # # https://bugs.python.org/issue38861 filename = info.filename if info.flag_bits & 0x800: filename = filename.encode("utf-8").decode(errors="surrogateescape") else: filename = filename.encode("cp437").decode(errors="surrogateescape") (dir_, filename_) = os.path.split(filename) if dir_ == "/": dir_ = "" dirlevel = self.dircache["0"] for level in dir_.split("/"): if level == "": continue if level not in dirlevel: self.dircache[str(nextinode)] = {} dirlevel[level] = str(nextinode) nextinode += 1 dirlevel = self.dircache[dirlevel[level]] if filename_: if self._islinkinfo(info): symlinkinodes.append( { "dirlevel": dirlevel, "filename": filename_, "pathname": info.filename, "dest": self._readlinkfspath(info.filename), } ) else: dirlevel[filename_] = str(nextinode) self.dircache[str(nextinode)] = info.filename nextinode += 1 lastsymlinklen = 0 while len(symlinkinodes) and len(symlinkinodes) != lastsymlinklen: lastsymlinklen = len(symlinkinodes) newsymlinkinodes = [] for item in symlinkinodes: if item["dest"][0] == "/": dest = item["dest"][1:] else: dest = os.path.join(os.path.dirname(item["pathname"]), item["dest"]) dest = os.path.normpath(dest) if self._isentryincache(dest): item["dirlevel"][item["filename"]] = self._getcacheinode(dest) else: newsymlinkinodes.append(item) symlinkinodes = newsymlinkinodes def _islinkinfo(self, info: zipfile.ZipInfo) -> bool: return stat.S_ISLNK(info.external_attr >> 16) def _readlinkfspath(self, fspath: str) -> str: return self.zip.read(fspath).decode(errors="surrogateescape") def _readlink(self, selector: str) -> str: return self._readlinkfspath(self._getfspathfinal(selector)) def iswritable(self, selector: str) -> bool: return False def unlink(self, selector: str): raise NotImplementedError("VFSZip cannot unlink files.") def _getfspathfinal(self, selector: str) -> str: # Strip off the filename part. selector = selector[len(self.zipfilename) :] if selector.startswith("/"): selector = selector[1:] if selector.endswith("/"): selector = selector[:-1] return selector def getfspath(self, selector: str) -> str: return self._getfspathfinal(selector) def stat(self, selector: str): fspath = self.getfspath(selector) try: inode_data = self._getcacheentry(fspath) except KeyError: raise OSError( "Entry %s does not exist in %s" % (selector, self.zipfilename) ) if isinstance(inode_data, dict): # It's a directory. return ( 16877, # mode 0, # inode 0, # device 3, # links 0, # uid 0, # gid 0, # size 0, # access time 0, # modification time 0, ) # change time zi = self.zip.getinfo(inode_data) zt = zi.date_time modtime = time.mktime(zt + (0, 0, -1)) return ( 33188, # mode 0, # inode 0, # device 1, # links 0, # uid 0, # gid zi.file_size, # size modtime, # access time modtime, # modification time modtime, ) # change time def isdir(self, selector: str) -> bool: fspath = self.getfspath(selector) try: item = self._getcacheentry(fspath) except KeyError: return False return type(item) == dict def isfile(self, selector: str) -> bool: fspath = self.getfspath(selector) try: item = self._getcacheentry(fspath) except KeyError: return False return type(item) != dict def exists(self, selector: str) -> bool: fspath = self.getfspath(selector) return self._isentryincache(fspath) def open( self, selector: str, mode: str = "rb", errors: typing.Optional[str] = None ) -> typing.IO: assert mode in ("r", "rb") fspath = self.getfspath(selector) try: item = self._getcacheentry(fspath) except KeyError: raise IOError("Request to open %s, which does not exist" % selector) if type(item) == dict: raise IOError( "Request to open %s, which is a directory (%s)" % (selector, str(item)) ) # zip.open() will only return the file object in bytes mode fp = self.zip.open(item) if mode == "r": # Attempted to read in "text mode", so decode the bytestream fp = codecs.getreader("utf-8")(fp, errors=errors) return fp def listdir(self, selector: str) -> typing.List[str]: fspath = self.getfspath(selector) try: retobj = self._getcacheentry(fspath) except KeyError: raise OSError( "listdir on %s (%s) failed: no such file or directory" % (selector, fspath) ) if type(retobj) != dict: raise OSError( "listdir on %s failed: that is a file, not a directory. Got %s" % (selector, str(retobj)) ) return list(retobj.keys()) class ZIPHandler(BaseHandler): handler: BaseHandler def canhandlerequest(self): """ We can handle the request if it's a ZIP file, in our pattern, etc. """ if not self.config.getboolean("handlers.ZIP.ZIPHandler", "enabled"): return False pattern = re.compile(self.config.get("handlers.ZIP.ZIPHandler", "pattern")) basename = self.selector appendage = None while True: if pattern.search(basename) and self.vfs.isfile(basename): # is_zipfile() accepts filenames as bytes, but the type stub is incorrect if zipfile.is_zipfile(self.vfs.getfspath(basename)): # noqa self.basename = basename self.appendage = appendage return True if ( len(basename) == 0 or basename == "/" or basename == "." or basename == "./" ): return False (head, tail) = os.path.split(basename) if appendage is not None: appendage = os.path.join(tail, appendage) else: appendage = tail basename = head def _makehandler(self): from pygopherd.handlers import HandlerMultiplexer if hasattr(self, "handler"): return vfs = VFSZip(self.config, self.vfs, self.basename) self.handler = HandlerMultiplexer.getHandler( self.getselector(), self.searchrequest, self.protocol, self.config, vfs=vfs ) def prepare(self): self._makehandler() self.handler.prepare() def isdir(self): return self.handler.isdir() def getdirlist(self): return self.handler.getdirlist() def write(self, wfile): self.handler.write(wfile) def getentry(self): self._makehandler() return self.handler.getentry() pygopherd-3.0.1/pygopherd/handlers/__init__.py000066400000000000000000000002621456676541200214460ustar00rootroot00000000000000__all__ = [ "base", "dir", "file", "url", "gophermap", "UMN", "ZIP", "html", "mbox", "virtual", "pyg", "scriptexec", "tal", ] pygopherd-3.0.1/pygopherd/handlers/base.py000066400000000000000000000154461456676541200206330ustar00rootroot00000000000000from __future__ import annotations import configparser import os import os.path import typing from pygopherd import gopherentry if typing.TYPE_CHECKING: from pygopherd.gopherentry import GopherEntry from pygopherd.protocols.base import BaseGopherProtocol rootpath = None class VFS_Real: def __init__( self, config: configparser.ConfigParser, chain: typing.Optional[VFS_Real] = None ): """This implementation does not chain.""" self.config = config self.chain = chain def iswritable(self, selector: str) -> bool: return True def unlink(self, selector: str) -> None: filepath = os.fsencode(self.getfspath(selector)) os.unlink(filepath) def stat(self, selector: str) -> os.stat_result: filepath = os.fsencode(self.getfspath(selector)) return os.stat(filepath) def isdir(self, selector: str) -> bool: filepath = os.fsencode(self.getfspath(selector)) return os.path.isdir(filepath) def isfile(self, selector: str) -> bool: filepath = os.fsencode(self.getfspath(selector)) return os.path.isfile(filepath) def exists(self, selector: str) -> bool: filepath = os.fsencode(self.getfspath(selector)) return os.path.exists(filepath) def open( self, selector: str, mode: str, errors: typing.Optional[str] = None ) -> typing.IO: filepath = os.fsencode(self.getfspath(selector)) return open(filepath, mode, errors=errors) def listdir(self, selector: str) -> typing.List[str]: filepath = os.fsencode(self.getfspath(selector)) files = os.listdir(filepath) return [os.fsdecode(filename) for filename in files] def getrootpath(self) -> str: global rootpath if not rootpath: rootpath = self.config.get("pygopherd", "root") return rootpath def getfspath(self, selector: str) -> str: """Gets the filesystem path corresponding to the selector.""" fspath = self.getrootpath() + selector # Strip off trailing slash. if fspath[-1] == "/": fspath = fspath[0:-1] return fspath def copyto(self, name: str, fd: typing.IO[bytes]) -> None: with self.open(name, "rb") as rfile: while 1: data = rfile.read(4096) if not len(data): break fd.write(data) class BaseHandler: """Skeleton handler -- includes commonly-used routines.""" entry: typing.Optional[GopherEntry] fspath: typing.Optional[str] def __init__( self, selector: str, searchrequest: str, protocol: BaseGopherProtocol, config: configparser.ConfigParser, statresult: typing.Optional[os.stat_result], vfs: typing.Optional[VFS_Real] = None, ): """Parameters are: selector -- requested selector. The selector must always start with a slash and never end with a slash UNLESS it is a one-char selector that contains only a slash. This should be handled by the default protocol. config -- config object.""" self.selector = selector self.searchrequest = searchrequest self.protocol = protocol self.config = config self.statresult = statresult self.fspath = None self.entry = None self.searchrequest = searchrequest if not vfs: self.vfs = VFS_Real(self.config) else: self.vfs = vfs def isrequestforme(self) -> bool: """Called by multiplexers or other handlers. The default implementation is just: return self.isrequestsecure() and self.canhandlerequest() """ return self.isrequestsecure() and self.canhandlerequest() def isrequestsecure(self) -> bool: """An auxiliary to canhandlerequest. In order for this handler to be selected for handling a given request, both the securitycheck and the canhandlerequest should be invoked. The securitycheck is intended to be a short, small, quick check -- usually not even looking at the filesystem. Here is a default. Returns true if the request is secure, false if not. By default, we eliminate ./, ../, and // This is split out from canhandlerequest becase it could be too easy to forget about it there.""" return ( (self.selector.find("./") == -1) and (self.selector.find("..") == -1) and (self.selector.find("//") == -1) and (self.selector.find(".\\") == -1) and (self.selector.find("\\\\") == -1) and (self.selector.find("\0") == -1) ) def canhandlerequest(self) -> bool: """Decides whether or not a given request is valid for this handler. Should be overridden by all subclasses.""" return False def getentry(self) -> gopherentry.GopherEntry: """Returns an entry object for this request.""" if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) return self.entry def getfspath(self) -> str: if not self.fspath: self.fspath = self.vfs.getfspath(self.getselector()) return self.fspath def getselector(self) -> str: """Returns the selector we are handling.""" return self.selector def gethandler(self) -> BaseHandler: """Returns the handler to use to process this request. For all but special cases (rewriting handleres, for instance), this should return self.""" return self ## The next three are the publically-exposed interface -- the ones ## called by things other than handlers. def prepare(self) -> None: """Prepares for a write. Ie, opens a file. This is used so that the protocols can try to detect an error before transmitting a result. Must always be called before write.""" pass def isdir(self) -> bool: """Returns true if this handler is handling a directory; false otherwise. Not valid unless prepare has been called.""" return False def write(self, wfile): """Writes out the request if isdir() returns false. You should NOT call write if isdir() returns true! Should be overridden by files.""" if self.isdir(): raise Exception("Attempt to use write for a directory") def getdirlist(self) -> typing.List[GopherEntry]: """Returns a list-like object (list, iterator, tuple, generator, etc) that contains as its elements the gopherentry objects corresponding to each item in the directory. Valid only if self.isdir() returns true.""" if not self.isdir(): raise Exception("Attempt to use getdir for a file.") return [] pygopherd-3.0.1/pygopherd/handlers/dir.py000066400000000000000000000100551456676541200204660ustar00rootroot00000000000000import pickle import re import stat import time import typing from pygopherd import gopherentry, handlers from pygopherd.handlers.base import BaseHandler class DirHandler(BaseHandler): cachetime: int cachefile: str cachename: str fromcache: bool files: typing.List[str] fileentries: typing.List[gopherentry.GopherEntry] selectorbase: str def canhandlerequest(self) -> bool: """We can handle the request if it's for a directory.""" return self.statresult and stat.S_ISDIR(self.statresult[stat.ST_MODE]) def getentry(self) -> gopherentry.GopherEntry: if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) self.entry.populatefromfs(self.getselector(), self.statresult, vfs=self.vfs) return self.entry def prep_initfiles(self) -> None: """Initialize the list of files. Ignore the files we're suppoed to.""" self.files = [] dirfiles = self.vfs.listdir(self.getselector()) ignorepatt = self.config.get("handlers.dir.DirHandler", "ignorepatt") for file in dirfiles: if self.prep_initfiles_canaddfile( ignorepatt, self.selectorbase + "/" + file, file ): self.files.append(file) def prep_initfiles_canaddfile( self, ignorepatt: str, pattern: str, file: str ) -> bool: return not re.search(ignorepatt, pattern) def prep_entries(self) -> None: """Generate entries from the list.""" self.fileentries = [] for file in self.files: # We look up the appropriate handler for this object, and ask # it to give us an entry object. handler = handlers.HandlerMultiplexer.getHandler( self.selectorbase + "/" + file, self.searchrequest, self.protocol, self.config, vfs=self.vfs, ) fileentry = handler.getentry() self.prep_entriesappend(file, handler, fileentry) def prep_entriesappend( self, file: str, handler: BaseHandler, fileentry: gopherentry.GopherEntry ): """Subclasses can override to do post-processing on the entry while we still have the filename around. IE, for .cap files.""" self.fileentries.append(fileentry) def prepare(self) -> bool: # Initialize some variables. self.selectorbase = self.selector if self.selectorbase == "/": self.selectorbase = "" # Avoid dup slashes if self.loadcache(): # No need to do anything else. return False # Did nothing. self.prep_initfiles() # Sort the list. self.files.sort() self.prep_entries() return True # Did something. def isdir(self) -> bool: return True def getdirlist(self): self.savecache() return self.fileentries def loadcache(self) -> bool: self.fromcache = False if not hasattr(self, "cachetime"): self.cachetime = self.config.getint("handlers.dir.DirHandler", "cachetime") self.cachefile = self.config.get("handlers.dir.DirHandler", "cachefile") self.cachename = self.selector + "/" + self.cachefile if not self.vfs.iswritable(self.cachename): return False try: statval = self.vfs.stat(self.cachename) except OSError: return False if time.time() - statval[stat.ST_MTIME] < self.cachetime: with self.vfs.open(self.cachename, "rb") as fp: self.fileentries = pickle.load(fp) self.fromcache = True return True return False def savecache(self) -> None: if self.fromcache: # Don't resave the cache. return if not self.vfs.iswritable(self.cachename): return try: with self.vfs.open(self.cachename, "wb") as fp: pickle.dump(self.fileentries, fp, 1) except IOError: pass pygopherd-3.0.1/pygopherd/handlers/file.py000066400000000000000000000055341456676541200206350ustar00rootroot00000000000000import re import stat import subprocess import typing from pygopherd import gopherentry from pygopherd.handlers.base import BaseHandler class CompressedGopherEntry(gopherentry.GopherEntry): """ Using an abstract class because we attach extra variables to the gopher entry. """ realencoding: str class FileHandler(BaseHandler): def canhandlerequest(self): """We can handle the request if it's for a file.""" return self.statresult and stat.S_ISREG(self.statresult[stat.ST_MODE]) def getentry(self): if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) self.entry.populatefromfs(self.getselector(), self.statresult, vfs=self.vfs) return self.entry def write(self, wfile): self.vfs.copyto(self.getselector(), wfile) class CompressedFileHandler(FileHandler): decompressors: typing.Dict[str, str] decompresspatt: str entry: typing.Optional[CompressedGopherEntry] def canhandlerequest(self): self.initdecompressors() # It's OK to call just canhandlerequest() since we're not # overriding the security or isrequestforme functions. return ( super().canhandlerequest() and self.getentry().realencoding and self.getentry().realencoding in self.decompressors and re.search(self.decompresspatt, self.selector) ) def getentry(self) -> CompressedGopherEntry: if not self.entry: self.entry = typing.cast(CompressedGopherEntry, super().getentry()) self.entry.realencoding = None if ( self.entry.getencoding() and self.entry.getencoding() in self.decompressors and self.entry.getencodedmimetype() ): # When the client gets it, there will not be # encoding. Therefore, we remove the encoding and switch # to the real MIME type. self.entry.mimetype = self.entry.getencodedmimetype() self.entry.encodedmimetype = None self.entry.realencoding = self.entry.encoding self.entry.encoding = None self.entry.type = self.entry.guesstype() return self.entry def initdecompressors(self) -> None: if not hasattr(self, "decompressors"): self.decompressors = eval( self.config.get("handlers.file.CompressedFileHandler", "decompressors") ) self.decompresspatt = self.config.get( "handlers.file.CompressedFileHandler", "decompresspatt" ) def write(self, wfile): decompprog = self.decompressors[self.getentry().realencoding] with self.vfs.open(self.getselector(), "rb") as fp: subprocess.run([decompprog], stdin=fp, stdout=wfile) pygopherd-3.0.1/pygopherd/handlers/gophermap.py000066400000000000000000000067151456676541200217020ustar00rootroot00000000000000import re import stat from pygopherd import gopherentry from pygopherd.handlers.base import BaseHandler class BuckGophermapHandler(BaseHandler): """Bucktooth selector handler. Adheres to the specification at gopher://gopher.floodgap.com:70/0/buck/dbrowse%3Ffaquse%201""" def canhandlerequest(self): """We can handle the request if it's for a directory AND the directory has a gophermap file.""" return self.statresult and ( ( stat.S_ISDIR(self.statresult[stat.ST_MODE]) and self.vfs.isfile(self.getselector() + "/gophermap") ) or ( stat.S_ISREG(self.statresult[stat.ST_MODE]) and self.getselector().endswith(".gophermap") ) ) def getentry(self): if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) if ( self.statresult and stat.S_ISREG(self.statresult[stat.ST_MODE]) and self.getselector().endswith(".gophermap") ): self.entry.populatefromvfs(self.vfs, self.getselector()) else: self.entry.populatefromfs( self.getselector(), self.statresult, vfs=self.vfs ) return self.entry def prepare(self): self.selectorbase = self.selector if self.selectorbase == "/": self.selectorbase = "" # Avoid dup slashes if ( self.getselector().endswith(".gophermap") and self.statresult and stat.S_ISREG(self.statresult[stat.ST_MODE]) ): selector = self.getselector() else: selector = self.selectorbase + "/gophermap" self.entries = [] selectorbase = self.selectorbase with self.vfs.open(selector, "rb") as rfile: while True: line = rfile.readline().decode(errors="surrogateescape") if not line: break if re.search("\t", line): # gophermap link args = [arg.strip() for arg in line.split("\t")] if len(args) < 2 or not len(args[1]): args[1] = args[0][1:] # Copy display string to selector selector = args[1] if selector[0] != "/" and selector[0:4] != "URL:": # Relative link selector = selectorbase + "/" + selector entry = gopherentry.GopherEntry(selector, self.config) entry.type = args[0][0] entry.name = args[0][1:] if len(args) >= 3 and len(args[2]): entry.host = args[2] if len(args) >= 4 and len(args[3]): entry.port = int(args[3]) if entry.gethost() is None and entry.getport() is None: # If we're using links on THIS server, try to fill # it in for gopher+. if self.vfs.exists(selector): entry.populatefromvfs(self.vfs, selector) self.entries.append(entry) else: # Info line line = line.strip() self.entries.append(gopherentry.getinfoentry(line, self.config)) def isdir(self): return True def getdirlist(self): return self.entries pygopherd-3.0.1/pygopherd/handlers/html.py000066400000000000000000000043721456676541200206610ustar00rootroot00000000000000import html.entities import html.parser import mimetypes import re from pygopherd.handlers.file import FileHandler class HTMLTitleParser(html.parser.HTMLParser): def __init__(self): super().__init__() self.titlestr = "" self.readingtitle = 0 self.gotcompletetitle = 0 def handle_starttag(self, tag, attrs): if tag == "title": self.readingtitle = 1 def handle_endtag(self, tag): if tag == "title": self.gotcompletetitle = 1 self.readingtitle = 0 def handle_data(self, data): if self.readingtitle: self.titlestr += data def handle_entityref(self, name): """Handle things like & or > or <. If it's not in the dictionary, ignore it.""" if self.readingtitle and name in html.entities.entitydefs: self.titlestr += html.entities.entitydefs[name] class HTMLFileTitleHandler(FileHandler): """This class will set the title of a HTML document based on the HTML title. It is a clone of the UMN gsfindhtmltitle function.""" def canhandlerequest(self): if FileHandler.canhandlerequest(self): mimetype, encoding = mimetypes.guess_type(self.selector) return mimetype == "text/html" else: return False def getentry(self): # Start with the entry from the parent. entry = FileHandler.getentry(self) parser = HTMLTitleParser() with self.vfs.open(self.getselector(), "rb") as fp: while not parser.gotcompletetitle: line = fp.readline() if not line: break # The PY3 HTML parser doesn't handle surrogateescape parser.feed(line.decode(errors="replace")) parser.close() # OK, we've parsed the file and exited because of either an EOF # or a complete title (or error). Now, figure out what happened. if parser.gotcompletetitle: # Convert all whitespace sequences to a single space. # Removes newlines, tabs, etc. Good for presentation # and for security. title = re.sub(r"[\s]+", " ", parser.titlestr) entry.setname(title) return entry pygopherd-3.0.1/pygopherd/handlers/mbox.py000066400000000000000000000133721456676541200206620ustar00rootroot00000000000000import os.path import re import stat import typing from email.header import Header from mailbox import Maildir, Message, mbox from pygopherd import gopherentry from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.virtual import Virtual class FolderHandler(Virtual): mbox: typing.Union[mbox, Maildir] entries: typing.List[gopherentry.GopherEntry] def getentry(self): # Return my own entry. if not self.entry: self.entry = gopherentry.GopherEntry(self.getselector(), self.config) self.entry.settype("1") self.entry.setname(os.path.basename(self.getselector())) self.entry.setmimetype("application/gopher-menu") self.entry.setgopherpsupport(0) return self.entry def prepare(self): self.entries = [] for index, message in enumerate(self.mbox, start=1): handler = MessageHandler( self.genargsselector(self.getargflag() + str(index)), self.searchrequest, self.protocol, self.config, None, ) self.entries.append(handler.getentry(message)) def isdir(self): return True def getdirlist(self): return self.entries def getargflag(self) -> str: raise NotImplementedError class MessageHandler(Virtual): message_num: int message: Message def canhandlerequest(self): """We put MBOX-MESSAGE in here so we don't have to re-check the first line of the mbox file before returning a true or false result.""" if not self.selectorargs: return False pattern = "^" + self.getargflag() + r"(\d+)$" match = re.search(pattern, self.selectorargs) if match is None: return False message_num = int(match.groups()[0]) if message_num < 1: return False self.message_num = message_num return True def getentry(self, message=None): """Set the message if called from, eg, the dir handler. Saves having to rescan the file. If not set, will figure it out.""" if not message: message = self.getmessage() if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) self.entry.settype("0") self.entry.setmimetype("text/plain") self.entry.setgopherpsupport(0) subject = message.get("Subject", "") if isinstance(subject, Header): subject = str(subject) # Sanitize, esp. for continuations. subject = re.sub(r"\s+", " ", subject) if subject: self.entry.setname(subject) else: self.entry.setname("") return self.entry def getmessage(self) -> Message: if hasattr(self, "message"): return self.message mailbox = iter(self.openmailbox()) message = None for _ in range(self.message_num): message = next(mailbox) self.message = message return self.message def prepare(self): self.canhandlerequest() # Init the vars def write(self, wfile): message = self.getmessage() wfile.write(message.as_bytes()) def getargflag(self) -> str: raise NotImplementedError def openmailbox(self): raise NotImplementedError class MBoxFolderHandler(FolderHandler): def canhandlerequest(self): """Figure out if this is a handleable request.""" # Must be a real file if ( not isinstance(self.vfs, VFS_Real) or self.selectorargs or not self.statresult or not stat.S_ISREG(self.statresult[stat.ST_MODE]) ): return False try: with self.vfs.open(self.getselector(), "rb") as fd: startline = fd.readline() except IOError: return False # Python 2 had an old "UnixMailbox" class that had more strict # pattern matching on the message "From:" line. This was deprecated # as early as python 2.5 and was dropped completely in python 3. # Since we are using the first line of the file to determine if the # filetype is a mbox or not, it's safer to be stricter with the # pattern matching and port over the old UnixMailbox pattern. fromlinepattern = ( rb"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+" rb"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*" rb"[^\s]*\s*" b"$" ) return re.match(fromlinepattern, startline) def prepare(self): self.mbox = mbox(self.getfspath(), create=False) super().prepare() def getargflag(self): return "/MBOX-MESSAGE/" class MBoxMessageHandler(MessageHandler): def getargflag(self): return "/MBOX-MESSAGE/" def openmailbox(self): return mbox(self.getfspath(), create=False) class MaildirFolderHandler(FolderHandler): def canhandlerequest(self): if not isinstance(self.vfs, VFS_Real): return 0 if self.selectorargs: return 0 if not (self.statresult and stat.S_ISDIR(self.statresult[stat.ST_MODE])): return 0 return self.vfs.isdir(self.getselector() + "/new") and self.vfs.isdir( self.getselector() + "/cur" ) def prepare(self): self.mbox = Maildir(self.getfspath()) super().prepare() def getargflag(self): return "/MAILDIR-MESSAGE/" class MaildirMessageHandler(MessageHandler): def getargflag(self): return "/MAILDIR-MESSAGE/" def openmailbox(self): return Maildir(self.getfspath(), create=False) pygopherd-3.0.1/pygopherd/handlers/pyg.py000066400000000000000000000026471456676541200205170ustar00rootroot00000000000000import imp import re import stat from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.virtual import Virtual class PYGHandler(Virtual): def canhandlerequest(self) -> bool: if not isinstance(self.vfs, VFS_Real): return False if not ( self.statresult # Is it a regular file? and stat.S_ISREG(self.statresult[stat.ST_MODE]) # Is it executable? and (stat.S_IMODE(self.statresult[stat.ST_MODE]) & stat.S_IXOTH) and re.search(r"\.pyg$", self.getselector()) ): return False with self.vfs.open(self.getselector(), "r") as modf: self.module = imp.load_module( "PYGHandler", modf, self.getfspath(), ("", "", imp.PY_SOURCE) ) self.pygclass = self.module.PYGMain self.pygobject = self.pygclass( self.selector, self.searchrequest, self.protocol, self.config, self.statresult, ) return self.pygobject.isrequestforme() def prepare(self): return self.pygobject.prepare() def getentry(self): return self.pygobject.getentry() def isdir(self): return self.pygobject.isdir() def getdirlist(self): return self.pygobject.getdirlist() def write(self, wfile): self.pygobject.write(wfile) class PYGBase(Virtual): pass pygopherd-3.0.1/pygopherd/handlers/scriptexec.py000066400000000000000000000036111456676541200220610ustar00rootroot00000000000000import os import stat import subprocess from pygopherd import gopherentry from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.virtual import Virtual class ExecHandler(Virtual): def canhandlerequest(self): # We ONLY handle requests from the real filesystem. return ( isinstance(self.vfs, VFS_Real) and self.statresult and stat.S_ISREG(self.statresult[stat.ST_MODE]) and (stat.S_IMODE(self.statresult[stat.ST_MODE]) & stat.S_IXOTH) ) def getentry(self): entry = gopherentry.GopherEntry(self.getselector(), self.config) entry.settype("0") entry.setname(os.path.basename(self.getselector())) entry.setmimetype("text/plain") entry.setgopherpsupport(0) return entry def write(self, wfile): newenv = os.environ.copy() newenv["SERVER_NAME"] = self.protocol.server.server_name newenv["SERVER_PORT"] = str(self.protocol.server.server_port) newenv["REMOTE_ADDR"] = self.protocol.requesthandler.client_address[0] newenv["REMOTE_PORT"] = str(self.protocol.requesthandler.client_address[1]) newenv["REMOTE_HOST"] = newenv["REMOTE_ADDR"] newenv["SELECTOR"] = self.selector newenv["REQUEST"] = self.getselector() if self.searchrequest: newenv["SEARCHREQUEST"] = self.searchrequest wfile.flush() args = [self.getfspath()] if self.selectorargs: args.extend(self.selectorargs.split(" ")) if not self.protocol.check_tls(): subprocess.run(args, env=newenv, stdout=wfile) else: # We can't pass the file handler because it's wrapped in a TLS context. # So grab the output from the CGI script and send it directly. resp = subprocess.run(args, env=newenv, capture_output=True) wfile.write(resp.stdout) pygopherd-3.0.1/pygopherd/handlers/tal.py000066400000000000000000000075611456676541200205000ustar00rootroot00000000000000from __future__ import annotations import os import typing from pygopherd import gopherentry from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.file import FileHandler try: from simpletal import simpleTAL, simpleTALES talavailable = True except ImportError: talavailable = False class TALLoader: def __init__(self, vfs: VFS_Real, path: str): self.vfs = vfs self.path = path def getpath(self) -> str: return self.path def getparent(self) -> TALLoader: if self.path == "/": return self else: return self.__class__(self.vfs, os.path.dirname(self.path)) def getchildrennames(self) -> typing.List[str]: return self.vfs.listdir(self.path) def __getattr__(self, key): fq = os.path.join(self.path, key) if self.vfs.isfile(fq + ".html.tal"): with self.vfs.open( fq + ".html.tal", "r", errors="replace" ) as template_file: compiled = simpleTAL.compileHTMLTemplate(template_file) return compiled elif self.vfs.isdir(fq): return self.__class__(self.vfs, fq) else: raise AttributeError("Key %s not found in %s" % (key, self.path)) class RecursiveTALLoader(TALLoader): def __getattr__(self, key): if self.path == "/": # Already at the top -- can't recurse. return TALLoader.__getattr__(self, key) try: return TALLoader.__getattr__(self, key) except AttributeError: return self.getparent().__getattr__(key) class TALFileHandler(FileHandler): talbasename: str allowpythonpath: int def canhandlerequest(self): """We can handle the request if it's for a file ending with .thtml.""" canhandle = FileHandler.canhandlerequest(self) and self.getselector().endswith( ".tal" ) if not canhandle: return False self.talbasename = self.getselector()[:-4] self.allowpythonpath = 1 if self.config.has_option("handlers.tal.TALFileHandler", "allowpythonpath"): self.allowpythonpath = self.config.getboolean( "handlers.tal.TALFileHandler", "allowpythonpath" ) return True def getentry(self): if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) self.entry.populatefromfs(self.getselector(), self.statresult, vfs=self.vfs) assert self.entry.getencoding() == "tal.TALFileHandler" # Remove the TAL encoding and revert to default. self.entry.mimetype = self.entry.getencodedmimetype() self.entry.encodedmimetype = None self.entry.realencoding = self.entry.encoding self.entry.encoding = None self.entry.type = self.entry.guesstype() return self.entry def write(self, wfile): context = simpleTALES.Context(allowPythonPath=self.allowpythonpath) context.addGlobal("selector", self.getselector()) context.addGlobal("handler", self) context.addGlobal("entry", self.getentry()) context.addGlobal("talbasename", self.talbasename) context.addGlobal("allowpythonpath", self.allowpythonpath) context.addGlobal("protocol", self.protocol) context.addGlobal("root", TALLoader(self.vfs, "/")) context.addGlobal("rroot", RecursiveTALLoader(self.vfs, "/")) dirname = os.path.dirname(self.getselector()) context.addGlobal("dir", TALLoader(self.vfs, dirname)) context.addGlobal("rdir", RecursiveTALLoader(self.vfs, dirname)) # SimpleTAL doesn't support reading from binary files with self.vfs.open(self.getselector(), "r", errors="replace") as rfile: template = simpleTAL.compileHTMLTemplate(rfile) template.expand(context, wfile) pygopherd-3.0.1/pygopherd/handlers/url.py000066400000000000000000000061101456676541200205070ustar00rootroot00000000000000import html import re from pygopherd import gopherentry, handlers from pygopherd.handlers.base import BaseHandler class HTMLURLHandler(BaseHandler): """Will take requests for a URL-like selector and generate a HTML page redirecting people to the actual URL. This implementation adheres to the proposal as specified at http://www.complete.org/mailinglists/archives/gopher-200202/msg00033.html """ def isrequestsecure(self): """For URLs, it is valid to have .., //, etc in the URLs.""" return ( self.canhandlerequest() and self.selector.find("\0") == -1 and self.selector.find("\n") == -1 and self.selector.find("\t") == -1 and self.selector.find('"') == -1 and self.selector.find("\r") == -1 ) def canhandlerequest(self): """We can handle the request if it's for something that starts with http or https.""" return re.search("^(/|)URL:.+://", self.selector) def getentry(self): if not self.entry: self.entry = gopherentry.GopherEntry(self.selector, self.config) self.entry.name = self.selector self.entry.mimetype = "text/html" self.entry.type = "h" return self.entry # We have nothing to prepare. def write(self, wfile): url = self.selector[4:] # Strip off URL: if self.selector[0] == "/": url = self.selector[5:] url = html.escape(url) outdoc = "\n" outdoc += '' % url outdoc += "\n" outdoc += """ You are following a link from gopher to a website. You will be automatically taken to the web site shortly. If you do not get sent there, please click """ outdoc += '
here ' % url outdoc += """to go to the web site.

The URL linked is:

""" outdoc += '%s' % (url, url) outdoc += """

Thanks for using gopher!

Document generated by pygopherd handlers.url.HTMLURLHandler """ wfile.write(outdoc.encode(errors="surrogateescape")) class URLTypeRewriter(BaseHandler): """Will take URLs that start with a file type (ie, /1/devel/offlineimap) and remove the type (/devel/offlineimap). Useful if you want to make relative links in both gopher and http space in a single document.""" def canhandlerequest(self): return ( len(self.selector) >= 3 and self.selector[0] == "/" and self.selector[2] == "/" ) def gethandler(self): handlers.HandlerMultiplexer.init_default_handlers(self.config) handlerlist = [ x for x in handlers.HandlerMultiplexer.handlers if x != URLTypeRewriter ] return handlers.HandlerMultiplexer.getHandler( self.selector[2:], self.searchrequest, self.protocol, self.config, handlerlist, ) pygopherd-3.0.1/pygopherd/handlers/virtual.py000066400000000000000000000031641456676541200214010ustar00rootroot00000000000000from pygopherd.handlers.base import BaseHandler class Virtual(BaseHandler): """Implementation of virtual folder support. This class will probably not be instantiated itself but it is designed to be instantiated by its children.""" selectorreal: str selectorargs: str def __init__(self, selector, searchrequest, protocol, config, statresult, vfs=None): super().__init__(selector, searchrequest, protocol, config, statresult, vfs) # These hold the "real" and the "argument" portion of the selector, # respectively. if self.selector.find("?") != -1 or self.selector.find("|") != -1: try: i = self.selector.index("?") except ValueError: i = self.selector.index("|") self.selectorreal = self.selector[0:i] self.selectorargs = self.selector[i + 1 :] # Now, retry the stat with the real selector. self.statresult = None try: self.statresult = self.vfs.stat(self.selectorreal) except OSError: pass else: # Best guess. self.selectorreal = self.selector self.selectorargs = "" def genargsselector(self, args: str) -> str: """Returns a string representing a full selector to this resource, with the given string of args. This is a selector that can be passed back to clients.""" return self.getselector() + "|" + args def getselector(self) -> str: """Overridden to return the 'real' portion of the selector.""" return self.selectorreal pygopherd-3.0.1/pygopherd/initialization.py000066400000000000000000000130671456676541200211450ustar00rootroot00000000000000import mimetypes import os import os.path import ssl # Import lots of stuff so it's here before chrooting. import sys import typing from configparser import ConfigParser import pygopherd.fileext import pygopherd.server from pygopherd import GopherExceptions, logger, sighandlers from pygopherd.server import GopherRequestHandler def init_config(filename: str) -> ConfigParser: if not (os.path.isfile(filename) and os.access(filename, os.R_OK)): raise Exception( f"Could NOT access config file {filename}\n" f"Please specify config file as a command-line argument\n" ) config = ConfigParser() config.read(filename) return config def init_logger(config: ConfigParser, filename: str) -> None: logger.init(config) logger.log(f"Pygopherd starting, using configuration file {filename}") def init_exceptions(config: ConfigParser) -> None: GopherExceptions.init(config.getboolean("pygopherd", "tracebacks")) def init_mimetypes(config: ConfigParser) -> None: files = config.get("pygopherd", "mimetypes").split(":") files = [x for x in files if os.path.isfile(x) and os.access(x, os.R_OK)] if not files: errmsg = "Could not find any mimetypes files; check mimetypes option in config." logger.log(errmsg) raise Exception(errmsg) encoding = eval(config.get("pygopherd", "encoding")) mimetypes.encodings_map.clear() for key, value in encoding: mimetypes.encodings_map[key] = value mimetypes.init(files) logger.log(f"mimetypes initialized with files: {files}") # Set up the inverse mapping file. pygopherd.fileext.init() def get_server( config: ConfigParser, context: typing.Optional[ssl.SSLContext] = None ) -> pygopherd.server.BaseServer: # Pick up the server type from the config. server_class: typing.Type[pygopherd.server.BaseServer] server_type = config.get("pygopherd", "servertype") if server_type == "ForkingTCPServer": server_class = pygopherd.server.ForkingTCPServer elif server_type == "ThreadingTCPServer": server_class = pygopherd.server.ThreadingTCPServer else: raise RuntimeError(f"Invalid servertype option: {server_type}") # Instantiate a server. Has to be done before the security so we can # get a privileged port if necessary. interface = "" if config.has_option("pygopherd", "interface"): interface = config.get("pygopherd", "interface") port = config.getint("pygopherd", "port") address = (interface, port) try: server = server_class(config, address, GopherRequestHandler, context=context) except Exception as e: GopherExceptions.log(e, None, None) logger.log("Application startup NOT successful!") raise return server def init_security(config: ConfigParser) -> None: uid = None gid = None if config.has_option("pygopherd", "setuid"): import pwd uid = pwd.getpwnam(config.get("pygopherd", "setuid"))[2] if config.has_option("pygopherd", "setgid"): import grp gid = grp.getgrnam(config.get("pygopherd", "setgid"))[2] if config.getboolean("pygopherd", "usechroot"): chroot_user = config.get("pygopherd", "root") os.chroot(chroot_user) logger.log(f"Chrooted to {chroot_user}") config.set("pygopherd", "root", "/") if uid is not None or gid is not None: os.setgroups(()) logger.log("Supplemental group list cleared.") if gid is not None: os.setregid(gid, gid) logger.log(f"Switched to group {gid}") if uid is not None: os.setreuid(uid, uid) logger.log(f"Switched to uid {uid}") def init_conditional_detach(config: ConfigParser) -> None: if config.getboolean("pygopherd", "detach"): pid = os.fork() if pid: logger.log("Parent process detaching; child is %d" % pid) sys.exit(0) def init_pidfile(config: ConfigParser) -> None: if config.has_option("pygopherd", "pidfile"): pidfile = config.get("pygopherd", "pidfile") with open(pidfile, "w") as fd: fd.write("%d\n" % os.getpid()) def init_process_group(config: ConfigParser) -> None: try: os.setpgrp() process_group = os.getpgrp() except OSError as e: logger.log(f"setpgrp() failed with {e}") except AttributeError: logger.log("setpgrp() unavailable; not initializing process group") else: logger.log(f"Process group is {process_group}") def init_signal_handlers() -> None: sighandlers.setsighuphandler() sighandlers.setsigtermhandler() def init_ssl_context(config: ConfigParser) -> typing.Optional[ssl.SSLContext]: if config.has_option("pygopherd", "enable_tls"): if config.getboolean("pygopherd", "enable_tls"): certfile = config.get("pygopherd", "tls_certfile") keyfile = config.get("pygopherd", "tls_keyfile") context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile, keyfile) return context def initialize(filename: str) -> pygopherd.server.BaseServer: config = init_config(filename) init_logger(config, filename) init_exceptions(config) init_mimetypes(config) context = init_ssl_context(config) server = get_server(config, context=context) init_conditional_detach(config) init_pidfile(config) init_process_group(config) init_signal_handlers() init_security(config) root = config.get("pygopherd", "root") logger.log(f"Running. Root is '{root}'") return server pygopherd-3.0.1/pygopherd/logger.py000066400000000000000000000026341456676541200173730ustar00rootroot00000000000000import sys import typing log: typing.Callable[[str], None] syslogfunc: typing.Callable[[int, str], None] priority: int facility: int def log_file(message: str) -> None: sys.stdout.buffer.write((message + "\n").encode(errors="surrogateescape")) sys.stdout.buffer.flush() def log_syslog(message: str) -> None: # Python's syslog forces UTF-8 and doesn't allow surrogate escapes. # Even though RFC 5424 clearly states the syslog encoding is optional. # # > The character set used in MSG SHOULD be UNICODE, encoded using UTF-8 # > as specified in [RFC3629]. If the syslog application cannot encode # > the MSG in Unicode, it MAY use any other encoding. # # Come on python message_bytes = message.encode(errors="surrogateescape") message = message_bytes.decode("utf-8", errors="backslashreplace") syslogfunc(priority, message) def log_none(message: str): pass def init(config): global log, priority, facility, syslogfunc logmethod = config.get("logger", "logmethod") if logmethod == "syslog": import syslog priority = eval("syslog." + config.get("logger", "priority")) facility = eval("syslog." + config.get("logger", "facility")) syslog.openlog("pygopherd", syslog.LOG_PID, facility) syslogfunc = syslog.syslog log = log_syslog elif logmethod == "file": log = log_file else: log = log_none pygopherd-3.0.1/pygopherd/protocols/000077500000000000000000000000001456676541200175615ustar00rootroot00000000000000pygopherd-3.0.1/pygopherd/protocols/ProtocolMultiplexer.py000066400000000000000000000010401456676541200241620ustar00rootroot00000000000000# Running eval() when loading the configuration requires all of the protocols to # be in the module namespace from pygopherd.protocols import * # noqa from pygopherd.protocols.base import BaseGopherProtocol def getProtocol( request, server, requesthandler, rfile, wfile, config ) -> BaseGopherProtocol: p = eval(config.get("protocols.ProtocolMultiplexer", "protocols")) for protocol in p: ptry = protocol(request, server, requesthandler, rfile, wfile, config) if ptry.canhandlerequest(): return ptry pygopherd-3.0.1/pygopherd/protocols/__init__.py000066400000000000000000000001311456676541200216650ustar00rootroot00000000000000__all__ = ["base", "enhanced", "gemini", "gopherp", "rfc1436", "http", "spartan", "wap"] pygopherd-3.0.1/pygopherd/protocols/base.py000066400000000000000000000142221456676541200210460ustar00rootroot00000000000000from __future__ import annotations import configparser import io import ssl import typing from pygopherd import GopherExceptions, gopherentry, logger from pygopherd.handlers import HandlerMultiplexer if typing.TYPE_CHECKING: from pygopherd.gopherentry import GopherEntry from pygopherd.handlers.base import BaseHandler from pygopherd.server import BaseServer, GopherRequestHandler class BaseGopherProtocol: """Skeleton protocol -- includes commonly-used routines.""" secure = False entry: GopherEntry def __init__( self, request: str, server: BaseServer, requesthandler: GopherRequestHandler, rfile: io.BufferedIOBase, wfile: io.BufferedIOBase, config: configparser.ConfigParser, ): """Parameters are: request -- the raw request string. server -- a SocketServer object. rfile -- input file. The first line will already have been read. wfile -- output file. Where the output should be sent. config -- a ConfigParser object.""" self.request = request requestparts = [arg.strip() for arg in request.split("\t")] self.rfile = rfile self.wfile = wfile self.config = config self.server = server self.requesthandler = requesthandler self.requestlist = requestparts self.searchrequest = None self.handler = None selector = requestparts[0] selector = self.slashnormalize(selector) self.selector = selector def slashnormalize(self, selector: str) -> str: """Normalize slashes in the selector. Make sure it starts with a slash and does not end with one. If it is a root directory request, make sure it is exactly '/'. Returns result.""" if len(selector) and selector[-1] == "/": selector = selector[0:-1] if len(selector) == 0 or selector[0] != "/": selector = "/" + selector return selector def canhandlerequest(self) -> bool: """Decides whether or not a given request is valid for this protocol. Should be overridden by all subclasses.""" return False def log(self, handler: BaseHandler) -> None: """Log a handled request.""" logger.log( "%s [%s/%s]: %s" % ( self.requesthandler.client_address[0], type(self).__name__, type(handler).__name__, self.selector, ) ) def handle(self) -> None: """Handles the request.""" try: handler = self.gethandler() self.log(handler) self.entry = handler.getentry() handler.prepare() if handler.isdir(): self.writedir(self.entry, handler.getdirlist()) else: handler.write(self.wfile) except GopherExceptions.FileNotFound as e: self.filenotfound(str(e)) except IOError as e: GopherExceptions.log(e, self, None) self.filenotfound(e.strerror) def filenotfound(self, msg: str): self.wfile.write( f"3{msg}\t\terror.host\t1\r\n".encode(errors="surrogateescape") ) def gethandler(self) -> BaseHandler: """Gets the handler for this object's selector.""" if not self.handler: self.handler = HandlerMultiplexer.getHandler( self.selector, self.searchrequest, self, self.config ) return self.handler def writedir( self, entry: GopherEntry, dirlist: typing.Iterable[GopherEntry] ) -> None: """Called to render a directory. Generally called by self.handle()""" startstr = self.renderdirstart(entry) if startstr is not None: self.wfile.write(startstr.encode(errors="surrogateescape")) abstractopt = self.config.get("pygopherd", "abstract_entries") doabstracts = abstractopt == "always" or ( abstractopt == "unsupported" and not self.groksabstract() ) if self.config.getboolean("pygopherd", "abstract_headers"): self.wfile.write( self.renderabstract(entry.getea("ABSTRACT", "")).encode( errors="surrogateescape" ) ) for direntry in dirlist: self.wfile.write( self.renderobjinfo(direntry).encode(errors="surrogateescape") ) if doabstracts: abstract = self.renderabstract(direntry.getea("ABSTRACT")) if abstract: self.wfile.write(abstract.encode(errors="surrogateescape")) endstr = self.renderdirend(entry) if endstr is not None: self.wfile.write(endstr.encode(errors="surrogateescape")) def renderabstract(self, abstractstring: str) -> str: if not abstractstring: return "" retval = "" for line in abstractstring.splitlines(): absentry = gopherentry.getinfoentry(line, self.config) retval += self.renderobjinfo(absentry) return retval def renderdirstart(self, entry: GopherEntry) -> typing.Optional[str]: """Renders the start of a directory. Most protocols will not need this. Exception might be HTML. Returns None if not needed. Argument should be the entry corresponding to the dir itself.""" return None def renderdirend(self, entry: GopherEntry) -> typing.Optional[str]: """Likewise for the end of a directory.""" return None def renderobjinfo(self, entry: GopherEntry) -> typing.Optional[str]: """Renders an object's info according to the protocol. Returns a string. A gopher0 server, for instance, would return a dir line. MUST BE OVERRIDDEN.""" return None def groksabstract(self) -> bool: """Returns true if this protocol understands abstracts natively; false otherwise.""" return False def check_tls(self) -> bool: """ Returns true if the connection was established over TLS. """ return isinstance(self.requesthandler.request, ssl.SSLSocket) pygopherd-3.0.1/pygopherd/protocols/enhanced.py000066400000000000000000000012101456676541200216720ustar00rootroot00000000000000from pygopherd.protocols import rfc1436 class EnhancedGopherProtocol(rfc1436.GopherProtocol): def renderobjinfo(self, entry): return ( entry.gettype() + entry.getname() + "\t" + entry.getselector() + "\t" + entry.gethost(default=self.server.server_name) + "\t" + str(entry.getport(default=self.server.server_port)) + "\t" + str(entry.getsize()) + "\t" + entry.getmimetype() + "\t" + entry.getencoding() + "\t" + entry.getlanguage() ) pygopherd-3.0.1/pygopherd/protocols/gemini.py000066400000000000000000000107651456676541200214140ustar00rootroot00000000000000import re import typing import urllib.error import urllib.parse import urllib.request from pygopherd import GopherExceptions from pygopherd.protocols.base import BaseGopherProtocol class GeminiProtocol(BaseGopherProtocol): secure = True query_prefix = "/GEMINI-QUERY" def __init__(self, *args: typing.Any, **kwargs: typing.Any): super().__init__(*args, **kwargs) def canhandlerequest(self): # Even though gemini can accept proxy URLs with different hostnames # and ports, we're pretending that every request starting with # gemini:// is meant for this server. return self.check_tls() and self.request.startswith("gemini://") def handle(self): # Be overly permissive here and ignore most request validation like # checking for a strict or denying requests over 1024 bytes. url_parts = urllib.parse.urlparse(self.request.strip()) selector = url_parts.path searchrequest = url_parts.query if selector.startswith(self.query_prefix): self.handle_input(selector, searchrequest) return self.selector = urllib.parse.unquote(selector, errors="surrogateescape") self.selector = self.slashnormalize(self.selector) self.searchrequest = urllib.parse.unquote( searchrequest, errors="surrogateescape" ) try: handler = self.gethandler() self.log(handler) self.entry = handler.getentry() handler.prepare() except GopherExceptions.FileNotFound as e: self.write_status(51, str(e)) return except IOError as e: GopherExceptions.log(e, self, None) self.write_status(51, e.args[1]) return if handler.isdir(): self.write_status(20, "text/gemini") self.writedir(self.entry, handler.getdirlist()) else: mimetype = self.adjust_mimetype(self.entry.getmimetype()) self.write_status(20, mimetype) self.handler.write(self.wfile) def handle_input(self, selector: str, searchrequest: str) -> None: """ Gemini is reversed from gopher in that it can't specify a search link inside a directory listing. So instead, we add a special prefix to search URLs in order to tell the server to prompt for input. After input has been submitted, we redirect back to the original selector. The selector and searchrequest arguments should already be URL-quoted. """ if not searchrequest: self.write_status(10, "Enter input") else: selector = selector[len(self.query_prefix) :] self.write_status(30, f"{selector}?{searchrequest}") def write_status(self, code: int, meta: str) -> None: self.wfile.write(f"{code} {meta}\r\n".encode(errors="backslashreplace")) def adjust_mimetype(self, mimetype: typing.Optional[str]) -> str: if mimetype is None: return "text/plain" if mimetype == "application/gopher-menu": return "text/gemini" return mimetype def renderobjinfo(self, entry): if re.match("(/|)URL:", entry.getselector()): # It's a plain URL. Make it that. url = re.match("(/|)URL:(.+)$", entry.getselector()).group(2) elif (not entry.gethost()) and (not entry.getport()): # It's a link to our own server. Make it as such. (relative) selector = entry.getselector().encode(errors="surrogateescape") url = urllib.parse.quote(selector) url = url or "/" # Use "/" for relative links to the root URL if entry.gettype() == "7": url = self.query_prefix + url else: # Link to a different server. Make it a gopher URL. url = entry.geturl(self.server.server_name, 70) description = entry.getname() or "" # text/gemini is expected to be UTF-8, so replace any stray bytes description_bytes = description.encode(errors="surrogateescape") description = description_bytes.decode(errors="backslashreplace") if entry.gettype() == "i": return f"{description}\n" else: return f"=> {url} {description}\n" def renderdirend(self, entry): if self.config.has_option("protocols.gemini.GeminiProtocol", "footer"): text = self.config.get("protocols.gemini.GeminiProtocol", "footer") return f"\n{text}\n" pygopherd-3.0.1/pygopherd/protocols/gopherp.py000066400000000000000000000135011456676541200215770ustar00rootroot00000000000000import time import typing from pygopherd import GopherExceptions from pygopherd.protocols.rfc1436 import GopherProtocol class GopherPlusProtocol(GopherProtocol): """Implementation of Gopher+ protocol. Will handle Gopher+ queries ONLY.""" gopherpstring: str handlemethod: typing.Optional[str] def canhandlerequest(self): """We can handle the request IF: * It has more than one parameter in the request list * The second parameter is ! or starts with + or $""" if self.secure != self.check_tls(): return False if len(self.requestlist) < 2: return False if len(self.requestlist) == 2: self.gopherpstring = self.requestlist[1] elif len(self.requestlist) == 3: self.gopherpstring = self.requestlist[2] self.searchrequest = self.requestlist[1] else: return False # Too many params. return ( self.gopherpstring[0] == "+" or self.gopherpstring == "!" or self.gopherpstring[0] == "$" ) def handle(self): """Handle Gopher+ request.""" self.handlemethod = None if self.gopherpstring[0] == "+": self.handlemethod = "documentonly" elif self.gopherpstring == "!": self.handlemethod = "infoonly" elif self.gopherpstring[0] == "$": self.handlemethod = "gopherplusdir" try: handler = self.gethandler() self.log(handler) self.entry = handler.getentry() if self.handlemethod == "infoonly": self.wfile.write(b"+-2\r\n") self.wfile.write( self.renderobjinfo(self.entry).encode(errors="surrogateescape") ) else: handler.prepare() self.wfile.write(f"+{self.entry.getsize(-2)}\r\n".encode()) if handler.isdir(): self.writedir(self.entry, handler.getdirlist()) else: handler.write(self.wfile) except GopherExceptions.FileNotFound as e: self.filenotfound(str(e)) except IOError as e: GopherExceptions.log(e, self, None) self.filenotfound(e.args[1]) def getsupportedblocknames(self, entry): # Return the always-supported values PLUS any extra ones for # this particular entry. return ["+INFO", "+ADMIN", "+VIEWS"] + [ "+" + x for x in list(entry.geteadict().keys()) ] def getallblocks(self, entry): retstr = "" for block in self.getsupportedblocknames(entry): retstr += self.getblock(block, entry) return retstr def getblock(self, block, entry): # If the entry has the block in its eadict, return that. # Otherwise, do our own thing. # Incoming block: +VIEWS blockname = block[1:].lower() if blockname.upper() in entry.geteadict(): return ( "+" + blockname.upper() + ":\r\n" + "".join( [ " " + x + "\r\n" for x in entry.getea(blockname.upper()).splitlines() ] ) ) # Not in there -- look up a custom function. # Name: views funcname = "get" + blockname + "block" # Funcname: getviewsblock func = getattr(self, funcname) return func(entry) def getinfoblock(self, entry): return "+INFO: " + GopherProtocol.renderobjinfo(self, entry) def getadminblock(self, entry): retstr = "+ADMIN:\r\n" retstr += " Admin: " retstr += self.config.get("protocols.gopherp.GopherPlusProtocol", "admin") retstr += "\r\n" if entry.getmtime(): retstr += " Mod-Date: " retstr += time.ctime(entry.getmtime()) m = time.localtime(entry.getmtime()) retstr += " <%04d%02d%02d%02d%02d%02d>\r\n" % ( m[0], m[1], m[2], m[3], m[4], m[5], ) return retstr def getviewsblock(self, entry): retstr = "" if entry.getmimetype(): retstr += "+VIEWS:\r\n " + entry.getmimetype() if entry.getlanguage(): retstr += " " + entry.getlanguage() retstr += ":" if entry.getsize() is not None: retstr += " <%dk>" % (entry.getsize() // 1024) retstr += "\r\n" return retstr def renderobjinfo(self, entry): if ( entry.getmimetype("FAKE") == "application/gopher-menu" and entry.getgopherpsupport() ): entry.mimetype = "application/gopher+-menu" if self.handlemethod == "documentonly": # It's a Gopher+ request for a gopher0 menu entry. retstr = GopherProtocol.renderobjinfo(self, entry) return retstr else: return self.getallblocks(entry) def filenotfound(self, msg: str) -> None: self.wfile.write(b"--2\r\n") self.wfile.write(b"1 ") self.wfile.write( self.config.get("protocols.gopherp.GopherPlusProtocol", "admin").encode() ) self.wfile.write(f"\r\n{msg}\r\n".encode(errors="surrogateescape")) def groksabstract(self) -> bool: return True class SecureGopherPlusProtocol(GopherPlusProtocol): secure = True class URLGopherPlus(GopherPlusProtocol): def getsupportedblocknames(self, entry): return GopherPlusProtocol.getsupportedblocknames(self, entry) + ["+URL"] def geturlblock(self, entry): return "+URL: %s\r\n" % entry.geturl( self.server.server_name, self.server.server_port ) pygopherd-3.0.1/pygopherd/protocols/http.py000066400000000000000000000271531456676541200211220ustar00rootroot00000000000000import binascii import html import re import time import urllib.error import urllib.parse import urllib.request from pygopherd import GopherExceptions from pygopherd.protocols.base import BaseGopherProtocol class HTTPProtocol(BaseGopherProtocol): def canhandlerequest(self): if self.secure != self.check_tls(): return False self.requestparts = [arg.strip() for arg in self.request.split(" ")] return ( len(self.requestparts) == 3 and (self.requestparts[0] == "GET" or self.requestparts[0] == "HEAD") and self.requestparts[2][0:5] == "HTTP/" ) def headerslurp(self): if hasattr(self.requesthandler, "pygopherd_http_slurped"): # Already slurped. self.httpheaders = self.requesthandler.pygopherd_http_slurped return # Slurp up remaining lines. self.httpheaders = {} while 1: line = self.rfile.readline().decode(errors="surrogateescape") if not len(line): break line = line.strip() if not len(line): break splitline = line.split(":", 1) if len(splitline) == 2: self.httpheaders[splitline[0].lower()] = splitline[1] self.requesthandler.pygopherd_http_slurped = self.httpheaders def handle(self): self.canhandlerequest() # To get self.requestparts self.iconmapping = eval( self.config.get("protocols.http.HTTPProtocol", "iconmapping") ) self.headerslurp() splitted = self.requestparts[1].split("?") self.selector = splitted[0] self.selector = urllib.parse.unquote(self.selector, errors="surrogateescape") self.selector = self.slashnormalize(self.selector) self.formvals = {} if len(splitted) >= 2: self.formvals = urllib.parse.parse_qs(splitted[1]) if "searchrequest" in self.formvals: self.searchrequest = self.formvals["searchrequest"][0] icon = re.match("/PYGOPHERD-HTTPPROTO-ICONS/(.+)$", self.selector) if icon: iconname = icon.group(1) if iconname in icons: self.wfile.write(b"HTTP/1.0 200 OK\r\n") self.wfile.write(b"Last-Modified: Fri, 14 Dec 2001 21:19:47 GMT\r\n") self.wfile.write(b"Content-Type: image/gif\r\n\r\n") if self.requestparts[0] == "HEAD": return self.wfile.write(binascii.unhexlify(icons[iconname])) return try: handler = self.gethandler() self.log(handler) self.entry = handler.getentry() handler.prepare() self.wfile.write(b"HTTP/1.0 200 OK\r\n") if self.entry.getmtime() is not None: gmtime = time.gmtime(self.entry.getmtime()) mtime = time.strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime) self.wfile.write(f"Last-Modified: {mtime}\r\n".encode()) mimetype = self.entry.getmimetype() mimetype = self.adjustmimetype(mimetype) self.wfile.write(f"Content-Type: {mimetype}\r\n\r\n".encode()) if self.requestparts[0] == "GET": if handler.isdir(): self.writedir(self.entry, handler.getdirlist()) else: self.handlerwrite(self.wfile) except GopherExceptions.FileNotFound as e: self.filenotfound(str(e)) except IOError as e: GopherExceptions.log(e, self, None) self.filenotfound(e.args[1]) def handlerwrite(self, wfile): self.handler.write(wfile) def adjustmimetype(self, mimetype): if mimetype is None: return "text/plain" if mimetype == "application/gopher-menu": return "text/html" return mimetype def renderobjinfo(self, entry): # Decision time.... if re.match("(/|)URL:", entry.getselector()): # It's a plain URL. Make it that. url = re.match("(/|)URL:(.+)$", entry.getselector()).group(2) elif (not entry.gethost()) and (not entry.getport()): # It's a link to our own server. Make it as such. (relative) url = urllib.parse.quote(entry.getselector(), errors="surrogateescape") else: # Link to a different server. Make it a gopher URL. url = entry.geturl(self.server.server_name, 70) # OK. Render. return self.getrenderstr(entry, url) def getrenderstr(self, entry, url): retstr = "" retstr += self.getimgtag(entry) retstr += "\n " if entry.gettype() != "i" and entry.gettype() != "7": retstr += '' % url retstr += "" if entry.getname() is not None: retstr += html.escape(entry.getname()) else: retstr += html.escape(entry.getselector()) retstr += "" if entry.gettype() != "i" and entry.gettype() != "7": retstr += "" if entry.gettype() == "7": retstr += '

' % url retstr += '' retstr += '' retstr += "
" retstr += '' if entry.getmimetype(): subtype = re.search("/.+$", entry.getmimetype()) if subtype: retstr += html.escape(subtype.group()[1:]) retstr += "\n" return retstr def renderdirstart(self, entry): retstr = '' retstr += "\nGopher" if self.entry.getname(): retstr += ": " + html.escape(self.entry.getname()) retstr += "" if self.config.has_option("protocols.http.HTTPProtocol", "pagetopper"): retstr += re.sub( "GOPHERURL", self.entry.geturl(self.server.server_name, self.server.server_port), self.config.get("protocols.http.HTTPProtocol", "pagetopper"), ) retstr += "

Gopher" if self.entry.getname(): retstr += ": " + html.escape(self.entry.getname()) retstr += '

' return retstr def renderdirend(self, entry): retstr = '

\n[server top]' retstr += ' [view with gopher]' % entry.geturl( self.server.server_name, self.server.server_port ) retstr += '
Generated by PyGopherd' return retstr + "\n\n" def filenotfound(self, msg: str): self.wfile.write(b"HTTP/1.0 404 Not Found\r\n") self.wfile.write(b"Content-Type: text/html\r\n\r\n") self.wfile.write( b'' ) self.wfile.write( b"""\nSelector Not Found

Selector Not Found

""" ) self.wfile.write(html.escape(msg).encode(errors="surrogateescape")) self.wfile.write(b"
Pygopherd\n") def getimgtag(self, entry): name = "generic.gif" if entry.gettype() in self.iconmapping: name = self.iconmapping[entry.gettype()] return ' * ' % ( "/PYGOPHERD-HTTPPROTO-ICONS/" + name ) class HTTPSProtocol(HTTPProtocol): secure = True icons = { "binary.gif": "47494638396114001600c20000ffffffccffffcccccc99999933333300000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000001002c000000001400160000036948babcf1301040ab9d24be590a105d210013a9715e07a8a509a16beab5ae14df6a41e8fc76839d5168e8b3182983e4a0e0038a6e1525d396931d97be2ad482a55a55c6eec429f484a7b4e339eb215fd138ebda1b7fb3eb73983bafee8b094a8182493b114387885309003b", "binhex.gif": "47494638396114001600c20000ffffffccffff99999966666633333300000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000001002c000000001400160000036948babcf1301040ab9d24be59baefc0146adce78555068914985e2b609e0551df9b3c17ba995b408a602828e48a2681856894f44cc1628e07a42e9b985d14ab1b7c9440a9131c0c733b229bb5222ecdb6bfd6da3cd5d29d688a1aee2c97db044482834336113b884d09003b", "folder.gif": "47494638396114001600c20000ffffffffcc99ccffff99663333333300000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000002002c000000001400160000035428badcfe30ca4959b9f8ce12baef45c47d64a629c5407a6a8906432cc72b1c8ef51a13579e0f3c9c8f05ec0d4945e171673cb2824e2234da495261569856c5ddc27882d46c3c2680c3e6b47acd232c4cf08c3b01003b", "image3.gif": "47494638396114001600e30000ffffffff3333ccffff9999996600003333330099cc00993300336600000000000000000000000000000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000002002c0000000014001600000479b0c849a7b85814c0bbdf45766d5e49861959762a3a76442c132ae0aa44a0ef49d1ff2f4e6ea74b188f892020c70c3007d04152b3aa46a7adcaa42355160ee0f041d5a572bee23017cb1abbbf6476d52a0720ee78fc5a8930f8ff06087b66768080832a7d8a81818873744a8f8805519596503e19489b9c5311003b", "sound1.gif": "47494638396114001600c20000ffffffff3333ccffffcccccc99999966000033333300000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000002002c000000001400160000036b28badcfe3036c34290ea1c61558f07b171170985c0687e0d9a729e77693401dc5bd7154148fcb6db6b77e1b984c20d4fb03406913866717a842aa7d22af22acd120cdf6fd2d49cd10e034354871518de06b43a17334de42a36243e187d4a7b1a762c7b140b8418898a0b09003b", "text.gif": "47494638396114001600c20000ffffffccffff99999933333300000000000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000001002c000000001400160000035838babcf1300c40ab9d23be693bcf11d75522b88dd7057144eb52c410cf270abb6e8db796e00b849aadf20b4a6ebb1705281c128daca412c03c3a7b50a4f4d9bc5645dae9f78aed6e975932baebfc0e7ef0b84f1691da8d09003b", "generic.gif": "47494638396114001600c20000ffffffccffff99999933333300000000000000000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000001002c000000001400160000035038babcf1300c40ab9d23be693bcf11d75522b88dd705892831b8f08952446d13f24c09bc804b3a4befc70a027c39e391a8ac2081cd65d2f82c06ab5129b4898d76b94c2f71d02b9b79afc86dcdfe2500003b", "blank.gif": "47494638396114001600a10000ffffffccffff00000000000021fe4e546869732061727420697320696e20746865207075626c696320646f6d61696e2e204b6576696e204875676865732c206b6576696e68406569742e636f6d2c2053657074656d62657220313939350021f90401000001002c00000000140016000002138c8fa9cbed0fa39cb4da8bb3debcfb0f864901003b", } pygopherd-3.0.1/pygopherd/protocols/rfc1436.py000066400000000000000000000016261456676541200212300ustar00rootroot00000000000000from pygopherd.protocols.base import BaseGopherProtocol class GopherProtocol(BaseGopherProtocol): """Implementation of basic protocol. Will handle every query.""" def canhandlerequest(self): if self.secure != self.check_tls(): return False if len(self.requestlist) > 1: self.searchrequest = self.requestlist[1] return True def renderobjinfo(self, entry): retval = ( entry.gettype("0") + entry.getname() + "\t" + entry.getselector() + "\t" + entry.gethost(default=self.server.server_name) + "\t" + str(entry.getport(default=self.server.server_port)) ) if entry.getgopherpsupport(): return retval + "\t+\r\n" else: return retval + "\r\n" class SecureGopherProtocol(GopherProtocol): secure = True pygopherd-3.0.1/pygopherd/protocols/spartan.py000066400000000000000000000073441456676541200216130ustar00rootroot00000000000000import re import typing import urllib.error import urllib.parse import urllib.request from pygopherd import GopherExceptions from pygopherd.protocols.base import BaseGopherProtocol class SpartanProtocol(BaseGopherProtocol): """ Spartan is a simple, niche TCP protocol developed by yours truly :) This protocol class borrows components from both HTTP and Gemini. Reference: gemini://spartan.mozz.us/specification.gmi """ def canhandlerequest(self): if self.check_tls(): return False # The request line must be ASCII encoded try: self.request.encode("ascii") except UnicodeEncodeError: return False # Three non-empty parts, with the third part being an integer >= 0. parts = self.request.strip().split(" ") return len(parts) == 3 and all(parts) and parts[2].isdigit() def handle(self): host, path, content_length = self.request.strip().split(" ") self.selector = urllib.parse.unquote(path, errors="surrogateescape") self.selector = self.slashnormalize(self.selector) content_length = int(content_length) if content_length: data = self.rfile.read(content_length) self.searchrequest = data.decode(errors="surrogateescape") try: handler = self.gethandler() self.log(handler) self.entry = handler.getentry() handler.prepare() except GopherExceptions.FileNotFound as e: self.write_status(4, str(e)) return except IOError as e: GopherExceptions.log(e, self, None) self.write_status(5, e.args[1]) return if handler.isdir(): self.write_status(2, "text/gemini") self.writedir(self.entry, handler.getdirlist()) else: mimetype = self.adjust_mimetype(self.entry.getmimetype()) self.write_status(2, mimetype) self.handler.write(self.wfile) def write_status(self, code: int, meta: str) -> None: self.wfile.write(f"{code} {meta}\r\n".encode(errors="backslashreplace")) def adjust_mimetype(self, mimetype: typing.Optional[str]) -> str: if mimetype is None: return "text/plain" if mimetype == "application/gopher-menu": return "text/gemini" return mimetype def renderobjinfo(self, entry): if re.match("(/|)URL:", entry.getselector()): # It's a plain URL. Make it that. url = re.match("(/|)URL:(.+)$", entry.getselector()).group(2) elif (not entry.gethost()) and (not entry.getport()): # It's a link to our own server. Make it as such. (relative) selector = entry.getselector().encode(errors="surrogateescape") url = urllib.parse.quote(selector) url = url or "/" # Use "/" for relative links to the root URL else: # Link to a different server. Make it a gopher URL. url = entry.geturl(self.server.server_name, 70) description = entry.getname() or "" # text/gemini is expected to be UTF-8, so replace any stray bytes description_bytes = description.encode(errors="surrogateescape") description = description_bytes.decode(errors="backslashreplace") if entry.gettype() == "i": return f"{description}\n" elif entry.gettype() == "7": return f"=: {url} {description}\n" else: return f"=> {url} {description}\n" def renderdirend(self, entry): if self.config.has_option("protocols.gemini.SpartanProtocol", "footer"): text = self.config.get("protocols.gemini.SpartanProtocol", "footer") return f"\n{text}\n" pygopherd-3.0.1/pygopherd/protocols/wap.py000066400000000000000000000120011456676541200207140ustar00rootroot00000000000000from __future__ import annotations import html import io import re import typing from pygopherd.protocols.http import HTTPProtocol if typing.TYPE_CHECKING: from pygopherd.protocols.base import GopherEntry accesskeys = "1234567890#*" wmlheader = """ """ class WAPProtocol(HTTPProtocol): def canhandlerequest(self) -> bool: ishttp = HTTPProtocol.canhandlerequest(self) if not ishttp: return False waptop = self.config.get("protocols.wap.WAPProtocol", "waptop") self.waptop = waptop if self.requestparts[1].startswith(waptop): # If it starts with waptop, *guaranteed* to be wap. self.requestparts[1] = self.requestparts[1][len(waptop) :] return True self.headerslurp() # See if we can auto-detect a WAP browser. if "accept" not in self.httpheaders: return False if not re.search("[, ]text/vnd.wap.wml", self.httpheaders["accept"]): return False # By now, we know that it lists WML in accept. Let's try a few # more things. for tryitem in ["x-wap-profile", "x-up-devcap-max-pdu"]: if tryitem in self.httpheaders: return True return False def adjustmimetype(self, mimetype: typing.Optional[str]) -> str: self.needsconversion = 0 if mimetype is None or mimetype == "text/plain": self.needsconversion = 1 return "text/vnd.wap.wml" if mimetype == "application/gopher-menu": return "text/vnd.wap.wml" return mimetype def getrenderstr(self, entry: GopherEntry, url: str) -> str: if url.startswith("/"): url = self.waptop + url retstr = "" if not entry.gettype() in ["i", "7"]: if self.accesskeyidx < len(accesskeys): retstr += '%s ' % ( accesskeys[self.accesskeyidx], accesskeys[self.accesskeyidx], url, ) self.accesskeyidx += 1 else: retstr += '' % url entry_name = entry.getname() if entry_name is not None: thisname = html.escape(entry_name) else: thisname = html.escape(entry.getselector()) retstr += thisname if not entry.gettype() in ["i", "7"]: retstr += "" if entry.gettype() == "7": retstr += "
\n" retstr += ' \n' % self.postfieldidx retstr += "Go\n" # retstr += '\n' retstr += ' \n' % url # .replace('%', '%25') retstr += ( ' \n' % self.postfieldidx ) # retstr += ' \n' retstr += " \n" # retstr += '\n' retstr += "\n" retstr += "
\n" self.postfieldidx += 1 return retstr def renderdirstart(self, entry: GopherEntry) -> str: self.accesskeyidx = 0 self.postfieldidx = 0 retval = wmlheader title = "Gopher" if self.entry.getname(): title = html.escape(self.entry.getname()) retval += '' % html.escape(title) retval += "\n

\n" retval += "%s
\n" % html.escape(title) return retval def renderdirend(self, entry: GopherEntry) -> str: return "

\n
\n
\n" def handlerwrite(self, wfile: typing.BinaryIO) -> None: if not self.needsconversion: self.handler.write(wfile) return fakefile = io.BytesIO() self.handler.write(fakefile) fakefile.seek(0) wfile.write(wmlheader.encode()) wfile.write(b'\n') wfile.write(b"

\n") while 1: line = fakefile.readline().decode(errors="surrogateescape") if not len(line): break line = line.rstrip() if len(line): wfile.write(html.escape(line).encode(errors="surrogateescape") + b"\n") else: wfile.write(b"

\n

") wfile.write(b"

\n
\n\n") def filenotfound(self, msg): wfile = self.wfile wfile.write(b"HTTP/1.0 200 Not Found\r\n") wfile.write(b"Content-Type: text/vnd.wap.wml\r\n\r\n") wfile.write(wmlheader.encode()) wfile.write(b'\n') wfile.write(b"

Gopher Error

\n") wfile.write(html.escape(msg).encode(errors="surrogateescape") + b"\n") wfile.write(b"

\n
\n\n") pygopherd-3.0.1/pygopherd/server.py000066400000000000000000000111421456676541200174140ustar00rootroot00000000000000import configparser import errno import io import os import socket import socketserver import ssl import struct import traceback import typing from pygopherd import GopherExceptions from pygopherd.protocols import ProtocolMultiplexer class BaseServer(socketserver.BaseServer): server_name: str server_port: int allow_reuse_address: bool = True def __init__( self, config: configparser.ConfigParser, *args: typing.Any, context: typing.Optional[ssl.SSLContext] = None, **kwargs: typing.Any ): self.config = config self.context = context super().__init__(*args, **kwargs) def server_bind(self) -> None: super().server_bind() if self.config.has_option("pygopherd", "timeout"): timeout = struct.pack("ll", int(self.config.get("pygopherd", "timeout")), 0) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, timeout) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDTIMEO, timeout) host, port = self.socket.getsockname() if self.config.has_option("pygopherd", "servername"): self.server_name = self.config.get("pygopherd", "servername") else: self.server_name = socket.getfqdn(host) if self.config.has_option("pygopherd", "advertisedport"): self.server_port = self.config.getint("pygopherd", "advertisedport") else: self.server_port = port def wrap_socket(self, sock: socket.SocketType) -> socket.SocketType: """ Check the first byte of the TCP request for a TLS handshake by looking for the SYN (\x16) and wrap the connection in a TLS context. This will wait for the first byte to be received through the socket, therefore it should be treated as *blocking* and should only be invoked from inside of the handler thread/forked process. """ if self.context: if sock.recv(1, socket.MSG_PEEK) == b"\x16": return self.context.wrap_socket(sock, server_side=True) return sock class ForkingTCPServer(BaseServer, socketserver.ForkingTCPServer): def process_request( self, request: socket.SocketType, client_address: typing.Tuple[str, int] ) -> None: """ Copied directly from the parent class with the addition of the call to self.wrap_socket() inside of the child process. """ pid = os.fork() if pid: # Parent process if self.active_children is None: self.active_children = set() self.active_children.add(pid) self.close_request(request) return else: status = 1 try: request = self.wrap_socket(request) self.finish_request(request, client_address) status = 0 except Exception: self.handle_error(request, client_address) finally: try: self.shutdown_request(request) finally: os._exit(status) class ThreadingTCPServer(BaseServer, socketserver.ThreadingTCPServer): def process_request_thread( self, request: socket.SocketType, client_address: typing.Tuple[str, int] ) -> None: """ Copied directly from the parent class with the addition of the call to self.wrap_socket() inside of the child thread. """ try: request = self.wrap_socket(request) self.finish_request(request, client_address) except Exception: self.handle_error(request, client_address) finally: self.shutdown_request(request) class GopherRequestHandler(socketserver.StreamRequestHandler): rfile: io.BytesIO wfile: io.BytesIO server: BaseServer def handle(self) -> None: request = self.rfile.readline().decode(errors="surrogateescape") protohandler = ProtocolMultiplexer.getProtocol( request, self.server, self, self.rfile, self.wfile, self.server.config ) try: protohandler.handle() except IOError as e: if not (e.errno in [errno.ECONNRESET, errno.EPIPE]): traceback.print_exc() GopherExceptions.log(e, protohandler, None) except Exception as e: if GopherExceptions.tracebacks: # Yes, this may be invalid. Not much else we can do. # traceback.print_exc(file = self.wfile) traceback.print_exc() GopherExceptions.log(e, protohandler, None) pygopherd-3.0.1/pygopherd/sighandlers.py000066400000000000000000000021631456676541200204140ustar00rootroot00000000000000import os import signal import sys from pygopherd import logger pid = None def huphandler(signum, frame): logger.log("SIGHUP (%d) received; terminating process" % signum) os._exit(5) # So we don't raise SystemExit def termhandler(signum, frame): if os.getpid() == pid: # Master killed; kill children. logger.log("SIGTERM (%d) received in master; doing orderly shutdown" % signum) logger.log("Terminating all of process group with SIGHUP") # Ignore this signal so that our own process won't get it again. signal.signal(signal.SIGHUP, signal.SIG_IGN) os.kill(0, signal.SIGHUP) logger.log("Master application process now exiting. Goodbye.") sys.exit(6) else: # Shouldn't need this -- just in case. logger.log("SIGTERM (%d) received in child; terminating this process" % signum) os._exit(7) # So we don't raise SystemExit def setsighuphandler(): if "SIGHUP" in signal.__dict__: signal.signal(signal.SIGHUP, huphandler) def setsigtermhandler(): global pid pid = os.getpid() signal.signal(signal.SIGTERM, termhandler) pygopherd-3.0.1/pygopherd/testutil.py000066400000000000000000000102021456676541200177570ustar00rootroot00000000000000import configparser import os import socket import ssl import typing from io import BytesIO, StringIO from pygopherd import initialization, logger from pygopherd.protocols import ProtocolMultiplexer from pygopherd.protocols.base import BaseGopherProtocol from pygopherd.server import BaseServer, GopherRequestHandler TEST_DATA = os.path.join(os.path.dirname(__file__), "..", "testdata") def get_config() -> configparser.ConfigParser: config = initialization.init_config("conf/pygopherd.conf") config.set("pygopherd", "root", TEST_DATA) return config def get_string_logger() -> StringIO: config = get_config() config.set("logger", "logmethod", "file") logger.init(config) fp = StringIO() def log(message: str) -> None: fp.write(message + "\n") logger.log = log return fp def get_testing_server( config: typing.Optional[configparser.ConfigParser] = None, ) -> BaseServer: config = config or get_config() config.set("pygopherd", "port", "64777") s = initialization.get_server(config) s.server_close() return s class MockRequest(socket.SocketType): def __init__(self, rfile: BytesIO, wfile: BytesIO): self.rfile = rfile self.wfile = wfile def makefile(self, mode: str, *_) -> BytesIO: if mode[0] == "r": return self.rfile return self.wfile class MockSSLRequest(MockRequest, ssl.SSLSocket): pass class MockRequestHandler(GopherRequestHandler): # Enable buffering (required to make the HandlerClass invoke RequestClass.makefile()) rbufsize = -1 wbufsize = -1 def __init__( # noqa self, request: MockRequest, client_address, server: BaseServer, ): self.request = request self.client_address = client_address self.server = server self.setup() # This does everything in the base class up to handle() def handle(self): # Normally finish() gets called in the __init__, but because we are # doing this roundabout method of calling handle() from inside of unit # tests, we want to make sure that the server cleans up after itself. try: super().handle() finally: self.finish() def get_testing_handler( rfile: BytesIO, wfile: BytesIO, config: typing.Optional[configparser.ConfigParser] = None, use_tls: bool = False, ) -> GopherRequestHandler: """Creates a testing handler with input from rfile. Fills in other stuff with fake values.""" config = config or get_config() server = get_testing_server(config) if use_tls: request = MockSSLRequest(rfile, wfile) else: request = MockRequest(rfile, wfile) address = ("10.77.77.77", "7777") return MockRequestHandler(request, address, server) def get_testing_protocol( request: str, config: typing.Optional[configparser.ConfigParser] = None, use_tls: bool = False, ) -> BaseGopherProtocol: config = config or get_config() rfile = BytesIO(request.encode(errors="surrogateescape")) # Pass fake rfile, wfile to get_testing_handler -- they'll be closed before # we can get the info, and some protocols need to read more from them. handler = get_testing_handler(BytesIO(), BytesIO(), config, use_tls=use_tls) # Now override. handler.rfile = rfile return ProtocolMultiplexer.getProtocol( rfile.readline().decode(errors="surrogateescape"), handler.server, handler, handler.rfile, handler.wfile, config, ) def supports_non_utf8_filenames() -> bool: """ Test non-utf8 filenames only if the host operating system supports them. For example, MacOS HFS+ does not and will raise an OSError. These files are also a pain to work with in git which is why I'm creating it on the fly instead of committing it to the git repo. """ try: # \xAE is the ® symbol in the ISO 8859-1 charset filename = os.path.join(TEST_DATA.encode(), b"\xAE.txt") with open(filename, "wb") as fp: fp.write(b"Hello, \xAE!") except OSError: return False else: return True pygopherd-3.0.1/runtests.py000066400000000000000000000004441456676541200157770ustar00rootroot00000000000000#!/usr/bin/env python3 import sys import tracemalloc import unittest if __name__ == "__main__": tracemalloc.start() suite = unittest.defaultTestLoader.discover(start_dir="tests/") runner = unittest.TextTestRunner(verbosity=2) sys.exit(not runner.run(suite).wasSuccessful()) pygopherd-3.0.1/setup.py000066400000000000000000000012121456676541200152420ustar00rootroot00000000000000#!/usr/bin/env python3 import setuptools setuptools.setup( name="pygopherd", version="3.0.1", description="Multiprotocol Internet Gopher Information Server", author="Michael Lazar", author_email="lazar.michael22@gmail.com", python_requires=">=3.7", url="https://www.github.com/michael-lazar/pygopherd", packages=["pygopherd", "pygopherd.handlers", "pygopherd.protocols"], scripts=["bin/pygopherd"], # Commenting out to prevent overwriting system files when upgrading package # data_files=[("/etc/pygopherd", ["conf/pygopherd.conf", "conf/mime.types"])], test_suite="pygopherd", license="GPLv2", ) pygopherd-3.0.1/simpletal/000077500000000000000000000000001456676541200155265ustar00rootroot00000000000000pygopherd-3.0.1/simpletal/FixedHTMLParser.py000066400000000000000000000036031456676541200210030ustar00rootroot00000000000000""" Fixed up HTMLParser Copyright (c) 2009 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TAL language, expanding both XML and HTML templates. Module Dependencies: logging, simpleTALES, simpleTALTemplates """ import simpletal import html.parser class HTMLParser (html.parser.HTMLParser): def unescape(self, s): # Just return the data - we don't partially unescaped data! return s pygopherd-3.0.1/simpletal/LICENSE.txt000066400000000000000000000027351456676541200173600ustar00rootroot00000000000000SimpleTAL 5.2 -------------------------------------------------------------------- Copyright (c) 2015 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pygopherd-3.0.1/simpletal/__init__.py000066400000000000000000000000241456676541200176330ustar00rootroot00000000000000__version__ = "5.2" pygopherd-3.0.1/simpletal/sgmlentitynames.py000066400000000000000000000154561456676541200213360ustar00rootroot00000000000000""" simpleTAL Implementation Copyright (c) 2009 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! A dictionary of HTML entity names to their decimal value. """ htmlNameToUnicodeNumber = {"nbsp": 160 ,"iexcl": 161 ,"cent": 162 ,"pound": 163 ,"curren": 164 ,"yen": 165 ,"brvbar": 166 ,"sect": 167 ,"uml": 168 ,"copy": 169 ,"ordf": 170 ,"laquo": 171 ,"not": 172 ,"shy": 173 ,"reg": 174 ,"macr": 175 ,"deg": 176 ,"plusmn": 177 ,"sup2": 178 ,"sup3": 179 ,"acute": 180 ,"micro": 181 ,"para": 182 ,"middot": 183 ,"cedil": 184 ,"sup1": 185 ,"ordm": 186 ,"raquo": 187 ,"frac14": 188 ,"frac12": 189 ,"frac34": 190 ,"iquest": 191 ,"Agrave": 192 ,"Aacute": 193 ,"Acirc": 194 ,"Atilde": 195 ,"Auml": 196 ,"Aring": 197 ,"AElig": 198 ,"Ccedil": 199 ,"Egrave": 200 ,"Eacute": 201 ,"Ecirc": 202 ,"Euml": 203 ,"Igrave": 204 ,"Iacute": 205 ,"Icirc": 206 ,"Iuml": 207 ,"ETH": 208 ,"Ntilde": 209 ,"Ograve": 210 ,"Oacute": 211 ,"Ocirc": 212 ,"Otilde": 213 ,"Ouml": 214 ,"times": 215 ,"Oslash": 216 ,"Ugrave": 217 ,"Uacute": 218 ,"Ucirc": 219 ,"Uuml": 220 ,"Yacute": 221 ,"THORN": 222 ,"szlig": 223 ,"agrave": 224 ,"aacute": 225 ,"acirc": 226 ,"atilde": 227 ,"auml": 228 ,"aring": 229 ,"aelig": 230 ,"ccedil": 231 ,"egrave": 232 ,"eacute": 233 ,"ecirc": 234 ,"euml": 235 ,"igrave": 236 ,"iacute": 237 ,"icirc": 238 ,"iuml": 239 ,"eth": 240 ,"ntilde": 241 ,"ograve": 242 ,"oacute": 243 ,"ocirc": 244 ,"otilde": 245 ,"ouml": 246 ,"divide": 247 ,"oslash": 248 ,"ugrave": 249 ,"uacute": 250 ,"ucirc": 251 ,"uuml": 252 ,"yacute": 253 ,"thorn": 254 ,"yuml": 255 ,"fnof": 402 ,"Alpha": 913 ,"Beta": 914 ,"Gamma": 915 ,"Delta": 916 ,"Epsilon": 917 ,"Zeta": 918 ,"Eta": 919 ,"Theta": 920 ,"Iota": 921 ,"Kappa": 922 ,"Lambda": 923 ,"Mu": 924 ,"Nu": 925 ,"Xi": 926 ,"Omicron": 927 ,"Pi": 928 ,"Rho": 929 ,"Sigma": 931 ,"Tau": 932 ,"Upsilon": 933 ,"Phi": 934 ,"Chi": 935 ,"Psi": 936 ,"Omega": 937 ,"alpha": 945 ,"beta": 946 ,"gamma": 947 ,"delta": 948 ,"epsilon": 949 ,"zeta": 950 ,"eta": 951 ,"theta": 952 ,"iota": 953 ,"kappa": 954 ,"lambda": 955 ,"mu": 956 ,"nu": 957 ,"xi": 958 ,"omicron": 959 ,"pi": 960 ,"rho": 961 ,"sigmaf": 962 ,"sigma": 963 ,"tau": 964 ,"upsilon": 965 ,"phi": 966 ,"chi": 967 ,"psi": 968 ,"omega": 969 ,"thetasym": 977 ,"upsih": 978 ,"piv": 982 ,"bull": 8226 ,"hellip": 8230 ,"prime": 8242 ,"Prime": 8243 ,"oline": 8254 ,"frasl": 8260 ,"weierp": 8472 ,"image": 8465 ,"real": 8476 ,"trade": 8482 ,"alefsym": 8501 ,"larr": 8592 ,"uarr": 8593 ,"rarr": 8594 ,"darr": 8595 ,"harr": 8596 ,"crarr": 8629 ,"lArr": 8656 ,"uArr": 8657 ,"rArr": 8658 ,"dArr": 8659 ,"hArr": 8660 ,"forall": 8704 ,"part": 8706 ,"exist": 8707 ,"empty": 8709 ,"nabla": 8711 ,"isin": 8712 ,"notin": 8713 ,"ni": 8715 ,"prod": 8719 ,"sum": 8721 ,"minus": 8722 ,"lowast": 8727 ,"radic": 8730 ,"prop": 8733 ,"infin": 8734 ,"ang": 8736 ,"and": 8743 ,"or": 8744 ,"cap": 8745 ,"cup": 8746 ,"int": 8747 ,"there4": 8756 ,"sim": 8764 ,"cong": 8773 ,"asymp": 8776 ,"ne": 8800 ,"equiv": 8801 ,"le": 8804 ,"ge": 8805 ,"sub": 8834 ,"sup": 8835 ,"nsub": 8836 ,"sube": 8838 ,"supe": 8839 ,"oplus": 8853 ,"otimes": 8855 ,"perp": 8869 ,"sdot": 8901 ,"lceil": 8968 ,"rceil": 8969 ,"lfloor": 8970 ,"rfloor": 8971 ,"lang": 9001 ,"rang": 9002 ,"loz": 9674 ,"spades": 9824 ,"clubs": 9827 ,"hearts": 9829 ,"diams": 9830 ,"quot": 34 ,"amp": 38 ,"lt": 60 ,"gt": 62 ,"OElig": 338 ,"oelig": 339 ,"Scaron": 352 ,"scaron": 353 ,"Yuml": 376 ,"circ": 710 ,"tilde": 732 ,"ensp": 8194 ,"emsp": 8195 ,"thinsp": 8201 ,"zwnj": 8204 ,"zwj": 8205 ,"lrm": 8206 ,"rlm": 8207 ,"ndash": 8211 ,"mdash": 8212 ,"lsquo": 8216 ,"rsquo": 8217 ,"sbquo": 8218 ,"ldquo": 8220 ,"rdquo": 8221 ,"bdquo": 8222 ,"dagger": 8224 ,"Dagger": 8225 ,"permil": 8240 ,"lsaquo": 8249 ,"rsaquo": 8250 ,"euro": 8364} pygopherd-3.0.1/simpletal/simpleTAL.py000066400000000000000000001574441456676541200177510ustar00rootroot00000000000000""" simpleTAL Interpreter Copyright (c) 2009 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TAL language, expanding both XML and HTML templates. Module Dependencies: logging, simpleTALES, simpleTALTemplates """ import logging import xml.sax, xml.sax.saxutils,html, io, re, types, codecs import simpletal, copy, sys from . import FixedHTMLParser, sgmlentitynames __version__ = simpletal.__version__ try: # Is PyXML's LexicalHandler available? from xml.sax.saxlib import LexicalHandler use_lexical_handler = 1 except ImportError: use_lexical_handler = 0 class LexicalHandler: pass try: # Is PyXML's DOM2SAX available? import xml.dom.ext.Dom2Sax use_dom2sax = 1 except ImportError: use_dom2sax = 0 # Check Python version. If 3.3 or later, all SGML entities will be expanded in the HTML Parser if sys.version_info[0] > 3 or (sys.version_info[0] == 3 and sys.version_info[1] > 3): HTML_ENTITIES_PRE_EXPANDED = True else: HTML_ENTITIES_PRE_EXPANDED = False from . import simpleTALES # Name-space URIs METAL_NAME_URI="http://xml.zope.org/namespaces/metal" TAL_NAME_URI="http://xml.zope.org/namespaces/tal" # All commands are of the form (opcode, args, commandList) # The numbers are the opcodes, and also the order of priority # Argument: [(isLocalFlag (Y/n), variableName, variablePath),...] TAL_DEFINE = 1 # Argument: expression, endTagSymbol TAL_CONDITION = 2 # Argument: (varname, expression, endTagSymbol) TAL_REPEAT = 3 # Argument: (replaceFlag, type, expression) TAL_CONTENT = 4 # Not used in byte code, only ordering. TAL_REPLACE = 5 # Argument: [(attributeName, expression)] TAL_ATTRIBUTES = 6 # Argument: expression TAL_OMITTAG = 7 # Argument: (originalAttributeList, currentAttributeList) TAL_START_SCOPE = 8 # Argument: String to output TAL_OUTPUT = 9 # Argument: None TAL_STARTTAG = 10 # Argument: Tag, omitTagFlag TAL_ENDTAG_ENDSCOPE = 11 # Argument: None TAL_NOOP = 13 # METAL Starts here # Argument: expression, slotParams, endTagSymbol METAL_USE_MACRO = 14 # Argument: macroName, endTagSymbol METAL_DEFINE_SLOT=15 # Only used for parsing METAL_FILL_SLOT=16 METAL_DEFINE_MACRO=17 METAL_NAME_REGEX = re.compile ("[a-zA-Z_][a-zA-Z0-9_]*") SINGLETON_XML_REGEX = re.compile ('^<[^\s/>]+(?:\s*[^=>]+="[^">]+")*\s*/>') SINGLETON_BYTES_XML_REGEX = re.compile (b'^<[^\s/>]+(?:\s*[^=>]+="[^">]+")*\s*/>') ENTITY_REF_REGEX = re.compile (r'(?:&[a-zA-Z][\-\.a-zA-Z0-9]*[^\-\.a-zA-Z0-9])|(?:&#[xX]?[a-eA-E0-9]*[^0-9a-eA-E])') # The list of elements in HTML that can not have end tags - done as a dictionary for fast # lookup. HTML_FORBIDDEN_ENDTAG = {'AREA': 1, 'BASE': 1, 'BASEFONT': 1, 'BR': 1, 'COL': 1 ,'FRAME': 1, 'HR': 1, 'IMG': 1, 'INPUT': 1, 'ISINDEX': 1 ,'LINK': 1, 'META': 1, 'PARAM': 1} # List of element:attribute pairs that can use minimized form in HTML HTML_BOOLEAN_ATTS = {'AREA:NOHREF': 1, 'IMG:ISMAP': 1, 'OBJECT:DECLARE': 1 , 'INPUT:CHECKED': 1, 'INPUT:DISABLED': 1, 'INPUT:READONLY': 1, 'INPUT:ISMAP': 1 , 'SELECT:MULTIPLE': 1, 'SELECT:DISABLED': 1 , 'OPTGROUP:DISABLED': 1 , 'OPTION:SELECTED': 1, 'OPTION:DISABLED': 1 , 'TEXTAREA:DISABLED': 1, 'TEXTAREA:READONLY': 1 , 'BUTTON:DISABLED': 1, 'SCRIPT:DEFER': 1} class TemplateInterpreter: def __init__ (self): self.programStack = [] self.commandList = None self.symbolTable = None self.slotParameters = {} self.commandHandler = {} self.commandHandler [TAL_DEFINE] = self.cmdDefine self.commandHandler [TAL_CONDITION] = self.cmdCondition self.commandHandler [TAL_REPEAT] = self.cmdRepeat self.commandHandler [TAL_CONTENT] = self.cmdContent self.commandHandler [TAL_ATTRIBUTES] = self.cmdAttributes self.commandHandler [TAL_OMITTAG] = self.cmdOmitTag self.commandHandler [TAL_START_SCOPE] = self.cmdStartScope self.commandHandler [TAL_OUTPUT] = self.cmdOutput self.commandHandler [TAL_STARTTAG] = self.cmdOutputStartTag self.commandHandler [TAL_ENDTAG_ENDSCOPE] = self.cmdEndTagEndScope self.commandHandler [METAL_USE_MACRO] = self.cmdUseMacro self.commandHandler [METAL_DEFINE_SLOT] = self.cmdDefineSlot self.commandHandler [TAL_NOOP] = self.cmdNoOp def tagAsText (self, tagObj, singletonFlag=0): """ This returns a tag as text. """ tag,atts = tagObj result = ["<"] result.append (tag) for attName, attValue in atts: result.append (' ') result.append (attName) result.append ('="') result.append (html.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) def initialise (self, context, outputFile): self.context = context self.file = outputFile def cleanState (self): self.scopeStack = [] self.programCounter = 0 self.movePCForward = None self.movePCBack = None self.outputTag = 1 self.originalAttributes = {} self.currentAttributes = [] # Used in repeat only. self.repeatAttributesCopy = [] self.currentSlots = {} self.repeatVariable = None self.tagContent = None # tagState flag as to whether there are any local variables to pop self.localVarsDefined = 0 # Pass in the parameters self.currentSlots = self.slotParameters def popProgram (self): vars, self.commandList, self.symbolTable = self.programStack.pop() self.programCounter,self.scopeStack,self.slotParameters,self.currentSlots, self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.repeatAttributesCopy,self.tagContent,self.localVarsDefined = vars def pushProgram (self): vars = (self.programCounter ,self.scopeStack ,self.slotParameters ,self.currentSlots ,self.movePCForward ,self.movePCBack ,self.outputTag ,self.originalAttributes ,self.currentAttributes ,self.repeatVariable ,self.repeatAttributesCopy ,self.tagContent ,self.localVarsDefined) self.programStack.append ((vars,self.commandList, self.symbolTable)) def execute (self, template): self.cleanState() self.commandList, self.programCounter, programLength, self.symbolTable = template.getProgram() cmndList = self.commandList while (self.programCounter < programLength): cmnd = cmndList [self.programCounter] #print "PC: %s - Executing command: %s" % (str (self.programCounter), str (cmnd)) self.commandHandler[cmnd[0]] (cmnd[0], cmnd[1]) def cmdDefine (self, command, args): """ args: [(isLocalFlag (Y/n), variableName, variablePath),...] Define variables in either the local or global context """ foundLocals = 0 for isLocal, varName, varPath in args: result = self.context.evaluate (varPath, self.originalAttributes) if (isLocal): if (not foundLocals): foundLocals = 1 self.context.pushLocals () self.context.setLocal (varName, result) else: self.context.addGlobal (varName, result) self.localVarsDefined = foundLocals self.programCounter += 1 def cmdCondition (self, command, args): """ args: expression, endTagSymbol Conditionally continues with execution of all content contained by it. """ result = self.context.evaluate (args[0], self.originalAttributes) #~ if (result is None or (not result)): conditionFalse = 0 if (result is None): conditionFalse = 1 else: if (not result): conditionFalse = 1 try: temp = len (result) if (temp == 0): conditionFalse = 1 except: # Result is not a sequence. pass if (conditionFalse): # Nothing to output - evaluated to false. self.outputTag = 0 self.tagContent = None self.programCounter = self.symbolTable[args[1]] return self.programCounter += 1 def cmdRepeat (self, command, args): """ args: (varName, expression, endTagSymbol) Repeats anything in the cmndList """ if (self.repeatVariable is not None): # We are already part way through a repeat # Restore any attributes that might have been changed. if (self.currentAttributes != self.repeatAttributesCopy): self.currentAttributes = copy.copy (self.repeatAttributesCopy) self.outputTag = 1 self.tagContent = None self.movePCForward = None try: self.repeatVariable.increment() self.context.setLocal (args[0], self.repeatVariable.getCurrentValue()) self.programCounter += 1 return except IndexError as e: # We have finished the repeat self.repeatVariable = None self.context.removeRepeat (args[0]) # The locals were pushed in context.addRepeat self.context.popLocals() self.movePCBack = None # Suppress the final close tag and content self.tagContent = None self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] # Restore the state of repeatAttributesCopy in case we are nested. self.repeatAttributesCopy = self.scopeStack.pop() return # The first time through this command result = self.context.evaluate (args[1], self.originalAttributes) if (result is not None and result == simpleTALES.DEFAULTVALUE): # Leave everything un-touched. self.programCounter += 1 return try: # We have three options, either the result is a natural sequence, an iterator, or something that can produce an iterator. isSequence = len (result) if (isSequence): # Only setup if we have a sequence with length self.repeatVariable = simpleTALES.RepeatVariable (result) else: # Delete the tags and their contents self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] return except: # Not a natural sequence, can it produce an iterator? if (hasattr (result, "__iter__") and hasattr (result.__iter__, "__call__")): # We can get an iterator! self.repeatVariable = simpleTALES.IteratorRepeatVariable (result.__iter__()) elif (hasattr (result, "__next__") and hasattr (result.__next__, "__call__")): # Treat as an iterator self.repeatVariable = simpleTALES.IteratorRepeatVariable (result) else: # Just a plain object, let's not loop # Delete the tags and their contents self.outputTag = 0 self.programCounter = self.symbolTable [args[2]] return try: curValue = self.repeatVariable.getCurrentValue() except IndexError as e: # The iterator ran out of values before we started - treat as an empty list self.outputTag = 0 self.repeatVariable = None self.programCounter = self.symbolTable [args[2]] return # We really do want to repeat - so lets do it self.movePCBack = self.programCounter self.context.addRepeat (args[0], self.repeatVariable, curValue) # We keep the old state of the repeatAttributesCopy for nested loops self.scopeStack.append (self.repeatAttributesCopy) # Keep a copy of the current attributes for this tag self.repeatAttributesCopy = copy.copy (self.currentAttributes) self.programCounter += 1 def cmdContent (self, command, args): """ args: (replaceFlag, structureFlag, expression, endTagSymbol) Expands content """ result = self.context.evaluate (args[2], self.originalAttributes) if (result is None): if (args[0]): # Only output tags if this is a content not a replace self.outputTag = 0 # Output none of our content or the existing content, but potentially the tags self.movePCForward = self.symbolTable [args[3]] self.programCounter += 1 return elif (not result == simpleTALES.DEFAULTVALUE): # We have content, so let's suppress the natural content and output this! if (args[0]): self.outputTag = 0 self.tagContent = (args[1], result) self.movePCForward = self.symbolTable [args[3]] self.programCounter += 1 return else: # Default, let's just run through as normal self.programCounter += 1 return def cmdAttributes (self, command, args): """ args: [(attributeName, expression)] Add, leave, or remove attributes from the start tag """ attsToRemove = {} newAtts = [] for attName, attExpr in args: resultVal = self.context.evaluate (attExpr, self.originalAttributes) if (resultVal is None): # Remove this attribute from the current attributes attsToRemove [attName]=1 elif (not resultVal == simpleTALES.DEFAULTVALUE): # We have a value - let's use it! attsToRemove [attName]=1 if (isinstance (resultVal, str)): escapedAttVal = resultVal elif (isinstance (resultVal, bytes)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii escapedAttVal = str (resultVal, 'ascii') else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii escapedAttVal = str (resultVal) newAtts.append ((attName, escapedAttVal)) # Copy over the old attributes for oldAttName, oldAttValue in self.currentAttributes: if (not oldAttName in attsToRemove): newAtts.append ((oldAttName, oldAttValue)) self.currentAttributes = newAtts # Evaluate all other commands self.programCounter += 1 def cmdOmitTag (self, command, args): """ args: expression Conditionally turn off tag output """ result = self.context.evaluate (args, self.originalAttributes) if (result is not None and result): # Turn tag output off self.outputTag = 0 self.programCounter += 1 def cmdOutputStartTag (self, command, args): # Args: tagName tagName, singletonTag = args if (self.outputTag): if (self.tagContent is None and singletonTag): self.file.write (self.tagAsText ((tagName, self.currentAttributes), 1)) else: self.file.write (self.tagAsText ((tagName, self.currentAttributes))) if (self.movePCForward is not None): self.programCounter = self.movePCForward return self.programCounter += 1 return def cmdEndTagEndScope (self, command, args): # Args: tagName, omitFlag, singletonTag if (self.tagContent is not None): contentType, resultVal = self.tagContent if (contentType): if (isinstance (resultVal, Template)): # We have another template in the context, evaluate it! # Save our state! self.pushProgram() resultVal.expandInline (self.context, self.file, self) # Restore state self.popProgram() # End of the macro expansion (if any) so clear the parameters self.slotParameters = {} else: if (isinstance (resultVal, str)): self.file.write (resultVal) elif (isinstance (resultVal, bytes)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (str (resultVal, 'ascii')) else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (str (resultVal)) else: if (isinstance (resultVal, str)): self.file.write (html.escape (resultVal, quote=False)) elif (isinstance (resultVal, bytes)): # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (html.escape (str (resultVal, 'ascii'), quote=False)) else: # THIS IS NOT A BUG! # Use Unicode in the Context object if you are not using Ascii self.file.write (html.escape (str (resultVal), quote=False)) if (self.outputTag and not args[1]): # Do NOT output end tag if a singleton with no content if not (args[2] and self.tagContent is None): self.file.write ('') if (self.movePCBack is not None): self.programCounter = self.movePCBack return if (self.localVarsDefined): self.context.popLocals() self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.tagContent,self.localVarsDefined = self.scopeStack.pop() self.programCounter += 1 def cmdOutput (self, command, args): self.file.write (args) self.programCounter += 1 def cmdStartScope (self, command, args): """ args: (originalAttributes, currentAttributes) Pushes the current state onto the stack, and sets up the new state """ self.scopeStack.append ((self.movePCForward ,self.movePCBack ,self.outputTag ,self.originalAttributes ,self.currentAttributes ,self.repeatVariable ,self.tagContent ,self.localVarsDefined)) self.movePCForward = None self.movePCBack = None self.outputTag = 1 self.originalAttributes = args[0] self.currentAttributes = args[1] self.repeatVariable = None self.tagContent = None self.localVarsDefined = 0 self.programCounter += 1 def cmdNoOp (self, command, args): self.programCounter += 1 def cmdUseMacro (self, command, args): """ args: (macroExpression, slotParams, endTagSymbol) Evaluates the expression, if it resolves to a SubTemplate it then places the slotParams into currentSlots and then jumps to the end tag """ value = self.context.evaluate (args[0], self.originalAttributes) if (value is None): # Don't output anything self.outputTag = 0 # Output none of our content or the existing content self.movePCForward = self.symbolTable [args[2]] self.programCounter += 1 return if (not value == simpleTALES.DEFAULTVALUE and isinstance (value, SubTemplate)): # We have a macro, so let's use it self.outputTag = 0 self.slotParameters = args[1] self.tagContent = (1, value) # NOTE: WE JUMP STRAIGHT TO THE END TAG, NO OTHER TAL/METAL COMMANDS ARE EVALUATED. self.programCounter = self.symbolTable [args[2]] return else: # Default, let's just run through as normal self.programCounter += 1 return def cmdDefineSlot (self, command, args): """ args: (slotName, endTagSymbol) If the slotName is filled then that is used, otherwise the original conent is used. """ if (args[0] in self.currentSlots): # This slot is filled, so replace us with that content self.outputTag = 0 self.tagContent = (1, self.currentSlots [args[0]]) # Output none of our content or the existing content # NOTE: NO FURTHER TAL/METAL COMMANDS ARE EVALUATED self.programCounter = self.symbolTable [args[1]] return # Slot isn't filled, so just use our own content self.programCounter += 1 return class HTMLTemplateInterpreter (TemplateInterpreter): def __init__ (self, minimizeBooleanAtts = 0): TemplateInterpreter.__init__ (self) self.minimizeBooleanAtts = minimizeBooleanAtts if (minimizeBooleanAtts): # Override the tagAsText method for this instance self.tagAsText = self.tagAsTextMinimizeAtts def tagAsTextMinimizeAtts (self, tagObj, singletonFlag=0): """ This returns a tag as text. """ tag,atts = tagObj result = ["<"] result.append (tag) upperTag = tag.upper() for attName, attValue in atts: if ('%s:%s' % (upperTag, attName.upper()) in HTML_BOOLEAN_ATTS): # We should output a minimised boolean value result.append (' ') result.append (attName) else: result.append (' ') result.append (attName) result.append ('="') result.append (html.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) class Template: def __init__ (self, commands, macros, symbols, doctype = None): self.commandList = commands self.macros = macros self.symbolTable = symbols self.doctype = doctype self.log = logging.getLogger("simpleTAL.Template") # Setup the macros for macro in list(self.macros.values()): macro.setParentTemplate (self) # Setup the slots for cmnd, arg in self.commandList: if (cmnd == METAL_USE_MACRO): # Set the parent of each slot slotMap = arg[1] for slot in list(slotMap.values()): slot.setParentTemplate (self) def expand (self, context, outputFile, outputEncoding=None, interpreter=None): """ This method will write to the outputFile, using the encoding specified, the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ # This method must wrap outputFile if required by the encoding, and write out # any template pre-amble (DTD, Encoding, etc) self.expandInline (context, outputFile, interpreter) def expandInline (self, context, outputFile, interpreter=None): """ Internally used when expanding a template that is part of a context.""" if (interpreter is None): ourInterpreter = TemplateInterpreter() ourInterpreter.initialise (context, outputFile) else: ourInterpreter = interpreter try: ourInterpreter.execute (self) except UnicodeError as unierror: self.log.error ("UnicodeError caused by placing a non-Unicode string in the Context object.") raise simpleTALES.ContextContentException ("Found non-unicode string in Context!") def getProgram (self): """ Returns a tuple of (commandList, startPoint, endPoint, symbolTable) """ return (self.commandList, 0, len (self.commandList), self.symbolTable) def __str__ (self): result = "Commands:\n" index = 0 for cmd in self.commandList: if (cmd[0] != METAL_USE_MACRO): result = result + "\n[%s] %s" % (str (index), str (cmd)) else: result = result + "\n[%s] %s, (%s{" % (str (index), str (cmd[0]), str (cmd[1][0])) for slot in list(cmd[1][1].keys()): result = result + "%s: %s" % (slot, str (cmd[1][1][slot])) result = result + "}, %s)" % str (cmd[1][2]) index += 1 result = result + "\n\nSymbols:\n" for symbol in list(self.symbolTable.keys()): result = result + "Symbol: " + str (symbol) + " points to: " + str (self.symbolTable[symbol]) + ", which is command: " + str (self.commandList[self.symbolTable[symbol]]) + "\n" result = result + "\n\nMacros:\n" for macro in list(self.macros.keys()): result = result + "Macro: " + str (macro) + " value of: " + str (self.macros[macro]) return result class SubTemplate (Template): """ A SubTemplate is part of another template, and is used for the METAL implementation. The two uses for this class are: 1 - metal:define-macro results in a SubTemplate that is the macro 2 - metal:fill-slot results in a SubTemplate that is a parameter to metal:use-macro """ def __init__ (self, startRange, endRangeSymbol): """ The parentTemplate is the template for which we are a sub-template. The startRange and endRange are indexes into the parent templates command list, and defines the range of commands that we can execute """ Template.__init__ (self, [], {}, {}) self.startRange = startRange self.endRangeSymbol = endRangeSymbol def setParentTemplate (self, parentTemplate): self.parentTemplate = parentTemplate self.commandList = parentTemplate.commandList self.symbolTable = parentTemplate.symbolTable def getProgram (self): """ Returns a tuple of (commandList, startPoint, endPoint, symbolTable) """ return (self.commandList, self.startRange, self.symbolTable[self.endRangeSymbol]+1, self.symbolTable) def __str__ (self): endRange = self.symbolTable [self.endRangeSymbol] result = "SubTemplate from %s to %s\n" % (str (self.startRange), str (endRange)) return result class HTMLTemplate (Template): """A specialised form of a template that knows how to output HTML """ def __init__ (self, commands, macros, symbols, doctype = None, minimizeBooleanAtts = 0): self.minimizeBooleanAtts = minimizeBooleanAtts Template.__init__ (self, commands, macros, symbols, doctype = None) def expand (self, context, outputFile, outputEncoding = "utf-8", interpreter=None): """ This method will write to the outputFile the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ if (isinstance (outputFile, io.TextIOBase) or isinstance (outputFile, codecs.StreamWriter)): self.log.debug ("Text based output file detected") else: self.log.debug ("Bytes based output file detected - wrapping in codec for %s", outputEncoding) outputFile = codecs.lookup (outputEncoding).streamwriter (outputFile, 'xmlcharrefreplace') self.expandInline (context, outputFile, interpreter) def expandInline (self, context, outputFile, interpreter=None): """ Ensure we use the HTMLTemplateInterpreter""" if (interpreter is None): ourInterpreter = HTMLTemplateInterpreter(minimizeBooleanAtts = self.minimizeBooleanAtts) ourInterpreter.initialise (context, outputFile) else: ourInterpreter = interpreter Template.expandInline (self, context, outputFile, ourInterpreter) class XMLTemplate (Template): """A specialised form of a template that knows how to output XML """ def __init__ (self, commands, macros, symbols, doctype = None): Template.__init__ (self, commands, macros, symbols) self.doctype = doctype def expand (self, context, outputFile, outputEncoding = "utf-8", docType=None, suppressXMLDeclaration=False,interpreter=None): """ This method will write to the outputFile, using the encoding attached to the outputFile, the expanded version of this template. The context passed in is used to resolve all expressions with the template. """ if (isinstance (outputFile, io.TextIOBase) or isinstance (outputFile, codecs.StreamWriter)): self.log.debug ("Text based output file detected") else: self.log.debug ("Bytes based output file detected - wrapping in codec for %s", outputEncoding) outputFile = codecs.lookup (outputEncoding).streamwriter (outputFile, 'xmlcharrefreplace') if (not suppressXMLDeclaration): if (outputEncoding.lower() != "utf-8"): outputFile.write ('\n' % outputEncoding.lower()) else: outputFile.write ('\n') if not docType and self.doctype: docType = self.doctype if docType: outputFile.write (docType) outputFile.write ('\n') self.expandInline (context, outputFile, interpreter) class TemplateCompiler: def __init__ (self): """ Initialise a template compiler. """ self.commandList = [] self.tagStack = [] self.symbolLocationTable = {} self.macroMap = {} self.endTagSymbol = 1 self.commandHandler = {} self.commandHandler [TAL_DEFINE] = self.compileCmdDefine self.commandHandler [TAL_CONDITION] = self.compileCmdCondition self.commandHandler [TAL_REPEAT] = self.compileCmdRepeat self.commandHandler [TAL_CONTENT] = self.compileCmdContent self.commandHandler [TAL_REPLACE] = self.compileCmdReplace self.commandHandler [TAL_ATTRIBUTES] = self.compileCmdAttributes self.commandHandler [TAL_OMITTAG] = self.compileCmdOmitTag # Metal commands self.commandHandler [METAL_USE_MACRO] = self.compileMetalUseMacro self.commandHandler [METAL_DEFINE_SLOT] = self.compileMetalDefineSlot self.commandHandler [METAL_FILL_SLOT] = self.compileMetalFillSlot self.commandHandler [METAL_DEFINE_MACRO] = self.compileMetalDefineMacro # Default namespaces self.setTALPrefix ('tal') self.tal_namespace_prefix_stack = [] self.metal_namespace_prefix_stack = [] self.tal_namespace_prefix_stack.append ('tal') self.setMETALPrefix ('metal') self.metal_namespace_prefix_stack.append ('metal') self.log = logging.getLogger ("simpleTAL.TemplateCompiler") def setTALPrefix (self, prefix): self.tal_namespace_prefix = prefix self.tal_namespace_omittag = '%s:omit-tag' % self.tal_namespace_prefix self.tal_attribute_map = {} self.tal_attribute_map ['%s:attributes'%prefix] = TAL_ATTRIBUTES self.tal_attribute_map ['%s:content'%prefix]= TAL_CONTENT self.tal_attribute_map ['%s:define'%prefix] = TAL_DEFINE self.tal_attribute_map ['%s:replace'%prefix] = TAL_REPLACE self.tal_attribute_map ['%s:omit-tag'%prefix] = TAL_OMITTAG self.tal_attribute_map ['%s:condition'%prefix] = TAL_CONDITION self.tal_attribute_map ['%s:repeat'%prefix] = TAL_REPEAT def setMETALPrefix (self, prefix): self.metal_namespace_prefix = prefix self.metal_attribute_map = {} self.metal_attribute_map ['%s:define-macro'%prefix] = METAL_DEFINE_MACRO self.metal_attribute_map ['%s:use-macro'%prefix] = METAL_USE_MACRO self.metal_attribute_map ['%s:define-slot'%prefix] = METAL_DEFINE_SLOT self.metal_attribute_map ['%s:fill-slot'%prefix] = METAL_FILL_SLOT def popTALNamespace (self): newPrefix = self.tal_namespace_prefix_stack.pop() self.setTALPrefix (newPrefix) def popMETALNamespace (self): newPrefix = self.metal_namespace_prefix_stack.pop() self.setMETALPrefix (newPrefix) def tagAsText (self, tagObj, singletonFlag=0): """ This returns a tag as text. """ tag,atts = tagObj result = ["<"] result.append (tag) for attName, attValue in atts: result.append (' ') result.append (attName) result.append ('="') result.append (html.escape (attValue, quote=1)) result.append ('"') if (singletonFlag): result.append (" />") else: result.append (">") return "".join (result) def getTemplate (self): template = Template (self.commandList, self.macroMap, self.symbolLocationTable) return template def addCommand (self, command): if (command[0] == TAL_OUTPUT and (len (self.commandList) > 0) and self.commandList[-1][0] == TAL_OUTPUT): # We can combine output commands self.commandList[-1] = (TAL_OUTPUT, self.commandList[-1][1] + command[1]) else: self.commandList.append (command) def addTag (self, tag, tagProperties={}): """ Used to add a tag to the stack. Various properties can be passed in the dictionary as being information required by the tag. Currently supported properties are: 'command' - The (command,args) tuple associated with this command 'originalAtts' - The original attributes that include any metal/tal attributes 'endTagSymbol' - The symbol associated with the end tag for this element 'popFunctionList' - A list of functions to execute when this tag is popped 'singletonTag' - A boolean to indicate that this is a singleton flag """ # Add the tag to the tagStack (list of tuples (tag, properties, useMacroLocation)) self.log.debug ("Adding tag %s to stack" % tag[0]) command = tagProperties.get ('command',None) originalAtts = tagProperties.get ('originalAtts', None) singletonTag = tagProperties.get ('singletonTag', 0) if (command is not None): if (command[0] == METAL_USE_MACRO): self.tagStack.append ((tag, tagProperties, len (self.commandList)+1)) else: self.tagStack.append ((tag, tagProperties, None)) else: self.tagStack.append ((tag, tagProperties, None)) if (command is not None): # All tags that have a TAL attribute on them start with a 'start scope' self.addCommand((TAL_START_SCOPE, (originalAtts, tag[1]))) # Now we add the TAL command self.addCommand(command) else: # It's just a straight output, so create an output command and append it self.addCommand((TAL_OUTPUT, self.tagAsText (tag, singletonTag))) def popTag (self, tag, omitTagFlag=0): """ omitTagFlag is used to control whether the end tag should be included in the output or not. In HTML 4.01 there are several tags which should never have end tags, this flag allows the template compiler to specify that these should not be output. """ while (len (self.tagStack) > 0): oldTag, tagProperties, useMacroLocation = self.tagStack.pop() endTagSymbol = tagProperties.get ('endTagSymbol', None) popCommandList = tagProperties.get ('popFunctionList', []) singletonTag = tagProperties.get ('singletonTag', 0) for func in popCommandList: func() self.log.debug ("Popped tag %s off stack" % oldTag[0]) if (oldTag[0] == tag[0]): # We've found the right tag, now check to see if we have any TAL commands on it if (endTagSymbol is not None): # We have a command (it's a TAL tag) # Note where the end tag symbol should point (i.e. the next command) self.symbolLocationTable [endTagSymbol] = len (self.commandList) # We need a "close scope and tag" command self.addCommand((TAL_ENDTAG_ENDSCOPE, (tag[0], omitTagFlag, singletonTag))) return elif (omitTagFlag == 0 and singletonTag == 0): # We are popping off an un-interesting tag, just add the close as text self.addCommand((TAL_OUTPUT, '')) return else: # We are suppressing the output of this tag, so just return return else: # We have a different tag, which means something like
which never closes is in # between us and the real tag. # If the tag that we did pop off has a command though it means un-balanced TAL tags! if (endTagSymbol is not None): # ERROR msg = "TAL/METAL Elements must be balanced - found close tag %s expecting %s" % (tag[0], oldTag[0]) self.log.error (msg) raise TemplateParseException (self.tagAsText(oldTag), msg) self.log.error ("Close tag %s found with no corresponding open tag." % tag[0]) raise TemplateParseException ("" % tag[0], "Close tag encountered with no corresponding open tag.") def parseStartTag (self, tag, attributes, singletonElement=0): # Note down the tag we are handling, it will be used for error handling during # compilation self.currentStartTag = (tag, attributes) # Look for tal/metal attributes foundTALAtts = [] foundMETALAtts = [] foundCommandsArgs = {} cleanAttributes = [] originalAttributes = {} tagProperties = {} popTagFuncList = [] TALElementNameSpace = 0 prefixToAdd = "" tagProperties ['singletonTag'] = singletonElement # Determine whether this element is in either the METAL or TAL namespace if (tag.find (':') > 0): # We have a namespace involved, so let's look to see if its one of ours namespace = tag[0:tag.find (':')] if (namespace == self.metal_namespace_prefix): TALElementNameSpace = 1 prefixToAdd = self.metal_namespace_prefix +":" elif (namespace == self.tal_namespace_prefix): TALElementNameSpace = 1 prefixToAdd = self.tal_namespace_prefix +":" if (TALElementNameSpace): # We should treat this an implicit omit-tag foundTALAtts.append (TAL_OMITTAG) # Will go to default, i.e. yes foundCommandsArgs [TAL_OMITTAG] = "" for att, value in attributes: originalAttributes [att] = value if (TALElementNameSpace and not att.find (':') > 0): # This means that the attribute name does not have a namespace, so use the prefix for this tag. commandAttName = prefixToAdd + att else: commandAttName = att self.log.debug ("Command name is now %s" % commandAttName) if (att[0:5] == "xmlns"): # We have a namespace declaration. prefix = att[6:] if (value == METAL_NAME_URI): # It's a METAL namespace declaration if (len (prefix) > 0): self.metal_namespace_prefix_stack.append (self.metal_namespace_prefix) self.setMETALPrefix (prefix) # We want this function called when the scope ends popTagFuncList.append (self.popMETALNamespace) else: # We don't allow METAL/TAL to be declared as a default msg = "Can not use METAL name space by default, a prefix must be provided." raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) elif (value == TAL_NAME_URI): # TAL this time if (len (prefix) > 0): self.tal_namespace_prefix_stack.append (self.tal_namespace_prefix) self.setTALPrefix (prefix) # We want this function called when the scope ends popTagFuncList.append (self.popTALNamespace) else: # We don't allow METAL/TAL to be declared as a default msg = "Can not use TAL name space by default, a prefix must be provided." raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) else: # It's nothing special, just an ordinary namespace declaration cleanAttributes.append ((att, value)) elif (commandAttName in self.tal_attribute_map): # It's a TAL attribute cmnd = self.tal_attribute_map [commandAttName] if (cmnd == TAL_OMITTAG and TALElementNameSpace): self.log.warning ("Supressing omit-tag command present on TAL or METAL element") else: foundCommandsArgs [cmnd] = value foundTALAtts.append (cmnd) elif (commandAttName in self.metal_attribute_map): # It's a METAL attribute cmnd = self.metal_attribute_map [commandAttName] foundCommandsArgs [cmnd] = value foundMETALAtts.append (cmnd) else: cleanAttributes.append ((att, value)) tagProperties ['popFunctionList'] = popTagFuncList # This might be just content if ((len (foundTALAtts) + len (foundMETALAtts)) == 0): # Just content, add it to the various stacks self.addTag ((tag, cleanAttributes), tagProperties) return # Create a symbol for the end of the tag - we don't know what the offset is yet self.endTagSymbol += 1 tagProperties ['endTagSymbol'] = self.endTagSymbol # Sort the METAL commands foundMETALAtts.sort() # Sort the tags by priority foundTALAtts.sort() # We handle the METAL before the TAL allCommands = foundMETALAtts + foundTALAtts firstTag = 1 for talAtt in allCommands: # Parse and create a command for each cmnd = self.commandHandler [talAtt](foundCommandsArgs[talAtt]) if (cmnd is not None): if (firstTag): # The first one needs to add the tag firstTag = 0 tagProperties ['originalAtts'] = originalAttributes tagProperties ['command'] = cmnd self.addTag ((tag, cleanAttributes), tagProperties) else: # All others just append self.addCommand(cmnd) if (firstTag): tagProperties ['originalAtts'] = originalAttributes tagProperties ['command'] = (TAL_STARTTAG, (tag, singletonElement)) self.addTag ((tag, cleanAttributes), tagProperties) else: # Add the start tag command in as a child of the last TAL command self.addCommand((TAL_STARTTAG, (tag,singletonElement))) def parseEndTag (self, tag): """ Just pop the tag and related commands off the stack. """ self.popTag ((tag,None)) def parseData (self, data): # Just add it as an output self.addCommand((TAL_OUTPUT, data)) def compileCmdDefine (self, argument): # Compile a define command, resulting argument is: # [(isLocalFlag (Y/n), variableName, variablePath),...] # Break up the list of defines first commandArgs = [] # We only want to match semi-colons that are not escaped argumentSplitter = re.compile ('(?2 elements means a local|global flag if (len (stmtBits) > 2): if (stmtBits[0] == 'global'): isLocal = 0 varName = stmtBits[1] expression = ' '.join (stmtBits[2:]) elif (stmtBits[0] == 'local'): varName = stmtBits[1] expression = ' '.join (stmtBits[2:]) else: # Must be a space in the expression that caused the >3 thing varName = stmtBits[0] expression = ' '.join (stmtBits[1:]) else: # Only two bits varName = stmtBits[0] expression = ' '.join (stmtBits[1:]) commandArgs.append ((isLocal, varName, expression)) return (TAL_DEFINE, commandArgs) def compileCmdCondition (self, argument): # Compile a condition command, resulting argument is: # path, endTagSymbol # Sanity check if (len (argument) == 0): # No argument passed msg = "No argument passed! condition commands must be of the form: 'path'" self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) return (TAL_CONDITION, (argument, self.endTagSymbol)) def compileCmdRepeat (self, argument): # Compile a repeat command, resulting argument is: # (varname, expression, endTagSymbol) attProps = argument.split (' ') if (len (attProps) < 2): # Error, badly formed repeat command msg = "Badly formed repeat command '%s'. Repeat commands must be of the form: 'localVariable path'" % argument self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) varName = attProps [0] expression = " ".join (attProps[1:]) return (TAL_REPEAT, (varName, expression, self.endTagSymbol)) def compileCmdContent (self, argument, replaceFlag=0): # Compile a content command, resulting argument is # (replaceFlag, structureFlag, expression, endTagSymbol) # Sanity check if (len (argument) == 0): # No argument passed msg = "No argument passed! content/replace commands must be of the form: 'path'" self.log.error (msg) raise TemplateParseException (self.tagAsText (self.currentStartTag), msg) structureFlag = 0 attProps = argument.split (' ') if (len(attProps) > 1): if (attProps[0] == "structure"): structureFlag = 1 express = " ".join (attProps[1:]) elif (attProps[1] == "text"): structureFlag = 0 express = " ".join (attProps[1:]) else: # It's not a type selection after all - assume it's part of the path express = argument else: express = argument return (TAL_CONTENT, (replaceFlag, structureFlag, express, self.endTagSymbol)) def compileCmdReplace (self, argument): return self.compileCmdContent (argument, replaceFlag=1) def compileCmdAttributes (self, argument): # Compile tal:attributes into attribute command # Argument: [(attributeName, expression)] # Break up the list of attribute settings first commandArgs = [] # We only want to match semi-colons that are not escaped argumentSplitter = re.compile ('(?") else: result.append (">") return "".join (result) def handle_startendtag (self, tag, attributes): self.handle_starttag (tag, attributes) if not (tag.upper() in HTML_FORBIDDEN_ENDTAG): self.handle_endtag(tag) def handle_starttag (self, tag, attributes): self.log.debug ("Received Start Tag: " + tag + " Attributes: " + str (attributes)) atts = [] for att, attValue in attributes: # We need to spot empty tal:omit-tags if (attValue is None): if (att == self.tal_namespace_omittag): atts.append ((att, "")) else: atts.append ((att, att)) elif not HTML_ENTITIES_PRE_EXPANDED: # Expand any SGML entity references or char references goodAttValue = [] last = 0 match = ENTITY_REF_REGEX.search (attValue) while (match): goodAttValue.append (attValue[last:match.start()]) ref = attValue[match.start():match.end()] if (ref.startswith ('&#')): # A char reference if (ref[2] in ['x', 'X']): # Hex refValue = int (ref[3:-1], 16) else: refValue = int (ref[2:-1]) goodAttValue.append (chr (refValue)) else: # A named reference. goodAttValue.append (chr (sgmlentitynames.htmlNameToUnicodeNumber.get (ref[1:-1], 65533))) last = match.end() match = ENTITY_REF_REGEX.search (attValue, last) goodAttValue.append (attValue [last:]) atts.append ((att, "".join (goodAttValue))) else: atts.append ((att, attValue)) if (tag.upper() in HTML_FORBIDDEN_ENDTAG): # This should have no end tag, so we just do the start and suppress the end self.parseStartTag (tag, atts) self.log.debug ("End tag forbidden, generating close tag with no output.") self.popTag ((tag, None), omitTagFlag=1) else: self.parseStartTag (tag, atts) def handle_endtag (self, tag): self.log.debug ("Recieved End Tag: " + tag) if (tag.upper() in HTML_FORBIDDEN_ENDTAG): self.log.warning ("HTML 4.01 forbids end tags for the %s element" % tag) else: # Normal end tag self.popTag ((tag, None)) def handle_data (self, data): self.parseData (html.escape (data, quote=False)) # These two methods are required so that we expand all character and entity references prior to parsing the template. def handle_charref (self, ref): self.log.debug ("Got Ref: %s", ref) self.parseData (chr (int (ref))) def handle_entityref (self, ref): self.log.debug ("Got Ref: %s", ref) # Use handle_data so that <&> are re-encoded as required. self.handle_data( chr (sgmlentitynames.htmlNameToUnicodeNumber.get (ref, 65533))) # Handle document type declarations def handle_decl (self, data): self.parseData ('' % data) # Pass comments through un-affected. def handle_comment (self, data): self.parseData ('' % data) def handle_pi (self, data): self.log.debug ("Recieved processing instruction.") self.parseData ('' % data) def report_unbalanced (self, tag): self.log.warning ("End tag %s present with no corresponding open tag.") def getTemplate (self): template = HTMLTemplate (self.commandList, self.macroMap, self.symbolLocationTable, minimizeBooleanAtts = self.minimizeBooleanAtts) return template class XMLTemplateCompiler (TemplateCompiler, xml.sax.handler.ContentHandler, xml.sax.handler.DTDHandler, LexicalHandler): def __init__ (self): TemplateCompiler.__init__ (self) xml.sax.handler.ContentHandler.__init__ (self) self.doctype = None self.log = logging.getLogger ("simpleTAL.XMLTemplateCompiler") self.singletonElement = 0 def parseTemplate (self, templateFile): self.ourParser = xml.sax.make_parser() self.log.debug ("Setting features of parser") try: self.ourParser.setFeature (xml.sax.handler.feature_external_ges, False) self.log.debug ("Set SAX Handler feature OK") except: pass if use_lexical_handler: self.ourParser.setProperty(xml.sax.handler.property_lexical_handler, self) self.ourParser.setContentHandler (self) self.ourParser.setDTDHandler (self) self.ourParser.parse (templateFile) def startDTD(self, name, public_id, system_id): self.log.debug ("Recieved DOCTYPE: " + name + " public_id: " + public_id + " system_id: " + system_id) if public_id: self.doctype = '' % (name, public_id, system_id,) else: self.doctype = '' % (name, system_id,) def startElement (self, tag, attributes): self.log.debug ("Recieved Real Start Tag: " + tag + " Attributes: " + str (attributes)) try: xmlText = self.ourParser.getProperty (xml.sax.handler.property_xml_string) if (isinstance (xmlText, str)): # Once issue 6686 is solved this should allow singletons to be detected if (SINGLETON_XML_REGEX.match (xmlText)): # This is a singleton! self.singletonElement=1 else: if (SINGLETON_BYTES_XML_REGEX.match (xmlText)): # This is a singleton! self.singletonElement = 1 except xml.sax.SAXException as e: # Parser doesn't support this property pass # Convert attributes into a list of tuples atts = [] for att in attributes.getNames(): self.log.debug ("Attribute name %s has value %s" % (att, attributes[att])) atts.append ((att, attributes [att])) self.parseStartTag (tag, atts, singletonElement=self.singletonElement) def endElement (self, tag): self.log.debug ("Recieved Real End Tag: " + tag) self.parseEndTag (tag) self.singletonElement = 0 def skippedEntity (self, name): self.log.info ("Recieved skipped entity: %s" % name) self.characters( chr (sgmlentitynames.htmlNameToUnicodeNumber.get (name, 65533))) def characters (self, data): #self.log.debug ("Recieved Real Data: " + data) # Escape any data we recieve - we don't want any: <&> in there. self.parseData (html.escape (data, quote=False)) def processingInstruction (self, target, data): self.log.debug ("Recieved processing instruction.") self.parseData ('' % (target, data)) def comment (self, data): # This is only called if your XML parser supports the LexicalHandler interface. self.parseData ('' % data) def getTemplate (self): template = XMLTemplate (self.commandList, self.macroMap, self.symbolLocationTable, self.doctype) return template def compileHTMLTemplate (template, minimizeBooleanAtts = 0): """ Reads the templateFile and produces a compiled template. To use the resulting template object call: template.expand (context, outputFile) """ if (isinstance (template, str)): # It's a string! templateFile = io.StringIO (template) else: templateFile = template compiler = HTMLTemplateCompiler() compiler.parseTemplate (templateFile, minimizeBooleanAtts) return compiler.getTemplate() def compileXMLTemplate (template): """ Reads the templateFile and produces a compiled template. To use the resulting template object call: template.expand (context, outputFile) """ if (isinstance (template, str)): # It's a string! templateFile = io.StringIO (template) elif (isinstance (template, bytes)): templateFile = io.BytesIO (template) else: templateFile = template compiler = XMLTemplateCompiler() compiler.parseTemplate (templateFile) return compiler.getTemplate() pygopherd-3.0.1/simpletal/simpleTALES.py000066400000000000000000000455061456676541200201740ustar00rootroot00000000000000""" simpleTALES Implementation Copyright (c) 2009 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! The classes in this module implement the TALES specification, used by the simpleTAL module. Module Dependencies: logging """ import types, sys import logging import simpletal __version__ = simpletal.__version__ DEFAULTVALUE = "This represents a Default value." class PathNotFoundException (Exception): pass class ContextContentException (Exception): """ This is raised when invalid content has been placed into the Context object. For example using non-ascii characters instead of Unicode strings. """ pass PATHNOTFOUNDEXCEPTION = PathNotFoundException() class ContextVariable (BaseException): def __init__ (self, value = None): self.ourValue = value def value (self, currentPath=None): if (hasattr (self.ourValue, "__call__")): return self.ourValue() return self.ourValue def rawValue (self): return self.ourValue def __str__ (self): return repr (self.ourValue) class RepeatVariable (ContextVariable): """ To be written""" def __init__ (self, sequence): ContextVariable.__init__ (self, 1) self.sequence = sequence self.position = 0 self.map = None def __getattr__(self, name): # to be used from python eval if (self.map is None): self.createMap() return self.map[name] def value (self, currentPath=None): if (self.map is None): self.createMap() return self.map def rawValue (self): return self.value() def getCurrentValue (self): return self.sequence [self.position] def increment (self): self.position += 1 if (self.position == len (self.sequence)): raise IndexError ("Repeat Finished") def createMap (self): self.map = {} self.map ['index'] = self.getIndex self.map ['number'] = self.getNumber self.map ['even'] = self.getEven self.map ['odd'] = self.getOdd self.map ['start'] = self.getStart self.map ['end'] = self.getEnd # TODO: first and last need to be implemented. self.map ['length'] = len (self.sequence) self.map ['letter'] = self.getLowerLetter self.map ['Letter'] = self.getUpperLetter self.map ['roman'] = self.getLowerRoman self.map ['Roman'] = self.getUpperRoman # Repeat implementation goes here def getIndex (self): return self.position def getNumber (self): return self.position + 1 def getEven (self): if ((self.position % 2) != 0): return 0 return 1 def getOdd (self): if ((self.position % 2) == 0): return 0 return 1 def getStart (self): if (self.position == 0): return 1 return 0 def getEnd (self): if (self.position == len (self.sequence) - 1): return 1 return 0 def getLowerLetter (self): result = "" nextCol = self.position if (nextCol == 0): return 'a' while (nextCol > 0): nextCol, thisCol = divmod (nextCol, 26) result = chr (ord ('a') + thisCol) + result return result def getUpperLetter (self): return self.getLowerLetter().upper() def getLowerRoman (self): romanNumeralList = (('m', 1000) ,('cm', 900) ,('d', 500) ,('cd', 400) ,('c', 100) ,('xc', 90) ,('l', 50) ,('xl', 40) ,('x', 10) ,('ix', 9) ,('v', 5) ,('iv', 4) ,('i', 1) ) if (self.position > 3999): # Roman numbers only supported up to 4000 return ' ' num = self.position + 1 result = "" for roman, integer in romanNumeralList: while (num >= integer): result += roman num -= integer return result def getUpperRoman (self): return self.getLowerRoman().upper() class IteratorRepeatVariable (RepeatVariable): def __init__ (self, sequence): RepeatVariable.__init__ (self, sequence) self.curValue = None self.iterStatus = 0 def getCurrentValue (self): if (self.iterStatus == 0): self.iterStatus = 1 try: self.curValue = next(self.sequence) except StopIteration as e: self.iterStatus = 2 raise IndexError ("Repeat Finished") return self.curValue def increment (self): # Need this for the repeat variable functions. self.position += 1 try: self.curValue = next(self.sequence) except StopIteration as e: self.iterStatus = 2 raise IndexError ("Repeat Finished") def createMap (self): self.map = {} self.map ['index'] = self.getIndex self.map ['number'] = self.getNumber self.map ['even'] = self.getEven self.map ['odd'] = self.getOdd self.map ['start'] = self.getStart self.map ['end'] = self.getEnd # TODO: first and last need to be implemented. self.map ['length'] = sys.maxsize self.map ['letter'] = self.getLowerLetter self.map ['Letter'] = self.getUpperLetter self.map ['roman'] = self.getLowerRoman self.map ['Roman'] = self.getUpperRoman def getEnd (self): if (self.iterStatus == 2): return 1 return 0 class PathFunctionVariable (ContextVariable): def __init__ (self, func): ContextVariable.__init__ (self, value = func) self.func = func def value (self, currentPath=None): if (currentPath is not None): index, paths = currentPath result = ContextVariable (self.func ('/'.join (paths[index:]))) # Fast track the result raise result class CachedFuncResult (ContextVariable): def value (self, currentPath=None): try: return self.cachedValue except: self.cachedValue = ContextVariable.value (self) return self.cachedValue def clearCache (self): try: del self.cachedValue except: pass class PythonPathFunctions: def __init__ (self, context): self.context = context def path (self, expr): return self.context.evaluatePath (expr) def string (self, expr): return self.context.evaluateString (expr) def exists (self, expr): return self.context.evaluateExists (expr) def nocall (self, expr): return self.context.evaluateNoCall (expr) def test (self, *arguments): if (len (arguments) % 2): # We have an odd number of arguments - which means the last one is a default pairs = arguments[:-1] defaultValue = arguments[-1] else: # No default - so use None pairs = arguments defaultValue = None index = 0 while (index < len (pairs)): test = pairs[index] index += 1 value = pairs[index] index += 1 if (test): return value return defaultValue class Context: def __init__ (self, options=None, allowPythonPath=0): self.allowPythonPath = allowPythonPath self.globals = {} self.locals = {} self.localStack = [] self.repeatStack = [] self.populateDefaultVariables (options) self.log = logging.getLogger ("simpleTALES.Context") self.true = 1 self.false = 0 self.pythonPathFuncs = PythonPathFunctions (self) def addRepeat (self, name, var, initialValue): # Pop the current repeat map onto the stack self.repeatStack.append (self.repeatMap) self.repeatMap = self.repeatMap.copy() self.repeatMap [name] = var # Map this repeatMap into the global space self.addGlobal ('repeat', self.repeatMap) # Add in the locals self.pushLocals() self.setLocal (name, initialValue) def removeRepeat (self, name): # Bring the old repeat map back self.repeatMap = self.repeatStack.pop() # Map this repeatMap into the global space self.addGlobal ('repeat', self.repeatMap) def addGlobal (self, name, value): self.globals[name] = value def pushLocals (self): # Push the current locals onto a stack so that we can safely over-ride them. self.localStack.append (self.locals) self.locals = self.locals.copy() def setLocal (self, name, value): # Override the current local if present with the new one self.locals [name] = value def popLocals (self): self.locals = self.localStack.pop() def evaluate (self, expr, originalAtts = None): # Returns a ContextVariable #self.log.debug ("Evaluating %s" % expr) if (originalAtts is not None): # Call from outside self.globals['attrs'] = originalAtts suppressException = 1 else: suppressException = 0 # Supports path, exists, nocall, not, and string expr = expr.strip () try: if expr.startswith ('path:'): return self.evaluatePath (expr[5:].lstrip ()) elif expr.startswith ('exists:'): return self.evaluateExists (expr[7:].lstrip()) elif expr.startswith ('nocall:'): return self.evaluateNoCall (expr[7:].lstrip()) elif expr.startswith ('not:'): return self.evaluateNot (expr[4:].lstrip()) elif expr.startswith ('string:'): return self.evaluateString (expr[7:].lstrip()) elif expr.startswith ('python:'): return self.evaluatePython (expr[7:].lstrip()) else: # Not specified - so it's a path return self.evaluatePath (expr) except PathNotFoundException as e: if (suppressException): return None raise e def evaluatePython (self, expr): if (not self.allowPythonPath): self.log.warning ("Parameter allowPythonPath is false. NOT Evaluating python expression %s" % expr) return self.false #self.log.debug ("Evaluating python expression %s" % expr) globals={} for name, value in list(self.globals.items()): if (isinstance (value, ContextVariable)): value = value.rawValue() globals [name] = value globals ['path'] = self.pythonPathFuncs.path globals ['string'] = self.pythonPathFuncs.string globals ['exists'] = self.pythonPathFuncs.exists globals ['nocall'] = self.pythonPathFuncs.nocall globals ['test'] = self.pythonPathFuncs.test locals={} for name, value in list(self.locals.items()): if (isinstance (value, ContextVariable)): value = value.rawValue() locals [name] = value try: result = eval(expr, globals, locals) if (isinstance (result, ContextVariable)): return result.value() return result except Exception as e: # An exception occured evaluating the template, return the exception as text self.log.warning ("Exception occurred evaluating python path, exception: " + str (e)) return "Exception: %s" % str (e) def evaluatePath (self, expr): #self.log.debug ("Evaluating path expression %s" % expr) allPaths = expr.split ('|') if (len (allPaths) > 1): for path in allPaths: # Evaluate this path try: return self.evaluate (path.strip ()) except PathNotFoundException as e: # Path didn't exist, try the next one pass # No paths evaluated - raise exception. raise PATHNOTFOUNDEXCEPTION else: # A single path - so let's evaluate it. # This *can* raise PathNotFoundException return self.traversePath (allPaths[0]) def evaluateExists (self, expr): #self.log.debug ("Evaluating %s to see if it exists" % expr) allPaths = expr.split ('|') # The first path is for us # Return true if this first bit evaluates, otherwise test the rest try: result = self.traversePath (allPaths[0], canCall = 0) return self.true except PathNotFoundException as e: # Look at the rest of the paths. pass for path in allPaths[1:]: # Evaluate this path try: pathResult = self.evaluate (path.strip ()) # If this is part of a "exists: path1 | exists: path2" path then we need to look at the actual result. if (pathResult): return self.true except PathNotFoundException as e: pass # If we get this far then there are *no* paths that exist. return self.false def evaluateNoCall (self, expr): #self.log.debug ("Evaluating %s using nocall" % expr) allPaths = expr.split ('|') # The first path is for us try: return self.traversePath (allPaths[0], canCall = 0) except PathNotFoundException as e: # Try the rest of the paths. pass for path in allPaths[1:]: # Evaluate this path try: return self.evaluate (path.strip ()) except PathNotFoundException as e: pass # No path evaluated - raise error raise PATHNOTFOUNDEXCEPTION def evaluateNot (self, expr): #self.log.debug ("Evaluating NOT value of %s" % expr) # Evaluate what I was passed try: pathResult = self.evaluate (expr) except PathNotFoundException as e: # In SimpleTAL the result of "not: no/such/path" should be TRUE not FALSE. return self.true if (pathResult is None): # Value was Nothing return self.true if (pathResult == DEFAULTVALUE): return self.false try: resultLen = len (pathResult) if (resultLen > 0): return self.false else: return self.true except: # Not a sequence object. pass if (not pathResult): return self.true # Everything else is true, so we return false! return self.false def evaluateString (self, expr): #self.log.debug ("Evaluating String %s" % expr) result = "" skipCount = 0 for position in range (0,len (expr)): if (skipCount > 0): skipCount -= 1 else: if (expr[position] == '$'): try: if (expr[position + 1] == '$'): # Escaped $ sign result += '$' skipCount = 1 elif (expr[position + 1] == '{'): # Looking for a path! endPos = expr.find ('}', position + 1) if (endPos > 0): path = expr[position + 2:endPos] # Evaluate the path - missing paths raise exceptions as normal. try: pathResult = self.evaluate (path) except PathNotFoundException as e: # This part of the path didn't evaluate to anything - leave blank pathResult = '' if (pathResult is not None): if (isinstance (pathResult, str)): result += pathResult else: # THIS IS NOT A BUG! # Use Unicode in Context if you aren't using Ascii! result += str (pathResult) skipCount = endPos - position else: # It's a variable endPos = expr.find (' ', position + 1) if (endPos == -1): endPos = len (expr) path = expr [position + 1:endPos] # Evaluate the variable - missing paths raise exceptions as normal. try: pathResult = self.traversePath (path) except PathNotFoundException as e: # This part of the path didn't evaluate to anything - leave blank pathResult = '' if (pathResult is not None): if (isinstance (pathResult, str)): result += pathResult else: # THIS IS NOT A BUG! # Use Unicode in Context if you aren't using Ascii! result += str (pathResult) skipCount = endPos - position - 1 except IndexError as e: # Trailing $ sign - just suppress it self.log.warning ("Trailing $ detected") pass else: result += expr[position] return result def traversePath (self, expr, canCall=1): # canCall only applies to the *final* path destination, not points down the path. # Check for and correct for trailing/leading quotes if (expr.startswith ('"') or expr.startswith ("'")): if (expr.endswith ('"') or expr.endswith ("'")): expr = expr [1:-1] else: expr = expr [1:] elif (expr.endswith ('"') or expr.endswith ("'")): expr = expr [0:-1] pathList = expr.split ('/') path = pathList[0] if path.startswith ('?'): path = path[1:] if path in self.locals: path = self.locals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (hasattr (path, "__call__")):path = path() elif path in self.globals: path = self.globals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (hasattr (path, "__call__")):path = path() #self.log.debug ("Dereferenced to %s" % path) if path in self.locals: val = self.locals[path] elif path in self.globals: val = self.globals[path] else: # If we can't find it then raise an exception raise PATHNOTFOUNDEXCEPTION index = 1 for path in pathList[1:]: #self.log.debug ("Looking for path element %s" % path) if path.startswith ('?'): path = path[1:] if path in self.locals: path = self.locals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (hasattr (path, "__call__")):path = path() elif path in self.globals: path = self.globals[path] if (isinstance (path, ContextVariable)): path = path.value() elif (hasattr (path, "__call__")):path = path() #self.log.debug ("Dereferenced to %s" % path) try: if (isinstance (val, ContextVariable)): temp = val.value((index,pathList)) elif (hasattr (val, "__call__")):temp = val() else: temp = val except ContextVariable as e: # Fast path for those functions that return values return e.value() if (hasattr (temp, path)): val = getattr (temp, path) else: try: try: val = temp[path] except TypeError: val = temp[int(path)] except: #self.log.debug ("Not found.") raise PATHNOTFOUNDEXCEPTION index = index + 1 #self.log.debug ("Found value %s" % str (val)) if (canCall): try: if (isinstance (val, ContextVariable)): result = val.value((index,pathList)) elif (hasattr (val, "__call__")):result = val() else: result = val except ContextVariable as e: # Fast path for those functions that return values return e.value() else: if (isinstance (val, ContextVariable)): result = val.realValue else: result = val return result def __str__ (self): return "Globals: " + str (self.globals) + "Locals: " + str (self.locals) def populateDefaultVariables (self, options): vars = {} self.repeatMap = {} vars['nothing'] = None vars['default'] = DEFAULTVALUE vars['options'] = options # To start with there are no repeats vars['repeat'] = self.repeatMap vars['attrs'] = None # Add all of these to the global context for name in list(vars.keys()): self.addGlobal (name,vars[name]) # Add also under CONTEXTS self.addGlobal ('CONTEXTS', vars) pygopherd-3.0.1/simpletal/simpleTALUtils.py000066400000000000000000000210201456676541200207460ustar00rootroot00000000000000""" simpleTALUtils Copyright (c) 2009 Colin Stewart (http://www.owlfish.com/) All rights reserved. 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. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. If you make any bug fixes or feature enhancements please let me know! This module is holds utilities that make using SimpleTAL easier. Initially this is just the HTMLStructureCleaner class, used to clean up HTML that can then be used as 'structure' content. Module Dependencies: None """ import io, os, stat, threading, sys, codecs, cgi, re, types, logging from . import __version__, simpleTAL # This is used to check for already escaped attributes. ESCAPED_TEXT_REGEX=re.compile (r"\&\S+?;") class TemplateCache: """ A TemplateCache is a multi-thread safe object that caches compiled templates. This cache only works with file based templates, the ctime of the file is checked on each hit, if the file has changed the template is re-compiled. """ def __init__ (self): self.templateCache = {} self.cacheLock = threading.Lock() self.hits = 0 self.misses = 0 def getTemplate (self, name, inputEncoding='utf-8'): """ Name should be the path of a template file. If the path ends in 'xml' it is treated as an XML Template, otherwise it's treated as an HTML Template. If the template file has changed since the last cache it will be re-compiled. inputEncoding is only used for HTML templates, and should be the encoding that the template is stored in. """ if (name in self.templateCache): template, oldctime = self.templateCache [name] ctime = os.stat (name)[stat.ST_MTIME] if (oldctime == ctime): # Cache hit! self.hits += 1 return template # Cache miss, let's cache this template return self._cacheTemplate_ (name, inputEncoding) def getXMLTemplate (self, name): """ Name should be the path of an XML template file. """ if (name in self.templateCache): template, oldctime = self.templateCache [name] ctime = os.stat (name)[stat.ST_MTIME] if (oldctime == ctime): # Cache hit! self.hits += 1 return template # Cache miss, let's cache this template return self._cacheTemplate_ (name, None, xmlTemplate=1) def _cacheTemplate_ (self, name, inputEncoding, xmlTemplate=0): self.cacheLock.acquire () try: tempFile = open (name, 'rb') if (xmlTemplate): # We know it is XML template = simpleTAL.compileXMLTemplate (tempFile) else: # We have to guess... firstline = tempFile.readline() tempFile.seek(0) if (name [-3:] == "xml") or (firstline.strip ()[:5] == b'" return result class MacroExpansionInterpreter (simpleTAL.TemplateInterpreter): def __init__ (self): simpleTAL.TemplateInterpreter.__init__ (self) # Override the standard interpreter way of doing things. self.macroStateStack = [] self.commandHandler [simpleTAL.TAL_DEFINE] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_CONDITION] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_REPEAT] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_CONTENT] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_ATTRIBUTES] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_OMITTAG] = self.cmdNoOp self.commandHandler [simpleTAL.TAL_START_SCOPE] = self.cmdStartScope self.commandHandler [simpleTAL.TAL_OUTPUT] = self.cmdOutput self.commandHandler [simpleTAL.TAL_STARTTAG] = self.cmdOutputStartTag self.commandHandler [simpleTAL.TAL_ENDTAG_ENDSCOPE] = self.cmdEndTagEndScope self.commandHandler [simpleTAL.METAL_USE_MACRO] = self.cmdUseMacro self.commandHandler [simpleTAL.METAL_DEFINE_SLOT] = self.cmdDefineSlot self.commandHandler [simpleTAL.TAL_NOOP] = self.cmdNoOp self.inMacro = None self.macroArg = None # Original cmdOutput # Original cmdEndTagEndScope def popProgram (self): self.inMacro = self.macroStateStack.pop() simpleTAL.TemplateInterpreter.popProgram (self) def pushProgram (self): self.macroStateStack.append (self.inMacro) simpleTAL.TemplateInterpreter.pushProgram (self) def cmdOutputStartTag (self, command, args): newAtts = [] for att, value in list(self.originalAttributes.items()): if (self.macroArg is not None and att == "metal:define-macro"): newAtts.append (("metal:use-macro",self.macroArg)) elif (self.inMacro and att=="metal:define-slot"): newAtts.append (("metal:fill-slot", value)) else: newAtts.append ((att, value)) self.macroArg = None self.currentAttributes = newAtts simpleTAL.TemplateInterpreter.cmdOutputStartTag (self, command, args) def cmdUseMacro (self, command, args): simpleTAL.TemplateInterpreter.cmdUseMacro (self, command, args) if (self.tagContent is not None): # We have a macro, add the args to the in-macro list self.inMacro = 1 self.macroArg = args[0] def cmdEndTagEndScope (self, command, args): # Args: tagName, omitFlag if (self.tagContent is not None): contentType, resultVal = self.tagContent if (contentType): if (isinstance (resultVal, simpleTAL.Template)): # We have another template in the context, evaluate it! # Save our state! self.pushProgram() resultVal.expandInline (self.context, self.file, self) # Restore state self.popProgram() # End of the macro expansion (if any) so clear the parameters self.slotParameters = {} # End of the macro self.inMacro = 0 else: if (isinstance (resultVal, str)): self.file.write (resultVal) elif (isinstance (resultVal, bytes)): self.file.write (str (resultVal, 'ascii')) else: self.file.write (str (str (resultVal), 'ascii')) else: if (isinstance (resultVal, str)): self.file.write (cgi.escape (resultVal)) elif (isinstance (resultVal, bytes)): self.file.write (cgi.escape (str (resultVal, 'ascii'))) else: self.file.write (cgi.escape (str (str (resultVal), 'ascii'))) if (self.outputTag and not args[1]): self.file.write ('') if (self.movePCBack is not None): self.programCounter = self.movePCBack return if (self.localVarsDefined): self.context.popLocals() self.movePCForward,self.movePCBack,self.outputTag,self.originalAttributes,self.currentAttributes,self.repeatVariable,self.tagContent,self.localVarsDefined = self.scopeStack.pop() self.programCounter += 1 def ExpandMacros (context, template, outputEncoding="utf-8"): out = io.StringIO() interp = MacroExpansionInterpreter() interp.initialise (context, out) template.expand (context, out, outputEncoding=outputEncoding, interpreter=interp) return out.getvalue() pygopherd-3.0.1/testdata/000077500000000000000000000000001456676541200153455ustar00rootroot00000000000000pygopherd-3.0.1/testdata/.abstract000066400000000000000000000000601456676541200171450ustar00rootroot00000000000000This is the abstract for the testdata directory.pygopherd-3.0.1/testdata/.cap/000077500000000000000000000000001456676541200161665ustar00rootroot00000000000000pygopherd-3.0.1/testdata/.cap/zzz.txt000066400000000000000000000000361456676541200175630ustar00rootroot00000000000000Name=New Long Cool Name Numb=1pygopherd-3.0.1/testdata/.linkfile000066400000000000000000000001321456676541200171370ustar00rootroot00000000000000Name=Cheese Ball Recipes Numb=2 Type=1 Port=150 Path=1/Moo/Cheesy Host=zippy.micro.umn.edupygopherd-3.0.1/testdata/.queryfile000066400000000000000000000000411456676541200173460ustar00rootroot00000000000000Name=Enter a query Type=7 Path=/ pygopherd-3.0.1/testdata/README000066400000000000000000000002161456676541200162240ustar00rootroot00000000000000This directory contains data for the unit tests. Some tests are dependant upon the precise length of files; those files are added with -kb. pygopherd-3.0.1/testdata/bucktooth/000077500000000000000000000000001456676541200173475ustar00rootroot00000000000000pygopherd-3.0.1/testdata/bucktooth/README000066400000000000000000000002161456676541200202260ustar00rootroot00000000000000This directory contains data for the unit tests. Some tests are dependant upon the precise length of files; those files are added with -kb. pygopherd-3.0.1/testdata/bucktooth/gophermap000066400000000000000000000001431456676541200212520ustar00rootroot00000000000000hello world 1filename 1filename README 1filename selector hostname 1filename selector hostname 69 pygopherd-3.0.1/testdata/demo.crt000066400000000000000000000017211456676541200170040ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICpDCCAYwCCQDzjfBwAuUNqDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls b2NhbGhvc3QwHhcNMjEwMTIzMDM1NzM0WhcNMjEwMjIyMDM1NzM0WjAUMRIwEAYD VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA 8TO7cBA3wYu14mrS8gjAUxdzxPXxzixVuPSNLMZsTKa0Z/Gr6LmV6T6+Ez80VQw4 MfnkPSxj6apudFic4tSIqlNJ7pEk0bq2oKD8YgRui9hV/g2l3ty4uG9KW2lgO9F6 drUevOEzu1NSPIcMngBW6kz+p5elz+NUVJivZiy8ob0WB+ZudxYBCyBW78EktYZQ tg/KrWXvx0wT5ra9ByLIlo4X7c3mAgnH0UNx+GIcFFM8KEJ/ntlPNcW2W4B/XcAO eljvhrDCgUO+VMSJAv3gfSMpXdffLS4zpetIW4RxFZuNjX4Z88c6gtUiFFIsW1J+ hZoa/fHvwXvQ6ENzU7n5AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAL2ZWGjQoz2M SxwG0bA7TcTs20j2UiHDSAdq7zVWiLZCO3tEL7fCxgKCBP9+rz+LtaPFm/SEEyhR HcdPBDpkkvw3mv1Wj7BGsNRlURJ0Q5kMsEXUMPNROFE0x8NPPYk4qVLs2HS8DUH9 N9RKMcbnm7ISOKDfRSlsz0YdR2Vx5UQotSX76sOSh+YxYKNqfb0IduxQHOmFZ0QO ClRXr3eaISJQGcRfOTHduhtCpF+VBflLCX0hzRtUXGGOq9A0K1nYpTqaiwjF2J6+ 793hUyf+UIOQxjXj3vnLzliB118doj4K2HVh/Upyn1BHt5LtWPfyNZzMcm+p/jJM /9QVSsdevUc= -----END CERTIFICATE----- pygopherd-3.0.1/testdata/demo.key000066400000000000000000000032501456676541200170030ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDA8TO7cBA3wYu1 4mrS8gjAUxdzxPXxzixVuPSNLMZsTKa0Z/Gr6LmV6T6+Ez80VQw4MfnkPSxj6apu dFic4tSIqlNJ7pEk0bq2oKD8YgRui9hV/g2l3ty4uG9KW2lgO9F6drUevOEzu1NS PIcMngBW6kz+p5elz+NUVJivZiy8ob0WB+ZudxYBCyBW78EktYZQtg/KrWXvx0wT 5ra9ByLIlo4X7c3mAgnH0UNx+GIcFFM8KEJ/ntlPNcW2W4B/XcAOeljvhrDCgUO+ VMSJAv3gfSMpXdffLS4zpetIW4RxFZuNjX4Z88c6gtUiFFIsW1J+hZoa/fHvwXvQ 6ENzU7n5AgMBAAECggEAWSUYidnVJG3AZ2EdiilZ8cJya4LtP7PKuDCkjTXK1+7y dxgviQYV+TWzT48E/ODurGgq1VGOWPt1S2NmLdZ/7EUGBnq7hQ+B/S9qMjH3ajwi 0Fh5ZdH6mT5d7TUfEt+QgcynEnSieIxsiup8W1AFSCMpP9+fKXVLy4LqqN/Ee8JP zCBywKVQjw6MVgUqzDTOQ8NiEIdkOrSLAYYC2molwS3jhPgEzKZeKBlDfv1vVXKr VyyL5N7fzCLRTw5z9ZgfWDzqbxDZV6hS8aSde4bV+6rpBoG9zPKWpM1AwkYCHjqe Gjenyz43tnQJ+pNJd1XqL+Yild0wmWXzySWKO93mIQKBgQD86gvYhr1NAgBhMQIi OaFO/DqdI7l6Tpa4EgMw15VnBu1pnlYUJFlhMw3FMb7zqfyhgt1kZ6WETm8F6uh4 RH7hN/m2ewjfSMf8rB6lQVI8HUepdhY3faMLK0mehV/gQCruKMjCVCpT7xRnsV1X v2JCIy8Hk4GZ1vI3D6NOSx+s8wKBgQDDS9a6owHxIn2QGlmPWbvdCCzxB5dsL9OH /BBCuw/uYySsMe/W730lLbEzgvj9MxtoUuS2T+KRLE+7hJHH393QbbMAGK63F+ir BQa3mAE68aq3Kz3ZvzYacrfUx8umlxLiPl7biWfChhtvadbM4odJzDgMPTlUl4DE hp5GgrLIYwKBgErkx9M7uyzlrdUaHSajaDgqivTjklY8lXc2pkk9XdmffIhtQdI/ HVSiOK6vV3tyWAQ/622DH8l5LHlVIbgTmHr7B3BZKLxuIgKZuY14NXDlvsXY2SVf h/uTuv49QrH2boAOBb0+DTbDsoguRpTocKFjJ9cXgCZdN2bEs7hImL2vAoGAFpEr 5fMyJUAcDEvPL45p8/ee4ddDux+nrN4Grv9Yru5L7Y3zrf2Mk4A9Krums/N05lA1 149Rmf7p07xU8CjBQ/V5Krivb77WhvSUuyBYfAwy8umPQxsiUFoTPgY8VSq95uDY KzwsfkDq6KvtQ02l3nQ3wcpNVqYPHiaEIZe2uwsCgYEAqLJ/G9qMPyfRYgBhFIew jDKNTVNMCw4fhN+zN7V6CmxCv2UVBjUDyJslddzEOJPQpS7811Ojc5K4dXreLJ7G qql3LV2iJv3ViuWJO1YVSYaKs7WjBvpP1n2IrBvFBg6257GxrgSDwU7GtZkP7rev 9D+aCUpiTqG68RFd9fRIdC0= -----END PRIVATE KEY----- pygopherd-3.0.1/testdata/gopherplus/000077500000000000000000000000001456676541200175355ustar00rootroot00000000000000pygopherd-3.0.1/testdata/gopherplus/README000066400000000000000000000000141456676541200204100ustar00rootroot00000000000000Hello world!pygopherd-3.0.1/testdata/gopherplus/README.3d000066400000000000000000000000401456676541200207140ustar00rootroot00000000000000this is a gopher+ info attributepygopherd-3.0.1/testdata/gopherplus/testfile.txt000066400000000000000000000000271456676541200221140ustar00rootroot00000000000000I am a simple test filepygopherd-3.0.1/testdata/pygopherd/000077500000000000000000000000001456676541200173465ustar00rootroot00000000000000pygopherd-3.0.1/testdata/pygopherd/cgitest.sh000077500000000000000000000001261456676541200213460ustar00rootroot00000000000000#!/bin/bash # Simple script to test CGI environment variables echo "$1 from $REQUEST"pygopherd-3.0.1/testdata/pygopherd/pipetest.sh000077500000000000000000000002611456676541200215410ustar00rootroot00000000000000#!/bin/bash # Simple script to echo back what came in. echo "Starting" read DATALINE while test -n "$DATALINE" ; do echo "Got [$DATALINE]" read DATALINE done echo "Ending" pygopherd-3.0.1/testdata/pygopherd/pipetestdata000066400000000000000000000000221456676541200217520ustar00rootroot00000000000000Word1 Word2 Word3 pygopherd-3.0.1/testdata/pygopherd/searchtest.sh000077500000000000000000000001041456676541200220450ustar00rootroot00000000000000#!/bin/bash echo "Request: $REQUEST" echo "Search: $SEARCHREQUEST" pygopherd-3.0.1/testdata/python-dev.mbox000066400000000000000000000342761456676541200203450ustar00rootroot00000000000000From da@ski.org Wed Jun 5 02:22:16 2019 From: David Ascher To: python-dev@python.org Subject: [Python-Dev] Pickling w/ low overhead Date: Mon, 02 Aug 1999 16:01:26 -0700 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7807071734274799233==" --===============7807071734274799233== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit An issue which has dogged the NumPy project is that there is (to my knowledge) no way to pickle very large arrays without creating strings which contain all of the data. This can be a problem given that NumPy arrays tend to be very large -- often several megabytes, sometimes much bigger. This slows things down, sometimes a lot, depending on the platform. It seems that it should be possible to do something more efficient. Two alternatives come to mind: -- define a new pickling protocol which passes a file-like object to the instance and have the instance write itself to that file, being as efficient or inefficient as it cares to. This protocol is used only if the instance/type defines the appropriate slot. Alternatively, enrich the semantics of the getstate interaction, so that an object can return partial data and tell the pickling mechanism to come back for more. -- make pickling of objects which support the buffer interface use that inteface's notion of segments and use that 'chunk' size to do something more efficient if not necessarily most efficient. (oh, and make NumPy arrays support the buffer interface =). This is simple for NumPy arrays since we want to pickle "everything", but may not be what other buffer-supporting objects want. Thoughts? Alternatives? --david --===============7807071734274799233==-- From mhammond@skippinet.com.au Wed Jun 5 02:22:16 2019 From: Mark Hammond To: python-dev@python.org Subject: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 10:41:23 +1000 Message-ID: <001001bedd48$ea796280$1101a8c0@bobcat> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6301840427696015601==" --===============6301840427696015601== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Hi all, Im trying to slowly wean myself over to the buffer interfaces. My exploration so far indicates that, for most cases, simply replacing "PyString_FromStringAndSize" with "PyBuffer_FromMemory" handles the vast majority of cases, and is preferred when the data contains arbitary bytes. PyArg_ParseTuple("s#", ...) still works correctly as we would hope. However, performing this explicitly is a pain. Looking at getargs.c, the code to achieve this is a little too convoluted to cut-and-paste each time. Therefore, I would like to propose these functions to be added to abstract.c: int PyObject_GetBufferSize(); void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ const void *PyObject_GetReadOnlyBuffer(); Although equivalent functions exist for the buffer object, I can't see the equivalent abstract implementations - ie, that work with any object supporting the protocol. Im willing to provide a patch if there is agreement a) the general idea is good, and b) my specific spelling of the idea is OK (less likely - PyBuffer_* seems better, but loses any implication of being abstract?). Thoughts? Mark. --===============6301840427696015601==-- From gstein@lyra.org Wed Jun 5 02:22:16 2019 From: Greg Stein To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Mon, 02 Aug 1999 18:51:43 -0700 Message-ID: <37A64B2F.3386F0A9@lyra.org> In-Reply-To: <001001bedd48$ea796280$1101a8c0@bobcat> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3766712876154848986==" --===============3766712876154848986== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Mark Hammond wrote: > ... > Therefore, I would like to propose these functions to be added to > abstract.c: > > int PyObject_GetBufferSize(); > void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ > const void *PyObject_GetReadOnlyBuffer(); > > Although equivalent functions exist for the buffer object, I can't see the > equivalent abstract implementations - ie, that work with any object > supporting the protocol. > > Im willing to provide a patch if there is agreement a) the general idea is > good, and b) my specific spelling of the idea is OK (less likely - > PyBuffer_* seems better, but loses any implication of being abstract?). Marc-Andre proposed exactly the same thing back at the end of March (to me and Guido). The two of us hashed out some of the stuff and M.A. came up with a full patch for the stuff. Guido was relatively non-committal at the point one way or another, but said they seemed fine. It appears the stuff never made it into source control. If Marc-Andre can resurface the final proposal/patch, then we'd be set. Until then: use the bufferprocs :-) Cheers, -g -- Greg Stein, http://www.lyra.org/ --===============3766712876154848986==-- From mal@lemburg.com Wed Jun 5 02:22:16 2019 From: "M.-A. Lemburg" To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 09:50:33 +0200 Message-ID: <37A69F49.3575AE85@lemburg.com> In-Reply-To: <37A64B2F.3386F0A9@lyra.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3450783038406365800==" --===============3450783038406365800== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Greg Stein wrote: > > Mark Hammond wrote: > > ... > > Therefore, I would like to propose these functions to be added to > > abstract.c: > > > > int PyObject_GetBufferSize(); > > void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ > > const void *PyObject_GetReadOnlyBuffer(); > > > > Although equivalent functions exist for the buffer object, I can't see the > > equivalent abstract implementations - ie, that work with any object > > supporting the protocol. > > > > Im willing to provide a patch if there is agreement a) the general idea is > > good, and b) my specific spelling of the idea is OK (less likely - > > PyBuffer_* seems better, but loses any implication of being abstract?). > > Marc-Andre proposed exactly the same thing back at the end of March (to > me and Guido). The two of us hashed out some of the stuff and M.A. came > up with a full patch for the stuff. Guido was relatively non-committal > at the point one way or another, but said they seemed fine. It appears > the stuff never made it into source control. > > If Marc-Andre can resurface the final proposal/patch, then we'd be set. Below is the code I currently use. I don't really remember if this is what Greg and I discussed a while back, but I'm sure he'll correct me ;-) Note that you the buffer length is implicitly returned by these APIs. /* Takes an arbitrary object which must support the character (single segment) buffer interface and returns a pointer to a read-only memory location useable as character based input for subsequent processing. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; const char *pp; int len; if ( pb == NULL || pb->bf_getcharbuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a character buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getcharbuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } /* Same as PyObject_AsCharBuffer() except that this API expects a readable (single segment) buffer interface and returns a pointer to a read-only memory location which can contain arbitrary data. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; void *pp; int len; if ( pb == NULL || pb->bf_getreadbuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a readable buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getreadbuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } /* Takes an arbitrary object which must support the writeable (single segment) buffer interface and returns a pointer to a writeable memory location in buffer of size buffer_len. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; void*pp; int len; if ( pb == NULL || pb->bf_getwritebuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a writeable buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getwritebuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: 150 days left Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --===============3450783038406365800==-- From mal@lemburg.com Wed Jun 5 02:22:16 2019 From: "M.-A. Lemburg" To: python-dev@python.org Subject: Re: [Python-Dev] Pickling w/ low overhead Date: Tue, 03 Aug 1999 11:11:11 +0200 Message-ID: <37A6B22F.7A14BA2C@lemburg.com> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1771830407250585468==" --===============1771830407250585468== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit David Ascher wrote: > > An issue which has dogged the NumPy project is that there is (to my > knowledge) no way to pickle very large arrays without creating strings > which contain all of the data. This can be a problem given that NumPy > arrays tend to be very large -- often several megabytes, sometimes much > bigger. This slows things down, sometimes a lot, depending on the > platform. It seems that it should be possible to do something more > efficient. > > Two alternatives come to mind: > > -- define a new pickling protocol which passes a file-like object to the > instance and have the instance write itself to that file, being as > efficient or inefficient as it cares to. This protocol is used only > if the instance/type defines the appropriate slot. Alternatively, > enrich the semantics of the getstate interaction, so that an object > can return partial data and tell the pickling mechanism to come back > for more. > > -- make pickling of objects which support the buffer interface use that > inteface's notion of segments and use that 'chunk' size to do > something more efficient if not necessarily most efficient. (oh, and > make NumPy arrays support the buffer interface =). This is simple > for NumPy arrays since we want to pickle "everything", but may not be > what other buffer-supporting objects want. > > Thoughts? Alternatives? Hmm, types can register their own pickling/unpickling functions via copy_reg, so they can access the self.write method in pickle.py to implement the write to file interface. Don't know how this would be done for cPickle.c though. For instances the situation is different since there is no dispatching done on a per-class basis. I guess an optional argument could help here. Perhaps some lazy pickling wrapper would help fix this in general: an object which calls back into the to-be-pickled object to access the data rather than store the data in a huge string. Yet another idea would be using memory mapped files instead of strings as temporary storage (but this is probably hard to implement right and not as portable). Dunno... just some thoughts. -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: 150 days left Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --===============1771830407250585468==-- From jack@oratrix.nl Wed Jun 5 02:22:16 2019 From: Jack Jansen To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 11:53:39 +0200 Message-ID: <19990803095339.E02CE303120@snelboot.oratrix.nl> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6337740323128302028==" --===============6337740323128302028== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Why not pass the index to the As*Buffer routines as well and make getsegcount available too? Then you could code things like for(i=0; i To: python-dev@python.org Subject: [Python-Dev] Pickling w/ low overhead Date: Mon, 02 Aug 1999 16:01:26 -0700 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7807071734274799233==" --===============7807071734274799233== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit An issue which has dogged the NumPy project is that there is (to my knowledge) no way to pickle very large arrays without creating strings which contain all of the data. This can be a problem given that NumPy arrays tend to be very large -- often several megabytes, sometimes much bigger. This slows things down, sometimes a lot, depending on the platform. It seems that it should be possible to do something more efficient. Two alternatives come to mind: -- define a new pickling protocol which passes a file-like object to the instance and have the instance write itself to that file, being as efficient or inefficient as it cares to. This protocol is used only if the instance/type defines the appropriate slot. Alternatively, enrich the semantics of the getstate interaction, so that an object can return partial data and tell the pickling mechanism to come back for more. -- make pickling of objects which support the buffer interface use that inteface's notion of segments and use that 'chunk' size to do something more efficient if not necessarily most efficient. (oh, and make NumPy arrays support the buffer interface =). This is simple for NumPy arrays since we want to pickle "everything", but may not be what other buffer-supporting objects want. Thoughts? Alternatives? --david --===============7807071734274799233==-- pygopherd-3.0.1/testdata/python-dev/cur/1606884253.000001.mbox:2,000066400000000000000000000030751456676541200231700ustar00rootroot00000000000000From: Mark Hammond To: python-dev@python.org Subject: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 10:41:23 +1000 Message-ID: <001001bedd48$ea796280$1101a8c0@bobcat> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6301840427696015601==" --===============6301840427696015601== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Hi all, Im trying to slowly wean myself over to the buffer interfaces. My exploration so far indicates that, for most cases, simply replacing "PyString_FromStringAndSize" with "PyBuffer_FromMemory" handles the vast majority of cases, and is preferred when the data contains arbitary bytes. PyArg_ParseTuple("s#", ...) still works correctly as we would hope. However, performing this explicitly is a pain. Looking at getargs.c, the code to achieve this is a little too convoluted to cut-and-paste each time. Therefore, I would like to propose these functions to be added to abstract.c: int PyObject_GetBufferSize(); void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ const void *PyObject_GetReadOnlyBuffer(); Although equivalent functions exist for the buffer object, I can't see the equivalent abstract implementations - ie, that work with any object supporting the protocol. Im willing to provide a patch if there is agreement a) the general idea is good, and b) my specific spelling of the idea is OK (less likely - PyBuffer_* seems better, but loses any implication of being abstract?). Thoughts? Mark. --===============6301840427696015601==-- pygopherd-3.0.1/testdata/python-dev/cur/1606884253.000002.mbox:2,000066400000000000000000000031551456676541200231700ustar00rootroot00000000000000From: Greg Stein To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Mon, 02 Aug 1999 18:51:43 -0700 Message-ID: <37A64B2F.3386F0A9@lyra.org> In-Reply-To: <001001bedd48$ea796280$1101a8c0@bobcat> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3766712876154848986==" --===============3766712876154848986== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Mark Hammond wrote: > ... > Therefore, I would like to propose these functions to be added to > abstract.c: > > int PyObject_GetBufferSize(); > void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ > const void *PyObject_GetReadOnlyBuffer(); > > Although equivalent functions exist for the buffer object, I can't see the > equivalent abstract implementations - ie, that work with any object > supporting the protocol. > > Im willing to provide a patch if there is agreement a) the general idea is > good, and b) my specific spelling of the idea is OK (less likely - > PyBuffer_* seems better, but loses any implication of being abstract?). Marc-Andre proposed exactly the same thing back at the end of March (to me and Guido). The two of us hashed out some of the stuff and M.A. came up with a full patch for the stuff. Guido was relatively non-committal at the point one way or another, but said they seemed fine. It appears the stuff never made it into source control. If Marc-Andre can resurface the final proposal/patch, then we'd be set. Until then: use the bufferprocs :-) Cheers, -g -- Greg Stein, http://www.lyra.org/ --===============3766712876154848986==-- pygopherd-3.0.1/testdata/python-dev/cur/1606884253.000003.mbox:2,000066400000000000000000000120441456676541200231660ustar00rootroot00000000000000From: "M.-A. Lemburg" To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 09:50:33 +0200 Message-ID: <37A69F49.3575AE85@lemburg.com> In-Reply-To: <37A64B2F.3386F0A9@lyra.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3450783038406365800==" --===============3450783038406365800== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Greg Stein wrote: > > Mark Hammond wrote: > > ... > > Therefore, I would like to propose these functions to be added to > > abstract.c: > > > > int PyObject_GetBufferSize(); > > void *PyObject_GetReadWriteBuffer(); /* or "char *"? */ > > const void *PyObject_GetReadOnlyBuffer(); > > > > Although equivalent functions exist for the buffer object, I can't see the > > equivalent abstract implementations - ie, that work with any object > > supporting the protocol. > > > > Im willing to provide a patch if there is agreement a) the general idea is > > good, and b) my specific spelling of the idea is OK (less likely - > > PyBuffer_* seems better, but loses any implication of being abstract?). > > Marc-Andre proposed exactly the same thing back at the end of March (to > me and Guido). The two of us hashed out some of the stuff and M.A. came > up with a full patch for the stuff. Guido was relatively non-committal > at the point one way or another, but said they seemed fine. It appears > the stuff never made it into source control. > > If Marc-Andre can resurface the final proposal/patch, then we'd be set. Below is the code I currently use. I don't really remember if this is what Greg and I discussed a while back, but I'm sure he'll correct me ;-) Note that you the buffer length is implicitly returned by these APIs. /* Takes an arbitrary object which must support the character (single segment) buffer interface and returns a pointer to a read-only memory location useable as character based input for subsequent processing. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; const char *pp; int len; if ( pb == NULL || pb->bf_getcharbuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a character buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getcharbuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } /* Same as PyObject_AsCharBuffer() except that this API expects a readable (single segment) buffer interface and returns a pointer to a read-only memory location which can contain arbitrary data. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; void *pp; int len; if ( pb == NULL || pb->bf_getreadbuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a readable buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getreadbuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } /* Takes an arbitrary object which must support the writeable (single segment) buffer interface and returns a pointer to a writeable memory location in buffer of size buffer_len. buffer and buffer_len are only set in case no error occurrs. Otherwise, -1 is returned and an exception set. */ static int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, int *buffer_len) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; void*pp; int len; if ( pb == NULL || pb->bf_getwritebuffer == NULL || pb->bf_getsegcount == NULL ) { PyErr_SetString(PyExc_TypeError, "expected a writeable buffer object"); goto onError; } if ( (*pb->bf_getsegcount)(obj,NULL) != 1 ) { PyErr_SetString(PyExc_TypeError, "expected a single-segment buffer object"); goto onError; } len = (*pb->bf_getwritebuffer)(obj,0,&pp); if (len < 0) goto onError; *buffer = pp; *buffer_len = len; return 0; onError: return -1; } -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: 150 days left Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --===============3450783038406365800==-- pygopherd-3.0.1/testdata/python-dev/cur/1606884253.000004.mbox:2,000066400000000000000000000057001456676541200231700ustar00rootroot00000000000000From: "M.-A. Lemburg" To: python-dev@python.org Subject: Re: [Python-Dev] Pickling w/ low overhead Date: Tue, 03 Aug 1999 11:11:11 +0200 Message-ID: <37A6B22F.7A14BA2C@lemburg.com> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1771830407250585468==" --===============1771830407250585468== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit David Ascher wrote: > > An issue which has dogged the NumPy project is that there is (to my > knowledge) no way to pickle very large arrays without creating strings > which contain all of the data. This can be a problem given that NumPy > arrays tend to be very large -- often several megabytes, sometimes much > bigger. This slows things down, sometimes a lot, depending on the > platform. It seems that it should be possible to do something more > efficient. > > Two alternatives come to mind: > > -- define a new pickling protocol which passes a file-like object to the > instance and have the instance write itself to that file, being as > efficient or inefficient as it cares to. This protocol is used only > if the instance/type defines the appropriate slot. Alternatively, > enrich the semantics of the getstate interaction, so that an object > can return partial data and tell the pickling mechanism to come back > for more. > > -- make pickling of objects which support the buffer interface use that > inteface's notion of segments and use that 'chunk' size to do > something more efficient if not necessarily most efficient. (oh, and > make NumPy arrays support the buffer interface =). This is simple > for NumPy arrays since we want to pickle "everything", but may not be > what other buffer-supporting objects want. > > Thoughts? Alternatives? Hmm, types can register their own pickling/unpickling functions via copy_reg, so they can access the self.write method in pickle.py to implement the write to file interface. Don't know how this would be done for cPickle.c though. For instances the situation is different since there is no dispatching done on a per-class basis. I guess an optional argument could help here. Perhaps some lazy pickling wrapper would help fix this in general: an object which calls back into the to-be-pickled object to access the data rather than store the data in a huge string. Yet another idea would be using memory mapped files instead of strings as temporary storage (but this is probably hard to implement right and not as portable). Dunno... just some thoughts. -- Marc-Andre Lemburg ______________________________________________________________________ Y2000: 150 days left Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --===============1771830407250585468==-- pygopherd-3.0.1/testdata/python-dev/cur/1606884253.000005.mbox:2,000066400000000000000000000017711456676541200231750ustar00rootroot00000000000000From: Jack Jansen To: python-dev@python.org Subject: Re: [Python-Dev] Buffer interface in abstract.c? Date: Tue, 03 Aug 1999 11:53:39 +0200 Message-ID: <19990803095339.E02CE303120@snelboot.oratrix.nl> In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6337740323128302028==" --===============6337740323128302028== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Why not pass the index to the As*Buffer routines as well and make getsegcount available too? Then you could code things like for(i=0; i To: python-dev@python.org Subject: [Python-Dev] Pickling w/ low overhead Date: Mon, 02 Aug 1999 16:01:26 -0700 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7807071734274799233==" --===============7807071734274799233== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit An issue which has dogged the NumPy project is that there is (to my knowledge) no way to pickle very large arrays without creating strings which contain all of the data. This can be a problem given that NumPy arrays tend to be very large -- often several megabytes, sometimes much bigger. This slows things down, sometimes a lot, depending on the platform. It seems that it should be possible to do something more efficient. Two alternatives come to mind: -- define a new pickling protocol which passes a file-like object to the instance and have the instance write itself to that file, being as efficient or inefficient as it cares to. This protocol is used only if the instance/type defines the appropriate slot. Alternatively, enrich the semantics of the getstate interaction, so that an object can return partial data and tell the pickling mechanism to come back for more. -- make pickling of objects which support the buffer interface use that inteface's notion of segments and use that 'chunk' size to do something more efficient if not necessarily most efficient. (oh, and make NumPy arrays support the buffer interface =). This is simple for NumPy arrays since we want to pickle "everything", but may not be what other buffer-supporting objects want. Thoughts? Alternatives? --david --===============7807071734274799233==-- pygopherd-3.0.1/testdata/python-dev/tmp/000077500000000000000000000000001456676541200202425ustar00rootroot00000000000000pygopherd-3.0.1/testdata/python-dev/tmp/1606884253.000000.mbox:2,000066400000000000000000000034361456676541200231770ustar00rootroot00000000000000From: David Ascher To: python-dev@python.org Subject: [Python-Dev] Pickling w/ low overhead Date: Mon, 02 Aug 1999 16:01:26 -0700 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============7807071734274799233==" --===============7807071734274799233== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit An issue which has dogged the NumPy project is that there is (to my knowledge) no way to pickle very large arrays without creating strings which contain all of the data. This can be a problem given that NumPy arrays tend to be very large -- often several megabytes, sometimes much bigger. This slows things down, sometimes a lot, depending on the platform. It seems that it should be possible to do something more efficient. Two alternatives come to mind: -- define a new pickling protocol which passes a file-like object to the instance and have the instance write itself to that file, being as efficient or inefficient as it cares to. This protocol is used only if the instance/type defines the appropriate slot. Alternatively, enrich the semantics of the getstate interaction, so that an object can return partial data and tell the pickling mechanism to come back for more. -- make pickling of objects which support the buffer interface use that inteface's notion of segments and use that 'chunk' size to do something more efficient if not necessarily most efficient. (oh, and make NumPy arrays support the buffer interface =). This is simple for NumPy arrays since we want to pickle "everything", but may not be what other buffer-supporting objects want. Thoughts? Alternatives? --david --===============7807071734274799233==-- pygopherd-3.0.1/testdata/symlinktest.zip000066400000000000000000000031261456676541200204610ustar00rootroot00000000000000PK xf./2(n linked.txtUT Sg>Sg>Uxreal.txtPK xf.- linktosubdirUT Sg>Sg>UxsubdirPK »e.<real.txtUT f>f>UxTest. PK xf.subdir/UT hg>f>UxPK xf.K subdir/linkedabs.txtUT hg>hg>Ux/real.txtPK xf.j subdir/linkedrel.txtUT Sg>Sg>Ux../real.txtPK xf.]subdir/linked2.txtUT Sg>Sg>Ux../subdir2/real2.txtPK xf.8z subdir/linktosubdir2UT Sg>Sg>Ux../subdir2PK xf.Bsubdir/linktoselfUT Sg>Sg>Ux.PK ֻe.subdir2/UT f>f>UxPK ֻe.QVsubdir2/real2.txtUT f>f>Uxasdf PK xf./2(n linked.txtUTSg>UxPK xf.- ElinktosubdirUTSg>UxPK »e.< real.txtUTf>UxPK xf. Asubdir/UThg>UxPK xf.K  subdir/linkedabs.txtUThg>UxPK xf.j  Usubdir/linkedrel.txtUTSg>UxPK xf.] subdir/linked2.txtUTSg>UxPK xf.8z  subdir/linktosubdir2UTSg>UxPK xf.B Qsubdir/linktoselfUTSg>UxPK ֻe. Asubdir2/UTf>UxPK ֻe.QV subdir2/real2.txtUTf>UxPK &pygopherd-3.0.1/testdata/talsample.html.tal000066400000000000000000000011641456676541200207760ustar00rootroot00000000000000 TAL Test My selector is: selector
My MIME type is: foo/bar
Another way of getting that is: foo/bar
Gopher type is: X
My handler is: handlername
My protocol is: protocol
Python path enabling status: 123
My vfs is: vfs
Math: 5 pygopherd-3.0.1/testdata/testarchive.tar000066400000000000000000000240001456676541200203720ustar00rootroot00000000000000testfile.txt0100644000175000017500000000000507455345341013674 0ustar jgoerzenjgoerzenTest pygopherd-3.0.1/testdata/testarchive.tar.gz000066400000000000000000000002061456676541200210130ustar00rootroot00000000000000Ե<1 ADю=Ŝ@j؞xqQDaN``"F QAUі8mQFwk}) ޓ~[mki_]k!&H(pygopherd-3.0.1/testdata/testarchive.tgz000066400000000000000000000002061456676541200204120ustar00rootroot00000000000000Ե<1 ADю=Ŝ@j؞xqQDaN``"F QAUі8mQFwk}) ޓ~[mki_]k!&H(pygopherd-3.0.1/testdata/testdata.zip000066400000000000000000000046601456676541200177100ustar00rootroot00000000000000PKiU.kREADMEUT IyV>IyV>Ux%0 5@HЀd!H[>CP} 0 ̘K)W@CŘ,ptM`{DWTez~Bxk.{~PKiU.-0 .abstractUT IyV>IyV>Ux ,VTĤ⒢"@IjqIJbIBJfQjrI~QPKiU.9pygopherd/pipetest.shUT JyV>JyV>UxUͻ @F~wbyAX w̆@^/`9ժv,% 3fD2L*#X,@QYdhͥ9ϭE B6xwhN?V2zPKiU.pygopherd/pipetestdataUT JyV>JyV>Ux /J1 F`Ҙ PKiU.!&Ht(testarchive.tarUT IyV>IyV>Ux1 ADю=Ŝ@j؞xqQDaN``"F QAUі8mQFwk}) ޓ~[mki_]kPKiU.mtestarchive.tar.gzUT IyV>IyV>Ux`xze ۋ\L.lqȺ1onwcsaKv֏_ܸ^p vq\O}wWKyM]':z߃L,{OƯ ̢vÃAPKiU.mtestarchive.tgzUT IyV>IyV>Ux`xze ۋ\L.lqȺ1onwcsaKv֏_ܸ^p vq\O}wWKyM]':z߃L,{OƯ ̢vÃAPK iU.x testfile.txtUT IyV>IyV>UxTest PK iU.hwtestfile.txt.gzUT IyV>IyV>UxԵ< I-.xPK iU.gY))testfile.txt.gz.abstractUT IyV>IyV>UxThis is the abstract for testfile.txt.gz PK tf>UxZIPonly PK #/RN .txtUT  ` `ux Hello, !PKiU.k READMEUTIyV>UxPKiU.-0 .abstractUTIyV>UxPKiU.9  pygopherd/pipetest.shUTJyV>UxPKiU. pygopherd/pipetestdataUTJyV>UxPKiU.!&Ht( .testarchive.tarUTIyV>UxPKiU.m testarchive.tar.gzUTIyV>UxPKiU.m testarchive.tgzUTIyV>UxPK iU.x qtestfile.txtUTIyV>UxPK iU.hw testfile.txt.gzUTIyV>UxPK iU.gY)) testfile.txt.gz.abstractUTIyV>UxPK UxPK #/RN .txtUT `ux PK pygopherd-3.0.1/testdata/testdata2.zip000066400000000000000000000044071456676541200177710ustar00rootroot00000000000000PKiU.-0 .abstractUT IyV>IyV>Ux ,VTĤ⒢"@IjqIJbIBJfQjrI~QPKiU.kREADMEUT IyV>IyV>Ux%0 5@HЀd!H[>CP} 0 ̘K)W@CŘ,ptM`{DWTez~Bxk.{~PK xe. pygopherd/UT jff>eff>UxPKxe.pygopherd/pipetestdataUT eff>eff>Ux /J1 F`Ҙ PKxe.9pygopherd/pipetest.shUT eff>eff>UxUͻ @F~wbyAX w̆@^/`9ժv,% 3fD2L*#X,@QYdhͥ9ϭE B6xwhN?V2zPKiU.!&Ht(testarchive.tarUT IyV>IyV>Ux1 ADю=Ŝ@j؞xqQDaN``"F QAUі8mQFwk}) ޓ~[mki_]kPKiU.mtestarchive.tar.gzUT IyV>IyV>Ux`xze ۋ\L.lqȺ1onwcsaKv֏_ܸ^p vq\O}wWKyM]':z߃L,{OƯ ̢vÃAPKiU.mtestarchive.tgzUT IyV>IyV>Ux`xze ۋ\L.lqȺ1onwcsaKv֏_ܸ^p vq\O}wWKyM]':z߃L,{OƯ ̢vÃAPK iU.x testfile.txtUT IyV>IyV>UxTest PK iU.hwtestfile.txt.gzUT IyV>IyV>UxԵ< I-.xPK iU.gY))testfile.txt.gz.abstractUT IyV>IyV>UxThis is the abstract for testfile.txt.gz PKiU.-0 .abstractUTIyV>UxPKiU.k iREADMEUTIyV>UxPK xe. A pygopherd/UTjff>UxPKxe. Jpygopherd/pipetestdataUTeff>UxPKxe.9 큢pygopherd/pipetest.shUTeff>UxPKiU.!&Ht( ktestarchive.tarUTIyV>UxPKiU.m !testarchive.tar.gzUTIyV>UxPKiU.m testarchive.tgzUTIyV>UxPK iU.x testfile.txtUTIyV>UxPK iU.hw testfile.txt.gzUTIyV>UxPK iU.gY)) Mtestfile.txt.gz.abstractUTIyV>UxPK 0pygopherd-3.0.1/testdata/testfile.gmi000066400000000000000000000000661456676541200176640ustar00rootroot00000000000000Hello world! => / root directory => gemini://mozz.us pygopherd-3.0.1/testdata/testfile.html000066400000000000000000000001751456676541200200550ustar00rootroot00000000000000 <Gopher Rocks>

Hello World!

`pygopherd-3.0.1/testdata/testfile.pyg000077500000000000000000000007601456676541200177130ustar00rootroot00000000000000from pygopherd.handlers.pyg import PYGBase from pygopherd.gopherentry import GopherEntry class PYGMain(PYGBase): def canhandlerequest(self): return True def isdir(self): return False def getentry(self): entry = GopherEntry(self.selector, self.config) entry.type = "0" entry.mimetype = "text/plain" entry.name = "My custom .pyg handler!" return entry def write(self, wfile): wfile.write("hello world!".encode()) pygopherd-3.0.1/testdata/testfile.txt000066400000000000000000000000051456676541200177200ustar00rootroot00000000000000Test pygopherd-3.0.1/testdata/testfile.txt.gz000066400000000000000000000000311456676541200203360ustar00rootroot00000000000000Ե< I-.xpygopherd-3.0.1/testdata/testfile.txt.gz.abstract000066400000000000000000000000511456676541200221420ustar00rootroot00000000000000This is the abstract for testfile.txt.gz pygopherd-3.0.1/testdata/ziptorture.zip000066400000000000000000000027351456676541200203270ustar00rootroot00000000000000PK 1e.UMN/UT f>f>UxPK e.^ UMN/test.txtUT f>f>UxThis is a test file. PK e. UMN/.cap/UT f>f>UxPK e.} HUMN/.cap/test.txtUT f>f>UxName=Test File PKe.r+78 UMN/.LinksUT "f>"f>Ux H,ɰ/.-,-/JKM |2Jl B* Rm PK e.buck/UT cf>'f>UxPK Ѱe. buck/test.txtUT If>If>UxFoo PKe.i03buck/gophermapUT cf>cf>Ux3I-.QpI,J*J KK+99 2R A"@s.PK ʰe.&h,&test.gophermapUT ;f>;f>Ux0Test File test.txt PK ˰e.test.txtUT >f>>f>UxFoo PK 1e. AUMN/UTf>UxPK e.^ 7UMN/test.txtUTf>UxPK e. AUMN/.cap/UTf>UxPK e.} H UMN/.cap/test.txtUTf>UxPKe.r+78 UMN/.LinksUT"f>UxPK e. Abuck/UTcf>UxPK Ѱe. buck/test.txtUTIf>UxPKe.i03  buck/gophermapUTcf>UxPK ʰe.&h,& {test.gophermapUT;f>UxPK ˰e. test.txtUT>f>UxPK pygopherd-3.0.1/testdata/zzz.txt000066400000000000000000000000001456676541200167310ustar00rootroot00000000000000pygopherd-3.0.1/tests/000077500000000000000000000000001456676541200146765ustar00rootroot00000000000000pygopherd-3.0.1/tests/handlers/000077500000000000000000000000001456676541200164765ustar00rootroot00000000000000pygopherd-3.0.1/tests/handlers/__init__.py000066400000000000000000000000001456676541200205750ustar00rootroot00000000000000pygopherd-3.0.1/tests/handlers/test_dir.py000066400000000000000000000033621456676541200206710ustar00rootroot00000000000000import os import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.dir import DirHandler class TestDirHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) # Make sure there's no directory cache file from a previous test run cachefile = self.config.get("handlers.dir.DirHandler", "cachefile") try: os.remove(self.vfs.getfspath(self.selector) + "/" + cachefile) except OSError: pass def test_dir_handler(self): handler = DirHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertTrue(handler.isdir()) handler.prepare() self.assertFalse(handler.fromcache) entry = handler.getentry() self.assertEqual(entry.mimetype, "application/gopher-menu") self.assertEqual(entry.type, "1") entries = handler.getdirlist() self.assertTrue(entries) # Create a second handler to test that it will load from the cached # file that the first handler should have created handler = DirHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) handler.prepare() self.assertTrue(handler.fromcache) cached_entries = handler.getdirlist() for a, b in zip(entries, cached_entries): self.assertEqual(a.selector, b.selector) pygopherd-3.0.1/tests/handlers/test_file.py000066400000000000000000000054761456676541200210420ustar00rootroot00000000000000import io import tempfile import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.file import CompressedFileHandler, FileHandler class TestFileHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/testfile.txt" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) def test_file_handler(self): handler = FileHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.type, "0") wfile = io.BytesIO() handler.write(wfile) data = wfile.getvalue().decode() self.assertEqual(data, "Test\n") @unittest.skipUnless( testutil.supports_non_utf8_filenames(), reason="Filesystem does not support non-utf8 filenames.", ) def test_file_handler_non_utf8(self): self.selector = b"/\xAE.txt".decode(errors="surrogateescape") handler = FileHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.type, "0") wfile = io.BytesIO() handler.write(wfile) data = wfile.getvalue() self.assertEqual(data, b"Hello, \xAE!") class TestCompressedFileHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/testfile.txt.gz" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) self.config.set( "handlers.file.CompressedFileHandler", "decompressors", "{'gzip' : 'zcat'}" ) def test_compressed_file_handler(self): handler = CompressedFileHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.type, "0") with tempfile.TemporaryFile("rb") as wfile: handler.write(wfile) wfile.seek(0) data = wfile.read() self.assertEqual(data, b"Test\n") pygopherd-3.0.1/tests/handlers/test_gophermap.py000066400000000000000000000032531456676541200220740ustar00rootroot00000000000000import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.gophermap import BuckGophermapHandler class TestBuckGophermapHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/bucktooth" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) def test_buck_gophermap_handler(self): handler = BuckGophermapHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertTrue(handler.isdir()) handler.prepare() entry = handler.getentry() self.assertEqual(entry.mimetype, "application/gopher-menu") self.assertEqual(entry.type, "1") entries = handler.getdirlist() self.assertTrue(entries) expected = [ ("i", "hello world", "fake", "(NULL)", 0), ("1", "filename", "/bucktooth/filename", None, None), ("1", "filename", "/bucktooth/README", None, None), ("1", "filename", "/bucktooth/selector", "hostname", None), ("1", "filename", "/bucktooth/selector", "hostname", 69), ] for i, entry in enumerate(entries): self.assertEqual(entry.type, expected[i][0]) self.assertEqual(entry.name, expected[i][1]) self.assertEqual(entry.selector, expected[i][2]) self.assertEqual(entry.host, expected[i][3]) self.assertEqual(entry.port, expected[i][4]) pygopherd-3.0.1/tests/handlers/test_html.py000066400000000000000000000014431456676541200210550ustar00rootroot00000000000000import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.html import HTMLFileTitleHandler class TestHTMLHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/testfile.html" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) def test_html_handler(self): handler = HTMLFileTitleHandler( "/testfile.html", "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) entry = handler.getentry() self.assertEqual(entry.name, "") pygopherd-3.0.1/tests/handlers/test_mbox.py000066400000000000000000000105021456676541200210520ustar00rootroot00000000000000import io import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.mbox import ( MaildirFolderHandler, MaildirMessageHandler, MBoxFolderHandler, MBoxMessageHandler, ) class TestMBoxHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/python-dev.mbox" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) def test_mbox_folder_handler(self): handler = MBoxFolderHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) handler.prepare() self.assertTrue(handler.canhandlerequest()) self.assertTrue(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "application/gopher-menu") self.assertEqual(entry.type, "1") messages = handler.getdirlist() self.assertTrue(len(messages), 6) self.assertEqual(messages[0].selector, "/python-dev.mbox|/MBOX-MESSAGE/1") self.assertEqual(messages[0].name, "[Python-Dev] Pickling w/ low overhead") def test_mbox_message_handler(self): """ Load the third message from the mbox. """ handler = MBoxMessageHandler( "/python-dev.mbox|/MBOX-MESSAGE/3", "", self.protocol, self.config, self.stat_result, self.vfs, ) handler.prepare() self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.name, "Re: [Python-Dev] Buffer interface in abstract.c?") self.assertEqual(entry.type, "0") wfile = io.BytesIO() handler.write(wfile) email_text = wfile.getvalue() assert email_text.startswith(b"From: Greg Stein ") class TestMaildirHandler(unittest.TestCase): """ The maildir test data was generated from a mailbox file using this script: http://batleth.sapienti-sat.org/projects/mb2md/ Important Note: The python implementation uses os.listdir() under the hood to iterate over the mail files in the directory. The order of files returned is deterministic but is *not* sorted by filename. This means that mail files in the generated gopher directory listing may appear out of order from their "true" ordering in the mail archive. It also makes writing this test a pain in the ass. """ def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/python-dev" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) def test_maildir_folder_handler(self): handler = MaildirFolderHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) handler.prepare() self.assertTrue(handler.canhandlerequest()) self.assertTrue(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "application/gopher-menu") self.assertEqual(entry.type, "1") messages = handler.getdirlist() self.assertTrue(len(messages), 6) self.assertEqual(messages[0].selector, "/python-dev|/MAILDIR-MESSAGE/1") self.assertIn("[Python-Dev]", messages[0].name) def test_maildir_message_handler(self): """ Load the third message from the maildir. """ handler = MaildirMessageHandler( "/python-dev|/MAILDIR-MESSAGE/3", "", self.protocol, self.config, self.stat_result, self.vfs, ) handler.prepare() self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.type, "0") wfile = io.BytesIO() handler.write(wfile) email_text = wfile.getvalue() assert email_text.startswith(b"From:") pygopherd-3.0.1/tests/handlers/test_pyg.py000066400000000000000000000016701456676541200207120ustar00rootroot00000000000000import io import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.pyg import PYGHandler class TestPYGHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/testfile.pyg" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat("/testfile.pyg") def test_pyg_handler(self): handler = PYGHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertFalse(handler.isdir()) entry = handler.getentry() self.assertEqual(entry.selector, "/testfile.pyg") wfile = io.BytesIO() handler.write(wfile) self.assertEqual(wfile.getvalue(), b"hello world!") pygopherd-3.0.1/tests/handlers/test_script_exec.py000066400000000000000000000025431456676541200224230ustar00rootroot00000000000000import tempfile import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.scriptexec import ExecHandler class TestExecHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) # The "hello" will be sent as an additional script argument. Multiple # query arguments can be provided using " " as the separator. self.selector = "/pygopherd/cgitest.sh?hello" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = None def test_exec_handler(self): handler = ExecHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.isrequestforme()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/plain") self.assertEqual(entry.type, "0") self.assertEqual(entry.name, "cgitest.sh") self.assertEqual(entry.selector, "/pygopherd/cgitest.sh") # The test script will print $REQUEST and exit with tempfile.TemporaryFile(mode="w+") as wfile: handler.write(wfile) wfile.seek(0) output = wfile.read() self.assertEqual(output, "hello from /pygopherd/cgitest.sh\n") pygopherd-3.0.1/tests/handlers/test_tal.py000066400000000000000000000037001456676541200206670ustar00rootroot00000000000000from __future__ import annotations import html import io import unittest from pygopherd import initialization, testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.tal import TALFileHandler, talavailable TEST_TEMPLATE = """ TAL Test My selector is: {selector}
My MIME type is: text/html
Another way of getting that is: text/html
Gopher type is: h
My handler is: {handler}
My protocol is: {protocol}
Python path enabling status: 1
My vfs is: {vfs}
Math: 4 """ class TestTALHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/talsample.html.tal" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) # Initialize the custom mimetypes encoding map initialization.init_logger(self.config, "") initialization.init_mimetypes(self.config) def test_tal_available(self): self.assertTrue(talavailable) def test_tal_handler(self): handler = TALFileHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/html") self.assertEqual(entry.type, "h") wfile = io.BytesIO() handler.write(wfile) rendered_data = wfile.getvalue().decode() expected_data = TEST_TEMPLATE.format( selector=handler.selector, handler=html.escape(str(handler)), protocol=html.escape(str(self.protocol)), vfs=html.escape(str(self.vfs)), ) self.assertEqual(rendered_data.strip(), expected_data.strip()) pygopherd-3.0.1/tests/handlers/test_umn.py000066400000000000000000000032701456676541200207100ustar00rootroot00000000000000import os.path import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.UMN import UMNDirHandler class TestUMNDirHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "/" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = self.vfs.stat(self.selector) # Make sure there's no directory cache file from a previous test run cachefile = self.config.get("handlers.dir.DirHandler", "cachefile") try: os.remove(self.vfs.getfspath(self.selector) + "/" + cachefile) except OSError: pass def test_dir_handler(self): handler = UMNDirHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.canhandlerequest()) self.assertTrue(handler.isdir()) handler.prepare() self.assertFalse(handler.fromcache) entry = handler.getentry() self.assertEqual(entry.mimetype, "application/gopher-menu") self.assertEqual(entry.type, "1") entries = handler.getdirlist() self.assertTrue(entries) # First entry should be the special cap file self.assertEqual(entries[0].name, "New Long Cool Name") self.assertEqual(entries[0].selector, "/zzz.txt") # Second entry should be the special link file self.assertEqual(entries[1].name, "Cheese Ball Recipes") self.assertEqual(entries[1].host, "zippy.micro.umn.edu") self.assertEqual(entries[1].port, 150) pygopherd-3.0.1/tests/handlers/test_url.py000066400000000000000000000055071456676541200207200ustar00rootroot00000000000000import io import unittest from pygopherd import testutil from pygopherd.handlers.base import VFS_Real from pygopherd.handlers.file import FileHandler from pygopherd.handlers.url import HTMLURLHandler, URLTypeRewriter class TestHTMLURLHandler(unittest.TestCase): def setUp(self): self.config = testutil.get_config() self.vfs = VFS_Real(self.config) self.selector = "URL:http://gopher.quux.org/" self.protocol = testutil.get_testing_protocol(self.selector, config=self.config) self.stat_result = None def test_url_rewriter_handler(self): """ The URL rewriter should drop the "/0" at the beginning of the selector and then pass it off to the appropriate handler. """ handler = HTMLURLHandler( self.selector, "", self.protocol, self.config, self.stat_result, self.vfs ) self.assertTrue(handler.isrequestforme()) entry = handler.getentry() self.assertEqual(entry.mimetype, "text/html") self.assertEqual(entry.type, "h") wfile = io.BytesIO() handler.write(wfile) out = wfile.getvalue() self.assertIn( b'http://gopher.quux.org/', out ) def test_handler_escape_urls(self): """ URLs should be escaped in the generated HTML. """ handler = HTMLURLHandler( 'URL:http://gopher.quux.org/"