From ef79a1c2c1cb55fc5b238d08f4b6157d6eab8c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Pi=C3=B1a?= Date: Sun, 6 Mar 2016 18:12:26 -0500 Subject: [PATCH] Initial develop commit Initial develop commit --- .gitignore | 325 ++++++++++++ COPYING | 674 ++++++++++++++++++++++++ COPYING.LESSER | 165 ++++++ README.md | 24 +- TODO | 2 + build/img/einstein.jpg | Bin 0 -> 68888 bytes build/xmlrpcwsc.dll | Bin 0 -> 22016 bytes documents/example fault.txt | 29 + documents/example request response.txt | 270 ++++++++++ documents/license template header.txt | 18 + documents/release.txt | 12 + sandbox/Program.cs | 368 +++++++++++++ sandbox/Properties/AssemblyInfo.cs | 48 ++ sandbox/sandbox.csproj | 43 ++ xmlrpcwsc.sln | 23 + xmlrpcwsc/ComponentInfo.cs | 49 ++ xmlrpcwsc/FactoryException.cs | 41 ++ xmlrpcwsc/Properties/AssemblyInfo.cs | 48 ++ xmlrpcwsc/RequestFactory.cs | 156 ++++++ xmlrpcwsc/ResponseFactory.cs | 152 ++++++ xmlrpcwsc/WebServiceConnection.cs | 340 ++++++++++++ xmlrpcwsc/WebServiceException.cs | 41 ++ xmlrpcwsc/WebServiceTimeoutException.cs | 42 ++ xmlrpcwsc/XmlRpcClient.cs | 135 +++++ xmlrpcwsc/XmlRpcParameter.cs | 85 +++ xmlrpcwsc/XmlRpcRequest.cs | 177 +++++++ xmlrpcwsc/XmlRpcResponse.cs | 323 ++++++++++++ xmlrpcwsc/xmlrpcwsc.csproj | 49 ++ 28 files changed, 3637 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 COPYING.LESSER create mode 100644 TODO create mode 100644 build/img/einstein.jpg create mode 100644 build/xmlrpcwsc.dll create mode 100644 documents/example fault.txt create mode 100644 documents/example request response.txt create mode 100644 documents/license template header.txt create mode 100644 documents/release.txt create mode 100644 sandbox/Program.cs create mode 100644 sandbox/Properties/AssemblyInfo.cs create mode 100644 sandbox/sandbox.csproj create mode 100644 xmlrpcwsc.sln create mode 100644 xmlrpcwsc/ComponentInfo.cs create mode 100644 xmlrpcwsc/FactoryException.cs create mode 100644 xmlrpcwsc/Properties/AssemblyInfo.cs create mode 100644 xmlrpcwsc/RequestFactory.cs create mode 100644 xmlrpcwsc/ResponseFactory.cs create mode 100644 xmlrpcwsc/WebServiceConnection.cs create mode 100644 xmlrpcwsc/WebServiceException.cs create mode 100644 xmlrpcwsc/WebServiceTimeoutException.cs create mode 100644 xmlrpcwsc/XmlRpcClient.cs create mode 100644 xmlrpcwsc/XmlRpcParameter.cs create mode 100644 xmlrpcwsc/XmlRpcRequest.cs create mode 100644 xmlrpcwsc/XmlRpcResponse.cs create mode 100644 xmlrpcwsc/xmlrpcwsc.csproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31e71ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,325 @@ + +# Created by https://www.gitignore.io/api/in,linux,windows,visualstudio,monodevelop + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + + +### Windows ### +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + + +### MonoDevelop ### +#User Specific +*.userprefs +*.usertasks + +#Mono Project Files +*.pidb +*.resources +test-results/ + +# Others +*.msi +*.application +*.exe.manifest +*.inf +*.db +*.db:encryptable +*.orig +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.cache +*.ilk +*.log +#*.dll +*.lib +*.sbr diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/COPYING.LESSER b/COPYING.LESSER new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.md b/README.md index f187922..527adb6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ -# xmlrpc-dotnet -XML-RPC Web Service Client C# implementation +xmlrpcwsc-dotnet +================ + +Description +----------- +XmlRpc Web Service Client is a C# implementation of XML-RPC, a popular +protocol that uses XML over HTTP to implement remote procedure calls. + + +Features +-------- +- Copyright: 2016 Saúl Piña +- Repository: https://github.com/sauljabin/xmlrpcwsc-dotnet +- License: LGPL 3 +- Language: C#, .NET 4.5 +- IDE: Visual Studio 2012, MonoDevelop 5.9.6 + + +Documentation +------------- +- http://xmlrpc.scripting.com/ +- https://en.wikipedia.org/wiki/XML-RPC diff --git a/TODO b/TODO new file mode 100644 index 0000000..85f5500 --- /dev/null +++ b/TODO @@ -0,0 +1,2 @@ +- [x] Improve management of secure connection (X509 Certificates) +- [x] Improve management of attempts connection diff --git a/build/img/einstein.jpg b/build/img/einstein.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d46fd498992f202166b538d319ad8249cae9c6bb GIT binary patch literal 68888 zcmbrmc~nzZ`!*a)E47NTT1SLDRs~xG>LZ9U9W8CCQjFRvC`hDKnS>OXhj6R|6sg44 z2dSXM2_iBC8X$l`stnO0MhFlfm>4325Ml^P4jIllc{k7RUGKNn_t&?+*J&+Ql9N5$ z_jO;_b?>cZ*z$(3;=niizacDIw1{vD{3cjL1iyu!{;z&5JmmlC0Sh0t{7v}y!$sE? zd0Q>|ly9gWa%W32!ur+{Lixq|NGaX_pILkV6pXwOFmi(-q5gu@ZKUTtM}fw z`rw22-v{ref!7J|fBeD9O*{52UUfL!`qP9@{{74EcR$?xW!;n2NBU;B?ELZEg(V-Y zS-WoihOG{c+dli;&3%{0?meDxFqO zdM_3Hwfgw|4>s*symH@R>+pnCpZ@!o4?p?x_q%mZmTca6WOntB=lVWcv&BuiRkJX) z|IY0H+r%#X|C-tVnb`j`uTjD>t3_b*tUe|{1T@#5`NR5uI3FmE9!WvG0v3iB`@bu|AZgrfSZEd+su@M`x!eGSnUN43Tu zetz&p^uNQ%)O1AjOPLLHsKr9aqoUt6TL^pR*WFn@&g;Bplqg!dCb*_ZG}A&D@W3Nr z`P`!-MI_5FA#T}?lzHgvV0=vy*SL841Sh_Db!eQXFx8yN{RMG#*h&{PN9l+296w||b`1Re`UWn7Y2dQmuQA#9iw&t>k;?v2EA zcV$0Gpu&2b))F~G`#jKgg@vHCk=MX3H)TUL-lTS|s_w0Y@WO9~q+f|3N}Xcp zyl1xk=<7{Qou0X-?@}-ep`Lpn1nk01$I-|pqw`D`#vOeOpV87MEQIOR9i!7kq$KUE z^@tcU%z-bCuM{%5QlaulV0GDB(WHg&orQ3%;b9Zrnqnc4URc!&sA_2=r#L+Fp&vC; z$482ksxnOPRrjKMSYY7R9I8hv5 zQWYw(5Kix-BKf=Zn~|P^7V1F>ooOM2o)71O1n2V9tUB*5^}AD z@H^G)!9p*wue|g2sYu^7grxj@Trn#GpWq=LAlNCC*?BbfV$0xJ-(IgVh3pWUj;#qO zaFfiiR4!oE?~d1%#)5!P%=Q&f@n5!f<$6+$vT_<0NXT?38}}Fd)Q>9R`rw!~KUxU* zg%d?&t%6Z@Zi$TH871xK_UZqe0r_De%xuNHa1zrauBsP-bhkn&qUjS%Ej9&9LF$crFIzs@vEi~UFK9&+>AaG>M6I1AygD&IZ}A$;?~cl`|? zY&d8kJRdyMWOi?-dV;kW_Att!{_|c-YT$-s*FR+QpK37@?q~OyWFdrk4!}`^Nfq3` z8Zzn5=6$E&x2r26i{DPRwSNo0YVXV*QGus^&V*UV#c+8TN!OEw(QjD@F?6L+dx!W{ z+>c_C%bab(-LfuuqJ{9U`$AN!K6&zzE@s-?7X(Z3~ln5zr-?N-TkL!z>D@YR>d&=REQ<_Dd-EQFD7Bmp3}ijW{C3$_rB z5;Ahy&fWY1E1erBHPRl5BqWN~6y(6r>?{_O>LXNZU@C{r9Zbjj)jXl@zWLbt>o5Cr zM;+EOPBBy_*2$e*kmdT~R7``kyHNx2i^^UmTZQ+G*t9Gs5-E?9em zWI6|SOfIsEeNS|x`LaqkOhhhU=9+>=-sQmKr$s3JpSD#89v4LZ@iNX&RdAMXIxRF> z2tKBtv}z=>lz*fZ;AY~ZXzuC$ch2yn6NAN6?zJQ3xVoG%e+5NpA^DsHzaSYsXbm;UZ$`}bhfdT)7r>swGh6w5Xc;}wO|iwA)FX) z)@;RIjKU(YK{P5>xOR9JdgpO3#t#y>E$Syfz?kNUBaNg{QWQRj_i#XRuS`k+U}7OG zFZ?tl_)81n6!=C#Ii~~%;QH3~5gZAZHuSXD&JKrCy6ii_AXp>1#}wlgI2wMj3T$^( z61TOvSuo>%)o;dt|0BRhL}mc*X%@m}-5r~rp56mbT-EQ$@9s}Z=!Tn_G?)QhPAQH< zJ&!itCI0HHc5(QFzX5`^__+@i0Bn}T=OI0`U8Ay@RA}@ojBa)^B`~z3Z2id-Pet>6 zp<%~IL}K_sOq;u_(Mp4rDDmw2MdA?39r6sT9%hb=&>KU*$Qh^7QS(rC*`wj(9r92M zp@wJrnrqbI{_U~3=Ez&6w8pzgKC#Y1xIY%_`wsj$*w$O>Fv+uqU{dFvZG{OUbPw;KZ+2ImlKCm zP$&CXo!R=j4NuJ-KME&AS_nI~N0>usVs^nFyt7sNw6bHvQh z8UPKC>b{d<--O_%PZp66Wa>+TwKZ;;7rUxK23~|4k|ZXZf;4sM=iPVH<`MB}tZ4vh zfCO(j4HiNXiK#{0pNrEyiahKCd85Akbi{mNr$j;L8Gn4xr}y#-`Earp?`<~w$k7A3 zwn+S*Kkf))F$9*|kkI2#GgRc>c7y7y)?y`Pkwy(&(VK|CXUul3NXGg8NiZYXq+~sh z!qVdn=j2D48}U~qW=OSmr-i`3gZIh@ECf>%`az<4nLwN_2oZ;Lm>4Qo!*#q=a+Pp4 zEbyE*G<_EgIKh`V-%LVS$c+*UVIN(KyLUZLOk8$jmMMD#le0k$S$3vjQ`Fi1m+Ru8 z1fGeEcAB#xsqvW4#LG&zA%v@$MJ$A=wFHnNr^w`kzHJZR+h1P%q>Dca$@sW89i~i( zxUY^j--UOLE~#;a`k}!w_=N`~N9Q+Qh-E}%(k^0-)m@62v91M#nlZoXGX=fKe<1>!Iu%o z6k``8Dw+dNlh#i=MO>F3(G(?y5_O94GJ6;`x@$_3XsFNc zG~(q3cH`|@>V3GAgYRpD_yeXZ-8a=J!*CO>*#)q*X*2lLNO2KFW@@|ACvM*;i-Qw9 zihhkJdY1iyUu;GVpDgMRtO~T5X#MvXT%IzxXCZ^+%99`9m5-PsldYV&cX2a1mZ2CP z08rM+;OtS4&3XzwShQl>Uf;Rc{7u+h3&C{_SNqWbo57mSJkyMMbk2Lm4c)Cxzc#&r zig>(hpcr#>h_zO+*X}l6x!mYo!dERNHZtl%hLifa@0ReCXkEzlj^$;E53vGSpgHh4 zC?Oy)&JtWecI{XnR-#hX9+3h2M3^L;q5x())uxM=vSpAm} z-&>1qv$_-D)kCc>lbdegT#+yHP9^=VIGPe&%W3^14l@6M-Cr+AP=b6nHkXBMooMLv z?CNGd+{#5WM~0U(^ea^bz75aQa(X9A%m+qgF9PU>qA^;LmWMbjCmVHlmblbpDb49s z7D8XYAF}k9q(rPzVMG*vckNWoifIKlM*_Uks{s#xJLpWq0MA|~v^R-$=I?}SZ)n59 zV4fPg#8#k>Qy1IvdIph0R5RcBO2_hj=6DL zUiwENSV63lSfaBLz~c!z6V1noL8JbJAj02q`F{cPg$LMgxsum*I*{eJQ)KiO9Uo!n z=%x=c%@)Ef%`2;hlJ9eDtG~33Wv~I2!rzIE@EJH1KU3pS$sFm;j|Fd~(0j&$)<#x~ z;0Iwb%}r)s7+@S{LS;1lK#xmLkBcwZu96Ne;)zW2-4J79uie=E{Pn=Zon!EWvD5}N zoy?=pCB7GHJ2Yfi|757`hOK5%7_R@h~4q1G3@UpGG$BO0f_| zHyi?Z2N@R^WJEILXyreWqs_T9^IwQC27a=A8?$gZ?VhBj=oB<*D}pfU!EIJQ&c&KRPyd$aay|B!9cgAQAX!uP!6fY}dsL^wza}Kp(<8mTKz$3l2H%12M4)(b znCKV-52u_RaI2IUQ*#y5@JlawaYtJA$m;G&;_y4?8b~%r7EVD$140k1vdZz@sd4)o z2-03EDU$aRGPahsA+hHFv^JT&L}FU|xVVE^o>y)m=zqa~YzbKUXT0QPV^gaZM0mq} zHm8~9E(ei!dhDlyx*xcUy_41fqD3Wk*jZNmSfR=(sX51+NusS)7Wd`{A$*ug~-mQ$A#n{imBJ6E7FG63!eBZ%w6EiQ4 zwOxglz%y991ow4;CO0fD2H^h%td)2VI+H@0>lzE9Yg{)2xg~o!{x|$=TlP91?rlQm z^1^EI*{0e7Hht!G(0mGMZY9`@qHKT|70RGHyNV81@mWzr+a+2p-lFD;O6W#vsVD7a z;oA*cbALnkPZAdcs##lf13vY~oU1{rEr2JtD)IN)9~j89ld>+~5BnP`(a`f zQGIFSgb@!no_wsXf)y`gJCcEpY#CT2&2VVE)?0ND)U469NGgL0W_O2*M3P}jy#5$& zAp~*(U)fOz**Q7Q#V>^s>#1&&+?uL$q!Hfj_?{3v^&Fw8yD7=E<`d z!|a!zU$9#Mbrgti^6pp%n_8Ck{2F)GLKr`am6e@L&ywL=+tS}AzJm(Sr55u<_K*?e zvkQnX65T?mN<7^DpZU)cmR!+3H`^y*(DKY|_pXqTQ0}OM`D$v1?aJ|?5E$U2~z1EA2q ziK{Rbc%}eIE*h3M<${9!Ew}r6^28`GL;~qy?#7KsDCx=X-4;qK5-MJ0`v_e5PMw!s!H?u2MkUz}|;|e2xCN8#)ZCN{w$+ z^0xR$b^zRg@4Ihy%ZxN)u@4$sui|{S`L#u>5|B(jrK13LrBtUkIQ8(^z3yDh6F~Dq zp=J6&q@IFpR{4R)Y@_ReY_6o&hbrc|iZvF3oFqN(RErPh2AAMII6rPkHgli5&ReU- z1J9*ikA95)hhz3mf#r1agyLDn_ED!`A9tcGPbBy zSlw`mU0W={tg5*j>>D7F$6i?nJeqDyy`KKX7}1mpQjN%y*tIE(GkH0=(N42WoZ-0M;j(G(PE|@OUcOv`&HaSl0{X|t0$IJmn7m^w8 zm1;_~5Qe%!Z%Rvm8He>YDew$XS~>*raScvhc>ovu=N3d1cFAm#u^u87&VM|OoTFeH z6JfP6PsLeYT-FE>${F4nGwiM z72X&AGxYW|uxpGC^vd+6A=TYRjwCYjkq-~O?6L!dF_)>8?YU#KG_v@U0+IQfxqzkg z1vYVq1)f7^a((vSt<9ZZmHkdMlN|(U{*6cI@L(W$_%@SSD!)}>a9M~rI0hsG%LpG> zNUIXnD%$;-AWs<0%8YKseGF>jtHqZaE4LPhdV}&D+04cVRbamS2`pxh`$+)ei5c6` z637Uk|Jsdn8OeGu=a1ylq5e72R<(CMeZCRAqF+hUTgmB4ahuhC!(mx(9C%ax$cTXy zXeJG>3LT=J2a)+C9$@yWg6uY*raQ~y^jmVY&p{R4xB`Ch{W^#|)Zq4hU^vdZ7d2lz zF+g*kabtPL^Kge_5;?am<%ZbSkSuN16YIxf#k&Wp)ov_Tb0ogC1<0Ky2l_=dkDKiT zg=t=l7B-Y#W{QB1XrMw<*=uLzh;IqdCK4t&9JmHHR?-=vhv$VfUT|M4R4y7(P&BT6 z-0=s($L9Zfz0gn#uX)z>auT(E%6_T+zXs#fP@kT-K88C=F@i9;=D}Kz^rrcijnj6m zi^F-)^Pk~<7hfRw_KIl-_xR>2UOHWG)%d&+ej00p5c0Pe?hiSPDlz1O89r^{@Klr0lxp09WH_dHOlIFiOXgbIciW5#1RMg^nh_+dp)~vD)FWF)geWGJaB00KqO_nvL5$G{^NyCkw-Ui z@PEuCu!L_Nfx`yRdTXx8^-hLtfrVfX2%He;7_|r>h4)WG-FM4EqS>M8&~!W`=;EQ5 zxTMaXA!d9WD89aDn%X#A`3yYnb;^vlZF}#QfFkzQHJQI|;G*@wOucqZkQv30>&7`- z`q2H4deg%rBPV?rCfeH+D|{b?rIaw&PX>~nFwQoz2dZmewr&i&AUnk6nNqR$>&fAm zQ{THYvt11h-6iE?aA%|Fd$Tjc+8kgGz%Rn0NRyU#f^b(lb=KQD{NeH8Xl;zWBdBs@ ze5|EE7x~>nsHHOHMyoJ5u_9D**X&{PmPB9{0%n!S=-8+cDEeDI42wH3=UyzE$>;*| zNG`*CJz{UW=@!ew8K`7ckV8$UQ18Vze# z4kk%#^uVyak!5r+XuF|pCV*rT{s||n9cAF9pcgc^Jb&eKxF-GC> zqxgc+{=&)ZhSM?=_}PQ^;kVOl+QmS;mlHtO5luM-7|b-hT1sXusS3!@O8lH{JwZS z%Ynnr%rT*ryJ)H4$+-EGRX!T zcmWue0#s`#_1w@i@<>F|JwdMesm>n{0pukBHD!}72h{?ZMV--AaQko(e%^JrT#J`> zpLZ&Mh70iDk-RFdOe~=rmn4B8&P-k0W+i1kq2^OIWPwL~2tTD;_sXuG5ZeX)pn3nC zBnrv!%`MkrWz`0DXE6^6qrXwvv(Z&=7%R{q4U~&ozwt_QM*YSEB%oBsP&DO+#3v@I zy|V@ZKOdrzP?NAF>q`waw+aHOcDmZBv-I;>(#*)4wuqw*8b|a~e6_aSF?#@7?Y^D9 z2K`nO$3b!U1?dSaB5A%!*4_Cidy~Oxc3w(*dH247gIwyvKTYEWu+7Kn?xP>ivJj*s zqGG|5dIn6~B{=ww&AHeUU}WjFulX0U*9Jz$`rv)JQR_LAt9i5HB~zc6+ecU4ySIC-6o#}Tk;;DPlG&eSKeeY4pB!GBH+ zBPEWjbAymI88-Z<=3#XII&2cirX}`wf$0{LK_#&idpDxK%W4Oz-a&uW!>gxEN82Xd zyu4V3ul3LjDAKP26#Sv9L4T)=o&|lf@c^GAqi+~>(`!#0s{_Snr4%aw{zeTPR@>jO zEpBGzoHk&{n^Ef@iKtahzJOJEsW30$Lq)soEDh`Js)yE6-SF^rw9d9gz z6^7ivf}XDg`uyAhSD@?uOb4}X*z@S0eHx5YZQ$U0-{4s(dTfi~qfb=z^h!1r1E0PQ_2OHUGyXtz5>}p z(k)Gf{bkc94qki%FPRc=6zD|!tI&!DU^q@?ubj2+z-;kTsD<#0dN1iE3N7;85_6)y z*zr7WXApI-m?kNLHsoH+vKyzbJigG~fwU_`{(oq1q( ztTW0)MUR9LLDFU)olsi{AGm7d-LU{Y)7}g4@(}2qoxW+}X#6{Fe`yyGTEav>4I=;m zn%{`%`7s3adtp7~QzB#7OotI^p0fdw_Uwp<(WCK&9>B26D;aP1v6oKDKG?Y06P`3i%evn&0VAiL*bG`x;@8Mp1i zN-Ts;bi?hb;_f!A2I8;Qa`XOM%&i<4)J&=C<*+53K6D>=la0M_d{>>6W$<@t0u82RGeJ$^F zT^3VZ)Jb0?2F(Nm@9BwS^z?FgEMS3Dbkp&~y(GuiF*OPtuwq>Kivkrt|)4;cFK@1@KlZ5Z5JSM3o<8kXZ*xM7~OZB~r_dU%bJa@M?zfXO9ELue~G3Z4Sy*B#l~XAuN@>9L!vZx+5ydu)Zc< z-sxG0mw0=2@kE zs-kPe`re0dlppo)e3fK`TO_0RG@KTvJ&LY!u^v%5tJ+8Kn~`ACx54ZTjYI%ExnYXo zM%0<65yz34caXdT|1w=()AS8-y+Sw7@)*n_6HQ-9Mi-BZjM;unPQy7<(XWRB-(vSM zB8Q@K{s9jge48QpwZGSS-a=Rq%r_VU)KpB+1yZ|Mk?uV7@o@qmXe= zf;+rTQpfl;DU&)HB3&61+?1p3Z1kjz@X#)}zV1Fl+3jSyXGjD^q+>0-Qb$@EyhKOy z8c%8e-T%j(aie2d9_YbEeeUfT4eCsRmbdO$Hd@`GOb{P8 zWNhzBPfX^6zDW`Ki<=nev@7r2vHj{zoPgL&FWN4$&gin;jb*rT3y={HjuEn%FTg-C z-1qsEtGCA~I>s!YUQ16;$jr~rq=17U_c`c6GmXrVRm4@qGztRTh9shEp~n@Jk(5-^ zF*;TTA<=jf9#+3do>B9k;-w-H+yh8!_HmscITWUE)ZdfKfpj^|9YMJUfX}s5wBuXe zgpk>mdLyH&p+EF^?G+iDEl473p`t~v;EgbMR^WMR1J{3&yU%jpX$L=^9NiVC?cSfZMSBXMK!uCIm z9Ss^$@xgwuOiQLIVG#f40tXKI@S zN%s>Hl7$BZ0JQTYNR*<0S(Zc+t@Z2>b-1@Nkm~Mi9u=`8;o}s8qg{5cL(5mStpn8! z`EiiH+4nm2j)ibmq`X1WI1g~y88QY_VLYEc8nt3BhA;M*ou-95N!NF~UF@59^=n0R5{ z+4F1G{>TRw!c&i}fL!bcx~`Tz1U0((sd;ug^@_tWVZ=VvFD=>03swa@cUJ|eHh^zK zzfZ}ig604V&J*X+jmy%YAjF55b!ahb29rl;uhtNM4TEPoL1A4k3>ttY=;$WjB~8Ls zu-qROVcp*07+o-@3L}+835$p5OoM2FljgL^mb5y#G(S2CcRr)hyGL`8T_yLTxpdB3 zCk2sU$l!MjrKDt3Pu!kl+&730aIepBMjb$XVyM@m}`j6{4dGu&m*Ss>o?Unk|+J4~BG%WqqLXd78N_KkY?FPw2 zpoJha5i?BkqXt`#ycxAi)>he7l7DR<)NmG(t`&0GdZ%8eBMaWtrTW*@Z(r^~Vb-Hq z$w$N-bcbCjGcx_Y;n8H=u_0NoCcdx=?ySUDk`1?FVa*m$+L=_qLj;cn-*@g37JqMm z!e;GCi_D^4Km1Ed{2V;#F)rR=KzQv=GsMf;iyIAARsQ3oPtqvn?~kzuTK7m{;>d7f zl_U);G=w^kM*V!+Z4Hn)Lfp~>MXFba8Y(*yDaS{|el<~h<|Z(t4D|S-V@b2QipEiK zNfrD|I{bSV4M?z$y4)!%#?l-q9Ja#vH?42fhxJcV0j^_SWwV*A-p&!f4y_@}{egt%84dDqk*LM!_bi0V z;T^M1QsGrS#mc}p`||w;lW5lXD(7?Q(D-S9K@rm@AoNme$UXR#^bHDktyLLbS@VEW zfFs+eviTful4G8?b-Cf-Iy8KowLUb>S9x^E+X-~nR>xQegZyKU)AQj8elQL`RP;I` zSXnTrXXZH=sI!8=0q?DEpcR2{ydawq1++Yg``ZSOTsI40ky0qU4tL6q_!0&h=*ATq z9{LLpb%E_N-IsxK^NVN%D9pHrVTn$r?HzkH{JfTrl71MmNd7^P!Gt++`1u% zbV5tD&H8l6_fy054sERcc43X}6Ul60*Op=;n)9!L)^Fj-CBXE74c8e)n@GVdVU9+6 z0xeE{j#~%#5nXQt{sie-U{N?`aA$QOdB>Ff_5pyN8f&5=6){}n? zWkqTdrQD0^w?IkfT}s%;G&rgxx?S3;*ik0(WC+5-{wDo_f6<38%{n+x<4t};+?ZC` zwPI?%xT<|i(_>9R9abjo^)QpnB>XEINGV+T%$v(?T6M6Bifm##G zJvHdQzkPGmJcF2Z6mZf!9zxB}@{kdYtBg;8oVbFm(B#fInYSuO#T6AN+ zqJi<`M000vfWVFb!xGtxc?#pa>?dJ8?SSm7$9-Jss>XhI*V-6+5)R5}-qqH>i8?B< zXMPKVzaxb!i|{4Qv({bYPqI8TK{+!hl+Ns>g+EI38W*D9XAnEp){2%~;6YZTQ2~No zgNFYrsKZ-q?;eWm@TfS(#9ky|Hk@4Cy-@n`Ph z$#ktjsJY~EZLHf=SbB4daE0+$#st8QERRPWivx{`{nS9pqDX5^9Ly>sgX?@#faG*WQ7n1`s=Y4@)Y*m(a}alI%fJBmW8IG7EW3 zTPZnV4{6%)b@C@-qV@4O?-fAfbxMM}fBR;iv3t?_&Df@-*Q+{wR|=|hpS*Hqy{XN8 z*6_zL!@)Lc%O7H=(=z;cx+A1MWIY%1=z-Tew@e=hAVel)D4a?m>23OvdS8Q|+o7kgnGP~l%db~O?ZR!@Bx+MD4~3&!BT*fYD82f)RYzNCUur;Sl-xSl zE_##zOrPi$D&_}v7CKNc;p%dBmk-zEH8L&HcwYl)6%@E({%^1dt6Vd&9A0NVN^Fh3lY3GuXJ7HDPHx57e@ohPI>okgLaLZ(IM+r=u<$SBs7T z)ubC}b;b3)_E1?gGDM^GIHI!#ESiqY0g!E z8A-R`uUc__6Q>0qhDKX%K;!#?K6G1@yJ5?&HM8Z=cr-Ynb`c=$j*}i{3Vz|FPn(zK zNLX|bprAOP-84|M9p@pH`E=Fc3M@%{yCoyFIxuKoEnp^zWufAb-h>6~07ebdCyIP5 zg!1h6!v21d*&cS0nIUZF3};OWN%Lks*(Lyf3}=Y&{B~M(;0X~};khgi ztjta>@_j;0z^YXP_RzM))eC$PW2yn6VPh*R_E2TazV&wt6SCD+t<2#V(%9lG&S|e>2 zC?ZiBr;`y?C)}|MREim(Y&7uYQ8gkW}2b_2)FWJ z@s!vs}X;!O=_AW}9isFeDqw)^L1Z3wj=;}os#4XWD}?b@A8DJNdUI0$jGnwSG`b}S z3H$9JsHu+($F#vJtQMLi+w+QtxwDJw63-=xs4M&)MMauF2dlvufPna(=8m4&19n2k zr$22WFH57U{+z{fDgY&GZv&BJk8jY#U&mPGps%$X;MinIMbv9}ocaV+HqAy}&e|Vc z6^*aeq@v%?1Nc$Q#qP2WHg6;$HUr$+ZSTp?;~$0^I{YvC7YAAg4>`Miyr#}V_@qLR zwO{%y=`{%;W8Sp^Bba3eifqI_o>fZyRaU3V6}bK2mRVN5+e016P#pR-R)_Qk1uE${ zcS1n_+2A}of3#WSTVN9B-kG8RnN6i+LIawyq(4?gWqy-;Xtd0^jSKX zFBS1!FxkN${@r=9RhH+_c96omXU9yrNOvXmzT$9{Nse~5`d7qI=4|m^u;2fJslsAC zdHqz82^h#Fg|LT*{K)gVSVeK^l~L>WW$Y; zd+-=Z!y;**tJeYNAZ9!GmQbxl-uo)Zu@B)F0cNK_SvxIPP@Q?ncXdvzkKch>4!db~ zR~;)xc;Z2oeLzqD-qN=CQBz&eULFE$|Owm8tkAi!aJP<2EFpBtF6229v-? zEQBs7q3X%QwCjQR%K`d^BJ_$urd3kb2Y{!nn8H65=-UqXcyyIIa$04I-M_<}<=S)>` z^`#8@?+?@BwMQZ09INtUJ;j!G)#ax?{n9vJ{!xz&6x4A8=wnLY;Q&y;^HV!$aNz)-_gUI*h~6MnZ0G!IuE$0)z&iR`AH4)A|Oi! zru$V=*BVdXvUF*0KpW>$!zLgxbCo(4aJT8Czg&Nl&fz=om$-MU;qDt7QZPQSA*1fui!JCwP9Gd)C*(ursi6wx)U9HK%mxkgu(x{a>0N*81+A^<@Jk-pT1;taf+) z3H~vS6NnElFz|~8kTxaKe>y#D-j^G2(fAt)=Qiox2htvOm_3eM|LRW# zm&$1!JnQzZ<3zBNhSo%Z=N;t zZX`s#*U^D56E>Iw9pq*gd1#0Xi93N0z2vJrhJ4^xlj2gcxtby;nr*WM9u@*2D_m;G zBE`o6Ox>w*L_Fx;WcrNgIqE?-egft>P6jFS;taO|T&4kv)AR}&dPf{J8VUGQ2Lbg-@zkn}I3fW)jn$AYVcZt8gX$NR90GNQ-cz6i zKFugRXT8CZ>7Al94qZs|6die$1TP6yfYS)YH2E-8?-mzg_5z2(Z?Ff1$`McIr&aC~gwOT!XEGr4a%=B7uyjGAMTl=JG=72x6;)?$ zHe?1i&mu+XkyNaiITl8%B)_Vuuk!OPtFUjm0n*RUn9jIT|Jo@y@JG92e4&SXsGNbmT2Do2K+TQY#^<8;JE```4oT-vSYLElS|ewGcv#M^hy}jlG|X z%r3T>{MyiOk^o=i08WV>glc(O)!vPz^u*|-Q4?u>Zn=`7(_7?V_`|TjJM+cyd@pM)q4nIBb=2p4;ta`>mX!H)R zINm{(Qk(*W?n~7w=Kz3c20tK;?aCFc@Nn*N6V&-xbv1wt!Xb9D1tlT6@fM zSDB2ea^8ubZ0Mz$Qn1*+rMZ-^t{*jj{brzM(*>of2<)TtpQcotdo|hKURYlldwXf1 zu%UP7Ay}ny+Q;rw!EcxOSfd9)rQWBW-ex6oll*G$*jy|g!5zT$r4YtU9JRB!HxE?l z{sqtMPb%6C@nw{6(xA?3hWrptxByQVIL7bZb5LP+ zL0X4&Z3km6$Bg&c zX7yC>yy}VX=Z&1fto_t-9&s3O1==~`(Va1r**^e{*$v`EOsAW#CShM^T6YBc9T^ha zI7GX>{*g}xCvdpA>KTBuuN{vFz{#5>a5UijjIwm-2_whXSyNh@%-=xXb@$Qq3apYm z+kO>7=s76y&h&}DK~>1kHVf_p5$RE}-$=(%Jy<9cktc)|-7+ zj?YPPUfGGU=#&i$J+JTT`C3y%@%5*arL9}8N1F<76&L;HzI#SbsRI-T^yYH_W`>Lr zd2_uqYtXpP-dVgf-`H*^4pDG5QfdMWD%zRplcsYpKU8;zxTU|9ROT1S6bEkf%;6y5 z9L)C|1W0Z@Mr*mEa0~E>bANpM*rfO+e?R`j>^!+02JM6nf1yCfI@Q$QaP{+8FCXg; z6VK!$#b0r_prV75!TltW9k7#hH60xpxmU~aSH-bCy%6pYEZ&|(3kdAzvY{yt;KMLF znym9hSvzvHs zN&jafkVOf43t=)u18(PKOC$gUZ!BnxB5D~SYwb9^NSQ(n{YdXw! zq4S7HVENE_-_6bJ)>-Wst=Nm-7_k9Ddhxpz(Ol&HAz;AB04Cd@Cp35-Fg>^c)K<~h zfO67uf7R0$?v+1`F9G(&FS_YH3d&b$+P_m>vAg9GI=el``=NM%;S0)(9PCwC27uAvT;`IKuF!BO(TkDd;jG<~aW9GdLYt8r5*s1|LB}p1W`x zH?jL0T%hsPPzK%o>ah-${TCY2dB7sP``bqz4acmtUs(q(omIeR0IxHHdzsby!~Y#E zykT;wi>!!3hEj`z7zyAGWZp6jo|z$hwZStjPA9s$I00jqg@(bMT5?N&L7B8V=(&lg zK_6Pl$yOn0)b0%qb&sZyd4`>@UC5M!vYW9C^+)K2Fv{{Qj|F2u^Y51>RYcX*2!FPk z&XdelB4X@M9VzEVDyg3Mgun9mba8xcI>KEFT8W|!MZ?+lPr+^6H%o7OFwy-cC8ehT z`Zn7Ke<8$|4%|0jvre7%TVA2zcg3_v0o3I*Mxf@0HL%Fa9MJLOM%g=J&z`xNGg}4??EM`8*U}>rAA@?^f5mBU}g!UJ`@PI z^BkoBl5;t$b&))J&JD>&**nvie3!Z)62>}r zt+(23mvBuYTmjH}uhNhip}(`t^!bY~9B*R~IJL9bXPV6zyZOsJBq!y9v$ad3y=!hU zgeah_-UC0sNCkEgRjcN2)IXHwgIh5Ad7VPg|DZ8@1R)95SqNbJOQWog^omK&{jwMP zH|-$0B`JCFuen$<)(t=TH2YJ7wo6hMbkS9=3A_35>(k@pRncp9C^w`c)p${O#MYt_ z-AyVy!5T(|Jm#OVhD32`Dr!zJq$mYekbE6$L_NF~nHlhX4_!UjPV&8fzr%(@*T)^` z_j>ISG+1*Cq|fp+@(Zo&-cP?1?@QV%v$}Qa3IWS#oGr?k1Y~Y&drABsv7@Y;2-uUW zKSXo2Hi9HERDCW(_ZeIjZSuK2$)@^nk!nyzz@_rZ)#ZwXx4-}!CW%#%1K^CiY3EV4 zASo^G9Tn<#Kj|81P9NO98yY<{wa{qb2{m%z#K09!;s!5Il-3seGAeAWeqaML=oO&8tL3p9X7Nq|JiVhTnb+u<01UNV zC1?Ja4s&g5qndX2fcd(0>Gwn{s4S*>*x(Y zSNCyeB-&qI6*%$Ha2p(4wLItlF5cR78gS|jMc87f4w}0N#E`Gum)g!E)1}d)Jkw9b zMI*^qeLDamMj}x%^I3S9RB#hzhe1`x#j#87_LPw^dOG;OJ3=6*qeJe_z;W_PcFArB z_J0(2$R+7Pzs}BHtR?4oIXjsnerVt$Hwr7FnI~mtst}b6T#vU7wDYLe$mQEz;255o zHG@k){p;Fa_PGwx}w!bRQ%)R$n z&U4PW5s%@MI|H7FmPA?&>2d=IN4r*itER}zCGZ=O~3mK9pg# zm-pGFiK5o$`8;ur56}t};q?B6|{)D1a=QVV!NLB0*=zd9V4rT`AYk&5xsR<~_pyow-&eIbf(Dca09sV~7)kg$_zDqM$1T$h=BV8o{)lEoP zoOb&mNMhe5lm5>1|Ko+@ohW!4TUVC=73>JXDDGDmj?dNB*5;*gi$~8DtV(NZL$R+x z_5ZJI=G0g)#a*^6^7t8a9D2rQDtradM>oA@o+xm7?Y*LSq)&JKTFHo4MI}4TEo~b8 z1j{+387zb+kXABXrq7`tAiKv(o)WzBUCZ<|}2Z{q87{1L5dCv%(oz)CcF zEch3wS48GHXM+2Im+xjDz9n*5?o1A&adPrmFcAN*qM;*O?P4I!Z5Ci(u}pis!f;>G z-+bOHW;BO^2<%7nbxB2t9URT0xDHo$x( zeAUH_Q|9{+s9iia=r9}i-Hj|*&&NAD&miNSFiuX_4|3(Mq1xdf&IOYXIZH5fo3^5c z)kgrPy&Gkj=~GQVqPbw&&duG8_jG$ZgmEGvp3?!%8MInqK{J(vrfd(ET`$ZgJ)fyq z+s$`Ohsv3!w1GcEz4d~=D58Lf9WNQ#iY(=S!4Mw&$0{#Q!vW|l^s8EJ46NTvIiObk z_>viC;lMn6YNtllbQH>w-ie_C)-XnrJKVgcJGAJqepv?%j z=gvtOC@N(~G?eV^|4XLa@G+}i+kW-9({V7`amtUIuVz01IKKu+YUX^A>ANRq_4K;fqe$dpVn^b&k4@h|O3* z8@<1u5u=DgXXCohRFGh?GU(GVRzyC}X|Bs7%|Bj&%*v9+_T zJ%Y=GYdukeTf6D+*JU>4QA$B?WPE{O2lFWTVgFdA)|2pt_*MBWTY>AGP|oz}a(hqg zaaF?yI;OHa!DdsxV~u!Lb_)AuGB%9AU!CrYC6ymN0v;pBLh;3qk`Zyq3Prtb0J>;w z*WI9_;fWOXyCdd%Q~0{VrW}@f4NMra2yE($&*mtmjxzqlCmZS5SGXf~UW~Kv!k3$z z(*vI2qxd0=v=}ZSUUYOE=!;nie6Ds)gI$x|&y3$>%^}OEU>P%rHbRTI zWbG}MIW^vuWK7~vyU%-POB)OohGVT7RkI$ob+>1lON2AD9^5J2=nuna^qpIwehm41 z7MjXmMy~gz-634{CMSf2{p2R#Zoq}+LcIeSzf->%Pf&;SR+z|X5lSsxIPiVjy2mp*VuOZM>Mj`g!`IqUA{2xZFw|E~cAzqSr#xsw(GJt~4<;MDG=#0!rl z*;&n!TI@b5$S59-TX&}zE0mX9aYGcjkM4W&9;n(f#4(6s_cp-kiNHHr{N9zfE3SCV zaf#MpxM$64SM;rDKQd_z74`!njW+3`@?SvKv~XjiPlE43mi@u>-Cc;>u1>5c0-^$^ z{pDZiNUSN~e>ieqBTMJ#to^^ro@!!Sd!NKJ^hw0o`3!Q1_$?^Q6892XQk*rvzv?-* z7B78ww0vZ3o#u6%Jw7RVhH_)Jq!u*tVP1;;()O7Bbc(0;`Azh zUy-&jYpb!CWd{7HD^zQW65tmJ|es;8=*?);nQE$C+ES^L|IF;$0k)ETz&=MBiA3x`i)^7O;Wh(py58s9BvwaLUo1s>YvWXXbp65ya-T(Gi7kmE z{fk@Tu9&v-vPso zRhk$MWWMoa6MGD=M~V@lw=emDC~t8eVezZWDMSq=a$b%4)w} zDy3Maz^v@Vl=?^0X3qy(H$%}U;?ikTqv|Ul0sevg2Oq{2S`d5ThvEW`zk1f&a>_e? zbfvGfLlA|Z)-KBNj8}SY@h*6ukLyLIrs@I6 zwx{DQzlBSUS^oi_TZ&}3m%6$8qv`+{_P@T*+S~s4BBW{UC=^I6$)qwr$?OGAMJ*3F zAqnURDO^C(@t>hBYWiDF@~g@w!NPY#FdjAv6LU>X58x01 zxsjw*$?;9m-!J#b3KaGw7qEdc7E^ZeZiFP5qmK}D!nCY-ESRn{jm&K|QPCors$Cf8 z@P>77&@8}h{G&kM1C8+kXs%_-V?OZs`0me;lGTQs~I| z;<4+?yQ-yXG8~Iv2Dw*t%4yS6Z`Kj*nvv1FK}S@!3GKLQe8#Z13kIU3HxgplJ(GL) zM!H+PV0jdYXxcNAckm$z^YdWYFk+1R$2?rgc&H;$45cV1-Q!_Iuq<7tKD>Q<=7+qF zqDO4-30o^T?k})BlBi-=5yO9PEp{nPp3Vx;5;9MlXvifKGE99lDu4}sg9{IJmjdK# z8E}`rVXnpI6EjR`0Mm5k@baUP}gsq!uOw7GvC*H3CCZv+JV&~mKkZ+MhtSfA7P|7m4^)w*i8)XE1eH*`e zj_&)E4x}piZTe;R%zvz`F{!-%-Gi_q+NfdKl?_Zc7{E0L!*NM9Lv*%vBa8rLV3MF# zexijHNO98Av(J!gwcq5srFripUmKzmM^UY-My79peYn|esfuBVcRzWZF-5iFPEgfh zNy5aU;j8Xu|6>BE&ahH%#+i!HfUcV8-O*qK6=2+x(c+#QdUd2`khwzR?xx96h%9oQ zTB#7e{2UAh5RJI~?-p`Ip#D1B{3{5cMxaK32YY~WP7t?a&J|dahzzq+?`Z8e!~22G z=Pt012=VTAH~Sh%`?bz3?BxM>(J+%O=3J~or(H3m!9X*ub99G&DwbR^-`9}O>yTO~ z5G_@q__HHY?A}yk?Plf{42^2bA5wn^jS0DtVxzH4jG&2%1I1d22ZkE0&3pjth+R4U zRT6Js;C==UevAdmp8%ri#mQLLKJ5^?U%L+W)@mvoX0rL`c$OX7b3@1Bd$6$ewDDh! zUM7ES0Jqs8v^ivxc3pay{)mToydpG28+e6xsCdK#`7Hu{Mry!`?KSM#4@T+*pIez< zV$RxS@}e0%1%?S9pS$X|G1|gXRwaKafmt!FPtbQ9_^j}tB#lqm^ns^mQ|xnhXS=i# zk95A1xOp5kCT~-)^*9OLxOtVeLFEEr0=FWkx2sVv}65!yTdQT)Ux#0 z5oz!6!7g{)!_^rdx<$F=Y4+Ga`Oj$X)^1I&G(RhJ-0ujNXW=&f!ogBVxgIaD^!>Yd zK8pFpApR6+zkYWuN`E>Y@96eYN^mFlIX8x0L`Cn$$vl>NzTQo}AStydzN>nWy{Gq$ zcCZdOaDAs*fH^nK4p? z(j&MCmwL&}-?+T;-gQqJo)-g?9<}?722_lP-U>{+bguq~NmKUTc(TE`m#|NMv0GgQ z+exnGwU31aN;lRVKjA1lPMVx9%TTbE%IcfC6Vp@2r<0PYtqBk-d$Hf}sUYn)|6;QrSF(!XR7mY)`Y=)tBnV24mJcAw zM{CU2s!MAY5N#s!==#B2dHv_WS$k+Hx0k z>84$pWYmlzCKz2HKhXLXoBWC~q{VSQPfOHaFN?nyRk!e3c{s(sqg;*;wga#rgVs?n zYYQRDRKWi=S_#p%^d8i#8mh?O)59gn=P)i4{!f*6E@OkX_-ZKbOejFyKqV=#HTm4v zNJR=#T7eUfYxG;1$od&f9YRN8d^YL*MM z^H|G3ndUYZ`z@Me3^V!%;G$taUUw9!X|z0oJG1m0e0{DaEX%`fe0Jj*hd@v~I_2fU z13K8^LPy=JW2$9a&q|igrNWM1!tRaPxB=d?42?JoPxyz(L=_lBR~}H(OBrGdHFse5 zVB5f&PNwXmv8CX>gSU!J7yb=fJ6Ie}$tu#8){~_{K+?*akvgUOw`Q|RrafpCb7E>* z>0FU8V6H6+i_@F8y6%>%Cn&Pmm;}x}52wek&kRudhViwA?A)+>Ba)?OSB`RJz3KS( zzJk-ZhaxdLm4AQZNl}mclh)6V|8Ec^p!Y`WQO*j$w(o1^<%1VM!TK(?KaZ=Kk)pNC zopP16i{(qScGV>#3h*_QRBP9z77wD~jNMT$eD({Q>~i~fq{^U3m@32gc>njdY$k3>W$j{m3e{Q~PPjXjgAmhtU67Q%6w zKXZ|?>IX<$YZT_&D@T`mIz>Nyjzdm}%nA(=Xy}(IM=I{Ti zbuQvmzK?bt+RpT-=qF(}nH##lo!b!dMMM7{!nP0RzEQEQpKF&jK4g@Eq$V*vV;ZDW zcN78Jzkz5T{jRL|e`qaCGskw}eE^)!s%4@5Uc25o8)VbviHSMSbYNP*T%qtcF9_il zNY&TrYlm!(X7(r7iT4ReeZlmT*s#-^0^SVU-kT&Rk*U}v&6x6~COv~{IQ8qVrD!9m z@$>`0nxl+OK;f?$0)zBNv7>wt{YYMLI>BU8H z**U1;@vvqF{ArXjUS|U6)@aZojNP8^Du^S`sxil#@c0$2($4!CL?L7KApf8G!GvpKnnqhY+x7`nUcfmAk% zf8N0t1E|zW-raes-QvbniWc|{xx6$*!!Z2b(a7Lteku&>SVhMpuS1PwN!Y)`ulAkj zI1vV7ZJy$LM*}{Uc!_e%`IUfpB7Jrjy1{-mL4q7Z3!-wgse@ieUL?rX{s-|c-m<{F zB94jM8Nablrr%}~JikrM?~n%YG%clyGBNzXMl!h0A&dJ)4XB<2Hq@4eel?%X*|RV) zFkO{+iW^-dN~n0xV~Cd?0{Kmp6EnOG$I^H{`#{)oDjWYXkk-21P;DJmYT1CSr8=Nc>K z<9mYv(fUmKID>981hF*as6~wFm79|6qt&&zyl3?!3GGCtwcLU&TK1K7tgkTC+T2|_ zWGpq^BJb9w!Bel2%|{#Ik8MJiqoJe6TNo2pW;w#2S_+&rl%lwjRtI*Lhl_b$n?eY3 z#aw;v&u5?pv{w)8goZ)yQA`V|Cf?U2gJ_ zQLLsdVdOO1EzBxr%tb){?c9#{Lcx@cZjtHM3}s#H6J0ft|75U*2J7J~{B6vGT2V9o zvZcEHCHLnPE7J-rFpe{V+jPbxhP60u>h@kCor|v*7o{*$S|zn19++V0Xmnh2$Q=Gr zV&AY_bd~7`33#REsl?(O=WZD+`OW zv?d?-=PfL|4SUeHTs)kw-c2`rkbEW?y0WiLWmA0nR+lDZiML;cG~!$?QNeOds7rop zo`JIJ$h$6&38*>*W6Q;ybtM-t8Clq0Z04f&>>l);4&2dVF_f5SY?QwA#?P| zI;+HOr~Vuy08lu@lyMnCb9a01&g|zD~n>Kk|b{E(%gi0#NZanlw zg;0F@e+6^7XOQ0;h7FQ#l4du1K9$2#r4U>WStE&7tIMhS>)gvo)pWbL zh>hJun@McZno;u?zM48QbS62%#C5E&5{xd?ryOR>(OG5(l)4$q^w%m&0DkBm&a*Ow znsd<;MtZMbNVmIxG@`yf=-zqyw424<{ee9HQ0JKe%iN&reZnyQ^oDMo;FR|qjh*n2 zmVHr||GA~8@Nic?T2yDP@UETB| zi(Ft%4AZKQe?{5EgCR=!vPV^2z&uHSF6N!R`C3>h`ix#2J0a^kkL-0vor5|G^My-+ zqNndTV!kdL2d`LwGl;X`gi^_1?|xj>?u``pNe3Zm_Q*89A3KIxOyu%pvn|#PStILm zoi&tsf7RChmUN~A_};%tXICf#RDXu&InPdX@T)ZgHEH!keM=GkD|$Ebuv5cHI9)zl zMLWUwa}TOGCz%Dap&J;nF_(R!D?U?Pd-`7wJN#8!(JeAK_fTn~Z4=K;{#9D<(xRe^ zzw{P?(=YzY3x}6I%|>w$YGx6h?h}FYtSn-;h)c%6VH0y#n%?+M@JWaH)DG& zKyFSl{)i|J!AwcUOxjBrMy?{E(Sa=~^WhwvjJ+Kmccgbr(4#*m>veSMM5}qb%F)v> z+B%-XR(9~WU^1f>!?}@f)xANk87L@KaF$1gtklLlDE}IuKv0qdq?`7%aQ{q#A?!QB zQ8&u!FZC&_@^?O}=hecN2-KHcli=%UFc7vpBrP3(4J8U2V&auF|Lv__)Y*?mwWQfk z0Jy>tHg$LhsTD~Vd@t*Bl(slJX^EF~;^j;?EXgsyD7-JEloLVITw`1}3IPxJg?^r5 z&m_OH44NO{k0!EXLmG5c`GNo2 zBf-|hii_9JlBSlVTbRyxrC?~zBx$@=lc{h^r7YeBztWmoL-%SIrkA6Q`!qC#-({e@ zd$|24nhdOhXgGV1bEY}pYGdwSA9QM;a1}h5W~8h?g0a5Q64JqHqFOfBbO>mj>a5e~ z_fW!L%#lj9(}c%b>q`aMQ@au>gCfoq(0eCz;NhS;?~vrz84u7tZTIYivgMw^i;;7v zL(sVz`dF=>6d>_xzEDeiicZ=nacEx%iDyS(3wV~%>downctfs(-*bYt7lB#0V--PEsfw0LW^oAdUe*CzDH2YwYzjN zFQ&|VhlEOgo_qivPSBYUIOcg?GbX=f#Uo^jy_S7R z2X0Ez^w(}@D(u7u@xPJYI*xgcm)UDC;Z>gKVl_~yNKIbbcp3wE?QT>e+ApRpoNiSt z&Dj*uRqnAoJ`-7FHX}gz=-v$R8yZYQMmT#5Z^04EyprFSorHrOP>=KkAO3SQy(0M6-w0Bx(VXlX z-q2)YnZA!SqRSpAQTA(WTyez&m1uS z+J=Nst{weh6K=3)RTC$@EStJ)M5E-6;v_ln8mH&n=e2upHXcVCps|Y(6L*EhYF;SQ zGge`)BuMVlPqxblCI&`>c}%L@O`q!ka6FW%olCScP`ni}{6u+|0QzXEpWfaYx3d$# zeQ{Ibi7pFmuPPS)vw|h^$LDLydrcw#Sp6Im9=tGp$@P3rN;9fCK)Mt>bAEi><3QHnlHhY*0{$d`1$P{~iRairbmDNXaw9jbcDTu_4(hihZ6+1@z%^iyy zhOOKEK}HS;63rC$W%oJao}hp*52Y#*)fbMD`nbVGB2y}wtk`oy2|Jthk5v#>Td&*} zb24j#j#V{w7$_{c<1@#A__}d)^yb20mSic@Uki=-L%zsOiYfxl*G}ri>f_dEF)3%UtFWmr!z^&V`mewxf;u5RNCSn|e#S=9v4sM*;}zoIDF58yS$ z8jrKoMqkQqLEHaGB2b+BGZ9GbG-s8a?p;xw!=+2j!+mr&_zPoCc21ejt4w9(+GQC| zRJA{`I)F~@!DX=^9fZ>ihIA#vnB6R?3HN;bxN7oDDU$50uee|&z;w6G6F{6@3aWj` zk^T|MR*7X+brA{asL4-u!*>c|x-2CWP>+%Kb5&Q~yw%csSy#M$ZmX^*ZihKxUB$p# z{7%Pp^xtx&}!2xqSRB3e}(^3_MwBn!yCR=6(2D-XlRrb!-@X=|-q= zmZa%C88e9h(aF?V{(D~mnNYsQ zvIKzK&rZMj9z2<66lL_~DP8DiwgEgNCI61;G?sr`m@@eUXw;u3f->_7Y)X9d|Jn4Su*Gpbyd8YPpMi(O zdQoAOG6!-|h5cBgScuQl@Qae8?u7*7#umrTU5`MO5B6ws*m)c+Cj)xa{8qYL(g2hcsV^OT zYcZOimUhFOm1W5?7p01C*tbUvZl()bOOjW=zvVS7g_tAvOQozv8+HhyXxL!`r+F8D zvB~|F=^(`}grQhXC+pw+6>pt1F4J5d$rG7&iB0=}hO*5t?X!NaO8g1-+mzxui>|Pb zMq2ESc`;=tz&DP#ydQ`g*dI_yHvK&uB-V=rLoO4H>8W&sH(vr-@g&9xE5pvZG%n09IX-}ehIG22wehi8$9MG2J61ax7`Dbp!X}h6 zms7x4Zs7%F$2~`b3o?sTf`{oWH`B>-W|W4WPFcr9C}a&Si)q8$si!Ri?~ACR zfCI+wjdIr2`0VYVBs6csZYVe;yp6NA)vSJlFX2^nR92h!cjD{f&nZ?fUij=0w`MCOhb)BnE}xz6r1Q59H10nAul*w3V9<623QY!$yyZX=HjFZF(W~2B_{Gei>3Kk1m>CaCqusCM-i=+|;* zmna68Ku;P)l}=9ji$5{#)yNu=ONlGHCwsA+7Jz#lKZhaP^KvLWD%2G`Te&LZL<3=M&R~RK+TKi@ZDz8JyTAZf8oAV#f$rx%?4k^ul-GY5GA}p5GCFNvf+dO5#1^Vl1R5Zsu~r&D)4?4 zuRhm!_-tZybHSZtxjE4Q+F78{BGrO7M47Y`a%#Hi6YYN@gPqe&D%SXu{7mt9{g;Sg zK}0R|D!aA=28^TMM;`7TO>n-Eo!np30iNdZs<`!bB>~ z*5q8p63$2U#$@-eowKSrZsT)f2wQl=v|?a@pEr zQOgXw@Qx|;ojtTrKOF!&=_33Ow&vQdpJqs*EKr@kLrnXyjy{U%)j?;w?T8t! z91rKt30HMt`l0);ErurWIBp9=j;KiB*;O^0a$Z8-4_(CkfTk*p*&)Uek5N`xYn!x7lXtir(moj>dtG`H{I(#si1FLhp-igwYtUe% zLhHPrH2Gf!SMyW&`MXF1b_}3NS zcueqXP5E2OjMwPizGDv&mtn~M-yBHl?z#{*Sm~5{?*i8zWXifrWG6~B#P$h%@b#Gg zA#BOkM-=<9I${g$L+npIadDQT>d>V70C9i%P0Zg2^FcdGQoIrf9GeACNuQX4HL`5? z72TK1RqxxXiK~hD4kp7b$WwW&98uq|QOL;lyfE{ouaL`s< z=M0JM!+#n*TZd+t_W3;Mj2Bx+24A39X=DEKc8s4;vp=>b;p=r;_WrX&VIK&Rr<2Kz zAzRwtd#D|iAzaW(BkEhezBPD{9h7Vn(6%?R?RwiSbbI)$oCR2?avO7P1%@^twPc|Y zVX;4?tPeL-rVa^~N9N3WiBbjC0tK}=Dv{olMZ$Mrb8)AVAkWbqr00X&V%dn{S`&Hm zEFCH+$H`!A7-0`0roE-LRn=3@nUY#{-k^CB>pW)C)oYCF8Bq-q$F*9{xK>etiqKC? z|4sUk@225iJ!31ET_w#q)ume?EQt`9$ChVB@}pFS`}E;swIBc?ats)qZR(1Zl+zu4N-J@ zM{^<5tFu&Xs8l7-AnT;>5(l1EL1dbGf z3MH~7+JCIFcn7B<`CJp}Mk#f%2m*jbf+h1&*wFo<*mHBM93TusvPax-53;H%v4ap+; zEA&@Pa#B7qM>V*$%iT<9FoYDr`0&8e`Sc>(5TRQQo3-0;9eSHhXe~*kx#Mmh6&3A> z2M=>AJ_ ziYoZx(GvjR<5U1qN`+_M|9=?yyHmo}?T+PZ=^7c!wqccF>papHIz>N@p1Z#|@5Gk+rY@N#jO%9*TmDAX^}d+*5{KZ%4<`r6cS)ie zf#7E#T-|tP5U?Hg0hVgUxk=EQFC6sby)tDpCP--XS0?K}!Q7`MAMWaF;=tR9sH+EKESfoiZW z{~nM!;dTKT0iNGd)U$URY#PP#iPX-ZZVHK!GU;#h@!#E{>~@H<4=@S638w;9Q4LAjeB8jQ`T#8(@h8H=AutYBtF7G@x|ye z2G>aT17DIUKTR^nw2tCFg2=asmHHBsEkQ0eZJB9sB?{}-4g-m$>FilDzN%}BMM4VG zE-)Va$10n_c_-HAXop!K8kF^k8u7W^rd_3x*Ar=3JkKE(5DH_AKeE%^U-{jLvDKCQ*JdVU=jGk*q_o2Z`sGkf1wWr&tYY`z%K+FwYrz5~)`Iz}1$(FxPK8zS zd<*dYP;^p8S{Rj zPyknweF2-I2L@cIZh5!QV^U|%W4QcAy_-rr(x05Y+yZa4)6oKt4QJ<$j_Q`I46Fl( zHw}I{k5UikY7rdzvAUT{Z|gvTe5xY_!iG(E5bi%)6M4_j9 z&qm%pSU_{WlDK@(7b3<>I)2_jVT~oTLL#YFDX)JTE%;PRIIk1TRpGW8Q4{gfxj`Fl zhqt}LXXRMP%Csp^arYQx8SVkgj0AtA2fqPvY9klA8tZQFqvheaa}}@iO#SzRbne)) zTvR(e55oN)$N^clZi*-S#6(hBQ}M-6c;t!TCoLLd$8=1rQ9+y(T$ihB;l00m{v=v{@!WXOPi$eSq zyG~D+8MnVU9{8MR5r?6()=HJSIjQ6+X%W^2e4M=jhX<#E3Y0sI@%0eUAiN|Lg_fAo z5UOg&ikSk(F1V}UX#XH^0b@FRsOrF_`npm}cKXgThlMgFch;xuzLwtOeYEtL?`;eX zsCr~1^`deo0T3-@MsQye_;v=Vrz@zoV_dx~TpM|`5B7X7Gd!&2tGLo1!p*QpGDN!a zWdG*67}lT3srWbkAlSltA3;0;m8mN4*EW=jb0e*0WxEAb0>&OEmWM>yRit0x%kCYc zjmi2BB*0xK+@nC0@EnDUV)zjUAl~PE`?w>XIGvB!M|id6GQL3{7Q+I<2??MFfE0?7 zjoy#NV`*E)>TVU}b0Q`_4ciM7)yk^M5cHV^BD+7x6{)6&0$*LXtH=xg?a1IRa?V{w zppe~@c>Me$c;-NT3{Wh@i_dmIj0&Y8U7^=m>K9u zv?zA=jLDk_lcZ&5fc7_HNF95KhVj^w#Ht#LG^>+jj?s~tCP)p6C()t1{aH}1*&K@u zuBgn7J=vBIuw=Qe-3xuTGHHhM%P>1gGr%=Dk=ebqiR(%k?)K5pZ-Bg#-(@j2S|zJi ztxWNr+Tj4%(8cRX|{U<3-T|9G84U;uQctKCGZ5GwI<{PC@mN@2=s$r;op zqAqQNQ-_IO6yJ%wfgWPDTPIg_G;b{gFcN7rIF*0@roq$anEk{s4jKQ{o&NXxN6%VWs!g@{lC z?gQo`I^}cV(BJ+=B}tPt9qzNv;-2?TI2n3_{~v7Iki+&CnRJDtn|Q9#K4?hesoo@ z-^_I5YHtpWp2at4WND^-CnibiPR)cUG3HEMu{D)ox6@JqJ^bmXpOONVeyJOE4qw9_ zx@31JufuJL_-#?m>xO1lQ!8=J9_`|h9XwKW$HER@!q}#-tr8aK0p%r0NC59$I?76E zcst(P<}DUTZsMLIZb;mBmj-Nn01@GHH@%Ru$2(so6SvJ6_AO~!gcimR!$lGxF)E^B z&Tf}a1LJJ%OjE$AM(UPk0qhjI1F?CjA!G}lzK{jCC{hG_QvTpHC9$*c&ubwMW_ncf zCS^eqPEG!0i&EQM6q95tH7Nv<8v#MHNofEklh2UZO_*Za2?r#-j>PhK5k-@Yg{;x0 z|BOZw=Ro`3Ro#gvo)X-Q6}&W3O|`$xsA*|``M@2n#2Te`UA{6u!lv!053(Qc0E?SI zi#13S_fS{eKUPIBg31tenxcwou?zRG#6G2Pa3k=yH^9>D;Qa0#rPVnJXa2YmSdp7mnOt%duMlh$7MP)a;u&af$n!Zbth4bbPT}n*OJLhcBZ*mz>=V@#F%nk7nbc4uuKE z@)gcSk*2Mk@v7FNjfupICURIML)n~%gKjnpIY8>|K0A|l{S0c|pY69bkUe_K@A2GU zugNnP+&bwxF0Y!DQ7uT+_`i3Hz=nzez3=SR6z`Py_g(?-FUj3Lf&uU8b9sVH-oA)X z`K`bM?fh0S30&ar(oi`fl=E+u9Qza#iP+1=E2yS*UrztR|MZl`PMP$>+!E}G!gVQa zA>-Uopm6)8T20KYyCakR4B7tI*X`Xd^EY)))bx0Nt>ql+ia({&lA03lzmp7kYVjx?!|c5o$HJ- zcPe_vf)8gcO^2E&gAO#oa)(ej=uQSbtko(Q8#FIb&jymBIkb_8mR#pd2$5wU`EiCRLS6HR)Tc9 zCiywQcfA3-#UhHk);S%VZTy;WyG|y@dNvea2PM27g44(7MHtICAab|Yx&j}A@-8PA zr$o(HWKw$zoA&n3ckV!boJdRg__b?g9W6@sDf6UKOfX-I?X;t$7MckTS;?@CJ_H}9 z;S3})$h18)fvnfPWnUZGHjY@l3FmXK2->HqOAX2f1ELopFZU9rBjDbe8uYf5N!D;K z)=+C1Q*gVMs&C@5dwFDtJ@%s#y&Npk`#~yv;Nf~A5^5&6U&&ctGCQGzI_Fc<`d4R? z#OeDmmmuC_&8>p6_;U0lL)m1=mDWta)jg2T+G{3MvvIV&%$1t0`D7T!_e9tw->jo& zyOSPbd&K_0sF*SRrwY=%6s~*%Yy5cx6F|`q-RV2KA14Ry=VK9nGT{n2!Q9^7QT}@D zk`l%CINjGeX4AcinwfxhfXp^&<`tPU+JKvfeTOJmrn*-I7M3I5lUgwnvPv_MeqmZ> zJ<0_=Wq^ledRQ9~9H#dKIeypUZj1H%dhNp0Li{DEs`8FPwn*f`uMg9t7=#VbNBw$> z1aYKHY!d`%iiHMm-s4y@vL|XR!((Fpb}Y4t@;LxcnnBA<*2aw7A_wqcPa!4%A8R3S zxnU_hiJWHoOrWG@qY>g2CO0#?x-5&_s3$FVbG{FGCgbp(VwD6|)0TdV-Yn1&H0Mmu zWygTy)re{W*cXClnt)ul%6yv{7M2hjU1+Y8G{g?TphG>lwu`qn-a4-7)<0Hlaig@( zi;}H<@AB`|MZs)xkoBY9xNQUS)(AU$M;@Jt7UO8<4%SSQuJDQ2Z^Mm&+=Asiqu0^FNG?sg8oUFGtjU4!)ax=N z1(Zkbb0!CdGdx)H81EF5@5BL}??dsw1-$lg(EC`b&4{|EQ2Kq08ipy?bi|81xMuyx z^EicVgkpj90pnp@5AZfTti{@Cm$nVL#=N9`(TK0UpTD=O(ocVJYa%759BwQD2J+xT zSm;_1icOV=3A_U%G)I->)b~uELe-!%w~G6U?zSO@-v-unPzVDY!4<84t}ds6 zt+~o5Xro%oL}3m!1;~THJzX1)a>!g8jU4|6@n&cUrLz8byIS4$IeumYw}PRRYoRgY@;ARyp* zS|;VI`M1zF>%9O}ORUV|1l$v_;}Q~L-Iw2g?Fu)C{s>P9{ogCPuGNZ3D>Ti?Z>&YN z-!T-E;)b(_6AwvxbZVGy(yd_t+b-6x?h?p1LEYB^r`YCy$U>Jk5Vq7A{U$r{#R!2h zwVw<2K>nG?LWWX7fUT$a(c;cC`5|y6PejR%FPm&l`5pa{fiwpnHr{fyRPy6_6=`J< z627?x(&1Qhy`DWjcq`6wU+ltvte&1lL#w)7IdIzvt9VSH`Mv-653_b>0H01pA3&j3 z{_kP^L)EjF@TMSD^Q38O-!yv#Z^gYR$Mwnon>skhXVEw?|k*Hogy-q74=GGu&~d-z87`^ zE1HfANx7Y$&C&X)m%!8&koJ*t1_bPB9NQ+*>LW6Y@WQ`P95&^?A}0fA=s!y zv-F^$CC1cDEzQvSflRMyJ#NQHoOJlUZE#8*+zbuTv5@O>fi+v=p_#UAMUF{ zKm26}=L-Zh8uWnCkbT;XaLdEDpa_Ru2Rlc;3iFdAm-jN=v0lXs;u7>!Zx4DZ%5EX6 zVk|f&-<%5jJ}cB1rr~s87OyI}y+zKeyMB$nke%=*2%q`}rdP0REY&nTr#K&PrLE-K zn@*VTd&g;xw)_GR21bq;4TiC z^?1QB6@S(3jr<5A;wDlgY!m3|UfM_}Cqia5RJr7eX>&QGKtYp>81wf&IbI41K16~ViiM{;JVy#S7 za4SlatMDlReS{&c)Eycjd_ngK&AALE0bjS(z)n*`VPX2O;!C0xd;HF`_qU@xmBw{E zO>#|J(U4%tx?5r95>3HWQ|u8DYGx7jds3BjEC&N8S}DBoGt%+#q_do-MCpN{TQ^D7 zF^_KxOZp;073n`SL*+02JHFuoM2g0fLmcd$H-v-KUvFFesUk?Yak+;G16@=?hnBxs#fdSFo(k=j`WfoPs)7_A_Rkf~LRN|CyP8!1u+L`JokDn zvONvqv~M`4NSZg*)Zor|fQ!8`2Uzo%R2V<8&KqtEZlT|M(L3F1Wox?E?;z91$HpE^ z$HHj0j05})6q@;;*}>kbgZZn2H1m!2Q92+Gw7$VZD_0NXS5NNvD@dN%p z&mw|w-b>wfhtCMe2G~% zMwA)=E?myBI8fXWO;_5+toTwd_HU`CciKC?a$1wD9q<;1*xX6U`1^4veI{`*d_(Eq z)qg(zFqqY_*-t~OZ7J4<--cN2lkyIr?Xnn`bV4q^SCmsiZl><*oE4EAtT zgM%McpWFYuXI9Hd^AlqAPtzU_6qQ6hegLNP`8H1)R;=(jlOz-oau9)SY({=)+80nhV4^CIG4a??U02r9ApKvt#4}$nU&Skb;jQh4_dT`rU`v7D&~l9sc-~t^*SVPDu#>NiRL?AW`ezh1 z_e-dTk1uxN5l7Bm*7*W285CL=VMdVjKU7Xt+&_8_sklPyc>pSkHetMW%_uqrKOwF% zNM2c!UXf=ZYM%aJl2EwIgc5x2vDB4nPwF83zHZ10NhsTKGD67xVuyG)Wi2Xdhz!|( z6jaW?3Z#!rhS9+Q?om|pVQ-kLSl>2A?@Y=cp>^8aVBC0hF`M@^Jnj z{g^SZ2Fmaw>Nw}F+E9<3vih5{ZEpUF0h98`^fu@-5|5Ado?}Ln&zx;1hZSskQCwF1 zBHq8kxLKt4)dvxm@_~Qi5tGNV>>y~^i8uvoqW`|G?gL%HDCRsoxbA-}`Z4{9I2|$2 zLWCK2aI7gSyPsu}M(}A%bgNN!{Gnw5+5}grCgr9d+s`J%;X-`3fp$%ltGmwm&umG> z-*|{|D^<_38uboTB=jb#XyyZv^E>wn!1i?=;fSBt21z=7q2VYE0T5Acj|aogW-X|N zPteeF5zTB4WqwQCnVpjQ5HcHLV8k!ic@5!raHY%`*tQRjxHN-#PuSq?TbZ=ylYm%U zF%$Z~MweP-Nqu+QHmZ5e!ky&0fgyu$kNkC}x0n72wz%-hcV)bdysDR<=bQvoqYNla z@^N_R0T9{W^jP2{tf%(o*e6&lUfGX`W1{>@i*YZ^oHSRY=4PWgxn&TQ9c#_m&g@tJ0<5Q|t4THIqRM3w}@2>g&x%4Ai^{HU9L}OZe^P$QFN6 zb&Ajsh175xiNE}$={!)-rWs?AqfE5yDPMK zcj~X*&b)2623u`v?$0UtQ~|PPARFLPaZiKaZ&TC7-)?&6^2S~^CQ)8*LKRS;y`T)tnW~a?0?M4R+no$6GRtj+!JEajD`1nVbg2oDV_9 zjEgMZf3~*=G9dY*Pkwg{pS1U2m^7NJO&pPxBLCFU3C1Z#58?-&Se_?OVAjo}DsL(0 zKqEw6G^v+^D96Ptm=-*M{-jb*hJKcr`yFgI$+V5=FY&iuY&JTh?QE>SOFJ;ailvru zx?ao8x%2v6Q@^4laIS0Zf@+d3%dh4=?cc92&pO>A>YHIPtWG~8m|yWj=B2WE4(C=t zK_4F-p--^&Y5oM?v?NSTL}6f8dF)sI?LT;%2a_C-S*Di z;n^WS7%f1`pT{*DFu|}NpM>xV`q<0?&w(VvYJCV+SgsvY@~dU%fQu6D^+u;*)a(~t z8O6V3p(>d4%)BMa?6!8I>%?{ zoB5oL%Kyw_-C1cD&)>MF6m0=_hx#thS1pVM&4W~(eX>O-l7~w{Mn*@7W;g;+XmMgy zIRb8G6+a#bW?Gju3=R$wo=SNx^ooHYFY!~}_(jazA9xr@?hK^&PZK@_y#?W8*)Xbb zFn(P`cq94lTP=9b#waKk8W5u`VKh!PBW#+Tvys>SPOVNiyGI7?e*pWRh9=!cqbahb zfzhOX?m&NM1$@bcchU0;o4Kn9S3E@#@3E~4>~uJPwWCheT5*~#Bw{_#HwG0v zUI*>hYH2NP-hXC~IS!Rvnzpw*?foG%FakLaKbdMnBe4%8T`{Jz7{)3~V?dr|ngq=g zT?oHIp;usFKnqn=l$=OT-`7DfpqbG|=-0 zY|bxVzw=!I`CYifxlaE{EB(xVX?oB3!)KV5OuxQ*s7;g|6RHYZxH-NOh;zKSFDn?| zzz=ip~7|=cG)5KB6YNNDUy=vGLz5bWkCEO~cs%&fSafcoloj zhBV^$Vr>j{QAwL7mz$C%q;LU$R4^qJ>EN~xH4m`T^Z;dQVEy<}9BAhz1L46B+2I!i4Ih2K~p-M7KAB9sHecaj)WcU)Syrtr~76 zEhb4&GBoK~Ig57G$@2ZVH z-UUD=UZIx_5VF~|zs62y4{2CAB0IDv2mMwQ#_H(m0Wz}jF!2K(gmDLYuBVnDuzl}b zy`f1*pFu?19RELSpF-?t=96P>TpBj}@6O51@1p0<*moClz(K=2!pGg zLst_c%~+09oVp5QT*@MLq;n4JZaKZ4W&`;uz_c&@zp7c!ImdO4Xujx0q(Rjz*ssco zeo39(E*EU4joW=~wzaozz`)0H(yA&}v=WXe8%>Y7u9Q)SZJ2rKc3xuc!nN+9kxNeU zj|ZK{F%XC;AdpOvu)r_Y9%xX*s&Q_F<|q0dJRA-3nbkLwOa!P9_ba@+*~{qCEx^ph zCDI!Dh13OZx7!O_csxM)31|cInUr0K?JqqQ%eA~}f4i-J{oh;G<`6gj;M<;{;^t4- z(4bC*+AqG7eK-{<#2G5IbMnD`mbQZ+qPcA7Qrmu-m>)Y*)6@fCLRS>2}I*4P|$aZ33BE94xDfs>PP%h+EA3-}XF@=(I%*S}8igc7fI{U&0 zbdBeWGOh6P=@3NW)P@w5Z3S?SX$`%=?l0KrNdNuz91x$^DU8ou7Jh*Fb){6$^?QHN9=l==@`M&P0yVJ5lX**nog!)?xJ~$emgh z^$nP|g6Uj}StLygK=(0$6@dmhGnY1>CcUZ?lYEI~#nAFQ4u>=52m9Lsi*%6yTMt)z z3_$Yy!HO7evGBeq)TbR$u%xAyG(QY^?cpUJ6U;^w%UG13Q%Ym)p1J1K7?|>GSYis;aR2Hr&V9nF)WF7 z@I2bU^R*QQP}})JG~?8>Gp*|>R&ey3R_AuExip>Q@Y;mV(Le1Wr&W!meuuGnF5t$j z6xwp2H#H-k|`=0lpuAPBaN1+O8`Pgc!JpglV&CLTkl)tp#8c>RfjxdxDB3)CG4sed7SZYXM7BjR%{8di+;fU$8m7$G0XdbOXLxD-;7gCfcco&*RQ% zh5_|T_f7wn34z{NP(s0a^kqt*(o@g;XLVQC)mr?aGR#vSSHMs)tm`tp z6y>fpk=9ojjDm7zSfE#aLtIHI)2ao1;i;EwU6lIx=Jvlr2VoafXm76_J2(1a*6!wL z2F9pPO1yj`>&tTI?4asL+9IU=4k*ihZ=4n(HVhzP}jLmPo^JyPcCkqYVAUXE?G zo5&Hvqn7Gtph~!h@o^v>IY2uv%D>;1#2~(t&pa`ayGDCfzc(Q(G;t%$Ua{@aw3f-XS0L!hc}~amL>M-Eqo^^W*Ta zYOgjm7a##u``}T&ff2+MdKDP3MbWi!Atj#rF(Qsy+3dof3kVd?`bQP*jk;3Hz)eM> zyke^1MWSaDsv0l`%5P+-ME)Q8%;~?qDtTqxT$ro(fUSqHLk0L~QGNkq*duS~Aab?B zwqIm58p9M;x{hps=VgwtHAfDe2>X z!h3)-5lwPa5SyXpF6%v9w>5r=j$ePtw0ZGV!LYZZBITs+vrjpAZ5X$9|LXkVuPuL! zxar8x|!sS9H+)Q?aCB8pm|Emxi# z=rTGEXjuQ)PiiR(ORH7Uu33w$m~(MvD3BwcIWbfgSKR@CIpek~C~vuDzkmOkY28H7 zwOy5ROIS_kVFI9qc80|DAlJZ+TTu$*7%@86od&D4ZQLn%nnvE~n`EC3&*jIj3yR2@ zuy;TktoyiS2%qh~1<;%7^JSi}R94X}@Dm0W@2~wPbIc=pzS76=RcMSzL6Z{SajE;* zI8VW{6IHS1^l@#IcVk7@S43|(>I4Rk{D~a8U#uM{r@<&Okyw;SH*MYGq$jEQ9&P94W_%cXc)L|pfv$<5vX`Pg5S(L zbYh;?LL$3T0xw)HrO$R2&N$Eyvy&p2AyQTl%jwi27-kGZ;*XPFEB|qAw(LrUdu*2! zp%FjdF(m54q*4vdtGHM~1Ml)-xc$`akyFG`?O4^2IftfbO#l^|peF-!nAQ!N3ORKz zCPElG7eeh*)IhE}=l}-r3-@TRkOImckE|c7NnP0n$KG)__VxX}aO3oL7TzXmWD%GY z2u#`v+6OcV+9}#dPe>Um=1#SX2;uT)-h|5~#TYZ*RRsZ=hWUBe)`@9gIsY zs4C>VzAn;3T~*4CMeN;A8h@o43>g=-@|`U%jzjn_%@V^W$z%7Wu6jv1Kq9=*Jb-eV zS1vhL;YJR%={OfynIDFB+u&6=4afK!D*A;U)zeH5F5c_g)zA{JnyH~*JE-}eh zEP<~VIT#NH&7UcsI2D`bLECcRv`xa$tusig=k?SSpo}&WQJBR}JV9AI^eroEj$2OF z@;|Om=2o4S(?aH4>bJMj3NBCjdkgiZarE%FVN=&UB1&J@#f3O`Ei!tP3vR2o7TwSc z$bS9JqR&+mW!y+?ZUl(XMMZ1+(dEQOmE|@|^BS9nZWZaS?Sv}`)6nMhKUPt{U~P-I zv&Vx*9v$B@4sx!PI~6`8%J+?fNaP-o6_R@7Qx6zQD7`Fqj`%@XyRFZB$`Kg@_alP- zRGp$#el)2|IMkz|&}C+Q`9F+WdhKn{lzBm2z2qYLyuEY4&?|U!059FyFuDY~I%VL~ z;8eR;ZO*j}>&u7dDELRxCQmZM3)62JzhKN`^gX|9k|Vu`R~CR<=$#X=%@zzy6(o z=fOroMEBvQpl^nDPPw||ZQ95zDx%i-rF^8Vxof!2EHbl(e-TPc?o_5l z)?ng~Z{G}ygd)0P?+;&XslW;3?vuXfbD&L^5r&2dVKDeUKvxJd>Ey{nl8Y|9u8GYD zC<8KTWE-cP*64IYshdw?Xbzn>Jo}-HEEJ62pkmf}Jo$0W$KC5qlxej3{>gDP!3_Pw9!cJS$)qgH&qYb=j7Nnk+3Z8X zWAh}*N)K0!>8fet(8Hm2NG=i3Q};U^&`41=Eba4(m7ELznMtf?g>*aMaT)D6zbdjO zd+e$UgO~T2H4L%;GRPo9=?o&Gfu8tZ%-I770LuZh5vKC+dL2o7EsC?g84=eby7C+6 zRJDyHK~V{Tgr~GmFgcjTi$0nI$pumRs5Y{m(dUQ)1+%%W$Q17P-r7^U8v#yxpuf;9 zQ=i$6o|=)afV4fulaM&m2ccRAn?HM&g4G#cnYzOJlwvT6n+{s>%{2gEPrx=-QI_EO z(UJ))UT7!o#DPYilz@}pH7C*+&P6XIi0^}l?@;Y|)e|G&98@`_5k`-J)CJnHYRjmq zQ_;&4rSxwZh{BSRX+1ByZ&vsWq7(Y{ZHSdSs+!)-5ld`jaVP3upfhe0@l->SgGAQR zru0m3DqH-7BYsVRl%<+r6kYu+C27@M+XfCiDt3n2ze&f(e|4v;XyZ%P$<%EEZKmce z#@~roYK5EdkO!fihw6n{oM((V93RPkAx}4CQ5j@v#jF?B6t=lZF7jgy%-pmda{cJH z6Ua=M@jo@LHSt?H7MrdP>D0wuPU|blOem-Wo|S{A z_IhqlgM09**LD%A`xv4z?+F8614(lF=Aa%F06~j5z8d;B4C?#OAhOV78R!k5HvIXC z)6K$Ax#@-f&5UoWyeJ7LM1(6$oEWo1>6U~CSeu2~NUP%cRvWB|T`!K=oJbA~>Jdyv zYd{{6Yi0T}K9nbO_YHKqTKLHlfVT3?-yI(?g2!?pwIT$^wom@SkZj=IEs>;ZQ-QleP8-&;!>Dpcaq5t^F zah3MDADM{+)8jyTk+2Ml=rQuZWkPPjVMzsD-4?A&l44xFTLGFXH7rSf6lz1$%YajA zwDr<*xpdBmgq|Jss~f!!o0{V}aeldgc$>_h?sAY_1Fc8gn5ore;~PDXXp& zx{={&DtIr6y&&4uybwL4_F#z_SKrGXP8$-OxM_hoqaqY>6qw?vY_U_Hh#qT-8 z-B7BxlzBenG*{m#s`!Db0~K31XJdK?Vuu^TXD&o*3Mr{dBhoGLZML647Kaar=6p_) zBnQDU(In6T-gAz!?t{Q|A3g3b--r7eEsX5yR0J!k=HnZqEyx6DR*s-=!0!yI`5|hK zkoXPNrsBir5O1ap;J^H57i#5KVGH~tytq>wX_fzSY*GS{51~Ih^vg(%y)`^U;8vW3 z((L1(@P~qC(*C^EOf97u=^l>lOe+{Rfb#Sd1Uz$gZODUS&^a{5wi+FF;rMPZgYMD! zgBPf&^E0`iIeM8`+)B8fI;En2ExhV1p9}K#jy>qN{=wY&;GXE^my5-gLvH5WI?z(! z$RG6xq<)5Eb3@#A)i7(5_QTkfaF!Lv%e!s)7xz_}9qsL$jg@26{6?J}tJ{Gl)Qh{J1z{0G2Xu=t8}Od%ORe z_Z=O5dTz`sIr}I>gEV;RLEq8A=xSseB7gtAO@J2;N2P32ZEK|@3tVs2o(f6>5%Ej_ zrN&86<<@?IBrCM@&SU-AD*|j;qm#~QZ`*EA7rB#!eq5Z2im@6qZUFU;79rf2-M$YL zUS&RI7i-@wNB(Cp^#;6DJn8DT`!-s%!%%M*+2wVoYGe?mF=x&e?dbmteo9y4YU)Cy zT>V~E+*^K1pHJ0k<>!c#&klBwslzIx@4rP&`oI+8|Am zto>tK0e>QSp}XE>!*%u6p8x5*z45wb+P}#J4d$OvzKz&Z;W%z;LRcQD$)AEvnn!VW zU~CWt%ZQWpxn0hp7joj;1B$cfs2`)@re8RNr+S!IMhY(iEn|j1NNA@ntcb0r$EB_+ z(}ri{sSd4?59;q)r`pY%GaqJ)N0GVn$Hz2I7_3CP-s3lWm9pQOxpsY8&Z7~p7yp?F z>Re%)XR6;HiUmI6Z1j6kK~X~4Dr}n4|6!K@{zHfGx&;+HNn**7F9GkO!=4Pd4g3** zPD(ApC7u)i2%31+j7mXz(h==W;bq8x$<^H!jXBP;`JA@ulGi_izNGy^YcM^G9bK3Z z%qiOW0>OS@u2fI>>&){tYo5;}28j?dPlE;vXC6ykgs1g9&EJ|e+U~@)?MJ7(?*U0a zi*rkwSCRLfh{ej0@W+Q`o^RfKr@C<=bY$d@^=l&jlq8zpvi=g#uOZR>u&{WB{LaRI zaCjZXIA38;3JMt4?3ZbgE78c&(=jw3{Nc$gPFLk`!G_y!ZP=G`xIY{SMzF>8Q=q*< zwXyih-{CTHepx*xxrns_i!nPjw>Q|$BSqAe!@GtQac6;3Wm5*cahQ1$i%Zs&s~DQ| zZPcb!b*SYT>qNKXtz&Df6YsFuHRUzJab~d$*7~IhzDfq)eRD(`*m>F!QGu3S)Pe6`2ZLEfF(7X3lfL62YZ9)^_6^$?KYg2&Pl7j8SJ(fa57LP&1EhNf$=aT zDq=#|(_p!2MEtAiYD>_MzM!b1-q>3=Ju!I^@BfPPtlL|Jd=>0|pG9xPOI5V1@P+#B zMYjeido7ugP?-3z{p81EyU;hT0nXdXN3J^Zn7ir6wxEsG;<;=FJc>Oj z-M!9HcZt%qyrD(k^^5q!njw~FAKlD-b56VE#zU|2v>*Pxwe3#l<}o6=%Ws7|FG4VM zA{um`Kh~Z2qok$4!i#V6a!3Wrt8ml+B!Ycd42GktHcJf({6Dj0*Uzo+lxwMi!}ExL z)*%2a7ci)zapc#%-2cqvQQ>6dY26UH%zGpP9UbW>-GZflvt!W0@HvZ7OniEe0R%D zm_9OTf?u$SXXw~?dMJJR38d-tc7e{m=d7^92Vd-3lkHnAm@HCE!3v}u)c0U$UBc#2iF2ht;+`2O?$MDn^l4T7FD_1>rp5f05YywYRqDy9&}`HI$}XZ{Cpw$w&) zTgW-FMVK4(81JOvw?4C2kXs1@x;Qp}x1eWAcnnNtPYwQs9_t^+=)^9Q zs0z&Or0iyo0UU1cg#~>JYeaKJ$AlLeI5$n&-~7%clFFTN}6RKgzv_O=Z{E%`BlHBj^| zx+rRUU>G?>rE3#6Vc#_pvy|DVcHzljj1{tjlXg&~RqGRDVTX~TDB$%*6TPvz;EP@DCT1-bddYmie`=f(*v0 z?W!JfD*Go7bGVw1%;l`G+a)cMYwv~(b9%tAwlfC+W2RShB0ck9pPF)>ghoFt50t_vj$cZjgrLQ|D$&%@4|K{w(9VMZepiy4b?kO6w}zfOCvVQ}AZ$z}xu>FiJ1t={ z&JuU-7PXr$xAsz>;asaroli}g#3JF3bBN+sd)(aNtBU)$uQpL^zY@{{s*=W+ZHPF# z=2Zrn2&Ml8<-6z#2JU^|E78tL zVsG4`2M>S|`qlb+!@zGw6b84z6nhN%%YYa-+mqr;Sqbg^Hw4hTh$|rQs2Ab)&|{zB zyZpNa{-bAZGi(_3a&CHb57ZTVZ`mJAG{9^+d<875mEmbRX`ATS_-g&prkwCaZSDa< zZ1s3jjgBmrl3$;0&H}4Xm}1XAT9JtPUfC)3E{lZ)+mZB-4Tlc;vrIEuuz5v6(gG4? zVRm6Uwq8P6;9C{(wZ%i!%IGb*4S(De8w2aL>dU9?HUczZ&SzE^s<&u3IVx+a_=kMR z{2ur1LC(2MBlmjK#gVjggrjLR+l~}k_VS>EsA5o1EiSmGHo_9lNUub_ZwWMJd{1A*I!PD$_8#6H@-(0YiQ`Jm;rbk-n>QUOD*%wKl*eI z=zFl#a)m8&d9T~2?x&db!K?Bb`dotbBxJA6I;~z9QEEgK=%xJ4=0>|{yWo}Ed$u0` zZtY>wjfXRvTsg$6g}^1aqSOpV5D}k`^>QPSh~9%+soRTy%Jif0%p>%vAzVM3H73`K z;Q{ZWPuQc6hTY6?QcA8xTU=AiM&Z+S!y#lczNCnh1xm-sD9YD9_^=>K^|n~nwMf*I zClierew%pHn|c|MgY-iZ7N}+Eej<+hK<#?QXj~4`40erRpR4H-vW3TL$C;9&Pg5j9&xfe8NKDgOaSjjB2Kk$|!@5$^zWxhTIq;pQ$OZVl&!Ub_L|@seTk-K!^Zk$4 zW6!N&PUDzwD#K_{nta=N1e`A+MG$AShRnr+JkoJ z-B>7dabxs8^np)y|Na{N8ov))m8ZxT-P`$dZWU>mne0e2>MuEYR*5FH&@r8cFBOiE zr;=b!ap)wD_IvIAXTl+ulKe^EK|y~~_fsgd?Y!;>nbCeld9!`?G`i5- znUDpx}R zWEfe*`jbn4v-?j0K30gRTP6rvS~I^u1^n4;4OcDC>~9lhvIjQ!+#2g9DAvbRj!dyw zMC6(5o&M_Vj5s%pHX-zEvt5Nz#%Z-tr0Z|7^;CE0yyLoQ2PdD--XZ1O5G z6DLvQPLL-)ExPtiw|7=FhrFj_SVVJfuJhDiFGUhWN9f<8RU5$=hFT1<*^e`gn)THb z(h(o-Flsu$2pg4s8e&0tpxw;s%&F~h(5#NoqEgpXmYCl8^IUh^2z?fLT?(RsXppI= z&Lj>d*f&$(42`_8FnohYDXlM34qTahDzzBjtCT4xT?E+mHq2fS5kT^vg6UF{uHvH7 z_QYB!q%xaCJha`*vyn1~lG0xkCX2me?=9g2WFh*O_>I@wjE6((e7$)}9aU zo42cA2iYJcX33?iIiC6`j5nC_?DMVn9G>10|Ag5pEK?skfn0ee9u)+7?;Erh2V1~X z*o0%e3@SHgi;nw_@Qs^snKyY~)KkiI$A(O4Mj?*}q{zOqayOy=xV%F?8}ywJ?8o}t zHv5&@v#0t8ZcZS#bDk^IVp}5s3Ay%eQeMHpdL*u5VaxI_qI@L3Y(mCof9ryKXtT2gJP@?fIC}U3a)J+eJLCWi#BHqg zOc%a|pr7>@XT8)7q>CovTv>IhNqwMs5Is_a+24Z;z`JH5JzeyNHHZmO@P42hN{GKD zqUP7p^ak!J5Yldr_HwPRy_d$@_@YU7#oc!PStvx@5^rSSYzZBTlB2D}fhR%K@Bf*N z*pNS%U(r4b@iioh%PlsQl^1Jk1lNK}8Z}=sp)k4S-2{cl??`@rw`jydL*)6fw0me* z{4Mbt*i>Xvv|FAwM-UJK2}`Z`puQw5NN}ZQ@vTDVHG*E}R#UUcGtT!9Cfc$oS!Zf_ zTKB<#}@DQ3ozCcUDDKrq15F$+dKFS^f*z%unb zJXcAd5(2Wo&^61?!SHNuUfY7E0??Jrj#B>e@BuUrV9*FW9kI!MM8hASHBS6s{s0WX zHw`dvQPVgA3Nl7J`MEZ4gm+cCc>eLak-Uimsh5x$7T(=z75h()@==+K1yjm41U!tlvr+9XK{_MjH5G{dCNKy`7FE(ElVx**zG6}(H~Iru4SNjY`nDTlS8 z!gxdk1SdIur%w-~V<)%oTHPq#Tm!$!E5$`qP|7bnKo+X!ApJ0S1cd4Fd_cP1(ix_Y z31w)Px%Uf`YWI0+T5zJpZ?C|ddz!7~;cie6MQffnhrt70iJbr#!-eCh?$v9H5LfgTaf-TH zbk$}QnMPPB@CU`MODZtlbvRDmVHxCISbeF9h42~cS^-`fft{6<(5hhHaG9(x4FXqt zue^8cFD`XQjf0VF-ts|6qj<_dq+B;tzfMEN$hE(r_|hR5um+2+r8=@N81%4Jzf|I% zphRN3ZLm$h_gAdI5@XADrSFITD=7g#r=Rhvh97Oe^CWh>|6?Y&-~N79&@MzJH#*w61?_au_DhSl30;Rs ztc|!IHQHZeUOyaGHWaP4FH?_F1%HKxzB#^vfqde3F)P6>kqs|jAl5#ZX1ioKO!2B% z4?iE<=S0Ecf15pco!my_0Jr?KT&OcdUX|q+@?y&5!7@Vt)IfUpm5`?LJcYIRl*(47 zNr>_(qojPK;|#RRmJmevJ0+`z;Ib_o2#$e3rGwwMq(~P;gmuEV`O}NP%F9E zBOkOwJY$imAqJl-?h%3M{b!TvZ)KrUL9A)%00o%{GMe&aR_NTZe*afNC^$()1Ob$N zv07YOE1UYcME5C$dbU6tqfb_32T@BImLVnJ&dIzR zv8JpATy&|KbxbvYaEIsSVnuq-Ltc_jgq*bMyvBzoLB9#lC~onJ_DnhQ>dpcOF|6dA zl-|zesa@*@niv-4AH7xoW(8V+mL{Y76D38fL;oDGpWRde#?`iHRfOVA&hk-PJCM7m zDhbk~bL8NZ_-PY9tTx-uWh=uBk!hi=*_za zFSU|#lK-u1>4Bh*l5x+o$IOTVj%O$2!F&-6>{q-pgxhgGyD#ox&%#IcP&E+7$)^!8 z9D)N;FD(MgkmWIvG)Z}&LiAc_6}|aY@jJF0Iu^GWb-Rn*UyN}s^rX)6k?S!7qk)^W zlP>m<_A+m6PGV4cp8*{@u>!(N+);kaQ#25YgwUNWrK1F__O-}m`B$)-_ZcMFJ8#Nr z>>V!1wv}EVX5b@DLXXq__l=~_SLKZphQoSa6^+=BjFrq0@HGt0!5H+7>`9JNy{Yh3 z;VtrPM-I}!ltEHw;P-+_(ZTTkfqnYc&Mq?5b{d*jUQw<;5LFo{(CoVodI{vK!AN7n zr1@*kj`hk1=P13V@keQehfYE##=vj!K}KGFaqp}Rf*5H#Q+je0zGtRV(>w@;X)IKuU zT#e4c54VtyLfLTe;P5|q4~34&pr$#0waHw#e zv*XaOE9P@M?9JYB+nx~%n@{`13T8Tu9&&sePtE>P{yZ6mBlyd9)mkkt{;kEn`WX>D zM@4rvvuYycv9o^5Yj&Ad$Iw8P=h8Q{9O*p>I3gWi!v_k1H&o^2ZoVdg(~0kaKtIpu z3;b{OYoCP1j`!#>4s779@$)_7h%$(Lu3%Y(fUpo`j?JRN)qn{5L`_ zCb~N)5xO)eBIE6Y&lOhKc77<#;@Saf+mM6gj>_?rKEosr8avSc#$R_LsW{cv`~hT8 zMBA#|fgPo z!3aZ~iQoDK9AmuvQtL;I7JjW@8&jPmC0>nEHO%|JSv=-8`a7ZK!EQ*EXmW_*pNe%Y zOtGSlCf@IVn@oSo!nAT+MymDxc1^#lv(7r~HaA z*_Gw$wt_=Q)&87>jQ)!G5LOXrN*W7R0KqnG^dxyb!oFPyHO&P!I7dh&zz*TI%jcJ^ zi|8r08lDwkL~zD#E##3)iPe!NcWZt^QX)9s_IU_mE&elm$Ery6Xv(M4_PzZbM8Mxg z3kE~cm(T+Ke=rQZnN=%3gntqJ{eX52AZmxj3PIeW=F@b|54tO`N>uvVCqgqhR1{K@ zNW@Cgv(eQ$ox0WCLQ!hz=-p~X&+Yo`3y!$eCcGYKgzU9*1r8AZ1$ok+{;bdK1GL)x z3wghdz(BEojNb86f63l^8Bn~M(CiObY^lMJoJq%(0;76QjCR#^5l}i< zO8%9d&D&ZSU`Tw=fiR3@qBX8<*Ac<|wqCi|?u5)6%hXIT9w0*S|9#}NGKTXU8+x33 zn8oE$x&^Tgh}v2av8d#oqzFbwK8aA87@kYep2sZh4)%G`OOg1)kC2+F9|S&_U3(Gp z8$6Ve=e)N4Thx`bB1LIGDdDCCv3+#NPptva`&l1u6k_%o!869PyJ`MmU#7GdU0UVw{oab z=t$>Aay3Ty2*>;9uW0~I*La&n+n}0Sa>xUnk7+(T?)>C3rJ|mVc}WE0qxh7bXAB~u{eX}v${dmXgnl!<)OkeoNnK<>=$W~)fq}g}g}lLzB-NOh zI%HG{i&R&iP-pME3r4vllBgc4J8S=yHnm8VEL&!2Kk{2%5rVBOE`TcFC`A40TLi$@ zUujDf73r$lH#&!=3b~@3sr5T17_qd;fz0)jT$9H?Or!sw=pb`i^eoJMX&Nr@p`>|D zLZl#?@vxt=0vgD2-9FJrOCVWn%?9`gyuERA_;5l0K~`lgdkSY;mpF2_T$>!C@1~VC zv2|OW=TRLQ`1KKprhhvC`j|av-#(`5ELSNHkyMdZ@2chUgrLy{hSnuBVpFX^_SN$9 ze&N-EADroV!AVO}(yp1VZMBiw%J;!HdH}(|U#m+gOjpJgR@PsHJ zc`vyhX_|3gQ)@q($7AYh*6Ka2E5aR5<{a#cWZqUp)g6Xl5fW1}A_joXdH03N4@h%! zL9~xjcHOnGr0!p)UH-e)ma>r#m4VOw;=v1jc=+@1mu^I}*i}$!+!Qh5!(HF1uJN(5 zTm4IM^KlpNHL9J(Wl*WbCZ^E`vI!6p(-m3)&K>Q{E zlYYQvMj~!HMBNo1-w7ApQ+Zw=p%%;gkmE0)*~Xkqz@)!Ti=va1&rdT>*skT)1!ap2 z9j}z%mD%$Y2r^DFhSm#v9pii3H=< zP@SyY?39*Y)ODcNMW*-r-!uK?bT-|%&C<1Bs-ot%?)krn<^$uchOp|+nBLm~c6SA1 zfX&w#xZ(XdB@UgZgYue(7|TbaJeK`uw$aFanpQ_Xr`dp2`^hfj;iqDB1~2RhuC8{g zX40F=7z$Pa=Yr3-F%LFQO3whQE|eH+RmLFS2Qv^!NV<1GSkNQ1x_M`ti_@~tYK?&f z!{lcj{Uso0_n+Be^b5UNAcI-z)zzG+4Q1E64q#uW)Bv#v?cV|T7l0%*XIzgVbL#>K zUow43n{c^?JGToq3LsWwVYL0tRO&JpRrI0CeUH$8=`feaeQVJHfyVVm|E(TUYin25 ztCrF;L%LD=-ASstF!b!7e|J$3?f<>*4K;<1;E3W?MUx{3)umye8kN`fsp(OOjZa?=AuGNt=qB_6MhZ5Vp z9@=NsH{u-z#-s95lh~E2_x(vc++g6&mXhOo_dnk|L`8^NU_xL#^%K1<6Pz+Tc+}LH z+PsY-JiUi>1xUfCk0TLhO493-mBLG@i&|Ha=^1@or$*h7<|4_@;#!Qz-h&VwG0Tyf z!qQ6jXa&_y^d4^Vb9~4csPUiGOu0wzZgCHL0BL^h_FMp`C0;5xPx1jC`Za_pc;Mef zQa?~MstLfcL7J%DB0NMHm)5A0jn4zuLpT`>%g-ez9s&1>p%LY*8*1(ronXR}u`-yT zhbhV#o_NYkZHoG$R1d{6ZT)Ysq5Xk||ASWF+F$?l^}I!t#}jko?ROO({d=2(pOF(wY%vZDn&-FeUVc5jX!>(%V*dWxBV>Q!j}#?!-jXUsH4OoTL4-;sIPVE zvZzt2T{L{$`NNF*DW}I5U+8TL2&xkqTst5e!PXr&j@BLdZnqp1tb@KxAneBGqr+R6^SbTagNb8qYh|!*4zYRl-Z|{MuO)waeM3|5HEP&8gS0RbTDN`& z9?;WO9@N8s?N}=t718>bi`TGbxd;5QyHEWq2IMT~KeM90f1Dtio_}WQycv7kQ#{4+$YqXNf`XKKmO=Ey*8 zJwmd0!?3n6X7(FSk7@=sK4$vBbz0jmZ@&L~i(t5!_|NQ2*0(%?!wAAF8dsiMxQQoh z)>xOL!e)NPvO-z+0r3#&VbOoRY-E4oTfm*dfuyw=TCPxD@Bd#(*B+PT-M-yix!w-6 zTv@v0ZJBPBx|U|1cxrCBaz=-lrY37{nVK>)6Xoz!F3n0=^`@Jp)J)CF%sgeOEKk&H zii(Mck^mDC2@pjN4^O|F_xH~}eFVnC_i!Jt`?`XYsX8`~E!Xd{Ch>GzS#Zx?o167I zF!d2VFKfv)BWW-*@s@AEk;?Rju`Ys2g-B)iA^a(h8b=Lxv=&~sMlBT)AOd{Eg2`{_ z-fEoVv-&?MV(T~!#}Y|{$Xn>63cdf9p;yMt*CW`liL*G+dKQ`EeE&S$P}fgD4XM>Y zV0ekhpOqJIT8F{lWqWR55(DcS``z7qWO!uFYcD8CW+QTCm(_N$a+$0>RU<#}Zp-(G zK!rS<&G}Xyp1K-^JGNaY63$4)cBf|e1RA}SwO)O-0s%gRj(MPC$#a!k>w3GouZn5= z1BCbecH)H^hduQ@Cn};%UT_SCDLNZ)U4Hu3Kt9w9CK$VQ_W#*58GgT9+~8WnUAv=R z4ZOvEfyEGt&c9~Ku14$~OOnA$PTO>_Z{R5!VHh=ku zb2F&nKPSk_rk`MzL5~ohV>@<{T1)1YG ze@cf&H$pACAZ ztsp`)dw;*AzHRkFPzEBLtMpJHOXH(l`dO`Sf(X@eqQ=8MaX$G_bl|Fg$E^OoBYlre zjK*D3mWh8#3k@2;0@fAXtk7p_yL$cn!G*2`_!Jy#>3gdUMEqXpxR4DdH%sDN7-Jh5s@bd;LdG9 zk1BP(i<0%YH7A_68%={yi8yV*$=xnWR-PyHpVAt1vntg#J1^WQC29>K z%pB*1`r;!p^Jmv}QY^P{^7`{deCin6_*RJrD&+0^8&FXiZcb-$UZl#mEq_OOZX#cz znpC@ejQF9XgC_@4?XP0+Urr2^U~9Mvg;L;$U;p`5;W!|MGKoLi7;w(j^s=Xgj@l5- zmS@LQPQmWMCT7RY!)?O{3OU+)#O_o60&(E!dli*V)pgYmbIFS*DO91GTkRpDDKKCf z9a|vh355Q~<7cz*kM}|)PNfc1dYgV@P=Eo(u4O;%3i#fjAmH^rs89V-tkf$Q zvBgI{Rr)Uo%1$voluV?tb*D9FYlYdk6T@5YTk$&Ff%~yJx8L)UCRltxaIO#gu(LGo z?%geSKA4NamUHosq0IkLMvv#~Al`teR@6$+J6Gm1cAE1`2_J~!Sauo|veQo|jemS( zzNSmBkEb~5ldXt`kCtX!saduY-@*Dszd?6V?_dh1T@w?Ziq4XV=6b3}C*Q6OaEn55 zA@o>3QJbWeBzIv%U1d2&Rxj;4(L@ew0{v45in3Dq(ZWnsujR(vK=n$$er!iJ~F!cWr z=etLew){aTWk7x~4;;psBlRujZ&aY89K<{)u_I3@KiDGB<P_;sWwmYcKH*aXv6cvl9S)=o7``wh8`EOKb zSs&M_q0(RzyAqBFt5EFv>Ea)LDr^I~zOmaam)q?8WEUC_O1MOTY-%dmkgRhY^sVg$ zSH~M9Tzi_Z-JW~iFIM88dZ5{EIJaJ!5FhoSwypkAjiF#}qs;AX;RVOQxgK+I_alRG zRySupYK0p0#_Q%lirm3j4;o@Q58X7+@>E?SV<5KciB^PU>2+2O|4RGH;GUGteaS2av{T*; zuZ}jOJmA_mLFvvM?HiY|XO06x@6V^wrWo!!7Jm$X=iq1l8?0odN>pU_-x!fboG`PV zQgIF)XEnD@r1yMO6g2AJD2iF3e&r~dUaagV!UOc|Ef3ZmO+0Lhq0aChoP-!nWa$2) zfjmRczIgH^IDX#Qrlw4EY@Jfistv|PIh!f_L)=3_2XJuHf4bZTgE{lT zp=H{(f{MbkXSrB#3W3xbRQ(T7G)MD@Vk0Y$u|n@qOe48283y84M?cL+#)?ziZm3B^ zUZE8%Et^2glpXCdkCL8Koh?YUH95{$G8@{W!<98PHu_=4T7U((uc?PICf~C4vH9 z&xsQc&Hcy2AwR27|cc%FS&_dC>{~Xg8T0!!7aw(ujtdn^$m6PBUJpav@|>`jm@9% zNB-GkGk|{Nx9)I4a@xIh+(E3#3ttC0!cZXY{Fpk;e}mc^VV>jNhQBU9y*E{nQJ6P3 zz4*Xe|J2bph9RZAYmYkS>@g1_A>u#vjXjpw0M5m5V@$Bjuq6JEe$|N_=jn(en&owW zQf&W}J`v2^daOOp8s3kgV-rjHx&K~@YoLoMXrH?15Bh1I4sp6{v$gWh6lsm$gCP(_ ze>nw|I&rHq7k?9>jNYeJT56Ck(M2fe)EcL^xy9Y|P!T4LqI0tgW;%o6C6d#VW@5C9 z3m(1gcrt&c@&$4p`6RK~g*LKhVEjr{gC!fQO<)kA+RzD;sFr8s)tftzaZkQvLycae zi4V~LAMvm1_M$2sa4;om=Ta|Ea;G;O5zN)F^yY_|StI-2$N)$Couapy)+ zJ0E5`ls#HJ4I<@paNWz$DAXttIO4Tc35%M8yAwC-a$h6QWDS`2eb%syk0Echx96ln ztpykEL!3#{p`r*gGUfpF{6uql&wSkZv@2JtVvgGgXR#*w%X6pz=O=LLx~KwB+%S8~ zg;)X41PWVM@UrrHqe(ZT9KG-VVgN!M9@mUmh9fJ@wAGqzpQu1T{1GvxvC*`>?-7q% z@5s$t-}GXj2g-n9ke0h~g{QIG1xFc*a|u~yI;%0pAeA3-Io-IvXuYsPY(lVIu8`(W z18{B~B)R#Y#Z%aZu{}0B)e7ZbV# z6qsJ3VhCEYJFe+~$&RR9i362g{rzqJfx2Vnn#gn>WWbZw8X+U5^^U z1OHy3B6U*#N3j#NR@cw925>+Zjlo}pxC|4_eg`=k<*b7DLkRsE$LACL5^yxn83ER9 zpB%hM)L_~vyM)sq;kfaEuF^Csn2`%-L9l_e^YWV_`V53R##aM$g9wuP*heI?jht`r z=T-y~(N<&6yd3V#2!{U{OaOeb;V_TXtmj)B(tnJ77|Ugf;94TG`|HU*@m|wt&pYDO zUzicRZ3W0gIQ}3&uj4V?wmwD$H8Ya}pOG;m z>qZO&N}I7$9v;2W+Oq>d$$P692f|haZAU^L!dlQS|yr&;0f?E01VPAMp{5DwS=RFS~AL z`VxQGo09z5=Ksm?e!q3vS02S3yq@zrs@R~8}1P(uO? zQMvif-uSpuH8l>DMyMWp*z~di7C;LTs$Z%xRh-�r73kb9BkowgSzW%y@vEbZ-y> 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 literal 0 HcmV?d00001 diff --git a/build/xmlrpcwsc.dll b/build/xmlrpcwsc.dll new file mode 100644 index 0000000000000000000000000000000000000000..97f1ce2114c378ed77353113ba39aa6cd4dc2b2c GIT binary patch literal 22016 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 B_1XXc literal 0 HcmV?d00001 diff --git a/documents/example fault.txt b/documents/example fault.txt new file mode 100644 index 0000000..bfaf086 --- /dev/null +++ b/documents/example fault.txt @@ -0,0 +1,29 @@ + + + + + + + faultCode + + 1 + + + + faultString + + Traceback (most recent call last): + File "/home/spina/Workspace/odoo/odoo/openerp/service/wsgi_server.py", line 56, in xmlrpc_return + result = openerp.http.dispatch_rpc(service, method, params) + File "/home/spina/Workspace/odoo/odoo/openerp/http.py", line 114, in dispatch_rpc + result = dispatch(method, params) + File "/home/spina/Workspace/odoo/odoo/openerp/service/model.py", line 23, in dispatch + (db, uid, passwd ) = params[0:3] +ValueError: need more than 0 values to unpack + + + + + + + diff --git a/documents/example request response.txt b/documents/example request response.txt new file mode 100644 index 0000000..0e66800 --- /dev/null +++ b/documents/example request response.txt @@ -0,0 +1,270 @@ +authenticate +REQUEST: + + + authenticate + + + + odoo + + + + + admin + + + + + admin + + + + + + + + + + +RESPONSE: + + + + + + 1 + + + + + +search +REQUEST: + + + execute_kw + + + + odoo + + + + + 1 + + + + + admin + + + + + res.partner + + + + + search + + + + + + + + + + + + + + is_company + + + = + + + 1 + + + + + + + + + customer + + + = + + + 1 + + + + + + + + + + + + + + +RESPONSE: + + + + + + + + + 7 + + + 11 + + + 8 + + + 44 + + + 10 + + + 12 + + + + + + + + +read +REQUEST: + + + execute_kw + + + + odoo + + + + + 1 + + + + + admin + + + + + res.partner + + + + + read + + + + + + + + + + + 7 + + + 11 + + + + + + + + + + + + + fields + + + + + name + + + + + + + + + + + +RESPONSE: + + + + + + + + + + + id + + 7 + + + + name + + Agrolait + + + + + + + + id + + 11 + + + + name + + Camptocamp + + + + + + + + + + diff --git a/documents/license template header.txt b/documents/license template header.txt new file mode 100644 index 0000000..070affc --- /dev/null +++ b/documents/license template header.txt @@ -0,0 +1,18 @@ +//// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// diff --git a/documents/release.txt b/documents/release.txt new file mode 100644 index 0000000..7d49ee2 --- /dev/null +++ b/documents/release.txt @@ -0,0 +1,12 @@ +- In branch develop +- Change Version in ComponentInfo +- Change Version in AssemblyInfo +- Make dll +- Commit +- In branch master +- Merge with develop +- Change Version Tag in README +- Commit in branch master +- Update to develop +- Add tag of master +- Push diff --git a/sandbox/Program.cs b/sandbox/Program.cs new file mode 100644 index 0000000..4e670d1 --- /dev/null +++ b/sandbox/Program.cs @@ -0,0 +1,368 @@ +//// +/// Program.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using XmlRpc; +using System.Xml; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace sandbox { + + /// + /// This class, test the xmlrpc component on odoo 9 + /// + class MainClass { + + public static string Url = "http://localhost:8069/xmlrpc/2", db = "odoo", pass = "admin", user = "admin"; + + public static void TestRequestXml() { + XmlRpcRequest request = new XmlRpcRequest("version"); + request.AddParam(false); + request.AddParam(3); + request.AddParam(4.9); + request.AddParam(DateTime.Now); + request.AddParam(DateTime.UtcNow); + request.AddParam(Encoding.UTF8.GetBytes("hello")); + + Dictionary dictest = new Dictionary(); + dictest.Add("hello", "hello"); + // request.AddParam(dictest); + + List listtest = new List(); + listtest.Add(3); + listtest.Add("hello"); + listtest.Add(dictest); + request.AddParam(listtest); + + XmlDocument xmlRequest = RequestFactory.BuildRequest(request); + + xmlRequest.Save(Console.Out); + + XmlRpcClient client = new XmlRpcClient(); + client.AppName = "Test"; + Console.WriteLine("\n"); + Console.WriteLine(client.GetUserAgent()); + } + + public static void TestReadVersion() { + XmlRpcClient client = new XmlRpcClient(); + client.Url = Url; + client.Path = "common"; + + XmlRpcResponse response = client.Execute("version"); + + Console.WriteLine("version"); + Console.WriteLine("REQUEST: "); + client.WriteRequest(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("RESPONSE: "); + client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + if (response.IsFault()) { + Console.WriteLine(response.GetFaultString()); + } else { + Console.WriteLine(response.GetString()); + } + } + + public static void TestReadRecords() { + XmlRpcClient client = new XmlRpcClient(); + client.Url = Url; + client.Path = "common"; + + // LOGIN + + XmlRpcRequest requestLogin = new XmlRpcRequest("authenticate"); + requestLogin.AddParams(db, user, pass, XmlRpcParameter.EmptyStruct()); + + XmlRpcResponse responseLogin = client.Execute(requestLogin); + + // Console.WriteLine("authenticate"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("LOGIN: "); + if (responseLogin.IsFault()) { + Console.WriteLine(responseLogin.GetFaultString()); + } else { + Console.WriteLine(responseLogin.GetString()); + } + + // SEARCH + + client.Path = "object"; + + XmlRpcRequest requestSearch = new XmlRpcRequest("execute_kw"); + requestSearch.AddParams(db, responseLogin.GetInt(), pass, "res.partner", "search", + XmlRpcParameter.AsArray( + XmlRpcParameter.AsArray( + XmlRpcParameter.AsArray("is_company", "=", true), XmlRpcParameter.AsArray("customer", "=", true) + ) + ) + ); + + requestSearch.AddParamStruct( + XmlRpcParameter.AsMember("limit", 2) + ); + + XmlRpcResponse responseSearch = client.Execute(requestSearch); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("search"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("SEARCH: "); + if (responseSearch.IsFault()) { + Console.WriteLine(responseSearch.GetFaultString()); + } else { + Console.WriteLine(responseSearch.GetString()); + } + + // READ + + XmlRpcRequest requestRead = new XmlRpcRequest("execute_kw"); + requestRead.AddParams(db, responseLogin.GetInt(), pass, "res.partner", "read", + XmlRpcParameter.AsArray( + responseSearch.GetArray() + ) + ); + + requestRead.AddParamStruct(XmlRpcParameter.AsMember("fields", + XmlRpcParameter.AsArray("name") + ) + ); + + XmlRpcResponse responseRead = client.Execute(requestRead); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("read"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("READ: "); + if (responseRead.IsFault()) { + Console.WriteLine(responseRead.GetFaultString()); + } else { + Console.WriteLine(responseRead.GetString()); + } + } + + public static void TestResponseXml() { + XmlDocument testDoc = new XmlDocument(); + // testDoc.AppendChild(testDoc.CreateElement("methodResponse")); + // testDoc.LoadXml("faultCode1faultStringError"); + testDoc.LoadXml("7118441012"); + + testDoc.Save(Console.Out); + XmlRpcResponse response = ResponseFactory.BuildResponse(testDoc); + + if (response.IsFault()) { + Console.WriteLine(response.GetFaultString()); + } else { + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine(response.GetString()); + } + } + + public static void TestCreateRecord() { + XmlRpcClient client = new XmlRpcClient(); + client.Url = Url; + client.Path = "common"; + + // LOGIN + + XmlRpcRequest requestLogin = new XmlRpcRequest("authenticate"); + requestLogin.AddParams(db, user, pass, XmlRpcParameter.EmptyStruct()); + + XmlRpcResponse responseLogin = client.Execute(requestLogin); + + // Console.WriteLine("authenticate"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("LOGIN: "); + if (responseLogin.IsFault()) { + Console.WriteLine(responseLogin.GetFaultString()); + } else { + Console.WriteLine(responseLogin.GetString()); + } + + // CREATE + + client.Path = "object"; + + XmlRpcRequest requestCreate = new XmlRpcRequest("execute_kw"); + requestCreate.AddParams(db, responseLogin.GetInt(), pass, "res.partner", "create", + XmlRpcParameter.AsArray( + XmlRpcParameter.AsStruct( + XmlRpcParameter.AsMember("name", "Albert Einstein") + , XmlRpcParameter.AsMember("image", Convert.ToBase64String(File.ReadAllBytes("img/einstein.jpg"))) + , XmlRpcParameter.AsMember("email", "albert.einstein@email.com") + ) + ) + ); + + XmlRpcResponse responseCreate = client.Execute(requestCreate); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("create"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("READ: "); + if (responseCreate.IsFault()) { + Console.WriteLine(responseCreate.GetFaultString()); + } else { + Console.WriteLine(responseCreate.GetString()); + } + } + + public static void TestSearchReadRecords() { + XmlRpcClient client = new XmlRpcClient(); + client.Url = Url; + client.Path = "common"; + + // LOGIN + + XmlRpcRequest requestLogin = new XmlRpcRequest("authenticate"); + requestLogin.AddParams(db, user, pass, XmlRpcParameter.EmptyStruct()); + + XmlRpcResponse responseLogin = client.Execute(requestLogin); + + // Console.WriteLine("authenticate"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("LOGIN: "); + if (responseLogin.IsFault()) { + Console.WriteLine(responseLogin.GetFaultString()); + } else { + Console.WriteLine(responseLogin.GetString()); + } + + // SEARCH + + client.Path = "object"; + + XmlRpcRequest requestSearch = new XmlRpcRequest("execute_kw"); + requestSearch.AddParams(db, responseLogin.GetInt(), pass, "res.partner", "search_read", + XmlRpcParameter.AsArray( + XmlRpcParameter.AsArray( + // XmlRpcParameter.AsArray("is_company", "=", true), XmlRpcRequest.AsArray("customer", "=", true) + XmlRpcParameter.AsArray("name", "ilike", "t") + ) + ), + XmlRpcParameter.AsStruct( + XmlRpcParameter.AsMember("fields", XmlRpcParameter.AsArray("name","email")) + // ,XmlRpcParameter.AsMember("limit", 2) + ) + ); + + + + XmlRpcResponse responseSearch = client.Execute(requestSearch); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("search"); + // Console.WriteLine("REQUEST: "); + // client.WriteRequest(Console.Out); + + // Console.WriteLine(); + // Console.WriteLine(); + // Console.WriteLine("RESPONSE: "); + // client.WriteResponse(Console.Out); + + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine("SEARCH: "); + if (responseSearch.IsFault()) { + Console.WriteLine(responseSearch.GetFaultString()); + } else { + Console.WriteLine(responseSearch.GetString()); + } + + } + + public static void Main(string[] args) { + TestRequestXml(); + // TestResponseXml(); + // TestReadVersion(); + // TestReadRecords(); + // TestCreateRecord(); + // TestSearchReadRecords(); + Console.ReadKey(); + } + } +} diff --git a/sandbox/Properties/AssemblyInfo.cs b/sandbox/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..428139d --- /dev/null +++ b/sandbox/Properties/AssemblyInfo.cs @@ -0,0 +1,48 @@ +//// +/// AssemblyInfo.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("sandbox")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("sandbox")] +[assembly: AssemblyCopyright("Copyright (c) 2016 Saúl Piña")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.0")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/sandbox/sandbox.csproj b/sandbox/sandbox.csproj new file mode 100644 index 0000000..9d7abfb --- /dev/null +++ b/sandbox/sandbox.csproj @@ -0,0 +1,43 @@ + + + + Debug + AnyCPU + {5B413D0A-0AC7-44BE-A4BF-0C824864C486} + Exe + sandbox + sandbox + v4.5 + + + true + full + false + ..\build\ + DEBUG; + prompt + 4 + true + + + full + true + ..\build\ + prompt + 4 + true + + + + + + False + ..\build\xmlrpcwsc.dll + + + + + + + + \ No newline at end of file diff --git a/xmlrpcwsc.sln b/xmlrpcwsc.sln new file mode 100644 index 0000000..ba494bc --- /dev/null +++ b/xmlrpcwsc.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xmlrpcwsc", "xmlrpcwsc\xmlrpcwsc.csproj", "{B5FA7348-6454-4545-AC0C-5E94FE53FB6C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sandbox", "sandbox\sandbox.csproj", "{5B413D0A-0AC7-44BE-A4BF-0C824864C486}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B413D0A-0AC7-44BE-A4BF-0C824864C486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B413D0A-0AC7-44BE-A4BF-0C824864C486}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B413D0A-0AC7-44BE-A4BF-0C824864C486}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B413D0A-0AC7-44BE-A4BF-0C824864C486}.Release|Any CPU.Build.0 = Release|Any CPU + {B5FA7348-6454-4545-AC0C-5E94FE53FB6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B5FA7348-6454-4545-AC0C-5E94FE53FB6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B5FA7348-6454-4545-AC0C-5E94FE53FB6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B5FA7348-6454-4545-AC0C-5E94FE53FB6C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/xmlrpcwsc/ComponentInfo.cs b/xmlrpcwsc/ComponentInfo.cs new file mode 100644 index 0000000..c1b9d74 --- /dev/null +++ b/xmlrpcwsc/ComponentInfo.cs @@ -0,0 +1,49 @@ +//// +/// ComponentInfo.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; + +namespace XmlRpc { + + /// + /// Component info + /// + public sealed class ComponentInfo { + + public static readonly string Name = "XML-RPC Web Service Client"; + public static readonly string ComponentName = "xmlrpcwsc"; + public static readonly string Version = "1.3.0"; + + /// + /// To the dictionary + /// + /// The dictionary + public static Dictionary ToDictionary() { + Dictionary info = new Dictionary(); + info.Add("Name", Name); + info.Add("ComponentName", ComponentName); + info.Add("Version", Version); + return info; + } + } +} + diff --git a/xmlrpcwsc/FactoryException.cs b/xmlrpcwsc/FactoryException.cs new file mode 100644 index 0000000..0bc6b55 --- /dev/null +++ b/xmlrpcwsc/FactoryException.cs @@ -0,0 +1,41 @@ +//// +/// FactoryException.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; + +namespace XmlRpc { + + /// + /// Factory exception + /// + public class FactoryException : Exception { + + public FactoryException() { + } + + public FactoryException(string message) : base(message) { + } + + public FactoryException(string message, Exception inner) : base(message, inner) { + } + } +} + diff --git a/xmlrpcwsc/Properties/AssemblyInfo.cs b/xmlrpcwsc/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..54ddbd7 --- /dev/null +++ b/xmlrpcwsc/Properties/AssemblyInfo.cs @@ -0,0 +1,48 @@ +//// +/// AssemblyInfo.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("XmlRpc Web Service Client")] +[assembly: AssemblyDescription("XmlRpc Web Service Client")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("xmlrpcwsc")] +[assembly: AssemblyCopyright("Copyright (c) 2016 Saúl Piña")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.3.0")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/xmlrpcwsc/RequestFactory.cs b/xmlrpcwsc/RequestFactory.cs new file mode 100644 index 0000000..9d85ed2 --- /dev/null +++ b/xmlrpcwsc/RequestFactory.cs @@ -0,0 +1,156 @@ +//// +/// RequestFactory.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Xml; +using System.Collections.Generic; + +namespace XmlRpc { + + /// + /// XML-RPC request factory + /// + public class RequestFactory { + + /// + /// Builds the xml request + /// + /// The xml request + /// Request + public static XmlDocument BuildRequest(XmlRpcRequest request) { + XmlDocument doc = new XmlDocument(); + + XmlElement xmlMethodCall = doc.CreateElement("methodCall"); + doc.AppendChild(xmlMethodCall); + + XmlElement xmlMethodName = doc.CreateElement("methodName"); + xmlMethodName.InnerText = request.MethodName ?? ""; + xmlMethodCall.AppendChild(xmlMethodName); + + XmlElement xmlParams = doc.CreateElement("params"); + xmlMethodCall.AppendChild(xmlParams); + + if (request.GetParamsCount() <= 0) + return doc; + + List parameters = request.GetParams(); + + foreach (object parameter in parameters) { + XmlElement xmlParam = doc.CreateElement("param"); + xmlParams.AppendChild(xmlParam); + xmlParam.AppendChild(doc.ImportNode(BuildXmlValue(parameter), true)); + } + + return doc; + } + + /// + /// Builds the xml value + /// + /// The xml value + /// Value + private static XmlElement BuildXmlValue(object value) { + XmlDocument doc = new XmlDocument(); + XmlElement xmlValue = doc.CreateElement("value"); + + if (value is bool) { + + XmlElement xmlType = doc.CreateElement("boolean"); + xmlType.InnerText = (bool)value ? "1" : "0"; + xmlValue.AppendChild(xmlType); + + } else if (value is int) { + + XmlElement xmlType = doc.CreateElement("int"); + xmlType.InnerText = value.ToString(); + xmlValue.AppendChild(xmlType); + + } else if (value is double) { + + XmlElement xmlType = doc.CreateElement("double"); + xmlType.InnerText = value.ToString(); + xmlValue.AppendChild(xmlType); + + } else if (value is DateTime) { + + XmlElement xmlType = doc.CreateElement("dateTime.iso8601"); + // EXAMPLE 19980717T14:08:55 + xmlType.InnerText = string.Format("{0:yyyyMMdd'T'HH:mm:ss}", value); + xmlValue.AppendChild(xmlType); + + } else if (value is byte[]) { + + XmlElement xmlType = doc.CreateElement("base64"); + xmlType.InnerText = Convert.ToBase64String((byte[])value); + xmlValue.AppendChild(xmlType); + + } else if (value is Dictionary) { + + XmlElement xmlType = doc.CreateElement("struct"); + xmlValue.AppendChild(xmlType); + + foreach (KeyValuePair item in (Dictionary) value) { + XmlElement xmlMember = doc.CreateElement("member"); + xmlType.AppendChild(xmlMember); + + XmlElement xmlName = doc.CreateElement("name"); + xmlName.InnerText = item.Key; + xmlMember.AppendChild(xmlName); + xmlMember.AppendChild(doc.ImportNode(BuildXmlValue(item.Value), true)); + } + + } else if (value is List) { + + XmlElement xmlType = doc.CreateElement("array"); + xmlValue.AppendChild(xmlType); + + XmlElement xmlData = doc.CreateElement("data"); + xmlType.AppendChild(xmlData); + + foreach (object item in (List) value) { + xmlData.AppendChild(doc.ImportNode(BuildXmlValue(item), true)); + } + + } else if (value is object[]) { + + XmlElement xmlType = doc.CreateElement("array"); + xmlValue.AppendChild(xmlType); + + XmlElement xmlData = doc.CreateElement("data"); + xmlType.AppendChild(xmlData); + + foreach (object item in (object[]) value) { + xmlData.AppendChild(doc.ImportNode(BuildXmlValue(item), true)); + } + + } else { + + XmlElement xmlType = doc.CreateElement("string"); + xmlType.InnerText = value.ToString(); + xmlValue.AppendChild(xmlType); + + } + + return xmlValue; + } + } +} + diff --git a/xmlrpcwsc/ResponseFactory.cs b/xmlrpcwsc/ResponseFactory.cs new file mode 100644 index 0000000..158c290 --- /dev/null +++ b/xmlrpcwsc/ResponseFactory.cs @@ -0,0 +1,152 @@ +//// +/// ResponseFactory.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Xml; +using System.Collections.Generic; +using System.Globalization; +using System.Collections; + +namespace XmlRpc { + + /// + /// XML-RPC response factory + /// + public class ResponseFactory { + + public static XmlRpcResponse BuildResponse(XmlDocument response) { + + XmlNodeList xmlMethodResponseList = response.GetElementsByTagName("methodResponse"); + + if (xmlMethodResponseList.Count <= 0) { + throw new FactoryException("XML file malformed, no tag methodResponse"); + } + + XmlElement xmlMethodResponse = (XmlElement)xmlMethodResponseList.Item(0); + + if (xmlMethodResponse.FirstChild == null) { + throw new FactoryException("XML file malformed, methodResponse child"); + } + + XmlElement xmlFirst = (XmlElement)xmlMethodResponse.FirstChild; + + if (xmlFirst.Name.Equals("fault")) { + object objectValue = BuildObjectValue((XmlElement)xmlFirst.FirstChild); + Dictionary faultStruct = (Dictionary)objectValue; + int faultCode = (int)faultStruct["faultCode"]; + string faultString = (string)faultStruct["faultString"]; + return new XmlRpcResponse(faultCode, faultString, faultStruct); + } else if (xmlFirst.Name.Equals("params")) { + XmlElement xmlParam = (XmlElement)xmlFirst.FirstChild; + if (xmlParam == null || !xmlParam.Name.Equals("param")) { + throw new FactoryException("XML file malformed, no tag param"); + } + + return new XmlRpcResponse(BuildObjectValue((XmlElement)xmlParam.FirstChild)); + } else { + throw new FactoryException("XML file malformed, methodResponse child"); + } + } + + private static object BuildObjectValue(XmlElement value) { + + if (value == null || !value.Name.Equals("value")) { + throw new FactoryException("XML file malformed, need value tag"); + } + + XmlElement xmlType = (XmlElement)value.FirstChild; + + if (xmlType == null) { + throw new FactoryException("XML file malformed, need type tag in value tag"); + } + + string stringType = xmlType.Name; + + if (stringType.Equals("int") || stringType.Equals("i4")) { + + return int.Parse(xmlType.InnerText); + + } else if (stringType.Equals("boolean")) { + + return xmlType.InnerText.Equals("1"); + + } else if (stringType.Equals("double")) { + + return double.Parse(xmlType.InnerText); + + } else if (stringType.Equals("base64")) { + + return Convert.FromBase64String(xmlType.InnerText); + + } else if (stringType.Equals("dateTime.iso8601") || stringType.Equals("dateTime") || stringType.Equals("date")) { + + // EXAMPLE 19980717T14:08:55 + return DateTime.ParseExact(xmlType.InnerText, "yyyyMMdd'T'HH:mm:ss", CultureInfo.InvariantCulture); + + } else if (stringType.Equals("array")) { + + List objectValue = new List(); + XmlElement xmlData = (XmlElement)xmlType.FirstChild; + + if (xmlData == null || !xmlData.Name.Equals("data")) { + throw new FactoryException("XML file malformed, need data tag in array tag"); + } + + IEnumerator iteValues = xmlData.GetEnumerator(); + while (iteValues.MoveNext()) { + XmlElement xmlValue = (XmlElement)iteValues.Current; + objectValue.Add(BuildObjectValue(xmlValue)); + } + return objectValue; + + } else if (stringType.Equals("struct")) { + + Dictionary objectValue = new Dictionary(); + IEnumerator iteMember = xmlType.GetEnumerator(); + while (iteMember.MoveNext()) { + XmlElement xmlMember = (XmlElement)iteMember.Current; + + IEnumerator iteMemberValues = xmlMember.GetEnumerator(); + + string name = ""; + object innerObject = null; + + while (iteMemberValues.MoveNext()) { + XmlElement xmlMemberValue = (XmlElement)iteMemberValues.Current; + if (xmlMemberValue.Name == "name") { + name = xmlMemberValue.InnerText; + } else if (xmlMemberValue.Name == "value") { + innerObject = BuildObjectValue(xmlMemberValue); + } + } + if (innerObject != null && !string.IsNullOrEmpty(name)) + objectValue.Add(name, innerObject); + } + return objectValue; + + } else { + return xmlType.InnerText; + } + + } + } +} + diff --git a/xmlrpcwsc/WebServiceConnection.cs b/xmlrpcwsc/WebServiceConnection.cs new file mode 100644 index 0000000..bf52ec4 --- /dev/null +++ b/xmlrpcwsc/WebServiceConnection.cs @@ -0,0 +1,340 @@ +//// +/// WebServiceConnection.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.IO; +using System.Threading; + +namespace XmlRpc { + + /// + /// This class send a stream data xml. + /// + public class WebServiceConnection { + + public static readonly string DefaultContentType = "text/xml; charset=UTF-8"; + public static readonly string DefaultRequestMethod = "POST"; + public static readonly int DefaultTimeout = 5000; + public static readonly int DefaultAttempts = 1; + public static readonly int DefaultAttemptsTimeout = 500; + public static readonly int DefaultConnectionLimit = 2; + public static readonly ICredentials DefaultCredentials = CredentialCache.DefaultCredentials; + public static readonly IWebProxy DefaultWebProxy = WebRequest.DefaultWebProxy; + + private int connectionLimit; + private int attempts; + private int attemptsTimeout; + private int timeout; + private string appName; + + /// + /// For connection simultaneously + /// + public int ConnectionLimit { + get { + return connectionLimit; + } + set { + if (value <= 0) + connectionLimit = DefaultConnectionLimit; + else + connectionLimit = value; + } + } + + /// + /// Attempts for request + /// + public int Attempts { + get { + return attempts; + } + set { + if (value <= 0) + attempts = DefaultAttempts; + else + attempts = value; + } + } + + /// + /// Gets or sets the attempts timeout. Default: WebServiceConnection.DefaultAttemptsTimeout + /// + /// The attempts timeout + public int AttemptsTimeout { + get { + return attemptsTimeout; + } + set { + if (value <= 0) + attemptsTimeout = DefaultTimeout; + else + attemptsTimeout = value; + } + } + + /// + /// Timeout for request. Default: WebServiceConnection.DefaultTimeout + /// + public int Timeout { + get { + return timeout; + } + set { + if (value <= 0) + timeout = DefaultTimeout; + else + timeout = value; + } + } + + /// + /// Gets or sets the name of the app + /// + /// The name of the app + public string AppName { + get { + return appName; + } + set { + if (appName == null) + appName = ""; + else + appName = value; + } + + } + + /// + /// total Attempts for request + /// + public int AttemptsRequest { + get; + protected set; + } + + /// + /// Total time for request + /// + public int TimeRequest { + get; + protected set; + } + + /// + /// Proxy. Default: WebServiceConnection.DefaultProxy + /// + public IWebProxy Proxy { + get; + set; + } + + /// + /// Credentials. Default: WebServiceConnection.DefaultCredentials + /// + public ICredentials Credentials { + get; + set; + } + + /// + /// Url for connect + /// + public string Url { + get; + set; + } + + /// + /// Path for connect + /// + public string Path { + get; + set; + } + + /// + /// Data typ. Default: WebServiceConnection.DefaultContentType + /// + public string ContentType { + get; + set; + } + + /// + /// Method for request. Default: WebServiceConnection.DefaultRequestMethod + /// + public string RequestMethod { + get; + set; + } + + /// + /// Gets the user agent + /// + /// The user agent + public string GetUserAgent() { + return string.Format("{0} ({1}/{2}/{3}/{4}) {5}", ComponentInfo.Name, ComponentInfo.ComponentName, ComponentInfo.Version, ".NET", Environment.OSVersion, AppName).Trim(); + } + + /// + /// Build the Url for WebService Connection + /// + /// Url for create HttpWebRequest + private string GetWebServiceUrl() { + if (Path == null) + return Url; + + string urlTemp = Url; + if (urlTemp.EndsWith("/")) + urlTemp = urlTemp.Substring(0, urlTemp.Length - 1); + + string path = Path; + if (path.StartsWith("/")) + path = path.Substring(1); + + return String.Format("{0}/{1}", urlTemp, path); + } + + /// + /// Default constructor + /// + public WebServiceConnection() { + Timeout = DefaultTimeout; + ContentType = DefaultContentType; + RequestMethod = DefaultRequestMethod; + Credentials = DefaultCredentials; + Attempts = DefaultAttempts; + ConnectionLimit = DefaultConnectionLimit; + AttemptsTimeout = DefaultAttemptsTimeout; + Proxy = DefaultWebProxy; + Url = ""; + AppName = ""; + } + + /// + /// FOR SSL + /// + /// + /// + /// + /// + /// + private bool OnValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { + return true; + } + + /// + /// Send data in xml format + /// + /// Xml Document + /// Xml Response + public XmlDocument SendRequest(XmlDocument dataRequest) { + return SendRequest(dataRequest.OuterXml); + } + + /// + /// Send string data + /// + /// Data + /// Xml Response + public XmlDocument SendRequest(string dataRequest) { + + if (string.IsNullOrEmpty(Url)) + throw new WebServiceException("URL must be different than empty or null"); + + ServicePointManager.ServerCertificateValidationCallback = OnValidateCertificate; + ServicePointManager.DefaultConnectionLimit = ConnectionLimit; + ServicePointManager.Expect100Continue = false; + + TimeSpan startTime = TimeSpan.FromMilliseconds(Environment.TickCount); + AttemptsRequest = 0; + bool successful = false; + string dataResponse = ""; + XmlDocument xmlDocument = new XmlDocument(); + + while (!successful) { + AttemptsRequest++; + + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GetWebServiceUrl()); + request.Timeout = Timeout; + request.KeepAlive = false; + request.Method = RequestMethod; + request.UserAgent = GetUserAgent(); + + byte[] bytesData = Encoding.UTF8.GetBytes(dataRequest); + request.ContentType = ContentType; + request.ContentLength = bytesData.Length; + + if (Proxy != null) + request.Proxy = Proxy; + + if (Credentials != null) + request.Credentials = Credentials; + + try { + Stream requestStreamData = request.GetRequestStream(); + requestStreamData.Write(bytesData, 0, bytesData.Length); + requestStreamData.Close(); + + WebResponse response = request.GetResponse(); + + Stream responseStreamData = response.GetResponseStream(); + StreamReader readResponseStreamData = new StreamReader(responseStreamData, Encoding.UTF8); + dataResponse = readResponseStreamData.ReadToEnd(); + + readResponseStreamData.Close(); + responseStreamData.Close(); + response.Close(); + + xmlDocument.LoadXml(dataResponse); + + successful = true; + } catch (Exception e) { + if (AttemptsRequest >= Attempts) { + TimeRequest = (int)TimeSpan.FromMilliseconds(Environment.TickCount).Subtract(startTime).Duration().TotalMilliseconds; + if (e.GetType().Equals(typeof(WebException))) { + WebException we = (WebException)e; + if (we.Status == WebExceptionStatus.Timeout) { + throw new WebServiceTimeoutException("Timeout exception, operation has expired", e); + } + } + throw new WebServiceException("Error sending request", e); + } else { + Thread.Sleep(AttemptsTimeout); + continue; + } + } + } + + TimeRequest = (int)TimeSpan.FromMilliseconds(Environment.TickCount).Subtract(startTime).Duration().TotalMilliseconds; + + return xmlDocument; + } + + } +} diff --git a/xmlrpcwsc/WebServiceException.cs b/xmlrpcwsc/WebServiceException.cs new file mode 100644 index 0000000..4cf9c97 --- /dev/null +++ b/xmlrpcwsc/WebServiceException.cs @@ -0,0 +1,41 @@ +//// +/// WebServiceException.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; + +namespace XmlRpc { + + /// + /// Web service exception + /// + public class WebServiceException : Exception { + + public WebServiceException() { + } + + public WebServiceException(string message) : base(message) { + } + + public WebServiceException(string message, Exception inner) : base(message, inner) { + } + } +} + diff --git a/xmlrpcwsc/WebServiceTimeoutException.cs b/xmlrpcwsc/WebServiceTimeoutException.cs new file mode 100644 index 0000000..01b45e0 --- /dev/null +++ b/xmlrpcwsc/WebServiceTimeoutException.cs @@ -0,0 +1,42 @@ +//// +/// WebServiceTimeoutException.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace XmlRpc { + + /// + /// Web service timeout exception + /// + public class WebServiceTimeoutException : WebServiceException { + + public WebServiceTimeoutException() { + } + + public WebServiceTimeoutException(string message) : base(message) { + } + + public WebServiceTimeoutException(string message, Exception inner) : base(message, inner) { + } + } +} diff --git a/xmlrpcwsc/XmlRpcClient.cs b/xmlrpcwsc/XmlRpcClient.cs new file mode 100644 index 0000000..7e509b2 --- /dev/null +++ b/xmlrpcwsc/XmlRpcClient.cs @@ -0,0 +1,135 @@ +//// +/// XmlRpcClient.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Xml; +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace XmlRpc { + + /// + /// XML-RPC client + /// + public class XmlRpcClient : WebServiceConnection { + + protected XmlDocument xmlRequest; + protected XmlDocument xmlResponse; + protected XmlRpcRequest request; + protected XmlRpcResponse response; + + /// + /// Gets the xml request + /// + /// The xml request + public XmlDocument GetXmlRequest() { + return xmlRequest; + } + + /// + /// Gets the xml response + /// + /// The xml response + public XmlDocument GetXmlResponse() { + return xmlResponse; + } + + /// + /// Writes the request + /// + /// File name + public void WriteRequest(String fileName) { + TextWriter streamWriter = new StreamWriter(fileName, false, Encoding.UTF8); + WriteRequest(streamWriter); + } + + /// + /// Writes the request + /// + /// Out stream + public void WriteRequest(TextWriter outStream) { + xmlRequest.Save(outStream); + } + + /// + /// Writes the response + /// + /// File name + public void WriteResponse(String fileName) { + TextWriter streamWriter = new StreamWriter(fileName, false, Encoding.UTF8); + WriteResponse(streamWriter); + } + + /// + /// Writes the response + /// + /// Out stream + public void WriteResponse(TextWriter outStream) { + xmlResponse.Save(outStream); + } + + /// + /// Execute the specified methodName and parameters + /// + /// Method name + /// Parameters + public XmlRpcResponse Execute(string methodName, List parameters){ + return Execute(new XmlRpcRequest(methodName, parameters)); + } + + /// + /// Execute the specified methodName and parameters + /// + /// Method name + /// Parameters + public XmlRpcResponse Execute(string methodName, object[] parameters){ + return Execute(new XmlRpcRequest(methodName, parameters)); + } + + /// + /// Execute the specified methodName + /// + /// Method name + public XmlRpcResponse Execute(string methodName){ + return Execute(new XmlRpcRequest(methodName)); + } + + /// + /// Execute the specified request + /// + /// Request + public virtual XmlRpcResponse Execute(XmlRpcRequest request){ + this.request = request; + + XmlDocument xmlRequest = RequestFactory.BuildRequest(request); + this.xmlRequest = xmlRequest; + + XmlDocument xmlResponse = SendRequest(xmlRequest); + this.xmlResponse = xmlResponse; + + this.response = ResponseFactory.BuildResponse(xmlResponse); + + return response; + } + } +} + diff --git a/xmlrpcwsc/XmlRpcParameter.cs b/xmlrpcwsc/XmlRpcParameter.cs new file mode 100644 index 0000000..198e803 --- /dev/null +++ b/xmlrpcwsc/XmlRpcParameter.cs @@ -0,0 +1,85 @@ +//// +/// XmlRpcParameter.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; + +namespace XmlRpc { + + /// + /// XML-RPC Parameter helper + /// + public class XmlRpcParameter { + + /// + /// Empty the struct. + /// + /// The struct + public static Dictionary EmptyStruct() { + return new Dictionary(); + } + + /// + /// Empty array + /// + /// The array + public static List EmptyArray() { + return new List(); + } + + /// + /// As array + /// + /// The array. + /// List. + public static List AsArray(params object[] list) { + List listReturn = new List(); + listReturn.AddRange(list); + return listReturn; + } + + /// + /// As struct + /// + /// The struct + /// List + public static Dictionary AsStruct(params KeyValuePair[] list) { + Dictionary dictReturn = new Dictionary(); + + foreach (KeyValuePair pair in list) { + dictReturn.Add(pair.Key, pair.Value); + } + + return dictReturn; + } + + /// + /// As member + /// + /// The member + /// Key + /// Value + public static KeyValuePair AsMember(string key, object value) { + KeyValuePair pairReturn = new KeyValuePair(key, value); + return pairReturn; + } + } +} diff --git a/xmlrpcwsc/XmlRpcRequest.cs b/xmlrpcwsc/XmlRpcRequest.cs new file mode 100644 index 0000000..0f25628 --- /dev/null +++ b/xmlrpcwsc/XmlRpcRequest.cs @@ -0,0 +1,177 @@ +//// +/// XmlRpcRequest.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; + +namespace XmlRpc { + + /// + /// XML-RPC request + /// + public class XmlRpcRequest { + + /// + /// Gets or sets the name of the method + /// + /// The name of the method + public string MethodName { + get; + set; + } + + /// + /// Gets or sets the parameters + /// + /// The parameters + private List Params { + get; + set; + } + + /// + /// Initializes a new instance of the class + /// + public XmlRpcRequest() { + this.MethodName = ""; + this.Params = new List(); + } + + /// + /// Initializes a new instance of the class + /// + /// Method name + public XmlRpcRequest(string methodName) { + this.MethodName = methodName ?? ""; + this.Params = new List(); + } + + /// + /// Initializes a new instance of the class + /// + /// Method name + /// Parameters + public XmlRpcRequest(string methodName, params object[] parameters) { + this.MethodName = methodName ?? ""; + this.Params = new List(); + if (parameters != null) + this.Params.AddRange(parameters); + } + + /// + /// Initializes a new instance of the class + /// + /// Method name + /// Parameters. + public XmlRpcRequest(string methodName, List parameters) { + this.MethodName = methodName ?? ""; + this.Params = parameters ?? new List(); + } + + /// + /// Adds the parameter, if param is DateTime uses DateTime.UtcNow, for dateTime.iso8601 conversion + /// + /// Parameter + public void AddParam(object param) { + Params.Add(param); + } + + /// + /// Adds the parameters + /// + /// Parameters + public void AddParams(params object[] list) { + Params.AddRange(list); + } + + /// + /// Adds the parameter array + /// + /// List + public void AddParamArray(params object[] list) { + AddParam(XmlRpcParameter.AsArray(list)); + } + + /// + /// Adds the parameter struct + /// + /// List + public void AddParamStruct(params KeyValuePair[] list) { + AddParam(XmlRpcParameter.AsStruct(list)); + } + + /// + /// Removes the parameter + /// + /// The parameter + /// Parameter + public void RemoveParam(object param) { + Params.Remove(param); + } + + /// + /// Removes the parameter + /// + /// The parameter + /// Position + public object RemoveParam(int pos) { + object operation = Params[pos]; + RemoveParam(operation); + return operation; + } + + /// + /// Gets the parameter + /// + /// The parameter + /// Position + public object GetParam(int pos) { + return Params[pos]; + } + + /// + /// Gets the parameters + /// + /// The parameters + public List GetParams() { + List temp = new List(); + temp.AddRange(Params); + return temp; + } + + /// + /// Gets the parameters count + /// + /// The parameters count + public int GetParamsCount() { + return Params.Count; + } + + /// + /// Clear this instance + /// + public void Clear() { + Params.Clear(); + } + + } +} + diff --git a/xmlrpcwsc/XmlRpcResponse.cs b/xmlrpcwsc/XmlRpcResponse.cs new file mode 100644 index 0000000..37b5ab5 --- /dev/null +++ b/xmlrpcwsc/XmlRpcResponse.cs @@ -0,0 +1,323 @@ +//// +/// XmlRpcResponse.cs +/// +/// Copyright (c) 2016 Saúl Piña . +/// +/// This file is part of xmlrpcwsc. +/// +/// xmlrpcwsc is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// xmlrpcwsc is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public License +/// along with xmlrpcwsc. If not, see . +//// + +using System; +using System.Collections.Generic; +using System.Collections; +using System.Text; + +namespace XmlRpc { + + /// + /// XML-RPC response + /// + public class XmlRpcResponse { + + private bool isFault; + private int faultCode; + private string faultString; + private object value; + + /// + /// Initializes a new instance of the class + /// + /// Fault code + /// Fault string + public XmlRpcResponse(int faultCode, string faultString) { + this.isFault = true; + this.faultCode = faultCode; + this.faultString = faultString; + this.value = null; + } + + /// + /// Initializes a new instance of the class + /// + /// Fault code + /// Fault string + /// Value. + public XmlRpcResponse(int faultCode, string faultString, object value) { + this.isFault = true; + this.faultCode = faultCode; + this.faultString = faultString; + this.value = value; + } + + /// + /// Initializes a new instance of the class + /// + /// Value + public XmlRpcResponse(object value) { + this.isFault = false; + this.faultCode = -1; + this.faultString = null; + this.value = value; + } + + /// + /// Determines whether this instance is fault + /// + /// true if this instance is fault; otherwise, false + public bool IsFault() { + return isFault; + } + + /// + /// Gets the fault code + /// + /// The fault code + public int GetFaultCode() { + return faultCode; + } + + /// + /// Gets the fault string + /// + /// The fault string + public string GetFaultString() { + return faultString; + } + + /// + /// Gets the value + /// + /// The value + public object GetObject() { + return value; + } + + /// + /// Determines whether this instance is null + /// + /// true if this instance is null; otherwise, false + public bool IsNull() { + return GetObject() == null; + } + + /// + /// Determines whether this instance is int + /// + /// true if this instance is int; otherwise, false + public bool IsInt() { + return GetObject() is int; + } + + /// + /// Gets the value int + /// + /// The value int + public int GetInt() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsInt()) + return (int)GetObject(); + else + throw new InvalidCastException("The value is not of type int"); + } + + /// + /// Determines whether this instance is boolean + /// + /// true if this instance is boolean; otherwise, false + public bool IsBoolean() { + return GetObject() is bool; + } + + /// + /// Gets the value boolean + /// + /// true, if value boolean was gotten, false otherwise + public bool GetBoolean() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsBoolean()) + return (bool)GetObject(); + else + throw new InvalidCastException("The value is not of type bool"); + } + + /// + /// Determines whether this instance is string + /// + /// true if this instance is string; otherwise, false + public bool IsString() { + return GetObject() is string; + } + + /// + /// Gets the value string + /// + /// The value string + public string GetString() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else + return ObjectToString(GetObject()); + } + + /// + /// Objects to string + /// + /// The to string + /// Value + private string ObjectToString(object value) { + if (value is List) { + + StringBuilder stringReturn = new StringBuilder(); + stringReturn.Append("["); + foreach (object temp in (List) value) { + stringReturn.Append(ObjectToString(temp)); + stringReturn.Append(", "); + } + if (((List)value).Count > 0) + stringReturn.Remove(stringReturn.Length - 2, 2); + stringReturn.Append("]"); + return stringReturn.ToString(); + + } else if (value is Dictionary) { + StringBuilder stringReturn = new StringBuilder(); + stringReturn.Append("{"); + foreach (KeyValuePair temp in (Dictionary) value) { + stringReturn.Append(temp.Key); + stringReturn.Append(": "); + stringReturn.Append(ObjectToString(temp.Value)); + stringReturn.Append(", "); + } + if (((Dictionary)value).Count > 0) + stringReturn.Remove(stringReturn.Length - 2, 2); + stringReturn.Append("}"); + return stringReturn.ToString(); + } else if (value is byte[]) { + return Convert.ToBase64String((byte[])value); + } else { + return value.ToString(); + } + + } + + /// + /// Determines whether this instance is double + /// + /// true if this instance is double; otherwise, false + public bool IsDouble() { + return GetObject() is double; + } + + /// + /// Gets the value double + /// + /// The value double + public double GetDouble() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsDouble()) + return (double)GetObject(); + else + throw new InvalidCastException("The value is not of type double"); + } + + /// + /// Determines whether this instance is date time + /// + /// true if this instance is date time; otherwise, false + public bool IsDateTime() { + return GetObject() is DateTime; + } + + /// + /// Gets the value date time + /// + /// The value date time + public DateTime GetDateTime() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsDateTime()) + return (DateTime)GetObject(); + else + throw new InvalidCastException("The value is not of type DateTime"); + } + + /// + /// Determines whether this instance is byte + /// + /// true if this instance is byte; otherwise, false + public bool IsByte() { + return GetObject() is byte[]; + } + + /// + /// Gets the value byte + /// + /// The value byte + public byte[] GetByte() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsByte()) + return (byte[])GetObject(); + else + throw new InvalidCastException("The value is not of type byte[]"); + } + + /// + /// Determines whether this instance is array + /// + /// true if this instance is array; otherwise, false + public bool IsArray() { + return GetObject() is List; + } + + /// + /// Gets the value array + /// + /// The value array + public List GetArray() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsArray()) + return (List)GetObject(); + else + throw new InvalidCastException("The value is not of type List"); + } + + /// + /// Determines whether this instance is struct + /// + /// true if this instance is struct; otherwise, false + public bool IsStruct() { + return GetObject() is Dictionary; + } + + /// + /// Gets the value struct + /// + /// The value struct + public Dictionary GetStruct() { + if (IsNull()) + throw new NullReferenceException("The value is null"); + else if (IsStruct()) + return (Dictionary)GetObject(); + else + throw new InvalidCastException("The value is not of type Dictionary"); + } + + } +} + diff --git a/xmlrpcwsc/xmlrpcwsc.csproj b/xmlrpcwsc/xmlrpcwsc.csproj new file mode 100644 index 0000000..f3c30e8 --- /dev/null +++ b/xmlrpcwsc/xmlrpcwsc.csproj @@ -0,0 +1,49 @@ + + + + Debug + AnyCPU + {B5FA7348-6454-4545-AC0C-5E94FE53FB6C} + Library + XmlRpc + xmlrpcwsc + v4.5 + + + true + full + false + ..\build\ + DEBUG; + prompt + 4 + false + + + full + true + ..\build\ + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file