XML/0000755000175100001440000000000014636540175010743 5ustar hornikusersXML/README0000644000175100001440000000077413607633674011637 0ustar hornikusersThe Packages/ directory has some package source tar.gz files. See index.html for a description of the package and the installation procedures. This R package is not in the R package format in the github repository. It was initially developed in 1999 and was intended for use in both S-Plus and R and so requires a different structure for each. make ADMIN=1 copies the files to an appropriate structure for R. It currently requires some supporting tools from the Omegahat admin facilities. XML/MD50000644000175100001440000005362314636540175011264 0ustar hornikusersa4b42cfd693ca4bfe46096018d887cbf *ChangeLog 4ce0142d918f335c54bd04b8271a50bf *DESCRIPTION 82de24270a90587d5492f8d12e85abcd *LICENSE 38d88c89e954d242754f758e149248e4 *NAMESPACE b29605c39dd87687b2928668b9b52c6d *R/AAA.R 05aace6af9a5a1b841570d5af955146f *R/DTD.R ff35133bf0deee2608952a104a91a913 *R/DTDClasses.R 2765bfebaefb9dd88753f0f46983980d *R/DTDRef.R 141db4feac6fc837cb1cb681f2374444 *R/SAXMethods.R 38a8b2e07bbc13e081d32f7c252de8c6 *R/XMLClasses.R 2f7e79941ed0b53c43367ba90cc3b7bd *R/XMLRErrorInfo.R ac3aac6bc1944fff50ee7c5522154a21 *R/applyDOM.R f6b79f4f7155fcc58b09178f906cd584 *R/assignChild.R 231e85de6cb9ea078ef0cb2c2213108d *R/bitList.R a15627f62c15dddff63f50d038855fe4 *R/catalog.R 284dc88fce56e922416b0f8a4f4c93e6 *R/compare.R d45c7ea9a3026b309a258ffa38a2bce5 *R/createNode.R 1dea4cf235af2cf05e1fb01f2b5a71d4 *R/dynSupports.R 8401b221124b4efb00ee989369522356 *R/encoding.R e6e506d5fee0a21b59c2fddcf652699e *R/error.R 1ac5e56a5e6c8f5876f8078d3340aebf *R/fixNS.R e2d9c2def91560514649a3cca62e5f06 *R/flatTree.R f8b6ca9e074f7d121814fb3cfd4f0d3c *R/getDependencies.R 762fd9017f65818096f8a5967bde9336 *R/getRelativeURL.R a6bf923a5a5e66ca887ecd9dbccdab46 *R/hashTree.R c1001a4a49a44e593ae73d9dd2da4873 *R/htmlLinks.R 9865b82f2c355021d696f2a219997dd3 *R/htmlLists.R 31aba90b32ddddcf6c97822bd23cf283 *R/htmlParse.R 319ad3af61d22bfb1b18b17889fea6c9 *R/keyValueDB.R 87fc1f8084549a2a96aeac61d19ef396 *R/libxmlFeatures.R 694bac4ce6060c28841e70a4715f0a33 *R/namespaceHandlers.R 57957d2e3fe9252d2df2d88a70b9f1dc *R/namespaces.R 1eb950a6be727681717a28964c7d43e6 *R/nodeAccessors.R 0a08d749c99681148ef8c635de0cd6cd *R/parseDTD.R 719bbd175850d2c345fe7245c45c7605 *R/parser.R 1da99c4595f2cad8d7c92c3916973750 *R/readHTMLTable.R ed3eddf359449369643ee34b7953fb4a *R/reflection.R 9dc1ee46d1277d6edfb4e846c89663c0 *R/saveXML.R b342c8113cd53470a81a31fbaf5e6b8e *R/schema.R da2153fc4017a2360b0f0ed2c5df3a23 *R/serialize.R 2fb09d82bbc6ab332646981cada8eee3 *R/simplifyPath.R 0c6410b1686f5da871fc704f2705ff6f *R/solrDocs.R ec6b4d13943f86381db6aa1583465fdb *R/summary.R 1eced5424f333bdd41bc79db551556d2 *R/supports.R.in fead2c9d63dc1a7acf3244431d84e1e0 *R/tangle.R 033f27eaa77cba260e69fabe55c0c2e6 *R/tangle1.R 9bc0920c6ab4c3011613d6e6a4d8030a *R/toString.R 3c83404c574ba491c4a8238cba41defc *R/tree.R 09e4d0bea29cff3b118f144b6d394c4a *R/version.R 4f4954b191d7593ac720220b9ec0117d *R/xincludes.R 05cf14141f68e19441882cf078c8fecb *R/xmlErrorEnums.R 65d281b1b17dcac2c51b57a044337d09 *R/xmlEventHandler.R 4f09b46f6b9f80ecd9eb3e35ab961594 *R/xmlEventParse.R e7aa7373fed505f7521b09824262b821 *R/xmlHandler.R 708a0b6988ed9e30f27724f56bf4610b *R/xmlIncludes.R 03170fa934f8adceed4c050d77bf0545 *R/xmlInternalSource.R 9d5a05b12bcffd8afe0b4bb154ecc7c2 *R/xmlMemoryMgmt.R 85f9b9b72ed10849323c8b8b8ee23828 *R/xmlNodes.R 468ff02fdbebfe9f72ee1d7b45cecfd0 *R/xmlOutputBuffer.R 1111ef217cf4adc2859e1bb378a46ed8 *R/xmlOutputDOM.R 58e1c8f1d96c1b01ac399ce0bee9b42e *R/xmlRoot.R d79e29581564fcb906eb9900437a8ee2 *R/xmlString.R 8d44500d5b5a04fa60301d575839a542 *R/xmlToDataFrame.R 8b33b9583824359c60b2f7f54f753d03 *R/xmlTree.R c1909bbb22618650552d7c9cca20d119 *R/xmlTreeParse.R 4ac67423f4eb47a3b0d2817f8e9d082a *R/zzz.R 081453acd1b3e6642a8ba518d2d14251 *README b0777f8f8a90181ea55c9efd274ba7d3 *cleanup fb248a085dbe1cc71c22ef263485d56b *configure d32e082bc9f133816d2388ff5352cfd9 *configure.ac 42f539f105aa0e7da29b7a209beba941 *configure.win 0b3b8ce6fd20c02d923efa867f9932c9 *inst/COPYRIGHTS ff54e5b8500551dcb3239e7054a77001 *inst/FAQ.html 44d42d43addc439811b65d03ac7b4619 *inst/exampleData/9003-en.html cf0768ed8a4e59a342242b6c1d33c035 *inst/exampleData/9003.html b80e1ae6db7489cf7f5e6b48af480546 *inst/exampleData/GNUmakefile a1e81bd1bc29f244d35afa4b6efed92e *inst/exampleData/README 2d6e8210d1eafecdea788df2bd2e0384 *inst/exampleData/Rref.xml d37680440cb95ae187a12d15f51cb10e *inst/exampleData/Rsource.xml dbfedc92e65ebdbbb2ed7d7a468fb894 *inst/exampleData/SOAPNamespaces.xml 79ce6fe72b75c6968eed74a920c04bb9 *inst/exampleData/StatModel.dtd efedd98237d8a6c2f279becd9b50a0e9 *inst/exampleData/TestInvalid.xml 4ee6988da664e5930ee670c6930fe337 *inst/exampleData/allNodeTypes.xml 7f50ccdaf78c88a6b2b0b5bfcddb1fea *inst/exampleData/author.xml 4a8057b4fb9de7d5b82228bcd2a62e68 *inst/exampleData/author.xsd 610921f9e4798e229b7143e403147219 *inst/exampleData/author1.xml 1120f2d2733484f09680f85c33378602 *inst/exampleData/author2.xml 2fde199a80305fc2ae20824a69b87e66 *inst/exampleData/author2.xsd bb728a400627b16058a4a14e64fd180b *inst/exampleData/basic.xml 2bf5de346f3b02da2527ae0f7706bc49 *inst/exampleData/book.xml ac36cd5afa45e76057c1fec502e857e0 *inst/exampleData/boxplot.svg 0b8cd77a8e89cccef6288c25bf1c2655 *inst/exampleData/branch.xml 8db93ffa949d3a52c580b11fb5712d26 *inst/exampleData/catalog.xml ebf7cbd275268fee6d99255d40b92815 *inst/exampleData/cdata.xml c4aea8311842ec63cba5bbe11246b9ee *inst/exampleData/charts.svg 2181f5ee7e349d271a3895bcc9ff4961 *inst/exampleData/cleanNamespace.xml 6364ba6fe7ca258455db30aa3aaab459 *inst/exampleData/content.html 44dc03ad2980890cfc2a7f14d4134897 *inst/exampleData/dataframe.xml 8c0e739d76e85bc31f5fff42e3b31fb3 *inst/exampleData/dot.xml c70532ba974608092ab3f05421ec39bd *inst/exampleData/dtd.zip 4af9e6abc00fe42e0b719b0c92fcd855 *inst/exampleData/entity.xml c710cbd83e3fa6f387a85a53bac1f121 *inst/exampleData/entity1.xml 6ad56e424028ad33c81a8c061676c9a9 *inst/exampleData/entity2.xml 3287218d12d1191c46e01ccb8bab42ab *inst/exampleData/entity3.html 6ead5e2aa1d5b4d042377296215667b8 *inst/exampleData/entity4.xml de5ee7ed01d3ddd6b11c933f01fcee17 *inst/exampleData/entityValue 06cfddecffe04977b837494622ac1f44 *inst/exampleData/eurofxref-hist.xml.gz cd2944d52234fe6890aea6b1f78e40b1 *inst/exampleData/event.xml e8eeb195309a9204d1ade99130943e81 *inst/exampleData/foo.dtd 83e2cde65b0837ddc64b9c570e9ecf05 *inst/exampleData/functionTemplate.xml 8ceea19ebb7722fece59b070c0fefaab *inst/exampleData/generalInfo.xml 68036459f5b8f80421c0de4a9ece9e2a *inst/exampleData/gnumeric.xml b58a3cce66f3aba2abc4a621fe872aea *inst/exampleData/graph.gxl 3b8924fc68699274888160bb50c89096 *inst/exampleData/iTunes.plist beb24da8ab9fa7ec5e47559f9320f1cc *inst/exampleData/include.xml aadeec466fab1bc2067e9b8889fc785d *inst/exampleData/job.xml f249ead2193d3976bff318096ed656b8 *inst/exampleData/kiva_lender.xml 26ed8c871e37dbeb7169258b4d597a28 *inst/exampleData/largeText.xml 2dc1e4b0db1ad4449c3e43413c8e828a *inst/exampleData/lists.html b1aa2e1d35e3071c2ec9caa85194da7b *inst/exampleData/literate.dtd f19eea9e1a763e11875950294e12f21f *inst/exampleData/literate.xml d8f5b8a714757af5df3b3c4a0502ccb3 *inst/exampleData/literate.xsl 08361bfe9a264b0c5dc22a04420072cb *inst/exampleData/literateFunction.xml 48f8b27de68bbe818671542ac4eea117 *inst/exampleData/longitudinalData.xml 2925b45e6f9babc05365f96f748eca7b *inst/exampleData/malformed.xml de5f042eb58448551ee1722ae736dc61 *inst/exampleData/mathml.dtd 2cca5ea86193e8e2ba52c020716cbcb5 *inst/exampleData/mathml.xml ea5e8caa00546abf0638ad1b0e187476 *inst/exampleData/mathmlFuncCall.xml 9600ca143954e485e1316b823a991e42 *inst/exampleData/mathmlInt.xml 75d5b4c2fcb667d551e0385eaa6bba74 *inst/exampleData/mathmlMatrix.xml d9981b76cdf98ed2c6969b00f3fcac3a *inst/exampleData/mathmlQuadratic.xml 08b828cd2b6d0695b1442729af4794f5 *inst/exampleData/mathmlRoot.xml 0e3b0f32d9ee397056425db4379418db *inst/exampleData/mathmlScript.xml 619b193c39c7b0af1bf2453d22d2c6aa *inst/exampleData/mathmlSet.xml 36dbc35da2f1dcda612a0c83eb2eac4c *inst/exampleData/mathmlSimple.xml 432ab4c8ad737186dc47dd6eef00289d *inst/exampleData/mathmlSphere.xml db81cd572c5679982ccee3e65beca0db *inst/exampleData/mathmlSums.xml 24002a1ef0ab95a7dd73270e95ff404a *inst/exampleData/matrixMult.xml 3f8c8d90f7632339e3dc6321a471a027 *inst/exampleData/mtcars.xml 3c564854baf7380ebc86b55ff1951b91 *inst/exampleData/namespaceHandlers.xml ad9ab25a06187df3b0a6c81d8f7de200 *inst/exampleData/namespaces.xml 9ad8af7e80c6e1a7ec7353661a17a909 *inst/exampleData/namespaces1.xml da759173f765e3cbafb729d21c24e050 *inst/exampleData/namespaces2.xml a24f30320d88a7806a86183c2f8b5244 *inst/exampleData/nodes.xml 0e91b5beb9ff7cc56e303fac65c93842 *inst/exampleData/nodes1.xml f1426b65547d2c366031079e0cccbd1c *inst/exampleData/nodes2.xml afe9ec03e1abb8ff5c5b09ae45fa9335 *inst/exampleData/nodes3.xml af7b231bf764cb1bb31e71d2ed5c9d3b *inst/exampleData/nsAttrs.xml e669db449eb9a4a6cb2cfb1d2842f559 *inst/exampleData/plist.xml 5e531be512a447d9b886f36c5bd8c5de *inst/exampleData/raw.xml 9e52d4d5f4bba538e0306c6a22830bf6 *inst/exampleData/redundantNS.xml 21b05839f6a1bb2de0d8536a213528d2 *inst/exampleData/reparent.xml 88d6fd716774a6c44f212980b8bf0c7d *inst/exampleData/rhelp.xsl 9bd7e5d34b9ddd237bbc7745ea0199e2 *inst/exampleData/rxinclude.xml 183bf612ca6e5c890229931f453fdd8f *inst/exampleData/same.xml 0742028b822457bf861587c39b1cc1ad *inst/exampleData/setInterval.xml b249f35607ad13d2ef1bab2393d0004b *inst/exampleData/simple.plist fc3d1a8275735fd4427e939165c7e652 *inst/exampleData/simple.xml e3e5697d89ad0a2bd0b0c41ce2c1266e *inst/exampleData/size.xml 590f58281834abdd7c526e9b215750a4 *inst/exampleData/size1.xml d55386fde14974c6baa010887e612430 *inst/exampleData/size2.xml d67895692910308f94011b9f5fb0152d *inst/exampleData/size3.xml 906f785af884bfd1aec11e5acda4c9a3 *inst/exampleData/solr.xml 752af23b592f34dcea376d6a974db2bd *inst/exampleData/something.xml 0403c6eb52393ae26dcae0469e2633ec *inst/exampleData/svg.xml c8641303870984426f793cbb6e429e7d *inst/exampleData/symslines.svg 1bdc99465a3308524b52c880708b5178 *inst/exampleData/tagnames.xml 7e2c79f6142315de68284c4c11f4f6b3 *inst/exampleData/test.xml af855018d145cf15c003a16d90e0916c *inst/exampleData/test1.xml 597371c880c3f567bda055a9e55fa17c *inst/exampleData/tides.xml 5f134aa5c6fcdcf8d2f26e5b60ac9120 *inst/exampleData/utf.xml 8da18b9854857f77beab31ceeb065c1b *inst/exampleData/vars.xml 7e84b65ee6af58a74a2762687a15ff12 *inst/exampleData/writeRS.S 0de92f65f4b930fe9771ef6796b4583c *inst/exampleData/writeRS.xml b5e2c9cb6f41ddae5481f168761cdecb *inst/exampleData/xinclude/a.xml a2dbd9063592a474076a4fa13f33b966 *inst/exampleData/xinclude/b.xml 7e9d4b62b63326ad2b043393c4fc0b4b *inst/exampleData/xinclude/c.xml ee12821458852845d84ba37f3f8012d7 *inst/exampleData/xinclude/d.xml 5ecd9593d72f87c8648e2ab7be5814cc *inst/exampleData/xinclude/e.xml 30b3e0c2056e41e7ea8bc2e14b5b361e *inst/exampleData/xinclude/simple.xml 3710d0c649035714b6e89873326951b7 *inst/exampleData/xinclude/top.xml 628b2098d6e59d8964df122215f286ad *inst/exampleData/xpathTest.xml 2bd5f311c3cf42bfdcc17a94f41f4b21 *inst/exampleData/xysize.svg f3cde0f326bae48239155a8f003086f4 *inst/exampleData/xyz.svg.gz 4cc0a05705b8d796cd18d86e23976e5b *inst/examples/CIS.R 0a0425fc2df2e3438c9c226ecda22eb4 *inst/examples/DiGIR.R b741c69ecefb8a58aa829974daffe87b *inst/examples/GNUmakefile a9008dcdfa2107e5c79f7f42b83f0d54 *inst/examples/HTMLText.R 398a829f0d66ce743eab9505cb6490e5 *inst/examples/README 9e8c2b2daa4c88bfa4d2a07de014339c *inst/examples/Rhelp.xml 1ab905aac19cb951a9c3ff5a184d50fc *inst/examples/RhelpArchive.xml a17eeb45d631e58e1e785439d1abd62f *inst/examples/RhelpInfo.xml 74e02084be0d639663d0955fee5e664f *inst/examples/SAXEntity.R ca5f6777ece68d2225789bf573ab7aa6 *inst/examples/SSource.dtd 931407aa812b6b22dd8734e3b861a541 *inst/examples/author.R e0110777dd3603557e1156f003a70175 *inst/examples/bondYields.R eb96f280983ffc7eda3b75d6fdf28fe7 *inst/examples/bondsTables.R 93e43213dcc1c972d7ab3bb5acb9ac07 *inst/examples/catalog.R 7b96bde0f308701b272590496b1a4b4c *inst/examples/connections.R 1d881dcf97c18a05a545d8caf9cbd589 *inst/examples/connections1.R 193722245b150f003aa6c0ed67e49acc *inst/examples/createTree.R 6b11fbe49509cd09c20b433d8b1b9fca *inst/examples/createTree1.R fea7a47b2f17464a36e897bb4dc148b7 *inst/examples/dataFrameEvent.R dc1d21cbc5b7051e4120c2a49849dc0c *inst/examples/docbook.R 8961e4e9d970588050e80de8ccfd54a6 *inst/examples/ecb.R aa2a998a56d5b948ef52c9f7055b2d19 *inst/examples/enhancedDataFrame.R 6a8a69608880f8a1bc7382e4f29e9e8e *inst/examples/event.R 6225a3cfd7f010c79cb46f016c4d39ad *inst/examples/event.S bbc46baf6ab9a671b8a32f9c93f44c14 *inst/examples/eventHandlers.R 53a90c1a32cd469dbf664a5ef69ecc1c *inst/examples/faq.R da0e4b523962d2b8fee68d4b404d2462 *inst/examples/filterDataFrameEvent.R 7d747d516d2778419b4cd500d21eb65a *inst/examples/foo.html 49ecb1ec6023519bb310a2bdd1ff6bd1 *inst/examples/formals.xsl 553ea13eaaf4ec9e1708c7d5027af3df *inst/examples/functionIndex.Sxml dddaf71eb6703b73c24426f388c24218 *inst/examples/genericHandlers.R 27f8cdf1d2df4efdd8706065331ac66b *inst/examples/generic_file.xml 98237d086b3bb907ccfce49c0eba1b87 *inst/examples/getElements.S 963cfec2a57ecb7ab040a48f4490f3e8 *inst/examples/gettingStarted.html 1cc8cb28e54bddab52bc403b0b4fd069 *inst/examples/gettingStarted.xml ebe5014777483064b65331f7d5704586 *inst/examples/gnumericHandler.R 0e286bc72b43f41dff67db9f4cb09fb8 *inst/examples/hashTree.R e729098f8a9a2045e9e138d56eb9b94d *inst/examples/iTunes.plist e1d4464f2dc9db55104be454f9f0ee93 *inst/examples/index.html 52a2f734918edcd65e9ff3e6d5d7aea2 *inst/examples/internalNodes.S cb2a1471077fa5d25a8d0b29930359bc *inst/examples/internalXInclude.xml 22dece19680308448b99e26a550450e2 *inst/examples/itunes.R 5a44f0bbe6a34309872a5c09b17aa269 *inst/examples/itunes.xsl b973f589468083bf1c9031afd90ed3bd *inst/examples/itunesSax.R 5b9ea2b9ef39d14f3e5eba4e382c5d7c *inst/examples/itunesSax1.R c365f368746b5a38ad7c81ac535e67b0 *inst/examples/itunesSax2.R 06b6ff5309b53e0d1f482a749fb9d27e *inst/examples/mathml.R f506a024b31c84e2deddd594240bc142 *inst/examples/mathmlPlot.R 4be116184764542572c1e4d5a0004bf9 *inst/examples/metlin.R 80a2167ebaf00ee4946e11e5b3fa0c7c *inst/examples/mexico.R 41d008fff79c428b8b2139d80af8710d *inst/examples/mexico.xml a8df416e57318da4eea96ab5715ab44b *inst/examples/mi1.R f2cc473a1e09c120f941e796a4e653b2 *inst/examples/modified_itunes_sax.R bc3ab0b0426862cc3d16b2308596e084 *inst/examples/namespaces.S 91f1b67dc3de04dea2fcc2f6920541f5 *inst/examples/namespaces1.S ce0cefc8f25a0994f488073c42e2d900 *inst/examples/newNodes.R dddf168fd7c5080be74a1576ef5466dd *inst/examples/oop.S ad089f3655d2f3acee30f7067b4d0b09 *inst/examples/pi.xml 785049ea7cfdae7b5e5e8e6b009982e9 *inst/examples/pmml.R fd3553a039641a18d7054220a67a7750 *inst/examples/prompt.xml 5441838e027e655b42651f4d382fdd15 *inst/examples/promptXML.R b14b2b7e24e681eee419ced37bc43948 *inst/examples/promptXML.Sxml 631b33237934928479582f3a3d7ecf82 *inst/examples/rcode.xml d41d8cd98f00b204e9800998ecf8427e *inst/examples/rcode.xsl 25a7c74cf466eb3daf9dbf493b718e89 *inst/examples/redirection.R 0d41bf0aadbce1279d255f80587d185a *inst/examples/reorder.xml bb78fe90a650625ae8dbd40ecf3636e2 *inst/examples/sbml.xml acadb3e6695e45ee3eb7bd786d494383 *inst/examples/sbmlSAX.S 9d49e19ba166fb9d9773c431938cbf06 *inst/examples/schema.xsd 04b016367c23b30873d1e5eca554bb6d *inst/examples/schemaEg.xml 755449de058d8f0300592fa140bbc99e *inst/examples/schemas.xml 603ead1f9155d91d3cdb0a004db097ec *inst/examples/svg.R c48636aa7b630785d5cc395fb6a0fa5a *inst/examples/tags.Sxml 1b2489004d118db8920a7a3f208c33b7 *inst/examples/trademe_cars.R 94ab383e5c6f30fdcf3f3b13ceef6eb1 *inst/examples/valueFilterDataFrameEvent.R 7df5d486adb60fcde1d84fbd94ae1801 *inst/examples/wordML.R a215bd1733d94718ed88a9632677eda0 *inst/examples/writeExamples.S 9053aae1a374bd10eee4e701e9c87bdb *inst/examples/xml2tex.Sxml b976c0a84da79df21f1d90e186402baa *inst/examples/xmlSource.R 411b82529f6cd31fa9b2634f2e2ca152 *inst/examples/xmlTags.xml 5f42960279557bdc33de85c7799f6a0f *inst/examples/xmlTree.R fdd705555e0c8267f6ef8bb0289390e9 *inst/examples/xpath.R 777186450f8e22d4f650499a8a150c3f *inst/examples/xpath.xml 068dee4e4e15c0f69e8df8a5a8eaa897 *inst/scripts/RSXML.bsh.in 03ae53b54d6d2168fcc7454c14682086 *inst/scripts/RSXML.csh.in ff1d23fdc64afb10560da4072e5e384e *man/AssignXMLNode.Rd 92ceaf274e4ebe321861b256b2262262 *man/Doctype-class.Rd 21df1aefac7e79053ac327bf4cc187ff *man/Doctype.Rd 8077dfeb6984bc654cf08ac857df5185 *man/SAXMethods.Rd c351eb7d588e799653622715a5202121 *man/SAXState-class.Rd d40daeb56cf6466e0ea5c3f789cf87fc *man/XMLAttributes-class.Rd 115aed144ea989230a5ba211355a385f *man/XMLCodeFile-class.Rd 25936f5c421f873b144226aa8d099344 *man/XMLInternalDocument.Rd b902296706b8fce8cccc5c912f5226a8 *man/XMLNode-class.Rd 80db5e6e8aeaee89d591958ff175655d *man/addChildren.Rd 7e2a071add5e13c3769a75665e83225a *man/addNode.Rd 559d78cddaaf4b1f8b9587b4765931eb *man/addSibling.Rd c1ac7589d644af035ef4e5e38a7b463d *man/append.XMLNode.Rd 09e56315e0cce3cdd48d0d47ef8510fd *man/asXMLNode.Rd 1be889cae84dc996aa91b836d2edc4a5 *man/asXMLTreeNode.Rd ad21fc83db2ccac174b48ad02d33aef9 *man/catalogResolve.Rd 6b604e709c29505b312532b77aa99752 *man/catalogs.Rd 635ee70f7d0119f27af30f48e2b05522 *man/coerce.Rd 22684c65804739d57060e84fa8bf4b29 *man/compareXMLDocs.Rd 79fd28a580531816d0028d74ffc5ef57 *man/docName.Rd 209ee649a2c52876b825f6ef1669ad29 *man/dtdElement.Rd 7675558f9687a98c871d7f215f42dc4e *man/dtdElementValidEntry.Rd 78b5b724f2474a4801b60029457a5352 *man/dtdIsAttribute.Rd 3711f5a6d158946f64c609575eb7ecf8 *man/dtdValidElement.Rd 66b32dc1889221b239b8c3c1dfabd839 *man/ensureNamespace.Rd d3e3902ea4fe25d3857aa794dec075b0 *man/findXInclude.Rd 0ee0f2813c0fc4fc732f8731445f506b *man/free.Rd 6205f11393939b912302330665a4624f *man/genericSAXHandlers.Rd 3d95b1004bd3e03b0d136bf4b3be8eae *man/getChildrenStrings.Rd 9443e267094cee408efe309f7223ab91 *man/getEncoding.Rd 6d94506d430ac22ba6ece4cffc9ddece *man/getHTMLLinks.Rd ab922d47da651c3656c4f9fc64d3c333 *man/getLineNumber.Rd ca4905696a784ae7f7b8a8f0c2bfa653 *man/getNodeSet.Rd e53d3f1962a3276a717453b022b55483 *man/getRelativeURL.Rd edcefdb7086f06186adad54d9980682a *man/getXIncludes.Rd 2f3fdbde9fb3f351326eca1bfcbc81f0 *man/getXMLErrors.Rd cfa4e11592ed00f9cb8247d0e59d3f95 *man/isXMLString.Rd 720c4fe165adaf7268bbea26fcf670fd *man/length.XMLNode.Rd 9398e99857eecde62710f84fe3f51137 *man/libxmlVersion.Rd 1cc7d2805bfe8d6d97064f5b5810bfac *man/makeClassTemplate.Rd bcc6efd399abe7a78f398f445f8410d8 *man/names.XMLNode.Rd 49856050e87fc54c666cf9fcfc328dc7 *man/newXMLDoc.Rd 43e3c93ff036a105e40dd1bf228d7236 *man/newXMLNamespace.Rd 3e0d0d90ec56e3fbbbfbf12f58469aac *man/parseDTD.Rd 02c7cd373c3ea7d6c476df65b87980e4 *man/parseURI.Rd 1c85a344a9e4bfd39cb3df303a2e20cf *man/parseXMLAndAdd.Rd 4a577e2869ec67fd1fdd1d81d017511a *man/print.Rd d36e4628f65dff3c8d5fe347b126676d *man/processXInclude.Rd f5607c676182e472a1f2a2a25f9db8e6 *man/readHTMLList.Rd 16e599b591aa177b6527f11665909cd6 *man/readHTMLTable.Rd 8f81d16226120619817fa1a172679a08 *man/readKeyValueDB.Rd 8d15b91eaa346f72664bbb62ab5455fc *man/readSolrDoc.Rd 72281e5a24125d35b55afc9f70555a4a *man/removeXMLNamespaces.Rd 56794c3fb2cd5d4918c32dc8acf10f30 *man/replaceNodeWithChildren.Rd e036dbeee478708b736ed15360634a80 *man/saveXML.Rd 24b46bf8f25897bacbcb7915b3d54687 *man/schema-class.Rd d56bfed177c3648de5284ef766500b3a *man/setXMLNamespace.Rd 9f498c1f0936c26ebf3fc70fa4018610 *man/supportsExpat.Rd c85b172d3a0894a6255c34323d777c04 *man/toHTML.Rd 931a149ae3b82f306c2e4abb70f3347a *man/toString.Rd af018657db302e2b7ebf0f63d8eb20e3 *man/xmlApply.Rd 033ba024a4023ac984f4dddc6079a8ad *man/xmlAttributeType.Rd ec6d297236892a9f9497be4de5d99eb0 *man/xmlAttrs.Rd 9a66741994d3e76e3004cbd2977ba735 *man/xmlChildren.Rd 0cdf4d25b1158c4162316028f244586e *man/xmlCleanNamespaces.Rd 36d83a7dcf52b5934a40247a46f4e2a4 *man/xmlClone.Rd e2f6330711aff2dd1df7c2bef9a0adb6 *man/xmlContainsEntity.Rd bd88d5b5436f57bd16f896fbb3837495 *man/xmlDOMApply.Rd 368fa01a925a08db5b309623c46b99ed *man/xmlElementSummary.Rd 6254505b1223b4accc51a87197a3154d *man/xmlElementsByTagName.Rd 07dc0ecb650472c2d1880a037ca49a81 *man/xmlEventHandler.Rd c853f6adda406317023bcdb0913816a5 *man/xmlEventParse.Rd fd932d88f2c3a3569dbc3ad399d39822 *man/xmlGetAttr.Rd e7aea11004bc636831c31529a881bbb6 *man/xmlHandler.Rd 27297649f3305d5bace0cdb20a75c705 *man/xmlHashTree.Rd dab8360df5edc368a530274327f4d245 *man/xmlName.Rd 103e4167eb19e9e61ba10023b90d5e3c *man/xmlNamespace.Rd 9800e219024b4b039230c9537c77c5d4 *man/xmlNamespaceDefinitions.Rd d24c723d68b6a88a89fb83e31a1596d1 *man/xmlNode.Rd cd2d11323d9ceea52093309cf8322a9d *man/xmlOutput.Rd 6a443760a3b345e78b99358a0fec28f5 *man/xmlParent.Rd 30122ab8c7c7263901d2b674731955bb *man/xmlParseDoc.Rd be5f3c2c9f4878e8b4df61c6df89a38c *man/xmlParserContextFunction.Rd e37360fcaa6ff0394040b2e26e187968 *man/xmlRoot.Rd 927722ec945cb55d1abb0e256f1b992e *man/xmlSchemaValidate.Rd 37b7957855c872a54bb1c60abef9e0b3 *man/xmlSearchNs.Rd 71b54af27e0f35cb4915bb058544e6e4 *man/xmlSerializeHook.Rd 793059a6b10875bfd03765d2162bfa19 *man/xmlSize.Rd 8f67d3e131531756743f1afaa16d76e4 *man/xmlSource.Rd 52b079e639f02b3e4780beed343de405 *man/xmlStopParser.Rd 05356cf28e8d23254acbf87162c9a8ee *man/xmlStructuredStop.Rd ffa5a30b01090b1d05a5a19c9a3bea68 *man/xmlSubset.Rd 55711b6c3f421eef82d2041c87dec5f4 *man/xmlToDataFrame.Rd 29646a080808de5840f7bcb8994400c9 *man/xmlToList.Rd 15fdef72e6e90aeacf92e9afd126b3b3 *man/xmlToS4.Rd 3d7f4bf5224bfd4eeb21632a4469e711 *man/xmlTree.Rd 55020834b11452c69fcf47c46c5eecff *man/xmlTreeParse.Rd 00f96e20f0a390f00ceefeb78f26e6e6 *man/xmlValue.Rd 70da44b0aa162474cb86decbc2fdb14f *src/DocParse.c 5244014df10ef5a255f890ff7df5424f *src/DocParse.h b5cb0dd5f43481ce20675e7501996484 *src/EventParse.c a855ea27bb2ad2247b4bec96992d9730 *src/EventParse.h 380aaf0a76f032635d696cd1f47dda4a *src/ExpatParse.c 21327b0c7a0406a35e0aa87168d02fd9 *src/ExpatParse.h 294efeedc91eecaef4b4917de756d723 *src/HTMLParse.c f8e657440de4c71940b40c6952e9d9d3 *src/Makevars.in 25e8b4be2f14b1b437eaa4411a30605a *src/Makevars.ucrt 217afdc4385bc2657eb8ee19978d00e5 *src/Makevars.win 4df946341180f6e453b0a9f7e6e19ba5 *src/NodeGC.c bba8153b861732e55247d7caf8d44817 *src/NodeGC.h 956d2b8925bf7a209732e71104657f58 *src/RSCommon.h 171c784de7fd4530c552c88ca8d39695 *src/RSDTD.c d51866b3b7de881b366d5f57819156f6 *src/RSDTD.h c8ef975634bb5874143107dfe9e1546a *src/RS_XML.h 9b5b0ab44c9f48f388cad45e79510132 *src/RUtils.c 816c0e976c2a0a3a0cfb1ff9cff4ac43 *src/Rcatalog.c dfb2d8cdac46685f4b989e0678dc4747 *src/Utils.c addb035c852a81af74f1af3a759d6e11 *src/Utils.h ec5c630530c87bc4a54e37f47a6d1336 *src/XMLEventParse.c 06d148d209a76bd776779709f29f2193 *src/XMLHashTree.c dfd8201878dd162bb317d550592acf06 *src/XMLTree.c 06dff24eae84b53211ddb5d1ad52dfcb *src/fixNS.c 34157f4ab7a2c930e4d3ea68d14e2a7f *src/libxmlFeatures.c b0a6144b6614a1489c4639635f448325 *src/schema.c f9f4a35d94a429e6924e0d3260ba34bb *src/xmlsecurity.c 5ff6882475929a186aadd9b71947eca1 *src/xpath.c XML/configure.win0000755000175100001440000000024614361737640013450 0ustar hornikusersecho "supportsExpat <- function() FALSE" > R/supports.R echo "supportsLibxml <- function() TRUE" >> R/supports.R echo "ADD_XML_OUTPUT_BUFFER = FALSE" >> R/supports.R XML/R/0000755000175100001440000000000014405636156011143 5ustar hornikusersXML/R/flatTree.R0000644000175100001440000001436013610046417013030 0ustar hornikusers## it looks like <<- assignments here should actually be to env. # Represent the tree as a flat collection of nodes # but allocate the list ahead of time and grow it # by doubling the space. This makes things a lot faster # for large trees. utils::globalVariables(c('e', 'idx', 'nodeNames', 'nodeSet', 'parentCount')) ## nothing here is exported. if(FALSE){ xmlFlatListTree = function(nodes = list(), parents = character(), children = list(), env = new.env(), n = 200) { # To make things reasonably fast, we store the nodes in a pre-allocated list env = structure(env, class = c("XMLFlatListTree", "XMLFlatTree")) assign("nodeSet", vector("list", n), env) assign("idx", 1, env) assign("parentCount", 0, env) assign("nodeNames", character(n), env) assign("parents", character(n), env) #XXX Deal with this if parents is specified. # Assign the parents and children values and fill in any orphans, etc. # after calling addNode for the different nodes. if(!exists(".nodes", env)) env$.nodes <- env #? # function to generate a new node identifier. Can be given the # proposed name and will then make one up if that conflicts with another # identifier. f = function(suggestion = "") { if(suggestion == "" || suggestion %in% nodeNames) as.character(idx + 1) else suggestion } environment(f) = env assign( ".nodeIdGenerator", f, env) g = addParentNode environment(g) = env assign(".addParentNode", g, env) assign(".this", env, env) assign("n", n, env) addNode = function(node, parentId) { node = asXMLTreeNode(node, .this) id = node$id # Put it in the nodeSet by position. nodeSet[[ idx ]] <<- node nodeNames[idx] <<- id idx <<- idx + 1 if(inherits(parentId, "XMLTreeNode")) parentId = parentId$id if(length(parentId)) { parentCount <<- parentCount + 1 .parents[ parentCount ] <<- parentId names(.parents)[parentCount] <<- id .children [[ parentId ]] <<- c(.children[[ parentId ]], id ) } if(idx == n) { n <<- 2*n length(nodeSet) <<- n } return(node) } environment(addNode) = env env$.addNode <- addNode # Populate the tree with any initial nodes. # XXX putting these in .nodes and not nodeSet! ids = names(nodes) nodes = lapply(seq(along = nodes), function(i) { x = nodes[[ i ]] if(!("id" %in% names(unclass(x)))) x$id = f( ifelse(ids[ i ] == "", xmlName(x), ids[i]) ) if(!inherits(x, "XMLTreeNode")) { ## no 'e' is visible here x$env = e class(x) = c("XMLTreeNode", class(x)) } x }) names(nodes) = sapply(nodes, function(x) x$id) env$.nodes <- nodes env$.parents = parents env$.children = children .tidy = # to be run when adding to the tree is complete. # This shrinks the vectors to their actual size # rather than their preallocated sizes. function() { idx <- idx - 1 length(nodeSet) <- idx length(nodeNames) <- idx names(nodeSet) <- nodeNames .nodes <<- nodeSet idx } .tidy environment(.tidy) <- env env$.tidy = .tidy env } xmlRoot.xmlFlatListTree = function(x, skip = TRUE, ...) { #XXX stop("not implemented") } # Represent the tree as a flat collection of nodes # combined with # See tests/tree.R # Use an environment within the node so that we can lookup the children and parent information # directly from within # # provide tools to set parent and children relationship. # # Validate entries for parents and children to ensure nodes exist. # # as(, "XMLTreeNode") function to make certain environment, id and class are present. # # Suppose we are given an empty xmlTree() object when parsing an XML document. # Then when we are converting the results back to R, we need to add nodes as we traverse the tree. # Need to make no # see convertNode() called in createXMLNode() # Given out an id within this tree for each node # xmlFlatTree = # # This version just concatenates each node to an existing list and so suffers # horrifically from garbage collection. # We leave it here in case it is useful either directly to someone for use on # small documents, or for performance comparisons with other approaches. # function(nodes = list(), parents = character(), children = list(), env = new.env()) { # Assign the parents and children values and fill in any orphans, etc. # after calling addNode for the different nodes. if(!exists(".nodes", env)) env$.nodes <- env # function to generate a new node identifier. Can be given the # proposed name and will then make one up if that conflicts with another # identifier. f = function(suggestion = "") { if(suggestion == "" || suggestion %in% names(.nodes)) as.character(length(.nodes) + 1) else suggestion } environment(f) = env assign( ".nodeIdGenerator", f, env) g = addParentNode environment(g) = env assign(".addParentNode", g, env) assign(".this", env, env) addNode = function(node, parentId) { node = asXMLTreeNode(node, .this) id = node$id if(length(parentId)) { .parents[ id ] <<- parentId .children [[ parentId ]] <<- c(.children[[ parentId ]], id ) } .nodes[[ id ]] <<- node id } environment(addNode) = env env$.addNode <- addNode ids = names(nodes) nodes = lapply(seq(along = nodes), function(i) { x = nodes[[ i ]] if(!("id" %in% names(unclass(x)))) x$id = f( ifelse(ids[ i ] == "", xmlName(x), ids[i]) ) if(!inherits(x, "XMLTreeNode")) { ## FIXME: there is no visible 'e' here x$env = e class(x) = c("XMLTreeNode", class(x)) } x }) names(nodes) = sapply(nodes, function(x) x$id) env$.nodes <- nodes env$.parents = parents env$.children = children structure(env, class = c("XMLSimpleFlatTree", "XMLFlatTree")) } } XML/R/getDependencies.R0000644000175100001440000000234614405636156014361 0ustar hornikusersgetXIncludes = function(filename, recursive = TRUE, skip = character(), omitPattern = "\\.(js|html?|txt|R|c)$", namespace = c(xi = "https://www.w3.org/2003/XInclude"), duplicated = TRUE) { doc = xmlParse(filename, xinclude = FALSE) if(missing(namespace)) { ns = xmlNamespaceDefinitions(doc, simplify = TRUE) if("https://www.w3.org/2001/XInclude" %in% ns) namespace = c(xi = "https://www.w3.org/2001/XInclude") } nodes = getNodeSet(doc, "//xi:include", namespaces = namespace) files = sapply(nodes, xmlGetAttr, "href") nonRecursive = as.logical(sapply(nodes, xmlGetAttr, "text", FALSE)) if(length(omitPattern)) nonRecursive = grepl(omitPattern, files) | nonRecursive if(recursive) { processed = c(filename, skip) for(f in unique(files[!nonRecursive])) { # path name relative to the base document of the XInclude f = getRelativeURL(f, filename) # dirname(filename)) if(file.exists(f)) files = c(files, getXIncludes(f, TRUE, skip = processed)) else warning(f, " doesn't exist") processed = c(processed, f) } } files = unlist(files) if(!duplicated) unique(files) else files } XML/R/xmlMemoryMgmt.R0000644000175100001440000000073313607633705014107 0ustar hornikuserssetGeneric("clearMemoryManagement", function(node, ...) { standardGeneric("clearMemoryManagement") }) setMethod("clearMemoryManagement", "XMLInternalElementNode", function(node, ...) { .Call("R_clearNodeMemoryManagement", node, PACKAGE = "XML") }) manageMemory_p = function(finalizer) { if(is.character(finalizer) || is(finalizer, "externalptr") || inherits(finalizer, c("NativeSymbol", "NativeSymbolInfo"))) return(TRUE) as.logical(finalizer) } XML/R/version.R0000644000175100001440000000075613610046417012753 0ustar hornikuserslibxmlVersion <- function(runTime = FALSE) { v <- if(runTime) .Call("RS_XML_libxmlVersionRuntime", PACKAGE = "XML") else .Call( "RS_XML_libxmlVersion", PACKAGE = "XML") v <- as.character(v) els <- substring(v, 1:nchar(v), 1:nchar(v)) list(major=els[1], minor=paste(els[2:3],sep="", collapse=""), patch=paste(els[4:5], sep="", collapse="")) } setEntitySubstitution = function(val) .Call("RS_XML_SubstituteEntitiesDefault", as.logical(val), PACKAGE = "XML") XML/R/dynSupports.R0000644000175100001440000000020313607633667013642 0ustar hornikuserssupportsExpat <- function() { is.loaded("RS_XML_initParser") } supportsLibxml <- function() { is.loaded("RS_XML_piHandler") } XML/R/tangle.R0000644000175100001440000000406013607633705012540 0ustar hornikusers# # tangle code from an XML file to a collection of files # getXPathExpr = function(language, nodeNames) { paste(paste("//", unlist(outer(language, nodeNames, FUN = "paste", sep = ":")), sep = ""), collapse = "|") } getTargetFiles = function(doc, language = names(xmlNamespaceDefinitions(doc)), nodeNames = c("code", "function", "plot", "class", "method"), xpath = getXPathExpr(language, nodeNames)) { if(is.character(doc)) doc = xmlParse(doc) nodes = getNodeSet(doc, xpath) ans = structure(sapply(nodes, xmlGetAttr, "file"), names = sapply(nodes, function(x) names(xmlNamespace(x)) )) ans = tapply(ans, names(ans), function(x) unique(unlist(x))) ans[ sapply(ans, length) != 0 ] } xmlTangle = function(doc, files = getTargetFiles(doc, xpath = xpath), dir = ".", language = names(xmlNamespaceDefinitions(doc)), nodeNames = c("code", "function", "plot", "class", "method"), xpath = getXPathExpr(language, nodeNames)) { if(is.character(doc)) doc = xmlParse(doc) if(length(files) == 0 && "r" %in% language) { return(tangleR(doc, out = NA)) } files = structure(lapply(names(files), function(ns) { xp = paste("//", ns, ":", nodeNames, sep = "") structure(sapply(files[[ns]], function(file) { expr = paste(xp, "[@file=", sQuote(file), "]", collapse = "|") paste(xpathSApply(doc, expr, xmlValue), collapse = "\n") }), names = files[[ns]]) }), names = names(files), class = "FileContentsList") if(!is.na(dir)) save.FileContentsList (files, dir) else files } save.FileContentsList = function(x, dir = ".") { x = structure(unlist(x, recursive = FALSE), names = unlist(lapply(x, names))) files = paste(dir, names(x), sep = .Platform$file.sep) sapply(seq(along = files), function(i) cat(x[[i]], file = files[i])) files } XML/R/xmlTree.R0000644000175100001440000002271713607633674012724 0ustar hornikusersxmlTree <- # # Create an XML document using internal nodes and help to manage # the state for the user rather than requiring them to manage # the individual nodes. For the most part, the two approaches # are relatively similar in complexity. # # function(tag = NULL, attrs = NULL, dtd = NULL, namespaces = list(), doc = newXMLDoc(dtd, namespaces)) # Allows a DOCTYPE, etc. at the beginning by specifying dtd as # a vector of 1, 2, 3 elements passed to newXMLDTDNode() or # as an XMLDTDNode directly. # { currentNodes <- list(doc) # the stack of nodes isXML2 <- libxmlVersion()$major != "1" # if we are given a DTD, add it to the document. if(!is.null(dtd)) { if(isXML2) { node = NULL if(inherits(dtd, "XMLDTDNode")) node = dtd else if(is.character(dtd) && dtd[1] != "") node = newXMLDTDNode(dtd, doc = doc) if(!is.null(node)) { addChildren(doc, node) currentNodes[[2]] <- node #???XXX } } else warning("DTDs not supported in R for libxml 1.*. Use libxml2 instead.") } definedNamespaces = list() defaultNamespace = NULL addNamespaceDefinitions = is.null(tag) setActiveNamespace = function(ns) { defaultNamespace <<- ns } asXMLNode <- function(x) { if(inherits(x, "XMLInternalNode")) return(x) v = if(is.list(x)) lapply(x, asXMLNode) else newXMLTextNode(as.character(x), doc = doc, escapeEntities = is(x, "AsIs")) v } setNamespace <- function(node, namespace = defaultNamespace) { # if there is no namespace or if we have one and no names on the namespace if(length(namespace) == 0 || ! ( length(namespace) == 1 && is.null(names(namespace)) ) ) return(NULL) if(is.list(namespace)) return(NULL) if(!is.na(match(namespace, names(namespaces))) && is.na(match(namespace, names(definedNamespaces)))) { ns <- .Call("R_xmlNewNs", node, namespaces[[namespace]], namespace, PACKAGE = "XML") definedNamespaces[[namespace]] <<- ns } setXMLNamespace(node, definedNamespaces[[namespace]]) #old setInternalNamespace( node, definedNamespaces[[namespace]]) } # namespace is intended to be the namespace for this node # and not any definitions. # How do we define new namespaces with this function? # Can we add them to attrs. No! addTag <- function(name, ..., attrs = NULL, close = TRUE, namespace = defaultNamespace, .children = list(...) ) { if(inherits(name, "XMLInternalNode")) { addChildren(currentNodes[[1]], name) currentNodes <<- c(node, currentNodes) addChildren(node, kids = .children) if(close) currentNodes <<- currentNodes[-1] return(name) } # if the user gives us something like "r" for the namespace as opposed to # c(r = "http:...") then we try to match the prefix in an earlier node # ??? Should we use the defined namespaces in the document? if(FALSE) { if(length(namespace) == 1 && length(names(namespace)) == 0) { tmp = namespace if(length(currentNodes)) { defs = namespaceDeclarations(currentNodes[[1]], TRUE) i = match(namespace, names(defs)) if(!is.na(i)) namespace = defs[[i]] } } } if(!is.null(attrs)) storage.mode(attrs) <- "character" if(inherits(name, "XMLInternalNode")) node = name else { parent = if(length(currentNodes) > 1) currentNodes[[1]] else xmlRoot(currentNodes[[1]]) node <- newXMLNode(name, attrs = attrs, namespace = namespace, doc = doc, parent = parent, namespaceDefinitions = if(addNamespaceDefinitions) namespaces else NULL) if(addNamespaceDefinitions) { # lapply(seq(along = namespaces), # function(i) # setXMLNamespace(node, namespaces[[i]], names(namespaces)[i])) addNamespaceDefinitions <<- FALSE } } # if(length(currentNodes) > 1) # addChildren(currentNodes[[1]], node) currentNodes <<- c(node, currentNodes) # if(!inherits(name, "XMLInternalNode")) # setNamespace(node, namespace) for(i in .children) addChildren(node, asXMLNode(i)) # vectorize XXX if(close == TRUE) closeTag() invisible(node) } closeTag <- function(name="") { if(nargs() == 0) { tmp <- currentNodes[[1]] currentNodes <<- currentNodes[-1] } else if( is.character(name) ) { w = sapply(currentNodes, inherits, "XMLInternalElementNode") useNamespace = length(grep(":", name)) > 0 ids = sapply(currentNodes[ w ], xmlName, useNamespace) tmp = list() for(id in name) { i = which(id == ids) if(length(i) == 0) stop("Cannot close tag for node with name ", id, " - no such node open") tmp = c(tmp, currentNodes[1:i]) currentNodes <<- currentNodes[-c(1:i)] ids = ids[-(1:i)] } } else if(inherits(name, "numeric")) { num = name if(is.na(num) || num == -1) # close all of the nodes, except the document node. w = seq(along = currentNodes[- length(currentNodes)]) else if(length(num) == 1) w = 1:num else w = num tmp = currentNodes[ w ] currentNodes <<- currentNodes[ - w ] } invisible(tmp) } add = function(node, parent = currentNodes[[1]], close = TRUE) { if(!is.null(parent)) { addChildren(parent, node) if(!close) currentNodes <<- c(node, currentNodes) } invisible(node) } addComment <- function(...) { add(newXMLCommentNode(paste(as.character(list(...)), sep=""), doc = doc)) } addCData <- function(text) { add(newXMLCDataNode(text, doc = doc)) } addPI <- function(name, text) { add(newXMLPINode(name, text, doc = doc), NULL) } # deal with the top-level node the user may have supplied. if(!is.null(tag)) { if(is.character(tag)) { node = addTag(tag, attrs = attrs, namespace = namespaces, close = FALSE) } else if(inherits(tag, "XMLInternalNode")) { if(is.null(xmlParent(node))) # if we have a DTD node, need to add it to that or parallel to that? addChildren(doc, node) } } v <- list( addTag = addTag, addNode = addTag, addCData = addCData, addPI = addPI, closeTag = closeTag, closeNode = closeTag, addComment = addComment, setNamespace = setActiveNamespace, value = function() doc, doc = function() doc, add = function(...){} ) #class(v) <- c("XMLInternalDOM", "XMLOutputStream") # v ans = new("XMLInternalDOM", v) names(ans) = names(v) ans } setAs("XMLInternalNode", "XMLNode", function(from) asRXMLNode(from) ) xmlRoot.XMLInternalDOM = function(x, skip = TRUE, ...) { xmlRoot(x$doc(), skip = skip) } #??? This was XMLInternalElement and not ...Node xmlRoot.XMLInternalElement = xmlRoot.XMLInternalNode = function(x, skip = TRUE, ...) { doc = as(x, "XMLInternalDocument") if(is.null(doc)) getRootNode(x) # skip = skip - getRootNode doesn't have a skip argument else xmlRoot(doc, skip = skip) } # Get the name of the file/URI for the document. setGeneric("docName", function(doc, ...) standardGeneric("docName")) setMethod("docName", "NULL", function(doc, ...) as.character(NA) ) setMethod("docName", "XMLNode", function(doc, ...) as.character(NA) ) setMethod("docName", "XMLHashTreeNode", function(doc, ...) docName(doc$env, ...) ) docName.XMLInternalDocument = function(doc, ...) { .Call("RS_XML_getDocumentName", doc, PACKAGE = "XML") } setMethod("docName", "XMLInternalDocument", docName.XMLInternalDocument) docName.XMLInternalNode = function(doc, ...) { docName(as(doc, "XMLInternalDocument")) } setMethod("docName", "XMLInternalNode", docName.XMLInternalNode) docName.XMLDocument = function(doc, ...) { doc$doc$file } setMethod("docName", "XMLDocument", docName.XMLDocument) docName.XMLDocumentContent = function(doc, ...) { doc$file } setOldClass("XMLDocumentContent") setMethod("docName", "XMLDocumentContent", docName.XMLDocumentContent) setGeneric("docName<-", function(x, value) standardGeneric("docName<-")) setMethod("docName<-", "XMLInternalDocument", function(x, value) { .Call("RS_XML_setDocumentName", x, value, PACKAGE = "XML") x }) # See hashTree.R setMethod("docName<-", "XMLHashTree", function(x, value) { assign(".doc", value, x) x }) parseXMLAndAdd = function(txt, parent = NULL, top = "tmp", nsDefs = character()) { txt = paste(txt, collapse = "") if(!inherits(txt, "AsIs") && length(top) > 0) { open = sprintf("%s%s", top, paste(sprintf(' xmlns%s%s="%s"', ifelse(names(nsDefs) != "", ":", ""), names(nsDefs), nsDefs), collapse = "")) tmp = sprintf("<%s>%s", open, txt, top) } else tmp = txt doc = xmlParse(tmp, asText = TRUE) if(!is.null(parent)) invisible(.Call("R_insertXMLNode", xmlChildren(xmlRoot(doc)), parent, -1L, FALSE, PACKAGE = "XML")) else xmlRoot(doc) } XML/R/xmlRoot.R0000644000175100001440000000121213607633705012726 0ustar hornikuserssetGeneric("xmlRoot<-", function(x, ..., value) standardGeneric("xmlRoot<-")) setMethod("xmlRoot<-", c("XMLInternalDocument", value = "character"), function(x, ..., value) { newXMLNode(value, doc = x) x }) setMethod("xmlRoot<-", c("XMLInternalDocument", value = "XMLInternalNode"), function(x, ..., value) { #XXX check that this does the reference counting correctly # specifically, d = newXMLDoc(); xmlRoot(d) = "bar"; xmlRoot(d) = newXMLNode("foo") .Call("RS_XML_setRootNode", x, value, PACKAGE = "XML") x }) setMethod("xmlRoot<-", "XMLHashTree", function(x, ..., value) { x$.addNode(value) x }) XML/R/htmlLists.R0000644000175100001440000000332013607633665013254 0ustar hornikuserssetGeneric("readHTMLList", function(doc, trim = TRUE, elFun = xmlValue, which = integer(), ...) standardGeneric("readHTMLList")) setMethod("readHTMLList", "character", function(doc, trim = TRUE, elFun = xmlValue, which = integer(), encoding = character(), ...) { readHTMLList(htmlParse(doc, encoding = encoding), trim, elFun, which, ...) }) setMethod("readHTMLList", "HTMLInternalDocument", function(doc, trim = TRUE, elFun = xmlValue, which = integer(), ...) { lists = getNodeSet(doc, "//ol | //ul | //dl") if(length(which)) lists = lists[which] ans = lapply(lists, readHTMLList, trim = trim, elFun = elFun) if(length(which) == 1) ans[[1]] else ans }) setMethod("readHTMLList", "XMLInternalNode", function(doc, trim = TRUE, elFun = xmlValue, which = integer(), ...) { if(xmlName(doc) == "dl") return(readHTMLDefinitionList(doc, trim, elFun)) ans = unname(sapply(xmlChildren(doc)[!xmlSApply(doc, is, "XMLInternalTextNode")], elFun)) if(trim) ans = unname(sapply(ans, function(x) if(is.character(x)) trim(x) else x)) ans }) readHTMLDefinitionList = function(node, trim = TRUE, elFun = xmlValue) { kids = xmlChildren(node) structure(sapply(kids[names(node) == "dd"], elFun), names = sapply(kids[names(node) == "dt"], elFun)) } XML/R/nodeAccessors.R0000644000175100001440000002326614405636156014072 0ustar hornikusersif(!exists("Sys.setenv", baseenv())) Sys.setenv <- get("Sys.putenv", "package:base") xmlRoot <- function(x, skip = TRUE, ...) { UseMethod("xmlRoot") } xmlRoot.XMLDocument <- function(x, skip = TRUE,...) { # x$children[[1]] # x$doc xmlRoot(x$doc, skip = skip,...) } xmlRoot.XMLDocumentContent <- function(x, skip = TRUE, ...) { args <- list(...) a <- x$children[[1]] if(skip & inherits(a, "XMLCommentNode")) { which <- sapply(x$children, function(x) !inherits(x, "XMLCommentNode")) if(any(which)) { which <- (1:length(x$children))[which] a <- x$children[[which[1]]] } } a } xmlRoot.HTMLDocument <- function(x, skip = TRUE, ...) { x$children[[1]] } xmlApply <- function(X, FUN, ...) { UseMethod("xmlApply") } xmlSApply <- function(X, FUN, ...) { UseMethod("xmlSApply") } xmlApply.XMLNode <- function(X, FUN, ...) { lapply(xmlChildren(X), FUN, ...) } xmlApply.XMLDocument <- function(X, FUN, ...) { xmlApply(xmlRoot(X), FUN, ...) } xmlSApply.XMLDocument <- function(X, FUN, ...) { xmlSApply(xmlRoot(X), FUN, ...) } xmlSApply.XMLNode <- function(X, FUN, ...) { sapply(xmlChildren(X), FUN, ...) } xmlApply.XMLDocumentContent <- function(X, FUN, ...) { xmlSApply(X$children, FUN, ...) } xmlSApply.XMLDocumentContent <- function(X, FUN, ...) { xmlSApply(X$children, FUN, ...) } xmlValue <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { UseMethod("xmlValue") } if(useS4) setGeneric("xmlValue", function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x)) standardGeneric("xmlValue")) xmlValue.XMLNode <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { if(recursive && xmlSize(x) > 0) { kids = xmlChildren(x) if(ignoreComments) kids = kids[ !sapply(kids, "XMLCommentNode") ] return(paste(unlist(lapply(kids, xmlValue, ignoreComments, trim = trim)), collapse = "")) } else if(!recursive && xmlSize(x) > 0) { #XXX If !recursive but have text nodes e.g. in the second child. i = sapply(xmlChildren(x), inherits, "XMLTextNode") if(any(i)) return(paste(unlist(lapply(xmlChildren(x)[i], xmlValue, ignoreComments, trim = trim)), collapse = "")) } # if(xmlSize(x) == 1) # && (inherits(x[[1]], "XMLTextNode")) # return(xmlValue(x[[1]], ignoreComments)) if(is.null(x$value)) character() else if(trim) trim(x$value) else x$value } setS3Method("xmlValue", "XMLNode") xmlValue.XMLTextNode <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { if(!is.null(x$value)) if(trim) trim(x$value) else x$value else character(0) } setS3Method("xmlValue", "XMLTextNode") xmlValue.XMLComment <- xmlValue.XMLCommentNode <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { if(ignoreComments) return("") if(!is.null(x$value)) if(trim) trim(x$value) else x$value else character(0) } setS3Method("xmlValue", "XMLCommentNode") xmlValue.XMLCDataNode <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { if(trim) trim(x$value) else x$value } setS3Method("xmlValue", "XMLCDataNode") xmlValue.XMLProcessingInstruction <- function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) { if(trim) trim(x$value) else x$value } setS3Method("xmlValue", "XMLProcessingInstruction") xmlValue.list = xmlValue.XMLNodeSet = function (x, ignoreComments = FALSE, recursive = TRUE, encoding = if(length(x)) getEncoding(x[[1]]) else "", trim = FALSE) { sapply(x, xmlValue, recursive = recursive, encoding = encoding, trim = trim) } setS3Method("xmlValue", "XMLNodeSet") "xmlValue.NULL" = function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) as.character(NA) #setS3Method("xmlValue", "NULL") getSibling.XMLInternalNode = # Access the next field in the xmlNodePtr object. # not exported. function(node, after = TRUE, addFinalizer = NA, ...) { if(!inherits(node, "XMLInternalNode")) stop("can only operate on an internal node") .Call("RS_XML_getNextSibling", node, as.logical(after), addFinalizer, PACKAGE = "XML") } xmlNamespaceDefinitions <- function(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) { UseMethod("xmlNamespaceDefinitions") } xmlNamespaces = xmlNamespaceDefinitions xmlNamespaceDefinitions.XMLInternalDocument = function(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) { r = xmlRoot(x, addFinalizer = FALSE) while(!is.null(r) && !inherits(r, "XMLInternalElementNode")) r = getSibling(r, addFinalizer = FALSE) if(is.null(r)) return(if(simplify) character() else NULL) xmlNamespaceDefinitions(r, addNames, recursive, simplify) } xmlNamespaceDefinitions.XMLNode = function(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) { ans = unclass(x)$namespaceDefinitions if(recursive == TRUE) { # warning("recursive facility not yet implemented.") f = function(node) { if(!inherits(node, "XMLNode") || xmlName(node) == "") return(FALSE) ans <<- append.xmlNode(ans, unclass(node)$namespaceDefinitions) xmlApply(node, f) } xmlApply(x, f) } if(addNames && length(ans) && length(names(ans)) == 0) names(ans) = sapply(ans, function(x) x$id) if(simplify) { if(length(ans) == 0) return(character()) ans = structure(sapply(ans, function(x) x$uri), class = c("SimplifiedXMLNamespaceDefinitions", "XMLNamespaceDefinitions")) } else if(!is.null(ans)) class(ans) = "XMLNamespaceDefinitions" ans } xmlNamespaceDefinitions.XMLInternalNode = function(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) { ans = .Call("RS_XML_internalNodeNamespaceDefinitions", x, as.logical(recursive), PACKAGE = "XML") if(addNames && length(ans) > 0) names(ans) = sapply(ans, function(x) x$id) if(simplify) { if(length(ans) == 0) return(character(0)) ans = sapply(ans, function(x) x$uri) ans = structure(removeDuplicateNamespaces(ans), class = c("SimplifiedXMLNamespaceDefinitions", "XMLNamespaceDefinitions")) } else if(!is.null(ans)) class(ans) = "XMLNamespaceDefinitions" ans } setGeneric("getEffectiveNamespaces", function(node, ...) standardGeneric("getEffectiveNamespaces")) tmp = function(node, ...) { ans = xmlNamespaceDefinitions(node) merge = function(to, what) { i = !(names(what) %in% names(to)) if(any(i)) ans[names(what)[i]] <<- what[i] } tmp = xmlParent(node, manageMemory = FALSE) while(!is.null(tmp)) { merge(ans, xmlNamespaceDefinitions(tmp)) tmp = xmlParent(tmp, manageMemory = FALSE) } ans } setMethod("getEffectiveNamespaces", "XMLInternalNode", tmp) setMethod("getEffectiveNamespaces", "XMLHashTreeNode", tmp) setMethod("getEffectiveNamespaces", "XMLNode", function(node) xmlNamespaceDefinitions(node)) removeDuplicateNamespaces = function(ns) { dups = duplicated(names(ns)) if(!any(dups)) return(ns) tapply(ns, names(ns), function(els) { if(length(els) == 1) return(TRUE) if(length(unique(els)) > 1) stop("different URIs for the same name space prefix ", names(els)[1]) TRUE }) ns[!dups] } xmlNamespace <- function(x) { UseMethod("xmlNamespace") } xmlNamespace.XMLNode <- function(x) { x$namespace } #setMethod("xmlNamespace", "character", xmlNamespace.character = function(x) { a = strsplit(x, ":")[[1]] if(length(a) == 1) character() else a[1] } #) verifyNamespace = # Check that the namespace prefix in tag (if any) # has a definition in def that matches the definition of the same prefix in node. function(tag, def, node) { # could have prefix: with no name, but that should never be allowed earlier than this. ns = strsplit(tag, ":")[[1]] if(length(ns) == 1) return(TRUE) if(! (ns[1] %in% names(def)) ) return(FALSE) defs = xmlNamespaceDefinitions(node) if( defs[[ ns[1] ]]$uri != def[ ns[1] ]) stop("name space prefix ", ns, " does not match ", def[ ns[1] ], " but ", defs[[ ns[1] ]] $uri) TRUE } xmlGetAttr <- #Added support for name spaces. function(node, name, default = NULL, converter = NULL, namespaceDefinition = character(), addNamespace = length(grep(":", name)) > 0) { a <- xmlAttrs(node, addNamespace) if(is.null(a) || is.na(match(name, names(a)))) return(default) if(length(namespaceDefinition)) verifyNamespace(name, namespaceDefinition, node) if(!is.null(converter)) converter(a[[name]]) else a[[name]] } getXInclude = function(node, parse = FALSE, sourceDoc = NULL) { href = xmlGetAttr(node, "href") xpointer = xmlGetAttr(node, "xpointer") if(parse) { # # Perhaps just reload the original document # and see what the difference is. Not guaranteed # to work since people may have already altered # the source document. if(!is.na(href)) { fileName = paste(dirname(docName(sourceDoc)), href, sep = .Platform$file.sep) doc = xmlParse(fileName) } else doc = sourceDoc if(!is.na(xpointer)) { } } else c(href = href, xpointer = xpointer) } getInclude = # #XXX getXIncludeInfo is not defined! # function(doc, parse = FALSE) { xpathApply(doc, "//xi:include", getXIncludeInfo, parse, docName(doc), doc, namespaces = c(xi="http://www.w3.org/2001/XInclude")) } getXIncludeInfo = function(node, parse = FALSE, baseURL = character(), doc = NULL) { } XML/R/xmlOutputDOM.R0000644000175100001440000000740513607633674013662 0ustar hornikuserssetClass("XMLOutputStream", "namedList") setClass("XMLOutputDOM", contains = "XMLOutputStream") setClass("XMLOutputBuffer", contains = "XMLOutputStream") setClass("XMLInternalDOM", contains = "XMLOutputStream") xmlOutputDOM <- function(tag = "doc", attrs = NULL, dtd = NULL, nameSpace = NULL, nsURI = character(0), xmlDeclaration = NULL) { buf <- NULL current <- NULL startingNode = 1 if(is.logical(xmlDeclaration) && xmlDeclaration) xmlDeclaration = xmlPINode("xml", 'version = "1.0"') else if(is.character(xmlDeclaration)) { if(length(grep('version *=', xmlDeclaration)) == 0) xmlDeclaration = paste(xmlDeclaration, "version='1.0'") xmlDeclaration = xmlPINode("xml", xmlDeclaration) } if(length(dtd)) dtd = paste(" 1) paste("PUBLIC", ddQuote(dtd[2])), ">") reset <- function() { buf <<- xmlNode(tag, attrs = attrs, namespace = nameSpace) if(length(nsURI) > 0) { names(nsURI) <- paste("xmlns", names(nsURI), sep=":") buf$attributes <<- nsURI } current <<- integer(0) invisible(buf) } reset() addTag <- function(tag, ..., attrs=NULL, close=TRUE, namespace=NULL, .children = list(...)) { if(missing(namespace)) namespace <- nameSpace addNode(n <- xmlNode(tag, attrs= attrs, namespace = namespace, .children = .children)) if(close == FALSE) { current <<- c(current, xmlSize(getCurrent())) } invisible(n) } getCurrentExpr <- function() { if(length(current) > 0) { p <- seq(2, length=length(current)-1) kall <- call("[[", as.name("buf"), current[1]) for(i in p) { kall <- call("[[", kall, current[i]) } } else kall <- as.name("buf") kall } getCurrent <- function() { eval(getCurrentExpr()) } # We want to append this to the currently open (or active) # node as defined by `current' # d[[1]] <- append.xmlNode(d[[1]], xmlNode("phone")) addNode <- function(node) { kall <- getCurrentExpr() if(length(current) > 0){ lhs <- kall kall <- call("append.xmlNode", kall, node) kall <- call("<<-", lhs, kall) } else { kall <- call("append.xmlNode", kall, node) } val <- eval(kall) if(length(current) == 0) buf <<- val invisible(node) } addComment <- function(...) { addNode(xmlCommentNode(paste(sapply(list(...), as.character), sep=""))) } addCData <- function(text) { addNode(xmlCDataNode(text)) } addPI <- function(name, text) { addNode(xmlPINode(name, text)) } addText <- function(text, namespace = "") { addNode(xmlTextNode(text, namespace)) } closeTag <- function(name="", namespace=NULL) { # namespace is ignored since we already have the tag name! current <<- current[-length(current)] } getValue = function() { # Add DOCTYPE if we have a dtd. if(!is.null(xmlDeclaration)) structure(list(xmlDeclaration = xmlDeclaration, root = buf, doctype = dtd), class = "XMLRDocument") else buf } con <- list( value= getValue, addTag = addTag, addEndTag = function(name){ closeTag(name)}, closeTag = closeTag, reset = reset, addNode = addNode, add = function(...) {}, addComment = addComment, addPI = addPI, addCData = addCData, current = function(){current} ) #class(con) <- c("XMLOutputDOM", "XMLOutputStream") # con ans = new("XMLOutputDOM", con) names(ans) = names(con) ans } xmlRoot.XMLRDocument = function(x, skip = TRUE, ...) x$root print.XMLRDocument = function(x, ...) { if(!is.null(x$xmlDeclaration)) print(x$xmlDeclaration) if(!is.null(x$doctype)) cat(x$doctype, "\n") print(x$root, ...) } XML/R/bitList.R0000644000175100001440000000033313607633667012706 0ustar hornikusersbitlist = # Taken from RAutoGenRuntime function(...) { bitOr = bitops::bitOr x = unlist(list(...)) if(length(x) == 1) return(x) ans = x[1] for(i in 2:length(x)) { ans = bitOr(ans, x[i]) } ans } XML/R/xmlToDataFrame.R0000644000175100001440000001672414205426523014141 0ustar hornikusers # Adapt this to be able to specify an XPath expression to identify a list of nodes. setGeneric("xmlToDataFrame", # # Read a relatively flat, 2-level deep XML document into a data frame. # The document is assumed to be something of the form # # # value # value # value # # # value # value # value # # # # This can handle cases where not all observations have the same # fields. # # z = xmlToDataFrame("~/size.xml") # z = xmlToDataFrame("~/size.xml", c("integer", "integer", "numeric")) # function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) standardGeneric("xmlToDataFrame")) setMethod("xmlToDataFrame", "character", # parse the XML document if it is a file name and # not a regular XML document already. function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) xmlToDataFrame(xmlParse(doc), colClasses, homogeneous, collectNames, stringsAsFactors = stringsAsFactors)) setMethod("xmlToDataFrame", c("XMLInternalDocument", nodes = "missing"), function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) xmlToDataFrame(doc, colClasses, homogeneous, collectNames, nodes = xmlChildren(xmlRoot(doc)), stringsAsFactors)) tmp = function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) { if(length(nodes) == 0) return(data.frame()) # Find out how many fields there. nfields = sapply(nodes, xmlSize) nvar = max(nfields) if(collectNames) varNames = unique(unlist( lapply(nodes, names) )) else varNames = names(nodes[[which.max(nfields)]]) if(is.na(homogeneous)) homogeneous = all(nfields == nvar) && all(sapply(nodes[-1], function(x) all(names(x) == varNames))) if(!homogeneous) return(fromRaggedXML2DataFrame(nodes, varNames, c(length(nfields), length(varNames)), colClasses, stringsAsFactors)) # Function to operate on each fun = function(x) { tmp = xmlSApply(x, xmlValue) length(tmp) = nvar tmp } # Get the individual values vals = unlist(lapply(nodes, fun)) ans = matrix(vals, length(nfields), byrow = TRUE) ans = if(length(colClasses)) { as.data.frame(lapply(seq(along = colClasses), function(i) { as(ans[, i], colClasses[i]) }), stringsAsFactors = stringsAsFactors) } else as.data.frame(ans, stringsAsFactors = stringsAsFactors) names(ans) = varNames ans } bob = function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) xmlToDataFrame(nodes = doc, colClasses = colClasses, homogeneous = homogeneous, collectNames = collectNames, stringsAsFactors = stringsAsFactors) setMethod("xmlToDataFrame", c(nodes = "XMLNodeSet"), tmp) setMethod("xmlToDataFrame", c(nodes = "list"), tmp) setOldClass("XMLInternalNodeList") setMethod("xmlToDataFrame", c(nodes = "XMLInternalNodeList"), tmp) setMethod("xmlToDataFrame", "XMLNodeSet", bob) setMethod("xmlToDataFrame", "XMLInternalNodeList", bob) setMethod("xmlToDataFrame", "list", bob) setMethod("xmlToDataFrame", "XMLInternalElementNode", function(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) xmlToDataFrame(nodes = xmlChildren(doc), colClasses = colClasses, homogeneous = homogeneous, collectNames = collectNames, stringsAsFactors = stringsAsFactors)) fromRaggedXML2DataFrame = # # This reads data from the nodes of an XML document and assumes # that they do not all have the same number or even names of fields. # So this does extra work to match each observation to the union of # the field names across all nodes. # # o = fromRaggedXML2DataFrame("size2.xml") # o = fromRaggedXML2DataFrame("size1.xml") # function(nodes, varNames = unique(unlist( lapply(nodes, names) )), dims = c(length(nodes), length(varNames)), colClasses = NULL, stringsAsFactors = FALSE) { #XXX if(is.character(nodes)) nodes = xmlChildren(xmlRoot(xmlParse(nodes))) # create an empty data frame with as many rows and columns as needed. ans = as.data.frame(replicate(dims[2], rep(as.character(NA), dims[1]), simplify = FALSE), stringsAsFactors = FALSE) names(ans) = varNames # Fill in the rows based on the names. for(i in seq(length = dims[1])) ans[i, names(nodes[[i]])] = xmlSApply(nodes[[i]], xmlValue) # Convert the columns to the specified classes if specified. # Should drop cols with NULL. Also guess those with NA. if(length(colClasses)) { i = ! sapply(colClasses, is.null) ans = ans[ i ] varNames = varNames[i] colClasses = colClasses[ i ] ans = as.data.frame(lapply(seq(length = ncol(ans)), function(i) { as(ans[, i], colClasses[[i]]) }), stringsAsFactors = stringsAsFactors) } names(ans) = varNames ans } setGeneric("xmlAttrsToDataFrame", function(doc, attrs = character(), omit = character(), ...) standardGeneric("xmlAttrsToDataFrame")) setMethod("xmlAttrsToDataFrame", "character", function(doc, attrs = character(), omit = character(), ...) xmlAttrsToDataFrame(xmlParse(doc), attrs, omit, ...)) setMethod("xmlAttrsToDataFrame", "AsIs", function(doc, attrs = character(), omit = character(), ...) xmlAttrsToDataFrame(xmlParse(doc), attrs, omit, ...)) setMethod("xmlAttrsToDataFrame", "XMLInternalElementNode", function(doc, attrs = character(), omit = character(), ...) xmlAttrsToDataFrame(xmlChildren(doc), attrs, omit, ...)) setMethod("xmlAttrsToDataFrame", "XMLNodeSet", function(doc, attrs = character(), omit = character(), ...) { xmlAttrsToDataFrame(as(doc, 'list'), attrs, omit, ...) }) setMethod("xmlAttrsToDataFrame", "list", function(doc, attrs = character(), omit = character(), ...) { # assuming these are all nodes. combineNamedVectors(lapply(doc, xmlAttrs), attrs, omit, ...) }) setMethod("xmlAttrsToDataFrame", "XMLInternalNodeList", function(doc, attrs = character(), omit = character(), ...) { # assuming these are all nodes. combineNamedVectors(lapply(doc, xmlAttrs), attrs, omit, ...) }) inAllRecords = function(x) { tt = table(unlist(lapply(x, names))) names(tt)[ tt == length(x)] } allNames = function(x) unique( unlist(lapply(x, names)) ) combineNamedVectors = function(els, attrs = character(), omit = character(), ...) { if(is.function(attrs)) attrs = attrs(els) if(!length(attrs)) { attrs = allNames(els) if(length(omit)) attrs = setdiff(attrs, omit) } if(length(attrs) == 0) { warning("no elements to combine across records") return(data.frame()) } values = lapply(els, function(x) { structure(x[attrs], names = attrs) }) ans = as.data.frame(do.call(rbind, values), row.names = NULL, ...) rownames(ans) = NULL ans } XML/R/toString.R0000644000175100001440000000041413610046416013065 0ustar hornikuserstoString.XMLNode <- function(x, ...) { .tempXMLOutput = "" # Put here for codetools to detect the variable locally. con <- textConnection(".tempXMLOutput", "w", local = TRUE) sink(con) print(x) sink() close(con) paste(.tempXMLOutput, collapse="\n") } XML/R/namespaceHandlers.R0000644000175100001440000000610013607633666014706 0ustar hornikusersnamespaceNodeHandlers = # # This is to manage a collection of node handlers # which have handlers for nodes with the same name but in an # different namespace. # For example, suppose we have a node array in an R representation # and another in Matlab but these are differentiated by the namespace. # r:array and m:array. # This function arranges to invoke the correct handler when a node is encountered. # # namespaceNodeHandlers("r:array" = function(...) ..., # "m:array" = function(...) ..., # other = function(...) ...) # # # namespaceNodeHandlers("r:array" = function(...) ..., # "m:array" = function(...) ..., # other = function(...) ..., # nsDefs= c(r = "http://www.r-project.org", # m = "http://www.mathworks.com") ) # # # If there is no handler for a given node, then call the default one # i.e. .startElement or startElement # function(..., .handlers = list(...), nsDefs = NULL, useDotNames = TRUE) { # Get the node name and namespace prefix/alias for each of the handler names tmp = strsplit(names(.handlers), ":") prefix = sapply(tmp, function(x) if(length(x) > 1) x[1] else "") nodeNames = sapply(tmp, function(x) if(length(x) > 1) x[2] else x[1]) # Now, find out which ones are duplicated. w = duplicated(nodeNames) if(!any(w)) return(.handlers) dups = nodeNames[w] # Now, take out the handler functions that have the same node name # as any other. w = nodeNames %in% dups nsHandlers = .handlers[ w ] # and remove them from .handlers .handlers = .handlers[ !w ] # This function will act as the proxy for doing the dispatch for a particular node. generalHandler = function(node, ...) { # Get the node name and the namespace prefix. id = xmlName(node) ns = xmlNamespace(node) if(is.null(ns)) ns = '' if(length(nsDefs)) { # get the namespace definition from the node # and its URI and then match this to the nsDefs # That gives us the prefix to use i = (ns == nsDefs) if(!any(i) && ns != '') ns = character() #stop("can't match namespace '", as.character(ns), "' in ", paste(nsDefs, collapse = ", ")) else ns = names(nsDefs)[i] } if(length(ns) && ns != "") tmp = paste(ns, id, sep = ":") else tmp = id f = nsHandlers[[ tmp ]] # if we didn't find a handler, use the startElement one if(is.null(f)) f = .handlers[[ if(useDotNames) '.startElement' else 'startElement' ]] # if we have a handler, call it. # Otherwise, just return the node... after all that! if(!is.null(f)) f(node, ...) else node } .handlers[ dups ] = rep(list(generalHandler), length(dups)) class(.handlers) <- "XMLNamespaceNodeHandlers" if(length(nsDefs)) class(.handlers) <- c(class(.handlers), "RequiresNamespaceInfo") .handlers } XML/R/serialize.R0000644000175100001440000000135413607633670013261 0ustar hornikusersxmlSerializeHook = function(x) { if(inherits(x, c("XMLInternalDocument", "XMLInternalElementNode"))) c(as(x, "character"), class(x)[1]) else if(is(x, "XMLNodeSet")) c(sapply(x, as, "character"), class(x)[1]) else NULL } xmlDeserializeHook = function(x) { if(length(x) == 2) { if(x[2] == "XMLInternalElementNode") xmlRoot(xmlParse(I(x[1]))) else if(x[2] == "XMLNodeSet") { #XXX we should put these into the same document, but it is hard to make this sensible. structure(lapply(x, function(x) xmlRoot(xmlParse(I(x)))), "XMLNodeSet") } else if(x[2] == "XMLInternalDocument") xmlParse(I(x[1])) else stop("Not sure how to handle ", x[2]) } else xmlParse(I(x)) } XML/R/XMLClasses.R0000644000175100001440000007723314405636156013260 0ustar hornikusers# # This file contains the definitions of methods # for operating on the XMLNode objects to make # the more user-friendly. Specifically, these # methods are # print displays the contents of a node and children # as XML text rather than R/S list # # size returns the number of children # # name retrieves the tag name # # attrs retrieves the attributes element of the XML node # # [ and [[ access the children # (To get at the regular R/S fields in the object, use $ # e.g. node$name, node$attributes, node$value) # # In S4/Splus5, we should use the new class mechanism. # setS3Method = function(fun, class) { if(!useS4) return() cat("setting method for", fun, class, "\n") setMethod(fun, class, get(paste(fun, class, sep = ".")), where = topenv(parent.frame())) } if(FALSE) setOldClass = function(classes) { ancestors = unique(sapply(classes[-1], oldClass)) if(length(ancestors)) { classes = c(classes[1], ancestors) oldClassTable[[ classes[1] ]] <<- ancestors } methods::setOldClass(classes) } # For R 2.7.2 and older. In 2.8.0, extends() for setOldClass() works # better. oldClassTable = list( "XMLNode" = c("RXMLAbstractNode", "XMLAbstractNode"), "XMLTextNode" = c("XMLNode", "RXMLAbstractNode", "XMLAbstractNode"), "XMLPINode" = c( "XMLNode", "RXMLAbstractNode", "XMLAbstractNode") , "XMLProcessingInstruction" = c( "XMLNode", "RXMLAbstractNode", "XMLAbstractNode") , "XMLCommentNode" = c("XMLNode", "XMLTextNode", "RXMLAbstractNode", "XMLAbstractNode"), "XMLCDataNode" = c("XMLNode", "RXMLAbstractNode", "XMLAbstractNode"), "XMLHashTree" = c("XMLAbstractDocument"), "XMLHashTreeNode" = c("RXMLAbstractNode"), "XMLDocumentContent" = c(), "XMLDocument" = c("XMLAbstractDocument"), "XMLHashTree" = c("XMLAbstractDocument"), "XMLInternalDocument" = c("XMLAbstractDocument"), "HTMLInternalDocument" = c("XMLInternalDocument", "XMLAbstractDocument"), "XMLTreeNode" = c("RXMLAbstractNode") ) oldClass = function(class) { if(version$major == "2" && as.integer(version$minor) >= 8) return(unique(c(class, extends(class)))) c(class, oldClassTable[[ class ]]) } ############################### # These were in xmlNodes, but need to be defined earlier. setOldClass("XMLAbstractDocument") setOldClass(c("XMLInternalDocument", "XMLAbstractDocument")) setOldClass(c("XMLHashTree", "XMLAbstractDocument")) setOldClass(c("XMLDocument", "XMLAbstractDocument")) #XXXsetOldClass(c("HTMLInternalDocument", "XMLInternalDocument")) # , "XMLAbstractDocument")) setOldClass(c("HTMLInternalDocument", "XMLInternalDocument", "XMLAbstractDocument")) setOldClass("XMLAbstractNode") setOldClass(c("RXMLAbstractNode", "XMLAbstractNode")) # Why do we have to repeat this class inheritance information? # We don't! # setOldClass(c("XMLHashTreeNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLTextNode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLPINode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLCommentNode", "XMLNode", "XMLTextNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLProcessingInstruction", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) # setOldClass(c("XMLCDataNode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) setOldClass(c("XMLHashTreeNode", "RXMLAbstractNode")) setOldClass(c("XMLNode", "RXMLAbstractNode")) ###setOldClass(c("XMLTextNode", "XMLNode")) methods::setOldClass(c("XMLTextNode", "XMLTextNode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode" )) #setOldClass(c("XMLEntitiesEscapedTextNode", "XMLTextNode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode")) #setOldClass(c("XMLEntitiesEscapedTextNode", "XMLTextNode")) setOldClass(c("XMLPINode", "XMLNode")) setOldClass(c("XMLCommentNode", "XMLNode")) setOldClass(c("XMLProcessingInstruction", "XMLNode")) setOldClass(c("XMLCDataNode", "XMLNode")) setOldClass(c("XMLTreeNode", "XMLNode", "RXMLAbstractNode", "XMLAbstractNode" )) setOldClass(c("XMLInternalNode", "XMLAbstractNode")) setOldClass(c("XMLInternalCDataNode", "XMLInternalNode")) setOldClass(c("XMLInternalPINode", "XMLInternalNode")) setOldClass(c("XMLInternalCommentNode", "XMLInternalNode")) setOldClass(c("XMLInternalElementNode", "XMLInternalNode")) setOldClass(c("XMLInternalTextNode", "XMLInternalNode")) setOldClass(c("XMLXIncludeStartNode", "XMLInternalNode")) setOldClass(c("XMLXIncludeEndNode", "XMLInternalNode")) setOldClass(c("XMLEntityDeclNode", "XMLInternalNode")) setOldClass(c("XMLAttributeDeclNode", "XMLInternalNode")) setOldClass(c("XMLDocumentNode", "XMLInternalNode")) setOldClass(c("XMLDocumentTypeNode", "XMLInternalNode")) setOldClass(c("XMLDocumentFragNode", "XMLInternalNode")) setOldClass(c("XMLNamespaceDeclNode", "XMLInternalNode")) setOldClass(c("XMLAttributeNode", "XMLInternalNode")) setOldClass(c("XMLDTDNode", "XMLInternalNode")) setOldClass("XMLNamespace") setOldClass("XMLNamespaceDefinition") setOldClass("XMLNamespaceDefinitions") #setOldClass("XMLInternalDOM") setOldClass(c("SimplifiedXMLNamespaceDefinitions", "XMLNamespaceDefinitions")) #setClass("XPathNodeSet", representation(ref = "externalptr")) setAs("XMLDocument", "XMLInternalDocument", function(from) { xmlParse(saveXML(from$doc$children$doc)) }) ################### ############ #setMethod("[[", c("XMLInternalElementNode", "numeric") , "[[.XMLInternalElementNode" = function(x, i, j, ..., exact = NA, namespaces = xmlNamespaceDefinitions(x, simplify = TRUE), addFinalizer = NA) { if(is(i, "numeric")) .Call("R_getNodeChildByIndex", x, as.integer(i), addFinalizer, PACKAGE = "XML") else NextMethod() } xmlChildren <- function(x, addNames = TRUE, ...) { UseMethod("xmlChildren") } setGeneric("xmlParent", function(x, ...) standardGeneric("xmlParent")) xmlChildren.XMLNode <- # # Retrieve the list of children (sub-nodes) within # an XMLNode object. # function(x, addNames = TRUE, ...) { structure(if(length(x$children)) x$children else list(), class = "XMLNodeList") } if(useS4) { setGeneric("xmlChildren", function(x, addNames = TRUE, ...) standardGeneric("xmlChildren")) setMethod("xmlChildren", "XMLNode", xmlChildren.XMLNode) } if(useS4) { setGeneric("xmlName", function(node, full = FALSE) standardGeneric("xmlName")) setMethod("xmlName", "XMLCommentNode", function(node, full = FALSE) "comment") setMethod("xmlName", "XMLNode", function(node, full = FALSE) { ns = unclass(node)$namespace if(!full || is.null(ns) || ns == "") return(node$name) # if(!is.character(ns)) { tmp = ns$id } else if(inherits(ns, "XMLNamespace")) tmp = names(ns) else tmp = ns if(length(tmp)) paste(tmp, unclass(node)$name, sep=":") else unclass(node)$name }) } else { xmlName <- function(node, full = FALSE) { UseMethod("xmlName", node) } xmlName.XMLComment <- function(node, full = FALSE) { return("comment") } xmlName.XMLNode <- # # Get the XML tag name of an XMLNode object # function(node, full = FALSE) { ns = unclass(node)$namespace if(!full || is.null(ns) || ns == "") return(node$name) # if(!is.character(ns)) { tmp = ns$id } else if(inherits(ns, "XMLNamespace")) tmp = names(ns) else tmp = ns if(length(tmp)) paste(tmp, unclass(node)$name, sep=":") else unclass(node)$name } } xmlAttrs <- function(node, ...) { UseMethod("xmlAttrs", node) } xmlAttrs.XMLNode <- # # Get the named list of attributes # for an XMLNode object. # function(node, ...) { node$attributes } if(useS4) setMethod("xmlAttrs", "XMLNode", xmlAttrs.XMLNode) "[.XMLNode" <- # # Extract the children (sub-nodes) within # the specified object identified by ... # and return these as a list # function(x, ..., all = FALSE) { obj <- xmlChildren(x) # x$children if(all) # "all" %in% names(list(...)) && list(...)[["all"]] == TRUE) structure(obj[ names(obj) %in% list(...)[[1]] ], class = "XMLNodeList") else structure(obj[...], class = "XMLNodeList") # NextMethod("[") } "[[.XMLDocumentContent" <- function(x, ...) { x$children[[...]] } "[[.XMLNode" <- # # Extract the children (sub-nodes) within # the specified object identified by ... # function(x, ...) { xmlChildren(x)[[...]] } names.XMLNode <- function(x) { # names(xmlChildren(x)) xmlSApply(x, xmlName) } "names<-.XMLNode" <- function(x, value) { names(x$children) <- value x } length.XMLNode <- function(x) { xmlSize(x) } xmlSize <- # # The number of elements within (or length of) a collection # function(obj) { UseMethod("xmlSize", obj) } xmlSize.XMLDocument <- function(obj) { return(length(obj$doc$children)) } xmlSize.default <- # # The number of elements within (or length of) a collection # function(obj) { length(obj) } xmlSize.XMLNode <- # # Determine the number of children (or sub-nodes) within an XML node. # function(obj) { length(obj$children) } print.XMLComment <- print.XMLCommentNode <- function(x, ..., indent = "", tagSeparator = "\n") { if(is.logical(indent) && !indent) indent <- "" cat(indent, "", tagSeparator, sep="") } print.XMLTextNode <- function(x, ..., indent = "", tagSeparator = "\n") { if(is.logical(indent) && !indent) indent <- "" if(inherits(x, "EntitiesEscaped")) txt = xmlValue(x) else txt = insertEntities( xmlValue(x) ) cat(indent, txt, tagSeparator, sep="") } setAs("XMLNamespaceDefinitions", "character", function(from) { if(length(from) == 0) return(character()) ans = structure(sapply(from, function(x) x$uri), names = sapply(from, function(x) x$id)) if(length(names(ans)) == 0) names(ans) = "" ans }) setAs("character", "XMLNamespaceDefinitions", function(from) { ids = names(from) if(is.null(ids)) ids = rep("", length(from)) structure(lapply(seq(along = from), function(i) structure(list(id = ids[[i]], uri = from[i], local = TRUE), class = "XMLNamespace")), class = "XMLNamespaceDefinitions", names = ids) }) print.XMLNode <- # # displays a node and attributes (and its children) # in its XML format. # function(x, ..., indent = "", tagSeparator = "\n") { if(length(xmlAttrs(x))) { tmp <- paste(names(xmlAttrs(x)),paste("\"", insertEntities(xmlAttrs(x)), "\"", sep=""), sep="=", collapse=" ") } else tmp <- "" if(length(x$namespaceDefinitions) > 0) { k = as(x$namespaceDefinitions, "character") ns = paste("xmlns", ifelse(nchar(names(k)), ":", ""), names(k), "=", ddQuote(k), sep = "", collapse = " ") # ns <- paste(sapply(x$namespaceDefinitions, # function(x) { # paste("xmlns", if(nchar(x$id) > 0) ":" else "", x$id, "=", "\"", x$uri, "\"", sep="") # }), collapse=" ") } else ns <- "" # Add one space to the indentation level for the children. # This will accumulate across successive levels of recursion. subIndent <- paste(indent, " ", sep="") if(is.logical(indent) && !indent) { indent <- "" subIndent <- FALSE } if (length(xmlChildren(x)) == 0) { ## Empty Node - so difference is cat(indent, paste("<", xmlName(x, TRUE), ifelse(tmp != "", " ", ""), tmp, ifelse(ns != "", " ", ""), ns, "/>", tagSeparator, sep = ""), sep = "") } else if (length(xmlChildren(x))==1 && inherits(xmlChildren(x)[[1]],"XMLTextNode")) { ## Sole child is text node, print without extra white space. cat(indent, paste("<", xmlName(x, TRUE), ifelse(tmp != "", " ", ""), tmp, ifelse(ns != "", " ", ""), ns, ">", sep = ""), sep = "") kid = xmlChildren(x)[[1]] if(inherits(kid, "EntitiesEscaped")) txt = xmlValue(kid) else txt = insertEntities( xmlValue(kid) ) cat(txt,sep="") cat(paste("", tagSeparator, sep = ""), sep = "") } else { cat(indent, paste("<", xmlName(x, TRUE), ifelse(tmp != "", " ", ""), tmp, ifelse(ns != "", " ", ""), ns, ">", tagSeparator, sep = ""), sep = "") for (i in xmlChildren(x)) print(i, indent = subIndent, tagSeparator = tagSeparator) cat(indent, paste("", tagSeparator, sep = ""), sep = "") } } print.XMLEntityRef <- function(x, ..., indent="", tagSeparator = "\n") { if(is.logical(indent) && !indent) indent <- "" cat(indent, x$value) } print.XMLCDataNode <- function(x, ..., indent="", tagSeparator = "\n") { if(is.logical(indent) && !indent) indent <- "" cat(indent, "", tagSeparator, sep = "") } print.XMLProcessingInstruction <- function(x, ..., indent="", tagSeparator = "\n") { if(is.logical(indent) && !indent) indent <- "" cat(indent, paste("", tagSeparator, sep=""), sep = "") } xmlElementsByTagName <- # # Extract all the sub-nodes within an XML node # with the tag name `name'. # function(el, name, recursive = FALSE) { kids = xmlChildren(el) idx = (names(kids) == name) els = kids[idx] # idx <- (names(el$children) == name) # els = el$children[idx] if(!recursive || xmlSize(el) == 0) return(els) subs = xmlApply(el, xmlElementsByTagName, name, TRUE) subs = unlist(subs, recursive = FALSE) append.xmlNode(els, subs[!sapply(subs, is.null)]) } getDefaultNamespace = function(doc, ns = xmlNamespaceDefinitions(doc, simplify = simplify), simplify = FALSE) { if(length(ns) == 0) return(character()) i = which(names(ns) == "") if(length(i)) ns[i] else character() # val = unlist(sapply(ns, function(x) if(x$id == "") x$uri)) # if(length(val)) # val[1] # else # character() } matchNamespaces = # d = xmlTreeParse("data/namespaces.xml", useInternal = TRUE) # "omg" # c("ns", "omegahat", "r") # c("ns", omegahat = "http://www.omegahat.net", "r") # c("ns" = "http://www.omegahat.net", "omg" = "http://www.omegahat.net/XML", "r") # # Error because z and rs are not defined in the document. # matchNamespaces(d, c("omg", "z", "rs")) # # function(doc, namespaces, nsDefs = xmlNamespaceDefinitions(doc, recursive = TRUE, simplify = FALSE), defaultNs = getDefaultNamespace(doc, simplify = TRUE) ) { # 3 cases: # i) we are given a single string (e.g. "r") which we use as a prefix for the default namespace # ii) we are given a vector of namespaces, but one has no name and we want to use that as the # prefix for the default namespace # e.g. sum(names(namespaces) == "") == 1) # iii) given several elements with no name and we match these to those in the document # if the first doesn't have a match, we use it as the default one. # iv) mixture of prefix = uri values and strings with no names. # # if it is a single "prefix" and we have a default namespace, then map the prefix to the default URI # and return. if(is.character(namespaces) && length(namespaces) == 1 && is.null(names(namespaces)) && length(defaultNs) > 0) { tmp = defaultNs names(tmp)[names(tmp) == ""] = namespaces # make certain to convert to c(id = url) form from an XMLNamespaceDefinition tmp = as(tmp[[1]], "character") # if no name, so default namespace, then use the one in namespaces. if(length(names(tmp)) == 0 || names(tmp) == "") names(tmp) = namespaces return(tmp) } # fix the names so that we have empty ones if we have none at all. if(is.null(names(namespaces))) names(namespaces) = rep("", length(namespaces)) # which need to be fixed up. i = (names(namespaces) == "") if(any(i)) { # from parameters now: nsDefs = xmlNamespaceDefinitions(xmlRoot(doc), recursive = TRUE) # deal with the first one as a special case. If this has no match, # we will map it to the default namespace's URI. if(i[1] && length(defaultNs) && is.na(match(namespaces[1], names(nsDefs)))) { names(namespaces)[1] = namespaces[1] namespaces[1] = defaultNs msg = paste("using", names(namespaces)[1], "as prefix for default namespace", defaultNs) e = simpleWarning(msg) class(e) = c("XPathDefaultNamespace", class(e)) warning(e) i[1] = FALSE } if(sum(i) > 0) { # So there is at least one namespace without a name. # See if there are duplicates dups = names(nsDefs)[duplicated(names(nsDefs))] tmp = match(namespaces[i], dups) if(length(dups) > 0 && any(is.na(tmp))) stop("duplicate namespaces, so cannot match namespace prefix(es) ", paste(namespaces[i][is.na(tmp)], collapse = ", "), " in ", paste(unique(names(nsDefs)), collapse= ", ")) idx = match(namespaces[i], names(nsDefs)) if(any(is.na(idx))) stop("cannot find defined namespace(s) with prefix(es) ", paste(namespaces[i][is.na(idx)], collapse = ", ")) names(namespaces)[i] = namespaces[i] namespaces[i] = sapply(nsDefs[idx], function(x) x$uri) # warning("namespaces without a name/prefix are not handled as you might expect in XPath. Use a prefix") } else if(length(defaultNs) == 0) stop("There is no default namespace on the target XML document") } if(!is.character(namespaces) || ( length(namespaces) > 1 && length(names(namespaces)) == 0)) stop("Namespaces must be a named character vector") if(length(namespaces) && (length(names(namespaces)) == 0 || any(names(namespaces) == ""))) warning("namespaces without a name/prefix are not handled as you might expect in XPath. Use a prefix") namespaces } getNodeSet = function(doc, path, namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), fun = NULL, sessionEncoding = CE_NATIVE, addFinalizer = NA, ...) { xpathApply(doc, path, fun, ..., namespaces = namespaces, sessionEncoding = sessionEncoding, addFinalizer = addFinalizer) } xpathSApply = function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, simplify = TRUE, addFinalizer = NA) { answer = xpathApply(doc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces, addFinalizer = addFinalizer) # Taken from sapply if (simplify && length(answer) && length(common.len <- unique(unlist(lapply(answer, length)))) == 1) { if (common.len == 1) unlist(answer, recursive = FALSE) else if (common.len > 1) array(unlist(answer, recursive = FALSE), dim = c(common.len, length(answer)), dimnames = if (!(is.null(n1 <- names(answer[[1]])) & is.null(n2 <- names(answer)))) list(n1, n2)) else answer } else answer } xpathApply = # # the caller can give the same prefixes of the namespaces defined in # the target document as simple names. # # xpathApply(d, "/o:a//c:c", fun = NULL, namespaces = c("o", "c")) # # function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list()) { UseMethod("xpathApply") } xpathApply.XMLNode = function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list()) { stop("xpathApply/xpathSApply/getNodeSet require an XML/HTML internal document or node. Use xmlParse() or htmlParse()") } toXMLNode = # # For taking an internal node and converting it to an R-level node # function(x, ...) { txt = saveXML(x) xmlRoot(xmlTreeParse(txt, asText = TRUE)) } xpathApply.XMLNode = function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list(), .node = NULL, noMatchOkay = FALSE) { idoc = xmlParse(saveXML(doc), asText = TRUE) ans = xpathApply(idoc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces, .node = .node, noMatchOkay = noMatchOkay, xpathFuns = xpathFuns) # Now convert the results if(length(ans)) ans = lapply(ans, toXMLNode) ans } xpathApply.XMLInternalDocument = function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list(), .node = NULL, noMatchOkay = FALSE, sessionEncoding = CE_NATIVE, noResultOk = FALSE) # native { path = paste(path, collapse = " | ") if(is(namespaces, "list") && all(sapply(namespaces, is, "XMLNamespaceDefinition"))) { namespaces = structure(sapply(namespaces, `[[`, "uri"), names = names(namespaces)) } if(resolveNamespaces && !inherits( namespaces, "XMLNamespaceDefinitions")) namespaces = matchNamespaces(doc, namespaces) if(!is.null(fun) && !is.call(fun)) fun = match.fun(fun) # create an expression of the form fun(x, ...) and the C code will insert x for each node. args = list(...) if(length(args)) fun = as.call(c(fun, append(1, args))) #XXX Match the session encoding c("native" = 0, utf8 = 1, latin1 = 2) encoding = if(is.integer(sessionEncoding)) sessionEncoding else getEncodingREnum(sessionEncoding) anonFuns = NULL if(is.character(xpathFuns)) xpathFuns = as.list(xpathFuns) else anonFuns = xpathFuns[ vapply(xpathFuns, is.function, FALSE) ] ans = .Call("RS_XML_xpathEval", doc, .node, as.character(path), namespaces, fun, encoding, addFinalizer, xpathFuns, anonFuns, PACKAGE = "XML") if(!noMatchOkay && length(ans) == 0 && length(getDefaultNamespace(xmlRoot(doc))) > 0) { tmp = strsplit(path, "/")[[1]] # if they have a function call, ignore. tmp = tmp[ - grep("\\(", path) ] if(length(grep(":", tmp)) != length(tmp) && !noResultOk) warning("the XPath query has no namespace, but the target document has a default namespace. This is often an error and may explain why you obtained no results") } ans } xmlDoc = function(node, addFinalizer = TRUE) { if(!is(node, "XMLInternalElementNode")) stop("xmlDoc must be passed an internal XML node") doc = .Call("RS_XML_createDocFromNode", node, PACKAGE = "XML") addDocFinalizer(doc, addFinalizer) doc } # Used to use # getDefaultNamespace(doc) if(FALSE) { xpathApply.XMLInternalNode = # # There are several situations here. # We/libxml2 needs a document to search. # We have a node. If we use its document, all is fine, but the # search will be over the entire document. We may get nodes from other sub-trees # that do not pertain to our starting point (doc). # Alternatively, we can create a new doc with this node as the top-level node # and do the search. But then we end up with new nodes. So if you want to find # nodes in the original document in order to change them rather than just read information # from them, then you will be sorely mistaken when you think your changes have been applied # to the original document. # # Regardless of what we do, we still have to figure out the adding of the doc attribute. # function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE) { addDocAttribute = FALSE # This is a wholesale copy. addDocAttribute = TRUE doc = xmlDoc(doc, TRUE) # # If the doc is already there, can't we just use that without copying it? Yes. # XXX maybe not. Looks like libxml2 starts at the top of the doc again. # But if there is no doc for this node, then we create a new doc and # put a finalizer on it. But we attach the document as an attribute to each of the # the resulting nodes. Then it will be protected from gc() and so will the nodes # until each of the nodes are released. #XXX??? What if we do a subsequent search on another of these nodes. # Then need to add it to the results. if(FALSE) { tmp = as(doc, "XMLInternalDocument") addDocAttribute = is.null(tmp) if(is.null(tmp)) { if(!is.null(attr(doc, "document"))) doc = attr(doc, "document") else doc = newXMLDoc(node = doc) # if we used xmlDoc(doc), no finalizer. } else doc = tmp } ans = xpathApply(doc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces) if(addDocAttribute && length(ans)) ans = lapply(ans, function(x) { attr(x, "document") = doc; x}) ans } } # end if if(FALSE) getRootNode = function(node) { p = node while(!is.null(xmlParent(p))) p = xmlParent(p) p } xpathApply.XMLInternalNode = xpathSubNodeApply = # # This allows us to use XPath to search within a sub-tree of the document, i.e. # from a particular node. # This is slightly tricky because the libxml2 routines require a document to search. # We could copy the nodes to a new document, e.g. # xmlDoc(node) # but then the results would be for new nodes, not the original ones. # So we would not be able to find nodes and then modify them as we would be modifying the # copies. # # If this what is desired, use # doc = xmlDoc(node) # xpathApply(doc, xpath, ...) # and then that is what you will get. # # In the case that you want the original nodes in the result, # then we have to do a little bit of work. We create a new document # and set the source node as its root node. We arrange to # a) put the node back where it came from and b) free the document. # So there is no memory leak. # # The other thing we must do is to find the # # # This version avoids doing any copying of nodes when there is a document already # associated with the nodes. # function(doc, path, fun = NULL, ..., namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list()) { path = paste(path, collapse = " | ") node = doc addDocAttribute = FALSE createdNewDocument = FALSE tmp = as(doc, "XMLInternalDocument") putBack = function(node, info) { if(!is.null(info$left)) addSibling(info$left, node) else if(!is.null(info$right)) addSibling(info$right, node, after = FALSE) else if(!is.null(info$parent)) addChildren(info$parent, node) else if(!is.null(tmp)) addChildren(tmp, node) } info = list(parent = xmlParent(node), left = getSibling(node, after = FALSE), right = getSibling(node, after = TRUE)) # The approaches here are to create a new empty document and then set the node # to be its root. We don't set the document for each of the sub-nodes but just this # top-level node. Then we arrange that when we end this function, we discard the # newly created document and put the node back into the original tree in its # original position. # This involves knowing the parent and the position at which to put the node back into the tree. # If it is the top most node, i.e. no parent, then it is simple - just set the parent back to NULL. # If it has a parent, but no siblings, just set the parent. # And if it has a sibling, put it back next to that sibling. # If it is the first child, put to the left of the sibling. # If it is not, put to the right. # Need to make certain the resulting nodes have the original document # Use xmlSetTreeDoc rather than node->doc = node as this is recursive. # And so this is now all done in the on.exit() via the call to RS_XML_setDocEl() # doc = newXMLDoc(node = node, addFinalizer = getNativeSymbolInfo("R_xmlFreeDocLeaveChildren")$address) doc = newXMLDoc(addFinalizer = FALSE) parent = xmlParent(node) .Call("RS_XML_setRootNode", doc, node, PACKAGE = "XML") on.exit({ .Call("RS_XML_unsetDoc", node, unlink = TRUE, parent, TRUE, PACKAGE = "XML") .Call("RS_XML_freeDoc", doc, PACKAGE = "XML") if(!is.null(tmp)) { # Need to create a new document with the current node as the root. # When we are finished, we have to ensure that we put the node back into the original document # We can use the same mechanism as when we have to create the document from scratch. .Call("RS_XML_setDocEl", node, tmp, PACKAGE = "XML") } putBack(node, info) }) docName(doc) = paste("created for xpathApply for", path, "in node", xmlName(node)) ans = xpathApply(doc, path, NULL, namespaces = namespaces, resolveNamespaces = resolveNamespaces, addFinalizer = addFinalizer, xpathFuns = xpathFuns) if(length(ans) == 0) return(ans) # now check if the result was actually a descendant of our top-level node for this # query. It is possible that it arose from a different sub-tree. w = sapply(ans, function(el) .Call("RS_XML_isDescendantOf", el, node, strict = FALSE, PACKAGE = "XML")) ans = ans[w] # if(FALSE && addDocAttribute && length(ans)) # ans = lapply(ans, function(x) { attr(x, "document") = doc; x}) # if(createdNewDocument) # # Need to remove the links from these nodes to the parent. # lapply(ans, function(x) .Call("RS_XML_unsetDoc", x, unlink = FALSE, TRUE)) if(!is.null(fun)) lapply(ans, fun, ...) else ans } if(TRUE) xpathApply.XMLInternalNode = function(doc, path, fun = NULL, ..., namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list()) { ndoc = as(doc, "XMLInternalDocument") if(is.null(ndoc)) xpathSubNodeApply(doc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces, addFinalizer = addFinalizer, xpathFuns = xpathFuns) else xpathApply.XMLInternalDocument(ndoc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces, .node = doc, addFinalizer = addFinalizer, xpathFuns = xpathFuns) } xpathApply.XMLDocument = #xpathApply.XMLNode = function(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, .node = NULL, addFinalizer = NA, xpathFuns = list()) { txt = saveXML(doc) doc = xmlParse(txt, asText = TRUE) ans = xpathApply(doc, path, fun, ..., namespaces = namespaces, resolveNamespaces = resolveNamespaces, .node = .node, addFinalizer = addFinalizer, xpathFuns = xpathFuns) if(length(ans)) ans = lapply(ans, toXMLNode) ans # stop("XPath expressions cannot be applied to R-level nodes. Use xmlParse() to process the document and then use xpathApply()") } # d = xmlTreeParse("data/book.xml", useInternal = TRUE) # ch = getNodeSet(d, "//chapter") # xpathApply(ch[[1]], "//section/title", xmlValue) # d = xmlTreeParse("data/mtcars.xml", useIntern = TRUE); z = getNodeSet(d, "/dataset/variables") # xpathApply(z[[1]], "variable[@unit]", NULL, namespaces = character()) getXMLPath = function(node, defaultPrefix = "ns") { paste(unlist(c("", xmlAncestors(node, xmlName, defaultPrefix))), collapse = "/") } xmlAncestors = function(x, fun = NULL, ..., addFinalizer = NA, count = -1L) { ans = list() tmp = x while(!is.null(tmp)) { if(!is.null(fun)) ans = c(fun(tmp, ...), ans) else ans = c(tmp, ans) if(count > 0 && length(ans) == count) break tmp = xmlParent(tmp, addFinalizer = addFinalizer) } ans } XML/R/xmlString.R0000644000175100001440000000415013607633674013262 0ustar hornikuserssetClass("XMLString", contains = "character") xml = function(x) { new("XMLString", x) } isXMLString = function(str) { is(str, "XMLString") || length(grep("<([a-zA-Z]+:)?[a-zA-Z]+(/?>| [a-zA-Z]+=[\"'])", str)) > 0 } RXMLNamespaces = c(r = "http://www.r-project.org", rh = "http://www.r-project.org/help") xmlParseString = # # have to do some trickery with garbage collection to avoid parsing # the tree and handing back a node within that that will be freed # when the top-level document is GC'ed # # If the caller gives us the target document, we parent the nodes # into that and all is well. # Otherwise, we have trouble and potential leak at present as we # explicitly kill off the finalizer. # # This should be cured now in the XML package. # function(content, doc = NULL, namespaces = RXMLNamespaces, clean = TRUE, addFinalizer = NA) { f = function(cdata = FALSE) newXMLNode("para", newXMLTextNode(content, cdata = cdata, doc = doc), doc = doc) # If the user has told us explicitly that this is not XML but raw text # then put it into a para enclosed within CDATA, just in case. if(inherits(content, "AsIs")) return(f(TRUE)) if(!isXMLString(content)) return(f(TRUE)) content = as(content, "XMLString") ns = paste(paste("xmlns", names(RXMLNamespaces), sep = ":"), sprintf('"%s"', RXMLNamespaces), sep = "=", collapse = " ") txt = paste('', content, "", sep = "") local.doc = tryCatch(xmlParse(txt, addFinalizer = addFinalizer), # addFinalizer = !inherits(doc, "XMLInternalDocument") error = function(e) e) if(inherits(local.doc, "condition")) return(f(TRUE)) tmp = xmlRoot(local.doc) if(xmlSize(tmp) == 1) # inherits(tmp[[1]], "XMLInternalElementNode") && xmlName(tmp[[1]]) == "para") tmp = tmp[[1]] if(clean) removeXMLNamespaces(tmp, .els = names(namespaces)) # XXX if(inherits(doc, "XMLInternalDocument")) { manageMemory = manageMemory_p(addFinalizer) .Call("RS_XML_copyNodesToDoc", tmp, doc, addFinalizer, PACKAGE = "XML") } else tmp } XML/R/xincludes.R0000644000175100001440000000622513607633674013276 0ustar hornikusers setGeneric("findXIncludeStartNodes", function(doc, ...) { standardGeneric("findXIncludeStartNodes") }) setMethod("findXIncludeStartNodes", "character", function(doc, ...) { findXIncludeStartNodes(xmlParse(doc), ...) }) setMethod("findXIncludeStartNodes", "XMLInternalDocument", function(doc, ...) { findXIncludeStartNodes(xmlRoot(doc), ...) }) setMethod("findXIncludeStartNodes", "XMLInternalElementNode", function(doc, ...) { nodes = .Call("R_findXIncludeStartNodes", xmlRoot(doc), PACKAGE = "XML") names(nodes) = sapply(nodes, xmlGetAttr, "href", NA) nodes }) findXInclude = function(x, asNode = FALSE, recursive = FALSE) { while(!is.null(x)) { tmp = getSiblingXIncludeStart(x, TRUE) if(!is.null(tmp)) return(fixFindXInclude(tmp, asNode, recursive)) sib = x if(is(sib, "XMLXIncludeStartNode")) return(fixFindXInclude(sib, asNode, recursive)) # if(asNode) sib else xmlAttrs(sib)) x = xmlParent(x) } fixFindXInclude(x, asNode, recursive) } bad.findXInclude = # This version just looks in the left sibling, not all siblings to the left. function(x, asNode = FALSE, recursive = FALSE) { ans = NULL while(!is.null(x)) { prev = getSiblingXIncludeStart(x, FALSE) if(inherits(prev, "XMLXIncludeStartNode")) { ans = prev break } x = xmlParent(x) } fixFindXInclude(ans, asNode, recursive) } fixFindXInclude = function(ans, asNode = FALSE, recursive = FALSE) { if(is.null(ans)) return(NULL) if(recursive) { tmp = getXIncludePath(ans) if(FALSE && grepl(sprintf("^(%s|http:|ftp:)", .Platform$file.sep), tmp)) tmp else sprintf("%s%s%s", paste(dirname(unique(tmp)), collapse = .Platform$file.sep), .Platform$file.sep, xmlAttrs(ans)) } else if(asNode) ans else xmlAttrs(ans)["href"] } getXIncludePath = function(node) { x = xmlParent(node) ans = character() while(!is.null(x)) { ans = c(ans, findXInclude(x)) prev = x x = xmlParent(x) } c(docName(prev), ans) } getSiblingXIncludeStart = function(x, asNode = FALSE) { sib = x while(!is.null(sib)) { if(inherits(sib, "XMLXIncludeEndNode")) return(NULL) if(inherits(sib, "XMLXIncludeStartNode")) return(if(asNode) sib else xmlAttrs(sib)) sib <- getSibling(sib, FALSE) } NULL } getNodePosition = function(x) { if(is.list(x)) return(sapply(x, getNodePosition)) tmp = getNodeLocation(x) sprintf("%s:%d", tmp$file[1], tmp$line) } getNodeLocation = function(node, recursive = TRUE, fileOnly = FALSE) { if(is.list(node)) return(lapply(node, getNodeLocation, recursive, fileOnly)) fil = findXInclude(node, recursive = recursive) if(is.null(fil)) fil = docName(node) if(fileOnly) fil[1] else list(file = fil, line = getLineNumber(node)) } getLineNumber = function(node, ...) { if(!is(node, "XMLInternalNode")) stop("This must be an C-level/native/internal XML node, i.e. of class 'XMLInternalNode'. Got ", paste(class(node), collapse = ", ")) .Call("R_getLineNumber", node, PACKAGE = "XML") } XML/R/tangle1.R0000644000175100001440000000107313607633674012627 0ustar hornikuserstangleR = xxx_getRCode = # conflicts with getRCode in xmlInternalSource.R function(doc, tags = c("code", "plot", "function"), out = gsub("\\.[a-zA-Z]+$", ".R", docName(doc))) { if(is.character(doc)) doc = xmlParse(doc) xp = sprintf("//r:%s[not(@eval='false') and not(ancestor::section[@eval='false'])]", tags) code = xpathSApply(doc, paste(xp, collapse = " | "), xmlValue, namespaces = c("r" = "http://www.r-project.org")) if(length(out) && !is.na(out)) { cat(code, sep = "\n", file = out) out } else code } XML/R/getRelativeURL.R0000644000175100001440000000403113610555150014111 0ustar hornikusersgetRelativeURL = # # takes the name of a file/URL and a baseURL and # figures out the URL for the new file given by u. # This handles the case where the file/URL is relative to the # the baseURL or if it is a fully qualified file or URL. # # getRelativeURL("/foo", "http://www.omegahat.net") # getRelativeURL("/foo", "http://www.omegahat.net/") # getRelativeURL("foo", "http://www.omegahat.net/") # getRelativeURL("http://www.foo.org", "http://www.omegahat.net/") # # XXX test - baseURL with /path/ and u as /other/path. Looks okay. See # ParsingStrategies example for kaggle. # getRelativeURL("../foo/xyz/bar.html", "http://www.omegahat.net/a/b.html") # getRelativeURL("./foo/xyz/bar.html", "http://www.omegahat.net/a/b.html") # getRelativeURL("../foo/xyz/bar.html", "http://www.omegahat.net/a/b.html") # # # BROKEN # getRelativeURL("foo", ".") yields :///foo # # # [Fixed] not working for ../... # fails # getRelativeURL("../foo", "http://www.omegahat.net/a/b.html") # should be http://www.omegahat.net/foo # or at least http://www.omegahat.net/a/../foo function(u, baseURL, sep = "/", addBase = TRUE, simplify = TRUE, escapeQuery = FALSE) { if(length(u) > 1) return(sapply(u, getRelativeURL, baseURL, sep)) pu = parseURI(u) #XXX Need to strip the path in baseURL if pu$path starts with / if(pu$scheme == "" && addBase) { b = parseURI(baseURL) b$query = "" if(grepl("^/", pu$path)) { b$path = u return(as(b, "character")) } endsWithSlash = grepl("/$", b$path) if(endsWithSlash && grepl("^\\./", u)) u = substring(u, 3) b$path = sprintf("%s%s%s", if(endsWithSlash) b$path else dirname(b$path), if(endsWithSlash) "" else sep, u) # handle .. in the path and try to collapse these. if(simplify && grepl("..", b$path, fixed = TRUE)) b$path = simplifyPath(b$path) return(as(b, "character")) # b = as(b, "character") # sprintf("%s%s%s", b, "" else sep, u) } else u } XML/R/simplifyPath.R0000644000175100001440000000256013607633705013742 0ustar hornikuserssimplifyPath = # Could use strsplit, etc. # simplifyPath2("XMLBasics/../WebTechData/RawData/KyphosisRpartExtract.xml") # simplifyPath2("../WebTechData/RawData/KyphosisRpartExtract.xml") # simplifyPath2("../../WebTechData/RawData/KyphosisRpartExtract.xml") # simplifyPath2("a/b/../../WebTechData/RawData/KyphosisRpartExtract.xml") # simplifyPath2("top/a/b/../../WebTechData/RawData/KyphosisRpartExtract.xml") # simplifyPath2("abc/../../WebTechData/RawData/KyphosisRpartExtract.xml") function(path) { els = strsplit(path, "/")[[1]] GoOn = TRUE els = els[ els != "."] while(GoOn && length(i <- which(els == ".."))) { i = min(i) if(length(i) == 1 && i == 1) break if(all(els[ seq( 1, i) ] == "..")) break if(i == 2 && els[1] == "..") break els = els[ - c(i, i - 1L) ] } paste(els, collapse = "/") } if(FALSE) { simplifyPath = function(path) { path = gsub("/\\./", "/", path) path = gsub("^\\./", "", path) # Doesn't handle "../foo" while(grepl("[^./]/\\.\\.", path)) { path = gsub("/[^/.]+/\\.\\./?", "/", path) } path = gsub("^(\\./)+", "", path) path } simplifyPath1 = # Could use strsplit, etc. function(path) { els = strsplit(path, "/")[[1]] while(length(i <- which(els == ".."))) { i = max(i) if(length(i) == 1 && i == 1) break i = i[i != 1] } paste(els, sep = "/") } } XML/R/DTDClasses.R0000644000175100001440000000450613607633665013231 0ustar hornikusers# # Some methods for the DTD classes, similar in spirit # to those in XMLClasses # # print() # # # # XMLSystemEntity # XMLEntity # XMLElementDef # XMLSequenceContent # XMLOrContent # XMLElementContent # XMLAttributeDef # print.XMLElementDef <- function(x, ...) { cat("\n") if(length(x$attributes)) { cat("\n") } } print.XMLElementContent <- function(x, ...) { if(names(x$type)[1] == "PCData") { cat(" ( #PCDATA ) ") return() } cat("(") cat(x$elements) cat(")",switch(names(x$ocur)[1],Once="", "One or More"="+","Zero or One"="?","Mult"="*")) } print.XMLOrContent <- function(x, ...) { n <- length(x$elements) cat("( ") for(i in 1:n) { print(x$elements[[i]]) if(i < n) cat(" | ") } cat(" )") } print.XMLSequenceContent <- function(x, ...) { cat("( ") n <- length(x$elements) for(i in 1:n) { print(x$elements[[i]]) if(i < n) cat(", ") } cat(" )") } print.XMLAttributeDef <- function(x, ...) { if(names(x$defaultType)[1] != "Implied") dflt <- paste("\"", x$defaultValue,"\"",collapse="",sep="") else dflt <- "" cat(x$name, xmlAttributeType(x), xmlAttributeType(x, TRUE), dflt) } xmlAttributeType <- function(def, defaultType = FALSE) { if(defaultType == FALSE & names(def$type)[1] == "Enumeration") { return( paste("(",paste(def$defaultValue,collapse=" | "),")", sep=" ", collapse="") ) } switch(ifelse(defaultType, names(def$defaultType)[1], names(def$type)[1]), "Fixed" = "#FIXED", "CDATA" = "CDATA", "Implied" = "#IMPLIED", "Required" = "#REQUIRED", "Id" = "#ID", "IDRef" = "#IDREF", "IDRefs" = "#IDREFS", "Entity" = "#ENTITY", "Entities" = "ENTITIES", "NMToken" = "#NMTOKEN", "NMTokens" = "#NMTOKENS", "Enumeration" = "", "Notation" = "", "" ) } print.XMLEntity <- function(x, ...) { cat("\n") } xmlAttrs.XMLElementDef <- function(node, ...) { node$attributes } if(useS4) { setGeneric("xmlAttrs", function(node, ...) standardGeneric("xmlAttrs")) setMethod("xmlAttrs", "XMLElementDef", xmlAttrs.XMLElementDef) } XML/R/AAA.R0000644000175100001440000000001613607633702011642 0ustar hornikusersuseS4 = FALSE XML/R/htmlLinks.R0000644000175100001440000000227613607633670013243 0ustar hornikusersreadHTMLLinks = getHTMLLinks = function(doc, externalOnly = TRUE, xpQuery = "//a/@href", baseURL = docName(doc), relative = FALSE) { if(is.character(doc)) doc = htmlParse(doc) # put a . in front of the xpQuery if we have a node rather than a document. if(is(doc, "XMLInternalNode") && grepl("^/", xpQuery)) xpQuery = sprintf(".%s", xpQuery) links = as.character(getNodeSet(doc, xpQuery)) links = if(externalOnly) grep("^#", links, value = TRUE, invert = TRUE) else links #XXX Put base URL onto these links, relative! if(relative) sapply(links, getRelativeURL, baseURL) else links } getHTMLExternalFiles = function(doc, xpQuery = c("//img/@src", "//link/@href", "//script/@href", "//embed/@src"), baseURL = docName(doc), relative = FALSE, asNodes = FALSE, recursive = FALSE) { if(is.character(doc)) doc = htmlParse(doc) if(asNodes) xpQuery = gsub("/@[a-zA-Z-]$+", "", xpQuery) nodes = getNodeSet(doc, xpQuery) if(asNodes) return(nodes) nodes = as.character(nodes) ans = if(relative) getRelativeURL(nodes, baseURL) else nodes # recursive. ans } XML/R/xmlInternalSource.R0000644000175100001440000005376513610555150014753 0ustar hornikusers #XXX Deal with line numbers in the original document. # # We could also do things this way # source(textConnection(saveXML(xsltApplyStyleSheet("cityTemperatures.xml", "~/Projects/org/omegahat/XML/Literate/segment.xsl")))) # # # Allow the user to specify a subset of nodes in which to find the code, etc. nodes. # Or an XPath query to restrict the search. # For example, suppose we have a document with two sections and we want to run the code # in only one of those sections. # getNodeSet(section[@id='second one']) # setOldClass("XMLNodeSet") DefaultXPathNamespaces = c(r = "http://www.r-project.org", s = "http://cm.bell-labs.com/stat/S4", omg = "http://www.omegahat.net", mlb = "http://www.mathworks.com", # matlab sh="http://www.shell.org", perl = "http://www.perl.org", py = "http://www.python.org", fo="http://www.w3.org/1999/XSL/Format", xsl="http://www.w3.org/1999/XSL/Transform", xi="http://www.w3.org/2001/XInclude" ) DefaultXMLSourceXPath = sprintf("%s[not(@eval='false') and not(ancestor::ignore) and not(ancestor::section[@r:eval = 'false'])]", c("//r:init", "//r:function", "//r:init", "//r:code", "//r:plot", "//r:expr")) setGeneric("xmlSource", function(url, ..., envir = globalenv(), xpath = character(), ids = character(), omit = character(), ask = FALSE, example = NA, fatal = TRUE, verbose = TRUE, echo = verbose, print = echo, xnodes = DefaultXMLSourceXPath, namespaces = DefaultXPathNamespaces, section = character(), eval = TRUE, init = TRUE, setNodeNames = FALSE, parse = TRUE, force = FALSE) { standardGeneric("xmlSource") }) # Break up into methods for character and xmlInternalDocument setMethod("xmlSource", c("character"), function(url, ..., envir =globalenv(), xpath = character(), ids = character(), omit = character(), ask = FALSE, example = NA, fatal = TRUE, verbose = TRUE, echo = verbose, print = echo, xnodes = DefaultXMLSourceXPath, namespaces = DefaultXPathNamespaces, section = character(), eval = TRUE, init = TRUE, setNodeNames = FALSE, parse = TRUE, force = FALSE) { doc = xmlTreeParse(url, ..., useInternalNodes = TRUE) xmlSource(doc, ..., envir = envir, xpath = xpath, ids = ids, omit = omit, ask = ask, example = example, fatal = fatal, verbose = verbose, print = print, xnodes = xnodes, namespaces = namespaces, section = section, eval = eval, init = init, setNodeNames = setNodeNames, parse = parse, force = force) }) setMethod("xmlSource", c("XMLInternalDocument"), function(url, ..., envir =globalenv(), xpath = character(), ids = character(), omit = character(), ask = FALSE, example = NA, fatal = TRUE, verbose = TRUE, echo = verbose, print = echo, xnodes = DefaultXMLSourceXPath, namespaces = DefaultXPathNamespaces, section = character(), eval = TRUE, init = TRUE, setNodeNames = FALSE, parse = TRUE, force = FALSE) { doc = url if(inherits(verbose, "numeric")) verbose = verbose - 1 if(!is.character(section)) section = as.integer(section) #XXX use section when processing the examples if(length(example) && !all(is.na(example))) { egs = getNodeSet(doc, "//r:example", namespaces) if(length(egs)) { ids = sapply(egs, xmlGetAttr, "id") if(length(example) == 1 && is.na(example)) { cat("Select an example\n") example = ids[w <- menu(ids)] } if(inherits(example, "numeric")) { i = example } else { i = pmatch(example, ids) if(all(is.na(i))) stop("no example named ", example) } # find any r:init nodes which are not inside an example. init = getNodeSet(doc, "//r:init[not(ancestor::r:example)]", c(r = "http://www.r-project.org")) if(length(init)) { xmlSource(init, envir = envir, omit = omit, verbose = verbose, namespaces = namespaces, eval = eval, force = force) cat("Done doc-level init", length(init), "\n") } ans = sapply(i, function(x) { nodes = getNodeSet(egs[[x]], paste(xnodes, collapse = "|"), namespaces) if(verbose) cat("Example", ids[x], "\n") #XXX put the correct ids in her. xmlSource(nodes, envir = envir, omit = omit, verbose = verbose, namespaces = namespaces, eval = eval, setNodeNames = setNodeNames, parse = parse, force = force) }) return(ans) } } # if(length(section) && is.character(section)) # section = paste("@id", ddQuote(section), sep = "=") if(length(xpath)) { # do an XPath query and then look inside the resulting nodes # for the xnodes of interest. if(length(section)) { # XXX assumes just one section. What about c(1, 2, 4) xpath =paste("//section[", section, "]", xpath, sep = "") } nodes = getNodeSet(doc, xpath, namespaces) v = unlist(lapply(nodes, function(n) { unlist(lapply(xnodes, function(p) getNodeSet(n, p, namespaces)), recursive = FALSE) }), recursive = FALSE) } else { functions = limitXPathToSection(section, "//r:function[not(@eval = 'false') and not(ancestor::ignore)]") xnodes = limitXPathToSection(section, xnodes) # Do we need to ensure the order for the functions first? v = getNodeSet(doc, paste(c(functions, xnodes), collapse = "|"), namespaces) # v = getNodeSet(doc, functions, namespaces) # w = getNodeSet(doc, xnodes, namespaces) # v = c(v, w) } if(is.null(v)) stop("No matching nodes in the document found") class(v) <- "XMLNodeSet" # deal with a top-level node r:codeIds which is of the form # abc # def # ghi # i.e. a single entry on each line which identifies the nodes that are to be read. if(missing(ids) && missing(xnodes) && length(ids <- getNodeSet(doc, "/*/r:codeIds|/*/invisible/r:codeIds", namespaces = c(r = "http://www.r-project.org")))) { if(length(ids) > 1) { warning("more than one r:codeIds node. Using the first one") } # txt = paste(sapply(ids, xmlValue)) ids = strsplit(xmlValue(ids[[1]]), "\\\n")[[1]] ids = unique(ids) ids = ids[ids != ""] } xmlSource(v, ids = ids, omit = omit, ask = ask, fatal = fatal, verbose = verbose, envir = envir, section = if(!is.character(section)) section else character(), eval = eval, setNodeNames = setNodeNames, parse = parse, force = force) }) limitXPathToSection = # # limitToSection(1:3) # limitToSection(letters[1:3]) # limitToSection(letters[1:3], "//r:plot") function(section, xpath = c("//r:code", "//r:func", "//r:plot", "//r:expr")) { if(length(section) == 0) return(paste(xpath, collapse = "|")) if(is.character(section)) section = paste("@id=", sQuote(section), sep = "") paste(outer(section, xpath, function(sect, xp) paste("//section[", sect, "]", xp, sep = "")), collapse = "|") } setMethod("xmlSource", "XMLNodeSet", function(url, ..., envir =globalenv(), xpath = character(), ids = character(), omit = character(), ask = FALSE, example = NA, fatal = TRUE, verbose = TRUE, echo = verbose, print = echo, xnodes = c("r:function[not(@val='false')]", "r:init[not(@eval='false')]", "r:code[not(@eval='false')]", "//r:plot[not(@eval='false')]"), namespaces = DefaultXPathNamespaces, section = character(), eval = TRUE, init = TRUE, setNodeNames = FALSE, parse = TRUE, force = FALSE) { if(ask) { doc = as(url[[1]], "XMLInternalDocument") #XXXX no doc here now. v = getNodeSet(doc, "//r:function|//r:init|//r:code|//r:plot", namespaces) funs = sapply(v, xmlName) == "function" if(any(funs)) { #XXX } } ans = sapply(url, evalNode, envir = envir, verbose = verbose, ids = ids, omit = omit, echo = echo, print = print, ask = ask, eval = eval, parse = parse, force = force) if(setNodeNames) names(ans) = sapply(url, getRCodeNodeName) else names(ans) = sapply(url, getNodePosition) #sapply(url, xmlName, full = TRUE) invisible(ans) }) evalNode = function(node, envir = globalenv(), ids = character(), verbose = FALSE, echo = verbose, omit = character(), namespaces = c(r = "http://www.r-project.org"), print = echo, ask = FALSE, eval = TRUE, parse = TRUE, force = FALSE) { #XXX check all ancestors. Ideally exclude them in the XPath query if(!force && (xmlName(xmlParent(node)) == "ignore" || length(getNodeSet(node, "./ancestor::section[@r:eval='false']|./ancestor::para[@r:eval='false']", c(r = "http://www.r-project.org"))) > 0)) return(FALSE) tmp = xmlGetAttr(node, "id", NA) if(is.na(tmp) && length(ids) > 0 && !("" %in% ids)) return() if(!is.na(tmp)) { if(length(omit) > 0 && tmp %in% omit) { if(verbose) warning("skipping id ", tmp) return() } else if(length(ids) > 0 && !(tmp %in% ids)) { if(verbose) warning("ignoring id ", tmp) return() } } tmp = xmlGetAttr(node, "ignore", NA, converter = as.logical) if(!is.na(tmp) && tmp) { if(verbose) warning("ignoring node", as(node, "character")) return() } # go through the node and see if there are any r:code nodes # with a ref attribute # and go fetch the corresponding node. txt = paste(getRCode(node, namespaces), collapse = "\n") if(!parse) return(txt) # txt = xmlValue(node) if(verbose) cat("*************\nEvaluating node\n") cmd = parse(text = txt) if(echo) print(cmd) if(eval) { if(ask) { w = utils::menu(c("evaluate", "skip", "terminate")) if(w == 2) return(NULL) else if(w == 3) stop("User terminated the xmlSource") } isPlot = xmlName(node) == "plot" if(isPlot) { f = xmlGetAttr(node, "img") if(!is.null(f)) { attrs = xmlAttrs(node) dev = openDevice(f, attrs) } if(!xmlGetAttr(node, "continuePlot", FALSE, as.logical)) on.exit(dev.off()) } ans = eval(cmd, envir) if(isPlot && inherits(ans, "trellis")) print(ans) ans } else cmd } openDevice = function(f, attrs) { if("format" %in% names(attrs)) ext = attrs["format"] else ext = getExtension(f) fun = switch(ext, png = png, jpeg = jpeg, pdf = pdf) args = lapply(c("width", "height"), getDevAttr, attrs, fun, as.numeric) cat("opening device for", f, "\n") fun(f) } getDevAttr = function(name, attrs, devFun, converter = as.character) { if(name %in% names(attrs)) converter(attrs[[name]]) else if(name %in% names(formals(devFun))) formals(devFun)[[name]] else converter(NA) } getExtension = function(f) { gsub(".*\\.", "", basename(f)) } getRCode = function(node, namespaces = c(r = "http://www.r-project.org"), recursive = TRUE, dropOutput = FALSE) { tmp = xmlSApply(node, function(x) { if(inherits(x, c("XMLInternalCommentNode", "XMLInternalPINode"))) { } else if(inherits(x, "XMLInternalElementNode") && xmlName(x, full = TRUE) %in% c("r:code", "r:frag")) { ref = xmlGetAttr(x, "ref", NA) if(!is.na(ref)) { v = getNodeSet(as(x, "XMLInternalDocument"), paste(sapply(c("code", "frag"), function(x) paste("//r:", x , "[@id='", ref, "']", sep = "")), collapse = "|"), namespaces) if(length(v) == 0) stop("No code block/fragment named ", ref) else if(length(v) > 1) stop("More than 1 code block/fragment named ", ref) else if(recursive) getRCode(v[[1]], namespaces, recursive = TRUE, dropOutput = dropOutput) else xmlValue(v[[1]]) } else { if(recursive) getRCode(x, namespaces, recursive = TRUE, dropOutput = dropOutput) else xmlValue(x) } } else if(inherits(x, "XMLInternalElementNode") && xmlName(x, full = TRUE) %in% c("r:error", "r:output")) { } else xmlValue(x) }) if(dropOutput && length(names(tmp))) tmp = tmp[names(tmp) != "output"] paste(tmp, collapse = "\n") } setClass("XMLCodeFile", contains = "character") setClass("XMLCodeDoc", contains = "XMLInternalDocument") setAs("XMLCodeFile", "XMLCodeDoc", function(from) { new("XMLCodeDoc", xmlParse(from)) }) setAs("character", "XMLCodeFile", function(from) { xmlCodeFile(from) }) setAs("character", "XMLCodeDoc", function(from) { xmlCodeFile(from, TRUE) }) xmlCodeFile = function(f, parse = FALSE) { if(parse) new("XMLCodeDoc", xmlParse(f)) else new("XMLCodeFile", f) } utils::globalVariables("use_file") tmp.source = function (file, local = FALSE, echo = verbose, print.eval = echo, verbose = getOption("verbose"), prompt.echo = getOption("prompt"), max.deparse.length = 150, chdir = FALSE, encoding = getOption("encoding"), continue.echo = getOption("continue"), skip.echo = 0, keep.source = getOption("keep.source")) { if(length(verbose) == 0) verbose = FALSE if(chdir) { cwd = getwd() on.exit(setwd(cwd)) setwd(dirname(file)) } xmlSource(file, verbose = verbose) } ## This version would require us to document source() ## setGeneric("source", function(file, ...) standardGeneric("source")) ## tmp.source = ## function (file, verbose = getOption("verbose"), chdir = FALSE, ...) ## { ## if(length(verbose) == 0) ## verbose = FALSE ## if(chdir) { ## cwd = getwd() ## on.exit(setwd(cwd)) ## setwd(dirname(file)) ## } ## xmlSource(file, verbose = verbose) ## } setMethod("source", "XMLCodeFile", tmp.source) setMethod("[[", "XMLCodeFile", function(x, i, j, ..., env = globalenv()) { doc = as(x, "XMLCodeDoc") n = getNodeSet(doc, paste("//*[@id=", sQuote(i), "]")) if(length(n) == 0) { # This needs code from ptoc to determine the name of an "element" ## was updateIds(doc, save = x), which was giving ## byte-compilation warnings in *other* packages. doc = updateIds(doc) } eval(parse(text = xmlValue(n[[1]])), envir = env) }) updateIds = function(doc, ...) { nodes = getNodeSet(doc, "//r:function[not(@id) and not(@eval = 'false')]|//r:code[not(@id) and not(@eval = 'false')]", c("r" = "http://www.r-project.org")) sapply(nodes, getCodeVar) } getCodeVar = function(node) { e = parse(text = getRCode(node)) e = e[[length(e)]] # This should use the code in ptoc in RTools. id = if(class(e) %in% c("=", "<-")) as.character(e[[2]]) else NA if(!is.na(id)) addAttributes(node, id = id) id } # # f = xmlCodeFile("~/Classes/stat242-08/Code/FormulaWeights/rpartScope.xml") # source(f) # f[["rpart.model"]] setGeneric("xmlSourceFunctions", function(doc, ids = character(), parse = TRUE, ...) { standardGeneric("xmlSourceFunctions") }) setMethod("xmlSourceFunctions", "character", # # evaluate the r:function nodes, or restricted to @id from ids. # function(doc, ids = character(), parse = TRUE, ...) { invisible(xmlSourceFunctions(xmlParse(doc), ids, parse = parse, ...)) }) sQuote = function(x) sprintf("'%s'", as.character(x)) setMethod("xmlSourceFunctions", "XMLInternalDocument", # # evaluate the r:function nodes, or restricted to @id from ids. # function(doc, ids = character(), parse = TRUE, setNodeNames = FALSE, ...) { if(length(ids)) nodes = getNodeSet(doc, paste("//r:function[", paste("@id", sQuote(ids), sep = "=", collapse = " or " ), "]"), c(r = "http://www.r-project.org")) else nodes = getNodeSet(doc, "//r:function[not(ancestor-or-self::*/@eval = 'false')]", c(r = "http://www.r-project.org")) if(parse == FALSE) return(nodes) ans = xmlSource(nodes, ...) if(setNodeNames) names(ans) = sapply(nodes, getRCodeNodeName) invisible(ans) }) getRCodeNodeName = function(node) { xmlGetAttr(node, "name", xmlGetAttr(node, "idx", getTaskId(node))) } ################ setGeneric("xmlSourceSection", function(doc, ids = character(), xnodes = c(".//r:function", ".//r:init[not(@eval='false')]", ".//r:code[not(@eval='false')]", ".//r:plot[not(@eval='false')]"), namespaces = DefaultXPathNamespaces, ...) standardGeneric("xmlSourceSection")) setMethod("xmlSourceSection", "character", function(doc, ids = character(), xnodes = c(".//r:function", ".//r:init[not(@eval='false')]", ".//r:code[not(@eval='false')]", ".//r:plot[not(@eval='false')]"), namespaces = DefaultXPathNamespaces, ...) xmlSourceSection(xmlParse(doc), ids, xnodes, namespaces, ...)) setMethod("xmlSourceSection", "XMLInternalDocument", function(doc, ids = character(), xnodes = c(".//r:function", ".//r:init[not(@eval='false')]", ".//r:code[not(@eval='false')]", ".//r:plot[not(@eval='false')]"), namespaces = DefaultXPathNamespaces, ...) { nodes = getNodeSet(doc, "//section") aids = sapply(nodes, xmlGetAttr, "id", NA) m = pmatch(ids, aids) if(any(is.na(m))) { # for those ids the caller gave us that didn't match # compare these to the titles. i = which(is.na(m)) tmp = ids[i] j = pmatch(ids[i], sapply(nodes, function(x) { tmp = getNodeSet(x, "./title") if(length(tmp)) xmlValue(tmp[[1]]) else "" })) m[i [!is.na(j)]] = j[!is.na(j)] } if(any(is.na(m))) stop("cannot match section id or title for ", paste(m[is.na(m)], collapse = ", ")) lapply(nodes[m], evalSection, xnodes, namespaces, ...) }) evalSection = function(node, xnodes, namespaces = DefaultXPathNamespaces, envir = globalenv(), ...) { # Or use xnodes by stripping away any [] and .// if(xmlName(node, TRUE) %in% c("r:function", "r:plot", "r:code", "r:graphics")) return(evalNode(node, envir, ...)) xpath = paste(xnodes, collapse = "|") nodes = getNodeSet(node, xpath, namespaces) sapply(nodes, evalNode, envir, ...) } ############################################# # r:code[@thread='name']|r:code[ancestor::*[@thread='name']] setGeneric("xmlSourceThread", function(doc, id, envir = globalenv(), ..., xnodes = c("r:function", "r:init", "r:code", "r:plot")) standardGeneric("xmlSourceThread")) setMethod("xmlSourceThread", "character", function(doc, id, envir = globalenv(), ..., xnodes = c("r:function", "r:init", "r:code", "r:plot")) xmlSourceThread(xmlParse(doc), id, envir, ..., xnodes = xnodes) ) setMethod("xmlSourceThread", "list", function(doc, id, envir = globalenv(), ..., xnodes = c("r:function", "r:init", "r:code", "r:plot")) sapply(doc, evalNode, envir = envir, ..., xnodes = xnodes)) if(FALSE) setMethod("xmlSourceThread", "XMLNodeList", function(doc, id, envir = globalenv(), ..., xnodes = c(".//r:function", ".//r:init[not(@eval='false')]", ".//r:code[not(@eval='false')]", ".//r:plot[not(@eval='false')]")) sapply(doc, evalNode, envir = envir, ...)) setMethod("xmlSourceThread", "XMLInternalDocument", function(doc, id, envir = globalenv(), ..., xnodes = c("r:function", "r:init", "r:code", "r:plot")) { # all the nodes that are "under" this thread. xp = sprintf("//*[@thread='%s']", id) anc = sprintf("//%s[not(ancestor::*[@thread]) and not(ancestor::altApproach)]", xnodes) xp = paste(c(xp, anc), collapse = " | ") nodes = getNodeSet(doc, xp) sapply(nodes, evalSection, envir = envir, ..., xnodes = xnodes) }) setGeneric("xmlSourceTask", function(doc, id, envir = globalenv(), ...) { standardGeneric("xmlSourceTask") } ) # nodes = c("r:code", "r:plot", "r:expr") # fmt = paste(nodes, "[@thread='%s']", sep = "") # xp = paste(sprintf(fmt, id), collapse = " | ") # paste(nodes[] # getNodeSet # "r:code[@thread='%s']|r:plot[@thread='%s']|r:expr[' # paste(getNode # }) # See tangle.R and xmlTangle. # Fix this up. Just thrown down one morning. xmlToCode = tangle = function(doc, file = stdout()) { e = xmlSourceFunctions(doc, eval = FALSE) # want to avoid parsing. if(!is(file, "connection")) con = file(file, "w") sapply(e, function(x) cat(x, "\n", file = file)) file } getTaskId = function(node) { els = getNodeSet(node, ".//ancestor::task") if(length(els)) xmlGetAttr(els[[1]], "id") else "" } XML/R/xmlEventParse.R0000644000175100001440000001204713610555150014056 0ustar hornikusers GeneralHandlerNames = list(SAX = c("text", "startElement", "endElement", "comment", "startDocument", "endDocument", "processingInstruction", "entityDeclaration", "externalEntity"), DOM = c("text", "startElement", "comment", "entity", "cdata", "processingInstruction")) checkHandlerNames = function(handlers, id = "SAX") { if(is.null(handlers)) return(TRUE) ids = names(handlers) i = match(ids, GeneralHandlerNames) prob = any(!is.na(i)) if(prob) { warning("future versions of the XML package will require names of general handler functions to be prefixed by a . to distinguish them from handlers for nodes with those names. This _may_ affect the ", paste(names(handlers)[!is.na(i)], collapse = ", ")) } if(any(w <- !sapply(handlers, is.function))) warning("some handlers are not functions: ", paste(names(handlers[w]), collapse = ", ")) !prob } xmlEventParse <- # # Parses an XML file using an event parser which calls user-level functions in the # `handlers' collection when different XML nodes are encountered in the parse stream. # # See also xmlParseTree() # function(file, handlers = xmlEventHandler(), ignoreBlanks = FALSE, addContext = TRUE, useTagName = TRUE, asText = FALSE, trim=TRUE, useExpat = FALSE, isURL=FALSE, state = NULL, replaceEntities = TRUE, validate = FALSE, saxVersion = 1, branches = NULL, useDotNames = length(grep("^\\.", names(handlers))) > 0, error = xmlErrorCumulator(), addFinalizer = NA, encoding = character()) { if(libxmlVersion()$major < 2 && !is.character(file)) stop("Without libxml2, the source of the XML can only be specified as a URI.") i = grep("^/", names(handlers)) if(length(i)) { endElementHandlers = handlers[i] names(endElementHandlers) = gsub("^/", "", names(endElementHandlers)) handlers = handlers[ - i] } else endElementHandlers = list() checkHandlerNames(handlers, "SAX") if(validate) warning("Currently, libxml2 does support validation using SAX/event-driven parsing. It requires a DOM.") else { oldValidate = xmlValidity() xmlValidity(validate) on.exit(xmlValidity(oldValidate)) } if(!any(saxVersion == c(1, 2))) { stop("saxVersion must be 1 or 2") } if(inherits(file, "connection")) { con = file if(!isOpen(file)) { open(file, "r") on.exit(close(con)) } leftOver = "" file = function(len) { if(nchar(leftOver) > 0) { txt = leftOver } else { # txt = readBin(con, "", n = len - 1L) txt = readLines(con, 1) } if(length(txt) == 0) return(txt) if(len < nchar(txt, "bytes")) { tmp = mkSubstringByBytes(txt, len) leftOver <<- tmp[2] # substring(txt, len - 1) txt =tmp[1] # substring(txt, 1, len - 2) } else leftOver <<- "" paste(txt, "\n", sep = "") } } else if(is.function(file)) { # call with -1 to allow us to close the connection # if necessary. on.exit(file(-1)) } else { if(!asText && missing(isURL)) { # check if this is a URL or regular file. isURL <- length(grep("http://",file)) | length(grep("ftp://",file)) | length(grep("file://",file)) } if(isURL == FALSE && asText == FALSE) { file = path.expand(file) if(file.exists(file) == FALSE) stop(paste("File", file, "does not exist ")) } file = as.character(file) } branches = as.list(branches) if(length(branches) > 0 && (length(names(branches)) == 0 || any(names(branches) == ""))) stop("All branch elements must have a name!") old = setEntitySubstitution(replaceEntities) on.exit(setEntitySubstitution(old)) if(!is.function(error)) stop("error must be a function") .oldErrorHandler = setXMLErrorHandler(error) on.exit(.Call("RS_XML_setStructuredErrorHandler", .oldErrorHandler, PACKAGE = "XML"), add = TRUE) state <- .Call("RS_XML_Parse", file, handlers, endElementHandlers, as.logical(addContext), as.logical(ignoreBlanks), as.logical(useTagName), as.logical(asText), as.logical(trim), as.logical(useExpat), state, as.logical(replaceEntities), as.logical(validate), as.integer(saxVersion), branches, as.logical(useDotNames), error, addFinalizer, as.character(encoding), PACKAGE = "XML") if(!is.null(state)) return(state) else return(invisible(handlers)) } mkSubstringByBytes = function(txt, nbytes) { letters = strsplit(txt, "")[[1]] nb = nchar(letters, "bytes") i = which(cumsum(nb) >= nbytes)[1] - 1 c(paste(letters[1:i], collapse = ""), paste(letters[-(1:i)], collapse = "")) } xmlStopParser = function(parser) { if(!inherits(parser, "XMLParserContext")) stop("Need an XMLParserContext object for xmlStopParser") .Call("RS_XML_xmlStopParser", parser, PACKAGE = "XML") } xmlParserContextFunction = function(f, class = "XMLParserContextFunction") { class(f) = c(class, class(f)) f } XML/R/fixNS.R0000644000175100001440000000223213607633702012311 0ustar hornikusersMissingNS = c(gating = "http://www.crap.org", 'data-type' = "http://www.morecrap.org") fixXMLNamespaces = # # call as # dd = fixXMLNamespaces("~/v75_step6.wsp", .namespaces = MissingNS) # or # dd = fixXMLNamespaces("~/v75_step6.wsp", gating = "http://www.crap.org", 'data-type' = "http://www.morecrap.org") # function(doc = "~/v75_step6.wsp", ..., .namespaces = list(...)) { # collect the error messages e = xmlErrorCumulator(, FALSE) doc = xmlParse(doc, error = e) if(length(e) == 0) return(doc) # find the ones that refer to prefixes that are not defined ns = grep("^Namespace prefix .* not defined", unique(environment(e)$messages), value = TRUE) ns = unique(gsub("Namespace prefix ([^ ]+) .*", "\\1", ns)) # now set those name spaces on the root of the document if(is(.namespaces, "list")) .namespaces = structure(as.character(unlist(.namespaces)), names = names(.namespaces)) uris = .namespaces[ns] if(length(uris)) { mapply(function(id, uri) newXMLNamespace(xmlRoot(doc), uri, id), names(uris), uris) xmlParse(saveXML(doc), asText = TRUE) } else doc } XML/R/namespaces.R0000644000175100001440000001520013607633667013412 0ustar hornikuserssetGeneric("simplifyNamespaces", function(doc, ...) standardGeneric("simplifyNamespaces")) setMethod("simplifyNamespaces", "character", function(doc, ...) { pdoc = xmlParseDoc(doc, NSCLEAN) simplifyNamespaces(pdoc, ...) }) xmlCleanNamespaces = # # @eg xmlParse("~/GitWorkingArea/XML/inst/exampleData/redundantNS.xml") # # ?Should we write the result to a file if we are given a file? # # function(doc, options = integer(), out = docName(doc), ...) { if(is(doc, "XMLInternalDocument")) doc = saveXML(doc) options = unique(c(options, NSCLEAN)) newDoc = xmlParse(doc, ..., options = options) if(is.logical(out)) out = if(out) docName(doc) else character() if(is.character(out) && length(out)) saveXML(newDoc, out) else newDoc } setMethod("simplifyNamespaces", "XMLInternalDocument", function(doc, alreadyCleaned = FALSE, ...) { # find all the nodes, but discard the root node. allNodes = getNodeSet(doc, "//node()") # [-1] root = xmlRoot(doc) # For each node, get its namespace definitions, # and then zoom in on the nodes that have namespace definitions. nsDefs = lapply(allNodes, xmlNamespaceDefinitions, simplify = TRUE) w = sapply(nsDefs, length) > 0 tmp = structure(unlist(nsDefs[w]), names = sapply(nsDefs[w], names)) d = data.frame(uri = tmp, prefix = names(tmp), stringsAsFactors = FALSE) multi = unlist(by(d, d$prefix, function(x) if(length(unique(x$uri)) == 1) character() else x$prefix[1])) if(length(multi)) d = d[ ! (d$prefix %in% multi), ] # Now we can move these namespace definitions to the top. # # # by(d, nsDefs, function(x) { u = unique(x$prefix) }) # remove the sapply(allNodes[w], removeXMLNamespaces) nsDefs }) getNodeNamespace = # Figure out what namespace to use for this node and return a reference to that # namespace definition object in C (a xmlNsPtr) function(ns, nsDefs, node, namespace, noNamespace, namespaceDefinitions = NULL, parent = NULL, suppressNamespaceWarning = FALSE) { if(noNamespace) return(NULL) if(is.character(namespace) && length(namespace) == 1L && !is.na(namespace) && namespace == "") { if(length(namespaceDefinitions) == 0) return(findNamespaceDefinition(node, "")) } if((is.list(namespace) || is.character(namespace)) && length(namespace) > 0) { # a single element with no name so this is the prefix. if(length(namespace) == 1 && length(names(namespace)) == 0) { if(namespace %in% namespaceDefinitions) { i = match(namespace, namespaceDefinitions) ns = nsPrefix = names(namespaceDefinitions)[i] } else if(namespace != "") { ns = nsPrefix = namespace } } else { # we have names and/or more than one element. So these are namespace definitions if(length(names(namespace)) == 0) names(namespace) <- rep("", length(namespace)) if(length(namespace) > 1 && !is.na(match(namespace[1], names(namespace)[-1]))) { if(length(ns)) warning("ignoring first element of namespace and using prefix from node name, ", ns) else { ns = namespace[1] namespace = namespace[-1] } } if(length(namespace) > 1 && sum(names(namespace) == "") > 1) warning("more than one namespace to use as the default") nsDefs = lapply(seq(along = namespace), function(i) { prefix = names(namespace)[i] newNamespace(node, namespace[[i]], prefix) # Don't set the namespace. This is just a definition/declaration for # this node, but not necessarily the namespace to use for this node. # We set this below }) names(nsDefs) = names(namespace) } } # Now handle the prefix for this node. if(length(ns)) { i = match(ns, names(nsDefs)) if(is.na(i)) { if(!is.null(parent)) ns = findNamespaceDefinition(node, ns) else { # raiseNsWarning(ns, suppressNamespaceWarning) # attr(node, "xml:namespace") = ns # ns = NULL ns = newNamespace(node, character(), ns) } if(!inherits(ns, "XMLNamespaceRef")) ns <- newNamespace(node, ns, "") } else ns <- nsDefs[[i]] } else { i = match("", names(nsDefs)) ns = if(is.na(i)) NULL else nsDefs[[i]] # if now namespace and we have a parent, use its namespace # if it has a namespace if(!noNamespace && length(ns) == 0 && length(parent) > 0) { ns = xmlNamespaceRef(parent) if(!is.null(ns) && names(as(ns, "character")) != "") ns = NULL } } ns } raiseNsWarning = function(ns, suppressNamespaceWarning) { if(is.character(suppressNamespaceWarning)) f = get(suppressNamespaceWarning, mode = "function") else if(is.logical(suppressNamespaceWarning)) { if(!suppressNamespaceWarning) f = warning else return(NULL) } else f = function(...) {} f("cannot find namespace definition for '", ns, "' because the node is not in a document and there are no matching local namespace definitions for this node") } fixDummyNS = function(node, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE)) { return(NULL) nodes = getNodeSet(node, "//*[./namespace::*[. = '']]", addFinalizer = FALSE) lapply(nodes, completeDummyNS, suppressNamespaceWarning = suppressNamespaceWarning) } completeDummyNS = function(node, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE)) { if(is.null(xmlParent(node))) return(FALSE) prefix = names(xmlNamespace(node)) ns = findNamespaceDefinition(xmlParent(node), prefix, error = FALSE) if(is.null(ns)) raiseNsWarning(prefix, suppressNamespaceWarning) # (if(suppressNamespaceWarning) warning else stop)("can't find namespace definition for prefix ", prefix) else { # remove the current namespace definition and kill it. .Call("R_replaceDummyNS", node, ns, prefix, PACKAGE = "XML") # setXMLNamespace(node, ns) } } XML/R/zzz.R0000644000175100001440000000227013607633674012131 0ustar hornikusersif(FALSE) { .First.lib <- function(libname, pkgname) { library.dynam("XML", pkgname, libname) if(.useNamespacesInXMLPackage && exists("setMethod")) { .InitSAXMethods() } # Set the error handlers to our local ones. .C("RSXML_setErrorHandlers", PACKAGE = "XML") } } .onLoad = function(libname, pkgname) { # Added by Uwe Ligges. if(.Platform$OS.type == "windows"){ fixPath = base::normalizePath temp <- Sys.getenv("PATH") Sys.setenv("PATH" = paste(fixPath(file.path(libname, pkgname, "libs")), file.path(Sys.getenv("R_HOME"), "modules", fsep="\\"), temp, sep=";")) on.exit(Sys.setenv(PATH = temp)) } library.dynam("XML", pkgname, libname) if(exists("setMethod")) { # .InitSAXMethods() } # Set the error handlers to our local ones. .C("RSXML_setErrorHandlers", PACKAGE = "XML") } .onUnload <- function (libpath) { library.dynam.unload("XML", libpath) } if(FALSE) { .Call = function(name, ...) { base::.Call(name, ..., PACKAGE = "XML") } .C = function(name, ...) { base::.C(name, ..., PACKAGE = "XML") } } # # Copyright (c) 1998, 1999 The Omega Project for Statistical Computing. # All rights reserved.# XML/R/xmlTreeParse.R0000644000175100001440000001634113610046417013676 0ustar hornikusersxmlSchemaParse = function(file, asText = FALSE, xinclude = TRUE, error = xmlErrorCumulator()) { xmlParse(file, asText = asText, isSchema = TRUE, xinclude = xinclude, error = error) } BOMRegExp = "(\\xEF\\xBB\\xBF|\\xFE\\xFF|\\xFF\\xFE)" xmlTreeParse <- # # XML parser that reads the entire `document' tree into memory # and then converts it to an R/S object. # Uses the libxml from Daniel Veillard at W3.org. # # asText treat the value of file as XML text, not the name of a file containing # the XML text, and parse that. # # function(file, ignoreBlanks = TRUE, handlers = NULL, replaceEntities = FALSE, asText = FALSE, trim = TRUE, validate = FALSE, getDTD = TRUE, isURL = FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = FALSE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = xmlErrorCumulator(), isHTML = FALSE, options = integer(), parentFirst = FALSE) { isMissingAsText = missing(asText) if(length(file) > 1) { file = paste(file, collapse = "\n") if(!missing(asText) && !asText) stop(structure(list(message = "multiple URLs passed to xmlTreeParse. If this is the content of the file, specify asText = TRUE"), class = c("MultipleURLError", "XMLParserError", "simpleError", "error", "condition"))) asText = TRUE } if(missing(isURL) && !asText) isURL <- length(grep("^(http|ftp|file)://", file, useBytes = TRUE, perl = TRUE)) if(file == "" || length(file) == 0) stop("empty or no content specified") if(isHTML) { validate = FALSE getDTD = FALSE isSchema = FALSE docClass = "HTMLInternalDocument" } else docClass = character() checkHandlerNames(handlers, "DOM") if(missing(fullNamespaceInfo) && inherits(handlers, "RequiresNamespaceInfo")) fullNamespaceInfo = TRUE oldValidate = xmlValidity() xmlValidity(validate) on.exit(xmlValidity(oldValidate)) # check whether we are treating the file name as # a) the XML text itself, or b) as a URL. # Otherwise, check if the file exists and report an error. if(!asText && isURL == FALSE) { if(file.exists(file) == FALSE) if(!missing(asText) && asText == FALSE) { e = simpleError(paste("File", file, "does not exist")) class(e) = c("FileNotFound", class(e)) stop(e) } else asText <- TRUE } if(asText && length(file) > 1) file = paste(file, collapse = "\n") old = setEntitySubstitution(replaceEntities) on.exit(setEntitySubstitution(old), add = TRUE) # Look for a < in the string. if(asText && length(grep(sprintf("^%s?\\s*<", BOMRegExp), file, perl = TRUE, useBytes = TRUE)) == 0) { # !isXMLString(file) ? if(!isHTML || (isMissingAsText && !inherits(file, "AsIs"))) { e = simpleError(paste("XML content does not seem to be XML:", if(file.exists(file)) file else sQuote(substring(file, 100)))) class(e) = c("XMLInputError", class(e)) (if(isHTML) warning else stop)(e) } } if(!is.logical(xinclude)) { # if(is(xinclude, "numeric")) # xinclude = bitlist(xinclude) # see bitList.R # else xinclude = as.logical(xinclude) } if(!asText && !isURL) file = path.expand(as.character(file)) if(useInternalNodes && trim) { prevBlanks = .Call("RS_XML_setKeepBlanksDefault", 0L, PACKAGE = "XML") on.exit(.Call("RS_XML_setKeepBlanksDefault", prevBlanks, PACKAGE = "XML"), add = TRUE) } .oldErrorHandler = setXMLErrorHandler(error) on.exit(.Call("RS_XML_setStructuredErrorHandler", .oldErrorHandler, PACKAGE = "XML"), add = TRUE) if(length(options)) options = sum(options) #XXX coerce to parser options ans <- .Call("RS_XML_ParseTree", as.character(file), handlers, as.logical(ignoreBlanks), as.logical(replaceEntities), as.logical(asText), as.logical(trim), as.logical(validate), as.logical(getDTD), as.logical(isURL), as.logical(addAttributeNamespaces), as.logical(useInternalNodes), as.logical(isHTML), as.logical(isSchema), as.logical(fullNamespaceInfo), as.character(encoding), as.logical(useDotNames), xinclude, error, addFinalizer, as.integer(options), as.logical(parentFirst), PACKAGE = "XML") if(!missing(handlers) && length(handlers) && !as.logical(asTree)) return(handlers) if(!isSchema && length(class(ans))) class(ans) = c(docClass, oldClass(class(ans))) if(inherits(ans, "XMLInternalDocument")) addDocFinalizer(ans, addFinalizer) else if(!getDTD && !isSchema) { #??? is this a good idea. class(ans) = oldClass("XMLDocumentContent") } ans } xmlNativeTreeParse = xmlInternalTreeParse = xmlTreeParse formals(xmlNativeTreeParse)[["useInternalNodes"]] = TRUE formals(xmlInternalTreeParse)[["useInternalNodes"]] = TRUE xmlParse = xmlNativeTreeParse if(FALSE) { # Another approach is to just change the call, as below, but this is tricky # to get evaluation of arguments, etc. right. tmp.xmlInternalTreeParse = function(file, ignoreBlanks = TRUE, handlers=NULL, replaceEntities=FALSE, asText=FALSE, trim=TRUE, validate=FALSE, getDTD=TRUE, isURL=FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\.", names(handlers))) > 0, # will be switched to TRUE in the future. xinclude = TRUE, addFinalizer = TRUE) { e = sys.call() e[[1]] = as.name("xmlTreeParse") e[[length(e) + 1]] = FALSE names(e)[length(e)] = "useInternalNodes" eval(e, parent.env()) } # Could try adding this to the top of xmlTreeParse # But it won't work with, e.g. lapply(fileNames, xmlInternalTreeParse) # if(missing(useInternalNodes) && as.character(sys.call()[[1]]) == "xmlInternalTreeParse") # useInternalNodes = FALSE } setGeneric("getEncoding", function(obj, ...) { standardGeneric("getEncoding") }) setMethod("getEncoding", "ANY", function(obj, ...) NA) setMethod("getEncoding", "XMLInternalDocument", function(obj, ...) { .Call("R_getDocEncoding", obj, PACKAGE = "XML") }) setMethod("getEncoding", "XMLInternalNode", function(obj, ...) { .Call("R_getDocEncoding", obj, PACKAGE = "XML") }) if(FALSE) { setMethod("getEncoding", "XMLInternalDOM", function(obj, ...) { getEncoding(obj) }) } xmlValidity = function(val = integer(0)) { .Call("RS_XML_getDefaultValiditySetting", as.integer(val), PACKAGE = "XML") } processXInclude = function(node, flags = 0L) UseMethod("processXInclude") processXInclude.list = function(node, flags = 0L) { lapply(node, processXInclude, flags) } processXInclude.XMLInternalDocument = function(node, flags = 0L) { .Call("RS_XML_xmlXIncludeProcessFlags", node, as.integer(flags), PACKAGE = "XML") } processXInclude.XMLInternalElementNode = function(node, flags = 0L) { # if(xmlName(node) != "include") # Should check name space also # stop("can only process XInclude on include nodes") .Call("RS_XML_xmlXIncludeProcessTreeFlags", node, as.integer(flags), PACKAGE = "XML") } XML/R/schema.R0000644000175100001440000000770413610046417012526 0ustar hornikuserssetClass("ExternalReference", representation(ref = "externalptr")) setClass("libxmlTypeTable", representation(ref = "ExternalReference")) # Identifies the class of the element within a libxmlTypeTable sub-class. setGeneric("getTableElementType", function(table) standardGeneric("getTableElementType")) # The name of the element is the name of the class of the table without the Table suffix and, # with Ref tagged on and with xml as a suffix. setMethod("getTableElementType", "libxmlTypeTable", function(table) paste("xml", gsub("Table$", "Ref", class(table)), sep = "") ) setMethod("$<-", "libxmlTypeTable", function(x, name, value) { stop("These tables are read-only for the moment") }) setMethod("names", "libxmlTypeTable", function(x) { .Call("R_libxmlTypeTable_names", x, character(0), PACKAGE = "XML") }) setAs("libxmlTypeTable", "list", function(from) { .Call("R_libxmlTypeTable_names", from, getTableElementType(from), PACKAGE = "XML") }) setMethod("$", "libxmlTypeTable", function(x, name) { .Call("R_libxmlTypeTable_lookup", x, name, getTableElementType(x), PACKAGE = "XML") }) ################################################################# setClass("xmlSchemaRef", contains = "ExternalReference") SchemaRefFields = c("name", "targetNamespace", "version", "id", "typeDecl", "attrDecl", "attrgrpDecl", "elemDecl", "notaDecl", "schemasImports" ) setMethod("$", "xmlSchemaRef", function(x, name) { idx = pmatch(name, SchemaRefFields) if(is.na(idx)) stop("No field ", name, " in ", paste(SchemaRefFields, collapse = ", ")) sym <- paste("R_libxmlTypeTable", SchemaRefFields[idx], sep = "_") .Call(sym, x, PACKAGE = "XML") }) setMethod("names", "xmlSchemaRef", function(x) SchemaRefFields) setClass("SchemaElementTable", contains = "libxmlTypeTable") setClass("xmlSchemaElementRef", contains = "ExternalReference") setClass("SchemaTypeTable", contains = "libxmlTypeTable") setClass("xmlSchemaTypeRef", contains = "ExternalReference") setClass("SchemaAttributeTable", contains = "libxmlTypeTable") setClass("xmlSchemaAttributeRef", contains = "ExternalReference") setClass("SchemaAttributeGroupTable", contains = "libxmlTypeTable") setClass("xmlSchemaAttributeGroupRef", contains = "ExternalReference") setClass("SchemaNotationTable", contains = "libxmlTypeTable") setClass("xmlSchemaNotationRef", contains = "ExternalReference") schemaValidationErrorHandler = function() { errors = character() warnings = character() h = function(msg) { if(inherits(msg, "XMLSchemaWarning")) warnings <<- c(warnings, msg) else errors <<- c(errors, msg) } structure(list(handler = h, results = function() list(errors = errors, warnings = warnings)), class = "XMLSchemaValidateHandler") } xmlSchemaValidate = # schemaValidationErrorHandler() function(schema, doc, errorHandler = xmlErrorFun(), options = 0L) { if(is.character(doc)) doc = xmlParse(doc) if(is.character(schema)) schema = xmlSchemaParse(schema) .oldErrorHandler = setXMLErrorHandler(if(is.list(errorHandler)) errorHandler[[1]] else errorHandler) on.exit(.Call("RS_XML_setStructuredErrorHandler", .oldErrorHandler, PACKAGE = "XML"), add = TRUE) status = .Call("RS_XML_xmlSchemaValidateDoc", schema@ref, doc, as.integer(options), NULL, PACKAGE = "XML") # errorHandler) if(inherits(errorHandler, "XMLStructuredErrorCumulator")) structure(list(status = status, errors = errorHandler[[2]]()), class = "XMLSchemaValidationResults") else if(inherits(errorHandler, "XMLSchemaValidateHandler")) c(status = status, errorHandler$results()) else status } setOldClass("XMLSchemaValidationResults") setMethod("show", "XMLSchemaValidationResults", function(object) show(object$errors)) XML/R/XMLRErrorInfo.R0000644000175100001440000006431413607633665013713 0ustar hornikusersXMLParseErrors <- structure(c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 52L, 53L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L, 66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 76L, 77L, 78L, 79L, 80L, 81L, 82L, 83L, 84L, 85L, 86L, 87L, 88L, 89L, 90L, 91L, 92L, 93L, 94L, 95L, 96L, 97L, 98L, 99L, 100L, 101L, 102L, 103L, 104L, 105L, 106L, 107L, 108L, 109L, 200L, 201L, 202L, 203L, 204L, 205L, 500L, 501L, 502L, 503L, 504L, 505L, 506L, 507L, 508L, 509L, 510L, 511L, 512L, 513L, 514L, 515L, 516L, 517L, 518L, 519L, 520L, 521L, 522L, 523L, 524L, 525L, 526L, 527L, 528L, 529L, 530L, 531L, 532L, 533L, 534L, 535L, 536L, 537L, 538L, 539L, 540L, 541L, 800L, 801L, 1000L, 1001L, 1002L, 1003L, 1004L, 1005L, 1006L, 1007L, 1008L, 1009L, 1010L, 1011L, 1012L, 1013L, 1014L, 1015L, 1016L, 1017L, 1018L, 1019L, 1020L, 1021L, 1022L, 1023L, 1024L, 1025L, 1026L, 1027L, 1028L, 1029L, 1030L, 1031L, 1032L, 1033L, 1034L, 1035L, 1036L, 1037L, 1038L, 1039L, 1040L, 1041L, 1042L, 1043L, 1044L, 1045L, 1046L, 1047L, 1048L, 1049L, 1050L, 1051L, 1052L, 1053L, 1054L, 1055L, 1056L, 1057L, 1058L, 1059L, 1060L, 1061L, 1062L, 1063L, 1064L, 1065L, 1066L, 1067L, 1068L, 1069L, 1070L, 1071L, 1072L, 1073L, 1074L, 1075L, 1076L, 1077L, 1078L, 1079L, 1080L, 1081L, 1082L, 1083L, 1084L, 1085L, 1086L, 1087L, 1088L, 1089L, 1090L, 1091L, 1092L, 1093L, 1094L, 1095L, 1096L, 1097L, 1098L, 1099L, 1100L, 1101L, 1102L, 1103L, 1104L, 1105L, 1106L, 1107L, 1108L, 1109L, 1110L, 1111L, 1112L, 1113L, 1114L, 1115L, 1116L, 1117L, 1118L, 1119L, 1120L, 1121L, 1122L, 1200L, 1201L, 1202L, 1203L, 1204L, 1205L, 1206L, 1207L, 1208L, 1209L, 1210L, 1211L, 1212L, 1213L, 1214L, 1215L, 1216L, 1217L, 1218L, 1219L, 1220L, 1221L, 1300L, 1301L, 1302L, 1303L, 1400L, 1401L, 1402L, 1403L, 1450L, 1500L, 1501L, 1502L, 1503L, 1504L, 1505L, 1506L, 1507L, 1508L, 1509L, 1510L, 1511L, 1512L, 1513L, 1514L, 1515L, 1516L, 1517L, 1518L, 1519L, 1520L, 1521L, 1522L, 1523L, 1524L, 1525L, 1526L, 1527L, 1528L, 1529L, 1530L, 1531L, 1532L, 1533L, 1534L, 1535L, 1536L, 1537L, 1538L, 1539L, 1540L, 1541L, 1542L, 1543L, 1544L, 1545L, 1546L, 1547L, 1548L, 1549L, 1550L, 1551L, 1552L, 1553L, 1554L, 1555L, 1556L, 1600L, 1601L, 1602L, 1603L, 1604L, 1605L, 1606L, 1607L, 1608L, 1609L, 1610L, 1611L, 1612L, 1613L, 1614L, 1615L, 1616L, 1617L, 1618L, 1650L, 1651L, 1652L, 1653L, 1654L, 1700L, 1701L, 1702L, 1703L, 1704L, 1705L, 1706L, 1707L, 1708L, 1709L, 1710L, 1711L, 1712L, 1713L, 1714L, 1715L, 1716L, 1717L, 1718L, 1719L, 1720L, 1721L, 1722L, 1723L, 1724L, 1725L, 1726L, 1727L, 1728L, 1729L, 1730L, 1731L, 1732L, 1733L, 1734L, 1735L, 1736L, 1737L, 1738L, 1739L, 1740L, 1741L, 1742L, 1743L, 1744L, 1745L, 1746L, 1747L, 1748L, 1749L, 1750L, 1751L, 1752L, 1753L, 1754L, 1755L, 1756L, 1757L, 1758L, 1759L, 1760L, 1761L, 1762L, 1763L, 1764L, 1765L, 1766L, 1767L, 1768L, 1769L, 1770L, 1771L, 1772L, 1773L, 1774L, 1775L, 1776L, 1777L, 1778L, 1779L, 1780L, 1781L, 1782L, 1783L, 1784L, 1785L, 1786L, 1787L, 1788L, 1789L, 1790L, 1791L, 1792L, 1793L, 1794L, 1795L, 1796L, 1797L, 1798L, 1799L, 1800L, 1801L, 1802L, 1803L, 1804L, 1805L, 1806L, 1807L, 1808L, 1809L, 1810L, 1811L, 1812L, 1813L, 1814L, 1815L, 1816L, 1817L, 1818L, 1819L, 1820L, 1821L, 1822L, 1823L, 1824L, 1825L, 1826L, 1827L, 1828L, 1829L, 1830L, 1831L, 1832L, 1833L, 1834L, 1835L, 1836L, 1837L, 1838L, 1839L, 1840L, 1841L, 1842L, 1843L, 1844L, 1845L, 1846L, 1847L, 1848L, 1849L, 1850L, 1851L, 1852L, 1853L, 1854L, 1855L, 1856L, 1857L, 1858L, 1859L, 1860L, 1861L, 1862L, 1863L, 1864L, 1865L, 1866L, 1867L, 1868L, 1869L, 1870L, 1871L, 1872L, 1873L, 1874L, 1875L, 1876L, 1877L, 1878L, 1879L, 1900L, 1901L, 1902L, 1903L, 1950L, 1951L, 1952L, 1953L, 1954L, 1955L, 2000L, 2001L, 2002L, 2003L, 2020L, 2021L, 2022L, 3000L, 3001L, 3002L, 3003L, 3004L, 3005L, 3006L, 3007L, 3008L, 3009L, 3010L, 3011L, 3012L, 3013L, 3014L, 3015L, 3016L, 3017L, 3018L, 3019L, 3020L, 3021L, 3022L, 3023L, 3024L, 3025L, 3026L, 3027L, 3028L, 3029L, 3030L, 3031L, 3032L, 3033L, 3034L, 3035L, 3036L, 3037L, 3038L, 3039L, 3040L, 3041L, 3042L, 3043L, 3044L, 3045L, 3046L, 3047L, 3048L, 3049L, 3050L, 3051L, 3052L, 3053L, 3054L, 3055L, 3056L, 3057L, 3058L, 3059L, 3060L, 3061L, 3062L, 3063L, 3064L, 3065L, 3066L, 3067L, 3068L, 3069L, 3070L, 3071L, 3072L, 3073L, 3074L, 3075L, 3076L, 3077L, 3078L, 3079L, 3080L, 3081L, 3082L, 3083L, 3084L, 3085L, 3086L, 3087L, 3088L, 3089L, 3090L, 3091L, 4000L, 4001L, 4900L, 4901L, 5000L, 5001L, 5002L, 5003L, 5004L, 5005L, 5006L, 5007L, 5008L, 5009L, 5010L, 5011L, 5012L, 5013L, 5014L, 5015L, 5016L, 5017L, 5018L, 5019L, 5020L, 5021L, 5022L, 5023L, 5024L, 5025L, 5026L, 5027L, 5028L, 5029L, 5030L, 5031L, 5032L, 5033L, 5034L, 5035L, 5036L, 5037L, 6000L, 6001L, 6002L, 6003L, 6004L), .Names = c("XML_ERR_OK", "XML_ERR_INTERNAL_ERROR", "XML_ERR_NO_MEMORY", "XML_ERR_DOCUMENT_START", "XML_ERR_DOCUMENT_EMPTY", "XML_ERR_DOCUMENT_END", "XML_ERR_INVALID_HEX_CHARREF", "XML_ERR_INVALID_DEC_CHARREF", "XML_ERR_INVALID_CHARREF", "XML_ERR_INVALID_CHAR", "XML_ERR_CHARREF_AT_EOF", "XML_ERR_CHARREF_IN_PROLOG", "XML_ERR_CHARREF_IN_EPILOG", "XML_ERR_CHARREF_IN_DTD", "XML_ERR_ENTITYREF_AT_EOF", "XML_ERR_ENTITYREF_IN_PROLOG", "XML_ERR_ENTITYREF_IN_EPILOG", "XML_ERR_ENTITYREF_IN_DTD", "XML_ERR_PEREF_AT_EOF", "XML_ERR_PEREF_IN_PROLOG", "XML_ERR_PEREF_IN_EPILOG", "XML_ERR_PEREF_IN_INT_SUBSET", "XML_ERR_ENTITYREF_NO_NAME", "XML_ERR_ENTITYREF_SEMICOL_MISSING", "XML_ERR_PEREF_NO_NAME", "XML_ERR_PEREF_SEMICOL_MISSING", "XML_ERR_UNDECLARED_ENTITY", "XML_WAR_UNDECLARED_ENTITY", "XML_ERR_UNPARSED_ENTITY", "XML_ERR_ENTITY_IS_EXTERNAL", "XML_ERR_ENTITY_IS_PARAMETER", "XML_ERR_UNKNOWN_ENCODING", "XML_ERR_UNSUPPORTED_ENCODING", "XML_ERR_STRING_NOT_STARTED", "XML_ERR_STRING_NOT_CLOSED", "XML_ERR_NS_DECL_ERROR", "XML_ERR_ENTITY_NOT_STARTED", "XML_ERR_ENTITY_NOT_FINISHED", "XML_ERR_LT_IN_ATTRIBUTE", "XML_ERR_ATTRIBUTE_NOT_STARTED", "XML_ERR_ATTRIBUTE_NOT_FINISHED", "XML_ERR_ATTRIBUTE_WITHOUT_VALUE", "XML_ERR_ATTRIBUTE_REDEFINED", "XML_ERR_LITERAL_NOT_STARTED", "XML_ERR_LITERAL_NOT_FINISHED", "XML_ERR_COMMENT_NOT_FINISHED", "XML_ERR_PI_NOT_STARTED", "XML_ERR_PI_NOT_FINISHED", "XML_ERR_NOTATION_NOT_STARTED", "XML_ERR_NOTATION_NOT_FINISHED", "XML_ERR_ATTLIST_NOT_STARTED", "XML_ERR_ATTLIST_NOT_FINISHED", "XML_ERR_MIXED_NOT_STARTED", "XML_ERR_MIXED_NOT_FINISHED", "XML_ERR_ELEMCONTENT_NOT_STARTED", "XML_ERR_ELEMCONTENT_NOT_FINISHED", "XML_ERR_XMLDECL_NOT_STARTED", "XML_ERR_XMLDECL_NOT_FINISHED", "XML_ERR_CONDSEC_NOT_STARTED", "XML_ERR_CONDSEC_NOT_FINISHED", "XML_ERR_EXT_SUBSET_NOT_FINISHED", "XML_ERR_DOCTYPE_NOT_FINISHED", "XML_ERR_MISPLACED_CDATA_END", "XML_ERR_CDATA_NOT_FINISHED", "XML_ERR_RESERVED_XML_NAME", "XML_ERR_SPACE_REQUIRED", "XML_ERR_SEPARATOR_REQUIRED", "XML_ERR_NMTOKEN_REQUIRED", "XML_ERR_NAME_REQUIRED", "XML_ERR_PCDATA_REQUIRED", "XML_ERR_URI_REQUIRED", "XML_ERR_PUBID_REQUIRED", "XML_ERR_LT_REQUIRED", "XML_ERR_GT_REQUIRED", "XML_ERR_LTSLASH_REQUIRED", "XML_ERR_EQUAL_REQUIRED", "XML_ERR_TAG_NAME_MISMATCH", "XML_ERR_TAG_NOT_FINISHED", "XML_ERR_STANDALONE_VALUE", "XML_ERR_ENCODING_NAME", "XML_ERR_HYPHEN_IN_COMMENT", "XML_ERR_INVALID_ENCODING", "XML_ERR_EXT_ENTITY_STANDALONE", "XML_ERR_CONDSEC_INVALID", "XML_ERR_VALUE_REQUIRED", "XML_ERR_NOT_WELL_BALANCED", "XML_ERR_EXTRA_CONTENT", "XML_ERR_ENTITY_CHAR_ERROR", "XML_ERR_ENTITY_PE_INTERNAL", "XML_ERR_ENTITY_LOOP", "XML_ERR_ENTITY_BOUNDARY", "XML_ERR_INVALID_URI", "XML_ERR_URI_FRAGMENT", "XML_WAR_CATALOG_PI", "XML_ERR_NO_DTD", "XML_ERR_CONDSEC_INVALID_KEYWORD", "XML_ERR_VERSION_MISSING", "XML_WAR_UNKNOWN_VERSION", "XML_WAR_LANG_VALUE", "XML_WAR_NS_URI", "XML_WAR_NS_URI_RELATIVE", "XML_ERR_MISSING_ENCODING", "XML_WAR_SPACE_VALUE", "XML_ERR_NOT_STANDALONE", "XML_ERR_ENTITY_PROCESSING", "XML_ERR_NOTATION_PROCESSING", "XML_WAR_NS_COLUMN", "XML_WAR_ENTITY_REDEFINED", "XML_ERR_UNKNOWN_VERSION", "XML_ERR_VERSION_MISMATCH", "XML_NS_ERR_XML_NAMESPACE", "XML_NS_ERR_UNDEFINED_NAMESPACE", "XML_NS_ERR_QNAME", "XML_NS_ERR_ATTRIBUTE_REDEFINED", "XML_NS_ERR_EMPTY", "XML_NS_ERR_COLON", "XML_DTD_ATTRIBUTE_DEFAULT", "XML_DTD_ATTRIBUTE_REDEFINED", "XML_DTD_ATTRIBUTE_VALUE", "XML_DTD_CONTENT_ERROR", "XML_DTD_CONTENT_MODEL", "XML_DTD_CONTENT_NOT_DETERMINIST", "XML_DTD_DIFFERENT_PREFIX", "XML_DTD_ELEM_DEFAULT_NAMESPACE", "XML_DTD_ELEM_NAMESPACE", "XML_DTD_ELEM_REDEFINED", "XML_DTD_EMPTY_NOTATION", "XML_DTD_ENTITY_TYPE", "XML_DTD_ID_FIXED", "XML_DTD_ID_REDEFINED", "XML_DTD_ID_SUBSET", "XML_DTD_INVALID_CHILD", "XML_DTD_INVALID_DEFAULT", "XML_DTD_LOAD_ERROR", "XML_DTD_MISSING_ATTRIBUTE", "XML_DTD_MIXED_CORRUPT", "XML_DTD_MULTIPLE_ID", "XML_DTD_NO_DOC", "XML_DTD_NO_DTD", "XML_DTD_NO_ELEM_NAME", "XML_DTD_NO_PREFIX", "XML_DTD_NO_ROOT", "XML_DTD_NOTATION_REDEFINED", "XML_DTD_NOTATION_VALUE", "XML_DTD_NOT_EMPTY", "XML_DTD_NOT_PCDATA", "XML_DTD_NOT_STANDALONE", "XML_DTD_ROOT_NAME", "XML_DTD_STANDALONE_WHITE_SPACE", "XML_DTD_UNKNOWN_ATTRIBUTE", "XML_DTD_UNKNOWN_ELEM", "XML_DTD_UNKNOWN_ENTITY", "XML_DTD_UNKNOWN_ID", "XML_DTD_UNKNOWN_NOTATION", "XML_DTD_STANDALONE_DEFAULTED", "XML_DTD_XMLID_VALUE", "XML_DTD_XMLID_TYPE", "XML_DTD_DUP_TOKEN", "XML_HTML_STRUCURE_ERROR", "XML_HTML_UNKNOWN_TAG", "XML_RNGP_ANYNAME_ATTR_ANCESTOR", "XML_RNGP_ATTR_CONFLICT", "XML_RNGP_ATTRIBUTE_CHILDREN", "XML_RNGP_ATTRIBUTE_CONTENT", "XML_RNGP_ATTRIBUTE_EMPTY", "XML_RNGP_ATTRIBUTE_NOOP", "XML_RNGP_CHOICE_CONTENT", "XML_RNGP_CHOICE_EMPTY", "XML_RNGP_CREATE_FAILURE", "XML_RNGP_DATA_CONTENT", "XML_RNGP_DEF_CHOICE_AND_INTERLEAVE", "XML_RNGP_DEFINE_CREATE_FAILED", "XML_RNGP_DEFINE_EMPTY", "XML_RNGP_DEFINE_MISSING", "XML_RNGP_DEFINE_NAME_MISSING", "XML_RNGP_ELEM_CONTENT_EMPTY", "XML_RNGP_ELEM_CONTENT_ERROR", "XML_RNGP_ELEMENT_EMPTY", "XML_RNGP_ELEMENT_CONTENT", "XML_RNGP_ELEMENT_NAME", "XML_RNGP_ELEMENT_NO_CONTENT", "XML_RNGP_ELEM_TEXT_CONFLICT", "XML_RNGP_EMPTY", "XML_RNGP_EMPTY_CONSTRUCT", "XML_RNGP_EMPTY_CONTENT", "XML_RNGP_EMPTY_NOT_EMPTY", "XML_RNGP_ERROR_TYPE_LIB", "XML_RNGP_EXCEPT_EMPTY", "XML_RNGP_EXCEPT_MISSING", "XML_RNGP_EXCEPT_MULTIPLE", "XML_RNGP_EXCEPT_NO_CONTENT", "XML_RNGP_EXTERNALREF_EMTPY", "XML_RNGP_EXTERNAL_REF_FAILURE", "XML_RNGP_EXTERNALREF_RECURSE", "XML_RNGP_FORBIDDEN_ATTRIBUTE", "XML_RNGP_FOREIGN_ELEMENT", "XML_RNGP_GRAMMAR_CONTENT", "XML_RNGP_GRAMMAR_EMPTY", "XML_RNGP_GRAMMAR_MISSING", "XML_RNGP_GRAMMAR_NO_START", "XML_RNGP_GROUP_ATTR_CONFLICT", "XML_RNGP_HREF_ERROR", "XML_RNGP_INCLUDE_EMPTY", "XML_RNGP_INCLUDE_FAILURE", "XML_RNGP_INCLUDE_RECURSE", "XML_RNGP_INTERLEAVE_ADD", "XML_RNGP_INTERLEAVE_CREATE_FAILED", "XML_RNGP_INTERLEAVE_EMPTY", "XML_RNGP_INTERLEAVE_NO_CONTENT", "XML_RNGP_INVALID_DEFINE_NAME", "XML_RNGP_INVALID_URI", "XML_RNGP_INVALID_VALUE", "XML_RNGP_MISSING_HREF", "XML_RNGP_NAME_MISSING", "XML_RNGP_NEED_COMBINE", "XML_RNGP_NOTALLOWED_NOT_EMPTY", "XML_RNGP_NSNAME_ATTR_ANCESTOR", "XML_RNGP_NSNAME_NO_NS", "XML_RNGP_PARAM_FORBIDDEN", "XML_RNGP_PARAM_NAME_MISSING", "XML_RNGP_PARENTREF_CREATE_FAILED", "XML_RNGP_PARENTREF_NAME_INVALID", "XML_RNGP_PARENTREF_NO_NAME", "XML_RNGP_PARENTREF_NO_PARENT", "XML_RNGP_PARENTREF_NOT_EMPTY", "XML_RNGP_PARSE_ERROR", "XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME", "XML_RNGP_PAT_ATTR_ATTR", "XML_RNGP_PAT_ATTR_ELEM", "XML_RNGP_PAT_DATA_EXCEPT_ATTR", "XML_RNGP_PAT_DATA_EXCEPT_ELEM", "XML_RNGP_PAT_DATA_EXCEPT_EMPTY", "XML_RNGP_PAT_DATA_EXCEPT_GROUP", "XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE", "XML_RNGP_PAT_DATA_EXCEPT_LIST", "XML_RNGP_PAT_DATA_EXCEPT_ONEMORE", "XML_RNGP_PAT_DATA_EXCEPT_REF", "XML_RNGP_PAT_DATA_EXCEPT_TEXT", "XML_RNGP_PAT_LIST_ATTR", "XML_RNGP_PAT_LIST_ELEM", "XML_RNGP_PAT_LIST_INTERLEAVE", "XML_RNGP_PAT_LIST_LIST", "XML_RNGP_PAT_LIST_REF", "XML_RNGP_PAT_LIST_TEXT", "XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME", "XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME", "XML_RNGP_PAT_ONEMORE_GROUP_ATTR", "XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR", "XML_RNGP_PAT_START_ATTR", "XML_RNGP_PAT_START_DATA", "XML_RNGP_PAT_START_EMPTY", "XML_RNGP_PAT_START_GROUP", "XML_RNGP_PAT_START_INTERLEAVE", "XML_RNGP_PAT_START_LIST", "XML_RNGP_PAT_START_ONEMORE", "XML_RNGP_PAT_START_TEXT", "XML_RNGP_PAT_START_VALUE", "XML_RNGP_PREFIX_UNDEFINED", "XML_RNGP_REF_CREATE_FAILED", "XML_RNGP_REF_CYCLE", "XML_RNGP_REF_NAME_INVALID", "XML_RNGP_REF_NO_DEF", "XML_RNGP_REF_NO_NAME", "XML_RNGP_REF_NOT_EMPTY", "XML_RNGP_START_CHOICE_AND_INTERLEAVE", "XML_RNGP_START_CONTENT", "XML_RNGP_START_EMPTY", "XML_RNGP_START_MISSING", "XML_RNGP_TEXT_EXPECTED", "XML_RNGP_TEXT_HAS_CHILD", "XML_RNGP_TYPE_MISSING", "XML_RNGP_TYPE_NOT_FOUND", "XML_RNGP_TYPE_VALUE", "XML_RNGP_UNKNOWN_ATTRIBUTE", "XML_RNGP_UNKNOWN_COMBINE", "XML_RNGP_UNKNOWN_CONSTRUCT", "XML_RNGP_UNKNOWN_TYPE_LIB", "XML_RNGP_URI_FRAGMENT", "XML_RNGP_URI_NOT_ABSOLUTE", "XML_RNGP_VALUE_EMPTY", "XML_RNGP_VALUE_NO_CONTENT", "XML_RNGP_XMLNS_NAME", "XML_RNGP_XML_NS", "XML_XPATH_EXPRESSION_OK", "XML_XPATH_NUMBER_ERROR", "XML_XPATH_UNFINISHED_LITERAL_ERROR", "XML_XPATH_START_LITERAL_ERROR", "XML_XPATH_VARIABLE_REF_ERROR", "XML_XPATH_UNDEF_VARIABLE_ERROR", "XML_XPATH_INVALID_PREDICATE_ERROR", "XML_XPATH_EXPR_ERROR", "XML_XPATH_UNCLOSED_ERROR", "XML_XPATH_UNKNOWN_FUNC_ERROR", "XML_XPATH_INVALID_OPERAND", "XML_XPATH_INVALID_TYPE", "XML_XPATH_INVALID_ARITY", "XML_XPATH_INVALID_CTXT_SIZE", "XML_XPATH_INVALID_CTXT_POSITION", "XML_XPATH_MEMORY_ERROR", "XML_XPTR_SYNTAX_ERROR", "XML_XPTR_RESOURCE_ERROR", "XML_XPTR_SUB_RESOURCE_ERROR", "XML_XPATH_UNDEF_PREFIX_ERROR", "XML_XPATH_ENCODING_ERROR", "XML_XPATH_INVALID_CHAR_ERROR", "XML_TREE_INVALID_HEX", "XML_TREE_INVALID_DEC", "XML_TREE_UNTERMINATED_ENTITY", "XML_TREE_NOT_UTF8", "XML_SAVE_NOT_UTF8", "XML_SAVE_CHAR_INVALID", "XML_SAVE_NO_DOCTYPE", "XML_SAVE_UNKNOWN_ENCODING", "XML_REGEXP_COMPILE_ERROR", "XML_IO_UNKNOWN", "XML_IO_EACCES", "XML_IO_EAGAIN", "XML_IO_EBADF", "XML_IO_EBADMSG", "XML_IO_EBUSY", "XML_IO_ECANCELED", "XML_IO_ECHILD", "XML_IO_EDEADLK", "XML_IO_EDOM", "XML_IO_EEXIST", "XML_IO_EFAULT", "XML_IO_EFBIG", "XML_IO_EINPROGRESS", "XML_IO_EINTR", "XML_IO_EINVAL", "XML_IO_EIO", "XML_IO_EISDIR", "XML_IO_EMFILE", "XML_IO_EMLINK", "XML_IO_EMSGSIZE", "XML_IO_ENAMETOOLONG", "XML_IO_ENFILE", "XML_IO_ENODEV", "XML_IO_ENOENT", "XML_IO_ENOEXEC", "XML_IO_ENOLCK", "XML_IO_ENOMEM", "XML_IO_ENOSPC", "XML_IO_ENOSYS", "XML_IO_ENOTDIR", "XML_IO_ENOTEMPTY", "XML_IO_ENOTSUP", "XML_IO_ENOTTY", "XML_IO_ENXIO", "XML_IO_EPERM", "XML_IO_EPIPE", "XML_IO_ERANGE", "XML_IO_EROFS", "XML_IO_ESPIPE", "XML_IO_ESRCH", "XML_IO_ETIMEDOUT", "XML_IO_EXDEV", "XML_IO_NETWORK_ATTEMPT", "XML_IO_ENCODER", "XML_IO_FLUSH", "XML_IO_WRITE", "XML_IO_NO_INPUT", "XML_IO_BUFFER_FULL", "XML_IO_LOAD_ERROR", "XML_IO_ENOTSOCK", "XML_IO_EISCONN", "XML_IO_ECONNREFUSED", "XML_IO_ENETUNREACH", "XML_IO_EADDRINUSE", "XML_IO_EALREADY", "XML_IO_EAFNOSUPPORT", "XML_XINCLUDE_RECURSION", "XML_XINCLUDE_PARSE_VALUE", "XML_XINCLUDE_ENTITY_DEF_MISMATCH", "XML_XINCLUDE_NO_HREF", "XML_XINCLUDE_NO_FALLBACK", "XML_XINCLUDE_HREF_URI", "XML_XINCLUDE_TEXT_FRAGMENT", "XML_XINCLUDE_TEXT_DOCUMENT", "XML_XINCLUDE_INVALID_CHAR", "XML_XINCLUDE_BUILD_FAILED", "XML_XINCLUDE_UNKNOWN_ENCODING", "XML_XINCLUDE_MULTIPLE_ROOT", "XML_XINCLUDE_XPTR_FAILED", "XML_XINCLUDE_XPTR_RESULT", "XML_XINCLUDE_INCLUDE_IN_INCLUDE", "XML_XINCLUDE_FALLBACKS_IN_INCLUDE", "XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE", "XML_XINCLUDE_DEPRECATED_NS", "XML_XINCLUDE_FRAGMENT_ID", "XML_CATALOG_MISSING_ATTR", "XML_CATALOG_ENTRY_BROKEN", "XML_CATALOG_PREFER_VALUE", "XML_CATALOG_NOT_CATALOG", "XML_CATALOG_RECURSION", "XML_SCHEMAP_PREFIX_UNDEFINED", "XML_SCHEMAP_ATTRFORMDEFAULT_VALUE", "XML_SCHEMAP_ATTRGRP_NONAME_NOREF", "XML_SCHEMAP_ATTR_NONAME_NOREF", "XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF", "XML_SCHEMAP_ELEMFORMDEFAULT_VALUE", "XML_SCHEMAP_ELEM_NONAME_NOREF", "XML_SCHEMAP_EXTENSION_NO_BASE", "XML_SCHEMAP_FACET_NO_VALUE", "XML_SCHEMAP_FAILED_BUILD_IMPORT", "XML_SCHEMAP_GROUP_NONAME_NOREF", "XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI", "XML_SCHEMAP_IMPORT_REDEFINE_NSNAME", "XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI", "XML_SCHEMAP_INVALID_BOOLEAN", "XML_SCHEMAP_INVALID_ENUM", "XML_SCHEMAP_INVALID_FACET", "XML_SCHEMAP_INVALID_FACET_VALUE", "XML_SCHEMAP_INVALID_MAXOCCURS", "XML_SCHEMAP_INVALID_MINOCCURS", "XML_SCHEMAP_INVALID_REF_AND_SUBTYPE", "XML_SCHEMAP_INVALID_WHITE_SPACE", "XML_SCHEMAP_NOATTR_NOREF", "XML_SCHEMAP_NOTATION_NO_NAME", "XML_SCHEMAP_NOTYPE_NOREF", "XML_SCHEMAP_REF_AND_SUBTYPE", "XML_SCHEMAP_RESTRICTION_NONAME_NOREF", "XML_SCHEMAP_SIMPLETYPE_NONAME", "XML_SCHEMAP_TYPE_AND_SUBTYPE", "XML_SCHEMAP_UNKNOWN_ALL_CHILD", "XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD", "XML_SCHEMAP_UNKNOWN_ATTR_CHILD", "XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD", "XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP", "XML_SCHEMAP_UNKNOWN_BASE_TYPE", "XML_SCHEMAP_UNKNOWN_CHOICE_CHILD", "XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD", "XML_SCHEMAP_UNKNOWN_ELEM_CHILD", "XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD", "XML_SCHEMAP_UNKNOWN_FACET_CHILD", "XML_SCHEMAP_UNKNOWN_FACET_TYPE", "XML_SCHEMAP_UNKNOWN_GROUP_CHILD", "XML_SCHEMAP_UNKNOWN_IMPORT_CHILD", "XML_SCHEMAP_UNKNOWN_LIST_CHILD", "XML_SCHEMAP_UNKNOWN_NOTATION_CHILD", "XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_REF", "XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD", "XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD", "XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD", "XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD", "XML_SCHEMAP_UNKNOWN_TYPE", "XML_SCHEMAP_UNKNOWN_UNION_CHILD", "XML_SCHEMAP_ELEM_DEFAULT_FIXED", "XML_SCHEMAP_REGEXP_INVALID", "XML_SCHEMAP_FAILED_LOAD", "XML_SCHEMAP_NOTHING_TO_PARSE", "XML_SCHEMAP_NOROOT", "XML_SCHEMAP_REDEFINED_GROUP", "XML_SCHEMAP_REDEFINED_TYPE", "XML_SCHEMAP_REDEFINED_ELEMENT", "XML_SCHEMAP_REDEFINED_ATTRGROUP", "XML_SCHEMAP_REDEFINED_ATTR", "XML_SCHEMAP_REDEFINED_NOTATION", "XML_SCHEMAP_FAILED_PARSE", "XML_SCHEMAP_UNKNOWN_PREFIX", "XML_SCHEMAP_DEF_AND_PREFIX", "XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD", "XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI", "XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI", "XML_SCHEMAP_NOT_SCHEMA", "XML_SCHEMAP_UNKNOWN_MEMBER_TYPE", "XML_SCHEMAP_INVALID_ATTR_USE", "XML_SCHEMAP_RECURSIVE", "XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE", "XML_SCHEMAP_INVALID_ATTR_COMBINATION", "XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION", "XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD", "XML_SCHEMAP_INVALID_ATTR_NAME", "XML_SCHEMAP_REF_AND_CONTENT", "XML_SCHEMAP_CT_PROPS_CORRECT_1", "XML_SCHEMAP_CT_PROPS_CORRECT_2", "XML_SCHEMAP_CT_PROPS_CORRECT_3", "XML_SCHEMAP_CT_PROPS_CORRECT_4", "XML_SCHEMAP_CT_PROPS_CORRECT_5", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3", "XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER", "XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE", "XML_SCHEMAP_UNION_NOT_EXPRESSIBLE", "XML_SCHEMAP_SRC_IMPORT_3_1", "XML_SCHEMAP_SRC_IMPORT_3_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3", "XML_SCHEMAP_COS_CT_EXTENDS_1_3", "XML_SCHEMAV_NOROOT", "XML_SCHEMAV_UNDECLAREDELEM", "XML_SCHEMAV_NOTTOPLEVEL", "XML_SCHEMAV_MISSING", "XML_SCHEMAV_WRONGELEM", "XML_SCHEMAV_NOTYPE", "XML_SCHEMAV_NOROLLBACK", "XML_SCHEMAV_ISABSTRACT", "XML_SCHEMAV_NOTEMPTY", "XML_SCHEMAV_ELEMCONT", "XML_SCHEMAV_HAVEDEFAULT", "XML_SCHEMAV_NOTNILLABLE", "XML_SCHEMAV_EXTRACONTENT", "XML_SCHEMAV_INVALIDATTR", "XML_SCHEMAV_INVALIDELEM", "XML_SCHEMAV_NOTDETERMINIST", "XML_SCHEMAV_CONSTRUCT", "XML_SCHEMAV_INTERNAL", "XML_SCHEMAV_NOTSIMPLE", "XML_SCHEMAV_ATTRUNKNOWN", "XML_SCHEMAV_ATTRINVALID", "XML_SCHEMAV_VALUE", "XML_SCHEMAV_FACET", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3", "XML_SCHEMAV_CVC_TYPE_3_1_1", "XML_SCHEMAV_CVC_TYPE_3_1_2", "XML_SCHEMAV_CVC_FACET_VALID", "XML_SCHEMAV_CVC_LENGTH_VALID", "XML_SCHEMAV_CVC_MINLENGTH_VALID", "XML_SCHEMAV_CVC_MAXLENGTH_VALID", "XML_SCHEMAV_CVC_MININCLUSIVE_VALID", "XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID", "XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID", "XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID", "XML_SCHEMAV_CVC_TOTALDIGITS_VALID", "XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID", "XML_SCHEMAV_CVC_PATTERN_VALID", "XML_SCHEMAV_CVC_ENUMERATION_VALID", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4", "XML_SCHEMAV_CVC_ELT_1", "XML_SCHEMAV_CVC_ELT_2", "XML_SCHEMAV_CVC_ELT_3_1", "XML_SCHEMAV_CVC_ELT_3_2_1", "XML_SCHEMAV_CVC_ELT_3_2_2", "XML_SCHEMAV_CVC_ELT_4_1", "XML_SCHEMAV_CVC_ELT_4_2", "XML_SCHEMAV_CVC_ELT_4_3", "XML_SCHEMAV_CVC_ELT_5_1_1", "XML_SCHEMAV_CVC_ELT_5_1_2", "XML_SCHEMAV_CVC_ELT_5_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_2_2", "XML_SCHEMAV_CVC_ELT_6", "XML_SCHEMAV_CVC_ELT_7", "XML_SCHEMAV_CVC_ATTRIBUTE_1", "XML_SCHEMAV_CVC_ATTRIBUTE_2", "XML_SCHEMAV_CVC_ATTRIBUTE_3", "XML_SCHEMAV_CVC_ATTRIBUTE_4", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2", "XML_SCHEMAV_CVC_COMPLEX_TYPE_4", "XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2", "XML_SCHEMAV_ELEMENT_CONTENT", "XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING", "XML_SCHEMAV_CVC_COMPLEX_TYPE_1", "XML_SCHEMAV_CVC_AU", "XML_SCHEMAV_CVC_TYPE_1", "XML_SCHEMAV_CVC_TYPE_2", "XML_SCHEMAV_CVC_IDC", "XML_SCHEMAV_CVC_WILDCARD", "XML_SCHEMAV_MISC", "XML_XPTR_UNKNOWN_SCHEME", "XML_XPTR_CHILDSEQ_START", "XML_XPTR_EVAL_FAILED", "XML_XPTR_EXTRA_OBJECTS", "XML_C14N_CREATE_CTXT", "XML_C14N_REQUIRES_UTF8", "XML_C14N_CREATE_STACK", "XML_C14N_INVALID_NODE", "XML_C14N_UNKNOW_NODE", "XML_C14N_RELATIVE_NAMESPACE", "XML_FTP_PASV_ANSWER", "XML_FTP_EPSV_ANSWER", "XML_FTP_ACCNT", "XML_FTP_URL_SYNTAX", "XML_HTTP_URL_SYNTAX", "XML_HTTP_USE_IP", "XML_HTTP_UNKNOWN_HOST", "XML_SCHEMAP_SRC_SIMPLE_TYPE_1", "XML_SCHEMAP_SRC_SIMPLE_TYPE_2", "XML_SCHEMAP_SRC_SIMPLE_TYPE_3", "XML_SCHEMAP_SRC_SIMPLE_TYPE_4", "XML_SCHEMAP_SRC_RESOLVE", "XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE", "XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE", "XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES", "XML_SCHEMAP_ST_PROPS_CORRECT_1", "XML_SCHEMAP_ST_PROPS_CORRECT_2", "XML_SCHEMAP_ST_PROPS_CORRECT_3", "XML_SCHEMAP_COS_ST_RESTRICTS_1_1", "XML_SCHEMAP_COS_ST_RESTRICTS_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5", "XML_SCHEMAP_COS_ST_RESTRICTS_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5", "XML_SCHEMAP_COS_ST_DERIVED_OK_2_1", "XML_SCHEMAP_COS_ST_DERIVED_OK_2_2", "XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED", "XML_SCHEMAP_S4S_ELEM_MISSING", "XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED", "XML_SCHEMAP_S4S_ATTR_MISSING", "XML_SCHEMAP_S4S_ATTR_INVALID_VALUE", "XML_SCHEMAP_SRC_ELEMENT_1", "XML_SCHEMAP_SRC_ELEMENT_2_1", "XML_SCHEMAP_SRC_ELEMENT_2_2", "XML_SCHEMAP_SRC_ELEMENT_3", "XML_SCHEMAP_P_PROPS_CORRECT_1", "XML_SCHEMAP_P_PROPS_CORRECT_2_1", "XML_SCHEMAP_P_PROPS_CORRECT_2_2", "XML_SCHEMAP_E_PROPS_CORRECT_2", "XML_SCHEMAP_E_PROPS_CORRECT_3", "XML_SCHEMAP_E_PROPS_CORRECT_4", "XML_SCHEMAP_E_PROPS_CORRECT_5", "XML_SCHEMAP_E_PROPS_CORRECT_6", "XML_SCHEMAP_SRC_INCLUDE", "XML_SCHEMAP_SRC_ATTRIBUTE_1", "XML_SCHEMAP_SRC_ATTRIBUTE_2", "XML_SCHEMAP_SRC_ATTRIBUTE_3_1", "XML_SCHEMAP_SRC_ATTRIBUTE_3_2", "XML_SCHEMAP_SRC_ATTRIBUTE_4", "XML_SCHEMAP_NO_XMLNS", "XML_SCHEMAP_NO_XSI", "XML_SCHEMAP_COS_VALID_DEFAULT_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2", "XML_SCHEMAP_CVC_SIMPLE_TYPE", "XML_SCHEMAP_COS_CT_EXTENDS_1_1", "XML_SCHEMAP_SRC_IMPORT_1_1", "XML_SCHEMAP_SRC_IMPORT_1_2", "XML_SCHEMAP_SRC_IMPORT_2", "XML_SCHEMAP_SRC_IMPORT_2_1", "XML_SCHEMAP_SRC_IMPORT_2_2", "XML_SCHEMAP_INTERNAL", "XML_SCHEMAP_NOT_DETERMINISTIC", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3", "XML_SCHEMAP_MG_PROPS_CORRECT_1", "XML_SCHEMAP_MG_PROPS_CORRECT_2", "XML_SCHEMAP_SRC_CT_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3", "XML_SCHEMAP_AU_PROPS_CORRECT_2", "XML_SCHEMAP_A_PROPS_CORRECT_2", "XML_SCHEMAP_C_PROPS_CORRECT", "XML_SCHEMAP_SRC_REDEFINE", "XML_SCHEMAP_SRC_IMPORT", "XML_SCHEMAP_WARN_SKIP_SCHEMA", "XML_SCHEMAP_WARN_UNLOCATED_SCHEMA", "XML_SCHEMAP_WARN_ATTR_REDECL_PROH", "XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH", "XML_SCHEMAP_AG_PROPS_CORRECT", "XML_SCHEMAP_COS_CT_EXTENDS_1_2", "XML_SCHEMAP_AU_PROPS_CORRECT", "XML_SCHEMAP_A_PROPS_CORRECT_3", "XML_SCHEMAP_COS_ALL_LIMITED", "XML_SCHEMATRONV_ASSERT", "XML_SCHEMATRONV_REPORT", "XML_MODULE_OPEN", "XML_MODULE_CLOSE", "XML_CHECK_FOUND_ELEMENT", "XML_CHECK_FOUND_ATTRIBUTE", "XML_CHECK_FOUND_TEXT", "XML_CHECK_FOUND_CDATA", "XML_CHECK_FOUND_ENTITYREF", "XML_CHECK_FOUND_ENTITY", "XML_CHECK_FOUND_PI", "XML_CHECK_FOUND_COMMENT", "XML_CHECK_FOUND_DOCTYPE", "XML_CHECK_FOUND_FRAGMENT", "XML_CHECK_FOUND_NOTATION", "XML_CHECK_UNKNOWN_NODE", "XML_CHECK_ENTITY_TYPE", "XML_CHECK_NO_PARENT", "XML_CHECK_NO_DOC", "XML_CHECK_NO_NAME", "XML_CHECK_NO_ELEM", "XML_CHECK_WRONG_DOC", "XML_CHECK_NO_PREV", "XML_CHECK_WRONG_PREV", "XML_CHECK_NO_NEXT", "XML_CHECK_WRONG_NEXT", "XML_CHECK_NOT_DTD", "XML_CHECK_NOT_ATTR", "XML_CHECK_NOT_ATTR_DECL", "XML_CHECK_NOT_ELEM_DECL", "XML_CHECK_NOT_ENTITY_DECL", "XML_CHECK_NOT_NS_DECL", "XML_CHECK_NO_HREF", "XML_CHECK_WRONG_PARENT", "XML_CHECK_NS_SCOPE", "XML_CHECK_NS_ANCESTOR", "XML_CHECK_NOT_UTF8", "XML_CHECK_NO_DICT", "XML_CHECK_NOT_NCNAME", "XML_CHECK_OUTSIDE_DICT", "XML_CHECK_WRONG_NAME", "XML_CHECK_NAME_NOT_NULL", "XML_I18N_NO_NAME", "XML_I18N_NO_HANDLER", "XML_I18N_EXCESS_HANDLER", "XML_I18N_CONV_FAILED", "XML_I18N_NO_OUTPUT" )) XMLDomainErrors <- structure(0:28, .Names = c("NONE", "PARSER", "TREE", "NAMESPACE", "DTD", "HTML", "MEMORY", "OUTPUT", "IO", "FTP", "HTTP", "XINCLUDE", "XPATH", "XPOINTER", "REGEXP", "DATATYPE", "SCHEMASP", "SCHEMASV", "RELAXNGP", "RELAXNGV", "CATALOG", "C14N", "XSLT", "VALID", "CHECK", "WRITER", "MODULE", "I18N", "SCHEMATRONV")) XML/R/solrDocs.R0000644000175100001440000000247213607633674013070 0ustar hornikuserssetGeneric("readSolrDoc", function(doc, ...) standardGeneric("readSolrDoc")) setMethod("readSolrDoc", "character", function(doc, ...) readSolrDoc(xmlParse(doc), ...)) setMethod("readSolrDoc", "AsIs", function(doc, ...) readSolrDoc(xmlParse(doc), ...)) setMethod("readSolrDoc", "XMLInternalDocument", function(doc, ...) readSolrDoc(xmlRoot(doc), ...)) setMethod("readSolrDoc", "XMLInternalNode", function(doc, ...) { kids = xmlChildren(doc) kids = kids[!sapply(kids, inherits, "XMLInternalCommentNode")] if(length(kids) == 0) return(list()) keys = sapply(kids, xmlGetAttr, "name") structure(lapply(kids, readSolrNodeValue), names = keys) }) readSolrNodeValue = function(node) { id = xmlName(node) switch(id, int = if(abs(tmp <- as.numeric(xmlValue(node))) > .Machine$integer.max) tmp else as.integer(xmlValue(node)), long = as.numeric(xmlValue(node)), str = xmlValue(node), lst = readSolrDoc(node), bool = as.logical(xmlValue(node)), date = as.POSIXct(strptime(xmlValue(node), "%Y-%m-%dT%H:%M:%SZ")), ) } XML/R/xmlErrorEnums.R0000644000175100001440000006464513607633670014130 0ustar hornikusers# Machine generated file. See org/omegahat/XML/RS/TU/tu.R # Wed Feb 13 03:17:42 2008 xmlErrorLevel <-structure(0:3, .Names = c("XML_ERR_NONE", "XML_ERR_WARNING", "XML_ERR_ERROR", "XML_ERR_FATAL")) xmlErrorDomain <-structure(0:27, .Names = c("XML_FROM_NONE", "XML_FROM_PARSER", "XML_FROM_TREE", "XML_FROM_NAMESPACE", "XML_FROM_DTD", "XML_FROM_HTML", "XML_FROM_MEMORY", "XML_FROM_OUTPUT", "XML_FROM_IO", "XML_FROM_FTP", "XML_FROM_HTTP", "XML_FROM_XINCLUDE", "XML_FROM_XPATH", "XML_FROM_XPOINTER", "XML_FROM_REGEXP", "XML_FROM_DATATYPE", "XML_FROM_SCHEMASP", "XML_FROM_SCHEMASV", "XML_FROM_RELAXNGP", "XML_FROM_RELAXNGV", "XML_FROM_CATALOG", "XML_FROM_C14N", "XML_FROM_XSLT", "XML_FROM_VALID", "XML_FROM_CHECK", "XML_FROM_WRITER", "XML_FROM_MODULE", "XML_FROM_I18N" )) xmlParserErrors <-structure(c(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 52L, 53L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L, 66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 76L, 77L, 78L, 79L, 80L, 81L, 82L, 83L, 84L, 85L, 86L, 87L, 88L, 89L, 90L, 91L, 92L, 93L, 94L, 95L, 96L, 97L, 98L, 99L, 100L, 101L, 102L, 103L, 104L, 105L, 106L, 107L, 200L, 201L, 202L, 203L, 204L, 500L, 501L, 502L, 503L, 504L, 505L, 506L, 507L, 508L, 509L, 510L, 511L, 512L, 513L, 514L, 515L, 516L, 517L, 518L, 519L, 520L, 521L, 522L, 523L, 524L, 525L, 526L, 527L, 528L, 529L, 530L, 531L, 532L, 533L, 534L, 535L, 536L, 537L, 538L, 539L, 540L, 800L, 801L, 1000L, 1001L, 1002L, 1003L, 1004L, 1005L, 1006L, 1007L, 1008L, 1009L, 1010L, 1011L, 1012L, 1013L, 1014L, 1015L, 1016L, 1017L, 1018L, 1019L, 1020L, 1021L, 1022L, 1023L, 1024L, 1025L, 1026L, 1027L, 1028L, 1029L, 1030L, 1031L, 1032L, 1033L, 1034L, 1035L, 1036L, 1037L, 1038L, 1039L, 1040L, 1041L, 1042L, 1043L, 1044L, 1045L, 1046L, 1047L, 1048L, 1049L, 1050L, 1051L, 1052L, 1053L, 1054L, 1055L, 1056L, 1057L, 1058L, 1059L, 1060L, 1061L, 1062L, 1063L, 1064L, 1065L, 1066L, 1067L, 1068L, 1069L, 1070L, 1071L, 1072L, 1073L, 1074L, 1075L, 1076L, 1077L, 1078L, 1079L, 1080L, 1081L, 1082L, 1083L, 1084L, 1085L, 1086L, 1087L, 1088L, 1089L, 1090L, 1091L, 1092L, 1093L, 1094L, 1095L, 1096L, 1097L, 1098L, 1099L, 1100L, 1101L, 1102L, 1103L, 1104L, 1105L, 1106L, 1107L, 1108L, 1109L, 1110L, 1111L, 1112L, 1113L, 1114L, 1115L, 1116L, 1117L, 1118L, 1119L, 1120L, 1121L, 1122L, 1200L, 1201L, 1202L, 1203L, 1204L, 1205L, 1206L, 1207L, 1208L, 1209L, 1210L, 1211L, 1212L, 1213L, 1214L, 1215L, 1216L, 1217L, 1218L, 1219L, 1220L, 1221L, 1300L, 1301L, 1302L, 1400L, 1401L, 1402L, 1403L, 1450L, 1500L, 1501L, 1502L, 1503L, 1504L, 1505L, 1506L, 1507L, 1508L, 1509L, 1510L, 1511L, 1512L, 1513L, 1514L, 1515L, 1516L, 1517L, 1518L, 1519L, 1520L, 1521L, 1522L, 1523L, 1524L, 1525L, 1526L, 1527L, 1528L, 1529L, 1530L, 1531L, 1532L, 1533L, 1534L, 1535L, 1536L, 1537L, 1538L, 1539L, 1540L, 1541L, 1542L, 1543L, 1544L, 1545L, 1546L, 1547L, 1548L, 1549L, 1550L, 1551L, 1552L, 1553L, 1554L, 1555L, 1556L, 1600L, 1601L, 1602L, 1603L, 1604L, 1605L, 1606L, 1607L, 1608L, 1609L, 1610L, 1611L, 1612L, 1613L, 1614L, 1615L, 1616L, 1617L, 1618L, 1650L, 1651L, 1652L, 1653L, 1654L, 1700L, 1701L, 1702L, 1703L, 1704L, 1705L, 1706L, 1707L, 1708L, 1709L, 1710L, 1711L, 1712L, 1713L, 1714L, 1715L, 1716L, 1717L, 1718L, 1719L, 1720L, 1721L, 1722L, 1723L, 1724L, 1725L, 1726L, 1727L, 1728L, 1729L, 1730L, 1731L, 1732L, 1733L, 1734L, 1735L, 1736L, 1737L, 1738L, 1739L, 1740L, 1741L, 1742L, 1743L, 1744L, 1745L, 1746L, 1747L, 1748L, 1749L, 1750L, 1751L, 1752L, 1753L, 1754L, 1755L, 1756L, 1757L, 1758L, 1759L, 1760L, 1761L, 1762L, 1763L, 1764L, 1765L, 1766L, 1767L, 1768L, 1769L, 1770L, 1771L, 1772L, 1773L, 1774L, 1775L, 1776L, 1777L, 1778L, 1779L, 1780L, 1781L, 1782L, 1783L, 1784L, 1785L, 1786L, 1787L, 1788L, 1789L, 1790L, 1791L, 1792L, 1793L, 1794L, 1795L, 1796L, 1797L, 1798L, 1799L, 1800L, 1801L, 1802L, 1803L, 1804L, 1805L, 1806L, 1807L, 1808L, 1809L, 1810L, 1811L, 1812L, 1813L, 1814L, 1815L, 1816L, 1817L, 1818L, 1819L, 1820L, 1821L, 1822L, 1823L, 1824L, 1825L, 1826L, 1827L, 1828L, 1829L, 1830L, 1831L, 1832L, 1833L, 1834L, 1835L, 1836L, 1837L, 1838L, 1839L, 1840L, 1841L, 1842L, 1843L, 1844L, 1845L, 1846L, 1847L, 1848L, 1849L, 1850L, 1851L, 1852L, 1853L, 1854L, 1855L, 1856L, 1857L, 1858L, 1859L, 1860L, 1861L, 1862L, 1863L, 1864L, 1865L, 1866L, 1867L, 1868L, 1869L, 1870L, 1871L, 1872L, 1873L, 1874L, 1875L, 1876L, 1877L, 1878L, 1879L, 1900L, 1901L, 1902L, 1903L, 1950L, 1951L, 1952L, 1953L, 1954L, 1955L, 2000L, 2001L, 2002L, 2003L, 2020L, 2021L, 2022L, 3000L, 3001L, 3002L, 3003L, 3004L, 3005L, 3006L, 3007L, 3008L, 3009L, 3010L, 3011L, 3012L, 3013L, 3014L, 3015L, 3016L, 3017L, 3018L, 3019L, 3020L, 3021L, 3022L, 3023L, 3024L, 3025L, 3026L, 3027L, 3028L, 3029L, 3030L, 3031L, 3032L, 3033L, 3034L, 3035L, 3036L, 3037L, 3038L, 3039L, 3040L, 3041L, 3042L, 3043L, 3044L, 3045L, 3046L, 3047L, 3048L, 3049L, 3050L, 3051L, 3052L, 3053L, 3054L, 3055L, 3056L, 3057L, 3058L, 3059L, 3060L, 3061L, 3062L, 3063L, 3064L, 3065L, 3066L, 3067L, 3068L, 3069L, 3070L, 3071L, 3072L, 3073L, 3074L, 3075L, 3076L, 3077L, 3078L, 3079L, 3080L, 3081L, 3082L, 3083L, 3084L, 3085L, 3086L, 3087L, 3088L, 3089L, 3090L, 3091L, 4900L, 4901L, 5000L, 5001L, 5002L, 5003L, 5004L, 5005L, 5006L, 5007L, 5008L, 5009L, 5010L, 5011L, 5012L, 5013L, 5014L, 5015L, 5016L, 5017L, 5018L, 5019L, 5020L, 5021L, 5022L, 5023L, 5024L, 5025L, 5026L, 5027L, 5028L, 5029L, 5030L, 5031L, 5032L, 5033L, 5034L, 5035L, 5036L, 5037L, 6000L, 6001L, 6002L, 6003L, 6004L ), .Names = c("XML_ERR_OK", "XML_ERR_INTERNAL_ERROR", "XML_ERR_NO_MEMORY", "XML_ERR_DOCUMENT_START", "XML_ERR_DOCUMENT_EMPTY", "XML_ERR_DOCUMENT_END", "XML_ERR_INVALID_HEX_CHARREF", "XML_ERR_INVALID_DEC_CHARREF", "XML_ERR_INVALID_CHARREF", "XML_ERR_INVALID_CHAR", "XML_ERR_CHARREF_AT_EOF", "XML_ERR_CHARREF_IN_PROLOG", "XML_ERR_CHARREF_IN_EPILOG", "XML_ERR_CHARREF_IN_DTD", "XML_ERR_ENTITYREF_AT_EOF", "XML_ERR_ENTITYREF_IN_PROLOG", "XML_ERR_ENTITYREF_IN_EPILOG", "XML_ERR_ENTITYREF_IN_DTD", "XML_ERR_PEREF_AT_EOF", "XML_ERR_PEREF_IN_PROLOG", "XML_ERR_PEREF_IN_EPILOG", "XML_ERR_PEREF_IN_INT_SUBSET", "XML_ERR_ENTITYREF_NO_NAME", "XML_ERR_ENTITYREF_SEMICOL_MISSING", "XML_ERR_PEREF_NO_NAME", "XML_ERR_PEREF_SEMICOL_MISSING", "XML_ERR_UNDECLARED_ENTITY", "XML_WAR_UNDECLARED_ENTITY", "XML_ERR_UNPARSED_ENTITY", "XML_ERR_ENTITY_IS_EXTERNAL", "XML_ERR_ENTITY_IS_PARAMETER", "XML_ERR_UNKNOWN_ENCODING", "XML_ERR_UNSUPPORTED_ENCODING", "XML_ERR_STRING_NOT_STARTED", "XML_ERR_STRING_NOT_CLOSED", "XML_ERR_NS_DECL_ERROR", "XML_ERR_ENTITY_NOT_STARTED", "XML_ERR_ENTITY_NOT_FINISHED", "XML_ERR_LT_IN_ATTRIBUTE", "XML_ERR_ATTRIBUTE_NOT_STARTED", "XML_ERR_ATTRIBUTE_NOT_FINISHED", "XML_ERR_ATTRIBUTE_WITHOUT_VALUE", "XML_ERR_ATTRIBUTE_REDEFINED", "XML_ERR_LITERAL_NOT_STARTED", "XML_ERR_LITERAL_NOT_FINISHED", "XML_ERR_COMMENT_NOT_FINISHED", "XML_ERR_PI_NOT_STARTED", "XML_ERR_PI_NOT_FINISHED", "XML_ERR_NOTATION_NOT_STARTED", "XML_ERR_NOTATION_NOT_FINISHED", "XML_ERR_ATTLIST_NOT_STARTED", "XML_ERR_ATTLIST_NOT_FINISHED", "XML_ERR_MIXED_NOT_STARTED", "XML_ERR_MIXED_NOT_FINISHED", "XML_ERR_ELEMCONTENT_NOT_STARTED", "XML_ERR_ELEMCONTENT_NOT_FINISHED", "XML_ERR_XMLDECL_NOT_STARTED", "XML_ERR_XMLDECL_NOT_FINISHED", "XML_ERR_CONDSEC_NOT_STARTED", "XML_ERR_CONDSEC_NOT_FINISHED", "XML_ERR_EXT_SUBSET_NOT_FINISHED", "XML_ERR_DOCTYPE_NOT_FINISHED", "XML_ERR_MISPLACED_CDATA_END", "XML_ERR_CDATA_NOT_FINISHED", "XML_ERR_RESERVED_XML_NAME", "XML_ERR_SPACE_REQUIRED", "XML_ERR_SEPARATOR_REQUIRED", "XML_ERR_NMTOKEN_REQUIRED", "XML_ERR_NAME_REQUIRED", "XML_ERR_PCDATA_REQUIRED", "XML_ERR_URI_REQUIRED", "XML_ERR_PUBID_REQUIRED", "XML_ERR_LT_REQUIRED", "XML_ERR_GT_REQUIRED", "XML_ERR_LTSLASH_REQUIRED", "XML_ERR_EQUAL_REQUIRED", "XML_ERR_TAG_NAME_MISMATCH", "XML_ERR_TAG_NOT_FINISHED", "XML_ERR_STANDALONE_VALUE", "XML_ERR_ENCODING_NAME", "XML_ERR_HYPHEN_IN_COMMENT", "XML_ERR_INVALID_ENCODING", "XML_ERR_EXT_ENTITY_STANDALONE", "XML_ERR_CONDSEC_INVALID", "XML_ERR_VALUE_REQUIRED", "XML_ERR_NOT_WELL_BALANCED", "XML_ERR_EXTRA_CONTENT", "XML_ERR_ENTITY_CHAR_ERROR", "XML_ERR_ENTITY_PE_INTERNAL", "XML_ERR_ENTITY_LOOP", "XML_ERR_ENTITY_BOUNDARY", "XML_ERR_INVALID_URI", "XML_ERR_URI_FRAGMENT", "XML_WAR_CATALOG_PI", "XML_ERR_NO_DTD", "XML_ERR_CONDSEC_INVALID_KEYWORD", "XML_ERR_VERSION_MISSING", "XML_WAR_UNKNOWN_VERSION", "XML_WAR_LANG_VALUE", "XML_WAR_NS_URI", "XML_WAR_NS_URI_RELATIVE", "XML_ERR_MISSING_ENCODING", "XML_WAR_SPACE_VALUE", "XML_ERR_NOT_STANDALONE", "XML_ERR_ENTITY_PROCESSING", "XML_ERR_NOTATION_PROCESSING", "XML_WAR_NS_COLUMN", "XML_WAR_ENTITY_REDEFINED", "XML_NS_ERR_XML_NAMESPACE", "XML_NS_ERR_UNDEFINED_NAMESPACE", "XML_NS_ERR_QNAME", "XML_NS_ERR_ATTRIBUTE_REDEFINED", "XML_NS_ERR_EMPTY", "XML_DTD_ATTRIBUTE_DEFAULT", "XML_DTD_ATTRIBUTE_REDEFINED", "XML_DTD_ATTRIBUTE_VALUE", "XML_DTD_CONTENT_ERROR", "XML_DTD_CONTENT_MODEL", "XML_DTD_CONTENT_NOT_DETERMINIST", "XML_DTD_DIFFERENT_PREFIX", "XML_DTD_ELEM_DEFAULT_NAMESPACE", "XML_DTD_ELEM_NAMESPACE", "XML_DTD_ELEM_REDEFINED", "XML_DTD_EMPTY_NOTATION", "XML_DTD_ENTITY_TYPE", "XML_DTD_ID_FIXED", "XML_DTD_ID_REDEFINED", "XML_DTD_ID_SUBSET", "XML_DTD_INVALID_CHILD", "XML_DTD_INVALID_DEFAULT", "XML_DTD_LOAD_ERROR", "XML_DTD_MISSING_ATTRIBUTE", "XML_DTD_MIXED_CORRUPT", "XML_DTD_MULTIPLE_ID", "XML_DTD_NO_DOC", "XML_DTD_NO_DTD", "XML_DTD_NO_ELEM_NAME", "XML_DTD_NO_PREFIX", "XML_DTD_NO_ROOT", "XML_DTD_NOTATION_REDEFINED", "XML_DTD_NOTATION_VALUE", "XML_DTD_NOT_EMPTY", "XML_DTD_NOT_PCDATA", "XML_DTD_NOT_STANDALONE", "XML_DTD_ROOT_NAME", "XML_DTD_STANDALONE_WHITE_SPACE", "XML_DTD_UNKNOWN_ATTRIBUTE", "XML_DTD_UNKNOWN_ELEM", "XML_DTD_UNKNOWN_ENTITY", "XML_DTD_UNKNOWN_ID", "XML_DTD_UNKNOWN_NOTATION", "XML_DTD_STANDALONE_DEFAULTED", "XML_DTD_XMLID_VALUE", "XML_DTD_XMLID_TYPE", "XML_HTML_STRUCURE_ERROR", "XML_HTML_UNKNOWN_TAG", "XML_RNGP_ANYNAME_ATTR_ANCESTOR", "XML_RNGP_ATTR_CONFLICT", "XML_RNGP_ATTRIBUTE_CHILDREN", "XML_RNGP_ATTRIBUTE_CONTENT", "XML_RNGP_ATTRIBUTE_EMPTY", "XML_RNGP_ATTRIBUTE_NOOP", "XML_RNGP_CHOICE_CONTENT", "XML_RNGP_CHOICE_EMPTY", "XML_RNGP_CREATE_FAILURE", "XML_RNGP_DATA_CONTENT", "XML_RNGP_DEF_CHOICE_AND_INTERLEAVE", "XML_RNGP_DEFINE_CREATE_FAILED", "XML_RNGP_DEFINE_EMPTY", "XML_RNGP_DEFINE_MISSING", "XML_RNGP_DEFINE_NAME_MISSING", "XML_RNGP_ELEM_CONTENT_EMPTY", "XML_RNGP_ELEM_CONTENT_ERROR", "XML_RNGP_ELEMENT_EMPTY", "XML_RNGP_ELEMENT_CONTENT", "XML_RNGP_ELEMENT_NAME", "XML_RNGP_ELEMENT_NO_CONTENT", "XML_RNGP_ELEM_TEXT_CONFLICT", "XML_RNGP_EMPTY", "XML_RNGP_EMPTY_CONSTRUCT", "XML_RNGP_EMPTY_CONTENT", "XML_RNGP_EMPTY_NOT_EMPTY", "XML_RNGP_ERROR_TYPE_LIB", "XML_RNGP_EXCEPT_EMPTY", "XML_RNGP_EXCEPT_MISSING", "XML_RNGP_EXCEPT_MULTIPLE", "XML_RNGP_EXCEPT_NO_CONTENT", "XML_RNGP_EXTERNALREF_EMTPY", "XML_RNGP_EXTERNAL_REF_FAILURE", "XML_RNGP_EXTERNALREF_RECURSE", "XML_RNGP_FORBIDDEN_ATTRIBUTE", "XML_RNGP_FOREIGN_ELEMENT", "XML_RNGP_GRAMMAR_CONTENT", "XML_RNGP_GRAMMAR_EMPTY", "XML_RNGP_GRAMMAR_MISSING", "XML_RNGP_GRAMMAR_NO_START", "XML_RNGP_GROUP_ATTR_CONFLICT", "XML_RNGP_HREF_ERROR", "XML_RNGP_INCLUDE_EMPTY", "XML_RNGP_INCLUDE_FAILURE", "XML_RNGP_INCLUDE_RECURSE", "XML_RNGP_INTERLEAVE_ADD", "XML_RNGP_INTERLEAVE_CREATE_FAILED", "XML_RNGP_INTERLEAVE_EMPTY", "XML_RNGP_INTERLEAVE_NO_CONTENT", "XML_RNGP_INVALID_DEFINE_NAME", "XML_RNGP_INVALID_URI", "XML_RNGP_INVALID_VALUE", "XML_RNGP_MISSING_HREF", "XML_RNGP_NAME_MISSING", "XML_RNGP_NEED_COMBINE", "XML_RNGP_NOTALLOWED_NOT_EMPTY", "XML_RNGP_NSNAME_ATTR_ANCESTOR", "XML_RNGP_NSNAME_NO_NS", "XML_RNGP_PARAM_FORBIDDEN", "XML_RNGP_PARAM_NAME_MISSING", "XML_RNGP_PARENTREF_CREATE_FAILED", "XML_RNGP_PARENTREF_NAME_INVALID", "XML_RNGP_PARENTREF_NO_NAME", "XML_RNGP_PARENTREF_NO_PARENT", "XML_RNGP_PARENTREF_NOT_EMPTY", "XML_RNGP_PARSE_ERROR", "XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME", "XML_RNGP_PAT_ATTR_ATTR", "XML_RNGP_PAT_ATTR_ELEM", "XML_RNGP_PAT_DATA_EXCEPT_ATTR", "XML_RNGP_PAT_DATA_EXCEPT_ELEM", "XML_RNGP_PAT_DATA_EXCEPT_EMPTY", "XML_RNGP_PAT_DATA_EXCEPT_GROUP", "XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE", "XML_RNGP_PAT_DATA_EXCEPT_LIST", "XML_RNGP_PAT_DATA_EXCEPT_ONEMORE", "XML_RNGP_PAT_DATA_EXCEPT_REF", "XML_RNGP_PAT_DATA_EXCEPT_TEXT", "XML_RNGP_PAT_LIST_ATTR", "XML_RNGP_PAT_LIST_ELEM", "XML_RNGP_PAT_LIST_INTERLEAVE", "XML_RNGP_PAT_LIST_LIST", "XML_RNGP_PAT_LIST_REF", "XML_RNGP_PAT_LIST_TEXT", "XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME", "XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME", "XML_RNGP_PAT_ONEMORE_GROUP_ATTR", "XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR", "XML_RNGP_PAT_START_ATTR", "XML_RNGP_PAT_START_DATA", "XML_RNGP_PAT_START_EMPTY", "XML_RNGP_PAT_START_GROUP", "XML_RNGP_PAT_START_INTERLEAVE", "XML_RNGP_PAT_START_LIST", "XML_RNGP_PAT_START_ONEMORE", "XML_RNGP_PAT_START_TEXT", "XML_RNGP_PAT_START_VALUE", "XML_RNGP_PREFIX_UNDEFINED", "XML_RNGP_REF_CREATE_FAILED", "XML_RNGP_REF_CYCLE", "XML_RNGP_REF_NAME_INVALID", "XML_RNGP_REF_NO_DEF", "XML_RNGP_REF_NO_NAME", "XML_RNGP_REF_NOT_EMPTY", "XML_RNGP_START_CHOICE_AND_INTERLEAVE", "XML_RNGP_START_CONTENT", "XML_RNGP_START_EMPTY", "XML_RNGP_START_MISSING", "XML_RNGP_TEXT_EXPECTED", "XML_RNGP_TEXT_HAS_CHILD", "XML_RNGP_TYPE_MISSING", "XML_RNGP_TYPE_NOT_FOUND", "XML_RNGP_TYPE_VALUE", "XML_RNGP_UNKNOWN_ATTRIBUTE", "XML_RNGP_UNKNOWN_COMBINE", "XML_RNGP_UNKNOWN_CONSTRUCT", "XML_RNGP_UNKNOWN_TYPE_LIB", "XML_RNGP_URI_FRAGMENT", "XML_RNGP_URI_NOT_ABSOLUTE", "XML_RNGP_VALUE_EMPTY", "XML_RNGP_VALUE_NO_CONTENT", "XML_RNGP_XMLNS_NAME", "XML_RNGP_XML_NS", "XML_XPATH_EXPRESSION_OK", "XML_XPATH_NUMBER_ERROR", "XML_XPATH_UNFINISHED_LITERAL_ERROR", "XML_XPATH_START_LITERAL_ERROR", "XML_XPATH_VARIABLE_REF_ERROR", "XML_XPATH_UNDEF_VARIABLE_ERROR", "XML_XPATH_INVALID_PREDICATE_ERROR", "XML_XPATH_EXPR_ERROR", "XML_XPATH_UNCLOSED_ERROR", "XML_XPATH_UNKNOWN_FUNC_ERROR", "XML_XPATH_INVALID_OPERAND", "XML_XPATH_INVALID_TYPE", "XML_XPATH_INVALID_ARITY", "XML_XPATH_INVALID_CTXT_SIZE", "XML_XPATH_INVALID_CTXT_POSITION", "XML_XPATH_MEMORY_ERROR", "XML_XPTR_SYNTAX_ERROR", "XML_XPTR_RESOURCE_ERROR", "XML_XPTR_SUB_RESOURCE_ERROR", "XML_XPATH_UNDEF_PREFIX_ERROR", "XML_XPATH_ENCODING_ERROR", "XML_XPATH_INVALID_CHAR_ERROR", "XML_TREE_INVALID_HEX", "XML_TREE_INVALID_DEC", "XML_TREE_UNTERMINATED_ENTITY", "XML_SAVE_NOT_UTF8", "XML_SAVE_CHAR_INVALID", "XML_SAVE_NO_DOCTYPE", "XML_SAVE_UNKNOWN_ENCODING", "XML_REGEXP_COMPILE_ERROR", "XML_IO_UNKNOWN", "XML_IO_EACCES", "XML_IO_EAGAIN", "XML_IO_EBADF", "XML_IO_EBADMSG", "XML_IO_EBUSY", "XML_IO_ECANCELED", "XML_IO_ECHILD", "XML_IO_EDEADLK", "XML_IO_EDOM", "XML_IO_EEXIST", "XML_IO_EFAULT", "XML_IO_EFBIG", "XML_IO_EINPROGRESS", "XML_IO_EINTR", "XML_IO_EINVAL", "XML_IO_EIO", "XML_IO_EISDIR", "XML_IO_EMFILE", "XML_IO_EMLINK", "XML_IO_EMSGSIZE", "XML_IO_ENAMETOOLONG", "XML_IO_ENFILE", "XML_IO_ENODEV", "XML_IO_ENOENT", "XML_IO_ENOEXEC", "XML_IO_ENOLCK", "XML_IO_ENOMEM", "XML_IO_ENOSPC", "XML_IO_ENOSYS", "XML_IO_ENOTDIR", "XML_IO_ENOTEMPTY", "XML_IO_ENOTSUP", "XML_IO_ENOTTY", "XML_IO_ENXIO", "XML_IO_EPERM", "XML_IO_EPIPE", "XML_IO_ERANGE", "XML_IO_EROFS", "XML_IO_ESPIPE", "XML_IO_ESRCH", "XML_IO_ETIMEDOUT", "XML_IO_EXDEV", "XML_IO_NETWORK_ATTEMPT", "XML_IO_ENCODER", "XML_IO_FLUSH", "XML_IO_WRITE", "XML_IO_NO_INPUT", "XML_IO_BUFFER_FULL", "XML_IO_LOAD_ERROR", "XML_IO_ENOTSOCK", "XML_IO_EISCONN", "XML_IO_ECONNREFUSED", "XML_IO_ENETUNREACH", "XML_IO_EADDRINUSE", "XML_IO_EALREADY", "XML_IO_EAFNOSUPPORT", "XML_XINCLUDE_RECURSION", "XML_XINCLUDE_PARSE_VALUE", "XML_XINCLUDE_ENTITY_DEF_MISMATCH", "XML_XINCLUDE_NO_HREF", "XML_XINCLUDE_NO_FALLBACK", "XML_XINCLUDE_HREF_URI", "XML_XINCLUDE_TEXT_FRAGMENT", "XML_XINCLUDE_TEXT_DOCUMENT", "XML_XINCLUDE_INVALID_CHAR", "XML_XINCLUDE_BUILD_FAILED", "XML_XINCLUDE_UNKNOWN_ENCODING", "XML_XINCLUDE_MULTIPLE_ROOT", "XML_XINCLUDE_XPTR_FAILED", "XML_XINCLUDE_XPTR_RESULT", "XML_XINCLUDE_INCLUDE_IN_INCLUDE", "XML_XINCLUDE_FALLBACKS_IN_INCLUDE", "XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE", "XML_XINCLUDE_DEPRECATED_NS", "XML_XINCLUDE_FRAGMENT_ID", "XML_CATALOG_MISSING_ATTR", "XML_CATALOG_ENTRY_BROKEN", "XML_CATALOG_PREFER_VALUE", "XML_CATALOG_NOT_CATALOG", "XML_CATALOG_RECURSION", "XML_SCHEMAP_PREFIX_UNDEFINED", "XML_SCHEMAP_ATTRFORMDEFAULT_VALUE", "XML_SCHEMAP_ATTRGRP_NONAME_NOREF", "XML_SCHEMAP_ATTR_NONAME_NOREF", "XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF", "XML_SCHEMAP_ELEMFORMDEFAULT_VALUE", "XML_SCHEMAP_ELEM_NONAME_NOREF", "XML_SCHEMAP_EXTENSION_NO_BASE", "XML_SCHEMAP_FACET_NO_VALUE", "XML_SCHEMAP_FAILED_BUILD_IMPORT", "XML_SCHEMAP_GROUP_NONAME_NOREF", "XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI", "XML_SCHEMAP_IMPORT_REDEFINE_NSNAME", "XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI", "XML_SCHEMAP_INVALID_BOOLEAN", "XML_SCHEMAP_INVALID_ENUM", "XML_SCHEMAP_INVALID_FACET", "XML_SCHEMAP_INVALID_FACET_VALUE", "XML_SCHEMAP_INVALID_MAXOCCURS", "XML_SCHEMAP_INVALID_MINOCCURS", "XML_SCHEMAP_INVALID_REF_AND_SUBTYPE", "XML_SCHEMAP_INVALID_WHITE_SPACE", "XML_SCHEMAP_NOATTR_NOREF", "XML_SCHEMAP_NOTATION_NO_NAME", "XML_SCHEMAP_NOTYPE_NOREF", "XML_SCHEMAP_REF_AND_SUBTYPE", "XML_SCHEMAP_RESTRICTION_NONAME_NOREF", "XML_SCHEMAP_SIMPLETYPE_NONAME", "XML_SCHEMAP_TYPE_AND_SUBTYPE", "XML_SCHEMAP_UNKNOWN_ALL_CHILD", "XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD", "XML_SCHEMAP_UNKNOWN_ATTR_CHILD", "XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD", "XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP", "XML_SCHEMAP_UNKNOWN_BASE_TYPE", "XML_SCHEMAP_UNKNOWN_CHOICE_CHILD", "XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD", "XML_SCHEMAP_UNKNOWN_ELEM_CHILD", "XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD", "XML_SCHEMAP_UNKNOWN_FACET_CHILD", "XML_SCHEMAP_UNKNOWN_FACET_TYPE", "XML_SCHEMAP_UNKNOWN_GROUP_CHILD", "XML_SCHEMAP_UNKNOWN_IMPORT_CHILD", "XML_SCHEMAP_UNKNOWN_LIST_CHILD", "XML_SCHEMAP_UNKNOWN_NOTATION_CHILD", "XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_REF", "XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD", "XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD", "XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD", "XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD", "XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD", "XML_SCHEMAP_UNKNOWN_TYPE", "XML_SCHEMAP_UNKNOWN_UNION_CHILD", "XML_SCHEMAP_ELEM_DEFAULT_FIXED", "XML_SCHEMAP_REGEXP_INVALID", "XML_SCHEMAP_FAILED_LOAD", "XML_SCHEMAP_NOTHING_TO_PARSE", "XML_SCHEMAP_NOROOT", "XML_SCHEMAP_REDEFINED_GROUP", "XML_SCHEMAP_REDEFINED_TYPE", "XML_SCHEMAP_REDEFINED_ELEMENT", "XML_SCHEMAP_REDEFINED_ATTRGROUP", "XML_SCHEMAP_REDEFINED_ATTR", "XML_SCHEMAP_REDEFINED_NOTATION", "XML_SCHEMAP_FAILED_PARSE", "XML_SCHEMAP_UNKNOWN_PREFIX", "XML_SCHEMAP_DEF_AND_PREFIX", "XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD", "XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI", "XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI", "XML_SCHEMAP_NOT_SCHEMA", "XML_SCHEMAP_UNKNOWN_MEMBER_TYPE", "XML_SCHEMAP_INVALID_ATTR_USE", "XML_SCHEMAP_RECURSIVE", "XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE", "XML_SCHEMAP_INVALID_ATTR_COMBINATION", "XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION", "XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD", "XML_SCHEMAP_INVALID_ATTR_NAME", "XML_SCHEMAP_REF_AND_CONTENT", "XML_SCHEMAP_CT_PROPS_CORRECT_1", "XML_SCHEMAP_CT_PROPS_CORRECT_2", "XML_SCHEMAP_CT_PROPS_CORRECT_3", "XML_SCHEMAP_CT_PROPS_CORRECT_4", "XML_SCHEMAP_CT_PROPS_CORRECT_5", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3", "XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER", "XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE", "XML_SCHEMAP_UNION_NOT_EXPRESSIBLE", "XML_SCHEMAP_SRC_IMPORT_3_1", "XML_SCHEMAP_SRC_IMPORT_3_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3", "XML_SCHEMAP_COS_CT_EXTENDS_1_3", "XML_SCHEMAV_NOROOT", "XML_SCHEMAV_UNDECLAREDELEM", "XML_SCHEMAV_NOTTOPLEVEL", "XML_SCHEMAV_MISSING", "XML_SCHEMAV_WRONGELEM", "XML_SCHEMAV_NOTYPE", "XML_SCHEMAV_NOROLLBACK", "XML_SCHEMAV_ISABSTRACT", "XML_SCHEMAV_NOTEMPTY", "XML_SCHEMAV_ELEMCONT", "XML_SCHEMAV_HAVEDEFAULT", "XML_SCHEMAV_NOTNILLABLE", "XML_SCHEMAV_EXTRACONTENT", "XML_SCHEMAV_INVALIDATTR", "XML_SCHEMAV_INVALIDELEM", "XML_SCHEMAV_NOTDETERMINIST", "XML_SCHEMAV_CONSTRUCT", "XML_SCHEMAV_INTERNAL", "XML_SCHEMAV_NOTSIMPLE", "XML_SCHEMAV_ATTRUNKNOWN", "XML_SCHEMAV_ATTRINVALID", "XML_SCHEMAV_VALUE", "XML_SCHEMAV_FACET", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2", "XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3", "XML_SCHEMAV_CVC_TYPE_3_1_1", "XML_SCHEMAV_CVC_TYPE_3_1_2", "XML_SCHEMAV_CVC_FACET_VALID", "XML_SCHEMAV_CVC_LENGTH_VALID", "XML_SCHEMAV_CVC_MINLENGTH_VALID", "XML_SCHEMAV_CVC_MAXLENGTH_VALID", "XML_SCHEMAV_CVC_MININCLUSIVE_VALID", "XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID", "XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID", "XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID", "XML_SCHEMAV_CVC_TOTALDIGITS_VALID", "XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID", "XML_SCHEMAV_CVC_PATTERN_VALID", "XML_SCHEMAV_CVC_ENUMERATION_VALID", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3", "XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4", "XML_SCHEMAV_CVC_ELT_1", "XML_SCHEMAV_CVC_ELT_2", "XML_SCHEMAV_CVC_ELT_3_1", "XML_SCHEMAV_CVC_ELT_3_2_1", "XML_SCHEMAV_CVC_ELT_3_2_2", "XML_SCHEMAV_CVC_ELT_4_1", "XML_SCHEMAV_CVC_ELT_4_2", "XML_SCHEMAV_CVC_ELT_4_3", "XML_SCHEMAV_CVC_ELT_5_1_1", "XML_SCHEMAV_CVC_ELT_5_1_2", "XML_SCHEMAV_CVC_ELT_5_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_2_1", "XML_SCHEMAV_CVC_ELT_5_2_2_2_2", "XML_SCHEMAV_CVC_ELT_6", "XML_SCHEMAV_CVC_ELT_7", "XML_SCHEMAV_CVC_ATTRIBUTE_1", "XML_SCHEMAV_CVC_ATTRIBUTE_2", "XML_SCHEMAV_CVC_ATTRIBUTE_3", "XML_SCHEMAV_CVC_ATTRIBUTE_4", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2", "XML_SCHEMAV_CVC_COMPLEX_TYPE_4", "XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1", "XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2", "XML_SCHEMAV_ELEMENT_CONTENT", "XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING", "XML_SCHEMAV_CVC_COMPLEX_TYPE_1", "XML_SCHEMAV_CVC_AU", "XML_SCHEMAV_CVC_TYPE_1", "XML_SCHEMAV_CVC_TYPE_2", "XML_SCHEMAV_CVC_IDC", "XML_SCHEMAV_CVC_WILDCARD", "XML_SCHEMAV_MISC", "XML_XPTR_UNKNOWN_SCHEME", "XML_XPTR_CHILDSEQ_START", "XML_XPTR_EVAL_FAILED", "XML_XPTR_EXTRA_OBJECTS", "XML_C14N_CREATE_CTXT", "XML_C14N_REQUIRES_UTF8", "XML_C14N_CREATE_STACK", "XML_C14N_INVALID_NODE", "XML_C14N_UNKNOW_NODE", "XML_C14N_RELATIVE_NAMESPACE", "XML_FTP_PASV_ANSWER", "XML_FTP_EPSV_ANSWER", "XML_FTP_ACCNT", "XML_FTP_URL_SYNTAX", "XML_HTTP_URL_SYNTAX", "XML_HTTP_USE_IP", "XML_HTTP_UNKNOWN_HOST", "XML_SCHEMAP_SRC_SIMPLE_TYPE_1", "XML_SCHEMAP_SRC_SIMPLE_TYPE_2", "XML_SCHEMAP_SRC_SIMPLE_TYPE_3", "XML_SCHEMAP_SRC_SIMPLE_TYPE_4", "XML_SCHEMAP_SRC_RESOLVE", "XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE", "XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE", "XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES", "XML_SCHEMAP_ST_PROPS_CORRECT_1", "XML_SCHEMAP_ST_PROPS_CORRECT_2", "XML_SCHEMAP_ST_PROPS_CORRECT_3", "XML_SCHEMAP_COS_ST_RESTRICTS_1_1", "XML_SCHEMAP_COS_ST_RESTRICTS_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4", "XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5", "XML_SCHEMAP_COS_ST_RESTRICTS_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4", "XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5", "XML_SCHEMAP_COS_ST_DERIVED_OK_2_1", "XML_SCHEMAP_COS_ST_DERIVED_OK_2_2", "XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED", "XML_SCHEMAP_S4S_ELEM_MISSING", "XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED", "XML_SCHEMAP_S4S_ATTR_MISSING", "XML_SCHEMAP_S4S_ATTR_INVALID_VALUE", "XML_SCHEMAP_SRC_ELEMENT_1", "XML_SCHEMAP_SRC_ELEMENT_2_1", "XML_SCHEMAP_SRC_ELEMENT_2_2", "XML_SCHEMAP_SRC_ELEMENT_3", "XML_SCHEMAP_P_PROPS_CORRECT_1", "XML_SCHEMAP_P_PROPS_CORRECT_2_1", "XML_SCHEMAP_P_PROPS_CORRECT_2_2", "XML_SCHEMAP_E_PROPS_CORRECT_2", "XML_SCHEMAP_E_PROPS_CORRECT_3", "XML_SCHEMAP_E_PROPS_CORRECT_4", "XML_SCHEMAP_E_PROPS_CORRECT_5", "XML_SCHEMAP_E_PROPS_CORRECT_6", "XML_SCHEMAP_SRC_INCLUDE", "XML_SCHEMAP_SRC_ATTRIBUTE_1", "XML_SCHEMAP_SRC_ATTRIBUTE_2", "XML_SCHEMAP_SRC_ATTRIBUTE_3_1", "XML_SCHEMAP_SRC_ATTRIBUTE_3_2", "XML_SCHEMAP_SRC_ATTRIBUTE_4", "XML_SCHEMAP_NO_XMLNS", "XML_SCHEMAP_NO_XSI", "XML_SCHEMAP_COS_VALID_DEFAULT_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1", "XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2", "XML_SCHEMAP_CVC_SIMPLE_TYPE", "XML_SCHEMAP_COS_CT_EXTENDS_1_1", "XML_SCHEMAP_SRC_IMPORT_1_1", "XML_SCHEMAP_SRC_IMPORT_1_2", "XML_SCHEMAP_SRC_IMPORT_2", "XML_SCHEMAP_SRC_IMPORT_2_1", "XML_SCHEMAP_SRC_IMPORT_2_2", "XML_SCHEMAP_INTERNAL", "XML_SCHEMAP_NOT_DETERMINISTIC", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2", "XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3", "XML_SCHEMAP_MG_PROPS_CORRECT_1", "XML_SCHEMAP_MG_PROPS_CORRECT_2", "XML_SCHEMAP_SRC_CT_1", "XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3", "XML_SCHEMAP_AU_PROPS_CORRECT_2", "XML_SCHEMAP_A_PROPS_CORRECT_2", "XML_SCHEMAP_C_PROPS_CORRECT", "XML_SCHEMAP_SRC_REDEFINE", "XML_SCHEMAP_SRC_IMPORT", "XML_SCHEMAP_WARN_SKIP_SCHEMA", "XML_SCHEMAP_WARN_UNLOCATED_SCHEMA", "XML_SCHEMAP_WARN_ATTR_REDECL_PROH", "XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH", "XML_SCHEMAP_AG_PROPS_CORRECT", "XML_SCHEMAP_COS_CT_EXTENDS_1_2", "XML_SCHEMAP_AU_PROPS_CORRECT", "XML_SCHEMAP_A_PROPS_CORRECT_3", "XML_SCHEMAP_COS_ALL_LIMITED", "XML_MODULE_OPEN", "XML_MODULE_CLOSE", "XML_CHECK_FOUND_ELEMENT", "XML_CHECK_FOUND_ATTRIBUTE", "XML_CHECK_FOUND_TEXT", "XML_CHECK_FOUND_CDATA", "XML_CHECK_FOUND_ENTITYREF", "XML_CHECK_FOUND_ENTITY", "XML_CHECK_FOUND_PI", "XML_CHECK_FOUND_COMMENT", "XML_CHECK_FOUND_DOCTYPE", "XML_CHECK_FOUND_FRAGMENT", "XML_CHECK_FOUND_NOTATION", "XML_CHECK_UNKNOWN_NODE", "XML_CHECK_ENTITY_TYPE", "XML_CHECK_NO_PARENT", "XML_CHECK_NO_DOC", "XML_CHECK_NO_NAME", "XML_CHECK_NO_ELEM", "XML_CHECK_WRONG_DOC", "XML_CHECK_NO_PREV", "XML_CHECK_WRONG_PREV", "XML_CHECK_NO_NEXT", "XML_CHECK_WRONG_NEXT", "XML_CHECK_NOT_DTD", "XML_CHECK_NOT_ATTR", "XML_CHECK_NOT_ATTR_DECL", "XML_CHECK_NOT_ELEM_DECL", "XML_CHECK_NOT_ENTITY_DECL", "XML_CHECK_NOT_NS_DECL", "XML_CHECK_NO_HREF", "XML_CHECK_WRONG_PARENT", "XML_CHECK_NS_SCOPE", "XML_CHECK_NS_ANCESTOR", "XML_CHECK_NOT_UTF8", "XML_CHECK_NO_DICT", "XML_CHECK_NOT_NCNAME", "XML_CHECK_OUTSIDE_DICT", "XML_CHECK_WRONG_NAME", "XML_CHECK_NAME_NOT_NULL", "XML_I18N_NO_NAME", "XML_I18N_NO_HANDLER", "XML_I18N_EXCESS_HANDLER", "XML_I18N_CONV_FAILED", "XML_I18N_NO_OUTPUT")) XML/R/createNode.R0000644000175100001440000000677713607633702013355 0ustar hornikusersxmlNode <- function(name, ..., attrs = NULL, namespace = "", namespaceDefinitions = NULL, .children = list(...)) { kids <- lapply(.children, asXMLNode) kids = addNames(kids) # Check the names paces node <- list(name = name, attributes = attrs, children = kids, namespace=namespace, namespaceDefinitions = as(namespaceDefinitions, "XMLNamespaceDefinitions")) class(node) <- oldClass("XMLNode") # , "XMLAbstractNode") node } setAs("NULL", "XMLNamespaceDefinitions", function(from) structure(list(), class = "XMLNamespaceDefinitions")) addNames = function(kids, fromTag = TRUE) { if(fromTag) names(kids) = sapply(kids, xmlName) else if(length(names(kids)) == 0) names(kids) <- sapply(kids,xmlName) else if(any( idx <- names(kids) == "")) names(kids)[idx] <- sapply(kids[idx], xmlName) kids } setGeneric("xmlChildren<-", function(x, ..., value) { standardGeneric("xmlChildren<-") }) setMethod("xmlChildren<-", "ANY", function(x, append = FALSE, ..., value) { #value = addNames(value) #x$children <- value addChildren(x, append = append, ..., kids = value) }) # Don't need this. # xmlName.character = # function(node, full = FALSE) # "text" setMethod("xmlChildren<-", "XMLInternalNode", function(x, append = TRUE, ..., value) { if(!append) removeNodes(xmlChildren(x)) if(!is.list(value)) value = list(value) addChildren(x, kids = value) }) addChildren = function(node, ..., kids = list(...), at = NA, cdata = FALSE, append = TRUE) UseMethod("addChildren") addChildren.XMLNode = function(node, ..., kids = list(...), at = NA, cdata = FALSE, append = TRUE) { kids = lapply(kids, function(i) { if(!inherits(i, "XMLNode")) xmlTextNode(as.character(i), cdata = cdata) else i }) node$children = if(append) c(node$children, kids) else kids node$children = addNames(node$children) node } # It would be better tokenize this, but ... XMLEntities = c("&" = "amp", # order is important as if we insert an entity, then the next time we will see the &. ">" = "gt", "<" = "lt", "'" = "apos", '"' = "quot") insertEntities = function(value, entities = XMLEntities) { pat = names(entities) subs = paste("&", entities, ";", sep = "") for(i in seq(along = entities)) value = gsub(pat[i], subs[i], value) value } xmlTextNode <- function(value, namespace = "", entities = XMLEntities, cdata = FALSE) { node <- xmlNode("text", namespace = namespace) if(length(entities) && !inherits(value, "AsIs")) value = insertEntities(value, XMLEntities) if(cdata) value = xmlCDataNode(value) node$value <- value if(!cdata) class(node) <- oldClass("XMLTextNode") # , class(node)) if(length(entities)) class(node) <- c(class(node), "EntitiesEscaped") #"XMLEntitiesEscapedTextNode" node } xmlPINode <- function(sys, value, namespace="") { x <- xmlNode(name=sys, namespace=namespace) x$value <- value class(x) <- oldClass("XMLProcessingInstruction") # , class(x)) x } xmlCommentNode <- function(text) { node <- xmlTextNode(text) class(node) <- oldClass("XMLCommentNode") # , class(node)) node } xmlCDataNode <- function(...) { txt <- paste(..., collapse="") node <- xmlNode("text") node$value <- txt class(node) <- oldClass("XMLCDataNode") # , class(node)) node } asXMLNode <- function(x) { #XXX if(!inherits(x, "XMLNode")) { xmlTextNode(x) } else { x } } XML/R/xmlEventHandler.R0000644000175100001440000000177513607633674014405 0ustar hornikusersxmlEventHandler <- function() { con <- xmlOutputDOM() startElement <- function(name, atts,...) { con$addTag(name, attrs=atts, close=FALSE) } endElement <- function(name) { con$closeTag(name) } text <- function(x,...) { con$addNode(xmlTextNode(x)) } comment <- function(x,...) { xmlCommentNode(x) } externalEntity <- function(ctxt, baseURI, sysId, publicId,...) { cat("externalEntity", ctxt, baseURI, sysId, publicId,"\n") } entityDeclaration <- function(name, baseURI, sysId, publicId, notation, ...) { # just writing to screen at this point. cat("externalEntity", name, baseURI, sysId, publicId, notation,"\n") } processingInstruction <- function(sys, value) { con$addNode(xmlPINode(sys, value)) } list(startElement=startElement, endElement=endElement, processingInstruction=processingInstruction, text=text, comment=comment, externalEntity=externalEntity, entityDeclaration=entityDeclaration, dom=function(){con}) } XML/R/DTDRef.R0000644000175100001440000000463613607633665012354 0ustar hornikusers# These are classes and facilities for referring to a DTD for the # DOCTYPE field of an XML document # The 4 elements are + or -//creator//name of what is being referenced//language (decribed by ISO639) # See XML Elements of Style by Simon St. Laurent. validatePublicIdentifier = function(object) { els = strsplit(object, "//")[[1]] if(length(els) != 4) return("a PUBLIC identifier must have 4 parts, separated by //") if(! (els[1] %in% c("+", "-"))) return("first element of PUBLIC identifier must be + or -") TRUE } setClass("DTDPublicIdentifier", contains = "character", validity = validatePublicIdentifier) # name is the node name for the top-level node. # system and public identify the DTD. setClass("Doctype", representation(name = "character", system = "character", public = "character"), validity = function(object) { if(length(nchar(object@system)) > 0 && length(object@public) > 0) return("only one of system and public can be specified") if(length(object@public) > 0 && length(object@public) != 2) return("the public part of the Doctype must have exactly 2 elements.") if(length(object@public) > 0) { tmp = validatePublicIdentifier(object@public[1]) if(!is.logical(tmp)) return(tmp) } TRUE }) Doctype = function(system = character(), public = character(), name = "") { if(length(public) == 1 && length(system) > 0) { public = c(public, system) system = character() } new("Doctype", name = name, system = system, public = public) } ddQuote = function(x) { if(length(x) == 0) return(character()) paste('"', x, '"', sep = "") } setAs("Doctype", "character", function(from) { extra = character() if(sum(nchar(from@public), nchar(from@system))) { if(length(from@system)) extra = c(extra, "SYSTEM", ddQuote(from@system)) if(length(from@public)) extra = c(extra, "PUBLIC", ddQuote(from@public)) } paste("") }) XML/R/xmlNodes.R0000644000175100001440000013421613610555150013055 0ustar hornikusers#xmlRoot.HTMLInternalDocument = xmlRoot.XMLInternalDocument = function(x, skip = TRUE, addFinalizer = NA, ...) { .Call("R_xmlRootNode", x, as.logical(skip), addFinalizer, PACKAGE = "XML") } setAs("XMLNode", "XMLInternalNode", function(from) { con = textConnection("tmp", "w", local = TRUE) sink(con) on.exit({sink(file = NULL); close(con)}) print(from) doc = xmlParse(tmp, asText = TRUE) node = xmlRoot(doc) removeChildren(node) node } ) setAs("XMLInternalDocument", "character", function(from) saveXML(from)) setAs("XMLInternalDOM", "character", function(from) saveXML(from)) setAs("XMLInternalDocument", "XMLInternalNode", function(from) xmlRoot(from)) setAs("XMLInternalNode", "XMLInternalDocument", function(from) { doc = .Call("R_getXMLNodeDocument", from, PACKAGE = "XML") addDocFinalizer(doc, TRUE) if(is(doc, "HTMLInternalDocument")) class(doc) = c(class(doc), "XMLInternalDocument", "XMLAbstractDocument") doc }) setGeneric("free", function(obj) standardGeneric("free")) setMethod("free", "XMLInternalDocument", function(obj) { invisible(.Call("R_XMLInternalDocument_free", obj, PACKAGE = "XML")) }) addFinalizer = function(obj, fun, ...) { UseMethod("addFinalizer") } addCFinalizer.XMLInternalDocument = function(obj, fun, ...) { if(missing(fun) || fun == NULL) fun = getNativeSymbolInfo("RSXML_free_internal_document")$address else if(!is.function(obj)) { } .Call("R_addXMLInternalDocument_finalizer", obj, fun, PACKAGE = "XML") } asRXMLNode = function(node, converters = NULL, trim = TRUE, ignoreBlanks = TRUE) { .Call("R_createXMLNode", node, converters, as.logical(trim), as.logical(ignoreBlanks), PACKAGE = "XML")[[1]] } "[.XMLInternalDocument" = function(x, i, j, ..., namespaces = xmlNamespaceDefinitions(x, simplify = TRUE), addFinalizer = NA) { if(is.character(i)) { getNodeSet(x, i, ..., addFinalizer = addFinalizer) } else stop("No method for subsetting an XMLInternalDocument with ", class(i)) } "[[.XMLInternalDocument" = function(x, i, j, ..., exact = NA, namespaces = xmlNamespaceDefinitions(x, simplify = TRUE), addFinalizer = NA) { ans = x[i, addFinalizer = addFinalizer] if(length(ans) > 1) warning(length(ans), " elements in node set. Returning just the first one! (Use [])") ans[[1]] } xmlName.XMLInternalNode = function(node, full = FALSE) { ans = .Call("RS_XML_xmlNodeName", node, PACKAGE = "XML") if((is.logical(full) && full) || (!is.logical(full) && length(full))) { tmp = xmlNamespace(node) if(length(tmp) && length(names(tmp)) > 0 && names(tmp) != "") ans = paste(names(tmp), ans, sep = ":") else if(is.character(full) && full != "") ans = paste(full, ans, sep = ":") } ans } if(useS4) setMethod("xmlName", "XMLInternalNode", xmlName.XMLInternalNode) xmlNamespace.XMLInternalNode = function(x) { .Call("RS_XML_xmlNodeNamespace", x, PACKAGE = "XML") } xmlAttrs.XMLInternalNode = function(node, addNamespacePrefix = FALSE, addNamespaceURLs = TRUE, ...) { ans = .Call("RS_XML_xmlNodeAttributes", node, as.logical(addNamespacePrefix), as.logical(addNamespaceURLs), PACKAGE = "XML") if(length(attr(ans, "namespaces"))) ans = new("XMLAttributes", ans) # class(ans) = "XMLAttributes" ans } #setOldClass(c("XMLAttributes", "character")) setClass("XMLAttributes", contains = "character") setMethod("show", "XMLAttributes", function(object) print(unclass(object))) setMethod('[', c('XMLAttributes', "ANY"), function(x, i, j, ...) { ans = callNextMethod() i = match(i, names(x)) structure(ans, namespaces = attr(x, "namespaces")[i], class = class(x)) }) xmlChildren.XMLInternalNode = function(x, addNames = TRUE, omitNodeTypes = c("XMLXIncludeStartNode", "XMLXIncludeEndNode"), addFinalizer = NA, ...) { kids = .Call("RS_XML_xmlNodeChildrenReferences", x, as.logical(addNames), addFinalizer, PACKAGE = "XML") if(length(omitNodeTypes)) kids = kids[! sapply(kids, function(x) any(inherits(x, omitNodeTypes)) )] structure(kids, class = c("XMLInternalNodeList", "XMLNodeList")) } xmlChildren.XMLInternalDocument = function(x, addNames = TRUE, ...) { # .Call("RS_XML_xmlDocumentChildren", x, as.logical(addNames), PACKAGE = "XML") xmlChildren.XMLInternalNode(x, addNames, ...) } if(useS4) { setMethod("xmlAttrs", "XMLInternalNode", xmlAttrs.XMLInternalNode) setMethod("xmlChildren", "XMLInternalNode", xmlChildren.XMLInternalNode) setMethod("xmlChildren", "XMLInternalDocument", xmlChildren.XMLInternalDocument) } xmlSize.XMLInternalNode = function(obj) .Call("RS_XML_xmlNodeNumChildren", obj, PACKAGE = "XML") "[[.XMLInternalNode" <- #setMethod("[[", "XMLInternalNode", function(x, i, j, ..., addFinalizer = NA) { if(inherits(i, "formula")) { return(getNodeSet(x, i, if(missing(j)) character() else j, addFinalizer = addFinalizer, ...)[[1]]) } if(is.na(i)) return(NULL) # Get the individual elements rather than all the children and then subset those return( if(is(i, "numeric")) .Call("R_getChildByIndex", x, as.integer(i), as.logical(addFinalizer), PACKAGE = "XML") else .Call("R_getChildByName", x, as.character(i), as.logical(addFinalizer), PACKAGE = "XML") ) kids = xmlChildren(x, addFinalizer = addFinalizer) if(length(kids) == 0) return(NULL) if(is.numeric(i)) kids[[i]] else { id = as.character(i) which = match(id, sapply(kids, xmlName)) kids[[which]] } } "[.XMLInternalNode" <- function(x, i, j, ..., addFinalizer = NA) { kids = xmlChildren(x, addFinalizer = addFinalizer) if(is.logical(i)) i = which(i) if(is(i, "numeric")) structure(kids[i], class = c("XMLInternalNodeList", "XMLNodeList")) else { id = as.character(i) which = match(sapply(kids, xmlName), id) structure(kids[!is.na(which)], class = c("XMLInternalNodeList", "XMLNodeList")) } } xmlValue.XMLInternalNode = function(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) #CE_NATIVE) { encoding = if(is.integer(encoding)) encoding else getEncodingREnum(encoding) if(!recursive) { if(xmlSize(x) == 0) return(character()) kids = xmlChildren(x, addFinaliizer = FALSE) i = sapply(kids, inherits, "XMLInternalTextNode") if(any(i)) return(paste(unlist(lapply(kids[i], xmlValue, ignoreComments, recursive = TRUE, encoding = encoding, trim = trim)), collapse = "")) else return(character()) } ans = .Call("R_xmlNodeValue", x, NULL, encoding, PACKAGE = "XML") # 2nd argument ignored. if(trim) trim(ans) else ans } setS3Method("xmlValue", "XMLInternalNode") setGeneric("xmlValue<-", function(x, ..., value) standardGeneric("xmlValue<-")) setMethod("xmlValue<-", "XMLInternalTextNode", function(x, ..., value) { .Call("R_setXMLInternalTextNode_value", x, as.character(value), PACKAGE = "XML") x }) setMethod("xmlValue<-", "XMLTextNode", function(x, ..., value) { x$value = as.character(value) x }) setMethod("xmlValue<-", "XMLAbstractNode", function(x, ..., value) { if(xmlSize(x) == 0) { x = addChildren(x, as.character(value)) } else if(xmlSize(x) == 1 && any(inherits(x[[1]], c("XMLTextNode", "XMLInternalTextNode")))) { #XXX Fix the assignment to children. # should be xmlValue(x[[1]]) = value tmp = x[[1]] xmlValue(tmp) = as.character(value) if(inherits(x[[1]], "XMLTextNode")) x$children[[1]] = tmp } else stop("Cannot set the content of a node that is not an XMLInternalTextNode or a node containing a text node") x }) names.XMLInternalNode = function(x) xmlSApply(x, xmlName, addFinalizer = FALSE) xmlApply.XMLInternalNode = function(X, FUN, ..., omitNodeTypes = c("XMLXIncludeStartNode", "XMLXIncludeEndNode"), addFinalizer = NA) { kids = xmlChildren(X, addFinalizer = addFinalizer) if(length(omitNodeTypes)) kids = kids[! sapply(kids, function(x) any(inherits(x, omitNodeTypes)) )] lapply(kids, FUN, ...) } xmlSApply.XMLInternalNode = function(X, FUN, ..., omitNodeTypes = c("XMLXIncludeStartNode", "XMLXIncludeEndNode"), addFinalizer = NA) { kids = xmlChildren(X, addFinalizer = addFinalizer) if(length(omitNodeTypes)) kids = kids[! sapply(kids, function(x) any(inherits(x, omitNodeTypes)) )] sapply(kids, FUN, ...) } xmlSApply.XMLNodeSet = function(X, FUN, ..., omitNodeTypes = c("XMLXIncludeStartNode", "XMLXIncludeEndNode"), addFinalizer = NA) { sapply(X, FUN, ...) } xmlApply.XMLNodeSet = function(X, FUN, ..., omitNodeTypes = c("XMLXIncludeStartNode", "XMLXIncludeEndNode"), addFinalizer = NA) { lapply(X, FUN, ...) } getChildrenStrings = function(node, encoding = getEncoding(node), asVector = TRUE, len = xmlSize(node), addNames = TRUE) { encoding = getEncodingREnum(encoding) .Call("R_childStringValues", node, as.integer(len), as.logical(asVector), as.integer(encoding), as.logical(addNames), PACKAGE = "XML") } setMethod("xmlParent", "XMLInternalNode", function(x, addFinalizer = NA, ...) { .Call("RS_XML_xmlNodeParent", x, addFinalizer, PACKAGE = "XML") }) newXMLDTDNode <- function(nodeName, externalID = character(), systemID = character(), doc = NULL, addFinalizer = NA) { if(length(nodeName) > 1 && missing(externalID)) externalID = nodeName[2] if(length(nodeName) > 2 && missing(systemID)) systemID = nodeName[3] .Call("R_newXMLDtd", doc, as.character(nodeName), as.character(externalID), as.character(systemID), addFinalizer, PACKAGE = "XML") } setInternalNamespace = function(node, ns) { .Call("R_xmlSetNs", node, ns, FALSE, PACKAGE = "XML") # as.logical(append)) } addDocFinalizer = function(doc, finalizer) { fun = NULL if(is.logical(finalizer)) { if(is.na(finalizer) || !finalizer) return() else fun = NULL } else { fun = finalizer if(inherits(fun, "NativeSymbolInfo")) fun = fun$address } if(!is.null(fun) && !is.function(fun) && typeof(fun) != "externalptr") stop("need an R function, address of a routine or NULL for finalizer") .Call("R_addXMLInternalDocument_finalizer", doc, fun, PACKAGE = "XML") } HTML_DTDs = c("http://www.w3.org/TR/html4/frameset.dtd", "http://www.w3.org/TR/html4/loose.dtd", "http://www.w3.org/TR/html4/strict.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" ) newHTMLDoc = function(dtd = "loose", addFinalizer = TRUE, name = character(), node = newXMLNode("html", newXMLNode("head", addFinalizer = FALSE), newXMLNode("body", addFinalizer = FALSE), addFinalizer = FALSE)) { if(is.na(dtd) || dtd == "") dtd = "" else if(tolower(dtd) %in% c("html5", "5")) dtd = "5" else { i = grep(dtd, HTML_DTDs) if(length(i)) { if(length(i) > 1) warning("matched multiple DTDs. Using the first") dtd = HTML_DTDs[i[1]] } else dtd = "" } doc = newXMLDoc(dtd = dtd, isHTML = TRUE, addFinalizer = addFinalizer, node = node) doc } newXMLDoc <- # # Creates internal C-level libxml object for representing # an XML document/tree of nodes. # function(dtd = "", namespaces = NULL, addFinalizer = TRUE, name = character(), node = NULL, isHTML = FALSE) { if(is(dtd, "XMLInternalNode")) { dtdNode = dtd dtd = character() } else dtdNode = NULL ans = .Call("R_newXMLDoc", dtd, namespaces, as.logical(isHTML), PACKAGE = "XML") class(ans) = oldClass(class(ans)) addDocFinalizer(ans, addFinalizer) if(length(name)) docName(ans) = as.character(name) if(length(dtdNode)) addChildren(ans, dtdNode) if(length(node)) { if(is.character(node)) ## was parent = doc newXMLTextNode(node, addFinalizer = FALSE, parent = ans) else addChildren(ans, node) } ans } XMLOptions = new.env() getOption = function(name, default = NULL, converter = NULL) { if(!exists(name, XMLOptions, inherits = FALSE)) return(base::getOption(name, default)) ans = get(name, XMLOptions) if(is.function(converter)) converter(ans) else ans } setOption = function(name, value) { prev = getOption(name) assign(name, value, XMLOptions) prev } newXMLNode <- ###XXX Note that there is another definition of this in dups.R # Which is now elided. # Create an internal C-level libxml node # # # It is possible to use a namespace prefix that is not defined. # This is okay as it may be defined in another node which will become # an ancestor of this newly created one. # XXX Have to add something to force the namespace prefix into the node # when there is no corresponding definition for that prefix. function(name, ..., attrs = NULL, namespace = character(), namespaceDefinitions = character(), doc = NULL, .children = list(...), parent = NULL, at = NA, cdata = FALSE, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), # i.e. warn. sibling = NULL, addFinalizer = NA, noNamespace = length(namespace) == 0 && !missing(namespace), fixNamespaces = c(dummy = TRUE, default = TRUE) ) { # determine whether we know now that there is definitely no namespace. # make certain we have a character vector for the attributes. if(length(attrs)) { ids = names(attrs) attrs = structure(as(attrs, "character"), names = ids) # Find any attributes that are actually namespace definitions. i = grep("^xmlns", names(attrs)) if(length(i)) { warning("Don't specify namespace definitions via 'attrs'; use namespaceDefinitions") namespace = c(namespace, structure(attrs[i], names = gsub("^xmlns:", "", names(attrs)[i]))) attrs = attrs[ -i] } } else attrs = character() # allow the caller to specify the node name as ns_prefix:name # but we have to create it as name and the set the namespace. ns = character() # the namespace prefix name = strsplit(name, ":")[[1]] if(length(name) == 2) { ns = name[1] name = name[2] noNamespace = FALSE } if(is.list(parent)) { if(length(parent) < 1 || !(is(parent[[1]], "XMLInternalElementNode") || is(parent[[1]], "XMLInternalDocument"))) stop("incorrect value for parent") parent = parent[[1]] } # if there is no doc, but we have a parent which is an XMLInternalDocument, use that. if(missing(doc) && !missing(parent) && inherits(parent, "XMLInternalDocument")) { doc = parent parent = NULL } # Get the doc from the parent node/document. if(is.null(doc) && !is.null(parent)) { # doc = as(parent, "XMLInternalDocument") doc = if(inherits(parent, "XMLInternalDocument")) parent else .Call("R_getXMLNodeDocument", parent, PACKAGE = "XML") } # create the node. Let's leave the namespace definitions and prefix till later. # xmlSetProp() routine in R_newXMLNode() handles namespaces on the attribute names, even checking them. node <- .Call("R_newXMLNode", as.character(name), character(), character(), doc, namespaceDefinitions, addFinalizer, PACKAGE = "XML") if(!is.null(sibling)) addSibling(sibling, node, after = as.logical(at)) else if(!is.null(parent)) addChildren(parent, node, at = at) if(TRUE) { # Create the name space definitions here rather than in C code. nsDefs = lapply(seq(along = namespaceDefinitions), function(i) newNamespace(node, namespaceDefinitions[[i]], names(namespaceDefinitions)[i], set = FALSE) ) if(length(namespaceDefinitions)) names(nsDefs) = if(length(names(namespaceDefinitions))) names(namespaceDefinitions) else "" } else nsDefs = xmlNamespaceDefinitions(node) # Now that the namespaces are defined, we can define the attributes which _may_ use them. addAttributes(node, .attrs = attrs, suppressNamespaceWarning = suppressNamespaceWarning) if(is(namespace, "XMLNamespaceRef")) { setInternalNamespace(node, namespace) } else if(is.na(noNamespace) || !noNamespace) { ns = getNodeNamespace(ns, nsDefs, node, namespace, noNamespace, namespaceDefinitions, parent, suppressNamespaceWarning) if(is.null(ns)) !.Call("R_setNamespaceFromAncestors", node, PACKAGE = "XML") # .Call("R_getAncestorDefaultNSDef", node, TRUE, PACKAGE = "XML") } # Here is where we set the namespace for this node. if(length(ns) && (inherits(ns, c("XMLNamespaceRef", "XMLNamespaceDeclaration")) || (is.character(ns) && ns != ""))) setXMLNamespace( node, ns) # should this be append = FALSE ? # Add any children to this node. if(length(.children)) { if(!is.list(.children)) .children = list(.children) addChildren(node, kids = .children, cdata = cdata, addFinalizer = addFinalizer) } if(any(fixNamespaces)) { # !is.null(parent)) { xmlFixNamespaces(node, fixNamespaces) # fixDummyNS(node, suppressNamespaceWarning) } node } xmlFixNamespaces = function(node, fix) { if(length(fix) == 1) fix = structure(rep(fix, 2), names = c("dummy", "default")) if(length(names(fix)) == 0) names(fix) = c("dummy", "default") if(fix["dummy"]) xmlApply(node, function(x) .Call("R_fixDummyNS", x, TRUE, PACKAGE = "XML")) if(fix["default"]) .Call("R_getAncestorDefaultNSDef", node, TRUE, PACKAGE = "XML") } FixDummyNS = 2L FixDefaultNS = 4L xmlNamespaceRef = function(node) .Call("R_getXMLNsRef", node, PACKAGE = "XML") if(FALSE) { # Quick check to see if the speed problem in newXMLNode above is in the extra processing newXMLNode <- function(name, ..., attrs = NULL, namespace = "", namespaceDefinitions = character(), doc = NULL, .children = list(...), parent = NULL, at = NA, cdata = FALSE, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE) # i.e. warn. ) { node = .Call("R_newXMLNode", name, as.character(attrs), character(), doc, character(), TRUE, PACKAGE = "XML") if(!is.null(parent)) addChildren(parent, node, at = at) node } } findNamespaceDefinition = # # Search up the node hierarchy looking for a namespace # matching that prefix. # function(node, namespace, error = TRUE) { ptr = node while(!is.null(ptr)) { tmp = namespaceDeclarations(ptr, TRUE) i = match(namespace, names(tmp)) if(!is.na(i)) return(tmp[[i]]) ptr = xmlParent(ptr) } if(error) stop("no matching namespace definition for prefix ", namespace) NULL } setXMLNamespace = # # Set the specified namespace as the namespace for this # node. # namespace can be a prefix in which case we find it in the # definition in this node or its ancestors. # Otherwise, we expect a name = value character vector giving the # prefix and URI and we create a new namespace definition. # Alternatively, if you already have the namespace reference object # from earlier, you can pass that in. # Then we set the namespace on the node. function(node, namespace, append = FALSE) { if(is.character(namespace) && is.null(names(namespace))) namespace = findNamespaceDefinition(node, namespace) else if(is.character(namespace)) namespace = newNamespace(node, namespace) else if(!is.null(namespace) && !inherits(namespace, c("XMLNamespaceRef", "XMLNamespaceDeclaration"))) stop("Must provide a namespace definition, a prefix of existing namespace or a reference to a namespace definition") .Call("R_xmlSetNs", node, namespace, FALSE, PACKAGE = "XML") } setAs("XMLNamespace", "character", function(from) unclass(from)) setAs("XMLNamespaceDefinition", "character", function(from) structure(from$uri, names = from$id)) setGeneric("xmlNamespace<-", function(x, ..., value) standardGeneric("xmlNamespace<-")) setMethod("xmlNamespace<-", "XMLInternalNode", function(x, ..., value) { setXMLNamespace(x, value) x }) setGeneric("xmlNamespaces<-", function(x, append = TRUE, set = FALSE, value) standardGeneric("xmlNamespaces<-")) setMethod("xmlNamespaces<-", "XMLNode", function(x, append = TRUE, set = FALSE, value) { if(inherits(value, "XMLNamespace")) value = as(value, "character") else if(is.null(names(value))) names(value) = "" # check for duplicates? i = duplicated(names(value)) if(any(i)) { warning("discarding duplicated namespace prefixes ", paste(names(value)[i], collapse = ", ")) value = value[!i] } if(append) { cur = as(x$namespaceDefinitions, "character") cur[names(value)] = value value = cur } x$namespaceDefinitions = as(value, "XMLNamespaceDefinitions") if(set) x$namespace = names(value) x }) setMethod("xmlNamespaces<-", "XMLInternalNode", function(x, append = TRUE, set = FALSE, value) { value = as(value, "character") if(is.null(names(value))) names(value) = "" # check for duplicates? i = duplicated(names(value)) if(any(i)) { warning("discarding duplicated namespace prefixes ", paste(names(value)[i], collapse = ", ")) value = value[!i] } if(append) { # Work with existing ones curDefs = namespaceDeclarations(x) i = names(value) %in% names(curDefs) if(any(i)) { warning("discarding duplicated namespace prefixes ", paste(names(value)[i], collapse = ", ")) value = value[!i] } } if(length(value) == 0) # Should worry about the set. return() if(length(set) == 1 && set == TRUE && length(value) > 1) set = c(set, rep(FALSE, length(value) - 1)) else set = rep(set, length.out = length(value)) for(i in seq(along = value)) newXMLNamespace(x, value[i], set = set[i]) x }) newXMLNamespace = newNamespace = # Create a new namespace reference object. function(node, namespace, prefix = names(namespace), set = FALSE) { if(is.null(namespace)) return(NULL) # XXX ns <- .Call("R_xmlNewNs", node, namespace, as.character(prefix), PACKAGE = "XML") if(set) setXMLNamespace(node, ns) ns } checkNodeNamespace = # # can only be checked after we know the parent node, # i.e. after it has been inserted. # function(node, prefix = xmlNamespace(node)) { if(length(prefix) == 0 || prefix == "") return(TRUE) # XXX should check that namespace is defined # walk the parents. okay = FALSE p = xmlParent(node) while(!is.null(p)) { okay = prefix %in% names(xmlNamespaceDefinitions(p)) if(okay) break } if(!okay) stop("using an XML namespace prefix '", prefix, "' for a node that is not defined for this node or its node's ancestors") TRUE } # Still to do: # element, entity, entity_ref, notation # And more in libxml/tree.h, e.g. the declaration nodes # newXMLTextNode = # # cdata allows the caller to specify that the text be # wrapped in a newXMLCDataNode function(text, parent = NULL, doc = NULL, cdata = FALSE, escapeEntities = is(text, "AsIs"), addFinalizer = NA) { if(cdata) return(newXMLCDataNode(text, parent, doc, addFinalizer = addFinalizer)) a = .Call("R_newXMLTextNode", as.character(text), doc, addFinalizer, PACKAGE = "XML") if(escapeEntities) setNoEnc(a) if(!is.null(parent)) addChildren(parent, a) a } newXMLPINode <- function(name, text, parent = NULL, doc = NULL, at = NA, addFinalizer = NA) { a = .Call("R_newXMLPINode", doc, as.character(name), as.character(text), addFinalizer, PACKAGE = "XML") if(!is.null(parent)) addChildren(parent, a, at = at) a } newXMLCDataNode <- function(text, parent = NULL, doc = NULL, at = NA, sep = "\n", addFinalizer = NA) { text = paste(as.character(text), collapse = "\n") a = .Call("R_newXMLCDataNode", doc, text, addFinalizer, PACKAGE = "XML") if(!is.null(parent)) addChildren(parent, a, at = at) a } newXMLCommentNode <- function(text, parent = NULL, doc = NULL, at = NA, addFinalizer = NA) { a = .Call("R_xmlNewComment", as.character(text), doc, addFinalizer, PACKAGE = "XML") if(!is.null(parent)) addChildren(parent, a, at = at) a } replaceNodes = function(oldNode, newNode, ...) { UseMethod("replaceNodes") } replaceNodes.list = function(oldNode, newNode, addFinalizer = NA, ...) { mapply(replaceNodes, oldNode, newNode, MoreArgs = list(addFinalizer = addFinalizer, ...)) } replaceNodes.XMLInternalNode = function(oldNode, newNode, addFinalizer = NA, ...) { oldNode = as(oldNode, "XMLInternalNode") #XXX deal with a list of nodes. newNode = as(newNode, "XMLInternalNode") .Call("RS_XML_replaceXMLNode", oldNode, newNode, addFinalizer, PACKAGE = "XML") } # if(FALSE) # This is vectorized for no reason "[[<-.XMLInternalNode" = function(x, i, j, ..., value) { if(!is.list(value)) value = list(value) if(is.character(i)) { if(length(names(x)) == 0) k = rep(NA, length(i)) else k = match(i, names(x)) if(any(is.na(k))) { # create a node with that name and text value[is.na(k)] = mapply(function(name, val) if(is.character(val)) newXMLNode(name, val) else val) } i = k } replace = (i <= xmlSize(x)) if(any(replace)) { replaceNodes(xmlChildren(x)[i[replace]], value[replace]) value = value[!replace] i = i[!replace] } if(length(i)) addChildren(x, kids = value, at = i) x } "[[<-.XMLInternalNode" = function(x, i, j, ..., value) { if(is.character(i)) { if(length(names(x)) == 0) k = NA else k = match(i, names(x)) if(is.na(k) && is.character(value) && !inherits(value, "AsIs")) { # create a node with that name and text value = newXMLNode(i, value) } i = k } replace = !is.na(i) & (i <= xmlSize(x)) if(replace) replaceNodes(xmlChildren(x)[[i]], value) else addChildren(x, kids = list(value), at = i) x } setNoEnc = function(node) { if(!is(node, "XMLInternalTextNode")) stop("setNoEnc can only be applied to an native/internal text node, not ", paste(class(node), collapse = ", ")) .Call("R_setXMLInternalTextNode_noenc", node, PACKAGE = "XML") } addChildren.XMLInternalNode = addChildren.XMLInternalDocument = # # XXX need to expand/recycle the at if it is given as a scalar # taking into account if the subsequent elements are lists, etc. # # Basically, if the caller specifies at as a scalar # we expand this to be the sequence starting at that value # and having length which is the total number of nodes # in kids. This is not just the length of kids but # the number of nodes since some of the elements might be lists. # function(node, ..., kids = list(...), at = NA, cdata = FALSE, addFinalizer = NA, fixNamespaces = c(dummy = TRUE, default = TRUE)) { kids = unlist(kids, recursive = FALSE) removeNodes(kids[!vapply(kids, is.character, logical(1L))]) if(length(kids) == 1 && inherits(kids[[1]], "XMLInternalNode") && is.na(at)) { .Call("R_insertXMLNode", kids[[1]], node, -1L, FALSE, PACKAGE = "XML") # return(node) } else { # if(all(is.na(at))) { # kids = lapply(kids, as, function(x) if(is.character(x)) newXMLTextNode(x) else as(x, "XMLInternalNode")) # .Call("R_insertXMLNodeDirectly", node, kids, PACKAGE = "XML") # return(node) # } if(!is.na(at)) { # if at is the name of a child node, find its index (first node with that name) if(is.character(at)) at = match(at, names(node)) if(length(at) == 1) at = seq(as.integer(at), length = sum(sapply(kids, function(x) if(is.list(x)) length(x) else 1))) else # pad with NAs length(at) = length(kids) return(lapply(seq(along = kids), function(j) { i = kids[[j]] if(is.character(i)) i = newXMLTextNode(i, cdata = cdata, addFinalizer = addFinalizer) if(!inherits(i, "XMLInternalNode")) #XX is(i, "XMLInternalNode") i = as(i, "XMLInternalNode") if(.Call("R_isNodeChildOfAt", i, node, as.integer(at[j]), PACKAGE = "XML")) return(i) if(is.na(at[j])) .Call("R_insertXMLNode", i, node, -1L, FALSE, PACKAGE = "XML") else { after = at[j] > 0 if(!after) at[j] = 1 if(xmlSize(node) < at[j]) .Call("R_insertXMLNode", i, node, as.integer(NA), FALSE, PACKAGE = "XML") else .Call("RS_XML_xmlAddSiblingAt", node[[ at[j] ]], i, after, addFinalizer, PACKAGE = "XML") # if at = 0, then shove it in before the sibling. } })) } for(j in seq(along = kids)) { i = kids[[j]] if(is.list(i)) { # can't happen now since we unlist() for(k in i) addChildren(node, k, addFinalizer = addFinalizer) } else { if(is.null(i)) next if(is.character(i)) i = newXMLTextNode(i, cdata = cdata, addFinalizer = FALSE) if(!inherits(i, "XMLInternalNode")) { i = as(i, "XMLInternalNode") } .Call("R_insertXMLNode", i, node, at[j], FALSE, PACKAGE = "XML") ns = attr(i, "xml:namespace") if(!is.null(ns)) { nsdef = findNamespaceDefinition(node, ns) if(!is.null(nsdef) && (inherits(nsdef, c("XMLNamespaceRef", "XMLNamespaceDeclaration")) || (is.character(nsdef) && nsdef != ""))) { setXMLNamespace( i, nsdef) attr(i, "xml:namespace") = NULL } } } } } if(!is(node, "XMLInternalDocument") && any(fixNamespaces)) xmlFixNamespaces(node, fixNamespaces) node } addSibling = function(node, ..., kids = list(...), after = NA) { UseMethod("addSibling") } addSibling.XMLInternalNode = function(node, ..., kids = list(...), after = TRUE, addFinalizer = NA) { #XXX Why add as children? if(FALSE && is.na(after)) addChildren(node, kids = kids, at = NA) else { lapply(kids, function(x) { .Call("RS_XML_xmlAddSiblingAt", node, x, as.logical(after), addFinalizer, PACKAGE = "XML") }) } } removeNodes = function(node, free = rep(FALSE, length(node))) UseMethod("removeNodes") removeNodes.default = function(node, free = rep(FALSE, length(node))) NULL removeNodes.list = removeNodes.XMLNodeList = function(node, free = rep(FALSE, length(node))) { if(!all(sapply(node, inherits, "XMLInternalNode"))) { warning("removeNode only works on internal nodes at present") return(NULL) } free = as.logical(free) free = rep(free, length = length(node)) .Call("R_removeInternalNode", node, free, PACKAGE = "XML") } removeNodes.XMLNodeSet = function(node, free = rep(FALSE, length(node))) { removeNodes.list(node, free) } removeNodes.XMLInternalNode = function(node, free = rep(FALSE, length(node))) { node = list(node) free = as.logical(free) .Call("R_removeInternalNode", node, free, PACKAGE = "XML") } removeChildren = function(node, ..., kids = list(...), free = FALSE) { UseMethod("removeChildren") } removeChildren.XMLNode = # # function(node, ..., kids = list(...), free = FALSE) { kidNames = names(node) w = sapply(kids, function(i) { orig = i if(length(i) > 1) warning("each node identifier should be a single value, i.e. a number or a name, not a vector. Ignoring ", paste(i[-1], collapse = ", ")) if(!inherits(i, "numeric")) i = match(i, kidNames) if(is.na(i)) { warning("can't find node identified by ", orig) i = 0 } i }) node$children = unclass(node)$children[ - w ] node } removeChildren.XMLInternalNode = function(node, ..., kids = list(...), free = FALSE) { # idea is to get the actual XMLInternalNode objects # corresponding the identifiers in the kids list. # These are numbers, node names or node objects themselves # This could be fooled by duplicates, e.g. kids = list(2, 2) # or kids = list(2, "d") where "d" identifies the second node. # We can put in stricter checks in the C code if needed. nodes = xmlChildren(node) nodeNames = xmlSApply(node, xmlName) v = lapply(kids, function(x) { if(inherits(x, "XMLInternalNode")) x else if(is.character(x)) { i = match(x, nodeNames) nodes[[i]] } else nodes[[as.integer(x)]] }) free = rep(free, length = length(v)) .Call("RS_XML_removeChildren", node, v, as.logical(free), PACKAGE = "XML") node } replaceNodeWithChildren = function(node) { if(!inherits(node, "XMLInternalNode")) stop("replaceNodeWithChildren only work on internal XML/HTML nodes") .Call("R_replaceNodeWithChildren", node, PACKAGE = "XML") } setGeneric("toHTML", function(x, context = NULL) standardGeneric("toHTML")) setMethod('toHTML', 'vector', function(x, context = NULL) { tb = newXMLNode("table") if(length(names(x)) > 0) addChildren(tb, newXMLNode("tr", .children = sapply(names(x), function(x) newXMLNode("th", x)))) addChildren(tb, newXMLNode("tr", .children = sapply(x, function(x) newXMLNode("th", format(x))))) tb }) setMethod('toHTML', 'matrix', function(x, context = NULL) { tb = newXMLNode("table") if(length(colnames(x)) > 0) addChildren(tb, newXMLNode("tr", .children = sapply(names(x), function(x) newXMLNode("th", x)))) rows = sapply(seq(length = nrow(x)), function(i) { row = newXMLNode("tr") if(length(rownames(x)) > 0) addChildren(row, newXMLNode("th", rownames(x)[i])) addChildren(row, .children = sapply(x[i,], function(x) newXMLNode("th", format(x)))) row }) addChildren(tb, rows) tb }) SpecialCallOperators = c("+", "-", "*", "/", "%*%", "%in%", ":") #XXX Not necessarily working yet! See RXMLDoc setMethod('toHTML', 'call', function(x, context) { # handle special operators like +, -, :, ... if(as.character(v[[1]]) %in% SpecialCallOperators) { } v = newXMLNode(x[[1]], "(") for(i in v[-1]) addChildren(v, toHTML( i , context)) v }) setAs("vector", "XMLInternalNode", function(from) { newXMLTextNode(as(from, "character")) }) print.XMLInternalDocument = function(x, ...) { cat(as(x, "character"), "\n") } print.XMLInternalNode = function(x, ...) { cat(as(x, "character"), "\n") } setAs("XMLInternalNode", "character", function(from) saveXML.XMLInternalNode(from)) setAs("XMLInternalTextNode", "character", function(from) xmlValue(from)) checkAttrNamespaces = function(nsDefs, .attrs, suppressNamespaceWarning) { ns = sapply(strsplit(names(.attrs), ":"), function(x) if(length(x) > 1) x[1] else NA) i = which(!is.na(ns)) m = match(ns[i], names(nsDefs)) if(any(is.na(m))) { f = if(is.character(suppressNamespaceWarning)) get(suppressNamespaceWarning, mode = "function") else warning f(paste("missing namespace definitions for prefix(es)", paste(ns[i][is.na(m)]))) } } setGeneric("addAttributes", function(node, ..., .attrs = NULL, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), append = TRUE) standardGeneric("addAttributes")) setMethod("addAttributes", "XMLInternalElementNode", function(node, ..., .attrs = NULL, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), append = TRUE) { if(missing(.attrs)) .attrs = list(...) .attrs = structure(as.character(.attrs), names = names(.attrs)) if(length(.attrs) == 0) return(node) if(is.null(names(.attrs)) || any(names(.attrs) == "")) stop("all node attributes must have a name") if(is.character(suppressNamespaceWarning) || !suppressNamespaceWarning) checkAttrNamespaces(getEffectiveNamespaces(node), .attrs, suppressNamespaceWarning) if(!append) removeAttributes(node, .all = TRUE) .Call("RS_XML_addNodeAttributes", node, .attrs, PACKAGE = "XML") node }) #if(!isGeneric("xmlAttrs<-")) setGeneric("xmlAttrs<-", function(node, append = TRUE, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), value) standardGeneric("xmlAttrs<-")) tmp = function(node, append = TRUE, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), value) { addAttributes(node, .attrs = value, suppressNamespaceWarning = suppressNamespaceWarning, append = append) } setMethod("xmlAttrs<-", "XMLInternalElementNode", tmp) setMethod("xmlAttrs<-", "XMLNode", tmp) setMethod("addAttributes", "XMLNode", function(node, ..., .attrs = NULL, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE), append = TRUE) { if(missing(.attrs)) .attrs = list(...) .attrs = structure(as.character(.attrs), names = names(.attrs)) if(is.null(names(.attrs)) || any(names(.attrs) == "")) stop("all node attributes must have a name") if(is.character(suppressNamespaceWarning) || !suppressNamespaceWarning) checkAttrNamespaces(getEffectiveNamespaces(node), .attrs, suppressNamespaceWarning) if(append) { i = match(names(.attrs), names(node$attributes)) if(any(!is.na(i))) { node$attributes[i[!is.na(i)]] = .attrs[!is.na(i)] .attrs = .attrs[is.na(i)] } node$attributes = c(node$attributes, .attrs) } else node$attributes = .attrs node }) setGeneric("removeAttributes", function(node, ..., .attrs = NULL, .namespace = FALSE, .all = (length(list(...)) + length(.attrs)) == 0) standardGeneric("removeAttributes")) setGeneric("removeXMLNamespaces", function(node, ..., all = FALSE, .els = unlist(list(...))) standardGeneric("removeXMLNamespaces")) setMethod("removeXMLNamespaces", "XMLInternalElementNode", function(node, ..., all = FALSE, .els = unlist(list(...))) { if(all) .Call("RS_XML_removeAllNodeNamespaces", node, PACKAGE = "XML") else { if(is.character(.els)) .els = lapply(.els, function(x) x) .Call("RS_XML_removeNodeNamespaces", node, .els, PACKAGE = "XML") } }) setMethod("removeAttributes", "XMLInternalElementNode", # # The idea here is to remove attributes by name # We handle the case where these are a simple collection # of character string identifiers given via the ... or as a character # vector using, e.g., .attrs = c("a", "b") # # Each identifier can be of the form "name" or "ns:name" giving # the namespace prefix. We resolve the namespace and # # If we are dealing with regular attributes (no namespace attributes) # then we expect these as a character vector. # # The intent of the .namespace argument was originally to indicate that # we wanted to remove the namespace definition. It appears that libxml2 does # not support that. (And it would seem that this is a real pain as the xmlNsPtr # objects can be shared across numerous places in a linked list, so it would # be very difficult to remove it from one node.) # # # function(node, ..., .attrs = NULL, .namespace = FALSE, .all = (length(list(...)) + length(.attrs)) == 0) { if(missing(.attrs)) .attrs = list(...) .attrs = as.character(.attrs) if(.all) { if(length(list(...)) || length(.attrs)) stop(".all specified as TRUE and individual values specified via .../.attrs") # Use the integer indices to identify the elements. .Call("RS_XML_removeNodeAttributes", node, seq(along = xmlAttrs(node)), FALSE, PACKAGE = "XML") return(node) } if(is(.namespace, "XMLNamespaceDeclaration")) .namespace = list(.namespace) #XXX tmp = strsplit(.attrs, ":") prefix = sapply(tmp, function(x) if(length(x) > 1) x[1] else "") ids = sapply(tmp, function(x) if(length(x) == 1) x[1] else x[2]) if(any(prefix != "") && is.logical(.namespace)) .namespace = TRUE if(is.logical(.namespace) && .namespace) { ns = namespaceDeclarations(node, TRUE) # need to create a list with the elements corresponding to the # (potentially repeated) ns elements i = match(prefix, names(ns)) ns = ns[i] names(ns) = gsub("^.*:", "", .attrs) # or ids from above .attrs = ns } .Call("RS_XML_removeNodeAttributes", node, .attrs, .namespace, PACKAGE = "XML") node }) setMethod("removeAttributes", "XMLNode", function(node, ..., .attrs = NULL, .namespace = FALSE, .all = (length(list(...)) + length(.attrs)) == 0) { a = node$attributes if(missing(.attrs)) .attrs = list(...) .attrs = as.character(.attrs) if(.all) { if(length(.attrs)) stop("Both individual attribute names and .all specified") node$attributes = character() return(node) } i = match(.attrs, names(a)) if(any(is.na(i)) ) warning("Can't locate attributes ", paste(.attrs[is.na(i)], collapse = ", "), "in XML node ", node$name) a = a[is.na(i)] node$attributes <- a node }) #xmlNamespaceDefinitions = # ??? added this but overrides other S3 generic. namespaceDeclarations = function(node, ref = FALSE, ...) { .Call("RS_XML_getNsList", node, as.logical(ref), PACKAGE = "XML") } "xmlName<-" = function(x, value) { UseMethod("xmlName<-") } "xmlName<-.XMLNode" <- function(x, value) { x$name <- value x } "xmlName<-.XMLInternalElementNode" <- function(x, value) { # we could handle a new namespace by accepting value as # a character vector with a name # e.g. c(r:array = 'http://www.r-project.org') # Alternatively, just define the namespace on the node _before_ # changing the name. id = names(value) if(!is.null(id) && length( (tmp <- strsplit(id, ":")[[1]])) > 1) { names(value) = tmp[1] newXMLNamespaces(x, .values = as(value, "character")) value = id } .Call("RS_XML_setNodeName", x, value, PACKAGE = "XML") x } newXMLNamespaces = # allow for multiple namespaces # and also allow for "r:value" # # newXMLNamespaces(node, r = "http://www.r-project.org", ...) # function(node, ..., .values = list(...)) { ids = names(.values) ans = lapply(ids, function(id) newNamespace(node, id, as.character(.values[[id]]))) names(ans) = ids ans } xmlNodeMatch = function(x, table, nomatch = NA_integer_) { .Call("R_matchNodesInList", x, table, as.integer(nomatch), PACKAGE = "XML") } setGeneric("xmlClone", function(node, recursive = TRUE, addFinalizer = FALSE, ...) { oclass = class(node) ans = standardGeneric("xmlClone") if(!isS4(node)) class(ans) = oclass ans }) setMethod("xmlClone", "XMLInternalDocument", function(node, recursive = TRUE, addFinalizer = NA, ...) { ans = .Call("RS_XML_clone", node, as.logical(recursive), addFinalizer, PACKAGE = "XML") addDocFinalizer(ans, addFinalizer) ans }) setMethod("xmlClone", "XMLInternalNode", function(node, recursive = TRUE, addFinalizer = FALSE, ...) { ans = .Call("RS_XML_clone", node, as.logical(recursive), addFinalizer, PACKAGE = "XML") }) ensureNamespace = # # Idea is to make certain that the root node has definitions for the specified # namespaces. The caller specifies the named vector of interest. # If the URL already exists, we return the corresponding prefix. # # # Returns the prefixes in the documents that correspond to the # namespace definitions # function(doc, what) { if(is(doc, "XMLInternalDocument")) node = xmlRoot(doc) else node = doc defs = xmlNamespaceDefinitions(xmlRoot(doc), simplify = TRUE) i = match(what, defs) w = is.na(i) if(any(w)) { sapply(names(what)[w], function(id) newXMLNamespace(node, what[id], id)) names(what)[w] } else names(defs)[i] } "xmlParent<-" = function(x, ..., value) { addChildren(value, ..., kids = list(x)) } setOldClass("XMLNamespaceRef") setAs("XMLNamespaceRef", "character", function(from) { .Call("R_convertXMLNsRef", from, PACKAGE = "XML") }) xmlSearchNs = function(node, ns, asPrefix = TRUE, doc = as(node, "XMLInternalDocument")) { .Call("R_xmlSearchNs", doc, node, as.character(ns), as.logical(asPrefix), PACKAGE = "XML") } XML/R/xmlOutputBuffer.R0000644000175100001440000002122013607633674014443 0ustar hornikusersxmlOutputBuffer <- # # # Want to check with the DTD whether a tag is legitimate # attributes are valid, etc. # # Add an indentation level. # # Need to escape characters via entities: # <- => %sgets; # < => %lt; # > => %gt; # etc. # # # Allow xmlEndTag with no argument to allow closing the current one. # (Maintain a stack) # # Allow addTag(tag, addTag(), addTag(),) # # # The handling of the connection (i.e. the buf argument) can # be cleaned up using the OOP package from Omegahat. This will be done # in the future. # # # sapply(names(nameSpace), function(i, x){paste("xmlns:",i,"=\"",x[[i]],"\"", sep="")}, x=nameSpace) # # # function(dtd = NULL, nameSpace = NULL, buf = NULL, nsURI = NULL, header = "") { # If the user gave as an existing buffer and header is non-NULL, # we appendd it to the buffer. This can be used for adding things # like section breaks, etc. # # If the user did not give us a buffer, then we use the header. # # This is done immediately the function is called, rather than # in the calls to the functions of the closure after it is returned. if(is.null(buf)) buf <- header else if(inherits(buf, "connection")) { if(!isOpen(buf)) { open(buf, rw = "w") on.exit(close(buf)) } cat(header,"\n", sep="", file = buf) } else if(!is.null(header)) cat(header,"\n", sep="", file = buf) emittedDocType <- FALSE if(missing(nameSpace) && !is.null(nsURI) && !is.null(names(nsURI))) { nameSpace <- names(nsURI)[1] } openTags <- NULL #list() lastTag <- 0 # This is called from addTag() when the tag being # emitted into the stream is left open by that call. # We store the tag name, its namespace and the URI of the # namespace if there is one in this call. # This triple is appended as the last row of the openTags # matrix and lastTag is incremented. addOpenTag <- function(tag, ns, xmlns) { lastTag <<- lastTag+1 if( lastTag == 1 ) { rval <- matrix(c(tag, if(is.null(ns)) "" else ns, if(is.null(xmlns)) "" else xmlns), nrow = 1, dimnames=list(NULL, c("tagname","nsprefix", "nsURI")) ) } else rval <- rbind(openTags, c(tag, ifelse(is.null(ns),openTags[lastTag-1,2], ns), ifelse(is.null(xmlns),"",xmlns))) openTags <<- rval } checkNamespace <- function(ns) { return(TRUE) ## Ignored if( (lastTag == 0) ) stop(paste("Namespace `",ns, "' is not defined\n",sep="")) m <- match(ns, openTags$nsprefix, NULL) if( any(!is.null(openTags[m,"nsURI"])) ) return(FALSE) stop(paste("Namespace:",ns, "is not defined\n",sep=" ")) } openTag <- function(tag, ..., attrs = NULL, sep = "\n", namespace = NULL, xmlns = NULL) { addTag(tag, ..., attrs = attrs, sep = sep, namespace = namespace, xmlns, close = FALSE) } # The namespace is the prefix for the tag name. # For example, if the namespace is shelp and the tag is arg # the element is shelp:tag. # In this function, we try to infer the ``current'' namespace # if the user doesn't specify it. We also have to ensure that # the namespace has a definition before it is used. # # We also need to allow the user specify an empty namespace # so that tags addTag <- function(tag, ..., attrs = NULL, sep = "\n", close = TRUE, namespace = NULL, xmlns = NULL) { tmp <- "" # Flag indicating whether this is the very first, top-level tag. # should be shared across these functions and part of the state of # the output buffer instance ? startingTag <- is.null(getOpenTag()) # The user didn't specify a namespace, then we need to check about the xmlns. # If the user specified that, then there is an inconsistency. # Otherwise, no namespace and no xmlns. So need to get the # current nameSpace. if(is.null(namespace)) { if( !is.null(xmlns) ) { # Really want to look this up in the set of "global" namespaces. if(is.null(names(xmlns))) stop("you must specify the namespace as well as xmlns") namespace <- names(xmlns)[1] } else { # so there is no xmlns. # We need to determine what the currently active # namespace is. cur <- getOpenTag() if(is.null(cur)) { # Use the default namespace given when the buffer waas constructed namespace <- nameSpace # xmlns <- nsURI } else { startingTag <- FALSE namespace <- cur[["nsprefix"]] } } } # if you remap prefixes this could be a problem if(!startingTag && !is.null(namespace) && namespace == nameSpace && is.null(xmlns) ) { tmp1 <- getOpenTag() if(is.null(tmp1) && !is.null(nsURI)) { # || tmp1[["nsURI"]] != nsURI) { xmlns <- nsURI[1] } # else namespace <- NULL } #if xmlns is given but not the namespace, then # check this. if( !is.null(namespace) && is.null(xmlns) ) checkNamespace(namespace) if( !is.null(namespace) && !is.null(xmlns) ) { if(!is.null(names(xmlns))) { tmpp <- xmlns names(tmpp) <- paste("xmlns", names(tmpp), sep=":") attrs <- c(attrs, tmpp) } else attrs[[paste("xmlns", namespace, sep=":")]] <- xmlns } if(startingTag && !is.null(nsURI)) { tmpp <- nsURI names(tmpp) <- paste("xmlns", names(nsURI), sep=":") attrs <- c(attrs, tmpp) } # if the namespace is non-trivial (null or ""), then concatenate with the # tag name. Also handle the case that this is the starting tag # and so no namespaces are defined at this point. # !startingTag && tagName <- if(!is.null(namespace) && namespace != "") paste(namespace,tag,sep=":") else tag if(!is.null(attrs)) { tmp <- paste(" ", paste(names(attrs), paste("\"",attrs,"\"", sep=""),sep="=", collapse=" "),sep="") } if(length(dtd) && !emittedDocType) { add(paste(" 1) paste("PUBLIC", ddQuote(dtd[2])), ">")) emittedDocType <<- TRUE } add(paste("<", tagName, tmp, ">", sep="")) if(length(list(...)) > 0) { add(..., sep=sep) } if(close) add(paste(if(sep == "\n")"" else"\n", "", "\n", sep=""), sep="") else addOpenTag(tag, namespace, xmlns) NULL } closeTag <- function(name = NULL, namespace = nameSpace) { if(is.null(name)) { tmp <- getOpenTag() name <- tmp[1] if(length(tmp)>1) namespace <- tmp[2] openTags <<- openTags[-lastTag, ,drop = FALSE] lastTag <<- lastTag-1 } else if(is.numeric(name)) { for(i in 1:name) closeTag() return() } add("\n", sep="") } # This returns the last entry in the matrix openTags # which should contain the currently open tag, namespace and # associated URI. getOpenTag <- function() { if(lastTag > 0) openTags[lastTag, ] else NULL } # paste0 <- function(..., sep="", collapse="") paste(..., sep = sep, collapse=collapse) reset <- function() { buf <<- header openTags <<- list() lastTag <<- 0 } addComment <- function(..., sep="\n") { add("", sep=sep) } add <- function(..., sep="\n") { if(is.character(buf)) buf <<- paste(buf, paste0(..., collapse=sep), sep=sep) else cat(paste0(..., collapse=sep), sep, sep="", file=buf) } addCData <- function(text) { add("", sep="\n") } addPI <- function(name, text) { add("\n", sep="") } tagString <- function(tag, ..., attrs, close=FALSE) { tmp <- "" if(!missing(attrs)) { tmp <- paste(" ", paste(names(attrs), paste("\"",attrs,"\"", sep=""), sep="=", collapse=" "),sep="") } return(paste0("<", tag,tmp, ">",...,"")) } con <- list( value=function() {buf}, addTag = addTag, openTag = openTag, closeTag = closeTag, addEndTag = closeTag, reset = reset, tagString = tagString, add = add, addComment = addComment, addPI = addPI, addCData = addCData, getOpenTag=getOpenTag, addOpenTag=addOpenTag ) # class(con) <- c("XMLOutputBuffer", "XMLOutputStream") # con ans = new("XMLOutputBuffer", con) names(ans) = names(con) ans } XML/R/libxmlFeatures.R0000644000175100001440000000011613607633670014253 0ustar hornikusers libxmlFeatures = function() { .Call("R_getXMLFeatures", PACKAGE = "XML") } XML/R/tree.R0000644000175100001440000000712113607633674012233 0ustar hornikusers## needed for sanity .children <- .this <- .nodes <- .parents <- NULL nodeIdGenerator = # # Not currently used. See asXMLTreeNode and the alternative default # argument for XMLHashTree instances which would allow us to use # this function. But then we'd have to deal XMLFlatListTree differently. # function(suggestion = "", env) { # the check to see if suggestion is a name in env is very expensive? Is it? if(suggestion == "" || exists(suggestion, env, inherits = FALSE)) as.character(length(objects(env))) # .count + 1) else suggestion } asXMLTreeNode = function(node, env, id = get(".nodeIdGenerator", env)(xmlName(node)), # nodeIdGenerator(xmlName(node), env), className = "XMLTreeNode") { node$id = id node$env = env class(node) = c(className, class(node)) node } addParentNode = function(node, kids = character()) { if(!inherits(node, 'XMLTreeNode')) { node = asXMLTreeNode(node, .this) } id = node$id .children[[ id ]] <<- kids .parents[ kids ] <<- id .nodes[[ id ]] <<- node id } addNode.XMLFlatListTree = function(node, parent) { e = parent$env if(!("id" %in% names(unclass(node)))) node$id = get(".nodeIdGenerator", e)(xmlName(node)) node$env = parent$env id = node$id nodes <- get(".nodes", e) nodes[[ id ]] <- node assign(".nodes", nodes, e) p = get(".parents", e) p[id] = parent$id assign(".parents", p, e) kids = get(".children", e) kids[[ parent$id ]] <- c(kids[[ parent$id ]] , node$id) assign(".children", kids, e) node } names.XMLFlatTree = function(x) { names(get(".nodes", x)) } "$.XMLFlatListTree" = function(x, name) { get(".nodes", envir = x)[[name]] } xmlRoot.XMLFlatTree = function(x, skip = TRUE, ...) { p = get(".parents", x) #XXX } xmlChildren.XMLTreeNode = function(x, addNames = TRUE, ...) { e = x$env kids = get(".children", e) nodes = get(".nodes", e) ans = if(x$id %in% names(kids)) nodes[ kids[[ x$id ]] ] else list() structure(ans, class = "XMLNodeList") } if(useS4) setMethod("xmlChildren", "XMLTreeNode", xmlChildren.XMLTreeNode) setMethod("xmlParent", "XMLTreeNode", function(x, ...) { p = get(".parents", x$env) idx = match(x$id, names(p)) if(is.na(idx)) return(NULL) get(".nodes", x$env)[[ p[x$id] ]] }) xmlToList = function(node, addAttributes = TRUE, simplify = FALSE) { if(is.character(node)) node = xmlParse(node) if(inherits(node, "XMLAbstractDocument")) node = xmlRoot(node) if(any(inherits(node, c("XMLTextNode", "XMLInternalTextNode")))) xmlValue(node) else if(xmlSize(node) == 0) xmlAttrs(node) else { if(is.list(node)) { # inherits(node, "XMLAbstractNode")) tmp = vals = xmlSApply(node, xmlToList, addAttributes) tt = xmlSApply(node, inherits, c("XMLTextNode", "XMLInternalTextNode")) } else { tmp = vals = (if(simplify) xmlSApply else xmlApply)(node, xmlToList, addAttributes) tt = xmlSApply(node, inherits, c("XMLTextNode", "XMLInternalTextNode")) } vals[tt] = (if(simplify) sapply else lapply)(vals[tt], function(x) x[[1]]) if(length(attrs <- xmlAttrs(node)) > 0) { if(addAttributes) vals[[".attrs"]] = attrs else attributes(vals) = as.list(attrs) } if(any(tt) && length(vals) == 1) vals[[1]] else vals } } indexOfNode = #XXX Do this for hash trees. function(x) { if(!inherits(x, "XMLInternalNode")) stop("must be an internal node") .Call("R_XML_indexOfChild", x, PACKAGE = "XML") } XML/R/readHTMLTable.R0000644000175100001440000002207313610555150013631 0ustar hornikusers trim = function(x) gsub("(^[[:space:]]+|[[:space:]]+$)", "", x) textNodesOnly = # Only process the top-level text nodes, not recursively. # Could be done as simply as # xmlValue(x, recursive = FALSE) function(x) paste(xmlSApply(x, function(n) if(is(n, "XMLInternalTextNode")) xmlValue(n) else ""), collapse = "") toNumber = function(x) { as.numeric(gsub("[%,]", "", x)) } if(FALSE) { doc = htmlParse("http://elections.nytimes.com/2008/results/states/president/california.html") tbls = getNodeSet(doc, "//table[not(./tbody)]|//table/tbody") o = readHTMLTable(tbls[[1]], skip.rows = c(1, Inf), header = FALSE, colClasses = c("character", replicate(5, toNumber)), elFun = textOnly) o = readHTMLTable("http://elections.nytimes.com/2008/results/states/president/california.html") x = readHTMLTable("http://www.usatoday.com/news/politicselections/vote2004/CA.htm", as.data.frame = FALSE) } setGeneric("readHTMLTable", function(doc, header = NA, colClasses = NULL, skip.rows = integer(), trim = TRUE, elFun = xmlValue, as.data.frame = TRUE, which = integer(), ...) standardGeneric("readHTMLTable")) setMethod("readHTMLTable", "character", function(doc, header = NA, colClasses = NULL, skip.rows = integer(), trim = TRUE, elFun = xmlValue, as.data.frame = TRUE, which = integer(), encoding = character(), ...) { pdoc = htmlParse(doc, encoding = encoding) readHTMLTable(pdoc, header, colClasses, skip.rows, trim, elFun, as.data.frame, which, ...) }) # XXX Should vectorize in header, colClasses, i.e. allow different values for different tables. setMethod("readHTMLTable", "HTMLInternalDocument", function(doc, header = NA, colClasses = NULL, skip.rows = integer(), trim = TRUE, elFun = xmlValue, as.data.frame = TRUE, which = integer(), ...) { # tbls = getNodeSet(doc, "//table[not(./tbody)]|//table/tbody") tbls = getNodeSet(doc, "//table") # XXX probably want something related to nested tables # "//table[not(ancestor::table)]" -> outer ones # if header is missing, compute it each time. if(length(which)) tbls = tbls[which] # ans = lapply(tbls, readHTMLTable, header, colClasses, skip.rows, trim, elFun, as.data.frame, ...) header = rep(header, length = length(tbls)) ans = mapply(readHTMLTable, tbls, header, MoreArgs = list(colClasses = colClasses, skip.rows = skip.rows, trim = trim, elFun = elFun, as.data.frame = as.data.frame, ...), SIMPLIFY = FALSE) names(ans) = sapply(tbls, getHTMLTableName) if(length(which) && length(tbls) == 1) ans[[1]] else ans }) getHTMLTableName = function(node) { id = xmlGetAttr(node, "id") if(!is.null(id)) return(id) cap = getNodeSet(node, "./caption") if(length(cap)) return(xmlValue(cap[[1]])) } setClass("FormattedNumber", contains = "numeric") setClass("FormattedInteger", contains = "integer") setAs('character', 'FormattedNumber', function(from) as.numeric(gsub(",", "", from))) setAs('character', 'FormattedInteger', function(from) as.integer(gsub(",", "", from))) setClass("Currency", contains = "numeric") setAs("character", "Currency", function(from) as.numeric(gsub("[$,]", "", from))) setClass("Percent", contains = "numeric") setAs('character', 'Percent', function(from) as.numeric(gsub("%", "", from))) setMethod("readHTMLTable", "XMLInternalElementNode", #readHTMLTable.XMLInternalElementNode = # # # header is computed based on whether we have a table node and it has a thead. # (We don't currently bother with the col spans.) # # colClasses can be a character vector giving the name of the type for a column, # an NULL to drop the corresponding column, or a function in which case it will # be passed the contents of the column and can transform it as it wants. # This allows us to clean text before converting it. # # skip.rows - an integer vector indicating which rows to ignore. # # trim - a logical indicating whether to trim white space from the start and end of text. # # elFun - a function which is called to process each th or td node to extract the content. # This is typically xmlValue, but one can supply others (e.g. textNodesOnly) # as.data.frame # function(doc, header = NA , colClasses = NULL, skip.rows = integer(), trim = TRUE, elFun = xmlValue, as.data.frame = TRUE, encoding = 0L, ...) { node = doc headerFromTable = FALSE dropFirstRow = FALSE # check if we have a header if(length(header) == 1 && is.na(header)) # this node was doc header = (xmlName(doc) %in% c("table", "tbody") && ("thead" %in% names(doc) || length(getNodeSet(node, "./tr[1]/th | ./tr[1]/td")) > 0)) if(is.logical(header) && (is.na(header) || header) && xmlName(node) == "table") { if("thead" %in% names(node)) header = node[["thead"]] else { if("tr" %in% names(node)) tmp = node[["tr"]] else tmp = node[["tbody"]][["tr"]] if(!is.null(tmp) && all(names(tmp) %in% c('text', 'th'))) { header = xpathSApply(tmp, "./th | ./td", xmlValue, encoding = encoding) dropFirstRow = TRUE } } } # Moved this from before the check for header as we set node here and that seems # premature. Checked on # readHTMLTable("http://www.google.com/finance?q=NASDAQ:MSFT&fstype=ii", header = TRUE, which = 1) tbody = getNodeSet(node, "./tbody") if(length(tbody)) node = tbody[[1]] if(is(header, "XMLInternalElementNode")) { # get the last tr in the thead if(xmlName(header) == "thead") { i = which(names(header) == "tr") header = header[[ i [ length(i) ] ]] xpath = "./th | ./td" } else xpath = "./*/th | ./*/td" header = as.character(xpathSApply(header, xpath, elFun, encoding = encoding)) headerFromTable = TRUE if(xmlName(node) == "table" && "tbody" %in% names(node)) node = node[["tbody"]] } # Process each row, by getting the content of each "cell" (th/td) rows = getNodeSet(node, ".//tr") if(dropFirstRow) rows = rows[-1] els = lapply(rows, function(row) { tmp = xpathSApply(row, "./th|./td", elFun) if(trim) trim(tmp) else tmp }) # spans = getNodeSet(node, ".//td[@rowspan] | .//th[@rowspan]") if(length(skip.rows)) { infs = (skip.rows == Inf) if(any(infs)) # want Inf - 2, Inf - 1, Inf, to indicate drop last 3, but that won't work # take sequence of Inf to identify Inf - 2, Inf - 1, Inf skip.rows[skip.rows == Inf] = length(els) - seq(0, length = sum(infs)) els = els[ - skip.rows ] } if(length(els) == 0) return(NULL) numEls = sapply(els, length) # els[[1]] should be a scalar if(is.logical(header) && !is.na(header) && header && any(nchar(els[[1]]) < 999)) { header = els[[1]] els = els[-1] numEls = numEls[ - 1] } if(length(els) == 0) return(NULL) #XXX we should have a header here so return a data frame with 0 rows. ans = lapply(seq(length = max(numEls)), function(col) { sapply(els, `[`, col) }) if(is.character(header) && length(header) == length(ans)) names(ans) = header if(length(colClasses)) { colClasses = rep(colClasses, length = length(ans)) n = sapply(colClasses, function(x) is.null(x) || x == "NULL") if(any(n)) { ans = ans[ ! n ] colClasses = colClasses[ ! n ] } ans = lapply(seq(along = ans) , function(i) if(is.function(colClasses[[i]])) colClasses[[i]](ans[[i]]) else if(colClasses[[i]] == "factor") factor(ans[[i]]) else if(colClasses[[i]] == "ordered") ordered(ans[[i]]) else as(ans[[i]], colClasses[[i]]) ) } if(as.data.frame) { ans = as.data.frame(ans, ...) if(is.character(header) && length(header) == length(ans)) names(ans) = header else if(nrow(ans) > 0) names(ans) = paste("V", seq(along = ans), sep = "") } ans }) getTableWithRowSpan = function(node, r = xmlSize(node), c = max(xmlSApply(node, function(x) length(getNodeSet(x, "./td | ./th")))), encoding = 0L) { ans = matrix(NA_character_, r, c) for(i in seq(length = r)) { col = 1 kids = getNodeSet(node[[i]], "./th | ./td") for(k in seq(along = kids)) { sp = xmlGetAttr(k, "rowspan", 1) ans[seq(i, length = sp)] = xmlValue(k, encoding = encoding) } } } XML/R/keyValueDB.R0000644000175100001440000000467613607633705013276 0ustar hornikusers# All the possible names, empirically # table(xpathSApply(it, "//*", xmlName)) # On a file that has 549,286 nodes (JasonLibrary.xml) # this took 37 seconds to process the entire file. # # array data date dict false integer key plist string # 5 14 22104 33103 3 133465 263594 1 96631 # true # 366 setGeneric("readKeyValueDB", function(doc, ...) standardGeneric("readKeyValueDB")) setMethod("readKeyValueDB", "character", function(doc, ...) readKeyValueDB(xmlParse(doc), ...)) setMethod("readKeyValueDB", "AsIs", function(doc, ...) readKeyValueDB(xmlParse(doc), ...)) setMethod("readKeyValueDB", "XMLInternalDocument", function(doc, ...) readKeyValueDB(xmlRoot(doc)[["dict"]], ...)) setMethod("readKeyValueDB", "XMLInternalNode", function(doc, dropComments = TRUE, ...) { kids = xmlChildren(doc) if(dropComments) kids = kids[!sapply(kids, is, "XMLInternalCommentNode")] if(length(kids) == 0) return(list()) i = seq(by = 2, length = length(kids)/2) keys = sapply(kids[ i ], xmlValue) structure(lapply(kids[i + 1], readPlistNodeValue, dropComments = dropComments, ...), names = keys) }) readPlistNodeValue = function(node, dropComments = TRUE) { id = xmlName(node) switch(id, integer = if(abs(tmp <- as.numeric(xmlValue(node))) > .Machine$integer.max) tmp else as.integer(xmlValue(node)), string = xmlValue(node), data = xmlValue(node), key = xmlValue(node), dict = readKeyValueDB(node), true = TRUE, false = FALSE, date = as.POSIXct(strptime(xmlValue(node), "%Y-%m-%dT%H:%M:%SZ")), array = { tmp = if(dropComments) node[!xmlSApply(node, inherits, "XMLInternalCommentNode")] else xmlChildren(node) # We might want lapply/xmlApply() so as to allow different types with classes, # e.g. POSIXct that doesn't collapse down to a string or whatever. sapply(tmp, readPlistNodeValue) } ) } readPlist = readKeyValueDB XML/R/supports.R.in0000644000175100001440000000024013607633674013573 0ustar hornikuserssupportsExpat <- function() { @SUPPORTS_EXPAT@ } supportsLibxml <- function() { @SUPPORTS_LIBXML@ } ADD_XML_OUTPUT_BUFFER = @ADD_XML_OUTPUT_BUFFER@ > 0 XML/R/DTD.R0000644000175100001440000000527013607633666011713 0ustar hornikusersdtdIsAttribute <- function(name, element, dtd) { if(!inherits(element,"XMLElementDef")) { element <- dtdElement(as.character(element), dtd) } # return(!is.na(amatch(name, names(element$attributes)))) return(!is.na(match(name, names(element$attributes)))) } dtdValidElement <- # # checks whether an XML element named `name' # can be inserted into an element named `within' # as defined in the specific DTD, optionally # specifying the position the `name' element would # be added. # # Ideally, this would be used when writing to an XML stream # (doesn't exist in R or S, yes). # The stream would monitor the currently open tags # (as a stack) and would be able to test whether a new # insertion was valid. function(name, within, dtd, pos=NULL) { el <- dtdElement(within, dtd) if(is.null(el)) stop(paste("No such element \"",within,"\" in DTD",sep="", collapse="")) return(dtdElementValidEntry(el, name,pos=pos)) } dtdElementValidEntry <- function(element, name, pos=NULL) { UseMethod("dtdElementValidEntry", element) # , name, pos) } dtdElementValidEntry.XMLElementDef <- function(element, name, pos=NULL) { return(dtdElementValidEntry(element$contents,name,pos=pos)) } dtdElementValidEntry.XMLOrContent <- function(element, name, pos=NULL) { for(i in element$elements) { if(dtdElementValidEntry(i, name, pos=pos)) return(TRUE) } return(FALSE) } dtdElementValidEntry.XMLElementContent <- function(element, name, pos=NULL) { # if there are no sub-element types, then can't be here. # Might check this is a PCDATA by looking at the type. if(is.null(element$elements)) { return(FALSE) } return( any(element$elements == name) ) } dtdElementValidEntry.character <- function(element, name, pos=NULL) { return(element == name) } dtdElementValidEntry.XMLSequenceContent <- function(element, name, pos=NULL) { if(!is.null(pos)) { tmp <- element$elements[[as.integer(pos)]] if(!is.null(tmp)) return(dtdElementValidEntry(tmp)) else return(FALSE) } for(i in element$elements) { if(dtdElementValidEntry(i, name)) { return(TRUE) } } return(FALSE) } xmlContainsEntity <- # # Determine if a particular entity is defined # within the DTD. # function(name, dtd) { return(!is.na(match(name,dtd$entities))) } xmlContainsElement <- # # Determine if a particular entity is defined # within the DTD. # function(name, dtd) { return(!is.na(match(name,dtd$element))) } dtdEntity <- # # Retrieves the specified entity from the DTD definition. # Uses the `dtd$entitities' list. # function(name, dtd) { dtd$entities[[name]] } dtdElement <- # # Retrieves the specified element from the DTD definition. # Uses the `dtd$elements' list. function(name, dtd) { dtd$elements[[name]] } XML/R/saveXML.R0000644000175100001440000001210213607633674012606 0ustar hornikusersif(FALSE) { saveXML <- function(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { UseMethod("saveXML") } } saveXML.XMLInternalNode <- function(doc, file = NULL, compression = 0, indent = TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { if(is.na(encoding) || length(encoding) == 0 || encoding == "") encoding = character() ans = .Call("RS_XML_printXMLNode", doc, as.integer(0), as.integer(indent), as.logical(indent), as.character(encoding), getEncodingREnum(as.character(encoding)), PACKAGE = "XML") if(length(file)) { cat(ans, file = file) file } else ans } saveXML.XMLInternalDocument <- function(doc, file = NULL, compression = 0, indent = TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { havePrefix = !missing(prefix) isDocType = is(doctype, "Doctype") if(isDocType) { # Check that the value in the DOCTYPE for the top-level name is the same as that of the # root element topname = xmlName(xmlRoot(doc)) if(doctype@name == "") doctype@name = topname else if(topname == doctype@name) stop("The top-level node and the name for the DOCTYPE must agree", doctype@name, " ", topname) prefix = c(doctype@name, doctype@public, doctype@system) } if(length(file)) file = path.expand(file) if(is.na(encoding)) encoding = "" #character() ans = .Call("R_saveXMLDOM", doc, file, as.integer(compression), as.logical(indent), if(is.character(prefix)) prefix else character(), as.character(encoding), # getEncodingREnum(as.character(encoding)), PACKAGE = "XML") if(!isDocType && havePrefix) { prefix = as(prefix, "character") # allow for an XMLInternalNode. if(length(file)) { txt = c(prefix, readLines(file)[-1]) cat(txt, file = file) } else { tmp = strsplit(ans, "\\\n")[[1]] tmp = c(prefix, tmp[-1]) ans = paste(tmp, collapse = "\n") } } if(length(file)) file else ans } saveXML.XMLInternalDOM <- function(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { saveXML(doc$value(), file, compression, indent, prefix, doctype, encoding) } saveXML.XMLOutputStream = function(doc, file = NULL, compression = 0, indent = TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { saveXML(doc$value(), file, compression, indent, prefix, doctype, encoding) } saveXML.sink = # # Need to handle a DTD here as the prefix argument.. # function(doc, file = NULL, compression = 0, indent = TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) { asString = is.null(file) if(asString) file = textConnection(NULL, "w") if(inherits(file, c("character", "connection"))) { sink(file) on.exit(sink()) } if(asString) on.exit(close(file), add = TRUE) if(!is.null(prefix)) cat(as.character(prefix)) if(!is.null(doctype)) cat(as(doctype, "character"), '\n') #XXX Should we return file if it is not missing() || NULL ??? print(doc) if(asString) paste(textConnectionValue(file), collapse = "\n") else file } saveXML.XMLNode = saveXML.sink saveXML.XMLFlatTree = saveXML.sink setGeneric("saveXML", function(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) standardGeneric("saveXML")) setMethod("saveXML", "XMLInternalNode", saveXML.XMLInternalNode) setMethod("saveXML", "XMLInternalDocument", saveXML.XMLInternalDocument) setMethod("saveXML", "XMLInternalDOM", saveXML.XMLInternalDOM) setMethod("saveXML", "XMLOutputStream", saveXML.XMLOutputStream) setMethod("saveXML", "XMLNode", saveXML.sink) setOldClass("XMLFlatTree") setOldClass(c("XMLFlatListTree", "XMLFlatTree")) setMethod("saveXML", "XMLFlatTree", saveXML.sink) setMethod("saveXML", "HTMLInternalDocument", function(doc, file = NULL, compression = 0, indent = TRUE, prefix = '\n', doctype = NULL, encoding = "", ...) { if(ADD_XML_OUTPUT_BUFFER) { if(length(file) && is.character(file)) out = file else out = tempfile() } else out = character() ans = .Call("RS_XML_dumpHTMLDoc", doc, as.integer(indent), as.character(encoding), as.logical(indent), as.character(out), PACKAGE = "XML") if(length(file) && length(out) == 0) { cat(ans, file = file) file } else if(length(out)) { paste(readLines(out), collapse = "\n") } else { ans } }) XML/R/summary.R0000644000175100001440000000326013607633667012773 0ustar hornikusers xmlElementSummaryHandlers = # # Functions for the event parser that we can use # to count the occurrences of each tag and the attributes function(file = character(), countAttributes = TRUE) { # Collect a list of attributes for each element. tags = list() # frequency table for the element names counts = integer() start = function(name, attrs, ...) { if(name == "xi:include") { # need to handle the xpointer piece # and the relative path names - done with getRelativeURL href = getRelativeURL(attrs['href'], dirname(file), sep = .Platform$file.sep) xmlElementSummary(href, funs) } if(!countAttributes) tags[[name]] <<- unique(c(names(attrs), tags[[name]])) else { x = tags[[name]] i = match(names(attrs), names(x)) if(any(!is.na(i))) x[i[!is.na(i)]] = x[i[!is.na(i)]] + 1 if(any(is.na(i))) x[names(attrs)[is.na(i)]] = 1 tags[[name]] <<- x } counts[name] <<- if(is.na(counts[name])) 1 else counts[name] + 1 } funs = list(.startElement = start, .getEntity = function(x, ...) "xxx", .getParameterEntity = function(x, ...) "xxx", result = function() list(nodeCounts = sort(counts, decreasing = TRUE), attributes = tags)) } xmlElementSummary = function(url, handlers = xmlElementSummaryHandlers(url)) { handlers if(file.exists(url) && file.info(url)[1, "isdir"]) url = list.files(url, pattern = "\\.xml$", full.names = TRUE) if(length(url) > 1) lapply(url, xmlElementSummary, handlers) else xmlEventParse(url, handlers, replaceEntities = FALSE) handlers$result() } XML/R/parser.R0000644000175100001440000000341114216306410012544 0ustar hornikusers# cat(paste(names(parserOptions), paste(2, 0:(length(parserOptions) - 1), sep = "^"), sep = " = ", collapse = "\n")) #setClass("XMLParserOption", "EnumValue") parserOptions = structure(c(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576 ), .Names = c("RECOVER", "NOENT", "DTDLOAD", "DTDATTR", "DTDVALID", "NOERROR", "NOWARNING", "PEDANTIC", "NOBLANKS", "SAX1", "XINCLUDE", "NONET", "NODICT", "NSCLEAN", "NOCDATA", "NOXINCNODE", "COMPACT", "OLD10", "NOBASEFIX", "HUGE", "OLDSAX")) RECOVER = 2^0 NOENT = 2^1 DTDLOAD = 2^2 DTDATTR = 2^3 DTDVALID = 2^4 NOERROR = 2^5 NOWARNING = 2^6 PEDANTIC = 2^7 NOBLANKS = 2^8 SAX1 = 2^9 XINCLUDE = 2^10 NONET = 2^11 NODICT = 2^12 NSCLEAN = 2^13 NOCDATA = 2^14 NOXINCNODE = 2^15 COMPACT = 2^16 OLD10 = 2^17 NOBASEFIX = 2^18 HUGE = 2^19 OLDSAX = 2^20 ## This can (and does) send illegal file names to file.exists(), which ## has been protected against that but should really be caught here. xmlParseDoc = function(file, options = 1L, encoding = character(), asText = !file.exists(file), baseURL = file) { if(is.character(options)) { i = pmatch(options, names(parserOptions)) if(any(is.na(i))) stop("unrecognized XML parser options: ", paste(options[is.na(i)], collapse = ", ")) options = parserOptions[i] } else { if(!all(options %in% parserOptions)) stop("unrecognized XML parser options: ", paste(options[!(options %in% parserOptions)], collapse = ", ")) } options = as.integer(sum(options)) if(asText) .Call("R_xmlReadMemory", file, nchar(file), as.character(encoding), options, as.character(baseURL), PACKAGE = "XML") else .Call("R_xmlReadFile", path.expand(file), as.character(encoding), options, PACKAGE = "XML") } XML/R/reflection.R0000644000175100001440000001221313610555150013406 0ustar hornikusers# These are functions that examine an XML node and # defines a class for each complex type. # # Need to make this work recursively # xmlToS4List = function(from, class = xmlName(from), type = gsub("s$", "", xmlName(from))) { new(class, xmlApply(from, as, type)) } setGeneric("xmlToS4", function(node, obj = new(xmlName(node)), ...) standardGeneric("xmlToS4") ) setMethod("xmlToS4", "XMLInternalNode", function(node, obj = new(xmlName(node)), ...) { if(is(obj, "character") && !isS4(obj)) obj = new(obj) # if(xmlSize(node) == 1 && node[[1]]) # return(as()) ids = names(node) nodes = xmlChildren(node) obj = addXMLAttributes(obj, xmlAttrs(node, addNamespacePrefix = TRUE)) slotIds = slotNames(obj) slots = getClass(class(obj))@slots if(any(duplicated(ids))) { # experimenting with a different way of doing this. # Group the nodes with the same names and the process those. groupedNodes = split(nodes, ids) ids = intersect(names(groupedNodes), slotIds) for(i in ids) { tmp = groupedNodes[[i]] slot = slots[[i]] if(length(tmp) > 1) { val = lapply(tmp, convertNode, slot) val = if(isAtomicType(slot)) unlist(val) else as(val, slot) # may be a specific sub-type of list } else { el = tmp[[1]] val = convertNode(el, slot) } slot(obj, i) <- val } } else { # This was the original mechanism but it doesn't handle multiple nodes of the same name. for(i in seq(along = nodes)) { if(ids[i] %in% slotIds) { val = if(slots[[ids[i]]] == "character") xmlValue(nodes[[i]]) else tryCatch(as(nodes[[i]], slots[[ids[i]]]), error = function(e) xmlToS4(nodes[[i]])) slot(obj, ids[i]) <- val # xmlToS4(nodes[[i]]) } # obj = addAttributes(obj, xmlAttrs(nodes[[i]])) } } obj }) convertNode = function(el, slot) { if(slot == "character") xmlValue(el) else tryCatch(as(el, slot), error = function(e) xmlToS4(el)) } isAtomicType = # # check if className refers to a primitive/atomic type # or not. function(className) { atomicTypes = c("logical", "integer", "numeric", "character") if(className %in% atomicTypes) return(TRUE) k = getClassDef(className) length(intersect(names(k@contains), atomicTypes)) > 0 } addXMLAttributes = function(obj, attrs) { slots = getClass(class(obj))@slots i = match(names(attrs), names(slots)) # handle any namespace prefix if(any(is.na(i))) { w = grepl(":", names(attrs)) & is.na(i) if(any(w)) i[which(w)] = match(gsub(".*:", "", names(attrs)[which(w)]), names(slots)) } m = i if(any(!is.na(i))) { vals = structure(attrs[!is.na(i)], names = names(slots)[i [!is.na(i)] ]) for(i in names(vals)) slot(obj, i) <- as(vals[i], slots[[i]]) } obj } makeClassTemplate = # # Get the class representation information to represent the contents of # an XML node. # # function(xnode, types = character(), default = "ANY", className = xmlName(xnode), where = globalenv()) { user.types = types slots = names(xnode) types = xmlSApply(xnode, function(x) { if(xmlSize(x) == 0) default else if(xmlSize(x) == 1 || is(x, "XMLInternalTextNode")) "character" else xmlName(x) }) names(types) = slots types[names(xmlAttrs(xnode))] = "character" if(length(user.types)) types[names(user.types)] = user.types coerce = sprintf("setAs('XMLAbstractNode', '%s', function(from) xmlToS4(from))", className) def = if(length(types)) sprintf("setClass('%s',\n representation(%s))", className, paste(sQuote(names(types)), sQuote(types), sep = " = ", collapse = ",\n\t")) else sprintf("setClass('%s')", className) if(!is.null(where) && !(is.logical(where) && !where)) { eval(parse(text = def), envir = where) eval(parse(text = coerce), envir = where) } list(name = className, slots = types, def = def, coerce = coerce) } setAs("XMLAbstractNode", "integer", function(from) as.integer(xmlValue(from))) setAs("XMLAbstractNode", "numeric", function(from) as.numeric(xmlValue(from))) setAs("XMLAbstractNode", "character", function(from) xmlValue(from)) setAs("XMLAbstractNode", "URL", function(from) new("URL", xmlValue(from))) setAs("XMLAbstractNode", "logical", function(from) as.logical(xmlValue(from))) setAs("XMLAbstractNode", "Date", function(from) as.Date(xmlValue(from), "%Y-%m-%d")) setAs("XMLAbstractNode", "POSIXct", function(from) as.POSIXct(strptime(xmlValue(from), "%Y-%m-%d %H:%M:%S"))) makeXMLClasses = function(doc, omit = character(), eval = FALSE) { a = getNodeSet(doc, "//*") ids = unique(sapply(a, xmlName)) if(length(omit)) ids = setdiff(ids, omit) lapply(ids, function(id) makeClassTemplate(getNodeSet(doc, sprintf("//%s", id))[[1]], where = eval)) } XML/R/assignChild.R0000644000175100001440000000227714405636156013526 0ustar hornikusers"[<-.XMLNode" <- function(x, i, value) { x$children[i] <- value if(!is.character(i)) { names(x$children)[i] = if(inherits(value, "XMLNode")) xmlName(value) else sapply(value, xmlName) } x } "[[<-.XMLNode" <- function(x, i, value) { x$children[[i]] <- value if(!is.character(i)) { names(x$children)[i] = if(inherits(value, "XMLNode")) xmlName(value) else sapply(value, xmlName) } x } append.xmlNode <- function(to, ...) { UseMethod("append.xmlNode") } append.XMLNode <- function(to, ...) { args <- list(...) if(!inherits(args[[1]], "XMLNode") && is.list(args[[1]])) args <- args[[1]] idx <- seq(length(to$children) + 1, length=length(args)) args = addNames(args) if(is.null(to$children)) to$children <- args else { to$children[idx] <- args names(to$children)[idx] <- names(args) } to } append.xmlNode.default <- function(to, ...) base::append(to, ...) if(FALSE) { xmlAddChild <- function(node, child) { node$children <- append(node$children, list(child)) names(node$children) <- sapply(node$children,xmlName) node } } XML/R/SAXMethods.R0000644000175100001440000001040713610046416013236 0ustar hornikusers.InitSAXMethods <- # Defines S4 classes for use with the SAX parser and specifically to do with the # state variable. # This also defines methods for the function(where = "package:XML") { # require(methods) setClass("SAXState", "VIRTUAL", where = where) setGeneric("startElement.SAX", function(name, atts, .state = NULL) standardGeneric("startElement.SAX"), where = where) setGeneric("endElement.SAX", function(name, .state = NULL) { standardGeneric("endElement.SAX")}, where = where) setGeneric("comment.SAX", function(content, .state = NULL) { standardGeneric("comment.SAX")}, where = where) # Note that we drop the . here. setGeneric("text.SAX", function(content, .state = NULL) { standardGeneric("text.SAX")}, where = where) setGeneric("cdata.SAX", function(content, .state = NULL) { standardGeneric("cdata.SAX")}, where = where) setGeneric("processingInstruction.SAX", function(target, content, .state = NULL) { standardGeneric("processingInstruction.SAX")}, where = where) setGeneric("entityDeclaration.SAX", function(name, base, sysId, publicId, notationName, .state = NULL) { standardGeneric("entityDeclaration.SAX")}, where = where) setMethod("startElement.SAX", signature(.state = "SAXState"), function(name, atts, .state = NULL) .state, where = where) setMethod("endElement.SAX", signature(.state = "SAXState"), function(name, .state = NULL) .state, where = where) setMethod("comment.SAX", signature(.state = "SAXState"), function(content, .state = NULL) .state, where = where) setMethod("text.SAX", signature(.state = "SAXState"), function(content, .state = NULL) .state, where = where) setMethod("processingInstruction.SAX", signature(.state = "SAXState"), function(target, content, .state = NULL) .state, where = where) setMethod("entityDeclaration.SAX", signature(.state = "SAXState"), function(name, base, sysId, publicId, notationName, .state = NULL) .state, where = where) return(TRUE) } .useNamespacesInXMLPackage = FALSE if(!.useNamespacesInXMLPackage) { setClass("SAXState", "VIRTUAL") setGeneric("startElement.SAX", function(name, atts, .state = NULL) standardGeneric("startElement.SAX")) setGeneric("endElement.SAX", function(name, .state = NULL) { standardGeneric("endElement.SAX")}) setGeneric("comment.SAX", function(content, .state = NULL) { standardGeneric("comment.SAX")}) # Note that we drop the . here. setGeneric("text.SAX", function(content, .state = NULL) { standardGeneric("text.SAX")}) setGeneric("processingInstruction.SAX", function(target, content, .state = NULL) { standardGeneric("processingInstruction.SAX")}) setGeneric("entityDeclaration.SAX", function(name, base, sysId, publicId, notationName, .state = NULL) { standardGeneric("entityDeclaration.SAX")}) setMethod("startElement.SAX", signature(.state = "SAXState"), function(name, atts, .state = NULL) .state) setMethod("endElement.SAX", signature(.state = "SAXState"), function(name, .state = NULL) .state) setMethod("comment.SAX", signature(.state = "SAXState"), function(content, .state = NULL) .state) setMethod("text.SAX", signature(.state = "SAXState"), function(content, .state = NULL) .state) setMethod("processingInstruction.SAX", signature(.state = "SAXState"), function(target, content, .state = NULL) .state) setMethod("entityDeclaration.SAX", signature(.state = "SAXState"), function(name, base, sysId, publicId, notationName, .state = NULL) .state) } genericSAXHandlers <- function(include, exclude, useDotNames = FALSE) { if(!exists("startElement.SAX")) stop("You must call .InitSAXMethods before calling genericSAXHandlers()n") ans <- list(startElement = startElement.SAX, endElement = endElement.SAX, comment = comment.SAX, text = text.SAX, processingInstruction = processingInstruction.SAX, entityDeclaration = entityDeclaration.SAX) if(!missing(include)) ans <- ans[include] else if(!missing(exclude)) { which <- match(exclude, names(ans)) ans <- ans[-which] } if(useDotNames) names(ans) = paste(".", names(ans), sep = "") ans } XML/R/htmlParse.R0000644000175100001440000001364513607633667013245 0ustar hornikusersisURL = function(file) { is.character(file) && grepl("^(http|ftp)", file) } ############ #XXXXXXXXX # This is now replaced by copying xmlTreeParse. htmlTreeParse <- # # HTML parser that reads the entire `document' tree into memory # and then converts it to an R/S object. # Uses the libxml from Daniel Veillard at W3.org. # # asText treat the value of file as XML text, not the name of a file containing # the XML text, and parse that. # See also xml # function(file, ignoreBlanks = TRUE, handlers = NULL, replaceEntities = FALSE, asText = inherits(file, "AsIs") || !isURL && grepl("^<", file), # could have a BOM trim = TRUE, isURL = is.character(file) && grepl("^(http|ftp)", file), asTree = FALSE, useInternalNodes = FALSE, encoding = character(), useDotNames = length(grep("^\\.", names(handlers))) > 0, xinclude = FALSE, addFinalizer = TRUE, error = function(...){}, options = integer(), parentFirst = FALSE) { if(TRUE) { doc = xmlTreeParse(file, ignoreBlanks, handlers, replaceEntities, asText, trim, validate = FALSE, getDTD = FALSE, isURL, asTree, addAttributeNamespaces = FALSE, useInternalNodes, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding, useDotNames, xinclude, addFinalizer, error, isHTML = TRUE, options = options) class(doc) = c("HTMLInternalDocument", class(doc)[1]) return(doc) } if(length(file) > 1) { file = paste(file, collapse = "\n") if(!missing(asText) && !asText) stop("multiple URIs passed to xmlTreeParse. If this is the content of the file, specify asText = TRUE") asText = TRUE } if(missing(asText) && substring(file, 1, 1) == "<") asText = TRUE if(!asText && missing(isURL)) { isURL <- length(grep("^(http|ftp)://", file, useBytes = TRUE, perl = TRUE)) } # check whether we are treating the file name as # a) the XML text itself, or b) as a URL. # Otherwise, check if the file exists and report an error. if(asText == FALSE && isURL == FALSE) { if(file.exists(file) == FALSE) stop(paste("File", file, "does not exist ")) } if(!asText && !isURL) file = path.expand(file) old = setEntitySubstitution(replaceEntities) on.exit(setEntitySubstitution(old)) if(!is.logical(xinclude)) { if(inherits(xinclude, "numeric")) xinclude = bitlist(xinclude) else xinclude = as.logical(xinclude) } .oldErrorHandler = setXMLErrorHandler(error) on.exit(.Call("RS_XML_setStructuredErrorHandler", .oldErrorHandler, PACKAGE = "XML"), add = TRUE) ans <- .Call("RS_XML_ParseTree", as.character(file), handlers, as.logical(ignoreBlanks), as.logical(replaceEntities), as.logical(asText), as.logical(trim), FALSE, FALSE, as.logical(isURL), FALSE, as.logical(useInternalNodes), TRUE, FALSE, FALSE, as.character(encoding), as.logical(useDotNames), xinclude, error, addFinalizer, options, as.logical(parentFirst), PACKAGE = "XML") if(!missing(handlers) & !as.logical(asTree)) return(handlers) if(inherits(ans, "XMLInternalDocument")) { addDocFinalizer(ans, addFinalizer) class(ans) = c("HTMLInternalDocument", class(ans)) } ans } #XXXXXX # This is another version that doesn't seem to release the document. Weird. I can't seem to find # out who is holding onto it. myHTMLParse = function(file, ignoreBlanks = TRUE, handlers = NULL, replaceEntities = FALSE, asText = inherits(file, "AsIs") || !isURL && grepl("^<", file), # could have a BOM trim = TRUE, isURL = is.character(file) && grepl("^(http|ftp)", file), asTree = FALSE, useInternalNodes = FALSE, encoding = character(), useDotNames = length(grep("^\\.", names(handlers))) > 0, xinclude = FALSE, addFinalizer = TRUE, error = function(...){}) { doc = xmlTreeParse(file, ignoreBlanks, handlers, replaceEntities, asText, trim, validate = FALSE, getDTD = FALSE, isURL, asTree, addAttributeNamespaces = FALSE, useInternalNodes, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding, useDotNames, xinclude, addFinalizer, error, isHTML = TRUE) class(doc) = c("HTMLInternalDocument", class(doc)[2]) return(doc) } hideParseErrors = function (...) NULL htmlTreeParse = xmlTreeParse formals(htmlTreeParse)$error = as.name("htmlErrorHandler") # as.name("hideParseErrors") formals(htmlTreeParse)$isHTML = TRUE htmlParse = htmlTreeParse formals(htmlParse)$useInternalNodes = TRUE parseURI = function(uri) { if(is.na(uri)) return(structure(as.character(uri), class = "URI")) u = .Call("R_parseURI", as.character(uri), PACKAGE = "XML") if(u$port == 0) u$port = as.integer(NA) class(u) = "URI" u } setOldClass("URI") setOldClass("URL") setAs("URI", "character", function(from) { if(from$scheme == "") sprintf("%s%s%s", from["path"], if(from[["query"]] != "") sprintf("?%s", from[["query"]]) else "", if(from[["fragment"]] != "") sprintf("#%s", from[["fragment"]]) else "" ) else sprintf("%s://%s%s%s%s%s%s%s", from[["scheme"]], from[["user"]], if(from[["user"]] != "") "@" else "", from[["server"]], if(!is.na(from[["port"]])) sprintf(":%d", as.integer(from[["port"]])) else "", from["path"], if(from[["query"]] != "") sprintf("?%s", from[["query"]]) else "", if(from[["fragment"]] != "") sprintf("#%s", from[["fragment"]]) else "" ) }) XML/R/error.R0000644000175100001440000000732513607633667012435 0ustar hornikusersxmlErrorCumulator = function(class = "XMLParserErrorList", immediate = TRUE) { messages = character() function(msg, ...) { # curently discards all the extra information. if(length(grep("\\\n$", msg)) == 0) paste(msg, "\n", sep = "") if(immediate) cat(msg) if(length(msg) == 0) { # collapse into string. Probably want to leave as separate elements of a character vector. # Make into real objects with the ... information. e = simpleError(paste(1:length(messages), messages, sep = ": ",collapse = "")) class(e) = c(class, class(e)) stop(e) } messages <<- c(messages, msg) } } xmlStop = # # Never used anymore. # Related to the non-structed error handling. function(msg, class = "XMLParserError") { err = simpleError(msg) class(err) = c(class , class(err)) stop(err) } makeXMLError = function(msg, code, domain, line, col, level, filename, class = "XMLError") { err = simpleError(msg) err$code = getEnumValue(code, xmlParserErrors) err$domain = getEnumValue(domain, xmlErrorDomain) err$line = line err$col = col err$level = getEnumValue(level, xmlErrorLevel) err$filename = filename class(err) = c(class, class(err)) err } htmlErrorHandler = function(msg, code, domain, line, col, level, filename, class = "XMLError") { e = makeXMLError(msg, code, domain, line, col, level, filename, class) dom = names(e$domain) class(e) = c(names(e$code), sprintf("%s_Error", gsub("_FROM_", "_", dom)), class(e)) if(e$code == xmlParserErrors["XML_IO_LOAD_ERROR"]) stop(e) } xmlStructuredStop = function(msg, code, domain, line, col, level, filename, class = "XMLError") { err = makeXMLError(msg, code, domain, line, col, level, filename, class) stop(err) } xmlErrorFun = function() { errors = list() h = function(msg, code, domain, line, col, level, filename) { if(length(msg) == 0) return(TRUE) err = list(msg = msg, code = code, domain = domain, line = line, col = col, level = level, filename = filename) err = fixXMLError(err) errors[[length(errors) + 1]] <<- err } structure(list(handler = h, errors = function() structure(errors, class = "XMLStructuredErrorList"), reset = function() errors <<- list), class = "XMLStructuredErrorCumulator") } setOldClass("XMLStructuredErrorList") print.XMLStructuredErrorList = function(x, ...) { if(length(x) == 0) print(NULL) else print(t(sapply(x, function(x) unlist(x[c("line", "msg")])))) } getXMLErrors= # # This attempts to read the specified file using the function given in parse # and then returns a list of the errors in the document. # This a somewhat convenient mechanism for fixing up, e.g., malformed HTML # pages or other XML documents. function(filename, parse = xmlParse, ...) { f = xmlErrorFun() opts = options() options(error = NULL) on.exit(options(opts)) tryCatch(parse(filename, ..., error = f$handler), error = function(e){}) f$errors() } # Low level error handler setXMLErrorHandler = function(fun) { prev = .Call("RS_XML_getStructuredErrorHandler", PACKAGE = "XML") sym = getNativeSymbolInfo("R_xmlStructuredErrorHandler", "XML")$address .Call("RS_XML_setStructuredErrorHandler", list(fun, sym), PACKAGE = "XML") prev } fixXMLError = function(err) { err$domain = getEnumValue(err$domain, xmlErrorDomain) err$code = getEnumValue(err$code, xmlParserErrors) err$level = getEnumValue(err$level, xmlErrorLevel) class(err) = "XMLError" err } getEnumValue = function(value, defs) { # might use for the class. name = substitute(defs) i = which(value == defs) defs[i] } XML/R/xmlIncludes.R0000644000175100001440000000444014405636156013557 0ustar hornikusersxmlXIncludes = # # This is similar to getXIncludes() but returns the hierarchical structure # if desired. # function(filename, recursive = TRUE, omitPattern = "\\.(js|html?|txt|R|c)$", namespace = c(xi = "https://www.w3.org/2003/XInclude"), addNames = TRUE, clean = NULL, ignoreTextParse = FALSE) { doc = xmlParse(filename, xinclude = FALSE) #if(filename == "./XPath/xpathApplyFunctionTable.xml") browser() if(missing(namespace)) { ns = xmlNamespaceDefinitions(doc, simplify = TRUE) if("https://www.w3.org/2001/XInclude" %in% ns) namespace = c(xi = "https://www.w3.org/2001/XInclude") } nodes = getNodeSet(doc, "//xi:include[not(ancestor::ignore)]", namespaces = namespace) files = lapply(nodes, xmlGetAttr, "href") nonRecursive = as.logical(sapply(nodes, xmlGetAttr, "parse", "") == "text") # get rid of duplicates. These arise from xpointer includes ofparts of the document. d = duplicated(files) files = files[!d] nodes = nodes[!d] nonRecursive = nonRecursive[!d] if(ignoreTextParse) { files = files[!nonRecursive] nonRecursive = rep(FALSE, length(files)) } files = doClean(files, clean) if(length(omitPattern)) nonRecursive = grepl(omitPattern, unlist(files)) | nonRecursive if(recursive) { ans = files ans[!nonRecursive] = lapply(files[!nonRecursive], function(x) { u = getRelativeURL(x, filename) u = gsub("#.*$", "", u) xmlXIncludes(u, recursive = TRUE, addNames = addNames, clean = clean, ignoreTextParse = ignoreTextParse) }) if(addNames) names(ans) = files if(length(ans) == 0 || ans == "") ans = list() files = ans # for D3 output. See RD3Device on github.com/duncantl/RD3Device. files = lapply(files, function(x) if(is.character(x)) list(name = x) else x) } else files = unlist(files) list(name = doClean(filename, clean), children = files) } doClean = function(txt, clean) { if(!is.null(clean)) { if(is.function(clean)) txt = clean(txt) else if(is.character(clean)) txt = gsub(clean[1], clean[2], txt) } txt } XML/R/applyDOM.R0000644000175100001440000000015213607633666012757 0ustar hornikusersxmlDOMApply <- function(dom, func) { .Call("RS_XML_RecursiveApply", dom, func, NULL, PACKAGE = "XML") } XML/R/hashTree.R0000644000175100001440000002357613607633702013043 0ustar hornikusers# # This is an experiment to see if a simple hash of the values # is faster. # # Basically, we keep the parents, children and nodes # each as hash tables not a list. Otherwise, this resembles # a flat tree # # The notion is that we have a collection of nodes # and a collection of .parents and .children # # Each element in .parents is assigned to the name of the node # whose parent is being stored. The value is the identifier for the # parent node. The top node has no entry in this collection. # # The .children environment maintains a collection of entries # indexed by the identifier of the relevant node. # The value is a character vector containing the identifiers of the # nodes which are children of this node. # xmlHashTree = # # Currently ignore the nodes, parents and children. # function(nodes = list(), parents = character(), children = list(), env = new.env(TRUE, parent = emptyenv())) { # function to generate a new node identifier. Can be given the # proposed name and will then make one up if that conflicts with another # identifier. .count = 0 # ability to be able to refer to this tree itself. # Not used here since the functions don't make use of the tt environment implicitly. # assign(".this", env, env) # We will store the children and parents as regular entries in these hash tables. env$.children = .children = new.env(TRUE) env$.parents = .parents = new.env(TRUE) #XXX we can do without this and make it a regular function # but we need to deal with XMLFlatListTree slightly different. f = function(suggestion = "") { # the check to see if suggestion is a name in env is very expensive. if(suggestion == "" || exists(suggestion, env, inherits = FALSE)) as.character(.count + 1) # can use length(tt) else suggestion } assign(".nodeIdGenerator", f, env) addNode = # This adds each new node. function(node, parent = character(), ..., attrs = NULL, namespace = NULL, namespaceDefinitions = character(), .children = list(...), cdata = FALSE, suppressNamespaceWarning = getOption('suppressXMLNamespaceWarning', FALSE)) { if(is.character(node)) node = xmlNode(node, attrs = attrs, namespace = namespace, namespaceDefinitions = namespaceDefinitions) .kids = .children .children = .this$.children node = asXMLTreeNode(node, .this, className = "XMLHashTreeNode") id = node$id assign(id, node, env) .count <<- .count + 1 # if no parent, if(!inherits(parent, "XMLNode") && (!is.environment(parent) && length(parent) == 0) || identical(parent, "")) return(node) if(inherits(parent, "XMLHashTreeNode")) parent = parent$id if(length(parent)) { assign(id, parent, envir = .parents) if(exists(parent, .children, inherits = FALSE)) tmp = c(get(parent, .children), id) else tmp = id assign(parent, tmp, .children) } return(node) } env$.addNode <- addNode # Create a .nodes vector with the names # of the node. And then makes a # .tidy = function() { idx <- idx - 1 length(nodeSet) <- idx length(nodeNames) <- idx names(nodeSet) <- nodeNames .nodes <<- nodeSet idx } # environment(env$.tidy) <- env .this = structure(env, class = oldClass("XMLHashTree")) .this } # Example of looping over all elements # table(unlist(eapply(tree, xmlName))) getDescendants = # # This is trying to avoid recursion and use iteration. # function(id, tree, kids = tree$.children) { # if no kids, then return empty list if(!exists(id, kids)) return(character()) ans = character() tmp = get(id, kids) hasKids = objects(kids) while( length( tmp ) > 0) { ans = c(ans, tmp) tmp = tmp[ tmp %in% hasKids ] k = get(tmp[1], kids) tmp = c(tmp[-1], k) } ans } getDescendants = # Simple mechanism, for xmlHashTree trees. # This is recursive. function(id, tree, kids = tree$.children) { if(inherits(id, "XMLHashTreeNode")) { if(missing(tree)) tree = id$env id = id$id } if(!exists(id, kids)) return(character()) ans = get(id, kids) c(ans, unlist(lapply(ans, getDescendants, tree, kids))) #Debugging # names(ans) = sapply(ans, function(i) xmlName(get(i, tree))) } subtree = copyXMLHashSubTree = function(node) { # find all the nodes below this node, i.e. in the subtree tree = node$env ids = getDescendants(node$id, tree, tree$.children) newTree = xmlHashTree() # Now copy the parent & children information to the new tree # and also the modified nodes. The only modification necessary # is to set the env field of the original node to the new tree. sapply(c(node$id, ids), function(id) { n = get(id, tree) n$env = newTree assign(id, n, newTree) if(exists(id, tree$.children)) assign(id, get(id, tree$.children), newTree$.children) if(exists(id, tree$.parents)) assign(id, get(id, tree$.parents), newTree$.parents) }) remove(list = node$id, envir = newTree$.parents) newTree } xmlNamespaceDefinitions.XMLAbstractDocument = function(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) { xmlNamespaces(as(x, "XMLAbstractNode")) } setAs("XMLAbstractDocument", "XMLAbstractNode", function(from) xmlRoot(from)) setAs("XMLHashTreeNode", "XMLHashTree", function(from) from$env ) "$.XMLHashTree" = function(x, name) get(name, x, inherits = FALSE) setMethod("xmlParent", "XMLHashTreeNode", # To get the parent of the node 'obj', we have to look in the .parents object # for the variable with obj's node identifier and then get the corresponding # value which is the identifier of the parent. function(x, ...) { p = get(".parents", x$env) idx = exists(x$id, p, inherits = FALSE) if(!idx) return(NULL) get(get(x$id, p), x$env) } ) xmlChildren.XMLHashTreeNode = # # For a given node 'obj', we have to use its id to find the entry # in the .children hash table and then the resulting entry is a character # vector giving the ids of the child nodes of obj. So we have to resolve those # children id's back in the hash table for the actual nodes. function(x, addNames = TRUE, ...) { e = x$env kids = get(".children", e) if(exists(x$id, kids, inherits = FALSE)) { ids = get(x$id, kids, inherits = FALSE) nodes = lapply(ids, get, e, inherits = FALSE) names(nodes) = sapply(nodes, xmlName) nodes } else list() } if(useS4) setMethod("xmlChildren", "XMLHashTreeNode", xmlChildren.XMLHashTreeNode) xmlSize.XMLHashTreeNode = function(obj) { length(xmlChildren(obj)) } xmlSize.XMLHashTree = function(obj) { # 3 is the number of entries with a . prefix that we put there # for our own implementation purposes # We could calculate this as # length(grep("^.", objects(obj, all = TRUE)) length(obj) - 3 } #??? Currently overridden below xmlRoot.XMLHashTree = function(x, skip = TRUE, ...) { id = setdiff(objects(x), objects(x[[".parents"]])) get(id, x) } "[[.XMLHashTreeNode" = function(x, ..., copy = FALSE, exact = TRUE) { # ans = NextMethod("[[") ans = xmlChildren(x)[[...]] if(copy) xmlRoot(subtree(ans)) else ans } addNode = function(node, parent, to, ...) { UseMethod("addNode", to) } addNode.XMLHashTree = function(node, parent = character(), to, ...) { to[[".addNode"]](node, parent, ...) } xmlRoot.XMLHashTree = # # This can return multiple roots # # Find all the identities of the nodes for which there is no # corresponding entry n the .parents # # # If skip is TRUE, discard comment nodes. Leave PI nodes, etc. # # If all is TRUE, return a list() with all the top-level nodes. # function(x, skip = TRUE, all = FALSE, ...) { parents = get(".parents", x, inherits = FALSE) tops = objects(x)[ is.na(match(objects(x), objects(parents)))] if(length(tops) == 0) return(NULL) ans = mget(tops, x) if(skip) ans = ans[!sapply(ans, inherits, c("XMLCommentNode"))] #XXX names of XML hash tree nodes for comment, processing instruction, text node, etc. if(all) return(ans) ans[[1]] } getSibling = # Access the next field in the xmlNodePtr object. # not exported. function(node, after = TRUE, ...) UseMethod("getSibling") getSibling.XMLHashTreeNode = function(node, after = TRUE, ...) { .this = node$env parent = xmlParent(node) if(!is.null(parent)) { kids = xmlChildren(parent) } else kids = xmlRoot(.this, skip = FALSE, all = TRUE) i = match(node$id, sapply(kids, function(x) x$id)) if(is.na(i)) stop("shouldn't happen") if(after) { if(i < length(kids)) kids[[i+1]] else NULL } else { if(i > 1) kids[[i-1]] else NULL } } print.XMLHashTree = function(x, ...) { print(xmlRoot(x), ...) } xmlElementsByTagName.XMLHashTree = # # non-recursive version only at present # function(el, name, recursive = FALSE) { kids = xmlChildren(el) if(!recursive) return(kids [ sapply(kids, xmlName) == name ]) } convertToHashTree = function(from) { xx = xmlHashTree() ans = .Call("R_convertDOMToHashTree", from, xx, xx$.children, xx$.parents, PACKAGE = "XML") docName(xx) = docName(from) xx } setAs("XMLInternalDocument", "XMLHashTree", function(from) { convertToHashTree(xmlRoot(from, skip = FALSE)) }) setAs("XMLInternalNode", "XMLHashTree", function(from) { ans = convertToHashTree(from) docName(ans) <- docName(from) ans }) docName.XMLHashTree = function(doc) { if(exists(".doc", doc)) doc$.doc else as.character(NA) } setMethod("docName", "XMLHashTree", docName.XMLHashTree) XML/R/catalog.R0000644000175100001440000000413213607633665012705 0ustar hornikusersxmlInitializeCatalog = function() .C("R_xmlInitializeCatalog", PACKAGE = "XML") catalogResolve = function(id, type = "uri", asIs = FALSE, debug = FALSE) { xmlInitializeCatalog() type = rep(type, length = length(id)) types = c("uri", "public", "system") i = pmatch(tolower(type), types, duplicates.ok = TRUE) if(any(is.na(i))) stop("don't recognize type. Must be one of ", paste(types, collapse = ", ")) ans = .Call("R_xmlCatalogResolve", as.character(id), i, as.logical(debug), PACKAGE = "XML") if(asIs) ans[is.na(ans)] = id[is.na(ans)] ans } catalogLoad = function(fileNames) { .Call("RS_XML_loadCatalog", path.expand(fileNames), PACKAGE = "XML") } catalogClearTable = function() { .Call("RS_XML_clearCatalog", PACKAGE = "XML") } XMLCatalogTypes = c("public", "system", "rewriteSystem", "rewriteURI", "uri", "delegateSystem", "delegatePublic", "delegateURI", "nextCatalog", "catalog") catalogAdd = function(orig, replace, type = "rewriteURI") { if(missing(replace)) { replace = orig orig = names(replace) } else length(replace) = length(orig) idx = pmatch(type, XMLCatalogTypes) if(any(is.na(idx))) { stop("unrecognized XML catalog type(s) ", type[is.na(idx)], ". Must be one of ", paste("'", XMLCatalogTypes, "'", sep = "", collapse = ", ")) } type = XMLCatalogTypes[idx] type = rep(as.character(type), length = length(orig)) xmlInitializeCatalog() .Call("RS_XML_catalogAdd", as.character(orig), as.character(replace), as.character(type), PACKAGE = "XML") } catalogDump = # # Get a snapshot of the current contents of the global catalog table # parsing it or writing it to a file for further use # If asText = TRUE and you don't specify a value for fileName, # it returns the XML content as a string for easier viewing. function(fileName = tempfile(), asText = TRUE) { xmlInitializeCatalog() ans = .Call("RS_XML_catalogDump", as.character(fileName), PACKAGE = "XML") if(missing(fileName)) { ans = xmlParse(fileName) if(asText) ans = saveXML(ans) unlink(fileName) } ans } XML/R/xmlHandler.R0000644000175100001440000000152213607633674013371 0ustar hornikusersxmlHandler <- function() { data <- list() startElement <- function(name, atts,...) { if(is.null(atts)) atts <- list() data[[name]] <<- atts } text <- function(x,...) { cat("MyText:",x,"\n") } comment <- function(x,...) { cat("comment", x,"\n") } externalEntity <- function(ctxt, baseURI, sysId, publicId,...) { cat("externalEntity", ctxt, baseURI, sysId, publicId,"\n") } entityDeclaration <- function(name, baseURI, sysId, publicId,notation,...) { cat("externalEntity", name, baseURI, sysId, publicId, notation,"\n") } foo <- function(x,attrs,...) { cat("In foo\n")} return(list(startElement=startElement, getData=function() {data}, comment=comment, externalEntity=externalEntity, entityDeclaration=entityDeclaration, text=text, foo=foo)) } XML/R/parseDTD.R0000644000175100001440000000133213607633674012740 0ustar hornikusersparseDTD <- function(extId, asText = FALSE, name = "", isURL = FALSE, error = xmlErrorCumulator()) { extId <- as.character(extId) if(!asText && missing(isURL)) { isURL <- length(grep("(http|ftp)://", extId, useBytes = TRUE)) > 0 } if(missing(name)) name <- extId .oldErrorHandler = setXMLErrorHandler(error) on.exit(.Call("RS_XML_setStructuredErrorHandler", .oldErrorHandler, PACKAGE = "XML"), add = TRUE) if(asText) { f <- gsub("\\", "/", tempfile(), fixed=TRUE) cat(extId, "\n", file = f) extId = f asText = FALSE } .Call("RS_XML_getDTD", as.character(name), as.character(extId), as.logical(asText), as.logical(isURL), error, PACKAGE = "XML") } XML/R/compare.R0000644000175100001440000000151113607633666012720 0ustar hornikusers # For comparing if two XML documents are "similar" whatever that means. # We look at the distribution of node names summary.XMLInternalDocument = function(object, ...) { counts = sort(table(xpathSApply(object, "//*", xmlName, ...)), decreasing = TRUE) list(nameCounts = counts, numNodes = sum(counts)) } compareXMLDocs = function(a, b, ...) { sa = summary(a, ...) sb = summary(b, ...) inAOnly = setdiff(names(sa$nameCounts), names(sb$nameCounts)) inBOnly = setdiff(names(sb$nameCounts), names(sa$nameCounts)) common.ids = intersect(names(sa$nameCounts), names(sb$nameCounts)) # != sb$nameCounts[names(sa$nameCounts) diffs = sa$nameCounts[common.ids] - sb$nameCounts[common.ids] diffs = diffs[diffs != 0] list(inA = sa$nameCounts[inAOnly], inB = sb$nameCounts[inBOnly], countDiffs = diffs) #all.equal(sa, sb) } XML/R/encoding.R0000644000175100001440000000176013607633665013065 0ustar hornikusersCE_NATIVE = 0L CE_UTF8 = 1L CE_LATIN1 = 2L # Map an encoding or document's encoding to the corresponding R internal enum value setGeneric("getEncodingREnum", function(doc, ...) standardGeneric("getEncodingREnum")) setMethod("getEncodingREnum", "XMLInternalDocument", function(doc, ...) getEncodingREnum( getEncoding(doc) )) setMethod("getEncodingREnum", "XMLInternalElementNode", # was XMLInternalElement, but no such class? function(doc, ...) getEncodingREnum( as(doc, "XMLInternalDocument") )) setMethod("getEncodingREnum", "character", function(doc, ...) { if(length(doc) == 0 || is.na(doc)) return(CE_NATIVE) str = tolower(doc) if(any(str == c("utf8", "utf-8"))) CE_UTF8 else if(any(str == c("latin1", "iso-8859-1"))) CE_LATIN1 else CE_NATIVE # or NA? }) XML/cleanup0000755000175100001440000000115314636531034012312 0ustar hornikusers#!/bin/sh # This cleans up after the auxillary files that were created when installing # the XML package. The R INSTALL command takes care of the others. # # This is a slightly modified version of Torsten Hothorn's original contribution # to work using the Bourne shell and for non-GNU versions of test. echo " Cleaning up after installing the XML package" for f in config.log config.status config.cache ; do if test -w $f ; then rm -f $f fi done for f in src/Makevars R/supports.R inst/scripts/RSXML.csh inst/scripts/RSXML.bsh src/Makevars ; do if test -w $f ; then rm -f $f fi done exit 0 XML/src/0000755000175100001440000000000014553462406011530 5ustar hornikusersXML/src/XMLHashTree.c0000644000175100001440000001712314343054535013761 0ustar hornikusers/* This set of functions is designed to map an internal XML DOM tree to an xmlHashTree. An xmlHashTree() is an environment, and so is mutable. It contains the following elements: 1) nodes each with a unique identifier, e.g. 1, 2, 3. which are used to index them in the elements that specify the structure. 2) .children - an environment 3) .parents - an environment 4) top - the root node Functions .addNode and .nodeIdGenerator If we are not going to be adding to this tree, we don't need these functions. As we move through the internal tree, we can construct a node and then the character vector of children for that node and assign it to the .children environment Suppose we have a tree like A / \ B C / | \ D E F | G We start giving the nodes names by number, i.e. 1, 2, 3,.... To create A, we make the node object as a list with name (A), attributes (NULL), namespace (""), [children], id (1) and env. The children are 2 and 3 The parents */ #include #include #include "DocParse.h" #include "Utils.h" static const char * const nodeElementNames[] = { "name", "attributes", "namespace", "children", "id", "env" }; /* Identifier for the node. Could be anything, so we use the pointer address to ensure uniqueness. Ignore the next definition in the comment! #define SET_NODE_NAME(x, id) sprintf(x, "%d", id) */ #define SET_NODE_NAME(x, id, node) snprintf(x, 20, "%p", (void *)node) SEXP makeHashNode(xmlNodePtr node, char *buf, SEXP env, R_XMLSettings *parserSettings) { SEXP ans, names, tmp; int i = 0, numEls = sizeof(nodeElementNames)/sizeof(nodeElementNames[0]); DECL_ENCODING_FROM_NODE(node) int hasValue = node->type == XML_TEXT_NODE || node->type == XML_COMMENT_NODE || node->type == XML_CDATA_SECTION_NODE || node->type == XML_PI_NODE; if(hasValue) numEls++; if(node->nsDef) numEls++; PROTECT(ans = NEW_LIST(numEls)); PROTECT(tmp = mkString(node->name ? XMLCHAR_TO_CHAR(node->name) : "")); if(node->ns) SET_NAMES(tmp, mkString((const char *)node->ns->prefix)); SET_VECTOR_ELT(ans, i++, tmp); UNPROTECT(1); SET_VECTOR_ELT(ans, i++, RS_XML(AttributeList)(node, parserSettings)); SET_VECTOR_ELT(ans, i++, ScalarString(ENC_COPY_TO_USER_STRING(node->ns && node->ns->prefix ? node->ns->prefix: (const xmlChar *)""))); /* skip the children */ i = 4; SET_VECTOR_ELT(ans, i++, mkString(buf)); SET_VECTOR_ELT(ans, i++, env); if(hasValue) SET_VECTOR_ELT(ans, i++, mkString((const char *)node->content)); if(node->nsDef) SET_VECTOR_ELT(ans, i++, processNamespaceDefinitions(node->nsDef, node, parserSettings)); PROTECT(names = NEW_CHARACTER(numEls)); for(i = 0; i < sizeof(nodeElementNames)/sizeof(nodeElementNames[0]); i++) SET_STRING_ELT(names, i, ENC_COPY_TO_USER_STRING(nodeElementNames[i])); if(hasValue) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("value")); if(node->nsDef) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("namespaceDefinitions")); SET_NAMES(ans, names); UNPROTECT(1); /* The class of the node */ PROTECT(names = NEW_CHARACTER( node->type == XML_ELEMENT_NODE ? 2 : 3)); i = 0; SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLHashTreeNode")); if(node->type == XML_TEXT_NODE) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLTextNode")); else if(node->type == XML_COMMENT_NODE) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLCommentNode")); else if(node->type == XML_CDATA_SECTION_NODE) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLCDataNode")); else if(node->type == XML_PI_NODE) SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLPINode")); SET_STRING_ELT(names, i++, COPY_TO_USER_STRING("XMLNode")); SET_CLASS(ans, names); UNPROTECT(2); return(ans); } unsigned int countChildNodes(xmlNodePtr root, unsigned int *ctr) { xmlNodePtr node; for(node = root->children; node; node = node->next) { if(node->type == XML_XINCLUDE_START) countChildNodes(node, ctr); else if(node->type != XML_XINCLUDE_END) (*ctr)++; } return(*ctr); } void collectChildNodes(xmlNodePtr root, unsigned int *ctr, SEXP kids) { xmlNodePtr node; for(node = root->children; node; node = node->next) { if(node->type == XML_XINCLUDE_END) continue; if(node->type == XML_XINCLUDE_START) collectChildNodes(node, ctr, kids); else { char buf[20]; SET_NODE_NAME(buf, *ctr + 1, node); SET_STRING_ELT(kids, *ctr, mkChar(buf)); (*ctr)++; } } } /* This is the recursive function that process a node and then its children. It builds the node (via makeHashNode) and then adds an entry for the children and parent These provide the structure for the tree. */ void processNode(xmlNodePtr root, xmlNodePtr parent, unsigned int *ctr, int parentId, char *id, SEXP env, SEXP childrenEnv, SEXP parentEnv, R_XMLSettings *parserSettings) { // int i; xmlNodePtr node; SEXP rnode, kids; unsigned int curId = *ctr; char buf[20]; SET_NODE_NAME(id, curId, root); if(root->type != XML_XINCLUDE_START && root->type != XML_XINCLUDE_END) { rnode = PROTECT(makeHashNode(root, id, env, parserSettings)); defineVar(Rf_install(id), rnode, env); UNPROTECT(1); if(root->parent && root->parent->type != XML_DOCUMENT_NODE && root->parent->type != XML_HTML_DOCUMENT_NODE) { /* Put an entry in the .parents environment for this current id with the single value which is the value of the parentId as a string, equivalent of assign(curId, parentId, parentEnv) */ SET_NODE_NAME(id, curId, root); SET_NODE_NAME(buf, parentId, parent); defineVar(Rf_install(id), PROTECT(mkString(buf)), parentEnv); UNPROTECT(1); } if(root->children) { /* We have to deal with */ unsigned int i = 0; countChildNodes(root, &i); PROTECT(kids = NEW_CHARACTER(i)); i = 0; collectChildNodes(root, &i, kids); defineVar(Rf_install(id), kids, childrenEnv); UNPROTECT(1); } (*ctr)++; } if(root->type != XML_XINCLUDE_END) { /* Discard XML_INCLUDE_END nodes, but for XML_INCLUDE_START, we need to specify a different parent, i.e., the parent of the XML_INCLUDE_START node so that it will act as the parent of the included nodes. */ xmlNodePtr parent; parent = root->type == XML_XINCLUDE_START ? root->parent : root; for(node = root->children; node; node = node->next) processNode(node, parent, ctr, curId, id, env, childrenEnv, parentEnv, parserSettings); } } /* This is the top-level C entry point for starting the conversion of the node. */ unsigned int convertDOMToHashTree(xmlNodePtr root, SEXP env, SEXP childrenEnv, SEXP parentEnv, R_XMLSettings *parserSettings) { // SEXP rnode; unsigned int ctr = 0; xmlNodePtr tmp; char id[20]; memset(id, '\0', sizeof(id)); for(tmp = root; tmp; tmp = tmp->next) processNode(tmp, (xmlNodePtr) NULL, &ctr, -1, id, env, childrenEnv, parentEnv, parserSettings); return(ctr); } /* This is the R entry point for the conversion of the node and its subnode. */ SEXP R_convertDOMToHashTree(SEXP rnode, SEXP env, SEXP childrenEnv, SEXP parentEnv) { unsigned int ctr; xmlNodePtr node; R_XMLSettings parserSettings; parserSettings.addAttributeNamespaces = 0; parserSettings.converters = NULL_USER_OBJECT; node = (xmlNodePtr) R_ExternalPtrAddr(rnode); ctr = convertDOMToHashTree(node, env, childrenEnv, parentEnv, &parserSettings); return(ScalarInteger(ctr)); } XML/src/RSDTD.c0000644000175100001440000005550014106741723012555 0ustar hornikusers/** This file defines the top-level entry routine called from R and S to parse and convert a DTD into a user-level object. Most of the routines are support routines. We leave them as global symbols (as opposed to static) so that others might be able to utilize them. Some are called from the other files (DocParse, specifically). * See Copyright for the license status of this software. */ #include "RSDTD.h" #ifdef USE_S extern char *strdup(const char *); #endif #include "Utils.h" /* for SET_CLASS_NAME */ #include /* For reading DTDs directly from text, not files. Copied directly from parser.c in the libxml(-1.7.3) library. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif #define INPUT_CHUNK 250 #define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur)) #ifdef OLD_SKIP_BLANKS #define SKIP_BLANKS \ do { \ while (IS_BLANK(CUR)) NEXT; \ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); \ } while (IS_BLANK(CUR)); #define NEXT { \ if (ctxt->token != 0) ctxt->token = 0; \ else { \ if ((*ctxt->input->cur == 0) && \ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) { \ xmlPopInput(ctxt); \ } else { \ if (*(ctxt->input->cur) == '\n') { \ ctxt->input->line++; ctxt->input->col = 1; \ } else ctxt->input->col++; \ ctxt->input->cur++; \ if (*ctxt->input->cur == 0) \ xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \ } \ if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt); \ }} #else #define SKIP_BLANKS xmlSkipBlankChars(ctxt) #define NEXT xmlNextChar(ctxt) #endif /* end temporary. */ /* Macro that sets the name of an enumerated value by indexing into an array of names based on the value being represented. */ #define SET_ENUM_NAME(names, which, obj) RS_XML_SetNames(1, RS_XML_##names+which-1,obj); enum {DTD_ELEMENTS_SLOT, DTD_ENTITIES_SLOT, DTD_NUM_SLOTS}; const char *RS_XML(DtdNames)[] = {"elements", "entities"}; /** Top-level entry point for reading the DTD. dtdFileName - name of the DTD. externalId - file identfying the DTD from which its contents are read. */ USER_OBJECT_ RS_XML(getDTD)(USER_OBJECT_ dtdFileName, USER_OBJECT_ externalId, USER_OBJECT_ asText, USER_OBJECT_ isURL, USER_OBJECT_ errorFun) { USER_OBJECT_ ans; const char * dtdName = strdup(CHAR_DEREF(STRING_ELT(dtdFileName, 0))); const char * extId = strdup(CHAR_DEREF(STRING_ELT(externalId, 0))); int localAsText = LOGICAL_DATA(asText)[0]; xmlParserCtxtPtr ctxt; xmlDtdPtr dtd; if(localAsText) { ctxt = xmlCreateDocParserCtxt((xmlChar*) extId); } else { if(LOGICAL_DATA(isURL)[0] == 0) { struct stat tmp_stat; if(extId == NULL || stat(extId, &tmp_stat) < 0) { Rf_error("Can't find file %s", extId); } } ctxt = xmlCreateFileParserCtxt(extId); /* from parser.c xmlSAXParseFile */ } if(ctxt == NULL) { Rf_error("error creating XML parser for `%s'", extId); } ctxt->validate = 1; #ifdef RS_XML_SET_STRUCTURED_ERROR /* Done in R code now. */ xmlSetStructuredErrorFunc(errorFun == NULL_USER_OBJECT ? NULL : errorFun, R_xmlStructuredErrorHandler); #endif if(ctxt->myDoc == NULL) ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0"); if(localAsText) { xmlCreateIntSubset(ctxt->myDoc, CHAR_TO_XMLCHAR(dtdName), NULL, NULL); while(ctxt->input->cur && ctxt->input->cur[0]) { SKIP_BLANKS; xmlParseMarkupDecl(ctxt); } dtd = ctxt->myDoc->intSubset; } else { /* Read the file. */ /* Added for 2.2.12. May need to be conditional for 1.8.9 */ ctxt->sax->internalSubset(ctxt->userData, CHAR_TO_XMLCHAR(dtdName), CHAR_TO_XMLCHAR(extId), CHAR_TO_XMLCHAR(extId)); /* Warnings will ensue about not being in internal subset if we don't go to level 2. */ #ifdef USE_EXTERNAL_SUBSET ctxt->inSubset = 2; ctxt->sax->externalSubset(ctxt->userData, CHAR_TO_XMLCHAR(dtdName), CHAR_TO_XMLCHAR(extId), CHAR_TO_XMLCHAR(extId)); ctxt->inSubset = 0; #endif dtd = ctxt->myDoc->extSubset; } #ifdef RS_XML_SET_STRUCTURED_ERROR xmlSetStructuredErrorFunc(NULL, NULL); #endif if(dtd == NULL) { if(errorFun != NULL_USER_OBJECT) { RSXML_structuredStop(errorFun, NULL); } else return(stop("DTDParseError", "error parsing %s", dtdName)); Rf_error("error in DTD %s", extId); } if(localAsText) { /* Don't bother with the internal and external split, just do the internal and return it. */ ans = RS_XML(createDTDParts)(dtd, ctxt); } else ans = RS_XML(ConstructDTDList)(ctxt->myDoc, 0, ctxt); return(ans); } const char *RS_XML(DtdTypeNames)[] = {"external", "internal"}; /** Create the representation of the DTD contained in the Document pointer, using both the internal and external descriptions and returning a list of the appropriate length. If the external description is empty, then we just return the description of the internal description. Otherwise, we return a named list of length 2 containing descriptions of both. */ USER_OBJECT_ RS_XML(ConstructDTDList)(xmlDocPtr myDoc, int processInternals, xmlParserCtxtPtr ctxt) { USER_OBJECT_ ans, el, klass; int i; xmlDtdPtr sets[2]; int num = processInternals ? 2 : 1; sets[0] = myDoc->extSubset; if(processInternals) { sets[1] = myDoc->intSubset; } PROTECT(ans = NEW_LIST(num)); for(i = 0; i < num; i++) { if(sets[i]) { SET_VECTOR_ELT(ans, i, el= RS_XML(createDTDParts)(sets[i], ctxt)); PROTECT(klass = NEW_CHARACTER(1)); SET_STRING_ELT(klass, 0, mkChar(i==0 ? "ExternalDTD" : "InternalDTD")); SET_CLASS(el, klass); UNPROTECT(1); } } RS_XML(SetNames)(num, RS_XML(DtdTypeNames), ans); UNPROTECT(1); return(processInternals ? ans : VECTOR_ELT(ans, 0)); } /** Process the entities and elements of the DTD, returning a list of length 2, irrespective if either is empty. */ USER_OBJECT_ RS_XML(createDTDParts)(xmlDtdPtr dtd, xmlParserCtxtPtr ctxt) { xmlEntitiesTablePtr entities; xmlElementTable *table; USER_OBJECT_ ans; PROTECT(ans = NEW_LIST(DTD_NUM_SLOTS)); table = (xmlElementTable*) dtd->elements; if(table) SET_VECTOR_ELT(ans, DTD_ELEMENTS_SLOT, RS_XML(ProcessElements)(table, ctxt)); entities = (xmlEntitiesTablePtr) dtd->entities; if(entities) SET_VECTOR_ELT(ans, DTD_ENTITIES_SLOT, RS_XML(ProcessEntities)(entities, ctxt)); RS_XML(SetNames)(DTD_NUM_SLOTS, RS_XML(DtdNames), ans); UNPROTECT(1); return(ans); } #ifdef LIBXML2 struct ElementTableScanner { USER_OBJECT_ dtdEls; USER_OBJECT_ dtdNames; int counter; }; #if LIBXML_VERSION >= 20908 # define CONST const #else # define CONST #endif #ifndef NO_XML_HASH_SCANNER_RETURN void *RS_xmlElementTableConverter(void *payload, void *data, CONST xmlChar *name); void* RS_xmlEntityTableConverter(void *payload, void *data, CONST xmlChar *name); #else void RS_xmlElementTableConverter(void *payload, void *data, CONST xmlChar *name); void RS_xmlEntityTableConverter(void *payload, void *data, CONST xmlChar *name); #endif #endif /** Convert the elements into a named list of objects with each element representing an element. */ USER_OBJECT_ RS_XML(ProcessElements)(xmlElementTablePtr table, xmlParserCtxtPtr ctxt) { USER_OBJECT_ dtdEls = NULL_USER_OBJECT; int n; #ifdef LIBXML2 n = xmlHashSize(table); #else int i; xmlElementPtr xmlEl; n = table->nb_elements; #endif if(n > 0) { USER_OBJECT_ dtdNames = NULL_USER_OBJECT; PROTECT_INDEX ipx; PROTECT_WITH_INDEX(dtdEls = NEW_LIST(n), &ipx); PROTECT(dtdNames = NEW_CHARACTER(n)); #ifdef LIBXML2 { struct ElementTableScanner scanData; scanData.dtdEls = dtdEls; scanData.dtdNames = dtdNames; scanData.counter = 0; xmlHashScan(table, RS_xmlElementTableConverter, &scanData); SET_LENGTH(dtdEls, scanData.counter); REPROTECT(dtdEls, ipx); SET_LENGTH(dtdNames, scanData.counter); } #else for(i = 0; i < n; i++) { xmlEl = table->table[i]; SET_VECTOR_ELT(dtdEls, i, RS_XML(createDTDElement)(xmlEl)); SET_STRING_ELT(dtdNames , i, COPY_TO_USER_STRING(xmlEl->name)); } #endif SET_NAMES(dtdEls, dtdNames); UNPROTECT(2); } return(dtdEls); } #ifdef LIBXML2 /* libxml2 2.4.21 (and perhaps earlier) redefines this to have a return type of void, rather than void*. Need to figure out if this makes any real difference to the interface and also when to */ #ifndef NO_XML_HASH_SCANNER_RETURN void* #else void #endif RS_xmlElementTableConverter(void *payload, void *data, CONST xmlChar *name) { struct ElementTableScanner *scanData = (struct ElementTableScanner *)data; SET_VECTOR_ELT(scanData->dtdEls, scanData->counter, RS_XML(createDTDElement)( payload)); SET_STRING_ELT(scanData->dtdNames, scanData->counter, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(name))); scanData->counter++; #ifndef NO_XML_HASH_SCANNER_RETURN return(payload); #endif } #endif /** Process the list of entities and convert them into a named list containing entity descriptions. */ USER_OBJECT_ RS_XML(ProcessEntities)(xmlEntitiesTablePtr table, xmlParserCtxtPtr ctxt) { USER_OBJECT_ dtdEls = NULL_USER_OBJECT; int n; #ifdef LIBXML2 n = xmlHashSize(table); #else xmlEntity *xmlEl; int i; n = table->nb_entities; #endif if(n > 0) { USER_OBJECT_ dtdNames; PROTECT_INDEX ipx; PROTECT_WITH_INDEX(dtdEls = NEW_LIST(n), &ipx); PROTECT(dtdNames = NEW_CHARACTER(n)); #ifdef LIBXML2 { struct ElementTableScanner scanData; scanData.dtdEls = dtdEls; scanData.dtdNames = dtdNames; scanData.counter = 0; xmlHashScan(table, RS_xmlEntityTableConverter, &scanData); /* Reset the length to be the actual number rather than the capacity of the table. See ProcessElements also. */ SET_LENGTH(dtdEls, scanData.counter); REPROTECT(dtdEls, ipx); SET_LENGTH(dtdNames, scanData.counter); } #else for(i = 0; i < n; i++) { xmlEl = table->table +i; SET_VECTOR_ELT(dtdEls, i, RS_XML(createDTDEntity)(xmlEl)); SET_STRING_ELT(dtdNames, i, COPY_TO_USER_STRING(xmlEl->name)); } #endif SET_NAMES(dtdEls, dtdNames); UNPROTECT(2); } return(dtdEls); } #ifdef LIBXML2 #ifndef NO_XML_HASH_SCANNER_RETURN void* #else void #endif RS_xmlEntityTableConverter(void *payload, void *data, CONST xmlChar *name) { struct ElementTableScanner *scanData = (struct ElementTableScanner *)data; SET_VECTOR_ELT(scanData->dtdEls, scanData->counter, RS_XML(createDTDEntity)( payload)); SET_STRING_ELT(scanData->dtdNames, scanData->counter, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(name))); scanData->counter++; #ifndef NO_XML_HASH_SCANNER_RETURN return(payload); #endif } #endif /* End of LIBXML2 for definint RS_xmlEntityTableConverter */ /** Convert an entity definition into a user-level object, handling both internal and system entities. We could have different slots for the two types of entities, but that may make it harder to program. S3/R classes aren't exactly good with inheritance of slots. */ /** Indices for the slots of the user-level list representing the entity. */ enum { DTD_ENTITY_NAME_SLOT, DTD_ENTITY_CONTENT_SLOT, DTD_ENTITY_ORIG_SLOT, DTD_ENTITY_NUM_SLOTS}; /* Names for the slots of the user-level list representing the entity. */ const char *RS_XML(EntityNames)[] = {"name", "value", "original"}; USER_OBJECT_ RS_XML(createDTDEntity)(xmlEntityPtr entity) { USER_OBJECT_ ans; const xmlChar *value; const char *localClassName; PROTECT(ans = NEW_LIST(DTD_ENTITY_NUM_SLOTS)); SET_VECTOR_ELT(ans, DTD_ENTITY_NAME_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_ENTITY_NAME_SLOT), 0, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(entity->name))); if(entity->content == NULL) { value = entity->SystemID; localClassName = "XMLSystemEntity"; } else { value = entity->content; localClassName = "XMLEntity"; } SET_VECTOR_ELT(ans, DTD_ENTITY_CONTENT_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_ENTITY_CONTENT_SLOT), 0, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(value))); if(entity->orig) { SET_VECTOR_ELT(ans, DTD_ENTITY_ORIG_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_ENTITY_ORIG_SLOT), 0, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(entity->orig))); } RS_XML(SetNames)(DTD_ENTITY_NUM_SLOTS, RS_XML(EntityNames), ans); /* Set the class of the specified object based on whether it is a internal or external entity. */ SET_CLASS_NAME(localClassName, ans); UNPROTECT(1); return(ans); } enum { DTD_ELEMENT_NAME_SLOT, DTD_ELEMENT_TYPE_SLOT, DTD_ELEMENT_CONTENT_SLOT, DTD_ELEMENT_ATTRIBUTES_SLOT, DTD_ELEMENT_NUM_SLOTS}; const char *RS_XML(ElementNames)[] = {"name", "type", "contents","attributes"}; const char *RS_XML(ElementTypeNames)[] = {"empty", "any", "mixed","element"}; /** Creates the user-level object representing the definition of an element within a DTD, including its attribute definitions, its type, name and finally contents. This is an object of class XMLElementDef. */ USER_OBJECT_ RS_XML(createDTDElement)(xmlElementPtr el) { USER_OBJECT_ rel; int type; #ifdef XML_ELEMENT_ETYPE type = el->etype; #else type = el->type; #endif PROTECT(rel = NEW_LIST(DTD_ELEMENT_NUM_SLOTS)); SET_VECTOR_ELT(rel, DTD_ELEMENT_NAME_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(rel, DTD_ELEMENT_NAME_SLOT), 0, COPY_TO_USER_STRING( XMLCHAR_TO_CHAR( ( el->name ? el->name : (xmlChar*)"")))); SET_VECTOR_ELT(rel, DTD_ELEMENT_TYPE_SLOT, NEW_INTEGER(1)); INTEGER_DATA(VECTOR_ELT(rel, DTD_ELEMENT_TYPE_SLOT))[0] = el->type; SET_ENUM_NAME(ElementTypeNames, type, VECTOR_ELT(rel, DTD_ELEMENT_TYPE_SLOT)); if(el->content != NULL) SET_VECTOR_ELT(rel, DTD_ELEMENT_CONTENT_SLOT, RS_XML(createDTDElementContents)(el->content, el, 1)); SET_VECTOR_ELT(rel, DTD_ELEMENT_ATTRIBUTES_SLOT, RS_XML(createDTDElementAttributes)(el->attributes, el)); RS_XML(SetNames)(DTD_ELEMENT_NUM_SLOTS, RS_XML(ElementNames), rel); SET_CLASS_NAME("XMLElementDef", rel); UNPROTECT(1); return(rel); } /* Indices for the slots/elements in the list. */ enum {DTD_CONTENT_TYPE_SLOT, DTD_CONTENT_OCCURANCE_SLOT, DTD_CONTENT_ELEMENTS_SLOT, DTD_CONTENT_NUM_SLOTS}; /* names for the elements */ const char *RS_XML(ContentNames)[] = {"type", "ocur", "elements"}; /* Names for the enumerated types of the entries in the data */ const char *RS_XML(ContentTypeNames)[] = {"PCData", "Element", "Sequence","Or"}; const char *RS_XML(OccuranceNames)[] = {"Once", "Zero or One", "Mult","One or More"}; /** Create an object representing the DTD element. The returned value is a list with 3 elements. The names are given by the array ContentNames above. The type and ocur elements are simple named integers identifying that the element is simple parsed character data, an element or a composite element which is either an one of several possible types (that is an OR or |) or an ordered sequence of types. The ocur field indicates whether this element is to be expected in this position exactly once (default qualifier), zero or one (i.e. optional) (?) , any number of times (including omitted) (*) and finally , at least once, but possible more(+) The recursive argument allows the RS_XML(SequenceContent) routine to use part of this routine. */ USER_OBJECT_ RS_XML(createDTDElementContents)(xmlElementContentPtr vals, xmlElementPtr el, int recursive) { char *localClassName = NULL; int num = 0; USER_OBJECT_ ans = NULL_USER_OBJECT; PROTECT(ans = NEW_LIST(DTD_CONTENT_NUM_SLOTS)); SET_VECTOR_ELT(ans, DTD_CONTENT_TYPE_SLOT, NEW_INTEGER(1)); INTEGER_DATA(VECTOR_ELT(ans, DTD_CONTENT_TYPE_SLOT))[0] = vals->type; SET_ENUM_NAME(ContentTypeNames, vals->type, VECTOR_ELT(ans, DTD_CONTENT_TYPE_SLOT)); SET_VECTOR_ELT(ans, DTD_CONTENT_OCCURANCE_SLOT, NEW_INTEGER(1)); INTEGER_DATA(VECTOR_ELT(ans, DTD_CONTENT_OCCURANCE_SLOT))[0] = vals->ocur; SET_ENUM_NAME(OccuranceNames, vals->ocur, VECTOR_ELT(ans, DTD_CONTENT_OCCURANCE_SLOT)); if(vals->type == XML_ELEMENT_CONTENT_SEQ && recursive) { SET_VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT, RS_XML(SequenceContent)(vals, el)); } else { num += (vals->c1 != NULL); if(recursive || 1) num += (vals->c2 != NULL); if(num > 0) { SET_VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT, NEW_LIST(num)); num = 0; if(vals->c1) { SET_VECTOR_ELT(VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT), num++, RS_XML(createDTDElementContents)(vals->c1, el, 1)); } if(recursive || 1) { if(vals->c2) { SET_VECTOR_ELT(VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT), num++, RS_XML(createDTDElementContents)(vals->c2, el, 1)); } } } else { if(vals->name) { SET_VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_CONTENT_ELEMENTS_SLOT), 0, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(vals->name))); } } } switch(vals->type) { case XML_ELEMENT_CONTENT_SEQ: localClassName = "XMLSequenceContent"; break; case XML_ELEMENT_CONTENT_OR: localClassName = "XMLOrContent"; break; default: localClassName = "XMLElementContent"; } if(localClassName) { SET_CLASS_NAME(localClassName, ans); } RS_XML(SetNames)(DTD_CONTENT_NUM_SLOTS, RS_XML(ContentNames), ans); UNPROTECT(1); return(ans); } /** Process the DTD element, knowing that it is a sequence definition. Compute the number of elements in the sequence by flattening out the lob-sided tree and then convert the each element and append it to the list. */ USER_OBJECT_ RS_XML(SequenceContent)(xmlElementContentPtr vals, xmlElementPtr el) { xmlElementContentPtr ptr = vals->c2; int ok = 1, n=1, deep = 0; USER_OBJECT_ ans = NULL_USER_OBJECT; USER_OBJECT_ tmp; /* Count the number of elements in this sequence. Descend all the c2's below this one. */ while(ptr && ok) { ok = (ptr->type == XML_ELEMENT_CONTENT_SEQ); ptr = ptr->c2; n++; } /* Now build the list and the elements within it.*/ PROTECT(ans = NEW_LIST(n)); SET_VECTOR_ELT(ans, 0, RS_XML(createDTDElementContents)(vals->c1, el, 1)); ptr = vals->c2; n = 1; do { /* Some jumping around here beacuse of the recursion and split types. Should be cleaner. */ deep = (ptr->c1 != NULL && ptr->type == XML_ELEMENT_CONTENT_SEQ ); tmp = RS_XML(createDTDElementContents)( deep ? ptr->c1 : ptr, el, deep); SET_VECTOR_ELT(ans, n, tmp); ok = (ptr->type == XML_ELEMENT_CONTENT_SEQ); ptr = ptr->c2; n++; } while(ptr && ok); UNPROTECT(1); return(ans); } /** Routine that creates a named list of XMLAttributeDef objects from a collection of attribute definitions associated with the specified XML element definition. */ USER_OBJECT_ RS_XML(createDTDElementAttributes)(xmlAttributePtr vals, xmlElementPtr el) { USER_OBJECT_ ans = NULL_USER_OBJECT; USER_OBJECT_ names; xmlAttributePtr tmp = vals; int n = 0, i; while(tmp) { #ifdef LIBXML2 tmp = tmp->nexth; #else tmp = tmp->next; #endif n++; } if(n > 0) { tmp = vals; PROTECT(ans = NEW_LIST(n)); PROTECT(names = NEW_CHARACTER(n)); for(i=0; i < n; i++) { SET_VECTOR_ELT(ans, i, RS_XML(createDTDAttribute)(tmp, el)); SET_STRING_ELT(names, i, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(tmp->name))); #ifdef LIBXML2 tmp = tmp->nexth; #else tmp = tmp->next; #endif } SET_NAMES(ans, names); UNPROTECT(2); } return(ans); } enum {DTD_ATTRIBUTE_NAME_SLOT, DTD_ATTRIBUTE_TYPE_SLOT, DTD_ATTRIBUTE_DEFAULT_SLOT, DTD_ATTRIBUTE_DEFAULT_VALUE_SLOT, DTD_ATTRIBUTE_NUM_SLOTS}; /* Names for the possible types of an attribute. */ const char *RS_XML(AttributeTypeNames) [] = {"CDATA","Id", "IDRef", "IDRefs", "Entity","Entities", "NMToken", "NMTokens", "Enumeration", "Notation"}; /* Names for the possible modes or default types of an attribute. */ const char *RS_XML(AttributeDefaultNames)[] = {"None", "Required", "Implied", "Fixed"}; /* Names of the elements within the returned list */ const char *RS_XML(AttributeSlotNames)[] = {"name", "type", "defaultType", "defaultValue"}; /** Create a user-level version of a DTD attribute within an Attribute list within the DTD. Return a vector of length 4 with elements named Name, Type, Default Type and Default Value. The first is a simple string (character vector of length 1). The next two are enumerated types describing the type of the attribute value and whether it is required, fixed, implied, etc. The final value is the default value */ USER_OBJECT_ RS_XML(createDTDAttribute)(xmlAttributePtr val, xmlElementPtr el) { USER_OBJECT_ ans; int attrType; #ifdef XML_ATTRIBUTE_ATYPE attrType = val->atype; #else attrType = val->type; #endif PROTECT(ans = NEW_LIST(DTD_ATTRIBUTE_NUM_SLOTS)); SET_VECTOR_ELT(ans, DTD_ATTRIBUTE_NAME_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_ATTRIBUTE_NAME_SLOT), 0, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(val->name))); SET_VECTOR_ELT(ans, DTD_ATTRIBUTE_TYPE_SLOT, NEW_INTEGER(1)); INTEGER_DATA(VECTOR_ELT(ans, DTD_ATTRIBUTE_TYPE_SLOT))[0] = val->type; SET_ENUM_NAME(AttributeTypeNames, attrType, VECTOR_ELT(ans, DTD_ATTRIBUTE_TYPE_SLOT)); SET_VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_SLOT, NEW_INTEGER(1)); INTEGER_DATA(VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_SLOT))[0] = val->def; SET_ENUM_NAME(AttributeDefaultNames, val->def, VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_SLOT)); if(val->type == (xmlElementType)XML_ATTRIBUTE_ENUMERATION) { SET_VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_VALUE_SLOT, RS_XML(AttributeEnumerationList)(val->tree, val, el)); } else { SET_VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_VALUE_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, DTD_ATTRIBUTE_DEFAULT_VALUE_SLOT), 0, COPY_TO_USER_STRING( XMLCHAR_TO_CHAR( (val->defaultValue ? val->defaultValue : (xmlChar*)"")))); } RS_XML(SetNames)(DTD_ATTRIBUTE_NUM_SLOTS, RS_XML(AttributeSlotNames), ans); SET_CLASS_NAME("XMLAttributeDef", ans); UNPROTECT(1); return(ans); } /** Return a character vector containing the elements listed in the enumeration of possible values in the attribute. These arise in DTD entries such as */ USER_OBJECT_ RS_XML(AttributeEnumerationList)(xmlEnumerationPtr list, xmlAttributePtr attr, xmlElementPtr element) { USER_OBJECT_ ans = NULL_USER_OBJECT; xmlEnumerationPtr tmp = list; int n = 0; /* Count the number of entries in the list/table. */ while(tmp) { n++; tmp = tmp->next; } /* Now convert each entry and add it to a list. */ if(n > 0) { int i; PROTECT(ans = NEW_CHARACTER(n)); tmp = list; for(i = 0; i < n; i++) { SET_STRING_ELT(ans, i, COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(tmp->name))); tmp = tmp->next; } UNPROTECT(1); } return(ans); } XML/src/Utils.h0000644000175100001440000002661014316271033012775 0ustar hornikusers/* * See Copyright for the license status of this software. */ #ifndef UTILS_H #define UTILS_H #include "RS_XML.h" #include "RSCommon.h" #define XMLCHAR_TO_CHAR(val) ((char *) val) #define CHAR_TO_XMLCHAR(val) ((xmlChar *) val) int isBlank(const char *str); char *trim(char *str); #include /* name of the R class identifying a function that wants the xmlParserCtxt as the first argument. */ #define XML_PARSE_CONTEXT_FUNCTION "XMLParserContextFunction" #define XML_PARSER_CONTEXT_TYPE_NAME "XMLParserContext" USER_OBJECT_ RS_XML(invokeFunction)(USER_OBJECT_ fun, USER_OBJECT_ opArgs, USER_OBJECT_ state, xmlParserCtxtPtr ctx); USER_OBJECT_ RS_XML(findFunction)(const char *opName, USER_OBJECT_ functions); void RS_XML(SetNames)(int n, const char *cnames[], USER_OBJECT_ ans); int RS_XML(SetClassName)(const char *name, USER_OBJECT_ target); SEXP R_makeRefObject(void *ref, const char *className); #ifndef SET_CLASS_NAME #define SET_CLASS_NAME(localClassName, target) RS_XML(SetClassName)((localClassName), (target)) #endif #ifdef LIBXML2 #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int xmlHashSize(xmlHashTablePtr table); #endif void RSXML_setErrorHandlers(void); USER_OBJECT_ RS_XML(RecursiveApply)(USER_OBJECT_ top, USER_OBJECT_ func, USER_OBJECT_ klasses); USER_OBJECT_ RS_XML(HtmlParseTree)(USER_OBJECT_ fileName, USER_OBJECT_ converterFunctions, USER_OBJECT_ skipBlankLines, USER_OBJECT_ replaceEntities, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ isURL); USER_OBJECT_ RS_XML(getDTD)(USER_OBJECT_ dtdFileName, USER_OBJECT_ externalId, USER_OBJECT_ asText, USER_OBJECT_ isURL, USER_OBJECT_ errorFun); USER_OBJECT_ RS_XML(libxmlVersion)(void); USER_OBJECT_ RS_XML(Parse)(USER_OBJECT_ fileName, USER_OBJECT_ handlers, USER_OBJECT_ endElementHandlers, USER_OBJECT_ addContext, USER_OBJECT_ ignoreBlanks, USER_OBJECT_ useTagName, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ useExpat, USER_OBJECT_ stateObject, USER_OBJECT_ replaceEntities, USER_OBJECT_ validate, USER_OBJECT_ saxVersion, USER_OBJECT_ branches, USER_OBJECT_ useDotNames, USER_OBJECT_ errorFun, USER_OBJECT_ manageMemory, USER_OBJECT_ r_encoding); /* USER_OBJECT_ RS_XML(Parse)(USER_OBJECT_ fileName, USER_OBJECT_ handlers, USER_OBJECT_ addContext, USER_OBJECT_ ignoreBlanks, USER_OBJECT_ useTagName, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ useExpat, USER_OBJECT_ stateObject, USER_OBJECT_ replaceEntities, USER_OBJECT_ validate); */ USER_OBJECT_ RS_XML(ParseTree)(USER_OBJECT_ fileName, USER_OBJECT_ converterFunctions, USER_OBJECT_ skipBlankLines, USER_OBJECT_ replaceEntities, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ validate, USER_OBJECT_ getDTD, USER_OBJECT_ isURL, USER_OBJECT_ addNamespaceAttributes, USER_OBJECT_ useInternalNodes, USER_OBJECT_ s_useHTML, USER_OBJECT_ isSchema, USER_OBJECT_ fullNamespaceInfo, USER_OBJECT_ r_encoding, USER_OBJECT_ useDotNames, USER_OBJECT_ xinclude, USER_OBJECT_ errorFun, USER_OBJECT_ manageMemory, USER_OBJECT_ r_parserOptions, USER_OBJECT_ r_rootFirst); USER_OBJECT_ R_newXMLDtd(USER_OBJECT_ sdoc, USER_OBJECT_ sname, USER_OBJECT_ sexternalID, USER_OBJECT_ ssysID, USER_OBJECT_ manageMemory); USER_OBJECT_ R_newXMLDoc(USER_OBJECT_ dtd, USER_OBJECT_ namespaces, USER_OBJECT_ isHTML); USER_OBJECT_ R_newXMLNode(USER_OBJECT_ name, USER_OBJECT_ attrs, USER_OBJECT_ nameSpace, USER_OBJECT_ sdoc, USER_OBJECT_ namespaceDefinitions, USER_OBJECT_ manageMemory); USER_OBJECT_ R_newXMLTextNode(USER_OBJECT_ value, USER_OBJECT_ sdoc, USER_OBJECT_ manageMemory); USER_OBJECT_ R_xmlNewComment(USER_OBJECT_ str, USER_OBJECT_ sdoc, USER_OBJECT_ manageMemory); USER_OBJECT_ R_newXMLCDataNode(USER_OBJECT_ sdoc, USER_OBJECT_ value, USER_OBJECT_ manageMemory); USER_OBJECT_ R_newXMLPINode(USER_OBJECT_ sdoc, USER_OBJECT_ name, USER_OBJECT_ content, USER_OBJECT_ manageMemory); USER_OBJECT_ R_xmlNewNs(USER_OBJECT_ sdoc, USER_OBJECT_ shref, USER_OBJECT_ sprefix); USER_OBJECT_ R_xmlSetNs(USER_OBJECT_ s_node, USER_OBJECT_ s_ns, USER_OBJECT_ append); USER_OBJECT_ R_insertXMLNode(USER_OBJECT_ node, USER_OBJECT_ parent, USER_OBJECT_ r_at, USER_OBJECT_ shallow) ; USER_OBJECT_ R_saveXMLDOM(USER_OBJECT_ sdoc, USER_OBJECT_ sfileName, USER_OBJECT_ compression, USER_OBJECT_ sindent, USER_OBJECT_ prefix, USER_OBJECT_ r_encoding); USER_OBJECT_ RS_XML_xmlNodeNumChildren(USER_OBJECT_ snode); USER_OBJECT_ R_createXMLNodeRef(xmlNodePtr node, USER_OBJECT_ finalize); USER_OBJECT_ R_createXMLDocRef(xmlDocPtr doc); USER_OBJECT_ R_xmlCatalogResolve(SEXP r_id, SEXP type, USER_OBJECT_ debug); USER_OBJECT_ RS_XML_setDoc(USER_OBJECT_ snode, USER_OBJECT_ sdoc); USER_OBJECT_ RS_XML_unsetDoc(USER_OBJECT_ snode, USER_OBJECT_ unlink, USER_OBJECT_ r_parent, USER_OBJECT_ recursive); USER_OBJECT_ RS_XML_printXMLNode(USER_OBJECT_ node, USER_OBJECT_ level, USER_OBJECT_ format, USER_OBJECT_ indent, USER_OBJECT_ r_encoding, USER_OBJECT_ r_encoding_int); USER_OBJECT_ RS_XML_dumpHTMLDoc(USER_OBJECT_ r_node, USER_OBJECT_ format, USER_OBJECT_ r_encoding, USER_OBJECT_ indent, USER_OBJECT_ outFile); USER_OBJECT_ RS_XML_removeChildren(USER_OBJECT_ s_node, USER_OBJECT_ kids, USER_OBJECT_ freeNode); USER_OBJECT_ RS_XML_clone(USER_OBJECT_ obj, USER_OBJECT_ recursive, USER_OBJECT_ addFinalizer); USER_OBJECT_ R_xmlRootNode(USER_OBJECT_ sdoc, USER_OBJECT_ skipDtd, USER_OBJECT_ manageMemory); SEXP RS_XML_xpathEval(SEXP sdoc, SEXP r_node, SEXP path, SEXP namespaces, SEXP fun, SEXP charEncoding, SEXP manageMemory, SEXP xpathFuns, SEXP anonFuns); USER_OBJECT_ RS_XML_xmlNodeChildrenReferences(USER_OBJECT_ snode, USER_OBJECT_ r_addNames, USER_OBJECT_ manageMemory); USER_OBJECT_ RS_XML(internalNodeNamespaceDefinitions)(USER_OBJECT_ r_node, USER_OBJECT_ recursive); USER_OBJECT_ RS_XML(getDefaultValiditySetting)(USER_OBJECT_ val); SEXP RS_XML_freeDoc(SEXP ref); SEXP RS_XML_setRootNode(USER_OBJECT_ r_doc, USER_OBJECT_ r_node); USER_OBJECT_ R_getNodeChildByIndex(USER_OBJECT_ snode, USER_OBJECT_ r_index, USER_OBJECT_ manageMemory); SEXP RS_XML_setDocEl(SEXP r_node, SEXP r_doc); USER_OBJECT_ RS_XML_isDescendantOf(USER_OBJECT_ r_node, USER_OBJECT_ r_top, USER_OBJECT_ strict); SEXP RS_XML_getStructuredErrorHandler(void); SEXP RS_XML_setStructuredErrorHandler(SEXP els); SEXP R_convertDOMToHashTree(SEXP rnode, SEXP env, SEXP childrenEnv, SEXP parentEnv); SEXP R_parseURI(SEXP r_uri); SEXP R_getXMLFeatures(void); SEXP R_xmlReadMemory(SEXP r_txt, SEXP len, SEXP r_encoding, SEXP r_options, SEXP r_base); SEXP R_xmlReadFile(SEXP r_filename, SEXP r_encoding, SEXP r_options); USER_OBJECT_ R_libxmlTypeTable_names(USER_OBJECT_ table, USER_OBJECT_ s_elType) ; USER_OBJECT_ R_libxmlTypeTable_lookup(USER_OBJECT_ table, USER_OBJECT_ name, USER_OBJECT_ s_elType); SEXP RS_XML_xmlSchemaValidateDoc(SEXP r_schema, SEXP r_doc, SEXP r_options, SEXP r_errorHandlers); SEXP R_XML_indexOfChild(SEXP r_node); SEXP RS_XML_xmlStopParser(SEXP r_context); SEXP R_clearNodeMemoryManagement(SEXP r_node); SEXP R_XMLInternalDocument_free(SEXP sdoc); SEXP R_addXMLInternalDocument_finalizer(SEXP sdoc, SEXP fun); USER_OBJECT_ R_createXMLNode(USER_OBJECT_ snode, USER_OBJECT_ handlers, USER_OBJECT_ r_trim, USER_OBJECT_ r_skipBlankLines); USER_OBJECT_ RS_XML_xmlNodeName(USER_OBJECT_ snode); USER_OBJECT_ RS_XML_xmlNodeNamespace(USER_OBJECT_ snode); USER_OBJECT_ RS_XML_xmlNodeAttributes(USER_OBJECT_ snode, USER_OBJECT_ addNamespaces, USER_OBJECT_ addNamespaceURLs); SEXP R_xmlNodeValue(SEXP node, SEXP raw, SEXP r_encoding); SEXP R_setXMLInternalTextNode_value(SEXP node, SEXP value); USER_OBJECT_ RS_XML_xmlNodeParent(USER_OBJECT_ snode, USER_OBJECT_ manageMemory); USER_OBJECT_ R_getXMLNsRef(USER_OBJECT_ r_node); SEXP R_setXMLInternalTextNode_noenc(SEXP node); SEXP R_isNodeChildOfAt(SEXP rkid, SEXP rnode, SEXP rat); SEXP R_findXIncludeStartNodes(SEXP r_root, SEXP manageMemory); SEXP RS_XML_removeAllNodeNamespaces(SEXP s_node); SEXP RS_XML_removeNodeNamespaces(SEXP s_node, SEXP r_ns); SEXP R_matchNodesInList(SEXP r_nodes, SEXP r_target, SEXP r_nomatch); USER_OBJECT_ RS_XML_copyNodesToDoc(USER_OBJECT_ s_node, USER_OBJECT_ s_doc, USER_OBJECT_ manageMemory); USER_OBJECT_ RS_XML_getDocumentName(USER_OBJECT_ sdoc); USER_OBJECT_ RS_XML_xmlXIncludeProcessFlags(USER_OBJECT_ r_doc, USER_OBJECT_ r_flags); USER_OBJECT_ RS_XML_xmlXIncludeProcessTreeFlags(USER_OBJECT_ r_node, USER_OBJECT_ r_flags); USER_OBJECT_ RS_XML(internalNodeNamespaceDefinitions)(USER_OBJECT_ r_node, USER_OBJECT_ recursive); Rboolean R_isInstanceOf(USER_OBJECT_ obj, const char *klass); USER_OBJECT_ RS_XML_addNodeAttributes(USER_OBJECT_ s_node, USER_OBJECT_ attrs); USER_OBJECT_ RS_XML_removeNodeAttributes(USER_OBJECT_ s_node, USER_OBJECT_ attrs, USER_OBJECT_ asNamespace); USER_OBJECT_ RS_XML_getNsList(USER_OBJECT_ s_node, USER_OBJECT_ asRef); USER_OBJECT_ RS_XML_setNodeName(USER_OBJECT_ s_node, USER_OBJECT_ s_name); USER_OBJECT_ R_xmlNsAsCharacter(USER_OBJECT_ s_ns); USER_OBJECT_ R_createXMLNsRef(xmlNsPtr ns); USER_OBJECT_ RS_XML_getNextSibling(USER_OBJECT_ node, USER_OBJECT_ s_prev, USER_OBJECT_ manageMemory); USER_OBJECT_ R_getXMLNodeDocument(USER_OBJECT_ s_node); USER_OBJECT_ RS_XML_createDocFromNode(USER_OBJECT_ s_node); SEXP R_removeInternalNode(SEXP r_node, SEXP r_free); USER_OBJECT_ RS_XML_replaceXMLNode(USER_OBJECT_ r_old, USER_OBJECT_ r_new, USER_OBJECT_ manageMemory); USER_OBJECT_ RS_XML_xmlAddSiblingAt(USER_OBJECT_ r_to, USER_OBJECT_ r_node, USER_OBJECT_ r_before, USER_OBJECT_ manageMemory); SEXP RS_XML_clearCatalog(void); SEXP RS_XML_loadCatalog(SEXP catalogs); SEXP RS_XML_catalogAdd(SEXP orig, SEXP replace, SEXP type); SEXP RS_XML_catalogDump(SEXP fileName); void R_xmlFreeDoc(SEXP ref); USER_OBJECT_ RS_XML_setDocumentName(USER_OBJECT_ sdoc, USER_OBJECT_ sname); USER_OBJECT_ RS_XML_setKeepBlanksDefault(USER_OBJECT_ val); SEXP RS_XML_setNS(SEXP s_node, SEXP r_ns); SEXP stop(const char *className, const char *msg, ...); SEXP RSXML_structuredStop(SEXP errorFun, xmlErrorPtr err); void R_xmlStructuredErrorHandler(void *data, xmlErrorPtr err); SEXP R_getDocEncoding(SEXP r_doc); SEXP R_getLineNumber(SEXP r_node); SEXP R_addXMLNodeFinalizer(SEXP r_node); extern int R_numXMLDocs, R_numXMLDocsFreed; SEXP CreateCharSexpWithEncoding(const xmlChar *encoding, const xmlChar *str); #define DECL_ENCODING_FROM_NODE(node) const xmlChar *encoding = node->doc ? node->doc->encoding : NULL; #define DECL_ENCODING_FROM_DOC(doc) const xmlChar *encoding = doc->encoding; #define DECL_ENCODING_FROM_EVENT_PARSER(parserData) const xmlChar *encoding = parserData->ctx->encoding; #define R_USE_XML_ENCODING 1 #ifdef R_USE_XML_ENCODING #undef COPY_TO_USER_STRING //#warning "Redefining COPY_TO_USER_STRING to use encoding from XML parser" /* #define COPY_TO_USER_STRING(x) CreateCharSexpWithEncoding(encoding, CHAR_TO_XMLCHAR (x)) */ // #define COPY_TO_USER_STRING(x) mkChar(CHAR_TO_XMLCHAR (x)) #define COPY_TO_USER_STRING(x) mkChar((const char *) (x)) #define ENC_COPY_TO_USER_STRING(x) CreateCharSexpWithEncoding(encoding, CHAR_TO_XMLCHAR (x)) #endif #include #define R_CHECK_INTERRUPTS R_CheckUserInterrupt(); //#include "NodeGC.h" SEXP R_createXMLNodeRefDirect(xmlNodePtr node, int addFinalizer); int R_XML_getManageMemory(USER_OBJECT_ user, xmlDocPtr doc, xmlNodePtr node); USER_OBJECT_ R_convertXMLNsRef(SEXP r_ns); USER_OBJECT_ R_replaceNodeWithChildren(USER_OBJECT_ r_node); #endif XML/src/ExpatParse.h0000644000175100001440000000107713607633744013766 0ustar hornikusers#ifndef EXPAT_PARSE_H #define EXPAT_PARSE_H /* */ #include "xmlparse.h" int RS_XML(parseWithParserData)(FILE *file, RS_XMLParserData *parserData); void RS_XML(initParser)(XML_Parser parser, RS_XMLParserData *parserData); int RS_XML(parse)(FILE *file, USER_OBJECT_ handlers); int RS_XML(parseBufferWithParserData)(char *buf, RS_XMLParserData *parserData); int RS_XML(externalEntityHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); #endif XML/src/Makevars.win0000644000175100001440000000055713700634770014025 0ustar hornikusersPKG_CPPFLAGS= -I${LIB_XML}/include/libxml2 -I${LIB_XML}/include -D_R_=1 -DUSE_R=1 -DUSE_XML_VERSION_H=1 -DLIBXML -DUSE_EXTERNAL_SUBSET=1 -DROOT_HAS_DTD_NODE=1 -DUMP_WITH_ENCODING=1 -DXML_ELEMENT_ETYPE=1 -DXML_ATTRIBUTE_ATYPE=1 -DLIBXML2=1 -DHAVE_XML_HAS_FEATURE -DLIBXML_STATIC -DNO_XML_HASH_SCANNER_RETURN=1 PKG_LIBS = -L${LIB_XML}/lib -lxml2 -liconv -lz -lws2_32 XML/src/RS_XML.h0000644000175100001440000000144413607633744012754 0ustar hornikusers/* * See Copyright for the license status of this software. */ #ifndef RS_XML_H #define RS_XML_H #define RS_XML(a) RS_XML_##a /* #define R_XML_DEBUG 1 */ #if 0 #if 1 #define XML_REF_COUNT_NODES 1 #else #ifdef XML_REF_COUNT_NODES #undef XML_REF_COUNT_NODES #endif #endif #endif /* #undef XML_REF_COUNT_NODES */ typedef enum {RS_XML_FILENAME, RS_XML_TEXT, RS_XML_CONNECTION, RS_XML_INVALID_CONTENT} RS_XML_ContentSourceType; #ifdef _R_ #include "R.h" #include "Rinternals.h" #if 0 #if R_VERSION < R_Version(1, 2, 0) #define STRING_ELT(x,i) STRING(x)[i] #define VECTOR_ELT(x,i) VECTOR(x)[i] #define SET_STRING_ELT(x,i,v) (STRING(x)[i]=(v)) #define SET_VECTOR_ELT(x,i,v) (VECTOR(x)[i]=(v)) #endif #endif /* end of ignoring version details */ #endif /* end of _R_ */ #endif XML/src/XMLTree.c0000644000175100001440000013007214636530730013155 0ustar hornikusers/** The purpose of this file is to provide the C-level facilities to create, modify and manage internal XML DOM nodes at the S language level. We want to be able to use the interface defined by xmlOutputDOM() and xmlOutputBuffer() but with an implementation that returns a tree that is built to be used with the libxml data structures. So the intent is to incrementally add nodes to the tree in memory and then pass this to libxml to add it to another tree or write it to a file, etc. The essential public/high-level functionality provided by the the S-leve interface for building trees consists of: 1) addTag 2) closeTag 3) addComment 4) value addNode a) getOpenTag b) reset */ #include "RSCommon.h" #include "RS_XML.h" #ifdef FROM_GNOME_XML_DIR #include #include #else #include #include #include #endif #define R_USE_XML_ENCODING 1 #include "Utils.h" /* R_createXMLNodeRef, Encoding macros. */ #include "NodeGC.h" #ifdef USE_OLD_ROOT_CHILD_NAMES # define XML_ROOT(n) (n)->childs #else # define XML_ROOT(n) (n)->xmlRootNode #endif void incrementDocRef(xmlDocPtr doc); int getNodeCount(xmlNodePtr node); void incrementDocRefBy(xmlDocPtr doc, int num); void RS_XML_recursive_unsetListDoc(xmlNodePtr list); /** Create a libxml comment node and return it as an S object referencing this value. */ USER_OBJECT_ R_xmlNewComment(USER_OBJECT_ str, USER_OBJECT_ sdoc, USER_OBJECT_ manageMemory) { xmlNodePtr node; xmlDocPtr doc = NULL; xmlChar *txt; if(GET_LENGTH(sdoc)) doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); txt = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(str, 0))); node = doc ? xmlNewDocComment(doc, txt) : xmlNewComment(txt); return(R_createXMLNodeRef(node, manageMemory)); } USER_OBJECT_ R_newXMLTextNode(USER_OBJECT_ value, USER_OBJECT_ sdoc, SEXP manageMemory) { xmlNodePtr node; xmlDocPtr doc = NULL; xmlChar *txt; if(GET_LENGTH(sdoc)) doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); txt = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(value, 0))); if(doc) node = xmlNewDocTextLen(doc, txt, (int)strlen(XMLCHAR_TO_CHAR(txt))); else node = xmlNewText(txt); return(R_createXMLNodeRef(node, manageMemory)); } USER_OBJECT_ R_newXMLCDataNode(USER_OBJECT_ sdoc, USER_OBJECT_ value, USER_OBJECT_ manageMemory) { xmlDocPtr doc = NULL; xmlNodePtr node; const char *tmp; if(GET_LENGTH(sdoc)) doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); tmp = CHAR_DEREF(STRING_ELT(value,0)); node = xmlNewCDataBlock(doc, CHAR_TO_XMLCHAR(tmp), (int)strlen(tmp)); return(R_createXMLNodeRef(node, manageMemory)); } USER_OBJECT_ R_newXMLPINode(USER_OBJECT_ sdoc, USER_OBJECT_ name, USER_OBJECT_ content, USER_OBJECT_ manageMemory) { xmlNodePtr node; node = xmlNewPI(CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(name, 0))), CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(content, 0)))); return( R_createXMLNodeRef(node, manageMemory) ); } USER_OBJECT_ R_newXMLNode(USER_OBJECT_ name, USER_OBJECT_ attrs, USER_OBJECT_ nameSpace, USER_OBJECT_ sdoc, USER_OBJECT_ nameSpaceDefinitions, USER_OBJECT_ manageMemory) { xmlDocPtr doc = NULL; xmlNsPtr ns = NULL; xmlNodePtr node; if(GET_LENGTH(sdoc)) { doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); if(doc->type != XML_DOCUMENT_NODE && doc->type != XML_HTML_DOCUMENT_NODE) doc = doc->doc; } if(GET_LENGTH(nameSpace) > 0) { /* Need the default namespace and then also any other */ CHAR_DEREF(STRING_ELT(nameSpace, 0)); } node = xmlNewDocNode(doc, ns, CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(name, 0))), NULL); if(doc && XML_ROOT(doc) == NULL) { XML_ROOT(doc) = node; } return( R_createXMLNodeRef(node, manageMemory) ); } USER_OBJECT_ RS_XML_getNextSibling(USER_OBJECT_ s_node, USER_OBJECT_ s_prev, USER_OBJECT_ manageMemory) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node), ptr; ptr = LOGICAL(s_prev)[0] ? node->next : node->prev; return(ptr ? R_createXMLNodeRef(ptr, manageMemory) : NULL_USER_OBJECT); } /* Add attributes to an existing node. At present, doesn't check for duplicates. Can do this in C or in R, but need to remove existing values, and ensure that namespace considerations are handled properly. */ USER_OBJECT_ RS_XML_addNodeAttributes(USER_OBJECT_ s_node, USER_OBJECT_ attrs) { int i, n; USER_OBJECT_ attr_names; xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); n = GET_LENGTH(attrs); attr_names = GET_NAMES(attrs); for(i = 0; i < n; i++) { xmlSetProp(node, CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(attr_names, i))), CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(attrs, i)))); } return(ScalarInteger(n)); } USER_OBJECT_ RS_XML_setNodeName(USER_OBJECT_ s_node, USER_OBJECT_ s_name) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); xmlChar *name = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(s_name, 0))); xmlNodeSetName(node, name); return(NULL_USER_OBJECT); } #if 0 int removeNodeNamespace(xmlNodePtr node, xmlNsPtr p) { if(!p) return(0); if(!node->prev) node->ns = p->next; else p->v->next = p->next; return(1); } #endif int removeNodeNamespaceByName(xmlNodePtr node, const char * const id) { xmlNsPtr p, prev; if(!node->nsDef) return(0); prev = node->nsDef; p = node->nsDef; if(!(id[0] && !p->prefix) || (p->prefix && strcmp((const char *)p->prefix, id) == 0)) { /*XXX Free or not */ if(node->ns == p) node->ns = NULL; node->nsDef = p->next; return(1); } while(1) { if((!id[0] && !p->prefix) || (p->prefix && strcmp((const char *)p->prefix, id) == 0)) { prev->next = p->next; if(node->ns == p) node->ns = NULL; return(1); } prev = p; p = p->next; } return(0); } SEXP R_replaceDummyNS(USER_OBJECT_ s_node, USER_OBJECT_ newNS, USER_OBJECT_ prefix) { xmlNodePtr node; if(TYPEOF(s_node) != EXTPTRSXP) { Rf_error("non external pointer passed to R_replaceDummyNS"); } node = (xmlNodePtr) R_ExternalPtrAddr(s_node); removeNodeNamespaceByName(node, CHAR(STRING_ELT(prefix, 0))); return(R_xmlSetNs(s_node, newNS, ScalarLogical(0))); // return(newNS); } SEXP RS_XML_removeAllNodeNamespaces(SEXP s_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); xmlNsPtr p, tmp; int n = 0; if(!node) return(ScalarLogical(FALSE)); p = node->nsDef; while(p) { if(node->ns == p) { node->ns = NULL; } tmp = p; p = p->next; if(0 && tmp->type) xmlFreeNs(tmp); n++; } node->nsDef = NULL; return(ScalarInteger(n)); } SEXP RS_XML_removeNodeNamespaces(SEXP s_node, SEXP r_ns) { int i, n; xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); SEXP el, ans; const char *prefix; // xmlNsPtr p; // int t = TYPEOF(r_ns); n = Rf_length(r_ns); PROTECT(ans = allocVector(LGLSXP, n)); for(i = 0; i < n; i++) { el = VECTOR_ELT(r_ns, i); if(TYPEOF(el) == STRSXP) { prefix = CHAR(STRING_ELT(el, 0)); LOGICAL(ans)[i] = removeNodeNamespaceByName(node, prefix); } else if(TYPEOF(el) == EXTPTRSXP) { xmlNsPtr p = (xmlNsPtr) R_ExternalPtrAddr(el); LOGICAL(ans)[i] = removeNodeNamespaceByName(node, (const char *)p->prefix); } } UNPROTECT(1); return(ans); } /* attrs is a vector whose names identify */ USER_OBJECT_ RS_XML_removeNodeAttributes(USER_OBJECT_ s_node, USER_OBJECT_ attrs, USER_OBJECT_ asNamespace) { int i, n; USER_OBJECT_ attr_names, ans; xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); n = GET_LENGTH(attrs); PROTECT(ans = NEW_LOGICAL(n)); attr_names = GET_NAMES(attrs); for(i = 0; i < n; i++) { if(TYPEOF(attrs) == INTSXP) { int which = INTEGER(attrs)[i] - i - 1; xmlAttrPtr p; int j = 0; p = node->properties; while(j < which && p) { p = p->next; j++; } xmlUnsetNsProp(node, p->ns, p->name); /* if(p) xmlFree(p); */ } else if(LOGICAL(asNamespace)[0]) { xmlNsPtr ns = NULL; xmlChar *id; id = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(attr_names, i))); SEXP ai = VECTOR_ELT(attrs, i); if(TYPEOF(ai) == EXTPTRSXP) ns = (xmlNsPtr) R_ExternalPtrAddr(ai); if(id[0]) INTEGER(ans)[i] = xmlUnsetNsProp(node, ns, id); } else INTEGER(ans)[i] = xmlUnsetProp(node, CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(attrs, i)))); } UNPROTECT(1); return(ans); } #define GET_R_XML_NODE_PTR(x) (xmlNodePtr) R_ExternalPtrAddr(s_node); USER_OBJECT_ RS_XML_getNsList(USER_OBJECT_ s_node, USER_OBJECT_ asRef) { xmlNodePtr node = GET_R_XML_NODE_PTR(s_node); xmlNsPtr *els, el; int n = 0, i; USER_OBJECT_ ans, names; DECL_ENCODING_FROM_NODE(node) els = xmlGetNsList(node->doc, node); if(!els) return(NULL_USER_OBJECT); el = *els; while(el) { n++; el = el->next; } el = *els; if(LOGICAL(asRef)[0]) { PROTECT(ans = NEW_LIST(n)); PROTECT(names = NEW_CHARACTER(n)); for(i = 0; i < n ; i++, el = el->next) { if(el->prefix) SET_STRING_ELT(names, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(el->prefix))); SET_VECTOR_ELT(ans, i, R_createXMLNsRef(el)); } } else { PROTECT(ans = NEW_CHARACTER(n)); PROTECT(names = NEW_CHARACTER(n)); for(i = 0; i < n ; i++, el = el->next) { if(el->prefix) SET_STRING_ELT(names, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(el->prefix))); if(el->href) SET_STRING_ELT(ans, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(el->href))); } } SET_NAMES(ans, names); UNPROTECT(2); return(ans); } SEXP R_removeInternalNode(SEXP r_node, SEXP r_free) { xmlNodePtr node; int n = GET_LENGTH(r_node), i; for(i = 0; i < n; i++) { SEXP el = VECTOR_ELT(r_node, i); if(TYPEOF(el) != EXTPTRSXP) { Rf_error("removeInternalNode needs ans external pointer object"); } node = (xmlNodePtr) R_ExternalPtrAddr(el); if(!node) { Rf_warning("removeInternalNode ignoring a NULL external pointer object"); } xmlUnlinkNode(node); if(LOGICAL(r_free)[i]) xmlFreeNode(node); } return(NULL_USER_OBJECT); } SEXP RS_XML_setRootNode(USER_OBJECT_ r_doc, USER_OBJECT_ r_node) { xmlDocPtr doc; xmlNodePtr node; doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); node = (xmlNodePtr) R_ExternalPtrAddr(r_node); /* Set the reference counting information. */ //if(!node->doc) // node->doc = doc; xmlDocSetRootElement(doc, node); return(ScalarLogical(TRUE)); } SEXP R_isNodeChildOfAt(SEXP rkid, SEXP rnode, SEXP rat) { int i=0, at; xmlNodePtr kid, node, ptr; node = (xmlNodePtr) R_ExternalPtrAddr(rnode); kid = (xmlNodePtr) R_ExternalPtrAddr(rkid); if(!node || !kid || !kid->parent) return(ScalarLogical(FALSE)); at = INTEGER(rat)[0] - 1; ptr = node->children; while(i < at && ptr) { ptr = ptr->next; i++; } return(ScalarLogical(ptr == kid)); } /** Add the internal XML node represented by the S object @node as a child of the XML node represented by the S object @parent. */ USER_OBJECT_ R_insertXMLNode(USER_OBJECT_ node, USER_OBJECT_ parent, USER_OBJECT_ at, USER_OBJECT_ shallow) { // check is currently set but unused. xmlNodePtr n, p, /*check,*/ tmp = NULL; if(TYPEOF(parent) != EXTPTRSXP) { Rf_error("R_insertXMLNode expects XMLInternalNode objects for the parent node"); } if(IS_LIST(node)) { int i; for(i = 0; i < GET_LENGTH(node); i++) R_insertXMLNode(VECTOR_ELT(node, i), parent, R_NilValue/*XXX*/, shallow); return(NULL_USER_OBJECT); } if(TYPEOF(node) == STRSXP) { int i; p = (xmlNodePtr) R_ExternalPtrAddr(parent); for(i = 0; i < GET_LENGTH(node); i++) { n = xmlNewText((const xmlChar *)CHAR(STRING_ELT(node, i))); xmlAddChild(p, n); } return(NULL_USER_OBJECT); } if(TYPEOF(node) != EXTPTRSXP) { Rf_error("R_insertXMLNode expects XMLInternalNode objects"); } p = (xmlNodePtr) R_ExternalPtrAddr(parent); n = (xmlNodePtr) R_ExternalPtrAddr(node); if(!p || !n) { Rf_error("either the parent or child node is NULL"); } #if 0 if(0 && n->parent == p || n->parent) { /*XX Need to decrement the reference count if there is a document. */ xmlUnlinkNode(n); } #endif /* Make certain the nodes belong to this document if they already belong to another by copying. */ if(n->doc && n->doc != p->doc) { n = xmlDocCopyNode(n, p->doc, 1); } else if(!n->doc && LOGICAL(shallow)[0]) { /* XXX This is intended to avoid setting all the nodes to this document and then having to undo that later on.*/ n->doc = p->doc; } switch(p->type) { case XML_ELEMENT_NODE: /* Need to be careful that if n is a text node, it could be * absorbed into its nearest sibling and then freed. So we take a copy of the text node*/ if(n->type == XML_TEXT_NODE) { tmp = xmlNewText(n->content); /* tmp = xmlCopyNode(n, 1); */ } else { tmp = n; if(n->_private) { #ifdef R_XML_DEBUG fprintf(stderr, "insertXMLNode: %p to %p, incrementing document (%p) %d\n", n, p, p->doc, *(int *) n->_private); #endif if(p->doc) incrementDocRefBy(p->doc, getNodeCount(n)); } } /* check = */ xmlAddChild(p, tmp); #if 0 /* XXXX */ if(n->type == XML_TEXT_NODE && check != tmp) xmlFreeNode(tmp); #endif break; case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: /*check = */ xmlAddChild(p, n); incrementDocRef((xmlDocPtr) p); break; case XML_PI_NODE: xmlAddSibling(p, n); break; default: { Rf_warning("ignoring request to add child (types parent: %d, child %d)", p->type, n->type); } break; } #if 0 /* This is where we handle the case where n being a text node may * have been freed by xmlAddChild. */ if(check != n) { fprintf(stderr, "xmlAddChild() may have freed the node\n");fflush(stderr); R_ClearExternalPtr(node); } #endif /* ??? internal_incrementNodeRefCount(n); */ return(NULL_USER_OBJECT); } USER_OBJECT_ RS_XML_xmlAddSiblingAt(USER_OBJECT_ r_to, USER_OBJECT_ r_node, USER_OBJECT_ r_after, USER_OBJECT_ manageMemory) { xmlNodePtr p, n, ans; xmlNodePtr (*f)(xmlNodePtr, xmlNodePtr); if(TYPEOF(r_to) != EXTPTRSXP) { Rf_error("RS_XML_xmlAddSiblingAt expects XMLInternalNode objects for the parent node"); } if(TYPEOF(r_node) != EXTPTRSXP) { Rf_error("RS_XML_xmlAddSiblingAt expects XMLInternalNode objects for the node to add"); } p = (xmlNodePtr) R_ExternalPtrAddr(r_to); n = (xmlNodePtr) R_ExternalPtrAddr(r_node); if(!p || !n) { Rf_error("either the parent or child node is NULL"); } f = LOGICAL(r_after)[0] ? xmlAddNextSibling : xmlAddPrevSibling ; ans = f(p, n); /* If adding to the root node and inserting a node before the * current first child, update the document.*/ if(p->doc && p->doc->children == p && n->next == p) p->doc->children = n; incrementDocRefBy(p->doc, getNodeCount(n)); return(R_createXMLNodeRef(ans, manageMemory)); } USER_OBJECT_ RS_XML_replaceXMLNode(USER_OBJECT_ r_old, USER_OBJECT_ r_new, USER_OBJECT_ manageMemory) { xmlNodePtr Old, New, ans; if(TYPEOF(r_old) != EXTPTRSXP && TYPEOF(r_new) != EXTPTRSXP) { Rf_error("R_replaceXMLNode expects XMLInternalNode objects"); } Old = (xmlNodePtr) R_ExternalPtrAddr(r_old); New = (xmlNodePtr) R_ExternalPtrAddr(r_new); if(!Old) { Rf_error("NULL value for XML node to replace"); } ans = xmlReplaceNode(Old, New); return(R_createXMLNodeRef(ans, manageMemory)); } /* a = newXMLNode("a", newXMLNode("b", newXMLNode("c", 3)), newXMLNode("d", "text")) removeChildren(a, 2) */ USER_OBJECT_ RS_XML_removeChildren(USER_OBJECT_ s_node, USER_OBJECT_ kids, USER_OBJECT_ freeNode) { int i, n; USER_OBJECT_ ans; xmlNodePtr node = NULL, tmp; if(GET_LENGTH(s_node)) { node = (xmlNodePtr) R_ExternalPtrAddr(s_node); if(!node) { Rf_error("Empty XMLInternalNode"); } } n = GET_LENGTH(kids); PROTECT(ans = NEW_LOGICAL(n)); for(i = 0; i < n; i++) { tmp = (xmlNodePtr) R_ExternalPtrAddr(VECTOR_ELT(kids, i)); if(!tmp) continue; if(node && tmp->parent != node) { Rf_error("trying to remove a child node from a different parent node"); } xmlUnlinkNode(tmp); if(LOGICAL(freeNode)[0]) xmlFreeNode(tmp); LOGICAL(ans)[i] = TRUE; } UNPROTECT(1); return(ans); } USER_OBJECT_ R_xmlRootNode(USER_OBJECT_ sdoc, USER_OBJECT_ skipDtd, USER_OBJECT_ manageMemory) { xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); xmlNodePtr node = NULL; if(doc) node = doc->children; if(!node) { Rf_warning("empty XML document"); return(NULL_USER_OBJECT); } if(LOGICAL(skipDtd)[0]) { while(node && node->type != XML_ELEMENT_NODE /* (node->type == XML_DTD_NODE || node->type == XML_COMMENT_NODE) */) { node = node->next; } } if(node == NULL) return(NULL_USER_OBJECT); return(R_createXMLNodeRef(node, manageMemory)); } /** Create an S object representing a newly created internal XML document object. */ int R_numXMLDocs = 0; int R_numXMLDocsFreed = 0; USER_OBJECT_ R_newXMLDoc(USER_OBJECT_ dtd, USER_OBJECT_ namespaces, USER_OBJECT_ isHTML) { xmlDocPtr doc; if(LOGICAL(isHTML)[0]) { const char *d = (TYPEOF(dtd) == STRSXP && Rf_length(dtd)) ? CHAR_DEREF(STRING_ELT(dtd, 0)) : NULL; if(d[0] == '5') doc = htmlNewDoc((const xmlChar *)"", NULL); else doc = htmlNewDocNoDtD(d && d[0] ? CHAR_TO_XMLCHAR(d) : NULL, NULL); } else doc = xmlNewDoc(CHAR_TO_XMLCHAR("1.0")); R_numXMLDocs++; return(R_createXMLDocRef(doc)); } USER_OBJECT_ R_newXMLDtd(USER_OBJECT_ sdoc, USER_OBJECT_ sdtdName, USER_OBJECT_ sexternalID, USER_OBJECT_ ssysID, USER_OBJECT_ manageMemory) { xmlDocPtr doc = NULL; xmlChar *dtdName = NULL; xmlChar *externalID = NULL; xmlChar *sysID = NULL; xmlDtdPtr node; #define GET_STR_VAL(x) \ if(GET_LENGTH(s##x) > 0) { \ x = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(s##x, 0))); \ if(!x[0]) \ x = NULL; \ } GET_STR_VAL(dtdName) GET_STR_VAL(externalID) GET_STR_VAL(sysID) if(sdoc != NULL_USER_OBJECT && TYPEOF(sdoc) == EXTPTRSXP) doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); node = xmlNewDtd(doc, dtdName, externalID, sysID); /* should we do this??? xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) DTD); */ return(R_createXMLNodeRef((xmlNodePtr) node, manageMemory)); } /* */ USER_OBJECT_ R_xmlSetNs(USER_OBJECT_ s_node, USER_OBJECT_ s_ns, USER_OBJECT_ append) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); xmlNsPtr ns = NULL; if(s_ns != NULL_USER_OBJECT) ns = (xmlNsPtr) R_ExternalPtrAddr(s_ns); if(LOGICAL(append)[0]) { xmlNsPtr el; if(!node->ns) xmlSetNs(node, xmlNewNs(node, NULL, NULL)); el = node->ns; while(el->next) el = el->next; el->next = ns; } else xmlSetNs(node, ns); return(s_ns); } #if 0 /* remove if the above is sufficient. */ SEXP RS_XML_setNS(SEXP s_node, SEXP r_ns) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); xmlNsPtr ns = (xmlNsPtr) R_ExternalPtrAddr(r_ns); xmlSetNS(node, ns); return(NULL_USER_OBJECT); } #endif static const char *DummyNamespaceHREF = ""; USER_OBJECT_ R_xmlNewNs(USER_OBJECT_ sdoc, USER_OBJECT_ shref, USER_OBJECT_ sprefix) { xmlNodePtr doc = (xmlNodePtr) R_ExternalPtrAddr(sdoc); const char *href = Rf_length(shref) == 0 ? DummyNamespaceHREF : CHAR_DEREF(STRING_ELT(shref, 0)); const char *prefix = NULL; xmlNsPtr ns; if(Rf_length(sprefix)) { prefix = CHAR_DEREF(STRING_ELT(sprefix, 0)); if(!prefix[0]) prefix = NULL; } if(!href[0]) href = NULL; ns = xmlNewNs(doc, CHAR_TO_XMLCHAR(href), CHAR_TO_XMLCHAR(prefix)); return(R_createXMLNsRef(ns)); /*XXX */ } USER_OBJECT_ RS_XML_clone(USER_OBJECT_ obj, USER_OBJECT_ recursive, USER_OBJECT_ manageMemory) { if(TYPEOF(obj) != EXTPTRSXP) { Rf_error( "clone can only be applied to an internal, C-level libxml2 object"); } if(!R_ExternalPtrAddr(obj)) { Rf_error( "NULL value passed to clone, possibly from a previous session"); } if(R_isInstanceOf(obj, "XMLInternalElementNode")) { xmlNodePtr node, node_ans; node = (xmlNodePtr) R_ExternalPtrAddr(obj); node_ans = xmlCopyNode(node, INTEGER(recursive)[0]); return(R_createXMLNodeRef(node_ans, manageMemory)); } else if(R_isInstanceOf(obj, "XMLInternalDocument") || R_isInstanceOf(obj, "XMLInternalDOM")) { xmlDocPtr doc; doc = (xmlDocPtr) R_ExternalPtrAddr(obj); return(R_createXMLDocRef(xmlCopyDoc(doc, INTEGER(recursive)[0]))); // , manageMemory)); } Rf_error("clone doesn't (yet) understand this internal data type"); return(NULL_USER_OBJECT); /* never reached */ } #ifdef R_XML_DEBUG xmlDocPtr currentDoc; #endif USER_OBJECT_ R_createXMLDocRef(xmlDocPtr doc) { SEXP ref, tmp; #ifdef R_XML_DEBUG currentDoc = doc; #endif if(!doc) return(R_NilValue); initDocRefCounter(doc); incrementDocRef(doc); #ifdef R_XML_DEBUG fprintf(stderr, "creating document reference %s %p, count = %d\n", doc->URL ? doc->URL : "internally created", doc, * ((int*) doc->_private)); #endif PROTECT(ref = R_MakeExternalPtr(doc, Rf_install("XMLInternalDocument"), R_NilValue)); PROTECT(tmp = NEW_CHARACTER(1)); SET_STRING_ELT(tmp, 0, mkChar( doc->type == XML_HTML_DOCUMENT_NODE ? "HTMLInternalDocument" : "XMLInternalDocument")); SET_CLASS(ref, tmp); UNPROTECT(2); return(ref); } USER_OBJECT_ R_removeXMLNsRef(xmlNsPtr ns) { /*XXX xmlNsPtr p = (xmlNsPtr) R_ExternalPtrAddr(); */ Rf_error("C routine R_removeXMLNsRef() not implemented yet"); return(R_NilValue); } USER_OBJECT_ R_createXMLNsRef(xmlNsPtr ns) { SEXP ref, tmp; PROTECT(ref = R_MakeExternalPtr(ns, Rf_install("XMLNamespaceRef"), R_NilValue)); PROTECT(tmp = NEW_CHARACTER(1)); SET_STRING_ELT(tmp, 0, mkChar("XMLNamespaceRef")); SET_CLASS(ref, tmp); UNPROTECT(2); return(ref); } USER_OBJECT_ R_convertXMLNsRef(SEXP r_ns) { SEXP ans; xmlNsPtr ns; if(TYPEOF(r_ns) != EXTPTRSXP) { Rf_error("wrong type for namespace reference"); } ns = (xmlNsPtr) R_ExternalPtrAddr(r_ns); PROTECT(ans = mkString((const char *)ns->href)); SET_NAMES(ans, mkString(ns->prefix ? XMLCHAR_TO_CHAR(ns->prefix) : "")); UNPROTECT(1); return(ans); } USER_OBJECT_ R_getXMLNsRef(USER_OBJECT_ r_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); if(!node) return(R_NilValue); return(node->ns ? R_createXMLNsRef(node->ns) : R_NilValue); } const char * R_getInternalNodeClass(xmlElementType type) { const char * p = ""; switch(type) { case XML_ELEMENT_NODE: p = "XMLInternalElementNode"; break; case XML_ELEMENT_DECL: p = "XMLInternalElementDeclNode"; break; case XML_TEXT_NODE: p = "XMLInternalTextNode"; break; case XML_CDATA_SECTION_NODE: p = "XMLInternalCDataNode"; break; case XML_ENTITY_NODE: p = "XMLInternalEntityNode"; break; case XML_ENTITY_REF_NODE: p = "XMLInternalEntityRefNode"; break; case XML_PI_NODE: p = "XMLInternalPINode"; break; case XML_COMMENT_NODE: p = "XMLInternalCommentNode"; break; case XML_NOTATION_NODE: p = "XMLInternalNotationNode"; break; case XML_DTD_NODE: p = "XMLDTDNode"; break; case XML_NAMESPACE_DECL: p = "XMLNamespaceDeclaration"; break; case XML_XINCLUDE_START: p = "XMLXIncludeStartNode"; break; case XML_XINCLUDE_END: p = "XMLXIncludeEndNode"; break; case XML_ENTITY_DECL: p = "XMLInternalEntityRefNode"; break; case XML_ATTRIBUTE_DECL: p = "XMLAttributeDeclNode"; break; case XML_DOCUMENT_NODE: p = "XMLDocumentNode"; break; case XML_HTML_DOCUMENT_NODE: p = "XMLHTMLDocumentNode"; break; case XML_DOCUMENT_TYPE_NODE: p = "XMLDocumentTypeNode"; break; case XML_DOCUMENT_FRAG_NODE: p = "XMLDocumentFragNode"; break; case XML_ATTRIBUTE_NODE: p = "XMLAttributeNode"; break; default: p = "XMLUnknownInternalNode"; } return(p); } SEXP R_createXMLNodeRefDirect(xmlNodePtr node, int addFinalizer) { SEXP ref, tmp; PROTECT(ref = R_MakeExternalPtr(node, Rf_install("XMLInternalNode"), R_NilValue)); #ifdef XML_REF_COUNT_NODES if(addFinalizer > 0 || (addFinalizer < 0 && !IS_NOT_OUR_NODE_TO_TOUCH(node))) { #ifdef R_XML_DEBUG fprintf(stderr, "Creating reference with finalizer for %s (%p) '%s'\n", node->name, node, node->type == XML_TEXT_NODE ? node->content : "");fflush(stderr); #endif R_RegisterCFinalizer(ref, decrementNodeRefCount); } /* #else #warning "no ref counting enabled" */ #endif PROTECT(tmp = NEW_CHARACTER(3)); SET_STRING_ELT(tmp, 0, mkChar(R_getInternalNodeClass(node->type))); SET_STRING_ELT(tmp, 1, mkChar("XMLInternalNode")); SET_STRING_ELT(tmp, 2, mkChar("XMLAbstractNode")); SET_CLASS(ref, tmp); UNPROTECT(2); return(ref); } /** Used to be used as R_XML_getManageMemory(manageMemory, node->doc, node) > 0 ? R_createXMLNodeRef() : R_createXMLNodeRefDirect(node, 0)); */ USER_OBJECT_ R_createXMLNodeRef(xmlNodePtr node, USER_OBJECT_ finalize) { int *val; int addFinalizer = 0; if(!node) return(NULL_USER_OBJECT); addFinalizer = R_XML_getManageMemory(finalize, node->doc, node); /* !IS_NOT_OUR_NODE_TO_TOUCH(node) */ if(addFinalizer && ((node->_private && ((int*)node->_private)[1] == (int) R_MEMORY_MANAGER_MARKER) || !node->doc || (!(IS_NOT_OUR_DOC_TO_TOUCH(node->doc))))) { if(node->_private == NULL) { node->_private = calloc(2, sizeof(int)); val = (int *) node->_private; val[1] = R_MEMORY_MANAGER_MARKER; } val = (int *) node->_private; (*val)++; if(*val == 1) incrementDocRef(node->doc); #ifdef R_XML_DEBUG fprintf(stderr, "creating reference to node (%s, %d) count = %d (%p) (doc = %p count = %d)\n", node->name, node->type, (int) *val, node, node->doc, (node->doc && node->doc->_private) ? ((int *)node->doc->_private)[0] : -1); #endif } return(R_createXMLNodeRefDirect(node, addFinalizer /* !IS_NOT_OUR_NODE_TO_TOUCH(node) */ )); } /* May not be used. Not yet. The idea is to allow the R user to explicitly add a finalizer, like we do for a document. */ SEXP R_addXMLNodeFinalizer(SEXP r_node) { #ifdef XML_REF_COUNT_NODES /* ??? should this be ifndef or ifdef.?? */ // xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); R_RegisterCFinalizer(r_node, decrementNodeRefCount); #endif return(r_node); } #define ValOrNULL(x) CHAR_TO_XMLCHAR ((x && x[0] ? x : NULL)) /** Write the XML tree/DOM to a file or into a buffer (depending on the value of sfileName) It would be nice to use connections, but this is not yet possible in full generality. Later @sdoc: the S object that is a reference to the top-level XML DOM. @sfileName: the S object that gives the name of the file to which the DOM should be written or alternatively, the S value `NULL' indicating that the DOM should be dumped to a buffer and returned as an S string. @compression: if @sfileName is the name of a file and we are not returning the DOM as a string, then we set the compression level to the value of this integer, unless it is omitted and specified as the S value `NULL'. */ USER_OBJECT_ R_saveXMLDOM(USER_OBJECT_ sdoc, USER_OBJECT_ sfileName, USER_OBJECT_ compression, USER_OBJECT_ sindent, USER_OBJECT_ prefix, USER_OBJECT_ r_encoding) { xmlDocPtr doc; const char *fileName = NULL; USER_OBJECT_ ans = NULL_USER_OBJECT; xmlDtdPtr dtd = NULL; int oldIndent = xmlIndentTreeOutput; const char *encoding = CHAR_DEREF(STRING_ELT(r_encoding, 0)); if(TYPEOF(sdoc) != EXTPTRSXP) { Rf_error("document passed to R_saveXMLDOM is not an external pointer"); } doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); if(doc == NULL) return(NEW_CHARACTER(0)); xmlIndentTreeOutput = LOGICAL_DATA(sindent)[0]; if(GET_LENGTH(prefix) == 3) { dtd = xmlNewDtd(doc, ValOrNULL(CHAR_DEREF(STRING_ELT(prefix, 0))), ValOrNULL(CHAR_DEREF(STRING_ELT(prefix, 1))), ValOrNULL(CHAR_DEREF(STRING_ELT(prefix, 2)))); dtd->parent = doc; dtd->doc = doc; dtd->prev = doc->children->prev; dtd->next = doc->children; doc->children->prev = (xmlNodePtr) dtd; doc->children = (xmlNodePtr) dtd; } /* Figure out what the name of the file is, or if it is NULL. */ if(GET_LENGTH(sfileName)) fileName = CHAR_DEREF(STRING_ELT(sfileName, 0)); /* If the user specified a file name, write to it and honor the compression setting they supplied. */ if(fileName && fileName[0]) { int compressionLevel = -1; if(GET_LENGTH(compression)) { compressionLevel = xmlGetDocCompressMode(doc); xmlSetDocCompressMode(doc, INTEGER_DATA(compression)[0]); } if(encoding && encoding[0]) // xmlSaveFileEnc doesn't indent. So use xmlSaveFormatFileEnc(). Issue identified by Earl Brown. // xmlSaveFileEnc(CHAR_DEREF(STRING_ELT(sfileName, 0)), doc, encoding); xmlSaveFormatFileEnc(CHAR_DEREF(STRING_ELT(sfileName, 0)), doc, encoding, LOGICAL_DATA(sindent)[0]); #if 0 else xmlSaveFile(CHAR_DEREF(STRING_ELT(sfileName, 0)), doc); #else else { FILE *f; f = fopen(CHAR_DEREF(STRING_ELT(sfileName, 0)), "w"); if(!f) { Rf_error("cannot create file %s. Check the directory exists and permissions are appropriate", CHAR_DEREF(STRING_ELT(sfileName, 0)) ); } xmlDocFormatDump(f, doc, 1); fclose(f); } #endif if(compressionLevel != -1) { xmlSetDocCompressMode(doc, compressionLevel); } } else { /* So we are writing to a buffer and returning the DOM as an S string. */ xmlChar *mem; int size; /*??? Do we need to allocate this memory? */ PROTECT(ans = NEW_CHARACTER(1)); if(encoding && encoding[0]) xmlDocDumpFormatMemoryEnc(doc, &mem, &size, encoding, LOGICAL_DATA(sindent)[0]); else { xmlDocDumpFormatMemory(doc, &mem, &size, 1); /* xmlDocDumpMemory(doc, &mem, &size); original */ } if(dtd) { xmlNodePtr tmp; doc->extSubset = NULL; tmp = doc->children->next; tmp->prev = NULL; doc->children = tmp; xmlFreeDtd(dtd); } if(mem) { DECL_ENCODING_FROM_DOC(doc) SET_STRING_ELT(ans, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(mem))); xmlFree(mem); } else { /*XXX get the error message from libxml2 */ Rf_error("failed to write XML document contents"); } UNPROTECT(1); return(ans); } xmlIndentTreeOutput = oldIndent; return(ans); } USER_OBJECT_ RS_XML_setDoc(USER_OBJECT_ snode, USER_OBJECT_ sdoc) { /*Might use xmlCopyNode or xmlCopyNodeList if we have to make a copy*/ xmlDocPtr doc; xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); if(sdoc != NULL_USER_OBJECT) { doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); } else { doc = xmlNewDoc(CHAR_TO_XMLCHAR("1.0")); R_numXMLDocs++; } xmlDocSetRootElement(doc, node); return(R_createXMLDocRef(doc)); } #if 0 void RS_XML_recursive_unsetDoc(xmlNodePtr node) { xmlNodePtr tmp; node->doc = NULL; tmp = node->children; while(tmp) { RS_XML_recursive_unsetDoc(tmp); tmp = tmp->next; } } #endif /* The following two routines are from Paul Murrell. They fix a problem with xpathApply() changing the document presumably when doing an XPath query on a node within a document. The old version didn't deal with the properties on the node. */ void RS_XML_recursive_unsetTreeDoc(xmlNodePtr node) { xmlAttrPtr prop; if (node == NULL) return; if(node->type == XML_ELEMENT_NODE) { prop = node->properties; while (prop != NULL) { prop->doc = NULL; RS_XML_recursive_unsetListDoc(prop->children); prop = prop->next; } } if (node->children != NULL) RS_XML_recursive_unsetListDoc(node->children); node->doc = NULL; } void RS_XML_recursive_unsetListDoc(xmlNodePtr list) { xmlNodePtr cur; if (list == NULL) return; cur = list; while (cur != NULL) { RS_XML_recursive_unsetTreeDoc(cur); cur = cur->next; } } USER_OBJECT_ RS_XML_unsetDoc(USER_OBJECT_ snode, USER_OBJECT_ unlink, USER_OBJECT_ r_parent, USER_OBJECT_ recursive) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); if(!node) { return(NULL_USER_OBJECT); } if(node->doc && node->doc->children == node) { xmlDocSetRootElement(node->doc, NULL); } if(LOGICAL(unlink)[0]) xmlUnlinkNode(node); node->doc = NULL; node->parent = NULL; if(r_parent != R_NilValue) { node->parent = (xmlNodePtr) R_ExternalPtrAddr(snode); } if(LOGICAL(recursive)[0]) { RS_XML_recursive_unsetTreeDoc(node); } return(ScalarLogical(TRUE)); } SEXP RS_XML_setDocEl(SEXP r_node, SEXP r_doc) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); xmlSetTreeDoc(node, doc); /* node->doc = doc; */ return(R_NilValue); } #ifdef ADD_XML_OUTPUT_BUFFER_CODE /* These two taken from libxml2-2.6.27 They are needed if xmlOutputBufferCreateBuffer() is not in the installed libxml2. It appeared in libxml2-2.6.23, released on Jan 5 2006 */ static int xmlBufferWrite (void * context, const char * buffer, int len) { int ret; ret = xmlBufferAdd((xmlBufferPtr) context, (const xmlChar *) buffer, len); if (ret != 0) return(-1); return(len); } xmlOutputBufferPtr xmlOutputBufferCreateBuffer(xmlBufferPtr buffer, xmlCharEncodingHandlerPtr encoder) { xmlOutputBufferPtr ret; if (buffer == NULL) return(NULL); ret = xmlOutputBufferCreateIO((xmlOutputWriteCallback) xmlBufferWrite, (xmlOutputCloseCallback) NULL, (void *) buffer, encoder); return(ret); } #endif /* Not completed. This could put the node into a new document and then call R_saveXMLDOM() but we are doing it in separate steps with separate C routines and calling these from R. xmlNodeDumpOutput Test: a = newXMLNode("a", "first bit", newXMLNode("b", "contents of b", newXMLNode("c", 3)), "more text") a = newXMLNode("a", newXMLNode("b", newXMLNode("c", 3))) .Call("RS_XML_printXMLNode", a, as.integer(1), as.integer(1), character()) */ USER_OBJECT_ RS_XML_printXMLNode(USER_OBJECT_ r_node, USER_OBJECT_ level, USER_OBJECT_ format, USER_OBJECT_ indent, USER_OBJECT_ r_encoding, USER_OBJECT_ r_encoding_int) { USER_OBJECT_ ans; xmlNodePtr node; const char *encoding = NULL; xmlOutputBufferPtr buf; xmlBufferPtr xbuf; int oldIndent; oldIndent = xmlIndentTreeOutput; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); xmlIndentTreeOutput = LOGICAL(indent)[0]; xbuf = xmlBufferCreate(); if(GET_LENGTH(r_encoding)) encoding = CHAR_DEREF(STRING_ELT(r_encoding, 0)); buf = xmlOutputBufferCreateBuffer(xbuf, NULL); // xmlKeepBlanksDefault(0); xmlNodeDumpOutput(buf, node->doc, node, INTEGER(level)[0], INTEGER(format)[0], encoding); xmlOutputBufferFlush(buf); xmlIndentTreeOutput = oldIndent; if(xbuf->use > 0) { /*XXX this const char * in CHARSXP means we have to make multiple copies. */ if(INTEGER(r_encoding_int)[0] == CE_NATIVE) ans = ScalarString(CreateCharSexpWithEncoding((const xmlChar *)encoding, (const xmlChar *)xbuf->content)); else ans = ScalarString(mkCharCE((const char *)xbuf->content, INTEGER(r_encoding_int)[0])); } else ans = NEW_CHARACTER(1); xmlOutputBufferClose(buf); return(ans); } SEXP R_setXMLInternalTextNode_noenc(SEXP node) { xmlNodePtr n = (xmlNodePtr) R_ExternalPtrAddr(node); if(!n) { Rf_error("null value passed for XMLInternalTextNode"); } n->name = (const xmlChar *) (&xmlStringTextNoenc); return(ScalarLogical(TRUE)); } SEXP /*R_setXMLInternalTextNode_value(SEXP node, SEXP value, SEXP r_encoding)*/ R_setXMLInternalTextNode_value(SEXP node, SEXP value) { xmlNodePtr n = (xmlNodePtr) R_ExternalPtrAddr(node); // xmlChar *tmp; const char *str; // DECL_ENCODING_FROM_NODE(n) if(n->type != XML_TEXT_NODE) { Rf_error( "Can only set value on an text node"); } str = CHAR(STRING_ELT(value, 0)); xmlNodeSetContent(n, (const xmlChar *)str); return(node); } SEXP R_xmlSetContent(SEXP node, SEXP content) { xmlNodePtr n = (xmlNodePtr) R_ExternalPtrAddr(node); xmlNodeSetContent(n, CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(content, 0)))); return(R_NilValue); } SEXP R_xmlNodeValue(SEXP node, SEXP raw, SEXP r_encoding) { xmlNodePtr n = (xmlNodePtr) R_ExternalPtrAddr(node); xmlChar *tmp; SEXP ans; DECL_ENCODING_FROM_NODE(n) if(!n) { Rf_error( "null value for xml node reference"); } tmp = xmlNodeGetContent(n); /* xmlGetNodeRawString xmlGetNodeString if(GET_LENGTH(raw) == 0) else if(LOGICAL(raw)[0]) { } else { } */ if(tmp) { if(INTEGER(r_encoding)[0] == CE_NATIVE) ans = ScalarString(CreateCharSexpWithEncoding(encoding, tmp)); else ans = ScalarString(mkCharCE((const char *)tmp, INTEGER(r_encoding)[0])); free(tmp); // ans = mkString(XMLCHAR_TO_CHAR(tmp)); // Just playing: ans = ScalarString(mkCharCE(tmp, CE_UTF8)); } else ans = NEW_CHARACTER(0); return(ans); } USER_OBJECT_ R_xmlNsAsCharacter(USER_OBJECT_ s_ns) { xmlNsPtr ns = NULL; USER_OBJECT_ ans, names; const xmlChar *encoding = NULL; ns = (xmlNsPtr) R_ExternalPtrAddr(s_ns); #ifdef LIBXML_NAMESPACE_HAS_CONTEXT encoding = ns->context ? ns->context->encoding : NULL; #endif PROTECT(ans = NEW_CHARACTER(2)); PROTECT(names = NEW_CHARACTER(2)); SET_STRING_ELT(names, 0, mkChar("prefix")); SET_STRING_ELT(names, 1, mkChar("href")); if(ns->prefix) SET_STRING_ELT(ans, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(ns->prefix))); if(ns->href) SET_STRING_ELT(ans, 1, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(ns->href))); SET_NAMES(ans, names); UNPROTECT(2); return(ans); } USER_OBJECT_ R_getXMLNodeDocument(USER_OBJECT_ s_node) { xmlNodePtr n = (xmlNodePtr) R_ExternalPtrAddr(s_node); if(!n->doc) return(NULL_USER_OBJECT); /*??? Does this arrange to free it? */ return(R_createXMLDocRef(n->doc)); } USER_OBJECT_ RS_XML_isDescendantOf(USER_OBJECT_ r_node, USER_OBJECT_ r_top, USER_OBJECT_ strict) { xmlNodePtr node, ptr, top; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); top = (xmlNodePtr) R_ExternalPtrAddr(r_top); if(!node || !top) { Rf_error( "null value passed to RS_XML_isDescendantOf"); } /*XXX */ if(node->type == XML_NAMESPACE_DECL) return(ScalarLogical(TRUE)); ptr = node; while(ptr && ptr->type != XML_DOCUMENT_NODE && ptr->type != XML_HTML_DOCUMENT_NODE) { if(ptr == top) return(ScalarLogical(ptr == node && LOGICAL(strict)[0] ? FALSE : TRUE)); ptr = ptr->parent; } return(ScalarLogical(FALSE)); } SEXP R_XML_indexOfChild(SEXP r_node) { xmlNodePtr node, ptr; // parent int i = 0; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); ptr = node->parent->children; while(ptr) { if(ptr == node) return(ScalarInteger(i + 1)); i++; ptr = ptr->next; } return(R_NilValue); } SEXP R_setNamespaceFromAncestors(SEXP r_node) { xmlNodePtr node, ptr; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); ptr = node->parent; while(ptr) { if((ptr->type != XML_HTML_DOCUMENT_NODE && ptr->type != XML_DOCUMENT_NODE) && ptr->ns && ptr->ns->href && (!ptr->ns->prefix || !ptr->ns->prefix[0])) { xmlSetNs(node, ptr->ns); return(ScalarLogical(TRUE)); } ptr = ptr->parent; } return(ScalarLogical(FALSE)); } #ifdef R_HAS_REMOVE_FINALIZERS int xmlNode_removeFinalizers(xmlNodePtr node) { xmlNodePtr tmp; int count = 0; #if R_XML_DEBUG fprintf(stderr, "xml removeFinalizers %p %s\n", node, node->name); #endif count = R_RemoveExtPtrWeakRef_direct(node); tmp = node->children; while(tmp) { count += xmlNode_removeFinalizers(tmp); tmp = tmp->next; } return(count); } SEXP R_xmlNode_removeFinalizers(SEXP r_node) { int num; xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); num = xmlNode_removeFinalizers(node); return(ScalarInteger(num)); } #endif SEXP R_xmlSearchNs(SEXP r_doc, SEXP r_node, SEXP r_ns, SEXP r_asPrefix) { const xmlChar * val; xmlNsPtr ns; xmlDocPtr doc = (r_doc == NULL_USER_OBJECT) ? NULL : R_ExternalPtrAddr(r_doc); xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); if(Rf_length(r_ns) == 0) return(NEW_CHARACTER(0)); val = (const xmlChar *)CHAR_DEREF(STRING_ELT(r_ns, 0)); ns = LOGICAL(r_asPrefix)[0] ? xmlSearchNs(doc, node, val) : xmlSearchNsByHref(doc, node, val); if(!ns) return(NEW_CHARACTER(0)); else { SEXP r_ans; PROTECT(r_ans = mkString((const char *)ns->href)); SET_NAMES(r_ans, mkString(ns->prefix ? XMLCHAR_TO_CHAR(ns->prefix) : "")); UNPROTECT(1); return(r_ans); } } USER_OBJECT_ R_getChildByIndex(USER_OBJECT_ r_node, USER_OBJECT_ r_index, USER_OBJECT_ r_addFinalizer) { xmlNodePtr node, ptr; int i = 0, idx; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); ptr = node->children; idx = INTEGER(r_index)[0]; while(ptr && i < idx) { ptr = ptr->next; i++; } return(R_createXMLNodeRef(ptr, r_addFinalizer)); } USER_OBJECT_ R_getChildByName(USER_OBJECT_ r_node, USER_OBJECT_ r_index, USER_OBJECT_ r_addFinalizer) { xmlNodePtr node, ptr; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); ptr = node->children; const char *name = CHAR_DEREF(STRING_ELT(r_index, 0)); while(ptr) { if(ptr->name && strcmp(name, (const char *)ptr->name) == 0) break; ptr = ptr->next; } return(R_createXMLNodeRef(ptr, r_addFinalizer)); } /* This is a C-level version equivalent to xmlApply(node, xmlValue) */ USER_OBJECT_ R_childStringValues(SEXP r_node, SEXP r_len, SEXP r_asVector, SEXP r_encoding, SEXP r_addNames) { xmlNodePtr node, kid; int len, i; SEXP ans, names = NULL; int asVector = LOGICAL(r_asVector)[0]; int encoding = INTEGER(r_encoding)[0]; xmlChar *tmp; int nprotect = 0; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); len = INTEGER(r_len)[0]; if(asVector) ans = NEW_CHARACTER(len); else ans = NEW_LIST(len); PROTECT(ans); nprotect++; if(LOGICAL(r_addNames)[0]) { PROTECT(names = NEW_CHARACTER(len)); nprotect++; } for(i = 0, kid = node->children; kid && i < len; i++, kid = kid->next) { tmp = xmlNodeGetContent(kid); SEXP val = mkCharCE((const char *)tmp, encoding); PROTECT(val); if(asVector) SET_STRING_ELT(ans, i, val); else SET_VECTOR_ELT(ans, i, ScalarString(val)); if(names && kid->name) { SET_STRING_ELT(names, i, mkCharCE((const char *)kid->name, encoding)); } UNPROTECT(1); } if(names) SET_NAMES(ans, names); UNPROTECT(nprotect); return(ans); } USER_OBJECT_ R_replaceNodeWithChildren(USER_OBJECT_ r_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); xmlNodePtr nxt = node->next; if(node->prev) { node->prev->next = node->children; node->children->prev = node->prev; } else if(node->parent) node->parent->children = node->children; if(node->children) { xmlNodePtr cur = node->children; while(cur->next) { cur->parent = node->parent; cur = cur->next; } cur->next = nxt; if(nxt) nxt->prev = cur; } return(NULL_USER_OBJECT); } XML/src/RSDTD.h0000644000175100001440000000277713607633744012602 0ustar hornikusers/* * See Copyright for the license status of this software. */ #ifndef RSDTD_H #define RSDTD_H #include "RSCommon.h" #define RS_XML(a) RS_XML_##a #ifdef FROM_GNOME_XML_DIR #include #include #include #include #include #else #if 0 /* Problems with xmlValidCtxt in libxml2-2.4.[n] where n >= 21*/ #include #endif #include #include #include #include #endif USER_OBJECT_ RS_XML(createDTDElement)(xmlElementPtr el); USER_OBJECT_ RS_XML(createDTDElementContents)(xmlElementContentPtr vals, xmlElementPtr el, int recursive); USER_OBJECT_ RS_XML(createDTDElementAttributes)(xmlAttributePtr vals, xmlElementPtr el); USER_OBJECT_ RS_XML(createDTDAttribute)(xmlAttributePtr val, xmlElementPtr el); USER_OBJECT_ RS_XML(AttributeEnumerationList)(xmlEnumerationPtr list, xmlAttributePtr attr, xmlElementPtr element); USER_OBJECT_ RS_XML(SequenceContent)(xmlElementContentPtr vals, xmlElementPtr el); USER_OBJECT_ RS_XML(ProcessElements)(xmlElementTablePtr table, xmlParserCtxtPtr ctxt); USER_OBJECT_ RS_XML(ProcessEntities)(xmlEntitiesTablePtr table, xmlParserCtxtPtr ctxt); USER_OBJECT_ RS_XML(createDTDEntity)(xmlEntityPtr entity); USER_OBJECT_ RS_XML(createDTDParts)(xmlDtdPtr dtd, xmlParserCtxtPtr ctxt); USER_OBJECT_ RS_XML(ConstructDTDList)(xmlDocPtr myDoc, int processInternals, xmlParserCtxtPtr ctxt); #endif XML/src/xpath.c0000644000175100001440000004341314327573457013035 0ustar hornikusers#include "RS_XML.h" #include #include "Utils.h" void xpathTolower(xmlXPathParserContextPtr ctxt, int nargs); void xpathGrepl(xmlXPathParserContextPtr ctxt, int nargs); void xpathReplace(xmlXPathParserContextPtr ctxt, int nargs); void xpathEndswith(xmlXPathParserContextPtr ctxt, int nargs); void xpathAbs(xmlXPathParserContextPtr ctxt, int nargs); void xpathBaseURI(xmlXPathParserContextPtr ctxt, int nargs); void xpathMin(xmlXPathParserContextPtr ctxt, int nargs); void xpathMax(xmlXPathParserContextPtr ctxt, int nargs); void R_genericXPathFun(xmlXPathParserContextPtr ctxt, int nargs); void R_genericAnonXPathFun(xmlXPathParserContextPtr ctxt, int nargs); static SEXP convertNodeSetToR(xmlNodeSetPtr obj, SEXP fun, int encoding, SEXP manageMemory) { SEXP ans, expr = NULL, arg = NULL, ref; int i; int nprot = 0; if(!obj) return(NULL_USER_OBJECT); PROTECT(ans = NEW_LIST(obj->nodeNr)); nprot++; if(GET_LENGTH(fun) && (TYPEOF(fun) == CLOSXP || TYPEOF(fun) == BUILTINSXP)) { PROTECT(expr = allocVector(LANGSXP, 2)); nprot++; SETCAR(expr, fun); arg = CDR(expr); } else if(TYPEOF(fun) == LANGSXP) { // change from Tomas Kalibera 2016-11-10 PROTECT(expr = duplicate(fun)); nprot++; arg = CDR(expr); } for(i = 0; i < obj->nodeNr; i++) { xmlNodePtr el; el = obj->nodeTab[i]; if(el->type == XML_ATTRIBUTE_NODE) { #if 0 PROTECT(ref = mkString((el->children && el->children->content) ? XMLCHAR_TO_CHAR(el->children->content) : "")); nprot++; SET_NAMES(ref, mkString(el->name)); #else PROTECT(ref = ScalarString(mkCharCE((el->children && el->children->content) ? XMLCHAR_TO_CHAR(el->children->content) : "", encoding))); SET_NAMES(ref, ScalarString(mkCharCE((const char *)el->name, encoding))); #endif SET_CLASS(ref, mkString("XMLAttributeValue")); UNPROTECT(1); } else if(el->type == XML_NAMESPACE_DECL) ref = R_createXMLNsRef((xmlNsPtr) el); else ref = R_createXMLNodeRef(el, manageMemory); if(expr) { PROTECT(ref); SETCAR(arg, ref); PROTECT(ref = Rf_eval(expr, R_GlobalEnv)); /*XXX do we want to catch errors here? Maybe to release the namespaces. */ SET_VECTOR_ELT(ans, i, ref); UNPROTECT(2); } else SET_VECTOR_ELT(ans, i, ref); } // change from Tomas Kalibera 2016-11-10 if(!expr) SET_CLASS(ans, mkString("XMLNodeSet")); UNPROTECT(nprot); return(ans); } SEXP convertXPathObjectToR(xmlXPathObjectPtr obj, SEXP fun, int encoding, SEXP manageMemory) { SEXP ans = NULL_USER_OBJECT; switch(obj->type) { case XPATH_NODESET: ans = convertNodeSetToR(obj->nodesetval, fun, encoding, manageMemory); break; case XPATH_BOOLEAN: ans = ScalarLogical(obj->boolval); break; case XPATH_NUMBER: ans = ScalarReal(obj->floatval); if(xmlXPathIsInf(obj->floatval)) REAL(ans)[0] = xmlXPathIsInf(obj->floatval) < 0 ? R_NegInf : R_PosInf; else if(xmlXPathIsNaN(obj->floatval)) REAL(ans)[0] = NA_REAL; break; case XPATH_STRING: ans = mkString(XMLCHAR_TO_CHAR(obj->stringval)); //XXX encoding break; // Next three not currently in xmlXPathObjectType #ifdef LIBXML_XPTR_LOCS_ENABLED case XPATH_POINT: case XPATH_RANGE: case XPATH_LOCATIONSET: #endif case XPATH_USERS: Rf_warning("currently unsupported xmlXPathObject type %d in convertXPathObjectToR. Please send mail to maintainer.", obj->type); default: ans = R_NilValue; } return(ans); } #include /* For xmlXPathRegisterNs() */ xmlNsPtr * R_namespaceArray(SEXP namespaces, xmlXPathContextPtr ctxt) { int i, n; SEXP names = GET_NAMES(namespaces); xmlNsPtr *els; n = GET_LENGTH(namespaces); els = xmlMallocAtomic(sizeof(xmlNsPtr) * n); if(!els) { Rf_error( "Failed to allocate space for namespaces"); } for(i = 0; i < n; i++) { /*XXX who owns these strings. */ const xmlChar *prefix, *href; href = CHAR_TO_XMLCHAR(strdup(CHAR_DEREF(STRING_ELT(namespaces, i)))); prefix = names == NULL_USER_OBJECT ? CHAR_TO_XMLCHAR("") /* NULL */ : CHAR_TO_XMLCHAR(strdup(CHAR_DEREF(STRING_ELT(names, i)))); els[i] = xmlNewNs(NULL, href, prefix); if(ctxt) xmlXPathRegisterNs(ctxt, prefix, href); } return(els); } #if R_XML_DEBUG_WEAK_REFS SEXP LastDoc = NULL; SEXP R_isWeakRef(SEXP sdoc) { void *ptr; if(sdoc == R_NilValue) { if(LastDoc == NULL) return(R_NilValue); sdoc = LastDoc; } ptr = R_ExternalPtrAddr(sdoc); return(ScalarLogical(R_findExtPtrWeakRef(ptr))); } #endif SEXP R_addXMLInternalDocument_finalizer(SEXP sdoc, SEXP fun) { R_CFinalizer_t action = NULL; #if R_XML_DEBUG_WEAK_REFS LastDoc = sdoc; #endif if(TYPEOF(fun) == CLOSXP) { R_RegisterFinalizer(sdoc, fun); return(sdoc); } if(fun == R_NilValue) { action = R_xmlFreeDoc; } else if(TYPEOF(fun) == EXTPTRSXP) action = (R_CFinalizer_t) R_ExternalPtrAddr(fun); R_RegisterCFinalizer(sdoc, action); #ifdef R_XML_DEBUG_WEAK_REFS void *ptr = R_ExternalPtrAddr(sdoc); int status = R_findExtPtrWeakRef(ptr); fprintf(stderr, "is weak ref %d\n", status); #endif return(sdoc); } SEXP R_XMLInternalDocument_free(SEXP sdoc) { if(TYPEOF(sdoc) != EXTPTRSXP || R_ExternalPtrTag(sdoc) != Rf_install("XMLInternalDocument")) { Rf_error("R_free must be given an internal XML document object, 'XMLInternalDocument'"); } R_xmlFreeDoc(sdoc); return(sdoc); } /* This may go into the context object */ static SEXP R_AnonXPathFuns = NULL; SEXP RS_XML_xpathEval(SEXP sdoc, SEXP r_node, SEXP path, SEXP namespaces, SEXP fun, SEXP charEncoding, SEXP manageMemory, SEXP xpathFuns, SEXP anonFuns) { xmlXPathContextPtr ctxt = NULL; xmlXPathObjectPtr result; SEXP ans = NULL_USER_OBJECT; xmlDocPtr doc; if(TYPEOF(sdoc) != EXTPTRSXP || R_ExternalPtrTag(sdoc) != Rf_install("XMLInternalDocument")) { Rf_error("xpathEval must be given an internal XML document object, 'XMLInternalDocument'"); } doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); ctxt = xmlXPathNewContext(doc); if(GET_LENGTH(r_node)) { ctxt->node = ctxt->origin = R_ExternalPtrAddr(r_node); } if(GET_LENGTH(namespaces)) { ctxt->namespaces = R_namespaceArray(namespaces, ctxt); /* xmlCopyNamespaceList(doc); */ ctxt->nsNr = GET_LENGTH(namespaces); } xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lower-case", xpathTolower); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ends-with", xpathEndswith); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"matches", xpathGrepl); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"replace", xpathReplace); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"abs", xpathAbs); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"base-uri", xpathBaseURI); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"min", xpathMin); xmlXPathRegisterFunc(ctxt, (const xmlChar *)"max", xpathMax); R_AnonXPathFuns = anonFuns; if(Rf_length(xpathFuns)) { SEXP names = GET_NAMES(xpathFuns), el; int i; xmlXPathFunction routine; const xmlChar *id; for(i = 0; i < Rf_length(xpathFuns); i++) { el = VECTOR_ELT(xpathFuns, i); id = (names != R_NilValue) ? (const xmlChar *)CHAR(STRING_ELT(names, i)) : NULL; if(TYPEOF(el) == EXTPTRSXP) { routine = R_ExternalPtrAddr(el); if(!id) { Rf_error("no name for XPath function routine"); } } else if(TYPEOF(el) == CLOSXP) { routine = R_genericAnonXPathFun; } else { routine = R_genericXPathFun; if(TYPEOF(el) == STRSXP) id = (const xmlChar *)CHAR(STRING_ELT(el, 0)); } xmlXPathRegisterFunc(ctxt, id, routine); } } result = xmlXPathEvalExpression(CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(path, 0))), ctxt); if(result) ans = convertXPathObjectToR(result, fun, INTEGER(charEncoding)[0], manageMemory); xmlXPathFreeObject(result); xmlXPathFreeContext(ctxt); R_AnonXPathFuns = NULL; if(!result) { Rf_error( "error evaluating xpath expression %s", CHAR_DEREF(STRING_ELT(path, 0))); } return(ans); } USER_OBJECT_ RS_XML_createDocFromNode(USER_OBJECT_ s_node) { xmlDocPtr doc; xmlNodePtr node, ptr; SEXP ans; node = (xmlNodePtr) R_ExternalPtrAddr(s_node); doc = xmlNewDoc(CHAR_TO_XMLCHAR("1.0")); R_numXMLDocs++; ptr = xmlDocCopyNode(node, doc, 1); node = (xmlNodePtr) doc; xmlAddChild(node, ptr); ans = R_createXMLDocRef(doc); return(ans); } USER_OBJECT_ RS_XML_copyNodesToDoc(USER_OBJECT_ s_node, USER_OBJECT_ s_doc, USER_OBJECT_ manageMemory) { xmlDocPtr doc; xmlNodePtr node, ptr; int len, i; SEXP ans; doc = (xmlDocPtr) R_ExternalPtrAddr(s_doc); if(TYPEOF(s_node) == EXTPTRSXP) { node = (xmlNodePtr) R_ExternalPtrAddr(s_node); ptr = xmlDocCopyNode(node, doc, 1); return(R_createXMLNodeRef(ptr, manageMemory)); } len = Rf_length(s_node); PROTECT(ans = NEW_LIST(len)); for(i = 0; i < len; i++) { node = (xmlNodePtr) R_ExternalPtrAddr(VECTOR_ELT(s_node, i)); ptr = xmlDocCopyNode(node, doc, 1); SET_VECTOR_ELT(ans, i, R_createXMLNodeRef(ptr, manageMemory)); } UNPROTECT(1); return(ans); } /* Thoughts that we could set the kids to NULL and then free the doc after we createDocFromNode but the return of xpathApply will return these nodes and we need to be able to get to a document */ SEXP RS_XML_killNodesFreeDoc(SEXP sdoc) { xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); if(!doc) { Rf_warning("null xmlDocPtr passed as externalptr to RS_XML_killNodesFreeDoc"); return(ScalarLogical(FALSE)); } doc->children = NULL; xmlFree(doc); return(ScalarLogical(TRUE)); } #if 0 SEXP RS_XML_xpathNodeEval(SEXP s_node, SEXP path, SEXP namespaces, SEXP fun) { xmlXPathContextPtr ctxt = NULL; xmlXPathObjectPtr result; SEXP ans = NULL_USER_OBJECT; xmlDocPtr doc; if(TYPEOF(s_node) != EXTPTRSXP || R_ExternalPtrTag(s_node) != Rf_install("XMLInternalNode")) { Rf_error("xpathEval must be given an internal XML document object, 'XMLInternalNode'"); } ctxt = xmlXPathNewContext(doc); if(GET_LENGTH(namespaces)) { ctxt->namespaces = R_namespaceArray(namespaces, ctxt); /* xmlCopyNamespaceList(doc); */ ctxt->nsNr = GET_LENGTH(namespaces); } result = xmlXPathEvalExpression(CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(path, 0))), ctxt); if(result) ans = convertXPathObjectToR(result, fun); xmlXPathFreeObject(result); xmlXPathFreeContext(ctxt); if(!result) { Rf_error( "error evaluating xpath expression %s", CHAR_DEREF(STRING_ELT(path, 0))); } return(ans); } #endif SEXP R_matchNodesInList(SEXP r_nodes, SEXP r_target, SEXP r_nomatch) { xmlNodePtr el; int i, j, n, n2; SEXP ans; n = GET_LENGTH(r_nodes); n2 = GET_LENGTH(r_target); ans = NEW_INTEGER( n ); for(i = 0; i < n ; i++) { el = R_ExternalPtrAddr(VECTOR_ELT(r_nodes, i)); INTEGER(ans)[i] = INTEGER(r_nomatch)[0]; for(j = 0; j < n2; j++) { if(el == R_ExternalPtrAddr(VECTOR_ELT(r_target, j))) { INTEGER(ans)[i] = j; break; } } } return(ans); } #if 0 /* taken from Sxslt and should be left there or moved here.*/ USER_OBJECT_ RXSLT_export_xmlXPathObject(xmlNodeSetPtr val, const char * className) { USER_OBJECT_ ans; USER_OBJECT_ klass; PROTECT(klass = MAKE_CLASS(className)); PROTECT(ans = NEW(klass)); SET_SLOT(ans, Rf_install("ref"), R_MakeExternalPtr(val, Rf_install(className), R_NilValue)); UNPROTECT(2); return(ans); } USER_OBJECT_ R_xmlXPathNewNodeSet(USER_OBJECT_ s_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(s_node); xmlXPathObjectPtr nodeset; nodeset = xmlXPathNewNodeSet(node); return(RXSLT_export_xmlXPathObject(nodeset->nodesetval, "XPathNodeSet")); } #endif #include /* XXX Does not handle unicode in any way. Very simple-minded for now. */ void xpathTolower(xmlXPathParserContextPtr ctxt, int nargs) { if(nargs == 0) return; xmlXPathObjectPtr obj = valuePop(ctxt); if (obj->type != XPATH_STRING) { valuePush(ctxt, obj); xmlXPathStringFunction(ctxt, 1); obj = valuePop(ctxt); } xmlChar *str = xmlStrdup(obj->stringval); // xmlChar *ptr = str; int i, n = xmlStrlen(str); for(i = 0; i < n ; i++) str[i] = (xmlChar)tolower(str[i]); valuePush(ctxt, xmlXPathNewString(str)); } void xpathEndswith(xmlXPathParserContextPtr ctxt, int nargs) { if(nargs < 2) return; xmlChar *pattern = xmlXPathPopString(ctxt); xmlChar *input = xmlXPathPopString(ctxt); int i, n = xmlStrlen(input), lenPattern = xmlStrlen(pattern); if(n < lenPattern) xmlXPathReturnBoolean(ctxt, 0); xmlChar *ptr = input + n - lenPattern; for(i = 0; i < lenPattern ; i++) { if(ptr[i] != pattern[i]) break; } xmlXPathReturnBoolean(ctxt, i == lenPattern); } void xpathAbs(xmlXPathParserContextPtr ctxt, int nargs) { if(nargs < 1) return; double num = xmlXPathPopNumber(ctxt); xmlXPathReturnNumber(ctxt, num < 0 ? - num : num); } void xpathBaseURI(xmlXPathParserContextPtr ctxt, int nargs) { xmlDocPtr doc; if(nargs == 0) { doc = ctxt->context->doc; } else { xmlXPathObjectPtr obj = valuePop(ctxt); if(obj->type != XPATH_NODESET) return; xmlNodePtr node = obj->nodesetval->nodeTab[0]; doc = node->doc; } xmlXPathReturnString(ctxt, xmlStrdup((doc && doc->URL) ? doc->URL : (const xmlChar *)"")); } #define MIN(x, y) (x) < (y) ? (x) : (y) #define MAX(x, y) (x) > (y) ? (x) : (y) void xpathExtreme(xmlXPathParserContextPtr ctxt, int nargs, int isMax) { if(nargs < 1) return; double ans = 0; int set = 0; int i, a; xmlXPathObjectPtr obj; double tmp = 0.0; for(a = 0; a < nargs; a++) { obj = valuePop(ctxt); if(obj->type == XPATH_NODESET) { for(i = 0; i < obj->nodesetval->nodeNr; i++) { tmp = xmlXPathCastNodeToNumber(obj->nodesetval->nodeTab[i]); if(set) ans = isMax ? MAX(tmp, ans) : MIN(tmp, ans); else { ans = tmp; set = 1; } } } else if(obj->type == XPATH_NUMBER) { if(set) ans = isMax ? MAX(tmp, ans) : MIN(tmp, ans); else { ans = tmp; set = 1; } } xmlXPathFreeObject(obj); } xmlXPathReturnNumber(ctxt, ans); } void xpathMin(xmlXPathParserContextPtr ctxt, int nargs) { xpathExtreme(ctxt, nargs, 0); } void xpathMax(xmlXPathParserContextPtr ctxt, int nargs) { xpathExtreme(ctxt, nargs, 1); } void xpathGrepl(xmlXPathParserContextPtr ctxt, int nargs) { if(nargs < 2) return; xmlChar *pattern = xmlXPathPopString(ctxt); xmlChar *input = xmlXPathPopString(ctxt); SEXP e = Rf_allocVector(LANGSXP, 3); PROTECT(e); SETCAR(e, Rf_install("grepl")); SETCAR(CDR(e), ScalarString(mkChar((const char *)pattern))); SETCAR(CDR(CDR(e)), ScalarString(mkChar((const char *)input))); SEXP ans = Rf_eval(e, R_GlobalEnv); xmlXPathReturnBoolean(ctxt, INTEGER(ans)[0]); UNPROTECT(1); } void xpathReplace(xmlXPathParserContextPtr ctxt, int nargs) { if(nargs < 3) return; xmlChar *replacement = xmlXPathPopString(ctxt); xmlChar *pattern = xmlXPathPopString(ctxt); xmlChar *input = xmlXPathPopString(ctxt); SEXP e = Rf_allocVector(LANGSXP, 4); PROTECT(e); SEXP cur = e; SETCAR(e, Rf_install("gsub")); cur = CDR(cur); SETCAR(cur, ScalarString(mkChar((const char *)pattern))); cur = CDR(cur); SETCAR(cur, ScalarString(mkChar((const char *)replacement))); cur = CDR(cur); SETCAR(cur, ScalarString(mkChar((const char *)input))); SEXP ans = Rf_eval(e, R_GlobalEnv); xmlXPathReturnString(ctxt, xmlStrdup((const xmlChar *)CHAR(STRING_ELT(ans, 0)))); UNPROTECT(1); } SEXP convertXPathVal(xmlXPathObjectPtr xval) { SEXP ans = R_NilValue; switch(xval->type) { case XPATH_BOOLEAN: ans = ScalarLogical(xval->boolval); break; case XPATH_NUMBER: ans = ScalarReal(xval->floatval); break; case XPATH_STRING: ans = ScalarString(mkChar((const char *)xval->stringval)); break; case XPATH_NODESET: { SEXP tmp = ScalarLogical(FALSE); PROTECT(tmp); ans = convertXPathObjectToR(xval, R_NilValue, 0, tmp); UNPROTECT(1); } break; default: Rf_warning("converting an XPath type %d to R not supported now", xval->type); } return(ans); } void R_pushResult(xmlXPathParserContextPtr ctxt, SEXP ans) { switch(TYPEOF(ans)) { case LGLSXP: xmlXPathReturnBoolean(ctxt, INTEGER(ans)[0]); break; case INTSXP: xmlXPathReturnNumber(ctxt, INTEGER(ans)[0]); break; case REALSXP: xmlXPathReturnNumber(ctxt, REAL(ans)[0]); break; case STRSXP: xmlXPathReturnString(ctxt, xmlStrdup((const xmlChar *)CHAR(STRING_ELT(ans, 0)))); break; default: Rf_error("R type not supported as result of XPath function"); } } void R_callGenericXPathFun(xmlXPathParserContextPtr ctxt, int nargs, SEXP fun) { SEXP e = Rf_allocVector(LANGSXP, nargs + 1); PROTECT(e); SETCAR(e, fun); SEXP cur = CDR(e); xmlXPathObjectPtr tmp; int j; for(int i = nargs ; i > 0; i--) { /* The arguments are on the stack with the last on the top, second to last next, and so on. So we have to add them to our expression starting at the end. */ cur = e; for(j = 0 ; j < i; j++) cur = CDR(cur); tmp = valuePop(ctxt); SETCAR(cur, convertXPathVal(tmp)); xmlXPathFreeObject(tmp); } SEXP ans = Rf_eval(e, R_GlobalEnv); PROTECT(ans); R_pushResult(ctxt, ans); UNPROTECT(2); } void R_genericAnonXPathFun(xmlXPathParserContextPtr ctxt, int nargs) { if(!R_AnonXPathFuns || R_AnonXPathFuns == R_NilValue) return; int i, n = Rf_length(R_AnonXPathFuns); SEXP names = GET_NAMES(R_AnonXPathFuns); for(i = 0; i < n; i++) { if(strcmp((const char *)ctxt->context->function, CHAR(STRING_ELT(names, i))) == 0) { R_callGenericXPathFun(ctxt, nargs, VECTOR_ELT(R_AnonXPathFuns, i)); return; } } } void R_genericXPathFun(xmlXPathParserContextPtr ctxt, int nargs) { SEXP f = Rf_install((const char *)ctxt->context->function); PROTECT(f); R_callGenericXPathFun(ctxt, nargs, f); UNPROTECT(1); } XML/src/EventParse.h0000644000175100001440000001234313610555146013755 0ustar hornikusers/* * See Copyright for the license status of this software. */ #ifndef EVENT_PARSE_H #define EVENT_PARSE_H #include #include #include "RSCommon.h" #include "RS_XML.h" #ifdef LIBEXPAT #include "xmlparse.h" #else typedef char XML_Char; #endif #ifdef FROM_GNOME_XML_DIR #include #else #include #endif /* Extensible Struct for carrying information about the parser and its options as specified by the caller from R or S. */ typedef struct { /** The name of the source file which is being parsed. */ char *fileName; /** Flag indicating whether blank (white-space only) text entries should be discarded and not reported. */ int ignoreBlankLines; /** Flag indicating whether the methods in the user-level functions should be invoked with additional information about the current context of the parser, specifically the level or depth of the current node in the tree, potentially the index sequence (i_child1, i_child2, i_child3,...) which identifies the node relative to the root of the tree. Specify this in the call to xmlEventParse(). */ int addContextInfo; /* Flag indicating whether an attempt should be made when calling startElement to lookup a method matching the tag name rather than the vanilla startElement method. Set this in the call xmlEventParse(). */ int callByTagName; /* The R object in which to search for appropriate methods, usually a closure. */ USER_OBJECT_ methods; USER_OBJECT_ endElementHandlers; /* The current depth in the XML document tree. Used when constructing */ int depth; /* Flag indicating whether we should trim the */ int trim; /* S object used in event parsing to share state across calls. */ USER_OBJECT_ stateObject; /* For identifying which element names are to be created into regular nodes. */ USER_OBJECT_ branches; xmlNodePtr current; xmlNodePtr top; int branchIndex; /* */ int useDotNames; /* The XML context */ xmlParserCtxtPtr ctx; /* A function which is used to process a branch "anonymously, i.e not one that is actively identified in the branches = list(....) but a function that is returned from a regular startElement handler that indicates collect up the node and call this. */ USER_OBJECT_ dynamicBranchFunction; USER_OBJECT_ finalize; } RS_XMLParserData; /* The name of the R element to call fo the general case. if useDotNames is on, then we paste a . to the regular name. */ #define HANDLER_FUN_NAME(ctx, txt) \ ((RS_XMLParserData *)(ctx))->useDotNames ? "." txt : txt void R_processBranch(RS_XMLParserData * rinfo, int branchIndex, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes, Rboolean sax1); int R_isBranch(const xmlChar *localname, RS_XMLParserData *rinfo); void R_endBranch(RS_XMLParserData *rinfo, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI); #if 0 typedef struct NodeList NodeList; struct NodeList { xmlNodePtr *el; NodeList *next }; #endif /* Allocate a data structure for use with the parser */ RS_XMLParserData *createRSXMLParserData(USER_OBJECT_ handlers) ; USER_OBJECT_ RS_XML(callUserFunction)(const char *opName, const char *preferredName, RS_XMLParserData *parser, USER_OBJECT_ opArgs) ; /*Made static now: USER_OBJECT_ RS_XML(createAttributesList)(const char **atts); */ void RS_XML(entityDeclarationHandler)(void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); void RS_XML(entityDeclarationHandler)(void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); void RS_XML(commentHandler)(void *userData, const XML_Char *data); void RS_XML(endElement)(void *userData, const char *name); void RS_XML(startElement)(void *userData, const char *name, const char **atts); void RS_XML(processingInstructionHandler)(void *userData, const XML_Char *target, const XML_Char *data); void RS_XML(textHandler)(void *userData, const XML_Char *s, int len); void RS_XML(startCdataSectionHandler)(void *userData) ; void RS_XML(endCdataSectionHandler)(void *userData) ; RS_XMLParserData *RS_XML(createParserData)(USER_OBJECT_ handlers, USER_OBJECT_ finalize); int RS_XML(parseBufferWithParserData)(char *buf, RS_XMLParserData *parserData); int RS_XML(notStandAloneHandler)(void *userData); int RS_XML(libXMLEventParse)(const char *fileName, RS_XMLParserData *parserData, RS_XML_ContentSourceType asText, int saxVersion, USER_OBJECT_ r_encoding); USER_OBJECT_ findEndElementFun(const char *name, RS_XMLParserData *rinfo); void updateState(USER_OBJECT_ val, RS_XMLParserData *parserData); #endif XML/src/xmlsecurity.c0000644000175100001440000000123713607643022014261 0ustar hornikusers#ifdef HAVE_LIBXMLSEC #include #include #include #include "Rinternals.h" void R_xmlSecCryptoInit(int *els) { int status; els[0] = status = xmlSecCryptoInit(); if(status != 0) return; els[1] = status = xmlSecCryptoAppInit(NULL); if(status != 0) return; els[2] = status = xmlSecCryptoInit(); } SEXP R_xmlSecCryptoShutdown() { int status; status = xmlSecCryptoShutdown(); return(ScalarInteger(status)); } #else // avoid a warning about an empty translation unit. // instead, this gives one about an unused variable! // static int foo; void R_xmlSecCryptoInit(int *els) {} #endif XML/src/Makevars.ucrt0000644000175100001440000000057114023353273014174 0ustar hornikusersPKG_CPPFLAGS= -I${LOCAL_SOFT}/include/libxml2 -I${LIB_XML}/include -D_R_=1 -DUSE_R=1 -DUSE_XML_VERSION_H=1 -DLIBXML -DUSE_EXTERNAL_SUBSET=1 -DROOT_HAS_DTD_NODE=1 -DUMP_WITH_ENCODING=1 -DXML_ELEMENT_ETYPE=1 -DXML_ATTRIBUTE_ATYPE=1 -DLIBXML2=1 -DHAVE_XML_HAS_FEATURE -DLIBXML_STATIC -DNO_XML_HASH_SCANNER_RETURN=1 PKG_LIBS = -L${LIB_XML}/lib -lxml2 -liconv -lz -llzma -lws2_32 XML/src/HTMLParse.c0000644000175100001440000000774614106741723013445 0ustar hornikusers/* This file uses the HTML parser in libxml to provide an HTML parser in R that is basically identical to the XML parsing interface. It can handle files, URLs, compressed files, and raw HTML text. It drops the DTD and validation options since these are not very relevant for HTML. (We can add put them back if anyone wants!) */ #include "DocParse.h" #include "Utils.h" #include "libxml/HTMLparser.h" #include "libxml/HTMLtree.h" #include #include USER_OBJECT_ RS_XML(HtmlParseTree)(USER_OBJECT_ fileName, USER_OBJECT_ converterFunctions, USER_OBJECT_ skipBlankLines, USER_OBJECT_ replaceEntities, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ isURL) { const char *name; xmlDocPtr doc; USER_OBJECT_ rdoc; USER_OBJECT_ className; R_XMLSettings parserSettings; int freeName = 0; int asTextBuffer = LOGICAL_DATA(asText)[0]; int isURLDoc = LOGICAL_DATA(isURL)[0]; parserSettings.skipBlankLines = LOGICAL_DATA(skipBlankLines)[0]; parserSettings.converters = converterFunctions; parserSettings.trim = LOGICAL_DATA(trim)[0]; if(asTextBuffer == 0) { struct stat tmp_stat; #ifdef USE_R name = CHAR(STRING_ELT(fileName, 0)); #else name = CHARACTER_DATA(fileName)[0]; #endif if(!isURLDoc && (name == NULL || stat(name, &tmp_stat) < 0)) { Rf_error("Can't find file %s", CHAR_DEREF(STRING_ELT(fileName, 0)) ); } } else { name = strdup(CHAR_DEREF(STRING_ELT(fileName, 0))); freeName = 1; } #if 0 /* If one wants entities expanded directly and to appear as text. */ if(LOGICAL_DATA(replaceEntities)[0]) xmlSubstituteEntitiesDefault(1); #endif if(asTextBuffer) { doc = htmlParseDoc(CHAR_TO_XMLCHAR(name), NULL); if(doc != NULL) { doc->name = (char *) xmlStrdup(CHAR_TO_XMLCHAR("")); } } else { doc = htmlParseFile(name, NULL); } if(doc == NULL) { if(freeName && name) free((char *) name); Rf_error("error in creating parser for %s", name); } PROTECT(rdoc = RS_XML(convertXMLDoc)(name, doc, converterFunctions, &parserSettings)); if(freeName && name) free((char *) name); #if 0 xmlFreeDoc(doc); R_numXMLDocsFreed++; #endif /* Set the class for the document. */ className = NEW_CHARACTER(1); PROTECT(className); SET_STRING_ELT(className, 0, mkChar("HTMLDocument")); SET_CLASS(rdoc, className); UNPROTECT(1); UNPROTECT(1); return(rdoc); } /* Copied from RS_XML_printXMLNode (XMLTree.c) with minor changes. */ USER_OBJECT_ RS_XML_dumpHTMLDoc(USER_OBJECT_ r_node, USER_OBJECT_ format, USER_OBJECT_ r_encoding, USER_OBJECT_ indent, USER_OBJECT_ outFile) { USER_OBJECT_ ans; xmlDocPtr node; const char *encoding = NULL; xmlOutputBufferPtr buf; xmlBufferPtr xbuf; int oldIndent; oldIndent = xmlIndentTreeOutput; node = (xmlDocPtr) R_ExternalPtrAddr(r_node); xmlIndentTreeOutput = LOGICAL(indent)[0]; #if ADD_XML_OUTPUT_BUFFER_CODE if(Rf_length(outFile)) { htmlSaveFile(CHAR_DEREF(STRING_ELT(outFile, 0)), node); return(R_NilValue); } #endif if(GET_LENGTH(r_encoding)) encoding = CHAR_DEREF(STRING_ELT(r_encoding, 0)); xbuf = xmlBufferCreate(); #if 1 buf = xmlOutputBufferCreateBuffer(xbuf, NULL); #else buf = xmlOutputBufferCreateFilename("/tmp/test.out", NULL, 0); #endif htmlDocContentDumpFormatOutput(buf, node, encoding, INTEGER(format)[0]); xmlOutputBufferFlush(buf); xmlIndentTreeOutput = oldIndent; if(xbuf->use > 0) { /*XXX this const char * in CHARSXP means we have to make multiple copies. */ #if 0 char *rbuf = R_alloc(sizeof(char) * (xbuf->use + 1)); memcpy(rbuf, xbuf->content, xbuf->use + 1); PROTECT(tmp = mkChar(rbuf)); #endif // ans = ScalarString(mkChar(xbuf->content)); DECL_ENCODING_FROM_DOC(node) ans = ScalarString(ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(xbuf->content))); } else ans = NEW_CHARACTER(1); xmlOutputBufferClose(buf); return(ans); } XML/src/DocParse.c0000644000175100001440000012402514552751546013405 0ustar hornikusers/** Routines for parsing and processing an XML document into an R/S data structure. * See Copyright for the license status of this software. */ #include "DocParse.h" #define R_USE_XML_ENCODING 1 #include "Utils.h" /* For isBlank() */ /* For the call to stat. */ #include #include #include "RSDTD.h" #include #include #include int RS_XML(setNodeClass)(xmlNodePtr node, USER_OBJECT_ ans); USER_OBJECT_ RS_XML(notifyNamespaceDefinition)(USER_OBJECT_ ns, R_XMLSettings *parserSettings); void RS_XML(ValidationWarning)(void *ctx, const char *msg, ...); void RS_XML(ValidationError)(void *ctx, const char *msg, ...); static USER_OBJECT_ convertNode(USER_OBJECT_ ans, xmlNodePtr node, R_XMLSettings *parserSettings); static void NodeTraverse(xmlNodePtr doc, USER_OBJECT_ converterFunctions, R_XMLSettings *parserSettings, int rootFirst); static USER_OBJECT_ makeSchemaReference(xmlSchemaPtr ref); USER_OBJECT_ RS_XML(libxmlVersionRuntime)(void) { return(mkString( #if LIBXML_VERSION < 21200 *__xmlParserVersion() #else xmlParserVersion #endif )); } USER_OBJECT_ RS_XML(getDefaultValiditySetting)(USER_OBJECT_ val) { #ifdef HAVE_VALIDITY // extern int xmlDoValidityCheckingDefaultValue; USER_OBJECT_ ans; ans = NEW_INTEGER(1); INTEGER_DATA(ans)[0] = xmlDoValidityCheckingDefaultValue; if(GET_LENGTH(val)) xmlDoValidityCheckingDefaultValue = INTEGER_DATA(val)[0]; return(ans); #else return(NEW_INTEGER(0)); #endif } #include void R_xmlStructuredErrorHandler(void *data, xmlErrorPtr err) { RSXML_structuredStop((SEXP) data, err); } /** Entry point for reading, parsing and converting an XML tree to an R object. fileName is the string identifying the file, and is expanded using the normal rules for an R file name. That is, it can contain environment variables, ~, etc. converterFunctions is a collection of functions used to map a node into an R object. This would normally be a closure. It is not currently used, but will be enabled in the future. skipBlankLines controls whether text elements consisting simply of white space are included in the resulting structure. The return value is a simple list with named elements file, version and children The children element is itself a list consisting of objects of class `XMLNode'. Each of these has the characteristic */ USER_OBJECT_ RS_XML(ParseTree)(USER_OBJECT_ fileName, USER_OBJECT_ converterFunctions, USER_OBJECT_ skipBlankLines, USER_OBJECT_ replaceEntities, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ validate, USER_OBJECT_ getDTD, USER_OBJECT_ isURL, USER_OBJECT_ addNamespaceAttributes, USER_OBJECT_ internalNodeReferences, USER_OBJECT_ s_useHTML, USER_OBJECT_ isSchema, USER_OBJECT_ fullNamespaceInfo, USER_OBJECT_ r_encoding, USER_OBJECT_ useDotNames, USER_OBJECT_ xinclude, USER_OBJECT_ errorFun, USER_OBJECT_ manageMemory, USER_OBJECT_ r_parserOptions, USER_OBJECT_ r_rootFirst) { const char *name; xmlDocPtr doc; USER_OBJECT_ rdoc, rdocObj; /* rdocObj is used to put the doc object * under R's garbage collection.*/ USER_OBJECT_ className; R_XMLSettings parserSettings; int asTextBuffer = LOGICAL_DATA(asText)[0]; int isURLDoc = LOGICAL_DATA(isURL)[0]; int useHTML = LOGICAL_DATA(s_useHTML)[0]; const char *encoding = NULL; int freeName = 0; int parserOptions = 0; int rootFirst = INTEGER(r_rootFirst)[0]; if(GET_LENGTH(r_encoding)) { encoding = CHAR(STRING_ELT(r_encoding, 0)); if(!encoding[0]) encoding = NULL; } if(Rf_length(r_parserOptions)) parserOptions = INTEGER(r_parserOptions)[0]; parserSettings.skipBlankLines = LOGICAL_DATA(skipBlankLines)[0]; parserSettings.converters = converterFunctions; parserSettings.useDotNames = LOGICAL_DATA(useDotNames)[0]; parserSettings.trim = LOGICAL_DATA(trim)[0]; parserSettings.xinclude = LOGICAL_DATA(xinclude)[0]; parserSettings.fullNamespaceInfo = LOGICAL_DATA(fullNamespaceInfo)[0]; parserSettings.internalNodeReferences = LOGICAL_DATA(internalNodeReferences)[0]; parserSettings.addAttributeNamespaces = LOGICAL_DATA(addNamespaceAttributes)[0]; parserSettings.finalize = manageMemory; if(asTextBuffer == 0) { struct stat tmp_stat; #ifdef USE_R name = CHAR(STRING_ELT(fileName, 0)); #else name = CHARACTER_DATA(fileName)[0]; #endif if(!isURLDoc && (name == NULL || stat(name, &tmp_stat) < 0)) { Rf_error("Can't find file %s", CHAR_DEREF(STRING_ELT(fileName, 0)) ); } } else { name = strdup(CHAR_DEREF(STRING_ELT(fileName, 0))); freeName = 1; } #if 0 /* Done in R now.*/ /* If one wants entities expanded directly and to appear as text. */ if(LOGICAL_DATA(replaceEntities)[0]) xmlSubstituteEntitiesDefault(1); #endif if(LOGICAL_DATA(isSchema)[0]) { xmlSchemaPtr schema = NULL; xmlSchemaParserCtxtPtr ctxt; ctxt = xmlSchemaNewParserCtxt(name); schema = xmlSchemaParse(ctxt); xmlSchemaFreeParserCtxt(ctxt); /*XXX make certain to cleanup the settings. Put a finalizer on this in makeSchemaReference. */ return(makeSchemaReference(schema)); } #ifdef RS_XML_SET_STRUCTURED_ERROR xmlSetStructuredErrorFunc(errorFun == NULL_USER_OBJECT ? NULL : errorFun, R_xmlStructuredErrorHandler); #endif if(asTextBuffer) { doc = useHTML ? htmlParseDoc(CHAR_TO_XMLCHAR(name), encoding) : xmlReadMemory(name, (int)strlen(name), NULL, encoding, parserOptions) ; /* xmlParseMemory(name, strlen(name)) */ if(doc != NULL) doc->name = (char *) xmlStrdup(CHAR_TO_XMLCHAR("")); } else { doc = useHTML ? htmlParseFile(XMLCHAR_TO_CHAR(name), encoding) : xmlReadFile(name, encoding, parserOptions) /* xmlParseFile(name) */ ; } #ifdef RS_XML_SET_STRUCTURED_ERROR xmlSetStructuredErrorFunc(NULL, NULL); #endif if(doc == NULL) { if(freeName && name) { #ifdef EXPERIMENTING free((char *) name); #endif } /*XXX Just freed the name ! */ if(errorFun != NULL_USER_OBJECT) { RSXML_structuredStop(errorFun, NULL); } else return(stop("XMLParseError", "error in creating parser for %s", name)); Rf_error("error in creating parser for %s", name); } if(TYPEOF(xinclude) == LGLSXP && LOGICAL_DATA(xinclude)[0]) { xmlXIncludeProcessFlags(doc, XML_PARSE_XINCLUDE); } else if(TYPEOF(xinclude) == INTSXP && GET_LENGTH(xinclude) > 0) { xmlXIncludeProcessFlags(doc, INTEGER(xinclude)[0]); } if(!useHTML && LOGICAL_DATA(validate)[0]) { xmlValidCtxt ctxt; ctxt.error = RS_XML(ValidationError); ctxt.warning = RS_XML(ValidationWarning); if(!xmlValidateDocument(&ctxt, doc)) { if(freeName && name) free((char *) name); Rf_error("XML document is invalid"); } } if(parserSettings.internalNodeReferences) { /* Use a different approach - pass internal nodes to the converter functions*/ if(GET_LENGTH(converterFunctions) > 0) { xmlNodePtr root; #ifdef USE_OLD_ROOT_CHILD_NAMES root = doc->root; #else root = doc->xmlRootNode; #ifdef ROOT_HAS_DTD_NODE if(root->next && root->children == NULL) root = root->next; #endif #endif PROTECT(rdocObj = R_createXMLDocRef(doc)); NodeTraverse(root, converterFunctions, &parserSettings, rootFirst); UNPROTECT(1); } PROTECT(rdoc = NULL_USER_OBJECT); } else { PROTECT(rdoc = RS_XML(convertXMLDoc)(name, doc, converterFunctions, &parserSettings)); } if(asTextBuffer && name) free((char *) name); if(!useHTML && !parserSettings.internalNodeReferences && LOGICAL_DATA(getDTD)[0]) { USER_OBJECT_ ans, klass, tmp; const char *names[] = {"doc", "dtd"}; PROTECT(ans = NEW_LIST(2)); SET_VECTOR_ELT(ans, 0, rdoc); SET_VECTOR_ELT(ans, 1, tmp = RS_XML(ConstructDTDList)(doc, 1, NULL)); PROTECT(klass = NEW_CHARACTER(1)); SET_STRING_ELT( klass, 0, mkChar("DTDList")); SET_CLASS(tmp, klass); RS_XML(SetNames)(sizeof(names)/sizeof(names[0]), names, ans); UNPROTECT(2); /* release the ans */ rdoc = ans; } if(parserSettings.internalNodeReferences && GET_LENGTH(converterFunctions) < 1) { UNPROTECT(1); return(R_createXMLDocRef(doc)); } if(!parserSettings.internalNodeReferences) { /* Set the class for the document. */ className = NEW_CHARACTER(1); PROTECT(className); SET_STRING_ELT(className, 0, mkChar(useHTML ? "HTMLDocument" : "XMLDocument")); SET_CLASS(rdoc, className); UNPROTECT(1); } UNPROTECT(1); return(rdoc); } enum { FILE_ELEMENT_NAME, VERSION_ELEMENT_NAME, CHILDREN_ELEMENT_NAME, NUM_DOC_ELEMENTS}; void NodeTraverse(xmlNodePtr root, USER_OBJECT_ converterFunctions, R_XMLSettings *parserSettings, int rootFirst) { xmlNodePtr c, tmp; c = root; while(c) { USER_OBJECT_ ref; #ifndef USE_OLD_ROOT_CHILD_NAMES tmp = c->xmlChildrenNode; #else c->childs; #endif if(!rootFirst && tmp) NodeTraverse(tmp, converterFunctions, parserSettings, rootFirst); PROTECT(ref = R_createXMLNodeRef(c, parserSettings->finalize)); convertNode(ref, c, parserSettings); UNPROTECT(1); if(rootFirst && tmp) NodeTraverse(tmp, converterFunctions, parserSettings, rootFirst); c = c->next; } } /** Returns a named list whose elements are file: the name of the file being processed. version: the XML version. root: the collection of children. */ USER_OBJECT_ RS_XML(convertXMLDoc)(const char *fileName, xmlDocPtr doc, USER_OBJECT_ converterFunctions, R_XMLSettings *parserSettings) { USER_OBJECT_ rdoc; USER_OBJECT_ rdoc_el_names, klass; int n = NUM_DOC_ELEMENTS; const char *version = ""; DECL_ENCODING_FROM_DOC(doc) PROTECT(rdoc = NEW_LIST(n)); PROTECT(rdoc_el_names = NEW_CHARACTER(n)); /* Insert the name of the file being processed */ SET_VECTOR_ELT(rdoc, FILE_ELEMENT_NAME, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(rdoc, FILE_ELEMENT_NAME), 0, ENC_COPY_TO_USER_STRING(doc->name ? (const xmlChar*)doc->name : (const xmlChar*)fileName)); //SET_STRING_ELT(VECTOR_ELT(rdoc, FILE_ELEMENT_NAME), 0, ENC_COPY_TO_USER_STRING(doc->name ? XMLCHAR_TO_CHAR(doc->name) : fileName)); SET_STRING_ELT(rdoc_el_names, FILE_ELEMENT_NAME, COPY_TO_USER_STRING("file")); /* Insert the XML version information */ SET_VECTOR_ELT(rdoc, VERSION_ELEMENT_NAME, NEW_CHARACTER(1)); if(doc->version) version = XMLCHAR_TO_CHAR(doc->version); SET_STRING_ELT(VECTOR_ELT(rdoc, VERSION_ELEMENT_NAME), 0, COPY_TO_USER_STRING(version)); SET_STRING_ELT(rdoc_el_names, VERSION_ELEMENT_NAME, COPY_TO_USER_STRING("version")); /* Compute the nodes for this tree, recursively. Note the SIDEWAYS argument to get the sibling nodes at the root, rather than just the first and its children. */ { xmlNodePtr root; #ifdef USE_OLD_ROOT_CHILD_NAMES root = doc->root; #else root = doc->xmlRootNode; #ifdef ROOT_HAS_DTD_NODE if(root->next && root->children == NULL) root = root->next; #endif #endif SET_VECTOR_ELT(rdoc, CHILDREN_ELEMENT_NAME, RS_XML(createNodeChildren)(root, SIDEWAYS, parserSettings)); } SET_STRING_ELT(rdoc_el_names, CHILDREN_ELEMENT_NAME, COPY_TO_USER_STRING("children")); SET_NAMES(rdoc, rdoc_el_names); PROTECT(klass = NEW_CHARACTER(1)); SET_STRING_ELT(klass, 0, COPY_TO_USER_STRING("XMLDocumentContent")); SET_CLASS(rdoc, klass); UNPROTECT(3); return(rdoc); } USER_OBJECT_ processNamespaceDefinitions(xmlNs *ns, xmlNodePtr node, R_XMLSettings *parserSettings) { int n = 0; xmlNs *ptr = ns; USER_OBJECT_ ans, tmp, names; DECL_ENCODING_FROM_NODE(node) while(ptr) { ptr = ptr->next; n++; } PROTECT(ans = NEW_LIST(n)); PROTECT(names = NEW_CHARACTER(n)); for(n = 0, ptr = ns; ptr ; n++, ptr = ptr->next) { // protection suggested by rchk tmp = PROTECT(RS_XML(createNameSpaceIdentifier)(ptr,node)); (void) RS_XML(notifyNamespaceDefinition)(tmp, parserSettings); SET_VECTOR_ELT(ans, n, tmp); UNPROTECT(1); if(ptr->prefix) SET_STRING_ELT(names, n, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(ptr->prefix))); } SET_NAMES(ans, names); SET_CLASS(ans, mkString("XMLNamespaceDefinitions")); UNPROTECT(2); return(ans); } /** Creates an R object representing the specified node, and its children if recursive is non-zero. Certain types of nodes have direction controls whether we take the siblings of this node or alternatively its children. parentUserNode the previously created user-leve node for the parent of the target node. */ enum { NODE_NAME, NODE_ATTRIBUTES, NODE_CHILDREN, NODE_NAMESPACE, NODE_NAMESPACE_DEFS, NUM_NODE_ELEMENTS}; USER_OBJECT_ getNamespaceDefs(xmlNodePtr node, int recursive) { USER_OBJECT_ nsDef = NULL_USER_OBJECT; if(node->nsDef || recursive) { int numProtects = 0; xmlNs *ptr = node->nsDef; int n = 0; while(ptr) { n++; ptr = ptr->next; } PROTECT(nsDef = NEW_LIST(n)); numProtects++; ptr = node->nsDef; n = 0; while(ptr) { SET_VECTOR_ELT(nsDef, n, RS_XML(createNameSpaceIdentifier)(ptr, node)); n++; ptr = ptr->next; } if(recursive && node->children) { xmlNodePtr ptr = node->children; USER_OBJECT_ tmp; int i; PROTECT(nsDef); numProtects++; while(ptr) { PROTECT(tmp = getNamespaceDefs(ptr, 1)); /* nsDef = Rf_appendList(nsDef, tmp); */ if(Rf_length(tmp)) { n = Rf_length(nsDef); PROTECT(SET_LENGTH(nsDef, n + Rf_length(tmp))); for(i = 0; i < Rf_length(tmp); i++) SET_VECTOR_ELT(nsDef, n + i, VECTOR_ELT(tmp, i)); UNPROTECT(3); /* old nsDef, tmp, new nsDef */ PROTECT(nsDef); } else UNPROTECT(1); /* tmp */ ptr = ptr->next; } } SET_CLASS(nsDef, mkString("NamespaceDefinitionList")); UNPROTECT(numProtects); } return(nsDef); } USER_OBJECT_ RS_XML(internalNodeNamespaceDefinitions)(USER_OBJECT_ r_node, USER_OBJECT_ recursive) { xmlNodePtr node; if(TYPEOF(r_node) != EXTPTRSXP) { Rf_error("R_internalNodeNamespaceDefinitions expects InternalXMLNode objects"); } node = (xmlNodePtr) R_ExternalPtrAddr(r_node); return(getNamespaceDefs(node, LOGICAL(recursive)[0])); } static USER_OBJECT_ RS_XML(createXMLNode)(xmlNodePtr node, int recursive, int direction, R_XMLSettings *parserSettings, USER_OBJECT_ parentUserNode) { int n = NUM_NODE_ELEMENTS; USER_OBJECT_ ans; USER_OBJECT_ ans_el_names; USER_OBJECT_ nsDef = NULL_USER_OBJECT; int addValue; DECL_ENCODING_FROM_NODE(node) char *contentValue = XMLCHAR_TO_CHAR(node->content); #ifdef ROOT_HAS_DTD_NODE if(node->type == XML_DTD_NODE) return(NULL); #endif if(parserSettings->trim) { contentValue = trim(XMLCHAR_TO_CHAR(node->content)); } addValue = (contentValue && strlen(contentValue) && isBlank(contentValue) == 0); #ifdef LIBXML2 if(node->type == XML_ENTITY_DECL) return(NULL); #endif /* Drop text nodes that are blank, if that is what the user wanted. */ if(parserSettings->skipBlankLines && addValue == 0 && node->type == XML_TEXT_NODE) return(NULL); if(addValue) n++; /* If we have a */ if(node->type != XML_ELEMENT_DECL) { /* Create the default return value being a list of name, attributes, children and possibly value. */ PROTECT(ans = NEW_LIST(n)); PROTECT(ans_el_names = NEW_CHARACTER(n)); /* If there are namespace definitions within this node, */ if(node->nsDef) { nsDef = processNamespaceDefinitions(node->nsDef, node, parserSettings); SET_VECTOR_ELT(ans, NODE_NAMESPACE_DEFS, nsDef); } SET_VECTOR_ELT(ans, NODE_NAME, NEW_CHARACTER(1)); if(node->name) SET_STRING_ELT(VECTOR_ELT(ans, NODE_NAME), 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(node->name))); SET_VECTOR_ELT(ans, NODE_ATTRIBUTES, RS_XML(AttributeList)(node, parserSettings)); if(recursive) SET_VECTOR_ELT(ans, NODE_CHILDREN, RS_XML(createNodeChildren)(node, direction, parserSettings)); else SET_VECTOR_ELT(ans, NODE_CHILDREN, NULL_USER_OBJECT); SET_STRING_ELT(ans_el_names, NODE_NAME, mkChar("name")); SET_STRING_ELT(ans_el_names, NODE_ATTRIBUTES, mkChar("attributes")); SET_STRING_ELT(ans_el_names, NODE_CHILDREN, mkChar("children")); SET_STRING_ELT(ans_el_names, NODE_NAMESPACE, mkChar("namespace")); SET_STRING_ELT(ans_el_names, NODE_NAMESPACE_DEFS, mkChar("namespaceDefinitions")); if(node->ns) { PROTECT(nsDef = NEW_CHARACTER(1)); if(!parserSettings->fullNamespaceInfo) { if(node->ns->prefix) { SET_STRING_ELT(nsDef, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(node->ns->prefix))); SET_CLASS(nsDef, mkString("XMLNamespacePrefix")); } } else { if(node->ns->href) SET_STRING_ELT(nsDef, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(node->ns->href))); if(node->ns->prefix) SET_NAMES(nsDef, ScalarString(ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(node->ns->prefix)))); /* XXX change! */ SET_CLASS(nsDef, mkString("XMLNamespace")); } SET_VECTOR_ELT(ans, NODE_NAMESPACE, nsDef); UNPROTECT(1); } if(addValue) { SET_STRING_ELT(ans_el_names, NUM_NODE_ELEMENTS, COPY_TO_USER_STRING("value")); SET_VECTOR_ELT(ans, NUM_NODE_ELEMENTS, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, NUM_NODE_ELEMENTS), 0, ENC_COPY_TO_USER_STRING(contentValue)); if(node->type == XML_ENTITY_REF_NODE) SET_NAMES(VECTOR_ELT(ans, NUM_NODE_ELEMENTS), ScalarString(ENC_COPY_TO_USER_STRING(node->name))); } SET_NAMES(ans, ans_el_names); /* Compute the class of this object based on the type in the XML node. */ RS_XML(setNodeClass)(node, ans); } else { /* XML_ELEMENT_DECL */ ans = NULL_USER_OBJECT; PROTECT(ans); PROTECT(ans); } /* Now invoke any user-level converters. */ if(recursive || direction) ans = convertNode(ans, node, parserSettings); UNPROTECT(1); UNPROTECT(1); return(ans); } static USER_OBJECT_ convertNode(USER_OBJECT_ ans, xmlNodePtr node, R_XMLSettings *parserSettings) { USER_OBJECT_ val = ans; if(parserSettings != NULL) { USER_OBJECT_ fun = NULL; const char *funName; if(parserSettings->xinclude && (node->type == XML_XINCLUDE_START || node->type == XML_XINCLUDE_END)) { return(NULL); } if(node->name) { funName = XMLCHAR_TO_CHAR(node->name); fun = RS_XML(findFunction)(funName, parserSettings->converters); } if(fun == NULL) { /* Didn't find the tag-specific function in the handlers. So see if there is one for this type node. */ fun = RS_XML(lookupGenericNodeConverter)(node, ans, parserSettings); } if(fun != NULL) { USER_OBJECT_ opArgs = NEW_LIST(1); PROTECT(opArgs); SET_VECTOR_ELT(opArgs, 0, ans); val = RS_XML(invokeFunction)(fun, opArgs, NULL, NULL); UNPROTECT(1); } } return(val); } const char * const XMLNodeClassHierarchy[] = {"XMLNode", "RXMLAbstractNode", "XMLAbstractNode", "oldClass"}; int RS_XML(setNodeClass)(xmlNodePtr node, USER_OBJECT_ ans) { char *className = NULL; int numEls = 1; int lenHier = sizeof(XMLNodeClassHierarchy)/sizeof(XMLNodeClassHierarchy[0]); numEls = lenHier + 1; switch(node->type) { case XML_ENTITY_REF_NODE: className = "XMLEntityRef"; break; case XML_PI_NODE: className = "XMLProcessingInstruction"; break; case XML_COMMENT_NODE: className = "XMLCommentNode"; break; case XML_TEXT_NODE: className = "XMLTextNode"; break; case XML_CDATA_SECTION_NODE: className = "XMLCDataNode"; break; #ifdef LIBXML2 case XML_ENTITY_DECL: className = "XMLEntityDeclaration"; break; #endif default: numEls--; break; } if(1) { USER_OBJECT_ Class; int ctr = 0, i; PROTECT(Class = NEW_CHARACTER(numEls)); if(className) SET_STRING_ELT(Class, ctr++, mkChar(className)); for(i = 0; i < lenHier; i++) SET_STRING_ELT(Class, ctr++, mkChar(XMLNodeClassHierarchy[i])); SET_CLASS(ans, Class); UNPROTECT(1); } return(node->type); } const char *RS_XML(NameSpaceSlotNames)[] = {"id", "uri", "local"}; enum {NAMESPACE_PREFIX_SLOT, NAMESPACE_URI_SLOT, NAMESPACE_TYPE_SLOT, NAMESPACE_NUM_SLOTS}; /** Create a local object identifying the name space used by a particular node. This is not the name space definition which would have a URL/URI and a type. */ USER_OBJECT_ RS_XML(createNameSpaceIdentifier)(xmlNs *space, xmlNodePtr node) { USER_OBJECT_ ans; DECL_ENCODING_FROM_NODE(node) if(node->nsDef) { PROTECT(ans = NEW_LIST(3)); SET_VECTOR_ELT(ans, NAMESPACE_PREFIX_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, NAMESPACE_PREFIX_SLOT), 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR( (space->prefix ? space->prefix : (xmlChar*)"")))); SET_VECTOR_ELT(ans, NAMESPACE_URI_SLOT, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(ans, NAMESPACE_URI_SLOT), 0, space->href ? ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(space->href)) : NA_STRING); SET_VECTOR_ELT(ans, NAMESPACE_TYPE_SLOT, NEW_LOGICAL(1)); LOGICAL_DATA(VECTOR_ELT(ans, NAMESPACE_TYPE_SLOT))[0] = (space->type == XML_LOCAL_NAMESPACE); RS_XML(SetNames)(NAMESPACE_NUM_SLOTS, RS_XML(NameSpaceSlotNames), ans); { USER_OBJECT_ klass; PROTECT(klass = NEW_CHARACTER(1)); SET_STRING_ELT(klass, 0, COPY_TO_USER_STRING("XMLNamespaceDefinition")); SET_CLASS(ans, klass); UNPROTECT(1); } UNPROTECT(1); } else { PROTECT(ans = NEW_CHARACTER(1)); if(space->prefix) SET_STRING_ELT(ans, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(space->prefix))); UNPROTECT(1); } return(ans); } /** Attempt to find a function in the handler methods corresponding to the type of the node, not its specific tag name. */ USER_OBJECT_ RS_XML(lookupGenericNodeConverter)(xmlNodePtr node, USER_OBJECT_ defaultNodeValue, R_XMLSettings *parserSettings) { #define DOT(x) parserSettings->useDotNames ? "." x : x char *name; USER_OBJECT_ fun = NULL; switch(node->type) { case XML_ENTITY_REF_NODE: name = DOT("entity"); break; case XML_ENTITY_NODE: name = DOT("entity"); break; case XML_ELEMENT_NODE: name = DOT("startElement"); break; case XML_PI_NODE: name = DOT("proccesingInstruction"); break; case XML_COMMENT_NODE: name = DOT("comment"); break; case XML_TEXT_NODE: name = DOT("text"); break; case XML_CDATA_SECTION_NODE: name = DOT("cdata"); break; default: name = NULL; } if(name && name[0]) fun = RS_XML(findFunction)(name, parserSettings->converters); return(fun); } /* XXX Unravel this recursive call into a loop. Starting at the top node, fix the id to be empty. Then add the node and get the ID. Then loop over the children, and the node and call the routine on its children */ /* at a given node, make the node */ void addNodeAndChildrenToTree(xmlNodePtr node, SEXP id, SEXP e, R_XMLSettings *parserSettings, int *ctr) { SEXP tmp; xmlNodePtr n; if(!node) return; /* Create a skeleton node with no children. */ tmp = RS_XML(createXMLNode)(node, 0, 0/* doesn't matter */, parserSettings, R_NilValue);/*XXX*/ if(!tmp) return; SETCAR(CDR(e), tmp); (*ctr)++; id = Rf_eval(e, R_GlobalEnv); PROTECT(id); n = node->children; while(n) { SETCAR(CDR(CDR(e)), id); addNodeAndChildrenToTree(n, id, e, parserSettings, ctr); (*ctr)++; n = n->next; } UNPROTECT(1); } SEXP addNodesToTree(xmlNodePtr node, R_XMLSettings *parserSettings) { xmlNodePtr ptr = node; SEXP e, id; int ctr = 0; PROTECT(e = allocVector(LANGSXP, 3)); SETCAR(e, parserSettings->converters); PROTECT(id = NEW_CHARACTER(0)); ptr = node; /* loop over the sibling nodes here in case we have multiple roots, e.g. a comment, PI and a real node. See xysize.svg */ while(ptr) { SETCAR(CDR(CDR(e)), id); addNodeAndChildrenToTree(ptr, id, e, parserSettings, &ctr); ptr = ptr->next; } UNPROTECT(2); /* e, id */ return(ScalarInteger(ctr)); } /** Creates the R objects representing the children or siblings of the specified node, handling simple text cases with no children, as well as recursively processing the children. node the node whose children or siblings should be converted. direction DOWN or SIDEWAYS indicating the children or siblings should be processed, respectively. If SIDEWAYS is specified, the node itself is included in the result. parserSettings "global" information about the parsing conversion for the duration of the parser. Return list of XMLNode objects. */ USER_OBJECT_ RS_XML(createNodeChildren)(xmlNodePtr node, int direction, R_XMLSettings *parserSettings) { int n = 0, i; USER_OBJECT_ ans = NULL_USER_OBJECT; USER_OBJECT_ elNames = NULL; int unProtect = 0; xmlNodePtr base, c = (direction == SIDEWAYS) ? node : #ifndef USE_OLD_ROOT_CHILD_NAMES node->xmlChildrenNode; #else node->childs; #endif DECL_ENCODING_FROM_NODE(node) base = c; if(IS_FUNCTION(parserSettings->converters)) { return(addNodesToTree(node, parserSettings)); } /* Count the number of elements being converted. */ while(c) { c = c->next; n++; } if(n > 0) { USER_OBJECT_ tmp; USER_OBJECT_ tmpNames; int count = 0; c = base; PROTECT(ans = NEW_LIST(n)); PROTECT(elNames = NEW_CHARACTER(n)); unProtect = 2; for(i = 0; i < n; i++, c = c->next) { tmp = RS_XML(createXMLNode)(c, 1, DOWN, parserSettings, ans); if(tmp && tmp != NULL_USER_OBJECT) { SET_VECTOR_ELT(ans, count, tmp); if(c->name) SET_STRING_ELT(elNames, count, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(c->name))); count++; } } if(count < n) { /* Reset the length! */ #ifdef USE_S #else PROTECT(tmp = NEW_LIST(count)); PROTECT(tmpNames = NEW_CHARACTER(count)); for(i = 0 ; i < count ; i++) { SET_VECTOR_ELT(tmp, i, VECTOR_ELT(ans, i)); SET_STRING_ELT(tmpNames, i, STRING_ELT(elNames, i)); } ans = tmp; SET_NAMES(ans, tmpNames); UNPROTECT(4); PROTECT(ans); unProtect = 1; #endif } else { SET_NAMES(ans, elNames); } if(unProtect > 0) UNPROTECT(unProtect); } return(ans); } USER_OBJECT_ RS_XML(notifyNamespaceDefinition)(USER_OBJECT_ arg, R_XMLSettings *parserSettings) { USER_OBJECT_ fun, ans = NULL_USER_OBJECT; fun = RS_XML(findFunction)("namespace", parserSettings->converters); if(fun != NULL) { USER_OBJECT_ opArgs = NEW_LIST(1); USER_OBJECT_ tmp; PROTECT(opArgs); SET_VECTOR_ELT(opArgs, 0, arg); tmp = RS_XML(invokeFunction)(fun, opArgs, NULL, NULL); ans = tmp; UNPROTECT(1); } return(ans); } #ifdef USE_XML_VERSION_H #ifndef LIBXML_TEST_VERSION #include #endif #endif USER_OBJECT_ RS_XML(libxmlVersion)(void) { USER_OBJECT_ ans; unsigned int val; #ifdef LIBXML_VERSION_NUMBER val = LIBXML_VERSION_NUMBER; #else #ifdef LIBXML_VERSION val = LIBXML_VERSION; #else val = 0; #endif #endif ans = NEW_NUMERIC(1); NUMERIC_DATA(ans)[0] = val; return(ans); } static void notifyError(const char *msg, va_list ap, Rboolean isError) { #if 0 if(isError) { Rf_error("error in validating XML document"); } else { Rf_error("warning when validating XML document"); } #else #define BUFSIZE 2048 char buf[BUFSIZE]; memset(buf, '\0', BUFSIZE); vsnprintf(buf, BUFSIZE, msg, ap); Rf_warning("%s", buf); #endif } void RS_XML(ValidationError)(void *ctx, const char *format, ...) { char *msg = "Message unavailable"; va_list(ap); va_start(ap, format); if(strcmp(format, "%s") == 0) msg = va_arg(ap, char *); va_end(ap); notifyError(msg, ap, TRUE); } void RS_XML(ValidationWarning)(void *ctx, const char *format, ...) { char *msg = "Message unavailable"; va_list(ap); va_start(ap, format); if(strcmp(format, "%s") == 0) msg = va_arg(ap, char *); va_end(ap); notifyError(msg, ap, FALSE); } USER_OBJECT_ R_createXMLNode(USER_OBJECT_ snode, USER_OBJECT_ handlers, USER_OBJECT_ r_trim, USER_OBJECT_ r_skipBlankLines) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); R_XMLSettings parserSettings; parserSettings.converters = handlers; parserSettings.trim = LOGICAL(r_trim)[0]; parserSettings.skipBlankLines = LOGICAL(r_skipBlankLines)[0]; return(RS_XML(createNodeChildren)(node, SIDEWAYS, &parserSettings)); } USER_OBJECT_ RS_XML_xmlNodeName(USER_OBJECT_ snode) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); USER_OBJECT_ ans; DECL_ENCODING_FROM_NODE(node) PROTECT(ans = NEW_CHARACTER(1)); SET_STRING_ELT(ans, 0, node->name ? ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(node->name)) : R_NaString); UNPROTECT(1); return(ans); } USER_OBJECT_ RS_XML_xmlNodeNamespace(USER_OBJECT_ snode) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); USER_OBJECT_ ans; xmlNs *ns; DECL_ENCODING_FROM_NODE(node) ns = node->ns; if(!ns) return(NEW_CHARACTER(0)); PROTECT(ans = NEW_CHARACTER(1)); if(ns->href) SET_STRING_ELT(ans, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(ns->href))); if(ns->prefix) SET_NAMES(ans, ScalarString(ENC_COPY_TO_USER_STRING(ns->prefix))); SET_CLASS(ans, mkString("XMLNamespace")); UNPROTECT(1); return(ans); } enum { R_XML_NS_ADD_PREFIX = 1, R_XML_NS_ADD_URL_DEFS = 2 }; USER_OBJECT_ RS_XML_xmlNodeAttributes(USER_OBJECT_ snode, USER_OBJECT_ addNamespaces, USER_OBJECT_ addNamespaceURLs) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); R_XMLSettings parserSettings; parserSettings.addAttributeNamespaces = 0; if(LOGICAL_DATA(addNamespaces)[0]) parserSettings.addAttributeNamespaces |= R_XML_NS_ADD_PREFIX; if(LOGICAL_DATA(addNamespaceURLs)[0]) parserSettings.addAttributeNamespaces |= R_XML_NS_ADD_URL_DEFS; return(RS_XML(AttributeList)(node, &parserSettings)); } USER_OBJECT_ RS_XML_xmlNodeParent(USER_OBJECT_ snode, USER_OBJECT_ manageMemory) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); if(node->parent && (node->parent->type == XML_DOCUMENT_NODE || node->parent->type == XML_HTML_DOCUMENT_NODE)) return(NULL_USER_OBJECT); return(R_createXMLNodeRef(node->parent, manageMemory)); } USER_OBJECT_ RS_XML_xmlNodeNumChildren(USER_OBJECT_ snode) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); int count = 0; xmlNodePtr ptr = node->children; while(ptr) { count++; ptr = ptr->next; } return(ScalarInteger(count)); } USER_OBJECT_ RS_XML_xmlNodeChildrenReferences(USER_OBJECT_ snode, USER_OBJECT_ r_addNames, USER_OBJECT_ manageMemory) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); USER_OBJECT_ ans, names = R_NilValue; int count = 0, i; xmlNodePtr ptr = node->children; int addNames = LOGICAL(r_addNames)[0]; DECL_ENCODING_FROM_NODE(node) int nprot = 0; while(ptr) { count++; ptr = ptr->next; } ptr = node->children; PROTECT(ans = NEW_LIST(count)); nprot++; if(addNames) { PROTECT(names = NEW_CHARACTER(count)); nprot++; } for(i = 0; i < count ; i++, ptr = ptr->next) { SET_VECTOR_ELT(ans, i, R_createXMLNodeRef(ptr, manageMemory)); if(addNames) SET_STRING_ELT(names, i, ENC_COPY_TO_USER_STRING(ptr->name ? ptr->name : (const xmlChar *)"")); } if(addNames) SET_NAMES(ans, names); UNPROTECT(nprot); return(ans); } USER_OBJECT_ R_getNodeChildByIndex(USER_OBJECT_ snode, USER_OBJECT_ r_index, USER_OBJECT_ manageMemory) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(snode); int count = 0, num; xmlNodePtr ptr = node->children; num = INTEGER(r_index)[0] - 1; if(num < 0) { Rf_error("cannot index an internal node with a negative number %d", num); } while(ptr && count < num) { count++; ptr = ptr->next; } return(ptr ? R_createXMLNodeRef(ptr, manageMemory) : NULL_USER_OBJECT); } static USER_OBJECT_ makeSchemaReference(xmlSchemaPtr schema) { return(R_makeRefObject(schema, "xmlSchemaRef")); /* USER_OBJECT_ ans; PROTECT(ans = R_MakeExternalPtr(schema, Rf_install("XMLSchema"), R_NilValue)); SET_CLASS(ans, mkString("XMLSchema")); UNPROTECT(1); return(ans); */ } // unused #define NO_XML_MEMORY_SHOW_ROUTINE 1 #ifndef NO_XML_MEMORY_SHOW_ROUTINE void RS_XML_MemoryShow() { xmlMemDisplay(stderr); } #endif USER_OBJECT_ RS_XML_setDocumentName(USER_OBJECT_ sdoc, USER_OBJECT_ sname) { /* if doc is NULL in C , return NULL in R If doc->name is NULL in C, return NA Otherwise, return the string. */ xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); if(!doc) { Rf_warning("NULL pointer supplied for internal document"); return(R_NilValue); } doc->URL = xmlStrdup(CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(sname, 0)))); return(sdoc); } USER_OBJECT_ RS_XML_getDocumentName(USER_OBJECT_ sdoc) { /* if doc is NULL in C , return NULL in R If doc->name is NULL in C, return NA Otherwise, return the string. */ xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(sdoc); USER_OBJECT_ ans; const xmlChar *encoding; if(!doc) { Rf_warning("NULL pointer supplied for internal document"); return(R_NilValue); } encoding = doc->encoding; PROTECT(ans = NEW_CHARACTER(1)); SET_STRING_ELT(ans, 0, doc->URL ? ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(doc->URL)) : R_NaString); UNPROTECT(1); return(ans); } USER_OBJECT_ RS_XML_setKeepBlanksDefault(USER_OBJECT_ val) { int prev; prev = xmlKeepBlanksDefault(INTEGER(val)[0]); return(ScalarInteger(prev)); } USER_OBJECT_ RS_XML_xmlXIncludeProcessFlags(USER_OBJECT_ r_doc, USER_OBJECT_ r_flags) { xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); int ans; ans = xmlXIncludeProcessFlags(doc, INTEGER(r_flags)[0]); return(ScalarInteger(ans)); } USER_OBJECT_ RS_XML_xmlXIncludeProcessTreeFlags(USER_OBJECT_ r_node, USER_OBJECT_ r_flags) { xmlNodePtr node; int flags = INTEGER(r_flags)[0]; int n; //xmlNodePtr prev, parent; SEXP ans = R_NilValue; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); //prev = node->prev; //parent = node->parent; n = xmlXIncludeProcessTreeFlags(node, flags); if(n == 0) return(R_NilValue); else if(n == -1) { Rf_error("failed in XInclude"); } #if 0 if(!prev) { fprintf(stderr, "Adding to children of %s\n", prev->name); prev = parent->children; } else { fprintf(stderr, "Adding after %s\n", prev->name); prev = prev->next; } prev = node->next; PROTECT(ans = NEW_LIST(n)); for(i = 0; i < n; i++) { SET_VECTOR_ELT(ans, i, prev ? R_createXMLNodeRef(prev) : R_NilValue); prev = prev->next; } UNPROTECT(1); #endif return(ans); } /** Create an R named list containing the attributes of the specified node. */ /* We could use the CONS mechanism rather than doing a double pass. Not certain what is quicker in this situation. Also, doesn't work that way in S4, so keep it this way. */ USER_OBJECT_ RS_XML(AttributeList)(xmlNodePtr node, R_XMLSettings *parserSettings) { USER_OBJECT_ ans = NULL_USER_OBJECT; USER_OBJECT_ ans_names; xmlAttr * atts; const xmlChar *encoding = node->doc ? node->doc->encoding : NULL; int n = 0, i; /* Count the number of attributes*/ atts = node->properties; while(atts) { n++; atts = atts->next; } if(n > 0) { SEXP ans_namespaces, ans_namespaceDefs; int nonTrivialAttrNamespaces = 0; int addNSPrefix = parserSettings->addAttributeNamespaces & R_XML_NS_ADD_PREFIX; int retNSDefs = parserSettings->addAttributeNamespaces & R_XML_NS_ADD_URL_DEFS; PROTECT(ans = NEW_CHARACTER(n)); PROTECT(ans_names = NEW_CHARACTER(n)); PROTECT(ans_namespaces = NEW_CHARACTER(n)); PROTECT(ans_namespaceDefs = NEW_CHARACTER(retNSDefs ? n : 0)); /* Loop over the attributes and create the string elements and the elements of the name vector. */ atts = node->properties; for(i=0; i < n ; i++) { /* Have to be careful that atts->val and atts->val->context are non-null. Something like kills it otherwise. */ #ifdef LIBXML2 SET_STRING_ELT(ans, i, ENC_COPY_TO_USER_STRING( XMLCHAR_TO_CHAR( ((atts->xmlChildrenNode != (xmlNode*)NULL && atts->xmlChildrenNode->content != (xmlChar*)NULL ) ? atts->xmlChildrenNode->content : (xmlChar*)"")))); #else SET_STRING_ELT(ans, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(((atts->val != (xmlNode*)NULL && atts->val->content != (xmlChar*)NULL ) ? atts->val->content : (xmlChar*)"")))); #endif if(atts->name) { if(addNSPrefix && atts->ns && atts->ns->prefix) { char buf[400]; snprintf(buf, 400, "%s:%s", atts->ns->prefix, atts->name); SET_STRING_ELT(ans_names, i, ENC_COPY_TO_USER_STRING(buf)); } else SET_STRING_ELT(ans_names, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(atts->name))); if((addNSPrefix | retNSDefs) && atts->ns && atts->ns->prefix) { SET_STRING_ELT(ans_namespaces, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(atts->ns->prefix))); if(retNSDefs) SET_STRING_ELT(ans_namespaceDefs, i, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(atts->ns->href))); nonTrivialAttrNamespaces++; } } atts = atts->next; } if(nonTrivialAttrNamespaces) { if(retNSDefs) Rf_setAttrib(ans_namespaces, Rf_install("names"), ans_namespaceDefs); Rf_setAttrib(ans, Rf_install("namespaces"), ans_namespaces); } SET_NAMES(ans, ans_names); UNPROTECT(4); } #if 0 else ans = NEW_CHARACTER(0); #endif return(ans); } SEXP R_getDocEncoding(SEXP r_doc) { xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); const xmlChar *encoding; SEXP ans; if(doc->type != XML_DOCUMENT_NODE && doc->type != XML_HTML_DOCUMENT_NODE) doc = ((xmlNodePtr) doc)->doc; if(!doc) return(NEW_CHARACTER(0)); encoding = doc->encoding; PROTECT(ans = NEW_CHARACTER(1)); SET_STRING_ELT(ans, 0, encoding ? CreateCharSexpWithEncoding(doc->encoding, doc->encoding) : R_NaString); UNPROTECT(1); return(ans); } int getTextElementLineNumber(xmlNodePtr node) { int val = -1; if(node->parent) val = node->parent->line; xmlNodePtr prev = node->prev; while(prev) { if(prev->line > 0) { val = prev->line; break; } prev = prev->prev; } return(val); } SEXP R_getLineNumber(SEXP r_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); if(!node) { return(NEW_INTEGER(0)); } // XML_GET_LINE(node) return(ScalarInteger(node->line == 0 ? getTextElementLineNumber(node) : node->line)); } SEXP R_xmlReadFile(SEXP r_filename, SEXP r_encoding, SEXP r_options) //, SEXP manageMemory) { const char *filename; const char *encoding = NULL; int options; xmlDocPtr doc; filename = CHAR_DEREF(STRING_ELT(r_filename, 0)); if(Rf_length(r_encoding)) encoding = CHAR_DEREF(STRING_ELT(r_encoding, 0)); options = INTEGER(r_options)[0]; doc = xmlReadFile(filename, encoding, options); return(R_createXMLDocRef(doc)); } SEXP R_xmlReadMemory(SEXP r_txt, SEXP len, SEXP r_encoding, SEXP r_options, SEXP r_base) //, SEXP manageMemory) { const char *txt; const char *encoding = NULL; const char *baseURL = NULL; int options; xmlDocPtr doc; txt = CHAR_DEREF(STRING_ELT(r_txt, 0)); if(Rf_length(r_encoding)) encoding = CHAR_DEREF(STRING_ELT(r_encoding, 0)); options = INTEGER(r_options)[0]; if(Rf_length(r_base)) baseURL = CHAR_DEREF(STRING_ELT(r_base, 0)); doc = xmlReadMemory(txt, INTEGER(len)[0], baseURL, encoding, options); return(R_createXMLDocRef(doc)); } #if 1 int addXInclude(xmlNodePtr ptr, SEXP *ans, int level, SEXP manageMemory) { if(ptr->type == XML_XINCLUDE_START) { int len = Rf_length(*ans) + 1; SEXP oans = *ans; // avoid sequence-point error PROTECT(*ans = SET_LENGTH(oans, len)); SET_VECTOR_ELT(*ans, len - 1, R_createXMLNodeRef(ptr, manageMemory)); UNPROTECT(1); return(1); } else return(0); } int processKids(xmlNodePtr ptr, SEXP *ans, int level, SEXP manageMemory) { xmlNodePtr kids; int count = 0; kids = ptr->children; while(kids) { count += addXInclude(kids, ans, level, manageMemory); count += processKids(kids, ans, level + 1, manageMemory); kids = kids->next; } return(count); } #if 0 int findXIncludeStartNodes(xmlNodePtr node, SEXP *ans, int level) { const char * prefix[] = {"", " ", " ", " " }; xmlNodePtr ptr = node; int count = 0; addXInclude(node, ans, level); ptr = node; while(ptr) { count += addXInclude(ptr, ans, level); count += processKids(ptr, ans, level); ptr = ptr->next; } //fprintf(stderr, "%s level = %d, %s: %p, type = %d\n", prefix[level], level, ptr->name, node, ptr->type); //fprintf(stderr, "%p, %s, level = %d, type = %d\n", ptr, ptr->name, level, ptr->type); return(count); } #endif /* This is a recursive version. We want an iterative version. */ SEXP R_findXIncludeStartNodes(SEXP r_root, SEXP manageMemory) { xmlNodePtr root; SEXP ans; root = (xmlNodePtr) R_ExternalPtrAddr(r_root); if(!root) return(R_NilValue); PROTECT(ans = allocVector(VECSXP, 0)); addXInclude(root, &ans, 0, manageMemory); processKids(root, &ans, 0, manageMemory); UNPROTECT(1); return(ans); } #endif XML/src/Utils.c0000644000175100001440000002176114343054535013000 0ustar hornikusers/** Routines that are shared across the two XML parsers and their callbacks to R. isBlank - determines if a string consists entirely of whitespace RS_XML(invokeFunction) - call a user-level function, previously located by RS_XML(findFunction). RS_XML(findFunction) - search a list or closure for a function object with a given name in that list. * See Copyright for the license status of this software. */ #include "Utils.h" #include /* For isspace() */ #ifdef LIBXML #ifdef FROM_GNOME_XML_DIR #include #else #include #endif #endif #include "RSCommon.h" /* for SET_NAMES */ /** Tests whether the string contains only white space or not. Returns 1 if is only white space. 0 otherwise. */ int isBlank(const char *str) { int blank=0; const char *ptr = str; while(ptr && (blank = isspace(ptr[0]))) { ptr++; } return(blank); } /** Does an in place trimming of a string by returning a pointer to the first non-white space character and also inserting a string terminator after the last non-whitespace character. */ char * trim(char *str) { char *tmp; /* If a degenerate string, just return. */ if(str == (char*)NULL || str[0] == '\0') return(str); /* Jumpt to the end */ tmp = str + strlen(str) - 1; while(tmp >= str && isspace(*tmp)) { tmp[0] = '\0'; tmp--; } if(tmp == str) { #if 0 if(strlen(tmp) > 1) tmp[0] = '\0'; #endif return(str); } #if 0 else tmp[1] = '\0'; #endif tmp = str; while(*tmp && isspace(*tmp)) { tmp++; } return(tmp); } USER_OBJECT_ RS_XML(treeApply)(USER_OBJECT_ rtree, USER_OBJECT_ function, USER_OBJECT_ args) { return(rtree); } /** Error handling utilities for use with the libxml document parsing mechanism. Intercept the error handling by replacing it with a routine of the same name and have it print to a buffer. Then call the Warning handler. Then the warnings will end up in the local system, accessible via the warnings() function. This allows them to be programmatically processed rather than having to process the output to the terminal (via catching it in a call sink()). */ #ifdef LIBXML #include void localXmlParserPrintFileInfo(xmlParserInputPtr input, char *buf, int nbuf); #ifndef USE_LINKED_ERROR_HANDLER void S_xmlParserError(void *ctx, const char *msg, ...) #else void xmlParserError(void *ctx, const char *msg, ...) #endif { va_list args; #if 1 va_start(args, msg); stop("XMLParserError", msg, args); #else xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; char buf[3000], *tmp; /* Empty the string buffer. */ memset(buf , '\0', sizeof(buf)/sizeof(buf[0])); /* Insert the file and line number. */ localXmlParserPrintFileInfo(ctxt->input, buf, 3000); /* Move to the end of the buffer's contents. */ tmp = buf + strlen(buf); va_start(args, msg); /* Write in the actual message. */ vsprintf(tmp, msg, args); va_end(args); Rf_warning("XML Parsing Error: %s", buf); #endif } #ifndef USE_LINKED_ERROR_HANDLER /* Set the default error handlers in the libxml library */ void RSXML_setErrorHandlers(void) { // Next 2 are deprecated in 2.10.x and will be made private #if LIBXML_VERSION < 21000 xmlDefaultSAXHandlerInit(); htmlDefaultSAXHandlerInit(); xmlDefaultSAXHandler.error = S_xmlParserError; htmlDefaultSAXHandler.error = S_xmlParserError; #endif #if 0 docbDefaultSAXHandlerInit(); docbDefaultSAXHandler.error = S_xmlParserError; #endif } #endif /** Write the file name and the current line number into the specified string. */ void localXmlParserPrintFileInfo(xmlParserInputPtr input, char *buf, int nbuf) { if (input != NULL) { if (input->filename) snprintf(buf, nbuf, "%s:%d: ", input->filename, input->line); else snprintf(buf, nbuf, "Entity: line %d: ", input->line); } } #endif /** Utility method for setting the names of a list/vector from an array of native strings rather than an R/S character vector structure. */ void RS_XML(SetNames)(int n, const char *cnames[], USER_OBJECT_ ans) { int i; USER_OBJECT_ names; PROTECT(names = NEW_CHARACTER(n)); for(i = 0; i < n ; i++) { /* could install as a pre-defined string. */ SET_STRING_ELT(names, i, mkChar(cnames[i])); } SET_NAMES(ans, names); UNPROTECT(1); } /* Set the class of the target object to be the character vector containing just the specified name. */ int RS_XML(SetClassName)(const char *localClassName, USER_OBJECT_ target) { USER_OBJECT_ className; PROTECT(className = NEW_CHARACTER(1)); SET_STRING_ELT(className, 0, mkChar(localClassName)); SET_CLASS(target, className); UNPROTECT(1); return(1); } #if LIBXML2 struct _xmlHashTable { struct _xmlHashEntry **table; int size; }; #endif #if OWN_XML_HASH_SIZE int xmlHashSize(xmlHashTablePtr table) { /* For version 2.2.* */ return(table->size); /* return(table->nb_entities); */ } #endif USER_OBJECT_ RS_XML(findFunction)(const char *opName, USER_OBJECT_ _userObject) { int i; USER_OBJECT_ fun = NULL; /* Get the names of the list. */ USER_OBJECT_ names = GET_NAMES(_userObject); /* lookup function in the names of the list */ for (i = 0; i < GET_LENGTH(names); i++) { if(!strcmp(opName, CHAR_DEREF(STRING_ELT(names, i)))) { fun = VECTOR_ELT(_userObject, i); break; } } return(fun); } SEXP R_makeRefObject(void *ref, const char *className) { SEXP klass, obj, sref; if(!ref) { Rf_warning("NULL value for external reference"); return(R_NilValue); } PROTECT(klass = MAKE_CLASS((char *) className)); /* XXX define MAKE_CLASS with const */ if(klass == R_NilValue) { /* Is this the right test? */ Rf_error("Cannot find class %s for external reference", className); } PROTECT(obj = NEW_OBJECT(klass)); PROTECT(sref = R_MakeExternalPtr(ref, Rf_install(className), R_NilValue)); obj = SET_SLOT(obj, Rf_install("ref"), sref); UNPROTECT(3); return(obj); } #include #define copyStrField(x) SET_VECTOR_ELT(ans, i, mkString(uri->x ? uri->x : "")); \ SET_STRING_ELT(names, i, mkChar(#x)); i++; SEXP R_parseURI(SEXP r_uri) { xmlURIPtr uri; SEXP ans, names; int i= 0; uri = xmlParseURI( CHAR( STRING_ELT( r_uri, 0 ))); if(!uri) { Rf_error("cannot parse URI %s", CHAR( STRING_ELT( r_uri, 0) ) ); } PROTECT(ans = NEW_LIST(8)); PROTECT(names = NEW_CHARACTER(8)); copyStrField(scheme); copyStrField(authority); copyStrField(server); copyStrField(user); copyStrField(path); copyStrField(query); copyStrField(fragment); SET_VECTOR_ELT(ans, i, ScalarInteger(uri->port)); SET_STRING_ELT(names, i, mkChar("port")); SET_NAMES(ans, names); UNPROTECT(2); return(ans); } #define min(x, y) ((x) < (y) ? (x) : (y)) SEXP RSXML_structuredStop(SEXP errorFun, xmlErrorPtr err) { SEXP e, ptr; int n = 8; if(!err) n = 2; PROTECT(e = allocVector(LANGSXP, n)); SETCAR(e, errorFun != NULL && errorFun != R_NilValue ? errorFun : Rf_install("xmlStructuredStop")); ptr = CDR(e); if(err) { SETCAR(ptr, mkString(err->message)); ptr= CDR(ptr); SETCAR(ptr, ScalarInteger(err->code)); ptr= CDR(ptr); SETCAR(ptr, ScalarInteger(err->domain)); ptr= CDR(ptr); SETCAR(ptr, ScalarInteger(err->line)); ptr= CDR(ptr); SETCAR(ptr, ScalarInteger(err->int2)); ptr= CDR(ptr); SETCAR(ptr, ScalarInteger(err->level)); ptr= CDR(ptr); SETCAR(ptr, err->file ? mkString(err->file) : NEW_CHARACTER(0)); } else { SETCAR(ptr, NEW_CHARACTER(0)); } Rf_eval(e, R_GlobalEnv); UNPROTECT(1); /* Shouldn't get back to here! Rf_eval() should raise an error.*/ return(R_NilValue); } /* Because we call this function via Rf_eval(), we end up with an extra call on the stack when we enter recover. */ SEXP stop(const char *className, const char *msg, ...) { char buf[10000]; SEXP error, e, ns_env, ns_name; va_list ap; va_start(ap, msg); /* Rvsnprintf(buf, sizeof(buf)/sizeof(buf[0]), msg, ap); */ vsnprintf(buf, sizeof(buf)/sizeof(buf[0]), msg, ap); va_end(ap); PROTECT(error = mkString(buf)); /* const char * classNames[] = {"simpleError", "error", "condition"}; PROTECT(tmp = allocVector(STRSXP, sizeof(classNames)/sizeof(classNames[0]))); for(i = 0; i < sizeof(classNames)/sizeof(classNames[0]); i++) SET_STRING_ELT(tmp, i+1, mkChar(classNames[i])); SET_STRING_ELT(tmp, 0, mkChar(className)); SET_CLASS(error, tmp); */ PROTECT(e = allocVector(LANGSXP, 2)); PROTECT(ns_name = mkString("XML")); PROTECT(ns_env = R_FindNamespace(ns_name)); SETCAR(e, findVarInFrame(ns_env, Rf_install("xmlStop"))); SETCAR(CDR(e), error); Rf_eval(e, R_GlobalEnv); UNPROTECT(4); /* errorcall(error, "%s", msg); UNPROTECT(1); */ return(error); } XML/src/Rcatalog.c0000644000175100001440000000412214316271033013416 0ustar hornikusers#include "Utils.h" /* For isBlank() */ #include USER_OBJECT_ R_xmlCatalogResolve(USER_OBJECT_ r_id, USER_OBJECT_ type, USER_OBJECT_ debug) { xmlChar *id; SEXP r_ans = R_NilValue; xmlChar* ans = NULL; int debugLevel = -1; int n, i; debugLevel = xmlCatalogSetDebug(LOGICAL(debug)[0]); n = GET_LENGTH(r_id); PROTECT(r_ans = NEW_CHARACTER(n)); for(i = 0; i < n; i++) { id = CHAR_TO_XMLCHAR(CHAR_DEREF(STRING_ELT(r_id, i))); switch(INTEGER(type)[i]) { case 1: ans = xmlCatalogResolveURI(id); break; case 2: ans = xmlCatalogResolvePublic(id); break; case 3: ans = xmlCatalogResolveSystem(id); break; default: break; } if(ans) { SET_STRING_ELT(r_ans, i, mkChar(XMLCHAR_TO_CHAR(ans))); xmlFree(ans); } else { SET_STRING_ELT(r_ans, i, NA_STRING); } } UNPROTECT(1); xmlCatalogSetDebug(debugLevel); return(r_ans); } SEXP RS_XML_loadCatalog(SEXP catalogs) { int i, n; SEXP ans; n = GET_LENGTH(catalogs); ans = NEW_LOGICAL(n); for(i = 0; i < n ; i++) { LOGICAL(ans)[i] = (xmlLoadCatalog(CHAR(STRING_ELT(catalogs, i))) == 0); } return(ans); } SEXP RS_XML_clearCatalog(void) { xmlCatalogCleanup(); return(ScalarLogical(1)); } SEXP RS_XML_catalogAdd(SEXP orig, SEXP replace, SEXP type) { int i, n; SEXP ans; n = LENGTH(orig); ans = NEW_LOGICAL(n); for(i = 0; i < n ; i++) { LOGICAL(ans)[i] = (xmlCatalogAdd(CHAR_TO_XMLCHAR(CHAR(STRING_ELT(type, i))), CHAR_TO_XMLCHAR(CHAR(STRING_ELT(orig, i))), CHAR_TO_XMLCHAR(CHAR(STRING_ELT(replace, i)))) == 0); } return(ans); } SEXP RS_XML_catalogDump(SEXP fileName) { FILE *out; out = fopen(CHAR(STRING_ELT(fileName, 0)), "w"); if(!out) { Rf_error("Can't open file %s for write access", CHAR(STRING_ELT(fileName, 0)) ); } xmlCatalogDump(out); return(ScalarLogical(TRUE)); } void R_xmlInitializeCatalog(void) { xmlInitializeCatalog(); } XML/src/NodeGC.c0000644000175100001440000002542214317044444012774 0ustar hornikusers/* THIS COMMENT MAY NOT BE UP TO DATE. Sep 19 2011. The idea is as follows. We use the private field in the xmlDocPtr object to store information about nodes that are out in the wild, i.e. that have been returned to R across the .Call() interface. Each time a node is returned, we increment the number of references to that node by incrementing a table in the xmlDocPtr. Each time these R objects are garbage collected, we decrement the reference count. When the number of references to that node go to 0, we remove that entry from the table. When all the node entries are removed and the document itself is no longer being pointed to, we free the document. What about circularity? Does it occur? What happens when we reparent a node? What happens when we put a node into an R object e.g. x = node[[2]] y[[3]] = x Will R's garbage collection handle this for us? */ /* This now contains the code related to our memory management. */ #include "Utils.h" #include "NodeGC.h" void R_xmlFreeDoc(SEXP ref) { xmlDocPtr doc; doc = (xmlDocPtr) R_ExternalPtrAddr(ref); if(doc && !IS_NOT_OUR_DOC_TO_TOUCH(doc)) { int *val; val = doc->_private; if(val) { (*val)--; if(*val) { #ifdef R_XML_DEBUG fprintf(stderr, "Not freeing XML document %p (%s); still has %d references in the wild\n", doc, doc->URL ? doc->URL : "?", *val); #endif R_ClearExternalPtr(ref); return; } } #ifdef R_XML_DEBUG const xmlChar *url = doc->URL ? doc->URL : (doc->name ? doc->name : (const xmlChar *)"?? (internally created)"); fprintf(stderr, "Cleaning up document %p, %s, has children %d\n", (void *) doc, url, (int) (doc->children != NULL)); #endif if(val) { free(val); doc->_private = NULL; #ifdef R_XML_DEBUG fprintf(stderr, "Freeing the XML doc %p\n", doc); #endif xmlFreeDoc(doc); R_numXMLDocsFreed++; } /* was before the xmlFreeDoc so that that was unconditional.*/ } R_ClearExternalPtr(ref); } SEXP RS_XML_freeDoc(SEXP ref) { R_xmlFreeDoc(ref); return(R_NilValue); } SEXP RS_XML_forceFreeDoc(SEXP ref) { xmlDocPtr doc; doc = (xmlDocPtr) R_ExternalPtrAddr(ref); xmlFreeDoc(doc); return(R_NilValue); } /* This is a finalizer that removes the nodes and disassociates the node and the document and then frees the document structure. Does xmlFreeDoc() deal with the URL and name fields in the doc? XXX With the nodes and document under garbage collection, do we really need this? */ void R_xmlFreeDocLeaveChildren(SEXP ref) { xmlDocPtr doc; doc = (xmlDocPtr) R_ExternalPtrAddr(ref); if(doc) { xmlNodePtr tmp; #ifdef R_XML_DEBUG const xmlChar *url = doc->URL ? doc->URL : (doc->name ? doc->name : (const xmlChar *) "?? (internally created)"); fprintf(stderr, "Cleaning up document but not children: %p, %s\n", (void *) doc, url); #endif tmp = doc->children; xmlUnlinkNode(doc->children); tmp->doc = NULL; xmlFreeDoc(doc); R_numXMLDocsFreed++; } R_ClearExternalPtr(ref); } int R_XML_MemoryMgrMarker = 1010101011; int R_XML_NoMemoryMgmt = 111111111; /* This returns a value that indicates whether we should add a finalizer and put the XML node under a C finalizer to reduce the reference count. user is an R object that should be an integer vector of length 1 and should be 0, 1 or NA (effectively a logical) If it is NA, we consult the document object in which the node is located (or NULL if not part of a document). This document object can have a value in the _private field that tells us no to */ int R_XML_getManageMemory(SEXP user, xmlDocPtr doc, xmlNodePtr node) { int manage; if(TYPEOF(user) == STRSXP || TYPEOF(user) == EXTPTRSXP) return(0); manage = INTEGER(user)[0]; // TYPEOF(user) == INTSXP ? INTEGER(user)[0] : INTEGER(asInteger(user))[0]; if(manage == R_NaInt) { if(!doc) manage = 1; else manage = doc->_private != &R_XML_NoMemoryMgmt; } #ifdef R_XML_DEBUG if(manage) fprintf(stderr, "getManageMemory (%p) %d (type = %d, name = %s)\n", doc, manage, node->type, node->name);fflush(stderr); #endif return(manage); } SEXP R_xmlSetNoMemoryMgmt(SEXP r_doc) { xmlDocPtr doc; doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); doc->_private = &R_XML_NoMemoryMgmt; return(NULL_USER_OBJECT); } void initDocRefCounter(xmlDocPtr doc) { int *val; if(doc->_private) return; doc->_private = calloc(2, sizeof(int)); val = (int *) doc->_private; val[1] = R_MEMORY_MANAGER_MARKER; } void incrementDocRefBy(xmlDocPtr doc, int num) { int *val; if(!doc || IS_NOT_OUR_DOC_TO_TOUCH(doc)) return; if(!doc->_private) { initDocRefCounter(doc); } val = (int *) doc->_private; (*val) += num; } void incrementDocRef(xmlDocPtr doc) { incrementDocRefBy(doc, 1); } #define GET_NODE_COUNT(n) \ n->_private ? *((int*) (n)->_private) : 0 int getNodeCount(xmlNodePtr node) { int val = 0; xmlNodePtr p = node->children; if(!node || IS_NOT_OUR_NODE_TO_TOUCH(node)) return(0); val = GET_NODE_COUNT(node); while(p) { val += getNodeCount(p); p = p->next; } return(val); } void internal_incrementNodeRefCount(xmlNodePtr node) { int *val; if(!node || IS_NOT_OUR_NODE_TO_TOUCH(node) || !node->_private) return; val = (int *) node->_private; (*val)++; } SEXP R_getXMLRefCount(SEXP rnode) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(rnode); if(!node || IS_NOT_OUR_NODE_TO_TOUCH(node) || !node->_private) return(ScalarInteger(-1)); return(ScalarInteger(*((int *) node->_private))); } int checkDescendantsInR(xmlNodePtr node, int process) { xmlNodePtr p; if(!node && (process || IS_NOT_OUR_NODE_TO_TOUCH(node))) return(0); if(node->_private) return(1); p = node->children; while(p) { if(checkDescendantsInR(p, 0)) return(1); p = p->next; } return(0); } int internal_decrementNodeRefCount(xmlNodePtr node) { int *val, status = 0; /* */ if(!node || IS_NOT_OUR_NODE_TO_TOUCH(node)) /* if node->_private == NULL, should * we free this node?, i.e. if it is * not in a parent or a document. No! Basically we shouldn't get here if we have not set the _private. We set the finalizer having set the _private */ return(status); if(!node->_private) return(status); /* Get the value of the reference count and decrement it by 1. If we are now at 0, then we can potentially free this node. Certainly, if we are at 0, we should remove the reference count memory altogether. Now that _we_ no longer need the node, perhaps we can free it. But we have to make certain that we don't free it if a) it is a child of another node or b) if it is within a document and that document is still "in play". To determine if the document is "in play" we look at it's reference count. We decrement it by one since we added one to it for this node. If that makes the document's reference count 0, then we free it. */ val = (int *) node->_private; (*val)--; #ifdef R_XML_DEBUG fprintf(stderr, "decremented node (%s, %d) to %d (%p) %s\n", node->name, node->type, *val, node, *val == 0 ? "***" : "");fflush(stderr); #endif if(*val == 0) { free(node->_private); node->_private = NULL; if(node->doc && !IS_NOT_OUR_DOC_TO_TOUCH(node->doc)) { val = (int *) node->doc->_private; if(val) (*val)--; if(!val || *val == 0) { /* Consolidate with R_xmlFreeDoc */ #ifdef R_XML_DEBUG fprintf(stderr, "releasing document (for node) %p %s (%s)\n", node->doc, node->doc->URL ? node->doc->URL : "?", val ? "has zero count" : "no count");fflush(stderr); #endif if(val) free(node->doc->_private); node->doc->_private = NULL; xmlFreeDoc(node->doc); status = 1; R_numXMLDocsFreed++; } } else if(!node->parent) { /* If the node is not in a tree by having a parent, then * check the children and if they aren't being referenced by an R variable, we can free those too. */ int hold; hold = checkDescendantsInR(node, 1); if(!hold) { #ifdef R_XML_DEBUG fprintf(stderr, "Calling xmlFreeNode() for %p (type = %d)\n", node, node->type);fflush(stderr); #endif xmlFreeNode(node); status = 1; } } else { /* So we have a parent. But what if that parent is not being held as an R variable. We need to free the node. We need to make this smarter to see what parts of the tree we can remove. For instance, we might be holding onto this one, but not the parent, but that parent has a second child which is being held onto. So we go to the top of the node tree and check for its descendants */ int hold; xmlNodePtr p = node->parent; while(p->parent) p = p->parent; hold = checkDescendantsInR(p, 0); if(!hold) { #ifdef R_XML_DEBUG fprintf(stderr, "Calling xmlFree() for %p\n", node);fflush(stderr); #endif xmlFree(p); //XXX xmlFree() or xmlFreeNode() ? status = 1; } } } return(status); } void decrementNodeRefCount(SEXP rnode) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(rnode); int status; status = internal_decrementNodeRefCount(node); if(status) R_ClearExternalPtr(rnode); } int clearNodeMemoryManagement(xmlNodePtr node) { xmlNodePtr tmp; int ctr = 0; if(node->_private) { int a, b; // This compares and int and a pointer. Changed to be like NodeGC.h // int isOurs = (a = node->_private != &R_XML_NoMemoryMgmt) && (b = ((int *)(node->_private))[1] == (int *) &R_XML_MemoryMgrMarker); int isOurs = (a = node->_private != &R_XML_NoMemoryMgmt) && (b = ((int *)(node->_private))[1] == R_MEMORY_MANAGER_MARKER); if(isOurs) { #if R_XML_DEBUG fprintf(stderr, "Removing memory management from %p, %s\n", node, node->name);fflush(stderr); #endif free(node->_private); ctr++; } node->_private = NULL; } tmp = node->children; while(tmp) { if(tmp) ctr += clearNodeMemoryManagement(tmp); tmp = tmp->next; } return(ctr); } SEXP R_clearNodeMemoryManagement(SEXP r_node) { xmlNodePtr node = (xmlNodePtr) R_ExternalPtrAddr(r_node); int val; if(!node) return(ScalarInteger(-1)); val = clearNodeMemoryManagement(node); return(ScalarInteger(val)); } SEXP R_xmlRefCountEnabled(void) { int ans = #ifdef XML_REF_COUNT_NODES 1; #else 0; #endif return(ScalarLogical(ans)); } XML/src/ExpatParse.c0000644000175100001440000000631214106741723013746 0ustar hornikusers/* only compile this if LIBEXPAT is defined. */ #ifdef LIBEXPAT /* File that provides the entry point for an event driven XML parser that performs callbacks to the different user-level functions in the closure passed to it. * See Copyright for the license status of this software. */ #include "EventParse.h" #include "Utils.h" /* For the findFunction and invokeFunction. */ #include "RSCommon.h" #include "ExpatParse.h" void RS_XML(initParser)(XML_Parser parser, RS_XMLParserData *parserData) { XML_SetUserData(parser, parserData); XML_SetElementHandler(parser, RS_XML(startElement), RS_XML(endElement)); XML_SetCommentHandler(parser, RS_XML(commentHandler)); XML_SetExternalEntityRefHandler(parser, RS_XML(externalEntityHandler)); XML_SetUnparsedEntityDeclHandler(parser, RS_XML(entityDeclarationHandler)); XML_SetCharacterDataHandler(parser, RS_XML(textHandler)); XML_SetProcessingInstructionHandler(parser, RS_XML(processingInstructionHandler)); XML_SetCdataSectionHandler(parser, RS_XML(startCdataSectionHandler), RS_XML(endCdataSectionHandler)); XML_SetBase(parser, parserData->fileName); XML_SetNotStandaloneHandler(parser, RS_XML(notStandAloneHandler)); } int RS_XML(parse)(FILE *file, USER_OBJECT_ handlers) { RS_XMLParserData *parserData; parserData = RS_XML(createParserData)(handlers); return(RS_XML(parseWithParserData)(file, parserData)); } int RS_XML(parseWithParserData)(FILE *file, RS_XMLParserData *parserData) { char buf[BUFSIZ]; int done; XML_Parser parser = XML_ParserCreate(NULL); RS_XML(initParser)(parser, parserData); do { size_t len = fread(buf, 1, sizeof(buf), file); done = len < sizeof(buf); if (!XML_Parse(parser, buf, len, done)) { Rf_warning("%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); return 1; } } while (!done); XML_ParserFree(parser); return 0; } int RS_XML(parseBufferWithParserData)(char *buf, RS_XMLParserData *parserData) { int status; XML_Parser parser = XML_ParserCreate(NULL); RS_XML(initParser)(parser, parserData); status = XML_Parse(parser, buf, strlen(buf), 1); if(status == 0) { const char *msg = XML_ErrorString(XML_GetErrorCode(parser)); Rf_error("XML Parser Error: %s", msg); } return(status); } int RS_XML(externalEntityHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId) { RS_XMLParserData *parserData = (RS_XMLParserData*)XML_GetUserData(parser); USER_OBJECT_ opArgs; int i, num; const XML_Char *xml_args[4]; num = sizeof(xml_args)/sizeof(xml_args[0]); xml_args[0] = context; xml_args[1] = base;xml_args[2] = systemId; xml_args[3] = publicId; opArgs = NEW_LIST(num); for(i =0;i < num; i++) { RECURSIVE_DATA(opArgs)[i] = NEW_CHARACTER(1); CHARACTER_DATA(RECURSIVE_DATA(opArgs)[i])[0] = ENC_COPY_TO_USER_STRING(xml_args[i] ? xml_args[i] : ""); } RS_XML(callUserFunction)("externalEntity", NULL, parserData, opArgs); return(1); /* ok to go on */ } #else /* Something to avoid an empty file.*/ void XML_Expat_unused_dummy(void) { } #endif /* only if LIBEXPAT is defined */ XML/src/Makevars.in0000644000175100001440000000013613607633744013635 0ustar hornikusersPKG_CPPFLAGS= @PKG_CPPFLAGS@ @LANGUAGE_DEFS@ @XMLSEC_DEFS@ -I. @LIBXML2@ PKG_LIBS= @PKG_LIBS@ XML/src/RUtils.c0000644000175100001440000002337014327573457013133 0ustar hornikusers#include "Utils.h" #include /* Utilities used in the R XML parsing facilities for invoking user-level functions from C. * See Copyright for the license status of this software. */ #include "Rinternals.h" /* Macros, etc. */ USER_OBJECT_ R_makeXMLContextRef(xmlParserCtxtPtr ctx) { USER_OBJECT_ ans; PROTECT(ans = R_MakeExternalPtr(ctx, Rf_install(XML_PARSER_CONTEXT_TYPE_NAME), R_NilValue)); SET_CLASS(ans, mkString(XML_PARSER_CONTEXT_TYPE_NAME)); UNPROTECT(1); return(ans); } USER_OBJECT_ R_InternalRecursiveApply(USER_OBJECT_ top, USER_OBJECT_ func, USER_OBJECT_ klasses); USER_OBJECT_ RS_XML(invokeFunction)(USER_OBJECT_ fun, USER_OBJECT_ opArgs, USER_OBJECT_ data, xmlParserCtxtPtr context) { int i; long n; USER_OBJECT_ c, call; USER_OBJECT_ ans; int addContext = 0; if(context && TYPEOF(fun) == CLOSXP && OBJECT(fun) && R_isInstanceOf(fun, XML_PARSE_CONTEXT_FUNCTION)) addContext = 1; n = Rf_length(opArgs) + addContext + 1; if(data) n++; if(n > 0) { #if 1 PROTECT(call = allocVector(LANGSXP, n)); c = call; SETCAR(call, fun); c = CDR(c); if(addContext) { SETCAR(c, R_makeXMLContextRef(context)); c = CDR(c); } for (i = 0; i < Rf_length(opArgs); i++) { SETCAR(c, VECTOR_ELT(opArgs, i)); c = CDR(c); } if(data) { SETCAR(c, data); SET_TAG(c, Rf_install(".state")); } #else PROTECT(c = call = allocList(n)); if(addContext) { SETCAR(c, R_makeXMLContextRef(context)); c = CDR(c); } for (i = 0; i < GET_LENGTH(opArgs); i++) { SETCAR(c, VECTOR_ELT(opArgs, i)); c = CDR(c); } if(data) { SETCAR(c, data); SET_TAG(c, Rf_install(".state")); } call = LCONS(fun, call); UNPROTECT(1); #endif } else { PROTECT(call = allocVector(LANGSXP, 1 + addContext)); SETCAR(call, fun); if(addContext) SETCAR(CDR(call), R_makeXMLContextRef(context)); } ans = eval(call, R_GlobalEnv); UNPROTECT(1); return(ans); } USER_OBJECT_ RS_XML(RecursiveApply)(USER_OBJECT_ top, USER_OBJECT_ func, USER_OBJECT_ klasses) { USER_OBJECT_ ans; PROTECT(top = duplicate(top)); ans = R_InternalRecursiveApply(top, func, klasses); UNPROTECT(1); return(ans); } USER_OBJECT_ R_InternalRecursiveApply(USER_OBJECT_ top, USER_OBJECT_ func, USER_OBJECT_ klasses) { int CHILD_NODE = 2, i; USER_OBJECT_ kids; int numChildren; USER_OBJECT_ args, tmp; if(GET_LENGTH(top) > CHILD_NODE) { kids = VECTOR_ELT(top, CHILD_NODE); numChildren = GET_LENGTH(kids); /* Do the children first. */ PROTECT(args = NEW_LIST(1)); PROTECT(tmp = NEW_LIST(numChildren)); for(i = 0; i < numChildren; i++) { SET_VECTOR_ELT(tmp, i, R_InternalRecursiveApply(VECTOR_ELT(kids, i), func, klasses)); } SET_VECTOR_ELT(top, CHILD_NODE, tmp); UNPROTECT(2); } PROTECT(args = NEW_LIST(1)); SET_VECTOR_ELT(args, 0, top); tmp = RS_XML(invokeFunction)(func, args, NULL, NULL); /*XXX get the context and user data!!! */ UNPROTECT(1); return(tmp); } USER_OBJECT_ RS_XML_SubstituteEntitiesDefault(USER_OBJECT_ replaceEntities) { int value; USER_OBJECT_ ans; value = xmlSubstituteEntitiesDefault(LOGICAL_DATA(replaceEntities)[0]); ans = NEW_LOGICAL(1); LOGICAL_DATA(ans)[0] = value; return(ans); } #include /* Simple macro for expanding ENTRY(x, n) to {"", (DL_FUNC) &, } */ #define ENTRY(name, n) { #name, (DL_FUNC) &name, n } static R_CallMethodDef callMethods[] = { ENTRY(RS_XML_RecursiveApply, 3), #ifdef UNUSED_DOT_CALLS ENTRY(RS_XML_HtmlParseTree, 7), ENTRY(RS_XML_setDoc, 2), ENTRY(R_xmlNsAsCharacter, 1), ENTRY(R_addXMLNodeFinalizer, 1), #endif ENTRY(RS_XML_getDTD, 5), ENTRY(RS_XML_libxmlVersion, 0), ENTRY(RS_XML_Parse, 18), ENTRY(RS_XML_ParseTree, 21), ENTRY(R_newXMLDtd, 5), ENTRY(R_newXMLDoc, 3), ENTRY(R_newXMLNode, 6), ENTRY(R_newXMLTextNode, 3), ENTRY(R_xmlNewComment, 3), ENTRY(R_newXMLCDataNode, 3), ENTRY(R_newXMLPINode, 4), ENTRY(R_xmlNewNs, 3), ENTRY(R_xmlSetNs, 3), ENTRY(R_xmlRootNode, 3), ENTRY(R_insertXMLNode, 4), ENTRY(R_saveXMLDOM, 6), ENTRY(R_xmlCatalogResolve, 3), ENTRY(RS_XML_xmlNodeNumChildren, 1), ENTRY(RS_XML_unsetDoc, 4), ENTRY(RS_XML_printXMLNode, 6), ENTRY(RS_XML_dumpHTMLDoc, 5), ENTRY(RS_XML_removeChildren, 3), ENTRY(RS_XML_clone, 3), ENTRY(RS_XML_addNodeAttributes, 2), ENTRY(RS_XML_removeNodeAttributes, 3), ENTRY(RS_XML_getNsList, 2), ENTRY(RS_XML_setNodeName, 2), ENTRY(RS_XML_SubstituteEntitiesDefault, 1), ENTRY(RS_XML_getNextSibling, 3), ENTRY(R_getXMLNodeDocument, 1), ENTRY(RS_XML_createDocFromNode, 1), ENTRY(R_removeInternalNode, 2), ENTRY(RS_XML_replaceXMLNode, 3), ENTRY(RS_XML_xmlAddSiblingAt, 4), ENTRY(RS_XML_loadCatalog, 1), ENTRY(RS_XML_clearCatalog, 0), ENTRY(RS_XML_catalogAdd, 3), ENTRY(RS_XML_catalogDump, 1), ENTRY(RS_XML_setDocumentName, 2), ENTRY(RS_XML_setKeepBlanksDefault, 1), ENTRY(R_getDocEncoding, 1), ENTRY(R_getLineNumber, 1), ENTRY(RS_XML_xpathEval, 9), ENTRY(RS_XML_xmlNodeChildrenReferences, 3), ENTRY(RS_XML_freeDoc, 1), ENTRY(RS_XML_setRootNode, 2), ENTRY(R_getNodeChildByIndex, 3), ENTRY(RS_XML_setDocEl, 2), ENTRY(RS_XML_isDescendantOf, 3), ENTRY(RS_XML_getStructuredErrorHandler, 0), ENTRY(RS_XML_setStructuredErrorHandler, 1), ENTRY(R_convertDOMToHashTree, 4), ENTRY(R_parseURI, 1), ENTRY(R_getXMLFeatures, 0), ENTRY(R_xmlReadMemory, 5), //XXX ENTRY(R_xmlReadFile, 3), //XXX ENTRY(RS_XML_internalNodeNamespaceDefinitions, 2), ENTRY(R_libxmlTypeTable_names, 2), ENTRY(R_libxmlTypeTable_lookup, 3), ENTRY(RS_XML_xmlSchemaValidateDoc, 4), ENTRY(R_XML_indexOfChild, 1), ENTRY(RS_XML_xmlStopParser, 1), ENTRY(R_clearNodeMemoryManagement, 1), ENTRY(R_XMLInternalDocument_free, 1), ENTRY(R_addXMLInternalDocument_finalizer, 2), ENTRY(R_createXMLNode, 4), ENTRY(RS_XML_xmlNodeName, 1), ENTRY(RS_XML_xmlNodeNamespace, 1), ENTRY(RS_XML_xmlNodeAttributes, 3), // ENTRY(RS_XML_xmlNodeChildrenReferences, 3), // duplicate ENTRY(R_xmlNodeValue, 3), ENTRY(R_setXMLInternalTextNode_value, 2), ENTRY(RS_XML_xmlNodeParent, 2), ENTRY(R_getXMLNsRef, 1), // XXX ENTRY(R_setXMLInternalTextNode_noenc, 1), ENTRY(R_isNodeChildOfAt, 3), ENTRY(R_findXIncludeStartNodes, 2), ENTRY(RS_XML_removeAllNodeNamespaces, 1), ENTRY(RS_XML_removeNodeNamespaces, 2), ENTRY(R_matchNodesInList, 3), ENTRY(RS_XML_copyNodesToDoc, 3), ENTRY(RS_XML_getDocumentName, 1), ENTRY(RS_XML_getDefaultValiditySetting, 1), ENTRY(RS_XML_xmlXIncludeProcessFlags, 2), ENTRY(RS_XML_xmlXIncludeProcessTreeFlags, 2), ENTRY(R_convertXMLNsRef, 1), ENTRY(R_replaceNodeWithChildren, 1), {NULL, NULL, 0} }; static R_CMethodDef cmethods[] = { ENTRY(RSXML_setErrorHandlers, 0), ENTRY(xmlInitializeCatalog, 0), {NULL, NULL, 0} }; void R_init_XML(DllInfo *dll) { R_useDynamicSymbols(dll, FALSE); R_registerRoutines(dll, cmethods, callMethods, NULL, NULL); } Rboolean R_isInstanceOf(USER_OBJECT_ obj, const char *klass) { USER_OBJECT_ klasses; int n, i; klasses = GET_CLASS(obj); n = GET_LENGTH(klasses); for(i = 0; i < n ; i++) { if(strcmp(CHAR_DEREF(STRING_ELT(klasses, i)), klass) == 0) return(TRUE); } return(FALSE); } SEXP RS_XML_getStructuredErrorHandler(void) { SEXP ans; PROTECT(ans = NEW_LIST(2)); SET_VECTOR_ELT(ans, 0, R_MakeExternalPtr(xmlGenericErrorContext, Rf_install("xmlGenericErrorContext"), R_NilValue)); SET_VECTOR_ELT(ans, 1, R_MakeExternalPtr((void *)xmlStructuredError, Rf_install("xmlStructuredErrorFunc"), R_NilValue)); UNPROTECT(1); return(ans); } SEXP RS_XML_setStructuredErrorHandler(SEXP els) { void *ctx; xmlStructuredErrorFunc handler; SEXP fun, sym; fun = VECTOR_ELT(els, 0); sym = VECTOR_ELT(els, 1); if(sym != R_NilValue && TYPEOF(sym) != EXTPTRSXP) { Rf_error("invalid symbol object for XML error handler. Need an external pointer, e.g from getNativeSymbolInfo"); } if(fun == R_NilValue) ctx = NULL; else if(TYPEOF(fun) == EXTPTRSXP) ctx = R_ExternalPtrAddr(fun); else { ctx = fun = Rf_duplicate(fun); /* Should R_PreserveObject and * ReleaseObject() but then we have to be able "remember" if it is an R function or not.*/ R_PreserveObject(fun); } handler = (sym == R_NilValue) ? NULL : (xmlStructuredErrorFunc) R_ExternalPtrAddr(sym); xmlSetStructuredErrorFunc(ctx, handler); return(ScalarLogical(TRUE)); } SEXP CreateCharSexpWithEncoding(const xmlChar *encoding, const xmlChar *str) { SEXP ans; #ifdef HAVE_R_CETYPE_T cetype_t enc = CE_NATIVE; if(encoding == (const xmlChar *) NULL || xmlStrcmp(encoding, (const xmlChar *) "")) { enc = CE_NATIVE; } else if(xmlStrcmp(encoding, (xmlChar *)"UTF-8") == 0 || xmlStrcmp(encoding, (xmlChar *)"utf-8") == 0) enc = CE_UTF8; else if(xmlStrcmp(encoding, (xmlChar *)"ISO-8859-1") == 0 || xmlStrcmp(encoding, (xmlChar *)"iso-8859-1") == 0) enc = CE_LATIN1; else { str = (xmlChar *)translateChar(mkChar((const char *) str)); } // REprintf("encoding: %d\n", enc); ans = mkCharCE((const char *) str, enc); #else ans = mkChar((const char *) str); #endif return(ans); } SEXP R_lookString(SEXP rstr) { const char *str; str = CHAR(STRING_ELT(rstr, 0)); return(ScalarInteger((int) strlen(str))); } #if 0 #include SEXP R_relativeURL(SEXP r_url, SEXP r_base) { xmlChar *url, *base; const xmlChar *ans; SEXP rans; url = CHAR_DEREF(STRING_ELT(r_url, 0)); base = CHAR_DEREF(STRING_ELT(r_base, 0)); ans = xmlBuildRelativeURI(url, base); rans = ScalarString(COPY_TO_USER_STRING(ans)); xmlFree(ans); return(rans); } #endif XML/src/schema.c0000644000175100001440000001412314106741723013131 0ustar hornikusers#include "RS_XML.h" #include "RSCommon.h" #include #include #include #include "Utils.h" #if 0 #define R_GET_EXTERNAL_REF(type, name) \ type \ name(SEXP obj) \ { \ SEXP ref = GET_SLOT(obj, Rf_install("ref")); \ if(TYPEOF(ref) != EXTPTRSXP) { \ Rf_error("Expected external pointer object"); \ } \ \ if(R_ExternalPtrTag(ref) != Rf_install(#type)) { \ Rf_error("Expected external pointer to have internal tag %s, got %s", \ #type, PRINTNAME(ref)); \ } \ \ return((type) R_ExternalPtrAddr(ref)); \ } R_GET_EXTERNAL_REF(xmlHashTablePtr, R_libxmlTypeTableGetRef) R_GET_EXTERNAL_REF(xmlSchemaElementPtr, R_libxmlSchemaElementGetRef) #endif void * R_getExternalRef(SEXP obj, const char *className) { SEXP ref = GET_SLOT(obj, Rf_install("ref")); void *ans; if(TYPEOF(ref) != EXTPTRSXP) { Rf_error("Expected external pointer object"); } if(className && R_ExternalPtrTag(ref) != Rf_install(className)) { Rf_error("Expected external pointer to have internal tag %s, got %s", className, CHAR(PRINTNAME(R_ExternalPtrTag(ref))) ); } ans = R_ExternalPtrAddr(ref); if(!ans) { Rf_error("Got NULL value in reference for %s", className); } return(ans); } typedef struct { int pos; USER_OBJECT_ els; USER_OBJECT_ names; char *elType; } HashGatherer; #if LIBXML_VERSION >= 20908 # define CONST const #else # define CONST #endif static void getKeys(void *el, void *data, CONST xmlChar *name) { HashGatherer *d = (HashGatherer *)data; SET_STRING_ELT(d->names, d->pos, COPY_TO_USER_STRING(name)); if(d->elType) { SET_VECTOR_ELT(d->els, d->pos, R_makeRefObject(el, d->elType)); } d->pos++; } USER_OBJECT_ R_libxmlTypeTable_names(USER_OBJECT_ table, USER_OBJECT_ s_elType) { xmlHashTablePtr t; int n = 0, ctr = 0; int getElements = GET_LENGTH(s_elType) > 0; HashGatherer d = {0, NULL_USER_OBJECT, NULL_USER_OBJECT, NULL}; t = R_getExternalRef(table, NULL); /* R_libxmlTypeTableGetRef(table); */ n = xmlHashSize(t); PROTECT(d.names = NEW_CHARACTER(n)); ctr++; if(getElements) { PROTECT(d.els = NEW_LIST(n)); ctr++; d.elType = (char *) CHAR_DEREF(STRING_ELT(s_elType, 0)); } xmlHashScan(t, getKeys, &d); if(getElements) SET_NAMES(d.els, d.names); else d.els = d.names; UNPROTECT(ctr); return(d.els); } USER_OBJECT_ R_libxmlTypeTable_lookup(USER_OBJECT_ table, USER_OBJECT_ name, USER_OBJECT_ s_elType) { xmlHashTablePtr t; USER_OBJECT_ ans; void *p; t = R_getExternalRef(table, NULL); /* R_libxmlTypeTableGetRef(table); */ p = xmlHashLookup(t, (const xmlChar *)CHAR_DEREF(STRING_ELT(name, 0))); ans = R_makeRefObject(p, CHAR_DEREF(STRING_ELT(s_elType, 0))); return(ans); } #define SchemaElement(id, type) \ USER_OBJECT_ \ R_libxmlTypeTable_##id(USER_OBJECT_ s) \ { \ xmlSchemaPtr schema; \ schema = R_getExternalRef(s, "xmlSchemaRef"); \ \ return(schema->id != NULL ? R_makeRefObject(schema->id, type) : R_NilValue); \ } SchemaElement(elemDecl, "SchemaElementTable") SchemaElement(typeDecl, "SchemaTypeTable") SchemaElement(attrDecl, "SchemaAttributeTable") SchemaElement(attrgrpDecl, "SchemaAttributeGroupTable") SchemaElement(notaDecl, "SchemaNotationTable") /* USER_OBJECT_ R_libxmlTypeTable_elemDecl(USER_OBJECT_ s) { xmlSchemaPtr schema; schema = R_getExternalRef(s, "xmlSchemaRef"); return(R_makeRefObject(schema->typeDecl, "SchemaElementTable")); } */ #include typedef struct { SEXP fun; } R_SchemaValidCallback; void R_schemaValidityFunctionCall(R_SchemaValidCallback *ctx, int warning, const char *msg, va_list args) { SEXP arg; char buf[10000]; vsnprintf(buf, sizeof(buf)/sizeof(buf[0]), msg, args); PROTECT(arg = mkString(buf)); SET_CLASS(arg, mkString(warning ? "XMLSchemaWarning" : "XMLSchemaError")); SETCAR(CDR(ctx->fun), arg); Rf_eval(ctx->fun, R_GlobalEnv); UNPROTECT(1); } void R_schemaValidityErrorFunc(R_SchemaValidCallback *ctx, const char *msg, ...) { va_list args; va_start(args, msg); R_schemaValidityFunctionCall(ctx, 0, msg, args); va_end(args); } void R_schemaValidityWarningFunc(R_SchemaValidCallback *ctx, const char *msg, ...) { va_list args; va_start(args, msg); R_schemaValidityFunctionCall(ctx, 1, msg, args); va_end(args); } SEXP RS_XML_xmlSchemaValidateDoc(SEXP r_schema, SEXP r_doc, SEXP r_options, SEXP r_errorHandlers) { xmlSchemaValidCtxtPtr ctxt; xmlDocPtr doc = (xmlDocPtr) R_ExternalPtrAddr(r_doc); xmlSchemaPtr schema = (xmlSchemaPtr) R_ExternalPtrAddr(r_schema); // int nprot = 0; // ctxt = (xmlSchemaValidCtxtPtr) R_ExternalPtrAddr(r_ctxt); int status; int numErrHandlers; ctxt = xmlSchemaNewValidCtxt(schema); if(LENGTH(r_options)) xmlSchemaSetValidOptions(ctxt, INTEGER(r_options)[0]); numErrHandlers = Rf_length(r_errorHandlers); if(numErrHandlers > 0) { R_SchemaValidCallback cbinfo; PROTECT(cbinfo.fun = allocVector(LANGSXP, 2)); SETCAR(cbinfo.fun, VECTOR_ELT(r_errorHandlers, 0)); xmlSchemaSetValidErrors(ctxt, (xmlSchemaValidityErrorFunc) R_schemaValidityErrorFunc, (xmlSchemaValidityWarningFunc) R_schemaValidityWarningFunc, &cbinfo); } status = xmlSchemaValidateDoc(ctxt, doc); xmlSchemaFreeValidCtxt(ctxt); /* R_alloc this if possible. */ if(numErrHandlers > 0) UNPROTECT(1); return(ScalarInteger(status)); } #if 0 SEXP RS_XML_xmlSchemaNewValidCtxt(SEXP r_schema, SEXP r_options, SEXP r_errorHandlers) { xmlSchemaPtr schema = (xmlSchemaPtr) R_ExternalPtrAddr(r_schema); xmlSchemaValidCtxtPtr ctxt; int numErrHandlers; ctxt = xmlSchemaNewValidCtxt(schema); if(LENGTH(r_options)) xmlSchemaSetValidOptions(ctxt, INTEGER(r_options)[0]); numErrHandlers = LENGTH(r_errorHandlers); if(numErrHandlers > 0) { R_SchemaValidCallback *cbinfo = (R_SchemaValidCallback*) malloc(sizeof(R_SchemaValidCallback)); cbinfo->fun = VECTOR_ELT(r_errorHandlers); xmlSchemaSetValidErrors(routine); } return(); } #endif XML/src/XMLEventParse.c0000644000175100001440000006303614553462406014341 0ustar hornikusers#include "EventParse.h" #include "DocParse.h" #define R_USE_XML_ENCODING 1 #include "Utils.h" #include #ifdef FROM_GNOME_XML_DIR #include #else #include #endif #ifdef _WIN32 /* on Unix, there is a configure check */ # if LIBXML_VERSION < 20627 || LIBXML_VERSION > 21100 # define NO_CHECKED_ENTITY_FIELD # endif #endif static USER_OBJECT_ createSAX2AttributesList(const xmlChar **attributes, int nb_attributes, int nb_defaulted, const xmlChar *encoding); /* This is an event driven parsing implementation for R & S using the libxml (http://xmlsoft.org) rather than Jim Clark's expat. It works much the same way, but has some advantages a) only one library need be installed for both document and event parsing b) the libxml tools can read data via ftp and http. Both expat and libxml provide the SAX interface and allow us to share a great deal of code between the two event parser implementations within this package. */ void RS_XML(startElementHandler)(void *ctx, const xmlChar *name, const xmlChar **atts); void RS_XML(commentElementHandler)(void *ctx, const xmlChar *val); void RS_XML(charactersHandler)(void *user_data, const xmlChar *ch, int len); void RS_XML(endElementHandler)(void *ctx, const xmlChar *name); void RS_XML(startDocumentHandler)(void *ctx); void RS_XML(endDocumentHandler)(void *ctx); void RS_XML(cdataBlockHandler)(void *ctx, const xmlChar *value, int len); void RS_XML(piHandler)(void *ctx, const xmlChar *target, const xmlChar *data); void RS_XML(entityDeclaration)(void *ctx, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content); xmlEntityPtr RS_XML(getEntityHandler)(void *userData, const xmlChar *name); xmlEntityPtr RS_XML(getParameterEntityHandler)(void *userData, const xmlChar *name); int RS_XML(isStandAloneHandler)(void *ctx); void RS_XML(warningHandler)(void *ctx, const char *msg, ...); void RS_XML(errorHandler)(void *ctx, const char *format, ...); void RS_XML(fatalErrorHandler)(void *ctx, const char *msg, ...); #if LIBXML_VERSION < 21200 void RS_XML(structuredErrorHandler)(void *ctx, xmlErrorPtr err); #else void RS_XML(structuredErrorHandler)(void *ctx, const struct _xmlError *err); #endif static void RS_XML(initXMLParserHandler)(xmlSAXHandlerPtr xmlParserHandler, int saxVersion); USER_OBJECT_ createSAX2AttributesList(const xmlChar **attributes, int nb_attributes, int nb_defaulted, const xmlChar *encoding) { int i; const char **ptr; USER_OBJECT_ attr_names; USER_OBJECT_ attr_values; USER_OBJECT_ nsURI, nsNames; if(nb_attributes < 1) return(NULL_USER_OBJECT); PROTECT(attr_values = NEW_CHARACTER(nb_attributes)); PROTECT(attr_names = NEW_CHARACTER(nb_attributes)); PROTECT(nsURI = NEW_CHARACTER(nb_attributes)); PROTECT(nsNames = NEW_CHARACTER(nb_attributes)); ptr = (const char **) attributes; /*XXX */ for(i=0; i < nb_attributes; i++, ptr+=5) { char *tmp; int len; len = (int)(ptr[4] - ptr[3] + 1); tmp = malloc(sizeof(char) * len); if(!tmp) { Rf_error("Cannot allocate space for attribute of length %d", (int) (ptr[4] - ptr[3] + 2)); } memcpy(tmp, ptr[3], ptr[4] - ptr[3]); tmp[len-1] = '\0'; /*XXX*/ SET_STRING_ELT(attr_values, i, ENC_COPY_TO_USER_STRING(tmp)); free(tmp); SET_STRING_ELT(attr_names, i, ENC_COPY_TO_USER_STRING(ptr[0])); if(ptr[2]) { SET_STRING_ELT(nsURI, i, ENC_COPY_TO_USER_STRING(ptr[2])); if(ptr[1]) SET_STRING_ELT(nsNames, i, ENC_COPY_TO_USER_STRING(ptr[1])); } } SET_NAMES(nsURI, nsNames); SET_NAMES(attr_values, attr_names); Rf_setAttrib(attr_values, Rf_install("namespaces"), nsURI); UNPROTECT(4); return(attr_values); } #ifdef NEED_CLOSE_CALLBACK /* Is this actually needed? We can ensure that all errors are caught by R and so ensure that we close things. */ int RS_XML_closeConnectionInput(void *context) { int status; status = RS_XML_readConnectionInput(context, NULL, -1); return(1); } #endif typedef struct { SEXP fun; xmlParserCtxtPtr ctx; } RFunCtxData; int RS_XML_readConnectionInput(void *context, char *buffer, int len) { SEXP e, tmp, arg = R_NilValue /* -Wall */; int n; int errorOccurred; const char *str; int left = len-1, count; int nprot = 0; #ifdef R_XML_DEBUG char *orig = buffer; #endif SEXP fun; xmlParserCtxtPtr ctx; #ifndef LIBXML2_NEW_BUFFER ctx = (xmlParserCtxtPtr) context; fun = ctx->_private; #else RFunCtxData *user = (RFunCtxData *) context; ctx = user->ctx; fun = user->fun; #endif if(len == -1) return(0); /* Setup the expression to call the user-supplied R function or call readLines(con, 1) if they gave us a connection. */ if(isFunction(fun)) { /* Invoke the user-provided function to get the next line. */ PROTECT(e = allocVector(LANGSXP, 2)); nprot++; SETCAR(e, fun); PROTECT(arg = NEW_INTEGER(1)); nprot++; INTEGER_DATA(arg)[0] = len; SETCAR(CDR(e), arg); } else e = fun; n = count = 0; while(n == 0 && left > 0) { str = NULL; /* Update the argument to the user-defined function to say how much is left. */ if(isFunction(fun)) INTEGER_DATA(arg)[0] = left; tmp = R_tryEval(e, R_GlobalEnv, &errorOccurred); if(errorOccurred || !IS_CHARACTER(tmp)) { UNPROTECT(nprot); if ((ctx->sax != NULL) && (ctx->sax->error != NULL)) /* throw an XML error. */ ctx->sax->error(ctx->userData, "Failed to call read on XML connection"); return(-1); } if(GET_LENGTH(tmp)) { str = CHAR_DEREF(STRING_ELT(tmp, 0)); n = (int)strlen(str); if(n != 0) { /* Just add a new line and do it again. */ if(n > left) { Rf_warning("string read from XML connection too long for buffer: truncating %s to %d characters", str, left); } strncpy(buffer, str, left); left -= n; count += n ; } } else { /* Notice that we may have actually added something to the buffer, specifically a sequence of empty lines \n, and these will be discarded and not passed to the XML parser but these are extraneous anyway. Are they? */ n = count = 0; break; } } #ifdef R_XML_DEBUG fprintf(stderr, "size (len = %d, n=%d, count=%d)\nbuffer= '%s'\nRstring='%s'\n", len, n, count, buffer, str);fflush(stderr); /* fprintf(stderr, "size (n=%d, count=%d) %s '%s'\n", n, count, str, orig);fflush(stderr); */ #endif UNPROTECT(nprot); return(count); /* return(count == 0 ? -1 : count); */ } xmlParserCtxtPtr RS_XML_xmlCreateConnectionParserCtxt(USER_OBJECT_ con) { xmlParserInputBufferPtr buf; xmlParserCtxtPtr ctx = NULL; #ifdef LIBXML2 ctx = xmlNewParserCtxt(); #ifndef LIBXML2_NEW_BUFFER // < 2.9.1 ctx->_private = (USER_OBJECT_) con; /* R_chk_calloc */ buf = (xmlParserInputBufferPtr) calloc(1, sizeof(xmlParserInputBuffer)); buf->readcallback = RS_XML_readConnectionInput; buf->context = (void*) ctx; buf->raw = NULL; /* buf->buffer; */ xmlBufferPtr tmp = xmlBufferCreate(); buf->buffer = tmp; #else RFunCtxData *userData = (RFunCtxData *) R_alloc(sizeof(RFunCtxData), 1); userData->fun = con; userData->ctx = ctx; buf = xmlParserInputBufferCreateIO(RS_XML_readConnectionInput, NULL, userData, XML_CHAR_ENCODING_NONE); #endif xmlParserInputPtr input = xmlNewIOInputStream(ctx, buf, XML_CHAR_ENCODING_NONE); if(!input) { Rf_error("can't create new IOInputStream"); } inputPush(ctx, input); #endif return(ctx); } int RS_XML(libXMLEventParse)(const char *fileName, RS_XMLParserData *parserData, RS_XML_ContentSourceType asText, int saxVersion, USER_OBJECT_ r_encoding) { xmlSAXHandlerPtr xmlParserHandler; xmlParserCtxtPtr ctx; int status; switch(asText) { case RS_XML_TEXT: ctx = xmlCreateDocParserCtxt(CHAR_TO_XMLCHAR(fileName)); break; case RS_XML_FILENAME: ctx = xmlCreateFileParserCtxt(fileName); break; case RS_XML_CONNECTION: ctx = RS_XML_xmlCreateConnectionParserCtxt((USER_OBJECT_) fileName); break; default: ctx = NULL; } if(ctx == NULL) { Rf_error("Can't parse %s", fileName); } xmlParserHandler = (xmlSAXHandlerPtr) S_alloc(sizeof(xmlSAXHandler), 1); /* Make certain this is initialized so that we don't have any references to unwanted routines! */ memset(xmlParserHandler, '\0', sizeof(xmlSAXHandler)); RS_XML(initXMLParserHandler)(xmlParserHandler, saxVersion); parserData->ctx = ctx; ctx->userData = parserData; ctx->sax = xmlParserHandler; if(Rf_length(r_encoding) && STRING_ELT(r_encoding, 0) != R_NaString) { // Rf_PrintValue(r_encoding); ctx->encoding = xmlStrdup((const xmlChar *)CHAR(STRING_ELT(r_encoding, 0))); } status = xmlParseDocument(ctx); ctx->sax = NULL; xmlFreeParserCtxt(ctx); return(status); /* Free(xmlParserHandler); */ } int R_isBranch(const xmlChar *localname, RS_XMLParserData *rinfo) { int n; if(rinfo->current) return(-2); /* we are processing a branch */ if((n = GET_LENGTH(rinfo->branches)) > 0) { int i; USER_OBJECT_ names = GET_NAMES(rinfo->branches); for(i = 0 ; i < n ; i++) { if(strcmp(XMLCHAR_TO_CHAR(localname), CHAR_DEREF(STRING_ELT(names, i))) == 0) { return(i); } } } return(-1); } char * getPropertyValue(const xmlChar **ptr) { int len; char *tmp; len = (int)(ptr[4] - ptr[3] + 1); tmp = malloc(sizeof(char) * len); if(!tmp) { Rf_error("Cannot allocate space for attribute of length %d", (int) (ptr[4] - ptr[3] + 2)); } memcpy(tmp, ptr[3], ptr[4] - ptr[3]); tmp[len-1] = '\0'; /*XXX*/ return(tmp); } void R_processBranch(RS_XMLParserData * rinfo, int branchIndex, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes, Rboolean sax1) { xmlNodePtr node; node = xmlNewNode(NULL, localname); if(attributes) { const xmlChar ** p = attributes; int i; if(sax1) { for(i = 0; *p ; i += 2, p += 2) xmlSetProp(node, p[0], p[1]); /*??? Do we need to xmlStrdup() this. */ } else { const xmlChar **ptr = p; for(i = 0; i < nb_attributes; i++, ptr += 5) { /*XXX does this get freed later on?*/ xmlSetProp(node, xmlStrdup(ptr[0]), (const xmlChar *)getPropertyValue(ptr)); } } } if(rinfo->current) { /* Add to children */ xmlAddChild(rinfo->current, node); } else { rinfo->top = node; rinfo->branchIndex = branchIndex; } rinfo->current = node; } void R_xmlFreeNode(SEXP node) { xmlNodePtr p; p = R_ExternalPtrAddr(node); if(p) { xmlFreeNode(p); #ifdef R_XML_DEBUG fprintf(stderr, "Freeing XML node from a branch\n"); #endif } R_SetExternalPtrAddr(node, NULL_USER_OBJECT); } int numDocsCreated = 0; void R_reportDocGC(void) { REprintf("\n", numDocsCreated, R_numXMLDocs, R_numXMLDocsFreed); } void R_endBranch(RS_XMLParserData *rinfo, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI) { if(rinfo->current) { xmlNodePtr tmp; xmlDocPtr doc = NULL; tmp = rinfo->current; if(tmp->parent == NULL) { /* Call the function with the given node.*/ SEXP fun, args; USER_OBJECT_ rnode; if(rinfo->dynamicBranchFunction) fun = rinfo->dynamicBranchFunction; else { fun = VECTOR_ELT(rinfo->branches, rinfo->branchIndex); } PROTECT(args = NEW_LIST(1)); if(tmp->doc == NULL) { doc = xmlNewDoc((const xmlChar*) "1.0"); initDocRefCounter(doc); xmlDocSetRootElement(doc, tmp); /* fprintf(stderr, "\n", doc); */ numDocsCreated++; } SET_VECTOR_ELT(args, 0, rnode = R_createXMLNodeRef(tmp, rinfo->finalize)); RS_XML(invokeFunction)(fun, args, NULL, rinfo->ctx); UNPROTECT(1); /* xmlFreeNode(rinfo->top); rinfo->top = NULL; */ #if 0 fprintf(stderr, "Finishing branch for %s %s\n", tmp->name, tmp->properties->children->content); #endif /* if(rinfo->dynamicBranchFunction) R_ReleaseObject(rinfo->dynamicBranchFunction); */ } rinfo->current = rinfo->current->parent; if(rinfo->current && (rinfo->current->type == XML_DOCUMENT_NODE || rinfo->current->type == XML_HTML_DOCUMENT_NODE)) rinfo->current = NULL; } } static int isBranchFunction(SEXP obj) { int i, n; SEXP classes; if(TYPEOF(obj) != CLOSXP) return(0); classes = GET_CLASS(obj); n = GET_LENGTH(classes); for(i = 0; i < n; i++) if(strcmp(CHAR(STRING_ELT(classes, i)), "SAXBranchFunction") == 0) return(1); return(0); } static void RS_XML(xmlSAX2StartElementNs)(void * userData, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI, int nb_namespaces, const xmlChar ** namespaces, int nb_attributes, int nb_defaulted, const xmlChar ** attributes) { int i, n; USER_OBJECT_ tmp, names; USER_OBJECT_ opArgs, ans; RS_XMLParserData *rinfo = (RS_XMLParserData*) userData; DECL_ENCODING_FROM_EVENT_PARSER(rinfo) if(!localname) return; /* if there is a branch function in the branches argument of xmlEventParse() with this name, call that and return.*/ if((i = R_isBranch(localname, rinfo)) != -1) { R_processBranch(rinfo, i, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes, FALSE); return; } PROTECT(opArgs = NEW_LIST(4)); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(localname))); /* Now convert the attributes list. */ SET_VECTOR_ELT(opArgs, 1, createSAX2AttributesList(attributes, nb_attributes, nb_defaulted, encoding)); PROTECT(tmp = NEW_CHARACTER(1)); if(URI) { SET_STRING_ELT(tmp, 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(URI))); SET_NAMES(tmp, ScalarString(CreateCharSexpWithEncoding(encoding, ( (void*)prefix ? prefix : (const xmlChar *)"")))); } SET_VECTOR_ELT(opArgs, 2, tmp); UNPROTECT(1); n = nb_namespaces; PROTECT(tmp = NEW_CHARACTER(n)); PROTECT(names = NEW_CHARACTER(n)); for(i = 0, n = 0; n < nb_namespaces; n++, i+=2) { SET_STRING_ELT(tmp, n, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(namespaces[i+1]))); if(namespaces[i]) SET_STRING_ELT(names, n, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(namespaces[i]))); } SET_NAMES(tmp, names); SET_VECTOR_ELT(opArgs, 3, tmp); UNPROTECT(2); ans = RS_XML(callUserFunction)(HANDLER_FUN_NAME(rinfo, "startElement"), XMLCHAR_TO_CHAR(localname), rinfo, opArgs); /* If the handler function returned us a SAXBranchFunction function, then we need to build the node's sub-tree and then invoke the function with that node as the main argument. (It may also get the context/parser.) */ if(isBranchFunction(ans)) { /* Hold on to the function to avoid it being garbage collected. */ R_PreserveObject(rinfo->dynamicBranchFunction = ans); /* Start the creation of the node's sub-tree. */ R_processBranch(rinfo, -1, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes, FALSE); } UNPROTECT(1); } static void RS_XML(xmlSAX2EndElementNs)(void * ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI) { USER_OBJECT_ args, tmp, fun; RS_XMLParserData *rinfo = (RS_XMLParserData *) ctx; DECL_ENCODING_FROM_EVENT_PARSER(rinfo) if(rinfo->current) { R_endBranch(rinfo, localname, prefix, URI); return; } PROTECT(args = NEW_LIST(2)); SET_VECTOR_ELT(args, 0, ScalarString(ENC_COPY_TO_USER_STRING(localname))); PROTECT(tmp = ScalarString(ENC_COPY_TO_USER_STRING(URI ? URI : (const xmlChar *)""))); if(prefix) SET_NAMES(tmp, ScalarString(ENC_COPY_TO_USER_STRING(prefix))); SET_VECTOR_ELT(args, 1, tmp); fun = findEndElementFun((const char *)localname, rinfo); if(fun) { USER_OBJECT_ val = PROTECT(RS_XML(invokeFunction)(fun, args, rinfo->stateObject, rinfo->ctx)); updateState(val, rinfo); UNPROTECT(1); } else RS_XML(callUserFunction)(HANDLER_FUN_NAME(ctx, "endElement"), NULL, (RS_XMLParserData *)ctx, args); UNPROTECT(2); } #if 0 static void RS_XML(xmlSAX2StartDocument)(void *userData) { } #endif void RS_XML(initXMLParserHandler)(xmlSAXHandlerPtr xmlParserHandler, int saxVersion) { if(saxVersion == 2) { xmlParserHandler->initialized = 0; xmlSAX2InitDefaultSAXHandler(xmlParserHandler, 0); xmlParserHandler->initialized = XML_SAX2_MAGIC; xmlParserHandler->startElementNs = RS_XML(xmlSAX2StartElementNs); xmlParserHandler->endElementNs = RS_XML(xmlSAX2EndElementNs); xmlParserHandler->startElement = NULL; xmlParserHandler->endElement = NULL; xmlParserHandler->serror = RS_XML(structuredErrorHandler); } else { xmlParserHandler->startElement = RS_XML(startElementHandler); xmlParserHandler->endElement = RS_XML(endElementHandler); } xmlParserHandler->entityDecl = RS_XML(entityDeclaration); xmlParserHandler->getEntity = RS_XML(getEntityHandler); xmlParserHandler->comment = RS_XML(commentElementHandler); xmlParserHandler->characters = RS_XML(charactersHandler); xmlParserHandler->processingInstruction = RS_XML(piHandler); xmlParserHandler->cdataBlock = RS_XML(cdataBlockHandler); xmlParserHandler->startDocument = RS_XML(startDocumentHandler); xmlParserHandler->endDocument = RS_XML(endDocumentHandler); xmlParserHandler->isStandalone = RS_XML(isStandAloneHandler); xmlParserHandler->fatalError = RS_XML(fatalErrorHandler); xmlParserHandler->warning = RS_XML(warningHandler); xmlParserHandler->error = RS_XML(errorHandler); /* external entity */ xmlParserHandler->internalSubset = NULL; xmlParserHandler->externalSubset = NULL; xmlParserHandler->hasInternalSubset = NULL; xmlParserHandler->hasExternalSubset = NULL; xmlParserHandler->resolveEntity = NULL; xmlParserHandler->getParameterEntity = RS_XML(getParameterEntityHandler); xmlParserHandler->attributeDecl = NULL; xmlParserHandler->elementDecl = NULL; xmlParserHandler->notationDecl = NULL; xmlParserHandler->unparsedEntityDecl = NULL; xmlParserHandler->setDocumentLocator = NULL; xmlParserHandler->reference = NULL; xmlParserHandler->ignorableWhitespace = NULL; } void RS_XML(startElementHandler)(void *userData, const xmlChar *name, const xmlChar **atts) { RS_XML(startElement)(userData, (const char *)name, (const char **)atts); } void RS_XML(endElementHandler)(void *ctx, const xmlChar *name) { RS_XML(endElement)(ctx, (const char *)name); } void RS_XML(commentElementHandler)(void *ctx, const xmlChar *val) { RS_XML(commentHandler)(ctx, (const XML_Char*)val); } void RS_XML(charactersHandler)(void *user_data, const xmlChar *ch, int len) { RS_XML(textHandler)(user_data, (const XML_Char*)ch, len); } void RS_XML(startDocumentHandler)(void *ctx) { RS_XML(callUserFunction)(HANDLER_FUN_NAME(ctx, "startDocument"), NULL, ((RS_XMLParserData*) ctx), NULL_USER_OBJECT); } void RS_XML(endDocumentHandler)(void *ctx) { RS_XML(callUserFunction)(HANDLER_FUN_NAME(ctx, "endDocument"), NULL, ((RS_XMLParserData*) ctx), NULL_USER_OBJECT); } void RS_XML(cdataBlockHandler)(void *ctx, const xmlChar *value, int len) { USER_OBJECT_ opArgs; RS_XMLParserData *parserData = (RS_XMLParserData*) ctx; DECL_ENCODING_FROM_EVENT_PARSER(parserData) if(parserData->current) { xmlAddChild(parserData->current, xmlNewCDataBlock(NULL, value, len)); return; } PROTECT(opArgs = NEW_LIST(1)); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR(value))); RS_XML(callUserFunction)(HANDLER_FUN_NAME(parserData, "cdata"), (const char *)NULL, (RS_XMLParserData*)ctx, opArgs); UNPROTECT(1); } void RS_XML(piHandler)(void *ctx, const xmlChar *target, const xmlChar *data) { RS_XML(processingInstructionHandler)(ctx, (const XML_Char*)target, (const XML_Char*)data); } //#define RString(x) (x ? mkString(XMLCHAR_TO_CHAR((x))) : NEW_CHARACTER(1)) #define RString(x) (x ? ScalarString(ENC_COPY_TO_USER_STRING(XMLCHAR_TO_CHAR((x)))) : NEW_CHARACTER(1)) /* Relies on the order and numbering of xmlEntityType from entities.h */ static const char * const EntityTypeNames[] = { "Internal_General", "External_General_Parsed", "External_General_Unparsed", "Internal_Parameter", "External_Parameter", "Internal_Predefined" }; void RS_XML(entityDeclaration)(void *ctx, const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) { USER_OBJECT_ fun, opArgs, tmp; RS_XMLParserData *parserData = (RS_XMLParserData*) ctx; DECL_ENCODING_FROM_EVENT_PARSER(parserData) /* check if there is a function to call before making the list of 5 elements. */ fun = RS_XML(findFunction)(HANDLER_FUN_NAME(parserData, "entityDeclaration"), parserData->methods); if(fun == NULL || fun == NULL_USER_OBJECT) return; PROTECT(fun); PROTECT(opArgs = NEW_LIST(5)); SET_VECTOR_ELT(opArgs, 0, RString(name)); PROTECT(tmp = ScalarInteger(type)); SET_NAMES(tmp, mkString(EntityTypeNames[type-1])); SET_VECTOR_ELT(opArgs, 1, tmp); UNPROTECT(1); SET_VECTOR_ELT(opArgs, 2, RString(content)); SET_VECTOR_ELT(opArgs, 3, RString(systemId)); SET_VECTOR_ELT(opArgs, 4, RString(publicId)); (void) RS_XML(invokeFunction)(fun, opArgs, parserData->stateObject, parserData->ctx); UNPROTECT(2); } static xmlEntityPtr do_getEntityHandler(void *userData, const xmlChar *name, const char * r_funName) { SEXP opArgs, r_ans; xmlEntityPtr ans = NULL; RS_XMLParserData *parserData = (RS_XMLParserData*) userData; DECL_ENCODING_FROM_EVENT_PARSER(parserData) PROTECT(opArgs = NEW_LIST(1)) ; SET_VECTOR_ELT(opArgs, 0, ScalarString(ENC_COPY_TO_USER_STRING(name))); /*XXX should we encode this? Done now! */ r_ans = RS_XML(callUserFunction)(r_funName, NULL, (RS_XMLParserData *) userData, opArgs); PROTECT(r_ans) ; if(r_ans != NULL_USER_OBJECT && GET_LENGTH(r_ans) > 0) { if(TYPEOF(r_ans) == STRSXP) { const char *value; value = CHAR_DEREF(STRING_ELT(r_ans, 0)); ans = (xmlEntityPtr) malloc(sizeof(xmlEntity)); memset(ans, 0, sizeof(xmlEntity)); ans->type = XML_ENTITY_DECL; ans->etype = XML_INTERNAL_GENERAL_ENTITY; ans->name = xmlStrdup(name); ans->orig = NULL; // xmlStrdup(CHAR_TO_XMLCHAR(value)); ans->content = xmlStrdup(CHAR_TO_XMLCHAR(value)); ans->length = (int)strlen(value); #ifndef NO_CHECKED_ENTITY_FIELD ans->checked = 1; #endif } } UNPROTECT(2); return(ans); } xmlEntityPtr RS_XML(getEntityHandler)(void *userData, const xmlChar *name) { return(do_getEntityHandler(userData, name, HANDLER_FUN_NAME(userData, "getEntity"))); } xmlEntityPtr RS_XML(getParameterEntityHandler)(void *userData, const xmlChar *name) { return(do_getEntityHandler(userData, name, HANDLER_FUN_NAME(userData, "getParameterEntity"))); } int RS_XML(isStandAloneHandler)(void *ctx) { return(1); } void RS_XML(fatalErrorHandler)(void *ctx, const char *format, ...) { const char *msg = "error message unavailable"; va_list args; va_start(args, format); if(strcmp(format, "%s") == 0) msg = va_arg(args, char *); va_end(args); Rf_error("Fatal error in the XML event driven parser for %s: %s", ((RS_XMLParserData*) ctx)->fileName, msg); } void RS_XML(errorHandler)(void *ctx, const char *format, ...) { const char *msg = "error message unavailable"; va_list args; va_start(args, format); if(strcmp(format, "%s") == 0) msg = va_arg(args, char *); va_end(args); Rf_error("Error in the XML event driven parser for %s: %s", ((RS_XMLParserData*) ctx)->fileName, msg); } // was RS_XML(structuredErrorHandler)(void *ctx, const xmlError err) void #if LIBXML_VERSION < 21200 RS_XML(structuredErrorHandler)(void *ctx, xmlErrorPtr err) #else RS_XML(structuredErrorHandler)(void *ctx, const struct _xmlError *err) #endif { if(err->level == XML_ERR_FATAL) { Rf_error("Error in the XML event driven parser (line = %d, column = %d): %s", err->line, err->int2 , err->message); } else { Rf_warning("Error in the XML event driven parser (line = %d, column = %d): %s", err->line, err->int2 , err->message); } } void RS_XML(warningHandler)(void *ctx, const char *msg, ...) { Rf_warning("XML event driven parser warning from %s.", ((RS_XMLParserData*) ctx)->fileName); } SEXP RS_XML_xmlStopParser(SEXP r_context) { xmlParserCtxtPtr context; if(TYPEOF(r_context) != EXTPTRSXP || R_ExternalPtrTag(r_context) != Rf_install(XML_PARSER_CONTEXT_TYPE_NAME)) { Rf_error("xmlStopParser requires an " XML_PARSER_CONTEXT_TYPE_NAME " object"); } context = (xmlParserCtxtPtr) R_ExternalPtrAddr(r_context); if(!context) { Rf_error("NULL value passed to RS_XML_xmlStopParser. Is it a value from a previous session?"); } xmlStopParser(context); return(ScalarLogical(1)); } XML/src/libxmlFeatures.c0000644000175100001440000000443214327573457014675 0ustar hornikusers#include "RS_XML.h" #include "Utils.h" #ifdef FROM_GNOME_XML_DIR #include #else #include #endif SEXP R_getXMLFeatures(void) { #ifdef HAVE_XML_HAS_FEATURE int features[] = { XML_WITH_THREAD, XML_WITH_TREE, XML_WITH_OUTPUT, XML_WITH_PUSH, XML_WITH_READER, XML_WITH_PATTERN, XML_WITH_WRITER, XML_WITH_SAX1, XML_WITH_FTP, XML_WITH_HTTP, XML_WITH_VALID, XML_WITH_HTML, XML_WITH_LEGACY, XML_WITH_C14N, XML_WITH_CATALOG, XML_WITH_XPATH, XML_WITH_XPTR, XML_WITH_XINCLUDE, XML_WITH_ICONV, XML_WITH_ISO8859X, XML_WITH_UNICODE, XML_WITH_REGEXP, XML_WITH_AUTOMATA, XML_WITH_EXPR, XML_WITH_SCHEMAS, XML_WITH_SCHEMATRON, XML_WITH_MODULES, XML_WITH_DEBUG, XML_WITH_DEBUG_MEM, XML_WITH_DEBUG_RUN, #ifdef HAVE_XML_WITH_ZLIB XML_WITH_ZLIB #else -1 #endif }; const char * const names[] = { "THREAD", "TREE", "OUTPUT", "PUSH", "READER", "PATTERN", "WRITER", "SAX1", "FTP", "HTTP", "VALID", "HTML", "LEGACY", "C14N", "CATALOG", "XPATH", "XPTR", "XINCLUDE", "ICONV", "ISO8859X", "UNICODE", "REGEXP", "AUTOMATA", "EXPR", "SCHEMAS", "SCHEMATRON", "MODULES", "DEBUG", "DEBUG_MEM", "DEBUG_RUN", "ZLIB" }; SEXP ans, rnames; int n = sizeof(features)/sizeof(features[0]), i; PROTECT(ans = allocVector(LGLSXP, n)); PROTECT(rnames = allocVector(STRSXP, n)); for(i = 0; i < n; i++) { if(features[i] > -1) LOGICAL(ans)[i] = xmlHasFeature(features[i]); else LOGICAL(ans)[i] = NA_LOGICAL; SET_STRING_ELT(rnames, i, mkChar(names[i])); } SET_NAMES(ans, rnames); UNPROTECT(2); return(ans); #else return(allocVector(STRSXP, 0)); #endif } XML/src/RSCommon.h0000644000175100001440000000124013607633744013377 0ustar hornikusers /* Copyright the Omegahat project 1999-2005. Distributed under the GPL license (version 2). */ /* Cut-dpwn version for XML as an R package */ #ifndef RSCOMMON_H #define RSCOMMON_H #ifdef __cplusplus extern "C" { #endif #include #include #ifdef length #undef length #endif #ifdef GET_LENGTH #undef GET_LENGTH #define GET_LENGTH(x) Rf_length(x) #endif #ifdef append #undef append #endif typedef SEXP USER_OBJECT_; typedef int RSInt; #include "R_ext/Boolean.h" #define CHAR_DEREF(x) CHAR((x)) #define IS_FUNCTION(x) isFunction((x)) #ifdef __cplusplus } #endif #endif /* end of RSCOMMON_H*/ XML/src/EventParse.c0000644000175100001440000003513614106741723013754 0ustar hornikusers /* File that provides the entry point for an event driven XML parser that performs callbacks to the different user-level functions in the closure passed to it. * See Copyright for the license status of this software. */ #include "EventParse.h" #define R_USE_XML_ENCODING 1 #include "Utils.h" /* For the findFunction and invokeFunction. */ #undef R_USE_XML_ENCODING /*XXX */ #include "RSCommon.h" extern void R_PreserveObject(SEXP); extern void R_ReleaseObject(SEXP); /* Read the specified file as an XML document and invoke functions/methods in the handlers closure object when each node in the tree is encountered by the parser. These events are startElement,endElement, character data, etc. The remaining arguments control how the calls to the user level functions are made. The first (addContext) indicates whether information about the position in the tree (an integer index path) */ typedef Rboolean Sboolean; Sboolean IsConnection(USER_OBJECT_ obj) { int i; USER_OBJECT_ k = GET_CLASS(obj); if(GET_LENGTH(k) == 0) return(FALSE); for(i = 0; i < GET_LENGTH(k); i++) { if(strcmp("connection", CHAR_DEREF(STRING_ELT(k, i))) == 0) return(TRUE); } return(FALSE); } static USER_OBJECT_ RS_XML(createAttributesList)(const char **atts, const xmlChar *encoding) { int n=0, i; const char **ptr = atts; USER_OBJECT_ attr_names; USER_OBJECT_ attr_values; while(ptr && ptr[0]) { n++; ptr += 2; } if(n < 1) return(NULL_USER_OBJECT); PROTECT(attr_values = NEW_CHARACTER(n)); PROTECT(attr_names = NEW_CHARACTER(n)); ptr = atts; for(i=0; i < n; i++, ptr+=2) { SET_STRING_ELT(attr_values, i, ENC_COPY_TO_USER_STRING(ptr[1])); SET_STRING_ELT(attr_names, i, ENC_COPY_TO_USER_STRING(ptr[0])); } SET_NAMES(attr_values, attr_names); UNPROTECT(2); return(attr_values); } USER_OBJECT_ RS_XML(Parse)(USER_OBJECT_ fileName, USER_OBJECT_ handlers, USER_OBJECT_ endElementHandlers, USER_OBJECT_ addContext, USER_OBJECT_ ignoreBlanks, USER_OBJECT_ useTagName, USER_OBJECT_ asText, USER_OBJECT_ trim, USER_OBJECT_ useExpat, USER_OBJECT_ stateObject, USER_OBJECT_ replaceEntities, USER_OBJECT_ validate, USER_OBJECT_ saxVersion, USER_OBJECT_ branches, USER_OBJECT_ useDotNames, USER_OBJECT_ errorFun, USER_OBJECT_ manageMemory, USER_OBJECT_ r_encoding) { #ifdef LIBEXPAT FILE *file = NULL; int expat = 0; #endif char *name, *input; RS_XML_ContentSourceType asTextBuffer; RS_XMLParserData *parserData; USER_OBJECT_ ans; int status; if(IsConnection(fileName) || isFunction(fileName)) asTextBuffer = RS_XML_CONNECTION; else asTextBuffer = LOGICAL_DATA(asText)[0] ? RS_XML_TEXT : RS_XML_FILENAME; #ifdef LIBEXPAT expat = LOGICAL_DATA(useExpat)[0]; if(expat && asTextBuffer == 0) { #ifdef USE_R name = R_ExpandFileName(CHAR(STRING(fileName)[0])); #else name = CHARACTER_DATA(fileName)[0]; #endif file = fopen(name,"r"); if(file == NULL) { Rf_error("Can't find file %s", name); } } else #endif /* ifdef LIBEXPAT */ if(asTextBuffer == RS_XML_CONNECTION) { name = strdup(""); input = (char *)fileName;/*XXX*/ } else { name = strdup(CHAR_DEREF(STRING_ELT(fileName, 0))); input = name; } parserData = RS_XML(createParserData)(handlers, manageMemory); parserData->endElementHandlers = endElementHandlers; parserData->branches = branches; parserData->fileName = name; parserData->callByTagName = LOGICAL_DATA(useTagName)[0]; parserData->addContextInfo = LOGICAL_DATA(addContext)[0]; parserData->trim = LOGICAL_DATA(trim)[0]; parserData->ignoreBlankLines = LOGICAL_DATA(ignoreBlanks)[0]; parserData->stateObject = (stateObject == NULL_USER_OBJECT ? NULL : stateObject); parserData->useDotNames = LOGICAL_DATA(useDotNames)[0]; parserData->dynamicBranchFunction = NULL; /*Is this necessary? Shouldn't it already be protected? Or is there a chance that we may be doing this asynchronously in a pull approach. */ if(parserData->stateObject && parserData->stateObject != NULL_USER_OBJECT) R_PreserveObject(parserData->stateObject); #ifdef LIBEXPAT if(expat) { if(asTextBuffer == 0) { RS_XML(parseWithParserData)(file, parserData); } else { parserData->fileName = ""; RS_XML(parseBufferWithParserData)(name, parserData); free(name); /* match the strdup() above */ } } else #endif /* ifdef LIBEXPAT */ #if 0 /* If one wants entities expanded directly and to appear as text. */ xmlSubstituteEntitiesDefault(LOGICAL_DATA(replaceEntities)[0]); #endif status = RS_XML(libXMLEventParse)(input, parserData, asTextBuffer, INTEGER_DATA(saxVersion)[0], r_encoding); /* How about using R_alloc() here so that it is freed, i.e. for the fileName and the parserData itself. */ ans = parserData->stateObject ? parserData->stateObject : handlers; free(parserData->fileName); if(parserData->stateObject && parserData->stateObject != NULL_USER_OBJECT) R_ReleaseObject(parserData->stateObject); if(status != 0) RSXML_structuredStop(errorFun, NULL); /* free(parserData); Now using R_alloc */ return(ans); } /** Handler that receives declarations of unparsed entities. These are entity declarations that have a notation (NDATA) field: */ void RS_XML(entityDeclarationHandler)(void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName) { RS_XMLParserData *parserData = (RS_XMLParserData*)userData; USER_OBJECT_ opArgs; int i, num; const XML_Char *xml_args[5]; DECL_ENCODING_FROM_EVENT_PARSER(parserData) num = sizeof(xml_args)/sizeof(xml_args[0]); xml_args[0] = entityName; xml_args[1] = base; xml_args[2] = systemId; xml_args[3] = publicId; xml_args[4] = notationName; opArgs = PROTECT(NEW_LIST(num)); for(i =0;i < num; i++) { SET_VECTOR_ELT(opArgs, i, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, i), 0, ENC_COPY_TO_USER_STRING(xml_args[i] ? (const xmlChar *)xml_args[i] : (const xmlChar *)"")); } RS_XML(callUserFunction)(HANDLER_FUN_NAME(parserData, "entityDeclaration"), (const char*)NULL, parserData, opArgs); UNPROTECT(1); } void RS_XML(startElement)(void *userData, const char *name, const char **atts) { USER_OBJECT_ opArgs; int i; RS_XMLParserData *rinfo = (RS_XMLParserData*) userData; DECL_ENCODING_FROM_EVENT_PARSER(rinfo) if((i = R_isBranch(CHAR_TO_XMLCHAR(name), rinfo)) != -1) { R_processBranch(rinfo, i, CHAR_TO_XMLCHAR(name), NULL, NULL, 0, NULL, 0, 0, (const xmlChar ** /*XXX*/) atts, 1); return; } PROTECT(opArgs = NEW_LIST(2)); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(name)); /* Now convert the attributes list. */ SET_VECTOR_ELT(opArgs, 1, RS_XML(createAttributesList)(atts, encoding)); RS_XML(callUserFunction)(HANDLER_FUN_NAME(rinfo, "startElement"), name, ((RS_XMLParserData*) userData), opArgs); UNPROTECT(1); } void RS_XML(commentHandler)(void *userData, const XML_Char *data) { USER_OBJECT_ opArgs = NEW_LIST(1); RS_XMLParserData *rinfo = (RS_XMLParserData *) userData; DECL_ENCODING_FROM_EVENT_PARSER(rinfo) PROTECT(opArgs); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(data)); RS_XML(callUserFunction)(HANDLER_FUN_NAME(rinfo, "comment"), (const char *)NULL, ((RS_XMLParserData*)userData), opArgs); UNPROTECT(1); } USER_OBJECT_ findEndElementFun(const char *name, RS_XMLParserData *rinfo) { int i, n; USER_OBJECT_ names = GET_NAMES(rinfo->endElementHandlers); n = GET_LENGTH(rinfo->endElementHandlers); for(i = 0 ; i < n ; i++) { if(strcmp(CHAR_DEREF(STRING_ELT(names, i)), name) == 0) return(VECTOR_ELT(rinfo->endElementHandlers, i)); } return(NULL); } void RS_XML(endElement)(void *userData, const char *name) { USER_OBJECT_ opArgs, fun; RS_XMLParserData *rinfo = (RS_XMLParserData *) userData; DECL_ENCODING_FROM_EVENT_PARSER(rinfo) if(rinfo->current) { /* Dealing with a branch, so close up. */ R_endBranch(rinfo, CHAR_TO_XMLCHAR(name), NULL, NULL); return; } ((RS_XMLParserData*)userData)->depth++; /* ??? should this be depth-- */ PROTECT(opArgs = NEW_LIST(1)); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(name)); fun = findEndElementFun(name, rinfo); if(fun) { USER_OBJECT_ val = PROTECT(RS_XML(invokeFunction)(fun, opArgs, rinfo->stateObject, rinfo->ctx)); updateState(val, rinfo); UNPROTECT(1); } else RS_XML(callUserFunction)(HANDLER_FUN_NAME(rinfo, "endElement"), NULL, ((RS_XMLParserData*) userData), opArgs); UNPROTECT(1); } /** Called for inline expressions of the form such as */ void RS_XML(processingInstructionHandler)(void *userData, const XML_Char *target, const XML_Char *data) { USER_OBJECT_ opArgs; RS_XMLParserData *parserData = (RS_XMLParserData *) userData; DECL_ENCODING_FROM_EVENT_PARSER(parserData) PROTECT(opArgs = NEW_LIST(2)); SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(target)); SET_VECTOR_ELT(opArgs, 1, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 1), 0, ENC_COPY_TO_USER_STRING(data)); RS_XML(callUserFunction)(HANDLER_FUN_NAME(parserData, "processingInstruction"), (const char *)NULL, (RS_XMLParserData*)userData, opArgs); UNPROTECT(1); } void RS_XML(startCdataSectionHandler)(void *userData) { } void RS_XML(endCdataSectionHandler)(void *userData) { } char * fixedTrim(char *str, int len, int *start, int *end) { char *tmp; *end = len; *start = 0; /* If a degenerate string, just return. */ if(len == 0 || str == (char*)NULL || str[0] == '\0') return(str); /* Jump to the end */ tmp = str + len - 2; // DTL has 1 while(tmp >= str && isspace(*tmp)) { tmp--; (*end)--; } if(tmp == str) { return(str); } tmp = str; while(*start <= *end && *tmp && isspace(*tmp)) { tmp++; (*start)++; } return(tmp); } void RS_XML(textHandler)(void *userData, const XML_Char *s, int len) { char *tmpString, *tmp; USER_OBJECT_ opArgs = NULL; RS_XMLParserData *parserData = (RS_XMLParserData*)userData; DECL_ENCODING_FROM_EVENT_PARSER(parserData) int nprot = 0; /* XXX Here is where we have to ignoreBlankLines and use the trim setting in parserData */ if(parserData->current) { xmlChar *tmp; int newLen = len, start = 0, end = len; #if 1 if(parserData->trim) { tmpString = fixedTrim(XMLCHAR_TO_CHAR(s), len, &start, &end); newLen = end - start; } else tmpString = XMLCHAR_TO_CHAR(s); if(newLen < 0 && parserData->ignoreBlankLines) return; #else tmpString = s; #endif if(newLen < 0) tmp = (xmlChar *)strdup(""); else { tmp = (xmlChar *) S_alloc(newLen + 2, sizeof(xmlChar)); memcpy(tmp, tmpString, newLen); tmp[newLen] = '\0'; } xmlAddChild(parserData->current, xmlNewText(tmp)); //XXX??? if(newLen < 0) free(tmp); return; } /* Last case handles ignoring the new line between the two nodes if trim is TRUE. */ if(s == (XML_Char*)NULL || s[0] == (XML_Char)0 || len == 0 || (len == 1 && ((const char *) s)[0] == '\n' && parserData->trim)) return; /*XXX Deal with encoding, memory cleanup, 1 more than length so we can put a \0 on the end. */ tmp = tmpString = (char*)calloc(len+1, sizeof(char)); strncpy(tmpString, s, len); if(parserData->trim) { tmpString = trim(tmpString); len = (int) strlen(tmpString); } if(len > 0 || parserData->ignoreBlankLines == 0 ) { PROTECT(opArgs = NEW_LIST(1)); nprot++; SET_VECTOR_ELT(opArgs, 0, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(opArgs, 0), 0, ENC_COPY_TO_USER_STRING(tmpString)); } free(tmp); /* If we are ignoring blanks and the potentially newly computed length is non-zero, then call the user function. */ if(opArgs != NULL) { RS_XML(callUserFunction)(HANDLER_FUN_NAME(parserData, "text"), (const char *)NULL, ((RS_XMLParserData*) userData), opArgs); } UNPROTECT(nprot); } int RS_XML(notStandAloneHandler)(void *userData) { /* printf("In NotStandalone handler\n"); */ return(1); } /** Create the parser data which contains the the collection of functions to call for each event type. This allocates the parser memory using calloc. The caller should arrange to free it. */ RS_XMLParserData * RS_XML(createParserData)(USER_OBJECT_ handlers, USER_OBJECT_ finalize) { RS_XMLParserData *parser = (RS_XMLParserData *) R_alloc(1, sizeof(RS_XMLParserData)); memset(parser, '\0', sizeof(RS_XMLParserData)); parser->methods = handlers; parser->finalize = finalize; return(parser); } /** Routine that locates and invokes the R function in the collection of handlers. opName is the identifier for the generic operation, i.e. startElement, text, etc. perferredName is the identifier for the node. */ USER_OBJECT_ RS_XML(callUserFunction)(const char *opName, const char *preferredName, RS_XMLParserData *parserData, USER_OBJECT_ opArgs) { USER_OBJECT_ fun = NULL, val; USER_OBJECT_ _userObject = parserData->methods; // int general = 0; R_CHECK_INTERRUPTS if(preferredName && parserData->callByTagName) { fun = RS_XML(findFunction)(preferredName, _userObject); } if(fun == NULL) { // general = 1; fun = RS_XML(findFunction)(opName, _userObject); } if(fun == NULL || isFunction(fun) == 0 ) { /* || (general && R_isInstanceOf(fun, "AsIs"))) Should we do this? */ /* FAILED */ return(NULL_USER_OBJECT); } val = PROTECT(RS_XML(invokeFunction)(fun, opArgs, parserData->stateObject, parserData->ctx)); updateState(val, parserData); UNPROTECT(1); return(val); } void updateState(USER_OBJECT_ val, RS_XMLParserData *parserData) { if(!parserData->stateObject || parserData->stateObject == NULL_USER_OBJECT) { return; } #ifdef _R_ R_ReleaseObject(parserData->stateObject); R_PreserveObject(val); #else decr_ref_count(parserData->stateObject, TRUE, Local_data, S_evaluator); incr_ref_count(val, TRUE, Local_data, S_evaluator); #endif parserData->stateObject = val; } XML/src/DocParse.h0000644000175100001440000000312013607633744013401 0ustar hornikusers/* * See Copyright for the license status of this software. */ #ifndef XMLPARSE_H #define XMLPARSE_H #include #include #include "RSCommon.h" #include "RS_XML.h" #ifdef FROM_GNOME_XML_DIR #include #else #include #endif typedef struct { int skipBlankLines; int trim; int xinclude; USER_OBJECT_ converters; int addAttributeNamespaces; int internalNodeReferences; int fullNamespaceInfo; int useDotNames; SEXP finalize; } R_XMLSettings; enum {DOWN, SIDEWAYS}; USER_OBJECT_ RS_XML(convertXMLDoc)(const char *fileName, xmlDocPtr doc, USER_OBJECT_ converterFunctions, R_XMLSettings *settings); /*USER_OBJECT_ RS_XML(createXMLNode)(xmlNodePtr node, int recursive, int direction, R_XMLSettings *settings, USER_OBJECT_ parentUserNode);*/ USER_OBJECT_ RS_XML(AttributeList)(xmlNodePtr node, R_XMLSettings *settings); USER_OBJECT_ RS_XML(createNodeChildren)(xmlNodePtr node, int direction, R_XMLSettings *parserSettings); USER_OBJECT_ RS_XML(lookupGenericNodeConverter)(xmlNodePtr node, USER_OBJECT_ methods, R_XMLSettings *parserSettings); USER_OBJECT_ RS_XML(createNameSpaceIdentifier)(xmlNs *space, xmlNodePtr node); USER_OBJECT_ RS_XML_xmlXIncludeProcessFlags(USER_OBJECT_ r_doc, USER_OBJECT_ r_flags); USER_OBJECT_ processNamespaceDefinitions(xmlNs *ns, xmlNodePtr node, R_XMLSettings *parserSettings); typedef struct _R_NodeGCInfo { struct _R_NodeGCInfo *prev; struct _R_NodeGCInfo *next; xmlNodePtr node; int count; } R_NodeGCInfo; void initDocRefCounter(xmlDocPtr doc); #endif XML/src/fixNS.c0000644000175100001440000000500513607633771012727 0ustar hornikusers#include #include "RSCommon.h" #include "RS_XML.h" #define R_USE_XML_ENCODING 1 #include "Utils.h" /* R_createXMLNodeRef, Encoding macros. */ // need to release any namespace. int fixDummyNS(xmlNodePtr node, int recursive); int setDummyNS(xmlNodePtr node, const xmlChar *prefix); xmlNs *findNSByPrefix(xmlNodePtr node, const xmlChar *prefix); SEXP R_fixDummyNS(SEXP r_node, SEXP r_recursive) { xmlNodePtr node; int status; node = (xmlNodePtr) R_ExternalPtrAddr(r_node); status = fixDummyNS(node, LOGICAL(r_recursive)[0]); return(ScalarInteger(status)); } int fixDummyNS(xmlNodePtr node, int recursive) { xmlNs *ns = node->ns; int count = 0; if(ns && strcmp((const char *)ns->href, "") == 0) count = setDummyNS(node, ns->prefix); if(recursive) { xmlNodePtr ptr = node->children; while(ptr) { count += fixDummyNS(ptr, recursive); ptr = ptr->next; } } return(count); } int setDummyNS(xmlNodePtr node, const xmlChar *prefix) { xmlNodePtr a = node->parent; while(a) { xmlNs *ns; ns = findNSByPrefix(a, prefix); if(ns) { #ifdef R_XML_DEBUG fprintf(stderr, "mapping %s to %s\n", prefix, ns->href);fflush(stderr); #endif node->nsDef = node->nsDef->next; xmlSetNs(node, ns); return(1); } a = a->parent; } return(0); } xmlNs * findNSByPrefix(xmlNodePtr node, const xmlChar *prefix) { xmlNs *ptr = node->nsDef; while(ptr) { if((!prefix || !prefix[0]) && !ptr->prefix) return(ptr); if(prefix && ptr->prefix && strcmp((const char *)ptr->prefix, (const char *)prefix) == 0) return(ptr); ptr = ptr->next; } return(NULL); } void setDefaultNs(xmlNodePtr node, xmlNsPtr ns, int recursive) { if(!node->ns) xmlSetNs(node, ns); if(recursive) { xmlNodePtr cur = node->children; while(cur) { setDefaultNs(cur, ns, 1); cur = cur->next; } } } SEXP R_getAncestorDefaultNSDef(SEXP r_node, SEXP r_recursive) { xmlNodePtr cur, node; xmlNs *ans = NULL; cur = (xmlNodePtr) R_ExternalPtrAddr(r_node); node = cur->parent; while(node && (node->type != XML_DOCUMENT_NODE && node->type != XML_HTML_DOCUMENT_NODE)) { /* Need to check for HTML_DOC or XML_DOC ?*/ ans = findNSByPrefix(node, NULL); if(ans) break; node = node->parent; } if(ans) { xmlSetNs(cur, ans); if(LOGICAL(r_recursive)[0]) { setDefaultNs(cur, ans, 1); } return(ScalarLogical(1)); // R_createXMLNsRef(ans)); } return(R_NilValue); } XML/src/NodeGC.h0000644000175100001440000000201013607633744012775 0ustar hornikusers#ifndef NODEGC_H #define NODEGC_H #if 1 /* We use the address of a global variable as a marker/signature that indicates we created the value of _private. */ extern int R_XML_MemoryMgrMarker; extern int R_XML_NoMemoryMgmt; #define R_MEMORY_MANAGER_MARKER R_XML_MemoryMgrMarker #define IS_NOT_OUR_DOC_TO_TOUCH(doc) (doc->_private == NULL || (doc->_private && doc->_private == &R_XML_NoMemoryMgmt) || ((int*)doc->_private)[1] != R_MEMORY_MANAGER_MARKER) #define IS_NOT_OUR_NODE_TO_TOUCH(node) ((node->_private == NULL) || (node->doc && node->doc->_private && node->doc->_private == &R_XML_NoMemoryMgmt) || ((int*)node->_private)[1] != R_MEMORY_MANAGER_MARKER) #else /* Not used. */ #define IS_NOT_OUR_DOC_TO_TOUCH(doc) (doc && doc->name && strcmp((doc)->name, " fake node libxslt") == 0) #define IS_NOT_OUR_NODE_TO_TOUCH(node) (node && (node)->doc && IS_NOT_OUR_DOC_TO_TOUCH((node)->doc)) #endif void decrementNodeRefCount(SEXP rnode); void initDocRefCounter(xmlDocPtr doc); void decrementNodeRefCount(SEXP rnode); #endif XML/ChangeLog0000644000175100001440000016076314636531006012523 0ustar hornikusers============ entries from CRAN ============ Version 3.99-0.17 Changes for safe use of R_ExternalPtrAddr() in src/XMLTree.c. Version 3.99-0.16.1 Changes for libxml2 >= 2.11.0, in src/DocParse.c and src/XMLEventParse.c Version 3.99-0.16 Avoid prntf-like warnings Rd markup Version 3.99-0.15 Complete stub in LICENSE file. Version 3.99-0.14 remove unexported generic append() update URLs Version 3.99-0.13 use snprintf instead of sprintf Version 3.99-0.12 version for libxml2 2.10.x update URLs tweaks for -Wstrict-prototypes Version 3.99-0.11 workaround for a LaTeX message that causes R CMD check to interpret it as an error reduce LaTeX warnings Version 3.99-0.10 Rd markup Version 3.99-0.9 replace default.stringsAsFactors() by FALSE Version 3.99-0.8 run autoupdate Version 3.99-0.7 use Rf_{error,warning} rather than S legacy macros Version 3.99-0.6 Add src/Makevars.ucrt Version 3.99-0.5 Update src/Makevars.win Add missing PROTECT() wrappers. Version 3.99-0.4 replace --slave by --no-echo Version: 3.99-0.3 follow DTL with BSD_3_clause tweak for Windows version 3.99-0.2 (2020-01-18) CRAN (not DTL) as maintainer. version 3.99-0.1 First 3.99 version in R svn, bug fixes. ============ entries from DTL ============ Version 3.99-0 * We can specify R functions and C routines for use as XPath functions in calls to getNodeSet() and xpathApply(). * Implementations of XPath 2.0 functions matches(), lower-case(), ends-with(), abs(), min(), max(), replace() Version 3.98-2 * xmlSave() of a document to a file with encoding now honors indenting. Uses xmlSaveFormatFileEnc(). Issue identified by Earl Brown. Version 3.98-1 * xmlToS4() handles attributes with namespace prefixes and children with the same node name. * Compilation error with clang. Simple declaration of a routine. * xmlXIncludes() added. * Changes to simplifyPath(). Version 3.98-0 * Update for libxml2-2.9.1 and reading from a connection for xmlEventParse(). * xmlIncludes() is a hierarchical version of getXIncludes() * Modifications to xmlSource(), e.g. verbose = TRUE as default. Version 3.97-0 * Fix for xmlValue(node) = text. Identified by Lawrence Edwards. Uses xmlNodeSetContent() now and leaves freeing the original content to that routine. * Updates for xmlSource() Version 3.96-1 * readHTMLTable() ignores headers that are over 999 characters. * Fix a problem in readHTMLTable() with some table headers not having the correct number of elements to match the columns. Version 3.96-0 * Introduced readHTMLList(), getHTMLLinks(), getHTMLExternalFiles(), getXIncludes(). * When serializing XMLNode objects, i.e. R representations of nodes, ensure " and <, etc. in attributes are serialized correctly. Version 3.95-1 * Allow htmlParse(), xmlParse(), etc. ? Version 3.95-0 * Moved development version of the source code for the package to github - https://github.com/omegahat/XML.git * Changes to the structure of the package to allow installation directly rather than via a one-step staging into the R package structure. * Sample XML documents moved from data/ to exampleData, and examples updated. * getDefaultNamespace() and matchNamespaces() use simplify = TRUE to call xmlNamespaceDefinitions() to get the namespaces as a character vector rather than list. * Documentation updates Version 3.94-0 * getNodeLocation() now reports the actual line number for text nodes rather than 0, using the sibling nodes' or parent node's line number. * xpathApply() and related functions work with builtin type "functions", e.g. class. * xpathApply() and related functions (getNodeSet, xpathSApply) allow the caller to specify multiple queries as a character vector and these are pasted together as compound location paths by separating them with a '|'. This makes it easier for the caller to manage the different queries. * assigning to a child of a node works, e.g. node[["abc"]] = text/node and node[[index]] = text/node. We replace a matching name. If the replacement value is text, we use the name to * getChildrenStrings() is a function that implements the equivalent of xmlApply(node, xmlValue) but faster because we avoid the function call for each element. * options parameter for xmlParse() and htmlParse() for controlling the parser. (Currently only used when encoding is explicitly specified.) * encoding parameter for xmlParse() and xmlTreeParse() now works for XML documents, not just HTML documents. * Update for readHTMLTable() method so that we look at just the final node in a . Version 3.93-1 * Fixed bug in findXInclude() that sometimes got the wrong XMLXIncludeStartNode. Hence getNodeLocation() might report the wrong file, but correct line number! * findXInclude() now has a recursive parameter that resolves the chain of XIncludes. This returns the full path to the file, relative to the base/top-level document, not just the parent document. * Change to the default value of the error parameter in htmlParse() and htmlTreeParse() which will generate a structured R error if there is an IO error. The set of issues that will raise an error will be broadened in the future. Version 3.93-0 * Enabled the fixing of namespaces by finding the definition o for that prefix in the ancestor nodes. Version 3.92-2 * Synchronized compilation flags for Windows with those on OSX & Linux. Version 3.92-1 * Restore original error handler function for htmlParse() and htmlTreeParse() * Fixed a reference counting problem caused by not adding a finalizer in the as() method for coercing an XMLInternalNode to an XMLInternalDocument. Example from Janko Thyson. * Fixed up some partial argument names found by R CMD check! Version 3.92-0 * Added --enable-xml-debug option for the configure script and this activates the debugging diagnostic reporting, mainly for the garbage collection and node reference counts. * Work-around for HTML documents not being freed (but XML documents are!) * Added an isHTML parameter for xmlTreeParse. * Merge htmlTreeParse/htmlParse with xmlTreeParse. * Implemented some diagnostic facilities to determine if an external pointer is in R's weak references list. This needs support within R. (Ask for code if you want.) Version 3.91-0 * Start of implementation to allow nested calls to newXMLNode() to use namespace prefixes defined in ancestor nodes. Disabled at present. Version 3.9-4 * readHTMLTable() passes the encoding to the cell function. * xmlValue() and saveXML() use the encoding from the document, improving conversion of strings. * More methods for getEncoding() Version 3.9-3 * getEncoding() returns NA when the encoding is not known. Previously, this might seg-fault! * readHTMLTable() passes an encoding argument to the call to xmlValue (and the value of elFun). Version 3.9-2 * Static NAMESPACE (rather than generated via configure) * Default for directory in Makevars.win to search for header files and libraries needed for compilation. Version 3.9-1 * Added method for removeNodes for XMLNodeList. Version 3.9-0 * Enabled additional encoding for element, attribute and namespace names, and in xmlValue(). * Corrected default value in documentation for parse in xmlSource(). Version 3.8-1 * Corrected documentation for readHTMLTable() about stringsAsFactors behaviour. * Added parse = FALSE as parameter for xmlSource() to allow just returning the text from each node. Version 3.8-0 * added readSolrDoc() and readKeyValueDB() functions to read Solr and Property list documents. Version 3.7-4 * saveXML() for XMLNode returns a character vector of length 1, i.e. a single string. Version 3.7-3 * Allow xmlTreeParse() and xmlParse() to process content starting with a BOM. This works when the name of a file/URL is provided, but didn't when the content was provided directly as a string. Identified by Milan Bouchet-Valat. * error message when XML content is not XML or a file name now puts the content at the end for improved readability. Version 3.7-2 * Import methods package explicitly. Version 3.7-1 * Added an alias for the coerce method for Currency. * Added a C routine to query if reference counting is enabled. See tests/checkRefCounts.R. Version 3.7-0 * Added Currency as an option for colClass in readHTMLTable to convert strings of the form $xxx,yyy,zzz, i.e. comma-separated and preceeded by a $. (No other currency supported yet.) * Fix for newXMLNode() that caused a seg fault if a node was specified as the document. Thanks to Jeff Allen. Version 3.6-2 * Changed URL in readHTMLTable() example to new page for population of countries * Changes to Rprintf() rather than stderr. Still some code that uses stderr intentionally. Version 3.6-1 * Fix bug which caused XMLInternalUnknownNode in xmlParent() for HTML documents. * General improvements to support nodes of type XML_HTML_DOCUMENT_NODE. * removeNodes() method for XMLNodeSet. Version 3.6-0 * xmlParent() is an S4 generic with methods. * xmlAncestors() has a count argument to limit the number of ancestors returned. * removeNodes() is generic. * addChildren() now removes "internal" nodes from their current parent, if any. Avoids memory corruption in XML tree. * ADD_XMLOUTPUT_BUFFER R variable for Windows. * Defined XMLTreeNode as an old-style class. Version 3.5-1 * Additional workaround for libxml2 2.6.16 for printing HTML document. * noMatchOk parameter for xpathApply.XMLInternalNode to suppress warnings about finding no nodes when there is a namespace in the query. * xmlNamespace<-() function and methods to allow one to set the namespace on a node, e.g., by the namespace prefix. * readHTMLTable() allows "factor" as an entry in colClasses. Version 3.5-0 * Addeds nsDef parameter for parseXMLAndAdd(). * Minor addition to readHTMLTable() methods to handle malformed HTML with all the tr nodes in the thead. Version 3.4-3 * Set default of append parameter in xmlChildren<-() method for non-internal nodes to FALSE so that we replace the existing nodes. Version 3.4-2 Version 3.4-1 * Type in C code for method for xmlClone(). * Minor fixes for formatting of 2 help/Rd files. * Removed definition of XPathNodeSet which is never used here but redefined in Sxslt. * Fix when adding a default namespace to a node in an HTML document. * Fix when adding a default namespace to a node in an HTML document. Version 3.4-0 * Added xmlSearchNs() to aid looking for XML definitions by URL or prefix. * Support in readHTMLTable() for identifying values formatted as percents or numbers with commas. Use the classes FormattedInteger, FormattedNumber and Percent in colClasses. Version 3.3-2 * Better handling of namespace definitions and uses in newXMLNode and separation of internal code into a separate function. Version 3.3-1 * Configuration to conditionally compile code and export functions for removing finalizers. This relies on C routines tha will be added to the base R distribution, so not present in any released version of R as yet. Version 3.3-0 * addFinalizer added as parameter to many functions and methods that can return a reference to an internal/C-level node. This controls whether a finalizer is added to the node and reference counting is performed. See MemoryManagement.pdf/.html for more details. * One can set the suppressXMLNamespaceWarning as either an XML option (via setOption()) or as a regular R option (via options(suppressXMLNamespaceWarning = ...) ) * Added methods for docName() for XMLHashTreeNode and XMLNode. * added docName when converting from an internal tree to an XMLHashTree. * xmlHashTree() uses an environment with no parent environment, by default. * Added an append parameter to addChildren(). * Fixed coercion from XMLInternalNode to XMLNode. * Made the methods (e.g. xmlAttrs<-(), xmlParent(), ...) for XMLNode and XMLInternalNode consistent. * Made classes agree for xmlParse() and newXMLDoc() * fixed corner/end cases for getSibling for XMLHashTreeNode * Added xmlRoot<- methods for XMLInternalDocument and XMLHashTree. * Minor enhancement to xmlToDataFrame() so that one can pass the value from getNodeSet() directly as the first argument to xmlToDataFrame() without passing it via the nodes parameter. * Registered all of the native routines being invoked via .Call(). Version 3.2-1 * Turn reference counting on by default again. Version 3.2-0 * Change to reference to normalizePath() which was moved from utils to base in R-devel/R-2.13 Version 3.1-1 * Minor change in readHTMLTable method to identify table header better. Version 3.1-0 * Method for [[ for internal element nodes that is much faster (by avoiding creating the list of children and then indexing that R list). Thanks to Stavros Mackracis for raising the issue. Version 3.0-0 * This is not a major release, but an incremental numbering from 2.9-0 to 3.0-0, but with one potentially significant change related to creating nodes. newXMLNode() now uses the namespace of the parent node if the namespace argument is not specified. * Refinments to improve the garbage counting and referencing counting on internal nodes. Version 2.9-0 * xmlAttrs(, TRUE) for internal nodes returns the URL of each namespace definition in the names of the attr(, "namespaces") vector. * Added parseXMLAndAdd() to parse XML from a string text and add the nodes to a parent node. This facilitates creating a large number of quite regular nodes using string processing techniques (e.g. sprintf(), paste()) * xmlEventParse() with branches now has garbage collecting activated. Version 2.8-1 * Filled in missing documentation * Added missing init = TRUE for the parameters in one of the methods for xmlSource(). Version 2.8-0 * xmlClone() puts the original S3 classes on the new object. * Trivial fix to readHTMLTable() to get the header when the table header is inside a tbody. * Garbage collection/Memory management re-enabled. Version 2.7-0 * compareXMLDocs() function * Added xmlSourceFunctions() and xmlSourceSection() * Support in saveXML() for XMLInternalDocument for the prefix parameter. * saveXML() and related methods can deal with NULL pointers in XMLInternalDocument objects. * fixed bug in catalogAdd(). * docName() made an S4 generic with S4 methods (rather than S3 methods). * added catalogDump() * readHTMLTable() puts sensible names on the data frames if there is no header for the table. Version 2.6-0 * When copying a node from one document to another, the node is explicitly copied and not removed from the original document. This also fixes a problem with the name space not being on the resulting node. * New functions for converting simple, shallow XML structure to an R data frame. xmlToDataFrame() & xmlToList() * addChildren() can handle _copying_ a node from a different document. * as()/coerce() method for URI to character. * New functions to convert an XML tree to an S4 object and also to infer S4 class definitions from XML. (makeClassTemplate(), xmlToS4()) * Minor change to C code for compilation on Solaris and Sun Studio Version 2.5-3 * Trivial change to an Rd file to add an omitted Version 2.5-2 * Configuration enhanced to handle very old (but standard on OS X) versions of libxml which do not have the xmlHasFeature() routine. People with such an old version of libxml (i.e. 2.6.16) should consider upgrading. That is 5 years old. Version 2.5-1 * Added a configuration check and compile time condition for the presence of XML_WITH_ZLIB. This allows installation with older versions of libxml2 such as 2.6.26. * Moved some old S3 classes to S4 class definitions to deal with recent changes to the methods package. Version 2.5-0 * Added xmlParseDoc() and parser option constants. These allow one to parse a document from a file, URL or string and specify any combination of 20 different options controlling the parser, e.g. whether to replace entities, perform XInclude, add start and end XInclude nodes, expand entities, load external DTDs, recover when there are errors. * Added libxmlFeatures() to dynamically determine which features were compiled into the version of libxml2. * newXMLNode() has a new argument sibling which is used to add the new node as the sibling of this node. The parametr 'at' is used as the value for the 'after' parameter in addSibling(). * saveXML() is now an S4 generic. (Changes in other packages, e.g. Sxslt, RXMLHelp.) * Added readHTMLTable() which is a reasonably robust and flexible way to read HTML tables. * Added runTime parameter for libxmlVersion() so we can get compile and run time version information. Version 2.4-0 * Significant change to garbage collection facilities for internal/C-level nodes. This works hard to ensure that XMLInternalDocument objects and XMLInternalNode objects in R remain valid even when their "parent" container is released in R. See memory.pdf. This can be disabled with configuration argument --enable-nodegc=no. * Configuration option to compile with xmlsec1 (or xmlsec1-openssl). More to come on support for this. Version 2.3-0 * Added getLineNumber() to be able to determine the line number of an XML node within its original document. * xmlApply() and xmlSApply() have a parameter to ignore the XInclude start and end nodes. * xmlChildren() also have an omitNodeTypes parameter and by default exclude XInclude nodes. * Added ensureNamespace() to add a namespace definition(s) if necessary. Version 2.2-1 * source() method equivalent to xmlSource() and appropriate installation changes for older versions of R ( < 2.8.0). Version 2.2-0 * Added xmlClone() and findXInclude() functions. * [Important] Bug fix regarding the error handling function for XML and HTML parsing. Uncovered by Roger Koenker. This manifested itself in R errors of the form "attempt to apply non-function". Version 1.99-1 * addChildren() unconditionally unlinks nodes that already have a parent. * Typo bug in removeChildren.XMLNode code found and fixed by Kate Mullen. Version 1.99-0 * Added recursive parameter to xmlValue() function to control whether to work on just the immediate nodes or also children. * Correction for xpathSApply() when returning an array/matrix which referred to a non-existent variable. * Faster creation of internal nodes via newXMLNode(). * xmlRoot() for XMLHashTree works for empty trees. * Added xmlValue<-() function. * Fix for removeAttributes() with namespaces. * Addition to configure script of the argument --with-xml-output-buffer to force whether to compile and use our own "local" version of xmlOutputBufferCreateBuffer() which is needed on unusual systems. Supplied by Jim Bullard (UC Berkeley). Version 1.98-1 * Deal with older S3-style classes with inheritance for 2.7.2 differently from the 2.8.0 mechanism. * Changes to catch more cases of xmlChar * being treated as char * which causes the Sun compiler to fail to compile DocParse.c * Export class XMLNamespaceDefinitions which caused problems in the code in the caMassClass package. Version 1.98-0 * The function XML:::xpathSubNodeApply() is the implementation of xpathApply() for an XMLInternalNode from earlier versions of the package and which explicitly moves the node to a new document and performs the XPath query and then re-parents the node. Instead of using this, users can use xpathApply()/getNodeSet() and simply change the XPath expression to be prefixed with ., e.g. instead of //tr, use .//tr to root the XPath query at the current node. * Minor patch to configure.in to allow for libxml2-2.7.*. * saveXML() for XMLInternalDocument now uses xmlDocFormatDump() ratehr than xmlSaveFile() and so formatting is "better". * The [ and [[ operators for XMLInternalDocument support a 'namespaces' parameter for ease of extracting nodes. This is syntactic sugar for getNodeSet()/xpathApply(). * xmlParse() and htmlParse() return internal documents and nodes by default and are easier to type. The results are amenable to XPath queries and so these are the most flexible representations. * xmlRoot() has a skip argument that controls whether to ignore comment and DTD nodes. The default is TRUE. * Additional functionality for XMLHashTree and XMLHashTreeNode, including facilities for creating nodes while adding them to the tree, copying sub-trees/nodes to separate trees. * Functionality to convert from an XMLInternalNode to an XMLHashTree - as(node, "XMLHashTree"). This is also an option in xmlTreeParse(, useHashTree = TRUE/FALSE) [or xmlTreeParse(, treeType = "hashTree")] * Branch nodes from xmlEventParse(, branches = list(...)) are now garbage collected appropriately. * xmlAttrs.XMLInternalNode now does not add the namespace prefix to the name of the attribute, by default. Use xmlAttrs(node, addNamespace = TRUE) to get old behaviour. * xmlGetAttr() has a corresponding new parameter addNamespace that is passed through to the call to xmlGetAttr(). * getRelativeURL() function available for getting URI of a document from a given attribute relative to a base URL, e.g. an HTML or a . * xmlAttrs<- methods support an append (TRUE by default) to add values to the existing attributes, or to replace the existing ones with the right-hand side of the assignment. * xmlAttrs<- checks for namespaces in all the ancestors for XMLInternalNode and XMLHashTreeNode. * Introduced the class XMLAbstractNode which is the parent for the XMLNode, XMLInternalNode and XMLHashTreeNode, which allows high-level methods that use the API to access the elements of the nodes to be defined for a single type. * Changed name of XMLNameSpace class to XMLNamespace (lower-case 's'). Version 1.97-1 * Fix for configuration in detecting existence of encoding enumerations in R. So now encoding of strings is working again. Version 1.97-0 * Added xmlNativeTreeParse() as an alias for xmlInternalTreeParse() and xmlTreeParse(, useInternalNodes = TRUE). * Assignment to attributes of an R-level XML node works again, e.g. xmlAttrs(doc[[3]][[2]])['foo'] = "bar" * Subsetting ([[) for XMLHashNode behaves correctly. * Added .children parameter to addTag() function in xmlOutputDOM() objects. * Thanks to Michael Lawrence, a significantly simpler and more general mechanism is used for getNodeSet()/xpathApply() when applied to a node and not a document. This allows xpath queries that go back up the ancestor path for the node. Version 1.96-0 * Functionality for working with XML Schema now incorporated. * xmlSchemaValidate() function for validating a document against a schema. * xmlSchemaValidate() using structured error handlers to give information about line numbers, columns, domain, etc. as well as the message. * xmlChildren() method for XMLInternalDocument * Recognize additional internal node types, e.g. XMLXIncludeStartNode, ... * foo.dtd example now uses internal and external entities for illustration. Version 1.95-3 * configuration change to support older versions of R that do not have the C enumeration type cetype_t defined in Rinternals.h. Version 1.95-2 * Fix for xpathApply()/getNodeSet() on the top-level node of a document which left the original document with no children! Found by Martin Morgan. Version 1.95-1 * Minor bug fixes regarding Encoding issues introduce in 1.95-0. * xmlEventParse() calls R_CheckUserInterrupt() when making callbacks to R functions and so should make the GUI more responsive. * Test for older versions of libxml2 which did not have a context field in the xmlNs data structure. Version 1.95-0 * Use the encoding of the document in creating R character strings to identify the Encoding() in R. There are probably omissions and potential problems, so I would be very grateful for examples which fail, along with the file, the locale and the R code used to manipulate these. Version 1.94-0 * Fixed a bug in xpathApply()/getNodeSet() applied to an XMLInternalNode which now ensures that the nodes emerge with the original internal document as their top-level document. * Added processXInclude() for processing individual XInclude nodes and determining what nodes they add. * If asText is TRUE in xmlTreeParse(), xmlInternalTreeParse(), ..., no call to file.exists() is made. This is both sensible and overcomes a potential file name length limitation (at least on Windows). * The trim parameter for xmlInternalTreeParse() and xmlTreeParse(, useInternal = TRUE) causes simple text nodes containing blank space to be discarded. saveXML() will, by default, put them back but not if text nodes are explicitly added. * xmlTreeParse(), xmlInternalTreeParse(), htmlTreeParser(), parseDTD(), etc. take an error handler function which defaults to collecting all the errors and reporting them at the end of the attempt to parse. * getXMLErrors() returns a list of errors from the XML/HTML parser for help in correcting documents. * Added xmlStopParser() which can be used to terminate a parser from R. This is useful in handler functions for SAX-style parsing via xmlEventParse(). * A handler function passed to xmlEventParse() can indicate that it wants to be passed a reference to the internal xmlParserContext by having the class XMLParserContextFunction. Such functions will be called with the context object as the first argument and the usual arguments displaced by 1, e.g. the name and attributes for a startElement handler would then be in positions 2 and 3. * When parsing with useInternalNodes= TRUE and trim = TRUE in xmlTreeParse() or xmlInternalTreeParse(), blank nodes are discarded so line breaks between nodes are not returned as part of the tree. This makes pretty-printing/indenting work on the resulting document but does not return the exact content of the original XML. Use trim = FALSE to preserve the breaks. * Added xmlInternalTreeParse() which is a simple copy of xmlTreeParse() with useInternalNodes defaulting to TRUE, so we get an internal C-level tree. * Added an xpathSApply() function that simplifies the result to a vector/matrix, if possible. * Added replaceNode() function which allows one to insert an internal node with another one. * addChildren() has a new at parameter to specify where in the list of children to add the new nodes. * newXMLNode(), etc. can compute the document (doc argument) from the parent. * The subset operator applied to an XMLInternalDocument and getNodeSubset() and xpathApply() compute the namespaces from the top-level of the document by default, so, e.g., doc[["//r:init"]] work. * section parameter added to xmlSource() to allow easy subsetting to a particular
within a document. * added catalogLoad(), catalogAdd(), catalogClearTable() functions. * Added docName() function for querying the file name or URL of a parsed XML document. * RS_XML_createDocFromNode() C routine adds root node correctly via xmlAddChild(). * Slightly improved identification of HTML content rather than a file or URL name. * Added a simplify parameter to the xmlNamespaceDefinition() function which, if TRUE, returns a character vector giving the prefix = URI pairs which can be used directly in xpathApply() and getNodeSet(). Version 1.93-1 * Method for xmlNamespace with a character is now exported! Needed for cases that arise in SSOAP. Version 1.93-0 * The closeTag() function within an XMLInternalDOM object returned by xmlTree() provides support for closing nodes by name or position in the stack of open nodes. * xmlRoot() method for an XMLInternalDOM tree. * Added a parent argument to the constructor functions for internal nodes, e.g. newXMLNode, newXMLPINode, newXMLCDataNode, etc. * doc argument for the constructor functions for internal nodes is now moved from second to third. Calling * Potentially changed the details about creating XML documents and nodes with namespaces. If these negatively effect your code, please send me email (duncan@wald.ucdavis.edu). * Enhancements and fixes for creating XML nodes and trees, especially with name spaces. * Many minor changes to catch special cases in working with internal nodes. Version 1.92-1 * Make addNode()/addTag() in XMLInternalDOM work with previously created XML nodes via newXMLNode(). Thanks to Seth Falcon for pointing out this omission. More improvements in the pipeline for generating XML. * addChildren for an XMLInternalNode can be given a list of XMLInternalNodes and/or character strings. * xmlSource() handles r:codeIds better. Version 1.92-0 * Added removeNodes function for unlinking XMLInternalNode objects directly by reference. * xmlRoot() handles empty documents. * Documentation cleanups. Version 1.91-1 * Remove output about "cleaning"/releasing an internal document pointer. * The warning from getNodeSet/xpathApply about using a prefix for the default namespace now has a class/type of condition, specificall "XPathDefaultNamespace". Version 1.91-0 * argument to add a finalizer for an XMLInternalDocument in xmlTreeParse()/htmlTreeParse() when useInternalNodes = TRUE. If this is set, automatic garbage collection is done which will free any sub-nodes. If you want to work with any of these nodes after the top-level tree variable has been released, specify addFinalizer = FALSE and explicitly free the document yourself with the free() function. * Sme improvements on namespace prefixes in internal nodes. See newXMLNode(). * classes for additional XMLInternalNodes (e.g. XMLInternalCDataNode) now exported * removeAttributes() has a .all argument to easily remove all the attributes within a node. Supported for both R and internal style nodes. * xmlAttrs<-() function for simply appending attributes to a node. * If xmlTreeParse() is called with asText = FALSE and the file is not found, an error of class "FileNotFound" is raised. * [[ opertor for XMLInternalDocument to get the first/only entry in the node set from an XPath query. This is a convenience mechansim for accessing the element when there is only one. Version 1.9-0 * Added xmlAncestors() functions for finding chain of parent nodes, and optionally applying a function to each. * xmlDoc() allows one to create a new XML document by copying an existing internal node, allowing for work with sub-trees as regular documents, e.g. XPath queries restricted to a subset of the tree. * Ability to do XPath searches on sub-nodes within a document. getNodeSet() and xpathApply() can now operate on an XMLInternalNode by creating a copy of the node and its sub-nodes into a new document. However, these is memory leak associated with this and you should us xmlDoc() to create a new document from the node and then perform the XPath query on that and free the document. Version 1.8-0 * Added xinclude argument to xmlTreeParse() and htmlTreeParse() to control whether should be resolved and the appropriate nodes inserted and the actual node discarded. * The namespaces argument of getNodeSet() (and implicitly of the [ method for an XMLInternalDocument object) can be a simple prefix name when referring to the default namespace of the document, e.g. getNodeSet(doc, "/r:help/r:keyword", "r") when the document has a default namespace. * Added a 'recursive = FALSE' parameter to xmlNamespaceDefinitions() to be able to process all descendant nodes and so fetch the namespace definitions in an entire sub-tree. This can be used as input to getNodeSet(), for example. * as() method for converting an XMLInternalDocument to a node. * xmlNamespaceDefinitions() handles the case where the top-level element is not the first node, e.g. when there is a DOCTYPE node and/or a comment. Version 1.7-3 * addChildren() coerces a string to an internal text node before adding the child. Version 1.7-2 * Trivial error in free() for XMLInternalDocument objects fixed so the memory is released. Version 1.7-1 * addition to configuration to detect whether the checked field of the xmlEntity structure is present. Version 1.7-0 This a quite comprehensive enhancement to the facilities in the XML package. A lot of work on the tools for creating or authoring XML from within R were added and improved. Using internal nodes directly with newXMLNode() and friends, or using xmlTree() is probably the simplest. But xmlHashTree() creates them in R. * IMPORTANT: one can and should use the names .comment, .startElement, .processingInstruction, .text, etc. when identifying general element handlers that apply to all elements of a particular type in an XML document rather than to nodes that have a particular name. This differentiates between a handler for a node named, say, text and a handler for all text elements found in the document. To use this new approach, call xmlTreeParse() or xmlEventParse() with useDotNames = TRUE This will become the default in future releases. * namespaceHandlers() function provided to deal with node handler functions with XML name spaces where there may be multiple handlers for the same node name but which are in different XML name spaces. * signature for entityDeclaration function in SAX interface is changed so that the second argument identifies the type of entity. Also, to query the value of an entity, the C code calls the getEntity() method of the handlers. * addChildren() & removeChildren() and addAttributes() & removeAttributes() for an existing node allows for post-creation modification of an XML node. * Improved support for name spaces on node attributes. * xmlName<-() methods for internal and R-level XML nodes to change the name of a node. * saveXML() and as(, "character") method for XMLInternalNode objects now to create a text representation of the internal nodes. * xmlTree() allows for creating a top-level node in the call to xmlTree() directly and does not ignore these arguments. * DTD and associated DOCTYPE can be created separately or directly in xmlTree(). * xmlTree() now allows the caller to specify the doc object as an argument, including NULL for when the nodes do not need to have a document object. * Better support in xmlTree() for namespaces and maintaining a default/active namespace prefix that is to be inserted on each subsequent node. * new functions for creating different internal node types - newXMLCDataNode, newXMLPINode, newXMLCommentNode, newXMLDTDNode. * newXMLNode() handles text, using the new newXMLTextNode() and coerce methods. * xmlTree() supports an active/default name space prefix which is used for new nodes. * Resetting the state of the xmlSubstituteEntities variable is handled correctly in the case of an error. Version 1.6-4 * xmlSize() method for an XMLInternalNode. Version 1.6-3 * Handle change from Sys.putenv() to Sys.setenv(). Version 1.6-2 * Added a URI (old) class label to the result of parseURI, and exported that class for use in other packages (specifically SSOAP, at present). * For subsetting child nodes by name, there is a new all = FALSE parameter which allows the caller to get the first element(s) that matches the name(s), or all of them with, e.g. node["bob", all = TRUE]. This allows us to avoid the equivalent idiom node[ names(node) == "bob" ] which is complicated when node is the result of an inline computation. * added method for setting names on an XMLNode (names<-.XMLNode), not just for retrieving them. Version 1.6-1 * Added catalogResolve() function for looking up local files and aliases for URIs, and PUBLIC and SYSTEM identifiers, e.g. in DOCTYPE nodes. * saveXML method added for XMLFlatTree. (Identified by Alberto Monteiro.) * Fixed saveXML methods for various classes. * Doctype class: added validity method, improved coercion to character, and slightly more flexible constructor function. Validates PUBLIC identifier. Version 1.6-0 * In saveXML() method for XMLInternalDocument, we "support" the encoding argument by passing it to xmlDocDumpFormatMemoryEnc() or xmlSaveFileEnc() in the libxml2 C code. We could also use the xmlSave() API of libxml2. * htmlTreeParse() supports an encoding argument, e.g. htmlTreeParse("9003.html", encoding = "UTF-8"). This allows one to correctly process HTML documents that do not contain their encoding information in the tag. The argument is also present in xmlTreeParse() but currently ignored. Version 1.5-1 * updated documentation for the alias for free method for XMLInternalDocument. Version 1.5-0 * added free() generic function and method for XMLInternalDocument Version 1.4-2 * xmlTreeParse and htmlTreeParse will accept a character vector of length > 1 and treat it as the contents of the XML stream and so call paste(file, collapse = "\n") before parsing. The asText = TRUE is implied. Thanks to Ingo Feinerer for prompting this addition. Version 1.4-1 * Fix to ensure a connection is closed in saveXML. Identified by Herve Pages * Update definition and documentation for xmlAttrs to take ... arguments. Version 1.4-0 * Added fullNamespaceInfo parameter for xmlTreeParse() which, if TRUE, provides the namespace for each node as a named character vector giving the URI of the namespace and the prefix as the element name, i.e. c(prefix = uri) The default is FALSE to preserve the earlier behavior. The namespace object has a class XMLNamespacePrefix for the old-style, and XMLNamespace for the new style with c(name = uri) form. This information makes comparing namespaces a lot simpler, e.g. in SOAP. Version 1.3-2 Mainly fixes for internal nodes. * Export XMLNode, XMLInternalNode, XMLInternalElementNode classes * as() method for XMLInternalNode wasn't recognized properly because the classes weren't exported. Also, the internal function asRXMLNode() accepts trim and ignoreBlanks arguments for cleaning up the XML node text elements that are created. * export coerce methods. Version 1.3-1 * parseURI() sets the port to NA if the value is 0. Version 1.3-0 * The SAX parser now has a branches argument that identifies XML elements which are to be built into (internal) nodes and then the sub-tree/node is passed to the handler function specified in the element of the branches argument. This mixes the efficient SAX event-driven parsing with the easier programming tree-based model, i.e. DOM. * XMLInternalNode objects in R now have extra class information identifying them as as regular element, text, CDATA, PI, ... Version 1.2-0 * names() method for XMLInternalNode * [ method for XMLInternalDocument and string using XPath notation. * getNodeSet() has support for default namespaces in the XML document. It is available, by default, to the XPath expression with the prefix 'd'. * Exported xmlNamespace() method for XMLInternalNode. * xmlNamespaceDefinitions() made generic (S3) and new method for XMLInternalNode class. Version 1.1-1 * Change to handling entities in printing of regular R-level XML text nodes created during xmlTreeParse() call. Identified by Ingo Feinerer. * saveXML for an XMLNode object will take a file name and write to the corresponding file, overwriting it if it already exists. Version 1.1-0 * xpathApply and getNodeSet take functions to be applied to nodes in a node set resulting from an XPath query. Version 1.0-0 * Version skipped as it is not a milestone release, just ran out of numbers! Version 0.99-94 Changes from Russell Almond and suggestions from Franck Giolat for creating XML in R * xmlNode() puts the names on children if omitted. Caller can use names other than the XML element name (but this is not necessarily advisable). * Added xmlChildren() method to set the children. * Printing of an XML node to the console handles empty nodes and text nodes better. * xmlTextNode() will replace reserved characters with their entity equivalent, e.g. & with & and < with <. One can specify the entity vector including providing an empty one should one want to avoid replacement. Version 0.99-93 Changes from Martin Morgan * import normalizePath from utils. * Changes to configure.win to find 3rd party DLLs in bin/ directory, not lib/ Version 0.99-92 * Fix for setting DTD entity field uncovered by the strict type checking in R internals. Version 0.99-91 * Added an encoding argument to saveXML(), initially for use in the Sxslt package. Version 0.99-9 * Example of using namespaces in getNodeSet() * Examples for xmlHashTree(). Version 0.99-8 * Introduced initial version of flat trees for storing the DOM in a non-hierarchical data structure in R. This allows us to work with a mutable tree and to perform certain operations across all the nodes more efficiently, i.e. non-recursively. Importantly, one can find the parent node of a given node in the tree which is not possible with the list of list approach. It does mean more computation for some common operations, specifically parsing. Indeed, it can be 25 times slower for a non-trivial file, i.e. one with. However, for a file with 7700 nodes, it still only takes 2 1/2 seconds. So there is a trade-off. While there are a few versions in the code, xmlHashTree() is the one to use for speed reasons. xmlFlatListTree() is another and xmlFlatTree() is excruciatingly slow. See tests/timings.R for some comparisons. xmlGetElementsByTagName and other facilities work on these types of trees. More functions and methods can and should be provided to work with these trees if they turn out to be used in any significant way. * add the R attribute 'namespaces' to an XML node's attributes vector so that one can differentiate between conflicting attribute names with different namespaces. * added parseURI() to return the elements of a URI from a string. Version 0.99-7 * Example of reading HTML tables using XPath and internal nodes in bondsTables.R * Some additional methods for XMLInternalNode. Version 0.99-6 * configure does not require the GNU sed, but can use any version of sed now that the use of + in the regular expression has been removed. Version 0.99-5 * Added append.XMLNode and append.xmlNode to the exported symbols from the NAMESPACE file. Version 0.99-4 * Fix for addComment() in xmlOutputDOM(). * Removed all the compilation warnings about interchanging xmlChar* and char*. Version 0.99-3 * Added support in print methods for XML objects for indent = FALSE, and tagSeparator, which defaults to "\n". These can be used to print a faithful representation of an original XML document, but only when used in combination with xmlTreeParse( skipBlanks = FALSE, trim = FALSE) Version 0.99-2 * Problems compiling with libxml2-2.5.11 and libxml2-2.6.{1,2}, so we now test for a recent version of libxml. The test uses sed -r which may cause problems. If one really wants to avoid the tests set the environment variable FORCE_XML2 to any value before running R CMD INSTALL XML. * Documentation for getNodeSet() didn't refer to the new namespaces argument. Version 0.99-1 * getNodeSet() takes a namespaces argument which is named character vector of prefix = URI pairs of namespaces used in the XPath expression. * Handlers for xmlEventParse() can include startDocument and endDocument elements to catch those particular events. Useful for closing connections and general cleanup, especially in the "pull" data source, i.e. connections or functions. * xmlEventParse() when called with a function as the data source now doesn't have a new line appended to each string returned to the parser by the function. * Passing a connection to xmlEventParse() now uses a regular R function to call readLines(con, 1) and no longer does this via C code to call readLines(). * Fix to the example in xmlEventParse() using the state variable. Version 0.99-0 * Implementation for the endElement in the xmlEventParse() for saxVersion == 2. * In xmlEventParse( , saxVersion = 2), the namespaces come as a named vector in the fourth argument. Version 0.98-1 * Messages from errors are now more informative. Using saxVersion = 2 in xmlEventParse(), you get get the line and column information about the error. Version 0.98 * Added saxVersion parameter to xmlEventParse() to control which interface is used at the C level. This changes the arguments to the startElement handler, adding the namespace for the element. * Added xmlValidity() function to set the value of the default validity action. This allows us to do the setting in the R code. This is currently not exported. * Added recursive parameter to xmlElementsByTagName() function. This provides functionality similar to getElementsByTagName() in XML parsing APIs for other languages. * xmlTreeParse() called with no handlers and useInternalNodes returns a reference to the C-level xmlDocPtr instance. This is an object of class "XMLInternalDocument". This can be used in much the same way as the regular "XMLDocument" tree returned by xmlTreeParse, e.g. xmlRoot, etc. * Added getNodeSet() to evaluate XPath expressions on an XMLInternalDocument object. * Added a validate parameter to the xmlEventParse() function. Version 0.97-8 * Fix error where CDATA nodes and potentially other types of nodes (without element names) were being omitted from the R tree in a simple call to xmlTreeParse("filename") (i.e. with no handlers). Version 0.97-7 * Documentation updates. Version 0.97-6 * useInternalNodes added to xmlTreeParse() and htmlTreeParse(). This allows one to avoid the overhead of converting the contents of nodes to R objects for each handler function call. Also, can access parents, siblings, etc. from within a handler function. * Included parameterizations for Windows from Uwe Ligges to aid automated-building and finding the libxml DLL at run time. Version 0.97-5 * Methods for accessing component of XMLInternalDocument and XMLInternalNode objects, e.g. xmlName, xmlNamespace, xmlAttrs, xmlChildren * saveXML.XMLInternalDOM now supports specification of a Doctype (see Doctype). * saveXML uses NextMethod and arguments are transferred. Identified by Vincent Carey. * Suppress warnings from R CMD check. * Change of the output file in saveXML() example to avoid conflict with Microsoft Windows use of name con.xml. Version 0.97-4 * Quote URI values in namespace definitions in print.XMLNode. Version 0.97-3 * Added a method for xmlRoot for HTMLDocument * Changed the maintainer email address. Version 0.97-2 * Added cdata to the collection of functions that are used in the handlers for xmlEventParse(). Omission identified by Jeff Gentry. * Fixed the maintainer email address to duncan@wald.ucdavis.edu Version 0.97-1 * Put the correct S3method declarations in the NAMESPACE. Version 0.97-0 * Using a NAMESPACE for the package Version 0.96-0 * Using libxml2 by default rather than libxml. * Fixed typo. in PACKAGE when initializing the library. Version 0.95-7 * When creating a namespace identifier, if the namespace doesn't have an href, then we put in an string. Version 0.95-6 * Documentation updates for synchronization with the code. Version 0.95-5 * Trivial bug of including extra arguments in call to UseMethod for dtdElementValidEntry that generated warnings. Version 0.95-4 * Configuration now tries to find libxml 1, then libxml 2 unless explicitly instructed to find libxml 2 via --with-libxml2. So the change is to pick up libxml 2 if libxml 1 is not found rather than signal an error. Version 0.95-3 * Remove the need to define xmlParserError. Instead, set the value of the error routine/function pointer to our error handler in the different default handlers in libxml. We now initialize these default objects when we load the library. * When setting the environment variables LIBXML_INCDIR and LIBXML_LIBDIR, one needs to specify the -I and -L prefixes for the compiler and linker respectively in front of directory names. * Detect whether the routine for xmlHashScan (in libxml2) provides a return value or not. This changed in version 2.4.21 of libxml2. Version 0.95-2 * Configuration detects Darwin and handles multiplicity of xmlParserError symbol. Version 0.95-1 * Configuration now supports the specification of the xml-config script to use via the environment variable XML_CONFIG or the --with-xml-config as in --with-xml-config=xml2-config * Recognize file:/// prefix as URL and not switch to treating file name as XML text. Version 0.95-0 * Event-driven parsing (SAX) can take a connection object or a function that is called when the parser needs more input. See the documentation for xmlEventParse(). * Classes and methods explicitly created during the installation. This will cause problems with namespaces until the saving of the image model works with namespaces. Version 0.94-1 * Minor change to configuration script to avoid -L-L in specification of directory for XML library (libxml). Version 0.94-0 * Use registration of C routines * Added methods for saveXML for XMLNode and XMLOutputStream objects. Version 0.93-4 * replaceEntities argument for xmlEventParse. * S4 SAX methods assigned to the correct database. Version 0.93-3 * Correct support for DTDs and namespaces in the internal nodes used in xmlTree(). Errors identified by Vincent Carey. Version 0.93-2 * Bug in trimming white space discovered by Ott Toomet. Version 0.93-1 * Documentation updates. Included xmlGetAttr.Rd. Version 0.93-0 * Added toString.XMLNode * Fixed the printing of degenerate namespaces in an XML node, i.e. the spurious `:'. Version 0.92-2 * Fixed C bug caused by using namespace without a suffix, e.g. xmlns="http:...." assumed prefix was present. Thanks to David Meyer. Version 0.92-1 * Display the namespace definitions when printing an XMLNode object. * New addAttributeNamespaces argument for xmlTreeParse() that controls whether namespaces are included in attribute names. Version 0.92-0 * XMLNode class now contains a field for namespace definitions The `namespace' field is a character string identifying the prefix's namespace. The `namespaceDefinition' field contains the full definitions of each of the namespaces defined within a node. * Printing of XLM nodes displays the namespace. * xmlName() takes a `full' argument that controls whether the namespace prefix is prepended to the tag name. Version 0.91-0 * Added a mechanism to the SAX parser to allow a state object be passed between the callbacks and returned as the result of the parsing. This avoids the need for closures. Also, works with S4 classes and the genericSAXHandlers() methods by allowing one to write methods for these generic callbacks that dispatch based on the type of the state object. * Fix to make work properly with S4 class system. Version 0.9-1 * Formatting of the help files to avoid long lines identified by Ott Toomet * Addition of `ignoreComments' argument for xmlValue() * Date in the DESCRIPTION file corrected (thanks to Doug Bates). Version 0.9-0 * Added addCData() and addPI() to the handlers of the different XMLOutputStream classes. Code for XMLInternalDOM (i.e. xmlTree()) from Byron Ellis. * print() method for XMLProcessingInstruction node has the terminating `?' as in . Version 0.8-2 * Changes to support libxml2-2.4.21 (specifically the issues with the headers and parse error regarding xmlValidCtxt). Thanks to Wolfgang Huber for identifying this. * Ignoring R_VERSION now, so dependency is R >= 1.2.0 Version 0.8-1 * Added an `attrs' argument to the xmlOutputBuffer and xmlTree functions for specifying the top-level node. Version 0.8-0 * xmlValue() extended to work recursively if a node has only one child. * T and F replaced by TRUE and FALSE Version 0.7-4 * Support for Windows Version 0.7-3 * Documents without are handled correctly. * Configuration tweak to set LD_LIBRARY_PATH to handle the case that the user specifies LIBXML_LIBDIR and it is needed to run the version test. * Keyword XML changed to IO. Version 0.7-2 * Fix for printing XMLNode objects to handle comments and elements with name "text". Identified by Andrew Schuh. Version 0.7-1 * Minor fixes for passing R CMD check. Version 0.7-0 * Generating XML trees using internal libxml structures: xmlTree(), newXMLDoc(), newXMLNode(), saveXML(). * Support parsing HTML (htmlTreeParse()) using DOM. Suggestion from Luis Torgo. * Additional updates for libxml2, relating to DTDs. Version 0.6-3 * Installation using --with-xml2 now attempts to link against libxml2.so and the appropriate header files. * Use libxml's xml-config or xml2-config scripts if these are available. Version 0.6 * xmlDOMApply for recursively applying a function to each node in a tree. Version 0.5-1 * simplification of xmlOutputBuffer so that it doesn't put the namespace definition in each and every tag. * configuration changes to support libxml2-2.3.6 (look for libxml2, check if xmlHashSize is available) * now dropping nodes if the handler function returns NULL. Updated documentation. * spelling correction in the documentation Version 0.5 * xmlOutputBuffer now accepts a connection. * Fixes for using libxml2, specifically 2.2.12. Also works for libxml2.2.8 * Enhanced configuration script to determine what features are available. Version 0.4 * `namespace' handler in xmlTreeParse is called when a namespace declaration is encountered. This is called before the child nodes are processed. * More documentation, in Tour. * xmlValue, xmlApply, xmlSApply, xmlRoot, xmlNamespace, length, names * Constructors for different types of nodes: XMLNode, XMLTextNode, XMLProcessingInstruction. * Methods for print(), subsetting ([ and [[), accessing the fields in an XMLNode object. * New classes for the different node types (e.g. XMLTextNode) * Event driven parsing available via libxml. Expat is not needed but can be used. * Document sources can be URLs (ftp and http) when using the libxml parser. * Examples for processing MathML and SVG files. See examples/ directory. * Examples for event driven parsing. * Class of result from xmlTreeParse is XMLDocument. * Comments, Entities, Text, etc. inherit from XMLNode in addition to defining their own XML class. XML/NAMESPACE0000644000175100001440000002437014405636156012167 0ustar hornikusers# Avoided if we are using Windows so that we can specify the directory to find the libxml DLL. # useDynLib(XML) importFrom(utils, menu) importFrom(grDevices, dev.off, jpeg, pdf, png) import(methods) export( append.xmlNode, append.XMLNode, Doctype, asXMLNode, comment.SAX, dtdElement, dtdElementValidEntry, dtdEntity, dtdIsAttribute, dtdValidElement, endElement.SAX, entityDeclaration.SAX, genericSAXHandlers, getNodeSet, xpathApply, htmlTreeParse, htmlParse, libxmlVersion, xmlDoc, newHTMLDoc, newXMLDoc, newXMLNode, newXMLNamespace, newXMLPINode, newXMLTextNode, newXMLCommentNode, newXMLCDataNode, newXMLDTDNode, parseDTD, processingInstruction.SAX, saveXML, startElement.SAX, supportsExpat, supportsLibxml, text.SAX, toString.XMLNode, xmlApply, xmlAttributeType, xmlAttrs, "xmlAttrs<-", xmlCDataNode, xmlChildren, xmlCommentNode, xmlContainsElement, xmlContainsEntity, xmlDOMApply, xmlElementsByTagName, xmlEventHandler, xmlEventParse, # new.xmlEventParse, # new.xmlTreeParse, xmlGetAttr, xmlHandler, xmlName, xmlNamespace, xmlNode, xmlOutputBuffer, xmlOutputDOM, xmlPINode, xmlParent, xmlAncestors, xmlRoot, xmlSApply, xmlSize, xmlSize.default, xmlTextNode, xmlTree, xmlTreeParse, xmlInternalTreeParse, xmlNativeTreeParse, xmlParse, xmlValue, names.XMLNode, parseURI, asXMLTreeNode, xmlHashTree, addNode, xmlNamespaceDefinitions, xmlNamespaces, matchNamespaces, getDefaultNamespace, catalogResolve, toHTML, addChildren, removeChildren, removeNodes, addAttributes, removeAttributes, "xmlName<-", addSibling # xmlFlatListTree ) S3method(removeNodes, "list") S3method(removeNodes, "XMLNodeSet") S3method(removeNodes, "XMLNodeList") S3method(removeNodes, "XMLInternalNode") exportMethods("addAttributes", "removeAttributes") exportMethods("toHTML") export("xmlChildren<-") exportMethods("xmlChildren<-") exportClasses("XMLInternalDocument", "XMLAbstractDocument") exportClass("URI") if(TRUE) { exportClasses("XMLAbstractNode", "XMLNode") exportClasses("HTMLInternalDocument") exportClasses("XMLInternalNode", "XMLInternalElementNode", "XMLInternalTextNode", "XMLInternalPINode", "XMLInternalCDataNode", "XMLInternalCommentNode", "XMLDTDNode", "XMLXIncludeStartNode", "XMLXIncludeEndNode", "XMLEntityDeclNode", "XMLAttributeDeclNode", "XMLDocumentNode", "XMLDocumentTypeNode", "XMLDocumentFragNode", "XMLNamespaceDeclNode") exportClass("XMLTreeNode") exportClass(XMLNamespace) exportClass(XMLNamespaceDefinitions) } exportMethods("coerce") exportMethods("free") S3method(removeChildren, XMLNode) S3method(removeChildren, XMLInternalNode) exportClasses(Percent, FormattedNumber, FormattedInteger) S3method(xpathApply, XMLInternalNode) S3method(xpathApply, XMLInternalDocument) S3method(xpathApply, XMLNode) export(xpathSApply) S3method(xmlNamespaceDefinitions, XMLNode) S3method(xmlNamespaceDefinitions, XMLInternalDocument) S3method(xmlNamespaceDefinitions, XMLInternalNode) S3method(xmlNamespaceDefinitions, XMLAbstractDocument) #XXX S3method(xmlNamespaceDefinitions, XMLHashTreeNode) #S3method(names, XMLFlatTree) #S3method("$", XMLFlatListTree) S3method(addNode, XMLHashTree) S3method(xmlRoot, XMLHashTree) S3method(print, XMLHashTree) S3method(print, XMLInternalDocument) S3method(print, XMLInternalNode) S3method(print, XMLRDocument) S3method(xmlRoot, XMLRDocument) S3method(xmlRoot, HTMLDocument) if(TRUE) { S3method(xmlName, XMLComment) S3method(xmlName, XMLNode) S3method(xmlName, XMLInternalNode) } else # S4 version exportMethods(xmlName) S3method("names<-", XMLNode) S3method("xmlName<-", XMLNode) S3method("xmlName<-", XMLInternalElementNode) exportMethods("xmlAttrs<-") if(TRUE) { S3method(xmlChildren, XMLTreeNode) S3method(xmlChildren, XMLInternalDocument) S3method(xmlChildren, XMLHashTreeNode) S3method(xmlChildren, XMLNode) S3method(xmlChildren, XMLInternalNode) } else exportMethods("xmlChildren") if(FALSE) { S3method(xmlParent, XMLTreeNode) S3method(xmlParent, XMLHashTreeNode) S3method(xmlParent, XMLInternalNode) } else exportMethods(xmlParent) S3method(xmlSize, XMLHashTreeNode) S3method(xmlSize, XMLHashTree) S3method(xmlRoot, XMLHashTree) S3method(xmlRoot, XMLInternalDOM) S3method(xmlRoot, XMLInternalNode) S3method(addChildren, XMLInternalNode) S3method(addChildren, XMLInternalDocument) S3method(addChildren, XMLNode) export(replaceNodes) S3method(replaceNodes, XMLInternalNode) S3method(xmlSize, XMLInternalNode) S3method(xmlValue, XMLInternalNode) S3method(xmlValue, XMLNodeSet) S3method(xmlValue, list) #exportS3method("xmlValue", "NULL") S3method("xmlValue", "NULL") S3method("[", XMLNode) if(TRUE) { S3method("[[", XMLNode) S3method("[[", XMLDocumentContent) S3method("[[", XMLInternalNode) S3method("[[", XMLInternalDocument) S3method("[[", XMLHashTreeNode) S3method("[[", XMLInternalElementNode) } S3method("[", XMLInternalNode) S3method("[", XMLInternalDocument) S3method("names", XMLInternalNode) S3method("[<-", XMLNode) S3method("[[<-", XMLNode) S3method("[[<-", XMLInternalNode) exportClass("XMLAttributes") exportMethods("[") export(xmlNamespaceDefinitions) S3method(names, XMLNode) S3method(length, XMLNode) if(TRUE) { S3method(xmlAttrs, XMLNode) S3method(xmlAttrs, XMLInternalNode) S3method(xmlAttrs, XMLElementDef) } else exportMethods("xmlAttrs") S3method(xmlSize, XMLDocument) S3method(xmlSize, default) S3method(xmlSize, XMLNode) S3method(print, XMLNode) S3method(print, XMLTextNode) S3method(print, XMLComment) S3method(print, XMLCommentNode) S3method(print, XMLEntityRef) S3method(print, XMLCDataNode) S3method(print, XMLProcessingInstruction) S3method(xmlRoot, XMLDocument) S3method(xmlRoot, XMLInternalDocument) S3method(xmlRoot, XMLDocumentContent) S3method(xmlApply, XMLNode) S3method(xmlApply, XMLDocument) S3method(xmlApply, XMLDocumentContent) S3method(xmlApply, XMLInternalNode) S3method(xmlSApply, XMLNode) S3method(xmlSApply, XMLDocument) S3method(xmlSApply, XMLDocumentContent) S3method(xmlSApply, XMLInternalNode) S3method(xmlSApply, XMLNodeSet) S3method(xmlApply, XMLNodeSet) if(TRUE) { S3method(xmlValue, XMLNode) S3method(xmlValue, XMLTextNode) S3method(xmlValue, XMLComment) S3method(xmlValue, XMLCDataNode) S3method(xmlValue, XMLProcessingInstruction) } else exportMethods("xmlValue") S3method(addSibling, XMLInternalNode) S3method(xmlNamespace, XMLNode) S3method(xmlNamespace, XMLInternalNode) S3method(xmlNamespace, character) ## formerly an unexported generic append() with uexported copy append.xmlNode() S3method(append.xmlNode, XMLNode, append.XMLNode) S3method(append.xmlNode, default) exportMethods(saveXML) # S3method(saveXML, XMLInternalDocument) # S3method(saveXML, XMLInternalDOM) # S3method(saveXML, XMLInternalNode) # S3method(saveXML, XMLOutputStream) # S3method(saveXML, XMLNode) # S3method(saveXML, XMLFlatTree) S3method(dtdElementValidEntry, XMLElementDef) S3method(dtdElementValidEntry, XMLOrContent) S3method(dtdElementValidEntry, XMLElementContent) S3method(dtdElementValidEntry, character) S3method(dtdElementValidEntry, XMLSequenceContent) export(docName) if(FALSE) { S3method(docName, XMLDocument) S3method(docName, XMLDocumentContent) S3method(docName, XMLInternalDocument) S3method(docName, XMLInternalNode) S3method(docName, XMLHashTree) } else exportMethods(docName) export("xmlNamespaces<-") exportMethods("xmlNamespaces<-") export("docName<-") exportMethods("docName<-") exportClass("SAXState") export(xmlSource) exportMethods("xmlSource") export(xmlSourceFunctions) exportMethods("xmlSourceFunctions") export(xmlSourceSection) exportMethods("xmlSourceSection") # Not yet exported.... #xmlValidity if(TRUE) { exportClasses("ExternalReference", "xmlSchemaRef", "libxmlTypeTable") exportClasses("SchemaElementTable", "xmlSchemaElementRef", "SchemaTypeTable", "xmlSchemaTypeRef", "SchemaAttributeTable", "xmlSchemaAttributeRef", "SchemaAttributeGroupTable", "xmlSchemaAttributeGroupRef", "SchemaNotationTable", "xmlSchemaNotationRef") export(xmlSchemaValidate, schemaValidationErrorHandler, xmlSchemaParse) exportMethods("names", "$", "$<-", "coerce") } #importFrom(utils, normalizePath) export(getSibling) S3method(getSibling, XMLInternalNode) S3method(getSibling, XMLHashTreeNode) export(catalogLoad, catalogClearTable, catalogAdd, catalogDump) export(xmlStructuredStop, xmlErrorCumulator) # xmlStop export(xmlStopParser) export(getXMLErrors) export(processXInclude) S3method(processXInclude, list) S3method(processXInclude, XMLInternalDocument) S3method(processXInclude, XMLInternalElementNode) exportMethods(show) export(xmlElementSummary) #, xmlElementSummaryHandlers) #export(xmlNodeMatch) #export(getRCode) export(xmlParserContextFunction) export(getRelativeURL) export(xmlToList) export('xmlValue<-') exportMethods('xmlValue<-') export(getEncoding) exportMethods(getEncoding) exportClass("XMLCodeFile") exportClass("XMLCodeDoc") exportMethods("[[") export(xmlCodeFile) exportMethods(source) export(xmlClone) export(findXInclude) export(getLineNumber, getNodeLocation, getNodePosition) export(ensureNamespace) export(removeXMLNamespaces) exportMethods(removeXMLNamespaces) export(xmlParseDoc) export(RECOVER, NOENT, DTDLOAD, DTDATTR, DTDVALID, NOERROR, NOWARNING, PEDANTIC, NOBLANKS, SAX1, XINCLUDE, NONET, NODICT, NSCLEAN, NOCDATA, NOXINCNODE, COMPACT, OLD10, NOBASEFIX, HUGE, OLDSAX) export(libxmlFeatures) exportClass("XMLString") export(xml, xmlParseString, isXMLString) export(readHTMLTable) export(xmlToS4, makeClassTemplate) # xmlToS4List exportMethods("xmlToS4") export(xmlToDataFrame) exportMethods(xmlToDataFrame) export(compareXMLDocs) S3method(summary, XMLInternalDocument) export(parseXMLAndAdd) #exportClass("XPathNodeSet") export(xmlSerializeHook, xmlDeserializeHook) if(FALSE) { export(clearMemoryManagement) exportMethods(clearMemoryManagement) } export("xmlParent<-") export(xmlSearchNs) export("xmlNamespace<-", setXMLNamespace) export(readKeyValueDB, readSolrDoc) export(getChildrenStrings) export(getHTMLLinks) export(readHTMLList) export(getXIncludes, xmlXIncludes) export(getHTMLExternalFiles) export(xmlCleanNamespaces) export(replaceNodeWithChildren) S3method(toString, XMLNode) XML/LICENSE0000644000175100001440000000023414516227653011747 0ustar hornikusersYEAR: 2015 COPYRIGHT HOLDER: Duncan Temple Lang, Bell Labs, Lucent Technologies, University of California, Davis; CRAN Team ORGANIZATION: copyright holder XML/configure.ac0000644000175100001440000005736214120536300013225 0ustar hornikusers# An input file for autoconf to configure # the XML parsing facilities for both R and S. # Currently this works for R. # # This was originally implemented by Friedrich Leisch # with modifications for subsequent versions # by Duncan Temple Lang. # AC_INIT AC_CONFIG_SRCDIR([DESCRIPTION]) dnl The different command line arguments for configure. dnl They can also be specified by setting environment variables. dnl dnl Establish the command line arguments accepted by this script. dnl dnl dnl whether to use Splus. AC_ARG_WITH(splus,[ --with-splus Compile as an SPlus library (rather than R). Value can be the (fully qualified) name of the Splus script.], USE_SPLUS=1) dnl explicitly force the use of the old names. If this doesn't match the header dnl files that are actually found, then AC_ARG_WITH(oldlibxml,[], USE_OLD_ROOT_CHILD_NAMES=1; FORCE_OLD=1;echo "Using old libxml names") dnl tell the configuration that we are using libxml2. AC_ARG_WITH(libxml2,[ --with-libxml2 indicate that the libxml version is 2.0 or higher], [ if test "${withval}" = "yes" ; then LIBXML2="-DLIBXML2=1"; USE_XML2="yes" ; fi], USE_XML2="yes") AC_ARG_WITH(xml-config,[ --with-xml-config the name of the xml-config program to use.], [ XML_CONFIG=${withval}]) dnl compile for use with libxml. This is the default. AC_ARG_WITH(libxml, [ --with-libxml use the libxml library (default)], [ if test "${withval}" = no; then USE_LIBXML=false; else USE_LIBXML=true; fi], USE_LIBXML=true) # Default is false for expat since we can # do event driven parsing with libxml. AC_ARG_WITH(expat, [ --with-expat use expat library (off by default)], [ if test "${withval}" = no; then USE_EXPAT= ; else USE_EXPAT=true; fi], USE_EXPAT= ) dnl Here we add a flag which we will use below in the case that dnl the user declaratively adds this option in. AC_ARG_WITH(xml_output_buffer, [ --with-xml-output-buffer use ADD_XML_OUTPUT_BUFFER_CODE (conditionally on)], [ if test "${withval}" = "yes" ; then ADD_XML_OUTPUT_BUFFER="yes"; else ADD_XML_OUTPUT_BUFFER="no"; fi], ADD_XML_OUTPUT_BUFFER=no) dnl dnl End of command line argument declarations. dnl Now compute the relevant settings. dnl dnl Get the C compiler, including any values set by the user dnl We need this to perform compilation and link checks. AC_PROG_CC AC_PROG_CPP dnl ====================================================== dnl Check whether we are compiling this for use with SPlus dnl and if so, figure out which version. if test -n "${USE_SPLUS}" ; then # Allows the user to say --with-splus=/usr/local/bin/Splus5 # This could be fooled, but unlikely unless the user does something # "clever" if test -x ${with_splus} ; then SPLUS=${with_splus} else SPLUS=Splus fi # Get the major version of the Splus being run. dnl Shouldn't this be perl -epn SPLUS_VERSION=`echo 'cat(version$major,"\n",sep="")' | ${SPLUS} | perl -e 'while(){ $x = $_;} printf $x;'` # If this is version 3, we are in trouble. if test ${SPLUS_VERSION} -lt 5 ; then echo "This package does not work with SPlus 3, but only SPlus 5 and 6" exit 1 fi fi # end of USE_SPLUS. AC_ARG_WITH(xmlsec, [ --with-xmlsec add support (experimental) for XML security with xmlsec. Specify no, xmlsec1 or xmlsec1-openssl], [ if test "${withval}" = no; then USE_XMLSEC=false else USE_XMLSEC=${withval} fi], USE_XMLSEC=true) dnl dnl Redirection: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html if test -n "" ; then # turned off for now #XXX get the redirection correct "$R_HOME/bin/R" CMD SHLIB testRemoveFinalizers.c &> AS_MESSAGE_FD if test "$?" = 0 ; then $R_HOME/bin/R --no-echo --vanilla < testRemoveFinalizers.R &> AS_MESSAGE_FD fi if ! test "$?" = 0 ; then echo "No ability to remove finalizers on externalptr objects in this verison of R"; EXPORT_MEMORY_MANAGEMENT="FALSE" else echo "Have R_RemoveExtPtrWeakRef" ; PKG_CPPFLAGS="$PKG_CPPFLAGS -DR_HAS_REMOVE_FINALIZERS=1"; EXPORT_MEMORY_MANAGEMENT="TRUE" fi else EXPORT_MEMORY_MANAGEMENT="FALSE" fi dnl ====================================================== AC_PATH_PROGS(SED, sed) AC_PATH_PROGS(PKG_CONFIG, pkg-config) dnl In this section, we try to find the different dnl characteristics of the libxml library. dnl We are looking to see if dnl a) it is version 1.8.* or version 2.* dnl b) whether it is installed with include files in /gnome-xml dnl or in a private, uninstalled form in which case the include dnl directory is usually libxml/ if test -n "${USE_LIBXML}" ; then dnl If the user gave us xml*-config, then use that. if test -n "${XML_CONFIG}" && test -x "${XML_CONFIG}" ; then USING_USER_XML_CONFIG="yes" XML_VERSION="`${XML_CONFIG} --version | ${SED} -e 's/\..*//g'`" if test "${XML_VERSION}" = "2" ; then USE_XML2="yes" LIBXML2="-DLIBXML2=1"; fi echo "User defined xml-config: ${XML_CONFIG}, XML Version: ${XML_VERSION}, XML2: ${USE_XML2}" fi LANGUAGE_DEFS="${LANGUAGE_DEFS} -DHAVE_VALIDITY=1" dnl if the user has not specified anything about libxml, dnl then lets look for xml-config. We let the user give this dnl as an environment variable `XML_CONFIG'. if test -z "${LIBXML_INCDIR}" && test -z "${LIBXML_LIBDIR}" ; then dnl find xml*-config dnl If they ask explicitly for xml2, find it or fail otherwise. if test "${USE_XML2}" = "yes" ; then if test -z "${XML_CONFIG}" ; then AC_PATH_PROGS(XML_CONFIG, xml2-config) if test -z "${XML_CONFIG}" ; then echo "Cannot find xml2-config" exit 1 fi fi fi dnl Otherwise, if they implicitly ask for xml-config dnl find that. if test -z "${XML_CONFIG}" ; then AC_PATH_PROGS(XML_CONFIG, xml-config) fi dnl and if they don't have libxml version 1, see if they dnl have libxml2 if test "${USE_XML2}" = "maybe" ; then if test -z "${XML_CONFIG}" ; then AC_PATH_PROGS(XML_CONFIG, xml2-config) if test -z "${XML_CONFIG}" ; then echo "Cannot find xml2-config" exit 1 else echo "Using libxml version `$XML_CONFIG --version`" fi fi fi if test -n "${XML_CONFIG}" ; then echo "USE_XML2 = ${USE_XML2}" if test "${USE_XML2}" != "no" && test -z "${FORCE_XML2}"; then dnl This is not needed now, but is a way to test whether we should use -E or -r to get dnl extended regular expression usage with this version of sed. echo "foo" | sed -Ee 's/foo/bar/' > /dev/null 2>&1 if test "$?" = "0" ; then SED_EXTENDED_ARG="-E" else SED_EXTENDED_ARG="-r" fi echo "SED_EXTENDED_ARG: ${SED_EXTENDED_ARG}" MINOR=`${XML_CONFIG} --version | ${SED} -e 's/^2\.\([[0-9]]\{1,\}\).*/\1/'` PATCH=`${XML_CONFIG} --version | ${SED} -e 's/^2\.[[0-9]]\{1,\}\.\([[0-9]]\{1,\}\)$/\1/'` echo "Minor $MINOR, Patch $PATCH for `$XML_CONFIG --version`" if test $MINOR -lt 6 ; then echo "" echo "**** You should use a recent version of libxml2, i.e. 2.6.22 or higher ****" echo "" exit 1 fi if test "$MINOR" -eq 6 -a "$PATCH" -lt 3 ; then echo "" echo "**** There are problems compiling this package with libxml2-2.6.1 or libmxml2-2.6.2. ****" echo "**** You will probably encounter compilation errors, so we are terminating the build. ****" echo "" exit 1 fi fi LIBXML_INCDIR=`${XML_CONFIG} --cflags` LIBXML_LIBDIR=`${XML_CONFIG} --libs` FOUND_LIBXML_INCLUDES="Ok" fi fi dnl USE_XML2 dnl If the user has specified LIBXML_INCDIR, then dnl we use that. dnl Otherwise, we try to find the parser.h file. if test -n "${LIBXML_INCDIR}" && test -z "${XML_CONFIG}" ; then echo "Checking directory of LIBXML_INCDIR" if test -d $LIBXML_INCDIR ; then dnl Maybe also test for ${LIBXML_INCDIR}/parser.h dnl in case somebody points us directly at the include directory. if test -r ${LIBXML_INCDIR}/libxml/parser.h ; then FOUND_LIBXML_INCLUDES="Ok" elif test -r ${LIBXML_INCDIR}/gnome-xml/parser.h ; then FOUND_LIBXML_INCLUDES="Ok" PKG_CPPFLAGS="${PKG_CPPFLAGS} -DFROM_GNOME_XML_DIR=1" else echo "You specified LIBXML_INCDIR, but we couldn't find parser.h" echo "Please specify it correctly and re-run the INSTALL'ation." exit 1 fi else echo "The LIBXML_INCDIR value you specified ($LIBXML_INCDIR) is not a directory." echo "Please specify it correctly and re-run the INSTALL'ation." exit 1 fi fi dnl We should have exited if we cannot find parser.h dnl LIBXML_INCDIR. if test -z "${FOUND_LIBXML_INCLUDES}" ; then dnl the idea is that we loop over different directories dnl looking for parser.h. We look in the sub-directory dnl gnome-xml/ TMP_CPPFLAGS=${CPPFLAGS} for dir in ${LIBXML_INCDIR} /usr/local/include /usr/include ; do CPPFLAGS="${TMP_CPPFLAGS} -I${dir}" AC_CHECK_HEADER(libxml/parser.h, FROM_LIBXML_DIR=1) if test -n "${FROM_LIBXML_DIR}" ; then LIBXML_INCDIR="-I${dir}" CPPFLAGS="${TMP_CPPFLAGS} -I${dir} -I${dir}/libxml" PKG_CPPFLAGS="${TMP_CPPFLAGS} -I${dir} -I${dir}/libxml" echo "Found the libxml parser.h in $dir/libxml/" break fi CPPFLAGS="${TMP_CPPFLAGS} -I${dir}/gnome-xml" AC_CHECK_HEADER(gnome-xml/parser.h, FROM_GNOME_XML_DIR=1) if test -n "${FROM_GNOME_XML_DIR}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DFROM_GNOME_XML_DIR=1" CPPFLAGS="${CPPFLAGS} -DFROM_GNOME_XML_DIR=1" LIBXML_INCDIR="-I${dir}" echo "Found the gnome-xml parser in $dir" break fi done if test -z "${FROM_GNOME_XML_DIR}" ; then CPPFLAGS=${TMP_CPPFLAGS} fi fi # end of -z FOUND_LIBXML_INCLUDES if test -z "${LIBXML_INCDIR}"; then AC_CHECK_HEADER(libxml/parser.h, LIBXML_INCDIR="libxml/") fi if test -z "${LIBXML_INCDIR}" ; then echo "Cannot find parser.h. Set the value of the environment variable" echo " LIBXML_INCDIR" echo "to point to where it can be found." exit 1; else echo "Located parser file ${LIBXML_INCDIR}/parser.h" fi dnl Do we need this? XXX #LIBS="${LIBS} ${LIBXML_INCDIR}" if test -z "${LIBXML2}" ; then CPPFLAGS="${PKG_CPPFLAGS} ${LIBXML_INCDIR}" echo "Checking for 1.8: ${CPPFLAGS}" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlAttr *attr; attr->val = NULL; ]])],[echo "Using libxml 1.8.*!"],[LIBXML2="-DLIBXML2=1"; echo "Using libxml2.*" ]) fi # AC_EGREP_HEADER(xmlParseFile, ${LIBXML_INCDIR}parser.h, # HAVE_LIBXML_HEADER=true, # AC_MSG_ERROR("header files for libxml seem to be incorrect")) AC_CHECK_LIB(z, gzopen) if test -n "${LIBXML2}" ; then AC_CHECK_LIB(xml2, xmlParseFile, LIBS="${LIBS} -lxml2"; USE_XMLLIB_NAME=xml2, NO_XML_LIB=1, "${LIBXML_LIBDIR--L.}") else NO_XML_LIB=1 fi if test -n "${NO_XML_LIB}" ; then AC_CHECK_LIB(xml, xmlParseFile, LIBS="${LIBS} -lxml";USE_XMLLIB_NAME=xml, AC_MSG_ERROR("libxml not found"), "${LIBXML_LIBDIR--L.}") fi if test -n "${LIBXML_LIBDIR}" ; then LIBS="${LIBXML_LIBDIR--L.} ${LIBS}" LD_PATH="${LIBXML_LIBDIR-.}" fi PKG_CPPFLAGS="${PKG_CPPFLAGS} -DLIBXML" if test -z "${FROM_GNOME_XML_DIR}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} ${LIBXML_INCDIR--I.}" fi if test -z "${LIBXML2}" ; then dnl Now we try to test whether we have a really old libxml dnl which uses childs and root instead of xmlChildren and xmlRootNode if test -z "${USE_OLD_ROOT_CHILD_NAMES}" ; then CPPFLAGS=${PKG_CPPFLAGS} AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlDocPtr node; node->xmlRootNode = NULL; ]])],[echo "New style libxml!"],[USE_OLD_ROOT_CHILD_NAMES=1; echo "Need to use old-style libxml names"]) echo "Using old root child names? ${USE_OLD_ROOT_CHILD_NAMES-0}" fi # USE_OLD_ROOT_CHILD_NAMES else # -z "${LIBXML2}" CPPFLAGS=${PKG_CPPFLAGS} if test -d "${LIBXML_LIBDIR}" ; then LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${LIBXML_LIBDIR} export LD_LIBRARY_PATH fi AC_RUN_IFELSE([AC_LANG_SOURCE([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main(int argc, char *argv[]) { xmlCheckVersion(20000); return(0); } ]])],[ LIBXML2_OK=1],[LIBXML2_OK=0],[]) if test "${LIBXML2_OK}" = "0" ; then echo "You are trying to use a version 2.* edition of libxml" echo "but an incompatible library. The header files and library seem to be" echo "mismatched. If you have specified LIBXML_INCDIR, make certain to also" echo "specify an appropriate LIBXML_LIBDIR if the libxml2 library is not in the default" echo "directories." exit 1 fi fi if test -n "${USE_OLD_ROOT_CHILD_NAMES}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_OLD_ROOT_CHILD_NAMES=1" fi fi if test "${USE_XMLLIB_NAME}" = "xml2" ; then AC_CHECK_LIB(xml2, xmlHashSize, echo "Using built-in xmlHashSize", PKG_CPPFLAGS="${PKG_CPPFLAGS} -DOWN_XML_HASH_SIZE=1") fi if test "${USE_LIBXML}" ; then echo "Checking DTD parsing (presence of externalSubset)..." AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlParserCtxtPtr ctxt; ctxt->inSubset = 0; ctxt->sax->externalSubset = NULL; ]])],[USE_EXT_SUBSET=1],[]) if test -n "${USE_EXT_SUBSET}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_EXTERNAL_SUBSET=1" fi AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlNodePtr node; int x; x = node->type == XML_DTD_NODE; ]])],[ROOT_HAS_DTD_NODE=1],[echo "No XML_DTD_NODE defined"]) if test -n "${ROOT_HAS_DTD_NODE}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DROOT_HAS_DTD_NODE=1" fi AC_CHECK_LIB(${USE_XMLLIB_NAME},xmlHashSize, echo "Found xmlHashSize", echo "No xmlHashSize") AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlEntityPtr ent; ent->checked = 1; ]])],[ENTITY_HAS_CHECKED="yes"],[ENTITY_HAS_CHECKED="no"]) if test "${ENTITY_HAS_CHECKED}" = "no" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DNO_CHECKED_ENTITY_FIELD=1" fi fi dnl Here we added the check of the flag to determine if the user wants to force dnl the XML_OUTPUT_BUFFER code in XMLTree.c AC_CHECK_LIB(${USE_XMLLIB_NAME}, xmlOutputBufferCreateBuffer, [echo "have xmlOutputBufferCreateBuffer()"; if test "${ADD_XML_OUTPUT_BUFFER}" = "yes" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DADD_XML_OUTPUT_BUFFER_CODE=1"; else ADD_XML_OUTPUT_BUFFER=no ; fi; ], [ echo "Using local xmlOutputBufferCreateBuffer. You might think about installing a newer version of libxml2, at least 2.6.23" ; PKG_CPPFLAGS="${PKG_CPPFLAGS} -DADD_XML_OUTPUT_BUFFER_CODE=1"; ADD_XML_OUTPUT_BUFFER=1]) AC_CHECK_LIB(${USE_XMLLIB_NAME}, xmlDocDumpFormatMemoryEnc, PKG_CPPFLAGS="${PKG_CPPFLAGS} -DDUMP_WITH_ENCODING=1") if test -z "${FROM_GNOME_XML_DIR}" ; then AC_CHECK_HEADER(libxml/xmlversion.h, PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_XML_VERSION_H=1") fi AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlElementPtr el; int x; x = el->etype; ]])],[PKG_CPPFLAGS="${PKG_CPPFLAGS} -DXML_ELEMENT_ETYPE=1" ],[]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif]], [[ xmlAttributePtr el; int x; x = el->atype; ]])],[PKG_CPPFLAGS="${PKG_CPPFLAGS} -DXML_ATTRIBUTE_ATYPE=1" ],[]) if test -n "${USE_EXPAT}" ; then AC_CHECK_HEADER(xmltok/xmlparse.h, XMLPARSE_INCDIR="xmltok/") if test -z "${XMLPARSE_INCDIR}" ; then AC_CHECK_HEADER(xmlparse/xmlparse.h, XMLPARSE_INCDIR="xmlparse/") fi AC_EGREP_HEADER(XML_Parse, ${XMLPARSE_INCDIR}xmlparse.h, HAVE_EXPAT_HEADER=true, AC_MSG_ERROR("header file xmlparse.h seems to be incorrect")) AC_CHECK_LIB(xmltok, XmlInitEncoding,,AC_MSG_ERROR("libxmltok not found")) AC_CHECK_LIB(xmlparse, XML_Parse,, AC_MSG_ERROR("libxmlparse not found"), -lxmltok) PKG_CPPFLAGS="${PKG_CPPFLAGS} -DLIBEXPAT -I${XMLPARSE_INCDIR}" LD_PATH="${LD_PATH}:${LIBXML_LIBDIR}" fi if test -n "${USE_EXPAT}" ; then SUPPORTS_EXPAT="TRUE" else SUPPORTS_EXPAT="FALSE" fi echo "Expat: ${USE_EXPAT} ${SUPPORTS_EXPAT}" if test -n "${USE_LIBXML}" ; then SUPPORTS_LIBXML="TRUE" else SUPPORTS_LIBXML="FALSE" fi if test -z "${USE_SPLUS}" ; then LANGUAGE_DEFS="-DUSE_R=1 -D_R_=1 ${LANGUAGE_DEFS}" dnl PKG_SYS_FILE='system.file("scripts", name, pkg="RSPerl")' else dnl Test to see if the patch has been made to renamin the attribute() dnl routine in libxml if test ${SUPPORTS_LIBXML}="TRUE" ; then AC_CHECK_LIB(xml, attribute, NEED_LIBXML_PATCH=1) if test -n "${NEED_LIBXML_PATCH}" ; then echo "The XML package will not work with S-Plus and the current libxml" echo "because of a conflict from both having a routine named attribute()" echo "We suggest that you modify the SAX.c file in the libxml and re-install." echo "See PATCH.attribute in this package's distribution." exit 1 fi fi # ? SUPPORTS_LIBXML = "TRUE" LANGUAGE_DEFS="-D_S_=1 -DUSE_S=1 -D_S4_=1 -D_SPLUS${SPLUS_VERSION}_ -DNO_SPLUS_THREAD_DEF=1 ${LANGUAGE_DEFS}" INSTALL_DIR=`pwd` PKG_SYS_FILE="paste(\"${INSTALL_DIR}/inst/scripts/\", name,sep=\"\")" fi dnl end of if S-Plus. AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include "parser.h" ]], [[ extern int xmlSkipBlankChars(xmlParserCtxtPtr ctxt); xmlParserCtxtPtr p; xmlSkipBlankChars(p); ]])],[echo "No need for old SKIP_BLANKS definition" ],[BLANKS_DEF="-DOLD_SKIP_BLANKS=1" ]) if test -n "LIBXML2" ; then TMP_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} -pedantic-errors" echo "Checking for return type of xmlHashScan element routine." AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #include #else #include #include #endif ]], [[ void *(*foo)(void *, void *, xmlChar*); xmlElementTablePtr table; xmlHashScan(table, foo, NULL); ]])],[echo "xmlHashScan wants a return value."],[echo "No return value for xmlHashScan"; PKG_CPPFLAGS="${PKG_CPPFLAGS} -DNO_XML_HASH_SCANNER_RETURN=1" ]) CFLAGS="${TMP_CFLAGS}" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ xmlNsPtr ns; ns->context; ]])],[PKG_CPPFLAGS="$PKG_CPPFLAGS -DLIBXML_NAMESPACE_HAS_CONTEXT=1"; echo "xmlNs has a context field"],[echo "No context field in xmlNs structure."]) fi CPPFLAGS="$CPPFLAGS -I$R_HOME/include" echo "Checking for cetype_t enumeration" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ cetype_t t; ]])],[PKG_CPPFLAGS="${PKG_CPPFLAGS} -DHAVE_R_CETYPE_T=1"; echo "Using recent version of R with cetype_t enumeration type for encoding"],[echo "No cetype_t enumeration defined in R headers."]) AC_SUBST(DUMP_WITH_ENCODING) PKG_LIBS=${LIBS} dnl ---------------------------------------------------- dnl Add -m to the linker flags (actually libraries) dnl to supress errors about multiple definitions of dnl symbols. dnl dnl This is not needed anymore as we no longer define dnl xmlParserError in our code and override the one dnl in libmxml. If we do find a situation (e.g. version dnl of libxml that doesn't allow us to play with routine dnl pointers to do this, we will need to define dnl NEED_XML_PARSER_ERROR dnl dnl AC_CANONICAL_HOST dnl Doesn't work on my machine. Where do we find it - R? if test -n "${NEED_XML_PARSER_ERROR}" ; then AC_PATH_PROG(UNAME, uname) if test -n "${UNAME}" ; then host_os=`${UNAME}` if test "${host_os}" = "Darwin" ; then PKG_LIBS="-m $PKG_LIBS" fi fi fi dnl --------------------------------------------------- AC_PATH_PROGS(XMLSEC_CONFIG, xmlsec1-config) if test -n "$XMLSEC_CONFIG" ; then PKG_CPPFLAGS="$PKG_CPPFLAGS `$XMLSEC_CONFIG --cflags`" PKG_LIBS="$PKG_LIBS `$XMLSEC_CONFIG --libs`" XMLSEC_DEFS=-DHAVE_LIBXML_SEC=1 fi AC_ARG_ENABLE(nodegc, [ --enable-nodegc enable node garbage collection], [ if test "${enableval}" = "yes" || test "${enableval}" = "default" ; then LANGUAGE_DEFS="${LANGUAGE_DEFS} -DXML_REF_COUNT_NODES=1" fi; echo "enabling nodegc? ${enableval}"], [echo "nodegc default $enableval"; LANGUAGE_DEFS="${LANGUAGE_DEFS} -DXML_REF_COUNT_NODES=1"]) AC_ARG_ENABLE(xml-debug, [ --enable-xml-debug enable debugging information, primarily for memory management], [ if test "${enableval}" = "yes" || test "${enableval}" = "default" ; then LANGUAGE_DEFS="${LANGUAGE_DEFS} -DR_XML_DEBUG=1" fi; echo "enabling xml-debug? ${enableval}"], [echo "xml-debug default $enableval"; LANGUAGE_DEFS="${LANGUAGE_DEFS}"]) dnl --------------------------------------------------- AC_DEFUN([CHECK_ENUM], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif ]], [[ int val; val = $1; ]])],[PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_$1=1"; echo "Version has $1"],[echo "No $1 enumeration value."]) ]) CHECK_ENUM(XML_WITH_ZLIB) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif ]], [[ xmlFeature f; xmlHasFeature(f); ]])],[PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_XML_HAS_FEATURE=1"; echo "Version has xmlHasFeature()"],[echo "No xmlHasFeature."]) dnl --------------------------------------------- AC_SUBST(XMLSEC_DEFS) AC_SUBST(LIBXML2) AC_SUBST(LANGUAGE_DEFS) AC_SUBST(LIBXML_INCDIR) AC_SUBST(XMLPARSE_INCDIR) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CPPFLAGS) AC_SUBST(SUPPORTS_LIBXML) AC_SUBST(SUPPORTS_EXPAT) AC_SUBST(LD_PATH) AC_SUBST(EXPORT_MEMORY_MANAGEMENT) if test -n "${USE_SPLUS}" ; then AC_SUBST(SPLUS) SPLUS_MAKEFILE=GNUmakefile.Splus fi echo "" echo "****************************************" echo "Configuration information:" echo "" echo "Libxml settings" echo "" echo "libxml include directory: ${LIBXML_INCDIR}" echo "libxml library directory: ${LIBS}" echo "libxml 2: ${LIBXML2-no}" echo "" echo "Compilation flags: ${PKG_CPPFLAGS} ${LANGUAGE_DEFS} $XMLSEC_DEFS" echo "Link flags: ${PKG_LIBS}" echo "" echo "****************************************" if test "$ADD_XML_OUTPUT_BUFFER" = "no" ; then ADD_XML_OUTPUT_BUFFER=0 fi if test "$ADD_XML_OUTPUT_BUFFER" = "yes" ; then ADD_XML_OUTPUT_BUFFER=1 fi AC_SUBST(ADD_XML_OUTPUT_BUFFER) if test -n "${_R_CHECK_TIMINGS_}" ; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DNO_XML_MEMORY_SHOW_ROUTINE=1" fi dnl create the different targets dnl We had NAMESPACE here when were conditionally exporting the functions to dnl remove finalizers on a node or document. Need to add NAMESPACE.in in dnl Install/GNUmakefile.admin AC_CONFIG_FILES([src/Makevars R/supports.R inst/scripts/RSXML.csh inst/scripts/RSXML.bsh ${SPLUS_MAKEFILE}]) AC_OUTPUT chmod +x cleanup dnl Set things up for an S-Plus chapter. if test -n "${USE_SPLUS}" ; then mv GNUmakefile.Splus GNUmakefile echo "Creating S-Plus chapter" cd src C_SRC_FILES="DocParse.c RSDTD.c Utils.c" ${SPLUS} CHAPTER ${C_SRC_FILES} echo "include Makevars" >> makefile echo 'CFLAGS:= $(PKG_CPPFLAGS) $(CFLAGS)' >> makefile echo 'LOCAL_LIBS=$(PKG_LIBS) ' >> makefile cd .. fi XML/inst/0000755000175100001440000000000013607643014011711 5ustar hornikusersXML/inst/examples/0000755000175100001440000000000014636531033013527 5ustar hornikusersXML/inst/examples/README0000644000175100001440000000024613607633730014415 0ustar hornikuserspropmptXML - an R function analogous to prompt for generating help/documentation files for R functions, but this generates this in XML format according to Rhelp.dtd. XML/inst/examples/gettingStarted.xml0000644000175100001440000001771313607633725017262 0ustar hornikusers
The idea here is to provide simple examples of how to get started with processing XML in R using some reasonably straightforward "flat" XML files and not worrying about efficiency.
An Example: Grades Here is an example of a simple file in XML containing grades for students for three different tests. We might want to turn this into a data frame in R with a row for each student and four variables, the name and the scores on the three tests. Since this is a small file, let's not worry about efficiency in any way. We can read the entire document tree into memory and make multiple passes over it to get the information. Our first approach will be to read the XML into an R tree, i.e. R-level XML node objects. We do this with a simple call to xmlTreeParse. doc = xmlRoot(xmlTreeParse("generic_file.xml")) We use xmlRoot to get the top-level node of the tree rather than holding onto the general document information since we won't need it. Since the structure of this file is just a list of elements under the root node, we need only process each of those nodes and turn them into something we want. The "easiest" way to apply the same function to each child of an XML node is with the xmlApply function. What do we want to do for each of the <GRADES> node? We want to get the value, i.e. the simple text within the node, of each of its children. Since this is the same for each of the child nodes in <GRADES>, this is again another call to xmlApply. And since this is all text, we can simplify the result and get back a character vector rather than a list by using xmlSApply which will perform this extra simplication step. So a function to do the initial processing of an individual <GRADES> node might be function(node) xmlSApply(node, xmlValue) since xmlValue returns the text content within an XML node. Let's check that this does what we want by calling it on the first child of the root node. xmlSApply(doc[[1]], xmlValue) And indeed it does. So we can process all the <GRADES> nodes with the command tmp = xmlSApply(doc, function(x) xmlSApply(x, xmlValue)) The result is a character matrix in which the rows are the variables and the columns are the records. So let's transpose this. tmp = t(tmp) Now, we have finished working with the XML; the rest is regular R programming. grades = as.data.frame(matrix(as.numeric(tmp[,-1]), 2)) names(grades) = names(doc[[1]])[-1] grades$Student = tmp[,1] There seems to be more messing about after we have got the values out of the XML file. There are several things that might seem more complex but that actually just move the work to different places, i.e. when we are traversing the XML tree. Here's another alternative using XPath. doc = xmlTreeParse("generic_file.xml", useInternal = TRUE) ans = lapply(c("STUDENT", "TEST1", "TEST2", "FINAL"), function(var) unlist(xpathApply(doc, paste("//", var, sep = ""), xmlValue))) And this gives us a list containing the variables with the values as character vectors. as.data.frame(lapply(names(ans), function(x) if(x != "STUDENT") as.integer(x) else x ))
Another Example: Customer Information List The second example is another list, this time of description of customers. The first two nodes in the document are shown below: ALFKI Alfreds Futterkiste Maria Anders Sales Representative
Obere Str. 57
Berlin 12209 Germany 030-0074321 030-0076545
ANATR Ana Trujillo Emparedados y helados Ana Trujillo Owner
Avda. de la Constitución 2222
México D.F. 05021 Mexico (5) 555-4729 (5) 555-3745
]]>
We can quickly verify that all the nodes under the root are customers with the command doc = xmlRoot(xmlTreeParse("Cust-List.xml")) table(names(doc)) We see that these are all "Customers". We could further explore to see if each of these nodes has the same fields. fields = xmlApply(doc, names) table(sapply(fields, identical, fields[[1]])) And the result indicates that about half of them are the same. Let's see how many unique field names there are: unique(unlist(fields)) This gives 10. And we can see how may fields are in each of the Customers nodes with xmlSApply(doc, xmlSize) So most of the nodes have most of the fields. So let's think about a data frame. What we can do is treat each of the fields as having a simple string value. Then we can create a data frame with the 10 character columns and with NA values for each of the records. Thne we will fill this in record at a time. ans = as.data.frame(replicate(10, character(xmlSize(doc))), stringsAsFactors = FALSE) names(ans) = unique(unlist(fields)) Now that we have the skeleton of the answer, we can process each of the Customers nodes. Note that we used a global assignemnt in the function to change the ans in the global environment rather than the local version within the function call. Also, we loop over the indices of the nodes in the tree, i.e. use sapply(1:xmlSize(doc), ) rather than xmlSApply(doc, ) simply because we need to know which row to put the results for each node.
There are various other ways to process these two XML files. One is to use handler functions to process the internal nodes as they are being converted from C-level data structures to R objects in a call to xmlTreeParse. This avoids multiple traversal of the tree but can seem a little indirect until you get the hang of it. And some transformations can be cumbersome using this approach as it is a bottom up transformation. The event-driven parsing provided by xmlEventParse is a SAX style approach. This is quite low level and used when reading the entire XML document into memory and then processing it is prohibitive, i.e. when the XML file is very, very large. The use of XPath to perform queries and get subsets of nodes involves a) learning XPath and b) potentially multiple passes over the tree. If one has to do many queries, this can be slow overall eventhough each is very fast. However, if you know XPath or are happy to learn the basics, this can be quite convenient, avoiding having to write recursive functions to search for the nodes of interests. Using the internal nodes (as you must for XPath) also gives you the ability to go up the tree, i.e. find parent, ancestor and sibling nodes, and not just down to children. So we have more flexibility in how we traverse the tree.
XML/inst/examples/promptXML.Sxml0000644000175100001440000001151013607633730016300 0ustar hornikusers ]> Here we define some prompt.xml this is the name of the file into which the documentation is placed. In the future, this will be a connection object. this is text that is to be placed immediately after the ]]> string emitted as the first part of the text. In the future, we will want to append/insert content into existing documents and so we will have to recognize not to add this PI again, etc. 0) { arg.names <- names(argls) } xml$addTag("sname", name,sep="") for (i in s) { xml$addTag("arg", xml$tagString("argName", arg.names[i]), close=F) if(!is.missing.arg(argls[[i]])) { xml$addTag("defaultValue", deparse(argls[[i]]),sep="") } xml$closeTag("arg") if(i < n) xml$addTag("next") } xml$add("") xml$addTag("arguments", close=F) for(i in arg.names) { xml$addTag("argument", xml$tagString("argDescriptionName", i), "\n", "~~Describe ",i," here~~", "") } xml$add("") xml$addTag("details"," ~~ If necessary, more details than the __description__ above ~~") xml$addTag("value", "~Describe the value returned", " If it is a LIST, use", " \\item{comp1 }{Description of `comp1'}", " \\item{comp2 }{Description of `comp2'}", " ...") xml$addTag("references", ifelse(!is.null(local$references), local$references, "")) xml$addTag("author", ifelse(!is.null(local$author), local$author, "")) xml$addTag("note") xml$addTag("seeAlso", xml$tagString("a", attrs=list("href"="\"\""))) xml$addTag("examples", xml$tagString("example")) xml$addTag("keywords", xml$tagString("keyword")) if(!is.null(footer)) xml$add(footer) val <- xml$value() if(!missing(file)) cat(val, file=file) val } ]]> # Always start with the perverse one! xmlPrompt(xmlPrompt) xmlWriteBuffer Want to check with the DTD whether a tag is legitimate attributes are valid, etc. Add an indentation level. Need to escape characters via entities: %sgets; < => %lt; > => %gt; ]]> etc. " add <- function(..., sep="\n") { buf <<- paste(buf, paste0(...), sep=sep) } tagString <- function(tag, ..., attrs, close=F) { tmp <- "" if(!missing(attrs)) { tmp <- paste(" ", paste(names(attrs), attrs,sep="=", collapse=" "),sep="") } return(paste0("<", tag,tmp, ">",...,"")) } addTag <- function(tag, ..., attrs=NULL, sep="\n", close=T) { tmp <- "" if(!missing(attrs)) { tmp <- paste(" ", paste(names(attrs), attrs,sep="=", collapse=" "),sep="") } add(paste("<",tag, tmp, ">", sep="")) if(length(list(...)) > 0) { add(..., sep=sep) } if(close) { add(paste("", sep=""), sep="") } NULL } closeTag <- function(name) { add("\n", "", sep="") } list( value=function() {buf}, add = add, addTag = addTag, closeTag = closeTag, tagString = tagString ) } ]]> XML/inst/examples/itunes.xsl0000644000175100001440000000126613607633725015603 0ustar hornikusers XML/inst/examples/HTMLText.R0000644000175100001440000000155013607633725015274 0ustar hornikusers# The following illustrates how we can get the text # Michael Conklin. # Also see ./foo.html as an example with javascript content # and a pseudo/fake css node. doc = htmlParse("http://www.omegahat.net/") txt = xpathSApply(doc, "//body//text()", xmlValue) #The result is a character vector that contains all the text. #By limiting the nodes to the body, we avoid the content in #such as inlined JavaScript or CSS. #It is also possible that a document may have CSS content

Some additional text. And a link.


Duncan Temple Lang <duncan@wald.ucdavis.edu>
Last modified: Thu Dec 3 17:13:16 PST 2009 XML/inst/examples/event.R0000644000175100001440000000153713607633725015011 0ustar hornikusersh = list(.text = function(content) cat("text:", content, "\n"), .comment = function(content) cat("##", content, "\n"), .processingInstruction = function(target, content) cat("PI: [", target, "]", content, "\n"), .startElement = function(node, attrs) { cat("New node:", node, paste(names(attrs), collapse = ", "), "\n")}, .endElement = function(node) { cat("end node:", node, "\n")}, .startDocument = function(...) cat("start of document\n"), .endDocument = function(...) cat("end of document\n"), .cdata = function(content) cat("CDATA:", content, "\n"), .entityDeclaration = function(...) {cat("Defining an entity\n"); print(list(...))}, .getEntity = function(name) { cat("Getting entity", name, "\n") ; "x"} #entity, isStandalone ) xmlEventParse("test.xml", h, useDotNames = TRUE) XML/inst/examples/valueFilterDataFrameEvent.R0000644000175100001440000000472413607633725020722 0ustar hornikusers# # A closure for use with xmlEventParse # and for reading a data frame using the DatasetByRecord.dtd # DTD in $OMEGA_HOME/XML/DTDs. # To test # xmlEventParse("mtcars.xml", handler()) # valueDataFrameFilter <- function(accept) { data <- NULL # Private or local variables used to store information across # method calls from the event parser numRecords <- 0 varNames <- NULL meta <- NULL expectingVariableName <- F rowNames <- NULL currentColumn <- 1 currentRowName <- NULL numCols <- 1 # read the attributes from the dataset dataset <- function(x, atts) { numRecords <<- as.integer(atts[["numRecords"]]) # store these so that we can put these as attributes # on data when we create it. meta <<- atts } variables <- function(x, atts) { # From the DTD, we expect a count attribute telling us the number # of variables. # data <<- matrix(0., numRecords, as.integer(atts[["count"]])) data <<- list() numCols <- as.integer(atts[["count"]]) # set the XML attributes from the dataset element as R # attributes of the data. # attributes(data) <<- meta } # when we see the start of a variable tag, then we are expecting # its name next, so handle text accordingly. variable <- function(x,...) { expectingVariableName <<- T } record <- function(x,atts) { currentRowName <<- atts[["id"]] } text <- function(x,...) { if(x == "") return(NULL) if(expectingVariableName) { varNames <<- c(varNames, x) if(length(varNames) >= numCols) { expectingVariableName <<- F #dimnames(data) <<- list(NULL, varNames) } } else { e <- gsub("[ \t]*",",",x) els <- strsplit(e,",")[[1]] names(els) <- varNames if(accept(els)) { data[[length(data)+1]] <<- els rowNames <<- c(rowNames, currentRowName) } } } endElement <- function(x,...) { if(x == "dataset") { data <<- data.frame(matrix(unlist(data),length(data),length(varNames), byrow=T)) names(data) <<- varNames dimnames(data)[[1]] <<- rowNames } else if(x == "record") { currentColumn <<- 1 } } return(list(variable = variable, variables = variables, dataset=dataset, text = text, record= record, endElement = endElement, data = function() {data }, rowNames = function() rowNames )) } XML/inst/examples/rcode.xsl0000644000175100001440000000000013607633725015351 0ustar hornikusersXML/inst/examples/xmlTree.R0000644000175100001440000000034213607633725015301 0ustar hornikuserstt = xmlTree("doc") # Shows that we can create the children within the call to create # a parent. tt$addTag("a", tt$addTag("b", tt$addTag("c")), tt$addTag("d", tt$addTag("e"))) XML/inst/examples/schema.xsd0000644000175100001440000000061313607633725015517 0ustar hornikusers XML/inst/examples/SAXEntity.R0000644000175100001440000000142613607633730015511 0ustar hornikusersentities <- new.env(TRUE) assign(".text", "", entities) handlers = list( .entityDeclaration = function(name, type, content, system, public) { if((length(content) == 0 || nchar(content) == 0) && length(system) > 0) { # if(file.exists(system)) content = paste(readLines(system), collapse = "\n") } if(length(content)) assign(name, content, entities) else warning("Can't resolve entity ", name) }, .getEntity = function(name) { if(exists(name, entities)) return(get(name, entities)) return(character()) }, .text = function(txt) { entities$.text <- paste(entities$.text, txt) }) xmlEventParse("entity2.xml", handlers, useDotNames = TRUE) XML/inst/examples/bondYields.R0000644000175100001440000000075313607633725015763 0ustar hornikusers uri = "http://www.treas.gov/offices/domestic-finance/debt-management/interest-rate/yield.xml" h = function() { tables = list() tb = function(node) { # this will drop any NULL values from empty nodes. els = unlist(xmlApply(node, xmlValue)) vals = as.numeric(els) names(vals) = gsub("BC_", "", names(els)) tables[[length(tables) + 1]] <<- vals NULL } list("G_BC_CAT" = tb, getTables = function() tables) } xmlTreeParse(uri, handlers = h())$getTables() XML/inst/examples/itunesSax.R0000644000175100001440000000276413607633744015657 0ustar hornikuserssaxHandlers = function() { tracks = list() dictLevel = 0L key = NA value = character() track = list() text = function(val) { value <<- paste(value, val, sep = "") } startElement = function(name, attrs) { if(name %in% c("integer", "string", "date", "key")) value <<- character() if(name == "dict") dictLevel <<- dictLevel + 1L } convertValue = function(value, textType) { switch(textType, integer = as.numeric(value), string = value, date = as.POSIXct(strptime(value, "%Y-%m-%dT%H:%M:%S")), default = value) } endElement = function(name) { if(name %in% c("integer", "string", "date")) track[[key]] <<- convertValue(value, name) else if(name == "key") key <<- value else if(name == "dict" && dictLevel == 3) { class(track) = "iTunesTrackInfo" tracks[[ length(tracks) + 1]] <<- track track <<- list() dictLevel <<- 2 } } list(startElement = startElement, endElement = endElement, text = text, tracks = function() tracks) } h = saxHandlers() #xmlEventParse(path.expand(fileName), handlers = h) # 5.9 seconds. But this is parsing and processing into tracks. # system.time({dd = xmlEventParse(path.expand(fileName), handlers = h, addContext = FALSE)}) # 5.93 seconds on average (SD of .09) # sax = replicate(10, system.time({dd = xmlEventParse(path.expand(fileName), handlers = h, addContext = FALSE)})) XML/inst/examples/connections.R0000644000175100001440000000144213607633725016205 0ustar hornikuserslibrary(XML) fileName = system.file("exampleData", "job.xml", package = "XML") # xmlEventParse(file(fileName, "r")) xmlConnection = function(con) { if(is.character(con)) con = file(con, "r") if(isOpen(con, "r")) open(con, "r") function(len) { if(len < 0) { cat("closing connection in xmlConnection\n") close(con) return(character(0)) } cat("getting line from connection\n") x = character(0) tmp = "" while(length(tmp) > 0 && nchar(tmp) == 0) { tmp = readLines(con, 1) if(length(tmp) == 0) break if(nchar(tmp) == 0) x = append(x, "\n") else x = tmp } if(length(tmp) == 0) return(tmp) x = paste(x, collapse="") print(x) x } } v = xmlEventParse(xmlConnection(fileName)) XML/inst/examples/sbmlSAX.S0000644000175100001440000000564013607633744015202 0ustar hornikusersMathMLOperations = c("power" = "^", "times" = "*", "plus" = "+" ) handlers = function(operations = MathMLOperations) { current = list() state = character() start = function(x, atts, ...) { # Handle the opening tags and set the stack appropriately. if(x == "apply") { # Make a call with a silly name that we will change when we read the next element # giving the operation. current <<- c(call(""), current) state <<- c("call", state) } else if(x == 'ci') { # Expecting the next text contents to be a name of a variable. state <<- c("name", state) current <<- c("", current) } else if(!is.na(idx <- match(x, names(operations)))) { # If we are dealing with a call and the name of this element being opened # matches our operation names, then insert the S name of the corrresponding # function into the previously created call. if(length(state) && state[1] == "call") current[[1]][[1]] <<- as.name(operations[idx]) # make certain that we add something to state stack so that when we close the # tag, we remove it, not the previously active element on the stack. state <<- c("<>", state) } } text = function(x, atts, ...) { if(x == "") return(FALSE) if(length(state) && state[1] == "name") { current[[1]] <<- paste(current[[1]], x, sep = "") } } end = function(x, atts, ...) { # If there is nothing on the stack, then nothing to close. if(length(state)) { if(state[1] == "call" && length(current) > 1) { # If ending an apply (call) and we have 2 or more things # on the stack, then fold this call (current[[1]]) into the argument of the # of the previous call (current[[2]]) at the end. e = current[[1]] f = current[[2]] # Should check f is a call or state[2] == "call" f[[length(f) + 1]] = e current[[2]] = f current <<- current[-1] } else if(state[1] == "name") { # ending a so we have a name, then put this into the # current call. if(length(state) > 1 && state[2] == "call") { # this is very similar to the previous block for call # except we have a as.name(). Could easily consolidate by doing # this coercion first. Left like this for clarity of concept. e = current[[2]] e[[length(e) + 1]] = as.name(current[[1]]) current[[2]] = e # Remove the elements from the top of the stacks. current <<- current[-1] } } state <<- state[-1] } } list(startElement = start, endElement = end, text = text, state = function() state, current = function() current) } XML/inst/examples/connections1.R0000644000175100001440000000147013607633725016267 0ustar hornikusers# Tests reading from a connection. # Trying to get the newlines. library(XML) ReadLines = function(con, n) { x = readLines(con, 1) #This works, but tagging the new line doesn't. return(x) if(length(x)) x = paste(x, "", sep="") print(x) x } handlers = function() { tags = character(0) atts = character(0) text = character(0) startElement = function(x, attrs) { tags <<- append(tags, x) atts <<- append(atts, attrs) } addText = function(txt, ...) { text <<- append(text, txt) } list(startElement = startElement, text = addText, .value = function() { list(tags, atts, text)}, cdata = function(x) addText(x)) } h = handlers() invisible(xmlEventParse(file(system.file("exampleData", "cdata.xml", package = "XML"), "r"), handlers = h)) h$.value() XML/inst/examples/modified_itunes_sax.R0000644000175100001440000000276513607633725017716 0ustar hornikusers# Read XML data using a low-level streaming model to be able to handle # very large data. # We'll just pick out Total Time # Use a modified version if iTunes format to make it a less generic format. #Need a state machine #Whenever we see the start of an XML element named Total_Time, #prepare to store the next pieces of text #Then when we see the end of the Total_Time, stop collecting. create = function(verbose = FALSE) { times <- character() inTotalTimeElement = FALSE # called for start of element, # so always set inTotalTime to TRUE tt = function(name, ...) { if(verbose) cat("In tt\n") inTotalTimeElement <<- TRUE } # If we are in a Total_Time element, # put the x into the times vector collect = function(x) { if(verbose) cat("in collect\n") if(inTotalTimeElement) times <<- c(times, x) } # Need to turn inTotalTimeElement off if it is on. endElement = function(name, ...) { # if(name == "Total_Time") if(verbose) cat("end Total_Time\n") inTotalTimeElement <<- FALSE } # return a list of functions which are used by the SAX parser # and also .result which gives us the values list("Total_Time" = tt, "/Total_Time" = endElement, .text = collect, .result = function() as.numeric(times)) } # if(FALSE) { h = create(verbose = TRUE) o = xmlEventParse("http://eeyore.ucdavis.edu/itunes-short.xml", handlers = h, saxVersion = 2) h$.result() } XML/inst/examples/newNodes.R0000644000175100001440000000050113607633744015441 0ustar hornikusersb = newXMLNode("k:bob", namespace = c(r = "http://www.r-project.org", omg = "http://www.omegahat.net", "")) addAttributes(b, a = 1, b = "xyz", "r:efg" = "2.4.1", "omg:len" = 3) xmlName(b) xmlName(b) <- "jane" saveXML(b) removeAttributes(b, "r:efg") removeAttributes(b, "a", "b") # or .attrs = c("a", "b") saveXML(b) XML/inst/examples/formals.xsl0000644000175100001440000000150413607633730015726 0ustar hornikusers other , = () XML/inst/examples/wordML.R0000644000175100001440000000117613607633744015074 0ustar hornikuserslibrary(XML) #tt = xmlTree("w:wordDocument", namespaces = c(w = "http://schemas.microsoft.com/office/word/2003/wordml")) tt = xmlTree(namespaces = c(w = "http://schemas.microsoft.com/office/word/2003/wordml")) tt$addPI("mso-application", "progid='Word.Document'") tt$addTag("wordDocument", namespace = "w", close = FALSE) # XXX if we put this first, we don't get the body. Need to then add the body # as a sibling of the PI. v = tt$addTag("w:body", tt$addTag("w:p", tt$addTag("w:r", tt$addTag("w:t", "Hello World!")))) tt$closeTag() cat(saveXML(tt)) XML/inst/examples/trademe_cars.R0000644000175100001440000000520213607633730016306 0ustar hornikusers# e.g. # getTradeMeCarData("http://www.trademe.co.nz/Trade-Me-Motors/Cars/Subaru/mcat-0001-0268-0332-.htm") getTradeMeCarPage = function(url, base = NULL) { tmp = parseURI(url) if(tmp$server == "") url = paste(base$scheme, "://", base$server, url, sep = "") d = htmlTreeParse(url, useInternal = TRUE) n = getNodeSet(d, "//table[@class='listings']") n = n[[1]] if(xmlName(n[[1]]) == "tbody") { rows = n[[1]] } else rows = n list(doc = d, rows = rows) } if(FALSE) { tbody = getTradeMeCarPage("~/TradeMe.cars.subaru.html")$tbody # the children of tbody are all tr elements table(xmlSApply(tbody, xmlName)) # And the first one has two elements and the remainder are the actual car listings xmlSApply(tbody, xmlSize) } getTradeMeCarData = function(url = "~/TradeMe.cars.subaru.html", data = NULL, numPages = 1) { uri = parseURI(url) doc = getTradeMeCarPage(url) rows = doc$rows if(is.null(data)) { # The first row has an entry of the form 1234 listings, showing 1 to 50" # so we get this number via regular expressions and gsub on the content # of that first cell. num = as.integer(gsub("^([0-9]+) .*", "\\1", xmlValue(rows[[1]][[1]]))) if(is.na(num) || numPages == 1) num = xmlSize(rows) - 1 # type/description, kms, amount, # bids, data = data.frame(description = I(character(num)), kms = integer(num), askingPrice = integer(num), numBid = as.integer(rep(NA, num)), auctionExpiration = I(character(num)), year = integer(num) ) } page = 1 cur = 1 while(page <= numPages) { tbody = rows for(i in 2:xmlSize(tbody)) { r = tbody[[i]] data[cur, 1] = xmlValue(r[[2]]) data[cur, "year"] = as.integer(gsub(".* ([0-9]{4})", "\\1", strsplit(data[cur, 1], "\302\240")[[1]][1])) data[cur, 2] = as.integer(gsub(",", "", xmlValue(r[[3]][[1]]))) data[cur, 3] = as.integer(gsub("[,$]", "", xmlValue(r[[4]]))) bids = xmlValue(r[[6]]) if(bids != "-") data[cur, 4] = as.integer(bids) data[cur, 5] = xmlValue(r[[7]]) cur = cur + 1 } nxt = getNodeSet(doc$doc, "//table//a/font/b[text() = 'Next']") if(length(nxt) == 0) { browser() print("no next page") break } # Get the element for the Next a = xmlParent(xmlParent(nxt[[1]])) doc = getTradeMeCarPage(xmlGetAttr(a, "href"), base = uri) tbody = doc$tbody } data[1:(cur-1), ] # invisible(data) } XML/inst/examples/functionIndex.Sxml0000644000175100001440000000216313607633725017223 0ustar hornikusers ]> functionIndex This function returns the names of the functions that are to be defined in this file. This allows one to know ahead of time what functions the file defines and to source specific functions from this file using the which argument of xmlSource function(file, ...) { d &sgets; xmlRoot(xmlTreeParse(file, ...)) sapply(d[names(d) == "function"], function(x) { if(!is.na(match("sname", names(x)))) xmlValue(x[["sname"]][[1]]) else { xmlValue(x[[1]][[1]]) } }) } XML/inst/examples/redirection.R0000644000175100001440000000202413607633725016167 0ustar hornikusers# This is an example of downloading data that is accessible via a text file # that is identified via a link in an HTML document that is returned from # a form submission. # The original form is available via the SWISSPROT site which is redirected # to www.expasy.org. # # This example illustrates the use of the FOLLOWLOCATION options in libcurl and hence # RCurl. # # The example was raised by Linda Tran at UC Davis. # Works as of May 12, 2006 # tt = getForm("http://www.expasy.org/cgi-bin/search", db = "sptrde", SEARCH = "fmod_bovin", .opts = list("FOLLOWLOCATION" = TRUE)) # Then, find the link node which has "raw text" # in the text of the link h = function() { link = "" a = function(node, ...) { v = xmlValue(node) if(length(grep("raw text", v))) link <<- xmlGetAttr(node, "href") node } list(a = a, .link = function() link) } a = h() htmlTreeParse(tt, asText = TRUE, handlers = a) a$.link() u = paste("http://www.expasy.org", a$.link(), sep = "") getURL(u) XML/inst/examples/namespaces1.S0000644000175100001440000000021113607633725016055 0ustar hornikusers XML/inst/examples/mexico.R0000644000175100001440000000062013607633730015140 0ustar hornikusers# An example posed by Herve Richard at INRIA. variable = function(node) { # Get the values. vals = scan(textConnection(xmlValue(node))) # Need the name attribute structure(list(vals), names = xmlGetAttr(node, "name")) } handlers = list(variable = variable) ans = xmlRoot(xmlTreeParse("mexico.xml", handlers = handlers, asTree = TRUE)) as.data.frame(xmlChildren(ans[["date"]])) XML/inst/examples/eventHandlers.R0000644000175100001440000000027413607633730016463 0ustar hornikuserscharacterOnlyHandler <- function() { txt <- NULL text <- function(val,...) { txt <<- c(txt, val) } getText <- function() { txt } return(list(text=text, getText=getText)) } XML/inst/examples/gnumericHandler.R0000644000175100001440000000166313607633725016777 0ustar hornikusers# # Should turn this into a data frame rather than a matrix. # This would allow us to preserve different data types across # columns/variables. Of course, there isn't an exact one-to-one # correspondence between spreadsheets and data frames. gnumericHandler <- function(fileName) { # read the XML tree from the file. d <- xmlTreeParse(fileName) # Get the Sheet sh <- d$doc$children[["Workbook"]]$children[["Sheets"]]$children[["Sheet"]]$children mat <- matrix(0, as.integer(sh$MaxRow$children[[1]]$value)+1, as.integer(sh$MaxCol$children[[1]]$value)+1) vals <- sh$Cells$children gnumericCellEntry <- function(x) { atts <- sapply(x$attributes, as.integer) val <- x$children$Content$children$text$value tmp <- switch(atts[["Style"]], "1"= as.numeric(val), "2"=as.numeric(val), "3"=val) mat[atts[["Row"]]+1, atts[["Col"]]+1] <<- tmp tmp } sapply(vals, gnumericCellEntry) return(mat) } XML/inst/examples/GNUmakefile0000644000175100001440000000041513607633725015611 0ustar hornikusersHTML_STYLESHEET=$(OMEGA_CSS_DIR)/OmegaTech.css #include $(OMEGA_HOME)/Config/GNUmakefile.xml include $(DYN_DOCS)/Make/Makefile #%.html: %.xml # xsltproc $(XSLT_PARAMS) --xinclude --param "html.stylesheet" "'http://www.omegahat.net/OmegaTech.css'" $(HTML_XSL) $< > $@ XML/inst/examples/pmml.R0000644000175100001440000000307213607633725014631 0ustar hornikusers # See http://www.dmg.org/v3-0/GeneralStructure.html setOldClass("rpart") setClass("PMMLTree", contains = "XMLInternalNode") setGeneric("getPMMLArrayType", function(x) standardGeneric("getPMMLArrayType")) PMMLArrayTypes = c("integer" = "int", "numeric" = "real", "logical" = "int", "character" = "string") setMethod("getPMMLArrayType", "vector", function(x) { as.character(PMMLArrayTypes[class(x)]) }) setAs("vector", "PMMLTree", function(from) { type = getPMMLArrayType(from) # put quotes around strings text = if(is.character(from)) paste('"', from, '"', sep = "", collapse = " ") else paste(from, collapse = " ") newXMLNode("Array", text, attrs = c(type = type, n = length(from))) }) setAs("logical", "PMMLTree", function(from) { as(as.integer(from), "PMMLTree") }) setAs("rpart", "PMMLTree", function(from) { tt = xmlTree("PMML", attrs = c(version = "3.0"), namespaces = "http://www.dmg.org/PMML-3_0") tt$addNode("Header", attrs = c(copyright = "?"), tt$addNode("Application", attrs = c(name = "R", version = paste(version$major, version$minor, sep = "."))), tt$addNode("Annotation", "Generated via the XML package"), tt$addNode("Timestamp", date())) tt$addNode("DataDictionary") xmlRoot(tt$value()) }) library(rpart) fit <- rpart(Kyphosis ~ Age + Number + Start, data=kyphosis) cat(saveXML( as(fit, "PMMLTree") )) XML/inst/examples/author.R0000644000175100001440000000037413607633725015170 0ustar hornikusersxsd = xmlTreeParse("examples/author.xsd", isSchema =TRUE, useInternal = TRUE) doc = xmlInternalTreeParse("examples/author.xml") #h = schemaValidationErrorHandler() #.Call("RS_XML_xmlSchemaValidateDoc", xsd@ref, doc, 0L, h) xmlSchemaValidate(xsd, doc) XML/inst/examples/xmlSource.R0000644000175100001440000001502213607633725015643 0ustar hornikusersxmlSource <- # # This is equivalent to source() but works # on an XML file with special tags. # See xml2tex.Sxml or promptXML.Sxml # for an early example. # function(file, env = globalenv(), include=character(0), validate = F, ..., trim=F) { # This handler will convert a XMLNode tag .... # into one with the additional class XMLFragmentNode, and # a reference to a fragment # to an object of class XMLFragmentRefNode h <- list(fragment=function(x, attr){ class(x) <- c("XMLFragmentNode", class(x)) x }, fragmentRef=function(x, attr){ class(x) <- c("XMLFragmentRefNode", class(x)) x }, defRef=function(x, attr){ class(x) <- c("XMLFunctionDefNode", class(x)) x }, Sexpression=function(x, attr){ class(x) <- c("XMLSExpressionNode", class(x)) x }) # Parse the tree, using the handlers above. doc <- xmlTreeParse(file, handlers=h, validate=as.logical(validate), ..., trim=trim, asTree=T) r <- xmlRoot(doc) # Get all the top-level fragment elements from the document # and massage them into a usable form. This means forming # a named list whose elements are the fragment contents/definitions # and whose names are the ids of the fragments. fragments <- xmlChildren(r)[names(r) == "fragment"] tmp <- sapply(fragments, function(x) xmlAttrs(x)["id"]) # fragments <- sapply(fragments, function(x) xmlValue(x[[1]])) names(fragments) <- tmp # Process all the children in the document. An apply..? # Perhaps a closure so that we can append the # functions that are defined to a list.... funs <- character(0) for(i in xmlChildren(r)[names(r) != "fragment"]) { # if the node is a processing instruction for R (), # evaluate its contents as an R expression. if(inherits(i, "XMLProcessingInstruction") & xmlName(i) == "R") eval(parse(text=xmlValue(i))) else if(inherits(i, "XMLTextNode")) { # Otherwise, if it is a text node, just print it. print(xmlValue(i)); cat("\n") } else if(inherits(i, "XMLSExpressionNode")) { xmlExpressionEval(i, r, env, fragments) } else { # Now, let's handle the other tags via switch statment. # Function definitions are handed to xmlFunctionDef() along # with the document itself, the list of fragments in which # chunk/fragment references can be resolved and finally the # environment in which to assign the function definition. obj <- switch(xmlName(i), "function" = xmlFunctionDef(i, r, env, fragments, include)) funs <- c(funs, obj) } } invisible(list(doc=r, defs = funs, file=file)) } xmlExpressionEval <- # # Need to resolve the references here. # function(node, root, env = globalenv(), fragments = NULL) { txt <- paste(unlist(xmlSApply(node, xmlValue)), collapse=" ") eval(parse(text=txt), envir=env) } xmlFunctionDef <- # # This takes a function definition in XML form and # resolves any fragment references and so generates # a complete textual version of the function body and # argument list. # It grabs the name from the tag assumed to be # at the top of the function definition. # # # Needs to handle cross-references. # That's why we need the entire document here. # function(node, root, env = globalenv(), fragments = NULL, includes=character(0)) { # First determine if this can run or not. isR <- length(xmlAttrs(node)) == 0 | is.na(match("lang", names(xmlAttrs(node)))) if(!isR) { lang <- xmlAttrs(node)["lang"] isR <- lang== "S" | lang=="R" } if(!isR){ warning(paste("Skipping function", xmlAttrs(node)["lang"])) return(F) } # What about multiple chunks within the definition def <- node[["def"]] if(is.null(def)) return(NULL) def <- xmlFunctionDef.XMLFunctionDefNode(def, root, env, fragments) if(!is.na(match("sname", names(node)))) { name <- xmlValue(node[["sname"]][[1]]) if(length(includes)) { if(is.na(match(name, includes))) warning(paste("Skipping function", name)) } # cat("Defining function",name,"\n") assign(name, def, envir=env) return(name) } else { return(def) } } xmlFunctionDef.XMLFunctionDefNode <- # # This attempts to convert the contents of a ... # element into a function definition. It does so by converting each # element within this to text, resolving any fragment references # and converting them to text recursively. # function(node, root, env = globalenv(), fragments = NULL) { txt <- character(0) for(i in xmlChildren(node)) { if(inherits(i, "XMLFragmentRefNode")) txt <- c(txt, xmlResolveFragmentRefs(i, root, fragments)) else { txt <- c(txt, " ", xmlValue(i)) } } #cat("Parsing.... ",paste(txt, collapse=""), "\n") obj <- eval(parse(text=paste(txt, collapse="")), envir = env) invisible(obj) } xmlResolveFragmentRefs <- function(body, root, fragments = NULL) { UseMethod("xmlResolveFragmentRefs") } xmlResolveFragmentRefs.XMLFragmentRefNode <- function(body, root, fragments = NULL) { id <- xmlAttrs(body)["id"] v <- xmlValue(fragments[[id]][[1]]) return(v) } xmlResolveFragmentRefs.XMLNode <- function(body, root, fragments = NULL) { v <- xmlSApply(body, function(x, fragments) { if(inherits(x, "XMLFragmentRefNode")) { id <- xmlAttrs(x)["id"] # print(class(fragments[[id]]));print(xmlSize(fragments[[id]]));print(fragments[[id]]) v <- xmlSApply(fragments[[id]], function(x, root, fragments) { print(class(x)) if(inherits(x,"XMLFragmentRefNode")) { print(x) xmlResolveFragmentRefs(x, root, fragments) } else if(inherits(x,"XMLNode")) xmlValue(x) else x }, root=root, fragments=fragments) v <- paste(as.character(unlist(v)), collapse=" ") #print(v) } else v <- c("\n",xmlValue(x)) v }, fragments = fragments) paste(as.character(unlist(v)), collapse="") } XML/inst/examples/mathmlPlot.R0000644000175100001440000001306513607633744016011 0ustar hornikusers# # Functions to illustrate how to convert a MathML tree # to an R expression that can be used to annotate a plot # as an argument to plotmath. # # # mchar # mfrac # !=, ==, <=, >=, etc.to the # sqrt, # sub-, super-script [], ^ # times %*% # %~~% # %subset%, %subseteq% # %supset%, %supseteq% # %in% # %notin% # hat # tilde # group("(",list(a, b),"]") # inf(S) # sum(x[i],i==1,n) # # # # mathmlPlot <- function(node) { UseMethod("mathmlPlot",node) } mathmlPlot.XMLDocument <- function(doc) { return(mathmlPlot(doc$doc$children)) } mathmlPlot.default <- function(children) { expr <- expression() i <- 1 ok <- (i <= length(children)) while(ok) { #cat(i,"\n") child <- children[[i]] if(is.null(child)) { i <- i+1 ok <- (i <= length(children)) next } if(!is.null(class(child)) && class(child) == "XMLComment") { i <- i+1 ok <- (i <= length(children)) next } # if(inherits(child,"XMLNode")) {} #if(is.null(class(child))) cat("Null child:",child,"\n") if(xmlName(child) == "mo") { op <- child$children[[1]]$value if(op == "sum") { # needs to get operand. tmp <- c(as.name(op), quote(x[i]),mathmlPlot(children[[i+1]]), mathmlPlot(children[[i+2]])) expr <- c(expr, tmp) i <- i+2 } else { expr <- c(mathmlPlot(child), expr , mathmlPlot(children[[i+1]])) } mode(expr) <- "call" i <- i+1 } else { expr <- c(expr, mathmlPlot(child)) } i <- i+1 ok <- (i <= length(children)) #cat(i,length(children),"\n") } return(expr) } mathmlPlot.XMLEntityRef <- function(node) { nm <- xmlName(node) val <- switch(nm, PlusMinus=as.name("%+-%"), InvisibleTimes=as.name("*"), int=as.name("integral"), infty = as.name("infinity"), NULL ) if(is.null(val)) { val <- as.name(nm) } return(val) } mathmlPlot.XMLNode <- function(node) { nm <- name(node) if(nm == "mi" || nm == "ci") { val <- c(as.name("italic"),mathmlPlot(node$children)) mode(val) <- "call" } else if(nm == "msqrt") { val <- c(as.name("sqrt"), mathmlPlot(node$children)) mode(val) <- "call" } else if(nm == "msubsup") { tmp <- c(as.name("^"), mathmlPlot(node$children[[1]]),mathmlPlot(node$children[[2]])) mode(tmp) <- "call" val <- c(as.name("["), tmp, mathmlPlot(node$children[[3]])) mode(val) <- "call" } else if(nm == "mrow") { val <- mathmlPlot(node$children) } else if(nm == "text") { val <- node$value } else if(nm == "mo") { if(inherits(node$children[[1]],"XMLEntityRef")) val <- mathmlPlot(node$children[[1]]) else { op <- node$children[[1]]$value tmp <- switch(op, "=" = "==", op) val <- as.name(tmp) } } else if(nm == "mfrac") { val <- list(as.name("frac"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]])) mode(val) <- "call" } else if(nm == "msup" || nm == "msub") { op <- switch(nm, "msup" = "^", "msub"="[") val <- c(as.name(op), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]])) mode(val) <- "call" } else if(nm == "mn" || nm == "cn") { val <- as.numeric(node$children[[1]]$value) } else if(nm == "mstyle") { val <- mathmlPlot(node$children) } else if(nm == "munderover") { val <- mathmlPlot(node$children) } else if(nm == "mroot") { val <- c(as.name("sqrt"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]])) mode(val) <- "call" } else if(nm == "reln") { val <- mathmlPlot(node$children) mode(val) <- "call" } else if(nm == "eq") { val <- as.name("==") } else if(nm == "geq") { val <- as.name(">=") } else if(nm == "set") { # This looks for a tag and takes # everything before that as preceeding the `|' n <- min( (1:length(node$children))[sapply(node$children, xmlName) == "condition"]) cat("Condition @",n,"\n") args <- c(mathmlPlot(node$children[1:(n-1)]), "|", mathmlPlot(node$children[n:length(node$children)])) args <- c(as.name("paste"), args) mode(args) <- "call" val <- list(as.name("group"),"{", args,"}") mode(val) <- "call" } else if(nm == "bvar") { val <- mathmlPlot(node$children) } else if(nm == "condition") { val <- mathmlPlot(node$children) } else if(nm == "interval") { sep <- xmlAttrs(node)[["closure"]] sep <- switch(sep, open=c("(",")"), closed=c("[","]"), "closed-open"=c("[",")"), "open-closed"=c("(","]"), ) els <- mathmlPlot(node$children) els <- c(as.name("paste"), els[[1]],",",els[[2]]) mode(els) <- "call" val <- list(as.name("group"),sep[1], els ,sep[2]) mode(val) <- "call" } else if(nm == "power") { val <- c(as.name("^"), mathmlPlot(node$children[[1]]), mathmlPlot(node$children[[2]])) # mode(val) <- "call" } else if(nm == "plus") { val <- as.name("+") } else if(nm == "apply") { val <- mathmlPlot.apply(node) } return(val) } mathmlPlot.apply <- function(node) { sub <- mathmlPlot(node$children) nm <- xmlName(node$children[[1]]) print(node$children[[1]]) if(nm == "plus" || nm == "minus" || nm == "times" || nm == "div" ) { print(sub[[1]]) val <- c(mathmlPlot(node$children[[1]]), sub[[2]], sub[[3]]) mode(val) <- "call" for(i in 4:length(sub)) { tmp <- c(mathmlPlot(node$children[[1]]), val, sub[[i]]) mode(tmp) <- "call" val <- tmp } } else { val <- sub mode(val) <- "call" } return(val) } XML/inst/examples/createTree.R0000644000175100001440000000071313607633730015742 0ustar hornikusersdoc <- xmlTree() doc$addTag("EXAMPLE", close= FALSE, attrs=c("prop1" = "gnome is great", prop2 = "& linux too")) doc$addComment("A comment") doc$addTag("head", close= FALSE) doc$addTag("title", "Welcome to Gnome") doc$addTag("chapter", close= FALSE) doc$addTag("title", "The Linux Adventure") doc$addTag("p") doc$addTag("image", attrs=c(href="linux.gif")) doc$closeTag() doc$closeTag() doc$addTag("foot") doc$closeTag() XML/inst/examples/svg.R0000644000175100001440000000746313607633744014474 0ustar hornikusers# # An example of processing an SVG document # See the example in the parallel directory data/svg.xml. # # # xmlplot <- xmlTreeParse("data/svg.xml") # x11() # svgRender(xmlplot) # # See also: mathml.R # # # need support for the general SVG tags and attributes # desc # path # image # viewbox # stroke # transform matrix # svgRender <- function(doc) { UseMethod("svgRender",doc) } svgRender.default <- function(doc) { svgRender(doc$doc$children$svg) } svgRender.XMLNode <- # # This processes an XML node assumed to come from an # SVG document and either # a) renders the corresponding element # and potentially recursively operates on its children, or # b) stores the settings specified in a group tag ( or ) # for use in the processing of the sub-nodes. # # This has basic support for circles, rectangles, polygons, # text # function(top, settings = NULL) { if(is.null(settings)) { settings <- SVGSettings() } if(top$name == "svg") { dims <- top$attributes frame() par(usr=c(0, as.integer(dims[["width"]]) + 1, 0, as.integer(dims[["height"]])+1)) } else if(top$name == "g") { if(!is.na(match("style", names(top$attributes)))) { settings$fill <- properties(top$attributes[["style"]])[["fill"]] } } for(i in top$children) { if(class(i) == "XMLComment") next ats <- i$attributes if(i$name == "rect") { if(!is.na(match("style", names(ats)))) { col <- properties(ats[["style"]])[["fill"]] } else { col <- settings$fill } rect(as.integer(ats[["x"]]), as.integer(ats[["y"]]), as.integer(ats[["x"]]) + as.integer(ats[["width"]]), as.integer(ats[["y"]]) + as.integer(ats[["width"]]), col = col) } else if(i$name == "text") { # need to gather up all the children in case the text # is split into different components. val <- i$children[[1]]$value text(as.integer(ats[["x"]]), as.integer(ats[["y"]]), val, adj=1.0) } else if(i$name == "polygon") { # read the points attribute as a integer vector data <- scan.string(ats[["points"]]) idx <- seq(1,length(data), by=2) x <- data[idx] y <- data[idx+1] if(!is.na(match("style", names(ats)))) { col <- properties(ats[["style"]])[["fill"]] } else { col <- settings$fill } polygon(x,y, col) } else if(i$name == "ellipse") { if(!is.na(match("style", names(ats)))) { col <- properties(ats[["style"]])[["fill"]] } else { col <- settings$fill } r <- min(as.integer(ats[["rx"]]), as.integer(ats[["ry"]])) symbols(as.integer(ats[["cx"]]), as.integer(ats[["cy"]]), circles=as.integer(r),inches=F, add=T) } else if(i$name == "g") { svgRender(i, settings) } } invisible(return(T)) } SVGSettings <- # # This class of object is used for storing the # "global" or currently active settings for within # an SVG group. This includes things such as color # fill style and color, font, etc. function() { val <- list(fill=NULL, font=NULL, fg=NULL, bg=NULL) class(val) <- "SVGSettings" val } # # The following are very simple (inefficient and potentially inconsistent with R) # ways of manipulating strings. These would be implemented using textConnection # objects in S4. # scan.string <- function(data) { # This could use string split # strsplit(data, rx) cmd <- paste("perl -e '$x = join(\"\n\", split(/ /, $ARGV[0])); printf \"$x\n\";'", paste("'",data,"'", collapse="",sep="")) els <- system(cmd, intern=T) vals <- as.integer(sapply(els, as.integer)) return(vals) } properties <- function(str) { cmd <- paste("perl -e '$x = join(\"\n\", split(/ /, $ARGV[0])); printf \"$x\n\";'", paste("'",str,"'", collapse="",sep="")) els <- system(cmd, intern=T) idx <- seq(1,length(els), by=2) vals <- els[idx+1] names(vals) <- els[idx] return(vals) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML/inst/examples/namespaces.S����������������������������������������������������������������������0000644�0001751�0000144�00000001305�13607633730�015775� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ library(XML) gg <- xmlTree("abc", dtd = "ggobi.dtd", namespaces = list(ggobi="http://www.ggobi.org", r = "http://www.r-project.org")) gg$addTag("ggobidata", attrs = c(count=1), namespace = "ggobi", close = FALSE) gg$addTag("data", attrs = c(name="cube6"), close = FALSE) gg$addTag("description", "A simple dataset") gg$addTag("variables", attrs = c(count="2"), close = FALSE) gg$addTag("realvariable", attrs = c(name="D1"), namespace = "r") gg$addTag("realvariable", attrs = c(name="D2"), namespace = "r") gg$closeTag() # variables gg$closeTag() # data gg$closeTag() # ggobidata # or gg$closeTag(3) # or gg$closeTag("ggobidata") cat(saveXML(gg)) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML/inst/examples/rcode.xml�������������������������������������������������������������������������0000644�0001751�0000144�00000000212�13607633725�015350� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ x = 1:10 plot(x) sum(x) 55 ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML/inst/examples/sbml.xml��������������������������������������������������������������������������0000644�0001751�0000144�00000003164�13607633725�015222� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ aada ATP fada4 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML/inst/examples/internalNodes.S�������������������������������������������������������������������0000644�0001751�0000144�00000000310�13607633725�016462� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������library(XML) tr <- xmlTree("Duncan") tr$addTag("name", attrs=c(a=1,b="xyz"), close=FALSE) tr$addTag("first", "Larry") tr$addTag("last", "User") tr$closeTag() o = xmlRoot(tr$value()) as(o, "XMLNode") ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������XML/inst/examples/docbook.R�������������������������������������������������������������������������0000644�0001751�0000144�00000001676�13607633725�015314� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Find the elements used in the collection of chapters of the SVN book. # The approach works for any set of XML documents. # The SVN book can be downloaded from # http://svnbook.red-bean.com/trac/changeset/3082/tags/en-1.4-final/src/en/book?old_path=%2F&format=zip if(FALSE) { # Find the nodes and attributes used in the SVN book. files = list.files("SVN-book", "\\.xml$", full.names = TRUE) svn.book = xmlElementSummary(files) } if(FALSE) { # Process the XSL files in IDynDocs, OmegahatXSL and docbook-xsl h = xmlElementSummaryHandlers() dir = "~/Classes/StatComputing/XDynDocs/inst/XSL" invisible( lapply(c("", "OmegahatXSL", "docbook-xsl-1.73.2/html", "docbook-xsl-1.73.2/fo"), function(sub) { files = list.files(paste(dir, sub, sep = .Platform$file.sep), "\\.xsl$", full.names = TRUE) invisible(sapply(files, xmlEventParse, handlers = h, replaceEntities = FALSE)) })) h$result() } ������������������������������������������������������������������XML/inst/examples/mexico.xml������������������������������������������������������������������������0000644�0001751�0000144�00000001641�13607633725�015547� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ 57.9332 53.4599 54.8241 55.7852 55.008 54.9579 53.3819 54.1589 53.3658 58.4322 57.9332 53.4599 54.8241 55.7852 55.008 54.9579 53.3819 54.1589 53.3658 58.4322 24.9125 24.0581 24.9128 25.5737 24.4704 25.697 26.1449 25.9035 25.4705 24.0121 24.9125 24.0581 24.9128 25.5737 24.4704 25.697 26.1449 25.9035 25.4705 24.012 30.0 28.0 16.0 28.0 31.0 34.0 32.0 24.0 32.0 28.0 30.0 28.0 16.0 28.0 31.0 34.0 32.0 24.0 32.0 28.0 �����������������������������������������������������������������������������������������������XML/inst/examples/gettingStarted.html���������������������������������������������������������������0000644�0001751�0000144�00000034612�13607633725�017423� 0����������������������������������������������������������������������������������������������������ustar �hornik��������������������������users������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������


Abstract

The idea here is to provide simple examples of how to get started with processing XML in R using some reasonably straightforward "flat" XML files and not worrying about efficiency.

An Example: Grades

Here is an example of a simple file in XML containing grades for students for three different tests.

<?xml version="1.0" ?>
<TABLE>
   <GRADES>
      <STUDENT> Fred </STUDENT>
      <TEST1> 66 </TEST1>
      <TEST2> 80 </TEST2>
      <FINAL> 70 </FINAL>
   </GRADES>
   <GRADES>
      <STUDENT> Wilma </STUDENT>
      <TEST1> 97 </TEST1>
      <TEST2> 91 </TEST2>
      <FINAL> 98 </FINAL>
   </GRADES>
</TABLE>

We might want to turn this into a data frame in R with a row for each student and four variables, the name and the scores on the three tests.

Since this is a small file, let's not worry about efficiency in any way. We can read the entire document tree into memory and make multiple passes over it to get the information. Our first approach will be to read the XML into an R tree, i.e. R-level XML node objects. We do this with a simple call to xmlTreeParse() .

doc = xmlRoot(xmlTreeParse("generic_file.xml"))

We use xmlRoot() to get the top-level node of the tree rather than holding onto the general document information since we won't need it.

Since the structure of this file is just a list of elements under the root node, we need only process each of those nodes and turn them into something we want. The "easiest" way to apply the same function to each child of an XML node is with the xmlApply() function. What do we want to do for each of the <GRADES> node? We want to get the value, i.e. the simple text within the node, of each of its children. Since this is the same for each of the child nodes in <GRADES>, this is again another call to xmlApply() . And since this is all text, we can simplify the result and get back a character vector rather than a list by using xmlSApply() which will perform this extra simplication step.

So a function to do the initial processing of an individual <GRADES> node might be

 function(node) 
     xmlSApply(node, xmlValue)

since xmlValue() returns the text content within an XML node. Let's check that this does what we want by calling it on the first child of the root node.

 xmlSApply(doc[[1]], xmlValue)

And indeed it does.

So we can process all the <GRADES> nodes with the command

 tmp = xmlSApply(doc, function(x) xmlSApply(x, xmlValue))

The result is a character matrix in which the rows are the variables and the columns are the records. So let's transpose this.

 tmp = t(tmp)

Now, we have finished working with the XML; the rest is regular R programming.

 grades = as.data.frame(matrix(as.numeric(tmp[,-1]), 2))
 names(grades) = names(doc[[1]])[-1]
 grades$Student = tmp[,1]

There seems to be more messing about after we have got the values out of the XML file. There are several things that might seem more complex but that actually just move the work to different places, i.e. when we are traversing the XML tree.

Here's another alternative using XPath.

doc = xmlTreeParse("generic_file.xml", useInternal = TRUE)

ans = lapply(c("STUDENT", "TEST1", "TEST2", "FINAL"),
             function(var)
               unlist(xpathApply(doc, paste("//", var, sep = ""), xmlValue)))

And this gives us a list containing the variables with the values as character vectors.

as.data.frame(lapply(names(ans), 
                     function(x) if(x != "STUDENT") as.integer(x) else x ))

Another Example: Customer Information List

The second example is another list, this time of description of customers. The first two nodes in the document are shown below:


<dataroot xmlns:od="urn:schemas-microsoft-com:officedata">
<Customers>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
<ContactName>Maria Anders</ContactName>
<ContactTitle>Sales Representative</ContactTitle>
<Address>Obere Str. 57</Address>
<City>Berlin</City>
<PostalCode>12209</PostalCode>
<Country>Germany</Country>
<Phone>030-0074321</Phone>
<Fax>030-0076545</Fax>
</Customers>
<Customers>
<CustomerID>ANATR</CustomerID>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
<ContactName>Ana Trujillo</ContactName>
<ContactTitle>Owner</ContactTitle>
<Address>Avda. de la Constitución 2222</Address>
<City>México D.F.</City>
<PostalCode>05021</PostalCode>
<Country>Mexico</Country>
<Phone>(5) 555-4729</Phone>
<Fax>(5) 555-3745</Fax>
</Customers>
</dataroot>

We can quickly verify that all the nodes under the root are customers with the command

 doc = xmlRoot(xmlTreeParse("Cust-List.xml"))
 table(names(doc))

We see that these are all "Customers". We could further explore to see if each of these nodes has the same fields.

fields = xmlApply(doc, names)
table(sapply(fields, identical, fields[[1]]))

And the result indicates that about half of them are the same. Let's see how many unique field names there are:

 unique(unlist(fields))

This gives 10. And we can see how may fields are in each of the Customers nodes with

xmlSApply(doc, xmlSize)

So most of the nodes have most of the fields.

So let's think about a data frame. What we can do is treat each of the fields as having a simple string value. Then we can create a data frame with the 10 character columns and with NA values for each of the records. Thne we will fill this in record at a time.

ans = as.data.frame(replicate(10, character(xmlSize(doc))), 
                      stringsAsFactors = FALSE)
names(ans) = unique(unlist(fields))

Now that we have the skeleton of the answer, we can process each of the Customers nodes.

sapply(1:xmlSize(doc),
          function(i) {
             customer = doc[[i]] 
             ans[i, names(customer)] <<- xmlSApply(customer, xmlValue)
          })

Note that we used a global assignemnt in the function to change the ans in the global environment rather than the local version within the function call. Also, we loop over the indices of the nodes in the tree, i.e. use sapply(1:xmlSize(doc), ) rather than xmlSApply(doc, ) simply because we need to know which row to put the results for each node.

There are various other ways to process these two XML files. One is to use handler functions to process the internal nodes as they are being converted from C-level data structures to R objects in a call to xmlTreeParse() . This avoids multiple traversal of the tree but can seem a little indirect until you get the hang of it. And some transformations can be cumbersome using this approach as it is a bottom up transformation.

The event-driven parsing provided by xmlEventParse() is a SAX style approach. This is quite low level and used when reading the entire XML document into memory and then processing it is prohibitive, i.e. when the XML file is very, very large.

The use of XPath to perform queries and get subsets of nodes involves a) learning XPath and b) potentially multiple passes over the tree. If one has to do many queries, this can be slow overall eventhough each is very fast. However, if you know XPath or are happy to learn the basics, this can be quite convenient, avoiding having to write recursive functions to search for the nodes of interests. Using the internal nodes (as you must for XPath) also gives you the ability to go up the tree, i.e. find parent, ancestor and sibling nodes, and not just down to children. So we have more flexibility in how we traverse the tree.

XML/inst/examples/getElements.S0000644000175100001440000000163013607633744016140 0ustar hornikusersgetElements = function(elementNames) { els = list() startElement = function(node, ...) { if(xmlName(node) %in% elementNames) els[[length(els) + 1]] <<- node node } list(startElement = startElement, els = function() els) } # h = getElements("a") htmlTreeParse("http://www.omegahat.net/RSXML/index.html", handlers = h) links = sapply(h$els(), function(x) xmlGetAttr(x, "href")) # Of course, we could do these two steps in one with a handler # function like # getLinks = function() { links = character() list(a = function(x) links <<- c(links, xmlGetAttr(x, "href")), links = function() links) } # h = getLinks() # htmlTreeParse("http://www.omegahat.net/RSXML/index.html", handlers = h) # h$links() # If we want the nodes, we can use getElements. Otherwise, we # can use a specialize handler that converts the information on the # fly into the data structures we want at the end. XML/inst/examples/generic_file.xml0000644000175100001440000000050613607633725016675 0ustar hornikusers Fred 66 80 70 Wilma 97 91 98
XML/inst/examples/iTunes.plist0000644000175100001440000001452413607633725016071 0ustar hornikusers Major Version1 Minor Version1 Application Version7.5 Features1 Show Content Ratings Music Folderfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/ Library Persistent IDBD55EC2E7FDB1DAE Tracks 181 Track ID181 NameDon't Know Why ArtistNorah Jones ComposerJesse Harris AlbumCome Away With Me GenreJazz KindAAC audio file Size3031411 Total Time186152 Disc Number1 Disc Count1 Track Number1 Track Count14 Year2002 Date Modified2007-02-05T10:46:04Z Date Added2005-08-22T21:14:30Z Bit Rate128 Sample Rate44100 Play Count24 Play Date3274252284 Play Date UTC2007-10-02T21:31:24Z Persistent IDD7F9F158A4A48E53 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/01%20Don't%20Know%20Why.m4a File Folder Count-1 Library Folder Count-1 182 Track ID182 NameSeven Years ArtistNorah Jones ComposerLee Alexander AlbumCome Away With Me GenreJazz KindAAC audio file Size2376546 Total Time145262 Disc Number1 Disc Count1 Track Number2 Track Count14 Year2002 Date Modified2007-02-05T10:46:05Z Date Added2005-08-22T21:14:49Z Bit Rate128 Sample Rate44100 Play Count23 Play Date3274252429 Play Date UTC2007-10-02T21:33:49Z Persistent IDD7F9F158A4A48E54 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/02%20Seven%20Years.m4a File Folder Count-1 Library Folder Count-1 183 Track ID183 NameCold Cold Heart ArtistNorah Jones ComposerHank Williams AlbumCome Away With Me GenreJazz KindAAC audio file Size3551301 Total Time218591 Disc Number1 Disc Count1 Track Number3 Track Count14 Year2002 Date Modified2007-02-05T10:46:06Z Date Added2005-08-22T21:15:14Z Bit Rate128 Sample Rate44100 Play Count23 Play Date3274252647 Play Date UTC2007-10-02T21:37:27Z Persistent IDD7F9F158A4A48E58 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/03%20Cold%20Cold%20Heart.m4a File Folder Count4 Library Folder Count1 184 Track ID184 NameFeelin' The Same Way ArtistNorah Jones ComposerLee Alexander AlbumCome Away With Me GenreJazz KindAAC audio file Size2891062 Total Time177352 Disc Number1 Disc Count1 Track Number4 Track Count14 Year2002 Date Modified2007-02-05T10:46:07Z Date Added2005-08-22T21:15:32Z Bit Rate128 Sample Rate44100 Play Count24 Play Date3274252825 Play Date UTC2007-10-02T21:40:25Z Persistent IDD7F9F158A4A48E59 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/04%20Feelin'%20The%20Same%20Way.m4a File Folder Count-1 Library Folder Count-1 XML/inst/examples/writeExamples.S0000644000175100001440000000056313607633725016520 0ustar hornikusersfoo <- function(x= 10, b="asd") { if(x) 1 else if(T) 2 else 4 } bar <- function(x) { for(i in 1:length(x)) { print(x[[i]]) } return(T) } single <- function(x) T While <- function() { while(f(x)) { print(f(x)) break } repeat { x <- x + 1 break } } Logic <- function() { if(x < 1 && y > 10) { x | y & z } } XML/inst/examples/ecb.R0000644000175100001440000000224113607633730014406 0ustar hornikusers# Reading European bank exchange rates. history = "~/eurofxref-hist.xml" daily = "~/eurofxref-daily.xml" # f = "http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml" f = history d = xmlTreeParse(f, useInternalNodes = TRUE) getNodeSet(d, "/gesmes:Envelope//Cube[@currency='SIT']", c(gesmes="http://www.gesmes.org/xml/2002-08-01")) getNodeSet(d, "//gesmes:Envelope", c(gesmes="http://www.gesmes.org/xml/2002-08-01")) namespaces = c(ns = "http://www.ecb.int/vocabulary/2002-08-01/eurofxref") namespaces <- c(ns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref") # Get the data for Slovenian currency for all time periods. # Find all the nodes of the form slovenia = getNodeSet(d, "//ns:Cube[@currency='SIT']", namespaces ) # Now we have a list of such nodes, loop over them and get the rate # attribute rates = as.numeric( sapply(slovenia, xmlGetAttr, "rate") ) # Now put the date on each element # find nodes of the form # and extract the time attribute names(rates) = sapply(getNodeSet(d, "//ns:Cube[@time]", namespaces ), xmlGetAttr, "time") # Or we could turn these into dates with strptime(). XML/inst/examples/prompt.xml0000644000175100001440000000350513607633744015606 0ustar hornikusers prompt.xml prompt.xml ~~function to do ... ~~ ~~ A concise (1-5 lines) description of what the function does. ~~ prompt.xml object file NULL ... header footer object ~~Describe objecthere~~ file ~~Describe filehere~~ ... ~~Describe ...here~~ header ~~Describe headerhere~~ footer ~~Describe footerhere~~
~~ If necessary, more details than the __description__ above ~~
~Describe the value returned If it is a LIST, use \item{comp1 }{Description of `comp1'} \item{comp2 }{Description of `comp2'} ... http://www.omegahat.net Duncan Temple Lang x %sgets function(a=1, b=2, ...) { ..... }
XML/inst/examples/itunes.R0000644000175100001440000000443113607633725015173 0ustar hornikusers# convert i # xsltproc itunes.xsl ~/Music/iTunes/iTunes\ Music\ Library.xml > itunes.xml # or with Sxslt # # user system elapsed # 7.514 0.090 7.981 system.time({ library(Sxslt) doc = xsltApplyStyleSheet("~/itunes.xml", "~/Projects/org/omegahat/XML/RS/examples/itunes.xsl") top = xmlRoot(doc$doc) songs.xsl = xmlApply(top, function(x) xmlSApply(x, xmlValue)) }) ##################### # As tempting as it is to take the xmlRoot() in this next command, # that will allow the XML document to be freed and then a crash will ensue. doc = xmlInternalTreeParse("~/Projects/org/omegahat/XML/RS/examples/itunes.xml") # fields = unique(unlist(xmlApply(top, names))) songs = xmlApply(xmlRoot(doc), function(x) xmlSApply(x, xmlValue)) ######################## # Working form the original format of /plist/dict/dict/dict/ doc = xmlInternalTreeParse("~/itunes.xml") dicts = doc["/plist/dict/dict/dict"] transform = function(dict) { vals = xmlSApply(dict, xmlValue) i = seq(1, by = 2, length = length(vals)/2) structure(vals[i + 1], names = gsub(" ", "_", vals[i])) } songs = lapply(dicts, transform) # For reading, xpath and lapply() # user system elapsed # 6.784 0.073 7.153 ########################################## # distribution of bit rates for sampling of the sound. table(as.numeric(sapply(songs, "[[", "Bit_Rate"))) # How often each song was played. hist(as.numeric(sapply(songs, "[[", "Play_Count"))) # Number of songs on each album hist(table(sapply(songs, "[", "Album"))) # Year song was recorded (?) hist(as.numeric(sapply(songs, "[", "Year"))) # Song size hist(as.numeric(sapply(songs, "[", "Total_Time"))) # Album time album.time = tapply(songs, sapply(songs, "[", "Album"), function(x) sum(as.numeric(sapply(x, "[", "Total_Time"))/1000)) dateAdded = as.POSIXct(strptime(sapply(songs, "[", "Date_Added"), "%Y-%m-%dT%H:%M:%S")) #XXX hist(as.numeric(dateAdded)) # Artists with most songs sort(table(sapply(songs, "[", "Artist")), decreasing = TRUE)[1:40] # How many songs on single and double "albums" table(sapply(songs, "[", "Disc_Number")) table(sapply(songs, "[", "Kind")) table(sapply(songs, "[", "Genre")) # Check the sampling rate for points off the line. plot(as.numeric(sapply(songs, "[", "Total_Time")), as.numeric(sapply(songs, "[", "Size"))) XML/inst/examples/event.S0000644000175100001440000000714513607633725015013 0ustar hornikusers# # Code for reading Chris (Volinsky)'s event data from XML into a dataframe. # # # This is the top-level function that you call to read the file and convert it # into a data frame. # You can call the eventHandlers() function manually and pass the result # as the argument to the handlers argument if you want to override the # RowConverters or verbose argument. # readXMLEventDataFrame = function(fileName = "event.xml", handlers = eventHandlers(), ...) { xmlEventParse(fileName, handlers = handlers, ...)$result() } # # The verbose argument prints out information about the different # events the parser observes. # # RowConverters is a named list of functions that convert the specified/name # variable's values. # # In the current implementation, we first build up a matrix of strings # and then at the very end, we convert the columns to variables and # form a data.frame(). If we were smarter (i.e. could assume more), # we could create the data.frame() first and then add rows to it. # Ideally, the XML dataset would tell us the number of records # (i.e. elements) it contains and we could populate the # data.frame() from its "declared" types. # # eventHandlers = function(RowConverters = list(Date=I, f2 = as.integer, f3 = as.numeric), verbose = TRUE) { # dataset = data.frame() dataset = matrix("", 1, length(RowConverters), dimnames = list(NULL, names(RowConverters))) dataName = "" date = "" recordNum = 1 var = "" record <- character() textString <- character(0) # This is called when we encounter the start of an XML element/tag. # For , we grab the id and date and store them to name the # dataset. # For , we grab the name attribute and use that as the name # of the current variable when we get its value from the (end of the) text # start = function(name, atts) { if(name == "event") { dataName <<- atts[["id"]] date <<- atts[["date"]] if(verbose) cat("Data name", dataName, ", date", date, "\n", sep="") } else if(name == "feature") { var <<- atts[["name"]] if(verbose) cat("Variable", var, "\n") } } text = function(val) { # We should have a converter here to get the right type. if(var != "") { if(verbose) cat("Text", val, "\n") textString <<- c(textString, val) } } # this is called when we get the close of a tag (i.e. ) # In the case of a dialog, we assume we have the end of a record # and we put it into the dataset by adding the record/row. # In our case, record is a character vector with names. # This is a character vector. We'll convert the columns at the end. end = function(name) { if(name == "dialog") { dataset <<- rbind(dataset, record) recordNum <<- recordNum + 1 if(verbose) cat("Next record\n") } else if(name == "feature") record[var] <<- paste(textString, collapse="") textString <<- character(0) var <<- "" } # This handler is the one we call at the end to # post-process the result result = function() { dataset = dataset[-1,] ans = as.data.frame(lapply(names(RowConverters), function(x) RowConverters[[x]](dataset[,x]))) names(ans) = names(RowConverters) ans = list(ans) names(ans) = dataName ans } list(result = result, text = text, endElement = end, startElement = start) } # # # How to call: data is in the file named event.xml # # v = readXMLEventDataFrame()[[1]] # v # Date f2 f3 #1 2003-05-23 1 3 # 2 2003-05-24 17 24 # > sapply(v, class) # Date f2 f3 # "AsIs" "integer" "numeric" # > # XML/inst/examples/filterDataFrameEvent.R0000644000175100001440000000534213607633725017722 0ustar hornikusers# A closure for use with xmlEventParse # and for reading a data frame using the DatasetByRecord.dtd # DTD in $OMEGA_HOME/XML/DTDs. # To test # xmlEventParse("mtcars.xml", handler()) # dataFrameFilter <- function(desiredRowNames) { data <- NULL # Private or local variables used to store information across # method calls from the event parser numRecords <- 0 varNames <- NULL meta <- NULL currentRecord <- 0 expectingVariableName <- F rowNames <- NULL currentColumn <- 1 processRow <- T # read the attributes from the dataset dataset <- function(x, atts) { numRecords <<- length(desiredRowNames) # as.integer(atts[["numRecords"]]) # store these so that we can put these as attributes # on data when we create it. meta <<- atts } variables <- function(x, atts) { # From the DTD, we expect a count attribute telling us the number # of variables. #cat("Creating matrix",numRecords, as.integer(atts[["count"]]),"\n") data <<- matrix(0., numRecords, as.integer(atts[["count"]])) # set the XML attributes from the dataset element as R # attributes of the data. attributes(data) <<- c(attributes(data),meta) } # when we see the start of a variable tag, then we are expecting # its name next, so handle text accordingly. variable <- function(x,...) { expectingVariableName <<- T } record <- function(x,atts) { if(is.na(match(atts[["id"]], desiredRowNames))) { # discard this entry cat("Discarding", atts[["id"]],"\n") return() } processRow <<- T # advance the current record index. currentRecord <<- currentRecord + 1 rowNames <<- c(rowNames, atts[["id"]]) } text <- function(x,...) { if(x == "") return(NULL) if(expectingVariableName == FALSE && processRow == FALSE) { cat("Ignoring",x,"\n") return() } if(expectingVariableName) { varNames <<- c(varNames, x) if(length(varNames) >= ncol(data)) { expectingVariableName <<- F dimnames(data) <<- list(NULL, varNames) } } else { e <- gsub("[ \t]*",",",x) els <- strsplit(e,",")[[1]] for(i in els) { data[currentRecord, currentColumn] <<- as.numeric(i) currentColumn <<- currentColumn + 1 } } } endElement <- function(x,...) { if(x == "dataset") { dimnames(data)[[1]] <<- rowNames } else if(x == "record") { currentColumn <<- 1 } } return(list(variable = variable, variables = variables, dataset=dataset, text = text, record= record, endElement = endElement, data = function() {data }, rowNames = function() rowNames )) } XML/inst/examples/faq.R0000644000175100001440000000031013607633725014423 0ustar hornikusers# Getting the question text from a FAQ. doc = xmlParse("FAQ.xml") q = getNodeSet(doc, "//question") sapply(q, function(x) paste(sapply(xmlChildren(x)[names(x) == "text"], xmlValue), collapse = "\n")) XML/inst/examples/metlin.R0000644000175100001440000000125513607633725015155 0ustar hornikusersreadMetlin = function(url = "http://metlin.scripps.edu/download/MSMS_test.XML", what = c("molid" = "integer", name = "character", formula = "character", mass = "numeric", mz = "numeric")) { doc = xmlTreeParse(url, useInternal = TRUE) z = xmlChildren(xmlRoot(doc)) nodes = z[ sapply(z, inherits, "XMLInternalElementNode") ] if(length(nodes) > 1) { } nodes = nodes[[1]] n = xmlSize(nodes) ans = as.data.frame(lapply(what, function(x) get(x)(n))) for(i in 1:n) { node = nodes[[i]] sapply(names(what), function(id) { ans[i, id] <<- as(xmlValue(node[[id]]), what[id]) }) } ans } XML/inst/examples/pi.xml0000644000175100001440000000036313607633730014667 0ustar hornikusers Hello World XML/inst/examples/mathml.R0000644000175100001440000001072013607633725015144 0ustar hornikusers# # Functions to illustrate how to convert a MathML tree an # R expression. # # mathml <- # generic method that converts an XMLNode # object to an R/S expression. function(node) { UseMethod("mathml", node) } mathml.XMLDocument <- function(doc) { return(mathml(doc$doc$children)) } mathml.default <- # # Attempts to create an expression from the Math ML # document tree given to it. # This is an example using the mathml.xml and is not # in any way intended to be a general MathML "interpreter" # for R/S. # function(children) { expr <- list() for(i in children) { if(class(i) == "XMLComment") next expr <- c(expr, mathml(i)) } return(expr) } mergeMathML <- # # This takes a list of objects previously converted to R terms # from MathML and aggregates them by collapsing elements # such as # term operator term # into R calls. # # see mathml.XMLNode # function(els) { #cat("Merging",length(els)); #print(els) ans <- list() more <- T ctr <- 1 while(more) { i <- els[[ctr]] if(inherits(i, "MathMLOperator")) { ans <- c(i, ans, els[[ctr+1]]) mode(ans) <- "call" ctr <- ctr + 1 } else if(inherits(i,"MathMLGroup")) { #print("MathMLGroup") ans <- c(ans, i) mode(ans) <- "call" } else ans <- c(ans, i) ctr <- ctr + 1 more <- (ctr <= length(els)) } #cat("Merged: "); print(ans) return(ans) } mathml.XMLNode <- # # Interprets a MathML node and converts it # to an R expression term. This handles tags # such as mi, mo, mn, msup, mfrac, mrow, mfenced, # msqrt, mroot # # Other tags include: # msub # msubsup # munder # mover # munderover # mmultiscripts # # mtable # mtr # mtd # # set, interval, vector, matrix # cn # matrix, matrixrow # transpose # Attributes for mfenced: open, close "[" function(node) { nm <- name(node) if(nm == "msup" || nm == "mfrac") { op <- switch(nm, msup="^", mfrac="/") a <- mathml(node$children[[1]]) b <- mathml(node$children[[2]]) expr <- list(as.name(op), a, b) mode(expr) <- "call" val <- expr } else if(nm == "mi" || nm == "ci") { # display in italics if(!is.null(node$children[[1]]$value)) val <- as.name(node$children[[1]]$value) } else if(nm == "mo") { if(inherits(node$children[[1]],"XMLEntityRef")) { # node$children[[1]]$value val <- as.name("*") class(val) <- "MathMLOperator" } else { # operator tmp <- node$children[[1]]$value if(!is.null(tmp)) { if(tmp == "=") { # or we could use "==" # to indicate equality, not assignment. tmp <- "<-" } val <- as.name(tmp) class(val) <- "MathMLOperator" } } } else if(nm == "text") { val <- node$value } else if(nm == "matrix"){ val <- mathml.matrix(node) } else if(nm == "vector"){ val <- mathml.vector(node) } else if(nm == "mn" || nm == "cn") { # number tag. if(!is.null(node$children[[1]]$value)) val <- as.numeric(node$children[[1]]$value) } else if(nm == "mrow" || nm == "mfenced" || nm == "msqrt" || nm == "mroot") { # group of elements (displayed in a single row) ans <- vector("list", length(node$children)) ctr <- 1 for(i in node$children) { ans[[ctr]] <- mathml(i) #cat(ctr,i$name,length(ans),"\n") ctr <- ctr + 1 } ans <- mergeMathML(ans) # if this is an mfenced, msqrt or mroot element, add the # enclosing parentheses or function call. # .... if(nm == "msqrt") { ans <- c(as.name("sqrt"), ans) mode(ans) <- "call" } else if(nm == "mfenced") { class(ans) <- "MathMLGroup" } val <- ans } else if(nm == "reln") { val <- mathml(node$children) mode(val) <- "call" } else if(nm == "eq") { val <- as.name("==") } else if(nm == "apply") { val <- mathml(node$children) cat("apply:",length(val),"\n") print(val) mode(val) <- "call" } else if(nm == "times") { val <- as.name("%*%") } else if(nm == "transpose") { val <- as.name("t") } return(val) } mathml.matrix <- # # # # function(node) { m <- matrix(character(1), length(node$children), length(node$children[[1]]$children)) i <- 1 for(row in node$children) { j <- 1 for(cell in row$children) { tmp <- mathml(cell) m[i,j] <- as.character((tmp)) j <- j + 1 } i <- i + 1 } print(m) return(m) } mathml.vector <- function(node) { ans <- character(length(node$children)) for(i in 1:length(node$children)) { tmp <- mathml(node$children[[i]]) ans[i] <- as.character(tmp) } print(ans) return(ans) } XML/inst/examples/promptXML.R0000644000175100001440000000460213607633725015566 0ustar hornikusers# Requires xmlOutputBuffer prompt.xml <- function(object, file = NULL, ..., header='\n\n',footer="") { local <- list(...) name <- substitute(object) # Taken from prompt.default is.missing.arg <- function(arg) typeof(arg) == "symbol" && deparse(arg) == "" if (is.language(name) && !is.name(name)) name <- eval(name) name <- as.character(name) fn <- get(name) xml <- xmlOutputBuffer(nameSpace = "shelp") if(!is.null(header)) xml$add(header) xml$addTag("sname",name) xml$addTag("alias",name) xml$addTag("title"," ~~function to do ... ~~ ") xml$addTag("description","~~ A concise (1-5 lines) description of what the function does. ~~") xml$addTag("usage", close=F) # Now handle arguments and generate the call. s <- seq(length = n <- length(argls <- formals(fn))) if (n > 0) { arg.names <- names(argls) } xml$addTag("sname", name,sep="") for (i in s) { xml$addTag("arg", xml$tagString("argName", arg.names[i]), close=F) if(!is.missing.arg(argls[[i]])) { xml$addTag("defaultValue", deparse(argls[[i]]),sep="") } xml$closeTag("arg") if(i < n) xml$addTag("next") } xml$add("") xml$addTag("arguments", close=F) for(i in arg.names) { xml$addTag("argument", xml$tagString("argDescriptionName", i), "\n", "~~Describe ",i," here~~", "") } xml$add("") xml$addTag("details"," ~~ If necessary, more details than the __description__ above ~~") xml$addTag("value", "~Describe the value returned", " If it is a LIST, use", " \\item{comp1 }{Description of `comp1'}", " \\item{comp2 }{Description of `comp2'}", " ...") xml$addTag("references", ifelse(!is.null(local$references), local$references, "")) xml$addTag("author", ifelse(!is.null(local$author), local$author, "")) xml$addTag("note") xml$addTag("seeAlso", xml$tagString("a", attrs=list("href"="\"\""))) xml$addTag("examples", xml$tagString("example")) xml$addTag("keywords", xml$tagString("keyword")) if(!is.null(footer)) xml$add(footer) val <- xml$value() if(!missing(file)) cat(val, file=file) val } XML/inst/examples/xmlTags.xml0000644000175100001440000002011413607633744015677 0ustar hornikusers
Introduction This is a short document that does a quick empirical study of the use of Docbook and XSL elements and attribute in some actual uses of these. The idea is to give a sense of what are the most common elements in use and help people who are new to those technologies get a sense of what to focus on. This also illustrates how we can use the XML package in R to extract this information relatively easily and efficiently using the SAX parser.
Subversion Book This part finds the Docbook elements used in the collection of chapters of the SVN book. The SVN book can be downloaded from Unzip this and find the XML files in tags/en-1.4-final/src/en/book. (Before being able to process the files, you will have to make them readable as for some reason the permissions on all the files are all removed.)
We can look at one of the documents from the KDE documentation project and get the same information: xmlElementSummary("http://l10n.kde.org/docs/translation-howto//translation-howto.docbook") If we check out the documentation from the KDE SVN repository, we can examine those also. kde.files = list.files("~/Downloads/KDE-doc", "\\.docbook$", recursive = TRUE, full.names = TRUE) i = grep("/entities/|dolphin|man-template", kde.files) if(length(i)) kde.files = kde.files[ - i ] kde = xmlElementSummary(kde.files)
bazaar = xmlElementSummary("http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar.xml")
The book Dive into Python by Mark Pilgrim was written in Docbook and the Docbook files are available for download. You have to slightly change the file diveintopython.xml to define entities before you parse the file. Also, the author uses external entities to perform the includes and many of the XML files have more than one top-level node. This means that our SAX-based XML parser raises errors and so we cannot use the the xmlEventParse function that is key to our xmlElementSummary function. Instead, we what we do is to read the entire document into memory as a regular DOM. Then, we use a very general XPath query to get all nodes. And then we extract the names and attributes as we want. The code to do this is relatively straightforward: dive = xmlInternalTreeParse("~/Downloads/diveintopython-5.4/xml/diveintopython-orig.xml", replaceEntities = TRUE) nodes = getNodeSet(dive, "//*") nodeNames = sapply(nodes, xmlName, full = TRUE) nodeCounts = sort(table(nodeNames), decreasing = TRUE) attributes = tapply(nodes, nodeNames, function(nodes) table(unlist(lapply(nodes, function(node) { attrs = xmlAttrs(node) if(length(attrs)) names(attrs) else character() })))) list(nodeCounts = nodeCounts, attributes = attributes) Note that this code is also quite general and can be used on an single XML document. It does not use handlers and cannot be run across multiple separate XML documents with the built-in effect of cumulating the results. But it can be run separately on each file and the results aggregated quite easily.
XSL and Docbook In this part, we look at the XSL files in the IDynDocs package. These include our own XSL files for generating HTML, FO, LaTeX from our extended Docbook elements, as well as the docbook source for HTML, XHTML and FO. Instead of using xmlElementSummary, we use our own instance of the SAX handlers to collect the results. This could also be done by finding all the files first and then using xmlElementSummary. Or we could also perform the summaries on each directory to see how the usage change.
XPath What do we need to know about XPath? There are lots of good features of XPath, but the commonly used ones can be found perhaps by looking at the use in XSL documents. So again, we will look at those XSL files in XDynDocs, including the Docbook XSL files it contains. We define a function to collect all the XPath attributes we can easily identify within the nodes in the XSL document. These are mainly the test and select attributes. So all we need is a handler for the start of a generic element in the SAX parser and extract the test and select attributes. We may end up with non-XPath attributes, but for the moment, this is fine. Now we can use this function and extract the XPath expressions from the XSL files in XDynDocs. dir = "~/Classes/StatComputing/XDynDocs/inst/XSL" all.files = lapply(c(dir, paste(dir, c("OmegahatXSL", "docbook-xsl-1.73.2/html", "docbook-xsl-1.73.2/fo"), sep = .Platform$file.sep)), list.files, pattern = "\\.xsl$", full.names = TRUE) h = xpathExprCollector() invisible(lapply(unlist(all.files), xmlEventParse, h)) summary(h$result()) Now we have all the expressions, but there are too many of them. Somewhat remarkably, we can take a look at the top 40 in each and see the common patterns: the values of variables (e.g. $content) and XPath paths (e.g. info/subtitle) in select, and function calls and variable references in test. lapply(h$result(), "[", 1:40) To undertand these further, we have to parse the expressions and look at the types of expressions rather than the actual values. But this is more complex. We can find all XPath expressions that count for more than 1%, say, of all the XPath expressions in that group as simply as top = lapply(h$result(), function(x) x[x/sum(x) >= .01])
XML/inst/examples/DiGIR.R0000644000175100001440000000164413607633725014565 0ustar hornikuserslibrary(XML) url <- "http://iobis.marine.rutgers.edu/digir2/DiGIR.php" doc <- "
1.0.0 20030421T170441.431Z 127.0.0.1 http://localhost/digir/DiGIR.php inventory
true
" u = paste(url, paste("doc", doc, sep = "="), sep = "?") r = xmlTreeParse(u) # Alternatively, library(RCurl) txt = getForm(url, doc = doc) r = xmlTreeParse(txt, asText = TRUE) ####### r = xmlTreeParse(u, useInternal = TRUE) science.names = xpathSApply(r,"//x:record", xmlValue, namespaces = "x") XML/inst/examples/internalXInclude.xml0000644000175100001440000000106113607633744017530 0ustar hornikusers
This is the title
This section should have the same title as the article. y = 10*x + 3 + rnorm(length(x))
x = 1:10
XML/inst/examples/xml2tex.Sxml0000644000175100001440000000404013607633730016001 0ustar hornikusers ]> The functions in this file are an initial attempt to define some filters for an XML document to produce &Latex; output by translating the contents of the XML document. Note that using XSL is slightly problematic because the result needs to be a valid XML document, which no &Latex; document ever is. xml2tex function(node, mappings=.XMLTexMappings) { n &sgets; 10 x &sgets; print(x+10) x } cat("Got to here\n") xml2texUnderline function(node, tex) { } xml2texCode &sgets; function(node, tex) { } xxx seq(1,n) + 10 xml2tex.map &sgets; list("i"="textit", "b"="textbf", "sfunction"="SFunction", "item"="item", "label"=c("[", "]"), "cite"=function(x) { paste("\cite{", xmlAttrs(x)["id"], "}", collapse="")}, "bibitem"="", "bibliography"="" ) mapXML2TeX function(node, attr) { name &sgets; xmlName(node) el &sgets; xml2tex.map[[name]] if(!is.null(el)) { if(mode(el) == "character") { } else if(mode(el) == "function") { el(node) } } } XML/inst/examples/itunesSax2.R0000644000175100001440000000116613607633725015733 0ustar hornikusers# This version works on the generic plist form # We want the dict/dict/dict depth = 0 count = 0 songs = vector("list", 1300) songNode = function(parser, node) { count <<- count + 1 songs[[count]] <<- node } class(songNode) = c("XMLParserContextFunction", "SAXBranchFunction") dict = function(parser, node, ...) { print(depth) if(depth == 2) { # return the songNode function so that it will be used as a branch # function for this node, i.e. will be invoked return(songNode) } else depth <<- depth + 1 TRUE } xmlEventParse("~/itunes.xml", handlers = list(dict = dict), saxVersion = 2L) XML/inst/examples/SSource.dtd0000644000175100001440000000260313607633725015620 0ustar hornikusers XML/inst/examples/RhelpInfo.xml0000644000175100001440000000041113607633725016143 0ustar hornikusers Omegahat The libxml2 library Duncan Temple Lang duncan@wald.ucdavis.edu XML/inst/examples/itunesSax1.R0000644000175100001440000000076113607633725015732 0ustar hornikusers# This works on the transformed version that has # the value form # rather than the generic # name12.... # for of a property/p list. # count = 0 songs = vector("list", 100) song = function(parser, node, ...) { count <<- count + 1 if(count == length(songs)) xmlStopParser(parser) songs[[count]] <<- node TRUE } class(song) = "XMLParserContextFunction" xmlEventParse("itunes.xml", branches = list(song = song)) XML/inst/examples/mi1.R0000644000175100001440000000024313607633744014350 0ustar hornikuserssystem.time(z <- xmlTreeParse("~/mi1.xml", useInternal = TRUE)) nn = getNodeSet(z, "/*/molecule/name") length(nn) ids = sapply(nn,function(x) xmlValue(x[[1]])) XML/inst/examples/index.html0000644000175100001440000000452413607633725015541 0ustar hornikusers XML Package for R and S-Plus

An XML package for the S language

Source: XML_0.97-0.tar.gz

Windows binary: XML_0.97-0.zip

Last Release: Thu Aug 12 07:56:21 PDT 2004

This package provides facilities for the S language to

  • parse XML files, URLs and strings, using either the DOM (Document Object Model)/tree-based approach, or the event-driven SAX (Simple API for XML) mechanism;
  • generate XML content to buffers, files, URLs, and internal XML trees;
  • read DTDs as S objects.
The package supports both R and S-Plus 5 and higher.

NOTE

The most significant visible changes to the package include:
  • uses libxml2, by default and only libxml(version 1) if libxml2 is not present
  • uses a namespace for R.

Download

The source for the S package can be downloaded as XML_0.97-0.tar.gz.

Latest windows binary: XML_0.97-0.zip

Note that this latest version has not been tested with S-Plus Specifically, it should work as before, however the state mechanism for the SAX parser may not. This just requires testing.

Documentation

  • A reasonably detailed overview of the package and what we might use XML for.
  • A manual in and a quick guide to the package (PDF).
    b
  • A short overview of the package.
  • Brief and incomplete Notes on generating XML within S
  • FAQ for the package.
  • Changes to the packages (by release).

  • Duncan Temple Lang <duncan@wald.ucdavis.edu>
    Last modified: Fri Apr 1 04:32:29 PST 2005 XML/inst/examples/schemaEg.xml0000644000175100001440000000050313607633730015767 0ustar hornikusers Bog Hopper Wee Beastie Count Zero XML/inst/examples/RhelpArchive.xml0000644000175100001440000000160213607633725016634 0ustar hornikusers Some general references that apply to all. Function 1 details about parameter named "a" Function 2 XML/inst/examples/createTree1.R0000644000175100001440000000043713607633725016032 0ustar hornikuserstr <- xmlTree("Duncan") tr$addTag("name", attrs=c(a=1,b="xyz"), close=F) tr$addTag("first", "Duncan") tr$addTag("last", "Temple Lang") tr$closeTag() tr$value() cat(saveXML(tr$value())) # # DuncanTemple Lang XML/inst/examples/hashTree.R0000644000175100001440000000045613607633744015433 0ustar hornikusers tt = xmlHashTree() top = addNode("top", , tt) addNode(xmlNode("a"), top, tt) b = addNode(xmlNode("b"), top, tt) c = addNode(xmlNode("c"), b, tt) addNode(xmlNode("c"), top, tt) addNode(xmlNode("c"), b, tt) addNode(xmlTextNode("Some text"), c, tt) xmlElementsByTagName(tt$top, "c") XML/inst/examples/schemas.xml0000644000175100001440000000033213607633725015702 0ustar hornikusers XML/inst/examples/CIS.R0000644000175100001440000000272713607633730014304 0ustar hornikusersrequire(RCurl) require(XML) #myCurl = getCurlHandle() #getURL("http://www.statindex.org/CIS/psqlQuery/", cookiejar = "-", curl = myCurl) #.opts = list(cookie = '_ZopeId="19324353A25Uc.N15jM"', verbose = TRUE)) mycookie <- '_ZopeId="19324353A25Uc.N15jM"' CISQuery <- function(author = "Ihaka", title = "", keyword = "", journal = "", yearbeg = "", yearend = "", format = "bib", url = "http://www.statindex.org/CIS/psqlQuery/Searcher", cookie=mycookie){ v <- postForm(url, skip = "+", authed = "+", authed = "a", authorstring = author, titlestring = title, keywordstring = keyword, jnt = "jp", jnamestring = journal, pt= "+", pt = "b", pt = "j", pt = "p", pt = "+", yearbeg = yearbeg, yearend = yearend, startDisplay = "1", endDisplay = "50", fmt = format, .opts = list(cookie = cookie, verbose = TRUE)) browser() g <- htmlTreeParse(v,asText = TRUE) h <- g$children$html[["body"]] uh <- unlist(h) ugh <- uh[grep("not an authenticated user",uh)] if(length(ugh)>0) stop("Not an authenticated CIS user") h <- h[["pre"]][["text"]] i <- unlist(strsplit(h$value,"@"))[-1] j <- gsub("\n+$","",i) k <- gsub("^","@",j) l <- sapply(k, function(x) strsplit(x,"\n"),USE.NAMES = FALSE) lapply(l,function(x) {x; class(x) <- "Bibtex"; x}) } f <- CISQuery(cookie=mycookie) XML/inst/examples/Rhelp.xml0000644000175100001440000000064613607633725015341 0ustar hornikusers An example This is a longer description of the function XML/inst/examples/catalog.R0000644000175100001440000000077613607633725015306 0ustar hornikusers# Examples of manipulating the catalog for resolving URIs. # Get this from catalog.xml catalogResolve("http://www.omegahat.net/XSL/") loadCatalogs("~/Classes/StatComputing/XDynDocs/inst/XML/catalog.xml") # Found in the first/original catalog, not IDynDocs. catalogResolve("http://docbook.sourceforge.net/release/xsl/current/foo") catalogResolve("http://www.statdocs.org/foo") catalogAdd(c("http://www.r-project.org/XSL/" = "/Users/duncan/R/XSL")) catalogResolve("http://www.r-project.org/XSL/bob.xsl") XML/inst/examples/reorder.xml0000644000175100001440000000061213607633730015716 0ustar hornikusers doc = xmlInternalTreeParse("examples/reorder.xml") bs = getNodeSet(doc, "//b") length(bs) # [1] 4 xmlName(xmlRoot(doc)[[1]]) # [1] "a" a = xmlRoot(doc)[[1]] addChildren(a, kids = bs) saveXML(doc) addChildren(a, kids = bs, at = 0) XML/inst/examples/dataFrameEvent.R0000644000175100001440000000462213607633725016554 0ustar hornikusers# A closure for use with xmlEventParse # and for reading a data frame using the DatasetByRecord.dtd # DTD in $OMEGA_HOME/XML/DTDs. # To test # xmlEventParse("mtcars.xml", handler()) # handler <- function() { data <- NULL # Private or local variables used to store information across # method calls from the event parser numRecords <- 0 varNames <- NULL meta <- NULL currentRecord <- 0 expectingVariableName <- F rowNames <- NULL currentColumn <- 1 # read the attributes from the dataset dataset <- function(x, atts) { numRecords <<- as.integer(atts[["numRecords"]]) # store these so that we can put these as attributes # on data when we create it. meta <<- atts } variables <- function(x, atts) { # From the DTD, we expect a count attribute telling us the number # of variables. #cat("Creating matrix",numRecords, as.integer(atts[["count"]]),"\n") data <<- matrix(0., numRecords, as.integer(atts[["count"]])) # set the XML attributes from the dataset element as R # attributes of the data. attributes(data) <<- c(attributes(data),meta) } # when we see the start of a variable tag, then we are expecting # its name next, so handle text accordingly. variable <- function(x,...) { expectingVariableName <<- T } record <- function(x,atts) { # advance the current record index. currentRecord <<- currentRecord + 1 rowNames <<- c(rowNames, atts[["id"]]) } text <- function(x,...) { if(x == "") return(NULL) if(expectingVariableName) { varNames <<- c(varNames, x) if(length(varNames) >= ncol(data)) { expectingVariableName <<- F dimnames(data) <<- list(NULL, varNames) } } else { e <- gsub("[ \t]*",",",x) els <- strsplit(e,",")[[1]] for(i in els) { data[currentRecord, currentColumn] <<- as.numeric(i) currentColumn <<- currentColumn + 1 } } } endElement <- function(x,...) { if(x == "dataset") { dimnames(data)[[1]] <<- rowNames } else if(x == "record") { currentColumn <<- 1 } } return(list(variable = variable, variables = variables, dataset=dataset, text = text, record= record, endElement = endElement, data = function() {data }, rowNames = function() rowNames )) } XML/inst/examples/xpath.R0000644000175100001440000000132013607633730014776 0ustar hornikusersxpathExprCollector = function(targetAttributes = c("test", "select")) { # Collect a list of attributes for each element. tags = list() # frequency table for the element names counts = integer() start = function(name, attrs, ...) { attrs = attrs[ names(attrs) %in% targetAttributes ] if(length(attrs) == 0) return(TRUE) tags[names(attrs)] <<- lapply(names(attrs), function(id) c(tags[[id]] , attrs[id])) } list(.startElement = start, .getEntity = function(x, ...) "xxx", .getParameterEntity = function(x, ...) "xxx", result = function() lapply(tags, function(x) sort(table(x), decreasing = TRUE))) } XML/inst/examples/enhancedDataFrame.R0000644000175100001440000000376313607633725017205 0ustar hornikusers handler <- function() { data <- NULL # Private or local variables used to store information across # method calls from the event parser numRecords <- 0 varNames <- NULL meta <- NULL currentRecord <- 0 expectingVariableName <- F rowNames <- NULL # read the attributes from the dataset dataset <- function(x,atts) { numRecords <<- as.integer(atts[["numRecords"]]) # store these so that we can put these as attributes # on data when we create it. meta <<- atts } variables <- function(x, atts) { # From the DTD, we expect a count attribute telling us the number # of variables. data <<- matrix(0., numRecords, as.integer(atts[["count"]])) # set the XML attributes from the dataset element as R # attributes of the data. attributes(data) <<- c(attributes(data),meta) } # when we see the start of a variable tag, then we are expecting # its name next, so handle text accordingly. variable <- function(x,...) { expectingVariableName <<- T } record <- function(x,atts) { # advance the current record index. currentRecord <<- currentRecord + 1 rowNames <<- c(rowNames, atts[["id"]]) } text <- function(x,...) { if(x == "") return(NULL) if(expectingVariableName) { varNames <<- c(varNames, x) if(length(varNames) >= ncol(data)) { expectingVariableName <<- F dimnames(data) <<- list(NULL, varNames) } } else { e <- gsub("[ \t]*",",",x) vals <- sapply(strsplit(e,",")[[1]], as.numeric) data[currentRecord,] <<- vals } } endElement <- function(x,...) { if(x == "dataset") { dimnames(data)[[1]] <<- rowNames } } return(list(variable = variable, variables = variables, dataset=dataset, text = text, record= record, endElement = endElement, data = function() {data }, rowNames = function() rowNames )) } XML/inst/examples/tags.Sxml0000644000175100001440000000246513607633725015351 0ustar hornikusers ]> This file defines some S functions for computing information about an XML tree. We start by defining a recursive function that computes the list of unique tags within a document. This is useful for defining translations from these tags to another format, e.g. &TeX;. This identifies the names of the tags that one has to map to the TeX macros or environments. xmlTags function(node, exclude=c("XMLEntityRef")) { if(inherits(node, exclude)) { return(character(0)) } if(xmlSize(node) > 0) { which &sgets; xmlSApply(node, function(x, excludes) !inherits(x, excludes), excludes = exclude) vals &sgets; names(node)[which] vals &sgets; unique(c(vals, unlist(sapply(xmlChildren(node)[which], xmlTags, exclude )))) } else vals &sgets; character(0) vals } XML/inst/examples/xpath.xml0000644000175100001440000000021213607633730015374 0ustar hornikusers Some text Other text More text XML/inst/examples/bondsTables.R0000644000175100001440000000156613607633730016126 0ustar hornikuserslibrary(XML) doc = htmlTreeParse("http://finance.yahoo.com/bonds/composite_bond_rates?bypass=true", useInternalNodes = TRUE) # Use XPath expression to find the nodes #
    .. # as these are the ones we want. o = getNodeSet(doc, "//div/table[@class='yfirttbl']") # Write a function that will extract the information out of a given table node. readHTMLTable = function(tb) { # get the header information. colNames = sapply(tb[["thead"]][["tr"]]["th"], xmlValue) vals = sapply(tb[["tbody"]]["tr"], function(x) sapply(x["td"], xmlValue)) matrix(as.numeric(vals[-1,]), nrow = ncol(vals), dimnames = list(vals[1,], colNames[-1]), byrow = TRUE ) } # Now process each of the table nodes in the o list. tables = lapply(o, readHTMLTable) names(tables) = lapply(o, function(x) xmlValue(x[["caption"]])) XML/inst/examples/genericHandlers.R0000644000175100001440000000145713607633725016766 0ustar hornikusers# This illustrates using the new naming scheme for generic handlers # that use a . prefix. h = list(.text = function(content) cat("text:", xmlValue(content), "\n"), .comment = function(node) cat("##", xmlValue(node), "\n"), .processingInstruction = function(target, content) cat("PI: [", target, "]", content, "\n"), .startElement = function(node, attrs) { cat("New node:", xmlName(node), paste(names(xmlAttrs(node)), collapse = ", "), "\n")}, .endElement = function(node) { cat("end node:", node, "\n")}, .startDocument = function(...) cat("start of document\n"), .endDocument = function(...) cat("end of document\n"), .cdata = function(node) cat("CDATA:", xmlValue(node), "\n") ) xmlTreeParse("test.xml", handlers = h, asTree = TRUE, useDotNames = TRUE) XML/inst/FAQ.html0000644000175100001440000003207013607643014013210 0ustar hornikusersFAQ for the XML package in R/S-Plus

    FAQ for the XML package in R/S-Plus

  • I have compiled the package from source and everything goes fine, but when I try to load it, I get an error about an "undefined symbol xmlOutputBufferCreateBuffer". What's the problem?
    The most obvious explanation is that you are compiling against one version of libxml2 but loading another. Here is the explanation I gave to several people.
    That particular routine is either "borrowed" from libxml2.so or if not available from that, a compiled copy I added to the XML source is used. So it looks like the configuration is smart enough not to compile the one we provide because xmlOutputBufferCreateBuffer() is available in libxml2-2.6.32, but then it fails to find it at load time.

    So the first thing that comes to mind is that there is some inconsistency between your compile/link configuration and your run-time load configuration. Is it possible that you have an older version of libxml2...so somewhere on your system that is being loaded at run time Try the shell command

    R CMD ldd /libs/XML.so
    
    and see where it thinks libxml2 is. Hopefully it will list it and we might see that it is /usr/lib/libxml2.so and that you are compiling against a version in /usr/local/lib/. If that is the case, you would need to change your personal setting for LD_LIBRARY_PATH or add /usr/local/lib to /etc/ld.so.conf file at a system level.
  • How do I create my own XML content from within R and not just parse other people's XML documents?
    There are several facilities for doing this in the XML package. Basically you will be creating a tree, a hierarchical collection of XML nodes. So you need to be able to create the nodes and then arrange them into this hierarachical structure. You can create all the nodes and then do the tree construction but it is typically easier to create the nodes and specify its parent during the creation. The XML package provides low-level functions for creating the nodes and several functions which provide a higher level interface that try to facilitate adding nodes to a 'current' point in the tree. These manage the notion of 'current' for you. These functions share a very similar interface and so it is easy to switch from one to the other. They differ in how they represent the tree which can be complicated in R since there are no references/pointers.

    The approach I prefer is the xmlTree() function. This uses the low-level node creation functions (e.g. newXMLNode, newXMLComment, newXMLPINode, etc.) but also allows us to manage a stack of "open" nodes and a default namespace prefix. New nodes are by default added to the most recent "open" node, i.e. that node acts as the parent for new nodes.

  • Doesn't the use of internal nodes such as with xmlTree() mean that we cannot store the tree across R sessions since they are external pointers to C data structures in memory.
    Well, yes and no. We cannot use R's regular serialization to RDA files of the variables holding the tree or the individual nodes. But we can easily create a text representation from the internal nodes by dumping the tree, either to a file or a character vector of length 1, and then we can restore that XML tree by parsing it again:
       tt = xmlTree("top")
       tt$addTag("b", "Some text")
       save(saveXML(tt), file = "tt.rda")
       load("tt.rda")
       tt = xmlTreeParse(tt, asText = TRUE, useInternal = TRUE)
    
    We don't get back the XMLInternalDOM with information about open nodes, etc. from which we could continue to add nodes. But we do get back the exact tree.

    We can also convert the nodes from internal nodes to regular R base nodes. And from that

  • My XML document has attributes that have a namespace prefix (e.g. <node mine:foo="abc" /> ) When I parse this document into S, the namespace prefix on the attribute is dropped. Why and how can I fix it?
    The first thing to do is use a value of TRUE for the addAttributeNamespaces argument in the call to xmlTreeParse.
    The next thing is to ensure that the namespace (mine, in our example) is defined in the document. In other words, there must be be an xmlns:mine="some url" attribute in some node before or in the node that is being processed. If no definition for the namespace is in the document, the libxml parser drops the prefix on the attribute.
    The same applies to namespaces for node names, and not just attributes.
  • I define a method in the closure, but it never gets called.
    The most likely cause is that you omitted to add it to the list of functions returned by the closure. Another possibility is that you have mis-spelled the name of the method. The matching is case-sensitive and exact. If the function corresponds to a particular XML element name, check whether the value of the argument useTagName is T, and also that there really is a tag with this name in the document. Again, the case is important.
  • When I compile the source code, I get lots of warning messages such as
    "RSDTD.c", line 110: warning: argument #2 is incompatible with prototype:
            prototype: pointer to const uchar : "unknown", line 0
            argument : pointer to const char   
          
    This is because the XML libraries work on unsigned characters for UniCode. The R and S facilities do not. I am not yet certain which direction to adapt things for this package. The warnings are typically harmless.
  • When I compile the chapter for Splus5/S4, I get warning messages about SET_CLASS being redefined.
    This is ok, in this situation. The warning is left there to remind people that there are some games being played and that if there are problems, to consider these warnings. The SET_CLASS macro being redefined is a local version for S3/R style classes. The one in the Splus5/S4 header files is for the S4 style classes.
  • On which platfforms does it compile?
    I have used gcc on both Linux (RedHat 6.1) (egcs-2.91.66) and Solaris (gcc-2.7.2.3), and the Sun compilers, cc 4.2 on Solaris 2.6/SunOS 5.6 and cc 5.0 on Solaris 2.7/SunOS 5.7.
  • I can't seem to use conditional DTD segments via the IGNORE/INCLUDE mechanism.
    Libxml doesn't support this. Perhaps we will add code for this.

    Daneil Veillard might add this.

  • When I read a relatively simple tree in Splus5 and print it to the terminal/console, I get an error about nested expressions exceeding the limit of 256.
    The simple fix is to set the value of the expressions option to a value larger than 256.
     options(expressions=1000)
    
    The main cause of this is that S and R are programming languages not specialized for handling trees. (They are functional languages and have no facilities for pointers or references as in C or Java.)
  • I get errors when using parameter entities in DTDs?
    This was true in version 1.7.3 and 1.8.2 of libxml. Thanks to Daneil Veillard for fixing this quickly when I pointed it out.

    Parameters are allowed, but the libxml parsing library is fussy about white-space, etc. The following is is ok

    <!ELEMENT legend  (%PlotPrimitives;)* >
    
    but
    <!ELEMENT legend  (%PlotPrimitives; )* >
    
    is not. The extra space preceeding the ) causes an error in the parser something like
    1: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementChildrenContentDecl : ',' '|' or ')' expected 
    2: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementChildrenContentDecl : ',' expected 
    3: XML Parsing Error: ../Histogram.dtd:80: xmlParseElementDecl: expected '>' at the end 
    4: XML Parsing Error: ../Histogram.dtd:80: Extra content at the end of the document 
    
    This can be fixed by adding a call to SKIP_BLANKS at the end of the loop while(CUR!= ')' { ... } in the routine xmlParseElementChildrenContentDecl() in parser.c The problem lies in the transition between the different input buffers introduced by the entity expansion.
  • I am trying to use XPath and getNodeSet(). But I am not matching any nodes.
    If you are certain that the XPath expression should match what you want, then it is probably a matter of namespaces. If the document in which you are trying to find the nodes has a default namespace (at the top-level node or a sub-node involved in your match), then you have to explicitly identify the namespace. Unfortunately, XPath doesn't use the default namespace of the target document, but requires the namespace to be explicitly mentioned in the XPath expression.

    For example, suppose we have a document that looks like

    
         My Title
           
    ]]>
    
    and we want to use an XPath expression to find the title node. We might think that "/doc/topic/title" would do the trick. But in fact, we need
      /ns:doc/ns:topci/ns:title    
    
    And then we need to map ns to the URI "http://www.omegahat.net". We do this in a call to getNodeSet() as
      getNodeSet(doc, "/ns:doc/ns:topci/ns:title", c(ns = "http://www.omegahat.net"))
    

    As a simplification, getNodeSet() will create the map between the prefix and the URI of the default namespace of the XML document if you specify a single string with no name as the value of the namespaces argument, e.g.

      getNodeSet(doc, "/ns:doc/ns:topci/ns:title", "ns")
    

    There are some additional comments here.

  • There is an table of data in HTML that I want to read into R as a data frame. How can I do it?
    Well, it is relatively easy, although the technology underlying it is quite powerful and somewhat complex in the general case. There is a document describing the approach(es)
  • I have a "large" XML file. Can I use DOM parsing or do I have to use SAX style parsing via the more complex xmlEventParse().
    Well, I was given a 70 Mb XML file (which when compressed is 6MB) and after uncompressing the file, I can read it into R via xmlTreeParse(, useInternalTrue = TRUE) This file contained 2,895,409 nodes (length(getNodeSet(z, "//*"))) This took 9.4 seconds on Intel MacBook Pro with a 2.33Ghz Dual processor and 3G of RAM, and on a machine with dual core 64bit AMD, it took 20 seconds. To find the nodes of interest took 8.9 seconds on the Mac, and (apparently) 1.1 seconds on the AMD.
  • I want to include one document inside another. How can I do this?
    Firstly, you want to look into XInclude. When processing the document in R, use xinclude = TRUE, which is the default, in calls to xmlTreeParse().
  • I want to use XInclude to include part of the same document. I can't figure out how to do it. Any ideas?
    Yes. Use
     <xi:include xpointer="xpointer(//mynode)"/>
    
    adapting that to what you want. Note that the attribute is named xpointer. There is no href so the XInclude defaults to this document and the expression for the xpointer attribute uses the function xpointer. This is not element.
  • When I parse HTML content, what does the &nbsp; entity turn into?
    This turns into the Unicode character U+00A0, or in R "\u00A0".

  • Duncan Temple Lang <duncan@wald.ucdavis.edu>
    Last modified: Fri Dec 14 04:29:02 PST 2012 XML/inst/exampleData/0000755000175100001440000000000013607633725014146 5ustar hornikusersXML/inst/exampleData/nodes1.xml0000644000175100001440000000027613607633725016066 0ustar hornikusers XML/inst/exampleData/xyz.svg.gz0000644000175100001440000027357713607633725016165 0ustar hornikusers‹Á¢Kxyz.svgì½[¯åH’¥÷®_q @ÉâÅy«éÔ:€žb=H/zëéÎÊLuNU¡.ÓUúõr'ÝÌÖr#÷‰ŒÓÖµ:ã«ÃEÒ¶ÓÝÜ|Ñùÿå/ÿý§—ÿñÝþøãï~û퇡ë?¼|÷ÛþÝ¿üøÛï¿ýðÿ_ÿÇ7Û‡ÿò¿ýOÿøÇÿñýKþËßþñÛ?üéO¿ÿõ¯~õoÿöoÝ¿MÝïþðý¯Æ¾ï•ÿâÃù'¿þËO?þö_½?ö}ÿÕñ¿~xù·ÿåO?|ûaîÓïÿôáå‡ï~üþ‡?é?ÿÇßýÛÿþ»¿|û¡é_2+ÿï^æð!_Ô¿|÷›?æÿó}¹¾¿þ÷ÿö»Ÿ^~—ÿä7?ýîß¾ýð?~üãÿí§ï>¼üø/ß~øþ§¿þþ‡ñ›¾ôûúÓ/üÓ_úîÛüÓ~÷¯ßýúå·¿ûíwÿùÃKþË¿Êò«SíQÙáçeÿëË7c·§!õËË7}7¯ý4Œ/_¾™ºiÚ·”€¾tÝöóo÷4šYšÖù囡ûò‡…Ì㔦­°ižÓ²ŸÇ.ý^ÿrî§Ceê¶a9Î=t˰[>&uô¬Ã~°ý¸²HÇnè‡y)WÙ·ÿÊÊiÙò9>â})ý^üûýœàŽ7_v‰E:n¦—PÍ—ŸJK(öq_JÆ®v>"»mã6´®GD8Ê!ùNæ3âc·¬çÁS×ÏýzÓocý=*{=b1ì3ÑÌì˜ýTæSŸìµP»îò»æÿ=£aª×X~‡Ü2Âá„Eíüéò•»;Ï;Os†å¿êÍçÝr[, ªïÆíüßsÓ*ÿóqô°ÍjßÇ£ UòZ.*-©6ãó¯Æn[‡~?Ș–ã¿&mº}WZÙV½Mó~žuÞ×¥œϾÄlt㣡- Äq§¯LíJÒÖ1)?šœsÇ㜣\çqô^ž¢ãwÉmx@v³Ky†m\åföéü)úÚ|ŽxÉojOßÐÉó¸êóVo>ÿùqo¥-Á?ÛÊЭöÌ ãÙ®éN´ ž´Í)­ÚÀÇúÐ執>V¥KgSÇ£åʃ"]‚²Ú7ZËïk³’F§LîXWiâcw¤Ö!(_dý¯Òvk+«Š‘Úª_‘Mµ•NÒ?––Tîç8rÜj“«#ÐyÅu\Ë q‘ÓËoi^ºã^FÌLÇíxœž<Êç゚ÿUb ÝŠ´”|‰µ1[1ÉÃW~øáü¯Ü½Õv4h'ŽÌÂ`t”6’Y_tûe§®F$-gWóŠIéÅ8U¬Î's„_¢²³Ùlgº‚9õ©Ža2äçŽñò˹Ïåxä±%%( º6ø¬S¸þ×Úð?žIÎP‚ùrMiòùߥ«.1=£ÚäÁWZÊÝ:JÔ^ÉKy õ9=NsŒ}IǼu9öHs4Î'úHø_µû(=—ýësú«ôP*4è£ÃýëyÙC½ÑzG7œj»®‘Ëw¤É\áÙíÕ ÇóLŽ~Ž'e`Lý™_›Ï¶÷ÊÔ¢l¤«}@Ž{’®¦Žç/¤Ý—œ'ßâ²hGµÕ‘ÀZ¡=hù:ΧÿP~ÔÜàvi&»uTg:pv°š ÷I{Øú¼fíïŒÍgZñÊT;Ë¡v$9Žó™š—ÄZÒõ°z–}—Æ-«5Ùšçzö@Çc"Ë?~þ#­—$µ W2¬¡»›ä·»¡šÆ~<Ó™¹æ5Ë:{‰3Á¨!ƒ>ºÆAzle¹›ÕüÎ~KËilH‚ìG;E£#´íYv ùßêÙ^¹·ÚépåÁ^žLõ{͇í/K[ÖÉÃ(ƒGM¾ÇÎ}kWéü}{ÍÓFy åöu¦K¯¥¯‰2æZ¥·Ñ¡k9Æ®úDjF\óð£]ÈS\êJ†358ò/§‹ùœþl~°?Kšœƒæ9mÖ±À¨þi¾™³‹¯®&¯ÇõƒdXÕÉ×Gˆ7Ñ2þ¦:ÖÖA¥¡uXÀKrá$?"]OA ‡µwø9?Äòè{•à:Ik4wxýÙ§'˜èJ¶‘gy½ä –L:Ò—DS²ÆI;è]“K{¦+ûÈ4él¦d3ÒS¤šoLšŽå >9;M{Mûj¯pæ˜2;œE u*ˆÿÈ1ÐÙ"Ò¤Eë/åyÊWÑë¼GûIS·Ò‡n;õNÇÌ@Ê$“óU“éQSáòÐ’Ñ×zÅ ‰Hù!ê˜2ȸtvš:…˜ôè:@”Ö¯á5f£6¥t Ò0&˯¡Ã–²Vªz Ц€6™íµBfKûË^ï¦(J 'Ieiv“¦$½5XØñÖ!ûX-ÚDUõzìïu2°@.UûašÅÖnÛ:ÞMUÌG¬V8jÑbÕ9§”lp®Skg™E5¥qá#]³ç)—9·fq5?nr;«Øs£Ï$ÍËž5d¿Â$Ù…5ÙZBdÚeìÌíøêï{tò8n» ÃõÇxÅâåhùR­Ì²ëÚ œv[Jb7ªIœ$vƒUI³Ž‹Ö¹©&³³–¢6É +{=‹%’|o:ÇÝúK¿Hš&Ó¶^² {ú9×$îò#ßýøŸ3άÊ-ϯ•‚W¦0#д½×Yíb±L"F-|Žú”Œš$Y…”ÊÎE;2ýCyvGý©& Ž’ ÔñD:%éç­Ž±Õ,ÆH­€rµCÏjݵ$vVá¾âõÙ¼¶Ü†Vù,Õ*_eG¸6íhlP±ŠžÃm„´î:Zºfµ(ûéÒ •‹Ë|mi8µ)¤MUõgé7]CÑÄCzz›Hý‡Y›Ú\§PæÚ´â¨SJ)7HíMªk´­^ƒ´ë¨,(dUö•©¤-Ìú4}]¥òqµh™“¥¢$±’ÉÌ EtÌ"z­„A•àì] 4_ÿd×2`¯KRµ/²_I×.?g]²¶¸÷ú”ZqA®Ã9,$bk†RKSr­Ò¶F-«Ú`ŒMÞÆ„ ®XÿP~iÑ&ô÷0$$­-Ù ŠM¬ËEf³1šNÔéFÂêš^ôu^{öÚBWí‡&ôöZÚ`ù¨²ó9Ÿ¥¯Ü­¬3WùñKë—îÓr÷Σ»ÎÜe`¡û<;¥sÕ ·õ› /š„HÝc”ºÕëùÄIùd×ÄáLµû±¾²W8í/s#Ò)–Ô<{©W—2ëL_§ØÚ{­_iZa–gÖù ÏØµ[³'ú„šü¤-ð¼R¹O”]˜v{ö—rª³gé¥h1i gЩWÚ•ê´Ý>È7Ï÷çä ÛC 4°äYç8¼j5™#G¨õ]ªiR»Ï÷¹J¦ÝkÍ^²9üí÷m½§²L¥ÙÙ"f¯SÅ^3Aëseý¥—ø®«„Rÿ ˤÅšaš« Ú‘ʳ,ÉN/õôò»aÉXçÑ“® ï6€ë(c«Õ•íN ¯òw‹±ÒsèÐ9h¤6M¬z±ÊcimYmŸ¯ Õ1˜þ—±I—%‰ZyI ‚ÒÏ©¿ôQdžҳ‹\u~­ÕâIG©H(¨×+t–4ͦKËð»OZA6¸Ú*³ݲ“¤É\?XMÁæý£æÍG/xꤺ°e35m4“.¸ÀßÙ㸈)ÂúÜZ:¨¹²Q ò¸ª-SZÿÖ>騵[¹•RH“sÛ¼Ü֤ћ #„ÿ¤,a£¬>¶™ŽPêwyâÌay¹Ô‚¬RÔK½ªY"”9érŸÝ ²Yó¤É„“¤”è'[×”1xÕËò©M‹g– XG}>qv¥•7˜íK!ü¬Pq°AØQgù6CÁ«cmW~¾Q Ç„K/f¶|[îx·ÄY›Ÿ%RVl «NAB!×½ëÒ$ºðПO]}\Î>uRë qGÙ÷Š?g”Ýš•[§—æHuѺÄð_zDâ]”>Ëu÷€›ï¿â–Õ­§QzV£ßLm6£=öº˜µëÂ弦QÚ=$Àš¤[¥Átһ㥮/ɂޥ@K öZ¦A›yºÔ~wd‹ò—µ!÷0ÔÕߤÖãO M‚ÀÌWã6@=ÝF*|r­lŽsUiõ{Ö.£öþ‘ö5 h–+G]=÷~Ë··œþ}l ýc6Ð^틤È_m^.œ%wx}±)Ò,Ù” ª³ôi£¦Œ³3Ë¡Òý.2ªÛ˜·H³t°Qôúb¦P…Igm‹4¤óÅÙZ÷¬™ï, è¬ó”Yf¯ùë¸1ÛdÖSÌRÚ5˜¥Â¿èÒÃ"EØ× eág‘è,Z Ð{X»áœÚá½n’Üt€^d2±i]l–ÒêëË®ë,µwuA¬¦&úïЕôù¿6©Ò?òßjÁaÍÍ×Z¹™epÕ¬}›Ðk†² 7ËZÌ Í¦æg‹ö|ŠJ(Ïæ %S»YÆ´Yûµ„¿¼9«Çi–Ú`’yÕl+¡‹ ÂJ’Ì^éVpy%Xûº¤U³$?z9¡¸Hk>T•m–•œ XÕ4‡Ÿm5eÔ¬Já¨÷;ËÉF\&6^_l¡$IEkеÑT—aŒL¢ñÑ` †v$}Í.ýÊçôa¹­']BímM­f’J¸ðŽgó#Tëãü‚g#’Ô"‹\¥Õ‰Î…³ù‹Ì“–2fs¾'ÍfIb“¦ò³Ì0±©cÁG€Ò >BCðX/¯ã¼ÔEûY¢(Ýå,+⃵öYfý£´„$·7ÊÅNöŸ¥Ô>T™Úmõ7¬½±®Õ—âi]d¡L_ÌÐjr/“ ­ÂÙ{3‰ˆ]˰ڃ©{B» (é„^—tΠƼI:¸ÁV²Ôä ,É“¡ÂTë ZË,í`=ï^‘’ÀV¥OðZÃf=Ðl‹gHºÀÏÍÐ)=ÞÔ)Ž“òiê5ŒuA¯/Z÷0h¯rõòœêCè¥.?çbNÁó²mÈ*h²R AµtéªDF5*‹ƒå }µ´O±˜ëCê<Ì¥?±k2£6Â:ê%uå'™îè€[®M»]›1Õ>ÐÍ4©µÁR_[£Vh3øYRÐAÕ’½Ôt,F•?—‰ø$Ëa†tµé•`.£¾VÌ.0Xï7‚Ù§Nlé­wÐÿ]Ûž¤+úK&˜ý×ÚÀñ”˜iùœ9%X#¬Þç÷+?ë¤sw©?g˜xÈ?iõs‘ªÚÑ5ÔY¤«j‹„ÝrÆÙ ³Öjg)´ÍRý9RûõÌS}c8úþ„•ÛšñJ\“Ô¾’Zî“t^Ik&³Øކ\ßæÔzÀ¤Kâ³òíÖ ¹ZšŽZ@žåW4K¶ŽcE¥šTÛÂÊ$±`›´Â:¹7§Ó Mš´LÁG­kjÉk#î*O±¹>Vq4ÚÛ-ðw›Zœk"Á›SZ3H]­¢™™Õäjñ8ÁÂx}‘ë#üæ Â…ÖŒÏüÓVëÀ˜ â¦-Ô’Y« Oò£¨“[»çÞFl=¹2|9¯J °ÞW!__zxÐë¢øÔ{ã•ì²@¡,Y•ZÆ™tÌÈýõÕ±A'#‹ü~Vù×Óy€>ävÎTÀ´‡™Ý(±›ÕG9ŸKF³þ€I'½RÑ왲'~”™ÉÙ?X —ízv_5]ÒO]ZƒXdåDŽ 0ÕY×Ù¯é"§:u)0))?S×Â_ÕYˆ®õ2“ñ­„êÑt­—Èi'„Ó±î+ä¸Ck© ·®éèë0òZ¾ôq}oRó#-`Ÿ9É •óŸGWu­ä×\YÎrN©áí -Å rº¨ªeöAJ”zÂcŠ\£YKgj l*§“ºß(t_—xu}·¯¼¶$íJP­4 eeYû¨ï£‹¹¬ ÞuÓê¼Ë %|}7v’\DÐd.O„µÙ'q†•ìA¦AµÈ”dà=²˜ŽY’œI‡¨¹ÕŸC5W1…AÍUܳ4f³g$[át’–ª%¾úœ9¿¨ :Pl¨…_¿Ø Y¤\ÿ"yÖ™`l5“ÑA.k¶²©,¦éM~¸É°~ IŸ€g½¼¨èÿ}Ô´à[§ˆºP\F[z˜¥K.³Qž¥Cµz‚öì¶žd*}¶¼­¬°üæã.3ò:ùLà0?G^dõ•¹ FYþOºR­Qç+0g³—¼áïdŒª£©8'u®ûªi³-´áæS{=Ј¼òLSéó~ëÚÖî·ÚóãÊ×$°5V½y} °¼´y^éÇsÌOö‚-£’–ò<›Å^ß·²ßW’FãM÷Ô’õc›ˆÖ¾¦æû¬nÛ*p—ÅI{‡£>ȰQ tâ¸S›®‡ã[xZ6–•Xu-ã‹wó¨+÷ðæˆšÁ\/Ëù—ÿ\Äíe÷³Uòºo2Ö|'éÂÔ$³¡¤½‚f±Ç°x’A^[X«½5¢dþƒ5±M}2“îã]@R(,[½¿öw“îp@ù²YH4_–A|–(à \?ÙLj—ÅäêÀÁª&ƒÎst†]:Få]½WÙ‚i¿å ;DÎ6Â:Á]äa°Û ƒ­s– fÒ=ÞÀ‘%‹wP “!yÏxÉ`Õ‚ ­®Í’?á"kýmqn°6c°‡ÚM¶eÜ$ —V®;)©”½ˆ|>,3,ÈÔgÁ—úĬµÀ«ÀúwfʨÏࢶAX»\tCPÝ“tÑwôe<> JuC …–¯FµŒ%‹Gmc³ ?ºHxx“öêSÎu¹ÎÑ{)RÏÒÀ{shÌò²ü•.Tö½®¸Û[ˆR„¶Í>­’,{†ÎÒsš…q“RlÒfpÞØÛíu™Ã²tÆMbl]mýಫeFuâéëCÊ{k§×aÎvé€çУz÷¬v3ˆo j<âáêq;nU£[&Ö ·‰Úu ¯öÀµ Ù “uK¶m­ˆž^ ©Ôü²)Úc¬j-j•®àã1%­ÅÆ+ƒtW=`>Ts*í1]{E¦ëÓ¶“ò.¶ßZH·‰¢½•­•MEjÇ2vÚÔ7;Ýj¯ÊŸÙ Áµë·² ¼¶£>1«TÂgË›hËM–eÅþL\¥È&-X÷êÏéïé!> ¤ìI«Ci†êø»I½kº:\»5|þÔUa_T×¢ƒN›{{«V†°Þ¼²ö^tm↴Œò ´í®|ÍÊWxæÚ—öûYËCΦŠ°zk›vj:0Icƒ?L°< p÷¬ë4ìã˪•GøËMKËt¸ìP~yucÔÁÚf…æ:àœ3˜³Õœ3yÊ(ºÎ Vt²~È;ë“ù'.¯±ðær]%Tûý7°OÔ e.0â[ W#¾½#Œ¯RèN]º,(S‡A~.|Ÿb•=ÂR}Ÿ¾ªÚ>ÚPj ˜¬¬3d¤–¬;Õ5dKÍg)»jn/=MðæšVtdM*:”'KEÇòäúè[m9Ù®¶ÙM’·ãíÇ“ªù1kñÑ+TÈ,jûÕh…?ðk¢Þ=ËY1S‚\ž0ô£Íèú€Î0¢ˆ?Õ”ÌA˜R&µdé«å Þ@×y®mçÙë{”e¦>I¹—¥í±Ó÷•w}A¦þzÊØÇ°üÍè [÷ðÉŠÚr{}¡A5=ld®s†6Ǫݪ(™ÕÜJ‡“,º 0¡QrßÔ¨œörÓŒ>«WzÈc{R›µ ¾’)®ÑRv¦Rr/û¢ÌºÊ,íoÖ1Ë\~ÖÒíl«³nr Ë\³>%Iãô…Ó£Û¨õÇEØ$¯¨ûïØ®èè^ øNLOG|©ÀÞ$Ö÷$l–l¯ó뢔UáNcÝ;ÁÔÉáD¸ÔòힸÕ'IÞ)TGÚ¦Gè“Ù¢PÂMÝ8‹8©m‹ÿZJ<Æf]´ÖÅí? oÍÙî`µø1Ã{ხ-é[Õú’‰ŽHõ:¤~ZžÏãâw-Ÿ â.Ò•Ú¾>æú‚ƒÎ¡…꓌âþ˜Z;È+úØd!Ù²áÚƒH3ï;]ŒÚàF{Xü¯©™¡Ñ^P5¨K!¢¤ozØš5¬´Xùe‘ÊÍx-€;mé:f؇d1?lÒq¦SçJnÞÄ!*ß)I²­PÒz‰XÞ¨˜%%œt{BEÇÌA׺*ÔÍìfy/ؾk“ÐÕmK?µm®n}«ÙŠ‚~·cRô/›V>èÏ“§˜}Ž“l#/h%p$ã˜{jZn;jùàÈ\{N´kÞÚžþ³îõA/ÔµhASÖ:\¯ `[¨ÅûþÌ,φ:z‹ßAzö³˜½ÚF¤$zú$&u¢‹“Â’YqRÈÚ‰–Êfx1OÓ„_¾9 |eóì&ð•Mùè…2õ ΰ‰S’Á,é ôM™»ð ò6 úäkï7IŸK©zR4_Ò½6ñìŽú%}±y”ÅÛ’Ÿ‰aTKIüÏæÛ[mµRæèh¨îë£g;xé·@è+$bg°ƒëbÏÇ "¯ð“ ¶­ƒ½¹]KµðÞöªcA͘¥l¡/PÙ9“Y#¼“]Ú w,OJZÔáÉ®-ÐáÁ‚ž¬2IËMV ·=YRWãä}¯I²@DƒMmkÆjrôc/£½”!û X$õ³lµ\;â¯-7~ù=o~æ·÷:Ãûl2<¶AŠîçÿì’ÿ˜ªG ×­‡ì³s6äŸÇi¨—þ¾ÇO‹y°V•Žò ºDë –G±e×yñÚEO°O¸ÇôÜxðöím}Nä\Ç•m²’µbÜÔ_ÝWòŽ•¾jỦꓺ£já†þúâÂeÿöfˆÁ#5ÔÝüGy9Ý6óŸt{Ar$)3îæ<éǤÆWÝœM_‹Â}üõï`##yëDfSº³ÿ±ä¶ÊÖRê«Ò]Cët7¸Uë)n¶<Ék̶Ç^¯m;ÙÑö»¤íûÅÑrÙ½€}ì©ýàÞýâÖýue?¯ïžÚ÷žª÷í¯'s¶ò¨;ùã¦ýõFX RSöë>²®tݲ°Pöj¾C¥+.¶[¯K9ÖÝêÁ=”MêÒ n×_}ïíöý¯u½‡Á´Ð.ó0Ý»ÿ˜ÖÌæ^”æÐìÒï<´gaß°ÒOƒâýâýõi±H{Ø3æú?}[LwÞ¯ÔÙ±ÿ•à¹*¢/HÙE|ƒY¢qg~ÛX¥Ý˜_ë­†Žg×¶å—¿»|nÉjBºQ ¹mÐV—²Ù€_÷ßpt­‰:’)Àùpç}}]Ï6Þ¯³Bg/~ Äå…¡­—¡ßOÑ)mº_ÿì²å¾ócÖödýžõöÚöövYҟଉé—:ìmÏjˆÒÒÙ~ÿ• l"¤.×:ñŸõ«iŠm³¯ïa^v٠μÛì×öØ×¿³-~ªØq&ÙÚ6دå Ü`?ÕQä²åþ+Àºã>n°üÓvݶ]•toØãçlwÖw~¶º,)³}a³ukØ®ú“¬Zâ k5¸§¾v„Òoë6ûÎ.û¯åÍ-ÛO‘q{Q÷þ&I»m\6ÓW¯„¡£AèVú¢7ØÞe® êf›Ø>úº‰•yüëò³³>,¥£ëãúÕ®d¹2l—MˆÊ)̺7‰3¾:¢ ºmŸ?ÈõÚ¨ØKúf5h];Á½óWñ©Ûv·3ýk°÷MÍc© S¶o~-é¶ùßôöéWüpƒlªsÝ5_ ø`J‚=óu y¹Q¥zø`´ysfØ–ýúÆì™2¶;è¿Ô-jtœÊ6ö®ï·ψNäÔWeåë…·¦ÿ¸~ÎXþ‡wŒÕWVð« µ“€f–‡Ï>A¦µú$èVw¹|t€M®qpÑj“%¤jþM2/°Ïlé'aF8Å&–v8´rrù<(0:gÔå«Íi2û©™OVKÝ—¯€ZA\Ñ‘”Úï[ÿ rRÙ´£ÎuS’r^]bÙà…Çú®,êõ|Ñ :4Mû64ÝJ÷0ë[fÔÙîGšï*ìáå?}I ?þ©†ñÚŽ´4vŒÃöÑOqµ]¾ù9ÀËŽ{ºC†Õ¼t78}a„O*ëåÊ~úÒƒn“§©X@+³È÷’è÷AÏ–]™EXìT}ÛBlºòÙ ›œH† k6sؤ™HË™ÌÛà i“÷¨Å­¿‘ó[Ö)†~£ öF•¤·ù›mpqÐ÷fwíWº÷Ìô-PýV†.[š¥v!¹Éh;äH;Ó•$[“70Ø.Þú¨Iª’‹U%ì3–úwR ž`O-|Öµmû6ý.¯wÖŽuª9wýiåë5fÙ°oÕ¦«þaøê¹íKl»Œ²Zû•A©z#FóäÝtCÛn Ö͇fž<Ù¶Ÿö!”»ÂêëJºC’$ðZãaë úö’ìeïîW(~lPÍ]°Œ$öШë4Ø>ËmÛÙW?ÍÄn8YB$xý²K/_énR²ö¦ËžúÚ1G\ë–Põ¾“íž>j;H°-–vyj‘7I¦nÕRµ}¡.šLà…ÒWí[*ê´@8‹ÝÊí:#´É¤¾é?ÂÖ‘µÁðv[}ábQýûÃneÛÁÉ”X_r03õ˜A61t=Nwg·éŠyÙ}òtò¡¹Æïô]aµ ŸAýÊùÏéwr”è×J¬0þÚÏ«×S½Î‹Êç\ñC¾ý, eº‘«ff“©ñ£cºy~ MRíYu6~ù:ÚiFX£~W\aðÞC-¾ëgHu»+4û×k¼~ͼœgè»G–gè–ˆµ m/Ì’âçÏlWìMþ®N!œ¢½”2·~…Ë>à¡\®µL5äë»—ïž Xl¸nº‰×~ôŒ¶Ì±Cá“gúwµË¨·8ÀF±}¨/`¶V#½nŒfEØ7÷ò­3çSgƒ½ýŠ;ìÛëª5û¯Õz݆¶Gµ¯œÍR8h¿{výìÙ+²Qön¶/œÕ¡ÝÖW'ÛÛ¾o6ê{žÍçͬ^M‰¤éúwæ)Ô­íK]°ˆ)ãµ&‚ð½u™qZ¸VB?Òä`µ5/ûª™¹¶u]ò°U{4|ëF*:_¾h6À.]úª~Ïlåj©$+ü̺Ö#uRûœÙ"Û“I„tõêòy³×ü’™neiéŠTämôj~:FaÙ‡©.üÒWÌdûG[õm÷+ÀZ4Ö—¶ë¥_0ûf°o™á'̪ÏJ¸5t>iÖTu%y´—UÇïv~¨êNZ(”mk¯Ÿ.»ŽE缡¥Ÿ3>´QX¯c‚æQNò+I‹dm“¼„=ªÁEÖat»txe^öÓuöÐ}e×ø (\xš™dÇ}ü‡ÝLM.Ú{ü,£ÖC{똙 ê†Ìiá36Gž¡p¢XÓo©}3Ú„?¥¦˜‘S^jÝu¾ïxötlAl‡u{9f—Â%~Dm•ä\ý®šít@e—NxWÙfV<äš]Ð]ÀØgŸ:Ö…óÕÿ2®~9íèŸeúveúëœÁËÖ´_}ŸÿÿüÓ¿ÿ?Ëï_ZEùGñî½¼œmâ|œÎþúYÿoùåÓråÿQ“qQó„ÇV8iOmÿõñeUg¥Oí¿>Â_=6¥p”þ§÷ºóÔ oö2Üã0èâö Æ{7 ¾wOûç/q~¯{_ZáaÔ„›îrîeD»Áxó ÂwïªÿüU®ïuûÛåöç]Ò\ºÏm—‰Õ ¦Û7‘æö=õŸ¿Êý½nÿ_øþ÷MRt¼ÑqÜt«Óý›Hsÿžú—ùnÞpéõÆi•mþèN—U_ö1D8®ú—ùn}ßpéüÆuÑÁNý"©Ô ¦˜HOýË|·p¸ô€Ó0˺/ÝiÒ-!o0D8®ú—ùn]àpé§Y7<£;Ýì8SL¤ €§þÀe¾['8^:Ái×ú/Þi'ÝØÇià©?p™ï—ù]S¿Iw™¦;]FýƬ)û3‘&ýóÔ¸ÌwëÇK'h×eùf¹>…T“_ÀœýšÊ×øn=àxéíºð>á6n0Ý¿ýMsÿžúWùnàxM-K¥;µd÷S@¥‰€«ÿÀ…¾[8]ó@ËTé^-á½ÁSiCàé?p¡ïÖ N—N’U¼WÈyo0‡ÀTÚxú\è»uƒÓ5´t•îÕ²ÞL!•&®þún}áté !aÅ{…¼÷sL¥ §ÿÀ…¾[w8]óAKYé^-ó½ÁPiBàê?p¡ïÖ¦kFhI+Ý«å¾7˜C`*m<ý.ôݺÃté!mÅ{…ì÷sL¥ §ÿÀ…¾_YðšZâJ÷jùï æÄÐTÚÌÐÓàBß­;L—î²ZKb(¾Á–$Qjl˜Scyà2ß­3L—ÎÒZ¼SÌ‚ï8†d8®þúná|Í !±¥{…DøŽc P‡ƒàŸák}·þp¾¦‡ÛÒÝB.|Ç)  ÓDÁ=Ã×ún]â|é1½Å»ÅtøŽS@§‰‚{†®õÝzÅùš$B†Kw ñÇ( GÁ?Ã×ún]ã|é1ÉŻŤøŽS@§‰‚{†®õÝzÇåš*BžKw yñÇ( GÁ?Ã×ún½ãrÍ!Õ¥»…ÔøŽS@§‰‚{†®õÝzÇåÒ;b¶‹w‹Ùñ§(€N÷ \ëû­(_sFHxén!A¾ã”6‚N“7ºgxàZß­w\.½#&½:®sŠìcË(s6ÜdÎ&óÀe¾[Ǹ^:FLyáN)C¾áá¸ú\è»õŠë5gÄŒï3äŽ1@‚†®õÝzÅõš3bÆ‹w‹ò §(€N÷ \ë»õŠëÕhƒ/Ü-eÈ7œ¢:MÜ3 ¸É§Mæ‘ë|¿.òúr ä»x¯˜7ßp ‚É4Apõ¹Ò÷믯Ç`¶Kw yó §(€Nÿ \ìûõ×wd0Û¥û…¼ù†sL§ƒ{†G.öýúÇë‹2˜íâýbÞ|Ã9¦ÓÆÁ=Ã#ûŽûH|êåA¾_È›o8Åtš8øgxäb߯“¼¾2ƒÙ.Þ/æÍ7œã`ÔÆÁ=Ã#û~ýäõÍÌvé~!o¾áÐiâàŸá‘‹}¿~òúú f»t¿7ßpŽƒé´qpÏðÈž_?y}³]¼_Ì›o8ÇÁtÚ8¸gxäb߯Ÿ¼¾BƒÙ.Ý/äÍ7œSIÓisI÷ \ìûõ“×—h ¶ç˜çlýåÓ†9Ÿ™G®óýºÈë4ã½bÞ|Ç1 ÃApõ¹Ò÷ë¯/Ð`Lw yóÇ( ‡Á?Ã#û~ýãõ̃é~!o¾ãÐiâàžá‘‹}¿þñú æÁx¿˜7ßqŠè4qpÏðÈžã¶dŸzÉïòæ;Žq@Žƒ†G.öý:Éë‹4˜ãýbÞ|Ç) ÓÄÁ=Ã#û~ýäõ}̃é~!o¾ãÔá8øgxäb߯Ÿ¼¾Tƒy0Ý/äÍwœâ:MÜ3õ}A»^Jœo°ÅƒòiÜOƒÌ#×ù~]äõUH„ñ^1o¾ãá ¸ú\éûõ×÷l0¦»…¼ùŽcP‡ÃàŸá‘‹}¿þÑùê äÁt¿7ßqŠè4qpÏðÈž_ÿè|zò`¼_Ì›ï8Åtš8¸gxäb߯¼¾gƒy0Ý/äÍwã€:ÿ \ìûu’ÎGh ÆûżùŽS@§‰ƒ{†G.öýúÉëË6˜ÓýBÞ|Ç1¨ÃqðÏðÈž_?é|Žò`º_È›ï8Åtš8¸gxäb߯Ÿt¾Iy0Þ/æÍwœâ:MÜ3}xùỿÿáOõõ3ï¿ùñ§Ÿ~ýò‡ïÿÛÿ2ôýÿü¿êÿï?ýç—ò?}ó»ßÿÓ?ÿø§¿þúeøÏ/üIø_P®ê›¢o?üù?ý/ÿPþ=ü§'ÿßË)òŸÿßýáwåòŽXÒ™­ªüÍq±¿~é»uVöÓ¿ýîŸÿé÷ù÷çßþ áÿ÷w?þ¶áç­ä{8þ¿ÿ¤·QÉÿñOßýá§óÿɰÿÏ/Ú¹Â:ºßjÿíSþv§÷sO÷üµ¿¿îxÝï¯?*D¢ý9ÏÖýç?~÷ò—Ìýõøî7ß~ø‡ïúëïè¿>”f”;öTò£5Í[· K)qý꓇ŽÇ¡óÜMË\FÙ·;Ç.C·¯ã2/×cÏÈ|"ƆæhÞS>‚ Tå6.ßHÎ9Ež±Õ ?}ð5ê6Z¯ pC{7Ó¾!¥ánh_º©éÖ+ w+C_ª\y.»5Ï‷ä<ûÔ%4·ôå†Ë¡—[_ÖcÜ* Ü6¯9„ýËòf÷Tà¿ÇùΡyè×λs~blNÇæ}ëζ“Ó‘í,e¼ÌËpޤù™‰­ƒèP…K—ÆóïôÒCƒ<ŽÏx½q´Ì÷wäÚånÖ!m)建wõ˵¥(}Ì=„ÇÍÄ´ zÓ£ƒ îz7ØÈz¹kdWD‡*œ»½”ö68…ƒôÐ ñ*³ƒ:2æÇ--µ¥ žººÉy¿I©Òex¸áÒ$·#" éB;kVy®´”D‚ÚZn9Ó\ µ5á¡ÚÖönÝοӆuEvhxáo½tÇ=pKÛº½mT²C¦®~ØÙÔT /êš·eaèÚÓ‘ÇBÇî1<Úè( r è1=:^ØžãæÛû²>çïK)/`_6uãYs°ŽËAx( ¦u%ÉÙ¡áâ5vóQ^kúþã1©ï¿ <‚8LçßAp.H ¯¦c‹{ éý¹¥¦³¿B d§‚9©p  ŒÞ”S§¹$½Y’'Œˆ QpɃdU]¨£WÖ¥ÿâè­]IGË}BD\ˆÔ!m¡@9PâEoò/x™(zëÔ¥ùüD‰Eć(@YÞZ¿qBÙàšÀ3z_ÑË#ÁpÔj/s†´.sDˆôä®cYYlž\ª@èY:Zì8GvypZ»Óºfé­‡àPƒ9ù;&W æ 94^¼r†:+‡¤¾ïެaÄ Ãèh ä9ùç]˜/lS·Ís¹YjgKž’&ž]¹ 6:ä)éñ_ è1=:\Øò|h<{ [νæ½ôb ÑÑFçnKç_Úy<¦G §RÕ¢Ð&só|~9Ž’9¢àQ¿åª.œƒ™$ž©ð—ŠÞ*'s}ן(æm$ êÙ/rœ®L;¨q©%nMDXjк.5x0\¹ :ì¡›ûé,~Í£ßzT4`ðmcìÞ{ ¦-°ãâlêz©²ÑX8-€ÆÌ+ã1ë[Ίe‡W¦G‡ Û3þìêæv:ÝÛau<_á1À(@IIJûØôc.T ÑÃB÷TJ‹¼f?vË6ˆ…ó ÂCuí!·£ñð®ÙÚÃÙ¡AâÅ©A-o·U‘ZàæªˆQ€†Ý6á¸=4HÜhÖ£šqÕE;šq]£GuƒÐ(selù„9nlŽƒ÷^ÉŒ~ƒÓ.ïÕÞ`2pâî5.~ü݉%tŒõZôÅ6]drÇwü§ YÀ°úèðd.Œf¯{Fï—E/ßå¹BN Äâ©ÆQ^yvnX]¨éÂh^‹aZ¤‚C `u†iìæóí²€axðd. çXLyRu¾/B–CÀêNœv±¸ 7 æDÓta8Çâ0MÝÞS¾b4"V‹â0õÒ2|HŠÍ¨ª.Œç_„_ÞLˆÅ¬MÌAv(@1+‚šƒbùól#'d‡S-ˆˆÕ­Xúóþ,û «aU]ÍÆX®}8g¹$ÃfjU†s:µ£Q°™!".$ÃfjU†s:R˜lu°­äBD\HTYÉ¥@90ÜònY©» Õ°ÙòÒÚ GouQÀ0ØòLÕ…ñ¼ziï¶³îÎ7oµtãé¦ð! (†@™ª Fo“V2*6ScJÜúÑÁÍÎz.ŒæqÆ©ZÁ¨P ¥8œÎy§Ëð`£âiA³9–+?Z /ò¶ÝŒa?V]ȆuQOæÂpK½cé°êˆfXD¬ÞÆaØ%õ÷! V{#ªº0šé±LÖu=jBà[lÇrŸã9ít! V—#žÌ…Ἡ¯½9šÉqZºc¯­tñxÀfr4Q…ó=N{7ž=絆!že3S’€aÈMÕ…áãT–eú&³-‹ã´É.….$Àêq„sy,œï1{µöM•$ÀVuÊ÷Y{$’€b¨:™ª ã•¢J–U—HÁºˆX]ŽGâvöO>$ÅÕë’WÎþxŒrÅèÄFÄjv<ÆÎ£kº$`XýލêÂh.Èc¡L(ÁUŒÉpnÃ%mVȆ!¶“¹0\†œ{¦:¥'/#`ó=–à\ð÷! 6ß#¨º0š²,»¨M-@ÕûX–rê è1:Z¨ÙMÑcñ<‘9½’¤Á Íú˜6çßtÐAªÝQÚG3?–þx«Kôè1 þ’ÒËëtì YÀ°ùKàd.|عFöçÙ7/ÈÕxƒ·M¾©qƒÉìˆ_®sq¸ |‡Òéœ ˆtKeýéèÝÂíà{wK†ãmªZæþû±ˆË·¤8Þ-­ºÚL·d8à-å¼§Ýò[aÀÛÙŵÂ7¤8Þ-yÝõvï¸9q:wî—êØ¸îÜû‰ƒçóàâÖØJÝðßc«á¥žs?ðç\nùˆÛp|3às^ºT–6œ@ýìÇ[ä &OÊ.ûî*+üR6>Dòá†Í ¯'rP8oü3jŸµE¾F†EÀêm,k§EÔet¸a³6‚¦ ÃùáW·™™¶8›ÃA‹ó nØæpz"…{“ çC5g¥Wë[9¬e€Ð'ƒwLÊ…ñ^ È?¶•ÛÌÿØÞ(ÁªÅ(’€bxWÀT]ï‚ò¶h}ÌÞ(o ¬ÅD'Ÿ ²CÊÛ æ `/”ªÛx¾ƒþÀö®@i"gE·(ØÞU†{ ÿÚ¥¾m—U0žµì²f@Lc§hº0Þ€ºŸ-¹*´ÅÙe–q¡%tàÉ`MV¤o‘V¯Íþ íµ Í•Ð@y"sAá^È£ÿ²JdÌÝØÞXó´ ?ü]>$Ãö&¨º0Üëpíèîlo@D\H†íMPua¸×(Lfbl†'ˆˆ Iƒ*†' ”ù r¶Õ¯ÇZ2ùÓ›—=ÿgí×}HŠÁËnª.Œgp_·î(¦Í͆@¥.Ÿû¼$ ¥ª. ½]ì¿äðlï¬yn~~tÚ‡$`ØÞU†{I ÜÆé-A£?P}% ¤©_îmTß EE{Q 'WuzI.&Ãàxʉ¬yÀ®›ã NæÂp6¨üÃ/òE{ðù¶wrcêÓ’€a{'T]îEÜÉ\6GVï”Üb”Šæòá†í}=‘ƒÂ½ 6±ú¢Ã°½ °èÝùÛë êÂp/ еSvkÑ“L˜¢ç@ ™ðp†K¡ÌˆÃð>€.]H€õ…8—ǽ$KX7¢•)0ÙRDKèо-9ÁZ„–4³"k?`{ À²5’€evõMÈá.$Þ»Gþ~æohíl¯”úZ»c2B¯{!£ª ýptæÇœŠ“â ^ŒüwIÝr®P¹ Cþk'sa¸¤xË™Â̶þŠÌþ¿Jm×Axàj5`1þW­ ÷õËfälžéþ¯„­‚¹ýa@ð`¼w¶]6€%C?`óýo‹ì!æC0\_É+ ÷j@É`W ³Yäúj€ÁÖAr}5NæÂ‡_ Ø#ëöM6:%³¿Çq•‚É & ©‰ÜàÇ·GúÀA‡ÅòngÎ…$XŒŠx.E3/ò’Ž”[ñ Vz\H¸$Å'ZԹ€)ͱЄˆX ‹·ù,Ç;=‹˜Í]H8cÔtÇ0!"VÃb2e‡{¢`5,¢ª £¹K³×ÝÇ0»5 ™ðÐëF0dÖ ÃÉ\8=FC"bµ.BÊëC0¬FTua4oc©•——…Ï”W ŠˆÕÉ8ö:‰ò! 6?#¨º0œÉ±ØFú3ÑE"bõ3–ºGÚd­Ö(ø´4¢ä•D39–~]¾d„vÃ`=Écç2£„ YÀ°YOàd.|Øä8 ‘ xåc€§Á‹|‹7¸¼vwÆç£Dnp¸ Ç4ȧ‰è–JÏWß ˆ¶òÝ-·që˜6ÙQoIq¼[Ê”÷ˆŽwKÞCCÏÒ;n¯{îV;N{mäÿ;äç9óLäüÉ>c§ÚaŒ<ÖäYD}gÛÜÈ•_9¥îüZ×ñ‘Í·,'¸’p6æ<ÿ—9.Ý´b Ï"N²€aˆ’Ì…ñ¢7ËÇÉ~Xjð‘.Ñá†Í¨š. ç^›Géu)‰6 wQëw.]H€-ᆓ¹0œ+<÷î2ëGk7`5Ï=¼³vet¸b°›¦ ã™Ãgµ9°úÀKDÄ/àBP >pSuatäî6jFðÜsŸÀtmÔ\à¦è±pÆð² ±\á€mÝšÐ`ŠÑâá.Œ7ŠZ?Œ f4Èâ $ lq FÆ[qƒkG 7`³{C \HT±{S Î>‹·ŒÜFÍì]zïs§wÑÑJÍémŠ gþ.µ”ÓxHÞmÀæó.)jݽ҅$`Ø|Þ êÂpæï’¿'±ô˜1°yXrDê¯IÀ°ÙX@Õ…áÌ-Åôz.‘û°9•Kl8Í-.$ÅàT6UƳ/çVäYçC ¦«u! LŽuÞT]0zKMFɺmÔ\Þ%=9¿ï1:Z©Y¼MÑcá\ß)uûÜîX‹TÞi.Ìex´Quxƒ¢Ç¢¹¾S/¶(r¥KY)¬ï6z›ƒNæÂp¶–òÙìóŠÉ´ Ø ÞåcÜ§ÙØ‡(Ø Þ êÂp®ï´ˆ˜LÛ†Áà]¶úz¼YÀ°¼ád. çúÎS€ºé"¹¾«Á»L´Jéè’€a3xƒª ù¾Ë„²~¹Ò[Ö §½Ûë°èB ©°©º0\~çÁu‰Èct¸aLQÓ…ñFØ¡;LQüQ4ÄV€ÞÊ&b'p †´©º0^UÚž/ò76/äV^r;ó¢`óB‚ª Ã$7µ¯Ç°Ù!·„ _! 6G$¨º0œOr;W'Èã(ÌÌyÞ9×­Ô\HG63¤H^I8oäÞk~€K·€m™w[4ãp! ¶e^Pua¸µß|íµtLæ<ÀfäË©/Þù ƒ‘ÏT]ÏÝ·•íç˾¶€)P×Ýr6Ñ»îkª. ½œ.Tï6Ú›²ôþµOw! 63$¨º0œErŸÅSŒ&G j‡Ì¹Ø2ê^U†GU;$(z,šErՀ˷†a©×š‡ I°-õÂÉ\ný7O(«ŒŽ€Í ™“Øþœ ø ›T]Î"Y¦ãu{9t87d™œ;ɹ ›NæÂpÉ’R?=;›r›ô3®.$ >*+nHPua8‹dïG†Œ8us­Ä» [F ª. —&oc××et87äš”sÁ…$Xíp.…³Hn«ÔÔÚZÒtqCægq½lš CÝÉT]¹EGÀ憴“QÀ°"MòJâY$7µCǰÙ!óÓµœî3’€a3D‚ª ù$­øÁI®bLˆ'ùO²€aKˆád. —%¯{ׯ©~\ÓLŽ€Í¹ÎÒMù ›!T]Î%™Ÿ°I?g&GÀfˆÌã窟£s C¤©º0žK2ÿòÕB&GÀfˆÌíÉ*J$ÃÕ ’WÎ%Y 5êO‰bðŸljWr! ÿ‰Ì…»$çÀ¾iȳ¨s¹–|7¸¼upö~7í rƒÃí›»$Ù@™n)M⨠·?îÝ-·óê49Agßæ%t¤'ºè›ã~’ <ȆÕq'sa4þ3z¿¬{µB…IÀj§Lƒ–½  ÷61x±¾¯€-Ï…$€x}_û‚+ ÷þòú&ÂúÆ61Á¡©}cÕë%î¸õÄú¾¶ ’€a}_U]î%†çûEú9XöE¬KÄØ¥¹pà­¥CL¯0ܺ1÷Ñúõ}%HÔú¾ÊÑ^bhºpy¡éÆÏ[j†…+$L\ê '#Œö§qú&b}k#âB0¬/. ª £½ÐÀaR£b5eaD\HéúîÊÑœZpíè¨G¬î{ˆˆIóÁê¾ç¼ñ ÃYòŸÑûrs }ï³¾»Àq à“[Ýüä:0Ú /À+ HååÈA\†G•—PÑcÁ^hh4\ËæÊÂÔ׃,@Ú™¿£Yµ¸1èûˆõÝŒˆ IÀ°¾»€ª.ŒöBÏšô}žÔwxâp…,€EÐúîAí…N³ô}Nôê» œè9 ë» ¨êÂh/4<Óä/=x³/}ws:²µv‘§+‹öBÏ8­®DmDjPÔšH¸)5(Z_¼ÂÈ…)|±¾»€ã€ IÀFÜóõY/$Ü Øà}Äúî¶$’€a}wU]í…†g–üåÊ¡ú>wâõÝH˜©Ôw8Sq`´¸·Ö÷ø>ë» ’€=¹úî>¤ ÷Bgú>Uj}œ‹*$™ÛœäJ¢½Ðð5T>eæ[#›ùæ$vTzEáÛΆ7˜L¯&rƒß°íó9È[ê†á²k3`°÷m½~–ǃ,`Øì}p2†óü=£÷…¢‡† ÀêÝ€€xŒ7lÖ Ðta8?G¾â:U¥ñÄ0Œ=y‚1Iž YÀ°=p2†sLB˜ÐòXÝ‘<Ñá;3GB˜<Ï1 ׎†GÀfŽ„@¹0zbޤè]a<Ç$\»ÙŠ=‚ä 8#|.¿Ñ/qAÁ“ÐÐðØÌ‘Ђ\H†Í ª. 瘄kÇ!’û¤¶u¹ŒÇÊ`Jar`à–êÊ4FH š ’¼Rƒ¦Áô 㦩6Ã#õMbޤ>Ì$€As$Êá“Ü…«á‘»ñjŽäaá I1GR2âÀpŽIzDÍðØÌ‘’çÑmìÃpŽI “­ä¶U_ˆˆ Iƒ*«¾(†[ ¶k'Ë`³÷YD|H˜нòÆ+Œçù{Fï‹Í-ÌðH÷)æHŠˆIŸ\1GÒ“ëÀpŽI«¡ç¨º#­Âä2<Ú¨º#AÑcÑ“ ]Ê…Úš-ûBi΃,@•mD(NWn-˜ƒ›9"âB0læHPua8Ç$ÍšÌðH)™˜#)y»BÀ"¨˜#©êÀpŽIJ³ÌðH‰ž˜#)Ñs àÌMÌ‘4s`8Çä3MþBÑCÃ#d_fŽ„œÎƒ,€A­]$ÅéÊÂ9&Ÿ…©/´èˆ†GÀfŽ„|Å…$`#nõGÂÈz!ñ“ 3<6s$„È…$€9¡˜#){t`8Çä3Kþ2Ñ#Ã#`3G‚ÍÂ…$`ØÌ‘ êÂpŽI¸v4<Ò}Š9’"â@°vjæHhь瘄kGÃ#`3GB \H†«?$¯$œc’ŒIæ/¡¦ ^j`WÈ8¶ˆ…F!>î˜Ü#›ùö1?rÇ,Š<>Nã¨yµÉi"78ÞÐåCã×Í®ó­‹y ÞÐþ-·mmêóãÇùW2ð–Ö®µ ‹w3ÅúŽót?†ãÝ’×PÇðŽ;%oç¾Û^gÛŸ³{pî”·aNŸµSrî*Ò2oÿ.;%Ç)S¿×Lñ3î5 SþQÊèþ¦ƒS=¸øM¦<±ÿŒ’Ç>pªPb®¯£¨ïܨYÔS?WÛ«Çøh¥êO‡óx,šeý¶_6ðÇ!ÄÂAt¬Ru‚žÇÂ÷<ç+ýbãÐ7 “¥Üã“íÛÖB0l“%8™ ÃYü!LèѬv~žÇèp‹¹ù!LŒgñ‡kG‡>`sóC \H=qóSô®0žÅ®Ý|úÅÏArŠ>ý"ôK\P,‹?uÛjЪ^~èô=FG+U#?(z,š·ÿ9¦þ¢ áÊ'P]$…üÍct4duòñ4ÌÕ.,Ü¢)\:xñªmBä1:‚Y=û¢+ gãçnZ]øÜUWÇ>wýWH˜œˆcŸ†³ñSªf.|ÀæØ‡ˆ¸8WnS]†³ñS˜Ì^جH’U¬H(†ó'Ùµ“°yÎ-">$ÌùÄsN¹áÆ3¢?£÷ÅææÂ§ûÇ>EÄ$€O®8öéÉu`4¿¥ àÃ(†}K?<„‡*·>¨9(˜ŸC#¾"È_Õ‚y®Ãøh dý0(Eè¢Y’¨ ¨í¨:ô!££•ª==αOE3ÜSö%æ|ÊÓ®°¦)æ|ªi:0œcŸ2*3ÜSN'æ|ÊéHX®s>•àαÿ̈¿PôÐp‰–™ó!}ó `P«;ŸâteáûÔ½™ážÚˆ˜ó©59°3s>upW¸ø„~{ j͇ Åct´µ§5ÆÔ„³ê§qêú³sA§=buå§!ßæ|˜¤}ˆ€Õ•ª.ŒfÕ‡k§œ–îSÒ_ŠÈ’`Ë€ád. —Ûµ£Ó±ºò!">DÀêÊGUF³ê㵃Ӟﳺò9"Dh§êÊÇíÁpV}¼vpÚ#VW>Ê…(ø4æ£ä•D³êÓb•ÚDh-¦®òњͅñÑJÕNçñØÃýqˆl¼+&Ã2H6fü¼ šIû˜ ª&rƒÃyô19KG ËغHå¶»ûÉOÄù¼ŽwKÖõÑ-Åëí–æ]º*º%Ão)uò^žáx·T;ºì¾œi}ÓúºuÛ’O?Öñuîúã©ý¤ï|üftº5Ïåçí=\öã7“wΜò-ǯý3œÜƒS7-‰.øSãõy¼NK¾×M[7ŸFv´¿#žt3}ã:Ý1:\±åAÓ…áÜóØÄÀüŽXòØò\HøˆW£<÷WÎ=CƒZàV«<Ž‚C V«<ª9(˜{4À6¯<<.$Ãf—U†3ÑõÓI}ÒÞôi.£Ã1¤:˜b˜n„…gíð€Í9O¡ IS>1ÏSw…ñV5áÚÑO}“è©s `PÅCOr`4g}¹Ë¤_°Tc«‰ž#â@Àì¦zÓ8r`8g½Í*ÑTô6SumT½ô è±h{KñÉ™¿Y‡`âàA0lÖ!8™ Ãù‰¨1˜U°¹ê¡1¹ ›±T]ÍnÏ%HuËs´:ë¹z…,€EÐê¬ç"¨£Ùí± nyÄê¬ÇЧ IÀ°:ëQÕ…Ñìö|í”åZô4#Æè9°Þ,1¦8MF·¯ïãœ_œsîÇkïs¾Õ9ß–jHóÚ§ÀÃsIˆ‡ã ”ú˜¿"Úºº3éY‚¿ü[1”ðøtÕòÔ=ãâÇ%çÂýY#‚ûñ0æYéù ¨%OU‹»â¢âµ[ôsUz2FKJÎZɬ‰’V´ K ÄåßЪ%<>]õ£ÄeîÆs&i£Ù+Ò¹tgåpìø 6ÚK½=-¹Î ažÂ¶ Agó黽Ì=ë!†Ÿ®úQâÒwmnô PNZª¯ÁCp¨Ak5ªæ híhÉÙÏyƒÜ©†þ{ëÆsW#R§Øúo8™ £uêÏ!ñvýÛtl­C2töYc7ÖÙiûo=ÄPÂãÓU?J\R7žÆ]ìÛI_¾œìË¿¡o”ðøtÕ—Q ¨Ô¹µ®|—¢¬Ë°7j½¹)z,Z?O²dIa3jÙTîLΉËxDj!2E… ÛÐ çâx“Z µ–•{ãs©ÝeØÚŒZˆLÑcÑ–æn9C@7nÔB4æ6”šPãjˆ@Ñcϰý]„­ re,Kmï$È~>ÖÖ]Æ©PLðEÑcѶ‡ˆrNa–œkårƒ(ÝU¨i©žàJ¢e©KÙÇ☠óM†ðÌݘŽù´I°¥óp2F‹Þ:Ê;ÊÜØ C ön:w ñ!E°µ18™ £E¯x/ójž“§nŸ¦¦¤ckxê)Ú‡‹TÙÇípq7ÙšPìôë–U.ã@(ff¢è±hÁ3Éý¼l­¹c ÊÜ¥ó)sgwB-Û›D ]šz¾P›YjáÆe<Åе{QôX´°•là4?µ9BµDÙ€8tË<–Š…›2®bK'ìT‹Öó—×=ÏjߺaS/ÆO6E\Å'8™ ÃEï™Ýþ²ásÛÓ¥»2j#@±|6 0ŒâP)Š‹ÖÙ•åsë«V’B}§ñòo(ü Jx|ºêG‰K__ßnŠû5…MýØ”·q.&ë{›Á^O%dj{h§I‚iZTÍ>læJŠqn¤'s!÷_Ÿ2ŽÍcf¹&§ö †ÜqôpÛû´uv*ÈËm¿œ°¯{öny[gñ,Îcý†OnöÛWå^ZÚœ¦7zZ%‡¾4ƒbÓ¸üóÞÅ5pF}Ù‡ÕO»Ìåï867¹Áoi†[è@ï²ó ¼ÈŽÁ9GA^ º;ÊX"äœ%Èðó ÏÏ„'ßÔ¹®Èm(ÆüŸgJ{CY¸ŽÆtFŸF›d Ó"{,Xkv6©iìæ³?º;ÊX"äœ%JxÒä9k’ ÄI}²Ôa «i™Ún¯Àò4c‰4’s–gxþc„gíŽmKÚNÜ0tøS·ž›¤ø [‡ª. 7 <£÷ŒÞß*zŤWˉxó€-Pií†s¬ó!%€†-P êÂpÑK»¼›Ã7oµtc»P C¢kª.Œ½M6Uã›7 JÝ% ‚è`"Ósa¸¸S]jrUŘØö²ÀuCY8$¶v>†Kvóµ;h;ÎÁª>¬Ú†P9EKÏèÓˆA¬Ÿ¡¾Q8„kØeãÉJÈ)\zFŸÆ âÒ­ëê<ˆÆ±Í• ÈݶnhûC(‡pÁ}.ˆ©¯æ, ”Bª·ˆßˇ”ÿ†aCE=n$™ön\.¯ƒ#†0ÍÝznÏèC0 i²©º0\ôRY`¹¼“„µÉGÏ}HÑ3 ­ÌT]/z³| £gR½Q6k÷a~Á(Sua¸è•ôë쥯I`åM¾w1Ê"½d,ѧáŽ2ê9{3 oÆÙ£¯º£—ÑW8³—müëÄY¾»s]/„kèæášbe à´X­gôi¸ –Ohëïm_&˜GÖ>‹°JZc,ªº0^g¸uçûEPfWTKñ©;ÊË¿íE OWý(qÉÉÕ5=QHYœóï&¡kÓ¶6¹ž,J˜r÷» ó—a@xÓáûS3w"œ:|=£OwÊî‘Ýs³·ØvxÇ‹‹ô|Hï8ùMæ¿Á¦8õ‘½¬g]Ôº;%g‡¸¤ü? ¶;ÆX…tÑòè?Ãâ‡eq_*G}_ùBÔt™se àÖ÷á}.§{¶-7,kê†ë–”ˆ-YË"³GèÐÊ,1†KQòo]³sjMÂjó™d¼;ÊX"äœ%Jxò¯\½áÔ0C ZåC>¤–eØÚ¨º0^㚺ã…ʶ„úõœ<ÕO›ÜPÒ@ý:œÑ§ñzû¥+ßÚZ+'pëÇvnh;d*§ÁQÏèÓxAÜ»çñJj6wØ¿ÕÙ_WàÀt‘}F#b4òð½¬×e>ÀÐÝЛËû S® ª. ×Ç?£÷ŒÞß,z«·û"bÔ$_-õ! †@­×MÝ+½­;Œj=0*uim×I6W0ÊT]/z»|9oÞ0j–ø C LÕ…á¢WvîépL_{šOY8ÍôŒ>—ÔŽ2‰¼dõÓåüykÏ@yzµyëÉxFŸÆ âÔ•ÏD^ƒhœÛ\Ÿ.AÚ¶DåÔæôŒ>Ä¥s|ÃJ1TS7\ß’ÚþÃõ-9;›ÇÂ/çjž_ ° Ëæø•¢`4ǯä]Á3zÑ{Ö7Ÿ+ÏÔ/Þ˜‘‡»ÁÍZŒsù·î“|CÛôQ9 °ƒ“µx×&ˆ›ï°ŽáJݲ”ï¿ÞQÖáÚ<ï¦{Q‚X: ¦«zºZöP3ynËSUëÂu{Öe[ØYi¯Ýó/ûû^ëîphrÄ£D¥|z»ìĊ̶ؚȾ#>$ÃÐtLÕ…áÚÔ²úþBàÜU9þB mæø ñŒ>}Ø_8 ‘moåóزcúoø8®V}ñ9 Mæ¿Å_8ô8Ìݼð·x‘=å¨_òñ3¿ãù^üóäyÚŸ‘°HÔwñ©Ç2j½Û˜Ÿ’;ÄÇ ÔN Nâ±hyÚØÏÒŸ[«v¶™~èÖóÍÞ+°£Œ%ÒHÎY„gq>_ T3ޱ/0FG—Oƒ¢Ç¢e ¥-Ô·l©};óØ=?@çÎW ¹-°DÉ9K˜ð,Ý>ômq1´¡©›RÛ®”ÑáJ© ‰¤ õ¬Á·¬!‡N=ÿIùòÑ=% äй{f8ÿ:Âqv÷ØGŽ#ãØ&Òö‡/L:£O‘ò.a’mI4®²0e‰4’s–gxþC„'gDÃuÄÐÝ×/j#$áú­lTua¸Qà½gôþfÑ›´Óf_—·ä÷ýú™=„X› 2UÆ‹^©Nå+n=ÃÐÌzùŽ›IÀ0ÊT]/zk7,ÎÄÁ0Mæ}]naÓxC LÕ…á¢7¬Ý6¦ËzÈ1ÁÍí伿ÚV™”C‚ gôi¸´·ìMál„ÂUö¸çõž²p žÑ§á‚8èêRÓŠŒc›+«Ví6HY8´98£Oãqêúùú©Lä<鿾‡´-\ßu£3ú4\­†Ö¦r×ù¬çCÊf Ãà1\wäs¯ LôžåáÏ|rÏo#† å´ø,ÊùBgØâª. =[Li§o‚i¦Ve|Ø<ó‚i¦&ª. ½gø%’ÀÑÝ9†ks¾Ž”ƒ¸9ßH§3ú4\s´O×ï!Çpõ²/Ë e à”©è}/ˆ®S ±õ{–û èá8ÅÜ+½±+¯ç“ÊíÂêbÿÆŸÏD`«»|5’s–0áò…÷íkˆaP]s. µ›z`hG¦êÂxks¿X€œÇÔej7ìGÚŽ´Ê¡'Ûœo!ø×ñ³î¸)²;®|!HöMC[á/¯ÉÉOâsô‚Ì ~‹ 1EtZ;Ú1EÁÙS¦ÔMö Xû§ý¹d‡¦V6ÊŸvÉÜàÕäõüôãØQÆi$ç,aÂ3˾¸/=Ÿm+CY¸õ|xFŸ†Ë÷æQò2k-Àj“Úä-W`mÌX"äœ%Lx&7lÉÉÜ__œ@HýõÅ Tua¸Œ%_ûz>EиŒm)‡¢®€]e,‘FrÎ&õ³ .>'ó¡ÉÜà·x—ÈÞJ;ÜÙÔ ìì/s¶³=_e,‘FrÎ¥ ØÖ®¼wÃá1V£1u%ýpe,‘FrÎ%<{îèÊ\¿µL‡¾°|}º¼° ”4[_ˆgôi¸ pŸ¯žV`g“Ú‡®øX]`GK¤‘œ³D =”‚¶tÅ2’€aKW@Õ…ár˜]h&Æj[JòâÈØQÆi$ç,Q“Aº~@ ±µ£uï¶¹ùv"B íÈT]¯q-ÝÞ;oe‡Ž~Ÿºòæ`3(e àÐÑÃ}­ûŸúE_„Á ·pM}n$—• ¤¬\ÃEgôi´ –‘oj>&¬¦eå-êmpfwÂi$ç,a£„ÇXÆÞ­+¦,<Æi$ç,Q“SÍcѹqÒ†l"9ûî$äl¨ ª. 7 ä&q)_ ƒÍÝ|n|ãC:Ú0„¨J^I¸ˆí½›u†-NÖâ¶8Y¨º0bô&çæS êëk>l¢'˜5y!½\A”èmeçÈù²%"` Ôu£E€Mô®Û'‚ª ãEoëfÇs ˜wøð†Ã4(Ì'·wQ¢·Ïbúmr}ã83ºåò™W¤¬fpFŸÆKuGñ8W×js¹¡mÍM9UלÅ÷:Âq‡×eæ*œç¨ýpÙØ h;sUNsT=£O#ÑÝ“x3Ñ¿îIô2ý¿îI„gôi¸ –¬ãh×d¤bªd^> ‹°)a]¾ùŠª. 7¢äËÛ0 ½óvIq 6ã±`z¯»“{W&zc×N*g y†º´ûk¤ê§a”©º0^ôÖnr,ˆ€é!]/û-lžÜõ²‹"¨º0\ô¨ûb¢e§Êi p&üвwQ‚¸™aFר-©ý6RÖnáÂ3ú4bkÕäDá®òªÙ5¡6ÊÀ)\zFŸ† âºwýš.ïã†Qcîæ3Aö! ¶~T]®3ÌW<µß?v–ã×òðûGô(`‰4’s–(áÉ?mµw´K0µ£k! `Ó¸®å)Pua¸ÆµÛ‡š/&Ê;ÎeÙéŤsYJ¤3úôqãØ]7 ¹ öõƒ²hK¼ãåu)4øýŠ sƒßbcÜBzÍ ª'G7²£¿œ†$‹W`GK¤‘œ³éžáùtxÒì¦ÑÈÁl‘'Fʃ“FÓ}-„‹·ÖìlR+°£Œ%ÒHÎY¢„ÇLAkº™I ]—wQÕ…Ñr˜gãz6®g÷ÿ âßOŸÝÜ3<ÏQà½gôžÑ{Fï½gô¾Îè=ÓÞgŸA|ñÄçˆòŒÞ3zÏèýýFï9x|Ñ&ÈᲆuCY¸… ÏèÓpA|¶ÄggøÕDïi9y6®¿»þíSN»=²ÓnNòµS¶(ÞqÛß莓wÑdnð,©è-uC³s²³¿ÌÏsÝAÿ ì(c‰4’s–(]À3<†‡{7àÐZn(k·¾ÏèÓpà¼tÛ9ZZkv6©yê¦ñxïä ì(c‰4’s–xá¡°¥+’€aKW@Õ…ár˜gãz6®‡èq× :z‹É e àÖÑã}¸ûñÙÍ=ÃóÂŽÏè=£÷ŒÞ3zÏè=£÷,=ƒø âßMŸ³ØçˆòŒÞ3zÏè=£÷ŸA|ñDþœ/bë÷,(>$ÃÖïª w†OËɳqýÝõoŸrÚ ‘vûØíã°]vc¼áimŽìsò.šÌ ~‹¥q è”T³  £·LýÜmÇ /ÿ¶C%<>]õƒ<ûϸü\\¨;l}ŸÝ½YÀ°v|x2†Köö¹[÷‘ߥvf'¹'|%€e,‘FrÎ/<”m¶ÌÄàC0l™ ¨º0\ºòl\ÏÆõì÷ŸÑû½g.öŒË³§Fï½gôžÑ{Fッ%zÏ ÷½gô"Fz^¡ëYÖ›ÝPÖnëYxFŸâsðxFï½gôþ.¢÷zQôÆ©ë‡}n÷ÌB¡òfÖD(i ·há}ú âßw±C¬Ň(X;ó´gxþ¦á»týðbÈ&¶n?þû69Š`èðMÕ…áFgôžÑûÛwlÏüí½gôâDïY:zξ’ >[â3ˆ_GŸ¥ÎgôžÙLÀè=ÛÞsðø[ñ™ >ƒøUñ9”ü’èÍ)ÇaË-ªîÀÎÒüÜçö1öfn`GK¤‘œ³D Ï2tûx¶¨m¶v4oÝ4ïí¨ˆ[;U†k\_ÿö)§ÝÙiWÚÊéNOåŽççÇ;¼Ž]nWÇFˆ7xÔ‡›Dn°‰ül—ÀAž×n¯Ö.ƒÅ<—UWÂs7NG r8pQp/«%¨êBÒ;<£÷K¢·ô]ßO{¿äk_d°x%œ‡êåø`û¼t)•é‚âòÅ÷c¼AUª@è•á÷ð^¿äÙZW:°±ä0ˆóq:²s{چ刈QðÔmçV´¨êBˆ½üÎç/?î]„sb÷Š8Oƒ—y,ƒóœÿk?Û“ IðÒ•;c<™ U JôR7ÏÛœÓâÒžêÃöŠ8÷PÇ :¾äœzß—þ’à¥ë—£âÉ\¨Q¢×wÃÑqËQj,wJg†í2<¨µ0;Ç¢5º<‹Øê=¦©;^AËpx‘ÊUîšÆº3ƒAñ =ªºP¢DÆ¿aés3hÛÜ„¦¹`Wˆ‡nÝŽ¿EUª@èåÎz›ŽIBI³¦é˜ˆ½NÝZêyd»Q&.DÃSžp,çßšª M JôR7æYkîjøæ[ ún9Ë,7 C LÕ…ñ¢7êÌJ]©¶oÛÙt¯R¼Ë³V©(ø]©ÊdŒª.T(Ñ›º£ 36ѬÊí©_üä¢` ¨º0\ô†n¨ë;tó€­™­ù>Ïu#bÛlUF‹^žç/õ5ä1çoË1O%œ§¢ç7Ur·Ô¯çç@|ˆ†‡]’Pu¡ Œ^1Ü&)Òcôj>ÆÑs ÎÙpþ-¨ºP‚D¯ŒeÈË}ö8urïHó”ý(Œæg±ŸE"ŸÙÑH‡.-:6‹¤ åø [s‡S~ñ´uÓºíǼTØ\.ìHa—µ;§QÂ# .¦¼8' eë¶¾Nñ7)œ¿".sø¹ŒŒ/ËÜéœÍ»—ZÒù·p2ª@è­c·kBåÚ·½ìRš—á<ÜÕ Á²wS_vT¸(€8OØÎ>žÌ…*$zy¢>Åóù¬½ Y»ýœ‚æ4Ÿ¦³m¸<åãüÛS°ý·%Rƒ~ª-gRÃX;#Ä©›ÏÉx TÝUŇ xÜË*:(^€'jšjN²™ '»³l߃ ¬ Aq¾¿³NŽª.œh;•¯?zi?ÚÀ>×u„t¦ñÓY´ÈPªO› éHÀ«¬Vòü/=$H„ „“­Z¾¦"Ò¸IŸ…!¢àÔ Ûù· êB½’!ÔõýMVG_–Dì\T]´VîC:ðœ;·cQNå1=3~rŽälç‚ć(x’ÜU]¨?ë³[ûìl×D²'Þ`ØLñ–£odnðìŒ[à0ï›ØÐNTw{ÄËðh£j»EEsâ=ÃöyuÒbú«Wqëe&qQ°zQÕ…Ñ Œöãý¨:­)¹ 6ª6EPôX4çbÔ»0äæúM ç7”4«gŒÎèÓh^2jej?¤î©:©»0:[dµ)R;»²hÎÅgÛû£Ø¹+¯–E ˆ€Õ²ˆª.ŒæcäaPmˆ½jYäè9(zÕ²ÈÑs`4#%[꣪–;è÷<†G[¿§~;èã΂÷ Û/.ÐýE\­b4\ø5«[Œ”}ÍDö â3ˆ__ÑŽH\½‹”Ïù5€›}•}ÎÕH®Ä&ˆòž Ñ£¨\]Œ¤ìÓhæFºxó'6“…º^Ëó ‚·ÎjflÚ›Gƒy¹B¥fEÀfk„ÄØ…$€ 7çäþ9CÆKM‹¯jpäx]! Ð¥¶<žÊ80šë‘¯]M‹=58bôÛ÷F!L>E äj€$eŸFóE6mB]ŽMË7 ·5‡’r5GÒ}Í:Ùdvj}$®>I ‹OQƒsìj•lòqFsP6˜,Ô6Yß¹¦Ûd}H4ÀÔÿäAÃÑ\”Í((&Èf> “Í8|…(Àãðé×hÆá+Œæ¢ä0© ±&1".DªæWwWèÍEÙôÝê‚lÆj™lƇ’F3†œÆ‚v qh43%ÒÅ èpNB¥¾ý·b¨ø&A¡ùg(e“a~¢w>3Mžç@à,o¯ï'S’çÀ`†Ê¦c?$÷8Õ;Éý˜Q€‡†sîÐ Wø¸¡rìô£#[$ï¸ýã–£wuîøã¦Ê¹¿ õ÷ç&,bPò//ÿøç?~÷ò—Ùýõøî7ß~ø‡ïúëïè¿Y?¼üåÛ%_=žŸ/ÍÿšÖ.Û: å"?qðvœŸÈ­tìãÛŽÞëÑS7ÛôƃÇzðÞØ9ø î§" ç.3𱾍„M8¶¶U¾0pC¹·6‡gôi¼–8uSmPèÿ%®fá’âÕEû;ŠÈÕ/LÊ>f#.ƒ`:ÝWd&®žá2¼Ö*î% àj&eŸFsËÞÕ=ÀØ T-°Ã2wSÖ[¡ù_MÎcñ<±Ï˜}VÞ²Ô¯xó¹ù4Ëæjýùõ„JÀͧ‰Ê> çÞ|ñį$ˆ«»­)qs ¯“.?ÝPÒ0ŽaPöi<ñºuG™l<ÀÈÍ1œÛKZÇcÿJÀÍ1ŒÊ> ç#^w-,¡ ±Z†×Y?µãClŽa”õi0q™ˆG }ÀÈÍ4<FõË=e à Ÿj¹9s˜°:UE;0róóÖ­µÇò)i Wû0ѧÑ\Å¥,½^¼º‚‘›…¸´¦>Õ º”5€«‹˜ÎèÓhæâ2ý¼z‹ª‹¸ÜæP·t¾¡¤\Ä ë±pÞâÕ¦ñä Fn.âeëÆñTo(j¯NbP½’xÞb¼xô#71†É§¨Ü\ĨìÓpÞb®cš/ë©æ"ÆzªKI¹¹ˆñŒ> ç-æÅ ó#7±®v8ˆŽhæaôi4Kq›†Ù‚.'€²üË à•²pµÓ}ÍY\†@™M¡3˜¸ÚˆKÒvu%Ñq“²O£ŒÏ>¿¬’³A˜¸º‰ËrïrÖÚï(iWC1)û4œÏ¸|Ÿ{nüÁ•“xÕê²ÃèX£æ!–s\I4G1vÝj&x¸ˆu(hÿi‡)b¸€X¶âmW³$º‚«ƒx[º~h½ÆQ°:ˆQÕ…ÁlÅe©;jÈL\=Ä¥“×ó{n7”4€«˜”}ú°»xž"»÷œDÔ]£É`yÃÇÜ›iÕ冓ñtîø ™)p¨ÇAçýä $®±îLÿ¤£F´ ’ˆO£ÙŸñzk¼R§5;5LUså8 Ý-¢cª§ä<Íe9ö³Žè’$®žÊ±Ô pCI¸º*IÙ§ÑÜ–c¿xßùl¦¶±¯_úÈãõ[ßx2Fs¹•fR'Oä•DÎÊ}í–úå$Ÿ’ß¹:+éŒ>æ·, `z©SŽímêjIÆ…¬`˜Ú›žÎ§ášá^>0JW[åØïêò¸¡¨\m•¤ìÓhfË’?è—!À(I\m•åVǹý&=QÒ®¥|Röi4³%]<Øÿš›ªCk.’†qs ¢²OÃ9 ŸAüBÙáPÍøh`#®v·2€^?TO”4çô¤ìÓh&¸gŸAüZ‚8Y- ¬”ÄÍx¹ïøaI¢¸/QÙ§áì˜cŸ$³%+%q5^Ž}¯D¼¡¤\—¤ìÓhv̱_%)C7%aq^–Ö2ïçí|ˆ€ÕxI²> fLJUßRE+%r3^–ú”¬Þù”5€/|ªåæÌQÂ6n¶ X)‘›ñr̬x]|ÊÀÕxIgôi4;fþém_°R"7ãå8”¼³ªâSÖ®ÆK:£O£Ù1Çaêúy»|«ž¸š/Ký@ßô)j Wû%)û4š-“*v`©$nL¬úm™ÀO&ª^I8[&V§ÁQ‰Xí—X´v! Vï%ªº0š³<7Þí‘›ó²<‘[­ÿù”4«ó’ÎèÓh~L\ôAG%q5_ârÒ % àjÁ$eŸF3f¶ ™­÷r*(Ëœ ^)kW &ѧь™cžAµµ ©’¸Z0óЪ{TÜPÔ@®LRöi4cfé‹Ä(¦JâjÁ‡Þv‚ò)iW &)û4š1³Z4X"73&æË>e àjʤ3ú4š]³èËûÕ5>½—æØóä¬!z ÂbÓ$¥ åÛ,—þìeÐvIX,š¥`RËL7‹E“T]Ì·YºöAÌà¹$®Í2š.uWžJÀÕ¡IÊ>}Ü·9G6–º¾ìm‡>Ì;^Þ>”Ýpôg¢Îƒos‰êÒXëv2f'Th–Ã<ëë:WF+5ë¡ :(œ±d4’óÑï˜#jò¸\–¶[JÀ!V ìÓxAœ»£¼<6®LäfàÌ÷'¯‚ÞPÒnFNTöi8ƒçÜ@l~NPua8g¾v}Gý™ÈÍÍ™¶ë?ñ¨D»d’ˆOÃÙ9¡Ó&!róÂppCI†óâ°äÒxNÄg¿D×|—- ›Y®tðu£j’€asʪ Ã¹çæ¹;:ž±½{àªQwË»¡¤¢Ê>Ä=é"<Q9…«N·îhDå.Uöi¸ –í;êž2äãD®ŽÍq±ÍDo(iÇ&(û4žsYÍ„ŠL俨,÷›Ö£¤Ü›¨ìÓp>ÎÜä“ZઆÍEjû>ãšY$]ÍÀ™Ó’jÖ`ó%p°j3‡¥5pe à Ÿj¹9s˜°õÝv^1›/ƒU³ŒõÝŸ’r³jâ}ÎÀ™×T_Ó$ó%p°jNùOÒi©ö)i 7«&žÑ§á œù>Öýº£&q³jæY¾|높p³j¢²OÃ8óÄa°™ƒ8‘«U³ÌÓdÂJÆ«]T¯$ž³LEëK9dÀDnnMøúå E äfØDeŸ†óq΋¾™MLààØÌ3Œ²°vOY¸96ñŒ> çãÌŸúñêãDnŽÍ–ºÉÔ % àæØDeŸ†óq–>½~‚<˜ÀÁ±9íù¡Ó­ÂJÈͱ‰gôi8gNnå›MäÁDnŽÍœÅííþšIÁ°Ù5QÖ§áLœ©¬¤4 &r³kNK·Hcñ)j 7»&*û4œ‰3'ʲI-0ƒ]3?f…8”4›]ÏèÓp&Î|£òi ób"<-›ù«”Gì@€‡g•. –‰Áƒ‰Xýš¸$ìB¬~MTua4gùÝÅÞ‹Läf×Ì’ä5OŸ’p³k¢²O7q®‘…«}¡„L™7|êgn\NfMйão0qn‘C½•–X·•B7!rónC·-“´E’pó¢²OÃ9·œ‰¤úf-8„kêJó JÀ!\ ìÓpAÜó̹~—,™ÈÍÀ¹mº”rCQ¹8QÙ§álû¬&`²d"7çžœñÜ+䆒p3p¢²OÃÙ:á1"#p°ÍÁêSÖn¶9<£OÙéÊ‹òÃÙù“%88÷¤oûø”5€›ÏèÓp¶ÎÜZ’|F°iE¡ͭ»ôù7”4C›ƒ3ú4^K\òtD_´5[&rópîSWJÓvKI¸Ù8QÙ§ÑÜS¿ØûMàÓ$®vΩõã>7”4€«¹“”}Îò™GЩ~–‚œ†ÈÍ—¸•7ç«oا¨|‰ ìÓxnE|ä(ˆÀ!\{·ÖíÐn(Ñ8†Ë”}/ˆ9!>–ã[Ã!rsÖmÉv‹ö)i7g*û4œß.·Yu†»šeÑ鎒p”È:(\àöÞÒ¼uä¨ÅÒŸRø€[¬PÙ§ƒ(•krj"7_g‹¼¬xCQ8ø:AÙ§ñÜž[Ùžt¾î¸‰Ü|9,Î^žHIcñöçDeŸ†s{æN|–/Àƒa±z;ËàP;|¢`sw¢¬O£™>÷YýÒdØöΜ¼-õËÊ>e à Ÿj¹9s˜°èH0Ã&p°wBñ)i 7{'žÑ§áLŸyR*v82l{gÎyk™ô†²p³wâ}ÎôYfö²³6‘›½³LÖöCêDI¸Ù;QÙ§áLŸ%ç8k"lØDnöÎÍ> CIÃxµx‚ê•Ä3}æþJ÷ŸGÃ&r³wæu–ê¼OI¸Ù;QÙ§áLŸÛØõuƒ ›ÀÁÞ¹æ©ërnÊîSÒ@nöN<£OÙ>·Uj!lØDnöÎü`®×-=‘’p³w¢²OÙ>±¶„†Mà`•OI¹Ù;ñŒ> gúÜÀÍ–MäæïÌ|ü†’psx¢²OÃù>¡œBžMäæðÜŠÉ«¦Í>% àæðDeŸ†ó}®{ “lnžMààð\gý0ºOY¸9<ñŒ> çûÌœ¾‡§öM„§Ë3´«}<®%z ÂÃæ‰JË÷™fq° m±Z÷ÀfÄi˜¥ Ê>Î;^Þ¨à G'êÜñÇ}ŸK:Ô«$yd7$®æÄiHºPrCI¸šIÙ§Ñ,‹Ï ~‰ –XHz žMâêðœòج‰·OI¸:% ªBT'cSWðh4h“¢©³IÒêZh“þy”4¨Ö¸ÎJþMâêö¤0ù”4€«Û“”}ÍÚ´ õo6-£º=›¶æPÖ®nO:£O£y@›¬Oý›ÄÕíIañ)iPþ]ÝžM®îÑhÐ6/Ó…á&#¬ËÈMFx¥¬AMQ3tx4š´Y‰Wÿ&qu{Òš»OI¸º=IÙ§Ñ< M £þMâêö¤¶åSÒ :mµ$65]Fó€6ºú7›¥º=›Å¡¬ÁK544‹C£y@›‡k»ÔNÇ'=™Wb,–ORº€PÐ& ý\°ºg8t P"xÚ=›<ÐÁ< í$Jü›M´É/õm% žÌsŒv2çЇ= ËÙ˜8'ý 0y:ï8lMuÇÉë :wü Ð1r¨·œ)×};‰›Qqëõ{7”4€›Q•}ξø â"ú7‘›ÛÃâSÒnnOTöi8è¼H:ÇþMäæöœ§në»G>% àæöDeŸ†ó€ÂÅ“koÊ[â— "ù7‘›Û[¢OI¸¹=QÙ§á< xñèßä ŠÛ“ƒèQÒ  ŠÛ“ƒèÑpP¼x´òM‰Q‘ÃåQÒ€‡ßŒŠØQ¸4ž}ñÄ/<:£k¹yì0,>% àæ±CeŸ†sÞ=ƒø âWDòo"7·'f~>% ãàöeŸÆó€âÅ£“ƒ(nO¢GI¸¹=QÙ§á< xñ`áäiEµ{ò Ä(@­3]ÇàÍÊÕ.óo·'Ôµ|ÊXk ]7gŽ6óorØÄíÉas(kPQQÜž\&ôh8(_¼ù71ˆæöÄ º”5(ˆâöä z4œ§èßDnnOœˆø”4¨ !nO®+x4œ”S4óor’&nONÿ çå[2ÿ&rs{bX|JÀÍí‰Ê> çå`™¹¹=1,>% Z¡·'¯Ð{4œ.žü›ÀÁí añ)k7·'žÑ§á< üpU+g3#»ØAZb<,Ÿ¨t±< Ø¬À‰XížØØ\ˆ€Õ.Œæmºkõor$nOîÛM,cù”4€›O•}νÉÙ˜9/9Ÿ&gz% *oµcë…ÄsorÝœ—Èͧ‰aò)i7Ÿ&*û4œ{“Û„9/¹eˆO“ÛšCY¸ù4ñŒ> çÞäÏœ—Èͧ‰añ)iPª->MNË=ͽÙ$bÎê°¹4›äïº:L¸’¼_‚]Ͷ™r®ßGZB–KâjÐLyÖZ{À;ŠÈÕ IÊ>fÛl‚¥–KâjФ°ø5«A“”}Ͷ‰–KäfÐİø”4«A“ÎèÓh¶Íæá:Ý—“&5ª+Ñ—&)]@(Û&5+s]‡&56‚bqh’ª ƒÙ6yTÇ%bµgâ@êBÀ•á:¯àÕ^>îל#›§¡ÛÎVÂþË;¾ 6¾áèËD;Þø5 ƒ°HÆÒ!\Ê{{S³ü<À#ÞTß çÃÝÜ”ò€7•ûø)OesSÆÞ”=;|SÍ3õ=ßQsâésüòòþãw/É÷ð¯¿þáßýæÛÿðýOýýã7Ç—¿|û!­[·-ù2æ/ýöC)¯ží½œïGîÑyÞ–[Õ¾®ŸwôÜMã8. Ž?_î†g÷¤¹W>#üY— çAñKä©[ŠÅboŒøÈ͵Ÿû‡j·¼£¤ÜŒû¨ìÓh~~¼xôâWç>†å†’puO£ùùS‰ÅvX÷ÈÜüÒ)O™ûò7·”5€«_šÎèÓp.jnqêŧÇKûô€º”5¨…Vç~Óæ<ÍÏ:µ"àÐæ`¨ð)k·6‡gôi¼–hùñ‘›yÐJÀÍ¿Ê> gëÇ‹G[>Q<üD’QlüD†s÷s~fþräfFÇÌϧ¤¿ùѱ£pi8›ú3ˆ_$ˆ£LÈM\½Ôå¡;lEã-E äê¥&eŸFsX?ƒø â×DÈÏÀ§O\]ý”ùù”4Œ›«•}ÎëO>ý&ˆÕÕßÑ£¤\]ý¤ìÓh^ºx³ê7ÓŠÓÖßÌ@ˆÔ:Óu ¾¡Ñ¼þ\í2¯>p0öÃDا¬Õ±¦Ðusæ0aƒiZöƒ¿&>e šÌˆÅŸ'> çüç`Î}l{fóǶçR֠ʬ8ý¹ÖêÑh/ÐŃyŸ¸Zý),>% àjõ'eŸF{€*­`Þ'®VªÀú”4¨2[†®³6$Ü tñ`Þ'®V “OI¸ZýIÙ§Ñ^h*žjÞ§Z€Zý©nàRÖ®V:£O£½Ð,k¨yŸ¸ZýéÁô)iW«?)û4œªÉËta¸Éë2r“^)kÐ@#†:<î=ÌËÐÃÜÿ˜ñù”4hm@ÿ\í÷h¸÷8XæáGnŽ ‹OIƒÖÄñÏÕ~†{€;tóðóÀ"ŽXÊ<°TCC3°84Ü{sîÛÓ±4 v~„§ëVŸ¯Gì@€‡í•. Ö{K1}Ùø«å.Ýú>ÑöÍA±ZþQÕ…ÑÞhºkõñs$¦îÛ3pKßõçÜ $ú âEÞm›1Cß@@<ˆMU]8{¥LiÏ95 ØÂ¶a9âBjvB­‰™¦Ç¢5»¹ çžÇ†}©74ßÛy“C·œë“>ƒ£N2ùEIÊñQ—d1¢ü櫼iƒx–…³bTØ—þ¢à^¾^„ª.T(Ñë;ÉövyîhN5–j©ZºZ«ò t‘î Îã1=:HØ–AÜj¥ã/“Íã}Äù–N£tµï‚âÔ¥æT]¨Q¢GÜáª/Cìñ_c3Ä:xˆ=Ê~c3Ä:P‚D/÷ÕÛ¹8^ú )”N2*Œb)òm´LjŽvŠÓ££„-ågïxtèÆjˆún© .ƒ£ZˆLÑcáÂ6jÕDÀ9ŒgFª.T(уS¶0å7ßÒtþ'¦­.DÃëÞÍç¼ T]hA¢—³úöëgBç„ú•hžqŸï‰mòÖ™Ïìh¤sw.ø¡¢Çäè(aËÏ^Ýöûy 0"ÔÄÖg4J(µ$]l”˜¥À?äÞi>K=¯HGy1•&qöü>„ãçI@ÍÎLÔcvx”È‘{cêÛl©†68È=R-l¹BøÙWöÀþºc„œeR¯¦ÿ< ƒd#·ß™ܼ$ð‰0¯}à0ï›XÀÕPýO{êl©ÿÊà`…ê~2=EóC=#öæG9Y9|‡ˆÕ£XV¡ëF]>DÀêQDUF3.>ÛÛ[#V:ýõZ ,ùàÐo²½Ï Äš’¬Oƒ%ŠôË«í¨:¡yy 6ªöDPôX4Ç"þäX®£¦ µ=jL.% äZå£3ú4Z µ"V«"öÿ.DÀjUDUFó/ò8§öC¾¥jUä@9h¤­VEiÍ¿Hý‘túÅr}™ƒàPgÅoãìEsà=ãõ‹òu}W‹ >E ÎMªK¬ÉM<Í<ö â3ˆ_aÁ†ØÞÔéYlÃåPÔ@®¶ERöi47#]<¸‰«u‘ÂâSÔàdºº›ôØ¡áLM»PSbÛ2NSÛæŠD51R]ÎÛÈI²®‚#Öṡ]ˆ4ó¨“džy80ÚB:^;˜›±"âB¬ÆF<™ £¹ù—W³"·½jlä¶ç@ ¶WÜöÍíÈsNµ-r+©ë»Üžˆ4ë=3žô^Y4d[]ñ÷4ïá@p%tlS>­£tSuh4Kß3xÏré×ÄçRÇ3éûÛEÌÍ-yŠQ€Þåš¡¸0š{’oHÍ|KÕ(Ér 6£$¨º0œ{’ºm3@¶³ûÓúÓ®‹]’T]ÌD uõÙ)Ýëð@%ù š½Ò½Ž ç±`#ýÚà$®fIjE>E àf˜DeŸ†3Rb‡>Hîòªg’»<¢uyÕ3É]Þ>n¤\‡À¿òñ9Ù¬‘w<íö²Û GÏ$êÜñ7˜)ÇСÖûG¿aµfåA·N¿¡(aXZ¨ëÂpÆ­gü~aüfùÞ%‰««²|rª/ÜPÒ®ÆJRöi4¿å0-ÝêB BlÍmåcNw% [{]†k„i´¢€X«Sž‹á;ˆ'üŽl8äÑh‰æ4u{}£”ÄÕmY>ÅQ¿N~GI¸z.I٧ἘШ0ˆ Ãʈش\JÈ­Œˆgôi¸ââX>L2Ëk°ê¥$®ÆËÒé÷C-zû”4€«÷’”}Í’Y.¾~ô,•ÄÕY¾k'»ÝPÒ®LRöi4gfé·t[̆Ú-³#íÁé@¬CTua8ßá3z¿(zk7/n|nÈÍ—G͵>q7”4€›+•}Î+÷ â3ˆ_Gg5¦±ã¹ù3ÓÚ Ã¹ŠÈÍŸ‰Ê> çÚL»nòMŽKäæÏ,Ÿg¬ïþßPÒ0þLPöi<×fÚäcì¸DnþÌTva«+,WFÇ g&hú4œ_s'ÙPWÞë*}©EË.7”$€ëB= »0Úê}¹öuÑí©å¹ù3KPd ʧ¬\-štFŸFsn–‹¯?;9/‰«Msôc¼w5«S“”}ÍÀY&ëzLâêÖ,·*Õ…JÀűIÂ. çãL½lÂFnBÃÕv8-¶«Û…СÈÍrçqa8â´ËGÆ›Û7.š¥ ê>¸E ÏäÓpÁKeQH÷‡2«q,¨ÚÐëS.³‡‚*œÑ§áʬ)·–­Ì§šÀº6’otÇå¢à ?1­²>¶`Rr0Y±m3Aáœô]öÅ$Ú¦‚— /IÙ§ñ’Á<øÙžÔŠI\}›Ç zôZ·”4€«u“”}ÍÑy,jˆå™ÄÕ¾™g«Ýl»øx”4Œ›ƒ•}ÏØ™»-©³ /±z8ËÑî–I«‡U]ÌØY–y`³q}ê¨1¦N†háÑFmÄIFErVtf5gÎî\@Çl›*ä±pFÎÒMof0P#&qum€Ì¬|JÆÍ¸‰Ê>}ƒŸsŠl2œÁ †þÌ;nÿ¸åäÛ;þ?gº õ—û zÿÍП#/ÝuI#ê×È—nšÒ¾ Ÿü”y_?e^º±uOû8:Gÿì·Ì×9r“Ú7óöa¹áã¸Z’véé€ÎC“Z‡zòÀ°\¾#MX}„#—zl>^=Ò'¦QÂ…ÑŒ„ÏP½!T²äƒ–] j»Et¬@uõ‚œÇ¢ù|Ç~ÆôC[ bkOýЭREö)J¶æº. ׿úÅy‡ ©Ì*Æ~¼¼E† ¯ï‘¡¤ ƒÍ4JóÐÊ2˜s‰›•w_s¬+iEƒ/rµò’²O£|Ëï¿ýQ°Äª1r«1½ZÙ\È †µÀL§ói´²s¥2DÎ\âêãû½+ßèúE äêã%eŸFs÷–¤A¿ìÎ\âêã-·:Îí‡ä‰’põñ’²O£¹{éâÍ^ÚÜS78XDÃjEEUFó§>£÷K³ÀÁV¹ÕI\Ý“eȼ~]ž(i ÎWãIÙ§Ñ<•Ï >ƒøµqÒŠ:s‰›wßñ›Ew/rõñ’²O£¹{Ç>åYét|½¹ÄÕÇ;ö½~Áð†’†qóñ¢²Où{Ç~톥NDÀK\¼¥½ÈËÃ7”4Œ››•}Îã;¹k«¯£¢-ƒ¸š8J1j\†õ”4€«‰ƒ”}ÍÚ1–EYY¸.rsôŽe±·ú9|ÊÀÕÑKgôi4Ÿoþém7ðèWGï8äÙ˜8|JÀÕÑKÊ>æó‡Òµm—ÌWGo)"¤ý|Ïㆢr±ô’° £ù|±h‡–ӦķÎm)°!dWE®ÆT:“O£ÙU›â´ÅnOŠpqúø@*bK„¨2}…ᢖŸï3ôȱªš³äZúó)[[]ÏèÓpÕV\þÁÀ¶6ëG.DÀ°:²>¶hòÌ¿D&8Ú»0`Ð%®vÞ<–Ú«">E äjç%eŸF3ù–nhŸ¦ËW7ÏY¥»¿£¤aÜ켨ìÓp&_LcÁ£KXü¼˜û‹Ÿ—T]Ìä[Jó}µzãX€ØÆ ›uùÀ6l ¬Oà &ƒ¾B®]âjï-”Z½£¨ܬ¾¨ìÓpàÒáfAPû.q5û–1v™ô]V’†q3û¢²Oß`^#›Ëõ~ò_ÞñœDëTð†£/uîøüš[äP§œï­3û»”™,å±½Ù+ÐL`"w%á–]æk_åAC'rur–¨ÈúÜ % àæäDeŸ†ówÎI§"T0åÅÝÞÛ¥¬ÜÊ‹xFŸ†+:΃l(MîLÀfåÌ}[}Þ‡(Ø|œ êÂpÞÎ|íúBú2‘›‹3m×âQi#Ã&Šø4œúlô"žœ!‡½?n¨çG£+ gD|FïEo•}ØÈ÷ØLr¥K¯¯³» ›CT]Î57ÏÝ‘TŒí݇Pº1õ % à-PöiÄ –ׇë*:Q9…kª{»ÝÐ&ˆÊ)\ªìÓpAÌ™—ìRNþMäêÔ—±+ëvµíQÒnNMTöi8ÿ沚ù½—ÈÍ©¹Lfkõ)i§&(û4ž³ÌÒesUÄæÓÌA‘}Í\HŠÁ¤iª.ŒgÜ,{ÐÚv”¶ÔŽÜæÓ ÝÛ % à¶0Ê> ·\Ÿún;Êpé8X4Kq¾¾…ãSÒ@nM<£OÃ7ËfNõM2]"7‹fÙ$ªn(zCQ¹Y4Q٧ጛ©ìÊÖ~âþ•¹Y4Ó$…’;JÀÕ£‰Â. gÜÌ3‰A¦è!^͆so_»>¸y ñL> gA,SSØÀÌ`¼† ¿^y!t,rœÉ§ñ‚·èËØ\5ŽEÓ±+‹@÷”5€CÑÎèÓx¥ÔE÷„§5 À¶þ1ÚVe.DÀ°ü²>¶(’ÊuÖï¿[2ÜR¿ò‰µdL95CêÊ>—¦nžfÉ,Ì{‰ÜœšIŠx7 ›Me}μ™ÊúÙ*›Îšñ¹Ù4ËèÖ„<ŠÀÁ¦ Ê>gÞœÝÞ½—ˆÕ§™6M;|ˆÕ§‰ª.ŒfÞÌw¹µAÀ@€X4wSÝâ܇(ØÆ ”õi´‘WdÑx‰Ülš¸ÖëSÒ06MPöi<ófiö•k3^"7›fšuïJÆÁ¦ Ê>}ƒysì(\—n¬ß#3æ ŸúÙ†›N&Mйã›7·>r¨VÝZ l\ˆÍó•ÇaùHÞ E Ãfú]†s‚mk7Ö/­Ñ͆HM]Éh>AQÂ0„Êt].~{ù,Évl`AVLäfÜ,O夯v{5›q•}ÎιϮ!±5·}èŠ÷÷% [{]†k„øTAºˆXSK|,]ˆ€-³DYŸFË7ËÛñƒŽfÅDnÆÍ=é+=7”4€›q•}ÎÎYêõuÂAõCàPm,žLe\JÈ­Úˆgôi¸ä¾t»}¯Òì˜ÈÍ»¹OÝ4Õ>˧¤Ü웨ìÓh®Î©_ì&ðgWçÔç'M§|JÀÕÔIÊ> gõÌ#§|o ½†ˆÕ—X–ŒÅ-ìž%ýBœúAÕ…áÌŠø¬aô[ ön­{ ù£geª. ½œø+ʭѹ9êr·¥ûAû”4€›£•}Îg—›Š,ÃÝ „@ÍÝ\÷Jº¡$%² ¸½·„o9Ê>QyC)|À-V¨ìÓˆA„Rµ94‘›Ÿ3‡E^F¼¡¨Üüœ¨ìÓp.Ïm—Ô‹šÈÍÏY* ×½;‘’ÆâíÇ Ê>çòÌø8„iíî=/xcך¹A¡Õ8–T7)êÝP.´‡’*œÑ§á ­yà›¯&b\Y/;x"ä%“õº-'Êú4Ü’ ™!™n©V³|ŠÈ!õ£òµGÃ%„ø5Ъ‰Ü|ùy[ä5Ÿ’psv¢²OÃù=¡¤B^MäæìÜ&)ÏßQÒ0ÎN,â¸4žß3ßGÚÛÈ®‰X­¹¯šk–ìC¬ÖNTua4¿§ùÚx,¬ãFþ¯Õ¾¹å@@ ÃÈú4Ú`’{1¯W¹9;óíiʧ¤aœ ìÓx~Ïâ2›y5‘›³³ ò6éSÔÎNPöéã~ÏmlBœ†YŠöìß¼ãåý «J¸}¨sÇßà÷C‡zíöÓò†>/Âj ›†¤+(7% «+ u]Í*öŒß/Œ_š-U¯&quvNiÀ”Ý£¤1`Ê^¤ìÓh~OºxhAˆ­¹aT|І­½® Ã5B|ª,]$,©%=–.D„ëÐ5³$YŸË7›ß^½šÄÕÙIMͧ¤\¤ìÓh~OlXB¤†¡GjZ.eä8;éŒ>V†l† õjWg'µ-Ÿ’uœµ¬Ût² ç÷ä±Ð¼š|Sâìäpy”4hLg'Éæ÷lz(øžêðÁÁr Àˆ,æD‘=ͱøŒÞÌgÔ-G\½u4”ø”4’ã­krFsÜ=ƒø âWDðm¶7uº<Ûp9”4€«Ë“”}ÍûI¾Mâêò¤°ø”4(í®.Ï&‘vh8ïgÓ.Ô·Ù¶ŒÓ¼Õ¶9‡’Q]žD—†ó~6i´.Ó×E}Jd|J4Gѹ5ÍQ<m©Ÿ.|›ÈÍå‰añ)kP¢º<›b†G£y?› ¾Í¦%V—gÓ=Jԫ˳i‰æýlæ$êÛlÚKuy6mË£¤A³åþ:3qa4ïg[h]±ù4+ÒZÉ…ð±\’•œ«¬f_|ïYtýz‚ø\>y&„óFˆ¾Mâêò¤®Ð§¤\]ž¤ìÓhÞÏ&µPßfÓ^ªË³i[% ZJ®.Ïf-١἟ԗ›u³-œ\S9¸B,6ORua0ïçs0ù‚­|›ÄÕåImʧ¤aÜ\ž¨ìÓpÞÏÆH ¾Í¦¬.Ϧô(iP?X]žM?èÐ7x?§È†Ä9Ùg€ÑËyÇa{ª;NOйãoð~¦È¡.˜á²Q'a3ˆå£~7§(aØb ëÂp¶±gü¾\üз‰Ü\ž*Ÿ’psy¢²OÃy?ç¥ÛäÓ^Ђ[s›'ñÊÝQ”0lí t]®â AºˆXSKŒˆ Q°e–(ëÓhù&ÿöæÛDn.Olj>% àæòDeŸ†ó~ÂÅS †±i¹”5€[ÁÏèÓpeHlèÛDn.Ol[>% ê8ÅåɬGÃy?ñâÑ·É7%.O—GI¸¹ çýÄ‹Gß&rsybX|J”v‹Ë“i‡Æó~r»0ßfÓ2ªË³is% ¢¹<1ˆ.çýäÒ–-Ó#·E},bù”4¨Â(sk®Fz4ÜR?^<ú6ƒËÂâSÖn.O<£OÃy?¹˜o“[¢¸<¹%z”4¨%ŠË“[¢GÃy?yNb¾M.~‰Ë“‹_% š-_s†ó~6…ÖÕ›«Y‘§uN=vuÆd0*6UV‡†³/>ƒ÷,º~5A|.Ÿ<¿}Ñ·ÙÜ”›µx”4h!yq²Ÿ†ó~ò-™o“oJ\ž.’ùÄåɆ‡Æó~ÂÅ£u±ÚDÀjóDUFó~bƒ€±±Žؤ\ˆ€mØ@YŸLÈ·‰Ü\žØ¦|JÆÁå Ê>çýdG•ù6¹—'÷ƒ% êÅåÉý Cßàýœ#÷Ü ÏÚ {9oxG›ÔÜpòx‚΃÷s êÔïÝu»?¤jKý\}^7Wªæ0ÐôX4¿Ø3p_ p`ÔD¬®N ’ IÀ°Z:QÕ…álžûÜ­%ÞÙ£‰Ø ¹?«A»£(aØ ëÂh­n2CÄšEbD\ˆ€-‰DYŸFK-ù·7‹&r3tbSó)i7C'*û4œÍ.žª…Ø0¬¶ˆMË¥¬Üj‹xFŸF«8ò€¡MÄjçıÁ…$€£uõrò¸îÀhþN՚ɷT}œ(’ŽÂÕÄÉ£°£;ñÚÍXÈw4ÕD Ãtex´¥~b@ÄÔÏaÑ<‰Ï°}‰œÅÌoÈÍ*‡Ã…OIƒò±ÊqÞâÑpºgŸAüú‚ˆ6Ìæ¦ªi³ —CI¸™6Q٧ᬜxñhÃDn¦M ‹OIƒRk1mr²ìÐxVNnfÃlZF5m6mΡ¤A4Ó&ѥᬜœ2ë¢;b]¡ÇÆ…$€ó:uæyˆ£-Ù㵃ý°y5!".dÃjÔÄ“¹0šy“yõ]rÛ«&Mn{$l{Õ¡ÉmÏá\›XCBÇ%ײğɵ,’p5h¢° ù6›ºéê ÃÕfÈÅ=§¼º:Ã/X ›¢©CßÁ{ÖP¿š >WCž¹ß¿sôÆ<‹Šßˆ­–ÄÕ˜™†]îr5f’²O£Ù5›[R«esSÕ˜Ù„Ë£¨ÜŒ™¨ìÓpvM¼xp[g&Ň €Xœ™¤êÂ`vMj6–ƒš” A±Ž$ëÓh£þö`µ$®ÆLjS>E àfÌDeŸ†³k²#J–Í5²yp$‘aßå_›ÆÜpôc¢ÎƒOs‹ê´tSÉW6ö "6oa»buûE Ãæ/]Fó}=ã÷KõÒQîòv²¹.‘›E3? Ã¤»„y”4€›K•}ͼI-±57ŒŠOQ°µ7Ðua¼F¸I¾Gy"bÍ)§œZëtQ°¥”(ëÓh‰&ÿöj¼$®6Mjj>% àjÓ$eŸF3ob/ŽECêòµÄH£ƒKY¸–éŒ>VxħˆÌ—ÈÍ© Ïç % àfÖDeŸ†ópâÅ£“oJ ›.’pól¢²OÃY91)[!bu bèB€_MˆØGx0š5ñ½_½QòZ²ÂWã\yÌŽRÅxKQ¹çHÙ§ÑìtÏ >ƒøµú'0eW 'uq>% àjá$eŸF3vÒŃ)“¸Z8),>% J»«…³I¤ÎØÙ´ 5e¶-ã´kµmΡ¤AT 'Ñ¥ñŒ\Ú²Åyä¶’ó_Ÿ’wtnM… †[ãǹú3ƒ™f>e àæçÄ3ú4œÍ“[€Ù4¹%Ч“[¢GIƒZ¢Ø:¹%z4šÛ³©«S³)~U_gSüò(iP»æ2\Àv`4·g[hÓ!=\‡=‘Í ác¹$[Gð¦ÊêÐh†ÅgðžEׯ¨>—Ož áߺ’a“‹Öbï䢵GIƒŠÖbï䢵GÙ>ù–̰É7%öN—GIžf³wâsëÒx¦OìËÁ³Ù”ÎG®©\! V'ªº0šésÎÓ‚RŸÛx,@¬ãÆÜçf2öìEˆ€mØ@YŸFL–A¦flØDnöÎ9‡í\𸣨ì ìÓx¦OìдÉý 8<¹ô(iP?(&OîúïçÙ8vërx…Çq•x>ÞáRA=ÇÝ<ì¹Éî%•!‘ "?ä½äyíöóÛõã0æña,­ñ•pªƒQî §sŽâ3<p/m5]¨Aú†gì>?vy èƒH¾ö©‹Ò¹f+sNÊÏ>Ðgv4Ò¾[æò—¨è19:HØÊ°{Ìór5ÊøòJ8)‡?¦4¤í&n îetAUª@”èÍÝ8Ÿ?ü8t[m5s²W†Šys‘j°¼S²!Ps%^)OÃŽ©Ü8.²öûJx—ÅßœT×2à DÀ¹·¥;TUª@”èõÝpô7ågïÏ»xE:í#OÑÎLÚ#p¤Ñaë–b$L æ1;:HÈòLa“{œÅ@øJ8ObO§GîˆÆ3A» €xû ªºP¢DƵœöÎ5¡@œ§š;ÀXéBÜïݺ ª.4 ÑËÝô6½ß<` ÔØužàC0lUÆ‹^êŠeÚš›lʉØYS¹(`eª.Œ½Q&÷%©Ú¤@€xî†ZMØ%ÿ¿ €¸—‡U]¨Q¢7u‡?pl¢X•ÛÓ‘DÜBlU†‹Þ …:¾yÀÖÌÖ|ŸÇÒ Ä¶Øª.Œ½4wË9'-Y+ÔG /ÝžêÛï¹=¥ó>]ˆ€sov”cIÕ…)Zu®=?Bç µÑ«Ï GÏ(xèŽ1•åB½26ž¦Ñò0m½Í0OyözL òÓØŸ+j7çYEšdV!ª.4 Ñ[s¯sLœòt)õßWcy4,΋íeY»:¿r©°_¥„,bWb‰Õ²É›;j±Ï¿{7-s7¦srïA¼vC”=ñd.T Ñ[GyaìËbC]ÅœÄZk“»8›}ˆˆs8 e°Å“¹P‚D/ÏÝçc¢Pßðx²ÊÛ9óßÏþèâ±€ó=Íüˆ`ûo=,J¤ùäWÛke.÷ñûùêË ÄV™U†+×AŠ^…µŒy­ƒôP€Z 65+§s-«>2¯ç¿ydr^•ä9s! 8§µK_pÚ/ÿÒC‚Dê9´ÖØÖe¬JäClë2 êÂh‹5%78×ó)Ï2j ÙÐ-g¹çâñ†-/3QÅËÖ¦n•òØœ¯ã(ȾÞr"ZÆÉR±¤¾æBDÀ¹žýªºP‚D/gÛ馡T°¥µ)ÿÔ»=ˆˆ5­Å“¹0\®»ÈBVY}ªæŽWº’•GúÎÐ DÀS7Ÿ«Z¨êBˆ=ÙœáH9dã* {7žÿ™V±ËÜ@8qÎ@Ògõ˜%rfê( *çH¶’’Šƒ XE\H€W±ÙáÉ\¨?ë¼;ïŽW,oð‡‡úrÆ''£ÉÜà·ÇÀaÎw?hOMv@ÅŽ·'µW85ªV<ÐóX4wÞ3hŸó@'-~€)©ØË.BgÓgp4P±/¢¢Ç‚YíÇ9.P[rmTç è±hÓãÒñ«W]‹NDkujÈiðx–â|fG•*z,XÕ ~q¨pÕb(´!áÑFµ Š‹Vm~qõ$¯îEj[Ãã±Å©ƒ‘ÚœKÃ9yPc"b51b§ïB¬&FTua4g#ߚë‘ #âB0lF2Pua8wåTzï”ÍÕ0Q:wex´R‹‘)zì¶¿°Q7 ~0âj£Á§¨\ýc¤ìÓh¶²gŸAü ƒEâêf¤°ø58¸ÕÐØ„Ë£Ñ|ŽMš¬>Å&ˆÕÔØÑ£¨Á©uõ56ɲG£Ù›‡KíŠÍMUoc.¢ÏCª¡™‡84œë‘‹Gº,Îém]Bç¤Ù(™´®¡c&íÁp+ëvídcÄûTË#FÄ,X-x2FóAb˜`i—D]æfv…$X—ñd.Œ¶6Ì“]54r¡š¹‚à@à§üt4ýÁFóF6#­Öîˆk† Ÿ¢§7µÚ×$, ^|Öœß6ô=W“$ħ¨\í’¤ìÓhfÊfV K=Íd®. 5“9¢g…uq¨Éó<mÑè™ý}©ül‘œTT %§*DÀj¡DUFóUrö ¶HÄj¡ÄfæB¬JTua4_%v;˜ûRŸ®‰2 .% äš+Ó}-…†ª:˜#ªª÷㪉=ÍWÙæ)âŒlÒ´j£l:¢F“לVÊ6Sqh4‹e³ª(Éf]ñ›ÕÊ $z«Ñ‡^>n±œ{ÿ†QwzeÓäO»½éæsrS‚΋Í2…µ~=|ÄÅ"˜ÿŸì{I¸úI×§ÑüƒÏ~æëhb.JÂb¸òìm’wR\ˆ€ÅsIª. æÄ¦Ež#·Éô”g…âH÷)i·É4*û4Ú{H“ídU.¤R›öîø¾Ñ³£j= =­F6MÝ^_³¡Ú*r«ÄN¹±Lu»*Ÿ’p«Ä¢²OÃÕgù÷7—%rqdbKóíÏü˜Ø]Î¥9Œe—õùÜD\–ÄÕ’Yúú~¨óŸ’pue’²O£™5ËÅ×åvò¾WŸÜŸ=ÝXȧ¤aÜÜr¨ìÓx.ºÉßÌ“8„ËÛΓ(ÑÛЕ}ú âßg×î(•6»#7¿\?×s½ùŽ’póË¡²OùèžA|ñëâÜÛ+ÀèÅDnÎÍ´vÃpîvCQ¹97QÙ§áüœi×mÂÉ‹‰Üœ›i‘2ø% àæÜDeŸ†ós¦œäÖQ‘¼˜È͹™ÊÎmõF¯ŒŽ žMÐôi8'çã°_×òë²})Hë&>% ã¶rÂ. ·œ_®]VFÑŒ œ›%(²S›K àjÞ¤3ú4š§³\|ý<(¯)‡è!÷W[ÝÏ¥¼¶ ÜV ñŒ>¶.]æuª@ÖLâêã,·:–¸î)iW+')û4œÃ3õ²cÿC¥pÑmàn(Õ[¥„]®z8íݸè—c ö¬T«Ôs·žK>ƒ£j•=­rFénØ™‰Ü|œ“~¨ùŽ¢róq¢²Où;Sn'Ûqżl„Ü™ò­æ?[>AI¸-2¡²OÃ-=•dÌt9%´%]Ìþ.{imsÂË&™¨ìÓ€Yá"† 2iWGç1º×-% àjê$eŸFózk›~5I½šÄÕØ9äsœOI¸z;IÙ§á,Ÿ¹ßJ³c×It*.[l"% ä–Dã}/µÎ³}ÝõD]›ˆÕàY—du! V'ªº0œó3§e–Á¨gÓ¨ù;s¢ç:n®ûê‹¡Ó„<ÍâYºì­ú Т‰ÜüœÇ``S0‡²pµtÒ}ú¸ÓsŽl?œÍµFÎÍ;¾•þ¯~÷Ççìè4;þ§ç9ÔËÚ]÷wªnÄ%O‹W]Ùw Ü̈¦ê±pöÄgè>?t‹}Œ™ˆÕĹŒÝ:Õù‡ Q°š8QÕ…ÑœúÃÓÄØ¨M¢¡1ÝPRn“hÓõX¸iõšdõ+[H¥¶–ï¡Í€ã*ÒÒy,Z9,ÿÐ2[ "*r+¹.“Ã>% àVsEeŸ†+Å–·zªaŸŒ˜ÈÅ´¹7@œ,› êÓxFÎÜRê9›0‘›e3gqµÀrGQ¹Y6Q٧ጜyÄ+†­ù&3q3Êå‘´¤¿Ÿ ¤aŒr ìÓxö¹eï´È ·¯B5wÍÆ’†èØ 1B"ç±gÌþb–S†e­KhlCn6¸ò)ÒÓ~pGI¸ÙàPÙ§áÌqÏ >ƒø•qu¿ NÜ ™ëÔÍgµþŽ’p3d¢²OÃÙ4×MR.¶X"7Cfn/i­ëÄ>% àfÈDeŸ†³i®êIc›%r³d®ºÆqGIÃ8Ø2AÙ§ñ̚勈½ÚálY¹-Â_ZTƒ‡GIÃ8,ƒ²Oã-Íç9C½²ÙÒ8Z3çÍÐ=ÊÈÍš‰gôi8ÃfnK_ƒ…+ÂÀaý8·­þ\˜»¡¬ÜÖñŒ> ·ªœg¤×­8š-3ßæ /2ú”€›-Ót=Ψ™s8õXau9Ô7soù”*„À­ˆÊ> W!Ä‹‡â2ÝèYƒæ\™ Ô*Ѧè±hÕi,u¢Ñ¹Ù2±\êSÔ@n¶LTöi8³&®Nàjr[;Ò5ÑÑmÑ}n1é™~™áwÜý•È͙ӵëDIct6Þ$eŸ†óh½ýiF%%rsc.IL•w”4€›•}Σ¹Ý%“® òåUËÊ£cZ¦,縒py3®u£›¹Y/u©ÜAt´@3]¢ OÃy1·]7$W%r³_n‹í6ãSÒnVLTöi8‹æ²úMà`ÆÌݘcÑÊɳhâ}ú¸Esì4ß$[.o8ü㎳ÓþqÇßbÑÜnCý=ǹ K”|ÄËË?þùß½ü%Gö_ýþûÍ·þáûŸþúûúoÖ/ùöÃØç&Â^þšÿ•Ÿª1 yˆ,ù‰ƒóœGç绌 ãÏÃsÿ8ÌkŽÍŸêá¥ù¦%mÎág„?æ=p‹Ë> ÕH-ôŽ—šM}…ü†SË;þ†=ô}äX§Üa¶ÎYƒâ‘Sê&yò‚èP¥j59E3ÌŽi×—–ùÆ[Œòø/û͹€C¤@×§ñB8ëž@`&,öâ^2õ! {1©º0˜çxœÇ®—ïC‡¸–„Æ´éþ 75kaˆ”}­\4Γí$®…Z¢µ¤;ν¦ð.ƒ£{œœÛƒ¢Ç‚•yË¥¯Îòq]L(©uÙ;JÀu1”}m‰aœ“½Û&bâ“´•«1™ïÙQÕ§áLÈ㜟š$_ Qÿ0b5—M6zp! V§1ªº0šû¸\û\‡´rW×gŽÉõŸxT"K1Šø4œ”ºpŠ×DUœ |JÆ1\¦ìÓgÿ>ƒ¸Ê¦pèÝD¬FÏ£ƒï%t V—'ªº0šósœçîH/ÆöîC¨F³ú”4€C´@Ù§ƒX]°— *§pMu£¹ÚQ9…K•}.ˆey³æaè&®nãqÉiǰoéÜPÒ®ncRöi4ò¸¬V~ÿ0quå Çiì?AI¸ºIÙ§Ñ<È¥Èw¹À>ŒX½Æ%(5;ö! (6£1¨º0œù¸Ô:÷ùê9!®î’1 Ú½ÝPÒ0nîTöi8ÏɘòÏ^mh6ã£D_ëO.e äj3¦3ú4šù¸T>«u„lÈÍ"1–MªÒºÜSÒ@®V :£O£™(Jý}ݯöcâj5Sîâ&-7x”4€«Ù˜”}Í„\æâ•ãêpªê×Ë|ÚT•C-”}¯B8©W®©N •J4~YÓcv4PªDËj W^ºiYõýyqÍW»q™n”Nþ”4€«Ý˜”}Í„\.^6©çå%à¶TÂ"Ÿ€ói³D¥’@Ù§á–—rw/yguÀ-,Ÿ“—|ŠÀ14eŸÌ õÙ!'1qõ—ümoÍÈIÁ°šŽI֧ѬÈå>‡¥¾ 6bâj:ËvìÒX|ŠÈÕtLÊ>fE.‹êóǼ8dÑiÃwÊù9pË¢ñŒ>—[oöB2XŒ‰«¹Ø3¦yNŸ ¤\=ɤìÓhNeZÊ—1qõ$Ór°OIƒ_œª *û4šSùh²µ:¸Œ‘›'¹´­o™])k·² žÑ§;•sŸÙl¸.ÝØ×½ãШyç~Ö1憳Ótîø›ŒcäXo¥-êaæ2D®–Ä-Ïô–Ižs’ps$¢®OÃù·µ“înÑšº’âÜCRÁ]Ÿ† á^>ž²ótj"VWgÙ#º®ºø««U]Íê¹Ïê¦y4r›uïƒÎo(i·Y7*û4Ü\ž(‡!•Â<•.ƒ£áù•Â>§‹VLÛ×n±/”Z¹•l÷<­›ë«>% àV²EeŸ†+äæv’d&´j"[çZ¾9:§[†ÇS'¨ú4žÕsÏó ù”&Z5‘›¯sŸº²¬|ôõ>% àfíDeŸFs|N=ì°Æ9âj³›ú²s».ay”4Œ›Í•}Ï|—ÇKü8œº‘›W1wüøá9‡¢pð*‚²O‘9"pW¹ë3E¹¡Dã.Söi¼ æÜ÷XoMˆÈÍm·•%ä^¾ôçQÒnn;Töi8^n-òúܽ@ÔÜÍçyGI8Jd.p{oéÞ:rÔb ŒO)|À-V¨ìÓˆA”’5¹7‘›×3‡EÞV¼¡¨Ü¼ž¨ìÓpÐü mµ'÷&rózæ°Œux¸¡¤ܼž¨ìÓpÐÜ‰Ïæ\7'r³{–áAº|Ÿ’†qp|‚²OãA÷YcAKõÈma?gp lFéPÒ0 û ìÓxËýû¨Á’‰Ó8Z>¡½¸”5›åÏèÓpFÐ$Ü¨Ü,Ÿ¨ìÓpFÐmí&Ïĉܖ™ò#)Å•JÀm™ •}nñ M”ÕQJr@.my5°à9 ¼\/3Ü̾A6NäæùÌÝb^;’ps}¢²OÃyA¡¶B>NäæúÜ&Ídn(i7×'*û4œtÝõ«=”‡Dzõ{@>e à–Hã}.½ÎœôíäãDn®Ï<ÞêW!}ŠÈÍõ‰Ê> çÍ-@m-èãDn®Ïܶ¤DuCI¸¹>QÙ§á¼ ÅTläã®Ïâ9‚åË+% äæúÄ3úô ^Ð)°?qÊœìñNÞÎ;^^Ä«ùœ<Ÿ sÇßäM¡c½v»|ø lˆÄų8åÿR‰ I¸ZI×§ÑŒŒÏþò¦YÓg°rÛç”MË}ˆ€ÅöIª. æÅkÇ©4qxcLn(i׉7)û4ÚtŸ«ˆ­µ3|*]GÃó[kgôœ:,X=~s¨Ãת-µ&Ÿ’p­Ú’²O£Õr›ß_½œÄ'i+éâmZŸ×'µ@—†ó‚6…ú8‰«ë“FŸ’pu}’²OÃyAù–ÌljÜ\ŸŸ’†qp}‚²OÃ9ðžA|ñ+ "vèà¤#®¾;B|JÉñÝ‘²O£¹ñžA|ñ+ "x:‰«”ÂâSÒ àVh.Fó…6 µz:› VhD’%áÕÚ¤Õæ m.õt675ȼ‚ÂåQÒ Ku€63‡†ó…6E(]¹oRŽºÎß$3% HqtŸR—†[ý‡‹'O'ݪ:@),m4€«”ÎèÓh¾P ,:7-c•:)µ9‡²p]¢¦3ú4ÚÂu33QOgS€¨Nˆ¦áQÒà‡ÿ´E´…C£ùB›QØê€È­jˆCˆOIƒR©r2ãÑàµÄgû3ñÀÓI\ Ÿ’-ïUh³`çÑh¾ÐfÆ`‹H<Ñ“%'žèy”4(c”%'Î=n!ê™~Ù–ˆžNâêŶuCI¸:@IÙ§Ñ|¡M2¡žNâê¥6çSÒ®PRöi4_hÓâ,5f‡$Òìøp(k·DÏèÓpé5 ç å[2'róÝaX|JÆÁwÊ>çÆ{ñį.ˆä¤ã¬P|wœz”4(+ßg… çÆ{ñį/ˆèéäÄW œR{”4(¸âåpy4œ/”jótrÅÊAô(iP.PN«=ÎÊ—y:ù¦ÄÊáò(iÐŒE ¢ž™áWDòtr’!PN_ ç eƒy:‘›ÛœOI¸9@QÙ§á|¡Ïôú ·Dôt"7(ѧ¤AÖq€²Ä£á|¡üØš§¹9@1,>% zÌÅÊ®GÃùBñ1BO'ÎâåÑÙ¡¬A£³8@ytöè|¡kd¯â>JkaŸç O9÷Ó”Ñçìÿ4;þ&_è8Ö)7*34«#±¸SNl6ýXè•Ñá†Õ¹ˆš.Œæf|ÆîËÄÎ|œHÅò‰ñð‘;S*Ü•E³€î³ôKËÒ_AØÈ‰Ü¼›Ÿ’=ÀâÝ䨣áÏu¥gø7Ž^žNôÃù {´aWÓf*=×|,ÝÞQÔ@®¦MRöi4+'^<Ú0‰«iÃrCQ¹š6I٧ѬœM‹³„oʲg ‹KI¹%ÐxFŸFË«)X`Ã$®¦M ¢OQ¹š6I٧ѬœÍc«6LâjÚ¤°ø5ø1¯¦ÍæÁõh4+g³$.Ìf1è+›%¦ d–«‹‡e¾ÁùGöNyqNÊØ“yÇ—Á’DŸ“Wtîxëá 4 ‚Ö‘/A8†Ø0µû›Ê½q}~ÂÍñ¦Šµäìù¦ŒG¼©!÷~[™”47¥<àMõ©»þLÆ»è èŽÚ.â{¾£æ ÄÓçáåååÿüÇï^þ’ïá_ýþûÍ·þáûŸþúûÆo¶/ùöCZ·n[òeÌ^þúí‡qÜêrb9ß'ŽÞý£ó°KÿsGþÑS7¦!·KO¿Ü ÏîIó(ž#ýYw[ÒûµLWæèärŸÒoûfwû©bè#§ié¦e¶­1È#W3}»²jsI¸ÙéQ×§á\öÏþòD6åÜd?_ê‡w ëk 9ù&ÝÔ(XßL@U{_¯kÂĵ‚Œ1¹¡¤\+ȤìÓpuåiëæÜç燖vˆÖE 4ÍòÐù Ž6*‹@¨è±` Cô›Ã‚"q]~¤ÖäSҮˤìÓh‹’ØwãûÄë» 8&¸ŒŽ‡ñCßL ‘Â¥ñÞWÀ‡ ß7@n/'àcéSÒnï' ²Oý¶À·dÖoäæǰø”4ŒƒU”}ÎAÞ¤aN%\œ z”4ŒC¸@Ù§Ï þ}q¹¿‰«W¼ƒøµò3x¸¾µ@¡OI¸¾µ@Ê>ö.C“Pë{Më[ M=J”„×·š´Ú£á–eðâá=„榙WP¸ ÷f¶ 4QqËË·9‡²p³\á}Έ…Á‚—ˆë« DŸ’?ü§Í¯í(í*ƒR8T ¡äêSÒ ¢­V ©¼ëÑpµÄgû—àåâú*¥)>% .ET÷nS\ph´è÷§E$à°ämͧ¤–œ@Ù§ñ¢ž™ám‰ôŽr{£3CŸ’p{£•}î=.üÛ; Èí$|JÀíTöi¸÷°²Œ©1»8$‘fLJCY¸%ÒxFŸ†K¯ç$ŽH~G¹½Ñ0÷¹½éà% àöF*û4Ü{ËÐíã¼¶[V·7æÜHÎ)òE äöF*û4Ü{Í’¥¾§Ð,ZÖ—šåÐ+e àö^žÑ§¿î0 ‘½Š£Üç¸,’›|¼ÃkŽ÷zî3}ƒ§;/íDn°‰Diªpíc—á<˜ð-¥¡›¦£ ž¥ü,Vìq¼[šçn\ŽÁšnÉp¼[J›=KpK†Þ’>4|Kü,}I{üt¸ÔË;W[Yn;MêKª ý=-ùÍ9s¦tþlãÇÀƒÍ¼Jz7–ÿ¬7Ð¥ïÎraÎ §ùXp tîÎ×Bñ<“£ƒ<(xéKw|Scä¸åLq.mh¤p¸O2FUª@èåöÓ¦Á|í{·ïK¬ŠÎãÛ´盫¾¢âµ+ƒIžâÉ\¨A¢Wæ Çk©gs8çί„sƒ8_Èí©ú?n νüù-VŽòTgë DÃ%"çÒ¨ºÐ¢DoÇãx|Î.çqé³NWP¾ã¥.¨»¯]š¿Å“¹P‚D/?=K݇iÚó°YfAÇ ‘â4t-û†åöt~SÒ…$x•"/žÌ…*0z›L+9z¶, Ñó ¶5a8™ U HôÊh8…rí’Ñ,EÚÃá·výÙÑyÈE¸œ™/žÂA[¨dxÍý̱jÒË~^¯Æ&éΖµ«‹+‚#æ9DÝôNÄ®Ä «e“W Jí}—=:çè|qp™»1³v¢àQÞ^DUª@è­c·-ç–—Iª•¯„çn=ã°ì²:tA±–JPÕ…*$z¥<~À9#ϱT]hq¢‡)î$ p’‚™¯ A IˆÏ…œ&ɽ@½tÞIÒ7ÎÚZ_ÔëC:ð*ÛH¤ýò/=$H„¸¬S=²\CtÊE$À«TØðd.T Ñ+™B54ݲºW¤sÎV±0˹YÁ Äã÷âóQéáQ"7uk­}•­“¬«žº£®Ý«¿Ó!x¨áFn âBäæp–•¸]À#Uu@ÑcÑ Œ¥÷_ƒ qõS ý&‹w5€›¥•}Îi¿?¸ªaZ”Çðh¥æV4E…30Òo 3qÍ®©•ù5°íi†MmÏ¥á2oì³ÕˆP‹8¸ÐX½‹¨è XvF¼r3$rзcvep4Ŭ:9j fg¤ÎFûyêèê˜@Ý•áÑØÑÕÑ€:º ‹=><Ãö9ãƒÙ©·®~EG#­–E:ÇbùÛ‰±I±ªi±IÞ<ŠMPOßb¬+ ggl³T±#6A¬±h‚èPÒà VûbDFs5âÅ£+‘nJ-Œ—’ru1Ò}ÍÜHæD ¢:)ˆ.% äjf¤3ú4šÇ±¹øšç6íð(»5­ðÂàhÞhݕŲ:bí <‹ˆÕ݈%)¢$Ëjrļ؃áÌxíà]D¬>G ” Q€ŠÕçÈeBF3?r#Sï"bõ9bD\ˆÔ$k‘“›™£™ùaR#Þ’:1"$šWÏœÍÙT„ÔÐØTE«û±©Šz58+¬È&Ïsh8_d›*‹¯± bm.M=ŠMj}ú ÛdùJÃÙ#›[R³cÓ2ª3²is% ž‡Td3ñh4esñê€lƒx.!¶A¼RÒh‚x:&Û :4š‘’ uBòx\]“<;h<®¶IÍLɯ:"9Å8ªê”µ´¥ºú&yнÂpfJn^ê…äºú&9‡v ðlåšyÍF3S¶ùÊêÕPÕ9IŸOQ£é&OódÛ¥:4š§’<ꈪæI¨Ô{ ¦uà37æõâ ‹f¦|®î~áiØ"Ù¨S-”lÿq ÐfµPò¤ß૜ûý†Ñ6·&§äϹœ¼çvÇÑB‰:wü-ÞÊ%t¬Ë§ŸŽž-’ˆÕL™ÿŸîíB,–J:™ ƒ9-éÚÁ-I\•Ÿ’põW’²O£ù.ë ¾Iäf²ÆQ¶¿¡¬\}–tFŸF³_Ó";µ“…’¸Ú-séæê9¿¡¤\M—¤ìÓpfÌ4á¶Bf¤Dn¶Ë²”y>Ãw5€ƒí”}Ï52M²ÒA†Jâj¾¦^¶ ¾£¤aÜ,˜¨ìÓxÖLl˜x#·4ÛœOQ[¢¥éØ].yÆò¹‰ù|µUÍ•DÕ‡Y:ÿ~йGAh5c’ªÇb94˥ׯޢɒ°ø1‡1éVB>DÀêÈ$YŸ3j–ŽJ÷̤Q€öÒ”1c¤:=ŠÀaÌeŸIžAüAÌ3Üòí±‘l˜@Õ°™̺bå2<¨6ñ< fâl¤Läf×ÄÐù”48¨Õ®ÙëJã™8ñ–ЀÉA»&Ñ¡¬AA»&Ñ£áLœe§>y ˜ÀÁ®™ïz8×Hn(i 7»&žÑ§áLœ‡á¬ø“8Ø5Ó"kž7”5€›]ÏèÓp&ÎTŠVç86L jØL©«A½NRöéìkdËá ÞB´kÞñ­t€gC»ãdã;þ{ç9Öen÷¿4h.Î%IAƇt8`uqÚ‰ÍÖiWކL£fÞÄXø”€›yÓt=ÎΙŸ-ùº Y1ƒq3ÿç:éÔá¬ÜŒ›xFŸ†³sR›P#&µŠjÚlÚšCI¸™6M×cálœkêç£ÞÄÍ!²ö]³ ˜!:ºB0†€ OãÙE–Õfè¼Dn>Í<Û ·v(iŸ&(û4ž{³¼Þ#Ö}̪‘[ú½®²BpGQ8¤â ìÓx)zY#Õê*kÆHͧ™;ø:rÞQS@*NMTõX0÷fúRîu¶Í—ˆÕ¨™‡ÔÒ.î! 6Ÿ&Êú4š{sÙ»ºB„€Q)J©j¼Atì|'QÉÉÖyC殪>ÌòÒ~>_u T|˜xóf6R_%rsabè|JÔêÂl‚u¥ñ¼™xKè«ä ЉƒèPÖ  Š “ƒèÑpÞÌœŒyŸýF.ÌuêæÓxCY¸¹0ñŒ> çÍ\7Yg_%ppaæö’Öº8ìRÖn.L<£OÃy3×RÜE à`ÅeŸÆshâÅ£»’ƒ¨­…‚èQÔà Š“ƒèÐxM¬f¢»’ë™âÅäJ©CI¹y1ñŒ> çÐäÅ sWâò„y1uÉãŠøhfÁÄù4œ1Ó14U"7 &&€>% JÅ‚É  GÃ3óP8H&ÖJäÕ…Y’8Þ‡“=:[l¢¦Oã3Þ¾:SÑT‰Ü,˜9á]–þèïo(i7 &*û4œ1s;y¯D •ÂÌz¹j Ùcx¬Q3]ŠÞ•„³`âØ€Jäæ·Ô1ÃAt´­°‹Ó’—â=΀¹íº{ /ú·åÝmÁeË>Ž«•fn8ù/A玿Á—9öc=s7/ËÙÓ™µ±Ú0Çâ@àÑ!#x.I×…Á¬˜tí`¥$®ÆË3Í?é¨]–$âÓhîËq=Ð7iÔ<–ã0twˆ¨ÖJ8‰Ç¢™-Ç~¶Ì’ÄÕZ9ö9ϳ·µ=JÀÕ\IÊ>fºûÅûÈ*bµ{ŒýxýÌ*B¯ZU†s‚”f/T«e’¸,÷U†É;жKàf°DeŸ†³]–°½Ž5{&®¹vλs†{IA±%Ú(ëÓpéwÍà§ŽI¢ê®û½›–uø5¤Õ_Iª‹å¹,YÃVc–IÂb¯,·9š]Õ(XÝ•$ëÓ`žKºvìÿùžd°à`y”4ŒÃxÊ>7Œ<ƒøeÒÁAö’Q_%Rq`–ÑrÞj•Àax4ÐêÀ¤óx,–+³ 8*‰«ÿ’BçSÒà öõ¯9XWΕI·ŽÊ&ˆòí¢CYƒ‚(o×p=Í•ydkRhG%rð_îz7”\™ÈÕIgôi4WæØ—jiNz7vT"7ÿåØçÿ,Km·”5€«ÿ’ÎèÓh®ÌüDvC]g3_%Rq`–¶RˆËðh ÕIçñX,Wæ8¬šI £’¸ú/Kåi\†õ”4Œ›ÿ•}Ε9–ÍLd»pTWÿåX6I‘o;ù”4€«ÿ’”}Í•™zû$8*‰«ÿr1ÂÝQÒ®þKRöi4Wæ8LRI"W%ró`–Z¼8èSÒ@®.L:£O£¹3©2ÎʦB(>L®zÝ™\!9®:4œ;“KÄj¬ä"µ´*R;¨H}Z0›"õ†³e–ç§ÖšÉR‰Ü ˜åÉܬæçPÒ@®L:£O£Ù2q‘•Í’¬Eòò‘CY¸:1éŒ>æÏ¤Ä ¼•ÄÕ‰I© OIƒGÙÙŸSAFógæY*nR­Kâ§3¯º½²‡ðhàæÄDMŸ†óg–^h¯½z+‰«szÛ`˧¤\˜¤ìÓhþLÌkÑgI|±ù˜eÌ7”4€«7“”}͵Y*ó}- ¢ï’¸Z4ÇÞæc75«Q“”};Yl.22ÐÒ/rX'^õ®o(-‡•bPöiÀõãM¿©ÖKâjÔ,#í2Ö—JÀÕ¨IÊ>}ܾ9‘-…æ©d;æ·Ür´i¢Î‹}s¼õ÷è&.bTò//ÿøç?~÷ò—Úýõøî7ß~ø‡ïúëïè¿Ò‡—¿|û!§^þšÿo™Ê¥5-C¹ÀO7Çë¢ûÐÎáçý}ò&§È j]´˜J ä†OyF±Ô]?î85йãoiP)r¬·¹Kb|s/`soƒŒ­>$ÀêÆ“¹0šIx[»2 «‰‡Ù}‘›+xËöZïÔ§¤Ü<¨ìÓpÎá½|Žd;ÚÈÿ ¬ÂeóåºêSÒ@n–a<£OÃY‰÷òýä³Ù€‘›ixº2Uþ% àfFeŸ†³ãc„$äæWÂÔ§¤aüJ ìÓx.¦RÓ¯Ÿö$G1rõ{²Y‡OIÃ8x‡AÙ§ñŹµÈ”‚&tÈmú·Z™ÿ†¢p˜þ²OãM ÷EV}ÑŒÔìÃûÔ•¶7m·€ŠU=ËT<õ°‡¹y‚ ‹xêËÞèI¶w Vû0Éú4š©8™úI7رڧÞ|ÚŒFð 83@Ù§GxÎ(ˆÀ!\{·V¿Ö ¥ Çp™²Oã1gÀé´¢-¨ˆ·d/8 *b<Ç‚™Šsû8Ÿ g$ΓÐùt° ¹Y†sª+ÝÖ % àfFeŸ†3—™ü4]ÄÀÁ2¼Of¢q)kLø-ñ{â}ÎH\ù\ó #1rµ —ÊlÔåQÒ˜pÓÇÑFoQöi<#qî·ð}<5#7×piçMgÊ% ã`eŸÆóoc×:ù7/0pp¯åã¼ý~OI¹9‡ñŒ> ç'ÞÖnšö«88‡óº^]Æ@Y¸9‡ñŒ> ç'†Òy‘›sŠV75›s•}ÎO¼oÁÈ«y8?q‹}Há‚èhãàMŸÆóCU…¼ÀÈÍ9œÍqÓ4Û£¤ܜèìÓp~âu×á¹9‡×Y?±sCI¸9‡QÙ§áüÄù‘›lÏó#7çpiõ{Š>E äæFeŸ†óç 6–fÙW9,ÏZœº¡¤a‰AÙ§—Žs ûz‘›s¸¸Œì‹ÏE äæFeŸ¾ÁO<¶$NÃl›§£óާ¤ÝãG›'êÜñ·Ø?—б.Cøù-po"V§ç4X³t! §'Ì…ÁìŸtí`Ý$®FOЉOI#¡Ó§]¤ìÓhöÏ)Í–Qƒu¹=§4X¶îRÖ®FO:£O£Ù?éâÁºI\žŸ’p5z’²O£Ù?é1¯qu–ÐêSÒH´=Ö¿6eŸ†ó›P ë&q5zRÛò)i7£'*û4œý“ZäßM÷_³õf¨ð(i$ÇèI-Ñ¥árø¦/ª‹ÏMX§yMèQP þp>ûNê ¯,˜ý“VuorìªÓ“Cç@ Ð‰Ñ“ƒçÑ`öϦó±Q€ïIÆ –GIƒ:A3¸thô‘äÄ_:’˜“úõjõ¤ñÂax4Ðjõ¤óx,–ý³ 8›Ô¬Ú=›¤Ï£¤ÁAíë_s°®4œ´ÍnÅÆÙ±>[MÊÉ1}6Aôh4+(^<Ú8é¦ÔôIaq)kWÓ'ѧѬ tñ`㤠ªé“‚èRÖ®¦O:£O£YA›‹—l˜ÛáÔ=†GSðj )tWË Ju,°qWÓ'Õ·|J®Q×uDJX\Î J6Nâjú¤pù”4¨¤XMŸMùѣѬ M‹S'q5}RX|JÔBkõ´isfm.µqÒM©é“ÂâRÖ ©tµë5³nF³‚6u%µq6•Öjúl*­% ÊÇå2€ø4œ´M£ÅÆÙQÚ Ñ£¤Ái÷iËié+ gmnImœM˨¦Ï¦Í9”5hŽRMŸÍţѬ ÍÅ«³ ¢¬Vr¯”58ˆýeÅó†F³‚6 ‡Ú8›Ñ¹š>›ÑÙ£¤A£s5}6£³G£YAɸfNâ§ï“ì ¢£i徚>›U~‡†³‚6mMmœMš]MŸMšíQÒà™Í9L´³ ‡F³‚¶IÌê]ÕôÙø?),>% n5}6áòh4+èsùKOøÀÆÙø…ªé³q"y”4ØþPÃÕX%ú+èÙžoþ‘µóŽÃvUwœ,Ÿ sÇßbÝ"ÇzKÝ0\6òDl®Ï­ïÊ"×:ß@¬®O<™ £YAñÚÑÆ‰ÜLŸŸ’p3}¢²OÃYAñâÑÆ‰mÐLŸØ]ÊÔ:ÅôÉMΣᬠ%M©›q’¹™>óŸL£¾ŸäQÒn¦OTöi8+(^<úF›ËÃâSÒ0.Pöi<ï _¼Ù89ˆbúä z”4(ˆbúä :4ž”.Ë¿ùñ’l\’Ѳu ¢Kãåð,Y|æQLŸÜ#z(°çšêÊ‚YAùaU''Ç®®kqèˆ:1}rð<Í úIžAüê‚fN¼%±}b¨†GÛ'žÇcÁ¬ M€ÔÆÉmALŸÜÊ9ˆ g…‹''Þ”™>1,.e àfúÄ3ú4œ/mœD3}b]ÊÀÍô‰gôi8+(_¼“O«í“[á…áѼKÞì²`VP®¥š¹™>±¾åSÒ ’brJª.gÅ‹G'r3}b¸|JTRÓ'—=Î Ê-ÎlœÈÍô‰añ)iP Ó'·9†³‚bò‚6Nà`ú„þͧ¬ASi±ëñ¬Û£á¬ <ã7'OíÄôÉS;’eŒbúäСñ¬ M=9-LŸD’§ÝÕôÙ$ÒWÏ Ê·d6Nnbúä6çPÖ 9Š˜>yŽâÑpVP¾x³q6A¬«•M¯”58ˆÕôÙѡᬠœp˜“Gg1}òèìQÒà¥ûjúlVùÎ ŠfNN9–ÖÎà :šÒl1}ršíÐxVPnkfãä4[LŸœf{”4xfSMŸÍ,ȡᬠØ.ÐÆÉ. –‘ÿã¤ÜLŸ¨ìÓpVP–Ù8Ù¥!¦Oöx”4(¸búäpy4œ”Û…-³‹HŒÙqäQÒ0 Æ ìÓxËÈÜV7ˆfúä–èQÒà–è„˧o°‚î‘í‰ûØíçÊ/[;oxG›nßp²|‚΃têÇ:õyÚ¡»&Š‘¨z>S?wuÏdÑÑFÅð‰çñX0(^:Ø7«×ÃáBøÿÛ;—eYnëh¿Ê z,DÝ/kÄ©_C–"ìÃÿ!½ýt°2Ä&7y$íEbb³?ήÊÂeUÊp z¢ª„ÞŸxìÛÄVWBžØìdlŽO“[™€îRŸ÷žÇNl"·|çŠ3¶a¬ ¤Üò¨¬©»Ô'£gŒ`›$‚m€U Ý ýï5Z@6ûîœâÄ1A0ü6МâÄßQÌY²³2¨¤2yæ3œ<'Q”4ØÔ'ÃY™ÕRÉÎj[R™lbN/±‰‚²™˜3œl¢¢î’pð”ÊÄ“² 'Ú")k· 'þ¢¦î’xð˜ÊD-É&JÊÀ-É¿¨©»d'|Îfr;|ßSâVØ0ü6™÷MÖµÌW²“k£%”‰¸$8±x%! `™pkK¤ º‹tâ±Cq‰n¢Q’– ŸÜ&ô–åäFVb˜ˆKf‘°I>åPnfº qâ<˜À!® ]™¦¬AeÖ´ã’¬¢îBœ\&²&×ür\“k~Š’Ms\“§{‚ú qV3æU´Dˆk²‰Š’ϰŸ¸f5gn©¿'Ÿ’0¹eä¸&·9AYƒ–#9®ÉËEÝ…8ùà-€Y™øÄ5+[Êlâ׬LÔ[ˆ“ç%ÉÃòÖäaY@ [îï¤fuo¾…ÞÒ›Û²ÆáÞëwºG5·ù.oÐV¿ Ürš¨©©»ô&<$/‰—œ&Ù¥)j°ßÏøPýaõ–Þ¤vÉKâ%§ImKSÔ@^r𤬩·ôfeVI^/9M²ESÔ`sŸœfe—¢ÞÒ›U»(·r‰—¿d‹¦¨Ünü¢²¦®oCð’S?OJ“³D’Þz"š|çJÀŸÛ\gÏQÂuÎÅ(Žaöxjó»Ã1ž‰:=þ™ØæâÙëíëñвQò°…4·%ß~Ò—œ&þ˜„ÞÒ›x옾DnQMôDSÒniMTÖÔ]ˆsÝòµÆ!LàØŒé¼>JKÊÀ-´‰¿¨©·,'<ä0‰—Ô&Ù¢)i/©MRÖÔ[–s[ãUy½REœAnñ‘5.»ß·z”4ŒC‚”5u,¡9Lâ%µImKSÒ0n©MTÖÔ]–“:tœxs÷Ÿ§é˜Ñ¤¾ª$:©_“”5€—D'ý¢¦ÞržtðÑ$K¢“L””5€—D'ý¢¦ÞržÕÁçÙ0·Ãµ. *†ß&ó£Éº–9Ëyb sšÈ-Ô‰õ-MIÊ–ëÄ¥¯¤þâž° ¸&rËvÂ2£CI¸Å;QYSw©Onq–ÚDnOlsš’µÐœòä6§¨·ðguq•à&T‰y’-’²ÕeŸ€^UÃUÔ[ø³Zñ—àfµæbžU1AQÒ Jëó¬*­‚º VeâܬL,í…LT”4¸\ýŽyÖåê–º VKþܬ*ŸO̳ª© ÊÀKÌ“~QSoáϪ]”àfuy廕|á ÊÀKÌ“~QSwáO¾ßiáMsÒ“GgEIƒFçöäÑYQwPœŸaŠùøÄiŸ@ômh±–öÄÖ-©¿ (<æ7yšÓž<ÍV”4Èïœöä?Œ¢î2 \Ÿ¶ü&§4ò²ŒóŠ’@S›¡ÑÔ]4ñœr˜W•ßDniÏ}Šíe™ªd(RÒniOTÖÔ]4v@÷òê¿ù0r»a;±gÒ£¨nƒ²¦¾o#c†¹>q¨Ð”4hRž3ŸE½%1!9J %r ¡!ÅðÛ˜“yò–”§©™¿fõ7/!ʪí=ó‰ªí)Š<¯y‚…ÕLEQoiL^Æ—0%žàD޽s U„¨ŸIcžŽS‚óRvå|eow~F®Ç)x :=þ©DæåÚë;W§(U ˜ó²ç­f5­4€—&ý¢¦Þò™tð˜×â“Êé.¶KQÒné.TÖÔ[æëu¢{¹?RÒ–ÄK4s^–\mìQÒ0néLTÖÔ]hs^Ó Çˉ–à%r iÎë’³#ÊÀívþ¢¦î"œÛŠ»Ù¥ˆÜ.Üô¾¾÷ùõ(j · •5uw9¯kžDS “x‰lÎëÖ÷›‰{”4€—©)kê.Ði-€Ã˜È-ºim«GQ[¢E7±Í)ê/Ð9/ik÷ý½_2‰—ôfêþ§¹l¨(i/NRÖÔ[®3ü|½wÀ\&ñ✗­ìMÔ¡¤¼ä8IYSoñÎÔo•ݰ!¢I¼Ä9ç6ßÖ5€[¨•5uö¤ƒ‡jvuRO黲KQÔ@O›‰’º+ŠÏë™çÛDn!Ï8†>ë´% àòDeMÝE?ñà1¶‰ÜBžh‹¦¤A&>)OöP@wÑOAXBwAе¼ŒCœÈ-ò¹îùí¦=JÀ-ò‰Êšº ‚néæÑ”S âDn‘ÏõÊe–E ãù4eMA·=ÏQ8ĉÜ"ŸñT—e9> ¤Ü"Ÿ¨¬©· èkj–ïïRÙ 8¹âœ¯Ù¡“(i‡"(kê¯ôµ”×»Rž“x ¾ÆÚ÷-½% à%ÿIÊšz‹…¾î{\e;Ûë$^2 ó»«œ­Ó”4€—()kê.û­mÉNä–MCE³q'QÔ@n9PTÖÔ[:4ÝÚÊþ%à‰¸dAÓ&°$Œ!jª: ‰Æ‰Ùsîï4jQÐ8Ý“€¾÷F–ý4!ż¥AS—}=¹Ls·äA ž¥W‡’†qK¢²¦Ÿ …ÞžƒŠ;1äÙãÉ®|]kÎáOÓéñÏ„B·É³×ÇÚ6 Åèç‡âóuÓNÓJ¸E?í×sµCÇÜžPΈ±MŠ’pˈ™®bîRcÇQ^«CNä÷<–<åëQÒ0qOPÖÔ_´üý)¾i­Â¢žØ¦$eàvÓË~M1wáÏs˾üÛÅz¦—°íÑ·3´«5õwõžy!ÁyMä–î<Ö2w(i·Ù*kê.ó™ž ²g,,΀ÜÒg .Ôo0'ŠÆ1ÝiÊš:Ì|ÆÖ²¾»rÎk"·tgœã{IÉ)ŠÈ-݉ʚºË|ÆAp»_9-Îk"·tg^ï÷Mü% à–îDeMÝe>;”¬¥5Z²óØCµË§!úî!ÐYäóñ´CÇ 5žP®fƒA ¢ïfϬˆmž 毬¯—çšã4&rËn¦·¡¾Ë% à–ÝDeMÝ%:ñà1‰Ü²›h‹¦¤A&>áMöP@w‰NÿÈO,[¹7-O:z”4€[p•5uç¼–pîU 33 lžO‰Y3ü®Q‹jf½–¸ nZ×ÍÁKä–Ò|F‰èÛ6Âä|&E-uÛŒ‹‰²S!0‘[R3UæfÇO¤¤ÜR›¨¬©»4çqê4'rÈl*͉”46•æeM?‘æÜfÏ Ãx!®9žŽéÌ_–3hzœS›¦ÓãŸJs.޽^æ=ìïõ¥1Cvsyöø‚Õ·Þ϶ä5P\SoN:xÈpU'õĽ²Aô‘¾E{ú‘ˆ¦ÞR_Ë\6g€´%Ð’Ì\æ9t}÷È49ÅÜE4—ØùÀøP"–È-¹Ä÷|øÖ”5€—;Yô‹šz‹j.q2cÏÙØ®ËŽ«ØIÀ°]¢ *¡»Ë6Ízóδ$n±Ì¸¦=òîšbXy™,‘²¦Þš©ÜïÛh´$^b™±Û ëVe5’BÆÉYMý%5ãøX‚€˜²$^2™Ët‡õ}/¯GQyÉd’²¦Þ’šiþð,É(eI¼d2Ó©>•Ò% à%“IÊšzKjâÁcÞ’x‰f¢-JÆ-¢‰Êšº‹nÒÁC=º:©§z]Ù¥(i€‰¥zM&JꮦfesÞr˜ÄKj3  ûõÔ4% à%µIÊšzËrÒÁC“xIm’-š’™ø”ýÙC½e9éàWœ›P»(jqŠ’ðɦ2 ¬©·,çk"goª(9Lâ–Ú¼ã8°.õ‹Ù‘b–yIm’²¦Þ²œË”ê©q>|}£&qXÕÆc_1% à%µIÊšzËr.Óæ|'r˜ÄKj3µ—ý>(i/©MRÖÔ[–s™S‚fË á’ÃDn©ÍT¢Z޶”5€—Ô&ý¢¦Þ²œKÚ2å*h—&ñ’Ú\ÒV,ö $EIø¥6QYSwYÎø§/¯1Ã&ñ’Ú\æ#ÿ“% à%µIÊšzËr.ó; k¯³˜ÄKr3ò“ˆŠÈKv“”5õ–éÄæ1‰[zŠƒŠ™Nä%½IÊšzËtb-☈Kv+Ô’V³Ÿà&W³ôæL×϶¾Þ CALâ%¶™®ÌgéQÔ0±MPÖÔ_˜“î>A“xInÒ])MIxÉo’²¦ÞRÕDªWÀ¡ÖDMI&ˆPë‚© ¤þ*`ËR¶¸ÆD&ñ’ߌC,îý¬(j /ùMRÖÔ[ª3õEwî¡ ‘I¼ä7—y²½€4% à%¿IÊšzKuÂì–Ò™ÄK’æÍ=JÀK¢“”5õ–õL•ûg™OiMâ%عL—m¹§)jL¾d7¿ëÑ”5õúL©˜é]T¥À&ñïLE–-¿[SÔ@^⤬©·Ðgêüáí%°Iܲ q¼=Öãü€’†q‹w¢²¦Ÿ }®žƒˆé%[ÓÓp0ÄÙãé)Ç·G=NáNÐéñO…>7Ï^oqöWïà™!æ;·”€X4«¾\¨å<˯ä.÷¹Ýø®‹ƒ!·ìØÇîçm®JÀ->†ÊšºK•mÖ(Ò‰ÜÒŸüæEIÃ8¤@AYSéÐ}±ê+&;Ct»Ê{’4% ävo QSwéÐ}-eiº‘Û…»OåEÎJÀíÂEeMÝ]ÎñàÏ|ÉaHy‰ƒ&[ò½% à6¹BeMÝ…D÷ÍV.ñDnyÐ]íóI”4ÔÞ ¬©Ãœè [ÞgØ"ž€-û¸'K§! ¶0(¨Jè. =?`BáNäÝ®ö#~k£ý9IDSwYPì´1ljÜRŸ8hJÆ!õ ÊšúË‚âÁc›O*×¼Ù.EIL´š7š(©¿Jø~–—¿bŒ°e>S?å{…’€a |‚ª„îB {Zï·¯h'nqÏ4ßµ% à%ï‰Âº ƃ¿·Rƒ™p‹{FSž»$=JÀ-î‰Êšº ¦ÝA®ç†@‘—¸çr,å?;”4€[Ü•5u=NL°Z€¹-^Ó Ö²îR”4€[Ü•5u=Ž<‹¥ü&` {FSòËI%$ÖôU Ý¥?Ó‹è­ªbÉMàóÜfìÞe à–óÄ_ÔÔ]ús›JÒƒ’›È-癪÷syb^QÔ9OPÖÔ_ú3½´ñy”’›È-ç™^ùLg:5[Ε5u—þÜÒ;XÛ½<‰[ÎsK#¦% à–óDeMÝ¥?ãJ¢lA‡éOä%ç™nyÜ¡¤Ürž¨¬©»ôgZ£ÚVs–ÞDnQÏí· ׊¢rK{¢²¦îB û‘Ÿ÷æ'r‹{ÆÅGª#@I£pŒ{š²¦C ñà·iiC È-î™lÉ›WiJ n­•_TÖÔ]4vþð¦ +[!·"×z—{ïŠÀ¡ÈÊšú+}ÅIî¾–ÝŒ-À‰Üâžq6w×;{"$… JZ9뉲šºK€néÛó†Lo"·¬çz”ûmŠÈ-ë‰ÊšºK€îsÞ—Ó›È-ë¹]yÒ£¨Ü²ž¨¬©»h<ÑçÆ§7‘[ÖsÛóÝã%Â1ëiÊš:L€â \Lo"·¬'Þ2Ö”4hòœõDeMÝ%@S °g>-½‰Ü‚±mmöì©¢¤a²ž ¬ég »çT¢Å29ÑÙáð¡Ç9éizüS УëõŸÙèÊ—Ñ•øoßþíÿþ÷Oßþ­ýÏýËÿüé?þøÃ¿üù¿þöß™þ0ï?|ûëHwÉ_/¸ýáÛßâ§t÷h_ÏyN‡ùÁ·ï÷—¯4"ÄEÇò¹oÏÇûëqr¸íÛ<}òëÛóí3®ÓâÛo‡?´ùtܤ×yÏû¾síñ4Ÿ|O-{œš.èôø§šôåÚë3G¿(š bÌëG©<Ô+Zi/ÙQúEM½Åœéà!ÓXÔ“€¬ìR”4€—$)kê-¹Æ>4Q&^Íë6—ry‡’†q 4£²¦îbÎÕ)•ˆ2T 4“]’²ðr÷—~QSo1çq9ï–åªeäÅ'·9EIxYA²¦ÞbÎÕ(\B>ÄK ™FgMIZb 4S›SÔ_̹ê¡JL™xÉ4SÛÒ”4€—X3)kê-팹eâ%ÞŒ¶t(i/agRÖÔ[šFaˆ//ag5% j·Oعjズ‹@WS™r§:©cm§8š’˜xÚ„L”ÔÝ} jV"ÌU÷ÿä«¡BQÒ^"Ϥ¬©·$4<¤˜«yÛû©f„Š’™øT%ØC½%¡«‰¯šà@æ¹jqŠ® Î$'8šzKBW_RÌ•‰O ¹2QQÒ`ß7kõ–„®¾¤˜«‹9¯oùbV”4€—Ì3)kê- ]µ¸’d®‡•wì¹V% êŸäsÕ%*ê-]­K˜¹šp<Ñçj*#(kÐ:æÉ[V+E½¢«*^ 3WÕļ7!W% šj?Ñçjª-¨»@t5ñ-aæêTóÛÿØEIƒVÎÏV+gE½¢ëeÿ!.g‹>×åAIƒL\®öÂÕÔ[ ºžRç03ñ}¦¡BSÒà)ø;ú\O«õˆ®FÅf®k~Ï}ª>((iÐÔç‰>W“E½¢© afâ%úLÅWMIƒÚm~—2·ñ–ú DW—Q 3WwXžèsu‡EQÒ –øDŸ«–¨¨·@ô(„}ï–qæê¢{²ÏÕª(iðJ扨TkA½e¢©@ž™xI?S›Ó”4¨ þ¤Ÿ«Š¹¢Þ2ÑÔ¡Cž™xI?Ó¢)iÐÁ滈ŠzËDW£bÉ3W£ó“~®FgEIƒ†¡'ý\ Y-õ—‰®Z@É3W-ñ™rT-QQÒ sŸôse—¢Þ2ÑÕ¿䙫DI)PBQÒà8ÓÞ&$ýL&úöjÜ7Û¡=~­Ö(5ç ¨éôøg¤ûäÙëk+ÿSøÓ8FE¯)? «i¥1ᓳ9*Š¿¨©»)<¦Åø¤r¶ŒíR”4&|(9gËPYSw‰39*Ê“EÝH±ŠáOäÅ⫦¤Aí6GE¹·Ôa€”/# ò–å;,Š’µÄå–¨¨»)Ï­ˆ…ÜJ^8™Ñ”4hÔÎ%/‡õWÃÇð'r‹Š¢]š’årT”óŠº rîÀŸlbŽŠ²‰Š’p‹Š¢²¦î¤˜¸Áð'r‹ŠbGSÒnQQTÖÔ]€ßÈ-*жhJ”ÛÉQQÎø´Ôa€”[€…?¹%æ¨(·DEIƒÌÍQQ¶KQwR^ø[ø“ 9¥ÀEIƒãLOZ¢Š3µôÒ}öjŒœ{yßs¦@h‡oËbóqÍ9(j:=þ©éâØëmºË[3!ûi‚¢[4åýÖ +Þ‰ö¤DñÇ$ô–Åc‡”ŸÒ)c£$Ã%O†ªz˘á±CÚ“Ï󉆲#’@Á– U ýeEÓ%t?oMÁœ'pH…¦ Èj{Æ´”5€Ûý1üEMÝeEÑ,Ìy"·T(š¨)i·T(*kêí:¦€9On9ÊmNQÒn3+TÖÔ]VÔžsžÈ-j¶ô(i@K´T(¶9EýeE±“‡˜'â’ ÅQBB0\¡¨*¡·(;æ;—0(8¢! .IPT•Ð[:çìD\R 8q‘°>PnÑ-t Åc‡B6ŸÒSõf£$s¯”¼Ñ=ý•Á±+Ç,'wñ9ùÉâ¤Ü’Ÿ¨¬©»<(IOvD@Àõðóäõ°€î¢Ÿ\ï´Ø&r yb¥JSÒn!OTÖÔ]ô³š=—Ø&r y⨠)iðlû yV3hAÝE?y´ØfUÂ{BžU¹OPÒ YNyò¼EQwÑO¬lbl¹…<±–ª)iP»Í!Onã-uýäËÈb›|Ã$‡<ù†‰¢¤A-1‡<¹%*ê-ú9Š]¿Ê½%öGïXå5‰—tç6Ç3Ý_¥ÐE ä%ÝIÊšzË|ÒÁC^³2ñIwV&*ŠÈKº“”5õ–ù„ƒ§¼&ñ’î[z5—t')kê-óIyMâ%ÝI¶hŠØKº“Úœ¢þ2ŸU (yͪ%>sª%*Šlî“î¬ìRÔ[æ“Wú%®Éµ†'kÀµI€òHûóo)ÔÀÏ„=WÏÄu.ûÚPx³ÇÙfàšS¨tz¼{:0 N6ŽÇï9 {pÅiÝ<9ZãvÏ)%yž‹*c§TnCUçäíö5²qá“ò}‘WNuR|Eý™Ï¨:€ñçcgüíÛ¿ýßÿþéÛ_ã9üç¿þåþôüá_þü_ûï¿,˜øö×?þ°q 8âaì?|ûÛHó›W½4ýÜ_>Ô—ÓµríiYŒÃÇ÷;âUÿèô9~âùí+=Íy÷n‡üá°·yö¶#.^Ë(ÎÍÇý¶„”fìÒJ¸åìñ5u¿ÇƒÇø<ŸTÎÚ³]Š’p‹Û£²¦ÞÒ»ÛºÅÎúλYйEîã´i^˃؊’†qH݃²¦îÂøÕ)• =T‰Ý“]’²ðN _ÔÔ[[ã_wºã×"r»p×=LËk‘Þ£¤Ü.\TÖÔóåŒAúªe<±ûªÍ)JÀmÕ‹Êšz ãW£pÉ /±{5% XJ잆E†ñá2¢0=rKÞÃÚ¡¤ÜÂ÷¨¬©»… ^ š’†qˆâƒ²¦þúxðxÓ‘O*ß¡d»% 0ÑnR¢‰’ú»wOt³×–=ñÉOÝ«·Zº5—H>)kê-¨O!{â%’O¶hŠlâ;“_y( · >üÊ“hy*Ã-NQÔ@>ÙT”5uW åb@ ÙW•–'’_Ue% ê)ŸH~Õ÷)ê-¨_ü)‡[ßrµFQÒ^"ù¤¬©· ~ÕâJȾZU<‘üj¢(iðH~>ÿšG}AÝõy…lA{®áäT>×pe ªáä`>×pu—×ÇÚ æí¹Ò’Ãù\•Q”4h‰˜óù¼œÔ_l[Æî‘[FÛ–¦¤Übú¨¬©·ô~uq•ä}eb¹èÈDEIƒL\®öÂÕÔ[z¿*…–ä=ñ’Ó§ WSÒ^rú¤¬©·ô><$vlÑ”4¨}rúUo«¨·ô>•B!yO¼äô©øª)iÀ§äôi2£¨¿ô~u•ä}u‡åÉéWwX% ËÏç_ó¸/¨»ô>Ï­ˆ…ÜJ^8OÔ”4hÔ.wiÔ_!Œû> àóÀ’ãú<°(JÔWæ¸>÷~Šº ñóed|61ÇõÙDEIƒFç×çÑYQw!~ìÐ1€Üâú8„hJtg0Çõù.¢¢îBüûÒlo½ª>r‹ëïSl/ibÓ¥¤Q8ÆõMYS‡!þc÷«¯øÈ-®¿§ûõï=c:5[\•5uâç…¿…ðy"RR 4iQ”4 a¡},@Hú™,ÿî9Ô¸„ßLð–z°×ûï=|Æ®ïy³pÏ{˜ß7[H¤ƒMÄKS…c_öät8œéá-§O)^ Oñ°¿SZÏœc¢S2ìð”–°¿k]|Jû;¥å Ó»ã¥S2ìð”æp¼Ê5Õ)ìk£Sªz¼ïùÈÂû¡ƒôØ×•bËïg,¶ó™êüÄ ·ür\€/Ëtþ¬§êï.á>çãúû<ž!2~|ÏH~ɹ.WX®c^ןõ4Jýå#ëëãÏ{²ãp< ÚÏœ™ƒ±îGÂ{Ž?ÄÕJÞÿZC<‡éýþT•ÐÛh;Üû5îS˜¦W-:Ò _9иaÛÞÒhˆ×p½ß©‚ªz›¼¦%ò³k#<`3j+¯9Ò£PUBwîí¹ŽÏ`»HçÃî@l)¨JèíÊmd߯=íÃ\5‚­™Má~ölÖ[3U ݵ½)4ËË‘–F¶á©‚Ißj-ÌóÖèŽ8K{Α† ÀÖ¾®úï@î1 ¶‘T%ôÖèÆ`û+‡‹k}ûéä›QKXò²QBl}¨Jèν-ïEPãÈp<·D4äá¢`Šª„îÜ[rižÇ À68ܹäß8d¶ñT%ô6jìkyý4¹ØætS~’¯y¸.ØŒU ݹWm¯g¹[3;ãy¾ß¯!¶=Àf¨JèͽhÓMå“lF-±=mµ¥Qp1 U%îýžÜKcãû9¹ºÛ*/Òçá‡ä+·`\UU ½¹wÆ^g©…•iÉq†ç>€@8É.°LHŠXK¼ÍOŽ+6™¶€ØìÙòÕÅ„(Ø *¡7÷Î¥¼Á†`3êëóÊ Ñ=ÀÖÆ@UBoîŵ{u­=«œ÷ºÖ5)€¼ )«œ»øìΩ9¿Å½žÉŒ]ÿ³\òxP0NÚŠª„ÞÆƒ1þU3¹ú¬Ùš=lÏU§!Oþ ¶iÚÝ|òæTwªÛÛ‚ÔjFr‘ `¼óPT%ôæ^š)<¼jþðP,çœßí@.,lS UÌÛ¨p¬á|êbØl—&vL%¬¬! .M U%t×îÆÌ÷שÏ õ˜Z° WX›Ž!Ž€qø,ªzk{é¾Ë{Ûv0ù¯òˆQ°ªºso ·˜ ʼnÛö~Z£y6W0–Aîf*,~Þ‹s_8vòaJïtœÒ»âTä½Ù=|ÐÁóÚÛì.ǧ@¦ƒ«‡>ôùrìsÚSºMf-=@Új¯NfÃoom2óÖ' Û~ÙU½•‚ö„ˆK¯yMù©DÀ¥×DU ½Míç´ØdMI2ü¶Ñâ(*æÍ¶4´=ýȼ\›ótå—Ðô(j /W()kêíÊmo´½1jxl‚ýÑï Û|Ø6†‹aâ0q˜8L&¿š‰c&=Üî ÷~oîÁc˜8L&LjòÝÝÃÖƒ¸45pDC\ÚªJ8ÚÞï©íîoä_FÛsÜö¾r÷÷aNðvœœÛü–=¾Ýö”\‡côuzü™Ìcríõ_ˆÆW8rë–½ìß¡¤ÜúTÖÔ[/1Lü.&ÆÝÏf(â¥_—%¿Ý®GIxéZIYSwÎ5ñ& @nv¥­½Ï«Úw(i7»PYSw&ÆkGmJDÜ.Üõ¯— ÷)j · •5uw9¯k~KÕŠ€C››Âº¾7ÁêPÒm”5-ñ÷Ø—ôö•½Ù 8 !é}`õƒD«Á©pB@YSw-1ü|µ›z»¶²;Q‡’p²«(kêÎÄUoJìR…%ÕV¡¤¬é0ñwiâ^ïtià0„¬áõ²Î>% à6„ ²¦î–aâ0ñk˜˜vÌO£ÈÍ®í ó¼Öe ¤4×nv¡²¦îLÜî²9ì:ÂÒìg@”4€Ã´”5õgbd§öÕÄÁ®´'\maaôýBÁ(ÐÔÔ}Ëš÷®ày‰a˜ÄLeCŒ% à06a ÝMlâ±?¯„n,œÌÊû¾uheaáäVQÖÔ£‰©v§L,Üìšcõ~Wv¢r²«(kêÏÄ#œïw7kŒÂ¡Í­aI›zõiõ‡(ìeMÝ™¸My÷7 Ã,ð([Êu(Í ÃàaºPÖ;,GŸ fíáUæëSÒiPÖÔ‰[º}Ôn–NìºÂk¥>%C“eMý™[Ëõzle"p˜.aY–ãZý! »@YSw&¦©Ùs‡·™ fÎsÁf—N¢õ ±Ù~“”5u7¨¤ñy'ßj7æãXû꺺”4€ÃyPÖÔ_KÜÃtµ/m"mn{ó<>QÒN7拲¦îZbì·¶]äëóÒlÞI´XšM9IYS-ñ "à.Û-´6@0 ׬©Jèν81çn”¦TSÂfÞ×x(~Ò‹[±Ë¾T"9/ßôRO. Óòíj³ò8~:ª8{Ž*înØg_©|Z‡Sützü3±Ðų×Ç©Š°F­8¶°žõ;ˆ’pëLW1wÄ0ïטwÈ7î·¾ôX¹6뤤ÜúRTÖÔݼ²üýùô «¬Mu()«Š®bîÌ;·xÄíËljÛÅz¦±íÑ·3´«5õwõže!Q7½­ q«Äš’pjh[â–ÇáÅÄôtz9´¶\hF¤Ô [›CeMýµÄ5¼ÞS±´­¨pksqŽwîMx )j ‡6Êšºk‰qÜâ_ut9 »©œõ­ãÂiØ-Êšú3ñ¢Új¬ÚCÓfDßÍ*rŠ Ï~žÅ‰ÃqŠ›¥Èa€˜ãw¯ö: JÀiªR”5u7l ‡‰_ÄÄS¾`›8صæÊT’p°ëïîÖÇáÆÄ+¼²€õm:ä`×¶³¹éŒ´jÍ…ƒ] ¬©?S´Ý‡8ص‡;þOPÒv²¦îLL¯bœD¦9LaÒ+Û•1PÒN+¢¬©»)N\3¬b»vâ°|»Êýõ¥Ep° ”5õgâŽI™œÚÜ´5&"­ZbáÔæŠ²¦þL<‚Èi¥rÖÜ> ‰´ú#Ìí³¦«˜;óâNFÁÃíKEÁÒM’KEÁPYSwÊ0q”Z¿†‰ã†É˜þ³ã'®QucÀ¡Ó[ÄÖŸDIc[z’²¦þZâU’«ÜŠ€Óâã˜^½~‡V÷ ‡6Êšºk‰×š”ôw¹È,YµÄnªZY¯%îÚÜ9~ES»m·BjnÀͨë(Õt(i‡fÊšº3ñ8už9uo"ω´êôDž•5ýDžsõœ1¼¯²)å3;|YN{\¢Ã)· :=þ™<çæØë%°GÓÑ/ÝÂÂ;ˆ-õÖa ïF"šzë†_ŸõkC ¥·\æ9t}7ÃÒI‚œbÞæŠË´Ëqƒ¸™4Íál'JÀÍ,TÖÔŸ‰‡Ú±]—ÓÒî–v‡xT•ÐÝe›É"vË nû G»[Rœþ ‡ÆÊšzl‚÷<5…XâÐÞÖ°nM#4H †©½YMÝ5ÃYG‰CŸw‡5Å:ú”š2p6TøP‡csšfOCâ0æ.ai¯D«?ÄÒ^IYÓaâ0q˜øKg‡³Ø·†8 sدwý CI8 ! ¬©»e˜8Lü"&®Vtª§xíž÷®µ©á"Åj-r° ”5õgbª¨Æã¾jC›‹Çšª~}JÀÁ.PÖÔŸ‰g˜µ\N+“ý>hÕš »@YSw&ÎgžeTÓà0™‰íå˜ÏhU5+&3 ¬©»)NÚ6ElfEÜìJÛ±<™% àf*kêÎÄÙn¿q+m.ÝØ« ;DI8´9PÖÔŸ‰k˜Ò»9ê2*r*5´O?­ í¤¬©;¡ˆWÏñÄV“PìPšâ‡!d[Mêãpcâ¨gÿºëx[ßo‡ápÀÁª8o~JƒJ‡»v ¬©;á~P½Þ+œVvùNS‡V}Aá´²+Êšº3qL¿Çq)Û\S+B·Ý/±ÿ3Qê.±ÿ3)kê¯%®á^Û7w‡67‰ý€ˆ’Æ$ö"eMݵÄY‡íˆC›³ys‡’pBTØN‡—žÜnFVä0„\âå¹Di`¹Ä qIYS&ÆóØßû’±‰ÀÁ®3ÚÒÞnZ•€ »@YS&^ò Äi>ÖúD«Ñ¹pèý@YÓOÄ>wÏQÄô¢­gc=ŠqöxzÎ1/ý:ã¨Ó㟉}ž½Þâì¯¹Ê ´!R¿õ}¹Pë Š @íÖóEä`R»Ÿwºv(i¯n5•ÇáÆÄ½¼xúFäÖ“ÂÛ:”4€[OŠÊšº›sî‹®Ê"».ñn&¢dâ%Þ·DÊšú3qÕwäváî“xJ†(iLâ)RÖÔÝåþT—"rksÑ–¹y4(i‡6Êšúk‰›^¹ §6×>€N´j‰íC夬©¿–8‡gÂÈ0õ}Ï‹•4¬úÃŒ¡¹™ª„þšà\1©í+­j?²gµ1EDS~­úÞ*rêáòpСU¿W8õpâÞª<ŽaâïÉÄ3ˆ× #†A"vðõË[ÖƒOý~T•Ðߨ±‡×£~.9Xµˆ½‰’Æ"öû#eM=šxoí­yâd×ú¼æµC+ '»Š²¦îLL;„\â5r³ëXBºÏWÆ‘’p³ •5õg⩳´ÈÁ®Udi‰’ƪ²´¨¬©? n&³šš"¬ l^gŠªºs/½Ž^ÖU€ÃÔy.Ý[‡’p(e²¦î&5Û®Wy®6¸Ù•ê÷íÓCHQ9ØÊšú3q Û,ê*ÈÁ®+^sg]±AJ&»@YS&¦7±¶ûy‡ 7vqk[nJÀÁ.PÖÔ‰q-1wÖ³XLÙ¹­ \…S)kËunL\å6tÄáFÓîv¸FZݺÛa•5õgâQžùfÓ¢$í*þ­–*…ƒ] ¬©G·IÜEÎv­ÍcHk׿±?TÖÔ‰ñˆóÛ*êA¡p‡ïxÑÕ{m¥Ñ8 ! ¬©»%Å5Öv§câÐûM¢&&QéBYMý5Ãt“íl›rhpG8DãJÍ8Í©‹²¦îšá>—-r¹3-îR³¤Ô/9“eMýµÄK¾„8ص‡u¯_ D”4€Ã…{‰7Œèãðb⸕üZ¢zú9¬îö|~=Zåœ ‡Þ”5ýDôôœK<°Lï׳R¦³Ã×i/cLSÖtzü3Ð˳×Wj‹w»AnÝÂ5‡ëXë.)i·n•5u×Y\gH—kk"p°k i–ó% à`(kêÎÄ{ iÑ·ÖAäÖ·^W¹Ó¡¨ÜúVTÖÔÝ,ôÞK†˜MnvÝsH!â(i»@YSw&ŽËù{´Ä3óÚN C›ÛÊóBJÀ¡Í²¦þZbü³«õrksç®v=„5C›eMýµÄ#ÜO‰[phskHÏ¡Ö}"PÒm”5õÖ×é°ç¦ÀâÅ®uZÂÙÜ#JÀ‹]¤¬©7Óú ƒÕ7‘Ãd&=œßD”‘Ò8´9PÖÔŸ‰?ãR»îpžÍ)™ìÒ¹:/&Æ ñëÖ}WD“™MíU”46µ5*kên`‰­¥­÷FíaömêÐjå]8•ergÜ=éi r0êPÓ¤dß¡¦5¨¬©Ge9Ù•ŸuìÐÊÄÂÉ.QA—ÇáÅÄ+mŽ*žÅENv‰D‘V&ŠÝAQYS&ÆU…ߑ󰡇9 §acocõò8¼˜xï%s]Wn §ÍѼ6šh5¿<š×F“²¦î¦5÷¢È©Z˜ÛK‡V5Ä©Z(ò8ܘx”[½^.œVÆÓÜlN†´š¤N+㢬©Gå¾Zȹ¼Ðî«…´^é´ûj¡²¦îLLÓ—bz’9•\Ûׂ­Jhí;?IYSwKì·äýÈiÞÛ-KV£óÞnY‚Êšú3q Ó¢æxÀ¡äWµG³·t9ÆCQ§Ç?=§®×f£+_DWâ7¾}û·ÿûß?}ûk´ö?ÿõ/ÿó§ÿøãÿòçÿúÛÿeúÃ|þðí¯üa]bÛˆ­ë‡o‹Ö9Üû}s:ʾ|?ßÓÂ=NøÄ—ß§øáyΞÛÔ¾ÙîÛØFzƒ2Nmtzü3mjñìõµ…yncÄÄËP³^“xä•(iLâ1VRÖÔÛ4LüÎ&RP ¹ÅšÀ–% àkBeM½­lÖ=.ËÄ&ÄÍ®} k󿢤ÜìBeM=›H—"r»pÁ–% àvᢲ¦î.çÑGKür&Ž–8L&‡‰c`&‡‰ÃÄaâ0ñ‹™8JaÃÄaâoÆÄ±bË0q˜8L&ŽÑù ›8nÞ–ø5L-q˜8Lü͘øEûÄc«çX㽄xšW?îðmYlÊØáÿL„tsìõ6Ýê=–ˆK§°M{û.3„$°·o(CU ½õýïävˆK_ ŽhH{ûžiT•ÐÝ„óÞÃy·¯1!ncQìÛ–uÚ> ¤ÜÆ"TÖÔ³‰4ÏAn³"°¥CI¸ÍŠPYSo×ñh‰£%~ Lj2Üî ÷~oîÁc˜8L&‡‰Ãįfâ˜Û ÷†{Ý•­1† ‡‰ÃÄaâ–¿Ž{KÚÿÞëÍh‰Û=ö9žé^¿Ož(j ·Û쨬©»&OM¹µ7°¥CQ¹59TÖt´ÄßyK&ǰ¬†å#ˆ»çâ:—÷pR|³ÇÙ&‰ޱNÔéñÏÄ=Ï^oGX³yQ7që¶%þçv|@I¸õ¨¬©»^b˜ø=®ú-ïî»JäÖ¯Æku^ë§­‰’pëZQYSwÓÏaâ÷01zqµ/Ù!ni©_²C”4€Û…‹ÊšŽËù÷ØÇÀò}/gnEÀ¡ÍÙÚ¡¤Ú(kê®%¿ïåL 7»àíPÒnv¡²¦ÃÄߥ‰KØ®ö~ q˜Ì\áõžÏ¥K«iRá0„€²¦î–aâ0ñ‹˜8æ‰ÃÄaâoÅıv+–/bâh‰Ãįaâ(Ê¿„‰cŠ3Zâ1q ,£%~5Çd{ ,ÿD÷-ÌÛBer³kŸb{Y¦* ‰”4€›]¨¬©;9Üï#fƒ]WX÷»ÞÉ)™ÜìBeMÝ™øõûÄc§çXãÎã9¶×Æÿ{ŸK˜Ï÷6Ÿlï’'‘6‘Ÿvùrìò~†û}žëžr´{º{ò#á3lïœs´*þ£­QptõáEU ‹€“þa¸÷kÜ;¦0Më=|òˆÍ¨#l[º؃èàbªJèͽ4¿¢î±³Zº¾æ4?ÞÂ9 ÇötÍÇË QÀðy‡ûýˆ¨Jh^ÜÛò¿ÿòtò€Í¨9.çÚ=€(`Œ2U ý¹·…}¿ö{kšNÁfÔîû˜ú ƒQ¦*¡?÷¦ðžqÔçži±)®âži¶dðm£àQQTÌmq!q‰3Glíë Ëó¹†Ücfl>ª„þܳ¡ŽÜlFÙª!ºgŒ2U ݹ;ëë}ÀõpQ°µ„%¯"$DÃ42dU ý¹·…%=¢w5ÃEÁ82OÍECî23¦‘!«JèϽ¥¬ý«¦S° w©)hˆC†a0ÊT%ôçÞŽUL“c3{ýGrÛËŒ2U ý¹7çbS=Ë-ØšÙÏó}·ICl{†Á(S•Ð{ÛŽçÁo:yÀfÔÛÓV[  ›Q *ápïwå^Ó×®° Æ‹4•>®«ùÊ͘VYUBwî±×Iv,+VêOÇÞk)…°¢U`©<±–x+DW¸¦÷RœN°Ù³‡e{/ð5DÀV±U ½¹w.á:Þï‚£ÆØŒºÃšß´+!ºØÚ¨Jèͽ¸v¯Ë(o‚UÎ{]ëš@^dLUνýì®G‹ó¨ü~Âj&W0vý÷³µ†<dL“¶¬*¡G÷Æ<ø—Ïäê³fkö°5W(BžümͺÝõ'wúÒ¯šÄ™Âs“¿š?<ÔË9ûòªyhˆßlS UÌÛøy¬á|êbtê€Í¦©¤¡4ä{¸›O *¡;÷ÆÌ÷ש׽½C8x÷p1j»r—Ô €Ør *¡;÷ް=ÏE×Ù‡Œ-'gøÛyìG¢`3 T%tçÞî£1€Z#‹ÿ5Õ#Bly€Í&UÌsú ëcº)GI4äÈSÁæ¨JÈî}˜Ò»§ô®89ßZL7vð<Ïa:Ÿ×Õw8ÆA¦ƒ?‘†¼&Ç>ßWNG`ÓZZñ½å¼…døm£¥ ƒ¢bÞú„aÛ/»ª·RÁ3G\Lºâˆñlm¢! .>¡ª„Þܳ?<.x–µ±5%ÉðÛ[›¢2EÅÜ­•Ó pŠJñbÓ<]ayÿg¢p3 •5ugâh{£í}QÏq1 F QÀ°9ª÷~Wî~oØ6†‹aâ0q˜8L&¿&ŽêÕpo¸çܽ±ƒÇ0q˜8L&Žñx¸7Üû¹‡Ýž=ñbvhŠÈ‹[¤¬©7Gþe´½ÑýµMðÜàì8'8/¶‹,%,{|»íá¹Çè%êôøg2™‹k¯ïØT¯æ YâÖ,{Ùn¶CI¸õ¨¬©·^b˜ø]LŒ'º‹±9ØWq̓,DI8ØÊšº3q=¼míz¹­¬×%ï£Ü£¤aVÖ ¬©»õö¼­rS"â`×öWð¿KÉDã`(kêÏÄu ÷ó¸ìšâ?©÷Û"JƱ͙²¦þL-ñ{ ,i{÷½Ù ¸Ù»ÿin*“HIÃ8ØÊšº4q¾Ú-ˆƒ]›Ø‰(ilbƒ#TÖÔŸ‰«Þ&”8Ø¥6 %J&ª­BQYÓaâïÓÄ3¬{ZøÖ&‡!d çuOÐj„Ïí2eM‡‰ÃÄaâ/31혟&F›]Ûæù½'Y‡Ò\Ó8ØÊšú3q»åèÄÁ®#,wè!JÆqZ}‹}Ðõq¸11NrÕèŒìJ{ÂÕFßÏ2MMýÙ·¬jë ÄPìšÄæDIbÛg °„î `ñØÓþ*õíBâdVÞ÷­C+ '·Š²¦MÜÞWScbáf×û«ë½Í^‡ÒíGàdWQÖÔŸ‰G8Ïvcxâ°"YÃ’6õêSÒ0ŽkcSÖÔ_¸My÷7 Ã,ð([ÊuhUÏ",¡?×;,Gûx$q0k¯2_Ÿ’†qœH›²¦þLÜÒí£v³tâ`×^;(õ)™h›œ)kêÐÄØZ®´ÂªM³À%,Ër|@«?Dæh—)kêÏÄ45“wšó\°Ù¥“h=Cl¶ß$eM]ŽÌÏ;©Øà`Wk_]W—VˆÂÁ.PÖÔŸ‰{˜rˆ¦º]_8Ø5‡½Éë% àtc¾(kêÎÄØom*ó€ÜìJCE›y@ŠÈÍ.TÖÔ‰ËDF1´¸-<¨†$`š›©Jèν81çnÚ$ ï½‘YcBйs+vÙד<¨‡ŽÂyx–^Z™Ó Q”5ýD,tõUÜ-ÝF1Ï¿RøÌ–;œâŸ Ó㟉…nž½>ÎЦæZk>¶°žsµõ6QRn­Ùts×I ó~y‡|ãq°*s³îAJÀÁ¬C¼ÌG‡OuŨ­¨¡Mu()‡uÑUÌßûÜÂ,^>Nܬ:Ó‹ØvèÛ@PSÞÅ?{^HÔM¯phf«Ðš’†qnhYYS&¦§ƒq79´¶\h®k¤Ô ƒ] ¬©?ckyp AnvÅ9Þ¹7·§‘R¬Â8¶9SÖÔ¡‰GØîe®_SI.Ü%¤rÖ”4Œ£]¦¬©Cï na«öf,)ˆ¾»7cI‘Slxö{ð,NŽS¸†ˆ9Oj{”4ŒóT%+k:L&¡‰§|Á6q°k û<ŸPÒ0ŽvâÝÝú8ܘx…W°ž"»¶°ÍMg¤UkÎí2eMš˜  íŽtÄÁ®=Üïi’†q´Ë”5õgbzã$2uÈ¡‚•^ñØÜAJÀ¡‚Êšú«k-eõZöÖfë—y¿Ôý|¤¨ìeMý™¸†cR&§67m‰H«–X8µ¹¢¬©? bþF©œ5·ÏB"­Êsû,dÑUÌ__çp2 †¬ºT )x©((k:Lü]š8J­ã†É?{0ÓÂï0ÏrFœî·»·­¦–í®l¤¬©?/hEN…ã˜f~ë5Ñ*¹P8Øu©¬¬</&ƨiA™™Mg.2K†ß5je½–¸³ ºn>mà`Ñ3"(DßÎÐBAMÝywݶ‹!57àfÔu”j:”4€C3eMÝ™xœ:ωœº7‘çDZuz"ωʚ~"Ϲ{ÎÞWÙ”ò™¾,g)Ðô8å6A§Ç?“ç<{½Ì{Ø£éh‰—½ÌKû‘¾E#6‰hê­_~}Ö¯MD^‚9sè"ún†àÐÖ$]Õ{ñlÚËø€ _âe¼Ls8›ĉ’†q[)£²¦îÖÏËt¨·¿"³–öý¯I`iß ª:to–O‡·2Í}†ãÙÿ¢C±~ÝšÅÓáú8ܘx„{žšB,qhokX·¦$…‚¹½eYMý98ëˆ q0ëkŠuô)yhìšUøP‡÷pÍGS…%nvÅS]šÀ+Ñê±4WTÖt˜8L&þâÙá,ö­!NóÀýª÷Ï&Z ï™óõl͑ġÀÛË1ŸЪjV8º@YSw°´mŠØÌŠ¸Ù•¶ci^›D”46ñÚ$RÖÔ‰³¾ HÚÜ‘o„ô(i‡6§nêãpcâ¦ônŽzz‚œJ íÓD«DûD#*kê¯OÅÄQÏþç_ÇÛÚ¾¥†8]±—,$^Bâ% ‰¦¬©?Ç}©1Aü&.KÙæš'wÀÁ®«ìèÜ¡d"p˜ ‚²¦îLŒ}ÑýôElp°k;R%IìHEÊšú3q̲¿Ëm¾tÀi­â1ÆÍ®I®§Îšq’+;TÖÔŸ‰s<øv4â`WùÏ%ƒ] ¬©?/ù†â4ký‚ ¢Õè\8Øu‰w‡èãøé(âé9Š˜^´õl¬G1ÎOÏ9æ%a‡c¼uzü3±Ï˳×[œý5WyÖ–·-ÔÏ£/j­¸ ä®kØn=_D&űûy§k‡’pðêV3QynLÜË‹÷Øà`—½½¡CI8ØÊšº31žÇ¤jAÈmŽ]å]IŠÀaÅ Êšú[‡ïk™0³‰ÀÍ®}/&J“xù3*kêÒÄS<&Nœì7‘V&Š›ƒ ¬©C7ÛFœ Nvµ ­Ll*GeMš8‡KeSß×¼† aÕ6/aU ]º—1©í+­j?²gµ1YDS‡~Ác˜ø5L<ƒx­0b0+vðõ¦ÚëÁ§ÞRT%tèÞ^SŒ¥>{à`Õ"ö$ZÏÆ›ýþPYS—&Þ[{kž8Ùµ>¯yíÐÊÄÌÙ®¬¬©?Ó!—¸AÜì:–îóU7¨‘’†q° ”5uh⩳´ÈÁ®Udi‰’ƪ²´ ¬©C9“Lfµ3i€•íLÚT%ôç^zý®Ë£…C)k.Ý[‡’p(e²¦î \Û®Wy®6¸Ù•ê÷sóè=RÔ@v²¦þL\Â6·[.»®xÍu©)™ìeMý™˜ÞÄ*æ×Èa%»¸ö^¤¤a:?PÖÔ_Ÿ×sg1‹ÉRÁêZ-ô2çRÖ,–/ê8ܘ¸–íæšÕòÖ¶ÄxÖ¢ð”Z¢ñj]¼µË=unL<ô³àÈiQ’vÿ€VK•ÌÑ®C=e.щÛ$ûCÎv­ÍcHk׿±?PÖÔŸ‰±óÏo«àÑ8ŒÃw¼èê½¶‰Òè ÆaPÖÔßè¼…}ÝÅ8L«§\¨Ò°šiÞõÞž$«©?ÓM¶³mBÈ¡Áá(5Cà4§.Êšº3qŸåV½Ä¡Å]b«^¢ô‡¸ÄV½¤¬©;ã‰æ÷}Ôví!þ³º%"­Ò%…C›eMÝ™·p¹%7»àæp‡’ƤœDeMÝ™˜Z€29µ¹­5iÕ·ÖDTÖôÐÛs.ñ<Â2=¯gÅLg‡¯Ó^Ƙ§¬'èôø'2 ÷äÙë+µÅ»MÝ#·}Íá:Öºõ#% àÖ¢QYSwÅu†ôUk"p°k i–ó% à`(kêÎÄ;.ßR¢69Øu•;1J&7»PYS&î%CLKjä¶¿çBÄPÒ0 pPÖÔß².#2¹Ùh‡’†q° ”5õgbz&^Û@#rhs[y^¨CIÃ8¶9SÖÔŸ‰6 iZÑÖ¼Eq‰g}=+œE àØæLYS&ÞG¸U©9´¹5¤çPë>(iÇ6gÊšº3q{> ^ìZ§4œÖwˆ’†q³ •5ugbA_a°úÖ rBÒÃùÍ=0¤ÕàtµÑ PÖÔ¡‰?})¢]w8ÛÍß’‰ÆÑ.}‘«ãðbbœ¿nÝ×yEä`צöªFJ›Ú‚”5uhâÄu˜!µ‡½Ý' ) G£YüwOzZƒŒ:Ô´)Ùw¨i (kêÒÄU€œìÊÏ:vhebæl×*­mˉWÚU &ÈÉ.±“(ÒÊD±;((kêÐÄ+ì*üŽœ‡ =ÄÈÉ8{«—ÇáÅÄ{/™k.·BWœÁK³RÒ….PÖÔ_ùkÑ äT-Ìí¥C«báT- ynLÉÏt÷ܪî%Ü/çªVÒáÛWËûYŒ§Ö:=þ™Vu8öz›î :>Ä¥—ܦ=¿bLC0\ºHT•ÐÛØ3ÜîýózÉ=œ÷Ò–e['ömËÚ|’†q(′¦þJ;ÃÄaâ0ñ·b"ôçxþˆ‹Y0JhH{ûÆUP•p¸7Üî ÷Æà1L&‡‰ÃÄaâïÐÄQçî ÷<º7º¿aâ0q˜8L&Žaù븷¤]ñS;¨Î¹Y5Ç3Ýë7ÊE äæ*k:L&‡‰ÃDÇ&~áaùÃâé9‚¸Îö†NŒoöø1Ûä±Ã1Ö‰:=^Å=˜†&”Ùoe‚»Ë¯{R{¸››»Oê<Âui§d>)ãOjÛöz1PuR…;<©t÷‘^Å'eÜãIMa¿¾:©Âž”õr|RUï÷ýðXþð~¾c;¯pñ0ž<Òk5^=Ó‡x,¸õ·×°/ñû?ñåÎOÇ‘ì<ï' ïÓ=§°½®„_tºÇæ{‰gýß>ô·÷°ÇIé½ü̧a.ÏÓ£íÑ®ùªÞAÜ& ÛÒ“|PÒnsPTÖÔÝÌb˜ø=&ê[8âEW¿7‡¸Ù§×ózœPÒnv¡²¦žM¤ "rK5‚-JÆ!ØÊšú›S¯WدöÍxÄÁ®=LKýf<¢¤aí2eMš8ZâwXÈäf JÆÁ.PÖÔŸ‰ãr&~ Çåq˜8Lü›8JaßwÅ»l Ò¡¤ìeMý™8Zâ(…} Gb˜ø%LSœÑ¿ˆ‰ctóÄaâoÅÄ#ù&î[˜“µÈÍ®}ŠíåÕç÷(i7»PYSw&s¸—=e6Ùä`×Öý®V@J&7»PYSw&~ý>ñÃXãí9ÖÏþx=&Ûtÿ{ŸK˜Ï×ÎÜ {w£Hƒˆ—¦ Çž²ÏéÁ•êLÓ£-³§gô)ÅkáyD°¿SJ¯ßXî4šÓ)öwJÓžòí|æðd¦ðš',Õùìî” ÀSª;†ïùdÀõ~WÅ®k?·÷«*¶eãZºjÖƒõ——תûù³ƒ¨¿ÿ×6_Ÿ§ võ“Ó^õˆŸzlCžë´Ä?ÌqL?õåM~yŠ+€ŸýBešÏâlë~?™û›‘ÍÓ·8•3§­ýdÿØ"BѸêÕ†=ÚsLašÖ{:àt%CŽü¤bõÉìörEàÊž´Ø{=ó­ ¯á˜×„c+¹æãeƒ†(`x¾Âõ^O‚ª„îf|{úã¿ÿìtò€Í¨9÷\» ƒQ¦*¡?÷¶°ïñ<¶¦élFMùÉÛDÃ`”©JèϽ)4 ¥‘›¶#¼OW3ø¶Qð¨(*æÎ¶cÎ'ã±4\ayï,V}²ñØ»ûѸÆpùSþû)o<]cÉ%,¹@Ÿìß{Ï­@´¾ìÙÂ2O÷zñÜ2³dÈŽwÕ½údÿØÛ m€/{–\èå>°uÐw. w vÛ†¡6U ÝõÜ{´aSUÀ83xeº‡ÌŒÁ(S•П{s˜ß€z¦Y°5³xU½£ˆmÏ0eªºsoÛó›€ùä›QKlO[m)@0lFª„ýߕ{i@Lã]»Ê)/Òtûðºz¯ÜŒifŸU%tçÞ{'ûÄéÇq†geÿmÓÞB^³Ž"ÄŸ\M@Žø'Þë];McɆxvÛ³v¦Oöï½'ó ÚWöœK¸Ž÷%cÍÅX2äëôÚ+«údö{·m€+{â²·®6¼ ïu­K7¹Ì“1÷ö³»N'NuRÏZ—WcïülZÖÜegLóª¬*¡G÷ÆTõ—O¶ê³fkö°5W(BžŸmͺÝõ'wAy¥ªÚl—k4äu|)ý`¾T‡tç^ÿßY,š¼QçpìË»AŸ°ÜZØ{Â`’õgW䱆ó]˜‚ØÅ„°¾·z=¦?ÕϹCU ½%ÂlÚÈ'ØŒ*“ÐDÀf¨Jèͽ8d]÷V%~$\ŒÚ®ü M‚âbªJèν#lÏFäàbTìæ¯í<ö£Q°ªºso ÷ñÎáâ¹µFv†mzuýˆ-°Ùd¢Š¹sÎÂxw±¤$& RÐ'¼ÁRØûþˆ6Ôc³ãÄØ›Æùz*òâ<ÏsH öeïr ’›L×ùò}^û|_a®Šf†bk—£ÝV·ö ½Ú)èÕŸ]͇/ër+E‰r®À¢WìÊß›Jò#óbÓ<]ayžOïPÔnf¡²¦îLmo´½1, {üÙ3&[×Ñe‡‰ÃÄaâ0q˜èÙÄ1Ùö {þþö`炸ôD`ƒ†(¦–n}WÐ]×4ú÷aâ0q˜8Lî§í¡d â’‚1:— ªJè-3ÜûNý=ñbôX=ŠÈ‹[¤¬©7K‘›Nh±ª”Ë5Ão-&¢bÞlmÏûØúafmuœY›—²G4§ýz|»íQ,Í):=þ©|àæÚë;l×ÅT"Œ­v^ö¼…tý¾ðÕjI¹%®&‰Ã¥ŸçR<»ýä­w¾l‰Öû„ú#|àã (·Ä—KëæmkµÈmùº.aÏÉgMIÃ8,_AYSw‹Úy[åF1ÄÁ®;쯜x—’‰ÆÁ.PÖÔŸ‰ëî÷ã•ÀÁ®)¬k½QÒ0ŽmΔ5õgâh‰ßcäHïWØyW2„Ï€:Í·ö‘›Ÿq”[âkäˆG>_+ï ‚ðeËf»ÃðGø ÀâIQn‰/—V±?"—-´C"~—ê=I¹%åߠKgX÷Tâ©;fàЯá¼îéZ²™ãXhÊšúë܇‰ÃįabÚ%-?Š 7»¶3Ìys;Mi¾gìeMý™¸Ýek68Øu„宓+DIÃ8NmMYS‡&ÆIèÔnKOìJqÕFßÏ2MMýÙ}¸«º;°×deÊ[ÔáŸY¯é6À×Ì%xÚÔb©-Êð1¥l¬ÅÉ£‹%E¹%î\Úž·“K&[æØÏ<»`Tí+‹'E¹%Î\:Ây¶{Z·Ž)þç’öBêSÒ0(kê¯ËÚ¦¼cw؆a¢v”í·:´*—í¼ /Âú3p½Ãr´@³öðª†õ)iǹ®)kêÏÄ-ÝZi÷y&vų^Ú›@ÉDãØäLYS‡&ÆÖr¥EPm"p˜¨-aYR‹éÒê‘9ÚeÊšú31ͬÚ[ªó¬Í¶-Ä<‰£­ I¹%þ†Þ÷{l8aƒÜò8i0}õM]JÀ-ƒÊšzKé¼î \í¾yÄÁ®9ìMvŒ(i»@YSw&ÆŽiÛEÖ ¹Ù•Æ‚fSC¢¨ÜìBeMÝ™¸\AÄeC‹‹Kù©i†IÀ047S•Ð{qæ%ÎÝ(4´=H@ß{#³Æ„sçV첯ç<Ý®Éð5¢Æ! ¯³ø#É>Ã)(·äçFwϱ¹ÝBZ9ìñ+õpÏ|WsŽ"šN*¢xxöú8Cµñ‰¡Ôj-¬§Ýò†ð€ï&kªõg_3Äá·îíû?¾,Yž÷¡7á+GŽê-"â·Ü¸tª{ FmÙ -¥CIÚž-[­y æo!{na/&nVS¨«,Ñ· ¦þ¼‹ög2ß4½Â¡™­6ˆjJƹ¡eeMý™˜ž YÄ]mäÐÚÒ üæºFJÍÐ8ØÊšú31¶–×ú õúÓÈ'_çnñ(øh_Aø  ÜgŶ4½ªá4ÃgüL•"ñ‘†ÓËàY”[âÌ¥;ÔUÊ‚^–ì¡ÜƒÍÿ ÿ4“dž"V¦¸7%ÞÇ)î "‡NzszäÝ¥¤aœ§ YYS]÷0q˜øEL<åKp‰ƒ]kØß%Å% ãh×)Þ¯«Ã‰WxåÒê”*r°k ÛÙÜ]EZµæÌÑ.SÖÔ¡‰©NØnFìÚÃÿ§(iG»LYS&¦WµMu: àkª’^ü6â#|`Yå–øšÃĹ|^"Ò¿¬ÓRéÊ·ë°røxÊ-qæR¼®¦Æ%ƒOã™6s >R[*°´œ¢Üg.A¤ÂRÕgnÞ­N´ªÍÍ;ÓMW1ÝUœfÉXr°êR±$¤dà¥bI ¬é0ñwiâ¨HŽû ÿìÑvÌÜ~Îh;OíîgÄ-Bç^í¦~DIc›õ‘²¦îb6¯N]¤+‘ƒ][8Žiæ7Ó% à`×¥r›ò8¼˜x-¡iA™™MçSåÕ ¿kÔ Êz-qg—õÍÕi‹Þ]¾Dôí Í!ÔÔw×m›¿QsnF]GÞP¤GI843PÖÔ‰Ç)²…Ÿ¤f á#ªl!*·äçf OÏy·û*ÛŸQV°Ã—å,…“ç ¡éôø§²…—c¯—yûQ½­al¹Ësû¡lÀb÷óI¤%®æ„ÃÆ­ÎWz™0‡æ¿áŸfòذQ¬²÷bJ:|ñD0ñ²]¦9œÍÁDIø-GQYSw‹Ôe:Ô }ƒYKûJ_„$°´/õU º7Ëlj[-äŽ×׳A‡b‘8º5‹Çõq¸1ñ÷<5ÕNâÐÞÖ°nM#4H s{˲šúspñ6„iX˜î&ýâ£}á36Ô9ñ[n\ÚÃ5‹YE†ïÙD<É’®ÄdìBéJRnÉpi¸ôût)žÀ,6 !Ns±ýª÷ö%Z ±™ó\ln¶!ÑÇ1L&?eâjµ™zšu7›Æßw¸Ö¥~|)Ív£]¦¬©CSµ1ÎJ¯ÚDàÐæâ±¦ÛR}JÆÑ.SÖÔ¡‰g˜µdN«ƒý>hÕš3G»LYS&Îg¸ÞõUœ|MZb+9æS|¤JTÏŒ”[âk“öª¨·B˜lI;_Ø[Wð#|e«ÞºBÊ-ñåÒ\n$aÃ0øj<éÆTÙø?ÂW>-”[âÌ¥5LiÛÿz:¨»<{Ö¡Ôm‡ ”5õ×mšÛ(ûþó¯ãm]åu\8]±×SUëÐê:Μ¯Ø¬¬©?Çí›1‡ûGÍá–¼¿/Eeˆ—`MCóV¶=ŠÈK°†”5õ·IÍýîl*€ƒ]SÞu¥GI¸Ù…Êšú3Q¿ˆƒ]e6Ü£¤ìRÁ/}nL\Bz’7‘•ÀÍ®é²]Ì4E ä`(kêÏÄ9ük£¨ÊDà`×mÙª46Q28ØÊšú3ñjßV€ðoŸs­?Òð[à3Ø^Õ+Äoýt,îö‹Koùy¶2£Ha§§æò¢NsŠ‚N&‚8Ož½ÞâÜŽCc™¤6»m¡<²bàßônªE­úèkÖ¸Ýå•pª_fÄ1×^‰á+C@¹%Î\ÚË{»à” ¾lýäù#|àã (·Ä—KûRêš´PEnËÚí*oiéPÔËZPÖÔßbw_Ká—MnvíSy k‡’†q´Ë”5uiâ)ž &Nv‰jH+ÅM2PÖÔ¡‰›í€L'»Ú'މV&¶O£²¦MœÃ{‘£€±×@q…岉Gù£†±÷¢ p6dÌâ!€oKìÿ£)xöÕC­¬CVq{艻qþ_øx²Ö÷Ûß.ý¦\:ƒxõ'bè¨c'[oø‹°êí~AUB‡=÷^ÃüRŸ=p°j{¦­gÄÍ>h¨¬©Kï­½Mœìzªn=Z™˜9Û••5õgbÚµáwb‘›]ÇÒM®êN,RÒ0v²¦MCP•П{é•Ñõ;p¾&¹³ujü¾ð©rK|ÍZ¶)\¯²ÁdKª^ÃC(ðѾ‚ðñ”[âÌ¥%lÏ£|T^ÌðeK¼l¶óÁ%€' Üg.¥—)Š)0r¨=Æ^¨}ì)i‡þ ”5õ×mÅéþÜYÌbÍ0…T×ù€Vu Ì¹â3‹†:7&®y—®¶¬»µ-ñw;¢"¥–h¼*àníŠL‡òè.›œÖ iCähµšÈí2eM]š¸Mâ)1äl×Ú<%†´6qmžeMý™;ÿ¼Ñ> ¿_ãí/µ²É0~„áà3Ø‚rKœ ¿[Ø×½Ùm¸mâdì®w=DH †-eƒ²šºËÞléfÓÙ¼•š¸™µáx·”E ä`(kêÎÄ}Îû†²È¡Å]yšÑ£ô‡nv¡²¦îLŒ'ú¼‹ 1 p°këÞ´D¤¤Ú(kêÎD»•YµÄMÅ7í&i’phs›ŠzÊãðbbjÍÊ_u“=lð°"|¤üÎÆ+¢rK~fqž=gäÎ#,Óó~FÌvø:íyéqΚN*¸xöúJ °ÞÑ`j¹×®c-í>ÂW¾›-*·Ä×$ò:Cj •K_¶Ä¥É ¦ÙGø ÀÇPn‰/—âÅ”^Êø²å²Ûü\øö•[âÌ¥½¤TiÝŠÜV¹qÀLqÕ(i‡U.(kêoí  €Üì‚Ë®CI.d³ ¯vIý™˜Â~{Qµ"àÐæ¶üüH’†qls¦¬©?ckÙÄ{Óˆ›]çϺ~•"QÔŽmΔ5õgb\ZÜSýÀ4TÜkHO#æ>ÂW>ã(·ÄÕȱNGy^¦œ2ÂhË:-á\K°?ÂW¾L&‡‰ÃÄaâW3qÌa†KÃ¥Q1rÖm¾˜8L&ÇðûK›Ånˆ—4ž% à%¤CÊšz‹îÀŸŸ @nvYƒêQÒnv¡²¦îL-q˜8Lü͘ø†ß#v»çˆÝ¾ÙÛL1žØã¸‘æ[4ÿTœñðìõµ…y®r¹S˽&ÛWŸ?ÂW¾›-*·Ä׿¿>ïaÛÎå8Ä×ßèòí¸Eoë\^VH-´Ç´™šW¦§– :=þ™½Lž½Þâ0Gz³7ÂØoÛR’^|„¯|uĤÜW+£áÒÏ»n·pÜ7'8&[â56¯%‚á+ßž rKܺ„Åâ¥tƒ^t(i€»¥tCIÝt¶õ ûÕ¾³„8ص‡i©ßYB”4Œ£]¦¬©CGKü®C€Üì‚ CI†³ ÇIý™— pÅM|YòGø Àgœå–89†Kc®6\úGº´„Mì%BÆÂ+¼^]¸ti5UÉ»qSÖÔ_ç>L&~Ç\m˜8Lü­˜8êMcÕ0ÚÒ¨yë¶Fír˜ø%L³Ñ¿ˆ‰cøýTS£ ñ;ƒÆÓ£¤¼ÄÎHYSoa´aâ÷9Øäf—=JÀÍ.TÖÔ‰ûæ­}ó7q³kŸb{Yªýp‰’p³ •5ugâ1‡{ÙÏ: KìºÂú<ÐÒ¡d"p³ •5ugâ¨|±›=Gì–p÷žöWµ@â¿÷ð¹„Ør^©Ú¶”"‰t°‰¸i‹!^@/ÇÞ[§þVNñâõº/§t‡¶‰ôv:qü»ÏcO÷¿ð„{;¥c’½ bw§ÔöØ-ðé|¿g æ?Üϳáz]¯ï@þÞG<ŒýÃ<ÿü‡ýç_Ã|_˶ˆ/ç‘ïûðû†ý Ëëoý¹Þ^_Ž e?×øÃñzq<^Gßîg»ïí Û»øqœ[_{ÚÉ;uë¾o]H€0½ºú1 ‹€“«t¸÷+»íiZïéˆÚe¯ùÁ„—°Ï¯|?¶¥ØF‚àhÏË’U%4'î¥åÚk\<`3j ×|ÔîDÃf¨JèϽ´<{šÃ‘ÿóGÂW\®]é?÷¸î½Ÿö$! ^Ãu¾ÿ-¨JX¼¸·…}¿ö{kšNÁÖ̦pßÇÔ‡(`š™©Jè¯íÅ~Ïã¨Ï/Ô†‡ØÏ?÷;Ãoµ±Á~G1wÃÅ\îþà‡Ø®Î+,÷ò%ÄKp¹:QUBo—,Žè`3 P Ñ=Àf¨JèͽØY_ë«ÀÌ׬a˜Ó-ÏR¤I°]£ðcz»rcg½ÌÓ½^Í,7c0j Ç»<¯aÕelFÁIèν¥”ã®Çú¾]Žx ç¶¼w)Ik€ãÞ×ë:¨Jh^Ü[Ãëx—Ê=ÀŨ؞^ïëB0 F™ª„þÜ›Ãü¤èä[3;ñ›€Øö ƒQ¦*¡;÷¶½¼Žæj†aZ·ÄöôÞ¨DB\º8ü1 ½õ{ý_¹È8Ò·µCæƒÁ¨3Lû;½&!¹WåÇ$ôæÞ{W¡§…•Uìqæz¼@XÑÊÐÖ¯Y¬%ǮéYŸãÊpYD{X¶g/! ¶E¨Jèmeq.ázjÜØ[ãºÃ:Mgb›3 mÌT%t×öb#Ú›úç^U9ïu­kR¹~•1U9÷ö³?§æ²›\U¯,¸\Û™o/v  ¶Ú&¨Jèí*ÅY(»W0U¦¼²{£QEUBoîmõ Œ§i{ØòU§`5ù+ئiwóÉÛ| I|;¢`+ÄA}IBŒwŠª„ÞÚWš)w—¢ò2^“²¦Þ–.£íý궇}=µ…2.Pk’”4—Ñ~QSÇ£^{ˆË…Š#„(¸\¥¨*¡·+w¸7&zÃ6¶Ñ°á1â%iFÃ…¦¨ÃE ›ÑÀ ©» Ú0q˜øõL³¿aâ0ѵ‰£z5Ö!_À½Ñö†{£€êí&ŽiÌ×3q´Ä1¢Œ¹ ß¶7ÜcÈ?¹¾IJ %t U{ÅðÛ…ZâÒsÂÄ¿9Æ(‰—Ì%¶¦E ä%wIÊšzËc~åîïÜàî8'8/eÃqNXöø«„ÿ~J®Ç1z‰:=înkày±0Ø„ÍváûÍœro›ÏαoÜ–vÓcâþNê Kz(i«O ¸»“’×NuMý½7 žçëië¿d·ày™Ã½¦'í~Ù·Ó³Ré¡‹ÈfÃóûG×ûq÷ò¶„u:ùüeßÞÃ1§7)ý²ÍŠ×Ãî¶÷p^h‡eIlÏK*:”5€Û²QSo‹•aâw11žèþ^^`ÁŠx©nÍËb¯?Д4Œ[ •5uW÷š×#1€ÜìŠK³=?Õ¤)i»@YS&¾ ÏþtX{Fn•ê8rí¯gÀº5[¥•5uW[×pOíÄ¡ÍMa]ßû!v(iÇ6gÊšºn‰4(`˰!Û–¤¤Ü†üEMý ,é…Q{³#q»pc÷?ÍÍM*¤¤Ü.\TÖÔÝå~¾Öfcâ`×f{âiJÀÉ®¢¬©;WÛ¯™/EØÇf„°´¤þ` ¹eæÒ˱ÓkÇï.% ã™eMý%醉ÃÄ/bâ™ ÔÍ .sœï­qþ<Ÿ}ÊÀ­ïÃ_ÔÔ_Ÿx…W°~ø 8ÚµÅòÜF–”5€ƒ]ð‹šú31@ß×°ÆÑ®=õ;”5€ƒ]ð‹šº31½•w™:ä°Nÿ¤]% ã¸6eMý­Œ£e­[­% ‡åÛ¥îç#¥EÝ¥îÑ£²¦þÖ#k8&UNmnzß·ëѪ%fÎm.+kê°%Aä´R9k^Ú +Ðê9£›”¶8/æÅ9œŒ‚!‡Â¥¢`H©+¸T •5uwG©õk˜8n˜Œiá?{0ž'5-Név#O¢ÕԲݠ“”5õ×/hEvmá8¦f”JÀÁ®Keeåqx1ñZB3< G QÇ>eÅû%êü-ñÌgvø²œ¥@Óã”Ûw·9ò2-åNxmBÞ\ê·sRȽí#¼LWyœO ¸»“š÷rƒN ¹»“Zæð¬|èŠ*Ôß ©Î ê$þ~[X_ï]•ï3ܯ‹÷s{2Ÿ¯o/S<î{¿îO~{¾'"[Ÿÿ[X/óÒó‹N7m-—šóü¹ooÏ·ÓÛ6âKíþÓX¯“ãYDêyöãh¶rCn«¬…÷Æ\êM1Þ÷’Ä5õ¶ä~}Ö¯MDé–2\¼xCÑwhÕ7“SÌ]=n™ö²ò¡3Gn&Å®þl¶>!JÆÁ,PÖÔ¡‰G~ ®*—%hïšÛßIÀpY¢ª„Þ q¯ùCžeWͧp« Ç¹ÊñììÔ¡XWŽÍ”5uÙïù]¶¥^8 ÓÖ­º9 Û8?§©¿ÑC‡ß‰Ã{‡5û”.dàvÑÎ*V¯Ã‰{œXÍýEâfW<Õ¥y”ƒhõ‡(ìeM=›XÏûÊIáDÏl‘´š§i_ùEMý]ÎÃÄï2;œóÎkì&^ràiMe€(i·8*kê.>L&~×r;¥™âµ»Ýw¸Ö¥ÞÙ(ÝþF3BøEMýõ‰é^aœ_µ‰ÆqR5Mº”5€ƒ]ð‹šú3ñ ó¡–+Æye²¿ÏºCëÖ\8Ø¿¨©;ç3\ËÖ,z‰C+¶—c>? UÕ,s,t™²¦þÎiC°¼i"®6ÛÚ$m4–æš’p[› ²¦þV,,áVÚ\Š¬Ô…¢¤aÛœ)kê¯%Îk˜Ò=¿ºŒŠŠ®·Ýp×”jiÆÑ.SÖÔŸ‰XÚ£ ̬6QÆò ¦˜B¥×Yl¢¬Ã‰£žýë®ãm}¿÷Œ«Æqç͹4()Ïm€C~QSws¼KDMh¹>ºÓ¤iÕMn@}^LÄï1A\ì4¹ÅëK¼Ù€(•´/ñfRÖÔ_K\ý¶ï¤$vM¶w¦¤¦þL´Ù-,0†â5Ì›%e à0„À/jên`™—ö$y ð$ñòÐBJ€–×´kŠÀíÑTÖÔÝ )3íï7ñaâåÑ…TdÙÞÆE äåÑRÖÔÛ ©óWï®"½ßŽõy“¦¤z¿K¼KÇO>аΞ£ˆé’yËXŒÝöxz‚?çK:\@ÿÄÕëâÙë-ÎþšTI†04mÛ“âVŒ¿\¨ JåWr7Hmw™ò‰G“â)ç·•KÊÀÁ+øEMý™¸—WÊÒʹ­sà½DJð#[瀲¦þV?û¢«²ÈÁ®K¼u(™x‰7 ¢²¦M\m‚Ž£4rÓã5œŸèìPÒnc:*kênõþT—"rksÑ–|c¯CIÃ8¶9SÖÔaKÜl傃pBvµµ RÖPÛ¥Ð/jên`ÙãŒnk«Û€í²g—_0(! †kÖT%ôwÏöôJe_áhUû‘=«)"šúókÕUìÌéâ,äõ%[8\œ«ªúÈã&þžL<ËÈ1>زv©ƒö3’ † ©Jè/|·ïá5ÅXê³V-¶ë­¦¤aÝ2eM]šxoO­ª2±p²kÍ/0×´21s¶++kêÏÄ´÷Õ%nP‡n/NŸÓ}¾ê5PÖnÝþ¢¦î:ÃãÔYZàh×*²´HYcUYZüEMý™xäylݯæñ´hJóªn€µÍ‹ºñÇ$tçÞ¶…[ÖU€Cf.Ý[‡’†q,e™²¦þVÄÛ”— Õ¸­?Rý¾}Ž )j ·Õ*kên’^J<‹º rkséuÇÛYWl¢pls¦¬©Ã–˜Þ1ÞîTM.ÜØÅ=Ïåv(iG»LYS&Æy^ÙH•ª À©¨š VЪÔZ8@YSw—sZ¥Š V‰CMæÎûõ(õ«À¹2ÝlݪÉGyæ›ËƱ¸°„ô¾Œ>e àP\€_ÔÔÝ'ü6‰àr¸p±$QÒXÄöޤ¬©»–;ÿü¦zP(Æá;Çkz”Fgã8„˜²¦þ–8ÉÝ×vâÐûM¥P%a5Ó¼›®e5õ× ÓM¶³y› q˜SáÈMHSši§9uQÖÔ‰û\6çÁ8f@.›…HÊÉà0~À/jênT‰G\Þd…ùMä–öÜö°îÏkì4% ãöeMýe@á.å7‘[Únw(i·´'*kê.šZ€zú9 {ØÚ§O‘’pèý@YÓOd@WϹÄ3žèô¼x3¾N{czœ²ž Óãþö¾–ü`{0—›J¿•sBìn[áë*ùo>'àîNêÞíElxRȽ”¾rª+êï·ôýÞ•øLÏ¡ŸÝyyùšÃ½ß÷¡6Dþþ;8ï½£=¯¿ù/ÚtúN3lפNøgì¼yö®4-¸ÛšpX+Ä?îõ¾»Ý¡¬ÜÖ ø‹šº[A\gXÞq‚Êãh×Ò‚³OY8Ø¿¨©;ï%¤úÛZoVÜ*PqèÊ7Å;5€C ”5õW—Šƒ_~œƒMnvÅn3=Ïñ% ãh—)kêÏD¼lq …Ü\x9kJÀmÁ…Êšº+M¥íQæwçÏ­8´¹­<ºÙ¡¤aÛœ)kê°%®a/_GCÈyÇÿÜ·>% ä0„À/jêo`9­î!· ÷^CÚ`½º”4€Û…‹Êšz»œ×é(ª¢Ä‹]ë´„s­o% àÅ.RÖÔ›‰i}årëR;pœž¹LÔ¡õ\ójSnø‹šú»œí’cáR»îp¶ûpeƒ]ð‹šº3ñ*GÌ©gä–‘¾6{m€¦¤a2Ò ¬©¿ätl-sóøB`Ôö¼±ž¦$`zdògÜ=ÙôO9uØ´FS²Ï8xÊšº4qUó:àØãö0º¤Ü‡~QSý`Ú§Z &ÀÙ.±©3ÐÚD±Q3þ¢¦þL¼Â¾ªVdíŠÃCîò%e à`ü¢¦îLL·-žÇ_êÊMáT£9òMM«ÊMæ\£)øHêo½|/–4£ep¨Ñ@ûÔ”*7ÀaQÊšú[¥%ØÌ­8´¹5Ls³O$RÒ0ŽmΔ5uزµ`mbádWÞ´°C+ˇdWÙÌPR&¦iÈ« Ô—"p*¹Î÷\?ƒ´*Ä%WPÖÔÝåû­Yí6ŠìÚÊ›†;”4€ƒ] ¬©?—0-jŽgK®ñŸÍk>€r!8Lfà5u7Źΰªè=rºpÏvog¤Õå|¶û5£²¦îZ"”šAamîðAA«Cé6)Ë`š¤.–º«–¡Í-áhŸCJÀi)Êšºk‰X©L,œ.Ü% 4­.çÂÉ®¢¬©;Ï;gÈ›»s™ã²Çkø™>KÊÀmÁ_ÔÔßÀ²”'«)}ܲúq¼=óû5E àÕeMý%øc ȹJß#·¬~l[¹`Õ¡¤ܲú¨¬©»ÿ]ÊÈM¢p*5\ÍÍS¢Õ„ýjnˆ’²¦ŸHðŒë¼‡ô¶¼³N£÷xz|.×(:“ú¨ÓãŸÙÅùpíõîkjn> ·j7WAÊ›ˆ Ð/jêmØ&~·ÝžŸµ ñ²òY·¹LÎ;”4ŒÛÊ•5u·&~çË™âMÈ- …—³¦¤ÜÂP¨¬©·õÐh‰c`ù"&b»ÀK¹]¸Ø¶4%YÔˆHYSÏ—ó0ñ;˜H—"ž”]¸h‹¤¬Ü.\üEM=_ÎÃÄï1ÅÐñÑ£ESÒØDD†IÝ÷†‰Ãįgâ˜'‡‰¾Mkç±bùr&Ž–8LüË(Ê¿†‰cŠ3ZâXÆÀ2Zâ˜låË™ñOâ%,J¶hJÆ-,ŠÊšº‹Ò)Aü“x ‹’-š’ð%eM½EHô‰ÆOϱÆ}³÷Êc$´Ça_¬§¨(èô¸» “×}·y KXófŒ¿™“Bînwá8ËÞó~zxRÈýT<âûhö&îî¤Î9lÛûéd:)äþNê×ÕnCNÜÝIÉ^®êýþ~;v¿w°^ãLþýÒÏí}>ß^Ã=ÝóõK6ÏNâ¾ßûùÙîûùÍã÷ë*øE§{NaÙÒ¿dót^wì-•[?c³ðËóôèÚÂ<·}#‡5å5Ùûú$e ඦÄ_ÔÔÝJs˜ø}M¤ò#r+V‚-J`¹+ñÏ#©¿æã.€Ü슣ĺ¼ŸîPÒ0v²¦®M¤¥6r[˜£-š’p[˜£²¦îJ˜£%~_iPÀSµ!m‘”5€Û‚¿¨©»e\ÎÃÄ/g⸜‡‰_ÃDÊÉ#·T=š¨)i€‰–ªG»$õ—µ&¿œ‰£O&}›8Jaß×DZm ·µ Ú¢)i·µ *kênÅ2Zâ(…}9Gb˜ø5LSœÑÇèì{tóÄaâ—3qÄH¾‡‰øÄr{¾mÑ”4ŒÃ󠬩¿§>ð”ð‰ äö|Ú¢)i·ç;PYSwO}|ý>ñÃXãí9ÖxÇÖ²ÌW³Ax‡oËbËë§§;@§Ç?±qø69öz›î vÐlÃÓ6íáz^ ® .cþ˜„ÞÆ«áÞwr/ˆËJÑÌé²ÌÁ¿‰‚þ–>÷Î÷hÍk?ä¶RŒ}ÛÓ¡õ(i‡•"(kêÚD¢‘Û€Ž¶hJÀm@GeMÝ-}FKü¾&ÒÚOÕVŠh‹¤¬ÜVŠø‹š:QðJD\.[%$$ÃåšEU ½]Çý1îyt ÌÐ!·Äš’ –¸ÃaBR9¼aâ0ñË™8æ‚ÃÄa¢kGk¬J¾€{£íÊÖ?ÛÄQc&~ Çlf´Ä1,û–·e ÓãMéÛüoŽgš\{—¢r›¢²¦îšà0ñûšHeg<)«Q£-’’r+Sã/jêmD¡ƒ‡Ä&ñ’ï$[4E à–ïDeMÝ¥>é” ±I¼ä;ÉMQyÉw’²¦ÞRŸ_¹ÖðaqöA´ &Ç7{Ü>t9Æ:Q§ÇÝí‡ ×VeB™Ìý†N ¹· ‰·õ×tíõ~ØÄÝ”|RÈýÔöøY¯ú¤€û;©2¬N ¸»“²[º|RÈýTð«“îî¤äxTS¿íØï×áizú?þ!›¢ÏïÝ–§×øÇüèôþÕ}{K÷W=4šYÜ2©fxîÖÝ“*Íßa%Nʺ)>)E<©2 T'å-S„'eC?Ÿ”¿ÊžT™¤U'U¸Ç“*Óéê¤Ü•§°ë. >)ãOªŒGÕIñ8õý†ü%Ï3lˆøÇòŒ!yÆò¼ñ¥þÑ}zzŽ¿ÏæÉMõ«ëõ4˜Ÿ÷®—méVɾßÁNØž9gìwRÉô}¨ÛŽó:çù×ÚL˜—gò˜ ë“ßÎSÏ3Lç=OË'¿~=sÈ9Lkº9!¾6¿ÿÏÿþ¿øÿþ?ü‡GãÌšXML/inst/exampleData/mathmlRoot.xml0000644000175100001440000000041713607633707017020 0ustar hornikusers 1 - x 2 3 XML/inst/exampleData/entityValue0000644000175100001440000000013213607633705016374 0ustar hornikusersThis is text that is referenced from foo.dtd as an entity and can be multiple lines long! XML/inst/exampleData/rxinclude.xml0000644000175100001440000000052013607633725016662 0ustar hornikusers 1 2 3 4 5 6 7 8 9 10 XML/inst/exampleData/nodes3.xml0000644000175100001440000000031413607633725016061 0ustar hornikusers XML/inst/exampleData/README0000644000175100001440000000065413607633725015033 0ustar hornikusers dataFrameEvent.R example of closure for reading a data frame via the event based parser. foo.dtd DTD used for testing the DTD parsing facilities (getDTD()). job.xml example XML file taken from the libxml-1.7.3 examples. enhancedDataFrame.R version of the event-driven data frame reader with more error checking. Some SVG files are available from http://plasma-gate.weizmann.ac.il/Grace/gallery/XML/inst/exampleData/same.xml0000644000175100001440000000016313607633725015615 0ustar hornikusers A B C XML/inst/exampleData/author1.xml0000644000175100001440000000046213607633705016253 0ustar hornikusers Mark Twain XML/inst/exampleData/size.xml0000644000175100001440000000056713607633725015652 0ustar hornikusers 0 0 500 0 1 300 1 0 200 1 1 400 10 0 XML/inst/exampleData/generalInfo.xml0000644000175100001440000000056613607633706017127 0ustar hornikusers Duncan Temple Lang duncan@wald.ucdavis.edu Joe Blogs XML/inst/exampleData/functionTemplate.xml0000644000175100001440000000173013607633706020211 0ustar hornikusers XML/inst/exampleData/namespaces1.xml0000644000175100001440000000042613607633710017064 0ustar hornikusers XML/inst/exampleData/vars.xml0000644000175100001440000000127713607633725015652 0ustar hornikusers 100 23 666 XML/inst/exampleData/kiva_lender.xml0000644000175100001440000200617513607633725017166 0ustar hornikusers
    57680312010-01-29T20:00:23Z1000
    mattMatt128291San Francisco CAUSmatt2006-01-01T09:01:01Zwww.socialedge.org/blogs/kiva-chroniclesEntrepreneurI love the stories. I co-founded a startup nonprofit (this one!) and I work with an amazing group of people dreaming up ways to alleviate poverty through personal lending. 8923jessicaJessica1972921San Francisco CAUSjessica2006-01-01T09:01:01Zwww.kiva.orgKiva cofounderLife is about connecting with each other.5426skylarSkylar1986091San Francisco CAUSskylar2006-01-01T09:01:01Zlarw.comMaking Kiva transparent and accessibleI believe empowering local entrepreneurs to develop their communities will eradicate many of the injustices and evils in our world. It works to level the socio-economic barriers between us, and return us to the relationship which we were created to be in with one another - equal.1693michaelMike & Carol1144101Lake Oswego ORUSmichael2006-01-01T09:01:01ZWe are amazed by the opportunities we get to connect with people through kiva. We are huge fans of the organization and the staff!I was first a Navy pilot and then I ran a company that manufactured lumber and paper. Carol was a nurse and a wonderful mother. 12METSMegan Tompkins-Stange2889611Ann Arbor MIUSMETS2006-01-01T09:01:01ZPhD student in Education Policy7ryanRyan Pressler787061Pleasanton CAUSryan2006-01-01T09:01:01Zwww.ryanpressler.comProduct DesignerI understand the importance of bringing an idea to fruition in order to better one's family, self, and community. I feel that primitive ideas such as agriculture are most important. When the mind and body is nourished our creativity can flourish!I design interactive things on tv screens that allow you to access informative and entertaining content.10sandraSandra945081Pittsburgh PAUSsandra2006-01-01T09:01:01Zwww.kiva.orgTeacherOur daughter Jessica Jackley (founder of Kiva.org) and our son Adam (teaching pastor) have shown us what it means to think and feel with your heart. I want to be able to make a difference in peoples lives just as my children have done. We have so much and so many have so little. I am blessed to have wonderful role models to watch as they both change the world.I teach first grade (6-7 year olds) and believe in lifelong learning. I believe in my children and their dreams! 26erikErikSan Carlos CAUSerik2006-01-01T09:01:01Zwww.aboutairportparking.com61davidDave27711Pittsburgh PAUSdavid2006-01-01T09:01:01Zwww.iwavz.comConsultantI want to help people stand on their own feet and be proud of what they can do, so they can help othersconnect people with ideas that can improve life37patrickPatrickRedwood City CAUSpatrick2006-01-01T09:01:01ZAttorneyI think it is important for each of us to do what we can to help each other along.I am a lawyer who helps people and companies develop and protect their inventions.25grahamGraham15641San Francisco CAUSgraham2006-01-01T09:01:01Zwww.chiseldesign.com/people/interaction designerall small businesses need access to capital.17hopeHope94941Bellevue WAUShope2006-01-01T09:01:01Z2danDan VanLos Altos hills CAUSdan2006-01-01T09:01:01Z3212brookeRyan & Brooke1144051Seattle WAUSbrooke2006-01-01T09:01:01ZHomebuilderWe love Kiva and all that it does. We love having our family connected to the world in this way.Ryan builds houses and Brooke keeps our house running212jeevanJeevan742341San Francisco CAUSjeevan2006-01-01T09:01:01Zconsultant of some kindit is the right thing to do.I work with small computers and make them do nice stuff for people, if all goes well.7peter8425Peter and Jane Carpenter2091631CaUSpeter84252006-01-01T09:01:01ZAdventure PhilanthropistWe are committed to helping others realize their full potential through innovation and hard work by adding our capital to their dreams.3emilyEmily1945381San Francisco CAUSemily2006-01-01T09:01:01ZI'd like to make a difference.161katieandtylerKatie and Tyler107281Bellevue WAUSkatieandtyler2006-01-01T09:01:01ZBusiness ManagementWe believe that "to whom much is given, much is expected." God has given us extraordinary blessings so we give on to others. Kiva.org is an opportunity to really connect with people who have completely different lives than ours. It is amazing to be a part of this incredible vision! Katie works for her family's business selling plumbing repair parts in Seattle. Tyler works for Advaiya, a consulting company in Redmond, Washington. 142bradBrad L2218251San Francisco CAUSbrad2006-01-01T09:01:01Zbradlauster.comUser Experience Designer1premalPremal3104151San Francisco CAUSpremal2006-01-01T09:01:01Zwww.kiva.orgPresident, Kiva.orgthere is no them.I work to help build Kiva's team and improve its service. I absolutely love working at Kiva because of the potential of this idea and the great people it has attracted along the way.17017michael8403MichaelSomerville NJUSmichael84032006-01-01T09:01:01Zwww.idia.netCivics EducationThese are people who have decided to take their destiny in their own hands... they're not sitting around waiting for things to be given to them.I run an organization that gets people involved in their communities, because I believe that one person can make a real difference both in their own society, and in the broader world.22daveschappelldaveschappell1975111Seattle WAUSdaveschappell2006-01-01T09:01:01Zwww.nosnivelling.comInternet entrepreneur at TeachStreet.comI want to empower people to improve their own livesI help people find great local teachers and schools, so they can learn new skills21adamAdam + Katie134381Pasadena CAUSadam2006-01-01T09:01:01ZPhysician Assistant and Seminary StudentWe loan as an active expression of our faith in God and belief in every entrepreneur in whom we invest. Katie does orthopedic surgery and Adam reads and writes about theology. 521robinRobin203761Castro Valley CAUSrobin2006-01-01T09:01:01ZDesignerTo offset my white middle class guiltI sit in front of a computer screen and pretend to interact with the world.12schnuckM,S,J, and T Schnuck69141San Francisco CAUSschnuck2006-01-01T09:01:01ZBusiness Analyst, Student, Online Marketing GuysWe loan because Kiva provides the lender with an incredible and unique opportunity to learn about, support, and connect with world-changing entrepreneurs. <p> Kiva co-founder Jessica Jackley Flannery is one of my great friends and favorite people. Like her organization, Jessica is incredible and unique and she inspires everyone who is lucky enough to meet or know her. You can\'t help but want to be involved in everything she does. <p> In addition, my sweet new husband and brothers-in-law are so cool, progressive and all-around amazing men that they agreed to support Kiva in lue of Christmas presents. Matt and Tommy build websites on a variety of topics (their websites are similar to magazines).<br>\r\nJason works for a grocery store and figures out how to buy products at a rate that brings savings to the consumer.<br>\r\nI (Shannon) am in school to learn how to work with students who are having trouble learning.<br>\r\nAs a group we enjoy St. Louis baseball, golf, watching ESPN, yoga, and milk.41karenKaren18881Berkeley CAUSkaren2006-01-01T09:01:01ZTeacherI traveled to Cambodia in the summer of 2006. I was able to see many lives changed for the better because of Kiva loans.I teach seventh grade history in Northern California.64pontusPontus319451Menlo Park CAUSpontus2006-01-01T09:01:01ZStudentMicrofinance is the most effective form of development support I know of.Am currently studying business at the graduate level.71maryMary155321San Mateo CAUSmary2006-01-01T09:01:01ZHomeschooling parentI wish I could do more.I teach my children.82david9963David17251New York NYUSdavid99632006-01-01T09:01:01ZTeacherMoney can do a lot of good -- especially in the hands of hard working people. I teach global history and civics at a Manhattan public high school. My students are 14 and 15 years old. 3carlCarl3546241New York NYUScarl2006-01-01T09:01:01ZProducer, Post-Production SupervisorI choose to speak in terms of microcredit.I make movies.391dennis4605dennis1472671San Francisco Bay Area CAUSdennis46052006-01-01T09:01:01ZDigital Media SoftwareI love to see more compassion in the world of finance and lending. Everyone deserves a fair chance to get ahead under conditions they can make a life with.Creating computer programs that show pictures and movies and songs21silviaSilvia16231Stanford CAUSsilvia2006-01-01T09:01:01Zwww.ghcorps.orgEvery entrepreneur deserves a fair chance.Fulbright Scholar in Romania81carlhaynesCarl HaynesSanta Clara CAUScarlhaynes2006-01-01T09:01:01Zwww.eastafricatechventures.com17kurtKurt and Susanne1684781Dallas TXUSkurt2006-01-01T09:01:01Zkurtjohnson.netManagement Consultant373rodneyRodneyNew York NYUSrodney2006-01-01T09:01:01Z53amfAndrew1098941San Francisco CAUSamf2006-01-01T09:01:01Zwww.prosper.com/I know that even these small loans can make a big difference.I work for a company like Kiva that lets Americans lend to other Americans.6toddToddCAUStodd2006-01-01T09:01:01Z4andrewjonesandrew1248301Bangkok FLTHandrewjones2006-01-01T09:01:01Zdignifieddevil.wordpress.comteacherit's fun242todd8176Todd4741301Atlanta GAUStodd81762006-01-01T09:01:01ZbankingAre you kidding me? Kiva is the coolest thing ever.My job is just like microfinance, only with a lot more paperwork.405tobiasTobias Buckell62201Bluffton OHUStobias2006-01-01T09:01:01Zwww.tobiasbuckell.comauthorgrew up in the developing world, know the concept is solid and much needed6EricSEric17911Saint Louis MOUSEricS2006-01-01T09:01:01Zwww.facebook.com/estiensrobin hood schemerI believe in you!I'm a freelance writer, mercenary statistician, coffee drinker, book lover, and program coordinator at a community center in St. Louis.362kennethandevelynKenneth and Evelyn633011Seattle WAUSkennethandevelyn2006-01-01T09:01:01ZHe messes with computers, she's in law school.4501subbaraoSubbarao199111Englewood NJUSsubbarao2006-01-01T09:01:01Zwww.edhee-adhee.comProject Manager - Softwareit is inspiring and humbling to see hardworking families strive and rise out of harsh \'man-made\' circumstances. \\\\r\\\\n I work in an office with computers and assist \'big\' businesses handle their day-to-day affairs - translation: software systems designer. \\\\r\\\\n151andrew6564AndrewNew Canaan CTUSandrew65642006-01-01T09:01:01ZI loan because I can. How can I ever expect the world to change if I'm not doing anything to change it? Kiva offers a chance for individuals to help themselves - everyone should have that opportunity so I'm happy to support an organization which recognizes that.9daniel7425Dan & Gin16401San Francisco CAUSdaniel74252006-01-01T09:01:01ZHuman Resources"When a poor person dies of hunger, it has not happened because God did not take care of him or her. It has happened because neither you nor I wanted to give that person what he or she needed." - Mother Teresa31jeremy4280JeremyNorth Balwyn VictoriaAUjeremy42802006-01-01T09:01:01Z6stephendannStephen Dann1966951Canberra ACTAUstephendann2006-01-01T09:01:01Zstephendann.com/Senior Lecturer in Marketingsmall changes made by individuals pool together to make major changes in societyI spend my time looking at ways to adapt commercial business activity to change the world into a better place.191kimmykKim2853301Elk Grove Village ILUSkimmyk2006-01-01T09:01:01Zwww.linkedin.com/in/kimkieferMarketingI am able.I am the Director of Marketing for a company in Chicago, IL that designs, implements, and maintains IP Telephony networks and provides network security for business all over the United States.17charlesCharles44621Vancouver BCCAcharles2006-01-01T09:01:01Zwww.globalyouthfund.orgJournalistWe should all do what we can.I\'m staring a new charity to support youth in working together to create positive global change.8andyboettcherAndy BoettcherWashington DCUSandyboettcher2006-01-01T09:01:01Z7joshua6241JoshTel Aviv ILILjoshua62412006-01-01T09:01:01Z4dave6169Dave3289631Boise IDUSdave61692006-01-01T09:01:01Zwww.boldapproach.comAuthor, Marketer, PersuasionistI love entrepreneursI write books and train entrepreneurs worldwide141DanRaineDan Raine216981Manchester Greater ManchesterGBDanRaine2006-01-01T09:01:01Zhttp://www.ImmediateEdge.com/Internet Marketer16stonyhillstonyhillPort Ludlow WAUSstonyhill2006-01-01T09:01:01Z19leslie8824Leslie133151Watertown MAUSleslie88242006-01-01T09:01:01ZRetired36misterajcAndrew57011FT LAUDERDALE FLUSmisterajc2006-01-01T09:01:01Zwww.flickr.com/photos/misterajc/Programmer1663chrisprewPrew Family2386401Minneapolis MNUSchrisprew2006-01-01T09:01:01Zso when my girls are grown up, hopefully the world will be a slightly better place.7kaitlinKaitlinDayton OHUSkaitlin2006-01-01T09:01:01ZResearcherPublic policy research.3andrew5549Andrew65101Lowell MAUSandrew55492006-01-01T09:01:01Zwww.andrew.wetmore.comProject Manager / playwrightGoing directly to where people are in need cuts down on the chance that funds will go astray, and helps give people confidence and a sense of control over their lives. If we are one big family, we should act like it and equip those who have little, so they can become much!During the day I am helping build the Course Development Studio and Billion Kids Library for Open Learning Exchange, www.ole.org. In my own time I write plays.163debraDebraIndianapolis INUSdebra2006-01-01T09:01:01ZSAHM & artistwhat a cool opportunity! How could anyone pass this up?! I'm a mother--super important job. I'm also an artist and I do this part-time now when time is available.5patsyPatsy53651Pasadena CAUSpatsy2006-01-01T09:01:01ZWhat goes around, comes around.52emmaspapaTrey (Papa) & Emma2201021San Francisco CAUSemmaspapa2006-01-01T09:01:01Zwww.lathefamily.orgBiologistI have a start-up company and I know how difficult it is to get started, and how wonderful it is to get some early help! I also want to teach my daughter (that is her photo) from an early age that helping others is our responsibility and our blessing. She enjoys helping me choose and having me read to her the updates. I own a small company that does biology research and training for other scientists in both universities and the biotech industry.241mischiMischi Carter54081Seattle WAUSmischi2006-01-01T09:01:01Zpelagiascuba.comEducator5benjaminBenSeattle WAUSbenjamin2006-01-01T09:01:01ZSoftware Test Developer2timothy8125TimothyWest Haven CTUStimothy81252006-01-01T09:01:01ZAdministrative AssistantI don't have much to give, but for the people looking for loans on this website, my small amount makes a big difference to their lives. It's a great feeling. 8mole333mole33333571Brooklyn NYUSmole3332006-01-01T09:01:01Zdailygotham.comResearch ScientistThis is the best way I can make a difference internationally. I described my reasons behind helping Kiva and other groups <a href="http://www.culturekitchen.com/mole333/blog/kiva_microlending_revisited">here on the internet</a>.I am a scientist currently studying how diet, reproduction and aging are coordinated in an animal.275brianbauteBrian Baute2624121Burlington NCUSbrianbaute2006-01-01T09:01:01Zwww.brianbaute.comInternet & E-Commerce Strategist94tessaTessa424751AmsterdamNLtessa2006-01-01T09:01:01Zwww.thenextspeaker.comOwner/Director of The Next SpeakerWe almost collectively gave up on the developing countries. Kiva is a fantastic initiative. Micro-lending might be critized, it might not be the perfect option, but it is currently the best option to help the poor and to circumvent corrupt governments. I strongly believe that development comes from these simple, but highly effective initiatives Particularly this one, as it stimulates entrepreneurship, the basis of all development.I am the owner of a speakersbureau, The Next Speaker. My bureau represents speakers that talk about new media, new technology, and innovation and most of them are entrepreneurs. My filosophy is that most of the innovation in a country takes place in smaller companies that can go faster and have the freedom to try out new ideas. The Next Speaker mediates between those speakers and companies that would like to learn about the latest developments.191susan9268SusanHoboken NJUSsusan92682006-01-01T09:01:01Z5david4414David & TrishMesa AZUSdavid44142006-01-01T09:01:01Z6matt1696Matt55211Brooklyn NYUSmatt16962006-01-01T09:01:01Zmattraymusic.commusicianRunning your own business is rewarding -- I am thrilled to help fund wonderful people through Kiva.I am a professional jazz pianist. (The picture is of me playing accordian -- I will add a piano picture soon).19leslie5099LeslieCAUSleslie50992006-01-01T09:01:01Z4stephen6473StephenRankin ILUSstephen64732006-01-01T09:01:01Z10koenkoenNLkoen2006-01-01T09:01:01Z4heidiHeidi2465471Oakland CAUSheidi2006-01-01T09:01:01Zwww.circleofancestors.orgCircle of Ancestors reconnects people with their own ancestral traditions.41mark9315Mark & Laurel442791Lacombe ABCAmark93152006-01-01T09:01:01Z73shakeelShakeelBerkeley CAUSshakeel2006-01-01T09:01:01ZCivil EngineerA little capital, given directly to the person who can make the best use of it, seems to be a really efficient way to help others work their way out of poverty. Designing and building systems that remove pollution from the water and soil all around us.9rosemaryRosemaryAustin TXUSrosemary2006-01-01T09:01:01Z8david3810David and MarieMidland MIUSdavid38102006-01-01T09:01:01Z127patricia8550PattySouth Daytona FLUSpatricia85502006-01-01T09:01:01Zspacebawl.blogspot.comLibrarianPeople in the U.S. are very lucky because we have many opportunities to be successful. But we often take that for granted and don\'t realize how hard it is for people in other countries to support themselves. I am very happy that Kiva has given me an opportunity to share my success with someone else who works hard and deserves opportunities like I have. I hope to encourage my friends and family to follow my example.I work in a university library, helping students with research for their studies.5ryanmcminnRyan1103271Seattle WAUSryanmcminn2006-01-01T09:01:01Zwww.ryanmcminn.comMan About Town38brian5281Brian53931Fairbanks AKUSbrian52812006-01-01T09:01:01ZUniversity ChancellorI can make a difference for Kiva borrowers.I am Chancellor at the University of Alaska Fairbanks - America's Arctic Research University.20902leslieinjapanLeslie2325171Yokosuka Team JapanJPleslieinjapan2006-01-01T09:01:01Zkivajapan.jpAbundance coachI believe in helping people, especially women, raise their quality of life by recognizing the abundance in their environments. 環境ã®è±Šã‹ã•ã«æ°—付ã„ã¦ç”Ÿæ´»ã‚’å‘上ã§ãるよã†ã«äººã€ç‰¹ã«å¥³æ€§ã€ã‚’支æ´ã™ã‚‹ã“ã¨ã‚’ä¿¡ã˜ã¦ã„ã¾ã™ã€‚ Please check my blog: http://www.yutakasaguide.orgBy asking the right questions and giving support, I help my clients recognize their abundance and find ways to create ripples in the world by sharing that abundance, one person at a time.32923julieJulieMonument COUSjulie2006-01-01T09:01:01ZI wish to represent the citizens of the US in a positive manner by helping others. There are many of us who wish for international peace. I support the individual - and Kiva gives me a way to do so.15dennis6399Dennis29131Bedford TXUSdennis63992006-01-01T09:01:01ZPedestrian Attorneydonating money to the peoples of developing nations cleanses my soul of the opportunistic misdeeds i commit in the first world. It\'s sort of a modern form of the Catholic indulgences. I defend jaywalkers in the court of law. Somehow, exercising your right to walk across the street in our supposedly free nation can earn you a citation from local law enforcement.21leonieandnicleonie & nic wise4405721LondonGBleonieandnic2006-01-01T09:01:01ZSoftware developer, Operations ManagerMany people have helped us out in times of need and we are continually looking to do the same for othersNic is a really smart guy, who writes computer programs and applications. He's an independant contractor who works for companies in London & Denmark. Leonie has been a project manager until recently. Now she's the operations manager for a recruitment consultancy in London, UK.343robinsloanRobin1104981San Francisco CAUSrobinsloan2006-01-01T09:01:01Zrobinsloan.cominternet nerdI work at a TV network.124mitchell9777Dylan M AustinSan Diego CAUSmitchell97772006-01-01T09:01:01ZwebA small effort in distributing the lavishness in which I effortlessly liveI build things on the internet1milliganDavid80121NEUSmilligan2006-01-01T09:01:01ZPatent Attorney423michael3789Leisureguy380481Monterey CAUSmichael37892006-01-01T09:01:01Zleisureguy.wordpress.comRetired91jeremySmooveJ1723681San Francisco CAUSjeremy2006-01-01T09:01:01Zwww.frazao.org/kivacloudDirector of Technology, Kiva.orgI make kiva go.5114whogivesashirtwhogivesashirtToronto ONCAwhogivesashirt2006-01-01T09:01:01Zwww.whogivesashirt.caSelf-employedI have the means, and would appreciate the opportunity if I were on the other side of the spectrum.Second hand clothing sales.3austinmayorAustin Mayor57721Chicagoland IllinoisUSaustinmayor2006-01-01T09:01:01Zaustinmayor.blogspot.comFictionI know how much strength it takes to ask strangers for help. And the men and women borrowing through Kiva not only have that strength, they are also willing to make themselves publicly accountable for the help they receive. Who wouldn't want to get behind that? Austin Mayor is a fictional character who blogs about politics, music, cartoons, peace, justice and other interests in Chicagoland Illinois.1stianStian1254171Oslo AKUSstian2006-01-01T09:01:01Zreganmian.net/blogstudent7robertwRobert2367261Pasadena CAUSrobertw2006-01-01T09:01:01ZStudentStudent5alexandreAlexandreBrooklyn NYUSalexandre2006-01-01T09:01:01Zpublishing peon22tom4278Tom2473171Redwood City CAUStom42782006-01-01T09:01:01Z42fredFred HapgoodBrighton MAUSfred2006-01-01T09:01:01Z10dinaDina2686801Boulder COUSdina2006-01-01T09:01:01Z162john8304Lee374921Keizer ORUSjohn83042006-01-01T09:01:01ZRetired EngineerI have been very fortunate in my life and feel it is now my turn to aid others with a helping hand.75douglasDouglas446061Charlotte NCUSdouglas2006-01-01T09:01:01Zwww.douglascoler.comActor/DirectorI have experienced first hand the transforming power of a simple act of kindness, and I want to share that with others who are determined to realize their dreams.I appear on stage, in films, television, and on the radio.24aaron3710Aaron419701Cordova TNUSaaron37102006-01-01T09:01:01ZProject Engineerit allows me to help make dreams come true.31chris7655Chris43741Marietta GAUSchris76552006-01-01T09:01:01ZComputer TechnicianEveryone deserves a chance to make a better life for themselves, their family, and their community.I work for an international news company supporting our employees around the world reporting using computer laptops, satellite phones, and video cameras.2iolaireIolaire77551Arlington VAUSiolaire2006-01-01T09:01:01Ziolaire.netManager AdvisorySuccess starts with a small dream. Sometimes it feels like here in the US people forget that. I know that most likely someone else can achieve far more with my $25 than I will.I work with real estate statistics, producing reports and books which show how commercial buildings are being built, occupied and sold throughout the US.48deanDean Evans76731Chicago ILUSdean2006-01-01T09:01:01Zwww.deanevans.netActorIt\'s a good way for someone who makes very little money, like myself, to help out others.I perform in and write plays for theater companies in Chicago. Occasionally I\'m on TV and in movies.2jillJill84491Champaign ILUSjill2006-01-01T09:01:01ZManager of Instructional TechnologyI believe in the dignity of each human being.I help people use technology in schools.10robert8997Bob2115351Phoenixville PAUSrobert89972006-01-01T09:01:01Zwww.FrontierServiceDesign.comEntrepreneurKarmaI help companies design and launch new services to create new sources of revenue for their business.19randRand Fitzpatrick4507061Altadena CAUSrand2006-01-01T09:01:01Znulldivide.blogspot.comEntrepreneur/DesignerA little compassion here turns into a lot of leverage for entrepreneurs out there - leverage that can affect very real change in the world.I specialize in technical product management, designing products that leverage information - helping people understand the world.51melissafaithMelissa Faith235301NCUSmelissafaith2006-01-01T09:01:01ZstudentI can. Why wouldn't I?I study the French language.21frogScott2457261Buenos AIres DCARfrog2006-01-01T09:01:01Zguyfrog.orgWeb Developerthere is a needI connect people that want to solve really big problems75seanSeanGotha FLUSsean2006-01-01T09:01:01ZBusinessmanIt\'s a great way to give someone a helping hand to make a long-term living for themselves.Accounting and business management25charlieCharlieWaldron WAUScharlie2006-01-01T09:01:01Zhttp://rheme.netprogrammerI help people use computers to talk to each other.3sucynisucy25741old town MEUSsucy2006-01-01T09:01:01ZStudentIt\'s like donating money--except I get it back.I\'m a part time student and I live off of disability--I\'m paralyzed.10rjrRobKivaFriends.org NYUSrjr2006-01-01T09:01:01ZIT Program Manager172CalvinLawsonCalvin Lawson18351Seattle WAUSCalvinLawson2006-01-01T09:01:01Zcalvinlawson.wordpress.com/Database DeveloperBecause it\'s an excellent idea, and I\'m curious as to how it works out.I work on a computer, to help make the internet.50peter5856Peter17561Eugene ORUSpeter58562006-01-01T09:01:01Zfaiththefinalfrontier.blogspot.com/BankerI first heard about microlending years ago but until I found out about Kiva in 2005 I didn't know of any way I could get involved. I loan mostly because I am excited to see how it will help the various entrepreneurs.I have been been in banking for 25+ years. I have always worked in "retail" banking - meaning that I have worked in branch offices. I started as a teller and worked my way through various positions including a few stints as a branch manager. Currently I work in a regional office helping a group of branches with issues related to day to day operations.445janJanLondon LondonGBjan2006-01-01T09:01:01Z40fractureFracture101431ABCAfracture2006-01-01T09:01:01Zboctaoe.blogspot.comSystems AnalystI work with computers at a very large phone company.9marieclaudemaudeclaude198691Montreal QuebecCAmarieclaude2006-01-01T09:01:01Z18fjarlqMatt Day3980311Orem UTUSfjarlq2006-01-01T09:01:01Zfjarlq.comStudentI have more than enough.Reading textbooks and trying to make sense out of them. :)133elizabethElizabethToronto OntarioCAelizabeth2006-01-01T09:01:01Zflickr.com/photos/lidbit/sets/writerI have travelled all over the world. In each country I have seen how much $1 means to people. My donation isn't a lot for me but I know it means a difference to those who receive it.I write ads.251jepaceJEP2993561Gilroy CAUSjepace2006-01-01T09:01:01Zwww.unhub.com/jepaceLand Developerit is an interesting way to make a positive impact on people's lives. I like the concept of "loan" vs "give" as a little hard work for the repayment is good for the soul.I spend millions of dollars and many years fighting through local government bureaucracies to turn land into lots for building houses on. 17maraMaraSomerville MAUSmara2006-01-01T09:01:01Z24huiskamplogan huiskampChicago ILUShuiskamp2006-01-01T09:01:01Zclimatestudios.comSome people need it more than we do. Ally & I will continue to re-loan as long as Kiva continues with this effort.451ssnyderSam Snyder1310051Lawrence KSUSssnyder2006-01-01T09:01:01Zwww.bigwinner.orgEveryone deserves the opportunity to succeed.29062fboosmanFrank Boosman77441Apex NCUSfboosman2006-01-01T09:01:01Zhttp://www.boosman.com/blogVideo game developmentIt gives me the opportunity to help people to become self-sufficient and build great lives for themselves.I run a business that creates video games -- games for people to play on their televisions. We try to create games that are easy to learn, quick to play, and above all, fun.311jeffrey1496jeffrey59331Allen TXUSjeffrey14962006-01-01T09:01:01Znetwork engineerI work with computers and computer networks to assist companies with data and voice communications.5helenHelen178611AKUShelen2006-01-01T09:01:01ZScientistI loan because I can. I want to give my child the best start in life, and other people should get the same chance.A researcher at an Oceanographic Institution, looking at how the living oceans really work.elizaElizaFairfax VAUSeliza2006-01-01T09:01:01ZEnvironmental Scientist63maryjoMary JoFederal Way WAUSmaryjo2006-01-01T09:01:01Zwww.flyawaycafe.comFlight AttendantIt's a small way that I can make a difference.2wayneWayne411421Auburn CAUSwayne2006-01-01T09:01:01ZBittermanI have been so fortunate thus far in my life. I feel it is my duty to try to leave a better world for the future. I pray that my little bit can help.68andreaAndreaDessauDEandrea2006-01-01T09:01:01Z7solmssenAndrew Solmssen52941West Hollywood CAUSsolmssen2006-01-01T09:01:01Zwww.bitboy.comComputer Consultant & Stand-Up ComedianKiva allows me to directly connect with and help people all over the world. I am truly grateful for the chance to use my small means to make a difference in someone\'s life and help them take advantage of the opportunities they have worked so hard to create.I help people with computers and computer networks, and I also entertain audiences with jokes and stories about computers and other funny things.53david4181David209941Alexandria VAUSdavid41812006-01-01T09:01:01ZCivil ServantCapitalism is the basis of freedom.I buy guns and bombs for the U.S. Navy.26jeff9862Jeff Burton3750471New Richmond WIUSjeff98622006-01-01T09:01:01ZComputer Programmer7kathryn8125hellbunnieDublinIEkathryn81252006-01-01T09:01:01Zhellbunnie.org/Postgrad Student6mike7888Mike2194401Tacoma WAUSmike78882006-01-01T09:01:01Z10kevin2557Kevin Kelly2382391Pacifica CAUSkevin25572006-01-01T09:01:01Zwww.kk.org/kk/Editor/Author/BloggerTo share is divine.I redistribute the future.1512royRo Mo1068161IDUSroy2006-01-01T09:01:01Z281carrieCarrie344451Ithaca NYUScarrie2006-01-01T09:01:01Z252karen7834KarenSan Francisco CAUSkaren78342006-01-01T09:01:01Zhousewifepeople should help each other.I take care of my four year old son and help teach my 14 year old stepson at home.4AGMycroftMycroftDallas TXUSAGMycroft2006-01-01T09:01:01Z18megan1967Megan2190601North Perth WAAUmegan19672006-01-01T09:01:01ZEconomistif you can, you shouldI am an economist with the Dept of Agriculture and Food Western Australia.36jtauberJames TauberBurlington MAUSjtauber2006-01-01T09:01:01Zjtauber.com/612martin1180Martin210201Hartlepool --GBmartin11802006-01-01T09:01:01ZSeafarerI want to help Africans lift themselves out of poverty. The richer nations have a duty to help the poorer.I am a Chief Engineer on a ship. I manage all the maintenance in the engine room and hotel areas.21jeanJean210651Scarborough ONTCAjean2006-01-01T09:01:01ZBookkeeperI enjoy knowing that there is someone able to get ahead in life with just a little help and that I can be a part of itI set up new companies bookkeeping system for their financials. Also look after animals for people that go on holidays. Either their place or mine. Enjoyable occupation42andyrAndy1777281Falls Church VAUSandyr2006-01-01T09:01:01Z4floraFlora Graham17851London LondonGBflora2006-01-01T09:01:01Zwww.floragraham.comWriterbeing able to support yourself and your family is important for happiness, independence and freedom.I write articles about science for newspapers and magazines.16alexander6631AlexanderAstoria NYUSalexander66312006-01-01T09:01:01ZScribeIt's the right thing to do.I make complicated technology easier to understand by explaining it in English.5brett6361Brett2666881Los Angeles CAUSbrett63612006-01-01T09:01:01ZAttorneyeveryone deserves a chance to better themselves.2addisonAddisonWAUSaddison2006-01-01T09:01:01ZLaw Student8ron5131RonLos Angeles CAUSron51312006-01-01T09:01:01ZWriter13chebuctonianDaniel50951Montreal QuebecCAchebuctonian2006-01-01T09:01:01Zwww.danielharan.comSoftware developerI want to be part of this social experiment. The amounts of money are so small by \"Western\" standards, it\'s a responsibility to help out.\r\n\r\nMicro-credit has incredible potential to lift people out of poverty while respecting their dignity. I believe that this is not charity, it\'s justice.I write software317davDav867711San Francisco CAUSdav2006-01-01T09:01:01ZAkuAku.org/Hacker-PoetI <3 capitalism.I help create our technology.71colinColin3836761Long Beach CAUScolin2006-01-01T09:01:01Zmensreapsych.blogspot.comGrad Student/TeacherEveryone in the world deserves the opportunity to improve their own lives and the state of their communities.I study and teach psychology.11lalexlalexNEW YORK NYUSlalex2006-01-01T09:01:01Z13matthew1977matthew46091Vancouver AKUSmatthew19772006-01-01T09:01:01ZI think microcredit is an interesting idea .I help the government figure out what they want to do with computers and technology.1Ben11BenMNBen112006-01-01T09:01:01ZMicrofinance guyI love this Kiva thing, and I believe in microfinanceI work for a commercial microfinance bank in Mongolia. I mostly work in the head office, which is located in the capital city, Ulaanbaatar, but sometimes get to travel to the countryside, to watch (and sort of assist) bank workers in action in remote counties of less than 3,000 people.4laurieLaurie & EmeraldFranklin TNUSlaurie2006-01-01T09:01:01Zemeraldestockphotography.com/librarian, photographerThis is the biggest return I can get for the small amount I have to invest.571kristinaKristina1054111West Liberty IAUSkristina2006-01-01T09:01:01ZI am a former Peace Corps Volunteer2susan6740Susan and ElianaSouth Orange NJUSsusan67402006-01-01T09:01:01ZThe need is great, so I participate in a number of development charities. Kiva, by allowing us to pick individual recipients, puts a face on it for my elementary-school age daughter.10claudioshikidaClaudio Shikida70521Belo Horizonte MGBRclaudioshikida2006-01-01T09:01:01Zcdshikida.orgEconomistI believe in the power of free markets to get people out of the poverty. Incentives matter. I hope the new entrepreneurs don\'t forget the social benefits of profit-seeking instead of the deleterious practice of rent-seeking.5alancheukAlan249811Burnaby British ColumbiaCAalancheuk2006-01-01T09:01:01ZStudent / ProgrammerI heard that there's big cash to be made in lending money. Now I just have to lie back and watch as the $$$ rolls in... With the economy the way it is, I'm already beating market!I'm a law student. In a few years I'll be evil, wait, I mean a lawyer, wait, I mean eviler.26lee7504Lee1271401W. Bloomfield MIUSlee75042006-01-01T09:01:01ZActor4john8325JohnCivic Square Australian Capital TerritoryAUjohn83252006-01-01T09:01:01ZI\'m retiredproviding credit directly to enterpreneurial people is probably a good way to encourage economic development more generally.I don\'t have any ongoing work but do occasional consultancy on political matters. I am also working on a Master\'s thesis on Arabic literature.5chris8643Chris3764281Morristown NJUSchris86432006-01-01T09:01:01Zwww.knowledgestreet.comWriterI can.I try to tell stories that people want to hear, so my clients can have their message heard.11jdJohn303541Everett MAUSjd2006-01-01T09:01:01Zwww.riaspot.com.comWeb DeveloperIt makes me feel good to make a real impact on the world - and I get to brag to my friends that I am an international financier.I help companies build their web sites.751kjetilKjetil538921Sandnes AKNOkjetil2006-01-01T09:01:01ZSoftware Developer34hunterHunterAnn Arbor MIUShunter2006-01-01T09:01:01ZIT Consultantwe are asked to share our blessingsHelp companies design and maintain computer programs to better their operations.12nancy9823NanMesa AZUSnancy98232006-01-01T09:01:01Z5jordan4303Jordan17451Vancouver British ColumbiaCAjordan43032006-01-01T09:01:01ZArchitectural Technologistit is a great, responsible way to assist people in their moment of need, no matter how long that moment is.I help with the design of building details, to make the buildings last longer and withstand the elements.13chelsaChelsa16001San Francisco CAUSchelsa2006-01-01T09:01:01Zwww.facebook.com/profile.php?id=591830456Marketing and Community Outreach Director @ KivaIt is inspiring to feel connected from so far away and truly remarkable to hear of both the struggles & joys our world's entrepreneurs face everyday. I love what I do, so it's easy to work hard.494jennifer6787JenniferPhoenixville PAUSjennifer67872006-01-01T09:01:01Zwww.sagestrat.commarketingPay it forwardI help technology and life sciences companies talk to their customers.1422scott4672Scott869501High River AlbertaCAscott46722006-01-01T09:01:01ZTeacher/AdministratorI want to bring hope.School administrator.3mariokristinMario & Kristin530941Towson MDUSmariokristin2006-01-01T09:01:01Zlaw clerk & actuaryeveryone deserves a chance and blessings should be shared.Mario works in maritime law. Kristin helps medical professionals and businesses manage their risks.2372bookchiqSarah Lewis2171801Meridian IDUSbookchiq2006-01-01T09:01:01Zwww.somethingepic.com/Web developerI believe that loans are an efficient, effective, and sustainable solution to poverty.I help businesses attract new customers.12ingeniatManuel AmorimFerrol GalizaESingeniat2006-01-01T09:01:01Zwww.ingeniat.esIndustrial Engineer3redevriesRené3383781UTNLredevries2006-01-01T09:01:01ZCTOI believe this to be the most effective way to provide help for people who try to improve upon their living standardsThink of new business, find new customers and manage the people and the organisation to make is happen. 12jeremycoleJeremy Cole1767111Sunnyvale CAUSjeremycole2006-01-01T09:01:01Zjcole.usGeek and EntrepreneurI love the idea of helping people who really need it; giving them a leg up on the world, even though their situation may be so dire.I participate in many Open Source software projects, and work at a video game startup.651judy7618STS HOP ClubCalgary AKUSjudy76182006-01-01T09:01:01ZStudentsWe want to give those who need it a hand-up.We are students from ages 9-11. We belong to a Humanitarian Outreach Club that does projects to raise awarenss and funds to help wipe out poverty7howardHoward563461Austin TXUShoward2006-01-01T09:01:01Z3mike1871Our Clients523821oakland CAUSmike18712006-01-01T09:01:01Zwww.grassshackroad.comBusiness ownerIt is the right thing to do. We work with companies to get their message across through events, conferences, videos, and new media such as web sites and podcasts. We bring in all the equipment and experts who we have worked with for years to do the job right! We bring in technical directors, creative writers & directors, lighting designers, audio visual equipment and video crews to make sure we get our client’s messages across to their attendees in the desired audience.17markbrunsMark Bruns1046351George IAUSmarkbruns2006-01-01T09:01:01Zsalebarn.comaccidental inventor ... mostly I burn stuffThe world needs more entrepreneurs. Push past limits. Test to failure. Understand and correct the root cause. Repeat. Accelerate the process.154gerryGerry1113631AKUSgerry2006-01-01T09:01:01Zwww.gerrykirk.netProject manager, Web DevelopmentI have seen in person the positive impact of micro credit while living in Bangladesh. I like Kiva's business model.5hoffkarKaren Hoffmann346541Pittsburgh PAUShoffkar2006-01-01T09:01:01Zhttp://www.karen-hoffmann.comScience communications4betsyBetsyfreeport MEUSbetsy2006-01-01T09:01:01ZMarketingI believe in the entrepreneurial spirit and love the concept of microfinance. 4joseph1683Joseph119181Jackson TNUSjoseph16832006-01-01T09:01:01ZRetired teacherbecause I can--and because I like the idea of helping people to help themselves.16tim2585Tim2144391LondonGBtim25852006-01-01T09:01:01Z3nancy1415Nancy1152221Seattle WAUSnancy14152006-01-01T09:01:01Zwww.fullcirc.com/I help people collaborate over the internet191cjhaydenC.J. Hayden34771San Francisco CAUScjhayden2006-01-01T09:01:01Zwww.cjhayden.comAuthor, Entrepreneurship Coach, ActivistI believe entrepreneurship is one of the best vehicles in existence for helping people in the developing world to create a sustainable livelihood.I'm the author of 3 business books, including the bestseller Get Clients Now! I serve as an advisor and coach to social entrepreneurs and activists, and serve on 3 nonprofit boards.531unreelUnreel Media45761Vancouver British ColumbiaCAunreel2006-01-01T09:01:01Zwww.unreelmedia.netEditorial Services CompanyAs a growing company, our view of the world is that the only way you can take out on a consistent basis, is if you give enough back so as to help the marketplace grow. When we loan money to Kiva entrepreneurs, we do so knowing that the businesses that are born as a result will one day grow into businesses that need our services.\r\n\r\nAnd if they don\'t... well it doesn\'t hurt to just be nice guys once in a while.We research, write and edit text for companies and individuals who want well-written content for their marketing material, websites, sales letters, press releases and more.\r\n\r\nWhen a company wants to send an advertising flyer to their customers, we write the text so that it well-received and increases sales. When that company wants to create a website, we make sure that it looks professional and is well-written.\r\n\r\nIn essence, we\'re writers for hire, and we commit a percentage of every dollar we earn in profit to Kiva.701ravenRaven4306841Sherwood Park AlbertaCAraven2006-01-01T09:01:01ZRNwe have been blessed, and we want to share God's gifts with others.31jaysonJayson71811Pittsburgh PAUSjayson2006-01-01T09:01:01Znorthbridge.orgPastorGod is in the business of helping the poor...179james7013James2001701Phoenix AZUSjames70132006-01-01T09:01:01Zwww.jeknauf.comPresidentArtist/businessman8mettlerMichael70391El Sobrante CAUSmettler2006-01-01T09:01:01Zmmettler.comworking for a startupwhen my loan capital is paid back, I can use it to help someone else.822chrisdnChristian1575861OverijseBEchrisdn2006-01-01T09:01:01ZManagement ConsultantEvery drop counts!7jesse4270JesseVictoria British ColumbiaCAjesse42702006-01-01T09:01:01Zwww.thenutter.comI believe micro loans are the way of the future. jensJensAarhusDKjens2006-01-01T09:01:01ZWorkflow Consultant (IT)Kiva simply is an amazing idea. The concept of helping an individual is a lot more appealing to me than simply donating to an organization, that then distributes the money for you. Not that I want to diminish the work that such organizations do, but actually having some sort of connection with the person who need a helping hand makes Kiva stand out. That Kiva provides loans rather than donations is another major reason. I have \"reinvested\" the money from my first loans, and the fact that the same money can help more than once, also makes Kiva truly engaging.I work for a Danish software company that produces computer systems for newspapers all over the world.16patricia5867Patricia178351hilliard OHUSpatricia58672006-01-01T09:01:01ZCashieri want to help. It's retail.2micheleMicheleKingsville MDUSmichele2006-01-01T09:01:01Z6phillipPhillip1760181Oakland CAUSphillip2006-01-01T09:01:01ZRetired PsychotherapistFeels better than buying more stuff I don't really need.I was a psychotherapist. Now retired. Guess I just can't stop trying to help people.24susan4768Sue1076351Brookfield VTUSsusan47682006-01-01T09:01:01ZTeacherIt is such a small investment on my part, and is not charity. It's a token of my faith in someone far away.I teach ecology in a small undergraduate program. 141haroldHarold1379391Bonshaw Prince Edward IslandCAharold2006-01-01T09:01:01Z10robert7621Robert52521Enfield Nova ScotiaCArobert76212006-01-01T09:01:01ZNewspaper ProductionAll peoples of the world deserve a break.I work in imaging for a daily newspaper in Nova Scotia, Canada.38joseph2694Joe572861Crossville TNUSjoseph26942006-01-01T09:01:01Zwww.mytown.ca/parkoretired college professorI believe that micro-credit loans are the best way to bypass bureaucracy and to get money directly in the hands of those who can put the loan immediately in use to help themselves.I am retired now and spend my time working for peace and justice in the world through the American Friends Service Committee and the Georgia Peace and Justice Coalition.8greg6725Greg179951Sacramento CAUSgreg67252006-01-01T09:01:01Zwater engineerit's fun - reallyprotecting water uses and quality for all the bugs, bats, and beetles (and humans) in CA365kimberKim2773251Durham NCUSkimber2006-01-01T09:01:01Z49diane2673Diane562021COUSdiane26732006-01-01T09:01:01Zwww.transitionallifecare.comCertified Massage Therapist, CEO Non-Profittouching people doesn't have to start and end with one's fingertips...I help healthy people and those with cancer live more pain-free lives through massage and energy work.5judith7470Judith572711culver city CAUSjudith74702006-01-01T09:01:01ZEntrepreneurI like to see where my money goes and get first hand information about how people are succeeding.I'm a designer and a writer.221karen5800Karen2390491Houston TXUSkaren58002006-01-01T09:01:01Zbligbi.comMomI enjoy helping people. 8david9918DAVIDSTUDIO CITY CAUSdavid99182006-01-01T09:01:01ZWriterI need to do something for someone other than myself.3charmaineCharmaineVentura CAUScharmaine2006-01-01T09:01:01ZPh.D. candidateI am interested in Haiti and its people and hope to encourage female entrepreneurs. I am proud to support entrepreneurs around the world, especially single mothers.I am researching the access and use of the altered state. Part of that study includes the Vodou religion. I am especially interested in the religious practice of indigenous peoples throughout the world.9ellen1450EllenEstacada ORUSellen14502006-01-01T09:01:01Z201sustainablewebsitesSustainable Websites700271San Francisco CAUSsustainablewebsites2006-01-01T09:01:01Zwww.sustainablewebsites.comGreen EntrepreneurI want to see sustainable entrepreneurship develop worldwide, so that we can all share nature's abundance and leave a better world for our children.I run www.sustainablewebsites.com that provides reasonably priced web hosting to start up companies that need a website9celesteCelestePort Chester NYUSceleste2006-01-01T09:01:01Z27tammeTammeMilwaukie ORUStamme2006-01-01T09:01:01Z25robert8058Rob652181Woodstock CTUSrobert80582006-01-01T09:01:01ZSoftware Developer5edVegas EdLas Vegas NVUSed2006-01-01T09:01:01ZFederal employee/college instructorI believe \"action is the consumation of thought.\" One cannot simply be aware of suffering around the world and not do something about it.I am currently a civilian federal employee. I was previously a Sergeant in the U.S. Marine Corps. I am also currently teaching American history, Asian Studies, and Chinese and Japanese history at the college level. 362erin9412ErinRochester NYUSerin94122006-01-01T09:01:01Zgraduate student36nidaNida3005571San Jose CAUSnida2006-01-01T09:01:01Z9jacobJacobChicago ILUSjacob2006-01-01T09:01:01Zwww.jakewalker.com/EntrepreneurKiva is just about the greatest idea in the world. Being able to directly help someone by loaning so little money is rewarding on so many levels. That I can continue to loan money time after time after each loan is paid back is even better.I have started several companies. The biggest one I started was called DiscLive. It\'s still around, but I\'m no longer involved. We created technology that allowed people who went to music concerts the ability to purchase a CD of the concert they just heard only minutes after the concert itself was over. Since then I\'ve stayed in the music business for the most part, working on other concert recording businesses.1TipitinaRebecca Theim562941Chicago ILUSTipitina2006-01-01T09:01:01Ztipitina.bizPublic RelationsWhat better way to help than to help people help themselves?I help get the word out about businesses so that potential customers know about their products or services.7paul6861Paul927191Glendora CAUSpaul68612006-01-01T09:01:01Zwww.theelrey.comConcert Venue ManagerI want to help enable others to help themselves.Produce Musical Concerts3suzanSuzan3804291San Luis Obispo CAUSsuzan2006-01-01T09:01:01Zwww.goddessgift.netPsychic Counselor & Internet RetailerIt touches lives in an empowering way. I love entrepreneurial business owners.I am an intuitive counselor who uses telepathic communication to talk to animals, loving spirits, and Higher Sources. I am also the owner of a retail website focused on the ancient historical wisdom of the Goddesses, bringing the feminine side of God back into consciousness.401heather3974Heather1433121El Sobrante CAUSheather39742006-01-01T09:01:01ZRetired Social WorkerI care.381carla7912CarlaGrass Lake MIUScarla79122006-01-01T09:01:01ZResearchI love the feeling that I'm helping someone.I work with people who look at people injured in car crashes to see how to make cars safer.4scott4181ScottRedondo Beach CAUSscott41812006-01-01T09:01:01Z141christopherscottChristopher51891Baltimore MDUSchristopherscott2006-01-01T09:01:01ZBusiness Process AnalystI grew up in East Africa and have seen the need for microfinance and local investment firsthand. I believe that local creativity, business initiatives, and accountability will do more for poverty eradication than World Bank loans and IMF restructurings that cater to government projects and end up crushing the national budget with interest...I've just finished my undergraduate degree in history and economics. At work I specialize in producing prodigious amounts of email-- accompanied by the occasional flowchart...:)14brian3557Brian2125861Stamford CTUSbrian35572006-01-01T09:01:01ZPC TechnicianI want to leave the world a better place for my having been here.I help people use computers and technology.943marionMarion in Savannah3113381Savannah GAUSmarion2006-01-01T09:01:01ZMedical transcriptionistIt's a way I can share, in a small way, the blessings that have been given to me. I was given help when I most needed it, and I know how much it means.I work for ear doctors, and when they see a patient they dictate a report on what the patient's condition is and what medication or surgery they think he needs. I listen to those tapes and type what they say so there is a written record of that visit to the doctor.271thomas3666ThomasDuncan SCUSthomas36662006-01-01T09:01:01ZRetired60ernestErnest82091Santa Rosa CAUSernest2006-01-01T09:01:01ZRetiredI have no religious convictions but I do believe that we are our brothers keeper. Life is more difficult for females and I prefer to help women who have children to support and educate.I was an Auditor and am long retired from a working life.8robert6623Robert J DonnellyMinneapolis MNUSrobert66232006-01-01T09:01:01Zsocial workereffective self helpcounseling 2shinShin HoFlushing nyUSshin2006-01-01T09:01:01Z4adam9714Adam4209391Lexington MAUSadam97142006-01-01T09:01:01Zconstitution411.org/climate/RetiredI enjoy getting to know people around the world, learning about their lives and sharing what I have.I spend most of my time working on global warming. I also play piano and tap dance.72damaliayodamali ayo2920571Portland ORUSdamaliayo2006-01-01T09:01:01Zdamaliayo.comartist / author / comedianeverything and everyone is connected. damali ayo brings a unique style of playful humor and piercing honesty to the conversation about race and human relationships. 13valerieValerieSan Francisco CAUSvalerie2006-01-01T09:01:01Z72jesperJesperCopenhagenDKjesper2006-01-01T09:01:01ZGame DesignerI feel it is my duty as a human being to empower people to improve on their own situation.I work designing and building computer games.2simon8477Simon340971Sieghartskirchen NOEATsimon84772006-01-01T09:01:01Zhttp://www.habmigern2003.infoSales technicianThis is the best way to ensure that the funds arrive where they will do some good and actually help somebody to improve their life.I sell and advise on sales of equipment for measuring pollution from combustion equipment.43asmundasmundrykkinnNOasmund2006-01-01T09:01:01Z14jason3724Jason & Co.3718141Evanston ILUSjason37242006-01-01T09:01:01ZProcurementIt's fun, and most importantly it works.I buy things for my company. My wife is an environmental attorney. We have our hands full at home with a high-energy son. 253nicole1399Steve and NicoleDowners Grove ILUSnicole13992006-01-01T09:01:01Z51gordon7148GordonElkmont ALUSgordon71482006-01-01T09:01:01ZComputer AnalystI have needed help to get going and know what a little assistance can mean.Computer Expert20charlie1085charlie3528861Riverside CTUScharlie10852006-01-01T09:01:01Z trader 1002louislouis daher52961ann arbor MIUSlouis2006-01-01T09:01:01ZIT ManagerI am interested in leveraging my fortunate life into opportunities for the benefit of others.I make sure that information is easily available and can be used by people with out much technical skills.86BudBudNorthampton MAUSBud2006-01-01T09:01:01ZretiredBeing a product of the depression era, I know from experience what it is like to be a small business person in bad economic times. I\'m sure that is multiplied by several orders of magnitude in the countries represented by the business people who are shown on the Kiva website. It gives me a great deal of satisfaction to know that I\'m helping these small businesses. Being able to see their photos and hear about them is an additional bonus.I\'m retired. Formerly I was a social scientist doing research on human behavior, particularly fundamental differences between people, hence my interest in people from different cultures and political situations.561max8101MaxStudio City CAUSmax81012006-01-01T09:01:01Z23jelizaJelizaShoreline WAUSjeliza2006-01-01T09:01:01Zwww.jeliza.netArtist15niki6203Niki2899901San Juan Capistrano CAUSniki62032006-01-01T09:01:01Zdzrtgrls.com271jane6603jane52871san francisco CAUSjane66032006-01-01T09:01:01Zwww.connectingstories.comconnecting the dotsWe're all in this together.Doing whatever I can to heal the world. 12david4401David3080271Calgary AlbertaCAdavid44012006-01-01T09:01:01ZParentIt worksFull time parent. 282wendyWendy Connors394801Albuquerque NMUSwendy2006-01-01T09:01:01Zwww.fadeddiscs.comHistorianEveryone deserves a chance to reach their dreams. I'm just sharing my dream too.I take the sounds of history and preserve them for future generations.7catherine1216Catrina304031CAUScatherine12162006-01-01T09:01:01ZIt beats buying $3.00 lattes...13david1196David520121Jacksboro TXUSdavid11962006-01-01T09:01:01Zthefirstmorning.wordpress.comPastorIt\'s a way to help others and allow them to keep their dignity intact.I'm the pastor of a United Methodist Church- I preach, teach, lead, sing, laugh, counsel, schmooze, fish, and explore.5210larissaLarissa3405031Toronto OntarioCAlarissa2006-01-01T09:01:01ZAquatics Instructor, StudentI believe that this is a fantastic way to make the world a better place!I teach aquatics for kids with and without disabilities - it's really rewarding to see a child swim on their own, or even dunk under the water, for the first time.10christophChristophEindhovenNLchristoph2006-01-01T09:01:01ZScientistR&D in a small high-tech company54adeleAdele576051Bristol UKGBadele2006-01-01T09:01:01ZResearcherUniversity based research into social policy around personal finances7grantyoungGrant3168321Newtown NSWAUgrantyoung2006-01-01T09:01:01Zsynapsechronicles.comConsultantI believe that families and communities are the best people to determine their future, and I want to support small businesses so that they can be self-sufficient and grow.I am self-employed working primarily for non-profits and NGOs10lewisLewis807671Hondo TXUSlewis2006-01-01T09:01:01ZWorld TravelerBecause The Good Lord has graced me with a bit more than I need.Currently working a couple of part time jobs in Japan. After this, who knows were I'll go or what I'll do. Certainly not me!83helen6108Helen3998691Hemel HempsteadGBhelen61082006-01-01T09:01:01Z6karen7513Karen447001Cambridge MAUSkaren75132006-01-01T09:01:01ZCommunity ActivistI strongly believe in self determination for all people. Providing funds without a bank interest rate and the requirement to pay back funds in a strict and structured timeframe is a great way to enable many to do so. Handouts rarely get to the beneficiaries and are often merely used to control people. I simply want to cut through the many barriers that have been put into place by the west mostly, to help lift people out of those barriers to prove their ability. Working for oneself is the best way to avoid dependence on the corporation and the ills it spreads.I work on prison issues in the US, where we have the highest incarceration rate on the planet, not to mention some of the worst abuse. The corporation has entered the prison system making it a multi-billion dollar industry that requires more and more people to fill the prisons for it to be profitable, and I shouldn't have to tell anyone how dangerous and deadly that is for all of us.6bryanthompsonBryan Thompson2819141Lisle ILUSbryanthompson2006-01-01T09:01:01ZBackpacker / StudentI believe in small steps towards a better, more equitable and more sustainable society.I´m backpacking in Latin America for a year after graduating from University and before law school. I believe that one must experience others conditions to truly understand them and be able to work to improve them.27jamilaJamilaBowie MDUSjamila2006-01-01T09:01:01Zwww.ecommercediva.comEntrepreneuras an entrepreneur, I know how difficult it is to raise capital in the U.S. I can imagine how hard it must be in the developing world. Thriving businesses can change the fate of a whole family, and a whole community.I help other business owners learn how to sell their products and services more effectively over the Internet.8saraSaraWaltham MAUSsara2006-01-01T09:01:01ZSoftware Engineer9calebCaleb1470661Lexington KyUScaleb2006-01-01T09:01:01Zwww.gnn.tvStudentI believe microfinance can be a very effective way to help people living in poverty around the world.Student in college.5jonathan1184Jon2911111Ashby-de-la-Zouch LeicestershireGBjonathan11842006-01-01T09:01:01Zwww.thebestof.co.uk/loughboroughWebsite ownerMicro-businesses can change the worldI promote small businesses in my community too!27equayonaEqua Yona4747651Chamberlain SDUSequayona2006-01-01T09:01:01Zwww.equayonabigbear.blogspot.comDog sitterWe can, we want to and Its a good thing Loafing around6laura5609Laura3951701Scottsdale AZUSlaura56092006-01-01T09:01:01ZCoach/EducatorIt's a great way to make a big difference with a small investment. As a fellow entrepreneur and professional coach I love to see people living into their dreams.151amanda5774AmandaLos Angeles CAUSamanda57742006-01-01T09:01:01Z9pattyPatty331261Lake Oswego ORUSpatty2006-01-01T09:01:01ZRetired TeacherMatt & Jessica have great vision and I have a heart for the people of East Africa.I taught health and home economics in secondary schools for 32 years.4clarkClark2987121Brooklyn NYUSclark2006-01-01T09:01:01Z12chris4758Chris4224091Chicago ILUSchris47582006-01-01T09:01:01Zwww.spikeball.comSales at MicrosoftI believe a loan is much more powerful than a donation. I am a sales representative for the XBox division at Microsoft. I also run a business that makes a beach/bcakyard game called Spikeball.43timmothyTimmothy916921Milwaukee WIUStimmothy2006-01-01T09:01:01Zwww.timmothymerath.comProject ManagerI care.5ed9081Ed PoolMyrtle Point ORUSed90812006-01-01T09:01:01Z3maraa2396Maria Jairo Nico4623771HuescaESmaraa23962006-01-01T09:01:01ZLecturer61reyesReyesSanta Cruz de Tenerife Santa Cruz de TenerifeESreyes2006-01-01T09:01:01Z1BobbuBobbu651451Washington DCUSBobbu2006-01-01T09:01:01Zwww.IAmALudditeAndAHermitAndDontMaintainABlog.comErsatz EntrepreneurIt is the least anyone could do, and Kiva (specifically) makes it tangible.I spend most of my energy and dubious talent "developing" software and providing blowhard advice to others.5138jane7816Jane1156611New York NYUSjane78162006-01-01T09:01:01ZI canActor and singer22craig5468CraigApple Valley MNUScraig54682006-01-01T09:01:01ZSoftware DeveloperHaving started a few small businesses on my own, I know how significant a little extra capital can be in making the difference between success and failure.We develop computer programs to help small and medium businesses better manage and respond to their telephone and internet-based communications.33laiaLaiaBarcelonaESlaia2006-01-01T09:01:01Z42rmkMatthewWashington DCUSrmk2006-01-01T09:01:01ZAttorney21coletteColetteRocklin, CA KivaFriends.orgUScolette2006-01-01T09:01:01Zkivafriends.orgMomIt is the right thing to do.Mom.1351daverDave28251Lake Forest Park WAUSdaver2006-01-01T09:01:01Zdefeatpoverty.comEntrepreneurI'm interested in empowering the working poor with a hand up to have the opportunity to improve their lives and the lives of their families.I help small local businesses who provide home repair, cleaning and improvement services find more customers.110mnothumMike NothumAZUSmnothum2006-01-01T09:01:01Z9danandbekahDan and Bekah150741Minneapolis MNUSdanandbekah2006-01-01T09:01:01ZEconomist and Physician Assistantwe like to use the opportunities given to us to benefit others!71steven3276Steve2725051Saint Paul MNUSsteven32762006-01-01T09:01:01ZComputer analystPeople all over the world want the same things: meeting basic personal needs (food, water, shelter), safety for themselves and their loved ones, and fulfillment in their lives. We in the U.S. are so blessed in those areas. We should help others who are willing to work to help themselves. I test computer software to see how well it works when many people are using it.44darenDaren2827621Orlando FLUSdaren2006-01-01T09:01:01Zwww.darenscotwilson.comComputer graphicsit keeps me from blowing it all on chocolate! And, for years i've wanted to be philanthropist. Such little $$ accomplishes much in faraway places, helping to even out some severe imbalances in the world economy. For five years, I worked on data sent from the Cassini spacecraft near Saturn. From this data, I made pictures to show on NASA's website and to be published in magazines. But I have now taken another job working with astronomers on another project.24andrew1487Andrew Berry374291henderson NVUSandrew14872006-01-01T09:01:01ZMail ManI belive anywhere in the world can have a thriving economy if the people have enough goods and services to trade. If the majority of people in an area are encouraged to specialize in an area where they excell then enough goods and services will likely be created. By loaning I encourage people to specialize in an area where they will hopefully thrive.I work for the U S postal service. I deliver letters from all over the world to the people of Boulder City Nevada. I also collect letters to be sent anround the world. I represent one of the oldest branches of the U S government and help to maintain the faith that everything is functioning normaly. 40elizabeth1349LibbyWebster NYUSelizabeth13492006-01-01T09:01:01Z21jason1125JasonNew York NYUSjason11252006-01-01T09:01:01Z25ellen6143Ellen1598881San Francisco CAUSellen61432006-01-01T09:01:01Z9jeff3422The Sutherlands62211Edmonton AlbertaCAjeff34222006-01-01T09:01:01ZIndustrial Real Estate AssociateI consult for people and businesses in purchasing, leasing, and selling industrial real estate.5kentKentIrvine CAUSkent2006-01-01T09:01:01ZPatent attorneyI admire those who are working in challenging environments to make a better life for themselves and their family and I want to help.Helping a company, Xerox, to benefit from its research investments 6ariannearianne z.116161Tucson AZUSarianne2006-01-01T09:01:01Zgraduate student22calicoCalico1711971New York NYUScalico2006-01-01T09:01:01ZwriterI want to help poor people, especially poor women, improve their lives. 168colbyColby Otero4320001Hood River ORUScolby2006-01-01T09:01:01Zwww.colbyotero.com111jd8208J.D.2156851Las Vegas NVUSjd82082006-01-01T09:01:01Zwriter and lawyerSmall business owners ought to help each other out, even if we're in different parts of the world from one another. I spend the day writing documents that help people and businesses protect their copyrights and trademarks. At night I write fiction, essays, and articles about various other subjects.611geneGene4687201Seattle WAUSgene2006-01-01T09:01:01Zwww.GeneDexter.comMarketing/PromotionI believe a difference can be made.Public relations. Also semi-retired from the music industry.282hjortholmKim Hjortholm94351Copenhagen .DKhjortholm2006-01-01T09:01:01Zedgecrafting.blogspot.comIt make very much sense to support local growth and initiative, it's more personal, and I'm happy to see the money return to my account because it proves the loan did make a difference - and I have another 25$ to re-invest141wxojx1105RaviCupertino CAUSwxojx11052006-01-01T09:01:01ZVice PresidentI am excited and happy to help out. Strongly feel this is an opportunity to give.27frediFredi80161Beverly Hills CAUSfredi2006-01-01T09:01:01ZSales and Marketing SpecialistI feel very fortunate in my life and, simply put, giving back is very rewarding.Entrepreneur9rebecca6067Rebecca87471AKUSrebecca60672006-01-01T09:01:01ZconsultantIt\'s an experiment to see how well this works for international development. I get involved with a lot of experiments. I'm in CA, not AK; not sure why AK pops up here. I find innovative, worthwhile projects in international development with sustainable social leverage and help them succeed, particularly projects that help women. 2shainaShaina362941San Francisco CAUSshaina2006-01-01T09:01:01ZRecruitermy sister helped start this organization and I think it's one of the most inspiring movements thus far in my lifetime. I help people find new jobs that they're excited about. 52dominiqueDominique2272611Bilbao VizcayaESdominique2006-01-01T09:01:01Zperso.wanadoo.es/write2mdi/TranslatorI´d like to be able to help a little.12alexander4763Alexander244261Las Vegas NVUSalexander47632006-01-01T09:01:01Zwww.edelstein.orgThis and ThatIt's the most effective way to change the world for the better.I build lots of wooden boxes, all on top of each other. Then people buy the boxes from me and live in them. Who knew?526j6841zariat448661CaliforniaUSj68412006-01-01T09:01:01Zwww.zariat.comfriendit's such a good idea!professional enabler of talented and creative individuals 1seemaSeema2022891Los Angeles CAUSseema2006-01-01T09:01:01Zseemachine.blogspot.comLaw ClerkI am privileged enough to have far beyond what I need to thrive, in a world where most have hardly enough to survive.I serve as the "apprentice" to a federal judge on the United States Court of Appeals.8joan9854Joan Friedlander2594961AKUSjoan98542006-01-01T09:01:01Zwww.lifeworkpartners.comStrategic Business CoachI believe business ownership is the first measure of freedom over one's livelihood, and wish to support it not just in my work but for others I can't see or know.I work with self-employed entrepreneurs to successfully build and run mission-centered service businesses throughout the U.S. As their coach, for a short period of time I am their sounding board, guide and accountability partner. They learn new strategies for marketing, time management and delegation, and gain momentum towards their goals.maryannMaryAnn Bailey3308291Seattle WAUSmaryann2006-01-01T09:01:01Zhttp:www.quietcourage.blogspot.comLife CoachI have seen first hand the incredible impact a small amount of money can make in people's lives.I help people find the courage to achieve their dreams.1colinruleColin Rule77921San Jose CAUScolinrule2006-01-01T09:01:01Zcyberlaw.stanford.edu/blog/colin-ruleMediatorIt\'s such a small thing for me, but a big thing for the receiver. It just seems to be the right thing to do, especially now that there\'s Kiva.I help people resolve their disputes, both when they\'re looking at each other face to face, and when they transact with each other over the internet.63sharon5055Sharon Kuku1734641KampalaUGsharon50552006-01-01T09:01:01ZDevelopment AssistantI would like to change someone's life, the amounts may look so little to many but to them it makes the world a better place. In a small way that i can afford, i want a smile out there!Operate children with corrective disabilities almost across the world. God indeed has done many miracles, sad that some have never noticed His presence in their lives.karen5336Karen3593181Alameda CAUSkaren53362006-01-01T09:01:01ZvolunteerI canI volunteer as a forth grade reading coach and tend the garden at the school.23ben2640Ben185711Madison WIUSben26402006-01-01T09:01:01Zwww.thememoryproject.orgMemory ProjectMicro-finance rocks! 2kendallKendall3159061Mountain View CAUSkendall2006-01-01T09:01:01Zwww.microfinancetravels.typepad.comBusiness OwnerSME and micro-credit loans help create self-employment in countries where neither the government nor private companies are generating enough new jobs.I am Board Chair and CEO of Prisma Microfinance with operations in Honduras & Nicaragua.15fionaFiona Ramsey1985911San Francisco CAUSfiona2006-01-01T09:01:01ZKiva Public Relations DirectorI would like to give others an opportunity - I've been given so many in my life!I talk to reporters so they can write great stories about Kiva.org. I spend my day in an office with lots of plants around me. My best friends at work are my laptop and my big Chinese teapot. 93erin1298Erin659271SalamancaESerin12982006-01-01T09:01:01Zwww.wandering-woman.blogspot.comMarketing & Communications Consultant, writerThere is no feeling in the world like opening a Kiva "payment-made !" email, unless it's that absolute high of a loan redemption notice. Don't tell ME I can't be a small part of the change I'd like to see....263blyonsBrian57191darnestown MDUSblyons2006-01-01T09:01:01ZTech WeenieI am a computer industry executive.8james6735Mike HNashville TNUSjames67352006-01-01T09:01:01Zmikehester.smugmug.comFinancial AnalystTime to give back...I crunch numbers in a cushy office.1591linda2259LindaAtlanta GAUSlinda22592006-01-01T09:01:01ZI want to help create abundance in the world.17mahmoodMahmood Remtulla2279751Arlington VAUSmahmood2006-01-01T09:01:01ZIT - Network AdmininistratorI love giving!My job is to make sure that computers in the work place are all connected and communicating with each other at all times.david6492Dave78001Los Angeles CAUSdavid64922006-01-01T09:01:01Zlaw student... this is a better use of my money.143daniel1243Dan and Heather331231Minneapolis MNUSdaniel12432006-01-01T09:01:01Zteacher/graduate student4nancy8449Nancy3094361Huntington Beach CAUSnancy84492006-01-01T09:01:01Zoffice managerthis is a really great way to help people all over the world I work for a small company that sells artwork; we put artists and projects together352jeffAndChrisJeff & Chris1715431Los Angeles CAUSjeffAndChris2006-01-01T09:01:01Zwww.marwencol.comFilmmaker & WriterIt's a great idea.26okdavidDavid2215231Saint Louis MOUSokdavid2006-01-01T09:01:01Zdavidharlow.comsongwriterIt's a nice way to help people.120loriLori377141ROCKVILLE MDUSlori2006-01-01T09:01:01ZScientistI can.3eleanorEleanorHyde Park MAUSeleanor2006-01-01T09:01:01ZRetiredI feel it is a great way of helping others who are definitely helping themselves. I enjoy reading the stories of the businesses that were started and how such a small donation makes such a huge difference.I am retired, but vowed when I did retire that I would give back by volunteering and helping others. I serve wonderful people at hospice, help an elderly woman with her finances, and work with people at my church.61gilGil115141Greater Seattle Area,USgil2006-01-01T09:01:01ZIt\'s a concrete way to make a difference and see the results. I\'m retired, and I\'ve been fortunate in life. This is a way to give a modest amount of money and know it will make a big difference in the life of a hardworking person who deserves a little help.171kathryn8331Kathryn1404401Battle Creek MIUSkathryn83312006-01-01T09:01:01ZconsultantI have what I need and I hope that I can help you to have what you need.In our country we have organizations to help other people. My job is to help them do their jobs more efficiently. 115mary6717Mary BethRockville MDUSmary67172006-01-01T09:01:01Zprogrammer100nancy7806Nancy514791Flagstaff AZUSnancy78062006-01-01T09:01:01ZHomemakerI like to feel the direct connection with the people who need the funds. Much better than donating to a big organization where a lot of the money goes for administrative costs.I take care of my home and my 17 year old son. I am also a potter and love to make dishes for people to use for their meals.194sueandpaulSue & Paul3007991CAUSsueandpaul2006-01-01T09:01:01ZRetiredGood way to help without it being a handout - can instill pride in entrepreneurs.11rossRoss1342221Kansas City MOUSross2006-01-01T09:01:01Zwww.soulpaths.comHealerEnergy Medicine in the Andean Tradition91melissaspurrMelissa & Peter Spurr569361Joshua Tree CAUSmelissaspurr2006-01-01T09:01:01Z28christopher7599ChristopherBellefonte PAUSchristopher75992006-01-01T09:01:01ZStudent pilot/CatererI could put the money into a savings account and earn 2%, or lend it to someone who could use it to make a better life for themselves. Not so hard a choice?Helicopter pilot-in-training.7valerie3992Valerie510881New Windsor MDUSvalerie39922006-01-01T09:01:01Z18peregrinoPeregrino15721San Mateo CAUSperegrino2006-01-01T09:01:01ZSales Manager, FilmmakerIf my small contribution can help someone reach their dream or goal, I\'m happy to do it.craig3817Craig & Ameeta124901Northfield MNUScraig38172006-01-01T09:01:01Zwww.uniyatra.com/84patricia2108patricia1921241CLEVELAND OHUSpatricia21082006-01-01T09:01:01Zplumbing salesIts important to give back, if just a little. I sell plumbing supplies to plumbers, contractors and builders.5chris3510Chris53841Laguna Beach CAUSchris35102006-01-01T09:01:01ZInsuranceI heard about Kiva on NPR and thought it was a great idea. I wish I'd thought of it...cause a Nobel Peace Prize would look great over the fireplace.9todd7797Todd and Brenda249531Rocklin CAUStodd77972006-01-01T09:01:01ZEngineerWe have been blessed with so much and want to help others.design complex networks.372chris3904Chris16561Worcester MAUSchris39042006-01-01T09:01:01ZI want to help give people a chance to improve their lives.I work with computers.15david1710David McCullough2401961Cazadero CAUSdavid17102006-01-01T09:01:01Zwww.davidmichaelmccullough.netNurse / FirefighterI live in one of the richest countries in the world yet gives less than most other countries and still complains it is too much. I have applied to Medicines Sans Frontieres (Doctors without Borders) in January 2009. I work as a nurse and volunteer firefighter.152tomTom1094381Front Royal VAUStom2006-01-01T09:01:01Zbaddogpip.blogspot.com/2006/12/mifex-neighborhoods-tres-trinitaria.htmlContractorWithout access to capital, I couldn't be in business myself, and it\'s taken years of hard work for me to reach where I am today. I would rather use my money to help someone engage in a business venture rather than for a charity. I believe that money borrowed and the profit that is earned is more valuable than a gift, since it allows the borrower to improve their condition with dignity. And in regards to the real REASON that I do this, it is because I am treating these entrepreneurs as I would like to be treated, and have been treated, myself.I fix old houses and turn them into beautiful homes.2842controlcontrol389891NZcontrol2006-01-01T09:01:01Zcontrol.orgmusicgovernments, corporations and religious organisations introduce unreasonable baggage to self-determined personal and community development.we provide the oontz.10bruce3965BruceSan Francisco CAUSbruce39652006-01-01T09:01:01Zwww.blinklist.com/bpaton/business school professorI admire the people that Kiva supports and enjoy being able to help.I teach courses at San Francisco State University about sustainable business, micro-credit, and base of the pyramid business.263scott3028ScottEugene orUSscott30282006-01-01T09:01:01ZI'm not wealthy, but I have enough money to have a good life and do what I want. I'm grateful to everyone who has helped me along the way, and I feel lucky to be able to pass some of that help on to other people. 23MikeBMikeB1946541voorhees NJUSMikeB2006-01-01T09:01:01ZStudentone person can make a differenceim your standard college student. trying to figure out what i want to do with the next 50 years of my life.133damienDamien118841CAUSdamien2006-01-01T09:01:01Zwww.zaproot.comMediaI live in one of the richest countries in the history of the world. That wealth is just an idea, the same as other countries poverty is just an idea. Money has no value unless we imagine it does. If I can relieve someones suffering with just an idea... then why wouldn't I do that?I produce films that focus on sustainability and ethics.211david5352DaveSan Francisco CAUSdavid53522006-01-01T09:01:01ZMISI can18shevyRené Clausen Nielsen2941081CopenhagenDKshevy2006-01-01T09:01:01Zshevy.dkAdvisorPeople all over the globe should be able to make a business that can help both themselves and their communities regardless of their parents' and communities' wealth. I loan because it's the best way to boost prosperity, self-help, and to foster self-supply in communities everywhere.84zack4261Zack Reuter1639461Grand Junction COUSzack42612006-01-01T09:01:01Z47justin7893The Schlottmans858231Sebastopol CAUSjustin78932006-01-01T09:01:01ZSoftware & TransportationWe believe in sharing and helping to ensure that everyone has the opportunity to succeed as they work toward a sustainable livelihood .In our professional and personal lives we each work to make the world a healthier place for everyone .481amy8556Amy Klement211521Palo Alto CAUSamy85562006-01-01T09:01:01ZTechnologyit gets the resources directly into the hands of the people who need it the most - the people with no access to the capital markets. What's better than empowering someone to reach their potential?build products and services for the internet 6willWill891011Moscow IDUSwill2006-01-01T09:01:01Z3sherrillSherrillPomona CAUSsherrill2006-01-01T09:01:01Z9kathy8113KathyOrinda CAUSkathy81132006-01-01T09:01:01Z6cathyCathyYankton SDUScathy2006-01-01T09:01:01ZComputer AideI love the idea of loaning money directly to people who have a great idea and the ambition to start a business.5shannonlcShannon392031Chicago ILUSshannonlc2006-01-01T09:01:01Zblogs.babble.com/strollerderby/tag/shannon-lc-cate/reading, writing, coercing others to read & writeI have more than I need.I teach young adults part time and write part time. I also care for my young daughters at home.6tommyTommy63311Norco CAUStommy2006-01-01T09:01:01ZWriter/DraftsmanIt's the right thing to do for a stable and peaceful world.I design fire alarm systems while I write screenplays.32t6109TkgDPO APUSt61092006-01-01T09:01:01ZCivil Servant93alexander8539Alexander921451Kalamazoo MIUSalexander85392006-01-01T09:01:01ZJudgeIt is a personal connection. We don't need grand schemes. Each one of us doing the right thing will get the job done.I am a judge in Michigan State Courts26elizabeth2543ElizabethDenver COUSelizabeth25432006-01-01T09:01:01Zsundeepsundeep2445821San Francisco CAUSsundeep2006-01-01T09:01:01Zthesunrising.comlifeit takes money to make moneyi'm an entrepreneur too :)157lisa9443Lisa17981Exeter NHUSlisa94432006-01-01T09:01:01Z251grant9249Grant79251Kingwood TXUSgrant92492006-01-01T09:01:01ZInformation TechnologyThe more economically stable a location is, the more the people have to lose. The more people have to lose, the less likely they are to go to war.I work on computer hardware and software.172christine1320Christine211641Chicago ILUSchristine13202006-01-01T09:01:01ZPhD student in PsychologyKiva gives me an amazing opportunity to make an impact. I don't make much money as a student, but I know that the little bit I give to others makes a world of difference. I am thankful for a chance like this one!People come to talk to me about things that are making their lives difficult and I try to help them figure out how to make it better. 61herzigmaJosh71431Newton MAUSherzigma2006-01-01T09:01:01Zjoshua.herzig-marx.comEntrepreneurIn Jewish tradition, the highest form of charitable work is providing others with the opportunity to help themselves--loans, not gifts, are the preferred way to accomplish this as the recipient can better maintain their pride.A retail technology entrepreneur.12susieplusdavidCovell Development Fund2008661San Francisco CAUSsusieplusdavid2006-01-01T09:01:01Zwww.susieplusdavid.comBusiness peopleEconomic opportunity means empowerment, it means choice, it means better lives, it means stronger communities. We think that's a meaningful contribution. Susie owns a water conservation company. David manages Yahoo! Mail in international markets. 59steven7783Madeleine2606541Solana Beach CAUSsteven77832006-01-01T09:01:01Zwww.SurfingBulldog.comBulldogI believe in supporting people less fortunate than me and as a dog I have a more comfortable lifestyle than most of the people on this site so I figure I should give back. I sleep til around 10:00AM then I go lay in the sun and take a nap then I eat something and check out the back yard go back in the house and get up on the couch and take a nap. My dad comes home and I go nuts for about 10-15 minutes and we go to the beach or the dog park...25jonasbJonas3211261Lewisham LondonGBjonasb2006-01-01T09:01:01Zandthennothing.netProgrammer2861karen6550Karenprinceton njUSkaren65502006-01-01T09:01:01Zattorney38jeff6751JeffWaterloo OntarioCAjeff67512006-01-01T09:01:01ZSoftware testerI thought this was pretty interesting and like the idea of helping out small businesses in developing countries I test software142phreddPhredd3004841Easton BristolGBphredd2006-01-01T09:01:01Zstudentarchaeologist21johannaJohannaKew Gardens NYUSjohanna2006-01-01T09:01:01Zlibrary internI believe in the power of everyday people to effect change, & love that, by lending just a few dollars, we can make concrete improvements in the lives of people around the world. Microfinance is amazing, & Kiva pairing it with the convenience of Paypal is... addictive!1503myles4403Myles107171San Francisco CAUSmyles44032006-01-01T09:01:01ZEngineerI'm hoping to leave the world a little better off than I found it.I work for a large internet company, writing software.211kythryneKythryne Aisling1895131Concord NHUSkythryne2006-01-01T09:01:01Zwyrdingstudios.comJewelerI am the owner of a small business, and I feel that supporting other small business owners is extremely important.I design and manufacture wire jewelry.20brad9165brad212941santa Cruz CAUSbrad91652006-01-01T09:01:01ZEngineerBecause I can26philip5273PhilipGainesville FLUSphilip52732006-01-01T09:01:01Zwww.thefruitblog.comFruit BreederIn a perfect world, everyone willing to work should be able to succeed. It's not a perfect world, but we can make it a little easier at least.I develop new varieties of strawberries and help farmers learn how best to grow them.2tim6742Tim1854261Mountain View CAUStim67422006-01-01T09:01:01ZElectrical EngineerThis is a simple way to help motivated peoples better their lives. I can relate to the 1-to-1 connection between lender and lendee.System on a Chip design for Apple inc.113rossjamesparkerRoss55181Croydon SurreyGBrossjamesparker2006-01-01T09:01:01Zwww.rossparker.comInternational development consultantit shows how the free market is compassionate and how private charity works better than the state.I help countries realise that their potential is in their people, not in their governments.16leviLeviNEUSlevi2006-01-01T09:01:01ZAnalystjoshua5929JoshFairport NYUSjoshua59292006-01-01T09:01:01Zrootedcosmopolitans.blogspot.comScience ResearchI think there is a moral obligation to help make people's lives better wherever they are, and this is a fantastic way to directly accomplish that goal, empowering people everywhere to improve their own lives through hard work and dedication.I study black holes by simulating them with computer codes.35michael9702MichaelDenver COUSmichael97022006-01-01T09:01:01ZI've been lucky.8brad3118Chris, Laurel, and Brad106731Denver COUSbrad31182006-01-01T09:01:01Zmicrofinance is a great way for people to connect and cut out the middleman.29eliza4632Eliza812951New Fairfield CTUSeliza46322006-01-01T09:01:01ZFreelance writerAs an American woman with her own business, I recognize the hundreds of advantages I have that my counterparts around the world do not.I help businesses sell their products and services by writing advertising copy and creating websites5lukeLukeParafield Gardens South AustraliaAUluke2006-01-01T09:01:01Z591cindyCindyB1949661Bedford VAUScindy2006-01-01T09:01:01ZWe enjoy it. :)4kitKitBloomington INUSkit2006-01-01T09:01:01Z762journeywildNicole208161Surrey BCCAjourneywild2006-01-01T09:01:01Zwww.journeywild.blogspot.com/Call Center SupervisorIt's exciting to help individuals rather than simply giving to a cause.If a company wants to telephone its customers, they hire us, and we make the phone calls.1jim9667Jim83471Port Orchard WAUSjim96672006-01-01T09:01:01Zwww.jimfreeman.comreal estate broker and angel investorI love to help hard working people create wealth.I provide high performance facilities for businesses in my home area and help them grow with capital and advice.231virginia1547Virginia4322961Grants Pass ORUSvirginia15472006-01-01T09:01:01ZFitness & Weight LossI love the opportunity to be involved in God's plan and supporting others becoming self-sufficient.I have the opportunity to make a difference in the lives of our clients at Excel Fitness in Grants Pass, OR. I help others improve their health through exercise and weight loss. God is good!8FreedomistFreedomistBellevue WAUSFreedomist2006-01-01T09:01:01ZI want to encourage these entrepreneurs to build their businesses and freedom through the beauty of capitalism and the free-market. Good luck and you have my gratitude for letting me be part of your journey.3uweUwe1050711Mountain View CAUSuwe2006-01-01T09:01:01ZElectrical EngineerI've traveled quite a bit in less developed countries and have seen what a difference access to micro loans can make.I develop computer chips.24sheriSheri364081Lake Oswego ORUSsheri2006-01-01T09:01:01ZChild AdvocateI can and it's the right thing to do. I work to make the world a better place for women and children. 201masoodMasood301801Troy MIUSmasood2006-01-01T09:01:01ZEternal Studenta BAILOUT is not the solution to every problem!!20alex1920Alex TabarrokCentreville AKUSalex19202006-01-01T09:01:01Zwww.marginalrevolution.comProfessor11mistergregGreg4053511Acworth GAUSmistergreg2006-01-01T09:01:01ZSoftware Engineer4david7193David15621Danbury CTUSdavid71932006-01-01T09:01:01Zmadmod.comComputer installation, repair and instructionPeople gave me a chance to get started with my education and previous teaching career. Because of that, I am grateful. Everyone needs to have a chance to succeed--no matter where they're starting from.My present work, after retiring from public school mathematics teaching in June, 2000, is to work with individuals and small businesses, taking care of their computer installation, repair and networking needs. My certifications are with Windows PC's, networking and security.185mark2457Mark42111Edmonton AKUSmark24572006-01-01T09:01:01ZStudentI am currently studying Economics at the University of Alberta.16rebekahRebekah2049411Norwood MAUSrebekah2006-01-01T09:01:01ZEditor/writerSmall businesses are the bedrock for building successful communities. For the borrower, taking and repaying loans builds business skills and self-confidence; for the lender, it provides an opportunity to participate meaningfully in improving the lives and communities of others and actually see the results of their input. Loans also enable the lender to do more, as the same funds can be reinvested every time they are paid back. I have had many loans paid back fully and have reinvested all the money in new loans - more than 25 in total. I am particularly interested in helping other working women!I work in business management consulting, which helps companies around the world improve and grow their businesses. 29nigelNigel60081BrusselsBEnigel2006-01-01T09:01:01Zwww.best4x4xfar.comIT ConsultantI feel vey fortunante in my life and would like to assist others to acheive their goals.I work with international businesses supporting their IT Projects.1alexander3013AlexanderAthensGRalexander30132006-01-01T09:01:01ZEntrepreneura small loan can make a huge difference, empowering people to change their life and transform their communities.351terry4482Terry2086521HampshireGBterry44822006-01-01T09:01:01ZSoftware testerCompared to most people on the planet, we in the developed world are incredibly wealthy. Giving a helping hand to those who are not as lucky as ourselves is what makes us a civilised society. Working in an office testing financial foreign exchange software.14fernandoFernando2016081LEESBURG VAUSfernando2006-01-01T09:01:01ZAccountantI feel good helping others. "If you can't feed a hundred people, then feed just one." Mother Teresa "Do not wait for leaders; do it alone, person to person." Mother Teresa 6eElenaAthensGRe2006-01-01T09:01:01Z13damian2101Damian & MaeveHuddersfield West YorkshireGBdamian21012006-01-01T09:01:01ZI can and I should and its also a direct way to lend to something meaningful.Father and Daughter. I do stuff with IT, my daughter is a student.275william6330William51431Coventry West MidlandsGBwilliam63302006-01-01T09:01:01ZBusiness DevelopmentI come from a part of the world, where food, education and health care are not only taken for granted - but are starting to be abused. I sincerely beleive that by giving everyone the opportunity to see the rewards from their efforts, will make the world a more equal place.I work for a drug company negotiating with University groups to help them turn their ideas into drugs for the benefit of humanity. 641alexander1713Alexander51311Seattle WAUSalexander17132006-01-01T09:01:01ZEconomist and writerin economic terms we are all interdependent. Economics is a learning field for practical brotherhood.I am a forecaster and analyst for a local government agency (environmental protection).13aaron9285Aaron362851Las Vegas NVUSaaron92852006-01-01T09:01:01ZTeacherI am impressed with the people on this site, who have been given less than people around me, but have produced more.I try to make over-privileged adolescents appreciate the education that they get for free.3steve9422Steve Clark1963241Welwyn Garden City HertfordshireGBsteve94222006-01-01T09:01:01Z13vaieelDawson3159851Chicago ILUSvaieel2006-01-01T09:01:01Zwww.vaieel.comGraphic DesignerPrint and web design.7sarahtmSarah17261Lymington HampshireGBsarahtm2006-01-01T09:01:01Zwww.milfordonsea.comwebmasterit makes a lot of sense and helps people who need itI am retired but I run 5 websites on a non-profit making base. The biggest site is the one I run for my village and if you go there you will see something about life in a little seaside town in England27jktoysJKToys.co.uk3825491St Albans HertsGBjktoys2006-01-01T09:01:01Zwww.jktoys.co.ukToy SellerI think micro-finance is a great idea to let individuals help out other individuals and also to learn about how others are making their way through life. There is also the fact that whenever I click on the button to make a loan I have a big smile on my face because it just makes me feel good!Selling toys.57daniel2283DanTarragindi QldAUdaniel22832006-01-01T09:01:01Z6chris1723ChrisAustin TXUSchris17232006-01-01T09:01:01ZComputer ProgrammerIt is the easiest way in the world to help others. I can help someone start a business, feed their family and build wealth in their country for less than the price of a mediocre meal at a resturant.I write computer programs.50sharadSharadNovi MIUSsharad2006-01-01T09:01:01ZEngineerWhat goes around comes around.7sachaSacha & AlexandraDroitwich AKUSsacha2006-01-01T09:01:01Z4catherine1821Catherinemclean VAUScatherine18212006-01-01T09:01:01Z9daniel9405Dan417291Newton MAUSdaniel94052006-01-01T09:01:01ZPublic HousingIt's simply the right thing to do for others. We are blessed to live in a part of the world that has so much. This is a wonderful way to pay it forward.Providing affordable housing to people in need.37joelleJoelle2930101Pearl City HIUSjoelle2006-01-01T09:01:01ZEngineerI can. 18chedChed59131NYUSched2006-01-01T09:01:01Zmedical sonographerEveryone deserves to live their life with dignity. We all wish the same for ourselves and our loved ones; hope, health, and happiness. I am married, with four grown children. I've worked in the medical field over 33 years.482andrew1801AndrewSeattle WAUSandrew18012006-01-01T09:01:01ZSystems Programmer118wesley1179Wes (Taka)4302791Kamiyama, Myozai Gun TokushimaJPwesley11792006-01-01T09:01:01ZUniversity StudentBecause I know that I don't need the next CD album, PS3 Game, or $100 jeans, and that this truly can drastically change someone's life.To learn more about myself in University. I am pursuing a career in Medical Laboratory Sciences. I'm currently a Team Leader at the Campus Food Bank at the University of Alberta. Unfortunately there are also local issues which need to be dealt with as well, including in such rich countries like Canada.22duncanDuncanGBduncan2006-01-01T09:01:01Z9margaret3512Margaret77701Talbotton GAUSmargaret35122006-01-01T09:01:01Zstudent9joeduckJoe Duck184991Talent ORUSjoeduck2006-01-01T09:01:01Zhttp://joeduck.wordpress.comInternet Travel MarketingPublish Travel Information1seijiSeijiBerkeley CAUSseiji2006-01-01T09:01:01ZInternational DevelopmentI believe.14christopher4057Chris119541Melbourne VictoriaAUchristopher40572006-01-01T09:01:01ZLawyer & ResearcherI always wanted to do something to help and this seemed like the perfect way to help someone get on their feet and help themselves. I do research into doctors and I work as a commercial lawyer.26davechurchChurchFishburn DurhamGBdavechurch2006-01-01T09:01:01ZChemical EngineerPeople need itI help to design and construct facilities to make chemicals such as penicillin.18tariqTariqAKUStariq2006-01-01T09:01:01ZProject Manager20vicky1014Clan Torrance129221Insch AberdeenshireGBvicky10142006-01-01T09:01:01ZBanker and EngineerIts good to give a world perspective to our children. And I had a friend who got murdered in Afghanistan trying to promote this sort of thing, so its in memory of him.I\'m a relationship banker, ironically enough. I lend money to companies who want to invest in property in the North of Scotland. My husband is a project engineer in the oil industry and here\'s a picture of our daughter with a dirty face.332arunArunBeverly MAUSarun2006-01-01T09:01:01ZEngineerI was born in India, moved to Australia and living in the US now. I know what a difference anything we loan can make in developing countries. I love the micro-credit concept where your money works for many people over time. 1891tom4789TomUStom47892006-01-01T09:01:01Zdrug developmentI admire the optimism and self-sufficiency of people who want to take care of themselves and their families.I make sure that my company's research meets the expectations of the US Food and Drug Administration65colin7578ColinEdinburgh ScotlandGBcolin75782006-01-01T09:01:01Z10sue4969SueHightstown NJUSsue49692006-01-01T09:01:01Z58gillian4386Gill3084891Nottingham NottsGBgillian43862006-01-01T09:01:01Zwww.astrologica.co.ukRetired School teacherI love it that my loans are for people to help themselves with their own ideas for how best to use the money. This is so much better than giving without any real insight into what might make people's lives better.Now I am retired from teaching I continue my own practice in Counselling and Astrology.102nnicoleNicole210111Los Angeles CAUSnnicole2006-01-01T09:01:01Zellipticcurve.livejournal.comEngineerMicrofinance is one of the few programs that can and does make a very real difference in people's lives. *** I'm especially interested in Paraguay, because of the time I spent there with an outfit called Amigos de las Americas (http://www.amigoslink.org/) (!Rohayhu Paraguay!) (By the way, for those of you thinking of backing a <i>dispensaria</i> but not sure what it is--it's like an old-fashioned general store. They're all over Paraguay, varying in size from "booth" all the way up to "7/11", and are a staple in rural life and its economy.)14tom9Tom16331FordingbridgeGBtom92006-01-01T09:01:01ZProcess Design Engineer (Oil Refining)I want to give people the opportunity to help themselves and their families out of poverty for the long term.324wayne7117Wayne339051Alexandria VAUSwayne71172006-01-01T09:01:01Z311phelimPhelim460271Brooklyn NYUSphelim2006-01-01T09:01:01Z114jennifer6141Jennifer37111Hyattsville MDUSjennifer61412006-01-01T09:01:01Zhttp://www.bigstockphoto.com/search.php?photo_by=9tD4afPp05Lab TechI don't have much but maybe if I give a little I can make someone else's life a little better and I will not have wasted mine.I assist research scientists. I keep notes, enter data into computers, get samples, sweep floors, everything that needs to be done in the laboratory.252tim1597TimWest Linn ORUStim15972006-01-01T09:01:01Z2coreyrolandCorey17291Montreal QuebecCAcoreyroland2006-01-01T09:01:01ZI think its a great thing to do. Kiva is a means to enable and empower others and I admire its mission. I like the portfolio aspect, and truly feel like I'm investing both in businesses and in people.I7steve9120Steve337631Los Angeles CAUSsteve91202006-01-01T09:01:01Zwww.shymob.comWriter/ProducerIn traveling to different places I saw first hand what even a little money could do for someone. I also like that these loans empower people to change their own lives how they see fit.I help produce television programs.10rickcRick CBanstead SurreyGBrickc2006-01-01T09:01:01ZChurch Minister19josh2179Josh & Amanda352781Seattle WAUSjosh21792006-01-01T09:01:01Zwww.interactionintl.org/Therapist; Nursing StudentThy kingdom come, Thy will be done on earth as it is in heaven.7533jo7801JoVancouver BCCAjo78012006-01-01T09:01:01Zwriter"From each according to his abilities, to each according to his needs." Tommy Douglas "Courage my friends, it is not too late to build a better world." Also Tommy Douglas201heather1238Heather584061Franklin NCUSheather12382006-01-01T09:01:01ZI am a visionary that helps change lives. I support CanadaWriter-Self Empowerment 24stephen6127Steve53921DudleyGBstephen61272006-01-01T09:01:01Z20pbdinkinsPaul283671St Charles MOUSpbdinkins2006-01-01T09:01:01Zwww.monitorclosely.com/f/stlOwner - MonitorClosely.com | St LouisI want to defeat poverty and I believe this is an excellent method.Sell and service secutrity camera systems.131amy1085AmyEureka CAUSamy10852006-01-01T09:01:01Z7felix1881FelixRockville MDUSfelix18812006-01-01T09:01:01ZEconomistIt's the best way to help people!69stephen1315Stephen15931Whashton North YorkshireGBstephen13152006-01-01T09:01:01Zwww.whashton.netRetiredKiva has the advantage of letting you see your money directly benefiting others. It also keeps your feet on the ground as it is quite humbling when you get a glimpse of their lives.165eugeneEugene1461811Rusthall Tunbridge WellsGBeugene2006-01-01T09:01:01Zwww.1ComputerCare.co.ukComputer TechnicianMy life was enriched by working overseas for many years and helping in a small way those who were so welcoming to me seems the right thing to do.I work with computers: repairing, advising on new purchases, helping with Internet connection problems, tuning performance, recovering lost data and removing virus infections.27francisco1186Francisco624801Pinos del Rey GranadaESfrancisco11862006-01-01T09:01:01ZEstudianteMe gusta ayudar a la gente directamente, sin intermediarios que se lleven parte del dinero51davemc500hatsDave2909881Palo Alto CAUSdavemc500hats2006-01-01T09:01:01Z500hats.typepad.comentrepreneuri like to help people help themselves.i'm an entrepreneur in california, involved in technology companies.167mario3526MarioChandler AZUSmario35262006-01-01T09:01:01ZLecturer12dan3764Dan54191Lawrence KSUSdan37642006-01-01T09:01:01ZCity PlannerMicro loans are a great way to use a small part of my cash to make a big difference in someone's life. I help plan for the future growth of a great community.9simon9925Simon102191North LincolnshireGBsimon99252006-01-01T09:01:01ZProject ManagerI learned of Kiva from a report from the BBC and was amazed again by such an innovative use of the internet to do good on a global scale. I would encourage anyone who can spare a little cash to support this site and the people around the world that it helps.I manage the delivery of networks and other IT services to large corporate organisations.45chfCHF International24271Silver Spring MDUSchf2006-01-01T09:01:01Zwww.chfinternational.orgHumanitarian Aid and Development Organizationwe believe in the power of people to build a better world for themselves. CHF International\'s mission is to serve as a catalyst for longlasting change assisting low-income communities improve their own conditions. As a Kiva partner, we believe in Kiva, its lenders, and its clients. 6john3748John1251631Argyle TXUSjohn37482006-01-01T09:01:01Zdallasstreetstories.blogspot.com/Tech SupportI believe that capitalism is the most effective means of wealth creation and this is a way that I can help directly.My work isn't very interesting. But what I do on the streets of Dallas is most important. I try to give some hope and encouragement to the Homeless in Dallas.3graemelklassGraeme and Mel Klass1839891Dandenong North VICAUgraemelklass2006-01-01T09:01:01Zwww.empoweringhealthykids.comEntrepreneurWe believe in the power of microcredit to help countries lift themselves out of poverty.We started tech-based businesses, MyPed (www.mypedtechnologies.com)7mateMátéBudapestHUmate2006-01-01T09:01:01Zengineer28bob1631Bob1625911DublinIEbob16312006-01-01T09:01:01Zwww.threshold.ieNGO DirectorI believe in helping people to help themselves Director of NGO that helps prevent homelessness in Ireland6christopher3795ChristopherCardiff Cardiffchristopher37952006-01-01T09:01:01Z5teganTegan202731Sunnyside WAUStegan2006-01-01T09:01:01Zrealtegan.blogspot.comComputer TroubleshooterIt's the right thing to do. Helping people help themselves is a noble cause.I make computers behave.23SydneyAustraliaRandal2843371Sydney NSWAUSydneyAustralia2006-01-01T09:01:01ZI loan because I can.1531lisa8531Lisa1038661Renton WAUSlisa85312006-01-01T09:01:01Zladunham.blogspot.comRetail SupervisorI am blessed with what I need, and I want people to have the opportunity to make their lives better. Working retail can have it's advantages and disadvantages. The biggest advantage is meeting people from all over. The daily grind though can be a bit overwhelming, it allows for the making of interesting situations and stories.4mark6698mark2306761pittsburgh PAUSmark66982006-01-01T09:01:01Zwww.northsidefarmer.blogspot.comfarmer and teacherI have money. Other people don't. I believe that it is the responsibility of those with means to use those means to make the world a more just place to live. Kiva is one very real way to do that.I teach kids how to grow vegetables on vacant lots in the city of Pittsburgh, Pennsylvania.48edward5886Ed 39171Ames IAUSedward58862006-01-01T09:01:01ZEngineerMicrolending is very effective and helps people to help themselves.I work in the Department of Transportation in my state. We try to make roads, bridges and other transportation related things better and safer. I\'m also studying for a graduate degree in environmental engineering.731robert9548Robert1794971Rome GAUSrobert95482006-01-01T09:01:01ZTeacherI love the idea of making people self sufficient.I teach business in a community college. Many of my students want to start their own businesses too.9chad4388LaurenOmaha NEUSchad43882006-01-01T09:01:01ZStudent10krisztinaKrisztinaMiskolcHUkrisztina2006-01-01T09:01:01ZGeneral ManagerI worked several years as financial manager for big international companies and now I work for the company of my family. I know how hard it is doing and staying in business with limited capital and I would like to help for those who dare to stand up and do business for really improve their standard of living.68hollyHollyRedwood City CAUSholly2006-01-01T09:01:01Z8maliwatChris1255411San Francisco CAUSmaliwat2006-01-01T09:01:01Zwww.maliwat.com9ann3660Ann179381Seattle WAUSann36602006-01-01T09:01:01Zwww.aboutbrownbags.comself employed craftspersonIt makes me feel good! Someone believed in me enough to loan me the funds I needed to start my small business. I owe it to the Universe to give back. I thank Kiva for making that possible.I design and handcraft leather bags. I've been selling my bags in Seattle's Pike Place Market for several years.....I love what I do.573ricardopereiraRicardo169961Zurich -CHricardopereira2006-01-01T09:01:01ZProject ManagerI can see the money put to good use. Keep the good work Kiva.4114john5272JohnWayne paUSjohn52722006-01-01T09:01:01ZSystems AnalystHelp goes directly to those who need it. The opportunity is tied to accountability, which is the only way to succeed and prosper. I wish all of Kiva\\\'s entrepreneurs the best!20devpDevP1287691Somerville MAUSdevp2006-01-01T09:01:01Zforgreatjustice.netProgrammerI like seeing entrepreneurs change things.I work on websites, connecting people together.17benjamin5175BenjaminMADRIDESbenjamin51752006-01-01T09:01:01ZUnemployedI invited my friends and family to make 2006 \"a year of sharing\". 15 of them joined me in funding 3 KIVA projects.I usually wokr in marketing and advertising. I recently worked with NGO\'s, designing fundraising campaingns for them31nicholasNicholasChicago ILUSnicholas2006-01-01T09:01:01ZIt's important for all of us to help each other.20kerryKYKerry201061Dry Ridge KYUSkerryKY2006-01-01T09:01:01ZThere is a need and I have the ability. It feels really good to be part of something so positive.1021jorgetownJorge4534371London WestminsterGBjorgetown2006-01-01T09:01:01Zwww.jorgetown.netSoftware Engineer36jordanaJP13Santa Cruz CAUSjordana2006-01-01T09:01:01Z141energystoreTimSydney AKUSenergystore2006-01-01T09:01:01Zwww.energystore.bizEnergy Consultant/Therapistit's the best use of a dwindling resource (cash!)People come to me to fix up problems in their lives no-one else has been able to help with8christina9245ChristinaLakewood COUSchristina92452006-01-01T09:01:01Z2srijanaSrijana1223351Redwood City CAUSsrijana2006-01-01T09:01:01Zwww.friendsofelshadai.comManager, Eco Policy & Emerging MarketsWe are all responsible to do our part to help those less fortunate than us. And I am all about empowering people at the grassroots level! I work for Global Policy and Government Affairs at Cisco Systems. I love my jobI love to travel and want to dedicate my life learning about the history, culture and struggles of people who live in various parts of the world. In 2007 I started a non profit for El Shadai foster home in Uganda along with my three wonderful friends. 31michele2870Michele2000481Rio Rancho NMUSmichele28702006-01-01T09:01:01Zwww.spottie.netIf you do a good thing it will set events in motion that will allow other good things to be done. If you do nothing - nothing happens.8janice8985Janice3325871Yonkers NYUSjanice89852006-01-01T09:01:01Zsuccessissweetest.comCareer and Lifestyle Coaching Micro-lending is such an incredibly effective and simple way to pitch in. I wouldn't otherwise be able to do so much with so little. I help people build work projects and accomplish life long goals.161chris2545chrisblackwood SAAUchris25452006-01-01T09:01:01Z4bobmanBob35651Berkeley CAUSbobman2006-01-01T09:01:01Zryskamp.orgWeb designI design and build programs on the internet.9tenthousandpoetwarriorsAlex346491Chino Hills CAUStenthousandpoetwarriors2006-01-01T09:01:01Zwww.xanga.com/tenthousandpoetwarriorsNanotechnologistProverbs 19:17 says, "One who is gracious to a poor man lends to the LORD,And He will repay him for his good deed."21diana7058DianaNY NYUSdiana70582006-01-01T09:01:01ZEditorHow can you not?Too much sitting at the computer, with some very neat, creative points39nfolkertNathan15611Brooklyn NYUSnfolkert2006-01-01T09:01:01Zstanford.facebook.com/profile.php?id=203195Software EngineerI believe that providing the opportunity to create local enterprise and satisfy local needs in an independent and self-managed way is one of the best ways to strengthen society, help people to escape poverty, and bring real progress and development. Plus I love the stories, both as narratives demonstrating this progress, and as touching views of the lives of people who are working to make a better life for themselves and their families. Thank you, Kiva!I work at a startup that writes programs to answer questions and solve problems for businesses.14065charles1331Ranger4082531Alpharetta GaUScharles13312006-01-01T09:01:01Z128carisaCarisa330121Washington DCUScarisa2006-01-01T09:01:01ZForeign Affairs OfficerInternational Trade Policy17moongsterStan Moong462161SGmoongster2006-01-01T09:01:01Zmoongster.blogspot.comFreelancerI've been given many opportunities in my life, and would like to help out other communities.I used to work in an office surrounded by papers and computers. :p7damien2484Damien1911001BarcelonaESdamien24842006-01-01T09:01:01Zwww.gocartours.esEntrepreneurI know that Banks are bastards!388quocanhDo Quoc-AnhSingaporeSGquocanh2006-01-01T09:01:01ZAssistant ProfessorI like helping people grab their opportunities.I do research in economics and teach at a university.jantiJanti Soeripto1032461RotterdamNLjanti2006-01-01T09:01:01Zwww.belu.orgManaging directorBusiness is a great way to help people take responsibility for their own lives rather than being dependant on aid.27leendertbosLeendert Bos169261Utrecht AKNLleendertbos2006-01-01T09:01:01Zwww.oikocredit.orgMarketing microfinancein professional life I do the marketing for Oikocredit, a leading investment fund for microfinance. I am enthusiastic about Kiva as it gives the opportunity to finance people with good business plans personally We raise investment capital to provide credit to poor people.4erica5917Erica47161Los Angeles CAUSerica59172006-01-01T09:01:01Z73jane8235Jane92861Winchester HampshireGBjane82352006-01-01T09:01:01Zknally.livejournal.comSoftware Engineermoney is like manure. It only does any good if you spread it around.I work in a group which provides fixes for software on mainframe computers. My job involves coding, testing, documenting and reviewing these fixes.1632sirishsirishNew Malden SurreyGBsirish2006-01-01T09:01:01Z1kevin91Kevin2187541Glen Burnie MDUSkevin912006-01-01T09:01:01ZEngineer76oOooOo17161Santa Monica CAUSoOo2006-01-01T09:01:01Zwww.ozoux.com/eclecticFilmmakerGive a man a fish, and he won\'t go hungry for a day. Teach a man to fish, and he will feed his family. Loan him some money for a fishing boat, and he will help bring his village out of poverty.26paul7489Paul2115701Scottsdale AZUSpaul74892006-01-01T09:01:01ZExecutiveIt is the most effective way that I personally can help make the world a better place.I design electronic machines that let people buy products and services with a bank card, credit card, or smart card.119linda9514Linda2197331Warin Chamrab Ubon RatchathaniTHlinda95142006-01-01T09:01:01Zwww.ned.com/user/u523412994/LecturerI can; I should; I MUST!I am a full time graduate student in Integral Development Studies focused on values based economics.13filibertoamatiFiliberto Amati4320501Saint Martin French West IndiesTFfilibertoamati2006-01-01T09:01:01Zwww.e-filiberto.comArea Manager CampariIt does work!!!!!!marketing and sales of branded spirits and wines572nathan9600Nathan1523731Tucson AZUSnathan96002006-01-01T09:01:01ZI don't see a reason not to.12brieBrie & Emil A.73421Santa Clara CAUSbrie2006-01-01T09:01:01ZAttorney; Ecologistit is a small way to help those in need in other countries. Brie works at an immigration law firm in the Bay Area. Emil is a UC Davis graduate student in ecology.1921lizaLiza468221Sunnyside NYUSliza2006-01-01T09:01:01ZI believe in the power of people to make changes in their own lives and situations. Sometimes we all just need a little help with the resources to make those changes.5jeff1667Jeff Parry2646951Pontypool TorfaenGBjeff16672006-01-01T09:01:01Zjeffanddith.wibsite.com/Freight ForwarderI believe that people are served best when they are allowed, and encouraged to help themselves. In addition it is my duty as a Christian to help those in need - regardless of faith, nationality or wealth.I arrange the movement of goods from various countries to the UK and to various countries from the UK. My wife and I also run a social enterprise to help those in need in our community and visiting people in prison.34kate4399KateCalgary ABCAkate43992006-01-01T09:01:01ZTechnical writerit's a way that I can help.31henkvanstokkomHenk J.Th. van Stokkom428501Dordrecht NL AKNLhenkvanstokkom2006-01-01T09:01:01Zwww.vanstokkom.nlDoendenkerHaving been involved in microfinance I know it works. Not a solution for everyone, but for a lot of people it can be.See my website/log: 572elliottElliott Campbell561001palo alto CAUSelliott2006-01-01T09:01:01ZPostdocI want people eveywhere to have greater access to resources.Applied research on the climate impacts of biofuels.51laura2108LauraBothell WAUSlaura21082006-01-01T09:01:01ZManager1264owenOwen2292511RIUSowen2006-01-01T09:01:01Zwww.existence.comEntrepreneurI believe local entrepreneurs are the key to building economies.3francescoFrancescoBrooklyn NYUSfrancesco2006-01-01T09:01:01Z2mjgoldMark Goldenson70131Palo Alto CAUSmjgold2006-01-01T09:01:01Zwww.goldenson.comProduct managerI believe microfinance is an awesome way to use a small effort for a big difference.16kcK.C. Teis546151Livermore CAUSkc2006-01-01T09:01:01ZDirectorIt makes me feel good and I really support what KIVA is doing.I manager a group of very talented Managers and Designers as PayPal.com161brookeinvaBrooke201981Roanoke VAUSbrookeinva2006-01-01T09:01:01ZTeacherI believe it's the right thing to do. And it's fun! It builds connections in the world for me.I spend my days teaching English to children who's parents do not speak English.191METARkivaRick50481Orlando FLUSMETARkiva2006-01-01T09:01:01ZApprentice WizardIt makes me smile.60terri1169Terri462101Fredericksburg VAUSterri11692006-01-01T09:01:01Zwww.tenthousandvillages.comTen Thousand VillagesIt makes a real difference, right now, in others lives.I am assistant manager and volunteer coordinator at a non-profit, fair trade store.20margettsBenjamin52951London SurreyGBmargetts2006-01-01T09:01:01Zwww.vso.org.ukTeacherI've been really lucky in life and I reckon I ought to help other people in some way realise their dreams.Right now I'm working in Cambodia and mulling over new ideas. 651mark7612MarkManchester Greater ManchesterGBmark76122006-01-01T09:01:01Z12asbjornAsbjorn Osland778311San Jose CAUSasbjorn2006-01-01T09:01:01Zwww.cob.sjsu.edu/osland_a/Business professorI worked in international development for 11 years and believe strongly in micro-lending. Kiva does a great job!I teach students practical and applied concepts that I hope will make them better managers and leaders.3161adamsteinAdam329781Brooklyn NYUSadamstein2006-01-01T09:01:01Zhttp://www.terrapass.com/terrablogSocial entrepreneurIt's so damned easy, why wouldn't I?I work to reduce air pollution caused by burning oil and coal.181valrozyckiValerie2060771BangaloreINvalrozycki2006-01-01T09:01:01Zwww.linkedin.com/in/valrozyckiAspiring Social EntrepreneurI believe in the power of technology to create access and enable grass roots development.I currently work for a mobile payments startup in India, mChek, responsible for our efforts around microfinance and the "bottom of the economic pyramid."peter4236Peter207711Silver Spring MDUSpeter42362006-01-01T09:01:01ZSocial WorkerWe are all One!I help people make good decisions and heal their personal sadness.541alan888AlanSunnyvale CAUSalan8882006-01-01T09:01:01ZinternetI believe in \"teaching someone how to fish\" instead of giving them a fish.13glenn2630GlennCambridge ONCAglenn26302006-01-01T09:01:01Z93BJAliciaBJ & AliciaWashington DCUSBJAlicia2006-01-01T09:01:01Z121fredericFrederic796801San Francisco CAUSfrederic2006-01-01T09:01:01ZI realize how lucky I am.40tammyjoTammy Jo3745401West Chester OHUStammyjo2006-01-01T09:01:01ZIt matters! A small amount can make such a difference! I love knowing that when we all put our small resources together it becomes so much more and we accomplish so much more than we could ever do alone. I love supporting and encouraging those who want to make a better life through their own dreams.2simon8263SimonSai Wan HoHKsimon82632006-01-01T09:01:01Z47kit4469kitLaval QuebecCAkit44692006-01-01T09:01:01Z51alanaachterkirchenAlana2268611Portola Valley CAUSalanaachterkirchen2006-01-01T09:01:01ZMarketingI really love the personal stories of Kiva entrepreneurs, and believe in the power of a global lending community. I've worked in marketing at high-tech companies in the Silicon Valley (California, United States) for the last 15 years. Although it's been a lot of work, I really enjoy what I do. Without question, I love seeing ambitious people doing whatever they do wherever they are & I'm thankful to Kiva for providing this window to the world. 2gary2255GaryCAUSgary22552006-01-01T09:01:01Z12peterjamesPeter17721Ottawa OntarioCApeterjames2006-01-01T09:01:01ZJournalistIf small businesses can succeed, communities can be built around them. This is a great way to help people build a sustainable economy.I am a sports writer/editor 2123kerry7396Kerry2687181SaskatoonCAkerry73962006-01-01T09:01:01ZEngineerits the right thing to do.61forrestForrest and Georgette1806861Zurich IACHforrest2006-01-01T09:01:01ZDoktorandI amStudying to get our PhD's in Sustainable Architecture and Biomedical Engineering9mimobaseMark4279341Woolloongabba QLDAUmimobase2006-01-01T09:01:01Zwww.mimobase.comGraphic DesignerSometimes I have spare money, which makes me feel a bit guilty and instead of buying things I don't need, I'd like it to help someone.I make things look nice.201andres6914Andy & JeaneBuffalo NYUSandres69142006-01-01T09:01:01Zcoming soon...media entrepreneursWe believe in the dignity of work. When someone believes in you, you don't have to work quite so hard at believing in yourself. And because fishing rods are better than fish. Our work is much like yours. We try to make something useful out of other things (in our case, fashion information) and by adding value to it, profit enough to keep body and soul together and better our circumstances a bit at a time. Microlending is a way to make a real difference that can be measured.19wayne1011Wayne161971Moncton NBCAwayne10112006-01-01T09:01:01Z171celinaCelina20151Bergen HordalandNOcelina2006-01-01T09:01:01ZCartographerI've been so fortunate both personally and professionally. Many (most?) women never have access to a career that brings both joy and security to their lives. I love my job and I want be a part of helping other women gain the kind of financial stability I enjoy.I like trying to be a better person today than I was yesterday.1351ellen3988Ellen767281Victoria British ColumbiaCAellen39882006-01-01T09:01:01ZThis is something I can do to try in my own small way to work towards more equality in the world.I am 42 years old and have 2 cats who are like my children. I do computer work in a government office in Canada.171sanamSanam427401LondonGBsanam2006-01-01T09:01:01ZPeople need the loan.141matt4426Matt1418211Madison WIUSmatt44262006-01-01T09:01:01Zwww.ithryv.comEntrepreneurI believe access to capital to create businesses can lead to long-term quality-of-life improvements for the entrepreneur, employees, and the community. I create technologies -- software and hardware -- to help people learn.66richard9176Richard660741Walton on Thames SurreyGBrichard91762006-01-01T09:01:01ZThe whole world is one family and we should look after other family members who are not as well-off as we are. Thank you Kiva for helping me to be able to make such a direct difference.222eric7396Eric2806021Durham NCUSeric73962006-01-01T09:01:01Zwww.ericpgreen.comPostdoctoral FellowIt works.1david4302David200071Miami Beach FLUSdavid43022006-01-01T09:01:01ZAlgorithm DeveloperI think helping people to become entrepreneurs, and thus to help both themselves and their communities improve is something I strongly believe in. It's also great that when the money gets repaid, I can loan it back out.I work at a company that makes biomedical testing instrument systems. The group I work in measures the different kinds of blood cells people have in their bodies. This information helps doctors figure out if a patient is normal, or might be sick.211naokoNaoko78941ErlenbachCHnaoko2006-01-01T09:01:01Zwww.microfinance.ws/weblogmicrofinance investment consultantI truly believe in microfinance, microfranchising, double bottom line businesses, sustainable businesses and in empowering people. I also believe that we can all participate in making the world a better place to live.Independent consultant for microfinance investments. Author, speaker.734eric6244Eric2217691Edmonton AlbertaCAeric62442006-01-01T09:01:01ZResearcherHelp gives hopeDreaming of a better world17michael5666Michael211301Cardiff WalesGBmichael56662006-01-01T09:01:01Zwww.helpfromhome.org/Architectural TechnicianI'm fed up of the 'me, me, me' culture I live in. I say 'give, give, give' - you get a much better glow in your heart because of it.I do the technical drawings ie. blueprints for buildings. Oh, and I also make origami hats.361ed8968EdwardDrogheda County LouthIEed89682006-01-01T09:01:01Zeveryone needs a hand up.legal and commercial3diego4DiegoSan Francisco CAUSdiego42006-01-01T09:01:01Z61brian8977Brian Evans1553301Palo Alto CAUSbrian89772006-01-01T09:01:01Zteacherit worksEconomics Instructor41robert7287Rob66711Toronto OntarioCArobert72872006-01-01T09:01:01ZActor/WriterThis is a brilliant way for us to help our friends around the world.I am an actor and writer in Toronto, Canada282patrick3047Patrick80311San Francisco CAUSpatrick30472006-01-01T09:01:01Zwww.paypal.comProduct ManagerPremal told me to. (http://www.kiva.org/lender/premal)I create and implement unique products that enable PayPal and Skype to empower global ecommerce and communications. I also attend many meetings and read many emails.14thomas2453Toma1511901Ctr Ossipee NHUSthomas24532006-01-01T09:01:01Z111vulgrinDavid Sanders2459441Fort Wayne INUSvulgrin2006-01-01T09:01:01ZWe all need to pitch in and help each other out, if we're all going to save the world.393ben5201Baume Family210801Coppell TXUSben52012006-01-01T09:01:01Zwww.stainlessrhino.comPresident/OwnerOpportunity knocks and more opportunities need to be provided to the world in the interests of making someone's life more fulfilling personally and professionally.I own a commercial construction sub-contracting/distribution company-we sell and install 30-40 products in the North Texas area ranging from bathroom partitions and accessories to flagpoles8kivabenBenjamin31431Rockville Centre NYUSkivaben2006-01-01T09:01:01Zwww.kiva.orgRegional Director, Anglophone Africa & South Asiabillions of people in the world live in poverty each day despite the will, desire, and hope of escaping through hard work and determination.I have the best job in the world talking to microfinance institutions in Anglophone Africa and South Asia about Kiva, helping them to partner with Kiva, and monitoring the partnership through time. My cup brims over.232benfben and jenny4132531cambridge MAUSbenf2006-04-18T05:51:39Zmedical device analystit makes me feel good.i study medical companies and tell investors which ones i think will succeed7peepPeep1861711EEpeep2006-04-18T06:33:47Zwww.dreaminder.cominternet entrepreneurI believe in entreprenerushipI help people live their life on their terms141kaiKaiTampa FLUSkai2006-04-18T10:59:25Zmedical studentReligion that God our Father accepts as pure and faultless is this: to look after orphans and widows in their distress and to keep oneself from being polluted by the world. - James 1:2715sarah1425Sarah1735931Austin TXUSsarah14252006-04-18T14:22:27Zwww.bagsmakeadiference.comEntrepreneurBest Investment.I have lived and traveled all over the world. I look for ways to use business to improve the lives of people and of the planet. My main interests are women empowerment, poverty eradication and environment11weiliWeiliWashington DCUSweili2006-04-18T19:02:12Zmedical studentIt\'s a great idea for empowerment as well as aid. I am very impressed by the business owners who participate.I am studying to become a doctor.4ericolsonEric Olson33641Chicago ILUSericolson2006-04-18T21:31:52Zwww.ericjohnolson.com/blogMBA StudentI want to help entrepreneurs build businesses that will pull them out of poverty.I am a student now but I used to help entrepreneurs build businesses by financing them and providing them with advice, support and contacts as a VC and I helped to build FeedBurner from the ground up as an early employee. I also enjoy cycling, baseball, drumming, movies, books, physics, history and a lot of other stuff.253dennismDennis54591Hayward CAUSdennism2006-04-19T00:11:18Zcaffeinatedcode.comEngineering ManagerThere\'s not enough monetary helping going on.I write computer programs that help people do things quicker. I am also a photographer.651jason2727Jason150391Plano IllinoisUSjason27272006-04-19T15:34:36ZProcess Improvement ManagerLots of people have helped me in life & this is just a small way of paying them back and saying thanks, plus this is a good way to teach my kids about giving! 'You don't owe me a thing, I've been there too. Someone once helped me out, just the way I'm helping you. If you really want to pay me back, here's what you do - Don't let the chain of love end with you. - Clay Walker; Live, Laugh, Love (1999)I manage projects that help my company improve the quality of the products they produce8andrew8067Andrew488501Chicago ILUSandrew80672006-04-19T19:23:42ZFinanceKiva strikes a great balance between capitalism and gift giving and I think it is the best way to improve lives.Watching financial markets and investing.109jysj.y.s.Bloomington INUSjys2006-04-20T04:54:17ZGraduate Student9russell8520Russell248541Cincinnati OHUSrussell85202006-04-21T01:45:11Zwww.russellsmusings.blogspot.comPastorI believe God has called us to be a blessing to others. Kiva offers the chance to offer a helping hand to people who are working to make themselves better. I pray regularly for the people to whom we loan, and we hope that God will bless them abundantly.34michael6969Michael W. Kruse145171Kansas City MOUSmichael69692006-04-21T04:16:11Zkrusekronicle.typepad.com6tashaTasha2125321Nashville TNUStasha2006-04-21T06:38:24Z131tracey2480Traceytracey24802006-04-21T21:33:05ZRetail Shop OwnerI like helping people get started in their future--everyone needs a little help and trust in each other!I own a ladies retail shop for bridal and formal wear 6amanda7986AsphaltQueen1712071Holt MichiganUSamanda79862006-04-21T22:08:32Z5paulinaPaulina3898621CApaulina2006-04-22T07:38:10Z6david6363David & Tricia3730381Scottsdale AZUSdavid63632006-04-22T18:22:52ZFinancial ServicesGod is Good!Financial Services Computer Software Development Horse Boarding325ashley9070Ashley2797441Vancouver BCCAashley90702006-04-23T00:29:54Z121beatBeat Muttenzer1500701ZürichCHbeat2006-04-23T08:07:50Zwww.muttenzer.netSearch Engine Marketing & Web Analytics Consultant433markusMarkus3914461RüschlikonCHmarkus2006-04-23T08:39:09Zweblotion.chEntrepreneuri can afford it and i think it is very important to give if you have more than you use.i'm programming websites and webapplications32juergJuergSt. GallenCHjuerg2006-04-23T09:15:06Z91andreasundsandraSandra and Andreas408891UrdorfCHandreasundsandra2006-04-23T09:16:08ZCredit for business is the best way to help developing countries.2581daniel9225Daniel and ChantalNiederwangen BernCHdaniel92252006-04-23T10:29:23Z31ueliUeli2647261CHueli2006-04-23T12:17:55ZConsultantI'm excited to see how easy it is to help with really not a lot of moneyI help other persons to reach their goals and to conquer their challenges in a company or as a private person11roger8429Roger2650641ZürichCHroger84292006-04-23T13:41:43Z872torrdanTorrdantorrdan2006-04-23T15:02:27Z2peter4793PeterWinterthurCHpeter47932006-04-23T15:42:22Z66maryjaneMary JaneArvada COUSmaryjane2006-04-23T15:42:45ZRetired18roland4499Rolandbaselroland44992006-04-23T17:05:06Z5nancy1124Nancy3551421Wexford PAUSnancy11242006-04-23T17:47:27Z10mike1172mike198771CHmike11722006-04-23T20:32:24Z97jonaslikestogowildJonas355821BernCHjonaslikestogowild2006-04-23T23:09:53Zlawyer traineeIt makes sense:) [->Muhammad Yunus] 4iridiumtechnologyIridium Technology2101211Reno NVUSiridiumtechnology2006-04-24T02:17:27Zwww.iridium-technology.comSoftware ConsultingThe small amount that we loan can make a huge difference in the quality of life for the recipients and their familiesI help legal and professional services firms to get maximum value from their busines intelligence solutions212gregorGregor463851ZugCHgregor2006-04-24T04:32:32ZIndependent Asset ManagerI think that microcredits can be a big piece in a puzzle to alleviate extreme poverty in developing countries and because it\'s fun - try it!I advise private clients on how to invest their money in accordance with their risk profile. I am married to a Thai and have visited Thailand, Cambodia, Laos and Vietnam more than once. I have seen the extreme poverty in Cambodia but I have also experienced the peoples\' friendliness.\r\nskype: gregorkaelin421RobiCHRobert301041Kloten SwitzerlandCHRobiCH2006-04-24T04:47:46ZBecause I hope to help others who have less capital than I have born in a rich country. 3221jennifer9761Jennifer P.2848281jennifer97612006-04-24T18:07:09Zjenpinkowski.comjournalist4philip1584philipphilip15842006-04-24T18:21:03Z28christoph3893Christoph256881HinwilCHchristoph38932006-04-24T21:09:44ZI like the idea how KIVA works. It is better to support people helping themselves than just sending money for consumption 115carlos5322Carlos44471Deer Park TXUScarlos53222006-04-25T04:45:22ZBusiness OwnerI loan because it is more blessed to give than to receive and I hope others do the same.I am blessed to own my own company that sells raw plastic materials all over the world. It is like selling fruits at the local market except that you sell by using the phone and computer.61kristineKris114861Yuma AZUSkristine2006-04-25T19:04:16ZI think it\'s fabulous and amazing that such a small amount of money can change a live/lives SO MUCH!8theresa8440tesshiva4219441Belmont MAUStheresa84402006-04-26T00:47:54ZretiredI treasure the entrepreneurial spirit, especially among women, single parents and those from the Middle East. If you have just a small amount of money, lending through Kiva is the most rewarding use for it!7christopher4084ChrisLos Angeles CAUSchristopher40842006-04-26T04:12:25Z443marcymarcybakersfield CAUSmarcy2006-04-26T05:41:56Zinsurance agentAs a small business owner myself, I know how hard it is to get started. God has been good to me, so it is important that I give back. I sell auto, home, business, and life insurance to people in the state of California, USA. I have been in business for 3 years. 25sonjaSonja17871ZürichCHsonja2006-04-26T11:39:51ZSecretaryI think it´s a great idea. With Kiva everyone, even with the smallest budget, can help. I always love to hear from \'my\' businesses.I work as a PA for a professor at the university of Zurich. The rest of my time is occupied by my son Tom and daughter Eva .16daniel4580Flügel family116671HilterfingenCHdaniel45802006-04-26T14:04:11Zit\'s great to help other people if one has the possibility431barbbarb211541london LondonGBbarb2006-04-26T21:55:45Zwww.barbjungr.co.uksingerKiva makes it possible to help people who need it, when they need it, and that's wonderful.I sing, make music and practice yoga.1081rupaRupa Tejura15581Philadelphia PAUSrupa2006-04-26T22:06:08Zwww.modiadesigns.comKivaSmall steps make a big difference.Exploring East Coast Development for Kiva and building a community of passionate lenders.7010neil2170NeilThirsk North YorkshireGBneil21702006-04-26T23:03:01Z1112declan5722Declan1371141Dunn Loring VAUSdeclan57222006-04-27T10:30:15Zwww.blog.fallondpicks.comSenior Market TechnicianFor every $25 Scratchback link I sell through my website - $25 goes to a KIVA project of your choice. 15,000 Pageviews a month for $25. Purchase a link today!Senior Market Technician for Zignals. Former reasearcher in insect pathology and sustainable methods for biological pest control. Financial market commentator and small business owner. Blogger.1441robbieRobbie Honerkamp36991Tucker GAUSrobbie2006-04-27T16:54:21ZEntrepreneurHelping startup businesses grow is the best way to help developing countries. And microlending is a great to help do this.I help start and support Internet businesses and service providers in Africa.1341natalia4467Natalia1595031natalia44672006-04-27T18:19:42Zwww.iheartpgh.org62mzrascoffMatthew2079681Boston MAUSmzrascoff2006-04-28T04:16:37ZStudentKiva is amazing.3sandra5094Sandy1731131Ann Arbor MIUSsandra50942006-04-28T14:07:30Z7james8196James116641SisselnCHjames81962006-04-28T15:59:06Zwwww.edouardlauzieres.comWatch Manufacturer in SwitzerlandI loan because I am convinced that helping other people growing their businesses is the way to go for me.\r\n\r\nI mostly loan to women. As a former professional lessor I know from experience that women are a lot more likely to pay back on time. This is important for a project like Kiva\'s.\r\n\r\nI thorougly enjoy being kept abreast of events every now and then by people I have lent to. It\'s interesting to see how they fare in their daily lives.I run a watch company here in Switzerland based upon my idea that systems have to evolve in order to survive.\r\n\r\nThe goal of the company is to make a living for as many people as possible. Profits are important to me and ploughed back into the business immediately.57ozfamilyOZ Family98541Palo Alto CAUSozfamily2006-04-28T20:26:39Zwww.kiva.orgKiva FanI believe every person should have the opportunity to have his/her own business.I work with an innovative and creative group of folks who know how to stretch a dollar! My days are filled with forecasting Kiva\'s budget, handling the daily operations, and talking to generous donors from around the world. I feel very proud to work for Kiva!663mike5431Mike & Loretta1288901boyds MDUSmike54312006-04-29T04:07:02Zshipbroker, RNIt's the right thing to do, and we like that the gifts can be continuously recycled to help even more people.Mike: International food aid shipping specialist/broker Loretta:RN121edward6348edward109381CAedward63482006-04-29T16:57:56ZRooming House WorkerI beleive in microfinancing and in allowing people to help themselves to a better life.I make sure that low-income people have a safe, secure, affordable place to live here in Ottawa.71joe3537Joe1174331PaUSjoe35372006-04-29T17:04:32Zantiquetintypes.com9brianphillipsBrian80061San Francisco CaliforniaUSbrianphillips2006-04-30T04:38:52Zwww.brianphillips.comEntrepreneurKiva is changing the world!14hajoHajo460131Berne BerneCHhajo2006-04-30T12:03:12Zwww.skppsc.chConsultantIt's a project worth to support. 100% of my loan will benefit the Entrepeneurs.I'm running a internet agency that is specialised in concepting internet prevention campaigns. My main projekt below:6richard1879RickCOUSrichard18792006-04-30T16:09:44ZWebmasterI can.96kimberly5079Kimberly, Delaney & Kody194111Huntington Beach CAUSkimberly50792006-04-30T18:16:45Z191martin9238Martin GodelTokyoJPmartin92382006-04-30T20:06:07Zwww.osec.chCivil ServantKiva is one of the best means how to promote development!Helping business in Japan71tammy4974Helping Hands75901Laguna Hills CAUStammy49742006-04-30T20:20:59ZI believe in a \"Hand Up\" not a hand out. Being able to help in this way restores self-esteem, ambition and renew's potential. KIVA provides a win-win situation for everyone.God uses my heart and hands to heal people.13garrett9586Garrett and Jen463521Austin TXUSgarrett95862006-05-01T01:03:16Z1001brian8516Brian233251North Falmouth MAUSbrian85162006-05-01T01:33:18ZSystems DevelopmentKiva provides a great opportunity to help entrepreneurs around the world with their businesses. It is rewarding to help people grow their businesses and become more financially self-sufficient. I manage a computer systems team that develops applications for a large financial organization in the United States3121leslie5641Leslie660591Norfolk VAUSleslie56412006-05-02T01:30:08Zwww.lynn.ecrater.comLPNHoping to help a person and their whole family. 5brentBrentOverland Park KSUSbrent2006-05-02T03:51:24Z42theodoreTheodore62661Seattle WAUStheodore2006-05-02T04:14:13Zsoftware engineerbecause I should.I sit at a computer all day, typing.29glen4794Glen Moore3836451Sonora CAUSglen47942006-05-02T04:31:59Zwww.greystoneelectric.netBusiness ManI believe in helping those who are trying hard to better themselves. I know how hard it is to start a new business and would like to help those willing to try.\"You only fail when you stop trying\"181heatherdearHeather1327561Santa Barbara CAUSheatherdear2006-05-02T04:52:55Zwww.evercharming.comInternet retail salesI know first hand what a difference a small loan can make and I am thrilled to be able to contribute to the dreams and businesses of people all around the world.I have a small business selling items on the internet. It is fun to work at home and spend time with my family and pets.2132theresa9189Theresa100441Mascot New South WalesAUtheresa91892006-05-02T13:07:24ZHuman Resources OfficerI have recently had some good fortune and so it seems right to help someone to succeed21matthew1069Matty374901San Francisco CAUSmatthew10692006-05-02T16:03:22Zwww.distilledclothing.comFashionI am excited about what Kiva is doing and wish to be a part of it.I design and make clothes sold in very nice stores across the United States. 2chrispadfieldChristopher3808681LondonGBchrispadfield2006-05-03T15:04:41Zwww.chrispadfield.comInvestment Managerit's the first time I have completely believed my money will make a real difference in someone's life.I work as an investment manager for a venture capital firm in London. I also have my own software company, http://www.deskpro.com32021dave8844DaveSpokane WAUSdave88442006-05-03T20:21:16ZIT ManagerI believe in the idea of seeking to serve Jesus by reaching out to the poorest of the poor and helping them to meet their most basic needs.I manage computer networks 51michael1689Michael Sawyer835081WAUSmichael16892006-05-03T20:39:52Z51anneholstAnne47181København Nanneholst2006-05-04T09:45:33Zmyspace.com/anneholstSociologistI have visited third world countries, seen the almost unimaginable poverty and felt frustrated that I couldn't see a way for me to make a visible, long term difference. Kiva provides me with the opportunity and practical means to try to make such a difference!As a sociologist I work with social and cultural issues at an analytical level - often issues related to social problems and inequalities. With Kiva I hope to make a more immediate difference to people who are affected by worldwide social inequalities.19aceAce Custodio1919121Columbia MDUSace2006-05-04T12:49:03Zwww.camtrading.comInvestment ManagementI was once on the other side of the spectrum before immigrating to the United States. My parents were rice farmers and we ate what we grew or caught for the day. We left everything we had in the rural part of the Philippines to start a new and better life. And now, I will help in whatever way I can for someone with a dream and determination to make their life better than it was yesterday. I loan because it is the right thing to do.I am Co-founder/CEO of Custodio Asset Management, an Investment Management firm in Columbia, MD. The company's mission is to produce superior returns to our clients through our proactive, disciplined approach to money management.4tom3836Caldie210171tom38362006-05-04T13:39:58ZCare giver managerI enjoy seeing businesses grow. I hire people to help seniors and disabled in their homes. 5bertrandBertrand4548701Booterstown Co DublinMTbertrand2006-05-04T16:03:30ZDevelopment Education4marina7960MinaAllen TXUSmarina79602006-05-05T04:28:33ZI want to make someones life better. 4megMeg1486271Minneapolis MNUSmeg2006-05-05T05:04:54ZAssociate Marketing ManagerI support small businesses locally, so why not support them globally!I work for a food company, helping come up with packaging and how much we should charge in the grocery store. I also tell my company how much they should be able to sell.2emily8563EmilyDacula GAUSemily85632006-05-05T16:20:41Z881maria9556Maria441071STAR IDUSmaria95562006-05-06T00:04:13ZRealtor, Candy VendorI care and want to make a difference. I am sure that the little bit that I contribute along with everyone else makes a HUGE difference in someone's life...and maybe even a whole family's life. This reminds me of the starfish on the beach story...I help people to buy and sell homes. I also have quarter bulk candy vending machines located in various businesses.19rodRod132381rod2006-05-06T01:06:14Zwww.beckstrom.comDirector, National Cyber Security CenterI like helping the poor.Backing great new people and ideas, like Kiva.org2mirazMirazWellingtonNZmiraz2006-05-06T03:33:03Zknowit.co.nzWriterI live in a part of the world where we're lucky enough to have so much. I want to share my good fortune with others.I work for myself. Clients pay me to write articles for websites, magazines and books. Sometimes clients pay me to rewrite information they already have, so it's easier for people to understand.95brooke8719BrookePrinceton NJUSbrooke87192006-05-06T04:37:32Z231holly1480Holly76611Santa Rosa CAUSholly14802006-05-07T04:33:42Zdesktop publisherour family has seen enough countries where just a few dollars would make a huge difference. Why not put those dollars to work where they will be more valuable than here? I think I can afford to lose the yearly interest on a couple hundred bucks!I have my own business at home where I design, edit and put together flyers, newsletters, etc. for other small businesses. My business comes to me by word of mouth.682kyle9164KyleStanford CAUSkyle91642006-05-07T07:42:08Z7audreyAudrey1287591audrey2006-05-07T15:14:19Zedupreneurthere's no reason not toI am currently working for a Malaysian inventor and entrepreneur . We are building a company that makes educational games, currently focusing on an online multi-lingual, open source, multi-player game.72cmaxMax1107121cmax2006-05-07T16:11:47Zwww.goodmagazine.comco-founder, GOOD Magazinei believe this is a wonderful way to put money to work.11adrian9634AdrianObernauCHadrian96342006-05-07T17:54:05Z53antonioandolgaantonio and olga62621menlo park CAUSantonioandolga2006-05-07T19:17:30Zwww.culturekiosque.comproduct managersHow can you say you\'re not responsible?I ask the customers of my company about what they need our products to do, and make sure that our products solve customer's problems.854eseemaSeema1236161San Francisco CAUSeseema2006-05-08T03:34:56Zeseema.wordpress.comGeneral ManagerIt's incredibly easy! More importantly, I believe in paying it forward and I'm getting a great return... I am the General Manager for WorldofGood.com & eBay Giving Works. I love what I do because I get paid to be innovative, I work with genuinely great people, and I know that our businesses create direct social value through ethical sourcing, economic empowerment, and fundraising. I am also a (lapsed) proud and humble Kiva volunteer. :-)381brian7215Brian KGladstone MIUSbrian72152006-05-08T06:35:27Z5todd6715Todd199411Mountain View CaliforniaUStodd67152006-05-08T06:39:38Zhttp://www.kulick.com/toddTiVo EngineerI make TV better!1laura8174Laura2728431San Diego CAUSlaura81742006-05-09T02:59:40ZBD DirectorI believe in micro-financing as a vehicle for empowerment and peace.183leahLeah1256461Tampa FloridaUSleah2006-05-09T17:09:55Zstudioslsm.carbonmade.comArtistI love being able to help give people a future as well as their dreams!61daniel1236Dan MarquesEasthampton MAUSdaniel12362006-05-09T20:21:09Z3moiraMoiraSan Francisco CAUSmoira2006-05-10T17:52:40Zi have the means to and the world sorely needs some economic redistribution1allenAllenStarks LAUSallen2006-05-10T18:25:12Zwww.warriorforum.comInternet MarketerI love helping people that are trying to help themselves.412julia2042Julia1467281Big Flats NYUSjulia20422006-05-11T06:25:07ZI like the feeling of a personal touch that a Kiva loan provides.42samuel5861Sam2898471Houston TXUSsamuel58612006-05-11T16:45:09ZEngineer16katherine2031Katherine1600621San Francisco CAUSkatherine20312006-05-11T18:50:06Z52dimitriDimitri Dadiomov300351Stanford CAUSdimitri2006-05-11T22:39:39ZStudent72rumeshaRumesha327551San Francisco CAUSrumesha2006-05-12T06:02:24Z3marclaurentMarc P.2858991Toronto OntarioCAmarclaurent2006-05-12T17:05:19ZProduct DesignerI like helping people.I help companies create products that are high quality, innovative, well designed and that appeal to buyers.3trentTrentWhite Bear Lake MNUStrent2006-05-12T21:07:47Z21sumitSumit SoniRiyadhSAsumit2006-05-13T15:50:58Z8judith5545Judith161071WinterthurCHjudith55452006-05-13T22:05:41Z113george1833George202061Halifax Nova ScotiaCAgeorge18332006-05-14T00:59:28Zclassroom support IT technicionIt feels very good to help a littel bit.I take care of the computers, data projectors, and other types of media equipment in the classrooms of a smaller sized university41susan6319susanRossland British ColumbiaCAsusan63192006-05-14T15:57:19Z38mithAlainThornton COUSmith2006-05-14T16:14:32ZSystems Engineer46chiragChirag3594491Chicago ILUSchirag2006-05-14T20:33:35ZKivaI believe we can alleviate poverty.1710bergerieMouton68311Chicago ILUSbergerie2006-05-14T23:29:24Zwww.travbuddy.com/widget_map_display.php?id=1324665Brownian jumperIt feels like travelling around the world and meeting people with vision, hope and strength in all these places.\r\nSheep love that :)I compute how much cacao bean and cottage cheese a pastry shop owner should buy forward when selling chocolate brownies to cover the risk that customers decide they prefer cheesecake.4258frank3814Frank68611Bronx NYUSfrank38142006-05-15T13:16:24Zrisk manageri like the idea of having a direct impact on a local business and the updates on how this business is doingi'm advising an investment bank on the risk it takes when extending credit to governments, corporations and banks in various countries around the world111matthiasmatthias249901Allschwil CHCHmatthias2006-05-15T21:23:56ZI hope to make dreams come true ;) I`m a teacher at high schools - working with 12-17year old teanagers.301helen5837Helen300051St Clears CarmarthenshireGBhelen58372006-05-15T21:24:28ZHighway maintenanceI'm lucky enough to not have to worry about where the next meal is coming from. Well done to those who want to work for themselves and their families, no matter how hard their lives are.I work on computers all day, letting engineers know where there are defects on the road, lights out etc. It can sometimes be interesting :-)13deenaDeena586931Manchester NHUSdeena2006-05-15T22:17:35Zteacher/historian/student"The best charity is to prevent people from having to accept charity; the best alms are those that enable people to dispense alms" - The Talmud183elizabeth1543Elizabeth618861San Ramon CAUSelizabeth15432006-05-16T02:45:35ZContact Lens TechnicianI wish to share what I have been blessed with.I help design new contact lenses.12wmhaywoodWilliam3052931Baton Rouge LAUSwmhaywood2006-05-16T04:47:41ZStudentI hope for a better world, a better future.26robert4262Robert and Dorothy526911Menlo Park CAUSrobert42622006-05-16T15:54:26ZWe are blessed and we want to be a blessing to others in needinvestment manager91matt7354Matt & Amanda63361Tampa FLUSmatt73542006-05-16T17:33:17Zwww.mmdevents.comEvent DesignersWe have our own small business and we want to help people with their businesses around the world.3hangHangSan Francisco CAUShang2006-05-16T22:00:19Zwww.hangnguyen.orgEditor/Artistwe all need a little help to realize our dreams.7deborah4125Debby McConroe TXUSdeborah41252006-05-16T22:45:56Z5nybble41Nybble41Marion IAUSnybble412006-05-17T02:56:51Zsoftware engineer26benandsarahBen & Sarah17461Louisville KYUSbenandsarah2006-05-17T13:41:54ZSeminary StudentsWe came into the world with nothing, and we can\'t take anything with us when we leave. Moreover, giving to others is one small way of reflecting how our heavenly Father has given us so much.11joe2528JoeKingsley MIUSjoe25282006-05-17T18:32:47Z http://www.myspace.com/jmielkeIT ConsultingIt's easy to do from this site and it's nice to see people have success.8maymay1710541San Francisco CAmay2006-05-17T22:29:59Z6judeJude49361North Quincy MAUSjude2006-05-17T23:15:03Zwww.msh.orgICTS and international health.International health.125steven6501Steven62931Salem ORUSsteven65012006-05-18T00:22:55ZPharmacy TechnicianIt would be obscene for me not to loan money to these people.I assist the Pharmacist in preparing and dispensing prescription medications. 9jkeddieJeffrey2843821Seattle WAUSjkeddie2006-05-18T00:25:42ZLaw StudentKiva gives me the opportunity to donate the same money over and over again.Lots of reading.101helen3936Helen297191Toronto OntarioCAhelen39362006-05-18T03:09:31ZUniversity AdministratorI think that people in developing nations acting on their own self interest to improve their material conditions is the only chance to end the problem of severe poverty in the world. 10christophernutileChristopher Nutile4195741New York NYUSchristophernutile2006-05-18T04:34:20ZNew MediaI have the opportunity to.9012davidhDavid461761davidh2006-05-18T07:15:39Zdbhlim.orgTechnical Support EngineerI fix problems with computers5mrflipFlip154861Austin txUSmrflip2006-05-18T10:12:37Zinfochimps.orgIdea FarmerI'm building tools to help organize, explore and comprehend massive information streams -- a librarian for numbers, basically.151carolyn1253Carolyn762731Ashburn VAUScarolyn12532006-05-18T14:51:43ZRetiredI want to be involved in an excellent program.I am old now and no longer work but I have enough money to lend some to others.131taddeiniAndre Taddeini206771Minneapolis MNUStaddeini2006-05-18T17:07:25ZSoftware Developer18ilaILA133891San Jose CAUSila2006-05-18T19:03:52Z2thomas3536Tom, Margaret and kids96721Brooklyn NYUSthomas35362006-05-19T01:11:37ZNonprofit ActivistsIt\'s a good way to support people who are working to provide other people with goods and services in place where it is needed.I run a nonprofit organization that teaches computer classes to the elderly. My wife re-develops manufacturing buildings in New York to help create jobs that pay well.2rachaelcahoursRachael1097501Mount Morris MIUSrachaelcahours2006-05-19T20:52:31Zwww.antithete.comFreelance Web DesignerI want everyone to have the power to make good choices to change their lives and their families' lives for the better.I make the internet a better place.3anna1773Anna3078201anna17732006-05-19T21:48:20Zportfolio.du.edu/acorio5nate6590Natenate65902006-05-20T04:23:05Z3akenanA Kenan1214211Brooklyn NYUSakenan2006-05-20T05:08:58Zscreenprinter I feel good to be able to help someone in need, especially to assist a person in business. You never know how far the person will be able to excel , and we all need a hand at one time or anotherI print and sell t-shirts to individuals and businesses. I also sell t-shirts and other merchandise at various festivals throughout the year.212stephanie3179StephanieCambridge MAUSstephanie31792006-05-20T14:57:16ZStudent1ted9325Ted and RuthGlenwood Springs COUSted93252006-05-20T23:51:06ZTed - retired, Ruth - ski instructor, photographerWe believe that it is one of the best ways to make a difference in the lives of people in developing countries.32christopher8871HKtrader532671Hong KongHKchristopher88712006-05-21T07:57:45Zwell....sometimes people need some help478amaraAmaraSouth Paris MEUSamara2006-05-21T18:33:12ZStudent2patelSeema ~ Sahil ~ Annika584641San Francisco CAUSpatel2006-05-21T22:10:12ZWe loan because we love the idea of helping others help themselves. We loan *through Kiva* because it's easy, effective, and empowering for all parties involved!We ~heart~ Kiva...*sigh*259enzoEnzo2932971Celano AQITenzo2006-05-21T22:26:23ZTo help make the world a better place. 72saccaChristopher2854751San Francisco CAUSsacca2006-05-22T04:32:02Z10indiaI. R. Meisnerindia2006-05-22T17:46:37ZElectrical EngineerI know that the money is going directly to people who need it.Electrical Engineer9livingplanetlivingplanet172631Tucson AZUSlivingplanet2006-05-22T18:59:07Zlivingplanet.blogspot.comapplied anthropologistbecause everyone deserves a chanceapplied anthropologist33astrid3321AstridRedwood City CAUSastrid33212006-05-22T21:44:17Z12sonaliSonalisonali2006-05-23T06:13:09Z4kareemkareem59221Santa Monica CAUSkareem2006-05-23T06:54:22Zwww.reemer.comi want to help people help themselves, and i think entrepreneurs can make the world a better place.building websites5francoFrancoCHfranco2006-05-24T06:59:53Z6kris8725KrisUSkris87252006-05-24T21:00:54ZSoftware EngineerI was blessed to be born in a wealthy country, with lots of advantages. I want to help others who may not have been as fortunate.I write programs that run on computers.3timlkTimtimlk2006-05-27T20:17:29Zelizabeth6549BissyTakoma Park MDUSelizabeth65492006-05-27T21:03:15ZArt Teacher202gopal7949GopalBrampton OntarioCAgopal79492006-05-27T22:31:11Z2peter8265PeterHamburgDEpeter82652006-05-28T09:58:47ZJournalist4gloriaGloriaGuttenberg NJUSgloria2006-05-28T19:57:40Z15kestkestOakland CAUSkest2006-05-29T04:46:56Z111dinahDinah54251San Francisco CAUSdinah2006-05-29T20:44:05Zdinahsanders.comProductivity CoachIt\'s fun! I have my own business and I know how rewarding it is to follow your dreams.I help small businesses and individuals be more productive by having a better understanding of their priorities, goals, projects, and next steps.75michaelharrMichael Harr2153101Florence KYUSmichaelharr2006-05-30T05:43:14Zstores.lulu.com/mharr1Financial Consultant, AuthorI view microlending as a superior alternative to traditional charitable contributions. The money can in effect be recycled many times over to help a much larger number of people. In addition, with the favorable exchange rates, the value of a few dollars can be leveraged to have a greater human impact in these other countries than it does here in the United States.I help people make the best decisions possible with their money.6daniel8314Dan & Esther957181Palo Alto CAUSdaniel83142006-05-30T17:42:26ZWe believe in the power of commerce to solve problems.Internet executive specializing in payments and risk management.183denise5242DeniseSan Francisco CAUSdenise52422006-05-30T18:30:28ZI've had a lot of good fortune in my life, and I can share it with others28dennis5915Dennis1954351palo alto caUSdennis59152006-05-30T19:49:20ZDesign EngineerI am lucky to be able to do this. It is a great and inspiring thing to support entrepreneurs around the world.Designing products and services. 11trishaTrisha16771Huntington Beach CAUStrisha2006-05-31T00:37:52Zwww.teachoutsidethebox.comEducator/AuthorI love knowing that I am helping people who want to help themselves. I admire initiative and self-motivation! teacher and author of books for teachers67natalieNatalieAuckland AucklandNZnatalie2006-06-01T02:52:27ZAccountantI careGreat!112marc2288marcmarc22882006-06-01T08:12:22Z2techsamaritantech.samaritantechsamaritan2006-06-01T15:49:29Ztech-samaritan.orgEunuchs System AdministratorLoans not only help promote self sufficiency, they also promote responsibility and accountability. This contributes to a positive outlook for the borrower.I maintain large computer systems that provide the basis for many different University services.8endeavoringdavidDavid2163371New York NYUSendeavoringdavid2006-06-03T15:20:23Zwww.endeavor.orgNon-Profitproviding people with the opportunity to scale their businesses is the best way to alleviate poverty.I work with entrepreneurs in emerging economies by providing them with mentors, networks and access to capital. My work helps create Silicon Valleys in places like Bogota and Cairo.42sumeetSumeet16421San Jose CAUSsumeet2006-06-04T09:41:24ZSoftware Engineer10thomas7837thomas205791thomas78372006-06-04T14:08:20ZSTOCKBROKEREntrepreneurial initiative is a universal mechanism of empowerment. It is great to underwrite that empowerment for people who most deserve it.2lillyLilly Irani508341San Francisco CAUSlilly2006-06-05T08:00:37ZDesigner, grad studentTypically, it is those with money who have access to capital, spurring growing gaps between the haves-and-have-nots. I want those who have the desire and can bootstrap to have the chance to do so. I try to make computers and the internet useful and easy to use. I study how technology affects lives and societies.293mairtinMairtin O Muilleoir514041Belfast AntrimIEmairtin2006-06-05T22:41:38Zwww.apublishersblog.blogspot.comBusiness ownerEntrepreneurship is a vital part of conquering poverty in the developing world and because the Irish have always been treated with outstanding generosity by the global community when they were in need.I publish community newspapers.30sheeluSheel Mohnot36471Ahmedabad GujaratINsheelu2006-06-06T01:16:24Zwww.sheelm.com/blogKiva!I think it's amazing that we have the opportunity to create a direct connection with someone in the developing world... I have a little bit of money, and I love that I can give it to someone and help them out immensely, then GET IT BACK and give it to someone else.I work in India to develop Kiva's partnerships out here. It's really awesome - I'm learning a lot and having a total blast... If you're interested to know more about what I've been up to in India you can check out my personal blog, below73jaxonJaxon513591jaxon2006-06-06T02:17:54Zjaxonville.blogspot.comkidIt helps people in need.student121annandchrisAnn & ChrisNew York NYUSannandchris2006-06-06T02:29:34ZWe think everyone could use a "boost" now and then.14stephen5828Steve156101Worthing West SussexGBstephen58282006-06-06T11:31:03ZEveryone needs help sometime...29lee4705Lee1592131Mountain View CAUSlee47052006-06-06T22:15:58ZSoftware Engineer471corey3136Corey360171Philadelphia PAUScorey31362006-06-07T02:15:31ZTechnology ExecutiveI love the stories! Why not help someone achieve their dreams?!I help manage a technology services company located in Philadelphia.45ja9Janineja92006-06-07T02:20:31ZStudent31jane9973the avenue clothing co.jane99732006-06-07T17:48:22Z27m5300mark palermo2470981haverhill MAUSm53002006-06-08T18:20:19Zmarkpalermo.tripod.comteacher I want to give others a hand as others have done for me in life.instructor at a community college9mark2387Mark366711mark23872006-06-08T19:29:30ZAttorney at Lawit is a chance to share some of the blessings we have received and to provide opportunity to kindred souls whose geographic and economic situations are limiting....I also loan because it feels so good to do it and the personal connection created by Kiva makes it unique and satisfying.I work as a trial attorney representing people whose lives have been turned upside down due to negligent or reckless acts by others.1abbyAbby1230071abby2006-06-08T21:45:05ZHigh School StudentI enjoy the feeling of making a difference in the world.2stephen3515StephenReading BerkshireGBstephen35152006-06-11T07:06:59ZComputer Support20blueavocadoBlueAvocado2030841Austin TXUSblueavocado2006-06-13T12:01:36Zwww.blueavocado.comSocial EntrepreneurWe are a "for women by women" business inspired by the desire to provide sustainable solutions to protect our children's future. BlueAvocado hopes to inspire customers, vendors, and strategic partners in making the planet billions of pounds lighter (CO2) and giving back to hundreds of micro-entrepreneurs through its "Goodbye Carbon. Hello Karma program." BlueAvocado is dedicated to creating lifestyle products that help women (and the men in their lives) to reduce their carbon footprint by making it easy to “do good and get it done.†371william7588William Keyser15741Newfane VTUSwilliam75882006-06-13T15:56:30Zwww.worksavvy.bizbusiness startup counselorI believe that micropreneurs create their own futures and can make contributions to development beyond their own circle through energy devoted to helping themselves.I offer advice and support to would-be and early stage entrepreneurs. My website has a wealth of free information offered to anyone wanting to start a business.58hpsH.P.Del Mar CAUShps2006-06-13T19:07:06ZRetired33jeff9194jeffSan Francisco CAUSjeff91942006-06-13T21:49:21Z131jon4931jon kilimnik351471Winnipeg ManitobaCAjon49312006-06-14T04:35:10Zwww.jonkilimnikphotography.comphotographerTo help improve the lives of those less fortunate. 6joetateJoe Tate376141Lanoka Harbor NJUSjoetate2006-06-14T14:49:16Zwww.FaerieGlenNJ.comSmall Business OwnerI want to help small business to improve the world economy. I want to help the people who can help themselves.I sell Fantasy Art, Collectibles, & Clothing.23katie1509Katie152551Ohio/PennsylvaniaUSkatie15092006-06-14T22:03:39ZStudentI love and respect Kiva's entrepreneurs. Through the Kiva Fellows program I actually met some of the borrowers I lent to, and seeing firsthand how much they have accomplished with the loans was inspiring.I'm studying economics so hopefully I can work in microfinance some day soon!191paula7526Bill and PaulaTucson AZUSpaula75262006-06-15T07:52:48ZSoftware EngineersWe believe the micro loan to be one of the best ways to fight poverty in the world. It is a way to share our wealth by going directly to those who need help.We write computer software for our employer's company intranet.231SyrrysRob572311NZSyrrys2006-06-15T20:17:26Zsyrrys-in-nz.blogspot.comBackpackerI really hope that someone would be willing to take a the same kind of risk on me.Just traveling for the moment.42trevorhartleyTrevorPenrith CumbriaGBtrevorhartley2006-06-15T22:12:43Zwww.beammeupnowplease.com/Web site designerIn life I\'ve discovered that it\'s those small changes you make to other peoples lives that really make the difference, whether it be close friends or people 10,000 miles away. \r\n\r\n$50 - you can spend it on booze with your friends on a Friday night, or a romantic meal out with your other half, or helping someone start their own business to feed themselves and their family for years to come...\r\n\r\nAnd if that isn\'t enough, calling yourself a \"Part Time International Financier\" sounds rather cool down the pub. ;-) 33mary2616MaryIndio CAUSmary26162006-06-15T23:26:16ZAdministratorI believe it is a way - the best way - to help people who are willing to work to improve their lives.I work at a facility that helps alcoholics and drug addicts to get and stay sober. I am in charge of Administration.81will4664Will531801Brooklyn NYUSwill46642006-06-16T01:37:36Z6tabasioTabasioBerneCHtabasio2006-06-16T12:14:57Ztabasio.googlepages.com33hamonryanRyan45841los angeles CAUShamonryan2006-06-16T18:27:59Zwww.myspace.com/theblackcometsgentleman of leisurei can be completely drunk and still help people out!i work at a hollywood studio, run a stand-up comedy record label, play a lot of dodgeball, and sing in a band.571mike3620Mike509481San Diego CAUSmike36202006-06-16T20:56:43ZI am lucky, I can.22mollymollyPasadena CAUSmolly2006-06-17T18:08:46Z22gregg4935Gregg & Elaine Koskela62921Newberg ORUSgregg49352006-06-18T06:48:19Zgreggsgambles.comPastorAs followers of Jesus, we believe we need to help the poor in the world. Kiva is a great idea and service!I help lead a church in their desire to live for God through faith in Jesus Christ. 88alegraw2348Alegraw1300551alegraw23482006-06-18T09:20:57Z2john6477JohnHutchinson KSUSjohn64772006-06-18T19:34:43ZJournalist7ghostyTim3917551Vancouver BCCAghosty2006-06-19T09:25:30ZI truly enjoy helping people regardless of how cheesy that may sound. I totally love and champion what Kiva is doing because you're truly helping someone by providing them with the opportunity to help themselves. It's not just a simple handout, it's enabling someone to take that next step. It's giving someone the ability to achieve something. Equipping someone that has everything they need to get where they want...except the funds to do so. In addition to helping someone financially, this goes beyond that. It ultimately gives them a sense of pride and accomplishment, which is something we all need regardless of our situation.6john7492John Johnson1173861Newberg ORUSjohn74922006-06-20T00:06:42ZProfessorI want to help folks outI teach mathematics to undergraduate college students.261sean1083sean2613371Calgary AlbertaCAsean10832006-06-20T21:55:55ZSales103kathy6338KathyArlington TXUSkathy63382006-06-21T20:49:17Zcustomer service managerI feel this is one of the best ways to fight world poverty and insure a families ability to thrive and educate their children.Helping people solve problems for a food distribution company31eliFair Wage Coffee.com3627191Hillsboro ORUSeli2006-06-22T01:52:37Zwww.FairWageCoffee.comFairWageCoffee.comOne of our missions at Fair Wage Coffee.com is to improve the standard of living in the poorest of the poor through direct relationships, and not only trading fairly but paying a Fair Wage to indigenous coffee farmers.We purchase green coffee beans at a Fair Wage through direct relationships from some of the poorest regions of the coffee growing world. Then we roast our coffee to order. This way we provide a more socially responsible way for someone to purchase a great artisan coffee.11haighaighaig2006-06-22T06:26:24ZstudentI careComputer science1kevinrectorKevin Rector182721Wausau WIUSkevinrector2006-06-24T06:34:31Zwww.kevinrector.comPastorIt's a small thing that I can do to make the world a better place.42jose1648JLM1440591Pasadena CAUSjose16482006-06-24T07:50:53ZElectric System OperatorIt's the right thing to do!I coordinate the flows of electricity across high voltage transmission lines.121darinDarin42981Alexandria VAUSdarin2006-06-24T20:05:11ZUS GovernmentWe want to help those in need to help themselves and break the cycle of poverty for the next generation.77frank4813FrankFairfield CTUSfrank48132006-06-25T00:39:35ZI like to support people who are working hard to support themselves.30007John18771Kernersville NCUS0072006-06-27T00:21:00Zhttp://jwoodward007.blogspot.com/Textile QC Mgr.My son gave me a Kiva gift.I check our samples going to our customers for color, softness or firmness of hand, and several other parameters.5taylorTaylor96691LURAY VAUStaylor2006-06-27T01:22:07Zhttp://www.taylordavidson.com9ltgLTG1538361Brighton East SussexGBltg2006-06-27T08:20:04ZLearning TechnologiesThis fund was set up at the request of Gareth when he left the Learning Technologies Group (LTG) for the delights of Wales. We support and develop learning technologies at the University of Brighton, Sussex, UK.14fredyRobert SteinerBerneCHfredy2006-06-28T12:58:50Z30robert3968FamilyThrive.com244771Salinas CAUSrobert39682006-06-28T18:01:05ZFamilyThrive.comSocial EntrepreneurI amConsciousness Raiser2alifkhanAlif Khan3491511Brooklyn NYUSalifkhan2006-06-28T19:32:11ZSales Coordinator at Conductor, Inc.I simply love helping people! Weather its by making a donation, lending a hand, or providing insight and guidance, I'm there. I think KIVA is a phenomenal organization and I am glad to be apart of helping people less fortunate enhance their way of life.Alif’s years of experience in the Interactive space has led to a comprehensive knowledge of Internet technologies and business practices. Simply put, his desire is to utilize the new conversations the Internet presents to help others. An entrepreneur at heart, he made a commitment two and half years ago to Conductor, Inc. (formerly knows as LinkExperts) and has every intention of seeing it through. He stands for trust, integrity, and a unique no nonsense approach to achieving goals. Alif’s uncanny way of mentally compartmentalizing tasks at hand allows him to surpass milestones along the path to achieving his goals. Alif posses a tenacious demeanor of completing tasks, then moves on to the next objective. Along this path, he enjoys sharing his experiences with everyone. His unique style of teaching, allows others to call upon their own apprehension in order to solve problems. He is completely candid, stands true to what he believes in, promotes the causes he is passionate about, and always strives for the best. Alif is the quintessential critical first hire for any organization that wishes to be successful. 1772danzarrellaDan Zarrella55861Boston MAUSdanzarrella2006-06-30T14:11:44Zdanzarrella.comOnline MarketingI can't imagine a better way to help make the world a better place.I help small businesses compete against the big ones online.13marieMarie1729081Austin TexasUSmarie2006-06-30T21:31:13ZMarketingI want to empower entrepreneurs around the world.111roberto8636Roberto & Sarah525991San Francisco CAUSroberto86362006-06-30T22:52:54ZMarketing ConsultantsWe help businesses better understand their customers332joe6307JoeMurrysville PAUSjoe63072006-07-01T01:58:12Zhttp://www.joegallo.org/ConsultantThis is a very personal way to help people. Rather than giving some money to a charity which will help many people a little, I am able to make a big difference for just one person. I like that.I teach people how to program computers.47richard4711RichardAustin TexasUSrichard47112006-07-01T13:02:04Zentrepreneura little help can make a big difference11jesus8410Jesus Abad238721Cordoba CordobaESjesus84102006-07-01T19:19:26Zque-cosas.blogspot.com/30fred6449FredNiskayuna NYUSfred64492006-07-01T21:28:27ZSoftware Designer, retiredI like to learn about people in other parts of the world, and help them if I can.I have helped companies use computers to make their business run better.151phil6554Phil637311Wellington North Islandphil65542006-07-02T03:17:51Zphil.cockfield.netDesignerI design computer software - the part of the software that relates to people.3john6075John120331Newton IowaUSjohn60752006-07-02T20:49:43Zdot5baked.blogspot.com/Project ManagerWe all should be able to fully participate in the benefits of free enterprise.I work with people to develop new computer systems.641lemminglemming119291Somerville MAUSlemming2006-07-02T21:35:43ZSoftware EngineerI want to be active in the world.I work with computers. My company works commercially by selling advertisements, and it also has a social mission of organizing the world's information so that people can learn whatever they want.765jan3399JanSeattle WAUSjan33992006-07-03T02:31:39ZengineeringThe internet will change the world.13cyrilCyrilBenicia CAUScyril2006-07-03T05:28:43ZI am first a citizen of the world and second of the country where I was born.4john6002John243181AmsterdamNLjohn60022006-07-03T06:48:56Zwww.bidnetwork.org/johnvanduursenbusiness in development pioneeri want to learn see www.bidnetwork.org 3engcherEngCher42971Singapore SingaporeSGengcher2006-07-03T06:57:50Zthemis-euterpe.livejournal.com/LawyerThe money sitting in the bank doesn't earn sufficient interest to cover inflation anyway, might as well use it to do something worthwhile!I advise on how to save on those pesky payments you have to make to the government without you getting into trouble - or too much! 12julia7600Julia679061Portland MEUSjulia76002006-07-03T11:27:25ZI've always wanted to be a philanthropist. Too bad I lack the means. I can easily participate in microfinance, however. I get a real kick out of spreading good will and dollars around in this way!24epilandScottBoston MAUSepiland2006-07-03T16:27:40ZEpidemiologistStudy of disease as well as work on surveillance for the state of Massachusetts20teresa2062Teresa25461Silver Spring MDUSteresa20622006-07-03T16:31:16Zflickr.com/photos/terrymct/ScientistI have been lucky enough to have good people help me in my life and I\'d like to return the favor.I am a scientist who works with the plants and animals living in coastal waters, trying to protect the habitats and restore them to their previous functions.14rick345Rick621301Mount Airy MDUSrick3452006-07-03T16:47:28ZWebsite Owner and Technical AdvisorIt's a great feeling to be able to help someone in need and I love seeing the Kiva success stories! I own and manage a website and I am also a Technical Advisor to a program that assists small businesses in the U.S.A., so helping small businesses in other countries through Kiva.org is a perfect fit!55marshaMarsha59301marsha2006-07-03T21:49:52ZGovernment employeeI am fortunate enough to be able to.I work on building and testing a software system.2elliotElliot4616841Belleville NJUSelliot2006-07-03T23:34:59Zsales - vitaminsI think it\'s a great idea of giving small loans to people who will turn this into a business. It gives somebody else a chance with just a small amount of money. I presently work in a store which sell endless amounts of different vitamins. I believe vitamins are one of the most cost effective ways to maintain one's health. 56carl9232Carl3054051Canton GAUScarl92322006-07-04T03:19:59ZBusiness Consultant1265judy2698Judy948621judy26982006-07-04T04:20:12ZLicensed Professional Counselor3georgiaGeorgia403551Garfield NJUSgeorgia2006-07-05T17:23:53ZTeacher's AideI can't do much to change the world. But I can do this.I work with pre-schoolers, 3-5 years old.33james9559James659801Redmond ORUSjames95592006-07-06T01:10:40ZwriterI want to helpMy work is bringing people together, looking to a better future for us all through learning to communicate and work together, whatever our 'differences'61patrick8748PatrickPrincetonUSpatrick87482006-07-06T21:05:51Z29chrisjChris J931451Seattle WAUSchrisj2006-07-07T08:04:23Z16deannaDeannaSeattle WAUSdeanna2006-07-07T08:09:04Z61tasavirtatasavirtaEspooFItasavirta2006-07-08T07:45:51Z23nandaSUMANA KISHOREValley Glen CAUSnanda2006-07-08T23:36:52ZManagerI am proud and grateful that I have a nice job, pretty girlfriend and I wish and hope that all of us deserve the same. Helping the people in our company do their jobs better and get the projects done within their budget, before the deadlines - no matter what it takes.6euan3253Euan3772431Hebden Bridge West YorkshireGBeuan32532006-07-09T09:58:36Zwww.eubielicious.comWeb ConsultantI care about supporting trade in developing nations and believe that access to affordable credit is vital to these small businesses.I help people to understand the Internet, and how it can help their business develop. I also am able to create an enjoyable, intuitive website for them.11adamjsorensenAdamJohannesburgZAadamjsorensen2006-07-09T16:19:23ZMicrofinance consultantI believe in opportunity.'Operationalizing microfinance' in Africa.orenOrenStanford CAAForen2006-07-10T00:50:35ZStudent/Teacher/Tree HuggerI want to support those who are working their way to a better livelihood41tim7293TimCAMBRIDGE CambridgeshireGBtim72932006-07-11T00:42:00Z151sharatSharatVenice CAUSsharat2006-07-11T06:52:20ZFilmmakerBecause I canI write, direct, and produce movies and television.13prakaruArun58241Austin TXUSprakaru2006-07-11T06:55:59Zwww.virgocapital.comPrivate Equityentrepreneurship is awesome at all levelsWe invest capital in small firms and help their leaders grow the businesses, eventually selling them in order to reap the rewards of hard work and risk taking.8santhoshSanthosh1842531chicago ILUSsanthosh2006-07-11T07:36:09ZPhysicianI would want someone to help me out if tables were turned and it's the right thing to do.I treat and heal the sick and elderly.8canrocksCanrocks98281Russell OntarioCAcanrocks2006-07-11T22:42:31ZStudentit\'s the easiest way for me to contribute to sustainable development in the Global South. \r\nTranslation: I\'m doing something fantastic with my money and all it\'s costing me is inflation.I am studying to one day become an urban planner. I would decide where to put roads, houses, businesses, and trains in a city so that it works as well as possible.191matt3925MattLos Angeles CAUSmatt39252006-07-12T06:10:49ZReal Estate consulting4patrick6647PatrickBoise IDUSpatrick66472006-07-12T06:31:48Z6lynn5996Lynn Sharrock3983261Ann Arbor MIUSlynn59962006-07-12T11:55:39ZRegistered NurseI can! I work with children in a psychiatric hospital at a university.35giacomoGiacomo322081Los Angeles CAUSgiacomo2006-07-12T15:05:53ZI'd like to support small family-run businesses. I grew up in a family business environment, and learned a great deal from it, and I'd like to see others benefit from that same type of experience. I work in International product management for web services. 13helen6259HelenBanda AcehIDhelen62592006-07-12T23:15:54ZNGO49david3655Daviddavid36552006-07-13T03:38:26Zandy5040Andy3992101Lafayette CAUSandy50402006-07-13T05:22:01Zwww.facebook.com/p/Andy_Smith/873835439Technology MarketingI believe in helping people help themselves.I help my company describe its products clearly and persuasively, and make things that people want.294AJJAJJNorth Palm Beach FLUSAJJ2006-07-13T06:36:28Z293kmfKevin1112581San Francisco CAUSkmf2006-07-13T16:21:01Zsprawlwall.blogspot.comSpirited Strategisti can. my profile picture is a telling depiction of why i can... i could forego a couple of the beers i probably spilled on the ground anway and instead route this money directly to an entrepreneur in need.i help people find a new place to live.1010heidi1821Heidi73631Chicago ILUSheidi18212006-07-14T14:51:42ZAccount ManagerI care about bettering the lives of thirld-world country citizens. I lived in Ghana for two years and through lending, I feel a sense of connectedness to people like my friends in Ghana. I work for PLATO Learning, an educational software company. I manage existing accounts and create/sell to new accounts. It's not the most noble job but I'm gaining invaluable business experience and an income for a change. 17jancarelJan CarelRotterdamNLjancarel2006-07-14T21:20:16Zwww.d4s-de.orgI became involved in a research project with Kiva, see www.intocontext.orgI am a researcher in the field of Design for Sustainability261mortenMorten3666291morten2006-07-14T22:45:17Zwww.wasab.dk/morten/142kristin1391KristinLondonGBkristin13912006-07-14T23:29:43Za little goes a long way here11lunalunaLunaLuna49381MECHELENBElunaluna2006-07-15T08:12:52Zwww.lunaluna.beBed and BreakfastWe want to improve the world.We have a micro Bed and Breakfast in Mechelen, Belgium.671alejandraAlejandra3408971Zaragoza ZaragozaESalejandra2006-07-15T21:54:07Z20larry5537Larry Coleman2237591Avon OHUSlarry55372006-07-16T06:50:33Zwww.facebook.com/people/Larry-Michael-Coleman/1018955073Computer technician$1 to me is like $100 to someone who really needs it.I fix computers for a midsize hospital.551josearochaJose Arocha118541Palo Alto CAUSjosearocha2006-07-17T08:00:31Zwww.josearocha.comInnovator, Internet Geek, Product Manager.There are many hardworking people in the developing world who could make significant contributions to themselves, their families and their communities have they had some financial support. I just want to help through Kiva so my insignificant contribution can be pooled and become significant to at least one of them across the world.I help people exchange in the internet the same way we exchange in a farmer's market.3heidi6932Heidi374781Renton WAUSheidi69322006-07-17T16:24:03Zmusingsofaredlettergirl.blogspot.comSchool AdministratorI love the micro-lending concept and would like to dream of ways to do this in my church, community, workplace and throughout the US. I work at a Christian School. We help provide a Christ-centered education to anyone that wants it-even if they can't pay. 252sandra3483SandraBrier WAUSsandra34832006-07-17T16:27:54ZHospice Nurse9connie7753Tony & Connie3224551Bothell WAUSconnie77532006-07-17T20:23:58ZKIVA member loans increase opportunity for growth and security of small business owners. 10john7665Johnjohn76652006-07-18T06:02:20Zsoftware developerI like seeing how different and similar our lives are across the world.I write CRM (communication) software for retailers.5colleen8639Colleen210761Clinton OHUScolleen86392006-07-18T12:57:53ZUnit ClerkI have always been very independent and worked hard to make my own way. I admire others trying to do the same and under much harder circumstances. If I can help even a little, that's great! I work as a secertary on a Nursing Unit at a very large and busy Hospital. We deliver Babies!111heather1846Harmless15681Cincinnati OHUSheather18462006-07-18T13:00:59ZTeacherI like knowing that what I lend can really affect someone\'s life- even if it\'s an amount that would just barely buy me dinner.I really believe in the American public school system, where all our kids get to know each other- poor and rich, black and white, gay and straight, of all religions and nationalities and points of view. I think that America\'s diversity is what makes the country strong, and that the public schools at their best nourish pride in our diversity.271miemieMiemie1847351Mililani HIUSmiemie2006-07-18T21:35:00ZProfessorI want to help.Professor31julia9701Julia523651Boston MAUSjulia97012006-07-20T16:41:42ZFair Trade banana company34rowanRowanLondon LondonGBrowan2006-07-21T15:11:41ZI had some money sitting in my Paypal account and this seemed like a good use for it...7myraMyra and Beau529531Whitefish MTUSmyra2006-07-21T16:57:21ZCPAI am so blessed in my life, I feel compelled to share my blessings with other. I am the American equivalent of a Chartered Accountant - I prepare and review financial statements, and prepare tax returns.453karen7157Karen HansenStudio City CAUSkaren71572006-07-21T22:03:23Z8alfred5323Alfred209701Lasberg OOeATalfred53232006-07-21T22:03:29Z46timothy2398Timosha78241Falls Church VAUStimothy23982006-07-21T22:29:35Zchocolate makerEveryone should have some sweetness in their life. I bring people happiness via their stomach.23neil650NeilMenlo Park CAUSneil6502006-07-22T02:28:17Z8darryl7692Darryl1280141Charlotte NCUSdarryl76922006-07-22T09:23:28Z7alexandre6630AlexandreVirginia Beach VAUSalexandre66302006-07-22T11:34:27Z23mankinenBrian & Veronica79711Hermosa Beach CAUSmankinen2006-07-22T15:45:12Z503vitalphotographyvitalphotographyAustin TXUSvitalphotography2006-07-22T15:49:47Zwww.vitalphotography.netwriter, photographerI want to help, but donating to large organizations, while important, is less personal. I don't know where the money goes or how it helps individual people. With Kiva, I know I made a difference.I photograph people and places. I like seeing old things in a new way, but I also love to explore new places. I write fiction (mostly speculative fiction, aka sci-fi), as well as magazine articles.20dan8067dan576811San Diego CAUSdan80672006-07-22T17:28:56ZGaslampphoto.comowner photo labIt's thrilling to see a small amount of money make a big differenceI own and operate a small photo lab that caters to wedding & portrait phototographers4anna3462Anna509131New York NYUSanna34622006-07-22T18:11:12ZMBA StudentI believe that microfinance allows people to be self-sufficient and to lift themselves and their communities up from poverty through hard work, determination, and a little help from friends.I read books, take tests, apply for jobs, and party. :-P151jason5574Wright FamilyEscondido CAUSjason55742006-07-22T19:44:08Z34gary6341Gary71561Upstate NYUSgary63412006-07-22T20:35:46ZProfessorThose of us born to a middle class family in the U.S. are very fortunate. I simply wish to give something back.30laurie6973laurie2041121mill valley CAUSlaurie69732006-07-22T20:42:07Z37normanIrinaCulver City CAUSnorman2006-07-22T21:53:12ZHome Designer/BuilderI want other people to suceed and feel they just need a little help getting started. People should be able to enjoy life and the fruits of it's bounties.I am a home Architect/Designer that works helping people realize their dreams.13rspRSPChicago ILUSrsp2006-07-22T22:05:09Z20IndyYoungsIndy Youngs528421Indianapolis INUSIndyYoungs2006-07-22T23:55:47ZCPA & AttorneyCapital is needed around the world to provide opportunity to turn a profit into more capital. Government aid is inferior to the human and intellectual capital unleashed through the opportunities provided through the medium of financing.As a CPA, I help people count what they have, understand who they owe, and help develop their financial plans to meet their various needs in the future. As an attorney, I help manage the legal responsibilities of a company.7kerrenKerrenClever MOUSkerren2006-07-23T00:36:32ZI love the opportunity to help (mostly) women become independent and successful.31nicholas7697Nicholas1964421Yardley PAUSnicholas76972006-07-23T04:08:56ZDirector33investorbloggerinvestorblogger362341Tamsui Town Taipei CountyTWinvestorblogger2006-07-23T04:41:07Zinvestorblogger.comInvestorBloggerBecause my loan enables others to have the same chances I had. Exciting, challenging, tiring, frustrating, but rewarding, too!4joseph8481JosephPittsburgh PAUSjoseph84812006-07-23T13:12:48ZGrad StudentEven though I\\\'m not rich, I got more than these people do. It would be very selfish not to share a little bit of what I have knowing how much of an impact it can have on their lives.19erichErich211581Rye NYUSerich2006-07-23T14:42:20ZGen. Mgr. Strategyall of us can make a difference and with Kiva I see directly whom I try to help. My daughters help me select the businesses and we follow their progress with great interest.I am responsible for the Strategy of a big IT company at worldwide level1322annwAnn W.856511Boston MAUSannw2006-07-23T15:03:15Zwww.aquent.comGeneral ManagerI want to invest in women who are starting a small business or expanding their existing small business.I'm a manager at Aquent. We help find contract opportunites for marketing and design professionals at Fortune 500 companies as well as small and mid-size companies.32ramRam477061FaridabadINram2006-07-23T15:03:40ZITThis is a painless way to make a real difference.10david4913David150161San Francisco CAUSdavid49132006-07-23T15:48:25ZMaker of neat thingsIt\'s exciting to be able to loan directly to a single person who has an idea and needs a little capital to make it real.I invent and build new technologies that help people do things easier, faster, or more creatively.7christopher5777Christopher299741christopher57772006-07-23T16:21:11ZPark RangerI find myself at a place in life where I have a little extra money. I lead a great life. I have always wanted to be an entrepreneur, but I am currently locked into a career that I'm unwilling to let go of, so I thought the next best thing would be to support entrepreneurs who don't have life as good as I do.I am a park ranger for the United States National Park Service and I work every day to preserve and protect America's most important natural, cultural, and historical resources for our generation and for the people of the future.steven3062StevenSeattle WAUSsteven30622006-07-23T16:50:28ZMental Health CounselorI believe it is my moral imperative. I help people who have experienced trauma or psychological pain. 3ted8767Ted381571Saint Louis MissouriUSted87672006-07-23T18:14:47Zwww.tedfischer.blogspot.comSoon to be Peace Corps VolunteerI wanted a direct and effective way of assisting those working to improve their lives.world wanderer who does a bit of volunteer work here and there.161issyIssy520151Issaquah WAUSissy2006-07-23T18:15:37Z5edinaEdina3903721Flushing MIUSedina2006-07-23T18:17:13ZStudent5abbeyAbbey193671St. Louis Park MNUSabbey2006-07-23T20:00:57Zwww.myspace.com/abssullySystems EngineerIts a small way that I can be a part of helping others around the world.6paul2593Paul38791Augusta GAUSpaul25932006-07-23T20:59:06ZProject ManagerI like to be able to help people in places around the world.I am a church musician, a scientist, and have made missionary trips to Jamaica (that is my friend Keno at the Westhaven Orphanage in Copse in the photo).100arezouArezou & Evan4165591Woodstock ILUSarezou2006-07-23T21:15:24Z16simon8795Simon199721Long Grove ILUSsimon87952006-07-23T21:25:45ZI like to see how people are improving their own and families lives. If I can help in a small way then I get a lot of pleasure of out it.29barry2202Barry112291Portland MEUSbarry22022006-07-24T03:26:54Zwww.caravanbeads.netBusiness OwnerMy son and I loan together. I was a Peace Corps volunteer in Senegal from 1970-1973. Supporting Kiva is a small repayment for all that I learned while living in West Africa for three years.We import beads, mostly from Japan, and sell them to retail bead stores, designers, and jewelry manufacturers all over the world.802gregorioGregorioWalnut CAUSgregorio2006-07-24T07:56:13Z19robert1871Robert1685501London LondonGBrobert18712006-07-24T08:26:18ZlawyerI believe micro finance loans are the best way of contributing to the economy of developing countriesI am a lawyer working in the electronic payments industry. I have previously worked as a consultant in micro-finance.8kurt3704Kurt114821Nashville TNUSkurt37042006-07-24T13:24:07ZSr. MIS Program ManagerI have been blessed with a comfortable life, and most of the people receiving these loans have a harder life than I can even fathom. I would hope I would be a recipient of a loan if I were in their situation.I manage a team of individuals who work on computer software.37arienneArienne1997811Los Angeles CAUSarienne2006-07-24T16:46:08Zbecause my $25 can make a big difference361patricia2955Patricia3092391barrington NHUSpatricia29552006-07-24T16:58:09ZAnimal Control Officer 34stefan2405Stefan & EmilyWeed CAUSstefan24052006-07-24T17:47:58Z571annmarieAnnMarieWindham MEUSannmarie2006-07-24T20:13:59Zhttp://am.paulukonisstudio.com/Instructional Technology DeveloperI have been fascinated with microlending since reading about the Grameen bank in college. I was thrilled to find out that I could personally participate.I help faculty at a university how to put course materials online. I teach them how to use the software, provide technical support, and guide them in creating new and better ways to teach using technology.23robert1065Robert209421Charlotte NCUSrobert10652006-07-24T22:56:07ZBankerA dream will always be just a dream without the tenacity to go after it and the money to get it started.I analyze medium sized US businesses to determine if the bank should lend money to them.1nicholas8469Trumptman702421Beaumont CAUSnicholas84692006-07-24T23:22:26Zelgallocrows.comteacherI can.I attempt to help people see past the end of their own nose.31andrewjanisAndrew965771andrewjanis2006-07-25T00:14:45Zandrewjanis.com321chuckerSören52611chucker2006-07-25T00:59:12Zchucker.me/Software developerIt simply helps make the world a better place, and what could possibly be greater than that?I mainly develop computer programs, and give tech support to individuals and organizations that use computers.17celina1854celina496981celina18542006-07-25T01:07:10Z2elias7648Elias Marenco3589991Guttenberg NJUSelias76482006-07-25T04:11:46ZTax ProfessionalIt empowers people to better themselves and not some multi million dollar corporation.Tax Consulting16edward3188Edward1492461Morton Grove ILUSedward31882006-07-25T12:37:52ZRetiredI want to give back for the advantages I've enjoyed.Enjoying volunteering, hobbies, and travel.49sunil1552Sunil and Shweta367451Toronto OntarioCAsunil15522006-07-25T14:52:27ZBankerI know how timely infusion of money can help small business. I lend money to Small Business owners.(Business Banker)8tarekTarek3835971Flower Mound TXUStarek2006-07-25T14:57:49Ztarek.hoteit.org3peter1615PeterHouston TXUSpeter16152006-07-25T15:22:52ZatttorneyI want to help people help themselves.31james7459James555691Ottawa OntarioCAjames74592006-07-25T15:48:45ZHigh Tech19william3296Will110021Arvada COUSwilliam32962006-07-25T17:26:20ZConsultant401matthew1775MattDayton OHUSmatthew17752006-07-25T18:05:44Z14tanujTanuj917391New York NYUStanuj2006-07-25T19:43:18Zfellowsblog.kiva.org/category/all/tanuj-parikh/Project Manager | NYC Economic Development CorpMaking direct connections and loans to people in an unbelievably powerful way to empower them to better thier lives. Loaning through Kiva is one small way I can be a part of that process.52peter4729Peter112921New York NYUSpeter47292006-07-25T20:31:15Zwww.PeterLouisSalon.comEntrepreneurI Can! People who really work hard and want to succeed should be helped!I spend my day looking for investment opportunities, Selling Hair Products in the USA and Cutting Hair is my favorite skill. I also like to travel, drive fast cars and have fun in New York City. http://www.peterlouis.blogspot.com25brian9803BrianAnn Arbor MIUSbrian98032006-07-25T21:49:03ZCEOI\'m an American, I\'m a progressive, I\'m of Ecuadorian decent, and this is better than giving to some pseudo-corporate NGOI own an internet business.21dawn8628MishiesmomBattle Ground WAUSdawn86282006-07-25T21:51:56Zreceiving clerkI can and where else can so little money do so much good. 36christian9832Christian195741Washington DCUSchristian98322006-07-25T22:35:43ZConsultantI want to give back, and I love Kiva's model. I have been using the site for over a year , and have just been overwhelmed by the great work it allows me to share in.I advise Fortune 500 executives on how to improve their company's IT performance.5879stephanie4126StephanieSan Francisco CAUSstephanie41262006-07-26T02:33:48Z23wilfred8211wilfredscarborough North YorkshireGBwilfred82112006-07-26T08:57:37Zpschool.comhypnotistI believe in private enterprise..I do not want politicians to give tax money to dictators to build palaces for themselves..started supermarts ran a pirate radio ship to help break the BBC monopoly, now teach hypnotherapists was in thr British Parliament for 8 years .. as a Conmservative ,with Margaret Thatcher2paulosepaulosekottayam keralaINpaulose2006-07-26T09:17:40Zpaulosev.blogspot.comBusinessI would like to help people improve themselves through their own effort and hard work.Maker of Automobile Tyre Retreading Material122thesmithsThe Smiths2134091GlasgowGBthesmiths2006-07-26T09:33:59ZEducationWe both work in education. My wife is a primary teacher and I am a manager in local government.65eric1269EricWyoming MIUSeric12692006-07-26T13:33:42Zwww.ericscc.comSoftware EngineerI like the idea of peer-to-peer lending and have been involved in Prosper.com (a for-profit p2p lending site) for a while now. I feel like Kiva is a way to make a little money go a long way for others around the worldI write computer software and create websites for companies. I also have a statistics website related to Prosper.com that I run as a hobby.2ashish4482Ashish2151031Ashburn VAUSashish44822006-07-26T15:08:44ZI want to encourage entrepreneurial activity in the hope to enable sincere and willing folks to generate a sustainable cash flow to better their lives.my work energizes my intellect and affords me the ability to assist someone in this borderless world to realize their dreams.1311ebereEbere445551Houston TXUSebere2006-07-26T16:01:33ZEngineerI love the Kiva slogan - changing the world, one loan at a time80lisa1799Lisa870931Cambridge MAUSlisa17992006-07-26T18:51:43Z9phyllisPhyllisNorth CarolinaUSphyllis2006-07-26T18:56:03ZSubstitute TeacherI enjoy helping people2pamela2892Pamelamatteson ILUSpamela28922006-07-26T20:31:39ZSocial Worker with small children and their families.3jfmccoyJim214651jfmccoy2006-07-26T20:33:55ZConsultantI hope to be able to give someone the chance I had to build and grow my own business.I lead a consulting organization that specializes in Talent Management. We help organizations plan, acquire and develop talent to enable them to succeed in their business mission.70betsy5536Betsy191451Philadelphia PAUSbetsy55362006-07-26T20:44:52Zwww.moneychangesthings.blogspot.comartistI have been blessed to be a successful self-employed woman, and am thrilled to pass the good karma forward.I am a scribe and illustrator.1310pederPeder469411East Palo Alto CAUSpeder2006-07-27T04:31:26ZEntrepreneurI wish to help others fulfill their dreams as others have helped me fulfill mine. I work with education. 41julie1098Julie210221Los Angeles CAUSjulie10982006-07-27T06:13:28Zwww.julietan.comMusician MomIt's the least I can doMusician, mom, fair trade marketeer for Novica.com111miamia4222211LondonGBmia2006-07-27T08:43:18ZEntrepreneurWe are all one :)I run a creative technology company.33laurie7742LaurieSouth Dennis MAUSlaurie77422006-07-27T13:49:38ZLeadership Development ConsultantAnyone who is willing to try deserves support from the rest of us: "Start where you are, Use what you have, Do what you can."Helping individuals and organizations be effective and successful10adamwinsAdam Bourque2968641Killeen TXUSadamwins2006-07-27T17:00:00ZGovernmentI have a desire to bless others with opportunities that they may not otherwise have. 211drew9203Drew342351Richardson TXUSdrew92032006-07-27T17:04:25ZAnalystI want to make a differenceI solve business problems with computers38maxandMax and LynnieBrunswick MEUSmaxand2006-07-27T19:18:31Zwe believe everyone should have the opportunity to make a better life for themself26erik6964Erik1694301Kansas City MOUSerik69642006-07-27T19:59:08Zwww.park.edu/icceUniversity AdministratorI care81clocsenOwen2031691Chester .GBclocsen2006-07-27T21:16:59Zowenwatkins.comI believe it's a very effective use of my money to help people in situations not as lucky as me to achieve their goals.24sanjayparekhSanjay Parekh517351Duluth GAUSsanjayparekh2006-07-27T23:31:08Zwww.sanjayparekh.comEntrepreneur36ralph8242RalphLivingston TXUSralph82422006-07-28T00:55:52Z375drew6631Drew3429051Culver City CAUSdrew66312006-07-28T01:36:10ZAudio EngineerI'm fortunate enough to be able to help others through Kiva.org.I'm an audio engineer and I work at a film studio in Los Angeles editing and mixing audio for television and film.57steven8776STEVENGLADWYNE PAUSsteven87762006-07-28T12:38:54ZInvestorBecause its the right thing to do.22mary1690Mary471081Somerville MAUSmary16902006-07-28T13:30:40Zentrepreneur (US)Everyone deserves a chance. And as a woman entrepreneur, I have a soft spot in my heart for women with great ideas, ambition, and a desire to serve their community.I teach people how to use software to analyze the human genome data. 21myronMyron2353961Miami FLUSmyron2006-07-28T13:54:41Zlawyerit makes me feel good inside and it helps othersRETIRED INTERNATIONAL LAWYER491ishmealIsraelAshaland VAUSishmeal2006-07-28T14:11:33ZAccountantIts always good to bless one another in need.Someone who control and protect someone elses money or investment. He purchase things for them and pays their bills including their taxes.selltoeuropeselltoeurope25061Brooklyn NYUSselltoeurope2006-07-28T14:31:15Zwww.selltoeurope.comIT...I think it is necessary to help at least one other person in your life on a permanent period. I currently work as an IT director and my ultimate goal is to grow my own company, which hopefully will be able to give large sums to companies in the third world. Kiva is a good and easy way to achieve this goal.10jack8373Jack184551Newport Beach CAUSjack83732006-07-28T15:23:33ZPeripheral VisionaryI think this site is an amazing idea.533edwinEdwinNorfolk VAUSedwin2006-07-28T15:40:57ZContracting Business Owner9joleneJolene2726471Houston TXUSjolene2006-07-28T17:07:47ZWaitressIt has always bothered me that here, we have so much and in other places people have so little. Ever since I was a child I wished there was a more easy and simplified way to help people that i could actually take part in and now there is!I work in a restaurant serving food and drinks to customers in Texas. I live off of tips. 31barakBarakSan Francisco CAUSbarak2006-07-29T00:56:58Zwww.rassak.comMarketerI help grow companies by making sure customers understand them, know about them and want to do business with them2charlene3200Charlene201051Jackson Hole WYUScharlene32002006-07-29T01:51:34Zwww.andersonshea.comArtist, writer, designer, traveler, athlete, geekI have been fortunate enough to travel to over 100 countries. What I remember most about the places I have visited is the people. Through Kiva, in my own small way, I can help people who have enriched my life so much. The feeling I get when I make a loan to someone that cannot be described. I feel warm, happy, peaceful, and honored to be able to help others.I design jewelry, clothing, textiles and other artwork, I also write about it in magazines and books and sell supplies, tools, and equipment to artists and craftspeople. I try to buy many of my products from artisans in third-world countries, such as beads from Uganda, Togo, Mali and India and fabrics from Ghana and Togo.491basdebeerBas de Beer172031muiderberg Noord-HollandNLbasdebeer2006-07-29T09:53:03Zcrm consultant at a bankIts a good thing 166stephen2100SteveSandy Hook CTUSstephen21002006-07-29T12:52:18ZIt is important to improve the economies of countries around the globe and small businesses drive the most growth and make the biggest difference in people\'s lives.I work for a company that manufactures and services computers.101joyce5961LindyKalamazoo MIjoyce59612006-07-29T12:57:34Z4john5951JohnQueen Creek AZUSjohn59512006-07-29T14:06:01ZI believe that if you give a man a fish you feed him for a day but if you give him a fishing rod you feed him for life.291ignacioIgnacio207481Barcelona BarcelonaESignacio2006-07-29T14:49:06ZExecutiveIt is nice to be able to give back. I like also to promote the use of web-enabled social networks to change the world. 262marie8325The Powell'sIndianapolis INUSmarie83252006-07-29T15:42:51Z19dankoifmanDan Koifman171941Brooklyn NYUSdankoifman2006-07-29T16:46:18Zwww.dankoifman.comConsultant and Trainer25 dollars in New York pays for 5 lattes. Put into the hands of an entrepreneur with no access to credit, it can develop their business and change their lives. One person can't change the world, but they can make a difference by being there to help one person at a time. Lather, rinse and repeat.I am do-gooder with a spreadsheet. A marketing and communications consultant to small businesses and non-profits, as well as a speaker and trainer. In the past, I managed the Bank of America Youth Entrepreneur Program, which helped train almost 3,000 NYC HS students to think like an entrepreneur.4justin9519Justin D1099601San Francisco CAUSjustin95192006-07-29T18:09:47ZI want to help those who have been less fortunate121umangUmang92381umang2006-07-29T18:42:37ZManagement ConsultantI believe in the power of micro-lending to help those with less opportunityI help organizations increase the efficiency (often through automation) of their processes (everything from payroll processing to manufacturing widgets).3walter9027ValConcord NHUSwalter90272006-07-29T19:07:49Zwww.zanchuk.comManufacturer - Consultant - EngineerI believe people respond best to help, not a hand out. My company makes parts for other companies from all over the world.81forrest8486FJay186261Grantville PAUSforrest84862006-07-29T19:35:48ZSemi-retiredI want to lend because others have given to me.I am a part-time school teacher for disadvantaged children.16jonJonMelbourne VictoriaAUjon2006-07-29T22:48:35ZinvestorI receive so much every day that I am inspired to give just as much to others to balance things out.46richard2206Richard236271Meridian IDUSrichard22062006-07-30T01:49:44ZRetiredTo help other peopleRetired Engineer and Manager37david3115David3219221High Point (aka Heaven) NCUSdavid31152006-07-30T04:21:25ZSeeking justicein the end the love you take is equal to the love you make.68darianDarian287351Pasadena CAUSdarian2006-07-30T05:26:09Zhttp://www.villagethegame.comEntrepreneurthis kinda lending is one of the most effective and simple ways of helping those in poverty.We're producing a video game to get people addicted to third world development called Village the Game.12caseyCasey1571961San Francisco CAUScasey2006-07-30T05:37:49ZProduct Manager, Kiva151paddyPaddy31121Ulverston Cumbria - EnglandGBpaddy2006-07-30T06:46:26Zwww.outdoorwriter.freeserve.co.ukOutdoor WriterI can see that it makes a difference, and I know how much a little help means to a small business. A little of my money goes a very long way with Kiva.I travel to places where I can explore on foot, taking notes and photographs so that I can write and illustrate guidebooks and magazine articles.423jeremiahJeremiah237611Houston TXUSjeremiah2006-07-30T15:56:52ZEngineer2061worldwideWWEXSA3133861San Antonio TXUSworldwide2006-07-30T16:50:50ZI do not have a car so I really do not have any other way to spend my allowance!31brockBrock and Diana549971Fair Oaks CAUSbrock2006-07-30T17:27:17Z23ryan4432RyanFort Wayne INUSryan44322006-07-30T18:53:23ZEngineer7timothy3299Tim952631Chertsey SurreyGBtimothy32992006-07-30T19:01:22ZWebsite Support OfficerIt does better good than being in a bank and being used to do unethical things.And what do I need with the interest anyway? Also we're rich because the west has made the third world poor!uploading, maintenance, training and stats reporting1901bobbieBobbiePortland ORUSbobbie2006-07-30T22:27:25ZChief Operations Officer, RetiredI believe strongly that we are here to serve others and if each one of us can help just a little, we can lift others upI left a job that I had worked at for 20 years because I did not like the way the business was run and how there was such disregard for employees. I now do work from home and am helping my children with their businesses by doing bookkeeping 3constantinoConstantino VoulgarisAventura FLUSconstantino2006-07-30T23:47:22Z122randy9277Randy67061Nanaimo British ColumbiaCArandy92772006-07-31T01:16:10Z161nicholas2989Nicco45931Washington DCUSnicholas29892006-07-31T12:48:43Znicco.orgCEOI started my own business in the United States, and I want to encourage others to do the same.I manage a 25-person company702julia4424JuliaWeston FLUSjulia44242006-07-31T13:41:40ZSoftware DeveloperI want to help hard-working people make the world better for their families and their communities.I work in the USA designing internet software.21peter9526Peter2552761WaikanaeNZpeter95262006-07-31T14:11:43ZSoftware developerBecause I can and it is the right thing to do.My work is both interesting and challenging - what more can one ask for?134aanduA&U1458911Houston TXUSaandu2006-07-31T14:23:22ZAesthetician & University professorFor entirely selfish reasons... it makes us happy.A is an aesthetician, and U is a university professor1537offnerTPO4233761ViennaAToffner2006-07-31T14:58:01Zwww.TPOwein.atEntrepreneur and vintnerKiva is like Venture Capital with an emotional rate of return. Moreover I like change. This money fuels change.Set up, build and develop companies. Produce and market wine in Vienna, Austria. 22william3611Bill DeBoer41161Hamburg NJUSwilliam36112006-07-31T17:34:08Zwww.saabcountry.comSmall Business Owner15nick9778Nick1538671Indianapolis INUSnick97782006-07-31T19:25:52ZMarketingI have been fortunate in my life and would like to help those who just need a little boost to help them outGlobal Pharmaceuticals9holly1666HollyWashington DCUSholly16662006-07-31T19:36:29ZUS DiplomatI was posted to Honduras for two years, as a Foreign Service Officer.1sumantSumantOTTAWA ONCAsumant2006-07-31T20:55:55Z151redcowboydesignsRed Cowboy Designs854911Sugar Hill GAUSredcowboydesigns2006-07-31T21:26:50Zwww.redcowboydesigns.com/kivaSelf-Employed Graphic Designer/PhotographerWe believe we can all play a small part in making the world a better place by being active participants in creating sustainability, justice, and equity. One of the ways in which attempt to practice this is by our new commitment (as of 11/07) to pledge 5% of all of our profits to helping launch other small businesses like ourselves. 512kerwinKerwin247991Plymouth MNUSkerwin2006-07-31T21:48:19ZFinancial OfficerBroader participation in economic activity creates a rising tide on which all boats will rise. It changes lives for the better.I prepare the financial books for our business14robert4647Robert34831Newport RIUSrobert46472006-08-01T11:21:41Zaboutmymoney.comBusiness CounselorKiva connects me to things I seen and things I know about. Other people may be able to \"forget\" about bad things and others\' difficulties. It\'s just not my thing--especially when I see a way to be directly involved.I help others to see opportunities in front of them--something Kiva's friends are very good at!11jeanfrancoisJeanFrancois46121Montreal QuebecCAjeanfrancois2006-08-01T13:42:46ZConsultantBecause I believe that people with big dreams should have the opportunity to live them.I work with companies and government to gain a better understanding of their environment. 87donald9415Donald951841DB CAUSdonald94152006-08-01T23:41:49ZTechnology ExecutiveIt's a quick & easy way to help out someone in need of a hand.Business-man25ronnRonn380111Madison WIUSronn2006-08-02T01:56:53ZAccountantI believe this is a great way to bypass all the bureaucracy, not only governmental, but also bureaucractic systems in place in more traditional non-profit and charitable organizations. I love the idea of getting money directly into the hands of those who are most in need, yet willing to pay back this type of loan. 44linda9354Lindalinda93542006-08-02T02:14:13ZNursethink that lending someone money if better than giving it. People who have responsiblity are driven to succeed. I work long hours in a hospital. I work with heart patients, sometimes even those who have had a heart transplant. I also work in an outpatient surgery department for a change of pace.8mark3491Mark2125991Westlake Village CAUSmark34912006-08-02T05:54:06Zwww.lefkogroup.netI want to make a difference when possible.To inspire CEO's Presidents and Business Owner to do things for the right reasons... and unlock the power of their executive teams.1314yvonne6597Yvonne4157341CaliforniaUSyvonne65972006-08-02T11:02:19Zwww.yvonnerichman.comArtist/WriterKiva is a wonderful program and it feels good to help others.My work comes from a deeply spiritual place and music, poetry, politics, philosophy, culture and religion all play a part in the creation of my art and writing.15sara5702Sara, Stockholm, Sweden2755011Bandhagen BandhagenSEsara57022006-08-02T12:21:35ZJournalistIt is great to give support directly to a person and not to a big and anonymous charity organization.I travel and write about travel and places all over the world where people want to go.531carinaCarinaThousand Oaks CAUScarina2006-08-02T16:59:08Z10paul9674Paul370921Briarcliff Manor NYUSpaul96742006-08-02T17:56:39Z3nick6347Nick & KellyOMAHA NEUSnick63472006-08-02T20:39:24ZWe like to help people!11therickernycRick804461San Francisco CAUStherickernyc2006-08-03T01:17:11ZProducerIt's the gift that keeps on giving! Kiva is a great way to invest in the economic development of those who are trying to climb toward prosperity.TV and Internet advertising.181lars0klundbyLars851301LENA OpplandNOlars0klundby2006-08-03T10:50:27ZStudent161roddyRoddy & Fiona164121ScotlandGBroddy2006-08-03T11:31:14ZEngineer & Civil ServantWe are lucky enough to be able to .19ronald6796Pat & Ron201161Atlantis FLUSronald67962006-08-03T14:33:15ZRetired People worldwide ask only for the opportunity to create a better life for their loved ones. Thanks to Kiva, we can provide that opportunity.Ron is a retired Merchant Marine Shipmaster, and Pat is a retired Registered Nurse. We keep busy by enjoying our family, and volunteering to help people.2501edouardEdouard DIELEMANFRedouard2006-08-03T14:50:06ZKey Account ManagerMicrofinance is the best way to encourage entrepreneurs and a step forward to economic development.51diane9946DianeNorth Las Vegas NVUSdiane99462006-08-03T16:42:12ZRetired (for now)I have been interested in micro loans ever since I heard of them years ago. I am finally able to participate thanks to Kiva.69
    XML/inst/exampleData/allNodeTypes.xml0000644000175100001440000000035013607633702017264 0ustar hornikusers Some text 2 ]]> XML/inst/exampleData/entity.xml0000644000175100001440000000005113607633725016200 0ustar hornikusers & XML/inst/exampleData/boxplot.svg0000644000175100001440000005435113607633705016364 0ustar hornikusers This sample is based on a real data processed with the "gracebox" script by Stewart Rounds. Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 100 1 k 10 k Daily Mean Streamflow (a sample of BoxPlot) The whisker properties are controlled by "Plot/Set appearance/Error bars" XML/inst/exampleData/raw.xml0000644000175100001440000000021413607633725015456 0ustar hornikusers XML/inst/exampleData/literate.dtd0000644000175100001440000000050713607633706016455 0ustar hornikusers XML/inst/exampleData/mathmlInt.xml0000644000175100001440000000071113607633725016624 0ustar hornikusers ]> 0 1 x x XML/inst/exampleData/svg.xml0000644000175100001440000000164713607633725015477 0ustar hornikusers ia XML/inst/exampleData/setInterval.xml0000644000175100001440000000061313607633725017170 0ustar hornikusers ]> x x0 0 &infty; XML/inst/exampleData/entity4.xml0000644000175100001440000000021313607633725016264 0ustar hornikusers ]> Some text and an entity reference &x; And a degree ° XML/inst/exampleData/test1.xml0000644000175100001440000000012613607633725015727 0ustar hornikusers Some text < 3>. More text > 3 XML/inst/exampleData/job.xml0000644000175100001440000000217313607633706015444 0ustar hornikusers GBackup Development Open Mon, 07 Jun 1999 20:27:45 -0400 MET DST USD 0.00 Nathan Clemons nathan@windsofstorm.net The program should be released as free software, under the GPL. XML/inst/exampleData/mathmlQuadratic.xml0000644000175100001440000000201713607633707020010 0ustar hornikusers ]> x = - b ± b 2 - 4 a c 2 a XML/inst/exampleData/tides.xml0000644000175100001440000000354013607633725016002 0ustar hornikusers NOAA/NOS/CO-OPS Disclaimer: These data are based upon the latest information available as of the date of your request, and may differ from the published tide tables. Daily Tide Prediction Sausalito, Corps of Engineers Dock CA 9414819 Subordinate SAN FRANCISCO (Golden Gate) 9414819 1.0 0.98 21 10 20101113 12:00AM 20101114 11:59PM Feet LST/LDT MLLW High/Low Tide Predictions 2010/11/13 Sat 4.74 H 2010/11/13 Sat 2.75 L 2010/11/13 Sat 4.28 H 2010/11/13 Sat 0.83 L 2010/11/14 Sun 4.89 H 2010/11/14 Sun 2.3 L 2010/11/14 Sun 4.04 H XML/inst/exampleData/literateFunction.xml0000644000175100001440000000243213607633706020207 0ustar hornikusers
    xmlSourceFunctions(system.file("exampleData", "literateFunction.xml", package = "XML")) fun fun = function(x, y = 2, z = 3) { } The first part is Now we do the heart of the computation. This creates a derived local variable and then simulates some values. We do the latter within a separate fragment. tmp = z * log(x)^y (Note that we cannot use a CDATA for this r:code as we refer to another r:code element. So we would have to use entities for any special characters such as & and < and >. Now we just put a class on the result We now come to the simulation part. Note that we have to agree on the local variables across the fragments, e.g. ans.
    XML/inst/exampleData/matrixMult.xml0000644000175100001440000000071313607633707017037 0ustar hornikusers 1 2 0 1 1 0 2 1 XML/inst/exampleData/SOAPNamespaces.xml0000644000175100001440000000112313607633705017425 0ustar hornikusers 99.5 XML/inst/exampleData/namespaces.xml0000644000175100001440000000036213607633725017010 0ustar hornikusers XML/inst/exampleData/redundantNS.xml0000644000175100001440000000022713607633725017116 0ustar hornikusers plot XML/inst/exampleData/dot.xml0000644000175100001440000000011013607633705015444 0ustar hornikusers <_text>Some text XML/inst/exampleData/rhelp.xsl0000644000175100001440000000102613607633725016007 0ustar hornikusers = value XML/inst/exampleData/graph.gxl0000644000175100001440000000426013607633725015765 0ustar hornikusers main.c test.c 225 316 127 27 42 XML/inst/exampleData/author2.xsd0000644000175100001440000000104613607633705016251 0ustar hornikusers XML/inst/exampleData/mathml.xml0000644000175100001440000000075113607633706016154 0ustar hornikusers ]> x 2 + 4 &invisibletimes; x + 4 = 0 XML/inst/exampleData/namespaces2.xml0000644000175100001440000000067213607633710017070 0ustar hornikusers XML/inst/exampleData/mtcars.xml0000644000175100001440000000732713607633710016164 0ustar hornikusers mpg cyl disp hp drat wt qsec vs am gear carb 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2 XML/inst/exampleData/nsAttrs.xml0000644000175100001440000000017013607633725016324 0ustar hornikusers XML/inst/exampleData/content.html0000644000175100001440000000067213607633725016513 0ustar hornikusers GXL 1 Examples XML/inst/exampleData/cleanNamespace.xml0000644000175100001440000000051313607633705017564 0ustar hornikusers foo XML/inst/exampleData/branch.xml0000644000175100001440000000040113607633705016116 0ustar hornikusers Some text XML/inst/exampleData/size3.xml0000644000175100001440000000047713607633725015735 0ustar hornikusers 0 0 A 0 1 B 1 0 C 1 1 D XML/inst/exampleData/nodes.xml0000644000175100001440000000122213607633710015767 0ustar hornikusers Works: xinclude:include href="something.xml" xpointer="element(/1/2)" parse="xml" xinclude:include href="something.xml#xpointer(/1/2)" xinclude:include href="something.xml" xpointer="/1/2" Fails /doc/1 /doc xinclude:include href="something.xml#xpointer(author)" TEST

    My own substitute text

    XML/inst/exampleData/GNUmakefile0000644000175100001440000000160013607633702016210 0ustar hornikusersXSLT_PROCESSOR=export LD_LIBRARY_PATH=/tmp/xml-xalan/c/lib ; /tmp/xml-xalan/c/bin/testXSLT PREFIX=$(OMEGA_HOME)/XML/Literate/ C_XSL=$(PREFIX)/croutine.xsl C_XSL=$(PREFIX)/fragment1.xsl writeRS.c: writeRS.xml $(C_XSL) ($(XSLT_PROCESSOR) $(XSLT_FLAGS) -in writeRS.xml -xsl $(C_XSL) -out $@ ) writeRS.S: writeRS.xml ($(XSLT_PROCESSOR) $(XSLT_FLAGS) -in $^ -xsl $(C_XSL) -param language "'S'" -out $@ ) writeRS.html: writeRS.xml $(PREFIX)/article.xsl ($(XSLT_PROCESSOR) $(XSLT_FLAGS) -in writeRS.xml -xsl $(PREFIX)/article.xsl -param language "'S'" -param cssURL "'file:///home/duncan/Projects/org/omegahat/XML/Literate/OmegaTech.css'" -param inputFile "'writeRS.xml'" -param outputFile "'writeRS.html'" -param inputXSL "'$(PREFIX)/article.xsl'" -out $@ -TT ) CFLAGS+= -I$(R_HOME)/include -I$(R_HOME)/src/include writeRS.so: writeRS.o: writeRS.c writeRS.so: writeRS.o R SHLIB -o $@ $^ XML/inst/exampleData/literate.xsl0000644000175100001440000000074413607633706016513 0ustar hornikusers XML/inst/exampleData/namespaceHandlers.xml0000644000175100001440000001136613607633710020306 0ustar hornikusers This is an R model This node with the same name identifies a model in PMML. And this is a model element with no namespace. We want to handle the model nodes in R. So we might think about this in the usual manner with something like the following handler. model = function(node) { cat(xmlValue(node), "\n"); node } Then, we pass this handler to the DOM parser with xmlRoot(xmlTreeParse("namespaceHandlers.xml", handlers = list(model = model), asTree = TRUE)) The output we get is This is an R model This node with the same name identifies a model in PMML. and then the resulting XML tree. We want to have different handlers, one for the R model node and the other for the PMML mode node. And we will add one for the node that has no namespace prefix. We can do this with handlers = list("r:model" = function(node) { cat("R handler: name = ", xmlName(node), ", value =", xmlValue(node), "\n"); node }, "pmml:model" = function(node) { cat("A PMML node\n") node }, model = function(node) { cat("ordinary model node\n") node }) We can then invoke these from R using xmlTreeParse("namespaceHandlers.xml", asTree = TRUE, handlers = namespaceNodeHandlers ( .handlers = handlers)) The key thing is that we call namespaceNodeHandlers We'll add an additional node handler to show that this is not limited to duplicate node names, but also handles general ones. handlers[["para"]] = function(node) { cat("alignment for para", xmlGetAttr(node, "align"), "\n") ; node} xmlRoot(xmlTreeParse("namespaceHandlers.xml", asTree = TRUE, handlers = namespaceNodeHandlers ( .handlers = handlers))) What we have done above is to rely on the fact that we have the same namespace prefixes used in the document and the handler names. It is better/safer to be explicit about this and define our own namespace prefixes and each to an explicit URI. Then, we can compare the URI for the node's namespace to ours and only follow the node then. We do this by providing a named character vector giving the prefix = URI pairs. h = namespaceNodeHandlers(.handlers = handlers, nsDefs = c(r = 'http://www.r-project.org', pmml = 'http://www.dmg.org/PMML-3_1')) z = xmlTreeParse("namespaceHandlers.xml", asTree = TRUE, handlers = h, fullNamespaceInfo = TRUE) Note that we have to specify fullNamespaceInfo to be . This is done automatically in xmlTreeParse for us now. And we see that we get the same handling of the nodes since the name space definitins correspond to the URIs in the document. We will illustrate that the name space prefix in the handlers does not have to be the same as that in the document for the same URI. We'll change the pmml prefix in the names of our handlers to a simple 'm'. And we use 'm' when specifying the name space definitions in R via the nsDefs argument. When we run this code names(handlers)[2] = 'm:model' z = xmlTreeParse("namespaceHandlers.xml", asTree = TRUE, fullNamespaceInfo = TRUE, handlers = namespaceNodeHandlers(.handlers = handlers, nsDefs = c(r = 'http://www.r-project.org', m = 'http://www.dmg.org/PMML-3_1'))) we get the same result, with all three handlers being called. And it is further useful to verify that if we had a different URI, then things wouldn't work. So we'll provide a different URI for the 'r' prefix z = xmlTreeParse("namespaceHandlers.xml", asTree = TRUE, fullNamespaceInfo = TRUE, handlers = namespaceNodeHandlers(.handlers = handlers, nsDefs = c(r = 'http://www.other.com', m = 'http://www.dmg.org/PMML-3_1'))) The result is that we call the standard model node handler for the r:model XML node in the document. Note that one does not have to specify the handler functions as a list, but can identify them separately via the parameter of namespaceNodeHandlers. XML/inst/exampleData/basic.xml0000644000175100001440000000020613607633725015747 0ustar hornikusers XML/inst/exampleData/utf.xml0000644000175100001440000000014413607633725015465 0ustar hornikusers â„«ﮛ <â„«ob/> Simple text Ä© XML/inst/exampleData/mathml.dtd0000644000175100001440000010134513607633706016130 0ustar hornikusers %ent-isoamsa; %ent-isoamsb; %ent-isoamsc; %ent-isoamsn; %ent-isoamso; %ent-isoamsr; %ent-isogrk3; %ent-isogrk4; %ent-isomfrk; %ent-isomopf; %ent-isomscr; %ent-isotech; %ent-isobox; %ent-isocyr1; %ent-isocyr2; %ent-isodia; %ent-isogrk1; %ent-isogrk2; %ent-isolat1; %ent-isolat2; %ent-isonum; %ent-isopub; %ent-mmlalias; %ent-mmlextra; XML/inst/exampleData/mathmlScript.xml0000644000175100001440000000047313607633725017343 0ustar hornikusers ]> x 1 α + x 1 α XML/inst/exampleData/TestInvalid.xml0000644000175100001440000000026313607633705017115 0ustar hornikusers ]> <version></version> XML/inst/exampleData/nodes2.xml0000644000175100001440000000043413607633710016055 0ustar hornikusers Some fallback text XML/inst/exampleData/gnumeric.xml0000644000175100001440000000664413607633706016512 0ustar hornikusers Application gnumeric Author Duncan Temple Lang Sheet1 1 7 1.000000 Helvetica Helvetica Helvetica 36524 4 d 1 x sd 2 5 s dsa 3 as XML/inst/exampleData/entity1.xml0000644000175100001440000000016713607633705016267 0ustar hornikusers ]> Some text and an entity reference &x; XML/inst/exampleData/mathmlSphere.xml0000644000175100001440000000100413607633707017314 0ustar hornikusers x y z x 2 y 2 z 2 1 XML/inst/exampleData/catalog.xml0000644000175100001440000000202713607633725016303 0ustar hornikusers XML/inst/exampleData/largeText.xml0000644000175100001440000003641213607633706016634 0ustar hornikusers
    Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors.
    XML/inst/exampleData/xysize.svg0000644000175100001440000002237613607633725016234 0ustar hornikusers 0.0 2.0 4.0 6.0 8.0 10.0 0.0 20.0 40.0 60.0 80.0 100.0 XYSize set presentation example The normalization of the symbol sizes is defined in "Plot/Graph app/Special" XML/inst/exampleData/Rref.xml0000644000175100001440000000047013607633705015565 0ustar hornikusers
    This is an example of code with references to other segments Top-level code x = 1 cat("top-level code node\n") print(x) cat("r:code node with id bob\n") x = 10
    XML/inst/exampleData/writeRS.S0000644000175100001440000001543113607633725015675 0ustar hornikuserswriteXML <- function(x, con, ...) { UseMethod("writeXML") } writeXML.default <- function(x, con, ...) { if(length(class(x)) > 0) return(writeXML.object(x, con, ...)) name <- paste("writeXML", typeof(x), sep=".") if(exists(name, mode="function")) { f <- get(name) f(x, con, ...) } else if(is.integer(x)) { lapply(x, function(i, con, ...) { con$addTag("integer", i); T} , con=con, ...) } else if(!is.na(match(mode(x), c("integer", "numeric", "character", "logical")))) { lapply(x, function(i, con, tag, ...) { con$addTag(tag, i); T} , con=con, tag=mode(x), ...) } else if(typeof(x) == "NULL") { con$addTag("null") } else stop(paste("No method for writeXML", typeof(x))) } writeXML.list <- # # Write the representation of an S list # to the XML connection. # # function(x, con, ...) { isNamed <- (length(names(x)) > 0) tag <- ifelse(isNamed, "namedlist", "list") con$addTag(tag, attrs=c(length=length(x)), close=F) for(i in 1:length(x)) { if(isNamed) { con$addTag("name", names(x)[i]) } con$addTag("element", close=F) writeXML(x[[i]], con, ...) con$addEndTag("element") } con$addEndTag(tag) invisible(con) } writeXML.object <- # # Writes a general S3 object, i.e. one with a # non-null class() value. # This just writes out the names of the named # elements of x. # Doesn't handle non-named lists yet # function(x, con, ...) { classes <- class(x) con$addTag("object", attrs=c(type=classes[1]), close=F) for(i in names(x)) { con$addTag("slot", attrs=c(name=i), close=F) writeXML(x[[i]], con, ...) con$addEndTag("slot") } if(length(classes) > 1) { con$addTag("classes", attrs=c(length=length(classes))) sapply(classes, function(x, con, ...) { con$addTag("class", x) }, con, ...) con$addEndTag("classes") } con$addEndTag("object") invisible(con) } writeXML.closure <- function(x, con, ...) { is.missing.arg <- function(arg) typeof(arg) == "symbol" && deparse(arg) == "" args <- formals(x) con$addTag("function", close=F) con$addTag("args", attrs=c(length=length(args)), close=F) for(i in names(args)) { con$addTag("arg", attrs=c(name=i), close=F) if(!is.missing.arg(args[[i]])) { con$addTag("value", close=F) writeXML(args[[i]], con, ...) con$addEndTag("value") } con$addEndTag("arg") } con$addEndTag("args") b <- body(x) if(length(b) > 1) bodyLen <- length(body(x))-1 else bodyLen <- 1 con$addTag("body", attrs=c(length=bodyLen), close = F) writeXML(b, con, ...) con$addEndTag("body") con$addEndTag("function") invisible(con) } writeXML.language <- function(x, con, ...) { if(x[[1]] == "if") { writeXML.if(x, con, ...) } else if(x[[1]] == "{") { for(i in 2:length(x)) writeXML(x[[i]], con, ...) } else if(x[[1]] == "for") { writeXML.for(x, con, ...) } else if(isLogicalExpression(x)) { writeXML.logicalExpr(x, con, ...) } else if(isComparator(x)) { writeXML.comparator(x, con, ...) } else if(x[[1]] == "while") { writeXML.while(x, con, ...) } else if(x[[1]] == "break" || x[[1]] == "next") { con$addTag(x[[1]]) } else if(x[[1]] == "<-") { con$addTag("assign", close=F) writeXML(x[[2]], con, ...) writeXML(x[[3]], con, ...) con$addEndTag("assign") } else if(x[[1]] == "repeat") { con$addTag("repeat", close=F) writeXML(x[[2]], con, ...) con$addEndTag("repeat") } else if(x[[1]] == "return") { con$addTag("return", close=F) if(length(x) > 1) writeXML(x[[2]], con, ...) con$addEndTag("return") } else if(mode(x) == "call") { writeXML.call(x, con, ...) } invisible(con) } writeXML.if <- function(x, con, ...) { con$addTag("if", close=F) con$addTag("cond", close=F) writeXML(x[[2]], con, ...) con$addEndTag("cond") if(length(x) > 2) { con$addTag("action", close=F) writeXML(x[[3]], con, ...) con$addEndTag("action") } if(length(x) == 4) { con$addTag("else", close=F) writeXML(x[[4]], con, ...) con$addEndTag("else") } con$addEndTag("if") invisible(con) } writeXML.for <- function(x, con, ...) { con$addTag("for", close=F) con$addTag("index", close=F) writeXML(x[[2]], con, ...) con$addEndTag("index") con$addTag("elements", close=F) writeXML(x[[3]], con, ...) con$addEndTag("elements") con$addTag("loop", close=F) writeXML(x[[4]], con, ...) con$addEndTag("loop") con$addEndTag("for") invisible(con) } writeXML.while <- function(x, con, ...) { con$addTag("while", attrs = c(doWhile= (x[[1]] == "do")), close=F) con$addTag("cond", close=F) writeXML(x[[2]], con, ...) con$addEndTag("cond") con$addTag("loop", close=F) writeXML(x[[3]], con, ...) con$addEndTag("loop") con$addEndTag("while") invisible(con) } writeXML.symbol <- function(x, con, ...) { con$addTag("symbol", as.character(x)) invisible(con) } writeXML.call <- function(x, con, ...) { con$addTag("call", close=F) con$addTag("caller", close=F) writeXML(x[[1]], con, ...) con$addEndTag("caller") # Don't make this a x[2:length(x)] # or x[-1]. Infinite loop results. argNames <- names(x) if(length(x) > 1) { for(i in seq(2, length=length(x)-1)) { if(!is.null(argNames) && argNames[i] != "") con$addTag("namedArg", attrs=c(name=argNames[i]), close=F) writeXML(x[[i]], con, ...) if(!is.null(argNames) && argNames[i] != "") con$addEndTag("namedArg") } } con$addEndTag("call") invisible(call) } isLogicalExpression <- function(x, ...) { !is.na(match(as.character(x[[1]]), c("&", "&&", "|", "||"))) } writeXML.logicalExpr <- function(x, con, ...) { logicalTags <- c("&" ="elementAnd", "&&"="logicalAnd", "|" ="elementOr", "||"="logicalOr") tag <- logicalTags[as.character(x[[1]])] con$addTag(tag, close=F) writeXML(x[[2]], con, ...) writeXML(x[[3]], con, ...) con$addEndTag(tag) } isComparator <- function(x, ...) { !is.na(match(as.character(x[[1]]), c("<", ">", "<=", ">=", "==", "!="))) } writeXML.comparator <- function(x, con, ...) { logicalTags <- c("<" ="lessThan", ">"="greaterThan", "<=" = "lessThanEqual", ">="="greaterThanEqual", "==" = "equal", "!=" = "notEqual") tag <- logicalTags[as.character(x[[1]])] con$addTag(tag, close=F) writeXML(x[[2]], con, ...) writeXML(x[[3]], con, ...) con$addEndTag(tag) } writeXML.builtin <- # # for primitives # function(x, con, ...) { con$addTag("builtin", attrs=c(name=getPrimitiveName(x)), close=F) } writeXML.special <- # # for primitives # function(x, con, ...) { con$addTag("special", attrs=c(name=getPrimitiveName(x)), close=F) } writeXML.environment <- # # for primitives # function(x, con, ...) { con$addTag("environment", attrs=c(name=getPrimitiveName(x)), close=F) } getPrimitiveName <- function(obj) { .Call("RXML_getPrimitiveName", obj) } XML/inst/exampleData/simple.xml0000644000175100001440000000015613607633725016163 0ustar hornikusers Some text XML/inst/exampleData/Rsource.xml0000644000175100001440000000214013607633702016302 0ustar hornikusers
    This is a very simple example of using an XML file to create annotated R code that defines some functions and also has a "main" script in the style of Python scripts that can be loaded or run. myFun = function(n) { sum(sample(1:10, n, replace = TRUE)) } We define a second function and we use an id attribute "B" eventhough this is not the name of the function. Note also that we use the CDATA construct to specify the content of the node as the code contains characters < and > and & that are special to XML. = x & pos[2] >= y & pos[1] <= x + w & pos[2] <= y + h } ]]> We only need to surround this code with the start and end of the CDATA delimeters and we don't have to escape the individual characters. This makes it easier to cut and paste the code directly into another application. inRect(c(10, 10), 3, 4, 10, 10) myFun()
    XML/inst/exampleData/iTunes.plist0000644000175100001440000000670213607633706016476 0ustar hornikusers Major Version1 Minor Version1 Application Version7.5 Features1 Show Content Ratings Music Folderfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/ Library Persistent IDBD55EC2E7FDB1DAE Tracks 181 Track ID181 NameDon't Know Why ArtistNorah Jones ComposerJesse Harris AlbumCome Away With Me GenreJazz KindAAC audio file Size3031411 Total Time186152 Disc Number1 Disc Count1 Track Number1 Track Count14 Year2002 Date Modified2007-02-05T10:46:04Z Date Added2005-08-22T21:14:30Z Bit Rate128 Sample Rate44100 Play Count24 Play Date3274252284 Play Date UTC2007-10-02T21:31:24Z Persistent IDD7F9F158A4A48E53 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/01%20Don't%20Know%20Why.m4a File Folder Count-1 Library Folder Count-1 182 Track ID182 NameSeven Years ArtistNorah Jones ComposerLee Alexander AlbumCome Away With Me GenreJazz KindAAC audio file Size2376546 Total Time145262 Disc Number1 Disc Count1 Track Number2 Track Count14 Year2002 Date Modified2007-02-05T10:46:05Z Date Added2005-08-22T21:14:49Z Bit Rate128 Sample Rate44100 Play Count23 Play Date3274252429 Play Date UTC2007-10-02T21:33:49Z Persistent IDD7F9F158A4A48E54 Track TypeFile Locationfile://localhost/Users/duncan/Music/iTunes/iTunes%20Music/Norah%20Jones/Come%20Away%20With%20Me/02%20Seven%20Years.m4a File Folder Count-1 Library Folder Count-1 XML/inst/exampleData/entity2.xml0000644000175100001440000000017313607633705016265 0ustar hornikusers ]> &x; y = &y; XML/inst/exampleData/dtd.zip0000644000175100001440000034403513607633705015454 0ustar hornikusersPK Q_†(dtd/UT )´ì8)´ì8Ux†>MPK3_†(D&‰rq·dtd/mathml2.dtdUT ò³ì8ò³ì8Ux†>M½]msÜ6’þ®_Ó®Êö•%Kr’¥½­r$e£:IñÙJ%[©|À˜®ùf’#i¶òã¯AD7^8$mz*)‹xi{ýš…Ú ØÕSÎþŠÕú%ñ'|Ë0¡|^ʶa,dÞýòÃÍõEÍÑÿúpu«ËåY‡«)¶øêÕ¯¯/^½’ŒÐ6àÕ««»ý¶hCfßoè´+Ϙ£ªfd Rà…4ÍŠ]ýü£²6ÄÜüß†Ç ýOD)ey‹]–®±hWw÷×÷ÿb G?¥@ã¨!±}wqóËåÕ>“E?p”9ÿ½Èž“Muñë«Ø^š81øWÿZî©Od›ìü?Z›-ÙÁ݇#³eô$Âs)M·^‚bñìšÔŽ»ÀâFóË—L5 FShð¿7¥T€Z™Ë2 ".V rÓ=ÅÐßIk„;·oﺽ9ª;˜ó@\Š >Rm6Íí¸2Ï÷÷þ±'{4’VSæ)‰Ó“RŒyÛu–•k^(á—Œ±†¬ì›,Y3é™x.²$ÉÒ¦1‡³kÍø>ÅQúñl l““ÐåÛû·ÌñûËõí»›ë«Ë¦RÃH´yC+•Õ${d¥(Dy×—®v¥'Õ›¶Òû«Tªn0<=šï°µnFÁt<Èãaڅ餦æe”F’^i6 Þá<‡2úO3eì·³¸è= 9#!Š*žžÃ¤þ@ÌþOÜ‘)ÖÃ!¶Ã„îUKrÁ%O¢x‹(ª„‰À3*bõßÇž¹‡$Ç©U<FE”W±x±…œäM’±¨Ìc¾%sKœäMšIjtRP’M\Eré_PäFžÕƒÄ‰ù7ØÒæMàù‚WE¶Iñ¢ !Nò¦ð<ËEj•oˆ“¼IÞf,—¯nâ$o’ηs@©‹›.V9•öfÑÈÄ:ZVqšç!ßK<…I¾#nä9ÉïœAôª®#Nò¦è,[V©A%M³…Ù#¢ÑAœ8q³IRMC/ytòtºíÜL¨6‰S¨J Îm.ä)tëºul%]&C¦SÇ 0ŒŽt«dZÿôÈé¼é&ô ›Ûœ †°É °ÄÅ5l56!O`79“OˆmW¦(]FR©ÍeG!üòr-dØbas$1ñ]¼î#.>mx,¥Á LÒ'ndÁDMò&…4*é´KWÒÁðƒN§è£1Vf´¢µ4ŽtÛ7ÕºN× DWÍf›ñq4àÊieÜQÜN¯ÇßNqÑíFÔNmÀP—yrçûÌÏQ=3Üb_š¼Ï²/˜¾ia¦\®L÷'šÆ&õ?™Ú 6é2&Zmsdº eMó¡bQÓ tIò$5J “…©“¼iÓZEËvJŸB8×èɦK’'±c!E±)]š:”°|/ƒzCž«½¡fÝŠ çUöÑáékÛ–DGõvÖ9HçA’⇬yh´X&Uâ©ÂEÊæ¡ÁøöþþæúÃ=ÓT[ àÚ·±¢¿Òþžï”:H¶‡D0çÐC‰*Še5ÙÔßÄ Äå`Ä;«š¤VÊ®’¼Ú²Ü)k–x |uâUâ”@囫[ ÀhcW·ï€¦Ùu\„DîšÐí]PÚ!w.…:c+‘Š‚Ç f)yhÀßi(¨2}†Ù k L¡ÑšOÑ¢"Ë*£2Y¤õb™Ô”³'NE‘Žº9Câ’ùš§U–\2ÀúTu‚ô¯—©º:îô(¹mÍ£5²]ËVÄÐÑ@ 6Ú€RÖûYœ¥«0zxfó0ÃÀFá"cý™jßÚ©a–ÀÏw¬€:ìçH§A5GW<]Gµ ðÂp¦åx¹7 Œ$fcdш‹#T_GLHz·Jpxä.ßJ–^¡ÑRëÊýi<1[Z±Â”(jv $ä4·Í.‹Ù µ42M¶KãpŽ”§geØÿ3ÖˆI}^ªÙ@³æ(Ó?'€,K¾ÉéãÂH©¥Ïaٳܕ3kÕk`ûì;4R ­²èæÆ¼1†´©•6hJ2ê1­’±Ñ&±#¦úð$Ý?“ä@àÙšwvꧨ=Öî<™<#Úª¬KO…KQ;=•Ž/í(”Œ²Q=Ò^¬]¡se‰U´‹™L#'èŒf'}’?„òN®Ö“ƒƒÞoéêŠØUÄ6Å|CÒÄÊë†bjƒ… MÔ&¹bŠñëÃ1=£u«ï_BNPÚÉS½n’!f±SÈ´˜éUX-AzV”žëø‰ce»s­ç4XÚëŽÖ]Æò¬¸¼øè³fÏú×.f¹“NÊÓ9Š K¼tëÁš½í’´;*Ñ ¸Š·ùº—"-AIòØ>zè8dX‡ú<†Q¹è="¢ í%CDê$‚ÆgbøæíAkè|c™Åqö(·uš·êi&ãúUÙüvE¨&¿ê5ž’‰§ú{©§Yù²ˆ*Î !WÄìËM(^¶ï[H®í™ü’̽N/²ÔˆæjÍ®cJJEûwÛÃÖ.4Ùø¡‡sOÀTuû¬>{Nlê¥ kWn0Ve4¶1Ø[èÍŒ=c=ý õ‚Û‡6ôy“r@ìþÙÉñ3Ïqù˜‹0Éó®Wq¡‹¸î•M\çýòþÆKý™‹,¬@³îtë­œçÇì"›òbE E·9‚2zì"šÁ¦(ðyeM—äùé.7i-€‡IŠØÙH¡Ž–´t‹pÀûÏÒM"Š(pT§Œ_Cäù©ÇYÀ`鮥MòFl¾ Yž±Xð%ؽÐá$®°xk3‚r›,²¹ Þ„ R+¬KijC|as‚ÐjAcSX›£wDËšâP8FË“¦E«i¼&0À9æe.‚ˆÇŽor|bw _®Ý¢a.D¬wÛZ1O!÷Œ?¡0.¤†W“ Â=Úµ·bó®~çÈÁ9ò.’K_²4Œ°“Ü EƒÛRJ‘ûôƬ?°£±ÏFû@Gmúi³3ÚĶóœ5Cœn3Î& ß4pèx1à[, •ó¢­M ÓGnG¸ËGãÉÓv“ÅÒu=£nÑ>h# ¤tЉôÑD]œLÖ9lÛ›¹”å:‡  ¢‡X•d[“¬'G»N§[¤àÝ¢§!›õŒ«Ùðf7ΦÉkÔ¸[v©·a1|ªÕ³Q8b®„!»É™1<“*[ÁS'åH8„í˜[‡ePR¶‚IÃ00ŸÁl%6·=X)¯6Á]8hÉËbñ$¬Œ¼ˆ;Ö¶Y*×’9›¼(á«ìù6² €6«öÍyÛL«Ïf[ ËèV”¦Õ˜ØÄ¢Xñ$áÀ´¶l[ª[Ý”a²Û5oXe¾´]íÐAvA¡æÃaÊ•‹Uh696&!§ ›eæÓï^¹Í¿‚¼ÚS­“#v©ùtšNñž9Ü(ó¥Ñ¸×ÿ¹hÞγ@Ìò·Xûò.¼Ü¯/Jòº1¤´›´È—£o©·oKד£>Œh®}–#BŸ!Aˆµn摳zYÿ0šEfD^È«Äl í¢{‹’ŒbúïÍŠWX`afGOK.WtZ?w0Љ’%v7{$5âñ.æ6Ä œy8ÍI'”=# <‚¾EÌŒfÈrõyz_C¹ q«·Yh>ÿÊÐG·eú '+N‰Ñi-N¥›ÒcpžûÌ)ðºqê3œòÈy„¦Ûä-Ž(!ÏÉñÖB$žŽ›Ô\}·Ê̪þ´3.ÄÙ*‚Åà§ §§ßÚ>ˆ§¨$Ï—YÁãØÓ-ZÚíð“ó¹O¦Ûw¢%¾“½v§Ø*gسx2·õb"íUDœ=›³Þù{ÄátOýžfa±w9žzMAÚo Òïk~>~¯W¬î(÷¹÷4׳’£EfìK ïûÈ™õkû}Å ÃÕ_.±£Ï ¹óAR[ ¡¼ƒ%Å`«àX—ƒMA$ð<æAÄSm’ÿÜ,5£~á9g|œ?Ûâñѹ.Çù32Ã@·ûašQÖSÂÙ3Føû£³éœ&LëŽÖQ·Ö üùÖ´¶Áp®ŸÅf¶‡þ½ŒØgŽâ~1ŸqáƒêU.èú(&/Bz”å¶:^øÖ¤ŠÏVHÌÐ\Ï¡I\dÞ~Ø;F]?6)= [Ÿ‰+EàszHyW¿pÍé=]„ ÍÈâO.§E‹Ê_•«Îp`Ï¥¾À'H›Þõ²ÎžÍ,R¸îƒ/¸ÈlÓ%â’Ûª¡³5Xõy¨eD·`IÔOû:ÊŠ+”äÉu—´°¦M¬ikg#kÚ %Q9êð" ÚH¨¼qÙ|ÓÙ³9žÙŽ£cå̪~_Sgω–{ 悲€ÎžOz-†Îžm²zÔ`=¿ôB@ù3jB/”?£.ô„ΟQú¢œ²ô…˜V܇)‚ùg:™y`Ì?G)Ôc¾™B»°w.Z·&»e(¬¨Ú/"Ncj‰Q0¥+)ß ö¸ ¸!禘ÚDsš ?“•.F™¹ Ð!t *1Œ¬ÿäÊŸYI’,î7•ãlœéé*1['b¯úBJ¡¨ägSŽ‚ë-áªàiiŸ)Õ<»®3žg›Íñ0{NÝÓB3³ÞŽ)µ¬W¯æ n´ˆ xÌýÙÙ¸JsÍñq6à´-Ž‚³™[W·œv×Qp.Pfº÷Iír3‹ŽV—õxwlLÊ|á®8Oò"æî‹d‚•H!×»±™ŠOž®ê÷Æl—=ÛX)èþ±Òeü>áÐàJgiM_µ%äQðO›èÇôÔ#ÏA$Ÿ<ÌéçÍl¬ÑÍ›€Ý0ŒR³9à˜Un—˜ ƪ—«Ùc«ýÕ¹›_õËäjv¡ŒûÄóŒRT.[‡ÞZBúf•ù,o_#@Z^TûÕ¦þÝ“™yN:á9?ó5@PÎy€B3‚1†ÌÇ(6³T¢i¬ó5LqÛ!k»{õU8<„½_·Ÿz5ü¤°¬2Ci®{]CŠ|¹~ Dtg‰Ó¹«§FËÈyW“Îtu?–ŸšB;~ c›ÜLY]·÷¾Z"-w…$5Á— âšàsÉž\F²«J„Zøå÷tÅ(UÍ>U/¬ë«5ºêøjÈýóƒ¦D-+ú²ëóÿmÜT+óL2|ótMIë›Mé–WkI®Áá$¦J3TR¼½aò²v€>iÞ(é#MßÞ\´å¬O³þ¥¡ù§qõûŸæÅí}7íÖ&×¾`]ý:uxžðm=nÆO$ !¿väóAëöÙÉõºø÷üÀì¥=¶Œ|Úκ3÷sh¥#q¡›=”}ÇW¶¿ú8AÝÚ5èóM) œ¡mq—=–m\‹®˜…~e‡%F1Å_Œ«Œ#£DÆŠ ‰ çìrLû>,ÕÍÐjRIüIù…½Öz´ôD:I¥ŸÆ$½£N•%ãÆçGÔt}ÕpXM—J «i~CuxMó‹¨#8d|uL?³‰mšŸ"SÓºÅ|x›îÊ;kº?€7¤¦ñÁmÒOû©éø2àÀšä;n£Ú¬¾Þ…韅[8Ã0H²&™æÄ,‹»0ÔyçkX3Ê àÿXmŠahd&™æF“å˱h@óSö£œQ†á&,<æÆNÑX<ê€Å@0@ßiN0Xüâ"R°ƒ1šá¤M2í|Ï3Éé´nƒ` ;Çc8ŒÁ ™æÄn’b¡>\«Ê‡fùŸÏ×C¥Ú0ñ@’N¾Ù髽Û,â¨\ÖU i¶I­ºúŒDÉš.¶Ø¶„wºäf/’$†¥W±SƯd¡]hé‘N´‰çt‘Áã–J[½â X@Ú=òu£¦¶S@u‹;ûQ4ûQ'¶ý cÙÒ³f’óDé•€ÿøCn|ˆêS3?E%8êÛ³½¶åkXi ¾¬Øór ëÓ'ö?ì79œ¼yó·Ããoß  *‘¯aÚÿaS>Š8nsê&€m“oP÷ÙBÀ2éX\¸+|wxú¦VõÿŽlóäôðäÛQu¾‡F¿[çøown +;U&òfÑŒB) ½‘Ÿž B—ü! Ù/@wcÑf(ëÖ-ðQ0T~ïfþ R;Š©¢zr|x‚©ÞEAÆÞey "Í| Ù®5kH'¿Û ìVúe.}¿r“׫àÓãããÃã:ôîÊ¿ýt/…7Kr0Û‹(–’«ªS^£ê·›¢à[ðñªµˆ’®mi’Œ ò¦þëÃÓì{:>Lõ4’]Þ_î 0ûbŸ?2MÍÿPK3_†("&U| ß-dtd/mathml2-qname-1.modUT ò³ì8ò³ì8Ux†>M­Zmoã6þž_ÁË5HHìd³Àu¢@v“¶AwÓ»].EÑ´DÛ¼•D…¢üòïoHJ–5C‰½Eƒ~èÚÏÃ>œi~ÿ·ËK6ùkþØåå'ßÛ?r³þøý«æ™\J‘²'ž‹Š}Ti ö§íu.e&f,‡aóìõåKÃ]^Or•žœ0û7_ËŠÁf-œqP™ð þ¡¿Ô%ûÀ‹UÍW‚}ë]{Å^O®./Ø3øéÇàe™ÇHU°¥Ò,U¢åB+gø0d¡Œñ"e /M­-ƲPfͤ©XetÀWÂÃTaDa&»ïU¹×rµ6ìúíÛï.__]]±ÿܼïçìñéÓãÝûEHõê‚Ýeûd±û$*¡7"øQ>‰¬À‘ûæ1 ªs±aדfÇŸ^½™^ݰë7³›ÌÞ¼f)ßÈ4a»’}ÃŽU¼Ÿß³Ü/”Õ4·ý.öNÞþû݇Ç÷nVŸû<øØat5kFb-ìôr:…™M§OóÇùãÃç66@ד+ V¯SÎ.9—€dÁÌV±’kS]°Œ/DŸ~‰‹¢ó»s'æù»óN½öË;ˆÂ$ãÄ:3B3«¶‘ð‘Q¬ªËRiì2UÉqÙñrpÒ}wÑAš1]WθýŽ•Z,宋eæÒÀÏÙ‡vïݨ{uÆÁÇR+ˆ5Ñ’;W‘‹ÎϲVf)‡Á˜Ù—¢š„UN…–l©UîÂóùçy òÌE^f܈†99éÖô õ¬áÚŠðtÐêG;­­Ò_Ø,ðׯ†‹îߨ{ú<ñ2‚iûwúøÓÓ¯ŸNÙǨwóŸAÓòôìˆwkÁÞ·ç²ø‚ã˜Ø|þðøôËd—gEÅNׯ”³ét»ÝN¶7¥WS(1o§» FB^ñ&ܨu^âS÷ÑÌQ VÝßÍïX÷÷÷ŸîÙùÙýöüôåHÄçFï´µôû»©mê‡ÓÐŽ{ÀïgHÝÛ߇ OÄÎhÞÌF°üñGÈJÞhuFUlðÏyR.wv˜ôvžìàZ!z·j‡Õ:áö¼ÉųÁéÝÚ káþÿlƒg0˜¾Æ='ñqâôäuÉ<¶p—o04ÎØúŸàâòn6Ô…ª )/0ÒÛ‰/}U3âWÞ¯®¼8ys7ÈÄmLJ¥ìBx¹»õ#9,”m©JSuÜ>­C ®ÝÖ‘Aĵl&¹*rh¨}ƒDºÒª.‡|혛¬¹ÆÎö¹Y«l_®GEuD“ÐX® óê{´ˆZð¬õÒ!0Ëu ˆÙgµ¼‚ºažu¾èÜí¯`艂\ìİá1K-sgÚcz¢‰] )ų.òz´c^•œ¯dÁõ^E^‡ ‘n¸—`ˆÚ!Ž‘$±DZÂRVäX¼4ûJ˜á°kx5$ñ¯VD@ǦW<Ïù"‚dÇRÒìDzÃ#±%õ³G1¶¸EZ"cyöü4ºH5j­AиŽÌ ˆÃ¤R  0G¯b½ Ô¤ñ¶ˆ¡\¬ ‘°øo½‚cÁHMi$i£´ì{‹’¦Aà2/‹z¼ì:b½Ô vöb$ÝZ"¦ÒvcÅÏ#p–ª­ß‚,_Yr@`K•Yʈ9ßE ‚ ãÈÔÀÎ j`çX%iÄ 'KbÒË­)Hn@ô—•Ý =¼‚çf?à"& G‘ÀÃ…oâô(;Â)â‘}–”š2“8"P©qš…°?‰¢×4ã,l8˜4§öƒ ¸°Õ:RG-‡ /3žH^ Ö´3U¬Ô‚ö­Ž ³år|Z ×¶Cësû¦Cà‰JšÖ"á:²^Aº C熺 ð¯. Õ­O82h{ŽÞ0[ö³ŽU)@ö[¥ubFæÖ °ö2—ã]‘C`£U¾"U>Q±îxgà1;†¤ í)ì[ã‚Ì'–Z ©l  >{RÝðÙd‰,‚*!Y•.æ ¨v1÷*JR&:'ƒI\'4ðP¯›ÐÀƒiìa=ø†¦ÑðËE fû  1›ŠMDx@ Ò†Cã[ ¢©ES9>3À4EZ\LS¤ÅÍUN]ˆ”j{Õ"?æö÷ AÎ缨ð¡ ÏVTØÓ*¥}ExžñQvû±惫x¿;BÄÍœcáÐ"p{&^bí™xÁ½m€‚z[J©å†gýH@”Ó°„)ãsH? 7tâŒ:²F)¦¬¢ò­ˆY”“Nh»Å½m¼) 7Þ!VU/Ðfye–s1³E†›$á¢Q{˜6`ψ"­Œi–Þµ¢·j ¾UKª}¾PÙˆ©yÑOÈ>W–Ù~tÅ‚Ü&Úot›@ÚïŒç‹”-˜GЛ TÔLã› ûûfDÆA c„L†ï³r¦n_  •¬1H½ÜåíÒP-"tpØ +:zpØK/šCt²´ÿ¯"·Ü'Ç–Úlrn´-å¤iµ\Ã_§D“hIÙ[z$B‡ìmèHT—£TÿX†x‹ ý«Ï³’+-Æï‚Þ ,øèevƒÀ+P™}ù%Ò"HŸ©õx˜x¦•kÈH•/A‹ÀD#"‘|©99üõIAyÑãÇf‡ ‚I†M@‚x=m♑Óf›_D@Pýå“Èo±v›Å|q ôKmߩȢ2¶WòïrÕ’™£W‚Ûµ(ü÷.†W üºàYÓÞÛG k¡Ä‹–•uåî<óé×ùÃŒÝ+{˜°¹Ü{èõÍþ‚);ÖVVͳ}lRëJn„Wöye%Mí]Íù¾¯ ’øW6H—<óo^'WG¯ ½ppÓmž7¿uo‡þPKA_†(¯6 @o _.dtd/isoamsa.entUT  ´ì8 ´ì8Ux†>M•ZmsÛ6þž_öf|íŒíX’-™m&s²d_3“º7V2é};ˆ¤$L(‚HËö¯¿ß@»Ò]>86E<|v±Ø—G|÷ᇋ‹wÌü{YÊ„–|¯ùeš—¬P2©â4aëWVîRöçê3Ó±EÉöû,)“Ë5k7Jî™È‹ªd /9üʪ\Ä2I/_öÙ廿®e)×)Si!UÉxþÊR¥¤Ò¬”¬¹cÉŸEÂ\eB›‰ù;þGη—±¼¬¾ì ¾Ÿ¼Ú§JÄ,ÞqÅã2Uì™gUª×Zls ¸)w ¬åk³ò'½“U–üÌö¼4 0M1¹ÙˆXðŒ}mh·{X©›uR ¯ç< -dγì•Áó²÷U³¤ÃZÈ\ƒÅ¢Ú³58 a2¯ÚׯaæÊV_>ýù÷f5<¡ÐÀhO®»~ˆX_²GY¦p7/ÍPÝñgðŽ,Ù:Ms¦`ÙFØmŒ¥R©.džˆ|Ë>­þhÅr¿e™^žÛUš5žø0×"I d‚¯akJÙ.Ûñ|›vÛr_;šå|Ÿ¶6 Í6&°¸Jˆg€¨£Å\Õ,æJ½½Ó6|y0—À§¿´Ð?-~fŸrpVö·³?Ô–çâ­þ³öÒªê\%ݵQÚÈKÕ^h³]&&bY¼v&aD®f[Ås³§§ .:Çäæ&ÃhõÏßá¼ê2ÝëÚM¼(2×O3an„ <‘7kÁ»ìöv7ñ’˜˜4.iL3ÏyœUI½ÄD‘á&R þ¼¸øøî݇î¿|úòoxØö \Åú?žýíåj<™-~ý‘}4‡îÈÚ,‘‡œ½‰íÅß‚ã•<0ƒÖƒÅÌI˜6¿èÀàŽ8KÏ™¹mf@nV™Mn;€,Ý”çpŸ‚ý>oaDjœÀªhrÓá(±ÝýO@™ãht7í€Þ×õRÃÍaõÿ 2Y„ä–½—šµ5NP»¿ÈàìxP §7CèÕ&~ê8;¹Ù-ä2+È;MRaáo Ígd‘…æN"ÌܰڛõZ„¥y6ÁÖÃV„eHa4;g¤†¨+Œk•¹ZUßn"bÕEXµ²9±üÎYžÈjÝE5†²Æ3æÕÂAY+ØhôŒfwÀ}HãõNsäŒE“©‡•„n²D%N1êJÑÌAéªa&ŸaÜlR¥sÝ®ô¹ËºŽ·ë…M­ºh ÀùHЄ„†ŽîÆ¡¡õJu<î¾OFuò®l ·U¾R š&œø‚¸j“İ7*4“MFªk§þ{^ VÍívÂ-º”a¿ã+£«~Nh; HW-„ûd‘8Mk§p<ôþ„;λö´Ù¡òØwÍà­å^e¥0wùìsä‘6'÷=øãý‘–Æ,Ç"6²ç¿Ë="ÈlÊ®oisÏ·ã¹ç@äžé€ËÉÜsÈñÜ3€œ±G<åHâ8ßÙãÜw@¬ó‚ÈQýBçðjîqL±uć®Úôž2w󭇯>(J}°tžÜ´ÐP¢õ‡'JÁµÍH[}]\—\æá\Íú ΋BÉ( eê*d| ½Eˆ†ÉãžÒ0 œÒ3üt5ÈW–¢¥ˆÜ#'¹ ’ˆ PsN½<¦ˆ(JL1"2ü®D!ˆ\ß Ö†Šˆ¢‘k•D%‰X…Û:©ÓDÔ1Eä GŒFS—UðUE-n†c®_¶BYù="j*ºv)\²˜<ŒS„¥Ù,Üõ'DE‰6Ö®õwî$ZxQ”€cÛŽÄG;©æ< #›±eQíìp’-%Í|Õ‰T’á:Qä„BÑ DQêÎáGË;Š’w¼–Ðw¥ï\ãæáÓ#b¡ð,Fîò$u ÓxW(f#ò(zÆU”ij8n;!(Jã¹vé¹"² 2Ò¨ŒP@!æPQÄßqJçñê%ô(Jè‰\JžÒcÄ,…KYŠRPl¬$‘W¯‡DÕØ:µûL=D"Å¿Šìò*àé’Îô¿å¿ä0Ä/tÉ®F|FÖžBØ]Ž1Èßÿu)ê}©ðU©ÿPKB_†(=º­¬ Ð%dtd/isoamsb.entUT  ´ì8 ´ì8Ux†>M…šmoÛ8€¿÷Wp÷€»]Ày³“&n‹â']ȵ ´ ì};Z¢mîJ¢—”œdýÍ%’C§jI>çTß|øáää Ã?Ÿd%˜4Š×f}*š–íµ*»B”lýÂÚ`¿{d¦Ðrß²º®Ê¶<}6•»Ñªf²Ùw-+yËá’u,T)NŸëêô“úµÜ¦Å^é–ñæ… ­•6¬UÌIÜóƒ,ÙŠëJÐæC‰÷Å¿¾=-Ôi÷çÇõôiºZhY°bÇ5/Z¡ÙW0Œ#· (\Á‹ƒÙÈöÅüÉìTW•?³š·ø•„©i¦6YH^±ßœÚ=£†‘ÆSzú sFª†WÕ ƒTÁ[o+7d`­Tc`Ʋ«Ù P2ÕXƒzÅ  ŸüïÛ÷Ï¿ÿˆ_ØÐh¿ ºîü# sʾ¨V€4oqˆ!TÝñXGµl-DÃ4 ÛÈq ¥µ0{Õ”²Ù²Ïß¾ºA…ªkÙ¶x Xn׿,ø²1²(•äkXšVõÃv¼ÙŠaY¬¡YÃkÑÏI¶AÇâZ0È ¬·àSà ®õ êá¶Q`Ë'|3…x×£ZýÌ>7`¬æƒfg_õ–7òo{k­ô­Õ¹.‡gËåEïyB×Òàr¡Ojÿ‚Ú¡Â8ð\öš7¸~ÈéÀ¨OàƒaB¾ýòÓŠÚX3ñý¾’…ý5t;˜áF¢ãÉÆë²››ëåÌùK‰>‰&qSÃß•MQu¥‚^„ºIaÀž''ß¼ùðÃ×ÿ—ñ‚…~üç?žÏçËóOïd1ˆke d•‘-ؘáèÉàrðý9xÆÚ'ëÜÀú¬,FD«yµMi· ¯Ê™¹{çdyí–, ³³I¥ ‘k®àx1r~w? AbÆP&÷¦KÇ­¼*Nd+P›Jma±*\¹Že|­b[ÝÑÈÅù[,U´\W9ðÚ¨jM,Âêjkq€T ʲ³ñcþê0pЊï©ÕœßϽ†(Ò«YÀ%hˆŠIŒ# »„Л“%½¼Ó±3ëú1`­‹nŸ–4À.'TB‘"˜ÞÀ¹£9áÝÊ_Bì(â5EìŽÖ¬„ŒšrÎiÍ00S µvóå{{qþvA㠤Ή`1mPÉGMQ)cSË먎F­"”µÌ†©ÆÕù1|ÖÜì™\ºHÍuá‘g½Èã»InQ{EÒM7]&ncÜtcÜt>n(oèÐßyêï7«Ÿ¤uô#×eüýmÀéÝò8‡ôòÛHŸþƒŒ”ŽôðùÍ}Äȸv]åBWÑðx]b×ó1q›ÄÄ1ïë 2PV£«tºzA)XW{í BªRX<ìSó Ä%é±äÛ­Ð þŽEʼn Ë¹+-*ž.ô}Žt1’&(ëÊlj¥ä5£æz9AÚE$Bh5l¸8Õ<œë [ ="¶‡¨Ÿt=´mˆíÃ)öUGe¥k?Yõ±‚æ å‚¡ÐÓCß–jsç Ò[ÂVò¼?º-tïØfkù’ èpMS’­3—(Sò×!$Êc¾gZM!V(W©Èý¸¹Iû=öÿØ.TbÓB÷_mX!uQ‰ælœ(áWºîªVîÁ“³ÀˆØî4Õ·­|¹>C‚•ò‹B•†wEd>6ôåíØ•ƒÚ$«‹M8Äîþö|Úä;³$ø'mÊâ‚ÌÁî½Q,‡x³ðŠY‰1%-)£\=L7söe¬–¼ÙÆ)ž†›ƒá‡£ó„c2e-–AM;6žêÍ–+ï^Ã8=šÕ¶ªNHh¤T“»d-²Út™ÅÍØ)vdŸH$‰ƒa/<ŽG½Èäå¤ÒYy%Å»½ò}=ÎÇ-ô.Õg|‡uöduéÉ ñLÍWãëǵܢÐã»0µÓ1ýlOe÷ýðú£›`×qÈ©ùjp:«—[¬ŒB%x¡Ð˜î4xO©žT ±Ò:ÕÌ’‡Ìøø&=½€Â7Ynzx—Q‘n#§Û^ÄY¡‘gosÀ0pˆí*]^‰î>ƒŒ mZgé„£R›!Ʊ™†&»aÖÑØÌ¢.¨EuÕ—®rK½oòþv1%¢Ðcð?r“sï’RÜùç„§Ù"äýPKC_†(X¿3u‹Ö dtd/isoamsc.entUT  ´ì8 ´ì8Ux†>M”aoÛ6†¿ûW\;`kÄMšµ» Øê$C€­)à è¾&OŠÔޤï×ï(Z–KÙüÁ°è{ß{ÅÉÅ‹ãã ¤Ï6Ú;Q{9E !§¢DË5„ áëâ7ð’t ® júèMÖäj扔‚B´Z:…ÓÇÚL'¹ê‹AáG„]9òäŠ+±Ò 悌öÜÍ…JÏòg+Ê©tÓøpÙ¡î¹k$-AV‚„ H°&¢á½.-7Î\²>ë¬|å+z µé/ÍG#pE¡¥þÈmo5+}Ö9Ú]K欴×Î cÖÀ_Nаõ*K:ÖÜYÏ'Ö±†% ÀÙÖÐmã>–VþZÜß~ý!«y‡ÆsGï̽VÈ_Zú)|v¹Z„$ñ­VbÅî¸KD IJB÷c”Ž}ã¬Ò¶„ÛÅ]IW×:džeçªè!;ÅþÓz­˜b´Xòh‚ÛÈ*aKìÆrÝ VÔ¸9“öP¤` B`€^1¢MKZõ Ñ:õ±5­pìå·´Ä'Ð?nЯæ¯áÖ²Y–Ï“l‡;*…Õÿ´­K‹À­ RÝÚélvºIR­}WÊ„tÍ:u—È:N®‡’„MóKœÈ¦~ã\tÆØT”:Züú;¿k°ö­M¢iŒ–ín)v|ÂB§ài›µì.œŸ˜弨”ÉdI>ZÚW[i¢j%)E©7žý<>¾œL.^\¾¿½ÿ”á±Yè?/¿ÿîñäíÙéõO/á2½ÄoL[ÂY¾ûì ÿ0XØ,&\O£ÚMO£pÞÑH—Õ0® æ‹ Ülö®Ã©¥ÉÝ4œ›b«ý{Ž"<…Γ‚ØikA\eð§|_¾¤ŸÚ“/ùÅ{Àpøwä( ¼Q‡ˆ›a„wF+~]–.öC‘WÏ#ƒk†yµ9<åÙÉy?À¶$e¡M?¤ïS ãÜáÜÎN~é)¹¤Ãä§}Hí¢óÚi¥-ዟH9 fHzÖI»}÷bcžŽ<ÐpüÞïÆ/Çw„Þï£h,|o;TÆŒ¥ÆÒ7ß×??‹ßõãäFò7;ùæXi,€³íÔs _›‹c(4–ÀO=&—l9¤±~è)#$D9$ý±“n7n£Ã—Ö“‘DZ›y;ò7qçfŽMóÜÍÇn櫞¶s3gÚÁÍü/PKC_†(bû©Î3Tdtd/isoamsn.entUT ´ì8´ì8Ux†>M•™ÛnÜ6†ïýl ´ `»>{AíxH“vô®\‰«%JBRŠÝ§ïŒ¨E ×n.Œ]-ù韙ŸäHÙy÷ÃÞÞÃ7R &MÉsSì‹Â²J—iˆ”­ž˜Ýöõî3‰–•ey®R›î?åæ®u™3YTµe)·>²ºI™ŠýÇ\íï¸Q(Á`ZT¥¶ŒOLh]jÃlÉ܈kÞÈ”}àZIjÞ¥ø=ù­àÙ~Rî×ÿ¼ïQ÷ §¨s¡eÂ’ ×<±B³†«ZÆ‘YÂ+x²a´Onæk³)k•¾a9·ø“„Ð4+×k™H®ØŸNvÇÈa¦qóJí_Ãä4ÒȲàJ=1øS&ܹrSzÖ‡²0±¬s¶‚¤¬,Ú„ & ¯ü}wûõg7îPP´†;ƒÖ€?21ûìsiŒæ§Bê†7Ò²•Ó0m-Ç2&¥ÖÂTe‘Ê"c·w_ܤ¤Ìsi­^™ÛÔ†¹L~,ŒL…Š’|¥±e7mËLôeY¶‰fÏE“4lÆâZ0È­[ðªa ×ú u I[—Ëïx "‰xÛ¡_xÃn HVñ`ÚÙñBþÛ~m³tgA:×iíðââ°sžÐ¹4X.ôDRVO¨óÀ¹†ešX?äÔÔïà‹>1BEw‡%ðd¬ÈM›&^UJ&íÝÐváZ¢ñdáæBvÙbq~±ëü’¢'1%.4¼¯,U§ítj“Â@>÷öÞïì¼ûaùùþöþ/–¼bþ¿W?ýøxpt¹¸üõ{‹øwydŸßB4ܨw[¸Ëì#R=¨`ôè샊o3 øVseBÖò%¬9,]©ÐÈœ.Ï=  pM*®Zèåᇃããňm„¶ƒV»Ëð»/vŠV±ÒŒ‘+¯4àzóL]T¬. èê2Ò¨ªXQ¦ €”–5®p)Ê™ìŠ2ÉŠ¨XEóŠ(¿"Ž»½&aIzøÉX¯$[‹ã(—ç3Î…6‡xt¸°÷„l8î™W/`Ãn»mBaaËÊ(ì¸tÜ.vü¬k<òq×#X) Â?»&%¨]†“¦(H‚lˆŠ²ÜN×!¡+£×Èùa«ëè`y:R3·XÙm{p~{¥Þs… Ðôª´O ‘»Ñ­ F›‚#h€Z§n—µ—ဘ"?f¤Æëù~†4 ],éN)6E(‘^Øç§>fˆ”\ÑEfIMg7^˜VS•ƒ‹€ÈeÑïy íÜ–?Úæ9¨sÎÙ±ó ÷ãZb©¦|1äaH5·³­nT7LpÞ+ªˆ§´‰[…¾ä'E[q¾‘{VD(U%ñá‰Ïp1Ò&Tï,ýáÞaúà"˜Ëg- "'ˆË±ƒ+,ú*SB‰µ—ýu›´ö)ä陉»ócóSd\¾` qÇH>=ëzøÑɨ‡L'UP`jÒØpà蜅ꃾ¤)¨'-<çWZ$>‹T„ë§ÒIM¥ü`r Öèž@ä~"´\^ÞÌ{ŸVÔX9J,o1ÙÕÜZf›Áe:ê1ñØu„8JÕ“™„.„wš: Ÿ…HÃHMBâÐ/D?w·+ ¡…,ÄÕ¼¹s¢ÆèF4Yˆ`Z0?H×'G;d (ÆÉ„áIr”˜¢œì5aù…K°›RÛùb4Ájc.Íö".ÐüÍÔ+1/&›¬°`áÀP#l,J Ué˜&UBoaÕ+Ò¨'S‹¡šùLªr‹‰›pžï§mQÕ«å y3 ù|‘“¡NCsé™Ï%ƒ»ðÅTApÏ$º"Ã#ˆ’ ÐfŠ ðüÂpègÛ³+¨Œ,æHßN ùZA·tñÇÐ&åf3Ç]zg½ÒåyøìùÁ«욆y›º2‡A² àCD×u=øê³UáCD¡÷,ñpM£ ›ŒÚé½g0¯ /yHl‚§ÙÃN„b-ë€À<û¨Ð(ZÓrlΘøcO¹Å¶“&5²ÈMƒÉ =Ø5)Ï‘ég†“ÃmdòÈ…“iÊêú›áøèO´@¯žú(Ç;8ïåÓØÐ¯xfLò ÔÕé”ÙmŽS µ9Šr&²kP¦@2l6÷Äåà<-Ü®Ñã›$’³qûÇfËËÙØ{ÅrL:ggSf—³)Ê™I"9 Dv9›ÉœÁÅ‚lï‰C?{¿kJµštdq|MWmsÛ6 þž_vwk{gù5Iã5×[ã$[î¶v7g·îÛh‰¶˜P¤FRvœ_?@o¶$Ú‰//¶ <<¡“Ë7Apôº’ƒ°š%V÷¹re!`±sø>ÿ lhDê Idä¢þ“•…ïÒè„J3s ßB¦D¨#ÞJdÿ¤°úCrf9žj〩-pc´±à4×l-"˜1#…Åh.#úþ¬Øªê~öø¹‚ºÇxT–p#BcfXè¸5“·À¬+…#.ga ˜pÛÂó½u&£0G_ LÍ€^.E(˜„¿Š°KŒ=má§Íþ5"g-¬ÐŠI¹ü£Cæj® — k¦•ÅŒE–À ˆ@«œÐ:pK„Ñ•ç÷wßßÞx‡ÔbDK¼3Æsü#BÛ‡¯Úq´fŽ\¬'Ô˜­‘í`Á¹ƒnK±+c¨á6Õ*jwóo…S¨“D8ÇO!sqf¡` QðKeEÄ ¢HÁX§K·˜©¯Êr“ Š%¼ÌIXX’°˜á€b¹Z誅³¥8jÒ–¹ÜÐ%Ì@„ü§úýìÜ)$Ka>D;|3+¦Äsþ1giî0tf¢êÚh:•Êã&–ÊEšuº¥èHè‡Êµ°2LQý'CR7¨‹ŠEFÑü—ß±¶ÖñÄæ4±4•"ÌïF²Ã —‚„'Tá‹ìÂÅÅÇi¯ÐKDš$JŠÔè¾B…2‹rRÅ&¸E>ƒàóÉÉå››¯÷w÷ÿàÍVÐx½ýñ‡§áx<~z Ÿ©‰h‚<PþG÷}oîñž~9­¼s§ðÿ2$¶í›ØÈsçQ}çÛ:Cm4"ª«>8Æ:¡\4B©½{¨£7=ÈÒ±ŠoÑÁ›¾Oò¥.ìÀ}y.Òu,À¨ƒxõ*ă!òàìÀ<8JÜ‹·ìà]¿€G¡„[uàn^¥íEŒ;ˆ·¯ Ð hÜz'™ pzý)3<ŸTÈEA_4uê;½>†AaµêºX˜GO“N®Î* …v'§Å&ÅiºÀ³ã‘·Ax’ºíº“ÚU=' _ãƒY„„ÔóV2·Q\ì e49¯{>7 rËüʆoZú º3gV7¦ÛhxÐù¼,R²-„Ôˆ„w†“³]HAa@™”ŸH–'¢›Ïðô¶Å aj©[’ ñ:®tâ¿$ŸæùE` ½n…„ßÜx(žÎ&m@¢)ÖF1JéŒgPÝÖëîÆø¸’£ ©g×“Æ 1¾ºmB}îÇHbíí‰ñN2dB®ð×î°… Ú ën_ÍŸìÚEÜ’NÏ·º*þ$¬ó4BMð 0ÁÃWùCXuaHÏ›)•@§³ÝÜ)JÍ)1– š¶sÚËËÙ€K%S]¸Ñ°¦yÓÄ ð©éy|g«m`œ P·Ó@eWãó-•˽i‰²s¶”¢,7”Cª4íç‡j;kŸ‡# gÍ9[€zküYœâmOwh/ªàtzt)ÊuU]ú,MwUæïª³ÛiâXW­ŸÅêyo1®7깩 ðqRZd*q;j‚l¸à&í2íd¼Áþ&;ܘµPlèÿPKE_†(ø0å 97dtd/isoamsr.entUT ´ì8´ì8Ux†>M›ësÛ6À¿ç¯@{3w錟Rüj;£%¹“™^Û9ç2½oG‘°Ä| íøþúÛH€NrùàHö§Åbw±xèÍß¿aøï®œUªÍk%OxÓ³N¶åPð’m_X¿çìû_˜*dÕõ¬®EÙ—'Ÿ”0²²­YÕtCÏʼÏá%šªhK~ò©'oL«ßÏg’w­ìYÞ¼0.e+ë[fZ¬ó§ªd«\ŠJ6?–ø¾ø{“ïNŠödxüiB}}𡿲*X±Ïe^ô\²§\ \±\©j×€âÀåy±gЛª1’oÕ¾Dù«ó?ª k’µUQå‚ý˨=2jTF®•óghœ§JUm“ ñÂàO[ä½µ•™X«¶QÐãj¨Ù P²¶ÑµŠ+4>ùÏý‡÷üÍHÃ7t 4z€o]÷þT…:a¿¶=‡Öy"ŠPuŸ?uÚžm9o˜±‡Ê cÑJÉU×6eÕìØûûߌPÑÖuÕ÷x Xn?(f,ø°QUÉ%PD•oahúvÛçÍŽOòцfM^ó±O•bèX¹ä Õ ´·àSÅŠ\ÊÔÃí¡[>ã#èAUðïGôÛÕwì}Æj ?hvö›ÜåMõ_ýV[é¾ÕsYNÏÎonÎGÏã²®úDÑv/¨z Èç*¶“yƒã‡œŒú ~1¦ÁF¨ÑýÏÿ€xQ=¯•6SÞu¢*ô·¡ÛA*t¼ª1²`]v}}usdü¥DŸD“˜®á÷VM!†R‹ ¡nW`ÏããŸÞ¼ùñ›Í¯Þø7|gÞ¿oÿú—Og‹Å»ì‡oÙOħ ‹l?ñûç÷̼®Àcøã‡!Š!pÆÛ|†7C€ƒkÆ€yF p¶î–Æ%ÀS Ф^êŽ"­]Guì%¾è[ ²:†ÀÛ\>ªe›« øÄeÄÊ­€è”ìm ï¿ó[ð¥ÔÊ*µÍ‹GÝ ô’JGÍN˜J}ïTÓΗ> [ pXª2•ŽxÔ>÷ÕZ];i _RU55^˵§¶šõÞVL¡8ZE(ãš Ý3¶b¯†­<;»Xý`È׋‰lY­¨ÊA¡¶Š‡V|‡²ƒ·± ÞB£6~!#?¡úùîÎõ“ÄЈ-61.ˬVØ‚–-*É©]X—>…&…Q_‰DXµè`„8nrÄúgL›Óœ¯ >#\ðâSE71ºXR•”]YPÙ8ñ¼ÂÀx+aÚ —ÖmDB¼·ŸsŸ›I¯ìï:b…hq¤ ÷ÈÖç´t¢j |5[Ÿ9J‡.ŸÖ‚rÒl½HÉ'ôx' ÇX»˜))^ø¡“¼ÐC‹o…3‡¢‘ÇDUPÄ»É. âÎË€XæjÿD³¥%š&ÀÂG ½žt<Κædçy05¼F€ª«Ï8ìì§m|Ät»J=²| ³L@%†~qqi»ÃÌ.¨±ŽG+À÷Ä»˜óÚq†™R•yàƒÖëyL¹ÈtI¢„`R&ÄÍ$ŒÕ”RƒÄ0S!ÏÇYÅÎ*Üèé_.xꔳðTpqaþô „J'åpãCŠèMö®Ë7™7 Ç­<ÞIžãàòŠ’_¬×3Û+ç®—Öj×ÃŒ¨? C˜^n³:]§t² “ì*]ÂP‘èèM…j=´’HôröRËênN¤T'E¢“W¤>_ÒÃ$ž˜¸¸pyG·ˆ¼W?…º¾Îåc„¬žÖë8 æ#QÁZTÏ3. ¨ — ×u9 òE乿å¸ù,ïÌ­yÈ# r R&*Åw.¸øX&: Q&nhNvµ r$) °GÒÕ\™ÑU°œ×í@÷&ÂP©~mÝ[@šÏe•‡e;¬ZŸ‰bi¹˜¥Ýçü&°Ðš»ÜŸÞ§~8+œB0k%äØHž-Ÿb°Ž›ˆ—.;ïøáàÁÆJŠšøwaF˜ };W¦ˆ¶Ìiðã4±Û|Ò1ÇÕØ+HNfžìj3ï´Î ˆ cò/*ï° ª“,³Ž1åyX…5¶öÚ¾˜A»Ÿ†“Iíú,€#†?ÓÁÂeŽÓÝnÇN¡¾0³z/«â Þi3êÒSïbVV`gD¿ENCvõÛô3ïrŽˆ ·ƒ²›Ð‘<[…Œ?i=bûn´Hl8•ù¤ÄœãgÉqÖqÅ5qìè݉ìz)5Ûˆû s†ð ÔÏ~Ýërõ,ê $Ì~ó#Êû]ï',kí«/ÊX¬"–{ÙU–€™å™’zºY{nmÜØT]vEËò]Tp“n+Z7¯n£R̯2^¬Ý¸êÍçÉj·‡T&aj÷Aû¶î÷De¹´£ -Ú~ÏaÅèKŠTà* tWLq›¨DÞS¼,³š€CîÆE¢ÔVR–­)Q»ÿ1ÍÓ9KdÜ0#Ù`¹œÉ6Æ<¯T5"\ÐMN™yç‡1qO9Ë;±ùBœÏ35MŠ™*iÖóîÚ’‰³¹w´a„¤‹ëé:EýHT4WwsòW—3"UΜ1–ø‘*#êò+©&„lßœ'D®OÔi_Ø‘•Ì—Á>3v‰JæêÒs^Ïsi-åǤ幯¥¯•Ïø%Q­Ý 49Âü‹¡±®²Ã蕪üì:–ã6U;ˆTí°ö;øZဠâä(»¾K0HSÿ’*f G˜u§ÎÎ2qá R…Ãåç³BD¢«†Š”.Dªdð=r¬fLº`½ 'xªƒzqBLî"UuÜÏ•–::ºu»=n8ìG}ø8©fÓãø”¬Æóú(LépsG Ó „3ª›PÃeƩڷ²§¦W€b0–³YÙ4Á¡£ >U'ö줧êªtj£dé†)Kï4 „ÜiXEv i‰%‘êròè}q‘0/´Gº.¹õfŸøàCp§d_Ï‚é0ÞYBè“&u‰I7#îٸŖ%™bÎJ¤‹CpÛdbžyÌ.ÔÎ\ !X”~‹ˆè7]G óâ}pÇ® œv÷Ör㺇´Ü°ÝPœëËYB3vS¬±X2AÂ8”Ä%£•s=ÏæÄM#hP‚@Dw…°¬u_"ùN *’¿n*éf¡¬¿ÿ9­ŽnBÙäÆ'6ðæˆIý«AO ð¡7¶S™á‹ÕEbL}×Ë‚rÙûÞ…u7¶ÀÁ&ç7UéùCWzý™t¹vºL>n}+W{ög[5ãÍç:BÒ.{5sÙnî²Ó¤¶£ö]¬ä+nÛíÕìLЪef¡³³ÅÑes5“ Q6»JÙ,’¤߯ò©>´ ƒ¸*— ÃŽ ÃqY ÄŽŽ"Êoè8êè8ŠÆôÕHêèHºLB¨ è÷9ykû:žAû}U<º¢[¿MÜ@¦Ì´˜]–Ö„± 54Ò^}Ûù×H¦®ÚêE¬·; m ,µìÅš™ã è0nQÚ›8ûçêµõr9»Îûgüõ^&_zˆ§[²fÉ6Ö}‚kízýÜkÿ¸M@¼MJBžÂöäfÙb‹$}ì«KgÆØ0™+#L0ËtsL§>gà¸}eÓÄçŒ÷<#¥trGÿ'&s¥ôú˜Ò‹0ø+ÚÄ;Ùær>î³ï+Úf™·ÊwjÜÎÌœËùž¤Þ‘4»mÇ}E*`ân Á<_ϙبoÍK‹?Ó?åIܸz’ 5—”š¦^ÁŽWõüúØ4nçî£õ±ñ¤ÒÿPKE_†(S§ÃE‹{dtd/isogrk3.entUT ´ì8´ì8Ux†>M}–mOã8Çßó)f÷¤»] z<»ô¡+- $nAj‘¸wç:nc‘Ø‘ít[>ý3IÜ›¾¨gæçÿ<ØñÁå§££ð¿[YV/ÍëÙ@(•ÑYÍEó ¸\ÀËô,7²rP–Eæ²ÁÚä»0º©ªÚAÆÃ!ÔJr‰Áº,dõTfQi〩 c´±à4Å„­dcf iQÍeæŸùߊ-\ê׫5C=ª.…‘xÎ ãNX±¢˜µr©P8rã9`4ÒmÈó‹Íu]d_¡dο’š½XH.YÏ$»e”èiÉO›í9Ÿœ•´R+VÀ?Í™ësE.k¬•ňe]ÂVMB{áÖ'ÌÏü7Ý¿üFÞ¸BeQÑWF­¹À?Éí~h'К9ïb#Rs¶Âìhs!t[ÈPF®¶Ò*“j ÷ÓGrâº,¥sy 3—×(SHÁ—ÊÊL¤’ͱ4N·n9SKÑ•å¦I4(VŠ6&iaá‹+D4Ýâg-pfÌÆë蓶И˟~ #\üÙ¢¿Œ¿Â½Âd)ŒÇ§Í’)ùÖ<6Yš:”ÎLÖÍ ‡'mç SJëËå{‚ëjãÕùD?ì\ KÔ¯ŸçÔ˜ÔŸØ]b”7òЦwÿàØX'JÛ¤‰UU!y³šo;Œp!}ãIE¾˜]¸¸ø><¤~É|Oú”Ph~]©xQg‹ï"¯M ‹ù<:º:8¸ütócv?û_U9ƒ­ßç_YŸ]Ÿüõ®ü&þLlé)ÍøîŒ¯àI=h.ܧö Æ„8~Åð\B 3þÞc¼ Qp…d¢pÑ þè!dB˜fM a‘ g•tØ:“$JTVÆ»>ïQÖ&—¹ó¦…V‡­¼þ1A]½§žž_÷Ôî"ì¹îÕ«2ê•*×’•e4Óg=„LÓŒ£ »h@dÒeú.‰jÉÞ£&ãP}IªÞKøÐ¯[;ê.ub ûeÊ„FÕ¿âÖftÔcÈ„8Í8 Z½Ýo·±v VÎ3Qzª5! ôÕð@ ª5éRû†•õn¿öºB]Ñ„4•u¡RˆIPBźËX}Æ¡ÌdB”f=&@£"“.5IT•:4¿½;[¼éQ«­JŸO Ü(à¼I§ë)Aü*†™œo7 âµÁÛ~"u…7‹fnµ'¨0ôrÕ}ªDP Ä( ž¶bJ„´QÒ·öÕÛDy.‚zÛË· ý È(@¼I@cr×¾÷Þ„´à(‰Vööd; ž³ã†·Éè?g<™ÐêÍ8ºþ4™tÙ˜&QÍ"‘Sr|º ÉÚqtlï,éÃÕÀ›P(8ЮޗӸE%•LºíKÝÍ }ˆ€g ð0€É¤ËÐ,‰j‰dh²Sl’¹¿‘ÛÙm\¸éP·× ²þàúóœ€MBõž[Xèó¸u⌸¾éqënŸ®ãûë%ÄKØ¥/qÈ[ê.Ž™·p7{Û«ÜÿPKF_†(G’2ºI¤dtd/isomfrk.entUT ´ì8´ì8Ux†>Mu•]SÛF†ïù'éL›Ì€’¦–a 6'|%6 äªkie/–vÅ®dl~}w- }ÏôøÂc¯u={öÕñÆÞ‹­­ J¯cSj2ÁU…Ÿ÷´m¨ö.o3ÓdEÍLÓõè”BæMÝPU•y“÷–¡ìj ï*2¶nÊU£âGj­É\®{˪ìmtW]–ZM^×Î7¤ìŠ´÷ÎjuW ÔÂäÔW¾4!Úìåé{ö—UÓ^æzí|ÿ 5Ž>¶­´7e3åUÖhO U¶: ÁLm\­²ÅݘfÕU¾ 3×–ùkªT“~2qkž\Q˜Ì¨’®:íGF+CWçü×Rs&gUY®(¾¹L5ϽêJžX}gCܱi+šÄää캡Ïâ!5,­ü=¯éªãêŠxçè:ÓñÍd¡Gç®ÑñjÕ¤’ð?ª3µˆÝq M´¶äcYaþ=ÆÌy¯Cíln씆£‹®(sUešFGž›µºNEJüÑ“k)¥Q“x4{,›);ÕOÇr´n4YUéÇ=™@E –òš"À,"b–´(SÞ¯’ÇsÓ {yŸ–âL¦ÿxD¿ê¿¦¡Í²q?©ítá§Êš‡õ×u—FMTW>ZÛÞÝÝ~Lžö• é¸R&2W¯’]J`¬‹É 4õʦóKœ66õ>æâ©16]”ŒF'gñX…FWaÝ&U×¥ÉÖwK±‹;,L ž±]mì.íì|ØÝìò’§L¦–t[K÷56+Û|]’R”ÜŒ±Ÿ[[û{/ŽÎÇÃñ ©Â¼^þüÓr{ð~ûèÏ—´Ÿâ_ ¯æ¤6)v/:KOš¢Dy†7¿!ä`“Úº Éä!0™ äP2yC0aL€¼}ƒ L2„ô%“ßÒÉ%“m„ä`’#d ™|@ÈLDK&o¢ÁD#äH2ÙAȘ0H!™¼CH&BŽ%“]„ƒ ƒL%û)˜Lr"™ äLd&™°ØÏÀd†’É!B>‚ ƒÉ„ÅÞ€‰AÈP2é#d& r+™°Øß‚É-B>I&„|™K&,ös0™#ä³dÂõg0aR2a±/Á¤DÈ©dÂõ)˜0H%™°ØW`R!äLúË`ƒú LÄJ&,öL,BÎ%6¨ÏÁ„AœdÂbïÀÄ!äB2aƒúL¤–LXìk0©r)™°A} & r'™°ØßÉB¾H&lPñ’ ‹½¯’ Ô_Á„A‚yÇbÀ$ d$™°A=i$ûL„Œ%6¨Ç` ­dÂbß‚I‹+É„ ê+0a…dÂb¿“B¾I&lP¹—LXìïÁä!ß%6¨¿ƒ ƒ,%û%˜,r-™°A} & ²’LXìW`²BÈdÂõ ˜0ȃdÂbÿ&ù!™°AýLhMùPKG_†(Wò/ÇVp dtd/isomopf.entUT ´ì8´ì8Ux†>MuÔmOÛ0àïý“6F7ÆØ`Chô ÊK ´@áÓ\Çi­%vd;ݯß9i™ÍýP5nîÉù|¹ÆÑÆÎNü§'3Òê\iS(…ÑIÉEÓ%¸¹€Éè,7²pçYâ’æ³ÍêØÔè¤*J s B©$׉h>çY³Qßu fQh〩%c´±à4ÔwtØB&Ðf&“³9Jü5ÿ¡Ø¬Éu³üu¼¦Æ˜*sa$>g†q' ,XV ÌZ9S˜8º‚ñ9àn¤[Ö‘[v®Ë,Ù†œ9ÿ—Ä­Ði*¹dÜÕi¯Œ#m§M¸æ‹³VjŲl ø¥9s/µªCÖV[+‹;–eS,@ZU}IÜú‚ù•Ÿ£qò®ŽÆ'3Jñɘë\à—ä¶ íÞÍœ±ÿIuÎXí`*„ƒa©üwŒ\#l¡U"Õ ú£aÄužKçz +7/-Ô•BÿTV& ’I6Å£qz6gj&ÖÇÒ­ Šåbµ'i!õŌ䉪[üªÎŒYú<^Š–j¬åo¿„;\|[Ñ[ímè+,–Âýø²ÃÐ̘’ªËªJ#‡©3“¬×vwW'L.­?.ß\KŸï@ŒÃε03LùóóN‰Eý}±.Œò7ùŒF§Wø ,­¹­ÊÄŠ"“¼zšo;Üa*}ãIUÇbuáààëáûº_ß“¾$õÖüs¥âY™T!¾‹|nRX¬çÎÎq£q´ÑŒûãG8Á—ÂÏæÛ7Ï»ý½ƒï›pì_â­éNÞƒ.ðÌS†ú xã…hňCB´B¢E‰vŒ8!D;$Ú”èĈ!:!Ñ¡D7F´ Ñ ‰.%z1¢Cˆ^Hô(q#º„8 ‰SJœÅˆ!ÎBâŒýñù#!ú!ѧÄyŒØ%ÄyHœSâ"F|"ÄEH\5.cÆ1.Cãò•q3>ã*4®^ƒ˜±OŒAh (1Œ_1 ‰!%®cÄWB\‡Ä5%nb7!qC‰ÛAGÆmHÜRb#èÈ…ĈãAGÆ8$Æ”¸‹tdÜ…Ä%îc÷!qO‰‡AGÆCHMuÕ]Sã6à{~…v;ÓîÎ,ii·]h¦ßðyUÅVb-I ¿¾RLè¾gzr‘!ŽõäÕ±ÎamûÃúúšH¯}]*¡½­|æ:ÊQ;›7™ÊÅx!B¡ÄÝðDÄïtDU•yÈ;s_¶k'ÎVB›º "—AÆ?EctfsÕ™Weg­½ë¢TÒ+áTm]Ò,„rÎ:/‚í=9Ó¹èJWjÓlçésö·‘ÓNf;ÍÓΊÅ<¦©”Ó™È éd”3Y6Ê é½žš<ºJf…ˆ»ÑaÑ®üä Û”ùgQɾÒqkNØÉDgZ–âºýfTq¥o×Y÷ýµTœ™öÚY– ßl&Ã{­Ú%+«k;ÖM%Ʊ¹°fYÐ÷à>,]ùg8ÜýÔ®Ž¿Pû˜h9f-T|Ó™ïˆ3T¼[†´ÄÿOÔBÎbulc¥ŒpqÙDÿ÷3ëœòµ5¹6S1ž·‹2[U:=+W4^´•ŠJüÒx+•RËq|4Á¾-+¤™ªÕcé/ -Œ¬ÔÛž´“t°¤S"z‰åiIW½È¤s‹”ã½hkù’.ÅèLýùFê~‹eâ~RÙŹ›J£_——U†]º|umckkãíä)WiŸW:™­)]:q]<¹^L4éù%§‰E}‰çbU“nJ‰†§±>¨Ê/Ë$ëºÔÙò×Ò±‹;œètð´iׯêŠÍÍo[_Úó’§3™JÒn-ý®6YÙäË%é¥lZùXÏõõµµíý³Ñ`tí̉ï_üa¾Ñûº÷Ç_ÅNjâŸÓò˪CKRGH‘œwf—a¶ºÀìRf™1—æ0cÊŒ‘ÙãÒô€Ù£Ì2—f˜Œ22].M˜.eºÈä\š-`rÊäÈô¸4ûÀô(ÓCFqivQ”QÈôf÷`ú”é#3áÒì3¡Ì™}.Í0û”ÙGfÊ¥Áf˜RfŠÌ—æW`(s€LÁ¥Áf((S sÈ¥ù ˜CÊ"£¹4Ø š2™—æ+0Ê yäÒ`3M­ZmoÛ8þÞ_ÁÝîRÀIü’¤I¶(ÎyÛ-Ðmmï°÷íh‰¶‰P¢BJv²¿þfH‰”HªîÞ]€8Ž4óh8œ7ÎèÕÛŽ_üyà‚®eͲí +kR)™7ËÉê…Ô[F~ÿòèLñª&E!ò:?yÖÂò®•,/«¦&9­)|%MÉ3™³“çBœ¼²T¿ F5#ŠURÕ„–/„)%•&µ$–âŽîxNn©\ƒ4osü?û{I7'™——™hrÂV„²q¦AŸÇÇï^½zûÃýǯï¿þ‹Ð,'ƒŸÿú—çé|¾xøéGò˜‚#4°³à¸Èê9«¶1çlqÞqžZó9!¿°•bû£L?}þÆaìY¾aäT éÍ5rz†sµLC-ÏT¾ãì¸Á„ŽÝ­¦ÞËo²çɧß:5–ù„l¥âȲˆœêm„¡…¬X„qÙaàm4AÕ†%…Ø%…Xö„0H žçàFY*,»ùú©MK ðîNŒ¨E„xu¿ˆµ0§ ½•…„PÞÇItà´2|È0 öó`§QK¡ Ž¥AL„.ö´ŠÛ ë–ïS§“Ò‹…ꈞyªœO^@$‹« öj8 3Ò^@­K¹NxÁìÊÙŸ ö@x„%ψ ûë âà /Çb¹|tÚ’àÿÙa±u"M]ˆ€s¦¤ 3› r[ç“Ά=øÀ̓’ªRu çüòXªãDM´¥±{Ϧ®ÚþÅP@¤¥q±öKX¬ñõ:%ßìîÌɇ$|mv_–`§ð=ÀàåšÇ)ûÊGC€a{<þBê,¬ÝyQ±<fvw~æÌÈPÐ2 \Ñàs2Ô/Ä °§"/$¹›»Éè2ïû1 Û “ÀÛÕ¶¡åÍÞxvR°5¸¦Rro=~+eÂlåÜಷ<4¿aÖ wP½ ëçcI©ùîâ<\}O)¨:…z6† õº ”˜Ç œHÏæ»ÄÃDôxL*ÖûÍŠ@¸zp`{[±_Ï\ý`(6©(ñ!ŒØˆ-h1íYPÛ)øtݤùo¥höÈÑ>Œ¹’2F@c2Ž3k©Ré|vçãû€²Î±¼67ˆ;m[tµZ©Ç„P³³P+ܰ2½.1ê}(ê… õ‚iý­8/d ¦N Ë@?°¥¹C•KެlUSÞ/Ïc „JakŠÔdOuâŒã#P aŠë ~¼lR®ímŽ–óKÀ\V"Õ&™ùÒ¤0瀛aèc ’®MH1õíPK’c­×%á‘¶Hœ­xËø}B[i”,]hˆ­Ù/Ü‚ÊC˜mr—þ4Üýöèd¤ ,yzQ¾49’S(Ôu{È®)íD'A\ íøþthèTxþ°Œ¡¿çÀV‹òÄz{¢¦‚tØTr]¥Ûþ¾}w7 ç ©*hê[B–ä#˜Û˜ÉUòc¼¾‰uúºˆí+ 7ZäMIjªýÅâòrR¡wïð›ÿ.‹á.þ[¸¡‹t«¾ áF\ùSZåÿ– )5ݧáZ€„bî¾ }lžÏϽi…-^ô…è0Ã&Ï¡óØ®,Zãߎ8 Bl%E¢Cºì•¼4é'&ZÛ_;â$:À.8²tG¦ûAÌÅ79´H‘)©uqã£é‚Nˆ¥2ë&¯_ÐíNö€°7Ø ÓØ§4ÌòÜ©§?× ¹¥™ :+’êÀX X"wÍg"7“~WäÚV K\©dª–\ž;_ïÏ㥠§ƒŽÛžáx0æO¦’åù_Çá`ØÚê¹T·¥.mCöM§ðÐ-S~9Ö׊RtÅž8Æã»a…“ü8\Lý (ÀÕd££Á+Ü©R‚ôf,†u±™™j:D©YùK0ëK0›Ž ±- šèÚø9bµ}Ñ<Óä×c Tü9:”ýZlÛ茧-na®Ë@•lðÅË3R“VŠƒ²´[boÇ ‰ýÄT d{8¿¡øQ¿=É9Í Y„úRrMEÏ¢»î¼‹`{Çí²˜‡/𨠸CCDZCèF­#€EIiؗ·yR¶7»ë©TVµ4[ó~¾%eßt »ÀOa›ªkGºôÊሠÐÏUSî3=…{Þ5û]ØòP–tÈÞÐ:™/zìøòvkˆ¢(ø]JU~Ð*Î-]ÔXKÁW¾Êön¯‰}Gâ ŠÏch.' Ò 5Ö¡ð>õ±|‹Âô'‚l­ÆšçC¾ÕPcý„«!Æá†‚k(Ü$FF:  „Ñ–‚ª‚⬳>§Û¸6S,«»ÅUÒiB¢ Mg#è‹qtÍ Þ¸âóþÜßÛûÂ{3’`W–Cî ó\ÌS¾å…s—–-qà×A„vƒðEÿѶõàPL÷ Ø]°ô<é,bl Â%Ç£ó¥tY’IG³¯ì>†¬Øãc‚o% < ÁšÞ©§¥ËÞ[RÍ ~¨&û ‚Ú7zŒ@”Ô»7û±U½ù>¢ù‘±üeo ›Ê Wá V¼T|A‚$Ú›­Ìâ¥E §¿nþìƒû¦zøf.;K8†o£’µT¦‘êÿ¤³åÜÏ÷Om²l_q9žj™Vø²'àoÈ·JøébáÀ‚õbê%¸—|™ÍÒbÒ¾îBV {¨C€‘ï•Ù.?‘Ý›±9þ4ÞÈ ¡éñ}36¾÷}_s jªƒÃû]øúc+ÏÍ}"-ôàP 6cø·0ý /mÞÿdjEã-™úšçHj‚ßAr€b^œ}JÈá ––Ä4J»w·ÍKóGæN']0ò~û§Ý¦Ý õýg›¨ÿPKI_†(÷™7Õ…»dtd/isobox.entUT ´ì8´ì8Ux†>M–_o;Åßó)ø#Ñ(IÉ6…ª’r[‰ W¤­à Çöf-¼ö^Û»4|ú;Î&¹”N ÞW¾Î//>?i«q‡Ê£¢wF­…Ä7Å}>Ø ñib‰'¤¬Awl€…”–åêÿcäÖ9é+k„2K¸˜l‹¸-K‚DžAçŠÚCëRðKã•)Z±M°›²‚™¥ÜËÙÚh0¬”›ž”‡<æŠ9 P "Öi‰«8snuìLË-zù=.aŠË—ôÓé3¸0h–Á~¢íðÑ-™Q?Ö×.ÍJgNl׆Ǔl“<éJåãqÅLp[­¢º˜@¬ÃäzX:fâùEN¦~Ç\l1ñ¡¨hþ×ß8+dé×6±ªÒНw‹±Ãsƒ§L[‹îÂdrtü¼Í‹ˆ™Œ–´­Å}•áºë’˜¢¨MI~œöz'Î>\^\~œI¡á§×ÃÇn£ñpðê!œÆFÓ0ÇZæþ­™ˆí@dÜB¼'ãq bF©gIRÅQR#Ž@ ¦·N-‹ß1>Q2FIŒ¥c|˜Æ u¼Hb@0»lÖ©Öù„;õçTýxoýíQ>š'‡æv/þ.mFÐ2*¥÷¡SÚ²]i¤6*þ÷ê´&h‡;muU%Ñ®(m“Ž´sJ[vÔ•Fj;îH«É«êtïÄÔä%ô6qE^…Ó$©b–Ôu ÉЮš¼‚&IŒ+ò*M}—]Sã6†ïùÚíL»;¾[ºSȤ „!agÃUY‰UlÉ#ÉY̯¯ÇÙ"å…‹ qt^?zÏÑ‘´sþaoo‡ø¿È8F±J·[\ZRh•”Œ'dV›rò}|C Ó¢°$ϳÄ&­“Õ±s­r"dQZ’PKÝ¿¤”‚©„·^ò¬µSºÏ85œh^(m •áZ+mˆU¤Ñ£K‘.Õ™0Žæ<ñßÙ_’.ZLµÊç/ÔÄñÈ2çZ0ÂRª)³\“%ÍJn5F,¤wºœ²”¸Ù[Õ‘ŸLªÊ,ùLrjýOÂMM5Ÿ &hFkìµFî"M§ôÿŸys–Â%i–UÄ}(FíÆ«:¤Ñê*iÜŒE™“™3 !J® Ý€o˜òÏx2üþ[íÞPG4wov¬)w‚™¹S–»ÑÔú³5¥K玲dƹ$Ú…ÍÅÏ42¥57…’‰ 2ê ¦ò\XËžtÎ¥¥!µSNÅý(H¸v*™ 3—«Öa)• Þ¤¥¿2šHšóõœ„!s_XTsâÄÒI¬ªÅ?5„Q­+ϱ1m®œ—?ü#7ÁøïkéOÝÏd(YÒÍÇÛNFzA¥x]}]¹4¶ê¤yÖ>;=^W×¹0>]¾&˜**Oç+ÐŹÊ5d¡©ôùó:¥3õ‡«‹Æéy¢ñÕ­[•±<7+›hQd‚­ÞæËÎÍp.|á YÇ:wÉééÉÙn]/‰¯IoI=5ÿ^!YV&«_EžMpãüÜÛû²³sþ¡7N¦„²Š¼ùûøë//ûû‡û|$_ü"þÓä>žî’n¥Eæ°ˆ—Ø(\…öOF a±Hc†(ÚÅŒ#‰K„ÑŽ0.ûH„¥ÊZäð$à`)é^o×èœD ÝkH’ G’‚ô#‡Hrp rØ 8 F(tz¤˜#ŠÐ >G„»Ñ ‘ÊÊAÀ±Àõq…Òr\áúpþm‰4Ž\$~ ñ})]_<ô¶)u."?ô]-ü9 ¨R"wN#š!¤‹¶¡8 )`’†aÕ6G1Ì‘PÛEŽÂ®&Ô.y(Ý6Be€1Ú®°7µáhü‹rrP¸]Ùž`fþF™9‹Xj%˜ŸgDÖî3Üt¾"˜¸h¿Â]çuû°NRÌš}\'×#C~\†Ý-C7È˸»Ý ‘qtCŽIÜ"ŽnÌq‹D$âˆö؈îÇ–Mçrø{€ E:íöñFd=Ä÷Ä·±áÒßÌ¡ÌA¡·‡K3…~4…Ò(Å  (`'¼GƒãvBöïð”É5’x@ûw|Ìì? ƒ8ÂŽÌ ’#ޏ%÷Ç# Nš GÜ“n>ãëà¬Ù ÄÙ…ýÇ >îÚæ=Ðã}{ü‰šÛ­¾„È|÷$2 &[½‰‘ú®–EUÓ ¨,\ET5gW‘ Ë·á89  ë·9ŽAƤDŽ„çà)<"CâSð#ÒX¢îæe íø†º[œ—oÐ*¼D7n„]¶‚ËgÞ¢;â.;…«§BY Ï×01S”˜ø$1í?ÀÜTa‰4,áþWa’°F’xœBŽWT#áþÖȪ‘øBÿkäô؃pí¾â›ãè±íxí>E7ÇÿPKJ_†(V¦Ic¡ dtd/isocyr2.entUT ´ì8´ì8Ux†>M}•ÝnÛ8…ïýÓ.°m€ÄpÛü8»i°ã¤vÒt9@³W¥IÚ["’r£<ý-;m%Ot!Xçè›3GrçìÕÁAâq…™ôVVî}W›…³ª”ZÁ´‚jø–Ü‚—‹yž© º>«kgÎæ€¦((ý„Ò ´Jwó¬Û©wý›iá58]X@˜ ´sÖyê—b… Âeè‰æLÅkùó®´Ýry¾•š)síP‚L…2h+‘•Úƒðç†ÀIW ™uƒ¡ª+ßúÔ–™Úƒ\„x ©5v6C‰"ƒû{£‘S¥¯ë¬ûu-š³BÖˆ,«€NVŠðìU]²ÕXã©c,s˜’ ¬Yú î£aqå{2}{SWÓ OD3z2±¦šN(}îlд[„Xâw ¦bEîØS­ 8*›áÏ1Jëœö…5 ÍFÉ׺HÚ<Ç4ér.-=ÔN‘ Ý4•v¤’¡˜Òh‚Ý”¥ÂÌõv,õÑ`D®7=¡‡Y –pHW$±NK\õ …sUäx6mfÉËq‰:@©ÿÚH¿ìÁÈY†ú‰¶ÃW7ŸÖ—k—’@è©íÚ»Óþñ&yÚåèã¸b&¤-ªHHu”\s'Lœ_Ô)ÉÔ”‹­1&nŠDÉõz*tî×6‰¢ÈP®ŸcGÎ0M]KîB¿rº_çEÅLFKêÖâsÑȬTë’˜¢È†Ú“ŸçÎÙ«áÝd4yµüz¼þóÇ^ïðèý߯á<¾Ä}ëÕBïC¢Ý…¨ñ,q9Þ-Ñû)!Eœ½åŽ£&‡'Ž/‚>Ö´Q娒 yõÄÐ\5ižXWþcP®Z(¼Èœ›Î‡Ç|ñ‚+×Ü€>´P®ÇCVËåï:[˜ã îÃýÒ lKŒ‰Þq‹dÄŠ,¼v¿©l9ú 6±cF¡×oa°]pnî `:svîä`T–\H ’åB³Ã½á22h¡ÜŒ_xs2æ´“±Ó¹åPN[(·ìx Çñ©ÁaXŽ;ŽãS‹ãŽå>Ý“‹mä@&ÉçÝ1¹hÐVޤœºÝ$ÃI¹•ά+é­©rϨô†-–û—t*dæsÒ ©ø¯ÉÈÐI‹å¡õ9ùPKJ_†(Cð¾&íÉdtd/isodia.entUT ´ì8´ì8Ux†>Mu•ooÓ0Æß÷SC‚!±ª `Œ h74 6¤ Þqµö„ÿD¶Ó­|zîâ6[FÈ‹¨qîw~î¹s::ytp0¹ÎÉ 4áØø u ºQFÃbyeàÇü $©ÎàœÕYo“-hƒòu“AcFþ '´ß:;•¨oÖ`2Mbô01†˜ (3\“†)FK‰ÅœhyV<.Ç*Œ›ß§»T׬Ç7ÎDR VQea¶1 0%ZzÎy ªp5”7…ÜO«ÐXý fyE\Z„PU¤-|/²·9“©p!Þ_sÖ”(x´v| sçUAv¹¦Á'®˜ 6@Cð­¡ð$†Éʯùõŧ…æêÄŠ*Þ™µ® ßH¥1\†l8³ i@ê ×ìNȰ0ÆCd¬¢»6ª£Iuðšü.æWRÁ9ÊÙp>ÏέšÅ)ÎÂ/}"m"g±„ nM[l…~ivm9kÎlk¢•ÌFœ€Öœ¢YM 0ÆèèL«{y#K\)óv›zú .<›å¹±®â=ýi[—晥cÔ»µÇGo¶“g¢£$í’™P¡Þˆ:™@æxr,#zéŸäiØÔž‹1^‚DÑüóW>›”K­MX×–T»›ŒWX‘ ù²»pttxü¼Ì‹–™KJi²/yeÝ"2E¢Lb?NG£“Gg—××?UÃM¿wí=y|;™L>½z·§r†ß—TJήмˆf=¿œup éQܶë_jzØQ%¤OMvHèÝ^mˆÅEÜë³'«¬¹,R/,ª¹³Y·±ŒîÿÒÔ³©ññN<‡ðéáÆõA>làËÙñ½Íù“·]æ¹êÍäͤ#KÈ^‡*ê=ï` yØ£°ì7¶Sû©Ã$ÄüîcQŽÀö±ÃÚ”ÉêÁÙ›vP éQëÍÐP#8ùïÆa,2ÿPKK_†(¬ D‰óWdtd/isolat1.entUT ´ì8´ì8Ux†>MWkO#7ýί¸»•Z ‚}ðh)*;™ìFj™ªiùVãq =²=Y¯ïu†@3ö„™øž9>>÷á½ËwGG{þFR Î(æOB{¨­).JxX‚Ÿ ø~û'8neí¡ªTéËÁ“SmìÔš ¤®%ó ÿ…FKnJ1xªÔ`¯]õ·Ì °¢6ÖÓKÖëÀhW ÙB–1«¤C6—eøÎÿÐl6àfÐ<^­¡în*a%>g–q/,,˜j„朜i$ޏ‚ñ9àn¤_¶‘ûnnU@Å|øIâÖ,˜éTrÉLZÚ/Fº6ÎØÿ? â,¤“F3¥–€†3ÿªU²ÆÊŒv¸cÙTð€”`ôJÐWâ.žü{{7þþKo¨2šâ›‘ë\à‡än7Æ \Í|q ªs¶@uŒ‡!4X ›Ê·cäÆZáj£K©g0¾-Ú nªJz/O£róÆA«¢àÚÉRXDQ’=àÑxó6gz&ÖÇ’¯„Í*ñ²'é`ŒÅ¬ „X¹%œ†*&ݱ¢Ùšÿª˜ÄÅd+XC“î¸Üô ULâqyÒ‡ÓP¹ÓmÙÍŽFŸP¹wïÉŽKÊWÝákÙç‡{ÊWñðu߇³¤ëfò²{ÿPKK_†(™í3aø©#dtd/isolat2.entUT ´ì8´ì8Ux†>MšQS7ÇßùJ:Ó&3À`clhÓL)câÚlOž*tòYáNòH:À|ú®|@bi× Úß­V»ÿ]yØùðfoo‡…¯ UH¦œ)¸oîKíÙš¬2c·Kæç’}˜V-<+Ë"óÙþ£+jÛ™5%SzQy–qÏáGVi%L&÷Ëb§^õo!¹“ÌÊ…±žq½dÒZcó†Õ+Îù½ÊØ·…rà͇,ü.þÒ<ßf¿ºûø‚š€?º*¥U‚‰9·\xiÙ=/*éwNå®äbÎ`7Ê/kËwnnª"{ÏJîßlÍ23›)¡xÁ¦µÛÏŒ,]mgìÏBpî•SFó¢X2øf÷¯±ªM^XgF;رªJv Șѫ€¾:îBÀ“ÿÆ“þ—ßjkxÃÂG3x3ø:—ðM ·Ï†ÆKXÍ}0qˆ«s~Ñ1žÝJ©™³™ú~ŒÂX+ÝÂèLéœõÇ£ÚH˜²TÞKàiˆÜ¼r¬ŽPàÚ©LZ ŠßÂÑxól6ç:—/ÇÒ]ši^Êç=)Çf!±¸• ê«l OÜÚeðã5h3±|`JÈߟÑïÎÞ³¾†`iØO;Ùœkõ´úu¥±×¹Í^ž5NŽÛÏ™'m©\8®Â,–Á»`™ëXn¹ç8õòâ%0:, {ÿ@ ,—¥[…‰/…«·…´ƒÎTH<¥k[ˆ.;>îœìÖù’…œ !©·Þ«´(ªle²(ø¦¤ƒxîí}ÜÙùð¦;œô'_¿µõû×Û_y<8hþñ–} Eü§+ƒ=ßeõÒ`ÿj~J™7_Í_(Q=E¼äÂ2ÐHß–B × ì0079­Øsœ ‰-4â“躔yz ] ‰clÄõ*ÉCìRˆ´X»$DÚ׈µ[âÊ×¥ìSñîâ ½ ÛF+9 ï²tµÈƒa·GŽbØÃ’PßF¬×Þ.eŸJD'ä„î^Äý#ߤº9ÑHqUçhíQæiU÷pÌãªHÍ4°Z\ðh „Ú6âÆ‘oÕÚ…J›Ho+,'j­ VNVZB¤šÕ#!sbSÍ8Qæ[·tI¡Ò™ãr+lNr3–³9.Ç—”}ªe—8¡O„÷0 oŸ ¯úV¨ƒÄj¨¾Á]#ç¾²±W!­þÁP„¦6cET¸¢ö)ûTû8Ai³Η]Äé®Vw®Ö&J E¨b3V#…kbŸ²O娔WE†Z3Öuð ^ºîežÊz|#*ì0.Öo[ëëŠB¥ÅzµvGèôa\¬w„J¢iµ~"w¹ ÷ÿqœúÐ K ¸Ò*±)ˆ¶yxAŠMms@QN’Ý 6q b&<ì¦Þ á€2?ÇÜ@u*gÈû±3P€¿Q0DQ*T8Z©°4+d*‚qx¹AQ ¢£´š©'X?Pö Ì Œ ‰¼jµ"ô¦¬R”ÃÄá&Žæ ã‰Å0xKaC‹y¼#"E[qÑj4A‡”yÛ ÐD‚¶ÚÈû±ôR€#Ô a²[q·F¦Œ*|Iʈ‚¥CËè'pFâÃÇQ<¾IŒ£.AHÇ—Q—`bühÅ3¼Á‡eŸî#œ`‰š9НÝT1×%í¹×›8–Hû£¸ò,šô×”y:†\£K$ýQÜî-‘ò× m÷×ÂQ±ŒGZ·)’cŠ’¶ãMG„´×°C:¦ÌÓª£G4Î1Hgã1u"ÄDyW©Û:OŽ)TZ°ã­0O7®]†vB™§E;Ažm;ÖPOvBR OÌí¸b=>yL(û´`'8¡"> jÇÙQ¡ŸM)ó4#¦( "c'®Ðê'Ú│¥õ:ý \Eô§v¬eÞ¦”}ªbSœPWãNœ£~1žRöiŠNqBe•Ææ„v¬`àÁjéúû)ëT¾¦˜}EÜÌÛqG­Ð{ù”2O;ê<‚׉5êa«Ü}¦P©^}Þ [R°X7–[Q_)T*!_·ÃªòGAüK°LI+rá¿ÀWŠÀF øDŒøêÿ´i¸¡(éÕÿfç‰è:øêÿ„öœÊ<½úß €'âÃÏN|õ"?ú¼¡éåÿ&†üPKL_†(„ ýóÌdtd/isonum.entUT  ´ì8 ´ì8Ux†>MXmoÛ6þž_ÁvÀ–q^ìæ­«‹ÙylmÑd@÷m4E[„)R!)'î¯ßd‹–tJ›Š-ßóèîx¯Úûðf0Øcøw§´dÊ[SdGÒ–;›B&l¶f!•ìÛÃ_Ì §òÀ²L'!9zñº‚Î͘2yX‡¬0JØD½dúh¯’ú¢%÷’9™[7k&³Î³`Y%qÃW*a×ÜiåA™ ~¾8ö¨X~ÜR=‚> §tJ0‘rÇEŽ­¸.¤gÜ{µ0 8ðJ.RÖ¨°®û>µ…NXÆþ¤À4Çì|®„âšýS©½áÈé+œu»÷Ð9+å•5\ë5ƒ‹<Ô¾ª [®kko˜°ÒÃÄ‹7—²­`BÙ gv½S‹ÙÏkŸÉ©á,ºD`5­yEçœð”ÉË-°6$¡ÏíZ)¤ýé–³–[–Ñ- Œìñ‹ïñK­ÒØ«Ÿ *»ëIp= ãµ%Á3%—Ó˜ž•H·e*I,•±âü$Ja7E‡_DfæóŽ-˜1Ç—J¾dûz£‚ ä€ù²Édé!u§C“ñFÁ1^ºfÁ>Ir GQ›"›IªµÛ”ÂOw&s!€.!ëìd°Ñྣ`cƒ]úC6—°t"3Škú*Wƽ(ºi¹ÁI²hQ®´Àв²°@åiiàA‹fSCDË0ŠÐ7ü¢lB€wZbk“6?ÜJ7tAo>±þ–"å³§ï»àŒ€§u79γ2ÄQr`ÝÎeKÖd²…I5&1¸*‘.´Ý‡ê~+á+ý+ iÿp½[tšp×Ó¾¦?j_ÕNÑâêé_µ*Ç%jÓÀ`SÇöUÞêë_®¯ÝDʪ]o©^k`®¯Ýü¨Qæö¬*“ÛX&•Z&_qa](Üž%®¯¥Õk\´®·§¹¾žÖrÕrÇU¯55××Ô®~ÔÔ_y)è•<¾Ÿ@‘ròí¸ÇC5¤À£éš¹™û´¹!×OŽGî-4ajØl¿’¨ÏånK¼€ð…YtqÃóóX¨³Â+mM²ýR<È—@•W_ä§”Óc(ðPõæÖ¶ë<ü8$ñCžm?"ñ#KT“!(|[Øe¸‰ãD%RŽ…*×Ô{†àxc»¯{p´¤)«\_ô•§Xì‹<¾¥(ò¾¢K9º^Äa÷6Þ¾îên?ëÆê³•uÓM…˜QoÛ8€ßó+¸{Ø[¨Û±d·).qÓEÛv±é{oGK”E„"µ$•Äýõ7#Ê¢%ÜpeyæÓÌp43äÙ»¦Ó3†¥L:SVÛs¡=+­I«D¤l»g>ì¯Ç3—XYzV*õéù«SA5³¦`R—•g)÷.Y¥ebRqþZ¨ó³ õ‡Ü fEi¬g\ï™°ÖXǼaAâ–)Ûp«¤cÞ¥ø=ù—æ»óÄœWO隷`® aeÂ’œ[žxaÙ3W•pŒ;'w ®àIÎÀé÷AsârS©ô +¸ÇŸ$¸f™É2™H®Ø‚Ù £MôŒ=¾‡Áy–NÍ•Ú3ø0 ÷m¬‚ʵ1ÚDz*Ø2£ë€¶†; Þùßã×Oý´á ¥‹2x2Øš ø‰;gŸ Í=ª8ÂÔœ?CtŒg[!4³ –ɸŒ‰±V¸ÒèTêûôø%(%¦(¤÷x"—WŽ…H~ÔN¦ÂEI¾…¥ñ¦Q˹މò<Ôfš¢ñI:–a^q+ä3 êlÁ»Ž%ÜÚ=ÚÑ-3˼ÈDüÒ '›7쓆`iðÃξØ×ò[ýµŽÒ£Ó¹M÷æ7×ë&ó„-¤ÃåœHL¹Gë0A2×±å×9õòâBhÑão¿Ã+°w^®/K%“úi˜vàa&1ñ¤º]v}}uó6äKŠ9‰! ®ás¥NT•Ö*˜Eh›â9¾?;{÷ÃÃ篟¾þ—m×OìèïÇþãu¶X..ý‘½Çwø“:?q·/¶F1$žæ‹!hu³hA«ÙO°ôÚBZ? K 0o‹Õw—$ ºrõÞ®¯[@VA()U¼?T-Zï/PDxvÿ »µ¦‚57ÞbÂ*0¨ÃƒôÙ!oƒD&R;aë¬,¸}zÓÃä‚òèjÞ†ä¢AUv ©óô¶Ñ©ïtYÒ2ÂÅÕæ>²¤MjñB‰·Ì”P'ºUmݲ^Y„"•ô€+V_6×cÁëæì€5Ÿ_ÅÜ­#mÔ¦º*¡Š•»ˆÕ=œ5Ž0íê·ÅzìÉŽrÊw;1´þµ~5"Ÿæ²Cø0F˜GÂ1ÂTX.)RÊ]N%ã¼µå6ß—9,ÍÄÛJ`‰*s™ôr'•¼ Wjí(÷a±š/'Ö+U¸r@¼œ}8Só¢_ Ð2%²:ÌeHÄÇŽp6NXëQ·’Jéû­‹ }ÞO bÐáóp‹Jo$fñ!ÖÅ“§¶†Ò•:BIØ8›Åª& æJe 8¿$—­âüârzByI(¯Ž”—cÊzÄäØ nAq2¿X¦—{Ì$܃Ü[Æ nD¨V#—’»¾öÇû2W`K9˜:vÜWVô ]@K˜õ ãÚ„e ÆrÄ„y0êƒâÒ¾¿íÛvQ‹Ü•ƒæ®‚B1bâgè0†98_ÅäE‘º}-¦0ÃØ”@¬ÄŠFd2ó9Xˆáä+…XPŽ,‡ÿb‚#Ž`Pž¬iFí Á¸¤W#·BŒR–åzHÉLeG!+*ªwÆóÖ$çÒºa)ŸÍ"E¨*“ n½¨®×±_‘º;Õ—'zS. × Cqqj £õ$7V~3ÚsÕ«[ù¾7ƶ6ßañM÷hªý¤éÅaìaŠÇ Î ÈGuXê)ÊLMFC•þ]b¬˜·éÖÂ~f£t«Èz0­n¿Ø.õÌQ9 Ùl[]Ç×”`ɹʨ9Y™oŒ€M»Þ "`çǦìpæ{Á&†RÉÞÍÃ}·ß t³Un$Xwý`á´ŸïÅkdÀØ\Œƒ:9_¨‘ùb³ ç‹šú'Œ‹j|ÂèµÚØlc»mµðÕd®ŽÆ^ÁÓ„ÛÃ1=ã³ïê.&)ìn½Iµ8wý™÷°p11aV B]E•Z£÷ô”€-cï‰ÛµuœôjHÛ)«[,k¿w8c–Íw:XÞÕ3 j9±«»±ZÄr?|™íXµ¹éYÓ-6' ÛÏÜ ÊM€@½±'ëÛÏ\Óõ&`±àØñ‚c_#̜ǖTæÜ°œ•¯'ÓÒŠp>Œë<ùóµç¶¯dºlßa”ÀÃÂÉzZYŸÇ9Ïû)ëà©Ä+°^Çí`iGæðµ )á墯’XƒH=–4Òãs ¤«Õ]<èÿÔêÁ/Tw\ÝÝuW/Àš¿OJaÈÜbg$!-ûD­ãs±•»úS ]ü²ëŒ5[ÿyk‚;è†aG‡ ÒÅo&YÅ)œ‘j€0èk²HŽŠÄÝîz¸Û­Æ¦ª¸Û­ÊòÄTU¬´‰[•ß?V©ÆŽUz”Ó‡*ÕXZ Š¿N–Ÿj¬ü,éòsÒùûLÏø‹‡ÖÁgMìýyw9’7 ÿ_Ÿ"¯çºmÏH²D-¶ìñÌ¥¶*u{/U]ÝgÎy“dŠÌr2“ÎEKþð/;IR¶\ýôcŸ^ÄLà—@ ÿùÿln&[_ç_²¹ù_?ü'þõ§¯^&‹¢k’Wi;Kv¶v’“'Éš_r€y‘=K®gí¼Øœ Ä­I;ùÞ÷~ñ‡ø÷a–7‰øOš,ꪭڛE–d×mV6yU&Õ…®•òr\Õ‹ªNÛ¼œJ,ñb°µ½e¡²äTUYò“€ª?,Q´þÔ-’—i9íÒi–<”˜T­ãjqSçÓY›ì>Ýloo'¿Tu1I~É'YòK6EʦªÛ¼›«*âßÃWiÓ¤ãY×dmÛ$çeÓæm×f@ñ‡l<+«¢šÞlØÉkAuU¦E2É,HòN”Ìjñß$+EÑ‹ªÌ?wâw †][é'É_²¼J>–ùeV7y{óhËá ‹"ymhd“Õ—ÙÄ0åmVÏóF2³­AîF2-ÞHæÕ$¿¸IÒr’Lò¦­óß ZÇ¡›$ ”Êz:WóEZÞ@Lªq7ÏÊV¶,Ä‹b7É¢}Ôd²ÊUÞÎ*Ñø‹,}¬ Dƒ³ÑM2­Ó²Íj™ˆnZdm'Ú´Bp)Ø>„¤­¤&U—™¤YõRYµù8sdµ @‹´Nâb–¤‹E–Ö› ¦ˆjyÖl)Ùp³ª˜.&óô“F*«¤Îµ`žiøn§(hié(/нðF j°aøy âlÛq/ñ¾gY‘]ÃWñFTÏç‹"^¥5°ãÆ`@—v¢|ýLþýª¯o’W[¢£Å×óyòŸ©úãÿËÊéVÓ•[¢[þËÖ}—]æÐãPûÿ=Ÿø£Süß,K'—¢ ûãíÝǃÃdgçÙþ“g;É$„Å@Z$ÿï?ØanÆ)´~RƒÊ‘/¹ %R° DF3HÉÐëtž5‹tœ‰1Ñ´Àµ-xúúÃù‡_“ûªà–AHîm>~üËîñãÇÀa'ˆV{¨ÿøñéë{‰Q0›LIÁÇwç ä‚ïe ²í™diWá1=sœNîÍÚvñìñã«««­«Ý­ªž>ªàð±äÚ=]ð}æŽÿéÒ"¿€®“M„ÁÔifäfW¥ª #OTC˜c)"’]ä×¢r^™Š¸óúý–.&$éüÇ×oÞB»#þ©BÉ=Ç£$Mðm@Õ‚—yùÉçî‘—ç¯ÿ²u=/ʆgM!00%®ÞVÚ‚BIîÉ_Ïdi¡iO††‚!ÿvvþ×Ó“äÁ}¯Æó’tMü³¯ó/Ñ“%QƒÏÐöM11Ôé–è¸D+ÊG/ÏÊJç§ï=±‹º}G‹¢“%'5Îú;;ð{ɦcêl’‹´Î’¢+U#Äê%TbÙ&¸G^åÍxKÒ«i½÷äOÿ¶ûä9ÔÚ’Ÿyî}!sŽÐ&yÚ"]¾Ê$Ÿ oK–©9aT0RÕÈ ù!_*%2wg×ÜÒš¡=»†1ihCF¾ÛöŒ’Bt…ícY)SGª 1Ký,Ä á»!s‡† PHß ™ÿë ™äý«ó/5fäü¬e±ÈÒFMé²×¤¼‚#1”ý‘ TßÉÛÀèàÕç­L¤5L¢¯g ý_c­`ê¸ož‰OeשBGåÉMÕ%0ßw (§”&yÛB( %HYröö\«(Í‹7Ç~}{š(‹A2sõ@Ѧ¾/5¶¬¤ŒJK²"“ÿ¿†üç d3^ÜFνÿ¶cò?ÿCÄ*ÆÀ=o½çpduÙ„KdÎ7& Æ³BÌ/îe¥C3·~ µþK·Æhæ™úý°¬Êì‘7•×¾€\tmWgNN,…Ñ`ëȈ|›øBp”«îUs¥œ½/²àÏ^Ð6[XAïÍ,w VEKQwbã& Ûëº0P? >ÙÂ'›n±>³ê‚ ‚èó×Ç/?žœ:Ú¿²ù-ߊ6žÕBÔ®ªú“èO ÅÚNHŸšÈh»ÍÙdR¥Éþj”!eMhïR¼iÅT(m$ï S¢™óu^Iõ .,e~­ˆijòsµ©¬ø-­ðô÷ûlÁçÿyù\50]+´#ÿ%AÒÿþ/µ¨É.A@A¸O(‘~UM²ÂhloÉ -Ëšs¨ ßZ²tò °ð³ôÂI+ oN¦¯´ÍìÄè•¢ýa}î„àOñV?¹ªÙ´­¤Øæ:½ØµWâöô0Åá;¶|Åu^F±¼^ñ{´wµák®›$¹Ú=KœóbóúÝùP->mÐ ds~‹Óµ”Žl3'ÉHÍÇZZ@·¿ÿõý‡ÓWžÙ¸¹ù‹…Jƒ3bÕ?kš©ö«‰3²}¾™ÁMh*e¿«çMRfBQê¡'ôºžù<û] Oþ»,©d6`S¡è&Â0óŒàÿ€eTëÏêá$Åbwµ¶¶s[i”S0{rAE'l‘Q8'¨ªvÒ:ëCüo’^‰'†;[?Ð~·´Ïú5­W‚R²æ5£__ž¾ÌP8‚ÚPÔÈ[aY×§_ú›¨Ö˜¬¯¡Zùßµê×ЪëŠR¨U=aúCªdMµÐ «8AщëÛ¸Ê;••)øUcÅðÉ%fRDFÀÔç8ÐjЛƈ~à1H|U,‚ç¢Äz¼ÌàÒær1ó y8,Ëì:ní Azÿæñùéq²³ýdoo#ˆË&²æ£-¹¢ž Fz´G! >Åš ±VP ëŸn>äs±¨ËFI# Eìû<¼åçì¦åTk±ÿ>/i‚ û8ùoÉì×o> ?œ¿y­b9²¯‡g'ï’á»ã£áûSÎgsª–þÒHz暦+Ã<ä0¸ž³ÖS’஦EÛ-Б@ïĺÑYäTQkXò «ÏÊzÊÿµ™OtõÉz¬ â+›>Ћ~_™©ÒÜ4m6wU|§ƒ*T7a½ ¢¡ 9ÿ<ÜÓsâ‘îÞÖÌèµ- ÞÊY^k¼¡•.£ ÀSýq17nªYYPïÅõ:íÄ òþÁkÑ=à5WÔ`n‚?µbæ*‘¼Y´ª¨}ìuæ tDÈ éx™7BW¿oëNЇ ð|„÷˜¤µàåy ÖªNåI=D¯Q­QÕoàb”)”¡í#qF‹¿6Uz  üM¬GÓzV@Œç[¨ ÿÚ&Á70V—¤ÐÀ²ô‡–Xýõ LÉzítQEu“¸%u#™Ã^Úù€Á–Qàa¬«¹ÞØ­Ä«:iÙXpn¬YLm´–h¶’_f™Xï”Iv-T |áìí¹Ý:ûTVWå,6 ›lX—ø lªmù;­»×m;å_ål± [”b&”–w5pì¬tµ;Þ¯w¨J„Q’<}úäЛ¾¼}Ùx7öÕËGV$¿ @€ @ßÃÌÀl¬ÛBᙂ@èH"×cÐˬœ‚Ÿ[Ê„ò"³¢X¤0íÃß°¶…þs•Je˜,òë¬h`÷¯,ï«'Y=†mGÁ‹B£Öê§?ô·Ví¶éÕä3McØjµàn2Ø.±)„ÌÊ@¹>-Þ|/Öüº©‡,"üR•¤Ì…ùš Î6ã:_´UQ$ œˆ÷kRôÊÔ )’ݱáõÁPWg Þ/³èã]Ñæ/oÓ¯\Í¡Äc§Oò)ì²?|ýñÕÑé»Gøëe7 ²Þ‡_ËJá7ó²Í¦Yí¶¼ARµ”Á†¼Qôuýt½¯¿••È®5;á„VÑÖûÒ{Y)ük]ZØ!ôiË­÷0ÃoœM¿º2ñ”Bj†„óYÉãïB‡îlìüo¤úlÁõ(?6õBòÓÀ[6®@m€5#FDò÷wgǃí½}’ˆ&[—yǪ&@mhǪ &¬Y™²uåT“†$U)#(±Â‡•ŒÒ[÷Û®føù~)õõZt­Í¯jHÙ‚ädô ø<÷Âx$Ôkõ “¯d¥õH9ÑÕ°ìÆŠvÒΓƒxð˜âÇ¢ôº3šWSñ±ÌåòX˜êU'&’äÜÚÇÊ™ò÷ïÎ#bº:_“BBFzHjúiZWJ ’Ž`‰‹¬ùžu®Ý'è_çâbÔ:7(³Ò¾¢uÃ÷.s-î7Yæ:š¾æ2µá_{™ûÇì'ò®t±8ý!+]K,ZéÂÄ‘Š¿j¨‡¾–r»ðÕ[ˆÄêw…uïßzmeõ…úÜ–iOrO.o±drˆféã¾~õáÍ_N_¿ÿ+!ßnV4<õ+­n [£ðË×+.þP.=x¨u–!T­(z:ŒY]XµPàèEƒ­+¾²] 8°ÆP\y5`©±V=OÒZ~, â>دa·ãïõtì Æ¸Cs–+ø%æ5õ¥Ú×¶—-¾1|û:b5#Ø)(Ï’uÔ­íZ‹/ž-›/¶Xý¯õ0>0EÑtÛcŠÊÃAýf¨_„2Aíû•ÌÏÕŽHù±îÂ,PLÖÚv(m‚z-øn~~}ós™0…F¨/NˆJísÍqÌØ¤2Ú¶½ªààO+´C‘޲B<}¯â¸“Ã’‰Ž8®™—CÕ«Î Í3?RÌ‚s1jŪmx2üø ùqx§Ïi€ac0À,UM†BöÐ~£${ÔK¬‰x×ÇLe6¸N…F©WØS ýÐŽû0®Äì¯I*»^:@ˆð?UéÿòêCä‹«½¬>”öj ñдh2-’«ª+&ɸÎä„j$£Éç9hSA<¥˜‚:="#m|Åíα>€{ã…ÅëøVl2geh+rÔfóE”:äI1}”GLÓ§áô8z`jø£îÁ#½ŸFsˆEŸÀ6Gó¤‚scÆÒñLükpnÜE.,9a°³•œèwø¨Rœ˜™!mØ»ÈëF…ŒFœ´‹H»†„£UÏ„GÏ¿æAk/²K“ÒP ‡l¸i|þ#:Àôƒž˜ýÛ÷}è¹73'¸í äë ¢fÓ­ä¾:ƒ¢ê>2òõ‹lŸkðÛð^‰Š}§Ô,ßí#akåQLM²^ÜŽ’eàlOì®ÞD¥9ƒ6MŒŽbi]›Àˆ)§›GúÄkr›ê±"†Q§bø&[z¢Io НºÌê:Ÿ¡ôNיЕ›D ^°éF°#!u¥‹MVÑÀc{:ôõ›§Ï’acÜ!j¼ÿ]ŒÞ×ÃW§ïÿwõži’:¼ã… } *Q2«ÅŠKw«hNYpp7+.„’œ–ÒSr›ôÇüóX{®¿Ò°c²Ésèlí×éSv#ÏdË…Ldh¹Xæ— ,qëDŸlÉÐlÓ£—iÑ e:“ºÞãô,«…&~pß;×(´·\!‡$– •ŠÑìÊ"kâºv#¢Q6f›Xwh—ÒPfK@¶NšñLÌŸ_xì -rÌß_c°\„#E’oIWEUæ¿‹O©¯<ÌÄàPõ„£í™˜Œ¤v–c†h3䂎”R–ˆÙL(y5àTœ"$ϰåïXjþNpâ¤Q|€ÕSZ%¾i!ÓÂ3 >†>Ì„³ZÜ»»%•Έñ¥k*¼¤"òf EÈ|<ŸÃXŒÕ(G‘ö²uÈ~kB+·À’ÚFù#GÐßsÒlóHÝ3NmW;];ªÀ£'VY ™TÅ”ïÄèÆ®•Û·\¶­‘+Ŭݨl)Ì1$Rªÿµ—oªÍßtÁ¦Ù¬Ø¶h.O2˜'nb¤½ÂÅËW_]ó!ü£çÄWÃ?­2)*Ë‘Ç;ÈÆôµ,ü`´,¡^óB›Öœqýô1 =V}Ü„¹ñ^">‡Ó±ÿa•:É$jP#šùâšk÷c~š®\mE•iÀ‘AôªNôŸí7êù=<ï³í|]K3ÅY)«SjÄh¹|݆NÉtP–XOW´?gm´§O"~ÀŠçèg-­š:áP/é̲äJùÖZç¹Qî0Û•N¨…é®J a™Ã¦Ü¬l\ݰš+ê”>ˆêB üAÑÈi ™ ¼ªám ²ê´®ºG«+ë†!&6¬ %p­iq³˜õ2U–@ÕôžsT ª™¨b¥EÓK¥,ké´_AͰ–){0•çÕT̯©ö`PU‡<]Evñ¶%PÍEÏ3ÜÒ ¦*ªe× !Qpð¹p’TóKà^™§Ó¼L뛜“É’/ÑÇd \ÖV½= K¢êýš.Ëõ’–‰¨N:Š4ª#Jà:õtYzJè¤~†ÜXc5ƒ-±°ü­›Š%CNÑ%¢A3n«:©EƒF—Àj>/»~µ+K ZŸ»JÌìeÏp3%PÅI@ŸòS%ð(­®²þ)L–ˆºo¾¤ËE ü¥"fúR±cž^/ù(3~Y¼Ä •˜9B%fŽéx²äK¢ªSŒ—±N”À쮪Hm v‹Ñð‡³¾}¡J`¯ÀqÜWM•ÀJ \Æ QÕ©"ÁÃu*,x×T ÊuT§$˜ͳ‘ªü–MŸ†W%âQ(æ'ØËàf0W SÆ, …I”ÀŠ­«—èQ(E0…lyZ²:Í–À5«eª^”ˆíÖ%urB™]\ô7 J`“Ö`¡…uCãJà†*5 óbœÖKú JDÖF· Y-A_WÂ6zŸ~’%ˆ%C ëH~Â4%0Ý2-%JDæw5éÆmOÛt Ìû|ž÷[E²¦p©–o"-?®–Y7¢žÒeßi£a"ºÔ¦cÚšeuD‰¨=ˆÖ8Òl‚+xíó ¯=[–T‚1ç–T‚1ë–‘'Jļ[F^WªÚ¥mjq¥´Ç‚‡lÝq,xâa,{¸Z,{âa,~¸Z,~óŒÙÐÊb™d—K/J J—©0|Kä! *™‰“¼¿eª®VE&.®VE&ÇË.TiNÔàj–bê× ç W"ZŸ§eƒmh}®K`Žf°š@ª4ä¨_wâ8-ÒÞÚA lu¢=X‹‡ö˜W"¸…$ŒS›gÙçeæYöÛ¶DdÛÆUºü2-BI@UL < ³Ò; e lÐÊtÑT¸´J«L—²oñ¢XZ§ˆêPÓ-¶%bÃ;®… oª–ŠHbÇŽ-×\Ô¸.®iJDþd$¾Tµø{¸ó½6+'M[õKºžµ–zÕÆØ«6nn棪èù”.ë-íñq4Ï-ÅMoË‘70¿‘7!2¿‹t>š¤}¦JÄž øÕç R%¢ù@îÃô°Q—ˆã²jŽy¶-­©Ml §²\ ¶*d¹¡|ða jáp‰\tñÂá2rzÅc(nllÿ7K¼P‚œ'ûºÿ’šlæi[罪\• «ÕÕÛ‡¶v§,Dñ"û*^¡Eöµ$êÄR*\$.¨z£Ëx+¬%¢á0­³~£,{\„=ÝÙª)–ìDB‰Èάë~1Q%pµÅLŒÈjÎw)+"!*Æ22¿¨ÓhñV‚G>×ýËfY"bH9.ðnbˆ*·,^mâ–E«Í¹˜ü–ðC”ˆ+Å;¸R´ Ó,®}‰¨'3#¡Ýê°ž_×îÊIä?kËÑ’är‰×]– ?†ª£ªÊÓ½tÊQµeîVQ×Ñ1q-O¥-}n™yÞbÚ<ãé2F>¿P½îº°g+dP¬èÏ´¨³trœ‚) hŠ›MÛt‹rÿß)¦1ÇPˆ4ïDÊÿDJ™¾¡IÉCl'à{‚̨ð”•<¯>ÉB¬`X‰ŠbðȱA˜ØJ^g9¼´Z à¿,èÓvï:§ýÈy5ñDuì‹Æœä—LG‰7¸SÑzÛëTöópýea3_o"?MÁQ™ì·åõä·á =RáMä¤yŸ÷ Ë7‘×qѵdiù†Üp¢†–zƒ7·mäíW0ïâ*ÞÊUˆW”°J:;¥*˜wØ;˜gŤ¡u©yíÝL3k°T¾ÁJ¨k[º ê +3sg£ YNYHˆÎdô>Ÿr=Ÿò€eѧ¯G£š–Txƒæãº*oæ”rWo¢}˜–™°àM´é0á ÇÛÕ“‹’°‘«8 ÃôËFá—ŸFV¼Ae?³‹w›t¾ [opáVprJŽXù&.`(ÖÞhV&Øi`Ä6 û G9'â Ö[,*öè4s?¶2àÀ<Ž© }§AéÈgº>ò¸Ú–“š–·Ý_û&Ã;ÁFCM˜©%#3‹”WH¹`ÑBüaZ4U2n䳤QDiÅ3†)â VžæFÚBëm’*8VIsÞЀaŠ—°áì‚cñK΄íáIæ2a‹Fñº,ÑÞqÇí¢hÔœ+Zä,—Ä’(¥¹oh¶ÃP®³hDùŠ´ò Y~˸á¢Þ‘¦…|ªmT½#õ«|…KðÌ;žŽ]è.0)uü™ö΢pg±Îhyš Þ`^MnhhxÓÓ´›‚1SÂMÈpÓ›$¤Ü[¡!Ù IĆ ä§p6i`I¤¤M°7@§Ø{áïñ¥/â½½6àoPÚð7° Öþ6ïâ*ŒúG §eçŸh—)Ü…y‚‹²Ê±°]w£º¯á -ð}»™Ö‹7¸lË–m£²#®M56*jv‰ö•ë[Ô[á¾—U£Ò.)•9„Éõ‘°Î*µ°‹€¢e8“ªP:*Ý*Þ\YívâJø •kÕX)Ùjtp_¶U…ýMòýGt­™ˆN¶ê7à{¶Õ¯Ÿmu©4…éVyúC2ö ‚½k©Ý5ÙòÞZ•RìÔüy©Ädok[ç‚4^ü§[ƒ­]1˜kîm¹jô•Ù:Ǧwo¶»2ð®ÍÖÂÞžm/°ùÖM½où*ºÙÝd»‘Uï½®Z1P†];ƒûFðMú¾F2!ˆÞÍ؇ÏÒrjöyàm‘‚#A«¼"Ü|ÞÎå®åêyÝÃÙd_›UWÚÞTŸU])w%TÙG[r¤ÈûbóÒ4V^ïèQ)­khÁt!ÔóL¦Ð×Êx¢›¢*¿‘f1p%+’_;`'éG0’‡æÒ_¨õ‹»ñWUŒÐÈ|»ð£­{?X%¤‚Žôé²'?|xyþþCx—2ºR]rQ§ ­$kæpI¤L”×è{¦#˜Êí®*°F&ù:±cj7kÇ7À2ÿ»Ð»ª®Û† `¡`+;¿HÜÜ~’ªŒñ7ˆô’Î×wVé=•çd—»H8qˆ5áŽ[UŽ…þ¤TË}t™ÝGý·óWo_žŸžhT•“Qaê­^i^A«ª«ríJB ÖÿD\­] B¼ÖÿR×®EÞ§ìF^'±n%Å»5+)Þ­PÉmyÃå(:§§¨e6¾ñ̉£›fÞ×Küç?è_eÑ,ù8"¹*G…Ðz+WZJ±Œ©`èu»&Ï-Ún4ÏÛÕf+Áu#íŠ\^N²Ü…áhö6oÑ«0:"zF¯N´Ü âˆöö¾%ѶOåÖÓš•ÔÌüµØ£I`øãïšý úºm5Ûj\kÃ-¹ÿKBmôq,ò7ÿ©†9øX¢­çÉ‘\Tédíîé\µ¯@rŸ(þ1bHÞ&ã/äzüªmKî4 Q.¯ÄJ>Žãj>‡ žŽ³}NþM¼1eë¹9h/GЂïnޝïæX.P¡Ÿ#©?ÄÑ‘Lä˵!‚soy7VQ6¼y/žˆ‰H°<^­O•Zn)ü;?IèȘ·hÇEÚ ¥ß™zò¢«u?È]ŸPn÷˜z÷ƒ›íž³€‚±&vÒ$^W½¡ÏÒñ,Xë7nì®6 dŽñ6Í‹æQ”XŸ"õWÕ= ãXÉ`atl{Ö>ñ{Ç>ô9ìJbržãŽ4ìQ ô3¸ÔM!÷µ=úÅ„‡òIÎ 'yâOr3÷A$E['ÿHê¶H­"Hç;OKÄ=÷Ûn¯UªÅ($˜@‰ª˜["}Zè‰Ô Üá,3 …’éˆO<œ8rí³Û£80=èÛ p=g!nV}?޹rr.ýsÆ3¤\äõ²ä–*éªÉB½ˆ_D d¼õÈ*«¹ÔD¹C:I¢«Rœ'ðkªvÿ~ä õ/I&M‰Å Þ”3ßÎwsâ ¯Hû®×–{伤Nt<¢œ4)䙺xCnÉè z>lÔ^Â<ý”%ÝB!h›#PwYœ©^6K«sê(V®t;/‹¼Ì¶æòø½£u³ZÕ:¯¯ü„Öëâ* ö:lÑD:´Á>­ÓÅLÝé W>ÊYQ]éA—Hp‹R.éq_V•†¢á]µŒ·…¤ûÎù§íÔípÆöY²!7 cÒxŽó´éëñ0-ªQZTþé#IS®™n%ˆË‹tûå½° ŽjÈÐSg¦-À̶údÎ|ªM,u£œXDsRp‹÷–Óð§p׎=ëäŒ_f¹ÚŽkªy&&5Q–™²'GÀ½«:o˜½.Ë¡!ïÈÕ»ofgÐ^³%‰Û€œ¥àì¶÷þè½ ½ù3–¯óf¦t™™^e8Û_ Ä¿+“MOõô=#æT§ý^x,ø­/“ Æá«¼ktø}5ƒûÅd;4©Þ8 –ëÁ¿pmcÝ|…ûF‚ý–Ì~*À¹:Dº¡oƒ'¸§w~á,Ú›wî.`U]^<ʦy)lJá—Í]Ó¢ÞûǽGZÝû‡Ó$#ñß±™`ÖT´É»ÐT;ÿ}K­ ‚à\+äµÔƒ@‰Â¿«ð<]Kþ¯(*)ST‰/ß“W›A/ƒ®VÕ³k1„¥@È+X`‡ÄÐ$“¼Yh?Ø©™Ä`§&²è²ŸDÁÍ Ò.ÌáªmÄ>Lîûq‰Ïsî{qwò· ò”?]¨íóäÑ¿;s6&!Î ±DÉàP¤%»‡\eOÊÞ=«F·ŠÜRî@Ñßf‡òâµî ÁöûöðŽ$ÝÏñ.ŠÑÁ«SËæ‡÷Y3|õþ»V6p!b!»Ë­f­ý01Úcèȉx†…>Çë§ü³Í*ð @m©Î ka.í¼¹¡/ÚÒj;¢)3ëv>„ñy¥u—¡¶”~_Ü$I‘lY9ŽÛßnûÐSh=B#åFé¥^!eü܄͖ß7‘òJ°m,|Äès}¸%hš¨bÎ|èáŽT(y2§Gä/wðä¹9b •ì¡ YÈž ‘¿ì© `¹øîd,œ‘O>÷´ILà¸I­/¹÷÷Èÿ;ŸMq*?ºQðkÁ‹b7ìqѨàPnC{ES¾iÒÄH ¬Ïý¾±Ç×ü‹Š 4¹e¬ §üíMÙB; /Uþv®ä§¿ñC|ßNñïáıºVº°VO‰™™\8cªCéÈ€Ö1X&iGªn<(U¾5 á1Q†šs€)xle1ô–„|ðkÝí¿p=gŸ:Žù¥ãÔ~¾)¦«Ó˾ÄÎÝ™˜( ÖÆ-x|ðÿ–rü{­Û¡æ?’uϬÈWÔ·F‰^ yŠê¨`fÑ}ç[$®ÒìZȱ¢#_4©·îwÝ›ß`, ÕJ| ¯z!ª{l»€è´ˆâûX‹yi3|(FuE­B ms$rɳ²m"i¥]e‚`Ás¶!ívµ¤TΧ`®”-¦–÷f±¯rƒHë.ÎM¢™ü¤ ¨ dUûþKÈù¨Ÿr«¬R¬LFåVÐk’r*4‰2E/ådhb@“½#ÎdRS£É• ~ìÆs©I{  ìû?˜ÕµX|­ó'âÊÿ1)˜úG&ñ ›‹€ªç nÏ”°y&”5€’U(ÅÏxA"[ý !M–’øÀ8òl?wþI~Ó‹”“?ƒò°]ìûËí 4l°î´k¹‚zõ°ô Î±ƒ8d~ð8Ö¬˜IÞ çÑð“çæìi¡¼w§W!YÓšpÔ:©÷­{èsz-Ý¥\ÇÚI·âJÜóÊm–NIë/ÄþÜbòµüd îï±…û=±8àõ?UïVXXˆŠÅñJ(—…Ng{rjTs_0ކÿ6Á81iko£Ñ9A+¾äÜA@Îr© #rB¹úc"rbšíW_pp "¶…„Ø+gçXˆ  ÅlF¼„-—dg#y/Ó³+¶«ÂWE¡N/¸êœi»óCoÇèO9‚¢1~ÏAmÅW$è“Ó’Îþ/©¶4Ë¿¤³Ö³ßRŒXò1Í­åÓ¯þÚ)®W/7Á¼¼6Orþþå;¯›ä½·…JãùJËô‹‘Å›…P;°Fl{ ntòâ±lø.—^Xô›ûîÍó¯®ynEx¨j,É?`EûÕ4íÛªV •‡ÇàH£rÙËm”7õ4-óßÕ¤ľoE‹Ózbží>=Ðúî-Ü=ÓÈ͹'°¸It¢VyEpqZ§%œI 8È&w~Æ•<ôæRоÿQXsÓ´Ù\írxs–Ü ôNM‚È>}úäpÃ$4™Rå¾(Üæ1VýgÖl@‘˜Äuy|¿t9jàÀн?ýÛÎÁ6˜öRªËjsTgé§De«|!×ùò‰Ì¨ 7’ÿ±½=ÜzÊnå°‰¥Qw,ª¼µ•«H¡™ç&)oýIcíXc0M5ÖÀbɧM>-uÝYw!ODªº»¶®zêUÞ¥?ÜÕbÆS•÷܇åÓñ_¬“ÉÓ[²þ¾­O¡ª`êM—–>Ì> 3ª/GÂ’‘0fTî{o^˜À]©qÄS y@B6ê8„„|b!MÞK¢'dõn^؆=µÕ'y*Öü¼RB@Rì3÷ðÄCÄh7ïÐ1ÚiA‡$AU=¹ÐOœ_dsHÛ›Áë¼”ŠX†PT†9C¬HÅ\ƒ9Ù-²‹vsQå¥ÜeœTÌi9ÿ +v'Ë¢õP6±e§]^ÀªÕ_="¿ [Ȧ o­?¦{svc«:!o*AÄìf1Ë@Ô&;?“®¾Ñ5è ZgS ê„_<Ë1à¢eØ{"–Æ“LñÀ£ù”„Ÿ§ãÚÀ»±1—»XžüØp¸Szú^$÷/åO'äg¤TM¼¸q£.Äð<¢5¬Øçjð?qCžnÊ+ƒMû哪öjXZ™5Ýb`ˆrCG<3¨Údn¯*`€÷d’Osûüsñ9ú´ÒuwÍ7éoÈ(ò+ú͸Ù¯ÐÚ1wm¦¾òÔ9õ4KõìúQ>Öp{doÍsÑÓÎ:õÔã*­"Á{©[üÔ žE^ˆÚW¶§L¨™GëÇy>™ˆ‘'ñv=b&XVTв³ªžæÊW5Oá`Ü'¯Œþ­AÇÙ$×óãSoj§EêñM?ÑX´ö¸c¿OvwUÒ]•¦OXµ:7ÈÞ mÆ]Ñ£Wh½Z;½úÔ(©áWU¬j:à4ë­YáÚ–=õ]7ä.»b*æNx©¼%|/­ÁüA>Ö¡u°üÈ@}ä°÷#³´¸À_€gžÖÆPzWµáp›…WƒW“Ûø ßèOÑš9ÿÜe’ýCÂt“o½.i»ºÄ5þ‰?cð2Søn¬rq0Ny+j¨ÌdUòEôR>W9–Ú è+JɯìöÅÓMÇ; Ú8¯ÇJt÷úÑ d7¿(²k 9` Û¼˜h÷û!eI¶Ë )“L¢ô£!“ìxA”‘ ñI?¢Š”ñ°q_ÁKý¥}æK§En¾ô”ûÒi-*¥Bø2ñNãÐøÇJÙJüCÿXwž¯nŸÐx§V€Åz“Á;õX£=eЬ ¶wúÑ|A=dЬ ¶¹ÁuÊê´¢5ØæFÒ)-ZG4â¹Ç@n4Ç ÝáÅ›¨OOåøÆõé7(ÞD}zÂ(Ç7®Ow¸Añ†îÓF;¾qÌÛáÅ›˜yŒ|ã$d‡oH 9at^›Ë~Ñ[^ÁjÖ¯ä™Á'´•ú¦)Òf¦P¸Á é‚ÈO±þ“HýF~ôd‡ cÙaTàGOv¸Áñ1–Fû}ôd‡%ÙaÔßG×Ûn¨|¤{›Q¿º&¸áòkÜdF~øéͻך>n¸È2†Q{ÍïfZ ð‘£I3KëEvjÖ4›¿›õæ £õR'&â©$ø‚ÇÅSF!¦NpxìXXlN˜:•3À£$ôÎ)£SOñ °ž2ê0µÆâ`€GI€G˜Šæ½3O5™fV¢vñÀÑ(Ö‰©á£0ÇÖHìâ!¤ Æ„‰xʘˆ™Õ]<„Zé³SF;fN(wéq”ÅBÉèÆÌ å.=„2F(õ˜9AÚ¥GLF £sqô¨ÉcÆ1Z1÷G˜úøö9^%J?lM„Ý’w¶ö¼Ð<1­AVk}@WP§ˆ–i–!'‚-¹¡ÎM_oéäX—iÑéM„á<×qnÐ-—Pò\õvß5•DçÔÙEVã\ÂRQõ:…|èc™ÃqQy#ƒj“×/¥U¹²ÉæÚ"*«‹DÛ€{‘óW)ß ÅÏYUÁÖÍEWÊÝ!>G€ü' •XIM½s(­´6œs”)…zõ‹Å,Õäz>²©,jøY \H¡°Äß=D3ÊQÖ¦‰ÅÙëljÂfÂü˜Â.­ÙBa# Éiýi7Ä;ÉŠÖáôãM °ÆÛ£ñNM^T¥Æ{Ò—©Âq?Dú[À°§ýH¿;† ‚4Š‚9\BEy‚|I³Ì±Éóv‘(íÌá<¥Ùt^yó|]$^^Y¸Ãæ/Bq:²ý0Ÿ °Æ†8/Óùh’œ%B^ÈÂèˆnß«.q\,‘öy§ÁŽ‘g?Y"ë¥9 Aþšû Kü:× §t³ÞÈ8-݃%Ò]©Âñ,DzµDºš,¤“õnVy`Kd¼žUͳQÕýrBMÞçÓyz±¡SF¨¢?à\¥b(u »Kä¹ÂšF-}H;×¢Ý%‚ݦºï‡{ÈCí+£Ý%bÝie´d‘ßÙ§©~;Ë=ª—Hýbfzõ€F;ЖˆÿØ¢!Íõ¶ñQ–È¿`FaôÖ›y6uý¼tˆÂïÆKýÙu·Qû>£¹UŤÅh#ÊØÃm ÐÜ «‚Ïb°©?Óîá¦`Þ<{ÄôÄŸg÷ðxмYöˆ™e3_°÷ð€Ђ9öˆÜß}Æíãé-Às3í#·™?ãîc]g±žÐX­?ïîc=`y³î#½¹?ëîc} ¹9÷ˆÝOþÜ»{æÍ¼*¦,F+üx¿w øóï3ÿÎý©s¿w$˜ÙW„ÅPeÕ;̬‚¿b¨kÒÛïf&>bfâÊŸ‰÷{G@0%¯OAQ—>Y½Òofâcf&®ý™ø Wöí<|Ìh39M^¬^Ù¿á‹Þ¼zÌ(µÆŸ§zG€Æ(µÖŸ¥z‡€£•Öù*í wt¾J;fTÚŸ=zG€‰6°z‡€‡¶ðçãƒÞ1`gãcFŸUþl|°dعø˜QhR67s‰ö¤·•J-+ו=Ù‰Çô“ÙÍ9|‚›j:Ü­ä¼5N/ëžâ!Fqö¥^ßgeV‹‘ò<òo…DWæOý ox‘A¼ô¨Hdžà3/¤Oz°=#nÑgUëJ¬~ýæƒ:½ —G¦yS-²ÚÄ;hu7ËŠ"_b¼­âYUç¿CÞ6ÈX*Ѝ³**6vRµ¢—Ò‰Šót º 3ë\ß àÞæ–zñ²HÊìÒ/’‹LE&¶wC§‰32C0§Wt´Ál²qUN3/dz¬Ñ¨»4j%ƒ³ ª7Åz‡(L€9ñâîâ2¥¶ñð0VÌW‰­íƼ€ä“üâ"«UY åúù9`Ïa9©TÎTùºÑŒ…“Ííƒp¡^( ¡›Tý9ÉUr3ºOϵe*æl‹êž«†3:t³m­:/ŸÐtæM^:¶yÁç&gZu¡žÒ°O[:7Á8HËçÁñ–êÇM :±Ü=V÷ÿj £xäê›mU7Éûpå¾¢š-SyÅ»Pieò Ìü76œ«‰G‚ë³rSZZr¯:ËüeÍšÁö™î°‘#FÂa«ÃéÑíùÀl *ô!7"&•[Êz㞇¶Ê1n5*µÔzƒô^ÖoÅÜ€òAYJMª•q–[Ç«¿ç!WˆðÆÐ—‹vÄD ¦­Ým£-ÇH¼ëÑqV-75¤9d@Š‹¢ªjò-\ÕKE,‹}²†Y!â"K¾ÕGQ©›«··¹¼M*¯ÈHtÒ'µ+Q§ 82U *`.íb1‡?ñ¯ ˜µ=.#½é‡É±„ORd„éM`{8hÐ ä ߢOzÏa72 îj-:•KŽTíXEÚF‘¤P­2»H¨b1­¿Ÿ¥pÅZHüngšÃƒ'¾‘ú{Vjw_e)€mn0‘» Í"=uøÔ ¬ÓÛRðZh»\ñî@Ù æ+^A¹ôm2ˆ¿zgž‰©ørÐÈÄÕÕbQi»j&oîBæT!´bix‚h€×’°g鼮Ɵ45»!5v›+­[צC„'_ÀË´cFåûˆû$"¸I…ÞL!Âë ç9>ĽÛpQú^‰¯}pƒHéirŽþ¡)=ýì¨úß$I5f!™+U¿¼¼ü†¹=ûÈGç6<¿Üø~pãÿ†ƒÇÛ2Å~ Ó|àH^¶ªŽs æN­½¥Z” 2 Êk"Ô²ŸÛõ[+Ú[‚ˆ§‚‚ ]—N€W8÷J°3a–³îìè.mê è5¬‡d"ÓqáaxÿF匒m‹dG¢Þ¨ Q;ûæ„1:Re} ÕbU™ÆÚ °´ÅhJå2}Þ”Ââ©7ìöVjî ô­.s¹i¡/jG¦Ëûqjöv£“£È'ü^ëŸÔÄíílÓMn|Túü¨ñ3ǘ;4æ¯./ìî._ŒFý•:ºóä)ÁÔ÷:Tå•X÷Ãl¤CJ›Ôy]ùñ'^¢¹©d"1ìq]¤R~xp|@Dʧ@½hz}&Ö:Þ*1‹É̸bÌTV6Ö!æ§•ƒüÀ&Á²˜ò$eb"ñ*»uw6*Ó–£GùmÐã­•àyPý¬þûUù›ù¶ŸÁë÷¬†áѯ.ú7±.0ÑTÛÇrÿþÝÙ±˜ÅŸlc¼ß‡·OáX'=XE=÷°Â˜€Í¶ÚT+J“¤P€ö€Õ…†sV 4¹âõÀÎzÀ„ÑÌ ˜·¹(º{bçvè›u~o{u÷ȺE#Ónêº(êC/äÂFÃ=%{À!žôâÑ9F›‘ç¹Êôº¹ºÚ<¤ñ†DHÈÄ Ï„ÞL'±èI¬à°[¢Îâ9 ð\7j¤ž¶ay“t: Mƒ¹Q¨žë ÆmR$N‚ªû˜Ža‡DX€a\˜¸EÇèÆÃ‚ØmÐmw=S62¬˜åv,›!ÆìÇ›LY¬µË³ i›Jö©Ÿ6be_ˆqÏÀw,ÎMò%ÄÕ>qÞ™Õ}&ÆÏBPgÔWWF3ízûOò¹cýðEc†‹s·SEˆ2Á­/²”¾ ¼€û㮪úYômÕ´›g¦ˆX™ø7Ð/ 1ãÌ*1›Öä­1ÞÞØQòžF]óSèU8XëbNËj¥Ž»Ep¹×E›ô°VW«›K^,ñAµè’cÕRÑíÅÕ¦ºÞ]õãë7ïÐ]PTÉçÿ{ûœ`+ù1A–cí¸uKߺôðìf‰ÂV¼~'![yõßrå• ®¸2¯¯ÁËÓW¢‚¹‰H6 ïF+@û&×Yù¬¼Í'h’#ÿû=V_#[È Òºœ<ùùC®­asN_³gy”)â ÌUzÁ=š::âh3ã2×ì¥`{÷½—26+Ú¶ÎGp »Œ*··Ðös\ŒëA™•¼¾Æý½¬ÕÁ©oô[üo¢4moáÂHAØWºÍµá»øúz`¹P…J‹Õ¢"¢mk“‘0ÀÅR¼\v¯]ïðO¼›U…ñÓt ˆ|ÓrŠÕëeV$ã˜2|Ïå¨~*hœÁmÄ%ì3Â¥P+5Ϫ‰Q½eÂT#5ãÞ Õ‚*é›DE¥ÓWo?üz/¼€n¤¯¹¯Gµ~§$"¹oÞ=Oäßörd¸z„9‹Êÿ€`¤¼ƒ™"[¿“qøáÃËó÷þ‡Íå£ÇBmo©þxþÃá¯üÀžƒN–LÁ{”ÍýÖNݯÄrÀà™î¿ 5º|Ã]ºþðnu£:®lú~ ^qï¡_üO=OBÖä]#߳㿠»Ç£ÀuÐ|^•Lß :)°Ñ‘*ñ—>ñ\©®"^6ëú¥˜I×YgÎ5óÚ’ WbÿŸ=ßzMø>ÝÞÙtËÉS4×úõGNµš`7Ϧ#˜iå5c7ódœÃ®låm$“‹r#ÉÄÃO£ÉFòyÂe2Û)I]¦õ—MÎzZVäܼÐìE³U@<¯çý·¡‘on«çee£çáÒóî=èyÿSXÏäz^¾gõ¼ÿ6Ôó+éùà;J:z8@ÌÖ/oÍo]ß²\ýÆ\÷KIƇŸxÚÔÓl¾Â¨‚VëôA‚&Ÿ|?øoÃNonÛ²²a?ü@¼wïñþ§0×ò¹æ±üö߆Ìö(X‰ÓÁw(:„ìa³÷±ÞÜšÍPÙ²YüÀl¶ï%›½OElöÉçšÇ³Ù{‹Øì(XÍþw:Ä ÃsÙ{2^Ü–ÇP×°Xü8l߃½Ï`þút3Íb¹ë½ ™ë>¾oý4d=ê:c4uv{%9ýœaÕœyZ9crÖ«‹³5œ18[Kùf½zW˜@V~æù™fãç~&ª§0SÙêýïη&i›¶7 Õþû·óWo_žŸžü€ îá;Xó=Nï-r’À›[;I ²u’ˆØIbßK'‰÷©ÈIâ“Ï5w’xo‘“ÄQ°š“ÄÿE‡\.õ0:xX­ÞÝšÙªºe·ü‰î•‘,>1=l ß\žñÁ{ÄzŸ–Õ˜~ G¬RyÞ{/CÆÃ‹Ûrê–‹¿¿í[`¶÷ÌiŸn¦Y,½—!ƒÝÇWâ®ÿ‘^÷ŸçÝèñþŠO«lºáb”ÿ/(³’ð¨¨ÆŸVÝs³ðßÄ‘¶¦ö¢6|w~}'àR™ Ý€Xªþ? ¦Ùy'ùåF²¸—Þ>¹t·Í­žòËžE¡{‰…âEÆ>+ª+nI(jÚ%a~‰—„æ­\ºDKBjjI(^óKB÷R6*DEØ_1ZÚXuîÓÐcí1¦Þ:v^¸=éŒÃ˜}ǘ}̘ýÕ³ß˘ýÆì3ŒÙ_‹1û½Œ9èaÌØǘ̘ƒÕsÐ˘ƒÆ0Œ9X‹1ô¼ˆ&Ì>.é,¡R? »¯nýµ=ð·Úâ0ò«Ì d¿‡£\4A™•|4®=}þ‹ûM4×üí Amøî¡ùú^˜Bï §?Ä=c‰õ\3Ë|-©\ß$¤ÙÌï°ÜH®fùXg2W©¤ôUW ›ø‰m6œäù´%ÏN2ÈÊ”ºK  |x{@¼å#' Ú"°ß]-”¾ çšIpûCVÏ×çvÛÃí–áv»vð¡exë1¼eÞö2¼íaxË0¼]‹á-ÃðIÀð“Lí]Àß«3¼'PÂÄéOzÃô‰Ø!Ën/ ÂáOzcð'=!ø&²Vþ„Š¿¯+¡MÞÔyß„T%UÎYñ³ioЬ‰½*»«mR1Ú¤BÚ¤ÈYRy ¤bHÕ«@ªR1 ¤ZKTŒéƒ?–UÀb}…ïÊ îzÜ1 îVgpç1¸cÜõ2¸ëapÇ0¸[‹ÁÃà"¦ØzÞfKu3Ã`Á–Áî]È`ñüv Ãõ„ü›a·GÁnñ–e·{²Û~w%v{_à_ÎtDë®g_çŸg%žNòÛ'&£Wr™€ì_Éy%¨•œy½ÒJì÷-êù›,ê"ª¾Jà¹#ÿû¢îë/êLŸ½RiûWwž$ý!«;,`n¡——XåeEßÒ.XÈ©k¢Ð:"¶úB\•®#¥|›©ðj&¤4É4M©Mmï»`À³äÜ Èütk›üƒŸQ¼—¡V· `‡šf±(þF¼} SŽ÷<çøT“¼fgïe8í¸Í(/í+½×k©J'ú®Éxýæ„KL.±•ä¬ÔÿÄ$ë[bgÜ;+n)PÓz ²¯Á3žñ«ð¬žõ­Ã3n!ž-±óþ(ð›ÃÛ8N"çèüäÉ5¸¹‡øSvsUÕ“ÄW%¦ZAѶŠ| qFî”»¤\:7¯¼%¾(®7½ /´=y P¼=ïØÍ:Š w/Qè¼xqÛÙPׯÍO*0oÞÊHy÷™(DÞ£›Š¯ù x÷EÃÛ»ùÑK™©ŸÉ`o·Tç¬ÌÈBsÕ»N õ¯µz0Á!3‡r)l.WVP/f¶pþG5TCj¨×»6÷JPÓ y½Ò<(ÙÓ7íÚ7™÷üŽú2<ÞsäßíÄwøÇÍyÄ*Rü5JA/k ´IþËÒ\6!oí»ÈñE†É¬mÏ?¾ººÚºÚݪêéãï¿ý¼J g8¡zâùÍfToB•Æ | j#©Gcñ?-üÏþÿ½‹æð1Q¼ôo 9ë/$pK´ê&ß» ®¬{†ï»jÄLði+Ñ:÷z4Æo[ïm½yU£š^Eüά®nc¸^$iQŒàžRÿrDÁ—Iv‘vEÝæ!µ³­äëYùc]u ÅZñ9Ü3>Oo’‘ €Ós(VÉh8c@¯fZBÿœ¡e*?rfí"0—´½#=:;+Ì]†’Ro‚–ÓEÐÈpª¨Õì$‘¶š|¾(L3`ËÄôÏó ñ·9/õßð£¥^$îé‰yÉ"l»aûH·X-¹ÑC±â–&ø‰„û¸äÕÝàøìsÛ^Y¬É'F ´ÐÁ¥ºµÐŽÓTÞ¬ä!Hðj«KFüßBÞ¶cî°17n(¸ƒHH\£î¸÷.¾W]/ìÓ1|¶tÔ¨(O{ׂ ç\†—©;8ï¿®|pW›¦:å³[=èŸ!U¾½ûÈõPìp1õÆÕ$Ÿ¾þøêèôÝ#l¹¡ø»äžóTˆ?~Ö›BAb{ÿ-/ÙÞŒÇÏsôT%ÔžMï47õaï†V}@±3ë£A “‡’K`Y˜/ûËöϵ˜AbŒòüq/{Ä Ä§DìiaÛx«õƒkºGKàêB7Tßµr›†¶} m¹†¶DC[¶¡­ßЖoh5ÔkìÈëÔžö÷j_§M_„G–R¡dšX Û†r e´”¡î0#³ŠDè3-» Y«PbV^ªœõÜÞ«¡yåüƒ5I Ù\#§ñ0[ÐÂÝŽ€$d)–rNÈ=¿m¿÷wÕmÜïí÷~gû½íï÷pÜûÞõLÇà^ ïTF®W`]NÑ[•ÅMâu|¯eÖ2W3!s5 ™Ót™L¼ü½{?DíD^[ZÈU÷Íàªá%²n„¼ßvîÉ%U3ɤj>›T4}{I¢j6KT¥‰B>/åjJ†võè]=æ.@¬Úåiz&¸€L_B/lÝ$K››ä*ÕWº‹¤L»Dy¸üE*H’oN C>ÚdI|-£4˜åÂ(\­é¥¼‚ëd–^RŸWCÖZ»Ä¸ôœÁ=ò×)UI'¤Ps’JáÄ_‘þ¡Ø˜†XtÜTÔFédâ΀hÙoZÅ{¥í„gž{!Yæ’ Är…ZàœšGQ/ŽRœà3—Óe§(M»·9j‚û1©Báh!ÉsÆzÌ­<{DÄ£™(„Ô˜3µ»:¦˜QŸî7¾™ “|õéú´…—´7*ƒškë5Z7˜‘˜¶µkµ­]¡mQ<#Ý¢mñw#eÌõ]±EôÝ ]·¤çnÑq·ê·µÚÕ®ÐmKzí¶tðó>ßÖÅZm],o+.‚ÚŠ3­ÐÖ裞|2;iÎ¥Ž¶ÒÞBf R{™×ÝR£Ã> ÙPÿf—W‚Úì2¯WÚì зé¨ßdÓ‹béíðüM/Gþ÷h¯¿+Õ+Eáî”'GH¼‡Oª°ñÑFU¸ ¥ôï? ¡Ñ{OÊŸ¿ðð7ëLˆ“`6—ÎÑ%L_:èÃB܈ë }sܪ@ãÓko«^i%´à»¸»[WW¡Pý¡7!ö*Xúm$£|*ÖÆI3Öø¿nÿ³ØHZ"Fì+_}’Çi”Çóˆ ¤º}• ¢Â!T^>Õ<Õ:ÅN­sžiDعîÛyÏí,ÞKÄÆüö÷²@]ËÊßÈbßJvælÒ/Ÿn¦Y0çÖa"uØÎ~[ªžžÛƒü×èò ùêÖwÉÚöê ø…Øê•ùŸ‹î ZÁ6“esð]䑱»ÃOQ´t=ZÕ{‰ØÝÝ^³B]ËêkWûV²¹c5¬O7Ó,žÁ£gÝÇWcn׫kÅT×ÇZîÆ±î .ë¼ûƺ躱οm¬ã/ëúïëú®븛ƺõ.ëzïk{ö"[&ÑD»~¢ ¯ªakÛ"®¶Þþ\Ëîϵ½I(Úžµ–ÙQk×JBÑ2I(¢Ë­¬½ºäž¥kº°wËÇ:k:}ËÁªK: ÿ-/ú¸µÃŒ¿èãû’îîïùX}EÊÔy×DzÝì.î«nóXmÍ6빑pÆ\H8³Š:§¯Þ~øÅÏÜ¥ƒ3|çàÌ»rpÆÞ88ë½ppÖsßàŒ¹np¶Ömƒ³U. ¤­/‡0[ âÓ…_è— E—d´%謀êõJ:?h@rÀòÓ7Jø,ÝâT½#ÿ»ž¿‹ä€=R„sZ9úƒr R³àh¦øT-O èjªƒÀ5gsj=¯Ë(¶‡y)ty^ŽóE‘=òCÁuÄÉ¡õ>|¦±QAÙu›Õ ÿ2ÿp#& ÚÎIÉÍSƒ’4ú’¨]£´n‹Ç]³‘d[Ó­¤iS88£µ¶¡Wü*î2¯ \)¾¹‘È\« 7’YV,tË# Jr‚þ’&ƒ¸š6S¨’f–e ™/Tðàžî̱¬Ç{‹qàMÿ´+‹Ø€ñGÜØ÷2äÆŒbn|"© xÏGÝxoQØ£`½«ø:{6‹¡“ƒ­_8n— nV‹¶‘[¾ZlBf‰6o CßFTJx ˆ $þ;Ñc÷ËÊn,ý\òHüƒÍhjwÀ*4'¿W÷@ÞÜ[ÏhJÕ×*÷ÎÊAj^vVš™]3ú¦eúm—ž·d0=1û ø>5ý©™£p^é™™-¥nZVDm$e¥þúâ Òz­në^ÈÓ±Ù¸SŽdõ)yæõ*BrV&Ö-œQ4ðCÌèY-fô¬ö*‹¿á€¼þÈ’k©*ôÌë›÷BÝ÷æ$ˆ¦P­Mø«à=бRï¨kÇ¡éÔ¿P¢ª”ÿV—ÎÛß\xUH8a¥JðAVÁ{gåÓò%Nä]»x1ZŠ^9·qv!äGÿ{¨†·ÕÇ•¾Î-÷ˆÕÁ Ø ºgÂÖÜT¢*”¤&QT¿” ^Nq‰PRíÛ(_ŒÑF x5[ˈ­y€7,¢‹¿‡…7j!¾¶ +À¸D(ˆª•â)¢oò¾ _ÑcËÉÛÉ[Ûvb,'€\b8yEH»É¼_ÍlòÚÐk8A¹ol7YÒ¾Ây'þïfÓW0›v¹!›É“¡?Ædr¤zF<\æÌPëy3²ùÈÞ&¥Ø÷·+ç…ó[ø®…ÀöêÏü±p¾¶×^iÞôñ_#ËG¾ZÉð‘%­Ý¿°ÙãJH«Ç‡ŽŒž€bÊæ‘x“Ç, 3W|‹ê¾ÄÒêÙ팜5·•¿ª½°©g’s#ÍqçsHwsË Ùô—ä’¾^ò|¯y¿Ò'ÛÐ?½IÀosœWsÛœãÜq^Gÿ?ëôVýŸ4½­&Aèü®'CÌé]I¥w‘Ô|JÌkzMߘœVb¦²Ûi“Ù5{AZ'6úP%ée•OD¬ýç:»«¼f\æ„û8 :íMàšÉ¤ƒ ¶¦#½ÐA¥èç©ü%ê‰Y´†(8UWðmS°²K ø„Ê Ufá†x*“é™KQ0ç¹­wó†rxȦH)­7€P$ÎÓq²àfÏ‘Í9s^ô{à¡„=ž9Ç'^í[yDsΞxõ©£ŽiÎ{N¼z/ÑQÍù’¯Ú‚Zm¦EÑ#^-¸NŠª†kU9…n^ò-¬–Iõ¥?õ2+§í,®‡*]å!Ú+WŠ»c…TNc i÷¸€»•Pê)8]¬´„æÌq“7B²û'Þ°5õz%Vš|É–ôOÆúßd:þ"FoqÓqЂÖ ùÿ¨õæí¤*œ C¹úC¦hšn7e‹gºÐ ®ûÈkïÍäc÷ò•3›­!FI-oå¦xšú«ÚÈ¡ÙbRQ ,‡åQ{‚^Ý Yز Ÿ:{ü¢ [ª¹Ï.„M¢Yõ>Õ[&0ßÛ€écVuSuå’C 3oÊ0É„)b·¢™˜ÌOåþÛPÊ7ý“¹,bfsø¦s÷æsOè‘ÄŒþ~–zëNXšÃUÉ?’q^Eþ#YT‚ ÿ0YSÅŠ= ô¸ªêIä¼ÛÃþÛÐrðÚÙk:Ü*ö¼¦ÛJ!#\µÀ6VZkª ¶s@Yyä=4?ñNªt;³¦MGòˆŠªE§7Ž?5gMó)»Qš‰!2n£zŒ…ôl`¢ˆAŸ_À1ãYåòTÑ9ò*µ*iãÚ$ˆ]AOëx G§³v² ÆÝ÷&j¨®¯ßªÈV QNÓr~òîô,!þáÞy ª=£7/Õ !¹~É'ÞòEö_òjøÖ¨àà ÖKm«×çhWÇB1TмäJ"°#‹µ)À*CüŸæ´Q‘Ïó2Õ¯Õ­zZñŸ·`%ü«åõÃIV×âëæÆ£äd‹Õ’n¤I§†‹ŠpàxÜÕrf(oÚÌFe4/"÷©‹øM{Rkx/QÐr¥Ö@i Â×èÑÎ@ؘægذoeDsÊfØðɧâ™Óž ÞKÍœ¢ b)ìþŸPšĊëþq‘6 ö’Uy{Ÿ¹:]ÁÕzÿôLfÿÎo2¿¼ ì=¼wç­ú¿Ò«YeÕ,]`5k.°È–,ÙÌû† ¬/bô»÷}uÇqP«IÚàûãX4Ý>ÿÒɤÑsj#gZ7­êÉ6XÛ˜»\Í¼é» u˜¼)áBMVæÎZÿð o#H Ìà|¨ò¡,ôÞM–{ ×Üöt““ —$eöŠY™Íû•ô[؆޼ÌPòÛ$f¾=_™œÌŽôïÚì’2÷ÊÊÊìIÑ“–ÙÜí¡òÈÿ9½L“¡èÕL{|NåÎŒ`Ñ›ÑoBÓxÞ#Izß–Op}‹±¿e-»’H ³¹ZKnû,²º½I.Ó¢ËD*ÉÓ6;('I™wÅ‹·‡$?÷,y-ßÀŸpåhN¥AX“>xj õªß‰£Ê»]þB–»Wl÷[ï!­„ý® °|ð:´á}2¬-=A–tp¶påc‚²ƒ—× ²’ ’x˜ÀŠ\,‘Àiò#br{ÏÍR~Í”k—/¼!&Hop­¯Îé R…þ2(CM‘®ÀJsd #ú¦H…ûMæHŸµ·‰v 'J¿ßgʯ?SöJR8Q²ô‡Ì”>±ÞŠšŒ–Dô©RKCú˜éÐ÷¢I*œ¾UEhŒjWfãe’<”7Âcˆ”±¶’7¥tïe¹¼|p\Mä%¶ AëPoËÇøútz½­ä<Œ+ÜP{-zŽ7Î:½}¤/ð‚òhÂV›BšRíÏ\+¨¼±Y„4§íæÞL…Ú¡Ó*²¡u&Eå£ù(ŠÍÏå²¢¼¸= ¥[ù  à=ÚRï¢ðúÀ øGrÿ¬¨®˜ì°ÂnÉŸx›È+#7Š‚ÏF[EaƒC—à7r‚÷h+ǧ%ðå…vÆí6>V´NÐÆG=žÁ1àµ*É¡´î— ’<Ù+µâþ”Lë}iÅpľ#[˜£°H,xÊWõÈ‚B«‘[-†‘ñ£ø×oAe( ÊXÉ‚ÂÍè3¢ô71¢¾ˆ»[œå7à»õõ¨eÂÚQ8ý!vïQP´-³¥Bëa­ã6#¤ÂÑ£b2mAâ3`Ã&Ü© ­k¼xFDlÙ˜˜ÐNûFQëÒ4aIêéG«ÿ´æcí›ð}¨;õ»žÌ÷βù2{"KGƒKGýD–Ž_,lé ¦–Ž.ÁZ:áûÐÒ hé [ÑÒ¯~<´?‘çÛ°SjvYWµ%ne€HÇ‹ù·j¥[%gòlÅU+æGoÄA?*>ºÑ•XóòÛþªŸkF{¨Ÿ·2~× "Ðr‹ÏŸ”Å÷Bôí –ÛÌ:‘±&3 ô|~ÊÞ³ïW2÷tú¬< øMŒáÑ}…?¨+ eþÖBÿ5º¸Ð#£×'#faK®é ¸ÕZ_Ï/ºÒÛü:+–&ºØ .RÞŸml6˜ÿé,ß•©‚J‹TÙ_ÿ¼rØ?[@‹¦1Çêçòë((“˜1¨@8fÌËuïã4’®Ä=`¤SKȳ)ÂJ4*ÊtH#Õ4MdÉÁo:R é\}ø±É‚´Ã:µÖWÉŽ!ñ Œ­Q¥ŸäÙO·òJÇuÕ4Ò?/†„0ÍÓ:‡ˆ }´§ËþÆŒ¶ÝA%¹è,tïJ#ȱW|k‘–YŸæQªŽW¾þkÉwÕªš‡´ŸïÈéH8݃îrõtnb~z2#ó Р÷•^x?2á‚7?‡oþ‹` -\0“á:¯/\€ ×…Äùbáòa¾’pÉy“.ÿ5šÙå«•eÇ›Ÿó“›]š¨ÙUà…Ë„Ë#ãî„+ /.è.#\GÐuKD+®yW´pîy)Yzñ >€,›dë2’ËLµX³ÓŸ\ !-'^"ü×H"ä«•%³Ð󓓈€&J"d^"ü×H"<2îN"òBsC›¹ÖÞ¨Šn^&?JÛ~©DØU€î[¸ÓOî%‹^8úy«Î÷6HH+ŽJÕÄO¬ï`C§”K½âfSÞ< TÈXR‹in„X\¬™ÎÛ:¨2vÌÛ@nÜZÌ›PpРñžp¦‘²pLÞÄA%Ð\ØéÖÙA!åýæ½PØÆˆå·½ì< -ûW %›ékÊ´:$­ë(1_2Í 2@Õúô©‹\ù~pK˜ÑªRˆÎ!’SK§—sC³ò³¶ö­šÿ5®‚P÷kZßš,÷âÞÁ޽ĢgTÐ¥ ¹ Bå··öÿ]×°WwØOŠ—²{™ã´kL ®ó®ÀféõéÁÕÌ7¦BZSÅÕr”öPvl2GG¼± Þ¸dðõŽ;fYa?þÞHÂÌ¡­…ÚŒ³wÕÕ†h/ƒŸË™ÆÛÍâ3/Ô·ðSºw¹xË^.Þö^.Þö\.Þ2—‹·K.ÿò.j™ ÉÛZ†ROyª4Šò¡ªU£Òr°ó¨.â¦}^ôÁøZÅ,?–·¤ ¸@g2`«Óþˆ^ëY42=?[-*ò98‘s]?ëíúYß‚‘[-®ÒõéhäyÌWô•¥×¹ÝY9ZÅ,ÿå?ó~y¥û¾ûØÐ Ö¹Õ\+¨-ØTY§ü—-Ÿ™á`½2'’µ|0P «Ï×1aÄvr[±õýVl# ú8/¶œ“c%Çw±ýÊb˸|‚H0/†‚UõüÖ™Œé@0ˆGêóJPa`æõJQ`ª}A`÷MbÀ¾ˆ—[\ ˜#ÿ{Ø×£Å'Œóè “4ºø/ g#)ÒQV@xÕ¢k7tÂ’¤Z´:ì«RÑa.jLhZ•™R0¨˜4™(]dS¡&6Àkí­Çdd˜Ë3Mž¬äÎÍ–:aîÁ^õEÊØùu^`›}lok[ÿâ€.©1L˜ü@AL’Y¶€ü…38]gø…oG,v×#ÈŸ¨Œa¿‹—×âr~tYE—ésáWú*gºÓµ_?À<í˜ â›$¥ ¸»$åOô¥§m–•ÒÐ`}èt¡Œrp=x•Œ œõˆh!\]#Öžy3Þ’aôÏq/btm÷È !‰¹®¥äYØ@/Ť=<*>5mÝÑx¾˜ÕiC<’Á;ç®0ä“éÏ,€×Ÿ-x&ÇíŠÑ „Í(¹ÀZþÛp•o軣üžsM ÈË€g J7ºÀ¤ôñ±QÐL˜•ò=kXúoCÓÒ£ ß¸”Zã­œÅ|žµ³ÊdÎ{˜L³Vf^mÚ åxn ¶¬»£쑉ÞŒûøzóêêJM%]]€j’MXºÇÙ¢Ý4·¶™ ÛPD‘:taFxDÕ˜` 'ÃQjG-¼g ÉKx’€©¾ÜyšŽg Bk‡¸M}a çÖ{óúTé­h¯45+öÁëPîÕ+nÉäÄÝÓôÒ÷ãëuå ¯|äëEo䜗©kÄsJ×ȉqÉHýÜÊ´­qQéøM‹øÄM°j)^!zÓ!Œè€sxH‡BŒiU€ÔÁëpTûdôk°1ì¿Uæ|QfݰQÁøò£Ç ººZß d¿‰ÂúØ„›ŸÜ%Ô­²ï„ÿ:$õ^I¥(åÐI_ `ų«ªžÈÑlüiT]C€ ˜ê+ñÿM7šç­¶jÁÊ"¨ó‰0öÅ*™ï?´å’è8È2a÷!#¸œ M`­€ÿQæO ?Êì1²W@Ãsw¨ánÁ-7*ÿVçÆn•ÑIr7ÓóÛCû³ÿ ã$oÀšèJö'™iü$ÂP“WȨJögo¥&ÿÝãÝŠi³çéu!÷/Ö©t«›Jƒ”«²üV' ¿EþpWéÖ–C¨Õ¨¦ÒgÉ^ø^þ¬zCâ‹îÔtÌßt¼GWÝ©w‘ñ.ËäŒ^á„‘Éö7wÕ]H3u×*ÁªÑð=ºíΧ¥W ÝJ§Ünü™ˆø÷Ðýìé·Ò)_tT±=V#V\ûÂSaµ‚ÅÔG%ÐQ}ó6ØšŒd·GÒì=áŽÜc2©C÷¦ ì•@ïCªzåôV‚ FN—ç&bXÀÉ‚t`*¥¢@fU>î9MÉBoxtÕ]±Ìä%^ïqÐUotµ4 ºZ]õÄ@W+„@k%#k{ÜþüúúbE1ù"»Šä1½y¨×’Ïs±ù"ƒäJZ-­W,»å·Q ´‘hÞ®"^xñë=á61yÔv¢)Ão*¢hk1¤êëO‚°Ãgßñ³ rÁ>ßúµ¾iýío¤‰:: ÆÓˆVÏ+Æ…‘ÍÕ-YUq©‚ìæùµŒêT­oµ4>gHæ®ÂåÆz{ ¸v5ËÛL]Í›7*Œ”¸cÊ:Fy/,*<±æmÏ>¾ï•ç²Z?,rÔzO8,nå“5ex¿,*|³!UÌØdè¢=’'Ï”Š„eÿKù`­e„æ+ïH Þ#O¢zwÛ£Ja—Úßœ-$”r°©¼‡-x\l>-K\ç_â. I zSyfž%o»f–)7MŸ‘Mõ¦ö¿²½¾{S¿czÓß8bwHÖõó’N]Úû»‚K7–°ÀØßŒ„!æ¦K°¾%ŒrʼnùV¯À÷Ðø­SÑx%Ô“_23ûIuöãPÔP¨éø&y¥võ—ŒFrtFA;…„tq??¾~ó…ýE¨ÀW`¥ÐŸ°}!@ ØE=w¼91W¨½—C¾«Ý}šÆ…üˆò`n•RÊ£ÿR)¿ y§”-°sˆfô^'%K}›Û¤0_×üs›”×€ïR_?PjyBIùõ‡ÄMÅ${I´àv»D¥ÎR)³€jï4K$¦&ë\s¤¿É¬ªHZ„÷ù*•’Ô}‰³’’Y·.e…I–$OrqOò¶_e> GBñ#H.ùʉ@ï¾*Ó*ÜM“€´7fÞ\ C@†YÉõÑÇwçz– Àl— ñ¹÷Õe‘×ó¢lž?ØÐŒ²ŸÿÉ÷ÅPSegXE*·‚•/([{ ÒŸ± JXÖóWàâ 6«EÛÈ•ÆFØÖ üÞlk‡˜¦½´s¦ä8§Ï4*™Bô%¶ó¢Œ¸Ö“ž<Ô pšGfd³÷Ó.ê fï(éÐ[õ{Á6%/¼4°‰š yaDÕ³‰Œ¼&ừÌpA/ñË~ßòF ]N5mgkG.Ö7½Ýlíª}Ã͵.’M ×»@ù+QH4d@.lÂ`kÒ~í­×~GÁ-Y‰՚֣ݳ“áU.<È@ª!¹¡ö‹¼LËiFëCUýÔ߀+Ü…P+oÁ«éfÍXˆþÜGFµ*‹ÈfÕÕ¢ŒÂ§vᲈƮ›d©ðFr!]ÕÂðþ•ü’`W¨©ê6ï\DAyÓ¤ã™0#Zñ…󲿍!ʲñ¬¬Šj*Vpæ…î@¦ xâ¥Y|'Jfõn«/EQ=þ? wˆ•ɰk+ýD-æ“e.i{óhËá |-£Y=ϩÄäBúå… Lˆq~q#9"–ö®bXmC15Éqåµãq5_¤å t„±œ\/‰É¢«U£X Vgª3Xq(Ñàlt“Lë´l•RëEÖv¢Mæ,ÏÄ­Fe>[I³ê%Ñãùؤs*'êÊ X@ ÄÅ 'KA™Ê€JQ-‡k>äŠÌa̪BžÃœ§Ÿ4RY +Q_w¦j”Ë¿‚´T§€Ö 6` j°aø¹\ìÙvÜƒëØš{–Ù5|EžDTŠeÌWi ì¸q©1<ÏL¢|3Þø“^™=í–Ù{¼½Ÿì<ÛÙ}¶»¸eüá¨Öóô”_Í%Ó£òŒïÅWz‘Ó%É&y+9 ž&‚^ñLȦ0‰Þœý`±S7Ì,ºšFCú|SN’œ'”(S¸ã …âç§ï}}‰AûB5÷Ôj-ÛíïÛÊ4†<õcNDhµV)š0e³v<3òj~Þžy7óy&4ÄØšß·œ§×žÑ¿nßÞy^úpê×íኴžf&Mü=ý+!¸÷h%¸yu  E>ËC£ÿŒea(„*X§¢ú‘P$2ýáÄ!Ò õoÏžã+„Å™•M³"ÈÐvYšùs[piÚmÐ&ÙÂ’&ÿþÒ ˜I&6‚n~ßz‹‘d`ÀøY<ɦP]Q|î`[6ügÈõßÝJçö€×_ ÌËòñ§2sÖªÇh÷ŽCïcô¸Îm‘]º˜z ¼»•Œ©ÖÀb6àÁ»[Í$’:}8I,­CÊÑ»¨KÁõØbÞÝ‚ç£tüi*ïIòÊkðàÝmx^-²2*¯Áƒw·²6‹ªÁbnÀƒw·ófp!÷–åþ«[aw#-³ü¢Eàá;¾|‘ÕÞ‚£w$üÒÙ¹+ÝeöEÂtHÕ:1­Ò¾…Øzwô.ü××8 ˆ1!¬a[“¹P˜㱡K`Ùô°}ïõgZšM–h”¸W›×6áîõsõN[SAÆ”ÞFEr˜^o Kv›5{+jPzoÉ.‹…¬¿×cŽ"X ²® ¶|n‘zٌůKy]Ó¯øÃk0[›˜×~*er ,ÞHczlà†VÏFMø\†,‡Ã>¿nUmßvP†!lÛi}Ch%eS1i  æ31Gu¶‡èE™Êä|¥Ìɽ…ä EvE/u>ŸŠµmUÂZ2õœœúÜB• }~“G$ˆÑ¬¾ß@86~&c³£ƒ÷Ê(†ÌècYWdõ4ÏÓˆÀRj¶›ply7†…ì¦æ¨Ì×Ö«–š “)RÂwG–+’–¨ÐÑC‹3¹)@—¼3Ê¢¡Dº3zÂLƒJÜ%”Ö è!ËÝU±¾"G|\êîd;Ò“ôfWTêÎ(òõ3EKðþΨfŠŒ°ÀÝÉ1š„HÆeîn|÷ÊíâÈk<Õ’‰KÝݘ§xfGe¾65ôú‘éÓy‘þÇj±C›Ò„\þr_&Jb͘ 4ͰÈ×ïÔ¶’mÛ…ï×€ÉÑ#âµÏÅ.Œ/ µ4ó‚wjMTý݈‹ÜY'¦5¤‹%Ôz÷FMЋåoÝ4m}3»÷ë"…]î­Ÿ-õ4ðKl;3’ï}„±.î¾ÛÆŒ}ŽKÝáøò[DÎøþû;[œ{|$×åþû;dî@Úüˆ Ý%EU¯OÉ}‡þ~ïly—*Ì7FéQ㽿»5m¬0ÈõQìŽõ!¿—Qpê¨èó;\øxz-Eº ÅLë C½÷ŠÖîýÝ’Mª~œaëÉnAø– šô‹Üm;â#ÛŽ® £aeL\“9£'(OµË/p‡j+ ’.ò Ý!‹?SF‹•ÎO•"V“nì[.2'H]ïzÙ½¾3µ’K¾øEîlºô¸Dk5¯Àõµ˜öY¨MnÁ^?gW8/ŸP¿Bü¢rùˆ/ÌÂOÌÂoÌÈ̯„-Q'­Çacă°=âAËÄM¿óͽ¾3óZ:ÖÜ1m¿­é^ßžhÑÐø®» é%À½¾;èÕîõu7X™a0»ûqÐK‚÷þGB/ Þû; ýáÞßáhèïˆæîIð4=3 îš„pZ¡ƒ)Æw?;„“CÆÝÏÁÊ‘qw3…3aÛ”\&³fž¥¾)ÐL²ËÈ«v™ÖyúÔæÙÄs¦Ø’p2˜1ü‘›vÙÝO›^ãHUáÞß ˜•¨Ì]‘v!Ý%^‰;#£ê|ðÞßñ ™WóŒÞqSo8Áö_2MðJÜY#Š´˜ö¹”&Y 7Ζ©ç\7Àm–MSêyq]ÒŸ»3ÃÌD݇…î˜õ±Oɰ^ÍC no7N‹”]u‚«á[Ü?äHÝB¼3uK5‹Ô»DÁ»"Š`&½O—»cñáçh•¬‡ÝuF¯+8(ó•›BFò×Y‘Ò‰dÆÓ¬oÙÍ2ûÌ4Õ½¡7fíë;ë+E:ßWŽ@ðÿ…¿|×àÔ½r#}jJ@(øç.¿L‹0ê1]‘¼f˜ÓÏ›;cû<&˜&•º3Ügm€û%i/7¦wî[íw¬Þõç§ý29½s¡,ú (î^a4YKé:ïÔ’7¾ËªÅ¿!ûZø@<[ÔÁÓøhSÿîÉóFÄZÄ,)1KJüñ’j +å¶>WJ†¦yÞŒ—3B×Ã~RÆÔ3Õ'!IŸM§ø®± r{iTßéå+S¤Nô‰u«BÛè·Ñ«1'È5Y ^"pŸ­žžsÉ^U&XÜSŽÿœËòjrþÙ ù¬6èÜcê'¤7zîTŸ[KpZUCyÃÈȰWßÊÐ}-&ªdÀÑU8@¥F?É‚]M¤¸¸óärŒry‰PI?É¥;÷Œò#^Ä[a.B.‡â²ÌdvC#È‹E&&3E{Ò“ù…p;”8ÐuŪy|ùä¾z\Ž»ºÉ/ýܾ²OMþæê"HÅœœ—2‰³¢˜Ëœ¶‰˜]³FüŸ¼Ó»©‚¢ª2Λ>«ŠIˆè‘al‹-UWSAe™&¾­K©ª6ù´üÞÛc™¾U|)ø²-hYz¡)–€= ðd·m6qÂ÷¸Šy©>{Ý>ŠÒWëatjùŠäþá}]BÊŠKvýüÑ¿£LµðÃX?ó´Drã-Fz•¶³˜ §é Á”@9†â«— $kOÇb<9Þ(é >ýêå±)]Íúoó(õû?pâö¾L»RåÆ ÖÕ?;ÎÓÙo©è¿l>Êà¶#NÌY…f÷Ùƒôºþ¿‡÷q+ã¾M‚«í¢œ¹_‚U®I——Ù“@æxlò×b¶ ¬³Á磱ðüQH{˜wvÍÊDêÙ%•¹¶© ³Q‡SyaW%.Î {[â\rTL`œÂtÍÀº¬¤FÑ E˜ñø]ÆH$1ÕÿîÇHÏ‘6 ³•šïݾþ•ýŒŸ×}ÆéKEŸçED½8Š„Ãô&wÛ\îM±"xwNÃts!ìnÛ½z—´VE‘üCš‹¾ýG"TU9N[ø³äQò@¢nyJÅ4<Ÿ"ªôg‚w·i‚½@"»·’è¨ü"FövgÕsù Øûƒ³,ŸÎÂ[ ¯òI; ž˜. Þ§ð#hâ×wXÃ=„¬²ÑYc|ró:›( ¬À"at%ƒ1KáBÂÌú.ÃÔ’üâ"ÉÛ$o’´h*T bÕ‘¶3ÎÖ °fÎöoÑÀGt<…vœçõÐ̰SEr ׿¢5·ê+ˆ@Ҽؗ,´V¨›NŒ·{ç¯_~<9Uâï÷ÉRÏÿ®H;U÷H6ì$ÕÕ<9ÿ&ùge.oò.[Tu›î?ÙÝÜÙM‚9È’!P7ó¦JçMª¹ðöãÑËóãäÞæãÇ¿ì?~,‹žŸ¾O†Ò üHÞ«‹Dž%C±œ»²û“JjŽ ¶¶¡ò½‚®º§?¶%>,Å›&ftbŽdêT»¿:5£%ÔŒoCÍI&=ÙtŒ—ÐQÞ†Ž×$pÜ¢“Ê%äT·!çM=QÝ´*Õ*êÛP±>3ê>2¦õ§ÝedüXgÙ'CÁjŸؾÏÎ/êOË>+Û=,3±°OÝY~j»z5à½T‹‹u óLÎ@Ó¯F‚øD/ Â>Y—„÷Òw°â÷~ß÷[¡o—v}V •Txºy¥O´ÿiJåÃüUü|™%iYf×b~—óÀÓ§OŸí>=H¾ÿñÕËG‰?íU×ËšqT]KáK0MOêT^f¼RKxÇ7õβ¿ëÄÔž–ÉñME>^íÀ¼ä˃e_~]•›·þú ïë“|é¤{’‹¥‰°7@h^‰5銚C ÷}X(¿¥ Wjó¥­2ÙYí«»ä³K¹ív°òg{Ù\vó¥}¬îÉ•âý^oÄþX§‹Ùª]-¾ÑG¢[jѼíFEÞÌVS)‡×Ù• h½í“Œn ØRûS>ŸbR/•ÒS(´Ù®+¥E.VMJ‰v¤#±~ŠÛÀ.Ñ–J›ûâRÊ% ¢<òR]0‹ÐÓêîzAâÿþ¯‹æ»Ìe˜ÈOy#ÌÔ›g?˜oƒ'IHÞ¤N/Úäas#d×ɋ䯠¿wŸlnïonz¤½o³ÅĻG]s•…y#?!XfêììyuÞU£L¬ ^ ¦Öt…ƒÍÁ¡ ê§øÏ`Íoî 6wöתóT|dsûéºuöÄ–×±k6hT3‡¸ÃZ÷B@‡ðñÁŽt’^æ“ä8­Å˜,2óB)'»¢õ¼pÁ¹˜yǹÚB+êÎöæŽú:WÉÛj±kÇ|šÇÆh¢!'–öZ,m›UM·Ë¾ÁöööæöNØõtå¿þô„·š/„ÖåH®ª.˜²ëUÕÕuz#,)±rÏçöÛ vÐŽ°®¿»9è¡ýç Ç‘ƒÉɇ“¥Un‘ý¥¬\$¤jÇY.VéÞ6QçX•š‡Æ_ß¿LÔÞT"tƤl]7ZµÁ¶èÚd±b†ë„9‡ð!àB«·E&t’OÙiy“È=ÓÄë‚ÉNà÷øÿ+ÓéÖ¸Úê>ý—?¾Þ‹$»L‹†‚°h¦ Wn–Žg 7EÏ«š›YÕ“GঀW¹ à©..r95~Tdk Ù㪞_ï0G21ân Ü·˵¨â•ªb°ŽÅ-λyÎ3!¥d¨7äêÉÿïý‡ó¿>0A”Õ¢Ñuà£z-ÌgQ:m¡JC:KÅlRVm2ʄ€ë#/r×㪮ň‚%1! ƒZUWs¹˜ÉaÞκ&Qœ(r³'Ÿdµ@S4¶z‰,ÚPN3Ó-zrw”nS.†>VZƒN©…1?QÒOH½^ß–i•ॴ¿áÀ×83sÈÃãGbÌ*õu˜b½=MËü÷ÔÆ¦¾oé©X…ëgBËhõÂ2U#¨²jqÔÂÜvÓ:-¡ÿ§L½ra#"@,7’æ¦i³¹R¸Á& X¥âR7¡çÚŸa–+J^@ÅJ–¨¦Áws±:‘ôå-hƒäÊ? àPÁäß«œÂ¹÷§»Þì>9W* bQ¢Pd'“êªL~ϧ›¿§SÁxðc.ºq.š3I0ØðôÌ€‰ã"ÛH Ø(+"€N°¹.0ÀáîSPdí†(W‹þÞPQ„Hœ¨U‡»û§‡ô*@EÀ ´st`€KYhK†Ïùÿ ™Ç\ÄÄX.©ºGHöÕª¦É{B'› ôÕýÔä<¦îQ§à<òä=!ØdX‡WqkúNv-}'‚ó DP&»a2*(ÂNRk¸c°díöªÚœeé„nÝd‚P4ÈñÐ(CTT HO@PON*aÏ&ñpg'5ŸQ“Jr‹Ñލ»«™6¢îðÉYÐD(•´i^ Ú?¥ƒöƒÚbnXTb}®FRðHQ‚ŠwE ºs¼0L#˜0 ?C’}0  ­Ô†”bÌŽÆ< Û.;a#é¤lt³”À8<8‹ø'!à„ tc0 ¸Ÿ„²PTBç÷èѬ&[søÄÊTö¹K‹` ê3ÚÐs¸g9 Ý#Qì,þTS4͸¡ì°^’XÌpÚÄlµq/Põr2ŒPš¨y$F¼"(žÄ­m>wù7yó*½¼A˜#WV&fUÿۀĒ“H>¯ü­S2pZ.±ËÀšêCúã'NY½„¹vÇDÒ.ŠèxɉéŪ”g€Ò$.Œq¸svTÞ¥õØch;!±uƒùXì$[ 4ûDtý¡mÙ¬ª>ÅÌRtÂ;A òÈISU-â‰_AÂ; rQÄÍÝ=¤šÏöP¿Éã©ùÉ.U_”ÌE¢IØ‚1"!ä ¶ Å­’ãN$ZµÏZÅ©~TŸTÝÈH5…2¢5æöq€2ª!€—Åp“qÓ‡3§Ä;Ü=@8b&á°bRO‚ÉÈLEO3J4ˆ”Ъ2xŽ»ÆG6Z7ඬ¨æªM=ÑUU„$Œ¸¡;Gƒ¸¡r A7”³xÂ~c,ž‚³x$›DS$“bÞ…¨âÕ„jY8hYFÉÄŽB<¦™fÔy”ǀĠ9ö7ìŽI*x¢ô°Ú°™Aä·\o¸ö€b× · ;ð%àÊJ@ß’¬á–dŽß[’½ï_’5Ü’Ì‚½_¾$k®JZ†ÈŸ’×tÇwCzyqâFêÇ…m[ ™eÊ¡µ$DÝþ0€¨|G¡1lû Ôú„ZÆu\ØÊ¾‡§\.”©›ÚúðàÔÃPÁ Ö‹¸ÙÜG`¦òŽ›ÊwÑ×]hŠ÷€Lé˜À”#gïu –‚>’ËïÓPÑó¸Î1“¨xu¿‰¦ÉމM9~êw‹p62ý‰dü’“Í}ËF/)¢þÄIÄ%7`ö½C‚1#çša¡oR±ʼn€Ñ¢}±’Ñ+^ØI?$齿U;¦!2*þšñÈžlGt"@–™x—#Þäf£ãšŸrüÚÏØ¹çšqìž ‚&R-Ý 8\Š‹—ŠC¥~€—Qxùè{xù÷ðòïáåÿLáå8|ä•™W²U“Ëó¸zHǧdeç*o¨˜ц²æÓyZLc´á®3T‘£gªl:÷²Bë»×BÈQZ_fY9p‘"Òc ep½«,Þçxñ ªÈ4jdŠ{!8¢ç6 .åÈ>¢!w·Ýl¡¼qX‚vf€GMUŒˆNp¦g‰…«=Q0ŸtrüPéczë}àMPD“9 0™çÄ;è E!æ¨K÷¬qà×Ý¢Fõ¸[D‡4€ìN1C„Œ‰M‰¡ « qÂ_¿UrðEˆ…ø„BÔGS6©b›}¸·MSfÔ#”0}–î;±4Ç Ø®ªóZÀh†$wþ²9N’U :êAIÎô`4ÑÂp»cÎDŠ•©”ºˆÙå¹u‘—Ï<ÝbsІã¦cÆÛŸ€"fÜtvÜPÒм§±¼Û¥ˆn¤ôž×1ò~àh±ìÇ!¥|ˆèÑÿGޔޔðÁÓ„Áˆv'¬:J„öQuÜ/Xôì˜Fc¢Oúºp1(^¤É¸«‹(%úUþm'„˜¤p°`g!˜B¸H=NÒé4‹ý1ÛoûC‘S™{6C¤Éùf&”Ú7êEœäé<¡Úê†PD˜‹€(ýÅæ7¹¬Êk片&P%lD0¾\G»L> 3¹Q‹Tt|#ÞÐ6ý8¸ ÁXvBšÉ‹ ±†(ø[‰Š•;Dƒú4Frû¿r\B!Ñ$ûw‚ô˜µ™Ž}Y(Œú« t½“ò=Øÿ`.h§wqA:¿ŠJñ8"Âö´ ˜[Ifb;«)» …nÊR¶ÓBH’Ep¾ÓÂÖTm:dGO(8²0m"5¶½í|Ÿá=§Âޝóæ®_vÍ(¦Èy-ªkuFO€¨? ¿Ä˜Á\„”˜oZmCjXÂŽTˆFºöa†/ǤOd¸gUí’‰«w4À ¦Î*ìÇ_3ÁÝą愤GAÄéUšʭ?õ£Ê‚uv#Ó?°xù%Å0'J;òõ+šmn È"Rˆ&Ðú È5p‡;të¦ ´é…ÈF/Ôb¿²ÃEÇÖ,a÷]»eVGVÕOëL¨èz³¥<“g#Ò5dm]Kš0Þ‰³f© ¦YîKZO³e­*˜VÙy¿Èš¦¿IáApGˆµ!ìPšÐ¥$æ‘5X1*„[Лî ž( ÆXVðYMDoºù då$—§¼yÒBxn|UD4+˜)I0!ïäsººj =Ú½E:‰ÅÌk^ˆxeçµhÚ¥ßЈCéÁhó§/m"´ͤ€ÿïæEv¤ã±É1ì/É1¸ëÊ÷Æ` ¼tWoý ]œ,” È!&M(J8_Þ‰M1u“’Méð–8p; B‚Y†¡iRÅ4íìù¦ADkH¼.º „AØP‚XE Ÿ ¶I»»‰ë1„C·¥®ù¢ƒ™Ïƒï1‚xBˆ2Ï“×ù|3Õé‹ 2¶ g½6ã4èwÔÕ(:t‡Ï9Pem¢5gÏŸF}²gB[ƒ¾æ ú}v/Cä z‰ÔcÑלEï̱š´èi”Iß0¶s>kÛG :ÏŠ€(50Üñ‡œvº‚FPµ)„&kç%êÂTC3½b7/º %ÄÈ=ˆ= ýi„/ÈO÷xܰ“ÚZ,öûK¼ÓÍç1y,ëÐyÙT`«ªÏ¯2dIjÝã}b,ÚQ$0;’À=ŸÀÎ'XÅÈ"e{e=¾«K!@ ¾5ó%‚Ô´iMXðNjB 'ÝðˇP݈t}»Ýu;çlºÐÁd›çFÚXüŸÙ+"õqC»(‡Î*%€',-Rá«{ïè„ß¼e ~ðîî:Xí;3ƒÄ!¶`v-a²ÄѤ:§˜²ê/æäfl«T¸z¸80Fþ„>Re¹l òu_}Ê6;t'µL=;zRa¼Tm[Í#$`RLÉQÔ,5³¢xêG/Qv"¡$.³lD„á ¼ƒHºˆ·9YÕ¬Œ\e o¸oíéæëÃzÓãö°_IZtAr†¸¦]G/ëÐ(ŸB¡—ÏBÕNéké•!Ä÷,ÀÓ®›`ÕpHÔÀK°8¤KuCÐDHA—¶@é‘a\‚0ñ(™H¡ÚPNò»obï…`'K5~1$Òf¤¿ì8YÈáÉŸ`8pˆå**½èÕoO´ñ<+ U¡—hªeñØŒ‡¦@ìL«Q]¦Sw©NU³?t)„—2]Šö›¬¼íøˆPèeyÀ5Ní%ÅpÛ>œ*ôÒ×!Ï5þÏõ=žë{<×?Q<פÝ›ü»î|êãB²ü†û•9Ó¢†{¯5ƒææÐ¢Ö š^opÓ¶xKpÓ „EHjòr !¶¹0Mµ‹íð y"¶>EW:¸<Ô/ ¼Èº-Fõ'Â#uø4Ì€3ï˜ýÒ3C4þv‡8£!ÌzJ›˜‡d´ wøô¤²­4Þ8ˉ üÝmçzVEÞ˜¬¨âHpˆrQTUÜo»ÛÎõ¢‹õ+™W]¼*úË#EŠo0 i(¨ªv’5ß Ä¦À]ÞÖ´øøâ§Ä7Êšè\3#|ÖXÕQÚŒôÕœô¡Ãƒ}âWsâwÊ`¬ 5#‡ÛK09¬9ôÎûÉ"ÇæÌ/)5'nÅ£‹XBkN5Z3"X ˜RU­Õi?,EG(-||…ÓÌÎÚyš¹[,ú4sÇif·˜è<ͬÐ"ÍL[uåw«î»U÷ݪû'²ê¦%VóÔMÀPÒª$¯Ÿ{iCJ—mYcè¢V³2t¹ hö9¤öè¦%ycÅ`0ãÒ€Á–Ÿ<}âB H¦™^"úy2ˆËK,õx [Ç–V›~É‹Œ ®k¼@3¯kÀ”XÒ/×/ž¡¤ûÅ¡Q<,¸N ’Þܧ™NñN¼™Nq€tž[®GžÆ=Rø=¢pûûw‰õGº>ñº¤·3D9ŠÎá“m2%™‡#æe´ •¢þÀ¹ vNEï­€-´I©""Ø1é#`½,‚²ˆn;ü]w0åË­Ëw1êæÐÙ,aòŠì‚P5Óãο«‹hº\ º¦ôy²£·ÉNÇR”ýl0ý`¯ÍªÞ$ÌêrJ,1ä«ÊDi26bAÛZÐVQ·‘ÈÇQ²¶§$'±>4ñË,£eX"‘Ø.gWÐRrD—t¤ÝàÀK+8mkª'pã rX]0ï„9×ÓÂ[*L2Ŭ@f»G¼óG'•#Û„@N mœ'#Û\€×#Š#Š!Z Š’B_äË‚$ð$Väž(Ê5ÑK#‡{>†j#-„t`äà H4*¾ÙÅÀ —Š Û2rŸ`pêe5»rÑ÷ÚK0Jï(JH³ïögCHOèÔÞC4m¾dÆÈp…1bÛÍ :ÞtàPË"a%:tàeS)mD¨nœýB »ÇãIþ¢ÎÆEüM¢|§‹zÜQ,ßfAyhÇ |¯Z†Ã³Øö‘D¹žóA‰á]3BvK„òhØš•±š‘±Ñ‘Z3BÖ Ǧ#¼Ù°éƶ#àï,›à–6cº#vüŽ0u7t—´qwŠ(×:MvRcÖó©ìdÖB†ÔÁ³½½Ã#ÉdM¢)š“¶æ Ž+°ã(ŒÍ‚ À…ÁÈ@à¡©r'-â–~nºQ^18JVï䚘 º•Ÿ!P'FÚ¥‘LLÕQkƒ§{¡ˆ5qMªçžÒõ|yêkU7:]/$×G Òðt?lšbO\—lÜ¡OÌ5n £dóD’l`;%#îŸú ´ölìß/Û0x"äîTyIG³ì‘º± øeè%:6dÂ˼¹^Ñü1ñïDªÁòò„ó”º*ƒ f€?3ÔyV×Ï>uÓKáÏ …ÞZâç¥ðrJU<Ù!za•Eâ唌> 2w÷,u. š¬mféRá² i¢žÓ†ï%2*MÙ#¶‘Ê òËš& aÎóeÈôšao§™œrÅÌbi{àÌ Ñ3P—dò©ÓÔ`ÁyÎ'gÐ9O„Iz ÜÙ3…©•cH)GHµ2"R(! ¡÷šÄS·©CŠ ¿3<ó² cË㙳½8ž Lšg!¦æYHñ¬3¸‡î1”þÀ‚¤þˆù@pðýKà>I>½§^}ßSÿ¾§þ}OýŸhO=-é=/wŽvˆ%„c,Å;P:hh5¾o²FuçTî/×Î\ ëNÈF@Á¦yJÁ¥iDÊÓ€[{Ãݲl,l oᮀ§íÕpãn¸N@ôÝèín~íEdIÌ"Àã%€ú’zœ^ã]Dx'Kðl^e nÁ®F^|‚FœEˆg+HÖí¥g™ð¸“h.õ#y°¨Oú0ˆ-çѨöS±[Ù-t(¤vê¨F’ÍíÍeÔ4wC£^ÜLl&•Ì¡´ä}./ÂcYdS–ÜH~ÊFu†ŽYªk8&QârÁw‚M5 ™¾£EMÇÙÞõÎ÷¨R›ö ¨þ 5ÙœØjØÞ;C\I àæ¸*¢Ôr_­×7`çò¼â µè;tµ °ÉKÒÒ´µL¾/æ1˜Í #*R©cZ}"{«9éÜvS)²¹Ìƒ‘x?ä¹Àl’qünÇÏ¥Šlê²´|M¸Ùaz„ÉHšä–ðÎŽ³§¡È&ìÊ4TV1 Í’’ŠEû±y.ËJWuò{VWäÄóð<+_˜3}Ü7˜§b8P©íw½à4YdS¥ÙçU›(/·)8«À’’aey!=Ác'@çsñ}(——i œÄmœ‡j{Ç/~¬ŠlêîÉa)ëØßhœíbø[ø X¤¨§Œî1Rèe|'„± 7Þ÷ÏÜM¹î ½ Z0Ûª.•ð…Æ˜ÏüŒ,^g;‘"0ÒK8›–ã(­$·$d$šÝQ öt³ëœˆ‚ºÛ Ä‚"bò…§rfø@Õû°IhÏ»7A§2{ K9hÛ÷\"¢E‘–Ÿb¸/»ŠLõ)V½‚=Ÿ4êFžÁ"'€â‘éQmc–@ÖœPFs‹Ê¥×–Ôð=FI›ùeD¥Ô&׎w àšÅqÍ–³‹¬ÀqŽ>£¨ãF•ËSëÎ/0âéQµvBôªËßóéïžal-E;¸m(sEÌ €\ey˜3Ìðщñ•°È“_ œ°Ò¦I=®žú»«ç»«ç»«çŸÉÕF,¸½/u«ÜEÊ>'ïž%Áý´ÔŽ ñÖŠÇaàãC¿ÓæfNm¸ÌíUh%üÑVÈÒˆÒšÌ.êŽa¸]w˜›Âôù-¹xtÿ2…ñ'YêKcåÂÒÑBzÑÓÆÎnˆ¥`ÉùNnÆÍÔˆG«é«– mó¬]äÊù0b¢»vO ”×rpÄyGPJ4X^·AÌüÍ(mŽï« üÁàé[v“ŠeuôBuÏ…v‰"Š:(|CŽxCîvzÉXHzB b oèCG—-¨@Éte@öYF¿{fÃS7˜¸cعŒ'gQ†Îˆt-„H]ˆÞ¥ÚªÈ»g²ì†Ë¨àœÐ8ÃS'y: ‹CÈdnbØÙO'ã·ùº)—“«{ß¹W³Ï2דÔ`GêÞ‹]jÙ nƒ·ïãUz†1ªŠðrf''T‚¦áïö1˜5ÄÕ$,;]T] à _]€à,aA¦Éì3 ÐÇ'ð—Â’z 7,Ä€$ƒ}w,ëB¹TƒÓ)D´¯fšìe²™ÅF†NfÓ†ª?ðnS×GTà8‘áš„kkæÀ”À t›¥é)G“2YÊÁ„Ç~N¦¡‡hašL+q+e]ÙLƒÄ5²`ù„¤g•~Їp¹Äpe‰HzåSa×ÏÓúS™_žœÄÂï‰\¬Eå<ãF5èkFtú"’\õŒ\œÖàm‡cËò¥SªQrçÜàÊ´™è 3ñ”Æ>ÙE:’¬-`”»gà]ѹÈÅr^–¤¸ ¥êÝ ÂP‚9þ#V­W„±´;ðÔŒ,ó ü¿˜À07§Ì±^Ç…ÇBèxÀwÞ¹pþXÏùè)Ö†ÑG>Ùg3¢-¦éüXMLOWƒt˜­ü„ÌHÍ3t·?¶ÇQ% 7fôŽÖÉÐ „(µí5ºQ¬›Ïƒ“JÍÜ"õWPn 9N îVH« £^ðÞúÀq°‚@'Ï6œÄak¡|yø¤PÔ-‡˜f¬¿ñieK²—b:M‹rð‡šÕÍ¡å– œŸÒSïÀ3«DÅhœí.R hèñAeÐ%i{„>£;<Ä‚ð cüFÓó_a€£¥Š-J•„rÓZRÏ:ýGº§´wbè2LáútÛÄKb»txˆ‡°÷>nuµ§ ¥ ´_pä"6ï§m¨°,·Ÿ¬¤±"0êJ—á“!f®v!TRK[ 'XC×w•NK=m‘gh;¦i ì6JµµèÚj½á⬷½«zVÍ[âªúK©,JTí,+F¼?ÌXÞÅÙBxœ`Æ-—n%%Ïz]4™Ì L%(ŒªzBUµþ߃º‹nGNQ`ŒÆÅÉ/S‹6ltÆ€ž¬/xAg„r0<û¬·Ñq\ÞÆÓáB<fMcr&͉ß\kÒ “Td^ƒ‚3j¬¤{'Þײh Æ¢yræ#¯mΜ9³³2,>¡P£4ôOw×D%‚ DM2¢á$¡l ^¦¤%³Ø’¾c,™'ð’KSIg™î„T†T…8ó†åŸÛÁE…úm y8à 'à`´«6z2qœíp6°Ïp êFð§g ÉjœËÃêBOájÝ)u ãLl8œáp°\+DH´ÕpH!ñ&CÁ™ ¡Dj›Áä †¢-è žj y…@«ãˆYfrà,'6úÊy/P–“wÏâ©( öëÓsèBïä݉*GÝ–Iûuøv‹Ð—+$4«æY ¡qìëÇyRlœ—³ß¡Þ”œczóÙDzHX©š„~H³ àE¥©"ÑçšvQ5wíÒ ¸¹ h¡\,VɸivFèý·4ÀÐ]€æ]wQÓ'ó=÷Ttö£;ËÚ8-ŒÅ<0õMJ§&Á)b¬¢9 1yZMO5ÊÕçG-ÐÁh†izZpxÌ)é®Î¨›íz0ӱζ»rÂ^4 !:A›Z¯Š„µ8µ²©“ØæÝ3Œë ¢â´æði˜ÌSï\ÒVAŠ~˜AFîŒVÈs"ÒH€ÛÖbˆ(VÈ^ʆë“×ÊE‘J²®ú?Íêè×eŸP€Ê1süCГ‚xÙÅ÷ OöÃêÚº`ú´!.Оì2”Ⱦïh/¬‹Øf„_Y¤äw‹IÐCËSG‹‘q+[prN9êÈçyI‹ìOd¾È†™ÄÈ„!´ÐîÅDöˆíbÜnÈR³ÐööàŒh2y' Q<{Âñ,ª_B|×çVø¢=‰P9n.ÈaxLëQqA"Jnèq´ ÇQÔ§½#iA¤„íì™i/N·ú¸åãOÎè–?yƒ[ “i‹¼`i‰  R…Fò«­a‰iªµ^äkéî€ÃCae´Ô²5zôY»({~µWù5åz9ð"À³ö No@0±þ3€¸<"m–¡K…ÂÚåúŵÿ[?ú<‘rtpLô( š°-ø<™@;!Ð()]í'жƒ½Û¢‘´Qâ¿RK;m×ÒæÜ_ í#E•`¥–R´¹hìuÑHÚo‰Ö‘ªj);b:R ­ñ‘T…ÇkATœ¬ÕJí Z¢>:R=] ã#© É <IÇp- êôþö¯*hEö3UÙèê¯|I¬ˆöÝúfw~ÀËõåO‚ ŽYágŠ—» IÃZ­ ÆÅI$ sb¦'Ш!r°sK´Ÿ)Úܽg뢑´íÞ¶¥äH>æÐ–)ÉKr0Þîgr|ŸÝŽ¢î`{8bé:¾©w¾¯]¿¯]¿¯]ÿ‰Ö®é8H¨GûöÞ®í/Tºt#9¾©ó¢À † ‚[ý¾09͆ƈ£bQ1Ê8ˆ#ŽŒˆŒ£Sd~äºe7"äG^>„†EÄpdˆ(‚2B›Cúiøî„B #z h/VÎñç)¢*çÎ9î<¨9g©ÀBk¨ØÇT°tŽ¥Ö±“ÁöQ^Ñ ûX«åÕFò®Óh:C#lÇJíü ƒñ×'‡ˆ dÄöÌŸ¹ž9ŒhQHlÿ|â(²û‰tþ í_ØYç§í±œÌx:8eËÉO,Ç#¬Ý â%Ç£X»½ä@æǘŽ9ñŠ£ã8¦ãRrtDs«ˆ^st“Îk–XTd°³c]Š/t‘ø ú¶ §¨ ÷u<ômN£&¼á0gˆŠ« ßrdœEd¼e5aÍÍßØÊ„àXâ7Çfæé;¤áèÀ‚òiˆ÷±J>}ÏÒ1C–¦¡#ÖÉc^ù¼ÿ Ùš†”X#CQVÿ4œijvÓG £ãyû}%ÕEKòk (Øk‰¼söäM¬ˆ h/VËIÍQÕ²£è'5ƒˆœì(j±ø:0 O–_CÈALÈ{–’Žã¶ƒ;á#ÇØ þÈa\rÚ ÷Ë%ËŽŸ9í÷ËÏ,7nð"ÚpkÙvøüŠWц±–ý•=7\¯`;â&«ÙŽù•ë˜Ø’øõôÛ77XD -xþ»á)Á2b(‰'À_Y:~çd¯ègeäoœŒÄ ú¿±2ò;£cwñØý_9þѱ;ñØý[´r¤²ƒïÙïÙïÙ"‡ì¯×ÓOj“ß„¢xŸÕ£hÅ‚—êÆkOj'>e@&Œ±±Ç06^¥B}TeL cnlÇëã078œ Öã†<ÅN~g¹‚õ¸!%žby)×;‘ð·®üÈuáüó) “wÈ“bˆÁsJ¾‘|üT§y qÎ@lÇSÊ9 ò[“Õ”­½×¬Äþ™AØŽW¬ÀþÆqûˆ ¦%æØ;‰å'$xóé·ŒíÜ¿p2/`þòçž‘SpÄà¥fÁöÎKŽ”xù’íž’£;ýJ–Ž×±Óï5KG‹W»†l$‹‚!ðj×ÛÈ¢(GI7ªiJ°‰,,䣛¬¨jʽû‘AÙŽ­ä}87Øwo¨Á†ò ¯M~ÅÞ{CKl)ÿ©Â@äéwûô»}úÝ>ý'²OÓqG¤[ØÞvy†^¨"éxßJ—iÄ•½T\/T‘pW>­‰$¶ǾZ©ã‹3'yP&õl (R +eú{¢žSËP¢›_Ù5ÙÈɨHã”xÛ^böú(9ϨIN%ìØÞvgË^ˆ"bôäøÂ‚ŠJŸ°íå}1aÒñÖ)Õ7Û.îë…*BÑ;OÇÄ!?A¯3®¡î£jv¬¥ÖM¤P$C)¶ëœºãoÛËø¢Ž¾¶y1!eÏTªH8IÏ©ÄÒAGˆ"©˜nlwb"›ÖŸv¿Ïdßg²…™ì_纳b1‹/–ÝÞu÷ø>VEtü½‘üXgX²ð‚Z äNºÊ"&„­¥aƳઅ9ön\ELZN‚L²‚¸-wÛ»³ò±*b¢Ç †šÈe:¬ŠXÿ …¯"³4¹bp_¤L¦î#3DÛŸ j|$|Û»îš Îª-•Í\ä8íú‹ë®iæF´ ^qYD;„àoèGÈeb}¬ŠXŸ %?2‰¡¼ÛR&¹¢*&¡·žuQÕñ Í–îôº,b¢ŽBÂ’£îÔ´*b¢ƒÄß1EB.Ùž dèdya&…Ó(Âe¨{üÖkÓ$Ô"Û¤ƒ I˜ú†é—#Šhò†~ÄK´El˜š¼[\Ðâæ{(¢hq dÏžíølœ0°%Ÿ’:þØKú&‹èðø›üþ{È»N±Ñ-,”ü¡%ƒЬp%•"]b*z©†S£KÄ_ä×áÎRÙ»NUEÌðU5Œe À`w‡ÙcUĺhY(ù‚C'Ag+2ñ@ÖOƒµ$c;­ÐisE;~{ÌŸ ˜»…ññG fý¿=p׌Ž8r™k¯Í8½¦Ç×_—Hóñ_Ý(ý+ ò;gK;5ó»³Í~G=G,½‹´ý~êìûÒû_béý¯ãDÆ^díU;Åq¸btóNÒ!ƒr‡âûpRìò5Ôà‹T]1Ðãû2PÇqèÅp)Xšy|¯ƒ  ïï§BóŬÁÝàE¥´íê åãžÒhÇñVÿðt¼;Œ uÄÉAÞqŽÃT†Tý;—Í×qXˆø:ád2Õãx! b7µù>Ž}ß·û ëÚQÄÇÃ!ÇxCÆÐ­ÜHÈ™cà˜8XÉ@dœÞÁÁYŸ¾8åôNqÚ‡“qz‡DdKUÅ)§wâЈӥ`7²qÎ 1•E‡P?üD‚œ§Gz`2nœE'µV§Ü8#Îm­™s2ŽOOå}²yÎÉx|€ê¼'çd¹äKÅòœ“ñ8Òå|)XÎÉ8ŽÑÊûdóœ“ñ8Hë¼'çä ‡7æ+ Á9'Wq°ãùŠ%3Ia›­$§¨×Lõ“ØX{MTŒDžá9¶ê“Ç7 ÊI<Õ¾ééa<Ã3nµTß0P'ñ\ûf)XÅHä¶e«>y|àœÄfì›>œª)ˆ<¨‚w; 0Œ»£ÈZXöV*=rÓÖÕ'$o¼“xNy#ïaÀ™m+Nˆ±™X‘2ø†âØN|C 13.ϰI_­8*ß0€'±UÿfEÈæwz¡p‚•Q#ü‹¤ÙH~ëÑ´L6¿'ÌbA,%j"„gû O² ;ÿ~øéÍ»×iñ ‹²@§L°éÕõ)œ2‰­®}8§L°YÑ-ÿ9e—‚uœ2Áær×§>rÊ$6—?öátÜØÁSv·¢ äÆN<{\ò†“+l|ÝôÉïœ\ůם}87Ç¢ƒ‰ýͣݪßÏŽ}w«~w«þS¹Uq|­ï;Û„Šˆ³rÕIç%â0P@¸u©pÐ!WŸtR)Ž(5„Š,rõI¿…0¦u÷Î6áæâ5÷1‡›uÇ}8c;mpð|N·8†ú˜«ÏÇ$À˜6Gv¶±1^jŒsP±í¼lŒã¤ ¶¸Æì•ßÇDlü³ ŽÁѹF’½'\õØ>!&r•ìà+¾O-ÈN¸úñˆ=¡2¦ ;„KhÀ)Wv|ÆÓ;x¼fl'žrñ`=eA2F÷í`Ýњ+ïS!CAõ!J! n$/Ŭ†(xý#]ŸèŠ×?R£}w÷<¥{O¹ú¤Ë™B˜2z7òLû´î”™Hw𨞒Óè\õxTÿHÐ;%;D¶™™’)£mwðÄ1]ªkä âIäÇ¥`Sf¬ °Âš²#íG"ÖY?² 3¦Qƒ(wÜÒ&ýÄAÅ6ÇOKÁfŒB`u6£ÕñO\ýX—ýD#œ3ìÝÙ{β7ÿôAíD‰6óß¬Ë ‘ñg!çf0rF§°FÌizÎÕ5â9—UÈNÓŠ(…¤\‹T°´ÆW*æŒV› ”N<çê“û.BN»MwX¯ç¤Óôœ«Næ%~cFX”ô·¥ãëÏ‘!`)Ø'FOGɉ>1Zú/@J…S“BÿŽ«›!ïH€šú(ÅJ͈ü; žîß1 ÇKlÒ6}œ|ϡĆíû>œ†aéà ÉÐ÷\õxÔ¾'Ž¡ÑV7ÃÎ÷@l¿çz„±(÷ñ(m–Ú“ï9("éíR°–c.»-ÉÚ\õxÐ~ Z†µX‡¶ c?pDÎ]¢els” ±ÿPò9ùޤ¨ÿ' Ô%Hì뀒ùÍ9J¢~P‚@d‰}P‚Òó¾ç(AŠú}@ i9JØ·%h¥ü£)ê%ØÇQ‚ľ (鈣)ê%ä’£‰ýe@Éeò3G RÔ?” +Ž$öW%WÈÅQ‚õ/%䚣‰ýu@ÉuòWޤ¨ÿP‚@n8JØß”Ü çG RÔ¿” ß9JØÿPò;rÑp” Eý·€’ßÖGS-.¾ûh¾ûh¾ûhþ‰|4C1(IMᦥ£ÑH‚|©@"¿q@ùGÈ¡ÁA ˆcây"8ˆ£âć8A.â8€8õ!NÑÚŸƒ8 Î|ˆ3´hç Nˆ}ˆÑj›ƒ8 ~ò!~BËdÂEÖIˆsâ­o9ˆâÏ>ÄŸÑ”ƒñ!þ’ %%‡±`¼ô1^"ŒWÆ^€ñÊÇx…0^sûÆkã5ZqÄâ Z8qOˆ·>Ä[´âá B•ñ?>Äÿ ¥ ªŒw>Ä;´Æà B•ñÞ‡xD¨2>øðÖ6ªŒ>ÄGdŽs¡ÊøÙ‡øÙÑD¨2~ñ!~A0ªŒ¿úE–+±ªŒ_}ˆ_‘ÉÉA„*ão>ÄßX{SØ”ßíÍïöæw{óŸÈÞLâ ¥“=/ó1”€ Øj„êtIxW9<`†™®#Žš'ÌÃàAŽš“æà +xÌQó4€c¼;ÈQsÀcdPO8j˜ †Á;„5gÌ †A¶yÆQ3 `2 ƒw ï’(qŠa™ÁQsÀ\`¼SÈQ³Àœa´b˜rÔ„ƒaŠaðn!GÍ €ùàÅÇŒ£& 3 ƒw 9jv˜Ÿ0 ZÇä5á`È1 Þ5ä¨Ù `Î1 ZýÆQ†ß0 Þ9ä¨Ù`þŒaÐêês†OïrÔ„*ý/æ/hÿ£& †Á;ˆ5¡J‰a^¢=DŽšp0Ì1 ÞEä¨ Uú+ ó í#rÔ„ƒ¡Ä0x'‘£&Té¯1 Z†V5á`¨0 ÞMä¨ Uú ƒV´ Žšp0,0 ÞQä¨ Uú[ ƒÇŸ9jÂÁðÃà]EŽšP¥ÿ†Aë욣& 5†Á;‹5¡J‡aÐ’½á¨ Cƒaðî"GM¨Òßc´úo9jÂÁÐb¼ÃÈQªô9:Žšp0tï2rL¨Ò?bä“¸ä¨ Ã%†Á;5¡Jÿà ÷ÆGM8®0 Þmä¨ Uú/yJ®9jÂÁpaðŽ#GM¨ÒÿŠaÓ冣& 7ï:rÔ„*ýW ƒü7¿sÔ„ƒáw ƒw9jB•þ7 ú‚ÊnþÝôÝô¯à ú×Iã8_c\òÁÁó?Éä­^&QPÈÐ( œ`@Ö‡šîô—X mÈë÷½A(rô,y!þ_tqƒï­/Gi¸%Ï‹œr,“‡—™&ã´x”@ ä}ªÈĵî ëãQ:þ¤|¿€S‹5„IUE>éM$ÏPCïˆa…jVu8oÛÛzUEÞ>ÃÉ ]·]D¡¨ñB•Š+Æ 7¶½¤P$«¥öJqNCtª¥Þ*Q¤–—éÍ턪ˆÏ>m»…ü‹iVfµø²*:¾!PÄ$.‚ìx—ÙNª«R”ª®’¡`üºã8QB°ŒÌH·íl¶¢H-ÔAHC0®{æ |QDJ².J`õD ³—™K‰ëfŸ»´hâº^]DÖ}‡d(»“#ÀËsEÒ¹Ò~ñ¹¼ 1Ûì Þ¹ïCY»*³ÍYZ\{Â1 ZSÃă<åÁË7€d ³c—"ä4ÆhgB ) CÑB4Há(j˜} †àì…˜y”' ѨF(¸’†™"}mÅÌÁˆ"¬•zSX%-l²ï©q¶²¬ÌªšPûƒmaûBɯJ8·éûÙ˜‰"Ý#ª»®‹„.Lwš°gþB¶àÕö•rŠ3Ó×ѲéK­)39Ÿ¢¬¥'0±R‡éK>âæ¯š›¿œ±Vó×±ê›Àjn;Y6QÍe–*žërsÙä,X§9¬ž3JjnJ³Ë8×:vN«¹9 ±ê“Ǫ¾I­æ&µÃe“Á«&ÓKr/;J¦-߈=ІTe/7&¡WæÍ,\!Û/{Ù”*1 SÆ&vIØ~ñ2íPˆ¦CyÕë¼,Có®ÉÇ0­eÉCY¼Í®[J½6Ýb‡¢áÈë†|BÊs[a=/^Èú²~{UEõwÉú»t}XD¡½¥¼…1‰3'TiJtE›/ ÊÏÐÖi°º·s°k‰*"µ\\¿ãÔ“SöÝÂy)º§”Ä¢€4]]ƗǰnH^wW¼ú¹ –>žT:§>yÿc[BøòÝè»/ÿ»/ÿ»/ÿŸÈ—?*ÒÒO¨õÌž·Î!=íÐÅ››ù¨BÑ;£âSàÎÓ@ûΞz±¿}îd¢FB¬±g^ìQÎY2Ø_°K¸¦lë.Käj9#Ù™äéœì)E„ºW¥ôô×Vè‹q×¥M±›-ʹ¥¥ "œšÁ9Žpô"‹jkÂVì{A¢„\R¢Ú JÌ#J¼ñ‚BtË,H1ú ÁJPZˆpK ¶½;ó²9å…‚Š;»DE·9´óxw³§r´¥!*ï{•÷¸Ê%C²› ÀR”î<${Â&)¢Í±Á·Ñ¨‹PS‘0¹Âää²öÙ‘c™Êq(Ê1™É/.¨ìæa#ð4 { àr†„„À¶¡H‰U¬¿^(¢Vw`xÇ7ÂÒ0@4°€ÝµXý<óÁưaê ±O@ìÓùµ?·s@@ÒM~MA ¨†ìÅbUªBì¨ ¨–в%Ô!…ñ„À[„Ê…ò4F¹¨ºšÙ§¸:$@`›Q²ÌÒ¼nbU¾í]RE(-3ËÒº6°…|»ùR‘³“ü³gnšeBÖ B<Ÿ¹,ž¬‡n«é­Ù 2Ùfå]˜"­ž=´¶¨çbe"ÀnÒˆ¡_h^nB™Íê‚T†rŒÚùtNë:ßX2Ò;–鞇b¹„È)fÂÈN"°ý§n¨¬$r–°“‹ê÷$!¼`YQ$+¿d31 òÛ öe‰ ÍêwbÇbpxzη(=Ùʽ1ŠYCÌ,Ï›ØÇ/ÆÀð¢ÿ% !„aWôÚc_x‡ûB¢¾ƒmAÞÂ@S­›lÝtÍNµâ5É<ñÌ^(Þ„æÂz†Ž%lß}ç~!V·m%,Õ¹)`›×tœLa«¨BaÅbBùÙ¼q/ê™X2¢/–0Ý\s©ÉË"Bl7í@5¿ŽrϾ+åa=Žp§ô\CrK ¶< 0Õ$ªe‡ M£‰ÝÌ2ɧ >•Ýv•OÄ$)”Nš¨H¼Ó6ïnÌïê×Vˆ§*FªäEWŽÉ¹ÁÍRP¤í”SÓ~§UsÊÐÚD±.TKˆ‡3ñÜ'Rë¼õžºsÍi›CDM¨lzâÖ3‡‘ºQ BßÔ½ú¦æÖ3Oi}£`AáԼ©¯“„ Ó»?t1Kë¹èÎNy¤u¦üÃÐÏß]ã]؈ñž¸ì]Pœ…6U.ýqM›b‘mÄW‰!ppàÅÀË"ÖdV?C…\”YâãE¤Y¢Kóv‰ŠWû^‘Ú£zO¼¡fÇ}ì=½³&zRÀ2npìݪ%Š”ˆç„x˜GùT~`3Q š´­’ÖÓ,Ú¿ìºü„fïR `:¨*!LVˆ‘IÀìÊIy Ò‚˜…¡_’JÊ­- ˆ[íīݎ³ªÜjW¥i㬪Žs¬XÁÕûC½n•Žs«œ"”~§JÇ)¡ýH Á¾U¯úé8õ³G«HËï%mãNm혵õ™­¬6Ͼïe}ßËúWØËú×ÉP2‚šìøv±IéXŸ @óA º>®é]ÀûX‘ÿ»‘ü”ê m´§%ýu/³øU6kÐÇpC­\êUS©l¢2CjèÜf`Ÿ²Õ¡ƒË(NMT·­À‰¾êòëÖ½.Jl$^¼t¼:%šBèóÃÚðÄ¥€é™$â’$bè!Ð\ì ‡1¦5±‰6pwGhSúp;Qç4%jÁ0M ¦c½Ó§‹hÙ´PÕåÿnÚ‡1A•wi÷JÀð7÷è ©»­RtËå%s#¯®®ÁWåB;âÆ »$× CgózU—Þß”^ E{–fZÁïÛJ,œÁêî[êps FÍUÞ`ê®ò’àÕÐ%P‡Ú‰¬½)«k\©ÚÂÚlœv±]>ð†¸*’¿ÌŸ¢.«.‚Øq禎d a;$°2•Ëm ˜¾Céz×YÑRpG§™Á·kw?ÖKYbJi‰—XK€ – ]oçò±ö¼y¦Rþ"6½äÀ¬I#ØËÉC²†ô™’§ß_Ú#ÛÃgÒó&ôŽv‹†P£QoYìzûí’(J…>‡Ì©z§J Põ…Tõö1£ç‹ ±Éô4 Hn1ˆ’$Šɪ˜– c YMZ½?Ýø3ßÕUŸ÷Új48oN§¸Q§>‰ºV–Åòƒ;:/ÑUSÙ™&s¹~‘ÐîÀ*Šq’10;T™€­g&aFÁc‰•'¹¢ˆøïgÆ=Rf´¡-@”ÍîbÐ-ÂqN|FöïЭfDmß=ºÁXe¸Mæ8ä¦QQä±0Ô½ÈnSPÚ¤!AÎìjê­­Z4åœ cèUleh”íõH¥”4v*Y¯Ò±ßo+{“`²‚¼Û^U‘×B¤²©Ü¹BS~Œç‹˜á×A,_$kHäË”¢TZû»îΙd¨ÂE¸.Ñ-àÆ1ÜÁmáÂ!bZ}Œá˜¡õ)®±õû¡Øtº¢à*‚1'«ÐËæÁ`߉vñÂXˆÓ1,¹Är¥ÐZØþˆ%NW©ØEUÒ¡g@ šç¤ßÚZmðé-ÎD€àp‰–,fÉtè\PpÌ¢¥*Ðù ár˜CKD|b…Ž>Yþ;ƒî2ƒ½ªö7öð4ö††º(r_×®jfWÐJdÐèÝ–Sq,ÄŽ»ûQ•W6r•« Â&nUW”-9tÁìþcÜ”pwÐÖ¶Š'ÜŒë“SÉÐ¥Ä5ú7±kËR¦Kí´-f_z ÇÃ’—œ_+B¢vLî¨Åc3ü–Ãìäaèn£¢‰ÚYÕÅÉÅêðŽ¿Ç"‹OÄÿƒr,­iŒÒfþÁRCÁŽOÁÎ6GÄŒJ4(äÔ±svÓäã&yµ) Öùu´({…%V;:ãÝÛ0ëeHÕÍTÕalÒEω×mïnYUDý/¨“ûpÞr(n«_­ä,J“«ˆ_uu‘ú©wÞêG!{›ºYP8ÇJ݌ܢÁT“!¿DŠñºé¼ ?°K@ÑèHÇ"Œ?s‹¥Õ¢­¤çVÆA””ŠtÁ^àÏØMeÜ‘.ñA.þ‰BÂПÔÝb¹Ÿé3îsãì·jËA©¢auˆT¦fǯ:v )u*ÆÅ*/ëx±zP뇚s)8Ë·Vþ„ãg:Ú¯ÇAñŽC³Ê˜€ =5ç¡pcêKÊ. éŸÀÉe8çÄ~HPŸw¢æü ‡!Ær‡BÍ9Ž$ñ(|Ê2ÎŒôYÞÆ¶™_—[¤b:5*$²Ðš1ƒ¾Ë£C³Å½?'sš ¼>¡xes1÷áùH<œ»|C—äFW#ü ÒÐv#|×ÿ´r=X;5šgô~Ò^D· †UÜ6¦lß¿…H‡ë¢qõ ¢:n0˜Èìå¾2\zêEIu#Xø›Ô_B©õøE!’ïO¢f½ü›á<³-ÿÔëÂna‰ƒ Aš="‡» A&¨â T[ ×§ÑQ=òô”ƒ {6Lª"R™„?ÎwŽb•© jbâBÜÌ#!Ž’ JRÎD2d;8†(—~Ç 0“qo§K,¼y[G6ç>’ªa<8@ª ‹?Uÿ=ïbÞpS½§ZðÊ)LÓfõP)ÝJ`¼u s‰…Gx âƒS˜K \4àë £2H»÷.1àøÁÜÝTh‚Hkï,ø`OÅ„1‚ìu>CÝj=ñPQýJõj¥|o˜ŒfVËò£ƒ™`©¸ÅJ]ùShqëÇÔzqq¤Í f±¼I$û¼°‰m4Ä 3ÏŽ»lU¢‚hº1‚`f{ÑŒ i`ÌzÆtwÑÊ@BøkÁXpã.òFˆK’³S©Ö„ÉÐÓœÅP³œÅ u`ÄóܯPÌ…lŠX Å8³´1áâ‘Zà„Ê [± >a¬†ìäÏS'u¹ˆÍJ¹ í!òt\çÒw>wF™ *VD`Å¥ã(VÆCPs®±‡ce ÑdÔ¥îÓ18‰‡šD… ‹óc .aÝ’ƒX‹ÂT–á>äÅÄÑ{˜¡•eÂ>ÕÙ¶£qƸ3 |DÃ"øé¿ƒ©é žšt6qTš7Ñ*.ì\øñÝ_vYz‚1¨H@ÿÕ`‚ÕW©bñLhqc~F0Ƈ(_•èNx!kôF9±ˆ!ÖDÒ)!&qøø>9ÉÂ(ä»jOeÀA®žwI{R¯žq—T-¹zÞa Oª# n0ËgÆ¿-aâžo[o%o3¦íáÕVj‚™á±—ºï˜˜ßP¼zÒKØIvWõ¯Ê¡ }2“Ñ éöC<(8ß…bá­(zd –‚1(dß“YʇÌów OìÎ%:k®Ëç !LJ×¾5’Žk¶9eõ&]³mP éñ05³„ì¢^Å]3lÈáû.¹<‰Ö´ âãBK‰“rä “Ž!âãÂI« „Ãä’øYoµ‹‘iÇã \àˆw‰w @¼{¾Ãy!²»N€uFœ­·'A˜ÞÐg ']l= ËŠÆÑp̸{&1PÒœVUxŒè]$! ,Dà1¢wÃÁ §?gãVž<0Ö8ãê/f)¾I äÐ0† F²kâCïPc]!Å2ŠošÔhE ôt˜¼‹§ÁJÜѰÍlà«ÒD6_´7M™Ûñ±…pa/+"¬Ïá6¥5:ÈiV‘#N Tv'ßG Ådq„DÍú™”00}ðV¼@€HËi[‡IJ@!L*‡Ì®q†C¥¤í¦–·lƒ@È‹|Tçæò`#á$ BÂa” •c$–.Æ¡R™iQäåÔ-:Mrí¸ˆ,Ù³ªög" ©ÐiIŒ0`Ìa0SÞ\õ?“õ™Uóô4ª/Õ>aü1SìМ¢[-¤“ü]òc‹ëSW¾¨å²ª|ËÓÅ é<%çŽ×²ÂG}üvq²D„ž¶ ¢x ²9›¼‘ Fذ ñïOÞIõ}zÇM߈]OT8MÆñÂ[ùêX=ãsõk¾,hRËŒó™è'Y¥óÔ-ßvi­Ñ7ZÕ(k ‹›ïܱÕÊæ¼³õ÷l«{Y¦¾aPõ -×(xì N¿cì}Ãè5žÄc÷ÂbÎkM0šæ±òµ\-ÎXÁyi¶,FÔ=`¶CËa$¡‰#÷i«¿mKÂÿÙv||™xƦG1ØTA¼(›0½Hžˆ x“–*˜Æv ŸQ ”#æ\x†+79¾ÏàŸ’TãéŸmJ †ï¥@åµ Æ}›Ùb\éü "$•ÄÆ";ïwK ÀÇ@|‚ñ$…òs\%6Âà©Põã"æ(>ˆYÍ‚>EV8\CÄu¦ODƒWpHf³”–ࣨ–ÃðHN€î h,ã“M}œ¾†XÎE yJ=bQ_ ã]£‘[õð)hêý;Ä~EŸ=%úܤÿ;‰-øY`}Egr^”`ÁÅK9föCaœ+–(p´@ÚSTCËõ§²ƒVEUnÊ¿^´—{~&øŸâ²jBÅ ·&öÀ«5ÝëÁ„¶Ö‡ÇîNq@Eqì7…ð»ûó„G銲|Î]ë| ôYF}qWÂøGäq?`é*ºìÀÓ¢!ìžtCd«Zâ.ñÝÓP>äñ¹=ÖòBÉÁºÕ"ÑžéDt~¡{Åt÷‘QW™dD:(Ùß‹‚ãæ¹"±å1Dbï2¯ü ˜i|Ûúãމ41ð>8ì¤ î#ÁÕKŠ-Jî#Á/Z-È÷¼ûHðGVØnc31»½(ìf…X1ÉÒ ¨Õ ÅSð©z!Y¬Âñà‰ze%€Åæ„®ÓŒhÝ“gÁ{3}á{÷ÛÉ6Hß3ˆxÐ÷\’šÈÄm+ˆüGÓ9b¿öô)T(úÈo‚°‹W˜«eÓÖ©3gMÈsèT¯Æ£U`=ÓÝz‚9\ÑgÓ ]Ÿ/ש‡ÿôTÒ­ôx„!ye—hE¼²•䕼?öÊV’WVÀ²­ûz'uÙ¾ÞSD€˜4 ·HÚ£É|gÔ)dB‚Ç0a&°œM¾íú&eñ3A©ú¾!¼q¾œr)FA°ä`µËñ(ãY(`zRHº¡\bX @ê1¤ç8ã ÚiÇ\ê–"8òÀH¨¡ br8ö¸Ÿ$¡FH‹ã„ #°YrèûV¿¬J§äoËÈß´MrÐé„ãZáÈ–JrÜãþ®ˆû{c[Y£¹|`²ð0D§lÄI#mSäÝÐBqÿ$mðˆ >³u68PO§}DyƒÉGÒ*®­ ÎCèB6 c¨”Õ’“Ô\&¿Ëc äÀ—¢÷ð ·"¹]onµóNvÔtÿNŠÄ‡Ž™`š×ô˜})º¾XYm)¬c_} ¨\öÍp¢ªT(À9gÙkäw;aà·w§ðÑFdh[°³¹Æ¯ðIXP€ÄŽÚ @ÊD'ÚwDPVv¦† 8ò©jŠ1¨žQc¥óT>†šj;5öû8‰ÃªÀ ‚ª5vü¸YˆÜ,xΘíã RØIÀœ-콄3Ò÷ÜÀ,=4O£«§(&-êKÓËÑ’ìmòE×}&( 6ËÊO“ß¡ £.úœÉŠ0ý>=…‘ØÚ“Ïj°k9Xr$û1šE½ ¼ÊbæÅGì)Ìô”aÒ 7+éªìŸq(B€ q%k@±Î‡ ’˜øDê´´ !D©¦K‘¬eÁ*ê†î÷Þ1ExgÕ_)œ‡$è·j‡±×ÈB°#¥EŒe¼+†ñ+i²Äµ4‰•€À±Ì×¶X+”jüQšN’Œ’€ª³Ë=f„B¢å (Uò„–º6 UwÂSOp½ŠNpÇÉÍ„U=ÕLZî4%éŠXmÅâÐÝè ]Ö3Å‘®ÇîI× •€LÎJâ^€Â1 e —¦Gü£À}Ïu‡ŸË=DêK=ú(ñ ¿ a¹,Šb`IðâÝ aàO³} Üá‚ÝÃÀò„8vû“.Jy@Ú­‘LCrŒÖì'~joEŠ+a¤‹FÀ¯ï%E º9¢6¼g I…A ä9 ¿š©æ°ˆõÉà^Ö±)™Þ"¦cBJËñ:iRÙ“Ô€É{>@R׉GÒCÍù‚%Êô¡Åúš‡àÓÚ‚ZOݺi{ 5¢éû}—qG÷GcE›ögÝ©¤†áA\_w‰d=D¶Ö¾4‚/[=ÄÓxlV†ê ‡‰g Àpíâ¹¶E­É\ÆKÕÚW²F㥪‡ÀD݉šÔ&ËÑóXÎ:~Ö7 ã¤BÍãÝ7³žFÁy\Ó7F*÷=¡˜ÊïÛ¢+äPªêÀ7Z!Ç£Ø9r¹ ĺeQÜÙ’ãXˆÔ0-Ž|WyrŒM7ýjzò\`€™«cpÓ)”ýr}ßàâ`Güàu¦‡¦s¨†î·8y_#ÌfŸ¨äJ‚W‚ݲÆÓ Ð¥íM4ÁÿŒ/møž [¢½·-Ö]ÁV²I„D<ÆžJ-Äé‹H Ä,Ö<„ï… 0ÆòôU`-P&%Ñg±5y!<Î8y'\bÛ–è¢"vöº Q¸ÅÄ‚Aˆƒ`öO‚¥G3ž˜_}»¢âXÈ:§y®_ãŽGS‘ÌÈ™g ÛJdãžxbb*Š õ¿— `ñB:€£ÌøR"Np«b^­ŠÉˆãÆ£’ËSjIÄ:ÀAñ,-QÖq:Àl%&„ øñ54FŒï „¥–ò<Ž¡÷ÇNªäMƒè£ª7ɵÄ'¿\gÏ´ž«ƒÀ££rô2â0|;ž˜P›Fá§.ø°¾Â»Z52e<¯3]gŒ•©Aâ8|K ¦ªø™ ÃçNZ‡‹wI- ¯lÔ0%šS)ê–U»Îíx´ÁÿÇg«•Ðàßk)~M˜;;)Àh|4ÿàÊ»MhrnC. q¶ÓoxìÈt;Ó›ÝÇ;±®3êÎÄÞÌÈ‚ßEly½B.^òhß ©\ÃŽQïÂã¨côf£–dê#§[&äG.›Íöí™îáïý¾mgö]ÑI™’Lj¼?ËŸCï =¥íÞ<ñŽçÔ¦¶Êt8Mçð„¼ÄΓ(Xz<Q gä©Pe‘{RÔoƒÌ4øÀqƒ±å!È4„ËŠ{޼ÙÛýÑ`@%=®ý£ù>Idv³š‰tO$‹9~¤=pKÄwÞ){’¾ñ´';ž‰§oË·ºL›S‰f˜>37=[ÉâˆOn„óª›Í¤Ö·¹v1»>YƼ=f4]\•¶ÈrÛuÍbvÌÌB#À¸=éxÞl)ÊŸäq ã¹ÐfeéÜ ðYGB; G¡ô½ÿð9Ôô FxýPãqp‡Ào0; bÉ;v…Àdü®ß³Ž]IRY¬cWHDcâ Òȉé‹H'ÆLA˜ãؾ âØII|‘ø‘qòB€uì ¯zÝ’8v5çØBÓ¬cWžK Ö±;ž˜j?Ö·ëœ(Á£àwV—øS¾¯5_E‰úüv6lIÃ$—MráEBiwzãáWæC¦ÀËyA¸!êz¤>t Œœ|óôÚ 0RZxVã©”ÞòRzž…ô6<>_,tˆNg!½§ÚÔ ÆíÿF¿.—Œ„yOCOÝ®dê£GH$¢@Œ”•v’ïÉñ¾]—õÍ6zm°OÔÁ Úé¿6÷ÙK¹ê×ÙñÏ?fÅ&ók»HÍ¢îߦÑfÜ̈yÈÄa÷“íKk„§ol–Fš%ûÄ"àk oŠ<£D8=üuž ŒÑñÛÀø#.}0NÙuâãL}˜€Þ$®à¢\SêÆuá“´ rn¿ñÕ7c'RóSÁÉx2нp}wD¡:œ—·ºMûîÌ5cüuFþ¬°×°iÖE¾ ¹[N îÏ+*G Mëæ{že×bê°›qnǧ‘%šlèø.°É•†2ýB‡­p-ñ%´ù7`|Yú¨¤ý¡SФ¬ý¹PÛq µÔ‡-ªKïæ UÆg&Á#Œ¯­æ?t¨Ð´{ê•^VäÉhØ&%åƒ3||²ë'¼O|Ûnùäúñt‚sÏúâNæž³c†¯´Ÿe žšoóh­¾1Iý©ðx&Àí¯ÂžqÔx›ïD¨¶ƒ°AªÀÚ¤çv|Š¡¸5é oIqÄÔ#ôn¯gjgžNcv|IŶ†Ðƒ)FÝ€Æ÷ÒsÆ2[XŸbx×[²«_¨Á B à$Ä 9ëTð<Óh!ko¤¨IÅ®žƒL'Ñ•²Ì“¿FЃŒÄ‹ü_»Þt¾dÏŒ3-{š ¶`À¶ÌÌ>í#d ö4ŒÎL™e=¡;såjºëÁ”î©RëT¹ñ%å"ˆ¸yÈ”÷ð´Uy caØáôû?„ïÇw;‡Ò#a6c¢9AùPÃïð•ù q4cñô"þ0BNOD–ä™ÕÄ"¡æ ä ® ÆkbR;sÚû¢‘9=çÌéu^¶ØœNÊGËÜ@y–÷O`JSú¾"Êœy°Õ¢ÿ¥(ÉeúÒ²cÈüüõýÑe©ŒÙͦ*¾÷mþâM÷Ób•ݽÂqÍþus•uKe+õ0nÕ¯Þ}ï*óñ}Ûl²²Þ}¶Ê•(ël¨Ëe³*Þ}ßTï~0£¾VEÞ™ºsÅyýšJh;egfÄEþ¬˜è\©oe§¦ó÷üïåÿÖùûeónxüu«æSuÈ—ÙRéjù‚¿žój(º,ï”T¯ÕÄn‘/×™ZMÙ¿š/ßtëf¨V?e›¼‡?•àMRìs_.˼ó¦m1 N²3ß©cýç¹ìthmõª˜­j–yïie>qXçMÝA®ÒïV™Ò7€ ~â þåÿnn?ÿë¿Ì×p;vjFð"«æº.Ô”Ëî¤ÛjtÞÃ'3Õ5´TEvWuÖªÏî˰J j‹nÛÔ+P8S˜–ÍfSö½’EÀèýZe†R ü8]¹*Z…¢X "ïúÆ~¶V¶PÛbÙÉòdeXÄò'ÔÆ×1°¸ œÝ϶Ûêõr¨õÓò/)ƒ'cÁ (ØX×½®ô­J !ýß•·jíŠRæ÷ùÃC‰=Tgšœô8E==Á³Fé¶y¯€ó|[öyuQÞß+šÕ&ÙÞìà*»Ð[;¨TóZEc»Ÿ³âÝûŸ•D­P— ‡渇uþZ¯´¶z¨Û]75L¸QÜÝ—Š/ZX°¢x³ì0Õ;àl'ê¸1ù™¥îçü½@ýu札ý8¥lÁÀ¥Lãj‚Aô‰?­ÙŸkÐTukâÍ&G¶,Y¸yxC‡ÿó&W:SÞ¾~FHáRéo=EÞÜínÛ(MU!¿£™)<³þ/t¿þ}(šMуPºß7TK±àma… €åT#?:]_BFŽðèöfiD+)à®s}•¯Ê%®QäAo“Jü³PÔm“·©zÙ—µRìË>+;eg)½\Éõf¥u†F™`y!  Zô‡ð>'3C{}•o+ÅßäÎ=š!Bï¾cØ.4v†{ù%oWÝ-Æ{ãS5hε‡6¿H>·hz§ÃB+,ÚµûJOûŽÄ7ú© %-‰é;{ú>Õ}†­Õ†-¯DYŠ* iŒb §Æaऎӓ34—Äq &z§,N(fƪþ}ç¼ûY;ÁÀyÄÙw)¤‰ù]SÔ êfBr(Z¡Ûþ±>—û¯ï䣄#í|„PŽ$jó(q!¶èvcâ¼q5×HALeP&áoñ¡äéñSÆó>Ü»p\êwÞ™†í~”ß è0D•W¼­dFH¢ÊjHäÄwGWlÊ·îqJk×wCZÙ¹ë¤d‹öá¨Ñ¯F;å€hH?4ª“ Aª*X¼/ŃvüV¬Êact{Kœ\’'äv}ûÞú]YÈ[ªJ™îÑñdbžî<Þ˜:šƒ—y蜭 ±Ã4·5Æö€Ì‹rSV¤ÜjñrëAî9 ¸ÀÓª9åFñQ†{þø‹ùï÷EœÖ_šOðwv¹¸ ²ò³ Šh; ÒŸÛóP„Û.ïoTÈüXçÝëfû AH;XË P èJ¡Ò¦òyŠgÇG"E5™…‘ …o½péq,0úöSÈ;*¿?ã9ÌæK?˜ÁJb)ÓR»9yl‹8Ôù.T¨l¼2I0(qAkTh¼ôŸM’lˆ¶ÃØiF‘{À¤$¶¶àÛD ÉH[¨SfŽ 0ÀÞ-ú·UùXèò<¥>¿P*ˆ÷Gµ Ë[ü<7t.ó@’ ¿+*ùw¹H&„R+>Åìw-ŽN½\„ª"æ;3„ýô1­ºxÂý§˜¾ðí×|œku‚»ð³'É·ÛhHò=tz]>®Ñr•ݽˆï`}ý¾é‹ãŽþ Ä´ÚVÅñÆÓ`~mÊz  »ˆ1ÏcL7* vG©^Õý[óE:ÁÖÚoXI8Áô¨ÝÚÁWëïÆ7î«Emò¯6!ÔÅá„j%[ÍoÞ[­ÍM!üŒ2:“g7œ§Ô6¡W¢ûƒ߀®…BÝðÏÌsÄ|~ÁÏ©æbºÝ}Ž«0îµÔõu*¨wÙÏ$¸Î÷X#¨èEl‹žìãö y¼ƒI’VãØoî¸,Ðx©oK Pû/4höÖ1³N‹’ýCY`l: ÷"HðØt0ÇÓ`š¡^Å­—-L¨Ýˆ¬´CÒ‡ª¸(ªüµXŇâôÒ/¥U#Þ®ì7K]xÊLJäùÖòq©½7f´©qAEOW(Ìu@´€Rlic_œÛ<‘fAŸ²:¿*}‰+ûSi‰‘GÖþ©ÄœY81Õf!†¬uó œyñ½nŸåŽCŸûfsWÖ ¿+µ0*Ò B‹æ¡nÚà‹€ì ï¿}LÒ³£,àð-¹âíÆ„É»'É£Àº;®}™BHÁÖ?ÓÔûØH#o'™¯?œ /¶—2ŒcÝaÜ8ß-ñŸ[ÿ®6÷Y}ïÏ"rŽFË Adj„äqøwÑ6ÿ&qüD<ͪ–ÂCÃPKN_†(UÈ|ºzˆdtd/mmlalias.entUT #´ì8#´ì8Ux†>M­Ysã8’€ßûWpf#fgºV²êrtÇÄʲª»bÜUµ>zgß–&a‰aˆ¤@Rrí¯_$H ‹TO=ôá>'®Df"þðóŸ~üñ‡Èüù”Iív2–Y\½y•ªH›D¤Ñã÷¨ÞŠèŸw7Q•¨¬¬M¹´Nß¼T²­ü¤Š]”åeSGi\Çú?£&Ï’"o^vòÍm©oRÄ•ˆ”( UGqþ=JªŠê"jK\LJ,V±’Y¥Åù95ÿŸügoÞ$Å›æùïu¯åÉ›PY%ÛXÅI-Ttˆe#ª(®ªl“kÁ5WÄÉ6Ò­ÉêïmÍ¿VÛ¢‘éߢ]\›¿ÊtÓTT<=eIËè¡»cìtͪ­W(ÿg¦sY•y,å÷Hÿ£Hâºï«¶Šc­Š¼Ò-Κ]ô¨; ŠÜvh/xe:Ìüäïî?ÿóßÛÚú7”•–èIÿf-ëVèdIõ&úRÔB—ŽkS¥"DÝÆÝ;E= ‘GJW{ʆaL ¥DUyšå›èóÝ×¶RRìvY] ÍËuÏm›*j{JSô_æU– ¥)zz<ê¡©‹®Ú6Î7BË?þý‡~þÓúËýçûÿÑŒ.äýùó_þíevqq1ûéÏÑßͬ³óÌüúåow_MùÈ@©Ûÿ‚o?"Àýzõ«.OÕ{TI p«Ë‹ð'ϺÙXÑ€G[!DYeR·‡˜/8„)Œ¥Êv"”b¶xG÷ãc[1ªl‡ºrq͈a S„¡7;ÂêâÊ d\mbþžB\E•¨w9”BEº°Wdw^uåC$qS ܸ?í´j˃¦üK*׋K«¹€1¿Àmé¦ä¦Öœa˜Ò@*¹‘iB[:d<Ǫ8").gd.#¥5—©õ§,þOä(b}…f`uÉ'Pí›X‰`.—Þœ°ª&²¥Ðœ0õÝúŠç¥À '%A0¯¨A¤'R<ÕAè+Û '*Ûl{ƶ, C _ÕxsbÉmE]pK-^vYNèFoÚˆ,žÁ¬S#Õ7…™Þ¶0`\)qÀ¶Þìâwèõçeôh‹‡RèPÔp¡å ‡Ä‡€]éÙzƒ±Föæm[´‚CÙ"BÂJ¤™”1ì‡1±L?$¦xHH´ /”·“9Þ@¾<ü¦çDŠö±•E\ÿD²Éó.VÏaO|˜cÝmFýÇS}ùŽÜoMy Ú[ÔîáÑ®sg]‘æû2*$R™Â_çó+¬2[„bi\Õa;.IÄUT˜’a0‘l‡&è’$!íMgG`6ã– ç„EÀ9Á›GØ:ꄸ…S{‰‡™UJlÈúw`B¼]á¥aݘâŽjÁoƒÂt-`¼‡¢Õ­ãÛ 0OXx„×"î…yÂÀë¬Á!‹äù˜UbUäuѨÏz½n”öóužÝD’£v0³.wYhR£ä÷ë¢Ñ~ù5&8ЩÏ9ž"vtÒ}Sp˜Ð𠱄 Ù¼j@ïRa‚±o²BÃÚG>ðRiǕբ½A1æÌ®œØòјàätÃJ½§ÐÓ­)W”¿ø– ÄÕwØÅ‰™eb_*jÄkfŸMQB•Ø"ª&f·×ˆ*!¾kàÌzÆtJäX„ï8cÁ% ŠFhÄÁßäú-ŠTkÚdhˆm®g´»\Ï u’aà}.…ŠsPȦhå #Òx³ÈçÔ‚FÃu[ ŠºÂ*`ù±Äõ5ܧ®…Œ‚?N`„åy¬ý€ÈâDeu–Är™4N™j +"cÅŶ Gh÷\gcejh³ ê¥îËqq—š¥džåü¢LH¸kÉ{¬E acËp„ûL¦ƒ 8Âdµ-ŽiïŠ3ñ%Ó’Gˆ0KÜ‹m·ˆÅŒ1m¯ˆ¨v«&˜þ+q«ûVÄþÞ‚°÷¸¤]Ø4ƒ £«Ì—Ên(ÝftM†ý4` ÷‘–p£·C@À“öB¾B¸5b‹qrl—Ñöʽðâ]Ë5 ˜Ó¹è/×Úç:ü‘mRÍá[cåxa›ÓQÆ7é…m“F2â¯1ŠÁŒBØ!z•Ðö®[6äò½×ȧme7K†yB®¼eÔ0B<”ÃluÒ!\Fñ»Pv‹Ô+³_sL$°Œ¡Í£y¬<Û«“á/»/ »ëšLYqýj=_ p£Ñ>1ý˜6ØzÔˆ¾+ªA†îI±¦ú6VeQäAĈ>EÒ]X²ˆ bDŸ†µ¢/Ì:ý]$µÑ ½5΄ú¥F e~ÌíÒp '3³¸ø„r‰u…–uœ´T shtÝb‡`x⃠3æ?«²¸ÒbWÖß+LÙ»ŸZçâ=9¶_ÛŠ€µ){£ƒÜfµÑqšPô'ù>œæ†`‹Fp?øÏä 3¦<Š×çõ¦V!p Z¦"RTa ‹°f[€k»µîÀ™mЄLfÊ$ÄøgEŠ g¸Y%ñ’Uu…;rÆ„3„)"žb)³|38n<¹v5R¶BLœE]ý¨U¸ØÍ†þýwf&úŒŸ†aPLNrФ–´N gÒ)šGµvçÍd®jäØj„غ9š<àNÖàÿþÉ#©ë‡{Üôq8hƒÚ_QÃjj/´—¯—Õ®«_ãD4ê…UÏÁpôoŨ}‰ûž¨ãLzb,™8‹‘£–X’•ÈŒç7eAŒ‡f¬ô”0ÛÊ ÚÓy¿Àl$©ÐG]¡TÈl—Õðô²¥sù™2ˆO²(T8<‹¹àu›žlaÔ·] ËÏÝ€ò~îîœÎ³o Fô£ìÇó˜Ci‰§š©Nmët"ô2±¸†0þDÜÏ!lE¹Z,¢“ªg0‰lR¡pIϨöM¶‰ýu»d&†iËwVdL{“‰vÀ‚Ô[%„;Åtû“Q'maB /¹ß™ÀÍA¢Ürø»Ä)¿e!ÆCÙ/÷a™0I ½à=Ày+ 1¡^)P}:öÁÄEåÕ§ÃGL‘dbœ#…vJ?´ï Î6Ô…%ꌎÑ%ö î8Ž`ÜGýBMay&ˆzC#üîpr¹¶1IÔÃ9ob¼#Òº[r ¾bô/iÒiý«ý枸b–«„™-’ <þ–(ü½‹e-ðMåÄ-|Ó¦8x«lÄJC m'âªQ"×/ˆ´àe÷À&êÙkÞ½ Ç î#Yw—ã›;?iý\F#µ×£«¹Äý®¶3ÔpSì#¼Ì®ˆ6Å<®?¦ØGþé;”¶8 ˆ †4,3Æ5Ïñ2û"ªZ¤µ Ö±§¾-Ø\Ý™áDS) ÀgÉmäkW0àÙ»3øæ]~Éš<ùb*bej| §¹¬1 ð£N õšַס¤î2ØŒáH_UÓÛ9 QºHcȱµ“øÓ8¤ ¬Ø<ÈaàÇIÁ"()è™1;53 C{ 183 ‡}€fFxž;Ì ²? ®Õ¢/F9i§hq-J3ølIr7Ñ”.©)kò†ÖŸíýŽ¢ÎrŒ ²Ï‰[-Bàúê9CñhFàkO^« kËÙšk ¡ÜÑSt`àÍ 7YZ¹èŒ=Íü¥Æ&L*qRq[e}€©å•LP¬¥ 8ÛÅ(. aвC¬™¥G,"hËš4Ô; ï*½cŠ2èƒUL5v¤a%8cßê†Q£ÒŽ´1vâÝ„’&kÜs‘HaÔ”ù¦D"RpÕø#'¼$é‚„ªå§n„&ár(Ü+k^ ¤Á [q0ÒN‹;åɤ'hýg‡SìÕ·œœ$¤é©%QÔj a‹Hk¥ãàÝÙ @wÍc%@ÏpÛcµ¯šGTš(nöÌ1(+ Xâ™ÙwÈ+x\Þ#ÂXêÅGnÎÐ j’DˆL`NñÂ+º ˜ÀW³S¸JxYˆ Ì DM`7>a£gº¶d\`4'8ˆS÷^$ÛB»X<-xË)(ü ›C ³á-éHj~ Ï1úÖLu‡5À·'‡ð׎]‚ ÆÆŒ¥0çj¼MšWÙÏÓÔ@Ü{>CSçAD²GÍéK´ëƒ#ŠíÝŒ ¯µöžªm¡jÓÕ OßžÚŒ+<>–å Ò0>§Xx¤‚7 ÏšõFÑù7RÎЭ=¦8A·öˆýxt+‡×ÎSÏ@ÌÚ3Ô³Qqd§Ž×ªwêx­Ú#`§¾‚€¼McçÓœ3lü<|ßl`Œ7B„–ã Û(?2‘F&xœã3ä¢ö«Âc*_K‘³/äà^µ‰oø…œžÒ=Óð,ï!¡P©PÅꎓ©aˇ¸WõÝ1öºé·Xo–±¼†€“kspC²:Ù>ðq° ú ð6²ECdSýæ_Þ·„Ùì kÓ“&_‚-É ãi°i÷.†›¶©O¦­0ÙÞ¥‚¶‹!t/Ù„æ"áO…âôF„bä[L}FÂYžÞ hò]‰ìYhAMnˆ‡3Nß1›X©-j~°×mˆÌ.¦k‚à'Áœ‚ì 2f|g~S…y =ëïºvˆsh…﹈0HD¼HÖêo ›Ÿ'ûÆ1/Š1sBØ !Cq™ëL¼Y¡¬oÅe®3o³¡ÌuÅe®3”¹~¼ÍÙ÷ÜØûlÀZ x‰Àü„¼1š¢>þÃÜ…Èáñx7‡_2> ¶ƒ<”sI‡ÞÍccs¨»ãgð±^Éü°ƒŠ #è¤9ÀøÛ-AâÉÙ"XzÞ„~›É\äF”¡'ºËî¼I›WÄ]+‰ KÛ ÆÃ¦m(|À"èËýüj­éq·:ÞpÀõÌø§$,¿àZENxÝ*â6€Ÿ7î=¹<å- a¯8“Ï¢p޲Eø×Μ&ÞÅ„! ~ü›–á'ã;“£¤ðœ‡9ôý²ã^òÆIôÞ«7Á¶D_~¹ø=W‡€£³rl3ü4üNº3ÍØ8 ? Áí _x×íÀN&‚§m¦Ûˆð2-ÄÏÃï:ƒxU|éÒð©•æçáŸ3Å«à-‰ÞØ`z£}¢9DpY·¤Ùµêʃ–0ñ?úö·n Nþ½åò×8•ggÅ%Ïã3ÿ žw›ð±;6¤g¯Æ µ8XùÀpfïv/^eÝF8œ £™ž…|yÛB*_òâT ±^ƒÑ>2ʤÇáÀèÝN7©}92æ~dRìÊ'0f•aøcj؉q×ý¤]Iâj|¿–?ß¾°eÁµÝ»½"CNsìSwÆ]šÐ¨=ß#Þ-úÈx¶< yɼ²H)Ú³AB :q¼e”4‰ÁlVÔqä]ð@bÏxßH4/éu)õƒ‹ÌN æc"ÕÝböiÏöœwʘ„g¼gÉ+ÇÄÓ‡å!ÏÂS±š!¾3sW“/Y\ЗÍzµ› gX­bbvßÉjÝÛaØÇUñ'²¡Üfž³!…%˜r!éôsƒñ¥ðÌ`ô%[Sž’¬ì#n‚“®up ô ¡è@(<ï?_†ŸÁ0§ºŒÀ;‰û pY.@éª+2ôl ¾ ßuÅñaö: „1;ãPŒÙâVÛa cF^‹oöçŒ\dÝÃú˜Ñ‡Þ‚Qeæ….L|@Oà"x ÈrÞ)%8àl!£>¶(ßH÷&V»V] Qe›âÈßla‚Dцø×kg:_¢Lóaûɰ5+ É®NÃéÃö“aX2í–ը߉-×ö»-Œû=4j)7þI9átñG¸eþN".fÄ!žmÄï c¸ÓãuÓ—è˜ÕÐÅ"æšGsu‹ß—Ú¹Ó},¸ÓsÊÞÆ™‚îtøAy¯yL(ÎAóþ›Lù(ý‘~eNØZÕÚLŠdŒéæÿPKO_†(åRuα Í#dtd/mmlextra.entUT &´ì8&´ì8Ux†>M¥YmoÛ8þÞ_ÁÝz)çüÚ$hQœÇÛÙlqqz{÷éh‰¶‰H¢–¤â¸¿þ†¤D‘åän4u¬™‡ÃyŸÑ»Ï? ïúYÒŒ <ÏÈ‹äøŒ•œ¥UBR´> ¹#è÷‡;$NK©èR™ž½ˆÌ0o8Ë-ÊJ¢K QUЄ¥äì%ÏÎÞªoÁ‚ NJÆ%ÂÅÎH2d(ø™¦èóŒ çsªþNþ^àíYÂΪ§/ Ô ä)ªœpš d‡9N$áèg A·¸';·¡ò`8OÄŽUYúåXªG®ÆÛlhBq†Ø5FœÂð1î~§”óLeβ‚_,ÁÒêʰ4X׬pcZåh H+´B­àB)L}óŸ‡Õíï5ÜpB)@¢ œ ²îü¢‰8C÷L ÆR±ˆˆ¨;ü Úa­ )¶ m͘0Ή(Y‘Òb‹n~3L Ës*%¼4·«2šxXš(Åk0d5Û[f ¾¼{÷ù§›ûÕíê_oÿóóû¿¼ ÇãO?£/Êëœ.—ƒòÑûyYf‡eU$tú )4 æ=‹‚µ.°{u¯MCŽ™‚mÔgÐr wM™¿%Þn±šVgGôñlÚœÖ*±’€~ÁBÄ5.©ÄÙ‚n6 3p>ø\ÃŒ¦³f¡M[A®Ô¡§ˆœmÏNÑœ“*±%Ùrø><呃Í ÊÜ+”À ¼[Rð ®. g‰d(A(Ï6P*¢ÖʽcÀ1JÈ DÇ Çî1àaà*€[“DZ®9ŽÀ Ö|¼´–Ô Ò3I”^M’>LšF½k4ýØã]ž%ïZ,zÀfq°¨q}DïQL¼ôOš~ÁöÅrçþ sGæËÑÄž+•טw®8p/=œŒlH­ÕÓSà™p•ØN”#‰'à?º`wd#ÿA·;ùÝØ­h6lð2 ÐR ¸"3BØ– 1 ·"$»é€Y]¢×TPG)«úØÕ§/}½®PÖu#÷ê—ÊÑ•+Öù°>¹@$í ®óÎ-†„-ê"R É4¤‡AHOœ÷DÓÍ Tã¯7A0Ýä¥<<äPþ¨0'5ÖlisQH($ Má;á¾Ë"‰æÜµÜ3]ÖHRé¼H4‡JìA¬‘—Ì„›ÚcÕ3±®íRœ4áC¥Ññ’µuÕ(õªlz9z\ Œm1‡\R¹6ˆèü¢ ¯ó‘{Reù¥÷h 3’Ælaƒq£IŽÃ`ôÙ4Ä|s̲KVqÐäß['6sÕúØBh§õ~á:5^ÿ׺Æ|Ü ™_V>ïWšAQ“=+¯Þš Mâ33N0è=²;ZË<ý8ÛY:h¶¡‡ o,Z‡­~´¢÷·…êT¡i»†KiOð_ôÿmŽ¡gÂüp µú¨­z ^ÜX—3èTy0 $–*£ª °ÆS«i,µ?O1ÅWª·7W#%ÖY )纔§4!} +šë«im­3æ˜? ”W™¤m#»ßAcO%¢æ,èË!¯³T÷ F0ŒS w›ö ÐΞd­ïp™w‚pdÑjо Ì 5YGÜîfêÖå=æ©8ÒŨÒiƒ”6”͉öº€ú5½,tâDy¥¤7PÝŠ~ÙÕw%·jp¦~ïS•u‡P•ñ&ªn ºAD5¦1ТÅ0I¬,³y Ë”³RÕl›m©çÚÖ>5¬êóeMvªÊŒ»ºZEàËVÛV,k5ÐNÛnz*97lÌ? €Þp¿Ç²5½è¢§ÏòF‹2îÓvEõ/l|森Ýï{; ¢”m3©ž¹AׇãO(î{apà Ib>kõú:ʯ$ƒ‚Ц*Û0ØYÉPô¥ªºCêÔŽÑÌ­‚ätЦ©ŠÎÀźÊÛ+Y¼1D¸™Á&nX(êƒéNc@$´<$¨ ¯(Þ=ÙêÁ¯$¥UnzœºJÌ $” «4ÓàÀe÷4•;4˜þmtH‡\íhòä!g¯"Î^A,|ÀËW'ÇU{Ú¿ :ŠDÐytŠs'ÑŽŠZ«ñî ªÙ£“èÌJÒ®Î_™F,Xw‹Ù,Øx·#‰Usg="S¼Ô@oÏú+6ÿMmˆØé8rÏVWí×!Ô[.è΀ д¨WáîØÀLþ7Vém^f´ÎI5̹U7WˆÖ$>s•‘Éð¤nP\.íU8P Òšä$aˆa„Òál¾Ô^ɾ°jëÆpÚí­õ ÊyuÕz,ÕÆd8é·40>Î {Ù¬í§Û\×U¦‹8ÌŸÐ%:Ùú =É™p\­©9'>8D§›GµÌsëzýZnbw Ë×´Pù;ƒ‹uSšAàPiÛ]„¢ˆVxËÛ”ø¦ÂϺ¼_¦¾y%9n]÷HyÐAØš62ëÏuµ;û{=ìœd¸ÏgÁÛf™Èb½Áxhv·]Ë^ïwõ¸í÷~g9ê\gl±€¢oãðoÂÙ?•“4þÔÙ4ÿŠÚÚ ÿPK Q_†( íAdtd/UT)´ì8UxPK3_†(D&‰rq· ¤7dtd/mathml2.dtdUTò³ì8UxPK3_†("&U| ß- ¤ëdtd/mathml2-qname-1.modUTò³ì8UxPKA_†(¯6 @o _. ¤±&dtd/isoamsa.entUT ´ì8UxPKB_†(=º­¬ Ð% ¤b1dtd/isoamsb.entUT ´ì8UxPKC_†(X¿3u‹Ö  ¤1;dtd/isoamsc.entUT ´ì8UxPKC_†(bû©Î3T ¤þ>dtd/isoamsn.entUT´ì8UxPKD_†(‚|@¦ë ¤sFdtd/isoamso.entUT´ì8UxPKE_†(ø0å 97 ¤[Ldtd/isoamsr.entUT´ì8UxPKE_†(S§ÃE‹{ ¤‚Ydtd/isogrk3.entUT´ì8UxPKF_†(G’2ºI¤ ¤O^dtd/isomfrk.entUT´ì8UxPKG_†(Wò/ÇVp  ¤Úbdtd/isomopf.entUT´ì8UxPKG_†(F·cR  ¤rfdtd/isomscr.entUT´ì8UxPKH_†(¨. ¿ 30 ¤kdtd/isotech.entUT´ì8UxPKI_†(÷™7Õ…» ¤xdtd/isobox.entUT´ì8UxPKI_†(Ô‚þÞ‘ ¤Í{dtd/isocyr1.entUT´ì8UxPKJ_†(V¦Ic¡  ¤í€dtd/isocyr2.entUT´ì8UxPKJ_†(Cð¾&íÉ ¤’„dtd/isodia.entUT´ì8UxPKK_†(¬ D‰óW ¤À‡dtd/isolat1.entUT´ì8UxPKK_†(™í3aø©# ¤õŒdtd/isolat2.entUT´ì8UxPKL_†(„ ýóÌ ¤/”dtd/isonum.entUT ´ì8UxPKM_†(søT†´Ë ¤c›dtd/isopub.entUT!´ì8UxPKP_†(÷,9úŒ° ¤X£dtd/xhtml-math11-f.dtdUT(´ì8UxPKN_†(UÈ|ºzˆ ¤Údtd/mmlalias.entUT#´ì8UxPKO_†(åRuα Í# ¤×¶dtd/mmlextra.entUT&´ì8UxPK<ËÀXML/inst/exampleData/dataframe.xml0000644000175100001440000000015513607633705016613 0ustar hornikusers
    100abctrue200wxyzFALSE XML/inst/exampleData/xinclude/0000755000175100001440000000000013607633725015761 5ustar hornikusersXML/inst/exampleData/xinclude/d.xml0000644000175100001440000000020113607633725016717 0ustar hornikusers From d, we load XML/inst/exampleData/xinclude/b.xml0000644000175100001440000000010313607633725016716 0ustar hornikusers
    This is the section from b.xml.
    XML/inst/exampleData/xinclude/e.xml0000644000175100001440000000006513607633725016730 0ustar hornikusers This is foo. XML/inst/exampleData/xinclude/top.xml0000644000175100001440000000022613607633725017305 0ustar hornikusers This is an example where we have nested includes. XML/inst/exampleData/xinclude/simple.xml0000644000175100001440000000012413607633725017771 0ustar hornikusers XML/inst/exampleData/xinclude/a.xml0000644000175100001440000000045213607633725016724 0ustar hornikusers This is the first document, a, that then includes b.xml This is the second paragraph in a, a, that then includes c.xml XML/inst/exampleData/xinclude/c.xml0000644000175100001440000000006313607633725016724 0ustar hornikusers
    Section from C.
    XML/inst/exampleData/solr.xml0000644000175100001440000001167413607633725015660 0ustar hornikusers 0 90 17 17 1044 1297337332283 true true false org.apache.lucene.store.NIOFSDirectory:org.apache.lucene.store.NIOFSDirectory@[{PATH}/dev/trunk/solr/example/solr/data/index lockFactory=org.apache.lucene.store.NativeFSLockFactory@349319d9 2011-02-10T11:29:03Z tdouble IT-----OF---- *_coordinate (unstored field) 14 64 14 6 4 4 4 4 4 4 4 2 46 9 7 1 1 text IT-M--------- (unstored field) 17 389 14 8 8 8 8 7 7 6 5 5 278 67 31 12 1 string I-SM---OF---l I-S----O---- 16 14 14 3 2 2 2 2 2 2 1 1 6 6 1 0 1 Indexed Tokenized Stored Multivalued TermVector Stored Store Offset With TermVector Store Position With TermVector Omit Norms Lazy Binary Sort Missing First Sort Missing Last Document Frequency (df) is not updated when a document is marked for deletion. df values include deleted documents. XML/inst/exampleData/test.xml0000644000175100001440000000200013607633725015637 0ustar hornikusers ]> &testEnt; %extEnt; Note that this caused a segmentation fault if replaceEntities was not TRUE. That is, xmlTreeParse("test.xml", replaceEntities = TRUE) works, but xmlTreeParse("test.xml") does not if this is called before the one above. This is now fixed and was caused by treating an xmlNodePtr in the C code that had type XML_ELEMENT_DECL and so was in fact an xmlElementPtr. Aaah, C and casting! XML/inst/exampleData/StatModel.dtd0000644000175100001440000000226613607633725016545 0ustar hornikusers XML/inst/exampleData/include.xml0000644000175100001440000000050413607633706016311 0ustar hornikusers This is a caveat that we repeat often.
    A
    B
    XML/inst/exampleData/mathmlFuncCall.xml0000644000175100001440000000035113607633706017560 0ustar hornikusers f x + y XML/inst/exampleData/xpathTest.xml0000644000175100001440000000031613607633725016654 0ustar hornikusers XML/inst/exampleData/entity3.html0000644000175100001440000000023113607633705016425 0ustar hornikusers

    This is an example of an entity <.

    And a degree ° XML/inst/exampleData/literate.xml0000644000175100001440000000542013607633725016502 0ustar hornikusers ]> This document is a very early attempt to illustrate how we might use XML for "literate programming" with the S language. The idea is that we write code to be read by ahuman rather than the machine, but that in the process, we also generate the code. The goal is to develop more readable, understandable and hence maintainable and useful code. The topic was pionereed by Donald Knuth and there are various pieces of software that do it in different format. XML is a rather natural form. See also Oasis-open

    There are numerous practical benefits associated with using literate programming techniques. For one, it is easy to comment out code while still leaving it in the source. It is also easy to have two pieces of similar code and swap them when experimenting with some modifications. Also, it is easy to reuse a block of code without having to play pre-processor tricks.

    In this example, we are going to mix programming languages within the same file. We will write an S-language (meaning both SPlus and R and from here on, simply referred to as S) function which calls a C routine to perform the computation. The function is uninteresting and simply computes the process identifier of the R session. It calls the C function getpid to do this. The function takes no arguments and returns a numeric vector of length 1. The getpid is declared in the unistd.h header file. So we include it here. ]]> ]]> USER_OBJECT_ RS_getpid() { USER_OBEJCT_ ans; pid_t id; id = getpid(); NEW_NUMERIC(1); NUMERIC_DATA(ans)[0] = id; return(id); } This is gratuitous text. while(T) { } Note how we use the sgets entity here to avoid having to use a CDATA construct to escape the text. if(x > 10) break else x %sgets; rnorm(9) What we are trying to do here is produce elements that are processed conditionally. It appears that INCLUDE and IGNORE directives have to be within DTDs. (Is this true?) Hence we escape them here. ]]> XML/inst/exampleData/mathmlSimple.xml0000644000175100001440000000021213607633707017317 0ustar hornikusers ]> x 2 XML/inst/exampleData/book.xml0000644000175100001440000000075213607633705015624 0ustar hornikusers XML

    The elements of an XML document
    Parsing XML
    DOM
    SAX
    XSL
    templates
    XPath expressions
    named templates
    XML/inst/exampleData/author2.xml0000644000175100001440000000052513607633705016254 0ustar hornikusers Mark Edgar Twain XML/inst/exampleData/size2.xml0000644000175100001440000000057713607633725015735 0ustar hornikusers 0 0 500 0 1 300 1 0 200 1 1 400 10 1000 XML/inst/exampleData/author.xsd0000644000175100001440000000063413607633725016173 0ustar hornikusers XML/inst/exampleData/9003.html0000644000175100001440000000041613607633702015423 0ustar hornikusers BKA/RIS VwGH - Volltext Veröffentlichungsdatum XML/inst/exampleData/mathmlSums.xml0000644000175100001440000000151113607633725017020 0ustar hornikusers ]> sum i = 1 &infty; x i + sum i = 1 &infty; x i XML/inst/exampleData/reparent.xml0000644000175100001440000000010213607633725016501 0ustar hornikusers
    XML/inst/exampleData/symslines.svg0000644000175100001440000022453013607633725016723 0ustar hornikusers 0.0 2.0 4.0 6.0 8.0 10.0 0.0 100.0 200.0 300.0 400.0 Circle Square Diamond Triangle up Triangle left Triangle down Triangle right Plus X Splat Filled Circle Filled Square Filled Diamond Filled Triangle up Filled Triangle left Filled Triangle down Filled Triangle right Opaque Circle Opaque Square Symbols 0.0 2.0 4.0 6.0 8.0 10.0 0.0 100.0 200.0 300.0 400.0 Solid Dotted Dashed Long dashed Dot-dashed Width 1 Width 2 Width 4 Width 6 Line styles Graph legend XML/inst/exampleData/size1.xml0000644000175100001440000000060113607633725015720 0ustar hornikusers 0 0 500 0 1 300 1 0 200 1 1 400 10 1000 XML/inst/exampleData/mathmlSet.xml0000644000175100001440000000062413607633707016630 0ustar hornikusers ]> x x0 0 &infty; XML/inst/exampleData/mathmlMatrix.xml0000644000175100001440000000074213607633707017342 0ustar hornikusers 1 2 0 1 1 0 2 1 XML/inst/exampleData/charts.svg0000644000175100001440000016610313607633705016160 0ustar hornikusers 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 0 5 10 15 20 Value Data A Data B Bar chart 3 5 4 9 6 5 7 8 2 7 8 12 12 18 9 13 9 19 14 24 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 0 10 20 30 Value Data A Data B Stacked bar chart 3 5 4 9 6 5 7 8 2 7 5 7 8 9 3 8 2 11 12 17 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 0 5 10 15 20 Value Data A Data B Scatter chart 3 5 4 9 6 5 7 8 2 7 8 12 12 18 9 13 9 19 14 24 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 0 10 20 30 Value Data B Data A Stacked line chart XML/inst/exampleData/cdata.xml0000644000175100001440000000012713607633705015742 0ustar hornikusers XML/inst/exampleData/eurofxref-hist.xml.gz0000644000175100001440000064633213607633706020276 0ustar hornikusers‹c[&Eeurofxref-hist.xmlÌý[“uév” Þׯé>Có|À€2ÎTCQ˜Ýw‚ÚÐtƒÀ„€ª_seÆÞ ÷|ÖòñNÞ•ñ™a˜!B_F¬Ã3ÇÁ‡ûßü_ÿ¯ÿôÿè¿ÿî/ÿëøÏñ·þxüþø~÷ÿö?ÿŸÿá/þýßúãù/þáOÇÿ¯ûù›ÿþwÿõ?ýî¿þðÿýwÿñ?ÿ—ßýÑõ¿õÿõoüò?ý[üÿý«¿ú/ãOþäüÿññËÿèã?ÿå¿ÿ“ëgþd†é§áøiÿø—ÿùáßýÛóñþâ¯þä¿ÿçûçÿæ¿ýÇ?ÿËÿûËÿŸüî¿ýåþwÿ×_þîßýñßþýÿ¿þ·óÿûÝ¿ý«¿ý§¿ûw¿ûËë÷üÝýåŸÿÕïþëßüûÿÿýÏÿÙïþâÿüÝ_þáÿùþŸ~÷·ÿÁõÏþ—ßýù_üÑßûÝ_üÕ_þùü£¿ûçñÿÿÿðóüáÿõûÿý¿÷ßþÍï~ù¿ÿè¯þÃúÝßúãë×Ü~‡Ÿ†í?ÿçÿö¿ýåã7ú¿¯WíÏþþÿü{=^ÏiÛ–?þ“_ýÌÿëŸÿ«?üÌr~,;üÌßûWÿü÷?3|¬û†?ó¯ÿÉïf:>&ø‰¿ÿOþðûDz®'üÌ?øø™qýØ–mƒúG÷˯³íýCÿø_þÃ?ü:ûü±Ó¿óOÿÅ?ýýÏÌ×/4ô3ÿïúå¿un#üÌÿþ/¾üÌ23üÌ?ÿ§ÿì¯ÿ[çtÒëÏþú??¦}ÇŸùßþÅþ®ùüØè¿õgýBÏûÇ8Ò›ñ÷þñ?üëÆzôwýoö‡çØ>úuþÙÿñ×?ò±Ìã ?ówÿÑ?ûëÿÔ¹®ôïüã?ýò٘ϓ>aú|y ×?Íú/ÿî~æzñ%üúןøãÄ—çïüË/ßœëm§Øßû;_~f™fú}þÞ?ûëÿÖð1 ø¾ÿãò÷ÿú}?Öƒ~¡ÿíïÿéþ¡qÛ†™þ¥ò§ÿŸ?üÔ4пó¿ÿ«?ü;ËǶô‡ý³ýå;‡ÞÔþÿðÜæ™þSöþðÏLןŽï׿øÇx¿– ø§ÿë¿ó§_^žsÿù³ñ'?ƒðA®‰„ûDw'!ýÙ7H8ÒËXˆ/ñ"Ÿ„…˽߇ÂÿEáqÒëã(Ì$ÄwÔ@H拓þ&áàŒØiÇàÿŽbp—þn¡à9‚û0fÎøÅ2®K„à9`u ÜÇë™D¼BðA•ÈÁá¤Wúåà†/µ‚pœñí#}š„ç1 „K, BIH/ß â7Ë9Hö.ô%®BîÛ@¸ H°¯ œ§© §…~ÆIHúWî\ƒ( ODw; ÷þcᆼԒ+0…ᄤ3.…’«+£á´Ò{¡%á1ÓÏhIx^£—Hiø¨‰3 ñ?§4œð›¡4\rU8ŽôÅPng¨ /ã¾Eα,œéµqâW§‡ôw¿«*Ä7ªÂ~æiÈ-…ÒI§0\±ºTbÍ¢0Äâ+ /ÔÑ?cu!>úÛaˆ¯±±?`VâgYY8âÇX¸â„AYÈeá†×Êp‡ŽV†ÓÕäÐKô«Ê0¢ðz;2 Ü ¯üYUbÇi…!Îç´C~yë_¡pÊ…!ý.†B~¼Ý¨ é5"žî°pÓBúË 7»)ç‘^d!þ;Âßt'ašž×Ã8’pA¬Ü) 3 ±À²ª?‚^HˆOZ#!¢À«BlH­*ÄÁ·V…ûöm« ù‡¬*ð'(œñkjUa¡EÆï—’pÇ/†’pþåzFÂáüéúDBz· „<úm!4Â^-2~utmò#pÇNÁV&ØÜ8é[s„qer|à{. œ:U„Ûã±¢ ì†A|¬Ûúÿ}(IJ¢pÃþï 3 ¹#bQ­$Ä_øFE˜A¸`%c½1~,¼7¦_Ç@ˆ¯±ƒa© œ±Dµ­ bÇzã«tÊáøÓhßšä9!WèJÂ+ ñß±’pŠ(Üç_64¯P¸wØš}zã©k%!>ûï°pÄõ•±%'ßÈÂ8'œð£ÓŽÂ—JÊÂÿ,ca® qò{CGƒ½–·Ç¹(Ä™‰ÉhðW6ò^YÈ/²uÇ,ù’¢pÇ/©V…Çõ:Òû¥UáÆ3e᎕£ ±Pµ 2~æ…8Ѱ¥É@ÿްpÛÏÈÂ,*Dø ÷«ïÃ…^?‡!=ÛoÀÿ0c!Î ¾…+¾Î7¤4fbób“ÂXÎ,—hfá2"|¬0ÄÂÈXˆHaˆ S•ºwÌÊÂe*L qAc,\X(ãr…(úJÂãÄÔªB]: ñÉd$ŒZš} ÌšBXQˆ‚® \Óª°°=Æ/à÷mw†éÖ„õlÍZš›I¯ qR/(ÄﺢÙÝŽB.ù”„øÅòõq&!oÓ¬,ÄÇ–&ŒKAá8â B[ä9îL®n”%Ú!¯üŽÙú+GÓâô+ —üê( y’lÛcú­ ?Éü …qy|à>ÒPxTd+ ±æ±Q!ÖæwP8c—#,ÜXaõ,ÄFH«B^7£6,ħÉž¿€¶?F]Æ[P¸á÷SQ8"æ…Û§…û€ãC!v‘†Â€ŠB>ÐiácoBo˜°p¼ÚÖ¸?ÞGÔ˜ÛÞ?AÊB>1"é†'.+lqòËÊì Ǭ*ŒÇ&׋\Ù hˆ5†ôߺCC,¬ýØä‡êùÏRŽ<1fYáŠÍmë¹ÉUÆ{“ WÑ7`Y8ãßde!þ;:-,T…¹ìÜìÖ ¸ µÅ ®«µAž·¤³Kiðg2Î/mXˆo˜¶È;Q®¥) ±p.ëwÈCâHÈ{ä>-2j¹½.ìÕ"#âmVˆÊÍï#aaV8âÓøÆ¬«f#!"AIˆm…’7o) Yti³Â¨¯>6ì …8÷¾qk²à÷ÏÄ48@WNŸ x‡L1Ó ðÐHˆEÓW6ÈX[ƒŒÃTá¼/IT8fQ!þÙ^â`ÉHˆß,ë b|²Ý"av$aŸyÍf #ΫÛÖ ~m”„'nît…ŒÏ}#a¯½Iåð÷`ÆBÔP) ñYb,ä’OYÈ#Yß›dòÕ†°ð*á?p¯,¼úß<-\ ÓÂñln ea^œŒ¨UÎk„aTn±;¾4îî6”#ݺ»Ã¯×W^ÒJN3å²p6ü„ù´°°8A¤þê9;tmHU…áÊ 3g!¶VF9Í9á»a,Ä–ÓªBü ñC¯Uá/5ê+Fgš 5?7©Èi [œs½k‡œ­if4ß 2ÖŠBž24¯ì$}T˜ïM jœT´“¿{FB|¯Ü¤+…>„ø¬ub7¥+ä‹Û›àU‡…ã““¢ðzCèïwe!>á”…Hy]!³ÓRûénôum2­‘…Ñ—fËc!ò²…+Þ÷û¹Wƒ¼á‡þMÞ­X‰Ý !n–Œ†ïÖJeXQÔðîR*Ã={ÓPá8,X·²‚C ÃB‹Ì—ÜfÈ€/²Ö…ÜSY]˜mºÖõ¨HÕ¥zVâ†\iÈÕ£ ­Ñlð LJkZžÎø3ZN¿¼D¯på…;¶À>/ìÔ&—æ…½Úd|ÓMPƒ«æïk“yomrAh]€aE^¸£DZå…,¾6¹“iáÁ†„êcl¶Úë“ÔàÔhXZã ±ÁÝìæ?ð&©+¥áYÙ#Œ¬¼²Ê×+îdÝi¶1/’tt2fmaÅ”•vÎØ¸ú¹Óõ?“ü褗SW'æ.™mÕn ÇxŽÂ¤´~rä¯u!6ä7, ^ÖQQó a¥KÎþ4, tËB|‘íæO…'Kž?æ¸Fwþ!7¨É§È¸¨±›<4¢[’0›2,Ÿïü =üiö¤»£iE! ßµEFô ‘+ßxs‚|Òû»±Ó%r……|‘¤e!0µ,ñe¾Cìuœv'vA!ÁÙ%2>j}`ˆ=—U…<»>ìK-2~VµEæ9°¢×TÊ‘g>Ú"$5øõ2EÍ™5C4¨)œðyB3 +¾þlbz‹…y`¸ñ!Ã7Â0Ì|°ô&"[ìè$J­GVl·ÃßQÕ®‘Ù=Yq˜Í¬·§‚C6%¼³?ÁÜ*Ã}$½2ÄIŸâp)ûï¸Ö‰!Ÿ5;ó 'ÁhmøiRþŠ‡Ñ¤†K¨; ”qVã<ìu‚‡­åœüPÞ…++õÍ™¡wáZ |ÂÛ ]&ÇyáÈ.wŒýñÖX»d¼ß´{d¬{l`ˆ5Âp«´É…õÉcÔa¸ Æ.OV>5NKe™\i“ùœAkCüË|b˜Y¸£Ýj ç9™3äì;¬š­4,‰­3 GÊú.¹W è’ »¶¼¾C<òl§!ï‰Û3Ÿ˜ªJC$¸ÑWk–s’qØGZ3ó;a¥!’ÎÝ" y‡g0ä¯…Í ³àzä+3…!~½~µ=‰Ž]ׇ‡¿ÍÆÂ\òGìø’JYˆØõ”“¨1œÆäÌÓïØÍËB|Co°°PvK¿ã¯(ÜùûÆ.™CLtdXqr-X3ðýx›OÍã /nOøø¾„¬Ö÷&9‚5Væ‰!ïᕃ*œ†|‚w²jËÌý'v^´D‚©IÍ€[ÓÔļåƒ=Ñݼ0]žO6,VŽéôdˆ‹älÙµ¸†¿Ñ —Ì »…ÃǼs¿„O–ÄJÂJô]® Yeï{ät‚Ï%!®ÃÞDBüw…œ0¤ÓB,œlZX¸;ùK¡5ባ9« YÜ$,\¾¯s¢(DYA¸ÆQáòÁù¯|—¼ý/â£_A¸®¯kÂã§9ƒ# „lMÔNB|ÞåÖ…Ân[#w#arŽº)j°–k'aÁ¢fdž #–(Þ !›.( qáEav©A¢)j ·È™ƒYMsr¨…!,S ®8U ²ÖÃÆ„iJ¸>¹A7×ÂèPs1¿ÆÂÁqù¥ø|ÅÁhÕuàm‹qµÚ9ˆ3œwÝœ,9ädãòàýóÉ «µšMvÎòUbh½q\ |üÓBÔs{r¥",èiðW¶’°`ì_iŽ9—Ì Â˜÷ô@!öŠÂ‰TæàšKB>aP²¤Ôãž’˜æà±®’p8^_ß…Ð]¿D®h¬ $Ä… »mL"W6ù>‘+ö­…å1ßšzÄIZW”4C¯0dÖ ZA˜u…ìÙo D¾»°°âÉPPÒàVÁHÈãZ!ᲄ4óPðdØGd‚-LbÆÉ…B–†Ywœ.‘ÏÒ(¤?Ïó^±0Ь $äƒK#!Öº/Á'í»ü[+ªBTÞ_oŒ«?C!6µÍž ØüùÞ8K ñ5VÎøDºBl^\`e4NtÕÖÀG¿õÆØò[MÈð¾1ÉE!;~•†ŒSÎ%†PøÇÆÿኟ¯ Óæø±faOãžAXH{*¬Žù¨ÎPˆ_.E!>ߥ°Æ?Ì&?V2gÙ 2«´ÚÛã¼/Éš“­ßÓ³c¿íKÐù_54/ë¥Þ®MXs¡EᎃqE!~m_² ¼S54{!ßäú4+ëŸÅ/ÉŽa}H 5an‡ ?ŽcšNYE“Mž8µ£Í}Þux‡¼ ð‰jüûÌif¬RÍ¿•íÚ;äÊ­ >—†9îiཆ'û¬0·È1ijߚäåÉ4r°›àçÙXÈ¿5ÊéÚd}²¡ó™a–ޏ³åÉöZc}‚@O\±»oaAd]aa%þßÐ;f]X² ÖL~caˆ·V–jòÐM8†ˆ:­ £‰ë€K¡÷°° ±f»ƒaáÞ¿ŸÊBNÈSžü1ýkþ …/¡6ÉãXˆ¿›W>JQ.ìÀ¦MrLÝž¸‡{(r^$<\‡yMCÜùÄ C;CÆYV; ùYâ,ì$³>Ø¡Î*Cl9¿«2<>«SV j ñüžÚé]–Ædž~ß@a¡EFU‰Õ…CÔy¸maÎìÙ`ea´ê:Wœ©™Uד¯Or$ròo}Ô„ØÀhMÈ_ž$7†3B||Ÿ‡ù¯8ºø 5VÎM*Ä7Ô9Øë9;Ó,lAöm5á±#x¬C.¢ÐÓrN*ÃBül(yç¨ ìTâ·ÆHˆ]«…ø¦[ø]…|| (¬hj6>ղ˫ ^jU¸³TØV'<÷PŽNxÜlU!*|•†LU¡áþ©RyEÃ>]¥|øRQø[Z¸fQ͆ÝÝ÷±ðÉ»æÃãëã0Äí…Æ$Гµê C|¼Ý€! f¬A.,Np0`,¬œœpU­,,8ÓLcÁ³pE€›5Í–|…¼píR났‹P“ÕdܬٿVIxL¯ BèŽBOï;Õ…ˆƒwé g|¯l‹üCß.i,,hj*(Ä‚¥ÙËDmoBŒvî<Tò<Ñ &]ôÏ 9ãSIˆo¹{tá°Þ|ýñÒ¼§G—“÷&G%ï‰íª|V˜[d‡Y‹Œ½yY㯬(üÄÆ+æ$Ðx‰¼<ñ¼¸±6ÁÿÖ»P¸äQáEŸNŽ…½zdÞë¬7Íí0d›ehšäý‘oÖ‡†8 Tya¡. )'öãfÔUØœÌ|ç¨4\ð3â/­4Ü®ObŒEþÙ Òpg÷5¥!nS͘Æqˆw@êeS`Åá j ‘O9$þá,Ó‡¿aƒŒB!ácRó#…[áxò‘ž'ŠÊ÷c&- [“BYxpíãdͪ3²fçí± ±·iFB¦œ’×ôVrtÈ3jJ³Ò!OO¼¶:áËJ%!qZaXñeHÒÂýƒ‡xÂm[c‹œjðÐÑŸøÒØtÖ¹C.#÷Úœà§ÇXˆ­ÿ·Y>ñ’WrÛa,ÄÂÑ6'Ù¼5Ôœ¿=³° +‹¾çrŸ®\F…l¸` 2–:*\pjV]¼ÁÒQáÌj7,Dá³ %á„ﻂµo q¦¡$<“®pÈ5•rEc]aiTØ „éÞd{"¿ûÆ¢0ž"¬vfÇBNrËÂ`Ps¿ì Â>¶ OD_FB,ÔŒ„øn¶±fÁé K“'Í‹-³¡ÿ><†¹®Ÿn¶5Iá&ò:v|‡ƒ5Û›`ÁbºÂBQx¯S@B èéVvA!§Ã¾IUXêñßù6²µ´•„…k“ ±0â ¨aÈ8óV²"üÆr%ÙW€~‡\°±Æ¹‰ÔÎMºÆÂÙ¤U!GÍ¡f( ¯·?d^æs“û ­ ù=³ª¦.±5Aa”æP\Ï ñ¥ñ9a…8 sÒÏÜZ›Ú㊄9Ù„ƒ…ÛIÈÉJ” ?`` pðàk•SÂŒÁ·7†AÄ€a©cd‹N­ GwÙ™æD½À¯­i2·d·1‘ÊÀ _D;3Á˜•ƒxm‚ÂdÓu1pÙb9˜wÇØÉûŒ°"£)„Âãçý]^ ¸½±Õq¯„§N'wc>@ž8MÚA˜ïLØeªM^}>nÆ" \{ÞhŽ+%!ê™ýÒ$–„ç€åŽûùg£®…÷Ë~iÈúb;@X á’B\Õ “‘õƒ†ø!³Š78nÆPW£êDM†óuôçEÃèL³çìÏíƒ%óFÃC–¶8 »™1dKÿ‹†?T¶É„7÷¦£Á±}eRþäÔoƒa0cxÔ…øF´Ãÿ(ÓÑ…œÅ­,äk0w².èh 2ö/÷åq–W/Üá8 qcd(Ì“ÿVöY˜,8þTŽ1Üdˆ®4¬•p, ¬lLzð`¹„ƒ°×ʤOÜÝÌ”S! ÎUZIx<±]³þ8•…O|Єv&kÁ£‹'Jne yÀe$Ī{1ÖÇ\ƒYYÈ7?îÑ…_f_ã®ÃXÈÉÖZF/ëG“\ˆzÊ'È|ø£0Üæ8'Ì‚Bä»Á÷`Í0,tȽ^¸Àð]I* GÎÇ0-a§K»Ê„°€Âµ86 ,T„…ù`!Ýi+lJΖ®ÓÖŸZN Ͷ£ZÕ$Õø^˜ ~-¬ ĽŒ]— 0ÏH¸¾Þ_$Œ¦\>n$¬ÜGÎ%a/æUÉÄ_ãï[•LøY6V‚à %á“6;/I[ã‘m”„xcð–¥ñOŽç'×.6!ĆMQ¸¢ùžÕ„8z±špÅ}аp?8Xæ+ —uá+0- +« h¿8æ—ñ ¯—údmgëÉññ9]…ÂèʵáÙ­¡[fV‚ºíJ CÂN%a7-a&aíЮÒgb· ½1²Ûîìúp°B>JÖæ8oŒquo›lü¬",¤Àg–UniI8]YTÏ 3_–*¹ôv抉k½1~Ùƒø pÏê×¢ê½ø¹!.Œ‚ø„xŒU˜w0ˆfsiÅOê·µÆ<œQ ò‡´ƒ3Þ|´Êg˜ñB²Ó–p'†AÎßVæ;6NsâK¬dDã æêÝ?³rpâ²] þmÊÁÅf¼€¯´° A¾ Ïa‰å`\ãa›ÖÞ6s·ÆÁNDý›SðGr]8ŸNÛbü·Zq=Œ& 'v)ôø¢ .ø­-î“ò¹à(M1ÈQׯA|'ƒ|ôm‡%%³ê‚tfÎ!&ÇZ°h=÷üz)—‚q?WÞÆA¬2Ú„œõe#Büo)?“â^0Zqm8÷3».zjþþyEØkH˜$.ü±QåLÉ›5s½œƒ¹+ÆWÐ8Ø'ɉ¯¬¬ä#<å`6g=·BcÌZ7gÍ&l¯œ±{T ;ÿª/ÎNÕœòeÄ"ÍÜgð%ræ;|P˜„p}­¤Þ£ׂA/»¬Jxò¦UIÁ²ÿ‰•Ä÷ ð1ºb?~mŒK¦ …+›§ Ù‰YKB¶w¢¾æ ³Šo[uSÂ.FBükù_sßQñ…„c¼ƒÑEÉ€è_-‘_I8žO¢ï”„#v½ž^R°$d¡—nJ .ÕÜšhE¸ïIOó=W|” Pí(,q­x¶skm»ãë7úqªÂ UáÊê¬ÆX»GRa^o؉Eá’â=µNN\¼.W²Ó°²ð@®( ¹ó5 ßß [cžN) ¹$¶“'Ô¾5ÎÁïÛ˜LÃÉ¥ù.ð¼GaÈy2 CÅ6â]ˆÂ‹f?²Ë“Âk>gaîkî·uå’EëÂ}—…ø¼µÅqáÔxdi¬mŽ“–ð±q Ç%ç#P;i s–»ê¸ñB%ö=“^vò$äÅ•púÁÊB^)™ gã4wÈ, VÆYáÂú!gŠÜ( ΄¼ iŒµ›žHÎ=ì¸Ð!ãÁšÍ '$³˜äÉ6¬„Ъð!RŽ(\ЫÍtÕ¨¯RΜFÛ~a’d4çc.™–&ctã⑱weí'Çö* 9Bök‡üp9ú±P˜hΆoF!‹§¼(Œ(,Ì ñõ{OMÈ©¸FBôSR2½}m’õ„3þ>¿Ê´‹$d·n,õíq!àsÁz×Ní°Ÿ2â¯m$,8U¨PnÁ´ÿ"a¶ã‚ÙOŽûôÇÄv'a'=!ûˆØÚ¤WMØ©;F X~ ´ß( ³žpÃßÇP˜7È ~2n°0Ǿóq »/äS»;;Caδãñ¦Ûá„ÁÓ=³æxŒ# ³Í‚˜9Ðàïc¬XР㔃SZš<ºã%Ý¢=óyÉÊÓ vLhú£,LSˆŸÔoº0y¬M¸÷µH»>¢B6ÌSâLRIˆUå÷šü Úê ÿS¶AƳ’oö<Þ³bÇ…M™ß Nz( W~ËLLƒ“I3¢Áõ°ÒÀ[ƒŽÊ/úwŒ†kRWç|OÎÁ4Vbí*[“ ;]ÛSt«îvvÜ…„ü]Wi>2áƒCaŒ0y´@…¸8¸1)ÄfËúã‚U5Nïle‚à>11uUa>3ù¢ØHȪ&!á2pëö«ýqVWs`’…2JBŽ.õIa. q˜¨íñ¸$-MrÚñ!áíqŸ²°àÀ°bÑs„¼¬VöK}ïÓ!³"UdügÚÝ +ªÂBüîÙµ]Ÿ;ÖX±Ã±0§lM˜hvNê³ ~n̨zdÃ$µ&ÌcÂãÉãOhÆB Ý¶eMáÈ›;ÅàÁ~HæÐš9¸¦@»óaôäÕC4¢Ùñ±eW&llÜ>&¬Ì ;]ܱç›R¿£ß·0É"šâÂFîø‹¬ÄẰpp×G]]˜²ÊÍ+ÂÂÂý”„#÷½¦¢)Œ Ÿ\†ê˜³fÒº°;€V„'›Œ ñê(dËô¯(Ü/^V&…ùànÃå§mLB¶ç…ÂhD³#3¬$ÄYì’°bÁЫ7ήý'‡"~cEXèŽñkzãø˜'þÖ'!ÍʉnÁÐIHS¶Çs2jý¹VÉ,,V³J٪‚k?ÿåŠÂí(œ_U!ÖÄfOˆ£;mŽO|…ÜÞYz /°…œ±¤cÂmLËãJÄgA\Ýɯ‹jG!ý;·Æ„XÔ8 ;šå™¹Õ…¥Ð÷ +“ÂÄÂjÊBúGî #¹“2æ›;|ð{Q˜»ã‚Í4ñGí²'×9à#RK­^Âà î|ƒ¼-ò´÷B¤îñõàîXÓI!Û³âÔéÄ$;v²êÀtÕ?ZoœÍh8÷æÆÞ¸pmÇÙA­3Â>ZBdqôb ÄgˆWƒqm¼?9*¶c»J9ˆc;à ¢R8¸ë]VßA‹qÂVʦ„8ÝS²5Õƒ…'žÑh=x/ší§9¯± ¶µ1cîÙžׯèü…3ß׳XÕŽíJ. ùØ®ËâxÿÀA ;-ŽÙ‚U;cœ]yà{d!Ç»XEXÈ{ÙÕÓÔ„(¦Ð1!‡* 6s™…O¼è¼7ÆË!]ãóÖzc #ò,§ÂÆßas¼ý4ECš'¶ZöáZH0Yñ™}KV]a'-aŸ’ðÉ*D1ˆ›wÇ *¸ƒ†\rä[‚œ <ÿnÛ_X—ädON=U òÈ×o޹u‘£ãÅ ŠÁyá¾íW¶\yD8ò¥–„üy òϘ~ `LIX¸´ûL'~…ÁlFLVc]*B|Ó „X…Ü!;Ñ™ÿB7ýLîÈ÷¬˜Ñäî˜ÜÆBü˜Ú„0·ÇüNܰîÏ«c6ÝpËjüò g„˜õÇ,±š0‹h†é¤0|â $0\F.ІXkX„I® GÎÀñAaf!ç<Þ3³pWÇ[!×nÍAÇÝÒÞ±\y ›c | 7Ô› Ù¥¡=Í ·~b’ä„k¡.%}wœYX˜>‘Ó ±óU®×÷´b[]Èød'mëñ^ZY8¡Äa˜ýZgüf( —8+,DÛáœË+ÃN …æ-ÆyàáÊ÷õÈý kT©µÃ§õ^¦Yáʯ ›0t‚aö£Ùø¬Ã*Ãêôø¦gCš’¨pà“}£!NSÍ›+{¶ÃÎ"?¸+諹³ƒ;ü¸Z›Ìª¯Ö3ü §íx}nw±0.WüdØÞ¤ÓÚ¤‚Â^¡NøÝRbGõ]$¼ªü<-dЙN™ƒÑ­µTâTíFŒ<Å ù¬&Ä×O082NýÊ$ûr |Ý­ØWX08f·Ö •¹A~XWc ªäKÂv5™[+jz=Ì$ ?õ±¯8ÍhÖlâ¿r†Ùš°`QˆßŠ[…qZxuȸÈù¶¢ð,…3‡'6_Û±3ž…)Þnáé éz†‹B,wóL.ò`ÒÈY[=TòŽÙ`HY¸g»Ö}Ÿ³]ëãò¸0,ÐìМ¹°DWž•¤OÜçkI˜íZç!œ™l•€;¬=…œÞÌBü„ ±Â¿ÃB|ý …½'ühN.çÔ¯¿^7M u!#‚B¾SÕº°SÒga‡£ß¯Ú»P–´4hàáÝq. Ÿœñª–†¹«Ýñ´Uìh®: ¬gü¾›]+jÛg…ü§™À;<[œŒ±?ŽºBÖ² ȶ7È…þ¸Ó• Ûe˜3SîÛT…|4lEa5LAÈgàšì„#xUÓtRX³Y–’/ò´?>ð´ 2~;­A.lM|ÒZQÈvåg‚øÒ¢p{âI­$ø®'R^I8ÅÔãíãHÆÕ?7ȹ*ä0¹;×§&[!æŽ/½Cî³5Á÷ÊPˆ‹©[ùïÑÅ¿þ°^9w`˜õ4n÷nD~æªpE£V…øÉP®\üñšNYˆÏZk ,œ Ê‚‡%ØiÇÂÑÚcìiµ&¼þ-gèíñÀ¡ .,Ì%!¾¶0áS+ 3Y ÜÇ_Û¯@×ǾÂ.!w32×AØ«&ŒwÓG¯’° ÙÙR ¸¡¿^ë™ÉÃA5C°àß_¨Yr£7f÷AÃ`>ºcs~X#* ƒø95âÚãnÚs¬•„Oª÷£Ár׿„gmðYTÈŽÓFB|ìÐ$ø?@¸%õíh²Œfá%k;qÂõ®‚°à[=vsðïBÂ'g낽t}œ—ÇüUâ°ÈT4…Ýüû+$LŠÂ‡X)xµþêT !Ç”Øö¸pkr ÀXKƒKs) 瑇¼$ÄJÖH˜²>n޳¤pÀ¤mLp^í5aDáöYd½Ba´£á=†±'Xí,Ƴ°Û 0†Ào'V¾¯9ÙkFiÈÚöî˜Â‡Ø¼(±øVâ˜ë]…a‡xÓc…aáÚ„7Ÿ‚ÃùÄwÝ5……èc޵ž£…ítp$‡uÈx%cŸøÙ¬ÏDíô.‹i&œË*?õ‹¯p˜U…¸v2² G3+·wøQ½ƒCV‡Ii8|à›õ}8Äõ¹Áã£ô ,ÌŸ)”„S…„l,ö…„?п£%!‚Å%…¹"äÉš€pÙæ×ð×ÿ‰Ûã Ÿ7Vr/ÕZòøî]‡&lp& \x†ü}$äƒÝš”BàÓ¸ð±ÐÀï²­NÒ ò\Ù³÷ß{NGü<{öq¸º{Ð7KVâ¬Ô†xào«“(°¾žê†çÉF„^f}õ’"M~–À$îO¬^loÂæ‘º7IGw‘Þœ¦…Ct¦)Dš¬l[ÙgÉ=ºzEš`j,Ä/ò÷lN(Ì;ä±$¯.°àÅ»ã¹àÐû-:šÂí1ßB[ìqb {êØŠã$KuB’*|¿"ðú¢O…Èãqá# 3),Ü˜Ìøk›a+_É g6üÂÀ'§`ÚïÁ¿«¤Ûá·Á—Ç]RF¼2töZsÇñS¿Ëã>åàŠÓ~++ ħ°0p/¬K6”Ã)±g³a§(¬-¬d3C3ðÏæ\¸Z7o®¬&œ°·1®¸„µ|»(¢9í5D ‰BlLNˆƒ|á†óZw®ÎÖ\|y¥$\Ò±]Ž·cƒaŸL§ Kà7WHTáÌßV ²W­MñaÒ>"d+d!Ž#„øÔ×áÖIV½²hZI˜uÕ§Óî\Í{†ÂBøûtâÛ¥(d©…+׿žê„Ò`sñ/8WÏØµ) |N q]iE!ÖßÊÂÏûöW0ŒŠÂ?†.£éÒϸzScÌîC¼õù>â·ÝBºDïOovo—:ã©`â¿oØÞÜ`!¾Ö,[y«0Äa›³°hRˆŸy¡ô……ÏÍ»†Ó…§ÀpùC/0|â¶ã§ÇÉ…á±êÈêê? Cì–„…ë–YWÇŽk…}òß§ {I “ñÉûm0 æ\3¾_í0äp[« qAø•†#CUiÈ’ð;-raa‚–•†¨å²”»’MaŽl椥!îzà'nòee²Ï(òq!~è-ú«^‡a^™p6ŠU†Èyï’3 ç3Ýš Ñ“fÇßÅ…}hˆS§a¯6Û« œX“‹…œÂfgwØr¶ê w<7t¦yb‡PÓÑts¯Îea„k* ‹ÑÊíqÅ‘†omqÂÖIº8ÁÚÉvÇ+—Ožî„?d’B¬}LRˆ¯£9ùs££$Œäfí?c¨ŸrpýiŽò¾CÏLX™Ð¼;Æ9Ž‘0s° ¡éeÁ ÂBsŒR›¢]©ég “ÂÝX¬;±@Órð(lM†³rp·}à‡Ð¶&X}Ú… Nµ9f~£ 4lR˜o×%„;­…¼Ïßwã kåÛ9XIwꥫÎõàÈ÷ÝßäQø!/‡„øµh¯qqg£Bœ/( qs®(ì”s‡¿° 3 q³`"ü»MYÍ]os´Ó<àÉ–& „ûy£¢£)˜Ñ,øáQ²…‡}c\ž[cŒ¥·j çTæ¬O> ±¶ß}{M £Wë6ð'ìÛêÁ'ÁàÙ©1fi«˜púÀO•„¸ñ~G![±YoœÜZþ} (¬Wã:Äzcjo|b`&þ'?Ý~unWè+U!v¬Ös&£ «ù\»cüáÕß½V®…d§·„FÃ.Eáˆãuöba. ñPóû$…¦#,œùh¶Ý›‹ß-+ Ó¾dú`[O- û,qnÐhÖzqkÝ•ä,“'Ò«9†A.QMQÈS ®Cas<<)/mY‚ « ñݰš°àß?¡ôÉjBœDkM8„û’ ƒQF³ããÏ0ˆÓ½Çv¿åw¬6%üÁD…¹*¼þªJs\p)Ì D<©¤'a~i÷[pÁ©W„Á‰æÂÂÕ1®2ÛE4ÓŒ¸´‚°0&\w~(¹/ö JBvdk½:Þù¡cõ ¾ÔBüŒ)§éõÕñÂhËud«Ö™·îí ,8µâWø–ùB. g1ß¡?(Kn­…µq¡"Ä]’‚0ïŽ ¹AÂBªÓ“³d›F¢.ßÖÆ<0.XïøÂ§{6%ħ€ª ×å;ZUü‘wiu, óÎøä¶Ûá%…K ãÉúùï¼â`ôã:päaŸ#“ŠUk¿“”x|Õƒø }—ì½0׎LèO·ÎqÐjÈ5Ul«;µÆxg`!Û¹¶bán{ãBÌ猫¿0Á½ƒbe¦žyr<â&…½ñ‚¿·Å|â3Òt„•Ö?ª¶7F…­p·ØGUõŽZŸöÙÓ+ó®˜ÏŠóÂÅAŽ{Tò¨ß9ˆueó„0ÖƒEõÇüoÁ + µ/F( KãS(Œƒ8ýóÆW.¦"Œ—v§|jùÚ8O'¬† ƒ¸3W r„`«|æ!§¦ßÙ¶Æ!Ãd-„9íXt 'î´n\WrízuÆxf1Vß·+Yp6£$䫇öŠpC’»q¥ì÷‘­¤ …}:cü…mY£ß,Œë’ƒ½;”…;ÃkÂlM8ñ5šÖ„‡ëÖø(Ô„ÃÁã~Ïs*ôÆ8Ãòü°ZMXØ#tkœ×%c¶ãŠ,|r§Ø~tŒ?c,ÄÆ î¼®ýR>»°ð ç”…% M¡*ä)—°pÁßYYˆÚ3䢚掖0Khpf,ÄÞWëBÜð ñ¯º³/‰1&çÀ‰2BÂédQ_ã~ÐbL8ŽA¯ìP¬ceaɘ0ïKP ÂåLë’1šr8ƒ,‰2âÐ\¹ š^Ùv;~mNˆïçw‘ð8ð×1²½Góu ÷Ù>' ›ããd¿6›v²&Äq‘’s–lPˆï„–…Øþ ö„¹?žG„·Ý—äŒÏu˜Y-àWvø"z´]6îçgŽ÷Œh Ÿ|§)$’CëZÈø¶øée÷%8M4"ÄÚc>Ÿø‡›iu\›LŸ¿ó+Æíñ‰/ ÁÃkšaÈÏÉ75Ȩf£B|³¾­AÞQ2g rŸª°°4YøÚU`ˆóFó'ìdZå„ËsKe! ˆ”…ˆ E! I¬,ä8HmYthö„lþ…Óqý[ô/iƒ¼| VlƒŒÓKk Ÿ(.h09py÷…„WQ³çrö㱑J7HX‰øÄÌ{‚í†4X»CB|Ô6£°pbÂ)–ÎB$ª°]—Ü«5Ä¿g!ÅdÇOò-M¬ —­w¼d †ë9…áR8¸ãleKs:p¦¦jš•÷W_a8#Oç¾Âp¼Þ2ü† YÆá–\ɶú}Èkä®Â;ÂÂ}9_[ø_,Œ^4;~·Œ…¬mg!µßuo‡_Ac!¶BwXˆgíÍ,œù³#0œØ†µÙªuÁ²Ã0¨iŽ“ÅÃ>áï;`0Di†­Ñ¦HaÈ'òÃ|i2àËšdþhØ9^šŒà5ä³Âp/^_ç¼:I~4ëÇ^( 98ÆXˆw…á'\^À°ô™-F@Ý€aAa/ß­Ûã‚! Ž*¾­Cf¿¡§ÑÍ—Çøup†\r6®€ðìdG³g-Íõ±Èeažîlt¡ \±J5†B‹q'iUáÈlA!óü …ѨpÜOÞÚ¬GK†Bļ¢pG¤ ñh(Dù³¢p[Òé]NûÜP×l(äðC!þŒÊ¬ñ3ö¦ö˜Ç=p×)ú¸O ÉñÄïW½ q˜ÚîÈ0ãÀÚiV'çãt:Ò«¬0ÄWGi¸c¨œÑm¡´IŽ0ÄÄˬ²glGµCf™±©ifÊhYxðYYÈÇ=Ö!cco{,¡lo‚Jbc!V5ÊÂ5°pùiŠ{“;qÏ4)d}¢»õâdÃù žø3.ü}_Q¸£öÂÖ&•u„Xd)yŒeea^›àÃíqªd ÌÖ4| oeaäàÊ1žõ™W&ÃÊVrRN(\Ñ¢ðq–•4Ó>M¬?i&?s0]›,,´šÊÁ'·ÊÁÏ;ÛWŒv K¾6™øaã,œÞáßä$ìz|ò—K¯Mð¡õ$äcYãïÓÞ WPx°7”:ùçwJ߆Âc…;n"]Uf…OVü, 71øŠÂá¼¾_1æŽû å ¯z„¬›Sò}±‚p»ãí!ñÌ üåxã£ÛdÙ˜­„ø79;Í ñÛgì6&ì‚ÁƒÛ^mQ*ycNˆßb-±Æ·`§Üc]tƒ‚…Æ j£ ¶™JANˆ·Ö¸`ã?ð¼H0Ȧ‘ŠÁ·dŠÁåzד-͸o|¶¡$ä“0#!–ŸJÂÃ?Œ„©3Þ>³wƱ"Œ"šñÚB.B „½8È;9vËuêSnøm÷‚°phR a–Ñìø…& \¡ÝÁ`^—` nd)¯ƒX•§.&ÌÅ ¾ßFAlZ”‚ëÀî¹JÁ…\FÁtaò ~%œ‚‚8‚¶r0÷ÅW ûzm¼RøÄË)اdôwM15Óãí~(†«+¥ Î=Û„œ×kóÁ´(Yø¼Ë̹ú\W8¸a»ö„3Ÿ*+6þk!ßn`Ïw!ëG„×§"i ¯®xc5“€p{b½¬ äËá‚ÔWΣ¡$ÜXÛ)$äÇ’pY~ù²¿"ataà«UóãïÆ„0 hX½p‡„>K¬5îvzܧ"<ð2 MaB˜ùá¦(ä†ì ׂ‚†ÿ¤÷hâ}É£èÎ%a!Ø©Ôs>îW|ø¯$\qŽfñ“30%aÅÃå~ÞHˆã%á–î$ÄU›’0ªg~Ÿ–ðŠƒÑaƯpp-90T8Hÿ)/égîa0Qpû±òíŽÁ­cöo¯Ÿ¸Ë+£’pç³#›öÁ`ᾄ;Vòp^[ã‚’påX !Ûü Ÿ|N„;¶ ÂídE†öÆcES=áK¤ \ñó£ dI{sÌM¢ p>Roœƒ $ä\¬v²«™“><·Zãì¿°ppß÷¡íù›í*Ç%X¬¨ˆK -óuÉ1vÊuª4Ç~‡ …••q¶(\ YŸñÒîi®»‘0ʇó\xޝ%á“7Þw%¹"ÄÑ€‚pf)X3W\˜+·ý¾Rx8êÇ ›( ±/1¢ÕÊ-Fn¬œý6çjö#µÎ˜¦µ5f¼’KT•ÎîP1Û Ây(x/X„(w¾fPâxÏšãÌAÖÞ G|Ú(ùßQá°òüÊ[ã|oÌ ½„ø:+ùNØ:c| ØŒ› í§9r0Ù Xã߸,áѰp¿YÎÁNŽ\gÎ<¾·^Íq§¬Oî&̰KsŒSzë±–Sõ ùB|BÞ a¡;>QH§$\ñŽÚ¦„ù NõÌŽÃ …׋Sgva‘’ðx4ÇyJ8}ð3û+ —™¯…ìÊ.5ǹ4¶/µÊÂgsÆÂåµ÷ÂRðï³~f~ržÚÌÂW`ïbá˜ÏìVN¹ù>NXA Kž\…ëþ¢Ú¨¥¼‚C|ø[͉í8 ÆÕ~Ù ‡øÌQ²ñµÈÙŒfæt:åáÈîq_yxµÚ…ýñÈ“åá“O½ò.¤ 8|hNriÈ·¥ŠCžkÛÚd~m\½Lüy–c8äð‹vV*ÃNGÇ|èc³Büæ|c¶SDáÌ›•öë|T4êª~ðYH3áó¶…SáäøD]†¡· †BÂ…+i2³f;³®zæÍІÇÁÚXáºòKA¸ A“ÚáWÙ Ã|iÇÙE ¡Ð#ÏëkÓê¥àà?àï{§.̳B¸Ž¦×ÚçÃÖ#w‹€ïS²á¹ pãpäf§Vü$»Ž&‘ðøÀ?Êzä>Úê™uQ|Œò#aö­.…ìYf,Äɤ²0;Ñ\|\›ÌÆxb²®… ø…;E!O# ……½ çZŒ}´³0ii†xu<æ4“™•wÍî ¨»0â]íS»¬(|SýmE!;¬ª¶šm»Ú ü '&ø¦+ ñ5VâçâcEÈù¤ŠÁ‹Å`6_ØxhŽ\yT˜½û—}¦'< Ö„ÛÀ»¥ ßþYAOLc䬬Ƨ± «£ p>ã‰É/Ž9“Ý–Ç(l‡`¡1ƃ„vîÀÿ5àñª‹oƒ ' Þ°«.@0ïŽwTÓl»\â×óãêxc†Éü$ÚÝmˆ;y\Èùd¿3Yo¨o7]uay|l<åQ9á„ç•v`‚ +Ñ®K1ÈÂM¿7ÎÅà‰`±b0/×þ ?=ÆAnš9ˆúŸöé‹wn‘~daõɾÊÁÛ¨vßþçNÂlwU!„Lfœ˜ q‚o"T%ÚêÛY%á‰SD#aœìܧ YÍ$ \.c„3¾_¦¢ÁjØâK°xRâx´]Lxâ{¡üôW{ÅÁxr<áÉMû»X®x‹îìuq\ˆµ[x¿úm äÌHaéÀ¤ÂÁ‚{á ñG „}Ô„¼/7â«c ÌŸ&9ÑG9È}”4Æ…UÉòäÎø˜ùˆNA¸~`±«ñ™œª$L‡vÓõäÊžý>jÕ”q¬3N+ãlÙÏx÷$ì2\ ñž¼L¹BüݦúÇŽùÞøzøõI/)¨ ùZã+ŸÈ1„O”L7*B\‚(ñŸQrßkÂB”ÉÌ…+T]”ðV7%žŽØÒødc4?µË7Ç ÎŽMLG„×KTp%\pÂàf\YL8ÿò·?EáüÓ\PÏìY9·¹&¬xquÓbmû{éªqª¤(|j(Ì&|f(L½ñöE!ç"µ£?„†B^¹z¦ «Æg¤…lC­7&X›°:wÇ󓜆«Ñd D»/áRp_à@wEá×3¶-Á*ÞœªóÑqtäºPXÐÏ’Ž»tÇì0ãê™nŽýÖ^ ìÂAž×ZIÈ›fI5>fmFˆ/àW®|˯ÄÚüFEˆßåàÄFÖÊA¬—­$,rñ~ßJÂlC³X˜x&¹T_ÕÌõO% O¹liŒ‰- ÊÜ’9sAxbû¬œÃÅñüÓ½xîid¿ÝV ²«£c°—œzijIg~¨e ÌÆA¶½l=8®–°õ‰”ƒØ²)±Ë¼1"ÌÕà„„S ÎøVY5˜³Þw¬ƒ=·$ œF*Ù÷ÞŒ†ü¯y_Œss¿²ËYv'>þ”ƒÇi1ù¨?+²R]ª?s^q0:/pínÄbÚ³ìðg„8ötö²ãÂy®mqîô}1gÞ¨ššÏ–šg„ØØ¸Ak¸8>6nÁ•„¬Í½Â¼,™ ­+~.L?Sh‹ þ¬„'~¸„;j-„‡_¼*¹êÁ[²à?cM1}º¬'Î{’'ç=Z â5¶ƒÇkgÖ¹ÝÄæåÂÀ'>àí ÄFìMµ xÚ¾³ßV ²ÁŠ gúlIبѩÿB`ö¨>ñM‚°pXÇ2t% >…Y@—ÅÛRè‡Yà«+’}ã1ˆ«f° ¶ V§žÜ”¢<¯¿¿V æJðÀ–BpÜ^ËçìÔ?ž8,ðŽ¸°"á{­ ìUÆ£º'™ ßW²·ŠB°’h\جì Ä¤îŠq”® ìâÊZ©GüÂXC\ˆmbï|ÛgS֙݃cÞO~,´¼¾øÉp5_ŠÁ©0\1ÑR1È’!Ã`î‡ñim¥à”ÅSÖÌ`uaät‹f nøåsvsÁªf~ Rð8ÐðÂJA^%7û,Y±ï¾±%îBÁ™7ÀzQWð!|2‰R "N현#â7÷Ój¯uYŒ/¢+ñ¿fÅ Îᔂ#þõ&˜Á¿Þ3ƒ›×ŒÁÏHöWŒæ[C¥dÏ5Ã`aMü¶Ä<ÂÕ©àU Ž…K’ëE+QįKâB†'Û!ëL°°Á‰ü ± >#”ƒOJF ¢›‘m‰±2°r'@_—9È')&Ì ~|7„¨Ž3µ ŠÌÍš_j!B×fƒ<¡°`÷¸(ÞŽ`73b›ØÊÁHÈüÍ$\ñBæ]ç$ؘŠk÷ï3éçK¤öÆ?‚Z²•šÁ0¸ô?3¹3ÆQR; ñŸ±Î8Ï,’ŒÂÂt „9Ö}gçe=&™°QÁÌEBü­Uf›>ÿ1bÙ¨×$/¦Ç$øœTŽx”¢ ü¬Ÿ^0êG\ú¦¸pM‚•ˆk¨ ì„At  >}_gÌþf@Ø¥$äFÓ÷Ä©5^pàëìS®Ù¢}b^­¬8±fûÁÒqqN4Þù³cv3±"Çù!-‰Ü+‰Æž)ãžäÁÁ‚I\”\! „ŸÓƒ ³éþw „ø¤uâÛ® ,yö’ÌD×­õä=ø÷åxÎ8=0ò"Î`˜-g°÷’0iff–¬™ˆºÓ]; 3 9ªÙÆ„X†˜õ_Ýë˜0ßÕí|Ÿ§0,xΌ˓á“Êffþ2›é võ à ¿;fKÍÉ:vbœa¸tÔËk‹…Ñ{«0'œx.ÞÎBn·Þ&Ì:ê±ße]Ÿö… ¦äDœf²nò›ðåQæXã“÷§7†……X«ù]]A<“õƒ3ö‡¾7N ÜØ׿„ø´îxçÄ]¿ªÃï„vǸ|7Æ„¨F±î8›o­ã/ß­W Œæ[ìµã “ʘ°ÂJrS¯»:¶¿NX¥~_ŒÕ“™Î”v&ø3* a•¯rßSmstÓ‰•Á M¡&±G´Ý1Ê”„¬¬UNì@ÒÝ´ñ¶+  ‡óÜ+ òÄÚF[™°:^Xȹìʹ¢ ‰ùî ÑôCÍ>—_±0+ qs‡…Ù¡ŸMàÞl|pœ‚íL˜ßweœÕ®Š×B¡ LV OÅ „}8Xpç_8ËÄ44Ù­"Äcæö ’1'ØM––ÊÁu.¸ó?NI³’ù¥Ü 7Æ#ÖÆAüSTgcêuXÒÆ$¦yŽ'ŠÍÝi¡"¢ÉÄ—Ï0Ø«3ΙÆãnÍ¿ñ²g¶9>*cÂ.ž3þ§tsŒT¶1!>Žn¤×v&¹5fõ‡„ÍÄv2JÂ|Z²²ï²’p§%WÑ4²Å ’ðäÞHˆ#,%!û+ ‡‚ç̂՞©ªómÉò9C~E´;O\¹ªºRæ‚°0$ÄGíz—в0¹~¡IBs…ÝñYQUW@ˆ«#!–4¶0ÉÛcÞ»¼å¼¤j\H®ãñ²ë^âÏ(³÷V „ãÌöñžïŽævB”ñßqâGU@8ãÃVA鱯 Â}Lû’!ÙÎŒØú¥qÆ o—OìVDÊ òë+w~:~ÛˆoÚÔsfâ`Äf ‹‹ ƒqo<ñªò a00ødþ§ž¸ñtf]5·J±pfÇi/NÂܳ§»…•œì›¬CÂG"B|V(ùðÛ®ìøN@A÷ÆÛ“d›n©7’ïÌȇFBü4·£/É †ø¸UâMh¸â½ì÷íKØSF`ˆªŒ,äÞNXÈJÊBüŽ* Yäw£$Œºê……SîºI˜‡„?J”ƒ,Srʧr0‡×=ìX ­ñÅAl3½"Ì­ñŒo—€0·ÅË…¿Â¶4ž“ñLŒï¼  ú‡Ò•]¥,œÙñ7ï=áÊØâº™‚Üù)kÌY% ߀iIˆ½Ö î•ôº“ÝoŠu/¤x.8‰âoca4èŸ7œòã™Ýć¿š¢ÜNã™æºu„“~fø88‰QQ˜3<ñ­0F®á9äȦ‘ÛAÈÎè~\Òéº$/Œ×åk«ï“T…ruéÂìKͦ«a¾9FÛºw˜p->ÖMGˆÂGÅàŽka–TϼmÒµ1›ðš%+~»…±o¾8 qáàøàS SÏ`oJÂB¦û†.íŒ_¦¨¯X˜hÒˆðúfaãw…øÒ¼KHX !þÎßÖódJA¸á ÛA˜9XϰŽW0˜Œ©¯¶çü70ˆ¯r‰kÌâ™?[FAü ¹wV a3ž'|uÌžÿjÛâ|ðáRS `„àP®¬hõ"Ür=86¯˜ìgF¾šltÖÁŠ)5~Éï0UÁ™O/¿­Ü9Ä(ÈÏØ6 >ü~3SJÉþD`ÃÁN7%èk,Dx.(PféÌÊ÷ ÊA^«Z_\Ø/ø@7!Gî“ ú¯)Gl°„_j~Ûƒœ£ðA«,ôÅÉ|f<ÿÆA6–iæà„WÂNn„GÌt_ŸÈ(¾m@¸s;¦ \Jg%„,t²ù`PÎìO.–meܧ-³×·MBöÕ¾WZü‰×ŠÝJ¤"ä8%áŽ3;Ë­{X˜F²‘®oŒ£tf?ñYa}qÁžzæ­•£†pÞÖ×}ñ”“JFd y.Ü^1ÞcP½³±‡•„½îëúðÉñœ’° žáŸÑƸr_‡ï…’°Pb]ÔN¡Prü²YT£ÃJ‚ŠpȱîóŠx­ ü`( Ù­RI8,l¯$œÙ5ÀŠB› ùó¬‡%…ð:¶±6â°¢0“0®Ü0 ÷R®{…„ù®¤ßÖ˜‹aá„ÕÓ÷¡í:”„+®¼*™PHî2´*9>ð7v²Ÿ)ÌÙܡ٬-ˆgž8Ë(£çÂ:³…ðW^}[Ú” ç²r™!\Ž;V¸w7ÎJx)eD"qŒ*œÎýµšz*D–1Êx~2¿ÂÂÖ¸_wœ‚›."à¿kW²³_õÔ] BÏøÆ8dx^Lçu9 íFEXqë/ôÆ\¥YoŒU¬0gÏþ§$ܲ7ë4ó[!Û’uáo—’ðäÃJ«ñ0ÎHˆŸ2ó$Ä‘¤5ÇØ•Ù©qN°›Ž×î3SN-yò¼1âKÓBö\OsüdÁoÝ1v ßW,–±ÏÚ˜Û6USsš¸¬9ðÌXا"ÌyÆR× soÌо7.€¿62$œØJ]‡„1½i®ÇR>°»h™×Æ…«üÖh=¸³‹°.œY õà§©ø+ Ƶq.+5ƒ¯~|`¿Ç£ú‰ß¥RWËߨ",䖰⺹$\pâæG%Ƀkà@Å _ ßéŒ ­qÁ¥š- MMl—ffó™ÛgÆ8ãÇ] ?Ó}Y‚xò‚0«Ù”ÂZcþ<Û¡q pÚ®þ9Ž§Ï¯û+æÍ1¾€7bK (\ðõsÒÏÜba”Ð<ì„~$î;‡’¨ »  sp §ø5^Øí×3;ׄì…z£?.£Ì¹]RÍ‘‹ÆBc* ‘b&¢Á¼‰h ÇÆÓ^pâZŸx3Øu ¯Á´=ÆB¢ÝuáG“Òg¥ág:Â+fÿìpnøÏThHÿÌ›2œ,Y †øQý>nwV¶Cpb›­0,Ä—°æ÷+ Wž] ;yq ø§[‹œg…[y_wüV yÿÞ:+܆‚óËl̓fa³ao‘q×cB¬¯†.ï†' ˆh„¡0ÌâêñÜ_[/L9¿d<°B°.¹´>În\sETˆô-u5¶JÃjk²±e‚†¸6f3®¹Ð$s Q3 »Œ ¯—/ÚU2Žqµn ÄŸñª0ÚíXñ™Œ›D့úí¹°lÚAˆLµûh!JdLQÈùæJX¸2A@Óö8f—ŒlRàf\•¢°ÂÁŒAü«o…Üx|åàÀ-Å7V……œc”·wȨ‘ñ¥IjWNKrrú Ff5á“H]Å`¡9F¥‰QFA$®Q?ÆJÁyc[¿0áÕž‰ so¼á›nbÂBœÝ‚ H3¡A¼[o|Är0%—Œ'¾€wŽ ¬¸õcMt«ü-1Ø…‚x¾eavsÖÂÒ„ß Ã vŠA¬ ƒÜhÝhñj$Äõž óö˜=SýƤ°>fû&²ìUu4¼¿Ò“‘ß …á“økwãÊçv+Nµ­$äa®M8iUu4øï( ÷r<¢K ñõsæc¾3â7ù=Ž\#×ßWòtØpX¹·ËâjÞæ; ÓÁÝ“bÄhØGIS²Ë²Á0k«qi`Ý1š) Y€&(ä¨ C!¢ÙPx°ÜÍw&hñÛ¾3ÙbÜû#7¸‚¼3aŸ[=2ùŒÿ~…¨)<ð¼ãКí|²¿ …1ñ}¹aÿ¶ºðd%!Þ¿7K y©k$D‡‘0×…ø#w4…yc2±ÞFI¸b¿~CLÃc@k’s€ oʆSáÒä‚!þ”ºÑŒ¥2þJV|û§‚CÅ·ÇfQa¸ì†yý ‹+“ÌBp¼…qeò ØUºä©‹!ÍÏÈ óÒc]šôÊrâo–ÅÚêBžž +jš‚s?þéº?ž ŽÕ,ÿ5g®ƒ…²Z¼Q3k.ì[……ý1[Ï»UkaŒÍ‡™ÒìILSÈ0ÁݺÇÚUö&†|ù®ý1ÛÛÀð‡‚á““iƒ!*\Ú'Œ£!>½”†(5—ÂN4\±WT®3Λó‘a„áT98aU®ÐoÊ•†Ü3ØåÝö|ÖÊpah¥a¡0Üñ…VòcÇÜZtzrÂÝY1D1M!Ǥ’uÌÜñ¹àÀÕ·Èô=¾•cRÐYÿXV…ÇÄ»áÎBþæýI¥2Ä—ç+ —˜m÷`a§3ä'œ¬ ÷‚CÖ é”›äƒÅ‡z{Ç[>½½ÃÁ­p;ù"Ü{d|Ü ©¾HÎÃ=Ö…|)(\°ól»dKSH3A< Ù|ÒP˜IX!þ3·6'©E^΋ƒ|c¥ãBœuµc°Râ?£%!˜¼Åã;‚øòYA˜»cŽÿn7®.¬7>5µö8¦¾Ã0 ÎÑWÈødS î•2¶Ùí!{ÑZEˆßck×ty³LÆ»HÁàĦ>†A^©™wua…Ü­"D‰žµÇÝö&½®ãâdâyÆ E ômX˜……8ê1vò§GYx*ƒ㠆‘…£ÂåÃe‚³æ÷Ì6*ÜøÄÈwȸû5r™ok“”ê4}ŒøÙpæ’“\l‡<¥µI!Ë¿ÆÂ™KêvòÚÉ÷&R>w¬©­;ÆëÛÒL $ÄûS“Jo\( ñ7§Bìøo0Þš<±üJÂåcÀÅŠ‘>FB–¨koŒ·:BÂ}â[y‰3YñÍNøÈJÌ'>³¿‚peŸ á‚áŒóa!q„œ‹â ŒEar¦¹@íæRÀ]„8áz“ÈšE]V"W¾ „cv¯žž47nM*5!~EMÃZz€ŒÏÑ(Ì$Œb𠣯šÏ}„Øhº®0Ö„û”ûã™í;•„Çŧo7Ä£»u¿ÌJÂô9=qTr`‚M s²Ó-ºb¢É4`#àÝ1îBÚ»c´¼}SEXH4?P[÷} da´€pæW»- Bö~a¦ N‚î´Æ±7ÞF^.+cAXÂ`åÒË&Åà‚ðR ²sÛ¯0ˆß-<Æ:V98st«nK¢¢pz™c!‹ÝuLˆí¼‚ð³ Âñ§9‚Ï „(Ühá‚ü7â¿sëü¸b^Ýˬ°Okœ'6]yÏõ1ç쪢0';á“öÆÚê„É…áâ`¾¹»êÊBk\èŒcªÓ¾åà÷™“ „ƒóz²Ý“rðàI†rsŒƒxóó•ƒõMƒ8ʰ!~Eukü)>{ÅÁ¤¬ž|l¹š×^" ÞÅAƒ¹9=Ù¾q_ÂZT!!ßÜ aÎ<έñZ9¹›: ómŒ±מÃ(&Ü*g&ìLmSÂÜÏ<Ëîøï( ßÓ¸/Ù'¾QVâÛnbB<§S½c½q® ù¨\Y8¿Nûs®Ó4faõÄëù;½1}A…½*ÂBkŒ"îo«§œõ9­ØµßW8È_?UUg Ö`70˜)8JÂ_cÅ [Sù®X8Èþ%_1x°í«`pYP§$\Æë›L/`ðj ñ‹£Ü ½1Oª•ƒ;ª ƒÉ»zD_E ®aFxq0)h¦)¦_ŽºQ4èkö.)!þñߨ©ÆúÜHˆg 7*ÂBœIààò¬öÉ<Þ å n`•ƒSö­æsF»-ÉRÂeÄ&S9¸c}&\œñ(·“Ï•ƒ;7ÐÊÁ£ ŸáEäW>rG³¢š„vmÂíõ¥ÝÂdÍ5M(µwÛê>Ë’ÒŒ°›‰?j„ǾßB|}ìЮäáŸ4l¢ \ð­%!Nò…øH¿Âõ¹±=¨²Ýn…ô q§)·ÆoWoèg DÜ!ŸµÛqÉ%ŸYð¼É@ˆ¿ò“ÂÌAÜ×)±EzK¾]¼6¾è•’LVû³žzæ$… Rž¼Ð ²¦J(¸-O¾ZŠÁÏõ <ñM·T'Ä—b° áÚó+ÄÚxpx-"sÊçÁ‚ MÅ‘«A&Ü›âí"×áÇ"`Ás¡KC¼ âÅ Áì?ƒ3n BÚ ¸gÿ™«,0+ƒ`ÞO¼ V¢æQKAÖ3*'\N+‡‘}¢¾Bp–‚1!‡\{ÔqDà‰ŠÖJðq¦+Á9Ïóºo3=ò½Â@+¹vÝÎŒ+®ý?’+áñ$šDÏŒ; ©Ù,×fƒ8 Ñé ÷Oº%ékÇ“y%!õÚž$'˜lØéû©q”R³/˜m‹ñÑf7%é̱²Ž¯¦ßw;*ÁÿœÓ¡ñŒ7ü¦›áCG;­Ë¶ýëœôƒcrẞ5Éma~’¢ÚBÞþ¿k6¸çÌ÷‘;­¹"œyÓtÃ…« D‘¡­I™70ˆ›`¥ ê\‚¨YS âîÌ-¸rAød•¢RjD®]”àÇÂT3yWüd®`÷$…0;(7üò£1ëÃF8ºTOëöÚtæÂ`òßšØk× û þ[ Øðúd°—|wLf×Ëw¦ W§'NŽmNöä¼rmŒ9i\(ˆ»!à ½70XØàßíËâŒAìè\3½–‘ϰ„‚WE3Û"\§‰;^m‹'…›v‰ê%„Á438¶ Î{͈pM»â˜êyÕƒòsÍ@ˆÏGa¥ì¶"Y+9Nø_ûF¯…‚_)È)“¯æZ—$ ï›_'®ÊˆpA…€±K9+ ±ŠõëºlExfáUæÖxÃ…»®‹ç•ϵ5^ØDʪÂBÆ1V”† [ƒ( ‘.JÃ5³–ã´$)uÌöœF½‡†;~4Œ†Ø-Ü¢!~XÝ…«SÎàoHgðg¼0¬8ög5õÂ1 ŠC,B ‡ÙqŸþwp˜·Æ|†m8,lLXsm8Ä¡ ³eÿ¾ãFÀŽìxd+8Ü7Ö¸i“|~à’Âó‘.ß­IÆÙ›ë©ÓÝãZ=ÓpÝÓ]ŒršÜ· ‹Ý¨ ³ç›ÁÝ!~I…ÈŒïó\à¶Bw&(ܸáÍZè‘Q¿¥$dOó#ìTvÇXéÛî¸0*Ì"B¶cÒªeiŠÁ1{õÏ3þ:æ¹pu¿yVxß×;{Ç`æ [¢ùÎ${ÏlyX8‡pÏ ƒÑ„kDÄ w ºSVD„¿Ý}ÝÀwƒßtÌAk W%… 'ö—4 M*èŽÄ&éM.ƒ<õYaX5YA˜/Kv.­Ì}&ØÍËYÈöÜOŽö¶z‡²Büë„l’q„Ùtá÷Ò+f®˜í9?ÉɺB¼ìµŠ ê[N©"|ö鹃BÔëß}Ïk“§ãíÃÂʬ0Æ?qµºqX‚o–®M ö3î,…Ø*4ïMØÐØPÈÇ'‚¨Ìs~Ú/O2x|Œµ¬ ±6bç¦,\ñœÑMrsœIxL±5.è Ӊݣ5®œØZãÌAü$¿Ë«ÿ‡²êß9uC1ˆ’öƸë¹D ÍÌ[_0ø˜wW0ˆWáŠÁÝ´q†Ÿ×Er0LóÂdaû1Órã¢Z„pØxÊ£\*Z ×ý¶0Á„Q°pjÌ66"Ä-¡­cEC='î]¬7.y.TÖÇÙ{fÅFó a7®.$äjØšã>v8âRFë™™¿WÊAÜáßà`AEóÄ–A@X茑;nFX8.aëV]ç;c>æS NkÁ¦ÿ¸¾¤ùÀŽOÍ ƒXcXcŒóeÃ`Z¬c6—þ3ƒ1ºiâ=¥ØqîB3+V„XµßêŠ+&ý?X†]ö[˜GÜkÝÈòäœIå 'éÎ8sãÙ „½ª ,ÌÙ‰WAÈN  B¬aMOÈ¡f¸€¯²öÅ…¶Ö*'D¤¨|æ`se›r…¯ZB¼Uƒ(T ž…žxÁ2W/—%Ù- Ñx&Ï—ƽ@X !ý§ÞBüÖ|[1xfGÖyª,Œ Ú®œ\UÞ7! ƒ'vò†Aü z=ó<++㉮tgÌ1ŠAìB›-Y×s-øSŸ36ÌŸŸµžjœœg®ïŸÆ ³çNDŒ„ÑžzˆÆ3N3„%OVüd( +Kc|’ÜB!V+a×IHØ©(œ9[g„|ÐÞCÄOûÅ1VXÃJwœaÈ‡Ë ÃÏ­&ÄWÙ…„Ù zÂÇh˜Ãw~•­=ÆJM½¶Uzd²qacάØ1XzSAW=㹘¹/ð°Bhx,hRÆû˜=GvG4]uɇ«€Cì;üê¸We¸gû…‘Ïs¿‡ Ÿ( W&YD³D4|§cö ‘…|3{cRX`aåì8¯QiíqáÂä@ ×'Ãl‰6ðk£uᣕŒÞ¬W]ˆ:y6æ;U›¢|‰\BSh‘±Å3ž‘„IL8ò œWüð£ñ…„O$>+ìœZ2}àMã·)hŽI„ƒ'g<µ‚_aZ™,¼q²Õq§@Oì`¬EƉ'zÆyÅÆmh2 ŸŒ… nÀ…ãžwÇW‘ÊéLîJˆ2–ò^päŠ×%Ó£Î$D%„’pÅ…’ðxåͺþ4N9Áiäp{“ÐT:äÂ{égðõ5 ¢µÜ7R02ð`sfæmÉŠ ¶";QC`¥/ÆwJÕ…­ñ_Þ¯|¢÷1âäÎÈ•ž"1)œp?¨|¢æÔ)áÆ-›Ëg°úRr&Ž"°P î8Q3âWËŠA|(?‹Êœ’zfäç§·Å•»B1˜»âÉtkHXÀ`·»>vì‹) \Füæ´ÏÙ\TIˆ 3ê|k<öò^È$<™–Z r’®¢Él(ÄÚÁP˜­JÕ ‡~Z5øð»ŽÕàR°ê_6”ì{5˜”„Oz-7äÊBÂ¥Þt¾Ê5þ…Ék<±ê4²Š¾…¿ oÚs™av½KP­ß>ÌÛ’eÆ•]û|;?'a6ªÆç’°—-aaYr²ìÚ\7¶f2³þð~",„ƒOãªdbGFáà>Î\®øªÁcÇÆX6Ú€ÕLº*™ð%²U [`èâ8¯JÖÏóœW L†\ã‚1k‹{ÙïêYÃæ­½®Kú4Ç"AYÈ—ŠíUaiY‚5…!ÙiYX¹8Æw«Õ£µòÎ÷ ¶,)X´æ#»ù``JQ¸áçB‹Â|o¼-À‘Xž…÷…KY[ãûeÆ ìª®²j6ÌÕ!žØ+ §ñ…×/,Ìkc|ýÞ•7ŠÂÂu ްÞr]ò( ¬ª0·Ç…ð’BIˆã… ¾Â AäöаA^‚(Q™öŽ•1~Šù´deã{eà‰…à9ñ2Ø Z³ûÌr fÔ„™#6´ÎÀ<#\ñ•6‘……q¡Äñi;œ­;{9U㵂jª±O¸Ã@ì7Úu„ya¼Ìø¹hÇ`AE—%kT>*’ꊌ°ÀÁ‡[6#Ä6Á@XóÑÅg„Y<³äÞxÜøÊGg„[ þÊ«:öÆËÆo«ÖƒˆK«±ž1âgÞ†„è¥,\Ž8$Lþ3ãã<)N8îh¯ÑeÄýg:õÆ;ßeYAØÍ‹« 9€ÜhØ¥3f7£!–sÖgvʳ[ØëÀ{ãLÑ­ò ‡ø:»uÁ—¿;ª%d«$Õ² †ªª—Üy+Ï‚ÍE–\._Â'gŠCD¦â§²ŠÃ±ž¿À0êgNìM †¬—n‡!~š†ìYwŸ ±ØøÆÊƒ±MFS© ±Íž•9!>ý•†9ÄdÀËÖ“…MB¬2ĆÙРé g9õI1A5€.Mž$/ Ëãý¸~¥¤£™Æ'qÔiWÐѰ°SÓ=œ4ØÒ¤°=>pp©$Ü# cªÝÈ*]÷íï4(Dº {Õ…øú¹ªúÇB!WGZò*¨ÕáTÁaE\Zaˆš ]™T¹â´p᥮wÉK.Δl½<Æ¿ÊOí2 Ql¢$d=ÓWÃU‚ÅíñÈ¢`ó¡ÁÛ7ã`¶¡9ñͲ£cåÅàC{1¸­kêc|ÉxÆ«ã{ôÇç‡1Ã`¯3»}Ïñ%3G|Ÿ¢]Îuu\0¢É³Bþ˜ºÿB€àò’»²«(« WvØ÷Z=XÉz/9áoì·%YEƒ«n…à“ϨP0®Ç742pçÕ²›q”„1àøä¤„ÓõÆ‚Ñ(ˆ¯¡Pp÷¤ “ ÍxâP÷|L Å Þ‹Þ¡ ~C½ìu]ÒKL˜W&ìrÔlÇõdze¶„ƒÉ°ÿúqvCL˜kÁJÒ{â+c¦„¸R1ò P­’ÄtaÀNÌjÁ'&"ÊÁ¥P bùê§%Ù«ŸO»œ‚é¼î|~¢µàçcö³MZ•,S-É®A»AŸ[ÓÁÂm þaw ˆQ‰íd»`å²$Ïùø×˜ìpk¬4ÄøÀÒR°Ò#0 ‚|ÚjÃÁ„Áõ`ÿiÝór^ÌgþÓ…ƒ#Nwt8¸Ÿè·.œFÀ›W¶¨ÞNÜ€h9ÈÓS!ïð„saK²OI@SìÆ3Ù-3;´ÜhŠQç¥$äÉ;$d¿6îdÅ…–í;c$Qâ×´ýܸ`ÄÅ^Ä:Äg‰¡^ãfr┕ƒX¥ÙiIE@ •…gî¸õ3ÛÄ3li‹ùÞÊÆ××"N§’)မ¢ jl>ˆë›bCæ5a<²[?Ãî^¡0j k(¬¬Œ±pTfÛ…¥×½1;Ï >‹ø6μ V"Zå37RBœÚ¹q® ÷Nžlîk(ÄÛ]C!¾ÊVææxe/Xc!×ÂÂÿ[ÎÂ|[2WVÆsEV½² ÞXˆ2c!þŒ•…Ñ~æá¾“uÕŸ…ü Æä’qÇá‹5È8Õ¼ÁBü¨zYØkgŒßSáöuêöiyÚo;cì_îÐ0×…“Ù¶3ÞŸœµ+«Y4­¹ž8?0a5V4îÄ•a¸|hØZM•„#ë¼DX=c…e1NO¬…|mŒµª* ÆýòI½Ø€Èä3ÈK¢ ²pˆ-òÍ8AX8r#y§.¬°°×Þ˜©*0\» h:±ÆXˆ Lc‹\* ¹NýJÂëaní$¬8råø’R]˜Ë‘çôJBl[„xen$ä°'!!þ: BlÆ•ƒçÉÔ¾:ŽýñÕxúã‚~æIq°`Iˆï©™ÐŒÉ’pˆÞ ؆q%ЊÁÚÎdAÜZ£$CÕ3ÝúãNžý<[QsVÞ ·ß—dlŒƒÙœkÏöа²3ÁúÂŒ s°çzdsÖucuŒrËî¯\8X@8˜•¢Î„ã–í¦qä…š¢pÊ>Õ{µ™ ÜÏŽs~ -4ÓîSñ …QJÈkVkñµqâÏØuIÁ›°W¨ÝÎç¶5é•j× †8ž³ó,F†Uóä*¬3 ñë.0äPˆEaåð8¯MÔ›7a¼.Y7lÅ †X`y{œ«Â™0Ô‚a)ìM®öu)fÓŠ#N…á‚­‰åÚ!¬.Ä%»ÂpÇ—ZëÂi‰0ŒŠBÞ KiNîŽûéª ö„8ã»#¦é³9ÙØÄHûãÒáqANÃvÊʨ)¼ÞŒ¸:9Р]YcaŨAg0Äé”Á †l a2Ž!¬Eæ7B ONÐu"è¬IÆ!•Á‹UK¶ã[(…!_ûè°°mwi‰œLxj]r¯»cœù; {U†…#“飗²°Ï±Ÿ£ +¾\†B—̇ÿl—õ4XB8 qy ,ä%„y0DiáÕ&s®¤Â0Ûñ¼†=b]2VÚ%ï¼Ï×ÂpdçE—X³•¦vÉxGh]2~6¬K.¸Vï¼Óo<þ̉{ÅÂhHÃÄ0v3¤É‹úÜê’câñÌÕ߯B| ×±xŒ³fC!k~p—Q˜ç…ˆŒÞ\…$“ ·JÂ._!g>y–X” NÑ…Ö"Zr¯Y0Ìëî ™„9îxÛðû§ Üñ{Ó^rs¢×&C¸¹+aNnË;îÄÁBð;?kn™Vç¸ãŽ7w(×jáÀòAáÄ×ÉÍ"küuŒ„1Êdam†¡°”ðÙ%׎é¬(ÄÇz; yzéÒ˜ý¾²®Â:dü€éáÝø$—\Q¸±SƒuÈÕ¥jšBUȭɬ9P¡Õ¶zû¼JyÃë´ã—Â`ˆ¯Í f™5û„Þa–Y,ÿ¶¬ã“¥—ÊBN~jø,œãPÛúãlÀkïvçê‚®ao³-×€ë;#!Ë&”„¥ùv…ÅÉÂ,!áõ%ÍEáôäØÔ'ø2 ó ò†áîG“«Böp6n¯Ûã±ê´Ç°ãë5æ¢vâ³Í- ;¿\ Bl§¾/ɤpoÂ:†A&»ÖÖ‡ “'Azíþ„XÊYIˆëŽ+QÇ…ŠñnÄq£6Ç|Œ£sÂ?ÚŸkÝ]WˆÅ®uÇ…dÎ6æ¨cDœkiâ©Éö™Aÿ ƒ…õq¡dÕ@û2êƒ,Ò©K!&½Zã>åàˆ8°üª;q’(êjvt ¦»»åƒs/ƒ=88óÙ‚M ñ7â#Ë8ˆ¿}Í„,ÁÖÖ˜Cµ5F jAø8.އ&ÓVðæºZãhPˆ5ÓÑp £Öƒx­cSB|„gÈ;¾@˜ý„#¾ žòÙ……Š›€ïcáÄ Ó V{Í7w¬qpŸÖ\â°ÈPX°¬®lLp-löýyJÈŽYÍÙvWo\¨ Çî…]TXèwöIóÞ_Ffâ·Ë½Z³y?ËIüÖ$j ·O‡ÁW,Œ¶4l"d.…(½kgaAEÓ-ð«K~ïåXÝ„ /ÛluÜC]}pa5!n²­&Œ"NžvFu5á±=tf'†ÿ![ªM!ŽíL]-«Ç™ŸH>$ÄâÛ ºp4` D6«S!'x +U!§ÊhUˆ/µúµnkœFAáŽ/³“°r}\ aöçêx¼ °Åli°ˆ¸ÃÂ.(ܳiõZ&qõñ_ÒÆ!á\p*<8à†wÞoÑ®u~25Æ@§•eSFÂè°°¦\Å„ø†›OáÈs ç îœLL˜iö?_6$,„¬ì N¸*r & M!Ü{-ŸV i ,x÷£Æí7žC«–°[Òg æmɺóEgso\À >ˆƒìh§&X;܉¶+Ø÷ãn{cìêÜœ+–„Û —¡0&\ðÙ§%!¾nb°ÝcJ˜}6\( GüV¨e+?•Ü›+9ø|ï+$<æíõ…ÉøÓׯ¼ wÿŠ~&ÝŸ×[Uˆ<Æ'É­È㊘°×Þ¸OsÌ/¢¢ ß^nœQiºêÉ%Ü C,ÛÏíðE6 þáVf1áÆa|^LüÙáZŠÂå:Z®ØBš®úä8c]œ‹¢,Y  UadáCY]ˆ¶Ã'²pÄßYa¸N©,£'͆o—ç¿Wºã çvÝ.L ,ìæãß…Ø# ·¿¥íUa …éÄdÊ'&ÇŠ_¬v#üs)äŸQ– $Ä?LILÆB¸©YUØÃæUÑöò`Èæ\C¿¢°KªÓyäT§m, s{\80aÇäÖ’p,õǹ&Dq¾à5a6)dÍy{°7 JÂ×RVâLRÏŽƒ=ôÜœ wýFÂ|m·³sÄš0FšÎÌ„„çä((Ü¢ÍõÕâh×,,Ì »E¿gï꥾…øž+ gœ·6£©Ûjä?ᦠ˜ÚLÖ‚OáŒÃC!Ú¨˜ ·ˆŽÂ>$Ä£’OJÂýàËQ!á°³Y»‘ÿz›Ìhv,­½&ÌŠBü•„ÓžVÇ1änäg¤ÿì ¬sáûy„Œ]#!"þÛÏ“ ]s:|+ OP¹‰nñUV"ŸÚÏŽÙ°ÆË q0ÐìÌõÄP—&,ÅrWf–­YP¸__Œ‚1×ÂM´[¶¶&8‚qM!ý[[ ãWPa8Άqœ¹®/N¯ª 5¯ éï¾Ubç¡âênáïÌh–aÂ?^YÈâàvò*Ìlü“’fâ“eaiT˜ë‚/?m …ˆæö{;¤®•…9èîú¼g²‰…5ÈcŽúàp"C!Ö>Ö ÇÌÏŸŸL…xLa£B”º+ óáñX°£),MJZšÂÒ¤°@îfäK'#!âà›úã" ÙL¥}|"ü,Ì2ÖOŠB|ÛÛËBü  sQxæ@“ Q`5!%¬AÎW&.V<Ð$»µÎ+KêUJs| ÀíàUqFBé«”fæpZ•ÒàÏØí1 !•„ŸÇ¡/HXˆ¹Cr ÷Z¦I¡(Äoºß™ôB!~Õ¿¢ðz•»© ; (ÜxµÒèQø¨ & XXÛâ$ w6øjß óŸnëìG×/žî”ËB¾YT²Ó…”…ym2YJ³m;ßÒ+ w¶Á4†xq·8ÈR²ß¶÷ǸÍWâ{jÃÂ1Ù0RîðéfE!kIÛQXPÒlØCßÚ §þø¡Ýìµ5é4+ä p-­M*Ua&!ú.%áÈU†íM*&þfîøÅr5>'še…ÛÀN:,ä³E!‡* ±U‰õ>q…<•cÞÖ+ §h͵ºB*eaAWøÄSEaˆ§Â¿É Ã’Ä:ð°C>¢®ðz•1‹Ò¯MèWVŽØP ¹ö–™ÛzeáÆî@_Yx[áùÑ2äd.®•…lŒaç&|/=òˆ <÷kÍÓÂ=$š\0Œ[d6žt¿Ö>È,} “A×röÛ›tj‘q’åÓÂJ‹ŒLUbûë-rÔ檰tWñ¤Á÷ÁóL’?×#Ü©0-Ì‹“mªìãÞdãñpZ³=×U^‚î:ìÂuÈ¡Ÿ;;>}áúñäŒT@8áYAÈgʾ6‰ Lž4Ï „Xè:ñƒ! \°‚x9ÇÍ:änÇ&}âL6üê˜ÆšÍ䂯šB¥&DzÕX%f5û–Ú 2’* 9 @Q8á7ÝPX¸A9.÷+ /ªÄiá<ã›þ•…Ó8L¼ÞTn amü€ ~=µ)æÏ¨VƒÛ/PyÁ˜è4ñö뎃Ž2Áï˛Ԅ>¬MX<ùF|HXÌ'ÿLc–ÉㆲÂÀ´*y$Vdîíò®„í…Z¹m_.è/k1^>X5ÈÇY_)xŒÙfñ%4ø^UÖÂÊÁƒj¬ Œ¼Šópdr±p凒°pMÛ’ŸÍ»^/& G)X=ȧEí(,Òlø¨¹ÕÇ\§éû¨ï;2ÁÂÉR>»(hÚŠ#MšÎÜj™# ý6íq!Öid• 7êFBüNø¹]Œù¼êA|Ü ,¿”„CôkÆu)T„k„xy¼rSâÊêÔoÊG.x£¤$䜒p^[s]$LÖ\Ó€Bo{?"Q 3B«ÜB!^p™aëCÂÇ¢„Oé$áÿ™V]õ3c sðÇË=¶‹ÄË %aAJÈ1êÖ³”u¼NÂxn·Œ\AHg¼â[®½ñŠÕ.K–³P®'ïù•„+úv ñ¢$ þ²Mšpp‡vÇãk«Ö!ç|Nš°ÛI)Ò ?Zâ<äMþ• áÜϦτpâu°€°dÀ“>O¬†„œ8®·v9Õ ÷)í …’Í쌄¸ø3âšÖ“>£Gá2Uf„ˆ%!Û§ª”ðØ>Pÿø«î8Û­sAKÈÃ%áÂ-ŽísM8âtN×%Ÿ«™W0Ì¢jü]Üë½fîøUWMÈ—²ÅßWòA¾ +±Ç9áŽ]m†ysŒŠ_« ñ±tÄ‹¾¯8¼•oLÆBü6Unqömþ•¹ÀÃʸŸ;<Äç»§Üõâ!ýÒÍ<<òò˜ÏGÚ­¹ -2Ö»ÊÂ<+ÜÏ’Š¦ÂÂBiˆÍm»¢Él}ŒHõqa4òß9ÜJÃLÂcaoS%áÁy\VV|°kP®øm÷Ê0ù> £³f W& £9›4yeXYœHX°aÀÉ­.GPZâ‚áÛ@EÕaz¡°4á°y!n6µ(,P°ë„45 v&Úç‘Vò÷¡5ãnc'm-Yeª¼é¹¼^ë|k7"t=ã.׃|Co§v9âî@bh˜É'À^@pŒ¾\ø”5òyå ü9·„4ø¼öö˜~£ï£ N±Œƒ%!Mag‚톃0wÇÙ¸úà¬ð,Ì'&ŒCa8ÈC@ã`\_Œ2š‰^•ƒûÊ't Â닚uÕÎ „™ƒm ,d}ò+­ ÜçÂèÊu¢<Ô]¹:Uƒø {“+×±TÒ>ñ;úmK“ã`Œ pguB{MÈþBŠBp gÇ8§oïw\¢Úœ° *œ*c¨)\OœØzkŒ?#0\ѩǦ„…Þx«$¯[!Ïä‰XË`íZ·äð)aþÇöË}Í+FE!'Y+ »€«a§…ÉÁChÕVc/õmçÆW‰µÕ<·k_Ö%|É¢rB|˜œ°d¾Pñ¬Î&¼q²!>Ž}DX‰u*h«YZ¦ÛctÖÖ¸ÿJP1x5Ç8î°!"®Õpÿ¹>"LF4×îÜʯ_0/±v×ê>íñV™vc!.P½;FÎÝ`!nãš»ã¿Ê™ýÚí ±ì1â ËÄÕ¹&œ+íqáØ.Çóé­±0ÇoKesÌQàvuœ5…¼â±«c\‰ÛÕñV¯ ó¹Ÿ\ qà¨%áYp'œ°§°“;Tò™Së/“¥W,L¦\#þ*†Bü“nôÇ•Aa'û…7R.­î5'ìCB–\ g| o4Çøòøœ0‰«¯J6À•T§·ÊIÁžßP#!§¼;Îw&••I\_ŸœdNx…3G»+WvR± ‘SÖçöx°gÆü÷ŸSŸ#?Ï(_0rœh.òצ™„+ÌQØ)ìó¨ø/t¢x¿}P˜­hf>Älg!2ÌïLÒœpæ ¡­L ‡&ŸÖlÀ°²W•„1õx›ñ%6r> ‚›HSÐ`k ,…‡€N^4|Þnž\±;æE™uÇ1ÓéꎳÍçzù F4qJ¸×rL ¬ègz-L"¯×Ÿk߇A|Ç•‚3Ï›)Èò¢Ös»'eˆb°SÌ'«¡ƒX/; †\%V¹¢9á>¡˜É…“Ö ÔœðI jƒBTTq…c(,h +Í1+2…óž.cÐç4àsÔXØ©$Ä/޳°ÓÅÝ‘«¯š߬okìÿ¬$į²Ã»l+ 1&ø¬ø Ã¥`Oxpdos{ŒÇtÒGâU„aŸkw054ûŽsjÅ —å_)xý—x¦åàR‘Ь…Î¿é Aü[9Xp_à¿2ð˜ÓeIÌrº êxi÷@t  ùeI/-aÔS÷shÅQö aܕ̜hô¦«cì•yU‚ßÏæü’»k[³ÂF-¹ ö œçgkc”Y*gÞG‰Í”G„KVÏŒ;?#Ü|/BÕ††ã«ƒK”TïO<Ì~!J ¯Ï2:õxŽSÚ” Ù†a` ¬xV4Õ¿¥9!Þ¥ éc¿°ZcvÇtÎì*Wv‘ƒˆ'«K;ãØsR6Æ{AGX(±/¼QÌV6KRš|l<®OÒ}e\ á‚û`+Ñ@I8#|B˜ÛbNÑQkÒÏ É‰fîu^’üY/âïümáÀFÂÁÖ~qÌ¡ îB“6&+'}ݱ«.0ç˜3~(VÎLúÔ†k¥If ‡Â°eÒiƒ\¨ …!çf˜?aÁ‚¡àZ]0(Üg|­0Ä!á°<–åk5« ñfuaÜš\xâ`žfa!½( ÏååþøA´?žØ­ÛHXÚg¢hÀAØ+Ô ¡bM26ÿß8-ħ€‚ƒ£„Ø¿( ³Àš+5å`œr€nóåñ²d+šµ"¤áŽwÈÛjÉ´ºrW–yœoMæs(ä9=‚3³Ä•B|n}áñÁ™õB|+³ö¯qk½h&|eŒƒ¥ð÷ÈÁ?ïïÊ~7wWwŒ«ÄoÒ`i¬lM d >WÒä›;özâ¾ýènÁ¿ÊPÈ—y‚ ÿ[õYèŽ Ç&,Æ…£»ƒI2+<ÏŒÐÅÉÌ÷³BBþ Qu¨$ܨJ«Ý/$\‡§F:*üTb½Ba´£™pXæ 䊔&¢pFxèq·œÏ˜drõÆ8ø¾Þ˜eÑz~ÌÎ]í(,X0p ¸…üµ¹‘m—'…K.ßæ) +ÆÕ¹*ä0g?¼Ë,UáÎÙuÊÁ>5a”Ï}P¬"¤i‡ »z*ù¿e,:U BÞ7©# »Ö¨#M‚—æBÁi¬8µ|Acž4…ÕñŒ#§`Òà&[!È{O½=÷—žÕ ÆÍ1Ÿ¼ù¹ÖŒÁ©ãìUf³Ö‹ï½ìû»`ð@Y¯ag‰ÂìO8ã ÞIAˆÛ'aŸƒ»‚¼zÙ±»±Þ˜ÝA›Mi80ZP¸0.¿¢ðÄ‚ZH¸²ç˜¶ÆÓÆç£¿jãêxùž\IE4Ï„«Ö§;“Ÿ[ãèI³Ÿ¿Hô^¡0yÒLl'(\J+“ 'üâ ;š”HØkLØ©3f73ç*ÜãÇÔÇ„YP¸à0ÿ+ 7ô7ñÝqs®ÒŒÆA|{¸]¡&Ìû’?í¾/‰æ\O¼"UB3±ÄȽû³YëÆ1Í­ÙvÇ3±—rO •ƒ~·¬$<’˜0fÛM<¢ðaáà®ÂÁBôûŠæw{%¿÷á9¢ÜÙjÂJo\!_ƒ5ƒ•g–èT( ³ŠfÄ-µ¢ð,x0¼­´D§‚quvaXV•–špCÄkQøääG`˜eÕÛXð¢Ù‰´^yP$á†%!ß™yÿ6Ç1ÙnšPnG&(r»±,É7&lÎq„8[7â÷ïûD43 ÕŽ¦ñ‰óSUãÔ·1Çd«Ørõ‰}Ç?É(ÈI'JAÜ"3ù>GÈv?Â@¾¼UNøßR^ØÁbØm«ñWR NX1£%×q5ê òÚJ0È_Åà§Å+ F-áŒ>Ñ~]Ò…‚8ó5 â;u‹‚ü˜ýŠÁ… ¾ƒÙžpbÙ†s0û²½œáó„;¿©–k×éºu8†ÂLÂÆ^f3} 3Ÿ×ZâÄÄL®j…~k- §RIˆPuýL^—pÉl,L÷%?³0¢p=_:ø_(âÖxÁÏ©U„l/tckœYˆßâ[Z »ùVã³¶…¹3.œÙaÃo ,ä{âk£ÄÙ» A&…(§ÊÚxÃÑÕW®#6l Bþ Z’I^³ëŽ þCÂQáöÌH@ø¸ÊÛ’ßUUU£ÀW>¬§ò”ð@z+Ù®\I8ÍÉfˆn4œcY&,¸AÂßrJÈß/#a¯K»>$œðf…æ‹cÎbwFr íšêºäÄg€£'ô‚Búp)ÙÁHˆÞUNBüú ùøJÂc¸\Q> eUòÒÉÌpk$äöEIˆg#!þ;JÂOSïW$ŒV4œ0e5!>%nìKð¿õ. ¾éFBDü7’°`EÃ-tsUˆji'a’ÐìlËaÝqÉ—«puœÛã••Œ……ó’Üo|£ª0d—Lƒ!Žé•…{öj=Î'÷ÄÊ oÍ…œXe(¤×YIxðc]IˆeüWŽ(ÞÖP§)Jªs¼Ï> „ìf×^æÜw¶·¸UÆ›ã™Õøß7'œ*évœ#Û¼8fÛ@'ar¡¹º…¤r[Rpä*Ô„øÄVòei;ÙzP9ȯ±pp°]Wf{Âsœ æ ûù‡¬ÂçºBœ!á><ØIȯ’ïX´&ÜÇ´9Žùv_ùœ°–pÀ á›´„Ÿa,ìæZÝiNÈë²3ÁŠö+»‰ß/E!{âÉî8Û/¥“ã¼1YP]k5!Â[Y8F…|š¤0œ 2k † î †Ol¢†KÁžð˜>°PUr÷o4 ;“ †üHVPˆƒÑ$Uõ—Ç+•lNˆôUuáÎÿ[·\«ãÝWî,Tvº0á’W…É“ëjòÖ¤ÆÂ‚Ž&£ÛH%! Ê„yg¢;!~¾ „k>1Ùy¯© |T|„sÁ}aŸ V4;VJ¿‚Âqˆî × ‰¥¬)i†tm7D+š7ë>*ìÓ!ãôÓXˆ‚ú;,䇉ðר° Y|gûcË ŸÖв:mM®OFnÙô憅?[+hYˆ¯²µÈ¨É´5 V"1•†;‡_謯ã¥Eæ²Î §ÇåK„á£cJ0Üö‚ÿÂïíw‚YJs`5f{²( ÏãõÞäøiŽ0ñã|#¾Cvtö²ðÇ_Èö&X$| —‡…o.XG8 # yðm0ĺÆ`ˆ“%!¾WíÓBn+Œ…øßruáòÏ錅ìbÑ*±>Ž\.»a|eáõl¹ œyqÂöB†Â|hÂV‡vr‡ÎÖŠB6!ÒÍÉd…G!ísÄE»µö1£áø]…!ï!ìÔ;Îoê’/r¤¥U†¥äã C.4\]Êê$Êiι”{œ C” 9 'w<¬We!¾¶;a¿[Ôp&¨°pÃÿ–²pÊOX¸?V“ñþxøÜKiN¬ù †¿Ö…mE†øßò«»¨±>§×ã÷9áÐiúH¬YtéÖÕÝbîbàçùŠ„ìÎh[äŠAa&!Vb£¨$ÄM—–…¸mµa˜ÙÍÁ¦…„§Ç&?Ü:ñI¢ d?W¹5a“½5Y°ù ÂGð‚+wªÖ¢³±|m’N”Û­ ~s„>J„ŸF‡¯Hõ43’Ç iðÛwƒ„¥qa¯™ÕýùÇq®~ °p<á¹=þ`›¦ÕÉÁÃ- q8ÞÜ"ÏG!׉c‚u\Èã9ßDw®íIV‰ cžÉ¹åŒ»•‹- ú•†Ë>†Ø“¶Ê¬'¦VbËn=2> ”†ë”zä)Ûs!½=Ù©Ï2{Ĺ̚^¿[=rfa¯ÍI¯9÷ÇØ'¶W…•aaLûÜ áÇçTj (Ä_ÙêBÄŠÕ…œ¶«(,\œp«d rÌ>>|˜( gü}ìôn¨xøoèmv ¸x³Ë;,ÀͧóÍÂ?—… >O„[°ð¿@ý¹&|HXYˆª‰ ,Ì ±ñ¸•|œ—ÈO¼h¿­*y hö\æ%2ÌlVˆu˜V…¨fSâ}G³žf>8¶ÉîMPt£Ãœì„ßs#a6¦Ùð©åa&Ñœká<Ýš,ÃGö¥y²µ¥ ª¨ „ØgÛ Ƭ«q¶k^ ø´Aa®³=~± „XòÜa¥?îtpÂß vú‘Â>—GãV¹ã¼“vfƈ»''_8xõÏþQ7jÂ\âæÓ*B$K¬³²pÄ©®‘ï´¤$ä“hó®Æ5ý¯\üqzç(,ØÒŒˆ0CaÁ–†×\m.þëê¤ðs›ÿŠ„9í3ç¿?ñKi'!áßunÂ[Õþ@ñïVÒ>±xj?7Á‰šoÓÎä(„:Öæo!!¾FÂÂá¶ÏÞg_š'r%aâ‡B08= äõ0¬† ƒÍŠU£YW³#ˆ…g âs_18FM!Ó) /OÜ=Û1X0bÀÿÔ- Fãêù[—°E¯ KêêÁ ¿[.(L3ƒgïFAüOÝhŒ³ˆ†Ãø\DS¸?ÆbÏ ÂÂÍg¡IkŒ_sÓÐàŸ. ·…õþŽH˶ÖÌÓß³e+‡ „øŽµ·Æó™f„ctçš²eë©7‘°W¸_½ …}Zã‚¶šGÍ(Dô´Þ™#†ÍšÊÚ¸"¬Æ‡•ƒXÀù"_9ÈAª:"ä  V£V@Aø0>ˆb‡Gq>2Pè3ÂBÈ'³˜¯mY²½6b¸@͹&¬g„…‹»þ¾àwÂG„ôÕºBäŽÝ˜àéûJЬºbá_) ¾ý"+mmÜ%ÔiÞ $ädeÐd ªA~ñ´+æïƒtÅ,õ“ØûüÞÚϬýp%a…‚ô°•q!ÈdƯRpϧvç')_Q0+ +å`Ŷš›½;ÆtÓT£dê–’¿7ïraèT"ã4É;þöM ßìù„0÷ÆÑƒá\û8øóE¿U„ÌJXˆe“W qå (ÜqHf2œn7 ׿ŠÂ±Ðo3ÎG=Ì$‹ª÷ʦ„óµ …ág„QFȇä&#D„µ£=²…ZãMšÞåÖZ ! TS_d#!.Þog\Í»l…bm¤$ä•°–„øê˜[k¥,Ì’j63òãFxý¬ #~†S©.\ÙÅÒLPUf0ÄZ0 œIÛõÉ>MÖ¿v: ÁN >Ͷ……î¸àÀÀ­;,dù‚ï ¨ÏGŒ{l£a%ô¸bHƒÕškh Oî¹ôÚŽ=ªÚ7Çì'f8Äq¿9ÒàBqˆ™LÞ%çl§“-Їvõæ^Íw­ wÞ ÿ*܉þ|s¤Á©£»¶&ÍÃK. y]¦8ädBÛ‡ø‹‡Ñ‘fÁ÷Ôí¹*µ!¾ïÚ&c!á<ì%(d‡<ã!o\È+7]›à¡\»Ž†gúFÃtowV?O|09 óB|œZ¶TV2?+0Ì#ÃC †l!¯0diÍ '^Kzê'Ž1†ë\0mņՆø½puu¡QÆ÷ÃVÈGÒŽÑ“fÆç’·öbaÎwêÖ'Ÿ…3“™eã߸:A aá“fÚJÜ~Œ3âËl,Ì)ðg)Ö$«i (œ°‹1r%",œ±êñÛã¨*,”…ÙæªÀâáñpl÷ê«I.T…3¾] B¾\wf- ¯‡Í†õ+ ÂaI6 9ósÆ—Y@xp2v; |ß´<ᔚZ\=³pZAXY!ü« ›“ŒÁ<.<Øp»½AÞ áÇSi^˜ù‰mäªZ8ÈÚ(·l嵑²—XRŽ3?Ü|‘Œ¯‘±ßcaa`ÈBmc!,Ô³?gÊÂcMÜú‰uˆ¡o( …øÑPŸB|: éãs…Ù›«c¬I®8²þ˜cìš iØüÆ`È—^²<Á•ùvaáÎÆ[ÊÂJržΕþ¸âç«B¼ú4rµ–…+E¼,Ä'œ£0÷Çî` …øvxY˜55¸³þBÂÇYç™ÚãœðÄ ïAáŽ/±£°ÓÍݵšî‘Q¦÷m(ä€>wa(œÜÚã‚!ÍŠ¿²’°2*,ÒäQáŠuˆ²ð‰­«²‡eÈÂ!k¬¹ò6âÆÚ}ücæç°¬‰øUœoùêÕ@ˆ³­ Î|P˜$Öã/5_"¯‰„ÑfÆÉœ yCÜLB„»ûµöÎÙ¥°£ÆºÏ­ÉÎÛó®®L +6…¢Ì¬Õ†¿67P˜«Â¹°Bf†) ù¢GXÈ`¶ªUª.

    qk ÄÑÀ7‚0—„æ´ÛÑà¼_1MNA°t§>Aw3Ÿ¡*Ù²À@X8¼ã½…¬T²·§ê¬ùoWuak2N¼ô äœù¹…¨;–0W…3>I­=.„Á^Ë¿ba¶¤Áß×Ó .…È•/,œ¯n?ªÆÂ>(<*wwxÚù.þYHÃêûv>ù’6nüB KÛã,³°TQîqT¸ü>ûâ% ÇlJ³žøßruÁ§ç0ùµŽ×£¿tw…¸„W3†ÆS?sQÈF«ŠB™+ Wü”¹su, £¬pÊ òÆAŽB”f( qHãr·­Iô¥yøw‚aæ¥I%Ϥ )d·>ŸæîßE!»·oM†¼A^ÙüÛP˜£àGü,[Uˆ¿²‘sA¥*DXQK¢$\'žoê¨pùÀ³ÙÒàŠÝ¥4™„kag2ÅQáÀ¦Ê¶3ù¥Ëy ½íıv{‡_‰vâ·Ï«{É«KEáµ2ɦ4 WF7ŠÂB<§lYQX86)D;U@˜ý¹Æ¨¤yh‡³q5›¨ZIX9CÆÿ––„–¨BÂùŒ¾4ãõ¼aݸք#Oë•„œ3mêj,!¾’p’­j5aä OÆ„ÓðZFs0Êh¢[k!õ¸Â@ÜQ¿iFˆ_`úü±<«™Û ÁŸè¡„Ñfg⪌|¼Äý~k%È` Â…¿z ˆÁaÑìO¸s”šÖþ>ÂÁýØyë'œŸ¬…ƒË‰û:«ñ×VNœX+äuÁ.'wk Â1¸Ñì9âs<±aqÇêJ5˜·$Nn|4Ø+øÕkžaÒ«'îƒB\ç) —RÚq’ÖHˆìQb]d%aƒÑ–k:QÝ­ \påg Äa»tæÀѳe˜Ä|Ï}’„ɱz¬Å{ÎSÁºáï§Ú冘£§„AN½<Šæ<\æ×Wv{!ÞsÀužµöY’pëò&²U²gw²¢éÓCV.¥qò¸WAÈ *žÉ¡vÆÓ,ž™8°ÝÝûsMÈÁ‰Vâa(,¬IvTp) D³²p/tÇÁ_dáÆ+~mާ‚¢:“eàFB[Õ’‰ª$Ü‚ Í^sñ}ðî)×L 'rï:²Ã&Èó=éÿ®5Éȇ[ Bþun,Œ»€0ŠOܘ63 m1þ*V bÍä,¤½³¬Fæƒ\Üë|G!JÀcâÀ˜׳äTÙì8‹´ù ö×`‚P±ÆxŒ«â¨™sc¼òåF9Hÿ)c þ3wëž]~'²Q›ÚêÚÏGì­MññÏO³h¥Oº—‚8$kîŠy i&…<;ü”ÚšgÝÆANý>±Ö 'ä©*f†¡ £ÞF–ŸØ•1§si)ˆÅ©rÛkSÌàšÈòK ‘vç9]¸m¹Ek%¿¤P â-›Ás«-Ž«’'=·‘pÉ7%ËT1\$Xhб¾ð¦8ŸÖq*³_”d²‡¢ÝÖE¯ê™Í ´"Ü7¶ÊUíà^HrZ‚!Çæ* çBÚ;;‡›Uu¸­{tÅãk¿…=g{Žlga鞤Ò6%ôêÝY”ìùÊø `$ÄϲO/¼+ƦDQÈÖ)†Â”ö~ðÖ]ÓÞQð5ÏþlU’ãÞWþVXUÈñfŠB¬.MFÍvqÂB\(è®dyR «xfç¼¢]¬(ÄÏÏWn¬eE!bךc|ç•…kZçpÏ¿ZÞc/uCF]ö[c?e,Dh|ß®däŒl=¯«œ”$^ 2ë?¬A.œ”ä!a)Ω $ÌsB¾F²ª¿ ^ÆUÉ“cÜÖ­ñÉ™ð¶)ÁÞE«Âñ`{MG!~—­*äëqA!ËÈ…!¼™Û%á¼Äª0oñ›e(ìÕW‚Ž±Âº•`‚Ó'%!þ;ßV û—±rR‚ 6¯ #9~Ò–%yk¼á7´=×®k‡ÿŠ ª ‰ïŽÓ¬=f%…‚0ùp=Tr8ï°þßs- Ï•¯{´?>xœh$,høXAûã…×z­ý1ÿ3æ=sÆ¢0ºp Ù¥ze³ª;$,×áÞî sÄç“óóíŽJÔq…œ+áö3¹(ÌŸø]o7á £Â §JÆÂ‚¤ŸnH˜'…+)tRˆ¥ˆ¡Ã¥(|¬Å³÷Ì“2LªQÔb$d{MK;. °P~ž²¿Ba´áqhk(,ù-® Ã;¾ñî,,¾BLÓn&!,FB.„øÔ¢_h'a;ÆÂÑîŒKUa…9»dݰ#m_ óŠ5È…C»¸6ù9Õ›%]!ãK7ÈÓTÈøÜžø›%!~{¬.Äm«¹ÏW~6©e>¤Z!û}/„|ŽHo‘;س>hˆ[z+ q x+Ô?ÐVöº¶Ã9èeuì‘9›¤±.*\8 符áY…/N2 ÙËL%Ö+bGH8­ø* ·íÉi‘ç—à˜Ï®íp›a$ć…©iøêSÕ4ø2* yœ£,\æ×ö¬ ³ jºŒ…øp"/•…ø@vö* ó½Ýñƒ›Túã ÇÚí ò‰Ÿ¢pÁa…±0oNJÊ‚mòƒÝªBÜfXŒBc![niœ] yÔ¬(ä]¾Ô„ã^© ¾ö2]!v¬vt‡SYó`Àá“‘0Ý=<p¡ÝñM†ìFƒ£M#!>¸œ„ø3jT]p£Y‘¨7HXÐXï¸Þü¾ª°²9ÙJ^ÕùòŽ·wVâ¿Ó&²~ °p}\h§ÂåÝ“ë<- Æ\e!¾Yí¦ý+®H•…ON ¥,|ìây+È“j0Œ^ÕÛ?t¿¼ ÒÂåebßbSÔÄ€ÏñÀVÜ`ÈoisY8à5¡Á°×åÝÎAôNè,ŽDTBn;Œ…X^ ‘a†B<<·Ó»ß…9ÀdåŦ¢pâùTs‡Ì¦œ¶5É2H…„3ʵ,|Ô»±,üÙÝ%’pdݼ‘Þ %áóü’lÍÅÄÚ SYÇ€ÏñÀê[H8Õô4øTb ê$ìU¤…;' |ßÞdĺ/Nú”…yV¸àØò=sÖ1ïÿšÏMrƒ¼ (1bÉc$ÄSó¥)¨iö¼69–,¦™ø ÕX8Nï™…ì‘`6…1Ön{²ø5â„SYÈóq­ ×¼8É äŠakIfX8=ñ }Ó¬?ñ®±îµ@î"-Ø&TAxàŸ~‡„…µ­ä«°öYပ±0…œ®« äœúÎgQÖs¡JšG—–`‚ͨ]Þ­]áã#Ÿ×&¼Q3â†ÏTÖ¸•´Øw^b©M!èTe½•õöÓœipOoý1ϕګÂBQØË¥]ÞÿXZš™ÝÝÌ¡ro’TÖýkam‚.Ca6ñ¯9¶Ô4|…ü×ïÖE¡€Â|„̱“îâŸg…áùgò#Ûœ" ‡¥b]ýMff·ÖË'áÆÊ0ÕÒðA¸‚°`UøéRò„…T»lÇPváÒ+ÕŽ7\Ân'È]üžÌÙ ëÆæý1%}œ'…|—  ëJ¬]nŸ© ¿‚«scÀ7ÝöÇØ,ñƒáUaVVì6\¬ØyæçŸÇ:á”Á.ï°Qr,°……QaL}lSêûC_½½n…`» >²l =õùî0ì4*ÜC|(}_Ô1ËÛ³ŽóÎdᙿ¢°°?Æ/©Ö„µØ÷‚¬ÕÓ‚B$ªß g)Í\ðð/d¾Ÿˆ + Y?eE!luR8ñØÛ“ ~…'úŠBü*›_!û+ qZ¡$Ķ՜i¶ÔLj»‰óa„ë@ÂÇ °°>îWfUáEÂ^ëã>£Â…ÕÓêÑ…s“ö²pæªFYÈ#ªÆ+俽–&BŠ•ÖWã“Äsbs¼<_·›;T<ëÍ•„뮢JÂ‹ÏøIµ›»|jÂ~{Ö cïÇ&YVÈ©ªZNKl³5 þ.‚±÷YØ™TŠÂNBšÊ© ªM¿oP8®î^ÉSÄÝ“¸vã ½~áàÉÂK4A„ÝPÒÄ9áˆ_a·°.Ô„H'EáÆ"KûŒÝñ‰Ãó¥Á±œI Ÿ„ §™k+ Qj« äêÛ’º&),¬LVìZ„ŸÎu¯@i†lÅ0phtãÕÝÂê ¤7ô ñ‰ì;“Ê·uà»W÷mí…¬¤™9ZMXˆô¶š° Ñá[‹Â#¯Lžø ( qá­(\ñÏòþ8žšœ.óÇ……ãŽN6(ÄWÈPXˆ=.¤;aï¢ \ð¦ Üæ8&Ìž4èc!ÏDš+ÂçB|7ï5ÇEá•q7,¨dNœyGGSXGÍY0neíÝ â¸C‹BìæmPˆ“2kñÓlE!ö~FBÖmj<á\IûcnÜ´?öÞô²0 ·AávbïfƒÂJÄ ؤ0{1Œûa˜%…YH3á9F{QÈ~ïbaE\û÷Ýq¡¡,¬¹ùwZš`‘ª,ÌBš£ù‰c]»4‰(Äÿ’{XgM!"†BÎ,Qâ‹Ó®¤É%á±±\^9ø$é»UGsq0Û¶N8‡pfÍ‘žqâ`bä2š>5á‰,ã >FîpýM͇‡=ßéI»ãiª€3 „,w³í1š…ꤰPV„49≿6JÂÊÎß%á†y#!ËluiR( Gº) ÏÂÒdŸ ®4W‹‡Å¬V…ÜXƒŒO5*dcSWgƒ®±0*<ƒQáöÓ˜×ÇøIµ¢ÄmvþÓ³B×iØÉµuC7è¢Ï÷­ùIa¸àgðÆ¨°piÂ÷` Cö÷âþꆒ&£0/M Ið+H„±$\üfYI¸ãWÂ[Q‰d’Â…ïɵ*<9Ô¶Çø+YYXH@æ\kÏ5É$ð£aÛãמ4“'Í4â÷Á»cl}„lÔkeaæ Îzî +íñU®XbÙ¨°ÓÊ„U¢¶2ÉÝ1ß©*ßšu÷„ø<²îS ‚¶úÉs_›ã´=þyN˜Ç„ºB˜OáÌš0!§Ðؘ5”ƒ¸DU캩íqòñÿyyLß-åà‘+Âu‡s9!Ú[ßaÁ²•]änÝ™àGLÛã*ßéê¥òÊ„QiÄ­J«Š†¯ÿlH˜LpTÖ\>3æ’z0‡;ñ!µÆXzñ¿e!ÿŒnޱ%i‚_Ï'ɼÊÁ‘žîTØ— EŒZ0l…ÌÏ ¿[¶<·ÇÓ§?ú+F9aÞO¥<“ÄÁljIιã+°;ÌÙÇO$¾¯\88[8ÈFNíáŠõ²„¨cÓ)a¶`àƒ²öÝñ€­VsIÈò4c!>‘L[E4u ÙN ­ Ç‚ŠfùÍPîì8jE!þJ6%ÄÉ“™bQ㎭yg²âÛ*,œ?S)^±° (,H«q¶â0Ì5!²Ç`ˆzÞ[;“¨­¾^ä^0ìí4Ì|«©E!’¥†¼[7bͧ0D9ŽÂW±7Æ„¹.ܲ¢¯ÀÚëB¬‹”…l÷ge!þ§¬,Ì.þ××"g~>BOrQˆ{2»1ÁžBAX™N؉›G!~Pµ(<Î×)wóò«j!W|M œ6!Ê ìuc²óA§‚°×”°Oșçº9f½ªmŽssü$¢\1Èñãr)È7?3 '&G!~Ão°ÙráÏ(Yõc‹ã …eÂÁuěݟœ:¤‹ãë³+B|׃8b6¬hÜŒ&‹ w\u+?%™/88D3š ŸÆA>)6,üéŸñµq§îxçØ®Ã•e2l|$ äKN+q<£dK)ã`ŽuBAyra;£ÌÛD®µâ Â=G™¬'–MÂdZý3ñã ä拓ð …Ó“’peÿ]E!Öº¦«.XµÎ¸ê7=!Žvµ7^¦tv3î&~p q©â(,Ô„ø(ñš°SÆÝÎ.;^öÚ˜ôÑÐl|Aò•†cņû"8Œ†(é±`§ìÀP@aV:cü* CB,­Ì½¹l äª[@#Ößm³i>PFéæ„øˆT r§n64H&/󄽸Í|! §ÏD¾WŒBB¾ø7 ò›n,¸â[êšna–U?¹Iû>K.,å„3 UÛ!ˆü7r’B0¯KqwÒí2q„o%aAT½cÙè$Œ œxЍá†ëeáÊ|mŸhÜ’ ßSe!O×……Ûõ®âóZ ÂlÝÏÛ6iDÓí&NÚóaeWR Ï$dõÚ-Çê(©~8`öa§Í1K …–vÇê½ph7ŽŽq7h›ã’Mf!~Ó…ÞE Ùªµ;ÞØUÐYX®l)¬,Äÿ˜Ý—L|W¤,Ü9½ÀXˆ¢s­Frx¼]. yj«0ŒbÂésGýŠ…qoÌùË&¢aY”±0û´òM¨³°“¬šõ^6'ÄÅ·±pdÏ7e!+­*Ì$äq‡’ÿª/$<†Š†ËÏ—vOÂíDN˜×ÆØñRr*²uÇ8è0â¶W9È+þ_q0gÏú)s½w…ƒ þŒÉªQ‚l ä]ÏKpάSÂ5º/ ÑŠfB ‘ÿFBŠ Ù™Âõ„½ªÂ5Æ|®?o¾/þOÖ…„üë4£ðàH¢ÆÕñÉžß:$ÄoÄþ8Ú¡æÜíxY©&Ù±zãM¶¡0ƒpáQ¶pÁ¦LI¸Œ…“Çå‹c>èð@§‚–°`ÓÊvQîXM¾p÷¤«ÎÑv,Ê0r•ßLB¦œ“°WÌ'G— ¶–ø6n8±šðžƒ×¿RYçsã,$<Ñ®åŽ!Wâ7Ø8È 6&Œ¢êíÉVØ6Ç…’¯èLBƒƒ;3äz’Ûª5áVò^à:_Iˆå®’«]/ ó¥»7*·íõâxýiŽ œñõ3'šŠ÷BžòdÁ7&\Zwî:¾bpFeÕ÷ÕƒÑwaÜØ½Ð†„ø3ÂÁƒ†LQíª±Àh·íÇݳ0zа÷±uÆ…T;0{=#LV~Øâ˜}”ƒgAJøÄsP  Wø¶9Æ_È:c|¿Ì %ÊV&_šñÂt,¯oKÖBÀ'gOYÔ1Þå:³”ÉÞ´9>ž4VÒgõÛHÈ~‚Bƒá7ǽKÁ£:$Ì›ãsít[’Ïìø*ù ׇD)‘pçׯHX¸-á¼m%á<á2IH¸l)*šëû…-¤ ð î·„…;†yE˜ýªŸär “ªúñGgÂéJµå´bG+$\ÙçÇI˜•„+Ö:Æaµ’o…¬bvæÕ1ëä… §Ä ŽS.{ ·'Eá‰Õµ¡ß0EᎃKCaòãú…yRøéÖö …QW½âׯPÈ(ü SßÙ,ÞĄݎíúL ÷œúÎÇœ­>hæ O”¾rpD€ÝØ—Ð c,T„,^Ó’uLÆAìÙ|L˜ 烷æZb±býñÄVð ÂǺ6&d=€€pÇŰ‚}㔃éÖî±0Ág­rðÓ²ëãîxCoã _¨ñ£!D›Ã`¯Íñã=ב/ñ¿­"ä\@£ Ç·jªñacd›r0,ŽÇŠºSâ{¡5Î!{^Ûº¤°/Ù8ÂÑ Â\ÎØˆj=8á×FëÁqfjåàÕ@ç9!‹àƒ¸€W³# äÿ–oŽ£AëE4côãb(!¾ÈB>AQVDÕøßº…BüŒ) »„ø ½±:Žû’‘ï8›í*‹cEáÇ?—„P˜E4…• Nb„øé2òs_HøÄ¼PQ¸¡6HQÈgmÖo…Ä÷}à:MPx°'‚£0­L®®ƒÏã…ø²ÞçÌŠÂóxmMx¡0úqm9às-ù/äÖx*å{ö* ÙáÞzc|Cï eûÍ(<9»SVÇìMßÞs‘å;®GKNLŽ'.lí(ÌSB^©( Ù O·Ç…š°B>4°a–UOò´„ÓÆÇÔZ|"n5!¾ B6 ´šµ/ÖãŸo5!~Õˆf ^Õk!Û“Ë|×ÐTj ‚¬ºÓuÉÁÁˆÁn®„=(8±×²yUcûÜ ÁÊ®$Õƒ3gKkã‚„&+ §d¼pQÿn›æz퓃ÛÀ1ÒŠÁu&ŠA>°µñ“˜Åà“„/«QÞçÌ ÇÛˆh=Èõ¹µÆÑŸu£ª:'{nøw{k\а¼J=h*Î 8¹µ+Áo—/üHåàï­Ç_ƒ°h—¼ª„l}ò…„ Ïœ¼3îDÂ\â>Å–ÆñÎîaö]`Ÿ#!~³¼ Äò‚0 7£qY²Ï¬!õ­q!vm¶4ÆzØ@˜²K D„6ÆŸº»W ŒKã '?/)p0:´Ø«)ò¦¤£aŸ¦xÃßÇûq‘Ûn?ƒŽŸŽÁtYRÁà€µò0;ôTh¾,‰~ýû„„³•1®U}e\(Yõ¯å vé Á½e·=éê¼Ì*Â=žØ+Žþ¼Ìö¬œ¬ü iEÁhÄÅî^ò9æP³ì*>Õ½ÕØcñ#ö}‡% ^jØt·M76%9iê™à@ó a¡5¦ßæŽM$!Úá( ×ìS½ÏX£ 9¦ÎV%ùÈnå`aáÉíóWNWiÅn@ZnüY®ü¦ªŒË]•Œ(ÿŽ>‘­"ćÿîç¶¼6%¼Xhظ×XX¸7æG`sÄ1ì–ñB<7~¬¤÷‘S™­$¬XÐÒì*ò™ÂŒ«F“SWd„…=IÁw!wÆþ3 B™9²L;cž# Ÿd)á#ùIqþ•„ãñpÕK$<ìí„'~|ìÌ.uÆ'æ*G¬ö”‚ü P .k¤`²œÓ(Èw“ŠAþb)±÷tãN&Õ|¼cÚ„î÷q°°/Jaæ >¬[åÔONVVLº„8¿WòþÌ&„øvÚ„'¬ZrÞŸÙÙ[9¸^ŸÕØ?JøxXr…Ã’_$%áÆoca¾7æC eáçQÈ æ\Ï#‡Ù­ü"7²p:y¿ÿ¦ ÷#Ž §}ßYɈqË&¨Æï{ó”°ó¾à´[¥3Øè²dÂ6ò,P®¡,Üð£ìâ™lØÏÁJ6',Èg¶'4ÚŸ1Ñn·Íe…sÁzáà°V%!Î_”„sv ¹zã¼6æ¤r!áUé'EuŽqâÍ÷ÆH9#ažX龫;~â¬,ìÕwšârÔZYdÓhÆu°s“_—¤Åñ̩ն8ƇR; Y/­×%™…'¦´.ÄÇêBìE­?fë&aáÎën« |J œÃ/³Àðœ uáÉÉ6)Œ[“Ƕ#ÓpÂ÷õ+ 7íáÐnÿØ?=^Ñ0úМ•™-7Œ†ALøØšàÞCŽ{õÈø=>™˜Ý!š{4Ãp͉ï¼#m‡áQ¹9ƉÒ0ùöÿLÃ>ž\øÍ>¹KVæòŒU†QW½q.—ÁpÂWÐ`ˆ ©°pOÞå+ ׂmÿÉùòÆB6Ø´°0.DÉŽ¢pD|+ ç--‡hCÃq¤ŽÂ\²…Šé qLê…a/²=“íM°xüÆ“|jÇñí>4•[»´?žøjû=ual‘'Öó¸p-ØUo|i $,´Èû„g·N¸?žÇ‚ ͹ð³ß@ØAI³?v=QIóÈªÏ Ä‚vÈc4_ÈážÖçÂ,¬æ!–™ÐàÏxMØ+À„?ó¶8ÁÑÉ7J« ä‰uÓVæ+6”²#“äMø¤ßRb tƒ„æ#¶¬´ 2ŽË¼CŽ›“«(̆\Û‚.¾9‰!&Ó˺²@Ωvǘ7âcG‹B¦ Ñ®[Ç…~V†GH}_ ùžl\åÇvùê¸ÃÊæÿ[w`ÈŸV;3ù-«Bì†OÖnêÀÀžoÜèÄ1FC:ªM4­çN»“ òΧ®Bãpy¼dõö$ Áhˆ§!~z”†ÛÂÚÅáÎÓÃ!"Êzäx{üx(”…¸#6ÆqáñùPyJÃå§)®‘Oüu…†?þ†¬0ûþÂò„>η¢í ,DéÉ÷†ì%f{ä’¤&³pÁžÓÓíðØKXˆŸd« ûh qY¯»“#W†'òIXx Xõ4‹¬7¶ò&‡BÊÂqˆ…Ó|l<÷Ð6yd× Ÿædö¡Ð>9œŒüY›ÎNÔ~mGs¡0ÚÑœøÕ2Î+(ÄÚû=…| íUa/Ïê ñ!j$,„ó§«™„Ü yw)=r6æêdQÈF¬ºDÎ×&…2[M»Uk¡&d«:­ yÈn5!«€”ƒÛÄ+!åàÌ:aå Y‹Œ³5ã Ät‡rß+äàFsqp^[V/…p;œÈ ŸL¬½?ŽäÊAöœ´Qa*'³™²°Oî;G”èýq¡ ä/ž€k}k‚M’‚— Â3>@ÈΨ ÂÇä;Î ÏÇx ƒwaÂkTáÄBa2­Ÿ´ÚŸg$aVâÀÃPXæ{“ ë=Ï1é¶@®¨¬qÀù.™uøJ ùÖCüÀû 9/N°^±Ya§2Žš­?N7'Û“³'Ûœàê~­…º«|ë[Ìñ¤‚Ãu¿Øi¸ñ×Yi8ãÌliÒæd$ûF›ÂqŽBëGÈH>9ùÔl½Âa–"Y¼2,èi 8äÑ·g™tª ˜êô°½èu†\¡a. YOª4älÖvVœi²žg ÊB|ÓÛQˆ/Ÿ9W'gš …8²Ê°@B˜©¬¹YRrX•O £cë´-cÁ±õ* c˜ÉY!›9ZŒ’I!Ö|Ö ãÀBëÂ}|mTx0­çV„‡V8 =2½Lº¦˜õ¹<1ì{ÏÅÉŒëXK¸Ë³B>Ej!þÆÞ#§‹“±Rò.ÿFU5ÖÚä'yÞ#g>1æÔ¢°ëtL…y<ÙCPä ºä4bÃp†ØT Wþ`¼……3~¾”…ìüm,ıœW…9Ë„ …ie<ðUYˆ_ˆ,,œ'šÇ”0‡Ûq†‹uÇØ¬›šš·‡vWR9+Á2õWæ„Ñ‚æÑÇl»sFòøÒ8ľ_íqÅ¿ŽÙv×ç°à»°ÍIM³íΜóy>ñz¿A•>ýožHØ«?î£"¼ÊB,çLM]ÐÎàWÇüû ÇØEAáþ$@ÊPØÇ‚&£pÆÅOì" W” ÙÍL«BßÚÊ„ض2ÁÏ»¢pxbÎû+MÖSOø¾ÛÞ˜o„……»’‚a5Ëì®dM$âÖøÀ–ßHXÈtªã§ç]çÆüݲ’°Wô;ökc|ôYAÈÛ¸f VÄ3+ް¾bð Mí¨ÇÎA”Ó}å «É„ƒì^d¶„…«¬4/LÖ;_ky‰hƒB|>j¤Óõfàû¥ÝñÈ{'æ˜Ï(¦~¤˜ðnO»ãBÞñ/‘ dK8'Œ œ¶™= ƒçð>&Œ–„ÇÍ1¾FÞç1!Ÿ£Ù˜pN¦„9Ü'çÞ®Jp¶à,hhz„9Ùnïç?S1㊊êq*lL8QÌ7&9Á„W^ÿ™ýIDž¡°âÆ•kBü……x#k"ü„ù˜0/Ÿ¤a) Y{fVÕ(u ›†KQx޼þÕö8®LŽƒMw•…øb +“¹âÜ­‡µÇ{l³ °0'D¹¯³FYˆ£ž÷°­S …xDö.Æåñ8| wš´—„…Sã˜æt‘¥‚FÂJ„I„8Ô¢0‡|byeSBd®Õ„Y' Üx^dÍ1.U¬9FË;ž£ ׃X¯(7Ô훬š#(TNX¸-™£+áÀï˜V„ŸXyEÁ,'ÄwË1XU' >dÕ M·½qŒ÷ÜÙ\ô]Ë’ì<3²µZ.T2í áWUç1!?MDC¿rý¾”ƒ9ø}Áÿ’5Ç8%3"¹Ý{&O ·‚aÿ¶¡1ƒU„¸Ñæx|ëª$\Qô¤ ä+a!§’*·Ê‘6‰¦&ÄÃ#ᖎ솼8Æ ˜$4Ø+(ñ¥y ·ìG¸³'Ó›$4•½q¾³cÄ7W„<îP&ï™ „øá1öY—`å$ Üð÷µc゚pÅS o£ ׺ãƒÖ“KÐLÈýq¶ù«\Ḛ°’tÌ7E!âÉŒ°á2bo5!v‰j¼¬YçŸæŒB|š°ÿ¦½qÉšµWwœ ÷nF\ÆS»­"l]RÐäÌ÷­¤  Çû“ë#3^¸+&Îí|¦ +܆°!¿3¬ ðÃŽëUð{îLɧ¹3V Ê‚#x\,HFTsxƒXÈ1b‘ÖE•€Ë~»ÓB‹ø›š“ÒË[Ä|o6óqnóÁYÎú]ñmW9nÌÝŒª x~cþ)ø<òµgnìø)bIäø=×{ÿå‰ÌFa€Ÿe‡1WOÏåõñé\ÉwÄnÕ¯O W•v[º~0ÈÑß_ºß°IÂå³Óe%œȟÆ;ƒG‘]ÛWìLy^4áÀ»Ò&é0ˆG¬šÌˆÿ)¿À¶0ñ6pL› eÑþ1±^ÚîÕéLŸË+Äé1º*8ÈmCIkßé6ïzE8dð¸M—h…Fa¨ŒLâôø|ëâÓã¤'xòŸRô`Á†žäÞ'äíWeÖq ·š_áïü+ŒÂð•Åý‘6 Ÿù³¯X®±¹|µ8—Êô´€‚RˆA§³›kF÷çéD‚Â" % Ö%°*M Éh¶çáÐ%%› xùªmö>Í}ÂŒ_™Æ:¹O8Ð6ƽd±ýñ¡§Ý¨F‡½éì<%³àófë b¤Éˆ4õbAhÈ÷™:@¬ô ܫϬ®yr‘õ& _œNÙqUG(ïjß*³/²w ihpuÙÈ/ŸÜÔÎX@N+l©ª8Àf_q0qð‰ààáÒ™ _ž„3¨Ù3~½Ÿ©¯p“=Fùj_AÃAÞ­ŽXº{ p'ÓúÍ+™ãÄOuš­ZŽ‚‰éŠÏ­¯@ØŸÌÌ5½KqPØ(ìB×Éå¼Ê†¶sV\Z>ëb•¯á?=fa§ˆÑÎxž°v2°Mg®ê€Oõ½Êƒk;MÅèÛx0løÐ¶nØ­;~Oí"+‹ÎPio¡à•^!uâsÂ…ÂZ·É ÆyÍ có‘v剀Rl¸ÞÑê`"ÒuæÌG~•„¯ á Á>š…Êè—)wpÕw>;}W·P˜– C)í¦O»°àï£<@ÈYuPqr˃Ä=ìç=±+.6,h {ó(ž°Úì Ò€ïâu¥ðé}ÿŠéDqf ;£ßa·ù|?ü{ “ÏÄ1âÆ¶w± ª 0 °ik® ^+°Ü±ûÄèÝ3á'½¹OQkm}ÎÝ-¦G Và÷×I-"–‰-"Œ|g¥…AÞ(ŒëùúBoΖÿ3o.¼0¨x]ç>rßUàgY`°ppÇ›¤G¹0¸Þ4løm<â žÿ8f5Qvnúˆ¸—7Ïüã.'¬0(·/œÔ¬<˜?°›pä­ïBL–¼D$µÁ<ã³Ø‚y!e<ȆS;ãÎTîð Û¸¬¬±|Ü ‚ƒs°¹¼P“²ìA•ª £€‹NC~0nu y›0sÌé»¶ A”|Ñ€mlÞZì•©ŽW•üyWtÙ.8t·Â àÂÁGìÞ%d±Á’eˆËõ+Ôy·È‘«JƒsLRƒ!](Ì<½ág3n¥Á\8ãîWÌùvqä©û›š„àhqÁ/½•8Hk½]Ü"Ã\D?‹ zV^ÀYmm»Yå㛄|®´°¼^›„íÜ#ËAm²¥ÃU=¤]BtÀž9;ÒdˆØ°´Ã€umƒ^:Ä_dc~µÞdà ÿÊ NmjŸnì×góÜ€Ó7ìVVç ¶EšŠƒ­€ƒ »xpª¯ËsÖ; ˜ì[ ¥Á2¦F!º@Ï| g4ÀrúF£P zéÖíb\-^\þ Y4Gó#Þ ^( “p b¾UʧJ8’jo²ý¶áWØP€§y†ÄŽKñsª‡ÌHäaC‘KZ,>VCslâ"ÍoŒ%Nu‘€Ÿ?GA¯º€§@_Q0õsÿĬz;cîŸó#œ%o¸¼ogÁÁæ\¦@LŠ£ Ñþsšºô Ÿ´Ze€n¤k‘+~è&\K(¦'•“n+F™)TûzKÇàýv!Þ.²¾ÕŽÙ×´5*g­ˆŽpåu‹è'¦<èfŒ^˜ Ò[Þ<3X¸¨lpáä²£ rm€ç×JQv´íˆ8ûʲ£™O[YŽ|±€¯¼•¸Øñ;æ8AÜ?£7_± ß.bKg,`ÿ’Vl88uô²8Éjä‹ô·¿Ë7o†|É<°Ûá °·µÒ àxT Aû³ ØÞ/™ ꉌ#>Úô”ùdckÃî_Ýâ$F¦ìkE[Ø™Û:ÃA‡ÓÅ ÄnöØ…b/bÉÖ VÛôY£€%l«ßÑ£ÖË0˜“¯Á1°c” î†Gé©>|­êÆÖYȾ•6A°GÒÚ`ç9™û|¤“ßу1ÔÓOS^(à[nƒ>7ûìˆw/:áàÄFËgˆ¿á©¶«V°4UyÀFÒÍDV™+ð1ª8Ènˆ¸Um/ ð?äÊ£ŠûY¡OÈ,˜±ÑÒmÂ\) FÔuö¡Â‚ëïz]\,ˆ× #öŒ•ë4{5T–‹8Ä~ ¦~îgd℟xÓ#ãÈâ Ò) †ÚŠƒl”Ì2ôöêãAž<9¤Q°…½v ì ú«â ‡4rʬÛDœáZiÊ^ˆ,š¿Árw½[ÌÑŠÜ©ÞÒegÔëEþ ç8£P̱ÁŽO®vQr!IgN+…c¨x!ö±M§Ñ* *$(%Œ…ô”ëg2 ¶ŒÀps£B\žmëÒq¼"Ô °ÖkGÁT²>ìu¤T* º%±W ¥A¾K8JÚCì8sÁ9&&<ôF¹4èRìøŒµÂÃAq€-›{á:ÔpP¹^Æ>Iq°-¯=M.äëål}¸ð§ë* Ì(ݼUD—t‡|ßõ2 âmnP9^Î0à¥Ã Í Æ'§úÜ[4Óà†H–Ý vò~¤„c=ïØ4Út9fqÆoŽ&L‰ùz™k4àW°ý0¡rÀÜ«OÀÈû„ßеPl%ò“ÄöæFã•ýf1ß),Ò+¶&‘þ¾>EÌWJ¥a4È,Xð¯ò0öÊ:¡ ?œ ¾&û’fÙ#Ã,ïèCäêcf€Ÿ-‡A/Wdô¦6ü–¢£äƒº<1ðûå>f[ÅØ$M¯ÏONOá…r{£€Ó‡AnNÎV52¯¥½4ˆ†gËõù)ô …ÊwàǘǂC:¿WFÎI2äÊ`ÂÖiÐIuT ÁÆ÷¥ï¢AˆV{пŪ3`‘Jse€sw?̪£¬3ÏR\B¢Á1¢Ê…ŸrfSäõÄ+z_0â/¤48ðXÂjƒÂsÁÍàê¤^ïÇì„:±.ЇˆDÌX5½kÀû!eþéïš †8öå©À’”ú° ¹ÚE8ây³ËÑŠµ¡  FfßQGAÁåhÀ¿KQ°ÖÒ º#|×u·¸Wä‹ñzùÄi‰Ý&à5úœÝ ºµ ÄÝâøD¥.,˜J)‹Ùþ¥x–¸Jß¿ÖÝâˆß¾f,XÝÛr1ž)®”.äa8pmè»ÅBÄ";ù¸9Ë RpÊøÓ˜n—ç§wΔ =BžÌøŸºƒ‚-¯¯7ë·Ü&äëå£às4a‘Û¾NØxÆc4( riÀ&Í—JKÁ%}ÅÏò€Ó– y¹8 81ÿU—Gˆ"j(L„8Ed¥Aa³È8m¯ *Ä^ãCö³Tà½æ{ꂼWÜ ¹)8®»1<,„%`]e-B\+²L¯k^+.øG)&„›ÝYeZ€OáÀ:}` •r€í\~[„sˆòÂE:¾:V pâ ›¤N; v†¶¡ÿcoBAn…Ù!3导 `jR0?,Œ :•9xyÁg¹±€/5…On]­&À÷SY°òÐÝX€ÿ± ^)g0E³êÌæY¾G( O~Œ…ƒÅ^=Â>`¹ó®q½çƒ<;dûnƒAÉØ¤ 1(° '–4Û¼  v¼‚Vð4Ài€f¥þ:Nôèl[å0}'4-ëW+ Ö×7‹ rÒ*~ÓíN©beÀ·LJ,šÞs§Ä97ƒ^z#zË YnÄi΂ŠÄ ÀÞ­ÙaBÊK˜>¢Ä€_ͳÃ?¦Ê‚¢Þ%äÊàIH¯Æ.ó/$,ØÙ€ÍPÀ!šºœ÷Ÿ7º¯PsVs ÚZ’²|EPÀ¹<Ž‚^tìÜZ_aðDW¨KÅ>ƒÂ‰R4Aø£®=BÛÃKr!ÁÁÔJ‚9ß(­genÈBn­ ÎJÐ*î#Œ·³OíÎ+ÄkÅ(³G¯  5Â/Œ·}6Š;›µøä°*ã‚le°qü®.*' øœÑiw}VD°³ŸêK—Ë9D ‹EeÁ˜ï÷ rlÊÄ“ó>Í è¿`,@žê¼`Þc‡Ô󈕴±€Ë*…æ( *ùë¿ác#ïÀ ”€ºÌv©¢»}¡ÈVk¢ÚÄv÷v‘ÐEkÄ·Â,™ (G5çCTù ؈]hððÊæèö—Fœ)˜ÖhN•AôAÍÓ‚ãÇp΂à‚ú˜ngütÝ) ðÓ.,x2@»ú‡A–°õ‚Ë *¥A§EBìæTª *kÅ$B>üô( °ú². F…ÁT09šÔß) vþ„ XT"0Øñ5üƒëKú™'÷ ñXqÌj££bx†eœ p;b•A'°¦\딂; ÐQY@?Ò:9ŸÄ쩼€Uj7„Fž˜‡6ÖÍç{ÎL9°ì4 ‘'ì v¬í…çÊàJ‚³pª¸'{£‹Ÿ¦/¯HOù/÷ àiÂŃ¢Ÿ^ô1?ÜžTÚÈ'ÆïZ$D¹Ñ8!P¼„ºqžT8\Žþ‡ó“À0û7'* ®¿Œìê«D((ޏÆÐÒ`fA¸»CÂ7¼Ú'|Š…^!ª xóo@À#0B!²‡›w·w€€@w5éÕ)Txl‘ÏB;›…ߘTÏÒñjòØ K`Âqâ|Ðö Yr׊'sq° øÛx›€7Ÿ æ™ëÜ[/—³E:gm ŽÂår9EiÆ9ÑðŽÎPÐmhPØ+¦$¥Šùxäåô±8â› ?]NJ%Œ¥Ò Áàœæ(F>°sñÝb65á{ÅÁÊ+Þ¯8X†‰m„}·—‹g0 Öã|¡3X~§‚*Ç÷Î|òµâ€u㆜ZÝÁ²º«I§N7Mí8àÎ×fˆì—Ú|¯¸ó¡Žâ¿9Šƒði’¸Œ;¯ã„çó”&¾¯ÒfaØ^4 ?Ó`Š̼i ü´i§ÁR¡¶·hPˆQÁ¢ðN·PØ+pÀ‹gij±«àFÅ«ƒtÀ¼ðYÐå<ád)¶ðàú|UªƒBûŠõžW18á*2J‚¬R•s$nûòbÇø â 3Çu ƒÄeiʃµ¶ˆ°{§‹…~Kˆ÷Ü.fQ2o4}ÌM¸1iµ=Ë;¬ÚYðÄñ+ †½Â‚ìy¶­F:9XذÌz…B’ o`ÞÞim°ò¡·ióà `v´-¯2Ö~ÁAÜ1®ˆ&ÿ€†ƒ¬FdŽ—½Dã³^k%TQóõbÉâ$ïXln¦YqÀAê8(9¢Æ#?ùë²UpÀŸTÅ[b(ÔŽ*Î'Öp&BÂ÷K˃œ°}æÈ¼âAÜ3.¨Ü¶Å[Lò¥BAq€UîàÛð¦>§ÐÍ ¤Š[:·áíWK؆{£ æt¶1”b•ò-ó–i°¸{pd°·¶Šö˜Ë¾ŒsÅ5_0NVFÊ‚‚xÉ*Se˸ðŽLP¸WX&Œ óê Áºó¦@@¬^I!BÔ°_©×Ï7ˆPèð1znÚKív©„‚äûg;V@†:Ý4– 36ŠƒÂIsÇô Û(íÖ­"9`w.ƒA¡:*>F,¬ùO3äò`û\¾€A6Ge ?cÌv'%flMîЀs°Þ£P>p Û¡À:åA骹bx’gìÐÛ¬9ÀM[û {­®ò¼Rd w­îƒ†U(o8mT ¬¬#Ñã%ìM\s‰c¼k^ðèÈ€Àz•f àXÅyÐg’¸øõ5c§v—@íåÁ–\åA)j-×;.·Œ©<¸ê«ìÎç9í‘*O\¾ðà*<(…Pæ…Ãß~µgÌ<à­¦Ùôd;¦Ô-ŒñºyÎ>çÒòpZf@è–Ð^‘ urFä¾Ö(…qeñ–•~Ÿ76MÌýÂû……åÖ0ô8f<9¶Mxp%0 mœ˜5‰KöL^¦ámzP\;ñÄÒx°§yb¶Pç„PãAŸ~¡„ƒ^†h™[·n¿~^DÒÈR.Å{cÝ8`â±µ Ixððk‰8è®®si·€}¸5 ØÏ[³°âÜ[›…ÿx« ðE¶^%¯&BšÒ®±` Ž¿‹±€M ÚaP¸nîæŽ8åëæýgù7hPñG̉kSi·PÑàYipV†‰¸í6áA„Þǵß6ã·ØjƒÒ0‘Õ˜vÝ\™àÇPqp4‰Ÿ—(ð¦8˜â1cÁ-5§«œ¼^ös…œ´t z|vЫ6ˆ¶'{¯ë¥Òä /M+‹õ˜?9Æ‚$P~¸{g{Äç£vÚœEHX5ø¼Ba°UÖŒ›z™-Z(O+~Aø mOT8ïvÌøKEó‚CñÀÐÉA…©S¸xÀ~@ƃ|°€ß »nî‘ÂxÌO²–þš×`©ð pÜÌÊO+øžCy°pýi<à÷Ô±:8>mÚ^ñ 3ìRqtu£6¨Ð S 㥠+”;Á pÙ§ˆÓ“ìmøÚ±½8À¡œÁ i&n‹µ4À§M3 øjK— c©Qà3;phŸ²€l~UŽYk¢,ÀCkƒsOƒƒì¤^¸V¨˜'Wîš9}RaÀïúÒ Ç0®<¿³S¨X©gÍÁΡ ‚ƒ'fíµAÁè€ëFsEË©¬sŸ-ã„¿±mϸJ³hV°éVaÅñ‚aä¬Oß2æ´öÿ|˜U(˜ ì•üµðƒjDÀgÛ­f¡àƒ„Ýñ"€·Œ;>LGµWv…-#Ž×M•›Öö߈`‹Â~•Ëp÷ OBCÕRýxL!ñ[j½B4BÚ>{ñW8ˆ‹…Ø+ì¬ìwäl^=X¯Ð«8ˆlK7Á®*}n/›¯â [¦â–ÛQ€?£µ[Š ò½–*ïÈhžpü§¥ÁT1Aâ%‡e°ÊO”ýÊ‚¡Ä‚¹B¼eÜ?‰òŠùœ§ÔžÆX8gdsT,ÑðK|knÏV^ßÁAÁA9¯F˜ró¥ÇYd¡2ˆ‚ƒ•_AÅÁÖÅøä³ÒY2BØRx°sPÏ#Ží 0… Á-nksT_Ó–qˆ¼ËmÏd¬Tgi’ØO‚T þewöŒTí½GƒÄ4­’ÄóKo#BàÁÆÿˆò`Âç@û^KƃÊ^aBñ±ò€—š^àWÝë^¼èè€Cv”ØÕ*¦ãE*ãѱ`¡Ìï–ñ€kËæ á,t ýFø3o&b«ÙÝ> ,0LX€:°UdÝÁˆÕ£¿8 „>»…ÿåÁyx0ò Lë¾~kçÁÌæÖ/Wöl”¸[âA6QžðÕ1àG¹ÕDyüÀóð÷à`¯Ä·#æÞ4=ÀGi0âÃÖhP˜ÚÞ« Ò5ãÆ#fGÛ“—òñÜ kžù* Xôٞö?¹õTàWBIåˆû9W ü˜1°b£½.(LzÙœ¸R·²?^oºkÆ«'º‚‚þ(2>Ê‚ ЗBQõG#n{Ûož/}#V¶Yj0(8$NgÞ)OnãœyÅÈ zÓœ/bZáAŽiE+AáÁ“¿©}ÅÈë1çA/å’è ÓØ÷7*ƒB¯§Û+ƒÂ!#Ç}åÁõð‹‡ŒãØepp²Ÿ™c;' ÖÂ’qÚ°ˆÕFacN$æÁ×+ „}Š@ˆ—Œü0 ”,”+Bå|‰þî[BÅú¤ÓõvR탃a„J¼BßzPB cQÙ΄¥jöÂeóÆ_cã.LŒcÎb&Ðx1,¶éµƒòXpPpDh<¨…+@àÑú{üÔÙK…ÁAŸdÆ}ÁÚ«ƒµàs€_Ò@À¡Éc¾Â©ê[€Àz3E«aÏÆ'+¯þØtèqewQ›#rUhõA>Y8BR똔'þ€™ð+µ@¨œ,àîáÞ ±üZ´aGd6›ð¾›ô™$b±k@@QŠÎxl.¤ÉÜ><(¡r±ÀCçA¾mx¨ÊËÖ5¾WÈ2$Ž,µYb¢A’Lü1ð'§™•´•^ù 'nK„O’q˱´q€¯ù©W S³ó ÞW b†ûVjº¤±]­¨N>–ÊZaǦUa€²2cÁŽƒ0g>ÿœy¯0š…9 ­&V» *á ¬S`Õôžp…Šia¡ýôðRŸØ„ÙXÐ%{édïZïòЧï¦@êÀ‚e๊¹ U戜˜®,à€BƒëÔJ}¯\6óœÂ`Êç¶D¤KFŽ¥7›A7Ã`ÁO»Ó › 1n®UÞDƒ‚{2ûÉZP+«˜[× þ36IÄ?Kq€-¤yžth–aÆrGqP1SßN~ZiÀgñŠƒuû‚ƒyæNÔ Ù£Fq—~ß¿ÂA:dœN|™Ý©27(ð[Þ7é°þrß“.48°ioVôR°kÀâ 0FDÉ”Ò'if{RQÐÏ ®R%Ò`¯œ1ÙK}]¸ËTœXe –G˜k¤ß½ÙÔ Î3 ¢{òtâÃØ¯š+[…,9ÀWæM1lO†mnˆÖGœÌÊ4ÇA'o,EùŠƒ_ ö±Á^X3f¤ý_eµL­´ ‘>@mlP19p&à­BÖ ÜOh«°°Y¥µ …Œ˿/88ecºUˆæÉ Gͨ/5`kã8(Lðï¾ÅƒŠ2Êïð µR¤ë¥ŸS*@ÈåÖ-†-]3î|ð®å¶Í͆Ÿ°±ŒCvH\±öÑ>±}t€5¾$fÑîe¬:S«0ĥ‘ý“·R(c¸Àð¶^©ŒÜ¼¼'¦uÇ%Q;ø\VË|¬78:Õü“±±IbÖà⡱<˜ÏçN¦H, […½¾àà|4ê1wéAƒ‚Ÿ«+ aŠƒ1ä°]8H—ŒÓÏ£Šƒ pû¦PÆŠ>îÀ 2:ˆ ¤«;ÆGB ®xÚ-SJ(#ÂÉfY ŒfTº…¹0;ØøÀ¾]4ŒøõI"Ž…sü^è’q=“"1º'O;¾Y¦Hä£åvTr»5 9yiýè㥾£• á÷V`Ëj“Ä>[ÆJ¶~ÚYq0â©ýZEàƒm/d­l'"×m‚>ùzý¦B^óŒ‚WkXr.(Ȧ'Ç6ŒÑ=yâàh#A%ƒ ·cN‚‚ú¨› ¹Þ&tš (ÍQ+¶óW,ì˜ÖàÔÎ`€¿Ààà…°Êž÷Ü1KG|›1Ž ¢à`Ç_×O— ò#ü†: ·KÝ ,=½0è$LÆ­‹ã *f.©kE™\°J=qØï8ÈÒdÜäÚ­BÄeر&Rœn"ÝK½pªNWšðöÀo³(™ãäÚaPÑ |Ɇ…º r¼yÀîÄʃ£Ô%r7–° F$·‹ñ‘®<Y^¢<ÀG›òàXR› R,›|zX¸Vª”(êvtºe>NlVøÝºÁÜ“8 ç‹|Öª·Ì|ŒÔ.<â¯?Vd à3²8¡P œsEg€¿OónñzÓ³·ÁÈU˜!¶ Ñêƒãáµy™ÙmÎxÀ_­Û„¿ >6è¤J>ðrÕQà³Ä`€_P+𹯵AÅ÷·$_X° œ>c,@‹ Vߣ‘ëVâõ¢£¥â|ôÄÏSYãFa+t ãÆGqÖ-`³n4@. ÆÏØ+Ä[fŽ@òèµ>4(( ºÕ´nJ6uDŸÖ-û)sáDŸGŽƒl{„:}¥ßí›Ð  †MÁTrO?ù.¿-¢ù¼ª‡мàe¢± ‡²[ e}˜ÔïIgÝÓY é • …<8@&; :m¥Àrª(ÀÂéFePp@ã„;g–Æ‚lŸÎ>¡í¥þLû}š hi0UrUXÑahX/+ Îì—<O’¨´OÈÇÌ[g(Ö=–Qm0gâúI7pw ½ÐpVd§ÌXÁÞú„ÂÐ`(è‘9CÝi$ˆÕF+ déQ©4ÈÊ#œÇ Ö±pœp=& 6'…¡ÁЇÞ:4žÐRaÀIzÚ'$£“GhÅ™¦Ù •}úl«À†ÓÍ0(øœ <çÖ ± BÄ÷óNm÷‹…Ú€=†¬M¨T}†+ÎìŒñ’¹‹Ð`X£Ð`©œ&l'§XYr~. rÜÚü_ #ÚiYRUç`Ãk÷³‹ñn‘WàFbo&šKXY€"•[…A>NØXsg‚XÑ æC¥…ãvôR©âÆ6jJƒÂ~‘}(lh€Ò© ؇µy„È¿±í*}Ûƒ»Wr\0®|Hé™kïô‰-qø ³Òàˆ@ˆ—‹î”]ˆX( ðí¹*K§Äö«8(x%#¢Þ„Bq0¡É„aŽ>'??û3øMU à–ÛìQó~±ÏéâžëƒÚz;ëðPàGi°<8öÝa‡ÓaÕl‡ûõ?Ø (Þ½ƒŠ#bŸ\• M´½:ˆ,ñŸ±â @‚ÂР`‡¸â¨Èc£0u YGtºÕ¡Ae‚¸QòÆ#'­ ppì­B!™yâɱ‡36Aœ# ²Ô Û£^0(´ ð÷Ê+ƒN' ¨~¼ØiŠXp@›pWâhTvIkß/bà“ƒÈƒÁÈŠv†ˆg!Gaø×xPèò‚ñêp@héÌ\È)ÐØÆ¤ˆókÔ¡àÊ•¹*BÁã§v^t[*äVaã‘ï àäÉ«ƒ˜º6o|¤–G|d<RÄX±o[…<;È©3¾‚í· ø_Ò£¥¡t«ÀÅ®¿ìºUàü ×&sðŒÇЦMFB™ñµ³Ápþ4ÇÆ%Ÿ-=‰åv äabÁ>}é•ÂÈæÖ¦>êÂÈÕöÉÁ^HRXK8'ŒÕQ"jè Qr0ã«|ã†1ÖÛ\qH°µÓ¥¬EÜqô¢48+±*¬ÿ6àÃlΗ™¬ ²aòŒÃuYê"8`—9§A'`%òo,c8±´Ò€ÏÍ;½¢L.¬²[2_·Z«Q€Oâö)"BG[…¹2Eœ°2o¯ ØlÁõøNx«㙇ûeA=Xõ\k/  [ møéz‹øèÀYڛƕ!"NÓ¬.(L¹Ã¾16¨Ô9b ÷ÆMµ×øÈ²9bÉ 1Ç(p¡§,˜pÜíą́0T.ñ‹£F'çë±ÁƒQq0å¼µšbÞ/rëâ£>0رÅôP•NÚ#üœ: ò‰ÂVÉXBñGÛ9󳵃O AíñDaÞJjƒ,˜K…A…±Ae½8ð£ÍYQ¤?;!¾ô6x °P(x•òÖ ((\(`Qu§.`y¥Ÿ(tò9)ä­±¦ÃL’yî§RƒŠÿY'Q2Z0µZÍ%kƒû„¥"JÞùÜÆÆ…u•¿e`Yî§‹…Tæ8<œâébI’Œ3nƒnQ ¿¥éÑ1WBÚ; JKùDõ¯T¡A¬ $(/æ¡49ÌgÌHÛ;$(Ü*qðµ¶>ñc%¡}á¦ÏƱE8×ç ÄÓÅ ç¡~«T( ,¨™!ö:P`GÎ7©’ñÐaY0òù± Mñ‹îŽG9v±ƒ,@œû$+UNÖ’1êÌ!sf +ÏAôyÄT2Kae7\mR”Êñqýé±Kˆ2vì7O–µÃ›¬wYœðTÔƒ{Á ¢HÎ' #ŸØ)s[ƒ‡)REfPÐa³o@è£;Â"C÷Š+Ñ)lÒ•ODk*IFu€òàúšBÚ+º£¤C¼ªƒ¼øB”ŒØ9 澂oÂ\%Ï[û$¼íút +–4>B̲£±§r”\pÌØšÄÊ–u6CŒÍ~ûn¨’ *ÄRuï88O`°ð–ü+ æs¨lØsLa°$—“ÇØ -ǼLÈ)¬KÉÕ Rà£Æ§½:…¼[Ü?ðÃ~£6ÀªÑYmÓgà›"ÏÛlNžÝ;»ËIFA<^äÙ ä¹Á^Ù&°Ž¥½2˜ò…Â0|à·ËˆynÀº…AŒñt‘Cb¼0¨Œ3 ð!ò&Ç£׆Ƃ>Û„µb”\( žl •ÈÅdkðó¡Ò%ä±A¶5Xx’Û>6ÀBFW‹k%fÅ¿ž¡Ç ÛŽhe0WÚ„'OÁŠä±!âkgƒ âí"çûZiÀËÙVðæð]û^) z©Ž Ik•å"û7*8àFePP-ø8¶B¼Vb¿üÇ Qi0U| vnÒ­6`÷<© Ôˆym€Ì°©Av<Ú²ÏÉ0/#U4ˆZ^Ü p€á4À!µ/Œ’QwzKœ§ˆ×GµS§PX*©ù»®Ï ›§ˆœÇ`<À]¦© Ò£>ÆGù:a>KåA®NF°Kò¥~ ø36DÄ*ÃZ…5© NÉ8T¹á”\à[…ùñ7›œìúú¦ê 07à#3Nïä‡XY)Š|'LpPÚ)ÂãŽq.MWöwÑê ‡/®üQuàñâ€&†ì¡­<ˆÇJcÜ)LØpŠÑ>GÜ+±*¨8»µd¤ïúW¬ÃvmwxÐCpðäÄÝ2–Ò±æy4rRŽâ‰úG!dižº˜%#ªãY9QØøÁ¥³ƒB³0ç{¥Ç 1ã€õŽƒDƒñ©/h0ÄÓÅŸ$6Häozëè`ÇÙ»3÷Z*à·ÏŠüݘ$⢲ýx‘o”mrP¡A.°œiiÇ?\aÀ—Qíµ¶? ƒ­29ØðKl0àPo‡%ë qåÇ×àºÜBUâŽ1›%³ì]h0=¹oi¯ páµA§Sf.®lrÐÉ<}ÅÇp€…‘á€ÝurPY1æ“%N³`æ‚]rÜ1Î,kRÈ­ÂP²=Z0ÜÇñúBp0ø* Ž¥²Wر6ÅÎÅÍmKò£ì˜<à{n8¨Ø Up€$ÇA/4¬xcŸÐµµb{„%ªñÿ[Êþz½§>À*ßfùXÛ¿©q’8 % °4»õˆ1O/d<©Ÿ´<Àc[Û3bš{¤&DÑÁ€_cÃ>hÛq€#h§A/Ñ®õ}Ö kÅèÿx›äd•qÆV´åTáA‚‚WòŒs²æcŸ¹Ápàì]QPJk_xIfÞYȃ mF¹ ’ƒÊñHSÄ!.x…m,ÀžíÆR j‡A/sd²Á€>îwæ…º Z,3t R¡O(œ3ãájóJ ´Ö²`àü³6¨Œ *œÂ* X±á#DšPŽpT«(˜÷tµ4ÄÆ­5l„XIXÂG„u 8 ðýb'Ó£=g,½.W”ÿ57 OþxS#rÔB³âÈUV$iò³£Ý0v‘#'>ÑU›<”ô|’kú£,G… Oqpü4gäÃ¥nõÁQ¹jî56ÈQ g/ët¶†õ±A¦ÁŠ£+J±k¹<` àŸnÍB‚«ÚY€kTä¾6ƬU”üô #þñƒJÌÎ(,ªýõ‚ñ(ø¦¸n±±AÉî¤Si€ïðºTa€uÜcAšŒã$…_É ð[ÜžÕ>a¡ëò£BV{#v '>AkÉøÖ*°WŽl¹|ÐÂñäõ±Ë¥ŒÞp(>“Ù^ð ;¤²'µó 2FÌÁ*È÷wM³uúÉK¶;+….¥Á†NqNƒÿYó£b]…ˆ;ÿ3F‚>G Xéôè(¥/V¬pd«E,Ð~µOÈ]ÂÂp·«¥L‚ùõnñA>h.´¡AÆÀŽ%ˆs ×1j’=B'ÜQñﲟŸÊÛµÄÂÀÿE‡™Ì  p¤n=BEeÀöIV°„UP€½ì¯Dˆ4,M=l­p¿$É â53++ ¥kæ ~KMòŽw¤ú‚Þ© ÓC|Œ( F– Vª·g(à˜Èë‚l•ÌÃr].ö¨ †ÇÊvŸPê ^É>$¬.À‡OsY°UÎð°yAÐãô1+’g>qdãô ¯Óß䀶cUù®éa…¹4২Ҁ/%o$­aýêç‹‘|œ'A¬ø®ß FCÄy:J4(”¨0´x ðX-f"À<¤=Á`L§‹GÁ8¿wlN ÇJøï¼É+yGgk¹\Yg}Ç­"4ˆ(XX¦.(Øñ›u£K( 2 pĦ$À)Iû©R6CœK‹„…îj#ÚÙNÓ§Šþp.x%ŸX) >?`¯XϘñ´Ê`ÀŠL·&°ö« p ç,èåqÒå2aaûu…{“Ü ò¦¸yfU&ìkÚ ¶ % â€X6°@EppàcKqpr‘á ‹ŸLL´O8×$2s+¾ž£Ð =2Jsîð€ÿk~É܇•€¥ìr²ð¯,<˜ÆÈƒG€Ï»T*ˆѕƜÓs£pâ7ùF§EGãXÂÈŸ_°±øFƒUØ^³ŸåÔZ«냑%ä¶Y\R}0rXãqýàôõæf¡¬Ò)Ja_ð‹c \N*¦Gy³ÈS;ÇAÒ mN 4(Ü-æÝ"ö‡Í3Ä+'½c. 'ü«ÚYõÈÓ³—LjÑñèI6½¢ · Ù95è–·Æ7PP˜!"vn© R¯°<™‡ßaAÙÕ`á[A…Á̾í½΂ÌÖ r§€£¶väæa)Á€W) [Y(3~A•GåZie+ ¥þõ.G~}®t¬Óùh4`³¬æÂ‚C•wMùþL°ã¿CƒÂ¯ÒÛKš¸qž3U²§ÁÆ›LÃAŸ¹AÒ#ïçQi¦ìx´q¶Ñ ›£Î«tnÔ(ð5±ÁüÚ:ý¨˜£f7D^™ PWï¥AA€ˆÿÎ-nûø›”2UJ£x©t½[ÉÒ z›P9dNµÁV™""½škƒçJƒµ¢<šðq­4`r»b,Ó—« 2 xô©—‹[¸\¼hÓX±2·¡^°ØNÙpðnù^Î] z%)tÁ;`*x ÐìvT±Jæà “$ÿVSƒh†¸%Ûô±Tà( x©¬+…£’·VƒAŒfþ\l½bAcņ×YPÐ$ã¢Òû„ŠùY§ #¾ ·ÖihP* ò‚ñÉݰ @‚<>doK“ä æ,AÄÏp3¶(:Ú£¤GÆ'¾÷…<Ô[yF;ÎzÍå.&5ÀÐÁúHðŠYjm7𵓇ÜKßAlý¤•ñaN[;rDûÈZÙÖˆöÂ"+8#A\+ÎS«#>5QLì›ê· 1LåbA¼MXÙüß‹¤©³C- ‚êh€;Ù.}Ê÷Ëë¯ ù~™3®œ½Š~T; zi -¾é¾UlÇÊüï]U†X¨ ¶’Er^&ðͦð`9â2¡`‰Š,S)œ'xÀ™#ïª °Suï3ú…îød çZÃTF^·ûø”Ú&TŠƒÀ‚­âŽLŸŠvCT\Ž( ÆÊ^‘S‡]œ˜svÂõf>qŒU -Üæ(w ËQÏqOì× Ø4£ è"ƒN±JJjŒ‚Tð%tä­"Ÿ ) J‘‹™¥ •t´øä(OÏ:9 â€ÍXP²ÒJÏ”²ãÙU3UQñ;숅fTù( ÆùuëÅ‚tµ8žø»xªRŸ²`¯X¥¯ÖŠl%ekvwƒ¸ôqü‘ó¥ÒÉqí± …ºßR¥A>a^Ø–½1cm?JMG…¸ËQ4Dù®Lo˜ÏRäbÞ$ [ÊMx”Gd³ôk"í½ìM:•Ø :m׊⻫ ²È`À>¾Ñ娿š+ƒŒÜ´§-ÆD¥}/úÅ•ke%NѼ.À£‚€cA ¨©×•âíβU:‡áYPqFædTŽ:å«mC½bð1ÒÜ%Ì>ELoT"gk“’Àß …¾:JüfÝð<‹uÁõ¹(-â ó6仄…@Šƒ…Ÿ¡†ƒŠQ:¾íZ|ª!Ÿâ`¯¸¡fs“š¡;ÎZ RefÐÉ(}c+pÃA'Û3¬„y™pr§J‘9u©Ýܤª´à‡ÐŠƒlŽ\ÁA.¢âÕ…–NÙÕÅ&ˆó™GÃQ™ r@ŒŸ…æÇÔà|}üÿ4Åå―œ.# 8…Æ{„Â3~rî° r£Ô©GÀ§~; ¾8L´òs“Ñ­$Èî& j[ÛÝMp'¡}Â\ ²ï’UÙqæEÁZC– ì;n•ÁQPb.ìÙ=SiPHZÄÛ,‡A/2? øµ¹ƒƒ‚Ì ²Xä _…’#jÁ‘oBÆA”"/,øhï²ùœJgJ|s§<ÈgJ3§$z§€ãJå÷΃\ìa¹¸|ÒK‘JÁÁû*Õ!Pß´PÀ¦×û„NÛEüu\u”c°¶ "Ûé¶¥&<†Ã _)áºXi€[‰öâwQ7,Q ë„mÄßÇò” š£?`Và³ÄôÈ9_mæ×SĽ╎„óuByl°bÇû¦XöŸ¢æu„›û;8(, 8à†á Р`utÑ€µÏž·˜§ˆØÝV\ì´ ð ª†sIx„³« òÒrང;!2.Ywtæ3¥õsðŠ9‰µ¾SÈ7‹• æB]ЫQÈÁ ýß±G.,pQn…ƒ¦4àON›™Áƒ,Åðé±± —¸ˆ»1BŒÌûQbïR”ì‘%rä_=`¾þsqÁx²E¹Áÿc ƒÏê+äæÜ',X¦8 G‹e?`¦çpJa•¾Yw’W+B#.kÁ#™ý{æA¡UÀ'’E©Äû˜4〠|ó3(]+Eâ6"Oí‚9Ã`e=¨<Öã܉êq§íî+ä fü{eïvÎQ ‚ÎaÐKm€T1`Gû¦[¥J¼öé&JƉ®ú„‚ñYÜ)¬¥bA{”ú„ýØ*;l¢ÌÎ ß'¬…©ÁEƒ‚CòÉv¹Kƒù³j|Eƒ(6˜sÔâÂ^ní4à8lŸô* X½åÉÌMð¯ow7Ù9dÙtˆ…k%öMU°q¸ÕW!Vôh®Î9J¯¢;ã`;sôêCu>ãg€:Ÿ]Ÿè̃#ß(Œ<S„$æ½`˜¾`át§SÈ8q ù.í2×iÐÉß«w§A„Áˆ ~¿c.ÔèCm0`  À”9s±Ïà`8q÷l‚ƒB§°¸S7`‰ª4àšÒ`cÙ»Ñ ³•‘Ê‚qKµAÁ¿žžm JµA%=¡×í"çjÛ¹R'H· 3x”J§º ±Æ_+ (èd‰û„}®d¬ñ?¤(˜q‡kÉ ø½Q”|ÏØÊÈ…”²ösQa™gaXeÀŠc[/fƒd¾†stΕ:E.n•ãEüþÙN¡àpÂi+†ƒÂz±°QèR¬} J…AI”Ì’Y¥2Wi°âðÔ ü‡lˆXè ' óÛ„˜¿Ê·Á  Vì²Þåj€Ïk!öê*3ƒì‚˜ƒ°§sÙÑcßÀs4Eî¬0ÈB” ÜÈe"Ä})1ã³ÚP€¹¡Wž£R˜ð¡ƒ[Ü-f«tŽ43ÙþÝí,¨Å¨ôò>Ã÷Áê|VßñA,ì }BfÁ€S‡AP$ÿ,FÈ)*ª8w·.û¾ö Ï÷š ±01˜¹Å,ùDaš*4ØùþÌ3âíb¶Jg?l¿Pè#B\°Ûpt['Dô `-Íó6áD9¶ñ š¥__vÜÊ7/ÙÀp€Ÿv=Xê¡4Ž5o†ÒЀ {”ù`iãK\§Aáv±°L0MØÚ„%I ²/j¡6XžðÜ AÅ‘þ[whpð~HqÐÇØ€c”q°² ŠI ð±åÕAAjÀ–4†ƒÇÌ_Šƒ.ñ«Ã‰1÷LÇÌÆ|¡<ÀNÊ«úw\ˆˆØõ[æ¼Q`ˆÙ-sÈ\¼€ãW±ú4 °†µ½Y¨Ü( ï© r³€Ã÷;ÍýLóà`XP,@ØKSÄÂ~1OǨK~f ®Œ=¬ .dÛô½d“ŒU{³0c/åÁJXZyÀ[eÅÖv¤0Åú G°âWÔgµAåd ¿YoÛ) {•]r֮毢D¬0F<ÉÈ4¤ÌÅ#Û£.K'Óô-6 ÇR TaÍ•Ò ›¦ol«4˜?ð3à‡Ùh€Ï =`œ‡4;È®é3†]ŠX)2 vü»ß%LFä z2ã¨yø²%ºÒ€wFƒœ¡ÀúæÖfáx2)Óâÿòöá–7 |mâ#6Í 8ì÷f¡ =âé°)3>}ÿ^á &|˽8èÓ+•œÞ a-Ȩütà£)Tô…ÙAîöÉiÛ2>›5: ²,™-@U–Ü'‚…úÆ‚’óŠ­]ˆ˜Ï<=÷@•ÂÜ€#rlnõŸ‚ÏW,ˆk…1Ï &n~œÙ*¹’ÇÜoŽXØ*t g_ñ+ѪJ^Çl•|UÕ©A^2îƒÔ ¯r£좚 ƒ ›(³K®lxB茱QXv\©íÑ\Èc>Yü¡çÌL¥Á†xÁX°=»Ñ?‚†ƒ^ÂäϾŽ5WÄ\¬8!l¾`\ÙâYy°U. µ¯'Œ…›%,ßmr@ïD;𰛥J£P±Esq°œ¹Q&ô3ð(Hy€ß·E|=FÜ †ÉcöOŸÐ¥¤<7àSôð4пs•F¡°SàÓV¡Áªöv³“Ju€–‡VdÌ¥¹AfÆO†:•ÒVü†úV!.λrWD¾øVWÄ‚>Ü, =ô [Á/™g*V0N›q€» §A/m2v½ƒ‰¢N\¶G;zôÞUáú^‰°"˜•K!pm(ø!ž¬OõuB&¹½ÎXÚ~s#V¹Fü™šdÜß::i’¯OX$ÂÊAã7Æø×;284ÅÆˆ…VÛ NL¬BÀ*V€_.ÎoÚ§ˆ8سƊ,yåÌåAŽjŸÏè:Ÿ{k¹Ô WžîŽ!®ÆxÀȉݮ5è‚Ö™».¹S°r ¨¥@ÖÂ迎ƒh~´î¥ c¾Ò>:È4ÈýB—\•‹yˆ8–Œlû¤4ˆ“ƒ™SÐËY])dsƒ³Æû‡ˆÙ.yÀ÷Á Â#il>Rè¥J^ñÃnÂ#ì o°+KgAVñÞ›…ÂF¡Â‚Bm0!½q8á«ÜN|Ê* jr|Gœå+½ÂPÂ{C©*¿†|µ6H³ƒl—<àèÝS–úäªTNz5 Û’ÍÓkÒ£ŠÞ p¢³XŸÄÖÝ( øŒÁœÞZàbÞ`õ<4o?QÀÁ“jJ¥Áöÿ÷nI’c±®åˆÊMÏ-iýÙÿ=ÿ´<+ιAä’[&¯kVŸaYþX"AÄw´Â ùà£ùð×X‡ ¯H‰Ü×U)+ïƒãÇŠò Ön0àW]–™y»¥ÿè eß1¢ò¢8xÊnðÀâ ¡Ø(ŒXó(‚Ü£`GM„r€ÑÒ€}æ7:«#Žc¢#.If2Gï¬xÕOÝG(©nàÝGìL«µÁñ v²0àï+­B2Y`±¶â]WŠƒ§„ži ’•¥`°$á¦vÿ˜qEÛFy8“qèTÏ3ãÚ‰t üXýrƒ1ZhB““zâÀ Ïâ…ïúV]^îœÂ‰»À8à0\eÄÀ™Ì%X½­LðukÎh•ƒù¡CK+ìÆ”IÒ+$+K¬RKqÀÀ«ˆŒJƒg"“ÑîSeƒŒ˜Ò}Yeæãw|iÀ2* Ü„q?»y“mЂÈäÑG"NìµøKíÜ P*º¥Ø%…ñ±B’t‚þ‚Æg? ~Îö³ qðVN/ 8†ýF€º§ÁE])ÏË+ °n’¨Û(ü‰:±0à*‘ °d¬4Øì|Ñç%O؆ÊÆäV»§Á”Ø ðzkIÁaî‘o²k Þ™|ðç¢Tìcí}a0!+ ðË',xhg DTŽ·6«2Q2Ððû©ù¨øHª0àG‰Íà½,b½GAX2êz5XRX(eáTO)þŒ3 …8 ¬F[XŸÁ„Ÿ-u! ðMBrOå©ËÌfW1ð¯ýÁ‚#/ƒUfžTõî2ÛÄí"󳶨5Iw`ëy=ðË+§T‚PƒÍÛW¾VÏ'ÁUæƒW½eŽàO+íÍÌÖf¿ÉŒ“5±&‡X‘[,¢Ù‘“ˆä‡X€UeõÝžML.®ôUp$¿œi¤&ðWÚÇ#* l¤ŸÍã„J¥^i÷cŤ?࠰ʃ5YUšø–¤ŸÙ²`6bÁšÄ¢¢¢âa`2`Çr]Nf OÕ({ ’¸#ŸŠÊ:“ìjBKRQýñ„U€_(X¶ÈVðJDx·)JzmD)°íÁ´lÑ‘5ß4 ØW_Ûƒ†u° ø‚N• ýÎâ±çáI;T±£$ÉA>2þIj7z, Ù†¥_Ä8ݰáß‹z±î$u"ì6 ùÍ/ÌX¥ôn,ŽØ9 ðƒÑ›n²¶-¸Î>°Íª²%p=œ¨†Á Rš‚hÓ ŽŸ+ïŸ``˜G¿•°r@¾Â·Ò%yG8K½EƒÀnô÷ýþ‘âgç÷KhÀ~æJƒ`™Å›ŠünIià˜à‡§–Ç}Ki8 0·DÒÏð ©ß"¬HÝX `` k–>àÛ E~Ž Éõ :~ëŽ ¾ߢ/ x™N©ø(Ä«÷Jƒ]Jï>äK!…ØZwÓ`Gá´JƉÄB´ÀÊŽçdIœ¿Î>¾ÞotLŸGŠ«ÏKsqá)²â 8ÎY[Pq¹…+Lˆî§TP.¹! ú“‹Næ6ûÛˆs'øó ˆ Çvªû÷®%ÌIHòα@B4°TpX[õ"ÿÈŸhà÷—“¹bâ>äM&¹«äÄÇh°azçzB²¦àÀw Qu´èO.^œLXg|ðKP²ÍEå\—nð킃mܱOð§¹Öþë엔ƙÓ儬òÔEü0Œ£'¸õåñð·T–‹–nðI¡ÁC,àkµ2Àï°°'QZ$³Eo7ÚY ,¥ÁæÏ'ì¼pq£QÀ×Gî'x𧽟“-Îß8pq‚“П‘…6µ6X9%LhxѬ\a0˜ÃJë?£[`LÊ‘sã* ¼yί.8ÒºEƒ@6ˆÖ”’Êà‘éâ6à½ÈØô* ‚Ò ¡J/½‡ÖfüB( èÿTa€x¯0Øwt9ÉmvŽ÷¯*¢O6á³² ƒàšÊÆAùµQÀ_H˜7g<²é' ‘e¡)°Vqð×`CeO¬ao%K‹Öƒ¸ñA²Þs*û;Ø–‹õ¡ArvÑðè§AP¬*š‰êEċʲà€?„êC òÒw>®'ÉFE|Í©ˆA^:¾8‚ü(+‚ˆd|ø)š0nXŠ¢ãìK#åí¶#O ØW¤<ð4ð±g8—{ÌÞz´a¦4 _¸Ð`E3q¡ÁyxFìj€X(ŒÖ¬ \÷U¢ï~vC?ÁÀŽxn£Þ£`¤Àà2QŸ« 0ì»À E™¨8v Äd?ÁŠˆ[ãÁ`­ l¸ÉŽ& AAgà]ˆ~¸8F’õ#/¨ÅÕ4ƒ…Ï€ˆd\N३* ø©øëþj  ¢«¨¢€ã¿* Úð9-ýDÛ^9¡[P€Y7ê|#]lœÔ³Jø¸s;!8«äãÒ·Àk°$žd¾ò^`À)2*‡- Pìîf¬‡ªñhß”¢>DöWL~{y¹¢Ñ€·P«‚ˆÈBƒégïÿ ÜúòÈs™'àÞKƒ÷*¦÷!ò§ýŽ×ç^rU ?wް0°©ggaà§‹ _C¥× 8ÆHJl%D4°QGÓ\]\PsªÕZ(ju0‘¨çÃ_]äÿYåo\juà—˜g®kq€ðÑÀÜUZ}Xú;GÒ〷½.ùlzñ˜WqðPm` Ùqö$)=`õm+o¶×à ¼”Øí4àј° 6ñNNUíF+7µ4hÉuö!¹ÎŽ+DÒ(wT¦þaâJæt«Êì¤ji0YÉÀ: ø&ª  '8SòôšÐø­(xÊ”ŒÜÉ :Èœœ_}$*}ã=™.¢gAqàW‚>aA: l"*§yö~¸8ÌðÂÀy¥;Ú f›•~ö¼ü•íE¬0¤Q°0X~. | OD°¦”T^?¸íÅ“Øû èÕ»eB´úáôBeùεd¸HX…ÁÅý4 8 úVª„èN8 µ¶ þódª- ¶³àFe¦v ~Ñ5Ñ– K¹êBÄù™Nà³8¢ØÙâÙ¶8 qðÛ‹øXÓó«OÑ ˜-â·ø’Ó ‰øëtç#o¾>Bƒ`yß -¥Šø•A£€ýn,þ2{;FœÙT¬Ü"I®- ¾é\i0±š«Ç˜ å­J·Ÿ0ØåE>›#•îý,q³LYðÔ~> ¾ù­ýï;BõA"ýyµl?!Ødæ(¶ß0¸¸ìXa€µgi€ÿ§ƒe Î-^$Û‹íÈQYñ¡¯iGø °¸Äýå† >(}@jëA¥gP0c ¢(xªKHÊ‚„AYbÆ×GÊIJ¢ - ¦ ,`óD- ü • ›æîÝ~ý* æmH„p{$[Ì^?G6 xùLÊ‚qr'6&}<ð“,…Ç—tÓ ÙbFOÃüw7TxÇ´_188«ú üuµ_g‘ƒº`ÅüKq Ú£ Óˆ–eÅ1W4—ƒ¸- ß×pî[Å:ñd= ù޼ùÂc.£E„øÇêùy´¸ü3ûÍE´XèáÕ`s1ÁAp`í¹âÀŸe¬%@Æ‹V3xÊ=¢âÀ; ¸ N¬÷$ã$9›` É Âé7Ú±hÑ€c=åöª_Oà+’j<ò¾£‘Cï* PX¯Fƒýø¼¬´ü3ÙÕE¾¦^hp.¸°Ð`‹–•žª8ên'ࣟ â²ßx´óT° ¡ôòò`±ÛJ§-‹làÀ§¦óܹTãÒ|äÑÉn¯!Nlg¯>D4Å”SÌûÂrnÿDaÄjåÁñ9Ö`ñ)ÉãQ‡‚žEu〗QOÙ“3*É~B "ò\Pqà›Ó¯4य़ìªÒ6JB¤œ$%ûfÍRÝ™é ~Ñkq04ô>Tpþs¥Áˆz¥ÁŽÖ¶Bƒ­]ä>ü¦Á~àÓVh€ÿN]eþYCþ„ç69ZCp€ýD?œÊiw‘¥c™)$'à'U­GÁ|ÑŸPG¬É=•>•½5µWHœˆ«ÍClû‰eo7à ÷Šƒ?`6ší¸ˆˆ«8œˆ#¾]5ÑÄœ,>+yäŒãß4˜ö§&Œ¨A+ ;¿j‹ƒåÈ6™ý\i©4ðźâ6H”¿ÈÌÖ6ðeXðÒI÷Xan.× Í')}§0òéŸ ”¸dCÁ^cžÛE†}…ÁÎÚp…jÌ’Ž:ÛVÁï/âï[hpp#zgÈ(Ɉíðǘ~²Ý ¶~7V–øZ2úë«'ü˜1q­¸%ù¨¾WÀ*­›\?¼÷Ýü˜‘K¯€kåA³hzkLÞ/NfUøhƒáçß'ø FïL8cüN¯D DKI .)à€çŽt¬-åv¾2X@† ðØt²qÉø’|ÔGüG+îgTìf# ÿщljü ¾<à{t‚¿¨pVv°à7±‚—ò€#%»×–Ö…§ÛÆïJÞ,à Ô­$òÓ¸Ò€/:) |uÀ·rºi€#ÄJƒ¤6ð0À~¿Â`bU\`ÀK7RØHÄiƹUí¶äÊÒd§óœÚ+4srm‰Ò’- v^˼œÀ­·n±â+¨4xh®„ ¡¾ ÅA $^è ÝÅ/öVà|¢âÀÓ—Iû#‘‚U:˜9S¤ìµ6ð§x3ºÖóÅ­ÚR\$`W {êiæÁ¬4/>/yPW‘Ú+áÞ„Ôwmàࡵ¥ÖðUÖ^¿êý» Qš8Øpï¦à`p¸–$&£<ܹǸ½ðW®@8ð"à¿S/-!P+¦?B„À”Èû÷•<¨¶ƒƒuœJ„†ù+¶ƒíüüìŸ×šO"ØÑ½¨÷ó;Ô§;Œ‰‰J'kÍHÃZ"Vù7xàÃÐ&¾ÚÝϾ€¤õA øn!ÙX°4ØpW¨ÐàGD¿ŽÐCÍe´àÔì|Õƒäw—ö‹‡@-°Æª086[¸MÆó¥ `€ìn$ËK8à¹Å‡‚SªnÈ‘Š¬+pÍX…WÅè ƒàèþÆâ? ²ÓY]â­¤ª¬Ö! À/ž€ÀçL|ƒ¤6 {o°'§Ý`_M ÚÄ%³NtÒv“‡åß* PÞÒã3U>øú Ü¥K Røä#ÖÉt¥ÙŸ\CG™ÜU¡7«;úhÃF¡Á°ðüµÒ`` þ¦Ázö£%ŠJƒ)q#®Üøý?¿•Fr¬4mà÷ñõ+0h™jd"âÏ puƒ+>Ä~iˆÉD>Ì‚Ôõ*8«P ‘99¸ÕÔì¹1ÀA¢"zxsò´-X{¬ÜnHqh3¶Îu¨Ð8 â`ršÁîêÚökñƒÛT˜œpKiÀ§(ºi°â³Fh€Ò;µæ\œ*¼q­ ý…™'rJ!)¼d0Þäë+), ~C»iÀAÿ¢L¾U8 j¿¸´ Ë„ÚC-þîT$×pݣ ™ƒ%ÈEñ[Sp°ñÙþüô-Á>ÓïØ»º¹†O’þM^›$×óvvÁ1~ôìѱvOoF|· Öp°îXÉÕVaç>³Ð`æ 3¯ÆUÌøi®8˜Üq•ís?áÀ#"¥8@m¡Ÿ år-žj¬ùhÙ84ìžQF¬}°6WÑ,.½ç – s¹´díÜË+  øˆøo¼?ø´‘ʉ[Y°áS_*$naÁ1$}oŽKi€_ÀNÙÀç"¨‰l€'ân°eÁC'×8‹üFe ’€ƒà83éäüb øy~³„Xr÷ú f6Öôf7PHYà#R×õJõxWò{Eò€ËJ© 0S Ž—挈ƒ[R˜8{RUƒ$î$hã>Œî Žh €V‰H <ÉÁ¡vNªeÁE'Ño¬,5lx{³Ðø^˜Ò€~F\GV3Ž 2P“G>Ø÷›«w-C»È†ª4àÈ«zš_g© VÛ%¸N±Í€ãçÕ†ˆ:c¡¯K*ž* xDTqdq Šàà™c +Q*8àC¾BŸ„6à[¡ Œnžp1x®4ˆµ»>aäˆçBƒqiÉBs}„¨÷XWqmç$&a%Ádô‚ùŸÙ’`òFƒÆqùýuÛÃÔið pÙíÎl10$'çýhqö7–&Îì¾³»˜ À‡¤¢œRQ€U÷•ö ½Š‚‰ã¤0à+ãÕi€íFeÁ„ØÑPDì7T> ÒÓñÓ¬vd‹·¯tñjÒIâ@ *ƒ#r=Õ(àçNÔIƒg:…ɯ/N+/<÷fð…]'¸¨“ýB-—>!‘ ‚Ë*Þy5 #ïâV ªRy0 j¬µ~¥8Àòªò€s¹ë8á'álJê4&²Êw:…äìÚSf,P5í! !¡¿>à´«ŠŽ{ð²ò 8ÉšÌÑ–VÀÅðóÌÖ{4 ,ÉÉB3wI•SO-¡ÌZg ûÅ•JÙW ®0&ûJ³+lÚħp¹@ØðË%@@[û—âFnËnøpLtã#'èÞ@‚w#â#GÓÐ,pXR€¯Mw0ù¥a›±Å‘ TôŠ©’h­É z••óê¢&-I€U ?š–ÏA©'üñ5/%î/üŠÞà¾é:d|È~´ù|ƒ“lÇZViàù^¥A¢ š}c?§‚ƒ >x$à€Ï» ¶`™×heÙUXVkF\†ù… LÿãŠ[ƒ‚ƒásøÑ‰{€môæäã…Vê[åA0YÀ:ÿ–žhÏ*Œœ$<Àa¤\`K¶­9¹ø «8à£TÊß.$Q©(ÿöUX°&ìîü\¨|€Ol©Øj_o¬àçBä·Ï¼ û _A¡–i2Z@ϰ$#ZñÀí-M¼3!—¢› .ídf BQðÔ>3>ŠÉBsP$9hÖ˜Üðk%Žƒ$Ø€GØ7ö™ý`s<ê`á…æù8°s®[ g àuƒ™3+ ø£SHÐìBó2/Ä èÁ‰æ gERxxÿ‘¿Å8e,à4™ tˆk£ðTôÑÏ>É7x&%•ÿøþ“íì«@“\Dö.ÔN!9¿fÏ4oxöFe`/*px|Í=æ é‘¡·maÐ&DXÁÁù‘ÇrPp€²\ÅÁŽía I݆Ïùs„6Û 4„»°`åIdaê)Z<$ø ´™µÚ"ø3r„ˆA1Zð=9借0òæ€NüŽÖktMÁ.) Ö˜|œ2! ài%º * ø\Z!ÁVIöw¬<åîš9¼v’À®3ó\š6µ÷ÀP~I1Øø,yáÁͬ˜·¦•AàAâ]¶ª$› |—¡fõùé %žß@¸p§U à/ÓiA:;¬d$ÝàÀ'¨bô·–X˜©ÂŠO® „‰“hõ¼Š÷&oØ®öf=`šyF:~–ÜBbNFÄߺÛîÌÉ'pî~ƒ(Äö×¼Æ.<`¿áol,d÷jÆC±•ØØÕNÇ#…“ø¨<FìJôN³B›ñ/¯Ù Ù¤äèXáöS ¨ ö˳J"ú›k õÿ€e}aN“@ÀNG›þfÀhÕk2àh@ã‚S9€”p%¢Êî0op`G!N$¤ ‚©"~%D1ໜՔœ %%* °ƒêeÁŽuW÷0ÿ™º¥°.Èä ®¶¥$à‘t&à“¯â`ºh¡êU•À•Ìkƒö9Ùàä&EAc“«ò€½ß…<)V4{IukO2Ðk,Å_QX b à Xi€Å{w£À³5‰CœÑš#‚,^HÏU=DçR,N/|õ«7 ²¹¾Ò`1§ÚOØÆ E?) ’œþ– ü~k½ßQ³ébDƒdº\gæÇ~ÍNçò¡{¾ˆ‡>¶Wà>½»:Øñ›%êá,4ψ'áâ©ò€³‘´UHÒQ9ð¶JpS}G‡ÝW¼ÑÀ7 ¹¡ðMÅÁC&ÄÍ_R;¿­Ä-vÿ0aã1SÍGŦ¶³SàÛw;>iE7°Bö¸¿U@GF‹¼Ó#Ë‹ø%–V•nQQ(08‹O|VðA~vÄkðù¼Ò$§Ï¾SØQ*ºÃ‚`°¸bxk™Ùªˆ WÔý‰ˆ-Ú\´»Jû”ƒO¥4ð›‹kàIæ>¼Zð%”Ú€>Éý2âj­Gó´ã;!µAà4à4Mñ ZçÑr¼pÝDÎ(ðJJ¡ŸÊ¬4ø±¿}Â_]ÄöZ…ƒgpÀq;_ÂÁ†ÕrÁAcKÕlì÷¶SØ9%¨êŽ/ÓWp-#}ò´÷N;ï]+ è%î• ÆuD“j÷mBYט ¦#™/NÁ¢ÒVAÁ<þk‚ú„¿¶ˆFª‚‚…ö[}I5ðù¨gi€¿Ð àצ{oqOÖ˜G|Ð*üvß=à¿S;þÀpΗðE1ú©Â¼ú; mÄ·K€àª4ìn*Fޤ“N!EܱÝ 8ØÅEÞö*8˜ù¢d7¦×l(<×)`m%¥¾W7pä%c·/¥»Õ«áÀî*EÄ‹è~¦€o{¥ âJ“—<þÆ•dž¢Þe<ÉÞ~´4œ`ÿµ¤à[…‘›¿êI¶Ë‹óO ñ‰Öo° UE:üxÝà~‹µ:x*Ô=¥Å…’9GUìGÉ&³=ª²³†/†drr5 ö#ŸŠ¸#-{W–¸ QлUiàg scdHHª¿±t>÷½Œˆ\®*âl,mLKÕ , ¦Ÿ`–O4°†ƒç-2bD%í xaUqð 8µFŠƒgh€ß¬îu¥ý`WZ­ $¶dƒÍ&"žµcÁ†f²~`©Wµ· ]CRî£Í/2Ÿ–­ ¶ñ‚•2R°î£qŠYÜGÆŠ8ý3Ùm¥Å¤ž¥6nÀ QS .ôðþ6* ¬3y瑨ýùŬSà9›ÐÀ¤Òkw¡>‘ê€Ýß•Ë0ÐØAhÀáž•H÷Z4{™yYOhaK† ñKË‚ƒ'%Ú*ø¨d\ƒ)<ØÆ5à[»+v¨}ŸðAZ[…í¢xªCF,{*Ø"XUÄyü&z77w °—Œö†Â¾&²ÁÀ^ºŠ^-(°…w—¬,ùûJãâG ËO‹ù vgiOPÀë-ý(àgµ²à©}fÞ;ùÍ‚) ¼ˆÈÿ/- ¼ùˆ½·Ò)ð9© < ’‘–æ½+ŒæÁ>ù xß¡àà£ÊŸ‚¿Ð|ðú˜ªˆ|JFŒž>8ý¬ÜPÁ§£îø Dé¨6úèäÖÓʃ§â’Q—*<˜£´“¤8H–å`Ã5 á~‘µ<ðùÉÞ¾„Ý"bwà`›Üã6d8ÀŽCq€Ûð>²k}pð‰Á¯®ðD¸ð`]L¾ÁÄ£n褖Í%~ûyÀã{žJ?bIå~šû…Ä !Ö_pRä AKyàqÀë|"xÏ6U8ÀŠOy`Ï)4Ÿ†v~CðÌ\†Œ¶<8k9q°5¾I$¦Ö‹dª`y°ü¬©â*p­"õ_°”;Kü*Wà+¨õÁC8°'’EƤ(d¤°8¸z©KÍø5®ÖdlÈ ÚÌ0ÅïPPª4XÝ<Á‡¤®h"×k¬ÕsTò!€ ~°‹® ã…/K… µ› ƒŸäšO0°ëÌ«9™Ù^rúµø%¾ƒÁѵ¤UˆDžyÆCœGÉi•à$+Ÿ¸a6ð‡–ZQ°Þ£ó}à¡ †"ú^­U9àÀ05"¢}KªÔFEBħa›?ï(ŒA~:GKu­r0½”W¿„ƒ³h%à JIõ·–>˜”^<˜xØT×’ÐdþwêH!1#bE,Dðê~à»ûž·ÔØäu@éNK}´à"Ÿ\TÀW°a¾˜ÀÖï_T"ø#ÍÇØ>o4Aˆ:ßà’!ºÅˆÓi!šL´_x¨BÀ§›ð€¯± ‚~!9ËŠozáA;pj%<Àž«ßޏð*_åA“Š:såVÄÝ<޶·iœƤú%F_pÐz5#.0,õ×g|’þ‚ÁñŽý³q BR›¿Ñ|ñ'iyÀ×{* p•HaðÔdŸ¢ôˆxÀqr¶Y8ß ï=º¸â,(ðáGÉ=…†_Њ¾:ú+¶I½(‚}]p†­ÆdK‚à Âùÿr,X‡õ…í_e/jKÖ –<«e2bý!ÛÌøÝ@VÚ(ü—u¾ w’ ¼Ž8cµ\û„M†²¦àYÄEúO{ƒ Vd`7 æÕÊû{gÉ“€OÖ&å?YQp3…u’õEÖY…تÖÁm,(ðËÌèõ”²€cÑ…œI]Sм ‘olÜ  æÈ’(ÚG´Cð…o$Ô‰NË»Q XVõF=2R|בÂYµ?ƒ‚»0¹£€¶ïÒ!ï#©ž¼y.¹Önpü”;ŸX`휬qg{1`~º„X^Üa¿£²Ëü\ ì²Ò6ó3_`ȇ8î”B—ì}ˆüä«ê!Šý8À‡µà€Ïw ÐfXq0á;¡–dkEܾd\qÀ¾ L6ÑéÇÿž^ù€Ÿ>c1(…§pÀÆoíZQà¼?ôè©‹¬¾6@ÝAMÉ^/À¡  »qÙÀ£6 ×l€¥LeÁ:nIiàרøW݃7"¶«õ i'¢ÙV:^ƒõøhÔ¥%A"$My•Oi‡¼}Vs °Eº3Y H`c ¶ÑŸ_4çje,( Δ|§rc¬èX0r¾qeÁ´ âtŒàÇŠ#‹M¥.À·Aï( V.süeªˆâZì¶Ký1VV¥K`£†Â ÈINXð ñà9qe~ùîÄ${ðʉ¸ýP11!¡é ¬%y¿8-XÕCܹë†XoQ˜ƒÓ‹f°…Á±¿°Æ•€{CÑ ü$aÙœ'y´{ÌÑX1ª °ý¿ƒÁ'œ\\ŽºAƒ ñ(™%ð£MC "G'u__äÇzzB*°Äèç‚°& þ:Ú(øÚ?ª:X´–£c{¡¿IŠƒ`}‘Ëmr&DšÎ;2zd)‰5F‹+vßr%ã;!‰G‰)wå¦Jà2Àõ(7–f® ú Auàf‹oÛà YXrñgãŒ{Õ5þlð‹¥Åïøv³œPÀç_µÌ/|º) |þÙŠúi( óçeæ1‰MGMO±&Õ¾* ¢…‡ª6™ÿ‚Á6d­BŽÜfžQ¢×‡HVò3ñgøªéÈÓÀ: BÑ%Vƒ³6`×wŇ¥H¯à÷ÐV\ We ô çQ5ÛàgKè‚tT‚ôN{bALp̰\¾ƒ|`ߨ ’{k‰pØ‘ÙH 4HòϼŠÈ×5èÄéˆ{œÞx­°7qœ¬¸Íã žÕò·¬jy°ãGU\ˆ^8À˜Öv™¹ýì¶|‚Ý_løèá °¿`à"¦×Œ¦¿oI|)@ÌGÑ¡ö :@ÑRy`ï­]p¥ð`ØY§ ðCM;á{b?ò@â’q`×m8ഘƒ³â ö’|N‹”h™-6Böœ‰”h7šçýpVÄÁ.0ò<@ˆ€_d%ÖJ„ [@Íûüŵ驴“ ‚•ƒtÔE|ÿ»†$B"C`à' ltê§öóµ:˜ùª¤t A³àwÞ†¨ÅÁ’h|ÞMÉV;˜çæ´ž¾a•&J"º¥ºó &ÞnQ‡Ö˜ÜvÎE/(@yõ;eAÒ&às¤Ò º¨â#N|›°^Øì+ Øþ-ªA°¥àw™¯²¤kQÀ3eÉ>³^ƒiž? þ° ÈJFï›°€=†ýiˆ+>Õ„X]ܪ  †(ã$‚A`= `°q(^­ |bcs¼ÐÀÙþVa`'‹ >dû³Qñm¨BqF ƒd˜à³Ïð㥮d^ XYÂÏW- ¶Ý“]RX|ÈÉ̇b41ØR@S–²à!ð¹RAœŽ6½µ–,)x"*V‘bà./f0ðm¾Ò& L¤4 ·½^X²ËÌÛùŧTßUiàD.BêãÎM±ê~²È¬U/ØÚ‡q¿4°; |?Ni,0²UJJT€ø3·Æ INrR^DÄÕò€ÏìU øœä³òþ`Eüþæš·"ÎÑ|‘—{DA „|ŠÞ›'x` qƒè¿éïøÿ%å_[èW‚Ó*~Qá’ø>„ò€^zZ_x°\åWà#Pb’ýaæÆÕŠƒ^UÌl é=Ó~–+ŒGhàcÜ@På ¡Õª8À7ýVy`C'Þǽ! ¶¢å >j¿+åÕžh¢àwô Ú ¨(@Q½wEaØðŸ©¥ÁœäíAP2¯#UpW[O(ììrUå qýµÊˆ?75?ÁÀn)ð•/J¬Þ5¯A à÷–t,) P}'9xÐ&:¢ßQhf¢S… 40ÍÇðBUNx´ X5V`ÇZy°ø øHD´‰r€NÅÁ…kOp€˜J¶6˜~Ú¤O8°+ \§H/·°ë$3ÆÇ¤›:?Ö) ßûW9f¼Ò€Þ.Þ ÓqøUû>%û‹øw×>ÁfmmÙñâÖœÜW²#ÆuÃù¯PD¯ A^ò€xªFÄŸØýO4°+ 3¾åJƒ ì„çÊ•lsúV§€ Håe¤þâ 8È,,qFe¥MBk/Iøuf΃¬¥ÏHîB¬eƸÙÑ'¶ä ë„WÝ* pþZa°%Û‹É’k`¿`°½¶}u3F‹ˆŸtaA’ŠÈéw•Áifö-ßj‚Ê÷êú-ÉlÞíÎAk<˜ùÅ‚÷ñ ›{Ôxð'0.)¬X>ôš¸åà X`°âœDÌGÜŒ øH}ÍAóî£åÀ'z¡ÁÒØo§; –ƒåBƒ}²•(ð:½ÔžT¼ShÀò—âà©%ŽÖãÌu XYöó ± ð€+]BÐ*×™„s‚_gfôt¡!z*Ž-ØQà ¬¯]Õò`ÄYIÂ:qK&ÙGì4©@À·´aý…ö/ì’ˆ5O!ÂÅ ú¿ˆà{…`¨0?vK!ØRÀoz? , ’;¬+;Q vÜ/Pøù"·uµ6ÀšPP`eƒqKDD¤`-µS¸øiš÷ øõ¬ÅAC§g} ì€qØqc¤¢àgYþ 욇KIqÀ³¨Š‚™¥ÚŠ|‘U6x&ùhð[¬ÁGÉ€-‹7jŒ•µ…ÊžN 8:Qš_ ¸ 2¢5'ãÓºÒ€5üêFÄn­ æûtm ªY+þ|ÕÊà=´ó4ÀWY*¬À¤2°3ŸŠ8¡{D*^qQøÊ`D GÝÉOÙ“y´¥`‚à *ø¤vưæQx;"ËAö ë{Ëßâ X[ÂŽ¿XßW¬øŠ;b\`¨0ú3íëráÞ–Ü#ë8üë+–ѹ“}.âäíG#ÔJ¿ÌÌ2ØgÝZ[²:âÆ²þuÎÀ¾Q¸U…7 /â…!a'p,5۩°%1h’8ÚÐäuÞ°6WáÀ*‰^6Xv4«ÔVáÈŠì°ëP¡m®UðÉG|è²À`àûQJ¿©0£µMið˜cí~ÓàâF^ÿu• Ý'YÛÌã€Bx ø»%4fŒèb’¨[$©øfÉ¢BÀ‚ÿa7œ· Lžwl²+ .ŽZIB*þÏ*6wzíÄÁ4ºã`÷T‚8ÁîÇÁ„õηpÀ?9¨d"4H®µ{qáœ:SH`àQX“´Ÿ~1SXàԯ ñ¢•À€Ô oMžù;\`0Ÿ_Ñช=6w­ýüâ4Ë»Å8âBúÑv³€7ÔO…%crCAÁ„Aý¢ÏnÌ\îÑ{¦´ ¼þ+4ð"ßH’ÂÀkˆì&S/¢§~0Ä‹ØðWÖÒÀªˆç_n…ù@/ø.]¥¯ªU FQi° BÿÅsŒ|?JJÞWV1HAKœÉÕíâNÂüBÙ®ƸçUø€$ž å®ºÇdÊÈ/£Œ=ÜÚÒ»<°@à4vc’Ú8ÍP«x±ùÐäé@¢–cl‰µ…g‰êòë7à(>•ƒó*3þ¿A„zÛàà]†ŒXÇÞÀêNZ ½‚Ï?bƒˆÒ€—›jl1â Dvš­ŽÈÛÓÚ,¸4´aš­t°,<›× u/ðÊZÌø;×ú`ä€(9ÓlW†Íûÿçòè%Æ&7UT²µ[H ‰=y@=W ‰ÏÌÚm›¬* nÒïOæ+ÃZXlCpl‰/™)‚¹‚÷ ±”Qq€ß )’~¦òO²Wì¬ |fòEaTyÀušò€MZ8Ú“òÀ×Û0|ö#ž@p›Œãaåƒéxa3õ—Ñ/6ã#Iyð”|€ß-á~šû=HütS¦¾à]7Ñ  <Î-SFD˜ðÀë u!Ùí¥Ùo/½Sšé‡¤]àJ¶òÕóÚ.°*©í«¬íꤕ,cÕáçYú‰n—qô§šO$£σ·á"àÁ3‹Íg»` Êc2YHp€í_?VüŽÊúR²®ÀeFÅ'ã˺BÀ/4À/MÐ×Ro¯í;¶ˆ:[°Hë‚Ë…#w&…Ó{{×Ò€o¾TÌøÉvÁ¨‰' œïà9ëi¨~éÏâ–ÇvзÊÎÀ­ h1øëklàÇGåƒ`¼ÀßõÊN뮸Ñî½ÝÎVT>² Ya:vÄ“kJyÓ®ðàü¬¢Å¶ò`a'já»°r6 ?!5Ÿpà|gqà–›§Ïuo,¼qà-Ê(êÞ*ðñ÷›ëΫ~¬¨iyà]‰3o!VçA°ÝÌ =Bº“¬©+ˆí‚í†àrûù®{5qöÛŒg}`³Žþéµ>˜“á/lH}€ß¯ „Ÿ‰ä' ¸é¸Ûë ÓÛvÁ Þ<º…ÇŽ³â÷¯ð`Ã(Á~“2'C+¼-‘K„A³à϶³·_÷—ÜÂÂγÚ~-‘§*µ[ðLËÁõxéÀÇ©O3æ¸i³àCÑö ÇIgŒ‰IùóÂÂÉ·Î8òò„*‰ó€£’* 0XAað”ó€Tkq€ÒÝâ ‘}«Àx 8€…ê~Ñg©c ¢»Í èÐTÒÊkË‚.‰* üöÒEÎpmôv( |]ÀÆXÙe4q©£ÏN±áàºÚ$x*Én+œ ˆâРFAໄqùöBeAÒ%eü´wçà#¿_3DÄqaK=™bGŒÓŒ+*…ØÄlø|`q*H«mvò¸aœ¨|ÉSh€òÃ$|·ny¼l-6£¹Šˆ¨‰w«+¯³KŸÀ™&R¸³K'؉#&eÎø©@ ‚ ðÿô ó±c5SEĵ¡0%@à+bU5à”Œª"ºÚ`>†{2bDƒˆˆîîÒ;‹ñøt0úðä‘O× ÐY¬<N2¢Ö¦#ÆÿP3Hü„‘5 …½¼°v ‰†ÐÀÃÛLIH DƒÃ/,ÌS‹:?Qà® ƒ†_œJƒõ°Y«ŽÃ®"¾•óä H£)lø©(48¿£A¯À‘ÙB4 *ž’ œé-!b`HD=\q`o.­[°Ëȧ„ ‚¼T¾Ó«!N‰áßÎÚ+ T* Æ}õwVæ`³yÂ?«Ò`²©'óv~Gñ$U­ üåv>(¨0pâè–Y¦-,hœ¦,à11#~.î°€p«r€Œ>nÔn`·W¾$¢9AqÀÛ0ÕœìÝÉ>Ž+ 8¸6 >Jí>µ6ð«ÍÓÅ•àJƒ)Ø]ñ‰Th04TD ÚžŒWÖ… ø{Zq°Úñ¢OƶOhU|ß½Òk+¡–V·hàa€eQÿjó’”( TðáP™(ð9%ApžËåîÒÅ=i| Ëü¢ØM…išqA`àcð;QQ0à[^Q0$Aê<™`vX½±2®Îzds“ß׿ Ö‹•7…KGÙ¥ò%ì|C«¶ ø;wGž,‰/¹SYÀí†øƒhDDnÿeÖf×NØókøÝëFÁ‚‚qઢ`䊨²Mµ¿`p¾|¤¦À`ùfv…§Šþ‚ÁûkƒÈ­uÁn—–lrò¸àï[`° ;§›ÓÅé0…ÁCmÂŽ?#0x$þÈmçGª‚à Â惕‰+é|¸¹sKûUG\P\få|æÊÔÜ+ Ϊ?¨0p²Ÿ°À¸Žö×î/¬ÌËžT°…Á â»00Æ;Mà)Š‰× ) ödºˆü;0°ÍÙ<ViÀIÆÂ¬xd¸Œ¬Õ`eO‘ÐÀ[ 6¬/* ð¡&0 ÿS·`°áó¼Â`?ër_àÇKäC¾âY`°¡DVaàWW®ó °<« ø ù»¹¸ ¸! H´CÞv® Jlß* ’±bR$B°š€—pÀ Þmªßc¶Àµ*ž~‰yJBÐ 4*à;&Ò´@*üú„¤$@¼¶ï±™g\Ö’?9R N+°iÉ#‡å ¿‡ïVà§ôKS„³ üF8ïºÁ‚v-a½¸Æ'×™µÀùÆ‹½Fá@»7 |\ò‚JzÅþQ¿qÐÎoh‚¬…ØFˆ\`3NÎÇÚ ‘*<àR°ò #˜´äѧ%lõÐ9BĬ}À!žð¡{‡öÌÒûÀ§ApyÁúUqàù‹SqÀëµ¥†* ÜŠÒö¿Húƒ`-H… ª•ç³Ñg%Ï<¯f#”I* ›•<¯˜³‡Ù–)€ؑâþùŽÂèÃ’Ç{11Jo  ˜(>F‚Ù§!NÉÂb‚|‚v‹‡ó\+ |ØÑYɹ%¥ñ"/Q¬‡(Ý×1¾:rªý4ƒø)}°/Kà6âc`¸®Sqpà˜ªº–‹-®zc)˜)F䟥ÆK ÿÌv¦ØPÆ”Â1¨4@Íô†Ýè¡E¥¶ã£­ô gÑÜðâ3²{ª¸±CÃíÒ⊔x਴ÂËi™)CEü°Wàê‡l%Ì(I©Ù›ØT_\èU¬/Üq.08†Àa0aYUƒŸýøO4°CÅ ‹J¡ºîÐ;g¥ÁCÑgûnoµŸM]²¦”l&$YG¾8ØÜó;*™—ZziÀù'}Dù^_@-LRò|¬(þÕ»*WÙ$%sáÎô«yDfì‰ãè’l·Ãü¾e5|– †&»ÃÌݵð€[Âü…õkP ÷>‚ƒ(Ï àx´:ðºÁð€7ž´[ð"= °üì­ öûë ƒ=/ ð‘^i°âÓ¯ÖóÅVjß+°Ú!µÁai`MG’ItÄ$÷,¡Á˜ì0£{k5Á!,ð'U¸¢VøØ3Ä…ˆˆìRxÕ hp­ª¢À®(E‘gn{yß}UÐÖ-§ºT°UMšˆ:¿_›mrLÁ%V¥jY°˜µ„!HDÝ8’tÄ$½¬LèÕ¸l,²<Ø^) L·(8ðÃ#³Å„ˆ¸ ƒ•é.4ð¹gþ+¾~±goØ<ÔeKê‚à˜ :G$×[ÇeÐ.Ü™<îì¼ðÞ›- ìtqÃLMC}ç_޲¨Vô~åÖÚÛòÌ<+îî,ƒÆ ›t þxÂÊ[ÙÝŠ÷ñRØÜ³)¸¼ÈqŸØŽTÌ ’‚?Å:²D¦É&þ”ÊÁçƒø «8ø±þ}Âß^¶·ÖÞ¹gÁ­5vçëfBàHÆýÖ)VGƒ5Û_Úœøõ· .ËàÏT+¡_Tš³vûtäq€_›Îh“wm`÷—Ç5Ò |²ÉŒ‹ˆ~š0òçK`À½aU œóè|•¯^ƒàt_žP‘¨Xä~išp$ÓlFoÐ ¹ÃŠÒŸ˜’y'±z ðYÛß)$ãÅ+Ág78qà$ĶG"ÇI©rà³MF{hmÞf6êT ðŠìxqÚÇÏëJC—ÞЃ)@ˆÆ‹؃ù- [ ‚ë l”ë;j4 8ý¿[GdÓ§ÞRñ@À'—!©¼v€©fÛµ ŒBñ@ÀÙWM8YqO¾ò€ØÝ<˜Ö‚?ðÀ§¢®8Û‘‘BâELêƒÀ‹È'GnáÀf´¨[@€Ðÿ0¥A„ÈÛl5á?;½0¸H­”c¿È¼$‡•‚nÑTi0D4À™•ì,a[[­É§U7xQ^ªì¦ÄšìWÏç¨ÓF»ÌÜpšŠŠ‘ù‡º­É|¯ô+w™ß'µ øÿRXkrcwVÅÍŠ/`¦çT¬”è…ƒ'êž, '8 8ŸC„ ¾…[Ë‚…Ï•J]\Uâi59Ø]憟™KÜû¨ïȯ,M8”¹uUÉOh,­ß þBý×V¾«QNðwî÷ñŒ°?òՈȲyÁAæ\6U Ds®eÊÈÁy¥Qà6 Þ‰˜O°c…q±c˜Î/%BâD Jƒ1P'´üß:¯äx°¾Ð•p‡ôIí>Ñ~Ö§AFrxÄ7$ÿÌÓÀ#°&×Oì* "Ù€w…¨}ÊÚ’w µýYµP' Ø­+°†œÔÞsà7ñÙ†¶ó*r¥A"$n|þSªÄ{•xýWiä°uA”D¬Â$?}´8°–ƒÀ€´óŽÏ_R¢Çºßißá<å8ˆ ÊþÄÒ‚Ý”t (;‰’èkƒà’'èŠh·F( ¬=yÆvþ7 Ö=Óÿ†VÛA æ9Ñ…’”ô Ãjµƒ`°ì2âCi€ß¾þs Ïi~Ì8óæé—B‚1ãÂFU¹¸d¥&–ò ¸Ì„¥8À܃õdq0r—T›¾ä[=H~´°\dZÝÀGËbqà×±øT»ÍÞ„ôÎŒöH8—º¥“üN|«:𶃠)IFd­±{[aFÆuï2òuwÚ2[LGRpøŽà HGœñ!©8À³ºØ^á'Çæ Ã$'³;R”ƒ¨4X€¥§°à©Ëk¼ã#–ƒHG `€ÚžÂÀg#ò„^tDün)‚+Œcp“uA×ðÀÞd±KÒÁB€ƒ‡šåà÷O£Ôí qø¤—à€ÇI•ø¾Ë ñø(%ž@ðÑÉ *+˜H‰>ødK–—0ìÖ.£=É:ó6Æ D×ÚýœÓn*xJ¦<ðËŒc°ÙÌÙVr­Ý·=ñ(ûA#;6‹˜xdb"Ž DL´çÚwvpŒó s£EKäÇ@¹¿¶a.&åíã‰æ7üeV”î¤>Àææ‚Ná)ðÓOʃ§âR—Ý9êÁúR²½„á‡ý­Â‚_t¹²b›ÙüÑíAb¶ `KR¶ç÷‚  ‘ lXÎL#¾„Á-Æ«½{â:…É_fÅßDHÀMH "Ñ<–yâ·–(Eq![Í#5è‚‚Åv&n? "Ã÷'cvfeAr`UÄir²Áº;Šm²ÚÌ㯠ÜD!#ÎÚ* fN§“ôdt?ÊaVü™Züd¹|ÂAp™Õ7Å)¹µ2H–KQ÷mn„( ÐÃ\i€ ¥ H\¶ 〃Aè ÖÊ’ˆ”¾M@¿;/•#c Ö‘èîRPØ&Á]{„«@˜Šnéj]àO¦Óõ'X¿ï“ ðkõWe€¼¨•¿ÙÎ)‚߉?b㨦%=ÂC…~÷$:9© ‚Â3$@Q¸ê‡Ì®îÍ%nk* ¦1Š8°(à’¨²`GA…ÁÎ_½ª4 XÌT,½GoX¯Ap°}ÏäÀ(ß+ è}¸£n£RWŽý½ú©Ñ'ž 4/¹ˆ .•{·–Vl³äðš·$KŒŽ³5œÏò(-’~dQpVg¾EXª(`χh‡XÊÔ ´Ÿõº,í(aF­óÎ’‚eÁô¾ëa€sº[¶d;KX#[2vÅ|»g ËÁ Šrz-hø tm€‹—ü¯FÄ'x0b³Vx°l|=Kyœat7VÞÉ>6yzÃ|i€ÝµÎ¬×`þœoðÆ]a´¡ÉóŰTiМ+yzíý‡múÌåcR‘ÉÉF³oÖtœ´^DŸ‹¸â@lˆÞh€¢^·dÀ-@­¢”Tô¾é½%ß' Xºkq\Xqi'oØYÂü9ûèÍ»¿ÈçsÈÛ¿"“}i°-IiðŒï(YQX“aBPðm™~Lø€”;ŒÉ†>õoL ¢´ÔÁ»‡ CPLÜEieTðA©çâVÑ`zá'C:^H-0hø)¬4g:ò‘Éü$–ä(?¨ëè1O²• –67†‹‰ëÈË ßáúƒ ÉWql3'Vð‘$&D…ô ÛÑlið^I$Ä QÀB·â ùFa\.4ÖŠný*ðaRp°XO²ÏMf«l¡ÁÄ­¡ÒÀç"r ŒÂà©u%æ»À ‘ ‚F!¹½f·•xTXp(·œhöËÌ+Z>è¿îŒÔ§Ú„³dô¥Á‚²qe+<µOˆJÖÉTDô·UÖÏ×Þ0°…ç·R$‘É v%ê3xf °¡ ]“;rÒ(`oØï3XøzwiXî§A2P@k¸Ø‘ƒCŒÉt+üÞÒ`ÎBRƒm¥Ë™ŠÞz*8Ú ?†ê5ð¶#³}úÑx>ÑÀî.NØøŒlAW oKjü ~ Þkpòà,øˆì¾´´Ìˆ˜¤"²[xÜZ¿]„+"bøA¿n€¿Kÿ„q„2Q°"âÆ;jµQ¸šÕâÀ¤¤þIRõ8˜>b|ãÀn/FÅÎê<Û©8à@?]_|¬Up4Èî«DÕA°Ê´ |Ѹö l‘S`•Qp€/³ÐŸlŠè/¯% ¶WØx ¾êÉ*s;‚sK(im`iՉЏ¢þ.­Âì† >3™WØÄo€dR×U’³¬Oy’/:bL¦ ~ĈÂT¿qògšÏa0aÄa¥+ò®d¯±Ë\z…'Šƒ­a¿ªC…‡"RËm÷C…aäˆ )< ð 0>_{ÃÀº 8/R`€ýµÂ€÷äki¹’ŸÚWJN4c7¡0ð2⌥M6X&ôTpx’ÖÂ[pÀë¨5èÄú Ž‹Åýz–5ÙdvåªDB"[l*Ø Xq0[LG{aI£î#6»V L“‚›* N§eK!™1&@hÉEüŸÝZf¶¤•;»@ÀDZgž"%bŒ!À¿®’ì2#TDH´0˜ñs¡ÅýÂ…,5Œáé5¿¦páVùMƒuħz¡Á¶'ë‹#V¨•êPCÐv»Í<¸õÅaÇOŽ_cãšÐ€ Ì…‰ÿ¿Ÿ7`°ûó*k6cô­La`«ƒó‹ã•ƒÀ~Ä9•;Lkq€•Úol/ôHT3â]j¶Õ›‚ †ÌˆÃåàXŒß<8;)w³}jûËã`à±àà3 ¶×þ3¿ÿÄ·¿xám+,`éý¯™‚G"EQð”/Ù· è©í¯ ð“ÞÏþ6ˆÛ ¸È:¦ä#È;b´¬/zçþŸz]É+‘•áf/ ¼àR80øº ­, ·;.†UìÍ6 Îm0ìøñ’²€œÂBÖ²å/mbúÄ ¶,j•Ø€+ìÆÒŒb[¥:Å”ކȮwV¸¬u_d `€.ž ƒ½%0ðㄇl•Íd=?¬¬,ÀèZp2DÁÿœÛùg6¸Å [R@bTà?¤•ÁS'ø½DçÚ±‘¨Š~4„Xò ܹö÷V@Ò&Xñ}ª#é,ð/¿;^œí•¥óZ£ñ¢_Y±*ªšÁŠ?Sxp¹Ñ%<ð9'þLÕ ~n9^ò`÷Ѩg½c³7¶t' MlÙþV4*þÒŠƒ$+9hp[R‹;_ä§q¡o#õŽBà#»Ò€§é2Ox‚“7&g¹é7´u¼è®ªœ4˜Pø«48?`~1¡Áˆ[•ƒÙR8iàŒÃŽ_b¡&9uG§O¬Þ«Ùà)Ù€ÛgQžINŸÐЯ4°G–f”¶* ’i‚30à7Knª¸q‚ß^d{I7 Ÿ…8e¢Ê+ Ø¥R>!T…5&ìo©ÕFÁÜ[;û„ŸoÍ'¸eæáÀY–^_ŒŽ±$ðƒÅŸ;$À¯•Ôh}¸Ñ&` «m‚×½íˆw;û]GXÈh8’m“ÀZ’²€þO¿YÐ{Ne³¼ôàP;[ÄjY0`]Ë‚…oâJYÀ­a- |.êÿÜwù·Ê<ìø~JY€‹ºÅœø …à~ÂŒ%È-—]^l‘Ë * —/ øÎN_cû ƒ‹31:NxB0ÀÏqev5Ý,h¸¢\õÃhYiǯ•¾EXfüäè0gÒµ.ØQ –aš–åëgýp÷‰éÃŽú†F$G‰GÇ€ÇY·:„$ñ(9¥ ’ílÅc`W'>0¤,,õj‹`Ë,k€p7 8­ ú¢,D¾¾.e‚½¢à@·¶K‹º7‚cÀŒL9«äË?XÄ€æ¢FwTü`ëEaÁcƒEo>ÜØõÐi¤¥{ëáÌ‘§…¥Ä›ø¢e^9©tÞb€MX‡à…Ã1¹°Ö6žŠÕ¥Eœ¹ °›Søƒ‹ûƇ.þ<{3› ' ìó€OOÙLÀ$;AÁŠ=–ÈþüêŒß«[rfTüFÁþž¯lŠSµÀî,F,à <ºÂìaÜfÇÞHhä›DNd›hÀßôº¦97^¶¯'ø‰¯‚Án.NÇEµT‰xè ƒŸ;ŸhàW˜- æ‘goJ|tùÒ pShpàeÙþ;*¼ÍÓ½¥t‘~\hÀnH¥ApŽùÂ/K‹žv”0£ØÔ[lÃîÓŽ²xž‰ÉU%Ç‚Öð¨+‹‰ûpç/ºì(yñÐÅìA`: ¢|†›ÛÊþpuk‡X5ÝJH¶~£ƒ…Þ~ípƉÂÀ¦›ÌÍÓ`“k#Ž«d]_M2’­j0ãçç+8ˆTƒ‹²Hj›vÔx§ò`¹8;UyÀ¶Óƒÿgµ8=ìóhÄyŽ.+qFyÊ7Ú*<h€ôþ „6F;ÌÉùÕd;u© ?KXðѦ“E^s®8`U¸â ­p0³Ÿ¡ãaqвꀗkå³'lì(ÕÛJhá°Å¼fø,ıŸÓÏö$u`5!P | "ÐÝ"ë@¿Q0p×o2ˆ.1ûä³K1&†#œ °«“6Á­)EÙ&{äE¶ªÁìmÛÙ P„­(hèª(`1²Æ¢¶‹麿ÌoWM>ó£ÅŸNô ìõUëDž—HBl8ÚÖËJž8¸Šê®'œ0xÈdÀV´u> ª÷ôé^B¢xÉ~iqƦ¥».`°gÑ&Á]v?PØx°²`½Xî–ܳàÎVh5Ùdv âhϯòºÀ€»¬ ƒ ™¶À`n.Îø?»UØ[*;wý+Ì ~û”Þr´±¡¨ö ‘1H:âYpÅ~Iáà.l5µ8 QÐÏTà'£â ±#oœ,µ?­´ñ!¿ÂƒyÀÝ :⋊| W³­ lbº?»xò€#çûy0á§TećpÀႃ$5ÀºŠ¿¦ÔР~d+,ç“?ÀAÐ+ ï£àÀ²€…cÁäĽ;‹'šiŸ`§‹;¯/TÌ/– 8ϺžcÆHn.šÔ³= LÇGDþÜ س\;¬¨Ïø‘·aåÔ늃gRÏüø( |¢Aó7X'vÂþåHhì'#öß×SkÉHÁþ<ûE¦O˜!P°¡<#wQÖ«@/F.Ý‘é;v¬ „ÏaG{‹ÊÆ?©¸®ì¦˜ ð[|o¤`ypdwX“ò Ñ x°è$8 Xdè³_QÀº¨ŸqT¿vàíG{âFÜfüúUìh«ª<àqxåWø­ª,ÀÂRÎ.𴣓ö +§û´h…9bA à`çV§`Yðž/&Cï>ZðA+,Àþ¹Û}t1;X¿Áû;‘œ8kòÎKBƒg¦ Xý†A‹ÒÏ6~G+ pÚTY°úÄôe œÉGãÕõƒ¯ð fË{†•m Âî¶d¬ÀÙj³€5µᙥ U Áþaý8X“Ef¿¥°ó‘´wt±_qÀµgí‚Ò­£Ý0ÀéX÷ý„Ùº R â8,©4@,WÉm¥†ªÀ/¼ÓhðqS°£m¬Ù€·ÎØðÿŸj0buú%Ñêmâ0…ú“¤6HΰÛ‹øwuœ,o½ûÙ¿éì ÑIf«#Î>âäˆb ‚¥FºôìU´šŽ+ V~Ï+ ðaSaЬßÀÆ¥)"0àT3é|D2pÔpð”ýˆ‡D¿a0³ŒqÃ}”¤øûì3÷ª²§”·Ý)'V6Ø8¼”øâô—›/ .›D4@ÝSD_°O jë ûðJƒ™/èÔ>?„•Ûâ‚ l0ê8¢ú%"ötJN•ª{ Ae€¼³§€ªT¡Á…•â†l\hDZ^R±(àWGQ,0&•¢²¢ÀÎFôîvþ.Q âÅqÐ:OàHŒztFï³³ÀZç 1© ð÷·Ö;Z L+m6cRøhƒÅ˜ NØ]fTJT> 2N< ÞO£$ð虺`l²Á tá÷Ÿc^ÑšÕ­ú…1‰>ãTLˆ 0þ¦²Ÿ²b4ˆ† ¾2@àdIˆ| I‡ ¶K8|â¼l‘Pƒ@3ÀºÂàGüû@—>òˆ·à ‹KpˆØ7ß/Ú6á¬ã°èvp’¾â (X¨Å2C€àû„d•9( |êN‡ú'XSr[£þ,×ÊÀ§œ\,¬Cr}Z•#êz•ãöy‘yóaé#ÏÈ•‰b€†íÒ&rÁSSEÜ=Ð!qùm¥#Ê›x´pÚEÁÀŰ¡ÓÅ>“‚ÀOìR$ ð=‚u$·ì3ï~JY€%y%AÃR°’ ‰?;øÃ£(ðeAÛ?Ï7ŸŠ:r˜ƒÎ£²À‹‡|£îK³”D¦Uq€òVÅÁÏ‘˜O8°ÛÌ ÖE2P@dÜáªdj;zŒ[´½˜ØŽð¹®Í‚µ-¼f+ËÌh`“ .f;šxd{Ä©PHæ mǯL'D¢u4>k_§ ¾Qj: v76WàKXPÐfºùÌô‘× Ño3“Nw„^´l=!XUBZY`3–E 9¦‚ï†ÂÀV:a€M=ò¥‡úàg¬œúPCBÛQ øxÔ«ê „1© Gd×ñ"ÆjIm0ömAr:ë̜ܺ$ñ¨ žò ¢8ªBâ:J6™Ÿ˜..œµ#0àONwe€…§î1ÛÊ€?ê8SÐÏTø{*-Z[\‚ÔôW÷e5þj;:^ø©é;öZµ6Ø7\ôɨœ;"(H¶ ˆížš)ðHépä~'5qyâd ]8|‚IÂQ=ð…®@`kMB·¿8hž¡Žèí<,¯FÄ8•splíXØN&)hA·`bN"Øeæ _!v@ÝÝŸ¿Ü#‹Ø[Ë‹Á`!¹«’U%‚3âxZ–™ù&O¯8â ávë•øâH¯@ÿJïŠBkX¦Õèô¨Wq-X‚ðE®8XQd­8X.îÎT_2Žx(qULæ<û‰»Ë<âYîª$Ñé/Œ쨉+Ü€£*nì/íþ;º¤`sNžWÖÁŠêJo¿ð>7„ H‰~e)+½¤¶âÄ®ÞYŠê(ÖðtkGl¨ ×ìôoú ©²§€rvåÁ¾[øufüÊm^„W¸ŽáäÖðßr#²MÒ ž®ªõ×lü©@àg©ÁóÀ×+ªÞ²¶dƒfVEúo« ²Yû…h¶„¤®ØÛʪŠ šƒ†áA  Û«à`ûÙñù„ Ž{­‚ƒ¨<ÀN@pÙžº»œS@›Íf!9µ”ÀÀª‰#Û2Ô†d僑G¬ŠoOf×]4>qi©ñ Ôz"ûQ4CÝo.á‹£r¢×x[Hh`窱?ö´O0–11JP`ÀîZ•b¯ŸKi€º÷ñþ ãÂT•U`€e‘z”}qàO4sýÙ’:.þºJ´Ç8bÓß}Qaç]*MMæƒrQÁìX}ÖfaÜítÁ.2ò _€ÀöãÎéÂø¶J< Ÿ¹,»…øKߨjN*xåÀ;”ùÐóÒ€õ~¥—9é«Ö ‚„}”%¤²ßB“}§°øSKsÃÕ™+°ï¬²Ç˵8LôÑöÏ`×9yRÂNØk W@eÁ3 í"ÌꆎÔØ„kmølòÑÈyšƒ "µ±˜&$‘ºq¸~µ'ã'¹»4˜Ð`Z,‰c&#rß[O²âäO2Rí¹öy>̯/MÌîŠ2ÄxpX<‘Ÿ>¿Ð ö‚Ú>”ÏÜ^kúD„Éíµ ä€ëý½+„u¬ÀV%BÐ+àë¬Â÷ðq±zlé‘‹í`µ:HÖYQª8˜y¶#â7ç¯âÀl]þBs›‹¡\SÀæð ¢Ná¡ê`ßñ«®ÉˆG9Xn^p‰@p€ß¿Š¯Dç’VoŒTà\O\HÉò’ÏOG£Â )ÚEšo¥ú¤8ðCÆeº8[+š½Žxø!ãrŒÎ ìcRù‹% ɉf>ÀRi€¬ï¸ÛEˆ³F$ H~¹™/˜öÜMiRÐ.°ÙT€Àúp‚ÅþUÒ,$<°9©Í6 ëlç6\x€Ž:Yfôc…u~áÍ=Åè³}­M›Û`ü2#ê*šŽøHìÉû­H€@ø àXMDÃïú žDëé˜Ñ〯óTŒÁµ%*´Yð$¬‹d·9Ùg´!Hü4é?©ñ È:àƒ•å) K 6ñÓ\yÐì q°lo—$üŠv\z÷«ÁöüwÄö™V âo$$ڿ۾𭈆t Ì•‚ž wjïdd‹œ\uã`ó1êc4fL‰ øR¡A;xª¢××|ÔÛk·°Î’ècÔW¿ß|¾¡A·+¾ç ƒg‰í౺n,$cF4*Uà»Þž¼L°/Ù'3ëÙ•ÜŒ °­•õfŸvÀ¡%ÝòÁnW˜Îz9â[lÅ¢lÚ…ã|bãXÂ6si-@på7ìÅ¥6Ÿã“[Ÿl»…§@°Ñ'æ¹l’¼UØÀÔÆ½oRtŽ›hÙi Vœ/öß*øÙ%íB{-’,A»‡ Ía|ΕèõÄõŒZ ,¼JÞÆwΫõ`™>ˉíŸÉ H4.¶+‚&ïJÄäÖ ÑšZve% ¾<ýÚAžÌפ8î¶ãP×—¼ïÀ¯/ñfw7 6ëB cSGüìˆï;) CÂÇVeÁ|‘#)çÍzs˜‹¶}VNØuFvš¨’ØÜ-Æ‘?ëB‚‡V›yÓL,Xtß±#&– ‚XxtúWŸà³ò¢®6—ü®ÂÔðWîö ,ȲÔ9™OX€?#e>ªUFÄ€°€7Xe¬àP°ý¤{|b]e\±ß׈Ąä&4ðAß S v޵ª4ÀaÓo4æ \i~&âà}Ÿ0E8à:W"ÑìãÁÇmužÀRšË@z;Qþ}ü}‚(pS'Þ ƨQxø3º¹”È>JíËʃàÔŠ-öX ¶DA ú>Qy€í¡œjN2Sv¿ÕÊ<øªÅ+µ8`w[¡Á{ÍÓ¯*¸À#ÓE'ü Ï40ícƒýʼnr räM¨ÌÜ¢U Êo4 h¯Qø=Fß* Jƒ¤W°,à“¿Y°^|Ø Øiׯ!¶èÎ ?o¤6àSžB»ªp,üÕàØYz| æÑÜYiA€róHûÅ(JÍA³€Âžò੽fσ•]:ʃÀŠˆÖ™îcÍ~QOM*  ‘ÓLôr»ëÖ@CäûÒ½VÄÓjmpd—ÛñÓ,!&ÿè7¿Z\ÕNÿ_ié€*‚ãLnAz2Ÿ.88ÿOÉêR‚Ä(f܉G n5'0ðÙˆ ý“½GØæ×¥8°[Œó뢨4Hn·»­í"Þ§ p ¶»6àËŽ[¤p \½­àvšßÛ¤øéª¥Á…E§²ÀF'Ÿ?ƒßˆªŸ³Zœ¼£¦.$@!Dû„`ž0'$@ãÛ­Ó V6Yòíw4俲ÀûŽN*©:¢=¬0¿.îzU[rp 5P ¼Ù ÙX²(`寢 ²$óþ]E;ÁöçžÓ –q¸Hƒ)(¸Hº,(`ëCÕ 6„vÂÀŽxïPºü~Þ( 8°BaðTj2Ž2Ã`=øôxa°âÌJaàO°Í¬&õ÷ ø·d¡¹ c{áY4Düuú¿³Ô²ÚÀ8Ñ·ö Í&#.ÃÀ/Žã¤6ð#…iX­Šh77ü x|¨ÕvcÁF3wc·úë>Zw6oÛºþ­+; kyÀABq°[ 3º^*üwÁzCΧöCJbÃy€žbÃJAŠե"u'A‚VU8Øþ[}‚]bäÈc­àï+ÝBP<#"ž½‚s¬§Óô÷ + eÝÇÛ„Õ~ÄM¦ÈIúQ ÌøW ñ‰ýÅ}š- ¶h]‰-öõ<«;¹ô® ¬ýh–‹“Ty%(°ÂÁüswö ¼Ý )ðo]WòÍÂŒ,¥Á3i'Û`G g³XQh<Ò*ðíÕƒÿWBƒàÞ_ÙÙÀí+­ùhÊ`àË,ôjYM’NOûÊ<~ª!^ípt³€­kR47Oð©Él‹ÔñâS,H¼GX¹çvûÅ>ï»ÌX+WŒÀî/6ä–v žÉ}•hi ›‰;$À¢[I€Às p!r¸›(ˆABêdÌIŸÀ‹'UCÄ—Yh`—†GŒˆÛž²G»©ùÈÒ€?_µK˜í™æ·‘æÕ–ìî²ç18 Ñ'&óueua›ÕP׿Ô$Œø" qÎ þœB2P˜qëDœˆAD*NxŒc%4ð]oìþ¿¿ÞR¶‡÷(^Ýi8Ê·Š8uÑ¿9û ßQ±"þ£ « Vç?òÉ §ÅA„ƒ`¼ˆoé—̈¬eL<»ã6p`g '|B꘤ ñ.dåGÓL( üæÁEwSx°ó}£îˆTæJ-¢Æ#ßî+@P`®@ðC…‰]äµ8p§ßšÁñ9à` RYOùMƒeà‡ú_ñé‰59± (±vk¼@P¤Ä19¯rþ;ÜA…÷{ú*%î/äFEÂd¤.ø[ð³/ó‰v¥yCœ4 l3"ðW<ž‰?ÚF4Õ 4ζ¾±ÑŒÏu‚ÍIGäõ#r'PyÀ¢¤!˜,¸ƒ o DA©Ž⻎’dÄ# …8g²»¶´ o+¹Å¾È2`ÄŸ)4Ø~ÖÞ>áÀ®4s̸à€wûq°`«þ¥#;Æ Ö>Øït >ÿhFq¥ò€7Éä¼Jx¾O’–Ám2®67ùâ¸{8"Šô…Q‚ú>` ZiÀ3•Ú0ìøi® ÃE¨¨Zƒ]F ~VñƒIP_ƒõÀ´gý¾¡RDƒÆ‡F ÖqpÒ 9Íš¬*à^i`Õ^.`Ñ£òA0häp¡J¿" ˜¤7 ’A£UY*8˜¢Eƃ?ε8ˆüG¶:/ P±"–òÀëóÏÅŽO<ð“F»¬°qJ’+ÕÁ×,LöºÊÙ,DáˆÉ Ñû“yiYpào- ÿ_Ê|ÜTøAãdO1¾¯>ÚA@§&n|p¢Ò Z]âÎW`à;žÉX!9J`€mÍF´Å_k¶cÆíÌ’ÃkˆÉo™ña£ÂC¦l!»MH þèˆp01I«À?)p®^pÀXÿiVïJœ²m¬QÅ•ÈéYÕx€(Ô¥fÜA R"¾¥•ãøy«ùäÝjnøëJ”:¿~ZqhøuÿðÙ¦HHº… øKë¶‚M9˜ZZõTs@„™Ý 2oôÃ…ÁÎW{ºýM„G‚O¶ eÝ*&&Ã…diÝ‚˜ƒ»©ºÑx¶¤ÞŠÄ•Ô™h‘0˜,õ5ÉRÇ÷SϬ$Ã… FHN°=f=JìèûmÊø5îÇW©Ájó8ñ8XÙTØÑßÔ«4ˆÔ° „ŸìO³¾÷›ýiÖ ÿY¥. ÇôykaÒÔƒ{ŒÑp!i’[ÍöVó ”oWÀoN?x¤$öÕž!PöŸW&àˆFÆ VPÄ)¡¾8µ>ÀW§ŽB«rŒÆ!›•¸LP”^ó’<õ <À¦¦¦ƒS|lê‚ïUÂÅÞß LH–o£Ùð“w…L}…€u¦¢Ù¸ƒ™·¿EBh0ìÁévN•Õ~Á)ó ëêÚ/ ÂÒ}{iÅâ¨z‘2ÁÛ× ©[o/ñåÆz{ig-¾ò€×_Õ+Þs._/Òûª3~qj»àç £]rfãt¡Áòb)ZÓ< 8O÷[òÞ ¤Ö}i‰r”½û€—D@à[*R àó¦ò€55œi¾ÐÏë¼ñ«2ƒª<Ⱥ¨õpòÁ»:ÀŸÑK­¨X빋ƒ¥ŠR´aü¼å¼±êü ØW 8à`ZÿÓ‰£m¾M£8À–Kqà­‰,¯ˆzÐ 1#ùá¿„â>0Á©o$Í‚u°Eû†Ég4îU`—T•ƒ·ák|L Ðê]h°üôdŸh`Í«¿½´¾Pþk­1 Z”ô ÝZkt)Êoé  Ap¸[õ;öpe:?© ¼r0¢¶Â `A´´`G +ºH –hÐÈFÉJÞ¢¬B"OÎõ_§%1¸âŽ_Á‚ƒuYrà£Sùâ€ã2n$"E8xªWÀQqðL6Ú8•ƒLs°×ÈøÊƒànó¬1y)qI¬| ¸_KôVåLKŒRPPð¨õÁb­Êç/}q¼²Ícµ@Àʺa­–8ØÅF¾Ò'Z"gÌ -1iðÓsK=À·´¶ XD(‚á–…ª%z³2Û%Å&&žD6™8ê¶çR!øÙB²ÈäqЬ–8G‰‰¼%âoÅŒøT-‘G/.9õ=Z0‹ ' ÖÁµ ƒÝk\PÌ–Ic­Î× ë>Ö¿’úÖQèNRæÞ·ŸA}€SsÁ¶22* ³²Ÿ4b!4xÆ«ÌKà…k”‰´sû+˜|yÀÏå RþƒcU~ÿŒïæ}p^e¬>{gâÌòǧzv%èðŹu„Éæ„ÞÄ€Á +£‚ƒiã ·zÍßhœ^­ñê¬;Ñf«ÏG ðÙ?\ÀJ¤-B0]àvó7Î:Ã*íb—^‡~ÚÈ#©Kë=˜üxaæ$H!päFcàUÆKCý@h‡I[_øÉè×à)ʃS•;Óo,°¨¢èy€Sz©’†Áò`mÃ0F ÃÆçÊw´u?K#,"*–¬Å‹ä­H¼nQp0M“Å/LØL)ãþN|'ø ¨GßXoLê¬æ¾@X‚{ cR lv{állƒÛ+#îØ|Š*k²ßÂÁíwÖýBÃÆ¿aJ¼ÊÁÀ‘g¶µ>hãçÕ%ÈQññ'z"~·þª|Žêå¨>c?hɼ1‰Q äÄß,‚MUffx%ZžT A¬2:¤a0GN  ý¼; …=w‹© ø;4,‰ Öó½0ËÎoøòÀtßß§>Ç&.>Huà6©Ð`äãRýÝýRy°ã/-4H¼H ¼û€ml©4¸H@«4X9qTh€›&2ntf¤9ˆBÙø¼|ï|¡U˜£Af@àó¤ZXsâºØ0”y¾ònl¼²R€°`«ý 'ué³;q rTüèHyÀ>d-V„ÏwN·¶ƒ³²+’Ó­|Àª¬”èYRAÑ·ï&@–ì&áb¯¥ß÷~ àÿ©!ÛeBÉCõD|ž pß_€°ìÁÓèð©@XÝa÷w_fN·ž@pzâp`ɬþƒ`·Å0B°¼€Ö·€ðT¿€¿´Áó ?0™F€0ïìt”~!öµD@Cípƒ´w›©5ï@È€Ühþâ€ó2k»°ó},‘9».3ùí…ᧆø„»Ìęӂ¾°Ò/l¸­ú¿rcÓ— ŠÉ|!àAŽ„Oœ „ càxáÁÄ×Ôµ@ IHðÊŽ®úýéý<ðû k¦'¢s@,ËȰJ„‡ãµ@¸ Ðeg?p\Q¯Dø €ýD·Ï4Þ‚ðNž~DBH øòÝáA´Ž—òÀ‡¥ÍØ’öó !yþ4Óôºb¬ÛìË©<@‰E$¿íüÈ|¡­8Š.“_kâaØ—€€ÝüDïRœÛ2–#b[æ B;SÇyÃOs¥BðIØzÜ8ÉbEÅ`Í1ÌAàC¶ìy/@à³ „˜– Ry0â;Qy°Œ¶@pS†û2áçHÜàþCÂü`ÜKĆÁ÷ T¾DàÓ±SbSœ9¨¥ûžë‘2v î¹>qÁ±µÙa³±£—?P~aæ=4-°ÊR$ø7âkPÒ`}Ë£»Ê2°IJÀ3Å~$pº˜"ᙣmgÏdª¢âÜÑ%E‚MJš8y\j„`‘!<þq©z")ËÞˆTÖ—´z_RËZþ¤VpˆFår¥òàHrQ6¬T…îÞû{óÙÜd9yàöÞ W$%»äJS€ƒ§¦ Iyà‡ŽSpí—3´<°(àøeÏ34bÙ Ë«,àO{Ýz~bËñ|ÚØê`ÏL<3«Š"ô)ý¿í…Ó~‘!¶e¿Ç0¢ëOªƒÃ¹mnÚÀ%O¡ÁÎ*²Ð`ÅOªä $6EüdÜÁ_á«@`¹°_AÖýÃ\l›ÙÀR0rN‹í ;†7t¯9â;!@@•½–Þ•´e©ª°¢7š,f¶;Ö¡ã…ç_F (§ Pu¬AŠ?ùŸ€àö›£8qµ§8À"Vôƒä„#…nM’ ‰+ÉÓ (°Ìó üT¯G^p’iwŒâ²ãà[r’ 6nH8{*8X¼a‰LI›ÏU]Qð¨4`;Hõ$5–¬Õ“dõÄg¿•»¹Ø¶øØ´aEÄ Ø^pƒ‰á©naG™KcÓOR Œøn üÃ|¡Ö\Õă0\8*PÕ!8Ê !(ÐPˆ0û£,ÙÈ‘×*ô(‹]{ž¸™¬Hx<'ƒmv~'4hÙÁ‚v!°(²“O–þS$©iX¯(‚úû?-ì–ãÜØ\S×ΊƒD@à’Ep`¯0̱`ˆKÁnpH`q°e7Y°Gû»Z!𪑮9w’ñÇ &''v‹aÃæN+„àƒ.ì‘|ðÔ¼ }õ,?râ™G‰Ý³…yÅU÷ƒiðGžß<à´f9Êâ ||±{܈¥Qå»ÉÒ|FÒ»4hpa¼èVx¤êúIJÌG3* ìla9·ähCÓìÚ´:º……‰û‹W¾oOÜ"ó/9Èt!p#Yõ`á&²°àb)Ã…1±ve6pH«l8úHÕ…ÜID‘ªû€õžžh²£Æ…[ÝyÆHÔƒ€£I:kK«%Zëg épÁã€uµ88’ÇÇFh+<ØP7œ¶«<°Û– «êJ„ %‚/ lDÒ¢›Ük³Â'-tw “¯ ¢üƒ}Àª ØýÆåð'šÚ[ï÷4Àx•ý¨ñ|"6"ÍÿÌ 2,¸&8Àtƒ/wŸ°Ü²QcÐ,$÷qV$8°0¸Øý ƒ?'|«ÀyÎ „ QÕ· üíÒú€þJk>ØÛoŽI‚¢µ&ž³õAk÷¯«vd¢LÁE×Ùm›}fÚ`’ÞåA0l\8×¾ŠÉÍ6ü®ß‚?èÚx§_E‘IúăõÀ¦µ¶ 6V•D<@A¤D,Ôj»0pþ¨,3ñΊˆn´pÒÀÎ7l¥ÉrcRìø?û–÷_@­žÁA˜†>£~-qedTlO) 8îZp€¥líøÄ@ @À_G[wÕu=l¨ê¾dîD”W„üù©D@Yíˆ ‘m}°sž‡Î>›O"ØugöE 8bJ„€8ôýøj”N!Q¨W$ØõÆyæ‹­ ~ºðNü ޏ"ØPÕùB?¯Š‘ɵ +‡ZÔ!Ûfò%Bc³{õ#ÙLÕiÃ&R xð:XÅÁ0ÚvÁ.;³ÙMpÀ‰õ‚l¦Ä}€åù—ôD^ãà×ø†û è/ÒìÍ“_dzÜ4¸H¯4 ¿«Ó›ÈlU\qpñÜ/(X£UgÖ™ÕšèY€oÄ_µeÁìטöݧ'¶yÿ<[˜}žêаÐU$Ãüî PŠ ±å °ÈÐná!+º7„ø$ÑÚÀï2í~Óy|ÍÌžŠƒ‹š¹âÀ9‘–è@“7&ò’·Èô9,<Ø¢ƒm «‰gSŘxàÇG‰ØQT"LØ)U"lþà{û‘ë?ÁÎ8lç†W™wl$?1°"¡ñ|JcA_àãG¬>¾Y¼~ÀSh•5‘¨•NM\5‘=—J>"^€0eš’,4aU 'YÆãb [€€ÏŠÊƒæ³PÚhq`÷œWŸøî¯2ß, ŒªÙ±ZëÄœNxÄ.<Àù§ðÀÞ|_ت&„ _°ÒAóý‰‰¾<’‘&¾@¯4àûוì«åò‚•6ÿ3ÚMgüt4NÔ¾QàÿKið̽÷¶á“VÃTŸiø¦¢Š¾8ÀåY\ÀÂR`àϹŽ'_~¶€OH‰EÂÇz笑ÍnemáÈ`À·* ð •Úí š{€±4 |ÀÇH+ šÕGk=à3Šƒ ÷€Ýà’“8¸U‹Ll;ìÇAÒ,xððA¤D^‘°÷µâ€s*ºkƒ`m!¹Ö†µpáÁ‚¯NMIËÄ>6VÅÄ@FË .i Î7f<˜ý¹¶6ò-ŸÂƒ Ÿoµ@Ø.^ z¾‘÷Óª[™_0šÜƒnÕyðo’m&¸)Ða¥ÓÆÀ­Œ“;Cr¿9ýÁ‰ÑýF¥zÁ^gšG¬Ä { !p…NBX_~Ù™#·VBà"¾?Ju_ ø ”Æ÷î ¶ÑΦ÷!Mz/ùU ,³3+Ûœu¾&!<àáoÏV?†ù*žÁA°ë¼ró{ÈB=ÞèqÀ¢G­ޤ_ˆpÀž’Š»Ý¸¾°¯ÓFüüð1Zí‰ø ÖqcbOÜG¤®àñTy°ø`¤6ñ©C©ؘ´í§ìùDç>‡$WKoÁ¾Bv¿…rà$_qÐÀ'°Å¸û¸óÜøÁ_w™’Í…“ˆîô ÎŒ´\ÄvãGùXTßÈIãøxiøpÁÁˆŸùŠƒí"V²êìJ­Y(ø¨@XggG²Iªã€Ë** þƒ‘7c$)-¨ðß¹µì¢ëÎÉ5× @@S—ø‘ð(#G^$$þD>¹!HÀßH Ë~æˆY­l’*»7kÃùQ½$X¡a Qõƒ‹tNÝvöçÞGœàÕ~að@°ËÚ3´Bî2ñó¦òkïo… 'Ux„#%§X‚$Õàð;ëfcÒ.¬I®2»„„Þ€àÛ~#Ô«ìÃP„¨g™²Ãökãû˜õ²3{&ÔÀ«à«;ÕdÚ8»va°«|—OaŒGVh* °[Wõà±» 6)³'&—ñ‰Ý4q!+ne4ºËòB4_@ÓDŽ»Ø6i ð X‹¬¯ª!);¼€²¤ÁŸm\y ^Ï6Iª Ó»ªjPü¹˜û‰ÖÀ›š†’ô œPY‰,;?eXÞñP"$ÉÊÁ~#>sºÃç)¸äza6$$ëL~ÙyEÒõÆ'²D€àäÄõ@ótm»Lžœ¸r©ö›Óq¼°Ì×ÁÞeÚô…Ëvãîæ>gÝN6^Tp\Šd#ÝÂc4ð9ë·;w“¬4KƒóŸ±êÁÈÁ›Þƒ¨åA°ËÔpÎ,Ùþì¡ðË\—­?ñ쀰$"v$>ãSý‰8 *<؇~ %ÿÀÒ`óÉHÛøï»~Iƒ)INLî2á§Ky€< ¥â[~eÔy~a{¬<ðËÎl\íö+OcÐ/—\Ç·[û¡ #dÜ]ÀYå FÚ¦,‰ý÷•ø5{¢Ó¦½%ÓÆ™£o+PdÁœmœ‚ðD~fË>?JÁC¢e¬ÞÃÅF`%„àtã7>P€Óiðe®D.ò£*p¾"D@BÕaX-‚[®vçùâl‰½jÒ3`c¦;ŽO‰Ù€! PD=µ{ÃqäiXf"@àá®ß él…°bª<°ÂäG k–‰b7žÛàãÒ..ïV¬A ê$¢ vuÀ`ž ;·þÓÎî[ˆcÙ–ÙéwgÁ1HZÇ àSmøE×êÀËÁ°1VöFKm€›$ºËXqšVP€¶þ^‡{Õ”Xwî* fTkiÀ¡uÚ8&òÁŒ¼LmaðS}~BNäbMR v™¸´’ ¸»ð |‘5i=© ÂÏGº°ð)-Âr!X ‚ãh-¨@À:·•T•-F{ªmkÉxáêÃZí^Oœ9}RõD¬ Ä~€/³è‰(^ªžèàÓyˆ#HàÍAËÕ¢'ú^aÆ_è|@Rc­çF ]§J?S‰°ò×½"!©– Ë[A7¿z}Á· ¨ªU$Løë( –ÃÞsÝÖ ! uäJ>¦U‰pð¹!‚ç–»…Çv|6,OA~"GäÝ0 ìa¬<޵Í(fÜá~oD=@7Í 9 ß¶>^øŒ«zÀ[„zpAp©|`ÚiÉ|Á–ËáK„9™8^,ãÖ–_AáúW*ÖäVÛ‚ZE·áØÍ>Ó$(nØ+é5×`Ÿ)!Â)Í6Ôu…øàºQ!àÓ_‰`-ãêÏ3üEÖƒ,+g¯UÇ2¯ùI…à,Ë3?à*¢û vÀ0x"D¡ªûì0ð» ÿª"Ì/”Ö$C‘“öë&C„ã5 ís„â”D("áa¾˜™(øìM!ÂŒ5–á!Bp‚!ËD‰2“ v©‰ïø§ ¦ H½†äâûùøOˆà¶šV.³jìzFls„øÍ¨ºâˆ•|%žl5­8ÚÕEÓ6¼‘°:[’QäômAB²Õ” ³/¾$#44v‰ =ˆ7\|‰Œ/œŒz³Ï|ˆˆÌQ÷©DÀG!ÂrD{ ôU" „Y‰Å$q½V‰ÀH",Ú³,Ó±ð¦!VÝñ½¶Á ‹.GqØðÜ4ö ö+!~zî?ªw’U"$W]ñ“Q™0ãù =&g]ç‹Ó?• œ7ܤ8s˜DeBv·ÍU ‡ÆÕ¬¤({E&A:Äň€ŸÝeÀBK•„ k0Öå³F­-É)¾·ÚŸ¬ºã‹¬ÒâC¶¤†™&£»M‘1)(ðW"x!!Òp!ÂbàSÄø7&¾f!8Føé©£Gœ•VD^ìK¥eÀ_YD[ ìÑ3 LŽâÛÒÞ>Ç L>GqàŒÀ€KKA“Ä ƒ‡‚QâTçŽô×ßp"$¹ªAyЂ–aå)•ˆ¬RU'“%5Íw èšD›M6gy ’¢¹# ku€¹,>cÝ\«ƒý—•Á]–@TlæŒãäsvtK¿€ŠÇ ‡Y°¹ÃÞd¯<ÀÎâÊ{ˆal¼£P¯<'ɪ#‡ˆè™ç$hÙY“&v{ èo žê!¯)¶=âAàU\‚Ã,my{¡ù¯òÀû’vw—åÄÁ¼;Aѧ(r"8`«à€½ÕªˆNu•ªø~µÎj¢úÀÏx]sQ’à´‘»½äÔøBK»àŠÜá(¬U±Þªùf&aå¯Xêª<˜§"{ ”¶c?_a˜’ E§&¾ç ¼tÀy–B\H½%$!ˉ‰(¹é|Áš?Ê2-øèŸÆ¢$ÕÇ?þ 8–Aq`ƒ8¸’µç][ü¨Ái¶nµ_/‚gëvŸÔ†íÖ•?CµOD°.„ å`¾2a;p‚®Ë œøÖät[´ËTø°í—/nþV&ðõa³Z"ølU¿Ý4ó²hí°ŠèîvŸ­ºE—šfþ°ÊÌÑú’ÞAø+ Á»6Üöè/†ÉY}–↿¯Þnó»Ž'žý­&|Ó…O…%ñº­„%áç]‰„§a%Q‰0b§X‰bÀÞVˆ0$áë;>âÔ†àFŽÓÅH­ý;JÌ1X}Ž4„…PÔ!C2rD½°¡-/l„Þ–ÔÐÞT°-Ÿ0þ3ûÝgï]>8!ëÐ'DÀƒ[D°}ÃüB÷î)~ÿ´Fð}ÃÅ"l=ÿ·لIÚ2÷®Z#ø1–•h‰P"X§âŽý)›=¤m@íLdìc*ÖV6Ò6ùiø™/D˜ÚüyîxÁ¯@ã‹,Û ÁÜ1"YB”úîuâJ„‡„„`™o {°îÈ“IáörªÉ‹Šæö—^ è/°x¬¢â‘ |€¬”ì4l– Öñ"œ^®¿{Ws*~.|ÀÁdןw| ‚©ã‰/"°@ 8xh¹iõ׿lý9à>Lúmøʹ&ÿ}x±QX˃ģèʃdù™'úýª"îØÕ뮑ªÈÎ/)Pâ•ëïøÝ©åÁqáë® «Àø× ,‡ `ƒvïK:À#Å „‹0Ùv €€]Å- ØŽaáœÈ;sÇ`Ò€Od]e@q©v è¯P"¬Ö¶üŽí ħa¹+ÂDØý·#’fΆ©DÀO}I^T¼ÎTBˆàöŸO",óg'˜$°)ø¡P $»Ž-é±½¦d𘠒ú ‰C°÷FtËÈŒÁn:¾aÀñ|Õ¥ÈË=#†õbm§Öɦ£Õ.N¦Ô!ÚaàEÅw%q*£Úðx›â†%h¡Á:ù†Áï>£†¬›ðÑÇŠ,cX}g‡¡±¥æ† ˆë/–êxaxí oΉo9(¬a¹ˆ ¬DHêkK â’ÂEG ® BàK±ÀªÂE»Ý/!4œ¢"ÌûñÙ™t!X}¶BãunE¦ÇHÇ€U¡Îþ»EÇ —ù$ù(Þ¹<§àdÓ€?Ÿ]|©Dn´¸|”%™:" ö¦ãŽÄ¬3†¨eàsƒ²çèÔxl«CGt ¼Q±aEWK„e°@ð›Ï¨Ž 0ÂW “x|qnõ 6du¡²}ã†[²hŠ~Íqâ¤1åÏ\Ž¢‚Ó%_à ƒëZ ›3$ùö€k’Š’à€ÕXåÁS­‚­ –ìö{P$§YüRÓÐø¬_Ýj—ð`ÛË2‡æV à#RŽ5Yàc@kÝWy‰¯s PŒÐï\y0°åMî1`Ÿ-<@|×áÂäZŸ­Úð}0Oü¸©Ú¾£j?xjËß-MA¤ƒ$lÙ¯0Œø¹x5qäIµâÀÓ ÂÁŠ¿³\j²å/}iy`6Êq‹bù4’Ú•ý©&¾ŒQp°/ì'ôÚ³ßz^O‚×+Œvé™ó£ .ªhÃ$™iO…¢¬(þÆÁ¼dáë8(<Qøíw'òäWú…SÐ-ðϨtàg |©°ð ‰Hò8ZØ– 8¸Xn(8Xؽ/ƒ…Ö…4íÉÑwœÍ×ôD|}jye+#Ĥ<ð6¤iB~Wé`HlÊì™S"ø@ÕÉÁØæ¦DlÊk†Â^f%ÂC@°kóÊO7‚WùÁ.DÀNI ¿è<Î~Ñù|;¸ï¨ƒFŽ´’Á‚w`­[í9ÛµÞz©<ˆ™FV¹*Xxú̓ñðñ‰gÀ”¾Bpù‰ûÿtp0ؽF>‘"8`‡{ÅÁÂç « ™«8x* Ŷ k”„XVñ XsÆ %)‚4Uþä üÇñbYU þ̳w$NÑMWaí2ðã­ö ­Uq€ âß Á#¾â7åäKsúÁ`÷9ŠHÄÄÀ¤<£³ª?ö`¦ì¸ $–DïQ‘ÝÂ|e°ÀÚÀo >±£][_¼Q.D@ЉñÀxŠÑÛ0,‡oæìd{.DO´DT[ ¦ý…ª™~Ö8â;¯DpÃF¸Î!ÛŒú‘€/²iy‹Κø&BR"þŒ"Á¬-̯åJAÿ5_Öœ—2ëUyÍ«;‰ïß)¼iâX­RÌ>:qžù‡ÐÀûyç¬Â`t[>m}Á†^G 8e§¢ 8ú>áWæ[Õ> oøЃ%,@•”^=.Î*TÌöËx‘†)0ðj¢ßid•´»[ü¡¶%‚Arz—k+ 6Ÿy°l/|¦kjÐ-Ø“ïû<8çÏQ±û°­Sx€Åžò ( ž²!=ƒdÔˆÞ~- Œ)qþßJï£vÀ*ôwX€_¿Ê|C¥0H–mŸ°¡°°`Œ ØÚHa€Õ}EÁ€ÃÑŠ‚ùâ,Eo^"·6Ûîö»Ë¸à×áFa€²Èˆô†k]ðT’µ ­üL»¡"&-NÊŸ¯>¼:[,ÁÉv_ÉH!p#>Ó"à/\ƒˆ¼B-‹Œ8Ë­(X°†«(h¯SQÀZˆ°ÀŸtÞ·›(†Áûžs¦ÌYø¼¦§4àNLÒ”ÿð;8À/WáAãµÓþ¤ƒ¤0À€,ø+*<ù…Öc  yOÚ¾þÔíOf+E%BäIäã†ägŒAÒ;Âß{.NæT øxõáç&Ì' XÓ“P€Ü[`“„Lpç]ð”GÙ—]xQéT³¡ÂÈýµSÄ”Èiv8îõ(O¼ˆØ „åðûŒc´Ï¸&¶DüV" œU7À˜_@˜^|Ѭò€ýÐUEÜ>E!ýáJœ‘_Ú-ažXT °¶¼#"ZKâš_ñ–Äwþ”faá=Oð–DŽÐøkìéÖÿYUÊ쉫dàÍcªÎ±hXîÈhÑ[§⿟h ©GW~¦¡Ÿ(`Wø:u¡ÀÌ͵P€½œr€Â‚‚à)¯¯©Wàÿ¬ÿ Ïû”¢_¬ˆèk I¦zà=ÂažÈ~²¸áLBp€]fÁÁìÄ9;ìΧˆã`=ðéXqÀ>ú:[lU“èŽÛÏ£Ú%ìÇ/â¿<°Ó„ »Yá'L ‚Ý%T–Xàg€I›àUD†·à‘!ó–ÿÄšœà È<áÿ™Z,¸î_UÀ߸ð`Á¯záÁ… ¡V$8ðkÍÃè3Þ#+ïL>øÐ^áÁŽ&0¹Òx|˜.þË«°oTëƒ@Fä¹–ø•àçëf{rå-$7Ù`™¡<ð8°*âp!8 Z‚†¼¬.Ñk(*¢ÍGœ’«­¶Y˜- Zv÷A*vþðülo—˜w&‘quÀhmˆ÷KäDãÑn*pt¤Ðß¿hàSØc¨8x¨:à››bCLf l,.!1D6ÀßGy`pð>»ÍyTÒ-ðjIgxòÊ!,‚_°®V³çAhDô<8Xƒ®åz0+4¿KuÀùµ[À—¹®6ÿhÙŸx`°·ÑcÒ,$8ÑX`ø¢ƒl ‚!£¯|ê ~µ6–ùü§ÞVð>DÞâ¯ñˆ^9X°H+,à@«Â‚ÌqàãÐ.BÛki°c[Q0°jÞ_8¿Áû²÷þaCá_øq‚_bŒÌG ’ÛŒ\ªÜ‚ù"~NïL’FÁ^f«0°×Üÿt ~E7ùê±Vûåö’w"øVH§€Ñ‚þJL¼ÿˆm†µ2@ §.,m/œ xë¤V8˜¯ÓÅcrºOGœðƒ#K„ƒ`§™ATH|6Ký=VxÆn0$K ¨LU´ ‰íY:b¼ð½W»Ap¬mL½·ZÑÙ­4°2⊵òoüÉC ÑlÀÁz m¶ Û:Ý_ÄÕhiì”qã›Þ²±4ØâÀOp†¦ÅA°£¨ˆhOÒ>ᱩBPàûFq€%µÒÀÛ 6l’„I"Úxq^ªƒà–;¾B½3Ïã“Ó R$2¢ïð‹®*">luÆhã6Þ_+âþaƒñ_ØE…¿~º²”èAqÀvýo¹p‹V§ ÏÜm‚»Í‰ŽÈ_⺴ì*ŒS`@ÚðAÐOƒ@:ÀJE«úëXÿ¨~l¼PyÀaô•øÖê %ÒK–Â|ºU¬ŸÎ.ýË»«Àöá–ií*X –•ôòÝRm¯Ð^ø3Ý› ë#)¡öB+4–E9Ø“3+ÜV¸E…õb{¿ž]òwÄrÁ°ÚÚ`Kö¶ƒn Í`ûŠtª4xksŸiðv$zÇÁ†n C;lq`œ®%0`Zó ¼’Èû~ßRQÅ 4|ш2˜âÀ[8nOª „éxí,IJuà Êü1¬@X¬iÆÿ“Z¬’8 /¡¡e@ðå•ë¢ åV ¬ìê ð^‰”¶:8š[\òñˆ¼¡Rb²¨ÿì/5 3¾ò?î7¤Äà.ãˆÂ€î*ØxÄáâà·ðÀ/2²Ø¨8pJâYxéßvµ yÍBâ9ØÞë8àµø‚ƒ …‚ƒqçuÁGUUØîÓ þìdaÀ‚Y+$Qhøn ðñ÷¥Ž}Ôú ƒò èptÕ»º4\œfï¯Z`AÚpË¢â›D :ΰ!˜ã`Þì©•uM¶Ï­Ç_c®8p «íBpj…·#¤_À¡l0΃4|¾¼4œ¿ þášžœˆ¶<^{p‡í1ù€o_ P7ÄÄÁ.#Ï +82G‰X8`Z€ÏRñX9qÚïîÀ l‰°FzâÎO¯Ê\Ü+LØ‚<õñàC¶²´(Þ¥OQx0$§ί–ßp¾h6ó ñêoŒooFŸȉ|ÌHôƒõsq0þ3}/¼‹„eáÁ˜å'<ˆŒÊm8[oâ–q·ã…õÀ7«_ODÓoÂÂöEÙi\õ€ŸJ¬«e܈‚YÝi òÔ±.@ð;Îëu [à?à33µ@àP› „ÏžK€«i…œê_ëƒiûì?8yðy§q¸J_ð‘ö^õà­'&ÂC9ÊžIJ\9»[°ÖØx¹aãíäßD˜^#âŠ!)0 ø¤D\·è8¾‘àˆ°d-©ú»æþ&‚õ+ÇY¯Gn+ðVK„ÏIÊ£ JÌ „ ©E¤ù áHÎ3>%,¨!KË€¥¾ „`{ÿø „Åï2 Í+„‰Ø%))ü€­;ý®¿ L^CX“”-IEj(-\ ʸí 8{WzL3¬@˜?cû Ÿ=Ã…¦-DÀ'»!é"KÒS‚¢ßgjl¡îÞgZ(Å¡a!ŠbR!LN…:qDö[ñkÚoBðèÕ !êæ,èÀÑz–7¾¤=* ²îÌÍ¢TÞ£¸šØÄÞ„€ß iØ¿"D` l!B‹6šJFâ¼Q!B”“4 ø "`ëU‘0ñ®[AÂÈ×=+XÇ"$ ŽAÏÀ½Õ¥˜Ø’蟩=ƒ—³¡ñ#NlIvæxÖÅvæ8¬nuôBÞØ*!ŠC¤+¾eh#zO+ìo+Ú ÿ¡Š„‹£»²úì‘p  6`y@ÈÂì $ü§%Bb]Æù®"ÁÎÏž!)ÌÙÆ?%‚Jø¢ “˜«¬˜ô Ø% |‰À+,š¸níŠü—×!Ûe@úH’¢÷"ìl¨=ÃÁ'À¤HÀÁ½®;ú¦aÙœ®8~ž4üÑmÓprt§iÀÝךk`Þ°¢»³ÛôH˰ðÞRáßQð%‡îíç†m—´ C`^f›O•ðª–Y“’–Á«îËE˜Tµ&±¥n3`y$‚“F¿êˆö8q"à¯rƒ<þÖÜ‘ïtWàXp€ °ààkk®z%è. *‚ì´†mNÕq¦(õA0cXðXíð­W¢u†ƒsaj}€)b’Žâ%„5Yu¼Ë­å>* ~bé?ñÀ-Ø)øvaCž~Ë»Œ¯_ÁÁþ |IX6j·X—ý¢#oßk·(Šs (r<ÞgòW°ôýÀ+Š þÆ•‹½Ï´DåK»ïµí\7j·€vÑ’në§‚ƒcX­~à]( °º„†c•Ÿ OÃ!#"<³Ý´`«¤ýBP $ŸŒÒÐ\Q˃À”µ vù™Eÿƒ̕ÄK¥ÂœT°¹YËü8W$8@CqÅÁ¼NFƒ å'Èj\ö4Qf–òÀ³[Ú[Z¢GA’Š‚ÿ޶ IÌr2]ðÅAr¼ñB¬.(`»Hgip1Ÿ‘MÁCP¦Ú)$µÁ>ð´¬v ød“Ù‚·#ŸÕ`‰!˜,øCï?Úç v°À‘þ:X„ƒ‘?×¥&¬08˾+Ñ`Ä:k|~Þå" ¥.„^P¸ëíÂ[½~ë™/A \Èr¨ì\èv§ªr¼J¥ÁÄn‚µg^ÿ©ÂA;,ìýFή½1i±S  gGðT§€ï„!‰QDÙI ôK÷OyðR‰ÀñÑu x_‰€Uìo"l/üÛ+ÖDJ´;M ÿOý÷\· ›HÙ`Àm. VÅ·BÝHˆ ]rôÍBóÇÞ÷Íj‰&hù½Ó„zí&.d¥[‚f|Ûo!DHn8&%ZýÚ79R#ð—]:†$+i Ö“"Û㊄àjÛ‚.†ºÕ„þéʄȱ¼qÖOe‚ORÜ>ÿ V5–å?IA8 âYª„ÕV û G‰ÚލëÎBàõįd!¼;iÔ û™€…±ö ~«‰ã¤*–Ä¢Èg#+xûPE‡„_Ê„ «±ÞsM3' ÖCÖ8¦eö”èV“oŽ Sw-°©”2ÁÊ?©TŸ€ðÙ€ð.PIÕ"á! pº¿á);ŽŒ„’[MÁÚs`Gâ+늃 »3U©p5Q`€¯ŽªÖ¯Ìñ˜-ëøO/0`·d­V„·ªÜSI}àUENØ®õA€ƒÏ†á*èUÃ!ÀŸÅP<µãÈ×·*‚òí›7܉Á)ƒa·Wß§?1›–KbGÂŒ± ,ù*ØZ×=dà}¯„=[`ª~ HÚ²ÞÏR_\ØÇ*°Ê¨õÁòoSq „áŸÙaÇÏ…Ú•!ªÐq£"}¿Œò.š¿²Aà ÍE ¢×±þ”¡ãC<²U“ûãʃø~ ›÷#E§“Ã, þY¶ì5 +_-ÿA0u\ü%†}1—N|^y~ãÀ¯8Ñ-G>!/úNù¾Õ.`¥&8à¯zï)†••Yå×8­CýHItÚÈW^ª# =ú:f Ÿ©Hàãæ ô(ÜôÛçó·:Îý”øuëBhèS S¥>ðâßx>~þ™8ðÙëXÌHq€ü ?R2s|®[`Xº…„VMÀúª?4-:sn­ „är[üwúËÞ—òÀžrÜ_ì T»rÐ/‰i¾]@b(œz0­ø)ì·(n+ª=“OL»8ÏUƒ×¯,5! Y(<@/håÁÏël¬ê†%Ï!âþŒòà¡õƉ¯kÈx!IDIx´ øÇkÒ²-øÏºÁ¾þ£ëÎÁåh‚‹Pœš=öœ­_¾^€€sVåRLO¿õz¤d»Ñ䮟<°ÓFîKTMŒBUýºó„Ìø?»U8×òû`Q2_x€“~°¾"&EëHâÔ>©pÞÝ›—©‰¨[vӀ߆Jƒ(/wB|œÏ{©éXØ4 8|øÁŒLÅÁaÕÄÉÞuÝð-`ÉsØ~k¸¸‘°<¿‘ºž¨‰XXÿÂÁòâ=@qxì<Í–f!À–¨²Ñdq° ‰ ëi¬–8EÓ…†M¨~ØØ&³ÞirˬHV<8~Ò“>ÑÀvÝ|öÁô¶÷ V¬À¾Ô,ð?Th0½8ö¨7é¤A°àhÔÄ…÷«DK´“Æ7 xÇ¡¶ X ðß‘â€^œJ)úa€¿LÁ˜Á )‚NÁžu}g+ãç¢?eÁ—ù þí£>‘ÀšXʾ%#$N/ }ÑP!Àzgµ(0k Ë{ùÝ[šUÞ_¼¦+u«<$XyÍM† ‰h`UÄ—}kY]xFZÊ v÷WÌ|´DŠ|y¤*@ œÿ‰U\†êÑ ÙcJhÀu†*¾:·DD „å…칄$ø??X–‹)ÐyîP#‘’£ ¾IàçÞ&ÁÓÿ™ZLY“à‰¼Î!¢AÀƒ–X”'v”×Â/ƒń œ<°÷\£¡ÕûyÀ«#Ú'ƒ 8À6³^{çÛi½7ÚÅ­†¤%KÎXÉÑ+Yh""UO7Z 4ÄÜ…Æw:deGÂÓlB±þ‚ÍLœ^l? F¨+ ‰|ðT4ê•|N¡ÿ¸ó32"Ïž+x`PqÐøªÕ*:dô ƒ_pÎrÒÜÊ´Ör鈼hß½ÁÔVë9˜æñ…R…à Ø` ʃiµ$±þ¦þÉ1Á*ºŠƒ‡h€_cÅA@ƒ`ĈB…ÒÀ‹|™Oº…ÇpTø l³0q“ØmQÞ Rb:ØìL$ï™Q79û¦ò`áU°¼)<ÀÏX‚2šÕá*rCiˆ‰ <µ¿Ä&Ñrà¦8ðÕÁÆ^”2fDmEq€Ÿ®Jƒd1ˆS¶ë ¬é~ƒS§ŒÕp7 ÚŽÕ{eÁÛŒiYpqMO"Ò|mðÁþ‰~ѦÌЀSïT;xÌr`˜V^¾³Ýœ,0Õ 8W±âÀ_p.:­<Puíà‰^aCGFåA¦ph QEœÔ¨º)¸—ª<À…© °Õ”ÚàgQì¿Ðˆ¿°j‰AÂz„@:Àò·´D¬˜»ãÑÖgÊ«|òààè³Âƒ•·]Ρ<ñU' þZ#:!j}€*aw}ÀbcÕ¢åfÞš‘ú€³sªvàg ãÎrªx°S „cq³F³>°‘Dh€µð ðE/á€Cĵº*ð…®DÀò©›¼ucÖ¸#ĺg ¶S["&rg+@ÀÑ”ª‰&f}p1ëo `7p#T9A„kÛŠ„‡¾= *#ŠO„@>€°áë,j";W¤>p&âµâ¿" $ùh~Ö8ã×ø†igϽ¤§‚ÅÁ˜œg›xÄ\q€»à`Z>g¬A|*gÌèS°àÌ CZ!zâS'XT`gÛŸz±ÛÖ=kä³¢‚Œ0ü Ét!à²GxàÏ»£ÑOã Vü\T$i‰;{Œµ_ðaH\*øå©³|àp ¢‚âbË»ÑˆÒ€à€­7p€Ô—6&ü¼Ì {ƒXìö{‘Ž -ñ*/3Æ‹ È3·ά@À7^î9'ñ))#¿¼Œö‹bURÄgW•½ûà]!x"\ÄâÕ ¾¥B‰4Ø­ÆÝo/ Ó)A¶¿7𘆀o» !8ðž £¿Í´ùœfÿ „€~€öß.4½`77¬W¤gÀ»ÕþC „§b•±ØP !éYîý@¸(ªk_ m›b0f@%½¯"àÛÞ­"ð±î**&.„}àXà ì¥Å†€p®@Ø_ø‡I‰€5¦d ¸«ãŸï×Ç Õ7|°2:O¤DÀÈò¿J‡e²Ò&4æÞ"‚Ýc˜#£b"+F%‚7"ð5ÏZ"$AªÓ…}IœÉ—¥º¾0ÕOd„äÚ;¾_… Óî÷#'‘œf⮳ IÔ:RU…E_#,ØvJ×0íNGðÙÊ;Ê]š­œ x¥Y‘ð 8^EG-:bÂp¿°±í¨ž^ý©¶éü…k’ï8¨ÖÁí{¹qâË©µFHN½ïÖñ¢+ò"LA°§\ÿd­5B è­IËñyÐðæ·"àÇôÆåÆ™i+ÌêEx ÁàÛí;9Š‚X/,^$) .¶ç ØÓ¿ìÈ· ëí…¤@°N„æ­Ëárö9R <°ªïpå@DØ9-¯òá#@X‡^Å7ì ÁªŠïÁc‹2óýLgë=»Þ^x*…½%ƒ¤@xt ÁæóĪò™mÜ©÷ó/(m÷Sä”k ! â#»Ž~÷9Ã>(TTô¹ªuZx°¯@SäíÕŠüÿZmú˜‹râ`|`ÕqÜ_<¸í<Ò'ðK©(øgIÈr¤0À÷ªÿòÂÊ ‹ãÅ«ð`Bêf“¿ÕæmS¢ø!C·žfâûâÂì¦t×ÑöÏâˆu9HQDEHmŸSUß8ð)Ëö²ó‰ƒ„~€]¤®1<†ƒÀ·ŒÿNÿÄqÇŠPqà›¾¤‡Ú‚½çiä‹-¬Øk躥A0sdU²7 gȵ:ˆÔD6ƒ lq°î¨þÖâ`¹X ¯4@çRÅÁ¨óO‹ó ÖƒÀ‡¼üvó Z|~jËEˆ;&E/&îèÁïç×øµ:HN0L¬T(¼š¸a÷"{eÆÙf÷Þ3­ï¤®ó zÅ«‰gáhÕÄmMö¼%‰ï¦ÿµ×dq`üÚ‚ „™×h+P¡àWý–#Éã[7p€¯âÀÏøÿucÜh¥Äw¯a¶ìÚsèQ´‘뼇u#8­±W¦f®sªNÁWŽíÂÄYq€¦I­‚váGÀû?]°þƒ-Ûj €0—'|Û¿sØyfóåi#"¾­ÉßyŸx,'@f6ÆW$$r"jÍ ¼ê_ úWºåƒ?>7n7n0]]Ëþ–k †¬>`ÈWýé£úÁ`õ½Ñ«Žçë{WŸ§ãµã„Kˆ€¿Ð·<ŠøžöG)röÎh¤†D)&ÑiÃd£–çh÷¹aµ_‘€•¼œw¾gH4„İ5Ô+DCÀVH.³8"´·gÛÀHÏ€£9!¶8C’ZÞ¼„Ð8‘ø¶Ä„cæ[QI ’pU?cxJS使¾À®@ðŠâ˜\{GˆUøËm3Öý8ÀIô¨$®fkÏÀf=䈫F „Ä¡hØÃ~Žt|â÷ØEÇÆRoÂÛ€?óµ–!0(&çýÞóžD-'ŽeŸ¥8 |ÓGw|yøñ÷ ÁÒ÷ƒ•6*‰·§ë¸1;Ú\qäËàµ6pAËc[.ÜÜ•Að:ŒTPt柳¼¡6 0àX™þT”‹a­ 8rfãý>ìVi¸‘ý€ü•\ZVìÑ;U@ðöƒ1׬ʉ¨Ý[ÏËlíHCv¦ ûu0øGöãjqÀóq+{;×rjGš]u0Ø uŠ~ÀÃDí,Æ$Wõ)ù`æZ¢ñ{£DH®<'þDK„‘ç­•Ê€aâÖJv”Jvš!B{á;/DÀ×°Û°Ìg¾jÃ]jš†’•ä/5Ù¬å·! su Nr’¢/–ŸÑ÷'"ØG>²§DxÈ‚”ø¨¸CÜ$‘ðu¼Ý8óŒÿ/~šøÇW p(“Ç bB‚Öàö;v0•Ñí6\€-Dàgi¿+) [Æ>§Ãe*æ‹(©B„™kÃêYÆ9VEºnêèã–9èVÀ±:Ú6P›ü’†0¡EyËɽ¦dÉ(IK§0aFAç/$àWY˜–QŒÿM„ó‹a§Ž ëõJëSÜÑìß²óÅ™1àë\‘ÀЊlº Á”kÌJ„Ö¼`}ˆBÑ8(Q—cް.s”« I|Z„à¦_ˆŒ€ÿN­8W€°Mœé->„ > øT"ø‹ ?…ȰÚ5ø=†HHØVT«²èO¸±¶aya¹Vpqæ»g©~ÔäODðËèÀ$$7“€UîUIxÈ«8³½ ˆ;Ö¤äF‹Xå‡Nek¸Â„6vEîÅ»ìí]2jˆŠ…€ÄßH8«µhòÈ:xEeõÿ5'qUWŸñɬöå e>†°{’±ŠÞ a?Oú™Àµ˜2á©Ýgü‡¾s{¦nmqà%ØjMB)O‰pð5ùB,[´HðDÀnè†à‹„†–þZ$d^σ`øØ|°Ó sÙG%8ØPóòç+-'&¿úŒR-e‘ãù VTÅعÞÁZ…§aóÑß5l臑ÌåÄŠ°®˜PxÀ™”¨åU pP-’uÇ kÀÑPB´Ð¬7aý$W°P àÿK€à´Þåeß?ONø+¯(¤+’ÙcÀƒD£pÿ{‡ølSY1ñ.'iA}ÈŠX¢Ì3W•ÁèqCy[BØýÙ&,vµc°nÞ¨8H¹m[•4ñã¤Vø§ëþ36åÒ1n„$_u?ï;îQ»õ'ïy–„¹!ò.?D„§Æ  !)‚3ðøà*[LI–+·x”X +ü€OŠky`÷Ç· ø‹.å[ì*FNÍ•~Á¬ú‹ŽjF…`÷³­¦°èÑ&ß1ÂvvÛ> aâc]r•ÁææKoB°j'’rÄ„(Š•þ*ÃòÂâQ%E,#ú÷‚Ï`çr•.6¤*X'®HÀÚG$EïJ·«û*Ãè#؇Ѕì5a? =ƒGÙæ—7!Œˆ:Ýt Rîª~B³Š Þ« ×auÄ€’õ·Š„$U“J„DTLŒËžö˜Ä:ƒáâ§*’œUló*p&DHR}‘0Za=Ö ,Äô­ž/Ž÷%]ìJÀ°d!øöÑe8‘`—Î[õ,C *&HàÝoÉŠ\÷Ýð%HÀÇ×ÓÏ|¸QrÂÄ÷¼ë áàÉ(‹Þ«0ÿ®þãŽHÕþe†}äåñ*×ÜüqÇv5ˆ©LÀ¯˜:¼´8þÌG>1Á_{Eó©07—´q˜ðŸŽP'&<³ïYð (Hð©ŠüÁø«JàaV©¦`›ÁF/Ï/«+rÐQ‰¬2DƒÇ N:yôןYfÑmGlÎ*øü¥Nƒ¡Ù@ÆÎ!4Ú6$fÔ•ôêÜ:æ†u_å~VïÔ¼U±ñªaåÜn5\\‰®@à<6hõ$‚-žé¨µgˆ€À¢³‹þtÓYx ´6k0{ƒYüÚýgŸÅ¾c¦@x¬?/ɬ·ç¾s~Í’YC²ïh{†q`‡áo ,¼$@Tc*– 1iE[ÌI¾FÀú»ÿÞ+¶7bVù(€d±ó.LLò § ³†´ žø+‹°¸»mÇ d¥>áçV«ˆ€†Ðš‡Ä£àKs‹VCXyu÷Æ õîÀ$OVp·î6m\ETËM+ÎÑ+°z”–!Yn²yܺUsRÖ2 ,XóÕØåËË¿º²"ÊÛÂü¬V »]f‚uG¯ $áÙ€"©ËøN( bÎ?/ÑA· S‘#@úº±¶T:^º"쇗‹x}‚3/Oè\S/BPØ4„ÑŸs[¢Á#÷nÒ1`#ÛŽø†,íŬä!03„Óçaûgö8À©¬ølSàõ+UþCð;Ú¸ô X[ög°sVy1,¼)«ý¾@½ÞåD>Àw]¼Ëôµé­ÆÑÒ %—Ü6ö_‚ŸñM¯Öå):ý̧8+ \ZÒq¾†Çg=q‹ò׃Sn|ó«Ò€+K©°­8॒[ýBP$«Žðy£òÇ/ÝȪ£?Óòî>‚|äÚ«ÏOÙ‘´ ¬>ó¹!ÛeÀ©­u@Q°SÒÝ&æeÝ}ƽ.½íèIÃ`â’¶$‚Ý_iÉꃋ@ïª("w…øY¾u:p!$ËŽQärÐ/$ j>R‘¯ýÝ/øe~W+Péu*fD°zâ„…F%B& ÖôF‹'Âþ²yŠ#2Uxà²Îá0·^7—¯:žHAMDpÀ@íÇ ²‚|nÝ2%=5`p*bÿÒ+, g)K¿°ñ ‚ƒª¸´¤•›ÀÊ|*ìaÇ ¡[x°GÂÊRWáß@(<Ø|Kõú3®HËÈ1¸ã¶¢}P}ŠógŸâ‰„Ï#Ç7PzRORB_ÂSÆå`“á©òŸ‘ʃÀ·ÌKoìç×úÀ†!,/ÎN­[ÃrP‡7Ÿ½|ÀÁ ZLöäóòÂw]X`‚{M|©QP€‰‡7Q0 O¹DLÄ}ÓÚ,`®Ž&«òµËÞëmK°â8Ƹ¹`Õ¼/(Àh/ ¦·þéÍH“ ðÉò‚Õڀ̈́²À/8òËS½HÍo/´×YyúÙÂÆy7uÁ[©Ú)à/Ty€“Våkf›¥Eà÷ ßÂ|\¯<¿KœŽ*X°û[•/¬ ’\U¿Ìt೤»6`_X4ò–’xf½E7HŽ9bó\i€ïiÿqW|' F|ß &$¼Ð‡*µ:à•c°Í„ ÑÂìDE6ø9ÿ‰Ÿ—ß4@ùF…`ÙÙí6¾q€r­ZŸºÃ€¯ êˆIŽb‚ƒ`Ù¿uwaæŒÕªœ\w]ÙB%ån|Œ""’³fqÞƒyØly°E³Æ1iÐi$@À§á@¨´ Á¤—ô¬ù€ غÜŒ¹¥(@`OŠû¤[@°õÁ…«¢mÀw«»_àWåz@ÛfÏ0œ8HBÓð‹Ü}Üuÿ«wÖ8/öPÓ6F»|*MxÀ›/…¾¥•-HZø¶!È?˜~ÔêODðÞTÎõšc0kÜÜu×éàÃvJ„‡ÜH k‰!ð+ã7Gˆ€?SKVÏe}!!×:ZxâRÓ$ÍØûöš‘ÎÁŽ¢üƒ³/ n·¡Æ æd5hÙË+Û©‚bÐ2 ?ãþOÍÂkHýÑëêþB !ŒÿCXï °Ï©@àÛ#Ñ-ëVf-µaŽ€Ð°Ôóï^PLÖ×·îh‰€Bî3™aãqV,ÿVûŸx`·ƒ8”õÅWåÁΖðÂÎ>Ò|¤§ìÊ>éÀ —ñÑ)†À­ÌÓƒ*)²?A€HŠø õžn[9s·ð€÷Hú/1àÓ¤®;G§]ñÃ#8@s®3Ù†¡ œî/8ðÛ ÁòÂø¯ßä üvc’žŒvbþƒýu á´8xˆ<>þÅ‚uâíÿz":m> ÷פWàýGaçœÈ&†^Tðç½·8˜’Óï­Y9q¶ìÖ…(ÛŠ /jq€_õJƒ‘ƒ*ª/?‡•?Ã<ð¡ë˜_¦ó… YàòR$ã…§n0\l¯ÿÆçãß ~ùtqÁ栌ܷÕ+ÏþÈóÛ•È?U7‘=B®|qâ³¶ œ×>PUq¤+o+ÖÃìb+4`Çx—äªëÅ›ZÅ4 U¬6ûÀç­ïø8îßc:Ðs¨ÒAÀœÀßâ“Ö‘m7€¸‘p -½G" ð†›aŠNäÄ0™/à|½ᑨ4ôjUí +Ðê]x°pðf]tÂÖ“d¤á"S[Vémõ³8ðG]ý•çÆ¥<˜ðüV}Àããß<¢Mçäª+¾BèϺr¯Ty0ù3Žg¿0s £ð 8¿`ÍÊ Ÿ$áHvµ‘ïÌ”tå5ì(sÉE|+ÔŽÄk^„`q?Û>|>ÚvÁ.6¢â¦I(øÁéÂÝ^xlØh³‘ödžXŒô‹‰¼Ô)@HZ†qg½º!¸¾ÐlZÚòBB¦ ‰Á:'öÿÔ¼õdak8Ãxk^ŽDô#ÎV¤gൕZ#à/-5Âàæ ƒ?íø•9§_‘Œñöµž!9횬:'ó…gVï ø¨»q)QÒTƒ8üÈ˃'_©D`žœzö¢××…¼#‡í†mäˆ )¼­ü hn=oIÞ:ö­…ç£48À©Á²ósDð¦å‹0ìy(øHî2Ìç·ÂO†…F‰ÀB„!Xn8ˆ—G4¯Á!ǽü5!ÉÞv]£„¤íÂŽ%cëZn›O?Ø/ } SâJÂ'seÂdÛëAàËå‚„$å`+¨ ÿå #eô´k0wLòPðÿ¥&Å HÀWº"ûª¿‰àj„@øT—¢Ÿ;¢«´n9bƒ¢5‚áÁ< ¢Å­±}®òÀO‘…Çx–ýÈ‘aY IÃñyäØþ™ì½¶ƒ„Á Äo‚î4=µâˆBŸ†$,† ø}Ð{eXñw® ÃÀѲÓÄI•zÓÕ²ÀO[àAX’!Ç0Õ¬« ¶d‡aÛp¨–$‡Â«µ:؃ƒ,Ã̻è0œÀüœ—v"ÁÞtÝýÃαڕ û€½‡ì9&sLJâ‘P» øªˆÝxm6Ÿ¯Ú„Ɇ„K0vÄ/ÍàˆJE„Ä”Ôøì×+Ïfµé¤¯_ÈŒ!‰EQVxã2Ê Ý«ŽQuàŽ¾ö€…{F¬óÈÁŠƒà¿úc[þÓ/xÛ2 LÕ…à``-<çp܉Àÿ!Žá¿³WÕe VüÀñ|ö[ÿÁ¬0œÕ Q\V|RTð“¢Æ¢ØÅw¯à3Ó!d§Édªž4°ó…%Yjâ|î~°Kx€*ê-íÀá`äþþsm;úqX5Jy€Ýhµ(6|Ž*8™Hp£ ØSq€xR$9¶]بU2íüˆÅu㟪<àO2ÓܺsãsWR >ì)ćà®0ÌÑÙwåùĽÁð®W‚†Ã!êzcÐ0ð<£â`˜?ÏÖ&»îŒ%˜Ð+¥»Êògæèi€í›ïVQœy3ãÎ>“×´ÅIuàÏ4ñŠ­Ð`ÚÙ_åƒäL“MP\SÆGuÃ`²¦¤óy5 AqòªSÃŽâ€a) M¾:6Æ}ûqD?à,½B„k!ÂÌ‘„B„`èÈ)•¨p ’úÀê³ aÈvP«¨HqQ¹"aÄ «6 Wõ“4 ~ãÙš’&w÷} ×qï®ð`y±§Ky” ¢ ¢Dù‰ÁÀ1\çS+B¡iäÔC¥÷n•+çŽg]±Í–éB 8°cqù›Stñ±YXÀG@³`ÄÉoAÁ´\„KVà7°¢€%,¹Ø¶qªÌ7¡—WÝ4Xqʪ4xè:G®i &ô¢ßå¨Ú'¦h·À#I.xûmÎφ‡Ad>pËΪ­8ˆÒVÔ6(šülaž_Ø*‰xàÍ+úôj³°®vØ8%ÃF|¯Iu€]‡ðà1áHøA½!`«<Ä^<¨v$v" Ö4ýæž÷K”ª=éÊ6´NïÁÀÝj«ùù–ðk‘ʃk§Êƒý¢zøÞ`/@˜'sžé‚]xöÙH‡oð€÷û…øÈ¾%xíçvý×Xx°_;`AVö±VœU„¿ÞÈ'œ„øñ5ÑjI”j¢ íâK@˜>U;à[öUN\9­·;l½ñÏT ¬V<°Þƒ¨@àƒwþx çÚø,ü­!8ùŽMö `ᣂ…ѨábŒ(ò»£¥@pà7ñÁ^q€ŠP/~âTdÞƒ Kuä[Àµ>À¡[ÅAKpÀ%_í¼Wù'Pí ¬ó`ÂoºÐË"¥GâP¥ÁC9ël÷àcâŽzÐÀËÁ:Ó4r# íÂa7žg>£Ý‚—ðŸ©8ÀÏr¿|€Ä¨ÃÆhw¡q%+“ß.p²dÅÁžX‘x4Uy°`sW`Ö J•×åÔ«œ´ ì¯V$T§¾ž8ájµžÓ,åþœëÖ8(µÁ{'±±ð`®¹r°XÎí*‚{m~ßyhH§„1Ò¹òV øú€m|ºïŒsV‚½×v‘÷%ÞÄÍÁ.éíß÷ÝÂÌ™Šƒ… §Ý8ðÎDœ(u÷ Ss‡Bù`Ã*MhÀÁk¯€ßÐÚ+œ?f®¸¾iÀ¾±ŠƒÀ™Ø<ì^#“pyÕ/$—ðks ÉæÂ3ÞvËmâ&²¯µ¨œˆ·Êƒ)¸Ä²¢©¾òÀßq½H‰Q"ØY#» –h²¬.LœÄ[€À£™ZÌö2ÓŸò ™.øúà§Îøo>ÀG‰*6>à$AiAðÔò‚ß]˜ÙUqA¶rÒ0ŒlY-@à@ ­fþˆ"ð[¯›Á„Á ü^(|¿`ÝHÓí9_(]5 Å—#µaÀ§N%KfâNÄA`%‚¹Ý¸aë#Šnê=Hv{"Æ®h‰ð=1B’¤¸øqãäõƒ‰«]]]à÷BqðH}€©èåé¦ÁНr•£áû…vÜ8²¤Â Ykâôž[ý:! ÖŸ'Î'ØáoبW9ñ&—Ú8ýüKIë#>ÙTPLæÞ›˜Ííí…‹û1¬Í)­CƒÂ£JÚ9}Ç0ûmç9»õÎÁ²½`³Öü–V$Œ/üpT$Løɸ'X Óf‘`—ù&³"!ŠFJF Á¼æ¼]y~a_vcÞˆ¬ ø,HX0]XšeÆÀ‡F¥FH4ï@@3‘ì/³ö:ÓÀ1ƒZ ঒bÀ|NÊuçÏŠâ$©(à)‚õÆóVÅ¡˜´ e©Ž8‘¾£7€€o¨Án/°~Wyàà°§™N« Íf¡,õpÅAÔ/øêÀê‰C4rdó˜à (ðŸQ?R4qô†Ù¯/¬»¹»pâÀé‰ûáoµ­œ7ª8ðó…há)G{r„XyßðÍ U´[°4@¥Kpp¡íþÆÁŸ+ãöîÂÌ»-7p€û¿x0Çb-c~€s.Ù`p†¤vRׇ'®GT»ò\wžðQZËwðý‚ÛgÚ|ö+‚‰#4„øT"Ð/t‹A˜*>oŒQ.T"ØK,í"ä"ÁŸbYÞ\. eäÆ_‘à+üºËŒÁ'ø]/@˜²k®øT ˜ã8DV `Ÿ¨û žþºó6›ôÄŇ©î;~#„Â+<`½ºð )ðgîàÀb¹kºQà·Xh€¨ÔÁ!–-¡ÁÎ7Í”~äÈ:©¤X´)‰SõB³—ÚÆ=ªxÁªa>ðÁ^0@Ø’óÎo°"ðju%²ZÁ ÷;@%BÐ24|G+Æ$?GOwÀŒ&<¤ àVŠ0Áßw>Ÿ¤VB¿õüÞirÂ{–sõÇÚðyQ+„ÿWÝHàK4 [¤).øT$¡½/$;Ž|œ¢"ÁÁšÚ1}L[|œêÎݦc  p¨ðÁ^q0áÏèÈ1HÚy5¥ÁJ[sÃè& ;ÿ&¦iåÁä+';ލbÝÁ_xž^ÜÜÀA )âñká¯&Ö|e~ò øì°Áó ¸íŒBðÀŸcá|À‚~¨¬Yuà€-mµaÀfI'ޏÒ%8à¸ËŠ´>ì‹‚ÛjÚ9A<ËøyW ðD»Jè¸ùpX/B2d@Y_ˆ€ßv%B`Iò[ #:",[Ð1ð×];±Ü^¾B޹²-·Áh[v¬<+xb]‰€õ¥®5¹„w¿ÀQº2d°¢â~lŸCQŸ©ºû5Ç5ÚjZY¸­@À)®=Ó»~«Df ‘) W£¥Döžƒ=ïr¯‡•³=×v>¹‚ƒ,¬`Và—]x„$-XU `SQ0e@ðEæ·t žW\tèè†É¯9Þ£hU÷=IQä'I?FüŸéÐñ¡Åç ›Ù Áò`õ9g J\©<ØØ[Xà÷š–÷£ó,‡R¤@@jHÏ`ƒX­P 8°y§ð`É.8ú½¦DAØ9™U¶?Óà‘Ð`ľCú…Éö Ö‚°'P¼A”ݾ’ĹÑ‚‡îµ­øú( üxábí À`à B`Àñ3K’Äq/×ÞYï.X•¬0Èî7ò`¥Â‹|÷¯nÁßkKªî~…³0Œ~Àૃpä'¤ð{DÂS|Ûk»ð |&JTð[Qp0pŸYi0ðº·Ò ( ¬¡]d~t¼z°‡s$kæHâ¥]Q¬!*ö¢ °Ù`Xy°M΀0º{mû†÷5s=ÀA0_à#EŠƒ§6|JÒƒ‚7fDð)Izh0Ú¦‘ãÎzëNÔëŽDႦòë™Âƒ9ÊTå,FmLHÒÉε­É¹wvghyài`¥D·ÞxþÁ±w~î÷3öl:\xjß99ïŒ.Ð~‡¢DIº« ¯¾ f\*Ý›QõøâU¥Ê‚àË‚/ްÀÝn×L8Ò·ìü® ð½Pðíªª“…ÑßfrÇŸ§ºo8Öí…§F Ó Üѯ#âÓZa 9I½V(¿ü̓`²À1‚Â?häuîI£ç¯pWí`‰x´ & åÄÁŒÅA°ì<ÖDþ‘'%Ú@Õ}ÃO…n;i(Iu°á”ìKqiœ$¯ÇÞõ 0#­> )"ÂEPˆÀà-D˜_GK܉øë]xÞø\^5'Únaß¼z-<£â¡^es¥½Í?‰Éí3½óPXí©‚_pܶåó‰¦ vºÀ—ÖÔ|ðšˆ?ò­ü/&Ι=Ñg®óÓV‰à÷-f40öÍ&,¯f¢&º¼´ìÒ0ÇÞ­U™¿è•Ùu&,½Õ›èiÀ[-šx'RÔ/˜óL' üzct%¢A°îOY‘üI–é•4 z€ÎVÝeò˃P6Þw’úÀ§¥@HQðá_€-•kôÎc®ÓÎeüsb°<`›\‘À§ ¶ù…ë8‚Ô4ÄŒ„cŠjFZ&[ øýÆdÜÈáGýHÀOó× {“eâÜ~ á÷ÁÙäø ‹o­þ€Õ†k Ló@@‚W ð¥ÃÎaß½Y9ÛfâO½‰üV ¬ª„xFõ­Òà'Äå ¬ù h¶W²Ì”\lÃVJóž/`=,íÎ2nŒ’nÁ'®³»ºâ HHšß®ú`Ù1ÅS·àDSã ¾À´·~àÓÆ-²*ÛLËàãÎŽÁ–m䡚‡’ðÀz•÷?å%æ&/)¢‹ïFÀ²'ÂøâToE¦Ðò¥@À æ ¨:惃O{V+›ý*8jAÝ–ØšlXöf웽Ðò€ÇÞ¢ Ç$_ùêÂeåA`?ðëU „Ù('ì.Ûåï¬;ÛÀ´wÖlƒÿNA˜³8”>P5:z¿òÀ·)…màÛn"!CGëPÜ8µ¾"uPE‚‰X>‘`Ï8Ž-ËPäˆà‚„='4b×a°ŠQßÒ_H‡×°SÒ¤ªnø†ê•¦ˆ nÆ0òe oI>eIDÅ Bqõ'.VêUTôMÃÀñZJ®$jày€ŸøÊì9¥D ¯Doǰí[4qä}U­<FôZiÇ€?¤3†$Éì38¶>áÀ‘_:d’¸èDëO¹,ʃgÎ8¾¤eÀmBQ8ȤÁ/<Ïg;‰š˜”‰O™ú‘D¦¹«,Ó~Ì {fZö‡ßgNga ˜) P@pHÛ€ÿŽÔ?{¢Ÿ à…Å$…­ž{»m|'zPx*6 kCBbD@‰W•Å ©)Pà™t_PøÛ‹àG;ŽÄ î¶ëv6° ¤óüût h[«LÍÞšÄ[ ºÈ`³×ÛžD-'YËlp–Ba3×N&ØÍ¦I'LÀºø/&øB!¹Í‚À¼u›% B0yÄÎ]G ¬¶Ø&Ö˜*™¿ú×´ÁŸoãj^¯1¸a¿Xö¯ÚbbOòââŽ.ÌZ$Di|«B€=“ ¥y--‚„ qà`e‚¹È0'ùª¨µÜHOóyËï×ù?­¬AiåšîÆþ3¾BÝL˜¸Ú¯%.1E]Ln¸ñ&;Nî¢ãq±ÓW0yË ¾„âP²Wà³n;*Vâû¶LU‹Òx‘QÀï»Á,9D˜›µ$ø€Õ-¹ÑÂ.ðJ„‹C8…œ©&¥§âÓ8KˆðÌ7äÒÆÁ^q»¸<'.f¹|– ¶2‚~˺^ú/LX’«MȺ:tÀ×°– 6|6içàõEŽ û+Á"g™êJðUÂ:z&ø5Tü$/üHç`Ï>|UõK‰Š|[[¸˜ƒÆ¡a E‚÷1/hÚ¬)jü@"ìèI”C¯‰¸h÷öàH˖ؘ"°._µ„È•°s*`5.¢˜W3V¿ }V ¸Ñ)UBÂî° ÿ~V?Áo:ùµ†‹õ@—bA¨"~ýîðÀû˜W–Ån ~í1‰\n §ó ‚iò±ÞP¹%ìˆp)lèòÖ‚S¯AnÒn¹MC”£†Â™}6B°Ø°n‰KiåÛ;µDp¡Ë'¦ŸOÇ'"ØE'Þš" zÖÀ_=ÜôP×À—6 I׌ðãS‘àU|q*‚-§‹#Óª+z Sa€”“~!¹§(0à´V‘ÿ*=ZpNAe?Ñò® ìàq=ð* Âð¯âó ÞŒ€ÕgAÁ„ŸcX¹ín°<ýÎøåõP„ÖŒý;ùâæc…Á4á³ø†z€pøÒ` vœt9ýߣ>h¨RðIì‚~·*ÿ²0ø|UlǼ £r¢§ïq~ | ³âùtcÀ­8y9qJbÔ‚¡ã<¢&Ú«Äõ> .eWc¾•Xª(lŠïØßÀÁ†~5+Ú nûèï5-ï½ÏìÚ.3é_³[hrÔpÔ£Hxˆ8ÁRõà©…œf"4®½ûO>gf{¾q”˜Ì¯â´£O‘à†Í˜÷ F ¿]ÝDج}y"11!ÂüŠÓÚlHÊ›l\¯â»ñúž/,“ë¿öˆ¿ŒoŠ›´ú¾;¸ð/¿…„`§!R‚¦_ÅNõ`ÆÝIáG+U¬þèóÉü®k‰@Ÿfñ%Ù Õ ¹Û-&²Â^•~ܸbâìo´¬S’»Ìð®Bp¢¥mn¸0ø…G|eÚˆÍÝ_‚_fÀ¿é[ƒU\8PúÆt{*éð¨>E‹ƒ _¹3ý?Ë›‰°s…%ÛM‘~`CØÔu‡Ø—©€`˃íð³ÆåbH˃ _°©Š?™ùŸh`½ Û¡Ÿò®å+ÝŠ> ý­Ð$œ>ÜøèÑ|¾ð·J·À˹:k ª{–aãAtÝcØ#;’„©7€Ð8䣯•T l^Q|çôyð0¨aÇ·¢aÍ×9ˆYm9%B¢øò`I,ËÏà`à„‹Z ÂpcýG4‚TÃtýÙo:&Ͱó«F*4@ÏŽi±ÃÆvà·Fi`Fä× +¾ëÖž $V |üPšޏ¨4@¥¢–Ûn»;`hø–ëU†äJ ö«RàcBp€õ[õA`NŒ vœtœŸZç ÉÃÂÿPMC@‘F€€>šZ`¯ýBÀ‡ƒÙ†°Oc´å¸¡Mºl+¸È¨<Ø/ö«‰âʃè ãçÄå)ˆTlXæËÚ3ŠÞY½‰å oÉ<  ~w½âNäF­x;ZüHx/%¾¯Dh¼ðvCN´þnl4m¬{wý+Ÿ*S í‚Xm¦>˜‚HÅ [àž-={lhßÿÖh!(’•çÁ · Y˜p¯âAcÏR­ž·‹ÑŠ‚à¼«][`'`-¢}g¶;k˜b€ü¼W\ŒY+ xÔq§8øìFš‚,Å@Ll/¶ʺsÐ,ðM¥ÁCy˃·)//œ¶}%<-ª øÖµÔ¼¤$µÁaçàa!‚3+o<1’…çG¼Ê~~ju!W?Å|Àù¼"&úaãp‘?[ÀK­bO´Ó…c2få)‰Sô ìYœb¸Œ üVnÊ/ÀþPºªÏM‹f R7‚ÙÂÌ¿³Ì°ŠU5ѧ¦±ù®ÐÇšÝ^åÉÞg™†(IñÀ4¥Dá9O-ŽÄœÈj«à'‚“®:%AŠØÉ…–D=HpdØq(Pëd˜Ô‰|€ŠìÖ+²Û²þÅßvmõÁ Y>þ÷LìøøDž ªžà ÈEÚ“ƒÏX¯Üªìxaæ>èÎÞB€ƒÄ›èÛîúÕ¬¼‰ªc°ìÌç>å £5FQiø+ÿæÁvLþCd?Hªß/l4¨ÕáeÀ`cPÖ{éæÃMƒôDüª)0îƒ=ˆAyÌ­|uõ›#¿[w:†@A@7®¬;ã#P€F)Þ[4 AÆòŽË½w.œ«½DØ|hß!‚=ñ:sVªl/øìÄåê"v%‚?éx6 ~ÀðSí"‚0`§­DòT[p† t¾Y·€`%„á1{bƒ@Að'àÇ ƒ…ò ÐI«-C  -½§½Ãƪ=èz’íF„Y¨~$„¡!°#a«(%Â`+¿½€“l/ðÀV+ú*Rü»¤>@d|eÓyÒ‘8±Vþ˜ãY‡M¼4].›+ 2pô 7Èý öwYp¢??ó+ÁŠ'ËE6„X’¼ Èñ¯ÂƒÑAr¢1¬ü`¿Q p¢"ÂSš"¾_ ¼{&DÖ±EV x‹"Wù¿‰0ña!ÂÁþ°J„%1$á×Töqaç7vümzÝÊüU¯^:è}WŸ…©fà3P ¾YðçßçE ‚}ÌzãG¨z•ñ£®îÄÿN;yu½ß}àI€T÷é÷$É/-Lo§²Ÿ4²±¼sËy ¶wF¿Ç-9o  F$‹ }4ë ;HÁ‡ã‰ïÀ•ß!iæxã”Ä&âgT|HÑAWÖf* ðWeE=õ¯gß5,Á× f}ûÙHÿ„;päôSq+'‹L(Ôü›„IjâS¡Ê¨|h¨²ãÁ: ÏJÝÊ6i°ãÔû­ž³@ù3óðÂd 49ñà.ž€…øÙÐÁÝsÞØW_#P²i£¾çUï9c5[—&ÞÒ‹ƒ6b!&(ÍŠvÃyG›vÁÁÎiÈý8Hî5âËw“?Ð6£ Vq°àÇTpà' Ë€Z=¹`i°siYiÐFÜ:–~!XlÄҨ¹S`p0w”þsõ`cfWæÓt…~û ŽÁ'"mûEÄlÅ#¾à€µ5ñ#ý(³Ÿx`÷œ½Aq±Ó½¸÷þ•ë­#Š—Ý+Î+Gé^cPà¼C¯5z+Ò⇷µ.ˆCBuNkÓ+œ8ðV$î²»i0aiYkƒÌ¬ŒåŒÐÀo/œÕ»]eÚVþÌËy6~»* 0…]¼H?»–Ÿh`-øÅ‘^“MziÀÑzqá©UÞMëµ&®3NdöºûÂa ›lñ&Z9q|{S°Åé.8_Wz;räë½ã…}ñÚA–ÂáŸ/ìXP›…Æë{jHòÍÂä2½yðc±þÀ¡Š4½À’¬/  ¦{âøX·Àûíª&ZLÈ÷Þ”eÀçl:ÚŒ|”Wê–Ø…ÆtòÀJ¿èu ìüNÔn!\u¶Ã……¯«TløµPñ€ã$«Í|"àÀZ#Ö-ìª3ÃÉx͇½Çó‘„)µßÊXG@õ· €#D€à—™Ø(ò_i© ôâG꽫@pלO  =E†Ä¡h°pOQ³–¨Š¨|ày€cƒÊƒó/ó» ‡ß]¸8¢QëƒégXÿ vÝyG¹Lv8lSó½~t è$º•’ÜdòÙë„U¼®7ZBT",|”]¶™œ%i|›S‚Ž!ÐÝ.Ó1AiGpÝÝ.0¼µ‡ƒèBÛÆñy2[ÀbDx@ÿŒ¥ác½à€oƒ ð‰\i°Ì‹S|¼:_ôÐÌĤ<@ÏR­‚âÉ}kÔÀÛ— ö²©|À˰ ƒ!XvžXzú ƒý,4xzU—ƒ~aCiü7Æ _X3~G øe.<˜²~jª'Ú~á`/_ÕÏ·Þê#7TýÓ…ù'­ð¬ùà@Š€ÀI'ÝD@_½ ŠO•øXW"Ø ï+;W…øÈV"XAqåü$Ù`@Åõ/!HCY9P´Ÿ6PùÀÖMˆàû…ÍÑ 'L ü½…£ai­‚"–R!øøƒÆûâÒ0 “‚0ðñ'gqK>’;âú6Äùeçëü[Qª„¥­¼%Dðy(g ê†ÁFöñIp6À’le|…*>•øõR"X$³EÂU»Ô>dýÂ(+5¾‚ ;¢‚®¼`$%‚IO<`—¬Ôž˜„©rcQˆ0&gq ‹60maû½‹–CǤFÀÇÝy拟Û"¾gàãE"!ø õÞ ·ê Â06jK…`íÊÎÕ–aLâP8óªâÀ×ã`ÿƒÝq<°l?Û½{Ï.¼;†@Q|,?qÇKx€O áA¯Œœë.VnJu!Ð؃WqÀ±†ýJÀÒ1$ñH¸€.=ƒ½ê¼D3Ÿ¨zVX60íX½C±­/Œd×ï>_yA”¦­/nèèÓÖƒ aÓxõW$¦Íø!¼…„ R5:òÓ_€òˆ"Á!8Å2óÖÓo"´×ÂFk!>u:U߃'§?),°©@HޏnØ p¯G*„ăÀ'«$@1¨‚móÚ>G,AÞúḶhƒq); Á˜z8צDBœ +¬myÙ9/§Î­¦¸½í)8ìF6½ ‡Í•Qàp°û¡c´ñ¼áWT=I^?@œþ…_ðœ¹ÒEëJƒõÇþ‰~€oƒèüúiຣÁ;$Éã€ó3îl4áRû6mݨð¯åÁÄQü½õÁöjªs£c@:÷N9i_§Ž¶aàˆ–„-ªø.UÂŒŸÃ ¾q[‰°]DDTSÓ*Hà Њ„ó]·‚[q<©bW~°+X±–ˆåDCxˆ, ý&ÂÄ(^v"ø³ÎË€ÉMó'Yا¡kMlÂï/ÀV ð˜ýÿa ‘oÙå(î;n  ‘‚ÀùP¼=ö Ûkà4Š„}ä}0°¼#ì~a|½ÏÆ: ¸Ç6'鈖W´3ÈÅ6l‘OKY©p„®D.8â3P‰$)ò}Žj\¶]ß=÷þ ÊÎ)ÃĬ !¸Ú¬6q&Ão&ÌcT$4|y | ¸Beª …•/V(°d(P°sÇñmzüàDÿ§ ËÏ 3$õÍVmvÒ0gÛŽs`UxW¶ð !¿k”âv1˜­ë {yĘ!ÂÏùîODðîel“uÝ16,üÀ‘ 'O„{[fE›ÒØdQ‰°¡%FgÁBrµ"añöåuà„Ø“øÀäo&ÌoSŒe_ìè¶+bÕË„}À žÂ„)Zyl(K€¯:mذ›Ö§ ih¼¥"HúëEG˜­ŒàýËø$D†E¾$ A‘ðTâr¨Øøz¹ÌñË¥H¶=x†[‰ˆç̉ókÄe}–òÝjX¤wa²™Is¶ÏÜdXFüW °ËBWœ>|GWýI†o5â“!áFï`ö‰ŠKtòÙá­+ÓGüþÝò']ƒç'qß°'a(³|J‰€JŸì<ŽÊZ"]þñ„ÀL„aÍXÅJ¬Ž’•†máx˜Jì.£†;åJ„ó“hÀIî úÕ aú9³ñ‰nÒp°n­'Ÿ“§äL ~â•[i~»êô‘EwJ¾Dà‰{›=ùüÞ‚l0½o§x$`¥Z' 8«H8‚SnfU«’e8[\oI¸ˆá+H`Õ¹&¥ì¹R• |½·z”ìôøæO–„™àF Ç€U}N”–ê°!ÐñCx˵t ¼ã\ ØÆh2B°1݃öLà œ2á@‘@˜ ]ÕÕ€d©†œ|(V›¼<Q0Â… ^€O‹ „ )å‚O^ùòNáAÃæ¬*‹?ËŸpàF Ÿ ¸¡"$8zA}ÇÄÜ^|Õ¹–ø4Ñ­Ç@WÄïDÅ{¤B°*Â;'Åž~ž_Ù‡æ O^ÁVPÝ*» ªe1²'ÍœA/‚Ň„W,/œœi}à—Ww¥å­*þ¬b|‚=ÓÂÒHÂÌ¥µ½.ÁÎ#VÄ·DEÛ2´dåqÇ7Kx€ÀT$g›æ‹ÚRxÀ¡•¼È*8°4à Jƒgú…Åã E¢â„…šLñ&BpÖñênu"ð…ߪ! N%¹Iûj {¦åðæ u‘8àÜNáÁC„n郯 ÈÜ[ÍYõ8@FÊ4FT°£ø/Ø•†“¼¤*@p^Å™×B*xVªD°9)AÔênbB ‚-§ ??•‚ĬÈUŸ˜“LÇð'ŠÝÞŠ€ÃBâM €€Å“ð›»[ ƒçAp©…ÿáA’ˆ`­Ëm ¬Ëï»|±=YxÀk}š’âäƒå…ÃáOQ pÀ7Á ö¬_à{–R ø;nAlÒ<Iì#‡&ªwÙâ`?>uüÖ†€_‰Bƒ ù¯eöê ›1`—øë¤&ñÊ•Z“ìe_!^Åyá9Dõ!¼EW „|µ.£þ7ÎÇŸ?̰ÑË ¦’Ô¡£OZÍN7q/)gŸ]Çð>ìè—æ«3¸A0ç8U Ì‹³*))¨± "AÑÍ`å}§8ðg›ì‚4/)¨ ¢a_ؾZÅlè¥8ØF¶2T11ØcØìÉçvqÄ´—“Ù‚eÁÔ¼˜í1LU‹ß*,øØ/(˜¾p$«Ž|ª³ÖøŽÖ ðË¿×'ø#-8q*(¢À¤¤W8ðMW<5]àí‚„]ø+ŽÁt³)ILòwg¾¶TÛ–+ÚÆÆ%!‚Bõ7¶vS>èøfø@6´Kq€à­D˜ñy]‰°¿p@#ÅApÖkÝZ´ÉY§Å‡°,!+°à)ÅÁkHÖ0“㬚xqÍZ ü j…L¼|0ðè n:ò¦ƒÈâ <@ç®ðÀÛE1üK=x‚ãâ—š¦L9ðAüªùª8d­Âz࣯À¯9/ÅAp£…=)Ýû &UYÀb¿²`¶F¤¬6ÀyÈo¬I³ÀP<@–Q£mæŸêò’ã?³Ÿ-ø„S÷ÿ"‚Ûz>K|q„øïÜ!Ö#…c’ŒÂj¡êÙPµFà3. +‡ÙU$,ÉJÊX ìÆí½ÑÂbj-V["dgܦÁ—3MT?ÜÊÑpÁ c;>+Šã?“ÝqÜQCþM„áÈ’QðqR‰À'Õ…øÌ¹E—ƒpÖXT Œ²°v"<ÀTìʉ;qµ7Zf^M”•g—“t´$ §‚hWàó¸v Ñ‚#ªj>ð'ZؾQqpeÖª†à$?*~á`íCûlN“(EÔH .6´nj­‹ò”†`ÏÀ¯J©¸ð»%@xæÎ+v…þÂZ4Ö%+¼÷`EóXUQ%$ ƒ6NôêßejøPWAÑÒ`烅ïȪÀŠÄ÷7%%ÉûkûñÈ~¢uløÿQ$«  ø¶ý—B’‚âà½#biÀk¯B, •¤èý‹D9yÀ%–(ØxhF’7¾“‚vÁñ Ùnᬨ ÞSy`aÀÛýÖ,.Œ¼¾^aà¼ûëGhþÄo=Àç•4 IÈòŒN8àgý \ðúz‘+ Ѝæß) £²%7ÿZrÆüV-$@–|ðÁÙ]ìú¶áÓæF„"d¯ÑÒ`ó·Ï*'PKià•D^…®4ø‰…þ„;[àÛÁ‚ƒ`´0³[©Ò 1&>¥ ¡BhàeÄ·oÁd'®ƒÀ—È9r—eâÓ#BžU 5Al~ÔˆÏÇÞIãÆ¿L•£ìDÖOEE´Îƒ}ÅŽJv¾ŠjÄ­ø¯0ø‰ ù»Ò¸¡°.}þ.J>$.ªAà<@ÅòœMyeïµà€»I›@¿Žðû9üîc‘æÝʈï;M#둵Oò•WŒjŸà…ƒ+óîû +ºZ+¢…çd’¯ŒS©4ÉTqLœH|ÿE`î4½…ƒÏF¤1WæÛÞƒälÛŒ+:¼:‘þ³Ã®ëÅ~‰!+`)¢@ðyëø+«Žètƒ“ïÛ@¾>À7¬âÀ¦4»ã¼½¼¸Ðƒó¢ûO4µƒwò¤>°—]w¾­<xoV»… nùTxмŽèm(QPãù‹¾YHfŒm-x—òÁ#2Ñ‚ˆ4•n¬4r•/KÎA»ppªF÷g\Þ®¦ìîj·Àc½n4ü£ú3‘ËšýçüŶiã’xÀf“:e4 û›Îsàs•ùÂŒâ HL| O]uqBV«ƒ@:HF AeÄ£q¢ À]x³€g Šc㪠ÖXãø:aU’¸_à7æFiÀÝ–,0a¯%¥AÀ‚#vd¬ Ý …ËaÒSÏÿüX·=•tÀŽ×Ú)à“æKö#6üø,3j{Z$:¢ÏF Âù×QƒòÀ7=* xá_..8Ùà"}_`°À¡€ïTwr„Ôø‚†^mô*âOšêN^^èeÕ cÀT* f;Sí2#Ÿ .,ØxGEYàwyƒ@Uć&Œ|¥]Úü´ ž) '"?! fþäÈöÒÁ%F½áê5>0^Yà{„€þ>¾ÄK„‚ƒÓ£¥A0!ÊïÁ› Îc$ xoRÔn Öit ¢MQÞwt{ qÂ=OA æ_ZeQå"_à—¦û‚kÐk§4ð]Â0ÙË+' »Ïâ* p½*ˆØ}wþ Ö¬6àÈ—>ë;14‰Uý¦Á°Mž+ [X¯ÁŽal{T/à•AB"’û læÉLy{ìFa`=ˆ]Kg¦‰õˆE ai*¸%…åB-¯ÃÅG¦ |n¦°`ÏÌÁ-g>ÏQÛ|»* ¶`‰qà“4RàÀ¡Ò`sÄ ?ÙFžœ4ˆÌüC…¾2XŸÚ`|?&œbð9X´àpëŠÏ¾þ |ÔÙâˆB¤ÎÝdqz;P= ìM¶ù…¯ŽŒ“D4 ƒÝ¦#ÎÙy¶ñT¸k+2Oìù¥÷‘//àçB$·Ðü¾Ì98ùpð'ƒ6!,&,@ùUÃÔŸêx4TŒG–[´«¸ ‚±"9+ &¾¢RQ°°|#÷ƒkl ?ïœÿWa]W°mÂîO¶îQÀÁÌŸçJ4äIÀ6cã Ÿnb4n8ó€»ÖÇàF‹ƒÝ_<ðS(ã^F’%¨+‚clO<’À“à‚3o8J¼A²¯¦&FÄ„±%'Ý“y‚¿­àç {4P°88|ÞÉžÝkå±jÁÇ“Êg?\\övâjLh`a0ïþ2#jº¾˜\fäHÚ¾«ô-áÀ· c°Ì܆èÖJ’Ÿì[…‹†¿&¢õÁŒ_.q%ãxLED?^ć„ ¸ÐŸÌ  µYÈn3âï#Hf ÛÿOÝŸ%·’n»º`‹Bæuñ˜-¸ï·ÿ I2–ö>ô9Ò\ëdšÅã´˜S"R³Ÿ,°ÂÌê¾7³´•är07^êø]·<Ø÷èô(.+2`ÃOÕ)ãwPÉ€=½|ÙˆŸ»‘ˆµ>À¾^É`x=M ÃÔÛüLVh¦‰\~jy€º‘Ö+•Q›81s¿ÞŒæ}ñ;‹*!Ì,B¶õﯔxÆnóÄd¦~á¥dë…Êõ$º'¯Xˆh¿ÐÜ0]0‹5²iŽj•ñ­BXŸª¯HwŠ&GŠ„0™ò}sLoN¾[û keÆ?ãŒp—…rAøƒYÖJ¡F*êƒ"zé`‘Fµ6¦hóÌ :O,L÷BÈb\³P¾£@Xp;õ0›õ ÎE<»9‹•Ϧ@XŠ£B”¾Û—W|óZñßb|Ðø qxå»—L3~K?ŠkM®h:ÀéÜÙÍX{Ã]”YþcYlMÇ0]œÊ½ß1`¥„À_x%„¦@ˆõŽÔ„¦jžXœ8u+Pï¦åÁóËé ˆfÄ?cÅÁ˜¶ ÙP½ bã±ÀûÛ…¹ðL½¯8@Û%+³Y«ƒ&k©ÇëƒìŒ†{z&Ͷ‘¥lF¼62Hòƒçµô=ÕA´P^bxó¿Óƒ[ĉlpkÅÎÆ• ¶Š xe¤ÅR·NÖÌùÌ¿‚°P/;¢ÎwyªÇê`ùÂó"S'æecÞœÓVøVÇØ€ÃØ€]§|µPÐŽ[•8PDÅwô {Þ5n•ic-9·K/™ðãÒab—ÜÜœ.dk´oãÞl-S¿¿† î!ƒGÞNwÅ2Fk´`EcËüúr¡0AÁ_‰² ÊÅ9÷ [£>`Ë@¤Sç‰Óì>P'Æa"»¶!©0Kœ¿m»ù`¿òÙ,‘­pu¹€•µ¶ ók´¤;ç“g\Å6çÑÁŠNwiBÈÇ Û€'„F›˜NìplxÐÈ•§«Ÿ&f>H£ƒ©°Ay¼£79D>8«vÝ ”8¯G耗ëÊÓEp¥òAsË„m‡òÁšF‰c>uÆÎÅø€ïóA#<¸²ò ªS$ÜT¿]°²Eـς\‰4ádÎ"à†Âš…¼jìÂ#ìøAì•öàb†ªíëVôÐ_~/r ¯,½[ˆ:¤a$!RtU?9hæ£K¦‚éÁM§S>m\¾ðºÁ¤ÊHï®LlÚ…¬=8ùâ@›”…‘ ²òjÝ×2Âø…£“&â7èÝÝÂP–½JkåÈ[7MŒ|ÀŠ¿]È›Æm­]ªœ«ƒqŽåAR§Lò Z4ãƒl Ê9›Ëœ è!¾~ÈT ê:=˜ÙôH§‰œôkÍ''),œ¶mÓƒ¤E9ÙÛè 1J+ŒPò8qªº´éúèè-ö[ʟǸ©¹]H|0E!R´P=±R16` ›+‹áAå>ãàé£n!®ÿ§|ØÈ™ç~ÉTX¨â Bù »¤­ìpâÂÄè¡:]E´8ˆ‡'6Øð©ð}#üŠ©T¹&^ÎXqg‰¬”ôKgœ¿Øe#ιŒ â¡ó´Ÿéi̇XT».±àƒ[DãƒÂé¾v!û"]\éÚ!®y¼](è *vvÊT>ØXbdÝÂÅÚÒf‰y¹pà/Ñʃ¬=Àë}#”˜×Ú•ÇX.äSç o„Ž¡!¾íxûtá[ ñŠâe#oY½@h¶ EÀý–î»?!„œÐ¸~ñæ@ŒðÏ# k(#œ9°u㨗_ó\ÞÙº7^"äã…5Ç4"º¼_HŃãÒtÝØè•F.fvÎøÉã„?º0¹¢ÝŽÂ4Nª,QPýÁ–ÄHÑfýäq™ÍYäþÁ-S‘Ç4#&þF«¼1{+!ì|Þ „Ð/à¾Há`tჽ²B©¤Ê|œ®|€…³ž:#AýàƒãyX´ Hàê†Ö¡9^8ø|ÝÿÍJ| ®„° ÇiäËte¼"U÷ƒoœW”S4W~º¡4Cî,„аÆ›¥!nÏ/>eF(œÖ·æx1Jq¿ðèÌšÞö˜<‘K:(bC)|É ¨ î¡‚®[ÈLgò+M§aúÂ×Ïx€Í2•°¿Q—´À2dÕsÄ †Ó@S4°áCìcBÛ²5ÊăÇnŠî„ÀYyJãÅhEa Ë.™òeã:½¶Q}ðA:l<§xº0>~¤Æ©¸rÞ׃Ûfˆ?ãƒB}p· [s»PÌx¼çÍBc“Æ´jûFæyS'fy"N •ŽJ}­•³imÔHßQZË€…±5 (;‘¦a\¾pC¬”°”0㙩R²Ó:ZÝZù¦ó¶ý+Nà{Uå„¢kÀ²Ù(8o¢ʱq ”ÐÍÙÅI™¢sâĆ1BqÍ„–íJ8£QBU#l¬3Bˆ|ÞŸ|€ª/å.=x!û&NcR d«uB÷s¦‚ §uìÿÈú€§#ïW òò'C®xµiç>;àOf=çï™ùA–+§kç'TŠ$ú«´icÓ06 _tnl¬iÀ>Yg±oäã ËxÏ„ð?È+BΦ¸]ñ æn( #Q,'jºœî’,73„B€€u†O …">Æù i¿67UŽso¤ØHAáØYµôƒÆó’;Å»!ÂE¦”—™p¿þf–ë2UŒÀÓe„”ôþÔ`篌ð4@Œpòý™Ns–ë·=ü+BˆŽ:Y–+4ok–—/öuÿ3»´8U|þ #!o„ÐHóÿ.!„8Sü— 3Õ«5ïÒ ÃÌîJ¸óxó éѼD}âTMÙŽÁé Ë‘øüçD$öü76@Å’°Á¸Äv¡P!DÁòΉ‹Îø?R6@[n#¬s?:pŒdpò©®‰øÏ˜©!+†=»¡G®WÎòD>œ¶l¦ÈXð)T>ªÙ çJÕð€wãï+pÞáZeübÇ+$d0¬ËKiâ“ ²!3=Ø€‹Jc¶Ú6`Ѫß;ßfζ¡9_à’úµr<_8ò}ãytgƒÂ,í(Ì7œ™;RÌt‹Óú¾÷£ 'sÆ)Øyâ5D²1+Fl|üþÄ‹õAÜ/Äûƽ²Rq¦d|€¿?eºix0I«üàvQ·áA±_À ¨ñîÓL‘TÂ÷ ÏnaÄÇÔäʼ Bà„c›&F>˜n1O<²ÓúÐ\3§LHº69ˆ§LÓ°âbN¹à¸F¸€5ŒZìÇKíÁ“ âq#ŸgÙ䀧„ÆIž¸|±BÈc\o²RÍ¡G±kÜ'ÕŸPã‚èŒt°Õ±+’ʃ ®&’J8óö˜¶48¸²Q.à(©wÉ༔ ªAâÎ)"Â+‡øüäƒiŸë×C1:(b™üä•–׿HBÈÞÊœO`„€ƒ)#„‰eáVäãÆGS1B´Gº :§„¬F—ÿ]F¸0ªRFà/¡3Â\˜#ñ°G !àC`ÎÊÅCÁø“˪ñ¨¦Ç”+Äò`b±›ÒÁÀ¥“²¯…µUÀ]Ù`H‹Æl¬Ìë #ƒ¢8à6@¹ÏQþŠ ò5ÓÎÿ £ÜmyuPlp$¢d0áGndžd0±:AG|€f¾ÊÙX9:?[ÚF«\¤¼tP•_n(äCçǯ:mž|ÀÎÓJ…Óú€|©„0§ÑAvVžrËQYLœnÕÁÿ1Ë•ðäŒP¬p ¦ŒÀ¶ˆBìûn„°³-¢UÍñBâƒm5íšé«´c˜r,S'D*š…¦:À« eƒç'³V+ÎñráÁi·0ÆÝB¥;`k)§ƒÈ|‹âÓƒÛ¬£ÊŠ¥œ©ð{êlPè³íï±Õ)C¸ ¶‹çF…Êl—-lpF§õáâû®>(M.SvNŒÇsg´ÎZ¦;(ŽÏâ¸q¿(ŸÔ:1 •W^Ïèfáuî“âq#Þ}Úfߟ%r²£Ò¾üNwÝ:ã«îFiùrw¾î¤Úd¸æ[gvÇSB8ðßãåÁ‰Ó %6±BàHå—µ ·¤6ÎÈ<ÂóVù¬#ŽÍ9‘3?Õ91Ú¡ŒÛÑä´ÍQ‡´î)†e6‰‰²±rÌ]hw ¸$3>À¥óÁMÝ+¬Ô %’Áˆßd'ƒbÍØO˜… öÚø¬Ž"…efq™’AºjXZf™Í$1êx“-d0Umœ¿ídS8{GÉ`b; %ƒ 塯iÕøh|¿Íš^ÑA’g"XS;¤Ô…³ w>¡Dºå9gËÄ•°?0YÇOS=TYW¬m8ëðÊ`åÈp!T(ŒI”xœ|¨j™L ¤çm?É`ªæˆûÂ,ø“ fî‘,Á5Ÿ0mc1Gž +$Uâþµmé`!{*³÷·_46¥AAø98ܤIYTö“¦/~ø­8Èl€R ¯ òýÒ€5†Ö ¶v^LÈðF9táÁaÍx\xféä`@ý“…xy%„Ð%6nXš[uO†µh®Wø 2EÚù“P>àæMù€ÅÂóšCÞc(¬)âýAËKßÄ'¤›ÆãÀñž°Á…iü¯†¡¸ilêÔ¹}Â9¥müÂTÙ€«B£ü2`Oot€ªqmÆâúÔ"5©þôÆxû¡|À.*U®B\S…°íQ‹4mU…Àñ3Bì)­„À6àN¨¯¶ßeüÿ(#|; ¾¢„$>`§^¿c*8JEŒ+®®>òUŽÒƒ‰GãÖ/íB。ó; ŒüNð;áåÛ=Øv“•pÈn C¦DúÛõÁ‰‹(VõAÎ]˜œ-Ù@™YØ`Y¾PnclPt ø¿Q2øŽðyEYz€s7c<‹ù@{À¦RNwY"±ÔÔ ‰¶©qDšæíÔÆcæd uÆ/ꯉb(Îlbt …ÑzUd4>±Ñê I^Ø'œyè@‘át ˆÛl<ú»H9â}Ýqgië…`ˆtü3g տЩ uæí•.`Kkl€×G‘‘ .¢ÌógÑÜ8i;/¡…f>~T:xTÞ7.œm¬|€‡©ò‚a+扬z>à¸J'VGæ'[0®ÊøG4ã}¼¸óRB` •&¢öBá<_w FÈGœW#4A,¼äòKç‚ð]ÿ›ÐÆ Ù[ r>pUn@…£-#,a"Ö ï–Ýzadƒ-Xè.åCT÷óÅþEù‡4ÆØÚ* ÿ¹¬zÁSqÅWÛù ¹sÎûF¼·óvá¦q"_h¹!Ÿ.ð1›"ód'£œC(ðªÚ•Êø 2>àuÕé’i¸Ñú 8]À³ S'¦Ó…¶]Èë…ÇÇUä2åiâ¶°Ðßæìt¥|€§AÊãëPç'ÄSçŸlãƒÆS¹èFüÝxyp—i"*ç„–/Ö¨"©ÉiôBä¾Û>˜é~Ê„›z+‚$üÛ”pnôÄv-i„ö&ÆuÙXåÅé'[èüàÂ^ÂêÖ–« W(¾ž'…ÅzŒiÎÊ$­¹s±òöúà¶Cç¢[(Lgœo~¹÷ 'ü È»Nlþ¾`Qúv}€k“·sù9–ë…¡Z/Lìá¥õkW´_ˆlp6ÕÇZà¡ÕÁ,•ÆDHãöGõê o»õÂM—Î3þe¶^Àmšõ ¨AóbÛ˜Š3ËÔ”PÿË Ëoãüéò9S2F:¾Æ&ç%Ü… !,Ý!_3 ¬^‘~aÀÞÖõÊø—)#¬B×~e„`„ò „¸odÁ B³``­›.°´4>ÀÏü£ú ¸gâV@ù 9uÆYÅû¦Ê+¢ÏæÅ=ÓEóætPÌS}ð2MÌ—Îlqéù+‘ Cå¾rÎY‹´ì|ñdd0³9‚I2HUm0VÒÄ8Mä«D¥ƒ&€åAùši*èàÀL·;k¹mxÈ`ãNIo™–LE€kÑ-«…çâ–Æ„­«nºn,\Ò¶/¶Gµ¼ÆF}pOÆû™}PXËí|0qJ‹ðÁÈ1Ýï ÅAL`Ù÷õíÄŽ:+ë¼`3éAßmÒÆí"®Äz…Ì뉟–Íãª1J˜v¬:h†‰Òå¤S㜹}ÂÑQy޹±Ê=Þ½Éf+<9%A[Î|V:XØ£Ãè ›¬¯#þôïÝ6>˃ÊE5‹°W×abÇœ=cZ¤º€~®EÂÂø€oÓÍc=ö áÒù(½^d6À-´]6¦faŒÙ­#.·|’X¬x³naÎØý‘kâŒm)ð{jt€m¿ÓA“Ï–CX.D?é`ZQQñët P僢[H›…çéBæ6‰{¿]ÈÓƒ¹ dÚ/Tª=ÀrÅÊú#Þ.`]¨|pr]¨íB¬ßƒ¯!ç·âdÅ¡¸eâ) 1BÁw•9ܽÐ%â£õÉ^!ëì°>]ì¬8Lp¡¸ðÊ /8›TÄÊ€Ûa‚µb‚ /û]…”…'Õ¾Vàp¥‚æjë"¥‚oÇ÷WToœñßk½–ƒogÖdü‘ëÁŒáO.X¶¯âȹ) ð‹áW9Ö›yeƒÆ`=ž8?Ø F1­ìQacƒ{$Ê‘ ½XT •›2çSê…3BÏ.œñ5W ÒÊèî©€Sp„ –)*¢¹úqf”³ÊZ`e¿QÍÿ*{¥áüf(°O¹“A±fÄo: […iÀzñך‘}“„üÉŒp¿¬(¬±QB¸ep°íØ#éSu´0³S)!Ž PF¸X]YuÓÙVNé4Jˆ‹…è¢zœ8uJh9à‰¤ †œ¿²Ž8müI{“¿Rí“&qãߎz¤U{Ve˜GödZ"løQ¨ Êö… ´•œ¹§„â÷¯ùuZãñÏN ?Z(&‰3” Õ»è·!F…_b.Ö³_Á²ZÉàÂÎ@É€“:lÍÈwZp††Æ- ¼ê'lÑRù™·Ð $.x”ð‰ º¸Þy*¬_ba¶s¬¡mðð¸…Íöà‚ïTöWlqdƒ½:p®Øß£?ºhäÑ“W™Ø©À¡ñO [±VÙÄø`žbVã3¤cB ˆ’˜ŽñßöKd›0Â0O_bž%ò¥½Â1ã8Hay)g„Àv·ê—ˆ™Âœ³ÁúG‰Ïç†p‡h[Ülyyp“ iD¬ 쬾6>à|WãƒÂ" ²Z °Ë£ÂÁçñJ_Ú<±ðD»åŽPÇÄÆQ9V–a?ù`<ªyba¨<ó·Gù k”§«úÉv ¹@à\åƒog¥W„ ÖñÍö –&®»H'„bшS®!ó~Ý•&\8*eü%*\¨‡„6¶E0>Xb@ÛôÅA°ÆøUUBàÅúû™ ø¢#ŒX®(#TóÄÏ·´D@!„R†ϩö ë¸u|Pîî´câÙBôP=ø¼ò“P¦†š›ÆÛ"Xâü oxáq Åv! \\‰ÛøûHgÞ¨½­=hÈeÕA5?H*¤ Ë|%ƒj€P”+ÌŒ 2 …iäí±rAJvߟ’”8=Ho5 ?e6]V‘2þü¢ñ®ìV |ფ|Ðø!­ÈÎyœÈ’Y66ö'ÓÁb%]-öêC¼oÞ¢Ÿò3ʹ°;ˆÑîÛˆ.aƒý(Ø`;ÙèÁè —Ø&i³pa #¿Î¹Y˜æÈ1¼õÀe’ñË ?ტ8ÀÿÏŸ¸>ø™Và7õoꃕcÕähaÀ_1ÂxbãGÎ…ú dǃ¡q<È LÍÊ•¡2õ#¤³…í9{Ë †‹Õœ…»7–Hq×ø-M¿$„=;¬ü&}æ\ñ'ò^á&à ldƒõ•¯Œâì`æ7Òf‰H—ZìÕ,qnü¹ê36 ?cÒƒ{¶QŠtá *lÐ…1M8iµi"~• &l• ¶œ·0ò5¾mQ5¨l0Ï‘¢iÇÚÉ-ªú *âÄ»nùÕ‡‰y|€ˆp:ˆÝÂã·«ƒ ‹s»Z(ÜS'N³ &ÎÜ3!RêvþH 2H›…Ç똴%0UÚ1<É w OíA–*³fÎØ ŒÇøz’¸g÷Ônר¸£57ìôàtpW:o•ðÁñ]cÑ- fÎù ž1mGÞ-<ž¶¢>W¦iªƒß“&>þ5oS‰͔RBåˆ4ãçe”À~Z¶mlâ[qÍc·‰J HJ ßû+JˆÛÆgðF |ú® ÊS«Ü¸ÜÖ1Ä aûB¥šQ6¶Ÿ”%°š²éxÖè%4‰ø/Òóü%ú¡é"%Ä„÷q«lðãzÙ8£zSaa1Ÿ …@ñÈÅqŸ^ß6>!F:³JÛXšŽ¡¨°€ú#‹õ12=åÊY4â+ùɆ! Y;®„Àkz'> rÅr±c@bQBÀrÖáŽ×GÝÛ†2¢ ¿ˆ6Qd ^Ý1dEÒ£E]³Õ¬'Õkç,@˜¾ýè^1B¼væ†Óãšß—(VmÎë?š"’¤Ü6,Ë…œ X€Ÿ¨R†ÑJ ì l”°oLB ‚&QÌ”€$®”€£˜·)aÃçK(a®I¼­ðIB-ï'¾ÛJ ®­H`¯l-bîÂø}¹ùŠ¢$‰m}숡±BiŠ„½Ú3ܤQbÌûÓ!Η…ŒÊXH#à; ŒcX¦3[+?j„ iL ¡°Nd-ß{'ÏÏ1Vàïz#­+~êBKGA®„é`Ë6ëóU¥ª¤Aˆ*„é*›È!w ™6oÓÁ–׎û¼­…F1g´Í|h«t0 þÐ׎ÍùB>p<±ŸP6ø…yÅñâ¹9xn ìUkþHŽ3~->!ƒh«¼¼!V6X3Ö*`Óï­B¼gº¸ÉT6¸P)¬0°^ï~• òì Û¥ Í5S–$ÍS¤ƒ£‰lÜ8ÿPé`Bs6mf¬U³|áà' E·Í‡cM †h´~ðé†ÂÖ©ð©õáAÁØ@2<À:ÍB\±9VFh\"#àâVae9²º'²š‚ßg%g°#öA*BHÎÊÏéA•Ë)ûMun¦ÛÅnE(CB„6NÌJÀ;[;xæ€M½aÀ]ù`Ú^û*ïÙiýbgbB£QäË*䌿Ú8æ”¶¥ ,¬`1>@¬{…ûz5Bh¦‰ÇEP°V…GÛ )!`1òÁÅs&„1zªvG ~ë­DH©ÎÏSoÜ…i‰°|ቺµ |Ífª¤Ø2 ßÒæW”÷ +3¬Dà~àƒ¡òL»©B@Ý·1‡2 #Œ…Ý:²˜BNqåFR†¦<¸¨@µ½»jäÐ.`±bb9]<¯¬`PéÁ´4ÓD6ŠS2À>@É€uáBÃñ…Å¥øÕü‘ŠÚ óA¼pܰ‘²vÙÔÕH… .bî £z¨sàÛN'ŽXôh¯°~¡ÌÁø °@8p²«âƒï]Ð+>ˆâƒGÎ_Z yn› ¶›by hãDl ­>Àï¡7 M/ØaÒŽšØQa[ÙVM†Âó¡• GU¾Ky[Ä¢oá„é™ä9-AR„º9k"!<ÝG³Ã2þUÞ/äõÂbÚöÂnŸ6ïn9`X.‚zœîªp1gÃdfáƒùà(xáƒÄÆ8¥Q>Ø9ªÇ.š ùÁÁv' ð'S>ÀòŽ!ÞmVÊ ÍEÓVœ4MG¶X^Yoú“†s½8µäÆÜ2°;ÈJx¶¿!®m/,Ug”E %¬ÕÆqFu°•ø=ý›†•÷8B C±qœyXh”€5ºQþ`ºqäØf$qÖŸ2Â:âàCa)lQðßl®iùêKÌw¯ž¾$B#„mÅfR aËÂã!H3„áX¾ðnœ޳IÒŒ…ÂñíÃüŠâ#ãÏ¡2]oîN÷\4ñ‚]4Iªë”p€nl€E¼ñÂñÁ¹a`·~ëX„þ“ d+Aed­p3nõAДú……C¶òÁЭÙOù`G·Jåƒh™6œãÅÈÕ" :„ýžÄóFö$22¨ üÖ(àtüôCÔ,žr{¿ÇøJàÄLÙ€p,¿±Ù7Î3kšŠn¡Ð'æu#¾êoÎl‘Q†nžX8¦ML§Ö,Ę÷g³€"%ƒëk°ûU6ø–>½¢ƒ¨=X°Æ7:@„~°oä¹·;¢Ütí<䆉½^”øJٹР!š(>¸'Ÿ3ñÔaœ°ÄÒnaä ^›'¦úà`n TúDúáu€//mà ì„D Û„›RÂѺbûbŒ€ce„ïèïWŒ<úý¤@àëU åÁ=MªhtµHˆæû…®[ˆÇ3ïc]ŽTÐÁÌk£ƒœ÷Î=[8æáSzÛ|»…ÊFqÛøíR6ÈõAÌkΓ7XÖ,à{kl€‡€ÊC+oÿLy¿åH+Ë-I34§Î·/ðµêO:˜‹s¦™­Ë}»PÜ:ÕßM¬œ-¯åâ0Jè`â±Í³ O.„ŽÊûTZ`ŧ|P]/ì9ÒubÕ’–lã­ ÇgPfb„qà$_eœö(#|çV¿b„xà¸fEÒÆ,÷ë€áJ¸«_ÀÝ >^´s¦¢](v Ñby޹Ɨ€¦³áƒ‘­ª¬<(ô‰(Ù5·´¨G:GUübpXˆö (‹•·† °hV6àªÐåX¦j}À:ËsE.T6x½YØ ‹å-o.ÖËάù2ûÄ‚ nJsÍ— ò'&NÄñŠ«3äS&ÜvÛä `–„+4c쯕 ØæC˜÷;ÆQ¨Ì» ]*[vAÙV´D6¡2þrT˜ÈAvÔÈi?F<Ö#&¼JWÕÁw¼À+*ˆªƒB¨¼1ùÐ)w ¼çþˆ 2W¼w1&¨¨ 1-ÖDÖ(äd¦G£0!Ç ±›óARÍU##½2ˆ>(|û'„pvsƒæŒ gJo+•‹+ç­h¢,ñɉ ¢à`Ãúö.(Z(72@€~äyDÊ%KFüRøÑBÔ$>ú‘¸Sžü$ƒgRbáÒpAÌe:/ŽöLtÇq²GÚT­ Oe>44.ÀÁ”^-ŒÍQ#Ÿœ½wÄô`ƒï1Ð+>ÈGø¤ÛçÎfPEbvTf«ºfÑiæ:×nðzÄ >À [*ði²ðŽ’~ XÚhŽENju”V´WhJƒ(@Úñ Õ¡ÁV ‹Ê ß0m줕ÁȽŸ· ÅÌaj3ƒpÓø ƒxÓÈ‘ƒŸøp ¡7 Ø#à?è>Èï»Sã|(¼Y(è —î&Z4åÇ/:Ÿ,°O‘×A„ô”ÜÅ“6%{W„tÄ×á¬bñ¥5>Ȥ»ù_–YÈ›e¥$]Ÿ$6ÈxC§ÅAA\xje€ór§‚{˜§!f¬žÇ‡CÓ'à èmç“…k%Np"XØ„U‰ [£ñ˜Ly j ŽÎú$ru·xVÊ£†raÀ·9ºL˜Yµ`…A!rl¨Ößtû‚ ²‘òš½S;-"›‹ûms1CÄ*î£ä•86Øšä•©8\â㊷‡ˆ?ù`à»óÁZØ ®a£p¬æÔ©AÁ¹(ÀE¸`©Šžn©ÑAa|²c‡©EÁÆÖVÆø9) F• ¾#1_qAVà{î7KÅq-BÎ"˜m½-¼•?QíPìb6‰ì…`>Å]3–‚Vä³¥81x Oõ‚&\](4Ä*¥1j’Ùñ[Ù °¶Íé —|›©t°~¡–Ì{„bf€Ü£MÂRÙ|W H_ÂKuÃÈÜ23(¸à®.!JŽ.¤TJ€>pLÅ!šÍ PV£TÉû×¾sÖ£5 Å9sŠ_zA!In‚Ý‹eB¾Yš«e'4»¥zÎ_Z×6ˆŽ'ËŽï¬I’ÙÁ$ÉÍ2!Nç­É[áh%åƒcÅ~Ìø€?VãƒtÂx²ù…,U' ©6Xx¯4q*.XêiKØêÂÕÁ·ð»½˜"»^Ÿ$Er៌S2« O4Î&±^@á„p“$yBL!䯅³ ?DÄùàK#õLÍHFØñ'³PwN"RFÈëEüýXpl¸”×ú šLòˆŸuDÃo¼Ž—/Ä*Ì\ô™&9÷ cÈtß e>± ¡¹`ä\sŸ#ò£Ûœ£GâràM¥Ý0b å7Œgj–\,Ä-*ýB£D<97ãm%"ªÈÍ3{ãwó›~F…†cGü)!Œ|„§·›B¶€Z ÌÍ#Ž›ãInþg)ðŠ¢à€ý:Œ8ÜÓ׸*8ÀOË á®a"þ–Í-O.„„˜à0ÌΖâãÜt ûÜÔì-þöc“±P1Bn²8y˜Y#oŒ€„iGÍÇ~W•.nB>a„è‘x¬Ámûgˆëæ]a„‰/0œØ“Wwηå4F[õ‹E™Õ¨ùñ¡8lΩlóŽÿf«ØE9a؇S9¡Ð$N¸Ø´ç|¯€ûc§„x×¼laŠpOW´Ìù~i:XÁ¦5B'zÊ8p]í:ÄȬóµVa‰|7‹+  ý–±Ù,ƨæçTÁØ ~Äé´¹d,-§ÔÌ3”šÑÁº²°M32Þf¬Ž¬[hdˆ™ðEB¨\“|ý¶9ñÁƒ{òéÒÞX¡Í¼þQBÈ+…oW˜W|w‹,pÝQa‡¶£¢ÏøGÂ^!Ü•·„Ä,|°ñ¾'N•œâ ñbZ¦|p‘¤d£DV€ûñRÑ0¤ÂÆÿ›$VÆ'qǸáNþ'lÏ„ÖÈ; 鄸04çdÜ;(!¬,g1­W†v˘Ó—à{ò`„|ÛŒdi·ÍÍj¡°JPAáÂ]iÍÑ:yÝ¿x¨ÎŒ¼@(¡ðJåCE­߯4_ >ȧÍ(]{€€èýB!=âÜúd°_§ÍùJaFõ– °i·%cdƒxÙÌ÷ãæœŒ û_lPÔˆˆ¿êøýI{?*°·ÑÞ¸ºÕA¶Bº˜þŸþx ¯é– ƒeáƒ&qÆUû…­åÞf„e^R LÓZ0{Âi€ÿ-vÜ;i´Ây1aÑõߢkîR!GüŽû~E Qw°ãxÀ"ØPcã”À±^:T,NxüÁKFÀåŠ0ÂEÀ‡2;S¸9ZîX´¨ŒPlç“Ýu”pá|V "ï{Þ]6®œq. ¤.Y¡¨¸R68&…°Á|6óDöS68Pc¶©ÿa•lmSwü÷ ÈÓƒªY@îù$kG—¾nŒ>‰+‹P\`Œ€=«V<ß³ñAS\88#ð”XaIÙÍF(æ8S{7Ì}Šô•µQ(žøÝðn!Þ4CNf[׋[p­¢þ`ãYë^{ ¬ÿ ñ¼ñÀÛꃦ<(IK³]ÀGû>@làðܶ àãæãÄ|áxâÃeÎE8ÛÂÌët „•©JX5+4IîÉePP)l0[Ãxìfl€;-Ø2D‡œ«ù>uâþ4ÊOµAvU?²‰òÁŸ÷'£D¬Dœ îš4£Dü<• xÿ d€ÅùÛd°øT2`Õ¥±Á´áàÉÙ «‘ØÓá½ …gœô-t0ænal¼Pv¶-6:àë)Æl~ð(ø \g‰üÁ !¤$¦ýñ¿I«…lª~âî|ÐÐAdƒFŠ„øü¤4T° œ6§T°ÊM›w <[V"À9†Á£•çÏóý¹Ëó,Ë=¤+<»„bˆˆfírfë£OÇvU‰ Ø(dÒÉë¾cäJh`ä°ÐÀ„£)åïô+"ˆ;¶Éò©A!RævC© sßk?š¤ü¥mbÎV2àˆ/#œR;äœU‰ã…÷™òÁr°¹’ÙP}ÁåéO>/–hÂ< }»2`ÃmÝu® ЦŠöÒ¸.l\o”ÍS· µ‹B S¼tâ]㉻p/ çÖØ:#4­ÂMFÊ0(”°å¹Á†ºµ (yrFˆ›…•ßl›Ä»…G°ñ…¤Ą̂x¯Sx Ëš!.pÔŒ†¶6{…/ Œ°æS>`僋{rãó(äÙÁ3Â:BX Õ‰ÙtÊøA8dUVë8Ü¥JĽ×ù®‡rN…L¹©pºbõA¶N|ÒAqè\„8Ïø{VêlÞïðñ×ÅBŠg‡±‘)ï\‹(ä9"/²… ö‘›meƒ/L” °˜S6øv>ÁSš$ž<æúÉãTÙ 4Õ~ÿª:à;”wÙ`ðµ6õFHsJ{öA _¤ík;ð1Q:¸¸÷U>ÀZä',Q”ø¨š|ÆÌ vSÂkUlxx­|p&Òþ5Ì8¦F8/D|ÊGvYßxu¬óƒï˽WŒî˜N>¯FØIûFÀ–Þ…H7:s„±÷ #»FþG;#DçÄ‹˜/e„äÆû\Ȕ٭×Ï“éñ±FBØoå˜Æ´ÎØSHÃðø«°˜UFØyØeŒ¤Ïe?²³0ÂSº•‰#ñ”°ŒPBØC.ÛRx©rü…5 È𿔉Y|À!—Î7å.L,-SF@u‹-pöíK†‚ð©ÐáĶKMÐlǰwÎMÇŒT—èµþäƒ[œWŽF‘ a_—d+”ƒsýtÁ€s5m†‹«¸{³"=”–íõ†a)¼T9ºÈøO ß/ØÊéà¦ÛN#w:ÈJe75:À_ÐÛt°±µätÀ)ÅFŇ¼)!¤–ã9-ø ß9cA#õÁ4Î…Pù@@%„³ „‰ÛR!„‰ÛI#œÆ[¤ÊK¶R=Ye„À6©>Q,n™ ³õ ¿`Õ2äacKmo Bœ!lK¡NdÓ_c„ùd—fc„l¦:ã/ÈJ„8œëdxãƒl|ppÞ —Æ8ñÂÍB Ô)!ÄùÁ˶:N,È€%Œ¶](¸à¦Ù޽Ï3^¥û¥sc{Õ+_³šI |”cÚ\€r%ƒÍ®Œ rmÀ_ö÷sq. Û…¥Qpöž±A´E:ùxÝÉ7jFE²ó‰½]:/‘ ¢OZv>Q‘ú«WÈt€Íü_•üyÜdª|ì<'´Ô…fµ0ãËg‰YŒ4áÇa|ï;5R,ð9:XJybAìѯ®ÊÙeñbΚ–Ž)`S¯N(Ç™ÄHÙ%ƒ€d¹ð ¥(ICù‡¾[¸íz¡ \¹)Áü|¡Ù-äÙA6BپƓ¯¢µ>ÀâÈcs³€o›3á—ì]uâ !B•^ù8ã^wX5› kÕ+OE·À Y¶kÄÞäÊÃk„%û¤=Šž4M§ª@À×FwXÂ;ÜdŒÄ§ÃÎñÜyãïŽñA£<(ÄÊ)¶ñ¹j¬ø€ÿEVç Þqë®1f°Œø£;$OåÒ#<>«¬E:¦l“¶ðJ×®p:õ“ ¦§Å`&Nsá‹4c¨tðÝn¾¢ƒ˜Â‚ª /:(l•7¤¸¿âƒÊTñÁºs²ãû× Øg!ð”Y¯ùÏ!8η{¦"çÇðÊ8Ð0íA㫌Šn³AÒÚ\/#?^ÊH—ëƒG··ÓÈ/86¹òœÔC:_8£8ñyàØ4 …J£M¼ÍG»'„\4bå¦>ˆíÂEI£t€» cƒ‰÷¬~ÝXTY‰”§,!22ÀIÎ{,ò`.X>Í.˜Òé³:ÀKªƒ§…e¼mœ8Ъƒ\¬CD·´s@Á“pÁÌ1”L·Ê.í.çDD±‘ÊD” FüöààtíÒ6>:à­_ÓvkW:Ào¡ñÊÏM‹”O¸íwBHÒÄ Ïi“&6ÕZ8#„–§Œ-º#MóZİLsNm¼±+%Kò?Èvi,°ò†¡¹vÎn(––´oœX{nŒû¾·ðÛÆÆY9j6^BØ1S1?˜&ìZŠv!Ý2M ˉհB'òTÚ…³jæB|pâcaû…,U>¿°mµ[&}›ÑzÔ&Žßí¯è jvüÄívV¼[(´HMdãM—Lˆ>gƒ¬>0 Ç•HM¤svWæõ•{¥5lPج³sÝ»õÁpÑ«2±"åå„¿ÁŸm[ã²~pØ·Ÿ:猶¥ºcÂÏËØ lÌV(Ã÷pî’ æÆ*-÷ WÕ¿¦‰¹_X±ñðêà&烟çƒì•6³ƒ’É ïD¬V¬:àl_óB©Æ9“‰»7/Òü ãƒb~× Ëœ¤‰Çy.Åv¡±Nä¸f»\Àñ”ŠÖ‹êIïs¤óÊfMFëëeãüÏ”/™¢éàñƒíBSÜFøÔ~Ð,Ëü~yuw P×abc8-…“jÅÉ*m¸0T-R#MŒd€ ™•0ñdM¦ø]~[‰´E«0®Ü!ZuGÃv¾6R}AÊ”È`ï|• ¥r“àzW"®P r¸û‚C]ç‚⦋=3=À•®™d[åõ™;žW ìÝbWÎ1¯ññ«ÎJeüþ¼k‹´Ìøqý¬ ŽÊ…cj¬6àyMdÂ_Žû¬sb•ÒS·Õ‘ ÎÉ4g#ÕãħÏ]ªAb¦6¨ø+—´‚ŠüÖMxи"eŽa:àì&Û,°6ALj8í72ÀZNÉ×mF·¨”qéù“ ¶¹* pƒa\À‰^¼µO˜Ã-sÁ6` k'±MÈ"$ä@㜩|`xðß ejî ‰rQðÄ™ Ïs­0(â…g!9àÁ°Ù%†.a? ¿D6¥~› âÈ`?¹Å4yrá–ÈÏ£RÁ†Ôä÷ 8gt;å"¹5–O#¨D9Ž UNž¶ÐÜ3ò­¬y£3Ü{}d°^Ì ðÏx\cQàkíléà(Fˆlj|0ìü²>¡àƒÈ´?ýXŠÒ © âEã‚ëiÎÂîààü#ß0¢À]3QÖ¢sƒýÂ-ÊæÍ13Â!Ÿ77öh|ú>7%BÂ.à}FXñérÿÔBr “JTƒ4ãŸ4^$;iМ0áÿç'!_Ș*BâµÞ»þhË’NœýhD‰#ðNyrÀþ1¿¶ ¹D`Q”Bäƒí|­O~ðAðï$4A42`?j#ƒfx€*.d.hJ\ê©û ViRlEÔÂÁ’2ã‚ì£<ãSâ+FΪÒ9"/–• ²Ò4¦9b6N=qåæ'…ñd›n­ š{DèGÅA¡?â‡_‹„¨ÑA㔘ϗvv"ó%cï>Ñ+;_©* |Fùç–ï[)ãîAkœˆüÔLÆs[,äû¥û(+ ðŸ£|p!yU>¸Ø«U".œ¬WÙ­B(®›‹(&ŽUù YÀ¯ŽÂ]Ý‚ý}B`¢O¦‰yËxkÆ&iadñ¿ñA3LÄÑœ5 Eþß&„e ÍÂ9t×Íøú#d…òÉ)]nžÊ|iöhy˜Èa0.Q~}°ð`„|ÝŒº5 è®ó¾RW!ܵ^À/˜B¾häj×ï› Ù.°œ²&±ºX(œ÷&jÿ=Ê™ŽfvÏ—vD–Ô'_ãÙõ›mvëƒ Û7KÄõñûIL– ¦;X"Äç™É…7 ”7ä\£Dú'󖜿;MÜ8õPé`o¢qg« ÿ\J;Ï ­@¸¸ƒ¶†¡)ÂŃðAF˜^Ni€°ò ØûõÁ̧·vß'#Ûùx6[¾X˜ØlÚòݱm· Âüú¾ùÁ1›pß6âæƒb‘ÝŠÏè'„€Òt#»ß¶!àÓe„€^ˆFøR(Y›¾4áîy|€?•²§É½[¬CT#mðÞÉè #¥ƒ=‡»WÂÄi,¢œGüGkpŽiÙ½ÕO¾h·m#ë > ƒÿ¢4qÎÙ­¯Q…öæÀyGê1:ÀöÅÚ~û…FpüR#ÖY)#pᬌ€•2jÞ”VÔ=iTã ¡rOІaf1ÛOB˜xû¢Îk!Fš.Æ¿oF³{”'f÷Ô—ÆMt뉇YŸìïªØÀÂ!./‚ýŒð7d„³WvnßÔ@•ãßõŠédk äßpÙMcæ”ì gÌg䃩òOe«á¾¦S>(²œ=‹¦ƒôÔ ÇÑÖ.¬Éñ`H7'[3}àŸzòÜÛy wE·ÎXÔ8ÄýÂÎG£ìq¼>Èó6E°(&ö>³«F6ã6>Ȇ‰K¡?ÀBÖʃ|Ô¸âwLé Jª<˜y7®tÀÛ)¡~²•¶ ¶Ôò'ÖVàŸQ>HÑ­>HWçŒÔýG|p4ö©XBÍùB.¦¦S,$ØûÛgKɄͭ3ÂZˆòD‘¿ñÆEË@ÿob€ä'TqLûQ’æd}ð,² éX8ÌÌΚ""ÐêœTÏ¿\ÆXð9iÎûGÏs“îŽò'›(f‹õ½±PÅíI–±}³p÷h„²>‹£L,Þq:çÎÏŽ!ÓÁX(Ù^þ͉âóåϾH;ÿä:BÀæVaÆŸÜ'hu¨|°pœÞÛ„,YÒyãÉñžî^d.4|°ãÂ'7I–çæ†Ÿu[9âªÐ»'„¨PÜy9n„À©ŽÊ¬ÿµ‰"+Ñm¤˜IXBX¿Pl±LÕv!JŽóª”VŽ¢R B²?ØŸ1‹9Ýý¸h§”ŠÀFN$¶†áõHqʶ‰'Ç×!0¡¾ß.ð:ñ¯&¬*± B4UÞÎÂ)mÇýùû;>°™">]FóÌÉ Ê¬Í1FÈî[•x’‘êÊ©?5ŠóÔ´ ksð\,F¬Fô†á,2Ç…7Bʸ1ëÄýufã”­Ï1¶ Ãóh®`¶y_µ|×Ñ3gòÚ!4û CqåˆF ŸI)„uBèà<Õ5Ëyéˆ[b› 4î‰9¦mǧ]¡‰]ØÙ˜ÇŽšòÙó¸ ë !,Ó¾pJ#wxjˆ‚;3#„åuÏ0eÿÄ“}7°µýU"à÷K¯š>¸-¦­Ù1D>àrίž››¦È'ޝ$ß'¬z”.öÐ:>È' ëÓ}³Ø047ÏÈóÊ9”©Ø7.8w3„ ?x|U«#»!àÜÄ/!„i¿li·À1J¹W Å)Û'ž#®Ó¬Wh –› ¾±ý£áiü¤ƒµÈaÙØ•܇Å#öáJüp)ð|ÁØ`.Ö ߥ¼}𜒦ÉÉù I–N1ýÁÛ´ð@Ö˃Â×ÃÚ/ðќ֙ æì¶¾žøhkqî¦Æ>1ú#-_|.þaZc¦z°¶Ì¸ »'²±È'ƒƒ¬=`YØ.xFåe{¤çoz·OÌ\€cq« ò¹s£=XÄZ$;”m†† 8SHK¬À´4àApÁxph¶ÒÁÄ‚¡¶b2w¤%ÑA4P<٩Šƒê¼±Ú56jåÛV #à×Çì ¯õYÕW Euù ;­?Z»ƒïcÞv?ÀGÔö ¹QÀ‘ˆ/D6à¡€²ÁZ(‘xŠó¾ ¾‘ºU8.¼!´6È“Äm@»L¯O¦lžø¨ï#8ce}£*qe…sOf” š3¦»¢œù@ë}6àjÙ[…f­wŒ3ß#ÊØ Y+l+ùk§P- ó¼›Á2q.šû Äо²Ô©Ï|}˧󉯿Ú)Ù9q¾¨À¬8`— ¥¬O­8ØÒš±pNDŠó1bEE*SߊsìœãÙÂÚ©îøÕ0BÀòéý9"Ÿÿ›‰KKcÖ–#4‹FüÛLwÐ.dFÀE­Ö‘æ„ö¥a„&•©ÐpŒ·· øIX}À=¢¶ yÏ8­SÚ3ΉÈ`¦SÆÂiÔE‰€»È¬‘ FÀîØ.3!ìM…Û…‹Ô÷gëΖ¬ÛØt yxPø¨I,+æq øTÈð`d©’µ Ü&©H[»rÆÃl=[¸¨ÃŒX%bFª9Š%’AöMćÍlPÚïdÀ§!:HDuš—w]5r–†•ÙiÄgËPŠÕ+ü¨ p¾ßg˜î³ÄœâŠ%5 ÅSÌeb‘„°Au²À‚i[2â KÙ`Á'À=°Ì÷â ³ ;ÍóàH' Ù7‘ ¹­8h4HNŒª3O3L}€_x-†/¬òm|ÀA[–âšSÚ¾ãâ_ÑA¼rñ;htФ2ܓپ±àƒ»¤‰<t>È GFé'g™ØþLaá]õOBX¾Î“ÿÔÛûFnümßX,ubf #¬ÅiãÆUª2Âüm¹ÎX»þÍnŠ”õH¦ZNÛk9ÒøÏåHm„€°ùE‘P…åûXð›ltÀ“B¥¬Óþ†Ø,Yè Ú§>snpnâZ$\"+`}ndo™ªÀ…Ø,,Ø..¡ß^IALÇÐt {sÅ”«ƒ=¥»?ÚC>Q²ÑA‘Õ8âTÓöŒX­#œO¬(p~å{Æœî~¯/ÆÂ[ýªMtÀÁ5J9_JÍáÂmfÊÑiá-«Š­~w|Ë5H|ûgšÄ|¶ð¨Šò ï°}¶±A17ˆ±îË‚o‰V\Ax§ýO–?ZuPhæ‹XU e+ev§°â ޳ujj¥OŸ ø«eLPøà_öQiPô Yp°ñ`áýQ¬XƒéJ¯œ” Ö…ÿGJ…q*"Ùø€WÇôov2ÈÖ©8¼RëÔF€TŒ –÷cVà¿ç'<@ø…ÿ#k¸?ÔÂ÷¸ÂËc@™ÜG|P,ŠÁÁ†ñß´ ¼0Ú€ãy§õˆk§¾üïóþ–•ð”E »ÄKX¥T`¿¡t°7ö'_©( "Jé Æ|àŒ?·W$µÁÊÓç¿* šcÆì„´â7ÇKƒ‚¢×Á±ò™¢u ™ –©hØÔr›€R‚·ã ›DN;zÛT}ãKk£‚ì„4ó/ùWeÕCöM}Zºä6!œ6…©ú‚íˆY™|ð]€’r8Ü”ÆÆÓÑ÷g¬Ÿüà’± ö/Ò k“—+Á”£áŸyó²ùQpܘj“é ÿö‘—¸:BäRÆÕG9»™íð”ø#õÒE~Úœ ÷•Öæ>Æêlm„€cQ/ðÏLMÓo¥ÐˆöÕPFøÅðò ž*8W1)bE,"q½A6Vg{pÐL1~P”)4 Lœ“itPÜ5G¹Á4N_Øÿ˜úGµÆ(´¹A8c ßÔ»aƒé ð÷ÙG!N7iXÐïl{ÎÌ52À‹n#¼Ö2ÈÊ| âTÀŠ£‚bf€ï£0Æ‘Ï㜠¢ò™w‹ëÙ ¤‰ƒ»~RÁ² £Ló~w¬0(fÅÈà;çãÄÆ{:« ¸Ñ2&ÈDÐTw37ÓÃètŒXàÈ›„¸Yd³Jß&UÁ<Œ|`f£03xNsPA”1È?ñ:É7Êߊ½Wdïüü@¡(.v×v±”¹à6—T,åŒ ð¦µÁÍ‹‘ÎÕß·Eäsy»_dCdåƒå䯘ê9pDù×læ„ùÉéý ÆxÍ<ç\ðEo‹ ²Ú9ð€æÝ÷mÆwBÙàÛþÄûEün°]–’ÁÂ_-Ý)`i¥lÀúGl· ÷@Vd!âó¶w•G'.¾,k£‚•¾&Dl<Ðòà€oó~RÁÌi§ï׈sËXAì™ðˆ}:´O`«Ô3–°ºWSÄ IÎjœó(ÌcZ,êqÁø¬ Uò-ÔŸ‹…âxñ6“Ôì{ô ƒ|³´ãiKšÅBÌT8ø¶ŒÑ÷h¾’løà K&\ÙcT&Ïlòò¾M*þTZ 4¹¹fæ¯npfⓃBŠ8³"]ë4Î2Fx19þ§ÂqFâñTÆbrÀb)[,àŠçbئÂì$²Á„ݳg°l€¨Q6à ËL“Ù`×êÞY}ÐØ ÅÍÂQ´ lôö=óˆ]›,ïz±XÈÆG'~3ôœyÅm›z&ïÅ93?’~͹`øÌ{E9¡×F8yq.ÈBD|f}Éx“qjôv¤&w6(|°yv2ˆ\À"rçT …¾Fʨ3ß#,x” 5 䴥ǟ)$ÅÉÒ€=’9ñ¬ÓÅE—¥)äº`@ÞQ.˜^Œ þCùz1ê 6&7§6¤6´Bp€åâ'\À~øÊ|¤•ACȃNyÁ¸äÉA³_9éÔÈ™ç]ýÑ—­&8(tÉl)¦d€»³KnÈëEd6À•ŒÖ#»‚øz1g)°»®‘ÁöBoð6È–GÑq®ÔG3ΰ °xõÊà®?OÛ.ÆÊ`ãpDwK.<°~µûEþ^ ¼„´Ò€£Øp}¡|ð}5þ‚¢)âÁ{î|pž¬àý„ð—슃{è`À=®qrðxmòä€=‹ŒrHó…UæO6Øxëð“ ¦­p‘a™¬yr0`Ë¡d€åž²ÁМ4GWĉe~²ÁМ4óœZÙ`Eá6x€oÁ/üO6öõ ³” v\Ø)`/dð€þŠ ÒFá8WR<¾íÅJ¡!ƒ"±}ÅÆø#2ˆcÄ…•bJþðFøÝ12hŒbipÅn}Â…ØUÈ€í>” °zW.ÀrY¸ q=Â\˜`þ¨Ãȇ Vä©Á¼á@I©€·³BOcùÈ9¬ýQ4…™Áö?Ò‘WLNŽ}¥Œ ØNò&ÀºÊ¨à®ÂÐä(dåÑÊv¤F¸«s*Ȳäñ)\°r'a][ž+°nÛÈJQx„?¸OÓÈ`â á‚cÆ ˆU,¸R.ˆû„_¥‚ç¬à‚<@\SªÊƒ›æWŽˆÿaƒt£ðèÃÌàÑ#4÷‹ …¿ÁŠ­õ'dPŒ °P.àà ãü Ì'Ö;¦BDØ(4óÃq,TˆìZúnapu°+dÀ’>·JNl°áêBØ`fù¥²ÁŒƒHeƒ%M?÷‰Ì#t°M|„ft×’oúö¼«{!Jþ¤…cÇÇè'ꨚ-~û>¡‚¢CˆÓ‚åÄ›2Á’«‚ùD7eÏPˆD°¢”ê׸€%ïZ°HL™¿Ê¸lx\€ƒa‚gÚ#E0²œV˜€Õ¿Êl9#L°L\4é´€OÔ„ X ªTðõþŠ ’ÐàØ±ŽùI;sÛ'\P¨‘Wüv}Bl}­²#|µ0‹CfÞyyaÏV¼T>à!¤WÕ ç‰¤éáƒâôç¸V$ âÄaÂ=Ï3¤»ÅíÉ·ÉÓ`XÖ† p jT€*Ø£9Z!lÞ¥LÀ)<tôWyUpWQý V6§R˜Šh¥loRÑKš­,Èw Ó×y¢LÃŒ[1ÀÚUyPå³1@Ã}³2A48†Fq4±òÒê‚ 8zŽí±/T2xîe3pò²~ç• ö!õÑñè8p’©=BcŒÚÐ/0}`p!ŒÙðhe·%žÜ!àÈ·Šù™] e‘À¥ƒòÁÅTA»ìILa€¿Bf—d¼Ãq2HWÌSŽSÖ&N…Oq|§¦‡Ïaþþ„ Ö£!ƒ"u±Ø)îûœÔÈCºM¸(ÜÔ# d˜à6¹ö…Îyv¸ã+kL€jmcÛ›MrÔ"o…öpzú¹f.X w6ó~[`Pãì? Ý$¬øs2È]‹” xƒ©ƒ±8`ØÃV ølIn4¤p¥ãHY*F‹ÁOü@}dpàWùíÐÅ•R|—Pˆ‘qÕnvGøåÑ^tãƒeÄrÆ4œ­«|òÙŸ­B0=½],ñ†ysÔ±!,Á´U`',¯r>û°³¶D· (cQB˜âéb4Cõ#æ,3hWDPÃiŽG¨á7™Ïœ”.|a­>àØ\äÝb!^\êàfCİ\\Ï“@^ äó„µpL´òÁÙÈŽÐiÛ—‹ìIxíŸ-ín*XµååÁ]ƒ|j²qã­ƒ ÙQNUÙxL(ýB1Hœ/F’Z ÏùmB®rÂÈî.Ɖ XÚ¥µ‡~›Ð Z£Îì_ebät™ðTáÇð¶§ÁZ öWTw ;þ[¬U¸iˆ¸ác䣃{¨€µ÷¬ŽÞy¹Ð Ù,u¿æÂG¾Ršžmo¶:âE¹1Âæ'¬EèâÅŽ+ è¯.ñ³°>¡˜"ÎøÛJ ´.qý¯uÁÆ–>žÏžþž• †åõà`ügNw‹'Ýþdƒ qÉG§ …ñ&=r±Qh,Ó—½Ð#/ùˆùAÙûlϦ\›:,\a(à¨ÿÝ>aåµ±òAex„ʬŸ|0rš…ô •÷¯„}ÅÌÏþâÇAâºò]9!æ …Jp0„[¥1[!øFþ¤ƒ‹ ¢è€77~ªt“§Á€öJog´/ìˆa|€?¼+é‡7>È^ˆìLb|08ÿÉÓÓ÷–ú€M}„š°“«°ÁÀ5(SÞÞ(ðq¨ † e.æ„ Füö„%㘽Ë¢Ÿt°Üv¸È¿@§ƒ»Î•PAèåAdŽ•76ÈŒ3[Ö¸©AT íûhþ¤ƒ¸Ü9dÒˆí±Ò"Pé? §ƒ$EÙ;â''«+mŠÈwZ­æO>ØXP,|ðø²²@KLjx¡|0 y <ãDÑjòÁ|[·0†ˆ,žyŸV>ÑöóÅ(;˜7ì•ØZÃ!ËŽ‘ ´Õ׀ϚŒfܘ(!l¬ÅySw°\d(!í~^B¶ýB#ßmÍù`:±.>¸0³øÁçy1÷õáAbƒeGä¬û{…¸TXpb©lÐ"Vl€…®{œÜÕ¾ž8œr““èyt1¡76ÀGÔØ¿_v§€Zhkr·0>]—“ê`ºðH04üª*eT9Äá[ü Ì|·jl€Í‹•¼”:Øq¾'åÁ0aéh|UH g?(!|Þ¿"„xøà°ì'!Lwi›%#Îé?h .È•ÁŽïˆW1béÁyÈöþʼ‚5.ØÙò\¹`eà ­ â±ÂZ„±8|q.H¤qJŠÄõ˜Î"€qBq‘qt) §(léÕï0.œÿm\°½>b³[òƒ ’¹ÁE¾ì'“Dœw»â=£ƒ•1Œ >`³òAtN4 Í cö<Љk2¸HìQ2àÍ»yŒˆ ¿‘AsÐ\°‚F+ƒ¿<ÆX $«“'`-Âx¡ÇP2àCvíRŽÂö™ œ„h›ÀUÕßxqG÷ÑРØ1â·K©€…bÞ&SĦ4àVÿM3ÄçÜkëøÈßÒÖ’úèQDŸ“a.òÙ1_Û„ªò Ët§äì†8r—)SÄÿÌO28ŽÂ)y\óR!6C|•¾ø:ˆŠþ{´0(LÓ+6ÀOÁW w±Ù76à\Eeƒ"˜™#$œ ò‘]åÍ ‘÷NXîÙN_H jÏÎ4ÐÁþ ŒÂ)¹˜!rC¦tÀ“)£df[2"­(ðHEè``3n¥|LŒ ²Qòz„C…ñŸ1®øWc3ƒ»|Ó+£ä{ÌNž¢õ‚²â  \c!ã4ÚåR¡8(:…•ÏÑ” Ø}ñÝ… ¿ëŠC…ûkaþ#Â#“‚D>fP6Xqìù“ ¿žB<³}Ð[C)|_h¾¢ƒxÈÈ?“5 7Í7<±fá2xšb%2˜yÂc‚„Ÿ‘Nÿ\p[…“h6E,È ;"> >¥YübÚ.®üÕ°íbE‰ ÖÜ(l{±]\xA¦\€O±rÁ‘ÄÉçóŠ£hðPÈÔøg|¿ø:–y,Ü’y€o\pÓãV˜"ÞæŽog6£P.˜9“M¹ »¦ÏÅ ãXL ^D),|™c}ÂXA´;Y¹¸²±AÕ'¤XæqÅm²ÁvKYl0ÏøgTŒ8Ä⃠²ßɸ¢*ÛÙ *“½qÒ"f·d–k£pÓ>aCÿYŸç3w@F(òÒ P&ãuŠ•1˜y[Ù\]é`> eòÖÜ0â§¡ZÎ 1­Á=t€’F¥ƒµX),øð[qÀ‡.RœÉ íIX@(Dëtþ+|‡¿â‚(4ÀvW©€Í!>ÉZk”wu …Ö§_J<²óÊ ÐåÊ€ê• FÎM²6ïR ¸Ü³…B>ZÂ1šM©A2?Y’&LpqGd…›÷ha€®ÔZ°ºYˆãª,” Ø3Å ƒ,4Ø#äFüš$ù6.(懷™¤6:ƒì|´ìEÒÚÒXä‹¥‹p q:9±áõº€÷¸63Àuž‘bËÈ ]0DŒ Æ-oŽjvXø¦/Y޼³€Sˆ ÉSùC0"ÀêÕV s¢‚!Þ.²ËÐO*oËSÙð«îTp“ Ú€¼ãT'#¶è.4(¨ yqmy*ð|ÌeæˆØT¬’µ*À?òv0ãÕTX|™ä¿„¦2@&µEös?É`Û¿ð ÉÖŠXÙ^AaeÁ™öŠÙ+™Ýz´G¸mxˆ-³[Ýsœ° ¨!ðyA QX&Žp·½bÁÙ*¹r@kôÈcClçîó‚4>¼ˆ¸W:`£ã÷ù Uø`Ç<>yQn|—  "ó‚çàªàƒhl°°RCùà{ô÷вÎ'áÊØê¤;jøà&KÄìˆ8sP˜›Åb¡2h‹9ƒuåÌΟlðoþlNgŸ8rÌFyzÈ—ûÂ{%HŽ­{à¨Ì€sÕÍ÷(sNlvˆ_A›"¿Ûì0—¬eW*XB¾ÒX˜%sRoËf/®˜qŸúg«„·¶1_(à¨×ç‡y•0²Ã™™%Ç™ÁsˆûPÏ[+Ø ¸bf—/eúý¸­A´9Ùò*áà+x›à¯Ù5GQ¸³\VæSöFÙàR§¸V6øþÿ¼bƒ¼˜ç‡L¥ŸÔÿ5.ØØ‰ô}.àÛcâ;âãÃxÃüàÿÜ',,Pù#.HÓÃ…SiÞgüÉ… 8P Æ¡HXbÛoÝ$ º!r–Ÿ)¡ ‹°µLkR ñ`qÃÁ×–xÊËMz£•§òÆXz¹õYf‚o›<"ÈáJÃ×Ä'Zï;¦³÷'Ì,†ôñaã„·Šìw ú‚¡‰c.´‡Ùu_°µ¥"Ž!­((‚™v„ –}‰UA ƒ§^DÁÑŒ¯¬’Gš`…a=B¬ –‹`.%ƒ™Ól->ßbF.ÂÃýÊ”ÿ].Øîí'ìÛ­†q¶,jzÆÿõ2àšú'¬ûÚTjeƒ•æoaù+.(Η³öY>à‚ÂÍ€e÷ŸpA. f¾-µûev<ÐʧZFøï±6‰ÐØ Ûü˹Q˜ñesÁQRÎ,|°F>Ô·­M†¸IØOþ«l¯ˆ’Jó@Ä—D*ƒQ‘\¤üš#jcy†Jw- ¾cÈ_ÐAvDñuüIÃ} íÿÅ6“ç ðk¡l0ã¸ÎJI)¨{{7‡u¹¬l£¬d€4ç™Ìi¯Xô 'çÖ¼+Eø²VÈ`š‹ù!Ûÿ ðýŒÁ·?É`Ù¾PBl)¬9ZiÙp[ªµÁ–Ú„)îù{üƒ ŽKÁO¨ _+rô×GTÕ‡Ó_ðFB©€} Š(\ßZ]€›QÁȯ¬u ™ †8?dÓc‚b‘m æ <úüH+ow• ü<• 8{é'̶ʉ„ üb(|½¢‚xº<#f” nìø2:ÜC;VUF9fmfY¾UDyÁ£øÏó‚l•Àá'ÎY‰ÌöæJlá#\€µq–ÿÊ1Ee¿8n6.È6Ó†GÉÊ;âSª‚õ ?« ›tüí(ìkd—ô$íîŠfgï0Üd„Š3"ç‚x”0¯Øyà–ÀÙ€¾Ê&6âm³°Á…‘º±ÁQ°ßO:$ûé¹K`YáÛ¥‹„.¸[é€tp‰¢óCÎΑùá|aó ÉìYepq'g¥AžD½ÏVe™pWaÐLoÚ$ ƒ9äEÂʉFy“pà/ÑÖŠYy¸ðF›„ A³’A‘Ÿ2DòóiËdШDéáÀ—µJÅbqÝsÂZE|5%dpqoµ^¬8Ä+¥yŸ#ämBœkM?™à×Âùঙæâ‘Ò|à¢ÀøkÏ– G¬DLtÄs¥¬Œ”ø GÝé3}{µxD™ÁþMÑ)à¥lÀÙiÊÌÌÆøuöxµb™€Ì£Ë„õL­Â˜”iâxn3AÅ騻.Ë.M|Ø\%à·ÐÈK KÀ>_Ø€C 8ÿBÉ ;"/C® ²;zl&voûˆ ²Ã”?) M]ˆœÍΆ¢C˜ñ™ý 4ÀŸËŽ”šyÁE®u|lbt—'.ÞYŒÃCÖk©ôp+*6v5%2]É`ŽçŠÛÐÄ­2 ÐEÙ`Òð°qAM›„›êü#Å9Tí"F™`eq¢(vȸ}ûÁ&ŒÖ#pÄÆ"Îç48_-ó°5 øÊšÚ¨hn¹[ñ—¬÷IÅNqã%‹Ý'á7Þ,Pñ—#÷I3¯ªÜ=ÁŠË»U|™òø¯8\NjwÑV9Æ8ºý¤=À# Wf/ä•=”ð³ôø¤ÌÙýÂ.Ù ¶ø7(²Y·¯<€F ÊØB(¬8!RÀæ\y`m¦†…êÀ_½ZÆ×ÓLÎðÛlWËø3"@íµõûkg£çárô2IÛÄ…¡Ÿ–¶FX´þMÒjE|³æÅ¡"ŽÏŒ pnÎè1[ñQì{!/8ŠÌ”1z Î_ø¿Q:@ s:Hl0ecô•mo½*ˆd0²a¦¸™$&عä´Þ ›ñ‰€Áy Ê 8NK‰àïÓ•çKæi„KüüÍ U¾ÓFÜ? S¤%ð»zÆ)Áƒ66b²¢·>MË:­((††|i <€â µ>­††,¯R"ˆ40à?ؘ Ç&5F&~ß­$ùªCaоáw]©?ʸ`C•‘jþÆyb»wËG¸­&ÈdÀ€P6¸X>9p#¡5nFܽ ­fþÂ뤠X `ªbXmÑÏ‚ &þ>k‡€¹v±*‹³¤qeËjs8ËgIû˜Î’²óéŽc(%ƒ{‚“Ö/öÆv2¸‰ pÒò>4rÃÊø4oX]kÛ쟌 Ö ³4¥,ÓÞõ=m¨€½:|}¹€“Î eάܺ :™ìlOol½ ÆmëŒ ¢%ú<Ç#Å!)ò±ÕO6XoŠ^À¸ñ>½gZ° 8ÙñiAL^_G„YŸâzÀØgl¾L,l›Â`ÆÝØ€/wß X½XÈZeP¤'!ü4 !ú»z;]Îm´Oà;Oq<¼pÇ0óÓ,4Zgü¹ì.ixíxø`ƒx§}Wî >"ƒ"—±õ …æóÍ™-R• ðûõ~Ž÷m“ÀÂu+öbjÀcc›à³n«„|‹Ð؜᫤ÅBK‡U£Pd$ 8¨´±A SÛ÷*_5K5a¾Lš¢î°°EÇßò²ò|ÀN˜^ÜÆr®>X°\Åbn€§“ºK`ë”7eÈ:Xv,WŒšÍbÌ1cõÉÅÜ€ ñm—´FǺ66gÅÜ`b—<¡.Á¤:?d†…ÑN¬:HƒlŽ~ààJÙ€mp>¨ðÁöhÅ[È`e}¿§'ÅÅâ£Z.BV±\v2È"ä£ ¾922X9»ÓfˆMÈj–¡ŠÝZ…b¯˜ ,fÖÄå&hud³G%ä\%ƒ-'._ÅÉ(ð%º¶ HËJë˹Ápþ3Å•ó’NY¶ùÁz±¨ nò3áŠÑ¸¿]V4ËÅbj€ ™QAžÄö¿¸ ˆRÛ› „|¦ˆ¯µRqzŸ¹`Ä!9—Ó¸ ç$p ¤Õy»¸ñ\Ê6 ŵ›¶PX^nŸTùÎߨࣳõ‹ á• ð»þѱIR‹ÇIìOìÄLø¥øÙ"dh¶ŠËÌ~Êo_"LÈÉ6<ÌdΆs *}Wk´ÍøÍ1çS¾³Ó’¿ÈÊ + ð߬<À;+ ðÿc·¯mÑŸDÏÙâo>At"¸k\€™1²­2·,FEƒ€…•N f¼²;Eœ(Lv#Fìügt}9*L„ÂÈÿÅÆ´5ÔaG޳¢ dåá9Æ¢à¸"˜øÿ.%ƒÁå–‡/å‡O2È2¤R»k±¸ «`UúQYuÈÝì°Ò…~1lvˆ­·9 âßåt°c+ktÀµ² 3d~þ´I¨lÎ '¶bz–p Û|ª³„(::&&I“p\è3µ8hv ˆåƒïÌW|…‰v!ùd^€và¯ï¯èm%MhPŒ ˜ß½O(FxÖm¨ ð‚ÖØ ùIìð©dФ-GÿS¿êÀ`Æ6Ô:…ly8óY•é ðá’â`¿p„T2(n”朾>ÏÛËU“ ò*þ)Ú(ܦGÆFËj|°>!\˜:Äü¤uEôy£öý³N!ë üZ Õà[lË[ÆOÃâ“ ™A#HŽöFã„3 Œè枇¹UÈ'õ~°Á8 G“¹<³®Tè`ŨGËVœbmƒV‹%Ö§|2AÌþFœÿù‘ΠÐ$gÙÑPÌ &Þûýr>O`͟п~^°hƲŠS¥ÀcVNÛT.ÀÌÉààòAÈ Q!ãÿFÉ k pþøþ´ û¢/|¶m\ËNõ1ËCÜ;Zð:öFJ…/ú:à…‰µ‘ âµ"o¬UbÀ OÆÞè¦âˆÚtç‚ÂÊ 8Oš±­ñbL[>9ÒT×c#@œ',– x=¤d€ßæ·­ùžóýèu|B5&aÞ‹$5ü"š™îw•ØJÊ­MPŸ©±Š™Füçxm¦‡…2nSµ6`áêµÂØùàϳmDí‰ñAam’s¥DŽãÃèºàøì—¼€í Š¡LA½¤'5LSÔfl4:‰‡ûV`óm•*OÌac‹ü÷Xe€[<« n™f;d|Bt^€?Ñ' ÈýƸxûˆ Š.+wë°m1.À:Ø»„èrt°üÜ6ŠÅôpºØ7d6ˆú‚ñÂéS&M“¹`<",lH¨\À ‹QËò‚}Ä/³pÁ3$rçg+àŸQ.XbQµRŽ­n¢ àaó'³Clu½GÈÚަ7&(x ÒÀ““º%£Rž# ‚ÂÊHo¦:¼%ZuDͪnvìDœ2 Ñ ò@È Ëêœ æfn˜ 8ùÚ˜ ÷{56Œ§I >Õ½^PÁ†„k=B® Öœžt^Q+4eއ¬,Ø__)…':çw™ÿiu›TÌ ŠÈeÔr}TDû‚±HOZû£:dÞ½™ÅY>GØo ­G(–Šø†Ú9BQTtϸLQ—³½âÈÊØUhJœ/ƒ•ïúŒò?” ¾J_±AÒ¬oT6`‹¸Ø_b§ƒ»®“Š&!-o|$fl€ÿæ,µ…sÒÞô8;¾=r…A±R,âR8,ì/Ú–hxÒ†ëz¿MÊæès²6zαœQ“3O»™I¾HX2”Ö°R<²ÿé9àüõ'l_øc; †Ê…"ƒîè áƒØ)lŸ-(à[ì|{…\ð®ÐØ`ÃYˆ±A12À­¶‘Aäþ¡>ÆÂ`e?|çüž*à^¹€ùB¹`åLjÝ(bmå~‡1WqZ‚öðÁq£8àj\pW£Ðä*ÞågÒ¨¢òEv³oãqw¼¶Uä@uÈÑíðA)LB -duÞh Œ|ýÁü0†'-|´adÏfîÒ­0Èæ§ÏˆªLh†`dµ‡Ó¾D2ˆWËgÔ®_wí°>ó6á.!rN`9 Ô— E¬bq¡T\%ìly¥:äb™°ìµm…AnVd;UÌ›Eþß¼ït–GˆÛ ¸¹‰UÄoÎñã2™Aq¥Ä#•÷W‹Ë§ñr™åò?Ù`¿M‰¼4ÊûtVÔBÕú1ß+ò½+£ïáÁÓ$m¢ÕÙƒfÖ±hqÀéB~™Mh/;ƒLXªèFaÃOTé€åŒðµbÔž'k[ív™7Á:5À‡ËUGq¥”瀃+¥°7:àÑ‚ÒþœnÚ) |Œntˆcq¦ÄŠù¤,3V­~w¼<àÿ‘ð'E[yPh °Eü„²á~¤Ú,°©¯ñA“ª–v û•q“v O¦Œ²Ú`Å?cÍÂðÚØäÈF¨çˆoÿO>8y‰d|À"^ÍÂ]A llktUˆ~• 8ÔÂØ‡WnŠœ.^pV£ÐwÙVàÿGéq£t€OÅÛÕ›gª&yó 33ª²_M ŒÞ} ŒOØÈ|ƒ¤t°c§d¡jGêÆtÄ|F›£³:N¨Ø (°ý_äOÊ” f ¥9äû~¯ß_1nC- .ÈsDlíl©p àÏ­T° ^Ö¨€W_B+>úJ¸Ãu&ÀºÒ˜ ‡%¬6–¨6E&HÌççOÁKÑ(°Ë®Ž±éõ•Â]ùЏË|¿QÀݨ¿;ïk|jÞ¶E~T¤¢\€o7 ¹O(Èà6˜ñÑÒ㈿cƒB“ÌaÇÚ&¨UQ:˜ ±ÁÄ2smVl‘ ¢Ø€ [´0à‚ÒÇ(ö´c$ƒ ¿¢‘AÑ&dcämÅ‚Çû„¸T¨9áGÙ€eÛÆëÌí:F,– X9)`A­+F„ñûlŽmÁŸÛeÉ™ øNÆkƒ˜ð`ƒ£qC°ö´â-ñ¼MHSÄh”~(¤Öâ€SwÞŸ"6ˆ·ÁÊ>Äï“A“®È¡W¾QÈCî´” 6Ís2(Ž2Àòý#…;¸`Äõ†pÁxàa×JloÒ£Èg¹ÁVD,òõŠ-²íÙôÍùŠ âBOü´2hRÕš‘›yipWªkÉ” °É´ÒA^ûE$B“!!‹ø½øE쟬ÎÈHOnkÙ O Æû±÷k”ïš,ç[¦>âIk6Ö¶bSàgj|À—ÖØÞhm0±UH÷‹'ºuÈæŸÔø?ò ã]„€=Ðû„€m/½AÌSªV SclPBs°TÅÊ;Þ·©`@ 6Õ<~Ź4ÀzÐJÜÿÛnµZìÅ ?®DÌbƒsLJÄ!ß/¢û£Ê’»,Q±¶òíâ=ºä••!Fœˆ Ú£³d¿£Æñ‘• 83ι€Õ†ˆ…C2R†¹ æ3œ‡¿ÉãÉ®Åâ‰zò§e|Àn°Ê97áä„,僽<~ðÁøô§*.ñªÞÄSDÇô“­„ulÐXŸñ)Ãû†é8·ú„šõ"þ£­2h–Šf\øY§Àš4U&7ÉÕÜàbçnt;…è‚8ŽU{.òNa<ð¯r±A±Sà…””+Å•Îèt2^ÄÒZ£€–6 Þ¤GÑ0ýäØre®®|Ãx`%ò‘0¹X0bn F|mp€ƒXß0æ@ö_s@«ŠƒfÃÈΊFXd˜!b–&ŸÕAs”"1“ýx`¢hšÉAq·t [êä`§ O>(´ÉÊ]m«p&ç£ì‹š''o"9(Ö w¥¯²'±B®Š8ì°ßŸ¸¼yß1}áëgƒlÊoϧ;¼NÆÇ#£Wϳaƒ¦:`ƒmàÛ‡{þЬ±:HWŒç€O¶Ž»ê  T8ÿÑIsYÊK…‘×MJMøjîbøê1sîûÅB—Œ€îgüÿLÆíq­e' øÕ.Xƈ[ÆæÂÓÖžÆlnd|Ð îêðÅv>ˆrħFÈaFH¼JSÖ -KsÈ8íXÓ¸R´ÊóEƒ¬õÁMêiËxN|Ê®„ÀV¤dæýkæu‰²ñù×q~°M¸BXÇ!õ Sà€õ ¸òu>ˆýÂ<áÛ¥|w ÿŽ¢åÉ6ãW^ù`:cO›qèm|М6_ « :¸i¹0áð×é ²Á†WËNÅð Ø<Ù Èdå3eƒ ¡® ðûîÅA²C››áþvÞ/3Fø& llì¡dp`É£dÀáÂJg5Kä}‘ÏÝ” ¾õä¯È JætÍøœ4Nê{líšôµ»f‰=bQ̈c£ƒ¢8À—ĦÈ„f€Ýï‡)`™atcYçÂõdd§烘Ñ<áÖW‡‰üWyqPìâì`ÇOBggãÈ­ÔÛ­Âò-”ÅqµÀ·²¾j,z…çÇ>;(rnkŠYb® Na12(j|’Œ 8—ïíâàØØLÉ&ùš‘¥×VäN¡%ÒŸQ2À/ÁÉDzF|·¥d€n]J'þµ8¸pÜ3:à²v Ø&„ËæÄËf¤8ó@jJ¼åP2À†ÃúBøõ22Èɬۿ[36Fêé|éÉÙM~œ .ô ïË{” póbtÐìéoR}2þÕ!±Ÿ£±Aá¸aÛ«:¤—°ªCš/\a” ðÏøb!3.ÉiÿgLÇÍ'Û³)4*$ŸÚØ»£|H>êŠcFö00:È>U⃆Ü*p æÙ¬ÐS—2àp]ÙçÐÊ{UÐÿÇÎb®ÂÌŸºÑAq»„uˆ±~ÊËêÒmÍȪseƒl¸ÌSš"fužhJ«0T¶'Íà€=`½U¸éz‰Íœðé·f![$ò£äÍBž$²„5 øG”6N6>h\ÑPQñ“ßø|²pà—ãÝL¥ƒ526&äq¶Ž qÚa@ÊTzt#;ñ+Úñkè@¼MZ¶ýuôê^¸¤sÑèSÂâ8éâ.^çøAü“Á–#Ööð6¬³K¢b Ÿ÷5 -s2hDFÃÔ¤¨`×ïä4'\X˜akúÙÕß©ÐDXÖ Ó’Ëj] 8’T¬ÏÍpf©‚?-{Ùã0{²*Ê^v\?;ØùvYõÅ8ás°ßõ²7hÏAË;çâ|ò²çÆ?&ÏL>^éoÅ1"Ÿ´x©Ÿ$…+‡RÚ1"Nêí8ðQ´oø³[ŸÅG¡<³%ÉòF!ÂY¡={’,ã8õØãÕ1Wö&¥û†±Ù™â_öØ sc6 Ò G*Ø W•*ØVõ¼ö+õ3mÒp£O;2¢}Á·ËО}ÌW±˜ÿÅ÷˜j0ù®x>xö¾8xÊŽ#Ëô‘Ç+¸Ç»â¹ÐÅÁűÀÖ¤£âTÖà~Ú›—=’HÇ‘†!›Ez‘|Ölú$ßôg”ã¶ÃÆwYX¼é ò’Šz&œTX¿ ßßÈUø] {äKV9N­Yâ“—økJ8|6ëØÜø“Î*@mÖ‹@ô ?ó@^˜äµÝÁé´óèAºŒbƒ9«öUÒ}…ï9g¸ÐY§eKüT½Ï_ø²A=¶mŠôh8|N>ŸŠtVÔñË£PŸ~ õù ]vžWrìɯPÿþ¾‚z\Ð3oÔ«V‡wZ½ã÷ý Ž"š·wrÇ€šï?é’¬X?ñM²[”ÿÛ ~奯öãȶ¢Ï§>[õBª;â°Ã^u$0…:_)Ô³6o[.Ìêl‘i¯:®Gëç–fðÙ=tA’c½¹ëã "Åz¾úÇ×ø£Ê½zÊ|úgP/Š÷Äc½5ý{­WˆîlB å¨á2˜ß¥ºC@8ÌãõîÁ…ùލ¿èQ?޼2×=Ã|á!m4wÉtæÌùlý¥Ï92>ç<òÒ=®Ô—;-}ÏÙËM~4k¶è+²Š½çsº¼âÞŠ¥²·éÍ].'Ѝ¼¶èÒqLùЋ>ãCéüÒ ;ðéÃÉÁâ*¯-²Ç÷™åÛ¶RoÎôÓÜ}fƒ:ýšëøQ¬óÙƒ•î, R¬³¿“`USŠõÊ“cee£a=¯Ô×8vÏFß ~¶e«nnY‹©XÇ.ꯊ÷ôª¯g‘ ºsEmÅ{“†¯‰b¿*•ËA êýâOÙ³^Ìä|Ì’ã†gïa´zg³IÛ°á‡nå;Ò ßñw#P_–•™RŽ›-­ßsäϲä>.Ôü%Ô›¨`žÞXŸÅ3÷íÓ±Ìðñ{–Åžœø6ÔãŽm±gó ºéóÉòÚ·fxV¤v\…woRÀ? Ž¿dƒz~ÕWö’W¤gMì2äë¸uÿB’íÒyò¢HÇžÌe_ä¶æ<|Ç…‚#½Ù³anHGd9Ôo*àq«à­z|Ô>ºõ‰\ÅŽ¸¸W¬_¼Åo/Úæ…÷îõ ñƒB=Êäš‘þ­~§¿ÇFrX¸…VQ¿ã·Ùê÷bͶ\X ™$6—ïÈ`Öª¯o]¶¦xù¶b¡¢—ow³e;Šä®Û"¿'þ@­U±žÇP\ÂVž9¹|wVOj«^Låf¾3P¤zØ5ÎÞ'î€løž¡ÎŸÝ¼PßYàeõ{tÇzðr~Õϯì‡Ã³}Ó ¯ýïxÂWHWmìÅøÒ o¬â¤í.g,œŸúƒž½p6nÌq]åÖXñ¢mäÁºÖîÅ2}Ì7.󳬌0_pvõ¶“nÖÁ2å+++å~1T›ôçÛ>ùÀ˜°œn”zšê¥k óﻸW0Ï»t§(̱®úÀso\¯îJÔÈMú“‘ ¤ó|þ¤ÇDX,‰3[ä>Úע`š=q¶¸ªÇ6ýx@=ççilkv—y¡¾Žwü¥…üd’w¬õìÂe{m[±5ö·I{¬mö;uÖÖhñÞ„eÜõhßÞÙðüìi5æc6¶ˆ÷G}ä]œ]©7™»¹vÇaˆ=êÑ‘bF×ÇȾtt\$ùáj¾eãÀ-?\ES¤9Nwã«]{ÕÕúéyôŽýˆ"½;eËæuØø£~[—^¼éùIÇÍŽß±Ñ_åOzÓ£Gœ_Äá)Ї£ˆÁàwÖWlY {ô‰-"̉*Þ¬ÎçYD\ðLØ€UïóŒEš>éUầȱòcó¸1>éùŠ ™ÒÊ÷{ªw¾ü+ sÄ¡!½€:®d¼z/žçîXÒñÓr¤³$A‘ÎÚo—ÂæmjñŽû…:~}ê;~êþ¦Æ3 Ô‘êW‹¾éX9Ôãä}ý>À~…ôxˆ\s ¼IòÎÌíÅûMÑVsLÅîŠ÷ëJϲɪ÷ëA[±¡2K±ÎîQõ­X±<~±G=i䞉ºêXàëHß>Éñúßõl;SŒäì~~­æ.Û1ó¡ ¹ÿ¹3zô¼LÇÜ–éPçËtÜcþ€úö(f ·Y,—?Ú¦'{É'Ôã£þ@_¶—ÜðÛãPÏ#9ö0S¨sZº¿ê…–¾M/R-ã:}â<µ¡À—MMgÖ"Ý~/"+Ïâ–-›Îlû ¬~/h½ëßqÃ/°žd›<ëæí êMœõ]çé‡Gïó¶ü®‡Ís96@°ïßÅÈ+°Ç:_ÃØùòé]?ŠØñC÷ËÕ»ÎÔ›f=¹4ù;Öù^ÃGMì4!Ã[ Ïq‚ öãâO)Ø9èOÑOW'öØU´ãÌVv¼9UwXVZzlaIÁï€<ì>p>—Kš'Ø‹e;<8ØÓ>»ÃVΑ\¹sdöb³Î¿åömÚ3Øy#n`Ç¿êmëÈñÌë¶™ÿˆb}ŸŠüGîëÉ}æ¢@¬ÏøXØb=b}™³†fy_dw.…*$}߯Æ;Šu>jP¬cQlXO³¹!Îà³íûȻӷÍgž5|c3u›ûLô\Ã8Fu¤®ïù¢së-Ï% àÝ?€¶m+LbÙlV‘õ™— ‚t–Ò§†ô\ÂÏ'zíÙEþ“éØSÒñt¤ÇvýœÒIÛOÚøîÒ*øJ[Lá±Ðu¤ßu¦Žº‡z~ÔYŸöA»Ž|i<_£)Ö‹G}¹xúßÃ#hÕr3Û¨k·Ž}›vë¬ÝP¨Ï¼ô•Gý•Hºu\Éi³~6ƒ9Þ êº k }Ò÷к±œË§zó¢g˜Wxl&>ò˜*&ðæ\|}°lÃrÚî\ðgW˜³\Óp>^ƒ)΋<Æ-ÚQŒ¬,ÖFñôMÇÿVï.,èÅ^}@¯Û¶šÊb*R›xj©oú>$Mv‰å¿ÇÊw^WعƷF½;þr>;R®9×…±Åµ ªîÞu™bËÃzÔÊ=e”XľÔ† E:§(ÒóM[Þ«3n èù¦m°Ü1YlFúº7Á«(vù{Ö¿ßá½zÜ«³Í¿OäšWË/SÀãn«÷›p^Ìã²—¹ïLÑ¥ãÜÊ¢\¸.œ7 šáÄÇÏ‚‹'}ÇÓ®Ÿ@.¾í:{R¹ñäüÍŸ@Ð-ÎÚ|43Á*Ðy•ä7møvKŠâL½@ú/]†8{g}–‹ån bÜ.(Οô›n]&ä'Ò#ÖÙ¨ØO]KŠœÎÆŠõ­É 1n vÖ<)ØQq¨`çnUuìoìœÐ-`_Gü3öªãHÀo]â±ËtâßåWm뜞l‡êEœú¹ÄF=^µ5:[ º%E:T>7 Ôï2š*Šwü"›%EáH¿w¤ÈÆï{‘Ĉ³?úú´É@?Øgä½ê}à@G›½ÓoGpÎ=‰à|>‹È¦5 †ó¼d›v¬ç[Ћ«6®DìQ½O_ÿ™3ÎqT¤ç«EÖꌽ˜Mä°¾w˜ß4yg£%ÇyŽlñï2 £Êëmë™á(&ïséksê²3*é1Šq(ÎW‹}ú„‹ú´§.ì³ñî’mbÛõž9ÙJÉút1)Òºº¾žÈ­…4/£êé;KétÇV<èøÕúéÍì=Äîì 쎅A,ޱm —ýaÙËDq>ó½‡ÙÉ'm<¤PœãC«8çKl}Ó±ý /|¿c@/òðnËJwÔ±þŠalžôܦ#Sêä}>_äÖ zÂ\qÎôö¦s+/@Çÿ_´Ýµdkr8T ³o°»Éµ;~¿ÌeŠ7ho:A?Î!Ö†ôÒ¸ùÁ·Y7âÚB€¾X¿j¾e §õÚqâ,ø'з/¸*ÐÙ÷È€Ž¤âV÷½1ŽíùÆu—œ“í æùduØñkjNÜÂΛT¶“¯@Ìr†þÌ oBb;dK{ôcÅYÁO¤¯+8»YU;ntæÃˆ5ŒÀ|ÌKô§‰\Æ]‚ÚœÏ{„y¼XeßÀŸ0ß«H6ÎͰš½(Úïò‹ä|]¿Mb™Ç“–»s)4 c] ïù…ºÂ¤qÎ9K̓ ençxiz™¨v?8˜Sžô™u½v°ŠÛI{Ò±&W¬³“>éãEîÑ9OŸô|¾|ïè^a=¬²b½UÆ?¢HÇ‘Ö߸Œq…¾Ñ9”£<ç)³¥¢£<ÈC¸yÌ—ªësš—zóÌ ”§<åʱA0_©d ÷@y4–ÚæåÈÐã<åuŒG­Ì<ŵڃv|Cã;ŠÙ[e2+ÛØZÑŽD†òì)5M\ÖÆgü’Úîß!7„ ¸ÈqÞbÞÏ(Å/¨¼šýر1O©"¤ Eù€DZµol2j(Ï9»º ÈçsIyt‰Þú†%®¿è·=é1ÍáñÅ9ÜÊQ†t|öíIÇï…!=Ç¡nÅÞ¤(sÀ‰e.‘Ìã=ÏÇ,#äæµÞ söþw7Øœå0!»+ιg±‹}Ð ÙëʶLú нzÜŸóž^÷ç,]7 g/X”Æúƒ~W‡Î˜=è åÛTœ¦²ß‹wèùh-oÕø:ÇQ~ÑÇÛò¼ÉaËK5ø½—¢ühÐcÛz.¸®ð=¿æø¯Ñ}Ãr[ô‹CN…y¾M]ÙÏÄâ·×ÖkáùÌŽõæùÌ ›µ³O‰àü@½œý¦#ôè¯iÞ«ñ?Èu2Eîçél·aIlÒ³åsÑœã3l«ó¨„QÝ"(ç¡©ÌÚ§ &Û¨áfܦí¸uS‘ [•̧&‚Hæ s¬m£†taµ%–íqÜ>àpC_óÆX†C9 æÅ úŠ#¤OÊö¨mTí1+}ã×èm™ÌÌ>Ä6qÏïùÅ¡£Â|gGv{йF³=Õí'K%íA¾2ÇŒ?»¼èÛŽ•Å-X_ØEPžtN*¬¿‚õG[œ‡î^’Y‹ŒeXkÖÓŠu¶öÊ= âžEQñ¤ã_öÑv-jâŽÂ,n›ñÀé“⽸MÅ9¸¡=cý˜XZ-³¸‘ÇÓö¬‡ôÖ›¶Ø£s·n×Ndf/ÞóÅOêG^¢S3uç»Sƒ:²®6éß°xõx±ÆÄ¢Ü@³õ©°Âšñ“W=ÛÅÙnb›ùå7 8ÏCwæÅùÀ6áöªO1.}~Ðn‘ׂ«Ez>M}¤E¨GµÌºŸ80±WLêÙ.n8²/äãUçs=}Õ3Ò÷±MR¨Ÿ,o¨_xG*Ô¾D±lUÔñM²[~ÕyÀ P¢ãÄ:±‡°B}â ŠfŠ]zxÓÏs¼øÁèKѨ/ùrm·T½GcÈãÄ[Îgü½Hjá‡í £ „?êñxm=ñ«ãz,àç³°€åûIƒzŽQ~z!Ûtö7¨ã{£PÇ…±B=ZNì'NÊéG1Y dBØ`û€ú‰¢+Áú^ìÙŽ™Åö¨Ç¡Üx¾v†|@=]¯=:‰Ô¨ï\å~$„- ~SÛzp‘fPÇÓ4}Ô‹…ú‚M‡AAc6Rø]V¨çT¦åk¾Ø»k*S‘Õ² ÷•"÷ÜŠtž/è£ÃZž!æ Ôsýž.UŸzr—9Ï…XŠô‰?QE:ÎÊéct—ÒñÚqâ¿W¡Ž'öŸ·`íéP¿G {1ê0¨óª)äò¥*çàú«žÇï»9ÿ„z5•›8CSÃyínPO‘éÛÕ¾é'Ôñ·£o:z~}9ïzÓ}&‘ÃÉŸH?Φ~ŸØöK5ïøØ ÒoÀëüµµ°{±O°é{ñ¨³+˜!¿>}¿Ç1îØU =oÕ‹´NÁx_ »áûhå;»JXùÎ*%EúÚlÕQúò¶ê}N!ÊãE«[u¾þ±¡\q¯Ê-߫ƭúxek/`ßsÖâÓA'>ëÉrùgŠlœklÏz!|Ç6Óý'èÇö¥ú=>°…·劥:~—?нãCk`φϜϠPùÄ ŽG0î™õ\¾³U…ïÑðùQ` žÎ‘ž7m±Sª?²VîK_ =3=žŠx™>M¯Çï Ç¶'f4Ó(bñ³r?©¢~¿ÉPª|Õ³¥ÔVÈgÐ1É_õ`ø<«Ø@·‰‡¾ŠsV6š¯{îÓQüø®ò/lu£>esÈ ÿ+Û¨§C¶ý¹ãˆõqg¥íÙ\~ѧoW‡W@Ï‘(%P óÕ“=?éÍ‹~Szr‡sÎKœï¸ürœ7å{ÉÍWaxõ¶øt­a¯IÅ:¤zXK±S/ŽV³|†UJª”ãVÓä3…¥Ô‚¤«`ß °…ÝÌqäå‹aÍ߃~fÉ.‘ÇOªŸizuÎ2°7C¹»õFÏ¥¹x>³I¼Iås÷ü¨ó¥­JåØzÊ ~‘Û«Pg¡‰•ïÙW Wd u¬Õ%„rê2r:¤Ëß³+½,Å›H5–ØP×õ\¾³ÒKŸõ-œº<žSðP¤óïϦr8Uñ©\qêrSVúzâ«åPÏöî+V±õÂ\ ËSÅ2Bê|cXçLYÃ:ŸsÛ³ží¥Š³¶-¯Ú8ÁîÚöì!Çe˜‚ýÈï3ìhdËUXªbyú"`Ï&rÓº½6…]²¿ÔÉ–)Šu^òåbýÖ)hx æ§.q¿s¶‰§3‹Ø“ùT.ƒßHo×ç®úïμh×ó]?nÚ®#Ñ©_$þM‚õuÇûJó‹,Âx^«)ÊH„æp¯PÇS gÂ;…ú>¥ù{4˜:9ÜJ¡ŽÄ¡ÎKUÐ4·}P—ggêÈîôc@R6 ã×Âãè×cøsöö'¿9ó&C94êûð…“¡øLxížßtœÐ(Ò KŠÜÂI3V¹ã§nî3X*{ÞbÜ´-œ¡@ØÈßôœÅÆgßV»§EÛãxØmYéX¢9Ò£#Åé8æP¤s/ñI›ŽŸºa•í„õ0“{`MëGó¬OlhXç)ª=‡«b d`§ÿ‹ðÉPn»¸92°#Å[Ÿžíg`ò™uýB‰ƒyRp+¥¯z¿!Žm)œ¦ØmÏÀŽ"h;n ì8†5°ã(í#/èâÔ…ÏÐì’†YÌs”3ØgV¸éÃÞ°ŽÙ ú9€Ï¶œ±d‰éh®¦{õ,‹åRDÛõësk׳ô2¤[õA¹†š ©EѾ"š}ym ¹fS+¾n÷‰ …¼agNÐ|6Še!ÉGfS…Q,žÖ(Ú|s íø¾™šþ@{ÑLÝðësöƒ~jhò±z“šŽ‹æ²ñ;û7ÖsÀÃ64e<–èŠu.ië+‹”ë1ãa[ó~ž¢†&»M¡!€½ì,yÿeŸð«óWXÇùÔû/ûŒß0Ã:æÝ8Öƒ5ųŒgóGõŠcø§•5ÎXìùÞeÇWɒӳІLìøThà—ÕÀÎwWZÆ'û÷çpçù ö MÅÝ06?ëÙƒfÚBÚêòϧðˆÎá,úÖópnÂZű~ÏmÛ6d铉ٰŽóÇz±pËâXn7 êüåQ¬¯}½ á‹">©hžE|aMAÿ]¬ç~á«"ƒ:;^+Ô‹w=Ä´c?yºëXÏ`Ÿ;Ö²ïiµ>D!ü†<èó¹jéVD¨ÿ7kxvõ·­[¼x9|?¨áñ3ÉKd41wìÏp¹è.7^œè:ØsÇ^øÐdÍ1%s¹mñG·ñ^ðØñÍQ°ˆc}×Ï c›Å/;ÎW´ˆŸ×tÞM§NÞ$Ø›—ýbØ£`/¬hî›ÏåPÆ‹³E;ç+Ú9šÛÐ^œ­ïù’•› ûܼìüƒy´ð°#«Úx.¾ì .ûÎ";oµcÇ ž€}e/û¾óêÒBœØ©[;ö|õ2CÚ¼EÛ©“/6¼Œ/^v6ÊW° Ø‘}>rˆn¼$c0ãÁ¤^ÆÃxôIù öüª³°N¾1ôáñý*r–¬vmÞ_õo*„Çó Sg#sÇòŠX…ðY6·°]†·ëØûÖ­ÐÒà@Qkøï£©WHÏ;ö¦aÇ~ë—š¦xÖ3Î2<êÈ ) Éùz=:N-Ñ­Í:oylãV}fÿ/ß³ þ(DsÐ|Šó5–ïœ/l|¦8ÇwÄpŽ•¹ãœ…ŠsÖ9¼ß«¯q>ÿ3ç}†©¼îÒˆæ&TŠ8Ðozϱ5öu[’Íá'jÙ\ÄóÆÄ‡ðy,7â’B±>ä܇‰µ‡¿ÐÎ×í¦‘Ís9öù0)M¼rxÕc+·ä1·M#Šš¬Œç‡ÉD²ñn}Y±¦Ñ2þñ×e´s‡¡=ž¾L{ˆhœ 3IîÛL5‡ †_CøŒö iÃÑ~×z=áwž­ØK5Âã è+·¼_çñ°í×cÂúü5r*¼kd3ØÏݶ_Ù§ÚÓ±Žÿ]¯O¸•3¬ó.È®_Ô×'…:ƒüšsfÓ6‚ÏúØï»•WHBö¤_T9Ò±iu¤¢¹û…4ùQ?PÏd0ǃïÚr»>ævËnCùVY0Çﬣ<©cÇæì%‹hŽè¿­œ›á½zÂóüEa¾á1´Àü¸šSÌÙDqÎÿ[Oƒ¹)®Ú8ýZ€¾TGn|-÷ Ðï‰h¼\Ø“Î>3Šu>zU¬7«¶ÂO’dê9b}zæzkõB âŸQ¬ãžß44êøGê<Îv‹ŠX¼/ßC)Ô»­zô’<Ïb«¾áZ¡þ‹ñ êqׯµƒ½é<­u½\¯_ØýWPÇÂÓ žƒŽ¥z‘°>â|Ï žãXg®s ìçÆwU vÆO°oìKùöÃC^^ è`޳a]0×<ìyãv`¦­ú~¡´óVÀ¥ð¹€?_½<ÀïY98ÑZõì¹€_«ü]`GPØ76À6°c=ü>Ø|—¬Ug§";›ÍÖ/ncLF“¡ŽƒB{×#Ò‹änÿêÄ•£×ðÑ:vaæyÿÀí"¸[¡ž+xþí˜Eô[õ¸Zgƒ>{Ö›ä6>0¤7b¹ÛŽ·£ö¬óâ\+xN‡° >wëü³u÷v‚ô‹êÜjxN S¤GÍÆìŠt0˜qlñ¨Gaì<"úìQÇ~Âu,.µ„çC_í֛붷ˆ^ÁÍúþÚ#z.<¢‹f}îDð Ô±àq¨ßãH³ñF\õŒs,C çÙfÄ*΂òì}™*˜W­:Î è82 ~’Ø((ÒQá§HŸñwhÍ:²!F>—‹@_£üô5Œ¬p¤óáƒ*à¿û¨HÏv’¬þ°òû¾_c¹¦|/õ›âœ_åø¨_DoÙ¦­Ø«sð‘årùÎËp{^ž¾ö³©Þñ-yëlÒ ×.ôGêQÉx99ßÌÊwþ¡êøË±k—X½?'ðùQg¹ŽmÚPäfð¯]PÏg¬)¸íß˶B{¡¾ú`,wÓ+§m;Ôó± [4Ô±Üs¨gKIŽî¨ÏÍ»¾M8T²¥:ªc¼€O—m¬g|a<µQ?LØÙV…ÜÚ«g¬Ï9øá›©;€Ö³?Åü)XÏW¬Y@3V‡mùŠuå_ßµÝõbŸßtøБºè¹Q/¢ÛXVåz—ÜÖtêÅø½Ê%˜/qúþ|/î]Šâ¯:‘‹.4=—=v9ž°>€ždrÙn é_ãñgÒ,Ö ÷¦ÚVhä°“°%[”ÃîO–‰g ”/Ù4vüó¸Qßq¸j]:§{ÎSæòÊé^Žò›´ïE¾s6¬ ä°#1”7ëô\·ïåc( ¢8TÇuž¡¼É±º=ÏãÖœâ44H?P~j:~{lòžoÚŽïŸíAÇ™¯Wîù¦mK2¹ì!É᲎ôF›rX× ‹RwŸ¹iÇÆ=±÷èyö¾à?Úô"áϾíEGO&ÅzU»/œWçÃ÷ܤ³_•ïø‰©òýÄCŸuÄ<ë+‚ìYç<13‘Ì^ð{Q½¯è‡ X_ЉÇËë³þmÝôìC’¾£wD„ï…ÓTÚ†“c;Vçï…b½¨Þ—‹¬ó,¤3è3©ï:¾Ùf@“µ33¾ õ#Á¯;†[[ŸÏW쿟¬²´ ;_«à‹;—!ä†xÑÆ¶'þ®7NSÍýjŽgä¾ø#¿ØØ¨oÍAOí|ëƒh«üb'¬\‹S.ÅúÆa|fKQ`}NC¹ÂyGÕ3Ð9­õ}éÌmHGô9ÒóHnÆêÀOW‹0'¬ üUÏÝúE»A}é êÅJÿÕö¬Pã÷ [ú£Ëήì.ãwê… |Žh|¯æñûQØR°e€íÔ§¤‰-¬¡£«Ü̈Oºõ¢‚Ç!ÅG7mY&Ç-ÅgêXA¼¦Þ`}iVê—[~Õ–7mR¯mÚr·^ä»ÌX®X Æ/]2ÖY,m«6ú©¼„Gá‚Mæ ýû†6¦¾SOCøl!¹å|—å‹Ï>0¥(]ð øìñR}ãµ€§ù>…ovmYËF öB)÷xó®mÏv±'K¾=˜ËÏúåÖuÄÝ3³xfÀË<)ò þñÌs¹Þ‘Þ¼êq.oÚøÒ΢b—¿G ïØ ø³~סKTÏT@gU£=àG©ü à»üÌÑðŠtv£ôGýŽëUü±T>½gÖ}Ì‘mëɵ¥nÛXm¡êw|Šé'Ÿà[ý޲=—¿Ó?ÚnÚ¦tè2Ä›¶ ïJ é ð+Eƒô»Þô¬ŸÙÿ÷ Qã'mE³ž$±¬sB±­Ö ¨JL…:·µö¨gS¹âMÏžrÓ™±ë̪ ÃzTÊÍ|ËnêwìþêçðU˜R–r80R /¯ÇïSaÉy$‚óí‹§7n3ULåpûW‚XÜÁú®-O帠6 £ZÓõó™åm&}o`Žß…ùÅ•§Á<¹BGêÑ4st€_7NOµé;’©ÕîÈ& ‰]úY bOŽÈÔ=ÊgÆowÒW@ÏΑ8‰ ¯_X¾~p϶à¸äŽÔy˜d@Ǫ۴ïxÛä#¹F@CÆ Ž_ž÷Ú8íÖž=¡/‚lß}Ð “Ø)wéÓ‚ŒkH/ÖløÓÙ;*Ò§F)w4Òwo)Ô‡àGñ€z¼qa//úñÅUžB}ÃfÌÞtüÌÿêMoîÙ¸0ÿ õs*Ü#9ÈÕƒ%ôê<¨?~‡±z®rQBúìÓÇO¼¿iãÇÍü#³09L[õÞlÕÆ¦×«Ø Üo`Ja_Åô°?~ËŸéÃŽ Â=HN…äûÉÃ+‡;>µSÇ÷ÏÑ~س#ô£SC¹sÃ9=B³_ªbÍøëØ'9ÔOžÜ ÔG¾Y0 |ÖÊåÓÕÂfŠÇ!z§ÎçafIÁŽ:‚tžú ÒwŽ—¤Ïs2Ÿž©ºQ>³³ç¥›¿Çþõžm|NŒzÇÊQŽÇ ô¢€¿K?3!@íØ%ˆbà›p4ª8?‘ è)ñkäLbÅ9Gз‹Ý¼½¸QǯàOœ?ýèüë Ÿq¡¾-|2£@go:¯‰èêíçËÕÕ®A¡@çnK½g¦ ž™’uäèØ‡Ðù0Õ€Ž¿c[³~Xí|‚t´M1¤§™ÜsùÅÙë uÄŸAýú¦s¦™býhê÷‹ûrÅúÄNßoªgÿ\,+Øs€ÓðÛòÀŠÐê÷Æ~†ûC‡ûS,‡sho×ã¹ËÉ·VÁ7g¬y­ÎJ;¢Ï°¾nü¬â|lµ|Ç®Í,åbŸŽJCíÓ¼·ò©\®Þç¬~ßö¨~Ç=íÙž†r\ƒI›ÎW5¦’Ó£>Æ|󿀵‚9øÍ0˜çPÆ“Ë ƒ9–4>•Ë+õ…3ÓèEÒÃø5óÔ^u¾M2¬gM,þ¢­WÏ%<[é¶Ëa»`åo«ÙGÆ­ú¶GŸ©Ç³În-6•ˬìD¬hÿv~…öxêÂIR†öæM/$±¼÷G©Œ#R³ƒ;q{a?sàwÇŸôpë²<[»<•c_H…ú4rº£B½¨ßq³ H/hÖ¬~ßp¥©ï:GHÒÙ½\§rXñhýÎFóŠô“GXö°cc¢P? ¨¯cËeûÈßc“аÉ6ë9ÔeÆÅÒÏý‘T?ÑŸP_Y»mÛ¶"ZýÀ†Õßõõ  Ô³ü}|ÞEõ{qÔVÄ7aËa·êy±>ç~:¿êò3ŠPßx'Pfâ圇“³1U+W¸GÎCjÕ³{äŽ2ƒz•ôP@_ ƒ:ί>zÕ¨ç]/Äêù¬=Wm±ÎÚÑÐðwG±>òRÓ±~DZzc85lùZ}©€}<‹[—BÛD=lâOÁ>ò`×Þõ"¿iÅRÖÀž”±ÙA’F]Û¬Õy(b`/T4¸ ù›¨‡µPÆž ²˜÷ë…Šë ›Â³A¤€õ?Á>U×.ÙpêQY'°Ïìkï>’¹ˆŸñÂÞÚõ˜ëò@û^oyŸÁÎE¿a}}Ùö@{Âç §§+Gñ²ã“óþ½ ¾IÉàãÊm-Ա焄Kæî¨áyEñö¹úãaŸ£“äë¬qT¬ãþÁn9V}.Ìåð_£û‚õ“=ìØN¹|¼mÛ8¾Þõ±i4÷¬âyÞªU<Gæ$yÆÙ\´’dË.Ãzµ^o^vœfüØó~ýö\Æw“ø¦ŒZšáÂR_ö öáB/oÃ9ì»ìaXÇ»ñŻޖ¾ëEŠÓºâøK7j! ³1|“×V„°®éYÏF’|û`RxÖWù¾xÕ‹†_ãVëEÃŽÿÇâ(Çű…:ѪšcÝŠ5ìYI3<Ç Å»^4ìh´¢XÇßÏÛw¬ѤžS;~|å–¡ÎwªŽÏú8.1„õ uNëѾÎ}_‰¿Âz\°Ÿ9pyÿBÇzñ¨*Ô[~¤ƒòص°—ã£ÐO6nY2-ó )p¾çhƧҭq‡NçmÓ…—¢6ëôGç¸ùÔ7}ÇÕ°÷êùàeÎêØÏèŸ}úÁKáMQ<êqµž]$Yš`ƒ9vÜ}Ûº’Ë!oÿÍÅúE@‡á‹N½xÒ‘O è…3ö ¿Îµå ¤ãÚÉÊ÷¨pH¨†±øLüDúrrÕ­HŸ–íd§Ã6‚C¹a¹ðÏ´¬¶b«½lûvÌ{…ô<‚Ç ÄnÖ±8ý5”Ëú^¤8ÝõúP½éôdoz6–ñI²ê½õQφSÃ׃{ ¬£rÅ_õdOñÀzËáüÁ\hâºmà nëÔ‹¼¶·¼m8ÔG}ºˆš6{Šì ;vÅ:ÆN='9áKbXÇyî/#šF[ ån*ߋ̇‹“c…ú€Ï±¯Ö { œÙ¶-«c— £I{×7\äûTõ©\ŠKVvÔ•‡}cm†‚uuo?ì¼TñÕ:kˆÌ16ƒïõÍ¡"nÛ Iü{ ì\ž»dûÑøC#p>A;;ƒ*ÚóÑúq²^^ÑŽØzÓúñ²ÏYH³ò±ÝúESÿö\._­?O¸"ØsÂË~â<ûuNþÑcVÞ)Ôç?hæbnÛÈ6£6™K5ü~â‚^‘ÎŽ#Žô¢ˆÇ³˜C­"}¾Ø4ê»qÎyÓúªáUÿ™3αMúè|*g%|qó‚ùGQNÑ~ýâøEÌáá%|žÌñù»YT°™ðO¤78¿HÔú½ˆ\fëz«ßó\®Xµ1ÐwαP cÿg8ç)Ž*hŠÁÜð…?–§»Í:öf&ùÚqj,¼$ùŸbé.¸ry{Ó†%œÃü&w¹ªvÇ­ž åšNÿ? àWæ.Eð/ [ØÚƒ^D»ðÛ÷¶Vû:À§UÛçŪmä¡’Iå²,–ÍèÓ¶c6•k®Xó‹þ]V¾z¾bE„ZŸÎDéF4ÅP®‰v¹­vÇ»5Çz„ú2ƒ:î›|©žå3,ù±“õF>3ì^¨X/Útôµù{‘Ø–}hX6¬²Ø¡È\žðSwýL,Þ÷rÁúta˜kA¬¹K?pigFðAûÀúë3Ö§éT¾XßxêâX/^õªM¿+t_6ƒ:ηÔtjÄ—m͹KÆúœÏ]V–“ÖG6B|±ÎR^;ö¢®‹Xǰ²ò¯Ç±žçïìbžSÑŠf¾ðöÝútüúØÉ:>“V¿/š19D?±Žÿ{×9Šûm¬ã8É¡~—<ŽÀêaúþô—ÑÓ'†SñÜåâœÃ¦ïéÜe<Ïçü¥8mêùýž=´„ÏïúŒŒ¡ïú»QÊe3É…]ŠëGö‡žŽfÙv±öÔ‡ÛMO~x­¢“?ô¿n’Ͳ­xØ9‘ÍÐÞ4ì8ÞûîØ18ÜÃþù²7{ã;•wmœ>bÑcûÁ¿h;:Ø£CÅT$?®SËÏX'nû ëEÆ Z0¨o,7/u|¼ì]/²œ8Âs{„úë üêøír¨ýz†úöÌ+* ~Wò~\ïC}Æ7Òœc±:rçØu¶µö][ó°ó/Èsùfs%b=zI²æÎìår¿ùê£@ç¡›"}ÅÏA+øãÂ[u®Ô´‚Çï©Kcãþõ ëéÈ(îDÓtë|=¨HonX±šù膵X¶q+®HÏúYhFœyÒ 7xÓÎ/º~ÓÏ8Ç}¥àü¢cÕÁ\6˜[‹Á܆8¶!|Ѭ³U¾b}Áͨb}åÕ”MæòZýÀ¿Ë ¾¤µúøú†u|΢ ~«TðÜÐ ÒÙwɯÕozÎm[øçR ó ÐÞxNaÕhÍ:Ï×õMOÁÿb­ð}ßV`=>éEðð®±ø7é³>á#`Ï:‡ *ÔYp!PßðÇÒ䇅õ`u>PÒg¿Ö«Ÿ¯M§Æd=^ø³^Hh6œ„i¯~V*ø»ætíè§Ï:¶/^À×mø³w-%Ô8–¥ò†ö‹0E;þ‹¼[O£¹ù"ìDü$y¾©pÏN4ÓPXÇVpgÛ{Ùãhîñ~™¬+/DôiÇž^áþ½j}÷×ûõáí).œØ~=íY1wâ%Áéàq¤æhÏA/<Éñ*>§¬È™.ƒÏe{y =®ÖG630¤ã.ÈŸõ,š+"6Òw^2Þ†MÿO¤/_Ø')Ô‡ìO±ã¿Æ*øb½¾á,CŸõGãú¬ó¿G±~aæ``g•ƒ=ëì߯À×ë^aš—${l{·~ϳ~—Cô„ý‚Z¤Ygo֋×¢†_9š[ÀÎûZûEó‰ ýðöX¿GüŽ_AÊ-Î{è#[ÁŸKöŒ}†wçÕúΆß:•ËøišRù¼$Ÿ8ǯOåšV=ž¬?=)‡¹»¢Ö³6vá kÖ9Ÿùƒf=帋´f½¨ßYq¢8_ Í€$§:{±(Ôñ߬<þÕú³ØÐÒ‹×zôiÍ64- é+Î9Ô›Ô‡Ô©/ìE`õ{ò¡9ßרªoE«Î'à†tü(ê.X?ÇtÊú4ˆæÕ¨@}4êó·¾ñÔãyß=XõÎÚ*{ÕSLãvá‰ðG­:‹¼ êØj)ÔÜúP®Áz|Ô'Nõ1¬'ߨ'Ö—‹Ùb o&¼,xùoHC¹«EúŒE¾½éÙ[neA"}ÿKõ­±ˆ>qf:~úªÇU[pˆþwü^8DãÃÿ«~Ïzc#y×N‹"zžÉ±»¸½yÔq«@/Y·‹qÛO O3øB-ÇÓËmËkul÷-h=Vï(·0ý ^XÚH®ð–cÇJE:|z«Ž|7ƒÏ›66GÓGýÛ…ôÔãV»pAúÄšKåŠF½ hÄþñ£‰\õبëR¹êX?ø¦-Ëàyñ®H?š€NQ0¤ck/Y3µ‚Ïîr"]ÓÏpJ¸@ÃìM*‡¡êgNCQ¨³"Ñ^pÜhšK/øG wþ3NÿÌù¸ 9ŽõÆvª;»¬ýQ–+Ê}×±ÎVPä>Xçù±ÉbóVýø:‡büÎJþ¬þÅÍKVËÍÑ‹fYØsÑ4>G/|r­ÂØý '†öâ¾m/”±—ïúÿ€}Šçmœªef’MœS>yù×½¾(âïÒËå4Öf?ðˆÁ3ïyÙ÷œÑXˆà§™_–Ëm¼Y1°§üÄgCvúÑÕŸ!!X_ù<Òöm…2–õ¾ŠõW¾ZÄ_øjÖQwàÑmÙ‹æ¼Âÿ/Øó}[>[Ÿ¿ð—óöÁËóD§;²î_-Ö›kÖâl½iØñÿcXÏz¹5KcÿÐæ<Ö‡FŽõèTÄ4â¼Gßuü*Ö'|N\C“ö-{ǼŠõ= ýl=ïÖÙPK«øoÂWX»uŽ3t—èF0W ½ú]¯:~æïûS¬8Oô³õ¢†ÇóÛr¹, yªg¹ÐG‡aÞ®¦SÑaŽ‹93“Ì@qv`3xüÿ˜ˆÉ t>AÑvýøÂÒÉ5ðùQç PÛ¬_²þ/Ðãž+-÷'ã¿6ëI-÷ XI¡Îžeu¾Â4MÌY?–|°¾¬MtÛÊv#ú¬£FÔ°>Ç>ïÖqQdXçƒÇ÷u4ø»±‹ÆO ^8Ná¿ÇŽŸƒ#½¸wÁ–_‘ÎŽæ&Y¼êG¥ŒeKo­à± ×N¿ïo†¼äõùñ˜d¨ó<Í žƒlžÝK‹]“Ærfó÷ ô5ß³·ßà{k#eý•¬Šéwµêøåy[?0j êØ+ø£oX§¹(à‘™M?œ<ø5Å\1‚ǯ‡YNåfý,šu—býÀ̰Žcñ÷Ö sŠu¸®³ë¶˜ÞÆî ¶kÛ®tðÿ öxÜÆÞÅvöõ½z‘èTlÛðøÖ M„:gµÔ›HÖ<€Ÿ.Œ¢D_:M|`Xçaµ 沓$r˜ à³Iô$çÏGìº-›S¬X«è³ÎHŸÀs­\·MØÛÙ¾0¢ùÖݽÂzoC®ô½zõÂrНë·)á£ÍÌmKo+fð,‚p ý;')Øüb¸`ŽÓ£| _<ìxüa¶±ñaçПXßOünÖǵ¸dÝñNÎwëq2·³¨;Dã÷PÁ^(á”`Y(ë¾>¯°ž³ÛðžßÞuü·|”ÝÖˆcïj×ñ¬ÊÀÎ×k*…/üà9¥ùm?øi*s¬Q¬O¶¤†u>ð¶‡=½ä)<^e+Ô± S¨?ƒz‘ÝÆ6P¦ƒÇVÀuð\Ò軎óOï×ãÂíQ ëqµ^4ìóÿßÇú‰¯Ä_5ìÈbïOáWdº¦ðqß6ñûg*š˜éô,A9ùI¡ÎÕ®õëéH*õ¢[OöróÌÕ¹Býä<:ëÖ3Ôw¼ðÝ:ïê‰VÂç“—óHCøl/7b¥ëCø&÷!T<^uôZù+q,÷Ò q,ª.\0W¼êXA¸ëTÎ}¸ùT¬ŸKõ…÷¨ºqÃý‹õëE ŸÜXW høÑ6´³q’¡=ëc±Sry,þ–­„ÏŠ¹c}6—jø!ç·áwÇgsųŽÕ§{IF¬Ï¨äúH1WøÆí:‡1ÖQõëX’¹©Édü£×äŒSC:Rm·ž›ui¿ô)ZDϱ†t,}2ßõ“Íêiåö4žâ =…:~êkÃñ¼mBs³£áûÀ÷C^Fì  ì8«ÿȦpžÊvð;[â›§vVÉ(ØcÊËþœöhç°]k×ó»Î©F6‡O`_pÄ.`Ÿ¸ø°o¬ÈQ°sà`çîÅoYñ;¯`ñÞ¬§PriÖS{|׳w,î5 ìU¢.ž ì…>‹§¿2”Ì—¬ÙNòô¢„GVQ¤óxØVnM ¿ò3i7/x=ã{ÈÎÅÙúÈ~ço†·=gsq½¾q²»=쬼°D§óòtoÎXÏ ûΪaýH ÙlËþg.¦©Î^nRÈb‹ø Ø‹"§VÄs˜£¢½Ãã2È%³#Ívá5£hŸ¸àµÃõ|ùrñ“Y¦.ž4¿-Jd'|Û~‚ýÁ…xŽé{ܹ­C>\?9hТ“þ v=›St>qûö/yö|㆖߸Uö&ª1çø¨ìoÜfö;´¥^?º×\!’-–nÍ~½€ú\ˆáŽ?2¨ç•®;Þ]¯óå@}Üñ­5)M1š;pŸfëu¤­á¯i-ç%«á9Á[ñû¡žÜÆ~ùÒøÑd§èÂzjÆWô£v=–ðV³9q+ÎY±F}ûîeb¶ñYJ³=Ï(Óþyp^<ëE_¼êÉTrçé¹@}Î|¸Îj­nÜp|àþ±ø¶ÃuœG{ÔK¶ž:¢õÔÜ[uv3ø „Ç7ÉÁ~[¿^Ìæð'3ë)œ^ú ¾˜Íå¥Ût ©Ú»õðÛ×q!ÂV¬sgf²¹ü®sˆÙ»Ìl‡¡û‰•¡çO†vì[í¼Ëø•ö’õð;¸mØ‹3·óõpnl,dñáR´PÇÕ°?ëÍ»~Ó~ÆÏÊ ^ð|xíP§êí°õ™E«fSQ@}_ùñW¨óÀÕ¤4y醒B}ʱN,ßT¨oÍzzÞ¶ŸZpº©•§äŽòiƒz‘ÀÖëcå‘~áEð¶Í¾³†tü TÁG%ÍÌ—8†tÜ8Ò«èŒôÂ>¶êÛ…Ä`ÞáQô®dnäS…9ÂSaÞÈcªR˜£ Ä_ôxö²ÉZ¿çP§÷ˆþ¢¿¾g}à<àQx`#x²¾-}Öï9€ù¶Ýú̉|v÷’wëÍå:~ þ¦çsÖ“÷æêG…47ì8SòÍz–Çæ— õ¸Yf8PǿʠŽ_Bƒ:þüEǦÍSY3Ò8Ö©¯U4¤Ç·£‚ôçÂŽt¾~Û$zÆ¥ÔG˶b³^˜TìØOx¬SuäKƒ:oÒÞ}þïY­ã?HÁŽ]¸-Û’ËÜ4IëÛÀÕ§Šcq ¦Ë6ά>'0óJàíX§i=__½Œ…y,ߨ›Íz–Ç>À^,Ö±øëÍf½Â(e6¬ãéXPçi‘™TDÁÜöMáÿH¡+øÒÓLn)RÆ W u¬˜B}|”<ñYßx¡iPÇà [@ß¿ðŠÉ´±ø…_¿?š±pŽ3ÐwÖ¯;Ð3ΙTþª|G‘²Â7Yб´ôPÖè<5OH†ô,˜{0ó\˜ÇžÕÙzÎZGɸb=;Â#ÇÙH.[Çnü[6ilŽ_f›°ŸPÔ÷ú¦ŒÍQS†úü}!ñ êq«>ãnQëͪm/4ÈÜõ¦7'/øÅ0¨cmàP/Þt<1±¡¿ÅºV/õ=&­ß5–{ Œ2г26':=°•{õ…¨®Œ ½úë¸ÐT¬?¾"Ö'¾GP¬£Â¶ÍZÿ¬qü>ao,X?¿ŠKÖê3 åÿ ëK4ç:Ö£õoºêq*7/X‰ØR=Ʋ>õB+Çù[ŠtüÉ éÅ“žÖyÉ¡HŸq?æz:-è,5 Ã~™ èXãгÅÜ|µþ¿@·mÙ‰æäSEz‘Ü6á4ÒëwúÝ|ô¼i[ ùÌÈ)ht¬>龊ô-åŠLÖǣ΂“ÅâÀíM{Š%ÑŒ<W¤ã4Du†¨"={I®ø€*ÐWüê(Ð÷˜¾ü:ªè3Š®è{ÈeßXND4 sÆ—¥9±Ó¾èÅší®{õ(’[¿PK¦(ÏINÛ€OõÛ _xD­ Çñ³ëaw¾i×÷œmËFøT”£”@`~á­£ó8l6æÇ‰C~ƒyF9{ ÌÙËF`>]8û•K´–Ûg\­ Ì—ï»ÜW8ûô9ߪŸ_,’öy\Q¹7Ê™›´ï3b›ô¨}gf+Ü í;6Å uÜÕ)Ò™ éGóœs;k‘myòÎ21yÐÏB;ƒd Hßìü|5F9­l9(PŸó<®ˆa=s¸ËΗÆúœ¯çq›ÎꟻéŒÍà;>Ã9ÂóœóÊÔôü¢3> çB.ÏÝYvk³8>Òs¶‹óV•Íd”Ǽåå"‹T÷kQó¾óÆYP¾ðþİ8fó»Õà>óìÐñŸ¬0ߨ~Ôd3\€é‘:þšéߟú+¤ç±{®Ü>¼w¤‰møM6¤c—ð Ò ûH,õlW”îøÊ:Îã-ÛrñZ Й çþÒô å]uœ¨Ôs‡žãv>¢¨?Q¨fp±ãS÷Ü£³¯¶NÝ×(†}.Ó¹HS¨ãPÊ <àPÇl\Yñ~Ó0nÁ'Àõ»štlü|‡’vmÓ‘s}—‹÷ Wc v.¨­zoÜgx`n`oâÕñS°ãönõ¾ŸØDê»~à¯Ðút>ÛÑN…Ö©ãæY;õñBG 9d(;ßKÚ@.Jä²[,g;ØïB{‘ø0cwøÚcºËŠsc{râÕŽcþ*ÅúšÙÔÓ©/XŽ(ع_ð—=ïÓóPnäɾìXë Ø§cŽgêÛ„ƒ{±O?ðOÁ¾cônÞÃÎÉ õà9V±üp¤Î3'ÛÓ(Ò›fKËW«wS½êÙž‚6gYŒb—ÓŽõoaë+«ÚÞv©àyŽoî3é¤mœN|ësvŸYSëó2L >¯ì?ªX_ø“P°GCŠy"ØãB9å'ØŸ"â -[Ïà´È›õ»€O\V–.ûž­˜ÊáÿíG}>qÀ @ç$¿_Î3¹€ç˜GÅyºO_Ø»GQŽ· r|n´Uçu”=èÍž-ålžäã…¶¹¿ÛtTáÊçtž>Äñ{µNç,/ÞóPŽ…dô»tïnŸPCz¶ÙŠP®*è7+¿èYÊv£>¶3Ü+Ò±æy·U<~E\[jÕÕ‚½èhý`‹¶bÏ6pŠö /C;û)ÚQæ«KõWh×lJ©ozñ ó¤@}Ç7ëoÞô™›1E:Ê+é[õ+ÒY$mPÇѰA=ß²íÜüÃòi´Bm ê…z&'.O?E:þ_äY|¹O_x+¬µ{2‰}î#пA&9Mp*žuvÃV /S,Þã5Gý¸ì½èÔsñŽ˜Éào\VŽÐÔ7ý!é…L®É-|¦2¹N [œ¸ ÿƒOäò›ž›tü‹çø ”ýÜq]`å;“—àœ£yæØû(ÌÏ&Ðeɦ3;~äŠòuÏyܨ¯XwZ‹Ž_Ñ·Q¾áûé0¿K:Ã{S…y¶‡xÑd0ÇGßaž¥3+ißoÒ7–º*Ì7ü-º|¦èÓsíÎBmÔ~Št–[íÎ=¤¾è8ÑT¨ãO%P_/¼˜êÎ(ê¹t_Ït´šýa¹º0¬óÙ€aãAíØñÿÑ£¾`.hztE´óUŽ¡½0äÉ”¢ÿ.C{3{çK;Ò˜+bó… Ž”ìU¦‘ûÝ–‚}Cª‚ý"¦FÀ^Œå$ŸÂ–§múÊ+õ‹ Í·Á¼ ‡Â3rÁ˜ß¸C9Ö6Ö×}4”‹X¿H ÓþÈfrïÇÞ/๠×úý _ÌPíj5âœíÔçøGæ,˜O{6}¿hÙ¼zÛô‘‡øþ¨³a¦¶éÈ_¾ONË÷?èÐãŽmÅÓ¦ïüB(ÎqŽýG8/öéÛ ^åMçù³á+oÓsÏ#ó75±6 < é¬s¶›Õ õbÏôß|AúÅ1ƒïÒsõ¾"°éÖ_ú Ï|®«:KôAGv²êýõ8îóx´ÊáîŽóÂq©Àvl…a$ÒÎGÏylÔ·bÇ65ÞRøi¾=x_f,M æ 4ø[åžOÓ×Û„Ÿ0_ Ù‰ûbzÚ§ÛÐQ j@©«ÏÂçŠó½¼_¬Dèø¿±Â}•{¼ZÝpv#]úXia<¿³É{“Íö_ìÒwNV¨ó7àŽSaÃ:v ï+äŽfɶ/¬·¶7½TÇâSÁÎÆ+:“+ÚtØê>o}úžëw6¤S´o1ŠñÑNð¡§×ïYËBû:‡(Æ¡°‚Þpö pŸ¸;t¸ûS‹ßA{>i›øÅq°ø\½ø³+Öùbä·ò=ß´mì™lXPωM?n&I׫ÃQ˜¾o܆+Ô£éûñ5øÿ¨;7&>’ËuN'W¨¯Ók#¹¡0äM¥@}æ$Y/á¹zÒ—U„ö›¶m ³·½ìì3ŸkØñu°G×ÈåÂHä3,`þeûÎB}Ù‹ÜUü)Ú±¤S´ã{¢†ø3õ þä6~ç „€ýÄ^RÁÎŽÛöç¯9¿ë'[ÿ Øù¤`/Êø¸lãK4ûòÅ>%v¬žÞ/ãojØÄÖÛUüÌfŠõ »VÃzŽmZXË$X?*¨WE<«ëÅ:þ~ë3Í ÖGüºëÃÎ}b}à ©`}Àë; <~b}†¯,¡¹¸Cø õƒ‹úöíÙþ êñz•mc êXÆþ‚zѱ7"š›ôïÒ3ЋÛUvœp çCõ" íQë6ò÷X éü¡*ÒcnÓš¥róX$1ÆW}ØgÔÁÒ³qä…ï­#=vëçÎu‘Að êøÃ+Ô‡-½êÙ úÀѯA½˜Í±µ¾ýÀªÈ‘~W·Ž…¥@ý"ÚP±>±MÝ£žÍ#Ys¨zá(7812¤ÍúEÆO¤oF©õ5ç+-ÍêÛšëãF:§b Ô¶†×G}þÂÞN >N Ô‘˜êËòZ;nÐ<ý4¨7j¹âª ¤?RÆ®<~1¨G­Ü¼à‡nPÇ Ì Ž¿g«ßóÆíàöïg= àO|Ý ìH öì6ÅŽíŠõè+÷h{‹gý`oCÅzܬ/ìg¢P¿õ(Ôñë¬Hç@Eú·äîÒãž]?é+Ÿé9Òñãü õýÎ ¬ßtÖ¶²*ʰ543ßÖ<~1l.ÇÚ)á¹ ·!üÅÿH¡Ž·xõ8—ÛØÄ@¡Î;Å:Þ…˜Œg¶ö®ãÚJx$B;ÎDì'w/ú¬#÷Ø‘PìIE3ÆëÕb¿|¡ âƒVOÄê7ðXÄZ¯ŽÏ„Oà ¤YŒV±jJÁ™ª:€oÞô•÷vôeFÖª£²LΑ„tœ¸™#tÊ]Ð…àsš Åû>nÛÎf±þx'£^î²+ôzL±U÷«|Ô,P¿Ð:ÔùÈU_õ"¢ ÿ®õh{øþ\nÂjÅ¡%sóš0»U¯l)8#ä'Ø—/¶Z4¬§ Ö§}XÄ:þct³Ž3Åú„4ç‡mÙ?òd³AËÅSõóøÂÂ[§rö¦ÇV}=BðêPØBóe©-Öñwì|’LDƒs Çú]Ï:6⦎E3—ÌåfiÅs9¢måD^UÌiêç ®j™½bWž÷ëž-—ôYÏÆÐ;Š`}9 ¬÷sX[š^×*¢г¶‹»#Y«³â^Õ±Û{õ¸Vç=¤C½¹W/²¶f­~Ô±>° ë ƒ:ß¹š†¦èÕqaqŒÅÁ:þ;lcS!ƒ:[°Ô³6¶ðš*<à¨s*‚AÝ6T‹F±ÎïÚXüõ8سþ@f¶“—#•ðÙ?’ŸZ×ÐTïzq°^8Hâ`ø£g=šÐ윧Xg6ôÕzqõ’Ý)æ­HYæ¹íÛ¸#ýà]GX˜^.ºMÍ#VÄ v|³ì¼4°³‘ÊÛ`ß±…Ö‡}jÒW/ÂõT0‡ß1ó› é«°Ç·ÅL6…Gs_Bø"Å +пÍízÆ:?JÞ®XǶV±Î¢iíÖ‹~;‹l¾ u¹ý\6™Ë7/ˆ%[ÇâàM°>£Âÿ'Ö Ù¯uë…ü‚23šËA¬ÇÚÈæ>IÔÙ\Î~˜§×ÖSO¬çxÆl=5~ñÝ¿{D§ÙÜ3k¡ÑÒÜç„¥ÑÛ¦’ã‰/©§?ƒø"¢qÌ/û–—n/!{Æ+Öyý¦wìÊ~£šºŒ:5Á:›õÖ×/c ëìw¨Ñøªyì‚—Ji.D—†uþ¸lå±>­±ˆÏö± *<Ì>¶*â“Íã¹iî^èó Òñw,H_x=j…§ä€È²w¹[>]øE Ò¹†øUÃíúˆ­¤a'·f4]*FVÚ ØGœ{ Øg.°¯GÈÊñ’ÑxbÕ£²Cô©~f4‡ó {|×ã~Au§a½8|aÏ:"âž-*V¾Q²Üüÿxîýèoç«OÅÙËVE4^ü!mÖYrb|v£É #Ïòè(ëÑWÓ­õU94^+xüŽé«Î.Æ ô“s©èlCd¯zQ¿Ç7='4ƈ—£»zÉO:•ôÛ,á3гAÅȾŸä«GÁÜÄ}åfŸôµxÒWlÃ=ä¥ÂGïØ1åØ>G€>²ŠÍ€Î·˜Z¾ÇN}ð·ì:$ÿß×yr$ á³`î{Zý èEHcZ¬¹“ŽôlE3áÇéH¿kÙ†=¦Aûk].¦rMv‰~ü~rúkêéKѧãÊÉÛô$}°wöˆÆQ£¶éQ.wL;v~†óì$¹rŽe.ãDÜt6ÜR ©m'|(пy^!=®ÕglÖìMG€#Ÿ•Æâ¶ÒGr7½éH=Ö§cï¬:K´ìQovm(›²>=>éìkb8穦™Á³†Ôòïpƒ9SRŸô1mÚž—ÒÅDŽß}Òsððáù–/‡Òýt~ÿ,å? EúžãW@KõǶgciÌ@Ç5®ý¦>s´õIÏg¬#‚ø“^ïqò>±ÿ¸!wžõ™Û ³’ÄéŒC=ï8±â=ÎÞ9óU‘ÎI¾ö¨³ó™"WËŠô#ËbŸH/u¬ êøð[õ>¿ÔÅ>°>ÆÙûœ­à‡*⥱’\š,ÖûnÖ›,Ö¼g[Ù™êƒV=Oߟ‚ïö®_\J›oló®gM³TÏ!ë¼Ò´?à^lÕ9X‡ïQ?°$_óX­zÈc}¾ë,dV°ã›£`_–TÁñ¶o'­‚oöìÍmÛ]¶Sìüi|¾w/É¡ñ§À¡ˆ÷ê9x¹Ijœ‡b*wòƦr…|>dåíàO¬o'þ ëë†u¾a½ð˜ã}Íj¹ç£(âóÃ^D²Îß=Å+¬Çã6¿¬ïãáX/sÕÉ:>\]¼DÍÂÓ){Ð 8c~ûaŸ‡¬‚ßXbëgë#ßÎ(Úó)k‡öü²Ç”—†ì˘ á/dûö(¡y€=¾ìo4Jîì¾”†öâe}´þ{ܪ³¦Ìªøæâ…‡¤ö õûŽÛâÑú\XÌœ e {sð‚u†½ëh¥Û¶ÂŠf™°ï0 ³¬ÌJølE“ž—m yè3ïèGN~XùŒ@¾àKë@G­}å2L€¾àæEå3ßzºWH{õ‡"¶nk4ð…ÅÜZ0ß•òÂa|úªã` é©…~K9;k‹’Xè©KùÂÂÁs€œMêl¯Ž¯¬Nå.z?kÔ¹×RElsZ–(‰òYŸ˜ã>³Žuü3êBSxÁãSô‘|uÎd¨Ïx_á±|®ÝsDãvq›êÕ;îU¼z/ô(ŠÝ.r ß”Ððå²@}Ûp(îþÐÙGrÏšX6Üÿ@û>4R9¬Í36¾è…g,"B¾³®#/B,Œ!áX¿©z硊oÖcÄËÄn6†uÜâ¿ïLQ@½Ð¬cÔÊ=º¾Ñ[u¤BEz#–Ëw.|h¦P_†<~ÇÿyÐð HÇS‘¾ç §adŸn•Êå §eÓV=ûÅrN¦½9sá?¤õ{“Ú†e÷'@ÇÕ·Øv«Ž«·‘,R #xœ,Ø¢­xÒ92Ë¢œ²€f=qïn@8ß³­0´zßñ—㦜ދ;Tƒ÷mäp C:_.™ú=æ3Î{ô¤Èv±+Ž{-É©b½øâ(б§3 cõз<Ûx¥`Õ;?zaJ1äK¶0w¨³ï¥A½rÂÞ¦ðo¤³ÖÉŽãCE:ïI él$lÅ{~Óg®íL¬zªØeyÏø„z½ói´=êÏë^SEâö†uP|‚u¾]ÒG¿…f[èb'|E=Þ…~xߨç(ÖË0/à'ì]|öÞ˜M¥w}gݾf>°”ðˆ ëÕ1‡Ý2‹€—³€;åª+ÅÔ¼ìëÕ³–[“ ~(‚Û"Ü/"7?xÙñ7è3ø»žv¿(ÜñÿãÞrí8‹õ>¢}â¹æ»¹ËëÆÒkMhÌfS+[£ÖsÄ:î´†Ço¡©gŠ Ö•# ´YÏø‰•Ÿú²æëfSE»žµrË·5Ø+¨çà¶<—kpÎb }ÖQL÷G»6¾±XX+Ô/îõê…‡ä’ígÖ ðõQçúJkxœÀÒ—×íúñÏ‘ÎÑ”žîÒôëÅ\®±šÂùÞ'XÇòÜ”r‡$®T<É©ÀG¨üè£^A½È{`ɹ?êùØ¥˜ÀG¬#’“B}À.Ñ^u\z’SÁx¯ øý õôQg/O]«£VÜõ×kõ£°†f«<¯ß ¤óA‘B½1¦¸Ë~Å9„@}ªÌ¦c |ÚÜ:êßÙaÚšõÆUnøò]·m<_yÓUn+®X/ŽxT(‡MöO¬o;—…†õÂljEA¢jhx(¢J¹§= ö™oìb=a}Þ^ç3>°^8HÆuÛ³ô¾ ë*ö6¬GüÄW<Žõüª£ÒÄ¡/ÖÇ‹ô%}Ö‹}Û¶±îΠ§ð¨ç ž…$ õ¸Xß8 R¡¾àslcx¶ÅTxüíÔ‘êërAôê… Í÷¹þ+¬Ç‡ÔûÆ­ hlÀÞˆhn{v‘œ¸5°³……=ìy0ÇþȆvn³õeo¶ëèŠö‰Õ¦Í5|1˜Ë`?ödDó`BüÑí]ÇšÙÀŽe˜=»Sp™YHòÕÌ)2Òƒ0öôxÂÊù Ö¬ßa ½±¼Öa~›„¦¨ßYóª’ÍQ6[ïÕ+ Ž{4…:G[ŠSsÔ¶]TŠvœ‹û>÷ê9íáÑÕæiWྱ-•ð8Îv|Ž{Ør¿ œîi–S”©ƒ9üB[ŒÓñÚú(¬¡ùŠ@à~0…ýZ¸åÖ¿ƒwlÉ>êÖ3Ú±±}[‘ãÄ÷·EðÓ€cE;na=tù©TÀÎcR×Ì2ø ö5»ÀØek·>©Ëì î«õ<„Ÿ‹l—í ìø Ú IÃN^¦×'/Gá%¹a¯ `?;M h|6ý…g,þ{>Z®'¬/¸õ3Öܪ󦿲ü”Í¡ÙÀ ~ <©W¨ÇÍúÊŒ¡HÇYõ›9¬Û‰•‘}Þ±›W ïÅ«Î7}öªãwÇ…ðèNd·m,‹Ò">_«/ßWW/€>æ+Vœ”YÙ÷7ëµÜmW¬¸¾ñ>_±þ‘þh[£\n_ÓØƒ¯LÞ‡z±Y/ Î{ž?Á:Rœ å#ø[ þ4›bÛþ¿€z.ý‰õéÂ÷×l.7ë#*Üÿê’éÇ·my6ÇwÇ~²že4,µ1´s“-hçãHEû0Ç·…c¬ìiÛ¶_8)jd[6‘Dݾa·ƒæNÁcd›ÃçÁÜŽRf—Á³XPKxüGÛ`ËfÅú´¦Á\¶‡f¿7ÁúøÅ–»ïÛSLÍÅ Va¥Ž-ŠxNlðÉ\á“XÇ=ëh.R ì#?‚ öýŽÕúEƒgXí*Ú±W´Oìhm¶S\aÚËž%s'jm<Î )ʪxüÁ¼ŠÏcøoGÊWhÏcø8™›¦/œžÿºoË/;ß´øË~SÊË…4JÑž²ÓƯ¿ ãæÞžÃ'Þä)ÚÏì<õ¼0EbU´_X¬ÚÛžÆsû…Óšâ 5<ö0ª¤Yp®f…|éÄ?¹âü² ܽyÜó5ë~'nßKÿWhÏ׬¸S´Ï•C4Kßy¹ëiß°!w‹èý0±eƒ½8|ÁþÄžöxø²óvØ›öµÏí\ŒÙËž–nÖù"Ø–nÉ{êñ[FsOš u¨¯ˆb…út‘pc£øßvàÏ%X_¿Ã^a=Ÿ³â×Ý^vöôyߨbÁ†À*nÆo9Ó©;[y|ð²ã&Â6ì<~Ó—½èÙç‹c8{Ñ´7`Ïgns¶¥ÉgnÛ£0Ìž’¬™·Å[ñ°óïYÑ>^œýèÃÎËC{ܰ¯ë‘NZ³M4|>xÙO6)Ô:µ«ŠöG†Ÿ kÛ±c­¯hg C;ÎÚýiÏzš,‡¿Ðר9àÀÁÞœ¯'°·ëÙR’ŒL'[¸Ç.|¦ûÿ‘®>[ÍÍüâ(Ò/¢Î\_hiðw(Hߢ”&ûDï881 ó”ýƒg½ϱ£ò'@ǺÑöó2±þ×€ÞUàÞ€Î"+yÖ>Û‹3·=Ç·þ±{cTÁ®® v,2ôYŸ±t·¹XÄ_Z(ØYãE<~éíÌ ÉÒŸõè6÷?ÇůЇñØ#Øù€Í_õ|ý² ØñçþèU/õì5ÇV¾þ¨z\¶*Ö—bÉÞd:­ÍÚ Ç²ï¯š9rc'û7=i¶yǾÄ+ø õ¿…ö®ç´õãüÂ͉C½x×s¦Óƒ-S?Ä;7þ~ð°³øéíK7T˜}‚ô"Ñ Õ›‚ô™Çe†t£Ò±iS¤_¤õ¾©‘}Öï…Ñ; ºYt’ÓÆŠõ¡0•Db¶Wö÷_õ÷„ õ;õçÝpQÂÇ^ý੤"}9_Í=/Ýø”‘^HçN”Ò £Š_Ú&sìó÷áv¶uý W/n_x\­`_³+ÍÓé‘Íh휙ýfÚËEf¯¡þ&}×óíË4âwÌÆðq0·¼ ¬Ìç¦êXôÔñ£²G=9ÒfÑÑ’fš¾ðõ÷Ø­jä9ýßXÒÌ_È6ƒ/tsÝÂ-ðe*Ùèû\¸á’½q†GÛ >7ë¹UÇ?òçëÙÍML^:ÇnK'ð<ÒÕ·•Íl_¸ñJÀærCÚ­7NÑë#¿}(iثֱ~›ƒltŠžÙòÞ¢ E<*rÞ_®óµª>êlnn.ZÙzÒ}áó`ÿˆMáé d:š4—{pw¡£á›i›Ë±·°®ÛðSW°ŸlÕä|Òœ¸]P°¯5²{á*¹Å¼—ç\®©àÙÎO±ŽDøGCø•=†ë8µŽtÔwÇJŽõ|ýÂ)R(i–l ߤ¸áKÁßõ™å’ v,{ôeÔXìX3;ØóÆg’.šK×/Ï— ,"ïÖ÷à5·ÿ3Å•[Ò<ÀÞ<ìMâKVȲ1Ä_-Üx™övàˌň/Üb·~që¬û6üæÒ¹”5¤£ÌÁ‘ž‡ð¸S¨¯8Ø59|r]÷¹y×óQkÓ­óì@‘¾²Ï‰{Pi/X‹(Ò—` ÿ@zŽfÅ™‰C½ÑÇfSÉ)× Ž¿›O Žÿ ;sÃ/™Òà?È ŽFM¾o£?£Pça¢©hð½¶¹›­]ç̳7§ðûWÒÌlv¥úXü Ö®ÏݪxÖñ#5Sšœì4\dÍ+Ö¹RÓ}.ëß³ÍWX7­üõ¬/<Áú$ñ7/ö»6n…[4ïÍU åÕÏ:òŠb-Ëë†3vÓz!¬Ó‡ÂG¤ÇpÖy*®××d»®3’{EgœcÙha/øµð^½Ì½zÖЬãñz¿VÑl›kzU¾g˜#„ÿh,·ç·ù ç`®—+Êwœ½xùO×/> Åy”Ë=£–ø`Úär… ÏV¾g¤ãS¬/:öHômÅžwmV±Ö¨ã®»¶m•½z šc@JV ß+¾zܶ-ØÚÿÌûÕ;ǯøZý¶¨ÆxÝöäÓ„ôço2"}ÂjÆ×ê1‚5”:’«žsœùs^ܱârT_tä ;w‰ìÇ-@œÚÙÕ:[âÚkÂù¸à_åaÓö@ ö5n&™ *¾M>^Á<.Úü[áŽ{€÷aαY´Sg§mƒyQ¸øÃ̱š1/œÞÌ;Il~é|iþéë…s ½è)mýѤç#VìYè–¸?¾œG¿Ì¾7æMáGN†úeF“]¢|¶Þ>XŸƒIôêñ†•3G½G/^µí…Ÿ$‡a~$ó¸ñ WVò‚ôîPÏ/úˆ£-…:{¬šM1/„ôŠt¾L¶7=G­ãïÇo]"ÔQ‘!P?V”úš~?Qs¢É§.#ç]y&+n/L)‡#óÂý½ÂOqöž“ Q,N– ëœ,iÕ{aMäGÖq7ð¾Bµ„¸NeëØaàm¹æ9UõûÉŽ¥ŠõÆ›§WµgïÑ~c«VúÆzWú…ÜÇ,æ²éÔ°cÇ¡Q/#ÿ\öª³o€%:e;øáõ ë^˜DØ"YŸ^Ôï;ÇC¼-бÎýD<ƒƒŽŸP_N¶î¨ì–d™NÍ­ ÖË? >+K(-º­:;ðj«Îj:¯à³M4–"õáŒÎfNú÷G{ƒ•‚ ö‘MKþØ÷§ÏvlÖ‡åbÅ(`ÏWm¼‰¨Oßçz¯°‡ïüü`£¾ãïÏJxü3vìì>;#v^— Ø›suþ¢Ø#ÔY¹öo,?\ö¨s­öf¿ñZÞtàœýÃåQ‹@§µ¸_]Gâ ÎOަVœ_ø(γEô‚Ÿƒ}‹åûÏW'|×¼~/,¢±y*Ç5=ê©Uà<«äšäöOyæÚõj5|/Õ9SÌqž3^rtÛ…µº"«}Ñ'ü©üEÏúÈ€"¿©Šô-vêãó·œßô õï{ÚWP÷«¬Íug¹B9s!¥Ö§ôî{—ú=:Ë-GáÿèÚ²×ÜÞ e}§ëzêR€}cïYyÔ9ñÑÀŽó ZXGž¨8—¨ï'vˆõœû0&ÉÒ|&~"ý_áB~Òs˜ÓŒ%«Ý·4}ÏÞÐìî™Â}fÇzÑÜgŠ…úŒ§²ŸàœµPÖ¨Ç;õÿ*Î9‘[‹÷&õQ4&é{ t$Œw>bmð'HŸq¦PðÝúÿw¨Çúˆ’C½Ø´53¹ ¿€õ»Õ£%Årf±–¹>’ËÕ{²Š}µÂ>|Ï@¿0ÇR ØBб>µÜ¶Œô"̉‚ôõÌaNëÄ*¯ŸH_N6&’Ü $ÇóøÊ+õ6‘˧«Óœb÷Â@rÂ&Üvê¬_¹ˆô—¢U¼£¬ÃuäSkÔ±Z1¨£ŽÂ°Ž-›ïE¼ ãÆÀþøÛŠWZlúž{uܰڳžCGÔÛ)Øw,ž ì,ÌÖg=IbÿíÕãTn’ýÌì|·d­z n›¾€^=´ñDÉÀÎ@~üζǞøp×»Î>#ú®gͰãÇKøíøÿñ|ûv²y‘}ªØõ‹MݾÀÇëÕl+·1¶ë ŸÒZ Ÿ“Ûª‡ýDÙ¢ÎåÆ ž³>;ÐLHböqmC¼hc›N{3—Ã×_±^ ý.û”Rx³ž‡r…ÿûˆ¢?ëA*÷ìÕñ¡5¤@ßV¾wמgÕÖ«'§©k>ú£]¶ 5úª³žåð‹ª¯:K«äUŸñáò>´=‘^ĬÏúéé¤-ÛBOÈÿ†tÖÁ½½lãѱ~Û²­xÕ³üÀ¦½þªXχ.j”­„os¼ht¬zõìra]hË6ú+Ô¼ž³ž¨õQçœÞ·¡>_ˆÿêÅQÛÎûe…z2‹Ý [h¾½¨¯•û K; ëøF:Öo:S_¢­\7„?+M£–Ëx¶þìËCÛ+[ƒ¾½[Ï’8òP°éRý™CÓXÙèÆ±¢—ŸÚüb(Ö‡/|Þ>èÖ£~\X¿Ç!üÔHàÙ‚ó¨gW¹¡^ìÛ8UY¡ŽßŒžõŒô±™Ì5Íú:±§¬"½iÖÓ©úÓÈ4—ðñ°ŸcAúÌc ïÕ‹ ¿< uVú³Îóö¬gSŠB.7gÒÐ ñ²SĬ‚GDü:wÉPǹ“Cý®)<›ú›\.!}ä¯!K¹÷+x®cê¼ÿõ¨ÂX–½¯¡a{dÅzÞ­óÌVÁΖ:v”½ØqP¡`ç _ûÚ€}äk;Ž?ìA/·n±3&y·Þ`½ÑàógXÇ:ã¯&sø9(ØÙEÊNÛÈîKQ8Må{uVU+ÔÇÇ+6‚gû°7's;›iØr=·ës¾vY8€^¡ÎÁ õ +=mcUC/}t2W¤8­ø¹» þõmÛVxÅò”µëM ŸŸuŽ/v¨ßTÁë¶“'Ž õ¥ñ€Ç9ŽA¡¥Pç¥azû0W¬>å‘mYIS,×qú+Xg›(Ò ó(ÖùNÀ°ŽÐR¬c•¡P?/hNeðE6ãV@}__Oæ¶Â,–ùÔ ÞØMáÞÓÌb‹À6~m>zÖ ¬³•”`}Å¥¯a7eoç«_l¦Lϧ®?±¾>÷3éŒõñ(åÌåõÄŸ>ìXì*ÖYÓ«`ÇQ…€ýBÂ``ÇÙ€=»ÅòUŸïÖóÉ û*™9E!šûÖ¼ÂzœÂ³7«`ÅοÛ"Ôq»åH¿k݆e†yS`©HçoŽ{S4HÏ’û»[´K4‘<ž.ÂY»doŠ éhQgÞчfÁ¹® áG,Ô èlv-@çÙ¯úа©¥_·q0¥Ý±fs .EÔrê;æÔãuÛœwëçêþêÖs»Žåƒý&¬ã+ê÷êqÝöx ÉF ï¬bßÙ·^ÖGýÄ3>­à3Òñ#}W/‡ã4ÓÁ'ÉùQåüÆÒN=nãmÕc2ãó—Œÿ ÁgMö›š¾íù^á<^·å¡ÜÊOß/±\‘õ€•§áqõ7.4Ç/·ê9éaÄZÅðùI¿§^¼pï0Që×EŠ¡=ã<ÂkS[ªÇ‘ܸãPÓp^HàGä[¾ŸÅªmYmÿnÕsí¾æ`ÆñXãƒ×ê3êª éM›^¼çGa"9ã­ÝŸmÕó®íœ?zŒVf6e,ǃú®í£N«÷ tüÙé9kyà#|Ãz´¦9æW±Î†T†õì{1Óô7ß ·¦È¡.+V±&Œ=âL.®Õg´Ë³â½¿ÂØ£q¡¹Ë~ÅÇÄ×êÙErFq‡UïM€SÑ©Ïøå±½z–Á¯OuU–Ð,LÏšÞõ#|Ù;õ1ªå¦±Øµì˜dî1—q`ãzíÔWs°ç{— ? «à·ô°w à¶z}¯~4c9,™ÿ ìÅXnÅ9¡ƒ½HpÂý¼%»°«Ä»Ë¶õ«Y¬_dÖ‹Û¶l:•ƒÄ–`}8p¥b–±ì’¢ãw„ŸßñïR¬|0õ>Öù|RösKûoÛpWéÒØæà%b}ÿbÇú]E<ŽÎ ëŒc}ØQeêE|‘íRhcWîîëg³l;Èoñ1nù™¡Ž¶JhpÖ£Pg#Dë׋‹uœ”Ù«q¾],Ì¢(à±×Ô7ýˆ‹¶ìË™×ö¦7.’I?ó´1-`Ž¿ã†råì;¡(/Vê•7Ež½Wñ«¹O8îmšõÄÅÖÛ.4…‰ä;õéܶfãÝ¡ÙÅfñ _{º-t UÿW=SxÀçc—ù[$ÿ èq£>ã*ܦrMüêÎÏþÿE¨ãoÙ¥r¹xgá¬íÙŠ³69[ªzv†>ðés°¯ø‹ö⽈ZƺÀâÚrñŽcÅ:nÈôE_ç˜â´î…aìTä=ly¥>Ž_89põL¾kãWR±>Ç7=nÔY¶`PgcwcœžP/VmwA­ßWÅîE+¿Žõø®#N ëŒbÊm|ø.Xßxüòæþñ‘eù̯¶vêØ·è~À>ÊÀžcÕ׉3;ìì-`ŸF 1°ó¤U#Û2Ö×ü®çÈ60{:c‘ãtàwYÁ>â<×Á~S§^MåPfi™m8‚ð‡½ÁGYìER˜‚}o¦rK í¬v~o³~µ_°ŸÙˆfÅìEËa…n`Ï^’+;šªXޝ ìÓů‚½Ø·y·¾ {|Úsh[ƒöBDsàÈMÁκ û]÷.Ct.âÏBE3á«äXS¹ 'eÁúɊןP_¾NÖŠ+Ô/SVÄg¬ã¿Yó#Ðó ë0`÷b»6öÖQU,ò©O©èY+w!bVœãߥ8Ï«¶lËñ±\!€oJø +æ¿zŽ|8¿ð¢Á_õâ†[qGz.áÙÇ@€>5úUy Hg :C:nC éQEÃ'¾ZÁã £¹¥Ñ\¬ë ÿXkܵM¯o ì8ºôG=¬_¾{±W3ø•ï¿ÞŽb}{iìmý:„Ü^.¬¯L¶X/Ö‹~=G±žR8«à/ÎaìØHر{³>Ì'Š ìb=Éà§÷d>œË2øê° O|íss±¾²%ç²kì<ņ=»ÆÎ¸ðuרìÉ4ö9±m*ø›lc—ÆJ²ÑpÛñ~òC>w'~¤[çÎ×Jø…YU±Î_0Åú8vÄŠI'Šõ¬ŽÅòI ¾ò…„mÖqJj;7,TMÖ§j ÏZJC:~à éçë—Òóeêy|_¼äw}Áo×_½ëX9Öq¥dX/\c¨GÏ©‘¯·ôYóeÛòø6ÑÍ`ŽÇ’õ8†ŸÈŠõ5Mæž™FëGö’\yHjXG‘¶ƒv̾±l¦¥`ÿv zöxÞ6ç䇵¹X/„4+¶¬®—»ÉsŠOB êø¶ž£™MI“±Žó k×3Ôñ7èú‚C]/à‹ã6¤9[¸ånùTëw|ŒõQç\tú6°9šNæØ Hëwl èç+ ô{zõe½z>nk`Žºþ„±|bá@¿É…†-7<¸- c™>^ÎÂØq) ÎÃuƒú€šrÓѰ æîØ­? ~Ë£Îæ„†õÂq*#+|ú<ò¾k ê(ëQ¨Ïs„zÞ¬g üÆ7ø>ƒ7&õ»fðøMv |Dz3G1……±bw£@_9“M€¾åܶåkžq!nòX.ÂÞ~ÔÑhL‘Ω=&ͯú„»+EúÈÓaE:3TEƒCTûã¥ÈS¹ Ç{ö¨¢YŽ`#¹þ3g¬ã^O°¾W©8Ê7¨ÿWïXñÃzß2w<®¡).Û ÍŠ?»aÿÈO¨Ï_á­~Ï@ÞÐÏ|³ ôܧ³¡ _ZÒób}aÓµ›B /Ã~¢6~ç¨ûŸ@?†b³~†‹õµp‘\”íU/Æï\nE6ø#»)¾_Rk¹ù0žø%|_Ëo¨"}gÝ« =ß«/W*n¿ó¹çÛ2x|‘¬|/Ì¡‘sëó0†õÂZnaÛpSËe¬O,7¬giì1àîJ°¾~›‡¾Âz\µ±\\°~TÖrM_¬Õo³‘l®Ûxö¾Z®8aÍÞã†õ B­jêÅ£þx(°<0¨cÇÿêTD¤s'e¯zºxyüþ°Æ0¤³T@‡røòÒqʪH_x¢ëKõè }Œ¨£4¤ÏéñŒuÅ>ÜÞD±õûшàqvð Ô ÃXüéÒ¼8x)§PGñþ£Îþ‰ôéÁ_˜WgHg ¤=êé¸5¶žþ&{Ó£|fÙ—ü¦³Eˆ½éù\}ÜðE¾^¤‘+Òw>W¤O(äoÃë÷xÇÊ_ÓŸHŸ^=;Ò¹K¨Ÿ8ƒöȇ›|$7¾`R¬ç,Ö‰[~Å:Ï ì¨|Q°Ÿœ `Ï%ü3%kBEûÖ˜Cca­hÇ=¶=ìùàe9â~cWg›Ë:ø ×’ŸpŸøÂ[ྠ|0åÉËq­~aü©pŸÎ×j¹µp‡æÚàÎÂ*ƒ{–Ëq𨥬oÈ©†vÖÇÚ›KÖ&eõVÃãße5ÙŠõÂM’ýë?Âg7É“Óü|Ï‚LÁ:Ÿ¿½uìÿìÎcU»;ÿkl,Ç6)ög8 vüj(ØÏ/üLì,®~ìÛ·ˆýØã ~ÃÕŒÍàY2ýØ›‡ý¬oÑ8öù®ç…ÛŽm¸a½‰}@3¬ãîJ±ÎfõûQ;cÍëM«Î™Fj&Í)Ä¡>.8|ù ‚G"T¨ïø,9Ô 3I^ ÔqYmïzÜ®ñŠuC±’èhø2ä×T./×÷&¤ñ®‹—ÂJ2'¬?å×¹Y/d4(È4 c³`ó÷|Æú”Á#õ¸GtÓ¬çW=Ïß±ÇV ãFJ€>°üÅ øèQ/7q| â|älÁùqbiÓ÷|۶͹Ug¬[Ž}¸Ø~t^%¹6ö®4VÄÏßs¿²-•íÚŠƒõâºíB_¥zq±>hílPÇ¡A=ZD? ž^N<óU°ç½úãËZ„9á‹m»¶l&ÙŒàÝz–Ì øR˜ ¿>&™ûѽ{\«³—=êM˜X~ÝÖáoZ¶±c„áódîÄ¿Ë*x'Øñ¸È&sXØ‹Åú~þrœMc`G”þûÉ K[¬çÑïÉ´„? 7Iþ®j³Ž›HÁúŒ¿?…úvqÚ§<«™´€Ço=ì[:dÍÑœ‹aXg{Ç:ª>ìÅ`É5ë…:Õàõ"ÑiÆœC=—ðÅ!ë…ƒ…B}cïƒ:ö8uœ*é»Îv,6…Hߣ„æñ‡Šó6‘Ôq§dPF’^½pœº°ê6%|nÕS§žm$YÐjC9vy7 ãvð} ßuÈÊ£—Ÿ8 ÉyÄ©“áÿ.Çy´¡™Øí\~á`ao:7¤ ôF‹5=éY@Ãë-:'ÉYýŽ-™ àqð¤@ßñU ³ÌF~n_ùMg£_«ç7}šRý>Äã¶'SõB*dzc+ß›eÛ}oz1€­úÌžŸõb¯ŽßSƒ:':è^½AúˆÜüéË›šyõ~Ò‹”Æ/×ôIçã\WÀÕ{Ü´Í6 ôãÂkKŸôl"yÌ(ä2Í”ÆrC>nÃa‘Ÿ±Vc¹Œtdî?»X/$4ØÌkõ¾5ªX¤WÀgs9N³Û¶ª|?ÙÕL±^¼êÑâàäŒwOÛVöÇü‰õqŸ°x2¬ãÕFðرêTŽÿT-·±ã¯Õ³͘%ðË÷'ú ìù´ Ÿ$w§h¤±|ih/L§n{ñ±>ágå˶æÚ¥˜Àã3j­zŽx™ñDzò½xÓqmú™|ÖÆ¹"ô#zËË%¡Mä ±ÜÌ£rêÂ*o=uY.ðuÙVÔï®èßr§W@Kõéß,§xPûþYÛÚ±ÞtDŸïÚ¢çÔ4ãÏåHo^õ¼Wß‹^}¬×êË×…†TÀ>â4Í4ðwxN=Àžü)Æ•OÄ ì‘$n솫j?XÇY¬'wvü™kìðº„_þ™ãž—öëÅb½zÔï’Ð4`Ç2ßÀΑ­vú3×æÔ æ.TÜ^ÂçÍ:·ýæ0WLæâ²må/Aû¼à˜ÞÝ$±—Ôž÷°‚vÞ’ùÅ:‡Ì+ÚùìØÐž=¢·ãõÅúòÏ”¯Û°>7´Wg¬ÅÉ ê‡þH/‡[X{Þ¶-ø¡Øñõw°GüÄDñ’±>Ž|R¥Xgz¶)|6ƒ/œc·˜æ´²˜W±>ä‹õÃ!l6‡¦a=ß¼<¯þ³EôÅfE-¢ñÿc™¬Çë›—¥pŽÝr&ëÞ¹If|eEƒ•ÑߘSŒ~Ã5¡çMÄ:'‹Ö‹ó¶ó¥| c·'®ö®çû6ìêøúiÇÎ¥‘Be­o/Üíx¼xY÷‹#^½Y/Yq²«Hß§øªçë¶h»óÁÞûSx>*ú«›u¬2ìUÇK¿Yo´±ÅÁK6šö¶<ÖŒôy@[¿Îÿ6…Ϲm¸°U¤óvA ¾Gƒ¹qf»e…ú‚<ƒzŽsš–ì».\šç+M¡¾„ õ¥0ŽÝðÞÚ x^þ]À7ö¸ ù{Š'ÔsýŽK¯ß‹'=ïÛ¦9_¼gÞ·M—[9:‹*ü¶-C?w+àñ¤PG ¨OœÁa¯:ÞþYÏvõ,}<긎´GÙÀŽÏ›A= æ¦|Ú–ãœöÎ\®p¢9ð¼ù¯°ÞÔïÅÅ ¶~à.íà'–­|€u¾«µú9þÝ“õÇ«Žgo¿êø± ÔdzxÕy­ù~¿àK§ð+·†uþ(þ¿ÍËŽ$KnD¿háñr-´Ó§ ´Ñ @߯LI(³>‘ÆLd´º›‹î®¬?Ø-×z%¢'oè~sÑH³÷è ½±Á“¡Ž³y†záF#›âøÑ‡ìN±ÞÌ)ëw¹†íeëªÇšŠgluž…ûnCƒÉŠ/·åš(êY€¿ŽQÔ÷™þuÖqöåeØóÊËç`gYIã:öB¾{!°ö¬À£:úÎMÁ6–7ª¾µÉŠŸ Ð~b‘‡hvì »Etaˆ&Ÿd3”vö;0aÙqa.Ã^àyŽD`ñúòÆ_½ï…ëm¼Ïb‘xª¿\\Y?Î=ï·íÖ±Òõ¶Ÿk|ÏPëmygýÚx)Ün«ì¬—ºmŸZdEPH_ØõÓ–Öñé± ¬Gt”6t6{•RÇ^ªOøí±Æ:‘Ú—lNÁã¡¿Q_òíežDUUŽof)é;iý&}oØ{°õ¸ô²´‰5,EýÈÓr#šmÓrÙ4–âÆ:Ö[°P/øMásñç˜/;ç±T_Ÿl}Ýœ…XåüFoÎ9DèÍz3 e /…í¶‚¹\¶Œ]°§`&4©©>|,S9lƒ«œcáb+ëhf£œŸääô}ð!>åC’­¬÷ç>4kÁ1–;žf8Åí‹W94|/¾tyyÏû. ã(ë|ëÉPÏ¥:Ïk ê 7±_ö¡™Û¶­6›ô˜žYÇÏYY/´ÚŽ9¶ÚïZP>4û„2½²Ž¼¢~ãäc¨|àW|ŸÔ‡æè1}Mu^?5ž•ÔÇ·²^‘à?5ßa}e×?¦›S;Â:¶Eõ>Å®úøŽ_.?ù³÷1áC¨¨óEÀ/­±vŒ£ÖQ°°Ž × ¤çü½ä"™@ŸÎPõ÷õ¦âÖ³;v·”tL†ô㚀¾Y‘ëŽ)èøVZLÇ×]ƒz–äNÐgüÙtnOhPÿIVž‘·ÚxåÁHço…çï©×6n6k¾ä9Õ±ê7ÒqzÍìåpÌI/ÌÀã7Ã`ç¼[¯>T`gÏoƒ÷“v1ÇØì˜êÚ¬\¬Ö÷ÿ¥½°Ø¶³WµÒÎWq5¬/q±í¤}ÁÄÑÂzÞWï?[3Ïh›m_¿°^±‚çÿISxœ1Úñ·þí˜Y ?½ÑŽAûõ¸Ž³eð(g¼ªÀŸyXçÍwëµU`ÏÕ:‡7­Ösg-aö†oªÂ>³Ã±ÂŽH…;S {»1×SØ+9ƒ=ûÆbËÀï>¼h²üÕÅ(ÔëÈß;°ó°„†v¾Ê&õÐ`ÏÆ±¬ñ)ì,ùkc½çÑØéÚ¡(ôÛØxÑh°c_@aÏý¶íÀÜZ`?Ã@ì·uÎM‡Ïí¶†øi?ól‚¥ñ…vË"–ÆÇñØìÛ?KãKí¶œÅ¯ØÚ3ÔQëyu.̬^Ïå:†?ï¬çã„’>óeE¡áé%P‹ê8y÷z½Že‡‚Î~wv¢‘þÛ*¦Áó) á1QÒyÌMI?ô†¢¤¯>ìáë‰y”à9Ëõó.]57ãÏyHÿÐ^[Nßô²Î:ÛMZ»­:¾ÿ zÙoêWðëî ÇfÛv`¿Û"zô–ãÁ=³‡ŽÙûùàæQ9¾ˆh½pÝeÅ?G9ÏW—¯ˆ^¸Ú¶cµ«Ë- sùj[F}<ðÿyõÊ +&ÔïtÖcò¾²·€Ÿ}¨ ^¹ð’›m•©ØB¥¾˜^êy,vãñW¢¶ç³k¬Q–+Y˱²é"|–åvL>½RÇGÂ:[(똬(ëÛô¼³¾üeɬc¤5o ž6´ìkh¥Žùé—ÂúΧ<^í¬Ïœè¾q¶ ST᳑äÀo¡µÖAn$Yìø«7‹è {œß'ÔUöi`‰í•zfS#»Ú†–7Üðñ±¸Îâ‹°¾aÕâúñ\‚_ Ñp?½\˜ãÛ–ÂÿQÇ é¨gg þ_ŒôÊ5§Ü[çýf—ËË.ç/£ñ˜–’^ˆêy_ǬRÏÇœÖ<-7-Xa輯§¤óp•Î#u®É¡ÆåQf%›¦Éý=ËBzÁË’7®9å»Ëã7`¾•ÀsûÔŠõ,¿w\Ï5ÔqÚË×XsPïIîÇýB}WAZHᱤ0Ø1&½ê½°j©Qæ_°/ÇÁÖª–ÂsÀÑrí‰d³m œ&°O7GŠm`Ÿxƒµ k¶Ï×X—‚‘ä@& öÊ‘—ÊÍR„GÅûÚ+°çj½°²¾ £.ÌÅ9ø¹rã¥ÕÙĔhòüvàGh |4—[ð­ë¡Óv’ÞКЅ¹B±žGc—Žðy±ž6Û®°^XbíX˜Øll=vÚ~6:þÂt,G"ôùHò&¾¾±C¦¢Î.†:ÖóÞVÏÍ6næÚ=ÖX«O× tî¶ñ7ÌÃz²¢lS¤s9¬o#¯·Åfž¡á–‰Â¾ò2”ÌÁ/qc}Yæ¾>6CÃCO{ÁºL{\ceÙÒiÿ ììãê°j½-iÜöJ ;[ŒìX ¼¼²¾ðæ‡MÇV"{vNw•öx~ùüvDinÍK/+š‰ÿ1V°ç‹¬;ÊŸÊúϬ/Ë~㣬㜤±nýgºñêq“•õy_8ûpsH3xN¾ØY}}6v«\_Æšõ { êmm=î·M×½¢B_ë9…gyJAÏÕúŒ½ «Öóíåóõ*žçà×|õaYVž91ž_oEC ²¾=ï­/{hžÖQÔ œÇ»ËãÑþ‘34£ÂnÚ\>ñÒ¹‹£°oùÔúŠ­~eý:œY¿)Ê4¬g“èüåNÔÓ.k›âvÛ|Ôn¬*ê…å6ühÞ!½¿ÇvÛÊkÆ9êÆ9þ6M—Ë”GÏ©«¯Ž©‘Qήß6›Ówn8 æøæü¦¼Þs>gï+Ž&(å“T¡|c-M0_Ç•Dż0ç9%Á|üd`Ï8[¬œ¡Ù² ï;çhT¾5ÏWø4¢ã‡¬ë#óS'=Fô…ÕuAj´¯~Ì…¾:û^{DÏ£±X' êXÚ)éÉEòLÞ¾¸JúVßy£Vã9Oÿ+é[¼Ùv’>0èé9 -¸S,sh6z§ÙV°œÂJô[æìh¹{Œéˆ9®ËïÒ1NXL/ Ž³ýž»ó‚œÎŽé za5ûÅn9uߨnXPß[A’ãÅ#C¿KrÉ~Y¶x^}¾®ŸæšŽïŠ¢þ3õó õØW?pÐçbK}õœ¼ãŸã¨ªLÇ–§¡ÎÓ1ÚiÃÔÒQÿH™¾°©m«ã‡è¶ÁCušÁs²ûÚͶ›8 °Ï͙ٞö>eQ®pôaïøw)ì캨q½WD¹•¯t˜(§åÆoÞ3أϭËà+ |l« õO)ðùÀ˧ãõŠ ö"_¶¡™9Ž*ë<ñëqO¸kl¡«^¨ÖÙ‹Easð+ SûÍÁVó¡AÝ÷õÈ^諯ƒMË\•+$ñqU•û™7y{ÜncMDM§ ¨î3\oþëÈŸwÁbÔÇå*)|a\ån9QgéΜ)0¥QЙã<ûM±oªpŽoœ`ÎÕŸ`¾°›‹5Ú =õ›_–ÀÇ øå¨$ð7æ½V«gÏØŸèg˜ÇÅ6Þ6o9*Wê…u—O9˱˜qž-hxÅÂD9lî¼!¿³†£÷sW½]û%Y–C)ßÓ÷<‹]SåâüÌ™å†Õ¶“õ‘ï«w6´ŽŠˆåïøöëÛù¢æù™•ö(ë¹§¾Æe—l=ð­Ôçšil¡¹øÊÑebë-g¹Ô§J¿â—ÙGh Å:ŽàÚº û¼¿Ömׯ&Õ&ÁWòwÌ!¬XÏù;»½ ì|õ\`o¸2SÖ±’|¹µž–]Ö ÷~£>~ä\‚ǯªFu|—uõȳrëv3¬¬ã\™_xÉVðËšZëSÜlyˆæ Ù_®ÐZïg-\iÄ7ã;îÐ7³¡>_Xm+í±æÕ¶)›Æâ ’Kð9¦c髜sÆüªüÎçú”ôd8µŒq`–fãr…µ¶ss›€Ç¿KI߸hõlCÃQ=;SL…½¶ÔX?ó÷Ò´\!ßð1pÐ?ÕY¯œmc—HÍßK·œ2è3~Òæ$™gh #4ÜÝÎ÷ʬ.…Xòúžån¼‡4¤³7ŸÏÅ@/mµEЗ£âL±HgWF[VÉZ.»C³+¡)ð,k¾.Ë•¶Õ?F:6ÿLƒG‰ÙÇå*¤Ò÷‚5EaY½2A3¯l‡ °ó(øëÙ;f! ;ŠWZ©£.¥A_'ê…ÉØl»²–¦¬/ì"ZPÏ17|Ñ%ÍÏdsh^[2Òù6Žoº’÷‚þŽeñ ü²[H/mão¶Ušê…³ËX:›Må´ËÂpY¡Î5M” ¤¬u¼Ö'ü¾‹(7µ‚þÞùB¸Šrøwéº &hþ>U޶…ëìàg |€}ÎÖro—xXϰ‰Ïøj· Õþ/UêlaäÞrQ€_ÙËÛhÇ‘C£5¥­òöÒÂúÎj*ðy4vCKiÇRSig“:£=­¼ŒÑ0(í|ZÑW^â%§/+þ1-[ëmÂ1R£=ï«)\m›³¿\›ð;hå:&úïÐ^™£ÁTíÚ±¾³$ž­'”öÜZ_Q†pØ GÖñϱí¶Â=Ö™+mc½°®Ži„²Žmƒ—YoØ WÖù˜­·U"{^Wßø æc4áÃl{a¿§õìCs~€¼Û§Këy<ö˜0¼™8ן›SÌ{9^ôÞzi<¶°ßVñ¡ùX¿Oñýb}= ÑÛ*oŒÌჵÖù2‹ >UÔ¹‰«R/Ù ¬#¦ ;Ö¤ {®SKDzChß* n<Íu*Ñä$~ÞKwÖ ®±¨i\ÿ±gzÆz^o‹—NÖqœ×rø :VÐßRáyVBçå >’r|}“ëH3œªÎ×[t:öÒùm~Ñrê`ÉUIg[T!}idnì•z½2 ¿`¥dêþ“Uˆï7v[†z¡½Žßz³¨Ha=Ú˵–Gáo—z¹Îs‰B;ïâ«\Ï÷œ®9¦ð{a¿mÅ„ÙhÏa¥0Ïà3ëOÉYƒKzg=õÜο,js(a}à¿Fsx>)ú† *0Âú΃ ØÑ6YqRËëõØ`?~VžÁ ææ¼¶~~á ¬c(ñr½Âú‡n¼ ö÷×rûŸÊú{gÆ:jÆ:&GV®‡®ÛÉ:Û=8ì|ÖAaçSC¯Ãžì}É÷×LˆÇç[açcªæQYïødhß+åzÁyê˜p<ÊPŸSÓ-z̵9o³.œªüÁ:–IÊz¡ZÇ÷ô;=·«‚I¨oSE™Ã:ÈPÇþŒm¸å°^9òÒâÊËü¸±xñÐúÁb¾©ðq>ö¬Õé_c o¹Vï<£- swF@çSŽJúÂWCL„Ï ó‘æï?›âÏ@Ýuùµî:¾ì:_‹9üü¾5JWY×£Ònë¥~}y t\ 1Ð §—bSàoºôŠzE–‹V4ÇEfE/›k±žQ?SáœÀs)e¨ç½õ71õ$ëÂ3fÕ «¬<ã¯Q½…Yø9›Ì |<çtð"ÃŽ¥”Ý~¨„õeðØ31Ú³¡äÊg[­X/˜T`†jÒJ…vg=öÛÆõˆñŸ¤´ó¯ÕDø;RÝoÃ_YGÑH…¹¹b(‰o¡åïùNcŸP’Ô¸>ñ –ëìd¬g~„eÖ9{̵û[~쩯 <~€_ ì|ÚPG¥Â2x>ïf~ð…Z=’Ζ“¶ÊZ™]yßÎHg¹ÕÌcs­ž·íanÇ‚BYgCß|ÉCs|ŒVYgÁZYŸ…»øëÒZ=ß^[,ÕÓ0|c—rêÙfL…Îzi`îS ã·ËczÜzÙf̼½T¯dð¹Tç vUà n!VÐYó~õšÓçßl>úN-|Õ\8_~:Æ9î[þ—^zÇéOżd1·æ[NGÃÑ ½§¾z´˜k „fËJ­‘Îq_Ówü õì;ÕØ ^Q_°úSÔÙ%ÅQ&s3Ÿ-µ¨‹õöàNE½cÅê¨gY.{Dï+ï«,m§NÒ1øùplŽé|yRaçiK7„G-¨³çˆÀ>c2§µúOÿæ ìÑdîZÊËaç^=¬§nÛe3ZX{A±ì­>uÛÖ›¶°ÁŽËr;Jù{¡µŽ ñ—%ø}céW`g*,/,½d]n˺\Ç @ëkáHãVðbÛ$c§ýÌzas}åI ì(£šŸJõh1w–êñôr¯ið…š‚AÖ6_ÙxYG!_Ju¸«r±Vo¼qf|åBãÍÕV!}Ën4;¯?Údlëim}éÑ ~ÌsÉ86×éøÑXŽo×éXK)ç­Ó§Ó÷¬g gý=Æ^ÇXK¥zž ás;Žú§ôw®Éõ¼Êº5üÁÞØnˤwî¤é‘—‰õ™/Ó(é7 ô,Ê!6ŸxÞ@UÖùëc¬|§øÐ±ÂŽº€²ÞØvØbzÖß f4#yIÎÙ_®±Ÿ¾¡^8ÝVhµõ¯‰êÞjµÅÆú¢éï8Öâ»m…ô•ae}+ôÚ*ÆS+—µÆ:ïwëéLãMãåb}ÇlNXŸf¬5=Ï34ì…hC4ØbÕÆú¸é3¾jö‚!ÍüÜMrÎ&s}Í„ö½²ÉZPæNÚqâÂhÇWãbs5)Ös¥Ž‚‘Uê…˜ž÷]øÐ‚ ð•N[ço—‚^©Ô+49{/ôÙâ²Ë4£~l3±HŒ`Þ[s6Ôõ©X¬9|>ZÑ ŸJ êKà£Ã\óŽí”?Òw| 4}Ç:ÀcúÇÒ÷B¥ŽÒ@ÇXì’\¡RGU@Qç@bù{œ€¿Ž4ÞT¦ÀÇÁØËHSåëon ìþè {Ãï˜ÍÅæ˜Þ9MsQ.úNñ¯°í‚sp>››mÖs[=ÎÊ]7 ð_T éø2;ìºètàWÙaÏ <ë„;ÊA{a„&³žü¡¯%Vv·¶:v“Œô‚éþTŠ:¿ñ‚úŠõêoÔ¯Ó€Ó)Ö5®çuõ>²ÅÜÒnz:[HßyçXYÿ)nYo™s¯ —©Ü#º€:–™¿Q¿œs*Û.ºç„Ê”uÚ°Á£¤³C‘‘^Qå°û ¥:-t*6‘>0ÌZ@ÏÓ3;a=_rÊç]–9îª÷Î' ó3³Œã3üƒ å£aê«ê¨¨µ\㮨vÔñϱ‰Øé¹ÝÔIyl³a²có!,£×”r¶[üåhì±s>Ñk˜Wì¡1SÌž«Òˆ^~ÇBÁHg'`#½Ð ‡œç ‹(á|ði*å|F5W9ç¹}ůŽî©·B¬ s»À@Ï»«?®:Ï8»«þ=¶ÒV™œi¼!¥ ãðK]6>Aa4lûô½î«óqOg(Lzçp­=µÙ®=õì*wæî¸|â¹{®Òñßlk.9¨óÜ¿æî=·ÔǘÀ¾å¨~à˜€zH®¿XvæSÖ×ì+wìûóé÷Vp‡fC=ß_­À[êûƒOkx™þ!Ö+×±>RÖy±ÄXÇc Ôóu—6 ç]ø.„m´ñÅ?ßhÃ\MYÇTíëcº9g¤§œ²þ¾` UInÅçÛXçÀ$¬N9< &°ï_©WØwöýع½ª°ÿ¬û?ƒ=ÎÏl•:å6ƒ·„öƒ›Ãþ©øŠ·_TÚQ<öÈNŸ¢Göx‹µq†`·Xs©ÞW¾ÎlËêš´ë2®aÀžg如ÍØsµŽ‰¾²Î#6Êú~sòBYç ØÊ:&,¿Xïi^ŸÏ¿·l"Ùø²”öŠþÎ1Ê:Ê&ßi©w>†â>’qW}_0åsÖ³þ[mç»H?¼Mk¨¯7¢ŽýA÷š Âܸù¹¬­žQŸ1ÍׂÕ2+Øó‰õ¾åËmGÇgEYßøä´æð¼†¨9ãÍ1å|.Ügdïãß%we-¦§¥¶qÍ pçÝX ãïôœ\ÞsáãóÒ¬8”ó†-¯ÕsþÎ==-Öw^ QÐù³‚Îs$š¿÷¿w„Ÿ¡X7üRXLçEG=)s[Í-÷<ßa§Ü>Wënœõ\­¯ùèòÄ.ùvtë +×§g´t«K.+׃ üÖó}—È: ãV«¯q§íï…ô=ërü<©Ó§5Öy†YYÇh¢¬G>C³I®·Ô+Qu0C¿¥Ö?Czéy£ÏZæ^€<éÛ Ù½¶ ä+·4­ÕÆVé6%G?™BŽ ! yt™âh­K.lZh™;/d å§b”rÞnÕÌ}-)r<ã¬U: ¨šº·°¥Þ –Ðl=f˜—zÊÝ·’úÎ@oôBòŽÙƒ‘Žr‰Ëï…äÿ=Ê:‡Xed†ú²ó1›Ÿ)žÃ9Ê[¶¥ž]¦xÛÊXÇÎŒ³žÛêýÇ^e½·Â–zÛóiƃ]+ÌúH­¶ìÉ©Œeï˜ZýÑjKêûVq”ãÃgï°Î¯·ÞaÍó3ûV°ŠÝñÛc¬ãã­± ô—ÔG¿3ñ˜^9ê’IÊ{Ç÷]Çg¢›\_>q&¼³p¬œãô/Î/Ñ3{¿÷3=ÍœsÛ8ÂûÜb‘Þâæêž­ßçæ©¡¾=ø°‡ôÏôØúĭſȊùŽÄ0GÃCzVÞ9‰UÒù1=ŽK#=ÛQl¾ƒJzáÊÜ—\þMÂúÖ°–0Ö³Klg-e}Æ7CX7G=õ<Ë©®°~=†‰õ¸·Ú£IìÕd«äïyx¦aë¬ªÇÆ÷³³¾=ðË£¬óµ2cßwc!µÝUÆÂz<¶Ü®جÆñeG=êíF”Ô±¢UÒ1Ò÷%Ÿyy&vÄ—ó3žòèLï7œ€Ît)éìð­Qýgýâé¹^0‰åÜgbcPÇjÖ9ÿTH/Ü^VÐ;;ßz'½¢ºç"=C>ñeŸ‘[ØkV7Ô NXÈ›—5wúp~C>¨ äsC!ÜD÷¼Ÿ¾`¯:{®im)¬¬6žTTÉÿ+ÐÃ-—Vp‚f?Ms¡ÀïßËãqÛƒÇjóOqÎ΀f9ç•që®aĽ»Æj¹rO,_™;¸˜‘S¡+.5އ¿eî}‹sïó‘—Ùæ5{¾®”õƒ–õ×ðÇò^zÞÙþÎXÇ]sœI¨gËH®/mh¦4 µ¸õü¡*Uú§PöR×ÔLt‡Ý÷ÂÎêŽÖË^¥Ç¹÷‰Wó5sÏËlƒÅ#½°µŠ¿.+ÑóÖ*ý–¶'ѽ·±ä´}å?m£ãߥ:¯Ûø,†-+Ð œoù¸Cqä}ŠËl{¼¹z&î<ý:裢º¬ÃƑķÙòÌ [ {‹­²Í–³÷Œ…ôÂzzxç™nÿ-Б-›‚Í.lK&¨O…SêceÝØ¶[Bö~éîø%ôýôÂÄ{ábÓÁ+]ºŸ>T¢Oq•­#Æ&Æ¡QŒ¡žÖÓOÐ %:–—ïp^ZdËÉû‰a^ð‹ÄOP)ç“WBy¾×t­¶dÌq„À0Çï±bމŒVÎG\ØYÐjtÔJó‚×Lç#*ÄEÈ·ãæ'È °{¾«Ü—)5ײ4šiYÚŽEª#žÆeά;Í9>ýo@Ξyœ–é ãƒ'í…PŽY“BÎ-(|ØÄÝ(¯Œºóùƒ×Üf.Îsk‡!_æ|à«£œó˜‹‚~$ÿ竃™:ô…Û5Bú|³…¤¨£`z¸ÖÔ ÐŸ;¡^¹Ö4óéNUã°©°oø¾{<à²5>ï´gØñ›ú:ì=@—›kÁBîfVÖ.0Æ[«;#¨°ãG(°|CYÊ:Ä ëy-}ð¸Ÿ‘Ž¿+!ý¸Ñ”ôwh|U5ZEþ¯^÷wÒÿï?ÿú׿ýû_ÿöOÿòÿý×ûÏÿúë?ÿkÚèØ|Ø XML/inst/exampleData/longitudinalData.xml0000644000175100001440000000301613607633706020152 0ustar hornikusers Gender History "MALE" 16 100.425.2 "FEMALE" 16 100.425.2 "NA" 16 100.425.2 XML/inst/exampleData/simple.plist0000644000175100001440000000052313607633725016514 0ustar hornikusers A100 BCDEA string with content other2007-02-05T10:46:04Z XML/inst/exampleData/plist.xml0000644000175100001440000000146413607633725016030 0ustar hornikusers Year Of Birth 1965 Pets Names Picture PEKBpYGlmYFCPA== City of Birth Springfield Name John Doe Kids Names John Kyra XML/inst/exampleData/event.xml0000644000175100001440000000107613607633705016013 0ustar hornikusers

    2003-05-23 1 3 2003-05-24 17 24 http://mtadss01.mt.att.com/nlslogapp/displaysession.jsp?serviceid=esc018&sessionid=2OLhD6ZX&dat+e=2003_05_23 17 24 XML/inst/exampleData/lists.html0000644000175100001440000000123713607633706016174 0ustar hornikusers

    First
    This is the text for the first element
    Number Two
    Here we have more text, but for the second item.
    1. ABC
    2. Def
    3. XYZ
    • ABC
    • Def
    • XYZ

    Duncan Temple Lang <duncan@wald.ucdavis.edu>
    Last modified: Sun Nov 11 12:30:07 PST 2012 XML/inst/exampleData/tagnames.xml0000644000175100001440000000041013607633725016462 0ustar hornikusers XML/inst/exampleData/author.xml0000644000175100001440000000041113607633705016164 0ustar hornikusers Mark Twain XML/inst/exampleData/9003-en.html0000644000175100001440000000052313607633705016025 0ustar hornikusers BKA/RIS VwGH - Volltext Veröffentlichungsdatum XML/inst/exampleData/writeRS.xml0000644000175100001440000002250513607633725016273 0ustar hornikusers ]>
    &R; Output Format using XML Duncan Temple Lang The code here defines a mechanism to create external representations of R (and S) objects using XML. The idea is to allow the objects to be shared across different systems, specifically &SPlus; and &R; 0) return(writeXML.object(x, con, ...)) name <- paste("writeXML", typeof(x), sep=".") if(exists(name, mode="function")) { f <- get(name) f(x, con, ...) } else if(is.integer(x)) { lapply(x, function(i, con, ...) { con$addTag("integer", i); T} , con=con, ...) } else if(!is.na(match(mode(x), c("integer", "numeric", "character", "logical")))) { lapply(x, function(i, con, tag, ...) { con$addTag(tag, i); T} , con=con, tag=mode(x), ...) } else if(typeof(x) == "NULL") { con$addTag("null") } else stop(paste("No method for writeXML", typeof(x))) } ]]> Given the default mechanism for dispatching to the different functions specific to the types of &R; objects, we now implement the details for these kinds of values. 0) tag <- ifelse(isNamed, "namedlist", "list") con$addTag(tag, attrs=c(length=length(x)), close=F) for(i in 1:length(x)) { if(isNamed) { con$addTag("name", names(x)[i]) } con$addTag("element", close=F) writeXML(x[[i]], con, ...) con$addEndTag("element") } con$addEndTag(tag) invisible(con) } writeXML.object <- # # Writes a general S3 object, i.e. one with a # non-null class() value. # This just writes out the names of the named # elements of x. # Doesn't handle non-named lists yet # function(x, con, ...) { classes <- class(x) con$addTag("object", attrs=c(type=classes[1]), close=F) for(i in names(x)) { con$addTag("slot", attrs=c(name=i), close=F) writeXML(x[[i]], con, ...) con$addEndTag("slot") } if(length(classes) > 1) { con$addTag("classes", attrs=c(length=length(classes))) sapply(classes, function(x, con, ...) { con$addTag("class", x) }, con, ...) con$addEndTag("classes") } con$addEndTag("object") invisible(con) } writeXML.closure <- function(x, con, ...) { is.missing.arg <- function(arg) typeof(arg) == "symbol" && deparse(arg) == "" args <- formals(x) con$addTag("function", close=F) con$addTag("args", attrs=c(length=length(args)), close=F) for(i in names(args)) { con$addTag("arg", attrs=c(name=i), close=F) if(!is.missing.arg(args[[i]])) { con$addTag("value", close=F) writeXML(args[[i]], con, ...) con$addEndTag("value") } con$addEndTag("arg") } con$addEndTag("args") b <- body(x) if(length(b) > 1) bodyLen <- length(body(x))-1 else bodyLen <- 1 con$addTag("body", attrs=c(length=bodyLen), close = F) writeXML(b, con, ...) con$addEndTag("body") con$addEndTag("function") invisible(con) } writeXML.language <- function(x, con, ...) { if(x[[1]] == "if") { writeXML.if(x, con, ...) } else if(x[[1]] == "{") { for(i in 2:length(x)) writeXML(x[[i]], con, ...) } else if(x[[1]] == "for") { writeXML.for(x, con, ...) } else if(isLogicalExpression(x)) { writeXML.logicalExpr(x, con, ...) } else if(isComparator(x)) { writeXML.comparator(x, con, ...) } else if(x[[1]] == "while") { writeXML.while(x, con, ...) } else if(x[[1]] == "break" || x[[1]] == "next") { con$addTag(x[[1]]) } else if(x[[1]] == "<-") { con$addTag("assign", close=F) writeXML(x[[2]], con, ...) writeXML(x[[3]], con, ...) con$addEndTag("assign") } else if(x[[1]] == "repeat") { con$addTag("repeat", close=F) writeXML(x[[2]], con, ...) con$addEndTag("repeat") } else if(x[[1]] == "return") { con$addTag("return", close=F) if(length(x) > 1) writeXML(x[[2]], con, ...) con$addEndTag("return") } else if(mode(x) == "call") { writeXML.call(x, con, ...) } invisible(con) } writeXML.if <- function(x, con, ...) { con$addTag("if", close=F) con$addTag("cond", close=F) writeXML(x[[2]], con, ...) con$addEndTag("cond") if(length(x) > 2) { con$addTag("action", close=F) writeXML(x[[3]], con, ...) con$addEndTag("action") } if(length(x) == 4) { con$addTag("else", close=F) writeXML(x[[4]], con, ...) con$addEndTag("else") } con$addEndTag("if") invisible(con) } writeXML.for <- function(x, con, ...) { con$addTag("for", close=F) con$addTag("index", close=F) writeXML(x[[2]], con, ...) con$addEndTag("index") con$addTag("elements", close=F) writeXML(x[[3]], con, ...) con$addEndTag("elements") con$addTag("loop", close=F) writeXML(x[[4]], con, ...) con$addEndTag("loop") con$addEndTag("for") invisible(con) } writeXML.while <- function(x, con, ...) { con$addTag("while", attrs = c(doWhile= (x[[1]] == "do")), close=F) con$addTag("cond", close=F) writeXML(x[[2]], con, ...) con$addEndTag("cond") con$addTag("loop", close=F) writeXML(x[[3]], con, ...) con$addEndTag("loop") con$addEndTag("while") invisible(con) } writeXML.symbol <- function(x, con, ...) { con$addTag("symbol", as.character(x)) invisible(con) } writeXML.call <- function(x, con, ...) { con$addTag("call", close=F) con$addTag("caller", close=F) writeXML(x[[1]], con, ...) con$addEndTag("caller") # Don't make this a x[2:length(x)] # or x[-1]. Infinite loop results. argNames <- names(x) if(length(x) > 1) { for(i in seq(2, length=length(x)-1)) { if(!is.null(argNames) && argNames[i] != "") con$addTag("namedArg", attrs=c(name=argNames[i]), close=F) writeXML(x[[i]], con, ...) if(!is.null(argNames) && argNames[i] != "") con$addEndTag("namedArg") } } con$addEndTag("call") invisible(call) } ]]> ", "<=", ">=", "==", "!="))) } writeXML.comparator <- function(x, con, ...) { logicalTags <- c("<" ="lessThan", ">"="greaterThan", "<=" = "lessThanEqual", ">="="greaterThanEqual", "==" = "equal", "!=" = "notEqual") tag <- logicalTags[as.character(x[[1]])] con$addTag(tag, close=F) writeXML(x[[2]], con, ...) writeXML(x[[3]], con, ...) con$addEndTag(tag) } writeXML.builtin <- # # for primitives # function(x, con, ...) { con$addTag("builtin", attrs=c(name=getPrimitiveName(x)), close=F) } writeXML.special <- # # for primitives # function(x, con, ...) { con$addTag("special", attrs=c(name=getPrimitiveName(x)), close=F) } writeXML.environment <- # # for primitives # function(x, con, ...) { con$addTag("environment", attrs=c(name=getPrimitiveName(x)), close=F) } ]]> When writing out a call to a Primitive (usually only in base), we need to know the name of the operation which is being called. This function is a simple call to a &C; routine which gets this name. Now we turn our attention to providing the low level mechanisms to gather some of the information that we need to output the XML representation of the R objects. There is no (simple) way to get the name of the primitive operation being called in a .Primitive call via user level code. Instead, we must use &C;-level code to get this information.

    The code is simple. It consists of including header files that we need, using some Defn.h that are not in &R;'s public API. This is not an issue here as this code will eventually be absorbed into the core, track the changes to the internals or simply disappear.

    The hear of this routine is simply to create a character vector of length 1 and then populate it with an entry which is computed by getting the name of the primitive operation specified in the function call given by the obj. SEXP RXML_getPrimitiveName(SEXP obj) { SEXP ans; PROTECT(ans = NEW_STRING(1)); SET_STRING_ELT(ans, 0, mkChar(PRIMNAME(obj))); UNPROTECT(1); return(ans); } The following are the list of header files that are needed by the &C; code in this library. Note that we require Defn.h to access PRIMNAME #include "R.h" #include "Defn.h" #include "Rinternals.h" #include "Rdefines.h"

    XML/inst/exampleData/malformed.xml0000644000175100001440000000016313607633725016636 0ustar hornikusers This is intentionally malformed XML which we use to generate an error XML/inst/exampleData/something.xml0000644000175100001440000000012513607633725016663 0ustar hornikusers

    something

    really

    bar

    simple

    XML/inst/exampleData/foo.dtd0000644000175100001440000000217413607633725015432 0ustar hornikusers XML/inst/scripts/0000755000175100001440000000000013607633730013404 5ustar hornikusersXML/inst/scripts/RSXML.csh.in0000644000175100001440000000025313607633730015415 0ustar hornikusersif(`test -n "@LD_PATH@"`) then if(${?LD_LIBRARY_PATH}) then setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:@LD_PATH@ else setenv LD_LIBRARY_PATH @LD_PATH@ endif endif XML/inst/scripts/RSXML.bsh.in0000644000175100001440000000015013607633725015414 0ustar hornikusersif test -n "@LD_PATH@" ; then LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:@LD_PATH@ export LD_LIBRARY_PATH fi XML/inst/COPYRIGHTS0000644000175100001440000000034713607633725013343 0ustar hornikusersCopyright (c) 1998, 1999, 2000 The Omega Project for Statistical Computing. All rights reserved. All the files in this directory and its sub-directories are released under the GNU General Public License. See COPYRIGHT. XML/configure0000755000175100001440000054224114636531034012654 0ustar hornikusers#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='' PACKAGE_TARNAME='' PACKAGE_VERSION='' PACKAGE_STRING='' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="DESCRIPTION" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='LTLIBOBJS LIBOBJS ADD_XML_OUTPUT_BUFFER SPLUS EXPORT_MEMORY_MANAGEMENT LD_PATH SUPPORTS_EXPAT SUPPORTS_LIBXML PKG_CPPFLAGS PKG_LIBS XMLPARSE_INCDIR LIBXML_INCDIR LANGUAGE_DEFS LIBXML2 XMLSEC_DEFS XMLSEC_CONFIG UNAME DUMP_WITH_ENCODING EGREP GREP XML_CONFIG PKG_CONFIG SED CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_splus with_oldlibxml with_libxml2 with_xml_config with_libxml with_expat with_xml_output_buffer with_xmlsec enable_nodegc enable_xml_debug ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-nodegc enable node garbage collection --enable-xml-debug enable debugging information, primarily for memory management Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-splus Compile as an SPlus library (rather than R). Value can be the (fully qualified) name of the Splus script. --with-libxml2 indicate that the libxml version is 2.0 or higher --with-xml-config the name of the xml-config program to use. --with-libxml use the libxml library (default) --with-expat use expat library (off by default) --with-xml-output-buffer use ADD_XML_OUTPUT_BUFFER_CODE (conditionally on) --with-xmlsec add support (experimental) for XML security with xmlsec. Specify no, xmlsec1 or xmlsec1-openssl Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --with-splus was given. if test ${with_splus+y} then : withval=$with_splus; USE_SPLUS=1 fi # Check whether --with-oldlibxml was given. if test ${with_oldlibxml+y} then : withval=$with_oldlibxml; USE_OLD_ROOT_CHILD_NAMES=1; FORCE_OLD=1;echo "Using old libxml names" fi # Check whether --with-libxml2 was given. if test ${with_libxml2+y} then : withval=$with_libxml2; if test "${withval}" = "yes" ; then LIBXML2="-DLIBXML2=1"; USE_XML2="yes" ; fi else $as_nop USE_XML2="yes" fi # Check whether --with-xml-config was given. if test ${with_xml_config+y} then : withval=$with_xml_config; XML_CONFIG=${withval} fi # Check whether --with-libxml was given. if test ${with_libxml+y} then : withval=$with_libxml; if test "${withval}" = no; then USE_LIBXML=false; else USE_LIBXML=true; fi else $as_nop USE_LIBXML=true fi # Default is false for expat since we can # do event driven parsing with libxml. # Check whether --with-expat was given. if test ${with_expat+y} then : withval=$with_expat; if test "${withval}" = no; then USE_EXPAT= ; else USE_EXPAT=true; fi else $as_nop USE_EXPAT= fi # Check whether --with-xml_output_buffer was given. if test ${with_xml_output_buffer+y} then : withval=$with_xml_output_buffer; if test "${withval}" = "yes" ; then ADD_XML_OUTPUT_BUFFER="yes"; else ADD_XML_OUTPUT_BUFFER="no"; fi else $as_nop ADD_XML_OUTPUT_BUFFER=no fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "${USE_SPLUS}" ; then # Allows the user to say --with-splus=/usr/local/bin/Splus5 # This could be fooled, but unlikely unless the user does something # "clever" if test -x ${with_splus} ; then SPLUS=${with_splus} else SPLUS=Splus fi # Get the major version of the Splus being run. SPLUS_VERSION=`echo 'cat(version$major,"\n",sep="")' | ${SPLUS} | perl -e 'while(){ $x = $_;} printf $x;'` # If this is version 3, we are in trouble. if test ${SPLUS_VERSION} -lt 5 ; then echo "This package does not work with SPlus 3, but only SPlus 5 and 6" exit 1 fi fi # end of USE_SPLUS. # Check whether --with-xmlsec was given. if test ${with_xmlsec+y} then : withval=$with_xmlsec; if test "${withval}" = no; then USE_XMLSEC=false else USE_XMLSEC=${withval} fi else $as_nop USE_XMLSEC=true fi if test -n "" ; then # turned off for now #XXX get the redirection correct "$R_HOME/bin/R" CMD SHLIB testRemoveFinalizers.c &> 6 if test "$?" = 0 ; then $R_HOME/bin/R --no-echo --vanilla < testRemoveFinalizers.R &> 6 fi if ! test "$?" = 0 ; then echo "No ability to remove finalizers on externalptr objects in this verison of R"; EXPORT_MEMORY_MANAGEMENT="FALSE" else echo "Have R_RemoveExtPtrWeakRef" ; PKG_CPPFLAGS="$PKG_CPPFLAGS -DR_HAS_REMOVE_FINALIZERS=1"; EXPORT_MEMORY_MANAGEMENT="TRUE" fi else EXPORT_MEMORY_MANAGEMENT="FALSE" fi for ac_prog in sed do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 printf "%s\n" "$SED" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$SED" && break done for ac_prog in pkg-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PKG_CONFIG" && break done if test -n "${USE_LIBXML}" ; then if test -n "${XML_CONFIG}" && test -x "${XML_CONFIG}" ; then USING_USER_XML_CONFIG="yes" XML_VERSION="`${XML_CONFIG} --version | ${SED} -e 's/\..*//g'`" if test "${XML_VERSION}" = "2" ; then USE_XML2="yes" LIBXML2="-DLIBXML2=1"; fi echo "User defined xml-config: ${XML_CONFIG}, XML Version: ${XML_VERSION}, XML2: ${USE_XML2}" fi LANGUAGE_DEFS="${LANGUAGE_DEFS} -DHAVE_VALIDITY=1" if test -z "${LIBXML_INCDIR}" && test -z "${LIBXML_LIBDIR}" ; then if test "${USE_XML2}" = "yes" ; then if test -z "${XML_CONFIG}" ; then for ac_prog in xml2-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XML_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $XML_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML_CONFIG="$XML_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_XML_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XML_CONFIG=$ac_cv_path_XML_CONFIG if test -n "$XML_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XML_CONFIG" >&5 printf "%s\n" "$XML_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$XML_CONFIG" && break done if test -z "${XML_CONFIG}" ; then echo "Cannot find xml2-config" exit 1 fi fi fi if test -z "${XML_CONFIG}" ; then for ac_prog in xml-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XML_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $XML_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML_CONFIG="$XML_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_XML_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XML_CONFIG=$ac_cv_path_XML_CONFIG if test -n "$XML_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XML_CONFIG" >&5 printf "%s\n" "$XML_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$XML_CONFIG" && break done fi if test "${USE_XML2}" = "maybe" ; then if test -z "${XML_CONFIG}" ; then for ac_prog in xml2-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XML_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $XML_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XML_CONFIG="$XML_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_XML_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XML_CONFIG=$ac_cv_path_XML_CONFIG if test -n "$XML_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XML_CONFIG" >&5 printf "%s\n" "$XML_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$XML_CONFIG" && break done if test -z "${XML_CONFIG}" ; then echo "Cannot find xml2-config" exit 1 else echo "Using libxml version `$XML_CONFIG --version`" fi fi fi if test -n "${XML_CONFIG}" ; then echo "USE_XML2 = ${USE_XML2}" if test "${USE_XML2}" != "no" && test -z "${FORCE_XML2}"; then echo "foo" | sed -Ee 's/foo/bar/' > /dev/null 2>&1 if test "$?" = "0" ; then SED_EXTENDED_ARG="-E" else SED_EXTENDED_ARG="-r" fi echo "SED_EXTENDED_ARG: ${SED_EXTENDED_ARG}" MINOR=`${XML_CONFIG} --version | ${SED} -e 's/^2\.\([0-9]\{1,\}\).*/\1/'` PATCH=`${XML_CONFIG} --version | ${SED} -e 's/^2\.[0-9]\{1,\}\.\([0-9]\{1,\}\)$/\1/'` echo "Minor $MINOR, Patch $PATCH for `$XML_CONFIG --version`" if test $MINOR -lt 6 ; then echo "" echo "**** You should use a recent version of libxml2, i.e. 2.6.22 or higher ****" echo "" exit 1 fi if test "$MINOR" -eq 6 -a "$PATCH" -lt 3 ; then echo "" echo "**** There are problems compiling this package with libxml2-2.6.1 or libmxml2-2.6.2. ****" echo "**** You will probably encounter compilation errors, so we are terminating the build. ****" echo "" exit 1 fi fi LIBXML_INCDIR=`${XML_CONFIG} --cflags` LIBXML_LIBDIR=`${XML_CONFIG} --libs` FOUND_LIBXML_INCLUDES="Ok" fi fi if test -n "${LIBXML_INCDIR}" && test -z "${XML_CONFIG}" ; then echo "Checking directory of LIBXML_INCDIR" if test -d $LIBXML_INCDIR ; then if test -r ${LIBXML_INCDIR}/libxml/parser.h ; then FOUND_LIBXML_INCLUDES="Ok" elif test -r ${LIBXML_INCDIR}/gnome-xml/parser.h ; then FOUND_LIBXML_INCLUDES="Ok" PKG_CPPFLAGS="${PKG_CPPFLAGS} -DFROM_GNOME_XML_DIR=1" else echo "You specified LIBXML_INCDIR, but we couldn't find parser.h" echo "Please specify it correctly and re-run the INSTALL'ation." exit 1 fi else echo "The LIBXML_INCDIR value you specified ($LIBXML_INCDIR) is not a directory." echo "Please specify it correctly and re-run the INSTALL'ation." exit 1 fi fi if test -z "${FOUND_LIBXML_INCLUDES}" ; then TMP_CPPFLAGS=${CPPFLAGS} for dir in ${LIBXML_INCDIR} /usr/local/include /usr/include ; do CPPFLAGS="${TMP_CPPFLAGS} -I${dir}" ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "libxml/parser.h" "ac_cv_header_libxml_parser_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_parser_h" = xyes then : FROM_LIBXML_DIR=1 fi if test -n "${FROM_LIBXML_DIR}" ; then LIBXML_INCDIR="-I${dir}" CPPFLAGS="${TMP_CPPFLAGS} -I${dir} -I${dir}/libxml" PKG_CPPFLAGS="${TMP_CPPFLAGS} -I${dir} -I${dir}/libxml" echo "Found the libxml parser.h in $dir/libxml/" break fi CPPFLAGS="${TMP_CPPFLAGS} -I${dir}/gnome-xml" ac_fn_c_check_header_compile "$LINENO" "gnome-xml/parser.h" "ac_cv_header_gnome_xml_parser_h" "$ac_includes_default" if test "x$ac_cv_header_gnome_xml_parser_h" = xyes then : FROM_GNOME_XML_DIR=1 fi if test -n "${FROM_GNOME_XML_DIR}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DFROM_GNOME_XML_DIR=1" CPPFLAGS="${CPPFLAGS} -DFROM_GNOME_XML_DIR=1" LIBXML_INCDIR="-I${dir}" echo "Found the gnome-xml parser in $dir" break fi done if test -z "${FROM_GNOME_XML_DIR}" ; then CPPFLAGS=${TMP_CPPFLAGS} fi fi # end of -z FOUND_LIBXML_INCLUDES if test -z "${LIBXML_INCDIR}"; then ac_fn_c_check_header_compile "$LINENO" "libxml/parser.h" "ac_cv_header_libxml_parser_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_parser_h" = xyes then : LIBXML_INCDIR="libxml/" fi fi if test -z "${LIBXML_INCDIR}" ; then echo "Cannot find parser.h. Set the value of the environment variable" echo " LIBXML_INCDIR" echo "to point to where it can be found." exit 1; else echo "Located parser file ${LIBXML_INCDIR}/parser.h" fi #LIBS="${LIBS} ${LIBXML_INCDIR}" if test -z "${LIBXML2}" ; then CPPFLAGS="${PKG_CPPFLAGS} ${LIBXML_INCDIR}" echo "Checking for 1.8: ${CPPFLAGS}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlAttr *attr; attr->val = NULL; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo "Using libxml 1.8.*!" else $as_nop LIBXML2="-DLIBXML2=1"; echo "Using libxml2.*" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi # AC_EGREP_HEADER(xmlParseFile, ${LIBXML_INCDIR}parser.h, # HAVE_LIBXML_HEADER=true, # AC_MSG_ERROR("header files for libxml seem to be incorrect")) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 printf %s "checking for gzopen in -lz... " >&6; } if test ${ac_cv_lib_z_gzopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gzopen (); int main (void) { return gzopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_z_gzopen=yes else $as_nop ac_cv_lib_z_gzopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 printf "%s\n" "$ac_cv_lib_z_gzopen" >&6; } if test "x$ac_cv_lib_z_gzopen" = xyes then : printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h LIBS="-lz $LIBS" fi if test -n "${LIBXML2}" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlParseFile in -lxml2" >&5 printf %s "checking for xmlParseFile in -lxml2... " >&6; } if test ${ac_cv_lib_xml2_xmlParseFile+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxml2 "${LIBXML_LIBDIR--L.}" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlParseFile (); int main (void) { return xmlParseFile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xml2_xmlParseFile=yes else $as_nop ac_cv_lib_xml2_xmlParseFile=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlParseFile" >&5 printf "%s\n" "$ac_cv_lib_xml2_xmlParseFile" >&6; } if test "x$ac_cv_lib_xml2_xmlParseFile" = xyes then : LIBS="${LIBS} -lxml2"; USE_XMLLIB_NAME=xml2 else $as_nop NO_XML_LIB=1 fi else NO_XML_LIB=1 fi if test -n "${NO_XML_LIB}" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlParseFile in -lxml" >&5 printf %s "checking for xmlParseFile in -lxml... " >&6; } if test ${ac_cv_lib_xml_xmlParseFile+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxml "${LIBXML_LIBDIR--L.}" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlParseFile (); int main (void) { return xmlParseFile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xml_xmlParseFile=yes else $as_nop ac_cv_lib_xml_xmlParseFile=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml_xmlParseFile" >&5 printf "%s\n" "$ac_cv_lib_xml_xmlParseFile" >&6; } if test "x$ac_cv_lib_xml_xmlParseFile" = xyes then : LIBS="${LIBS} -lxml";USE_XMLLIB_NAME=xml else $as_nop as_fn_error $? "\"libxml not found\"" "$LINENO" 5 fi fi if test -n "${LIBXML_LIBDIR}" ; then LIBS="${LIBXML_LIBDIR--L.} ${LIBS}" LD_PATH="${LIBXML_LIBDIR-.}" fi PKG_CPPFLAGS="${PKG_CPPFLAGS} -DLIBXML" if test -z "${FROM_GNOME_XML_DIR}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} ${LIBXML_INCDIR--I.}" fi if test -z "${LIBXML2}" ; then if test -z "${USE_OLD_ROOT_CHILD_NAMES}" ; then CPPFLAGS=${PKG_CPPFLAGS} cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlDocPtr node; node->xmlRootNode = NULL; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo "New style libxml!" else $as_nop USE_OLD_ROOT_CHILD_NAMES=1; echo "Need to use old-style libxml names" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext echo "Using old root child names? ${USE_OLD_ROOT_CHILD_NAMES-0}" fi # USE_OLD_ROOT_CHILD_NAMES else # -z "${LIBXML2}" CPPFLAGS=${PKG_CPPFLAGS} if test -d "${LIBXML_LIBDIR}" ; then LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${LIBXML_LIBDIR} export LD_LIBRARY_PATH fi if test "$cross_compiling" = yes then : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main(int argc, char *argv[]) { xmlCheckVersion(20000); return(0); } _ACEOF if ac_fn_c_try_run "$LINENO" then : LIBXML2_OK=1 else $as_nop LIBXML2_OK=0 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test "${LIBXML2_OK}" = "0" ; then echo "You are trying to use a version 2.* edition of libxml" echo "but an incompatible library. The header files and library seem to be" echo "mismatched. If you have specified LIBXML_INCDIR, make certain to also" echo "specify an appropriate LIBXML_LIBDIR if the libxml2 library is not in the default" echo "directories." exit 1 fi fi if test -n "${USE_OLD_ROOT_CHILD_NAMES}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_OLD_ROOT_CHILD_NAMES=1" fi fi if test "${USE_XMLLIB_NAME}" = "xml2" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlHashSize in -lxml2" >&5 printf %s "checking for xmlHashSize in -lxml2... " >&6; } if test ${ac_cv_lib_xml2_xmlHashSize+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxml2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlHashSize (); int main (void) { return xmlHashSize (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xml2_xmlHashSize=yes else $as_nop ac_cv_lib_xml2_xmlHashSize=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml2_xmlHashSize" >&5 printf "%s\n" "$ac_cv_lib_xml2_xmlHashSize" >&6; } if test "x$ac_cv_lib_xml2_xmlHashSize" = xyes then : echo "Using built-in xmlHashSize" else $as_nop PKG_CPPFLAGS="${PKG_CPPFLAGS} -DOWN_XML_HASH_SIZE=1" fi fi if test "${USE_LIBXML}" ; then echo "Checking DTD parsing (presence of externalSubset)..." cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlParserCtxtPtr ctxt; ctxt->inSubset = 0; ctxt->sax->externalSubset = NULL; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : USE_EXT_SUBSET=1 fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test -n "${USE_EXT_SUBSET}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_EXTERNAL_SUBSET=1" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlNodePtr node; int x; x = node->type == XML_DTD_NODE; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ROOT_HAS_DTD_NODE=1 else $as_nop echo "No XML_DTD_NODE defined" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test -n "${ROOT_HAS_DTD_NODE}" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DROOT_HAS_DTD_NODE=1" fi as_ac_Lib=`printf "%s\n" "ac_cv_lib_${USE_XMLLIB_NAME}""_xmlHashSize" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlHashSize in -l${USE_XMLLIB_NAME}" >&5 printf %s "checking for xmlHashSize in -l${USE_XMLLIB_NAME}... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-l${USE_XMLLIB_NAME} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlHashSize (); int main (void) { return xmlHashSize (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else $as_nop eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : echo "Found xmlHashSize" else $as_nop echo "No xmlHashSize" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlEntityPtr ent; ent->checked = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ENTITY_HAS_CHECKED="yes" else $as_nop ENTITY_HAS_CHECKED="no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test "${ENTITY_HAS_CHECKED}" = "no" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DNO_CHECKED_ENTITY_FIELD=1" fi fi as_ac_Lib=`printf "%s\n" "ac_cv_lib_${USE_XMLLIB_NAME}""_xmlOutputBufferCreateBuffer" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlOutputBufferCreateBuffer in -l${USE_XMLLIB_NAME}" >&5 printf %s "checking for xmlOutputBufferCreateBuffer in -l${USE_XMLLIB_NAME}... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-l${USE_XMLLIB_NAME} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlOutputBufferCreateBuffer (); int main (void) { return xmlOutputBufferCreateBuffer (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else $as_nop eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : echo "have xmlOutputBufferCreateBuffer()"; if test "${ADD_XML_OUTPUT_BUFFER}" = "yes" ; then PKG_CPPFLAGS="${PKG_CPPFLAGS} -DADD_XML_OUTPUT_BUFFER_CODE=1"; else ADD_XML_OUTPUT_BUFFER=no ; fi; else $as_nop echo "Using local xmlOutputBufferCreateBuffer. You might think about installing a newer version of libxml2, at least 2.6.23" ; PKG_CPPFLAGS="${PKG_CPPFLAGS} -DADD_XML_OUTPUT_BUFFER_CODE=1"; ADD_XML_OUTPUT_BUFFER=1 fi as_ac_Lib=`printf "%s\n" "ac_cv_lib_${USE_XMLLIB_NAME}""_xmlDocDumpFormatMemoryEnc" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xmlDocDumpFormatMemoryEnc in -l${USE_XMLLIB_NAME}" >&5 printf %s "checking for xmlDocDumpFormatMemoryEnc in -l${USE_XMLLIB_NAME}... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-l${USE_XMLLIB_NAME} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char xmlDocDumpFormatMemoryEnc (); int main (void) { return xmlDocDumpFormatMemoryEnc (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else $as_nop eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : PKG_CPPFLAGS="${PKG_CPPFLAGS} -DDUMP_WITH_ENCODING=1" fi if test -z "${FROM_GNOME_XML_DIR}" ; then ac_fn_c_check_header_compile "$LINENO" "libxml/xmlversion.h" "ac_cv_header_libxml_xmlversion_h" "$ac_includes_default" if test "x$ac_cv_header_libxml_xmlversion_h" = xyes then : PKG_CPPFLAGS="${PKG_CPPFLAGS} -DUSE_XML_VERSION_H=1" fi fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlElementPtr el; int x; x = el->etype; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="${PKG_CPPFLAGS} -DXML_ELEMENT_ETYPE=1" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlAttributePtr el; int x; x = el->atype; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="${PKG_CPPFLAGS} -DXML_ATTRIBUTE_ATYPE=1" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test -n "${USE_EXPAT}" ; then ac_fn_c_check_header_compile "$LINENO" "xmltok/xmlparse.h" "ac_cv_header_xmltok_xmlparse_h" "$ac_includes_default" if test "x$ac_cv_header_xmltok_xmlparse_h" = xyes then : XMLPARSE_INCDIR="xmltok/" fi if test -z "${XMLPARSE_INCDIR}" ; then ac_fn_c_check_header_compile "$LINENO" "xmlparse/xmlparse.h" "ac_cv_header_xmlparse_xmlparse_h" "$ac_includes_default" if test "x$ac_cv_header_xmlparse_xmlparse_h" = xyes then : XMLPARSE_INCDIR="xmlparse/" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <${XMLPARSE_INCDIR}xmlparse.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "XML_Parse" >/dev/null 2>&1 then : HAVE_EXPAT_HEADER=true else $as_nop as_fn_error $? "\"header file xmlparse.h seems to be incorrect\"" "$LINENO" 5 fi rm -rf conftest* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XmlInitEncoding in -lxmltok" >&5 printf %s "checking for XmlInitEncoding in -lxmltok... " >&6; } if test ${ac_cv_lib_xmltok_XmlInitEncoding+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxmltok $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char XmlInitEncoding (); int main (void) { return XmlInitEncoding (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xmltok_XmlInitEncoding=yes else $as_nop ac_cv_lib_xmltok_XmlInitEncoding=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xmltok_XmlInitEncoding" >&5 printf "%s\n" "$ac_cv_lib_xmltok_XmlInitEncoding" >&6; } if test "x$ac_cv_lib_xmltok_XmlInitEncoding" = xyes then : printf "%s\n" "#define HAVE_LIBXMLTOK 1" >>confdefs.h LIBS="-lxmltok $LIBS" else $as_nop as_fn_error $? "\"libxmltok not found\"" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XML_Parse in -lxmlparse" >&5 printf %s "checking for XML_Parse in -lxmlparse... " >&6; } if test ${ac_cv_lib_xmlparse_XML_Parse+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxmlparse -lxmltok $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char XML_Parse (); int main (void) { return XML_Parse (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xmlparse_XML_Parse=yes else $as_nop ac_cv_lib_xmlparse_XML_Parse=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xmlparse_XML_Parse" >&5 printf "%s\n" "$ac_cv_lib_xmlparse_XML_Parse" >&6; } if test "x$ac_cv_lib_xmlparse_XML_Parse" = xyes then : printf "%s\n" "#define HAVE_LIBXMLPARSE 1" >>confdefs.h LIBS="-lxmlparse $LIBS" else $as_nop as_fn_error $? "\"libxmlparse not found\"" "$LINENO" 5 fi PKG_CPPFLAGS="${PKG_CPPFLAGS} -DLIBEXPAT -I${XMLPARSE_INCDIR}" LD_PATH="${LD_PATH}:${LIBXML_LIBDIR}" fi if test -n "${USE_EXPAT}" ; then SUPPORTS_EXPAT="TRUE" else SUPPORTS_EXPAT="FALSE" fi echo "Expat: ${USE_EXPAT} ${SUPPORTS_EXPAT}" if test -n "${USE_LIBXML}" ; then SUPPORTS_LIBXML="TRUE" else SUPPORTS_LIBXML="FALSE" fi if test -z "${USE_SPLUS}" ; then LANGUAGE_DEFS="-DUSE_R=1 -D_R_=1 ${LANGUAGE_DEFS}" else if test ${SUPPORTS_LIBXML}="TRUE" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for attribute in -lxml" >&5 printf %s "checking for attribute in -lxml... " >&6; } if test ${ac_cv_lib_xml_attribute+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lxml $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char attribute (); int main (void) { return attribute (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_xml_attribute=yes else $as_nop ac_cv_lib_xml_attribute=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xml_attribute" >&5 printf "%s\n" "$ac_cv_lib_xml_attribute" >&6; } if test "x$ac_cv_lib_xml_attribute" = xyes then : NEED_LIBXML_PATCH=1 fi if test -n "${NEED_LIBXML_PATCH}" ; then echo "The XML package will not work with S-Plus and the current libxml" echo "because of a conflict from both having a routine named attribute()" echo "We suggest that you modify the SAX.c file in the libxml and re-install." echo "See PATCH.attribute in this package's distribution." exit 1 fi fi # ? SUPPORTS_LIBXML = "TRUE" LANGUAGE_DEFS="-D_S_=1 -DUSE_S=1 -D_S4_=1 -D_SPLUS${SPLUS_VERSION}_ -DNO_SPLUS_THREAD_DEF=1 ${LANGUAGE_DEFS}" INSTALL_DIR=`pwd` PKG_SYS_FILE="paste(\"${INSTALL_DIR}/inst/scripts/\", name,sep=\"\")" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "parser.h" int main (void) { extern int xmlSkipBlankChars(xmlParserCtxtPtr ctxt); xmlParserCtxtPtr p; xmlSkipBlankChars(p); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : echo "No need for old SKIP_BLANKS definition" else $as_nop BLANKS_DEF="-DOLD_SKIP_BLANKS=1" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -n "LIBXML2" ; then TMP_CFLAGS="${CFLAGS}" CFLAGS="${CFLAGS} -pedantic-errors" echo "Checking for return type of xmlHashScan element routine." cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #include #else #include #include #endif int main (void) { void *(*foo)(void *, void *, xmlChar*); xmlElementTablePtr table; xmlHashScan(table, foo, NULL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo "xmlHashScan wants a return value." else $as_nop echo "No return value for xmlHashScan"; PKG_CPPFLAGS="${PKG_CPPFLAGS} -DNO_XML_HASH_SCANNER_RETURN=1" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="${TMP_CFLAGS}" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { xmlNsPtr ns; ns->context; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="$PKG_CPPFLAGS -DLIBXML_NAMESPACE_HAS_CONTEXT=1"; echo "xmlNs has a context field" else $as_nop echo "No context field in xmlNs structure." fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi CPPFLAGS="$CPPFLAGS -I$R_HOME/include" echo "Checking for cetype_t enumeration" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { cetype_t t; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="${PKG_CPPFLAGS} -DHAVE_R_CETYPE_T=1"; echo "Using recent version of R with cetype_t enumeration type for encoding" else $as_nop echo "No cetype_t enumeration defined in R headers." fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext PKG_LIBS=${LIBS} if test -n "${NEED_XML_PARSER_ERROR}" ; then # Extract the first word of "uname", so it can be a program name with args. set dummy uname; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_UNAME+y} then : printf %s "(cached) " >&6 else $as_nop case $UNAME in [\\/]* | ?:[\\/]*) ac_cv_path_UNAME="$UNAME" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_UNAME="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi UNAME=$ac_cv_path_UNAME if test -n "$UNAME"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $UNAME" >&5 printf "%s\n" "$UNAME" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -n "${UNAME}" ; then host_os=`${UNAME}` if test "${host_os}" = "Darwin" ; then PKG_LIBS="-m $PKG_LIBS" fi fi fi for ac_prog in xmlsec1-config do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_XMLSEC_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $XMLSEC_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_XMLSEC_CONFIG="$XMLSEC_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_XMLSEC_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XMLSEC_CONFIG=$ac_cv_path_XMLSEC_CONFIG if test -n "$XMLSEC_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XMLSEC_CONFIG" >&5 printf "%s\n" "$XMLSEC_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$XMLSEC_CONFIG" && break done if test -n "$XMLSEC_CONFIG" ; then PKG_CPPFLAGS="$PKG_CPPFLAGS `$XMLSEC_CONFIG --cflags`" PKG_LIBS="$PKG_LIBS `$XMLSEC_CONFIG --libs`" XMLSEC_DEFS=-DHAVE_LIBXML_SEC=1 fi # Check whether --enable-nodegc was given. if test ${enable_nodegc+y} then : enableval=$enable_nodegc; if test "${enableval}" = "yes" || test "${enableval}" = "default" ; then LANGUAGE_DEFS="${LANGUAGE_DEFS} -DXML_REF_COUNT_NODES=1" fi; echo "enabling nodegc? ${enableval}" else $as_nop echo "nodegc default $enableval"; LANGUAGE_DEFS="${LANGUAGE_DEFS} -DXML_REF_COUNT_NODES=1" fi # Check whether --enable-xml-debug was given. if test ${enable_xml_debug+y} then : enableval=$enable_xml_debug; if test "${enableval}" = "yes" || test "${enableval}" = "default" ; then LANGUAGE_DEFS="${LANGUAGE_DEFS} -DR_XML_DEBUG=1" fi; echo "enabling xml-debug? ${enableval}" else $as_nop echo "xml-debug default $enableval"; LANGUAGE_DEFS="${LANGUAGE_DEFS}" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { int val; val = XML_WITH_ZLIB; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_XML_WITH_ZLIB=1"; echo "Version has XML_WITH_ZLIB" else $as_nop echo "No XML_WITH_ZLIB enumeration value." fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef FROM_GNOME_XML_DIR #include #else #include #endif int main (void) { xmlFeature f; xmlHasFeature(f); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : PKG_CPPFLAGS="$PKG_CPPFLAGS -DHAVE_XML_HAS_FEATURE=1"; echo "Version has xmlHasFeature()" else $as_nop echo "No xmlHasFeature." fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test -n "${USE_SPLUS}" ; then SPLUS_MAKEFILE=GNUmakefile.Splus fi echo "" echo "****************************************" echo "Configuration information:" echo "" echo "Libxml settings" echo "" echo "libxml include directory: ${LIBXML_INCDIR}" echo "libxml library directory: ${LIBS}" echo "libxml 2: ${LIBXML2-no}" echo "" echo "Compilation flags: ${PKG_CPPFLAGS} ${LANGUAGE_DEFS} $XMLSEC_DEFS" echo "Link flags: ${PKG_LIBS}" echo "" echo "****************************************" if test "$ADD_XML_OUTPUT_BUFFER" = "no" ; then ADD_XML_OUTPUT_BUFFER=0 fi if test "$ADD_XML_OUTPUT_BUFFER" = "yes" ; then ADD_XML_OUTPUT_BUFFER=1 fi if test -n "${_R_CHECK_TIMINGS_}" ; then PKG_CPPFLAGS="$PKG_CPPFLAGS -DNO_XML_MEMORY_SHOW_ROUTINE=1" fi ac_config_files="$ac_config_files src/Makevars R/supports.R inst/scripts/RSXML.csh inst/scripts/RSXML.bsh ${SPLUS_MAKEFILE}" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/Makevars") CONFIG_FILES="$CONFIG_FILES src/Makevars" ;; "R/supports.R") CONFIG_FILES="$CONFIG_FILES R/supports.R" ;; "inst/scripts/RSXML.csh") CONFIG_FILES="$CONFIG_FILES inst/scripts/RSXML.csh" ;; "inst/scripts/RSXML.bsh") CONFIG_FILES="$CONFIG_FILES inst/scripts/RSXML.bsh" ;; "${SPLUS_MAKEFILE}") CONFIG_FILES="$CONFIG_FILES ${SPLUS_MAKEFILE}" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi chmod +x cleanup if test -n "${USE_SPLUS}" ; then mv GNUmakefile.Splus GNUmakefile echo "Creating S-Plus chapter" cd src C_SRC_FILES="DocParse.c RSDTD.c Utils.c" ${SPLUS} CHAPTER ${C_SRC_FILES} echo "include Makevars" >> makefile echo 'CFLAGS:= $(PKG_CPPFLAGS) $(CFLAGS)' >> makefile echo 'LOCAL_LIBS=$(PKG_LIBS) ' >> makefile cd .. fi XML/man/0000755000175100001440000000000014405636156011515 5ustar hornikusersXML/man/xmlClone.Rd0000644000175100001440000000356313700532410013555 0ustar hornikusers\name{xmlClone} \alias{xmlClone} \alias{xmlClone,XMLInternalNode-method} \alias{xmlClone,XMLInternalDocument-method} \title{Create a copy of an internal XML document or node} \description{ These methods allow the caller to create a copy of an XML internal node. This is useful, for example, if we want to use the node or document in an additional context, e.g. put the node into another document while leaving it in the existing document. Similarly, if we want to remove nodes to simplify processing, we probably want to copy it so that the changes are not reflected in the original document. At present, the newly created object is not garbage collected. } \usage{ xmlClone(node, recursive = TRUE, addFinalizer = FALSE, ...) } \arguments{ \item{node}{the object to be cloned} \item{recursive}{a logical value indicating whether the entire object and all its descendants should be duplicated/cloned (\code{TRUE}) or just the top-level object (\code{FALSE})} \item{addFinalizer}{typically a logical value indicating whether to bring this new object under R's regular garbage collection. This can also be a reference to a C routine which is to be used as the finalizer. See \code{\link{getNativeSymbolInfo}}. } \item{\dots}{additional parameters for methods} } \value{ A new R object representing the object. } \references{libxml2} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlParse}} \code{\link{newXMLNode}} \code{\link{newXMLDoc}} } \examples{ doc = xmlParse(paste0('Duncan', 'Temple Lang')) au = xmlRoot(doc)[[1]] # make a copy other = xmlClone(au) # change it slightly xmlAttrs(other) = c(id = "dtl2") # add it to the children addChildren(xmlRoot(doc), other) } \keyword{IO} \keyword{programming} \concept{XML} XML/man/addChildren.Rd0000644000175100001440000002141114316477364014211 0ustar hornikusers\name{addChildren} \alias{addChildren} \alias{xmlParent<-} \alias{removeChildren} \alias{removeNodes} \alias{removeNodes.list} \alias{removeNodes.XMLNodeSet} \alias{removeNodes.XMLNodeList} \alias{removeNodes.XMLInternalNode} \alias{replaceNodes} \alias{addAttributes} \alias{removeAttributes} \alias{addChildren,XMLInternalNode-method} \alias{addChildren,XMLNode-method} \alias{addAttributes,XMLInternalElementNode-method} \alias{addAttributes,XMLNode-method} \alias{removeAttributes,XMLInternalElementNode-method} \alias{removeAttributes,XMLNode-method} \title{Add child nodes to an XML node} \description{ This collection of functions allow us to add, remove and replace children from an XML node and also to and and remove attributes on an XML node. These are generic functions that work on both internal C-level \code{XMLInternalElementNode} objects and regular R-level \code{XMLNode} objects. \code{addChildren} is similar to \code{\link{addNode}} and the two may be consolidated into a single generic function and methods in the future. } \usage{ addChildren(node, ..., kids = list(...), at = NA, cdata = FALSE, append = TRUE) removeChildren(node, ..., kids = list(...), free = FALSE) removeNodes(node, free = rep(FALSE, length(node))) replaceNodes(oldNode, newNode, ...) addAttributes(node, ..., .attrs = NULL, suppressNamespaceWarning = getOption("suppressXMLNamespaceWarning", FALSE), append = TRUE) removeAttributes(node, ..., .attrs = NULL, .namespace = FALSE, .all = (length(list(...)) + length(.attrs)) == 0) %xmlParent(node) = value } \arguments{ \item{node}{the XML node whose state is to be modified, i.e. to which the child nodes are to be added or whose attribute list is to be changed.} \item{\dots}{This is for use in interactive settings when specifying a collection of values individuall. In programming contexts when one obtains the collection as a vector or list from another call, use the \code{kids} or \code{.attrs} parameter. } \item{kids}{when adding children to a node, this is a list of children nodes which should be of the same "type" (i.e. internal or R-level nodes) as the \code{node} argument. However, they can also be regular strings in which case they are converted to XML text nodes. For \code{removeChildren}, this is again a list which identifies the child nodes to be removed using the integer identifier of the child, or the name of the XML node (but this will only remove the first such node and not necessarily do what you expect when there are multiple nodes with the same name), or the \code{XMLInternalNode} object itself. } \item{at}{if specified, an integer identifying the position in the original list of children at which the new children should be added. The children are added after that child. This can also be a vector of indices which is as long as the number of children being added and specifies the position for each child being added. If the vector is shorter than the number of children being added, it is padded with NAs and so the corresponding children are added at the end of the list. This parameter is only implemented for internal nodes at present. } \item{cdata}{a logical value which controls whether children that are specified as strings/text are enclosed within a CDATA node when converted to actual nodes. This value is passed on to the relevant function that creates the text nodes, e.g. \code{\link{xmlTextNode}} and \code{\link{newXMLTextNode}}. } \item{.attrs}{a character vector identifying the names of the attributes. These strings can have name space prefixes, e.g. \code{r:length} and the namespaces will be resolved relative to the list supported by \code{node} to ensure those namespaces are defined. } \item{.namespace}{This is currently ignored and may never be supported. The intent is to identify on which set of attributes the operation is to perform - the name space declarations or the regular node attributes. This is a logical value indicating if \code{TRUE} that the attributes of interested are name space declarations, i.e. of the form \code{xmlns:prefix} or \code{xmlns}. If a value of \code{FALSE} is supplied this indicates that we are identifying regular attributes. Note that we can still identify attributes with a name space prefix as, e.g., \code{ns:attr} without this value } \item{free}{a logical value indicating whether to free the C-level memory associated with the child nodes that were removed. \code{TRUE} means to free that memory. This is only applicable for the internal nodes created with \code{xmlTree} and \code{newXMLNode} and related functions. It is necessary as automated garbage collection is tricky in this tree-based context spanning both R and C data structures and memory managers. } \item{.all}{a logical value indicating whether to remove all of the attributes within the XML node without having to specify them by name.} \item{oldNode}{the node which is to be replaced} \item{newNode}{the node which is to take the place of \code{oldNode} in the list of children of the parent of \code{oldNode}} \item{suppressNamespaceWarning}{a logical value or a character string. This is used to control the situation when an XML node or attribute is created with a name space prefix that currently has no definition for that node. This is not necessarily an error but can lead to one. This argument controls whether a warning is issued or if a separate function is called. A value of \code{FALSE} means not to suppress the warning and so it is issued. A value of \code{TRUE} causes the potential problem to be ignored assuming that the namespace will be added to this node or one of its ancestors at a later point. And if this value is a character string, we search for a function of that name and invoke it. } \item{append}{a logical value that indicates whether (\code{TRUE}) the specified attributes or children should be added to the existing attributes on the XML node (if any exist), or, if \code{FALSE} these should replace any existing attributes.} } %\details{} \value{ Each of these functions returns the modified node. For an internal node, this is the same R object and only the C-level data structures have changed. For an R \code{XMLNode} object, this is is an entirely separate object from the original node. It must be inserted back into its parent "node" or context if the changes are to be seen in that wider context. } \references{ libxml2 \url{http://www.xmlsoft.org} } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTree}} \code{\link{newXMLNode}} } \examples{ b = newXMLNode("bob", namespace = c(r = "http://www.r-project.org", omg = "https://www.omegahat.net")) cat(saveXML(b), "\n") addAttributes(b, a = 1, b = "xyz", "r:version" = "2.4.1", "omg:len" = 3) cat(saveXML(b), "\n") removeAttributes(b, "a", "r:version") cat(saveXML(b), "\n") removeAttributes(b, .attrs = names(xmlAttrs(b))) addChildren(b, newXMLNode("el", "Red", "Blue", "Green", attrs = c(lang ="en"))) k = lapply(letters, newXMLNode) addChildren(b, kids = k) cat(saveXML(b), "\n") removeChildren(b, "a", "b", "c", "z") # can mix numbers and names removeChildren(b, 2, "e") # d and e cat(saveXML(b), "\n") i = xmlChildren(b)[[5]] xmlName(i) # have the identifiers removeChildren(b, kids = c("m", "n", "q")) x <- xmlNode("a", xmlNode("b", "1"), xmlNode("c", "1"), "some basic text") v = removeChildren(x, "b") # remove c and b v = removeChildren(x, "c", "b") # remove the text and "c" leaving just b v = removeChildren(x, 3, "c") \dontrun{ # this won't work as the 10 gets coerced to a # character vector element to be combined with 'w' # and there is no node name 10. removeChildren(b, kids = c(10, "w")) } # for R-level nodes (not internal) z = xmlNode("arg", attrs = c(default="TRUE"), xmlNode("name", "foo"), xmlNode("defaultValue","1:10")) o = addChildren(z, "some text", xmlNode("a", "a link", attrs = c(href = "https://www.omegahat.net/RSXML"))) o # removing nodes doc = xmlParse("bob") top = xmlRoot(doc) top removeNodes(list(top[[1]], top[[3]])) # a and c have disappeared. top } \keyword{IO } \keyword{programming} \concept{XML} \concept{document tree} XML/man/XMLNode-class.Rd0000644000175100001440000000374214405636156014363 0ustar hornikusers\name{XMLNode-class} \docType{class} \alias{XMLAbstractNode-class} \alias{XMLAbstractNode-class} \alias{RXMLNode-class} \alias{XMLNode-class} \alias{XMLTreeNode-class} \alias{XMLInternalNode-class} \alias{XMLInternalTextNode-class} \alias{XMLInternalElementNode-class} \alias{XMLInternalCommentNode-class} \alias{XMLInternalPINode-class} \alias{XMLInternalCDataNode-class} \alias{XMLAttributeDeclNode-class} % Added later. Do they fit here. \alias{XMLDocumentFragNode-class} \alias{XMLDocumentNode-class} \alias{XMLDocumentTypeNode-class} \alias{XMLEntityDeclNode-class} \alias{XMLNamespaceDeclNode-class} \alias{XMLXIncludeStartNode-class} \alias{XMLXIncludeEndNode-class} \alias{XMLDTDNode-class} \alias{coerce,XMLAbstractNode,Date-method} \alias{coerce,XMLAbstractNode,POSIXct-method} \alias{coerce,XMLAbstractNode,URL-method} \alias{coerce,XMLAbstractNode,character-method} \alias{coerce,XMLAbstractNode,integer-method} \alias{coerce,XMLAbstractNode,logical-method} \alias{coerce,XMLAbstractNode,numeric-method} \alias{XMLNamespaceDefinitions-class} \title{Classes to describe an XML node object.} \description{These classes are intended to represent an XML node, either directly in S or a reference to an internal libxml node. Such nodes respond to queries about their name, attributes, namespaces and children. These are old-style, S3 class definitions at present. } \section{Slots}{ \describe{These are old-style S3 class definitions and do not have formal slots} } \section{Methods}{ No methods defined with class "XMLNode" in the signature. } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlTree}} \code{\link{newXMLNode}} \code{\link{xmlNode}} } \examples{ # An R-level XMLNode object a <- xmlNode("arg", attrs = c(default="T"), xmlNode("name", "foo"), xmlNode("defaultValue","1:10")) xmlAttrs(a) = c(a = 1, b = "a string") } \keyword{classes} XML/man/toHTML.Rd0000644000175100001440000000254413607633744013123 0ustar hornikusers\name{toHTML} \alias{toHTML} \alias{toHTML,vector-method} \alias{toHTML,matrix-method} \alias{toHTML,call-method} \title{Create an HTML representation of the given R object, using internal C-level nodes} \description{ This generic function and the associated methods are intended to create an HTML tree that represents the R object in some intelligent manner. For example, we represent a vector as a table and we represent a matrix also as a table. } \usage{ toHTML(x, context = NULL) } \arguments{ \item{x}{ the R object which is to be represented via an HTML tree } \item{context}{an object which provides context in which the node will be used. This is currently arbitrary. It may be used, for example, when creating HTML for R documentation and providing information about variabes and functions that are available on that page and so have internal links. } } \details{ It would be nicer if we could pass additional arguments to control whether the outer/parent layer is created, e.g. when reusing code for a vector for a row of a matrix. } \value{ an object of class \code{XMLInternalNode} } %\references{ } \author{Duncan Temple Lang} \seealso{ The \code{R2HTML} package. } \examples{ cat(as(toHTML(rnorm(10)), "character")) } \keyword{IO} \keyword{programming} \concept{XML} \concept{serialization} \concept{data exchange} XML/man/xmlSchemaValidate.Rd0000644000175100001440000000465213607633744015411 0ustar hornikusers\name{xmlSchemaValidate} \alias{xmlSchemaValidate} \alias{schemaValidationErrorHandler} \title{Validate an XML document relative to an XML schema} \description{ This function validates an XML document relative to an XML schema to ensure that it has the correct structure, i.e. valid sub-nodes, attributes, etc. The \code{xmlSchemaValidationErrorHandler} is a function that returns a list of functions which can be used to cumulate or collect the errors and warnings from the schema validation operation. } \usage{ xmlSchemaValidate(schema, doc, errorHandler = xmlErrorFun(), options = 0L) schemaValidationErrorHandler() } \arguments{ \item{schema}{an object of class \code{xmlSchemaRef} which is usually the result of a call to \code{\link{xmlInternalTreeParse}} with \code{isSchema = TRUE}, or \code{\link{xmlSchemaParse}}.} \item{doc}{an XML document which has already been parsed into a \code{XMLInternalDocument} or which is a file name or string which is coerced to an \code{\link{XMLInternalDocument-class}} object} \item{options}{an integer giving the options controlling the validation. At present, this is either 0 or 1 and is essentially irrelevant to us. It may be of value in the future. } \item{errorHandler}{ a function or a list whose first element is a function which is then used as the collector for the warning and error messages reported during the validation. For each warning or error, this function is invoked and the class of the message is either \code{XMLSchemaWarning} or \code{XMLSchemaError} respectively. } } \value{ Typically, a list with 3 elements: \item{status}{0 for validated, and non-zero for invalid} \item{errors}{a character vector} \item{warnings}{a character vector} If an empty error handler is provided (i.e. \code{NULL}) just an integer indicating the status of the validation is returned. 0 indicates everything was okay; a non-zero value indicates a validation error. (-1 indicates an internal error in libxml2) } \references{libxml2 www.xmlsoft.org } \seealso{ \code{\link{xmlSchemaParse}} } \examples{ if(FALSE) { xsd = xmlParse(system.file("exampleData", "author.xsd", package = "XML"), isSchema =TRUE) doc = xmlInternalTreeParse(system.file("exampleData", "author.xml", package = "XML")) xmlSchemaValidate(xsd, doc) } } \keyword{IO} \concept{validation} \concept{XML} \concept{schema} XML/man/catalogs.Rd0000644000175100001440000001147614316477364013617 0ustar hornikusers \name{catalogLoad} \alias{catalogLoad} \alias{catalogClearTable} \alias{catalogAdd} \alias{catalogDump} \title{Manipulate XML catalog contents} \description{ These functions allow the R user to programmatically control the XML catalog table used in the XML parsing tools in the C-level libxml2 library and hence in R packages that use these, e.g. the XML and Sxslt packages. Catalogs are consulted whenever an external document needs to be loaded. XML catalogs allow one to influence how such a document is loaded by mapping document identifiers to alternative locations, for example to refer to locally available versions. They support mapping URI prefixes to local file directories/files, resolving both SYSTEM and PUBLIC identifiers used in DOCTYPE declarations at the top of an XML/HTML document, and delegating resolution to other catalog files. Catalogs are written using an XML format. Catalogs allow resources used in XInclude nodes and XSL templates to refer to generic network URLs and have these be mapped to local files and so avoid potentially slow network retrieval. Catalog files are written in XML We might have a catalog file that contains the XML In the XDynDocs package, we refer to OmegahatXSL files and DocBook XSL files have a catalog file of the form The functions provided here allow the R programmer to empty the current contents of the global catalog table and so start from scratch ( \code{catalogClearTable} ), load the contents of a catalog file into the global catalog table ( \code{catalogLoad} ), and to add individual entries programmatically without the need for a catalog table. In addition to controlling the catalogs via these functions, we can use \code{\link{catalogResolve}} to use the catalog to resolve the name of a resource and map it to a local resource. \code{catalogDump} allows us to retrieve an XML document representing the current contents of the in-memory catalog . More information can be found at \url{http://xmlsoft.org/catalog.html} and \url{http://www.sagehill.net/docbookxsl/Catalogs.html} among many resources and the specification for the catalog format at \url{https://www.oasis-open.org/committees/entity/spec-2001-08-06.html}. } \usage{ catalogLoad(fileNames) catalogClearTable() catalogAdd(orig, replace, type = "rewriteURI") catalogDump(fileName = tempfile(), asText = TRUE) } \arguments{ \item{orig}{a character vector of identifiers, e.g. URIs, that are to be mapped to a different name via the catalog. This can be a named character vector where the names are the original URIs and the values are the corresponding rewritten values. } \item{replace}{a character vector of the rewritten or resolved values for the identifiers given in orig. Often this omitted and the original-rewrite pairs are given as a named vector via orig. } \item{type}{a character vector with the same length as orig (or recycled to have the same length) which specifies the type of the resources in the elements of orig. Valid values are rewriteURI, rewriteSystem, system, public. } \item{fileNames}{a character vector giving the names of the catalog files to load.} \item{fileName}{the name of the file in which to place the contents of the current catalog} \item{asText}{a logical value which indicates whether to write the catalog as a character string if \code{filename} is not specified.} } \value{ These functions are used for their side effects on the global catalog table maintained in C by libxml2. Their return values are logical values/vectors indicating whether the particular operation were successful or not. } \references{ This provides an R-like interface to a small subset of the catalog API made available in libxml2. } \seealso{ \code{\link{catalogResolve}} XInclude, XSL and import/include directives. In addition to these functions, there is an un-exported, undocumented function named \code{catalogDump} that can be used to get the contents of the (first) catalog table. } \examples{ # Add a rewrite rule # # catalogAdd(c("https://www.omegahat.net/XML" = system.file("XML", package = "XML"))) catalogAdd("https://www.omegahat.net/XML", system.file("XML", package = "XML")) catalogAdd("http://www.r-project.org/doc/", paste(R.home(), "doc", "", sep = .Platform$file.sep)) # # This shows how we can load a catalog and then resolve a # systemidentifier that it maps. # catalogLoad(system.file("exampleData", "catalog.xml", package = "XML")) catalogResolve("docbook4.4.dtd", "system") catalogResolve("-//OASIS//DTD DocBook XML V4.4//EN", "public") } \keyword{IO} XML/man/xmlToList.Rd0000644000175100001440000000452413607633744013753 0ustar hornikusers\name{xmlToList} \alias{xmlToList} \title{Convert an XML node/document to a more R-like list} \description{ This function is an early and simple approach to converting an XML node or document into a more typical R list containing the data values directly (rather than as XML nodes). It is useful for dealing with data that is returned from REST requests or other Web queries or generally when parsing XML and wanting to be able to access the content as elements in a list indexed by the name of the node. For example, if given a node of the form \code{ text a phrase } We would end up with a list with elements named "a", "b" and "c". "a" would be the string "text", b would contain the named character vector \code{c(foo = "1")} (i.e. the attributes) and "c" would contain the list with two elements named "d" and ".attrs". The element corresponding to "d" is a character vector with the single element "a phrase". The ".attrs" element of the list is the character vector of attributes from the node \code{...}. } \usage{ xmlToList(node, addAttributes = TRUE, simplify = FALSE) } \arguments{ \item{node}{the XML node or document to be converted to an R list. This can be an "internal" or C-level node (i.e. \code{\link{XMLInternalNode-class}}) or a regular R-level node (either \code{\link{XMLNode-class}} or \code{XMLHashNode}).} \item{addAttributes}{a logical value which controls whether the attributes of an empty node are added to the } \item{simplify}{a logical value that controls whether we collapse the list to a vector if the elements all have a common compatible type. Basically, this controls whether we use \code{sapply} or \code{lapply}. } } \value{ A list whose elements correspond to the children of the top-level nodes. } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} \code{\link{getNodeSet}} and \code{\link{xpathApply}} \code{\link{xmlRoot}}, \code{\link{xmlChildren}}, \code{\link{xmlApply}}, \code{[[}, etc. for accessing the content of XML nodes. } \examples{ tt = ' text a phrase ' doc = xmlParse(tt) xmlToList(doc) # use an R-level node representation doc = xmlTreeParse(tt) xmlToList(doc) } \keyword{IO} \keyword{data} XML/man/xmlSearchNs.Rd0000644000175100001440000000246113607633744014241 0ustar hornikusers\name{xmlSearchNs} \alias{xmlSearchNs} \alias{coerce,XMLNamespaceRef,character-method} \title{Find a namespace definition object by searching ancestor nodes} \description{ This function allows one to search an XML tree from a particular node and find the namespace definition for a given namespace prefix or URL. This namespace definition can then be used to set it on a node to make it the effective namespace for that node. } \usage{ xmlSearchNs(node, ns, asPrefix = TRUE, doc = as(node, "XMLInternalDocument")) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{node}{an \code{XMLInternaElementNode}} \item{ns}{a character string (vector of length 1). If \code{asPrefix} is \code{TRUE}, this is the namespace alias/prefix. If \code{asPrefix} is \code{FALSE}, this is the URL of the namespace definition} \item{asPrefix}{a logical value. See \code{ns}.} \item{doc}{the XML document in which the node(s) are located} } \value{ An object of class XMLNamespaceRef. } \references{ libxml2 } \author{ Duncan Temple Lang } \seealso{ \code{\link{newXMLNode}} } \examples{ txt = '
    ' doc = xmlParse(txt) bottom = xmlRoot(doc)[[1]][[1]] xmlSearchNs(bottom, "r") } \keyword{programming} \keyword{data} XML/man/saveXML.Rd0000644000175100001440000001347214405636156013332 0ustar hornikusers\name{saveXML} \alias{saveXML} \alias{saveXML.XMLInternalDocument} \alias{saveXML.XMLInternalDOM} \alias{saveXML.XMLInternalNode} \alias{saveXML.XMLNode} \alias{saveXML.XMLOutputStream} \alias{coerce,XMLInternalDocument,character-method} \alias{coerce,XMLInternalDOM,character-method} \alias{coerce,XMLInternalNode,character-method} \alias{saveXML,XMLFlatTree-method} \alias{saveXML,XMLInternalDocument-method} \alias{saveXML,XMLInternalDOM-method} \alias{saveXML,XMLInternalNode-method} \alias{saveXML,XMLNode-method} \alias{saveXML,XMLOutputStream-method} \alias{saveXML,HTMLInternalDocument-method} \title{Output internal XML Tree} \description{ Methods for writing the representation of an XML tree to a string or file. Originally this was intended to be used only for DOMs (Document Object Models) stored in internal memory created via \code{\link{xmlTree}}, but methods for \code{XMLNode}, \code{XMLInternalNode} and \code{XMLOutputStream} objects (and others) allow it to be generic for different representations of the XML tree. Note that the indentation when writing an internal C-based node (XMLInternalNode) may not be as expected if there are text nodes within the node. Also, not all the parameters are meaningful for all methods. For example, compressing when writing to a string is not supported. } \usage{ saveXML(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) \method{saveXML}{XMLInternalDocument}(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) \method{saveXML}{XMLInternalDOM}(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) \method{saveXML}{XMLNode}(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) \method{saveXML}{XMLOutputStream}(doc, file=NULL, compression=0, indent=TRUE, prefix = '\n', doctype = NULL, encoding = getEncoding(doc), ...) } \arguments{ \item{doc}{the document object representing the XML document.} \item{file}{the name of the file to which the contents of the XML nodes will be serialized.} \item{compression}{an integer value between 0 and 9 indicating the level of compression to use when saving the file. Higher values indicate increased compression and hence smaller files at the expense of computational time to do the compression and decompression.} \item{indent}{a logical value indicating whether to indent the nested nodes when serializing to the stream.} \item{prefix}{a string that is written to the stream/connection before the XML is output. If this is NULL, it is ignored. This allows us to put the XML introduction/preamble at the beginning of the document while allowing it to be omitted when we are outputting multiple "documents" within a single stream.} \item{doctype}{an object identifying the elements for the DOCTYPE in the output. This can be a string or an object of class \code{Doctype}.} \item{encoding}{a string indicating which encoding style to use. This is currently ignored except in the method in \code{Sxslt} for saving a document generated by applying an XSL style sheet to an XML document.} \item{\dots}{extra parameters for specific methods} } \details{ One can create an internal XML tree (or DOM) using \code{\link{newXMLDoc}} and \code{\link{newXMLNode}}. \code{saveXML} allows one to generate a textual representation of that DOM in human-readable and reusable XML format. \code{saveXML} is a generic function that allows one to call the rendering operation with either the top-level node of the DOM or of the document object (of class \code{XMLInternalDocument} that is used to accumulate the nodes and with which the developer adds nodes. } \value{ If \code{file} is not specified, the result is a character string containing the resulting XML content. If \code{file} is passed in the call, } \references{\url{https://www.w3.org/XML/}, \url{https://www.omegahat.net/RSXML/}} \author{Duncan Temple Lang} \seealso{ \code{\link{newXMLDoc}} \code{\link{newXMLNode}} \code{\link{xmlOutputBuffer}} \code{\link{xmlOutputDOM}} } \examples{ b = newXMLNode("bob") saveXML(b) f = tempfile() saveXML(b, f) doc = xmlInternalTreeParse(f) saveXML(doc) con <- xmlOutputDOM() con$addTag("author", "Duncan Temple Lang") con$addTag("address", close=FALSE) con$addTag("office", "2C-259") con$addTag("street", "Mountain Avenue.") con$addTag("phone", close=FALSE) con$addTag("area", "908", attrs=c(state="NJ")) con$addTag("number", "582-3217") con$closeTag() # phone con$closeTag() # address saveXML(con$value(), file=file.path(tempdir(), "out.xml")) # Work with entities f = system.file("exampleData", "test1.xml", package = "XML") doc = xmlRoot(xmlTreeParse(f)) outFile = tempfile() saveXML(doc, outFile) alt = xmlRoot(xmlTreeParse(outFile)) if(! identical(doc, alt) ) stop("Problems handling entities!") con = textConnection("test1.xml", "w") saveXML(doc, con) close(con) alt = get("test1.xml") identical(doc, alt) x = newXMLNode("a", "some text", newXMLNode("c", "sub text"), "more text") cat(saveXML(x), "\n") cat(as(x, "character"), "\n") # Showing the prefix parameter doc = newXMLDoc() n = newXMLNode("top", doc = doc) b = newXMLNode("bar", parent = n) # suppress the saveXML(doc, prefix = character()) # put our own comment in saveXML(doc, prefix = "") # or use a comment node. saveXML(doc, prefix = newXMLCommentNode("This is an alternative prefix")) } \keyword{IO} \keyword{file} XML/man/removeXMLNamespaces.Rd0000644000175100001440000000216613607633744015672 0ustar hornikusers\name{removeXMLNamespaces} %\Rdversion{1.1} \alias{removeXMLNamespaces} \alias{removeXMLNamespaces,XMLInternalNode-method} \alias{removeXMLNamespaces,XMLInternalElementNode-method} \alias{removeXMLNamespaces,XMLInternalDocument-method} \title{Remove namespace definitions from a XML node or document} \description{ This function and its methods allow one to remove one or more XML namespace definitions on XML nodes within a document. } \usage{ removeXMLNamespaces(node, ..., all = FALSE, .els = unlist(list(...))) } \arguments{ \item{node}{an XMLInternalNode or XMLInternalDocument object} \item{\dots}{the names of the namespaces to remove or an XMLNamespaceRef object returned via \code{\link{getNodeSet}} or \code{\link{xpathApply}}.} \item{all}{a logical value indicating whether to remove all the namespace definitions on a node.} \item{.els}{a list which is sometimes a convenient way to specify the namespaces to remove.} } \value{ This function is used for its side-effects and changing the internal node.} \author{ Duncan Temple Lang } \seealso{ \code{\link{newXMLNamespace}} } %\examples{} \keyword{IO} XML/man/readHTMLList.Rd0000644000175100001440000000350614316477364014251 0ustar hornikusers\name{readHTMLList} \alias{readHTMLList} \alias{readHTMLList,HTMLInternalDocument-method} \alias{readHTMLList,XMLInternalNode-method} \alias{readHTMLList,character-method} \title{Read data in an HTML list or all lists in a document} \description{ This function and its methods are somewhat similar to \code{\link{readHTMLTable}} but read the contents of lists in an HTML document. We can specify the URL of the document or an already parsed document or an individual node within the document. } \usage{ readHTMLList(doc, trim = TRUE, elFun = xmlValue, which = integer(), ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{doc}{the URL of the document or the parsed HTML document or an individual node.} \item{trim}{a logical value indicating whether we should remove leading and trailing white space in each list item when returning it} \item{elFun}{a function that is used to process each list item node (\code{li}). This provides an opportunity to customize how each node is processed, for example accessing attributes on the list item or on its contents such as links in the items.} \item{which}{an index or name which or vector of same which identifies which list nodes to process in the overall document. This is for subsetting particular lists rather than processing them all.} \item{\dots}{additional arguments passed to \code{\link{htmlParse}} and for the specific methods.} } \value{ A list of character vectors or lists, with one element for each list in the document. If only one list is being read (by specifying \code{which} as a single identifier), that is returned as is. } \author{ Duncan Temple Lang } \seealso{ \code{\link{readHTMLTable}} } \examples{\donttest{ try(readHTMLList("https://www.omegahat.net")) }} \keyword{IO} \keyword{programming} XML/man/names.XMLNode.Rd0000644000175100001440000000226614405636156014362 0ustar hornikusers\name{names.XMLNode} \alias{names.XMLNode} \title{Get the names of an XML nodes children.} \description{ This is a convenient way to obtain the XML tag name of each of the sub-nodes of a given \code{XMLNode} object. } \usage{ \method{names}{XMLNode}(x) } \arguments{ \item{x}{the \code{XMLNode} whose sub-node tag names are being queried.} } \value{ A character vector returning the tag names of the sub-nodes of the given \code{XMLNode} argument. } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \note{ This overrides the regular names method which would display the names of the internal fields of an \code{XMLNode} object. Since these are intended to be invisible and queried via the accessor methods (\code{\link{xmlName}}, \code{\link{xmlAttrs}}, etc.), this should not be a problem. If you really need the names of the fields, use \code{names(unclass(x))}. } \seealso{ \code{\link{xmlApply}} \code{\link{xmlSApply}} } \examples{ doc <- xmlTreeParse(system.file("exampleData", "mtcars.xml", package="XML")) names(xmlRoot(doc)) r <- xmlRoot(doc) r[names(r) == "variables"] } \keyword{file} XML/man/toString.Rd0000644000175100001440000000213214405636156013613 0ustar hornikusers\name{toString.XMLNode} \alias{toString.XMLNode} \title{Creates string representation of XML node} \description{ This creates a string from a hierarchical XML node and its children just as it prints on the console or one might see it in a document. } \usage{ \method{toString}{XMLNode}(x, ...) } \arguments{ \item{x}{an object of class \code{XMLNode}.} \item{\dots}{currently ignored} } \details{ This uses a textConnection object using the name .tempXMLOutput. Since this is global, it will overwrite any existing object of that name! As a result, this function cannot be used recursively in its present form. } \value{ A character vector with one element, that being the string corresponding to the XML node's contents. } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}} \author{Duncan Temple Lang} \note{ This requires the Expat XML parser to be installed. } \seealso{ \code{\link{xmlNode}} \code{\link{xmlTreeParse}} } \examples{ x <- xmlRoot(xmlTreeParse(system.file("exampleData", "gnumeric.xml", package = "XML"))) toString(x) } \keyword{file} XML/man/newXMLDoc.Rd0000644000175100001440000003557614405636156013624 0ustar hornikusers% insert facilities \name{newXMLDoc} \alias{newXMLDoc} \alias{newHTMLDoc} \alias{newXMLNode} \alias{newXMLPINode} \alias{newXMLCDataNode} \alias{newXMLCommentNode} \alias{newXMLTextNode} \alias{newXMLDTDNode} \alias{xmlDoc} \alias{coerce,vector,XMLInternalNode-method} \title{Create internal XML node or document object} \description{ These are used to create internal `libxml' nodes and top-level document objects that are used to write XML trees. While the functions are available, their direct use is not encouraged. Instead, use \code{\link{xmlTree}} as the functions need to be used within a strict regime to avoid corrupting C level structures. \code{xmlDoc} creates a new XMLInternalDocument object by copying the given node and all of its descendants and putting them into a new document. This is useful when we want to work with sub-trees with general tools that work on documents, e.g. XPath queries. \code{newXMLDoc} allows one to create a regular XML node with a name and attributes. One can provide new namespace definitions via \code{namespaceDefinitions}. While these might also be given in the attributes in the slightly more verbose form of \code{c('xmlns:prefix' = 'http://...')}, the result is that the XML node does not interpret that as a namespace definition but merely an attribute with a name 'xmlns:prefix'. Instead, one should specify the namespace definitions via the \code{namespaceDefinitions} parameter. In addition to namespace definitions, a node name can also have a namespace definition. This can be specified in the \code{name} argument as \code{prefix:name} and \code{newXMLDoc} will do the right thing in separating this into the namespace and regular name. Alternatively, one can specify a namespace separately via the \code{namespace} argument. This can be either a simple name or an internal namespace object defined earlier. How do we define a default namespace? } \usage{ xmlDoc(node, addFinalizer = TRUE) newXMLDoc(dtd = "", namespaces=NULL, addFinalizer = TRUE, name = character(), node = NULL, isHTML = FALSE) newHTMLDoc(dtd = "loose", addFinalizer = TRUE, name = character(), node = newXMLNode("html", newXMLNode("head", addFinalizer = FALSE), newXMLNode("body", addFinalizer = FALSE), addFinalizer = FALSE)) newXMLNode(name, ..., attrs = NULL, namespace = character(), namespaceDefinitions = character(), doc = NULL, .children = list(...), parent = NULL, at = NA, cdata = FALSE, suppressNamespaceWarning = getOption("suppressXMLNamespaceWarning", FALSE), sibling = NULL, addFinalizer = NA, noNamespace = length(namespace) == 0 && !missing(namespace), fixNamespaces = c(dummy = TRUE, default = TRUE)) newXMLTextNode(text, parent = NULL, doc = NULL, cdata = FALSE, escapeEntities = is(text, "AsIs"), addFinalizer = NA) newXMLCDataNode(text, parent = NULL, doc = NULL, at = NA, sep = "\n", addFinalizer = NA) newXMLCommentNode(text, parent = NULL, doc = NULL, at = NA, addFinalizer = NA) newXMLPINode(name, text, parent = NULL, doc = NULL, at = NA, addFinalizer = NA) newXMLDTDNode(nodeName, externalID = character(), systemID = character(), doc = NULL, addFinalizer = NA) } \arguments{ \item{node}{a \code{XMLInternalNode} object that will be copied to create a subtree for a new document.} \item{dtd}{the name of the DTD to use for the XML document. Currently ignored!} \item{namespaces}{a named character vector with each element specifying a name space identifier and the corresponding URI for that namespace that are to be declared and used in the XML document, \\ e.g. \code{c(shelp = "https://www.omegahat.net/XML/SHelp")}} \item{addFinalizer}{a logical value indicating whether the default finalizer routine should be registered to free the internal xmlDoc when R no longer has a reference to this external pointer object. This can also be the name of a C routine or a reference to a C routine retrieved using \code{\link{getNativeSymbolInfo}}. } \item{name}{the tag/element name for the XML node and the for a Processing Instruction (PI) node, this is the "target", e.g. the identifier for the system for whose attention this PI node is intended.} \item{...}{the children of this node. These can be other nodes created earlier or R strings that are converted to text nodes and added as children to this newly created node.} \item{attrs}{a named list of name-value pairs to be used as attributes for the XML node. One should not use this argument to define namespaces, i.e. attributes of the form \code{xmlns:prefix='http:/...'}. Instead, such definitions should be specified ideally via the \code{namespaceDefinitions} argument, or even the \code{namespace} argument. The reason is that namespace definitions are special attributes that are shared across nodes wherease regular attributes are particular to a node. So a namespace needs to be explicitly defined so that the XML representation can recognize it as such. } \item{namespace}{a character vector specifying the namespace for this new node. Typically this is used to specify i) the prefix of the namespace to use, or ii) one or more namespace definitions, or iii) a combination of both. If this is a character vector with a) one element and b) with an empty \code{names} attribute and c) whose value does not start with \code{http:/} or \code{ftp:/}, then it is assumed that the value is a namespace prefix for a namespace defined in an ancestor node. To be able to resolve this prefix to a namespace definition, \code{parent} must be specified so that we can traverse the chain of ancestor nodes. However, if c) does not hold, i.e. the string starts with \code{http:/} or \code{ftp:/}, then we take this single element to be a namespace definition and the since it has no name b), this is the definition for the default namespace for this new node, i.e. corresponding to \code{xmlns='http:/...'}. It is cumbersome to specify \code{""} as a name for an element in a character vector (as \code{c('' = 'value') gives an unnecessary error!}. Elements with names are expanded to namespace definitions with the name as the prefix and the value as the namespace URI. } \item{doc}{the \code{XMLInternalDocument} object created with \code{newXMLDoc} that is used to root the node.} \item{.children}{a list containing XML node elements or content. This is an alternative form of specifying the child nodes than \dots which is useful for programmatic interaction when the "sub"-content is already in a list rather than a loose collection of values.} \item{text}{the text content for the new XML node} \item{nodeName}{the name of the node to put in the DOCTYPE element that will appear as the top-most node in the XML document.} \item{externalID}{the PUBLIC identifier for the document type. This is a string of the form \code{A//B//C//D}. A is either + or -; B identifies the person or insitution that defined the format (i.e. the "creator"); C is the name of the format; and language is an encoding for the language that comes from the ISO 639 document.} \item{systemID}{the SYSTEM identifier for the DTD for the document. This is a URI} \item{namespaceDefinitions}{a character vector or a list with each element being a string. These give the URIs identifying the namespaces uniquely. The elements should have names which are used as prefixes. A default namespace has "" as the name. This argument can be used to remove any ambiguity that arises when specifying a single string with no names attribute as the value for \code{namespace}. The values here are used only for defining new namespaces and not for determining the namespace to use for this particular node. } \item{parent}{the node which will act as the parent of this newly created node. This need not be specified and one can add the new node to another node in a separate operation via \code{\link{addChildren}}.} \item{sibling}{if this is specified (rather than \code{parent}) this should be an \code{XMLInternalNode} and the new node is added as a sibling of this node, after this node, i.e. to the right. This is just a convenient form of \code{parent = xmlParent(node)}.} \item{cdata}{a logical value indicating whether to enclose the text within a CDATA node (\code{TRUE}) or not (\code{FALSE}). This is a convenience mechanism to avoid having to create the text node and then the CDATA node. If one is not certain what characters are in the text, it is useful to use \code{TRUE} to ensure that they are \dQuote{escaped}. It is an argument for \code{newXMLNode} as the child nodes can be given as simple strings and are converted to text nodes. This \code{cdata} value is passed to the calls to create these text nodes and so controls whether they are enclosed within CDATA nodes. } \item{suppressNamespaceWarning}{see \code{\link{addChildren}}} \item{at}{this allows one to control the position in the list of children at which the node should be added. The default means at the end and this can be any position from 0 to the current number of children.} \item{sep}{when adding text nodes, this is used as an additional separator text to insert between the specified strings.} \item{escapeEntities}{a logical value indicating whether to mark the internal text node in such a way that protects characters in its contents from being escaped as entities when being serialized via \code{\link{saveXML}}} \item{noNamespace}{a logical value that allows the caller to specify that the new node has no namespace. This can avoid searching parent and ancestor nodes up the tree for the default namespace.} \item{isHTML}{a logical value that indicates whether the XML document being created is HTML or generic XML. This helps to create an object that is identified as an HTML document.} \item{fixNamespaces}{a logical vector controlling how namespaces in child nodes are to be processed. The two entries should be named \code{dummy} and \code{default}. The \code{dummy} element controls whether we process child nodes that have a namespace which was not defined when the node was created. These are created as \dQuote{dummy} namespaces and can be resolved now that the parent node is defined and the name space may be defined. When we know it is not yet defined, but will be defined in an ancestor node, we can turn off this processing with a value of \code{FALSE}. The \code{default} element controls how we process the child nodes and give them the default name space defined in the parent or ancestor nodes.} } \details{ These create internal C level objects/structure instances that can be added to a libxml DOM and subsequently inserted into other document objects or ``serialized'' to textual form. } \value{ Each function returns an R object that points to the C-level structure instance. These are of class \code{XMLInternalDocument} and \code{XMLInternalNode}, respectively } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}, \url{https://www.omegahat.net}} \author{ Duncan Temple Lang } \note{These functions are used to build up an internal XML tree. This can be used in the Sxslt package (\url{https://www.omegahat.net/Sxslt/}) when creating content in R that is to be dynamically inserted into an XML document.} \seealso{ \code{\link{xmlTree}} \code{saveXML} } \examples{ doc = newXMLDoc() # Simple creation of an XML tree using these functions top = newXMLNode("a") newXMLNode("b", attrs = c(x = 1, y = 'abc'), parent = top) newXMLNode("c", "With some text", parent = top) d = newXMLNode("d", newXMLTextNode("With text as an explicit node"), parent = top) newXMLCDataNode("x <- 1\n x > 2", parent = d) newXMLPINode("R", "library(XML)", top) newXMLCommentNode("This is a comment", parent = top) o = newXMLNode("ol", parent = top) kids = lapply(letters[1:3], function(x) newXMLNode("li", x)) addChildren(o, kids) cat(saveXML(top)) x = newXMLNode("block", "xyz", attrs = c(id = "bob"), namespace = "fo", namespaceDefinitions = c("fo" = "http://www.fo.org")) xmlName(x, TRUE) == "fo" # a short cut to define a name space and make it the prefix for the # node, thus avoiding repeating the prefix via the namespace argument. x = newXMLNode("block", "xyz", attrs = c(id = "bob"), namespace = c("fo" = "http://www.fo.org")) # name space on the attribute x = newXMLNode("block", attrs = c("fo:id" = "bob"), namespaceDefinitions = c("fo" = "http://www.fo.org")) x = summary(rnorm(1000)) d = xmlTree() d$addNode("table", close = FALSE) d$addNode("tr", .children = sapply(names(x), function(x) d$addNode("th", x))) d$addNode("tr", .children = sapply(x, function(x) d$addNode("td", format(x)))) d$closeNode() # Just doctype z = xmlTree("people", dtd = "people") # no public element z = xmlTree("people", dtd = c("people", "", "https://www.omegahat.net/XML/types.dtd")) # public and system z = xmlTree("people", dtd = c("people", "//a//b//c//d", "https://www.omegahat.net/XML/types.dtd")) # Using a DTD node directly. dtd = newXMLDTDNode(c("people", "", "https://www.omegahat.net/XML/types.dtd")) z = xmlTree("people", dtd = dtd) x = rnorm(3) z = xmlTree("r:data", namespaces = c(r = "http://www.r-project.org")) z$addNode("numeric", attrs = c("r:length" = length(x)), close = FALSE) lapply(x, function(v) z$addNode("el", x)) z$closeNode() # should give # shows namespace prefix on an attribute, and different from the one on the node. z = xmlTree() z$addNode("r:data", namespace = c(r = "http://www.r-project.org", omg = "https://www.omegahat.net"), close = FALSE) x = rnorm(3) z$addNode("r:numeric", attrs = c("omg:length" = length(x))) z = xmlTree("people", namespaces = list(r = "http://www.r-project.org")) z$setNamespace("r") z$addNode("person", attrs = c(id = "123"), close = FALSE) z$addNode("firstname", "Duncan") z$addNode("surname", "Temple Lang") z$addNode("title", "Associate Professor") z$addNode("expertize", close = FALSE) z$addNode("topic", "Data Technologies") z$addNode("topic", "Programming Language Design") z$addNode("topic", "Parallel Computing") z$addNode("topic", "Data Visualization") z$closeTag() z$addNode("address", "4210 Mathematical Sciences Building, UC Davis") # txt = newXMLTextNode("x < 1") txt # okay saveXML(txt) # x &lt; 1 # By escaping the text, we ensure the entities don't # get expanded, i.e. < doesn't become &lt; txt = newXMLTextNode(I("x < 1")) txt # okay saveXML(txt) # x < 1 newXMLNode("r:expr", newXMLTextNode(I("x < 1")), namespaceDefinitions = c(r = "http://www.r-project.org")) } \keyword{IO} XML/man/libxmlVersion.Rd0000644000175100001440000000402714405636156014644 0ustar hornikusers\name{libxmlVersion} \alias{libxmlVersion} \alias{libxmlFeatures} \title{Query the version and available features of the libxml library.} \description{ \code{libxmlVersion} retrieves the version of the libxml library used when installing this XML package. \code{libxmlFeatures} returns a named logical vector indicating which features are enabled. } \usage{ libxmlVersion(runTime = FALSE) libxmlFeatures() } \arguments{ \item{runTime}{a logical value indicating whether to retrieve the version information describing libxml when the R package was compiled or the run-time version. These may be different if a) a new version of libxml2 is installed after the package is installed, b) if the package was installed as a binary package built on a different machine. } } \value{ \code{libxmlVersion} returns a named list with fields \item{major}{the major version number, either 1 or 2 indicating the old or new-style library.} \item{minor}{the within version release number.} \item{patch}{the within minor release version number} \code{libxmlFeatures} returns a logical vector with names given by: \code{ [1] "THREAD" "TREE" "OUTPUT" "PUSH" "READER" [6] "PATTERN" "WRITER" "SAX1" "FTP" "HTTP" [11] "VALID" "HTML" "LEGACY" "C14N" "CATALOG" [16] "XPATH" "XPTR" "XINCLUDE" "ICONV" "ISO8859X" [21] "UNICODE" "REGEXP" "AUTOMATA" "EXPR" "SCHEMAS" [26] "SCHEMATRON" "MODULES" "DEBUG" "DEBUG_MEM" "DEBUG_RUN" [31] "ZLIB" } Elements are either \code{TRUE} or \code{FALSE} indicating whether support was activatd for that feature, or \code{NA} if that feature is not part of the particular version of libcurl. } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } %\seealso{} \examples{ ver <- libxmlVersion() if(is.null(ver)) { cat("Relly old version of libxml\n") } else { if(ver$major > 1) { cat("Using libxml2\n") } } } \keyword{IO} XML/man/xmlParserContextFunction.Rd0000644000175100001440000000400613607633744017037 0ustar hornikusers\name{xmlParserContextFunction} \alias{xmlParserContextFunction} \title{Identifies function as expecting an xmlParserContext argument} \description{ This is a convenience function for setting the class of the specified function to include \code{"XMLParserContextFunction"}. This identifies it as expecting an \code{xmlParserCtxt} object as its first argument. The resulting function can be passed to the internal/native XML parser as a handler/callback function. When the parser calls it, it recognizes this class information and includes a reference to the C-level \code{xmlParserCtxt} object as the first argument in the call. This \code{xmlParserCtxt} object can be used to gracefully terminate the parsing (without an error), and in the future will also provide access to details about the current state of the parser, e.g. the encoding of the file, the XML version, whether entities are being replaced, line and column number for each node processed. } \usage{ xmlParserContextFunction(f, class = "XMLParserContextFunction") } \arguments{ \item{f}{the function whose class information is to be augmented.} \item{class}{the name of the class which is to be added to the \code{class} attribute of the function.} } \value{ The function object \code{f} whose class attribute has been prepended with the value of \code{class}. } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlInternalTreeParse}}/\code{\link{xmlParse}} and the \code{branches} parameter of \code{\link{xmlEventParse}}. } \examples{ fun = function(context, ...) { # do things to parse the node # using the context if necessary. cat("In XMLParserContextFunction\n") xmlStopParser(context) } fun = xmlParserContextFunction(fun) txt = "" # doesn't work for xmlTreeParse() # xmlTreeParse(txt, handlers = list(a = fun)) # but does in xmlEventParse(). xmlEventParse(txt, handlers = list(startElement = fun), asText = TRUE) } \keyword{IO} \keyword{programming} \concept{XML} XML/man/xmlStopParser.Rd0000644000175100001440000000446113607633744014637 0ustar hornikusers\name{xmlStopParser} \alias{xmlStopParser} \title{Terminate an XML parser} \description{ This function allows an R-level function to terminate an XML parser before it completes the processing of the XML content. This might be useful, for example, in event-driven parsing with \code{\link{xmlEventParse}} when we want to read through an XML file until we find a record of interest. Then, having retrieved the necessary information, we want to terminate the parsing rather than let it pointlessly continue. Instead of raising an error in our handler function, we can call \code{xmlStopParser} and return. The parser will then take control again and terminate and return back to the original R function from which it was invoked. The only argument to this function is a reference to internal C-level which identifies the parser. This is passed by the R-XML parser mechanism to a function invoked by the parser if that function inherits (in the S3 sense) from the class \code{XMLParserContextFunction}. } \usage{ xmlStopParser(parser) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{parser}{ an object of class \code{XMLParserContext} which must have been obtained by via an \code{XMLParserContextFunction} function called by the parser. This is just a handler function whose class includes \code{XMLParserContextFunction} } } \value{ \code{TRUE} if it succeeded and an error is raised if the \code{parser} object is not valid. } \references{libxml2 \url{http://xmlsoft.org}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlEventParse}} } \examples{ ############################################ # Stopping the parser mid-way and an example of using XMLParserContextFunction. startElement = function(ctxt, name, attrs, ...) { print(ctxt) print(name) if(name == "rewriteURI") { cat("Terminating parser\n") xmlStopParser(ctxt) } } class(startElement) = "XMLParserContextFunction" endElement = function(name, ...) cat("ending", name, "\n") fileName = system.file("exampleData", "catalog.xml", package = "XML") xmlEventParse(fileName, handlers = list(startElement = startElement, endElement = endElement)) } \keyword{IO} \keyword{programming} \concept{Error handling} \concept{streaming data} XML/man/print.Rd0000644000175100001440000000636014405636156013145 0ustar hornikusers\name{print.XMLAttributeDef} \alias{print.XMLAttributeDef} \alias{print.XMLCDataNode} \alias{print.XMLElementContent} \alias{print.XMLElementDef} \alias{print.XMLEntity} \alias{print.XMLEntityRef} \alias{print.XMLNode} \alias{print.XMLTextNode} \alias{print.XMLComment} \alias{print.XMLOrContent} \alias{print.XMLSequenceContent} \alias{print.XMLProcessingInstruction} \title{Methods for displaying XML objects} \description{ These different methods attempt to provide a convenient way to display R objects representing XML elements when they are printed in the usual manner on the console, files, etc. via the \code{\link{print}} function. Each typically outputs its contents in the way that they would appear in an XML document. } \usage{ \method{print}{XMLNode}(x, ..., indent= "", tagSeparator = "\n") \method{print}{XMLComment}(x, ..., indent = "", tagSeparator = "\n") \method{print}{XMLTextNode}(x, ..., indent = "", tagSeparator = "\n") \method{print}{XMLCDataNode}(x, ..., indent="", tagSeparator = "\n") \method{print}{XMLProcessingInstruction}(x, ..., indent="", tagSeparator = "\n") \method{print}{XMLAttributeDef}(x, ...) \method{print}{XMLElementContent}(x, ...) \method{print}{XMLElementDef}(x, ...) \method{print}{XMLEntity}(x, ...) \method{print}{XMLEntityRef}(x, ..., indent= "", tagSeparator = "\n") \method{print}{XMLOrContent}(x, ...) \method{print}{XMLSequenceContent}(x, ...) } \arguments{ \item{x}{the XML object to be displayed} \item{...}{additional arguments for controlling the output from print. Currently unused.} \item{indent}{a prefix that is emitted before the node to indent it relative to its parent and child nodes. This is appended with a space at each succesive level of the tree. If no indentation is desired (e.g. when \code{\link{xmlTreeParse}} is called with \code{trim} and \code{ignoreBlanks} being \code{FALSE}) and \code{TRUE} respectively, one can pass the value \code{FALSE} for this \code{indent} argument. } \item{tagSeparator}{when printing nodes, successive nodes and children are by default displayed on new lines for easier reading. One can specify a string for this argument to control how the elements are separated in the output. The primary purpose of this argument is to allow no space between the elements, i.e. a value of \code{""}. } } \value{ Currently, \code{NULL}. } \references{\url{https://www.w3.org}, \url{https://www.omegahat.net/RSXML/}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} } \note{We could make the node classes self describing with information about whether \code{ignoreBlanks} was \code{TRUE} or \code{FALSE} and if trim was TRUE or FALSE. This could then be used to determine the appropriate values for \code{indent} and \code{tagSeparator}. Adding an S3 class element would allow this to be done without the addition of an excessive number of classes. } \examples{ fileName <- system.file("exampleData", "event.xml", package ="XML") # Example of how to get faithful copy of the XML. doc = xmlRoot(xmlTreeParse(fileName, trim = FALSE, ignoreBlanks = FALSE)) print(doc, indent = FALSE, tagSeparator = "") # And now the default mechanism doc = xmlRoot(xmlTreeParse(fileName)) print(doc) } \keyword{IO} \keyword{file} XML/man/xmlParseDoc.Rd0000644000175100001440000000545113607633744014235 0ustar hornikusers\name{xmlParseDoc} \Rdversion{1.1} \alias{xmlParseDoc} \alias{COMPACT} \alias{DTDATTR} \alias{DTDLOAD} \alias{DTDVALID} \alias{HUGE} \alias{NOBASEFIX} \alias{NOBLANKS} \alias{NOCDATA} \alias{NODICT} \alias{NOENT} \alias{NOERROR} \alias{NONET} \alias{NOWARNING} \alias{NOXINCNODE} \alias{NSCLEAN} \alias{OLDSAX} \alias{PEDANTIC} \alias{RECOVER} \alias{XINCLUDE} \alias{OLD10} \alias{SAX1} \title{Parse an XML document with options controlling the parser.} \description{ This function is a generalization of \code{\link{xmlParse}} that parses an XML document. With this function, we can specify a combination of different options that control the operation of the parser. The options control many different aspects the parsing process } \usage{ xmlParseDoc(file, options = 1L, encoding = character(), asText = !file.exists(file), baseURL = file) } \arguments{ \item{file}{the name of the file or URL or the XML content itself} \item{options}{options controlling the behavior of the parser. One specifies the different options as elements of an integer vector. These are then bitwised OR'ed together. The possible options are \code{RECOVER}, \code{NOENT}, \code{DTDLOAD}, \code{DTDATTR}, \code{DTDVALID}, \code{NOERROR}, \code{NOWARNING}, \code{PEDANTIC}, \code{NOBLANKS}, \code{SAX1}, \code{XINCLUDE}, \code{NONET}, \code{NODICT}, \code{NSCLEAN}, \code{NOCDATA}, \code{NOXINNODE}, \code{COMPACT}, \code{OLD10}, \code{NOBASEFIX}, \code{HUGE}, \code{OLDSAX}. ( These options are also listed in the (non-exported) variable \code{parserOptions}.) } \item{encoding}{character string that provides the encoding of the document if it is not explicitly contained within the document itself.} \item{asText}{a logical value indicating whether \code{file} is the XML content (\code{TRUE}) or the name of a file or URL (\code{FALSE})} \item{baseURL}{the base URL used for resolving relative documents, e.g. XIncludes. This is important if \code{file} is the actual XML content rather than a URL} } \value{ An object of class \code{XMLInternalDocument}. } \references{libxml2} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlParse}} } \examples{ f = system.file("exampleData", "mtcars.xml", package="XML") # Same as xmlParse() xmlParseDoc(f) txt = ' ' xmlParseDoc(txt, NSCLEAN, asText = TRUE) txt = ' ' xmlParseDoc(txt, c(NSCLEAN, NOERROR), asText = TRUE) } \keyword{data} \concept{XML} XML/man/getEncoding.Rd0000644000175100001440000000177313700532410014223 0ustar hornikusers\name{getEncoding} %\Rdversion{1.1} \alias{getEncoding} \alias{getEncoding,XMLInternalDocument-method} \alias{getEncoding,XMLInternalNode-method} \alias{getEncoding,ANY-method} \title{Determines the encoding for an XML document or node} \description{ This function and its methods are intended to return the encoding of n XML . It is similar to \code{\link{Encoding}} but currently restricted to XML nodes and documents. } \usage{ getEncoding(obj, ...) } \arguments{ \item{obj}{the object whose encoding is being queried.} \item{\dots}{any additional parameters which can be customized by the methods.} } \value{ A character vector of length 1 giving the encoding of the XML document. } \author{ Duncan Temple Lang} \examples{ f = system.file("exampleData", "charts.svg", package = "XML") doc = xmlParse(f) getEncoding(doc) n = getNodeSet(doc, "//g/text")[[1]] getEncoding(n) f = system.file("exampleData", "iTunes.plist", package = "XML") doc = xmlParse(f) getEncoding(doc) } \keyword{IO} XML/man/xmlChildren.Rd0000644000175100001440000000334714405636156014264 0ustar hornikusers\name{xmlChildren} \alias{xmlChildren} \alias{xmlChildren<-} \alias{xmlChildren.XMLNode} \alias{xmlChildren.XMLInternalNode} \alias{xmlChildren.XMLInternalDocument} \alias{xmlChildren<-,XMLInternalNode-method} \alias{xmlChildren<-,ANY-method} \title{ Gets the sub-nodes within an XMLNode object. } \description{ These functions provide access to the children of the given XML node. The simple accessor returns a list of child XMLNode objects within an XMLNode object. The assignment operator (\code{xmlChildren<-}) sets the children of the node to the given value and returns the updated/modified node. No checking is currently done on the type and values of the right hand side. This allows the children of the node to be arbitrary R objects. This can be useful but means that one cannot rely on any structure in a node being present.. } \usage{ xmlChildren(x, addNames= TRUE, ...) } \arguments{ \item{x}{an object of class XMLNode.} \item{addNames}{a logical value indicating whether to add the XML names of the nodes as names of the R list. This is only relevant for XMLInternalNode objects as XMLNode objects in R already have R-level names. } \item{\dots}{additional arguments for the particular methods, e.g. \code{omitTypes} for an XMLInternalNode.} } \value{ A list whose elements are sub-nodes of the user-specified XMLNode. These are also of class XMLNode. } \references{\url{https://www.w3.org/XML/}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlChildren}},\code{\link{xmlSize}}, \code{\link{xmlTreeParse}} } \examples{ fileName <- system.file("exampleData", "mtcars.xml", package="XML") doc <- xmlTreeParse(fileName) names(xmlChildren(doc$doc$children[["dataset"]])) } \keyword{file} XML/man/addSibling.Rd0000644000175100001440000000572613607633730014054 0ustar hornikusers \name{getSibling} \alias{getSibling} \alias{addSibling} \title{Manipulate sibling XML nodes} \description{ These functions allow us to both access the sibling node to the left or right of a given node and so walk the chain of siblings, and also to insert a new sibling } \usage{ getSibling(node, after = TRUE, ...) addSibling(node, ..., kids = list(...), after = NA) } \arguments{ \item{node}{the internal XML node (XMLInternalNode) whose siblings are of interest} \item{\dots}{the XML nodes to add as siblings or children to node.} \item{kids}{a list containing the XML nodes to add as siblings. This is equivalent to ... but used when we already have the nodes in a list rather than as individual objects. This is used in programmatic calls to \code{addSibling} rather interactive use where we more commonly have the individual node objects. } \item{after}{a logical value indicating whether to retrieve or add the nodes to the right (\code{TRUE}) or to the left (\code{FALSE}) of this sibling. } } \value{ \code{getSibling} returns an object of class XMLInternalNode (or some derived S3 class, e.g. XMLInternalTextNode) \code{addSibling} returns a list whose elements are the newly added XML (internal) nodes. } \seealso{ \code{\link{xmlChildren}}, \code{\link{addChildren}} \code{\link{removeNodes}} \code{\link{replaceNodes}} } \examples{ # Reading Apple's iTunes files # # Here we read a "censored" "database" of songs from Apple's iTune application # which is stored in a property list. The format is quite generic and # the fields for each song are given in the form # # ArtistPerson's name # # So to find the names of the artists for all the songs, we want to # find all the Artist nodes and then get their next sibling # which has the actual value. # # More information can be found in . # fileName = system.file("exampleData", "iTunes.plist", package = "XML") doc = xmlParse(fileName) nodes = getNodeSet(doc, "//key[text() = 'Artist']") sapply(nodes, function(x) xmlValue(getSibling(x))) f = system.file("exampleData", "simple.xml", package = "XML") tt = as(xmlParse(f), "XMLHashTree") tt e = getSibling(xmlRoot(tt)[[1]]) # and back to the first one again by going backwards along the sibling list. getSibling(e, after = FALSE) # This also works for multiple top-level "root" nodes f = system.file("exampleData", "job.xml", package = "XML") tt = as(xmlParse(f), "XMLHashTree") x = xmlRoot(tt, skip = FALSE) getSibling(x) getSibling(getSibling(x), after = FALSE) } \keyword{IO} XML/man/getLineNumber.Rd0000644000175100001440000000412614250171714014537 0ustar hornikusers\name{getLineNumber} \alias{getNodeLocation} \alias{getNodePosition} \alias{getLineNumber} \title{Determine the location - file & line number of an (internal) XML node} \description{ The \code{getLineNumber} function is used to query the location of an internal/C-level XML node within its original "file". This gives us the line number. \code{getNodeLocation} gives both the line number and the name of the file in which the node is located, handling XInclude files in a top-level document and identifying the included file, as appropriate. \code{getNodePosition} returns a simplified version of \code{getNodeLocation}, combining the file and line number into a string and ignoring the \code{XPointer} component. This is useful when we identify a node with a particular charactestic and want to view/edit the original document, e.g. when authoring an Docbook article. } \usage{ getLineNumber(node, ...) getNodeLocation(node, recursive = TRUE, fileOnly = FALSE) } \arguments{ \item{node}{the node whose location or line number is of interest} \item{\dots}{additional parameters for methods should they be defined.} \item{recursive}{a logical value that controls whether the full path of the nested includes is returned or just the path in the immediate XInclude element.} \item{fileOnly}{a logical value which if \code{TRUE} means that only the name of the file is returned, and not the \code{xpointer} attribute or line number .} } \value{ \code{getLineNumber} returns an integer. \code{getNodeLocation} returns a list with two elements - \code{file} and \code{line} which are a character string and the integer line number. For text nodes, the line number is taken from the previous sibling nodes or the parent node. } \references{libxml2 } \author{Duncan Temple Lang} \seealso{ \code{\link{findXInclude}} \code{\link{xmlParse}} \code{\link{getNodeSet}} \code{\link{xpathApply}} } \examples{ f = system.file("exampleData", "xysize.svg", package = "XML") doc = xmlParse(f) e = getNodeSet(doc, "//ellipse") sapply(e, getLineNumber) } \keyword{IO} \concept{XML} XML/man/xmlApply.Rd0000644000175100001440000000346214405636156013617 0ustar hornikusers\name{xmlApply} \alias{xmlApply} \alias{xmlApply.XMLNode} \alias{xmlApply.XMLDocument} \alias{xmlApply.XMLDocumentContent} \alias{xmlSApply} \alias{xmlSApply.XMLNode} \alias{xmlSApply.XMLDocument} \alias{xmlSApply.XMLDocumentContent} \title{Applies a function to each of the children of an XMLNode} \description{ These methods are simple wrappers for the \code{\link{lapply}} and \code{\link{sapply}} functions. They operate on the sub-nodes of the XML node, and not on the fields of the node object itself. } \usage{ xmlApply(X, FUN, ...) \method{xmlApply}{XMLNode}(X, FUN, ...) \method{xmlApply}{XMLDocument}(X, FUN, ...) \method{xmlApply}{XMLDocumentContent}(X, FUN, ...) xmlSApply(X, FUN, ...) \method{xmlSApply}{XMLNode}(X, FUN, ...) \method{xmlSApply}{XMLDocument}(X, FUN, ...) } \arguments{ \item{X}{the \code{XMLNode} on whose children the regular \code{\link{apply}} or \code{\link{sapply}} is to be performed} \item{FUN}{the function to apply to each child node. This is passed directly to the relevant \code{\link{apply}} function.} \item{\dots}{additional arguments to be given to each invocation of \code{FUN}. This is passed directly to the relevant \code{\link{apply}} function.} } \value{ The result is that obtained from calling the \code{\link{apply}} or \code{\link{sapply}} on \code{xmlChildren(x)}. } \references{ \url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlChildren}} \code{\link{xmlRoot}} \code{\link{[.XMLNode}} \code{\link{sapply}} \code{\link{lapply}} } \examples{ doc <- xmlTreeParse(system.file("exampleData", "mtcars.xml", package="XML")) r <- xmlRoot(doc) xmlSApply(r[[2]], xmlName) xmlApply(r[[2]], xmlAttrs) xmlSApply(r[[2]], xmlSize) } \keyword{file} XML/man/xmlTree.Rd0000644000175100001440000001350014405636156013423 0ustar hornikusers\name{xmlTree} \alias{xmlTree} \title{An internal, updatable DOM object for building XML trees} \description{ This is a mutable object (implemented via a closure) for representing an XML tree, in the same spirit as \code{\link{xmlOutputBuffer}} and \code{\link{xmlOutputDOM}} but that uses the internal structures of libxml. This can be used to create a DOM that can be constructed in R and exported to another system such as XSLT (\url{https://www.omegahat.net/Sxslt/}) } \usage{ xmlTree(tag, attrs = NULL, dtd=NULL, namespaces=list(), doc = newXMLDoc(dtd, namespaces)) } \arguments{ \item{tag}{the node or element name to use to create the new top-level node in the tree or alternatively, an \code{XMLInternalNode} that was already created. This is optional. If it is not specified, no top-most node is created but can be added using \code{addNode}. If a top-level tag is added in the call to \code{xmlTree}, that becomes the currently active or open node (e.g. same as \code{addNode( ..., close = FALSE)}) and nodes subsequently added to this } \item{attrs}{attributes for the top-level node, in the form of a named character vector.} \item{dtd}{the name of the external DTD for this document. If specified, this adds the DOCTYPE node to the resulting document. This can be a node created earlier with a call to \code{\link{newXMLDTDNode}}, or alternatively it can be a character vector with 1, 2 or 3 elements giving the name of the top-level node, and the public identifier and the system identifier for the DTD in that order. } \item{namespaces}{a named character vector with each element giving the name space identifier and the corresponding URI, \\ e.g \code{c(shelp = "https://www.omegahat.net/XML/SHelp")} If \code{tag} is specified as a character vector, these name spaces are defined within that new node. } \item{doc}{an internal XML document object, typically created with \code{\link{newXMLDoc}}. This is used as the host document for all the new nodes that will be created as part of this document. If one wants to create nodes without an internal document ancestor, one can alternatively specify this is as \code{NULL}.} } \details{ This creates a collection of functions that manipulate a shared state to build and maintain an XML tree in C-level code. } \value{ An object of class \code{XMLInternalDOM} that extends \code{XMLOutputStream} and has the same interface (i.e. ``methods'') as \code{\link{xmlOutputBuffer}} and \code{\link{xmlOutputDOM}}. Each object has methods for adding a new XML tag, closing a tag, adding an XML comment, and retrieving the contents of the tree. \item{addTag}{create a new tag at the current position, optionally leaving it as the active open tag to which new nodes will be added as children} \item{closeTag}{close the currently active tag making its parent the active element into which new nodes will be added.} \item{addComment}{add an XML comment node as a child of the active node in the document.} \item{value}{retrieve an object representing the XML tree. See \code{\link{saveXML}} to serialize the contents of the tree.} \item{add}{degenerate method in this context.} } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \note{This is an early version of this function and I need to iron out some of the minor details.} \seealso{ \code{\link{saveXML}} \code{\link{newXMLDoc}} \code{\link{newXMLNode}} \code{\link{xmlOutputBuffer}} \code{\link{xmlOutputDOM}} } \examples{ z = xmlTree("people", namespaces = list(r = "http://www.r-project.org")) z$setNamespace("r") z$addNode("person", attrs = c(id = "123"), close = FALSE) z$addNode("firstname", "Duncan") z$addNode("surname", "Temple Lang") z$addNode("title", "Associate Professor") z$addNode("expertize", close = FALSE) z$addNode("topic", "Data Technologies") z$addNode("topic", "Programming Language Design") z$addNode("topic", "Parallel Computing") z$addNode("topic", "Data Visualization") z$addNode("topic", "Meta-Computing") z$addNode("topic", "Inter-system interfaces") z$closeTag() z$addNode("address", "4210 Mathematical Sciences Building, UC Davis") z$closeTag() tr <- xmlTree("CDataTest") tr$addTag("top", close=FALSE) tr$addCData("x <- list(1, a='&');\nx[[2]]") tr$addPI("S", "plot(1:10)") tr$closeTag() cat(saveXML(tr$value())) f = tempfile() saveXML(tr, f, encoding = "UTF-8") # Creating a node x = rnorm(3) z = xmlTree("r:data", namespaces = c(r = "http://www.r-project.org")) z$addNode("numeric", attrs = c("r:length" = length(x))) # shows namespace prefix on an attribute, and different from the one on the node. z = xmlTree() z$addNode("r:data", namespace = c(r = "http://www.r-project.org", omg = "https://www.omegahat.net"), close = FALSE) x = rnorm(3) z$addNode("r:numeric", attrs = c("omg:length" = length(x))) z = xmlTree("examples") z$addNode("example", namespace = list(r = "http://www.r-project.org"), close = FALSE) z$addNode("code", "mean(rnorm(100))", namespace = "r") x = summary(rnorm(1000)) d = xmlTree() d$addNode("table", close = FALSE) d$addNode("tr", .children = sapply(names(x), function(x) d$addNode("th", x))) d$addNode("tr", .children = sapply(x, function(x) d$addNode("td", format(x)))) d$closeNode() cat(saveXML(d)) # Dealing with DTDs and system and public identifiers for DTDs. # Just doctype za = xmlTree("people", dtd = "people") ### www.omegahat.net is flaky # no public element zb = xmlTree("people", dtd = c("people", "", "https://www.omegahat.net/XML/types.dtd")) # public and system zc = xmlTree("people", dtd = c("people", "//a//b//c//d", "https://www.omegahat.net/XML/types.dtd")) } \keyword{IO} XML/man/xmlOutput.Rd0000644000175100001440000001271714405636156014035 0ustar hornikusers\name{xmlOutputBuffer} \alias{xmlOutputBuffer} \alias{xmlOutputDOM} \title{XML output streams} \description{ These two functions provide different ways to construct XML documents incrementally. They provide a single, common interface for adding and closing tags, and inserting nodes. The buffer version stores the XML representation as a string. The DOM version builds the tree of XML node objects entirely within R. } \usage{ xmlOutputBuffer(dtd=NULL, nameSpace="", buf=NULL, nsURI=NULL, header="") xmlOutputDOM(tag="doc", attrs = NULL, dtd=NULL, nameSpace=NULL, nsURI=character(0), xmlDeclaration = NULL) } \arguments{ \item{dtd}{a DTD object (see \code{\link{parseDTD}} and \code{\link{xmlTreeParse}}) which contains specifications about what elements are valid within other elements and what attributes are supported by different elements. This can be used to validate the document as it is being constructed incrementally.} \item{attrs}{attributes for the top-level node, in the form of a named vector or list.} \item{nameSpace}{the default namespace identifier to be used when an element is created without an explicit namespace. This provides a convenient way to specify the default name space that appers in tags throughout the resulting document.} \item{buf}{a connection object or a string into which the XML content is written. This is currently a simplistic implementation since we will use the OOP-style classes from the Omegahat projects in the future.} \item{nsURI}{the URI or value for the name space which is used when declaring the namespace. For \code{xmlOuputDOM}, this is a named character vector with each element giving the name space identifier and the corresponding URI, \\ e.g \code{c(shelp = "https://www.omegahat.net/XML/SHelp")} } \item{header}{if non-NULL, this is immediately written to the output stream allowing one to control the initial section of the XML document.} \item{tag}{the name of the top-level node/element in the DOM being created.} \item{xmlDeclaration}{ a logical value or a string. If this is a logical value and \code{TRUE}, the default processing instruction is emitted at the top of the document. If it is \code{FALSE}, no xml declaration is emitted at the top of the document. If this is provided as a string, the contents of this is added as the content of the processing instruction. A version='1.0' is added if there is no 'version=' content within the given string. } } \details{ These functions create a closure instance which provides methods or functions that operate on shared data used to represent the contents of the XML document being created and the current state of that creation. } \value{ Both of these functions return a list of functions which operate on the XML data in a shared environment. \item{value}{get the contents of the XML document as they are currently defined.} \item{addTag}{add a new element to the document, specifying its name and attributes. This allows the tag to be left open so that new elements will be added as children of it.} \item{closeTag}{close the currently open tag, indicating that new elements will be added, by default, as siblings of this one.} \item{reset}{discard the current contents of the document so that we can start over and free the resources (memory) associated with this document.} The following are specific to \code{xmlOutputDOM}: \item{addNode}{insert an complete \code{XMLNode} object into the currently active (i.e. open) node.} \item{current}{obtain the path or collection of indices to to the currently active/open node from the root node.} } \references{\url{https://www.omegahat.net/RSXML/}, \url{https://www.w3.org/XML//}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTree}} for a native/internal (C-level) representation of the tree, \code{\link{xmlNode}}, \code{\link{xmlTextNode}}, \code{\link{append.xmlNode}} And a different representation of a tree is available via \code{\link{xmlHashTree}}. } \examples{ con <- xmlOutputDOM() con$addTag("author", "Duncan Temple Lang") con$addTag("address", close=FALSE) con$addTag("office", "2C-259") con$addTag("street", "Mountain Avenue.") con$addTag("phone", close = FALSE) con$addTag("area", "908", attrs=c(state="NJ")) con$addTag("number", "582-3217") con$closeTag() # phone con$closeTag() # address con$addTag("section", close = FALSE) con$addNode(xmlTextNode("This is some text ")) con$addTag("a","and a link", attrs=c(href="https://www.omegahat.net")) con$addNode(xmlTextNode("and some follow up text")) con$addTag("subsection", close = FALSE) con$addNode(xmlTextNode("some addtional text ")) con$addTag("a", attrs=c(href="https://www.omegahat.net"), close=FALSE) con$addNode(xmlTextNode("the content of the link")) con$closeTag() # a con$closeTag() # "subsection" con$closeTag() # section d <- xmlOutputDOM() d$addPI("S", "plot(1:10)") d$addCData('x <- list(1, a="&");\nx[[2]]') d$addComment("A comment") print(d$value()) print(d$value(), indent = FALSE, tagSeparator = "") d = xmlOutputDOM("bob", xmlDeclaration = TRUE) print(d$value()) d = xmlOutputDOM("bob", xmlDeclaration = "encoding='UTF-8'") print(d$value()) d = xmlOutputBuffer("bob", header = "", dtd = "foo.dtd") d$addTag("bob") cat(d$value()) } \keyword{file} \keyword{IO} XML/man/replaceNodeWithChildren.Rd0000644000175100001440000000170113610555151016521 0ustar hornikusers\name{replaceNodeWithChildren} \alias{replaceNodeWithChildren} \title{Replace an XML node with it child nodes} \description{ This function can be used to flatten parts of an XML tree. This takes a node and removes itself from the tree, but places its kids in it place. } \usage{ replaceNodeWithChildren(node) } \arguments{ \item{node}{an \code{XMLInternalNode} object} } \value{ \code{NULL}. The purpose of this function is to modify the internal document. } \references{ libxml2 documentation. } \author{ Duncan Temple Lang } \examples{ doc = xmlParse('

    A

    B

    C

    D

    E

    F

    ') pages = getNodeSet(doc, "//page") invisible(lapply(pages, replaceNodeWithChildren)) doc } \keyword{IO} XML/man/dtdIsAttribute.Rd0000644000175100001440000000250614405636156014742 0ustar hornikusers\name{dtdIsAttribute} \alias{dtdIsAttribute} \title{Query if a name is a valid attribute of a DTD element.} \description{ Examines the definition of the DTD element definition identified by \code{element} to see if it supports an attribute named \code{name}. } \usage{ dtdIsAttribute(name, element, dtd) } %- maybe also `usage' for other objects documented here. \arguments{ \item{name}{The name of the attribute being queried} \item{element}{The name of the element whose definition is to be used to obtain the list of valid attributes.} \item{dtd}{The DTD containing the definition of the elements, specifically \code{element}.} } \value{ A logical value indicating if the list of attributes suppported by the specified element has an entry named \code{name}. This does indicate what type of value that attribute has, whether it is required, implied, fixed, etc. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{parseDTD}}, \code{\link{dtdElement}}, \code{\link{xmlAttrs}} } \examples{ dtdFile <- system.file("exampleData", "foo.dtd", package="XML") foo.dtd <- parseDTD(dtdFile) # true dtdIsAttribute("numRecords", "dataset", foo.dtd) # false dtdIsAttribute("date", "dataset", foo.dtd) } \keyword{file} XML/man/compareXMLDocs.Rd0000644000175100001440000000317713607633762014637 0ustar hornikusers\name{compareXMLDocs} \alias{compareXMLDocs} \title{Indicate differences between two XML documents} \description{ This function is an attempt to provide some assistance in determining if two XML documents are the same and if not, how they differ. Rather than comparing the tree structure, this function compares the frequency distributions of the names of the node. It omits position, attributes, simple content from the comparison. Those are left to the functions that have more contextual information to compare two documents. } \usage{ compareXMLDocs(a, b, ...) } \arguments{ \item{a,b}{two parsed XML documents that must be internal documents, i.e. created with \code{\link{xmlParse}} or created with \code{\link{newXMLNode}}.} \item{\dots}{additional parameters that are passed on to the \code{summary} method for an internal document.} } \value{ A list with elements \item{inA}{the names and counts of the XML elements that only appear in the first document} \item{inB}{the names and counts of the XML elements that only appear in the second document} \item{countDiffs}{a vector giving the difference in number of nodes with a particular name.} These give a description of what is missing from one document relative to the other. } %\references{} \author{ Duncan Temple Lang } \seealso{ \code{\link{getNodeSet}} } \examples{ tt = '
    text a phrase ' a = xmlParse(tt, asText = TRUE) b = xmlParse(tt, asText = TRUE) d = getNodeSet(b, "//d")[[1]] xmlName(d) = "bob" addSibling(xmlParent(d), newXMLNode("c")) compareXMLDocs(a, b) } \keyword{IO} XML/man/getRelativeURL.Rd0000644000175100001440000000443114316477364014651 0ustar hornikusers\name{getRelativeURL} \alias{getRelativeURL} \title{Compute name of URL relative to a base URL} \description{ This function is a convenience function for computing the fullly qualified URI of a document relative to a base URL. It handles the case where the document is already fully qualified and so ignores the base URL or, alternatively, is a relative document name and so prepends the base URL. It does not (yet) try to be clever by collapsing relative directories such as "..". } \usage{ getRelativeURL(u, baseURL, sep = "/", addBase = TRUE, simplify = TRUE, escapeQuery = FALSE) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{u}{the location of the target document whose fully qualified URI is to be determined.} \item{baseURL}{the base URL relative to which the value of \code{u} should be interpreted.} \item{sep}{the separator to use to separate elements of the path. For external URLs (e.g. accessed via HTTP, HTTPS, FTP), / should be used. For local files on Windows machines one might use \code{.Platform$file.sep}, but this is incorrect unless one knows that the resulting file is to be accessed using Windows file system notation, i.e. \code{C:\\\\my\\\\folder\\\\file}. } \item{addBase}{a logical controlling whether we prepend the base URL to the result.} \item{simplify}{a logical value that controls whether we attempt to simplify/normalize the path to remove \code{..} and \code{.}} \item{escapeQuery}{a logical value. Currently ignored.} } \details{ This uses the function \code{parseURI} to compute the components of the different URIs. } \value{ A character string giving the fully qualified URI for \code{u}. } \author{Duncan Temple Lang} \seealso{ \code{\link{parseURI}} which uses the libxml2 facilities for parsing URIs. \code{\link{xmlParse}}, \code{\link{xmlTreeParse}}, \code{\link{xmlInternalTreeParse}}. XInclude and XML Schema import/include elements for computing relative locations of included/imported files.. } \examples{ getRelativeURL("https://www.omegahat.net", "http://www.r-project.org") getRelativeURL("bar.html", "http://www.r-project.org/") getRelativeURL("../bar.html", "http://www.r-project.org/") } \keyword{IO} \keyword{programming} \concept{XML} XML/man/readSolrDoc.Rd0000644000175100001440000000216513607633744014214 0ustar hornikusers\name{readSolrDoc} \alias{readSolrDoc} \alias{readSolrDoc,XMLInternalDocument-method} \alias{readSolrDoc,XMLInternalNode-method} \alias{readSolrDoc,character-method} \alias{readSolrDoc,AsIs-method} \title{Read the data from a Solr document} \description{ Solr documents are used to represent general data in a reasonably simple format made up of lists, integers, logicals, longs, doubles, dates, etc. each with an optional name. These correspond very naturally to R objects. } \usage{ readSolrDoc(doc, ...) } \arguments{ \item{doc}{the object containing the data. This can be the name of a file, a parsed XML document or an XML node.} \item{\dots}{additional parameters for the methods.} } \value{ An R object representing the data in the Solr document, typically a named vector or named list. } \references{ Lucene text search system. } \author{ Duncan Temple Lang } \seealso{ \code{\link{readKeyValueDB}}, \code{\link{xmlToList}}, \code{\link{xmlToDataFrame}}, \code{\link{xmlParse}} } \examples{ f = system.file("exampleData", "solr.xml", package = "XML") readSolrDoc(f) } \keyword{IO} \concept{Solr} XML/man/xmlTreeParse.Rd0000644000175100001440000006432514531613761014426 0ustar hornikusers\name{xmlTreeParse} \alias{xmlTreeParse} \alias{htmlTreeParse} \alias{htmlParse} \alias{xmlInternalTreeParse} \alias{xmlNativeTreeParse} \alias{xmlParse} \alias{xmlSchemaParse} \title{XML Parser} \description{ Parses an XML or HTML file or string containing XML/HTML content, and generates an R structure representing the XML/HTML tree. Use \code{htmlTreeParse} when the content is known to be (potentially malformed) HTML. This function has numerous parameters/options and operates quite differently based on their values. It can create trees in R or using internal C-level nodes, both of which are useful in different contexts. It can perform conversion of the nodes into R objects using caller-specified handler functions and this can be used to map the XML document directly into R data structures, by-passing the conversion to an R-level tree which would then be processed recursively or with multiple descents to extract the information of interest. \code{xmlParse} and \code{htmlParse} are equivalent to the \code{xmlTreeParse} and \code{htmlTreeParse} respectively, except they both use a default value for the \code{useInternalNodes} parameter of \code{TRUE}, i.e. they working with and return internal nodes/C-level nodes. These can then be searched using XPath expressions via \code{\link{xpathApply}} and \code{\link{getNodeSet}}. \code{xmlSchemaParse} is a convenience function for parsing an XML schema. } \usage{ xmlTreeParse(file, ignoreBlanks=TRUE, handlers=NULL, replaceEntities=FALSE, asText=FALSE, trim=TRUE, validate=FALSE, getDTD=TRUE, isURL=FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = FALSE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = xmlErrorCumulator(), isHTML = FALSE, options = integer(), parentFirst = FALSE) xmlInternalTreeParse(file, ignoreBlanks=TRUE, handlers=NULL, replaceEntities=FALSE, asText=FALSE, trim=TRUE, validate=FALSE, getDTD=TRUE, isURL=FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = TRUE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = xmlErrorCumulator(), isHTML = FALSE, options = integer(), parentFirst = FALSE) xmlNativeTreeParse(file, ignoreBlanks=TRUE, handlers=NULL, replaceEntities=FALSE, asText=FALSE, trim=TRUE, validate=FALSE, getDTD=TRUE, isURL=FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = TRUE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = xmlErrorCumulator(), isHTML = FALSE, options = integer(), parentFirst = FALSE) htmlTreeParse(file, ignoreBlanks=TRUE, handlers=NULL, replaceEntities=FALSE, asText=FALSE, trim=TRUE, validate=FALSE, getDTD=TRUE, isURL=FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = FALSE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = htmlErrorHandler, isHTML = TRUE, options = integer(), parentFirst = FALSE) htmlParse(file, ignoreBlanks = TRUE, handlers = NULL, replaceEntities = FALSE, asText = FALSE, trim = TRUE, validate = FALSE, getDTD = TRUE, isURL = FALSE, asTree = FALSE, addAttributeNamespaces = FALSE, useInternalNodes = TRUE, isSchema = FALSE, fullNamespaceInfo = FALSE, encoding = character(), useDotNames = length(grep("^\\\\.", names(handlers))) > 0, xinclude = TRUE, addFinalizer = TRUE, error = htmlErrorHandler, isHTML = TRUE, options = integer(), parentFirst = FALSE) xmlSchemaParse(file, asText = FALSE, xinclude = TRUE, error = xmlErrorCumulator()) } \arguments{ \item{file}{ The name of the file containing the XML contents. This can contain ~ which is expanded to the user's home directory. It can also be a URL. See \code{isURL}. Additionally, the file can be compressed (gzip) and is read directly without the user having to de-compress (gunzip) it.} \item{ignoreBlanks}{ logical value indicating whether text elements made up entirely of white space should be included in the resulting \sQuote{tree}. } \item{handlers}{Optional collection of functions used to map the different XML nodes to R objects. Typically, this is a named list of functions, and a closure can be used to provide local data. This provides a way of filtering the tree as it is being created in R, adding or removing nodes, and generally processing them as they are constructed in the C code. In a recent addition to the package (version 0.99-8), if this is specified as a single function object, we call that function for each node (of any type) in the underlying DOM tree. It is invoked with the new node and its parent node. This applies to regular nodes and also comments, processing instructions, CDATA nodes, etc. So this function must be sufficiently general to handle them all. } \item{replaceEntities}{ logical value indicating whether to substitute entity references with their text directly. This should be left as False. The text still appears as the value of the node, but there is more information about its source, allowing the parse to be reversed with full reference information. } \item{asText}{logical value indicating that the first argument, \code{file}, should be treated as the XML text to parse, not the name of a file. This allows the contents of documents to be retrieved from different sources (e.g. HTTP servers, XML-RPC, etc.) and still use this parser.} \item{trim}{ whether to strip white space from the beginning and end of text strings. } \item{validate}{ logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. This is ignored when parsing an HTML document. } \item{getDTD}{ logical flag indicating whether the DTD (both internal and external) should be returned along with the document nodes. This changes the return type. This is ignored when parsing an HTML document. } \item{isURL}{ indicates whether the \code{file} argument refers to a URL (accessible via ftp or http) or a regular file on the system. If \code{asText} is TRUE, this should not be specified. The function attempts to determine whether the data source is a URL by using \code{\link{grep}} to look for http or ftp at the start of the string. The libxml parser handles the connection to servers, not the R facilities (e.g. \code{\link{scan}}). } \item{asTree}{this only applies when on passes a value for the \code{handlers} argument and is used then to determine whether the DOM tree should be returned or the \code{handlers} object. } \item{addAttributeNamespaces}{a logical value indicating whether to return the namespace in the names of the attributes within a node or to omit them. If this is \code{TRUE}, an attribute such as \code{xsi:type="xsd:string"} is reported with the name \code{xsi:type}. If it is \code{FALSE}, the name of the attribute is \code{type}.} \item{useInternalNodes}{a logical value indicating whether to call the converter functions with objects of class \code{XMLInternalNode} rather than \code{XMLNode}. This should make things faster as we do not convert the contents of the internal nodes to R explicit objects. Also, it allows one to access the parent and ancestor nodes. However, since the objects refer to volatile C-level objects, one cannot store these nodes for use in further computations within R. They \dQuote{disappear} after the processing the XML document is completed. If this argument is \code{TRUE} and no handlers are provided, the return value is a reference to the internal C-level document pointer. This can be used to do post-processing via XPath expressions using \code{\link{getNodeSet}}. This is ignored when parsing an HTML document. } \item{isSchema}{a logical value indicating whether the document is an XML schema (\code{TRUE}) and should be parsed as such using the built-in schema parser in libxml.} \item{fullNamespaceInfo}{a logical value indicating whether to provide the namespace URI and prefix on each node or just the prefix. The latter (\code{FALSE}) is currently the default as that was the original way the package behaved. However, using \code{TRUE} is more informative and we will make this the default in the future. This is ignored when parsing an HTML document. } \item{encoding}{ a character string (scalar) giving the encoding for the document. This is optional as the document should contain its own encoding information. However, if it doesn't, the caller can specify this for the parser. If the XML/HTML document does specify its own encoding that value is used regardless of any value specified by the caller. (That's just the way it goes!) So this is to be used as a safety net in case the document does not have an encoding and the caller happens to know theactual encoding. } \item{useDotNames}{a logical value indicating whether to use the newer format for identifying general element function handlers with the '.' prefix, e.g. .text, .comment, .startElement. If this is \code{FALSE}, then the older format text, comment, startElement, ... are used. This causes problems when there are indeed nodes named text or comment or startElement as a node-specific handler are confused with the corresponding general handler of the same name. Using \code{TRUE} means that your list of handlers should have names that use the '.' prefix for these general element handlers. This is the preferred way to write new code. } \item{xinclude}{a logical value indicating whether to process nodes of the form \code{} to insert content from other parts of (potentially different) documents. \code{TRUE} means resolve the external references; \code{FALSE} means leave the node as is. Of course, one can process these nodes oneself after document has been parse using handler functions or working on the DOM. Please note that the syntax for inclusion using XPointer is not the same as XPath and the results can be a little unexpected and confusing. See the libxml2 documentation for more details. } \item{addFinalizer}{a logical value indicating whether the default finalizer routine should be registered to free the internal xmlDoc when R no longer has a reference to this external pointer object. This is only relevant when \code{useInternalNodes} is \code{TRUE}. } \item{error}{a function that is invoked when the XML parser reports an error. When an error is encountered, this is called with 7 arguments. See \code{\link{xmlStructuredStop}} for information about these If parsing completes and no document is generated, this function is called again with only argument which is a character vector of length 0. This gives the function an opportunity to report all the errors and raise an exception rather than doing this when it sees th first one. This function can do what it likes with the information. It can raise an R error or let parser continue and potentially find further errors. The default value of this argument supplies a function that cumulates the errors If this is \code{NULL}, the default error handler function in the package \code{\link{xmlStructuredStop}} is invoked and this will raise an error in R at that time in R. } \item{isHTML}{a logical value that allows this function to be used for parsing HTML documents. This causes validation and processing of a DTD to be turned off. This is currently experimental so that we can implement \code{htmlParse} with this same function.} \item{options}{an integer value or vector of values that are combined (OR'ed) together to specify options for the XML parser. This is the same as the \code{options} parameter for \code{\link{xmlParseDoc}}. } \item{parentFirst}{a logical value for use when we have handler functions and are traversing the tree. This controls whether we process the node before processing its children, or process the children before their parent node.} } \details{ The \code{handlers} argument is used similarly to those specified in \link{xmlEventParse}. When an XML tag (element) is processed, we look for a function in this collection with the same name as the tag's name. If this is not found, we look for one named \code{startElement}. If this is not found, we use the default built in converter. The same works for comments, entity references, cdata, processing instructions, etc. The default entries should be named \code{comment}, \code{startElement}, \code{externalEntity}, \code{processingInstruction}, \code{text}, \code{cdata} and \code{namespace}. All but the last should take the XMLnode as their first argument. In the future, other information may be passed via \dots, for example, the depth in the tree, etc. Specifically, the second argument will be the parent node into which they are being added, but this is not currently implemented, so should have a default value (\code{NULL}). The \code{namespace} function is called with a single argument which is an object of class \code{XMLNameSpace}. This contains \describe{ \item{id}{the namespace identifier as used to qualify tag names;} \item{uri}{the value of the namespace identifier, i.e. the URI identifying the namespace.} \item{local}{a logical value indicating whether the definition is local to the document being parsed.} } One should note that the \code{namespace} handler is called before the node in which the namespace definition occurs and its children are processed. This is different than the other handlers which are called after the child nodes have been processed. Each of these functions can return arbitrary values that are then entered into the tree in place of the default node passed to the function as the first argument. This allows the caller to generate the nodes of the resulting document tree exactly as they wish. If the function returns \code{NULL}, the node is dropped from the resulting tree. This is a convenient way to discard nodes having processed their contents. } \value{ By default ( when \code{useInternalNodes} is \code{FALSE}, \code{getDTD} is \code{TRUE}, and no handler functions are provided), the return value is, an object of (S3) class \code{XMLDocument}. This has two fields named \code{doc} and \code{dtd} and are of class \code{DTDList} and \code{XMLDocumentContent} respectively. If \code{getDTD} is \code{FALSE}, only the \code{doc} object is returned. The \code{doc} object has three fields of its own: \code{file}, \code{version} and \code{children}. \item{\code{file}}{The (expanded) name of the file containing the XML.} \item{\code{version}}{A string identifying the version of XML used by the document.} \item{\code{children}}{ A list of the XML nodes at the top of the document. Each of these is of class \code{XMLNode}. These are made up of 4 fields. \describe{ \item{\code{name}}{The name of the element.} \item{\code{attributes}}{For regular elements, a named list of XML attributes converted from the } \item{\code{children}}{List of sub-nodes.} \item{\code{value}}{Used only for text entries.} } Some nodes specializations of \code{XMLNode}, such as \code{XMLComment}, \code{XMLProcessingInstruction}, \code{XMLEntityRef} are used. If the value of the argument getDTD is TRUE and the document refers to a DTD via a top-level DOCTYPE element, the DTD and its information will be available in the \code{dtd} field. The second element is a list containing the external and internal DTDs. Each of these contains 2 lists - one for element definitions and another for entities. See \code{\link{parseDTD}}. If a list of functions is given via \code{handlers}, this list is returned. Typically, these handler functions share state via a closure and the resulting updated data structures which contain the extracted and processed values from the XML document can be retrieved via a function in this handler list. If \code{asTree} is \code{TRUE}, then the converted tree is returned. What form this takes depends on what the handler functions have done to process the XML tree. If \code{useInternalNodes} is \code{TRUE} and no handlers are specified, an object of S3 class \code{XMLInternalDocument} is returned. This can be used in much the same ways as an \code{XMLDocument}, e.g. with \code{\link{xmlRoot}}, \code{\link{docName}} and so on to traverse the tree. It can also be used with XPath queries via \code{\link{getNodeSet}}, \code{\link{xpathApply}} and \code{doc["xpath-expression"]}. If internal nodes are used and the internal tree returned directly, all the nodes are returned as-is and no attempt to trim white space, remove \dQuote{empty} nodes (i.e. containing only white space), etc. is done. This is potentially quite expensive and so is not done generally, but should be done during the processing of the nodes. When using XPath queries, such nodes are easily identified and/or ignored and so do not cause any difficulties. They do become an issue when dealing with a node's chidren directly and so one can use simple filtering techniques such as \code{ xmlChildren(node)[!xmlSApply(node, inherits, "XMLInternalTextNode")]} and even check the \code{\link{xmlValue}} to determine if it contains only white space. \code{ xmlChildren(node)[!xmlSApply(node, function(x) inherit(x, "XMLInternalTextNode")] && trim(xmlValue(x)) == "")} } } \references{\url{http://xmlsoft.org}, \url{https://www.w3.org/XML//}} \author{Duncan Temple Lang } \note{Make sure that the necessary 3rd party libraries are available.} \seealso{ \link{xmlEventParse}, \code{\link{free}} for releasing the memory when an \code{XMLInternalDocument} object is returned. } \examples{ fileName <- system.file("exampleData", "test.xml", package="XML") # parse the document and return it in its standard format. xmlTreeParse(fileName) # parse the document, discarding comments. xmlTreeParse(fileName, handlers=list("comment"=function(x,...){NULL}), asTree = TRUE) # print the entities invisible(xmlTreeParse(fileName, handlers=list(entity=function(x) { cat("In entity",x$name, x$value,"\n") x} ), asTree = TRUE ) ) # Parse some XML text. # Read the text from the file xmlText <- paste(readLines(fileName), "\n", collapse="") print(xmlText) xmlTreeParse(xmlText, asText=TRUE) # with version 1.4.2 we can pass the contents of an XML # stream without pasting them. xmlTreeParse(readLines(fileName), asText=TRUE) # Read a MathML document and convert each node # so that the primary class is # MathML # so that we can use method dispatching when processing # it rather than conditional statements on the tag name. # See plotMathML() in examples/. fileName <- system.file("exampleData", "mathml.xml",package="XML") m <- xmlTreeParse(fileName, handlers=list( startElement = function(node){ cname <- paste(xmlName(node),"MathML", sep="",collapse="") class(node) <- c(cname, class(node)); node })) # In this example, we extract _just_ the names of the # variables in the mtcars.xml file. # The names are the contents of the # tags. We discard all other tags by returning NULL # from the startElement handler. # # We cumulate the names of variables in a character # vector named 'vars'. # We define this within a closure and define the # variable function within that closure so that it # will be invoked when the parser encounters a # tag. # This is called with 2 arguments: the XMLNode object (containing # its children) and the list of attributes. # We get the variable name via call to xmlValue(). # Note that we define the closure function in the call and then # create an instance of it by calling it directly as # (function() {...})() # Note that we can get the names by parsing # in the usual manner and the entire document and then executing # xmlSApply(xmlRoot(doc)[[1]], function(x) xmlValue(x[[1]])) # which is simpler but is more costly in terms of memory. fileName <- system.file("exampleData", "mtcars.xml", package="XML") doc <- xmlTreeParse(fileName, handlers = (function() { vars <- character(0) ; list(variable=function(x, attrs) { vars <<- c(vars, xmlValue(x[[1]])); NULL}, startElement=function(x,attr){ NULL }, names = function() { vars } ) })() ) # Here we just print the variable names to the console # with a special handler. doc <- xmlTreeParse(fileName, handlers = list( variable=function(x, attrs) { print(xmlValue(x[[1]])); TRUE }), asTree=TRUE) # This should raise an error. try(xmlTreeParse( system.file("exampleData", "TestInvalid.xml", package="XML"), validate=TRUE)) \dontrun{ # Parse an XML document directly from a URL. # Requires Internet access. xmlTreeParse("https://www.omegahat.net/Scripts/Data/mtcars.xml", asText=TRUE) } counter = function() { counts = integer(0) list(startElement = function(node) { name = xmlName(node) if(name \%in\% names(counts)) counts[name] <<- counts[name] + 1 else counts[name] <<- 1 }, counts = function() counts) } h = counter() xmlParse(system.file("exampleData", "mtcars.xml", package="XML"), handlers = h) h$counts() f = system.file("examples", "index.html", package = "XML") htmlTreeParse(readLines(f), asText = TRUE) htmlTreeParse(readLines(f)) # Same as htmlTreeParse(paste(readLines(f), collapse = "\n"), asText = TRUE) getLinks = function() { links = character() list(a = function(node, ...) { links <<- c(links, xmlGetAttr(node, "href")) node }, links = function()links) } h1 = getLinks() htmlTreeParse(system.file("examples", "index.html", package = "XML"), handlers = h1) h1$links() h2 = getLinks() htmlTreeParse(system.file("examples", "index.html", package = "XML"), handlers = h2, useInternalNodes = TRUE) all(h1$links() == h2$links()) # Using flat trees tt = xmlHashTree() f = system.file("exampleData", "mtcars.xml", package="XML") xmlTreeParse(f, handlers = list(.startElement = tt[[".addNode"]])) xmlRoot(tt) doc = xmlTreeParse(f, useInternalNodes = TRUE) sapply(getNodeSet(doc, "//variable"), xmlValue) #free(doc) # character set encoding for HTML f = system.file("exampleData", "9003.html", package = "XML") # we specify the encoding d = htmlTreeParse(f, encoding = "UTF-8") # get a different result if we do not specify any encoding d.no = htmlTreeParse(f) # document with its encoding in the HEAD of the document. d.self = htmlTreeParse(system.file("exampleData", "9003-en.html",package = "XML")) # XXX want to do a test here to see the similarities between d and # d.self and differences between d.no # include f = system.file("exampleData", "nodes1.xml", package = "XML") xmlRoot(xmlTreeParse(f, xinclude = FALSE)) xmlRoot(xmlTreeParse(f, xinclude = TRUE)) f = system.file("exampleData", "nodes2.xml", package = "XML") xmlRoot(xmlTreeParse(f, xinclude = TRUE)) # Errors try(xmlTreeParse(" & < ")) # catch the error by type. tryCatch(xmlTreeParse(" & < "), "XMLParserErrorList" = function(e) { cat("Errors in XML document\n", e$message, "\n") }) # terminate on first error try(xmlTreeParse(" & < ", error = NULL)) # see xmlErrorCumulator in the XML package f = system.file("exampleData", "book.xml", package = "XML") doc.trim = xmlInternalTreeParse(f, trim = TRUE) doc = xmlInternalTreeParse(f, trim = FALSE) xmlSApply(xmlRoot(doc.trim), class) # note the additional XMLInternalTextNode objects xmlSApply(xmlRoot(doc), class) top = xmlRoot(doc) textNodes = xmlSApply(top, inherits, "XMLInternalTextNode") sapply(xmlChildren(top)[textNodes], xmlValue) # Storing nodes f = system.file("exampleData", "book.xml", package = "XML") titles = list() xmlTreeParse(f, handlers = list(title = function(x) titles[[length(titles) + 1]] <<- x)) sapply(titles, xmlValue) rm(titles) } \keyword{file} \keyword{IO} XML/man/xmlSize.Rd0000644000175100001440000000201414405636156013434 0ustar hornikusers\name{xmlSize} \alias{xmlSize} \alias{xmlSize.default} \alias{xmlSize.XMLDocument} \alias{xmlSize.XMLNode} \title{The number of sub-elements within an XML node.} \description{ XML elements can contain other, nested sub-elements. This generic function determines the number of such elements within a specified node. It applies to an object of class XMLNode or XMLDocument. } \usage{ xmlSize(obj) } \arguments{ \item{obj}{ An an object of class XMLNode or XMLDocument.} } \value{ an integer which is the \code{\link{length}} of the value from \code{\link{xmlChildren}}. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlChildren}}, \code{\link{xmlAttrs}}, \code{\link{xmlName}}, \code{\link{xmlTreeParse}} } \examples{ fileName <- system.file("exampleData", "mtcars.xml", package="XML") doc <- xmlTreeParse(fileName) xmlSize(doc) xmlSize(doc$doc$children[["dataset"]][["variables"]]) } \keyword{file} XML/man/Doctype-class.Rd0000644000175100001440000000267714405636156014532 0ustar hornikusers\name{Doctype-class} \docType{class} \alias{Doctype-class} \title{Class to describe a reference to an XML DTD} \description{This class is intended to identify a DTD by SYSTEM file and/or PUBLIC catalog identifier. This is used in the DOCTYPE element of an XML document.} \section{Objects from the Class}{ Objects can be created by calls to the constructor function \code{\link{Doctype}}. } \section{Slots}{ \describe{ \item{\code{name}:}{Object of class \code{"character"}. This is the name of the top-level element in the XML document.} \item{\code{system}:}{Object of class \code{"character"}. This is the name of the file on the system where the DTD document can be found. Can this be a URI?} \item{\code{public}:}{Object of class \code{"character"}. This gives the PUBLIC identifier for the DTD that can be searched for in a catalog, for example to map the DTD reference to a local system element.} } } \section{Methods}{ There is a constructor function and also methods for \code{\link{coerce}} to convert an object of this class to a character. } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}} \author{Duncan Temple Lang} \seealso{ \code{\link{Doctype}} \code{\link{saveXML}} } \examples{ d = Doctype(name = "section", public = c("-//OASIS//DTD DocBook XML V4.2//EN", "http://oasis-open.org/docbook/xml/4.2/docbookx.dtd")) } \keyword{classes} XML/man/xmlHashTree.Rd0000644000175100001440000001167514405636156014242 0ustar hornikusers\name{xmlHashTree} \alias{xmlHashTree} \title{Constructors for trees stored as flat list of nodes with information about parents and children.} \description{ These (and related internal) functions allow us to represent trees as a simple, non-hierarchical collection of nodes along with corresponding tables that identify the parent and child relationships. This is different from representing a tree as a list of lists of lists ... in which each node has a list of its own children. In a functional language like R, it is not possible then for the children to be able to identify their parents. We use an environment to represent these flat trees. Since these are mutable without requiring the change to be reassigned, we can modify a part of the tree locally without having to reassign the top-level object. We can use either a list (with names) to store the nodes or a hash table/associative array that uses names. There is a non-trivial performance difference. } \usage{ xmlHashTree(nodes = list(), parents = character(), children = list(), env = new.env(TRUE, parent = emptyenv())) } \arguments{ \item{nodes}{ a collection of existing nodes that are to be added to the tree. These are used to initialize the tree. If this is specified, you must also specify \code{children} and \code{parents}. } \item{parents}{ the parent relationships for the nodes given by \code{nodes}.} \item{children}{the children relationships for the nodes given by \code{nodes}.} \item{env}{an environment in which the information for the tree will be stored. This is essentially the tree object as it allows us to modify parts of the tree without having to reassign the top-level object. Unlike most R data types, environments are mutable. } } \value{ An \code{xmlHashTree} object has an accessor method via \code{$} for accessing individual nodes within the tree. One can use the node name/identifier in an expression such as \code{tt$myNode} to obtain the element. The name of a node is either its XML node name or if that is already present in the tree, a machine generated name. One can find the names of all the nodes using the \code{objects} function since these trees are regular environments in R. Using the \code{all = TRUE} argument, one can also find the \dQuote{hidden} elements that make define the tree's structure. These are \code{.children} and \code{.parents}. The former is an (hashed) environment. Each element is identified by the node in the tree by the node's identifier (corresponding to the name of the node in the tree's environment). The value of that element is simply a character vector giving the identifiers of all of the children of that node. The \code{.parents} element is also an environemnt. Each element in this gives the pair of node and parent identifiers with the parent identifier being the value of the variable in the environment. In other words, we look up the parent of a node named 'kid' by retrieving the value of the variable 'kid' in the \code{.parents} environment of this hash tree. The function \code{.addNode} is used to insert a new node into the tree. The structure of this tree allows one to easily travers all nodes, navigate up the tree from a node via its parent. Certain tasks are more complex as the hierarchy is not implicit within a node. } \references{\url{https://www.w3.org/XML/}} \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlTree}} \code{\link{xmlOutputBuffer}} \code{\link{xmlOutputDOM}} } \examples{ f = system.file("exampleData", "dataframe.xml", package = "XML") tr = xmlHashTree() xmlTreeParse(f, handlers = list(.startElement = tr[[".addNode"]])) tr # print the tree on the screen # Get the two child nodes of the dataframe node. xmlChildren(tr$dataframe) # Find the names of all the nodes. objects(tr) # Which nodes have children objects(tr$.children) # Which nodes are leaves, i.e. do not have children setdiff(objects(tr), objects(tr$.children)) # find the class of each of these leaf nodes. sapply(setdiff(objects(tr), objects(tr$.children)), function(id) class(tr[[id]])) # distribution of number of children sapply(tr$.children, length) # Get the first A node tr$A # Get is parent node. xmlParent(tr$A) f = system.file("exampleData", "allNodeTypes.xml", package = "XML") # Convert the document r = xmlInternalTreeParse(f, xinclude = TRUE) ht = as(r, "XMLHashTree") ht # work on the root node, or any node actually as(xmlRoot(r), "XMLHashTree") # Example of making copies of an XMLHashTreeNode object to create a separate tree. f = system.file("exampleData", "simple.xml", package = "XML") tt = as(xmlParse(f), "XMLHashTree") xmlRoot(tt)[[1]] xmlRoot(tt)[[1, copy = TRUE]] table(unlist(eapply(tt, xmlName))) # if any of the nodes had any attributes # table(unlist(eapply(tt, xmlAttrs))) } \keyword{IO} \concept{XML} XML/man/docName.Rd0000644000175100001440000000312113607633730013345 0ustar hornikusers\name{docName} \alias{docName} \alias{docName,XMLDocument-method} \alias{docName,XMLDocumentContent-method} \alias{docName,XMLHashTree-method} \alias{docName,XMLInternalDocument-method} \alias{docName,XMLInternalNode-method} \alias{docName,XMLHashTreeNode-method} \alias{docName,NULL-method} \alias{docName,XMLNode-method} \alias{docName<-} \alias{docName<-,XMLInternalDocument-method} \alias{docName<-,XMLHashTree-method} \title{Accessors for name of XML document} \description{ These functions and methods allow us to query and set the \dQuote{name} of an XML document. This is intended to be its URL or file name or a description of its origin if raw XML content provided as a string. } \usage{ docName(doc, ...) } \arguments{ \item{doc}{the XML document object, of class \code{XMLInternalDocument} or \code{XMLDocument}. } \item{\dots}{additional methods for methods} } \value{ A character string giving the name. If the document was created from text, this is \code{NA} (of class character). The assignment function returns the updated object, but the R assignment operation will return the value on the right of the assignment! } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlInternalTreeParse}} \code{\link{newXMLDoc}} } \examples{ f = system.file("exampleData", "catalog.xml", package = "XML") doc = xmlInternalTreeParse(f) docName(doc) doc = xmlInternalTreeParse("", asText = TRUE) # an NA docName(doc) docName(doc) = "Simple XML example" docName(doc) } \keyword{IO} \keyword{programming} \concept{XML} XML/man/xmlNode.Rd0000644000175100001440000001054014405636156013412 0ustar hornikusers\name{xmlNode} \alias{xmlNode} \alias{xmlTextNode} \alias{xmlPINode} \alias{xmlCDataNode} \alias{xmlCommentNode} \title{Create an XML node} \description{ These functions allow one to create XML nodes as are created in C code when reading XML documents. Trees of XML nodes can be constructed and integrated with other trees generated manually or with via the parser. } \usage{ xmlNode(name, ..., attrs=NULL, namespace="", namespaceDefinitions = NULL, .children = list(...)) xmlTextNode(value, namespace="", entities = XMLEntities, cdata = FALSE) xmlPINode(sys, value, namespace="") xmlCDataNode(...) xmlCommentNode(text) } \arguments{ \item{name}{The tag or element name of the XML node. This is what appears in the elements as \code{ .. }} \item{\dots}{The children nodes of this XML node. These can be objects of class \code{XMLNode} or arbitrary values that will be converted to a string to form an \code{XMLTextNode} object.} \item{.children}{an alternative mechanism to specifying the children which is useful for programmatic use when one has the children in an existing list. The \dots mechanism is for use when the children are specified directly and individually. } \item{attrs}{A named character vector giving the name, value pairs of attributes for this XML node.} \item{value}{This is the text that is to be used when forming an \code{XMLTextNode}.} \item{cdata}{a logical value which controls whether the text being used for the child node is to be first enclosed within a CDATA node to escape special characters such as \code{>} and \code{&}. } \item{namespace}{The XML namespace identifier for this node.} \item{namespaceDefinitions}{a collection of name space definitions, containing the prefixes and the corresponding URIs. This is most conveniently specified as a character vector whose names attribute is the vector of prefixes and whose values are the URIs. Alternatively, one can provide a list of name space definition objects such as those returned} \item{sys}{the name of the system for which the processing instruction is targeted. This is the value that appears in the \code{}} \item{text}{character string giving the contents of the comment.} \item{entities}{a character vector giving the mapping from special characters to their entity equivalent. This provides the character-expanded entity pairings of 'character = entity' , e.g. '<' = "lt" which are used to make the content valid XML so that it can be used within a text node. The text searched sequentially for instances of each character in the names and each instance is replaced with the corresponding '&entity;' } } \value{ An object of class \code{XMLNode}. In the case of \code{xmlTextNode}, this also inherits from \code{XMLTextNode}. The fields or slots that objects of these classes have include \code{name}, \code{attributes}, \code{children} and \code{namespace}. However, one should the accessor functions \code{\link{xmlName}}, \code{\link{xmlAttrs}}, \code{\link{xmlChildren}} and \code{\link{xmlNamespace}} } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{addChildren}} \code{\link{xmlTreeParse}} \code{\link{asXMLNode}} \code{\link{newXMLNode}} \code{\link{newXMLPINode}} \code{\link{newXMLCDataNode}} \code{\link{newXMLCommentNode}} } \examples{ # node named arg with two children: name and defaultValue # Both of these have a text node as their child. n <- xmlNode("arg", attrs = c(default="TRUE"), xmlNode("name", "foo"), xmlNode("defaultValue","1:10")) # internal C-level node. a = newXMLNode("arg", attrs = c(default = "TRUE"), newXMLNode("name", "foo"), newXMLNode("defaultValue", "1:10")) xmlAttrs(a) = c(a = 1, b = "a string") xmlAttrs(a) = c(a = 1, b = "a string", append = FALSE) newXMLNamespace(a, c("r" = "http://www.r-project.org")) xmlAttrs(a) = c("r:class" = "character") xmlAttrs(a[[1]]) = c("r:class" = "character") # Using a character vector as a namespace definitions x = xmlNode("bob", namespaceDefinitions = c(r = "http://www.r-project.org", omg = "https://www.omegahat.net")) } \keyword{file} XML/man/xmlEventHandler.Rd0000644000175100001440000000257714405636156015117 0ustar hornikusers\name{xmlEventHandler} \alias{xmlEventHandler} \title{Default handlers for the SAX-style event XML parser} \description{ This is a function that returns a closure instance containing the default handlers for use with \code{\link{xmlEventParse}} for parsing XML documents via the SAX-style parsing. } \usage{ xmlEventHandler() } \details{ These handlers simply build up the DOM tree and thus perform the same job as \code{xmlTreeParse}. It is here more as an example, reference and a base that users can extend. } \value{ The return value is a list of functions which are used as callbacks by the internal XML parser when it encounters certain XML elements/structures. These include items such as the start of an element, end of an element, processing instruction, text node, comment, entity references and definitions, etc. \item{startElement}{} \item{endElement}{} \item{processingInstruction}{} \item{text}{} \item{comment}{} \item{externalEntity}{} \item{entityDeclaration}{} \item{cdata}{} \item{dom}{} } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlEventParse}} \code{\link{xmlTreeParse}} } \examples{ xmlEventParse(system.file("exampleData", "mtcars.xml", package="XML"), handlers=xmlEventHandler()) } \keyword{file} \keyword{IO} XML/man/xmlName.Rd0000644000175100001440000000266314405636156013414 0ustar hornikusers\name{xmlName} \alias{xmlName} \alias{xmlName<-} \alias{xmlName.XMLComment} \alias{xmlName.XMLNode} \alias{xmlName.XMLInternalNode} \title{ Extraces the tag name of an XMLNode object.} \description{ Each XMLNode object has an element or tag name introduced in the \code{} entry in an XML document. This function returns that name. We can also set that name using \code{xmlName(node) <- "name"} and the value can have an XML name space prefix, e.g. \code{"r:name"}. } \usage{ xmlName(node, full = FALSE) } \arguments{ \item{node}{The XMLNode object whose tag name is being requested.} \item{full}{a logical value indicating whether to prepend the namespace prefix, if there is one, or return just the name of the XML element/node. \code{TRUE} means prepend the prefix.} } \value{ A character vector of length 1 which is the \code{node$name} entry. } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlChildren}}, \code{\link{xmlAttrs}}, \code{\link{xmlTreeParse}} } \examples{ fileName <- system.file("exampleData", "test.xml", package="XML") doc <- xmlTreeParse(fileName) xmlName(xmlRoot(doc)[[1]]) tt = xmlRoot(doc)[[1]] xmlName(tt) xmlName(tt) <- "bob" # We can set the node on an internal object also. n = newXMLNode("x") xmlName(n) xmlName(n) <- "y" xmlName(n) <- "r:y" } \keyword{file} XML/man/xmlElementSummary.Rd0000644000175100001440000000277013607633744015505 0ustar hornikusers\name{xmlElementSummary} \alias{xmlElementSummary} \title{Frequency table of names of elements and attributes in XML content} \description{ This function is used to get an understanding of the use of element and attribute names in an XML document. It uses a collection of handler functions to gather the information via a SAX-style parser. The distribution of attribute names is done within each "type" of element (i.e. element name) } \usage{ xmlElementSummary(url, handlers = xmlElementSummaryHandlers(url)) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{url}{the source of the XML content, e.g. a file, a URL, a compressed file, or a character string} \item{handlers}{the list of handler functions used to collect the information. These are passed to the function \code{\link{xmlEventParse}} as the value for the \code{handlers} parameter. } } \value{ A list with two elements \item{nodeCounts}{a named vector of counts where the names are the (XML namespace qualified) element names in the XML content} \item{attributes}{a list with as many elements as there are elements in the \code{nodeCounts} element of the result. Each element of this sub-list gives the frequency counts for the different attributes seen within the XML elements with that name.} } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlEventParse}} } \examples{ xmlElementSummary(system.file("exampleData", "eurofxref-hist.xml.gz", package = "XML")) } \keyword{IO} \concept{XML} XML/man/isXMLString.Rd0000644000175100001440000000416013607633744014173 0ustar hornikusers\name{isXMLString} \Rdversion{1.1} \alias{isXMLString} \alias{xml} \alias{xmlParseString} \alias{XMLString-class} \title{Facilities for working with XML strings} \description{ These functions and classes are used to represent and parse a string whose content is known to be XML. \code{xml} allows us to mark a character vector as containing XML, i.e. of class \code{XMLString}. \code{xmlParseString} is a convenience routine for converting an XML string into an XML node/tree. \code{isXMLString} is examines a strings content and heuristically determines whether it is XML. } \usage{ isXMLString(str) xmlParseString(content, doc = NULL, namespaces = RXMLNamespaces, clean = TRUE, addFinalizer = NA) xml(x) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{str,x,content}{the string containing the XML material.} \item{doc}{if specified, an \code{XMLInternalDocument} object which is used to "house" the new nodes. Specifically, when the nodes are created, they are made as part of this document. This may not be as relevant now with the garbage collection being done at a node and document level. But it still potentially of some value.} \item{namespaces}{a character vector giving the URIs for the XML namespaces which are to be removed if \code{clean} is \code{TRUE}.} \item{clean}{a logical value that controls whether namespaces are removed after the document is parsed..} \item{addFinalizer}{a logical value or identifier for a C routine that controls whether we register finalizers on the intenal node.} } %\details{} \value{ \code{isXMLString} returns a logical value. \code{xmlParseString} returns an object of class \code{XMLInternalElementNode}. \code{xml} returns an object of class \code{XMLString} identifying the text as \code{XML}. } %\references{} \author{Dncan Temple Lang} \seealso{ \code{\link{xmlParse}} \code{\link{xmlTreeParse}} } \examples{ isXMLString("a regular string < 20 characters long") isXMLString("c") xmlParseString("c") # We can lie! isXMLString(xml("foo")) } \keyword{IO} \concept{XML} XML/man/free.Rd0000644000175100001440000000305413607633762012732 0ustar hornikusers\name{free} \alias{free} \alias{free,XMLInternalDocument-method} \title{Release the specified object and clean up its memory usage} \description{ This generic function is available for explicitly releasing the memory associated with the given object. It is intended for use on external pointer objects which do not have an automatic finalizer function/routine that cleans up the memory that is used by the native object. This is the case, for example, for an XMLInternalDocument. We cannot free it with a finalizer in all cases as we may have a reference to a node in the associated document tree. So the user must explicitly release the XMLInternalDocument object to free the memory it occupies. } \usage{ free(obj) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{obj}{ the object whose memory is to be released, typically an external pointer object or object that contains a slot that is an external pointer. } } \details{ The methods will generally call a C routine to free the native memory. } \value{ An updated version of the object with the external address set to NIL. This is up to the individual methods. } \author{ Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} with \code{useInternalNodes = TRUE} } \examples{ f = system.file("exampleData", "boxplot.svg", package = "XML") doc = xmlParse(f) nodes = getNodeSet(doc, "//path") rm(nodes) # free(doc) } % Add one or more standard keywords, see file 'KEYWORDS' in the % R documentation directory. \keyword{IO} \concept{external memory} XML/man/XMLCodeFile-class.Rd0000644000175100001440000000570513607633762015154 0ustar hornikusers\name{XMLCodeFile-class} %\Rdversion{1.1} \docType{class} \alias{XMLCodeFile-class} \alias{XMLCodeDoc-class} \alias{xmlCodeFile} \alias{[[,XMLCodeFile-method} %\alias{[[,XMLCodeFile,ANY,ANY-method} \alias{[[,XMLCodeFile,ANY-method} \alias{coerce,XMLCodeFile,XMLCodeDoc-method} \alias{coerce,character,XMLCodeDoc-method} \alias{coerce,character,XMLCodeFile-method} \alias{source,XMLCodeFile-method} \title{Simple classes for identifying an XML document containing R code} \description{ These two classes allow the user to identify an XML document or file as containing R code (amongst other content). Objects of either of these classes can then be passed to \code{\link{source}} to read the code into R and also used in \code{link{xmlSource}} to read just parts of it. \code{XMLCodeFile} represents the file by its name; \code{XMLCodeDoc} parses the contents of the file when the R object is created. Therefore, an \code{XMLCodeDoc} is a snapshot of the contents at a moment in time while an \code{XMLCodeFile} object re-reads the file each time and so reflects any "asynchronous" changes. } \section{Objects from the Class}{ One can create these objects using coercion methods, e.g \code{as("file/name", "XMLCodeFile")} or \code{as("file/name", "XMLCodeDoc")}. One can also use \code{xmlCodeFile}. } \section{Slots}{ \describe{ \item{\code{.Data}:}{Object of class \code{"character"}} } } \section{Extends}{ Class \code{"\linkS4class{character}"}, from data part. Class \code{"\linkS4class{vector}"}, by class "character", distance 2. %Class \code{"\linkS4class{data.frameRowLabels}"}, by class "character", distance 2. %Class \code{"\linkS4class{EnumerationValue}"}, by class "character", distance 2. %Class \code{"\linkS4class{NodeIndex}"}, by class "character", distance 2. %Class \code{"\linkS4class{RAnonymousFunctionOrCode}"}, by class "character", distance 2. } \section{Methods}{ \describe{ \item{[[}{\code{signature(x = "XMLCodeFile", i = "ANY", j = "ANY")}: this method allows one to retrieve/access an individual R code element in the XML document. This is typically done by specifying the value of the XML element's "id" attribute. } \item{coerce}{\code{signature(from = "XMLCodeFile", to = "XMLCodeDoc")}: parse the XML document from the "file" and treat the result as a \code{XMLCodeDoc} object. } \item{source}{\code{signature(file = "XMLCodeFile")}: read and evaluate all the R code in the XML document. For more control, use \code{\link{xmlSource}}.} } } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlSource}} } \examples{ src = system.file("exampleData", "Rsource.xml", package = "XML") # mark the string as an XML file containing R code k = xmlCodeFile(src) # read and parse the code, but don't evaluate it. code = xmlSource(k, eval = FALSE) # read and evaluate the code in a special environment. e = new.env() ans = xmlSource(k, envir = e) ls(e) } \keyword{classes} XML/man/getHTMLLinks.Rd0000644000175100001440000000442414316477364014262 0ustar hornikusers\name{getHTMLLinks} \alias{getHTMLLinks} \alias{getHTMLExternalFiles} \title{Get links or names of external files in HTML document} \description{ These functions allow us to retrieve either the links within an HTML document, or the collection of names of external files referenced in an HTML document. The external files include images, JavaScript and CSS documents. } \usage{ getHTMLLinks(doc, externalOnly = TRUE, xpQuery = "//a/@href", baseURL = docName(doc), relative = FALSE) getHTMLExternalFiles(doc, xpQuery = c("//img/@src", "//link/@href", "//script/@href", "//embed/@src"), baseURL = docName(doc), relative = FALSE, asNodes = FALSE, recursive = FALSE) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{doc}{the HTML document as a URL, local file name, parsed document or an XML/HTML node} \item{externalOnly}{a logical value that indicates whether we should only return links to external documents and not references to internal anchors/nodes within this document, i.e. those that of the form \code{#foo}.} \item{xpQuery}{a vector of XPath elements which match the elements of interest} \item{baseURL}{the URL of the container document. This is used to resolve relative references/links. } \item{relative}{a logical value indicating whether to leave the references as relative to the base URL or to expand them to their full paths. } \item{asNodes}{a logical value that indicates whether we want the actual HTML/XML nodes in the document that reference external documents or just the names of the external documents.} \item{recursive}{a logical value that controls whether we recursively process the external documents we find in the top-level document examining them for their external files.} } \value{ \code{getHTMLLinks} returns a character vector of the links. \code{getHTMLExternalFiles} returns a character vector. } \author{ Duncan Temple Lang } \seealso{ \code{\link{getXIncludes}} } \examples{\donttest{ # site is flaky try(getHTMLLinks("https://www.omegahat.net")) try(getHTMLLinks("https://www.omegahat.net/RSXML")) try(unique(getHTMLExternalFiles("https://www.omegahat.net"))) }} \keyword{IO} \keyword{programming} XML/man/xmlSource.Rd0000644000175100001440000002544513700532410013760 0ustar hornikusers\name{xmlSource} \alias{xmlSource} \alias{xmlSource,character-method} \alias{xmlSource,XMLNodeSet-method} \alias{xmlSource,XMLInternalDocument-method} \alias{xmlSourceFunctions} \alias{xmlSourceFunctions,character-method} \alias{xmlSourceFunctions,XMLInternalDocument-method} \alias{xmlSourceSection} \alias{xmlSourceSection,character-method} \alias{xmlSourceSection,XMLInternalDocument-method} \alias{xmlSourceThread} \alias{xmlSourceThread,XMLInternalDocument-method} \alias{xmlSourceThread,character-method} \alias{xmlSourceThread,list-method} \title{Source the R code, examples, etc. from an XML document} \description{ This is the equivalent of a smart \code{\link{source}} for extracting the R code elements from an XML document and evaluating them. This allows for a \dQuote{simple} way to collect R functions definitions or a sequence of (annotated) R code segments in an XML document along with other material such as notes, documentation, data, FAQ entries, etc., and still be able to access the R code directly from within an R session. The approach enables one to use the XML document as a container for a heterogeneous collection of related material, some of which is R code. In the literate programming parlance, this function essentially dynamically "tangles" the document within R, but can work on small subsets of it that are easily specified in the \code{xmlSource} function call. This is a convenient way to annotate code in a rich way and work with source files in a new and potentially more effective manner. \code{xmlSourceFunctions} provides a convenient way to read only the function definitions, i.e. the \code{} nodes. We can restrict to a subset by specifying the node ids of interest. \code{xmlSourceSection} allows us to evaluate the code in one or more specific sections. This style of authoring code supports mixed language support in which we put, for example, C and R code together in the same document. Indeed, one can use the document to store arbitrary content and still retrieve the R code. The more structure there is, the easier it is to create tools to extract that information using XPath expressions. We can identify individual \code{r:code} nodes in the document to process, i.e. evaluate. We do this using their \code{id} attribute and specifying which to process via the \code{ids} argument. Alternatively, if a document has a node \code{r:codeIds} as a child of the top-level node (or within an invisible node), we read its contents as a sequence of line separated \code{id} values as if they had been specified via the argument \code{ids} to this function. We can also use XSL to extract the code. See \code{getCode.xsl} in the Omegahat XSL collection. This particular version (as opposed to other implementations) uses XPath to conveniently find the nodes of interest. } \usage{ xmlSource(url, ..., envir = globalenv(), xpath = character(), ids = character(), omit = character(), ask = FALSE, example = NA, fatal = TRUE, verbose = TRUE, echo = verbose, print = echo, xnodes = DefaultXMLSourceXPath, namespaces = DefaultXPathNamespaces, section = character(), eval = TRUE, init = TRUE, setNodeNames = FALSE, parse = TRUE, force = FALSE) xmlSourceFunctions(doc, ids = character(), parse = TRUE, ...) xmlSourceSection(doc, ids = character(), xnodes = c(".//r:function", ".//r:init[not(@eval='false')]", ".//r:code[not(@eval='false')]", ".//r:plot[not(@eval='false')]"), namespaces = DefaultXPathNamespaces, ...) } \arguments{ \item{url}{the name of the file, URL containing the XML document, or an XML string. This is passed to \code{\link[XML]{xmlTreeParse}} which is called with \code{useInternalNodes = TRUE}. } \item{\dots}{additional arguments passed to \code{\link[XML]{xmlTreeParse}}} \item{envir}{the environment in which the code elements of the XML document are to be evaluated. By default, they are evaluated in the global environment so that assignments take place there. } \item{xpath}{a string giving an XPath expression which is used after parsing the document to filter the document to a particular subset of nodes. This allows one to restrict the evaluation to a subset of the original document. One can do this directly by parsing the XML document, applying the XPath query and then passing the resulting node set to this \code{xmlSource} function's appropriate method. This argument merely allows for a more convenient form of those steps, collapsing it into one action. } \item{ids}{a character vector. XML nodes containing R code (e.g. \code{r:code}, \code{r:init}, \code{r:function}, \code{r:plot}) can have an id attribute. This vector allows the caller to specify the subset of these nodes to process, i.e. whose code will be evaluated. The order is currently not important. It may be used in the future to specify the order in which the nodes are evaluated. If this is not specified and the document has a node \code{r:codeIds} as an immediate child of the top-most node, the contents of this node or contained within an \code{invisible} node (so that it doesn't have to be filtered when rendering the document), the names of the r:code id values to process are taken as the individual lines from the body of this node. } \item{omit}{a character vector. The values of the id attributes of the nodes that we want to skip or omit from the evaluation. This allows us to specify the set that we don't want evaluated, in contrast to the \code{ids} argument. The order is not important. } \item{ask}{logical} \item{example}{a character or numeric vector specifying the values of the id attributes of any \code{r:example} nodes in the document. A single document may contain numerous, separate examples and these can be marked uniquely using an \code{id} attribute, e.g. \code{} \seealso{ \code{\link[XML]{xmlTreeParse}} } \examples{ xmlSource(system.file("exampleData", "Rsource.xml", package="XML")) # This illustrates using r:frag nodes. # The r:frag nodes are not processed directly, but only # if referenced in the contents/body of a r:code node f = system.file("exampleData", "Rref.xml", package="XML") xmlSource(f) } \keyword{IO} \keyword{programming} \concept{Annotated code} \concept{Literate Programming} \concept{Mixed language} XML/man/coerce.Rd0000644000175100001440000000142113607633730013240 0ustar hornikusers\name{coerceNodes} \alias{coerce,XMLHashTreeNode,XMLHashTree-method} \alias{coerce,XMLInternalDocument,XMLHashTree-method} \alias{coerce,XMLInternalNode,XMLHashTree-method} \alias{coerce,XMLNode,XMLInternalNode-method} \alias{coerce,XMLAbstractDocument,XMLAbstractNode-method} \title{Transform between XML representations} \description{ This collection of coercion methods (i.e. \code{as(obj, "type")}) allows users of the \code{XML} package to switch between different representations of XML nodes and to map from an XML document to the root node and from a node to the document. This helps to manage the nodes } %\usage{} \value{ An object of the target type. } \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlParse}} } \keyword{IO} \keyword{programming} \concept{XML} XML/man/xmlNamespace.Rd0000644000175100001440000000505314405636156014424 0ustar hornikusers\name{xmlNamespace} \alias{xmlNamespace} \alias{xmlNamespace.XMLNode} \alias{xmlNamespace.XMLInternalNode} \alias{xmlNamespace.character} \alias{XMLNamespace-class} \alias{xmlNamespace<-} \alias{xmlNamespace<-,XMLInternalNode-method} \title{Retrieve the namespace value of an XML node.} \description{ Each XML node has a namespace identifier which is a string indicating in which DTD (Document Type Definition) the definition of that element can be found. This avoids the problem of having different document definitions using the same names for XML elements that have different meaning. To resolve the name space, i.e. i.e. find out to where the identifier points, one can use the expression \code{xmlNamespace(xmlRoot(doc))}. The class of the result is is an S3-style object of class \code{XMLNamespace}. } \usage{ xmlNamespace(x) xmlNamespace(x, ...) <- value } \arguments{ \item{x}{the object whose namespace is to be computed} \item{value}{the prefix for a namespace that is defined in the node or any of the ancestors.} \item{\dots}{additional arguments for setting the name space} } \value{ For non-root nodes, this returns a string giving the identifier of the name space for this node. For the root node, this returns a list with 2 elements: \item{id}{the identifier by which other nodes refer to this namespace.} \item{uri}{the URI or location that defines this namespace.} \item{local}{? (can't remember off-hand).} } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlName}} \code{\link{xmlChildren}} \code{\link{xmlAttrs}} \code{\link{xmlValue}} \code{\link{xmlNamespaceDefinitions}} } \examples{ doc <- xmlTreeParse(system.file("exampleData", "job.xml", package="XML")) xmlNamespace(xmlRoot(doc)) xmlNamespace(xmlRoot(doc)[[1]][[1]]) doc <- xmlInternalTreeParse(system.file("exampleData", "job.xml", package="XML")) # Since the first node, xmlRoot() will skip that, by default. xmlNamespace(xmlRoot(doc)) xmlNamespace(xmlRoot(doc)[[1]][[1]]) node <- xmlNode("arg", xmlNode("name", "foo"), namespace="R") xmlNamespace(node) doc = xmlParse('a = 1:10') node = xmlRoot(doc)[[1]][[1]] xmlNamespace(node) = "r" node doc = xmlParse('a = 1:10') node = xmlRoot(doc)[[1]][[1]] xmlNamespaces(node, set = TRUE) = c(omg = "https://www.omegahat.net") node } \keyword{file} XML/man/xmlElementsByTagName.Rd0000644000175100001440000000553614405636156016042 0ustar hornikusers\name{xmlElementsByTagName} \alias{xmlElementsByTagName} \title{Retrieve the children of an XML node with a specific tag name} \description{ This returns a list of the children or sub-elements of an XML node whose tag name matches the one specified by the user. } \usage{ xmlElementsByTagName(el, name, recursive = FALSE) } \arguments{ \item{el}{the node whose matching children are to be retrieved.} \item{name}{a string giving the name of the tag to match in each of \code{el}'s children.} \item{recursive}{a logical value. If this is \code{FALSE}, the default, only the direct child nodes are searched. Alternatively, if this is \code{TRUE}, all sub-nodes at all levels are searched. In other words, we find all descendants of the node \code{el} and return a list with the nodes having the given name. The relationship between the nodes in the resulting list cannot be determined. This is a set of nodes. See the note. } } \details{ This does a simple matching of names and subsets the XML node's children list. If \code{recursive} is \code{TRUE}, then the function is applied recursively to the children of the given node and so on. } \note{ The addition of the \code{recursive} argument makes this function behave like the \code{getElementsByTagName} in other language APIs such as Java, C#. However, one should be careful to understand that in those languages, one would get back a set of node objects. These nodes have references to their parents and children. Therefore one can navigate the tree from each node, find its relations, etc. In the current version of this package (and for the forseeable future), the node set is a \dQuote{copy} of the nodes in the original tree. And these have no facilities for finding their siblings or parent. Additionally, one can consume a large amount of memory by taking a copy of numerous large nodes using this facility. If one does not modify the nodes, the extra memory may be small. But modifying them means that the contents will be copied. Alternative implementations of the tree, e.g. using unique identifiers for nodes or via internal data structures from libxml can allow us to implement this function with different semantics, more similar to the other APIs. } \value{ A list containing those child nodes of \code{el} whose tag name matches that specified by the user. } \references{\url{https://www.w3.org/XML/}, \url{https://www.omegahat.net/RSXML/}, } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlChildren}} \code{\link{xmlTreeParse}} } \examples{ \dontrun{ doc <- xmlTreeParse("https://www.omegahat.net/Scripts/Data/mtcars.xml") xmlElementsByTagName(doc$children[[1]], "variable") } doc <- xmlTreeParse(system.file("exampleData", "mtcars.xml", package="XML")) xmlElementsByTagName(xmlRoot(doc)[[1]], "variable") } \keyword{IO} \keyword{file} XML/man/getNodeSet.Rd0000644000175100001440000004746214405636156014062 0ustar hornikusers\name{getNodeSet} \alias{getNodeSet} \alias{xpathApply} \alias{xpathSApply} \alias{matchNamespaces} \title{Find matching nodes in an internal XML tree/DOM} \description{ These functions provide a way to find XML nodes that match a particular criterion. It uses the XPath syntax and allows very powerful expressions to identify nodes of interest within a document both clearly and efficiently. The XPath language requires some knowledge, but tutorials are available on the Web and in books. XPath queries can result in different types of values such as numbers, strings, and node sets. It allows simple identification of nodes by name, by path (i.e. hierarchies or sequences of node-child-child...), with a particular attribute or matching a particular attribute with a given value. It also supports functionality for navigating nodes in the tree within a query (e.g. \code{ancestor()}, \code{child()}, \code{self()}), and also for manipulating the content of one or more nodes (e.g. \code{text}). And it allows for criteria identifying nodes by position, etc. using some counting operations. Combining XPath with R allows for quite flexible node identification and manipulation. XPath offers an alternative way to find nodes of interest than recursively or iteratively navigating the entire tree in R and performing the navigation explicitly. One can search an entire document or start the search from a particular node. Such node-based searches can even search up the tree as well as within the sub-tree that the node parents. Node specific XPath expressions are typically started with a "." to indicate the search is relative to that node. You can use several XPath 2.0 functions in the XPath query. Furthermore, you can also register additional XPath functions that are implemented either with R functions or C routines. (See \code{xpathFuns}.) The set of matching nodes corresponding to an XPath expression are returned in R as a list. One can then iterate over these elements to process the nodes in whatever way one wants. Unfortunately, this involves two loops - one in the XPath query over the entire tree, and another in R. Typically, this is fine as the number of matching nodes is reasonably small. However, if repeating this on numerous files, speed may become an issue. We can avoid the second loop (i.e. the one in R) by applying a function to each node before it is returned to R as part of the node set. The result of the function call is then returned, rather than the node itself. One can provide an R expression rather than an R function for \code{fun}. This is expected to be a call and the first argument of the call will be replaced with the node. Dealing with expressions that relate to the default namespaces in the XML document can be confusing. \code{xpathSApply} is a version of \code{xpathApply} which attempts to simplify the result if it can be converted to a vector or matrix rather than left as a list. In this way, it has the same relationship to \code{xpathApply} as \code{\link{sapply}} has to \code{\link{lapply}}. \code{matchNamespaces} is a separate function that is used to facilitate specifying the mappings from namespace prefix used in the XPath expression and their definitions, i.e. URIs, and connecting these with the namespace definitions in the target XML document in which the XPath expression will be evaluated. \code{matchNamespaces} uses rules that are very slightly awkard or specifically involve a special case. This is because this mapping of namespaces from XPath to XML targets is difficult, involving prefixes in the XPath expression, definitions in the XPath evaluation context and matches of URIs with those in the XML document. The function aims to avoid having to specify all the prefix=uri pairs by using "sensible" defaults and also matching the prefixes in the XPath expression to the corresponding definitions in the XML document. The rules are as follows. \code{namespaces} is a character vector. Any element that has a non-trivial name (i.e. other than "") is left as is and the name and value define the prefix = uri mapping. Any elements that have a trivial name (i.e. no name at all or "") are resolved by first matching the prefix to those of the defined namespaces anywhere within the target document, i.e. in any node and not just the root one. If there is no match for the first element of the \code{namespaces} vector, this is treated specially and is mapped to the default namespace of the target document. If there is no default namespace defined, an error occurs. It is best to give explicit the argument in the form \code{c(prefix = uri, prefix = uri)}. However, one can use the same namespace prefixes as in the document if one wants. And one can use an arbitrary namespace prefix for the default namespace URI of the target document provided it is the first element of \code{namespaces}. See the 'Details' section below for some more information. } \usage{ getNodeSet(doc, path, namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), fun = NULL, sessionEncoding = CE_NATIVE, addFinalizer = NA, ...) xpathApply(doc, path, fun, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, addFinalizer = NA, xpathFuns = list()) xpathSApply(doc, path, fun = NULL, ... , namespaces = xmlNamespaceDefinitions(doc, simplify = TRUE), resolveNamespaces = TRUE, simplify = TRUE, addFinalizer = NA) matchNamespaces(doc, namespaces, nsDefs = xmlNamespaceDefinitions(doc, recursive = TRUE, simplify = FALSE), defaultNs = getDefaultNamespace(doc, simplify = TRUE)) } \arguments{ \item{doc}{an object of class \code{XMLInternalDocument}} \item{path}{a string (character vector of length 1) giving the XPath expression to evaluate.} \item{namespaces}{ a named character vector giving the namespace prefix and URI pairs that are to be used in the XPath expression and matching of nodes. The prefix is just a simple string that acts as a short-hand or alias for the URI that is the unique identifier for the namespace. The URI is the element in this vector and the prefix is the corresponding element name. One only needs to specify the namespaces in the XPath expression and for the nodes of interest rather than requiring all the namespaces for the entire document. Also note that the prefix used in this vector is local only to the path. It does not have to be the same as the prefix used in the document to identify the namespace. However, the URI in this argument must be identical to the target namespace URI in the document. It is the namespace URIs that are matched (exactly) to find correspondence. The prefixes are used only to refer to that URI. } \item{fun}{a function object, or an expression or call, which is used when the result is a node set and evaluated for each node element in the node set. If this is a call, the first argument is replaced with the current node. } \item{...}{any additional arguments to be passed to \code{fun} for each node in the node set.} \item{resolveNamespaces}{a logical value indicating whether to process the collection of namespaces and resolve those that have no name by looking in the default namespace and the namespace definitions within the target document to match by prefix.} \item{nsDefs}{a list giving the namespace definitions in which to match any prefixes. This is typically computed directly from the target document and the default value is most appropriate.} \item{defaultNs}{the default namespace prefix-URI mapping given as a named character vector. This is not a namespace definition object. This is used when matching a simple prefix that has no corresponding entry in \code{nsDefs} and is the first element in the \code{namespaces} vector. } \item{simplify}{a logical value indicating whether the function should attempt to perform the simplification of the result into a vector rather than leaving it as a list. This is the same as \code{\link{sapply}} does in comparison to \code{\link{lapply}}. } %XXX \item{sessionEncoding}{experimental functionality and parameter related to encoding.} \item{addFinalizer}{a logical value or identifier for a C routine that controls whether we register finalizers on the intenal node.} \item{xpathFuns}{a list containing either character strings, functions or named elements containing the address of a C routine. These identify functions that can be used in the XPath expression. A character string identifies the name of the XPath function and the R function of the same name (and located on the R search path). A C routine to implement an XPath function is specified via a call to \code{\link{getNativeSymbolInfo}} and passing just the address field. This is provided in the \code{list()} with a name which is used as the name of the XPath function. } } \details{ When a namespace is defined on a node in the XML document, an XPath expressions must use a namespace, even if it is the default namespace for the XML document/node. For example, suppose we have an XML document \code{...} To find all the topic nodes, we might want to use the XPath expression \code{"/help/topic"}. However, we must use an explicit namespace prefix that is associated with the URI \code{http://www.r-project.org/Rd} corresponding to the one in the XML document. So we would use \code{getNodeSet(doc, "/r:help/r:topic", c(r = "http://www.r-project.org/Rd"))}. As described above, the functions attempt to allow the namespaces to be specified easily by the R user and matched to the namespace definitions in the target document. This calls the libxml routine \code{xmlXPathEval}. } \value{ The results can currently be different based on the returned value from the XPath expression evaluation: \item{list}{a node set} \item{numeric}{a number} \item{logical}{a boolean} \item{character}{a string, i.e. a single character element.} If \code{fun} is supplied and the result of the XPath query is a node set, the result in R is a list. } \references{\url{http://xmlsoft.org}, \url{https://www.w3.org/XML//} \url{https://www.w3.org/TR/xpath/} \url{https://www.omegahat.net/RSXML/} } \author{Duncan Temple Lang } \note{ In order to match nodes in the default name space for documents with a non-trivial default namespace, e.g. given as \code{xmlns="https://www.omegahat.net"}, you will need to use a prefix for the default namespace in this call. When specifying the namespaces, give a name - any name - to the default namespace URI and then use this as the prefix in the XPath expression, e.g. \code{getNodeSet(d, "//d:myNode", c(d = "https://www.omegahat.net"))} to match myNode in the default name space \code{https://www.omegahat.net}. This default namespace of the document is now computed for us and is the default value for the namespaces argument. It can be referenced using the prefix 'd', standing for default but sufficiently short to be easily used within the XPath expression. More of the XPath functionality provided by libxml can and may be made available to the R package. Facilities such as compiled XPath expressions, functions, ordered node information are examples. Please send requests to the package maintainer. } \seealso{ \code{\link{xmlTreeParse}} with \code{useInternalNodes} as \code{TRUE}. } \examples{ doc = xmlParse(system.file("exampleData", "tagnames.xml", package = "XML")) els = getNodeSet(doc, "/doc//a[@status]") sapply(els, function(el) xmlGetAttr(el, "status")) # use of namespaces on an attribute. getNodeSet(doc, "/doc//b[@x:status]", c(x = "https://www.omegahat.net")) getNodeSet(doc, "/doc//b[@x:status='foo']", c(x = "https://www.omegahat.net")) # Because we know the namespace definitions are on /doc/a # we can compute them directly and use them. nsDefs = xmlNamespaceDefinitions(getNodeSet(doc, "/doc/a")[[1]]) ns = structure(sapply(nsDefs, function(x) x$uri), names = names(nsDefs)) getNodeSet(doc, "/doc//b[@omegahat:status='foo']", ns)[[1]] # free(doc) ##### f = system.file("exampleData", "eurofxref-hist.xml.gz", package = "XML") e = xmlParse(f) ans = getNodeSet(e, "//o:Cube[@currency='USD']", "o") sapply(ans, xmlGetAttr, "rate") # or equivalently ans = xpathApply(e, "//o:Cube[@currency='USD']", xmlGetAttr, "rate", namespaces = "o") # free(e) # Using a namespace f = system.file("exampleData", "SOAPNamespaces.xml", package = "XML") z = xmlParse(f) getNodeSet(z, "/a:Envelope/a:Body", c("a" = "http://schemas.xmlsoap.org/soap/envelope/")) getNodeSet(z, "//a:Body", c("a" = "http://schemas.xmlsoap.org/soap/envelope/")) # free(z) # Get two items back with namespaces f = system.file("exampleData", "gnumeric.xml", package = "XML") z = xmlParse(f) getNodeSet(z, "//gmr:Item/gmr:name", c(gmr="http://www.gnome.org/gnumeric/v2")) #free(z) ##### # European Central Bank (ECB) exchange rate data # Data is available from "http://www.ecb.int/stats/eurofxref/eurofxref-hist.xml" # or locally. uri = system.file("exampleData", "eurofxref-hist.xml.gz", package = "XML") doc = xmlParse(uri) # The default namespace for all elements is given by namespaces <- c(ns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref") # Get the data for Slovenian currency for all time periods. # Find all the nodes of the form slovenia = getNodeSet(doc, "//ns:Cube[@currency='SIT']", namespaces ) # Now we have a list of such nodes, loop over them # and get the rate attribute rates = as.numeric( sapply(slovenia, xmlGetAttr, "rate") ) # Now put the date on each element # find nodes of the form # and extract the time attribute names(rates) = sapply(getNodeSet(doc, "//ns:Cube[@time]", namespaces ), xmlGetAttr, "time") # Or we could turn these into dates with strptime() strptime(names(rates), "\%Y-\%m-\%d") # Using xpathApply, we can do rates = xpathApply(doc, "//ns:Cube[@currency='SIT']", xmlGetAttr, "rate", namespaces = namespaces ) rates = as.numeric(unlist(rates)) # Using an expression rather than a function and ... rates = xpathApply(doc, "//ns:Cube[@currency='SIT']", quote(xmlGetAttr(x, "rate")), namespaces = namespaces ) #free(doc) # uri = system.file("exampleData", "namespaces.xml", package = "XML") d = xmlParse(uri) getNodeSet(d, "//c:c", c(c="http://www.c.org")) getNodeSet(d, "/o:a//c:c", c("o" = "https://www.omegahat.net", "c" = "http://www.c.org")) # since https://www.omegahat.net is the default namespace, we can # just the prefix "o" to map to that. getNodeSet(d, "/o:a//c:c", c("o", "c" = "http://www.c.org")) # the following, perhaps unexpectedly but correctly, returns an empty # with no matches getNodeSet(d, "//defaultNs", "https://www.omegahat.net") # But if we create our own prefix for the evaluation of the XPath # expression and use this in the expression, things work as one # might hope. getNodeSet(d, "//dummy:defaultNs", c(dummy = "https://www.omegahat.net")) # And since the default value for the namespaces argument is the # default namespace of the document, we can refer to it with our own # prefix given as getNodeSet(d, "//d:defaultNs", "d") # And the syntactic sugar is d["//d:defaultNs", namespace = "d"] # this illustrates how we can use the prefixes in the XML document # in our query and let getNodeSet() and friends map them to the # actual namespace definitions. # "o" is used to represent the default namespace for the document # i.e. https://www.omegahat.net, and "r" is mapped to the same # definition that has the prefix "r" in the XML document. tmp = getNodeSet(d, "/o:a/r:b/o:defaultNs", c("o", "r")) xmlName(tmp[[1]]) #free(d) # Work with the nodes and their content (not just attributes) from the node set. # From bondsTables.R in examples/ \dontrun{## fails to download as from May 2017 doc = htmlTreeParse("http://finance.yahoo.com/bonds/composite_bond_rates?bypass=true", useInternalNodes = TRUE) if(is.null(xmlRoot(doc))) doc = htmlTreeParse("http://finance.yahoo.com/bonds?bypass=true", useInternalNodes = TRUE) # Use XPath expression to find the nodes #
    .. # as these are the ones we want. if(!is.null(xmlRoot(doc))) { o = getNodeSet(doc, "//div/table[@class='yfirttbl']") } # Write a function that will extract the information out of a given table node. readHTMLTable = function(tb) { # get the header information. colNames = sapply(tb[["thead"]][["tr"]]["th"], xmlValue) vals = sapply(tb[["tbody"]]["tr"], function(x) sapply(x["td"], xmlValue)) matrix(as.numeric(vals[-1,]), nrow = ncol(vals), dimnames = list(vals[1,], colNames[-1]), byrow = TRUE ) } # Now process each of the table nodes in the o list. tables = lapply(o, readHTMLTable) names(tables) = lapply(o, function(x) xmlValue(x[["caption"]])) } # this illustrates an approach to doing queries on a sub tree # within the document. # Note that there is a memory leak incurred here as we create a new # XMLInternalDocument in the getNodeSet(). f = system.file("exampleData", "book.xml", package = "XML") doc = xmlParse(f) ch = getNodeSet(doc, "//chapter") xpathApply(ch[[2]], "//section/title", xmlValue) # To fix the memory leak, we explicitly create a new document for # the subtree, perform the query and then free it _when_ we are done # with the resulting nodes. subDoc = xmlDoc(ch[[2]]) xpathApply(subDoc, "//section/title", xmlValue) free(subDoc) txt = '' doc = xmlInternalTreeParse(txt, asText = TRUE) \dontrun{ # Will fail because it doesn't know what the namespace x is # and we have to have one eventhough it has no prefix in the document. xpathApply(doc, "//x:b") } # So this is how we do it - just say x is to be mapped to the # default unprefixed namespace which we shall call x! xpathApply(doc, "//x:b", namespaces = "x") # Here r is mapped to the the corresponding definition in the document. xpathApply(doc, "//r:a", namespaces = "r") # Here, xpathApply figures this out for us, but will raise a warning. xpathApply(doc, "//r:a") # And here we use our own binding. xpathApply(doc, "//x:a", namespaces = c(x = "http://www.r-project.org")) # Get all the nodes in the entire tree. table(unlist(sapply(doc["//*|//text()|//comment()|//processing-instruction()"], class))) ## Use of XPath 2.0 functions min() and max() doc = xmlParse('

    ') getNodeSet(doc, "//p[@age = min(//p/@age)]") getNodeSet(doc, "//p[@age = max(//p/@age)]") avg = function(...) { mean(as.numeric(unlist(...))) } getNodeSet(doc, "//p[@age > avg(//p/@age)]", xpathFuns = "avg") doc = xmlParse('') getNodeSet(doc, "//ev[month-from-date(@date) > 7]", xpathFuns = list("month-from-date" = function(node) { match(months(as.Date(as.character(node[[1]]))), month.name) })) } \keyword{file} \keyword{IO} XML/man/xmlToDataFrame.Rd0000644000175100001440000001032514205426523014646 0ustar hornikusers\name{xmlToDataFrame} \alias{xmlToDataFrame} \alias{xmlToDataFrame,character,ANY,ANY,ANY,ANY-method} \alias{xmlToDataFrame,XMLInternalDocument,ANY,ANY,ANY,missing-method} \alias{xmlToDataFrame,ANY,ANY,ANY,ANY,XMLNodeSet-method} \alias{xmlToDataFrame,ANY,ANY,ANY,ANY,XMLInternalNodeList-method} \alias{xmlToDataFrame,ANY,ANY,ANY,ANY,list-method} \alias{xmlToDataFrame,XMLInternalNodeList,ANY,ANY,ANY,ANY-method} \alias{xmlToDataFrame,XMLInternalElementNode,ANY,ANY,ANY,ANY-method} \alias{xmlToDataFrame,XMLNodeSet,ANY,ANY,ANY,ANY-method} \alias{xmlToDataFrame,list,ANY,ANY,ANY,ANY-method} \title{Extract data from a simple XML document} \description{ This function can be used to extract data from an XML document (or sub-document) that has a simple, shallow structure that does appear reasonably commonly. The idea is that there is a collection of nodes which have the same fields (or a subset of common fields) which contain primitive values, i.e. numbers, strings, etc. Each node corresponds to an "observation" and each of its sub-elements correspond to a variable. This function then builds the corresponding data frame, using the union of the variables in the different observation nodes. This can handle the case where the nodes do not all have all of the variables. } \usage{ xmlToDataFrame(doc, colClasses = NULL, homogeneous = NA, collectNames = TRUE, nodes = list(), stringsAsFactors = FALSE) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{doc}{the XML content. This can be the name of a file containing the XML, the parsed XML document. If one wants to work on a subset of nodes, specify these via the \code{nodes} parameter.} \item{colClasses}{a list/vector giving the names of the R types for the corresponding variables and this is used to coerce the resulting column in the data frame to this type. These can be named. This is similar to the \code{colClasses} parameter for \code{\link{read.table}}. If this is given as a list, columns in the data frame corresponding to elements that are \code{NULL} are omitted from the answer. This can be slightly complex to specify if the different nodes have the "variables" in quite different order as there is not a well defined order for the variables corresponding to \code{colClasses}. } \item{homogeneous}{a logical value that indicates whether each of the nodes contains all of the variables (\code{TRUE}) or if there may be some nodes which have only a subset of them. The function determines this if the caller does not specify \code{homogeneous} or uses \code{NA} as the value. It is a parameter to allow the caller to specify this information and avoid these "extra" computations. If the caller knows this information it is more efficient to specify it. } \item{collectNames}{a logical value indicating whether we compute the names by explicitly computing the union of all variable names or, if \code{FALSE}, we use the names from the node with the most children. This latter case is useful when the caller knows that the there is at least one node with all the variables. } \item{nodes}{a list of XML nodes which are to be processed} \item{stringsAsFactors}{a logical value that controls whether character vectors are converted to factor objects in the resulting data frame.} } \value{ A data frame. } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlParse}} \code{\link{getNodeSet}} } \examples{ f = system.file("exampleData", "size.xml", package = "XML") xmlToDataFrame(f, c("integer", "integer", "numeric")) # Drop the middle variable. z = xmlToDataFrame(f, colClasses = list("integer", NULL, "numeric")) # This illustrates how we can get a subset of nodes and process # those as the "data nodes", ignoring the others. f = system.file("exampleData", "tides.xml", package = "XML") doc = xmlParse(f) xmlToDataFrame(nodes = xmlChildren(xmlRoot(doc)[["data"]])) # or, alternatively xmlToDataFrame(nodes = getNodeSet(doc, "//data/item")) f = system.file("exampleData", "kiva_lender.xml", package = "XML") doc = xmlParse(f) dd = xmlToDataFrame(getNodeSet(doc, "//lender")) } \keyword{IO} XML/man/xmlStructuredStop.Rd0000644000175100001440000000655713700532410015535 0ustar hornikusers\name{xmlStructuredStop} \alias{xmlStructuredStop} \alias{xmlErrorCumulator} \title{Condition/error handler functions for XML parsing} \description{ These functions provide basic error handling for the XML parser in R. They also illustrate the basics which will allow others to provide customized error handlers that make more use of the information provided in each error reported. The \code{xmlStructuredStop} function provides a simple R-level handler for errors raised by the XML parser. It collects the information provided by the XML parser and raises an R error. This is only used if \code{NULL} is specified for the \code{error} argument of \code{\link{xmlTreeParse}}, \code{\link{xmlTreeParse}} and \code{\link{htmlTreeParse}}. The default is to use the function returned by a call to \code{xmlErrorCumulator} as the error handler. This, as the name suggests, cumulates errors. The idea is to catch each error and let the parser continue and then report them all. As each error is encountered, it is collected by the function. If \code{immediate} is \code{TRUE}, the error is also reported on the console. When the parsing is complete and has failed, this function is invoked again with a zero-length character vector as the message (first argument) and then it raises an error. This function will then raise an R condition of class \code{class}. } \usage{ xmlStructuredStop(msg, code, domain, line, col, level, filename, class = "XMLError") xmlErrorCumulator(class = "XMLParserErrorList", immediate = TRUE) } \arguments{ \item{msg}{character string, the text of the message being reported} \item{code}{ an integer code giving an identifier for the error (see xmlerror.h) for the moment,} \item{domain}{ an integer domain indicating in which "module" or part of the parsing the error occurred, e.g. name space, parser, tree, xinclude, etc.} \item{line}{ an integer giving the line number in the XML content being processed corresponding to the error, } \item{col}{ an integer giving the column position of the error, } \item{level}{ an integer giving the severity of the error ranging from 1 to 3 in increasing severity (warning, error, fatal),} \item{filename}{character string, the name of the document being processed, i.e. its file name or URL.} \item{class}{ character vector, any classes to prepend to the class attribute to make the error/condition. These are prepended to those returned via \code{\link{simpleError}}.} \item{immediate}{logical value, if \code{TRUE} errors are displayed on the R console as they are encountered. Otherwise, the errors are collected and displayed at the end of the XML parsing.} } \value{ This calls \code{\link{stop}} and so does not return a value. } \references{libxml2 and its error handling facilities (\url{http://xmlsoft.org}} \author{ Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlInternalTreeParse}} \code{\link{htmlTreeParse}} } \examples{ tryCatch( xmlTreeParse("", asText = TRUE, error = NULL), XMLError = function(e) { cat("There was an error in the XML at line", e$line, "column", e$col, "\n", e$message, "\n") }) } \keyword{IO } \keyword{programming} \concept{error handling} XML/man/xmlEventParse.Rd0000644000175100001440000005257414405636156014616 0ustar hornikusers\name{xmlEventParse} \alias{xmlEventParse} \title{ XML Event/Callback element-wise Parser} \description{ This is the event-driven or SAX (Simple API for XML) style parser which process XML without building the tree but rather identifies tokens in the stream of characters and passes them to handlers which can make sense of them in context. This reads and processes the contents of an XML file or string by invoking user-level functions associated with different components of the XML tree. These components include the beginning and end of XML elements, e.g \code{} and \code{} respectively, comments, CDATA (escaped character data), entities, processing instructions, etc. This allows the caller to create the appropriate data structure from the XML document contents rather than the default tree (see \link{xmlTreeParse}) and so avoids having the entire document in memory. This is important for large documents and where we would end up with essentially 2 copies of the data in memory at once, i.e the tree and the R data structure containing the information taken from the tree. When dealing with classes of XML documents whose instances could be large, this approach is desirable but a little more cumbersome to program than the standard DOM (Document Object Model) approach provided by \code{XMLTreeParse}. Note that \code{xmlTreeParse} does allow a hybrid style of processing that allows us to apply handlers to nodes in the tree as they are being converted to R objects. This is a style of event-driven or asynchronous calling In addition to the generic token event handlers such as "begin an XML element" (the \code{startElement} handler), one can also provide handler functions for specific tags/elements such as \code{} with handler elements with the same name as the XML element of interest, i.e. \code{"myTag" = function(x, attrs)}. When the event parser is reading text nodes, it may call the text handler function with different sub-strings of the text within the node. Essentially, the parser collects up n characters into a buffer and passes this as a single string the text handler and then continues collecting more text until the buffer is full or there is no more text. It passes each sub-string to the text handler. If \code{trim} is \code{TRUE}, it removes leading and trailing white space from the substring before calling the text handler. If the resulting text is empty and \code{ignoreBlanks} is \code{TRUE}, then we don't bother calling the text handler function. So the key thing to remember about dealing with text is that the entire text of a node may come in multiple separate calls to the text handler. A common idiom is to have the text handler concatenate the values it is passed in separate calls and to have the end element handler process the entire text and reset the text variable to be empty. } \usage{ xmlEventParse(file, handlers = xmlEventHandler(), ignoreBlanks = FALSE, addContext=TRUE, useTagName = TRUE, asText = FALSE, trim=TRUE, useExpat=FALSE, isURL = FALSE, state = NULL, replaceEntities = TRUE, validate = FALSE, saxVersion = 1, branches = NULL, useDotNames = length(grep("^\\\\.", names(handlers))) > 0, error = xmlErrorCumulator(), addFinalizer = NA, encoding = character()) } \arguments{ \item{file}{the source of the XML content. This can be a string giving the name of a file or remote URL, the XML itself, a connection object, or a function. If this is a string, and \code{asText} is \code{TRUE}, the value is the XML content. This allows one to read the content separately from parsing without having to write it to a file. If \code{asText} is \code{FALSE} and a string is passed for \code{file}, this is taken as the name of a file or remote URI. If one is using the libxml parser (i.e. not expat), this can be a URI accessed via HTTP or FTP or a compressed local file. If it is the name of a local file, it can include \code{~}, environment variables, etc. which will be expanded by R. (Note this is not the case in S-Plus, as far as I know.) If a connection is given, the parser incrementally reads one line at a time by calling the function \code{\link{readLines}} with the connection as the first argument (and \code{1} as the number of lines to read). The parser calls this function each time it needs more input. If invoking the \code{readLines} function to get each line is excessively slow or is inappropriate, one can provide a function as the value of \code{fileName}. Again, when the XML parser needs more content to process, it invokes this function to get a string. This function is called with a single argument, the maximum size of the string that can be returned. The function is responsible for accessing the correct connection(s), etc. which is typically done via lexical scoping/environments. This mechanism allows the user to control how the XML content is retrieved in very general ways. For example, one might read from a set of files, starting one when the contents of the previous file have been consumed. This allows for the use of hybrid connection objects. Support for connections and functions in this form is only provided if one is using libxml2 and not libxml version 1. } \item{handlers}{ a closure object that contains functions which will be invoked as the XML components in the document are encountered by the parser. The standard function or handler names are \code{startElement()}, \code{endElement()} \code{comment()}, \code{getEntity}, \code{entityDeclaration()}, \code{processingInstruction()}, \code{text()}, \code{cdata()}, \code{startDocument()}, and \code{endDocument()}, or alternatively and preferrably, these names prefixed with a '.', i.e. .startElement, .comment, ... The call signature for the entityDeclaration function was changed in version 1.7-0. Note that in earlier versions, the C routine did not invoke any R function and so no code will actually break. Also, we have renamed \code{externalEntity} to \code{getEntity}. These were based on the expat parser. The new signature is \code{c(name = "character", type = "integer", content = "", system = "character", public = "character" )} \code{name} gives the name of the entity being defined. The \code{type} identifies the type of the entity using the value of a C-level enumerated constant used in libxml2, but also gives the human-readable form as the name of the single element in the integer vector. The possible values are \code{"Internal_General"}, \code{"External_General_Parsed"}, \code{"External_General_Unparsed"}, \code{"Internal_Parameter"}, \code{"External_Parameter"}, \code{"Internal_Predefined"}. If we are dealing with an internal entity, the content will be the string containing the value of the entity. If we are dealing with an external entity, then \code{content} will be a character vector of length 0, i.e. empty. Instead, either or both of the system and public arguments will be non-empty and identify the location of the external content. \code{system} will be a string containing a URI, if non-empty, and \code{public} corresponds to the PUBLIC identifier used to identify content using an SGML-like approach. The use of PUBLIC identifiers is less common. } \item{ignoreBlanks}{a logical value indicating whether text elements made up entirely of white space should be included in the resulting `tree'. } \item{addContext}{ logical value indicating whether the callback functions in `handlers' should be invoked with contextual information about the parser and the position in the tree, such as node depth, path indices for the node relative the root, etc. If this is True, each callback function should support \dots. } \item{useTagName}{ a logical value. If this is \code{TRUE}, when the SAX parser signals an event for the start of an XML element, it will first look for an element in the list of handler functions whose name matches (exactly) the name of the XML element. If such an element is found, that function is invoked. Otherwise, the generic \code{startElement} handler function is invoked. The benefit of this is that the author of the handler functions can write node-specific handlers for the different element names in a document and not have to establish a mechanism to invoke these functions within the \code{startElement} function. This is done by the XML package directly. If the value is \code{FALSE}, then the \code{startElement} handler function will be called without any effort to find a node-specific handler. If there are no node-specific handlers, specifying \code{FALSE} for this parameter will make the computations very slightly faster. } \item{asText}{logical value indicating that the first argument, `file', should be treated as the XML text to parse, not the name of a file. This allows the contents of documents to be retrieved from different sources (e.g. HTTP servers, XML-RPC, etc.) and still use this parser.} \item{trim}{ whether to strip white space from the beginning and end of text strings. } % \item{restartCounter}{} \item{useExpat}{ a logical value indicating whether to use the expat SAX parser, or to default to the libxml. If this is TRUE, the library must have been compiled with support for expat. See \link{supportsExpat}. } \item{isURL}{ indicates whether the \code{file} argument refers to a URL (accessible via ftp or http) or a regular file on the system. If \code{asText} is TRUE, this should not be specified. } \item{state}{an optional S object that is passed to the callbacks and can be modified to communicate state between the callbacks. If this is given, the callbacks should accept an argument named \code{.state} and it should return an object that will be used as the updated value of this state object. The new value can be any S object and will be passed to the next callback where again it will be updated by that functions return value, and so on. If this not specified in the call to \code{xmlEventParse}, no \code{.state} argument is passed to the callbacks. This makes the interface compatible with previous releases. } \item{replaceEntities}{ logical value indicating whether to substitute entity references with their text directly. This should be left as False. The text still appears as the value of the node, but there is more information about its source, allowing the parse to be reversed with full reference information. } \item{saxVersion}{an integer value which should be either 1 or 2. This specifies which SAX interface to use in the C code. The essential difference is the number of arguments passed to the \code{startElement} handler function(s). Under SAX 2, in addition to the name of the element and the named-attributes vector, two additional arguments are provided. The first identifies the namespace of the element. This is a named character vector of length 1, with the value being the URI of the namespace and the name being the prefix that identifies that namespace within the document. For example, \code{xmlns:r="http://www.r-project.org"} would be passed as \code{c(r = "http://www.r-project.org")}. If there is no prefix because the namespace is being used as the default, the result of calling \code{\link{names}} on the string is \code{""}. The second additional argument (the fourth in total) gives the collection of all the namespaces defined within this element. Again, this is a named character vector. } \item{validate}{ Currently, this has no effect as the libxml2 parser uses a document structure to do validation. a logical indicating whether to use a validating parser or not, or in other words check the contents against the DTD specification. If this is true, warning messages will be displayed about errors in the DTD and/or document, but the parsing will proceed except for the presence of terminal errors. } \item{branches}{a named list of functions. Each element identifies an XML element name. If an XML element of that name is encountered in the SAX stream, the stream is processed until the end of that element and an internal node (see \code{\link{xmlTreeParse}} and its \code{useInternalNodes} parameter) is created. The function in our branches list corresponding to this XML element is then invoked with the (internal) node as the only argument. This allows one to use the DOM model on a sub-tree of the entire document and thus use both SAX and DOM together to get the efficiency of SAX and the simpler programming model of DOM. Note that the branches mechanism works top-down and does not work for nested tags. If one specifies an element name in the \code{branches} argument, e.g. myNode, and there is a nested myNode instance within a branch, the branches handler will not be called for that nested instance. If there is an instance where this is problematic, please contact the maintainer of this package. One can cause the parser to collect a branch without identifying the node within the \code{branches} list. Specifically, within a regular start-element handler, one can return a function whose class is \code{SAXBranchFunction}. The SAX parser recognizes this and collects up the branch starting at the current node being processed and when it is complete, invokes this function. This allows us to dynamically determine which nodes to treat as branches rather than just matching names. This is necessary when a node name has different meanings in different parts of the XML hierarchy, e.g. dict in an iTunes song list. See the file \code{itunesSax2.R} inthe examples for an example of this. This is a two step process. In the future, we might make it so that the R function handling the start-element event could directly collect the branch and continue its operations without having to call another function asynchronously. } \item{useDotNames}{a logical value indicating whether to use the newer format for identifying general element function handlers with the '.' prefix, e.g. .text, .comment, .startElement. If this is \code{FALSE}, then the older format text, comment, startElement, ... are used. This causes problems when there are indeed nodes named text or comment or startElement as a node-specific handler are confused with the corresponding general handler of the same name. Using \code{TRUE} means that your list of handlers should have names that use the '.' prefix for these general element handlers. This is the preferred way to write new code. } \item{error}{a function that is called when an XML error is encountered. This is called with 6 arguments and is described in \code{\link{xmlTreeParse}}. } \item{addFinalizer}{a logical value or identifier for a C routine that controls whether we register finalizers on the intenal node.} \item{encoding}{ a character string (scalar) giving the encoding for the document. This is optional as the document should contain its own encoding information. However, if it doesn't, the caller can specify this for the parser. } } \details{ This is now implemented using the libxml parser. Originally, this was implemented via the Expat XML parser by Jim Clark (\url{http://www.jclark.com/}). } \value{ The return value is the `handlers' argument. It is assumed that this is a closure and that the callback functions have manipulated variables local to it and that the caller knows how to extract this. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}} \author{Duncan Temple Lang} \note{ The libxml parser can read URLs via http or ftp. It does not require the support of \code{wget} as used in other parts of \R, but uses its own facilities to connect to remote servers. The idea for the hybrid SAX/DOM mode where we consume tokens in the stream to create an entire node for a sub-tree of the document was first suggested to me by Seth Falcon at the Fred Hutchinson Cancer Research Center. It is similar to the XML::Twig module in Perl by Michel Rodriguez. } \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlStopParser}} XMLParserContextFunction } \examples{ fileName <- system.file("exampleData", "mtcars.xml", package="XML") # Print the name of each XML tag encountered at the beginning of each # tag. # Uses the libxml SAX parser. xmlEventParse(fileName, list(startElement=function(name, attrs){ cat(name,"\n") }), useTagName=FALSE, addContext = FALSE) \dontrun{ # Parse the text rather than a file or URL by reading the URL's contents # and making it a single string. Then call xmlEventParse xmlURL <- "https://www.omegahat.net/Scripts/Data/mtcars.xml" xmlText <- paste(scan(xmlURL, what="",sep="\n"),"\n",collapse="\n") xmlEventParse(xmlText, asText=TRUE) } # Using a state object to share mutable data across callbacks f <- system.file("exampleData", "gnumeric.xml", package = "XML") zz <- xmlEventParse(f, handlers = list(startElement=function(name, atts, .state) { .state = .state + 1 print(.state) .state }), state = 0) print(zz) # Illustrate the startDocument and endDocument handlers. xmlEventParse(fileName, handlers = list(startDocument = function() { cat("Starting document\n") }, endDocument = function() { cat("ending document\n") }), saxVersion = 2) if(libxmlVersion()$major >= 2) { startElement = function(x, ...) cat(x, "\n") xmlEventParse(ff <- file(f), handlers = list(startElement = startElement)) close(ff) # Parse with a function providing the input as needed. xmlConnection = function(con) { if(is.character(con)) con = file(con, "r") if(isOpen(con, "r")) open(con, "r") function(len) { if(len < 0) { close(con) return(character(0)) } x = character(0) tmp = "" while(length(tmp) > 0 && nchar(tmp) == 0) { tmp = readLines(con, 1) if(length(tmp) == 0) break if(nchar(tmp) == 0) x = append(x, "\n") else x = tmp } if(length(tmp) == 0) return(tmp) x = paste(x, collapse="") x } } \donttest{## this leaves a connection open ## xmlConnection would need amending to return the connection. ff = xmlConnection(f) xmlEventParse(ff, handlers = list(startElement = startElement)) } # Parse from a connection. Each time the parser needs more input, it # calls readLines(, 1) xmlEventParse(ff <-file(f), handlers = list(startElement = startElement)) close(ff) # using SAX 2 h = list(startElement = function(name, attrs, namespace, allNamespaces){ cat("Starting", name,"\n") if(length(attrs)) print(attrs) print(namespace) print(allNamespaces) }, endElement = function(name, uri) { cat("Finishing", name, "\n") }) xmlEventParse(system.file("exampleData", "namespaces.xml", package="XML"), handlers = h, saxVersion = 2) # This example is not very realistic but illustrates how to use the # branches argument. It forces the creation of complete nodes for # elements named and extracts the id attribute. # This could be done directly on the startElement, but this just # illustrates the mechanism. filename = system.file("exampleData", "branch.xml", package="XML") b.counter = function() { nodes <- character() f = function(node) { nodes <<- c(nodes, xmlGetAttr(node, "id"))} list(b = f, nodes = function() nodes) } b = b.counter() invisible(xmlEventParse(filename, branches = b["b"])) b$nodes() filename = system.file("exampleData", "branch.xml", package="XML") invisible(xmlEventParse(filename, branches = list(b = function(node) { print(names(node))}))) invisible(xmlEventParse(filename, branches = list(b = function(node) { print(xmlName(xmlChildren(node)[[1]]))}))) } ############################################ # Stopping the parser mid-way and an example of using XMLParserContextFunction. startElement = function(ctxt, name, attrs, ...) { print(ctxt) print(name) if(name == "rewriteURI") { cat("Terminating parser\n") xmlStopParser(ctxt) } } class(startElement) = "XMLParserContextFunction" endElement = function(name, ...) cat("ending", name, "\n") fileName = system.file("exampleData", "catalog.xml", package = "XML") xmlEventParse(fileName, handlers = list(startElement = startElement, endElement = endElement)) } \keyword{file} \keyword{IO} XML/man/setXMLNamespace.Rd0000644000175100001440000000254213607633744015003 0ustar hornikusers\name{setXMLNamespace} \alias{setXMLNamespace} \title{Set the name space on a node} \description{ This function sets the name space for an XML node, typically an internal node. We can use it to either define a new namespace and use that, or refer to a name space definition in an ancestor of the current node. } \usage{ setXMLNamespace(node, namespace, append = FALSE) } \arguments{ \item{node}{the node on which the name space is to be set} \item{namespace}{the name space to use for the node. This can be a name space prefix (string) defined in an ancestor node, or a named character vector of the form \code{c(prefix = URI)} that defines a new namespace on this node, or we can use a name space object created with \code{\link{newXMLNamespace}}.} \item{append}{currently ignored.} } \value{ An object of class \code{XMLNamespaceRef} which is a reference to the native/internal/C-level name space object. } %\references{} \author{ Duncan Temple Lang } \seealso{ \code{\link{newXMLNamespace}} \code{\link{removeXMLNamespaces}} } \examples{ # define a new namespace e = newXMLNode("foo") setXMLNamespace(e, c("r" = "http://www.r-project.org")) # use an existing namespace on an ancestor node e = newXMLNode("top", namespaceDefinitions = c("r" = "http://www.r-project.org")) setXMLNamespace(e, "r") e } \keyword{programming} XML/man/xmlRoot.Rd0000644000175100001440000000457214405636156013460 0ustar hornikusers\name{xmlRoot} \alias{xmlRoot} \alias{xmlRoot.XMLDocument} \alias{xmlRoot.XMLInternalDocument} \alias{xmlRoot.XMLInternalDOM} \alias{xmlRoot.XMLDocumentRoot} \alias{xmlRoot.XMLDocumentContent} \alias{xmlRoot.HTMLDocument} \title{Get the top-level XML node.} \description{ These are a collection of methods for providing easy access to the top-level \code{XMLNode} object resulting from parsing an XML document. They simplify accessing this node in the presence of auxillary information such as DTDs, file name and version information that is returned as part of the parsing. } \usage{ xmlRoot(x, skip = TRUE, ...) \method{xmlRoot}{XMLDocumentContent}(x, skip = TRUE, ...) \method{xmlRoot}{XMLInternalDocument}(x, skip = TRUE, addFinalizer = NA, ...) \method{xmlRoot}{HTMLDocument}(x, skip = TRUE, ...) } \arguments{ \item{x}{the object whose root/top-level XML node is to be returned.} \item{skip}{a logical value that controls whether DTD nodes and/or XMLComment objects that appear before the \dQuote{real} top-level node of the document should be ignored (\code{TRUE}) or not (\code{FALSE}) when returning the root node.} \item{...}{arguments that are passed by the generic to the different specialized methods of this generic.} \item{addFinalizer}{a logical value or identifier for a C routine that controls whether we register finalizers on the intenal node.} } \value{ An object of class \code{XMLNode}. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \note{One cannot obtain the parent or top-level node of an XMLNode object in S. This is different from languages like C, Java, Perl, etc. and is primarily because S does not provide support for references.} \seealso{ \code{\link{xmlTreeParse}} \code{\link{[[.XMLNode}} } \examples{ doc <- xmlTreeParse(system.file("exampleData", "mtcars.xml", package="XML")) xmlRoot(doc) # Note that we cannot use getSibling () on a regular R-level XMLNode object # since we cannot go back up or across the tree from that node, but # only down to the children. # Using an internal node via xmlParse (== xmlInternalTreeParse()) doc <- xmlParse(system.file("exampleData", "mtcars.xml", package="XML")) n = xmlRoot(doc, skip = FALSE) # skip over the DTD and the comment d = getSibling(getSibling(n)) } \keyword{file} XML/man/getXMLErrors.Rd0000644000175100001440000000264014316477364014350 0ustar hornikusers\name{getXMLErrors} \alias{getXMLErrors} \title{Get XML/HTML document parse errors} \description{ This function is intended to be a convenience for finding all the errors in an XML or HTML document due to being malformed, i.e. missing quotes on attributes, non-terminated elements/nodes, incorrectly terminated nodes, missing entities, etc. The document is parsed and a list of the errors is returned along with information about the file, line and column number. } \usage{ getXMLErrors(filename, parse = xmlParse, ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{filename}{ the identifier for the document to be parsed, one of a local file name, a URL or the XML/HTML content itself} \item{parse}{ the function to use to parse the document, usually either \code{\link{xmlTreeParse}} or \code{\link{htmlTreeParse}}. } \item{\dots}{additional arguments passed to the function given by \code{parse}} } \value{ A list of S3-style \code{XMLError} objects. } \references{libxml2 (\url{http://xmlsoft.org})} \author{Duncan Temple Lang} \seealso{ \code{error} argument for \code{\link{xmlTreeParse}} and related functions. } \examples{ # Get the "errors" in the HTML that was generated from this Rd file getXMLErrors(system.file("html", "getXMLErrors.html", package = "XML")) \dontrun{ getXMLErrors("https://www.omegahat.net/index.html") } } \keyword{IO} \keyword{programming} XML/man/xmlParent.Rd0000644000175100001440000000714114405636156013761 0ustar hornikusers\name{xmlParent} \alias{xmlParent} \alias{xmlAncestors} \alias{xmlParent.XMLInternalNode} \alias{xmlParent,XMLInternalNode-method} \alias{xmlParent,XMLHashTreeNode-method} \alias{xmlParent,XMLTreeNode-method} \title{Get parent node of XMLInternalNode or ancestor nodes} \description{ \code{xmlParent} operates on an XML node and returns a reference to its parent node within the document tree. This works for an internal, C-level \code{XMLInternalNode} object created, for examply, using \code{\link{newXMLNode}} and related functions or \code{\link{xmlTree}} or from \code{\link{xmlTreeParse}} with the \code{useInternalNodes} parameter. It is possible to find the parent of an R-level XML node when using a tree created with, for example, \code{\link{xmlHashTree}} as the parent information is stored separately. \code{xmlAncestors} walks the chain of parens to the top of the document and either returns a list of those nodes, or alternatively a list of the values obtained by applying a function to each of the nodes. } \usage{ xmlParent(x, ...) xmlAncestors(x, fun = NULL, ..., addFinalizer = NA, count = -1L) } \arguments{ \item{x}{an object of class \code{XMLInternalNode} whose parent is being requested. } \item{fun}{an R function which is invoked for each node as we walk up the tree.} \item{\dots}{any additional arguments that are passed in calls to \code{fun} after the node object and for \code{xmlParent} this allows methods to define their own additional parameters.} \item{addFinalizer}{a logical value indicating whether the default finalizer routine should be registered to free the internal xmlDoc when R no longer has a reference to this external pointer object. This can also be the name of a C routine or a reference to a C routine retrieved using \code{\link{getNativeSymbolInfo}}. } \item{count}{an integer that indicates how many levels of the hierarchy to traverse. This allows us to get the \code{count} most recent ancestors of the node.} } \details{ This uses the internal libxml structures to access the parent in the DOM tree. This function is generic so that we can add methods for other types of nodes if we so want in the future. } \value{ \code{xmlParent} returns object of class \code{XMLInternalNode}. If \code{fun} is \code{NULL}, \code{xmlAncestors} returns a list of the nodes in order of top-most node or root of the tree, then its child, then the child of that child, etc. This is the reverse order in which the nodes are visited/found. If \code{fun} is a function, \code{xmlAncestors} returns a list whose elements are the results of calling that function for each node. Again, the order is top down. } \references{\url{https://www.w3.org/XML/}} \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlChildren}} \code{\link{xmlTreeParse}} \code{\link{xmlNode}} } \examples{ top = newXMLNode("doc") s = newXMLNode("section", attr = c(title = "Introduction")) a = newXMLNode("article", s) addChildren(top, a) xmlName(xmlParent(s)) xmlName(xmlParent(xmlParent(s))) # Find the root node. root = a while(!is.null(xmlParent(root))) root = xmlParent(root) # find the names of the parent nodes of each 'h' node. # use a global variable to "simplify" things and not use a closure. filename = system.file("exampleData", "branch.xml", package = "XML") parentNames <- character() xmlParse(filename, handlers = list(h = function(x) { parentNames <<- c(parentNames, xmlName(xmlParent(x))) })) table(parentNames) } \keyword{file} \keyword{IO} XML/man/getChildrenStrings.Rd0000644000175100001440000000326613607633744015620 0ustar hornikusers\name{getChildrenStrings} \alias{getChildrenStrings} \title{Get the individual } \description{ This is different from \code{xmlValue} applied to the node. That concatenates all of the text in the child nodes (and their descendants) This is a faster version of \code{xmlSApply(node, xmlValue)} } \usage{ getChildrenStrings(node, encoding = getEncoding(node), asVector = TRUE, len = xmlSize(node), addNames = TRUE) } \arguments{ \item{node}{the parent node whose child nodes we want to process} \item{encoding}{the encoding to use for the text. This should come from the document itself. However, it can be useful to specify it if the encoding has not been set for the document (e.g. if we are constructing it node-by-node).} \item{asVector}{a logical value that controls whether the result is returned as a character vector or as a list (\code{FALSE}). } \item{len}{an integer giving the number of elements we expect returned. This is best left unspecified but can be provided if the caller already knows the number of child nodes. This avoids recomputing this and so provides a marginal speedup.} \item{addNames}{a logical value that controls whether we add the element names to each element of the resulting vector. This makes it easier to identify from which element each string came.} } \value{ A character vector. } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlValue}} } \examples{ doc = xmlParse("a string some text another") getChildrenStrings(xmlRoot(doc)) doc = xmlParse("a string some text anotherabcxyz") getChildrenStrings(xmlRoot(doc)) } \keyword{programming} XML/man/getXIncludes.Rd0000644000175100001440000000524614405636156014411 0ustar hornikusers\name{getXIncludes} \alias{getXIncludes} \alias{xmlXIncludes} \title{Find the documents that are XInclude'd in an XML document} \description{ The \code{getXMLIncludes} function finds the names of the documents that are XIncluded in a given XML document, optionally processing these documents recursively. \code{xmlXIncludes} returns the hierarchy of included documents. } \usage{ getXIncludes(filename, recursive = TRUE, skip = character(), omitPattern = "\\\\.(js|html?|txt|R|c)$", namespace = c(xi = "https://www.w3.org/2003/XInclude"), duplicated = TRUE) xmlXIncludes(filename, recursive = TRUE, omitPattern = "\\\\.(js|html?|txt|R|c)$", namespace = c(xi = "https://www.w3.org/2003/XInclude"), addNames = TRUE, clean = NULL, ignoreTextParse = FALSE) } \arguments{ \item{filename}{the name of the XML document's URL or file or the parsed document itself.} \item{recursive}{a logical value controlling whether to recursively process the XInclude'd files for their XInclude'd files} \item{skip}{a character vector of file names to ignore or skip over} \item{omitPattern}{a regular expression for indentifying files that are included that we do not want to recursively process} \item{namespace}{the namespace to use for the XInclude. There are two that are in use 2001 and 2003.} \item{duplicated}{a logical value that controls whether only the unique names of the files are returned, or if we get all references to all files.} \item{addNames}{a logical that controls whether we add the name of the parent file as the names vector for the collection of included file names. This is useful, but sometimes we want to disable this, e.g. to create a \code{JSON} representation of the hierarchy for use in, e.g., D3.} \item{clean}{how to process the names of the files. This can be a function or a character vector of two regular expressions passed to \code{gsub}. The function is called with a vector of file names. The regular expressions are used in a call to \code{gsub}.} \item{ignoreTextParse}{if \code{TRUE}, ignore the XIncluded files that are identified as text and not XML with \code{parse="text"}.} } \value{ If \code{recursive} is \code{FALSE}, a character vector giving the names of the included files. For \code{recursive} is \code{TRUE}, currently the same character vector form. However, this will be a hierarchical list. } \author{ Duncan Temple Lang } \seealso{ \code{\link{getHTMLExternalFiles}} } \examples{ f = system.file("exampleData", "xinclude", "a.xml", package = "XML") getXIncludes(f, recursive = FALSE) } \keyword{IO} \concept{XML} XML/man/xmlHandler.Rd0000644000175100001440000000212514316477364014107 0ustar hornikusers\name{xmlHandler} \alias{xmlHandler} \title{ Example XML Event Parser Handler Functions} \description{ A closure containing simple functions for the different types of events potentially called by the \link{xmlEventParse}, and some tag-specific functions to illustrate how one can add functions for specific DTDs and XML element types. Contains a local \link{list} which can be mutated by invocations of the closure's function. } \usage{ xmlHandler() } \value{ List containing the functions enumerated in the closure definition along with the \link{list}. } \author{Duncan Temple Lang} \note{This is just an example.} \seealso{\link{xmlEventParse}, \link{xmlTreeParse}} \examples{ \dontrun{ xmlURL <- "https://www.omegahat.net/Scripts/Data/mtcars.xml" xmlText <- paste(scan(xmlURL, what="", sep="\n"),"\n",collapse="\n") } xmlURL <- system.file("exampleData", "mtcars.xml", package="XML") xmlText <- paste(readLines(xmlURL), "\n", collapse="") xmlEventParse(xmlText, handlers = NULL, asText=TRUE) xmlEventParse(xmlText, xmlHandler(), useTagName=TRUE, asText=TRUE) } \keyword{file} \keyword{IO} XML/man/append.XMLNode.Rd0000644000175100001440000000427114405636156014524 0ustar hornikusers\name{append.xmlNode} \alias{append.xmlNode} \alias{append.XMLNode} \title{Add children to an XML node} \description{ This appends one or more XML nodes as children of an existing node. } \usage{ append.XMLNode(to, ...) append.xmlNode(to, ...) } \arguments{ \item{to}{the XML node to which the sub-nodes are to be added.} \item{\dots}{the sub-nodes which are to be added to the \code{to} node. If this is a \code{list} of \code{XMLNode} objects (e.g. create by a call to \code{\link{lapply}}), then that list is used.} } \details{ \code{append.xmlNode} is a generic function with method \code{append.XMLNode} for class \code{"XMLNode"} and default method \code{base::append}. This seems historical and users may as well use \code{append.XMLNode} directly. } \value{ The original \code{to} node containing its new children nodes. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{[<-.XMLNode}} \code{\link{[[<-.XMLNode}} \code{\link{[.XMLNode}} \code{\link{[[.XMLNode}} } \examples{ # Create a very simple representation of a simple dataset. # This is just an example. The result is # # # # A # # # B # # # # 1.2 3.5 # # # 20.2 13.9 # # # 10.1 5.67 # # n = xmlNode("data", attrs = c("numVars" = 2, numRecords = 3)) n = append.xmlNode(n, xmlNode("varNames", xmlNode("string", "A"), xmlNode("string", "B"))) n = append.xmlNode(n, xmlNode("record", "1.2 3.5")) n = append.xmlNode(n, xmlNode("record", "20.2 13.9")) n = append.xmlNode(n, xmlNode("record", "10.1 5.67")) print(n) \dontrun{ tmp <- lapply(references, function(i) { if(!inherits(i, "XMLNode")) i <- xmlNode("reference", i) i }) r <- xmlNode("references") r[["references"]] <- append.xmlNode(r[["references"]], tmp) } } \keyword{file} \keyword{IO} XML/man/asXMLTreeNode.Rd0000644000175100001440000000336014405636156014420 0ustar hornikusers\name{asXMLTreeNode} \alias{asXMLTreeNode} \title{Convert a regular XML node to one for use in a "flat" tree} \description{ This coerces a regular R-based XML node (i.e. not an internal C-level node) to a form that can be inserted into a flat tree, i.e. one that stores the nodes in a non-hierarchical manner. It is thus used in conjunction with \code{\link{xmlHashTree}} %% and \code{\link{xmlFlatListTree}}. It adds \code{id} and \code{env} fields to the node and specializes the class by prefixing \code{className} to the class attribute. This is not used very much anymore as we use the internal nodes for most purposes. } \usage{ asXMLTreeNode(node, env, id = get(".nodeIdGenerator", env)(xmlName(node)), className = "XMLTreeNode") } %- maybe also 'usage' for other objects documented here. \arguments{ \item{node}{the original XML node} \item{env}{the \code{XMLFlatTree} object into which this node will be inserted.} \item{id}{the identifier for the node in the flat tree. If this is not specified, we consult the tree itself and its built-in identifier generator. By default, the name of the node is used as its identifier unless there is another node with that name. } \item{className}{a vector of class names to be prefixed to the existing class vector of the node.} } \value{ An object of class \code{className}, i.e. by default \code{"XMLTreeNode"}. } \references{\url{https://www.w3.org/XML/}} \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlHashTree}} %% \code{\link{xmlFlatListTree}} } \examples{ txt = 'some textother text' doc = xmlTreeParse(txt) class(xmlRoot(doc)) as(xmlRoot(doc), "XMLInternalNode") } \keyword{IO} \concept{XML} XML/man/parseURI.Rd0000644000175100001440000000337414316477364013512 0ustar hornikusers\name{parseURI} \alias{parseURI} \alias{URI-class} \alias{coerce,URI,character-method} \title{Parse a URI string into its elements} \description{ This breaks a URI given as a string into its different elements such as protocol/scheme, host, port, file name, query. This information can be used, for example, when constructing URIs relative to a base URI. The return value is an S3-style object of class \code{URI}. This function uses libxml routines to perform the parsing. } \usage{ parseURI(uri) } \arguments{ \item{uri}{a single string} } \value{ A list with 8 elements \item{scheme}{the name of the protocol being used, http, ftp as a string.} \item{authority}{a string represeting a rarely used aspect of URIs} \item{server}{a string identifying the host, e.g. www.omegahat.net} \item{user}{a string giving the name of the user, e.g. in FTP "ftp://duncan@www.omegahat.net", this would yield "duncan"} \item{path}{a string identifying the path of the target file} \item{query}{the CGI query part of the string, e.g. the bit after '?' of the form \code{name=value&name=value}} \item{fragment}{a string giving the coo} \item{port}{an integer identifying the port number on which the connection is to be made} } \seealso{ \code{\link{getRelativeURL}} } \examples{\dontrun{ ## site is flaky parseURI("https://www.omegahat.net:8080/RCurl/index.html") parseURI("ftp://duncan@www.omegahat.net:8080/RCurl/index.html") parseURI("ftp://duncan@www.omegahat.net:8080/RCurl/index.html#my_anchor") as(parseURI("http://duncan@www.omegahat.net:8080/RCurl/index.html#my_anchor"), "character") as(parseURI("ftp://duncan@www.omegahat.net:8080/RCurl/index.html?foo=1&bar=axd"), "character") }} \keyword{IO} \concept{URI} \concept{Web} XML/man/xmlAttributeType.Rd0000644000175100001440000000203014405636156015325 0ustar hornikusers\name{xmlAttributeType} \alias{xmlAttributeType} \title{The type of an XML attribute for element from the DTD} \description{ This examines the definition of the attribute, usually returned by parsing the DTD with \code{\link{parseDTD}} and determines its type from the possible values: Fixed, string data, implied, required, an identifier, an identifier reference, a list of identifier references, an entity, a list of entities, a name, a list of names, an element of enumerated set, a notation entity. } \usage{ xmlAttributeType(def, defaultType=FALSE) } \arguments{ \item{def}{the attribute definition object, usually retrieved from the DTD via \code{\link{parseDTD}}.} \item{defaultType}{whether to return the default value if this attribute is defined as being a value from an enumerated set.} } \value{ A string identifying the type for the sspecified attributed. } \references{\url{https://www.w3.org/XML/}, \url{https://www.omegahat.net/RSXML/}} \author{Duncan Temple Lang} \seealso{ \code{\link{parseDTD}} } \keyword{file} XML/man/supportsExpat.Rd0000644000175100001440000000233514405636156014710 0ustar hornikusers\name{supportsExpat} \alias{supportsExpat} \alias{supportsLibxml} \title{ Determines which native XML parsers are being used.} \description{ Use of the Gnome libxml and Expat parsers is supported in this R/S XML package, but both need not be used when compiling the package. These functions determine whether each is available in the underlying native code. } \usage{ supportsExpat() supportsLibxml() } \details{ One might to use different parsers to test validity of a document in different ways and to get different error messages. Additionally, one parser may be more efficient than the other. These methods allow one to write code in such a way that one parser is preferred and is used if it is available, but the other is used if the first is not available. } \value{ Returns \code{TRUE} if the corresponding library has been linked into the package. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlEventParse}} } \examples{ # use Expat if possible, otherwise libxml fileName <- system.file("exampleData", "mtcars.xml", package="XML") xmlEventParse(fileName, useExpat = supportsExpat()) } \keyword{file} XML/man/length.XMLNode.Rd0000644000175100001440000000161114405636156014531 0ustar hornikusers\name{length.XMLNode} \alias{length.XMLNode} \title{Determine the number of children in an XMLNode object.} \description{ This function is a simple way to compute the number of sub-nodes (or children) an \code{XMLNode} object possesses. It is provided as a convenient form of calling the \code{\link{xmlSize}} function. } \usage{ \method{length}{XMLNode}(x) } \arguments{ \item{x}{the \code{XMLNode} object whose length is to be queried.} } \value{ An integer giving the number of sub-nodes of this node. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlSize}} \code{\link{xmlChildren}} } \examples{ doc <- xmlTreeParse(system.file("exampleData", "mtcars.xml", package="XML")) r <- xmlRoot(doc, skip=TRUE) length(r) # get the last entry r[[length(r)]] } \keyword{file} XML/man/dtdElementValidEntry.Rd0000644000175100001440000000347614405636156016105 0ustar hornikusers\name{dtdElementValidEntry} \alias{dtdElementValidEntry.character} \alias{dtdElementValidEntry.XMLElementContent} \alias{dtdElementValidEntry.XMLElementDef} \alias{dtdElementValidEntry.XMLOrContent} \alias{dtdElementValidEntry.XMLSequenceContent} \alias{dtdElementValidEntry} \title{Determines whether an XML element allows a particular type of sub-element.} \description{ This tests whether \code{name} is a legitimate tag to use as a direct sub-element of the \code{element} tag according to the definition of the \code{element} element in the specified DTD. This is a generic function that dispatches on the element type, so that different version take effect for \code{XMLSequenceContent}, \code{XMLOrContent}, \code{XMLElementContent}. } \usage{ dtdElementValidEntry(element, name, pos=NULL) } \arguments{ \item{element}{The \code{XMLElementDef} defining the tag in which we are asking whether the sub-element can be used. } \item{name}{The name of the sub-element about which we are querying the list of sub-tags within \code{element}. } \item{pos}{An optional argument which, if supplied, queries whether the \code{name} sub-element is valid as the \code{pos}-th child of \code{element}. } } \details{ This is not intended to be called directly, but indirectly by the \code{\link{dtdValidElement}} function. } \value{ Logical value indicating whether the sub-element can appear in an \code{element} tag or not. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{parseDTD}}, \code{\link{dtdValidElement}}, \code{\link{dtdElement}} } \examples{ dtdFile <- system.file("exampleData", "foo.dtd",package="XML") dtd <- parseDTD(dtdFile) dtdElementValidEntry(dtdElement("variables",dtd), "variable") } \keyword{file} XML/man/xmlSubset.Rd0000644000175100001440000000502514405636156013774 0ustar hornikusers\name{[.XMLNode} \alias{[.XMLNode} \alias{[[.XMLNode} \alias{[[.XMLInternalElementNode} \alias{[[.XMLDocumentContent} \title{Convenience accessors for the children of XMLNode objects.} \description{ These provide a simplified syntax for extracting the children of an XML node. } \usage{ \method{[}{XMLNode}(x, ..., all = FALSE) \method{[[}{XMLNode}(x, ...) \method{[[}{XMLDocumentContent}(x, ...) } \arguments{ \item{x}{the XML node or the top-level document content in which the children are to be accessed. The \code{XMLDocumentContent} is the container for the top-level node that also contains information such as the URI/filename and XML version. This accessor method is merely a convenience to get access to children of the top-level node.} % \item{i}{index of the child of interest or the name of an XML element % of interest. In this latter case, only the first matching element is % returned, if any.} \item{\dots}{the identifiers for the children to be retrieved, given as integer indices, names, etc. in the usual format for the generic \code{link{[}} and \code{link{[[}} operators} \item{all}{logical value. When \dots is a character vector, a value of \code{TRUE} for \code{all} means to retrieve all of the nodes with those names rather than just the first one. \code{FALSE} gives the usual result of subsetting a list by name which gives just the first element. This allows us to avoid the idiom \code{node[ names(node) == "bob" ]} which is complicated when node is the result of an inline computation and instead we use \code{node["bob", all = TRUE]}. } } \value{ A list or single element containing the children of the XML node given by \code{obj} and identified by \dots. } \references{\url{https://www.w3.org/XML/}, \url{https://www.omegahat.net/RSXML/}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlAttrs}} \code{\link{[<-.XMLNode}} \code{\link{[[<-.XMLNode}} } \examples{ f = system.file("exampleData", "gnumeric.xml", package = "XML") top = xmlRoot(xmlTreeParse(f)) # Get the first RowInfo element. top[["Sheets"]][[1]][["Rows"]][["RowInfo"]] # Get a list containing only the first row element top[["Sheets"]][[1]][["Rows"]]["RowInfo"] top[["Sheets"]][[1]][["Rows"]][1] # Get all of the RowInfo elements by position top[["Sheets"]][[1]][["Rows"]][1:xmlSize(top[["Sheets"]][[1]][["Rows"]])] # But more succinctly and accurately, get all of the RowInfo elements top[["Sheets"]][[1]][["Rows"]]["RowInfo", all = TRUE] } \keyword{IO} \keyword{file} XML/man/XMLAttributes-class.Rd0000644000175100001440000000262013607633730015614 0ustar hornikusers\name{XMLAttributes-class} \Rdversion{1.1} \docType{class} \alias{XMLAttributes-class} \alias{[,XMLAttributes-method} \alias{show,XMLAttributes-method} \title{Class \code{"XMLAttributes"}} \description{A simple class to represent a named character vector of XML attributes some of which may have a namespace. This maintains the name space} \section{Objects from the Class}{ Objects can be created by calls of the form \code{new("XMLAttributes", ...)}. These are typically generated via a call to \code{\link{xmlAttrs}}. } \section{Slots}{ \describe{ \item{\code{.Data}:}{Object of class \code{"character"}} } } \section{Extends}{ Class \code{"\linkS4class{character}"}, from data part. Class \code{"\linkS4class{vector}"}, by class "character", distance 2. Class \code{"\linkS4class{data.frameRowLabels}"}, by class "character", distance 2. Class \code{"\linkS4class{SuperClassMethod}"}, by class "character", distance 2. } \section{Methods}{ \describe{ \item{[}{\code{signature(x = "XMLAttributes")}: ... } \item{show}{\code{signature(object = "XMLAttributes")}: ... } } } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlAttrs}} \code{\link{newXMLNode}} \code{\link{xmlParse}} } \examples{ nn = newXMLNode("foo", attrs = c(a = "123", 'r:show' = "true"), namespaceDefinitions = c(r = "http://www.r-project.org")) a = xmlAttrs(nn) a["show"] } \keyword{classes} XML/man/XMLInternalDocument.Rd0000644000175100001440000000415414024143652015633 0ustar hornikusers\name{XMLInternalDocument-class} \docType{class} \alias{XMLAbstractDocument-class} %XXX put somewhere else. \alias{XMLInternalDocument-class} \alias{HTMLInternalDocument-class} \alias{coerce,XMLInternalNode,XMLInternalDocument-method} \alias{coerce,XMLInternalDocument,XMLInternalNode-method} \alias{coerce,XMLDocument,XMLInternalDocument-method} \title{Class to represent reference to C-level data structure for an XML document} \description{ This class is used to provide a handle/reference to a C-level data structure that contains the information from parsing parsing XML content. This leaves the nodes in the DOM or tree as C-level nodes rather than converting them to explicit R \code{XMLNode} objects. One can then operate on this tree in much the same way as one can the \code{XMLNode} representations, but we a) avoid copying the nodes to R, and b) can navigate the tree both down and up using \code{\link{xmlParent}} giving greater flexibility. Most importantly, one can use an \code{XMLInternalDocument} class object with an XPath expression to easily and relatively efficiently find nodes within a document that satisfy some criterion. See \code{\link{getNodeSet}}. } \section{Objects from the Class}{ Objects of this type are created via \code{\link{xmlTreeParse}} and \code{\link{htmlTreeParse}} with the argument \code{useInternalNodes} given as \code{TRUE}. } \section{Extends}{ Class \code{\linkS4class{oldClass}}, directly. } \section{Methods}{ There are methods to serialize (dump) a document to a file or as a string, and to coerce it to a node by finding the top-level node of the document. There are functions to search the document for nodes specified by an XPath expression. } \references{ XPath \url{https://www.w3.org/TR/xpath/} } \seealso{ \code{\link{xmlTreeParse}} \code{\link{htmlTreeParse}} \code{\link{getNodeSet}} } \examples{ f = system.file("exampleData", "mtcars.xml", package="XML") doc = xmlParse(f) getNodeSet(doc, "//variables[@count]") getNodeSet(doc, "//record") getNodeSet(doc, "//record[@id='Mazda RX4']") # free(doc) } \keyword{classes} XML/man/SAXMethods.Rd0000644000175100001440000000447314405636156013773 0ustar hornikusers\name{startElement.SAX} \alias{startElement.SAX} \alias{endElement.SAX} \alias{text.SAX} \alias{comment.SAX} \alias{processingInstruction.SAX} \alias{entityDeclaration.SAX} \alias{.InitSAXMethods} \alias{text.SAX,ANY,SAXState-method} \alias{comment.SAX,ANY,SAXState-method} \alias{endElement.SAX,ANY,SAXState-method} \alias{startElement.SAX,ANY,ANY,SAXState-method} \alias{processingInstruction.SAX,ANY,ANY,SAXState-method} \alias{entityDeclaration.SAX,ANY,ANY,ANY,ANY,ANY,SAXState-method} \title{Generic Methods for SAX callbacks} \description{ This is a collection of generic functions for which one can write methods so that they are called in repsonse to different SAX events. The idea is that one defines methods for different classes of the \code{.state} argument and dispatch to different methods based on that argument. The functions represent the different SAX events. } \usage{ startElement.SAX(name, atts, .state = NULL) endElement.SAX(name, .state = NULL) comment.SAX(content, .state = NULL) processingInstruction.SAX(target, content, .state = NULL) text.SAX(content, .state = NULL) entityDeclaration.SAX(name, base, sysId, publicId, notationName, .state = NULL) .InitSAXMethods(where = "package:XML") } %- maybe also `usage' for other objects documented here. \arguments{ \item{name}{the name of the XML element or entity being declared} \item{atts}{named character vector of XML attributes} \item{content}{the value/string in the processing instruction or comment} \item{target}{the target of the processing instruction, e.g. the R in \code{}} \item{base}{x} \item{sysId}{the system identifier for this entity} \item{publicId}{the public identifier for the entity} \item{notationName}{name of the notation specification} \item{.state}{the state object on which the user-defined methods should dispatch.} \item{where}{the package in which the class and method definitions should be defined. This is almost always unspecified.} } \value{ Each method should return the (potentially modified) state value. } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}} \author{Duncan Temple Lang} \note{ This no longer requires the Expat XML parser to be installed. Instead, we use libxml's SAX parser.} \seealso{ \code{\link{xmlEventParse}} } %\examples{} \keyword{file} XML/man/processXInclude.Rd0000644000175100001440000000375413607633744015132 0ustar hornikusers\name{processXInclude} \alias{processXInclude} \alias{processXInclude.list} \alias{processXInclude.XMLInternalDocument} \alias{processXInclude.XMLInternalElement} \title{Perform the XInclude substitutions} \description{ This function and its methods process the XInclude directives within the document of the form \code{ABCXYZ", "3.54available") doc = xmlParse(txt) code = makeClassTemplate(xmlRoot(doc)[[1]], types = c(cost = "numeric")) as(xmlRoot(doc)[["part"]], "part") } \keyword{programming} \concept{reflection} \concept{meta-programming} XML/man/AssignXMLNode.Rd0000644000175100001440000000252714405636156014425 0ustar hornikusers\name{[<-.XMLNode} \alias{[<-.XMLNode} \alias{[[<-.XMLNode} \title{Assign sub-nodes to an XML node} \description{ These functions allow one to assign a sub-node to an existing XML node by name or index. These are the assignment equivalents of the subsetting accessor functions. They are typically called indirectly via the assignment operator, such as \code{x[["myTag"]] <- xmlNode("mySubTag")}. } \usage{ \method{[}{XMLNode}(x, i) <- value \method{[}{XMLNode}(x, i) <- value \method{[[}{XMLNode}(x, i) <- value } \arguments{ \item{x}{the \code{XMLNode} object to which the sub-node is to be assigned.} \item{i}{the identifier for the position in the list of children of \code{x} into which the right-hand-side node(s) should be assigned. These can be either numbers or names.} \item{value}{one or more \code{XMLNode} objects which are to be the sub-nodes of \code{x}.} } \value{ The XML node \code{x} containing the new or modified nodes. } \references{\url{https://www.w3.org}, \url{https://www.omegahat.net/RSXML/}} \author{Duncan Templle Lang} \seealso{ \code{\link{[.XMLNode}} \code{\link{[[.XMLNode}} \code{\link{append.xmlNode}} \code{\link{xmlSize}} } \examples{ top <- xmlNode("top", xmlNode("next","Some text")) top[["second"]] <- xmlCDataNode("x <- 1:10") top[[3]] <- xmlNode("tag",attrs=c(id="name")) } \keyword{IO} \keyword{file} XML/man/xmlContainsEntity.Rd0000644000175100001440000000232414405636156015501 0ustar hornikusers\name{xmlContainsEntity} \alias{xmlContainsEntity} \alias{xmlContainsElement} \title{Checks if an entity is defined within a DTD.} \description{ A DTD contains entity and element definitions. These functions test whether a DTD contains a definition for a particular named element or entity. } \usage{ xmlContainsEntity(name, dtd) xmlContainsElement(name, dtd) } \arguments{ \item{name}{ The name of the element or entity being queried.} \item{dtd}{ The DTD in which to search for the entry.} } \details{ See \code{\link{parseDTD}} for more information about DTDs, entities and elements. } \value{ A logical value indicating whether the entry was found in the appropriate list of entitiy or element definitions. } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{parseDTD}}, \code{\link{dtdEntity}}, \code{\link{dtdElement}}, } \examples{ dtdFile <- system.file("exampleData", "foo.dtd", package="XML") foo.dtd <- parseDTD(dtdFile) # Look for entities. xmlContainsEntity("foo", foo.dtd) xmlContainsEntity("bar", foo.dtd) # Now look for an element xmlContainsElement("record", foo.dtd) } \keyword{file} XML/man/SAXState-class.Rd0000644000175100001440000000717214405636156014552 0ustar hornikusers\name{SAXState-class} \docType{class} \alias{SAXState-class} \title{A virtual base class defining methods for SAX parsing} \description{ This is a degenerate virtual class which others are expected to sub-class when they want to use S4 methods as handler functions for SAX-based XML parsing. The idea is that one can pass both i) a collection of handlers to \code{\link{xmlEventParse}} which are simply the generic functions for the different SAX actions, and ii) a suitable object to maintain state across the different SAX calls. This is used to perform the method dispatching to get the appropriate behavior for the action. Each of these methods is expected to return the updated state object and the SAX parser will pass this in the next callback. We define this class here so that we can provide default methods for each of the different handler actions. This allows other programmers to define new classes to maintain state that are sub-class of \code{SAXState} and then they do not have to implement methods for each of the different handlers. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Methods}{ \describe{ \item{comment.SAX}{\code{signature(content = "ANY", .state = "SAXState")}: ... } \item{endElement.SAX}{\code{signature(name = "ANY", .state = "SAXState")}: ... } \item{entityDeclaration.SAX}{\code{signature(name = "ANY", base = "ANY", sysId = "ANY", publicId = "ANY", notationName = "ANY", .state = "SAXState")}: ... } \item{processingInstruction.SAX}{\code{signature(target = "ANY", content = "ANY", .state = "SAXState")}: ... } \item{startElement.SAX}{\code{signature(name = "ANY", atts = "ANY", .state = "SAXState")}: ... } \item{text.SAX}{\code{signature(content = "ANY", .state = "SAXState")}: ... } } } \references{\url{https://www.w3.org/XML/}, \url{http://www.xmlsoft.org}} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlEventParse}} } \examples{ # For each element in the document, grab the node name # and increment the count in an vector for this name. # We define an S4 class named ElementNameCounter which # holds the vector of frequency counts for the node names. setClass("ElementNameCounter", representation(elements = "integer"), contains = "SAXState") # Define a method for handling the opening/start of any XML node # in the SAX streams. setMethod("startElement.SAX", c(.state = "ElementNameCounter"), function(name, atts, .state = NULL) { if(name \%in\% names(.state@elements)) .state@elements[name] = as.integer(.state@elements[name] + 1) else .state@elements[name] = as.integer(1) .state }) filename = system.file("exampleData", "eurofxref-hist.xml.gz", package = "XML") # Parse the file, arranging to have our startElement.SAX method invoked. z = xmlEventParse(filename, genericSAXHandlers(), state = new("ElementNameCounter"), addContext = FALSE) z@elements # Get the contents of all the comments in a character vector. setClass("MySAXState", representation(comments = "character"), contains = "SAXState") setMethod("comment.SAX", c(.state = "MySAXState"), function(content, .state = NULL) { cat("comment.SAX called for MySAXState\n") .state@comments <- c(.state@comments, content) .state }) filename = system.file("exampleData", "charts.svg", package = "XML") st = new("MySAXState") z = xmlEventParse(filename, genericSAXHandlers(useDotNames = TRUE), state = st) z@comments } \keyword{classes} XML/man/xmlAttrs.Rd0000644000175100001440000000573414405636156013633 0ustar hornikusers\name{xmlAttrs} \alias{xmlAttrs} \alias{xmlAttrs<-} \alias{xmlAttrs.XMLElementDef} \alias{xmlAttrs<-,XMLNode} \alias{xmlAttrs<-,XMLInternalNode} \alias{xmlAttrs<-,XMLNode-method} \alias{xmlAttrs<-,XMLInternalElementNode-method} \alias{xmlAttrs.XMLNode} \alias{xmlAttrs.XMLInternalNode} \title{ Get the list of attributes of an XML node. } \description{ This returns a named character vector giving the name-value pairs of attributes of an XMLNode object which is part of an XML document. } \usage{ xmlAttrs(node, ...) 'xmlAttrs<-'(node, append = TRUE, suppressNamespaceWarning = getOption("suppressXMLNamespaceWarning", FALSE), value) } \arguments{ \item{node}{The \code{XMLNode} object whose attributes are to be extracted. } \item{append}{a logical value indicating whether to add the attributes in \code{value} to the existing attributes within the XML node, or to replace the set of any existing attributes with this new set, i.e. remove the existing ones and then set the attributes with the contents of \code{value}.} \item{...}{additional arguments for the specific methods. For XML internal nodes, these are \code{addNamespacePrefix} and \code{addNamespaceURLs}. These are both logical values and indicate whether to prepend the name of the attribute with the namespace prefix and also whether to return the namespace prefix and URL as a vector in the \code{namespaces} attribute.} \item{value}{a named character vector giving the new attributes to be added to the node.} \item{suppressNamespaceWarning}{see \code{\link{addChildren}}} } \value{ A named character vector, where the names are the attribute names and the elements are the corresponding values. This corresponds to the (attr, "value") pairs in the XML tag \code{ ') xmlAttrs(xmlRoot(doc)[[1]], TRUE, TRUE) xmlAttrs(xmlRoot(doc)[[1]], FALSE, TRUE) xmlAttrs(xmlRoot(doc)[[1]], TRUE, FALSE) xmlAttrs(xmlRoot(doc)[[1]], FALSE, FALSE) } \keyword{IO} \keyword{file} XML/man/dtdValidElement.Rd0000644000175100001440000000347214405636156015057 0ustar hornikusers\name{dtdValidElement} \alias{dtdValidElement} \title{Determines whether an XML tag is valid within another.} \description{ This tests whether \code{name} is a legitimate tag to use as a direct sub-element of the \code{within} tag according to the definition of the \code{within} element in the specified DTD. } \usage{ dtdValidElement(name, within, dtd, pos=NULL) } \arguments{ \item{name}{The name of the tag which is to be inserted inside the \code{within} tag.} \item{within}{The name of the parent tag the definition of which we are checking to determine if it contains \code{name}.} \item{dtd}{The DTD in which the elements \code{name} and \code{within} are defined. } \item{pos}{ An optional position at which we might add the \code{name} element inside \code{within}. If this is specified, we have a stricter test that accounds for sequences in which elements must appear in order. These are comma-separated entries in the element definition.} } \details{ This applies to direct sub-elements or children of the \code{within} tag and not tags nested within children of that tag, i.e. descendants. } \value{ Returns a logical value. TRUE indicates that a \code{name} element can be used inside a \code{within} element. FALSE indicates that it cannot. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{parseDTD}}, \code{\link{dtdElement}}, \code{\link{dtdElementValidEntry}}, } \examples{ dtdFile <- system.file("exampleData", "foo.dtd", package="XML") foo.dtd <- parseDTD(dtdFile) # The following are true. dtdValidElement("variable","variables", dtd = foo.dtd) dtdValidElement("record","dataset", dtd = foo.dtd) # This is false. dtdValidElement("variable","dataset", dtd = foo.dtd) } \keyword{file} XML/man/parseDTD.Rd0000644000175100001440000001022114531615041013434 0ustar hornikusers\name{parseDTD} \alias{parseDTD} \title{Read a Document Type Definition (DTD)} \description{ Represents the contents of a DTD as a user-level object containing the element and entity definitions. } \usage{ parseDTD(extId, asText=FALSE, name="", isURL=FALSE, error = xmlErrorCumulator()) } \arguments{ \item{extId}{The name of the file containing the DTD to be processed.} \item{asText}{logical indicating whether the value of `extId' is the name of a file or the DTD content itself. Use this when the DTD is read as a character vector, before being parsed and handed to the parser as content only.} \item{name}{Optional name to provide to the parsing mechanism.} \item{isURL}{A logical value indicating whether the input source is to be considred a URL or a regular file or string containing the XML.} \item{error}{an R function that is called when an error is encountered. This can report it and continue or terminate by raising an error in R. See the error parameter for \code{link{xmlTreeParse}}.} } \details{ Parses and converts the contents of the DTD in the specified file into a user-level object containing all the information about the DTD. } \value{ A list with two entries, one for the entities and the other for the elements defined within the DTD. \item{entities}{a named list of the entities defined in the DTD. Each entry is indexed by the name of the corresponding entity. Each is an object of class \code{XMLEntity} or alternatively \code{XMLExternalEntity} if the entity refers to an external definition. The fields of these types of objects are \describe{ \item{name}{the name of the entity by which users refer to it.} \item{content}{the expanded value or definition of the entity} \item{original}{the value of the entity, but with references to other entities not expanded, but maintained in symbolic form.} } } \item{elements}{a named list of the elements defined in the DTD, with the name of each element being the identifier of the element being defined. Each entry is an object of class \code{XMLElementDef} which has 4 fields. \describe{ \item{name}{the name of the element.} \item{type}{a named integer indicating the type of entry in the DTD, usually either \code{element} or \code{mixed}. The name of the value is a user-level type. The value is used for programming, both internally and externally. } \item{contents}{a description of the elements that can be nested within this element. This is an object of class \code{XMLElementContent} or one of its specializations - \code{XMLSequenceContent}, \code{XMLOrContent}. Each of these encodes the number of such elements permitted (one, one or more, zero or one, or zero or more); the type indicating whether the contents consist of a single element type, an ordered sequence of elements, or one of a set of elements. Finally, the actual contents description is described in the \code{elements} field. This is a list of one or more \code{XMLElementContent}, \code{XMLSequenceContent} and \code{XMLOrContent} objects. } \item{attributes}{a named list of the attributes defined for this element in the DTD. Each element is of class \code{XMLAttributeDef} which has 4 fields. \describe{ \item{name}{name of the attribute, i.e. the left hand side} \item{type}{the type of the value, e.g. an CDATA, Id, Idref(s), Entity(s), NMToken(s), Enumeration, Notation} \item{defaultType}{the defined type, one of None, Implied, Fixed or Required.} \item{defaultValue}{the default value if it is specified, or the enumerated values as a character vector, if the type is Enumeration.} } } } } } \references{ \url{https://www.w3.org} } \author{Duncan Temple Lang } \note{Needs libxml (currently version 1.8.7)} \section{WARNING}{Errors in the DTD are stored as warnings for programmatic access.} \seealso{\code{\link{xmlTreeParse}}, WritingXML.html in the distribution.} \examples{ dtdFile <- system.file("exampleData", "foo.dtd",package="XML") parseDTD(dtdFile) txt <- readLines(dtdFile) txt <- paste(txt, collapse="\n") d <- parseDTD(txt, asText=TRUE) \dontrun{ url <- "https://www.omegahat.net/XML/DTDs/DatasetByRecord.dtd" d <- parseDTD(url, asText=FALSE) } } \keyword{file} \keyword{IO} XML/man/xmlCleanNamespaces.Rd0000644000175100001440000000266613607633744015564 0ustar hornikusers\name{xmlCleanNamespaces} \alias{xmlCleanNamespaces} \title{Remove redundant namespaces on an XML document} \description{ This is a convenience function that removes redundant repeated namespace definitions in an XML node. It removes namespace definitions in nodes where an ancestor node also has that definition. It does not remove unused namespace definitions. This uses the \code{NSCLEAN} option for \code{\link{xmlParse}} } \usage{ xmlCleanNamespaces(doc, options = integer(), out = docName(doc), ...) } \arguments{ \item{doc}{either the name of an XML documentor the XML content itself, or an already parsed document} \item{options}{options for the XML parser. \code{NSCLEAN} is added to this.} \item{\dots}{additional arguments passed to \code{\link{xmlParse}}} \item{out}{the name of a file to which to write the resulting XML document, or an empty character vector or logical value \code{FALSE} to avoid writing the new document. } } \value{ If the new document is written to a file, the name of the file is returned. Otherwise, the new parsed XML document is returned. } \references{ libxml2 documentation \url{http://xmlsoft.org/html/libxml-parser.html} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlParse}} } \examples{ f = system.file("exampleData", "redundantNS.xml", package = "XML") doc = xmlParse(f) print(doc) newDoc = xmlCleanNamespaces(f, out = FALSE) } \keyword{programming} \keyword{IO} XML/man/Doctype.Rd0000644000175100001440000000362214405636156013416 0ustar hornikusers\name{Doctype} \alias{Doctype} \alias{coerce,Doctype,character-method} \title{Constructor for DTD reference} \description{ This is a constructor for the \code{Doctype} class that can be provided at the top of an XML document to provide information about the class of document, i.e. its DTD or schema. Also, there is a method for converting such a \code{Doctype} object to a character string. } \usage{ Doctype(system = character(), public = character(), name = "") } \arguments{ \item{system}{the system URI that locates the DTD. } \item{public}{the identifier for locating the DTD in a catalog, for example. This should be a character vector of length 2, giving the public identifier and a URI. If just the public identifier is given and a string is given for \code{system} argument, the \code{system} value is used as the second element of \code{public}. The public identifer should be of the form \code{+//creator//name//language} where the first element is either + or -, and the language is described by a code in the ISO 639 document. } \item{name}{the name of the root element in the document. This should be the first parameter, but is left this way for backward compatability. And } } \value{ An object of class \code{Doctype}. } \references{\url{https://www.w3.org/XML/} XML Elements of Style, Simon St. Laurent. } \author{ Duncan Temple Lang } \seealso{ \code{\link{saveXML}} } \examples{ d = Doctype(name = "section", public = c("-//OASIS//DTD DocBook XML V4.2//EN", "http://oasis-open.org/docbook/xml/4.2/docbookx.dtd")) as(d, "character") # this call switches the system to the URI associated with the PUBLIC element. d = Doctype(name = "section", public = c("-//OASIS//DTD DocBook XML V4.2//EN"), system = "http://oasis-open.org/docbook/xml/4.2/docbookx.dtd") } \keyword{IO} XML/man/readKeyValueDB.Rd0000644000175100001440000000324413607633762014601 0ustar hornikusers\name{readKeyValueDB} \alias{readKeyValueDB} \alias{readKeyValueDB,character-method} \alias{readKeyValueDB,XMLInternalDocument-method} \alias{readKeyValueDB,XMLInternalNode-method} \alias{readKeyValueDB,AsIs-method} \title{Read an XML property-list style document} \description{ This function and its methods reads an XML document that is in the format of name-value or key-value pairs made up of a \code{plist} and \code{dict} nodes, each of which is made up \code{key}, and value node pairs. These used to be used for property lists on OS X and can represetn arbitrary data relatively conveniently. } \usage{ readKeyValueDB(doc, ...) } \arguments{ \item{doc}{the object containing the data. This can be the name of a file, a parsed XML document or an XML node.} \item{\dots}{additional parameters for the methods. One can pass \code{dropComments} as a logical value to control whether comment nodes are processed or ignored (\code{TRUE}). } } \value{ An R object representing the data read from the XML content. This is typically a named list or vector where the names are the keys and the values are collected into an R "container". } \references{ Property lists. } \author{ Duncan Temple Lang } \seealso{ \code{\link{readSolrDoc}}, \code{\link{xmlToList}}, \code{\link{xmlToDataFrame}}, \code{\link{xmlParse}} } \examples{ if(file.exists("/usr/share/hiutil/Stopwords.plist")) { o = readKeyValueDB("/usr/share/hiutil/Stopwords.plist") } if(file.exists("/usr/share/java/Tools/Applet Launcher.app/Contents/Info.plist")) javaInfo = readKeyValueDB('/usr/share/java/Tools/Applet Launcher.app/Contents/Info.plist') } \keyword{IO} \concept{XML} XML/man/addNode.Rd0000644000175100001440000000344214405636156013345 0ustar hornikusers\name{addNode} \alias{addNode} \alias{addNode.XMLHashTree} \title{Add a node to a tree} \description{ This generic function allows us to add a node to a tree for different types of trees. Currently it just works for XMLHashTree, but it could be readily extended to the more general XMLFlatTree class. However, the concept in this function is to change the tree and return the node. This does not work unless the tree is directly mutable without requiring reassignment, i.e. the changes do not induce a new copy of the original tree object. DOM trees which are lists of lists of lists do not fall into this category. } \usage{ addNode(node, parent, to, ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{node}{the node to be added as a child of the parent.} \item{parent}{the parent node or identifier} \item{to}{the tree object} \item{\dots}{additional arguments that are understood by the different methods for the different types of trees/nodes. These can include \code{attrs}, \code{namespace}, \code{namespaceDefinitions}, \code{.children}.} } \value{ The new node object. For flat trees, this will be the \code{node} after it has been coerced to be compatible with a flat tree, i.e. has an id and the host tree added to it. } \references{\url{https://www.w3.org} } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlHashTree}} \code{\link{asXMLTreeNode}} } \examples{ tt = xmlHashTree() top = addNode(xmlNode("top"), character(), tt) addNode(xmlNode("a"), top, tt) b = addNode(xmlNode("b"), top, tt) c = addNode(xmlNode("c"), b, tt) addNode(xmlNode("c"), top, tt) addNode(xmlNode("c"), b, tt) addNode(xmlTextNode("Some text"), c, tt) xmlElementsByTagName(tt$top, "c") tt } \keyword{IO} \concept{tree} XML/man/schema-class.Rd0000644000175100001440000000215213607633762014352 0ustar hornikusers\name{schema-class} \docType{class} \alias{ExternalReference-class} \alias{SchemaAttributeGroupTable-class} \alias{SchemaAttributeTable-class} \alias{SchemaElementTable-class} \alias{SchemaNotationTable-class} \alias{SchemaTypeTable-class} \alias{libxmlTypeTable-class} \alias{xmlSchemaAttributeGroupRef-class} \alias{xmlSchemaAttributeRef-class} \alias{xmlSchemaElementRef-class} \alias{xmlSchemaNotationRef-class} \alias{xmlSchemaRef-class} \alias{xmlSchemaTypeRef-class} \alias{names,xmlSchemaRef-method} \alias{$,xmlSchemaRef-method} \alias{names,libxmlTypeTable-method} \alias{$,libxmlTypeTable-method} \alias{$<-,libxmlTypeTable-method} \alias{coerce,libxmlTypeTable,list-method} \alias{show,XMLSchemaValidationResults-method} \title{Classes for working with XML Schema} \description{ These are classes used when working with XML schema and using them to validate a document or querying the schema for its elements. The basic representation is an external/native object stored in the \code{ref} slot. } %\section{Slots}{ \describe{}} %\section{Methods}{} \seealso{ \code{\link{xmlSchemaValidate}} } \keyword{classes} XML/man/xmlToS4.Rd0000644000175100001440000000251613607643020013311 0ustar hornikusers\name{xmlToS4} \alias{xmlToS4} \alias{xmlToS4,XMLInternalNode-method} \title{General mechanism for mapping an XML node to an S4 object} \description{ This generic function and its methods recursively process an XML node and its child nodes ( and theirs and so on) to map the nodes to S4 objects. This is the run-time function that corresponds to the \code{\link{makeClassTemplate}} function. } \usage{ xmlToS4(node, obj = new(xmlName(node)), ...) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{node}{the top-level XML node to convert to an S4 object} \item{obj}{the object whose slots are to be filled from the information in the XML node} \item{\dots}{additional parameters for methods} } \value{ The object \code{obj} whose slots have been modified. } \author{Duncan Temple Lang} \seealso{ \code{\link{makeClassTemplate}} } \examples{ txt = paste0("ABCXYZ', 3.54available") doc = xmlParse(txt) setClass("part", representation(name = "character", type = "character", cost = "numeric", status= "character")) xmlToS4(xmlRoot(doc)[["part"]]) } \keyword{programming} \keyword{IO} \concept{meta-computing} XML/man/ensureNamespace.Rd0000644000175100001440000000317213607633744015130 0ustar hornikusers\name{ensureNamespace} \alias{ensureNamespace} \title{Ensure that the node has a definition for particular XML namespaces} \description{ This function is a helper function for use in creating XML content. We often want to create a node that will be part of a larger XML tree and use a particular namespace for that node name. Rather than defining the namespace in each new node, we want to ensure that it is define on an ancestor node. This function aids in that task. We call the function with the ancestor node or top-level document and have it check whether the namespace is already defined or have it add it to the node and return. This is intended for use with \code{XMLInternalNode} objects which are direclty mutable (rather than changing a copy of the node and having to insert that back into the larger tree.) } \usage{ ensureNamespace(doc, what) } \arguments{ \item{doc}{an \code{XMLInternalDocument} or \code{XMLInternalNode} on which the namespace is to be defined. If this is a documentm, we use the root node.} \item{what}{a named character vector giving the URIs for the namespace definitions and the names giving the desired prefixes} } \value{ This is used for the potential side effects of modifying the XML node to add (some of) the namespaces as needed. } \references{XML namespaces} \author{Duncan Temple Lang} \seealso{ \code{\link{newXMLNamespace}} \code{\link{newXMLNode}} } \examples{ doc = newXMLDoc() top = newXMLNode("article", doc = doc) ensureNamespace(top, c(r = "http://www.r-project.org")) b = newXMLNode("r:code", parent = top) print(doc) } \keyword{IO} \concept{XML} XML/man/catalogResolve.Rd0000644000175100001440000000535414316477364014772 0ustar hornikusers\name{catalogResolve} \alias{catalogResolve} \title{Look up an element via the XML catalog mechanism} \description{ XML parsers use a catalog to map generic system and public addresses to actual local files or potentially different remote files. We can use a catalog to map a reference such as \code{https://www.omegahat.net/XSL/} to a particular directory on our local machine and then not have to modify any of the documents if we move the local files to another directory, e.g. install a new version in an alternate directory. This function provides a mechanism to query the catalog to resolve a URI, PUBLIC or SYSTEM identifier. This is now vectorized, so accepts a character vector of URIs and recycles \code{type} to have the same length. If an entry is not resolved via the catalog system, a \code{NA} is returned for that element. To leave the value unaltered in this case, use \code{asIs = TRUE} . } \usage{ catalogResolve(id, type = "uri", asIs = FALSE, debug = FALSE) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{id}{the name of the (generic) element to be resolved} \item{type}{a string, specifying whether the lookup is for a uri, system or public element} \item{asIs}{a logical. If \code{TRUE} any element of \code{id} which is not resolved by the catalog system will be left as given in the call. If \code{FALSE}, such unresolved elements are identified by \code{NA}. } \item{debug}{logical value indicating whether to turn on debugging output written to the console (\code{TRUE}) or not (\code{FALSE}).} } \value{ A character vector. If the element was resolved, the single element is the resolved value. Otherwise, the character vector will contain no elements. } \references{ \url{http://www.xmlsoft.org} \url{http://www.sagehill.net/docbookxsl/Catalogs.html} provides a short, succinct tutorial on catalogs. } \author{Duncan Temple Lang} \seealso{ \code{\link{xmlTreeParse}} } \examples{ if(!exists("Sys.setenv")) Sys.setenv = Sys.putenv Sys.setenv("XML_CATALOG_FILES" = system.file("exampleData", "catalog.xml", package = "XML")) catalogResolve("-//OASIS//DTD DocBook XML V4.4//EN", "public") catalogResolve("https://www.omegahat.net/XSL/foo.xsl") catalogResolve("https://www.omegahat.net/XSL/article.xsl", "uri") catalogResolve("https://www.omegahat.net/XSL/math.xsl", "uri") # This one does not resolve anything, returning an empty value. catalogResolve("http://www.oasis-open.org/docbook/xml/4.1.2/foo.xsl", "uri") # Vectorized and returns NA for the first and /tmp/html.xsl # for the second. catalogAdd("http://made.up.domain", "/tmp") catalogResolve(c("ddas", "http://made.up.domain/html.xsl"), asIs = TRUE) } \keyword{IO} \concept{XML} XML/man/asXMLNode.Rd0000644000175100001440000000215014405636156013574 0ustar hornikusers\name{asXMLNode} \alias{asXMLNode} \alias{coerce,XMLInternalNode,XMLNode-method} \title{Converts non-XML node objects to XMLTextNode objects} \description{ This function is used to convert S objects that are not already \code{XMLNode} objects into objects of that class. Specifically, it treats the object as a string and creates an \code{XMLTextNode} object. Also, there is a method for converting an XMLInternalNode - the C-level libxml representation of a node - to an explicit R-only object which contains the R values of the data in the internal node. } \usage{ asXMLNode(x) } \arguments{ \item{x}{the object to be converted to an \code{XMLNode} object. This is typically alread an object that inherits from \code{XMLNode} or a string.} } \value{ An object of class XMLNode. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlNode}} \code{\link{xmlTextNode}} } \examples{ # creates an XMLTextNode. asXMLNode("a text node") # unaltered. asXMLNode(xmlNode("p")) } \keyword{file} XML/man/parseXMLAndAdd.Rd0000644000175100001440000000641414316477364014545 0ustar hornikusers\name{parseXMLAndAdd} \alias{parseXMLAndAdd} \title{Parse XML content and add it to a node} \description{ This function parses the given XML content as a string by putting it inside a top-level node and then returns the document or adds the children to the specified parent. The motivation for this function is when we can use string manipulation to efficiently create the XML content by using vectorized operations in R, but then converting that content into parsed nodes. Generating XML/HTML content by glueing strings together is a poor approach. It is often convenient, but rarely good general software design. It makes for bad software that is not very extensible and difficult to maintain and enhance. Structure that it is programmatically accessible is much better. The tree approach provides this structure. Using strings is convenient and somewhat appropriate when done atomically for large amounts of highly regular content. But then the results should be converted to the structured tree so that they can be modified and extended. This function facilitates using strings and returning structured content. } \usage{ parseXMLAndAdd(txt, parent = NULL, top = "tmp", nsDefs = character()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{txt}{the XML content to parse} \item{parent}{an XMLInternalNode to which the top-level nodes in \code{txt} will be added as children} \item{top}{the name for the top-level node. If \code{parent} is specified, this is used but irrelevant.} \item{nsDefs}{a character vector of name = value pairs giving namespace definitions to be added to the top node.} } \value{ If \code{parent} is \code{NULL}, the root node of the parsed document is returned. This will be an element whose name is given by \code{top} unless the XML content in \code{txt} is AsIs or \code{code} is empty. If \code{parent} is non-\code{NULL}, . } \author{ Duncan Temple Lang } \seealso{ \code{\link{newXMLNode}} \code{\link{xmlParse}} \code{\link{addChildren}} } \examples{ long = runif(10000, -122, -80) lat = runif(10000, 25, 48) txt = sprintf("\%.3f,\%.3f,0", long, lat) f = newXMLNode("Folder") parseXMLAndAdd(txt, f) xmlSize(f) \dontrun{ # this version is much slower as i) we don't vectorize the # creation of the XML nodes, and ii) the parsing of the XML # as a string is very fast as it is done in C. f = newXMLNode("Folder") mapply(function(a, b) { newXMLNode("Placemark", newXMLNode("Point", newXMLNode("coordinates", paste(a, b, "0", collapse = ","))), parent = f) }, long, lat) xmlSize(f) o = c("dog", "cat") node = parseXMLAndAdd(o, nsDefs = c("http://cran.r-project.org", omg = "https://www.omegahat.net")) xmlNamespace(node[[1]]) xmlNamespace(node[[2]]) tt = newXMLNode("myTop") node = parseXMLAndAdd(o, tt, nsDefs = c("http://cran.r-project.org", omg = "https://www.omegahat.net")) tt } } \keyword{IO} XML/man/xmlGetAttr.Rd0000644000175100001440000000547714405636156014114 0ustar hornikusers\name{xmlGetAttr} \alias{xmlGetAttr} \title{Get the value of an attribute in an XML node} \description{ This is a convenience function that retrieves the value of a named attribute in an XML node, taking care of checking for its existence. It also allows the caller to provide a default value to use as the return value if the attribute is not present. } \usage{ xmlGetAttr(node, name, default = NULL, converter = NULL, namespaceDefinition = character(), addNamespace = length(grep(":", name)) > 0) } %- maybe also `usage' for other objects documented here. \arguments{ \item{node}{the XML node} \item{name}{the name of the attribute} \item{default}{a value to use as the default return if the attribute is not present in the XML node. } \item{converter}{an optional function which if supplied is invoked with the attribute value and the value returned. This can be used to convert the string to an arbitrary value which is useful if it is, for example, a number. This is only called if the attribute exists within the node. In other words, it is not applied to the \code{default} value.} \item{namespaceDefinition}{a named character vector giving name space prefixes and URIs to use when resolving for the the attribute with a namespace. The values are used to compare the name space prefix used in the \code{name} given by the user to the name space definition in the node to ensure they match. This is important as we might ask for an attribute named \code{r:width} assuming that the prefix \code{r} corresponded to the URI \code{http://www.r-project.org}. However, there may be a name space prefix \code{r} defined on the node that points to a different URI and so this would be an erroneous match. } \item{addNamespace}{a logical value that indicates whether we should put the namespace prefix on the resulting name. This is passed on to \code{\link{xmlAttrs}} and so controls whether the resulting attribute names have the prefix attached. So one specifies \code{TRUE} for this argument if the attribute identifier has a namespace prefix. } } \details{ This just checks that the attribute list is non-NULL and that there is an element with the specified name. } \value{ If the attribute is present, the return value is a string which is the value of the attribute. Otherwise, the value of \code{default} is returned. } \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlAttrs}} } \examples{ node <- xmlNode("foo", attrs=c(a="1", b="my name")) xmlGetAttr(node, "a") xmlGetAttr(node, "doesn't exist", "My own default value") xmlGetAttr(node, "b", "Just in case") } \keyword{file} XML/man/readHTMLTable.Rd0000644000175100001440000001727414316477364014374 0ustar hornikusers\name{readHTMLTable} \alias{readHTMLTable} \alias{readHTMLTable,character-method} \alias{readHTMLTable,HTMLInternalDocument-method} \alias{readHTMLTable,XMLInternalElementNode-method} \alias{coerce,character,FormattedInteger-method} \alias{coerce,character,FormattedNumber-method} \alias{coerce,character,Percent-method} \alias{coerce,character,Currency-method} \alias{FormattedInteger-class} \alias{FormattedNumber-class} \alias{Percent-class} \title{Read data from one or more HTML tables} \description{ This function and its methods provide somewhat robust methods for extracting data from HTML tables in an HTML document. One can read all the tables in a document given by filename or (\code{http:} or \code{ftp:}) URL, or having already parsed the document via \code{\link{htmlParse}}. Alternatively, one can specify an individual \code{

    } node in the document. The methods attempt to do some heuristic computations to determine the header labels for the columns, the name of the table, etc. } % xmlName(node) == "table" && ("thead" \%in\% names(node) || length(getNodeSet(node, "./tr[1]/th")) > 0) \usage{ readHTMLTable(doc, header = NA, colClasses = NULL, skip.rows = integer(), trim = TRUE, elFun = xmlValue, as.data.frame = TRUE, which = integer(), ...) } \arguments{ \item{doc}{the HTML document which can be a file name or a URL or an already parsed \code{HTMLInternalDocument}, or an HTML node of class \code{XMLInternalElementNode}, or a character vector containing the HTML content to parse and process.} \item{header}{either a logical value indicating whether the table has column labels, e.g. the first row or a \code{thead}, or alternatively a character vector giving the names to use for the resulting columns. This can be a logical vector and the individual values will be used in turn for the different tables. This allows the caller to control whether individual tables are processed as having column names. Alternatively, one can read a specific table via the \code{which} parameter and control how that is processed with a single scalar logical. } \item{colClasses}{either a list or a vector that gives the names of the data types for the different columns in the table, or alternatively a function used to convert the string values to the appropriate type. A value of \code{NULL} means that we should drop that column from the result. Note that currently the conversion occurs before the vectors are converted to a data frame (if \code{as.data.frame} is \code{TRUE}). As a result, to ensure that character vectors remain as characters and not factors, use \code{stringsAsFactors = FALSE}. This typically applies only to an individual table and so for the method applied to a \code{XMLInternalElementNode} object. In addition to the usual "integer", "numeric", "logical", "character", etc. names of R data types, one can use "FormattedInteger", "FormattedNumber" and "Percent" to specify that format of the values are numbers possibly with commas (,) separating groups of digits or a number followed by a percent sign (\%). This mechanism allows one to introduce new classes and specify these as targets in \code{colClasses}. } \item{skip.rows}{an integer vector indicating which rows to ignore.} \item{trim}{a logical value indicating whether to remove leading and trailing white space from the content cells.} \item{elFun}{a function which, if specified, is called when converting each cell. Currently, only the node is specified. In the future, we might additionally pass the index of the column so that the function has some context, e.g. whether the value is a row label or a regular value, or if the caller knows the type of columns. } \item{as.data.frame}{a logical value indicating whether to turn the resluting table(s) into data frames or leave them as matrices. } \item{which}{an integer vector identifying which tables to return from within the document. This applies to the method for the document, not individual tables.} \item{\dots}{currently additional parameters that are passed on to \code{\link{as.data.frame}} if \code{as.data.frame} is \code{TRUE}. We may change this to use these as additional arguments for calls to \code{elFun}.} } \value{ If the document (either by name or parsed tree) is specified, the return vale is a list of data frames or matrices. If a single HTML node is provided } \references{ HTML4.0 specification } \author{Duncan Temple Lang} \seealso{ \code{\link{htmlParse}} \code{\link{getNodeSet}} \code{\link{xpathSApply}} } \examples{ \dontrun{ ## This changed to using https: in June 2015, and that is unsupported. # u = "http://en.wikipedia.org/wiki/World_population" u = "https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population" tables = readHTMLTable(u) names(tables) tables[[2]] # Print the table. Note that the values are all characters # not numbers. Also the column names have a preceding X since # R doesn't allow the variable names to start with digits. tmp = tables[[2]] # Let's just read the second table directly by itself. doc = htmlParse(u) tableNodes = getNodeSet(doc, "//table") tb = readHTMLTable(tableNodes[[2]]) # Let's try to adapt the values on the fly. # We'll create a function that turns a th/td node into a val tryAsInteger = function(node) { val = xmlValue(node) ans = as.integer(gsub(",", "", val)) if(is.na(ans)) val else ans } tb = readHTMLTable(tableNodes[[2]], elFun = tryAsInteger) tb = readHTMLTable(tableNodes[[2]], elFun = tryAsInteger, colClasses = c("character", rep("integer", 9))) } zz = readHTMLTable("https://www.inflationdata.com/Inflation/Consumer_Price_Index/HistoricalCPI.aspx") if(any(i <- sapply(zz, function(x) if(is.null(x)) 0 else ncol(x)) == 14)) { # guard against the structure of the page changing. zz = zz[[which(i)[1]]] # 4th table # convert columns to numeric. Could use colClasses in the call to readHTMLTable() zz[-1] = lapply(zz[-1], function(x) as.numeric(gsub(".* ", "", as.character(x)))) matplot(1:12, t(zz[-c(1, 14)]), type = "l") } # From Marsh Feldman on R-help, possibly # https://stat.ethz.ch/pipermail/r-help/2010-March/232586.html # That site was non-responsive in June 2015, # and this does not do a good job on the current table. \dontrun{ doc <- "http://www.nber.org/cycles/cyclesmain.html" # The main table is the second one because it's embedded in the page table. tables <- getNodeSet(htmlParse(doc), "//table") xt <- readHTMLTable(tables[[2]], header = c("peak","trough","contraction", "expansion","trough2trough","peak2peak"), colClasses = c("character","character","character", "character","character","character"), trim = TRUE, stringsAsFactors = FALSE ) } if(FALSE) { # Here is a totally different way of reading tables from HTML documents. # The data are formatted using PRE and so can be read via read.table u = "http://tidesonline.nos.noaa.gov/data_read.shtml?station_info=9414290+San+Francisco,+CA" h = htmlParse(u) p = getNodeSet(h, "//pre") con = textConnection(xmlValue(p[[2]])) tides = read.table(con) } \dontrun{ ## This is not accessible without authentication ... u = "https://www.omegahat.net/RCurl/testPassword/table.html" if(require(RCurl) && url.exists(u)) { tt = getURL(u, userpwd = "bob:duncantl") readHTMLTable(tt) }} } \keyword{IO} \keyword{data} XML/man/xmlSerializeHook.Rd0000644000175100001440000000405113700532410015256 0ustar hornikusers\name{xmlSerializeHook} \alias{xmlSerializeHook} \alias{xmlDeserializeHook} \title{Functions that help serialize and deserialize XML internal objects} \description{ These functions can be used to control how the C-level data structures associated with XML documents, nodes, XPath queries, etc. are serialized to a a file or connection and deserialized back into an R session. Since these C-level data structures are represented in R as external pointers, they would normally be serialized and deserialized in a way that loses all the information about the contents of the memory being referenced. \code{xmlSerializeHook} arranges to serialize these pointers by saving the corresponding XML content as a string and also the class of the object. The deserialize function converts such objects back to their original form. These functions are used in calls to \code{\link{saveRDS}} and \code{\link{readRDS}} via the \code{refhook} argument. \code{ saveRDS(obj, filename, refhook = xmlSerializeHook) readRDS(filename, refhook = xmlDeserializeHook) } } \usage{ xmlSerializeHook(x) xmlDeserializeHook(x) } \arguments{ \item{x}{the object to be deserialized, and the character vector to be deserialized.} } \value{ \code{xmlSerializeHook} returns a character version of the XML document or node, along with the basic class. If it is called with an object that is not an native/internal XML object, it returns \code{NULL} \code{xmlDeserializeHook} returns the parsed XML object, either a document or a node. } \references{ The R Internals Manual. } \author{ Duncan Temple Lang } \seealso{ \code{\link{saveRDS}} and \code{\link{readRDS}} } \examples{ z = newXMLNode("foo") f = system.file("exampleData", "tides.xml", package = "XML") doc = xmlParse(f) hdoc = as(doc, "XMLHashTree") nodes = getNodeSet(doc, "//pred") ff <- file.path(tempdir(), "tmp.rda") saveRDS(list(a = 1:10, z = z, doc = doc, hdoc = hdoc, nodes = nodes), ff, refhook = xmlSerializeHook) v = readRDS(ff, refhook = xmlDeserializeHook) unlink(ff) } \keyword{IO} XML/man/xmlNamespaceDefinitions.Rd0000644000175100001440000001006714405636156016621 0ustar hornikusers\name{xmlNamespaceDefinitions} \alias{xmlNamespaceDefinitions} \alias{getDefaultNamespace} \alias{xmlNamespaces} \alias{xmlNamespaces<-} \alias{xmlNamespaces<-,XMLInternalNode-method} \alias{xmlNamespaces<-,XMLNode-method} \alias{coerce,NULL,XMLNamespaceDefinitions-method} \alias{coerce,XMLNamespace,character-method} \alias{coerce,XMLNamespaceDefinition,character-method} \alias{coerce,XMLNamespaceDefinitions,character-method} \alias{coerce,character,XMLNamespaceDefinitions-method} \title{Get definitions of any namespaces defined in this XML node} \description{ If the given node has any namespace definitions declared within it, i.e. of the form \code{xmlns:myNamespace="http://www.myNS.org"}, \code{xmlNamespaceDefinitions} provides access to these definitions. While they appear in the XML node in the document as attributes, they are treated differently by the parser and so do not show up in the nodes attributes via \code{\link{xmlAttrs}}. \code{getDefaultNamespace} is used to get the default namespace for the top-level node in a document. The \code{recursive} parameter allows one to conveniently find all the namespace definitions in a document or sub-tree without having to examine the file. This can be useful when working with XPath queries via \code{\link{getNodeSet}}. } \usage{ xmlNamespaceDefinitions(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) xmlNamespaces(x, addNames = TRUE, recursive = FALSE, simplify = FALSE, ...) getDefaultNamespace(doc, ns = xmlNamespaceDefinitions(doc, simplify = simplify), simplify = FALSE) } \arguments{ \item{x}{the \code{XMLNode} object in which to find any namespace definitions} \item{addNames}{a logical indicating whether to compute the names for the elements in the resulting list. The names are convenient, but one can avoid the (very small) overhead of computing these with this parameter.} \item{doc}{the XMLInternalDocument object obtained from a call to \code{\link{xmlParse}} } \item{recursive}{a logical value indicating whether to extract the namespace definitions for just this node (\code{FALSE}) or all of the descendant nodes as well (\code{TRUE}). If this is \code{TRUE}, all the namespace definitions are collected into a single "flat" list and so there may be duplicate names. } \item{simplify}{a logical value. If this is \code{TRUE}, a character vector of prefix-URI pairs is returned. This can be used directly in calls to functions such as \code{\link{xpathApply}} and \code{\link{getNodeSet}}. The default value of \code{FALSE} returns a list of name space definitions which also identify whether the definition is local to the particular node or inherited from an ancestor. } \item{ns}{the collection of namespaces. This is typically omitted but can be specified if it has been computed in an earlier step.} \item{\dots}{additional parameters for methods} } \value{ A list with as many elements as there are namespace definitions. Each element is an object of class XMLNameSpace, containing fields giving the local identifier, the associated defining URI and a logical value indicating whether the definition is local to this node. The name of each element is the prefix or alias used for that namespace definition, i.e. the value of the \code{id} field in the namespace definition. For default namespaces, i.e. those that have no prefix/alias, the name is \code{""}. } \references{\url{https://www.w3.org/XML/}} \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlTreeParse}} \code{\link{xmlAttrs}} \code{\link{xmlGetAttr}} } \examples{ f = system.file("exampleData", "longitudinalData.xml", package = "XML") n = xmlRoot(xmlTreeParse(f)) xmlNamespaceDefinitions(n) xmlNamespaceDefinitions(n, recursive = TRUE) # Now using internal nodes. f = system.file("exampleData", "namespaces.xml", package = "XML") doc = xmlInternalTreeParse(f) n = xmlRoot(doc) xmlNamespaceDefinitions(n) xmlNamespaceDefinitions(n, recursive = TRUE) } \keyword{IO} \concept{XML} XML/man/dtdElement.Rd0000644000175100001440000000374614405636156014103 0ustar hornikusers\name{dtdElement} \alias{dtdElement} \alias{dtdEntity} \title{Gets the definition of an element or entity from a DTD.} \description{ A DTD in R consists of both element and entity definitions. These two functions provide simple access to individual elements of these two lists, using the name of the element or entity. The DTD is provided to determine where to look for the entry. } \usage{ dtdElement(name,dtd) dtdEntity(name,dtd) } \arguments{ \item{name}{The name of the element being retrieved/acessed.} \item{dtd}{The DTD from which the element is to be retrieved.} } \details{ An element within a DTD contains both the list of sub-elements it can contain and a list of attributes that can be used within this tag type. \code{dtdElement} retrieves the element by name from the specified DTD definition. Entities within a DTD are like macros or text substitutes used within a DTD and/or XML documents that use it. Each consists of a name/label and a definition, the text that is substituted when the entity is referenced. \code{dtdEntity} retrieves the entity definition from the DTD. \\ One can read a DTD directly (using \code{\link{parseDTD}}) or implicitly when reading a document (using \code{\link{xmlTreeParse}}) The names of all available elements can be obtained from the expression \code{names(dtd$elements)}. This function is simply a convenience for indexing this \code{elements} list. } \value{ An object of class \code{XMLElementDef}. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{parseDTD}}, \code{\link{dtdValidElement}} } \examples{ dtdFile <- system.file("exampleData","foo.dtd", package="XML") foo.dtd <- parseDTD(dtdFile) # Get the definition of the `entry1' element tmp <- dtdElement("variable", foo.dtd) xmlAttrs(tmp) tmp <- dtdElement("entry1", foo.dtd) # Get the definition of the `img' entity dtdEntity("img", foo.dtd) } \keyword{file} XML/man/findXInclude.Rd0000644000175100001440000000437613607633730014370 0ustar hornikusers\name{findXInclude} \alias{findXInclude} %- Also NEED an '\alias' for EACH other topic documented here. \title{Find the XInclude node associated with an XML node} \description{ This function is used to traverse the ancestors of an internal XML node to find the associated XInclude node that identifies it as being an XInclude'd node. Each top-level node that results from an include href=... in the libxml2 parser is sandwiched between nodes of class XMLXIncludeStartNode and XMLXIncludeStartNode. These are the sibling nodes. Another approach to finding the origin of the XInclude for a given node is to search for an attribute xml:base. This only works if the document being XInclude'd is in a different directory than the base document. If this is the case, we can use an XPath query to find the node containing the attribute via \code{"./ancestor::*[@xml:base]"}. } \usage{ findXInclude(x, asNode = FALSE, recursive = FALSE) } \arguments{ \item{x}{the node whose XInclude "ancestor" is to be found} \item{asNode}{a logical value indicating whether to return the node itself or the attributes of the node which are typically the immediately interesting aspect of the node.} \item{recursive}{a logical value that controls whether the full path of the nested includes is returned or just the path in the immediate XInclude element.} } \value{ Either \code{NULL} if there was no node of class XMLXIncludeStartNode found. Otherwise, if \code{asNode} is \code{TRUE}, that XMLXIncludeStartNode node is returned, or alternatively its attribute character vector. } \references{www.libxml.org} \author{Duncan Temple Lang} \seealso{ \code{\link{xmlParse}} and the \code{xinclude} parameter. } \examples{ f = system.file("exampleData", "functionTemplate.xml", package = "XML") cat(readLines(f), "\n") doc = xmlParse(f) # Get all the para nodes # We just want to look at the 2nd and 3rd which are repeats of the # first one. a = getNodeSet(doc, "//author") findXInclude(a[[1]]) i = findXInclude(a[[1]], TRUE) top = getSibling(i) # Determine the top-level included nodes tmp = getSibling(i) nodes = list() while(!inherits(tmp, "XMLXIncludeEndNode")) { nodes = c(nodes, tmp) tmp = getSibling(tmp) } } \keyword{IO} XML/man/xmlDOMApply.Rd0000644000175100001440000000430514405636156014154 0ustar hornikusers\name{xmlDOMApply} \alias{xmlDOMApply} \title{Apply function to nodes in an XML tree/DOM.} \description{ This recursively applies the specified function to each node in an XML tree, creating a new tree, parallel to the original input tree. Each element in the new tree is the return value obtained from invoking the specified function on the corresponding element of the original tree. The order in which the function is recursively applied is "bottom-up". In other words, function is first applied to each of the children nodes first and then to the parent node containing the newly computed results for the children. } \usage{ xmlDOMApply(dom, func) } \arguments{ \item{dom}{a node in the XML tree or DOM on which to recursively apply the given function. This should not be the \code{XMLDocument} itself returned from \code{\link{xmlTreeParse}} but an object of class \code{XMLNode}. This is typically obtained by calling \code{\link{xmlRoot}} on the return value from \code{\link{xmlTreeParse}}. } \item{func}{ the function to be applied to each node in the XML tree. This is passed the node object for the and the return value is inserted into the new tree that is to be returned in the corresponding position as the node being processed. If the return value is \code{NULL}, this node is dropped from the tree.} } \details{ This is a native (C code) implementation that understands the structure of an XML DOM returned from \code{\link{xmlTreeParse}} and iterates over the nodes in that tree. } \value{ A tree that parallels the structure in the \code{dom} object passed to it. } \author{Duncan Temple Lang} \references{\url{https://www.w3.org/XML//}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \seealso{\link{xmlTreeParse}} \examples{ dom <- xmlTreeParse(system.file("exampleData","mtcars.xml", package="XML")) tagNames <- function() { tags <- character(0) add <- function(x) { if(inherits(x, "XMLNode")) { if(is.na(match(xmlName(x), tags))) tags <<- c(tags, xmlName(x)) } NULL } return(list(add=add, tagNames = function() {return(tags)})) } h <- tagNames() xmlDOMApply(xmlRoot(dom), h$add) h$tagNames() } \keyword{file} XML/man/xmlValue.Rd0000644000175100001440000000445114405636156013605 0ustar hornikusers\name{xmlValue} \alias{xmlValue} \alias{xmlValue.XMLCDataNode} \alias{xmlValue.XMLNode} \alias{xmlValue.XMLProcessingInstruction} \alias{xmlValue.XMLTextNode} \alias{xmlValue.XMLComment} \alias{xmlValue<-} \alias{xmlValue<-,XMLAbstractNode-method} \alias{xmlValue<-,XMLInternalTextNode-method} \alias{xmlValue<-,XMLTextNode-method} \alias{coerce,XMLInternalTextNode,character-method} \title{Extract or set the contents of a leaf XML node} \description{ Some types of XML nodes have no children nodes, but are leaf nodes and simply contain text. Examples are \code{XMLTextMode}, \code{XMLProcessingInstruction}. This function provides access to their raw contents. This has been extended to operate recursivel on arbitrary XML nodes that contain a single text node. } \usage{ xmlValue(x, ignoreComments = FALSE, recursive = TRUE, encoding = getEncoding(x), trim = FALSE) } \arguments{ \item{x}{the \code{XMLNode} object whose contents are to be returned.} \item{ignoreComments}{a logical value which, if \code{TRUE} does not include the text in XML comment nodes. If this is \code{FALSE}, the text in the comments is part of the return value. } \item{recursive}{a logical value indicating whether to process all sub-nodes (\code{TRUE}) or only the text nodes within the node \code{x}. } %XXX \item{encoding}{experimental functionality and parameter related to encoding.} \item{trim}{a logical value controlling whether we remove leading or trailing white space when returning the string value} } \value{ The object stored in the \code{value} slot of the \code{XMLNode} object. This is typically a string. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlChildren}} \code{\link{xmlName}} \code{\link{xmlAttrs}} \code{\link{xmlNamespace}} } \examples{ node <- xmlNode("foo", "Some text") xmlValue(node) xmlValue(xmlTextNode("some more raw text")) # Setting the xmlValue(). a = newXMLNode("a") xmlValue(a) = "the text" xmlValue(a) = "different text" a = newXMLNode("x", "bob") xmlValue(a) = "joe" b = xmlNode("bob") xmlValue(b) = "Foo" xmlValue(b) = "again" b = newXMLNode("bob", "some text") xmlValue(b[[1]]) = "change" b } \keyword{file} XML/man/genericSAXHandlers.Rd0000644000175100001440000000407714405636156015465 0ustar hornikusers\name{genericSAXHandlers} \alias{genericSAXHandlers} \title{SAX generic callback handler list} \description{ This is a convenience function to get the collection of generic functions that make up the callbacks for the SAX parser. The return value can be used directly as the value of the \code{handlers} argument in \code{\link{xmlEventParse}}. One can easily specify a subset of the handlers by giving the names of the elements to include or exclude. } \usage{ genericSAXHandlers(include, exclude, useDotNames = FALSE) } %- maybe also `usage' for other objects documented here. \arguments{ \item{include}{if supplied, this gives the names of the subset of elements to return. } \item{exclude}{if supplied (and \code{include} is not), this gives the names of the elements to remove from the list of functions. } \item{useDotNames}{ a logical value. If this is \code{TRUE}, the names of the elements in the list of handler functions are prefixed with '.'. This is the newer format used to differentiate general element handlers and node-name-specific handlers.} } \value{ A list of functions. By default, the elements are named startElement, endElement, comment, text, processingInstruction, entityDeclaration and contain the corresponding generic SAX callback function, i.e. given by the element name with the .SAX suffix. If \code{include} or \code{exclude} is specified, a subset of this list is returned. } \references{\url{https://www.w3.org/XML/}, \url{http://www.jclark.com/xml/}, \url{https://www.omegahat.net} } \author{ Duncan Temple Lang } \seealso{ \code{\link{xmlEventParse}} \code{\link{startElement.SAX}} \code{\link{endElement.SAX}} \code{\link{comment.SAX}} \code{\link{processingInstruction.SAX}} \code{\link{entityDeclaration.SAX}} \code{\link{.InitSAXMethods}} } \examples{ \testonly{ # .InitSAXMethods() names(genericSAXHandlers()) names(genericSAXHandlers(inc=c("startElement", "endElement", "text"))) names(genericSAXHandlers(ex=c("startElement", "endElement", "text"))) } } \keyword{file} XML/DESCRIPTION0000644000175100001440000000405514636540175012455 0ustar hornikusersPackage: XML Version: 3.99-0.17 Authors@R: c(person("CRAN Team", role = c('ctb', 'cre'), email = "CRAN@r-project.org", comment = "de facto maintainer since 2013"), person("Duncan", "Temple Lang", role = c("aut"), email = "duncan@r-project.org", comment = c(ORCID = "0000-0003-0159-1546")), person("Tomas", "Kalibera", role = "ctb")) Title: Tools for Parsing and Generating XML Within R and S-Plus Depends: R (>= 4.0.0), methods, utils Suggests: bitops, RCurl SystemRequirements: libxml2 (>= 2.6.3) Description: Many approaches for both reading and creating XML (and HTML) documents (including DTDs), both local and accessible via HTTP or FTP. Also offers access to an 'XPath' "interpreter". URL: https://www.omegahat.net/RSXML/ License: BSD_3_clause + file LICENSE Collate: AAA.R DTD.R DTDClasses.R DTDRef.R SAXMethods.R XMLClasses.R applyDOM.R assignChild.R catalog.R createNode.R dynSupports.R error.R flatTree.R nodeAccessors.R parseDTD.R schema.R summary.R tangle.R toString.R tree.R version.R xmlErrorEnums.R xmlEventHandler.R xmlEventParse.R xmlHandler.R xmlInternalSource.R xmlOutputDOM.R xmlNodes.R xmlOutputBuffer.R xmlTree.R xmlTreeParse.R htmlParse.R hashTree.R zzz.R supports.R parser.R libxmlFeatures.R xmlString.R saveXML.R namespaces.R readHTMLTable.R reflection.R xmlToDataFrame.R bitList.R compare.R encoding.R fixNS.R xmlRoot.R serialize.R xmlMemoryMgmt.R keyValueDB.R solrDocs.R XMLRErrorInfo.R xincludes.R namespaceHandlers.R tangle1.R htmlLinks.R htmlLists.R getDependencies.R getRelativeURL.R xmlIncludes.R simplifyPath.R NeedsCompilation: yes Packaged: 2024-06-25 12:03:40 UTC; hornik Author: CRAN Team [ctb, cre] (de facto maintainer since 2013), Duncan Temple Lang [aut] (), Tomas Kalibera [ctb] Maintainer: CRAN Team Repository: CRAN Date/Publication: 2024-06-25 13:05:01 UTC