From 7095563153af0e3481605eb5979ca8e6982d95cc Mon Sep 17 00:00:00 2001 From: Christophe Fergeau Date: Mon, 13 Jan 2014 20:01:42 +0100 Subject: [PATCH] Add reference manual This manual documents how to enable/use various SPICE features when creating a VM by running QEMU directly, or when using libvirt, or when using virt-manager. This is based on work by Lubos Kocman --- Makefile.am | 3 +- configure.ac | 21 + docs/Makefile.am | 3 + docs/manual/Makefile.am | 38 + docs/manual/SpiceUserManual-Basics.xml | 689 +++++++++++++++++++ docs/manual/SpiceUserManual-Guest.xml | 54 ++ docs/manual/SpiceUserManual-Installation.xml | 199 ++++++ docs/manual/SpiceUserManual-Introduction.xml | 264 +++++++ docs/manual/SpiceUserManual-References.xml | 218 ++++++ docs/manual/SpiceUserManual.xml | 71 ++ docs/manual/resources/pepper.png | Bin 0 -> 10582 bytes docs/manual/resources/spicec01.png | Bin 0 -> 10244 bytes 12 files changed, 1559 insertions(+), 1 deletion(-) create mode 100644 docs/Makefile.am create mode 100644 docs/manual/Makefile.am create mode 100644 docs/manual/SpiceUserManual-Basics.xml create mode 100644 docs/manual/SpiceUserManual-Guest.xml create mode 100644 docs/manual/SpiceUserManual-Installation.xml create mode 100644 docs/manual/SpiceUserManual-Introduction.xml create mode 100644 docs/manual/SpiceUserManual-References.xml create mode 100644 docs/manual/SpiceUserManual.xml create mode 100644 docs/manual/resources/pepper.png create mode 100644 docs/manual/resources/spicec01.png diff --git a/Makefile.am b/Makefile.am index e260e007..c7a0e92d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ NULL = ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = spice-common server +SUBDIRS = spice-common server docs if SUPPORT_CLIENT SUBDIRS += client @@ -15,6 +15,7 @@ DISTCHECK_CONFIGURE_FLAGS = \ --enable-opengl \ --enable-smartcard \ --with-sasl \ + --enable-manual \ $(NULL) EXTRA_DIST = \ diff --git a/configure.ac b/configure.ac index c897368a..aaa7ffc1 100644 --- a/configure.ac +++ b/configure.ac @@ -415,6 +415,23 @@ if test "x$enable_automated_tests" = "xyes"; then AC_MSG_RESULT([found]) fi + +AC_ARG_ENABLE([manual], + AS_HELP_STRING([--enable-manual=@<:@auto/yes/no@:>@], + [Build SPICE manual]), + [], + [enable_manual="auto"]) +if test "x$enable_manual" != "xno"; then + AC_PATH_PROG([XMLTO], [xmlto]) + AS_IF([test -z "$XMLTO" && test "x$enable_manual" = "xyes"], + [AC_MSG_ERROR([xmlto is missing and build of manual was requested])] + [have_xmlto = no] + ) +fi +AS_IF([test -n "$XMLTO"], [have_xmlto=yes], [have_xmlto=no]) +AM_CONDITIONAL([BUILD_MANUAL], [test -n "$XMLTO"]) + + dnl =========================================================================== dnl check compiler flags @@ -495,6 +512,8 @@ spice-server.pc server/Makefile server/tests/Makefile client/Makefile +docs/Makefile +docs/manual/Makefile ]) dnl ========================================================================== @@ -525,6 +544,8 @@ echo " SASL support: ${enable_sasl} Automated tests: ${enable_automated_tests} + + Manual: ${have_xmlto} " if test $os_win32 == "yes" ; then diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..18e785f0 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,3 @@ +if BUILD_MANUAL +SUBDIRS = manual +endif diff --git a/docs/manual/Makefile.am b/docs/manual/Makefile.am new file mode 100644 index 00000000..75cc4f79 --- /dev/null +++ b/docs/manual/Makefile.am @@ -0,0 +1,38 @@ +SUFFIXES = .xml .html .txt .1 + +# apparently, xmlto does not support validation of docbook5 docs +# that's why it's disabled with --skip-validation +.xml.html: + $(AM_V_GEN)$(XMLTO) --skip-validation -o html xhtml $< + +.xml.1: + $(AM_V_GEN)$(XMLTO) --skip-validation -o man man $< + +.xml.txt: + $(AM_V_GEN)$(XMLTO) --skip-validation -o txt txt $< + +all: allhtml manpages + +XMLMAN = +XMLDOC = \ + SpiceUserManual-Basics.xml \ + SpiceUserManual-Guest.xml \ + SpiceUserManual-Installation.xml \ + SpiceUserManual-Introduction.xml \ + SpiceUserManual-References.xml \ + SpiceUserManual.xml +XMLALL = $(XMLMAN) $(XMLDOC) +SOURCES = $(XMLALL) $(TXTDOC) + +allhtml: $(XMLALL:.xml=.html) + +manpages: $(XMLMAN:.xml=.1) + +# Control what goes in the distribution tarball. +# We include all of the XML, and also generated HTML pages +# so people working from the distribution tarball won't need xmlto. +EXTRA_DIST = $(SOURCES) html + +clean-local: + rm -fr html $(XMLMAN:.xml=.1) + diff --git a/docs/manual/SpiceUserManual-Basics.xml b/docs/manual/SpiceUserManual-Basics.xml new file mode 100644 index 00000000..dfc8e563 --- /dev/null +++ b/docs/manual/SpiceUserManual-Basics.xml @@ -0,0 +1,689 @@ + + + + + Spice basics +
+ Basic Definitions +
+ Host + Host is a machine running an instance of qemu-kvm. +
+ +
+ Guest + + Guest is a virtual machine hosted on the host + which will be accessed with a spice client. + +
+ +
+ Client + + Client is referring to a system running the spice client + (the recommended one is virt-viewer). + +
+
+ +
+ Launching qemu + I'll use qemu-kvm as a name for the executable. If you're using a manually built qemu or + a qemu without kvm then just replace qemu-kvm with your own binary. I'll use host# client# + guest# shell prompt notations to distinguish where the command should be the command. See + section Basic Definitions to be sure that you know + difference between the host, client and guest. You can ignore the difference between guest, client + and host if they are all running on the same machine. + + + The first important thing to do is to create a guest + image. You can use any raw device such as a clean logical volume, or an iSCSI + lun. You may also use a file as the disk image for the guest. I'll use a file created by qemu-img as a demonstration. + + + + The following command will allocate a 10GB file. See qemu-img man page for further information. + + + host# qemu-img create /path/to/xp.img 10G + + + Now that we created an image, we can now start with image population. I assume that you have + a locally stored ISO of your favourite operating system so you can use it for installation. + + + host# sudo qemu-kvm -boot order=dc -vga qxl \ + -spice port=3001,disable-ticketing -soundhw ac97 \ + -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent \ + -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \ + -cdrom /path/to/your.iso /path/to/your.img + + + Let's take a brief look at the qemu options that were used. The option -boot order=dc specifies that the guest system + should try to boot from the first cdrom and then fallback to the first disk, -vga qxl specifies that qemu should + emulate the qxl device adapter. + + The Spice port option defines what port will be used for communication with the client. The Spice + option disable-ticketing is telling us that ticketing (simple + authentication method) is not used. The virtio and chardev devices are + required by the guest + agent. + +
+ +
+ Adding Spice support to an existing virtual machine + + This section will assume that you already have a running QEMU virtual machine, + and that you are running it either through virt-manager, libvirt or through + direct QEMU use, and that you want to enable Spice support for this virtual + machine. + + +
+ Using virt-manager + + Double-click on the virtual machine you are interested in, go to View/Details. + If the left pane has a "Display Spice" entry, then the virtual machine already + has Spice support, and you can check the connection details (port number) + by clicking on it. If it has no Spice entry, click on "Add + Hardware", and add a "Graphics" element of type "Spice server". + If the host and the client are not the same machine, you should check + the "Listen on all public network interfaces" checkbox, otherwise you + don't need to make any changes. + + + You should also add a QXL video device. It can be done by double-clicking + on a virtual machine, then by going to View/Details, and by clicking + on "Add Hardware" if the virtual machine does not have a "Video QXL" item + in its left pane. From the "Add hardware" dialog, you should then create + a "Video" device whose model is "QXL". + + + After stopping and restarting the virtual machine, it should be + accessible with a Spice client. + + + You can remove non-Spice display entries and non-QXL video entries from + the virtual machine configuration. + + + If you go to Edit/Preferences/VM Details in the main virt-manager window, + you can set Spice graphics type as the default setting for new virtual + machines. + +
+ +
+ Using libvirt + + All libvirt examples will assume that the virtual machine to modify + is $vmname and that virsh is using the correct + libvirt connection + by default. + + + To add Spice support to an existing virtual machine managed by libvirt, + you need to edit it: + +host# virsh edit $vmname + + and then add a Spice graphics element: + +<graphics type='spice'/> + + You should also add a QXL video device + +<video> + <model type='qxl'> +</video> + + + + After stopping and restarting the virtual machine $vmname, it should be + accessible through Spice. You can check the connection parameters with: + +host# virsh domdisplay $vmname + + +
+ +
+ Using QEMU + + To enable Spice support to your virtual machine, you only need to + append the following to your QEMU command line: + +-spice port=3001,disable-ticketing + + This will setup a Spice session listening on port 3001 exporting + your virtual machine display. + + + You can also add a QXL device by appending this to the command line: + +-vga qxl + + + +
+ +
+ Connecting to guest + + + The following section will show you basic usage of the Spice + client. The example connection will be related to the qemu instance + started in the previous section. + + + + Be aware that the port used for spice communication + (port 3001 in our case) should not be + blocked by firewall. Host myhost is referring to the + machine which is running our qemu instance. + + + client# remote-viewer spice://myhost:3001 +
+ Established connection to Windows 2008 guest + + + + + +
+
+
+ +
+ Ticketing + + Spice does not currently support multiple connections to the same qemu + instance. So anybody who will connect to the same host and port can simply + take over your session. + + You can eliminate this problem by using + ticketing or SSL. + + + + Ticketing is a simple authentication system which enables you to set simple + tickets to a vm. + Client has to authentificate before the connection can be established. See + the spice option password in the following example. + + +
+ Using virt-manager + + To set a Spice password for a virtual machine, go to this machine + details in virt-manager, and then click on the "Display Spice" item in + the left pane, and enter the ticket you want to use in the "Password" + field. + +
+ +
+ Using libvirt + + All you need to do is to append a passwd attribute to the Spice + graphics node for your virtual machine: + +<graphics type='spice' passwd='mysecretpassword'/> + + +
+ +
+ Using QEMU + + Adding a ticket with QEMU involves a slight modification of the -spice + parameter used when running QEMU: + +-spice port=3001,password=mysecretpassword + + +
+ +
+ Client + + When you start the client as usual, if ticketing was enabled on the host, + remote-viewer will pop up a window asking for a password before starting + the Spice session. It won't be established if an incorrect ticket was + passed to the client. + + + + You might have figured out that passing tickets as a commandline option isn't very safe. + It's not safe as everybody with access to the host can read it from the output of ps(1). + To prevent this, the ticket can be also set by using the qemu console command spice._set_ticket. + +
+
+ +
+ Agent + + Agent support allows better integration with the guest. For example, it + allows copy and paste between the guest and the host OSes, dynamic resolution + changes when the client window is resized/fullscreened, file transfers through + drag and drop, ... + + + The agent is a daemon/service running in the guest OS so it must be installed + if it was not installed by default during the guest OS installation. It also + relies on a virtio-serial PCI device and a dedicated spicevmc char device + to achieve communication between the guest and the host. These devices must + be added to the virtual machine if we want to agent to work properly in the + guest. + + +
+ Using virt-manager + + The needed devices can be added from the virtual machine details. Click + on "Add hardware" and then add a "Channel" device with type + "Spice agent (spicevmc)". This will automatically add the needed + virtio-serial device in addition to the spicevmc channel. + +
+ +
+ Using libvirt + + Two distinct devices must be added: + + a virtio serial device + a spicevmc channel + + +<devices> + <controller type='virtio-serial' index='0'/> + <channel type='spicevmc'> + <target type='virtio' name='com.redhat.spice.0'/> + </channel> +</devices> + + +
+ +
+ Using QEMU + + Adding the following parameters to your QEMU command line will + enable the needed devices for agent support in the guest OS: + +-device virtio-serial \ +-chardev spicevmc,id=vdagent,debug=0,name=vdagent \ +-device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \ + + +
+
+ +
+ USB redirection + + With USB redirection, USB devices plugged into the client machine can be + transparently redirected to the guest OS. This redirection can either be + automatic (all newly plugged devices are redirected), or manual + (the user selects which devices (s)he wants to redirect). + + + For redirection to work, the virtual machine must have an USB2 EHCI controller + (this implies 3 additional UHCI controllers). It also needs to have + Spice channels for USB redirection. The number of such channels correspond + to the number of USB devices that it will be possible to redirect at the same + time. + + +
+ Using virt-manager + + Virtual machines created with virt-manager should have a USB controller + by default. In the virtual machine details, select "Controller USB" in + the left pane, and make sure its model is set to USB2. You can then + click on "Add Hardware" and add as many "USB Redirection" items as + the number of USB devices you want to be able to redirect simultaneously. + +
+ +
+ Using libvirt + + You need to add the needed USB controllers to the libvirt XML (make + sure there is no pre-existing USB controller in your virtual machine + XML before doing this), as well as one Spice USB redirection channel + per device you want to redirect simultaneously. + + <controller type='usb' index='0' model='ich9-ehci1'/> +<controller type='usb' index='0' model='ich9-uhci1'> + <master startport='0'/> +</controller> +<controller type='usb' index='0' model='ich9-uhci2'> + <master startport='2'/> +</controller> +<controller type='usb' index='0' model='ich9-uhci3'> + <master startport='4'/> +</controller> +<redirdev bus='usb' type='spicevmc'/> +<redirdev bus='usb' type='spicevmc'/> +<redirdev bus='usb' type='spicevmc'/> +<redirdev bus='usb' type='spicevmc'/> + + +
+ +
+ Using QEMU + + Similarly to libvirt, we need to add EHCI/UHCI controllers to QEMU + command line, and we also need to add one Spice redirection channel per + device we want to redirect simultaneously. + +-device ich9-usb-ehci1,id=usb \ +-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \ +-device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \ +-device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \ +-chardev spicevmc,name=usbredir,id=usbredirchardev1 \ +-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \ +-chardev spicevmc,name=usbredir,id=usbredirchardev2 \ +-device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \ +-chardev spicevmc,name=usbredir,id=usbredirchardev3 \ +-device usb-redir,chardev=usbredirchardev3,id=usbredirdev3 + + +
+ +
+ Client + + The client needs to have support for USB redirection. In remote-viewer, + you can select which USB devices to redirect in File/USB device selection + once the Spice connection is established. There are also various command + line redirection options which are described when running remote-viewer + with --help-spice. + +
+
+ +
+ Multiple monitor support + + When using Spice, it's possible to use multiple monitors. For that, the guest + must have multiple QXL devices (for Windows guests), or a single QXL device + configured to support multiple heads (for Linux guests). + + + Before following the instructions in this section, make sure your virtual machine + already has a QXL device. If that is not the case, refer to + this section. Your guest OS will + also need to have the QXL driver installed or multiple monitor support will + not work. + + + Once your virtual machine is using a QXL device, you don't need to make + any other change to get multiple heads in a Linux guest. The following + paragraph will deal with adding multiple QXL devices to get multiple + monitors in a Windows guest. + + +
+ Using virt-manager + + To add an additional QXL device for Windows guests, simply go to your + virtual machine details. Check that you already have a "Video QXL" device, + if notclick on "Add Hardware", and add a "Video" device + with model "QXL". This can also work with Linux guests if your are willing + to configure X.Org to use Xinerama (instead of XRandR). + + + If you are using a new enough distribution (for example Fedora 19), and if your + virtual machine already has a QXL device, you should not need to make any changes + in virt-manager. If you are using an older distribution, you can't do the required + changes from virt-manager, you'll need to edit libvirt XML as described on this + blog post. + +
+ +
+ Using libvirt + + To add an additional QXL device to your virtual machine managed by + libvirt, you simply need to append a new video node whose model is + QXL: + +<video> + <model type='qxl'> +</video> +<video> + <model type='qxl'> +</video> + + +
+ +
+ Using QEMU + + To get a second QXL device in your virtual machine, you need to append + -device qxl to your QEMU command line in addition to the -vga qxl that + is already there: + +-vga qxl -device qxl + + +
+ +
+ Client + + You can enable additional displays either from the Display/Displays menu + in remote-viewer, or from your guest OS display configuration tool. + +
+
+ +
+ TLS + + TLS support allows to encrypt all/some of the channels Spice uses + for its communication. + A separate port is used for the encrypted channels. + When connecting through a TLS channel, the Spice client will verify + the certificate sent by the host. It will check that this + certificate matches the hostname it's connecting, and that + this certificate is signed by a known certificate authority + (CA). This can be achieved by either getting the host + certificate signed by an official CA, or by passing to the client + the certificate of the authority which signed the host certificate. + The latter allows the use of self-signed certificates. + + +
+ Using virt-manager + + It's not possible to define the CA certificate/host certificate + to use for the TLS connection using virt-manager, see the next + section for how to enable this using libvirt. + +
+ +
+ Using libvirt + + The certificate must be specified in libvirtd configuration + file in /etc/libvirt/qemu.conf (or in + ~/.config/libvirt/qemu.conf if you are using a session libvirt). + See the documentation in this file reproduced below: + +# Enable use of TLS encryption on the SPICE server. +# +# It is necessary to setup CA and issue a server certificate +# before enabling this. +# +spice_tls = 1 + + +# Use of TLS requires that x509 certificates be issued. The +# default it to keep them in /etc/pki/libvirt-spice. This directory +# must contain +# +# ca-cert.pem - the CA master certificate +# server-cert.pem - the server certificate signed with ca-cert.pem +# server-key.pem - the server private key +# +# This option allows the certificate directory to be changed. +# +spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice" + + + + Once the above is done, when the domain is running, you + should get something like what is below if you are leaving + Spice port allocation up to libvirt: + +host# virsh domdisplay +spice://127.0.0.1?tls-port=5901 + + + + This means that the connection is possible both through TLS and + without any encryption. You can edit the libvirt graphics node + if you want to change that behaviour and only allow connections + through TLS: + +<graphics type='spice' autoport='yes' defaultMode='secure'/> + + +
+ +
+ Using QEMU + + QEMU expects the certificates to be named the same way as what + libvirt expects in the previous paragraph. The directory where + these certificates can be found is specified as options to the + -spice command line parameters: + +-spice port=5900,tls-port=5901,disable-ticketing,x509-dir=/etc/pki/libvirt-spice + + +
+ +
+ Client + + We need to change 2 things when starting the client: + + specify the tls port to use + specify the CA certificate to use when verifying the host certificate + + With remote-viewer, this is done this way: + +client# remote-viewer --spice-ca-file=/etc/pki/libvirt-spice/ca-cert.ca spice://myhost?tls-port=5901 + + +
+ +
+ Generating self-signed certificates for use with Spice + + The following script can be used to create the various certificates + needed to use a TLS Spice connection. Make sure to substitute the hostname + of your Spice host in the subject of the certificate signing request. + +SERVER_KEY=server-key.pem + +# creating a key for our ca +if [ ! -e ca-key.pem ]; then + openssl genrsa -des3 -out ca-key.pem 1024 +fi +# creating a ca +if [ ! -e ca-cert.pem ]; then + openssl req -new -x509 -days 1095 -key ca-key.pem -out ca-cert.pem -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=my CA" +fi +# create server key +if [ ! -e $SERVER_KEY ]; then + openssl genrsa -out $SERVER_KEY 1024 +fi +# create a certificate signing request (csr) +if [ ! -e server-key.csr ]; then + openssl req -new -key $SERVER_KEY -out server-key.csr -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=myhostname.example.com" +fi +# signing our server certificate with this ca +if [ ! -e server-cert.pem ]; then + openssl x509 -req -days 1095 -in server-key.csr -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem +fi + +# now create a key that doesn't require a passphrase +openssl rsa -in $SERVER_KEY -out $SERVER_KEY.insecure +mv $SERVER_KEY $SERVER_KEY.secure +mv $SERVER_KEY.insecure $SERVER_KEY + +# show the results (no other effect) +openssl rsa -noout -text -in $SERVER_KEY +openssl rsa -noout -text -in ca-key.pem +openssl req -noout -text -in server-key.csr +openssl x509 -noout -text -in server-cert.pem +openssl x509 -noout -text -in ca-cert.pem + + +
+
+ +
+ SASL + + Spice server and client have support for SASL authentication. When using QEMU, /etc/sasl2/qemu.conf will be + used as a configuration file. For testing, you can use the digest-md5 mechanism, and populate a test database + using 'saslpasswd2 -f /etc/qemu/passwd.db -c foo'. These files have to be readable by the qemu process that will + handle your VM. + + + + To troubleshoot SASL issues, running strace -e open on the QEMU process can be a useful first step. + + + +
+ Using virt-manager + + It's currently not possible to enable SASL from virt-manager. + +
+ +
+ Using libvirt + + SASL support for SPICE has been added to libvirt mid-October 2013 so you need a libvirt version + that was released after this date. To enable SASL, you need to add spice_sasl = 1 in /etc/libvirt/qemu.conf + for the system libvirtd instance, and to ~/.config/libvirt/qemu.conf for the session libvirtd instance. + +
+ +
+ Using QEMU + + Using SASL with QEMU involves a slight modification of the -spice + parameter used when running QEMU: + +-spice port=3001,sasl + + +
+ +
+ Client + + When you start the client as usual, if SASL was enabled on the host, + remote-viewer will pop up a window asking for a password before starting + the Spice session. It won't be established if an incorrect ticket was + passed to the client. + +
+
+
diff --git a/docs/manual/SpiceUserManual-Guest.xml b/docs/manual/SpiceUserManual-Guest.xml new file mode 100644 index 00000000..6648f831 --- /dev/null +++ b/docs/manual/SpiceUserManual-Guest.xml @@ -0,0 +1,54 @@ + + + + + Spice Guest Additions + +
+ Introduction + + While you will be able to remotely access your virtual machine + through Spice without making any change to the virtual machine + configuration, you can get better integration if you tweak it + specially for Spice. + + + If your virtual machine has a QXL video device and you install + the corrresponding guest driver, your guest will support higher + resolutions, multiple monitors, resizing to arbitrary resolutions, + ... + + + Installing the Spice vdagent in your guest will let you copy and + paste between your guest and client OSes, to drag and drop files + between the 2 OSes, ... In order for the agent to work, your + virtual machine must have a virtio serial device (and the + corresponding guest drivers) as well as a Spice spicevmc channel. + +
+ +
+ Windows Guest + + The recommended way of getting all the needed drivers installed is + to use the all-in-one Spice guest tools installer which can be + found + on spice-space.org. + + + To get USB redirection working on Windows, you need to ... + + + If you want to manually install them, the QXL driver can be downloaded from + this location + , agent builds can be found + here + . You also need the vioserial driver which is distributed with the + other + virtio-win drivers. + +
+ +
diff --git a/docs/manual/SpiceUserManual-Installation.xml b/docs/manual/SpiceUserManual-Installation.xml new file mode 100644 index 00000000..4e883acd --- /dev/null +++ b/docs/manual/SpiceUserManual-Installation.xml @@ -0,0 +1,199 @@ + + + + + Installation + +
+ Installing Spice on RHEL or Fedora + + Be aware that RHEL has no builds of qemu/spice-server for i386, only x86_64 builds are available. + +
+ RHEL >=6 and Fedora >=13 + + yum install qemu-kvm virt-viewer + + + The package spice-protocol will be downloaded automatically as a dependency of package kvm. + +
+
RHEVM Users + + + oVirt/RHEVM users + could be also interested in the spice-xpi package as it allows you + to execute spice-client directly from the oVirt/RHEVM UserPortal. + + yum install spice-xpi + +
+
+ +
+ Generic Build Instructions + + + This section is for distributions that don't have *spice* packages in their repositories. + It will show you step by step how to build the required spice components. + + +
+ Client requirements + + + autotools + gtk+2 > 2.18 or gtk+3 + celt = 0.5.1.3 The exact version is required due to the lack of backwards compatibility in newer celt releases. + cyrus-sasl + pixman + openssl + pyparsing + usbredir + PolicyKit + +
+ +
+ Host requirements + + KVM supported by kernel (It should work also without KVM, but + it's not being tested as most Linux distrubitions already support + KVM.) + + +
+ +
+ Guest requirements +
+ Linux Guest + + spice-vdagent requires virtio-serial support to be enabled. This is described in the chapter Spice basics. + Guest should have installed qxl driver (xorg-x11-drv-qxl on Fedora and RHEL). + +
+
+ Windows Guest + + Drivers for QXL and drivers for virtio-serial require Win XP SP3 and Win 7. + +
+ +
+ Setting up the build environment + + + This is a list of prerequisites on RHEL or Fedora. Install + equivalent packages for your distribution in case that you're not using RHEL + or Fedora. + + + All prerequisites for Windows are available in one big package which is available + at http://spice-space.org/download.html. + + yum install git pixman-devel celt051-devel cegui-devel libjpeg-devel alsa-lib-devel log4cpp-devel \ + openssl-devel libXrandr-devel libgcrypt-devel SDL-devel nss-devel dev86 iasl pyparsing + + + Package prerequisites for Ubuntu + + apt-get install build-essential autoconf git-core libtool liblog4cpp5-dev libavcodec-dev \ + libssl-dev xlibmesa-glu-dev libasound-dev libpng12-dev libfreetype6-dev libfontconfig1-dev \ + libogg-dev libxrandr-dev kvm libgcrypt-dev libsdl-dev + +
+ +
+ Building libcacard + Fedora >=14 RHEL >=6.1 has libcacard already available. So you can install it directly trough yum. + yum install libcacard + Otherwise follow these instructions. The environment + variable $BUILD_ROOT will point to a directory with stored sources and will + be used during the whole build process. The variable $INST_ROOT will point to a + directory in which Spice will be installed. + export BUILD_ROOT=/tmp/spice; mkdir $BUILD_ROOT; cd $BUILD_ROOT; +export INST_ROOT="/opt/spice"; mkdir $INST_ROOT +git clone git://anongit.freedesktop.org/~alon/libcacard +cd libcacard +./configure --prefix=/usr --libdir=/usr/lib64 # Ignore --libdir at Ubuntu +make +make install + +
+ +
+ Getting client sources + + cd $BUILD_ROOT +git clone git://cgit.freedesktop.org/spice/spice-protocol +git clone git://cgit.freedesktop.org/spice/spice +wget http://downloads.us.xiph.org/releases/celt/celt-0.5.1.3.tar.gz +tar xvzf celt-0.5.1.3.tar.gz + +
+ +
+ Getting client/server sources + Skip this section if you don't want to build server side. + cd $BUILD_ROOT +git clone git://cgit.freedesktop.org/spice/qemu +cd qemu; git checkout -b spice.v13 origin/spice.v13; cd .. +git clone git://cgit.freedesktop.org/spice/spice-protocol +git clone git://cgit.freedesktop.org/spice/spice +git clone git://cgit.freedesktop.org/spice/win32/vd_agent +git clone git://cgit.freedesktop.org/spice/win32/qxl +git clone git://cgit.freedesktop.org/spice/slirp +wget http://downloads.us.xiph.org/releases/celt/celt-0.5.1.3.tar.gz +tar xvzf celt-0.5.1.3.tar.gz + +
+ +
+ Building common sources. + This part applies to both server and client build process. + cd $BUILD_ROOT/spice-protocol +mkdir m4 +./autogen.sh --prefix=$INST_ROOT +sudo make install +cd $BUILD_ROOT/celt-0.5.1.3 +./configure --prefix=$INST_ROOT +sudo make install + + +
+
+ Building client side tools + cd $BUILD_ROOT/spice +./autogen.sh --prefix=$INST_ROOT --enable-smartcard +cd client +sudo make install +
+ +
+ Building server side tools + These instructions contain flags for a minimal working build of qemu with Spice support enabled. + You might want to build qemu with the --enable-io-thread option + cd $SRC_ROOT/qemu +./configure --prefix=$INST_ROOT --target-list=x86_64-softmmu --enable-spice +make +
+ +
+ +
+ Setting up PATH + Last steps before starting with Spice are to set proper PATH variable. + For example RHEL is using /usr/libexec as directory for spicec and qemu-kvm binaries. + The following setup should be suitable for qemu and Spice built according to the instructions in + this chapter. + + + echo "export PATH=$PATH:$INST_ROOT/bin:$BUILD_ROOT/x86_64-softmmu >> ~/.bashrc +source ~/.bashrc + + You should now be able to access the qemu-system-x86_64 and spicec binaries. +
+
+ +
diff --git a/docs/manual/SpiceUserManual-Introduction.xml b/docs/manual/SpiceUserManual-Introduction.xml new file mode 100644 index 00000000..f5618bd0 --- /dev/null +++ b/docs/manual/SpiceUserManual-Introduction.xml @@ -0,0 +1,264 @@ + + + + + Introduction + + Spice is an open remote computing solution, providing client access to remote displays and devices (e.g. keyboard, mouse, audio). + At the moment, it's mainly used to get remote access to virtual machines. Spice provides a desktop-like user experience, while trying to + offload most of the intensive CPU and GPU tasks to the client. + + The basic building blocks of Spice are: + + + + Spice Server + Spice Client + Spice Protocol + + + + The following sections provide basic information on Spice components and features, obtaining, building installing and using Spice. + + +
+ Spice and Spice-related Components +
+ Spice Server + + Spice server is implemented in libspice, a VDI pluggable library. + Currently, the main user of this library is QEMU. QEMU uses spice-server + to provide remote access to virtual machines through the Spice protocol. + Virtual Device Interface (VDI) defines a set of interfaces that provide + a standard way to publish virtual devices (e.g. display device, keyboard, + mouse) and enables different Spice components to interact with those + devices. On one side, the server communicates with the remote client + using the Spice protocol and on the other side, it interacts with the + VDI host application (e.g QEMU). + +
+ +
+ Spice Client + + The Spice client is a cross-platform (Linux and Windows) + which is used by the end user to access remote systems through Spice. + The recommended client is remote-viewer + (which is shipped with virt-viewer). + GNOME Boxes + can also be used as a Spice client. spicec is an obsolete + legacy client, and spicy is only a test application. + +
+ +
+ QXL Device and Drivers + + Spice server supports the QXL VDI interface. When libspice is used with + QEMU, a specific video PCI device can be used for improving + remote display performance and enhancing the graphic capabilities of the + guest graphic system. This video device is called a QXL + device and requires guest QXL drivers for full functionality. However, + standard VGA is supported when no driver exists. + +
+ +
+ Spice Agent + + The Spice agent is an optional component for enhancing user + experience and performing guest-oriented management tasks. + For example, the agent injects mouse position and state to + the guest when using client mouse mode. It also enables you to + move cursor freely between guest and client. Other features + of agent are shared clipboard (copy and paste between guest and host) + and aligning guest resolution with client when entering fullscreen mode. + +
+ +
+ VDI Port Device + + Spice protocol supports a communication channel between the + client and the agent on the server side. When using QEMU, Spice agent + resides on the guest. VDI port is a QEMU PCI device used + for communication with the agent. + +
+ +
+ +
+ Features + + The server and client communicate via channels. Each channel is dedicated to + a specific type of data. The available channels are following. + +
+ Multiple Channels + + + + Main - control and configuration + + + Display - graphics commands images and video streams + + + Inputs - keyboard and mouse inputs + + + Cursor - pointer device position and cursor shape + + + Playback - audio received from the server to be played by the client + + + Record - audio captured on the client side + + + Smartcard - passthrough of smartcard data from the client machine to the guest OS + + + USB - redirection of USB devices plugged into the client to the guest OS + + +
+ +
+ Image Compression + + + Spice offers several image compression algorithms, which + can be chosen on server initiation and dynamically at run-time. Quic is a + Spice proprietary image compression technology based on the SFALIC + algorithm. The Lempel-Ziv (LZ) algorithm is another option. Both Quic and + LZ are local algorithms encoding each image separately. Global LZ (GLZ) is + another proprietary Spice technology that uses LZ with history-based global + dictionary. GLZ takes advantage of repeating patterns among images to + shrink the traffic and save bandwidth, which is critical in a WAN + environment. Spice also offers an automatic mode for compression selection + per image, where the choice between LZ/GLZ and Quic is heuristically based + on image properties. Conceptually, synthetic images are better compressed + with LZ/GLZ and real images are better with Quic. + +
+ +
+ Video Compression + + + Spice uses loss-less compression for images sent to the + client. However, video streams are handled differently. Spice server + heuristically identifies video areas and sends them as a video stream coded + using M-JPEG. This handling saves a lot of traffic, improving Spice + performance, especially in a WAN environment. However, in some + circumstances the heuristic behavior might cause low quality images (e.g. + identifying updated text area as a video stream). Video streaming can be + chosen on server initiation and dynamically at run-time. + +
+ +
+ Mouse modes + + + Spice supports two mouse modes: server and client. The mode + can be changed dynamically and is negotiated between the client and the + server. + + + + + Server mouse - When a user + clicks inside the Spice client window, the client mouse is + captured and set invisible. In this mode, the server controls + the mouse position on display. However, it might be problematic + on WAN or on a loaded server, where mouse cursor might have some + latency or non-responsiveness. + + + + + + Client mouse - Not + captured and is used as the effective pointing device. To enable + client mouse, the VDI host application must register an absolute + pointing device (e.g. USB tablet in QEMU). This mode is + appropriate for WAN or or for a loaded server, since cursor has + smooth motion and responsiveness. However, the cursor might + lose synchronization (position and shape) for a while. + + + + +
+ +
+ Other Features + + + + + Multiple Monitors - any number of monitors is supported + + + + + + Arbitrary Resolution - when + using the QXL driver, the resolution of the guest OS will be + automatically adjusted to the size of the client window. + + + + + + USB Redirection - Spice + can be used to redirect USB devices that are plugged in the + client to the guest OS. This redirection can either be + automatic (all newly plugged devices are redirected), or manual + (the user selects which devices (s)he wants to redirect). + + + + + + Smartcard Redirection - + data from smartcard that are inserted into the client machine + can be passed through to the guest OS. The smartcard can be + used by both the client OS and the guest OS. + + + + + + Bidirectional Audio - Spice supports audio playback and recording. Playback is compressed using the CELT algorithm + + + + + + Lip-sync - between video and audio. Available only when video streaming is enabled. + + + + + + Migration - switching channel connectivity for supporting server migration + + + + + + Pixmap and Palette caching + + + + +
+
+ +
diff --git a/docs/manual/SpiceUserManual-References.xml b/docs/manual/SpiceUserManual-References.xml new file mode 100644 index 00000000..6fcee02c --- /dev/null +++ b/docs/manual/SpiceUserManual-References.xml @@ -0,0 +1,218 @@ + + + + + QEMU Spice Reference + +
+ QEMU Spice command line options + + They are covered in QEMU online documentation. + Basic syntax is -spice <spice_options> + + + + + [port=<port>][,tls-port=<tls-port>][,addr=<addr>] + Listen on interface addr <addr> (if given, otherwise any interface) + using port <port> and/or tls-port <tls-port> (at least one of them must be given) + + + + ipv4=<on|off> + IPv4 only (default:off) + + + + ipv6=<on|off> + IPv6 only (default:off) + + + + + image-compression=on|auto_glz|auto_lz|quic|glz|lz|off + Set image compression (default=on=auto_glz) + quic is based on the SFALIC algorithm + lz is the Lempel-Ziv algorithm, glz uses lz with history based global dictionary + The auto_[glz/lz] modes choose between the [glz/lz] and quic, + based on the image properties + + + + streaming-video=<all|filter|off> + Set video streams detection and (lossy) compression (default=filter) + + + + playback-compression=<on|off> + Set playback compression, using the CELT algorithm (default=on) + + + + jpeg-wan-compression=<auto|never|always> + (default = auto) + + + + zlib-glz-wan-compression=<auto|never|always> + (default = auto) + + + + + disable-ticketing + Enables client connection with no password. + + + + password=<password> + Set ticket password, which must be used by a client for connection. The passwords never expires. + + + + sasl=<on|off> + + + + x509-dir=<dir_name> + + + + x509-key-file=<key_file> + TLS private key file + + + + x509-key-password=<pem_password> + Password to open the private key file which is in PEM format + + + + x509-cert-file=<cert_file> + TLS certificate file + + + + tls-cacert-file=<ca_file> + SSL certificates file of the trusted CA (certificate authority) and CRL (certificate revocation list) + + + + x509-dh-key-file=<dh_file> + Symmetric Diffie-Hellman key file + + + + tls-ciphers=<ciphers> + Cipher suite to use, see http://www.openssl.org/docs/apps/ciphers.html or ciphers(1) + + + + tls-channel=[all|channel_name] + plaintext-channel=[all|channel_name] + Force TLS/plain text connection on all/specific channels. This option + can be specified multiple times in order to force multiple channels + to use TLS or plain text. + Channels are: main, display, inputs, cursor, playback and record + By default, any channel allows both TLS and plain text connection, depending on the + port and tls-port parameters. + + + + + + agent-mouse=<on|off> + Define whether spice agent is used for client mouse mode (default=on) + + + + disable-copy-paste=<on|off> + (default=off) + + + + disable-agent-file-xfer=<on|off> + (default=off) + + + + seamless-migration=<on|off> + (default=off) + + +
+ +
+ QEMU QXL command line options + + + ram_size + + + vram_size + + + revision + + + debug + + + guestdebug + + + cmdlog + + + ram_size_mb + + + vram_size_mb + + + vram64_size_mb + + + vgamem_mb + + + surfaces + + +
+ +
+ QEMU Console Spice control commands + + + set_password spice <password> [keep|disconnect] + Set the spice connection ticket (one time password). An + empty password prevents any connection. keep/disconnect + indicates what to do if a client is already connected + when the command is issued. + + + + expire_password + + + + client_migrate_info + + + +
+ +
+ QEMU Console Spice info commands + + + info spice + Show current spice state + + +
+ +
diff --git a/docs/manual/SpiceUserManual.xml b/docs/manual/SpiceUserManual.xml new file mode 100644 index 00000000..d7106361 --- /dev/null +++ b/docs/manual/SpiceUserManual.xml @@ -0,0 +1,71 @@ + + + + + + Spice User Manual + + + + Lubos Kocman + lkocman@redhat.com + + + Arnon Giloba + agiloba@redhat.com + + + Yaniv Kamay + ykamay@redhat.com + + + Christophe Fergeau + cfergeau@redhat.com + + + + + 2009 + 2010 + 2011 + 2013 + Red Hat, Inc. + + + + + Licensed under a Creative Commons Attribution-Share Alike 3.0 United States License + (see http://creativecommons.org/licenses/by-sa/3.0/us/legalcode). + + + Draft 6 + Built on + + + + + + + + + Lubos Kocman + + + + + + + + + + + + + + + + diff --git a/docs/manual/resources/pepper.png b/docs/manual/resources/pepper.png new file mode 100644 index 0000000000000000000000000000000000000000..e837194edfb42ccf788e444f6787e3e98452a949 GIT binary patch literal 10582 zcmV-cDXG?pP)Px$EKp2TMF0Q*=l}o!007(o0LTCUumAw00058x0DJ%d{9Ii8R8;(AWc-kj{D6S` zNJwx10Q_)p{5UxLXlOtH0Q_KJ{3s}x003M704x9iPyhhD008_D5d1tmQ~&@V000mG z0Q`7({4g+R003YB0Q^KmbN~SSARvSQ0E_?t&;S5L002w?00;m8FaQAjEG!TV3_vU_ zBme-o003A30Du4htN;MS007_s04M+ehyVbb005`}0Q^{3Gynk9006WA0Q`uEH~;_y z1OzA?96SI37ytmE002k;0C)fZ*Z=@*003kF02}}S>;M4F008`;pb!WMlmGw}006)M z0Q^u;dugAQTidARs&_C|Ec+a7ajmSXlfR81ha# zA^-pY0d!JMQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L00tre00trfVD7y!00007 zbV*G`2ipS!5*0M)oA%8B03ZNKL_t(|+Rc3ld)i30HfXQHlvLUfLISiQ#MTWM?@N3; zarX4ycV_PW_W%DMzEff`*u-&Ti%dP!os2uguh06PQ>Us*rDrXU`_F3W-*HvBeEplD z`#=B5ZLEI_NwvA{>-$0a2luV@YVVl-n|tDF?-f>``x{H!AFd}N`j7wEGqkVS`a@(t z{II~L{rr7!ef19kv>)cb(+~EJ>+wJM!@i*Xok+D;Xn!w+E};GNQ{mA5c4S|eTH(-k zNI46k{rJ#9Q!3mCwB2&_|IYRK(~m#?xPW&1($EfeB@c6<{dfmWIVehE|JdP^ zKm4=??PV2u2Q2)%AN^}3v?Vm{;CtKHy3l?s2HNuo>Kd{Iw0~3&{%w%u-gyU2dnsto z=3oQa4|nXF ztM0K3%_Y=oHb3=xmo4_q2i=j?Ilk)t^}q58?;f%Pyf<9q=1FwsCc|FxVKD#h#(4u) zxqSTI{_CfOK9|s{2M5~0UgS1#5@jl(_v59CCmA9OTOZ8~0oqo;2&KG!cbIKy56Z2dRpp z1OOM(drK?$+P?kJ`|YKG8B>LvDoLb>j|%H6_y8b?PpyNv907Ys$483u%ZmWJw7Va% z(efFv@@@;@0XU<1IlU$bRsMCBINS@^m_mdE9}R2r&cJeTf(U{$dj3Q}CK2Rl{5))R zFn-b|0REy--E*9UQpYE!v3J|wm3+12_vF_c84e(5@Y{hk_<59D zL)M{?H?gLVMxOQM{^xj}VQUWRaopX_M}OfWK?zUHR~i_a7|Pq!$qStz74C5rHq~jJqO0yNyNT@V3PLvm7pR~^YPrI;STM0Di6@7dxTZB0z94=L zLs1IcM3uIEP*R(%tRhTzs=r?czcXYys1r|!`%s6ZD87FPB4sLN8qMweP%*l= zts~l1w+maUwIbBM-3eJlfz=F9rLCD1dx|POL?+3JqI7N1&3IShJLSf4r@=Ckq^Q16 z&FZUzDzdC?zQc=()3UVdPk$d+i&H2Nj25nFuk;HnT z?ssmDDArL$Ya{Az^BrE0>n&TqaGV`vmQWyn1Hr6RA=r|sabKOhFgf=0YN>Pp&`fg7 zkcmKo;Fm8J)=h*7q)E)n+r3(BuTG z2W@m{9Pq;N2);}@Vb8beHs_oRTpjjNb-D{O$Ib~eG4%rwnl-H7S0^tXQ7Za9Km4d3 z$^fjxARhBVRxZ0Ur~(Y5J_`b2d-f1y=LA*5XqR{vGG5QkK%G^+f)zu3pic42d97aW zT1PUA^?bt$tOm0*AU*JPC>IpvOXn-3j+g2uR8yi|oYUzh{y4;yO8Wq!ZS2?OhtODp zJhqN=3J%b~%J@8L$TK^YAeM+RkK=V!U7x;*o~@7(Ex1VV}4=<)9+61On$*&d45hC4{LR( zlkv(iRow_PNCN)rJ zv+3?y8V{!SwZNp-24wi{!)VJiS2I3_;k!g-@D!*mn>Hcc)}S>W8tP+W6J(<$?b=ar zK7EkSgdm8k5IN$@`^XsGNI&|3gm^S?L&Grq-gw~Hgk{Z1)bB+MoA9+@TN?_=u7wKM zOJr9FF2K$z;Y_ll{@XA~w|N7ww4}Rx>xwh_ z$q@(u5>&WJ(twz%e&6tqbVky2LMOi-FLC{I{$Zw69b`#I?#!J$B<$khX>(^}P0k4y z$fOOv0o0KX2-0-i&5#z{v<7d9_KIn7eJ`9XMk6ty7XLtMg8Z)k455va+yN@4=hxP% z0bX<|25Z-}i&-!4+HrmULSvd`XqK~(2i3M-xu8cBahuh06q*a$IT|An&AaYvlrd|r@pq78u$mXyH?P6h)j@ApM&g|1n0<*=&v{$ z06XgTLmmuE!_i<$gY2}c_$SRIuC%KH>ofLkEl2jMs+pLikqdpchAbbJeGW*u1vcVeWq<94a^N+a(>;5#+Ou~Umu`-B@# zKm3a6=@=4vUjTJh(1&d9x=^)mrnp1@ImishW%+5v9eJUFN0v$SBNLKi2~>U58>VTh zrhGuD$2xD#v7l)>dQVKVqU#WHOcT4j=ixY8cTu21e(O15qla1gBPYfZ8E;wXOd&W_ zAP1DH=zU*_2^|F_02Y}^_U$~Hff{vs1r(&BGY@k8u1BSf=po4Ab2{)`WCAkaj!U)y zC9tF#<1W7DZcA-l@77}vxFZPyn?ePsy?XU34`~dV#J$d;=@k=^q~?E2*Qkx z@BETz3>lgZ7i@!{cN{&WrJ&3<>Go*sdB>sO8+K#8qAxkeK?!))aRr&r)a=+h0J6X zwfP>K6$EK)w3eoLvDSJH5ejo6Wa9o><`kg95Uc3t(m`9(VL?5bdBp2;O-p0^0$4Zz zGhIjpEmYCl%+kOQ5RR?Mdc#?LM%dt5k85+haVT%pXl9z27xV&Q#9B%fmQL}T8$~+Y=yyTcxihjp_gWU>d9%s`&anK8!3p^I zx~JtPmH$)4A3#Jy5DzfmD`ZtPjp0RX7y&Vb^EEN1{6-eYk?jbrKbW4mUIo%Ji%E2L zxbOm~1m4@jkmyKbwFm$+XDr5AW(8yff&yv2sv?ilPG(PUx)_FZ43dCEbZgin8ngLO(W!gcznsXkYk}|7V zS{!Q%)!3AWB+0O(2W<}4OP=8!k@e2g=z0mwq%7Pn_vJd0JA&Fy>PZkbm>=YYoECH~ znxr7j)@3hD?elpH>)}T6VrwAXt-s-5s1>3)l_5v(RCO!%id16^>yEc5ovd+^XlyXORGWuCtkXoju z|N7_8jCUvfM9iQ}unwio!cH;5on+<=`hd*mPN+x_9!07oG&c5=*w*>`A(!fFQ-c`7 zEilKNfuMypwd$)^K)#VT+w5IJ=Io>0A}t`RV0+vfzH>*sEQt@>U{bdUesY&%qSIT* zMAszmzU2QLUC)aH4G8y0zK?AB3}oooFre0DV~!8I)KEwbYY@5?+`b>gNHi z!e-4Ovm)z0vifewN^_ZI5rdVFUv5LD#INSAxJm%0@3D@OQ>yFM$r-_HlYn^vy7255 zL-tyLJU+{}Lm>5K;N78MkTVh={6cg%yv^xPkZmgRbIL5Axjmz!{*Hqb%ph6(;QGXMebUrGPlh;IV zYd9Hj<6f%?WiMvojM89~iQO8re+1F2Bk-~;G}fmmK$%>!E3&Z?ah##5^`3`V1@80K z1~MhnwUCplCB4oyZA$H0N=IVY8xDIz!x%1R@dqEeVKh&?_ms))e6~ReT|pTdb>}UJ z?7}FTE$g$as1v_8X2u5fFstt7Nvk=ZM!45KXg&j3$&dpg z4x3E{M0OGN33b7;jw4>ZMK2MHv(7IkUt@l2b^u-Wx6j(J;2(}yE`f&xE) zv@^0#Qx}mF?!;s56iLN#c@3H6W$G*@Vb80!#af>CWqWi{EwR0dQX3~TlAlnl>an#Y z<$?on>CVU^XND5^(OA)mYa$6ot6fxH_>3(GaF*&@TFK3iIEa$PDo9|p8ll~UBE~%0 zI;I_AJF;hN?{Eo3g9wTg(%Ug^20{HilYBWQ{=wsZ89H-f8 zHMj4*N(RR%rRNEam^i^Uk2}#uMrRX_mk(UhX%J!gEHD3`dcex>a%Za;#x^yLVA|oj%fKQ1CKy6qf^z0ChubukPdJyt=7u^1XmlI+#+;w&56+F`uGuU-UuZ}< zCG_2Fqp$JxQ%-U^Vmq@{&D8U~YYlbpPp0!MpZlffLVJByL4KEv)bq|$PVs;`Lux{G zcOeLIg{1+Fr1y~J4lsQ-vOyG>)Uc^5Po8qd4ib+M+TE%1TDi(6n8487!~50Ai(FU6 zIWjhd8=IFU;YrApk5psD0ihHM(E6KU?c?TP`m-~@l0b5`BcK{5{u9sH335c+Y>!i7 zEtg^Ndq5Lad_c~k(hCS}00a#kUOMWNga*iL;6JRB!1z$<038_{2U=cAnGD+HtyV!+ z_?4qsTjo-w>bx{&^DZcHni~`IFQv@+*yA}si|zDjX+Rx@I+GT-rA~BwESzr4F$+rb z1!Bgk&36`D+jheCU-@rGG{1}5Y*pv@^o_7F=Voc?g@pFYboT!0^n~@AzG-Vv)Q_+U z)h6opT4Mn?F1FW@<=er7(n~F_dke%ty6HvAH{AfTdfN4f*aHCm3?$d4$sIC253}9U z%dPVd8QZnC>#F>%z^cRf==$z%to*7mFGT4!?7;dhHHDH0vqe@mR@#o27@Ma zZCH=S57r*;k!oo^@@r!E?yOnvnJv5Y($J>3$_||(>^*wk1d!GI4{RHe`;@rv`O`II ztTuU5dhx~eZ8q9cF+E#;^h}4$!u;Y+j(5u19(mn1$Vw1CakZBsZTp`P&nNke0l7Th!@HFgZJDy@) z*8rSwo17n1^G5U<&*&C}taPo@6XOvx6C@>Zk1tB4vtbtlhtz%@uMR)taW*LmSr^;m z`r~Gn;C5b`P4y9FLYN))dnf(GMS0T^#or z?dvgvQCgQUGi#%mH8#xfF2v*xP*l(uD_85v@ZPkjK zwbqqs9XIY>S0Se(gb)cbJLxr>&U9$pAuG@UxR9pnF{42@J4AegcUAxGjdQmle7Cuu zJ3v$rvcVZL*369O8=Xy&S#cl@TPHUIZV>gI-YHM!Get!^K;3cUH~v~QCYy|3EXT_Ssad-gF_o81I!$E_RpoU|iI7Qt+XB6Bl>+AOoji`u?O2XH`{ zwtaVfM&meWJV@u0fE`p}1K%1Oem`h;7R`eq9f0cxD59e~nKd2;4LKT0`PsU5yRDg! z*om_6fZPF!VU1%>F=?N6q(_-{t>@+2=em|(1>((?J){CD5a$HQ4r%rcWT%ic^<&%5 zcZH!mU5YF>vtk^8iz@h}7km*PEt_hGbg~L(gOl;bg* z;U_07XuL-nR9WFNIpt1{8!#*Hmhr_EE-Q_{!7jFWs+5cGu zWskK)bBU#=iHJ3kus3&SihX*&HV_8$`&D>Q4) zaOm59y@?B2n_0o?`k*{!6oTy6B;~m6%A8-!lSf$(v)y3KkWC~- zQKZ#;a2_)XQRb!W4w|a8<$Mskr)qwk-68cn4nptzDi~pfblvk8=+5tJwG@ zk!2ToFX>pxg99!<6BdC1mmkXBxVhqT{MjSUp zQI@I3=rytq0hs&ci#riBzFc^F7XDsLMroOPR%3qOSw2RU-~IPFw%8#fHDKp-s<8{Y z6h?6jKf>KM7*nQG46-I6;zye<=kM56as2$kETL>Q*zLlGt(U<1XA0OoPYJAGRgC62 zvk=ehH)nwwO8lrHE`V7e!rUp@&~t8O?|fNOd|#E>4O-{3nVa3s9u}v}BoP#eWtzqI zA)AXES-JeI`Gw39lTu6%YqFT*v~BrrKkxbDW?x;Olq*8r!&Nxrh5YtQhOCn#bIZ8Y zHVF~fRT|>td_>6T?$Ca|rBhI$DPKuUPyE{TJUo+`z;})zWR&UXsuR!=pWpE~u>z=? zaAyz7EDgf`jo;lEbL1_YL+e-pFYz(XfSA2g581(6p@Vg=^QW+(%z7cfdfbWc`|{?P zqZM?@U{m0wBE+xRyU=Aqo3Lnd99Zt!6j6aKplHy$-rNJr?{w@;B#E~y_(eQSM}(c* zIiBCW%1_pgZWTu}AUE~IXn5Doo8ONv$*wFbUCBLyU(_ttG-8z}^D6;`^)t&w?&v7f zkaLu~$!G>kR@{!D+Orw_PEluZ$>Y<*WuV|U29yeH8>fBlZgYYa;^*gfnp(&LcHspb z7g#o;6II!IDP@7dtW^5#HTc%T%os&6lw#Dw`gE3?_9WdJ7$6Q4{7scm@P_R2>LRxiYoHFOo??J2Z@xb zb_|Shbpr>#c!l9E{u@Ohi^d$=qHN5qUlu&=Lhpzkh)gfr?}FgUb+a$4TQ15L%c=Z6 zL{{D5{k*)n|t3+Y%a%a`}C)mlmu;SCFC`T2Mk2g=a#c_OH)Ygxx< z?+#NSYZkwtM`eoinBPd5#fdBpWzJzFLU7M(DIqTKLp5^`g_r;g&zjB3pZR5o1#|qo zy7jN%ee=?7^cn&!AhUvzs8~ezXkhd7{M;IqsaDdU@?F)H;3h}qJNtjebuCX>ZhgSj z*@Y(~cD<^H+ZrB87V0SSp_+Cm-MHB47>dtEV|}OfLxIRb);ItXoppeXQLNJ}id<~5 z%QF;3cGr&(=fyF$4DjC}uIkM;O3s720=ux?|I zYpEi;?LG*~x1sMC&M<@`Bu)A3KCniov!}!~ujzmTF=SalgUq%Q-w;jgk=R1QfiON*+|nyll9YCuo{g$vHzMI+QP4Ar8PU)@&K2mtxr0qS{TN(x1G21-$(JPHu;hZFt~3KB!f zI+9E& zryZCIAQL6k_H;c?Ri4rg|Ft6@MfLLTmdz>*wRQ$nOh;M78g~l2x{TO|$JW>0$`Fd% zGrwCBAgkA;7+qW-ov_OfMR^9H4XB3D_{zodyvP!hQ!p}iVO?F#Jdf={lXG?zh;$y{ zk*!QRoyJ$67b)KUOAu#UHPvGG8<>l}Bh)Fb%nH!20GlVKqU}F-&6><^i9YK3`LUw> zO%&;o6CZPtg+(LF9Y9UfP;te@$sI_L{9`9kczGWpvvV_3>q$T~yxd1^Smj3!do()A z9;}SzCawl#f8=3&cZj+1_^G1d9z<4B@~jCCP(s1^(@t$4iC%#IkwN zPyv}BJPlZ*eAwEH$Z|rfh)=}@Q7$v~BQhqlrYtrZ<);A?vWVM{$a2~!3-{;7ADLO& zlP>43DG7X|@g#|fYLhFtVX$g9GS?KJ_NeOWINe@EmY>de+H12WkHAW^{2s|~-$D}EB)<@OZ@}hRQ~2iH5H-a^nAHunjvH2!wbVCP7ARB>PL6__~wX3$`7w@ir{ z^tj7?B6Gpc*3aE`w%!WyHb6Mx_A0WHd%}VS{|GQat`8@uBJUYk$ryekXb4ixkif{C zJp(Jf88E8-SkbE*AvS~8`v#VNBcC%P^NES4FMRvS(+KU-0k*uvn;V(1f9s$3L7U2B zw+PgRU9kSv-hq`~8;_Y8d%gY!n`h1a1M5DT0eDe$TDB>E2VnU|fGU2S_d8sV2>tH> ztaQ7L0`beIjTM7yQj|2m12DEncb{mm(MvX|odatfRlDB>Sia#Z-q)ej7zGWH72`ty z=6nxeCH$ZWX4P)l!y{J)V7)8tI{{-d+w@EZ%%#}N)EYDX?<28a-BTj6!4`fKm^{L` zqt+d+d9`0)(~6b`4CAI)~0@uy1zRzEpA za$WJ_?rFc}>wZej^{{8Nw>Hm&!huC#<~93>kWBE}C=322yeA0R;}*fEwY8~ZNmlET z>yc5)fQ7EoD-@P7a9&4e0wL__LS5G@>;jRGQ6DO%xA`5u{Oa`|wf?ai5FGgIDTNa| zDO6$(_bF0rVxrStFG+2FlEl`BR=&o)VEGJOj;rQ}HpR%ikn$%UlG?aHaltoml-FDj z6Q#wqhQp!X8~SYGtzI`Aqr=X|iFq0VJw{6Amj`8nmL>HETn+>{Fk; z-?mt6I#8_{X9Sno9&0YJXhzB6Ev1-^It-=-?J0%fr&eDMOq33|`J-~HC(@4CfgmvT zlp^mupHc;fjLLw^oWBQ|pZqnd1)$2WNQmTf0U@khI<*{>An>b|8UNd4nOO;xH^mfh`6Ey@Mf$Ss`NTVk**wK20`#@IVH0$LOvD_s5{rpb3^3LS zZmRjovaie-<<_6EQAQL?e%&y@C-e7E;eVK(hrbn6i8SYX&OHCvr5(~|j}VV1G&PK7 zi05zU3ATV;+bFEl$$jILd#=mOBUT{23oIxkPx$;rL>ylU_*xkkcEqKs+~cPY=Vcn5 zBMW<1G>L>mqt(h^&CpDIadE9&7TCAYysutau!#KvZ@Ha-+E!#lL#{Ppj}%uA4z%kJ z<3gM1nte0ej*Mrof${G}i5-2(q~uq_X>pE#09Vz!PV%?7ilkz?GuVDL9^V-8vTJoD z`B<_8X_B1*6z7;-b#JO62TmujV>WPL8T9cu!7z7#E9d z>SEM?^TD|$r$DpAtM-B34FT7G0Mu$?PJ=z9U< zZvPjqSK8lNydI|vxL%a9yJ;fdF)nQ=@$#x8FUQ_5RL*-~~q)B#lQB4`rIJY2ML=*o~t8wDkQ~ kHGf!9)7sU8?+xYu18@`(iBJ0S!Tg)JI44)!ji_C0HI&qS)L%H1cRCIA2c_Z8%&H35KI zaoC?Q-firWTEhf#?Bn+H{Z|Ag$dXr_|EbMZU6uw)|HU_ z79cI-5%wUiyMl@gF6s^;Av2-gnKAaYi;k@ojIRGn#lmpy@h6-NtF9YiydFC zRh81)*OHR&UOgr12HmnCvsWgnS@~t^ynU*=z1|s*W@Tf4L3ZIyPFh zi-w*TCw}TClly7pg^HqrvoRk0lVQ)mFuA9jJ~-E z1?W+N^L^g%lKw(t15JLti4g+_AKFOi<)b3L_+P>Zvy~X3q4>R+?u`8c)r*9^?0S-A z?OIj;!91tUjEnt`mnfg^4i+mdG)HEy39Z+3p1rL%G>cD>gwv6 zo0|(KrWJngrGY1$pSbRWE)TIXK(CHsEFt53`HAqY7<3smaH(U7Twu#53z-%H8W8@5 zbBoJ}=_A^MdN{kL=A}?Wsv=85))t3Ro%39SNA286&y=y(-1ZEDRdcnSo~+En%4+pl ztZ1d%`tW)-be`*j9lRdW6GPkRx#PQ$pF+uD0#XCVvlOsf;ZOK&m44;t4&Nyob};2k9qM!kcJOh zwTM|$XjIup4((A{VB==rjrMw~k#q^Dje(7Uf-y_+6_Ey ztgfz(l|Y{nayB_%?$m55PsxXnyv_Jz29cYIk;XPxN`q^P}h1h@jXttM>X8W z2@|E6wSf3OFA7b=)9mLA*ib6cwmn=M!X_<1l-t;N*{}saR64@SHC$eQad}zZd@{Qm zuT1F%b0_}}e{7y7YvMs( z;@A0+TA-PfRL8>A(1J3I$7-P^09E7Ac(xpU9hsxqkHOJY1m^!~+->26o)2VSOcWB+ z2s$4Q3HW85KEUifSUBqzp!45r!=>|HOkcQKD^N*CUt`%_YB{ew{A5v_VzpcRtc5%&tAC&3M>iF#7e)}Fw38fE@C7Y z?&V5;XmNNO8Y1C*260(d3BF5uxm(jIEgAQe+r6zdmc;z1fe@pSDo^C-J1CX4{5XpX zV)^;eVR_pn9<^IIdC!^J=9ym5bcjMJBr+m0GF6|1`x0}2ar)i9*hAiP?Y4KYNGto& zqqs5FNAQcr*4o>NuvC4bITSs|Ri&?BdTJ_6R$?XxmzF;&-086|6WwKAci?7wZqEmw zhaJrIn*CJ{=^@-?`kj&yZSUQFKVi$|Abc&YNhI@*gh~EjasNe^vojGf-POWUt}&5S z`cq1&2fv&Yh#j4|Z1d=y&|>;Orte3!sgtsbcJ}hJ3OfQKzj5x=*~Oq1zuH|5(ue?X zsg+e-I;3tbu6OK(7ou-TxOVmOvl2ZLKL`&WO}!s8`xV;!s1b+T+sS;4k1ud@P&|cDqByHShFy6 zN~1RY75O$Lx=+0U-&u!#1TCP!Nou5|moSfHk16TfcF*5m#TJIr9MUVang42SOC~WV z1km(cAI;T{9C<2PsVPG683yq)X`$p{s?yH%5bh}A0ga`%U=Huv0=>JYm zp{SD`B#&<@In44D9bS{F8Os>)J7+4~j?>oRwv%yi$@}W-R9@Z4Z2hzxFuXNL26JBv zf?oEh{k+t>oG@~bzIr_UIE81;`;u_0+tS+?3?xE??63;sE8@p^>d)+ctFk z1c2dzi>T(7N~Ngc0;-pw%dK+%otTm}v3bUy2m?_rv@nPvLf+=j#>k`KNO_xl(X#F_ zMH>iYD6M*}X{WgD)!lc86n4h?yh`#NBv*?U0ohoV{7%ISn|USb=g$b`y42&72B*Uk z83x!sQYl5*$|%}N6eW%s+R!P2)Hdcns7UL-$8k2%(>LEs?=$o{grBX<*zJB8F|gKO z;x*9`A1z z_9cgr5kUGI*>>xc3m`j!Hfv~Yma$Rt(?;?QuLt1T2$FHVs!v~dO~q*EX9lZw3kXY~ zYIkjpWA2)0k4f!S;2g-3GPE12DYW?=TWwBt=R1=u@^0E6$+PwMyBlh1B^>r3MH7+Q z50V8>dFgUC&$ic+Ycg^zn7<`6HBZK?6pnX(!j+&h1@+v1*Ox}7x~C=C*4gL2`2|?1 zqiGXwkm{^JmY~eMqs&pB6czqf*P~tM=m4oo{E&L-E6Kg#MO?tHuPMHHfh82Irsu~; z7TNtpQgNs>DN34goO%;x@M!6ea!h8G!#a}^V{*LU0Re!8yMo1?_z_e&=1bYm&c1Xz zk4gt0Xq-=_BTkaUCV$(XV`>WG)x28SH#^=hgG&ft;jLhCtqF@Ch2+&2wlbtwAJ#hy zeyQ$9dCJN4#COQ0rKi*MWQsVU6oa%Bil9BbZ~}F=GPaT@~oG!?$Pe<4LpRt(nW)bJ;flK)OL*2;n#A&;@kre6vR!) zAX(4{Id2i4MQss~QsGeb)^SC=Fz2p1=;!Q>!}jt_kjEJQ;_unbkb&UdxL;7u-qO^_ z(5IL|0jbkt44in$LK2W#`d#?j#-Hr6Zmth;z{Em(wODHZPb1eMe2gsXG-6~y1!j*W z*;j2eZTFP>@Hha1mti^tHZ?Is9M~HRsCBJYqQfI{Vz4SWv9g=ITwyMyqDU3G&I3u;%$z7%KY%|CL z4q$Wa5*2lUdS1ts-OM^`7gQ%b)CC+RAODCUQ#Q9h7Xv-*Frg(+e&(Ijc}+$cM6>_W z8rj+T@df_VcP%tP51y`_&|9 z%udO`<<6c5l>oeGWfu*Z+I`bhJy2jI-28U-0M@!txAINEmym3g-q1jNF{Io?^N%fY z7nuMYrUNO)aVvhZ#YVjSlN??GY!}G6wP=55i^AH@d8{wn-dp5JWz_w7=;zg?kLA$a zeBC$EW8S^}r%dF$eyFqq9|2tw1!>E9&yzn+7w2KL5@*JG@=-^xFu9zx_DkxWo`?-? z>)~FA!_6c?#Da1wDk{9ulRd^;z74gU^@t&39l3JPa3_633roLKEAuHM^-0v|!?K9h zi~jiQ%$e#GKIEg}m<|WI!^j7qqU0HOH$_-{uo9JaOY_zbxJhFP>s&(ry3t%pe@-M0 zz}mue_nwBHo*r~SBBmu7#*au0=JQkjB+sn`#6gVF5Wo&M6+LNpxbN0yQEJLFL>O>C z(NuhGXxH^Cmi4tJ-p&H;s({NXO)?oZq%}xUd=3$mLy#=^U z2rxakL)eJjBh{BCvo5>+?sKAkD%tHwCH*&qhI#s~4u-Fo_pnbKDu zK$6%b`G62`oBVI@+l1CMIPadS;E!SeM4F96&fZ#?P<-h8}YI`&AztMA^nr{;T1Z%l(60RU1yz!L&s}?K+H!}WPp1*lE zB}M)Zm7Yibt#|oNKVf^~F}9Olf0s081-w#!T7i`t2k`FuZ2-1;Z)U)aiS6}&nI!sv zf0;MF|Cq0^v*jQ2CiGwCKS(#`KS=)#m_&d2?}7gF>HoLm{(q_9Kd1Pw;<42HUvu%F zk#0EuKa>2wv-;nVzQcGUd-toJcDDfDxltxOWz@p+J&I0w1_vw}u|)jAAUP5uJ~cZG ziW)pg3d^bPM&qOocIe=}Uf&gcEBIL%Lw|pK-4d~ZSSW=eb~2f z_{n+?@E$b&({FJHjkXjuaWNYso- za8k6%?EjTVqG+QB6iGoS^HLB$4&%H3j2d4FxJO99l?I8CWt2IN?2oEEbi2^h&_GU( z@{s8d4h~uyyAmKv)h>xY8_@h7c7(1b&G1qu8&z$d55+1B^shVgeCuGa8=2s<3KA?NElJenw&+olN=c9~2+g@86>wd{r@OtNsBr48bmGzkF8pId~ zmI_kweUo;oJf??nOj+XK8cfU2hTc|#i=8#H z)_8VFTm>mDyDqXyoI6+xU&J?Z`WvIu8 z(zZJ^@x~PSY3*!x?bRR$F)N|%q%xp9t~@h?g4Ah$buM1~7aNgb zUBMF+ebbEY0%{HJz(+ZEG`hSXUgdB|e(5v3GbJD^#lrmN9s%W5*Kzk9%=uYRnUgNa zaPs^}>W-BFn6Gg*)%n?5Wz#zkr%6NWZJ)`ZAT)WJ$Bn@y3hw{nko$OExu)Wtt?4G{%y_j&3Ic( zE>%|tYYPG8r=~#7OlF_0dvI3Im}5siZ8jPYMtnsIS1q@xi<-AGZTWWWLe>xPR?3>D zHh$TaI^Qx|rEV&m;S-j-S?3eruhmXWNlHv4QXN$7r3G4Xq=+CVMDuG{;^m1_UZ6uq z-z00YBoxUrnH#Lx5JOje*r!SZuVJZ=?96Z2!OgsW#nGpK5Va-q82fJS8F;?37t=#P zJxF^Y)ns2|rsw(K$b|3mQ`^k4>HQ90Bb|%Q3U%BNG}*{DEx%%hU_> zO1c{OBg6PLsA=0dvds`}w0h)Lavnv-F&vnSNLIS_N7 z9@bL2X#K?7U8$ITM<8B?&;B80$TNn4eRuF|(PwgB{owk#9j|Y8M%;>2{pix3Y08=S^8j<00Jm%YqDBw?s)2zTQKQFg}12Bb-q#J{Een#Xo zs^XTKAjU)BGcw}Gnrs6Ep`dXtmgzQ4kS6i{I>w^2=~qY%dtUIUdSxBs#jkivu zFbHcp@EgL4nKJXsNLT5z$f(K-0%WH2z4+IIgJ}`QevrI{mYDRJ!x$RpYFGJHO&c;6 zTXt`!M`1G)KM$h8Xy1Vnl=vyk4{2PDtl5bV?r_lqH*yqfnZ=P5X*W39N||YVGc!EaD(qgtG29xftfYD={v;X_6&)S%JbPeg4*I#GZaZMg ze{qBL=Ai@ddZbO&o*Y)-Z#B^7{{}T*`=TeW5V{YBmB5`vRhd3uF8UsPbssL2sNJpy zi)UoHj5gIVyRRPLu+i`+Xme)fQjWZ#J`heG(Q|#99+pRsKKVUwVe;Hwas27~FB-fw zFZG6_Ff)mjD|gtl5dxqFzl%`zwVqf?iW+SzJN6P^N|@4xmw4c=6mBi%G=*nlq87b5 zoU(&6F9&y=ZrUZB9xfRj>LtzlYd@QW*1;q+~4!&7UU&%82YzXwb5WldY`JmxXb{>8LRY!{xC+uW2GR`@JHh(>TPt8e|l z4r$~&lV4)ZKkRONTK6WOkEp}hxV*S{?UT}!wytjTQG1xXu(6Smvb16mP^%y=E}*#? z`_G=NGi#lHILkuB2lJMfXr)XlJX*1Yqt)MmiOdY*cRC;JEI(+Q7yO9O#Rvi%G4}2H zsKjB-(1{aGNfuA?p1dG-{#=8sJ#IM-^~aPUk0h-)g_G%ZUdJRmfv5$ua)tDWBLX&jZmGyEn@*D-wV}jy{y6* zI-%M5c{&veok?ZbOFKuXwVjq5YE{o@(*5j5Ii26Knp5i}S02MJ8}Zp^418|F<&6lF zG17qgL{`vd4#jIo=ZWRAHm{Fip^*PPKltYH4ow9OTL?mBAjzIzh8LShN zG|+Fh`gXOVvbr*qsq8NA?9N^mzFa$JOP$RC(johDyKrl>;Dfflbb%F}Xa(kDW;r2) zTRjc8M6FA+)$cD~c(9M-MqpxFqjGfOXD6eZoBfZ+pGYPr4XoPQ7M!sYg|YL$mXueJ zKJ;=_rLl|sm7)Eb>2gU#+iKE<9(Fkg*P?j;9>FZ+9u%%?`N3#!#bF|zBjoo;1%ZrU zVnnCp=y~3!Y+z+0nkcbnK$!)nhWf`tlADI_ZR3Z)({WLblh4m7dv1boMrXv zqXUjW#fnTd zHI&8D8^>~md_<1-=+b*!B*xK;i3|ven9xa@NT$lR*P-IY@0!T=noWRPq&wU(d9C2T zkvKgUUBX*~o+TW@jV+Kt@=6*}@3ZAf%CBe-6nR&y^eSrnd~cK$%H(+HPshh@8YjEt`r$S;@FZEnME#ZD|BbLckRv5wdE=u_zdWlHwNAL*y#r zcd}&3vjry)v@lc6CZsXbvCMqZ#}qXp(BcSNdoOV%+uVqmPC%W=ru+@bW*Tr0!XnFpIzL%Gmi_G~Gzxl!Zdyo#%{T}T)e9A>b;&eok(J~crF`t-*zCcn4Rv&w{u6)bF%1Zx^jPH zk3`+sDE*Z%&+exZPFtezu|_ZJwLy4I>90Qm2)A`@B_Q8;{-F(2uQTJos0UH5ArgJf zsFq<|_vv@o${oA&D`Cbo)d?78K~7}eoxp;b-z|jXAtGggcdI=|ujSV`v?Vp<^Fu1) zoe$@M{w8iHW3(53PfbQnJIvF`zlc`!@XIrc^ z(635<|C6AtBJg9C1!uN~@9~F9dIvl6PhKxTL$kgEK|wvjyf|hYAB(&N`KC{W4Fo=B0%-7s%og&MW1z5?JWI$S@!L zZDzQ&+20@Y2VGNBGlN)XB8yyGTg$#a$`L|9n8@BQXnv5*9Y}t$v9+}@>(4Y_*V}?w z$TKak?1u3=Y5T}9g>G&dd3VT>wfg*ao_7P=H7`az6v;xP+3yfy%w>0wa+t%=U!VM_ z?TGE|GF!dPwwKl1#gD&3{nv+>=`VimLNBhbqF^XG^b*8xa$Bf6ogTYqeOzjwgZ4T& z@ZmIMAgXuWXJk$AN_gCJ=$`j^8#_(*wut1&mcn#$%W1AJa5-a*o~bs(s-AO)f3Cb; z607qvolwR?*I?)SE1ndu5Rz)0$((~tZ74lyl8!FhPR5@?+0H>&X~KqrqoP&qwgZxe zkwC1qEYov)Vj*rXnyQcdJn%~xF!RhCDx26h}UQs~y{rKT@!-~E7d6jAMR z|A41Nl2(@2{wzN#d-#cT`H7{3kyvvc)3rIcX>f;~{UO3UM>k&&?9mltZB%y5yak`$ z|3EED0)v~ZQiahC8GDQw#QT_&WwW)jhMM(uU-W0}v;=4kPnSro~x{hJRg8+S5a*{W+<$q&(zxFi!noRCI{dUe#M)Pb1jU-i8Sd zIdH_yZKqEe3hqzTWTwKz)rYvE3=)(?(Q$MNW*0t=g=_X$okoX&95HF>77 zX~BeUktGE|8shK{8N#(p_h-2&d6X>6(%KEKUBAaH&$J{NtXhsM1gvI4bx?0a7HWnJ z89)s8Mtq-!GVw^G@#G4^+%aD0^CA!WX2j(TZo-{qQA3cV#UFjdVU(rBbcLc9 zZvu0{qk;>}89%G2=by#L)m!=+K-o|;>031jm^+7)NRD&wHwWl`kyXU9^Y1)D4VVGm z7>JEz;J7d>ekj1l^zd+RjCaB z8kB!y06e*PYB-P36^HRd$DQG}@4kiLA)z6aK*B4g!+vfpc0~%q*0Y(|rZFGAn$~&5 zUcgdt@X*LkEowIH9_4P}%Dbsa#KvQU|I!Q91|{jPl?Q>)Ar*STy%PEipGXJz_%XvZF zh-h;ZnMw{>O-$vF1Ih7fl zIlW<})b{4R{&dc!PZ1IDmh)x1UpWq_mBZXo^_4lVkt23QS9aY%>uIr_(_y130)DwN zx%(?AjnzRrbKiuVTrd~uvd<8~xTJ3EVPNbrGj`6)Gm`<~0Dd@p4EZ5K160m6wGGgo zwsEoioU86^tf67xpI;amp{xL-I6Xb`WbyGe0u{A#K`y|r+Cxa@R~e%sU}rSKUHKT% zD$V;!l$UbUA01p(z%`a{03jw}ioH`+yRJr+Yvxnmox6=%{G>eD>j;XCvgS=uju{Q?T zoLoSZqZj`E2v7u7j8M=*8Pt7;$uZz)6BVibs<8e5d#(FL5i5>%F6|EX@)+xJtZZeU zfwqkJs4x~6rALDC0D`A5PN#WgObB*?d%Yn=zzL0cAc*_bmi*3L>??Wz1sPRoxTI