From 80ae894b87f87ead7660b0dc5503730794f69e71 Mon Sep 17 00:00:00 2001 From: Alex Bligh Date: Fri, 14 Sep 2012 12:11:27 +0100 Subject: [PATCH] Initial commit - from Precise source --- .gitignore | 49 + .pc/.quilt_patches | 1 + .pc/.quilt_series | 1 + .pc/.version | 1 + CMakeLists.txt | 187 + ChangeLog | 118 + LICENSE | 202 + README | 34 + channels/CMakeLists.txt | 26 + channels/cliprdr/CMakeLists.txt | 33 + channels/cliprdr/cliprdr_constants.h | 58 + channels/cliprdr/cliprdr_format.c | 354 ++ channels/cliprdr/cliprdr_format.h | 34 + channels/cliprdr/cliprdr_main.c | 276 + channels/cliprdr/cliprdr_main.h | 58 + channels/drdynvc/CMakeLists.txt | 37 + channels/drdynvc/audin/CMakeLists.txt | 41 + channels/drdynvc/audin/alsa/CMakeLists.txt | 33 + channels/drdynvc/audin/alsa/audin_alsa.c | 366 ++ channels/drdynvc/audin/audin_main.c | 544 ++ channels/drdynvc/audin/audin_main.h | 65 + channels/drdynvc/audin/pulse/CMakeLists.txt | 34 + channels/drdynvc/audin/pulse/audin_pulse.c | 471 ++ channels/drdynvc/drdynvc_main.c | 346 ++ channels/drdynvc/drdynvc_main.h | 30 + channels/drdynvc/drdynvc_types.h | 34 + channels/drdynvc/dvcman.c | 441 ++ channels/drdynvc/dvcman.h | 35 + channels/drdynvc/tsmf/CMakeLists.txt | 57 + channels/drdynvc/tsmf/alsa/CMakeLists.txt | 34 + channels/drdynvc/tsmf/alsa/tsmf_alsa.c | 263 + channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt | 34 + channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c | 518 ++ channels/drdynvc/tsmf/pulse/CMakeLists.txt | 34 + channels/drdynvc/tsmf/pulse/tsmf_pulse.c | 402 ++ channels/drdynvc/tsmf/tsmf_audio.c | 80 + channels/drdynvc/tsmf/tsmf_audio.h | 49 + channels/drdynvc/tsmf/tsmf_codec.c | 407 ++ channels/drdynvc/tsmf/tsmf_codec.h | 29 + channels/drdynvc/tsmf/tsmf_constants.h | 120 + channels/drdynvc/tsmf/tsmf_decoder.c | 81 + channels/drdynvc/tsmf/tsmf_decoder.h | 50 + channels/drdynvc/tsmf/tsmf_ifman.c | 478 ++ channels/drdynvc/tsmf/tsmf_ifman.h | 65 + channels/drdynvc/tsmf/tsmf_main.c | 448 ++ channels/drdynvc/tsmf/tsmf_main.h | 29 + channels/drdynvc/tsmf/tsmf_media.c | 795 +++ channels/drdynvc/tsmf/tsmf_media.h | 59 + channels/drdynvc/tsmf/tsmf_types.h | 47 + channels/rail/CMakeLists.txt | 32 + channels/rail/rail_main.c | 251 + channels/rail/rail_main.h | 69 + channels/rail/rail_orders.c | 633 +++ channels/rail/rail_orders.h | 97 + channels/rdpdbg/CMakeLists.txt | 29 + channels/rdpdbg/rdpdbg_main.c | 69 + channels/rdpdr/CMakeLists.txt | 47 + channels/rdpdr/devman.c | 108 + channels/rdpdr/devman.h | 29 + channels/rdpdr/disk/CMakeLists.txt | 33 + channels/rdpdr/disk/disk_file.c | 655 +++ channels/rdpdr/disk/disk_file.h | 55 + channels/rdpdr/disk/disk_main.c | 651 +++ channels/rdpdr/irp.c | 97 + channels/rdpdr/irp.h | 28 + channels/rdpdr/parallel/CMakeLists.txt | 31 + channels/rdpdr/parallel/parallel_main.c | 335 ++ channels/rdpdr/printer/CMakeLists.txt | 46 + channels/rdpdr/printer/printer_cups.c | 283 + channels/rdpdr/printer/printer_cups.h | 28 + channels/rdpdr/printer/printer_main.c | 340 ++ channels/rdpdr/printer/printer_main.h | 79 + channels/rdpdr/rdpdr_capabilities.c | 187 + channels/rdpdr/rdpdr_capabilities.h | 29 + channels/rdpdr/rdpdr_constants.h | 442 ++ channels/rdpdr/rdpdr_main.c | 317 ++ channels/rdpdr/rdpdr_main.h | 41 + channels/rdpdr/rdpdr_types.h | 90 + channels/rdpdr/serial/CMakeLists.txt | 34 + channels/rdpdr/serial/serial_constants.h | 154 + channels/rdpdr/serial/serial_main.c | 714 +++ channels/rdpdr/serial/serial_tty.c | 980 ++++ channels/rdpdr/serial/serial_tty.h | 72 + channels/rdpdr/smartcard/CMakeLists.txt | 34 + channels/rdpdr/smartcard/scard_main.c | 204 + channels/rdpdr/smartcard/scard_main.h | 52 + channels/rdpdr/smartcard/scard_operations.c | 1540 +++++ channels/rdpsnd/CMakeLists.txt | 39 + channels/rdpsnd/alsa/CMakeLists.txt | 33 + channels/rdpsnd/alsa/rdpsnd_alsa.c | 360 ++ channels/rdpsnd/pulse/CMakeLists.txt | 33 + channels/rdpsnd/pulse/rdpsnd_pulse.c | 509 ++ channels/rdpsnd/rdpsnd_main.c | 561 ++ channels/rdpsnd/rdpsnd_main.h | 76 + client/CMakeLists.txt | 40 + client/DirectFB/CMakeLists.txt | 37 + client/DirectFB/df_event.c | 275 + client/DirectFB/df_event.h | 28 + client/DirectFB/df_graphics.c | 121 + client/DirectFB/df_graphics.h | 27 + client/DirectFB/dfreerdp.c | 476 ++ client/DirectFB/dfreerdp.h | 69 + client/Windows/CMakeLists.txt | 36 + client/Windows/wf_event.c | 223 + client/Windows/wf_event.h | 36 + client/Windows/wf_gdi.c | 545 ++ client/Windows/wf_gdi.h | 34 + client/Windows/wf_graphics.c | 242 + client/Windows/wf_graphics.h | 32 + client/Windows/wfreerdp.c | 682 +++ client/Windows/wfreerdp.h | 99 + client/X11/CMakeLists.txt | 98 + client/X11/xf_cliprdr.c | 1235 ++++ client/X11/xf_cliprdr.h | 40 + client/X11/xf_event.c | 762 +++ client/X11/xf_event.h | 30 + client/X11/xf_gdi.c | 788 +++ client/X11/xf_gdi.h | 29 + client/X11/xf_graphics.c | 320 ++ client/X11/xf_graphics.h | 27 + client/X11/xf_keyboard.c | 188 + client/X11/xf_keyboard.h | 39 + client/X11/xf_monitor.c | 127 + client/X11/xf_monitor.h | 47 + client/X11/xf_rail.c | 607 ++ client/X11/xf_rail.h | 33 + client/X11/xf_tsmf.c | 370 ++ client/X11/xf_tsmf.h | 29 + client/X11/xf_window.c | 751 +++ client/X11/xf_window.h | 112 + client/X11/xfreerdp.1.xml | 461 ++ client/X11/xfreerdp.c | 1131 ++++ client/X11/xfreerdp.h | 215 + client/test/CMakeLists.txt | 26 + client/test/freerdp.c | 338 ++ cmake/AutoVersioning.cmake | 54 + cmake/ConfigOptions.cmake | 26 + cmake/FindCUnit.cmake | 47 + cmake/FindDirectFB.cmake | 49 + cmake/FindFFmpeg.cmake | 41 + cmake/FindOptionalPackage.cmake | 51 + cmake/FindPCSC.cmake | 13 + cmake/FindPulseAudio.cmake | 12 + cmake/FindX11.cmake | 49 + cmake/FindXKBFile.cmake | 49 + cmake/FindXShm.cmake | 49 + cmake/FindXTest.cmake | 49 + cmake/FindXcursor.cmake | 49 + cmake/FindXdamage.cmake | 49 + cmake/FindXext.cmake | 49 + cmake/FindXfixes.cmake | 49 + cmake/FindXinerama.cmake | 49 + cmake/FindXmlto.cmake | 35 + cmake/FindXv.cmake | 49 + cmake/GNUInstallDirsWrapper.cmake | 13 + config.h.in | 51 + cunit/CMakeLists.txt | 77 + cunit/test_ber.c | 96 + cunit/test_ber.h | 28 + cunit/test_bitmap.c | 1250 ++++ cunit/test_bitmap.h | 26 + cunit/test_channels.c | 91 + cunit/test_channels.h | 26 + cunit/test_cliprdr.c | 248 + cunit/test_cliprdr.h | 26 + cunit/test_color.c | 152 + cunit/test_color.h | 31 + cunit/test_drdynvc.c | 97 + cunit/test_drdynvc.h | 26 + cunit/test_freerdp.c | 226 + cunit/test_freerdp.h | 43 + cunit/test_gcc.c | 215 + cunit/test_gcc.h | 30 + cunit/test_libgdi.c | 2991 ++++++++++ cunit/test_libgdi.h | 47 + cunit/test_librfx.c | 410 ++ cunit/test_librfx.h | 34 + cunit/test_license.c | 499 ++ cunit/test_license.h | 29 + cunit/test_list.c | 94 + cunit/test_list.h | 26 + cunit/test_mcs.c | 115 + cunit/test_mcs.h | 26 + cunit/test_mppc.c | 670 +++ cunit/test_mppc.h | 26 + cunit/test_orders.c | 772 +++ cunit/test_orders.h | 48 + cunit/test_pcap.c | 99 + cunit/test_pcap.h | 26 + cunit/test_per.c | 64 + cunit/test_per.h | 27 + cunit/test_rail.c | 891 +++ cunit/test_rail.h | 26 + cunit/test_stream.c | 76 + cunit/test_stream.h | 26 + cunit/test_utils.c | 672 +++ cunit/test_utils.h | 32 + debian/changelog | 114 + debian/compat | 1 + debian/control | 85 + debian/copyright | 40 + debian/freerdp-x11.install | 2 + debian/libfreerdp-dev.install | 5 + debian/libfreerdp-plugins-standard.install | 1 + debian/libfreerdp1.install | 1 + debian/libfreerdp1.symbols | 1279 +++++ debian/rules | 21 + debian/source/format | 1 + debian/watch | 3 + docs/Doxyfile | 1515 +++++ docs/FreeRDP.vsd | Bin 0 -> 214528 bytes freerdp.pc.in | 13 + freerdp.spec | 107 + include/CMakeLists.txt | 30 + include/freerdp/altsec.h | 217 + include/freerdp/api.h | 62 + include/freerdp/cache/bitmap.h | 70 + include/freerdp/cache/brush.h | 65 + include/freerdp/cache/cache.h | 52 + include/freerdp/cache/glyph.h | 73 + include/freerdp/cache/offscreen.h | 55 + include/freerdp/cache/palette.h | 57 + include/freerdp/cache/pointer.h | 53 + include/freerdp/channels/channels.h | 53 + include/freerdp/channels/wtsvc.h | 128 + include/freerdp/codec/bitmap.h | 27 + include/freerdp/codec/color.h | 264 + include/freerdp/codec/nsc.h | 73 + include/freerdp/codec/rfx.h | 149 + include/freerdp/constants.h | 113 + include/freerdp/dvc.h | 149 + include/freerdp/extension.h | 59 + include/freerdp/freerdp.h | 124 + include/freerdp/gdi/16bpp.h | 31 + include/freerdp/gdi/32bpp.h | 31 + include/freerdp/gdi/8bpp.h | 31 + include/freerdp/gdi/bitmap.h | 43 + include/freerdp/gdi/brush.h | 32 + include/freerdp/gdi/clipping.h | 31 + include/freerdp/gdi/dc.h | 33 + include/freerdp/gdi/drawing.h | 34 + include/freerdp/gdi/gdi.h | 283 + include/freerdp/gdi/line.h | 34 + include/freerdp/gdi/palette.h | 29 + include/freerdp/gdi/pen.h | 31 + include/freerdp/gdi/region.h | 45 + include/freerdp/gdi/shape.h | 34 + include/freerdp/graphics.h | 162 + include/freerdp/input.h | 75 + include/freerdp/kbd/kbd.h | 42 + include/freerdp/kbd/layouts.h | 184 + include/freerdp/kbd/locales.h | 328 ++ include/freerdp/kbd/vkcodes.h | 587 ++ include/freerdp/listener.h | 65 + include/freerdp/peer.h | 77 + include/freerdp/plugins/cliprdr.h | 74 + include/freerdp/plugins/tsmf.h | 64 + include/freerdp/pointer.h | 102 + include/freerdp/primary.h | 495 ++ include/freerdp/rail.h | 344 ++ include/freerdp/rail/icon.h | 61 + include/freerdp/rail/rail.h | 67 + include/freerdp/rail/window.h | 77 + include/freerdp/rail/window_list.h | 55 + include/freerdp/secondary.h | 224 + include/freerdp/settings.h | 446 ++ include/freerdp/svc.h | 116 + include/freerdp/types.h | 164 + include/freerdp/update.h | 191 + include/freerdp/utils/args.h | 48 + include/freerdp/utils/bitmap.h | 27 + include/freerdp/utils/blob.h | 35 + include/freerdp/utils/debug.h | 38 + include/freerdp/utils/dsp.h | 42 + include/freerdp/utils/event.h | 30 + include/freerdp/utils/file.h | 39 + include/freerdp/utils/hexdump.h | 29 + include/freerdp/utils/list.h | 52 + include/freerdp/utils/load_plugin.h | 33 + include/freerdp/utils/memory.h | 34 + include/freerdp/utils/mutex.h | 32 + include/freerdp/utils/passphrase.h | 28 + include/freerdp/utils/pcap.h | 81 + include/freerdp/utils/print.h | 29 + include/freerdp/utils/profiler.h | 71 + include/freerdp/utils/rail.h | 38 + include/freerdp/utils/rect.h | 33 + include/freerdp/utils/registry.h | 72 + include/freerdp/utils/semaphore.h | 32 + include/freerdp/utils/signal.h | 36 + include/freerdp/utils/sleep.h | 29 + include/freerdp/utils/stopwatch.h | 47 + include/freerdp/utils/stream.h | 176 + include/freerdp/utils/string.h | 39 + include/freerdp/utils/svc_plugin.h | 84 + include/freerdp/utils/thread.h | 60 + include/freerdp/utils/unicode.h | 54 + include/freerdp/utils/wait_obj.h | 34 + include/freerdp/window.h | 265 + keymaps/CMakeLists.txt | 3 + keymaps/aliases | 17 + keymaps/amiga | 193 + keymaps/ataritt | 104 + keymaps/digital_vndr/lk | 197 + keymaps/digital_vndr/pc | 192 + keymaps/empty | 13 + keymaps/evdev | 135 + keymaps/fujitsu | 119 + keymaps/hp | 105 + keymaps/ibm | 5 + keymaps/macintosh | 142 + keymaps/macosx | 107 + keymaps/sgi_vndr/indigo | 116 + keymaps/sgi_vndr/indy | 148 + keymaps/sgi_vndr/iris | 10 + keymaps/sony | 103 + keymaps/sun | 618 ++ keymaps/xfree86 | 152 + keymaps/xfree98 | 106 + keymaps/xkb.pl | 303 + libfreerdp-cache/CMakeLists.txt | 36 + libfreerdp-cache/bitmap.c | 282 + libfreerdp-cache/brush.c | 185 + libfreerdp-cache/cache.c | 57 + libfreerdp-cache/glyph.c | 513 ++ libfreerdp-cache/offscreen.c | 169 + libfreerdp-cache/palette.c | 92 + libfreerdp-cache/pointer.c | 155 + libfreerdp-channels/CMakeLists.txt | 32 + libfreerdp-channels/libchannels.c | 988 ++++ libfreerdp-channels/libchannels.h | 32 + libfreerdp-channels/wtsvc.c | 372 ++ libfreerdp-channels/wtsvc.h | 61 + libfreerdp-codec/CMakeLists.txt | 66 + libfreerdp-codec/bitmap.c | 471 ++ libfreerdp-codec/color.c | 1061 ++++ libfreerdp-codec/include/bitmap.c | 567 ++ libfreerdp-codec/nsc.c | 380 ++ libfreerdp-codec/rfx.c | 894 +++ libfreerdp-codec/rfx_bitstream.h | 86 + libfreerdp-codec/rfx_constants.h | 60 + libfreerdp-codec/rfx_decode.c | 194 + libfreerdp-codec/rfx_decode.h | 33 + libfreerdp-codec/rfx_differential.c | 47 + libfreerdp-codec/rfx_differential.h | 28 + libfreerdp-codec/rfx_dwt.c | 194 + libfreerdp-codec/rfx_dwt.h | 28 + libfreerdp-codec/rfx_encode.c | 280 + libfreerdp-codec/rfx_encode.h | 32 + libfreerdp-codec/rfx_neon.c | 352 ++ libfreerdp-codec/rfx_neon.h | 38 + libfreerdp-codec/rfx_pool.c | 112 + libfreerdp-codec/rfx_pool.h | 40 + libfreerdp-codec/rfx_quantization.c | 82 + libfreerdp-codec/rfx_quantization.h | 28 + libfreerdp-codec/rfx_rlgr.c | 431 ++ libfreerdp-codec/rfx_rlgr.h | 28 + libfreerdp-codec/rfx_sse2.c | 669 +++ libfreerdp-codec/rfx_sse2.h | 31 + libfreerdp-codec/rfx_types.h | 73 + libfreerdp-core/CMakeLists.txt | 111 + libfreerdp-core/activation.c | 340 ++ libfreerdp-core/activation.h | 65 + libfreerdp-core/ber.c | 432 ++ libfreerdp-core/ber.h | 83 + libfreerdp-core/capabilities.c | 2086 +++++++ libfreerdp-core/capabilities.h | 173 + libfreerdp-core/certificate.c | 760 +++ libfreerdp-core/certificate.h | 98 + libfreerdp-core/channel.c | 116 + libfreerdp-core/channel.h | 27 + libfreerdp-core/connection.c | 700 +++ libfreerdp-core/connection.h | 68 + libfreerdp-core/credssp.c | 670 +++ libfreerdp-core/credssp.h | 67 + libfreerdp-core/crypto.c | 541 ++ libfreerdp-core/crypto.h | 140 + libfreerdp-core/errinfo.c | 453 ++ libfreerdp-core/errinfo.h | 136 + libfreerdp-core/extension.c | 214 + libfreerdp-core/extension.h | 55 + libfreerdp-core/fastpath.c | 680 +++ libfreerdp-core/fastpath.h | 122 + libfreerdp-core/freerdp.c | 229 + libfreerdp-core/gcc.c | 1169 ++++ libfreerdp-core/gcc.h | 111 + libfreerdp-core/graphics.c | 224 + libfreerdp-core/info.c | 726 +++ libfreerdp-core/info.h | 90 + libfreerdp-core/input.c | 403 ++ libfreerdp-core/input.h | 59 + libfreerdp-core/license.c | 938 +++ libfreerdp-core/license.h | 205 + libfreerdp-core/listener.c | 230 + libfreerdp-core/listener.h | 37 + libfreerdp-core/mcs.c | 837 +++ libfreerdp-core/mcs.h | 156 + libfreerdp-core/mppc.c | 1292 +++++ libfreerdp-core/mppc.h | 45 + libfreerdp-core/nego.c | 720 +++ libfreerdp-core/nego.h | 120 + libfreerdp-core/ntlmssp.c | 1897 +++++++ libfreerdp-core/ntlmssp.h | 166 + libfreerdp-core/orders.c | 2020 +++++++ libfreerdp-core/orders.h | 233 + libfreerdp-core/peer.c | 355 ++ libfreerdp-core/peer.h | 27 + libfreerdp-core/per.c | 455 ++ libfreerdp-core/per.h | 48 + libfreerdp-core/rdp.c | 919 +++ libfreerdp-core/rdp.h | 205 + libfreerdp-core/redirection.c | 225 + libfreerdp-core/redirection.h | 75 + libfreerdp-core/security.c | 525 ++ libfreerdp-core/security.h | 47 + libfreerdp-core/settings.c | 217 + libfreerdp-core/surface.c | 128 + libfreerdp-core/surface.h | 48 + libfreerdp-core/tcp.c | 332 ++ libfreerdp-core/tcp.h | 61 + libfreerdp-core/tls.c | 434 ++ libfreerdp-core/tls.h | 60 + libfreerdp-core/tpdu.c | 223 + libfreerdp-core/tpdu.h | 54 + libfreerdp-core/tpkt.c | 111 + libfreerdp-core/tpkt.h | 34 + libfreerdp-core/transport.c | 417 ++ libfreerdp-core/transport.h | 80 + libfreerdp-core/update.c | 580 ++ libfreerdp-core/update.h | 57 + libfreerdp-core/window.c | 341 ++ libfreerdp-core/window.h | 36 + libfreerdp-gdi/16bpp.c | 1024 ++++ libfreerdp-gdi/32bpp.c | 1053 ++++ libfreerdp-gdi/8bpp.c | 933 +++ libfreerdp-gdi/CMakeLists.txt | 47 + libfreerdp-gdi/bitmap.c | 189 + libfreerdp-gdi/brush.c | 96 + libfreerdp-gdi/clipping.c | 172 + libfreerdp-gdi/dc.c | 232 + libfreerdp-gdi/drawing.c | 131 + libfreerdp-gdi/gdi.c | 937 +++ libfreerdp-gdi/gdi.h | 28 + libfreerdp-gdi/graphics.c | 239 + libfreerdp-gdi/graphics.h | 34 + libfreerdp-gdi/include/line.c | 110 + libfreerdp-gdi/line.c | 152 + libfreerdp-gdi/palette.c | 106 + libfreerdp-gdi/pen.c | 70 + libfreerdp-gdi/region.c | 423 ++ libfreerdp-gdi/shape.c | 223 + libfreerdp-kbd/CMakeLists.txt | 53 + libfreerdp-kbd/layouts.c | 300 + libfreerdp-kbd/layouts_xkb.c | 418 ++ libfreerdp-kbd/layouts_xkb.h | 44 + libfreerdp-kbd/libkbd.c | 168 + libfreerdp-kbd/libkbd.h | 31 + libfreerdp-kbd/locales.c | 510 ++ libfreerdp-kbd/x_layout_id_table.c | 1172 ++++ libfreerdp-kbd/x_layout_id_table.h | 31 + libfreerdp-rail/CMakeLists.txt | 33 + libfreerdp-rail/icon.c | 112 + libfreerdp-rail/librail.h | 31 + libfreerdp-rail/rail.c | 149 + libfreerdp-rail/window.c | 384 ++ libfreerdp-rail/window_list.c | 200 + libfreerdp-utils/CMakeLists.txt | 67 + libfreerdp-utils/args.c | 695 +++ libfreerdp-utils/bitmap.c | 105 + libfreerdp-utils/blob.c | 47 + libfreerdp-utils/dsp.c | 336 ++ libfreerdp-utils/event.c | 167 + libfreerdp-utils/file.c | 261 + libfreerdp-utils/hexdump.c | 56 + libfreerdp-utils/list.c | 151 + libfreerdp-utils/load_plugin.c | 209 + libfreerdp-utils/memory.c | 133 + libfreerdp-utils/mutex.c | 71 + libfreerdp-utils/passphrase.c | 124 + libfreerdp-utils/pcap.c | 217 + libfreerdp-utils/profiler.c | 72 + libfreerdp-utils/rail.c | 184 + libfreerdp-utils/rect.c | 56 + libfreerdp-utils/registry.c | 194 + libfreerdp-utils/semaphore.c | 96 + libfreerdp-utils/signal.c | 115 + libfreerdp-utils/sleep.c | 58 + libfreerdp-utils/stopwatch.c | 77 + libfreerdp-utils/stream.c | 76 + libfreerdp-utils/string.c | 39 + libfreerdp-utils/svc_plugin.c | 410 ++ libfreerdp-utils/thread.c | 95 + libfreerdp-utils/unicode.c | 240 + libfreerdp-utils/wait_obj.c | 225 + resources/FreeRDP-fav.ico | Bin 0 -> 1150 bytes resources/FreeRDP.ico | Bin 0 -> 30160 bytes resources/FreeRDP_Icon_256px.h | 8195 +++++++++++++++++++++++++++ resources/FreeRDP_Icon_256px.png | Bin 0 -> 6586 bytes resources/FreeRDP_Icon_256px.xpm | 347 ++ resources/FreeRDP_Logo_Icon.ai | 4650 +++++++++++++++ resources/FreeRDP_Logo_Icon.svg | 76 + resources/FreeRDP_OSX.icns | Bin 0 -> 60681 bytes resources/conv_to_ewm_prop.py | 64 + server/CMakeLists.txt | 33 + server/X11/CMakeLists.txt | 69 + server/X11/rfx_test.pcap | Bin 0 -> 994948 bytes server/X11/server.crt | 17 + server/X11/server.key | 27 + server/X11/xf_encode.c | 171 + server/X11/xf_encode.h | 32 + server/X11/xf_event.c | 198 + server/X11/xf_event.h | 75 + server/X11/xf_input.c | 125 + server/X11/xf_input.h | 34 + server/X11/xf_peer.c | 710 +++ server/X11/xf_peer.h | 54 + server/X11/xfreerdp.c | 124 + server/X11/xfreerdp.h | 75 + server/test/CMakeLists.txt | 26 + server/test/rfx_test.pcap | Bin 0 -> 994948 bytes server/test/server.crt | 17 + server/test/server.key | 27 + server/test/test_icon.ppm | 5572 ++++++++++++++++++ server/test/tfreerdp.c | 699 +++ 524 files changed, 126178 insertions(+) create mode 100644 .gitignore create mode 100644 .pc/.quilt_patches create mode 100644 .pc/.quilt_series create mode 100644 .pc/.version create mode 100644 CMakeLists.txt create mode 100644 ChangeLog create mode 100644 LICENSE create mode 100644 README create mode 100644 channels/CMakeLists.txt create mode 100644 channels/cliprdr/CMakeLists.txt create mode 100644 channels/cliprdr/cliprdr_constants.h create mode 100644 channels/cliprdr/cliprdr_format.c create mode 100644 channels/cliprdr/cliprdr_format.h create mode 100644 channels/cliprdr/cliprdr_main.c create mode 100644 channels/cliprdr/cliprdr_main.h create mode 100644 channels/drdynvc/CMakeLists.txt create mode 100644 channels/drdynvc/audin/CMakeLists.txt create mode 100644 channels/drdynvc/audin/alsa/CMakeLists.txt create mode 100644 channels/drdynvc/audin/alsa/audin_alsa.c create mode 100644 channels/drdynvc/audin/audin_main.c create mode 100644 channels/drdynvc/audin/audin_main.h create mode 100644 channels/drdynvc/audin/pulse/CMakeLists.txt create mode 100644 channels/drdynvc/audin/pulse/audin_pulse.c create mode 100644 channels/drdynvc/drdynvc_main.c create mode 100644 channels/drdynvc/drdynvc_main.h create mode 100644 channels/drdynvc/drdynvc_types.h create mode 100644 channels/drdynvc/dvcman.c create mode 100644 channels/drdynvc/dvcman.h create mode 100644 channels/drdynvc/tsmf/CMakeLists.txt create mode 100644 channels/drdynvc/tsmf/alsa/CMakeLists.txt create mode 100644 channels/drdynvc/tsmf/alsa/tsmf_alsa.c create mode 100644 channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt create mode 100644 channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c create mode 100644 channels/drdynvc/tsmf/pulse/CMakeLists.txt create mode 100644 channels/drdynvc/tsmf/pulse/tsmf_pulse.c create mode 100644 channels/drdynvc/tsmf/tsmf_audio.c create mode 100644 channels/drdynvc/tsmf/tsmf_audio.h create mode 100644 channels/drdynvc/tsmf/tsmf_codec.c create mode 100644 channels/drdynvc/tsmf/tsmf_codec.h create mode 100644 channels/drdynvc/tsmf/tsmf_constants.h create mode 100644 channels/drdynvc/tsmf/tsmf_decoder.c create mode 100644 channels/drdynvc/tsmf/tsmf_decoder.h create mode 100644 channels/drdynvc/tsmf/tsmf_ifman.c create mode 100644 channels/drdynvc/tsmf/tsmf_ifman.h create mode 100644 channels/drdynvc/tsmf/tsmf_main.c create mode 100644 channels/drdynvc/tsmf/tsmf_main.h create mode 100644 channels/drdynvc/tsmf/tsmf_media.c create mode 100644 channels/drdynvc/tsmf/tsmf_media.h create mode 100644 channels/drdynvc/tsmf/tsmf_types.h create mode 100644 channels/rail/CMakeLists.txt create mode 100644 channels/rail/rail_main.c create mode 100644 channels/rail/rail_main.h create mode 100644 channels/rail/rail_orders.c create mode 100644 channels/rail/rail_orders.h create mode 100644 channels/rdpdbg/CMakeLists.txt create mode 100644 channels/rdpdbg/rdpdbg_main.c create mode 100644 channels/rdpdr/CMakeLists.txt create mode 100644 channels/rdpdr/devman.c create mode 100644 channels/rdpdr/devman.h create mode 100644 channels/rdpdr/disk/CMakeLists.txt create mode 100644 channels/rdpdr/disk/disk_file.c create mode 100644 channels/rdpdr/disk/disk_file.h create mode 100644 channels/rdpdr/disk/disk_main.c create mode 100644 channels/rdpdr/irp.c create mode 100644 channels/rdpdr/irp.h create mode 100644 channels/rdpdr/parallel/CMakeLists.txt create mode 100644 channels/rdpdr/parallel/parallel_main.c create mode 100644 channels/rdpdr/printer/CMakeLists.txt create mode 100644 channels/rdpdr/printer/printer_cups.c create mode 100644 channels/rdpdr/printer/printer_cups.h create mode 100644 channels/rdpdr/printer/printer_main.c create mode 100644 channels/rdpdr/printer/printer_main.h create mode 100644 channels/rdpdr/rdpdr_capabilities.c create mode 100644 channels/rdpdr/rdpdr_capabilities.h create mode 100644 channels/rdpdr/rdpdr_constants.h create mode 100644 channels/rdpdr/rdpdr_main.c create mode 100644 channels/rdpdr/rdpdr_main.h create mode 100644 channels/rdpdr/rdpdr_types.h create mode 100644 channels/rdpdr/serial/CMakeLists.txt create mode 100644 channels/rdpdr/serial/serial_constants.h create mode 100644 channels/rdpdr/serial/serial_main.c create mode 100644 channels/rdpdr/serial/serial_tty.c create mode 100644 channels/rdpdr/serial/serial_tty.h create mode 100644 channels/rdpdr/smartcard/CMakeLists.txt create mode 100644 channels/rdpdr/smartcard/scard_main.c create mode 100644 channels/rdpdr/smartcard/scard_main.h create mode 100644 channels/rdpdr/smartcard/scard_operations.c create mode 100644 channels/rdpsnd/CMakeLists.txt create mode 100644 channels/rdpsnd/alsa/CMakeLists.txt create mode 100644 channels/rdpsnd/alsa/rdpsnd_alsa.c create mode 100644 channels/rdpsnd/pulse/CMakeLists.txt create mode 100644 channels/rdpsnd/pulse/rdpsnd_pulse.c create mode 100644 channels/rdpsnd/rdpsnd_main.c create mode 100644 channels/rdpsnd/rdpsnd_main.h create mode 100644 client/CMakeLists.txt create mode 100644 client/DirectFB/CMakeLists.txt create mode 100644 client/DirectFB/df_event.c create mode 100644 client/DirectFB/df_event.h create mode 100644 client/DirectFB/df_graphics.c create mode 100644 client/DirectFB/df_graphics.h create mode 100644 client/DirectFB/dfreerdp.c create mode 100644 client/DirectFB/dfreerdp.h create mode 100644 client/Windows/CMakeLists.txt create mode 100644 client/Windows/wf_event.c create mode 100644 client/Windows/wf_event.h create mode 100644 client/Windows/wf_gdi.c create mode 100644 client/Windows/wf_gdi.h create mode 100644 client/Windows/wf_graphics.c create mode 100644 client/Windows/wf_graphics.h create mode 100644 client/Windows/wfreerdp.c create mode 100644 client/Windows/wfreerdp.h create mode 100644 client/X11/CMakeLists.txt create mode 100644 client/X11/xf_cliprdr.c create mode 100644 client/X11/xf_cliprdr.h create mode 100644 client/X11/xf_event.c create mode 100644 client/X11/xf_event.h create mode 100644 client/X11/xf_gdi.c create mode 100644 client/X11/xf_gdi.h create mode 100644 client/X11/xf_graphics.c create mode 100644 client/X11/xf_graphics.h create mode 100644 client/X11/xf_keyboard.c create mode 100644 client/X11/xf_keyboard.h create mode 100644 client/X11/xf_monitor.c create mode 100644 client/X11/xf_monitor.h create mode 100644 client/X11/xf_rail.c create mode 100644 client/X11/xf_rail.h create mode 100644 client/X11/xf_tsmf.c create mode 100644 client/X11/xf_tsmf.h create mode 100644 client/X11/xf_window.c create mode 100644 client/X11/xf_window.h create mode 100644 client/X11/xfreerdp.1.xml create mode 100644 client/X11/xfreerdp.c create mode 100644 client/X11/xfreerdp.h create mode 100644 client/test/CMakeLists.txt create mode 100644 client/test/freerdp.c create mode 100644 cmake/AutoVersioning.cmake create mode 100644 cmake/ConfigOptions.cmake create mode 100644 cmake/FindCUnit.cmake create mode 100644 cmake/FindDirectFB.cmake create mode 100644 cmake/FindFFmpeg.cmake create mode 100644 cmake/FindOptionalPackage.cmake create mode 100644 cmake/FindPCSC.cmake create mode 100644 cmake/FindPulseAudio.cmake create mode 100644 cmake/FindX11.cmake create mode 100644 cmake/FindXKBFile.cmake create mode 100644 cmake/FindXShm.cmake create mode 100644 cmake/FindXTest.cmake create mode 100644 cmake/FindXcursor.cmake create mode 100644 cmake/FindXdamage.cmake create mode 100644 cmake/FindXext.cmake create mode 100644 cmake/FindXfixes.cmake create mode 100644 cmake/FindXinerama.cmake create mode 100644 cmake/FindXmlto.cmake create mode 100644 cmake/FindXv.cmake create mode 100644 cmake/GNUInstallDirsWrapper.cmake create mode 100644 config.h.in create mode 100644 cunit/CMakeLists.txt create mode 100644 cunit/test_ber.c create mode 100644 cunit/test_ber.h create mode 100644 cunit/test_bitmap.c create mode 100644 cunit/test_bitmap.h create mode 100644 cunit/test_channels.c create mode 100644 cunit/test_channels.h create mode 100644 cunit/test_cliprdr.c create mode 100644 cunit/test_cliprdr.h create mode 100644 cunit/test_color.c create mode 100644 cunit/test_color.h create mode 100644 cunit/test_drdynvc.c create mode 100644 cunit/test_drdynvc.h create mode 100644 cunit/test_freerdp.c create mode 100644 cunit/test_freerdp.h create mode 100644 cunit/test_gcc.c create mode 100644 cunit/test_gcc.h create mode 100644 cunit/test_libgdi.c create mode 100644 cunit/test_libgdi.h create mode 100644 cunit/test_librfx.c create mode 100644 cunit/test_librfx.h create mode 100644 cunit/test_license.c create mode 100644 cunit/test_license.h create mode 100644 cunit/test_list.c create mode 100644 cunit/test_list.h create mode 100644 cunit/test_mcs.c create mode 100644 cunit/test_mcs.h create mode 100644 cunit/test_mppc.c create mode 100644 cunit/test_mppc.h create mode 100644 cunit/test_orders.c create mode 100644 cunit/test_orders.h create mode 100644 cunit/test_pcap.c create mode 100644 cunit/test_pcap.h create mode 100644 cunit/test_per.c create mode 100644 cunit/test_per.h create mode 100644 cunit/test_rail.c create mode 100644 cunit/test_rail.h create mode 100644 cunit/test_stream.c create mode 100644 cunit/test_stream.h create mode 100644 cunit/test_utils.c create mode 100644 cunit/test_utils.h create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/freerdp-x11.install create mode 100644 debian/libfreerdp-dev.install create mode 100644 debian/libfreerdp-plugins-standard.install create mode 100644 debian/libfreerdp1.install create mode 100644 debian/libfreerdp1.symbols create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 debian/watch create mode 100644 docs/Doxyfile create mode 100644 docs/FreeRDP.vsd create mode 100644 freerdp.pc.in create mode 100644 freerdp.spec create mode 100644 include/CMakeLists.txt create mode 100644 include/freerdp/altsec.h create mode 100644 include/freerdp/api.h create mode 100644 include/freerdp/cache/bitmap.h create mode 100644 include/freerdp/cache/brush.h create mode 100644 include/freerdp/cache/cache.h create mode 100644 include/freerdp/cache/glyph.h create mode 100644 include/freerdp/cache/offscreen.h create mode 100644 include/freerdp/cache/palette.h create mode 100644 include/freerdp/cache/pointer.h create mode 100644 include/freerdp/channels/channels.h create mode 100644 include/freerdp/channels/wtsvc.h create mode 100644 include/freerdp/codec/bitmap.h create mode 100644 include/freerdp/codec/color.h create mode 100644 include/freerdp/codec/nsc.h create mode 100644 include/freerdp/codec/rfx.h create mode 100644 include/freerdp/constants.h create mode 100644 include/freerdp/dvc.h create mode 100644 include/freerdp/extension.h create mode 100644 include/freerdp/freerdp.h create mode 100644 include/freerdp/gdi/16bpp.h create mode 100644 include/freerdp/gdi/32bpp.h create mode 100644 include/freerdp/gdi/8bpp.h create mode 100644 include/freerdp/gdi/bitmap.h create mode 100644 include/freerdp/gdi/brush.h create mode 100644 include/freerdp/gdi/clipping.h create mode 100644 include/freerdp/gdi/dc.h create mode 100644 include/freerdp/gdi/drawing.h create mode 100644 include/freerdp/gdi/gdi.h create mode 100644 include/freerdp/gdi/line.h create mode 100644 include/freerdp/gdi/palette.h create mode 100644 include/freerdp/gdi/pen.h create mode 100644 include/freerdp/gdi/region.h create mode 100644 include/freerdp/gdi/shape.h create mode 100644 include/freerdp/graphics.h create mode 100644 include/freerdp/input.h create mode 100644 include/freerdp/kbd/kbd.h create mode 100644 include/freerdp/kbd/layouts.h create mode 100644 include/freerdp/kbd/locales.h create mode 100644 include/freerdp/kbd/vkcodes.h create mode 100644 include/freerdp/listener.h create mode 100644 include/freerdp/peer.h create mode 100644 include/freerdp/plugins/cliprdr.h create mode 100644 include/freerdp/plugins/tsmf.h create mode 100644 include/freerdp/pointer.h create mode 100644 include/freerdp/primary.h create mode 100644 include/freerdp/rail.h create mode 100644 include/freerdp/rail/icon.h create mode 100644 include/freerdp/rail/rail.h create mode 100644 include/freerdp/rail/window.h create mode 100644 include/freerdp/rail/window_list.h create mode 100644 include/freerdp/secondary.h create mode 100644 include/freerdp/settings.h create mode 100644 include/freerdp/svc.h create mode 100644 include/freerdp/types.h create mode 100644 include/freerdp/update.h create mode 100644 include/freerdp/utils/args.h create mode 100644 include/freerdp/utils/bitmap.h create mode 100644 include/freerdp/utils/blob.h create mode 100644 include/freerdp/utils/debug.h create mode 100644 include/freerdp/utils/dsp.h create mode 100644 include/freerdp/utils/event.h create mode 100644 include/freerdp/utils/file.h create mode 100644 include/freerdp/utils/hexdump.h create mode 100644 include/freerdp/utils/list.h create mode 100644 include/freerdp/utils/load_plugin.h create mode 100644 include/freerdp/utils/memory.h create mode 100644 include/freerdp/utils/mutex.h create mode 100644 include/freerdp/utils/passphrase.h create mode 100644 include/freerdp/utils/pcap.h create mode 100644 include/freerdp/utils/print.h create mode 100644 include/freerdp/utils/profiler.h create mode 100644 include/freerdp/utils/rail.h create mode 100644 include/freerdp/utils/rect.h create mode 100644 include/freerdp/utils/registry.h create mode 100644 include/freerdp/utils/semaphore.h create mode 100644 include/freerdp/utils/signal.h create mode 100644 include/freerdp/utils/sleep.h create mode 100644 include/freerdp/utils/stopwatch.h create mode 100644 include/freerdp/utils/stream.h create mode 100644 include/freerdp/utils/string.h create mode 100644 include/freerdp/utils/svc_plugin.h create mode 100644 include/freerdp/utils/thread.h create mode 100644 include/freerdp/utils/unicode.h create mode 100644 include/freerdp/utils/wait_obj.h create mode 100644 include/freerdp/window.h create mode 100644 keymaps/CMakeLists.txt create mode 100644 keymaps/aliases create mode 100644 keymaps/amiga create mode 100644 keymaps/ataritt create mode 100644 keymaps/digital_vndr/lk create mode 100644 keymaps/digital_vndr/pc create mode 100644 keymaps/empty create mode 100644 keymaps/evdev create mode 100644 keymaps/fujitsu create mode 100644 keymaps/hp create mode 100644 keymaps/ibm create mode 100644 keymaps/macintosh create mode 100644 keymaps/macosx create mode 100644 keymaps/sgi_vndr/indigo create mode 100644 keymaps/sgi_vndr/indy create mode 100644 keymaps/sgi_vndr/iris create mode 100644 keymaps/sony create mode 100644 keymaps/sun create mode 100644 keymaps/xfree86 create mode 100644 keymaps/xfree98 create mode 100755 keymaps/xkb.pl create mode 100644 libfreerdp-cache/CMakeLists.txt create mode 100644 libfreerdp-cache/bitmap.c create mode 100644 libfreerdp-cache/brush.c create mode 100644 libfreerdp-cache/cache.c create mode 100644 libfreerdp-cache/glyph.c create mode 100644 libfreerdp-cache/offscreen.c create mode 100644 libfreerdp-cache/palette.c create mode 100644 libfreerdp-cache/pointer.c create mode 100644 libfreerdp-channels/CMakeLists.txt create mode 100644 libfreerdp-channels/libchannels.c create mode 100644 libfreerdp-channels/libchannels.h create mode 100644 libfreerdp-channels/wtsvc.c create mode 100644 libfreerdp-channels/wtsvc.h create mode 100644 libfreerdp-codec/CMakeLists.txt create mode 100644 libfreerdp-codec/bitmap.c create mode 100644 libfreerdp-codec/color.c create mode 100644 libfreerdp-codec/include/bitmap.c create mode 100644 libfreerdp-codec/nsc.c create mode 100644 libfreerdp-codec/rfx.c create mode 100644 libfreerdp-codec/rfx_bitstream.h create mode 100644 libfreerdp-codec/rfx_constants.h create mode 100644 libfreerdp-codec/rfx_decode.c create mode 100644 libfreerdp-codec/rfx_decode.h create mode 100644 libfreerdp-codec/rfx_differential.c create mode 100644 libfreerdp-codec/rfx_differential.h create mode 100644 libfreerdp-codec/rfx_dwt.c create mode 100644 libfreerdp-codec/rfx_dwt.h create mode 100644 libfreerdp-codec/rfx_encode.c create mode 100644 libfreerdp-codec/rfx_encode.h create mode 100644 libfreerdp-codec/rfx_neon.c create mode 100644 libfreerdp-codec/rfx_neon.h create mode 100644 libfreerdp-codec/rfx_pool.c create mode 100644 libfreerdp-codec/rfx_pool.h create mode 100644 libfreerdp-codec/rfx_quantization.c create mode 100644 libfreerdp-codec/rfx_quantization.h create mode 100644 libfreerdp-codec/rfx_rlgr.c create mode 100644 libfreerdp-codec/rfx_rlgr.h create mode 100644 libfreerdp-codec/rfx_sse2.c create mode 100644 libfreerdp-codec/rfx_sse2.h create mode 100644 libfreerdp-codec/rfx_types.h create mode 100644 libfreerdp-core/CMakeLists.txt create mode 100644 libfreerdp-core/activation.c create mode 100644 libfreerdp-core/activation.h create mode 100644 libfreerdp-core/ber.c create mode 100644 libfreerdp-core/ber.h create mode 100644 libfreerdp-core/capabilities.c create mode 100644 libfreerdp-core/capabilities.h create mode 100644 libfreerdp-core/certificate.c create mode 100644 libfreerdp-core/certificate.h create mode 100644 libfreerdp-core/channel.c create mode 100644 libfreerdp-core/channel.h create mode 100644 libfreerdp-core/connection.c create mode 100644 libfreerdp-core/connection.h create mode 100644 libfreerdp-core/credssp.c create mode 100644 libfreerdp-core/credssp.h create mode 100644 libfreerdp-core/crypto.c create mode 100644 libfreerdp-core/crypto.h create mode 100644 libfreerdp-core/errinfo.c create mode 100644 libfreerdp-core/errinfo.h create mode 100644 libfreerdp-core/extension.c create mode 100644 libfreerdp-core/extension.h create mode 100644 libfreerdp-core/fastpath.c create mode 100644 libfreerdp-core/fastpath.h create mode 100644 libfreerdp-core/freerdp.c create mode 100644 libfreerdp-core/gcc.c create mode 100644 libfreerdp-core/gcc.h create mode 100644 libfreerdp-core/graphics.c create mode 100644 libfreerdp-core/info.c create mode 100644 libfreerdp-core/info.h create mode 100644 libfreerdp-core/input.c create mode 100644 libfreerdp-core/input.h create mode 100644 libfreerdp-core/license.c create mode 100644 libfreerdp-core/license.h create mode 100644 libfreerdp-core/listener.c create mode 100644 libfreerdp-core/listener.h create mode 100644 libfreerdp-core/mcs.c create mode 100644 libfreerdp-core/mcs.h create mode 100644 libfreerdp-core/mppc.c create mode 100644 libfreerdp-core/mppc.h create mode 100644 libfreerdp-core/nego.c create mode 100644 libfreerdp-core/nego.h create mode 100644 libfreerdp-core/ntlmssp.c create mode 100644 libfreerdp-core/ntlmssp.h create mode 100644 libfreerdp-core/orders.c create mode 100644 libfreerdp-core/orders.h create mode 100644 libfreerdp-core/peer.c create mode 100644 libfreerdp-core/peer.h create mode 100644 libfreerdp-core/per.c create mode 100644 libfreerdp-core/per.h create mode 100644 libfreerdp-core/rdp.c create mode 100644 libfreerdp-core/rdp.h create mode 100644 libfreerdp-core/redirection.c create mode 100644 libfreerdp-core/redirection.h create mode 100644 libfreerdp-core/security.c create mode 100644 libfreerdp-core/security.h create mode 100644 libfreerdp-core/settings.c create mode 100644 libfreerdp-core/surface.c create mode 100644 libfreerdp-core/surface.h create mode 100644 libfreerdp-core/tcp.c create mode 100644 libfreerdp-core/tcp.h create mode 100644 libfreerdp-core/tls.c create mode 100644 libfreerdp-core/tls.h create mode 100644 libfreerdp-core/tpdu.c create mode 100644 libfreerdp-core/tpdu.h create mode 100644 libfreerdp-core/tpkt.c create mode 100644 libfreerdp-core/tpkt.h create mode 100644 libfreerdp-core/transport.c create mode 100644 libfreerdp-core/transport.h create mode 100644 libfreerdp-core/update.c create mode 100644 libfreerdp-core/update.h create mode 100644 libfreerdp-core/window.c create mode 100644 libfreerdp-core/window.h create mode 100644 libfreerdp-gdi/16bpp.c create mode 100644 libfreerdp-gdi/32bpp.c create mode 100644 libfreerdp-gdi/8bpp.c create mode 100644 libfreerdp-gdi/CMakeLists.txt create mode 100644 libfreerdp-gdi/bitmap.c create mode 100644 libfreerdp-gdi/brush.c create mode 100644 libfreerdp-gdi/clipping.c create mode 100644 libfreerdp-gdi/dc.c create mode 100644 libfreerdp-gdi/drawing.c create mode 100644 libfreerdp-gdi/gdi.c create mode 100644 libfreerdp-gdi/gdi.h create mode 100644 libfreerdp-gdi/graphics.c create mode 100644 libfreerdp-gdi/graphics.h create mode 100644 libfreerdp-gdi/include/line.c create mode 100644 libfreerdp-gdi/line.c create mode 100644 libfreerdp-gdi/palette.c create mode 100644 libfreerdp-gdi/pen.c create mode 100644 libfreerdp-gdi/region.c create mode 100644 libfreerdp-gdi/shape.c create mode 100644 libfreerdp-kbd/CMakeLists.txt create mode 100644 libfreerdp-kbd/layouts.c create mode 100644 libfreerdp-kbd/layouts_xkb.c create mode 100644 libfreerdp-kbd/layouts_xkb.h create mode 100644 libfreerdp-kbd/libkbd.c create mode 100644 libfreerdp-kbd/libkbd.h create mode 100644 libfreerdp-kbd/locales.c create mode 100644 libfreerdp-kbd/x_layout_id_table.c create mode 100644 libfreerdp-kbd/x_layout_id_table.h create mode 100644 libfreerdp-rail/CMakeLists.txt create mode 100644 libfreerdp-rail/icon.c create mode 100644 libfreerdp-rail/librail.h create mode 100644 libfreerdp-rail/rail.c create mode 100644 libfreerdp-rail/window.c create mode 100644 libfreerdp-rail/window_list.c create mode 100644 libfreerdp-utils/CMakeLists.txt create mode 100644 libfreerdp-utils/args.c create mode 100644 libfreerdp-utils/bitmap.c create mode 100644 libfreerdp-utils/blob.c create mode 100644 libfreerdp-utils/dsp.c create mode 100644 libfreerdp-utils/event.c create mode 100644 libfreerdp-utils/file.c create mode 100644 libfreerdp-utils/hexdump.c create mode 100644 libfreerdp-utils/list.c create mode 100644 libfreerdp-utils/load_plugin.c create mode 100644 libfreerdp-utils/memory.c create mode 100644 libfreerdp-utils/mutex.c create mode 100644 libfreerdp-utils/passphrase.c create mode 100644 libfreerdp-utils/pcap.c create mode 100644 libfreerdp-utils/profiler.c create mode 100644 libfreerdp-utils/rail.c create mode 100644 libfreerdp-utils/rect.c create mode 100644 libfreerdp-utils/registry.c create mode 100644 libfreerdp-utils/semaphore.c create mode 100644 libfreerdp-utils/signal.c create mode 100644 libfreerdp-utils/sleep.c create mode 100644 libfreerdp-utils/stopwatch.c create mode 100644 libfreerdp-utils/stream.c create mode 100644 libfreerdp-utils/string.c create mode 100644 libfreerdp-utils/svc_plugin.c create mode 100644 libfreerdp-utils/thread.c create mode 100644 libfreerdp-utils/unicode.c create mode 100644 libfreerdp-utils/wait_obj.c create mode 100644 resources/FreeRDP-fav.ico create mode 100644 resources/FreeRDP.ico create mode 100644 resources/FreeRDP_Icon_256px.h create mode 100644 resources/FreeRDP_Icon_256px.png create mode 100644 resources/FreeRDP_Icon_256px.xpm create mode 100644 resources/FreeRDP_Logo_Icon.ai create mode 100644 resources/FreeRDP_Logo_Icon.svg create mode 100644 resources/FreeRDP_OSX.icns create mode 100755 resources/conv_to_ewm_prop.py create mode 100644 server/CMakeLists.txt create mode 100644 server/X11/CMakeLists.txt create mode 100644 server/X11/rfx_test.pcap create mode 100644 server/X11/server.crt create mode 100644 server/X11/server.key create mode 100644 server/X11/xf_encode.c create mode 100644 server/X11/xf_encode.h create mode 100644 server/X11/xf_event.c create mode 100644 server/X11/xf_event.h create mode 100644 server/X11/xf_input.c create mode 100644 server/X11/xf_input.h create mode 100644 server/X11/xf_peer.c create mode 100644 server/X11/xf_peer.h create mode 100644 server/X11/xfreerdp.c create mode 100644 server/X11/xfreerdp.h create mode 100644 server/test/CMakeLists.txt create mode 100644 server/test/rfx_test.pcap create mode 100644 server/test/server.crt create mode 100644 server/test/server.key create mode 100644 server/test/test_icon.ppm create mode 100644 server/test/tfreerdp.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00fb8ed --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +# CMake +CMakeFiles/ +CMakeCache.txt +config.h +install_manifest.txt +CTestTestfile.cmake +freerdp.pc +Makefile +cmake_install.cmake +CPackConfig.cmake +CPackSourceConfig.cmake + +# Eclipse +*.project +*.cproject +*.settings + +# Documentation +docs/api +client/X11/xfreerdp.1 + +# Mac OS X +.DS_Store + +# Windows +*.vcxproj +*.vcxproj.* +*.sdf +*.sln +*.suo +*.opensdf +ipch +Debug + +# Binaries +*.a +*.so +*.so.* +*.dylib +cunit/test_freerdp +client/X11/xfreerdp +client/test/freerdp-test +client/DirectFB/dfreerdp +server/test/tfreerdp-server +server/X11/xfreerdp-server + +# Other +*~ + diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches new file mode 100644 index 0000000..6857a8d --- /dev/null +++ b/.pc/.quilt_patches @@ -0,0 +1 @@ +debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series new file mode 100644 index 0000000..c206706 --- /dev/null +++ b/.pc/.quilt_series @@ -0,0 +1 @@ +series diff --git a/.pc/.version b/.pc/.version new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/.pc/.version @@ -0,0 +1 @@ +2 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5399db7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,187 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 2.6) +project(FreeRDP C) +set(CMAKE_COLOR_MAKEFILE ON) + +# Include cmake modules +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(FindPkgConfig) +include(TestBigEndian) + +# Include our extra modules +set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) + +include(AutoVersioning) +include(ConfigOptions) +include(FindOptionalPackage) +include(CheckCCompilerFlag) +include(GNUInstallDirsWrapper) + +# Soname versioning +set(FREERDP_VERSION_MAJOR "1") +set(FREERDP_VERSION_MINOR "0") +set(FREERDP_VERSION_REVISION "1") +set(FREERDP_VERSION "${FREERDP_VERSION_MAJOR}.${FREERDP_VERSION_MINOR}") +set(FREERDP_VERSION_FULL "${FREERDP_VERSION}.${FREERDP_VERSION_REVISION}") + +# Default to release build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release") +endif() + +# build shared libs +if(NOT BUILD_SHARED_LIBS) + set(BUILD_SHARED_LIBS ON) +endif() + +# Compiler-specific flags +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") + CHECK_C_COMPILER_FLAG (-Wno-unused-result Wno-unused-result) + if(Wno-unused-result) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result") + endif() + CHECK_C_COMPILER_FLAG (-Wno-unused-but-set-variable Wno-unused-but-set-variable) + if(Wno-unused-but-set-variable) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable") + endif() + if(CMAKE_BUILD_TYPE STREQUAL "Release") + set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") + endif() + if(WITH_SSE2_TARGET) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2") + endif() +endif() + +if(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gd /MT") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /O2 /Ob2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") + SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}) + SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}) +endif() + +# Include files +check_include_files(sys/param.h HAVE_SYS_PARAM_H) +check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) +check_include_files(netdb.h HAVE_NETDB_H) +check_include_files(fcntl.h HAVE_FCNTL_H) +check_include_files(unistd.h HAVE_UNISTD_H) +check_include_files(limits.h HAVE_LIMITS_H) +check_include_files(stdint.h HAVE_STDINT_H) +check_include_files(stdbool.h HAVE_STDBOOL_H) +check_include_files(inttypes.h HAVE_INTTYPES_H) + +# Libraries that we have a hard dependency on +find_required_package(OpenSSL) + +# Mac OS X +if(APPLE) + include_directories(/opt/local/include) + link_directories(/opt/local/lib) + set(CMAKE_SHARED_LINKER_FLAGS "-mmacosx-version-min=10.4") +endif() + +if(NOT WIN32) + find_required_package(ZLIB) + find_optional_package(PulseAudio) + find_optional_package(PCSC) + find_suggested_package(Cups) + + if(NOT APPLE) + find_suggested_package(FFmpeg) + find_suggested_package(ALSA) + else(NOT APPLE) + find_optional_package(FFmpeg) + endif() +endif() + +# Endian +test_big_endian(BIG_ENDIAN) + +# Path to put keymaps +set(FREERDP_KEYMAP_PATH "${CMAKE_INSTALL_PREFIX}/freerdp/keymaps") + +# Path to put plugins +set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp") + +# Include directories +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_SOURCE_DIR}/include) + +# Configure files +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) + +# Generate pkg-config +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + +# Build CUnit +find_optional_package(CUnit) +if(WITH_CUNIT) + enable_testing() + add_subdirectory(cunit) +endif() + +# Sub-directories +add_subdirectory(include) +add_subdirectory(libfreerdp-utils) + +if(NOT WIN32) + add_subdirectory(libfreerdp-kbd) +endif() + +add_subdirectory(libfreerdp-gdi) +add_subdirectory(libfreerdp-rail) +add_subdirectory(libfreerdp-cache) +add_subdirectory(libfreerdp-codec) +add_subdirectory(libfreerdp-channels) +add_subdirectory(libfreerdp-core) + +if(NOT WIN32) + add_subdirectory(channels) +endif() + +option(WITH_CLIENT "Build client binaries" ON) +if(WITH_CLIENT) + add_subdirectory(client) +endif() + +option(WITH_SERVER "Build server binaries" OFF) +if(WITH_SERVER) + add_subdirectory(server) +endif() + +add_subdirectory(keymaps) + +# Source package +set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt") + +string(TOLOWER ${CMAKE_PROJECT_NAME} CMAKE_PROJECT_NAME_lower) +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME_lower}-${FREERDP_VERSION_FULL}") + +include(CPack) diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..6149261 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,118 @@ +2012-02-07 Version 1.0.1 + +FreeRDP 1.0.1 is a maintenance release to address a certain number of +issues found in 1.0.0. This release also brings corrective measures +to certificate validation which were required for inclusion in Ubuntu. + +* Certificate Validation + * Improved validation logic and robustness + * Added validation of certificate name against hostname + +* Token-based Server Redirection + * Fixed redirection logic + * HAProxy load-balancer support + +* xfreerdp-server + * better event handling + * capture performance improvements + +* wfreerdp + * Fix RemoteFX support + * Fix mingw64 compilation + +* libfreerdp-core: + * Fix severe TCP sending bug + * Added server-side Standard RDP security + +2012-01-16 Version 1.0.0 + +License: + +FreeRDP 1.0 is the first release of FreeRDP under the Apache License 2.0. +The FreeRDP 1.x series is a rewrite, meaning there is no continuity with +the previous FreeRDP 0.x series which were released under GPLv2. + +New Features: + +* RemoteFX + * Both encoder and decoder + * SSE2 and NEON optimization +* NSCodec +* RemoteApp + * Working, minor glitches +* Multimedia Redirection + * ffmpeg support +* Network Level Authentication (NLA) + * NTLMv2 +* Certificate validation +* FIPS-compliant RDP security +* new build system (cmake) +* added official logo and icon + +New Architecture: + +* libfreerdp-core + * core protocol + * highly portable + * both client and server +* libfreerdp-cache + * caching operations +* libfreerdp-codec + * bitmap decompression + * codec encoding/decoding +* libfreerdp-kbd + * keyboard mapping +* libfreerdp-channels + * virtual channel management + * client and server side support +* libfreerdp-gdi + * extensively unit tested + * portable software GDI implementation +* libfreerdp-rail + * RemoteApp library +* libfreerdp-utils + * shared utility library + +FreeRDP Clients: + +* client/X11 (xfreerdp) + * official client + * RemoteApp support + * X11 GDI implementation +* client/DirectFB (dfreerdp) + * DirectFB support + * software-based GDI (libfreerdp-gdi) +* client/Windows (wfreerdp) + * Native Win32 support + +FreeRDP Servers (experimental): + +* server/X11 (xfreerdp-server) + * RemoteFX-only + * no authentication + * highly experimental + * keyboard and mouse input supported + +Virtual Channels: + +* cliprdr (Clipboard Redirection) +* rail (RemoteApp) +* drdynvc (Dynamic Virtual Channels) + * audin (Audio Input Redirection) + * alsa support + * pulse support + * tsmf (Multimedia Redirection) + * alsa support + * pulse support + * ffmpeg support +* rdpdr (Device Redirection) + * disk (Disk Redirection) + * parallel (Parallel Port Redirection) + * serial (Serial Port Redirection) + * printer (Printer Redirection) + * CUPS support + * smartcard (Smartcard Redirection) +* rdpsnd (Sound Redirection) + * alsa support + * pulse support + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README b/README new file mode 100644 index 0000000..6c67f01 --- /dev/null +++ b/README @@ -0,0 +1,34 @@ +FreeRDP: A Remote Desktop Protocol Implementation +================================================= + +FreeRDP is a free implementation of the Remote Desktop Protocol (RDP), released under the Apache license. +Enjoy the freedom of using your software wherever you want, the way you want it, in a world where +interoperability can finally liberate your computing experience. + +Resources +--------- + +Website: http://www.freerdp.com/ +Wiki: https://github.com/FreeRDP/FreeRDP/wiki +Sources: https://github.com/FreeRDP/FreeRDP/ +API doc: http://www.freerdp.com/api/ + +IRC channel: #freerdp @ irc.freenode.net +Mailing list: https://lists.sourceforge.net/lists/listinfo/freerdp-devel + +Microsoft Open Specifications +----------------------------- + +Information regarding the Microsoft Open Specifications can be found at: +http://www.microsoft.com/openspecifications/ + +A list of reference documentation is maintained here: +https://github.com/FreeRDP/FreeRDP/wiki/Reference-Documentation + +Compilation +----------- + +Instructions on how to get started compiling FreeRDP can be found on the wiki: +https://github.com/FreeRDP/FreeRDP/wiki/Compilation + + diff --git a/channels/CMakeLists.txt b/channels/CMakeLists.txt new file mode 100644 index 0000000..648e2a8 --- /dev/null +++ b/channels/CMakeLists.txt @@ -0,0 +1,26 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_subdirectory(cliprdr) +add_subdirectory(drdynvc) +add_subdirectory(rdpdbg) +add_subdirectory(rdpdr) +add_subdirectory(rail) +add_subdirectory(rdpsnd) + diff --git a/channels/cliprdr/CMakeLists.txt b/channels/cliprdr/CMakeLists.txt new file mode 100644 index 0000000..03fb0ba --- /dev/null +++ b/channels/cliprdr/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(CLIPRDR_SRCS + cliprdr_constants.h + cliprdr_format.c + cliprdr_format.h + cliprdr_main.c + cliprdr_main.h +) + +add_library(cliprdr ${CLIPRDR_SRCS}) +set_target_properties(cliprdr PROPERTIES PREFIX "") + +target_link_libraries(cliprdr freerdp-utils) + +install(TARGETS cliprdr DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/cliprdr/cliprdr_constants.h b/channels/cliprdr/cliprdr_constants.h new file mode 100644 index 0000000..d3544ba --- /dev/null +++ b/channels/cliprdr/cliprdr_constants.h @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CLIPRDR_CONSTANTS +#define __CLIPRDR_CONSTANTS + +/* CLIPRDR_HEADER.msgType */ +#define CB_MONITOR_READY 0x0001 +#define CB_FORMAT_LIST 0x0002 +#define CB_FORMAT_LIST_RESPONSE 0x0003 +#define CB_FORMAT_DATA_REQUEST 0x0004 +#define CB_FORMAT_DATA_RESPONSE 0x0005 +#define CB_TEMP_DIRECTORY 0x0006 +#define CB_CLIP_CAPS 0x0007 +#define CB_FILECONTENTS_REQUEST 0x0008 +#define CB_FILECONTENTS_RESPONSE 0x0009 +#define CB_LOCK_CLIPDATA 0x000A +#define CB_UNLOCK_CLIPDATA 0x000B + +/* CLIPRDR_HEADER.msgFlags */ +#define CB_RESPONSE_OK 0x0001 +#define CB_RESPONSE_FAIL 0x0002 +#define CB_ASCII_NAMES 0x0004 + +/* CLIPRDR_CAPS_SET.capabilitySetType */ +#define CB_CAPSTYPE_GENERAL 0x0001 + +/* CLIPRDR_GENERAL_CAPABILITY.lengthCapability */ +#define CB_CAPSTYPE_GENERAL_LEN 12 + +/* CLIPRDR_GENERAL_CAPABILITY.version */ +#define CB_CAPS_VERSION_1 0x00000001 +#define CB_CAPS_VERSION_2 0x00000002 + +/* CLIPRDR_GENERAL_CAPABILITY.generalFlags */ +#define CB_USE_LONG_FORMAT_NAMES 0x00000002 +#define CB_STREAM_FILECLIP_ENABLED 0x00000004 +#define CB_FILECLIP_NO_FILE_PATHS 0x00000008 +#define CB_CAN_LOCK_CLIPDATA 0x00000010 + +#endif /* __CLIPRDR_CONSTANTS */ diff --git a/channels/cliprdr/cliprdr_format.c b/channels/cliprdr/cliprdr_format.c new file mode 100644 index 0000000..19099b0 --- /dev/null +++ b/channels/cliprdr/cliprdr_format.c @@ -0,0 +1,354 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cliprdr_constants.h" +#include "cliprdr_main.h" +#include "cliprdr_format.h" + +#define CFSTR_HTML "H\0T\0M\0L\0 \0F\0o\0r\0m\0a\0t\0\0" +#define CFSTR_PNG "P\0N\0G\0\0" +#define CFSTR_JPEG "J\0F\0I\0F\0\0" +#define CFSTR_GIF "G\0I\0F\0\0" + +void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event) +{ + int i; + STREAM* s; + + DEBUG_CLIPRDR("Sending Clipboard Format List"); + + if (cb_event->raw_format_data) + { + s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size); + stream_write(s, cb_event->raw_format_data, cb_event->raw_format_data_size); + } + else + { + STREAM* body = stream_new(0); + + for (i = 0; i < cb_event->num_formats; i++) + { + const char* name; + int name_length; + + switch (cb_event->formats[i]) + { + case CB_FORMAT_HTML: + name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML); + break; + case CB_FORMAT_PNG: + name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG); + break; + case CB_FORMAT_JPEG: + name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG); + break; + case CB_FORMAT_GIF: + name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF); + break; + default: + name = "\0\0"; name_length = 2; + } + + if (!cliprdr->use_long_format_names) + name_length = 32; + + stream_extend(body, stream_get_size(body) + 4 + name_length); + + stream_write_uint32(body, cb_event->formats[i]); + stream_write(body, name, name_length); + } + + s = cliprdr_packet_new(CB_FORMAT_LIST, 0, stream_get_size(body)); + stream_write(s, stream_get_head(body), stream_get_size(body)); + stream_free(body); + } + + cliprdr_packet_send(cliprdr, s); +} + +static void cliprdr_send_format_list_response(cliprdrPlugin* cliprdr) +{ + STREAM* s; + DEBUG_CLIPRDR("Sending Clipboard Format List Response"); + s = cliprdr_packet_new(CB_FORMAT_LIST_RESPONSE, CB_RESPONSE_OK, 0); + cliprdr_packet_send(cliprdr, s); +} + +void cliprdr_process_short_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint32 length, uint16 flags) +{ + int i; + boolean ascii; + int num_formats; + CLIPRDR_FORMAT_NAME* format_name; + + num_formats = length / 36; + + if (num_formats <= 0) + { + cliprdr->format_names = NULL; + cliprdr->num_format_names = 0; + return; + } + + if (num_formats * 36 != length) + DEBUG_WARN("dataLen %d not divided by 36!", length); + + ascii = (flags & CB_ASCII_NAMES) ? true : false; + + cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xmalloc(sizeof(CLIPRDR_FORMAT_NAME) * num_formats); + cliprdr->num_format_names = num_formats; + + for (i = 0; i < num_formats; i++) + { + format_name = &cliprdr->format_names[i]; + + stream_read_uint32(s, format_name->id); + + if (ascii) + { + format_name->name = xstrdup((char*) s->p); + format_name->length = strlen(format_name->name); + } + else + { + format_name->name = freerdp_uniconv_in(cliprdr->uniconv, s->p, 32); + format_name->length = strlen(format_name->name); + } + + stream_seek(s, 32); + } +} + +void cliprdr_process_long_format_names(cliprdrPlugin* cliprdr, STREAM* s, uint32 length, uint16 flags) +{ + int allocated_formats = 8; + uint8* end_mark; + CLIPRDR_FORMAT_NAME* format_name; + + stream_get_mark(s, end_mark); + end_mark += length; + + cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xmalloc(sizeof(CLIPRDR_FORMAT_NAME) * allocated_formats); + cliprdr->num_format_names = 0; + + while (stream_get_left(s) >= 6) + { + uint8* p; + int name_len; + + if (cliprdr->num_format_names >= allocated_formats) + { + allocated_formats *= 2; + cliprdr->format_names = (CLIPRDR_FORMAT_NAME*) xrealloc(cliprdr->format_names, + sizeof(CLIPRDR_FORMAT_NAME) * allocated_formats); + } + + format_name = &cliprdr->format_names[cliprdr->num_format_names++]; + stream_read_uint32(s, format_name->id); + + format_name->name = NULL; + format_name->length = 0; + + for (p = stream_get_tail(s), name_len = 0; p + 1 < end_mark; p += 2, name_len += 2) + { + if (*((unsigned short*) p) == 0) + break; + } + + format_name->name = freerdp_uniconv_in(cliprdr->uniconv, stream_get_tail(s), name_len); + format_name->length = strlen(format_name->name); + stream_seek(s, name_len + 2); + } +} + +void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags) +{ + int i; + uint32 format; + boolean supported; + CLIPRDR_FORMAT_NAME* format_name; + RDP_CB_FORMAT_LIST_EVENT* cb_event; + + cb_event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + if (dataLen > 0) + { + cb_event->raw_format_data = (uint8*) xmalloc(dataLen); + memcpy(cb_event->raw_format_data, stream_get_tail(s), dataLen); + cb_event->raw_format_data_size = dataLen; + } + + if (cliprdr->use_long_format_names) + cliprdr_process_long_format_names(cliprdr, s, dataLen, msgFlags); + else + cliprdr_process_short_format_names(cliprdr, s, dataLen, msgFlags); + + if (cliprdr->num_format_names > 0) + cb_event->formats = (uint32*) xmalloc(sizeof(uint32) * cliprdr->num_format_names); + + cb_event->num_formats = 0; + + for (i = 0; i < cliprdr->num_format_names; i++) + { + supported = true; + format_name = &cliprdr->format_names[i]; + format = format_name->id; + + switch (format) + { + case CB_FORMAT_TEXT: + case CB_FORMAT_DIB: + case CB_FORMAT_UNICODETEXT: + break; + + default: + + if (format_name->length > 0) + { + DEBUG_CLIPRDR("format: %s", format_name->name); + + if (strcmp(format_name->name, "HTML Format") == 0) + { + format = CB_FORMAT_HTML; + break; + } + if (strcmp(format_name->name, "PNG") == 0) + { + format = CB_FORMAT_PNG; + break; + } + if (strcmp(format_name->name, "JFIF") == 0) + { + format = CB_FORMAT_JPEG; + break; + } + if (strcmp(format_name->name, "GIF") == 0) + { + format = CB_FORMAT_GIF; + break; + } + } + else + { + supported = false; + } + + break; + } + + if (supported) + cb_event->formats[cb_event->num_formats++] = format; + + if (format_name->length > 0) + xfree(format_name->name); + } + + xfree(cliprdr->format_names); + cliprdr->format_names = NULL; + + cliprdr->num_format_names = 0; + + svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (RDP_EVENT*) cb_event); + cliprdr_send_format_list_response(cliprdr); +} + +void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags) +{ + /* where is this documented? */ +#if 0 + RDP_EVENT* event; + + if ((msgFlags & CB_RESPONSE_FAIL) != 0) + { + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL); + svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); + } +#endif +} + +void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags) +{ + RDP_CB_DATA_REQUEST_EVENT* cb_event; + + cb_event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_REQUEST, NULL, NULL); + + stream_read_uint32(s, cb_event->format); + svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (RDP_EVENT*) cb_event); +} + +void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_RESPONSE_EVENT* cb_event) +{ + STREAM* s; + + DEBUG_CLIPRDR("Sending Format Data Response"); + + if (cb_event->size > 0) + { + s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_OK, cb_event->size); + stream_write(s, cb_event->data, cb_event->size); + } + else + { + s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_FAIL, 0); + } + + cliprdr_packet_send(cliprdr, s); +} + +void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event) +{ + STREAM* s; + + DEBUG_CLIPRDR("Sending Format Data Request"); + + s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST, 0, 4); + stream_write_uint32(s, cb_event->format); + cliprdr_packet_send(cliprdr, s); +} + +void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags) +{ + RDP_CB_DATA_RESPONSE_EVENT* cb_event; + + cb_event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_RESPONSE, NULL, NULL); + + if (dataLen > 0) + { + cb_event->size = dataLen; + cb_event->data = (uint8*) xmalloc(dataLen); + memcpy(cb_event->data, stream_get_tail(s), dataLen); + } + + svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (RDP_EVENT*) cb_event); +} diff --git a/channels/cliprdr/cliprdr_format.h b/channels/cliprdr/cliprdr_format.h new file mode 100644 index 0000000..48040b6 --- /dev/null +++ b/channels/cliprdr/cliprdr_format.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CLIPRDR_FORMAT_H +#define __CLIPRDR_FORMAT_H + +void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event); +void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags); +void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags); + +void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags); +void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_RESPONSE_EVENT* cb_event); + +void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event); +void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen, uint16 msgFlags); + +#endif /* __CLIPRDR_FORMAT_H */ diff --git a/channels/cliprdr/cliprdr_main.c b/channels/cliprdr/cliprdr_main.c new file mode 100644 index 0000000..a2f5a79 --- /dev/null +++ b/channels/cliprdr/cliprdr_main.c @@ -0,0 +1,276 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cliprdr_constants.h" +#include "cliprdr_main.h" +#include "cliprdr_format.h" + +static const char* const CB_MSG_TYPE_STRINGS[] = +{ + "", + "CB_MONITOR_READY", + "CB_FORMAT_LIST", + "CB_FORMAT_LIST_RESPONSE", + "CB_FORMAT_DATA_REQUEST", + "CB_FORMAT_DATA_RESPONSE", + "CB_TEMP_DIRECTORY", + "CB_CLIP_CAPS", + "CB_FILECONTENTS_REQUEST", + "CB_FILECONTENTS_RESPONSE", + "CB_LOCK_CLIPDATA" + "CB_UNLOCK_CLIPDATA" +}; + +STREAM* cliprdr_packet_new(uint16 msgType, uint16 msgFlags, uint32 dataLen) +{ + STREAM* s; + + s = stream_new(dataLen + 8); + stream_write_uint16(s, msgType); + stream_write_uint16(s, msgFlags); + /* Write actual length after the entire packet has been constructed. */ + stream_seek(s, 4); + + return s; +} + +void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* s) +{ + int pos; + uint32 dataLen; + + pos = stream_get_pos(s); + dataLen = pos - 8; + stream_set_pos(s, 4); + stream_write_uint32(s, dataLen); + stream_set_pos(s, pos); + + svc_plugin_send((rdpSvcPlugin*) cliprdr, s); +} + +static void cliprdr_process_connect(rdpSvcPlugin* plugin) +{ + DEBUG_CLIPRDR("connecting"); + + ((cliprdrPlugin*) plugin)->uniconv = freerdp_uniconv_new(); +} + +void cliprdr_print_general_capability_flags(uint32 flags) +{ + printf("generalFlags (0x%08X) {\n", flags); + + if (flags & CB_USE_LONG_FORMAT_NAMES) + printf("\tCB_USE_LONG_FORMAT_NAMES\n"); + if (flags & CB_STREAM_FILECLIP_ENABLED) + printf("\tCB_STREAM_FILECLIP_ENABLED\n"); + if (flags & CB_FILECLIP_NO_FILE_PATHS) + printf("\tCB_FILECLIP_NO_FILE_PATHS\n"); + if (flags & CB_CAN_LOCK_CLIPDATA) + printf("\tCB_CAN_LOCK_CLIPDATA\n"); + + printf("}\n"); +} + +static void cliprdr_process_general_capability(cliprdrPlugin* cliprdr, STREAM* s) +{ + uint32 version; + uint32 generalFlags; + + stream_read_uint32(s, version); /* version (4 bytes) */ + stream_read_uint32(s, generalFlags); /* generalFlags (4 bytes) */ + + DEBUG_CLIPRDR("Version: %d", version); + +#ifdef WITH_DEBUG_CLIPRDR + cliprdr_print_general_capability_flags(generalFlags); +#endif + + if (generalFlags & CB_USE_LONG_FORMAT_NAMES) + cliprdr->use_long_format_names = true; + + if (generalFlags & CB_STREAM_FILECLIP_ENABLED) + cliprdr->stream_fileclip_enabled = true; + + if (generalFlags & CB_FILECLIP_NO_FILE_PATHS) + cliprdr->fileclip_no_file_paths = true; + + if (generalFlags & CB_CAN_LOCK_CLIPDATA) + cliprdr->can_lock_clipdata = true; + + cliprdr->received_caps = true; +} + +static void cliprdr_process_clip_caps(cliprdrPlugin* cliprdr, STREAM* s, uint16 length, uint16 flags) +{ + int i; + uint16 lengthCapability; + uint16 cCapabilitiesSets; + uint16 capabilitySetType; + + stream_read_uint16(s, cCapabilitiesSets); /* cCapabilitiesSets (2 bytes) */ + stream_seek_uint16(s); /* pad1 (2 bytes) */ + + DEBUG_CLIPRDR("cCapabilitiesSets %d", cCapabilitiesSets); + + for (i = 0; i < cCapabilitiesSets; i++) + { + stream_read_uint16(s, capabilitySetType); /* capabilitySetType (2 bytes) */ + stream_read_uint16(s, lengthCapability); /* lengthCapability (2 bytes) */ + + switch (capabilitySetType) + { + case CB_CAPSTYPE_GENERAL: + cliprdr_process_general_capability(cliprdr, s); + break; + + default: + DEBUG_WARN("unknown cliprdr capability set: %d", capabilitySetType); + break; + } + } +} + +static void cliprdr_send_clip_caps(cliprdrPlugin* cliprdr) +{ + STREAM* s; + uint32 flags; + + s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN); + + DEBUG_CLIPRDR("Sending Capabilities"); + + flags = CB_USE_LONG_FORMAT_NAMES; + + stream_write_uint16(s, 1); /* cCapabilitiesSets */ + stream_write_uint16(s, 0); /* pad1 */ + stream_write_uint16(s, CB_CAPSTYPE_GENERAL); /* capabilitySetType */ + stream_write_uint16(s, CB_CAPSTYPE_GENERAL_LEN); /* lengthCapability */ + stream_write_uint32(s, CB_CAPS_VERSION_2); /* version */ + stream_write_uint32(s, flags); /* generalFlags */ + + cliprdr_packet_send(cliprdr, s); +} + +static void cliprdr_process_monitor_ready(cliprdrPlugin* cliprdr, STREAM* s, uint16 length, uint16 flags) +{ + RDP_EVENT* event; + + if (cliprdr->received_caps) + cliprdr_send_clip_caps(cliprdr); + + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_MONITOR_READY, NULL, NULL); + svc_plugin_send_event((rdpSvcPlugin*) cliprdr, event); +} + +static void cliprdr_process_receive(rdpSvcPlugin* plugin, STREAM* s) +{ + uint16 msgType; + uint16 msgFlags; + uint32 dataLen; + cliprdrPlugin* cliprdr = (cliprdrPlugin*) plugin; + + stream_read_uint16(s, msgType); + stream_read_uint16(s, msgFlags); + stream_read_uint32(s, dataLen); + + DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d", + CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen); + + switch (msgType) + { + case CB_CLIP_CAPS: + cliprdr_process_clip_caps(cliprdr, s, dataLen, msgFlags); + break; + + case CB_MONITOR_READY: + cliprdr_process_monitor_ready(cliprdr, s, dataLen, msgFlags); + break; + + case CB_FORMAT_LIST: + cliprdr_process_format_list(cliprdr, s, dataLen, msgFlags); + break; + + case CB_FORMAT_LIST_RESPONSE: + cliprdr_process_format_list_response(cliprdr, s, dataLen, msgFlags); + break; + + case CB_FORMAT_DATA_REQUEST: + cliprdr_process_format_data_request(cliprdr, s, dataLen, msgFlags); + break; + + case CB_FORMAT_DATA_RESPONSE: + cliprdr_process_format_data_response(cliprdr, s, dataLen, msgFlags); + break; + + default: + DEBUG_WARN("unknown msgType %d", msgType); + break; + } + + stream_free(s); +} + +static void cliprdr_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + cliprdr_process_format_list_event((cliprdrPlugin*) plugin, (RDP_CB_FORMAT_LIST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_REQUEST: + cliprdr_process_format_data_request_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_REQUEST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + cliprdr_process_format_data_response_event((cliprdrPlugin*) plugin, (RDP_CB_DATA_RESPONSE_EVENT*) event); + break; + + default: + DEBUG_WARN("unknown event type %d", event->event_type); + break; + } + + freerdp_event_free(event); +} + +static void cliprdr_process_terminate(rdpSvcPlugin* plugin) +{ + cliprdrPlugin* cliprdr_plugin = (cliprdrPlugin*) plugin; + + if (cliprdr_plugin->uniconv != NULL) + freerdp_uniconv_free(cliprdr_plugin->uniconv); + + xfree(plugin); +} + +DEFINE_SVC_PLUGIN(cliprdr, "cliprdr", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL) diff --git a/channels/cliprdr/cliprdr_main.h b/channels/cliprdr/cliprdr_main.h new file mode 100644 index 0000000..e3059a2 --- /dev/null +++ b/channels/cliprdr/cliprdr_main.h @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Clipboard Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CLIPRDR_MAIN_H +#define __CLIPRDR_MAIN_H + +#include +#include + +struct _CLIPRDR_FORMAT_NAME +{ + uint32 id; + char* name; + int length; +}; +typedef struct _CLIPRDR_FORMAT_NAME CLIPRDR_FORMAT_NAME; + +struct cliprdr_plugin +{ + rdpSvcPlugin plugin; + UNICONV* uniconv; + boolean received_caps; + boolean use_long_format_names; + boolean stream_fileclip_enabled; + boolean fileclip_no_file_paths; + boolean can_lock_clipdata; + CLIPRDR_FORMAT_NAME* format_names; + int num_format_names; +}; +typedef struct cliprdr_plugin cliprdrPlugin; + +STREAM* cliprdr_packet_new(uint16 msgType, uint16 msgFlags, uint32 dataLen); +void cliprdr_packet_send(cliprdrPlugin* cliprdr, STREAM* data_out); + +#ifdef WITH_DEBUG_CLIPRDR +#define DEBUG_CLIPRDR(fmt, ...) DEBUG_CLASS(CLIPRDR, fmt, ## __VA_ARGS__) +#else +#define DEBUG_CLIPRDR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __CLIPRDR_MAIN_H */ diff --git a/channels/drdynvc/CMakeLists.txt b/channels/drdynvc/CMakeLists.txt new file mode 100644 index 0000000..1e3cc13 --- /dev/null +++ b/channels/drdynvc/CMakeLists.txt @@ -0,0 +1,37 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(DRDYNVC_SRCS + drdynvc_main.c + drdynvc_main.h + drdynvc_types.h + dvcman.c + dvcman.h +) + +add_library(drdynvc ${DRDYNVC_SRCS}) +set_target_properties(drdynvc PROPERTIES PREFIX "") + +target_link_libraries(drdynvc freerdp-utils) + +install(TARGETS drdynvc DESTINATION ${FREERDP_PLUGIN_PATH}) + +add_subdirectory(tsmf) +add_subdirectory(audin) + diff --git a/channels/drdynvc/audin/CMakeLists.txt b/channels/drdynvc/audin/CMakeLists.txt new file mode 100644 index 0000000..37fe004 --- /dev/null +++ b/channels/drdynvc/audin/CMakeLists.txt @@ -0,0 +1,41 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(AUDIN_SRCS + audin_main.c + audin_main.h +) + +include_directories(..) + +add_library(audin ${AUDIN_SRCS}) +set_target_properties(audin PROPERTIES PREFIX "") + +target_link_libraries(audin freerdp-utils) + +install(TARGETS audin DESTINATION ${FREERDP_PLUGIN_PATH}) + +if(WITH_ALSA) + add_subdirectory(alsa) +endif() + +if(WITH_PULSEAUDIO) + add_subdirectory(pulse) +endif() + diff --git a/channels/drdynvc/audin/alsa/CMakeLists.txt b/channels/drdynvc/audin/alsa/CMakeLists.txt new file mode 100644 index 0000000..786f9ce --- /dev/null +++ b/channels/drdynvc/audin/alsa/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(AUDIN_ALSA_SRCS + audin_alsa.c +) + +include_directories(..) +include_directories(${ALSA_INCLUDE_DIRS}) + +add_library(audin_alsa ${AUDIN_ALSA_SRCS}) +set_target_properties(audin_alsa PROPERTIES PREFIX "") + +target_link_libraries(audin_alsa freerdp-utils) +target_link_libraries(audin_alsa ${ALSA_LIBRARIES}) + +install(TARGETS audin_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/drdynvc/audin/alsa/audin_alsa.c b/channels/drdynvc/audin/alsa/audin_alsa.c new file mode 100644 index 0000000..540d184 --- /dev/null +++ b/channels/drdynvc/audin/alsa/audin_alsa.c @@ -0,0 +1,366 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Input Redirection Virtual Channel - ALSA implementation + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "audin_main.h" + +typedef struct _AudinALSADevice +{ + IAudinDevice iface; + + char device_name[32]; + uint32 frames_per_packet; + uint32 target_rate; + uint32 actual_rate; + snd_pcm_format_t format; + uint32 target_channels; + uint32 actual_channels; + int bytes_per_channel; + int wformat; + int block_size; + ADPCM adpcm; + + freerdp_thread* thread; + + uint8* buffer; + int buffer_frames; + + AudinReceive receive; + void* user_data; +} AudinALSADevice; + +static boolean audin_alsa_set_params(AudinALSADevice* alsa, snd_pcm_t* capture_handle) +{ + int error; + snd_pcm_hw_params_t* hw_params; + + if ((error = snd_pcm_hw_params_malloc(&hw_params)) < 0) + { + DEBUG_WARN("snd_pcm_hw_params_malloc (%s)", + snd_strerror(error)); + return false; + } + snd_pcm_hw_params_any(capture_handle, hw_params); + snd_pcm_hw_params_set_access(capture_handle, hw_params, + SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_format(capture_handle, hw_params, + alsa->format); + snd_pcm_hw_params_set_rate_near(capture_handle, hw_params, + &alsa->actual_rate, NULL); + snd_pcm_hw_params_set_channels_near(capture_handle, hw_params, + &alsa->actual_channels); + snd_pcm_hw_params(capture_handle, hw_params); + snd_pcm_hw_params_free(hw_params); + snd_pcm_prepare(capture_handle); + + if ((alsa->actual_rate != alsa->target_rate) || + (alsa->actual_channels != alsa->target_channels)) + { + DEBUG_DVC("actual rate %d / channel %d is " + "different from target rate %d / channel %d, resampling required.", + alsa->actual_rate, alsa->actual_channels, + alsa->target_rate, alsa->target_channels); + } + return true; +} + +static boolean audin_alsa_thread_receive(AudinALSADevice* alsa, uint8* src, int size) +{ + int frames; + int cframes; + int ret = 0; + int encoded_size; + uint8* encoded_data; + int rbytes_per_frame; + int tbytes_per_frame; + uint8* resampled_data; + + rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; + tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; + + if ((alsa->target_rate == alsa->actual_rate) && + (alsa->target_channels == alsa->actual_channels)) + { + resampled_data = NULL; + frames = size / rbytes_per_frame; + } + else + { + resampled_data = dsp_resample(src, alsa->bytes_per_channel, + alsa->actual_channels, alsa->actual_rate, size / rbytes_per_frame, + alsa->target_channels, alsa->target_rate, &frames); + DEBUG_DVC("resampled %d frames at %d to %d frames at %d", + size / rbytes_per_frame, alsa->actual_rate, frames, alsa->target_rate); + size = frames * tbytes_per_frame; + src = resampled_data; + } + + while (frames > 0) + { + if (freerdp_thread_is_stopped(alsa->thread)) + break; + + cframes = alsa->frames_per_packet - alsa->buffer_frames; + if (cframes > frames) + cframes = frames; + memcpy(alsa->buffer + alsa->buffer_frames * tbytes_per_frame, + src, cframes * tbytes_per_frame); + alsa->buffer_frames += cframes; + if (alsa->buffer_frames >= alsa->frames_per_packet) + { + if (alsa->wformat == 0x11) + { + encoded_data = dsp_encode_ima_adpcm(&alsa->adpcm, + alsa->buffer, alsa->buffer_frames * tbytes_per_frame, + alsa->target_channels, alsa->block_size, &encoded_size); + DEBUG_DVC("encoded %d to %d", + alsa->buffer_frames * tbytes_per_frame, encoded_size); + } + else + { + encoded_data = alsa->buffer; + encoded_size = alsa->buffer_frames * tbytes_per_frame; + } + + if (freerdp_thread_is_stopped(alsa->thread)) + { + ret = 0; + frames = 0; + } + else + ret = alsa->receive(encoded_data, encoded_size, alsa->user_data); + alsa->buffer_frames = 0; + if (encoded_data != alsa->buffer) + xfree(encoded_data); + if (!ret) + break; + } + src += cframes * tbytes_per_frame; + frames -= cframes; + } + + if (resampled_data) + xfree(resampled_data); + + return ret; +} + +static void* audin_alsa_thread_func(void* arg) +{ + int error; + uint8* buffer; + int rbytes_per_frame; + int tbytes_per_frame; + snd_pcm_t* capture_handle = NULL; + AudinALSADevice* alsa = (AudinALSADevice*) arg; + + DEBUG_DVC("in"); + + rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; + tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel; + alsa->buffer = (uint8*) xzalloc(tbytes_per_frame * alsa->frames_per_packet); + alsa->buffer_frames = 0; + buffer = (uint8*) xzalloc(rbytes_per_frame * alsa->frames_per_packet); + memset(&alsa->adpcm, 0, sizeof(ADPCM)); + do + { + if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0) + { + DEBUG_WARN("snd_pcm_open (%s)", snd_strerror(error)); + break; + } + if (!audin_alsa_set_params(alsa, capture_handle)) + { + break; + } + + while (!freerdp_thread_is_stopped(alsa->thread)) + { + error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet); + if (error == -EPIPE) + { + snd_pcm_recover(capture_handle, error, 0); + continue; + } + else if (error < 0) + { + DEBUG_WARN("snd_pcm_readi (%s)", snd_strerror(error)); + break; + } + if (!audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame)) + break; + } + } while (0); + + xfree(buffer); + xfree(alsa->buffer); + alsa->buffer = NULL; + if (capture_handle) + snd_pcm_close(capture_handle); + + freerdp_thread_quit(alsa->thread); + + DEBUG_DVC("out"); + + return NULL; +} + +static void audin_alsa_free(IAudinDevice* device) +{ + AudinALSADevice* alsa = (AudinALSADevice*) device; + + freerdp_thread_free(alsa->thread); + xfree(alsa); +} + +static boolean audin_alsa_format_supported(IAudinDevice* device, audinFormat* format) +{ + switch (format->wFormatTag) + { + case 1: /* PCM */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= 48000) && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + + case 0x11: /* IMA ADPCM */ + if ((format->nSamplesPerSec <= 48000) && + (format->wBitsPerSample == 4) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + } + return false; +} + +static void audin_alsa_set_format(IAudinDevice* device, audinFormat* format, uint32 FramesPerPacket) +{ + int bs; + AudinALSADevice* alsa = (AudinALSADevice*) device; + + alsa->target_rate = format->nSamplesPerSec; + alsa->actual_rate = format->nSamplesPerSec; + alsa->target_channels = format->nChannels; + alsa->actual_channels = format->nChannels; + switch (format->wFormatTag) + { + case 1: /* PCM */ + switch (format->wBitsPerSample) + { + case 8: + alsa->format = SND_PCM_FORMAT_S8; + alsa->bytes_per_channel = 1; + break; + case 16: + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->bytes_per_channel = 2; + break; + } + break; + + case 0x11: /* IMA ADPCM */ + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->bytes_per_channel = 2; + bs = (format->nBlockAlign - 4 * format->nChannels) * 4; + alsa->frames_per_packet = (alsa->frames_per_packet * format->nChannels * 2 / + bs + 1) * bs / (format->nChannels * 2); + DEBUG_DVC("aligned FramesPerPacket=%d", + alsa->frames_per_packet); + break; + } + alsa->wformat = format->wFormatTag; + alsa->block_size = format->nBlockAlign; +} + +static void audin_alsa_open(IAudinDevice* device, AudinReceive receive, void* user_data) +{ + AudinALSADevice* alsa = (AudinALSADevice*) device; + + DEBUG_DVC(""); + + alsa->receive = receive; + alsa->user_data = user_data; + + freerdp_thread_start(alsa->thread, audin_alsa_thread_func, alsa); +} + +static void audin_alsa_close(IAudinDevice* device) +{ + AudinALSADevice* alsa = (AudinALSADevice*) device; + + DEBUG_DVC(""); + + freerdp_thread_stop(alsa->thread); + + alsa->receive = NULL; + alsa->user_data = NULL; +} + +int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +{ + AudinALSADevice* alsa; + RDP_PLUGIN_DATA* data; + + alsa = xnew(AudinALSADevice); + + alsa->iface.Open = audin_alsa_open; + alsa->iface.FormatSupported = audin_alsa_format_supported; + alsa->iface.SetFormat = audin_alsa_set_format; + alsa->iface.Close = audin_alsa_close; + alsa->iface.Free = audin_alsa_free; + + data = pEntryPoints->plugin_data; + if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 && + data->data[1] && strcmp(data->data[1], "alsa") == 0) + { + if (data[2].size) + strncpy(alsa->device_name, (char*)data->data[2], sizeof(alsa->device_name)); + } + if (alsa->device_name[0] == '\0') + { + strcpy(alsa->device_name, "default"); + } + + alsa->frames_per_packet = 128; + alsa->target_rate = 22050; + alsa->actual_rate = 22050; + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->target_channels = 2; + alsa->actual_channels = 2; + alsa->bytes_per_channel = 2; + alsa->thread = freerdp_thread_new(); + + pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) alsa); + + return 0; +} + diff --git a/channels/drdynvc/audin/audin_main.c b/channels/drdynvc/audin/audin_main.c new file mode 100644 index 0000000..095c539 --- /dev/null +++ b/channels/drdynvc/audin/audin_main.c @@ -0,0 +1,544 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Input Redirection Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "audin_main.h" + +#define MSG_SNDIN_VERSION 0x01 +#define MSG_SNDIN_FORMATS 0x02 +#define MSG_SNDIN_OPEN 0x03 +#define MSG_SNDIN_OPEN_REPLY 0x04 +#define MSG_SNDIN_DATA_INCOMING 0x05 +#define MSG_SNDIN_DATA 0x06 +#define MSG_SNDIN_FORMATCHANGE 0x07 + +typedef struct _AUDIN_LISTENER_CALLBACK AUDIN_LISTENER_CALLBACK; +struct _AUDIN_LISTENER_CALLBACK +{ + IWTSListenerCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; +}; + +typedef struct _AUDIN_CHANNEL_CALLBACK AUDIN_CHANNEL_CALLBACK; +struct _AUDIN_CHANNEL_CALLBACK +{ + IWTSVirtualChannelCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + IWTSVirtualChannel* channel; + + /** + * The supported format list sent back to the server, which needs to + * be stored as reference when the server sends the format index in + * Open PDU and Format Change PDU + */ + audinFormat* formats; + int formats_count; +}; + +typedef struct _AUDIN_PLUGIN AUDIN_PLUGIN; +struct _AUDIN_PLUGIN +{ + IWTSPlugin iface; + + AUDIN_LISTENER_CALLBACK* listener_callback; + + /* Parsed plugin data */ + uint16 fixed_format; + uint16 fixed_channel; + uint32 fixed_rate; + + /* Device interface */ + IAudinDevice* device; +}; + +static int audin_process_version(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s) +{ + int error; + STREAM* out; + uint32 Version; + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + + stream_read_uint32(s, Version); + + DEBUG_DVC("Version=%d", Version); + + out = stream_new(5); + stream_write_uint8(out, MSG_SNDIN_VERSION); + stream_write_uint32(out, Version); + error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); + stream_free(out); + + return error; +} + +static int audin_send_incoming_data_pdu(IWTSVirtualChannelCallback* pChannelCallback) +{ + uint8 out_data[1]; + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + + out_data[0] = MSG_SNDIN_DATA_INCOMING; + return callback->channel->Write(callback->channel, 1, out_data, NULL); +} + +static int audin_process_formats(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s) +{ + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin; + uint32 i; + uint8* fm; + int error; + STREAM* out; + uint32 NumFormats; + audinFormat format; + uint32 cbSizeFormatsPacket; + + stream_read_uint32(s, NumFormats); + DEBUG_DVC("NumFormats %d", NumFormats); + if ((NumFormats < 1) || (NumFormats > 1000)) + { + DEBUG_WARN("bad NumFormats %d", NumFormats); + return 1; + } + stream_seek_uint32(s); /* cbSizeFormatsPacket */ + + callback->formats = (audinFormat*) xzalloc(NumFormats * sizeof(audinFormat)); + + out = stream_new(9); + stream_seek(out, 9); + + /* SoundFormats (variable) */ + for (i = 0; i < NumFormats; i++) + { + stream_get_mark(s, fm); + stream_read_uint16(s, format.wFormatTag); + stream_read_uint16(s, format.nChannels); + stream_read_uint32(s, format.nSamplesPerSec); + stream_seek_uint32(s); /* nAvgBytesPerSec */ + stream_read_uint16(s, format.nBlockAlign); + stream_read_uint16(s, format.wBitsPerSample); + stream_read_uint16(s, format.cbSize); + format.data = stream_get_tail(s); + stream_seek(s, format.cbSize); + + DEBUG_DVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d " + "nBlockAlign=%d wBitsPerSample=%d cbSize=%d", + format.wFormatTag, format.nChannels, format.nSamplesPerSec, + format.nBlockAlign, format.wBitsPerSample, format.cbSize); + + if (audin->fixed_format > 0 && audin->fixed_format != format.wFormatTag) + continue; + if (audin->fixed_channel > 0 && audin->fixed_channel != format.nChannels) + continue; + if (audin->fixed_rate > 0 && audin->fixed_rate != format.nSamplesPerSec) + continue; + if (audin->device && audin->device->FormatSupported(audin->device, &format)) + { + DEBUG_DVC("format ok"); + + /* Store the agreed format in the corresponding index */ + callback->formats[callback->formats_count++] = format; + /* Put the format to output buffer */ + stream_check_size(out, 18 + format.cbSize); + stream_write(out, fm, 18 + format.cbSize); + } + } + + audin_send_incoming_data_pdu(pChannelCallback); + + cbSizeFormatsPacket = stream_get_pos(out); + stream_set_pos(out, 0); + + stream_write_uint8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */ + stream_write_uint32(out, callback->formats_count); /* NumFormats (4 bytes) */ + stream_write_uint32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */ + + error = callback->channel->Write(callback->channel, cbSizeFormatsPacket, stream_get_head(out), NULL); + stream_free(out); + + return error; +} + +static int audin_send_format_change_pdu(IWTSVirtualChannelCallback* pChannelCallback, uint32 NewFormat) +{ + int error; + STREAM* out; + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + + out = stream_new(5); + stream_write_uint8(out, MSG_SNDIN_FORMATCHANGE); + stream_write_uint32(out, NewFormat); + error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL); + stream_free(out); + + return error; +} + +static int audin_send_open_reply_pdu(IWTSVirtualChannelCallback* pChannelCallback, uint32 Result) +{ + int error; + STREAM* out; + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + + out = stream_new(5); + stream_write_uint8(out, MSG_SNDIN_OPEN_REPLY); + stream_write_uint32(out, Result); + error = callback->channel->Write(callback->channel, 5, stream_get_head(out), NULL); + stream_free(out); + + return error; +} + +static boolean audin_receive_wave_data(uint8* data, int size, void* user_data) +{ + int error; + STREAM* out; + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) user_data; + + error = audin_send_incoming_data_pdu((IWTSVirtualChannelCallback*) callback); + + if (error != 0) + return false; + + out = stream_new(size + 1); + stream_write_uint8(out, MSG_SNDIN_DATA); + stream_write(out, data, size); + error = callback->channel->Write(callback->channel, stream_get_length(out), stream_get_head(out), NULL); + stream_free(out); + + return (error == 0 ? true : false); +} + +static int audin_process_open(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s) +{ + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin; + audinFormat* format; + uint32 initialFormat; + uint32 FramesPerPacket; + + stream_read_uint32(s, FramesPerPacket); + stream_read_uint32(s, initialFormat); + + DEBUG_DVC("FramesPerPacket=%d initialFormat=%d", + FramesPerPacket, initialFormat); + + if (initialFormat >= callback->formats_count) + { + DEBUG_WARN("invalid format index %d (total %d)", + initialFormat, callback->formats_count); + return 1; + } + + format = &callback->formats[initialFormat]; + if (audin->device) + { + IFCALL(audin->device->SetFormat, audin->device, format, FramesPerPacket); + IFCALL(audin->device->Open, audin->device, audin_receive_wave_data, callback); + } + + audin_send_format_change_pdu(pChannelCallback, initialFormat); + audin_send_open_reply_pdu(pChannelCallback, 0); + + return 0; +} + +static int audin_process_format_change(IWTSVirtualChannelCallback* pChannelCallback, STREAM* s) +{ + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + AUDIN_PLUGIN * audin = (AUDIN_PLUGIN*) callback->plugin; + uint32 NewFormat; + audinFormat* format; + + stream_read_uint32(s, NewFormat); + + DEBUG_DVC("NewFormat=%d", NewFormat); + + if (NewFormat >= callback->formats_count) + { + DEBUG_WARN("invalid format index %d (total %d)", + NewFormat, callback->formats_count); + return 1; + } + + format = &callback->formats[NewFormat]; + + if (audin->device) + { + IFCALL(audin->device->Close, audin->device); + IFCALL(audin->device->SetFormat, audin->device, format, 0); + IFCALL(audin->device->Open, audin->device, audin_receive_wave_data, callback); + } + + audin_send_format_change_pdu(pChannelCallback, NewFormat); + + return 0; +} + +static int audin_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, uint32 cbSize, uint8* pBuffer) +{ + int error; + STREAM* s; + uint8 MessageId; + + s = stream_new(0); + stream_attach(s, pBuffer, cbSize); + + stream_read_uint8(s, MessageId); + + DEBUG_DVC("MessageId=0x%x", MessageId); + + switch (MessageId) + { + case MSG_SNDIN_VERSION: + error = audin_process_version(pChannelCallback, s); + break; + + case MSG_SNDIN_FORMATS: + error = audin_process_formats(pChannelCallback, s); + break; + + case MSG_SNDIN_OPEN: + error = audin_process_open(pChannelCallback, s); + break; + + case MSG_SNDIN_FORMATCHANGE: + error = audin_process_format_change(pChannelCallback, s); + break; + + default: + DEBUG_WARN("unknown MessageId=0x%x", MessageId); + error = 1; + break; + } + + stream_detach(s); + stream_free(s); + + return error; +} + +static int audin_on_close(IWTSVirtualChannelCallback* pChannelCallback) +{ + AUDIN_CHANNEL_CALLBACK* callback = (AUDIN_CHANNEL_CALLBACK*) pChannelCallback; + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) callback->plugin; + + DEBUG_DVC(""); + + if (audin->device) + IFCALL(audin->device->Close, audin->device); + + xfree(callback->formats); + xfree(callback); + + return 0; +} + +static int audin_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, + IWTSVirtualChannel* pChannel, uint8* Data, int* pbAccept, + IWTSVirtualChannelCallback** ppCallback) +{ + AUDIN_CHANNEL_CALLBACK* callback; + AUDIN_LISTENER_CALLBACK* listener_callback = (AUDIN_LISTENER_CALLBACK*) pListenerCallback; + + DEBUG_DVC(""); + + callback = xnew(AUDIN_CHANNEL_CALLBACK); + + callback->iface.OnDataReceived = audin_on_data_received; + callback->iface.OnClose = audin_on_close; + callback->plugin = listener_callback->plugin; + callback->channel_mgr = listener_callback->channel_mgr; + callback->channel = pChannel; + + *ppCallback = (IWTSVirtualChannelCallback*) callback; + + return 0; +} + +static int audin_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) +{ + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; + + DEBUG_DVC(""); + + audin->listener_callback = xnew(AUDIN_LISTENER_CALLBACK); + + audin->listener_callback->iface.OnNewChannelConnection = audin_on_new_channel_connection; + audin->listener_callback->plugin = pPlugin; + audin->listener_callback->channel_mgr = pChannelMgr; + + return pChannelMgr->CreateListener(pChannelMgr, "AUDIO_INPUT", 0, + (IWTSListenerCallback*) audin->listener_callback, NULL); +} + +static int audin_plugin_terminated(IWTSPlugin* pPlugin) +{ + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; + + DEBUG_DVC(""); + + if (audin->device) + { + IFCALL(audin->device->Close, audin->device); + IFCALL(audin->device->Free, audin->device); + audin->device = NULL; + } + + xfree(audin->listener_callback); + xfree(audin); + + return 0; +} + +static void audin_register_device_plugin(IWTSPlugin* pPlugin, IAudinDevice* device) +{ + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; + + if (audin->device) + { + DEBUG_WARN("existing device, abort."); + return; + } + + DEBUG_DVC("device registered."); + + audin->device = device; +} + +static boolean audin_load_device_plugin(IWTSPlugin* pPlugin, const char* name, RDP_PLUGIN_DATA* data) +{ + char* fullname; + PFREERDP_AUDIN_DEVICE_ENTRY entry; + FREERDP_AUDIN_DEVICE_ENTRY_POINTS entryPoints; + + if (strrchr(name, '.') != NULL) + { + entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(name, AUDIN_DEVICE_EXPORT_FUNC_NAME); + } + else + { + fullname = xzalloc(strlen(name) + 8); + strcpy(fullname, "audin_"); + strcat(fullname, name); + entry = (PFREERDP_AUDIN_DEVICE_ENTRY) freerdp_load_plugin(fullname, AUDIN_DEVICE_EXPORT_FUNC_NAME); + xfree(fullname); + } + + if (entry == NULL) + return false; + + entryPoints.plugin = pPlugin; + entryPoints.pRegisterAudinDevice = audin_register_device_plugin; + entryPoints.plugin_data = data; + + if (entry(&entryPoints) != 0) + { + DEBUG_WARN("%s entry returns error.", name); + return false; + } + + return true; +} + +static boolean audin_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) +{ + boolean ret; + AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*) pPlugin; + RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } }; + + if (data->data[0] && (strcmp((char*)data->data[0], "audin") == 0 || strstr((char*) data->data[0], "/audin.") != NULL)) + { + if (data->data[1] && strcmp((char*)data->data[1], "format") == 0) + { + audin->fixed_format = atoi(data->data[2]); + return true; + } + else if (data->data[1] && strcmp((char*)data->data[1], "rate") == 0) + { + audin->fixed_rate = atoi(data->data[2]); + return true; + } + else if (data->data[1] && strcmp((char*)data->data[1], "channel") == 0) + { + audin->fixed_channel = atoi(data->data[2]); + return true; + } + else if (data->data[1] && ((char*)data->data[1])[0]) + { + return audin_load_device_plugin(pPlugin, (char*) data->data[1], data); + } + else + { + default_data[0].size = sizeof(RDP_PLUGIN_DATA); + default_data[0].data[0] = "audin"; + default_data[0].data[1] = "pulse"; + default_data[0].data[2] = ""; + + ret = audin_load_device_plugin(pPlugin, "pulse", default_data); + + if (!ret) + { + default_data[0].size = sizeof(RDP_PLUGIN_DATA); + default_data[0].data[0] = "audin"; + default_data[0].data[1] = "alsa"; + default_data[0].data[2] = "default"; + ret = audin_load_device_plugin(pPlugin, "alsa", default_data); + } + + return ret; + } + } + + return true; +} + +int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +{ + int error = 0; + AUDIN_PLUGIN* audin; + + audin = (AUDIN_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "audin"); + + if (audin == NULL) + { + audin = xnew(AUDIN_PLUGIN); + + audin->iface.Initialize = audin_plugin_initialize; + audin->iface.Connected = NULL; + audin->iface.Disconnected = NULL; + audin->iface.Terminated = audin_plugin_terminated; + error = pEntryPoints->RegisterPlugin(pEntryPoints, "audin", (IWTSPlugin*) audin); + } + + if (error == 0) + audin_process_plugin_data((IWTSPlugin*) audin, pEntryPoints->GetPluginData(pEntryPoints)); + + return error; +} + diff --git a/channels/drdynvc/audin/audin_main.h b/channels/drdynvc/audin/audin_main.h new file mode 100644 index 0000000..6ac45a2 --- /dev/null +++ b/channels/drdynvc/audin/audin_main.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Input Redirection Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AUDIN_MAIN_H +#define __AUDIN_MAIN_H + +#include "drdynvc_types.h" + +typedef boolean (*AudinReceive) (uint8* data, int size, void* user_data); + +typedef struct audin_format audinFormat; +struct audin_format +{ + uint16 wFormatTag; + uint16 nChannels; + uint32 nSamplesPerSec; + uint16 nBlockAlign; + uint16 wBitsPerSample; + uint16 cbSize; + uint8* data; +}; + +typedef struct _IAudinDevice IAudinDevice; +struct _IAudinDevice +{ + void (*Open) (IAudinDevice* devplugin, AudinReceive receive, void* user_data); + boolean (*FormatSupported) (IAudinDevice* devplugin, audinFormat* format); + void (*SetFormat) (IAudinDevice* devplugin, audinFormat* format, uint32 FramesPerPacket); + void (*Close) (IAudinDevice* devplugin); + void (*Free) (IAudinDevice* devplugin); +}; + +#define AUDIN_DEVICE_EXPORT_FUNC_NAME "FreeRDPAudinDeviceEntry" + +typedef void (*PREGISTERAUDINDEVICE)(IWTSPlugin* plugin, IAudinDevice* device); + +struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS +{ + IWTSPlugin* plugin; + PREGISTERAUDINDEVICE pRegisterAudinDevice; + RDP_PLUGIN_DATA* plugin_data; +}; +typedef struct _FREERDP_AUDIN_DEVICE_ENTRY_POINTS FREERDP_AUDIN_DEVICE_ENTRY_POINTS; +typedef FREERDP_AUDIN_DEVICE_ENTRY_POINTS* PFREERDP_AUDIN_DEVICE_ENTRY_POINTS; + +typedef int (*PFREERDP_AUDIN_DEVICE_ENTRY)(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints); + +#endif /* __AUDIN_MAIN_H */ + diff --git a/channels/drdynvc/audin/pulse/CMakeLists.txt b/channels/drdynvc/audin/pulse/CMakeLists.txt new file mode 100644 index 0000000..10d6afe --- /dev/null +++ b/channels/drdynvc/audin/pulse/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(AUDIN_PULSE_SRCS + audin_pulse.c +) + +include_directories(..) +include_directories(${PULSE_INCLUDE_DIRS}) + +add_library(audin_pulse ${AUDIN_PULSE_SRCS}) +set_target_properties(audin_pulse PROPERTIES PREFIX "") + +target_link_libraries(audin_pulse freerdp-utils) +target_link_libraries(audin_pulse ${PULSE_LIBRARIES}) + +install(TARGETS audin_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/drdynvc/audin/pulse/audin_pulse.c b/channels/drdynvc/audin/pulse/audin_pulse.c new file mode 100644 index 0000000..61e1427 --- /dev/null +++ b/channels/drdynvc/audin/pulse/audin_pulse.c @@ -0,0 +1,471 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Input Redirection Virtual Channel - PulseAudio implementation + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "audin_main.h" + +typedef struct _AudinPulseDevice +{ + IAudinDevice iface; + + char device_name[32]; + uint32 frames_per_packet; + pa_threaded_mainloop* mainloop; + pa_context* context; + pa_sample_spec sample_spec; + pa_stream* stream; + int format; + int block_size; + ADPCM adpcm; + + int bytes_per_frame; + uint8* buffer; + int buffer_frames; + + AudinReceive receive; + void* user_data; +} AudinPulseDevice; + +static void audin_pulse_context_state_callback(pa_context* context, void* userdata) +{ + pa_context_state_t state; + AudinPulseDevice* pulse = (AudinPulseDevice*) userdata; + + state = pa_context_get_state(context); + switch (state) + { + case PA_CONTEXT_READY: + DEBUG_DVC("PA_CONTEXT_READY"); + pa_threaded_mainloop_signal (pulse->mainloop, 0); + break; + + case PA_CONTEXT_FAILED: + case PA_CONTEXT_TERMINATED: + DEBUG_DVC("state %d", (int)state); + pa_threaded_mainloop_signal (pulse->mainloop, 0); + break; + + default: + DEBUG_DVC("state %d", (int)state); + break; + } +} + +static boolean audin_pulse_connect(IAudinDevice* device) +{ + pa_context_state_t state; + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + if (!pulse->context) + return false; + + if (pa_context_connect(pulse->context, NULL, 0, NULL)) + { + DEBUG_WARN("pa_context_connect failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + pa_threaded_mainloop_lock(pulse->mainloop); + if (pa_threaded_mainloop_start(pulse->mainloop) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + for (;;) + { + state = pa_context_get_state(pulse->context); + if (state == PA_CONTEXT_READY) + break; + if (!PA_CONTEXT_IS_GOOD(state)) + { + DEBUG_WARN("bad context state (%d)", + pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_CONTEXT_READY) + { + DEBUG_DVC("connected"); + return true; + } + else + { + pa_context_disconnect(pulse->context); + return false; + } +} + +static void audin_pulse_free(IAudinDevice* device) +{ + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + DEBUG_DVC(""); + + if (!pulse) + return; + if (pulse->mainloop) + { + pa_threaded_mainloop_stop(pulse->mainloop); + } + if (pulse->context) + { + pa_context_disconnect(pulse->context); + pa_context_unref(pulse->context); + pulse->context = NULL; + } + if (pulse->mainloop) + { + pa_threaded_mainloop_free(pulse->mainloop); + pulse->mainloop = NULL; + } + xfree(pulse); +} + +static boolean audin_pulse_format_supported(IAudinDevice* device, audinFormat* format) +{ + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + if (!pulse->context) + return 0; + + switch (format->wFormatTag) + { + case 1: /* PCM */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX)) + { + return true; + } + break; + + case 6: /* A-LAW */ + case 7: /* U-LAW */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 8) && + (format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX)) + { + return true; + } + break; + + case 0x11: /* IMA ADPCM */ + if ((format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 4) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + } + return false; +} + +static void audin_pulse_set_format(IAudinDevice* device, audinFormat* format, uint32 FramesPerPacket) +{ + int bs; + pa_sample_spec sample_spec = { 0 }; + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + if (!pulse->context) + return; + + if (FramesPerPacket > 0) + { + pulse->frames_per_packet = FramesPerPacket; + } + + sample_spec.rate = format->nSamplesPerSec; + sample_spec.channels = format->nChannels; + switch (format->wFormatTag) + { + case 1: /* PCM */ + switch (format->wBitsPerSample) + { + case 8: + sample_spec.format = PA_SAMPLE_U8; + break; + case 16: + sample_spec.format = PA_SAMPLE_S16LE; + break; + } + break; + + case 6: /* A-LAW */ + sample_spec.format = PA_SAMPLE_ALAW; + break; + + case 7: /* U-LAW */ + sample_spec.format = PA_SAMPLE_ULAW; + break; + + case 0x11: /* IMA ADPCM */ + sample_spec.format = PA_SAMPLE_S16LE; + bs = (format->nBlockAlign - 4 * format->nChannels) * 4; + pulse->frames_per_packet = (pulse->frames_per_packet * format->nChannels * 2 / + bs + 1) * bs / (format->nChannels * 2); + DEBUG_DVC("aligned FramesPerPacket=%d", + pulse->frames_per_packet); + break; + } + + pulse->sample_spec = sample_spec; + pulse->format = format->wFormatTag; + pulse->block_size = format->nBlockAlign; +} + +static void audin_pulse_stream_state_callback(pa_stream* stream, void* userdata) +{ + pa_stream_state_t state; + AudinPulseDevice* pulse = (AudinPulseDevice*) userdata; + + state = pa_stream_get_state(stream); + switch (state) + { + case PA_STREAM_READY: + DEBUG_DVC("PA_STREAM_READY"); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + case PA_STREAM_FAILED: + case PA_STREAM_TERMINATED: + DEBUG_DVC("state %d", (int)state); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + default: + DEBUG_DVC("state %d", (int)state); + break; + } +} + +static void audin_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata) +{ + int frames; + int cframes; + boolean ret; + const void* data; + const uint8* src; + int encoded_size; + uint8* encoded_data; + AudinPulseDevice* pulse = (AudinPulseDevice*) userdata; + + pa_stream_peek(stream, &data, &length); + frames = length / pulse->bytes_per_frame; + + DEBUG_DVC("length %d frames %d", (int) length, frames); + + src = (const uint8*) data; + while (frames > 0) + { + cframes = pulse->frames_per_packet - pulse->buffer_frames; + if (cframes > frames) + cframes = frames; + memcpy(pulse->buffer + pulse->buffer_frames * pulse->bytes_per_frame, + src, cframes * pulse->bytes_per_frame); + pulse->buffer_frames += cframes; + if (pulse->buffer_frames >= pulse->frames_per_packet) + { + if (pulse->format == 0x11) + { + encoded_data = dsp_encode_ima_adpcm(&pulse->adpcm, + pulse->buffer, pulse->buffer_frames * pulse->bytes_per_frame, + pulse->sample_spec.channels, pulse->block_size, &encoded_size); + DEBUG_DVC("encoded %d to %d", + pulse->buffer_frames * pulse->bytes_per_frame, encoded_size); + } + else + { + encoded_data = pulse->buffer; + encoded_size = pulse->buffer_frames * pulse->bytes_per_frame; + } + + ret = pulse->receive(encoded_data, encoded_size, pulse->user_data); + pulse->buffer_frames = 0; + if (encoded_data != pulse->buffer) + xfree(encoded_data); + if (!ret) + break; + } + src += cframes * pulse->bytes_per_frame; + frames -= cframes; + } + + pa_stream_drop(stream); +} + + +static void audin_pulse_close(IAudinDevice* device) +{ + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + if (!pulse->context || !pulse->stream) + return; + + DEBUG_DVC(""); + + pa_threaded_mainloop_lock(pulse->mainloop); + pa_stream_disconnect(pulse->stream); + pa_stream_unref(pulse->stream); + pulse->stream = NULL; + pa_threaded_mainloop_unlock(pulse->mainloop); + + pulse->receive = NULL; + pulse->user_data = NULL; + if (pulse->buffer) + { + xfree(pulse->buffer); + pulse->buffer = NULL; + pulse->buffer_frames = 0; + } +} + +static void audin_pulse_open(IAudinDevice* device, AudinReceive receive, void* user_data) +{ + pa_stream_state_t state; + pa_buffer_attr buffer_attr = { 0 }; + AudinPulseDevice* pulse = (AudinPulseDevice*) device; + + if (!pulse->context) + return; + if (!pulse->sample_spec.rate || pulse->stream) + return; + + DEBUG_DVC(""); + + pulse->receive = receive; + pulse->user_data = user_data; + + pa_threaded_mainloop_lock(pulse->mainloop); + pulse->stream = pa_stream_new(pulse->context, "freerdp_audin", + &pulse->sample_spec, NULL); + if (!pulse->stream) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_DVC("pa_stream_new failed (%d)", + pa_context_errno(pulse->context)); + return; + } + pulse->bytes_per_frame = pa_frame_size(&pulse->sample_spec); + pa_stream_set_state_callback(pulse->stream, + audin_pulse_stream_state_callback, pulse); + pa_stream_set_read_callback(pulse->stream, + audin_pulse_stream_request_callback, pulse); + buffer_attr.maxlength = (uint32_t) -1; + buffer_attr.tlength = (uint32_t) -1; + buffer_attr.prebuf = (uint32_t) -1; + buffer_attr.minreq = (uint32_t) -1; + /* 500ms latency */ + buffer_attr.fragsize = pa_usec_to_bytes(500000, &pulse->sample_spec); + if (pa_stream_connect_record(pulse->stream, + pulse->device_name[0] ? pulse->device_name : NULL, + &buffer_attr, PA_STREAM_ADJUST_LATENCY) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_stream_connect_playback failed (%d)", + pa_context_errno(pulse->context)); + return; + } + + for (;;) + { + state = pa_stream_get_state(pulse->stream); + if (state == PA_STREAM_READY) + break; + if (!PA_STREAM_IS_GOOD(state)) + { + DEBUG_WARN("bad stream state (%d)", + pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_STREAM_READY) + { + memset(&pulse->adpcm, 0, sizeof(ADPCM)); + pulse->buffer = xzalloc(pulse->bytes_per_frame * pulse->frames_per_packet); + pulse->buffer_frames = 0; + DEBUG_DVC("connected"); + } + else + { + audin_pulse_close(device); + } +} + +int FreeRDPAudinDeviceEntry(PFREERDP_AUDIN_DEVICE_ENTRY_POINTS pEntryPoints) +{ + AudinPulseDevice* pulse; + RDP_PLUGIN_DATA * data; + + pulse = xnew(AudinPulseDevice); + + pulse->iface.Open = audin_pulse_open; + pulse->iface.FormatSupported = audin_pulse_format_supported; + pulse->iface.SetFormat = audin_pulse_set_format; + pulse->iface.Close = audin_pulse_close; + pulse->iface.Free = audin_pulse_free; + + data = pEntryPoints->plugin_data; + if (data && data->data[0] && strcmp(data->data[0], "audin") == 0 && + data->data[1] && strcmp(data->data[1], "pulse") == 0) + { + strncpy(pulse->device_name, (char*)data->data[2], sizeof(pulse->device_name)); + } + + pulse->mainloop = pa_threaded_mainloop_new(); + if (!pulse->mainloop) + { + DEBUG_WARN("pa_threaded_mainloop_new failed"); + audin_pulse_free((IAudinDevice*) pulse); + return 1; + } + pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); + if (!pulse->context) + { + DEBUG_WARN("pa_context_new failed"); + audin_pulse_free((IAudinDevice*) pulse); + return 1; + } + pa_context_set_state_callback(pulse->context, audin_pulse_context_state_callback, pulse); + if (!audin_pulse_connect((IAudinDevice*) pulse)) + { + audin_pulse_free((IAudinDevice*) pulse); + return 1; + } + + pEntryPoints->pRegisterAudinDevice(pEntryPoints->plugin, (IAudinDevice*) pulse); + + return 0; +} + diff --git a/channels/drdynvc/drdynvc_main.c b/channels/drdynvc/drdynvc_main.c new file mode 100644 index 0000000..27ad531 --- /dev/null +++ b/channels/drdynvc/drdynvc_main.c @@ -0,0 +1,346 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvcman.h" +#include "drdynvc_types.h" +#include "drdynvc_main.h" + +#define CREATE_REQUEST_PDU 0x01 +#define DATA_FIRST_PDU 0x02 +#define DATA_PDU 0x03 +#define CLOSE_REQUEST_PDU 0x04 +#define CAPABILITY_REQUEST_PDU 0x05 + +struct drdynvc_plugin +{ + rdpSvcPlugin plugin; + + int version; + int PriorityCharge0; + int PriorityCharge1; + int PriorityCharge2; + int PriorityCharge3; + + IWTSVirtualChannelManager* channel_mgr; +}; + +static int drdynvc_write_variable_uint(STREAM* stream, uint32 val) +{ + int cb; + + if (val <= 0xFF) + { + cb = 0; + stream_write_uint8(stream, val); + } + else if (val <= 0xFFFF) + { + cb = 1; + stream_write_uint16(stream, val); + } + else + { + cb = 3; + stream_write_uint32(stream, val); + } + return cb; +} + +int drdynvc_write_data(drdynvcPlugin* drdynvc, uint32 ChannelId, uint8* data, uint32 data_size) +{ + STREAM* data_out; + uint32 pos = 0; + uint32 cbChId; + uint32 cbLen; + uint32 chunk_len; + int error; + + DEBUG_DVC("ChannelId=%d size=%d", ChannelId, data_size); + + data_out = stream_new(CHANNEL_CHUNK_LENGTH); + stream_set_pos(data_out, 1); + cbChId = drdynvc_write_variable_uint(data_out, ChannelId); + + if (data_size <= CHANNEL_CHUNK_LENGTH - pos) + { + pos = stream_get_pos(data_out); + stream_set_pos(data_out, 0); + stream_write_uint8(data_out, 0x30 | cbChId); + stream_set_pos(data_out, pos); + stream_write(data_out, data, data_size); + error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + } + else + { + /* Fragment the data */ + cbLen = drdynvc_write_variable_uint(data_out, data_size); + pos = stream_get_pos(data_out); + stream_set_pos(data_out, 0); + stream_write_uint8(data_out, 0x20 | cbChId | (cbLen << 2)); + stream_set_pos(data_out, pos); + chunk_len = CHANNEL_CHUNK_LENGTH - pos; + stream_write(data_out, data, chunk_len); + data += chunk_len; + data_size -= chunk_len; + error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + + while (error == CHANNEL_RC_OK && data_size > 0) + { + data_out = stream_new(CHANNEL_CHUNK_LENGTH); + stream_set_pos(data_out, 1); + cbChId = drdynvc_write_variable_uint(data_out, ChannelId); + + pos = stream_get_pos(data_out); + stream_set_pos(data_out, 0); + stream_write_uint8(data_out, 0x30 | cbChId); + stream_set_pos(data_out, pos); + + chunk_len = data_size; + if (chunk_len > CHANNEL_CHUNK_LENGTH - pos) + chunk_len = CHANNEL_CHUNK_LENGTH - pos; + stream_write(data_out, data, chunk_len); + data += chunk_len; + data_size -= chunk_len; + error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + } + } + if (error != CHANNEL_RC_OK) + { + DEBUG_WARN("VirtualChannelWrite failed %d", error); + return 1; + } + return 0; +} + +int drdynvc_push_event(drdynvcPlugin* drdynvc, RDP_EVENT* event) +{ + int error; + + error = svc_plugin_send_event((rdpSvcPlugin*)drdynvc, event); + if (error != CHANNEL_RC_OK) + { + DEBUG_WARN("pVirtualChannelEventPush failed %d", error); + return 1; + } + return 0; +} + +static int drdynvc_process_capability_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) +{ + STREAM* data_out; + int error; + + DEBUG_DVC("Sp=%d cbChId=%d", Sp, cbChId); + stream_seek(s, 1); /* pad */ + stream_read_uint16(s, drdynvc->version); + if (drdynvc->version == 2) + { + stream_read_uint16(s, drdynvc->PriorityCharge0); + stream_read_uint16(s, drdynvc->PriorityCharge1); + stream_read_uint16(s, drdynvc->PriorityCharge2); + stream_read_uint16(s, drdynvc->PriorityCharge3); + } + data_out = stream_new(4); + stream_write_uint16(data_out, 0x0050); /* Cmd+Sp+cbChId+Pad. Note: MSTSC sends 0x005c */ + stream_write_uint16(data_out, drdynvc->version); + error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + if (error != CHANNEL_RC_OK) + { + DEBUG_WARN("VirtualChannelWrite failed %d", error); + return 1; + } + return 0; +} + +static uint32 drdynvc_read_variable_uint(STREAM* stream, int cbLen) +{ + uint32 val; + + switch (cbLen) + { + case 0: + stream_read_uint8(stream, val); + break; + case 1: + stream_read_uint16(stream, val); + break; + default: + stream_read_uint32(stream, val); + break; + } + return val; +} + +static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) +{ + STREAM* data_out; + int pos; + int error; + uint32 ChannelId; + + ChannelId = drdynvc_read_variable_uint(s, cbChId); + pos = stream_get_pos(s); + DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s)); + + error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*)stream_get_tail(s)); + + data_out = stream_new(pos + 4); + stream_write_uint8(data_out, 0x10 | cbChId); + stream_set_pos(s, 1); + stream_copy(data_out, s, pos - 1); + + if (error == 0) + { + DEBUG_DVC("channel created"); + stream_write_uint32(data_out, 0); + } + else + { + DEBUG_DVC("no listener"); + stream_write_uint32(data_out, (uint32)(-1)); + } + + error = svc_plugin_send((rdpSvcPlugin*)drdynvc, data_out); + if (error != CHANNEL_RC_OK) + { + DEBUG_WARN("VirtualChannelWrite failed %d", error); + return 1; + } + return 0; +} + +static int drdynvc_process_data_first(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) +{ + uint32 ChannelId; + uint32 Length; + int error; + + ChannelId = drdynvc_read_variable_uint(s, cbChId); + Length = drdynvc_read_variable_uint(s, Sp); + DEBUG_DVC("ChannelId=%d Length=%d", ChannelId, Length); + + error = dvcman_receive_channel_data_first(drdynvc->channel_mgr, ChannelId, Length); + if (error) + return error; + + return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, + stream_get_tail(s), stream_get_left(s)); +} + +static int drdynvc_process_data(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) +{ + uint32 ChannelId; + + ChannelId = drdynvc_read_variable_uint(s, cbChId); + DEBUG_DVC("ChannelId=%d", ChannelId); + + return dvcman_receive_channel_data(drdynvc->channel_mgr, ChannelId, + stream_get_tail(s), stream_get_left(s)); +} + +static int drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) +{ + uint32 ChannelId; + + ChannelId = drdynvc_read_variable_uint(s, cbChId); + DEBUG_DVC("ChannelId=%d", ChannelId); + dvcman_close_channel(drdynvc->channel_mgr, ChannelId); + + return 0; +} + +static void drdynvc_process_receive(rdpSvcPlugin* plugin, STREAM* s) +{ + drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; + int value; + int Cmd; + int Sp; + int cbChId; + + stream_read_uint8(s, value); + Cmd = (value & 0xf0) >> 4; + Sp = (value & 0x0c) >> 2; + cbChId = (value & 0x03) >> 0; + + DEBUG_DVC("Cmd=0x%x", Cmd); + + switch (Cmd) + { + case CAPABILITY_REQUEST_PDU: + drdynvc_process_capability_request(drdynvc, Sp, cbChId, s); + break; + case CREATE_REQUEST_PDU: + drdynvc_process_create_request(drdynvc, Sp, cbChId, s); + break; + case DATA_FIRST_PDU: + drdynvc_process_data_first(drdynvc, Sp, cbChId, s); + break; + case DATA_PDU: + drdynvc_process_data(drdynvc, Sp, cbChId, s); + break; + case CLOSE_REQUEST_PDU: + drdynvc_process_close_request(drdynvc, Sp, cbChId, s); + break; + default: + DEBUG_WARN("unknown drdynvc cmd 0x%x", Cmd); + break; + } + + stream_free(s); +} + +static void drdynvc_process_connect(rdpSvcPlugin* plugin) +{ + drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; + + DEBUG_DVC("connecting"); + + drdynvc->channel_mgr = dvcman_new(drdynvc); + dvcman_load_plugin(drdynvc->channel_mgr, svc_plugin_get_data(plugin)); + dvcman_init(drdynvc->channel_mgr); +} + +static void drdynvc_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + freerdp_event_free(event); +} + +static void drdynvc_process_terminate(rdpSvcPlugin* plugin) +{ + drdynvcPlugin* drdynvc = (drdynvcPlugin*)plugin; + + DEBUG_DVC("terminating"); + + if (drdynvc->channel_mgr != NULL) + dvcman_free(drdynvc->channel_mgr); + xfree(drdynvc); +} + +DEFINE_SVC_PLUGIN(drdynvc, "drdynvc", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP) diff --git a/channels/drdynvc/drdynvc_main.h b/channels/drdynvc/drdynvc_main.h new file mode 100644 index 0000000..519c61d --- /dev/null +++ b/channels/drdynvc/drdynvc_main.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DRDYNVC_MAIN_H +#define __DRDYNVC_MAIN_H + +#include + +typedef struct drdynvc_plugin drdynvcPlugin; + +int drdynvc_write_data(drdynvcPlugin* plugin, uint32 ChannelId, uint8* data, uint32 data_size); +int drdynvc_push_event(drdynvcPlugin* plugin, RDP_EVENT* event); + +#endif diff --git a/channels/drdynvc/drdynvc_types.h b/channels/drdynvc/drdynvc_types.h new file mode 100644 index 0000000..a08a605 --- /dev/null +++ b/channels/drdynvc/drdynvc_types.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DRDYNVC_TYPES_H +#define __DRDYNVC_TYPES_H + +#include "config.h" +#include +#include +#include + +#ifdef WITH_DEBUG_DVC +#define DEBUG_DVC(fmt, ...) DEBUG_CLASS(DVC, fmt, ## __VA_ARGS__) +#else +#define DEBUG_DVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif diff --git a/channels/drdynvc/dvcman.c b/channels/drdynvc/dvcman.c new file mode 100644 index 0000000..d24b114 --- /dev/null +++ b/channels/drdynvc/dvcman.c @@ -0,0 +1,441 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel Manager + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "dvcman.h" + +#define MAX_PLUGINS 10 + +typedef struct _DVCMAN DVCMAN; +struct _DVCMAN +{ + IWTSVirtualChannelManager iface; + + drdynvcPlugin* drdynvc; + + const char* plugin_names[MAX_PLUGINS]; + IWTSPlugin* plugins[MAX_PLUGINS]; + int num_plugins; + + IWTSListener* listeners[MAX_PLUGINS]; + int num_listeners; + + LIST* channels; +}; + +typedef struct _DVCMAN_LISTENER DVCMAN_LISTENER; +struct _DVCMAN_LISTENER +{ + IWTSListener iface; + + DVCMAN* dvcman; + char* channel_name; + uint32 flags; + IWTSListenerCallback* listener_callback; +}; + +typedef struct _DVCMAN_ENTRY_POINTS DVCMAN_ENTRY_POINTS; +struct _DVCMAN_ENTRY_POINTS +{ + IDRDYNVC_ENTRY_POINTS iface; + + DVCMAN* dvcman; + RDP_PLUGIN_DATA* plugin_data; +}; + +typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; +struct _DVCMAN_CHANNEL +{ + IWTSVirtualChannel iface; + + DVCMAN* dvcman; + DVCMAN_CHANNEL* next; + uint32 channel_id; + IWTSVirtualChannelCallback* channel_callback; + + STREAM* dvc_data; +}; + +static int dvcman_get_configuration(IWTSListener* pListener, void** ppPropertyBag) +{ + *ppPropertyBag = NULL; + return 1; +} + +static int dvcman_create_listener(IWTSVirtualChannelManager* pChannelMgr, + const char* pszChannelName, uint32 ulFlags, + IWTSListenerCallback* pListenerCallback, IWTSListener** ppListener) +{ + DVCMAN* dvcman = (DVCMAN*)pChannelMgr; + DVCMAN_LISTENER* listener; + + if (dvcman->num_listeners < MAX_PLUGINS) + { + DEBUG_DVC("%d.%s.", dvcman->num_listeners, pszChannelName); + listener = xnew(DVCMAN_LISTENER); + listener->iface.GetConfiguration = dvcman_get_configuration; + listener->dvcman = dvcman; + listener->channel_name = xstrdup(pszChannelName); + listener->flags = ulFlags; + listener->listener_callback = pListenerCallback; + + if (ppListener) + *ppListener = (IWTSListener*)listener; + dvcman->listeners[dvcman->num_listeners++] = (IWTSListener*)listener; + return 0; + } + else + { + DEBUG_WARN("Maximum DVC listener number reached."); + return 1; + } +} + +static int dvcman_push_event(IWTSVirtualChannelManager* pChannelMgr, RDP_EVENT* pEvent) +{ + int error; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + error = drdynvc_push_event(dvcman->drdynvc, pEvent); + + if (error == 0) + { + DEBUG_DVC("event_type %d pushed.", pEvent->event_type); + } + else + { + DEBUG_WARN("event_type %d push failed.", pEvent->event_type); + } + + return error; +} + +static int dvcman_register_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name, IWTSPlugin* pPlugin) +{ + DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; + + if (dvcman->num_plugins < MAX_PLUGINS) + { + DEBUG_DVC("num_plugins %d", dvcman->num_plugins); + dvcman->plugin_names[dvcman->num_plugins] = name; + dvcman->plugins[dvcman->num_plugins++] = pPlugin; + return 0; + } + else + { + DEBUG_WARN("Maximum DVC plugin number reached."); + return 1; + } +} + +IWTSPlugin* dvcman_get_plugin(IDRDYNVC_ENTRY_POINTS* pEntryPoints, const char* name) +{ + int i; + DVCMAN* dvcman = ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->dvcman; + + for (i = 0; i < dvcman->num_plugins; i++) + { + if (dvcman->plugin_names[i] == name || + strcmp(dvcman->plugin_names[i], name) == 0) + { + return dvcman->plugins[i]; + } + } + + return NULL; +} + +RDP_PLUGIN_DATA* dvcman_get_plugin_data(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +{ + return ((DVCMAN_ENTRY_POINTS*) pEntryPoints)->plugin_data; +} + +IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin) +{ + DVCMAN* dvcman; + + dvcman = xnew(DVCMAN); + dvcman->iface.CreateListener = dvcman_create_listener; + dvcman->iface.PushEvent = dvcman_push_event; + dvcman->drdynvc = plugin; + dvcman->channels = list_new(); + + return (IWTSVirtualChannelManager*) dvcman; +} + +int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data) +{ + DVCMAN_ENTRY_POINTS entryPoints; + PDVC_PLUGIN_ENTRY pDVCPluginEntry = NULL; + + while (data && data->size > 0) + { + pDVCPluginEntry = freerdp_load_plugin((char*) data->data[0], "DVCPluginEntry"); + + if (pDVCPluginEntry != NULL) + { + entryPoints.iface.RegisterPlugin = dvcman_register_plugin; + entryPoints.iface.GetPlugin = dvcman_get_plugin; + entryPoints.iface.GetPluginData = dvcman_get_plugin_data; + entryPoints.dvcman = (DVCMAN*) pChannelMgr; + entryPoints.plugin_data = data; + pDVCPluginEntry((IDRDYNVC_ENTRY_POINTS*) &entryPoints); + } + + data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); + } + + return 0; +} + +static void dvcman_channel_free(DVCMAN_CHANNEL* channel) +{ + if (channel->channel_callback) + channel->channel_callback->OnClose(channel->channel_callback); + + xfree(channel); +} + +void dvcman_free(IWTSVirtualChannelManager* pChannelMgr) +{ + int i; + IWTSPlugin* pPlugin; + DVCMAN_LISTENER* listener; + DVCMAN_CHANNEL* channel; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + while ((channel = (DVCMAN_CHANNEL*) list_dequeue(dvcman->channels)) != NULL) + dvcman_channel_free(channel); + + list_free(dvcman->channels); + + for (i = 0; i < dvcman->num_listeners; i++) + { + listener = (DVCMAN_LISTENER*) dvcman->listeners[i]; + xfree(listener->channel_name); + xfree(listener); + } + + for (i = 0; i < dvcman->num_plugins; i++) + { + pPlugin = dvcman->plugins[i]; + + if (pPlugin->Terminated) + pPlugin->Terminated(pPlugin); + } + + xfree(dvcman); +} + +int dvcman_init(IWTSVirtualChannelManager* pChannelMgr) +{ + int i; + IWTSPlugin* pPlugin; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + for (i = 0; i < dvcman->num_plugins; i++) + { + pPlugin = dvcman->plugins[i]; + + if (pPlugin->Initialize) + pPlugin->Initialize(pPlugin, pChannelMgr); + } + + return 0; +} + +static int dvcman_write_channel(IWTSVirtualChannel* pChannel, uint32 cbSize, uint8* pBuffer, void* pReserved) +{ + DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; + + return drdynvc_write_data(channel->dvcman->drdynvc, channel->channel_id, pBuffer, cbSize); +} + +static int dvcman_close_channel_iface(IWTSVirtualChannel* pChannel) +{ + DVCMAN_CHANNEL* channel = (DVCMAN_CHANNEL*) pChannel; + DVCMAN* dvcman = channel->dvcman; + + DEBUG_DVC("id=%d", channel->channel_id); + + if (list_remove(dvcman->channels, channel) == NULL) + DEBUG_WARN("channel not found"); + + dvcman_channel_free(channel); + + return 1; +} + +int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, const char* ChannelName) +{ + int i; + int bAccept; + DVCMAN_LISTENER* listener; + DVCMAN_CHANNEL* channel; + IWTSVirtualChannelCallback* pCallback; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + for (i = 0; i < dvcman->num_listeners; i++) + { + listener = (DVCMAN_LISTENER*)dvcman->listeners[i]; + + if (strcmp(listener->channel_name, ChannelName) == 0) + { + channel = xnew(DVCMAN_CHANNEL); + channel->iface.Write = dvcman_write_channel; + channel->iface.Close = dvcman_close_channel_iface; + channel->dvcman = dvcman; + channel->channel_id = ChannelId; + + bAccept = 1; + pCallback = NULL; + + if (listener->listener_callback->OnNewChannelConnection(listener->listener_callback, + (IWTSVirtualChannel*) channel, NULL, &bAccept, &pCallback) == 0 && bAccept == 1) + { + DEBUG_DVC("listener %s created new channel %d", + listener->channel_name, channel->channel_id); + channel->channel_callback = pCallback; + list_add(dvcman->channels, channel); + + return 0; + } + else + { + DEBUG_WARN("channel rejected by plugin"); + dvcman_channel_free(channel); + return 1; + } + } + } + + return 1; +} + +static DVCMAN_CHANNEL* dvcman_find_channel_by_id(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId) +{ + LIST_ITEM* curr; + DVCMAN* dvcman = (DVCMAN*) pChannelMgr; + + for (curr = dvcman->channels->head; curr; curr = curr->next) + { + if (((DVCMAN_CHANNEL*) curr->data)->channel_id == ChannelId) + { + return (DVCMAN_CHANNEL*)curr->data; + } + } + + return NULL; +} + +int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId) +{ + DVCMAN_CHANNEL* channel; + IWTSVirtualChannel* ichannel; + + channel = dvcman_find_channel_by_id(pChannelMgr, ChannelId); + + if (channel == NULL) + { + DEBUG_WARN("ChannelId %d not found!", ChannelId); + return 1; + } + + if (channel->dvc_data) + { + stream_free(channel->dvc_data); + channel->dvc_data = NULL; + } + + DEBUG_DVC("dvcman_close_channel: channel %d closed", ChannelId); + ichannel = (IWTSVirtualChannel*)channel; + ichannel->Close(ichannel); + + return 0; +} + +int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint32 length) +{ + DVCMAN_CHANNEL* channel; + + channel = dvcman_find_channel_by_id(pChannelMgr, ChannelId); + + if (channel == NULL) + { + DEBUG_WARN("ChannelId %d not found!", ChannelId); + return 1; + } + + if (channel->dvc_data) + stream_free(channel->dvc_data); + + channel->dvc_data = stream_new(length); + + return 0; +} + +int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint8* data, uint32 data_size) +{ + int error = 0; + DVCMAN_CHANNEL* channel; + + channel = dvcman_find_channel_by_id(pChannelMgr, ChannelId); + + if (channel == NULL) + { + DEBUG_WARN("ChannelId %d not found!", ChannelId); + return 1; + } + + if (channel->dvc_data) + { + /* Fragmented data */ + if (stream_get_length(channel->dvc_data) + data_size > stream_get_size(channel->dvc_data)) + { + DEBUG_WARN("data exceeding declared length!"); + stream_free(channel->dvc_data); + channel->dvc_data = NULL; + return 1; + } + + stream_write(channel->dvc_data, data, data_size); + + if (stream_get_length(channel->dvc_data) >= stream_get_size(channel->dvc_data)) + { + error = channel->channel_callback->OnDataReceived(channel->channel_callback, + stream_get_size(channel->dvc_data), stream_get_data(channel->dvc_data)); + stream_free(channel->dvc_data); + channel->dvc_data = NULL; + } + } + else + { + error = channel->channel_callback->OnDataReceived(channel->channel_callback, data_size, data); + } + + return error; +} diff --git a/channels/drdynvc/dvcman.h b/channels/drdynvc/dvcman.h new file mode 100644 index 0000000..679243f --- /dev/null +++ b/channels/drdynvc/dvcman.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel Manager + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DVCMAN_H +#define __DVCMAN_H + +#include +#include "drdynvc_main.h" + +IWTSVirtualChannelManager* dvcman_new(drdynvcPlugin* plugin); +int dvcman_load_plugin(IWTSVirtualChannelManager* pChannelMgr, RDP_PLUGIN_DATA* data); +void dvcman_free(IWTSVirtualChannelManager* pChannelMgr); +int dvcman_init(IWTSVirtualChannelManager* pChannelMgr); +int dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, const char* ChannelName); +int dvcman_close_channel(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId); +int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint32 length); +int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, uint32 ChannelId, uint8* data, uint32 data_size); + +#endif diff --git a/channels/drdynvc/tsmf/CMakeLists.txt b/channels/drdynvc/tsmf/CMakeLists.txt new file mode 100644 index 0000000..e28cac6 --- /dev/null +++ b/channels/drdynvc/tsmf/CMakeLists.txt @@ -0,0 +1,57 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(TSMF_SRCS + tsmf_audio.c + tsmf_audio.h + tsmf_codec.c + tsmf_codec.h + tsmf_constants.h + tsmf_decoder.c + tsmf_decoder.h + tsmf_ifman.c + tsmf_ifman.h + tsmf_main.c + tsmf_main.h + tsmf_media.c + tsmf_media.h + tsmf_types.h +) + +include_directories(..) + +add_library(tsmf ${TSMF_SRCS}) +set_target_properties(tsmf PROPERTIES PREFIX "") + +target_link_libraries(tsmf freerdp-utils) + +install(TARGETS tsmf DESTINATION ${FREERDP_PLUGIN_PATH}) + +if(WITH_FFMPEG) + add_subdirectory(ffmpeg) +endif() + +if(WITH_ALSA) + add_subdirectory(alsa) +endif() + +if(WITH_PULSEAUDIO) + add_subdirectory(pulse) +endif() + diff --git a/channels/drdynvc/tsmf/alsa/CMakeLists.txt b/channels/drdynvc/tsmf/alsa/CMakeLists.txt new file mode 100644 index 0000000..c769a18 --- /dev/null +++ b/channels/drdynvc/tsmf/alsa/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(TSMF_ALSA_SRCS + tsmf_alsa.c +) + +include_directories(..) +include_directories(${ALSA_INCLUDE_DIRS}) + +add_library(tsmf_alsa ${TSMF_ALSA_SRCS}) +set_target_properties(tsmf_alsa PROPERTIES PREFIX "") + +target_link_libraries(tsmf_alsa freerdp-utils) +target_link_libraries(tsmf_alsa ${ALSA_LIBRARIES}) + +install(TARGETS tsmf_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/drdynvc/tsmf/alsa/tsmf_alsa.c b/channels/drdynvc/tsmf/alsa/tsmf_alsa.c new file mode 100644 index 0000000..3017dac --- /dev/null +++ b/channels/drdynvc/tsmf/alsa/tsmf_alsa.c @@ -0,0 +1,263 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - ALSA Audio Device + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tsmf_audio.h" + +typedef struct _TSMFALSAAudioDevice +{ + ITSMFAudioDevice iface; + + char device[32]; + snd_pcm_t* out_handle; + uint32 source_rate; + uint32 actual_rate; + uint32 source_channels; + uint32 actual_channels; + uint32 bytes_per_sample; +} TSMFALSAAudioDevice; + +static boolean tsmf_alsa_open_device(TSMFALSAAudioDevice* alsa) +{ + int error; + + error = snd_pcm_open(&alsa->out_handle, alsa->device, SND_PCM_STREAM_PLAYBACK, 0); + if (error < 0) + { + DEBUG_WARN("failed to open device %s", alsa->device); + return false; + } + + DEBUG_DVC("open device %s", alsa->device); + return true; +} + +static boolean tsmf_alsa_open(ITSMFAudioDevice* audio, const char* device) +{ + TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; + + if (!device) + { + if (!alsa->device[0]) + strcpy(alsa->device, "default"); + } + else + { + strcpy(alsa->device, device); + } + + return tsmf_alsa_open_device(alsa); +} + +static boolean tsmf_alsa_set_format(ITSMFAudioDevice* audio, + uint32 sample_rate, uint32 channels, uint32 bits_per_sample) +{ + int error; + snd_pcm_uframes_t frames; + snd_pcm_hw_params_t* hw_params; + snd_pcm_sw_params_t* sw_params; + TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; + + if (!alsa->out_handle) + return false; + + snd_pcm_drop(alsa->out_handle); + + alsa->actual_rate = alsa->source_rate = sample_rate; + alsa->actual_channels = alsa->source_channels = channels; + alsa->bytes_per_sample = bits_per_sample / 8; + + error = snd_pcm_hw_params_malloc(&hw_params); + if (error < 0) + { + DEBUG_WARN("snd_pcm_hw_params_malloc failed"); + return false; + } + snd_pcm_hw_params_any(alsa->out_handle, hw_params); + snd_pcm_hw_params_set_access(alsa->out_handle, hw_params, + SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_format(alsa->out_handle, hw_params, + SND_PCM_FORMAT_S16_LE); + snd_pcm_hw_params_set_rate_near(alsa->out_handle, hw_params, + &alsa->actual_rate, NULL); + snd_pcm_hw_params_set_channels_near(alsa->out_handle, hw_params, + &alsa->actual_channels); + frames = sample_rate; + snd_pcm_hw_params_set_buffer_size_near(alsa->out_handle, hw_params, + &frames); + snd_pcm_hw_params(alsa->out_handle, hw_params); + snd_pcm_hw_params_free(hw_params); + + error = snd_pcm_sw_params_malloc(&sw_params); + if (error < 0) + { + DEBUG_WARN("snd_pcm_sw_params_malloc"); + return false; + } + snd_pcm_sw_params_current(alsa->out_handle, sw_params); + snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params, + frames / 2); + snd_pcm_sw_params(alsa->out_handle, sw_params); + snd_pcm_sw_params_free(sw_params); + + snd_pcm_prepare(alsa->out_handle); + + DEBUG_DVC("sample_rate %d channels %d bits_per_sample %d", + sample_rate, channels, bits_per_sample); + DEBUG_DVC("hardware buffer %d frames", (int)frames); + if ((alsa->actual_rate != alsa->source_rate) || + (alsa->actual_channels != alsa->source_channels)) + { + DEBUG_DVC("actual rate %d / channel %d is different " + "from source rate %d / channel %d, resampling required.", + alsa->actual_rate, alsa->actual_channels, + alsa->source_rate, alsa->source_channels); + } + return true; +} + +static boolean tsmf_alsa_play(ITSMFAudioDevice* audio, uint8* data, uint32 data_size) +{ + int len; + int error; + int frames; + uint8* end; + uint8* src; + uint8* pindex; + int rbytes_per_frame; + int sbytes_per_frame; + uint8* resampled_data; + TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; + + DEBUG_DVC("data_size %d", data_size); + + if (alsa->out_handle) + { + sbytes_per_frame = alsa->source_channels * alsa->bytes_per_sample; + rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_sample; + + if ((alsa->source_rate == alsa->actual_rate) && + (alsa->source_channels == alsa->actual_channels)) + { + resampled_data = NULL; + src = data; + } + else + { + resampled_data = dsp_resample(data, alsa->bytes_per_sample, + alsa->source_channels, alsa->source_rate, data_size / sbytes_per_frame, + alsa->actual_channels, alsa->actual_rate, &frames); + DEBUG_DVC("resampled %d frames at %d to %d frames at %d", + data_size / sbytes_per_frame, alsa->source_rate, frames, alsa->actual_rate); + data_size = frames * rbytes_per_frame; + src = resampled_data; + } + + pindex = src; + end = pindex + data_size; + while (pindex < end) + { + len = end - pindex; + frames = len / rbytes_per_frame; + error = snd_pcm_writei(alsa->out_handle, pindex, frames); + if (error == -EPIPE) + { + snd_pcm_recover(alsa->out_handle, error, 0); + error = 0; + } + else if (error < 0) + { + DEBUG_DVC("error len %d", error); + snd_pcm_close(alsa->out_handle); + alsa->out_handle = 0; + tsmf_alsa_open_device(alsa); + break; + } + DEBUG_DVC("%d frames played.", error); + if (error == 0) + break; + pindex += error * rbytes_per_frame; + } + + if (resampled_data) + xfree(resampled_data); + } + xfree(data); + + return true; +} + +static uint64 tsmf_alsa_get_latency(ITSMFAudioDevice* audio) +{ + uint64 latency = 0; + snd_pcm_sframes_t frames = 0; + TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; + + if (alsa->out_handle && alsa->actual_rate > 0 && + snd_pcm_delay(alsa->out_handle, &frames) == 0 && + frames > 0) + { + latency = ((uint64)frames) * 10000000LL / (uint64)alsa->actual_rate; + } + return latency; +} + +static void tsmf_alsa_flush(ITSMFAudioDevice* audio) +{ +} + +static void tsmf_alsa_free(ITSMFAudioDevice* audio) +{ + TSMFALSAAudioDevice* alsa = (TSMFALSAAudioDevice*) audio; + + DEBUG_DVC(""); + + if (alsa->out_handle) + { + snd_pcm_drain(alsa->out_handle); + snd_pcm_close(alsa->out_handle); + } + xfree(alsa); +} + +ITSMFAudioDevice* TSMFAudioDeviceEntry(void) +{ + TSMFALSAAudioDevice* alsa; + + alsa = xnew(TSMFALSAAudioDevice); + + alsa->iface.Open = tsmf_alsa_open; + alsa->iface.SetFormat = tsmf_alsa_set_format; + alsa->iface.Play = tsmf_alsa_play; + alsa->iface.GetLatency = tsmf_alsa_get_latency; + alsa->iface.Flush = tsmf_alsa_flush; + alsa->iface.Free = tsmf_alsa_free; + + return (ITSMFAudioDevice*) alsa; +} + diff --git a/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt b/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt new file mode 100644 index 0000000..ea0b101 --- /dev/null +++ b/channels/drdynvc/tsmf/ffmpeg/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(TSMF_FFMPEG_SRCS + tsmf_ffmpeg.c +) + +include_directories(..) +include_directories(${FFMPEG_INCLUDE_DIRS}) + +add_library(tsmf_ffmpeg ${TSMF_FFMPEG_SRCS}) +set_target_properties(tsmf_ffmpeg PROPERTIES PREFIX "") + +target_link_libraries(tsmf_ffmpeg freerdp-utils) +target_link_libraries(tsmf_ffmpeg ${FFMPEG_LIBRARIES}) + +install(TARGETS tsmf_ffmpeg DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c b/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c new file mode 100644 index 0000000..4210fa0 --- /dev/null +++ b/channels/drdynvc/tsmf/ffmpeg/tsmf_ffmpeg.c @@ -0,0 +1,518 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - FFmpeg Decoder + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tsmf_constants.h" +#include "tsmf_decoder.h" + +/* Compatibility with older FFmpeg */ +#if LIBAVUTIL_VERSION_MAJOR < 50 +#define AVMEDIA_TYPE_VIDEO 0 +#define AVMEDIA_TYPE_AUDIO 1 +#endif + +typedef struct _TSMFFFmpegDecoder +{ + ITSMFDecoder iface; + + int media_type; + enum CodecID codec_id; + AVCodecContext* codec_context; + AVCodec* codec; + AVFrame* frame; + int prepared; + + uint8* decoded_data; + uint32 decoded_size; + uint32 decoded_size_max; +} TSMFFFmpegDecoder; + +static boolean tsmf_ffmpeg_init_context(ITSMFDecoder* decoder) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + mdecoder->codec_context = avcodec_alloc_context(); + if (!mdecoder->codec_context) + { + DEBUG_WARN("avcodec_alloc_context failed."); + return false; + } + + return true; +} + +static boolean tsmf_ffmpeg_init_video_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + mdecoder->codec_context->width = media_type->Width; + mdecoder->codec_context->height = media_type->Height; + mdecoder->codec_context->bit_rate = media_type->BitRate; + mdecoder->codec_context->time_base.den = media_type->SamplesPerSecond.Numerator; + mdecoder->codec_context->time_base.num = media_type->SamplesPerSecond.Denominator; + + mdecoder->frame = avcodec_alloc_frame(); + + return true; +} + +static boolean tsmf_ffmpeg_init_audio_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + mdecoder->codec_context->sample_rate = media_type->SamplesPerSecond.Numerator; + mdecoder->codec_context->bit_rate = media_type->BitRate; + mdecoder->codec_context->channels = media_type->Channels; + mdecoder->codec_context->block_align = media_type->BlockAlign; + +#ifdef AV_CPU_FLAG_SSE2 + mdecoder->codec_context->dsp_mask = AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_MMX2; +#else +#if LIBAVCODEC_VERSION_MAJOR < 53 + mdecoder->codec_context->dsp_mask = FF_MM_SSE2 | FF_MM_MMXEXT; +#else + mdecoder->codec_context->dsp_mask = FF_MM_SSE2 | FF_MM_MMX2; +#endif +#endif + + return true; +} + +static boolean tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE* media_type) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + uint32 size; + const uint8* s; + uint8* p; + + mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id); + if (!mdecoder->codec) + { + DEBUG_WARN("avcodec_find_decoder failed."); + return false; + } + + mdecoder->codec_context->codec_id = mdecoder->codec_id; + mdecoder->codec_context->codec_type = mdecoder->media_type; + + if (mdecoder->media_type == AVMEDIA_TYPE_VIDEO) + { + if (!tsmf_ffmpeg_init_video_stream(decoder, media_type)) + return false; + } + else if (mdecoder->media_type == AVMEDIA_TYPE_AUDIO) + { + if (!tsmf_ffmpeg_init_audio_stream(decoder, media_type)) + return false; + } + + if (media_type->ExtraData) + { + if (media_type->SubType == TSMF_SUB_TYPE_AVC1 && + media_type->FormatType == TSMF_FORMAT_TYPE_MPEG2VIDEOINFO) + { + /* The extradata format that FFmpeg uses is following CodecPrivate in Matroska. + See http://haali.su/mkv/codecs.pdf */ + mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8; + mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size); + p = mdecoder->codec_context->extradata; + *p++ = 1; /* Reserved? */ + *p++ = media_type->ExtraData[8]; /* Profile */ + *p++ = 0; /* Profile */ + *p++ = media_type->ExtraData[12]; /* Level */ + *p++ = 0xff; /* Flag? */ + *p++ = 0xe0 | 0x01; /* Reserved | #sps */ + s = media_type->ExtraData + 20; + size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1))); + memcpy(p, s, size + 2); + s += size + 2; + p += size + 2; + *p++ = 1; /* #pps */ + size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1))); + memcpy(p, s, size + 2); + } + else + { + /* Add a padding to avoid invalid memory read in some codec */ + mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8; + mdecoder->codec_context->extradata = xzalloc(mdecoder->codec_context->extradata_size); + memcpy(mdecoder->codec_context->extradata, media_type->ExtraData, media_type->ExtraDataSize); + memset(mdecoder->codec_context->extradata + media_type->ExtraDataSize, 0, 8); + } + } + + if (mdecoder->codec->capabilities & CODEC_CAP_TRUNCATED) + mdecoder->codec_context->flags |= CODEC_FLAG_TRUNCATED; + + return true; +} + +static boolean tsmf_ffmpeg_prepare(ITSMFDecoder* decoder) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + if (avcodec_open(mdecoder->codec_context, mdecoder->codec) < 0) + { + DEBUG_WARN("avcodec_open failed."); + return false; + } + + mdecoder->prepared = 1; + + return true; +} + +static boolean tsmf_ffmpeg_set_format(ITSMFDecoder* decoder, TS_AM_MEDIA_TYPE* media_type) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + switch (media_type->MajorType) + { + case TSMF_MAJOR_TYPE_VIDEO: + mdecoder->media_type = AVMEDIA_TYPE_VIDEO; + break; + case TSMF_MAJOR_TYPE_AUDIO: + mdecoder->media_type = AVMEDIA_TYPE_AUDIO; + break; + default: + return false; + } + switch (media_type->SubType) + { + case TSMF_SUB_TYPE_WVC1: + mdecoder->codec_id = CODEC_ID_VC1; + break; + case TSMF_SUB_TYPE_WMA2: + mdecoder->codec_id = CODEC_ID_WMAV2; + break; + case TSMF_SUB_TYPE_WMA9: + mdecoder->codec_id = CODEC_ID_WMAPRO; + break; + case TSMF_SUB_TYPE_MP3: + mdecoder->codec_id = CODEC_ID_MP3; + break; + case TSMF_SUB_TYPE_MP2A: + mdecoder->codec_id = CODEC_ID_MP2; + break; + case TSMF_SUB_TYPE_MP2V: + mdecoder->codec_id = CODEC_ID_MPEG2VIDEO; + break; + case TSMF_SUB_TYPE_WMV3: + mdecoder->codec_id = CODEC_ID_WMV3; + break; + case TSMF_SUB_TYPE_AAC: + mdecoder->codec_id = CODEC_ID_AAC; + /* For AAC the pFormat is a HEAACWAVEINFO struct, and the codec data + is at the end of it. See + http://msdn.microsoft.com/en-us/library/dd757806.aspx */ + if (media_type->ExtraData) + { + media_type->ExtraData += 12; + media_type->ExtraDataSize -= 12; + } + break; + case TSMF_SUB_TYPE_H264: + case TSMF_SUB_TYPE_AVC1: + mdecoder->codec_id = CODEC_ID_H264; + break; + case TSMF_SUB_TYPE_AC3: + mdecoder->codec_id = CODEC_ID_AC3; + break; + default: + return false; + } + + if (!tsmf_ffmpeg_init_context(decoder)) + return false; + if (!tsmf_ffmpeg_init_stream(decoder, media_type)) + return false; + if (!tsmf_ffmpeg_prepare(decoder)) + return false; + + return true; +} + +static boolean tsmf_ffmpeg_decode_video(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + int decoded; + int len; + AVFrame* frame; + boolean ret = true; + +#if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20) + len = avcodec_decode_video(mdecoder->codec_context, mdecoder->frame, &decoded, data, data_size); +#else + { + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = (uint8*) data; + pkt.size = data_size; + if (extensions & TSMM_SAMPLE_EXT_CLEANPOINT) + pkt.flags |= AV_PKT_FLAG_KEY; + len = avcodec_decode_video2(mdecoder->codec_context, mdecoder->frame, &decoded, &pkt); + } +#endif + + if (len < 0) + { + DEBUG_WARN("data_size %d, avcodec_decode_video failed (%d)", data_size, len); + ret = false; + } + else if (!decoded) + { + DEBUG_WARN("data_size %d, no frame is decoded.", data_size); + ret = false; + } + else + { + DEBUG_DVC("linesize[0] %d linesize[1] %d linesize[2] %d linesize[3] %d " + "pix_fmt %d width %d height %d", + mdecoder->frame->linesize[0], mdecoder->frame->linesize[1], + mdecoder->frame->linesize[2], mdecoder->frame->linesize[3], + mdecoder->codec_context->pix_fmt, + mdecoder->codec_context->width, mdecoder->codec_context->height); + + mdecoder->decoded_size = avpicture_get_size(mdecoder->codec_context->pix_fmt, + mdecoder->codec_context->width, mdecoder->codec_context->height); + mdecoder->decoded_data = xzalloc(mdecoder->decoded_size); + frame = avcodec_alloc_frame(); + avpicture_fill((AVPicture *) frame, mdecoder->decoded_data, + mdecoder->codec_context->pix_fmt, + mdecoder->codec_context->width, mdecoder->codec_context->height); + + av_picture_copy((AVPicture *) frame, (AVPicture *) mdecoder->frame, + mdecoder->codec_context->pix_fmt, + mdecoder->codec_context->width, mdecoder->codec_context->height); + + av_free(frame); + } + + return ret; +} + +static boolean tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + int len; + int frame_size; + uint32 src_size; + const uint8* src; + uint8* dst; + int dst_offset; + +#if 0 + LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size)); + int i; + for (i = 0; i < data_size; i++) + { + LLOG(0, ("%02X ", data[i])); + if (i % 16 == 15) + LLOG(0, ("\n")); + } + LLOG(0, ("\n")); +#endif + + if (mdecoder->decoded_size_max == 0) + mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16; + mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max); + /* align the memory for SSE2 needs */ + dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); + dst_offset = dst - mdecoder->decoded_data; + src = data; + src_size = data_size; + + while (src_size > 0) + { + /* Ensure enough space for decoding */ + if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE) + { + mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16; + mdecoder->decoded_data = xrealloc(mdecoder->decoded_data, mdecoder->decoded_size_max); + dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); + if (dst - mdecoder->decoded_data != dst_offset) + { + /* re-align the memory if the alignment has changed after realloc */ + memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); + dst_offset = dst - mdecoder->decoded_data; + } + dst += mdecoder->decoded_size; + } + frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size; +#if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20) + len = avcodec_decode_audio2(mdecoder->codec_context, + (int16_t*) dst, &frame_size, + src, src_size); +#else + { + AVPacket pkt; + av_init_packet(&pkt); + pkt.data = (uint8*) src; + pkt.size = src_size; + len = avcodec_decode_audio3(mdecoder->codec_context, + (int16_t*) dst, &frame_size, &pkt); + } +#endif + if (len <= 0 || frame_size <= 0) + { + DEBUG_WARN("error decoding"); + break; + } + src += len; + src_size -= len; + mdecoder->decoded_size += frame_size; + dst += frame_size; + } + + if (mdecoder->decoded_size == 0) + { + xfree(mdecoder->decoded_data); + mdecoder->decoded_data = NULL; + } + else if (dst_offset) + { + /* move the aligned decoded data to original place */ + memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); + } + + DEBUG_DVC("data_size %d decoded_size %d", + data_size, mdecoder->decoded_size); + + return true; +} + +static boolean tsmf_ffmpeg_decode(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + if (mdecoder->decoded_data) + { + xfree(mdecoder->decoded_data); + mdecoder->decoded_data = NULL; + } + mdecoder->decoded_size = 0; + + switch (mdecoder->media_type) + { + case AVMEDIA_TYPE_VIDEO: + return tsmf_ffmpeg_decode_video(decoder, data, data_size, extensions); + case AVMEDIA_TYPE_AUDIO: + return tsmf_ffmpeg_decode_audio(decoder, data, data_size, extensions); + default: + DEBUG_WARN("unknown media type."); + return false; + } +} + +static uint8* tsmf_ffmpeg_get_decoded_data(ITSMFDecoder* decoder, uint32* size) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + uint8* buf; + + *size = mdecoder->decoded_size; + buf = mdecoder->decoded_data; + mdecoder->decoded_data = NULL; + mdecoder->decoded_size = 0; + return buf; +} + +static uint32 tsmf_ffmpeg_get_decoded_format(ITSMFDecoder* decoder) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + switch (mdecoder->codec_context->pix_fmt) + { + case PIX_FMT_YUV420P: + return RDP_PIXFMT_I420; + + default: + DEBUG_WARN("unsupported pixel format %u", + mdecoder->codec_context->pix_fmt); + return (uint32) -1; + } +} + +static boolean tsmf_ffmpeg_get_decoded_dimension(ITSMFDecoder* decoder, uint32* width, uint32* height) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + if (mdecoder->codec_context->width > 0 && mdecoder->codec_context->height > 0) + { + *width = mdecoder->codec_context->width; + *height = mdecoder->codec_context->height; + return true; + } + else + { + return false; + } +} + +static void tsmf_ffmpeg_free(ITSMFDecoder* decoder) +{ + TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; + + if (mdecoder->frame) + av_free(mdecoder->frame); + if (mdecoder->decoded_data) + xfree(mdecoder->decoded_data); + if (mdecoder->codec_context) + { + if (mdecoder->prepared) + avcodec_close(mdecoder->codec_context); + if (mdecoder->codec_context->extradata) + xfree(mdecoder->codec_context->extradata); + av_free(mdecoder->codec_context); + } + xfree(decoder); +} + +static boolean initialized = false; + +ITSMFDecoder* +TSMFDecoderEntry(void) +{ + TSMFFFmpegDecoder * decoder; + + if (!initialized) + { + avcodec_init(); + avcodec_register_all(); + initialized = true; + } + + decoder = xnew(TSMFFFmpegDecoder); + + decoder->iface.SetFormat = tsmf_ffmpeg_set_format; + decoder->iface.Decode = tsmf_ffmpeg_decode; + decoder->iface.GetDecodedData = tsmf_ffmpeg_get_decoded_data; + decoder->iface.GetDecodedFormat = tsmf_ffmpeg_get_decoded_format; + decoder->iface.GetDecodedDimension = tsmf_ffmpeg_get_decoded_dimension; + decoder->iface.Free = tsmf_ffmpeg_free; + + return (ITSMFDecoder*) decoder; +} + diff --git a/channels/drdynvc/tsmf/pulse/CMakeLists.txt b/channels/drdynvc/tsmf/pulse/CMakeLists.txt new file mode 100644 index 0000000..373d4d3 --- /dev/null +++ b/channels/drdynvc/tsmf/pulse/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(TSMF_PULSE_SRCS + tsmf_pulse.c +) + +include_directories(..) +include_directories(${PULSE_INCLUDE_DIRS}) + +add_library(tsmf_pulse ${TSMF_PULSE_SRCS}) +set_target_properties(tsmf_pulse PROPERTIES PREFIX "") + +target_link_libraries(tsmf_pulse freerdp-utils) +target_link_libraries(tsmf_pulse ${PULSE_LIBRARIES}) + +install(TARGETS tsmf_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/drdynvc/tsmf/pulse/tsmf_pulse.c b/channels/drdynvc/tsmf/pulse/tsmf_pulse.c new file mode 100644 index 0000000..de3c901 --- /dev/null +++ b/channels/drdynvc/tsmf/pulse/tsmf_pulse.c @@ -0,0 +1,402 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - PulseAudio Device + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "tsmf_audio.h" + +typedef struct _TSMFPulseAudioDevice +{ + ITSMFAudioDevice iface; + + char device[32]; + pa_threaded_mainloop* mainloop; + pa_context* context; + pa_sample_spec sample_spec; + pa_stream* stream; +} TSMFPulseAudioDevice; + +static void tsmf_pulse_context_state_callback(pa_context* context, void* userdata) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) userdata; + pa_context_state_t state; + + state = pa_context_get_state(context); + switch (state) + { + case PA_CONTEXT_READY: + DEBUG_DVC("PA_CONTEXT_READY"); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + case PA_CONTEXT_FAILED: + case PA_CONTEXT_TERMINATED: + DEBUG_DVC("state %d", (int)state); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + default: + DEBUG_DVC("state %d", (int)state); + break; + } +} + +static boolean tsmf_pulse_connect(TSMFPulseAudioDevice* pulse) +{ + pa_context_state_t state; + + if (!pulse->context) + return false; + + if (pa_context_connect(pulse->context, NULL, 0, NULL)) + { + DEBUG_WARN("pa_context_connect failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + pa_threaded_mainloop_lock(pulse->mainloop); + if (pa_threaded_mainloop_start(pulse->mainloop) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + for (;;) + { + state = pa_context_get_state(pulse->context); + if (state == PA_CONTEXT_READY) + break; + if (!PA_CONTEXT_IS_GOOD(state)) + { + DEBUG_DVC("bad context state (%d)", + pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_CONTEXT_READY) + { + DEBUG_DVC("connected"); + return true; + } + else + { + pa_context_disconnect(pulse->context); + return false; + } +} + +static boolean tsmf_pulse_open(ITSMFAudioDevice* audio, const char* device) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + + if (device) + { + strcpy(pulse->device, device); + } + + pulse->mainloop = pa_threaded_mainloop_new(); + if (!pulse->mainloop) + { + DEBUG_WARN("pa_threaded_mainloop_new failed"); + return false; + } + pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); + if (!pulse->context) + { + DEBUG_WARN("pa_context_new failed"); + return false; + } + pa_context_set_state_callback(pulse->context, tsmf_pulse_context_state_callback, pulse); + if (tsmf_pulse_connect(pulse)) + { + DEBUG_WARN("tsmf_pulse_connect failed"); + return false; + } + + DEBUG_DVC("open device %s", pulse->device); + return true; +} + +static void tsmf_pulse_stream_success_callback(pa_stream* stream, int success, void* userdata) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) userdata; + + pa_threaded_mainloop_signal(pulse->mainloop, 0); +} + +static void tsmf_pulse_wait_for_operation(TSMFPulseAudioDevice* pulse, pa_operation* operation) +{ + if (operation == NULL) + return; + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + { + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_operation_unref(operation); +} + +static void tsmf_pulse_stream_state_callback(pa_stream* stream, void* userdata) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) userdata; + pa_stream_state_t state; + + state = pa_stream_get_state(stream); + switch (state) + { + case PA_STREAM_READY: + DEBUG_DVC("PA_STREAM_READY"); + pa_threaded_mainloop_signal (pulse->mainloop, 0); + break; + + case PA_STREAM_FAILED: + case PA_STREAM_TERMINATED: + DEBUG_DVC("state %d", (int)state); + pa_threaded_mainloop_signal (pulse->mainloop, 0); + break; + + default: + DEBUG_DVC("state %d", (int)state); + break; + } +} + +static void tsmf_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) userdata; + + DEBUG_DVC("%d", (int) length); + + pa_threaded_mainloop_signal(pulse->mainloop, 0); +} + +static boolean tsmf_pulse_close_stream(TSMFPulseAudioDevice* pulse) +{ + if (!pulse->context || !pulse->stream) + return false; + + DEBUG_DVC(""); + + pa_threaded_mainloop_lock(pulse->mainloop); + pa_stream_set_write_callback(pulse->stream, NULL, NULL); + tsmf_pulse_wait_for_operation(pulse, + pa_stream_drain(pulse->stream, tsmf_pulse_stream_success_callback, pulse)); + pa_stream_disconnect(pulse->stream); + pa_stream_unref(pulse->stream); + pulse->stream = NULL; + pa_threaded_mainloop_unlock(pulse->mainloop); + + return true; +} + +static boolean tsmf_pulse_open_stream(TSMFPulseAudioDevice* pulse) +{ + pa_stream_state_t state; + pa_buffer_attr buffer_attr = { 0 }; + + if (!pulse->context) + return false; + + DEBUG_DVC(""); + + pa_threaded_mainloop_lock(pulse->mainloop); + pulse->stream = pa_stream_new(pulse->context, "freerdp", + &pulse->sample_spec, NULL); + if (!pulse->stream) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_stream_new failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + pa_stream_set_state_callback(pulse->stream, + tsmf_pulse_stream_state_callback, pulse); + pa_stream_set_write_callback(pulse->stream, + tsmf_pulse_stream_request_callback, pulse); + buffer_attr.maxlength = pa_usec_to_bytes(500000, &pulse->sample_spec); + buffer_attr.tlength = pa_usec_to_bytes(250000, &pulse->sample_spec); + buffer_attr.prebuf = (uint32_t) -1; + buffer_attr.minreq = (uint32_t) -1; + buffer_attr.fragsize = (uint32_t) -1; + if (pa_stream_connect_playback(pulse->stream, + pulse->device[0] ? pulse->device : NULL, &buffer_attr, + PA_STREAM_ADJUST_LATENCY | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE, + NULL, NULL) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_stream_connect_playback failed (%d)", + pa_context_errno(pulse->context)); + return false; + } + + for (;;) + { + state = pa_stream_get_state(pulse->stream); + if (state == PA_STREAM_READY) + break; + if (!PA_STREAM_IS_GOOD(state)) + { + DEBUG_WARN("bad stream state (%d)", + pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_STREAM_READY) + { + DEBUG_DVC("connected"); + return true; + } + else + { + tsmf_pulse_close_stream(pulse); + return false; + } +} + +static boolean tsmf_pulse_set_format(ITSMFAudioDevice* audio, + uint32 sample_rate, uint32 channels, uint32 bits_per_sample) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + + DEBUG_DVC("sample_rate %d channels %d bits_per_sample %d", + sample_rate, channels, bits_per_sample); + + pulse->sample_spec.rate = sample_rate; + pulse->sample_spec.channels = channels; + pulse->sample_spec.format = PA_SAMPLE_S16LE; + + return tsmf_pulse_open_stream(pulse); +} + +static boolean tsmf_pulse_play(ITSMFAudioDevice* audio, uint8* data, uint32 data_size) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + uint8* src; + int len; + int ret; + + DEBUG_DVC("data_size %d", data_size); + + if (pulse->stream) + { + pa_threaded_mainloop_lock(pulse->mainloop); + + src = data; + while (data_size > 0) + { + while ((len = pa_stream_writable_size(pulse->stream)) == 0) + { + DEBUG_DVC("waiting"); + pa_threaded_mainloop_wait(pulse->mainloop); + } + if (len < 0) + break; + if (len > data_size) + len = data_size; + ret = pa_stream_write(pulse->stream, src, len, NULL, 0LL, PA_SEEK_RELATIVE); + if (ret < 0) + { + DEBUG_DVC("pa_stream_write failed (%d)", + pa_context_errno(pulse->context)); + break; + } + src += len; + data_size -= len; + } + + pa_threaded_mainloop_unlock(pulse->mainloop); + } + xfree(data); + + return true; +} + +static uint64 tsmf_pulse_get_latency(ITSMFAudioDevice* audio) +{ + pa_usec_t usec; + uint64 latency = 0; + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + + if (pulse->stream && pa_stream_get_latency(pulse->stream, &usec, NULL) == 0) + { + latency = ((uint64)usec) * 10LL; + } + return latency; +} + +static void tsmf_pulse_flush(ITSMFAudioDevice* audio) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + + pa_threaded_mainloop_lock(pulse->mainloop); + tsmf_pulse_wait_for_operation(pulse, + pa_stream_flush(pulse->stream, tsmf_pulse_stream_success_callback, pulse)); + pa_threaded_mainloop_unlock(pulse->mainloop); +} + +static void tsmf_pulse_free(ITSMFAudioDevice* audio) +{ + TSMFPulseAudioDevice* pulse = (TSMFPulseAudioDevice*) audio; + + DEBUG_DVC(""); + + tsmf_pulse_close_stream(pulse); + if (pulse->mainloop) + { + pa_threaded_mainloop_stop(pulse->mainloop); + } + if (pulse->context) + { + pa_context_disconnect(pulse->context); + pa_context_unref(pulse->context); + pulse->context = NULL; + } + if (pulse->mainloop) + { + pa_threaded_mainloop_free(pulse->mainloop); + pulse->mainloop = NULL; + } + xfree(pulse); +} + +ITSMFAudioDevice* TSMFAudioDeviceEntry(void) +{ + TSMFPulseAudioDevice* pulse; + + pulse = xnew(TSMFPulseAudioDevice); + + pulse->iface.Open = tsmf_pulse_open; + pulse->iface.SetFormat = tsmf_pulse_set_format; + pulse->iface.Play = tsmf_pulse_play; + pulse->iface.GetLatency = tsmf_pulse_get_latency; + pulse->iface.Flush = tsmf_pulse_flush; + pulse->iface.Free = tsmf_pulse_free; + + return (ITSMFAudioDevice*) pulse; +} + diff --git a/channels/drdynvc/tsmf/tsmf_audio.c b/channels/drdynvc/tsmf/tsmf_audio.c new file mode 100644 index 0000000..5a1a145 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_audio.c @@ -0,0 +1,80 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Audio Device Manager + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "tsmf_audio.h" + +static ITSMFAudioDevice* tsmf_load_audio_device_by_name(const char* name, const char* device) +{ + ITSMFAudioDevice* audio; + TSMF_AUDIO_DEVICE_ENTRY entry; + char* fullname; + + if (strrchr(name, '.') != NULL) + entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(name, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME); + else + { + fullname = xzalloc(strlen(name) + 6); + strcpy(fullname, "tsmf_"); + strcat(fullname, name); + entry = (TSMF_AUDIO_DEVICE_ENTRY) freerdp_load_plugin(fullname, TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME); + xfree(fullname); + } + if (entry == NULL) + { + return NULL; + } + + audio = entry(); + if (audio == NULL) + { + DEBUG_WARN("failed to call export function in %s", name); + return NULL; + } + if (!audio->Open(audio, device)) + { + audio->Free(audio); + audio = NULL; + } + return audio; +} + +ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device) +{ + ITSMFAudioDevice* audio; + + if (name) + { + audio = tsmf_load_audio_device_by_name(name, device); + } + else + { + audio = tsmf_load_audio_device_by_name("pulse", device); + if (!audio) + audio = tsmf_load_audio_device_by_name("alsa", device); + } + + return audio; +} + diff --git a/channels/drdynvc/tsmf/tsmf_audio.h b/channels/drdynvc/tsmf/tsmf_audio.h new file mode 100644 index 0000000..af00759 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_audio.h @@ -0,0 +1,49 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Audio Device Manager + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_AUDIO_H +#define __TSMF_AUDIO_H + +#include "drdynvc_types.h" + +typedef struct _ITSMFAudioDevice ITSMFAudioDevice; + +struct _ITSMFAudioDevice +{ + /* Open the audio device. */ + boolean (*Open) (ITSMFAudioDevice* audio, const char* device); + /* Set the audio data format. */ + boolean (*SetFormat) (ITSMFAudioDevice* audio, uint32 sample_rate, uint32 channels, uint32 bits_per_sample); + /* Play audio data. */ + boolean (*Play) (ITSMFAudioDevice* audio, uint8* data, uint32 data_size); + /* Get the latency of the last written sample, in 100ns */ + uint64 (*GetLatency) (ITSMFAudioDevice* audio); + /* Flush queued audio data */ + void (*Flush) (ITSMFAudioDevice* audio); + /* Free the audio device */ + void (*Free) (ITSMFAudioDevice* audio); +}; + +#define TSMF_AUDIO_DEVICE_EXPORT_FUNC_NAME "TSMFAudioDeviceEntry" +typedef ITSMFAudioDevice* (*TSMF_AUDIO_DEVICE_ENTRY) (void); + +ITSMFAudioDevice* tsmf_load_audio_device(const char* name, const char* device); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_codec.c b/channels/drdynvc/tsmf/tsmf_codec.c new file mode 100644 index 0000000..bd5a317 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_codec.c @@ -0,0 +1,407 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Codec + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "tsmf_constants.h" +#include "tsmf_types.h" + +#include "tsmf_codec.h" + +typedef struct _TSMFMediaTypeMap +{ + uint8 guid[16]; + const char* name; + int type; +} TSMFMediaTypeMap; + +static const TSMFMediaTypeMap tsmf_major_type_map[] = +{ + /* 73646976-0000-0010-8000-00AA00389B71 */ + { + { 0x76, 0x69, 0x64, 0x73, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIATYPE_Video", + TSMF_MAJOR_TYPE_VIDEO + }, + + /* 73647561-0000-0010-8000-00AA00389B71 */ + { + { 0x61, 0x75, 0x64, 0x73, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIATYPE_Audio", + TSMF_MAJOR_TYPE_AUDIO + }, + + { + { 0 }, + "Unknown", + TSMF_MAJOR_TYPE_UNKNOWN + } +}; + +static const TSMFMediaTypeMap tsmf_sub_type_map[] = +{ + /* 31435657-0000-0010-8000-00AA00389B71 */ + { + { 0x57, 0x56, 0x43, 0x31, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_WVC1", + TSMF_SUB_TYPE_WVC1 + }, + + /* 00000161-0000-0010-8000-00AA00389B71 */ + { + { 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_WMAudioV2", /* V7, V8 has the same GUID */ + TSMF_SUB_TYPE_WMA2 + }, + + /* 00000162-0000-0010-8000-00AA00389B71 */ + { + { 0x62, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_WMAudioV9", + TSMF_SUB_TYPE_WMA9 + }, + + /* 00000055-0000-0010-8000-00AA00389B71 */ + { + { 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_MP3", + TSMF_SUB_TYPE_MP3 + }, + + /* E06D802B-DB46-11CF-B4D1-00805F6CBBEA */ + { + { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA }, + "MEDIASUBTYPE_MPEG2_AUDIO", + TSMF_SUB_TYPE_MP2A + }, + + /* E06D8026-DB46-11CF-B4D1-00805F6CBBEA */ + { + { 0x26, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA }, + "MEDIASUBTYPE_MPEG2_VIDEO", + TSMF_SUB_TYPE_MP2V + }, + + /* 33564D57-0000-0010-8000-00AA00389B71 */ + { + { 0x57, 0x4D, 0x56, 0x33, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_WMV3", + TSMF_SUB_TYPE_WMV3 + }, + + /* 00001610-0000-0010-8000-00AA00389B71 */ + { + { 0x10, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_MPEG_HEAAC", + TSMF_SUB_TYPE_AAC + }, + + /* 34363248-0000-0010-8000-00AA00389B71 */ + { + { 0x48, 0x32, 0x36, 0x34, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_H264", + TSMF_SUB_TYPE_H264 + }, + + /* 31435641-0000-0010-8000-00AA00389B71 */ + { + { 0x41, 0x56, 0x43, 0x31, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 }, + "MEDIASUBTYPE_AVC1", + TSMF_SUB_TYPE_AVC1 + }, + + /* E06D802C-DB46-11CF-B4D1-00805F6CBBEA */ + { + { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA }, + "MEDIASUBTYPE_DOLBY_AC3", + TSMF_SUB_TYPE_AC3 + }, + + { + { 0 }, + "Unknown", + TSMF_SUB_TYPE_UNKNOWN + } + +}; + +static const TSMFMediaTypeMap tsmf_format_type_map[] = +{ + /* AED4AB2D-7326-43CB-9464-C879CAB9C43D */ + { + { 0x2D, 0xAB, 0xD4, 0xAE, 0x26, 0x73, 0xCB, 0x43, 0x94, 0x64, 0xC8, 0x79, 0xCA, 0xB9, 0xC4, 0x3D }, + "FORMAT_MFVideoFormat", + TSMF_FORMAT_TYPE_MFVIDEOFORMAT + }, + + /* 05589F81-C356-11CE-BF01-00AA0055595A */ + { + { 0x81, 0x9F, 0x58, 0x05, 0x56, 0xC3, 0xCE, 0x11, 0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A }, + "FORMAT_WaveFormatEx", + TSMF_FORMAT_TYPE_WAVEFORMATEX + }, + + /* E06D80E3-DB46-11CF-B4D1-00805F6CBBEA */ + { + { 0xE3, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA }, + "FORMAT_MPEG2_VIDEO", + TSMF_FORMAT_TYPE_MPEG2VIDEOINFO + }, + + /* F72A76A0-EB0A-11D0-ACE4-0000C0CC16BA */ + { + { 0xA0, 0x76, 0x2A, 0xF7, 0x0A, 0xEB, 0xD0, 0x11, 0xAC, 0xE4, 0x00, 0x00, 0xC0, 0xCC, 0x16, 0xBA }, + "FORMAT_VideoInfo2", + TSMF_FORMAT_TYPE_VIDEOINFO2 + }, + + { + { 0 }, + "Unknown", + TSMF_FORMAT_TYPE_UNKNOWN + } +}; + +static void tsmf_print_guid(const uint8* guid) +{ +#ifdef WITH_DEBUG_DVC + int i; + + for (i = 3; i >= 0; i--) + printf("%02X", guid[i]); + printf("-"); + for (i = 5; i >= 4; i--) + printf("%02X", guid[i]); + printf("-"); + for (i = 7; i >= 6; i--) + printf("%02X", guid[i]); + printf("-"); + for (i = 8; i < 16; i++) + { + printf("%02X", guid[i]); + if (i == 9) + printf("-"); + } + printf("\n"); +#endif +} + +/* http://msdn.microsoft.com/en-us/library/dd318229.aspx */ +static uint32 tsmf_codec_parse_BITMAPINFOHEADER(TS_AM_MEDIA_TYPE* mediatype, STREAM* s, boolean bypass) +{ + uint32 biSize; + uint32 biWidth; + uint32 biHeight; + + stream_read_uint32(s, biSize); + stream_read_uint32(s, biWidth); + stream_read_uint32(s, biHeight); + stream_seek(s, 28); + + if (mediatype->Width == 0) + mediatype->Width = biWidth; + if (mediatype->Height == 0) + mediatype->Height = biHeight; + /* Assume there will be no color table for video? */ + + if (bypass && biSize > 40) + stream_seek(s, biSize - 40); + + return (bypass ? biSize : 40); +} + +/* http://msdn.microsoft.com/en-us/library/dd407326.aspx */ +static uint32 tsmf_codec_parse_VIDEOINFOHEADER2(TS_AM_MEDIA_TYPE* mediatype, STREAM* s) +{ + uint64 AvgTimePerFrame; + + /* VIDEOINFOHEADER2.rcSource, RECT(LONG left, LONG top, LONG right, LONG bottom) */ + stream_seek_uint32(s); + stream_seek_uint32(s); + stream_read_uint32(s, mediatype->Width); + stream_read_uint32(s, mediatype->Height); + /* VIDEOINFOHEADER2.rcTarget */ + stream_seek(s, 16); + /* VIDEOINFOHEADER2.dwBitRate */ + stream_read_uint32(s, mediatype->BitRate); + /* VIDEOINFOHEADER2.dwBitErrorRate */ + stream_seek_uint32(s); + /* VIDEOINFOHEADER2.AvgTimePerFrame */ + stream_read_uint64(s, AvgTimePerFrame); + mediatype->SamplesPerSecond.Numerator = 1000000; + mediatype->SamplesPerSecond.Denominator = (int)(AvgTimePerFrame / 10LL); + /* Remaining fields before bmiHeader */ + stream_seek(s, 24); + + return 72; +} + +boolean tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, STREAM* s) +{ + int i; + uint32 cbFormat; + boolean ret = true; + + memset(mediatype, 0, sizeof(TS_AM_MEDIA_TYPE)); + + /* MajorType */ + DEBUG_DVC("MajorType:"); + tsmf_print_guid(stream_get_tail(s)); + for (i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++) + { + if (memcmp(tsmf_major_type_map[i].guid, stream_get_tail(s), 16) == 0) + break; + } + mediatype->MajorType = tsmf_major_type_map[i].type; + if (mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN) + ret = false; + DEBUG_DVC("MajorType %s", tsmf_major_type_map[i].name); + stream_seek(s, 16); + + /* SubType */ + DEBUG_DVC("SubType:"); + tsmf_print_guid(stream_get_tail(s)); + for (i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++) + { + if (memcmp(tsmf_sub_type_map[i].guid, stream_get_tail(s), 16) == 0) + break; + } + mediatype->SubType = tsmf_sub_type_map[i].type; + if (mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN) + ret = false; + DEBUG_DVC("SubType %s", tsmf_sub_type_map[i].name); + stream_seek(s, 16); + + /* bFixedSizeSamples, bTemporalCompression, SampleSize */ + stream_seek(s, 12); + + /* FormatType */ + DEBUG_DVC("FormatType:"); + tsmf_print_guid(stream_get_tail(s)); + for (i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++) + { + if (memcmp(tsmf_format_type_map[i].guid, stream_get_tail(s), 16) == 0) + break; + } + mediatype->FormatType = tsmf_format_type_map[i].type; + if (mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN) + ret = false; + DEBUG_DVC("FormatType %s", tsmf_format_type_map[i].name); + stream_seek(s, 16); + + /* cbFormat */ + stream_read_uint32(s, cbFormat); + DEBUG_DVC("cbFormat %d", cbFormat); + +#ifdef WITH_DEBUG_DVC + freerdp_hexdump(stream_get_tail(s), cbFormat); +#endif + + switch (mediatype->FormatType) + { + case TSMF_FORMAT_TYPE_MFVIDEOFORMAT: + /* http://msdn.microsoft.com/en-us/library/aa473808.aspx */ + + stream_seek(s, 8); /* dwSize and ? */ + stream_read_uint32(s, mediatype->Width); /* videoInfo.dwWidth */ + stream_read_uint32(s, mediatype->Height); /* videoInfo.dwHeight */ + stream_seek(s, 32); + /* videoInfo.FramesPerSecond */ + stream_read_uint32(s, mediatype->SamplesPerSecond.Numerator); + stream_read_uint32(s, mediatype->SamplesPerSecond.Denominator); + stream_seek(s, 80); + stream_read_uint32(s, mediatype->BitRate); /* compressedInfo.AvgBitrate */ + stream_seek(s, 36); + + if (cbFormat > 176) + { + mediatype->ExtraDataSize = cbFormat - 176; + mediatype->ExtraData = stream_get_tail(s); + } + break; + + case TSMF_FORMAT_TYPE_WAVEFORMATEX: + /* http://msdn.microsoft.com/en-us/library/dd757720.aspx */ + + stream_seek_uint16(s); + stream_read_uint16(s, mediatype->Channels); + stream_read_uint32(s, mediatype->SamplesPerSecond.Numerator); + mediatype->SamplesPerSecond.Denominator = 1; + stream_read_uint32(s, mediatype->BitRate); + mediatype->BitRate *= 8; + stream_read_uint16(s, mediatype->BlockAlign); + stream_read_uint16(s, mediatype->BitsPerSample); + stream_read_uint16(s, mediatype->ExtraDataSize); + if (mediatype->ExtraDataSize > 0) + mediatype->ExtraData = stream_get_tail(s); + + break; + + case TSMF_FORMAT_TYPE_MPEG2VIDEOINFO: + /* http://msdn.microsoft.com/en-us/library/dd390707.aspx */ + + i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s); + i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, true); + if (cbFormat > i) + { + mediatype->ExtraDataSize = cbFormat - i; + mediatype->ExtraData = stream_get_tail(s); + } + break; + + case TSMF_FORMAT_TYPE_VIDEOINFO2: + i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s); + i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, false); + if (cbFormat > i) + { + mediatype->ExtraDataSize = cbFormat - i; + mediatype->ExtraData = stream_get_tail(s); + } + break; + + default: + break; + } + + if (mediatype->SamplesPerSecond.Numerator == 0) + mediatype->SamplesPerSecond.Numerator = 1; + if (mediatype->SamplesPerSecond.Denominator == 0) + mediatype->SamplesPerSecond.Denominator = 1; + + return ret; +} + +boolean tsmf_codec_check_media_type(STREAM* s) +{ + uint8* m; + boolean ret; + TS_AM_MEDIA_TYPE mediatype; + + stream_get_mark(s, m); + ret = tsmf_codec_parse_media_type(&mediatype, s); + stream_set_mark(s, m); + + return ret; +} + diff --git a/channels/drdynvc/tsmf/tsmf_codec.h b/channels/drdynvc/tsmf/tsmf_codec.h new file mode 100644 index 0000000..eb6bbea --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_codec.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Codec + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_CODEC +#define __TSMF_CODEC + +#include "tsmf_types.h" + +boolean tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, STREAM* s); +boolean tsmf_codec_check_media_type(STREAM* s); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_constants.h b/channels/drdynvc/tsmf/tsmf_constants.h new file mode 100644 index 0000000..e836dd7 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_constants.h @@ -0,0 +1,120 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Constants + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_CONSTANTS_H +#define __TSMF_CONSTANTS_H + +#define GUID_SIZE 16 +#define TSMF_BUFFER_PADDING_SIZE 8 + +/* Interface IDs defined in [MS-RDPEV]. There's no constant names in the MS + documentation, so we create them on our own. */ +#define TSMF_INTERFACE_DEFAULT 0x00000000 +#define TSMF_INTERFACE_CLIENT_NOTIFICATIONS 0x00000001 +#define TSMF_INTERFACE_CAPABILITIES 0x00000002 + +/* Interface ID Mask */ +#define STREAM_ID_STUB 0x80000000 +#define STREAM_ID_PROXY 0x40000000 +#define STREAM_ID_NONE 0x00000000 + +/* Functon ID */ +/* Common IDs for all interfaces are as follows. */ +#define RIMCALL_RELEASE 0x00000001 +#define RIMCALL_QUERYINTERFACE 0x00000002 +/* Capabilities Negotiator Interface IDs are as follows. */ +#define RIM_EXCHANGE_CAPABILITY_REQUEST 0x00000100 +/* The Client Notifications Interface ID is as follows. */ +#define PLAYBACK_ACK 0x00000100 +#define CLIENT_EVENT_NOTIFICATION 0x00000101 +/* Server Data Interface IDs are as follows. */ +#define EXCHANGE_CAPABILITIES_REQ 0x00000100 +#define SET_CHANNEL_PARAMS 0x00000101 +#define ADD_STREAM 0x00000102 +#define ON_SAMPLE 0x00000103 +#define SET_VIDEO_WINDOW 0x00000104 +#define ON_NEW_PRESENTATION 0x00000105 +#define SHUTDOWN_PRESENTATION_REQ 0x00000106 +#define SET_TOPOLOGY_REQ 0x00000107 +#define CHECK_FORMAT_SUPPORT_REQ 0x00000108 +#define ON_PLAYBACK_STARTED 0x00000109 +#define ON_PLAYBACK_PAUSED 0x0000010a +#define ON_PLAYBACK_STOPPED 0x0000010b +#define ON_PLAYBACK_RESTARTED 0x0000010c +#define ON_PLAYBACK_RATE_CHANGED 0x0000010d +#define ON_FLUSH 0x0000010e +#define ON_STREAM_VOLUME 0x0000010f +#define ON_CHANNEL_VOLUME 0x00000110 +#define ON_END_OF_STREAM 0x00000111 +#define SET_ALLOCATOR 0x00000112 +#define NOTIFY_PREROLL 0x00000113 +#define UPDATE_GEOMETRY_INFO 0x00000114 +#define REMOVE_STREAM 0x00000115 + +/* Supported platform */ +#define MMREDIR_CAPABILITY_PLATFORM_MF 0x00000001 +#define MMREDIR_CAPABILITY_PLATFORM_DSHOW 0x00000002 +#define MMREDIR_CAPABILITY_PLATFORM_OTHER 0x00000004 + +/* TSMM_CLIENT_EVENT Constants */ +#define TSMM_CLIENT_EVENT_ENDOFSTREAM 0x0064 +#define TSMM_CLIENT_EVENT_STOP_COMPLETED 0x00C8 +#define TSMM_CLIENT_EVENT_START_COMPLETED 0x00C9 +#define TSMM_CLIENT_EVENT_MONITORCHANGED 0x012C + +/* TS_MM_DATA_SAMPLE.SampleExtensions */ +#define TSMM_SAMPLE_EXT_CLEANPOINT 0x00000001 +#define TSMM_SAMPLE_EXT_DISCONTINUITY 0x00000002 +#define TSMM_SAMPLE_EXT_INTERLACED 0x00000004 +#define TSMM_SAMPLE_EXT_BOTTOMFIELDFIRST 0x00000008 +#define TSMM_SAMPLE_EXT_REPEATFIELDFIRST 0x00000010 +#define TSMM_SAMPLE_EXT_SINGLEFIELD 0x00000020 +#define TSMM_SAMPLE_EXT_DERIVEDFROMTOPFIELD 0x00000040 +#define TSMM_SAMPLE_EXT_HAS_NO_TIMESTAMPS 0x00000080 +#define TSMM_SAMPLE_EXT_RELATIVE_TIMESTAMPS 0x00000100 +#define TSMM_SAMPLE_EXT_ABSOLUTE_TIMESTAMPS 0x00000200 + +/* MajorType */ +#define TSMF_MAJOR_TYPE_UNKNOWN 0 +#define TSMF_MAJOR_TYPE_VIDEO 1 +#define TSMF_MAJOR_TYPE_AUDIO 2 + +/* SubType */ +#define TSMF_SUB_TYPE_UNKNOWN 0 +#define TSMF_SUB_TYPE_WVC1 1 +#define TSMF_SUB_TYPE_WMA2 2 +#define TSMF_SUB_TYPE_WMA9 3 +#define TSMF_SUB_TYPE_MP3 4 +#define TSMF_SUB_TYPE_MP2A 5 +#define TSMF_SUB_TYPE_MP2V 6 +#define TSMF_SUB_TYPE_WMV3 7 +#define TSMF_SUB_TYPE_AAC 8 +#define TSMF_SUB_TYPE_H264 9 +#define TSMF_SUB_TYPE_AVC1 10 +#define TSMF_SUB_TYPE_AC3 11 + +/* FormatType */ +#define TSMF_FORMAT_TYPE_UNKNOWN 0 +#define TSMF_FORMAT_TYPE_MFVIDEOFORMAT 1 +#define TSMF_FORMAT_TYPE_WAVEFORMATEX 2 +#define TSMF_FORMAT_TYPE_MPEG2VIDEOINFO 3 +#define TSMF_FORMAT_TYPE_VIDEOINFO2 4 + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_decoder.c b/channels/drdynvc/tsmf/tsmf_decoder.c new file mode 100644 index 0000000..db31c02 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_decoder.c @@ -0,0 +1,81 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Decoder + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "tsmf_types.h" +#include "tsmf_constants.h" +#include "tsmf_decoder.h" + +static ITSMFDecoder* tsmf_load_decoder_by_name(const char* name, TS_AM_MEDIA_TYPE* media_type) +{ + ITSMFDecoder* decoder; + TSMF_DECODER_ENTRY entry; + char* fullname; + + if (strrchr(name, '.') != NULL) + entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(name, TSMF_DECODER_EXPORT_FUNC_NAME); + else + { + fullname = xzalloc(strlen(name) + 6); + strcpy(fullname, "tsmf_"); + strcat(fullname, name); + entry = (TSMF_DECODER_ENTRY) freerdp_load_plugin(fullname, TSMF_DECODER_EXPORT_FUNC_NAME); + xfree(fullname); + } + if (entry == NULL) + { + return NULL; + } + + decoder = entry(); + if (decoder == NULL) + { + DEBUG_WARN("failed to call export function in %s", name); + return NULL; + } + if (!decoder->SetFormat(decoder, media_type)) + { + decoder->Free(decoder); + decoder = NULL; + } + return decoder; +} + +ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type) +{ + ITSMFDecoder* decoder; + + if (name) + { + decoder = tsmf_load_decoder_by_name(name, media_type); + } + else + { + decoder = tsmf_load_decoder_by_name("ffmpeg", media_type); + } + + return decoder; +} + diff --git a/channels/drdynvc/tsmf/tsmf_decoder.h b/channels/drdynvc/tsmf/tsmf_decoder.h new file mode 100644 index 0000000..2aee84f --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_decoder.h @@ -0,0 +1,50 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Decoder + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_DECODER_H +#define __TSMF_DECODER_H + +#include "drdynvc_types.h" +#include "tsmf_types.h" + +typedef struct _ITSMFDecoder ITSMFDecoder; + +struct _ITSMFDecoder +{ + /* Set the decoder format. Return true if supported. */ + boolean (*SetFormat) (ITSMFDecoder* decoder, TS_AM_MEDIA_TYPE* media_type); + /* Decode a sample. */ + boolean (*Decode) (ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions); + /* Get the decoded data */ + uint8* (*GetDecodedData) (ITSMFDecoder* decoder, uint32* size); + /* Get the pixel format of decoded video frame */ + uint32 (*GetDecodedFormat) (ITSMFDecoder* decoder); + /* Get the width and height of decoded video frame */ + boolean (*GetDecodedDimension) (ITSMFDecoder* decoder, uint32* width, uint32* height); + /* Free the decoder */ + void (*Free) (ITSMFDecoder* decoder); +}; + +#define TSMF_DECODER_EXPORT_FUNC_NAME "TSMFDecoderEntry" +typedef ITSMFDecoder* (*TSMF_DECODER_ENTRY) (void); + +ITSMFDecoder* tsmf_load_decoder(const char* name, TS_AM_MEDIA_TYPE* media_type); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_ifman.c b/channels/drdynvc/tsmf/tsmf_ifman.c new file mode 100644 index 0000000..10d351d --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_ifman.c @@ -0,0 +1,478 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Interface Manipulation + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "tsmf_constants.h" +#include "tsmf_media.h" +#include "tsmf_codec.h" + +#include "tsmf_ifman.h" + +int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman) +{ + uint32 CapabilityValue; + + stream_read_uint32(ifman->input, CapabilityValue); + DEBUG_DVC("server CapabilityValue %d", CapabilityValue); + + stream_check_size(ifman->output, 8); + stream_write_uint32(ifman->output, 1); /* CapabilityValue */ + stream_write_uint32(ifman->output, 0); /* Result */ + + return 0; +} + +int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) +{ + uint32 i; + uint32 v; + uint32 pos; + uint32 CapabilityType; + uint32 cbCapabilityLength; + uint32 numHostCapabilities; + + pos = stream_get_pos(ifman->output); + stream_check_size(ifman->output, ifman->input_size + 4); + stream_copy(ifman->output, ifman->input, ifman->input_size); + + stream_set_pos(ifman->output, pos); + stream_read_uint32(ifman->output, numHostCapabilities); + for (i = 0; i < numHostCapabilities; i++) + { + stream_read_uint32(ifman->output, CapabilityType); + stream_read_uint32(ifman->output, cbCapabilityLength); + pos = stream_get_pos(ifman->output); + switch (CapabilityType) + { + case 1: /* Protocol version request */ + stream_read_uint32(ifman->output, v); + DEBUG_DVC("server protocol version %d", v); + break; + case 2: /* Supported platform */ + stream_peek_uint32(ifman->output, v); + DEBUG_DVC("server supported platform %d", v); + /* Claim that we support both MF and DShow platforms. */ + stream_write_uint32(ifman->output, + MMREDIR_CAPABILITY_PLATFORM_MF | MMREDIR_CAPABILITY_PLATFORM_DSHOW); + break; + default: + DEBUG_WARN("unknown capability type %d", CapabilityType); + break; + } + stream_set_pos(ifman->output, pos + cbCapabilityLength); + } + stream_write_uint32(ifman->output, 0); /* Result */ + + ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; + + return 0; +} + +int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman) +{ + uint32 numMediaType; + uint32 PlatformCookie; + uint32 FormatSupported = 1; + + stream_read_uint32(ifman->input, PlatformCookie); + stream_seek_uint32(ifman->input); /* NoRolloverFlags (4 bytes) */ + stream_read_uint32(ifman->input, numMediaType); + + DEBUG_DVC("PlatformCookie %d numMediaType %d", PlatformCookie, numMediaType); + + if (!tsmf_codec_check_media_type(ifman->input)) + FormatSupported = 0; + + if (FormatSupported) + DEBUG_DVC("format ok."); + + stream_check_size(ifman->output, 12); + stream_write_uint32(ifman->output, FormatSupported); + stream_write_uint32(ifman->output, PlatformCookie); + stream_write_uint32(ifman->output, 0); /* Result */ + + ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; + + return 0; +} + +int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman) +{ + int error = 0; + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_new(stream_get_tail(ifman->input), ifman->channel_callback); + if (presentation == NULL) + error = 1; + tsmf_presentation_set_audio_device(presentation, ifman->audio_name, ifman->audio_device); + ifman->output_pending = true; + return error; +} + +int tsmf_ifman_add_stream(TSMF_IFMAN* ifman) +{ + uint32 StreamId; + int error = 0; + TSMF_STREAM* stream; + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + stream_seek(ifman->input, 16); + + if (presentation == NULL) + error = 1; + else + { + stream_read_uint32(ifman->input, StreamId); + stream_seek_uint32(ifman->input); /* numMediaType */ + stream = tsmf_stream_new(presentation, StreamId); + if (stream) + tsmf_stream_set_format(stream, ifman->decoder_name, ifman->input); + } + ifman->output_pending = true; + return error; +} + +int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + + stream_check_size(ifman->output, 8); + stream_write_uint32(ifman->output, 1); /* TopologyReady */ + stream_write_uint32(ifman->output, 0); /* Result */ + ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; + return 0; +} + +int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman) +{ + int error = 0; + uint32 StreamId; + TSMF_STREAM* stream; + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + stream_seek(ifman->input, 16); + + if (presentation == NULL) + error = 1; + else + { + stream_read_uint32(ifman->input, StreamId); + stream = tsmf_stream_find_by_id(presentation, StreamId); + if (stream) + tsmf_stream_free(stream); + else + error = 1; + } + ifman->output_pending = true; + return error; +} + +int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) + tsmf_presentation_free(presentation); + + stream_check_size(ifman->output, 4); + stream_write_uint32(ifman->output, 0); /* Result */ + ifman->output_interface_id = TSMF_INTERFACE_DEFAULT | STREAM_ID_STUB; + return 0; +} + +int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_set_video_window(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + uint32 numGeometryInfo; + uint32 Left; + uint32 Top; + uint32 Width; + uint32 Height; + uint32 cbVisibleRect; + RDP_RECT* rects = NULL; + int num_rects = 0; + int error = 0; + int i; + int pos; + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + stream_seek(ifman->input, 16); + + stream_read_uint32(ifman->input, numGeometryInfo); + pos = stream_get_pos(ifman->input); + + stream_seek(ifman->input, 12); /* VideoWindowId (8 bytes), VideoWindowState (4 bytes) */ + stream_read_uint32(ifman->input, Width); + stream_read_uint32(ifman->input, Height); + stream_read_uint32(ifman->input, Left); + stream_read_uint32(ifman->input, Top); + + stream_set_pos(ifman->input, pos + numGeometryInfo); + stream_read_uint32(ifman->input, cbVisibleRect); + num_rects = cbVisibleRect / 16; + + DEBUG_DVC("numGeometryInfo %d Width %d Height %d Left %d Top %d cbVisibleRect %d num_rects %d", + numGeometryInfo, Width, Height, Left, Top, cbVisibleRect, num_rects); + + if (presentation == NULL) + error = 1; + else + { + if (num_rects > 0) + { + rects = (RDP_RECT*) xzalloc(sizeof(RDP_RECT) * num_rects); + for (i = 0; i < num_rects; i++) + { + stream_read_uint16(ifman->input, rects[i].y); /* Top */ + stream_seek_uint16(ifman->input); + stream_read_uint16(ifman->input, rects[i].x); /* Left */ + stream_seek_uint16(ifman->input); + stream_read_uint16(ifman->input, rects[i].height); /* Bottom */ + stream_seek_uint16(ifman->input); + stream_read_uint16(ifman->input, rects[i].width); /* Right */ + stream_seek_uint16(ifman->input); + rects[i].width -= rects[i].x; + rects[i].height -= rects[i].y; + + DEBUG_DVC("rect %d: %d %d %d %d", i, + rects[i].x, rects[i].y, rects[i].width, rects[i].height); + } + } + tsmf_presentation_set_geometry_info(presentation, Left, Top, Width, Height, num_rects, rects); + } + ifman->output_pending = true; + return error; +} + +int tsmf_ifman_set_allocator(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_sample(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + TSMF_STREAM* stream; + uint32 StreamId; + uint64 SampleStartTime; + uint64 SampleEndTime; + uint64 ThrottleDuration; + uint32 SampleExtensions; + uint32 cbData; + + stream_seek(ifman->input, 16); + stream_read_uint32(ifman->input, StreamId); + stream_seek_uint32(ifman->input); /* numSample */ + stream_read_uint64(ifman->input, SampleStartTime); + stream_read_uint64(ifman->input, SampleEndTime); + stream_read_uint64(ifman->input, ThrottleDuration); + stream_seek_uint32(ifman->input); /* SampleFlags */ + stream_read_uint32(ifman->input, SampleExtensions); + stream_read_uint32(ifman->input, cbData); + + DEBUG_DVC("MessageId %d StreamId %d SampleStartTime %d SampleEndTime %d " + "ThrottleDuration %d SampleExtensions %d cbData %d", + ifman->message_id, StreamId, (int)SampleStartTime, (int)SampleEndTime, + (int)ThrottleDuration, SampleExtensions, cbData); + + presentation = tsmf_presentation_find_by_id(ifman->presentation_id); + if (presentation == NULL) + { + DEBUG_WARN("unknown presentation id"); + return 1; + } + stream = tsmf_stream_find_by_id(presentation, StreamId); + if (stream == NULL) + { + DEBUG_WARN("unknown stream id"); + return 1; + } + tsmf_stream_push_sample(stream, ifman->channel_callback, + ifman->message_id, SampleStartTime, SampleEndTime, ThrottleDuration, SampleExtensions, + cbData, stream_get_tail(ifman->input)); + + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_flush(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + uint32 StreamId; + + stream_seek(ifman->input, 16); + stream_read_uint32(ifman->input, StreamId); + DEBUG_DVC("StreamId %d", StreamId); + + presentation = tsmf_presentation_find_by_id(ifman->presentation_id); + if (presentation == NULL) + { + DEBUG_WARN("unknown presentation id"); + return 1; + } + + tsmf_presentation_flush(presentation); + + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + TSMF_STREAM* stream; + uint32 StreamId; + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + stream_seek(ifman->input, 16); + stream_read_uint32(ifman->input, StreamId); + stream = tsmf_stream_find_by_id(presentation, StreamId); + tsmf_stream_end(stream); + + DEBUG_DVC("StreamId %d", StreamId); + + stream_check_size(ifman->output, 16); + stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + stream_write_uint32(ifman->output, StreamId); /* StreamId */ + stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_ENDOFSTREAM); /* EventId */ + stream_write_uint32(ifman->output, 0); /* cbData */ + ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; + + return 0; +} + +int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) + tsmf_presentation_start(presentation); + else + DEBUG_WARN("unknown presentation id"); + + stream_check_size(ifman->output, 16); + stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + stream_write_uint32(ifman->output, 0); /* StreamId */ + stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_START_COMPLETED); /* EventId */ + stream_write_uint32(ifman->output, 0); /* cbData */ + ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; + + return 0; +} + +int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman) +{ + DEBUG_DVC(""); + ifman->output_pending = true; + return 0; +} + +int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman) +{ + TSMF_PRESENTATION* presentation; + + DEBUG_DVC(""); + + presentation = tsmf_presentation_find_by_id(stream_get_tail(ifman->input)); + if (presentation) + tsmf_presentation_stop(presentation); + else + DEBUG_WARN("unknown presentation id"); + + stream_check_size(ifman->output, 16); + stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + stream_write_uint32(ifman->output, 0); /* StreamId */ + stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_STOP_COMPLETED); /* EventId */ + stream_write_uint32(ifman->output, 0); /* cbData */ + ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; + + return 0; +} + +int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN * ifman) +{ + DEBUG_DVC(""); + + stream_check_size(ifman->output, 16); + stream_write_uint32(ifman->output, CLIENT_EVENT_NOTIFICATION); /* FunctionId */ + stream_write_uint32(ifman->output, 0); /* StreamId */ + stream_write_uint32(ifman->output, TSMM_CLIENT_EVENT_MONITORCHANGED); /* EventId */ + stream_write_uint32(ifman->output, 0); /* cbData */ + ifman->output_interface_id = TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY; + + return 0; +} + diff --git a/channels/drdynvc/tsmf/tsmf_ifman.h b/channels/drdynvc/tsmf/tsmf_ifman.h new file mode 100644 index 0000000..7a68c06 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_ifman.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Interface Manipulation + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_IFMAN_H +#define __TSMF_IFMAN_H + +typedef struct _TSMF_IFMAN TSMF_IFMAN; +struct _TSMF_IFMAN +{ + IWTSVirtualChannelCallback* channel_callback; + const char* decoder_name; + const char* audio_name; + const char* audio_device; + uint8 presentation_id[16]; + uint32 stream_id; + uint32 message_id; + + STREAM* input; + uint32 input_size; + STREAM* output; + boolean output_pending; + uint32 output_interface_id; +}; + +int tsmf_ifman_rim_exchange_capability_request(TSMF_IFMAN* ifman); +int tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman); +int tsmf_ifman_check_format_support_request(TSMF_IFMAN* ifman); +int tsmf_ifman_on_new_presentation(TSMF_IFMAN* ifman); +int tsmf_ifman_add_stream(TSMF_IFMAN* ifman); +int tsmf_ifman_set_topology_request(TSMF_IFMAN* ifman); +int tsmf_ifman_remove_stream(TSMF_IFMAN* ifman); +int tsmf_ifman_shutdown_presentation(TSMF_IFMAN* ifman); +int tsmf_ifman_on_stream_volume(TSMF_IFMAN* ifman); +int tsmf_ifman_on_channel_volume(TSMF_IFMAN* ifman); +int tsmf_ifman_set_video_window(TSMF_IFMAN* ifman); +int tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman); +int tsmf_ifman_set_allocator(TSMF_IFMAN* ifman); +int tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman); +int tsmf_ifman_on_sample(TSMF_IFMAN* ifman); +int tsmf_ifman_on_flush(TSMF_IFMAN* ifman); +int tsmf_ifman_on_end_of_stream(TSMF_IFMAN* ifman); +int tsmf_ifman_on_playback_started(TSMF_IFMAN* ifman); +int tsmf_ifman_on_playback_paused(TSMF_IFMAN* ifman); +int tsmf_ifman_on_playback_restarted(TSMF_IFMAN* ifman); +int tsmf_ifman_on_playback_stopped(TSMF_IFMAN* ifman); +int tsmf_ifman_on_playback_rate_changed(TSMF_IFMAN* ifman); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_main.c b/channels/drdynvc/tsmf/tsmf_main.c new file mode 100644 index 0000000..e0c944d --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_main.c @@ -0,0 +1,448 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "tsmf_constants.h" +#include "tsmf_ifman.h" +#include "tsmf_media.h" + +#include "tsmf_main.h" + +typedef struct _TSMF_LISTENER_CALLBACK TSMF_LISTENER_CALLBACK; + +typedef struct _TSMF_CHANNEL_CALLBACK TSMF_CHANNEL_CALLBACK; + +typedef struct _TSMF_PLUGIN TSMF_PLUGIN; + +struct _TSMF_LISTENER_CALLBACK +{ + IWTSListenerCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; +}; + +struct _TSMF_CHANNEL_CALLBACK +{ + IWTSVirtualChannelCallback iface; + + IWTSPlugin* plugin; + IWTSVirtualChannelManager* channel_mgr; + IWTSVirtualChannel* channel; + + uint8 presentation_id[16]; + uint32 stream_id; +}; + +struct _TSMF_PLUGIN +{ + IWTSPlugin iface; + + TSMF_LISTENER_CALLBACK* listener_callback; + + const char* decoder_name; + const char* audio_name; + const char* audio_device; +}; + +void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, + uint32 message_id, uint64 duration, uint32 data_size) +{ + STREAM* s; + int error; + TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; + + s = stream_new(32); + stream_write_uint32(s, TSMF_INTERFACE_CLIENT_NOTIFICATIONS | STREAM_ID_PROXY); + stream_write_uint32(s, message_id); + stream_write_uint32(s, PLAYBACK_ACK); /* FunctionId */ + stream_write_uint32(s, callback->stream_id); /* StreamId */ + stream_write_uint64(s, duration); /* DataDuration */ + stream_write_uint64(s, data_size); /* cbData */ + + DEBUG_DVC("response size %d", stream_get_length(s)); + error = callback->channel->Write(callback->channel, stream_get_length(s), stream_get_head(s), NULL); + if (error) + { + DEBUG_WARN("response error %d", error); + } + stream_free(s); +} + +boolean tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, + RDP_EVENT* event) +{ + int error; + TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; + + error = callback->channel_mgr->PushEvent(callback->channel_mgr, event); + if (error) + { + DEBUG_WARN("response error %d", error); + return false; + } + return true; +} + +static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, + uint32 cbSize, + uint8* pBuffer) +{ + int length; + STREAM* input; + STREAM* output; + int error = -1; + TSMF_IFMAN ifman; + uint32 MessageId; + uint32 FunctionId; + uint32 InterfaceId; + TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; + + /* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */ + if (cbSize < 12) + { + DEBUG_WARN("invalid size. cbSize=%d", cbSize); + return 1; + } + input = stream_new(0); + stream_attach(input, (uint8*) pBuffer, cbSize); + output = stream_new(256); + stream_seek(output, 8); + + stream_read_uint32(input, InterfaceId); + stream_read_uint32(input, MessageId); + stream_read_uint32(input, FunctionId); + DEBUG_DVC("cbSize=%d InterfaceId=0x%X MessageId=0x%X FunctionId=0x%X", + cbSize, InterfaceId, MessageId, FunctionId); + + memset(&ifman, 0, sizeof(TSMF_IFMAN)); + ifman.channel_callback = pChannelCallback; + ifman.decoder_name = ((TSMF_PLUGIN*) callback->plugin)->decoder_name; + ifman.audio_name = ((TSMF_PLUGIN*) callback->plugin)->audio_name; + ifman.audio_device = ((TSMF_PLUGIN*) callback->plugin)->audio_device; + memcpy(ifman.presentation_id, callback->presentation_id, 16); + ifman.stream_id = callback->stream_id; + ifman.message_id = MessageId; + ifman.input = input; + ifman.input_size = cbSize - 12; + ifman.output = output; + ifman.output_pending = false; + ifman.output_interface_id = InterfaceId; + + switch (InterfaceId) + { + case TSMF_INTERFACE_CAPABILITIES | STREAM_ID_NONE: + + switch (FunctionId) + { + case RIM_EXCHANGE_CAPABILITY_REQUEST: + error = tsmf_ifman_rim_exchange_capability_request(&ifman); + break; + + default: + break; + } + break; + + case TSMF_INTERFACE_DEFAULT | STREAM_ID_PROXY: + + switch (FunctionId) + { + case SET_CHANNEL_PARAMS: + memcpy(callback->presentation_id, stream_get_tail(input), 16); + stream_seek(input, 16); + stream_read_uint32(input, callback->stream_id); + DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id); + ifman.output_pending = true; + error = 0; + break; + + case EXCHANGE_CAPABILITIES_REQ: + error = tsmf_ifman_exchange_capability_request(&ifman); + break; + + case CHECK_FORMAT_SUPPORT_REQ: + error = tsmf_ifman_check_format_support_request(&ifman); + break; + + case ON_NEW_PRESENTATION: + error = tsmf_ifman_on_new_presentation(&ifman); + break; + + case ADD_STREAM: + error = tsmf_ifman_add_stream(&ifman); + break; + + case SET_TOPOLOGY_REQ: + error = tsmf_ifman_set_topology_request(&ifman); + break; + + case REMOVE_STREAM: + error = tsmf_ifman_remove_stream(&ifman); + break; + + case SHUTDOWN_PRESENTATION_REQ: + error = tsmf_ifman_shutdown_presentation(&ifman); + break; + + case ON_STREAM_VOLUME: + error = tsmf_ifman_on_stream_volume(&ifman); + break; + + case ON_CHANNEL_VOLUME: + error = tsmf_ifman_on_channel_volume(&ifman); + break; + + case SET_VIDEO_WINDOW: + error = tsmf_ifman_set_video_window(&ifman); + break; + + case UPDATE_GEOMETRY_INFO: + error = tsmf_ifman_update_geometry_info(&ifman); + break; + + case SET_ALLOCATOR: + error = tsmf_ifman_set_allocator(&ifman); + break; + + case NOTIFY_PREROLL: + error = tsmf_ifman_notify_preroll(&ifman); + break; + + case ON_SAMPLE: + error = tsmf_ifman_on_sample(&ifman); + break; + + case ON_FLUSH: + error = tsmf_ifman_on_flush(&ifman); + break; + + case ON_END_OF_STREAM: + error = tsmf_ifman_on_end_of_stream(&ifman); + break; + + case ON_PLAYBACK_STARTED: + error = tsmf_ifman_on_playback_started(&ifman); + break; + + case ON_PLAYBACK_PAUSED: + error = tsmf_ifman_on_playback_paused(&ifman); + break; + + case ON_PLAYBACK_RESTARTED: + error = tsmf_ifman_on_playback_restarted(&ifman); + break; + + case ON_PLAYBACK_STOPPED: + error = tsmf_ifman_on_playback_stopped(&ifman); + break; + + case ON_PLAYBACK_RATE_CHANGED: + error = tsmf_ifman_on_playback_rate_changed(&ifman); + break; + + default: + break; + } + break; + + default: + break; + } + + stream_detach(input); + stream_free(input); + input = NULL; + ifman.input = NULL; + + if (error == -1) + { + switch (FunctionId) + { + case RIMCALL_RELEASE: + /* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE) + This message does not require a reply. */ + error = 0; + ifman.output_pending = 1; + break; + + case RIMCALL_QUERYINTERFACE: + /* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP) + This message is not supported in this channel. */ + error = 0; + break; + } + + if (error == -1) + { + DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.", + InterfaceId, FunctionId); + /* When a request is not implemented we return empty response indicating error */ + } + error = 0; + } + + if (error == 0 && !ifman.output_pending) + { + /* Response packet does not have FunctionId */ + length = stream_get_length(output); + stream_set_pos(output, 0); + stream_write_uint32(output, ifman.output_interface_id); + stream_write_uint32(output, MessageId); + + DEBUG_DVC("response size %d", length); + error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL); + if (error) + { + DEBUG_WARN("response error %d", error); + } + } + + stream_free(output); + + return error; +} + +static int tsmf_on_close(IWTSVirtualChannelCallback* pChannelCallback) +{ + TSMF_STREAM* stream; + TSMF_PRESENTATION* presentation; + TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; + + DEBUG_DVC(""); + + if (callback->stream_id) + { + presentation = tsmf_presentation_find_by_id(callback->presentation_id); + if (presentation) + { + stream = tsmf_stream_find_by_id(presentation, callback->stream_id); + if (stream) + tsmf_stream_free(stream); + } + } + xfree(pChannelCallback); + + return 0; +} + +static int tsmf_on_new_channel_connection(IWTSListenerCallback* pListenerCallback, + IWTSVirtualChannel* pChannel, + uint8* Data, + int* pbAccept, + IWTSVirtualChannelCallback** ppCallback) +{ + TSMF_CHANNEL_CALLBACK* callback; + TSMF_LISTENER_CALLBACK* listener_callback = (TSMF_LISTENER_CALLBACK*) pListenerCallback; + + DEBUG_DVC(""); + + callback = xnew(TSMF_CHANNEL_CALLBACK); + callback->iface.OnDataReceived = tsmf_on_data_received; + callback->iface.OnClose = tsmf_on_close; + callback->plugin = listener_callback->plugin; + callback->channel_mgr = listener_callback->channel_mgr; + callback->channel = pChannel; + *ppCallback = (IWTSVirtualChannelCallback*) callback; + + return 0; +} + +static int tsmf_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr) +{ + TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin; + + DEBUG_DVC(""); + + tsmf->listener_callback = xnew(TSMF_LISTENER_CALLBACK); + tsmf->listener_callback->iface.OnNewChannelConnection = tsmf_on_new_channel_connection; + tsmf->listener_callback->plugin = pPlugin; + tsmf->listener_callback->channel_mgr = pChannelMgr; + return pChannelMgr->CreateListener(pChannelMgr, "TSMF", 0, + (IWTSListenerCallback*) tsmf->listener_callback, NULL); +} + +static int tsmf_plugin_terminated(IWTSPlugin* pPlugin) +{ + TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin; + + DEBUG_DVC(""); + + if (tsmf->listener_callback) + xfree(tsmf->listener_callback); + xfree(tsmf); + + return 0; +} + +static void tsmf_process_plugin_data(IWTSPlugin* pPlugin, RDP_PLUGIN_DATA* data) +{ + TSMF_PLUGIN* tsmf = (TSMF_PLUGIN*) pPlugin; + + while (data && data->size > 0) + { + if (data->data[0] && ( strcmp((char*)data->data[0], "tsmf") == 0 || strstr((char*)data->data[0], "/tsmf.") != NULL) ) + { + if (data->data[1] && strcmp((char*)data->data[1], "decoder") == 0) + { + tsmf->decoder_name = data->data[2]; + } + else if (data->data[1] && strcmp((char*)data->data[1], "audio") == 0) + { + tsmf->audio_name = data->data[2]; + tsmf->audio_device = data->data[3]; + } + } + + data = (RDP_PLUGIN_DATA*)(((void*)data) + data->size); + } +} + +int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints) +{ + TSMF_PLUGIN * tsmf; + int error = 0; + + tsmf = (TSMF_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "tsmf"); + if (tsmf == NULL) + { + tsmf = xnew(TSMF_PLUGIN); + + tsmf->iface.Initialize = tsmf_plugin_initialize; + tsmf->iface.Connected = NULL; + tsmf->iface.Disconnected = NULL; + tsmf->iface.Terminated = tsmf_plugin_terminated; + error = pEntryPoints->RegisterPlugin(pEntryPoints, "tsmf", (IWTSPlugin*) tsmf); + + tsmf_media_init(); + } + if (error == 0) + { + tsmf_process_plugin_data((IWTSPlugin*) tsmf, + pEntryPoints->GetPluginData(pEntryPoints)); + } + return error; +} + diff --git a/channels/drdynvc/tsmf/tsmf_main.h b/channels/drdynvc/tsmf/tsmf_main.h new file mode 100644 index 0000000..deda1ce --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_main.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_MAIN_H +#define __TSMF_MAIN_H + +void tsmf_playback_ack(IWTSVirtualChannelCallback* pChannelCallback, + uint32 message_id, uint64 duration, uint32 data_size); +boolean tsmf_push_event(IWTSVirtualChannelCallback* pChannelCallback, + RDP_EVENT* event); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_media.c b/channels/drdynvc/tsmf/tsmf_media.c new file mode 100644 index 0000000..134ac78 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_media.c @@ -0,0 +1,795 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Media Container + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drdynvc_types.h" +#include "tsmf_constants.h" +#include "tsmf_types.h" +#include "tsmf_decoder.h" +#include "tsmf_audio.h" +#include "tsmf_main.h" +#include "tsmf_codec.h" +#include "tsmf_media.h" + +#define AUDIO_TOLERANCE 10000000LL + +struct _TSMF_PRESENTATION +{ + uint8 presentation_id[GUID_SIZE]; + + const char* audio_name; + const char* audio_device; + int eos; + + uint32 last_x; + uint32 last_y; + uint32 last_width; + uint32 last_height; + uint16 last_num_rects; + RDP_RECT* last_rects; + + uint32 output_x; + uint32 output_y; + uint32 output_width; + uint32 output_height; + uint16 output_num_rects; + RDP_RECT* output_rects; + + IWTSVirtualChannelCallback* channel_callback; + + uint64 audio_start_time; + uint64 audio_end_time; + + /* The stream list could be accessed by differnt threads and need to be protected. */ + freerdp_mutex mutex; + + LIST* stream_list; +}; + +struct _TSMF_STREAM +{ + uint32 stream_id; + + TSMF_PRESENTATION* presentation; + + ITSMFDecoder* decoder; + + int major_type; + int eos; + uint32 width; + uint32 height; + + ITSMFAudioDevice* audio; + uint32 sample_rate; + uint32 channels; + uint32 bits_per_sample; + + /* The end_time of last played sample */ + uint64 last_end_time; + /* Next sample should not start before this system time. */ + uint64 next_start_time; + + freerdp_thread* thread; + + LIST* sample_list; + + /* The sample ack response queue will be accessed only by the stream thread. */ + LIST* sample_ack_list; +}; + +struct _TSMF_SAMPLE +{ + uint32 sample_id; + uint64 start_time; + uint64 end_time; + uint64 duration; + uint32 extensions; + uint32 data_size; + uint8* data; + uint32 decoded_size; + uint32 pixfmt; + + TSMF_STREAM* stream; + IWTSVirtualChannelCallback* channel_callback; + uint64 ack_time; +}; + +static LIST* presentation_list = NULL; + +static uint64 get_current_time(void) +{ + struct timeval tp; + + gettimeofday(&tp, 0); + return ((uint64)tp.tv_sec) * 10000000LL + ((uint64)tp.tv_usec) * 10LL; +} + +static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync) +{ + TSMF_STREAM* s; + LIST_ITEM* item; + TSMF_SAMPLE* sample; + boolean pending = false; + TSMF_PRESENTATION* presentation = stream->presentation; + + if (!stream->sample_list->head) + return NULL; + + if (sync) + { + if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO) + { + /* Check if some other stream has earlier sample that needs to be played first */ + if (stream->last_end_time > AUDIO_TOLERANCE) + { + freerdp_mutex_lock(presentation->mutex); + for (item = presentation->stream_list->head; item; item = item->next) + { + s = (TSMF_STREAM*) item->data; + if (s != stream && !s->eos && s->last_end_time && + s->last_end_time < stream->last_end_time - AUDIO_TOLERANCE) + { + pending = true; + break; + } + } + freerdp_mutex_unlock(presentation->mutex); + } + } + else + { + if (stream->last_end_time > presentation->audio_end_time) + { + pending = true; + } + } + } + if (pending) + return NULL; + + freerdp_thread_lock(stream->thread); + sample = (TSMF_SAMPLE*) list_dequeue(stream->sample_list); + freerdp_thread_unlock(stream->thread); + + if (sample && sample->end_time > stream->last_end_time) + stream->last_end_time = sample->end_time; + + return sample; +} + +static void tsmf_sample_free(TSMF_SAMPLE* sample) +{ + if (sample->data) + xfree(sample->data); + xfree(sample); +} + +static void tsmf_sample_ack(TSMF_SAMPLE* sample) +{ + tsmf_playback_ack(sample->channel_callback, sample->sample_id, sample->duration, sample->data_size); +} + +static void tsmf_sample_queue_ack(TSMF_SAMPLE* sample) +{ + TSMF_STREAM* stream = sample->stream; + + list_enqueue(stream->sample_ack_list, sample); +} + +static void tsmf_stream_process_ack(TSMF_STREAM* stream) +{ + TSMF_SAMPLE* sample; + uint64 ack_time; + + ack_time = get_current_time(); + while (stream->sample_ack_list->head && !freerdp_thread_is_stopped(stream->thread)) + { + sample = (TSMF_SAMPLE*) list_peek(stream->sample_ack_list); + if (sample->ack_time > ack_time) + break; + + sample = list_dequeue(stream->sample_ack_list); + tsmf_sample_ack(sample); + tsmf_sample_free(sample); + } +} + +TSMF_PRESENTATION* tsmf_presentation_new(const uint8* guid, IWTSVirtualChannelCallback* pChannelCallback) +{ + TSMF_PRESENTATION* presentation; + + presentation = tsmf_presentation_find_by_id(guid); + if (presentation) + { + DEBUG_WARN("duplicated presentation id!"); + return NULL; + } + + presentation = xnew(TSMF_PRESENTATION); + + memcpy(presentation->presentation_id, guid, GUID_SIZE); + presentation->channel_callback = pChannelCallback; + + presentation->mutex = freerdp_mutex_new(); + presentation->stream_list = list_new(); + + list_enqueue(presentation_list, presentation); + + return presentation; +} + +TSMF_PRESENTATION* tsmf_presentation_find_by_id(const uint8* guid) +{ + LIST_ITEM* item; + TSMF_PRESENTATION* presentation; + + for (item = presentation_list->head; item; item = item->next) + { + presentation = (TSMF_PRESENTATION*) item->data; + if (memcmp(presentation->presentation_id, guid, GUID_SIZE) == 0) + return presentation; + } + return NULL; +} + +static void tsmf_presentation_restore_last_video_frame(TSMF_PRESENTATION* presentation) +{ + RDP_REDRAW_EVENT* revent; + + if (presentation->last_width && presentation->last_height) + { + revent = (RDP_REDRAW_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_TSMF, RDP_EVENT_TYPE_TSMF_REDRAW, + NULL, NULL); + revent->x = presentation->last_x; + revent->y = presentation->last_y; + revent->width = presentation->last_width; + revent->height = presentation->last_height; + if (!tsmf_push_event(presentation->channel_callback, (RDP_EVENT*) revent)) + { + freerdp_event_free((RDP_EVENT*) revent); + } + presentation->last_x = 0; + presentation->last_y = 0; + presentation->last_width = 0; + presentation->last_height = 0; + } +} + +static void tsmf_sample_playback_video(TSMF_SAMPLE* sample) +{ + uint64 t; + RDP_VIDEO_FRAME_EVENT* vevent; + TSMF_STREAM* stream = sample->stream; + TSMF_PRESENTATION* presentation = stream->presentation; + + DEBUG_DVC("MessageId %d EndTime %d data_size %d consumed.", + sample->sample_id, (int)sample->end_time, sample->data_size); + + if (sample->data) + { + t = get_current_time(); + if (stream->next_start_time > t && + (sample->end_time >= presentation->audio_start_time || + sample->end_time < stream->last_end_time)) + { + freerdp_usleep((stream->next_start_time - t) / 10); + } + stream->next_start_time = t + sample->duration - 50000; + + if (presentation->last_x != presentation->output_x || + presentation->last_y != presentation->output_y || + presentation->last_width != presentation->output_width || + presentation->last_height != presentation->output_height || + presentation->last_num_rects != presentation->output_num_rects || + (presentation->last_rects && presentation->output_rects && + memcmp(presentation->last_rects, presentation->output_rects, + presentation->last_num_rects * sizeof(RDP_RECT)) != 0)) + { + tsmf_presentation_restore_last_video_frame(presentation); + + presentation->last_x = presentation->output_x; + presentation->last_y = presentation->output_y; + presentation->last_width = presentation->output_width; + presentation->last_height = presentation->output_height; + + if (presentation->last_rects) + { + xfree(presentation->last_rects); + presentation->last_rects = NULL; + } + presentation->last_num_rects = presentation->output_num_rects; + if (presentation->last_num_rects > 0) + { + presentation->last_rects = xzalloc(presentation->last_num_rects * sizeof(RDP_RECT)); + memcpy(presentation->last_rects, presentation->output_rects, + presentation->last_num_rects * sizeof(RDP_RECT)); + } + } + + vevent = (RDP_VIDEO_FRAME_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_TSMF, RDP_EVENT_TYPE_TSMF_VIDEO_FRAME, + NULL, NULL); + vevent->frame_data = sample->data; + vevent->frame_size = sample->decoded_size; + vevent->frame_pixfmt = sample->pixfmt; + vevent->frame_width = sample->stream->width; + vevent->frame_height = sample->stream->height; + vevent->x = presentation->output_x; + vevent->y = presentation->output_y; + vevent->width = presentation->output_width; + vevent->height = presentation->output_height; + if (presentation->output_num_rects > 0) + { + vevent->num_visible_rects = presentation->output_num_rects; + vevent->visible_rects = (RDP_RECT*) xzalloc(presentation->output_num_rects * sizeof(RDP_RECT)); + memcpy(vevent->visible_rects, presentation->output_rects, + presentation->output_num_rects * sizeof(RDP_RECT)); + } + + /* The frame data ownership is passed to the event object, and is freed after the event is processed. */ + sample->data = NULL; + sample->decoded_size = 0; + + if (!tsmf_push_event(sample->channel_callback, (RDP_EVENT*) vevent)) + { + freerdp_event_free((RDP_EVENT*) vevent); + } + +#if 0 + /* Dump a .ppm image for every 30 frames. Assuming the frame is in YUV format, we + extract the Y values to create a grayscale image. */ + static int frame_id = 0; + char buf[100]; + FILE * fp; + if ((frame_id % 30) == 0) + { + snprintf(buf, sizeof(buf), "/tmp/FreeRDP_Frame_%d.ppm", frame_id); + fp = fopen(buf, "wb"); + fwrite("P5\n", 1, 3, fp); + snprintf(buf, sizeof(buf), "%d %d\n", sample->stream->width, sample->stream->height); + fwrite(buf, 1, strlen(buf), fp); + fwrite("255\n", 1, 4, fp); + fwrite(sample->data, 1, sample->stream->width * sample->stream->height, fp); + fflush(fp); + fclose(fp); + } + frame_id++; +#endif + } +} + +static void tsmf_sample_playback_audio(TSMF_SAMPLE* sample) +{ + uint64 latency = 0; + TSMF_STREAM* stream = sample->stream; + + DEBUG_DVC("MessageId %d EndTime %d consumed.", + sample->sample_id, (int)sample->end_time); + + if (sample->stream->audio && sample->data) + { + sample->stream->audio->Play(sample->stream->audio, + sample->data, sample->decoded_size); + sample->data = NULL; + sample->decoded_size = 0; + + if (stream->audio && stream->audio->GetLatency) + latency = stream->audio->GetLatency(stream->audio); + } + else + { + latency = 0; + } + + sample->ack_time = latency + get_current_time(); + stream->last_end_time = sample->end_time + latency; + stream->presentation->audio_start_time = sample->start_time + latency; + stream->presentation->audio_end_time = sample->end_time + latency; +} + +static void tsmf_sample_playback(TSMF_SAMPLE* sample) +{ + boolean ret = false; + uint32 width; + uint32 height; + uint32 pixfmt = 0; + TSMF_STREAM* stream = sample->stream; + + if (stream->decoder) + ret = stream->decoder->Decode(stream->decoder, sample->data, sample->data_size, sample->extensions); + if (!ret) + { + tsmf_sample_ack(sample); + tsmf_sample_free(sample); + return; + } + + xfree(sample->data); + sample->data = NULL; + + if (stream->major_type == TSMF_MAJOR_TYPE_VIDEO) + { + if (stream->decoder->GetDecodedFormat) + { + pixfmt = stream->decoder->GetDecodedFormat(stream->decoder); + if (pixfmt == ((uint32) -1)) + { + tsmf_sample_ack(sample); + tsmf_sample_free(sample); + return; + } + sample->pixfmt = pixfmt; + } + + if (stream->decoder->GetDecodedDimension) + ret = stream->decoder->GetDecodedDimension(stream->decoder, &width, &height); + if (ret && (width != stream->width || height != stream->height)) + { + DEBUG_DVC("video dimension changed to %d x %d", width, height); + stream->width = width; + stream->height = height; + } + } + + if (stream->decoder->GetDecodedData) + { + sample->data = stream->decoder->GetDecodedData(stream->decoder, &sample->decoded_size); + } + + switch (sample->stream->major_type) + { + case TSMF_MAJOR_TYPE_VIDEO: + tsmf_sample_playback_video(sample); + tsmf_sample_ack(sample); + tsmf_sample_free(sample); + break; + case TSMF_MAJOR_TYPE_AUDIO: + tsmf_sample_playback_audio(sample); + tsmf_sample_queue_ack(sample); + break; + } +} + +static void* tsmf_stream_playback_func(void* arg) +{ + TSMF_SAMPLE* sample; + TSMF_STREAM* stream = (TSMF_STREAM*) arg; + TSMF_PRESENTATION* presentation = stream->presentation; + + DEBUG_DVC("in %d", stream->stream_id); + + if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO && + stream->sample_rate && stream->channels && stream->bits_per_sample) + { + stream->audio = tsmf_load_audio_device( + presentation->audio_name && presentation->audio_name[0] ? presentation->audio_name : NULL, + presentation->audio_device && presentation->audio_device[0] ? presentation->audio_device : NULL); + if (stream->audio) + { + stream->audio->SetFormat(stream->audio, + stream->sample_rate, stream->channels, stream->bits_per_sample); + } + } + while (!freerdp_thread_is_stopped(stream->thread)) + { + tsmf_stream_process_ack(stream); + sample = tsmf_stream_pop_sample(stream, 1); + if (sample) + tsmf_sample_playback(sample); + else + freerdp_usleep(5000); + } + if (stream->eos || presentation->eos) + { + while ((sample = tsmf_stream_pop_sample(stream, 1)) != NULL) + tsmf_sample_playback(sample); + } + if (stream->audio) + { + stream->audio->Free(stream->audio); + stream->audio = NULL; + } + + freerdp_thread_quit(stream->thread); + + DEBUG_DVC("out %d", stream->stream_id); + + return NULL; +} + +static void tsmf_stream_start(TSMF_STREAM* stream) +{ + if (!freerdp_thread_is_running(stream->thread)) + { + freerdp_thread_start(stream->thread, tsmf_stream_playback_func, stream); + } +} + +static void tsmf_stream_stop(TSMF_STREAM* stream) +{ + if (freerdp_thread_is_running(stream->thread)) + { + freerdp_thread_stop(stream->thread); + } +} + +void tsmf_presentation_start(TSMF_PRESENTATION* presentation) +{ + LIST_ITEM* item; + TSMF_STREAM* stream; + + for (item = presentation->stream_list->head; item; item = item->next) + { + stream = (TSMF_STREAM*) item->data; + tsmf_stream_start(stream); + } +} + +void tsmf_presentation_stop(TSMF_PRESENTATION* presentation) +{ + LIST_ITEM* item; + TSMF_STREAM* stream; + + tsmf_presentation_flush(presentation); + + for (item = presentation->stream_list->head; item; item = item->next) + { + stream = (TSMF_STREAM*) item->data; + tsmf_stream_stop(stream); + } + + tsmf_presentation_restore_last_video_frame(presentation); + if (presentation->last_rects) + { + xfree(presentation->last_rects); + presentation->last_rects = NULL; + } + presentation->last_num_rects = 0; + if (presentation->output_rects) + { + xfree(presentation->output_rects); + presentation->output_rects = NULL; + } + presentation->output_num_rects = 0; +} + +void tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, + uint32 x, uint32 y, uint32 width, uint32 height, + int num_rects, RDP_RECT* rects) +{ + presentation->output_x = x; + presentation->output_y = y; + presentation->output_width = width; + presentation->output_height = height; + if (presentation->output_rects) + xfree(presentation->output_rects); + presentation->output_rects = rects; + presentation->output_num_rects = num_rects; +} + +void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation, const char* name, const char* device) +{ + presentation->audio_name = name; + presentation->audio_device = device; +} + +static void tsmf_stream_flush(TSMF_STREAM* stream) +{ + TSMF_SAMPLE* sample; + + while ((sample = tsmf_stream_pop_sample(stream, 0)) != NULL) + tsmf_sample_free(sample); + + while ((sample = list_dequeue(stream->sample_ack_list)) != NULL) + tsmf_sample_free(sample); + + if (stream->audio) + stream->audio->Flush(stream->audio); + + stream->eos = 0; + stream->last_end_time = 0; + stream->next_start_time = 0; + if (stream->major_type == TSMF_MAJOR_TYPE_AUDIO) + { + stream->presentation->audio_start_time = 0; + stream->presentation->audio_end_time = 0; + } +} + +void tsmf_presentation_flush(TSMF_PRESENTATION* presentation) +{ + LIST_ITEM* item; + TSMF_STREAM * stream; + + for (item = presentation->stream_list->head; item; item = item->next) + { + stream = (TSMF_STREAM*) item->data; + tsmf_stream_flush(stream); + } + + presentation->eos = 0; + presentation->audio_start_time = 0; + presentation->audio_end_time = 0; +} + +void tsmf_presentation_free(TSMF_PRESENTATION* presentation) +{ + TSMF_STREAM* stream; + + tsmf_presentation_stop(presentation); + list_remove(presentation_list, presentation); + + while (presentation->stream_list->head) + { + stream = (TSMF_STREAM*) list_peek(presentation->stream_list); + tsmf_stream_free(stream); + } + list_free(presentation->stream_list); + + freerdp_mutex_free(presentation->mutex); + + xfree(presentation); +} + +TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, uint32 stream_id) +{ + TSMF_STREAM* stream; + + stream = tsmf_stream_find_by_id(presentation, stream_id); + if (stream) + { + DEBUG_WARN("duplicated stream id %d!", stream_id); + return NULL; + } + + stream = xnew(TSMF_STREAM); + + stream->stream_id = stream_id; + stream->presentation = presentation; + stream->thread = freerdp_thread_new(); + stream->sample_list = list_new(); + stream->sample_ack_list = list_new(); + + freerdp_mutex_lock(presentation->mutex); + list_enqueue(presentation->stream_list, stream); + freerdp_mutex_unlock(presentation->mutex); + + return stream; +} + +TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, uint32 stream_id) +{ + LIST_ITEM* item; + TSMF_STREAM* stream; + + for (item = presentation->stream_list->head; item; item = item->next) + { + stream = (TSMF_STREAM*) item->data; + if (stream->stream_id == stream_id) + return stream; + } + return NULL; +} + +void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, STREAM* s) +{ + TS_AM_MEDIA_TYPE mediatype; + + if (stream->decoder) + { + DEBUG_WARN("duplicated call"); + return; + } + + tsmf_codec_parse_media_type(&mediatype, s); + + if (mediatype.MajorType == TSMF_MAJOR_TYPE_VIDEO) + { + DEBUG_DVC("video width %d height %d bit_rate %d frame_rate %f codec_data %d", + mediatype.Width, mediatype.Height, mediatype.BitRate, + (double)mediatype.SamplesPerSecond.Numerator / (double)mediatype.SamplesPerSecond.Denominator, + mediatype.ExtraDataSize); + } + else if (mediatype.MajorType == TSMF_MAJOR_TYPE_AUDIO) + { + DEBUG_DVC("audio channel %d sample_rate %d bits_per_sample %d codec_data %d", + mediatype.Channels, mediatype.SamplesPerSecond.Numerator, mediatype.BitsPerSample, + mediatype.ExtraDataSize); + stream->sample_rate = mediatype.SamplesPerSecond.Numerator; + stream->channels = mediatype.Channels; + stream->bits_per_sample = mediatype.BitsPerSample; + if (stream->bits_per_sample == 0) + stream->bits_per_sample = 16; + } + + stream->major_type = mediatype.MajorType; + stream->width = mediatype.Width; + stream->height = mediatype.Height; + stream->decoder = tsmf_load_decoder(name, &mediatype); +} + +void tsmf_stream_end(TSMF_STREAM* stream) +{ + stream->eos = 1; + stream->presentation->eos = 1; +} + +void tsmf_stream_free(TSMF_STREAM* stream) +{ + TSMF_PRESENTATION* presentation = stream->presentation; + + tsmf_stream_stop(stream); + tsmf_stream_flush(stream); + + freerdp_mutex_lock(presentation->mutex); + list_remove(presentation->stream_list, stream); + freerdp_mutex_unlock(presentation->mutex); + + list_free(stream->sample_list); + list_free(stream->sample_ack_list); + + if (stream->decoder) + stream->decoder->Free(stream->decoder); + + freerdp_thread_free(stream->thread); + + xfree(stream); +} + +void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pChannelCallback, + uint32 sample_id, uint64 start_time, uint64 end_time, uint64 duration, uint32 extensions, + uint32 data_size, uint8* data) +{ + TSMF_SAMPLE* sample; + + sample = xnew(TSMF_SAMPLE); + + sample->sample_id = sample_id; + sample->start_time = start_time; + sample->end_time = end_time; + sample->duration = duration; + sample->extensions = extensions; + sample->stream = stream; + sample->channel_callback = pChannelCallback; + sample->data_size = data_size; + sample->data = xzalloc(data_size + TSMF_BUFFER_PADDING_SIZE); + memcpy(sample->data, data, data_size); + + freerdp_thread_lock(stream->thread); + list_enqueue(stream->sample_list, sample); + freerdp_thread_unlock(stream->thread); +} + +void tsmf_media_init(void) +{ + if (presentation_list == NULL) + presentation_list = list_new(); +} + diff --git a/channels/drdynvc/tsmf/tsmf_media.h b/channels/drdynvc/tsmf/tsmf_media.h new file mode 100644 index 0000000..eac3e00 --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_media.h @@ -0,0 +1,59 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Media Container + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The media container maintains a global list of presentations, and a list of + * streams in each presentation. + */ + +#ifndef __TSMF_MEDIA_H +#define __TSMF_MEDIA_H + +typedef struct _TSMF_PRESENTATION TSMF_PRESENTATION; + +typedef struct _TSMF_STREAM TSMF_STREAM; + +typedef struct _TSMF_SAMPLE TSMF_SAMPLE; + +TSMF_PRESENTATION* tsmf_presentation_new(const uint8* guid, IWTSVirtualChannelCallback* pChannelCallback); +TSMF_PRESENTATION* tsmf_presentation_find_by_id(const uint8* guid); +void tsmf_presentation_start(TSMF_PRESENTATION* presentation); +void tsmf_presentation_stop(TSMF_PRESENTATION* presentation); +void tsmf_presentation_set_geometry_info(TSMF_PRESENTATION* presentation, + uint32 x, uint32 y, uint32 width, uint32 height, + int num_rects, RDP_RECT* rects); +void tsmf_presentation_set_audio_device(TSMF_PRESENTATION* presentation, + const char* name, const char* device); +void tsmf_presentation_flush(TSMF_PRESENTATION* presentation); +void tsmf_presentation_free(TSMF_PRESENTATION* presentation); + +TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, uint32 stream_id); +TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, uint32 stream_id); +void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, STREAM* s); +void tsmf_stream_end(TSMF_STREAM* stream); +void tsmf_stream_free(TSMF_STREAM* stream); + +void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pChannelCallback, + uint32 sample_id, uint64 start_time, uint64 end_time, uint64 duration, uint32 extensions, + uint32 data_size, uint8* data); + +void tsmf_media_init(void); + +#endif + diff --git a/channels/drdynvc/tsmf/tsmf_types.h b/channels/drdynvc/tsmf/tsmf_types.h new file mode 100644 index 0000000..20745cb --- /dev/null +++ b/channels/drdynvc/tsmf/tsmf_types.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Video Redirection Virtual Channel - Types + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_TYPES_H +#define __TSMF_TYPES_H + +#include + +typedef struct _TS_AM_MEDIA_TYPE +{ + int MajorType; + int SubType; + int FormatType; + + uint32 Width; + uint32 Height; + uint32 BitRate; + struct + { + uint32 Numerator; + uint32 Denominator; + } SamplesPerSecond; + uint32 Channels; + uint32 BitsPerSample; + uint32 BlockAlign; + const uint8* ExtraData; + uint32 ExtraDataSize; +} TS_AM_MEDIA_TYPE; + +#endif + diff --git a/channels/rail/CMakeLists.txt b/channels/rail/CMakeLists.txt new file mode 100644 index 0000000..3164111 --- /dev/null +++ b/channels/rail/CMakeLists.txt @@ -0,0 +1,32 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RAIL_SRCS + rail_main.c + rail_main.h + rail_orders.c + rail_orders.h) + +add_library(rail ${RAIL_SRCS}) +set_target_properties(rail PROPERTIES PREFIX "") + +target_link_libraries(rail freerdp-utils) + +install(TARGETS rail DESTINATION ${FREERDP_PLUGIN_PATH}) + diff --git a/channels/rail/rail_main.c b/channels/rail/rail_main.c new file mode 100644 index 0000000..58d1de4 --- /dev/null +++ b/channels/rail/rail_main.c @@ -0,0 +1,251 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Virtual Channel Plugin + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rail_orders.h" +#include "rail_main.h" + +void rail_send_channel_data(void* rail_object, void* data, size_t length) +{ + STREAM* s = NULL; + railPlugin* plugin = (railPlugin*) rail_object; + + s = stream_new(length); + stream_write(s, data, length); + + svc_plugin_send((rdpSvcPlugin*) plugin, s); +} + +static void on_free_rail_channel_event(RDP_EVENT* event) +{ + if (event->event_class == RDP_EVENT_CLASS_RAIL) + { + rail_free_cloned_order(event->event_type, event->user_data); + } +} + +void rail_send_channel_event(void* rail_object, uint16 event_type, void* param) +{ + void * payload = NULL; + RDP_EVENT* out_event = NULL; + railPlugin* plugin = (railPlugin*) rail_object; + + payload = rail_clone_order(event_type, param); + + if (payload != NULL) + { + out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, + on_free_rail_channel_event, payload); + + svc_plugin_send_event((rdpSvcPlugin*) plugin, out_event); + } +} + +static void rail_process_connect(rdpSvcPlugin* plugin) +{ + railPlugin* rail = (railPlugin*) plugin; + + rail->rail_order = rail_order_new(); + rail->rail_order->plugin_data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData; + rail->rail_order->plugin = rail; +} + +static void rail_process_terminate(rdpSvcPlugin* plugin) +{ + +} + +static void rail_process_receive(rdpSvcPlugin* plugin, STREAM* s) +{ + railPlugin* rail = (railPlugin*) plugin; + rail_order_recv(rail->rail_order, s); + stream_free(s); +} + +static void rail_process_plugin_data(rdpRailOrder* rail_order, RDP_PLUGIN_DATA* data) +{ + char* exeOrFile; + + exeOrFile = (char*) data->data[0]; + + if (strlen(exeOrFile) >= 2) + { + if (strncmp(exeOrFile, "||", 2) != 0) + rail_order->exec.flags |= RAIL_EXEC_FLAG_FILE; + } + + rail_string_to_unicode_string(rail_order, (char*) data->data[0], &rail_order->exec.exeOrFile); + rail_string_to_unicode_string(rail_order, (char*) data->data[1], &rail_order->exec.workingDir); + rail_string_to_unicode_string(rail_order, (char*) data->data[2], &rail_order->exec.arguments); + + rail_send_client_exec_order(rail_order); +} + +static void rail_recv_set_sysparams_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RDP_PLUGIN_DATA* data; + RAIL_SYSPARAM_ORDER* sysparam; + + /* Send System Parameters */ + + sysparam = (RAIL_SYSPARAM_ORDER*)event->user_data; + memmove(&rail_order->sysparam, sysparam, sizeof(RAIL_SYSPARAM_ORDER)); + + rail_send_client_sysparams_order(rail_order); + + /* execute */ + + rail_order->exec.flags = RAIL_EXEC_FLAG_EXPAND_ARGUMENTS; + + data = rail_order->plugin_data; + while (data && data->size > 0) + { + rail_process_plugin_data(rail_order, data); + data = (RDP_PLUGIN_DATA*)(((void*) data) + data->size); + } +} + +static void rail_recv_exec_remote_app_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RDP_PLUGIN_DATA* data = (RDP_PLUGIN_DATA*) event->user_data; + + rail_process_plugin_data(rail_order, data); +} + +static void rail_recv_activate_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_ACTIVATE_ORDER* activate = (RAIL_ACTIVATE_ORDER*) event->user_data; + + memcpy(&rail_order->activate, activate, sizeof(RAIL_ACTIVATE_ORDER)); + rail_send_client_activate_order(rail_order); +} + +static void rail_recv_sysmenu_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_SYSMENU_ORDER* sysmenu = (RAIL_SYSMENU_ORDER*) event->user_data; + + memcpy(&rail_order->sysmenu, sysmenu, sizeof(RAIL_SYSMENU_ORDER)); + rail_send_client_sysmenu_order(rail_order); +} + +static void rail_recv_syscommand_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_SYSCOMMAND_ORDER* syscommand = (RAIL_SYSCOMMAND_ORDER*) event->user_data; + + memcpy(&rail_order->syscommand, syscommand, sizeof(RAIL_SYSCOMMAND_ORDER)); + rail_send_client_syscommand_order(rail_order); +} + +static void rail_recv_notify_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_NOTIFY_EVENT_ORDER* notify = (RAIL_NOTIFY_EVENT_ORDER*) event->user_data; + + memcpy(&rail_order->notify_event, notify, sizeof(RAIL_NOTIFY_EVENT_ORDER)); + rail_send_client_notify_event_order(rail_order); +} + +static void rail_recv_window_move_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_WINDOW_MOVE_ORDER* window_move = (RAIL_WINDOW_MOVE_ORDER*) event->user_data; + + memcpy(&rail_order->window_move, window_move, sizeof(RAIL_WINDOW_MOVE_ORDER)); + rail_send_client_window_move_order(rail_order); +} + +static void rail_recv_app_req_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_GET_APPID_REQ_ORDER* get_appid_req = (RAIL_GET_APPID_REQ_ORDER*) event->user_data; + + memcpy(&rail_order->get_appid_req, get_appid_req, sizeof(RAIL_GET_APPID_REQ_ORDER)); + rail_send_client_get_appid_req_order(rail_order); +} + +static void rail_recv_langbarinfo_event(rdpRailOrder* rail_order, RDP_EVENT* event) +{ + RAIL_LANGBAR_INFO_ORDER* langbar_info = (RAIL_LANGBAR_INFO_ORDER*) event->user_data; + + memcpy(&rail_order->langbar_info, langbar_info, sizeof(RAIL_LANGBAR_INFO_ORDER)); + rail_send_client_langbar_info_order(rail_order); +} + +static void rail_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + railPlugin* rail = NULL; + rail = (railPlugin*) plugin; + + switch (event->event_type) + { + case RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS: + rail_recv_set_sysparams_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP: + rail_recv_exec_remote_app_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE: + rail_recv_activate_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU: + rail_recv_sysmenu_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND: + rail_recv_syscommand_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT: + rail_recv_notify_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE: + rail_recv_window_move_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ: + rail_recv_app_req_event(rail->rail_order, event); + break; + + case RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO: + rail_recv_langbarinfo_event(rail->rail_order, event); + break; + + default: + break; + } + + freerdp_event_free(event); +} + +DEFINE_SVC_PLUGIN(rail, "rail", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL) + diff --git a/channels/rail/rail_main.h b/channels/rail/rail_main.h new file mode 100644 index 0000000..49870a5 --- /dev/null +++ b/channels/rail/rail_main.h @@ -0,0 +1,69 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Virtual Channel Plugin + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_MAIN_H +#define __RAIL_MAIN_H + +#include +#include +#include +#include + +struct rdp_rail_order +{ + UNICONV* uniconv; + RDP_PLUGIN_DATA* plugin_data; + void* plugin; + RAIL_HANDSHAKE_ORDER handshake; + RAIL_CLIENT_STATUS_ORDER client_status; + RAIL_EXEC_ORDER exec; + RAIL_EXEC_RESULT_ORDER exec_result; + RAIL_SYSPARAM_ORDER sysparam; + RAIL_ACTIVATE_ORDER activate; + RAIL_SYSMENU_ORDER sysmenu; + RAIL_SYSCOMMAND_ORDER syscommand; + RAIL_NOTIFY_EVENT_ORDER notify_event; + RAIL_MINMAXINFO_ORDER minmaxinfo; + RAIL_LOCALMOVESIZE_ORDER localmovesize; + RAIL_WINDOW_MOVE_ORDER window_move; + RAIL_LANGBAR_INFO_ORDER langbar_info; + RAIL_GET_APPID_REQ_ORDER get_appid_req; + RAIL_GET_APPID_RESP_ORDER get_appid_resp; +}; +typedef struct rdp_rail_order rdpRailOrder; + +struct rail_plugin +{ + rdpSvcPlugin plugin; + rdpRailOrder* rail_order; +}; +typedef struct rail_plugin railPlugin; + +void rail_send_channel_event(void* rail_object, uint16 event_type, void* param); +void rail_send_channel_data(void* rail_object, void* data, size_t length); + +#ifdef WITH_DEBUG_RAIL +#define DEBUG_RAIL(fmt, ...) DEBUG_CLASS(RAIL, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __RAIL_MAIN_H */ diff --git a/channels/rail/rail_orders.c b/channels/rail/rail_orders.c new file mode 100644 index 0000000..0674be0 --- /dev/null +++ b/channels/rail/rail_orders.c @@ -0,0 +1,633 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Remote Applications Integrated Locally (RAIL) Orders + * + * Copyright 2009 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "rail_orders.h" + +#define RAIL_ORDER_TYPE_EXEC 0x0001 +#define RAIL_ORDER_TYPE_ACTIVATE 0x0002 +#define RAIL_ORDER_TYPE_SYSPARAM 0x0003 +#define RAIL_ORDER_TYPE_SYSCOMMAND 0x0004 +#define RAIL_ORDER_TYPE_HANDSHAKE 0x0005 +#define RAIL_ORDER_TYPE_NOTIFY_EVENT 0x0006 +#define RAIL_ORDER_TYPE_WINDOW_MOVE 0x0008 +#define RAIL_ORDER_TYPE_LOCALMOVESIZE 0x0009 +#define RAIL_ORDER_TYPE_MINMAXINFO 0x000A +#define RAIL_ORDER_TYPE_CLIENT_STATUS 0x000B +#define RAIL_ORDER_TYPE_SYSMENU 0x000C +#define RAIL_ORDER_TYPE_LANGBAR_INFO 0x000D +#define RAIL_ORDER_TYPE_EXEC_RESULT 0x0080 +#define RAIL_ORDER_TYPE_GET_APPID_REQ 0x000E +#define RAIL_ORDER_TYPE_GET_APPID_RESP 0x000F + +static const char* const RAIL_ORDER_TYPE_STRINGS[] = +{ + "", + "Execute", + "Activate", + "System Parameters Update", + "System Command", + "Handshake", + "Notify Event", + "", + "Window Move", + "Local Move/Size", + "Min Max Info", + "Client Status", + "System Menu", + "Language Bar Info", + "Get Application ID Request", + "Get Application ID Response", + "Execute Result" +}; + +void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string) +{ + char* buffer; + size_t length = 0; + + if (unicode_string->string != NULL) + xfree(unicode_string->string); + + unicode_string->string = NULL; + unicode_string->length = 0; + + if (string == NULL || strlen(string) < 1) + return; + + buffer = freerdp_uniconv_out(rail_order->uniconv, string, &length); + + unicode_string->string = (uint8*) buffer; + unicode_string->length = (uint16) length; +} + +void rail_read_pdu_header(STREAM* s, uint16* orderType, uint16* orderLength) +{ + stream_read_uint16(s, *orderType); /* orderType (2 bytes) */ + stream_read_uint16(s, *orderLength); /* orderLength (2 bytes) */ +} + +void rail_write_pdu_header(STREAM* s, uint16 orderType, uint16 orderLength) +{ + stream_write_uint16(s, orderType); /* orderType (2 bytes) */ + stream_write_uint16(s, orderLength); /* orderLength (2 bytes) */ +} + +STREAM* rail_pdu_init(int length) +{ + STREAM* s; + s = stream_new(length + RAIL_PDU_HEADER_LENGTH); + stream_seek(s, RAIL_PDU_HEADER_LENGTH); + return s; +} + +void rail_send_pdu(rdpRailOrder* rail_order, STREAM* s, uint16 orderType) +{ + uint16 orderLength; + + orderLength = stream_get_length(s); + stream_set_pos(s, 0); + + rail_write_pdu_header(s, orderType, orderLength); + stream_set_pos(s, orderLength); + + /* send */ + DEBUG_RAIL("Sending %s PDU, length:%d", + RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); + + rail_send_channel_data(rail_order->plugin, s->data, orderLength); +} + +void rail_write_high_contrast(STREAM* s, HIGH_CONTRAST* high_contrast) +{ + high_contrast->colorSchemeLength = high_contrast->colorScheme.length + 2; + stream_write_uint32(s, high_contrast->flags); /* flags (4 bytes) */ + stream_write_uint32(s, high_contrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */ + rail_write_unicode_string(s, &high_contrast->colorScheme); /* colorScheme */ +} + +void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake) +{ + stream_read_uint32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ +} + +void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result) +{ + stream_read_uint16(s, exec_result->flags); /* flags (2 bytes) */ + stream_read_uint16(s, exec_result->execResult); /* execResult (2 bytes) */ + stream_read_uint32(s, exec_result->rawResult); /* rawResult (4 bytes) */ + stream_seek_uint16(s); /* padding (2 bytes) */ + rail_read_unicode_string(s, &exec_result->exeOrFile); /* exeOrFile */ +} + +void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam) +{ + uint8 body; + stream_read_uint32(s, sysparam->param); /* systemParam (4 bytes) */ + stream_read_uint8(s, body); /* body (1 byte) */ + + switch (sysparam->param) + { + case SPI_SET_SCREEN_SAVE_ACTIVE: + sysparam->setScreenSaveActive = (body != 0) ? true : false; + break; + + case SPI_SET_SCREEN_SAVE_SECURE: + sysparam->setScreenSaveSecure = (body != 0) ? true : false; + break; + + default: + break; + } +} + +void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo) +{ + stream_read_uint32(s, minmaxinfo->windowId); /* windowId (4 bytes) */ + stream_read_uint16(s, minmaxinfo->maxWidth); /* maxWidth (2 bytes) */ + stream_read_uint16(s, minmaxinfo->maxHeight); /* maxHeight (2 bytes) */ + stream_read_uint16(s, minmaxinfo->maxPosX); /* maxPosX (2 bytes) */ + stream_read_uint16(s, minmaxinfo->maxPosY); /* maxPosY (2 bytes) */ + stream_read_uint16(s, minmaxinfo->minTrackWidth); /* minTrackWidth (2 bytes) */ + stream_read_uint16(s, minmaxinfo->minTrackHeight); /* minTrackHeight (2 bytes) */ + stream_read_uint16(s, minmaxinfo->maxTrackWidth); /* maxTrackWidth (2 bytes) */ + stream_read_uint16(s, minmaxinfo->maxTrackHeight); /* maxTrackHeight (2 bytes) */ +} + +void rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize) +{ + uint16 isMoveSizeStart; + stream_read_uint32(s, localmovesize->windowId); /* windowId (4 bytes) */ + + stream_read_uint16(s, isMoveSizeStart); /* isMoveSizeStart (2 bytes) */ + localmovesize->isMoveSizeStart = (isMoveSizeStart != 0) ? true : false; + + stream_read_uint16(s, localmovesize->moveSizeType); /* moveSizeType (2 bytes) */ + stream_read_uint16(s, localmovesize->posX); /* posX (2 bytes) */ + stream_read_uint16(s, localmovesize->posY); /* posY (2 bytes) */ +} + +void rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp) +{ + stream_read_uint32(s, get_appid_resp->windowId); /* windowId (4 bytes) */ + stream_read(s, &get_appid_resp->applicationIdBuffer[0], 512); /* applicationId (256 UNICODE chars) */ + + get_appid_resp->applicationId.length = 512; + get_appid_resp->applicationId.string = &get_appid_resp->applicationIdBuffer[0]; +} + +void rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) +{ + stream_read_uint32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ +} + +void rail_write_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake) +{ + stream_write_uint32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ +} + +void rail_write_client_status_order(STREAM* s, RAIL_CLIENT_STATUS_ORDER* client_status) +{ + stream_write_uint32(s, client_status->flags); /* flags (4 bytes) */ +} + +void rail_write_client_exec_order(STREAM* s, RAIL_EXEC_ORDER* exec) +{ + stream_write_uint16(s, exec->flags); /* flags (2 bytes) */ + stream_write_uint16(s, exec->exeOrFile.length); /* exeOrFileLength (2 bytes) */ + stream_write_uint16(s, exec->workingDir.length); /* workingDirLength (2 bytes) */ + stream_write_uint16(s, exec->arguments.length); /* argumentsLength (2 bytes) */ + rail_write_unicode_string_value(s, &exec->exeOrFile); /* exeOrFile */ + rail_write_unicode_string_value(s, &exec->workingDir); /* workingDir */ + rail_write_unicode_string_value(s, &exec->arguments); /* arguments */ +} + +void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam) +{ + uint8 body; + stream_write_uint32(s, sysparam->param); /* systemParam (4 bytes) */ + + switch (sysparam->param) + { + case SPI_SET_DRAG_FULL_WINDOWS: + body = sysparam->dragFullWindows; + stream_write_uint8(s, body); + break; + + case SPI_SET_KEYBOARD_CUES: + body = sysparam->keyboardCues; + stream_write_uint8(s, body); + break; + + case SPI_SET_KEYBOARD_PREF: + body = sysparam->keyboardPref; + stream_write_uint8(s, body); + break; + + case SPI_SET_MOUSE_BUTTON_SWAP: + body = sysparam->mouseButtonSwap; + stream_write_uint8(s, body); + break; + + case SPI_SET_WORK_AREA: + freerdp_write_rectangle_16(s, &sysparam->workArea); + break; + + case SPI_DISPLAY_CHANGE: + freerdp_write_rectangle_16(s, &sysparam->displayChange); + break; + + case SPI_TASKBAR_POS: + freerdp_write_rectangle_16(s, &sysparam->taskbarPos); + break; + + case SPI_SET_HIGH_CONTRAST: + rail_write_high_contrast(s, &sysparam->highContrast); + break; + } +} + +void rail_write_client_activate_order(STREAM* s, RAIL_ACTIVATE_ORDER* activate) +{ + uint8 enabled; + + stream_write_uint32(s, activate->windowId); /* windowId (4 bytes) */ + + enabled = activate->enabled; + stream_write_uint8(s, enabled); /* enabled (1 byte) */ +} + +void rail_write_client_sysmenu_order(STREAM* s, RAIL_SYSMENU_ORDER* sysmenu) +{ + stream_write_uint32(s, sysmenu->windowId); /* windowId (4 bytes) */ + stream_write_uint16(s, sysmenu->left); /* left (2 bytes) */ + stream_write_uint16(s, sysmenu->top); /* top (2 bytes) */ +} + +void rail_write_client_syscommand_order(STREAM* s, RAIL_SYSCOMMAND_ORDER* syscommand) +{ + stream_write_uint32(s, syscommand->windowId); /* windowId (4 bytes) */ + stream_write_uint16(s, syscommand->command); /* command (2 bytes) */ +} + +void rail_write_client_notify_event_order(STREAM* s, RAIL_NOTIFY_EVENT_ORDER* notify_event) +{ + stream_write_uint32(s, notify_event->windowId); /* windowId (4 bytes) */ + stream_write_uint32(s, notify_event->notifyIconId); /* notifyIconId (4 bytes) */ + stream_write_uint32(s, notify_event->message); /* notifyIconId (4 bytes) */ +} + +void rail_write_client_window_move_order(STREAM* s, RAIL_WINDOW_MOVE_ORDER* window_move) +{ + stream_write_uint32(s, window_move->windowId); /* windowId (4 bytes) */ + stream_write_uint16(s, window_move->left); /* left (2 bytes) */ + stream_write_uint16(s, window_move->top); /* top (2 bytes) */ + stream_write_uint16(s, window_move->right); /* right (2 bytes) */ + stream_write_uint16(s, window_move->bottom); /* bottom (2 bytes) */ +} + +void rail_write_client_get_appid_req_order(STREAM* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req) +{ + stream_write_uint32(s, get_appid_req->windowId); /* windowId (4 bytes) */ +} + +void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) +{ + stream_write_uint32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ +} + +void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_handshake_order(s, &rail_order->handshake); + + rail_order->handshake.buildNumber = 0x00001DB0; + rail_send_handshake_order(rail_order); + + rail_order->client_status.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE; + rail_send_client_status_order(rail_order); + + /* sysparam update */ + + rail_order->sysparam.params = 0; + + rail_order->sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST; + rail_order->sysparam.highContrast.colorScheme.string = NULL; + rail_order->sysparam.highContrast.colorScheme.length = 0; + rail_order->sysparam.highContrast.flags = 0x7E; + + rail_order->sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP; + rail_order->sysparam.mouseButtonSwap = false; + + rail_order->sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF; + rail_order->sysparam.keyboardPref = false; + + rail_order->sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS; + rail_order->sysparam.dragFullWindows = false; + + rail_order->sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES; + rail_order->sysparam.keyboardCues = false; + + rail_order->sysparam.params |= SPI_MASK_SET_WORK_AREA; + rail_order->sysparam.workArea.left = 0; + rail_order->sysparam.workArea.top = 0; + rail_order->sysparam.workArea.right = 1024; + rail_order->sysparam.workArea.bottom = 768; + + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS, &rail_order->sysparam); +} + +void rail_recv_exec_result_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_server_exec_result_order(s, &rail_order->exec_result); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS, &rail_order->exec_result); +} + +void rail_recv_server_sysparam_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_server_sysparam_order(s, &rail_order->sysparam); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM, &rail_order->sysparam); +} + +void rail_recv_server_minmaxinfo_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_server_minmaxinfo_order(s, &rail_order->minmaxinfo); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO, &rail_order->minmaxinfo); +} + +void rail_recv_server_localmovesize_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_server_localmovesize_order(s, &rail_order->localmovesize); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE, &rail_order->localmovesize); +} + +void rail_recv_server_get_appid_resp_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_server_get_appid_resp_order(s, &rail_order->get_appid_resp); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP, &rail_order->get_appid_resp); +} + +void rail_recv_langbar_info_order(rdpRailOrder* rail_order, STREAM* s) +{ + rail_read_langbar_info_order(s, &rail_order->langbar_info); + rail_send_channel_event(rail_order->plugin, + RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO, &rail_order->langbar_info); +} + +void rail_order_recv(rdpRailOrder* rail_order, STREAM* s) +{ + uint16 orderType; + uint16 orderLength; + + rail_read_pdu_header(s, &orderType, &orderLength); + + DEBUG_RAIL("Received %s PDU, length:%d", + RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)], orderLength); + + switch (orderType) + { + case RDP_RAIL_ORDER_HANDSHAKE: + rail_recv_handshake_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_EXEC_RESULT: + rail_recv_exec_result_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_SYSPARAM: + rail_recv_server_sysparam_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_MINMAXINFO: + rail_recv_server_minmaxinfo_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_LOCALMOVESIZE: + rail_recv_server_localmovesize_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_GET_APPID_RESP: + rail_recv_server_get_appid_resp_order(rail_order, s); + break; + + case RDP_RAIL_ORDER_LANGBARINFO: + rail_recv_langbar_info_order(rail_order, s); + break; + + default: + printf("Unknown RAIL PDU order reveived."); + break; + } +} + +void rail_send_handshake_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_HANDSHAKE_ORDER_LENGTH); + rail_write_handshake_order(s, &rail_order->handshake); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_HANDSHAKE); +} + +void rail_send_client_status_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_CLIENT_STATUS_ORDER_LENGTH); + rail_write_client_status_order(s, &rail_order->client_status); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_CLIENT_STATUS); +} + +void rail_send_client_exec_order(rdpRailOrder* rail_order) +{ + STREAM* s; + int length; + + length = RAIL_EXEC_ORDER_LENGTH + + rail_order->exec.exeOrFile.length + + rail_order->exec.workingDir.length + + rail_order->exec.arguments.length; + + s = rail_pdu_init(RAIL_EXEC_ORDER_LENGTH); + rail_write_client_exec_order(s, &rail_order->exec); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_EXEC); +} + +void rail_send_client_sysparam_order(rdpRailOrder* rail_order) +{ + STREAM* s; + int length; + + length = RAIL_SYSPARAM_ORDER_LENGTH; + + switch (rail_order->sysparam.param) + { + case SPI_SET_DRAG_FULL_WINDOWS: + case SPI_SET_KEYBOARD_CUES: + case SPI_SET_KEYBOARD_PREF: + case SPI_SET_MOUSE_BUTTON_SWAP: + length += 1; + break; + + case SPI_SET_WORK_AREA: + case SPI_DISPLAY_CHANGE: + case SPI_TASKBAR_POS: + length += 8; + break; + + case SPI_SET_HIGH_CONTRAST: + length += rail_order->sysparam.highContrast.colorSchemeLength + 10; + break; + } + + s = rail_pdu_init(RAIL_SYSPARAM_ORDER_LENGTH + 8); + rail_write_client_sysparam_order(s, &rail_order->sysparam); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSPARAM); +} + +void rail_send_client_sysparams_order(rdpRailOrder* rail_order) +{ + if (rail_order->sysparam.params & SPI_MASK_SET_HIGH_CONTRAST) + { + rail_order->sysparam.param = SPI_SET_HIGH_CONTRAST; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_TASKBAR_POS) + { + rail_order->sysparam.param = SPI_TASKBAR_POS; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_SET_MOUSE_BUTTON_SWAP) + { + rail_order->sysparam.param = SPI_SET_MOUSE_BUTTON_SWAP; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_SET_KEYBOARD_PREF) + { + rail_order->sysparam.param = SPI_SET_KEYBOARD_PREF; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_SET_DRAG_FULL_WINDOWS) + { + rail_order->sysparam.param = SPI_SET_DRAG_FULL_WINDOWS; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_SET_KEYBOARD_CUES) + { + rail_order->sysparam.param = SPI_SET_KEYBOARD_CUES; + rail_send_client_sysparam_order(rail_order); + } + + if (rail_order->sysparam.params & SPI_MASK_SET_WORK_AREA) + { + rail_order->sysparam.param = SPI_SET_WORK_AREA; + rail_send_client_sysparam_order(rail_order); + } +} + +void rail_send_client_activate_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_ACTIVATE_ORDER_LENGTH); + rail_write_client_activate_order(s, &rail_order->activate); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_ACTIVATE); +} + +void rail_send_client_sysmenu_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_SYSMENU_ORDER_LENGTH); + rail_write_client_sysmenu_order(s, &rail_order->sysmenu); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSMENU); +} + +void rail_send_client_syscommand_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_SYSCOMMAND_ORDER_LENGTH); + rail_write_client_syscommand_order(s, &rail_order->syscommand); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_SYSCOMMAND); +} + +void rail_send_client_notify_event_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_NOTIFY_EVENT_ORDER_LENGTH); + rail_write_client_notify_event_order(s, &rail_order->notify_event); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_NOTIFY_EVENT); +} + +void rail_send_client_window_move_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_WINDOW_MOVE_ORDER_LENGTH); + rail_write_client_window_move_order(s, &rail_order->window_move); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_WINDOW_MOVE); +} + +void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_GET_APPID_REQ_ORDER_LENGTH); + rail_write_client_get_appid_req_order(s, &rail_order->get_appid_req); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_GET_APPID_REQ); +} + +void rail_send_client_langbar_info_order(rdpRailOrder* rail_order) +{ + STREAM* s; + s = rail_pdu_init(RAIL_LANGBAR_INFO_ORDER_LENGTH); + rail_write_langbar_info_order(s, &rail_order->langbar_info); + rail_send_pdu(rail_order, s, RAIL_ORDER_TYPE_LANGBAR_INFO); +} + +rdpRailOrder* rail_order_new() +{ + rdpRailOrder* rail_order; + + rail_order = xnew(rdpRailOrder); + + if (rail_order != NULL) + { + rail_order->uniconv = freerdp_uniconv_new(); + } + + return rail_order; +} + +void rail_order_free(rdpRailOrder* rail_order) +{ + if (rail_order != NULL) + { + freerdp_uniconv_free(rail_order->uniconv); + xfree(rail_order); + } +} + diff --git a/channels/rail/rail_orders.h b/channels/rail/rail_orders.h new file mode 100644 index 0000000..fbbe20f --- /dev/null +++ b/channels/rail/rail_orders.h @@ -0,0 +1,97 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2009 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_ORDERS_H +#define __RAIL_ORDERS_H + +#include "rail_main.h" + +#define RAIL_ORDER_TYPE_EXEC 0x0001 +#define RAIL_ORDER_TYPE_ACTIVATE 0x0002 +#define RAIL_ORDER_TYPE_SYSPARAM 0x0003 +#define RAIL_ORDER_TYPE_SYSCOMMAND 0x0004 +#define RAIL_ORDER_TYPE_HANDSHAKE 0x0005 +#define RAIL_ORDER_TYPE_NOTIFY_EVENT 0x0006 +#define RAIL_ORDER_TYPE_WINDOW_MOVE 0x0008 +#define RAIL_ORDER_TYPE_LOCALMOVESIZE 0x0009 +#define RAIL_ORDER_TYPE_MINMAXINFO 0x000A +#define RAIL_ORDER_TYPE_CLIENT_STATUS 0x000B +#define RAIL_ORDER_TYPE_SYSMENU 0x000C +#define RAIL_ORDER_TYPE_LANGBAR_INFO 0x000D +#define RAIL_ORDER_TYPE_EXEC_RESULT 0x0080 +#define RAIL_ORDER_TYPE_GET_APPID_REQ 0x000E +#define RAIL_ORDER_TYPE_GET_APPID_RESP 0x000F + +#define RAIL_PDU_HEADER_LENGTH 4 + +/* Fixed length of PDUs, excluding variable lengths */ +#define RAIL_HANDSHAKE_ORDER_LENGTH 4 /* fixed */ +#define RAIL_CLIENT_STATUS_ORDER_LENGTH 4 /* fixed */ +#define RAIL_EXEC_ORDER_LENGTH 8 /* variable */ +#define RAIL_SYSPARAM_ORDER_LENGTH 4 /* variable */ +#define RAIL_ACTIVATE_ORDER_LENGTH 5 /* fixed */ +#define RAIL_SYSMENU_ORDER_LENGTH 8 /* fixed */ +#define RAIL_SYSCOMMAND_ORDER_LENGTH 6 /* fixed */ +#define RAIL_NOTIFY_EVENT_ORDER_LENGTH 12 /* fixed */ +#define RAIL_WINDOW_MOVE_ORDER_LENGTH 12 /* fixed */ +#define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */ +#define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */ + +void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string); + +void rail_read_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake); +void rail_read_server_exec_result_order(STREAM* s, RAIL_EXEC_RESULT_ORDER* exec_result); +void rail_read_server_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam); +void rail_read_server_minmaxinfo_order(STREAM* s, RAIL_MINMAXINFO_ORDER* minmaxinfo); +void rail_read_server_localmovesize_order(STREAM* s, RAIL_LOCALMOVESIZE_ORDER* localmovesize); +void rail_read_server_get_appid_resp_order(STREAM* s, RAIL_GET_APPID_RESP_ORDER* get_appid_resp); +void rail_read_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info); + +void rail_write_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake); +void rail_write_client_status_order(STREAM* s, RAIL_CLIENT_STATUS_ORDER* client_status); +void rail_write_client_exec_order(STREAM* s, RAIL_EXEC_ORDER* exec); +void rail_write_client_sysparam_order(STREAM* s, RAIL_SYSPARAM_ORDER* sysparam); +void rail_write_client_activate_order(STREAM* s, RAIL_ACTIVATE_ORDER* activate); +void rail_write_client_sysmenu_order(STREAM* s, RAIL_SYSMENU_ORDER* sysmenu); +void rail_write_client_syscommand_order(STREAM* s, RAIL_SYSCOMMAND_ORDER* syscommand); +void rail_write_client_notify_event_order(STREAM* s, RAIL_NOTIFY_EVENT_ORDER* notify_event); +void rail_write_client_window_move_order(STREAM* s, RAIL_WINDOW_MOVE_ORDER* window_move); +void rail_write_client_get_appid_req_order(STREAM* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req); +void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info); + +void rail_order_recv(rdpRailOrder* rail_order, STREAM* s); + +void rail_send_handshake_order(rdpRailOrder* rail_order); +void rail_send_client_status_order(rdpRailOrder* rail_order); +void rail_send_client_exec_order(rdpRailOrder* rail_order); +void rail_send_client_sysparam_order(rdpRailOrder* rail_order); +void rail_send_client_sysparams_order(rdpRailOrder* rail_order); +void rail_send_client_activate_order(rdpRailOrder* rail_order); +void rail_send_client_sysmenu_order(rdpRailOrder* rail_order); +void rail_send_client_syscommand_order(rdpRailOrder* rail_order); +void rail_send_client_notify_event_order(rdpRailOrder* rail_order); +void rail_send_client_window_move_order(rdpRailOrder* rail_order); +void rail_send_client_get_appid_req_order(rdpRailOrder* rail_order); +void rail_send_client_langbar_info_order(rdpRailOrder* rail_order); + +rdpRailOrder* rail_order_new(); +void rail_order_free(rdpRailOrder* rail_order); + +#endif /* __RAIL_ORDERS_H */ diff --git a/channels/rdpdbg/CMakeLists.txt b/channels/rdpdbg/CMakeLists.txt new file mode 100644 index 0000000..db562a0 --- /dev/null +++ b/channels/rdpdbg/CMakeLists.txt @@ -0,0 +1,29 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPDBG_SRCS + rdpdbg_main.c +) + +add_library(rdpdbg ${RDPDBG_SRCS}) +set_target_properties(rdpdbg PROPERTIES PREFIX "") + +target_link_libraries(rdpdbg freerdp-utils) + +install(TARGETS rdpdbg DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdbg/rdpdbg_main.c b/channels/rdpdbg/rdpdbg_main.c new file mode 100644 index 0000000..c4d8217 --- /dev/null +++ b/channels/rdpdbg/rdpdbg_main.c @@ -0,0 +1,69 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Debugging Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +typedef struct rdpdbg_plugin rdpdbgPlugin; +struct rdpdbg_plugin +{ + rdpSvcPlugin plugin; +}; + +static void rdpdbg_process_connect(rdpSvcPlugin* plugin) +{ + DEBUG_WARN("connecting"); +} + +static void rdpdbg_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) +{ + STREAM* data_out; + + DEBUG_WARN("size %d", stream_get_size(data_in)); + stream_free(data_in); + + data_out = stream_new(8); + stream_write(data_out, "senddata", 8); + svc_plugin_send(plugin, data_out); +} + +static void rdpdbg_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + DEBUG_WARN("event_type %d", event->event_type); + freerdp_event_free(event); + + event = freerdp_event_new(RDP_EVENT_CLASS_DEBUG, 0, NULL, NULL); + svc_plugin_send_event(plugin, event); +} + +static void rdpdbg_process_terminate(rdpSvcPlugin* plugin) +{ + DEBUG_WARN("terminating"); + xfree(plugin); +} + +DEFINE_SVC_PLUGIN(rdpdbg, "rdpdbg", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL) diff --git a/channels/rdpdr/CMakeLists.txt b/channels/rdpdr/CMakeLists.txt new file mode 100644 index 0000000..e43aeff --- /dev/null +++ b/channels/rdpdr/CMakeLists.txt @@ -0,0 +1,47 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPDR_SRCS + rdpdr_constants.h + rdpdr_types.h + rdpdr_capabilities.c + rdpdr_capabilities.h + devman.c + devman.h + irp.c + irp.h + rdpdr_main.c + rdpdr_main.h +) + +add_library(rdpdr ${RDPDR_SRCS}) +set_target_properties(rdpdr PROPERTIES PREFIX "") + +target_link_libraries(rdpdr freerdp-utils) + +install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH}) + +add_subdirectory(disk) +add_subdirectory(printer) +add_subdirectory(parallel) +add_subdirectory(serial) + +if(WITH_PCSC) + add_subdirectory(smartcard) +endif() diff --git a/channels/rdpdr/devman.c b/channels/rdpdr/devman.c new file mode 100644 index 0000000..5c15b1f --- /dev/null +++ b/channels/rdpdr/devman.c @@ -0,0 +1,108 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_types.h" +#include "devman.h" + +DEVMAN* devman_new(rdpSvcPlugin* plugin) +{ + DEVMAN* devman; + + devman = xnew(DEVMAN); + devman->plugin = plugin; + devman->id_sequence = 1; + devman->devices = list_new(); + + return devman; +} + +void devman_free(DEVMAN* devman) +{ + DEVICE* device; + + while ((device = (DEVICE*) list_dequeue(devman->devices)) != NULL) + IFCALL(device->Free, device); + + list_free(devman->devices); + + xfree(devman); +} + +static void devman_register_device(DEVMAN* devman, DEVICE* device) +{ + device->id = devman->id_sequence++; + list_add(devman->devices, device); + + DEBUG_SVC("device %d.%s registered", device->id, device->name); +} + +static void devman_unregister_device(DEVMAN* devman, DEVICE* device) +{ + list_remove(devman->devices, device); + + DEBUG_SVC("device %d.%s unregistered", device->id, device->name); +} + +boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data) +{ + DEVICE_SERVICE_ENTRY_POINTS ep; + PDEVICE_SERVICE_ENTRY entry; + + entry = freerdp_load_plugin((char*) plugin_data->data[0], "DeviceServiceEntry"); + + if (entry == NULL) + return false; + + ep.devman = devman; + ep.RegisterDevice = devman_register_device; + ep.UnregisterDevice = devman_unregister_device; + ep.plugin_data = plugin_data; + + entry(&ep); + + return true; +} + +DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id) +{ + LIST_ITEM* item; + DEVICE* device; + + for (item = devman->devices->head; item; item = item->next) + { + device = (DEVICE*) item->data; + + if (device->id == id) + return device; + } + + return NULL; +} diff --git a/channels/rdpdr/devman.h b/channels/rdpdr/devman.h new file mode 100644 index 0000000..5860347 --- /dev/null +++ b/channels/rdpdr/devman.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEVMAN_H +#define __DEVMAN_H + +DEVMAN* devman_new(rdpSvcPlugin* plugin); +void devman_free(DEVMAN* devman); +boolean devman_load_device_service(DEVMAN* devman, RDP_PLUGIN_DATA* plugin_data); +DEVICE* devman_get_device_by_id(DEVMAN* devman, uint32 id); + +#endif /* __DEVMAN_H */ diff --git a/channels/rdpdr/disk/CMakeLists.txt b/channels/rdpdr/disk/CMakeLists.txt new file mode 100644 index 0000000..c1acd80 --- /dev/null +++ b/channels/rdpdr/disk/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(DISK_SRCS + disk_file.c + disk_file.h + disk_main.c +) + +include_directories(..) + +add_library(disk ${DISK_SRCS}) +set_target_properties(disk PROPERTIES PREFIX "") + +target_link_libraries(disk freerdp-utils) + +install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/disk/disk_file.c b/channels/rdpdr/disk/disk_file.c new file mode 100644 index 0000000..3221a25 --- /dev/null +++ b/channels/rdpdr/disk/disk_file.c @@ -0,0 +1,655 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WIN32 +#include +#endif + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" +#include "disk_file.h" + +#define FILE_TIME_SYSTEM_TO_RDP(_t) \ + (((uint64)(_t) + 11644473600LL) * 10000000LL) +#define FILE_TIME_RDP_TO_SYSTEM(_t) \ + (((_t) == 0LL || (_t) == (uint64)(-1LL)) ? 0 : (time_t)((_t) / 10000000LL - 11644473600LL)) + +#define FILE_ATTR_SYSTEM_TO_RDP(_f, _st) ( \ + (S_ISDIR(_st.st_mode) ? FILE_ATTRIBUTE_DIRECTORY : 0) | \ + (_f->filename[0] == '.' ? FILE_ATTRIBUTE_HIDDEN : 0) | \ + (_f->delete_pending ? FILE_ATTRIBUTE_TEMPORARY : 0) | \ + (st.st_mode & S_IWUSR ? 0 : FILE_ATTRIBUTE_READONLY)) + + +static boolean disk_file_wildcard_match(const char* pattern, const char* filename) +{ + const char *p = pattern, *f = filename; + char c; + + /* + * TODO: proper wildcard rules per msft's File System Behavior Overview + * Simple cases for now. + */ + f = filename; + while ((c = *p++)) + { + if (c == '*') + { + c = *p++; + if (!c) /* shortcut */ + return true; + /* TODO: skip to tail comparison */ + } + if (c != *f++) + return false; + } + + if (!*f) + return true; + + return false; +} + +static void disk_file_fix_path(char* path) +{ + int len; + int i; + + len = strlen(path); + for (i = 0; i < len; i++) + { + if (path[i] == '\\') + path[i] = '/'; + } + if (len > 0 && path[len - 1] == '/') + path[len - 1] = '\0'; +} + +static char* disk_file_combine_fullpath(const char* base_path, const char* path) +{ + char* fullpath; + + fullpath = xmalloc(strlen(base_path) + strlen(path) + 1); + strcpy(fullpath, base_path); + strcat(fullpath, path); + disk_file_fix_path(fullpath); + + return fullpath; +} + +static boolean disk_file_remove_dir(const char* path) +{ + DIR* dir; + struct dirent* pdirent; + struct stat st; + char* p; + boolean ret = true; + + dir = opendir(path); + if (dir == NULL) + return false; + + pdirent = readdir(dir); + while (pdirent) + { + if (strcmp(pdirent->d_name, ".") == 0 || strcmp(pdirent->d_name, "..") == 0) + { + pdirent = readdir(dir); + continue; + } + + p = xmalloc(strlen(path) + strlen(pdirent->d_name) + 2); + sprintf(p, "%s/%s", path, pdirent->d_name); + if (stat(p, &st) != 0) + { + DEBUG_WARN("stat %s failed.", p); + ret = false; + } + else if (S_ISDIR(st.st_mode)) + { + ret = disk_file_remove_dir(p); + } + else if (unlink(p) < 0) + { + DEBUG_WARN("unlink %s failed.", p); + ret = false; + } + else + ret = true; + xfree(p); + + if (!ret) + break; + + pdirent = readdir(dir); + } + + closedir(dir); + if (ret) + { + if (rmdir(path) < 0) + { + DEBUG_WARN("rmdir %s failed.", path); + ret = false; + } + } + + return ret; +} + +static void disk_file_set_fullpath(DISK_FILE* file, char* fullpath) +{ + xfree(file->fullpath); + file->fullpath = fullpath; + file->filename = strrchr(file->fullpath, '/'); + if (file->filename == NULL) + file->filename = file->fullpath; + else + file->filename += 1; +} + +static boolean disk_file_init(DISK_FILE* file, uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions) +{ + const static int mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + struct stat st; + boolean exists; + int oflag = 0; + + if (stat(file->fullpath, &st) == 0) + { + file->is_dir = (S_ISDIR(st.st_mode) ? true : false); + exists = true; + } + else + { + file->is_dir = ((CreateOptions & FILE_DIRECTORY_FILE) ? true : false); + if (file->is_dir) + { + if (mkdir(file->fullpath, mode) != 0) + { + file->err = errno; + return true; + } + } + exists = false; + } + if (file->is_dir) + { + file->dir = opendir(file->fullpath); + if (file->dir == NULL) + { + file->err = errno; + return true; + } + } + else + { + switch (CreateDisposition) + { + case FILE_SUPERSEDE: + oflag = O_TRUNC | O_CREAT; + break; + case FILE_OPEN: + break; + case FILE_CREATE: + oflag = O_CREAT | O_EXCL; + break; + case FILE_OPEN_IF: + oflag = O_CREAT; + break; + case FILE_OVERWRITE: + oflag = O_TRUNC; + break; + case FILE_OVERWRITE_IF: + oflag = O_TRUNC | O_CREAT; + break; + default: + break; + } + + if (CreateOptions & FILE_DELETE_ON_CLOSE && DesiredAccess & DELETE) + { + file->delete_pending = true; + } + + if ((DesiredAccess & GENERIC_ALL) + || (DesiredAccess & GENERIC_WRITE) + || (DesiredAccess & FILE_WRITE_DATA) + || (DesiredAccess & FILE_APPEND_DATA)) + { + oflag |= O_RDWR; + } + else + { + oflag |= O_RDONLY; + } + + file->fd = open(file->fullpath, oflag, mode); + if (file->fd == -1) + { + file->err = errno; + return true; + } + } + + return true; +} + +DISK_FILE* disk_file_new(const char* base_path, const char* path, uint32 id, + uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions) +{ + DISK_FILE* file; + + file = xnew(DISK_FILE); + file->id = id; + file->basepath = (char*) base_path; + disk_file_set_fullpath(file, disk_file_combine_fullpath(base_path, path)); + file->fd = -1; + + if (!disk_file_init(file, DesiredAccess, CreateDisposition, CreateOptions)) + { + disk_file_free(file); + return NULL; + } + + return file; +} + +void disk_file_free(DISK_FILE* file) +{ + if (file->fd != -1) + close(file->fd); + if (file->dir != NULL) + closedir(file->dir); + + if (file->delete_pending) + { + if (file->is_dir) + disk_file_remove_dir(file->fullpath); + else + unlink(file->fullpath); + } + + xfree(file->pattern); + xfree(file->fullpath); + xfree(file); +} + +boolean disk_file_seek(DISK_FILE* file, uint64 Offset) +{ + if (file->is_dir || file->fd == -1) + return false; + + if (lseek(file->fd, Offset, SEEK_SET) == (off_t)-1) + return false; + + return true; +} + +boolean disk_file_read(DISK_FILE* file, uint8* buffer, uint32* Length) +{ + ssize_t r; + + if (file->is_dir || file->fd == -1) + return false; + + r = read(file->fd, buffer, *Length); + if (r < 0) + return false; + *Length = (uint32)r; + + return true; +} + +boolean disk_file_write(DISK_FILE* file, uint8* buffer, uint32 Length) +{ + ssize_t r; + + if (file->is_dir || file->fd == -1) + return false; + + while (Length > 0) + { + r = write(file->fd, buffer, Length); + if (r == -1) + return false; + Length -= r; + buffer += r; + } + + return true; +} + +boolean disk_file_query_information(DISK_FILE* file, uint32 FsInformationClass, STREAM* output) +{ + struct stat st; + + if (stat(file->fullpath, &st) != 0) + { + stream_write_uint32(output, 0); /* Length */ + return false; + } + switch (FsInformationClass) + { + case FileBasicInformation: + /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ + stream_write_uint32(output, 36); /* Length */ + stream_check_size(output, 36); + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + /* Reserved(4), MUST NOT be added! */ + break; + + case FileStandardInformation: + /* http://msdn.microsoft.com/en-us/library/cc232088.aspx */ + stream_write_uint32(output, 22); /* Length */ + stream_check_size(output, 22); + stream_write_uint64(output, st.st_size); /* AllocationSize */ + stream_write_uint64(output, st.st_size); /* EndOfFile */ + stream_write_uint32(output, st.st_nlink); /* NumberOfLinks */ + stream_write_uint8(output, file->delete_pending ? 1 : 0); /* DeletePending */ + stream_write_uint8(output, file->is_dir ? 1 : 0); /* Directory */ + /* Reserved(2), MUST NOT be added! */ + break; + + case FileAttributeTagInformation: + /* http://msdn.microsoft.com/en-us/library/cc232093.aspx */ + stream_write_uint32(output, 8); /* Length */ + stream_check_size(output, 8); + stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + stream_write_uint32(output, 0); /* ReparseTag */ + break; + + default: + stream_write_uint32(output, 0); /* Length */ + DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); + return false; + } + return true; +} + +boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, uint32 Length, STREAM* input) +{ + char* s; + mode_t m; + uint64 size; + char* fullpath; + struct stat st; + UNICONV* uniconv; + struct timeval tv[2]; + uint64 LastWriteTime; + uint32 FileAttributes; + uint32 FileNameLength; + + switch (FsInformationClass) + { + case FileBasicInformation: + /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ + stream_seek_uint64(input); /* CreationTime */ + stream_seek_uint64(input); /* LastAccessTime */ + stream_read_uint64(input, LastWriteTime); + stream_seek_uint64(input); /* ChangeTime */ + stream_read_uint32(input, FileAttributes); + + if (fstat(file->fd, &st) != 0) + return false; + + tv[0].tv_sec = st.st_atime; + tv[0].tv_usec = 0; + tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime); + tv[1].tv_usec = 0; + futimes(file->fd, tv); + + if (FileAttributes > 0) + { + m = st.st_mode; + if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0) + m |= S_IWUSR; + else + m &= ~S_IWUSR; + if (m != st.st_mode) + fchmod(file->fd, st.st_mode); + } + break; + + case FileEndOfFileInformation: + /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ + case FileAllocationInformation: + /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ + stream_read_uint64(input, size); + if (ftruncate(file->fd, size) != 0) + return false; + break; + + case FileDispositionInformation: + /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ + /* http://msdn.microsoft.com/en-us/library/cc241371.aspx */ + if (Length) + stream_read_uint8(input, file->delete_pending); + else + file->delete_pending = 1; + break; + + case FileRenameInformation: + /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ + stream_seek_uint8(input); /* ReplaceIfExists */ + stream_seek_uint8(input); /* RootDirectory */ + stream_read_uint32(input, FileNameLength); + uniconv = freerdp_uniconv_new(); + s = freerdp_uniconv_in(uniconv, stream_get_tail(input), FileNameLength); + freerdp_uniconv_free(uniconv); + + fullpath = disk_file_combine_fullpath(file->basepath, s); + xfree(s); + + if (rename(file->fullpath, fullpath) == 0) + { + DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath); + disk_file_set_fullpath(file, fullpath); + } + else + { + DEBUG_WARN("rename %s to %s failed", file->fullpath, fullpath); + free(fullpath); + return false; + } + + break; + + default: + DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); + return false; + } + + return true; +} + +boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, + const char* path, STREAM* output) +{ + struct dirent* ent; + char* ent_path; + struct stat st; + UNICONV* uniconv; + size_t len; + boolean ret; + + DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery); + + if (!file->dir) + { + stream_write_uint32(output, 0); /* Length */ + stream_write_uint8(output, 0); /* Padding */ + return false; + } + + if (InitialQuery != 0) + { + rewinddir(file->dir); + xfree(file->pattern); + + if (path[0]) + file->pattern = strdup(strrchr(path, '\\') + 1); + else + file->pattern = NULL; + } + + if (file->pattern) + { + do + { + ent = readdir(file->dir); + if (ent == NULL) + continue; + + if (disk_file_wildcard_match(file->pattern, ent->d_name)) + break; + } while (ent); + } + else + { + ent = readdir(file->dir); + } + + if (ent == NULL) + { + DEBUG_SVC(" pattern %s not found.", file->pattern); + stream_write_uint32(output, 0); /* Length */ + stream_write_uint8(output, 0); /* Padding */ + return false; + } + + memset(&st, 0, sizeof(struct stat)); + ent_path = xmalloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); + sprintf(ent_path, "%s/%s", file->fullpath, ent->d_name); + if (stat(ent_path, &st) != 0) + { + DEBUG_WARN("stat %s failed.", ent_path); + } + xfree(ent_path); + + DEBUG_SVC(" pattern %s matched %s\n", file->pattern, ent_path); + + uniconv = freerdp_uniconv_new(); + ent_path = freerdp_uniconv_out(uniconv, ent->d_name, &len); + freerdp_uniconv_free(uniconv); + + ret = true; + switch (FsInformationClass) + { + case FileDirectoryInformation: + /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ + stream_write_uint32(output, 64 + len); /* Length */ + stream_check_size(output, 64 + len); + stream_write_uint32(output, 0); /* NextEntryOffset */ + stream_write_uint32(output, 0); /* FileIndex */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + stream_write_uint64(output, st.st_size); /* EndOfFile */ + stream_write_uint64(output, st.st_size); /* AllocationSize */ + stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + stream_write_uint32(output, len); /* FileNameLength */ + stream_write(output, ent_path, len); + break; + + case FileFullDirectoryInformation: + /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ + stream_write_uint32(output, 68 + len); /* Length */ + stream_check_size(output, 68 + len); + stream_write_uint32(output, 0); /* NextEntryOffset */ + stream_write_uint32(output, 0); /* FileIndex */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + stream_write_uint64(output, st.st_size); /* EndOfFile */ + stream_write_uint64(output, st.st_size); /* AllocationSize */ + stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + stream_write_uint32(output, len); /* FileNameLength */ + stream_write_uint32(output, 0); /* EaSize */ + stream_write(output, ent_path, len); + break; + + case FileBothDirectoryInformation: + /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ + stream_write_uint32(output, 93 + len); /* Length */ + stream_check_size(output, 93 + len); + stream_write_uint32(output, 0); /* NextEntryOffset */ + stream_write_uint32(output, 0); /* FileIndex */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ + stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ + stream_write_uint64(output, st.st_size); /* EndOfFile */ + stream_write_uint64(output, st.st_size); /* AllocationSize */ + stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ + stream_write_uint32(output, len); /* FileNameLength */ + stream_write_uint32(output, 0); /* EaSize */ + stream_write_uint8(output, 0); /* ShortNameLength */ + /* Reserved(1), MUST NOT be added! */ + stream_write_zero(output, 24); /* ShortName */ + stream_write(output, ent_path, len); + break; + + case FileNamesInformation: + /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ + stream_write_uint32(output, 12 + len); /* Length */ + stream_check_size(output, 12 + len); + stream_write_uint32(output, 0); /* NextEntryOffset */ + stream_write_uint32(output, 0); /* FileIndex */ + stream_write_uint32(output, len); /* FileNameLength */ + stream_write(output, ent_path, len); + break; + + default: + stream_write_uint32(output, 0); /* Length */ + stream_write_uint8(output, 0); /* Padding */ + DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); + ret = false; + break; + } + + xfree(ent_path); + + return ret; +} diff --git a/channels/rdpdr/disk/disk_file.h b/channels/rdpdr/disk/disk_file.h new file mode 100644 index 0000000..e833cf6 --- /dev/null +++ b/channels/rdpdr/disk/disk_file.h @@ -0,0 +1,55 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DISK_FILE_H +#define __DISK_FILE_H + +#include +#include +#include + +typedef struct _DISK_FILE DISK_FILE; +struct _DISK_FILE +{ + uint32 id; + boolean is_dir; + int fd; + int err; + DIR* dir; + char* basepath; + char* fullpath; + char* filename; + char* pattern; + boolean delete_pending; +}; + +DISK_FILE* disk_file_new(const char* base_path, const char* path, uint32 id, + uint32 DesiredAccess, uint32 CreateDisposition, uint32 CreateOptions); +void disk_file_free(DISK_FILE* file); + +boolean disk_file_seek(DISK_FILE* file, uint64 Offset); +boolean disk_file_read(DISK_FILE* file, uint8* buffer, uint32* Length); +boolean disk_file_write(DISK_FILE* file, uint8* buffer, uint32 Length); +boolean disk_file_query_information(DISK_FILE* file, uint32 FsInformationClass, STREAM* output); +boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, uint32 Length, STREAM* input); +boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, + const char* path, STREAM* output); + +#endif /* __DISK_FILE_H */ diff --git a/channels/rdpdr/disk/disk_main.c b/channels/rdpdr/disk/disk_main.c new file mode 100644 index 0000000..5f820c6 --- /dev/null +++ b/channels/rdpdr/disk/disk_main.c @@ -0,0 +1,651 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" +#include "disk_file.h" + +typedef struct _DISK_DEVICE DISK_DEVICE; +struct _DISK_DEVICE +{ + DEVICE device; + + char* path; + LIST* files; + + LIST* irp_list; + freerdp_thread* thread; +}; + + +static uint32 +disk_map_posix_err(int fs_errno) +{ + uint32 rc; + + /* try to return NTSTATUS version of error code */ + switch (fs_errno) + { + case EPERM: + case EACCES: + rc = STATUS_ACCESS_DENIED; + break; + case ENOENT: + rc = STATUS_NO_SUCH_FILE; + break; + case EBUSY: + rc = STATUS_DEVICE_BUSY; + break; + case EEXIST: + rc = STATUS_OBJECT_NAME_COLLISION; + break; + case EISDIR: + rc = STATUS_FILE_IS_A_DIRECTORY; + break; + + default: + rc = STATUS_UNSUCCESSFUL; + break; + } + DEBUG_SVC("errno 0x%x mapped to 0x%x\n", fs_errno, rc); + return rc; +} + +static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, uint32 id) +{ + LIST_ITEM* item; + DISK_FILE* file; + + for (item = disk->files->head; item; item = item->next) + { + file = (DISK_FILE*)item->data; + if (file->id == id) + return file; + } + return NULL; +} + +static void disk_process_irp_create(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 DesiredAccess; + uint32 CreateDisposition; + uint32 CreateOptions; + uint32 PathLength; + UNICONV* uniconv; + char* path; + uint32 FileId; + uint8 Information; + + stream_read_uint32(irp->input, DesiredAccess); + stream_seek(irp->input, 16); /* AllocationSize(8), FileAttributes(4), SharedAccess(4) */ + stream_read_uint32(irp->input, CreateDisposition); + stream_read_uint32(irp->input, CreateOptions); + stream_read_uint32(irp->input, PathLength); + + uniconv = freerdp_uniconv_new(); + path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); + freerdp_uniconv_free(uniconv); + + FileId = irp->devman->id_sequence++; + file = disk_file_new(disk->path, path, FileId, + DesiredAccess, CreateDisposition, CreateOptions); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + FileId = 0; + Information = 0; + + DEBUG_WARN("failed to create %s.", path); + } + else if (file->err) + { + FileId = 0; + Information = 0; + + /* map errno to windows result*/ + irp->IoStatus = disk_map_posix_err(file->err); + + disk_file_free(file); + } + else + { + list_enqueue(disk->files, file); + + switch (CreateDisposition) + { + case FILE_SUPERSEDE: + case FILE_OPEN: + case FILE_CREATE: + case FILE_OVERWRITE: + Information = FILE_SUPERSEDED; + break; + case FILE_OPEN_IF: + Information = FILE_OPENED; + break; + case FILE_OVERWRITE_IF: + Information = FILE_OVERWRITTEN; + break; + default: + Information = 0; + break; + } + DEBUG_SVC("%s(%d) created.", file->fullpath, file->id); + } + + stream_write_uint32(irp->output, FileId); + stream_write_uint8(irp->output, Information); + + xfree(path); + + irp->Complete(irp); +} + +static void disk_process_irp_close(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else + { + DEBUG_SVC("%s(%d) closed.", file->fullpath, file->id); + + list_remove(disk->files, file); + disk_file_free(file); + } + + stream_write_zero(irp->output, 5); /* Padding(5) */ + + irp->Complete(irp); +} + +static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 Length; + uint64 Offset; + uint8* buffer = NULL; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else if (!disk_file_seek(file, Offset)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id); + } + else + { + buffer = (uint8*)xmalloc(Length); + if (!disk_file_read(file, buffer, &Length)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + xfree(buffer); + buffer = NULL; + Length = 0; + + DEBUG_WARN("read %s(%d) failed.", file->fullpath, file->id); + } + else + { + DEBUG_SVC("read %llu-%llu from %s(%d).", Offset, Offset + Length, file->fullpath, file->id); + } + } + + stream_write_uint32(irp->output, Length); + if (Length > 0) + { + stream_check_size(irp->output, Length); + stream_write(irp->output, buffer, Length); + } + xfree(buffer); + + irp->Complete(irp); +} + +static void disk_process_irp_write(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 Length; + uint64 Offset; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + stream_seek(irp->input, 20); /* Padding */ + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else if (!disk_file_seek(file, Offset)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("seek %s(%d) failed.", file->fullpath, file->id); + } + else if (!disk_file_write(file, stream_get_tail(irp->input), Length)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("write %s(%d) failed.", file->fullpath, file->id); + } + else + { + DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, file->fullpath, file->id); + } + + stream_write_uint32(irp->output, Length); + stream_write_uint8(irp->output, 0); /* Padding */ + + irp->Complete(irp); +} + +static void disk_process_irp_query_information(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 FsInformationClass; + + stream_read_uint32(irp->input, FsInformationClass); + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else if (!disk_file_query_information(file, FsInformationClass, irp->output)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("FsInformationClass %d on %s(%d) failed.", FsInformationClass, file->fullpath, file->id); + } + else + { + DEBUG_SVC("FsInformationClass %d on %s(%d).", FsInformationClass, file->fullpath, file->id); + } + + irp->Complete(irp); +} + +static void disk_process_irp_set_information(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 FsInformationClass; + uint32 Length; + + stream_read_uint32(irp->input, FsInformationClass); + stream_read_uint32(irp->input, Length); + stream_seek(irp->input, 24); /* Padding */ + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else if (!disk_file_set_information(file, FsInformationClass, Length, irp->input)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("FsInformationClass %d on %s(%d) failed.", FsInformationClass, file->fullpath, file->id); + } + else + { + DEBUG_SVC("FsInformationClass %d on %s(%d) ok.", FsInformationClass, file->fullpath, file->id); + } + + stream_write_uint32(irp->output, Length); + + irp->Complete(irp); +} + +static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* irp) +{ + uint32 FsInformationClass; + STREAM* output = irp->output; + + stream_read_uint32(irp->input, FsInformationClass); + + switch (FsInformationClass) + { + case FileFsVolumeInformation: + /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ + stream_write_uint32(output, 34); /* Length */ + stream_check_size(output, 34); + stream_write_uint64(output, 0); /* VolumeCreationTime */ + stream_write_uint32(output, 0); /* VolumeSerialNumber */ + stream_write_uint32(output, 16); /* VolumeLabelLength */ + stream_write_uint8(output, 0); /* SupportsObjects */ + stream_write_uint8(output, 0); /* Reserved */ + stream_write(output, "F\0R\0E\0E\0R\0D\0P\0\0\0", 16); /* VolumeLabel (Unicode) */ + break; + + case FileFsSizeInformation: + /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ + stream_write_uint32(output, 24); /* Length */ + stream_check_size(output, 24); + stream_write_uint64(output, 0x1000000); /* TotalAllocationUnits */ + stream_write_uint64(output, 0x800000); /* AvailableAllocationUnits */ + stream_write_uint32(output, 1); /* SectorsPerAllocationUnit */ + stream_write_uint32(output, 0x400); /* BytesPerSector */ + break; + + case FileFsAttributeInformation: + /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ + stream_write_uint32(output, 22); /* Length */ + stream_check_size(output, 22); + stream_write_uint32(output, + FILE_CASE_SENSITIVE_SEARCH | + FILE_CASE_PRESERVED_NAMES | + FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ + stream_write_uint32(output, 510); /* MaximumComponentNameLength */ + stream_write_uint32(output, 10); /* FileSystemNameLength */ + stream_write(output, "F\0A\0T\03\02\0", 10); /* FileSystemName */ + break; + + case FileFsFullSizeInformation: + /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ + stream_write_uint32(output, 32); /* Length */ + stream_check_size(output, 32); + stream_write_uint64(output, 0x1000000); /* TotalAllocationUnits */ + stream_write_uint64(output, 0x800000); /* CallerAvailableAllocationUnits */ + stream_write_uint64(output, 0x800000); /* ActualAvailableAllocationUnits */ + stream_write_uint32(output, 1); /* SectorsPerAllocationUnit */ + stream_write_uint32(output, 0x400); /* BytesPerSector */ + break; + + case FileFsDeviceInformation: + /* http://msdn.microsoft.com/en-us/library/cc232109.aspx */ + stream_write_uint32(output, 8); /* Length */ + stream_check_size(output, 8); + stream_write_uint32(output, FILE_DEVICE_DISK); /* DeviceType */ + stream_write_uint32(output, 0); /* Characteristics */ + break; + + default: + irp->IoStatus = STATUS_UNSUCCESSFUL; + stream_write_uint32(output, 0); /* Length */ + DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); + break; + } + + irp->Complete(irp); +} + +static void disk_process_irp_query_directory(DISK_DEVICE* disk, IRP* irp) +{ + DISK_FILE* file; + uint32 FsInformationClass; + uint8 InitialQuery; + uint32 PathLength; + UNICONV* uniconv; + char* path; + + stream_read_uint32(irp->input, FsInformationClass); + stream_read_uint8(irp->input, InitialQuery); + stream_read_uint32(irp->input, PathLength); + stream_seek(irp->input, 23); /* Padding */ + + uniconv = freerdp_uniconv_new(); + path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); + freerdp_uniconv_free(uniconv); + + file = disk_get_file_by_id(disk, irp->FileId); + + if (file == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + stream_write_uint32(irp->output, 0); /* Length */ + DEBUG_WARN("FileId %d not valid.", irp->FileId); + } + else if (!disk_file_query_directory(file, FsInformationClass, InitialQuery, path, irp->output)) + { + irp->IoStatus = STATUS_NO_MORE_FILES; + } + + xfree(path); + + irp->Complete(irp); +} + +static void disk_process_irp_directory_control(DISK_DEVICE* disk, IRP* irp) +{ + switch (irp->MinorFunction) + { + case IRP_MN_QUERY_DIRECTORY: + disk_process_irp_query_directory(disk, irp); + break; + + case IRP_MN_NOTIFY_CHANGE_DIRECTORY: /* TODO */ + irp->Discard(irp); + break; + + default: + DEBUG_WARN("MinorFunction 0x%X not supported", irp->MinorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + stream_write_uint32(irp->output, 0); /* Length */ + irp->Complete(irp); + break; + } +} + +static void disk_process_irp_device_control(DISK_DEVICE* disk, IRP* irp) +{ + stream_write_uint32(irp->output, 0); /* OutputBufferLength */ + irp->Complete(irp); +} + +static void disk_process_irp(DISK_DEVICE* disk, IRP* irp) +{ + switch (irp->MajorFunction) + { + case IRP_MJ_CREATE: + disk_process_irp_create(disk, irp); + break; + + case IRP_MJ_CLOSE: + disk_process_irp_close(disk, irp); + break; + + case IRP_MJ_READ: + disk_process_irp_read(disk, irp); + break; + + case IRP_MJ_WRITE: + disk_process_irp_write(disk, irp); + break; + + case IRP_MJ_QUERY_INFORMATION: + disk_process_irp_query_information(disk, irp); + break; + + case IRP_MJ_SET_INFORMATION: + disk_process_irp_set_information(disk, irp); + break; + + case IRP_MJ_QUERY_VOLUME_INFORMATION: + disk_process_irp_query_volume_information(disk, irp); + break; + + case IRP_MJ_DIRECTORY_CONTROL: + disk_process_irp_directory_control(disk, irp); + break; + + case IRP_MJ_DEVICE_CONTROL: + disk_process_irp_device_control(disk, irp); + break; + + default: + DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + irp->Complete(irp); + break; + } +} + +static void disk_process_irp_list(DISK_DEVICE* disk) +{ + IRP* irp; + + while (1) + { + if (freerdp_thread_is_stopped(disk->thread)) + break; + + freerdp_thread_lock(disk->thread); + irp = (IRP*)list_dequeue(disk->irp_list); + freerdp_thread_unlock(disk->thread); + + if (irp == NULL) + break; + + disk_process_irp(disk, irp); + } +} + +static void* disk_thread_func(void* arg) +{ + DISK_DEVICE* disk = (DISK_DEVICE*)arg; + + while (1) + { + freerdp_thread_wait(disk->thread); + + if (freerdp_thread_is_stopped(disk->thread)) + break; + + freerdp_thread_reset(disk->thread); + disk_process_irp_list(disk); + } + + freerdp_thread_quit(disk->thread); + + return NULL; +} + +static void disk_irp_request(DEVICE* device, IRP* irp) +{ + DISK_DEVICE* disk = (DISK_DEVICE*)device; + + freerdp_thread_lock(disk->thread); + list_enqueue(disk->irp_list, irp); + freerdp_thread_unlock(disk->thread); + + freerdp_thread_signal(disk->thread); +} + +static void disk_free(DEVICE* device) +{ + DISK_DEVICE* disk = (DISK_DEVICE*)device; + IRP* irp; + DISK_FILE* file; + + freerdp_thread_stop(disk->thread); + freerdp_thread_free(disk->thread); + + while ((irp = (IRP*)list_dequeue(disk->irp_list)) != NULL) + irp->Discard(irp); + list_free(disk->irp_list); + + while ((file = (DISK_FILE*)list_dequeue(disk->files)) != NULL) + disk_file_free(file); + list_free(disk->files); + xfree(disk); +} + +int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + DISK_DEVICE* disk; + char* name; + char* path; + int i, len; + + name = (char*)pEntryPoints->plugin_data->data[1]; + path = (char*)pEntryPoints->plugin_data->data[2]; + + if (name[0] && path[0]) + { + disk = xnew(DISK_DEVICE); + + disk->device.type = RDPDR_DTYP_FILESYSTEM; + disk->device.name = name; + disk->device.IRPRequest = disk_irp_request; + disk->device.Free = disk_free; + + len = strlen(name); + disk->device.data = stream_new(len + 1); + for (i = 0; i <= len; i++) + stream_write_uint8(disk->device.data, name[i] < 0 ? '_' : name[i]); + + disk->path = path; + disk->files = list_new(); + + disk->irp_list = list_new(); + disk->thread = freerdp_thread_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)disk); + + freerdp_thread_start(disk->thread, disk_thread_func, disk); + } + + return 0; +} diff --git a/channels/rdpdr/irp.c b/channels/rdpdr/irp.c new file mode 100644 index 0000000..3668b1c --- /dev/null +++ b/channels/rdpdr/irp.c @@ -0,0 +1,97 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" +#include "devman.h" +#include "irp.h" + +static void irp_free(IRP* irp) +{ + DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); + + stream_free(irp->input); + stream_free(irp->output); + xfree(irp); +} + +static void irp_complete(IRP* irp) +{ + int pos; + + DEBUG_SVC("DeviceId %d FileId %d CompletionId %d", irp->device->id, irp->FileId, irp->CompletionId); + + pos = stream_get_pos(irp->output); + stream_set_pos(irp->output, 12); + stream_write_uint32(irp->output, irp->IoStatus); + stream_set_pos(irp->output, pos); + + svc_plugin_send(irp->devman->plugin, irp->output); + irp->output = NULL; + + irp_free(irp); +} + +IRP* irp_new(DEVMAN* devman, STREAM* data_in) +{ + IRP* irp; + uint32 DeviceId; + DEVICE* device; + + stream_read_uint32(data_in, DeviceId); + device = devman_get_device_by_id(devman, DeviceId); + if (device == NULL) + { + DEBUG_WARN("unknown DeviceId %d", DeviceId); + return NULL; + } + + irp = xnew(IRP); + irp->device = device; + irp->devman = devman; + stream_read_uint32(data_in, irp->FileId); + stream_read_uint32(data_in, irp->CompletionId); + stream_read_uint32(data_in, irp->MajorFunction); + stream_read_uint32(data_in, irp->MinorFunction); + irp->input = data_in; + + irp->output = stream_new(256); + stream_write_uint16(irp->output, RDPDR_CTYP_CORE); + stream_write_uint16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); + stream_write_uint32(irp->output, DeviceId); + stream_write_uint32(irp->output, irp->CompletionId); + stream_seek_uint32(irp->output); /* IoStatus */ + + irp->Complete = irp_complete; + irp->Discard = irp_free; + + DEBUG_SVC("DeviceId %d FileId %d CompletionId %d MajorFunction 0x%X MinorFunction 0x%x", + irp->device->id, irp->FileId, irp->CompletionId, irp->MajorFunction, irp->MinorFunction); + + return irp; +} diff --git a/channels/rdpdr/irp.h b/channels/rdpdr/irp.h new file mode 100644 index 0000000..d33e518 --- /dev/null +++ b/channels/rdpdr/irp.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IRP_H +#define __IRP_H + +#include "rdpdr_types.h" + +IRP* irp_new(DEVMAN* devman, STREAM* data_in); + +#endif /* __IRP_H */ diff --git a/channels/rdpdr/parallel/CMakeLists.txt b/channels/rdpdr/parallel/CMakeLists.txt new file mode 100644 index 0000000..44387f5 --- /dev/null +++ b/channels/rdpdr/parallel/CMakeLists.txt @@ -0,0 +1,31 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(PARALLEL_SRCS + parallel_main.c +) + +include_directories(..) + +add_library(parallel ${PARALLEL_SRCS}) +set_target_properties(parallel PROPERTIES PREFIX "") + +target_link_libraries(parallel freerdp-utils) + +install(TARGETS parallel DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/parallel/parallel_main.c b/channels/rdpdr/parallel/parallel_main.c new file mode 100644 index 0000000..934def0 --- /dev/null +++ b/channels/rdpdr/parallel/parallel_main.c @@ -0,0 +1,335 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Redirected Parallel Port Device Service + * + * Copyright 2010 O.S. Systems Software Ltda. + * Copyright 2010 Eduardo Fiss Beloni + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef __LINUX__ +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" + +struct _PARALLEL_DEVICE +{ + DEVICE device; + + int file; + char* path; + uint32 id; + + LIST* irp_list; + freerdp_thread* thread; +}; +typedef struct _PARALLEL_DEVICE PARALLEL_DEVICE; + +static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) +{ + uint32 PathLength; + char* path; + UNICONV* uniconv; + + stream_seek(irp->input, 28); + /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ + /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ + stream_read_uint32(irp->input, PathLength); + + uniconv = freerdp_uniconv_new(); + path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); + freerdp_uniconv_free(uniconv); + + parallel->id = irp->devman->id_sequence++; + parallel->file = open(parallel->path, O_RDWR); + if (parallel->file < 0) + { + irp->IoStatus = STATUS_ACCESS_DENIED; + parallel->id = 0; + + DEBUG_WARN("failed to create %s: %s", parallel->path, strerror(errno)); + } + else + { + /* all read and write operations should be non-blocking */ + if (fcntl(parallel->file, F_SETFL, O_NONBLOCK) == -1) + DEBUG_WARN("%s fcntl %s", path, strerror(errno)); + + DEBUG_SVC("%s(%d) created", parallel->path, parallel->file); + } + + stream_write_uint32(irp->output, parallel->id); + stream_write_uint8(irp->output, 0); + + xfree(path); + + irp->Complete(irp); +} + +static void parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp) +{ + if (close(parallel->file) < 0) + DEBUG_SVC("failed to close %s(%d)", parallel->path, parallel->id); + else + DEBUG_SVC("%s(%d) closed", parallel->path, parallel->id); + + stream_write_zero(irp->output, 5); /* Padding(5) */ + + irp->Complete(irp); +} + +static void parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp) +{ + uint32 Length; + uint64 Offset; + ssize_t status; + uint8* buffer = NULL; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + + buffer = (uint8*) xmalloc(Length); + + status = read(parallel->file, irp->output->p, Length); + + if (status < 0) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + xfree(buffer); + buffer = NULL; + Length = 0; + + DEBUG_WARN("read %s(%d) failed", parallel->path, parallel->id); + } + else + { + DEBUG_SVC("read %llu-%llu from %d", Offset, Offset + Length, parallel->id); + } + + stream_write_uint32(irp->output, Length); + if (Length > 0) + { + stream_check_size(irp->output, Length); + stream_write(irp->output, buffer, Length); + } + xfree(buffer); + + irp->Complete(irp); +} + +static void parallel_process_irp_write(PARALLEL_DEVICE* parallel, IRP* irp) +{ + uint32 Length; + uint64 Offset; + ssize_t status; + uint32 len; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + stream_seek(irp->input, 20); /* Padding */ + + DEBUG_SVC("Length %u Offset %llu", Length, Offset); + + len = Length; + while (len > 0) + { + status = write(parallel->file, stream_get_tail(irp->input), len); + + if (status < 0) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("write %s(%d) failed.", parallel->path, parallel->id); + break; + } + + stream_seek(irp->input, status); + len -= status; + } + + stream_write_uint32(irp->output, Length); + stream_write_uint8(irp->output, 0); /* Padding */ + + irp->Complete(irp); +} + +static void parallel_process_irp_device_control(PARALLEL_DEVICE* parallel, IRP* irp) +{ + DEBUG_SVC("in"); + stream_write_uint32(irp->output, 0); /* OutputBufferLength */ + irp->Complete(irp); +} + +static void parallel_process_irp(PARALLEL_DEVICE* parallel, IRP* irp) +{ + DEBUG_SVC("MajorFunction %u", irp->MajorFunction); + + switch (irp->MajorFunction) + { + case IRP_MJ_CREATE: + parallel_process_irp_create(parallel, irp); + break; + + case IRP_MJ_CLOSE: + parallel_process_irp_close(parallel, irp); + break; + + case IRP_MJ_READ: + parallel_process_irp_read(parallel, irp); + break; + + case IRP_MJ_WRITE: + parallel_process_irp_write(parallel, irp); + break; + + case IRP_MJ_DEVICE_CONTROL: + parallel_process_irp_device_control(parallel, irp); + break; + + default: + DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + irp->Complete(irp); + break; + } +} + +static void parallel_process_irp_list(PARALLEL_DEVICE* parallel) +{ + IRP* irp; + + while (1) + { + if (freerdp_thread_is_stopped(parallel->thread)) + break; + + freerdp_thread_lock(parallel->thread); + irp = (IRP*) list_dequeue(parallel->irp_list); + freerdp_thread_unlock(parallel->thread); + + if (irp == NULL) + break; + + parallel_process_irp(parallel, irp); + } +} + +static void* parallel_thread_func(void* arg) +{ + PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) arg; + + while (1) + { + freerdp_thread_wait(parallel->thread); + + if (freerdp_thread_is_stopped(parallel->thread)) + break; + + freerdp_thread_reset(parallel->thread); + parallel_process_irp_list(parallel); + } + + freerdp_thread_quit(parallel->thread); + + return NULL; +} + +static void parallel_irp_request(DEVICE* device, IRP* irp) +{ + PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; + + freerdp_thread_lock(parallel->thread); + list_enqueue(parallel->irp_list, irp); + freerdp_thread_unlock(parallel->thread); + + freerdp_thread_signal(parallel->thread); +} + +static void parallel_free(DEVICE* device) +{ + IRP* irp; + PARALLEL_DEVICE* parallel = (PARALLEL_DEVICE*) device; + + DEBUG_SVC("freeing device"); + + freerdp_thread_stop(parallel->thread); + freerdp_thread_free(parallel->thread); + + while ((irp = (IRP*) list_dequeue(parallel->irp_list)) != NULL) + irp->Discard(irp); + + list_free(parallel->irp_list); + + xfree(parallel); +} + +int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + char* name; + char* path; + int i, length; + PARALLEL_DEVICE* parallel; + + name = (char*) pEntryPoints->plugin_data->data[1]; + path = (char*) pEntryPoints->plugin_data->data[2]; + + if (name[0] && path[0]) + { + parallel = xnew(PARALLEL_DEVICE); + + parallel->device.type = RDPDR_DTYP_PARALLEL; + parallel->device.name = name; + parallel->device.IRPRequest = parallel_irp_request; + parallel->device.Free = parallel_free; + + length = strlen(name); + parallel->device.data = stream_new(length + 1); + + for (i = 0; i <= length; i++) + stream_write_uint8(parallel->device.data, name[i] < 0 ? '_' : name[i]); + + parallel->path = path; + + parallel->irp_list = list_new(); + parallel->thread = freerdp_thread_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) parallel); + + freerdp_thread_start(parallel->thread, parallel_thread_func, parallel); + } + + return 0; +} diff --git a/channels/rdpdr/printer/CMakeLists.txt b/channels/rdpdr/printer/CMakeLists.txt new file mode 100644 index 0000000..d0f184c --- /dev/null +++ b/channels/rdpdr/printer/CMakeLists.txt @@ -0,0 +1,46 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(PRINTER_SRCS + printer_main.c + printer_main.h +) + +if(WITH_CUPS) + set(PRINTER_SRCS + ${PRINTER_SRCS} + printer_cups.c + printer_cups.h + ) + include_directories(${CUPS_INCLUDE_DIR}) + add_definitions(-DWITH_CUPS) +endif() + +include_directories(..) + +add_library(printer ${PRINTER_SRCS}) +set_target_properties(printer PROPERTIES PREFIX "") + +target_link_libraries(printer freerdp-utils) + +if(WITH_CUPS) + target_link_libraries(printer ${CUPS_LIBRARIES}) +endif() + +install(TARGETS printer DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/printer/printer_cups.c b/channels/rdpdr/printer/printer_cups.c new file mode 100644 index 0000000..846cc31 --- /dev/null +++ b/channels/rdpdr/printer/printer_cups.c @@ -0,0 +1,283 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Print Virtual Channel - CUPS driver + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" +#include "printer_main.h" + +#include "printer_cups.h" + +typedef struct rdp_cups_printer_driver rdpCupsPrinterDriver; +typedef struct rdp_cups_printer rdpCupsPrinter; +typedef struct rdp_cups_print_job rdpCupsPrintJob; + +struct rdp_cups_printer_driver +{ + rdpPrinterDriver driver; + + int id_sequence; +}; + +struct rdp_cups_printer +{ + rdpPrinter printer; + + rdpCupsPrintJob* printjob; +}; + +struct rdp_cups_print_job +{ + rdpPrintJob printjob; + + void* printjob_object; + int printjob_id; +}; + +static void printer_cups_get_printjob_name(char* buf, int size) +{ + time_t tt; + struct tm* t; + + tt = time(NULL); + t = localtime(&tt); + snprintf(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d", + t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); +} + +static void printer_cups_write_printjob(rdpPrintJob* printjob, uint8* data, int size) +{ + rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob; + +#ifndef _CUPS_API_1_4 + + { + FILE* fp; + + fp = fopen((const char*)cups_printjob->printjob_object, "a+b"); + if (fp == NULL) + { + DEBUG_WARN("failed to open file %s", (char*)cups_printjob->printjob_object); + return; + } + if (fwrite(data, 1, size, fp) < size) + { + DEBUG_WARN("failed to write file %s", (char*)cups_printjob->printjob_object); + } + fclose(fp); + } + +#else + + cupsWriteRequestData((http_t*)cups_printjob->printjob_object, (const char*)data, size); + +#endif +} + +static void printer_cups_close_printjob(rdpPrintJob* printjob) +{ + rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob; + +#ifndef _CUPS_API_1_4 + + { + char buf[100]; + + printer_cups_get_printjob_name(buf, sizeof(buf)); + if (cupsPrintFile(printjob->printer->name, (const char *)cups_printjob->printjob_object, buf, 0, NULL) == 0) + { + DEBUG_WARN("cupsPrintFile: %s", cupsLastErrorString()); + } + unlink(cups_printjob->printjob_object); + xfree(cups_printjob->printjob_object); + } + +#else + + cupsFinishDocument((http_t*)cups_printjob->printjob_object, printjob->printer->name); + cups_printjob->printjob_id = 0; + httpClose((http_t*)cups_printjob->printjob_object); + +#endif + + xfree(cups_printjob); + + ((rdpCupsPrinter*)printjob->printer)->printjob = NULL; +} + +static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, uint32 id) +{ + rdpCupsPrinter* cups_printer = (rdpCupsPrinter*)printer; + rdpCupsPrintJob* cups_printjob; + + if (cups_printer->printjob != NULL) + return NULL; + + cups_printjob = xnew(rdpCupsPrintJob); + + cups_printjob->printjob.id = id; + cups_printjob->printjob.printer = printer; + + cups_printjob->printjob.Write = printer_cups_write_printjob; + cups_printjob->printjob.Close = printer_cups_close_printjob; + +#ifndef _CUPS_API_1_4 + + cups_printjob->printjob_object = xstrdup(tmpnam(NULL)); + +#else + { + char buf[100]; + + cups_printjob->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED); + if (cups_printjob->printjob_object == NULL) + { + DEBUG_WARN("httpConnectEncrypt: %s", cupsLastErrorString()); + xfree(cups_printjob); + return NULL; + } + + printer_cups_get_printjob_name(buf, sizeof(buf)); + cups_printjob->printjob_id = cupsCreateJob((http_t*)cups_printjob->printjob_object, + printer->name, buf, 0, NULL); + + if (cups_printjob->printjob_id == 0) + { + DEBUG_WARN("cupsCreateJob: %s", cupsLastErrorString()); + httpClose((http_t*)cups_printjob->printjob_object); + xfree(cups_printjob); + return NULL; + } + cupsStartDocument((http_t*)cups_printjob->printjob_object, + printer->name, cups_printjob->printjob_id, buf, + CUPS_FORMAT_AUTO, 1); + } + +#endif + + cups_printer->printjob = cups_printjob; + + return (rdpPrintJob*)cups_printjob; +} + +static rdpPrintJob* printer_cups_find_printjob(rdpPrinter* printer, uint32 id) +{ + rdpCupsPrinter* cups_printer = (rdpCupsPrinter*)printer; + + if (cups_printer->printjob == NULL) + return NULL; + if (cups_printer->printjob->printjob.id != id) + return NULL; + + return (rdpPrintJob*)cups_printer->printjob; +} + +static void printer_cups_free_printer(rdpPrinter* printer) +{ + rdpCupsPrinter* cups_printer = (rdpCupsPrinter*)printer; + + if (cups_printer->printjob) + cups_printer->printjob->printjob.Close((rdpPrintJob*)cups_printer->printjob); + xfree(printer->name); + xfree(printer); +} + +static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver, const char* name, boolean is_default) +{ + rdpCupsPrinter* cups_printer; + + cups_printer = xnew(rdpCupsPrinter); + + cups_printer->printer.id = cups_driver->id_sequence++; + cups_printer->printer.name = xstrdup(name); + /* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */ + cups_printer->printer.driver = "MS Publisher Imagesetter"; + cups_printer->printer.is_default = is_default; + + cups_printer->printer.CreatePrintJob = printer_cups_create_printjob; + cups_printer->printer.FindPrintJob = printer_cups_find_printjob; + cups_printer->printer.Free = printer_cups_free_printer; + + return (rdpPrinter*)cups_printer; +} + +static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver) +{ + rdpPrinter** printers; + int num_printers; + cups_dest_t *dests; + cups_dest_t *dest; + int num_dests; + int i; + + num_dests = cupsGetDests(&dests); + printers = (rdpPrinter**)xzalloc(sizeof(rdpPrinter*) * (num_dests + 1)); + num_printers = 0; + for (i = 0, dest = dests; i < num_dests; i++, dest++) + { + if (dest->instance == NULL) + { + printers[num_printers++] = printer_cups_new_printer((rdpCupsPrinterDriver*)driver, + dest->name, dest->is_default); + } + } + cupsFreeDests(num_dests, dests); + + return printers; +} + +static rdpPrinter* printer_cups_get_printer(rdpPrinterDriver* driver, const char* name) +{ + rdpCupsPrinterDriver* cups_driver = (rdpCupsPrinterDriver*)driver; + + return printer_cups_new_printer(cups_driver, name, cups_driver->id_sequence == 1 ? true : false); +} + +static rdpCupsPrinterDriver* cups_driver = NULL; + +rdpPrinterDriver* printer_cups_get_driver(void) +{ + if (cups_driver == NULL) + { + cups_driver = xnew(rdpCupsPrinterDriver); + + cups_driver->driver.EnumPrinters = printer_cups_enum_printers; + cups_driver->driver.GetPrinter = printer_cups_get_printer; + + cups_driver->id_sequence = 1; + +#ifdef _CUPS_API_1_4 + DEBUG_SVC("using CUPS API 1.4"); +#else + DEBUG_SVC("using CUPS API 1.2"); +#endif + } + + return (rdpPrinterDriver*)cups_driver; +} + diff --git a/channels/rdpdr/printer/printer_cups.h b/channels/rdpdr/printer/printer_cups.h new file mode 100644 index 0000000..c6e1ff5 --- /dev/null +++ b/channels/rdpdr/printer/printer_cups.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Print Virtual Channel - CUPS driver + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PRINTER_CUPS_H +#define __PRINTER_CUPS_H + +#include "printer_main.h" + +rdpPrinterDriver* printer_cups_get_driver(void); + +#endif + diff --git a/channels/rdpdr/printer/printer_main.c b/channels/rdpdr/printer/printer_main.c new file mode 100644 index 0000000..d379102 --- /dev/null +++ b/channels/rdpdr/printer/printer_main.c @@ -0,0 +1,340 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Print Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" + +#ifdef WITH_CUPS +#include "printer_cups.h" +#endif + +#include "printer_main.h" + +typedef struct _PRINTER_DEVICE PRINTER_DEVICE; +struct _PRINTER_DEVICE +{ + DEVICE device; + + rdpPrinter* printer; + + LIST* irp_list; + freerdp_thread* thread; +}; + +static void printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp) +{ + rdpPrintJob* printjob = NULL; + + if (printer_dev->printer != NULL) + printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, irp->devman->id_sequence++); + + if (printjob != NULL) + { + stream_write_uint32(irp->output, printjob->id); /* FileId */ + + DEBUG_SVC("printjob id: %d", printjob->id); + } + else + { + stream_write_uint32(irp->output, 0); /* FileId */ + irp->IoStatus = STATUS_PRINT_QUEUE_FULL; + + DEBUG_WARN("error creating print job."); + } + + irp->Complete(irp); +} + +static void printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) +{ + rdpPrintJob* printjob = NULL; + + if (printer_dev->printer != NULL) + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + + if (printjob == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + + DEBUG_WARN("printjob id %d not found.", irp->FileId); + } + else + { + printjob->Close(printjob); + + DEBUG_SVC("printjob id %d closed.", irp->FileId); + } + + stream_write_zero(irp->output, 4); /* Padding(4) */ + + irp->Complete(irp); +} + +static void printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) +{ + rdpPrintJob* printjob = NULL; + uint32 Length; + uint64 Offset; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + stream_seek(irp->input, 20); /* Padding */ + + if (printer_dev->printer != NULL) + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + + if (printjob == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("printjob id %d not found.", irp->FileId); + } + else + { + printjob->Write(printjob, stream_get_tail(irp->input), Length); + + DEBUG_SVC("printjob id %d written %d bytes.", irp->FileId, Length); + } + + stream_write_uint32(irp->output, Length); + stream_write_uint8(irp->output, 0); /* Padding */ + + irp->Complete(irp); +} + +static void printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) +{ + switch (irp->MajorFunction) + { + case IRP_MJ_CREATE: + printer_process_irp_create(printer_dev, irp); + break; + + case IRP_MJ_CLOSE: + printer_process_irp_close(printer_dev, irp); + break; + + case IRP_MJ_WRITE: + printer_process_irp_write(printer_dev, irp); + break; + + default: + DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + irp->Complete(irp); + break; + } +} + +static void printer_process_irp_list(PRINTER_DEVICE* printer_dev) +{ + IRP* irp; + + while (1) + { + if (freerdp_thread_is_stopped(printer_dev->thread)) + break; + + freerdp_thread_lock(printer_dev->thread); + irp = (IRP*)list_dequeue(printer_dev->irp_list); + freerdp_thread_unlock(printer_dev->thread); + + if (irp == NULL) + break; + + printer_process_irp(printer_dev, irp); + } +} + +static void* printer_thread_func(void* arg) +{ + PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)arg; + + while (1) + { + freerdp_thread_wait(printer_dev->thread); + + if (freerdp_thread_is_stopped(printer_dev->thread)) + break; + + freerdp_thread_reset(printer_dev->thread); + printer_process_irp_list(printer_dev); + } + + freerdp_thread_quit(printer_dev->thread); + + return NULL; +} + +static void printer_irp_request(DEVICE* device, IRP* irp) +{ + PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device; + + freerdp_thread_lock(printer_dev->thread); + list_enqueue(printer_dev->irp_list, irp); + freerdp_thread_unlock(printer_dev->thread); + + freerdp_thread_signal(printer_dev->thread); +} + +static void printer_free(DEVICE* device) +{ + PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device; + IRP* irp; + + freerdp_thread_stop(printer_dev->thread); + freerdp_thread_free(printer_dev->thread); + + while ((irp = (IRP*)list_dequeue(printer_dev->irp_list)) != NULL) + irp->Discard(irp); + list_free(printer_dev->irp_list); + + if (printer_dev->printer) + printer_dev->printer->Free(printer_dev->printer); + + xfree(printer_dev->device.name); + + xfree(printer_dev); +} + +void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer) +{ + PRINTER_DEVICE* printer_dev; + char* port; + UNICONV* uniconv; + uint32 Flags; + size_t DriverNameLen; + char* DriverName; + size_t PrintNameLen; + char* PrintName; + uint32 CachedFieldsLen; + uint8* CachedPrinterConfigData; + + port = xmalloc(10); + snprintf(port, 10, "PRN%d", printer->id); + + printer_dev = xnew(PRINTER_DEVICE); + + printer_dev->device.type = RDPDR_DTYP_PRINT; + printer_dev->device.name = port; + printer_dev->device.IRPRequest = printer_irp_request; + printer_dev->device.Free = printer_free; + + printer_dev->printer = printer; + + CachedFieldsLen = 0; + CachedPrinterConfigData = NULL; + + DEBUG_SVC("Printer %s registered", printer->name); + + Flags = 0; + if (printer->is_default) + Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; + + uniconv = freerdp_uniconv_new(); + DriverName = freerdp_uniconv_out(uniconv, printer->driver, &DriverNameLen); + PrintName = freerdp_uniconv_out(uniconv, printer->name, &PrintNameLen); + freerdp_uniconv_free(uniconv); + + printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen); + + stream_write_uint32(printer_dev->device.data, Flags); + stream_write_uint32(printer_dev->device.data, 0); /* CodePage, reserved */ + stream_write_uint32(printer_dev->device.data, 0); /* PnPNameLen */ + stream_write_uint32(printer_dev->device.data, DriverNameLen + 2); + stream_write_uint32(printer_dev->device.data, PrintNameLen + 2); + stream_write_uint32(printer_dev->device.data, CachedFieldsLen); + stream_write(printer_dev->device.data, DriverName, DriverNameLen); + stream_write_uint16(printer_dev->device.data, 0); + stream_write(printer_dev->device.data, PrintName, PrintNameLen); + stream_write_uint16(printer_dev->device.data, 0); + if (CachedFieldsLen > 0) + { + stream_write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); + } + + xfree(DriverName); + xfree(PrintName); + + printer_dev->irp_list = list_new(); + printer_dev->thread = freerdp_thread_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)printer_dev); + + freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev); +} + +int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + rdpPrinterDriver* driver = NULL; + rdpPrinter** printers; + rdpPrinter* printer; + int i; + char* name; + char* driver_name; + +#ifdef WITH_CUPS + driver = printer_cups_get_driver(); +#endif + if (driver == NULL) + { + DEBUG_WARN("no driver."); + return 1; + } + + name = (char*)pEntryPoints->plugin_data->data[1]; + driver_name = (char*)pEntryPoints->plugin_data->data[2]; + + if (name && name[0]) + { + printer = driver->GetPrinter(driver, name); + if (printer == NULL) + { + DEBUG_WARN("printer %s not found.", name); + return 1; + } + if (driver_name && driver_name[0]) + printer->driver = driver_name; + + printer_register(pEntryPoints, printer); + } + else + { + printers = driver->EnumPrinters(driver); + for (i = 0; printers[i]; i++) + { + printer = printers[i]; + printer_register(pEntryPoints, printer); + } + xfree(printers); + } + + return 0; +} diff --git a/channels/rdpdr/printer/printer_main.h b/channels/rdpdr/printer/printer_main.h new file mode 100644 index 0000000..256c4a7 --- /dev/null +++ b/channels/rdpdr/printer/printer_main.h @@ -0,0 +1,79 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Print Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PRINTER_MAIN_H +#define __PRINTER_MAIN_H + +#include "rdpdr_types.h" + +/* SERVER_PRINTER_CACHE_EVENT.cachedata */ +#define RDPDR_ADD_PRINTER_EVENT 0x00000001 +#define RDPDR_UPDATE_PRINTER_EVENT 0x00000002 +#define RDPDR_DELETE_PRINTER_EVENT 0x00000003 +#define RDPDR_RENAME_PRINTER_EVENT 0x00000004 + +/* DR_PRN_DEVICE_ANNOUNCE.Flags */ +#define RDPDR_PRINTER_ANNOUNCE_FLAG_ASCII 0x00000001 +#define RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER 0x00000002 +#define RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER 0x00000004 +#define RDPDR_PRINTER_ANNOUNCE_FLAG_TSPRINTER 0x00000008 +#define RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT 0x00000010 + +typedef struct rdp_printer_driver rdpPrinterDriver; +typedef struct rdp_printer rdpPrinter; +typedef struct rdp_print_job rdpPrintJob; + +typedef rdpPrinter** (*pcEnumPrinters) (rdpPrinterDriver* driver); +typedef rdpPrinter* (*pcGetPrinter) (rdpPrinterDriver* driver, const char* name); + +struct rdp_printer_driver +{ + pcEnumPrinters EnumPrinters; + pcGetPrinter GetPrinter; +}; + +typedef rdpPrintJob* (*pcCreatePrintJob) (rdpPrinter* printer, uint32 id); +typedef rdpPrintJob* (*pcFindPrintJob) (rdpPrinter* printer, uint32 id); +typedef void (*pcFreePrinter) (rdpPrinter* printer); + +struct rdp_printer +{ + int id; + char* name; + char* driver; + boolean is_default; + + pcCreatePrintJob CreatePrintJob; + pcFindPrintJob FindPrintJob; + pcFreePrinter Free; +}; + +typedef void (*pcWritePrintJob) (rdpPrintJob* printjob, uint8* data, int size); +typedef void (*pcClosePrintJob) (rdpPrintJob* printjob); + +struct rdp_print_job +{ + uint32 id; + rdpPrinter* printer; + + pcWritePrintJob Write; + pcClosePrintJob Close; +}; + +#endif diff --git a/channels/rdpdr/rdpdr_capabilities.c b/channels/rdpdr/rdpdr_capabilities.c new file mode 100644 index 0000000..c31dbea --- /dev/null +++ b/channels/rdpdr/rdpdr_capabilities.c @@ -0,0 +1,187 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" +#include "rdpdr_capabilities.h" + +/* Output device redirection capability set header */ +static void rdpdr_write_capset_header(STREAM* data_out, uint16 capabilityType, uint16 capabilityLength, uint32 version) +{ + stream_write_uint16(data_out, capabilityType); + stream_write_uint16(data_out, capabilityLength); + stream_write_uint32(data_out, version); +} + +/* Output device direction general capability set */ +static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, STREAM* data_out) +{ + rdpdr_write_capset_header(data_out, CAP_GENERAL_TYPE, 44, GENERAL_CAPABILITY_VERSION_02); + + stream_write_uint32(data_out, 0); /* osType, ignored on receipt */ + stream_write_uint32(data_out, 0); /* osVersion, unused and must be set to zero */ + stream_write_uint16(data_out, 1); /* protocolMajorVersion, must be set to 1 */ + stream_write_uint16(data_out, RDPDR_MINOR_RDP_VERSION_5_2); /* protocolMinorVersion */ + stream_write_uint32(data_out, 0x0000FFFF); /* ioCode1 */ + stream_write_uint32(data_out, 0); /* ioCode2, must be set to zero, reserved for future use */ + stream_write_uint32(data_out, RDPDR_DEVICE_REMOVE_PDUS | RDPDR_CLIENT_DISPLAY_NAME_PDU | RDPDR_USER_LOGGEDON_PDU); /* extendedPDU */ + stream_write_uint32(data_out, ENABLE_ASYNCIO); /* extraFlags1 */ + stream_write_uint32(data_out, 0); /* extraFlags2, must be set to zero, reserved for future use */ + stream_write_uint32(data_out, 0); /* SpecialTypeDeviceCap, number of special devices to be redirected before logon */ +} + +/* Process device direction general capability set */ +static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 capabilityLength; + + stream_read_uint16(data_in, capabilityLength); + stream_seek(data_in, capabilityLength - 4); +} + +/* Output printer direction capability set */ +static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, STREAM* data_out) +{ + rdpdr_write_capset_header(data_out, CAP_PRINTER_TYPE, 8, PRINT_CAPABILITY_VERSION_01); +} + +/* Process printer direction capability set */ +static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 capabilityLength; + + stream_read_uint16(data_in, capabilityLength); + stream_seek(data_in, capabilityLength - 4); +} + +/* Output port redirection capability set */ +static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, STREAM* data_out) +{ + rdpdr_write_capset_header(data_out, CAP_PORT_TYPE, 8, PORT_CAPABILITY_VERSION_01); +} + +/* Process port redirection capability set */ +static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 capabilityLength; + + stream_read_uint16(data_in, capabilityLength); + stream_seek(data_in, capabilityLength - 4); +} + +/* Output drive redirection capability set */ +static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, STREAM* data_out) +{ + rdpdr_write_capset_header(data_out, CAP_DRIVE_TYPE, 8, DRIVE_CAPABILITY_VERSION_02); +} + +/* Process drive redirection capability set */ +static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 capabilityLength; + + stream_read_uint16(data_in, capabilityLength); + stream_seek(data_in, capabilityLength - 4); +} + +/* Output smart card redirection capability set */ +static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, STREAM* data_out) +{ + rdpdr_write_capset_header(data_out, CAP_SMARTCARD_TYPE, 8, SMARTCARD_CAPABILITY_VERSION_01); +} + +/* Process smartcard redirection capability set */ +static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 capabilityLength; + + stream_read_uint16(data_in, capabilityLength); + stream_seek(data_in, capabilityLength - 4); +} + +void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 i; + uint16 numCapabilities; + uint16 capabilityType; + + stream_read_uint16(data_in, numCapabilities); + stream_seek(data_in, 2); /* pad (2 bytes) */ + + for(i = 0; i < numCapabilities; i++) + { + stream_read_uint16(data_in, capabilityType); + + switch (capabilityType) + { + case CAP_GENERAL_TYPE: + rdpdr_process_general_capset(rdpdr, data_in); + break; + + case CAP_PRINTER_TYPE: + rdpdr_process_printer_capset(rdpdr, data_in); + break; + + case CAP_PORT_TYPE: + rdpdr_process_port_capset(rdpdr, data_in); + break; + + case CAP_DRIVE_TYPE: + rdpdr_process_drive_capset(rdpdr, data_in); + break; + + case CAP_SMARTCARD_TYPE: + rdpdr_process_smartcard_capset(rdpdr, data_in); + break; + + default: + DEBUG_WARN("Unknown capabilityType %d", capabilityType); + break; + } + } +} + +void rdpdr_send_capability_response(rdpdrPlugin* rdpdr) +{ + STREAM* data_out; + + data_out = stream_new(256); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_CLIENT_CAPABILITY); + + stream_write_uint16(data_out, 5); /* numCapabilities */ + stream_write_uint16(data_out, 0); /* pad */ + + rdpdr_write_general_capset(rdpdr, data_out); + rdpdr_write_printer_capset(rdpdr, data_out); + rdpdr_write_port_capset(rdpdr, data_out); + rdpdr_write_drive_capset(rdpdr, data_out); + rdpdr_write_smartcard_capset(rdpdr, data_out); + + svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); +} diff --git a/channels/rdpdr/rdpdr_capabilities.h b/channels/rdpdr/rdpdr_capabilities.h new file mode 100644 index 0000000..28b83c7 --- /dev/null +++ b/channels/rdpdr/rdpdr_capabilities.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDPDR_CAPABILITIES_H +#define __RDPDR_CAPABILITIES_H + +#include "rdpdr_main.h" + +void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, STREAM* data_in); +void rdpdr_send_capability_response(rdpdrPlugin* rdpdr); + +#endif /* __RDPDR_CAPABILITIES_H */ diff --git a/channels/rdpdr/rdpdr_constants.h b/channels/rdpdr/rdpdr_constants.h new file mode 100644 index 0000000..ce8b7f0 --- /dev/null +++ b/channels/rdpdr/rdpdr_constants.h @@ -0,0 +1,442 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDPDR_CONSTANTS_H +#define __RDPDR_CONSTANTS_H + +/* RDPDR_HEADER.Component */ +enum RDPDR_CTYP +{ + RDPDR_CTYP_CORE = 0x4472, + RDPDR_CTYP_PRN = 0x5052 +}; + +/* RDPDR_HEADER.PacketId */ +enum RDPDR_PAKID +{ + PAKID_CORE_SERVER_ANNOUNCE = 0x496E, + PAKID_CORE_CLIENTID_CONFIRM = 0x4343, + PAKID_CORE_CLIENT_NAME = 0x434E, + PAKID_CORE_DEVICELIST_ANNOUNCE = 0x4441, + PAKID_CORE_DEVICE_REPLY = 0x6472, + PAKID_CORE_DEVICE_IOREQUEST = 0x4952, + PAKID_CORE_DEVICE_IOCOMPLETION = 0x4943, + PAKID_CORE_SERVER_CAPABILITY = 0x5350, + PAKID_CORE_CLIENT_CAPABILITY = 0x4350, + PAKID_CORE_DEVICELIST_REMOVE = 0x444D, + PAKID_CORE_USER_LOGGEDON = 0x554C, + PAKID_PRN_CACHE_DATA = 0x5043, + PAKID_PRN_USING_XPS = 0x5543 +}; + +/* CAPABILITY_HEADER.CapabilityType */ +enum RDPDR_CAP_TYPE +{ + CAP_GENERAL_TYPE = 0x0001, + CAP_PRINTER_TYPE = 0x0002, + CAP_PORT_TYPE = 0x0003, + CAP_DRIVE_TYPE = 0x0004, + CAP_SMARTCARD_TYPE = 0x0005 +}; + +/* CAPABILITY_HEADER.Version */ +enum RDPDR_CAP_VERSION +{ + GENERAL_CAPABILITY_VERSION_01 = 0x00000001, + GENERAL_CAPABILITY_VERSION_02 = 0x00000002, + PRINT_CAPABILITY_VERSION_01 = 0x00000001, + PORT_CAPABILITY_VERSION_01 = 0x00000001, + DRIVE_CAPABILITY_VERSION_01 = 0x00000001, + DRIVE_CAPABILITY_VERSION_02 = 0x00000002, + SMARTCARD_CAPABILITY_VERSION_01 = 0x00000001 +}; + +/* DEVICE_ANNOUNCE.DeviceType */ +enum RDPDR_DTYP +{ + RDPDR_DTYP_SERIAL = 0x00000001, + RDPDR_DTYP_PARALLEL = 0x00000002, + RDPDR_DTYP_PRINT = 0x00000004, + RDPDR_DTYP_FILESYSTEM = 0x00000008, + RDPDR_DTYP_SMARTCARD = 0x00000020 +}; + +/* DR_DEVICE_IOREQUEST.MajorFunction */ +enum IRP_MJ +{ + IRP_MJ_CREATE = 0x00000000, + IRP_MJ_CLOSE = 0x00000002, + IRP_MJ_READ = 0x00000003, + IRP_MJ_WRITE = 0x00000004, + IRP_MJ_DEVICE_CONTROL = 0x0000000E, + IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A, + IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B, + IRP_MJ_QUERY_INFORMATION = 0x00000005, + IRP_MJ_SET_INFORMATION = 0x00000006, + IRP_MJ_DIRECTORY_CONTROL = 0x0000000C, + IRP_MJ_LOCK_CONTROL = 0x00000011 +}; + +/* DR_DEVICE_IOREQUEST.MinorFunction */ +enum IRP_MN +{ + IRP_MN_QUERY_DIRECTORY = 0x00000001, + IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002 +}; + +/* DR_CREATE_REQ.CreateDisposition */ +enum FILE_CREATE_DISPOSITION +{ + FILE_SUPERSEDE = 0x00000000, + FILE_OPEN = 0x00000001, + FILE_CREATE = 0x00000002, + FILE_OPEN_IF = 0x00000003, + FILE_OVERWRITE = 0x00000004, + FILE_OVERWRITE_IF = 0x00000005 +}; + +/* DR_CREATE_REQ.CreateOptions [MS-SMB2] */ +enum FILE_CREATE_OPTION +{ + FILE_DIRECTORY_FILE = 0x00000001, + FILE_NON_DIRECTORY_FILE = 0x00000040, + FILE_COMPLETE_IF_OPLOCKED = 0x00000100, + FILE_DELETE_ON_CLOSE = 0x00001000, + FILE_OPEN_REPARSE_POINT = 0x00200000, + FILE_OPEN_FOR_FREE_SPACE_QUERY = 0x00800000 +}; + +/* DR_CREATE_REQ.DesiredAccess [MS-SMB2] */ +enum FILE_ACCESS +{ + FILE_READ_DATA = 0x00000001, + FILE_WRITE_DATA = 0x00000002, + FILE_APPEND_DATA = 0x00000004, + FILE_READ_EA = 0x00000008, + FILE_WRITE_EA = 0x00000010, + FILE_EXECUTE = 0x00000020, + FILE_READ_ATTRIBUTES = 0x00000080, + FILE_WRITE_ATTRIBUTES = 0x00000100, + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + ACCESS_SYSTEM_SECURITY = 0x01000000, + MAXIMUM_ALLOWED = 0x02000000, + GENERIC_ALL = 0x10000000, + GENERIC_EXECUTE = 0x20000000, + GENERIC_WRITE = 0x40000000, + GENERIC_READ = 0x80000000 +}; + +/* DR_CREATE_RSP.Information */ +/* DR_DRIVE_CREATE_RSP.DeviceCreateResponse */ +enum FILE_RESPONSE +{ + FILE_SUPERSEDED = 0x00000000, + FILE_OPENED = 0x00000001, + FILE_OVERWRITTEN = 0x00000003 +}; + +/* DR_CORE_CLIENT_ANNOUNCE_RSP.VersionMinor */ +enum RDPDR_MINOR_RDP_VERSION +{ + RDPDR_MINOR_RDP_VERSION_5_0 = 0x0002, + RDPDR_MINOR_RDP_VERSION_5_1 = 0x0005, + RDPDR_MINOR_RDP_VERSION_5_2 = 0x000A, + RDPDR_MINOR_RDP_VERSION_6_X = 0x000C +}; + +/* DR_CORE_CLIENT_NAME_REQ.UnicodeFlag */ +enum RDPDR_CLIENT_NAME_FLAG +{ + RDPDR_CLIENT_NAME_UNICODE = 0x00000001, + RDPDR_CLIENT_NAME_ASCII = 0x00000000 +}; + +/* GENERAL_CAPS_SET.ioCode1 */ +enum RDPDR_CAPS_IRP_MJ +{ + RDPDR_IRP_MJ_CREATE = 0x00000001, + RDPDR_IRP_MJ_CLEANUP = 0x00000002, + RDPDR_IRP_MJ_CLOSE = 0x00000004, + RDPDR_IRP_MJ_READ = 0x00000008, + RDPDR_IRP_MJ_WRITE = 0x00000010, + RDPDR_IRP_MJ_FLUSH_BUFFERS = 0x00000020, + RDPDR_IRP_MJ_SHUTDOWN = 0x00000040, + RDPDR_IRP_MJ_DEVICE_CONTROL = 0x00000080, + RDPDR_IRP_MJ_QUERY_VOLUME_INFORMATION = 0x00000100, + RDPDR_IRP_MJ_SET_VOLUME_INFORMATION = 0x00000200, + RDPDR_IRP_MJ_QUERY_INFORMATION = 0x00000400, + RDPDR_IRP_MJ_SET_INFORMATION = 0x00000800, + RDPDR_IRP_MJ_DIRECTORY_CONTROL = 0x00001000, + RDPDR_IRP_MJ_LOCK_CONTROL = 0x00002000, + RDPDR_IRP_MJ_QUERY_SECURITY = 0x00004000, + RDPDR_IRP_MJ_SET_SECURITY = 0x00008000 +}; + +/* GENERAL_CAPS_SET.extendedPDU */ +enum RDPDR_CAPS_PDU +{ + RDPDR_DEVICE_REMOVE_PDUS = 0x00000001, + RDPDR_CLIENT_DISPLAY_NAME_PDU = 0x00000002, + RDPDR_USER_LOGGEDON_PDU = 0x00000004 +}; + +/* GENERAL_CAPS_SET.extraFlags1 */ +enum RDPDR_CAPS_FLAG +{ + ENABLE_ASYNCIO = 0x00000001 +}; + +/* DR_DRIVE_LOCK_REQ.Operation */ +enum RDP_LOWIO_OP +{ + RDP_LOWIO_OP_SHAREDLOCK = 0x00000002, + RDP_LOWIO_OP_EXCLUSIVELOCK = 0x00000003, + RDP_LOWIO_OP_UNLOCK = 0x00000004, + RDP_LOWIO_OP_UNLOCK_MULTIPLE = 0x00000005 +}; + +/* NTSTATUS values */ +/* http://msdn.microsoft.com/en-us/library/cc704588.aspx */ +enum NTSTATUS +{ + STATUS_SUCCESS = 0x00000000, + STATUS_TIMEOUT = 0x00000102, + STATUS_PENDING = 0x00000103, + STATUS_REPARSE = 0x00000104, + STATUS_MORE_ENTRIES = 0x00000105, + STATUS_NOT_ALL_ASSIGNED = 0x00000106, + STATUS_OPLOCK_BREAK_IN_PROGRESS = 0x00000108, + STATUS_VOLUME_MOUNTED = 0x00000109, + STATUS_NOTIFY_CLEANUP = 0x0000010B, + STATUS_NOTIFY_ENUM_DIR = 0x0000010C, + STATUS_NO_QUOTAS_FOR_ACCOUNT = 0x0000010D, + STATUS_FILE_LOCKED_WITH_ONLY_READERS = 0x0000012A, + STATUS_FILE_LOCKED_WITH_WRITERS = 0x0000012B, + STATUS_WAIT_FOR_OPLOCK = 0x00000367, + STATUS_OBJECT_NAME_EXISTS = 0x40000000, + STATUS_BAD_CURRENT_DIRECTORY = 0x40000007, + STATUS_NO_MORE_FILES = 0x80000006, + STATUS_DEVICE_PAPER_EMPTY = 0x8000000E, + STATUS_DEVICE_POWERED_OFF = 0x8000000F, + STATUS_DEVICE_OFF_LINE = 0x80000010, + STATUS_DEVICE_BUSY = 0x80000011, + STATUS_NO_MORE_ENTRIES = 0x8000001A, + STATUS_UNSUCCESSFUL = 0xC0000001, + STATUS_NOT_IMPLEMENTED = 0xC0000002, + STATUS_INVALID_INFO_CLASS = 0xC0000003, + STATUS_INVALID_HANDLE = 0xC0000008, + STATUS_INVALID_PARAMETER = 0xC000000D, + STATUS_NO_SUCH_DEVICE = 0xC000000E, + STATUS_NO_SUCH_FILE = 0xC000000F, + STATUS_INVALID_DEVICE_REQUEST = 0xC0000010, + STATUS_END_OF_FILE = 0xC0000011, + STATUS_NO_MEDIA_IN_DEVICE = 0xC0000013, + STATUS_UNRECOGNIZED_MEDIA = 0xC0000014, + STATUS_ACCESS_DENIED = 0xc0000022, + STATUS_OBJECT_NAME_INVALID = 0xC0000033, + STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034, + STATUS_OBJECT_NAME_COLLISION = 0xc0000035, + STATUS_PORT_DISCONNECTED = 0xC0000037, + STATUS_OBJECT_PATH_INVALID = 0xC0000039, + STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A, + STATUS_INVALID_PORT_HANDLE = 0xC0000042, + STATUS_DELETE_PENDING = 0xC0000056, + STATUS_DISK_FULL = 0xC000007F, + STATUS_DEVICE_NOT_READY = 0xC00000A3, + STATUS_IO_TIMEOUT = 0xC00000B5, + STATUS_FILE_IS_A_DIRECTORY = 0xC00000BA, + STATUS_NOT_SUPPORTED = 0xC00000BB, + STATUS_PRINT_QUEUE_FULL = 0xC00000C6, + STATUS_PRINT_CANCELLED = 0xC00000C8, + STATUS_DIRECTORY_NOT_EMPTY = 0xC0000101, + STATUS_FILE_CORRUPT_ERROR = 0xC0000102, + STATUS_NOT_A_DIRECTORY = 0xC0000103, + STATUS_NAME_TOO_LONG = 0xC0000106, + STATUS_CANCELLED = 0xC0000120, + STATUS_CANNOT_DELETE = 0xC0000121, + STATUS_FILE_DELETED = 0xC0000123, + STATUS_FILE_CLOSED = 0xC0000128 +}; + +enum RDPDR_PRINTER_ANNOUNCE_FLAG +{ + RDPDR_PRINTER_ANNOUNCE_FLAG_ASCII = 0x00000001, + RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER = 0x00000002, + RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER = 0x00000004, + RDPDR_PRINTER_ANNOUNCE_FLAG_TSPRINTER = 0x00000008, + RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT = 0x00000010 +}; + +/* [MS-FSCC] FileAttributes */ +enum FILE_ATTRIBUTE +{ + FILE_ATTRIBUTE_ARCHIVE = 0x00000020, + FILE_ATTRIBUTE_COMPRESSED = 0x00000800, + FILE_ATTRIBUTE_DIRECTORY = 0x00000010, + FILE_ATTRIBUTE_ENCRYPTED = 0x00004000, + FILE_ATTRIBUTE_HIDDEN = 0x00000002, + FILE_ATTRIBUTE_NORMAL = 0x00000080, + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000, + FILE_ATTRIBUTE_OFFLINE = 0x00001000, + FILE_ATTRIBUTE_READONLY = 0x00000001, + FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400, + FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200, + FILE_ATTRIBUTE_SYSTEM = 0x00000004, + FILE_ATTRIBUTE_TEMPORARY = 0x00000100 +}; + +/* [MS-FSCC] FSCTL Structures */ +enum FSCTL_STRUCTURE +{ + FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900c0, + FSCTL_GET_REPARSE_POINT = 0x900a8, + FSCTL_GET_RETRIEVAL_POINTERS = 0x90073, + FSCTL_IS_PATHNAME_VALID = 0x9002c, + FSCTL_LMR_SET_LINK_TRACKING_INFORMATION = 0x1400ec, + FSCTL_PIPE_PEEK = 0x11400c, + FSCTL_PIPE_TRANSCEIVE = 0x11c017, + FSCTL_PIPE_WAIT = 0x110018, + FSCTL_QUERY_FAT_BPB = 0x90058, + FSCTL_QUERY_ALLOCATED_RANGES = 0x940cf, + FSCTL_QUERY_ON_DISK_VOLUME_INFO = 0x9013c, + FSCTL_QUERY_SPARING_INFO = 0x90138, + FSCTL_READ_FILE_USN_DATA = 0x900eb, + FSCTL_RECALL_FILE = 0x90117, + FSCTL_SET_COMPRESSION = 0x9c040, + FSCTL_SET_DEFECT_MANAGEMENT = 0x98134, + FSCTL_SET_ENCRYPTION = 0x900D7, + FSCTL_SET_OBJECT_ID = 0x90098, + FSCTL_SET_OBJECT_ID_EXTENDED = 0x900bc, + FSCTL_SET_REPARSE_POINT = 0x900a4, + FSCTL_SET_SPARSE = 0x900c4, + FSCTL_SET_ZERO_DATA = 0x980c8, + FSCTL_SET_ZERO_ON_DEALLOCATION = 0x90194, + FSCTL_SIS_COPYFILE = 0x90100, + FSCTL_WRITE_USN_CLOSE_RECORD = 0x900ef +}; + +/* [MS-FSCC] FileFsAttributeInformation.FileSystemAttributes */ +enum FILE_FS_ATTRIBUTE_INFORMATION +{ + FILE_SUPPORTS_USN_JOURNAL = 0x02000000, + FILE_SUPPORTS_OPEN_BY_FILE_ID = 0x01000000, + FILE_SUPPORTS_EXTENDED_ATTRIBUTES = 0x00800000, + FILE_SUPPORTS_HARD_LINKS = 0x00400000, + FILE_SUPPORTS_TRANSACTIONS = 0x00200000, + FILE_SEQUENTIAL_WRITE_ONCE = 0x00100000, + FILE_READ_ONLY_VOLUME = 0x00080000, + FILE_NAMED_STREAMS = 0x00040000, + FILE_SUPPORTS_ENCRYPTION = 0x00020000, + FILE_SUPPORTS_OBJECT_IDS = 0x00010000, + FILE_VOLUME_IS_COMPRESSED = 0x00008000, + FILE_SUPPORTS_REMOTE_STORAGE = 0x00000100, + FILE_SUPPORTS_REPARSE_POINTS = 0x00000080, + FILE_SUPPORTS_SPARSE_FILES = 0x00000040, + FILE_VOLUME_QUOTAS = 0x00000020, + FILE_FILE_COMPRESSION = 0x00000010, + FILE_PERSISTENT_ACLS = 0x00000008, + FILE_UNICODE_ON_DISK = 0x00000004, + FILE_CASE_PRESERVED_NAMES = 0x00000002, + FILE_CASE_SENSITIVE_SEARCH = 0x00000001 +}; + +/* [MS-FSCC] FileFsDeviceInformation.DeviceType */ +enum FILE_FS_DEVICE_TYPE +{ + FILE_DEVICE_CD_ROM = 0x00000002, + FILE_DEVICE_DISK = 0x00000007 +}; + +/* [MS-FSCC] FileFsDeviceInformation.Characteristics */ +enum FILE_FS_DEVICE_FLAG +{ + FILE_REMOVABLE_MEDIA = 0x00000001, + FILE_READ_ONLY_DEVICE = 0x00000002, + FILE_FLOPPY_DISKETTE = 0x00000004, + FILE_WRITE_ONCE_MEDIA = 0x00000008, + FILE_REMOTE_DEVICE = 0x00000010, + FILE_DEVICE_IS_MOUNTED = 0x00000020, + FILE_VIRTUAL_VOLUME = 0x00000040, + FILE_DEVICE_SECURE_OPEN = 0x00000100 +}; + +enum FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileObjectIdInformation, + FileUnknownInformation1, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileAttributeTagInformation, + FileTrackingInformation, + FileIdBothDirectoryInformation, + FileIdFullDirectoryInformation, + FileValidDataLengthInformation, + FileShortNameInformation +}; + +enum FILE_FS_INFORMATION_CLASS +{ + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectIdInformation, + FileFsDriverPathInformation, + FileFsMaximumInformation +}; + +#endif /* __RDPDR_CONSTANTS_H */ diff --git a/channels/rdpdr/rdpdr_main.c b/channels/rdpdr/rdpdr_main.c new file mode 100644 index 0000000..714dd3f --- /dev/null +++ b/channels/rdpdr/rdpdr_main.c @@ -0,0 +1,317 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" +#include "rdpdr_capabilities.h" +#include "devman.h" +#include "irp.h" +#include "rdpdr_main.h" + +static void rdpdr_process_connect(rdpSvcPlugin* plugin) +{ + rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; + RDP_PLUGIN_DATA* data; + + rdpdr->devman = devman_new(plugin); + data = (RDP_PLUGIN_DATA*) plugin->channel_entry_points.pExtendedData; + + while (data && data->size > 0) + { + if (strcmp((char*) data->data[0], "clientname") == 0) + { + strncpy(rdpdr->computerName, (char*) data->data[1], sizeof(rdpdr->computerName) - 1); + DEBUG_SVC("computerName %s", rdpdr->computerName); + } + else + { + devman_load_device_service(rdpdr->devman, data); + } + data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); + } +} + +static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + stream_read_uint16(data_in, rdpdr->versionMajor); + stream_read_uint16(data_in, rdpdr->versionMinor); + stream_read_uint32(data_in, rdpdr->clientID); + + DEBUG_SVC("version %d.%d clientID %d", rdpdr->versionMajor, rdpdr->versionMinor, rdpdr->clientID); +} + +static void rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr) +{ + STREAM* data_out; + + data_out = stream_new(12); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_CLIENTID_CONFIRM); + + stream_write_uint16(data_out, rdpdr->versionMajor); + stream_write_uint16(data_out, rdpdr->versionMinor); + stream_write_uint32(data_out, rdpdr->clientID); + + svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); +} + +static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) +{ + char* s; + STREAM* data_out; + UNICONV* uniconv; + size_t computerNameLenW; + + uniconv = freerdp_uniconv_new(); + + if (!rdpdr->computerName[0]) + gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1); + + s = freerdp_uniconv_out(uniconv, rdpdr->computerName, &computerNameLenW); + data_out = stream_new(16 + computerNameLenW + 2); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_CLIENT_NAME); + + stream_write_uint32(data_out, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ + stream_write_uint32(data_out, 0); /* codePage, must be set to zero */ + stream_write_uint32(data_out, computerNameLenW + 2); /* computerNameLen, including null terminator */ + stream_write(data_out, s, computerNameLenW); + stream_write_uint16(data_out, 0); /* null terminator */ + + xfree(s); + freerdp_uniconv_free(uniconv); + + svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); +} + +static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + uint16 versionMajor; + uint16 versionMinor; + uint32 clientID; + + stream_read_uint16(data_in, versionMajor); + stream_read_uint16(data_in, versionMinor); + stream_read_uint32(data_in, clientID); + + if (versionMajor != rdpdr->versionMajor || versionMinor != rdpdr->versionMinor) + { + DEBUG_WARN("unmatched version %d.%d", versionMajor, versionMinor); + rdpdr->versionMajor = versionMajor; + rdpdr->versionMinor = versionMinor; + } + + if (clientID != rdpdr->clientID) + { + DEBUG_WARN("unmatched clientID %d", clientID); + rdpdr->clientID = clientID; + } +} + +static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean user_loggedon) +{ + int i; + int pos; + uint8 c; + uint32 count; + int data_len; + int count_pos; + STREAM* data_out; + DEVICE* device; + LIST_ITEM* item; + + data_out = stream_new(256); + + stream_write_uint16(data_out, RDPDR_CTYP_CORE); + stream_write_uint16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); + + count_pos = stream_get_pos(data_out); + count = 0; + stream_seek_uint32(data_out); /* deviceCount */ + + for (item = rdpdr->devman->devices->head; item; item = item->next) + { + device = (DEVICE*) item->data; + + /** + * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON + * so all devices should be sent regardless of user_loggedon + * 2. smartcard devices should be always sent + * 3. other devices are sent only after user_loggedon + */ + if (rdpdr->versionMinor == 0x0005 || + device->type == RDPDR_DTYP_SMARTCARD || + user_loggedon) + { + data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); + stream_check_size(data_out, 20 + data_len); + + stream_write_uint32(data_out, device->type); /* deviceType */ + stream_write_uint32(data_out, device->id); /* deviceID */ + strncpy((char*) stream_get_tail(data_out), device->name, 8); + + for (i = 0; i < 8; i++) + { + stream_peek_uint8(data_out, c); + + if (c > 0x7F) + stream_write_uint8(data_out, '_'); + else + stream_seek_uint8(data_out); + } + + stream_write_uint32(data_out, data_len); + + if (data_len > 0) + stream_write(data_out, stream_get_data(device->data), data_len); + + count++; + + printf("registered device #%d: %s (type=%d id=%d)\n", + count, device->name, device->type, device->id); + } + } + + pos = stream_get_pos(data_out); + stream_set_pos(data_out, count_pos); + stream_write_uint32(data_out, count); + stream_set_pos(data_out, pos); + stream_seal(data_out); + + svc_plugin_send((rdpSvcPlugin*) rdpdr, data_out); +} + +static boolean rdpdr_process_irp(rdpdrPlugin* rdpdr, STREAM* data_in) +{ + IRP* irp; + + irp = irp_new(rdpdr->devman, data_in); + + if (irp == NULL) + return false; + + IFCALL(irp->device->IRPRequest, irp->device, irp); + + return true; +} + +static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) +{ + rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; + uint16 component; + uint16 packetID; + uint32 deviceID; + uint32 status; + + stream_read_uint16(data_in, component); + stream_read_uint16(data_in, packetID); + + if (component == RDPDR_CTYP_CORE) + { + switch (packetID) + { + case PAKID_CORE_SERVER_ANNOUNCE: + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_ANNOUNCE"); + rdpdr_process_server_announce_request(rdpdr, data_in); + rdpdr_send_client_announce_reply(rdpdr); + rdpdr_send_client_name_request(rdpdr); + break; + + case PAKID_CORE_SERVER_CAPABILITY: + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_SERVER_CAPABILITY"); + rdpdr_process_capability_request(rdpdr, data_in); + rdpdr_send_capability_response(rdpdr); + break; + + case PAKID_CORE_CLIENTID_CONFIRM: + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_CLIENTID_CONFIRM"); + rdpdr_process_server_clientid_confirm(rdpdr, data_in); + rdpdr_send_device_list_announce_request(rdpdr, false); + break; + + case PAKID_CORE_USER_LOGGEDON: + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_USER_LOGGEDON"); + rdpdr_send_device_list_announce_request(rdpdr, true); + break; + + case PAKID_CORE_DEVICE_REPLY: + /* connect to a specific resource */ + stream_read_uint32(data_in, deviceID); + stream_read_uint32(data_in, status); + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_REPLY (deviceID=%d status=0x%08X)", deviceID, status); + break; + + case PAKID_CORE_DEVICE_IOREQUEST: + DEBUG_SVC("RDPDR_CTYP_CORE / PAKID_CORE_DEVICE_IOREQUEST"); + if (rdpdr_process_irp(rdpdr, data_in)) + data_in = NULL; + break; + + default: + DEBUG_WARN("RDPDR_CTYP_CORE / unknown packetID: 0x%02X", packetID); + break; + + } + } + else if (component == RDPDR_CTYP_PRN) + { + DEBUG_SVC("RDPDR_CTYP_PRN"); + } + else + { + DEBUG_WARN("RDPDR component: 0x%02X packetID: 0x%02X\n", component, packetID); + } + + stream_free(data_in); +} + +static void rdpdr_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + freerdp_event_free(event); +} + +static void rdpdr_process_terminate(rdpSvcPlugin* plugin) +{ + rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin; + + devman_free(rdpdr->devman); + xfree(plugin); +} + +DEFINE_SVC_PLUGIN(rdpdr, "rdpdr", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP) diff --git a/channels/rdpdr/rdpdr_main.h b/channels/rdpdr/rdpdr_main.h new file mode 100644 index 0000000..af867fb --- /dev/null +++ b/channels/rdpdr/rdpdr_main.h @@ -0,0 +1,41 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDPDR_MAIN_H +#define __RDPDR_MAIN_H + +#include + +#include "rdpdr_types.h" + +typedef struct rdpdr_plugin rdpdrPlugin; +struct rdpdr_plugin +{ + rdpSvcPlugin plugin; + + DEVMAN* devman; + + uint16 versionMajor; + uint16 versionMinor; + uint16 clientID; + char computerName[256]; +}; + +#endif /* __RDPDR_MAIN_H */ diff --git a/channels/rdpdr/rdpdr_types.h b/channels/rdpdr/rdpdr_types.h new file mode 100644 index 0000000..a87dad2 --- /dev/null +++ b/channels/rdpdr/rdpdr_types.h @@ -0,0 +1,90 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * File System Virtual Channel + * + * Copyright 2010-2011 Marc-Andre Moreau + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDPDR_TYPES_H +#define __RDPDR_TYPES_H + +#include "config.h" +#include +#include +#include + +typedef struct _DEVICE DEVICE; +typedef struct _IRP IRP; +typedef struct _DEVMAN DEVMAN; + + +typedef void (*pcIRPRequest)(DEVICE* device, IRP* irp); +typedef void (*pcFreeDevice)(DEVICE* device); + +struct _DEVICE +{ + uint32 id; + + uint32 type; + char* name; + STREAM* data; + + pcIRPRequest IRPRequest; + pcFreeDevice Free; +}; + +typedef void (*pcIRPResponse)(IRP* irp); + +struct _IRP +{ + DEVICE* device; + DEVMAN* devman; + uint32 FileId; + uint32 CompletionId; + uint32 MajorFunction; + uint32 MinorFunction; + STREAM* input; + + uint32 IoStatus; + STREAM* output; + + pcIRPResponse Complete; + pcIRPResponse Discard; +}; + +struct _DEVMAN +{ + rdpSvcPlugin* plugin; + uint32 id_sequence; /* generate unique device id */ + LIST* devices; +}; + +typedef void (*pcRegisterDevice)(DEVMAN* devman, DEVICE* device); + +struct _DEVICE_SERVICE_ENTRY_POINTS +{ + DEVMAN* devman; + + pcRegisterDevice RegisterDevice; + pcRegisterDevice UnregisterDevice; + RDP_PLUGIN_DATA* plugin_data; +}; +typedef struct _DEVICE_SERVICE_ENTRY_POINTS DEVICE_SERVICE_ENTRY_POINTS; +typedef DEVICE_SERVICE_ENTRY_POINTS* PDEVICE_SERVICE_ENTRY_POINTS; + +typedef int (*PDEVICE_SERVICE_ENTRY)(PDEVICE_SERVICE_ENTRY_POINTS); + +#endif /* __RDPDR_TYPES_H */ diff --git a/channels/rdpdr/serial/CMakeLists.txt b/channels/rdpdr/serial/CMakeLists.txt new file mode 100644 index 0000000..40c962a --- /dev/null +++ b/channels/rdpdr/serial/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(serial_SRCS + serial_tty.c + serial_tty.h + serial_constants.h + serial_main.c +) + +include_directories(..) + +add_library(serial ${serial_SRCS}) +set_target_properties(serial PROPERTIES PREFIX "") + +target_link_libraries(serial freerdp-utils) + +install(TARGETS serial DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/serial/serial_constants.h b/channels/rdpdr/serial/serial_constants.h new file mode 100644 index 0000000..ac16f9a --- /dev/null +++ b/channels/rdpdr/serial/serial_constants.h @@ -0,0 +1,154 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Serial Port Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SERIAL_CONSTANTS_H +#define __SERIAL_CONSTANTS_H + +/* http://www.codeproject.com/KB/system/chaiyasit_t.aspx */ +#define SERIAL_TIMEOUT_MAX 4294967295u + +/* DR_CONTROL_REQ.IoControlCode */ +enum DR_PORT_CONTROL_REQ +{ + IOCTL_SERIAL_SET_BAUD_RATE = 0x001B0004, + IOCTL_SERIAL_GET_BAUD_RATE = 0x001B0050, + IOCTL_SERIAL_SET_LINE_CONTROL = 0x001B000C, + IOCTL_SERIAL_GET_LINE_CONTROL = 0x001B0054, + IOCTL_SERIAL_SET_TIMEOUTS = 0x001B001C, + IOCTL_SERIAL_GET_TIMEOUTS = 0x001B0020, + +/* GET_CHARS and SET_CHARS are swapped in the RDP docs [MS-RDPESP] */ + IOCTL_SERIAL_GET_CHARS = 0x001B0058, + IOCTL_SERIAL_SET_CHARS = 0x001B005C, + + IOCTL_SERIAL_SET_DTR = 0x001B0024, + IOCTL_SERIAL_CLR_DTR = 0x001B0028, + IOCTL_SERIAL_RESET_DEVICE = 0x001B002C, + IOCTL_SERIAL_SET_RTS = 0x001B0030, + IOCTL_SERIAL_CLR_RTS = 0x001B0034, + IOCTL_SERIAL_SET_XOFF = 0x001B0038, + IOCTL_SERIAL_SET_XON = 0x001B003C, + IOCTL_SERIAL_SET_BREAK_ON = 0x001B0010, + IOCTL_SERIAL_SET_BREAK_OFF = 0x001B0014, + IOCTL_SERIAL_SET_QUEUE_SIZE = 0x001B0008, + IOCTL_SERIAL_GET_WAIT_MASK = 0x001B0040, + IOCTL_SERIAL_SET_WAIT_MASK = 0x001B0044, + IOCTL_SERIAL_WAIT_ON_MASK = 0x001B0048, + IOCTL_SERIAL_IMMEDIATE_CHAR = 0x001B0018, + IOCTL_SERIAL_PURGE = 0x001B004C, + IOCTL_SERIAL_GET_HANDFLOW = 0x001B0060, + IOCTL_SERIAL_SET_HANDFLOW = 0x001B0064, + IOCTL_SERIAL_GET_MODEMSTATUS = 0x001B0068, + IOCTL_SERIAL_GET_DTRRTS = 0x001B0078, + +/* according to [MS-RDPESP] it should be 0x001B0084, but servers send 0x001B006C */ + IOCTL_SERIAL_GET_COMMSTATUS = 0x001B006C, + + IOCTL_SERIAL_GET_PROPERTIES = 0x001B0074, + IOCTL_SERIAL_XOFF_COUNTER = 0x001B0070, + IOCTL_SERIAL_LSRMST_INSERT = 0x001B007C, + IOCTL_SERIAL_CONFIG_SIZE = 0x001B0080, + IOCTL_SERIAL_GET_STATS = 0x001B008C, + IOCTL_SERIAL_CLEAR_STATS = 0x001B0090, + IOCTL_SERIAL_GET_MODEM_CONTROL = 0x001B0094, + IOCTL_SERIAL_SET_MODEM_CONTROL = 0x001B0098, + IOCTL_SERIAL_SET_FIFO_CONTROL = 0x001B009C, +}; + +enum SERIAL_PURGE_MASK +{ + SERIAL_PURGE_TXABORT = 0x00000001, + SERIAL_PURGE_RXABORT = 0x00000002, + SERIAL_PURGE_TXCLEAR = 0x00000004, + SERIAL_PURGE_RXCLEAR = 0x00000008, +}; + +enum SERIAL_WAIT_MASK +{ + SERIAL_EV_RXCHAR = 0x0001, /* Any Character received */ + SERIAL_EV_RXFLAG = 0x0002, /* Received certain character */ + SERIAL_EV_TXEMPTY = 0x0004, /* Transmitt Queue Empty */ + SERIAL_EV_CTS = 0x0008, /* CTS changed state */ + SERIAL_EV_DSR = 0x0010, /* DSR changed state */ + SERIAL_EV_RLSD = 0x0020, /* RLSD changed state */ + SERIAL_EV_BREAK = 0x0040, /* BREAK received */ + SERIAL_EV_ERR = 0x0080, /* Line status error occurred */ + SERIAL_EV_RING = 0x0100, /* Ring signal detected */ + SERIAL_EV_PERR = 0x0200, /* Printer error occured */ + SERIAL_EV_RX80FULL = 0x0400,/* Receive buffer is 80 percent full */ + SERIAL_EV_EVENT1 = 0x0800, /* Provider specific event 1 */ + SERIAL_EV_EVENT2 = 0x1000, /* Provider specific event 2 */ +}; + +enum SERIAL_MODEM_STATUS +{ + SERIAL_MS_DTR = 0x01, + SERIAL_MS_RTS = 0x02, + SERIAL_MS_CTS = 0x10, + SERIAL_MS_DSR = 0x20, + SERIAL_MS_RNG = 0x40, + SERIAL_MS_CAR = 0x80, +}; + +enum SERIAL_HANDFLOW +{ + SERIAL_DTR_CONTROL = 0x01, + SERIAL_CTS_HANDSHAKE = 0x08, + SERIAL_ERROR_ABORT = 0x80000000, +}; + +enum SERIAL_FLOW_CONTROL +{ + SERIAL_XON_HANDSHAKE = 0x01, + SERIAL_XOFF_HANDSHAKE = 0x02, + SERIAL_DSR_SENSITIVITY = 0x40, +}; + +enum SERIAL_CHARS +{ + SERIAL_CHAR_EOF = 0, + SERIAL_CHAR_ERROR = 1, + SERIAL_CHAR_BREAK = 2, + SERIAL_CHAR_EVENT = 3, + SERIAL_CHAR_XON = 4, + SERIAL_CHAR_XOFF = 5, +}; + +enum SERIAL_ABORT_IO +{ + SERIAL_ABORT_IO_NONE = 0, + SERIAL_ABORT_IO_WRITE = 1, + SERIAL_ABORT_IO_READ = 2, +}; + +enum SERIAL_STOP_BITS +{ + SERIAL_STOP_BITS_1 = 0, + SERIAL_STOP_BITS_2 = 2, +}; + +enum SERIAL_PARITY +{ + SERIAL_NO_PARITY = 0, + SERIAL_ODD_PARITY = 1, + SERIAL_EVEN_PARITY = 2, +}; + +#endif diff --git a/channels/rdpdr/serial/serial_main.c b/channels/rdpdr/serial/serial_main.c new file mode 100644 index 0000000..3bee5ab --- /dev/null +++ b/channels/rdpdr/serial/serial_main.c @@ -0,0 +1,714 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Serial Port Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "config.h" + +#ifdef HAVE_SYS_MODEM_H +#include +#endif +#ifdef HAVE_SYS_FILIO_H +#include +#endif +#ifdef HAVE_SYS_STRTIO_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" +#include "devman.h" +#include "serial_tty.h" +#include "serial_constants.h" + +#include +#include +#include +#include + +typedef struct _SERIAL_DEVICE SERIAL_DEVICE; +struct _SERIAL_DEVICE +{ + DEVICE device; + + char* path; + SERIAL_TTY* tty; + + LIST* irp_list; + LIST* pending_irps; + freerdp_thread* thread; + struct wait_obj* in_event; + + fd_set read_fds; + fd_set write_fds; + uint32 nfds; + struct timeval tv; + uint32 select_timeout; + uint32 timeout_id; +}; + +static void serial_abort_single_io(SERIAL_DEVICE* serial, uint32 file_id, uint32 abort_io, uint32 io_status); +static void serial_check_for_events(SERIAL_DEVICE* serial); +static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp); +static boolean serial_check_fds(SERIAL_DEVICE* serial); + +static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) +{ + SERIAL_TTY* tty; + uint32 PathLength; + uint32 FileId; + char* path; + UNICONV* uniconv; + + stream_seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ + /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ + stream_read_uint32(irp->input, PathLength); + + uniconv = freerdp_uniconv_new(); + path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); + freerdp_uniconv_free(uniconv); + + FileId = irp->devman->id_sequence++; + + tty = serial_tty_new(serial->path, FileId); + if (tty == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + FileId = 0; + + DEBUG_WARN("failed to create %s", path); + } + else + { + serial->tty = tty; + DEBUG_SVC("%s(%d) created.", serial->path, FileId); + } + + stream_write_uint32(irp->output, FileId); + stream_write_uint8(irp->output, 0); + + xfree(path); + + irp->Complete(irp); +} + +static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) +{ + SERIAL_TTY* tty; + + tty = serial->tty; + if (tty == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + DEBUG_WARN("tty not valid."); + } + else + { + DEBUG_SVC("%s(%d) closed.", serial->path, tty->id); + + serial_tty_free(tty); + serial->tty = NULL; + } + + stream_write_zero(irp->output, 5); /* Padding(5) */ + + irp->Complete(irp); +} + +static void serial_process_irp_read(SERIAL_DEVICE* serial, IRP* irp) +{ + SERIAL_TTY* tty; + uint32 Length; + uint64 Offset; + uint8* buffer = NULL; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + + DEBUG_SVC("length %u offset %llu", Length, Offset); + + tty = serial->tty; + if (tty == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("tty not valid."); + } + else + { + buffer = (uint8*)xmalloc(Length); + if (!serial_tty_read(tty, buffer, &Length)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + xfree(buffer); + buffer = NULL; + Length = 0; + + DEBUG_WARN("read %s(%d) failed.", serial->path, tty->id); + } + else + { + DEBUG_SVC("read %llu-%llu from %d", Offset, Offset + Length, tty->id); + } + } + + stream_write_uint32(irp->output, Length); + if (Length > 0) + { + stream_check_size(irp->output, Length); + stream_write(irp->output, buffer, Length); + } + xfree(buffer); + + irp->Complete(irp); +} + +static void serial_process_irp_write(SERIAL_DEVICE* serial, IRP* irp) +{ + SERIAL_TTY* tty; + uint32 Length; + uint64 Offset; + + stream_read_uint32(irp->input, Length); + stream_read_uint64(irp->input, Offset); + stream_seek(irp->input, 20); /* Padding */ + + DEBUG_SVC("length %u offset %llu", Length, Offset); + + tty = serial->tty; + if (tty == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("tty not valid."); + } + else if (!serial_tty_write(tty, stream_get_tail(irp->input), Length)) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + Length = 0; + + DEBUG_WARN("write %s(%d) failed.", serial->path, tty->id); + } + else + { + DEBUG_SVC("write %llu-%llu to %s(%d).", Offset, Offset + Length, serial->path, tty->id); + } + + stream_write_uint32(irp->output, Length); + stream_write_uint8(irp->output, 0); /* Padding */ + + irp->Complete(irp); +} + +static void serial_process_irp_device_control(SERIAL_DEVICE* serial, IRP* irp) +{ + SERIAL_TTY* tty; + uint32 IoControlCode; + uint32 InputBufferLength; + uint32 OutputBufferLength; + uint32 abort_io = SERIAL_ABORT_IO_NONE; + + DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); + + stream_read_uint32(irp->input, InputBufferLength); + stream_read_uint32(irp->input, OutputBufferLength); + stream_read_uint32(irp->input, IoControlCode); + stream_seek(irp->input, 20); /* Padding */ + + tty = serial->tty; + if (tty == NULL) + { + irp->IoStatus = STATUS_UNSUCCESSFUL; + OutputBufferLength = 0; + + DEBUG_WARN("tty not valid."); + } + else + { + irp->IoStatus = serial_tty_control(tty, IoControlCode, irp->input, irp->output, &abort_io); + } + + if (abort_io & SERIAL_ABORT_IO_WRITE) + serial_abort_single_io(serial, tty->id, SERIAL_ABORT_IO_WRITE, STATUS_CANCELLED); + if (abort_io & SERIAL_ABORT_IO_READ) + serial_abort_single_io(serial, tty->id, SERIAL_ABORT_IO_READ, STATUS_CANCELLED); + + if (irp->IoStatus == STATUS_PENDING) + list_enqueue(serial->pending_irps, irp); + else + irp->Complete(irp); +} + +static void serial_process_irp(SERIAL_DEVICE* serial, IRP* irp) +{ + DEBUG_SVC("MajorFunction %u", irp->MajorFunction); + + switch (irp->MajorFunction) + { + case IRP_MJ_CREATE: + serial_process_irp_create(serial, irp); + break; + + case IRP_MJ_CLOSE: + serial_process_irp_close(serial, irp); + break; + + case IRP_MJ_READ: + serial_handle_async_irp(serial, irp); + //serial_process_irp_read(serial, irp); + break; + + case IRP_MJ_WRITE: + serial_handle_async_irp(serial, irp); + //serial_process_irp_write(serial, irp); + break; + + case IRP_MJ_DEVICE_CONTROL: + serial_process_irp_device_control(serial, irp); + break; + + default: + DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + irp->Complete(irp); + break; + } + + serial_check_for_events(serial); +} + +static void serial_process_irp_list(SERIAL_DEVICE* serial) +{ + IRP* irp; + + while (1) + { + if (freerdp_thread_is_stopped(serial->thread)) + break; + + freerdp_thread_lock(serial->thread); + irp = (IRP*)list_dequeue(serial->irp_list); + freerdp_thread_unlock(serial->thread); + + if (irp == NULL) + break; + + serial_process_irp(serial, irp); + } +} + +static void* serial_thread_func(void* arg) +{ + SERIAL_DEVICE* serial = (SERIAL_DEVICE*)arg; + + while (1) + { + freerdp_thread_wait(serial->thread); + + serial->nfds = 1; + FD_ZERO(&serial->read_fds); + FD_ZERO(&serial->write_fds); + + serial->tv.tv_sec = 20; + serial->tv.tv_usec = 0; + serial->select_timeout = 0; + + if (freerdp_thread_is_stopped(serial->thread)) + break; + + freerdp_thread_reset(serial->thread); + serial_process_irp_list(serial); + + if (wait_obj_is_set(serial->in_event)) + { + if (serial_check_fds(serial)) + wait_obj_clear(serial->in_event); + } + } + + freerdp_thread_quit(serial->thread); + + return NULL; +} + +static void serial_irp_request(DEVICE* device, IRP* irp) +{ + SERIAL_DEVICE* serial = (SERIAL_DEVICE*)device; + + freerdp_thread_lock(serial->thread); + list_enqueue(serial->irp_list, irp); + freerdp_thread_unlock(serial->thread); + + freerdp_thread_signal(serial->thread); +} + +static void serial_free(DEVICE* device) +{ + SERIAL_DEVICE* serial = (SERIAL_DEVICE*)device; + IRP* irp; + + DEBUG_SVC("freeing device"); + + freerdp_thread_stop(serial->thread); + freerdp_thread_free(serial->thread); + + while ((irp = (IRP*)list_dequeue(serial->irp_list)) != NULL) + irp->Discard(irp); + list_free(serial->irp_list); + + while ((irp = (IRP*)list_dequeue(serial->pending_irps)) != NULL) + irp->Discard(irp); + list_free(serial->pending_irps); + + xfree(serial); +} + +int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + SERIAL_DEVICE* serial; + char* name; + char* path; + int i, len; + + name = (char*)pEntryPoints->plugin_data->data[1]; + path = (char*)pEntryPoints->plugin_data->data[2]; + + if (name[0] && path[0]) + { + serial = xnew(SERIAL_DEVICE); + + serial->device.type = RDPDR_DTYP_SERIAL; + serial->device.name = name; + serial->device.IRPRequest = serial_irp_request; + serial->device.Free = serial_free; + + len = strlen(name); + serial->device.data = stream_new(len + 1); + for (i = 0; i <= len; i++) + stream_write_uint8(serial->device.data, name[i] < 0 ? '_' : name[i]); + + serial->path = path; + serial->irp_list = list_new(); + serial->pending_irps = list_new(); + serial->thread = freerdp_thread_new(); + serial->in_event = wait_obj_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)serial); + + freerdp_thread_start(serial->thread, serial_thread_func, serial); + } + + return 0; +} + +static void serial_abort_single_io(SERIAL_DEVICE* serial, uint32 file_id, uint32 abort_io, uint32 io_status) +{ + IRP* irp = NULL; + uint32 major; + SERIAL_TTY* tty; + + DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); + + tty = serial->tty; + + switch (abort_io) + { + case SERIAL_ABORT_IO_NONE: + major = 0; + break; + + case SERIAL_ABORT_IO_READ: + major = IRP_MJ_READ; + break; + + case SERIAL_ABORT_IO_WRITE: + major = IRP_MJ_WRITE; + break; + + default: + DEBUG_SVC("unexpected abort_io code %d", abort_io); + return; + } + + irp = (IRP*)list_peek(serial->pending_irps); + while (irp) + { + if (irp->FileId != file_id || irp->MajorFunction != major) + { + irp = (IRP*)list_next(serial->pending_irps, irp); + continue; + } + + /* Process a SINGLE FileId and MajorFunction */ + list_remove(serial->pending_irps, irp); + irp->IoStatus = io_status; + stream_write_uint32(irp->output, 0); + irp->Complete(irp); + + wait_obj_set(serial->in_event); + break; + } + + DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps)); +} + +static void serial_check_for_events(SERIAL_DEVICE* serial) +{ + IRP* irp = NULL; + IRP* prev; + uint32 result = 0; + SERIAL_TTY* tty; + + tty = serial->tty; + + DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); + + irp = (IRP*)list_peek(serial->pending_irps); + while (irp) + { + prev = NULL; + + if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL) + { + if (serial_tty_get_event(tty, &result)) + { + DEBUG_SVC("got event result %u", result); + + irp->IoStatus = STATUS_SUCCESS; + stream_write_uint32(irp->output, result); + irp->Complete(irp); + + prev = irp; + irp = (IRP*)list_next(serial->pending_irps, irp); + list_remove(serial->pending_irps, prev); + + wait_obj_set(serial->in_event); + } + } + + if (!prev) + irp = (IRP*)list_next(serial->pending_irps, irp); + } + + DEBUG_SVC("[out] pending size %d", list_size(serial->pending_irps)); +} + +void serial_get_timeouts(SERIAL_DEVICE* serial, IRP* irp, uint32* timeout, uint32* interval_timeout) +{ + SERIAL_TTY* tty; + uint32 Length; + uint32 pos; + + pos = stream_get_pos(irp->input); + stream_read_uint32(irp->input, Length); + stream_set_pos(irp->input, pos); + + DEBUG_SVC("length read %u", Length); + + tty = serial->tty; + *timeout = (tty->read_total_timeout_multiplier * Length) + + tty->read_total_timeout_constant; + *interval_timeout = tty->read_interval_timeout; + + DEBUG_SVC("timeouts %u %u", *timeout, *interval_timeout); +} + +static void serial_handle_async_irp(SERIAL_DEVICE* serial, IRP* irp) +{ + uint32 timeout = 0; + uint32 itv_timeout = 0; + SERIAL_TTY* tty; + + tty = serial->tty; + + switch (irp->MajorFunction) + { + case IRP_MJ_WRITE: + DEBUG_SVC("handling IRP_MJ_WRITE"); + break; + + case IRP_MJ_READ: + DEBUG_SVC("handling IRP_MJ_READ"); + + serial_get_timeouts(serial, irp, &timeout, &itv_timeout); + + /* Check if io request timeout is smaller than current (but not 0). */ + if (timeout && (serial->select_timeout == 0 || timeout < serial->select_timeout)) + { + serial->select_timeout = timeout; + serial->tv.tv_sec = serial->select_timeout / 1000; + serial->tv.tv_usec = (serial->select_timeout % 1000) * 1000; + serial->timeout_id = tty->id; + } + if (itv_timeout && (serial->select_timeout == 0 || itv_timeout < serial->select_timeout)) + { + serial->select_timeout = itv_timeout; + serial->tv.tv_sec = serial->select_timeout / 1000; + serial->tv.tv_usec = (serial->select_timeout % 1000) * 1000; + serial->timeout_id = tty->id; + } + DEBUG_SVC("select_timeout %u, tv_sec %lu tv_usec %lu, timeout_id %u", + serial->select_timeout, serial->tv.tv_sec, serial->tv.tv_usec, serial->timeout_id); + break; + + default: + DEBUG_SVC("no need to handle %d", irp->MajorFunction); + return; + } + + irp->IoStatus = STATUS_PENDING; + list_enqueue(serial->pending_irps, irp); + wait_obj_set(serial->in_event); +} + +static void __serial_check_fds(SERIAL_DEVICE* serial) +{ + IRP* irp; + IRP* prev; + SERIAL_TTY* tty; + uint32 result = 0; + + memset(&serial->tv, 0, sizeof(struct timeval)); + tty = serial->tty; + + /* scan every pending */ + irp = list_peek(serial->pending_irps); + while (irp) + { + DEBUG_SVC("MajorFunction %u", irp->MajorFunction); + + switch (irp->MajorFunction) + { + case IRP_MJ_READ: + if (FD_ISSET(tty->fd, &serial->read_fds)) + { + irp->IoStatus = STATUS_SUCCESS; + serial_process_irp_read(serial, irp); + } + break; + + case IRP_MJ_WRITE: + if (FD_ISSET(tty->fd, &serial->write_fds)) + { + irp->IoStatus = STATUS_SUCCESS; + serial_process_irp_write(serial, irp); + } + break; + + case IRP_MJ_DEVICE_CONTROL: + if (serial_tty_get_event(tty, &result)) + { + DEBUG_SVC("got event result %u", result); + + irp->IoStatus = STATUS_SUCCESS; + stream_write_uint32(irp->output, result); + irp->Complete(irp); + } + break; + + default: + DEBUG_SVC("no request found"); + break; + } + + prev = irp; + irp = (IRP*)list_next(serial->pending_irps, irp); + if (prev->IoStatus == STATUS_SUCCESS) + { + list_remove(serial->pending_irps, prev); + wait_obj_set(serial->in_event); + } + } +} + +static void serial_set_fds(SERIAL_DEVICE* serial) +{ + fd_set* fds; + IRP* irp; + SERIAL_TTY* tty; + + DEBUG_SVC("[in] pending size %d", list_size(serial->pending_irps)); + + tty = serial->tty; + irp = (IRP*)list_peek(serial->pending_irps); + while (irp) + { + fds = NULL; + + switch (irp->MajorFunction) + { + case IRP_MJ_WRITE: + fds = &serial->write_fds; + break; + + case IRP_MJ_READ: + fds = &serial->read_fds; + break; + } + + if (fds && (tty->fd >= 0)) + { + FD_SET(tty->fd, fds); + serial->nfds = MAX(serial->nfds, tty->fd); + } + irp = (IRP*)list_next(serial->pending_irps, irp); + } +} + +static boolean serial_check_fds(SERIAL_DEVICE* serial) +{ + if (list_size(serial->pending_irps) == 0) + return 1; + + serial_set_fds(serial); + DEBUG_SVC("waiting %lu %lu", serial->tv.tv_sec, serial->tv.tv_usec); + + switch (select(serial->nfds + 1, &serial->read_fds, &serial->write_fds, NULL, &serial->tv)) + { + case -1: + DEBUG_SVC("select has returned -1 with error: %s", strerror(errno)); + return 0; + + case 0: + if (serial->select_timeout) + { + serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_NONE, STATUS_TIMEOUT); + serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_READ, STATUS_TIMEOUT); + serial_abort_single_io(serial, serial->timeout_id, SERIAL_ABORT_IO_WRITE, STATUS_TIMEOUT); + } + DEBUG_SVC("select has timed out"); + return 0; + + default: + break; + } + + __serial_check_fds(serial); + + return 1; +} diff --git a/channels/rdpdr/serial/serial_tty.c b/channels/rdpdr/serial/serial_tty.c new file mode 100644 index 0000000..a07718d --- /dev/null +++ b/channels/rdpdr/serial/serial_tty.c @@ -0,0 +1,980 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Serial Port Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_constants.h" +#include "rdpdr_types.h" +#include "serial_tty.h" +#include "serial_constants.h" + +#ifdef HAVE_SYS_MODEM_H +#include +#endif +#ifdef HAVE_SYS_FILIO_H +#include +#endif +#ifdef HAVE_SYS_STRTIO_H +#include +#endif + +#ifndef CRTSCTS +#define CRTSCTS 0 +#endif + +/* FIONREAD should really do the same thing as TIOCINQ, where it is + * not available */ +#if !defined(TIOCINQ) && defined(FIONREAD) +#define TIOCINQ FIONREAD +#endif +#if !defined(TIOCOUTQ) && defined(FIONWRITE) +#define TIOCOUTQ FIONWRITE +#endif + + +static uint32 tty_write_data(SERIAL_TTY* tty, uint8* data, int len); +static void tty_set_termios(SERIAL_TTY* tty); +static boolean tty_get_termios(SERIAL_TTY* tty); +static int tty_get_error_status(); + +uint32 serial_tty_control(SERIAL_TTY* tty, uint32 IoControlCode, STREAM* input, STREAM* output, uint32* abort_io) +{ + int purge_mask; + uint32 result; + uint32 modemstate; + uint8 immediate; + uint32 ret = STATUS_SUCCESS; + uint32 length = 0; + uint32 pos; + + DEBUG_SVC("in"); + + stream_seek(output, sizeof(uint32)); + + switch (IoControlCode) + { + case IOCTL_SERIAL_SET_BAUD_RATE: + stream_read_uint32(input, tty->baud_rate); + tty_set_termios(tty); + DEBUG_SVC("SERIAL_SET_BAUD_RATE %d", tty->baud_rate); + break; + + case IOCTL_SERIAL_GET_BAUD_RATE: + length = 4; + stream_write_uint32(output, tty->baud_rate); + DEBUG_SVC("SERIAL_GET_BAUD_RATE %d", tty->baud_rate); + break; + + case IOCTL_SERIAL_SET_QUEUE_SIZE: + stream_read_uint32(input, tty->queue_in_size); + stream_read_uint32(input, tty->queue_out_size); + DEBUG_SVC("SERIAL_SET_QUEUE_SIZE in %d out %d", tty->queue_in_size, tty->queue_out_size); + break; + + case IOCTL_SERIAL_SET_LINE_CONTROL: + stream_read_uint8(input, tty->stop_bits); + stream_read_uint8(input, tty->parity); + stream_read_uint8(input, tty->word_length); + tty_set_termios(tty); + DEBUG_SVC("SERIAL_SET_LINE_CONTROL stop %d parity %d word %d", + tty->stop_bits, tty->parity, tty->word_length); + break; + + case IOCTL_SERIAL_GET_LINE_CONTROL: + DEBUG_SVC("SERIAL_GET_LINE_CONTROL"); + length = 3; + stream_write_uint8(output, tty->stop_bits); + stream_write_uint8(output, tty->parity); + stream_write_uint8(output, tty->word_length); + break; + + case IOCTL_SERIAL_IMMEDIATE_CHAR: + DEBUG_SVC("SERIAL_IMMEDIATE_CHAR"); + stream_read_uint8(input, immediate); + tty_write_data(tty, &immediate, 1); + break; + + case IOCTL_SERIAL_CONFIG_SIZE: + DEBUG_SVC("SERIAL_CONFIG_SIZE"); + length = 4; + stream_write_uint32(output, 0); + break; + + case IOCTL_SERIAL_GET_CHARS: + DEBUG_SVC("SERIAL_GET_CHARS"); + length = 6; + stream_write(output, tty->chars, 6); + break; + + case IOCTL_SERIAL_SET_CHARS: + DEBUG_SVC("SERIAL_SET_CHARS"); + stream_read(input, tty->chars, 6); + tty_set_termios(tty); + break; + + case IOCTL_SERIAL_GET_HANDFLOW: + length = 16; + tty_get_termios(tty); + stream_write_uint32(output, tty->control); + stream_write_uint32(output, tty->xonoff); + stream_write_uint32(output, tty->onlimit); + stream_write_uint32(output, tty->offlimit); + DEBUG_SVC("IOCTL_SERIAL_GET_HANDFLOW %X %X %X %X", + tty->control, tty->xonoff, tty->onlimit, tty->offlimit); + break; + + case IOCTL_SERIAL_SET_HANDFLOW: + stream_read_uint32(input, tty->control); + stream_read_uint32(input, tty->xonoff); + stream_read_uint32(input, tty->onlimit); + stream_read_uint32(input, tty->offlimit); + DEBUG_SVC("IOCTL_SERIAL_SET_HANDFLOW %X %X %X %X", + tty->control, tty->xonoff, tty->onlimit, tty->offlimit); + tty_set_termios(tty); + break; + + case IOCTL_SERIAL_SET_TIMEOUTS: + stream_read_uint32(input, tty->read_interval_timeout); + stream_read_uint32(input, tty->read_total_timeout_multiplier); + stream_read_uint32(input, tty->read_total_timeout_constant); + stream_read_uint32(input, tty->write_total_timeout_multiplier); + stream_read_uint32(input, tty->write_total_timeout_constant); + + /* http://www.codeproject.com/KB/system/chaiyasit_t.aspx, see 'ReadIntervalTimeout' section + http://msdn.microsoft.com/en-us/library/ms885171.aspx */ + if (tty->read_interval_timeout == SERIAL_TIMEOUT_MAX) + { + tty->read_interval_timeout = 0; + tty->read_total_timeout_multiplier = 0; + } + + DEBUG_SVC("SERIAL_SET_TIMEOUTS read timeout %d %d %d", + tty->read_interval_timeout, + tty->read_total_timeout_multiplier, + tty->read_total_timeout_constant); + break; + + case IOCTL_SERIAL_GET_TIMEOUTS: + DEBUG_SVC("SERIAL_GET_TIMEOUTS read timeout %d %d %d", + tty->read_interval_timeout, + tty->read_total_timeout_multiplier, + tty->read_total_timeout_constant); + length = 20; + stream_write_uint32(output, tty->read_interval_timeout); + stream_write_uint32(output, tty->read_total_timeout_multiplier); + stream_write_uint32(output, tty->read_total_timeout_constant); + stream_write_uint32(output, tty->write_total_timeout_multiplier); + stream_write_uint32(output, tty->write_total_timeout_constant); + break; + + case IOCTL_SERIAL_GET_WAIT_MASK: + DEBUG_SVC("SERIAL_GET_WAIT_MASK %X", tty->wait_mask); + length = 4; + stream_write_uint32(output, tty->wait_mask); + break; + + case IOCTL_SERIAL_SET_WAIT_MASK: + stream_read_uint32(input, tty->wait_mask); + DEBUG_SVC("SERIAL_SET_WAIT_MASK %X", tty->wait_mask); + break; + + case IOCTL_SERIAL_SET_DTR: + DEBUG_SVC("SERIAL_SET_DTR"); + ioctl(tty->fd, TIOCMGET, &result); + result |= TIOCM_DTR; + ioctl(tty->fd, TIOCMSET, &result); + tty->dtr = 1; + break; + + case IOCTL_SERIAL_CLR_DTR: + DEBUG_SVC("SERIAL_CLR_DTR"); + ioctl(tty->fd, TIOCMGET, &result); + result &= ~TIOCM_DTR; + ioctl(tty->fd, TIOCMSET, &result); + tty->dtr = 0; + break; + + case IOCTL_SERIAL_SET_RTS: + DEBUG_SVC("SERIAL_SET_RTS"); + ioctl(tty->fd, TIOCMGET, &result); + result |= TIOCM_RTS; + ioctl(tty->fd, TIOCMSET, &result); + tty->rts = 1; + break; + + case IOCTL_SERIAL_CLR_RTS: + DEBUG_SVC("SERIAL_CLR_RTS"); + ioctl(tty->fd, TIOCMGET, &result); + result &= ~TIOCM_RTS; + ioctl(tty->fd, TIOCMSET, &result); + tty->rts = 0; + break; + + case IOCTL_SERIAL_GET_MODEMSTATUS: + modemstate = 0; +#ifdef TIOCMGET + ioctl(tty->fd, TIOCMGET, &result); + if (result & TIOCM_CTS) + modemstate |= SERIAL_MS_CTS; + if (result & TIOCM_DSR) + modemstate |= SERIAL_MS_DSR; + if (result & TIOCM_RNG) + modemstate |= SERIAL_MS_RNG; + if (result & TIOCM_CAR) + modemstate |= SERIAL_MS_CAR; + if (result & TIOCM_DTR) + modemstate |= SERIAL_MS_DTR; + if (result & TIOCM_RTS) + modemstate |= SERIAL_MS_RTS; +#endif + DEBUG_SVC("SERIAL_GET_MODEMSTATUS %X", modemstate); + length = 4; + stream_write_uint32(output, modemstate); + break; + + case IOCTL_SERIAL_GET_COMMSTATUS: + length = 18; + stream_write_uint32(output, 0); /* Errors */ + stream_write_uint32(output, 0); /* Hold reasons */ + + result = 0; +#ifdef TIOCINQ + ioctl(tty->fd, TIOCINQ, &result); +#endif + stream_write_uint32(output, result); /* Amount in in queue */ + if (result) + DEBUG_SVC("SERIAL_GET_COMMSTATUS in queue %d", result); + + result = 0; +#ifdef TIOCOUTQ + ioctl(tty->fd, TIOCOUTQ, &result); +#endif + stream_write_uint32(output, result); /* Amount in out queue */ + DEBUG_SVC("SERIAL_GET_COMMSTATUS out queue %d", result); + + stream_write_uint8(output, 0); /* EofReceived */ + stream_write_uint8(output, 0); /* WaitForImmediate */ + break; + + case IOCTL_SERIAL_PURGE: + stream_read_uint32(input, purge_mask); + DEBUG_SVC("SERIAL_PURGE purge_mask %X", purge_mask); + + /* See http://msdn.microsoft.com/en-us/library/ms901431.aspx + PURGE_TXCLEAR Clears the output buffer, if the driver has one. + PURGE_RXCLEAR Clears the input buffer, if the driver has one. + + It clearly states to clear the *driver* buffer, not the port buffer + */ + +#ifdef DEBUG_SVC + if (purge_mask & SERIAL_PURGE_TXCLEAR) + DEBUG_SVC("Ignoring SERIAL_PURGE_TXCLEAR"); + if (purge_mask & SERIAL_PURGE_RXCLEAR) + DEBUG_SVC("Ignoring SERIAL_PURGE_RXCLEAR"); +#endif + + if (purge_mask & SERIAL_PURGE_TXABORT) + *abort_io |= SERIAL_ABORT_IO_WRITE; + if (purge_mask & SERIAL_PURGE_RXABORT) + *abort_io |= SERIAL_ABORT_IO_READ; + break; + case IOCTL_SERIAL_WAIT_ON_MASK: + DEBUG_SVC("SERIAL_WAIT_ON_MASK %X", tty->wait_mask); + tty->event_pending = 1; + length = 4; + if (serial_tty_get_event(tty, &result)) + { + DEBUG_SVC("WAIT end event = %X", result); + stream_write_uint32(output, result); + break; + } + ret = STATUS_PENDING; + break; + + case IOCTL_SERIAL_SET_BREAK_ON: + DEBUG_SVC("SERIAL_SET_BREAK_ON"); + tcsendbreak(tty->fd, 0); + break; + + case IOCTL_SERIAL_RESET_DEVICE: + DEBUG_SVC("SERIAL_RESET_DEVICE"); + break; + + case IOCTL_SERIAL_SET_BREAK_OFF: + DEBUG_SVC("SERIAL_SET_BREAK_OFF"); + break; + + case IOCTL_SERIAL_SET_XOFF: + DEBUG_SVC("SERIAL_SET_XOFF"); + break; + + case IOCTL_SERIAL_SET_XON: + DEBUG_SVC("SERIAL_SET_XON"); + tcflow(tty->fd, TCION); + break; + + default: + DEBUG_SVC("NOT FOUND IoControlCode SERIAL IOCTL %d", IoControlCode); + return STATUS_INVALID_PARAMETER; + } + + /* Write OutputBufferLength */ + pos = stream_get_pos(output); + stream_set_pos(output, 16); + stream_write_uint32(output, length); + stream_set_pos(output, pos); + + return ret; +} + +boolean serial_tty_read(SERIAL_TTY* tty, uint8* buffer, uint32* Length) +{ + long timeout = 90; + struct termios *ptermios; + ssize_t r; + + DEBUG_SVC("in"); + ptermios = tty->ptermios; + + /* Set timeouts kind of like the windows serial timeout parameters. Multiply timeout + with requested read size */ + if (tty->read_total_timeout_multiplier | tty->read_total_timeout_constant) + { + timeout = + (tty->read_total_timeout_multiplier * (*Length) + + tty->read_total_timeout_constant + 99) / 100; + } + else if (tty->read_interval_timeout) + { + timeout = (tty->read_interval_timeout * (*Length) + 99) / 100; + } + + /* If a timeout is set, do a blocking read, which times out after some time. + It will make FreeRDP less responsive, but it will improve serial performance, + by not reading one character at a time. */ + if (timeout == 0) + { + ptermios->c_cc[VTIME] = 0; + ptermios->c_cc[VMIN] = 0; + } + else + { + ptermios->c_cc[VTIME] = timeout; + ptermios->c_cc[VMIN] = 1; + } + + tcsetattr(tty->fd, TCSANOW, ptermios); + + memset(buffer, 0, *Length); + r = read(tty->fd, buffer, *Length); + if (r < 0) + return false; + + tty->event_txempty = r; + *Length = r; + + return true; +} + +boolean serial_tty_write(SERIAL_TTY* tty, uint8* buffer, uint32 Length) +{ + ssize_t r; + uint32 event_txempty = Length; + + DEBUG_SVC("in"); + + while (Length > 0) + { + r = write(tty->fd, buffer, Length); + if (r < 0) + return false; + + Length -= r; + buffer += r; + } + tty->event_txempty = event_txempty; + + return true; +} + +void serial_tty_free(SERIAL_TTY* tty) +{ + DEBUG_SVC("in"); + + if (tty->fd >= 0) + { + tcsetattr(tty->fd, TCSANOW, tty->pold_termios); + close(tty->fd); + } + + xfree(tty->ptermios); + xfree(tty->pold_termios); + xfree(tty); +} + +SERIAL_TTY* serial_tty_new(const char* path, uint32 id) +{ + SERIAL_TTY* tty; + + tty = xnew(SERIAL_TTY); + tty->id = id; + tty->fd = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (tty->fd < 0) + { + perror("open"); + DEBUG_WARN("failed to open device %s", path); + return NULL; + } + else + DEBUG_SVC("tty fd %d successfully opened", tty->fd); + + tty->ptermios = (struct termios*) malloc(sizeof(struct termios)); + memset(tty->ptermios, 0, sizeof(struct termios)); + tty->pold_termios = (struct termios*) malloc(sizeof(struct termios)); + memset(tty->pold_termios, 0, sizeof(struct termios)); + tcgetattr(tty->fd, tty->pold_termios); + + if (!tty_get_termios(tty)) + { + DEBUG_WARN("%s access denied", path); + fflush(stdout); + return NULL; + } + + tty->ptermios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + tty->ptermios->c_iflag = IGNPAR | ICRNL; + tty->ptermios->c_oflag &= ~OPOST; + tty->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + tty->ptermios->c_cflag &= ~(CSIZE | PARENB); + tty->ptermios->c_cflag |= CLOCAL | CREAD | CS8; + tcsetattr(tty->fd, TCSANOW, tty->ptermios); + + tty->event_txempty = 0; + tty->event_cts = 0; + tty->event_dsr = 0; + tty->event_rlsd = 0; + tty->event_pending = 0; + + /* all read and writes should be non-blocking */ + if (fcntl(tty->fd, F_SETFL, O_NONBLOCK) == -1) + { + DEBUG_WARN("%s fcntl", path); + perror("fcntl"); + return NULL; + } + + tty->read_total_timeout_constant = 5; + + return tty; +} + +boolean serial_tty_get_event(SERIAL_TTY* tty, uint32* result) +{ + int bytes; + boolean ret = false; + + DEBUG_SVC("in"); + + *result = 0; + +#ifdef TIOCINQ + /* When wait_mask is set to zero we ought to cancel it all + For reference: http://msdn.microsoft.com/en-us/library/aa910487.aspx */ + if (tty->wait_mask == 0) + { + tty->event_pending = 0; + return true; + } + + ioctl(tty->fd, TIOCINQ, &bytes); + + if (bytes > 0) + { + DEBUG_SVC("bytes %d", bytes); + + if (bytes > tty->event_rlsd) + { + tty->event_rlsd = bytes; + if (tty->wait_mask & SERIAL_EV_RLSD) + { + DEBUG_SVC("SERIAL_EV_RLSD"); + *result |= SERIAL_EV_RLSD; + ret = true; + } + + } + + if ((bytes > 1) && (tty->wait_mask & SERIAL_EV_RXFLAG)) + { + DEBUG_SVC("SERIAL_EV_RXFLAG bytes %d", bytes); + *result |= SERIAL_EV_RXFLAG; + ret = true; + } + if ((tty->wait_mask & SERIAL_EV_RXCHAR)) + { + DEBUG_SVC("SERIAL_EV_RXCHAR bytes %d", bytes); + *result |= SERIAL_EV_RXCHAR; + ret = true; + } + + } + else + { + tty->event_rlsd = 0; + } +#endif + +#ifdef TIOCOUTQ + ioctl(tty->fd, TIOCOUTQ, &bytes); + if ((bytes == 0) + && (tty->event_txempty > 0) && (tty->wait_mask & SERIAL_EV_TXEMPTY)) + { + DEBUG_SVC("SERIAL_EV_TXEMPTY"); + *result |= SERIAL_EV_TXEMPTY; + ret = true; + } + tty->event_txempty = bytes; +#endif + + ioctl(tty->fd, TIOCMGET, &bytes); + if ((bytes & TIOCM_DSR) != tty->event_dsr) + { + tty->event_dsr = bytes & TIOCM_DSR; + if (tty->wait_mask & SERIAL_EV_DSR) + { + DEBUG_SVC("SERIAL_EV_DSR %s", (bytes & TIOCM_DSR) ? "ON" : "OFF"); + *result |= SERIAL_EV_DSR; + ret = true; + } + } + + if ((bytes & TIOCM_CTS) != tty->event_cts) + { + tty->event_cts = bytes & TIOCM_CTS; + if (tty->wait_mask & SERIAL_EV_CTS) + { + DEBUG_SVC("SERIAL_EV_CTS %s", (bytes & TIOCM_CTS) ? "ON" : "OFF"); + *result |= SERIAL_EV_CTS; + ret = true; + } + } + + if (ret) + tty->event_pending = 0; + + return ret; +} + +static boolean tty_get_termios(SERIAL_TTY* tty) +{ + speed_t speed; + struct termios *ptermios; + ptermios = tty->ptermios; + + DEBUG_SVC("tcgetattr? %d", tcgetattr(tty->fd, ptermios) >= 0); + if (tcgetattr(tty->fd, ptermios) < 0) + return false; + + speed = cfgetispeed(ptermios); + switch (speed) + { +#ifdef B75 + case B75: + tty->baud_rate = 75; + break; +#endif +#ifdef B110 + case B110: + tty->baud_rate = 110; + break; +#endif +#ifdef B134 + case B134: + tty->baud_rate = 134; + break; +#endif +#ifdef B150 + case B150: + tty->baud_rate = 150; + break; +#endif +#ifdef B300 + case B300: + tty->baud_rate = 300; + break; +#endif +#ifdef B600 + case B600: + tty->baud_rate = 600; + break; +#endif +#ifdef B1200 + case B1200: + tty->baud_rate = 1200; + break; +#endif +#ifdef B1800 + case B1800: + tty->baud_rate = 1800; + break; +#endif +#ifdef B2400 + case B2400: + tty->baud_rate = 2400; + break; +#endif +#ifdef B4800 + case B4800: + tty->baud_rate = 4800; + break; +#endif +#ifdef B9600 + case B9600: + tty->baud_rate = 9600; + break; +#endif +#ifdef B19200 + case B19200: + tty->baud_rate = 19200; + break; +#endif +#ifdef B38400 + case B38400: + tty->baud_rate = 38400; + break; +#endif +#ifdef B57600 + case B57600: + tty->baud_rate = 57600; + break; +#endif +#ifdef B115200 + case B115200: + tty->baud_rate = 115200; + break; +#endif +#ifdef B230400 + case B230400: + tty->baud_rate = 230400; + break; +#endif +#ifdef B460800 + case B460800: + tty->baud_rate = 460800; + break; +#endif + default: + tty->baud_rate = 9600; + break; + } + + speed = cfgetospeed(ptermios); + tty->dtr = (speed == B0) ? 0 : 1; + + tty->stop_bits = (ptermios->c_cflag & CSTOPB) ? SERIAL_STOP_BITS_2 : SERIAL_STOP_BITS_1; + tty->parity = + (ptermios->c_cflag & PARENB) ? ((ptermios->c_cflag & PARODD) ? SERIAL_ODD_PARITY : + SERIAL_EVEN_PARITY) : SERIAL_NO_PARITY; + switch (ptermios->c_cflag & CSIZE) + { + case CS5: + tty->word_length = 5; + break; + case CS6: + tty->word_length = 6; + break; + case CS7: + tty->word_length = 7; + break; + default: + tty->word_length = 8; + break; + } + + if (ptermios->c_cflag & CRTSCTS) + { + tty->control = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE | SERIAL_ERROR_ABORT; + } + else + { + tty->control = SERIAL_DTR_CONTROL | SERIAL_ERROR_ABORT; + } + + tty->xonoff = SERIAL_DSR_SENSITIVITY; + if (ptermios->c_iflag & IXON) + tty->xonoff |= SERIAL_XON_HANDSHAKE; + + if (ptermios->c_iflag & IXOFF) + tty->xonoff |= SERIAL_XOFF_HANDSHAKE; + + tty->chars[SERIAL_CHAR_XON] = ptermios->c_cc[VSTART]; + tty->chars[SERIAL_CHAR_XOFF] = ptermios->c_cc[VSTOP]; + tty->chars[SERIAL_CHAR_EOF] = ptermios->c_cc[VEOF]; + tty->chars[SERIAL_CHAR_BREAK] = ptermios->c_cc[VINTR]; + tty->chars[SERIAL_CHAR_ERROR] = ptermios->c_cc[VKILL]; + + return true; +} + +static void tty_set_termios(SERIAL_TTY* tty) +{ + speed_t speed; + struct termios *ptermios; + + DEBUG_SVC("in"); + ptermios = tty->ptermios; + switch (tty->baud_rate) + { +#ifdef B75 + case 75: + speed = B75; + break; +#endif +#ifdef B110 + case 110: + speed = B110; + break; +#endif +#ifdef B134 + case 134: + speed = B134; + break; +#endif +#ifdef B150 + case 150: + speed = B150; + break; +#endif +#ifdef B300 + case 300: + speed = B300; + break; +#endif +#ifdef B600 + case 600: + speed = B600; + break; +#endif +#ifdef B1200 + case 1200: + speed = B1200; + break; +#endif +#ifdef B1800 + case 1800: + speed = B1800; + break; +#endif +#ifdef B2400 + case 2400: + speed = B2400; + break; +#endif +#ifdef B4800 + case 4800: + speed = B4800; + break; +#endif +#ifdef B9600 + case 9600: + speed = B9600; + break; +#endif +#ifdef B19200 + case 19200: + speed = B19200; + break; +#endif +#ifdef B38400 + case 38400: + speed = B38400; + break; +#endif +#ifdef B57600 + case 57600: + speed = B57600; + break; +#endif +#ifdef B115200 + case 115200: + speed = B115200; + break; +#endif +#ifdef B230400 + case 230400: + speed = B115200; + break; +#endif +#ifdef B460800 + case 460800: + speed = B115200; + break; +#endif + default: + speed = B9600; + break; + } + +#ifdef CBAUD + ptermios->c_cflag &= ~CBAUD; + ptermios->c_cflag |= speed; +#else + /* on systems with separate ispeed and ospeed, we can remember the speed + in ispeed while changing DTR with ospeed */ + cfsetispeed(tty->ptermios, speed); + cfsetospeed(tty->ptermios, tty->dtr ? speed : 0); +#endif + + ptermios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CSIZE | CRTSCTS); + switch (tty->stop_bits) + { + case SERIAL_STOP_BITS_2: + ptermios->c_cflag |= CSTOPB; + break; + default: + ptermios->c_cflag &= ~CSTOPB; + break; + } + + switch (tty->parity) + { + case SERIAL_EVEN_PARITY: + ptermios->c_cflag |= PARENB; + break; + case SERIAL_ODD_PARITY: + ptermios->c_cflag |= PARENB | PARODD; + break; + case SERIAL_NO_PARITY: + ptermios->c_cflag &= ~(PARENB | PARODD); + break; + } + + switch (tty->word_length) + { + case 5: + ptermios->c_cflag |= CS5; + break; + case 6: + ptermios->c_cflag |= CS6; + break; + case 7: + ptermios->c_cflag |= CS7; + break; + default: + ptermios->c_cflag |= CS8; + break; + } + +#if 0 + if (tty->rts) + ptermios->c_cflag |= CRTSCTS; + else + ptermios->c_cflag &= ~CRTSCTS; +#endif + + if (tty->control & SERIAL_CTS_HANDSHAKE) + { + ptermios->c_cflag |= CRTSCTS; + } + else + { + ptermios->c_cflag &= ~CRTSCTS; + } + + + if (tty->xonoff & SERIAL_XON_HANDSHAKE) + { + ptermios->c_iflag |= IXON | IMAXBEL; + } + if (tty->xonoff & SERIAL_XOFF_HANDSHAKE) + { + ptermios->c_iflag |= IXOFF | IMAXBEL; + } + + if ((tty->xonoff & (SERIAL_XOFF_HANDSHAKE | SERIAL_XON_HANDSHAKE)) == 0) + { + ptermios->c_iflag &= ~IXON; + ptermios->c_iflag &= ~IXOFF; + } + + ptermios->c_cc[VSTART] = tty->chars[SERIAL_CHAR_XON]; + ptermios->c_cc[VSTOP] = tty->chars[SERIAL_CHAR_XOFF]; + ptermios->c_cc[VEOF] = tty->chars[SERIAL_CHAR_EOF]; + ptermios->c_cc[VINTR] = tty->chars[SERIAL_CHAR_BREAK]; + ptermios->c_cc[VKILL] = tty->chars[SERIAL_CHAR_ERROR]; + + tcsetattr(tty->fd, TCSANOW, ptermios); +} + +static uint32 tty_write_data(SERIAL_TTY* tty, uint8* data, int len) +{ + ssize_t r; + + DEBUG_SVC("in"); + + r = write(tty->fd, data, len); + if (r < 0) + return tty_get_error_status(); + + tty->event_txempty = r; + + return STATUS_SUCCESS; +} + +static int tty_get_error_status() +{ + DEBUG_SVC("in errno %d", errno); + + switch (errno) + { + case EACCES: + case ENOTDIR: + case ENFILE: + return STATUS_ACCESS_DENIED; + case EISDIR: + return STATUS_FILE_IS_A_DIRECTORY; + case EEXIST: + return STATUS_OBJECT_NAME_COLLISION; + case EBADF: + return STATUS_INVALID_HANDLE; + default: + return STATUS_NO_SUCH_FILE; + } +} diff --git a/channels/rdpdr/serial/serial_tty.h b/channels/rdpdr/serial/serial_tty.h new file mode 100644 index 0000000..a4b82f9 --- /dev/null +++ b/channels/rdpdr/serial/serial_tty.h @@ -0,0 +1,72 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Serial Port Device Service Virtual Channel + * + * Copyright 2011 O.S. Systems Software Ltda. + * Copyright 2011 Eduardo Fiss Beloni + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SERIAL_TTY_H +#define __SERIAL_TTY_H + +#include +#include +#include + +typedef struct _SERIAL_TTY SERIAL_TTY; +struct _SERIAL_TTY +{ + uint32 id; + int fd; + + int dtr; + int rts; + uint32 control; + uint32 xonoff; + uint32 onlimit; + uint32 offlimit; + uint32 baud_rate; + uint32 queue_in_size; + uint32 queue_out_size; + uint32 wait_mask; + uint32 read_interval_timeout; + uint32 read_total_timeout_multiplier; + uint32 read_total_timeout_constant; + uint32 write_total_timeout_multiplier; + uint32 write_total_timeout_constant; + uint8 stop_bits; + uint8 parity; + uint8 word_length; + uint8 chars[6]; + struct termios* ptermios; + struct termios* pold_termios; + int event_txempty; + int event_cts; + int event_dsr; + int event_rlsd; + int event_pending; +}; + + +SERIAL_TTY* serial_tty_new(const char* path, uint32 id); +void serial_tty_free(SERIAL_TTY* tty); + +boolean serial_tty_read(SERIAL_TTY* tty, uint8* buffer, uint32* Length); +boolean serial_tty_write(SERIAL_TTY* tty, uint8* buffer, uint32 Length); +uint32 serial_tty_control(SERIAL_TTY* tty, uint32 IoControlCode, STREAM* input, STREAM* output, uint32* abort_io); + +boolean serial_tty_get_event(SERIAL_TTY* tty, uint32* result); + +#endif /* __SERIAL_TTY_H */ diff --git a/channels/rdpdr/smartcard/CMakeLists.txt b/channels/rdpdr/smartcard/CMakeLists.txt new file mode 100644 index 0000000..816fc09 --- /dev/null +++ b/channels/rdpdr/smartcard/CMakeLists.txt @@ -0,0 +1,34 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(SCARD_SRCS + scard_main.c + scard_operations.c +) + +include_directories(..) +include_directories(${PCSC_INCLUDE_DIRS}) + +add_library(scard ${SCARD_SRCS}) +set_target_properties(scard PROPERTIES PREFIX "") + +target_link_libraries(scard freerdp-utils) +target_link_libraries(scard ${PCSC_LIBRARIES}) + +install(TARGETS scard DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpdr/smartcard/scard_main.c b/channels/rdpdr/smartcard/scard_main.c new file mode 100644 index 0000000..5066bf2 --- /dev/null +++ b/channels/rdpdr/smartcard/scard_main.c @@ -0,0 +1,204 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + Redirected Smart Card Device Service + + Copyright 2011 O.S. Systems Software Ltda. + Copyright 2011 Eduardo Fiss Beloni + Copyright 2011 Anthony Tong + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "config.h" + +#include +#include +#include + +#include +#include +#include + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" + +#include "scard_main.h" + + +static void +scard_free(DEVICE* dev) +{ + SCARD_DEVICE* scard = (SCARD_DEVICE*)dev; + IRP* irp; + + freerdp_thread_stop(scard->thread); + freerdp_thread_free(scard->thread); + + while ((irp = (IRP*)list_dequeue(scard->irp_list)) != NULL) + irp->Discard(irp); + list_free(scard->irp_list); + + xfree(dev); + return; +} + + +static void +scard_process_irp(SCARD_DEVICE* scard, IRP* irp) +{ + switch (irp->MajorFunction) + { + case IRP_MJ_DEVICE_CONTROL: + scard_device_control(scard, irp); + break; + + default: + printf("MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction); + DEBUG_WARN("Smartcard MajorFunction 0x%X not supported.", irp->MajorFunction); + irp->IoStatus = STATUS_NOT_SUPPORTED; + irp->Complete(irp); + break; + } +} + + +static void +scard_process_irp_list(SCARD_DEVICE* scard) +{ + IRP *irp; + + while (!freerdp_thread_is_stopped(scard->thread)) + { + freerdp_thread_lock(scard->thread); + irp = (IRP *) list_dequeue(scard->irp_list); + freerdp_thread_unlock(scard->thread); + + if (irp == NULL) + break; + + scard_process_irp(scard, irp); + } +} + + +struct scard_irp_thread_args { + SCARD_DEVICE* scard; + IRP* irp; + freerdp_thread* thread; +}; + + +static void +scard_process_irp_thread_func(struct scard_irp_thread_args* args) +{ + scard_process_irp(args->scard, args->irp); + + freerdp_thread_free(args->thread); + xfree(args); +} + + +static void * +scard_thread_func(void* arg) +{ + SCARD_DEVICE* scard = (SCARD_DEVICE*) arg; + + while (1) + { + freerdp_thread_wait(scard->thread); + + if (freerdp_thread_is_stopped(scard->thread)) + break; + + freerdp_thread_reset(scard->thread); + scard_process_irp_list(scard); + } + + freerdp_thread_quit(scard->thread); + + return NULL; +} + + +static void +scard_irp_request(DEVICE* device, IRP* irp) +{ + SCARD_DEVICE* scard = (SCARD_DEVICE*)device; + + if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL && + scard_async_op(irp)) + { + /* + * certain potentially long running operations + * get their own thread + * TODO: revise this mechanism.. maybe worker pool + */ + struct scard_irp_thread_args *args = xmalloc(sizeof(struct scard_irp_thread_args)); + + + args->thread = freerdp_thread_new(); + args->scard = scard; + args->irp = irp; + freerdp_thread_start(args->thread, scard_process_irp_thread_func, args); + + return; + } + + freerdp_thread_lock(scard->thread); + list_enqueue(scard->irp_list, irp); + freerdp_thread_unlock(scard->thread); + + freerdp_thread_signal(scard->thread); +} + + +int +DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) +{ + SCARD_DEVICE* scard; + char* name; + char* path; + int i, length; + + name = (char *)pEntryPoints->plugin_data->data[1]; + path = (char *)pEntryPoints->plugin_data->data[2]; + + if (name) + { + /* TODO: check if server supports sc redirect (version 5.1) */ + + scard = xnew(SCARD_DEVICE); + + scard->device.type = RDPDR_DTYP_SMARTCARD; + scard->device.name = "SCARD"; + scard->device.IRPRequest = scard_irp_request; + scard->device.Free = scard_free; + + length = strlen(scard->device.name); + scard->device.data = stream_new(length + 1); + + for (i = 0; i <= length; i++) + stream_write_uint8(scard->device.data, name[i] < 0 ? '_' : name[i]); + + scard->path = path; + + scard->irp_list = list_new(); + scard->thread = freerdp_thread_new(); + + pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard); + + freerdp_thread_start(scard->thread, scard_thread_func, scard); + } + + return 0; +} diff --git a/channels/rdpdr/smartcard/scard_main.h b/channels/rdpdr/smartcard/scard_main.h new file mode 100644 index 0000000..7813f48 --- /dev/null +++ b/channels/rdpdr/smartcard/scard_main.h @@ -0,0 +1,52 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + Redirected Smart Card Device Service + + Copyright 2011 O.S. Systems Software Ltda. + Copyright 2011 Eduardo Fiss Beloni + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __SCARD_MAIN_H +#define __SCARD_MAIN_H + +#include + +#include "devman.h" +#include "rdpdr_types.h" +#include + +struct _SCARD_DEVICE +{ + DEVICE device; + + char * name; + char * path; + + LIST* irp_list; + + freerdp_thread* thread; +}; +typedef struct _SCARD_DEVICE SCARD_DEVICE; + +#ifdef WITH_DEBUG_SCARD +#define DEBUG_SCARD(fmt, ...) DEBUG_CLASS(SCARD, fmt, ## __VA_ARGS__) +#else +#define DEBUG_SCARD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +boolean scard_async_op(IRP*); +void scard_device_control(SCARD_DEVICE*, IRP*); + +#endif diff --git a/channels/rdpdr/smartcard/scard_operations.c b/channels/rdpdr/smartcard/scard_operations.c new file mode 100644 index 0000000..26c7bc9 --- /dev/null +++ b/channels/rdpdr/smartcard/scard_operations.c @@ -0,0 +1,1540 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + Redirected Smart Card Device Service + + Copyright (C) Alexi Volkov 2006 + Copyright 2011 O.S. Systems Software Ltda. + Copyright 2011 Anthony Tong + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "rdpdr_types.h" +#include "rdpdr_constants.h" + +#include "scard_main.h" + +/* [MS-RDPESC] 3.1.4 */ +#define SCARD_IOCTL_ESTABLISH_CONTEXT 0x00090014 /* EstablishContext */ +#define SCARD_IOCTL_RELEASE_CONTEXT 0x00090018 /* ReleaseContext */ +#define SCARD_IOCTL_IS_VALID_CONTEXT 0x0009001C /* IsValidContext */ +#define SCARD_IOCTL_LIST_READER_GROUPS 0x00090020 /* ListReaderGroups */ +#define SCARD_IOCTL_LIST_READERS 0x00090028 /* ListReadersA */ +#define SCARD_IOCTL_INTRODUCE_READER_GROUP 0x00090050 /* IntroduceReaderGroup */ +#define SCARD_IOCTL_FORGET_READER_GROUP 0x00090058 /* ForgetReader */ +#define SCARD_IOCTL_INTRODUCE_READER 0x00090060 /* IntroduceReader */ +#define SCARD_IOCTL_FORGET_READER 0x00090068 /* IntroduceReader */ +#define SCARD_IOCTL_ADD_READER_TO_GROUP 0x00090070 /* AddReaderToGroup */ +#define SCARD_IOCTL_REMOVE_READER_FROM_GROUP 0x00090078 /* RemoveReaderFromGroup */ +#define SCARD_IOCTL_GET_STATUS_CHANGE 0x000900A0 /* GetStatusChangeA */ +#define SCARD_IOCTL_CANCEL 0x000900A8 /* Cancel */ +#define SCARD_IOCTL_CONNECT 0x000900AC /* ConnectA */ +#define SCARD_IOCTL_RECONNECT 0x000900B4 /* Reconnect */ +#define SCARD_IOCTL_DISCONNECT 0x000900B8 /* Disconnect */ +#define SCARD_IOCTL_BEGIN_TRANSACTION 0x000900BC /* BeginTransaction */ +#define SCARD_IOCTL_END_TRANSACTION 0x000900C0 /* EndTransaction */ +#define SCARD_IOCTL_STATE 0x000900C4 /* State */ +#define SCARD_IOCTL_STATUS 0x000900C8 /* StatusA */ +#define SCARD_IOCTL_TRANSMIT 0x000900D0 /* Transmit */ +#define SCARD_IOCTL_CONTROL 0x000900D4 /* Control */ +#define SCARD_IOCTL_GETATTRIB 0x000900D8 /* GetAttrib */ +#define SCARD_IOCTL_SETATTRIB 0x000900DC /* SetAttrib */ +#define SCARD_IOCTL_ACCESS_STARTED_EVENT 0x000900E0 /* SCardAccessStartedEvent */ +#define SCARD_IOCTL_LOCATE_CARDS_BY_ATR 0x000900E8 /* LocateCardsByATR */ + +#define SCARD_INPUT_LINKED 0xFFFFFFFF + +/* Decode Win CTL_CODE values */ +#define WIN_CTL_FUNCTION(ctl_code) ((ctl_code & 0x3FFC) >> 2) +#define WIN_CTL_DEVICE_TYPE(ctl_code) (ctl_code >> 16) + +#define WIN_FILE_DEVICE_SMARTCARD 0x00000031 + + +static uint32 sc_output_string(IRP* irp, char *src, boolean wide) +{ + uint8* p; + uint32 len; + + p = stream_get_tail(irp->output); + len = strlen(src) + 1; + + if (wide) + { + int i; + + for (i = 0; i < len; i++ ) + { + p[2 * i] = src[i] < 0 ? '?' : src[i]; + p[2 * i + 1] = '\0'; + } + + len *= 2; + } + else + { + memcpy(p, src, len); + } + + stream_seek(irp->output, len); + return len; +} + +static void sc_output_alignment(IRP *irp, uint32 seed) +{ + uint32 size = stream_get_length(irp->output) - 20; + uint32 add = (seed - (size % seed)) % seed; + + if (add > 0) + stream_write_zero(irp->output, add); +} + +static void sc_output_repos(IRP* irp, uint32 written) +{ + uint32 add = (4 - (written % 4)) % 4; + + if (add > 0) + stream_write_zero(irp->output, add); +} + +static uint32 sc_output_return(IRP* irp, uint32 rv) +{ + stream_write_zero(irp->output, 256); + return rv; +} + +static void sc_output_buffer_limit(IRP* irp, char *buffer, unsigned int length, unsigned int highLimit) +{ + int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length)); + + stream_write_uint32(irp->output, header); + + if (length <= 0) + { + stream_write_uint32(irp->output, 0); + } + else + { + if (header < length) + length = header; + + stream_write(irp->output, buffer, length); + sc_output_repos(irp, length); + } +} + +static void sc_output_buffer(IRP* irp, char *buffer, unsigned int length) +{ + sc_output_buffer_limit(irp, buffer, length, 0x7FFFFFFF); +} + +static void sc_output_buffer_start_limit(IRP *irp, int length, int highLimit) +{ + int header = (length < 0) ? (0) : ((length > highLimit) ? (highLimit) : (length)); + + stream_write_uint32(irp->output, header); + stream_write_uint32(irp->output, 0x00000001); /* Magic DWORD - any non zero */ +} + +static void sc_output_buffer_start(IRP *irp, int length) +{ + sc_output_buffer_start_limit(irp, length, 0x7FFFFFFF); +} + +static uint32 sc_input_string(IRP* irp, char **dest, uint32 dataLength, boolean wide) +{ + char *buffer; + int bufferSize; + + bufferSize = wide ? (2 * dataLength) : dataLength; + buffer = xmalloc(bufferSize + 2); /* reserve 2 bytes for the '\0' */ + + stream_read(irp->input, buffer, bufferSize); + if (wide) + { + int i; + for (i = 0; i < dataLength; i++) + { + if ((buffer[2 * i] < 0) || (buffer[2 * i + 1] != 0)) + buffer[i] = '?'; + else + buffer[i] = buffer[2 * i]; + } + } + + buffer[dataLength] = '\0'; + *dest = buffer; + + return bufferSize; +} + +static void sc_input_repos(IRP* irp, uint32 read) +{ + uint32 add = 4 - (read % 4); + + if (add < 4 && add > 0) + stream_seek(irp->input, add); +} + +static void sc_input_reader_name(IRP* irp, char **dest, boolean wide) +{ + uint32 dataLength; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, dataLength); + + DEBUG_SCARD("datalength %d", dataLength); + sc_input_repos(irp, sc_input_string(irp, dest, dataLength, wide)); +} + +static void sc_input_skip_linked(IRP* irp) +{ + uint32 len; + stream_read_uint32(irp->input, len); + + if (len > 0) + { + stream_seek(irp->input, len); + sc_input_repos(irp, len); + } +} + +static uint32 sc_map_state(uint32 state) +{ + /* is this mapping still needed? */ + + if (state & SCARD_SPECIFIC) + state = 0x00000006; + else if (state & SCARD_NEGOTIABLE) + state = 0x00000005; + else if (state & SCARD_POWERED) + state = 0x00000004; + else if (state & SCARD_SWALLOWED) + state = 0x00000003; + else if (state & SCARD_PRESENT) + state = 0x00000002; + else if (state & SCARD_ABSENT) + state = 0x00000001; + else + state = 0x00000000; + + return state; +} + +static uint32 handle_EstablishContext(IRP* irp) +{ + uint32 len, rv; + uint32 scope; + SCARDCONTEXT hContext = -1; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, len); + + if (len != 8) + return SCARD_F_INTERNAL_ERROR; + + stream_seek_uint32(irp->input); + stream_read_uint32(irp->input, scope); + + rv = SCardEstablishContext(scope, NULL, NULL, &hContext); + + stream_write_uint32(irp->output, 4); // ? + stream_write_uint32(irp->output, -1); // ? + + stream_write_uint32(irp->output, 4); + stream_write_uint32(irp->output, hContext); + + /* TODO: store hContext in allowed context list */ + + return SCARD_S_SUCCESS; +} + +static uint32 handle_ReleaseContext(IRP* irp) +{ + uint32 len, rv; + SCARDCONTEXT hContext = -1; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, len); + + stream_seek(irp->input, 0x10); + stream_read_uint32(irp->input, hContext); + + rv = SCardReleaseContext(hContext); + if (rv) + DEBUG_SCARD("%s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("success 0x%08lx", hContext); + + return rv; +} + +static uint32 handle_IsValidContext(IRP* irp) +{ + uint32 rv; + SCARDCONTEXT hContext; + + stream_seek(irp->input, 0x1C); + stream_read_uint32(irp->input, hContext); + + rv = SCardIsValidContext(hContext); + + if (rv) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success context: 0x%08x", (unsigned) hContext); + + stream_write_uint32(irp->output, rv); + + return rv; +} + +static uint32 handle_ListReaders(IRP* irp, boolean wide) +{ + uint32 len, rv; + SCARDCONTEXT hContext; + DWORD dwReaders; + char *readerList = NULL, *walker; + int elemLength, dataLength; + int pos, poslen1, poslen2; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, len); + + stream_seek(irp->input, 0x1c); + stream_read_uint32(irp->input, len); + + if (len != 4) + return SCARD_F_INTERNAL_ERROR; + + stream_read_uint32(irp->input, hContext); + + /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ + + rv = SCARD_S_SUCCESS; +#ifdef SCARD_AUTOALLOCATE + dwReaders = SCARD_AUTOALLOCATE; + rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); +#else + rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); + + readerList = xmalloc(dwReaders); + rv = SCardListReaders(hContext, NULL, readerList, &dwReaders); +#endif + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + return rv; + } + +/* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ + + poslen1 = stream_get_pos(irp->output); + stream_seek_uint32(irp->output); + + stream_write_uint32(irp->output, 0x01760650); + + poslen2 = stream_get_pos(irp->output); + stream_seek_uint32(irp->output); + + walker = readerList; + dataLength = 0; + + while (1) + { + elemLength = strlen(walker); + if (elemLength == 0) + break; + + dataLength += sc_output_string(irp, walker, wide); + walker += elemLength + 1; + elemLength = strlen(walker); + } + + dataLength += sc_output_string(irp, "\0", wide); + + pos = stream_get_pos(irp->output); + + stream_set_pos(irp->output, poslen1); + stream_write_uint32(irp->output, dataLength); + stream_set_pos(irp->output, poslen2); + stream_write_uint32(irp->output, dataLength); + + stream_set_pos(irp->output, pos); + + sc_output_repos(irp, dataLength); + sc_output_alignment(irp, 8); + +#ifdef SCARD_AUTOALLOCATE + SCardFreeMemory(hContext, readerList); +#else + xfree(readerList); +#endif + + return rv; +} + +static uint32 handle_GetStatusChange(IRP* irp, boolean wide) +{ + LONG rv; + SCARDCONTEXT hContext; + DWORD dwTimeout = 0; + DWORD readerCount = 0; + SCARD_READERSTATE *readerStates, *cur; + int i; + + stream_seek(irp->input, 0x18); + stream_read_uint32(irp->input, dwTimeout); + stream_read_uint32(irp->input, readerCount); + + stream_seek(irp->input, 8); + + stream_read_uint32(irp->input, hContext); + + stream_seek(irp->input, 4); + + DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", + (unsigned) hContext, (unsigned) dwTimeout, (int) readerCount); + if (readerCount > 0) + { + readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE)); + if (!readerStates) + return sc_output_return(irp, SCARD_E_NO_MEMORY); + + + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + + stream_seek(irp->input, 4); + + /* + * TODO: on-wire is little endian; need to either + * convert to host endian or fix the headers to + * request the order we want + */ + stream_read_uint32(irp->input, cur->dwCurrentState); + stream_read_uint32(irp->input, cur->dwEventState); + stream_read_uint32(irp->input, cur->cbAtr); + stream_read(irp->input, cur->rgbAtr, 32); + + stream_seek(irp->input, 4); + + /* reset high bytes? */ + cur->dwCurrentState &= 0x0000FFFF; + cur->dwEventState &= 0x0000FFFF; + cur->dwEventState = 0; + } + + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + uint32 dataLength; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, dataLength); + sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide)); + + DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); + DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", + (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, + (unsigned) cur->dwEventState); + + if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) + cur->dwCurrentState |= SCARD_STATE_IGNORE; + } + } + else + { + readerStates = NULL; + } + + rv = SCardGetStatusChange(hContext, (DWORD) dwTimeout, readerStates, (DWORD) readerCount); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success"); + + stream_write_uint32(irp->output, readerCount); + stream_write_uint32(irp->output, 0x00084dd8); + stream_write_uint32(irp->output, readerCount); + + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + + DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); + DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x\n", + (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, + (unsigned) cur->dwEventState); + + /* TODO: do byte conversions if necessary */ + stream_write_uint32(irp->output, cur->dwCurrentState); + stream_write_uint32(irp->output, cur->dwEventState); + stream_write_uint32(irp->output, cur->cbAtr); + stream_write(irp->output, cur->rgbAtr, 32); + + stream_write_zero(irp->output, 4); + + xfree((void *)cur->szReader); + } + + sc_output_alignment(irp, 8); + + xfree(readerStates); + return rv; +} + +static uint32 handle_Cancel(IRP *irp) +{ + LONG rv; + SCARDCONTEXT hContext; + + stream_seek(irp->input, 0x1C); + stream_read_uint32(irp->input, hContext); + + rv = SCardCancel(hContext); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)\n", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success context: 0x%08x %s\n", (unsigned) hContext, pcsc_stringify_error(rv)); + + sc_output_alignment(irp, 8); + + return rv; +} + +static uint32 handle_Connect(IRP* irp, boolean wide) +{ + LONG rv; + SCARDCONTEXT hContext; + char *readerName = NULL; + DWORD dwShareMode = 0; + DWORD dwPreferredProtocol = 0; + DWORD dwActiveProtocol = 0; + SCARDHANDLE hCard; + + stream_seek(irp->input, 0x1c); + stream_read_uint32(irp->input, dwShareMode); + stream_read_uint32(irp->input, dwPreferredProtocol); + + sc_input_reader_name(irp, &readerName, wide); + + stream_seek(irp->input, 4); + stream_read_uint32(irp->input, hContext); + + DEBUG_SCARD("(context: 0x%08x, share: 0x%08x, proto: 0x%08x, reader: \"%s\")", + (unsigned) hContext, (unsigned) dwShareMode, + (unsigned) dwPreferredProtocol, readerName ? readerName : "NULL"); + + rv = SCardConnect(hContext, readerName, (DWORD) dwShareMode, + (DWORD) dwPreferredProtocol, &hCard, (DWORD *) &dwActiveProtocol); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s 0x%08x", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success 0x%08x", (unsigned) hCard); + + stream_write_uint32(irp->output, 0x00000000); + stream_write_uint32(irp->output, 0x00000000); + stream_write_uint32(irp->output, 0x00000004); + stream_write_uint32(irp->output, 0x016Cff34); + stream_write_uint32(irp->output, dwActiveProtocol); + stream_write_uint32(irp->output, 0x00000004); + stream_write_uint32(irp->output, hCard); + stream_seek(irp->output, 28); + + sc_output_alignment(irp, 8); + + xfree(readerName); + return rv; +} + +static uint32 handle_Reconnect(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hContext; + SCARDHANDLE hCard; + DWORD dwShareMode = 0; + DWORD dwPreferredProtocol = 0; + DWORD dwInitialization = 0; + DWORD dwActiveProtocol = 0; + + stream_seek(irp->input, 0x20); + stream_read_uint32(irp->input, dwShareMode); + stream_read_uint32(irp->input, dwPreferredProtocol); + stream_read_uint32(irp->input, dwInitialization); + + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, hContext); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, hCard); + + DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, share: 0x%08x, proto: 0x%08x, init: 0x%08x)", + (unsigned) hContext, (unsigned) hCard, + (unsigned) dwShareMode, (unsigned) dwPreferredProtocol, (unsigned) dwInitialization); + + rv = SCardReconnect(hCard, (DWORD) dwShareMode, (DWORD) dwPreferredProtocol, + (DWORD) dwInitialization, (LPDWORD) &dwActiveProtocol); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success (proto: 0x%08x)", (unsigned) dwActiveProtocol); + + sc_output_alignment(irp, 8); + stream_write_uint32(irp->output, dwActiveProtocol); /* reversed? */ + + return rv; +} + +static uint32 handle_Disconnect(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hContext; + SCARDHANDLE hCard; + DWORD dwDisposition = 0; + + stream_seek(irp->input, 0x20); + stream_read_uint32(irp->input, dwDisposition); + stream_seek(irp->input, 4); + stream_read_uint32(irp->input, hContext); + stream_seek(irp->input, 4); + stream_read_uint32(irp->input, hCard); + + DEBUG_SCARD("(context: 0x%08x, hcard: 0x%08x, disposition: 0x%08x)", + (unsigned) hContext, (unsigned) hCard, (unsigned) dwDisposition); + + rv = SCardDisconnect(hCard, (DWORD) dwDisposition); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success"); + + sc_output_alignment(irp, 8); + + return rv; +} + +static uint32 handle_BeginTransaction(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hCard; + + stream_seek(irp->input, 0x30); + stream_read_uint32(irp->input, hCard); + + rv = SCardBeginTransaction(hCard); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard); + + sc_output_alignment(irp, 8); + + return rv; +} + +static uint32 handle_EndTransaction(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hCard; + DWORD dwDisposition = 0; + + stream_seek(irp->input, 0x20); + stream_read_uint32(irp->input, dwDisposition); + + stream_seek(irp->input, 0x0C); + stream_read_uint32(irp->input, hCard); + + rv = SCardEndTransaction(hCard, dwDisposition); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success hcard: 0x%08x", (unsigned) hCard); + + sc_output_alignment(irp, 8); + + return rv; +} + +static uint32 handle_State(IRP* irp) +{ + LONG rv; + SCARDHANDLE hCard; + DWORD state = 0, protocol = 0; + DWORD readerLen; + DWORD atrLen = MAX_ATR_SIZE; + char * readerName; + BYTE pbAtr[MAX_ATR_SIZE]; + +#ifdef WITH_DEBUG_SCARD + int i; +#endif + + stream_seek(irp->input, 0x24); + stream_seek_uint32(irp->input); /* atrLen */ + + stream_seek(irp->input, 0x0c); + stream_read_uint32(irp->input, hCard); + stream_seek(irp->input, 0x04); + +#ifdef SCARD_AUTOALLOCATE + readerLen = SCARD_AUTOALLOCATE; + + rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); +#else + readerLen = 256; + readerName = xmalloc(readerLen); + + rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); +#endif + + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + return sc_output_return(irp, rv); + } + + DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)", + (unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol); + +#ifdef WITH_DEBUG_SCARD + printf(" ATR: "); + for (i = 0; i < atrLen; i++) + printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); + printf("\n"); +#endif + + state = sc_map_state(state); + + stream_write_uint32(irp->output, state); + stream_write_uint32(irp->output, protocol); + stream_write_uint32(irp->output, atrLen); + stream_write_uint32(irp->output, 0x00000001); + stream_write_uint32(irp->output, atrLen); + stream_write(irp->output, pbAtr, atrLen); + + sc_output_repos(irp, atrLen); + sc_output_alignment(irp, 8); + +#ifdef SCARD_AUTOALLOCATE + xfree(readerName); +#else + xfree(readerName); +#endif + + return rv; +} + +static DWORD handle_Status(IRP *irp, boolean wide) +{ + LONG rv; + SCARDHANDLE hCard; + DWORD state, protocol; + DWORD readerLen = 0; + DWORD atrLen = 0; + char * readerName; + BYTE pbAtr[MAX_ATR_SIZE]; + uint32 dataLength; + int pos, poslen1, poslen2; + +#ifdef WITH_DEBUG_SCARD + int i; +#endif + + stream_seek(irp->input, 0x24); + stream_read_uint32(irp->input, readerLen); + stream_read_uint32(irp->input, atrLen); + stream_seek(irp->input, 0x0c); + stream_read_uint32(irp->input, hCard); + stream_seek(irp->input, 0x4); + + atrLen = MAX_ATR_SIZE; + +#ifdef SCARD_AUTOALLOCATE + readerLen = SCARD_AUTOALLOCATE; + + rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); +#else + readerLen = 256; + readerName = xmalloc(readerLen); + + rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); +#endif + + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + return sc_output_return(irp, rv); + } + + DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol); + DEBUG_SCARD(" Reader: \"%s\"", readerName ? readerName : "NULL"); + +#ifdef WITH_DEBUG_SCARD + printf(" ATR: "); + for (i = 0; i < atrLen; i++) + printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); + printf("\n"); +#endif + + state = sc_map_state(state); + + poslen1 = stream_get_pos(irp->output); + stream_write_uint32(irp->output, readerLen); + stream_write_uint32(irp->output, 0x00020000); + stream_write_uint32(irp->output, state); + stream_write_uint32(irp->output, protocol); + stream_write(irp->output, pbAtr, atrLen); + + if (atrLen < 32) + stream_write_zero(irp->output, 32 - atrLen); + stream_write_uint32(irp->output, atrLen); + + poslen2 = stream_get_pos(irp->output); + stream_write_uint32(irp->output, readerLen); + + dataLength = sc_output_string(irp, readerName, wide); + dataLength += sc_output_string(irp, "\0", wide); + sc_output_repos(irp, dataLength); + + pos = stream_get_pos(irp->output); + stream_set_pos(irp->output, poslen1); + stream_write_uint32(irp->output,dataLength); + stream_set_pos(irp->output, poslen2); + stream_write_uint32(irp->output,dataLength); + stream_set_pos(irp->output, pos); + + sc_output_alignment(irp, 8); + +#ifdef SCARD_AUTOALLOCATE + /* SCardFreeMemory(NULL, readerName); */ + free(readerName); +#else + xfree(readerName); +#endif + + return rv; +} + +static uint32 handle_Transmit(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hCard; + uint32 map[7], linkedLen; + SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; + DWORD cbSendLength = 0, cbRecvLength = 0; + BYTE *sendBuf = NULL, *recvBuf = NULL; + + stream_seek(irp->input, 0x14); + stream_read_uint32(irp->input, map[0]); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, map[1]); + + stream_read_uint32(irp->input, pioSendPci.dwProtocol); + stream_read_uint32(irp->input, pioSendPci.cbPciLength); + + stream_read_uint32(irp->input, map[2]); + stream_read_uint32(irp->input, cbSendLength); + stream_read_uint32(irp->input, map[3]); + stream_read_uint32(irp->input, map[4]); + stream_read_uint32(irp->input, map[5]); + stream_read_uint32(irp->input, cbRecvLength); + + if (map[0] & SCARD_INPUT_LINKED) + sc_input_skip_linked(irp); + + stream_seek(irp->input, 4); + stream_read_uint32(irp->input, hCard); + + if (map[2] & SCARD_INPUT_LINKED) + { + /* sendPci */ + stream_read_uint32(irp->input, linkedLen); + + stream_read_uint32(irp->input, pioSendPci.dwProtocol); + stream_seek(irp->input, linkedLen - 4); + + sc_input_repos(irp, linkedLen); + } + pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); + + if (map[3] & SCARD_INPUT_LINKED) + { + /* send buffer */ + stream_read_uint32(irp->input, linkedLen); + + sendBuf = xmalloc(linkedLen); + stream_read(irp->input, sendBuf, linkedLen); + sc_input_repos(irp, linkedLen); + } + + if (cbRecvLength) + recvBuf = xmalloc(cbRecvLength); + + if (map[4] & SCARD_INPUT_LINKED) + { + /* recvPci */ + stream_read_uint32(irp->input, linkedLen); + + stream_read_uint32(irp->input, pioRecvPci.dwProtocol); + stream_seek(irp->input, linkedLen - 4); + + sc_input_repos(irp, linkedLen); + + stream_read_uint32(irp->input, map[6]); + if (map[6] & SCARD_INPUT_LINKED) + { + /* not sure what this is */ + stream_read_uint32(irp->input, linkedLen); + stream_seek(irp->input, linkedLen); + + sc_input_repos(irp, linkedLen); + } + pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST); + pPioRecvPci = &pioRecvPci; + } + else + { + pPioRecvPci = NULL; + } + pPioRecvPci = NULL; + + DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)", + (long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength); + + rv = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, + pPioRecvPci, recvBuf, &cbRecvLength); + + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + } + else + { + DEBUG_SCARD("Success (%d bytes)", (int) cbRecvLength); + + stream_write_uint32(irp->output, 0); /* pioRecvPci 0x00; */ + + sc_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ + + sc_output_buffer(irp, (char *) recvBuf, cbRecvLength); + } + + sc_output_alignment(irp, 8); + + xfree(sendBuf); + xfree(recvBuf); + + return rv; +} + +static uint32 handle_Control(IRP* irp) +{ + LONG rv; + SCARDCONTEXT hContext; + SCARDHANDLE hCard; + uint32 map[3]; + uint32 controlCode; + uint32 controlFunction; + BYTE *recvBuffer = NULL, *sendBuffer = NULL; + uint32 recvLength; + DWORD nBytesReturned; + DWORD outBufferSize; + + stream_seek(irp->input, 0x14); + stream_read_uint32(irp->input, map[0]); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, map[1]); + stream_read_uint32(irp->input, controlCode); + stream_read_uint32(irp->input, recvLength); + stream_read_uint32(irp->input, map[2]); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, outBufferSize); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, hContext); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, hCard); + + /* Translate Windows SCARD_CTL_CODE's to corresponding local code */ + if (WIN_CTL_DEVICE_TYPE(controlCode) == WIN_FILE_DEVICE_SMARTCARD) + { + controlFunction = WIN_CTL_FUNCTION(controlCode); + controlCode = SCARD_CTL_CODE(controlFunction); + } + DEBUG_SCARD("controlCode: 0x%08x", (unsigned) controlCode); + + if (map[2] & SCARD_INPUT_LINKED) + { + /* read real input size */ + stream_read_uint32(irp->input, recvLength); + + recvBuffer = xmalloc(recvLength); + + if (!recvBuffer) + return sc_output_return(irp, SCARD_E_NO_MEMORY); + + stream_read(irp->input, recvBuffer, recvLength); + } + + nBytesReturned = outBufferSize; + sendBuffer = xmalloc(outBufferSize); + + if (!sendBuffer) + return sc_output_return(irp, SCARD_E_NO_MEMORY); + + rv = SCardControl(hCard, (DWORD) controlCode, recvBuffer, (DWORD) recvLength, + sendBuffer, (DWORD) outBufferSize, &nBytesReturned); + + if (rv != SCARD_S_SUCCESS) + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); + else + DEBUG_SCARD("Success (out: %u bytes)", (unsigned) nBytesReturned); + + stream_write_uint32(irp->output, (uint32) nBytesReturned); + stream_write_uint32(irp->output, 0x00000004); + stream_write_uint32(irp->output, nBytesReturned); + + if (nBytesReturned > 0) + { + stream_write(irp->output, sendBuffer, nBytesReturned); + sc_output_repos(irp, nBytesReturned); + } + + sc_output_alignment(irp, 8); + + xfree(recvBuffer); + xfree(sendBuffer); + + return rv; +} + +static uint32 handle_GetAttrib(IRP* irp) +{ + LONG rv; + SCARDHANDLE hCard; + DWORD dwAttrId = 0, dwAttrLen = 0; + DWORD attrLen = 0; + uint8* pbAttr = NULL; + + stream_seek(irp->input, 0x20); + stream_read_uint32(irp->input, dwAttrId); + stream_seek(irp->input, 0x4); + stream_read_uint32(irp->input, dwAttrLen); + stream_seek(irp->input, 0xC); + stream_read_uint32(irp->input, hCard); + + DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)\n", + (unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen); + +#ifdef SCARD_AUTOALLOCATE + if(dwAttrLen == 0) + { + attrLen = 0; + } + else + { + attrLen = SCARD_AUTOALLOCATE; + } +#endif + + rv = SCardGetAttrib(hCard, dwAttrId, attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); + if( rv != SCARD_S_SUCCESS ) { +#ifdef SCARD_AUTOALLOCATE + if(dwAttrLen == 0) + { + attrLen = 0; + } + else + { + attrLen = SCARD_AUTOALLOCATE; + } +#endif + } + + if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A && rv == SCARD_E_UNSUPPORTED_FEATURE) + { + rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, + attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); + if( rv != SCARD_S_SUCCESS ) { +#ifdef SCARD_AUTOALLOCATE + if(dwAttrLen == 0) + { + attrLen = 0; + } + else + { + attrLen = SCARD_AUTOALLOCATE; + } +#endif + } + } + if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W && rv == SCARD_E_UNSUPPORTED_FEATURE) + { + rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, + attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); + if( rv != SCARD_S_SUCCESS ) { +#ifdef SCARD_AUTOALLOCATE + if(dwAttrLen == 0) + { + attrLen = 0; + } + else + { + attrLen = SCARD_AUTOALLOCATE; + } +#endif + } + } + if(attrLen > dwAttrLen && pbAttr != NULL) + { + rv = SCARD_E_INSUFFICIENT_BUFFER; + } + dwAttrLen = attrLen; + + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned int) rv); + free(pbAttr); + return sc_output_return(irp, rv); + } + else + { + DEBUG_SCARD("Success (%d bytes)", (int) dwAttrLen); + + stream_write_uint32(irp->output, dwAttrLen); + stream_write_uint32(irp->output, 0x00000200); + stream_write_uint32(irp->output, dwAttrLen); + + if (!pbAttr) + { + stream_write_zero(irp->output, dwAttrLen); + } + else + { + stream_write(irp->output, pbAttr, dwAttrLen); + } + sc_output_repos(irp, dwAttrLen); + /* align to multiple of 4 */ + stream_write_uint32(irp->output, 0); + } + sc_output_alignment(irp, 8); + + xfree(pbAttr); + + return rv; +} + +static uint32 handle_AccessStartedEvent(IRP* irp) +{ + stream_write_zero(irp->output, 8); + return SCARD_S_SUCCESS; +} + +void scard_error(SCARD_DEVICE* scard, IRP* irp, uint32 ntstatus) +{ + /* [MS-RDPESC] 3.1.4.4 */ + printf("scard processing error %x\n", ntstatus); + + stream_set_pos(irp->output, 0); /* CHECKME */ + irp->IoStatus = ntstatus; + irp->Complete(irp); +} + +/* http://msdn.microsoft.com/en-gb/library/ms938473.aspx */ +typedef struct _SERVER_SCARD_ATRMASK +{ + uint32 cbAtr; + uint8 rgbAtr[36]; + uint8 rgbMask[36]; +} +SERVER_SCARD_ATRMASK; + +static uint32 handle_LocateCardsByATR(IRP* irp, boolean wide) +{ + LONG rv; + int i, j, k; + SCARDCONTEXT hContext; + uint32 atrMaskCount = 0; + uint32 readerCount = 0; + SCARD_READERSTATE* cur = NULL; + SCARD_READERSTATE* rsCur = NULL; + SCARD_READERSTATE* readerStates = NULL; + SERVER_SCARD_ATRMASK* curAtr = NULL; + SERVER_SCARD_ATRMASK* pAtrMasks = NULL; + + stream_seek(irp->input, 0x2C); + stream_read_uint32(irp->input, hContext); + stream_read_uint32(irp->input, atrMaskCount); + + pAtrMasks = xmalloc(atrMaskCount * sizeof(SERVER_SCARD_ATRMASK)); + + if (!pAtrMasks) + return sc_output_return(irp, SCARD_E_NO_MEMORY); + + for (i = 0; i < atrMaskCount; i++) + { + stream_read_uint32(irp->input, pAtrMasks[i].cbAtr); + stream_read(irp->input, pAtrMasks[i].rgbAtr, 36); + stream_read(irp->input, pAtrMasks[i].rgbMask, 36); + } + + stream_read_uint32(irp->input, readerCount); + + readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE)); + + if (!readerStates) + return sc_output_return(irp, SCARD_E_NO_MEMORY); + + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + + stream_seek(irp->input, 4); + + /* + * TODO: on-wire is little endian; need to either + * convert to host endian or fix the headers to + * request the order we want + */ + stream_read_uint32(irp->input, cur->dwCurrentState); + stream_read_uint32(irp->input, cur->dwEventState); + stream_read_uint32(irp->input, cur->cbAtr); + stream_read(irp->input, cur->rgbAtr, 32); + + stream_seek(irp->input, 4); + + /* reset high bytes? */ + cur->dwCurrentState &= 0x0000FFFF; + cur->dwEventState &= 0x0000FFFF; + cur->dwEventState = 0; + } + + for (i = 0; i < readerCount; i++) + { + cur = &readerStates[i]; + uint32 dataLength; + + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, dataLength); + sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide)); + + DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); + DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", + (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, + (unsigned) cur->dwEventState); + + if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) + cur->dwCurrentState |= SCARD_STATE_IGNORE; + } + + rv = SCardGetStatusChange(hContext, 0x00000001, readerStates, readerCount); + if (rv != SCARD_S_SUCCESS) + { + DEBUG_SCARD("Failure: %s (0x%08x)", + pcsc_stringify_error(rv), (unsigned) rv); + + return sc_output_return(irp, rv); + } + + DEBUG_SCARD("Success"); + for (i = 0, curAtr = pAtrMasks; i < atrMaskCount; i++, curAtr++) + { + for (j = 0, rsCur = readerStates; j < readerCount; j++, rsCur++) + { + boolean equal = 1; + for (k = 0; k < cur->cbAtr; k++) + { + if ((curAtr->rgbAtr[k] & curAtr->rgbMask[k]) != + (rsCur->rgbAtr[k] & curAtr->rgbMask[k])) + { + equal = 0; + break; + } + } + if (equal) + { + rsCur->dwEventState |= 0x00000040; /* SCARD_STATE_ATRMATCH 0x00000040 */ + } + } + } + + stream_write_uint32(irp->output, readerCount); + stream_write_uint32(irp->output, 0x00084dd8); + stream_write_uint32(irp->output, readerCount); + + for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++) + { + stream_write_uint32(irp->output, cur->dwCurrentState); + stream_write_uint32(irp->output, cur->dwEventState); + stream_write_uint32(irp->output, cur->cbAtr); + stream_write(irp->output, cur->rgbAtr, 32); + + stream_write_zero(irp->output, 4); + + xfree((void*) cur->szReader); + } + + sc_output_alignment(irp, 8); + + free(readerStates); + + return rv; +} + +boolean scard_async_op(IRP* irp) +{ + uint32 ioctl_code; + + /* peek ahead */ + stream_seek(irp->input, 8); + stream_read_uint32(irp->input, ioctl_code); + stream_rewind(irp->input, 12); + + switch (ioctl_code) + { + /* non-blocking events */ + case SCARD_IOCTL_ACCESS_STARTED_EVENT: + + case SCARD_IOCTL_ESTABLISH_CONTEXT: + case SCARD_IOCTL_RELEASE_CONTEXT: + case SCARD_IOCTL_IS_VALID_CONTEXT: + + return false; + break; + + /* async events */ + case SCARD_IOCTL_GET_STATUS_CHANGE: + case SCARD_IOCTL_GET_STATUS_CHANGE + 4: + + case SCARD_IOCTL_TRANSMIT: + + case SCARD_IOCTL_STATUS: + case SCARD_IOCTL_STATUS + 4: + return true; + break; + + default: + break; + } + + /* default to async */ + return true; +} + +void scard_device_control(SCARD_DEVICE* scard, IRP* irp) +{ + uint32 output_len, input_len, ioctl_code; + uint32 stream_len, result; + uint32 pos, pad_len; + uint32 irp_len; + uint32 irp_result_pos, output_len_pos, result_pos; + + stream_read_uint32(irp->input, output_len); + stream_read_uint32(irp->input, input_len); + stream_read_uint32(irp->input, ioctl_code); + + stream_seek(irp->input, 20); /* padding */ + + // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ + // stream_seek(irp->input, 4); /* 0xcccccccc */ + // stream_seek(irp->input, 4); /* rpce len */ + + /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ + stream_extend(irp->output, 2048); + + irp_result_pos = stream_get_pos(irp->output); + + stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ + + /* [MS-RPCE] 2.2.6.1 */ + stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ + stream_write_uint32(irp->output, 0xcccccccc); /* filler */ + + output_len_pos = stream_get_pos(irp->output); + stream_seek(irp->output, 4); /* size */ + + stream_write_uint32(irp->output, 0x0); /* filler */ + + result_pos = stream_get_pos(irp->output); + stream_seek(irp->output, 4); /* result */ + + /* body */ + switch (ioctl_code) + { + case SCARD_IOCTL_ESTABLISH_CONTEXT: + result = handle_EstablishContext(irp); + break; + + case SCARD_IOCTL_IS_VALID_CONTEXT: + result = handle_IsValidContext(irp); + break; + + case SCARD_IOCTL_RELEASE_CONTEXT: + result = handle_ReleaseContext(irp); + break; + + case SCARD_IOCTL_LIST_READERS: + result = handle_ListReaders(irp, 0); + break; + case SCARD_IOCTL_LIST_READERS + 4: + result = handle_ListReaders(irp, 1); + break; + + case SCARD_IOCTL_LIST_READER_GROUPS: + case SCARD_IOCTL_LIST_READER_GROUPS + 4: + /* typically not used unless list_readers fail */ + result = SCARD_F_INTERNAL_ERROR; + break; + + case SCARD_IOCTL_GET_STATUS_CHANGE: + result = handle_GetStatusChange(irp, 0); + break; + case SCARD_IOCTL_GET_STATUS_CHANGE + 4: + result = handle_GetStatusChange(irp, 1); + break; + + case SCARD_IOCTL_CANCEL: + result = handle_Cancel(irp); + break; + + case SCARD_IOCTL_CONNECT: + result = handle_Connect(irp, 0); + break; + case SCARD_IOCTL_CONNECT + 4: + result = handle_Connect(irp, 1); + break; + + case SCARD_IOCTL_RECONNECT: + result = handle_Reconnect(irp); + break; + + case SCARD_IOCTL_DISCONNECT: + result = handle_Disconnect(irp); + break; + + case SCARD_IOCTL_BEGIN_TRANSACTION: + result = handle_BeginTransaction(irp); + break; + + case SCARD_IOCTL_END_TRANSACTION: + result = handle_EndTransaction(irp); + break; + + case SCARD_IOCTL_STATE: + result = handle_State(irp); + break; + + case SCARD_IOCTL_STATUS: + result = handle_Status(irp, 0); + break; + case SCARD_IOCTL_STATUS + 4: + result = handle_Status(irp, 1); + break; + + case SCARD_IOCTL_TRANSMIT: + result = handle_Transmit(irp); + break; + + case SCARD_IOCTL_CONTROL: + result = handle_Control(irp); + break; + + case SCARD_IOCTL_GETATTRIB: + result = handle_GetAttrib(irp); + break; + + case SCARD_IOCTL_ACCESS_STARTED_EVENT: + result = handle_AccessStartedEvent(irp); + break; + + case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: + result = handle_LocateCardsByATR(irp, 0); + break; + case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: + result = handle_LocateCardsByATR(irp, 1); + break; + + default: + result = 0xc0000001; + printf("scard unknown ioctl 0x%x\n", ioctl_code); + break; + } + + /* look for NTSTATUS errors */ + if ((result & 0xc0000000) == 0xc0000000) + return scard_error(scard, irp, result); + + /* per Ludovic Rousseau, map different usage of this particular + * error code between pcsc-lite & windows */ + if (result == 0x8010001F) + result = 0x80100022; + + /* handle response packet */ + pos = stream_get_pos(irp->output); + stream_len = pos - irp_result_pos - 4; + + stream_set_pos(irp->output, output_len_pos); + stream_write_uint32(irp->output, stream_len - 24); + + stream_set_pos(irp->output, result_pos); + stream_write_uint32(irp->output, result); + + stream_set_pos(irp->output, pos); + + /* pad stream to 16 byte align */ + pad_len = stream_len % 16; + stream_write_zero(irp->output, pad_len); + pos = stream_get_pos(irp->output); + irp_len = stream_len + pad_len; + + stream_set_pos(irp->output, irp_result_pos); + stream_write_uint32(irp->output, irp_len); + stream_set_pos(irp->output, pos); + +#ifdef WITH_DEBUG_SCARD + freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); +#endif + irp->IoStatus = 0; + + irp->Complete(irp); + +} diff --git a/channels/rdpsnd/CMakeLists.txt b/channels/rdpsnd/CMakeLists.txt new file mode 100644 index 0000000..3065ac6 --- /dev/null +++ b/channels/rdpsnd/CMakeLists.txt @@ -0,0 +1,39 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPSND_SRCS + rdpsnd_main.c + rdpsnd_main.h +) + +add_library(rdpsnd ${RDPSND_SRCS}) +set_target_properties(rdpsnd PROPERTIES PREFIX "") + +target_link_libraries(rdpsnd freerdp-utils) + +install(TARGETS rdpsnd DESTINATION ${FREERDP_PLUGIN_PATH}) + +if(WITH_ALSA) + add_subdirectory(alsa) +endif() + +if(WITH_PULSEAUDIO) + add_subdirectory(pulse) +endif() + diff --git a/channels/rdpsnd/alsa/CMakeLists.txt b/channels/rdpsnd/alsa/CMakeLists.txt new file mode 100644 index 0000000..4d6deb4 --- /dev/null +++ b/channels/rdpsnd/alsa/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPSND_ALSA_SRCS + rdpsnd_alsa.c +) + +include_directories(..) +include_directories(${ALSA_INCLUDE_DIRS}) + +add_library(rdpsnd_alsa ${RDPSND_ALSA_SRCS}) +set_target_properties(rdpsnd_alsa PROPERTIES PREFIX "") + +target_link_libraries(rdpsnd_alsa freerdp-utils) +target_link_libraries(rdpsnd_alsa ${ALSA_LIBRARIES}) + +install(TARGETS rdpsnd_alsa DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpsnd/alsa/rdpsnd_alsa.c b/channels/rdpsnd/alsa/rdpsnd_alsa.c new file mode 100644 index 0000000..e7ae03d --- /dev/null +++ b/channels/rdpsnd/alsa/rdpsnd_alsa.c @@ -0,0 +1,360 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Output Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpsnd_main.h" + +typedef struct rdpsnd_alsa_plugin rdpsndAlsaPlugin; +struct rdpsnd_alsa_plugin +{ + rdpsndDevicePlugin device; + + char* device_name; + snd_pcm_t* out_handle; + uint32 source_rate; + uint32 actual_rate; + snd_pcm_format_t format; + uint32 source_channels; + uint32 actual_channels; + int bytes_per_channel; + int wformat; + int block_size; + int latency; + ADPCM adpcm; +}; + +static void rdpsnd_alsa_set_params(rdpsndAlsaPlugin* alsa) +{ + snd_pcm_hw_params_t* hw_params; + snd_pcm_sw_params_t* sw_params; + int error; + snd_pcm_uframes_t frames; + snd_pcm_uframes_t start_threshold; + + snd_pcm_drop(alsa->out_handle); + + error = snd_pcm_hw_params_malloc(&hw_params); + if (error < 0) + { + DEBUG_WARN("snd_pcm_hw_params_malloc failed"); + return; + } + snd_pcm_hw_params_any(alsa->out_handle, hw_params); + snd_pcm_hw_params_set_access(alsa->out_handle, hw_params, + SND_PCM_ACCESS_RW_INTERLEAVED); + snd_pcm_hw_params_set_format(alsa->out_handle, hw_params, + alsa->format); + snd_pcm_hw_params_set_rate_near(alsa->out_handle, hw_params, + &alsa->actual_rate, NULL); + snd_pcm_hw_params_set_channels_near(alsa->out_handle, hw_params, + &alsa->actual_channels); + if (alsa->latency < 0) + frames = alsa->actual_rate * 4; /* Default to 4-second buffer */ + else + frames = alsa->latency * alsa->actual_rate * 2 / 1000; /* Double of the latency */ + if (frames < alsa->actual_rate / 2) + frames = alsa->actual_rate / 2; /* Minimum 0.5-second buffer */ + snd_pcm_hw_params_set_buffer_size_near(alsa->out_handle, hw_params, + &frames); + snd_pcm_hw_params(alsa->out_handle, hw_params); + snd_pcm_hw_params_free(hw_params); + + error = snd_pcm_sw_params_malloc(&sw_params); + if (error < 0) + { + DEBUG_WARN("snd_pcm_sw_params_malloc failed"); + return; + } + snd_pcm_sw_params_current(alsa->out_handle, sw_params); + if (alsa->latency == 0) + start_threshold = 0; + else + start_threshold = frames / 2; + snd_pcm_sw_params_set_start_threshold(alsa->out_handle, sw_params, start_threshold); + snd_pcm_sw_params(alsa->out_handle, sw_params); + snd_pcm_sw_params_free(sw_params); + + snd_pcm_prepare(alsa->out_handle); + + DEBUG_SVC("hardware buffer %d frames, playback buffer %.2g seconds", + (int)frames, (double)frames / 2.0 / (double)alsa->actual_rate); + if ((alsa->actual_rate != alsa->source_rate) || + (alsa->actual_channels != alsa->source_channels)) + { + DEBUG_SVC("actual rate %d / channel %d is different from source rate %d / channel %d, resampling required.", + alsa->actual_rate, alsa->actual_channels, alsa->source_rate, alsa->source_channels); + } +} + +static void rdpsnd_alsa_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + + if (format != NULL) + { + alsa->source_rate = format->nSamplesPerSec; + alsa->actual_rate = format->nSamplesPerSec; + alsa->source_channels = format->nChannels; + alsa->actual_channels = format->nChannels; + switch (format->wFormatTag) + { + case 1: /* PCM */ + switch (format->wBitsPerSample) + { + case 8: + alsa->format = SND_PCM_FORMAT_S8; + alsa->bytes_per_channel = 1; + break; + case 16: + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->bytes_per_channel = 2; + break; + } + break; + + case 0x11: /* IMA ADPCM */ + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->bytes_per_channel = 2; + break; + } + alsa->wformat = format->wFormatTag; + alsa->block_size = format->nBlockAlign; + } + + alsa->latency = latency; + + rdpsnd_alsa_set_params(alsa); +} + +static void rdpsnd_alsa_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + int error; + + if (alsa->out_handle != 0) + return; + + DEBUG_SVC("opening"); + + error = snd_pcm_open(&alsa->out_handle, alsa->device_name, + SND_PCM_STREAM_PLAYBACK, 0); + if (error < 0) + { + DEBUG_WARN("snd_pcm_open failed"); + } + else + { + memset(&alsa->adpcm, 0, sizeof(ADPCM)); + rdpsnd_alsa_set_format(device, format, latency); + } +} + +static void rdpsnd_alsa_close(rdpsndDevicePlugin* device) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + + if (alsa->out_handle != 0) + { + DEBUG_SVC("close"); + snd_pcm_drain(alsa->out_handle); + snd_pcm_close(alsa->out_handle); + alsa->out_handle = 0; + } +} + +static void rdpsnd_alsa_free(rdpsndDevicePlugin* device) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + + rdpsnd_alsa_close(device); + xfree(alsa->device_name); + xfree(alsa); +} + +static boolean rdpsnd_alsa_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format) +{ + switch (format->wFormatTag) + { + case 1: /* PCM */ + if (format->cbSize == 0 && + format->nSamplesPerSec <= 48000 && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + + case 0x11: /* IMA ADPCM */ + if (format->nSamplesPerSec <= 48000 && + format->wBitsPerSample == 4 && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + } + return false; +} + +static void rdpsnd_alsa_set_volume(rdpsndDevicePlugin* device, uint32 value) +{ +} + +static void rdpsnd_alsa_play(rdpsndDevicePlugin* device, uint8* data, int size) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + uint8* decoded_data; + int decoded_size; + uint8* src; + uint8* resampled_data; + int len; + int error; + int frames; + int rbytes_per_frame; + int sbytes_per_frame; + uint8* pindex; + uint8* end; + + if (alsa->out_handle == 0) + return; + + if (alsa->wformat == 0x11) + { + decoded_data = dsp_decode_ima_adpcm(&alsa->adpcm, + data, size, alsa->source_channels, alsa->block_size, &decoded_size); + size = decoded_size; + src = decoded_data; + } + else + { + decoded_data = NULL; + src = data; + } + + sbytes_per_frame = alsa->source_channels * alsa->bytes_per_channel; + rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel; + if ((size % sbytes_per_frame) != 0) + { + DEBUG_WARN("error len mod"); + return; + } + + if ((alsa->source_rate == alsa->actual_rate) && + (alsa->source_channels == alsa->actual_channels)) + { + resampled_data = NULL; + } + else + { + resampled_data = dsp_resample(src, alsa->bytes_per_channel, + alsa->source_channels, alsa->source_rate, size / sbytes_per_frame, + alsa->actual_channels, alsa->actual_rate, &frames); + DEBUG_SVC("resampled %d frames at %d to %d frames at %d", + size / sbytes_per_frame, alsa->source_rate, frames, alsa->actual_rate); + size = frames * rbytes_per_frame; + src = resampled_data; + } + + pindex = src; + end = pindex + size; + while (pindex < end) + { + len = end - pindex; + frames = len / rbytes_per_frame; + error = snd_pcm_writei(alsa->out_handle, pindex, frames); + if (error == -EPIPE) + { + snd_pcm_recover(alsa->out_handle, error, 0); + error = 0; + } + else if (error < 0) + { + DEBUG_WARN("error %d", error); + snd_pcm_close(alsa->out_handle); + alsa->out_handle = 0; + rdpsnd_alsa_open(device, NULL, alsa->latency); + break; + } + pindex += error * rbytes_per_frame; + } + + if (resampled_data) + xfree(resampled_data); + if (decoded_data) + xfree(decoded_data); +} + +static void rdpsnd_alsa_start(rdpsndDevicePlugin* device) +{ + rdpsndAlsaPlugin* alsa = (rdpsndAlsaPlugin*)device; + + if (alsa->out_handle == 0) + return; + + snd_pcm_start(alsa->out_handle); +} + +int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +{ + rdpsndAlsaPlugin* alsa; + RDP_PLUGIN_DATA* data; + + alsa = xnew(rdpsndAlsaPlugin); + + alsa->device.Open = rdpsnd_alsa_open; + alsa->device.FormatSupported = rdpsnd_alsa_format_supported; + alsa->device.SetFormat = rdpsnd_alsa_set_format; + alsa->device.SetVolume = rdpsnd_alsa_set_volume; + alsa->device.Play = rdpsnd_alsa_play; + alsa->device.Start = rdpsnd_alsa_start; + alsa->device.Close = rdpsnd_alsa_close; + alsa->device.Free = rdpsnd_alsa_free; + + data = pEntryPoints->plugin_data; + if (data && strcmp((char*)data->data[0], "alsa") == 0) + { + alsa->device_name = xstrdup((char*)data->data[1]); + } + if (alsa->device_name == NULL) + { + alsa->device_name = xstrdup("default"); + } + alsa->out_handle = 0; + alsa->source_rate = 22050; + alsa->actual_rate = 22050; + alsa->format = SND_PCM_FORMAT_S16_LE; + alsa->source_channels = 2; + alsa->actual_channels = 2; + alsa->bytes_per_channel = 2; + + pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)alsa); + + return 0; +} + diff --git a/channels/rdpsnd/pulse/CMakeLists.txt b/channels/rdpsnd/pulse/CMakeLists.txt new file mode 100644 index 0000000..4460daf --- /dev/null +++ b/channels/rdpsnd/pulse/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(RDPSND_PULSE_SRCS + rdpsnd_pulse.c +) + +include_directories(..) +include_directories(${PULSE_INCLUDE_DIRS}) + +add_library(rdpsnd_pulse ${RDPSND_PULSE_SRCS}) +set_target_properties(rdpsnd_pulse PROPERTIES PREFIX "") + +target_link_libraries(rdpsnd_pulse freerdp-utils) +target_link_libraries(rdpsnd_pulse ${PULSE_LIBRARIES}) + +install(TARGETS rdpsnd_pulse DESTINATION ${FREERDP_PLUGIN_PATH}) diff --git a/channels/rdpsnd/pulse/rdpsnd_pulse.c b/channels/rdpsnd/pulse/rdpsnd_pulse.c new file mode 100644 index 0000000..1a331f0 --- /dev/null +++ b/channels/rdpsnd/pulse/rdpsnd_pulse.c @@ -0,0 +1,509 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Output Virtual Channel + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpsnd_main.h" + +typedef struct rdpsnd_pulse_plugin rdpsndPulsePlugin; +struct rdpsnd_pulse_plugin +{ + rdpsndDevicePlugin device; + + char* device_name; + pa_threaded_mainloop *mainloop; + pa_context *context; + pa_sample_spec sample_spec; + pa_stream *stream; + int format; + int block_size; + int latency; + ADPCM adpcm; +}; + +static void rdpsnd_pulse_context_state_callback(pa_context* context, void* userdata) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + pa_context_state_t state; + + state = pa_context_get_state(context); + switch (state) + { + case PA_CONTEXT_READY: + DEBUG_SVC("PA_CONTEXT_READY"); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + case PA_CONTEXT_FAILED: + case PA_CONTEXT_TERMINATED: + DEBUG_SVC("PA_CONTEXT_FAILED/PA_CONTEXT_TERMINATED %d", (int)state); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + default: + DEBUG_SVC("state %d", (int)state); + break; + } +} + +static boolean rdpsnd_pulse_connect(rdpsndDevicePlugin* device) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + pa_context_state_t state; + + if (!pulse->context) + return false; + + if (pa_context_connect(pulse->context, NULL, 0, NULL)) + { + DEBUG_WARN("pa_context_connect failed (%d)", pa_context_errno(pulse->context)); + return false; + } + pa_threaded_mainloop_lock(pulse->mainloop); + if (pa_threaded_mainloop_start(pulse->mainloop) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_threaded_mainloop_start failed (%d)", pa_context_errno(pulse->context)); + return false; + } + for (;;) + { + state = pa_context_get_state(pulse->context); + if (state == PA_CONTEXT_READY) + break; + if (!PA_CONTEXT_IS_GOOD(state)) + { + DEBUG_WARN("bad context state (%d)", pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_CONTEXT_READY) + { + DEBUG_SVC("connected"); + return true; + } + else + { + pa_context_disconnect(pulse->context); + return false; + } +} + +static void rdpsnd_pulse_stream_success_callback(pa_stream* stream, int success, void* userdata) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + pa_threaded_mainloop_signal(pulse->mainloop, 0); +} + +static void rdpsnd_pulse_wait_for_operation(rdpsndPulsePlugin* pulse, pa_operation* operation) +{ + if (operation == NULL) + return; + while (pa_operation_get_state(operation) == PA_OPERATION_RUNNING) + { + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_operation_unref(operation); +} + +static void rdpsnd_pulse_stream_state_callback(pa_stream* stream, void* userdata) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + pa_stream_state_t state; + + state = pa_stream_get_state(stream); + switch (state) + { + case PA_STREAM_READY: + DEBUG_SVC("PA_STREAM_READY"); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + case PA_STREAM_FAILED: + case PA_STREAM_TERMINATED: + DEBUG_SVC("state %d", (int)state); + pa_threaded_mainloop_signal(pulse->mainloop, 0); + break; + + default: + DEBUG_SVC("state %d", (int)state); + break; + } +} + +static void rdpsnd_pulse_stream_request_callback(pa_stream* stream, size_t length, void* userdata) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)userdata; + + pa_threaded_mainloop_signal(pulse->mainloop, 0); +} + +static void rdpsnd_pulse_close(rdpsndDevicePlugin* device) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + + if (!pulse->context || !pulse->stream) + return; + + pa_threaded_mainloop_lock(pulse->mainloop); + rdpsnd_pulse_wait_for_operation(pulse, + pa_stream_drain(pulse->stream, rdpsnd_pulse_stream_success_callback, pulse)); + pa_stream_disconnect(pulse->stream); + pa_stream_unref(pulse->stream); + pulse->stream = NULL; + pa_threaded_mainloop_unlock(pulse->mainloop); +} + +static void rdpsnd_pulse_set_format_spec(rdpsndPulsePlugin* pulse, rdpsndFormat* format) +{ + pa_sample_spec sample_spec = { 0 }; + + if (!pulse->context) + return; + + sample_spec.rate = format->nSamplesPerSec; + sample_spec.channels = format->nChannels; + switch (format->wFormatTag) + { + case 1: /* PCM */ + switch (format->wBitsPerSample) + { + case 8: + sample_spec.format = PA_SAMPLE_U8; + break; + case 16: + sample_spec.format = PA_SAMPLE_S16LE; + break; + } + break; + + case 6: /* A-LAW */ + sample_spec.format = PA_SAMPLE_ALAW; + break; + + case 7: /* U-LAW */ + sample_spec.format = PA_SAMPLE_ULAW; + break; + + case 0x11: /* IMA ADPCM */ + sample_spec.format = PA_SAMPLE_S16LE; + break; + } + + pulse->sample_spec = sample_spec; + pulse->format = format->wFormatTag; + pulse->block_size = format->nBlockAlign; +} + +static void rdpsnd_pulse_open(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + pa_stream_state_t state; + pa_stream_flags_t flags; + pa_buffer_attr buffer_attr = { 0 }; + char ss[PA_SAMPLE_SPEC_SNPRINT_MAX]; + + if (!pulse->context || pulse->stream) + { + DEBUG_WARN("pulse stream has been created."); + return; + } + + rdpsnd_pulse_set_format_spec(pulse, format); + pulse->latency = latency; + + if (pa_sample_spec_valid(&pulse->sample_spec) == 0) + { + pa_sample_spec_snprint(ss, sizeof(ss), &pulse->sample_spec); + DEBUG_WARN("Invalid sample spec %s", ss); + return; + } + + pa_threaded_mainloop_lock(pulse->mainloop); + pulse->stream = pa_stream_new(pulse->context, "freerdp", + &pulse->sample_spec, NULL); + if (!pulse->stream) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_stream_new failed (%d)", + pa_context_errno(pulse->context)); + return; + } + + /* install essential callbacks */ + pa_stream_set_state_callback(pulse->stream, + rdpsnd_pulse_stream_state_callback, pulse); + pa_stream_set_write_callback(pulse->stream, + rdpsnd_pulse_stream_request_callback, pulse); + + flags = PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE; + if (pulse->latency > 0) + { + buffer_attr.maxlength = pa_usec_to_bytes(pulse->latency * 2 * 1000, &pulse->sample_spec); + buffer_attr.tlength = pa_usec_to_bytes(pulse->latency * 1000, &pulse->sample_spec); + buffer_attr.prebuf = (uint32_t) -1; + buffer_attr.minreq = (uint32_t) -1; + buffer_attr.fragsize = (uint32_t) -1; + flags |= PA_STREAM_ADJUST_LATENCY; + } + if (pa_stream_connect_playback(pulse->stream, + pulse->device_name, pulse->latency > 0 ? &buffer_attr : NULL, flags, NULL, NULL) < 0) + { + pa_threaded_mainloop_unlock(pulse->mainloop); + DEBUG_WARN("pa_stream_connect_playback failed (%d)", + pa_context_errno(pulse->context)); + return; + } + + for (;;) + { + state = pa_stream_get_state(pulse->stream); + if (state == PA_STREAM_READY) + break; + if (!PA_STREAM_IS_GOOD(state)) + { + DEBUG_WARN("bad stream state (%d)", + pa_context_errno(pulse->context)); + break; + } + pa_threaded_mainloop_wait(pulse->mainloop); + } + pa_threaded_mainloop_unlock(pulse->mainloop); + if (state == PA_STREAM_READY) + { + memset(&pulse->adpcm, 0, sizeof(ADPCM)); + DEBUG_SVC("connected"); + } + else + { + rdpsnd_pulse_close(device); + } +} + +static void rdpsnd_pulse_free(rdpsndDevicePlugin* device) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + + if (!pulse) + return; + rdpsnd_pulse_close(device); + if (pulse->mainloop) + { + pa_threaded_mainloop_stop(pulse->mainloop); + } + if (pulse->context) + { + pa_context_disconnect(pulse->context); + pa_context_unref(pulse->context); + pulse->context = NULL; + } + if (pulse->mainloop) + { + pa_threaded_mainloop_free(pulse->mainloop); + pulse->mainloop = NULL; + } + xfree(pulse->device_name); + xfree(pulse); +} + +static boolean rdpsnd_pulse_format_supported(rdpsndDevicePlugin* device, rdpsndFormat* format) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + + if (!pulse->context) + return false; + + switch (format->wFormatTag) + { + case 1: /* PCM */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 8 || format->wBitsPerSample == 16) && + (format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX)) + { + return true; + } + break; + + case 6: /* A-LAW */ + case 7: /* U-LAW */ + if (format->cbSize == 0 && + (format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 8) && + (format->nChannels >= 1 && format->nChannels <= PA_CHANNELS_MAX)) + { + return true; + } + break; + + case 0x11: /* IMA ADPCM */ + if ((format->nSamplesPerSec <= PA_RATE_MAX) && + (format->wBitsPerSample == 4) && + (format->nChannels == 1 || format->nChannels == 2)) + { + return true; + } + break; + } + return false; +} + +static void rdpsnd_pulse_set_format(rdpsndDevicePlugin* device, rdpsndFormat* format, int latency) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + + if (pulse->stream) + { + pa_threaded_mainloop_lock(pulse->mainloop); + pa_stream_disconnect(pulse->stream); + pa_stream_unref(pulse->stream); + pulse->stream = NULL; + pa_threaded_mainloop_unlock(pulse->mainloop); + } + rdpsnd_pulse_open(device, format, latency); +} + +static void rdpsnd_pulse_set_volume(rdpsndDevicePlugin* device, uint32 value) +{ +} + +static void rdpsnd_pulse_play(rdpsndDevicePlugin* device, uint8* data, int size) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + int len; + int ret; + uint8* decoded_data; + uint8* src; + int decoded_size; + + if (!pulse->stream) + return; + + if (pulse->format == 0x11) + { + decoded_data = dsp_decode_ima_adpcm(&pulse->adpcm, + data, size, pulse->sample_spec.channels, pulse->block_size, &decoded_size); + size = decoded_size; + src = decoded_data; + } + else + { + decoded_data = NULL; + src = data; + } + + pa_threaded_mainloop_lock(pulse->mainloop); + while (size > 0) + { + while ((len = pa_stream_writable_size(pulse->stream)) == 0) + { + pa_threaded_mainloop_wait(pulse->mainloop); + } + if (len < 0) + break; + if (len > size) + len = size; + ret = pa_stream_write(pulse->stream, src, len, NULL, 0LL, PA_SEEK_RELATIVE); + if (ret < 0) + { + DEBUG_WARN("pa_stream_write failed (%d)", + pa_context_errno(pulse->context)); + break; + } + src += len; + size -= len; + } + pa_threaded_mainloop_unlock(pulse->mainloop); + + if (decoded_data) + xfree(decoded_data); +} + +static void rdpsnd_pulse_start(rdpsndDevicePlugin* device) +{ + rdpsndPulsePlugin* pulse = (rdpsndPulsePlugin*)device; + + if (!pulse->stream) + return; + + pa_stream_trigger(pulse->stream, NULL, NULL); +} + +int FreeRDPRdpsndDeviceEntry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints) +{ + rdpsndPulsePlugin* pulse; + RDP_PLUGIN_DATA* data; + + pulse = xnew(rdpsndPulsePlugin); + + pulse->device.Open = rdpsnd_pulse_open; + pulse->device.FormatSupported = rdpsnd_pulse_format_supported; + pulse->device.SetFormat = rdpsnd_pulse_set_format; + pulse->device.SetVolume = rdpsnd_pulse_set_volume; + pulse->device.Play = rdpsnd_pulse_play; + pulse->device.Start = rdpsnd_pulse_start; + pulse->device.Close = rdpsnd_pulse_close; + pulse->device.Free = rdpsnd_pulse_free; + + data = pEntryPoints->plugin_data; + if (data && strcmp((char*)data->data[0], "pulse") == 0) + { + if(strlen((char*)data->data[1]) > 0) + pulse->device_name = xstrdup((char*)data->data[1]); + else + pulse->device_name = NULL; + } + + pulse->mainloop = pa_threaded_mainloop_new(); + if (!pulse->mainloop) + { + DEBUG_WARN("pa_threaded_mainloop_new failed"); + rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); + return 1; + } + pulse->context = pa_context_new(pa_threaded_mainloop_get_api(pulse->mainloop), "freerdp"); + if (!pulse->context) + { + DEBUG_WARN("pa_context_new failed"); + rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); + return 1; + } + pa_context_set_state_callback(pulse->context, rdpsnd_pulse_context_state_callback, pulse); + if (!rdpsnd_pulse_connect((rdpsndDevicePlugin*)pulse)) + { + DEBUG_WARN("rdpsnd_pulse_connect failed"); + rdpsnd_pulse_free((rdpsndDevicePlugin*)pulse); + return 1; + } + + pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*)pulse); + + return 0; +} + diff --git a/channels/rdpsnd/rdpsnd_main.c b/channels/rdpsnd/rdpsnd_main.c new file mode 100644 index 0000000..48b5455 --- /dev/null +++ b/channels/rdpsnd/rdpsnd_main.c @@ -0,0 +1,561 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Output Virtual Channel + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdpsnd_main.h" + +#define SNDC_CLOSE 1 +#define SNDC_WAVE 2 +#define SNDC_SETVOLUME 3 +#define SNDC_SETPITCH 4 +#define SNDC_WAVECONFIRM 5 +#define SNDC_TRAINING 6 +#define SNDC_FORMATS 7 +#define SNDC_CRYPTKEY 8 +#define SNDC_WAVEENCRYPT 9 +#define SNDC_UDPWAVE 10 +#define SNDC_UDPWAVELAST 11 +#define SNDC_QUALITYMODE 12 + +#define TSSNDCAPS_ALIVE 1 +#define TSSNDCAPS_VOLUME 2 +#define TSSNDCAPS_PITCH 4 + +#define DYNAMIC_QUALITY 0x0000 +#define MEDIUM_QUALITY 0x0001 +#define HIGH_QUALITY 0x0002 + +struct rdpsnd_plugin +{ + rdpSvcPlugin plugin; + + LIST* data_out_list; + + uint8 cBlockNo; + rdpsndFormat* supported_formats; + int n_supported_formats; + int current_format; + + boolean expectingWave; + uint8 waveData[4]; + uint16 waveDataSize; + uint32 wTimeStamp; /* server timestamp */ + uint32 wave_timestamp; /* client timestamp */ + + boolean is_open; + uint32 close_timestamp; + + uint16 fixed_format; + uint16 fixed_channel; + uint32 fixed_rate; + int latency; + + /* Device plugin */ + rdpsndDevicePlugin* device; +}; + +struct data_out_item +{ + STREAM* data_out; + uint32 out_timestamp; +}; + +/* get time in milliseconds */ +static uint32 get_mstime(void) +{ + struct timeval tp; + + gettimeofday(&tp, 0); + return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); +} + +/* process the linked list of data that has queued to be sent */ +static void rdpsnd_process_interval(rdpSvcPlugin* plugin) +{ + rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; + struct data_out_item* item; + uint32 cur_time; + + while (rdpsnd->data_out_list->head) + { + item = (struct data_out_item*)rdpsnd->data_out_list->head->data; + cur_time = get_mstime(); + if (cur_time <= item->out_timestamp) + break; + + item = (struct data_out_item*)list_dequeue(rdpsnd->data_out_list); + svc_plugin_send(plugin, item->data_out); + xfree(item); + + DEBUG_SVC("processed data_out"); + } + + if (rdpsnd->is_open && rdpsnd->close_timestamp > 0) + { + cur_time = get_mstime(); + if (cur_time > rdpsnd->close_timestamp) + { + if (rdpsnd->device) + IFCALL(rdpsnd->device->Close, rdpsnd->device); + rdpsnd->is_open = false; + rdpsnd->close_timestamp = 0; + + DEBUG_SVC("processed close"); + } + } + + if (rdpsnd->data_out_list->head == NULL && !rdpsnd->is_open) + { + rdpsnd->plugin.interval_ms = 0; + } +} + +static void rdpsnd_free_supported_formats(rdpsndPlugin* rdpsnd) +{ + uint16 i; + + for (i = 0; i < rdpsnd->n_supported_formats; i++) + xfree(rdpsnd->supported_formats[i].data); + xfree(rdpsnd->supported_formats); + + rdpsnd->supported_formats = NULL; + rdpsnd->n_supported_formats = 0; +} + +/* receives a list of server supported formats and returns a list + of client supported formats */ +static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in) +{ + uint16 wNumberOfFormats; + uint16 nFormat; + uint16 wVersion; + STREAM* data_out; + rdpsndFormat* out_formats; + uint16 n_out_formats; + rdpsndFormat* format; + uint8* format_mark; + uint8* data_mark; + int pos; + + rdpsnd_free_supported_formats(rdpsnd); + + stream_seek_uint32(data_in); /* dwFlags */ + stream_seek_uint32(data_in); /* dwVolume */ + stream_seek_uint32(data_in); /* dwPitch */ + stream_seek_uint16(data_in); /* wDGramPort */ + stream_read_uint16(data_in, wNumberOfFormats); + stream_read_uint8(data_in, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ + stream_read_uint16(data_in, wVersion); + stream_seek_uint8(data_in); /* bPad */ + + DEBUG_SVC("wNumberOfFormats %d wVersion %d", wNumberOfFormats, wVersion); + if (wNumberOfFormats < 1) + { + DEBUG_WARN("wNumberOfFormats is 0"); + return; + } + + out_formats = (rdpsndFormat*)xzalloc(wNumberOfFormats * sizeof(rdpsndFormat)); + n_out_formats = 0; + + data_out = stream_new(24); + stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */ + stream_write_uint8(data_out, 0); /* bPad */ + stream_seek_uint16(data_out); /* BodySize */ + stream_write_uint32(data_out, TSSNDCAPS_ALIVE); /* dwFlags */ + stream_write_uint32(data_out, 0); /* dwVolume */ + stream_write_uint32(data_out, 0); /* dwPitch */ + stream_write_uint16_be(data_out, 0); /* wDGramPort */ + stream_seek_uint16(data_out); /* wNumberOfFormats */ + stream_write_uint8(data_out, 0); /* cLastBlockConfirmed */ + stream_write_uint16(data_out, 6); /* wVersion */ + stream_write_uint8(data_out, 0); /* bPad */ + + for (nFormat = 0; nFormat < wNumberOfFormats; nFormat++) + { + stream_get_mark(data_in, format_mark); + format = &out_formats[n_out_formats]; + stream_read_uint16(data_in, format->wFormatTag); + stream_read_uint16(data_in, format->nChannels); + stream_read_uint32(data_in, format->nSamplesPerSec); + stream_seek_uint32(data_in); /* nAvgBytesPerSec */ + stream_read_uint16(data_in, format->nBlockAlign); + stream_read_uint16(data_in, format->wBitsPerSample); + stream_read_uint16(data_in, format->cbSize); + stream_get_mark(data_in, data_mark); + stream_seek(data_in, format->cbSize); + format->data = NULL; + + DEBUG_SVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d nBlockAlign=%d wBitsPerSample=%d", + format->wFormatTag, format->nChannels, format->nSamplesPerSec, + format->nBlockAlign, format->wBitsPerSample); + + if (rdpsnd->fixed_format > 0 && rdpsnd->fixed_format != format->wFormatTag) + continue; + if (rdpsnd->fixed_channel > 0 && rdpsnd->fixed_channel != format->nChannels) + continue; + if (rdpsnd->fixed_rate > 0 && rdpsnd->fixed_rate != format->nSamplesPerSec) + continue; + if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, format)) + { + DEBUG_SVC("format supported."); + + stream_check_size(data_out, 18 + format->cbSize); + stream_write(data_out, format_mark, 18 + format->cbSize); + if (format->cbSize > 0) + { + format->data = xmalloc(format->cbSize); + memcpy(format->data, data_mark, format->cbSize); + } + n_out_formats++; + } + } + + rdpsnd->n_supported_formats = n_out_formats; + if (n_out_formats > 0) + { + rdpsnd->supported_formats = out_formats; + } + else + { + xfree(out_formats); + DEBUG_WARN("no formats supported"); + } + + pos = stream_get_pos(data_out); + stream_set_pos(data_out, 2); + stream_write_uint16(data_out, pos - 4); + stream_set_pos(data_out, 18); + stream_write_uint16(data_out, n_out_formats); + stream_set_pos(data_out, pos); + + svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out); + + if (wVersion >= 6) + { + data_out = stream_new(8); + stream_write_uint8(data_out, SNDC_QUALITYMODE); /* msgType */ + stream_write_uint8(data_out, 0); /* bPad */ + stream_write_uint16(data_out, 4); /* BodySize */ + stream_write_uint16(data_out, HIGH_QUALITY); /* wQualityMode */ + stream_write_uint16(data_out, 0); /* Reserved */ + + svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out); + } +} + +/* server is getting a feel of the round trip time */ +static void rdpsnd_process_message_training(rdpsndPlugin* rdpsnd, STREAM* data_in) +{ + uint16 wTimeStamp; + uint16 wPackSize; + STREAM* data_out; + + stream_read_uint16(data_in, wTimeStamp); + stream_read_uint16(data_in, wPackSize); + + data_out = stream_new(8); + stream_write_uint8(data_out, SNDC_TRAINING); /* msgType */ + stream_write_uint8(data_out, 0); /* bPad */ + stream_write_uint16(data_out, 4); /* BodySize */ + stream_write_uint16(data_out, wTimeStamp); + stream_write_uint16(data_out, wPackSize); + + svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out); +} + +static void rdpsnd_process_message_wave_info(rdpsndPlugin* rdpsnd, STREAM* data_in, uint16 BodySize) +{ + uint16 wFormatNo; + + stream_read_uint16(data_in, rdpsnd->wTimeStamp); + stream_read_uint16(data_in, wFormatNo); + stream_read_uint8(data_in, rdpsnd->cBlockNo); + stream_seek(data_in, 3); /* bPad */ + stream_read(data_in, rdpsnd->waveData, 4); + rdpsnd->waveDataSize = BodySize - 8; + rdpsnd->wave_timestamp = get_mstime(); + rdpsnd->expectingWave = true; + + DEBUG_SVC("waveDataSize %d wFormatNo %d", rdpsnd->waveDataSize, wFormatNo); + + rdpsnd->close_timestamp = 0; + if (!rdpsnd->is_open) + { + rdpsnd->current_format = wFormatNo; + rdpsnd->is_open = true; + if (rdpsnd->device) + IFCALL(rdpsnd->device->Open, rdpsnd->device, &rdpsnd->supported_formats[wFormatNo], + rdpsnd->latency); + } + else if (wFormatNo != rdpsnd->current_format) + { + rdpsnd->current_format = wFormatNo; + if (rdpsnd->device) + IFCALL(rdpsnd->device->SetFormat, rdpsnd->device, &rdpsnd->supported_formats[wFormatNo], + rdpsnd->latency); + } +} + +/* header is not removed from data in this function */ +static void rdpsnd_process_message_wave(rdpsndPlugin* rdpsnd, STREAM* data_in) +{ + uint16 wTimeStamp; + uint32 delay_ms; + uint32 process_ms; + struct data_out_item* item; + + rdpsnd->expectingWave = 0; + memcpy(stream_get_head(data_in), rdpsnd->waveData, 4); + if (stream_get_size(data_in) != rdpsnd->waveDataSize) + { + DEBUG_WARN("size error"); + return; + } + if (rdpsnd->device) + IFCALL(rdpsnd->device->Play, rdpsnd->device, stream_get_head(data_in), stream_get_size(data_in)); + + process_ms = get_mstime() - rdpsnd->wave_timestamp; + delay_ms = 250; + wTimeStamp = rdpsnd->wTimeStamp + delay_ms; + + DEBUG_SVC("data_size %d delay_ms %u process_ms %u", + stream_get_size(data_in), delay_ms, process_ms); + + item = xnew(struct data_out_item); + item->data_out = stream_new(8); + stream_write_uint8(item->data_out, SNDC_WAVECONFIRM); + stream_write_uint8(item->data_out, 0); + stream_write_uint16(item->data_out, 4); + stream_write_uint16(item->data_out, wTimeStamp); + stream_write_uint8(item->data_out, rdpsnd->cBlockNo); /* cConfirmedBlockNo */ + stream_write_uint8(item->data_out, 0); /* bPad */ + item->out_timestamp = rdpsnd->wave_timestamp + delay_ms; + + list_enqueue(rdpsnd->data_out_list, item); + rdpsnd->plugin.interval_ms = 10; +} + +static void rdpsnd_process_message_close(rdpsndPlugin* rdpsnd) +{ + DEBUG_SVC("server closes."); + if (rdpsnd->device) + IFCALL(rdpsnd->device->Start, rdpsnd->device); + rdpsnd->close_timestamp = get_mstime() + 2000; + rdpsnd->plugin.interval_ms = 10; +} + +static void rdpsnd_process_message_setvolume(rdpsndPlugin* rdpsnd, STREAM* data_in) +{ + uint32 dwVolume; + + stream_read_uint32(data_in, dwVolume); + DEBUG_SVC("dwVolume 0x%X", dwVolume); + if (rdpsnd->device) + IFCALL(rdpsnd->device->SetVolume, rdpsnd->device, dwVolume); +} + +static void rdpsnd_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) +{ + rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; + uint8 msgType; + uint16 BodySize; + + if (rdpsnd->expectingWave) + { + rdpsnd_process_message_wave(rdpsnd, data_in); + return; + } + + stream_read_uint8(data_in, msgType); /* msgType */ + stream_seek_uint8(data_in); /* bPad */ + stream_read_uint16(data_in, BodySize); + + DEBUG_SVC("msgType %d BodySize %d", msgType, BodySize); + + switch (msgType) + { + case SNDC_FORMATS: + rdpsnd_process_message_formats(rdpsnd, data_in); + break; + case SNDC_TRAINING: + rdpsnd_process_message_training(rdpsnd, data_in); + break; + case SNDC_WAVE: + rdpsnd_process_message_wave_info(rdpsnd, data_in, BodySize); + break; + case SNDC_CLOSE: + rdpsnd_process_message_close(rdpsnd); + break; + case SNDC_SETVOLUME: + rdpsnd_process_message_setvolume(rdpsnd, data_in); + break; + default: + DEBUG_WARN("unknown msgType %d", msgType); + break; + } +} + +static void rdpsnd_register_device_plugin(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device) +{ + if (rdpsnd->device) + { + DEBUG_WARN("existing device, abort."); + return; + } + rdpsnd->device = device; +} + +static boolean rdpsnd_load_device_plugin(rdpsndPlugin* rdpsnd, const char* name, RDP_PLUGIN_DATA* data) +{ + FREERDP_RDPSND_DEVICE_ENTRY_POINTS entryPoints; + PFREERDP_RDPSND_DEVICE_ENTRY entry; + char* fullname; + + if (strrchr(name, '.') != NULL) + entry = (PFREERDP_RDPSND_DEVICE_ENTRY)freerdp_load_plugin(name, RDPSND_DEVICE_EXPORT_FUNC_NAME); + else + { + fullname = xzalloc(strlen(name) + 8); + strcpy(fullname, "rdpsnd_"); + strcat(fullname, name); + entry = (PFREERDP_RDPSND_DEVICE_ENTRY)freerdp_load_plugin(fullname, RDPSND_DEVICE_EXPORT_FUNC_NAME); + xfree(fullname); + } + if (entry == NULL) + { + return false; + } + + entryPoints.rdpsnd = rdpsnd; + entryPoints.pRegisterRdpsndDevice = rdpsnd_register_device_plugin; + entryPoints.plugin_data = data; + if (entry(&entryPoints) != 0) + { + DEBUG_WARN("%s entry returns error.", name); + return false; + } + return true; +} + +static void rdpsnd_process_plugin_data(rdpsndPlugin* rdpsnd, RDP_PLUGIN_DATA* data) +{ + if (strcmp((char*)data->data[0], "format") == 0) + { + rdpsnd->fixed_format = atoi(data->data[1]); + } + else if (strcmp((char*)data->data[0], "rate") == 0) + { + rdpsnd->fixed_rate = atoi(data->data[1]); + } + else if (strcmp((char*)data->data[0], "channel") == 0) + { + rdpsnd->fixed_channel = atoi(data->data[1]); + } + else if (strcmp((char*)data->data[0], "latency") == 0) + { + rdpsnd->latency = atoi(data->data[1]); + } + else + { + rdpsnd_load_device_plugin(rdpsnd, (char*)data->data[0], data); + } +} + +static void rdpsnd_process_connect(rdpSvcPlugin* plugin) +{ + rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; + RDP_PLUGIN_DATA* data; + RDP_PLUGIN_DATA default_data[2] = { { 0 }, { 0 } }; + + DEBUG_SVC("connecting"); + + plugin->interval_callback = rdpsnd_process_interval; + + rdpsnd->data_out_list = list_new(); + rdpsnd->latency = -1; + + data = (RDP_PLUGIN_DATA*)plugin->channel_entry_points.pExtendedData; + while (data && data->size > 0) + { + rdpsnd_process_plugin_data(rdpsnd, data); + data = (RDP_PLUGIN_DATA*) (((void*) data) + data->size); + } + + if (rdpsnd->device == NULL) + { + default_data[0].size = sizeof(RDP_PLUGIN_DATA); + default_data[0].data[0] = "pulse"; + default_data[0].data[1] = ""; + if (!rdpsnd_load_device_plugin(rdpsnd, "pulse", default_data)) + { + default_data[0].data[0] = "alsa"; + default_data[0].data[1] = "default"; + rdpsnd_load_device_plugin(rdpsnd, "alsa", default_data); + } + } + if (rdpsnd->device == NULL) + { + DEBUG_WARN("no sound device."); + } +} + +static void rdpsnd_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + freerdp_event_free(event); +} + +static void rdpsnd_process_terminate(rdpSvcPlugin* plugin) +{ + rdpsndPlugin* rdpsnd = (rdpsndPlugin*)plugin; + struct data_out_item* item; + + if (rdpsnd->device) + IFCALL(rdpsnd->device->Free, rdpsnd->device); + + while ((item = list_dequeue(rdpsnd->data_out_list)) != NULL) + { + stream_free(item->data_out); + xfree(item); + } + list_free(rdpsnd->data_out_list); + + rdpsnd_free_supported_formats(rdpsnd); + + xfree(plugin); +} + +DEFINE_SVC_PLUGIN(rdpsnd, "rdpsnd", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP) + diff --git a/channels/rdpsnd/rdpsnd_main.h b/channels/rdpsnd/rdpsnd_main.h new file mode 100644 index 0000000..9c12747 --- /dev/null +++ b/channels/rdpsnd/rdpsnd_main.h @@ -0,0 +1,76 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Audio Output Virtual Channel + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDPSND_MAIN_H +#define __RDPSND_MAIN_H + +typedef struct rdpsnd_plugin rdpsndPlugin; + +typedef struct rdpsnd_format rdpsndFormat; +struct rdpsnd_format +{ + uint16 wFormatTag; + uint16 nChannels; + uint32 nSamplesPerSec; + uint16 nBlockAlign; + uint16 wBitsPerSample; + uint16 cbSize; + uint8* data; +}; + +typedef struct rdpsnd_device_plugin rdpsndDevicePlugin; + +typedef boolean (*pcFormatSupported) (rdpsndDevicePlugin* device, rdpsndFormat* format); +typedef void (*pcOpen) (rdpsndDevicePlugin* device, rdpsndFormat* format, int latency); +typedef void (*pcSetFormat) (rdpsndDevicePlugin* device, rdpsndFormat* format, int latency); +typedef void (*pcSetVolume) (rdpsndDevicePlugin* device, uint32 value); +typedef void (*pcPlay) (rdpsndDevicePlugin* device, uint8* data, int size); +typedef void (*pcStart) (rdpsndDevicePlugin* device); +typedef void (*pcClose) (rdpsndDevicePlugin* device); +typedef void (*pcFree) (rdpsndDevicePlugin* device); + +struct rdpsnd_device_plugin +{ + pcFormatSupported FormatSupported; + pcOpen Open; + pcSetFormat SetFormat; + pcSetVolume SetVolume; + pcPlay Play; + pcStart Start; + pcClose Close; + pcFree Free; +}; + +#define RDPSND_DEVICE_EXPORT_FUNC_NAME "FreeRDPRdpsndDeviceEntry" + +typedef void (*PREGISTERRDPSNDDEVICE)(rdpsndPlugin* rdpsnd, rdpsndDevicePlugin* device); + +struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS +{ + rdpsndPlugin* rdpsnd; + PREGISTERRDPSNDDEVICE pRegisterRdpsndDevice; + RDP_PLUGIN_DATA* plugin_data; +}; +typedef struct _FREERDP_RDPSND_DEVICE_ENTRY_POINTS FREERDP_RDPSND_DEVICE_ENTRY_POINTS; +typedef FREERDP_RDPSND_DEVICE_ENTRY_POINTS* PFREERDP_RDPSND_DEVICE_ENTRY_POINTS; + +typedef int (*PFREERDP_RDPSND_DEVICE_ENTRY)(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS pEntryPoints); + +#endif /* __RDPSND_MAIN_H */ + diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..00949d2 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,40 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Client User Interfaces +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# User Interfaces + +if(NOT WIN32) + # Build Test Client + add_subdirectory(test) + + # Build X11 Client + find_suggested_package(X11) + if(WITH_X11) + add_subdirectory(X11) + endif() + + # Build DirectFB Client + find_optional_package(DirectFB) + if(WITH_DIRECTFB) + add_subdirectory(DirectFB) + endif() +else() + # Build Windows Client + add_subdirectory(Windows) +endif() diff --git a/client/DirectFB/CMakeLists.txt b/client/DirectFB/CMakeLists.txt new file mode 100644 index 0000000..e267f6b --- /dev/null +++ b/client/DirectFB/CMakeLists.txt @@ -0,0 +1,37 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP DirectFB Client +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_directories(${DIRECTFB_INCLUDE_DIRS}) + +add_executable(dfreerdp + df_event.c + df_event.h + df_graphics.c + df_graphics.c + dfreerdp.c + dfreerdp.h) + +target_link_libraries(dfreerdp freerdp-core) +target_link_libraries(dfreerdp freerdp-gdi) +target_link_libraries(dfreerdp freerdp-kbd) +target_link_libraries(dfreerdp freerdp-channels) +target_link_libraries(dfreerdp freerdp-utils) +target_link_libraries(dfreerdp ${DIRECTFB_LIBRARIES}) + +install(TARGETS dfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/DirectFB/df_event.c b/client/DirectFB/df_event.c new file mode 100644 index 0000000..19af30a --- /dev/null +++ b/client/DirectFB/df_event.c @@ -0,0 +1,275 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "df_event.h" + +static uint8 keymap[256]; +static uint8 functionmap[128]; + +void df_keyboard_init() +{ + memset(keymap, 0, sizeof(keymap)); + + /* Map DirectFB keycodes to Virtual Key Codes */ + + keymap[DIKI_A - DIKI_UNKNOWN] = VK_KEY_A; + keymap[DIKI_B - DIKI_UNKNOWN] = VK_KEY_B; + keymap[DIKI_C - DIKI_UNKNOWN] = VK_KEY_C; + keymap[DIKI_D - DIKI_UNKNOWN] = VK_KEY_D; + keymap[DIKI_E - DIKI_UNKNOWN] = VK_KEY_E; + keymap[DIKI_F - DIKI_UNKNOWN] = VK_KEY_F; + keymap[DIKI_G - DIKI_UNKNOWN] = VK_KEY_G; + keymap[DIKI_H - DIKI_UNKNOWN] = VK_KEY_H; + keymap[DIKI_I - DIKI_UNKNOWN] = VK_KEY_I; + keymap[DIKI_J - DIKI_UNKNOWN] = VK_KEY_J; + keymap[DIKI_K - DIKI_UNKNOWN] = VK_KEY_K; + keymap[DIKI_L - DIKI_UNKNOWN] = VK_KEY_L; + keymap[DIKI_M - DIKI_UNKNOWN] = VK_KEY_M; + keymap[DIKI_N - DIKI_UNKNOWN] = VK_KEY_N; + keymap[DIKI_O - DIKI_UNKNOWN] = VK_KEY_O; + keymap[DIKI_P - DIKI_UNKNOWN] = VK_KEY_P; + keymap[DIKI_Q - DIKI_UNKNOWN] = VK_KEY_Q; + keymap[DIKI_R - DIKI_UNKNOWN] = VK_KEY_R; + keymap[DIKI_S - DIKI_UNKNOWN] = VK_KEY_S; + keymap[DIKI_T - DIKI_UNKNOWN] = VK_KEY_T; + keymap[DIKI_U - DIKI_UNKNOWN] = VK_KEY_U; + keymap[DIKI_V - DIKI_UNKNOWN] = VK_KEY_V; + keymap[DIKI_W - DIKI_UNKNOWN] = VK_KEY_W; + keymap[DIKI_X - DIKI_UNKNOWN] = VK_KEY_X; + keymap[DIKI_Y - DIKI_UNKNOWN] = VK_KEY_Y; + keymap[DIKI_Z - DIKI_UNKNOWN] = VK_KEY_Z; + + keymap[DIKI_0 - DIKI_UNKNOWN] = VK_KEY_0; + keymap[DIKI_1 - DIKI_UNKNOWN] = VK_KEY_1; + keymap[DIKI_2 - DIKI_UNKNOWN] = VK_KEY_2; + keymap[DIKI_3 - DIKI_UNKNOWN] = VK_KEY_3; + keymap[DIKI_4 - DIKI_UNKNOWN] = VK_KEY_4; + keymap[DIKI_5 - DIKI_UNKNOWN] = VK_KEY_5; + keymap[DIKI_6 - DIKI_UNKNOWN] = VK_KEY_6; + keymap[DIKI_7 - DIKI_UNKNOWN] = VK_KEY_7; + keymap[DIKI_8 - DIKI_UNKNOWN] = VK_KEY_8; + keymap[DIKI_9 - DIKI_UNKNOWN] = VK_KEY_9; + + keymap[DIKI_F1 - DIKI_UNKNOWN] = VK_F1; + keymap[DIKI_F2 - DIKI_UNKNOWN] = VK_F2; + keymap[DIKI_F3 - DIKI_UNKNOWN] = VK_F3; + keymap[DIKI_F4 - DIKI_UNKNOWN] = VK_F4; + keymap[DIKI_F5 - DIKI_UNKNOWN] = VK_F5; + keymap[DIKI_F6 - DIKI_UNKNOWN] = VK_F6; + keymap[DIKI_F7 - DIKI_UNKNOWN] = VK_F7; + keymap[DIKI_F8 - DIKI_UNKNOWN] = VK_F8; + keymap[DIKI_F9 - DIKI_UNKNOWN] = VK_F9; + keymap[DIKI_F10 - DIKI_UNKNOWN] = VK_F10; + keymap[DIKI_F11 - DIKI_UNKNOWN] = VK_F11; + keymap[DIKI_F12 - DIKI_UNKNOWN] = VK_F12; + + keymap[DIKI_COMMA - DIKI_UNKNOWN] = VK_OEM_COMMA; + keymap[DIKI_PERIOD - DIKI_UNKNOWN] = VK_OEM_PERIOD; + keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = VK_OEM_MINUS; + keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = VK_OEM_PLUS; + + keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = VK_ESCAPE; + keymap[DIKI_LEFT - DIKI_UNKNOWN] = VK_LEFT; + keymap[DIKI_RIGHT - DIKI_UNKNOWN] = VK_RIGHT; + keymap[DIKI_UP - DIKI_UNKNOWN] = VK_UP; + keymap[DIKI_DOWN - DIKI_UNKNOWN] = VK_DOWN; + keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = VK_LCONTROL; + keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = VK_RCONTROL; + keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = VK_LSHIFT; + keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = VK_RSHIFT; + keymap[DIKI_ALT_L - DIKI_UNKNOWN] = VK_LMENU; + keymap[DIKI_ALT_R - DIKI_UNKNOWN] = VK_RMENU; + keymap[DIKI_TAB - DIKI_UNKNOWN] = VK_TAB; + keymap[DIKI_ENTER - DIKI_UNKNOWN] = VK_RETURN; + keymap[DIKI_SPACE - DIKI_UNKNOWN] = VK_SPACE; + keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = VK_BACK; + keymap[DIKI_INSERT - DIKI_UNKNOWN] = VK_INSERT; + keymap[DIKI_DELETE - DIKI_UNKNOWN] = VK_DELETE; + keymap[DIKI_HOME - DIKI_UNKNOWN] = VK_HOME; + keymap[DIKI_END - DIKI_UNKNOWN] = VK_END; + keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = VK_PRIOR; + keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = VK_NEXT; + keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = VK_CAPITAL; + keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = VK_NUMLOCK; + keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = VK_SCROLL; + keymap[DIKI_PRINT - DIKI_UNKNOWN] = VK_PRINT; + keymap[DIKI_PAUSE - DIKI_UNKNOWN] = VK_PAUSE; + keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = VK_DIVIDE; + keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = VK_MULTIPLY; + keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = VK_SUBTRACT; + keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = VK_ADD; + keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = VK_RETURN; + keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = VK_DECIMAL; + + keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = VK_OEM_3; + keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = VK_OEM_4; + keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = VK_OEM_6; + keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = VK_OEM_5; + keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = VK_OEM_1; + keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = VK_OEM_7; + keymap[DIKI_COMMA - DIKI_UNKNOWN] = VK_OEM_COMMA; + keymap[DIKI_PERIOD - DIKI_UNKNOWN] = VK_OEM_PERIOD; + keymap[DIKI_SLASH - DIKI_UNKNOWN] = VK_OEM_2; + + keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = 0; + + keymap[DIKI_KP_0 - DIKI_UNKNOWN] = VK_NUMPAD0; + keymap[DIKI_KP_1 - DIKI_UNKNOWN] = VK_NUMPAD1; + keymap[DIKI_KP_2 - DIKI_UNKNOWN] = VK_NUMPAD2; + keymap[DIKI_KP_3 - DIKI_UNKNOWN] = VK_NUMPAD3; + keymap[DIKI_KP_4 - DIKI_UNKNOWN] = VK_NUMPAD4; + keymap[DIKI_KP_5 - DIKI_UNKNOWN] = VK_NUMPAD5; + keymap[DIKI_KP_6 - DIKI_UNKNOWN] = VK_NUMPAD6; + keymap[DIKI_KP_7 - DIKI_UNKNOWN] = VK_NUMPAD7; + keymap[DIKI_KP_8 - DIKI_UNKNOWN] = VK_NUMPAD8; + keymap[DIKI_KP_9 - DIKI_UNKNOWN] = VK_NUMPAD9; + + keymap[DIKI_META_L - DIKI_UNKNOWN] = VK_LWIN; + keymap[DIKI_META_R - DIKI_UNKNOWN] = VK_RWIN; + keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = VK_APPS; + + + memset(functionmap, 0, sizeof(functionmap)); + + functionmap[DFB_FUNCTION_KEY(23) - DFB_FUNCTION_KEY(0)] = VK_HANGUL; + functionmap[DFB_FUNCTION_KEY(24) - DFB_FUNCTION_KEY(0)] = VK_HANJA; + +} + +void df_send_mouse_button_event(rdpInput* input, boolean down, uint32 button, uint16 x, uint16 y) +{ + uint16 flags; + + flags = (down) ? PTR_FLAGS_DOWN : 0; + + if (button == DIBI_LEFT) + flags |= PTR_FLAGS_BUTTON1; + else if (button == DIBI_RIGHT) + flags |= PTR_FLAGS_BUTTON2; + else if (button == DIBI_MIDDLE) + flags |= PTR_FLAGS_BUTTON3; + + if (flags != 0) + input->MouseEvent(input, flags, x, y); +} + +void df_send_mouse_motion_event(rdpInput* input, uint16 x, uint16 y) +{ + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); +} + +void df_send_mouse_wheel_event(rdpInput* input, sint16 axisrel, uint16 x, uint16 y) +{ + uint16 flags = PTR_FLAGS_WHEEL; + + if (axisrel < 0) + flags |= 0x0078; + else + flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + + input->MouseEvent(input, flags, x, y); +} + +void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8 function) +{ + uint16 flags; + uint8 vkcode; + uint8 scancode; + boolean extended; + + if (keycode) + vkcode = keymap[keycode]; + else if (function) + vkcode = functionmap[function]; + else + return; + + scancode = freerdp_kbd_get_scancode_by_virtualkey(vkcode, &extended); + + flags = (extended) ? KBD_FLAGS_EXTENDED : 0; + flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; + + input->KeyboardEvent(input, flags, scancode); +} + +boolean df_event_process(freerdp* instance, DFBEvent* event) +{ + int flags; + rdpGdi* gdi; + dfInfo* dfi; + int pointer_x; + int pointer_y; + DFBInputEvent* input_event; + + gdi = instance->context->gdi; + dfi = ((dfContext*) instance->context)->dfi; + + dfi->layer->GetCursorPosition(dfi->layer, &pointer_x, &pointer_y); + + if (event->clazz == DFEC_INPUT) + { + flags = 0; + input_event = (DFBInputEvent*) event; + + switch (input_event->type) + { + case DIET_AXISMOTION: + + if (pointer_x > (gdi->width - 1)) + pointer_x = gdi->width - 1; + + if (pointer_y > (gdi->height - 1)) + pointer_y = gdi->height - 1; + + if (input_event->axis == DIAI_Z) + { + df_send_mouse_wheel_event(instance->input, input_event->axisrel, pointer_x, pointer_y); + } + else + { + df_send_mouse_motion_event(instance->input, pointer_x, pointer_y); + } + break; + + case DIET_BUTTONPRESS: + df_send_mouse_button_event(instance->input, true, input_event->button, pointer_x, pointer_y); + break; + + case DIET_BUTTONRELEASE: + df_send_mouse_button_event(instance->input, false, input_event->button, pointer_x, pointer_y); + break; + + case DIET_KEYPRESS: + df_send_keyboard_event(instance->input, true, input_event->key_id - DIKI_UNKNOWN, input_event->key_symbol - DFB_FUNCTION_KEY(0)); + break; + + case DIET_KEYRELEASE: + df_send_keyboard_event(instance->input, false, input_event->key_id - DIKI_UNKNOWN, input_event->key_symbol - DFB_FUNCTION_KEY(0)); + break; + + case DIET_UNKNOWN: + break; + } + } + + return true; +} diff --git a/client/DirectFB/df_event.h b/client/DirectFB/df_event.h new file mode 100644 index 0000000..ebe20cd --- /dev/null +++ b/client/DirectFB/df_event.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DF_EVENT_H +#define __DF_EVENT_H + +#include "dfreerdp.h" + +void df_keyboard_init(); +boolean df_event_process(freerdp* instance, DFBEvent* event); + +#endif /* __DF_EVENT_H */ diff --git a/client/DirectFB/df_graphics.c b/client/DirectFB/df_graphics.c new file mode 100644 index 0000000..3203a59 --- /dev/null +++ b/client/DirectFB/df_graphics.c @@ -0,0 +1,121 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "df_graphics.h" + +/* Pointer Class */ + +void df_Pointer_New(rdpContext* context, rdpPointer* pointer) +{ + dfInfo* dfi; + DFBResult result; + dfPointer* df_pointer; + DFBSurfaceDescription dsc; + + dfi = ((dfContext*) context)->dfi; + df_pointer = (dfPointer*) pointer; + + dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; + dsc.caps = DSCAPS_SYSTEMONLY; + dsc.width = pointer->width; + dsc.height = pointer->height; + dsc.pixelformat = DSPF_ARGB; + + result = dfi->dfb->CreateSurface(dfi->dfb, &dsc, &(df_pointer->surface)); + + if (result == DFB_OK) + { + int pitch; + uint8* point = NULL; + + df_pointer->xhot = pointer->xPos; + df_pointer->yhot = pointer->yPos; + + result = df_pointer->surface->Lock(df_pointer->surface, + DSLF_WRITE, (void**) &point, &pitch); + + if (result != DFB_OK) + { + DirectFBErrorFatal("Error while creating pointer surface", result); + return; + } + + if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0)) + { + freerdp_alpha_cursor_convert(point, pointer->xorMaskData, pointer->andMaskData, + pointer->width, pointer->height, pointer->xorBpp, dfi->clrconv); + } + + if (pointer->xorBpp > 24) + { + freerdp_image_swap_color_order(point, pointer->width, pointer->height); + } + + df_pointer->surface->Unlock(df_pointer->surface); + } +} + +void df_Pointer_Free(rdpContext* context, rdpPointer* pointer) +{ + dfPointer* df_pointer = (dfPointer*) pointer; + df_pointer->surface->Release(df_pointer->surface); +} + +void df_Pointer_Set(rdpContext* context, rdpPointer* pointer) +{ + dfInfo* dfi; + DFBResult result; + dfPointer* df_pointer; + + dfi = ((dfContext*) context)->dfi; + df_pointer = (dfPointer*) pointer; + + dfi->layer->SetCooperativeLevel(dfi->layer, DLSCL_ADMINISTRATIVE); + + result = dfi->layer->SetCursorShape(dfi->layer, + df_pointer->surface, df_pointer->xhot, df_pointer->yhot); + + if (result != DFB_OK) + { + DirectFBErrorFatal("SetCursorShape Error", result); + return; + } + + dfi->layer->SetCooperativeLevel(dfi->layer, DLSCL_SHARED); +} + +/* Graphics Module */ + +void df_register_graphics(rdpGraphics* graphics) +{ + rdpPointer* pointer; + + pointer = xnew(rdpPointer); + pointer->size = sizeof(dfPointer); + + pointer->New = df_Pointer_New; + pointer->Free = df_Pointer_Free; + pointer->Set = df_Pointer_Set; + + graphics_register_pointer(graphics, pointer); + xfree(pointer); +} + diff --git a/client/DirectFB/df_graphics.h b/client/DirectFB/df_graphics.h new file mode 100644 index 0000000..fe2d5c8 --- /dev/null +++ b/client/DirectFB/df_graphics.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DF_GRAPHICS_H +#define __DF_GRAPHICS_H + +#include "dfreerdp.h" + +void df_register_graphics(rdpGraphics* graphics); + +#endif /* __DF_GRAPHICS_H */ diff --git a/client/DirectFB/dfreerdp.c b/client/DirectFB/dfreerdp.c new file mode 100644 index 0000000..1af7cc9 --- /dev/null +++ b/client/DirectFB/dfreerdp.c @@ -0,0 +1,476 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Client + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "df_event.h" +#include "df_graphics.h" + +#include "dfreerdp.h" + +static freerdp_sem g_sem; +static int g_thread_count = 0; + +struct thread_data +{ + freerdp* instance; +}; + +void df_context_new(freerdp* instance, rdpContext* context) +{ + context->channels = freerdp_channels_new(); +} + +void df_context_free(freerdp* instance, rdpContext* context) +{ + +} + +void df_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; +} + +void df_end_paint(rdpContext* context) +{ + rdpGdi* gdi; + dfInfo* dfi; + + gdi = context->gdi; + dfi = ((dfContext*) context)->dfi; + + if (gdi->primary->hdc->hwnd->invalid->null) + return; + +#if 1 + dfi->update_rect.x = gdi->primary->hdc->hwnd->invalid->x; + dfi->update_rect.y = gdi->primary->hdc->hwnd->invalid->y; + dfi->update_rect.w = gdi->primary->hdc->hwnd->invalid->w; + dfi->update_rect.h = gdi->primary->hdc->hwnd->invalid->h; +#else + dfi->update_rect.x = 0; + dfi->update_rect.y = 0; + dfi->update_rect.w = gdi->width; + dfi->update_rect.h = gdi->height; +#endif + + dfi->primary->Blit(dfi->primary, dfi->surface, &(dfi->update_rect), dfi->update_rect.x, dfi->update_rect.y); +} + +boolean df_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +{ + dfInfo* dfi; + + dfi = ((dfContext*) instance->context)->dfi; + + rfds[*rcount] = (void*)(long)(dfi->read_fds); + (*rcount)++; + + return true; +} + +boolean df_check_fds(freerdp* instance, fd_set* set) +{ + dfInfo* dfi; + + dfi = ((dfContext*) instance->context)->dfi; + + if (!FD_ISSET(dfi->read_fds, set)) + return true; + + if (read(dfi->read_fds, &(dfi->event), sizeof(dfi->event)) > 0) + df_event_process(instance, &(dfi->event)); + + return true; +} + +boolean df_pre_connect(freerdp* instance) +{ + dfInfo* dfi; + boolean bitmap_cache; + dfContext* context; + rdpSettings* settings; + + dfi = (dfInfo*) xzalloc(sizeof(dfInfo)); + context = ((dfContext*) instance->context); + context->dfi = dfi; + + settings = instance->settings; + bitmap_cache = settings->bitmap_cache; + + settings->order_support[NEG_DSTBLT_INDEX] = true; + settings->order_support[NEG_PATBLT_INDEX] = true; + settings->order_support[NEG_SCRBLT_INDEX] = true; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; + settings->order_support[NEG_MULTIPATBLT_INDEX] = false; + settings->order_support[NEG_MULTISCRBLT_INDEX] = false; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_LINETO_INDEX] = true; + settings->order_support[NEG_POLYLINE_INDEX] = true; + settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache; + settings->order_support[NEG_MEM3BLT_INDEX] = false; + settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache; + settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; + settings->order_support[NEG_SAVEBITMAP_INDEX] = false; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = false; + settings->order_support[NEG_FAST_INDEX_INDEX] = false; + settings->order_support[NEG_FAST_GLYPH_INDEX] = false; + settings->order_support[NEG_POLYGON_SC_INDEX] = false; + settings->order_support[NEG_POLYGON_CB_INDEX] = false; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; + + dfi->clrconv = xnew(CLRCONV); + dfi->clrconv->alpha = 1; + dfi->clrconv->invert = 0; + dfi->clrconv->rgb555 = 0; + dfi->clrconv->palette = xnew(rdpPalette); + + freerdp_channels_pre_connect(instance->context->channels, instance); + + return true; +} + +boolean df_post_connect(freerdp* instance) +{ + rdpGdi* gdi; + dfInfo* dfi; + dfContext* context; + + context = ((dfContext*) instance->context); + dfi = context->dfi; + + gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL); + gdi = instance->context->gdi; + + dfi->err = DirectFBCreate(&(dfi->dfb)); + + dfi->dsc.flags = DSDESC_CAPS; + dfi->dsc.caps = DSCAPS_PRIMARY; + dfi->err = dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->primary)); + dfi->err = dfi->primary->GetSize(dfi->primary, &(gdi->width), &(gdi->height)); + dfi->dfb->SetVideoMode(dfi->dfb, gdi->width, gdi->height, gdi->dstBpp); + dfi->dfb->CreateInputEventBuffer(dfi->dfb, DICAPS_ALL, DFB_TRUE, &(dfi->event_buffer)); + dfi->event_buffer->CreateFileDescriptor(dfi->event_buffer, &(dfi->read_fds)); + + dfi->dfb->GetDisplayLayer(dfi->dfb, 0, &(dfi->layer)); + dfi->layer->EnableCursor(dfi->layer, 1); + + dfi->dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT; + dfi->dsc.caps = DSCAPS_SYSTEMONLY; + dfi->dsc.width = gdi->width; + dfi->dsc.height = gdi->height; + + if (gdi->dstBpp == 32 || gdi->dstBpp == 24) + dfi->dsc.pixelformat = DSPF_AiRGB; + else if (gdi->dstBpp == 16 || gdi->dstBpp == 15) + dfi->dsc.pixelformat = DSPF_RGB16; + else if (gdi->dstBpp == 8) + dfi->dsc.pixelformat = DSPF_RGB332; + else + dfi->dsc.pixelformat = DSPF_AiRGB; + + dfi->dsc.preallocated[0].data = gdi->primary_buffer; + dfi->dsc.preallocated[0].pitch = gdi->width * gdi->bytesPerPixel; + dfi->dfb->CreateSurface(dfi->dfb, &(dfi->dsc), &(dfi->surface)); + + instance->update->BeginPaint = df_begin_paint; + instance->update->EndPaint = df_end_paint; + + df_keyboard_init(); + + pointer_cache_register_callbacks(instance->update); + df_register_graphics(instance->context->graphics); + + freerdp_channels_post_connect(instance->context->channels, instance); + + return true; +} + +static int df_process_plugin_args(rdpSettings* settings, const char* name, + RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChannels* channels = (rdpChannels*) user_data; + + printf("loading plugin %s\n", name); + freerdp_channels_load_plugin(channels, settings, name, plugin_data); + + return 1; +} + +boolean df_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +{ + printf("Certificate details:\n"); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fingerprint); + printf("The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA.\n"); + + char answer; + while (1) + { + printf("Do you trust the above certificate? (Y/N) "); + answer = fgetc(stdin); + + if (answer == 'y' || answer == 'Y') + { + return true; + } + else if (answer == 'n' || answer == 'N') + { + break; + } + } + + return false; +} + +static int +df_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) +{ + return freerdp_channels_data(instance, channelId, data, size, flags, total_size); +} + +static void +df_process_cb_monitor_ready_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + RDP_CB_FORMAT_LIST_EVENT* format_list_event; + + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event; + format_list_event->num_formats = 0; + + freerdp_channels_send_event(channels, event); +} + +static void +df_process_channel_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + + event = freerdp_channels_pop_event(channels); + + if (event) + { + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_MONITOR_READY: + df_process_cb_monitor_ready_event(channels, instance); + break; + default: + printf("df_process_channel_event: unknown event type %d\n", event->event_type); + break; + } + + freerdp_event_free(event); + } +} + +static void df_free(dfInfo* dfi) +{ + dfi->dfb->Release(dfi->dfb); + xfree(dfi); +} + +int dfreerdp_run(freerdp* instance) +{ + int i; + int fds; + int max_fds; + int rcount; + int wcount; + void* rfds[32]; + void* wfds[32]; + fd_set rfds_set; + fd_set wfds_set; + dfInfo* dfi; + dfContext* context; + rdpChannels* channels; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); + + if (!freerdp_connect(instance)) + return 0; + + context = (dfContext*) instance->context; + + dfi = context->dfi; + channels = instance->context->channels; + + while (1) + { + rcount = 0; + wcount = 0; + + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get channel manager file descriptor\n"); + break; + } + if (df_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get dfreerdp file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("dfreerdp_run: select failed\n"); + break; + } + } + + if (freerdp_check_fds(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + if (df_check_fds(instance, &rfds_set) != true) + { + printf("Failed to check dfreerdp file descriptor\n"); + break; + } + if (freerdp_channels_check_fds(channels, instance) != true) + { + printf("Failed to check channel manager file descriptor\n"); + break; + } + df_process_channel_event(channels, instance); + } + + freerdp_channels_close(channels, instance); + freerdp_channels_free(channels); + df_free(dfi); + gdi_free(instance); + freerdp_disconnect(instance); + freerdp_free(instance); + + return 0; +} + +void* thread_func(void* param) +{ + struct thread_data* data; + data = (struct thread_data*) param; + + dfreerdp_run(data->instance); + + xfree(data); + + pthread_detach(pthread_self()); + + g_thread_count--; + + if (g_thread_count < 1) + freerdp_sem_signal(g_sem); + + return NULL; +} + +int main(int argc, char* argv[]) +{ + pthread_t thread; + freerdp* instance; + dfContext* context; + rdpChannels* channels; + struct thread_data* data; + + setlocale(LC_ALL, ""); + + freerdp_channels_global_init(); + + g_sem = freerdp_sem_new(1); + + instance = freerdp_new(); + instance->PreConnect = df_pre_connect; + instance->PostConnect = df_post_connect; + instance->VerifyCertificate = df_verify_certificate; + instance->ReceiveChannelData = df_receive_channel_data; + + instance->context_size = sizeof(dfContext); + instance->ContextNew = df_context_new; + instance->ContextFree = df_context_free; + freerdp_context_new(instance); + + context = (dfContext*) instance->context; + channels = instance->context->channels; + + DirectFBInit(&argc, &argv); + freerdp_parse_args(instance->settings, argc, argv, df_process_plugin_args, channels, NULL, NULL); + + data = (struct thread_data*) xzalloc(sizeof(struct thread_data)); + data->instance = instance; + + g_thread_count++; + pthread_create(&thread, 0, thread_func, data); + + while (g_thread_count > 0) + { + freerdp_sem_wait(g_sem); + } + + freerdp_channels_global_uninit(); + + return 0; +} diff --git a/client/DirectFB/dfreerdp.h b/client/DirectFB/dfreerdp.h new file mode 100644 index 0000000..622329d --- /dev/null +++ b/client/DirectFB/dfreerdp.h @@ -0,0 +1,69 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * DirectFB Client + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DFREERDP_H +#define __DFREERDP_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef struct df_info dfInfo; + +struct df_context +{ + rdpContext _p; + + dfInfo* dfi; + rdpSettings* settings; +}; +typedef struct df_context dfContext; + +struct df_pointer +{ + rdpPointer pointer; + IDirectFBSurface* surface; + uint32 xhot; + uint32 yhot; +}; +typedef struct df_pointer dfPointer; + +struct df_info +{ + int read_fds; + DFBResult err; + IDirectFB* dfb; + DFBEvent event; + HCLRCONV clrconv; + DFBRectangle update_rect; + DFBSurfaceDescription dsc; + IDirectFBSurface* primary; + IDirectFBSurface* surface; + IDirectFBDisplayLayer* layer; + IDirectFBEventBuffer* event_buffer; +}; + +#endif /* __DFREERDP_H */ diff --git a/client/Windows/CMakeLists.txt b/client/Windows/CMakeLists.txt new file mode 100644 index 0000000..68b4671 --- /dev/null +++ b/client/Windows/CMakeLists.txt @@ -0,0 +1,36 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Windows cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_executable(wfreerdp WIN32 + wf_gdi.c + wf_gdi.h + wf_event.c + wf_event.h + wf_graphics.c + wf_graphics.h + wfreerdp.c + wfreerdp.h) + +target_link_libraries(wfreerdp freerdp-core) +target_link_libraries(wfreerdp freerdp-gdi) +target_link_libraries(wfreerdp freerdp-utils) +target_link_libraries(wfreerdp freerdp-codec) +target_link_libraries(wfreerdp freerdp-channels) + +install(TARGETS wfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c new file mode 100644 index 0000000..e2f04d3 --- /dev/null +++ b/client/Windows/wf_event.c @@ -0,0 +1,223 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Event Handling + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "wfreerdp.h" + +#include "wf_event.h" + +static HWND g_focus_hWnd; +extern HCURSOR g_default_cursor; + +#define X_POS(lParam) (lParam & 0xffff) +#define Y_POS(lParam) ((lParam >> 16) & 0xffff) + +LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam) +{ + DWORD flags; + wfInfo* wfi; + uint8 scanCode; + rdpInput* input; + uint16 kbdFlags; + PKBDLLHOOKSTRUCT p; + + DEBUG_KBD("Low-level keyboard hook, hWnd %X nCode %X wParam %X\n", g_focus_hWnd, nCode, wParam); + + if (g_focus_hWnd && (nCode == HC_ACTION)) + { + switch (wParam) + { + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + wfi = (wfInfo*) GetWindowLongPtr(g_focus_hWnd, GWLP_USERDATA); + p = (PKBDLLHOOKSTRUCT) lParam; + scanCode = (uint8) p->scanCode; + input = wfi->instance->input; + flags = p->flags; + kbdFlags = 0; + + DEBUG_KBD("keydown %d scanCode %04X flags %02X vkCode %02X\n", + (wParam == WM_KEYDOWN), scanCode, flags, p->vkCode); + + if (wfi->fs_toggle && + ((p->vkCode == VK_RETURN) || (p->vkCode == VK_CANCEL)) && + (GetAsyncKeyState(VK_CONTROL) & 0x8000) && + (GetAsyncKeyState(VK_MENU) & 0x8000)) /* could also use flags & LLKHF_ALTDOWN */ + { + if (wParam == WM_KEYDOWN) + //wf_toggle_fullscreen(wfi); + return 1; + } + + if (scanCode == 0x45) /* NumLock-ish */ + { + if (flags & LLKHF_EXTENDED) + { + /* Windows sends NumLock as extended - rdp doesn't */ + DEBUG_KBD("hack: NumLock (x45) should not be extended\n"); + flags &= ~LLKHF_EXTENDED; + } + else + { + /* Windows sends Pause as if it was a RDP NumLock (handled above). + * It must however be sent as a one-shot Ctrl+NumLock */ + if (wParam == WM_KEYDOWN) + { + DEBUG_KBD("Pause, sent as Ctrl+NumLock\n"); + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x1D); /* Ctrl down */ + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x45); /* NumLock down */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x1D); /* Ctrl up */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x45); /* NumLock up */ + } + else + { + DEBUG_KBD("Pause up\n"); + } + + return 1; + } + } + + if ((scanCode == 0x36) && (flags & LLKHF_EXTENDED)) + { + DEBUG_KBD("hack: right shift (x36) should not be extended\n"); + flags &= ~LLKHF_EXTENDED; + } + + kbdFlags |= (flags & LLKHF_UP) ? KBD_FLAGS_RELEASE : KBD_FLAGS_DOWN; + kbdFlags |= (flags & LLKHF_EXTENDED) ? KBD_FLAGS_EXTENDED : 0; + input->KeyboardEvent(input, kbdFlags, scanCode); + + if (p->vkCode == VK_CAPITAL) + DEBUG_KBD("caps lock is processed on client side too to toggle caps lock indicator\n"); + else + return 1; + + break; + } + } + + return CallNextHookEx(NULL, nCode, wParam, lParam); +} + +LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + LONG ptr; + wfInfo* wfi; + int x, y, w, h; + PAINTSTRUCT ps; + rdpInput* input; + boolean processed; + + processed = true; + ptr = GetWindowLongPtr(hWnd, GWLP_USERDATA); + wfi = (wfInfo*) ptr; + + if (wfi != NULL) + { + input = wfi->instance->input; + + switch (Msg) + { + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + + x = ps.rcPaint.left; + y = ps.rcPaint.top; + w = ps.rcPaint.right - ps.rcPaint.left + 1; + h = ps.rcPaint.bottom - ps.rcPaint.top + 1; + + //printf("WM_PAINT: x:%d y:%d w:%d h:%d\n", x, y, w, h); + + BitBlt(hdc, x, y, w, h, wfi->primary->hdc, x, y, SRCCOPY); + + EndPaint(hWnd, &ps); + break; + + case WM_LBUTTONDOWN: + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_LBUTTONUP: + input->MouseEvent(input, PTR_FLAGS_BUTTON1, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_RBUTTONDOWN: + input->MouseEvent(input, PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_RBUTTONUP: + input->MouseEvent(input, PTR_FLAGS_BUTTON2, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_MOUSEMOVE: + input->MouseEvent(input, PTR_FLAGS_MOVE, X_POS(lParam), Y_POS(lParam)); + break; + + case WM_SETCURSOR: + SetCursor(wfi->cursor); + break; + + default: + processed = false; + break; + } + } + else + { + processed = false; + } + + if (processed) + return 0; + + switch (Msg) + { + case WM_DESTROY: + PostQuitMessage(WM_QUIT); + break; + + case WM_SETCURSOR: + SetCursor(g_default_cursor); + break; + + case WM_SETFOCUS: + DEBUG_KBD("getting focus %X\n", hWnd); + g_focus_hWnd = hWnd; + break; + + case WM_KILLFOCUS: + DEBUG_KBD("loosing focus %X\n", hWnd); + if (g_focus_hWnd == hWnd) + g_focus_hWnd = NULL; + break; + + default: + return DefWindowProc(hWnd, Msg, wParam, lParam); + break; + } + + return 0; +} diff --git a/client/Windows/wf_event.h b/client/Windows/wf_event.h new file mode 100644 index 0000000..57ada3f --- /dev/null +++ b/client/Windows/wf_event.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Event Handling + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WF_EVENT_H +#define __WF_EVENT_H + +#include "wfreerdp.h" + +LRESULT CALLBACK wf_ll_kbd_proc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + +#ifdef WITH_DEBUG_KBD +#define DEBUG_KBD(fmt, ...) DEBUG_CLASS(KBD, fmt, ## __VA_ARGS__) +#else +#define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __WF_EVENT_H */ diff --git a/client/Windows/wf_gdi.c b/client/Windows/wf_gdi.c new file mode 100644 index 0000000..9943c37 --- /dev/null +++ b/client/Windows/wf_gdi.c @@ -0,0 +1,545 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows GDI + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "wfreerdp.h" +#include "wf_graphics.h" + +const uint8 wf_rop2_table[] = +{ + R2_BLACK, /* 0 */ + R2_NOTMERGEPEN, /* DPon */ + R2_MASKNOTPEN, /* DPna */ + R2_NOTCOPYPEN, /* Pn */ + R2_MASKPENNOT, /* PDna */ + R2_NOT, /* Dn */ + R2_XORPEN, /* DPx */ + R2_NOTMASKPEN, /* DPan */ + R2_MASKPEN, /* DPa */ + R2_NOTXORPEN, /* DPxn */ + R2_NOP, /* D */ + R2_MERGENOTPEN, /* DPno */ + R2_COPYPEN, /* P */ + R2_MERGEPENNOT, /* PDno */ + R2_MERGEPEN, /* PDo */ + R2_WHITE, /* 1 */ +}; + +boolean wf_set_rop2(HDC hdc, int rop2) +{ + if ((rop2 < 0x01) || (rop2 > 0x10)) + { + printf("Unsupported ROP2: %d\n", rop2); + return false; + } + + SetROP2(hdc, wf_rop2_table[rop2 - 1]); + + return true; +} + +wfBitmap* wf_glyph_new(wfInfo* wfi, GLYPH_DATA* glyph) +{ + wfBitmap* glyph_bmp; + glyph_bmp = wf_image_new(wfi, glyph->cx, glyph->cy, 1, glyph->aj); + return glyph_bmp; +} + +void wf_glyph_free(wfBitmap* glyph) +{ + wf_image_free(glyph); +} + +uint8* wf_glyph_convert(wfInfo* wfi, int width, int height, uint8* data) +{ + int indexx; + int indexy; + uint8* src; + uint8* dst; + uint8* cdata; + int src_bytes_per_row; + int dst_bytes_per_row; + + src_bytes_per_row = (width + 7) / 8; + dst_bytes_per_row = src_bytes_per_row + (src_bytes_per_row % 2); + cdata = (uint8 *) malloc(dst_bytes_per_row * height); + + src = data; + for (indexy = 0; indexy < height; indexy++) + { + dst = cdata + indexy * dst_bytes_per_row; + + for (indexx = 0; indexx < dst_bytes_per_row; indexx++) + { + if (indexx < src_bytes_per_row) + *dst++ = *src++; + else + *dst++ = 0; + } + } + + return cdata; +} + +HBRUSH wf_create_brush(wfInfo * wfi, rdpBrush* brush, uint32 color, int bpp) +{ + int i; + HBRUSH br; + LOGBRUSH lbr; + uint8* cdata; + uint8 ipattern[8]; + HBITMAP pattern = NULL; + + lbr.lbStyle = brush->style; + + if (lbr.lbStyle == BS_DIBPATTERN || lbr.lbStyle == BS_DIBPATTERN8X8 || lbr.lbStyle == BS_DIBPATTERNPT) + lbr.lbColor = DIB_RGB_COLORS; + else + lbr.lbColor = color; + + if (lbr.lbStyle == BS_PATTERN || lbr.lbStyle == BS_PATTERN8X8) + { + if (brush->bpp > 1) + { + pattern = wf_create_dib(wfi, 8, 8, bpp, brush->data, NULL); + lbr.lbHatch = (ULONG_PTR) pattern; + } + else + { + for (i = 0; i != 8; i++) + ipattern[7 - i] = brush->data[i]; + + cdata = wf_glyph_convert(wfi, 8, 8, ipattern); + pattern = CreateBitmap(8, 8, 1, 1, cdata); + lbr.lbHatch = (ULONG_PTR) pattern; + free(cdata); + } + } + else if (lbr.lbStyle == BS_HATCHED) + { + lbr.lbHatch = brush->hatch; + } + else + { + lbr.lbHatch = 0; + } + + br = CreateBrushIndirect(&lbr); + SetBrushOrgEx(wfi->drawing->hdc, brush->x, brush->y, NULL); + + if (pattern != NULL) + DeleteObject(pattern); + + return br; +} + +void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height) +{ + wfi->update_rect.left = x; + wfi->update_rect.top = y; + wfi->update_rect.right = x + width; + wfi->update_rect.bottom = y + height; + InvalidateRect(wfi->hwnd, &(wfi->update_rect), FALSE); + gdi_InvalidateRegion(wfi->hdc, x, y, width, height); +} + +void wf_toggle_fullscreen(wfInfo* wfi) +{ + ShowWindow(wfi->hwnd, SW_HIDE); + wfi->fullscreen = !wfi->fullscreen; + SetForegroundWindow(wfi->hwnd); +} + +void wf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) +{ + +} + +void wf_set_null_clip_rgn(wfInfo* wfi) +{ + SelectClipRgn(wfi->drawing->hdc, NULL); +} + +void wf_set_clip_rgn(wfInfo* wfi, int x, int y, int width, int height) +{ + HRGN clip; + clip = CreateRectRgn(x, y, x + width, y + height); + SelectClipRgn(wfi->drawing->hdc, clip); + DeleteObject(clip); +} + +void wf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +{ + HRGN hrgn; + wfInfo* wfi = ((wfContext*) context)->wfi; + + if (bounds != NULL) + { + hrgn = CreateRectRgn(bounds->left, bounds->top, bounds->right + 1, bounds->bottom + 1); + SelectClipRgn(wfi->drawing->hdc, hrgn); + DeleteObject(hrgn); + } + else + { + SelectClipRgn(wfi->drawing->hdc, NULL); + } +} + +void wf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +{ + wfInfo* wfi = ((wfContext*) context)->wfi; + + BitBlt(wfi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop)); + + wf_invalidate_region(wfi, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); +} + +void wf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + HBRUSH brush; + HBRUSH org_brush; + int org_bkmode; + uint32 fgcolor; + uint32 bgcolor; + COLORREF org_bkcolor; + COLORREF org_textcolor; + wfInfo* wfi = ((wfContext*) context)->wfi; + + fgcolor = freerdp_color_convert_bgr(patblt->foreColor, wfi->srcBpp, 32, wfi->clrconv); + bgcolor = freerdp_color_convert_bgr(patblt->backColor, wfi->srcBpp, 32, wfi->clrconv); + + brush = wf_create_brush(wfi, &patblt->brush, fgcolor, wfi->srcBpp); + org_bkmode = SetBkMode(wfi->drawing->hdc, OPAQUE); + org_bkcolor = SetBkColor(wfi->drawing->hdc, bgcolor); + org_textcolor = SetTextColor(wfi->drawing->hdc, fgcolor); + org_brush = (HBRUSH)SelectObject(wfi->drawing->hdc, brush); + + PatBlt(wfi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)); + + SelectObject(wfi->drawing->hdc, org_brush); + DeleteObject(brush); + + SetBkMode(wfi->drawing->hdc, org_bkmode); + SetBkColor(wfi->drawing->hdc, org_bkcolor); + SetTextColor(wfi->drawing->hdc, org_textcolor); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); +} + +void wf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +{ + wfInfo* wfi = ((wfContext*) context)->wfi; + + BitBlt(wfi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight, wfi->primary->hdc, + scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop)); + + wf_invalidate_region(wfi, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight); +} + +void wf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +{ + RECT rect; + HBRUSH brush; + uint32 brush_color; + wfInfo* wfi = ((wfContext*) context)->wfi; + + brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, wfi->srcBpp, 24, wfi->clrconv); + + rect.left = opaque_rect->nLeftRect; + rect.top = opaque_rect->nTopRect; + rect.right = opaque_rect->nLeftRect + opaque_rect->nWidth; + rect.bottom = opaque_rect->nTopRect + opaque_rect->nHeight; + brush = CreateSolidBrush(brush_color); + FillRect(wfi->drawing->hdc, &rect, brush); + DeleteObject(brush); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); +} + +void wf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + int i; + RECT rect; + HBRUSH brush; + uint32 brush_color; + DELTA_RECT* rectangle; + wfInfo* wfi = ((wfContext*) context)->wfi; + + for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++) + { + rectangle = &multi_opaque_rect->rectangles[i]; + + brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, wfi->srcBpp, 32, wfi->clrconv); + + rect.left = rectangle->left; + rect.top = rectangle->top; + rect.right = rectangle->left + rectangle->width; + rect.bottom = rectangle->top + rectangle->height; + brush = CreateSolidBrush(brush_color); + + brush = CreateSolidBrush(brush_color); + FillRect(wfi->drawing->hdc, &rect, brush); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1); + + DeleteObject(brush); + } +} + +void wf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +{ + HPEN pen; + HPEN org_pen; + int x, y, w, h; + uint32 pen_color; + wfInfo* wfi = ((wfContext*) context)->wfi; + + pen_color = freerdp_color_convert_bgr(line_to->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + + pen = CreatePen(line_to->penStyle, line_to->penWidth, pen_color); + + wf_set_rop2(wfi->drawing->hdc, line_to->bRop2); + org_pen = (HPEN) SelectObject(wfi->drawing->hdc, pen); + + MoveToEx(wfi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); + LineTo(wfi->drawing->hdc, line_to->nXEnd, line_to->nYEnd); + + x = (line_to->nXStart < line_to->nXEnd) ? line_to->nXStart : line_to->nXEnd; + y = (line_to->nYStart < line_to->nYEnd) ? line_to->nYStart : line_to->nYEnd; + w = (line_to->nXStart < line_to->nXEnd) ? (line_to->nXEnd - line_to->nXStart) : (line_to->nXStart - line_to->nXEnd); + h = (line_to->nYStart < line_to->nYEnd) ? (line_to->nYEnd - line_to->nYStart) : (line_to->nYStart - line_to->nYEnd); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, x, y, w, h); + + SelectObject(wfi->drawing->hdc, org_pen); + DeleteObject(pen); +} + +void wf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +{ + int i; + POINT* pts; + int org_rop2; + HPEN hpen; + HPEN org_hpen; + uint32 pen_color; + wfInfo* wfi = ((wfContext*) context)->wfi; + + pen_color = freerdp_color_convert_bgr(polyline->penColor, wfi->srcBpp, wfi->dstBpp, wfi->clrconv); + + hpen = CreatePen(0, 1, pen_color); + org_rop2 = wf_set_rop2(wfi->drawing->hdc, polyline->bRop2); + org_hpen = (HPEN) SelectObject(wfi->drawing->hdc, hpen); + + if (polyline->numPoints > 0) + { + pts = (POINT*) xmalloc(sizeof(POINT) * polyline->numPoints); + + for (i = 0; i < (int) polyline->numPoints; i++) + { + pts[i].x = polyline->points[i].x; + pts[i].y = polyline->points[i].y; + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, pts[i].x, pts[i].y, pts[i].x + 1, pts[i].y + 1); + } + + Polyline(wfi->drawing->hdc, pts, polyline->numPoints); + xfree(pts); + } + + SelectObject(wfi->drawing->hdc, org_hpen); + wf_set_rop2(wfi->drawing->hdc, org_rop2); + DeleteObject(hpen); +} + +void wf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +{ + wfBitmap* bitmap; + wfInfo* wfi = ((wfContext*) context)->wfi; + + bitmap = (wfBitmap*) memblt->bitmap; + + BitBlt(wfi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect, + memblt->nWidth, memblt->nHeight, bitmap->hdc, + memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop)); + + if (wfi->drawing == wfi->primary) + wf_invalidate_region(wfi, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight); +} + +void wf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +{ + int i, j; + int tx, ty; + char* tile_bitmap; + RFX_MESSAGE* message; + wfInfo* wfi = ((wfContext*) context)->wfi; + + RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) wfi->rfx_context; + NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) wfi->nsc_context; + + tile_bitmap = (char*) xzalloc(32); + + if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + { + message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + + /* blit each tile */ + for (i = 0; i < message->num_tiles; i++) + { + tx = message->tiles[i]->x + surface_bits_command->destLeft; + ty = message->tiles[i]->y + surface_bits_command->destTop; + + freerdp_image_convert(message->tiles[i]->data, wfi->tile->pdata, 64, 64, 32, 32, wfi->clrconv); + + for (j = 0; j < message->num_rects; j++) + { + wf_set_clip_rgn(wfi, + surface_bits_command->destLeft + message->rects[j].x, + surface_bits_command->destTop + message->rects[j].y, + message->rects[j].width, message->rects[j].height); + + BitBlt(wfi->primary->hdc, tx, ty, 64, 64, wfi->tile->hdc, 0, 0, SRCCOPY); + } + } + + wf_set_null_clip_rgn(wfi); + + /* invalidate regions */ + for (i = 0; i < message->num_rects; i++) + { + tx = surface_bits_command->destLeft + message->rects[i].x; + ty = surface_bits_command->destTop + message->rects[i].y; + wf_invalidate_region(wfi, tx, ty, message->rects[i].width, message->rects[i].height); + } + + rfx_message_free(rfx_context, message); + } + else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + { + nsc_context->width = surface_bits_command->width; + nsc_context->height = surface_bits_command->height; + nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + wfi->image->_bitmap.width = surface_bits_command->width; + wfi->image->_bitmap.height = surface_bits_command->height; + wfi->image->_bitmap.bpp = surface_bits_command->bpp; + wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); + freerdp_image_flip(nsc_context->bmpdata, wfi->image->_bitmap.data, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); + BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, GDI_SRCCOPY); + nsc_context_destroy(nsc_context); + } + else if (surface_bits_command->codecID == CODEC_ID_NONE) + { + wfi->image->_bitmap.width = surface_bits_command->width; + wfi->image->_bitmap.height = surface_bits_command->height; + wfi->image->_bitmap.bpp = surface_bits_command->bpp; + + wfi->image->_bitmap.data = (uint8*) xrealloc(wfi->image->_bitmap.data, + wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); + + if ((surface_bits_command->bpp != 32) || (wfi->clrconv->alpha == true)) + { + uint8* temp_image; + + freerdp_image_convert(surface_bits_command->bitmapData, wfi->image->_bitmap.data, + wfi->image->_bitmap.width, wfi->image->_bitmap.height, + wfi->image->_bitmap.bpp, 32, wfi->clrconv); + + surface_bits_command->bpp = 32; + surface_bits_command->bitmapData = wfi->image->_bitmap.data; + + temp_image = (uint8*) xmalloc(wfi->image->_bitmap.width * wfi->image->_bitmap.height * 4); + freerdp_image_flip(wfi->image->_bitmap.data, temp_image, wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); + xfree(wfi->image->_bitmap.data); + wfi->image->_bitmap.data = temp_image; + } + else + { + freerdp_image_flip(surface_bits_command->bitmapData, wfi->image->_bitmap.data, + wfi->image->_bitmap.width, wfi->image->_bitmap.height, 32); + } + + BitBlt(wfi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height, wfi->image->hdc, 0, 0, SRCCOPY); + } + else + { + printf("Unsupported codecID %d\n", surface_bits_command->codecID); + } + + if (tile_bitmap != NULL) + xfree(tile_bitmap); +} + +void wf_gdi_register_update_callbacks(rdpUpdate* update) +{ + rdpPrimaryUpdate* primary = update->primary; + + update->Palette = wf_gdi_palette_update; + update->SetBounds = wf_gdi_set_bounds; + + primary->DstBlt = wf_gdi_dstblt; + primary->PatBlt = wf_gdi_patblt; + primary->ScrBlt = wf_gdi_scrblt; + primary->OpaqueRect = wf_gdi_opaque_rect; + primary->DrawNineGrid = NULL; + primary->MultiDstBlt = NULL; + primary->MultiPatBlt = NULL; + primary->MultiScrBlt = NULL; + primary->MultiOpaqueRect = wf_gdi_multi_opaque_rect; + primary->MultiDrawNineGrid = NULL; + primary->LineTo = wf_gdi_line_to; + primary->Polyline = wf_gdi_polyline; + primary->MemBlt = wf_gdi_memblt; + primary->Mem3Blt = NULL; + primary->SaveBitmap = NULL; + primary->GlyphIndex = NULL; + primary->FastIndex = NULL; + primary->FastGlyph = NULL; + primary->PolygonSC = NULL; + primary->PolygonCB = NULL; + primary->EllipseSC = NULL; + primary->EllipseCB = NULL; + + update->SurfaceBits = wf_gdi_surface_bits; +} diff --git a/client/Windows/wf_gdi.h b/client/Windows/wf_gdi.h new file mode 100644 index 0000000..df35f6d --- /dev/null +++ b/client/Windows/wf_gdi.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows GDI + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WF_GDI_H +#define __WF_GDI_H + +#include "wfreerdp.h" + +void wf_invalidate_region(wfInfo* wfi, int x, int y, int width, int height); +wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); +void wf_image_free(wfBitmap* image); +void wf_toggle_fullscreen(wfInfo* wfi); + +void wf_gdi_register_update_callbacks(rdpUpdate* update); + +#endif /* __WF_GDI_H */ diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c new file mode 100644 index 0000000..715d3c5 --- /dev/null +++ b/client/Windows/wf_graphics.c @@ -0,0 +1,242 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Graphical Objects + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "wf_gdi.h" +#include "wf_graphics.h" + +HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, uint8** pdata) +{ + HDC hdc; + int negHeight; + HBITMAP bitmap; + BITMAPINFO bmi; + uint8* cdata = NULL; + + /** + * See: http://msdn.microsoft.com/en-us/library/dd183376 + * if biHeight is positive, the bitmap is bottom-up + * if biHeight is negative, the bitmap is top-down + * Since we get top-down bitmaps, let's keep it that way + */ + + negHeight = (height < 0) ? height : height * (-1); + + hdc = GetDC(NULL); + bmi.bmiHeader.biSize = sizeof(BITMAPINFO); + bmi.bmiHeader.biWidth = width; + bmi.bmiHeader.biHeight = negHeight; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = bpp; + bmi.bmiHeader.biCompression = BI_RGB; + bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0); + + if (data != NULL) + freerdp_image_convert(data, cdata, width, height, bpp, bpp, wfi->clrconv); + + if (pdata != NULL) + *pdata = cdata; + + ReleaseDC(NULL, hdc); + GdiFlush(); + + return bitmap; +} + +wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) +{ + HDC hdc; + wfBitmap* image; + + hdc = GetDC(NULL); + image = (wfBitmap*) malloc(sizeof(wfBitmap)); + image->hdc = CreateCompatibleDC(hdc); + + if (data == NULL) + image->bitmap = CreateCompatibleBitmap(hdc, width, height); + else + image->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(image->pdata)); + + image->org_bitmap = (HBITMAP) SelectObject(image->hdc, image->bitmap); + ReleaseDC(NULL, hdc); + + return image; +} + +wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) +{ + HDC hdc; + wfBitmap* bitmap; + + hdc = GetDC(NULL); + bitmap = (wfBitmap*) malloc(sizeof(wfBitmap)); + bitmap->hdc = CreateCompatibleDC(hdc); + bitmap->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(bitmap->pdata)); + bitmap->org_bitmap = (HBITMAP) SelectObject(bitmap->hdc, bitmap->bitmap); + ReleaseDC(NULL, hdc); + + return bitmap; +} + +void wf_image_free(wfBitmap* image) +{ + if (image != 0) + { + SelectObject(image->hdc, image->org_bitmap); + DeleteObject(image->bitmap); + DeleteDC(image->hdc); + free(image); + } +} + +/* Bitmap Class */ + +void wf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) +{ + HDC hdc; + wfBitmap* wf_bitmap = (wfBitmap*) bitmap; + wfInfo* wfi = ((wfContext*) context)->wfi; + + wf_bitmap = (wfBitmap*) bitmap; + + hdc = GetDC(NULL); + wf_bitmap->hdc = CreateCompatibleDC(hdc); + + if (bitmap->data == NULL) + wf_bitmap->bitmap = CreateCompatibleBitmap(hdc, bitmap->width, bitmap->height); + else + wf_bitmap->bitmap = wf_create_dib(wfi, bitmap->width, bitmap->height, bitmap->bpp, bitmap->data, NULL); + + wf_bitmap->org_bitmap = (HBITMAP) SelectObject(wf_bitmap->hdc, wf_bitmap->bitmap); + ReleaseDC(NULL, hdc); +} + +void wf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +{ + wfBitmap* wf_bitmap = (wfBitmap*) bitmap; + + if (wf_bitmap != 0) + { + SelectObject(wf_bitmap->hdc, wf_bitmap->org_bitmap); + DeleteObject(wf_bitmap->bitmap); + DeleteDC(wf_bitmap->hdc); + } +} + +void wf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) +{ + int width, height; + wfBitmap* wf_bitmap = (wfBitmap*) bitmap; + wfInfo* wfi = ((wfContext*) context)->wfi; + + width = bitmap->right - bitmap->left + 1; + height = bitmap->bottom - bitmap->top + 1; + + BitBlt(wfi->primary->hdc, bitmap->left, bitmap->top, + width, height, wf_bitmap->hdc, 0, 0, SRCCOPY); + + wf_invalidate_region(wfi, bitmap->left, bitmap->top, width, height); +} + +void wf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed) +{ + uint16 size; + + size = width * height * (bpp / 8); + + if (bitmap->data == NULL) + bitmap->data = (uint8*) xmalloc(size); + else + bitmap->data = (uint8*) xrealloc(bitmap->data, size); + + if (compressed) + { + boolean status; + + status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); + + if (status != true) + { + printf("Bitmap Decompression Failed\n"); + } + } + else + { + freerdp_image_flip(data, bitmap->data, width, height, bpp); + } + + bitmap->compressed = false; + bitmap->length = size; + bitmap->bpp = bpp; +} + +void wf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primary) +{ + wfInfo* wfi = ((wfContext*) context)->wfi; + + if (primary) + wfi->drawing = wfi->primary; + else + wfi->drawing = (wfBitmap*) bitmap; +} + +/* Pointer Class */ + +void wf_Pointer_New(rdpContext* context, rdpPointer* pointer) +{ + +} + +void wf_Pointer_Free(rdpContext* context, rdpPointer* pointer) +{ + +} + +void wf_Pointer_Set(rdpContext* context, rdpPointer* pointer) +{ + +} + +/* Graphics Module */ + +void wf_register_graphics(rdpGraphics* graphics) +{ + rdpBitmap bitmap; + rdpPointer pointer; + + memset(&bitmap, 0, sizeof(rdpBitmap)); + bitmap.size = sizeof(wfBitmap); + bitmap.New = wf_Bitmap_New; + bitmap.Free = wf_Bitmap_Free; + bitmap.Paint = wf_Bitmap_Paint; + bitmap.Decompress = wf_Bitmap_Decompress; + bitmap.SetSurface = wf_Bitmap_SetSurface; + + memset(&pointer, 0, sizeof(rdpPointer)); + pointer.size = sizeof(wfPointer); + pointer.New = wf_Pointer_New; + pointer.Free = wf_Pointer_Free; + pointer.Set = wf_Pointer_Set; + + graphics_register_bitmap(graphics, &bitmap); + graphics_register_pointer(graphics, &pointer); +} diff --git a/client/Windows/wf_graphics.h b/client/Windows/wf_graphics.h new file mode 100644 index 0000000..024d3f7 --- /dev/null +++ b/client/Windows/wf_graphics.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Graphical Objects + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WF_GRAPHICS_H +#define __WF_GRAPHICS_H + +#include "wfreerdp.h" + +HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, uint8** pdata); +wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); +wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); +void wf_image_free(wfBitmap* image); + +void wf_register_graphics(rdpGraphics* graphics); + +#endif /* WF_GRAPHICS */ diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c new file mode 100644 index 0000000..cf27244 --- /dev/null +++ b/client/Windows/wfreerdp.c @@ -0,0 +1,682 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Client + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "wf_gdi.h" +#include "wf_graphics.h" + +#include "wfreerdp.h" + +struct _thread_data +{ + freerdp* instance; +}; +typedef struct _thread_data thread_data; + +HANDLE g_done_event; +HINSTANCE g_hInstance; +HCURSOR g_default_cursor; +volatile int g_thread_count = 0; +LPCTSTR g_wnd_class_name = L"wfreerdp"; + +void wf_context_new(freerdp* instance, rdpContext* context) +{ + context->channels = freerdp_channels_new(); +} + +void wf_context_free(freerdp* instance, rdpContext* context) +{ + +} + +int wf_create_console(void) +{ + if (!AllocConsole()) + return 1; + + freopen("CONOUT$", "w", stdout); + printf("Debug console created.\n"); + + return 0; +} + +void wf_sw_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +void wf_sw_end_paint(rdpContext* context) +{ + int i; + rdpGdi* gdi; + wfInfo* wfi; + sint32 x, y; + uint32 w, h; + int ninvalid; + RECT update_rect; + HGDI_RGN cinvalid; + + gdi = context->gdi; + wfi = ((wfContext*) context)->wfi; + + if (gdi->primary->hdc->hwnd->ninvalid < 1) + return; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + for (i = 0; i < ninvalid; i++) + { + x = cinvalid[i].x; + y = cinvalid[i].y; + w = cinvalid[i].w; + h = cinvalid[i].h; + + update_rect.left = x; + update_rect.top = y; + update_rect.right = x + w - 1; + update_rect.bottom = y + h - 1; + + InvalidateRect(wfi->hwnd, &update_rect, FALSE); + } +} + +void wf_hw_begin_paint(rdpContext* context) +{ + wfInfo* wfi = ((wfContext*) context)->wfi; + wfi->hdc->hwnd->invalid->null = 1; + wfi->hdc->hwnd->ninvalid = 0; +} + +void wf_hw_end_paint(rdpContext* context) +{ + +} + +boolean wf_pre_connect(freerdp* instance) +{ + int i1; + wfInfo* wfi; + wfContext* context; + rdpSettings* settings; + + wfi = (wfInfo*) xzalloc(sizeof(wfInfo)); + context = (wfContext*) instance->context; + wfi->instance = instance; + context->wfi = wfi; + + settings = instance->settings; + + settings->os_major_type = OSMAJORTYPE_WINDOWS; + settings->os_minor_type = OSMINORTYPE_WINDOWS_NT; + settings->order_support[NEG_DSTBLT_INDEX] = true; + settings->order_support[NEG_PATBLT_INDEX] = true; + settings->order_support[NEG_SCRBLT_INDEX] = true; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; + settings->order_support[NEG_MULTIPATBLT_INDEX] = false; + settings->order_support[NEG_MULTISCRBLT_INDEX] = false; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_LINETO_INDEX] = true; + settings->order_support[NEG_POLYLINE_INDEX] = true; + settings->order_support[NEG_MEMBLT_INDEX] = true; + settings->order_support[NEG_MEM3BLT_INDEX] = false; + settings->order_support[NEG_SAVEBITMAP_INDEX] = false; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = false; + settings->order_support[NEG_FAST_INDEX_INDEX] = false; + settings->order_support[NEG_FAST_GLYPH_INDEX] = false; + settings->order_support[NEG_POLYGON_SC_INDEX] = false; + settings->order_support[NEG_POLYGON_CB_INDEX] = false; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; + + settings->glyph_cache = false; + + wfi->cursor = g_default_cursor; + + wfi->fullscreen = settings->fullscreen; + wfi->fs_toggle = wfi->fullscreen; + wfi->sw_gdi = settings->sw_gdi; + + wfi->clrconv = (HCLRCONV) xzalloc(sizeof(CLRCONV)); + wfi->clrconv->palette = NULL; + wfi->clrconv->alpha = 0; + + instance->context->cache = cache_new(settings); + + if (wfi->percentscreen > 0) + { + i1 = (GetSystemMetrics(SM_CXSCREEN) * wfi->percentscreen) / 100; + settings->width = i1; + + i1 = (GetSystemMetrics(SM_CYSCREEN) * wfi->percentscreen) / 100; + settings->height = i1; + } + + if (wfi->fs_toggle) + { + settings->width = GetSystemMetrics(SM_CXSCREEN); + settings->height = GetSystemMetrics(SM_CYSCREEN); + } + + i1 = settings->width; + i1 = (i1 + 3) & (~3); + settings->width = i1; + + if ((settings->width < 64) || (settings->height < 64) || + (settings->width > 4096) || (settings->height > 4096)) + { + printf("wf_pre_connect: invalid dimensions %d %d\n", settings->width, settings->height); + return 1; + } + + settings->kbd_layout = (int) GetKeyboardLayout(0) & 0x0000FFFF; + freerdp_channels_pre_connect(instance->context->channels, instance); + + return true; +} + +void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) +{ +#if defined(__GNUC__) +#if defined(__i386__) || defined(__x86_64__) + *eax = info; + __asm volatile + ("mov %%ebx, %%edi;" /* 32bit PIC: don't clobber ebx */ + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + :"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : :"edi"); +#endif +#elif defined(_MSC_VER) + int a[4]; + __cpuid(a, info); + *eax = a[0]; + *ebx = a[1]; + *ecx = a[2]; + *edx = a[3]; +#endif +} + +uint32 wfi_detect_cpu() +{ + uint32 cpu_opt = 0; + unsigned int eax, ebx, ecx, edx = 0; + + cpuid(1, &eax, &ebx, &ecx, &edx); + + if (edx & (1<<26)) + { + cpu_opt |= CPU_SSE2; + } + + return cpu_opt; +} + +boolean wf_post_connect(freerdp* instance) +{ + rdpGdi* gdi; + wfInfo* wfi; + rdpCache* cache; + wfContext* context; + int width, height; + wchar_t win_title[64]; + rdpSettings* settings; + + settings = instance->settings; + context = (wfContext*) instance->context; + cache = instance->context->cache; + wfi = context->wfi; + + wfi->dstBpp = 32; + width = settings->width; + height = settings->height; + + if (wfi->sw_gdi) + { + gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_32BPP, NULL); + gdi = instance->context->gdi; + wfi->hdc = gdi->primary->hdc; + wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, gdi->primary_buffer); + + rfx_context_set_cpu_opt(gdi->rfx_context, wfi_detect_cpu()); + } + else + { + wf_gdi_register_update_callbacks(instance->update); + wfi->srcBpp = instance->settings->color_depth; + wfi->primary = wf_image_new(wfi, width, height, wfi->dstBpp, NULL); + + wfi->hdc = gdi_GetDC(); + wfi->hdc->bitsPerPixel = wfi->dstBpp; + wfi->hdc->bytesPerPixel = wfi->dstBpp / 8; + + wfi->hdc->alpha = wfi->clrconv->alpha; + wfi->hdc->invert = wfi->clrconv->invert; + + wfi->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + wfi->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + wfi->hdc->hwnd->invalid->null = 1; + + wfi->hdc->hwnd->count = 32; + wfi->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * wfi->hdc->hwnd->count); + wfi->hdc->hwnd->ninvalid = 0; + + wfi->image = wf_bitmap_new(wfi, 64, 64, 32, NULL); + wfi->image->_bitmap.data = NULL; + + if (settings->rfx_codec) + { + wfi->tile = wf_bitmap_new(wfi, 64, 64, 32, NULL); + wfi->rfx_context = rfx_context_new(); + rfx_context_set_cpu_opt(wfi->rfx_context, wfi_detect_cpu()); + } + + if (settings->ns_codec) + wfi->nsc_context = nsc_context_new(); + } + + if (settings->window_title != NULL) + _snwprintf(win_title, sizeof(win_title), L"%S", settings->window_title); + else if (settings->port == 3389) + _snwprintf(win_title, sizeof(win_title) / sizeof(win_title[0]), L"FreeRDP: %S", settings->hostname); + else + _snwprintf(win_title, sizeof(win_title) / sizeof(win_title[0]), L"FreeRDP: %S:%d", settings->hostname, settings->port); + + if (wfi->hwnd == 0) + { + wfi->hwnd = CreateWindowEx((DWORD) NULL, g_wnd_class_name, win_title, + 0, 0, 0, 0, 0, NULL, NULL, g_hInstance, NULL); + + SetWindowLongPtr(wfi->hwnd, GWLP_USERDATA, (LONG_PTR) wfi); + } + + if (wfi->fullscreen) + { + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_POPUP); + SetWindowPos(wfi->hwnd, HWND_TOP, 0, 0, width, height, SWP_FRAMECHANGED); + } + else + { + POINT diff; + RECT rc_client, rc_wnd; + + SetWindowLongPtr(wfi->hwnd, GWL_STYLE, WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX); + /* Now resize to get full canvas size and room for caption and borders */ + SetWindowPos(wfi->hwnd, HWND_TOP, 10, 10, width, height, SWP_FRAMECHANGED); + GetClientRect(wfi->hwnd, &rc_client); + GetWindowRect(wfi->hwnd, &rc_wnd); + diff.x = (rc_wnd.right - rc_wnd.left) - rc_client.right; + diff.y = (rc_wnd.bottom - rc_wnd.top) - rc_client.bottom; + SetWindowPos(wfi->hwnd, HWND_TOP, -1, -1, width + diff.x, height + diff.y, SWP_NOMOVE | SWP_FRAMECHANGED); + } + + BitBlt(wfi->primary->hdc, 0, 0, width, height, NULL, 0, 0, BLACKNESS); + wfi->drawing = wfi->primary; + + ShowWindow(wfi->hwnd, SW_SHOWNORMAL); + UpdateWindow(wfi->hwnd); + + if (wfi->sw_gdi) + { + instance->update->BeginPaint = wf_sw_begin_paint; + instance->update->EndPaint = wf_sw_end_paint; + } + else + { + instance->update->BeginPaint = wf_hw_begin_paint; + instance->update->EndPaint = wf_hw_end_paint; + } + + pointer_cache_register_callbacks(instance->update); + + if (wfi->sw_gdi != true) + { + brush_cache_register_callbacks(instance->update); + bitmap_cache_register_callbacks(instance->update); + offscreen_cache_register_callbacks(instance->update); + } + + wf_register_graphics(instance->context->graphics); + + freerdp_channels_post_connect(instance->context->channels, instance); + + return true; +} + +boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +{ + return true; +} + +int wf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) +{ + return freerdp_channels_data(instance, channelId, data, size, flags, total_size); +} + +void wf_process_channel_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + + event = freerdp_channels_pop_event(channels); + + if (event) + freerdp_event_free(event); +} + +boolean wf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +{ + return true; +} + +boolean wf_check_fds(freerdp* instance) +{ + return true; +} + +int wf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChannels* channels = (rdpChannels*) user_data; + + printf("loading plugin %s\n", name); + freerdp_channels_load_plugin(channels, settings, name, plugin_data); + + return 1; +} + +int wf_process_client_args(rdpSettings* settings, const char* opt, const char* val, void* user_data) +{ + return 0; +} + +int wfreerdp_run(freerdp* instance) +{ + MSG msg; + int index; + int rcount; + int wcount; + BOOL msg_ret; + int quit_msg; + void* rfds[32]; + void* wfds[32]; + int fds_count; + HANDLE fds[64]; + rdpChannels* channels; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); + + if (freerdp_connect(instance) != true) + return 0; + + channels = instance->context->channels; + + while (1) + { + rcount = 0; + wcount = 0; + + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get wfreerdp file descriptor\n"); + break; + } + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get channel manager file descriptor\n"); + break; + } + + fds_count = 0; + /* setup read fds */ + for (index = 0; index < rcount; index++) + { + fds[fds_count++] = rfds[index]; + } + /* setup write fds */ + for (index = 0; index < wcount; index++) + { + fds[fds_count++] = wfds[index]; + } + /* exit if nothing to do */ + if (fds_count == 0) + { + printf("wfreerdp_run: fds_count is zero\n"); + break; + } + + /* do the wait */ + if (MsgWaitForMultipleObjects(fds_count, fds, FALSE, 1, QS_ALLINPUT) == WAIT_FAILED) + { + printf("wfreerdp_run: WaitForMultipleObjects failed: 0x%04X\n", GetLastError()); + break; + } + + if (freerdp_check_fds(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + if (wf_check_fds(instance) != true) + { + printf("Failed to check wfreerdp file descriptor\n"); + break; + } + if (freerdp_channels_check_fds(channels, instance) != true) + { + printf("Failed to check channel manager file descriptor\n"); + break; + } + wf_process_channel_event(channels, instance); + + quit_msg = FALSE; + while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) + { + msg_ret = GetMessage(&msg, NULL, 0, 0); + + if (msg_ret == 0 || msg_ret == -1) + { + quit_msg = TRUE; + break; + } + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (quit_msg) + break; + } + + /* cleanup */ + freerdp_channels_free(channels); + freerdp_free(instance); + + return 0; +} + +static DWORD WINAPI thread_func(LPVOID lpParam) +{ + wfInfo* wfi; + freerdp* instance; + thread_data* data; + + data = (thread_data*) lpParam; + instance = data->instance; + + wfi = (wfInfo*) xzalloc(sizeof(wfInfo)); + ((wfContext*) instance->context)->wfi = wfi; + wfi->instance = instance; + + wfreerdp_run(instance); + + g_thread_count--; + + if (g_thread_count < 1) + SetEvent(g_done_event); + + return (DWORD) NULL; +} + +static DWORD WINAPI kbd_thread_func(LPVOID lpParam) +{ + MSG msg; + BOOL status; + HHOOK hook_handle; + + hook_handle = SetWindowsHookEx(WH_KEYBOARD_LL, wf_ll_kbd_proc, g_hInstance, 0); + + if (hook_handle) + { + while ((status = GetMessage( &msg, NULL, 0, 0 )) != 0) + { + if (status == -1) + { + printf("keyboard thread error getting message\n"); + break; + } + else + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + UnhookWindowsHookEx(hook_handle); + } + else + printf("failed to install keyboard hook\n"); + + return (DWORD) NULL; +} + +INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + freerdp* instance; + thread_data* data; + WSADATA wsa_data; + WNDCLASSEX wnd_cls; + + if (NULL == getenv("HOME")) + { + char home[MAX_PATH * 2] = "HOME="; + strcat(home, getenv("HOMEDRIVE")); + strcat(home, getenv("HOMEPATH")); + _putenv(home); + } + + if (WSAStartup(0x101, &wsa_data) != 0) + return 1; + + g_done_event = CreateEvent(0, 1, 0, 0); + +#if defined(WITH_DEBUG) || defined(_DEBUG) + wf_create_console(); +#endif + + g_default_cursor = LoadCursor(NULL, IDC_ARROW); + + wnd_cls.cbSize = sizeof(WNDCLASSEX); + wnd_cls.style = CS_HREDRAW | CS_VREDRAW; + wnd_cls.lpfnWndProc = wf_event_proc; + wnd_cls.cbClsExtra = 0; + wnd_cls.cbWndExtra = 0; + wnd_cls.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wnd_cls.hCursor = g_default_cursor; + wnd_cls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wnd_cls.lpszMenuName = NULL; + wnd_cls.lpszClassName = g_wnd_class_name; + wnd_cls.hInstance = hInstance; + wnd_cls.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + RegisterClassEx(&wnd_cls); + + g_hInstance = hInstance; + freerdp_channels_global_init(); + + instance = freerdp_new(); + instance->PreConnect = wf_pre_connect; + instance->PostConnect = wf_post_connect; + instance->VerifyCertificate = wf_verify_certificate; + instance->ReceiveChannelData = wf_receive_channel_data; + + instance->context_size = sizeof(wfContext); + instance->ContextNew = wf_context_new; + instance->ContextFree = wf_context_free; + freerdp_context_new(instance); + + instance->context->argc = __argc; + instance->context->argv = __argv; + + if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL)) + printf("error creating keyboard handler thread"); + + //while (1) + { + data = (thread_data*) xzalloc(sizeof(thread_data)); + data->instance = instance; + + freerdp_parse_args(instance->settings, __argc, __argv, + wf_process_plugin_args, instance->context->channels, wf_process_client_args, NULL); + + if (CreateThread(NULL, 0, thread_func, data, 0, NULL) != 0) + g_thread_count++; + } + + if (g_thread_count > 0) + WaitForSingleObject(g_done_event, INFINITE); + else + MessageBox(GetConsoleWindow(), + L"Failed to start wfreerdp.\n\nPlease check the debug output.", + L"FreeRDP Error", MB_ICONSTOP); + + WSACleanup(); + +#ifdef _DEBUG + system("pause"); +#endif + + return 0; +} diff --git a/client/Windows/wfreerdp.h b/client/Windows/wfreerdp.h new file mode 100644 index 0000000..2841c02 --- /dev/null +++ b/client/Windows/wfreerdp.h @@ -0,0 +1,99 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windows Client + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WFREERDP_H +#define __WFREERDP_H + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wf_event.h" + +struct wf_bitmap +{ + rdpBitmap _bitmap; + HDC hdc; + HBITMAP bitmap; + HBITMAP org_bitmap; + uint8* pdata; +}; +typedef struct wf_bitmap wfBitmap; + +struct wf_pointer +{ + rdpPointer pointer; +}; +typedef struct wf_pointer wfPointer; + +typedef struct wf_info wfInfo; + +struct wf_context +{ + rdpContext _p; + + wfInfo* wfi; +}; +typedef struct wf_context wfContext; + +struct wf_info +{ + int fs_toggle; + int fullscreen; + int percentscreen; + char window_title[64]; + + HWND hwnd; + HGDI_DC hdc; + uint16 srcBpp; + uint16 dstBpp; + freerdp* instance; + wfBitmap* primary; + wfBitmap* drawing; + HCLRCONV clrconv; + HCURSOR cursor; + HBRUSH brush; + HBRUSH org_brush; + RECT update_rect; + + wfBitmap* tile; + wfBitmap* image; + RFX_CONTEXT* rfx_context; + NSC_CONTEXT* nsc_context; + + boolean sw_gdi; +}; + +#endif diff --git a/client/X11/CMakeLists.txt b/client/X11/CMakeLists.txt new file mode 100644 index 0000000..29f9ad8 --- /dev/null +++ b/client/X11/CMakeLists.txt @@ -0,0 +1,98 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP X11 Client +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(FindXmlto) +include_directories(${X11_INCLUDE_DIRS}) + +add_executable(xfreerdp + xf_gdi.c + xf_gdi.h + xf_rail.c + xf_rail.h + xf_tsmf.c + xf_tsmf.h + xf_event.c + xf_event.h + xf_cliprdr.c + xf_cliprdr.h + xf_monitor.c + xf_monitor.h + xf_graphics.c + xf_graphics.h + xf_keyboard.c + xf_keyboard.h + xf_window.c + xf_window.h + xfreerdp.c + xfreerdp.h) + +if(WITH_MANPAGES) + if(XMLTO_FOUND) + add_custom_command(OUTPUT xfreerdp.1 + COMMAND ${XMLTO_EXECUTABLE} man ${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp.1.xml + DEPENDS xfreerdp.1.xml) + + add_custom_target(xfreerdp.manpage ALL + DEPENDS xfreerdp.1) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION share/man/man1) + else(XMLTO_FOUND) + message(WARNING "WITH_MANPAGES was set, but xmlto was not found. man-pages will not be installed") + endif(XMLTO_FOUND) +endif(WITH_MANPAGES) + +find_suggested_package(Xinerama) +if(WITH_XINERAMA) + add_definitions(-DWITH_XINERAMA -DWITH_XEXT) + include_directories(${XINERAMA_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XINERAMA_LIBRARIES}) +endif() + +find_suggested_package(Xext) +if(WITH_XEXT) + add_definitions(-DWITH_XEXT) + include_directories(${XEXT_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XEXT_LIBRARIES}) +endif() + +find_suggested_package(Xcursor) +if(WITH_XCURSOR) + add_definitions(-DWITH_XCURSOR) + include_directories(${XCURSOR_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XCURSOR_LIBRARIES}) +endif() + +find_suggested_package(Xv) +if(WITH_XV) + add_definitions(-DWITH_XV) + include_directories(${XV_INCLUDE_DIRS}) + target_link_libraries(xfreerdp ${XV_LIBRARIES}) +endif() + +include_directories(${CMAKE_SOURCE_DIR}/resources) + +target_link_libraries(xfreerdp freerdp-core) +target_link_libraries(xfreerdp freerdp-gdi) +target_link_libraries(xfreerdp freerdp-kbd) +target_link_libraries(xfreerdp freerdp-rail) +target_link_libraries(xfreerdp freerdp-channels) +target_link_libraries(xfreerdp freerdp-utils) +target_link_libraries(xfreerdp ${X11_LIBRARIES} ${CMAKE_DL_LIBS}) + +install(TARGETS xfreerdp DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c new file mode 100644 index 0000000..fb36bea --- /dev/null +++ b/client/X11/xf_cliprdr.c @@ -0,0 +1,1235 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Clipboard Redirection + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xf_cliprdr.h" + +typedef struct clipboard_format_mapping clipboardFormatMapping; +struct clipboard_format_mapping +{ + Atom target_format; + uint32 format_id; +}; + +typedef struct clipboard_context clipboardContext; +struct clipboard_context +{ + rdpChannels* channels; + Window root_window; + Atom clipboard_atom; + Atom property_atom; + Atom identity_atom; + + clipboardFormatMapping format_mappings[20]; + int num_format_mappings; + + /* server->client data */ + uint32* formats; + int num_formats; + Atom targets[20]; + int num_targets; + uint8* data; + uint32 data_format; + uint32 data_alt_format; + int data_length; + XEvent* respond; + + /* client->server data */ + Window owner; + int request_index; + boolean sync; + + /* INCR mechanism */ + Atom incr_atom; + boolean incr_starts; + uint8* incr_data; + int incr_data_length; +}; + +void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman) +{ + int n; + uint32 id; + clipboardContext* cb; + + cb = xnew(clipboardContext); + xfi->clipboard_context = cb; + + cb->channels = chanman; + cb->request_index = -1; + + cb->root_window = DefaultRootWindow(xfi->display); + cb->clipboard_atom = XInternAtom(xfi->display, "CLIPBOARD", false); + + if (cb->clipboard_atom == None) + { + DEBUG_WARN("unable to get CLIPBOARD atom"); + } + + id = 1; + cb->property_atom = XInternAtom(xfi->display, "_FREERDP_CLIPRDR", false); + cb->identity_atom = XInternAtom(xfi->display, "_FREERDP_CLIPRDR_ID", false); + + XChangeProperty(xfi->display, xfi->drawable, cb->identity_atom, + XA_INTEGER, 32, PropModeReplace, (uint8*) &id, 1); + + XSelectInput(xfi->display, cb->root_window, PropertyChangeMask); + + n = 0; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "_FREERDP_RAW", false); + cb->format_mappings[n].format_id = CB_FORMAT_RAW; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "UTF8_STRING", false); + cb->format_mappings[n].format_id = CB_FORMAT_UNICODETEXT; + + n++; + cb->format_mappings[n].target_format = XA_STRING; + cb->format_mappings[n].format_id = CB_FORMAT_TEXT; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/png", false); + cb->format_mappings[n].format_id = CB_FORMAT_PNG; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/jpeg", false); + cb->format_mappings[n].format_id = CB_FORMAT_JPEG; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/gif", false); + cb->format_mappings[n].format_id = CB_FORMAT_GIF; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "image/bmp", false); + cb->format_mappings[n].format_id = CB_FORMAT_DIB; + + n++; + cb->format_mappings[n].target_format = XInternAtom(xfi->display, "text/html", false); + cb->format_mappings[n].format_id = CB_FORMAT_HTML; + + cb->num_format_mappings = n + 1; + cb->targets[0] = XInternAtom(xfi->display, "TIMESTAMP", false); + cb->targets[1] = XInternAtom(xfi->display, "TARGETS", false); + cb->num_targets = 2; + + cb->incr_atom = XInternAtom(xfi->display, "INCR", false); +} + +void xf_cliprdr_uninit(xfInfo* xfi) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (cb) + { + xfree(cb->formats); + xfree(cb->data); + xfree(cb->respond); + xfree(cb->incr_data); + xfree(cb); + xfi->clipboard_context = NULL; + } +} + +static uint8* lf2crlf(uint8* data, int* size) +{ + uint8 c; + uint8* outbuf; + uint8* out; + uint8* in_end; + uint8* in; + int out_size; + + out_size = (*size) * 2 + 1; + outbuf = (uint8*) xzalloc(out_size); + out = outbuf; + in = data; + in_end = data + (*size); + + while (in < in_end) + { + c = *in++; + if (c == '\n') + { + *out++ = '\r'; + *out++ = '\n'; + } + else + { + *out++ = c; + } + } + + *out++ = 0; + *size = out - outbuf; + + return outbuf; +} + +static void crlf2lf(uint8* data, int* size) +{ + uint8 c; + uint8* out; + uint8* in; + uint8* in_end; + + out = data; + in = data; + in_end = data + (*size); + + while (in < in_end) + { + c = *in++; + + if (c != '\r') + *out++ = c; + } + + *size = out - data; +} + +static void be2le(uint8* data, int size) +{ + uint8 c; + + while (size >= 2) + { + c = data[0]; + data[0] = data[1]; + data[1] = c; + + data += 2; + size -= 2; + } +} + +static boolean xf_cliprdr_is_self_owned(xfInfo* xfi) +{ + Atom type; + uint32 id = 0; + uint32* pid = NULL; + int format, result = 0; + unsigned long length, bytes_left; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + cb->owner = XGetSelectionOwner(xfi->display, cb->clipboard_atom); + + if (cb->owner != None) + { + result = XGetWindowProperty(xfi->display, cb->owner, + cb->identity_atom, 0, 4, 0, XA_INTEGER, + &type, &format, &length, &bytes_left, (uint8**) &pid); + } + + if (pid) + { + id = *pid; + XFree(pid); + } + + if ((cb->owner == None) || (cb->owner == xfi->drawable)) + return false; + + if (result != Success) + return false; + + return (id ? true : false); +} + +static int xf_cliprdr_select_format_by_id(clipboardContext* cb, uint32 format_id) +{ + int i; + + for (i = 0; i < cb->num_format_mappings; i++) + { + if (cb->format_mappings[i].format_id == format_id) + return i; + } + + return -1; +} + +static int xf_cliprdr_select_format_by_atom(clipboardContext* cb, Atom target) +{ + int i; + int j; + + if (cb->formats == NULL) + return -1; + + for (i = 0; i < cb->num_format_mappings; i++) + { + if (cb->format_mappings[i].target_format != target) + continue; + + if (cb->format_mappings[i].format_id == CB_FORMAT_RAW) + return i; + + for (j = 0; j < cb->num_formats; j++) + { + if (cb->format_mappings[i].format_id == cb->formats[j]) + return i; + } + } + + return -1; +} + +static void xf_cliprdr_send_raw_format_list(xfInfo* xfi) +{ + Atom type; + uint8* format_data; + int format, result; + unsigned long length, bytes_left; + RDP_CB_FORMAT_LIST_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + result = XGetWindowProperty(xfi->display, cb->root_window, + cb->property_atom, 0, 3600, 0, XA_STRING, + &type, &format, &length, &bytes_left, (uint8**) &format_data); + + if (result != Success) + { + DEBUG_WARN("XGetWindowProperty failed"); + return; + } + DEBUG_X11_CLIPRDR("format=%d len=%d bytes_left=%d", format, (int) length, (int) bytes_left); + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + event->raw_format_data = (uint8*) xmalloc(length); + memcpy(event->raw_format_data, format_data, length); + event->raw_format_data_size = length; + XFree(format_data); + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); +} + +static void xf_cliprdr_send_null_format_list(xfInfo* xfi) +{ + RDP_CB_FORMAT_LIST_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + event->num_formats = 0; + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); +} + +static void xf_cliprdr_send_supported_format_list(xfInfo* xfi) +{ + int i; + RDP_CB_FORMAT_LIST_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + event->formats = (uint32*) xmalloc(sizeof(uint32) * cb->num_format_mappings); + event->num_formats = cb->num_format_mappings; + + for (i = 0; i < cb->num_format_mappings; i++) + event->formats[i] = cb->format_mappings[i].format_id; + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); +} + +static void xf_cliprdr_send_format_list(xfInfo* xfi) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (xf_cliprdr_is_self_owned(xfi)) + { + xf_cliprdr_send_raw_format_list(xfi); + } + else if (cb->owner == None) + { + xf_cliprdr_send_null_format_list(xfi); + } + else if (cb->owner != xfi->drawable) + { + /* Request the owner for TARGETS, and wait for SelectionNotify event */ + XConvertSelection(xfi->display, cb->clipboard_atom, + cb->targets[1], cb->property_atom, xfi->drawable, CurrentTime); + } +} + +static void xf_cliprdr_send_data_request(xfInfo* xfi, uint32 format) +{ + RDP_CB_DATA_REQUEST_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + event = (RDP_CB_DATA_REQUEST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_REQUEST, NULL, NULL); + + event->format = format; + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); +} + +static void xf_cliprdr_send_data_response(xfInfo* xfi, uint8* data, int size) +{ + RDP_CB_DATA_RESPONSE_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + event = (RDP_CB_DATA_RESPONSE_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_DATA_RESPONSE, NULL, NULL); + + event->data = data; + event->size = size; + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); +} + +static void xf_cliprdr_send_null_data_response(xfInfo* xfi) +{ + xf_cliprdr_send_data_response(xfi, NULL, 0); +} + +static void xf_cliprdr_process_cb_monitor_ready_event(xfInfo* xfi) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + xf_cliprdr_send_format_list(xfi); + cb->sync = true; +} + +static void xf_cliprdr_process_cb_data_request_event(xfInfo* xfi, RDP_CB_DATA_REQUEST_EVENT* event) +{ + int i; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + DEBUG_X11_CLIPRDR("format %d", event->format); + + if (xf_cliprdr_is_self_owned(xfi)) + { + /* CB_FORMAT_RAW */ + i = 0; + XChangeProperty(xfi->display, xfi->drawable, cb->property_atom, + XA_INTEGER, 32, PropModeReplace, (uint8*) &event->format, 1); + } + else + { + i = xf_cliprdr_select_format_by_id(cb, event->format); + } + + if (i < 0) + { + DEBUG_X11_CLIPRDR("unsupported format requested"); + xf_cliprdr_send_null_data_response(xfi); + } + else + { + cb->request_index = i; + + DEBUG_X11_CLIPRDR("target=%d", (int) cb->format_mappings[i].target_format); + + XConvertSelection(xfi->display, cb->clipboard_atom, + cb->format_mappings[i].target_format, cb->property_atom, + xfi->drawable, CurrentTime); + XFlush(xfi->display); + /* After this point, we expect a SelectionNotify event from the clipboard owner. */ + } +} + +static void xf_cliprdr_get_requested_targets(xfInfo* xfi) +{ + int num; + int i, j; + Atom atom; + int format; + uint8* data = NULL; + unsigned long length, bytes_left; + RDP_CB_FORMAT_LIST_EVENT* event; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + XGetWindowProperty(xfi->display, xfi->drawable, cb->property_atom, + 0, 200, 0, XA_ATOM, + &atom, &format, &length, &bytes_left, &data); + + DEBUG_X11_CLIPRDR("type=%d format=%d length=%d bytes_left=%d", + (int) atom, format, (int) length, (int) bytes_left); + + if (length > 0) + { + event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + event->formats = (uint32*) xmalloc(sizeof(uint32) * cb->num_format_mappings); + num = 0; + for (i = 0; i < length; i++) + { + atom = ((Atom*) data)[i]; + DEBUG_X11("atom %d", (int) atom); + for (j = 0; j < cb->num_format_mappings; j++) + { + if (cb->format_mappings[j].target_format == atom) + { + DEBUG_X11("found format %d for atom %d", + cb->format_mappings[j].format_id, (int)atom); + event->formats[num++] = cb->format_mappings[j].format_id; + break; + } + } + } + event->num_formats = num; + XFree(data); + + freerdp_channels_send_event(cb->channels, (RDP_EVENT*) event); + } + else + { + if (data) + XFree(data); + + xf_cliprdr_send_null_format_list(xfi); + } +} + +static uint8* xf_cliprdr_process_requested_raw(uint8* data, int* size) +{ + uint8* outbuf; + + outbuf = (uint8*) xmalloc(*size); + memcpy(outbuf, data, *size); + return outbuf; +} + +static uint8* xf_cliprdr_process_requested_unicodetext(uint8* data, int* size) +{ + uint8* inbuf; + uint8* outbuf; + size_t out_size; + UNICONV* uniconv; + + inbuf = lf2crlf(data, size); + + uniconv = freerdp_uniconv_new(); + outbuf = (uint8*) freerdp_uniconv_out(uniconv, (char*) inbuf, &out_size); + freerdp_uniconv_free(uniconv); + + xfree(inbuf); + + *size = (int) out_size + 2; + + return outbuf; +} + +static uint8* xf_cliprdr_process_requested_text(uint8* data, int* size) +{ + uint8* outbuf; + + outbuf = lf2crlf(data, size); + + return outbuf; +} + +static uint8* xf_cliprdr_process_requested_dib(uint8* data, int* size) +{ + uint8* outbuf; + + /* length should be at least BMP header (14) + sizeof(BITMAPINFOHEADER) */ + if (*size < 54) + { + DEBUG_X11_CLIPRDR("bmp length %d too short", *size); + return NULL; + } + + *size -= 14; + outbuf = (uint8*) xzalloc(*size); + memcpy(outbuf, data + 14, *size); + + return outbuf; +} + +static uint8* xf_cliprdr_process_requested_html(uint8* data, int* size) +{ + uint8* inbuf; + uint8* in; + uint8* outbuf; + char num[11]; + UNICONV* uniconv; + + inbuf = NULL; + if (*size > 2) + { + if ((uint8) data[0] == 0xFE && (uint8) data[1] == 0xFF) + { + be2le(data, *size); + } + + if ((uint8) data[0] == 0xFF && (uint8) data[1] == 0xFE) + { + uniconv = freerdp_uniconv_new(); + inbuf = (uint8*) freerdp_uniconv_in(uniconv, data + 2, *size - 2); + freerdp_uniconv_free(uniconv); + } + } + if (inbuf == NULL) + { + inbuf = xzalloc(*size + 1); + memcpy(inbuf, data, *size); + } + + outbuf = (uint8*) xzalloc(*size + 200); + strcpy((char*) outbuf, + "Version:0.9\r\n" + "StartHTML:0000000000\r\n" + "EndHTML:0000000000\r\n" + "StartFragment:0000000000\r\n" + "EndFragment:0000000000\r\n"); + + in = (uint8*) strstr((char*) inbuf, ""); + } + strcat((char*) outbuf, ""); + /* StartFragment */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 69, num, 10); + strcat((char*) outbuf, (char*) inbuf); + /* EndFragment */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 93, num, 10); + strcat((char*) outbuf, ""); + if (in == NULL) + { + strcat((char*) outbuf, ""); + } + /* EndHTML */ + snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); + memcpy(outbuf + 43, num, 10); + + *size = strlen((char*) outbuf) + 1; + xfree(inbuf); + + return outbuf; +} + +static void xf_cliprdr_process_requested_data(xfInfo* xfi, boolean has_data, uint8* data, int size) +{ + uint8* outbuf; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (cb->incr_starts && has_data) + return; + + if (!has_data || data == NULL) + { + xf_cliprdr_send_null_data_response(xfi); + return; + } + + switch (cb->format_mappings[cb->request_index].format_id) + { + case CB_FORMAT_RAW: + case CB_FORMAT_PNG: + case CB_FORMAT_JPEG: + case CB_FORMAT_GIF: + outbuf = xf_cliprdr_process_requested_raw(data, &size); + break; + + case CB_FORMAT_UNICODETEXT: + outbuf = xf_cliprdr_process_requested_unicodetext(data, &size); + break; + + case CB_FORMAT_TEXT: + outbuf = xf_cliprdr_process_requested_text(data, &size); + break; + + case CB_FORMAT_DIB: + outbuf = xf_cliprdr_process_requested_dib(data, &size); + break; + + case CB_FORMAT_HTML: + outbuf = xf_cliprdr_process_requested_html(data, &size); + break; + + default: + outbuf = NULL; + break; + } + + if (outbuf) + xf_cliprdr_send_data_response(xfi, outbuf, size); + else + xf_cliprdr_send_null_data_response(xfi); + + /* Resend the format list, otherwise the server won't request again for the next paste */ + xf_cliprdr_send_format_list(xfi); +} + +static boolean xf_cliprdr_get_requested_data(xfInfo* xfi, Atom target) +{ + Atom type; + int format; + uint8* data = NULL; + boolean has_data = false; + unsigned long length, bytes_left, dummy; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if ((cb->request_index < 0) || + (cb->format_mappings[cb->request_index].target_format != target)) + { + DEBUG_X11_CLIPRDR("invalid target"); + xf_cliprdr_send_null_data_response(xfi); + return false; + } + + XGetWindowProperty(xfi->display, xfi->drawable, + cb->property_atom, 0, 0, 0, target, + &type, &format, &length, &bytes_left, &data); + + DEBUG_X11_CLIPRDR("type=%d format=%d bytes=%d request_index=%d", + (int) type, format, (int) bytes_left, cb->request_index); + + if (data) + { + XFree(data); + data = NULL; + } + if (bytes_left <= 0 && !cb->incr_starts) + { + DEBUG_X11("no data"); + } + else if (type == cb->incr_atom) + { + DEBUG_X11("INCR started"); + cb->incr_starts = true; + if (cb->incr_data) + { + xfree(cb->incr_data); + cb->incr_data = NULL; + } + cb->incr_data_length = 0; + /* Data will be followed in PropertyNotify event */ + has_data = true; + } + else + { + if (bytes_left <= 0) + { + /* INCR finish */ + data = cb->incr_data; + cb->incr_data = NULL; + bytes_left = cb->incr_data_length; + cb->incr_data_length = 0; + cb->incr_starts = 0; + DEBUG_X11("INCR finished"); + has_data = true; + } + else if (XGetWindowProperty(xfi->display, xfi->drawable, + cb->property_atom, 0, bytes_left, 0, target, + &type, &format, &length, &dummy, &data) == Success) + { + if (cb->incr_starts) + { + bytes_left = length * format / 8; + DEBUG_X11("%d bytes", (int)bytes_left); + cb->incr_data = (uint8*) xrealloc(cb->incr_data, cb->incr_data_length + bytes_left); + memcpy(cb->incr_data + cb->incr_data_length, data, bytes_left); + cb->incr_data_length += bytes_left; + XFree(data); + data = NULL; + } + has_data = true; + } + else + { + DEBUG_X11_CLIPRDR("XGetWindowProperty failed"); + } + } + XDeleteProperty(xfi->display, xfi->drawable, cb->property_atom); + + xf_cliprdr_process_requested_data(xfi, has_data, data, (int) bytes_left); + + if (data) + XFree(data); + + return true; +} + +static void xf_cliprdr_append_target(clipboardContext* cb, Atom target) +{ + int i; + + if (cb->num_targets >= sizeof(cb->targets) / sizeof(Atom)) + return; + + for (i = 0; i < cb->num_targets; i++) + { + if (cb->targets[i] == target) + return; + } + + cb->targets[cb->num_targets++] = target; +} + +static void xf_cliprdr_provide_targets(xfInfo* xfi, XEvent* respond) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (respond->xselection.property != None) + { + XChangeProperty(xfi->display, + respond->xselection.requestor, + respond->xselection.property, + XA_ATOM, 32, PropModeReplace, + (uint8*) cb->targets, cb->num_targets); + } +} + +static void xf_cliprdr_provide_data(xfInfo* xfi, XEvent* respond) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (respond->xselection.property != None) + { + XChangeProperty(xfi->display, + respond->xselection.requestor, + respond->xselection.property, + respond->xselection.target, 8, PropModeReplace, + (uint8*) cb->data, cb->data_length); + } +} + +static void xf_cliprdr_process_cb_format_list_event(xfInfo* xfi, RDP_CB_FORMAT_LIST_EVENT* event) +{ + int i, j; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (cb->data) + { + xfree(cb->data); + cb->data = NULL; + } + + if (cb->formats) + xfree(cb->formats); + + cb->formats = event->formats; + cb->num_formats = event->num_formats; + event->formats = NULL; + event->num_formats = 0; + + cb->num_targets = 2; + for (i = 0; i < cb->num_formats; i++) + { + for (j = 0; j < cb->num_format_mappings; j++) + { + if (cb->formats[i] == cb->format_mappings[j].format_id) + { + DEBUG_X11("announce format#%d : %d", i, cb->formats[i]); + xf_cliprdr_append_target(cb, cb->format_mappings[j].target_format); + } + } + } + + XSetSelectionOwner(xfi->display, cb->clipboard_atom, xfi->drawable, CurrentTime); + if (event->raw_format_data) + { + XChangeProperty(xfi->display, cb->root_window, cb->property_atom, + XA_STRING, 8, PropModeReplace, + event->raw_format_data, event->raw_format_data_size); + } + + XFlush(xfi->display); +} + +static void xf_cliprdr_process_text(clipboardContext* cb, uint8* data, int size) +{ + cb->data = (uint8*) xmalloc(size); + memcpy(cb->data, data, size); + cb->data_length = size; + crlf2lf(cb->data, &cb->data_length); +} + +static void xf_cliprdr_process_unicodetext(clipboardContext* cb, uint8* data, int size) +{ + UNICONV* uniconv; + + uniconv = freerdp_uniconv_new(); + cb->data = (uint8*) freerdp_uniconv_in(uniconv, data, size); + freerdp_uniconv_free(uniconv); + cb->data_length = strlen((char*) cb->data); + crlf2lf(cb->data, &cb->data_length); +} + +static void xf_cliprdr_process_dib(clipboardContext* cb, uint8* data, int size) +{ + STREAM* s; + uint16 bpp; + uint32 offset; + uint32 ncolors; + + /* size should be at least sizeof(BITMAPINFOHEADER) */ + if (size < 40) + { + DEBUG_X11_CLIPRDR("dib size %d too short", size); + return; + } + + s = stream_new(0); + stream_attach(s, data, size); + stream_seek(s, 14); + stream_read_uint16(s, bpp); + stream_read_uint32(s, ncolors); + offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0); + stream_detach(s); + stream_free(s); + + DEBUG_X11_CLIPRDR("offset=%d bpp=%d ncolors=%d", offset, bpp, ncolors); + + s = stream_new(14 + size); + stream_write_uint8(s, 'B'); + stream_write_uint8(s, 'M'); + stream_write_uint32(s, 14 + size); + stream_write_uint32(s, 0); + stream_write_uint32(s, offset); + stream_write(s, data, size); + + cb->data = stream_get_head(s); + cb->data_length = stream_get_length(s); + stream_detach(s); + stream_free(s); +} + +static void xf_cliprdr_process_html(clipboardContext* cb, uint8* data, int size) +{ + char* start_str; + char* end_str; + int start; + int end; + + start_str = strstr((char*) data, "StartHTML:"); + end_str = strstr((char*) data, "EndHTML:"); + if (start_str == NULL || end_str == NULL) + { + DEBUG_X11_CLIPRDR("invalid HTML clipboard format"); + return; + } + start = atoi(start_str + 10); + end = atoi(end_str + 8); + if (start > size || end > size || start >= end) + { + DEBUG_X11_CLIPRDR("invalid HTML offset"); + return; + } + + cb->data = (uint8*) xmalloc(size - start + 1); + memcpy(cb->data, data + start, end - start); + cb->data_length = end - start; + crlf2lf(cb->data, &cb->data_length); +} + +static void xf_cliprdr_process_cb_data_response_event(xfInfo* xfi, RDP_CB_DATA_RESPONSE_EVENT* event) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + DEBUG_X11_CLIPRDR("size=%d", event->size); + + if (cb->respond == NULL) + { + DEBUG_X11_CLIPRDR("unexpected data"); + return; + } + + if (event->size == 0) + { + cb->respond->xselection.property = None; + } + else + { + if (cb->data) + { + xfree(cb->data); + cb->data = NULL; + } + switch (cb->data_format) + { + case CB_FORMAT_RAW: + case CB_FORMAT_PNG: + case CB_FORMAT_JPEG: + case CB_FORMAT_GIF: + cb->data = event->data; + cb->data_length = event->size; + event->data = NULL; + event->size = 0; + break; + + case CB_FORMAT_TEXT: + xf_cliprdr_process_text(cb, event->data, event->size); + break; + + case CB_FORMAT_UNICODETEXT: + xf_cliprdr_process_unicodetext(cb, event->data, event->size); + break; + + case CB_FORMAT_DIB: + xf_cliprdr_process_dib(cb, event->data, event->size); + break; + + case CB_FORMAT_HTML: + xf_cliprdr_process_html(cb, event->data, event->size); + break; + + default: + cb->respond->xselection.property = None; + break; + } + xf_cliprdr_provide_data(xfi, cb->respond); + } + + XSendEvent(xfi->display, cb->respond->xselection.requestor, 0, 0, cb->respond); + XFlush(xfi->display); + xfree(cb->respond); + cb->respond = NULL; +} + +void xf_process_cliprdr_event(xfInfo* xfi, RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_MONITOR_READY: + xf_cliprdr_process_cb_monitor_ready_event(xfi); + break; + + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + xf_cliprdr_process_cb_format_list_event(xfi, (RDP_CB_FORMAT_LIST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_REQUEST: + xf_cliprdr_process_cb_data_request_event(xfi, (RDP_CB_DATA_REQUEST_EVENT*) event); + break; + + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + xf_cliprdr_process_cb_data_response_event(xfi, (RDP_CB_DATA_RESPONSE_EVENT*) event); + break; + + default: + DEBUG_X11_CLIPRDR("unknown event type %d", event->event_type); + break; + } +} + +boolean xf_cliprdr_process_selection_notify(xfInfo* xfi, XEvent* xevent) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (xevent->xselection.target == cb->targets[1]) + { + if (xevent->xselection.property == None) + { + DEBUG_X11_CLIPRDR("owner not support TARGETS. sending all format."); + xf_cliprdr_send_supported_format_list(xfi); + } + else + { + xf_cliprdr_get_requested_targets(xfi); + } + + return true; + } + else + { + return xf_cliprdr_get_requested_data(xfi, xevent->xselection.target); + } +} + +boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent) +{ + int i; + int fmt; + Atom type; + uint32 format; + XEvent* respond; + uint32 alt_format; + uint8* data = NULL; + boolean delay_respond; + unsigned long length, bytes_left; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + DEBUG_X11_CLIPRDR("target=%d", (int) xevent->xselectionrequest.target); + + if (xevent->xselectionrequest.owner != xfi->drawable) + { + DEBUG_X11_CLIPRDR("not owner"); + return false; + } + + delay_respond = false; + respond = xnew(XEvent); + respond->xselection.property = None; + respond->xselection.type = SelectionNotify; + respond->xselection.display = xevent->xselectionrequest.display; + respond->xselection.requestor = xevent->xselectionrequest.requestor; + respond->xselection.selection = xevent->xselectionrequest.selection; + respond->xselection.target = xevent->xselectionrequest.target; + respond->xselection.time = xevent->xselectionrequest.time; + + if (xevent->xselectionrequest.target == cb->targets[0]) /* TIMESTAMP */ + { + /* TODO */ + DEBUG_X11_CLIPRDR("target: TIMESTAMP (unimplemented)"); + } + else if (xevent->xselectionrequest.target == cb->targets[1]) /* TARGETS */ + { + /* Someone else requests our available formats */ + DEBUG_X11_CLIPRDR("target: TARGETS"); + respond->xselection.property = xevent->xselectionrequest.property; + xf_cliprdr_provide_targets(xfi, respond); + } + else + { + DEBUG_X11_CLIPRDR("target: other"); + + i = xf_cliprdr_select_format_by_atom(cb, xevent->xselectionrequest.target); + + if (i >= 0 && xevent->xselectionrequest.requestor != xfi->drawable) + { + format = cb->format_mappings[i].format_id; + alt_format = format; + if (format == CB_FORMAT_RAW) + { + if (XGetWindowProperty(xfi->display, xevent->xselectionrequest.requestor, + cb->property_atom, 0, 4, 0, XA_INTEGER, + &type, &fmt, &length, &bytes_left, &data) != Success) + { + DEBUG_X11_CLIPRDR("XGetWindowProperty failed"); + } + if (data) + { + memcpy(&alt_format, data, 4); + XFree(data); + } + } + DEBUG_X11_CLIPRDR("provide format 0x%04x alt_format 0x%04x", format, alt_format); + if ((cb->data != 0) && (format == cb->data_format) && (alt_format == cb->data_alt_format)) + { + /* Cached clipboard data available. Send it now */ + respond->xselection.property = xevent->xselectionrequest.property; + xf_cliprdr_provide_data(xfi, respond); + } + else if (cb->respond) + { + DEBUG_X11_CLIPRDR("duplicated request"); + } + else + { + /** + * Send clipboard data request to the server. + * Response will be postponed after receiving the data + */ + if (cb->data) + { + xfree(cb->data); + cb->data = NULL; + } + + respond->xselection.property = xevent->xselectionrequest.property; + cb->respond = respond; + cb->data_format = format; + cb->data_alt_format = alt_format; + delay_respond = true; + + xf_cliprdr_send_data_request(xfi, alt_format); + } + } + } + + if (delay_respond == false) + { + XSendEvent(xfi->display, xevent->xselectionrequest.requestor, 0, 0, respond); + XFlush(xfi->display); + xfree(respond); + } + + return true; +} + +boolean xf_cliprdr_process_selection_clear(xfInfo* xfi, XEvent* xevent) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (xf_cliprdr_is_self_owned(xfi)) + return false; + + XDeleteProperty(xfi->display, cb->root_window, cb->property_atom); + + return true; +} + +boolean xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent) +{ + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (xevent->xproperty.atom != cb->property_atom) + return false; /* Not cliprdr-related */ + + if (xevent->xproperty.window == cb->root_window) + { + DEBUG_X11_CLIPRDR("root window PropertyNotify"); + xf_cliprdr_send_format_list(xfi); + } + else if (xevent->xproperty.window == xfi->drawable && + xevent->xproperty.state == PropertyNewValue && + cb->incr_starts && cb->request_index >= 0) + { + DEBUG_X11_CLIPRDR("cliprdr window PropertyNotify"); + xf_cliprdr_get_requested_data(xfi, + cb->format_mappings[cb->request_index].target_format); + } + + return true; +} + +void xf_cliprdr_check_owner(xfInfo* xfi) +{ + Window owner; + clipboardContext* cb = (clipboardContext*) xfi->clipboard_context; + + if (cb->sync) + { + owner = XGetSelectionOwner(xfi->display, cb->clipboard_atom); + + if (cb->owner != owner) + { + cb->owner = owner; + xf_cliprdr_send_format_list(xfi); + } + } +} + diff --git a/client/X11/xf_cliprdr.h b/client/X11/xf_cliprdr.h new file mode 100644 index 0000000..2678fc3 --- /dev/null +++ b/client/X11/xf_cliprdr.h @@ -0,0 +1,40 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Clipboard Redirection + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_CLIPRDR_H +#define __XF_CLIPRDR_H + +#include "xfreerdp.h" + +void xf_cliprdr_init(xfInfo* xfi, rdpChannels* chanman); +void xf_cliprdr_uninit(xfInfo* xfi); +void xf_process_cliprdr_event(xfInfo* xfi, RDP_EVENT* event); +boolean xf_cliprdr_process_selection_notify(xfInfo* xfi, XEvent* xevent); +boolean xf_cliprdr_process_selection_request(xfInfo* xfi, XEvent* xevent); +boolean xf_cliprdr_process_selection_clear(xfInfo* xfi, XEvent* xevent); +boolean xf_cliprdr_process_property_notify(xfInfo* xfi, XEvent* xevent); +void xf_cliprdr_check_owner(xfInfo* xfi); + +#ifdef WITH_DEBUG_X11_CLIPRDR +#define DEBUG_X11_CLIPRDR(fmt, ...) DEBUG_CLASS(X11_CLIPRDR, fmt, ## __VA_ARGS__) +#else +#define DEBUG_X11_CLIPRDR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __XF_CLIPRDR_H */ diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c new file mode 100644 index 0000000..ccd293d --- /dev/null +++ b/client/X11/xf_event.c @@ -0,0 +1,762 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include "xf_rail.h" +#include "xf_window.h" +#include "xf_cliprdr.h" + +#include "xf_event.h" + +static const char* const X11_EVENT_STRINGS[] = +{ + "", "", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", + "GenericEvent", +}; + +void xf_send_mouse_motion_event(rdpInput* input, boolean down, uint32 button, uint16 x, uint16 y) +{ + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); +} + +boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app) +{ + int x, y; + int w, h; + + x = event->xexpose.x; + y = event->xexpose.y; + w = event->xexpose.width; + h = event->xexpose.height; + + if (app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } + else + { + xfWindow* xfw; + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window); + + if (window != NULL) + { + xfw = (xfWindow*) window->extra; + xf_UpdateWindowArea(xfi, xfw, x, y, w, h); + } + } + + return true; +} + +boolean xf_event_VisibilityNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + xfi->unobscured = event->xvisibility.state == VisibilityUnobscured; + return true; +} + +boolean xf_event_MotionNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + rdpInput* input; + + input = xfi->instance->input; + + if (app != true) + { + if (xfi->mouse_motion != true) + { + if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0) + return true; + } + + input->MouseEvent(input, PTR_FLAGS_MOVE, event->xmotion.x, event->xmotion.y); + + if (xfi->fullscreen) + XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); + } + else if (xfi->mouse_motion == true) + { + rdpWindow* window; + int x = event->xmotion.x; + int y = event->xmotion.y; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xmotion.window); + + if (window != NULL) + { + x += window->windowOffsetX; + y += window->windowOffsetY; + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); + } + } + + return true; +} + +boolean xf_event_ButtonPress(xfInfo* xfi, XEvent* event, boolean app) +{ + uint16 x, y; + uint16 flags; + boolean wheel; + rdpInput* input; + + input = xfi->instance->input; + + x = 0; + y = 0; + flags = 0; + wheel = false; + + switch (event->xbutton.button) + { + case 1: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1; + break; + + case 2: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3; + break; + + case 3: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2; + break; + + case 4: + wheel = true; + flags = PTR_FLAGS_WHEEL | 0x0078; + break; + + case 5: + wheel = true; + flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; + break; + + default: + x = 0; + y = 0; + flags = 0; + break; + } + + if (flags != 0) + { + if (wheel) + { + input->MouseEvent(input, flags, 0, 0); + } + else + { + if (app) + { + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xbutton.window); + + if (window != NULL) + { + x += window->windowOffsetX; + y += window->windowOffsetY; + } + } + + input->MouseEvent(input, flags, x, y); + } + } + + return true; +} + +boolean xf_event_ButtonRelease(xfInfo* xfi, XEvent* event, boolean app) +{ + uint16 x, y; + uint16 flags; + rdpInput* input; + + input = xfi->instance->input; + + x = 0; + y = 0; + flags = 0; + + switch (event->xbutton.button) + { + case 1: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_BUTTON1; + break; + + case 2: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_BUTTON3; + break; + + case 3: + x = event->xbutton.x; + y = event->xbutton.y; + flags = PTR_FLAGS_BUTTON2; + break; + + default: + flags = 0; + break; + } + + if (flags != 0) + { + if (app) + { + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xbutton.window); + + if (window != NULL) + { + x += window->windowOffsetX; + y += window->windowOffsetY; + } + } + + input->MouseEvent(input, flags, x, y); + } + + return true; +} + +boolean xf_event_KeyPress(xfInfo* xfi, XEvent* event, boolean app) +{ + KeySym keysym; + char str[256]; + + XLookupString((XKeyEvent*) event, str, sizeof(str), &keysym, NULL); + + xf_kbd_set_keypress(xfi, event->xkey.keycode, keysym); + + if (xfi->fullscreen_toggle && xf_kbd_handle_special_keys(xfi, keysym)) + return true; + + xf_kbd_send_key(xfi, true, event->xkey.keycode); + + return true; +} + +boolean xf_event_KeyRelease(xfInfo* xfi, XEvent* event, boolean app) +{ + XEvent next_event; + + if (XPending(xfi->display)) + { + memset(&next_event, 0, sizeof(next_event)); + XPeekEvent(xfi->display, &next_event); + + if (next_event.type == KeyPress) + { + if (next_event.xkey.keycode == event->xkey.keycode) + return true; + } + } + + xf_kbd_unset_keypress(xfi, event->xkey.keycode); + xf_kbd_send_key(xfi, false, event->xkey.keycode); + + return true; +} + +boolean xf_event_FocusIn(xfInfo* xfi, XEvent* event, boolean app) +{ + if (event->xfocus.mode == NotifyGrab) + return true; + + xfi->focused = true; + + if (xfi->mouse_active && (app != true)) + XGrabKeyboard(xfi->display, xfi->window->handle, true, GrabModeAsync, GrabModeAsync, CurrentTime); + + if (app) + xf_rail_send_activate(xfi, event->xany.window, true); + + xf_kbd_focus_in(xfi); + + if (app != true) + xf_cliprdr_check_owner(xfi); + + return true; +} + +boolean xf_event_FocusOut(xfInfo* xfi, XEvent* event, boolean app) +{ + if (event->xfocus.mode == NotifyUngrab) + return true; + + xfi->focused = false; + + if (event->xfocus.mode == NotifyWhileGrabbed) + XUngrabKeyboard(xfi->display, CurrentTime); + + if (app) + xf_rail_send_activate(xfi, event->xany.window, false); + + return true; +} + +boolean xf_event_MappingNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + if (event->xmapping.request == MappingModifier) + { + XFreeModifiermap(xfi->modifier_map); + xfi->modifier_map = XGetModifierMapping(xfi->display); + } + + return true; +} + +boolean xf_event_ClientMessage(xfInfo* xfi, XEvent* event, boolean app) +{ + if ((event->xclient.message_type == xfi->WM_PROTOCOLS) + && ((Atom) event->xclient.data.l[0] == xfi->WM_DELETE_WINDOW)) + { + if (app) + { + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xclient.window); + + if (window != NULL) + { + xf_rail_send_client_system_command(xfi, window->windowId, SC_CLOSE); + } + + return true; + } + else + { + return false; + } + } + + return true; +} + +boolean xf_event_EnterNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + xfi->mouse_active = true; + + if (xfi->fullscreen) + XSetInputFocus(xfi->display, xfi->window->handle, RevertToPointerRoot, CurrentTime); + + if (xfi->focused) + XGrabKeyboard(xfi->display, xfi->window->handle, true, GrabModeAsync, GrabModeAsync, CurrentTime); + } + else + { + /* keep track of which window has focus so that we can apply pointer updates */ + + xfWindow* xfw; + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window); + + if (window != NULL) + { + xfw = (xfWindow*) window->extra; + xfi->window = xfw; + } + } + + return true; +} + +boolean xf_event_LeaveNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + xfi->mouse_active = false; + XUngrabKeyboard(xfi->display, CurrentTime); + } + + return true; +} + +boolean xf_event_ConfigureNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xconfigure.window); + + if (window != NULL) + { + xfWindow* xfw; + Window childWindow; + xfw = (xfWindow*) window->extra; + + /* + * ConfigureNotify coordinates are expressed relative to the window parent. + * Translate these to root window coordinates. + */ + + XTranslateCoordinates(xfi->display, xfw->handle, + RootWindowOfScreen(xfi->screen), + 0, 0, &xfw->left, &xfw->top, &childWindow); + + xfw->width = event->xconfigure.width; + xfw->height = event->xconfigure.height; + xfw->right = xfw->left + xfw->width - 1; + xfw->bottom = xfw->top + xfw->height - 1; + + DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u send_event=%d", + (uint32) xfw->handle, xfw->left, xfw->top, xfw->right, xfw->bottom, + xfw->width, xfw->height, event->xconfigure.send_event); + + if (app && ! event->xconfigure.send_event) + xf_rail_adjust_position(xfi, window); + } + + return True; +} + +boolean xf_event_MapNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + if (app != true) + return true; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); + + if (window != NULL) + { + /* local restore event */ + xf_rail_send_client_system_command(xfi, window->windowId, SC_RESTORE); + xfWindow *xfw = (xfWindow*) window->extra; + xfw->is_mapped = true; + } + + return true; +} + +boolean xf_event_UnmapNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + rdpWindow* window; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + + if (app != true) + return true; + + window = window_list_get_by_extra_id(rail->list, (void*) event->xany.window); + + if (window != NULL) + { + xfWindow *xfw = (xfWindow*) window->extra; + xfw->is_mapped = false; + } + + return true; +} + +boolean xf_event_SelectionNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + if (xf_cliprdr_process_selection_notify(xfi, event)) + return true; + } + + return true; +} + +boolean xf_event_SelectionRequest(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + if (xf_cliprdr_process_selection_request(xfi, event)) + return true; + } + + return true; +} + +boolean xf_event_SelectionClear(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + if (xf_cliprdr_process_selection_clear(xfi, event)) + return true; + } + + return true; +} + +boolean xf_event_PropertyNotify(xfInfo* xfi, XEvent* event, boolean app) +{ + if (app != true) + { + if (xf_cliprdr_process_property_notify(xfi, event)) + return true; + } + + return true; +} + +boolean xf_event_suppress_events(xfInfo *xfi, rdpWindow *window, XEvent*event) +{ + if (! xfi->remote_app) + return false; + + switch (xfi->window->local_move.state) + { + case LMS_NOT_ACTIVE: + // No local move in progress, nothing to do + break; + case LMS_STARTING: + // Local move initiated by RDP server, but we + // have not yet seen any updates from the X server + switch(event->type) + { + case ConfigureNotify: + // Starting to see move events + // from the X server. Local + // move is now in progress. + xfi->window->local_move.state = LMS_ACTIVE; + + // Allow these events to be processed during move to keep + // our state up to date. + break; + case ButtonPress: + case ButtonRelease: + case KeyPress: + case KeyRelease: + case UnmapNotify: + // A button release event means the X + // window server did not grab the + // mouse before the user released it. + // In this case we must cancel the + // local move. The event will be + // processed below as normal, below. + break; + case VisibilityNotify: + case PropertyNotify: + case Expose: + // Allow these events to pass + break; + default: + // Eat any other events + return true; + } + break; + + case LMS_ACTIVE: + // Local move is in progress + switch(event->type) + { + case ConfigureNotify: + case VisibilityNotify: + case PropertyNotify: + case Expose: + // Keep us up to date on position + break; + default: + // Any other event terminates move + xf_rail_end_local_move(xfi, window); + break; + } + break; + + case LMS_TERMINATING: + // Already sent RDP end move to sever + // Allow events to pass. + break; + } + + return false; +} + + +boolean xf_event_process(freerdp* instance, XEvent* event) +{ + boolean status = true; + xfInfo* xfi = ((xfContext*) instance->context)->xfi; + rdpRail* rail = ((rdpContext*) xfi->context)->rail; + rdpWindow* window; + + if (xfi->remote_app) + { + window = window_list_get_by_extra_id( + rail->list, (void*) event->xexpose.window); + if (window) + { + // Update "current" window for cursor change orders + xfi->window = (xfWindow *) window->extra; + + if (xf_event_suppress_events(xfi, window, event)) + return true; + } + } + + if (event->type != MotionNotify) + DEBUG_X11("%s Event: wnd=0x%04X", X11_EVENT_STRINGS[event->type], (uint32) event->xany.window); + + switch (event->type) + { + case Expose: + status = xf_event_Expose(xfi, event, xfi->remote_app); + break; + + case VisibilityNotify: + status = xf_event_VisibilityNotify(xfi, event, xfi->remote_app); + break; + + case MotionNotify: + status = xf_event_MotionNotify(xfi, event, xfi->remote_app); + break; + + case ButtonPress: + status = xf_event_ButtonPress(xfi, event, xfi->remote_app); + break; + + case ButtonRelease: + status = xf_event_ButtonRelease(xfi, event, xfi->remote_app); + break; + + case KeyPress: + status = xf_event_KeyPress(xfi, event, xfi->remote_app); + break; + + case KeyRelease: + status = xf_event_KeyRelease(xfi, event, xfi->remote_app); + break; + + case FocusIn: + status = xf_event_FocusIn(xfi, event, xfi->remote_app); + break; + + case FocusOut: + status = xf_event_FocusOut(xfi, event, xfi->remote_app); + break; + + case EnterNotify: + status = xf_event_EnterNotify(xfi, event, xfi->remote_app); + break; + + case LeaveNotify: + status = xf_event_LeaveNotify(xfi, event, xfi->remote_app); + break; + + case NoExpose: + break; + + case GraphicsExpose: + break; + + case ConfigureNotify: + status = xf_event_ConfigureNotify(xfi, event, xfi->remote_app); + break; + + case MapNotify: + status = xf_event_MapNotify(xfi, event, xfi->remote_app); + break; + + case UnmapNotify: + status = xf_event_UnmapNotify(xfi, event, xfi->remote_app); + break; + + case ReparentNotify: + break; + + case MappingNotify: + status = xf_event_MappingNotify(xfi, event, xfi->remote_app); + break; + + case ClientMessage: + status = xf_event_ClientMessage(xfi, event, xfi->remote_app); + break; + + case SelectionNotify: + status = xf_event_SelectionNotify(xfi, event, xfi->remote_app); + break; + + case SelectionRequest: + status = xf_event_SelectionRequest(xfi, event, xfi->remote_app); + break; + + case SelectionClear: + status = xf_event_SelectionClear(xfi, event, xfi->remote_app); + break; + + case PropertyNotify: + status = xf_event_PropertyNotify(xfi, event, xfi->remote_app); + break; + } + + return status; +} diff --git a/client/X11/xf_event.h b/client/X11/xf_event.h new file mode 100644 index 0000000..c6938b3 --- /dev/null +++ b/client/X11/xf_event.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_EVENT_H +#define __XF_EVENT_H + +#include "xf_keyboard.h" + +#include "xfreerdp.h" + +boolean xf_event_process(freerdp* instance, XEvent* event); +void xf_event_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...); + +#endif /* __XF_EVENT_H */ diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c new file mode 100644 index 0000000..0b20d0c --- /dev/null +++ b/client/X11/xf_gdi.c @@ -0,0 +1,788 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 GDI + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "xf_gdi.h" + +static const uint8 xf_rop2_table[] = +{ + 0, + GXclear, /* 0 */ + GXnor, /* DPon */ + GXandInverted, /* DPna */ + GXcopyInverted, /* Pn */ + GXandReverse, /* PDna */ + GXinvert, /* Dn */ + GXxor, /* DPx */ + GXnand, /* DPan */ + GXand, /* DPa */ + GXequiv, /* DPxn */ + GXnoop, /* D */ + GXorInverted, /* DPno */ + GXcopy, /* P */ + GXorReverse, /* PDno */ + GXor, /* DPo */ + GXset /* 1 */ +}; + +boolean xf_set_rop2(xfInfo* xfi, int rop2) +{ + if ((rop2 < 0x01) || (rop2 > 0x10)) + { + printf("Unsupported ROP2: %d\n", rop2); + return false; + } + + XSetFunction(xfi->display, xfi->gc, xf_rop2_table[rop2]); + return true; +} + +boolean xf_set_rop3(xfInfo* xfi, int rop3) +{ + int function = -1; + + switch (rop3) + { + case GDI_BLACKNESS: + function = GXclear; + break; + + case 0x000500A9: + function = GXnor; + break; + + case 0x000A0329: + function = GXandInverted; + break; + + case 0x000F0001: + function = GXcopyInverted; + break; + + case GDI_NOTSRCERASE: + function = GXnor; + break; + + case GDI_DSna: + function = GXandInverted; + break; + + case GDI_NOTSRCCOPY: + function = GXcopyInverted; + break; + + case GDI_SRCERASE: + function = GXandReverse; + break; + + case 0x00500325: + function = GXandReverse; + break; + + case GDI_DSTINVERT: + function = GXinvert; + break; + + case GDI_PATINVERT: + function = GXxor; + break; + + case 0x005F00E9: + function = GXnand; + break; + + case GDI_SRCINVERT: + function = GXxor; + break; + + case 0x007700E6: + function = GXnand; + break; + + case GDI_SRCAND: + function = GXand; + break; + + case 0x00990066: + function = GXequiv; + break; + + case 0x00A000C9: + function = GXand; + break; + + case GDI_PDxn: + function = GXequiv; + break; + + case 0x00AA0029: + function = GXnoop; + break; + + case 0x00AF0229: + function = GXorInverted; + break; + + case GDI_MERGEPAINT: + function = GXorInverted; + break; + + case GDI_SRCCOPY: + function = GXcopy; + break; + + case 0x00DD0228: + function = GXorReverse; + break; + + case GDI_SRCPAINT: + function = GXor; + break; + + case GDI_PATCOPY: + function = GXcopy; + break; + + case 0x00F50225: + function = GXorReverse; + break; + + case 0x00FA0089: + function = GXor; + break; + + case GDI_WHITENESS: + function = GXset; + break; + + default: + break; + } + + if (function < 0) + { + printf("Unsupported ROP3: 0x%08X\n", rop3); + XSetFunction(xfi->display, xfi->gc, GXclear); + return false; + } + + XSetFunction(xfi->display, xfi->gc, function); + + return true; +} + +Pixmap xf_brush_new(xfInfo* xfi, int width, int height, int bpp, uint8* data) +{ + Pixmap bitmap; + uint8* cdata; + XImage* image; + + bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, xfi->depth); + + if(data != NULL) + { + GC gc; // FIXME, should cache + + cdata = freerdp_image_convert(data, NULL, width, height, bpp, xfi->bpp, xfi->clrconv); + image = XCreateImage(xfi->display, xfi->visual, xfi->depth, + ZPixmap, 0, (char*) cdata, width, height, xfi->scanline_pad, 0); + + gc = XCreateGC(xfi->display, xfi->drawable, 0, NULL); + XPutImage(xfi->display, bitmap, gc, image, 0, 0, 0, 0, width, height); + XFree(image); + if (cdata != data) + xfree(cdata); + + XFreeGC(xfi->display, gc); + } + + return bitmap; +} + +Pixmap xf_mono_bitmap_new(xfInfo* xfi, int width, int height, uint8* data) +{ + int scanline; + XImage* image; + Pixmap bitmap; + + scanline = (width + 7) / 8; + + bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, 1); + + image = XCreateImage(xfi->display, xfi->visual, 1, + ZPixmap, 0, (char*) data, width, height, 8, scanline); + + XPutImage(xfi->display, bitmap, xfi->gc_mono, image, 0, 0, 0, 0, width, height); + XFree(image); + + return bitmap; +} + +Pixmap xf_glyph_new(xfInfo* xfi, int width, int height, uint8* data) +{ + int scanline; + Pixmap bitmap; + XImage* image; + + scanline = (width + 7) / 8; + + bitmap = XCreatePixmap(xfi->display, xfi->drawable, width, height, 1); + + image = XCreateImage(xfi->display, xfi->visual, 1, + ZPixmap, 0, (char*) data, width, height, 8, scanline); + + image->byte_order = MSBFirst; + image->bitmap_bit_order = MSBFirst; + + XInitImage(image); + XPutImage(xfi->display, bitmap, xfi->gc_mono, image, 0, 0, 0, 0, width, height); + XFree(image); + + return bitmap; +} + +void xf_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + xfi->clrconv->palette->count = palette->number; + xfi->clrconv->palette->entries = palette->entries; +} + +void xf_gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +{ + XRectangle clip; + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (bounds != NULL) + { + clip.x = bounds->left; + clip.y = bounds->top; + clip.width = bounds->right - bounds->left + 1; + clip.height = bounds->bottom - bounds->top + 1; + XSetClipRectangles(xfi->display, xfi->gc, 0, 0, &clip, 1, YXBanded); + } + else + { + XSetClipMask(xfi->display, xfi->gc, None); + } +} + +void xf_gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + xf_set_rop3(xfi, gdi_rop3_code(dstblt->bRop)); + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XFillRectangle(xfi->display, xfi->drawable, xfi->gc, + dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight); + } + + gdi_InvalidateRegion(xfi->hdc, dstblt->nLeftRect, dstblt->nTopRect, dstblt->nWidth, dstblt->nHeight); + } + XSetFunction(xfi->display, xfi->gc, GXcopy); +} + +void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + Pixmap pattern; + rdpBrush* brush; + uint32 foreColor; + uint32 backColor; + xfInfo* xfi = ((xfContext*) context)->xfi; + + brush = &patblt->brush; + xf_set_rop3(xfi, gdi_rop3_code(patblt->bRop)); + + foreColor = freerdp_color_convert_rgb(patblt->foreColor, xfi->srcBpp, 32, xfi->clrconv); + backColor = freerdp_color_convert_rgb(patblt->backColor, xfi->srcBpp, 32, xfi->clrconv); + + if (brush->style == GDI_BS_SOLID) + { + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, foreColor); + + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + } + else if (brush->style == GDI_BS_PATTERN) + { + if (brush->bpp > 1) + { + pattern = xf_brush_new(xfi, 8, 8, brush->bpp, brush->data); + + XSetFillStyle(xfi->display, xfi->gc, FillTiled); + XSetTile(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + + XSetTile(xfi->display, xfi->gc, xfi->primary); + + XFreePixmap(xfi->display, pattern); + } + else + { + pattern = xf_mono_bitmap_new(xfi, 8, 8, brush->data); + + XSetForeground(xfi->display, xfi->gc, backColor); + XSetBackground(xfi->display, xfi->gc, foreColor); + XSetFillStyle(xfi->display, xfi->gc, FillOpaqueStippled); + XSetStipple(xfi->display, xfi->gc, pattern); + XSetTSOrigin(xfi->display, xfi->gc, brush->x, brush->y); + + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + + XFreePixmap(xfi->display, pattern); + } + } + else + { + printf("unimplemented brush style:%d\n", brush->style); + } + + if (xfi->drawing == xfi->primary) + { + XSetFunction(xfi->display, xfi->gc, GXcopy); + + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight, patblt->nLeftRect, patblt->nTopRect); + } + + gdi_InvalidateRegion(xfi->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight); + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); +} + +void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + xf_set_rop3(xfi, gdi_rop3_code(scrblt->bRop)); + + XCopyArea(xfi->display, xfi->primary, xfi->drawing, xfi->gc, scrblt->nXSrc, scrblt->nYSrc, + scrblt->nWidth, scrblt->nHeight, scrblt->nLeftRect, scrblt->nTopRect); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + if (xfi->unobscured) + { + XCopyArea(xfi->display, xfi->drawable, xfi->drawable, xfi->gc, + scrblt->nXSrc, scrblt->nYSrc, scrblt->nWidth, scrblt->nHeight, + scrblt->nLeftRect, scrblt->nTopRect); + } + else + { + XSetFunction(xfi->display, xfi->gc, GXcopy); + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, + scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight, + scrblt->nLeftRect, scrblt->nTopRect); + } + } + + gdi_InvalidateRegion(xfi->hdc, scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight); + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); +} + +void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +{ + uint32 color; + xfInfo* xfi = ((xfContext*) context)->xfi; + + color = freerdp_color_convert_var(opaque_rect->color, xfi->srcBpp, 32, xfi->clrconv); + + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, color); + + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + opaque_rect->nLeftRect, opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XFillRectangle(xfi->display, xfi->drawable, xfi->gc, + opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight); + } + + gdi_InvalidateRegion(xfi->hdc, opaque_rect->nLeftRect, opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight); + } +} + +void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + int i; + uint32 color; + DELTA_RECT* rectangle; + xfInfo* xfi = ((xfContext*) context)->xfi; + + color = freerdp_color_convert_var(multi_opaque_rect->color, xfi->srcBpp, 32, xfi->clrconv); + + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, color); + + for (i = 1; i < multi_opaque_rect->numRectangles + 1; i++) + { + rectangle = &multi_opaque_rect->rectangles[i]; + + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, + rectangle->left, rectangle->top, + rectangle->width, rectangle->height); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XFillRectangle(xfi->display, xfi->drawable, xfi->gc, + rectangle->left, rectangle->top, rectangle->width, rectangle->height); + } + + gdi_InvalidateRegion(xfi->hdc, rectangle->left, rectangle->top, rectangle->width, rectangle->height); + } + } +} + +void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +{ + uint32 color; + xfInfo* xfi = ((xfContext*) context)->xfi; + + xf_set_rop2(xfi, line_to->bRop2); + color = freerdp_color_convert_rgb(line_to->penColor, xfi->srcBpp, 32, xfi->clrconv); + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, color); + + XDrawLine(xfi->display, xfi->drawing, xfi->gc, + line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd); + + if (xfi->drawing == xfi->primary) + { + int width, height; + + if (xfi->remote_app != true) + { + XDrawLine(xfi->display, xfi->drawable, xfi->gc, + line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd); + } + + width = line_to->nXStart - line_to->nXEnd; + height = line_to->nYStart - line_to->nYEnd; + + if (width < 0) + width *= (-1); + + if (height < 0) + height *= (-1); + + gdi_InvalidateRegion(xfi->hdc, line_to->nXStart, line_to->nYStart, width, height); + + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); +} + +void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +{ + int i; + int x, y; + int x1, y1; + int x2, y2; + int npoints; + uint32 color; + XPoint* points; + int width, height; + xfInfo* xfi = ((xfContext*) context)->xfi; + + xf_set_rop2(xfi, polyline->bRop2); + color = freerdp_color_convert_rgb(polyline->penColor, xfi->srcBpp, 32, xfi->clrconv); + + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, color); + + npoints = polyline->numPoints + 1; + points = xmalloc(sizeof(XPoint) * npoints); + + points[0].x = polyline->xStart; + points[0].y = polyline->yStart; + + for (i = 0; i < polyline->numPoints; i++) + { + points[i + 1].x = polyline->points[i].x; + points[i + 1].y = polyline->points[i].y; + } + + XDrawLines(xfi->display, xfi->drawing, xfi->gc, points, npoints, CoordModePrevious); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + XDrawLines(xfi->display, xfi->drawable, xfi->gc, points, npoints, CoordModePrevious); + + x1 = points[0].x; + y1 = points[0].y; + + for (i = 1; i < npoints; i++) + { + x2 = points[i].x + x1; + y2 = points[i].y + y1; + + x = (x2 < x1) ? x2 : x1; + width = (x2 > x1) ? x2 - x1 : x1 - x2; + + y = (y2 < y1) ? y2 : y1; + height = (y2 > y1) ? y2 - y1 : y1 - y2; + + x1 = x2; + y1 = y2; + + gdi_InvalidateRegion(xfi->hdc, x, y, width, height); + } + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); + xfree(points); +} + +void xf_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +{ + xfBitmap* bitmap; + xfInfo* xfi = ((xfContext*) context)->xfi; + + bitmap = (xfBitmap*) memblt->bitmap; + xf_set_rop3(xfi, gdi_rop3_code(memblt->bRop)); + + XCopyArea(xfi->display, bitmap->pixmap, xfi->drawing, xfi->gc, + memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight, + memblt->nLeftRect, memblt->nTopRect); + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, bitmap->pixmap, xfi->drawable, xfi->gc, + memblt->nXSrc, memblt->nYSrc, memblt->nWidth, memblt->nHeight, + memblt->nLeftRect, memblt->nTopRect); + } + + gdi_InvalidateRegion(xfi->hdc, memblt->nLeftRect, memblt->nTopRect, memblt->nWidth, memblt->nHeight); + } + + XSetFunction(xfi->display, xfi->gc, GXcopy); +} + +void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) +{ + +} + +void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +{ + +} + +void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +{ + int i, tx, ty; + XImage* image; + RFX_MESSAGE* message; + xfInfo* xfi = ((xfContext*) context)->xfi; + RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) xfi->rfx_context; + NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) xfi->nsc_context; + + if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + { + message = rfx_process_message(rfx_context, + surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + + XSetClipRectangles(xfi->display, xfi->gc, + surface_bits_command->destLeft, surface_bits_command->destTop, + (XRectangle*) message->rects, message->num_rects, YXBanded); + + /* Draw the tiles to primary surface, each is 64x64. */ + for (i = 0; i < message->num_tiles; i++) + { + image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, + (char*) message->tiles[i]->data, 64, 64, 32, 0); + + tx = message->tiles[i]->x + surface_bits_command->destLeft; + ty = message->tiles[i]->y + surface_bits_command->destTop; + + XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, tx, ty, 64, 64); + XFree(image); + } + + /* Copy the updated region from backstore to the window. */ + for (i = 0; i < message->num_rects; i++) + { + tx = message->rects[i].x + surface_bits_command->destLeft; + ty = message->rects[i].y + surface_bits_command->destTop; + + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, + tx, ty, message->rects[i].width, message->rects[i].height, tx, ty); + } + + gdi_InvalidateRegion(xfi->hdc, tx, ty, message->rects[i].width, message->rects[i].height); + } + + XSetClipMask(xfi->display, xfi->gc, None); + rfx_message_free(rfx_context, message); + } + else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + { + nsc_context->width = surface_bits_command->width; + nsc_context->height = surface_bits_command->height; + nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + + xfi->bmp_codec_nsc = (uint8*) xrealloc(xfi->bmp_codec_nsc, + surface_bits_command->width * surface_bits_command->height * 4); + + freerdp_image_flip(nsc_context->bmpdata, xfi->bmp_codec_nsc, + surface_bits_command->width, surface_bits_command->height, 32); + + image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, + (char*) xfi->bmp_codec_nsc, surface_bits_command->width, surface_bits_command->height, 32, 0); + + XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, + surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height); + + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, + surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height, + surface_bits_command->destLeft, surface_bits_command->destTop); + } + + gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height); + + XSetClipMask(xfi->display, xfi->gc, None); + nsc_context_destroy(nsc_context); + } + else if (surface_bits_command->codecID == CODEC_ID_NONE) + { + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + + xfi->bmp_codec_none = (uint8*) xrealloc(xfi->bmp_codec_none, + surface_bits_command->width * surface_bits_command->height * 4); + + freerdp_image_flip(surface_bits_command->bitmapData, xfi->bmp_codec_none, + surface_bits_command->width, surface_bits_command->height, 32); + + image = XCreateImage(xfi->display, xfi->visual, 24, ZPixmap, 0, + (char*) xfi->bmp_codec_none, surface_bits_command->width, surface_bits_command->height, 32, 0); + + XPutImage(xfi->display, xfi->primary, xfi->gc, image, 0, 0, + surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height); + + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, + surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height, + surface_bits_command->destLeft, surface_bits_command->destTop); + } + + gdi_InvalidateRegion(xfi->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height); + + XSetClipMask(xfi->display, xfi->gc, None); + } + else + { + printf("Unsupported codecID %d\n", surface_bits_command->codecID); + } +} + +void xf_gdi_register_update_callbacks(rdpUpdate* update) +{ + rdpPrimaryUpdate* primary = update->primary; + + update->Palette = xf_gdi_palette_update; + update->SetBounds = xf_gdi_set_bounds; + + primary->DstBlt = xf_gdi_dstblt; + primary->PatBlt = xf_gdi_patblt; + primary->ScrBlt = xf_gdi_scrblt; + primary->OpaqueRect = xf_gdi_opaque_rect; + primary->DrawNineGrid = NULL; + primary->MultiDstBlt = NULL; + primary->MultiPatBlt = NULL; + primary->MultiScrBlt = NULL; + primary->MultiOpaqueRect = xf_gdi_multi_opaque_rect; + primary->MultiDrawNineGrid = NULL; + primary->LineTo = xf_gdi_line_to; + primary->Polyline = xf_gdi_polyline; + primary->MemBlt = xf_gdi_memblt; + primary->Mem3Blt = xf_gdi_mem3blt; + primary->SaveBitmap = NULL; + primary->GlyphIndex = NULL; + primary->FastIndex = NULL; + primary->FastGlyph = NULL; + primary->PolygonSC = NULL; + primary->PolygonCB = NULL; + primary->EllipseSC = NULL; + primary->EllipseCB = NULL; + + update->SurfaceBits = xf_gdi_surface_bits; + update->SurfaceFrameMarker = xf_gdi_surface_frame_marker; +} + diff --git a/client/X11/xf_gdi.h b/client/X11/xf_gdi.h new file mode 100644 index 0000000..635e533 --- /dev/null +++ b/client/X11/xf_gdi.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 GDI + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_GDI_H +#define __XF_GDI_H + +#include + +#include "xfreerdp.h" + +void xf_gdi_register_update_callbacks(rdpUpdate* update); + +#endif /* __XF_GDI_H */ diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c new file mode 100644 index 0000000..0f3ab7c --- /dev/null +++ b/client/X11/xf_graphics.c @@ -0,0 +1,320 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#ifdef WITH_XCURSOR +#include +#endif + +#include + +#include "xf_graphics.h" + +/* Bitmap Class */ + +void xf_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) +{ + uint8* data; + Pixmap pixmap; + XImage* image; + xfInfo* xfi = ((xfContext*) context)->xfi; + + XSetFunction(xfi->display, xfi->gc, GXcopy); + pixmap = XCreatePixmap(xfi->display, xfi->drawable, bitmap->width, bitmap->height, xfi->depth); + + if (bitmap->data != NULL) + { + data = freerdp_image_convert(bitmap->data, NULL, + bitmap->width, bitmap->height, bitmap->bpp, xfi->bpp, xfi->clrconv); + + if (bitmap->ephemeral != true) + { + image = XCreateImage(xfi->display, xfi->visual, xfi->depth, + ZPixmap, 0, (char*) data, bitmap->width, bitmap->height, xfi->scanline_pad, 0); + + XPutImage(xfi->display, pixmap, xfi->gc, image, 0, 0, 0, 0, bitmap->width, bitmap->height); + XFree(image); + + if (data != bitmap->data) + xfree(data); + } + else + { + if (data != bitmap->data) + xfree(bitmap->data); + + bitmap->data = data; + } + } + + ((xfBitmap*) bitmap)->pixmap = pixmap; +} + +void xf_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (((xfBitmap*) bitmap)->pixmap != 0) + XFreePixmap(xfi->display, ((xfBitmap*) bitmap)->pixmap); +} + +void xf_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) +{ + XImage* image; + int width, height; + xfInfo* xfi = ((xfContext*) context)->xfi; + + width = bitmap->right - bitmap->left + 1; + height = bitmap->bottom - bitmap->top + 1; + + XSetFunction(xfi->display, xfi->gc, GXcopy); + + image = XCreateImage(xfi->display, xfi->visual, xfi->depth, + ZPixmap, 0, (char*) bitmap->data, bitmap->width, bitmap->height, xfi->scanline_pad, 0); + + XPutImage(xfi->display, xfi->primary, xfi->gc, + image, 0, 0, bitmap->left, bitmap->top, width, height); + + XFree(image); + + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, + bitmap->left, bitmap->top, width, height, bitmap->left, bitmap->top); + } + + gdi_InvalidateRegion(xfi->hdc, bitmap->left, bitmap->top, width, height); +} + +void xf_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed) +{ + uint16 size; + + size = width * height * (bpp + 7) / 8; + + if (bitmap->data == NULL) + bitmap->data = (uint8*) xmalloc(size); + else + bitmap->data = (uint8*) xrealloc(bitmap->data, size); + + if (compressed) + { + boolean status; + + status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); + + if (status != true) + { + printf("Bitmap Decompression Failed\n"); + } + } + else + { + freerdp_image_flip(data, bitmap->data, width, height, bpp); + } + + bitmap->compressed = false; + bitmap->length = size; + bitmap->bpp = bpp; +} + +void xf_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primary) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (primary) + xfi->drawing = xfi->primary; + else + xfi->drawing = ((xfBitmap*) bitmap)->pixmap; +} + +/* Pointer Class */ + +void xf_Pointer_New(rdpContext* context, rdpPointer* pointer) +{ + XcursorImage ci; + xfInfo* xfi = ((xfContext*) context)->xfi; + + memset(&ci, 0, sizeof(ci)); + ci.version = XCURSOR_IMAGE_VERSION; + ci.size = sizeof(ci); + ci.width = pointer->width; + ci.height = pointer->height; + ci.xhot = pointer->xPos; + ci.yhot = pointer->yPos; + ci.pixels = (XcursorPixel*) malloc(ci.width * ci.height * 4); + memset(ci.pixels, 0, ci.width * ci.height * 4); + + if ((pointer->andMaskData != 0) && (pointer->xorMaskData != 0)) + { + freerdp_alpha_cursor_convert((uint8*) (ci.pixels), pointer->xorMaskData, pointer->andMaskData, + pointer->width, pointer->height, pointer->xorBpp, xfi->clrconv); + } + + ((xfPointer*) pointer)->cursor = XcursorImageLoadCursor(xfi->display, &ci); + xfree(ci.pixels); +} + +void xf_Pointer_Free(rdpContext* context, rdpPointer* pointer) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (((xfPointer*) pointer)->cursor != 0) + XFreeCursor(xfi->display, ((xfPointer*) pointer)->cursor); +} + +void xf_Pointer_Set(rdpContext* context, rdpPointer* pointer) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + /* in RemoteApp mode, window can be null if none has had focus */ + + if (xfi->window != NULL) + XDefineCursor(xfi->display, xfi->window->handle, ((xfPointer*) pointer)->cursor); +} +/* Glyph Class */ + +void xf_Glyph_New(rdpContext* context, rdpGlyph* glyph) +{ + xfInfo* xfi; + int scanline; + XImage* image; + xfGlyph* xf_glyph; + + xf_glyph = (xfGlyph*) glyph; + xfi = ((xfContext*) context)->xfi; + + scanline = (glyph->cx + 7) / 8; + + xf_glyph->pixmap = XCreatePixmap(xfi->display, xfi->drawing, glyph->cx, glyph->cy, 1); + + image = XCreateImage(xfi->display, xfi->visual, 1, + ZPixmap, 0, (char*) glyph->aj, glyph->cx, glyph->cy, 8, scanline); + + image->byte_order = MSBFirst; + image->bitmap_bit_order = MSBFirst; + + XInitImage(image); + XPutImage(xfi->display, xf_glyph->pixmap, xfi->gc_mono, image, 0, 0, 0, 0, glyph->cx, glyph->cy); + XFree(image); +} + +void xf_Glyph_Free(rdpContext* context, rdpGlyph* glyph) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (((xfGlyph*) glyph)->pixmap != 0) + XFreePixmap(xfi->display, ((xfGlyph*) glyph)->pixmap); +} + +void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) +{ + xfGlyph* xf_glyph; + xfInfo* xfi = ((xfContext*) context)->xfi; + + xf_glyph = (xfGlyph*) glyph; + + XSetStipple(xfi->display, xfi->gc, xf_glyph->pixmap); + XSetTSOrigin(xfi->display, xfi->gc, x, y); + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, glyph->cx, glyph->cy); + XSetStipple(xfi->display, xfi->gc, xfi->bitmap_mono); +} + +void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + bgcolor = (xfi->clrconv->invert)? + freerdp_color_convert_var_bgr(bgcolor, xfi->srcBpp, 32, xfi->clrconv): + freerdp_color_convert_var_rgb(bgcolor, xfi->srcBpp, 32, xfi->clrconv); + + fgcolor = (xfi->clrconv->invert)? + freerdp_color_convert_var_bgr(fgcolor, xfi->srcBpp, 32, xfi->clrconv): + freerdp_color_convert_var_rgb(fgcolor, xfi->srcBpp, 32, xfi->clrconv); + + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, fgcolor); + XFillRectangle(xfi->display, xfi->drawing, xfi->gc, x, y, width, height); + + XSetForeground(xfi->display, xfi->gc, bgcolor); + XSetBackground(xfi->display, xfi->gc, fgcolor); + XSetFillStyle(xfi->display, xfi->gc, FillStippled); +} + +void xf_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + xfInfo* xfi = ((xfContext*) context)->xfi; + + if (xfi->drawing == xfi->primary) + { + if (xfi->remote_app != true) + { + XCopyArea(xfi->display, xfi->primary, xfi->drawable, xfi->gc, x, y, width, height, x, y); + } + + gdi_InvalidateRegion(xfi->hdc, x, y, width, height); + } +} + +/* Graphics Module */ + +void xf_register_graphics(rdpGraphics* graphics) +{ + rdpBitmap* bitmap; + rdpPointer* pointer; + rdpGlyph* glyph; + + bitmap = xnew(rdpBitmap); + bitmap->size = sizeof(xfBitmap); + + bitmap->New = xf_Bitmap_New; + bitmap->Free = xf_Bitmap_Free; + bitmap->Paint = xf_Bitmap_Paint; + bitmap->Decompress = xf_Bitmap_Decompress; + bitmap->SetSurface = xf_Bitmap_SetSurface; + + graphics_register_bitmap(graphics, bitmap); + xfree(bitmap); + + pointer = xnew(rdpPointer); + pointer->size = sizeof(xfPointer); + + pointer->New = xf_Pointer_New; + pointer->Free = xf_Pointer_Free; + pointer->Set = xf_Pointer_Set; + + graphics_register_pointer(graphics, pointer); + xfree(pointer); + + glyph = xnew(rdpGlyph); + glyph->size = sizeof(xfGlyph); + + glyph->New = xf_Glyph_New; + glyph->Free = xf_Glyph_Free; + glyph->Draw = xf_Glyph_Draw; + glyph->BeginDraw = xf_Glyph_BeginDraw; + glyph->EndDraw = xf_Glyph_EndDraw; + + graphics_register_glyph(graphics, glyph); + xfree(glyph); +} diff --git a/client/X11/xf_graphics.h b/client/X11/xf_graphics.h new file mode 100644 index 0000000..14216f3 --- /dev/null +++ b/client/X11/xf_graphics.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_GRAPHICS_H +#define __XF_GRAPHICS_H + +#include "xfreerdp.h" + +void xf_register_graphics(rdpGraphics* graphics); + +#endif /* __XF_GRAPHICS_H */ diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c new file mode 100644 index 0000000..020b5e4 --- /dev/null +++ b/client/X11/xf_keyboard.c @@ -0,0 +1,188 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Keyboard Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "xf_keyboard.h" + +void xf_kbd_init(xfInfo* xfi) +{ + memset(xfi->pressed_keys, 0, 256 * sizeof(boolean)); + xfi->keyboard_layout_id = xfi->instance->settings->kbd_layout; + xfi->keyboard_layout_id = freerdp_kbd_init(xfi->display, xfi->keyboard_layout_id); + xfi->instance->settings->kbd_layout = xfi->keyboard_layout_id; +} + +void xf_kbd_set_keypress(xfInfo* xfi, uint8 keycode, KeySym keysym) +{ + if (keycode >= 8) + xfi->pressed_keys[keycode] = keysym; + else + return; +} + +void xf_kbd_unset_keypress(xfInfo* xfi, uint8 keycode) +{ + if (keycode >= 8) + xfi->pressed_keys[keycode] = NoSymbol; + else + return; +} + +boolean xf_kbd_key_pressed(xfInfo* xfi, KeySym keysym) +{ + KeyCode keycode = XKeysymToKeycode(xfi->display, keysym); + return (xfi->pressed_keys[keycode] == keysym); +} + +void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode) +{ + uint16 flags; + uint8 scancode; + boolean extended; + rdpInput* input; + + input = xfi->instance->input; + scancode = freerdp_kbd_get_scancode_by_keycode(keycode, &extended); + + if (scancode == 0) + { + /* unknown key */ + } + else if ((scancode == 0x46) && extended && + !xf_kbd_key_pressed(xfi, XK_Control_L) && !xf_kbd_key_pressed(xfi, XK_Control_R)) + { + /* Pause without Ctrl has to be sent as Ctrl + NumLock. */ + if (down) + { + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x1D); /* Ctrl down */ + input->KeyboardEvent(input, KBD_FLAGS_DOWN, 0x45); /* NumLock down */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x1D); /* Ctrl up */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x45); /* NumLock up */ + } + } + else + { + flags = (extended) ? KBD_FLAGS_EXTENDED : 0; + flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; + + input->KeyboardEvent(input, flags, scancode); + + if ((scancode == 0x3A) && (down == false)) /* caps lock was released */ + { + uint32 syncFlags; + syncFlags = xf_kbd_get_toggle_keys_state(xfi); + input->SynchronizeEvent(input, syncFlags); + } + } +} + +int xf_kbd_read_keyboard_state(xfInfo* xfi) +{ + int dummy; + Window wdummy; + uint32 state = 0; + + if (xfi->remote_app != true) + { + XQueryPointer(xfi->display, xfi->window->handle, + &wdummy, &wdummy, &dummy, &dummy, &dummy, &dummy, &state); + } + + return state; +} + +boolean xf_kbd_get_key_state(xfInfo* xfi, int state, int keysym) +{ + int offset; + int modifierpos, key, keysymMask = 0; + KeyCode keycode = XKeysymToKeycode(xfi->display, keysym); + + if (keycode == NoSymbol) + return false; + + for (modifierpos = 0; modifierpos < 8; modifierpos++) + { + offset = xfi->modifier_map->max_keypermod * modifierpos; + for (key = 0; key < xfi->modifier_map->max_keypermod; key++) + { + if (xfi->modifier_map->modifiermap[offset + key] == keycode) + { + keysymMask |= 1 << modifierpos; + } + } + } + + return (state & keysymMask) ? true : false; +} + +int xf_kbd_get_toggle_keys_state(xfInfo* xfi) +{ + int state; + int toggle_keys_state = 0; + + state = xf_kbd_read_keyboard_state(xfi); + if (xf_kbd_get_key_state(xfi, state, XK_Scroll_Lock)) + toggle_keys_state |= KBD_SYNC_SCROLL_LOCK; + if (xf_kbd_get_key_state(xfi, state, XK_Num_Lock)) + toggle_keys_state |= KBD_SYNC_NUM_LOCK; + if (xf_kbd_get_key_state(xfi, state, XK_Caps_Lock)) + toggle_keys_state |= KBD_SYNC_CAPS_LOCK; + if (xf_kbd_get_key_state(xfi, state, XK_Kana_Lock)) + toggle_keys_state |= KBD_SYNC_KANA_LOCK; + + return toggle_keys_state; +} + +void xf_kbd_focus_in(xfInfo* xfi) +{ + rdpInput* input; + uint32 syncFlags; + + input = xfi->instance->input; + + /* on focus in send a tab up like mstsc.exe */ + input->KeyboardEvent(input, KBD_FLAGS_RELEASE, 0x0F); + + /* synchronize toggle keys */ + syncFlags = xf_kbd_get_toggle_keys_state(xfi); + input->SynchronizeEvent(input, syncFlags); +} + +boolean xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym) +{ + if (keysym == XK_Return) + { + if ((xf_kbd_key_pressed(xfi, XK_Alt_L) || xf_kbd_key_pressed(xfi, XK_Alt_R)) + && (xf_kbd_key_pressed(xfi, XK_Control_L) || xf_kbd_key_pressed(xfi, XK_Control_R))) + { + /* Ctrl-Alt-Enter: toggle full screen */ + xf_toggle_fullscreen(xfi); + return true; + } + } + + return false; +} + diff --git a/client/X11/xf_keyboard.h b/client/X11/xf_keyboard.h new file mode 100644 index 0000000..92e08fc --- /dev/null +++ b/client/X11/xf_keyboard.h @@ -0,0 +1,39 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Keyboard Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_KEYBOARD_H +#define __XF_KEYBOARD_H + +#include +#include + +#include "xfreerdp.h" + +void xf_kbd_init(xfInfo* xfi); +void xf_kbd_set_keypress(xfInfo* xfi, uint8 keycode, KeySym keysym); +void xf_kbd_unset_keypress(xfInfo* xfi, uint8 keycode); +boolean xf_kbd_key_pressed(xfInfo* xfi, KeySym keysym); +void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode); +int xf_kbd_read_keyboard_state(xfInfo* xfi); +boolean xf_kbd_get_key_state(xfInfo* xfi, int state, int keysym); +int xf_kbd_get_toggle_keys_state(xfInfo* xfi); +void xf_kbd_focus_in(xfInfo* xfi); +boolean xf_kbd_handle_special_keys(xfInfo* xfi, KeySym keysym); + +#endif /* __XF_KEYBOARD_H */ diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c new file mode 100644 index 0000000..eedf715 --- /dev/null +++ b/client/X11/xf_monitor.c @@ -0,0 +1,127 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Monitor Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifdef WITH_XINERAMA +#include +#endif + +#include "xf_monitor.h" + +/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */ + +boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) +{ + int i; + VIRTUAL_SCREEN* vscreen; + +#ifdef WITH_XINERAMA + int ignored, ignored2; + XineramaScreenInfo* screen_info = NULL; +#endif + + vscreen = &xfi->vscreen; + + if (xf_GetWorkArea(xfi) != true) + { + xfi->workArea.x = 0; + xfi->workArea.y = 0; + xfi->workArea.width = WidthOfScreen(xfi->screen); + xfi->workArea.height = HeightOfScreen(xfi->screen); + } + + if (settings->fullscreen) + { + settings->width = WidthOfScreen(xfi->screen); + settings->height = HeightOfScreen(xfi->screen); + } + else if (settings->workarea) + { + settings->width = xfi->workArea.width; + settings->height = xfi->workArea.height; + } + else if (settings->percent_screen) + { + settings->width = (xfi->workArea.width * settings->percent_screen) / 100; + settings->height = (xfi->workArea.height * settings->percent_screen) / 100; + } + + if (settings->fullscreen != true && settings->workarea != true) + return true; + +#ifdef WITH_XINERAMA + if (XineramaQueryExtension(xfi->display, &ignored, &ignored2)) + { + if (XineramaIsActive(xfi->display)) + { + screen_info = XineramaQueryScreens(xfi->display, &vscreen->nmonitors); + + if (vscreen->nmonitors > 16) + vscreen->nmonitors = 0; + + vscreen->monitors = xzalloc(sizeof(MONITOR_INFO) * vscreen->nmonitors); + + if (vscreen->nmonitors) + { + for (i = 0; i < vscreen->nmonitors; i++) + { + vscreen->monitors[i].area.left = screen_info[i].x_org; + vscreen->monitors[i].area.top = screen_info[i].y_org; + vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1; + vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1; + + if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0)) + vscreen->monitors[i].primary = true; + } + } + + XFree(screen_info); + } + } +#endif + + settings->num_monitors = vscreen->nmonitors; + + for (i = 0; i < vscreen->nmonitors; i++) + { + settings->monitors[i].x = vscreen->monitors[i].area.left; + settings->monitors[i].y = vscreen->monitors[i].area.top; + settings->monitors[i].width = vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1; + settings->monitors[i].height = vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1; + settings->monitors[i].is_primary = vscreen->monitors[i].primary; + + vscreen->area.left = MIN(vscreen->monitors[i].area.left, vscreen->area.left); + vscreen->area.right = MAX(vscreen->monitors[i].area.right, vscreen->area.right); + vscreen->area.top = MIN(vscreen->monitors[i].area.top, vscreen->area.top); + vscreen->area.bottom = MAX(vscreen->monitors[i].area.bottom, vscreen->area.bottom); + } + + if (settings->num_monitors) + { + settings->width = vscreen->area.right - vscreen->area.left + 1; + settings->height = vscreen->area.bottom - vscreen->area.top + 1; + } + + return true; +} diff --git a/client/X11/xf_monitor.h b/client/X11/xf_monitor.h new file mode 100644 index 0000000..d6b7d6d --- /dev/null +++ b/client/X11/xf_monitor.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Monitor Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_MONITOR_H +#define __XF_MONITOR_H + +#include +#include + +struct _MONITOR_INFO +{ + RECTANGLE_16 area; + RECTANGLE_16 workarea; + boolean primary; +}; +typedef struct _MONITOR_INFO MONITOR_INFO; + +struct _VIRTUAL_SCREEN +{ + int nmonitors; + RECTANGLE_16 area; + RECTANGLE_16 workarea; + MONITOR_INFO* monitors; +}; +typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN; + +#include "xfreerdp.h" + +boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings); + +#endif /* __XF_MONITOR_H */ diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c new file mode 100644 index 0000000..f6f9dc3 --- /dev/null +++ b/client/X11/xf_rail.c @@ -0,0 +1,607 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RAIL + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include + +#include "xf_window.h" +#include "xf_rail.h" + +void xf_rail_enable_remoteapp_mode(xfInfo* xfi) +{ + if (xfi->remote_app == false) + { + xfi->remote_app = true; + xfi->drawable = DefaultRootWindow(xfi->display); + xf_DestroyWindow(xfi, xfi->window); + xfi->window = NULL; + } +} + +void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom) +{ + xfWindow* xfw; + rdpWindow* window; + boolean intersect; + uint32 iwidth, iheight; + sint32 ileft, itop; + uint32 iright, ibottom; + sint32 wleft, wtop; + uint32 wright, wbottom; + + window_list_rewind(rail->list); + + while (window_list_has_next(rail->list)) + { + window = window_list_get_next(rail->list); + xfw = (xfWindow*) window->extra; + + // RDP can have zero width or height windows. X cannot, so we ignore these. + + if (window->windowWidth == 0 || window->windowHeight == 0) + { + continue; + } + + wleft = window->windowOffsetX; + wtop = window->windowOffsetY; + wright = window->windowOffsetX + window->windowWidth - 1; + wbottom = window->windowOffsetY + window->windowHeight - 1; + + ileft = MAX(uleft, wleft); + itop = MAX(utop, wtop); + iright = MIN(uright, wright); + ibottom = MIN(ubottom, wbottom); + + iwidth = iright - ileft + 1; + iheight = ibottom - itop + 1; + + intersect = ((iright > ileft) && (ibottom > itop)) ? true : false; + + if (intersect) + { + xf_UpdateWindowArea(xfi, xfw, ileft - wleft, itop - wtop, iwidth, iheight); + } + } +} + +void xf_rail_CreateWindow(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + + xf_rail_enable_remoteapp_mode(xfi); + + xfw = xf_CreateWindow((xfInfo*) rail->extra, window, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight, + window->windowId); + + xf_SetWindowStyle(xfi, xfw, window->style, window->extendedStyle); + + XStoreName(xfi->display, xfw->handle, window->title); + + window->extra = (void*) xfw; + window->extraId = (void*) xfw->handle; +} + +void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + // Do nothing if window is already in the correct position + if ( xfw->left == window->windowOffsetX && + xfw->top == window->windowOffsetY && + xfw->width == window->windowWidth && + xfw->height == window->windowHeight) + { + return; + } + + xf_MoveWindow((xfInfo*) rail->extra, xfw, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight); +} + +void xf_rail_ShowWindow(rdpRail* rail, rdpWindow* window, uint8 state) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + xf_ShowWindow((xfInfo*) rail->extra, xfw, state); +} + +void xf_rail_SetWindowText(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + XStoreName(xfi->display, xfw->handle, window->title); +} + +void xf_rail_SetWindowIcon(rdpRail* rail, rdpWindow* window, rdpIcon* icon) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + icon->extra = freerdp_icon_convert(icon->entry->bitsColor, NULL, icon->entry->bitsMask, + icon->entry->width, icon->entry->height, icon->entry->bpp, rail->clrconv); + + xf_SetWindowIcon(xfi, xfw, icon); +} + +void xf_rail_SetWindowRects(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + xf_SetWindowRects(xfi, xfw, window->windowRects, window->numWindowRects); +} + +void xf_rail_SetWindowVisibilityRects(rdpRail* rail, rdpWindow* window) +{ + xfInfo* xfi; + xfWindow* xfw; + + xfi = (xfInfo*) rail->extra; + xfw = (xfWindow*) window->extra; + + xf_SetWindowVisibilityRects(xfi, xfw, window->windowRects, window->numWindowRects); +} + +void xf_rail_DestroyWindow(rdpRail* rail, rdpWindow* window) +{ + xfWindow* xfw; + xfw = (xfWindow*) window->extra; + xf_DestroyWindow((xfInfo*) rail->extra, xfw); +} + +void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail) +{ + rail->extra = (void*) xfi; + rail->rail_CreateWindow = xf_rail_CreateWindow; + rail->rail_MoveWindow = xf_rail_MoveWindow; + rail->rail_ShowWindow = xf_rail_ShowWindow; + rail->rail_SetWindowText = xf_rail_SetWindowText; + rail->rail_SetWindowIcon = xf_rail_SetWindowIcon; + rail->rail_SetWindowRects = xf_rail_SetWindowRects; + rail->rail_SetWindowVisibilityRects = xf_rail_SetWindowVisibilityRects; + rail->rail_DestroyWindow = xf_rail_DestroyWindow; +} + +static void xf_on_free_rail_client_event(RDP_EVENT* event) +{ + if (event->event_class == RDP_EVENT_CLASS_RAIL) + { + rail_free_cloned_order(event->event_type, event->user_data); + } +} + +static void xf_send_rail_client_event(rdpChannels* channels, uint16 event_type, void* param) +{ + RDP_EVENT* out_event = NULL; + void * payload = NULL; + + payload = rail_clone_order(event_type, param); + if (payload != NULL) + { + out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, + xf_on_free_rail_client_event, payload); + freerdp_channels_send_event(channels, out_event); + } +} + +void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled) +{ + rdpRail* rail; + rdpChannels* channels; + rdpWindow* rail_window; + RAIL_ACTIVATE_ORDER activate; + + rail = xfi->_context->rail; + channels = xfi->_context->channels; + + rail_window = window_list_get_by_extra_id(rail->list, (void*) xwindow); + + if (rail_window == NULL) + return; + + activate.windowId = rail_window->windowId; + activate.enabled = enabled; + + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, &activate); +} + +void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command) +{ + rdpChannels* channels; + RAIL_SYSCOMMAND_ORDER syscommand; + + channels = xfi->_context->channels; + + syscommand.windowId = windowId; + syscommand.command = command; + + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, &syscommand); +} + +/** + * The position of the X window can become out of sync with the RDP window + * if the X window is moved locally by the window manager. In this event + * send an update to the RDP server informing it of the new window position + * and size. + */ +void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window) +{ + xfWindow* xfw; + rdpChannels* channels; + RAIL_WINDOW_MOVE_ORDER window_move; + + xfw = (xfWindow*) window->extra; + channels = xfi->_context->channels; + + if (! xfw->is_mapped || xfw->local_move.state != LMS_NOT_ACTIVE) + return; + + // If current window position disagrees with RDP window position, send + // update to RDP server + if ( xfw->left != window->windowOffsetX || + xfw->top != window->windowOffsetY || + xfw->width != window->windowWidth || + xfw->height != window->windowHeight) + { + window_move.windowId = window->windowId; + window_move.left = xfw->left; + window_move.top = xfw->top; + window_move.right = xfw->right; + window_move.bottom = xfw->bottom; + + DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u" + " RDP=0x%X rc={l=%d t=%d} w=%d h=%d", + (uint32) xfw->handle, xfw->left, xfw->top, + xfw->right, xfw->bottom, xfw->width, xfw->height, + window->windowId, + window->windowOffsetX, window->windowOffsetY, + window->windowWidth, window->windowHeight); + + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); + } +} + +void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window) +{ + xfWindow* xfw; + rdpChannels* channels; + RAIL_WINDOW_MOVE_ORDER window_move; + int x,y; + rdpInput* input = xfi->instance->input; + + xfw = (xfWindow*) window->extra; + channels = xfi->_context->channels; + + // Send RDP client event to inform RDP server + + window_move.windowId = window->windowId; + window_move.left = xfw->left; + window_move.top = xfw->top; + window_move.right = xfw->right + 1; // In the update to RDP the position is one past the window + window_move.bottom = xfw->bottom + 1; + + DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d", + (uint32) xfw->handle, + xfw->left, xfw->top, xfw->right, xfw->bottom, + xfw->width, xfw->height); + + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, &window_move); + + // Send synthetic button up event to the RDP server. This is per the RDP spec to + // indicate a local move has finished. + + x = xfw->left + xfw->local_move.window_x; + y = xfw->top + xfw->local_move.window_y; + input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); + + // Proactively update the RAIL window dimensions. There is a race condition where + // we can start to receive GDI orders for the new window dimensions before we + // receive the RAIL ORDER for the new window size. This avoids that race condition. + + window->windowOffsetX = xfw->left; + window->windowOffsetY = xfw->top; + window->windowWidth = xfw->width; + window->windowHeight = xfw->height; + + xfw->local_move.state = LMS_TERMINATING; +} + +void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_SYSPARAM_ORDER* sysparam; + + sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data; + + sysparam->workArea.left = xfi->workArea.x; + sysparam->workArea.top = xfi->workArea.y; + sysparam->workArea.right = xfi->workArea.x + xfi->workArea.width; + sysparam->workArea.bottom = xfi->workArea.y + xfi->workArea.height; + + sysparam->taskbarPos.left = 0; + sysparam->taskbarPos.top = 0; + sysparam->taskbarPos.right = 0; + sysparam->taskbarPos.bottom = 0; + + sysparam->dragFullWindows = false; + + xf_send_rail_client_event(channels, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sysparam); +} + +const char* error_code_names[] = +{ + "RAIL_EXEC_S_OK", + "RAIL_EXEC_E_HOOK_NOT_LOADED", + "RAIL_EXEC_E_DECODE_FAILED", + "RAIL_EXEC_E_NOT_IN_ALLOWLIST", + "RAIL_EXEC_E_FILE_NOT_FOUND", + "RAIL_EXEC_E_FAIL", + "RAIL_EXEC_E_SESSION_LOCKED" +}; + +void xf_process_rail_exec_result_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_EXEC_RESULT_ORDER* exec_result; + + exec_result = (RAIL_EXEC_RESULT_ORDER*) event->user_data; + + if (exec_result->execResult != RAIL_EXEC_S_OK) + { + printf("RAIL exec error: execResult=%s NtError=0x%X\n", + error_code_names[exec_result->execResult], exec_result->rawResult); + xfi->disconnect = True; + } + else + { + xf_rail_enable_remoteapp_mode(xfi); + } +} + +void xf_process_rail_server_sysparam_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_SYSPARAM_ORDER* sysparam = (RAIL_SYSPARAM_ORDER*) event->user_data; + + switch (sysparam->param) + { + case SPI_SET_SCREEN_SAVE_ACTIVE: + break; + + case SPI_SET_SCREEN_SAVE_SECURE: + break; + } +} + +void xf_process_rail_server_minmaxinfo_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + rdpRail* rail; + rdpWindow* rail_window = NULL; + RAIL_MINMAXINFO_ORDER* minmax = (RAIL_MINMAXINFO_ORDER*) event->user_data; + + rail = ((rdpContext*) xfi->context)->rail; + rail_window = window_list_get_by_id(rail->list, minmax->windowId); + + if (rail_window != NULL) + { + xfWindow * window = NULL; + window = (xfWindow *) rail_window->extra; + + DEBUG_X11_LMS("windowId=0x%X maxWidth=%d maxHeight=%d maxPosX=%d maxPosY=%d " + "minTrackWidth=%d minTrackHeight=%d maxTrackWidth=%d maxTrackHeight=%d", + minmax->windowId, minmax->maxWidth, minmax->maxHeight, + (sint16)minmax->maxPosX, (sint16)minmax->maxPosY, + minmax->minTrackWidth, minmax->minTrackHeight, + minmax->maxTrackWidth, minmax->maxTrackHeight); + + xf_SetWindowMinMaxInfo(xfi, window, minmax->maxWidth, minmax->maxHeight, minmax->maxPosX, minmax->maxPosY, + minmax->minTrackWidth, minmax->minTrackHeight, minmax->maxTrackWidth, minmax->maxTrackHeight); + } +} + +const char* movetype_names[] = +{ + "(invalid)", + "RAIL_WMSZ_LEFT", + "RAIL_WMSZ_RIGHT", + "RAIL_WMSZ_TOP", + "RAIL_WMSZ_TOPLEFT", + "RAIL_WMSZ_TOPRIGHT", + "RAIL_WMSZ_BOTTOM", + "RAIL_WMSZ_BOTTOMLEFT", + "RAIL_WMSZ_BOTTOMRIGHT", + "RAIL_WMSZ_MOVE", + "RAIL_WMSZ_KEYMOVE", + "RAIL_WMSZ_KEYSIZE" +}; + +void xf_process_rail_server_localmovesize_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + rdpRail* rail; + rdpWindow* rail_window = NULL; + RAIL_LOCALMOVESIZE_ORDER* movesize = (RAIL_LOCALMOVESIZE_ORDER*) event->user_data; + int direction = 0; + Window child_window; + int x,y; + + rail = ((rdpContext*) xfi->context)->rail; + rail_window = window_list_get_by_id(rail->list, movesize->windowId); + + if (rail_window != NULL) + { + xfWindow* xfw = NULL; + xfw = (xfWindow*) rail_window->extra; + + DEBUG_X11_LMS("windowId=0x%X isMoveSizeStart=%d moveSizeType=%s PosX=%d PosY=%d", + movesize->windowId, movesize->isMoveSizeStart, + movetype_names[movesize->moveSizeType], (sint16) movesize->posX, (sint16) movesize->posY); + + switch (movesize->moveSizeType) + { + case RAIL_WMSZ_LEFT: //0x1 + direction = _NET_WM_MOVERESIZE_SIZE_LEFT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_RIGHT: //0x2 + direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_TOP: //0x3 + direction = _NET_WM_MOVERESIZE_SIZE_TOP; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_TOPLEFT: //0x4 + direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_TOPRIGHT: //0x5 + direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_BOTTOM: //0x6 + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_BOTTOMLEFT: //0x7 + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_BOTTOMRIGHT: //0x8 + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_MOVE: //0x9 + direction = _NET_WM_MOVERESIZE_MOVE; + XTranslateCoordinates(xfi->display, xfw->handle, + RootWindowOfScreen(xfi->screen), + movesize->posX, movesize->posY, &x, &y, &child_window); + break; + case RAIL_WMSZ_KEYMOVE: //0xA + direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD; + x = movesize->posX; + y = movesize->posY; + break; + case RAIL_WMSZ_KEYSIZE: //0xB + direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; + x = movesize->posX; + y = movesize->posY; + break; + } + + if (movesize->isMoveSizeStart) + { + xf_StartLocalMoveSize(xfi, xfw, direction, x, y); + } else { + xf_EndLocalMoveSize(xfi, xfw); + } + } +} + +void xf_process_rail_appid_resp_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_GET_APPID_RESP_ORDER* appid_resp = + (RAIL_GET_APPID_RESP_ORDER*)event->user_data; + + printf("Server Application ID Response PDU: windowId=0x%X " + "applicationId=(length=%d dump)\n", + appid_resp->windowId, appid_resp->applicationId.length); + + freerdp_hexdump(appid_resp->applicationId.string, appid_resp->applicationId.length); +} + +void xf_process_rail_langbarinfo_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + RAIL_LANGBAR_INFO_ORDER* langbar = + (RAIL_LANGBAR_INFO_ORDER*) event->user_data; + + printf("Language Bar Information PDU: languageBarStatus=0x%X\n", + langbar->languageBarStatus); +} + +void xf_process_rail_event(xfInfo* xfi, rdpChannels* channels, RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS: + xf_process_rail_get_sysparams_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS: + xf_process_rail_exec_result_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM: + xf_process_rail_server_sysparam_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO: + xf_process_rail_server_minmaxinfo_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE: + xf_process_rail_server_localmovesize_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP: + xf_process_rail_appid_resp_event(xfi, channels, event); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO: + xf_process_rail_langbarinfo_event(xfi, channels, event); + break; + + default: + break; + } +} diff --git a/client/X11/xf_rail.h b/client/X11/xf_rail.h new file mode 100644 index 0000000..0c66e1c --- /dev/null +++ b/client/X11/xf_rail.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RAIL + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_RAIL_H +#define __XF_RAIL_H + +#include "xfreerdp.h" + +void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom); +void xf_rail_register_callbacks(xfInfo* xfi, rdpRail* rail); +void xf_rail_send_client_system_command(xfInfo* xfi, uint32 windowId, uint16 command); +void xf_rail_send_activate(xfInfo* xfi, Window xwindow, boolean enabled); +void xf_process_rail_event(xfInfo* xfi, rdpChannels* chanman, RDP_EVENT* event); +void xf_rail_adjust_position(xfInfo* xfi, rdpWindow *window); +void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window); + +#endif /* __XF_RAIL_H */ diff --git a/client/X11/xf_tsmf.c b/client/X11/xf_tsmf.c new file mode 100644 index 0000000..8d16d5e --- /dev/null +++ b/client/X11/xf_tsmf.c @@ -0,0 +1,370 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Video Redirection + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xf_tsmf.h" + +#ifdef WITH_XV + +#include +#include + +typedef struct xf_xv_context xfXvContext; + +struct xf_xv_context +{ + long xv_port; + Atom xv_colorkey_atom; + int xv_image_size; + int xv_shmid; + char* xv_shmaddr; + uint32* xv_pixfmts; +}; + +#ifdef WITH_DEBUG_XV +#define DEBUG_XV(fmt, ...) DEBUG_CLASS(XV, fmt, ## __VA_ARGS__) +#else +#define DEBUG_XV(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +void xf_tsmf_init(xfInfo* xfi, long xv_port) +{ + int ret; + unsigned int i; + unsigned int version; + unsigned int release; + unsigned int event_base; + unsigned int error_base; + unsigned int request_base; + unsigned int num_adaptors; + xfXvContext* xv; + XvAdaptorInfo* ai; + XvAttribute* attr; + XvImageFormatValues* fo; + + xv = xnew(xfXvContext); + xfi->xv_context = xv; + + xv->xv_colorkey_atom = None; + xv->xv_image_size = 0; + xv->xv_port = xv_port; + + if (!XShmQueryExtension(xfi->display)) + { + DEBUG_XV("no shmem available."); + return; + } + + ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base); + if (ret != Success) + { + DEBUG_XV("XvQueryExtension failed %d.", ret); + return; + } + DEBUG_XV("version %u release %u", version, release); + + ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display), + &num_adaptors, &ai); + if (ret != Success) + { + DEBUG_XV("XvQueryAdaptors failed %d.", ret); + return; + } + + for (i = 0; i < num_adaptors; i++) + { + DEBUG_XV("adapter port %ld-%ld (%s)", ai[i].base_id, + ai[i].base_id + ai[i].num_ports - 1, ai[i].name); + if (xv->xv_port == 0 && i == num_adaptors - 1) + xv->xv_port = ai[i].base_id; + } + + if (num_adaptors > 0) + XvFreeAdaptorInfo(ai); + + if (xv->xv_port == 0) + { + DEBUG_XV("no adapter selected, video frames will not be processed."); + return; + } + DEBUG_XV("selected %ld", xv->xv_port); + + attr = XvQueryPortAttributes(xfi->display, xv->xv_port, &ret); + for (i = 0; i < (unsigned int)ret; i++) + { + if (strcmp(attr[i].name, "XV_COLORKEY") == 0) + { + xv->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", false); + XvSetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, attr[i].min_value + 1); + break; + } + } + XFree(attr); + +#ifdef WITH_DEBUG_XV + printf("xf_tsmf_init: pixel format "); +#endif + fo = XvListImageFormats(xfi->display, xv->xv_port, &ret); + if (ret > 0) + { + xv->xv_pixfmts = (uint32*) xzalloc((ret + 1) * sizeof(uint32)); + for (i = 0; i < ret; i++) + { + xv->xv_pixfmts[i] = fo[i].id; +#ifdef WITH_DEBUG_XV + printf("%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1], + ((char*)(xv->xv_pixfmts + i))[2], ((char*)(xv->xv_pixfmts + i))[3]); +#endif + } + xv->xv_pixfmts[i] = 0; + } + XFree(fo); +#ifdef WITH_DEBUG_XV + printf("\n"); +#endif +} + +void xf_tsmf_uninit(xfInfo* xfi) +{ + xfXvContext* xv = (xfXvContext*) xfi->xv_context; + + if (xv) + { + if (xv->xv_image_size > 0) + { + shmdt(xv->xv_shmaddr); + shmctl(xv->xv_shmid, IPC_RMID, NULL); + } + if (xv->xv_pixfmts) + { + xfree(xv->xv_pixfmts); + xv->xv_pixfmts = NULL; + } + xfree(xv); + xfi->xv_context = NULL; + } +} + +static boolean +xf_tsmf_is_format_supported(xfXvContext* xv, uint32 pixfmt) +{ + int i; + + if (!xv->xv_pixfmts) + return false; + + for (i = 0; xv->xv_pixfmts[i]; i++) + { + if (xv->xv_pixfmts[i] == pixfmt) + return true; + } + + return false; +} + +static void xf_process_tsmf_video_frame_event(xfInfo* xfi, RDP_VIDEO_FRAME_EVENT* vevent) +{ + int i; + uint8* data1; + uint8* data2; + uint32 pixfmt; + XvImage * image; + int colorkey = 0; + XShmSegmentInfo shminfo; + xfXvContext* xv = (xfXvContext*) xfi->xv_context; + + if (xv->xv_port == 0) + return; + + /* In case the player is minimized */ + if (vevent->x < -2048 || vevent->y < -2048 || vevent->num_visible_rects <= 0) + return; + + if (xv->xv_colorkey_atom != None) + { + XvGetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, &colorkey); + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XSetForeground(xfi->display, xfi->gc, colorkey); + for (i = 0; i < vevent->num_visible_rects; i++) + { + XFillRectangle(xfi->display, xfi->window->handle, xfi->gc, + vevent->x + vevent->visible_rects[i].x, + vevent->y + vevent->visible_rects[i].y, + vevent->visible_rects[i].width, + vevent->visible_rects[i].height); + } + } + + pixfmt = vevent->frame_pixfmt; + image = XvShmCreateImage(xfi->display, xv->xv_port, + pixfmt, 0, vevent->frame_width, vevent->frame_height, &shminfo); + if (xv->xv_image_size != image->data_size) + { + if (xv->xv_image_size > 0) + { + shmdt(xv->xv_shmaddr); + shmctl(xv->xv_shmid, IPC_RMID, NULL); + } + xv->xv_image_size = image->data_size; + xv->xv_shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); + xv->xv_shmaddr = shmat(xv->xv_shmid, 0, 0); + } + shminfo.shmid = xv->xv_shmid; + shminfo.shmaddr = image->data = xv->xv_shmaddr; + shminfo.readOnly = false; + + if (!XShmAttach(xfi->display, &shminfo)) + { + XFree(image); + DEBUG_XV("XShmAttach failed."); + return; + } + + /* The video driver may align each line to a different size + and we need to convert our original image data. */ + switch (pixfmt) + { + case RDP_PIXFMT_I420: + case RDP_PIXFMT_YV12: + if (!xf_tsmf_is_format_supported(xv, RDP_PIXFMT_I420) && + !xf_tsmf_is_format_supported(xv, RDP_PIXFMT_YV12)) + { + DEBUG_XV("pixel format 0x%X not supported by hardware.", pixfmt); + break; + } + /* Y */ + if (image->pitches[0] == vevent->frame_width) + { + memcpy(image->data + image->offsets[0], + vevent->frame_data, + vevent->frame_width * vevent->frame_height); + } + else + { + for (i = 0; i < vevent->frame_height; i++) + { + memcpy(image->data + image->offsets[0] + i * image->pitches[0], + vevent->frame_data + i * vevent->frame_width, + vevent->frame_width); + } + } + /* UV */ + /* Conversion between I420 and YV12 is to simply swap U and V */ + if (xf_tsmf_is_format_supported(xv, pixfmt)) + { + data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height; + data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height + + vevent->frame_width * vevent->frame_height / 4; + } + else + { + data2 = vevent->frame_data + vevent->frame_width * vevent->frame_height; + data1 = vevent->frame_data + vevent->frame_width * vevent->frame_height + + vevent->frame_width * vevent->frame_height / 4; + image->id = pixfmt == RDP_PIXFMT_I420 ? RDP_PIXFMT_YV12 : RDP_PIXFMT_I420; + } + if (image->pitches[1] * 2 == vevent->frame_width) + { + memcpy(image->data + image->offsets[1], + data1, + vevent->frame_width * vevent->frame_height / 4); + memcpy(image->data + image->offsets[2], + data2, + vevent->frame_width * vevent->frame_height / 4); + } + else + { + for (i = 0; i < vevent->frame_height / 2; i++) + { + memcpy(image->data + image->offsets[1] + i * image->pitches[1], + data1 + i * vevent->frame_width / 2, + vevent->frame_width / 2); + memcpy(image->data + image->offsets[2] + i * image->pitches[2], + data2 + i * vevent->frame_width / 2, + vevent->frame_width / 2); + } + } + break; + + default: + memcpy(image->data, vevent->frame_data, image->data_size <= vevent->frame_size ? + image->data_size : vevent->frame_size); + break; + } + + XvShmPutImage(xfi->display, xv->xv_port, xfi->window->handle, xfi->gc, image, + 0, 0, image->width, image->height, + vevent->x, vevent->y, vevent->width, vevent->height, false); + XSync(xfi->display, false); + + XShmDetach(xfi->display, &shminfo); + XFree(image); +} + +static void xf_process_tsmf_redraw_event(xfInfo* xfi, RDP_REDRAW_EVENT* revent) +{ + XSetFunction(xfi->display, xfi->gc, GXcopy); + XSetFillStyle(xfi->display, xfi->gc, FillSolid); + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, + revent->x, revent->y, revent->width, revent->height, revent->x, revent->y); +} + +void xf_process_tsmf_event(xfInfo* xfi, RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_TSMF_VIDEO_FRAME: + xf_process_tsmf_video_frame_event(xfi, (RDP_VIDEO_FRAME_EVENT*) event); + break; + + case RDP_EVENT_TYPE_TSMF_REDRAW: + xf_process_tsmf_redraw_event(xfi, (RDP_REDRAW_EVENT*) event); + break; + + } +} + +#else /* WITH_XV */ + +void xf_tsmf_init(xfInfo* xfi, long xv_port) +{ +} + +void xf_tsmf_uninit(xfInfo* xfi) +{ +} + +void xf_process_tsmf_event(xfInfo* xfi, RDP_EVENT* event) +{ +} + +#endif /* WITH_XV */ diff --git a/client/X11/xf_tsmf.h b/client/X11/xf_tsmf.h new file mode 100644 index 0000000..09083e2 --- /dev/null +++ b/client/X11/xf_tsmf.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Video Redirection + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_TSMF_H +#define __XF_TSMF_H + +#include "xfreerdp.h" + +void xf_tsmf_init(xfInfo* xfi, long xv_port); +void xf_tsmf_uninit(xfInfo* xfi); +void xf_process_tsmf_event(xfInfo* xfi, RDP_EVENT* event); + +#endif /* __XF_TSMF_H */ diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c new file mode 100644 index 0000000..a159c6b --- /dev/null +++ b/client/X11/xf_window.c @@ -0,0 +1,751 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include + +#ifdef WITH_XEXT +#include +#endif + +#include "FreeRDP_Icon_256px.h" +#define xf_icon_prop FreeRDP_Icon_256px_prop + +#include "xf_window.h" + +/* Extended Window Manager Hints: http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html */ + +/* bit definitions for MwmHints.flags */ +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +/* bit definitions for MwmHints.functions */ +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +/* bit definitions for MwmHints.decorations */ +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define PROP_MOTIF_WM_HINTS_ELEMENTS 5 + +struct _PropMotifWmHints +{ + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long inputMode; + unsigned long status; +}; +typedef struct _PropMotifWmHints PropMotifWmHints; + +/** + * Post an event from the client to the X server + */ +void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...) +{ + XEvent xevent; + unsigned int i; + va_list argp; + + va_start(argp, numArgs); + + xevent.xclient.type = ClientMessage; + xevent.xclient.serial = 0; + xevent.xclient.send_event = False; + xevent.xclient.display = xfi->display; + xevent.xclient.window = window->handle; + xevent.xclient.message_type = atom; + xevent.xclient.format = 32; + + for (i=0; idisplay, RootWindowOfScreen(xfi->screen), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xevent); + XSync(xfi->display, False); + + va_end(argp); +} + +void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen) +{ + if (fullscreen) + { + xf_SetWindowDecorations(xfi, window, false); + + XMoveResizeWindow(xfi->display, window->handle, 0, 0, window->width, window->height); + XMapRaised(xfi->display, window->handle); + + window->fullscreen = true; + } +} + +/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */ + +boolean xf_GetWindowProperty(xfInfo* xfi, Window window, Atom property, int length, + unsigned long* nitems, unsigned long* bytes, uint8** prop) +{ + int status; + Atom actual_type; + int actual_format; + + if (property == None) + return false; + + status = XGetWindowProperty(xfi->display, window, + property, 0, length, false, AnyPropertyType, + &actual_type, &actual_format, nitems, bytes, prop); + + if (status != Success) + return false; + + if (actual_type == None) + { + DEBUG_WARN("Property %lu does not exist", property); + return false; + } + + return true; +} + +boolean xf_GetCurrentDesktop(xfInfo* xfi) +{ + boolean status; + unsigned long nitems; + unsigned long bytes; + unsigned char* prop; + + status = xf_GetWindowProperty(xfi, DefaultRootWindow(xfi->display), + xfi->_NET_CURRENT_DESKTOP, 1, &nitems, &bytes, &prop); + + if (status != true) { + return false; + } + + xfi->current_desktop = (int) *prop; + xfree(prop); + + return true; +} + +boolean xf_GetWorkArea(xfInfo* xfi) +{ + long* plong; + boolean status; + unsigned long nitems; + unsigned long bytes; + unsigned char* prop; + + status = xf_GetCurrentDesktop(xfi); + + if (status != true) + return false; + + status = xf_GetWindowProperty(xfi, DefaultRootWindow(xfi->display), + xfi->_NET_WORKAREA, 32 * 4, &nitems, &bytes, &prop); + + if (status != true) + return false; + + if ((xfi->current_desktop * 4 + 3) >= nitems) { + xfree(prop); + return false; + } + + plong = (long*) prop; + + xfi->workArea.x = plong[xfi->current_desktop * 4 + 0]; + xfi->workArea.y = plong[xfi->current_desktop * 4 + 1]; + xfi->workArea.width = plong[xfi->current_desktop * 4 + 2]; + xfi->workArea.height = plong[xfi->current_desktop * 4 + 3]; + xfree(prop); + + return true; +} + +void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show) +{ + PropMotifWmHints hints; + + hints.decorations = (show) ? MWM_DECOR_ALL : 0; + hints.functions = MWM_FUNC_ALL ; + hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS; + + XChangeProperty(xfi->display, window->handle, xfi->_MOTIF_WM_HINTS, xfi->_MOTIF_WM_HINTS, 32, + PropModeReplace, (uint8*) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS); +} + +void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window) +{ + Atom window_state[2]; + + window_state[0] = xfi->_NET_WM_STATE_SKIP_PAGER; + window_state[1] = xfi->_NET_WM_STATE_SKIP_TASKBAR; + + XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_STATE, + XA_ATOM, 32, PropModeReplace, (uint8*) &window_state, 2); +} + +void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style) +{ + Atom window_type; + + if ((ex_style & WS_EX_TOPMOST) || (ex_style & WS_EX_TOOLWINDOW)) + { + /* + * These include tool tips, dropdown menus, etc. These won't work + * correctly if the local window manager resizes or moves them. + * Set override redirect to prevent this from occurring. + */ + + XSetWindowAttributes attrs; + attrs.override_redirect = True; + XChangeWindowAttributes(xfi->display, window->handle, CWOverrideRedirect, &attrs); + window->is_transient = true; + xf_SetWindowUnlisted(xfi, window); + + window_type = xfi->_NET_WM_WINDOW_TYPE_POPUP; + } + else if (style & WS_POPUP) + { + /* this includes dialogs, popups, etc, that need to be full-fledged windows */ + window_type = xfi->_NET_WM_WINDOW_TYPE_DIALOG; + xf_SetWindowUnlisted(xfi, window); + } + else + { + window_type = xfi->_NET_WM_WINDOW_TYPE_NORMAL; + } + + XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_WINDOW_TYPE, + XA_ATOM, 32, PropModeReplace, (uint8*) &window_type, 1); + +} + +xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, boolean decorations) +{ + xfWindow* window; + + window = (xfWindow*) xzalloc(sizeof(xfWindow)); + + if (window != NULL) + { + int input_mask; + XClassHint* class_hints; + + window->width = width; + window->height = height; + window->fullscreen = false; + window->decorations = decorations; + window->local_move.state = LMS_NOT_ACTIVE; + window->is_mapped = false; + window->is_transient = false; + + window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), + xfi->workArea.x, xfi->workArea.y, xfi->width, xfi->height, 0, xfi->depth, InputOutput, xfi->visual, + CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | + CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs); + + class_hints = XAllocClassHint(); + + if (class_hints != NULL) + { + class_hints->res_name = "xfreerdp"; + class_hints->res_class = "xfreerdp"; + XSetClassHint(xfi->display, window->handle, class_hints); + XFree(class_hints); + } + + xf_ResizeDesktopWindow(xfi, window, width, height); + xf_SetWindowDecorations(xfi, window, decorations); + + input_mask = + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + VisibilityChangeMask | FocusChangeMask | StructureNotifyMask | + PointerMotionMask | ExposureMask | PropertyChangeMask; + + if (xfi->grab_keyboard) + input_mask |= EnterWindowMask | LeaveWindowMask; + + XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_ICON, XA_CARDINAL, 32, + PropModeReplace, (uint8*) xf_icon_prop, sizeof(xf_icon_prop) / sizeof(long)); + + XSelectInput(xfi->display, window->handle, input_mask); + XMapWindow(xfi->display, window->handle); + } + + XStoreName(xfi->display, window->handle, name); + + return window; +} + +void xf_ResizeDesktopWindow(xfInfo* xfi, xfWindow* window, int width, int height) +{ + XSizeHints* size_hints; + + size_hints = XAllocSizeHints(); + + if (size_hints) + { + size_hints->flags = PMinSize | PMaxSize; + size_hints->min_width = size_hints->max_width = xfi->width; + size_hints->min_height = size_hints->max_height = xfi->height; + XSetWMNormalHints(xfi->display, window->handle, size_hints); + XFree(size_hints); + } +} + +void xf_FixWindowCoordinates(xfInfo* xfi, int* x, int* y, int* width, int* height) +{ + int vscreen_width; + int vscreen_height; + + vscreen_width = xfi->vscreen.area.right - xfi->vscreen.area.left + 1; + vscreen_height = xfi->vscreen.area.bottom - xfi->vscreen.area.top + 1; + + if (*width < 1) + { + *width = 1; + } + if (*height < 1) + { + *height = 1; + } + if (*x < xfi->vscreen.area.left) + { + *width += *x; + *x = xfi->vscreen.area.left; + } + if (*y < xfi->vscreen.area.top) + { + *height += *y; + *y = xfi->vscreen.area.top; + } + if (*width > vscreen_width) + { + *width = vscreen_width; + } + if (*height > vscreen_height) + { + *height = vscreen_height; + } +} + +char rail_window_class[] = "RAIL:00000000"; + +xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, int height, uint32 id) +{ + xfWindow* window; + + window = (xfWindow*) xzalloc(sizeof(xfWindow)); + + xf_FixWindowCoordinates(xfi, &x, &y, &width, &height); + + window->left = x; + window->top = y; + window->right = x + width - 1; + window->bottom = y + height - 1; + window->width = width; + window->height = height; + + XGCValues gcv; + XClassHint* class_hints; + int input_mask; + + window->decorations = false; + window->fullscreen = false; + window->window = wnd; + window->local_move.state = LMS_NOT_ACTIVE; + window->is_mapped = false; + window->is_transient = false; + + window->handle = XCreateWindow(xfi->display, RootWindowOfScreen(xfi->screen), + x, y, window->width, window->height, 0, xfi->depth, InputOutput, xfi->visual, + CWBackPixel | CWBackingStore | CWOverrideRedirect | CWColormap | + CWBorderPixel | CWWinGravity | CWBitGravity, &xfi->attribs); + + DEBUG_X11_LMS("Create window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d rdp=0x%X", + (uint32) window->handle, window->left, window->top, window->right, window->bottom, + window->width, window->height, wnd->windowId); + + xf_SetWindowDecorations(xfi, window, window->decorations); + xf_SetWindowStyle(xfi, window, wnd->style, wnd->extendedStyle); + + class_hints = XAllocClassHint(); + + if (class_hints != NULL) + { + char* class; + class = xmalloc(sizeof(rail_window_class)); + snprintf(class, sizeof(rail_window_class), "RAIL:%08X", id); + class_hints->res_name = "RAIL"; + class_hints->res_class = class; + XSetClassHint(xfi->display, window->handle, class_hints); + XFree(class_hints); + xfree(class); + } + + XSetWMProtocols(xfi->display, window->handle, &(xfi->WM_DELETE_WINDOW), 1); + + input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | + ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | + PointerMotionMask | Button1MotionMask | Button2MotionMask | + Button3MotionMask | Button4MotionMask | Button5MotionMask | + ButtonMotionMask | KeymapStateMask | ExposureMask | + VisibilityChangeMask | StructureNotifyMask | SubstructureNotifyMask | + SubstructureRedirectMask | FocusChangeMask | PropertyChangeMask | + ColormapChangeMask | OwnerGrabButtonMask; + + XSelectInput(xfi->display, window->handle, input_mask); + XMapWindow(xfi->display, window->handle); + + memset(&gcv, 0, sizeof(gcv)); + window->gc = XCreateGC(xfi->display, window->handle, GCGraphicsExposures, &gcv); + + xf_MoveWindow(xfi, window, x, y, width, height); + + return window; +} + +void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, + int maxWidth, int maxHeight, int maxPosX, int maxPosY, + int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight) +{ + XSizeHints* size_hints; + + size_hints = XAllocSizeHints(); + + if (size_hints) + { + size_hints->flags = PMinSize | PMaxSize | PResizeInc; + + size_hints->min_width = minTrackWidth; + size_hints->min_height = minTrackHeight; + + size_hints->max_width = maxTrackWidth; + size_hints->max_height = maxTrackHeight; + + /* to speedup window drawing we need to select optimal value for sizing step. */ + size_hints->width_inc = size_hints->height_inc = 1; + + XSetWMNormalHints(xfi->display, window->handle, size_hints); + XFree(size_hints); + } +} + +void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y) +{ + Window child_window; + + if (window->local_move.state != LMS_NOT_ACTIVE) + return; + + DEBUG_X11_LMS("direction=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d " + "RDP=0x%X rc={l=%d t=%d} w=%d h=%d mouse_x=%d mouse_y=%d", + direction, (uint32) window->handle, + window->left, window->top, window->right, window->bottom, + window->width, window->height, window->window->windowId, + window->window->windowOffsetX, window->window->windowOffsetY, + window->window->windowWidth, window->window->windowHeight, x, y); + + window->local_move.root_x = x; + window->local_move.root_y = y; + window->local_move.state = LMS_STARTING; + + XTranslateCoordinates(xfi->display, RootWindowOfScreen(xfi->screen), window->handle, + window->local_move.root_x, + window->local_move.root_y, + &window->local_move.window_x, + &window->local_move.window_y, + &child_window); + + XUngrabPointer(xfi->display, CurrentTime); + + xf_SendClientEvent(xfi, window, + xfi->_NET_WM_MOVERESIZE, /* request X window manager to initiate a local move */ + 5, /* 5 arguments to follow */ + x, /* x relative to root window */ + y, /* y relative to root window */ + direction, /* extended ICCM direction flag */ + 1, /* simulated mouse button 1 */ + 1); /* 1 == application request per extended ICCM */ +} + +void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window) +{ + + DEBUG_X11_LMS("state=%d window=0x%X rc={l=%d t=%d r=%d b=%d} w=%d h=%d " + "RDP=0x%X rc={l=%d t=%d} w=%d h=%d", + window->local_move.state, + (uint32) window->handle, window->left, window->top, window->right, window->bottom, + window->width, window->height, window->window->windowId, + window->window->windowOffsetX, window->window->windowOffsetY, + window->window->windowWidth, window->window->windowHeight); + + if (window->local_move.state == LMS_NOT_ACTIVE) + return; + + if (window->local_move.state == LMS_STARTING) + { + /* + * The move never was property started. This can happen due to race + * conditions between the mouse button up and the communications to the + * RDP server for local moves. We must cancel the X window manager move. + * Per ICCM, the X client can ask to cancel an active move. + */ + xf_SendClientEvent(xfi, window, + xfi->_NET_WM_MOVERESIZE, /* request X window manager to abort a local move */ + 5, /* 5 arguments to follow */ + window->local_move.root_x, /* x relative to root window */ + window->local_move.root_y, /* y relative to root window */ + _NET_WM_MOVERESIZE_CANCEL, /* extended ICCM direction flag */ + 1, /* simulated mouse button 1 */ + 1); /* 1 == application request per extended ICCM */ + } + + window->local_move.state = LMS_NOT_ACTIVE; +} + +void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height) +{ + boolean resize = false; + + if ((width * height) < 1) + return; + + if ((window->width != width) || (window->height != height)) + resize = true; + + if (window->local_move.state == LMS_STARTING || + window->local_move.state == LMS_ACTIVE) + return; + + DEBUG_X11_LMS("window=0x%X rc={l=%d t=%d r=%d b=%d} w=%u h=%u " + "new rc={l=%d t=%d r=%d b=%d} w=%u h=%u" + " RDP=0x%X rc={l=%d t=%d} w=%d h=%d", + (uint32) window->handle, window->left, window->top, + window->right, window->bottom, window->width, window->height, + x, y, x + width -1, y + height -1, width, height, + window->window->windowId, + window->window->windowOffsetX, window->window->windowOffsetY, + window->window->windowWidth, window->window->windowHeight); + + window->left = x; + window->top = y; + window->right = x + width - 1; + window->bottom = y + height - 1; + window->width = width; + window->height = height; + + if (resize) + XMoveResizeWindow(xfi->display, window->handle, x, y, width, height); + else + XMoveWindow(xfi->display, window->handle, x, y); + + xf_UpdateWindowArea(xfi, window, 0, 0, width, height); +} + +void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state) +{ + switch (state) + { + case WINDOW_HIDE: + XWithdrawWindow(xfi->display, window->handle, xfi->screen_number); + break; + + case WINDOW_SHOW_MINIMIZED: + XIconifyWindow(xfi->display, window->handle, xfi->screen_number); + break; + + case WINDOW_SHOW_MAXIMIZED: + XRaiseWindow(xfi->display, window->handle); + break; + + case WINDOW_SHOW: + XMapWindow(xfi->display, window->handle); + break; + } + + XFlush(xfi->display); +} + +void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon) +{ + int x, y; + int pixels; + int propsize; + long* propdata; + long* dstp; + uint32* srcp; + + if (icon->big != true) + return; + + pixels = icon->entry->width * icon->entry->height; + propsize = 2 + pixels; + propdata = xmalloc(propsize * sizeof(long)); + + propdata[0] = icon->entry->width; + propdata[1] = icon->entry->height; + dstp = &(propdata[2]); + srcp = (uint32*) icon->extra; + + for (y = 0; y < icon->entry->height; y++) + { + for (x = 0; x < icon->entry->width; x++) + { + *dstp++ = *srcp++; + } + } + + XChangeProperty(xfi->display, window->handle, xfi->_NET_WM_ICON, XA_CARDINAL, 32, + PropModeReplace, (uint8*) propdata, propsize); + + XFlush(xfi->display); +} + +void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects) +{ + int i; + XRectangle* xrects; + + xrects = xmalloc(sizeof(XRectangle) * nrects); + + for (i = 0; i < nrects; i++) + { + xrects[i].x = rects[i].left; + xrects[i].y = rects[i].top; + xrects[i].width = rects[i].right - rects[i].left; + xrects[i].height = rects[i].bottom - rects[i].top; + } + +#ifdef WITH_XEXT + XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); +#endif + + xfree(xrects); +} + +void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects) +{ + int i; + XRectangle* xrects; + + xrects = xmalloc(sizeof(XRectangle) * nrects); + + for (i = 0; i < nrects; i++) + { + xrects[i].x = rects[i].left; + xrects[i].y = rects[i].top; + xrects[i].width = rects[i].right - rects[i].left; + xrects[i].height = rects[i].bottom - rects[i].top; + } + +#ifdef WITH_XEXT + //XShapeCombineRectangles(xfi->display, window->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); +#endif + + xfree(xrects); +} + +void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height) +{ + int ax, ay; + rdpWindow* wnd; + wnd = window->window; + + ax = x + wnd->windowOffsetX; + ay = y + wnd->windowOffsetY; + + if (ax + width > wnd->windowOffsetX + wnd->windowWidth) + width = (wnd->windowOffsetX + wnd->windowWidth - 1) - ax; + + if (ay + height > wnd->windowOffsetY + wnd->windowHeight) + height = (wnd->windowOffsetY + wnd->windowHeight - 1) - ay; + + if (xfi->sw_gdi) + { + XPutImage(xfi->display, xfi->primary, window->gc, xfi->image, + ax, ay, ax, ay, width, height); + } + + XCopyArea(xfi->display, xfi->primary, window->handle, window->gc, + ax, ay, width, height, x, y); + + XFlush(xfi->display); +} + +boolean xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y) +{ + rdpWindow* wnd; + boolean clientArea = false; + boolean windowArea = false; + + wnd = xfw->window; + + if (((x > wnd->clientOffsetX) && (x < wnd->clientOffsetX + wnd->clientAreaWidth)) && + ((y > wnd->clientOffsetY) && (y < wnd->clientOffsetY + wnd->clientAreaHeight))) + clientArea = true; + + if (((x > wnd->windowOffsetX) && (x < wnd->windowOffsetX + wnd->windowWidth)) && + ((y > wnd->windowOffsetY) && (y < wnd->windowOffsetY + wnd->windowHeight))) + windowArea = true; + + return (windowArea && !(clientArea)); +} + +void xf_DestroyWindow(xfInfo* xfi, xfWindow* window) +{ + if (window == NULL) + return; + + if (xfi->window == window) + xfi->window = NULL; + + if (window->gc) + XFreeGC(xfi->display, window->gc); + + if (window->handle) + { + XUnmapWindow(xfi->display, window->handle); + XDestroyWindow(xfi->display, window->handle); + } + + xfree(window); +} diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h new file mode 100644 index 0000000..15a2c86 --- /dev/null +++ b/client/X11/xf_window.h @@ -0,0 +1,112 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_WINDOW_H +#define __XF_WINDOW_H + +#include +#include +#include + +typedef struct xf_localmove xfLocalMove; +typedef struct xf_window xfWindow; + +#include "xfreerdp.h" + +// Extended ICCM flags http://standards.freedesktop.org/wm-spec/wm-spec-latest.html +#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 +#define _NET_WM_MOVERESIZE_SIZE_TOP 1 +#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 +#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 +#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 +#define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */ +#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */ +#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */ +#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */ + +enum xf_localmove_state +{ + LMS_NOT_ACTIVE, + LMS_STARTING, + LMS_ACTIVE, + LMS_TERMINATING +}; + +struct xf_localmove +{ + int root_x; // relative to root + int root_y; + int window_x; // relative to window + int window_y; + enum xf_localmove_state state; +}; + +struct xf_window +{ + GC gc; + int left; + int top; + int right; + int bottom; + int width; + int height; + Window handle; + boolean fullscreen; + boolean decorations; + rdpWindow* window; + boolean is_mapped; + boolean is_transient; + xfLocalMove local_move; +}; + +void xf_ewmhints_init(xfInfo* xfi); + +boolean xf_GetCurrentDesktop(xfInfo* xfi); +boolean xf_GetWorkArea(xfInfo* xfi); + +void xf_SetWindowFullscreen(xfInfo* xfi, xfWindow* window, boolean fullscreen); +void xf_SetWindowDecorations(xfInfo* xfi, xfWindow* window, boolean show); +void xf_SetWindowUnlisted(xfInfo* xfi, xfWindow* window); + +xfWindow* xf_CreateDesktopWindow(xfInfo* xfi, char* name, int width, int height, boolean decorations); +void xf_ResizeDesktopWindow(xfInfo* xfi, xfWindow* window, int width, int height); + +xfWindow* xf_CreateWindow(xfInfo* xfi, rdpWindow* wnd, int x, int y, int width, int height, uint32 id); +void xf_MoveWindow(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height); +void xf_ShowWindow(xfInfo* xfi, xfWindow* window, uint8 state); +void xf_SetWindowIcon(xfInfo* xfi, xfWindow* window, rdpIcon* icon); +void xf_SetWindowRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects); +void xf_SetWindowVisibilityRects(xfInfo* xfi, xfWindow* window, RECTANGLE_16* rects, int nrects); +void xf_SetWindowStyle(xfInfo* xfi, xfWindow* window, uint32 style, uint32 ex_style); +void xf_UpdateWindowArea(xfInfo* xfi, xfWindow* window, int x, int y, int width, int height); +boolean xf_IsWindowBorder(xfInfo* xfi, xfWindow* xfw, int x, int y); +void xf_DestroyWindow(xfInfo* xfi, xfWindow* window); + +void xf_SetWindowMinMaxInfo(xfInfo* xfi, xfWindow* window, int maxWidth, int maxHeight, + int maxPosX, int maxPosY, int minTrackWidth, int minTrackHeight, int maxTrackWidth, int maxTrackHeight); + + +void xf_StartLocalMoveSize(xfInfo* xfi, xfWindow* window, int direction, int x, int y); +void xf_EndLocalMoveSize(xfInfo *xfi, xfWindow *window); +void xf_SendClientEvent(xfInfo *xfi, xfWindow* window, Atom atom, unsigned int numArgs, ...); + +#endif /* __XF_WINDOW_H */ diff --git a/client/X11/xfreerdp.1.xml b/client/X11/xfreerdp.1.xml new file mode 100644 index 0000000..39e89e3 --- /dev/null +++ b/client/X11/xfreerdp.1.xml @@ -0,0 +1,461 @@ + + + + 2011-08-27 + + The FreeRDP Team + + + + xfreerdp + 1 + freerdp + xfreerdp + + + xfreerdp + FreeRDP X11 client + + + + 2011-08-27 + + + xfreerdp [options] server[:port] [[options] server[:port] …] + + + + + 2011-08-27 + + DESCRIPTION + + xfreerdp is an X11 Remote Desktop Protocol (RDP) + client which is part of the FreeRDP project. An RDP server is built-in + to many editions of Windows. Alternative servers included xrdp and VRDP (VirtualBox). + + + + OPTIONS + + + -0 + + + Attach to the admin console of the server. + + + + + -a bpp + + + Sets the color depth for the connection to bpp bits per pixel. + Valid values are 8, 15, 16, 24 and 32. The default value is the color depth of the FreeRDP-window. + + + + + -c dir + + + Sets the working-dir to dir. + This parameter is only used when an AlternateShell () is requested. + dir should contain the executable file specified in the AlternateShell. + + + + + -D + + + Removes the windows decorations. + + + + + -d + + + Domain used in authentication. + + + + + -f + + + start in full screen mode. This mode can always be en- and disabled using Ctrl-Alt-Enter. + + + + + -T text + + + Sets the window title to text. + + + + + -g geometry + + + Sets the size of the FreeRDP window (and of the remote desktop, when establishing a new connection). + geometry can have one of the following forms: + + + + WxH - + in this case the resulting window will be of + WxH pixels. + + + + + P% - + in this case the resulting window will be P% + of your screen. + + + + + The special keyword workarea - + in this case the resulting window will be of the same size as your workarea. + + + + + + + + -k id + + + Sets the keyboard-layout-id to id. + + + + + -m + + + Don't send mouse motion events. + + + + + -n hostname + + + Set the reported client hostname to hostname. + Default is to automatically detect the hostname. + + + + + -o + + + Play audio on the console instead of redirecting to the client. + + + + + -p password + + + Password used in authentication. + + + + + -s shell + + + Sets the startup-shell to shell. + This parameter should contain a complete path to the alternate shell. + If the alternete shell requires a different working directory use . + + + + + -t port + + + Connect to port, instead of the default 3389. + + + + + -u username + + + Username used in authentication. + + + + + -x flag + + + Set the experiance performance flags. + flag can be one of: + + + + m - (modem): Equivalent to 15. + + + + + b - (broadband): Equivalent to 1. + + + + + l - (lan): Equivalent to 0. + + + + + num - A hexadecimal number that + represents a bit-mask, were numbers mean the following + Taken from + MS-RDPBCGR Section 2.2.1.11.1.1.1 - Extended Info Packet: + + + 1: Disable desktop wallpaper. + + + 2: Disable full-window drag (only the window outline is displayed when the window is moved). + + + 4: Disable menu animations. + + + 8: Disable user interface themes. + + + 20: Disable mouse cursor shadows. + + + 40: Disable cursor blinking. + + + 80: Enable font smoothing. + + + 100: Enable Desktop Composition. + + + + + + + + + + -z + + + Enable compression. + + + + + --app + + + initialize a RemoteApp connection. This implies -g workarea. + + + + + --ext + + + load an extension + + + + + --no-auth + + + Skips authentication. This is useful e.g. for the current FreeRDP server that doesn't yet support server-side authentication. + + + + + --no-fastpath + + + Disables fast-path. Use slow-path packets instead, which have larger headers. + It might be good for debugging certain issues when you suspect it might be + linked to the parsing of one of the two header types. + + + + + --gdi + + + GDI rendering backend. backend can be either sw (software) or hw (hardware). + + + + + --no-osb + + + Disable off screen bitmaps. + + + + + --no-bmp-cache + + + Disable bitmap cache. + + + + + --plugin + + + load a plugin + + + + + --rfx + + + Enable RemoteFX. + + + + + --rfx-mode + + + RemoteFX operational flags. flags can be either v[ideo], i[mage]), default is video. + + + + + --nsc + + + Enable NSCodec. + + + + + --disable-wallpaper + + + Disable wallpaper. + + + + + --composition + + + Enable composition (RDVH only, not to be confused with remote composition). + + + + + --disable-full-window-drag + + + Disable full window drag. + + + + + --disable-menu-animations + + + Disable menu animations. + + + + + --disable-theming + + + Disable theming. + + + + + --no-rdp + + + Disable Standard RDP encryption. + + + + + --no-tls + + + Disable TLS encryption. + + + + + --no-nla + + + Disable network level authentication. + + + + + --sec proto + + + force protocol security. proto can be one of rdp, tls or nla. + + + + + --ntlm + + + force NTLM protocol version. version can be one of 1 or 2. + + + + + --ignore-certificate + + + ignore verification of logon certificate. + + + + + --version + + + Print version information. + + + + + + + LINKS + + http://www.freerdp.com/ + + + diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c new file mode 100644 index 0000000..de58122 --- /dev/null +++ b/client/X11/xfreerdp.c @@ -0,0 +1,1131 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Client + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#ifdef WITH_XCURSOR +#include +#endif + +#ifdef WITH_XINERAMA +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xf_gdi.h" +#include "xf_rail.h" +#include "xf_tsmf.h" +#include "xf_event.h" +#include "xf_cliprdr.h" +#include "xf_monitor.h" +#include "xf_graphics.h" +#include "xf_keyboard.h" + +#include "xfreerdp.h" + +static freerdp_sem g_sem; +static int g_thread_count = 0; +static uint8 g_disconnect_reason = 0; + +static long xv_port = 0; +static const size_t password_size = 512; + +struct thread_data +{ + freerdp* instance; +}; + +int xf_process_client_args(rdpSettings* settings, const char* opt, const char* val, void* user_data); +int xf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data); + +void xf_context_new(freerdp* instance, rdpContext* context) +{ + context->channels = freerdp_channels_new(); +} + +void xf_context_free(freerdp* instance, rdpContext* context) +{ + +} + +void xf_sw_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +void xf_sw_end_paint(rdpContext* context) +{ + rdpGdi* gdi; + xfInfo* xfi; + sint32 x, y; + uint32 w, h; + + xfi = ((xfContext*) context)->xfi; + gdi = context->gdi; + + if (xfi->remote_app != true) + { + if (xfi->complex_regions != true) + { + if (gdi->primary->hdc->hwnd->invalid->null) + return; + + x = gdi->primary->hdc->hwnd->invalid->x; + y = gdi->primary->hdc->hwnd->invalid->y; + w = gdi->primary->hdc->hwnd->invalid->w; + h = gdi->primary->hdc->hwnd->invalid->h; + + XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } + else + { + int i; + int ninvalid; + HGDI_RGN cinvalid; + + if (gdi->primary->hdc->hwnd->ninvalid < 1) + return; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + for (i = 0; i < ninvalid; i++) + { + x = cinvalid[i].x; + y = cinvalid[i].y; + w = cinvalid[i].w; + h = cinvalid[i].h; + + XPutImage(xfi->display, xfi->primary, xfi->gc, xfi->image, x, y, x, y, w, h); + XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y); + } + + XFlush(xfi->display); + } + } + else + { + if (gdi->primary->hdc->hwnd->invalid->null) + return; + + x = gdi->primary->hdc->hwnd->invalid->x; + y = gdi->primary->hdc->hwnd->invalid->y; + w = gdi->primary->hdc->hwnd->invalid->w; + h = gdi->primary->hdc->hwnd->invalid->h; + + xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1); + } +} + +void xf_sw_desktop_resize(rdpContext* context) +{ + xfInfo* xfi; + rdpSettings* settings; + + xfi = ((xfContext*) context)->xfi; + settings = xfi->instance->settings; + + if (xfi->fullscreen != true) + { + rdpGdi* gdi = context->gdi; + gdi_resize(gdi, xfi->width, xfi->height); + + if (xfi->image) + { + xfi->image->data = NULL; + XDestroyImage(xfi->image); + xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0, + (char*) gdi->primary_buffer, gdi->width, gdi->height, xfi->scanline_pad, 0); + } + } +} + +void xf_hw_begin_paint(rdpContext* context) +{ + xfInfo* xfi; + xfi = ((xfContext*) context)->xfi; + xfi->hdc->hwnd->invalid->null = 1; + xfi->hdc->hwnd->ninvalid = 0; +} + +void xf_hw_end_paint(rdpContext* context) +{ + xfInfo* xfi; + sint32 x, y; + uint32 w, h; + + xfi = ((xfContext*) context)->xfi; + + if (xfi->remote_app) + { + if (xfi->hdc->hwnd->invalid->null) + return; + + x = xfi->hdc->hwnd->invalid->x; + y = xfi->hdc->hwnd->invalid->y; + w = xfi->hdc->hwnd->invalid->w; + h = xfi->hdc->hwnd->invalid->h; + + xf_rail_paint(xfi, context->rail, x, y, x + w - 1, y + h - 1); + } +} + +void xf_hw_desktop_resize(rdpContext* context) +{ + xfInfo* xfi; + boolean same; + rdpSettings* settings; + + xfi = ((xfContext*) context)->xfi; + settings = xfi->instance->settings; + + if (xfi->fullscreen != true) + { + xfi->width = settings->width; + xfi->height = settings->height; + + if (xfi->window) + xf_ResizeDesktopWindow(xfi, xfi->window, settings->width, settings->height); + + if (xfi->primary) + { + same = (xfi->primary == xfi->drawing) ? true : false; + + XFreePixmap(xfi->display, xfi->primary); + + xfi->primary = XCreatePixmap(xfi->display, xfi->drawable, + xfi->width, xfi->height, xfi->depth); + + if (same) + xfi->drawing = xfi->primary; + } + } +} + +boolean xf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +{ + xfInfo* xfi = ((xfContext*) instance->context)->xfi; + + rfds[*rcount] = (void*)(long)(xfi->xfds); + (*rcount)++; + + return true; +} + +boolean xf_check_fds(freerdp* instance, fd_set* set) +{ + XEvent xevent; + xfInfo* xfi = ((xfContext*) instance->context)->xfi; + + while (XPending(xfi->display)) + { + memset(&xevent, 0, sizeof(xevent)); + XNextEvent(xfi->display, &xevent); + + if (xf_event_process(instance, &xevent) != true) + return false; + } + + return true; +} + +void xf_create_window(xfInfo* xfi) +{ + XEvent xevent; + char* win_title; + int width, height; + + width = xfi->width; + height = xfi->height; + + xfi->attribs.background_pixel = BlackPixelOfScreen(xfi->screen); + xfi->attribs.border_pixel = WhitePixelOfScreen(xfi->screen); + xfi->attribs.backing_store = xfi->primary ? NotUseful : Always; + xfi->attribs.override_redirect = xfi->fullscreen; + xfi->attribs.colormap = xfi->colormap; + xfi->attribs.bit_gravity = ForgetGravity; + xfi->attribs.win_gravity = StaticGravity; + + if (xfi->instance->settings->window_title != NULL) + { + win_title = xstrdup(xfi->instance->settings->window_title); + } + else if (xfi->instance->settings->port == 3389) + { + win_title = xmalloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname)); + sprintf(win_title, "FreeRDP: %s", xfi->instance->settings->hostname); + } + else + { + win_title = xmalloc(1 + sizeof("FreeRDP: ") + strlen(xfi->instance->settings->hostname) + sizeof(":00000")); + sprintf(win_title, "FreeRDP: %s:%i", xfi->instance->settings->hostname, xfi->instance->settings->port); + } + + xfi->window = xf_CreateDesktopWindow(xfi, win_title, width, height, xfi->decorations); + xfree(win_title); + + if (xfi->parent_window) + XReparentWindow(xfi->display, xfi->window->handle, xfi->parent_window, 0, 0); + + if (xfi->fullscreen) + xf_SetWindowFullscreen(xfi, xfi->window, xfi->fullscreen); + + /* wait for VisibilityNotify */ + do + { + XMaskEvent(xfi->display, VisibilityChangeMask, &xevent); + } + while (xevent.type != VisibilityNotify); + + xfi->unobscured = (xevent.xvisibility.state == VisibilityUnobscured); + + XSetWMProtocols(xfi->display, xfi->window->handle, &(xfi->WM_DELETE_WINDOW), 1); + xfi->drawable = xfi->window->handle; +} + +void xf_toggle_fullscreen(xfInfo* xfi) +{ + Pixmap contents = 0; + + contents = XCreatePixmap(xfi->display, xfi->window->handle, xfi->width, xfi->height, xfi->depth); + XCopyArea(xfi->display, xfi->primary, contents, xfi->gc, 0, 0, xfi->width, xfi->height, 0, 0); + + XDestroyWindow(xfi->display, xfi->window->handle); + xfi->fullscreen = (xfi->fullscreen) ? false : true; + xf_create_window(xfi); + + XCopyArea(xfi->display, contents, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height, 0, 0); + XFreePixmap(xfi->display, contents); +} + +boolean xf_get_pixmap_info(xfInfo* xfi) +{ + int i; + int vi_count; + int pf_count; + XVisualInfo* vi; + XVisualInfo* vis; + XVisualInfo template; + XPixmapFormatValues* pf; + XPixmapFormatValues* pfs; + + pfs = XListPixmapFormats(xfi->display, &pf_count); + + if (pfs == NULL) + { + printf("xf_get_pixmap_info: XListPixmapFormats failed\n"); + return 1; + } + + for (i = 0; i < pf_count; i++) + { + pf = pfs + i; + + if (pf->depth == xfi->depth) + { + xfi->bpp = pf->bits_per_pixel; + xfi->scanline_pad = pf->scanline_pad; + break; + } + } + XFree(pfs); + + memset(&template, 0, sizeof(template)); + template.class = TrueColor; + template.screen = xfi->screen_number; + + vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count); + + if (vis == NULL) + { + printf("xf_get_pixmap_info: XGetVisualInfo failed\n"); + return false; + } + + vi = NULL; + for (i = 0; i < vi_count; i++) + { + vi = vis + i; + + if (vi->depth == xfi->depth) + { + xfi->visual = vi->visual; + break; + } + } + + if (vi) + { + /* + * Detect if the server visual has an inverted colormap + * (BGR vs RGB, or red being the least significant byte) + */ + + if (vi->red_mask & 0xFF) + { + xfi->clrconv->invert = true; + } + } + + XFree(vis); + + if ((xfi->visual == NULL) || (xfi->scanline_pad == 0)) + { + return false; + } + + return true; +} + +static int (*_def_error_handler)(Display*, XErrorEvent*); +int xf_error_handler(Display* d, XErrorEvent* ev) +{ + char buf[256]; + int do_abort = true; + + XGetErrorText(d, ev->error_code, buf, sizeof(buf)); + printf("%s", buf); + + if (do_abort) + abort(); + + _def_error_handler(d, ev); + + return false; +} + +int _xf_error_handler(Display* d, XErrorEvent* ev) +{ + /* + * ungrab the keyboard, in case a debugger is running in + * another window. This make xf_error_handler() a potential + * debugger breakpoint. + */ + XUngrabKeyboard(d, CurrentTime); + return xf_error_handler(d, ev); +} + +boolean xf_pre_connect(freerdp* instance) +{ + xfInfo* xfi; + boolean bitmap_cache; + rdpSettings* settings; + int arg_parse_result; + + xfi = (xfInfo*) xzalloc(sizeof(xfInfo)); + ((xfContext*) instance->context)->xfi = xfi; + + xfi->_context = instance->context; + xfi->context = (xfContext*) instance->context; + xfi->context->settings = instance->settings; + xfi->instance = instance; + + arg_parse_result = freerdp_parse_args(instance->settings, instance->context->argc,instance->context->argv, + xf_process_plugin_args, instance->context->channels, xf_process_client_args, xfi); + + if (arg_parse_result < 0) + { + if (arg_parse_result == FREERDP_ARGS_PARSE_FAILURE) + printf("failed to parse arguments.\n"); + + exit(XF_EXIT_PARSE_ARGUMENTS); + } + + settings = instance->settings; + bitmap_cache = settings->bitmap_cache; + + settings->os_major_type = OSMAJORTYPE_UNIX; + settings->os_minor_type = OSMINORTYPE_NATIVE_XSERVER; + settings->order_support[NEG_DSTBLT_INDEX] = true; + settings->order_support[NEG_PATBLT_INDEX] = true; + settings->order_support[NEG_SCRBLT_INDEX] = true; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; + settings->order_support[NEG_MULTIPATBLT_INDEX] = false; + settings->order_support[NEG_MULTISCRBLT_INDEX] = false; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; + settings->order_support[NEG_LINETO_INDEX] = true; + settings->order_support[NEG_POLYLINE_INDEX] = true; + settings->order_support[NEG_MEMBLT_INDEX] = bitmap_cache; + settings->order_support[NEG_MEM3BLT_INDEX] = false; + settings->order_support[NEG_MEMBLT_V2_INDEX] = bitmap_cache; + settings->order_support[NEG_MEM3BLT_V2_INDEX] = false; + settings->order_support[NEG_SAVEBITMAP_INDEX] = false; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_GLYPH_INDEX] = true; + settings->order_support[NEG_POLYGON_SC_INDEX] = false; + settings->order_support[NEG_POLYGON_CB_INDEX] = false; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; + + freerdp_channels_pre_connect(xfi->_context->channels, instance); + + xfi->display = XOpenDisplay(NULL); + + if (xfi->display == NULL) + { + printf("xf_pre_connect: failed to open display: %s\n", XDisplayName(NULL)); + printf("Please check that the $DISPLAY environment variable is properly set.\n"); + return false; + } + + if (xfi->debug) + { + printf("Enabling X11 debug mode.\n"); + XSynchronize(xfi->display, true); + _def_error_handler = XSetErrorHandler(_xf_error_handler); + } + + xfi->_NET_WM_ICON = XInternAtom(xfi->display, "_NET_WM_ICON", False); + xfi->_MOTIF_WM_HINTS = XInternAtom(xfi->display, "_MOTIF_WM_HINTS", False); + xfi->_NET_CURRENT_DESKTOP = XInternAtom(xfi->display, "_NET_CURRENT_DESKTOP", False); + xfi->_NET_WORKAREA = XInternAtom(xfi->display, "_NET_WORKAREA", False); + xfi->_NET_WM_STATE = XInternAtom(xfi->display, "_NET_WM_STATE", False); + xfi->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfi->display, "_NET_WM_STATE_FULLSCREEN", False); + xfi->_NET_WM_WINDOW_TYPE = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE", False); + + xfi->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_NORMAL", False); + xfi->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); + xfi->_NET_WM_WINDOW_TYPE_POPUP= XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_POPUP", False); + xfi->_NET_WM_WINDOW_TYPE_UTILITY = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_UTILITY", False); + xfi->_NET_WM_WINDOW_TYPE_DROPDOWN_MENU = XInternAtom(xfi->display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False); + xfi->_NET_WM_STATE_SKIP_TASKBAR = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_TASKBAR", False); + xfi->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfi->display, "_NET_WM_STATE_SKIP_PAGER", False); + xfi->_NET_WM_MOVERESIZE = XInternAtom(xfi->display, "_NET_WM_MOVERESIZE", False); + xfi->_NET_MOVERESIZE_WINDOW = XInternAtom(xfi->display, "_NET_MOVERESIZE_WINDOW", False); + + xfi->WM_PROTOCOLS = XInternAtom(xfi->display, "WM_PROTOCOLS", False); + xfi->WM_DELETE_WINDOW = XInternAtom(xfi->display, "WM_DELETE_WINDOW", False); + + xf_kbd_init(xfi); + + xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA); + + instance->context->cache = cache_new(instance->settings); + + xfi->xfds = ConnectionNumber(xfi->display); + xfi->screen_number = DefaultScreen(xfi->display); + xfi->screen = ScreenOfDisplay(xfi->display, xfi->screen_number); + xfi->depth = DefaultDepthOfScreen(xfi->screen); + xfi->big_endian = (ImageByteOrder(xfi->display) == MSBFirst); + + xfi->mouse_motion = settings->mouse_motion; + xfi->complex_regions = true; + xfi->decorations = settings->decorations; + xfi->fullscreen = settings->fullscreen; + xfi->grab_keyboard = settings->grab_keyboard; + xfi->fullscreen_toggle = true; + xfi->sw_gdi = settings->sw_gdi; + xfi->parent_window = (Window) settings->parent_window_xid; + + xf_detect_monitors(xfi, settings); + + return true; +} + +void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) +{ +#ifdef __GNUC__ +#if defined(__i386__) || defined(__x86_64__) + *eax = info; + __asm volatile + ("mov %%ebx, %%edi;" /* 32bit PIC: don't clobber ebx */ + "cpuid;" + "mov %%ebx, %%esi;" + "mov %%edi, %%ebx;" + :"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : :"edi"); +#endif +#endif +} + +uint32 xf_detect_cpu() +{ + unsigned int eax, ebx, ecx, edx = 0; + uint32 cpu_opt = 0; + + cpuid(1, &eax, &ebx, &ecx, &edx); + + if (edx & (1<<26)) + { + DEBUG("SSE2 detected"); + cpu_opt |= CPU_SSE2; + } + + return cpu_opt; +} + +boolean xf_post_connect(freerdp* instance) +{ + xfInfo* xfi; + XGCValues gcv; + rdpCache* cache; + rdpChannels* channels; + RFX_CONTEXT* rfx_context = NULL; + + xfi = ((xfContext*) instance->context)->xfi; + cache = instance->context->cache; + channels = xfi->_context->channels; + + if (xf_get_pixmap_info(xfi) != true) + return false; + + xf_register_graphics(instance->context->graphics); + + if (xfi->sw_gdi) + { + rdpGdi* gdi; + uint32 flags; + + flags = CLRCONV_ALPHA; + + if (xfi->bpp > 16) + flags |= CLRBUF_32BPP; + else + flags |= CLRBUF_16BPP; + + gdi_init(instance, flags, NULL); + gdi = instance->context->gdi; + xfi->primary_buffer = gdi->primary_buffer; + + rfx_context = gdi->rfx_context; + } + else + { + xfi->srcBpp = instance->settings->color_depth; + xf_gdi_register_update_callbacks(instance->update); + + xfi->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp); + + if (instance->settings->rfx_codec) + { + rfx_context = (void*) rfx_context_new(); + xfi->rfx_context = rfx_context; + } + + if (instance->settings->ns_codec) + xfi->nsc_context = (void*) nsc_context_new(); + } + + if (rfx_context) + { +#ifdef WITH_SSE2 + /* detect only if needed */ + rfx_context_set_cpu_opt(rfx_context, xf_detect_cpu()); +#endif + } + + xfi->width = instance->settings->width; + xfi->height = instance->settings->height; + + xf_create_window(xfi); + + memset(&gcv, 0, sizeof(gcv)); + xfi->modifier_map = XGetModifierMapping(xfi->display); + + xfi->gc = XCreateGC(xfi->display, xfi->drawable, GCGraphicsExposures, &gcv); + xfi->primary = XCreatePixmap(xfi->display, xfi->drawable, xfi->width, xfi->height, xfi->depth); + xfi->drawing = xfi->primary; + + xfi->bitmap_mono = XCreatePixmap(xfi->display, xfi->drawable, 8, 8, 1); + xfi->gc_mono = XCreateGC(xfi->display, xfi->bitmap_mono, GCGraphicsExposures, &gcv); + + XSetForeground(xfi->display, xfi->gc, BlackPixelOfScreen(xfi->screen)); + XFillRectangle(xfi->display, xfi->primary, xfi->gc, 0, 0, xfi->width, xfi->height); + + xfi->image = XCreateImage(xfi->display, xfi->visual, xfi->depth, ZPixmap, 0, + (char*) xfi->primary_buffer, xfi->width, xfi->height, xfi->scanline_pad, 0); + + xfi->bmp_codec_none = (uint8*) xmalloc(64 * 64 * 4); + + if (xfi->sw_gdi) + { + instance->update->BeginPaint = xf_sw_begin_paint; + instance->update->EndPaint = xf_sw_end_paint; + instance->update->DesktopResize = xf_sw_desktop_resize; + } + else + { + instance->update->BeginPaint = xf_hw_begin_paint; + instance->update->EndPaint = xf_hw_end_paint; + instance->update->DesktopResize = xf_hw_desktop_resize; + } + + pointer_cache_register_callbacks(instance->update); + + if (xfi->sw_gdi != true) + { + glyph_cache_register_callbacks(instance->update); + brush_cache_register_callbacks(instance->update); + bitmap_cache_register_callbacks(instance->update); + offscreen_cache_register_callbacks(instance->update); + palette_cache_register_callbacks(instance->update); + } + + instance->context->rail = rail_new(instance->settings); + rail_register_update_callbacks(instance->context->rail, instance->update); + xf_rail_register_callbacks(xfi, instance->context->rail); + + freerdp_channels_post_connect(channels, instance); + + xf_tsmf_init(xfi, xv_port); + + xf_cliprdr_init(xfi, channels); + + return true; +} + +boolean xf_authenticate(freerdp* instance, char** username, char** password, char** domain) +{ + *password = xmalloc(password_size * sizeof(char)); + + if (freerdp_passphrase_read("Password: ", *password, password_size) == NULL) + return false; + + return true; +} + +boolean xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) +{ + char answer; + + printf("Certificate details:\n"); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fingerprint); + printf("The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA.\n"); + + while (1) + { + printf("Do you trust the above certificate? (Y/N) "); + answer = fgetc(stdin); + + if (answer == 'y' || answer == 'Y') + { + return true; + } + else if (answer == 'n' || answer == 'N') + { + break; + } + printf("\n"); + } + + return false; +} + +int xf_process_client_args(rdpSettings* settings, const char* opt, const char* val, void* user_data) +{ + int argc = 0; + xfInfo* xfi = (xfInfo*) user_data; + + if (strcmp("--kbd-list", opt) == 0) + { + int i; + rdpKeyboardLayout* layouts; + + layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD); + printf("\nKeyboard Layouts\n"); + for (i = 0; layouts[i].code; i++) + printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); + free(layouts); + + layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); + printf("\nKeyboard Layout Variants\n"); + for (i = 0; layouts[i].code; i++) + printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); + free(layouts); + + layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME); + printf("\nKeyboard Input Method Editors (IMEs)\n"); + for (i = 0; layouts[i].code; i++) + printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); + free(layouts); + + exit(0); + } + else if (strcmp("--xv-port", opt) == 0) + { + xv_port = atoi(val); + argc = 2; + } + else if (strcmp("--dbg-x11", opt) == 0) + { + xfi->debug = true; + argc = 1; + } + + return argc; +} + +int xf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChannels* channels = (rdpChannels*) user_data; + + printf("loading plugin %s\n", name); + freerdp_channels_load_plugin(channels, settings, name, plugin_data); + + return 1; +} + +int xf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) +{ + return freerdp_channels_data(instance, channelId, data, size, flags, total_size); +} + +void xf_process_channel_event(rdpChannels* chanman, freerdp* instance) +{ + xfInfo* xfi; + RDP_EVENT* event; + + xfi = ((xfContext*) instance->context)->xfi; + + event = freerdp_channels_pop_event(chanman); + + if (event) + { + switch (event->event_class) + { + case RDP_EVENT_CLASS_RAIL: + xf_process_rail_event(xfi, chanman, event); + break; + + case RDP_EVENT_CLASS_TSMF: + xf_process_tsmf_event(xfi, event); + break; + + case RDP_EVENT_CLASS_CLIPRDR: + xf_process_cliprdr_event(xfi, event); + break; + + default: + break; + } + + freerdp_event_free(event); + } +} + +void xf_window_free(xfInfo* xfi) +{ + rdpContext* context = xfi->instance->context; + + XFreeModifiermap(xfi->modifier_map); + xfi->modifier_map = 0; + + XFreeGC(xfi->display, xfi->gc); + xfi->gc = 0; + + XFreeGC(xfi->display, xfi->gc_mono); + xfi->gc_mono = 0; + + if (xfi->window != NULL) + { + xf_DestroyWindow(xfi, xfi->window); + xfi->window = NULL; + } + + if (xfi->primary) + { + XFreePixmap(xfi->display, xfi->primary); + xfi->primary = 0; + } + + if (xfi->image) + { + xfi->image->data = NULL; + XDestroyImage(xfi->image); + xfi->image = NULL; + } + + if (context != NULL) + { + cache_free(context->cache); + context->cache = NULL; + + rail_free(context->rail); + context->rail = NULL; + } + + if (xfi->rfx_context) + { + rfx_context_free(xfi->rfx_context); + xfi->rfx_context = NULL; + } + + freerdp_clrconv_free(xfi->clrconv); + + if (xfi->hdc) + gdi_DeleteDC(xfi->hdc); + + xf_tsmf_uninit(xfi); + xf_cliprdr_uninit(xfi); +} + +void xf_free(xfInfo* xfi) +{ + xf_window_free(xfi); + + xfree(xfi->bmp_codec_none); + + XCloseDisplay(xfi->display); + + xfree(xfi); +} + +int xfreerdp_run(freerdp* instance) +{ + int i; + int fds; + xfInfo* xfi; + int max_fds; + int rcount; + int wcount; + int ret = 0; + void* rfds[32]; + void* wfds[32]; + fd_set rfds_set; + fd_set wfds_set; + int select_status; + rdpChannels* channels; + struct timeval timeout; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); + memset(&timeout, 0, sizeof(struct timeval)); + + if (!freerdp_connect(instance)) + return XF_EXIT_CONN_FAILED; + + xfi = ((xfContext*) instance->context)->xfi; + channels = instance->context->channels; + + while (!xfi->disconnect && !freerdp_shall_disconnect(instance)) + { + rcount = 0; + wcount = 0; + + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + ret = XF_EXIT_CONN_FAILED; + break; + } + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get channel manager file descriptor\n"); + ret = XF_EXIT_CONN_FAILED; + break; + } + if (xf_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get xfreerdp file descriptor\n"); + ret = XF_EXIT_CONN_FAILED; + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + FD_ZERO(&wfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + timeout.tv_sec = 5; + select_status = select(max_fds + 1, &rfds_set, &wfds_set, NULL, &timeout); + + if (select_status == 0) + { + //freerdp_send_keep_alive(instance); + continue; + } + else if (select_status == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("xfreerdp_run: select failed\n"); + break; + } + } + + if (freerdp_check_fds(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + if (xf_check_fds(instance, &rfds_set) != true) + { + printf("Failed to check xfreerdp file descriptor\n"); + break; + } + if (freerdp_channels_check_fds(channels, instance) != true) + { + printf("Failed to check channel manager file descriptor\n"); + break; + } + xf_process_channel_event(channels, instance); + } + + if (!ret) + ret = freerdp_error_info(instance); + + freerdp_channels_close(channels, instance); + freerdp_channels_free(channels); + freerdp_disconnect(instance); + gdi_free(instance); + xf_free(xfi); + + freerdp_free(instance); + + return ret; +} + +void* thread_func(void* param) +{ + struct thread_data* data; + data = (struct thread_data*) param; + + g_disconnect_reason = xfreerdp_run(data->instance); + + xfree(data); + + pthread_detach(pthread_self()); + + g_thread_count--; + + if (g_thread_count < 1) + freerdp_sem_signal(g_sem); + + pthread_exit(NULL); +} + +static uint8 exit_code_from_disconnect_reason(uint32 reason) +{ + if (reason == 0 || + (reason >= XF_EXIT_PARSE_ARGUMENTS && reason <= XF_EXIT_CONN_FAILED)) + return reason; + + /* Licence error set */ + else if (reason >= 0x100 && reason <= 0x10A) + reason -= 0x100 + XF_EXIT_LICENSE_INTERNAL; + + /* RDP protocol error set */ + else if (reason >= 0x10c9 && reason <= 0x1193) + reason = XF_EXIT_RDP; + + /* There's no need to test protocol-independent codes: they match */ + else if (!(reason <= 0xB)) + reason = XF_EXIT_UNKNOWN; + + return reason; +} + +int main(int argc, char* argv[]) +{ + pthread_t thread; + freerdp* instance; + struct thread_data* data; + + freerdp_handle_signals(); + + setlocale(LC_ALL, ""); + + freerdp_channels_global_init(); + + g_sem = freerdp_sem_new(1); + + instance = freerdp_new(); + instance->PreConnect = xf_pre_connect; + instance->PostConnect = xf_post_connect; + instance->Authenticate = xf_authenticate; + instance->VerifyCertificate = xf_verify_certificate; + instance->ReceiveChannelData = xf_receive_channel_data; + + instance->context_size = sizeof(xfContext); + instance->ContextNew = (pContextNew) xf_context_new; + instance->ContextFree = (pContextFree) xf_context_free; + freerdp_context_new(instance); + + instance->context->argc = argc; + instance->context->argv = argv; + instance->settings->sw_gdi = false; + + data = (struct thread_data*) xzalloc(sizeof(struct thread_data)); + data->instance = instance; + + g_thread_count++; + pthread_create(&thread, 0, thread_func, data); + + while (g_thread_count > 0) + { + freerdp_sem_wait(g_sem); + } + + freerdp_channels_global_uninit(); + + return exit_code_from_disconnect_reason(g_disconnect_reason); +} diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h new file mode 100644 index 0000000..88850ca --- /dev/null +++ b/client/X11/xfreerdp.h @@ -0,0 +1,215 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Client + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XFREERDP_H +#define __XFREERDP_H + +#include +#include +#include +#include +#include +#include +#include + +typedef struct xf_info xfInfo; + +#include "xf_window.h" +#include "xf_monitor.h" + +struct xf_WorkArea +{ + uint32 x; + uint32 y; + uint32 width; + uint32 height; +}; +typedef struct xf_WorkArea xfWorkArea; + +struct xf_pointer +{ + rdpPointer pointer; + Cursor cursor; +}; +typedef struct xf_pointer xfPointer; + +struct xf_bitmap +{ + rdpBitmap bitmap; + Pixmap pixmap; +}; +typedef struct xf_bitmap xfBitmap; + +struct xf_glyph +{ + rdpGlyph glyph; + Pixmap pixmap; +}; +typedef struct xf_glyph xfGlyph; + +struct xf_context +{ + rdpContext _p; + + xfInfo* xfi; + rdpSettings* settings; +}; +typedef struct xf_context xfContext; + +struct xf_info +{ + freerdp* instance; + xfContext* context; + rdpContext* _context; + + GC gc; + int bpp; + int xfds; + int depth; + int width; + int height; + int srcBpp; + GC gc_mono; + Screen* screen; + XImage* image; + Pixmap primary; + Pixmap drawing; + Visual* visual; + Display* display; + Drawable drawable; + Pixmap bitmap_mono; + Colormap colormap; + int screen_number; + int scanline_pad; + boolean big_endian; + boolean fullscreen; + boolean grab_keyboard; + boolean unobscured; + boolean decorations; + boolean debug; + xfWindow* window; + xfWorkArea workArea; + int current_desktop; + boolean remote_app; + boolean disconnect; + HCLRCONV clrconv; + Window parent_window; + + HGDI_DC hdc; + boolean sw_gdi; + uint8* primary_buffer; + + boolean focused; + boolean mouse_active; + boolean mouse_motion; + boolean fullscreen_toggle; + uint32 keyboard_layout_id; + boolean pressed_keys[256]; + XModifierKeymap* modifier_map; + XSetWindowAttributes attribs; + boolean complex_regions; + VIRTUAL_SCREEN vscreen; + uint8* bmp_codec_none; + uint8* bmp_codec_nsc; + void* rfx_context; + void* nsc_context; + void* xv_context; + void* clipboard_context; + + Atom _NET_WM_ICON; + Atom _MOTIF_WM_HINTS; + Atom _NET_CURRENT_DESKTOP; + Atom _NET_WORKAREA; + + Atom _NET_WM_STATE; + Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER; + + Atom _NET_WM_WINDOW_TYPE; + Atom _NET_WM_WINDOW_TYPE_NORMAL; + Atom _NET_WM_WINDOW_TYPE_DIALOG; + Atom _NET_WM_WINDOW_TYPE_UTILITY; + Atom _NET_WM_WINDOW_TYPE_POPUP; + Atom _NET_WM_WINDOW_TYPE_DROPDOWN_MENU; + + Atom _NET_WM_MOVERESIZE; + Atom _NET_MOVERESIZE_WINDOW; + + Atom WM_PROTOCOLS; + Atom WM_DELETE_WINDOW; +}; + +void xf_toggle_fullscreen(xfInfo* xfi); +boolean xf_post_connect(freerdp* instance); + +enum XF_EXIT_CODE +{ + /* section 0-15: protocol-independent codes */ + XF_EXIT_SUCCESS = 0, + XF_EXIT_DISCONNECT = 1, + XF_EXIT_LOGOFF = 2, + XF_EXIT_IDLE_TIMEOUT = 3, + XF_EXIT_LOGON_TIMEOUT = 4, + XF_EXIT_CONN_REPLACED = 5, + XF_EXIT_OUT_OF_MEMORY = 6, + XF_EXIT_CONN_DENIED = 7, + XF_EXIT_CONN_DENIED_FIPS = 8, + XF_EXIT_USER_PRIVILEGES = 9, + XF_EXIT_FRESH_CREDENTIALS_REQUIRED = 10, + XF_EXIT_DISCONNECT_BY_USER = 11, + + /* section 16-31: license error set */ + XF_EXIT_LICENSE_INTERNAL = 16, + XF_EXIT_LICENSE_NO_LICENSE_SERVER = 17, + XF_EXIT_LICENSE_NO_LICENSE = 18, + XF_EXIT_LICENSE_BAD_CLIENT_MSG = 19, + XF_EXIT_LICENSE_HWID_DOESNT_MATCH = 20, + XF_EXIT_LICENSE_BAD_CLIENT = 21, + XF_EXIT_LICENSE_CANT_FINISH_PROTOCOL = 22, + XF_EXIT_LICENSE_CLIENT_ENDED_PROTOCOL = 23, + XF_EXIT_LICENSE_BAD_CLIENT_ENCRYPTION = 24, + XF_EXIT_LICENSE_CANT_UPGRADE = 25, + XF_EXIT_LICENSE_NO_REMOTE_CONNECTIONS = 26, + + /* section 32-127: RDP protocol error set */ + XF_EXIT_RDP = 32, + + /* section 128-254: xfreerdp specific exit codes */ + XF_EXIT_PARSE_ARGUMENTS = 128, + XF_EXIT_MEMORY = 129, + XF_EXIT_PROTOCOL = 130, + XF_EXIT_CONN_FAILED = 131, + + XF_EXIT_UNKNOWN = 255, +}; + +#ifdef WITH_DEBUG_X11 +#define DEBUG_X11(fmt, ...) DEBUG_CLASS(X11, fmt, ## __VA_ARGS__) +#else +#define DEBUG_X11(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#ifdef WITH_DEBUG_X11_LOCAL_MOVESIZE +#define DEBUG_X11_LMS(fmt, ...) DEBUG_CLASS(X11_LMS, fmt, ## __VA_ARGS__) +#else +#define DEBUG_X11_LMS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __XFREERDP_H */ diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt new file mode 100644 index 0000000..4a4f6fc --- /dev/null +++ b/client/test/CMakeLists.txt @@ -0,0 +1,26 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Test UI cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_executable(freerdp-test + freerdp.c) + +target_link_libraries(freerdp-test freerdp-core) +target_link_libraries(freerdp-test freerdp-gdi) +target_link_libraries(freerdp-test freerdp-utils) +target_link_libraries(freerdp-test freerdp-channels ${CMAKE_DL_LIBS}) diff --git a/client/test/freerdp.c b/client/test/freerdp.c new file mode 100644 index 0000000..6c0a197 --- /dev/null +++ b/client/test/freerdp.c @@ -0,0 +1,338 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Test UI + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct tf_info +{ + void* data; +}; +typedef struct tf_info tfInfo; + +struct tf_context +{ + rdpContext _p; + + tfInfo* tfi; +}; +typedef struct tf_context tfContext; + +freerdp_sem g_sem; +static int g_thread_count = 0; + +struct thread_data +{ + freerdp* instance; +}; + +#include +#include + +void tf_context_new(freerdp* instance, rdpContext* context) +{ + context->channels = freerdp_channels_new(); +} + +void tf_context_free(freerdp* instance, rdpContext* context) +{ + +} + +void tf_begin_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + gdi->primary->hdc->hwnd->invalid->null = 1; +} + +void tf_end_paint(rdpContext* context) +{ + rdpGdi* gdi = context->gdi; + + if (gdi->primary->hdc->hwnd->invalid->null) + return; +} + +int tf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) +{ + return freerdp_channels_data(instance, channelId, data, size, flags, total_size); +} + +int tf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + rdpChannels* channels = (rdpChannels*) user_data; + + printf("Load plugin %s\n", name); + freerdp_channels_load_plugin(channels, settings, name, plugin_data); + + return 1; +} + +void tf_process_cb_monitor_ready_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + RDP_CB_FORMAT_LIST_EVENT* format_list_event; + + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL); + + format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; + format_list_event->num_formats = 0; + + freerdp_channels_send_event(channels, event); +} + +void tf_process_channel_event(rdpChannels* channels, freerdp* instance) +{ + RDP_EVENT* event; + + event = freerdp_channels_pop_event(channels); + + if (event) + { + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_MONITOR_READY: + tf_process_cb_monitor_ready_event(channels, instance); + break; + default: + printf("tf_process_channel_event: unknown event type %d\n", event->event_type); + break; + } + + freerdp_event_free(event); + } +} + +boolean tf_pre_connect(freerdp* instance) +{ + tfInfo* tfi; + tfContext* context; + rdpSettings* settings; + + context = (tfContext*) instance->context; + tfi = (tfInfo*) xzalloc(sizeof(tfInfo)); + context->tfi = tfi; + + settings = instance->settings; + + settings->order_support[NEG_DSTBLT_INDEX] = true; + settings->order_support[NEG_PATBLT_INDEX] = true; + settings->order_support[NEG_SCRBLT_INDEX] = true; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = true; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = true; + settings->order_support[NEG_MULTIPATBLT_INDEX] = true; + settings->order_support[NEG_MULTISCRBLT_INDEX] = true; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = true; + settings->order_support[NEG_LINETO_INDEX] = true; + settings->order_support[NEG_POLYLINE_INDEX] = true; + settings->order_support[NEG_MEMBLT_INDEX] = true; + settings->order_support[NEG_MEM3BLT_INDEX] = true; + settings->order_support[NEG_SAVEBITMAP_INDEX] = true; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_GLYPH_INDEX] = true; + settings->order_support[NEG_POLYGON_SC_INDEX] = true; + settings->order_support[NEG_POLYGON_CB_INDEX] = true; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = true; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = true; + + freerdp_channels_pre_connect(instance->context->channels, instance); + + return true; +} + +boolean tf_post_connect(freerdp* instance) +{ + rdpGdi* gdi; + + gdi_init(instance, CLRCONV_ALPHA | CLRCONV_INVERT | CLRBUF_16BPP | CLRBUF_32BPP, NULL); + gdi = instance->context->gdi; + + instance->update->BeginPaint = tf_begin_paint; + instance->update->EndPaint = tf_end_paint; + + freerdp_channels_post_connect(instance->context->channels, instance); + + return true; +} + +int tfreerdp_run(freerdp* instance) +{ + int i; + int fds; + int max_fds; + int rcount; + int wcount; + void* rfds[32]; + void* wfds[32]; + fd_set rfds_set; + fd_set wfds_set; + rdpChannels* channels; + + memset(rfds, 0, sizeof(rfds)); + memset(wfds, 0, sizeof(wfds)); + + channels = instance->context->channels; + + freerdp_connect(instance); + + while (1) + { + rcount = 0; + wcount = 0; + + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != true) + { + printf("Failed to get channel manager file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, &wfds_set, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("tfreerdp_run: select failed\n"); + break; + } + } + + if (freerdp_check_fds(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + if (freerdp_channels_check_fds(channels, instance) != true) + { + printf("Failed to check channel manager file descriptor\n"); + break; + } + tf_process_channel_event(channels, instance); + } + + freerdp_channels_close(channels, instance); + freerdp_channels_free(channels); + freerdp_free(instance); + + return 0; +} + +void* thread_func(void* param) +{ + struct thread_data* data; + data = (struct thread_data*) param; + + tfreerdp_run(data->instance); + + xfree(data); + + pthread_detach(pthread_self()); + + g_thread_count--; + + if (g_thread_count < 1) + freerdp_sem_signal(&g_sem); + + return NULL; +} + +int main(int argc, char* argv[]) +{ + pthread_t thread; + freerdp* instance; + struct thread_data* data; + rdpChannels* channels; + + freerdp_channels_global_init(); + + g_sem = freerdp_sem_new(1); + + instance = freerdp_new(); + instance->PreConnect = tf_pre_connect; + instance->PostConnect = tf_post_connect; + instance->ReceiveChannelData = tf_receive_channel_data; + + instance->context_size = sizeof(tfContext); + instance->ContextNew = tf_context_new; + instance->ContextFree = tf_context_free; + freerdp_context_new(instance); + + channels = instance->context->channels; + freerdp_parse_args(instance->settings, argc, argv, tf_process_plugin_args, channels, NULL, NULL); + + data = (struct thread_data*) xzalloc(sizeof(struct thread_data)); + data->instance = instance; + + g_thread_count++; + pthread_create(&thread, 0, thread_func, data); + + while (g_thread_count > 0) + { + freerdp_sem_wait(g_sem); + } + + freerdp_channels_global_uninit(); + + return 0; +} diff --git a/cmake/AutoVersioning.cmake b/cmake/AutoVersioning.cmake new file mode 100644 index 0000000..04e6479 --- /dev/null +++ b/cmake/AutoVersioning.cmake @@ -0,0 +1,54 @@ +# - AutoVersioning +# Gather version from tarball or SCM +# +# This module defines the following variables: +# PRODUCT_VERSION - Version of product +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +if(EXISTS "${CMAKE_SOURCE_DIR}/.version" ) + file(READ ${CMAKE_SOURCE_DIR}/.version PRODUCT_VERSION) + + string(STRIP ${PRODUCT_VERSION} PRODUCT_VERSION) +else() + execute_process(COMMAND git describe --match "v[0-9]*" --abbrev=4 + OUTPUT_VARIABLE PRODUCT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + + if(PRODUCT_VERSION) + string(REGEX REPLACE "^v(.*)" "\\1" PRODUCT_VERSION ${PRODUCT_VERSION}) + else() + # GIT is the default version + set(PRODUCT_VERSION GIT) + endif() + + # Check if has not commited changes + execute_process(COMMAND git update-index -q --refresh) + execute_process(COMMAND git diff-index --name-only HEAD -- + OUTPUT_VARIABLE CHANGED_SOURCE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + + if(CHANGED_SOURCE) + set(PRODUCT_VERSION ${PRODUCT_VERSION}-dirty) + endif() +endif() + +message(STATUS "${CMAKE_PROJECT_NAME} ${PRODUCT_VERSION}") diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake new file mode 100644 index 0000000..995d7a8 --- /dev/null +++ b/cmake/ConfigOptions.cmake @@ -0,0 +1,26 @@ +option(WITH_DEBUG_TRANSPORT "Print transport debug messages." OFF) +option(WITH_DEBUG_CHANNELS "Print channel manager debug messages." OFF) +option(WITH_DEBUG_SVC "Print static virtual channel debug messages." OFF) +option(WITH_DEBUG_DVC "Print dynamic virtual channel debug messages." OFF) +option(WITH_DEBUG_KBD "Print keyboard related debug messages." OFF) +option(WITH_DEBUG_NLA "Print authentication related debug messages." OFF) +option(WITH_DEBUG_NEGO "Print negotiation related debug messages." OFF) +option(WITH_DEBUG_CERTIFICATE "Print certificate related debug messages." OFF) +option(WITH_DEBUG_LICENSE "Print license debug messages." OFF) +option(WITH_DEBUG_GDI "Print graphics debug messages." OFF) +option(WITH_DEBUG_RFX "Print RemoteFX debug messages." OFF) +option(WITH_DEBUG_X11 "Print X11 Client debug messages" OFF) +option(WITH_DEBUG_X11_CLIPRDR "Print X11 clipboard redirection debug messages" OFF) +option(WITH_DEBUG_X11_LOCAL_MOVESIZE "Print X11 Client local movesize debug messages" OFF) +option(WITH_DEBUG_RAIL "Print RemoteApp debug messages" OFF) +option(WITH_DEBUG_XV "Print XVideo debug messages" OFF) +option(WITH_DEBUG_SCARD "Print smartcard debug messages" OFF) +option(WITH_DEBUG_ORDERS "Print drawing orders debug messages" OFF) +option(WITH_MANPAGES "Generate manpages." ON) +option(WITH_PROFILER "Compile profiler." OFF) +option(WITH_SSE2 "Use SSE2 optimization." OFF) +option(WITH_SSE2_TARGET "Allow compiler to generate SSE2 instructions." OFF) +option(WITH_DEBUG_REDIR "Redirection debug messages" OFF) +option(WITH_DEBUG_CLIPRDR "Print clipboard redirection debug messages" OFF) +option(WITH_DEBUG_WND "Print window order debug messages" OFF) +option(WITH_NEON "Enable NEON optimization for rfx decoder" OFF) diff --git a/cmake/FindCUnit.cmake b/cmake/FindCUnit.cmake new file mode 100644 index 0000000..3e6b175 --- /dev/null +++ b/cmake/FindCUnit.cmake @@ -0,0 +1,47 @@ +# - Find CUnit +# Find the CUnit libraries +# +# This module defines the following variables: +# CUNIT_FOUND - true if CUNIT_INCLUDE_DIR & CUNIT_LIBRARY are found +# CUNIT_LIBRARIES - Set when CUNIT_LIBRARY is found +# CUNIT_INCLUDE_DIRS - Set when CUNIT_INCLUDE_DIR is found +# +# CUNIT_INCLUDE_DIR - where to find CUnit.h, etc. +# CUNIT_LIBRARY - the cunit library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(CUNIT_INCLUDE_DIR NAMES CUnit.h + PATH_SUFFIXES CUnit + DOC "The CUnit include directory" +) + +find_library(CUNIT_LIBRARY NAMES cunit + DOC "The CUnit library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(CUnit DEFAULT_MSG CUNIT_LIBRARY CUNIT_INCLUDE_DIR) + +if(CUNIT_FOUND) + set( CUNIT_LIBRARIES ${CUNIT_LIBRARY} ) + set( CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR} ) +endif() + +mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY) diff --git a/cmake/FindDirectFB.cmake b/cmake/FindDirectFB.cmake new file mode 100644 index 0000000..6fe24ca --- /dev/null +++ b/cmake/FindDirectFB.cmake @@ -0,0 +1,49 @@ +# - Find DirectFB +# Find the DirectFB libraries +# +# This module defines the following variables: +# DIRECTFB_FOUND - true if DIRECTFB_INCLUDE_DIR & DIRECTFB_LIBRARY are found +# DIRECTFB_LIBRARIES - Set when DIRECTFB_LIBRARY is found +# DIRECTFB_INCLUDE_DIRS - Set when DIRECTFB_INCLUDE_DIR is found +# +# DIRECTFB_INCLUDE_DIR - where to find CUnit.h, etc. +# DIRECTFB_LIBRARY - the cunit library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(DIRECTFB_INCLUDE_DIR NAMES directfb.h + PATH_SUFFIXES directfb + DOC "The directfb include directory" +) + +find_library(DIRECTFB_LIBRARY NAMES directfb + DOC "The DirectFB library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectFB DEFAULT_MSG DIRECTFB_LIBRARY DIRECTFB_INCLUDE_DIR) + +if(DIRECTFB_FOUND) + set( DIRECTFB_LIBRARIES ${DIRECTFB_LIBRARY} ) + set( DIRECTFB_INCLUDE_DIRS ${DIRECTFB_INCLUDE_DIR} ) +endif() + +mark_as_advanced(DIRECTFB_INCLUDE_DIR DIRECTFB_LIBRARY) + diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake new file mode 100644 index 0000000..9b2464e --- /dev/null +++ b/cmake/FindFFmpeg.cmake @@ -0,0 +1,41 @@ +# - Try to find FFmpeg +# Using Pkg-config if available for path +# +# FFMPEG_FOUND - all required ffmpeg components found on system +# FFMPEG_INCLUDE_DIRS - combined include directories +# FFMPEG_LIBRARIES - combined libraries to link + +include(FindPkgConfig) + +if (PKG_CONFIG_FOUND) + pkg_check_modules(AVCODEC libavcodec) + pkg_check_modules(AVUTIL libavutil) +endif ( PKG_CONFIG_FOUND ) + +# avcodec +find_path(AVCODEC_INCLUDE_DIR avcodec.h PATHS ${AVCODEC_INCLUDE_DIRS} + PATH_SUFFIXES libavcodec ) +find_library(AVCODEC_LIBRARY avcodec PATHS ${AVCODEC_LIBRARY_DIRS}) + +# avutil +find_path(AVUTIL_INCLUDE_DIR avutil.h PATHS ${AVUTIL_INCLUDE_DIRS} + PATH_SUFFIXES libavutil ) +find_library(AVUTIL_LIBRARY avutil PATHS ${AVUTIL_LIBRARY_DIRS}) + +if(AVCODEC_INCLUDE_DIR AND AVCODEC_LIBRARY) + set(AVCODEC_FOUND TRUE) +endif() + +if(AVUTIL_INCLUDE_DIR AND AVUTIL_LIBRARY) + set(AVUTIL_FOUND TRUE) +endif() + + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(FFmpeg DEFAULT_MSG AVUTIL_FOUND AVCODEC_FOUND) + +if(FFMPEG_FOUND) + set(FFMPEG_INCLUDE_DIRS ${AVCODEC_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR}) + set(FFMPEG_LIBRARIES ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY}) +endif() + +mark_as_advanced(FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARYS) diff --git a/cmake/FindOptionalPackage.cmake b/cmake/FindOptionalPackage.cmake new file mode 100644 index 0000000..3e543bd --- /dev/null +++ b/cmake/FindOptionalPackage.cmake @@ -0,0 +1,51 @@ +# - FindOptionalPackage +# Enable or disable optional packages. Also force optional packages. +# +# This module defines the following macros: +# find_required_package : find a required package, can not be disabled +# find_suggested_package : find a suggested package - required but can be disabled +# find_optional_package : find an optional package - required only if enabled +# + +#============================================================================= +# Copyright 2011 Nils Andresen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +macro(find_required_package _normal_package) + find_package(${_normal_package} REQUIRED) +endmacro(find_required_package) + +macro(find_suggested_package _normal_package) + string(TOUPPER ${_normal_package} _upper_package) + option(WITH_${_upper_package} "Add dependency to ${_normal_package} - recommended" ON) + + if(WITH_${_upper_package}) + message(STATUS "Finding suggested package ${_normal_package}.") + message(STATUS " Disable this using \"-DWITH_${_upper_package}=OFF\".") + find_package(${_normal_package} REQUIRED) + endif(WITH_${_upper_package}) +endmacro(find_suggested_package) + +macro(find_optional_package _normal_package) + string(TOUPPER ${_normal_package} _upper_package) + option(WITH_${_upper_package} "Add dependency to ${_normal_package}" OFF) + + if(WITH_${_upper_package}) + find_package(${_normal_package} REQUIRED) + else(WITH_${_upper_package}) + message(STATUS "Skipping optional package ${_normal_package}.") + message(STATUS " Enable this using \"-DWITH_${_upper_package}=ON\".") + endif(WITH_${_upper_package}) +endmacro(find_optional_package) diff --git a/cmake/FindPCSC.cmake b/cmake/FindPCSC.cmake new file mode 100644 index 0000000..a94709c --- /dev/null +++ b/cmake/FindPCSC.cmake @@ -0,0 +1,13 @@ +include(FindPkgConfig) + +if (PKG_CONFIG_FOUND) + pkg_check_modules(PCSC libpcsclite) +endif() + +find_path(PCSC_INCLUDE_DIR pcsclite.h PATHS ${PCSC_INCLUDE_DIRS} + PATH_SUFFIXES PCSC ) +find_library(PCSC_LIBRARY pcsclite PATHS ${PCSC_LIBRARY_DIRS}) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCSC DEFAULT_MSG PCSC_INCLUDE_DIR PCSC_LIBRARY) + +mark_as_advanced(PCSC_INCLUDE_DIR PCSC_LIBRARY) diff --git a/cmake/FindPulseAudio.cmake b/cmake/FindPulseAudio.cmake new file mode 100644 index 0000000..03d1c61 --- /dev/null +++ b/cmake/FindPulseAudio.cmake @@ -0,0 +1,12 @@ +include(FindPkgConfig) + +if (PKG_CONFIG_FOUND) + pkg_check_modules(PULSEAUDIO libpulse) +endif() + +find_path(PULSEAUDIO_INCLUDE_DIR pulseaudio.h PATHS ${PULSEAUDIO_INCLUDE_DIRS} PATH_SUFFIXES pulse ) +find_library(PULSEAUDIO_LIBRARY pulse PATHS ${PULSEAUDIO_LIBRARY_DIRS}) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PulseAudio DEFAULT_MSG PULSEAUDIO_INCLUDE_DIR PULSEAUDIO_LIBRARY) + +mark_as_advanced(PULSEAUDIO_INCLUDE_DIR PULSEAUDIO_LIBRARY) diff --git a/cmake/FindX11.cmake b/cmake/FindX11.cmake new file mode 100644 index 0000000..594b2c0 --- /dev/null +++ b/cmake/FindX11.cmake @@ -0,0 +1,49 @@ +# - Find X11 +# Find the X11 libraries +# +# This module defines the following variables: +# X11_FOUND - true if X11_INCLUDE_DIR & X11_LIBRARY are found +# X11_LIBRARIES - Set when X11_LIBRARY is found +# X11_INCLUDE_DIRS - Set when X11_INCLUDE_DIR is found +# +# X11_INCLUDE_DIR - where to find Xlib.h, etc. +# X11_LIBRARY - the X11 library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(X11_INCLUDE_DIR NAMES X11/Xlib.h + PATH_SUFFIXES X11 + DOC "The X11 include directory" +) + +find_library(X11_LIBRARY NAMES X11 + DOC "The X11 library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(X11 DEFAULT_MSG X11_LIBRARY X11_INCLUDE_DIR) + +if(X11_FOUND) + set( X11_LIBRARIES ${X11_LIBRARY} ) + set( X11_INCLUDE_DIRS ${X11_INCLUDE_DIR} ) +endif() + +mark_as_advanced(X11_INCLUDE_DIR X11_LIBRARY) + diff --git a/cmake/FindXKBFile.cmake b/cmake/FindXKBFile.cmake new file mode 100644 index 0000000..e47ff99 --- /dev/null +++ b/cmake/FindXKBFile.cmake @@ -0,0 +1,49 @@ +# - Find XKBFILE +# Find the XKBFILE libraries +# +# This module defines the following variables: +# XKBFILE_FOUND - true if XKBFILE_INCLUDE_DIR & XKBFILE_LIBRARY are found +# XKBFILE_LIBRARIES - Set when XKBFILE_LIBRARY is found +# XKBFILE_INCLUDE_DIRS - Set when XKBFILE_INCLUDE_DIR is found +# +# XKBFILE_INCLUDE_DIR - where to find XKBfile.h, etc. +# XKBFILE_LIBRARY - the xkbfile library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XKBFILE_INCLUDE_DIR NAMES X11/extensions/XKBfile.h + PATH_SUFFIXES X11/extensions + DOC "The XKBFile include directory" +) + +find_library(XKBFILE_LIBRARY NAMES xkbfile + DOC "The XKBFile library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XKBFile DEFAULT_MSG XKBFILE_LIBRARY XKBFILE_INCLUDE_DIR) + +if(XKBFILE_FOUND) + set( XKBFILE_LIBRARIES ${XKBFILE_LIBRARY} ) + set( XKBFILE_INCLUDE_DIRS ${XKBFILE_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XKBFILE_INCLUDE_DIR XKBFILE_LIBRARY) + diff --git a/cmake/FindXShm.cmake b/cmake/FindXShm.cmake new file mode 100644 index 0000000..cc4b6d5 --- /dev/null +++ b/cmake/FindXShm.cmake @@ -0,0 +1,49 @@ +# - Find XSHM +# Find the XSHM libraries +# +# This module defines the following variables: +# XSHM_FOUND - true if XSHM_INCLUDE_DIR & XSHM_LIBRARY are found +# XSHM_LIBRARIES - Set when XSHM_LIBRARY is found +# XSHM_INCLUDE_DIRS - Set when XSHM_INCLUDE_DIR is found +# +# XSHM_INCLUDE_DIR - where to find XShm.h, etc. +# XSHM_LIBRARY - the XSHM library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XSHM_INCLUDE_DIR NAMES X11/extensions/XShm.h + PATH_SUFFIXES X11/extensions + DOC "The XShm include directory" +) + +find_library(XSHM_LIBRARY NAMES Xext + DOC "The XShm library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XShm DEFAULT_MSG XSHM_LIBRARY XSHM_INCLUDE_DIR) + +if(XSHM_FOUND) + set( XSHM_LIBRARIES ${XSHM_LIBRARY} ) + set( XSHM_INCLUDE_DIRS ${XSHM_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XSHM_INCLUDE_DIR XSHM_LIBRARY) + diff --git a/cmake/FindXTest.cmake b/cmake/FindXTest.cmake new file mode 100644 index 0000000..f4a8561 --- /dev/null +++ b/cmake/FindXTest.cmake @@ -0,0 +1,49 @@ +# - Find XTEST +# Find the XTEST libraries +# +# This module defines the following variables: +# XTEST_FOUND - true if XTEST_INCLUDE_DIR & XTEST_LIBRARY are found +# XTEST_LIBRARIES - Set when XTEST_LIBRARY is found +# XTEST_INCLUDE_DIRS - Set when XTEST_INCLUDE_DIR is found +# +# XTEST_INCLUDE_DIR - where to find XTest.h, etc. +# XTEST_LIBRARY - the XTEST library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XTEST_INCLUDE_DIR NAMES X11/extensions/XTest.h + PATH_SUFFIXES X11/extensions + DOC "The XTest include directory" +) + +find_library(XTEST_LIBRARY NAMES Xtst + DOC "The XTest library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XTest DEFAULT_MSG XTEST_LIBRARY XTEST_INCLUDE_DIR) + +if(XTEST_FOUND) + set( XTEST_LIBRARIES ${XTEST_LIBRARY} ) + set( XTEST_INCLUDE_DIRS ${XTEST_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XTEST_INCLUDE_DIR XTEST_LIBRARY) + diff --git a/cmake/FindXcursor.cmake b/cmake/FindXcursor.cmake new file mode 100644 index 0000000..cc22bbd --- /dev/null +++ b/cmake/FindXcursor.cmake @@ -0,0 +1,49 @@ +# - Find Xcursor +# Find the Xcursor libraries +# +# This module defines the following variables: +# XCURSOR_FOUND - true if XCURSOR_INCLUDE_DIR & XCURSOR_LIBRARY are found +# XCURSOR_LIBRARIES - Set when XCURSOR_LIBRARY is found +# XCURSOR_INCLUDE_DIRS - Set when XCURSOR_INCLUDE_DIR is found +# +# XCURSOR_INCLUDE_DIR - where to find Xcursor.h, etc. +# XCURSOR_LIBRARY - the Xcursor library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XCURSOR_INCLUDE_DIR NAMES X11/Xcursor/Xcursor.h + PATH_SUFFIXES X11/Xcursor + DOC "The Xcursor include directory" +) + +find_library(XCURSOR_LIBRARY NAMES Xcursor + DOC "The Xcursor library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xcursor DEFAULT_MSG XCURSOR_LIBRARY XCURSOR_INCLUDE_DIR) + +if(XCURSOR_FOUND) + set( XCURSOR_LIBRARIES ${XCURSOR_LIBRARY} ) + set( XCURSOR_INCLUDE_DIRS ${XCURSOR_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XCURSOR_INCLUDE_DIR XCURSOR_LIBRARY) + diff --git a/cmake/FindXdamage.cmake b/cmake/FindXdamage.cmake new file mode 100644 index 0000000..a3ddf28 --- /dev/null +++ b/cmake/FindXdamage.cmake @@ -0,0 +1,49 @@ +# - Find XDAMAGE +# Find the XDAMAGE libraries +# +# This module defines the following variables: +# XDAMAGE_FOUND - true if XDAMAGE_INCLUDE_DIR & XDAMAGE_LIBRARY are found +# XDAMAGE_LIBRARIES - Set when XDAMAGE_LIBRARY is found +# XDAMAGE_INCLUDE_DIRS - Set when XDAMAGE_INCLUDE_DIR is found +# +# XDAMAGE_INCLUDE_DIR - where to find Xdamage.h, etc. +# XDAMAGE_LIBRARY - the XDAMAGE library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XDAMAGE_INCLUDE_DIR NAMES X11/extensions/Xdamage.h + PATH_SUFFIXES X11/extensions + DOC "The Xdamage include directory" +) + +find_library(XDAMAGE_LIBRARY NAMES Xdamage + DOC "The Xdamage library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xdamage DEFAULT_MSG XDAMAGE_LIBRARY XDAMAGE_INCLUDE_DIR) + +if(XDAMAGE_FOUND) + set( XDAMAGE_LIBRARIES ${XDAMAGE_LIBRARY} ) + set( XDAMAGE_INCLUDE_DIRS ${XDAMAGE_INCLUDE_DIR} ) +endif() + + +mark_as_advanced(XDAMAGE_INCLUDE_DIR XDAMAGE_LIBRARY) diff --git a/cmake/FindXext.cmake b/cmake/FindXext.cmake new file mode 100644 index 0000000..8cfe552 --- /dev/null +++ b/cmake/FindXext.cmake @@ -0,0 +1,49 @@ +# - Find Xext +# Find the Xext libraries +# +# This module defines the following variables: +# Xext_FOUND - true if Xext_INCLUDE_DIR & Xext_LIBRARY are found +# Xext_LIBRARIES - Set when Xext_LIBRARY is found +# Xext_INCLUDE_DIRS - Set when Xext_INCLUDE_DIR is found +# +# Xext_INCLUDE_DIR - where to find Xext.h, etc. +# Xext_LIBRARY - the Xext library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XEXT_INCLUDE_DIR NAMES X11/extensions/Xext.h + PATH_SUFFIXES X11/extensions + DOC "The Xext include directory" +) + +find_library(XEXT_LIBRARY NAMES Xext + DOC "The Xext library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xext DEFAULT_MSG XEXT_LIBRARY XEXT_INCLUDE_DIR) + +if(XEXT_FOUND) + set( XEXT_LIBRARIES ${XEXT_LIBRARY} ) + set( XEXT_INCLUDE_DIRS ${XEXT_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XEXT_INCLUDE_DIR XEXT_LIBRARY) + diff --git a/cmake/FindXfixes.cmake b/cmake/FindXfixes.cmake new file mode 100644 index 0000000..a7e633e --- /dev/null +++ b/cmake/FindXfixes.cmake @@ -0,0 +1,49 @@ +# - Find XFIXES +# Find the XFIXES libraries +# +# This module defines the following variables: +# XFIXES_FOUND - true if XFIXES_INCLUDE_DIR & XFIXES_LIBRARY are found +# XFIXES_LIBRARIES - Set when XFIXES_LIBRARY is found +# XFIXES_INCLUDE_DIRS - Set when XFIXES_INCLUDE_DIR is found +# +# XFIXES_INCLUDE_DIR - where to find Xfixes.h, etc. +# XFIXES_LIBRARY - the XFIXES library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XFIXES_INCLUDE_DIR NAMES X11/extensions/Xfixes.h + PATH_SUFFIXES X11/extensions + DOC "The Xfixes include directory" +) + +find_library(XFIXES_LIBRARY NAMES Xfixes + DOC "The Xfixes library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xfixes DEFAULT_MSG XFIXES_LIBRARY XFIXES_INCLUDE_DIR) + +if(XFIXES_FOUND) + set( XFIXES_LIBRARIES ${XFIXES_LIBRARY} ) + set( XFIXES_INCLUDE_DIRS ${XFIXES_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XFIXES_INCLUDE_DIR XFIXES_LIBRARY) + diff --git a/cmake/FindXinerama.cmake b/cmake/FindXinerama.cmake new file mode 100644 index 0000000..ff9f4d1 --- /dev/null +++ b/cmake/FindXinerama.cmake @@ -0,0 +1,49 @@ +# - Find XINERAMA +# Find the XINERAMA libraries +# +# This module defines the following variables: +# XINERAMA_FOUND - true if XINERAMA_INCLUDE_DIR & XINERAMA_LIBRARY are found +# XINERAMA_LIBRARIES - Set when XINERAMA_LIBRARY is found +# XINERAMA_INCLUDE_DIRS - Set when XINERAMA_INCLUDE_DIR is found +# +# XINERAMA_INCLUDE_DIR - where to find Xinerama.h, etc. +# XINERAMA_LIBRARY - the XINERAMA library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XINERAMA_INCLUDE_DIR NAMES X11/extensions/Xinerama.h + PATH_SUFFIXES X11/extensions + DOC "The Xinerama include directory" +) + +find_library(XINERAMA_LIBRARY NAMES Xinerama + DOC "The Xinerama library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xinerama DEFAULT_MSG XINERAMA_LIBRARY XINERAMA_INCLUDE_DIR) + +if(XINERAMA_FOUND) + set( XINERAMA_LIBRARIES ${XINERAMA_LIBRARY} ) + set( XINERAMA_INCLUDE_DIRS ${XINERAMA_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XINERAMA_INCLUDE_DIR XINERAMA_LIBRARY) + diff --git a/cmake/FindXmlto.cmake b/cmake/FindXmlto.cmake new file mode 100644 index 0000000..167be67 --- /dev/null +++ b/cmake/FindXmlto.cmake @@ -0,0 +1,35 @@ +# - Find xmlto +# Find the xmlto docbook xslt frontend +# +# This module defines the following variables: +# XMLTO_FOUND - true if xmlto was found +# XMLTO_EXECUTABLE - Path to xmlto, if xmlto was found +# + +#============================================================================= +# Copyright 2011 Nils Andresen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +set(XMLTO_FOUND false) + +find_program(XMLTO_EXECUTABLE + NAMES xmlto + DOC "docbook xslt frontend") + +if(XMLTO_EXECUTABLE) + set(XMLTO_FOUND true) + message(STATUS "Found XMLTO: ${XMLTO_EXECUTABLE}") +endif() + +mark_as_advanced(XMLTO_EXECUTABLE) diff --git a/cmake/FindXv.cmake b/cmake/FindXv.cmake new file mode 100644 index 0000000..346e6c6 --- /dev/null +++ b/cmake/FindXv.cmake @@ -0,0 +1,49 @@ +# - Find Xv +# Find the Xv libraries +# +# This module defines the following variables: +# XV_FOUND - true if XV_INCLUDE_DIR & XV_LIBRARY are found +# XV_LIBRARIES - Set when XV_LIBRARY is found +# XV_INCLUDE_DIRS - Set when XV_INCLUDE_DIR is found +# +# XV_INCLUDE_DIR - where to find Xv.h, etc. +# XV_LIBRARY - the Xv library +# + +#============================================================================= +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(XV_INCLUDE_DIR NAMES X11/extensions/Xv.h + PATH_SUFFIXES X11/extensions + DOC "The Xv include directory" +) + +find_library(XV_LIBRARY NAMES Xv + DOC "The Xv library" +) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Xv DEFAULT_MSG XV_LIBRARY XV_INCLUDE_DIR) + +if(XV_FOUND) + set( XV_LIBRARIES ${XV_LIBRARY} ) + set( XV_INCLUDE_DIRS ${XV_INCLUDE_DIR} ) +endif() + +mark_as_advanced(XV_INCLUDE_DIR XV_LIBRARY) + diff --git a/cmake/GNUInstallDirsWrapper.cmake b/cmake/GNUInstallDirsWrapper.cmake new file mode 100644 index 0000000..e438a01 --- /dev/null +++ b/cmake/GNUInstallDirsWrapper.cmake @@ -0,0 +1,13 @@ +# GNUInstallDirs is a relatively new cmake module, so wrap it to avoid errors +include(GNUInstallDirs OPTIONAL RESULT_VARIABLE GID_PATH) +if(GID_PATH STREQUAL "NOTFOUND") + if(NOT DEFINED CMAKE_INSTALL_BINDIR) + set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)") + endif() + + if(NOT DEFINED CMAKE_INSTALL_LIBDIR) + set(CMAKE_INSTALL_LIBDIR "lib${LIB_SUFFIX}" CACHE PATH "object code libraries (lib)") + endif() + + mark_as_advanced(CMAKE_INSTALL_BINDIR CMAKE_INSTALL_LIBDIR) +endif() diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..7428764 --- /dev/null +++ b/config.h.in @@ -0,0 +1,51 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#define FREERDP_VERSION "${FREERDP_VERSION}" +#define FREERDP_VERSION_FULL "${FREERDP_VERSION_FULL}" +#define FREERDP_VERSION_MAJOR ${FREERDP_VERSION_MAJOR} +#define FREERDP_VERSION_MINOR ${FREERDP_VERSION_MINOR} +#define FREERDP_VERSION_REVISION ${FREERDP_VERSION_REVISION} + +/* Include files */ +#cmakedefine HAVE_SYS_PARAM_H +#cmakedefine HAVE_SYS_SOCKET_H +#cmakedefine HAVE_NETDB_H +#cmakedefine HAVE_FCNTL_H +#cmakedefine HAVE_UNISTD_H +#cmakedefine HAVE_LIMITS_H +#cmakedefine HAVE_STDINT_H +#cmakedefine HAVE_STDBOOL_H +#cmakedefine HAVE_INTTYPES_H + +/* Endian */ +#cmakedefine BIG_ENDIAN + +/* Options */ +#cmakedefine WITH_DEBUG_TRANSPORT +#cmakedefine WITH_DEBUG_CHANNELS +#cmakedefine WITH_DEBUG_SVC +#cmakedefine WITH_DEBUG_DVC +#cmakedefine WITH_DEBUG_KBD +#cmakedefine WITH_DEBUG_NLA +#cmakedefine WITH_DEBUG_NEGO +#cmakedefine WITH_DEBUG_CERTIFICATE +#cmakedefine WITH_DEBUG_LICENSE +#cmakedefine WITH_DEBUG_GDI +#cmakedefine WITH_DEBUG_ASSERT +#cmakedefine WITH_DEBUG_RFX +#cmakedefine WITH_PROFILER +#cmakedefine WITH_SSE2 +#cmakedefine WITH_SSE2_TARGET +#cmakedefine WITH_NEON +#cmakedefine WITH_DEBUG_X11 +#cmakedefine WITH_DEBUG_X11_CLIPRDR +#cmakedefine WITH_DEBUG_X11_LOCAL_MOVESIZE +#cmakedefine WITH_DEBUG_RAIL +#cmakedefine WITH_DEBUG_XV +#cmakedefine WITH_DEBUG_SCARD +#cmakedefine WITH_DEBUG_ORDERS +#cmakedefine WITH_DEBUG_REDIR +#cmakedefine WITH_DEBUG_CLIPRDR +#cmakedefine WITH_DEBUG_WND +#endif diff --git a/cunit/CMakeLists.txt b/cunit/CMakeLists.txt new file mode 100644 index 0000000..7dbb6e9 --- /dev/null +++ b/cunit/CMakeLists.txt @@ -0,0 +1,77 @@ +# FreeRDP: A Remote Desktop Protocol Client +# cunit cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_directories(${CUNIT_INCLUDE_DIRS}) +include_directories(${CMAKE_SOURCE_DIR}) # for some internal tests + +include_directories(../libfreerdp-core) +include_directories(../libfreerdp-gdi) +include_directories(../libfreerdp-cache) +include_directories(../libfreerdp-codec) + +add_executable(test_freerdp + test_per.c + test_per.h + test_ber.c + test_ber.h + test_gcc.c + test_gcc.h + test_mcs.c + test_mcs.h + test_color.c + test_color.h + test_bitmap.c + test_bitmap.h + test_libgdi.c + test_libgdi.h + test_list.c + test_list.h + test_orders.c + test_orders.h + test_pcap.c + test_pcap.h + test_license.c + test_license.h + test_stream.c + test_stream.h + test_utils.c + test_utils.h + test_channels.c + test_channels.h + test_cliprdr.c + test_cliprdr.h + test_drdynvc.c + test_drdynvc.h + test_librfx.c + test_librfx.h + test_freerdp.c + test_freerdp.h + test_rail.c + test_rail.h + test_mppc) + +target_link_libraries(test_freerdp ${CUNIT_LIBRARIES}) + +target_link_libraries(test_freerdp freerdp-core) +target_link_libraries(test_freerdp freerdp-gdi) +target_link_libraries(test_freerdp freerdp-utils) +target_link_libraries(test_freerdp freerdp-channels) +target_link_libraries(test_freerdp freerdp-codec) + +add_test(CUnitTests ${EXECUTABLE_OUTPUT_PATH}/test_freerdp) diff --git a/cunit/test_ber.c b/cunit/test_ber.c new file mode 100644 index 0000000..2f1825a --- /dev/null +++ b/cunit/test_ber.c @@ -0,0 +1,96 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Basic Encoding Rules (BER) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "test_ber.h" +#include "libfreerdp-core/ber.h" + +int init_ber_suite(void) +{ + return 0; +} + +int clean_ber_suite(void) +{ + return 0; +} + +int add_ber_suite(void) +{ + add_test_suite(ber); + + add_test_function(ber_write_length); + add_test_function(ber_write_universal_tag); + add_test_function(ber_write_application_tag); + + return 0; +} + +uint8 ber_length_expected_1[1] = "\x40"; /* 64 */ +uint8 ber_length_expected_2[3] = "\x82\x01\x94"; /* 404 */ + +void test_ber_write_length(void) +{ + STREAM *s1, *s2; + + s1 = stream_new(sizeof(ber_length_expected_1)); + s2 = stream_new(sizeof(ber_length_expected_2)); + + ber_write_length(s1, 64); + ASSERT_STREAM(s1, (uint8*) ber_length_expected_1, sizeof(ber_length_expected_1)); + + ber_write_length(s2, 404); + ASSERT_STREAM(s2, (uint8*) ber_length_expected_2, sizeof(ber_length_expected_2)); + + stream_free(s1); + stream_free(s2); +} + +/* BOOLEAN, length 1, without value */ +uint8 ber_universal_tag_expected[1] = "\x01"; + +void test_ber_write_universal_tag(void) +{ + STREAM* s; + + s = stream_new(sizeof(ber_universal_tag_expected)); + ber_write_universal_tag(s, 1, false); + + ASSERT_STREAM(s, (uint8*) ber_universal_tag_expected, sizeof(ber_universal_tag_expected)); + + stream_free(s); +} + +/* T.125 MCS Application 101 (Connect-Initial), length 404 */ +uint8 ber_application_tag_expected[5] = "\x7F\x65\x82\x01\x94"; + +void test_ber_write_application_tag(void) +{ + STREAM* s; + + s = stream_new(sizeof(ber_application_tag_expected)); + ber_write_application_tag(s, 101, 404); + + ASSERT_STREAM(s, (uint8*) ber_application_tag_expected, sizeof(ber_application_tag_expected)); + + stream_free(s); +} diff --git a/cunit/test_ber.h b/cunit/test_ber.h new file mode 100644 index 0000000..0cc9228 --- /dev/null +++ b/cunit/test_ber.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Basic Encoding Rules (BER) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_ber_suite(void); +int clean_ber_suite(void); +int add_ber_suite(void); + +void test_ber_write_length(void); +void test_ber_write_universal_tag(void); +void test_ber_write_application_tag(void); diff --git a/cunit/test_bitmap.c b/cunit/test_bitmap.c new file mode 100644 index 0000000..b25a065 --- /dev/null +++ b/cunit/test_bitmap.c @@ -0,0 +1,1250 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap Unit Tests + * + * Copyright 2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "test_bitmap.h" + +uint8 compressed_16x1x8[] = +{ +0x10 +}; + +uint8 decompressed_16x1x8[] = +{ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_32x32x8[] = +{ +0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, +0xec, 0x6c, 0x0e, 0x0e, 0x44, 0x0e, 0x0e, 0x0e, 0x13, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, +0xed, 0x06, 0x06, 0x06, 0x00, 0x00, 0xe4, 0x04, 0x06, 0x8e, 0x60, 0x0e, 0x60, 0x8c, 0xb4, 0xb5, +0xdc, 0xdc, 0xbb, 0xb4, 0x8c, 0x66, 0x0b, 0x6c, 0xe4, 0x04, 0x06, 0x02, 0x8b, 0x06, 0x06, 0xed, +0x06, 0xed, 0x06, 0xf8, 0x0e, 0x66, 0xb4, 0xdc, 0x68, 0xe2, 0x97, 0xdd, 0xb4, 0xa7, 0x16, 0x06, +0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0x00, 0x00, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x0b, 0xae, +0xdc, 0xe9, 0x6a, 0xdc, 0x96, 0xe9, 0xe9, 0xb4, 0x0e, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x00, +0x00, 0x06, 0x06, 0xed, 0x06, 0x06, 0x0e, 0xae, 0xdc, 0xdb, 0xdb, 0xd0, 0x09, 0x07, 0xcf, 0x03, +0x95, 0xdb, 0xdb, 0xdc, 0xb4, 0x66, 0x6c, 0xed, 0x06, 0x06, 0x06, 0x00, 0x00, 0x04, 0x06, 0x04, +0x06, 0x0b, 0xae, 0xdb, 0xd4, 0xd5, 0x6c, 0xdb, 0x80, 0xaf, 0xd5, 0xd4, 0xdb, 0xb4, 0x66, 0x04, +0x06, 0x04, 0x06, 0x00, 0x00, 0xed, 0x06, 0xed, 0x66, 0xae, 0xd5, 0xad, 0xd4, 0xd4, 0xd5, 0xd5, +0xd5, 0xdb, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xad, 0xd5, 0xb4, 0x0e, +0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x06, 0x60, 0xa7, 0xb4, 0xad, 0xad, 0xad, 0xb3, 0xb3, 0xd4, +0xd4, 0xb3, 0x8c, 0xb6, 0x07, 0xb6, 0x8c, 0xb3, 0xd4, 0xb3, 0xb3, 0xad, 0xad, 0xad, 0xb4, 0xad, +0x66, 0x00, 0x06, 0x00, 0x00, 0x06, 0x06, 0x66, 0xae, 0xad, 0x8b, 0xad, 0xad, 0xad, 0xad, 0xad, +0xb3, 0xad, 0xb5, 0x07, 0x07, 0x07, 0xf0, 0x8b, 0xad, 0xad, 0xad, 0xad, 0xad, 0x8b, 0xa7, 0xae, +0xa7, 0x6c, 0x06, 0x00, 0x00, 0x04, 0x6c, 0xa7, 0xad, 0xa7, 0xa7, 0x8b, 0xad, 0xad, 0xad, 0xad, +0xad, 0xad, 0xb5, 0xbd, 0xbd, 0xbd, 0xbd, 0xf0, 0x8b, 0x8b, 0xad, 0x8b, 0x8b, 0xa7, 0xa7, 0xc8, +0xc8, 0x60, 0x06, 0x00, 0x00, 0x06, 0x66, 0xc8, 0xa7, 0x66, 0xa7, 0xa7, 0x8b, 0x8b, 0x8b, 0x8b, +0xad, 0x8b, 0x92, 0xf1, 0xf1, 0xf1, 0xf1, 0xf2, 0x07, 0xa7, 0xa7, 0x8b, 0xa7, 0xa7, 0x66, 0x66, +0xc8, 0x66, 0x06, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x66, 0x66, 0x66, 0xa7, 0xa7, 0xa7, 0xa7, 0x8b, +0x8b, 0x8b, 0xa7, 0xb6, 0xf3, 0xf3, 0xf3, 0xf3, 0xf3, 0x07, 0x66, 0xa7, 0xa7, 0x66, 0x66, 0x66, +0xa7, 0xa7, 0x6c, 0x00, 0x00, 0x6c, 0x04, 0xa7, 0x60, 0x6b, 0x66, 0x99, 0xb6, 0xf5, 0xf5, 0xf5, +0xf5, 0xf5, 0xef, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xa7, 0x66, 0x00, 0x00, 0x60, 0xa7, 0x66, +0x60, 0x66, 0x66, 0x8c, 0xf1, 0x6e, 0xff, 0x85, 0xbd, 0x66, 0x66, 0x66, 0x60, 0x05, 0x87, 0x13, +0x04, 0x66, 0x66, 0x66, 0x66, 0xf4, 0x70, 0xff, 0x84, 0xbd, 0x66, 0x66, 0x66, 0x05, 0x85, 0x0b, +0xa7, 0xb5, 0xae, 0x8c, 0xd0, 0x13, 0xc1, 0x01, 0x00, 0x08, 0x8e, 0x8c, 0xae, 0xb5, 0xae, 0x66, +0x00, 0x00, 0x6c, 0xae, 0xbc, 0xb5, 0xb5, 0xae, 0xb5, 0xd0, 0x0e, 0x0c, 0x01, 0x00, 0x90, 0xf2, +0xae, 0xae, 0xb5, 0xb5, 0xbc, 0xb5, 0x66, 0x00, 0x00, 0x04, 0xae, 0x0a, 0xb5, 0xb5, 0xb5, 0x68, +0xae, 0x82, 0x8c, 0x0a, 0x05, 0x8c, 0xf2, 0xae, 0xae, 0xb5, 0xb5, 0xb5, 0xbc, 0xb5, 0x6c, 0x00, +0x00, 0x06, 0x05, 0x81, 0xd0, 0x06, 0x9a, 0x8c, 0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, +0xae, 0xd0, 0xb5, 0xb5, 0xb5, 0x0a, 0xb5, 0x6c, 0x00, 0x00, 0x00, 0x8b, 0x0a, 0xbc, 0xb5, 0xb5, +0xb5, 0x06, 0x9b, 0xb6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xae, 0xb5, 0xb5, 0xb5, +0xb6, 0x0a, 0x8c, 0x06, 0x00, 0x00, 0x06, 0x6c, 0xb5, 0x0a, 0xb6, 0xb5, 0xb5, 0xb5, 0x05, 0x80, +0x7d, 0xbc, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xae, 0xb5, 0xb5, 0xb5, 0xb6, 0x0a, 0x0a, +0x8b, 0x06, 0x00, 0x00, 0x04, 0x06, 0x87, 0x0a, 0xbc, 0xb6, 0xb5, 0xb5, 0xb5, 0xd0, 0xae, 0xae, +0xae, 0xb6, 0xff, 0xff, 0xff, 0xf2, 0xd0, 0xae, 0xd0, 0xb5, 0xb5, 0xb5, 0xb6, 0xbc, 0x1a, 0xb5, +0x04, 0x06, 0x00, 0x00, 0xed, 0x06, 0x6e, 0xb5, 0x0a, 0xbc, 0xb6, 0xb5, 0xb5, 0xb5, 0xd0, 0xd0, +0xd0, 0xb5, 0xf4, 0xff, 0xf2, 0xd0, 0xd0, 0xd0, 0xb5, 0xb5, 0xb5, 0xb6, 0xbc, 0x0a, 0x0a, 0x8b, +0x06, 0x06, 0x00, 0x00, 0x00, 0x06, 0x04, 0x8b, 0xbc, 0x1a, 0x0a, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, +0xb5, 0xb5, 0xd0, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, 0x0a, 0xde, 0x0a, 0xa7, 0x06, +0x00, 0x06, 0x00, 0x00, 0x06, 0x06, 0xed, 0x06, 0x8b, 0xbc, 0xf2, 0x0a, 0xb6, 0xb6, 0xb6, 0xb6, +0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb6, 0x0a, 0xf2, 0x1a, 0x8c, 0xec, 0x06, +0x06, 0x06, 0x00, 0x00, 0x04, 0x06, 0x04, 0x06, 0x04, 0xa7, 0xbc, 0x1a, 0x0a, 0x0a, 0x6a, 0xb6, +0x96, 0x0a, 0x0a, 0xf2, 0x0a, 0x87, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x00, 0x06, 0x06, 0xed, +0x06, 0xed, 0x06, 0x8c, 0xb6, 0xf4, 0xf2, 0xd0, 0x09, 0xbc, 0x87, 0x03, 0x80, 0x2c, 0xde, 0xf4, +0x0a, 0x8b, 0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0x00, 0x00, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, +0x04, 0x6c, 0x87, 0x0a, 0xf4, 0xf4, 0xf2, 0xde, 0xbd, 0xbd, 0xde, 0xf2, 0xf4, 0xf4, 0x0a, 0xd0, +0x04, 0x06, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x00, 0x00, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, +0xed, 0x06, 0x06, 0x6c, 0x8c, 0xb5, 0xbc, 0x0a, 0xde, 0xf2, 0xbd, 0x0a, 0xb5, 0x8c, 0x6c, 0x06, +0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0x00, 0x00, 0xe6, 0x04, 0x06, 0x86, 0x04, 0x6c, +0x04, 0x8b, 0x04, 0x6c, 0xe6, 0x04, 0x06, 0x82, 0x00, 0x00 +}; + +uint8 decompressed_32x32x8[] = +{ +0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x6c, 0x04, 0x8b, +0x04, 0x6c, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x6c, 0x8c, 0xb5, 0xbc, 0x0a, 0xde, 0xf2, +0xbd, 0x0a, 0xb5, 0x8c, 0x6c, 0x06, 0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0x00, 0x00, +0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x04, 0x6c, 0x87, 0x0a, 0xf4, 0xf4, 0xf2, 0xde, 0xbd, 0xbd, +0xde, 0xf2, 0xf4, 0xf4, 0x0a, 0xd0, 0x04, 0x06, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0x8c, 0xb6, 0xf4, 0xf2, 0x0a, 0x0a, 0x0a, 0xb6, 0xb6, 0xb6, +0xb6, 0x0a, 0x0a, 0x0a, 0xde, 0xf4, 0x0a, 0x8b, 0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0x00, 0x00, +0x04, 0x06, 0x04, 0x06, 0x04, 0xa7, 0xbc, 0x1a, 0x0a, 0x0a, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, +0xb6, 0xb6, 0xb6, 0xb6, 0x0a, 0x0a, 0xf2, 0x0a, 0x87, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0x8b, 0xbc, 0xf2, 0x0a, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, +0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb6, 0x0a, 0xf2, 0x1a, 0x8c, 0xec, 0x06, 0x06, 0x06, 0x00, 0x00, +0x00, 0x06, 0x04, 0x8b, 0xbc, 0x1a, 0x0a, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xd0, 0xb5, +0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb6, 0xb6, 0x0a, 0xde, 0x0a, 0xa7, 0x06, 0x00, 0x06, 0x00, 0x00, +0xed, 0x06, 0x6e, 0xb5, 0x0a, 0xbc, 0xb6, 0xb5, 0xb5, 0xb5, 0xd0, 0xd0, 0xd0, 0xb5, 0xf4, 0xff, +0xf2, 0xd0, 0xd0, 0xd0, 0xb5, 0xb5, 0xb5, 0xb6, 0xbc, 0x0a, 0x0a, 0x8b, 0x06, 0x06, 0x00, 0x00, +0x04, 0x06, 0x87, 0x0a, 0xbc, 0xb6, 0xb5, 0xb5, 0xb5, 0xd0, 0xae, 0xae, 0xae, 0xb6, 0xff, 0xff, +0xff, 0xf2, 0xd0, 0xae, 0xd0, 0xb5, 0xb5, 0xb5, 0xb6, 0xbc, 0x1a, 0xb5, 0x04, 0x06, 0x00, 0x00, +0x06, 0x6c, 0xb5, 0x0a, 0xb6, 0xb5, 0xb5, 0xb5, 0xae, 0xae, 0xae, 0xae, 0xae, 0xbc, 0xff, 0xff, +0xff, 0xff, 0xf2, 0xae, 0xae, 0xae, 0xb5, 0xb5, 0xb5, 0xb6, 0x0a, 0x0a, 0x8b, 0x06, 0x00, 0x00, +0x00, 0x8b, 0x0a, 0xbc, 0xb5, 0xb5, 0xb5, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xb6, 0xff, 0xff, +0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xae, 0xb5, 0xb5, 0xb5, 0xb6, 0x0a, 0x8c, 0x06, 0x00, 0x00, +0x06, 0xae, 0x0a, 0xb5, 0xb5, 0xb5, 0xd0, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0x8c, 0x0a, 0xff, +0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xd0, 0xb5, 0xb5, 0xb5, 0x0a, 0xb5, 0x6c, 0x00, 0x00, +0x04, 0xae, 0x0a, 0xb5, 0xb5, 0xb5, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0x8c, 0x0a, +0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xb5, 0xb5, 0xb5, 0xbc, 0xb5, 0x6c, 0x00, 0x00, +0x6c, 0xae, 0xbc, 0xb5, 0xb5, 0xae, 0xb5, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xae, 0xae, 0xb5, 0xb5, 0xbc, 0xb5, 0x66, 0x00, 0x00, +0x0b, 0xa7, 0xb5, 0xae, 0x8c, 0xa7, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, 0xa7, 0x8c, 0xae, 0xb5, 0xae, 0x66, 0x00, 0x00, +0x13, 0x04, 0x66, 0x66, 0x66, 0x66, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, 0x66, 0x66, 0x66, 0x66, 0xa7, 0x66, 0x00, 0x00, +0x60, 0xa7, 0x66, 0x60, 0x66, 0x66, 0x8c, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, 0x66, 0x66, 0x66, 0x60, 0x66, 0xa7, 0x66, 0x00, 0x00, +0x6c, 0x04, 0xa7, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xb6, +0xf5, 0xf5, 0xf5, 0xf5, 0xf5, 0xef, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xa7, 0x66, 0x00, 0x00, +0x00, 0x60, 0xa7, 0x66, 0x66, 0x66, 0xa7, 0xa7, 0xa7, 0xa7, 0x8b, 0x8b, 0x8b, 0xa7, 0xb6, 0xf3, +0xf3, 0xf3, 0xf3, 0xf3, 0x07, 0x66, 0xa7, 0xa7, 0x66, 0x66, 0x66, 0xa7, 0xa7, 0x6c, 0x00, 0x00, +0x06, 0x66, 0xc8, 0xa7, 0x66, 0xa7, 0xa7, 0x8b, 0x8b, 0x8b, 0x8b, 0xad, 0x8b, 0x92, 0xf1, 0xf1, +0xf1, 0xf1, 0xf2, 0x07, 0xa7, 0xa7, 0x8b, 0xa7, 0xa7, 0x66, 0x66, 0xc8, 0x66, 0x06, 0x00, 0x00, +0x04, 0x6c, 0xa7, 0xad, 0xa7, 0xa7, 0x8b, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xb5, 0xbd, 0xbd, +0xbd, 0xbd, 0xf0, 0x8b, 0x8b, 0xad, 0x8b, 0x8b, 0xa7, 0xa7, 0xc8, 0xc8, 0x60, 0x06, 0x00, 0x00, +0x06, 0x06, 0x66, 0xae, 0xad, 0x8b, 0xad, 0xad, 0xad, 0xad, 0xad, 0xb3, 0xad, 0xb5, 0x07, 0x07, +0x07, 0xf0, 0x8b, 0xad, 0xad, 0xad, 0xad, 0xad, 0x8b, 0xa7, 0xae, 0xa7, 0x6c, 0x06, 0x00, 0x00, +0x00, 0x06, 0x60, 0xa7, 0xb4, 0xad, 0xad, 0xad, 0xb3, 0xb3, 0xd4, 0xd4, 0xb3, 0x8c, 0xb6, 0x07, +0xb6, 0x8c, 0xb3, 0xd4, 0xb3, 0xb3, 0xad, 0xad, 0xad, 0xb4, 0xad, 0x66, 0x00, 0x06, 0x00, 0x00, +0xed, 0x06, 0xed, 0x66, 0xae, 0xd5, 0xad, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xdb, 0xb4, 0xb4, 0xb4, +0xb4, 0xb4, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xad, 0xd5, 0xb4, 0x0e, 0x06, 0x06, 0x06, 0x00, 0x00, +0x04, 0x06, 0x04, 0x06, 0x0b, 0xae, 0xdb, 0xd4, 0xd5, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, +0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xd5, 0xd4, 0xdb, 0xb4, 0x66, 0x04, 0x06, 0x04, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0x06, 0x0e, 0xae, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, +0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, 0xb4, 0x66, 0x6c, 0xed, 0x06, 0x06, 0x06, 0x00, 0x00, +0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x0b, 0xae, 0xdc, 0xe9, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, +0xdc, 0xdc, 0xdc, 0xdc, 0xe9, 0xe9, 0xb4, 0x0e, 0x00, 0x06, 0x04, 0x06, 0x00, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0xf8, 0x0e, 0x66, 0xb4, 0xdc, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, +0xe2, 0xe2, 0xe2, 0xdd, 0xb4, 0xa7, 0x16, 0x06, 0x06, 0x06, 0xed, 0x06, 0xed, 0x06, 0x00, 0x00, +0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x60, 0x0e, 0x60, 0x8c, 0xb4, 0xb5, 0xdc, 0xdc, +0xbb, 0xb4, 0x8c, 0x66, 0x0b, 0x6c, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x00, 0x00, +0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0xec, 0x6c, 0x0e, 0x0e, 0x44, 0x0e, +0x0e, 0x0e, 0x13, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0xed, 0x06, 0x06, 0x06, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_16x1x16[] = +{ +0x0c, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 decompressed_16x1x16[] = +{ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_32x32x16[] = +{ +0x1c, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xef, 0x1a, 0x8a, +0xcf, 0x12, 0x4e, 0x12, 0xce, 0x09, 0xaf, 0x09, 0x8f, 0x01, 0x8f, 0x01, 0xaf, 0x09, 0xce, 0x09, +0x2e, 0x12, 0xaf, 0x12, 0x2a, 0x0a, 0x8e, 0x8f, 0x12, 0xae, 0x09, 0xd2, 0x01, 0x9b, 0x23, 0x1d, +0x5d, 0x1e, 0x86, 0xbf, 0x9e, 0xdf, 0xa6, 0x5f, 0x8e, 0x7e, 0x6d, 0xfc, 0x2b, 0x16, 0x02, 0x8f, +0x09, 0x4f, 0x12, 0x11, 0x91, 0xce, 0x09, 0x17, 0x02, 0x1e, 0x55, 0x5f, 0xaf, 0xff, 0xcf, 0xff, +0xc7, 0xff, 0xbf, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xc7, 0xff, 0xcf, 0xbf, 0xb7, 0xbe, +0x6d, 0xba, 0x02, 0xae, 0x09, 0xcf, 0x12, 0x0d, 0x94, 0xcf, 0x12, 0x6f, 0x01, 0x1d, 0x2c, 0x7f, +0x9f, 0xff, 0xaf, 0xff, 0x97, 0xdf, 0x87, 0xbf, 0x8f, 0xbf, 0x97, 0xbf, 0x9f, 0xbf, 0x9f, 0xbf, +0x97, 0xbf, 0x8f, 0xdf, 0x87, 0xff, 0x8f, 0xff, 0xa7, 0xdf, 0xa7, 0xdd, 0x3c, 0x4f, 0x01, 0x8f, +0x12, 0x0b, 0x96, 0xaf, 0x12, 0x2f, 0x01, 0xbd, 0x34, 0xbf, 0x8f, 0x5f, 0x77, 0x5f, 0x6f, 0x9f, +0x77, 0x9f, 0x7f, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, 0x9f, +0x7f, 0x7f, 0x7f, 0x5f, 0x6f, 0x3f, 0x6f, 0xbf, 0x87, 0xbf, 0x55, 0x72, 0x01, 0x6f, 0x12, 0x09, +0x98, 0xcf, 0x12, 0x4f, 0x01, 0xde, 0x34, 0xff, 0x6e, 0x5f, 0x4e, 0xbf, 0x5e, 0x1f, 0x67, 0x3f, +0x6f, 0x5f, 0x6f, 0x5f, 0x6f, 0x5f, 0x77, 0x5f, 0x77, 0x5f, 0x77, 0x5f, 0x77, 0x5f, 0x6f, 0x5f, +0x6f, 0x3f, 0x6f, 0x1f, 0x67, 0xdf, 0x5e, 0x3f, 0x4e, 0xbf, 0x66, 0xdf, 0x4d, 0x72, 0x01, 0xaf, +0x12, 0x08, 0x99, 0x8e, 0x09, 0xfc, 0x1b, 0x3f, 0x4e, 0x3e, 0x25, 0xff, 0x3d, 0x5f, 0x4e, 0x9f, +0x56, 0xbf, 0x5e, 0xdf, 0x66, 0xdf, 0x5e, 0x3c, 0x56, 0x79, 0x4d, 0x17, 0x4d, 0x99, 0x4d, 0x5d, +0x5e, 0xdf, 0x66, 0xbf, 0x5e, 0x9f, 0x56, 0x5f, 0x4e, 0xff, 0x3d, 0x1e, 0x25, 0xdf, 0x3d, 0xfe, +0x34, 0x2f, 0x01, 0xcf, 0x12, 0x06, 0x80, 0xa6, 0x0f, 0x0a, 0xba, 0x02, 0x5f, 0x35, 0x5d, 0x0c, +0xbd, 0x14, 0x5e, 0x2d, 0xbe, 0x3d, 0xff, 0x3d, 0x1f, 0x46, 0x3f, 0x46, 0x1e, 0x4e, 0xd7, 0x44, +0xb7, 0xa5, 0xf7, 0xbd, 0x97, 0x95, 0xb7, 0x44, 0x9c, 0x45, 0x1f, 0x46, 0xff, 0x3d, 0xbf, 0x3d, +0x5e, 0x2d, 0xbd, 0x1c, 0x3d, 0x04, 0x1e, 0x25, 0xbc, 0x13, 0xae, 0x09, 0xef, 0x1a, 0xef, 0x1a, +0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0xaf, 0x12, 0x31, 0x01, 0x7d, 0x24, 0xdc, 0x03, 0xfc, 0x03, +0x5d, 0x0c, 0xbd, 0x14, 0x1e, 0x25, 0x3e, 0x2d, 0x7e, 0x35, 0x9e, 0x35, 0xfb, 0x34, 0x17, 0x6d, +0x18, 0xc6, 0x18, 0xc6, 0x18, 0xc6, 0xb8, 0xa5, 0x57, 0x2c, 0xfb, 0x2c, 0x5e, 0x2d, 0x1e, 0x25, +0xbd, 0x14, 0x5d, 0x0c, 0xfd, 0x03, 0x7a, 0x03, 0x9e, 0x24, 0xd6, 0x01, 0x6f, 0x12, 0xef, 0x1a, +0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0x2f, 0x0a, 0x79, 0x02, 0xdd, 0x0b, 0xf8, 0x02, 0x9b, 0x03, +0xfd, 0x03, 0x3d, 0x0c, 0x7d, 0x14, 0xbd, 0x1c, 0xdd, 0x1c, 0xfe, 0x24, 0x7a, 0x1c, 0x18, 0x6d, +0x79, 0xce, 0x79, 0xce, 0x79, 0xce, 0x79, 0xce, 0xd9, 0xad, 0xd7, 0x23, 0x5b, 0x14, 0x7d, 0x14, +0x3d, 0x0c, 0xfd, 0x03, 0x9b, 0x03, 0x18, 0x03, 0x7b, 0x03, 0x1b, 0x0b, 0xaf, 0x09, 0xef, 0x1a, +0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0x6f, 0x01, 0xda, 0x0a, 0x97, 0x02, 0x96, 0x02, 0x19, 0x03, +0x9b, 0x03, 0xfd, 0x03, 0x1d, 0x0c, 0x3d, 0x0c, 0x3d, 0x0c, 0x5d, 0x14, 0x1a, 0x14, 0xd8, 0x5c, +0xba, 0xd6, 0xba, 0xd6, 0xba, 0xd6, 0xdb, 0xd6, 0xdb, 0xde, 0x1a, 0xae, 0x77, 0x13, 0xba, 0x03, +0xfd, 0x03, 0x9b, 0x03, 0x19, 0x03, 0xb7, 0x02, 0x54, 0x02, 0x1b, 0x0b, 0x31, 0x01, 0xcf, 0x12, +0x00, 0x00, 0x00, 0x00, 0xaf, 0x12, 0x52, 0x01, 0xba, 0x02, 0xf3, 0x01, 0x34, 0x02, 0xb7, 0x02, +0xf8, 0x02, 0x7b, 0x03, 0xbc, 0x03, 0xdc, 0x03, 0xfd, 0x03, 0xfd, 0x03, 0x1d, 0x0c, 0x99, 0x03, +0x9a, 0x8d, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x5b, 0xb6, 0x36, 0x0b, +0x39, 0x03, 0xf8, 0x02, 0xb7, 0x02, 0x34, 0x02, 0xd2, 0x01, 0x99, 0x02, 0x97, 0x01, 0x4f, 0x12, +0x00, 0x00, 0x00, 0x00, 0x6f, 0x12, 0x95, 0x01, 0x77, 0x02, 0xd2, 0x01, 0x13, 0x02, 0x55, 0x02, +0x75, 0x02, 0x74, 0x02, 0x94, 0x02, 0xb5, 0x02, 0xd6, 0x02, 0xf6, 0x02, 0xf6, 0x02, 0xf6, 0x02, +0x17, 0x03, 0xbb, 0x8d, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7c, 0xbe, +0xb4, 0x0a, 0x75, 0x02, 0x55, 0x02, 0xf3, 0x01, 0xd2, 0x01, 0x35, 0x02, 0xf8, 0x01, 0xef, 0x09, +0x00, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0xf6, 0x01, 0x14, 0x02, 0xd2, 0x01, 0xf3, 0x01, 0xf2, 0x01, +0x75, 0x43, 0xfd, 0xce, 0x6e, 0xff, 0xff, 0x91, 0xbc, 0xc6, 0x32, 0x12, 0xf2, 0x01, 0xf3, 0x01, +0xd2, 0x01, 0xd2, 0x01, 0x17, 0x02, 0x8e, 0x09, 0x00, 0x00, 0x00, 0x00, 0xef, 0x09, 0xf5, 0x01, +0x14, 0x02, 0xd2, 0x01, 0xd2, 0x01, 0xb0, 0x01, 0x5e, 0xe7, 0x70, 0xff, 0xff, 0x90, 0x9c, 0xc6, +0xf0, 0x09, 0xd2, 0x01, 0xd2, 0x01, 0x13, 0x02, 0x16, 0x02, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, +0x0f, 0x0a, 0x3a, 0x1b, 0x9d, 0x75, 0xdb, 0x54, 0xfa, 0x33, 0xd5, 0x12, 0x7e, 0xe7, 0x10, 0x91, +0xbd, 0xc6, 0xf6, 0x1a, 0xfa, 0x33, 0xdb, 0x5c, 0xbd, 0x7d, 0x3b, 0x3c, 0x90, 0x01, 0x00, 0x00, +0x00, 0x00, 0x2f, 0x0a, 0x5b, 0x4c, 0xde, 0xae, 0xdd, 0x85, 0x7c, 0x75, 0xfb, 0x5c, 0x5b, 0x75, +0x3e, 0xdf, 0x0e, 0x80, 0xc6, 0x1e, 0xd7, 0x9a, 0x54, 0xfb, 0x5c, 0x7c, 0x75, 0xdd, 0x85, 0xbe, +0xa6, 0xbd, 0x7d, 0xf0, 0x09, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x12, 0x9b, 0x4c, 0x1f, 0xb7, 0xfd, +0x8d, 0x7c, 0x7d, 0x3c, 0x6d, 0xdc, 0x5c, 0x9c, 0x4c, 0x7c, 0x44, 0x7c, 0x3c, 0x5c, 0x34, 0x3c, +0x34, 0x3c, 0x2c, 0x3c, 0x2c, 0x1c, 0x24, 0x7e, 0xa6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0x3f, 0xd7, 0xdc, 0x54, 0xdc, 0x5c, 0x3c, 0x6d, 0x7c, 0x7d, 0xdc, 0x8d, 0xde, +0xb6, 0xdd, 0x85, 0x71, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x12, 0x5a, 0x44, 0x5f, 0xc7, 0x1d, +0x96, 0xbc, 0x85, 0x5c, 0x75, 0xfb, 0x64, 0xbc, 0x54, 0x9b, 0x4c, 0x7c, 0x44, 0x5c, 0x3c, 0x5c, +0x34, 0x3c, 0x34, 0x3c, 0x2c, 0x7e, 0xae, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0x3f, 0xd7, 0xbc, 0x54, 0xbc, 0x54, 0x1c, 0x65, 0x5c, 0x75, 0xbc, 0x85, 0x1d, 0x96, 0x3f, +0xc7, 0xbd, 0x7d, 0x90, 0x12, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0x57, 0x1b, 0x3f, 0xc7, 0x7d, +0xa6, 0xdc, 0x8d, 0x7c, 0x7d, 0x3c, 0x6d, 0xdc, 0x5c, 0xbb, 0x54, 0x7b, 0x4c, 0x7b, 0x44, 0x5b, +0x3c, 0x5c, 0x3c, 0xdd, 0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, +0xd7, 0xbc, 0x54, 0xbb, 0x54, 0xdb, 0x5c, 0x3c, 0x6d, 0x7c, 0x7d, 0xdc, 0x8d, 0x5d, 0xa6, 0x7f, +0xcf, 0x5a, 0x44, 0xef, 0x12, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0xb1, 0x12, 0x3d, 0x96, 0x1e, +0xc7, 0xfc, 0x9d, 0xbc, 0x8d, 0x5c, 0x7d, 0x1b, 0x6d, 0xdb, 0x5c, 0x9b, 0x54, 0x7b, 0x4c, 0x7b, +0x44, 0x5b, 0x44, 0x1d, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xd7, 0xbb, +0x54, 0x9b, 0x54, 0xdb, 0x5c, 0x1c, 0x6d, 0x5c, 0x7d, 0xbc, 0x8d, 0x1d, 0x9e, 0xde, 0xbe, 0x1e, +0xbf, 0xf5, 0x0a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0xcf, 0x12, 0xb8, 0x33, 0x7f, +0xd7, 0x7d, 0xae, 0xfc, 0x95, 0x9c, 0x85, 0x3b, 0x75, 0xfb, 0x64, 0xdb, 0x5c, 0x9b, 0x54, 0x9b, +0x54, 0x7b, 0x4c, 0xfd, 0x9d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xd7, 0xbb, 0x5c, 0x9b, +0x54, 0xdb, 0x5c, 0xfb, 0x64, 0x3b, 0x75, 0x9c, 0x85, 0xdc, 0x95, 0x7d, 0xae, 0x9f, 0xdf, 0x1b, +0x65, 0xd0, 0x12, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0xef, 0x1a, 0xd1, 0x12, 0xbd, +0x85, 0x5f, 0xd7, 0x5d, 0xae, 0xdc, 0x95, 0x7c, 0x85, 0x3b, 0x7d, 0x1b, 0x6d, 0xdb, 0x64, 0xbb, +0x5c, 0xbb, 0x5c, 0xfb, 0x64, 0x7f, 0xe7, 0xff, 0xff, 0x1e, 0xd7, 0xdb, 0x64, 0xbb, 0x5c, 0xdb, +0x64, 0xfb, 0x6c, 0x3b, 0x7d, 0x9c, 0x85, 0xdc, 0x95, 0x3d, 0xae, 0x3e, 0xcf, 0xbe, 0xb6, 0xf4, +0x0a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xd3, +0x0a, 0x5d, 0xa6, 0x5e, 0xd7, 0x5d, 0xae, 0xdc, 0x9d, 0x9c, 0x8d, 0x5b, 0x85, 0x3b, 0x7d, 0x1b, +0x75, 0xfb, 0x6c, 0xdb, 0x6c, 0xdb, 0x6c, 0x3b, 0x7d, 0xdb, 0x6c, 0xfb, 0x6c, 0x1b, 0x75, 0x3b, +0x7d, 0x5b, 0x85, 0x9c, 0x8d, 0xdc, 0x9d, 0x5d, 0xae, 0x3e, 0xd7, 0x3e, 0xcf, 0x36, 0x13, 0xef, +0x1a, 0x07, 0x98, 0xef, 0x1a, 0xd5, 0x0a, 0xbe, 0xb6, 0x5e, 0xdf, 0x5d, 0xae, 0xdc, 0x9d, 0xbc, +0x95, 0x7b, 0x8d, 0x5b, 0x85, 0x3b, 0x85, 0x3b, 0x7d, 0x1b, 0x7d, 0x1b, 0x7d, 0x3b, 0x7d, 0x3b, +0x85, 0x5b, 0x85, 0x9c, 0x8d, 0xbc, 0x95, 0xdc, 0x9d, 0x5d, 0xb6, 0x3e, 0xd7, 0x7f, 0xd7, 0x78, +0x23, 0xef, 0x12, 0x09, 0x97, 0xef, 0x1a, 0xd5, 0x0a, 0x7e, 0xae, 0x5e, 0xdf, 0x7d, 0xbe, 0x1c, +0xae, 0xdc, 0xa5, 0xbc, 0x9d, 0x9c, 0x95, 0x9b, 0x95, 0x9c, 0x8d, 0x9c, 0x8d, 0x9b, 0x95, 0x9c, +0x95, 0xbc, 0x9d, 0xdc, 0xa5, 0x1c, 0xae, 0x7d, 0xbe, 0x5e, 0xdf, 0x3e, 0xcf, 0x77, 0x23, 0xcf, +0x12, 0xef, 0x1a, 0x0a, 0x95, 0xef, 0x1a, 0xb3, 0x0a, 0xdd, 0x95, 0x9f, 0xe7, 0x1e, 0xd7, 0x9d, +0xbe, 0x3d, 0xae, 0x1c, 0xae, 0xfc, 0xa5, 0xdc, 0xa5, 0xdc, 0xa5, 0xfc, 0xa5, 0x1c, 0xae, 0x3d, +0xae, 0x7d, 0xbe, 0x1e, 0xd7, 0xbf, 0xef, 0x7d, 0xae, 0xf5, 0x12, 0xef, 0x12, 0xef, 0x1a, 0x0c, +0x93, 0xef, 0x1a, 0x90, 0x12, 0xd8, 0x3b, 0x7d, 0xae, 0x7f, 0xe7, 0x7f, 0xe7, 0x1e, 0xd7, 0xde, +0xce, 0xbd, 0xc6, 0xbd, 0xc6, 0xde, 0xce, 0x1e, 0xd7, 0x7f, 0xe7, 0x9f, 0xef, 0xde, 0xc6, 0x7a, +0x54, 0xb2, 0x0a, 0xef, 0x1a, 0xef, 0x1a, 0x0e, 0x8f, 0xef, 0x1a, 0xcf, 0x12, 0xb0, 0x12, 0x56, +0x1b, 0xda, 0x64, 0x1d, 0xa6, 0xbe, 0xbe, 0xfe, 0xce, 0xfe, 0xce, 0xde, 0xc6, 0x5d, 0xae, 0x3b, +0x7d, 0x97, 0x2b, 0xb2, 0x0a, 0xcf, 0x12, 0x68, 0xef, 0x1a, 0x0a, 0x8b, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xcf, 0x12, 0xb0, 0x12, 0x91, 0x0a, 0xb3, 0x0a, 0xb3, 0x0a, 0x91, 0x0a, 0xb0, 0x12, +0xcf, 0x12, 0x69, 0xef, 0x1a, 0x84, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 decompressed_32x32x16[] = +{ +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xcf, 0x12, 0xb0, 0x12, 0x91, 0x0a, 0xb3, 0x0a, 0xb3, 0x0a, +0x91, 0x0a, 0xb0, 0x12, 0xcf, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0xcf, 0x12, 0xb0, 0x12, 0x56, 0x1b, 0xda, 0x64, 0x1d, 0xa6, 0xbe, 0xbe, 0xfe, 0xce, 0xfe, 0xce, +0xde, 0xc6, 0x5d, 0xae, 0x3b, 0x7d, 0x97, 0x2b, 0xb2, 0x0a, 0xcf, 0x12, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x90, 0x12, +0xd8, 0x3b, 0x7d, 0xae, 0x7f, 0xe7, 0x7f, 0xe7, 0x1e, 0xd7, 0xde, 0xce, 0xbd, 0xc6, 0xbd, 0xc6, +0xde, 0xce, 0x1e, 0xd7, 0x7f, 0xe7, 0x9f, 0xef, 0xde, 0xc6, 0x7a, 0x54, 0xb2, 0x0a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xb3, 0x0a, 0xdd, 0x95, +0x9f, 0xe7, 0x1e, 0xd7, 0x9d, 0xbe, 0x3d, 0xae, 0x1c, 0xae, 0xfc, 0xa5, 0xdc, 0xa5, 0xdc, 0xa5, +0xfc, 0xa5, 0x1c, 0xae, 0x3d, 0xae, 0x7d, 0xbe, 0x1e, 0xd7, 0xbf, 0xef, 0x7d, 0xae, 0xf5, 0x12, +0xef, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xd5, 0x0a, 0x7e, 0xae, 0x5e, 0xdf, +0x7d, 0xbe, 0x1c, 0xae, 0xdc, 0xa5, 0xbc, 0x9d, 0x9c, 0x95, 0x9b, 0x95, 0x9c, 0x8d, 0x9c, 0x8d, +0x9b, 0x95, 0x9c, 0x95, 0xbc, 0x9d, 0xdc, 0xa5, 0x1c, 0xae, 0x7d, 0xbe, 0x5e, 0xdf, 0x3e, 0xcf, +0x77, 0x23, 0xcf, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xd5, 0x0a, 0xbe, 0xb6, 0x5e, 0xdf, 0x5d, 0xae, +0xdc, 0x9d, 0xbc, 0x95, 0x7b, 0x8d, 0x5b, 0x85, 0x3b, 0x85, 0x3b, 0x7d, 0x1b, 0x7d, 0x1b, 0x7d, +0x3b, 0x7d, 0x3b, 0x85, 0x5b, 0x85, 0x9c, 0x8d, 0xbc, 0x95, 0xdc, 0x9d, 0x5d, 0xb6, 0x3e, 0xd7, +0x7f, 0xd7, 0x78, 0x23, 0xef, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xd3, 0x0a, 0x5d, 0xa6, 0x5e, 0xd7, 0x5d, 0xae, 0xdc, 0x9d, +0x9c, 0x8d, 0x5b, 0x85, 0x3b, 0x7d, 0x1b, 0x75, 0xfb, 0x6c, 0xdb, 0x6c, 0xdb, 0x6c, 0x3b, 0x7d, +0xdb, 0x6c, 0xfb, 0x6c, 0x1b, 0x75, 0x3b, 0x7d, 0x5b, 0x85, 0x9c, 0x8d, 0xdc, 0x9d, 0x5d, 0xae, +0x3e, 0xd7, 0x3e, 0xcf, 0x36, 0x13, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xd1, 0x12, 0xbd, 0x85, 0x5f, 0xd7, 0x5d, 0xae, 0xdc, 0x95, 0x7c, 0x85, +0x3b, 0x7d, 0x1b, 0x6d, 0xdb, 0x64, 0xbb, 0x5c, 0xbb, 0x5c, 0xfb, 0x64, 0x7f, 0xe7, 0xff, 0xff, +0x1e, 0xd7, 0xdb, 0x64, 0xbb, 0x5c, 0xdb, 0x64, 0xfb, 0x6c, 0x3b, 0x7d, 0x9c, 0x85, 0xdc, 0x95, +0x3d, 0xae, 0x3e, 0xcf, 0xbe, 0xb6, 0xf4, 0x0a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xcf, 0x12, 0xb8, 0x33, 0x7f, 0xd7, 0x7d, 0xae, 0xfc, 0x95, 0x9c, 0x85, 0x3b, 0x75, +0xfb, 0x64, 0xdb, 0x5c, 0x9b, 0x54, 0x9b, 0x54, 0x7b, 0x4c, 0xfd, 0x9d, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x3e, 0xd7, 0xbb, 0x5c, 0x9b, 0x54, 0xdb, 0x5c, 0xfb, 0x64, 0x3b, 0x75, 0x9c, 0x85, +0xdc, 0x95, 0x7d, 0xae, 0x9f, 0xdf, 0x1b, 0x65, 0xd0, 0x12, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xb1, 0x12, 0x3d, 0x96, 0x1e, 0xc7, 0xfc, 0x9d, 0xbc, 0x8d, 0x5c, 0x7d, 0x1b, 0x6d, +0xdb, 0x5c, 0x9b, 0x54, 0x7b, 0x4c, 0x7b, 0x44, 0x5b, 0x44, 0x1d, 0x9e, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x3e, 0xd7, 0xbb, 0x54, 0x9b, 0x54, 0xdb, 0x5c, 0x1c, 0x6d, 0x5c, 0x7d, +0xbc, 0x8d, 0x1d, 0x9e, 0xde, 0xbe, 0x1e, 0xbf, 0xf5, 0x0a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0x57, 0x1b, 0x3f, 0xc7, 0x7d, 0xa6, 0xdc, 0x8d, 0x7c, 0x7d, 0x3c, 0x6d, 0xdc, 0x5c, +0xbb, 0x54, 0x7b, 0x4c, 0x7b, 0x44, 0x5b, 0x3c, 0x5c, 0x3c, 0xdd, 0x85, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xd7, 0xbc, 0x54, 0xbb, 0x54, 0xdb, 0x5c, 0x3c, 0x6d, +0x7c, 0x7d, 0xdc, 0x8d, 0x5d, 0xa6, 0x7f, 0xcf, 0x5a, 0x44, 0xef, 0x12, 0x00, 0x00, 0x00, 0x00, +0xcf, 0x12, 0x5a, 0x44, 0x5f, 0xc7, 0x1d, 0x96, 0xbc, 0x85, 0x5c, 0x75, 0xfb, 0x64, 0xbc, 0x54, +0x9b, 0x4c, 0x7c, 0x44, 0x5c, 0x3c, 0x5c, 0x34, 0x3c, 0x34, 0x3c, 0x2c, 0x7e, 0xae, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xd7, 0xbc, 0x54, 0xbc, 0x54, 0x1c, 0x65, +0x5c, 0x75, 0xbc, 0x85, 0x1d, 0x96, 0x3f, 0xc7, 0xbd, 0x7d, 0x90, 0x12, 0x00, 0x00, 0x00, 0x00, +0xb0, 0x12, 0x9b, 0x4c, 0x1f, 0xb7, 0xfd, 0x8d, 0x7c, 0x7d, 0x3c, 0x6d, 0xdc, 0x5c, 0x9c, 0x4c, +0x7c, 0x44, 0x7c, 0x3c, 0x5c, 0x34, 0x3c, 0x34, 0x3c, 0x2c, 0x3c, 0x2c, 0x1c, 0x24, 0x7e, 0xa6, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xd7, 0xdc, 0x54, 0xdc, 0x5c, +0x3c, 0x6d, 0x7c, 0x7d, 0xdc, 0x8d, 0xde, 0xb6, 0xdd, 0x85, 0x71, 0x0a, 0x00, 0x00, 0x00, 0x00, +0x2f, 0x0a, 0x5b, 0x4c, 0xde, 0xae, 0xdd, 0x85, 0x7c, 0x75, 0xfb, 0x5c, 0x5b, 0x75, 0x3e, 0xdf, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0xd7, 0x9a, 0x54, +0xfb, 0x5c, 0x7c, 0x75, 0xdd, 0x85, 0xbe, 0xa6, 0xbd, 0x7d, 0xf0, 0x09, 0x00, 0x00, 0x00, 0x00, +0x0f, 0x0a, 0x3a, 0x1b, 0x9d, 0x75, 0xdb, 0x54, 0xfa, 0x33, 0xd5, 0x12, 0x7e, 0xe7, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbd, 0xc6, +0xf6, 0x1a, 0xfa, 0x33, 0xdb, 0x5c, 0xbd, 0x7d, 0x3b, 0x3c, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, +0xef, 0x09, 0xf5, 0x01, 0x14, 0x02, 0xd2, 0x01, 0xd2, 0x01, 0xb0, 0x01, 0x5e, 0xe7, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9c, 0xc6, +0xf0, 0x09, 0xd2, 0x01, 0xd2, 0x01, 0x13, 0x02, 0x16, 0x02, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, +0x0e, 0x0a, 0xf6, 0x01, 0x14, 0x02, 0xd2, 0x01, 0xf3, 0x01, 0xf2, 0x01, 0x75, 0x43, 0xfd, 0xce, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xc6, 0x32, 0x12, +0xf2, 0x01, 0xf3, 0x01, 0xd2, 0x01, 0xd2, 0x01, 0x17, 0x02, 0x8e, 0x09, 0x00, 0x00, 0x00, 0x00, +0x6f, 0x12, 0x95, 0x01, 0x77, 0x02, 0xd2, 0x01, 0x13, 0x02, 0x55, 0x02, 0x75, 0x02, 0x74, 0x02, +0x94, 0x02, 0xb5, 0x02, 0xd6, 0x02, 0xf6, 0x02, 0xf6, 0x02, 0xf6, 0x02, 0x17, 0x03, 0xbb, 0x8d, +0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x9e, 0xf7, 0x7c, 0xbe, 0xb4, 0x0a, 0x75, 0x02, +0x55, 0x02, 0xf3, 0x01, 0xd2, 0x01, 0x35, 0x02, 0xf8, 0x01, 0xef, 0x09, 0x00, 0x00, 0x00, 0x00, +0xaf, 0x12, 0x52, 0x01, 0xba, 0x02, 0xf3, 0x01, 0x34, 0x02, 0xb7, 0x02, 0xf8, 0x02, 0x7b, 0x03, +0xbc, 0x03, 0xdc, 0x03, 0xfd, 0x03, 0xfd, 0x03, 0x1d, 0x0c, 0x99, 0x03, 0x9a, 0x8d, 0x3c, 0xe7, +0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x5b, 0xb6, 0x36, 0x0b, 0x39, 0x03, 0xf8, 0x02, +0xb7, 0x02, 0x34, 0x02, 0xd2, 0x01, 0x99, 0x02, 0x97, 0x01, 0x4f, 0x12, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0x6f, 0x01, 0xda, 0x0a, 0x97, 0x02, 0x96, 0x02, 0x19, 0x03, 0x9b, 0x03, 0xfd, 0x03, +0x1d, 0x0c, 0x3d, 0x0c, 0x3d, 0x0c, 0x5d, 0x14, 0x1a, 0x14, 0xd8, 0x5c, 0xba, 0xd6, 0xba, 0xd6, +0xba, 0xd6, 0xdb, 0xd6, 0xdb, 0xde, 0x1a, 0xae, 0x77, 0x13, 0xba, 0x03, 0xfd, 0x03, 0x9b, 0x03, +0x19, 0x03, 0xb7, 0x02, 0x54, 0x02, 0x1b, 0x0b, 0x31, 0x01, 0xcf, 0x12, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0x2f, 0x0a, 0x79, 0x02, 0xdd, 0x0b, 0xf8, 0x02, 0x9b, 0x03, 0xfd, 0x03, 0x3d, 0x0c, +0x7d, 0x14, 0xbd, 0x1c, 0xdd, 0x1c, 0xfe, 0x24, 0x7a, 0x1c, 0x18, 0x6d, 0x79, 0xce, 0x79, 0xce, +0x79, 0xce, 0x79, 0xce, 0xd9, 0xad, 0xd7, 0x23, 0x5b, 0x14, 0x7d, 0x14, 0x3d, 0x0c, 0xfd, 0x03, +0x9b, 0x03, 0x18, 0x03, 0x7b, 0x03, 0x1b, 0x0b, 0xaf, 0x09, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xaf, 0x12, 0x31, 0x01, 0x7d, 0x24, 0xdc, 0x03, 0xfc, 0x03, 0x5d, 0x0c, 0xbd, 0x14, +0x1e, 0x25, 0x3e, 0x2d, 0x7e, 0x35, 0x9e, 0x35, 0xfb, 0x34, 0x17, 0x6d, 0x18, 0xc6, 0x18, 0xc6, +0x18, 0xc6, 0xb8, 0xa5, 0x57, 0x2c, 0xfb, 0x2c, 0x5e, 0x2d, 0x1e, 0x25, 0xbd, 0x14, 0x5d, 0x0c, +0xfd, 0x03, 0x7a, 0x03, 0x9e, 0x24, 0xd6, 0x01, 0x6f, 0x12, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0x0f, 0x0a, 0xba, 0x02, 0x5f, 0x35, 0x5d, 0x0c, 0xbd, 0x14, 0x5e, 0x2d, +0xbe, 0x3d, 0xff, 0x3d, 0x1f, 0x46, 0x3f, 0x46, 0x1e, 0x4e, 0xd7, 0x44, 0xb7, 0xa5, 0xf7, 0xbd, +0x97, 0x95, 0xb7, 0x44, 0x9c, 0x45, 0x1f, 0x46, 0xff, 0x3d, 0xbf, 0x3d, 0x5e, 0x2d, 0xbd, 0x1c, +0x3d, 0x04, 0x1e, 0x25, 0xbc, 0x13, 0xae, 0x09, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x8e, 0x09, 0xfc, 0x1b, 0x3f, 0x4e, 0x3e, 0x25, 0xff, 0x3d, +0x5f, 0x4e, 0x9f, 0x56, 0xbf, 0x5e, 0xdf, 0x66, 0xdf, 0x5e, 0x3c, 0x56, 0x79, 0x4d, 0x17, 0x4d, +0x99, 0x4d, 0x5d, 0x5e, 0xdf, 0x66, 0xbf, 0x5e, 0x9f, 0x56, 0x5f, 0x4e, 0xff, 0x3d, 0x1e, 0x25, +0xdf, 0x3d, 0xfe, 0x34, 0x2f, 0x01, 0xcf, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xcf, 0x12, 0x4f, 0x01, 0xde, 0x34, 0xff, 0x6e, 0x5f, 0x4e, +0xbf, 0x5e, 0x1f, 0x67, 0x3f, 0x6f, 0x5f, 0x6f, 0x5f, 0x6f, 0x5f, 0x77, 0x5f, 0x77, 0x5f, 0x77, +0x5f, 0x77, 0x5f, 0x6f, 0x5f, 0x6f, 0x3f, 0x6f, 0x1f, 0x67, 0xdf, 0x5e, 0x3f, 0x4e, 0xbf, 0x66, +0xdf, 0x4d, 0x72, 0x01, 0xaf, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xaf, 0x12, 0x2f, 0x01, 0xbd, 0x34, 0xbf, 0x8f, +0x5f, 0x77, 0x5f, 0x6f, 0x9f, 0x77, 0x9f, 0x7f, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, 0xbf, 0x87, +0xbf, 0x87, 0xbf, 0x87, 0x9f, 0x7f, 0x7f, 0x7f, 0x5f, 0x6f, 0x3f, 0x6f, 0xbf, 0x87, 0xbf, 0x55, +0x72, 0x01, 0x6f, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xcf, 0x12, 0x6f, 0x01, 0x1d, 0x2c, +0x7f, 0x9f, 0xff, 0xaf, 0xff, 0x97, 0xdf, 0x87, 0xbf, 0x8f, 0xbf, 0x97, 0xbf, 0x9f, 0xbf, 0x9f, +0xbf, 0x97, 0xbf, 0x8f, 0xdf, 0x87, 0xff, 0x8f, 0xff, 0xa7, 0xdf, 0xa7, 0xdd, 0x3c, 0x4f, 0x01, +0x8f, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xce, 0x09, +0x17, 0x02, 0x1e, 0x55, 0x5f, 0xaf, 0xff, 0xcf, 0xff, 0xc7, 0xff, 0xbf, 0xff, 0xb7, 0xff, 0xb7, +0xff, 0xb7, 0xff, 0xc7, 0xff, 0xcf, 0xbf, 0xb7, 0xbe, 0x6d, 0xba, 0x02, 0xae, 0x09, 0xcf, 0x12, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0x8f, 0x12, 0xae, 0x09, 0xd2, 0x01, 0x9b, 0x23, 0x1d, 0x5d, 0x1e, 0x86, 0xbf, 0x9e, 0xdf, 0xa6, +0x5f, 0x8e, 0x7e, 0x6d, 0xfc, 0x2b, 0x16, 0x02, 0x8f, 0x09, 0x4f, 0x12, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xcf, 0x12, 0x4e, 0x12, 0xce, 0x09, 0xaf, 0x09, 0x8f, 0x01, 0x8f, 0x01, +0xaf, 0x09, 0xce, 0x09, 0x2e, 0x12, 0xaf, 0x12, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, +0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0xef, 0x1a, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_16x1x24[] = +{ +0x0c, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 decompressed_16x1x24[] = +{ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_32x32x24[] = +{ +0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x38, 0x8a, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, +0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x1a, 0x87, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, +0x00, 0x80, 0x80, 0x80, 0x1a, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x1d, 0x84, 0xff, 0xff, 0xff, +0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x18, 0x88, 0xc0, 0xc0, 0xc0, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, +0x80, 0x80, 0x80, 0x17, 0x8a, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, +0xc0, 0xc0, 0xc0, 0x1d, 0x83, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x18, 0x89, +0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x16, 0x8a, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x17, 0x8a, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x17, 0x97, 0xff, 0xff, 0xff, +0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xc0, +0xc0, 0xc0, 0x6b, 0xff, 0xff, 0xff, 0x01, 0x95, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x6c, 0xff, 0xff, 0xff, 0x86, 0x80, 0x80, 0x80, 0x80, +0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x6d, 0xff, +0xff, 0xff, 0x01, 0x81, 0xc0, 0xc0, 0xc0, 0x6d, 0xff, 0xff, 0xff, 0x88, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x09, 0x82, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x6f, 0xff, 0xff, 0xff, +0x02, 0x86, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x07, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x0f, 0x91, 0x80, 0x80, +0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, +0x80, 0x0f, 0x81, 0xc0, 0xc0, 0xc0, 0x06, 0x8a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, +0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, +0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x0d, 0x85, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, +0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x06, 0x87, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, +0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x6e, 0xff, +0xff, 0xff, 0x91, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x80, +0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, +0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x6e, 0xff, 0xff, 0xff, 0x85, 0xc0, 0xc0, 0xc0, 0x80, 0x80, +0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x09, 0x83, 0x80, 0x80, 0x00, 0x80, +0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x6f, 0xff, 0xff, 0xff, 0x01, 0x84, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x08, 0x83, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, +0xc0, 0xc0, 0x70, 0xff, 0xff, 0xff, 0x06, 0x81, 0x80, 0x80, 0x80, 0x06, 0x82, 0x80, 0x80, 0x00, +0xc0, 0xc0, 0xc0, 0x71, 0xff, 0xff, 0xff, 0x13, 0x83, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, +0xc0, 0xc0, 0x0e, 0x83, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x06, 0x8a, 0x80, +0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0x16, 0x8a, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x6a, 0xff, 0xff, +0xff, 0x0c, 0x89, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x18, 0x89, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x0a, 0x86, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x6b, +0xff, 0xff, 0xff, 0x01, 0x82, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x6d, 0xff, 0xff, 0xff, 0x04, +0x81, 0xc0, 0xc0, 0xc0, 0x7c, 0xff, 0xff, 0xff, 0x83, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0x60, 0x0e, 0xff, 0xff, 0xff, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff +}; + +uint8 decompressed_32x32x24[] = +{ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x80, 0x80, +0x80, 0xff, 0xff, 0xff, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, +0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, +0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, +0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, +0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, +0x80, 0x80, 0x80, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, +0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, +0xc0, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, +0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, +0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, +0x00, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, +0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, +0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0xc0, +0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, +0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, +0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, +0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, +0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, +0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x00, 0x80, 0x80, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xc0, +0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +uint8 compressed_16x1x32[] = +{ +0x10, 0x01, 0x01, 0x01, 0x01 +}; + +uint8 decompressed_16x1x32[] = +{ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8 compressed_32x32x32[] = +{ +0x10, 0x02, 0x02, 0x0a, 0xbb, 0x22, 0x8e, 0xf6, 0xb9, 0x91, 0x91, 0xa9, 0xf5, 0xaa, 0x3c, 0x00, +0x08, 0xf9, 0x5e, 0xd1, 0x59, 0x8f, 0xf7, 0xb8, 0x90, 0x90, 0xa8, 0xf4, 0xab, 0x59, 0xa3, 0x8c, +0x00, 0x06, 0x67, 0x02, 0xe7, 0x6d, 0xd0, 0x36, 0x00, 0x67, 0x1c, 0xa2, 0x8d, 0xb9, 0x20, 0x00, +0x05, 0x5c, 0x2c, 0x9b, 0xe6, 0x0e, 0x00, 0x46, 0xb8, 0x77, 0x66, 0x00, 0x04, 0x4f, 0x3c, 0x8b, +0x98, 0x00, 0x45, 0x56, 0x8b, 0x84, 0x00, 0x03, 0x4d, 0x20, 0x9b, 0x5e, 0x00, 0x04, 0x44, 0x24, +0xa5, 0x62, 0x00, 0x03, 0x3f, 0xd1, 0x5e, 0x00, 0x04, 0x43, 0x20, 0xb5, 0x1c, 0x00, 0x5f, 0x00, +0x00, 0xdc, 0xb0, 0x00, 0x06, 0x33, 0x52, 0xcf, 0x00, 0x4f, 0x00, 0x30, 0xfd, 0x00, 0x08, 0x50, +0xb2, 0x86, 0x00, 0x00, 0x00, 0x4f, 0x00, 0xb4, 0x20, 0x00, 0x09, 0x40, 0xd4, 0x00, 0x00, 0x00, +0x3f, 0x04, 0xae, 0x00, 0x0a, 0x40, 0x8a, 0x32, 0x00, 0x00, 0x3f, 0x3e, 0x5e, 0x00, 0x0a, 0x40, +0x1a, 0x74, 0x00, 0x00, 0x3f, 0x54, 0x0e, 0x00, 0x0b, 0x30, 0x64, 0x00, 0x00, 0x2f, 0x44, 0x00, +0x0c, 0x30, 0x44, 0x00, 0x00, 0x2f, 0x1c, 0x00, 0x0c, 0x30, 0x1e, 0x00, 0x00, 0x2f, 0x03, 0x00, +0x0c, 0x30, 0x03, 0x00, 0x00, 0x2f, 0x27, 0x00, 0x0c, 0x30, 0x29, 0x00, 0x00, 0x2f, 0x49, 0x00, +0x0c, 0x30, 0x4d, 0x00, 0x00, 0x3f, 0x53, 0x1d, 0x00, 0x0b, 0x30, 0x69, 0x00, 0x00, 0x3f, 0x2b, +0x79, 0x00, 0x0a, 0x40, 0x35, 0x6b, 0x00, 0x00, 0x3f, 0x00, 0xb9, 0x00, 0x0a, 0x40, 0xa5, 0x19, +0x00, 0x00, 0x4f, 0x00, 0x9d, 0x4f, 0x00, 0x08, 0x50, 0x0b, 0xd5, 0x00, 0x00, 0x00, 0x5f, 0x00, +0x0d, 0xf0, 0x01, 0x00, 0x07, 0x50, 0xe9, 0x4b, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x9d, 0xf6, +0x00, 0x06, 0x33, 0xa1, 0xfa, 0x00, 0x03, 0x3f, 0xf1, 0xbf, 0x00, 0x04, 0x43, 0x67, 0xc6, 0x01, +0x00, 0x04, 0x3d, 0xca, 0xc1, 0x00, 0x04, 0x44, 0x6f, 0x9c, 0x21, 0x00, 0x04, 0x4f, 0x07, 0xc4, +0xf4, 0x00, 0x45, 0xbd, 0x8e, 0x31, 0x00, 0x06, 0x4b, 0xf1, 0xaa, 0x5b, 0x00, 0x56, 0x33, 0xd8, +0xc0, 0x1b, 0x00, 0x07, 0x65, 0xa7, 0x6c, 0xae, 0x9d, 0x29, 0x00, 0x68, 0x15, 0x79, 0xde, 0x60, +0xd5, 0x00, 0x08, 0xf9, 0x0d, 0xab, 0xa0, 0x54, 0x7a, 0xc2, 0xec, 0xf0, 0xd0, 0x8e, 0x56, 0x7c, +0xdb, 0x29, 0x00, 0x02, 0x02, 0x19, 0x3a, 0xb9, 0x36, 0x2a, 0x1e, 0x14, 0x10, 0x10, 0x14, 0x1c, +0x26, 0x34, 0x3a, 0x20, 0x00, 0x00, 0x08, 0xf9, 0x09, 0x21, 0x2f, 0x16, 0x98, 0xf6, 0xd1, 0xcd, +0xf9, 0xb4, 0x38, 0x2f, 0x27, 0x0f, 0x00, 0x07, 0xf0, 0x1f, 0x2d, 0x8c, 0xb1, 0xaf, 0xd2, 0x6a, +0x26, 0x20, 0x54, 0xb2, 0xcd, 0x9b, 0xc2, 0x21, 0x37, 0x25, 0x03, 0x00, 0x05, 0xf0, 0x05, 0x27, +0x3e, 0xcb, 0xae, 0x33, 0x85, 0x6f, 0x4b, 0x33, 0x31, 0x45, 0x65, 0x85, 0x53, 0x66, 0x70, 0xbd, +0x6a, 0x2b, 0x0b, 0x00, 0x04, 0xf0, 0x05, 0x29, 0x56, 0xba, 0x4b, 0x75, 0x39, 0x13, 0x17, 0x23, +0x21, 0x21, 0x23, 0x1b, 0x11, 0x85, 0x21, 0x6d, 0x75, 0x8c, 0x98, 0x29, 0x0f, 0x00, 0x03, 0xf0, +0x03, 0x29, 0x62, 0x6e, 0x79, 0x31, 0x11, 0x11, 0x1b, 0x21, 0x1b, 0x25, 0x29, 0x1b, 0x21, 0xa4, +0x1d, 0x1d, 0x0b, 0x17, 0x79, 0x20, 0x98, 0x25, 0x0b, 0x00, 0x03, 0xf0, 0x21, 0x2a, 0x30, 0x8b, +0x19, 0x1b, 0x21, 0x1f, 0x19, 0x1f, 0x39, 0x49, 0x47, 0x49, 0x2d, 0xb3, 0x19, 0x1f, 0x21, 0x1f, +0x11, 0x7b, 0x1d, 0x60, 0x23, 0x03, 0x00, 0xf0, 0x00, 0x00, 0x19, 0x11, 0x2c, 0x87, 0x1d, 0x25, +0x2b, 0x29, 0x2b, 0x31, 0x2d, 0x25, 0xa2, 0xe3, 0xdc, 0x8c, 0x2f, 0x3f, 0x2b, 0x29, 0x29, 0x25, +0x13, 0x71, 0x19, 0x1c, 0x21, 0x00, 0xf0, 0x00, 0x05, 0x1b, 0x42, 0x5d, 0x11, 0x15, 0x29, 0x2b, +0x2b, 0x27, 0x27, 0x2f, 0x4e, 0x46, 0xf0, 0x0e, 0x5c, 0xc8, 0x21, 0x31, 0x29, 0x2d, 0x29, 0x1b, +0x09, 0x47, 0x1c, 0x11, 0x0f, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x00, +0x0f, 0x17, 0x1d, 0x1f, 0x25, 0x23, 0x21, 0x08, 0x12, 0xf0, 0x12, 0x12, 0x50, 0xf2, 0x13, 0x25, +0x1d, 0x17, 0x0f, 0x00, 0x00, 0x3f, 0x16, 0x17, 0x00, 0x20, 0x00, 0x00, 0xf3, 0x00, 0x13, 0x0e, +0x15, 0x00, 0x00, 0x03, 0x0f, 0x15, 0x1b, 0x1d, 0x1f, 0x1b, 0x1f, 0x16, 0xe0, 0x60, 0xe7, 0x05, +0x17, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x05, 0x00, 0x00, 0x43, 0x07, 0x09, 0x0b, 0x00, +0xf0, 0x03, 0x0d, 0x11, 0x13, 0x15, 0x11, 0xaf, 0x9b, 0x1a, 0x1a, 0x1a, 0x18, 0x70, 0xbd, 0x0e, +0x23, 0x03, 0x00, 0x50, 0x11, 0x00, 0x0b, 0x00, 0x00, 0x45, 0x09, 0x00, 0x03, 0x00, 0x83, 0x01, +0x05, 0x09, 0x0f, 0x0b, 0xf2, 0xab, 0x18, 0x45, 0x7a, 0xa3, 0x1c, 0x00, 0x30, 0x0b, 0x00, 0x00, +0x24, 0x05, 0x00, 0xb3, 0x84, 0x63, 0x05, 0x07, 0x09, 0x09, 0x07, 0x09, 0x0b, 0xdc, 0x18, 0x54, +0x1a, 0x86, 0x91, 0x1e, 0x00, 0x30, 0x07, 0x00, 0x00, 0x24, 0x03, 0x00, 0x58, 0xbd, 0x60, 0x02, +0x04, 0x06, 0x73, 0x04, 0x00, 0x00, 0x72, 0x93, 0x18, 0x00, 0x30, 0x03, 0x00, 0x00, 0x8f, 0x00, +0x30, 0xe4, 0xac, 0x66, 0x20, 0x06, 0x00, 0x90, 0x05, 0x1e, 0x64, 0xae, 0xf2, 0x7c, 0x02, 0x00, +0x00, 0x9d, 0x06, 0x60, 0x6c, 0x56, 0x7e, 0x98, 0xdf, 0x4b, 0x00, 0xa0, 0x5d, 0xe3, 0x84, 0x7e, +0x54, 0x5a, 0x7c, 0x04, 0x00, 0x00, 0xf0, 0x08, 0x0a, 0x16, 0x12, 0x0a, 0x16, 0x3b, 0xe2, 0x86, +0x76, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x24, 0xb1, 0x00, 0xb0, 0x53, 0xf9, 0x10, 0x14, 0x0c, 0x10, +0x14, 0x0a, 0x08, 0x00, 0x00, 0xf0, 0x08, 0x0d, 0x18, 0x16, 0x16, 0x14, 0x12, 0x14, 0x0c, 0x10, +0x0c, 0x0e, 0x0a, 0x0c, 0xfb, 0x23, 0xb2, 0x00, 0xc0, 0x53, 0xf8, 0x02, 0x14, 0x14, 0x16, 0x18, +0x1e, 0x07, 0x0c, 0x00, 0x00, 0xf0, 0x06, 0x59, 0x00, 0x20, 0x12, 0x14, 0x18, 0x14, 0x14, 0x0e, +0x0e, 0x0c, 0x10, 0xb0, 0xac, 0x13, 0x00, 0xd0, 0x53, 0xfa, 0x00, 0x14, 0x16, 0x16, 0x12, 0x1c, +0x1c, 0x75, 0x0e, 0x00, 0x00, 0xf3, 0x00, 0x0d, 0x55, 0x34, 0x18, 0x18, 0x16, 0x16, 0x14, 0x12, +0x12, 0x10, 0x12, 0x26, 0x00, 0xe0, 0x53, 0xfd, 0x02, 0x16, 0x18, 0x16, 0x16, 0x18, 0x2c, 0x23, +0x67, 0x02, 0x00, 0x00, 0xf0, 0x00, 0x12, 0xc7, 0x22, 0x26, 0x18, 0x1a, 0x16, 0x16, 0x18, 0x16, +0x16, 0x14, 0x03, 0x00, 0xf0, 0x00, 0x00, 0x4f, 0xf5, 0x00, 0x16, 0x16, 0x16, 0x1a, 0x18, 0x24, +0x3c, 0xa9, 0x14, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x02, 0x39, 0x99, 0x4a, 0x28, 0x1e, 0x22, +0x24, 0x20, 0x1c, 0x1c, 0x1a, 0x63, 0x33, 0xf0, 0x00, 0x57, 0xe7, 0x08, 0x1c, 0x1e, 0x24, 0x24, +0x1e, 0x28, 0x48, 0x4d, 0xb1, 0x08, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x12, 0xe9, 0x59, +0x58, 0x30, 0x2a, 0x2a, 0x2c, 0x2c, 0x28, 0x26, 0x06, 0xf9, 0xe3, 0xf6, 0xd3, 0x12, 0x28, 0x2c, +0x2e, 0x2a, 0x28, 0x30, 0x52, 0x07, 0xc8, 0x1e, 0x00, 0x03, 0xf0, 0x1c, 0xd8, 0x43, 0x58, 0x2a, +0x20, 0x24, 0x26, 0x26, 0x28, 0x26, 0x24, 0x00, 0x26, 0x28, 0xa4, 0x26, 0x28, 0x22, 0x20, 0x2a, +0x4e, 0x08, 0xb8, 0x0c, 0x00, 0x04, 0xf0, 0x1c, 0xb8, 0x5b, 0x5a, 0x36, 0x24, 0x26, 0x28, 0x26, +0x28, 0x2a, 0x2a, 0x28, 0x26, 0x28, 0x94, 0x24, 0x26, 0x34, 0x58, 0x0f, 0xa0, 0x17, 0x04, 0x00, +0x05, 0xf0, 0x1e, 0xc8, 0x91, 0x5a, 0x58, 0x3a, 0x2a, 0x2a, 0x28, 0x24, 0x24, 0x28, 0x2a, 0x2c, +0x36, 0x75, 0x54, 0x6c, 0x5b, 0x8e, 0x13, 0x06, 0x00, 0x06, 0xf0, 0x1c, 0xff, 0xa8, 0x49, 0x48, +0x6c, 0x5e, 0x4e, 0x4a, 0x4a, 0x4e, 0x5a, 0x6a, 0x5a, 0x1d, 0x56, 0xd2, 0xc6, 0x14, 0x04, 0x00, +0x07, 0xf0, 0x14, 0x3b, 0xc8, 0x80, 0xfb, 0x67, 0x17, 0x0e, 0x12, 0x0d, 0x53, 0xd7, 0x90, 0x9a, +0x77, 0x28, 0x18, 0x00, 0x08, 0xf9, 0x02, 0x14, 0x07, 0x95, 0xe6, 0xa6, 0x86, 0x80, 0x9a, 0xd4, +0xbd, 0x25, 0x1a, 0x04, 0x00, 0x02, 0x02, 0x19, 0xbe, 0xb9, 0xb6, 0x98, 0x76, 0x6a, 0x62, 0x62, +0x68, 0x74, 0x8e, 0xb0, 0xbe, 0x20, 0x00, 0x00, 0x08, 0xf9, 0x19, 0x51, 0x45, 0x48, 0xd0, 0xe5, +0xb5, 0xaf, 0xd7, 0xe6, 0x6c, 0x29, 0x5b, 0x23, 0x00, 0x07, 0xf0, 0x4b, 0x23, 0xd6, 0x9d, 0xe1, +0xb8, 0x7a, 0x52, 0x4c, 0x6e, 0xa4, 0xfb, 0x9d, 0xf3, 0x12, 0x37, 0x55, 0x07, 0x00, 0x05, 0xf0, +0x07, 0x5f, 0x92, 0xa3, 0xbc, 0x2c, 0x07, 0x0f, 0x11, 0x13, 0x13, 0x11, 0x0f, 0x09, 0x12, 0x66, +0x90, 0xb5, 0xc8, 0x65, 0x15, 0x00, 0x04, 0xa3, 0x0b, 0x65, 0xca, 0xea, 0x07, 0x2b, 0x1d, 0x0f, +0x05, 0x01, 0xa5, 0x05, 0x0d, 0x1b, 0x29, 0x27, 0xba, 0xe7, 0x4b, 0x1f, 0x00, 0x03, 0xf0, 0x03, +0x5f, 0xe6, 0x96, 0x5b, 0x27, 0x11, 0x15, 0x15, 0x11, 0x13, 0x11, 0x17, 0x13, 0x11, 0xa4, 0x15, +0x13, 0x13, 0x1d, 0x5d, 0x42, 0xe7, 0x43, 0x11, 0x00, 0x03, 0xf0, 0x53, 0xa6, 0x56, 0x75, 0x19, +0x17, 0x1f, 0x1d, 0x1d, 0x1f, 0x49, 0x79, 0x89, 0x71, 0x41, 0xb3, 0x1d, 0x1d, 0x1f, 0x1b, 0x11, +0x65, 0x00, 0xe2, 0x5d, 0x03, 0x00, 0xf0, 0x00, 0x00, 0x35, 0x44, 0x5c, 0x77, 0x1d, 0x23, 0x29, +0x27, 0x27, 0x27, 0x31, 0x5b, 0x0c, 0xe3, 0x32, 0x03, 0x67, 0x4f, 0x27, 0x27, 0x29, 0x25, 0x15, +0x65, 0x0a, 0x9a, 0x4f, 0x00, 0xf0, 0x00, 0x0b, 0x39, 0x72, 0x5f, 0x1b, 0x15, 0x27, 0x27, 0x29, +0x29, 0x29, 0x45, 0x12, 0x1e, 0xf0, 0x0e, 0x26, 0x42, 0x4f, 0x4b, 0x27, 0x27, 0x29, 0x19, 0x0f, +0x67, 0x3e, 0x06, 0x1f, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x23, 0x4a, 0x2b, 0x35, 0x13, 0x15, +0x1d, 0x23, 0x23, 0x29, 0x27, 0x21, 0x00, 0x12, 0xf0, 0x12, 0x12, 0x2a, 0x64, 0x45, 0x3f, 0x23, +0x1b, 0x15, 0x19, 0x1d, 0x4d, 0x54, 0x33, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x01, 0x33, 0x1e, 0x4b, +0x17, 0x1f, 0x1d, 0x13, 0x1b, 0x1d, 0x21, 0x21, 0x1b, 0x11, 0x16, 0xf0, 0x16, 0x16, 0x18, 0x3a, +0x8e, 0x31, 0x2f, 0x13, 0x19, 0x1f, 0x17, 0x47, 0x01, 0x1b, 0x07, 0x20, 0x00, 0x00, 0xf0, 0x09, +0x09, 0x07, 0x29, 0x17, 0x1b, 0x21, 0x21, 0x17, 0x17, 0x15, 0x19, 0x02, 0x4f, 0x4d, 0xf0, 0x1a, +0x1a, 0x18, 0x18, 0x4a, 0xb2, 0x25, 0x31, 0x25, 0x1b, 0x19, 0x19, 0x1d, 0x18, 0x1f, 0x20, 0x00, +0x00, 0xf0, 0x13, 0x12, 0x13, 0x07, 0x0d, 0x17, 0x25, 0x3b, 0x45, 0x49, 0x45, 0x43, 0x45, 0x21, +0x9f, 0x23, 0x5d, 0x18, 0xc0, 0x54, 0xd4, 0x1f, 0x23, 0x17, 0x0f, 0x03, 0x1b, 0x16, 0x15, 0x00, +0x00, 0xf0, 0x1b, 0x16, 0x15, 0x00, 0x01, 0x13, 0x44, 0xe3, 0xa7, 0xaf, 0xb9, 0xbf, 0xc3, 0xc5, +0xc7, 0x23, 0x8e, 0x18, 0xc0, 0x1a, 0x62, 0xfd, 0x0b, 0x11, 0x00, 0x00, 0x13, 0x0a, 0x17, 0x00, +0x00, 0xb8, 0x05, 0x04, 0x02, 0x04, 0x0b, 0x13, 0xf8, 0x46, 0x02, 0x04, 0x06, 0xd0, 0x04, 0x00, +0x00, 0x54, 0xe7, 0x03, 0x0d, 0x04, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x8f, 0x06, 0x4c, 0xde, 0xbc, +0x8c, 0x48, 0x08, 0x00, 0x90, 0x04, 0x42, 0x8a, 0xbc, 0xee, 0x88, 0x04, 0x00, 0x00, 0x9d, 0x0e, +0x4e, 0x50, 0x3e, 0x5e, 0x88, 0x89, 0x2f, 0x00, 0xa0, 0x3b, 0x89, 0x7e, 0x60, 0x3e, 0x40, 0x62, +0x18, 0x00, 0x00, 0xf0, 0x1a, 0x0c, 0x0c, 0x08, 0x02, 0x12, 0x1b, 0xa7, 0xdf, 0xe5, 0xeb, 0xef, +0xf1, 0xf5, 0xf7, 0x24, 0x65, 0x00, 0xb0, 0x31, 0x91, 0x16, 0x10, 0x04, 0x06, 0x08, 0x08, 0x1e, +0x00, 0x00, 0x93, 0x0e, 0x09, 0x10, 0x0c, 0x0c, 0x0a, 0x08, 0x08, 0x04, 0x53, 0x00, 0x02, 0x94, +0x66, 0x00, 0xc0, 0x31, 0x9f, 0x01, 0x0a, 0x0a, 0x0c, 0x0e, 0x16, 0x07, 0x0a, 0x00, 0x00, 0xf0, +0x06, 0x45, 0x03, 0x16, 0x08, 0x08, 0x0a, 0x08, 0x06, 0x02, 0x02, 0x02, 0x06, 0x66, 0x64, 0x13, +0x00, 0x43, 0x33, 0xa3, 0x03, 0x08, 0x60, 0x12, 0x12, 0x59, 0x14, 0x00, 0x00, 0xf3, 0x00, 0x21, +0x41, 0x28, 0x0c, 0x0c, 0x0c, 0x0a, 0x08, 0x08, 0x06, 0x04, 0x02, 0x12, 0x00, 0xe0, 0x33, 0x9d, +0x01, 0x08, 0x0c, 0x0c, 0x0c, 0x0e, 0x20, 0x19, 0x55, 0x02, 0x00, 0x00, 0xf0, 0x00, 0x0a, 0x9b, +0x1c, 0x1e, 0x10, 0x0e, 0x0a, 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x05, 0x00, 0xf0, 0x00, 0x00, 0x31, +0x9b, 0x05, 0x0a, 0x0a, 0x0a, 0x10, 0x0e, 0x1a, 0x2e, 0x7f, 0x09, 0x00, 0x20, 0x00, 0x00, 0xf0, +0x00, 0x04, 0x39, 0x71, 0x36, 0x18, 0x12, 0x14, 0x14, 0x10, 0x10, 0x0e, 0x0a, 0x41, 0x21, 0xf0, +0x00, 0x37, 0x97, 0x00, 0x10, 0x0e, 0x14, 0x14, 0x10, 0x18, 0x34, 0x37, 0x89, 0x0a, 0x00, 0x20, +0x00, 0x00, 0xf0, 0x00, 0x00, 0x0a, 0xb7, 0x3b, 0x42, 0x1c, 0x16, 0x16, 0x16, 0x14, 0x12, 0x10, +0x03, 0xa7, 0xe3, 0xb1, 0x8f, 0x04, 0x12, 0x14, 0x18, 0x16, 0x16, 0x1c, 0x3c, 0x01, 0xe3, 0x04, +0x00, 0x03, 0xf0, 0x0a, 0xdd, 0x29, 0x42, 0x1c, 0x12, 0x14, 0x14, 0x14, 0x16, 0x14, 0x12, 0x05, +0x14, 0x16, 0xa4, 0x14, 0x16, 0x12, 0x12, 0x1c, 0x3a, 0x0e, 0xef, 0x09, 0x00, 0x04, 0xf0, 0x06, +0xf5, 0x35, 0x44, 0x28, 0x18, 0x18, 0x18, 0x16, 0x16, 0x1a, 0x1a, 0x16, 0x16, 0x18, 0x85, 0x16, +0x1a, 0x24, 0x40, 0x01, 0xfd, 0x25, 0x00, 0x05, 0xf0, 0x0c, 0xed, 0x5d, 0x44, 0x42, 0x2a, 0x20, +0x1c, 0x1c, 0x16, 0x16, 0x1c, 0x1c, 0x20, 0x26, 0x75, 0x3e, 0x52, 0x37, 0xf4, 0x1d, 0x08, 0x00, +0x06, 0xf0, 0x10, 0xcb, 0xef, 0x2b, 0x38, 0x4e, 0x46, 0x38, 0x36, 0x36, 0x38, 0x44, 0x4c, 0x44, +0x0d, 0x56, 0xcf, 0xed, 0x02, 0x02, 0x00, 0x07, 0xf0, 0x14, 0x37, 0xed, 0xf8, 0xa9, 0x41, 0x0b, +0x0e, 0x10, 0x03, 0x33, 0x8f, 0xf9, 0xfc, 0x65, 0x28, 0x12, 0x00, 0x08, 0xf9, 0x04, 0x14, 0x11, +0x77, 0xd5, 0xff, 0xf2, 0xf2, 0xfa, 0xe3, 0x95, 0x27, 0x10, 0x08, 0x00, 0x02, 0x02, 0x19, 0xf4, +0xb9, 0xf2, 0xec, 0xe0, 0xf0, 0xfc, 0xfc, 0xf6, 0xe8, 0xea, 0xf2, 0xf4, 0x20, 0x00, 0x00, 0x08, +0xf9, 0x01, 0x07, 0x3c, 0xd0, 0xfe, 0xfe, 0xfa, 0xfa, 0xfc, 0xfe, 0xde, 0x74, 0x03, 0x03, 0x00, +0x07, 0xf0, 0x09, 0x7e, 0xf6, 0xd0, 0x42, 0x20, 0x10, 0x08, 0x08, 0x0c, 0x18, 0x36, 0x98, 0xfe, +0xbe, 0x37, 0x09, 0x01, 0x00, 0x05, 0xf0, 0x01, 0x05, 0xe6, 0x8e, 0x1c, 0x00, 0x00, 0x00, 0x01, +0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x66, 0x10, 0x50, 0xf4, 0x06, 0x01, 0x00, 0x04, 0x54, 0x01, +0x03, 0xf0, 0x2e, 0x00, 0x54, 0x02, 0x04, 0x04, 0x02, 0x00, 0x55, 0x20, 0xf8, 0x36, 0x05, 0x00, +0x03, 0x66, 0x02, 0x03, 0xf4, 0x20, 0x01, 0x00, 0x25, 0x05, 0x00, 0x64, 0x03, 0x0e, 0xca, 0x3c, +0x02, 0x00, 0x03, 0xf0, 0x0b, 0xdc, 0x18, 0x11, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x33, 0x6b, +0x81, 0x5f, 0x27, 0xa4, 0x00, 0x00, 0x00, 0x03, 0x07, 0x15, 0x02, 0xba, 0x01, 0x00, 0xf0, 0x00, +0x00, 0x05, 0xb8, 0x26, 0x1d, 0x0f, 0x09, 0x0b, 0x07, 0x07, 0x05, 0x0f, 0x51, 0x19, 0xe3, 0x02, +0x25, 0x5d, 0x37, 0x07, 0x09, 0x07, 0x07, 0x09, 0x19, 0x0a, 0xcc, 0x05, 0x00, 0xf0, 0x00, 0x01, +0x22, 0x3c, 0x21, 0x11, 0x01, 0x0b, 0x09, 0x0d, 0x0b, 0x0b, 0x35, 0x02, 0x0e, 0xf0, 0x0e, 0x0e, +0x0a, 0x51, 0x3b, 0x0d, 0x0d, 0x0b, 0x03, 0x09, 0x41, 0x26, 0x74, 0x03, 0x00, 0x20, 0x00, 0x00, +0xf0, 0x00, 0x06, 0x8c, 0x0d, 0x43, 0x15, 0x07, 0x05, 0x07, 0x07, 0x0b, 0x09, 0x0b, 0x0a, 0x12, +0xf0, 0x12, 0x12, 0x16, 0x1c, 0x49, 0x31, 0x07, 0x05, 0x07, 0x1b, 0x23, 0x27, 0x4e, 0x02, 0x00, +0x20, 0x00, 0x00, 0xf0, 0x00, 0x02, 0x10, 0x59, 0x1f, 0x1f, 0x19, 0x05, 0x07, 0x05, 0x05, 0x07, +0x02, 0x04, 0x16, 0xf0, 0x16, 0x16, 0x18, 0x20, 0x32, 0x43, 0x2f, 0x05, 0x15, 0x1f, 0x15, 0x71, +0x02, 0x22, 0x02, 0x20, 0x00, 0x00, 0xf0, 0x02, 0x30, 0x07, 0x43, 0x1d, 0x1d, 0x29, 0x1f, 0x0d, +0x09, 0x07, 0x07, 0x26, 0x10, 0x09, 0xf0, 0x1a, 0x1a, 0x18, 0x18, 0x28, 0x46, 0x3d, 0x41, 0x31, +0x1d, 0x23, 0x21, 0x21, 0x5e, 0x05, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x30, 0x2b, 0x0b, 0x13, 0x23, +0x3b, 0x67, 0x77, 0x77, 0x6d, 0x67, 0x65, 0x29, 0x33, 0x23, 0x15, 0x18, 0xc0, 0x2e, 0x54, 0x49, +0x35, 0x23, 0x1b, 0x00, 0x3d, 0x10, 0x08, 0x00, 0x00, 0xf0, 0x0b, 0x10, 0x31, 0x01, 0x07, 0x2b, +0x01, 0x8c, 0xae, 0xa4, 0x96, 0x8e, 0x8a, 0x8a, 0x88, 0x23, 0x46, 0x18, 0xc0, 0x1a, 0x3c, 0x88, +0x31, 0x25, 0x00, 0x00, 0x27, 0x09, 0x09, 0x00, 0x00, 0xb8, 0x06, 0x11, 0x00, 0x02, 0x05, 0x21, +0x94, 0x28, 0x02, 0x04, 0x06, 0xd0, 0x04, 0x00, 0x00, 0x30, 0xa6, 0x21, 0x09, 0x03, 0x10, 0x15, +0x0a, 0x00, 0x00, 0x8f, 0x06, 0x48, 0x8c, 0x94, 0x82, 0x5a, 0x0a, 0x00, 0x90, 0x0e, 0x56, 0x7e, +0x94, 0x9a, 0x56, 0x0a, 0x00, 0x00, 0x9d, 0x06, 0x18, 0x1c, 0x16, 0x1e, 0x56, 0x33, 0x11, 0x00, +0xa0, 0x15, 0x31, 0x5a, 0x24, 0x16, 0x16, 0x20, 0x08, 0x00, 0x00, 0xf0, 0x04, 0x04, 0x02, 0x00, +0x01, 0x10, 0x08, 0x2b, 0x39, 0x39, 0x39, 0x37, 0x33, 0x33, 0x35, 0x24, 0x15, 0x00, 0xb0, 0x0b, +0x25, 0x1e, 0x0a, 0x01, 0x01, 0x00, 0x02, 0x08, 0x00, 0x00, 0xf0, 0x07, 0x0f, 0x04, 0x04, 0x02, +0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x01, 0x07, 0x05, 0x1e, 0x23, 0x16, 0x00, 0xc0, 0x0b, 0x2f, +0x01, 0x01, 0x00, 0x02, 0x04, 0x06, 0x05, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x3b, 0x01, 0x08, 0x00, +0x00, 0x02, 0x00, 0x01, 0x07, 0x05, 0x05, 0x01, 0x14, 0x18, 0x13, 0x00, 0xd0, 0x0d, 0x31, 0x05, +0x01, 0x00, 0x00, 0x00, 0x08, 0x08, 0x2f, 0x07, 0x00, 0x00, 0xf3, 0x00, 0x57, 0x15, 0x10, 0x04, +0x04, 0x02, 0x01, 0x00, 0x01, 0x01, 0x03, 0x05, 0x04, 0x00, 0xe0, 0x0f, 0x31, 0x03, 0x00, 0x02, +0x02, 0x04, 0x06, 0x0c, 0x09, 0x4d, 0x05, 0x00, 0x00, 0xf0, 0x00, 0x21, 0x51, 0x0a, 0x0c, 0x02, +0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0xf0, 0x00, 0x00, 0x0f, 0x2f, 0x05, 0x01, +0x01, 0x01, 0x02, 0x00, 0x08, 0x12, 0x31, 0x57, 0x00, 0x20, 0x00, 0x00, 0xf0, 0x00, 0x01, 0x73, +0x25, 0x16, 0x0a, 0x04, 0x02, 0x04, 0x00, 0x00, 0x01, 0x00, 0x17, 0x09, 0xf0, 0x00, 0x11, 0x2f, +0x05, 0x00, 0x01, 0x04, 0x04, 0x04, 0x0c, 0x16, 0x13, 0x71, 0x09, 0x00, 0x20, 0x00, 0x00, 0xf0, +0x00, 0x00, 0x21, 0x97, 0x13, 0x1a, 0x0c, 0x08, 0x04, 0x04, 0x02, 0x00, 0x03, 0x07, 0x3d, 0xe3, +0x3f, 0x35, 0x07, 0x00, 0x02, 0x06, 0x04, 0x08, 0x0a, 0x18, 0x00, 0x79, 0x55, 0x00, 0x03, 0xf0, +0x43, 0x81, 0x0d, 0x1a, 0x0c, 0x06, 0x06, 0x04, 0x02, 0x04, 0x04, 0x02, 0x05, 0x04, 0x04, 0xa4, +0x02, 0x08, 0x02, 0x04, 0x0a, 0x18, 0x04, 0x6d, 0x6d, 0x00, 0x04, 0xf0, 0x65, 0x8d, 0x0d, 0x1a, +0x10, 0x0a, 0x0a, 0x0a, 0x06, 0x04, 0x08, 0x08, 0x04, 0x06, 0x0a, 0x94, 0x06, 0x0c, 0x12, 0x1a, +0x02, 0x73, 0x85, 0x07, 0x00, 0x05, 0xf0, 0x5d, 0xaf, 0x1d, 0x1a, 0x1a, 0x12, 0x0c, 0x0c, 0x0c, +0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x10, 0x75, 0x1a, 0x20, 0x0f, 0x91, 0x83, 0x05, 0x00, 0x06, 0xf0, +0x3b, 0xc3, 0x6d, 0x0b, 0x16, 0x20, 0x1c, 0x16, 0x18, 0x18, 0x16, 0x1a, 0x20, 0x1c, 0x00, 0x56, +0x57, 0xbb, 0x65, 0x03, 0x00, 0x07, 0xf0, 0x17, 0x8d, 0xcf, 0x87, 0x43, 0x11, 0x02, 0x08, 0x0a, +0x04, 0x0d, 0x35, 0x79, 0xbf, 0xa7, 0x28, 0x2d, 0x00, 0x08, 0xf9, 0x01, 0x17, 0x73, 0xb5, 0xd5, +0xcf, 0xb5, 0xb3, 0xc7, 0xd3, 0xc1, 0x85, 0x31, 0x03, 0x00 +}; + +uint8 decompressed_32x32x32[] = +{ +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7b, 0x5c, 0x1b, 0x14, +0x80, 0x57, 0x16, 0x3c, 0x89, 0x54, 0x12, 0x60, 0x98, 0x56, 0x10, 0x75, 0x9a, 0x57, 0x0f, 0x77, +0x8e, 0x55, 0x11, 0x67, 0x82, 0x56, 0x15, 0x46, 0x7c, 0x59, 0x19, 0x1f, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7b, 0x5d, 0x1c, 0x07, 0x86, 0x55, 0x13, 0x56, 0xb4, 0x68, 0x21, 0xb0, 0xd6, 0x98, 0x66, 0xea, +0xeb, 0xc2, 0xa3, 0xff, 0xf1, 0xd4, 0xbf, 0xff, 0xf3, 0xdd, 0xcd, 0xff, 0xf4, 0xde, 0xcf, 0xff, +0xf2, 0xd8, 0xc4, 0xff, 0xec, 0xc8, 0xab, 0xff, 0xdd, 0xa4, 0x78, 0xf4, 0xbd, 0x73, 0x30, 0xc2, +0x93, 0x57, 0x10, 0x6e, 0x7c, 0x5b, 0x1b, 0x15, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x86, 0x55, 0x13, 0x54, +0xc2, 0x79, 0x3a, 0xd1, 0xee, 0xcc, 0xaf, 0xff, 0xf8, 0xec, 0xe1, 0xff, 0xf8, 0xed, 0xe4, 0xff, +0xf4, 0xe3, 0xd7, 0xff, 0xf0, 0xda, 0xcb, 0xff, 0xef, 0xd6, 0xc6, 0xff, 0xef, 0xd6, 0xc6, 0xff, +0xf0, 0xda, 0xcb, 0xff, 0xf3, 0xe2, 0xd5, 0xff, 0xf8, 0xec, 0xe4, 0xff, 0xfa, 0xf0, 0xe8, 0xff, +0xf3, 0xd9, 0xc3, 0xff, 0xd0, 0x8e, 0x57, 0xe5, 0x91, 0x56, 0x11, 0x6b, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x98, 0x57, 0x0f, 0x79, 0xe8, 0xbb, 0x93, 0xff, +0xf9, 0xf1, 0xe6, 0xff, 0xf4, 0xe2, 0xd4, 0xff, 0xed, 0xd0, 0xbd, 0xff, 0xe8, 0xc6, 0xae, 0xff, +0xe6, 0xc0, 0xa8, 0xff, 0xe5, 0xbe, 0xa4, 0xff, 0xe3, 0xbb, 0xa1, 0xff, 0xe3, 0xbb, 0xa1, 0xff, +0xe5, 0xbe, 0xa4, 0xff, 0xe6, 0xc0, 0xa8, 0xff, 0xe8, 0xc6, 0xaf, 0xff, 0xec, 0xce, 0xbb, 0xff, +0xf3, 0xe0, 0xd2, 0xff, 0xfc, 0xf6, 0xee, 0xff, 0xef, 0xcd, 0xae, 0xff, 0xad, 0x5e, 0x13, 0xa0, +0x7c, 0x5e, 0x1b, 0x0e, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x04, 0xa9, 0x59, 0x0e, 0x9e, 0xf0, 0xce, 0xab, 0xff, 0xf7, 0xea, 0xdc, 0xff, +0xec, 0xcf, 0xb9, 0xff, 0xe7, 0xc1, 0xa8, 0xff, 0xe4, 0xbb, 0xa0, 0xff, 0xe2, 0xb6, 0x99, 0xff, +0xe0, 0xb2, 0x93, 0xff, 0xdf, 0xb0, 0x90, 0xff, 0xe0, 0xb0, 0x8f, 0xff, 0xe0, 0xb0, 0x8f, 0xff, +0xdf, 0xb0, 0x90, 0xff, 0xe0, 0xb2, 0x93, 0xff, 0xe2, 0xb6, 0x99, 0xff, 0xe4, 0xbb, 0xa0, 0xff, +0xe6, 0xc1, 0xa8, 0xff, 0xec, 0xcd, 0xb8, 0xff, 0xf7, 0xe9, 0xdc, 0xff, 0xf6, 0xe4, 0xcc, 0xff, +0xbe, 0x6d, 0x25, 0xc7, 0x7d, 0x5b, 0x1a, 0x19, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0xad, 0x5c, 0x0f, 0x9f, 0xf0, 0xd4, 0xb2, 0xff, 0xf7, 0xe9, 0xd9, 0xff, 0xea, 0xc8, 0xaf, 0xff, +0xe4, 0xbb, 0x9e, 0xff, 0xe2, 0xb5, 0x96, 0xff, 0xdf, 0xaf, 0x8d, 0xff, 0xdd, 0xaa, 0x85, 0xff, +0xdd, 0xa7, 0x80, 0xff, 0xdd, 0xa5, 0x7c, 0xff, 0xdc, 0xa3, 0x7a, 0xff, 0xdc, 0xa3, 0x7a, 0xff, +0xdd, 0xa5, 0x7c, 0xff, 0xdd, 0xa7, 0x80, 0xff, 0xdd, 0xaa, 0x85, 0xff, 0xe1, 0xb0, 0x8e, 0xff, +0xe0, 0xb4, 0x95, 0xff, 0xe3, 0xbb, 0x9e, 0xff, 0xea, 0xc9, 0xb0, 0xff, 0xf5, 0xe5, 0xd4, 0xff, +0xf8, 0xec, 0xd5, 0xff, 0xc0, 0x6e, 0x26, 0xcb, 0x7e, 0x5f, 0x1b, 0x11, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x9c, 0x5a, 0x0f, 0x79, +0xee, 0xcb, 0xa3, 0xff, 0xf7, 0xe9, 0xd4, 0xff, 0xea, 0xc8, 0xad, 0xff, 0xe4, 0xba, 0x9a, 0xff, +0xe1, 0xb2, 0x8e, 0xff, 0xdf, 0xab, 0x84, 0xff, 0xdd, 0xa5, 0x7a, 0xff, 0xdc, 0xa0, 0x72, 0xff, +0xdb, 0x9c, 0x6c, 0xff, 0xdb, 0x9b, 0x69, 0xff, 0xdb, 0x9a, 0x68, 0xff, 0xdf, 0xa6, 0x7a, 0xff, +0xdb, 0x9b, 0x69, 0xff, 0xdb, 0x9c, 0x6c, 0xff, 0xdc, 0xa0, 0x72, 0xff, 0xdd, 0xa5, 0x7a, 0xff, +0xdf, 0xab, 0x84, 0xff, 0xe1, 0xb2, 0x8e, 0xff, 0xe5, 0xbb, 0x9b, 0xff, 0xe9, 0xc8, 0xad, 0xff, +0xf6, 0xe5, 0xd1, 0xff, 0xf7, 0xe6, 0xca, 0xff, 0xb5, 0x64, 0x15, 0xae, 0x7a, 0x5f, 0x1d, 0x01, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x8b, 0x5a, 0x14, 0x4f, 0xe8, 0xb6, 0x84, 0xfe, +0xf8, 0xe9, 0xd0, 0xff, 0xea, 0xc8, 0xa8, 0xff, 0xe4, 0xba, 0x95, 0xff, 0xe0, 0xaf, 0x85, 0xff, +0xdf, 0xa7, 0x79, 0xff, 0xdd, 0xa0, 0x6e, 0xff, 0xdc, 0x9b, 0x64, 0xff, 0xdc, 0x97, 0x5e, 0xff, +0xdd, 0x94, 0x59, 0xff, 0xdf, 0x9d, 0x66, 0xff, 0xfa, 0xee, 0xe5, 0xff, 0xff, 0xff, 0xff, 0xff, +0xf6, 0xe3, 0xd3, 0xff, 0xdf, 0x9a, 0x63, 0xff, 0xdc, 0x97, 0x5e, 0xff, 0xdc, 0x9b, 0x64, 0xff, +0xdc, 0x9f, 0x6d, 0xff, 0xdf, 0xa7, 0x79, 0xff, 0xe1, 0xb0, 0x87, 0xff, 0xe4, 0xba, 0x95, 0xff, +0xea, 0xc7, 0xa8, 0xff, 0xf7, 0xe7, 0xce, 0xff, 0xf2, 0xd6, 0xb1, 0xff, 0xa5, 0x5d, 0x0e, 0x84, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7b, 0x5d, 0x1c, 0x07, 0xc5, 0x77, 0x31, 0xd7, 0xfb, 0xef, 0xd1, 0xff, +0xed, 0xce, 0xab, 0xff, 0xe5, 0xbc, 0x94, 0xff, 0xe2, 0xb1, 0x86, 0xff, 0xdf, 0xa5, 0x74, 0xff, +0xdd, 0x9d, 0x67, 0xff, 0xdd, 0x98, 0x5e, 0xff, 0xdc, 0x93, 0x56, 0xff, 0xdd, 0x90, 0x50, 0xff, +0xdd, 0x8f, 0x4c, 0xff, 0xeb, 0xbe, 0x98, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xf7, 0xe6, 0xd7, 0xff, 0xdf, 0x97, 0x5a, 0xff, 0xdc, 0x93, 0x56, 0xff, +0xdd, 0x98, 0x5e, 0xff, 0xdd, 0x9d, 0x67, 0xff, 0xdf, 0xa6, 0x75, 0xff, 0xe2, 0xb2, 0x86, 0xff, +0xe4, 0xbb, 0x94, 0xff, 0xec, 0xcd, 0xaa, 0xff, 0xfc, 0xf2, 0xd8, 0xff, 0xde, 0xa2, 0x67, 0xf9, +0x7f, 0x5a, 0x19, 0x26, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x8c, 0x58, 0x13, 0x56, 0xee, 0xc5, 0x95, 0xff, 0xf6, 0xe1, 0xc0, 0xff, +0xe7, 0xbf, 0x98, 0xff, 0xe4, 0xb4, 0x88, 0xff, 0xe1, 0xaa, 0x79, 0xff, 0xdf, 0xa0, 0x69, 0xff, +0xde, 0x98, 0x5c, 0xff, 0xdd, 0x93, 0x52, 0xff, 0xdd, 0x8f, 0x4b, 0xff, 0xdd, 0x8c, 0x45, 0xff, +0xdd, 0x8a, 0x42, 0xff, 0xee, 0xc1, 0x9a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xe5, 0xd5, 0xff, 0xdf, 0x96, 0x56, 0xff, +0xde, 0x93, 0x53, 0xff, 0xde, 0x98, 0x5c, 0xff, 0xe0, 0xa1, 0x6a, 0xff, 0xe1, 0xaa, 0x79, 0xff, +0xe4, 0xb4, 0x88, 0xff, 0xe8, 0xc0, 0x98, 0xff, 0xf3, 0xdb, 0xba, 0xff, 0xf7, 0xe2, 0xbc, 0xff, +0xab, 0x5f, 0x0f, 0x91, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0xb8, 0x69, 0x1a, 0xb3, 0xf9, 0xe6, 0xc0, 0xff, 0xee, 0xcd, 0xa6, 0xff, +0xe5, 0xb9, 0x8c, 0xff, 0xe2, 0xae, 0x7c, 0xff, 0xe0, 0xa4, 0x6e, 0xff, 0xe0, 0x9b, 0x5e, 0xff, +0xde, 0x94, 0x52, 0xff, 0xde, 0x8f, 0x49, 0xff, 0xde, 0x8c, 0x42, 0xff, 0xdf, 0x8a, 0x3d, 0xff, +0xe0, 0x89, 0x39, 0xff, 0xec, 0xb8, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xe5, 0xd5, 0xff, +0xe0, 0x94, 0x52, 0xff, 0xde, 0x94, 0x51, 0xff, 0xdf, 0x9b, 0x5e, 0xff, 0xe0, 0xa4, 0x6e, 0xff, +0xe2, 0xae, 0x7d, 0xff, 0xe5, 0xb9, 0x8c, 0xff, 0xed, 0xcb, 0xa4, 0xff, 0xfc, 0xef, 0xce, 0xff, +0xd2, 0x8a, 0x43, 0xe4, 0x7d, 0x5e, 0x1c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7c, 0x5c, 0x1a, 0x16, 0xd6, 0x8c, 0x47, 0xf0, 0xfa, 0xe8, 0xc0, 0xff, 0xea, 0xc2, 0x96, 0xff, +0xe5, 0xb5, 0x83, 0xff, 0xe2, 0xaa, 0x72, 0xff, 0xdf, 0x9f, 0x62, 0xff, 0xe0, 0x97, 0x54, 0xff, +0xdf, 0x91, 0x48, 0xff, 0xe2, 0x8e, 0x42, 0xff, 0xe1, 0x8b, 0x3b, 0xff, 0xe2, 0x89, 0x37, 0xff, +0xe1, 0x86, 0x31, 0xff, 0xe2, 0x85, 0x2f, 0xff, 0xf3, 0xcd, 0xa9, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xf9, 0xe6, 0xd5, 0xff, 0xe1, 0x96, 0x51, 0xff, 0xe0, 0x97, 0x54, 0xff, 0xe0, 0xa0, 0x63, 0xff, +0xe2, 0xaa, 0x72, 0xff, 0xe5, 0xb5, 0x83, 0xff, 0xe9, 0xc2, 0x96, 0xff, 0xf8, 0xe6, 0xc0, 0xff, +0xea, 0xb7, 0x7e, 0xff, 0x81, 0x54, 0x15, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x80, 0x55, 0x16, 0x40, 0xde, 0x91, 0x4e, 0xff, 0xf8, 0xe0, 0xb4, 0xff, 0xe8, 0xbc, 0x8b, 0xff, +0xe4, 0xaf, 0x78, 0xff, 0xe2, 0xa5, 0x68, 0xff, 0xe1, 0x9b, 0x59, 0xff, 0xe0, 0x93, 0x4a, 0xff, +0xe2, 0x8f, 0x42, 0xff, 0xe2, 0x8c, 0x3a, 0xff, 0xe2, 0x89, 0x35, 0xff, 0xe3, 0x87, 0x30, 0xff, +0xe5, 0x86, 0x2c, 0xff, 0xe5, 0x84, 0x29, 0xff, 0xe4, 0x83, 0x27, 0xff, 0xf4, 0xcc, 0xa6, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xf9, 0xe6, 0xd5, 0xff, 0xe1, 0x98, 0x53, 0xff, 0xe1, 0x9b, 0x59, 0xff, +0xe2, 0xa5, 0x68, 0xff, 0xe4, 0xaf, 0x78, 0xff, 0xe7, 0xbb, 0x8a, 0xff, 0xf5, 0xdb, 0xb1, 0xff, +0xed, 0xbb, 0x82, 0xff, 0x89, 0x4f, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7e, 0x48, 0x12, 0x65, 0xdc, 0x8b, 0x49, 0xff, 0xf7, 0xda, 0xa9, 0xff, 0xe8, 0xb8, 0x82, 0xff, +0xe5, 0xae, 0x73, 0xff, 0xda, 0x9c, 0x5d, 0xff, 0xdd, 0xa9, 0x77, 0xff, 0xf6, 0xe7, 0xd9, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xe1, 0xd0, 0xff, 0xd2, 0x90, 0x51, 0xff, +0xdd, 0x9d, 0x5e, 0xff, 0xe5, 0xad, 0x72, 0xff, 0xe8, 0xb8, 0x82, 0xff, 0xf5, 0xd7, 0xa7, 0xff, +0xec, 0xb7, 0x7d, 0xff, 0x85, 0x40, 0x0b, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7b, 0x41, 0x0f, 0x79, 0xd0, 0x64, 0x19, 0xff, 0xe9, 0xb2, 0x73, 0xff, 0xdd, 0x99, 0x57, 0xff, +0xd6, 0x7f, 0x34, 0xff, 0xaf, 0x58, 0x11, 0xff, 0xf7, 0xee, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, 0xd5, 0xc3, 0xff, +0xb0, 0x5e, 0x1c, 0xff, 0xd3, 0x7d, 0x33, 0xff, 0xdd, 0x99, 0x58, 0xff, 0xea, 0xb7, 0x7a, 0xff, +0xdc, 0x86, 0x3f, 0xff, 0x81, 0x34, 0x09, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x78, 0x3e, 0x0f, 0x7b, 0xac, 0x3e, 0x01, 0xff, 0xa3, 0x43, 0x01, 0xff, 0x93, 0x3b, 0x01, 0xff, +0x95, 0x39, 0x01, 0xff, 0x82, 0x34, 0x01, 0xff, 0xf2, 0xea, 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe4, 0xd3, 0xc6, 0xff, +0x85, 0x3d, 0x0d, 0xff, 0x94, 0x38, 0x01, 0xff, 0x93, 0x3b, 0x01, 0xff, 0x9d, 0x40, 0x01, 0xff, +0xb1, 0x42, 0x01, 0xff, 0x7c, 0x32, 0x08, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x75, 0x41, 0x11, 0x6d, 0xb5, 0x3c, 0x01, 0xff, 0xa3, 0x42, 0x01, 0xff, 0x92, 0x39, 0x01, 0xff, +0x98, 0x3f, 0x01, 0xff, 0x93, 0x3e, 0x01, 0xff, 0xa8, 0x6e, 0x43, 0xff, 0xeb, 0xdc, 0xcf, 0xff, +0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfd, 0xfd, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, +0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, +0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfc, 0xfc, 0xfc, 0xff, 0xfd, 0xfd, 0xfd, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xd5, 0xc6, 0xff, 0x91, 0x47, 0x10, 0xff, +0x96, 0x3f, 0x01, 0xff, 0x99, 0x3f, 0x01, 0xff, 0x95, 0x39, 0x01, 0xff, 0x95, 0x3a, 0x01, 0xff, +0xbc, 0x43, 0x01, 0xff, 0x77, 0x34, 0x0a, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7b, 0x4f, 0x14, 0x4b, 0xad, 0x31, 0x01, 0xff, 0xbc, 0x4d, 0x01, 0xff, 0x93, 0x39, 0x01, 0xff, +0x9c, 0x40, 0x01, 0xff, 0xa9, 0x48, 0x01, 0xff, 0xa9, 0x4c, 0x01, 0xff, 0xa5, 0x4e, 0x01, 0xff, +0xa7, 0x52, 0x01, 0xff, 0xab, 0x55, 0x01, 0xff, 0xb1, 0x59, 0x01, 0xff, 0xb5, 0x5c, 0x01, 0xff, +0xb7, 0x5e, 0x00, 0xff, 0xb7, 0x5f, 0x01, 0xff, 0xb8, 0x60, 0x02, 0xff, 0xd9, 0xb5, 0x8e, 0xff, +0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf0, 0xf0, 0xf0, 0xff, 0xf1, 0xf1, 0xf1, 0xff, +0xf2, 0xf2, 0xf2, 0xff, 0xe1, 0xce, 0xbc, 0xff, 0xa3, 0x54, 0x0f, 0xff, 0xaa, 0x4d, 0x01, 0xff, +0xa9, 0x48, 0x01, 0xff, 0x99, 0x3f, 0x01, 0xff, 0x95, 0x39, 0x01, 0xff, 0xa9, 0x44, 0x01, 0xff, +0xc1, 0x3e, 0x01, 0xff, 0x7c, 0x40, 0x0e, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7b, 0x59, 0x19, 0x21, 0x95, 0x28, 0x01, 0xf8, 0xd2, 0x57, 0x03, 0xff, 0x99, 0x3d, 0x01, 0xff, +0xa6, 0x47, 0x01, 0xff, 0xbb, 0x54, 0x01, 0xff, 0xc7, 0x5f, 0x01, 0xff, 0xd9, 0x6c, 0x01, 0xff, +0xe3, 0x75, 0x01, 0xff, 0xe7, 0x7a, 0x02, 0xff, 0xe8, 0x7c, 0x04, 0xff, 0xe9, 0x7e, 0x06, 0xff, +0xea, 0x81, 0x08, 0xff, 0xcc, 0x70, 0x07, 0xff, 0xd2, 0xb0, 0x89, 0xff, 0xe4, 0xe4, 0xe4, 0xff, +0xe4, 0xe4, 0xe4, 0xff, 0xe4, 0xe4, 0xe4, 0xff, 0xe4, 0xe4, 0xe4, 0xff, 0xe5, 0xe5, 0xe5, 0xff, +0xdb, 0xc8, 0xb5, 0xff, 0xb7, 0x64, 0x0e, 0xff, 0xc8, 0x64, 0x01, 0xff, 0xc5, 0x5f, 0x01, 0xff, +0xbb, 0x54, 0x01, 0xff, 0xa7, 0x47, 0x01, 0xff, 0x95, 0x3b, 0x01, 0xff, 0xc8, 0x52, 0x01, 0xff, +0xb9, 0x33, 0x01, 0xff, 0x78, 0x4b, 0x14, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5e, 0x1d, 0x02, 0x7d, 0x2d, 0x06, 0xc9, 0xd6, 0x5b, 0x09, 0xff, 0xbb, 0x52, 0x01, 0xff, +0xb5, 0x53, 0x01, 0xff, 0xca, 0x62, 0x01, 0xff, 0xdc, 0x70, 0x01, 0xff, 0xe9, 0x7d, 0x03, 0xff, +0xea, 0x81, 0x08, 0xff, 0xec, 0x86, 0x0b, 0xff, 0xec, 0x87, 0x0e, 0xff, 0xed, 0x8b, 0x11, 0xff, +0xd7, 0x80, 0x11, 0xff, 0xc4, 0x98, 0x5f, 0xff, 0xd7, 0xd7, 0xd7, 0xff, 0xd7, 0xd7, 0xd7, 0xff, +0xd7, 0xd7, 0xd7, 0xff, 0xd8, 0xd8, 0xd7, 0xff, 0xd8, 0xd8, 0xd8, 0xff, 0xd1, 0xc0, 0xad, 0xff, +0xb8, 0x6f, 0x14, 0xff, 0xd6, 0x77, 0x07, 0xff, 0xe9, 0x7d, 0x03, 0xff, 0xde, 0x72, 0x01, 0xff, +0xca, 0x62, 0x01, 0xff, 0xb9, 0x54, 0x01, 0xff, 0xa6, 0x48, 0x01, 0xff, 0xd9, 0x61, 0x0a, 0xff, +0x8a, 0x27, 0x01, 0xf2, 0x7b, 0x5b, 0x1a, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7c, 0x47, 0x10, 0x72, 0xce, 0x4c, 0x02, 0xff, 0xe8, 0x78, 0x0c, 0xff, +0xc5, 0x5f, 0x01, 0xff, 0xda, 0x72, 0x01, 0xff, 0xe9, 0x7f, 0x03, 0xff, 0xec, 0x87, 0x0b, 0xff, +0xee, 0x8f, 0x13, 0xff, 0xef, 0x95, 0x19, 0xff, 0xef, 0x98, 0x1d, 0xff, 0xf1, 0x9c, 0x21, 0xff, +0xd6, 0x8e, 0x1f, 0xff, 0xc2, 0xa1, 0x6f, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, +0xcc, 0xcc, 0xcc, 0xff, 0xcc, 0xcc, 0xcc, 0xff, 0xc8, 0xbb, 0xa8, 0xff, 0xb8, 0x79, 0x21, 0xff, +0xda, 0x88, 0x17, 0xff, 0xee, 0x8f, 0x13, 0xff, 0xec, 0x87, 0x0b, 0xff, 0xe9, 0x7f, 0x03, 0xff, +0xda, 0x72, 0x01, 0xff, 0xc4, 0x60, 0x01, 0xff, 0xdf, 0x6c, 0x01, 0xff, 0xd8, 0x62, 0x0c, 0xff, +0x79, 0x35, 0x09, 0xad, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x79, 0x59, 0x1a, 0x18, 0x88, 0x27, 0x02, 0xef, 0xef, 0x8e, 0x22, 0xff, +0xe7, 0x7a, 0x01, 0xff, 0xe5, 0x7c, 0x01, 0xff, 0xed, 0x8a, 0x0b, 0xff, 0xef, 0x96, 0x17, 0xff, +0xf2, 0xa1, 0x22, 0xff, 0xf3, 0xa7, 0x29, 0xff, 0xf5, 0xad, 0x30, 0xff, 0xf6, 0xb0, 0x33, 0xff, +0xdc, 0x9f, 0x30, 0xff, 0xbd, 0xa1, 0x6b, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xff, +0xc3, 0xc3, 0xc3, 0xff, 0xc1, 0xb7, 0xa4, 0xff, 0xba, 0x89, 0x2f, 0xff, 0xdd, 0x9c, 0x2b, 0xff, +0xf3, 0xa8, 0x2a, 0xff, 0xf2, 0xa1, 0x22, 0xff, 0xef, 0x95, 0x17, 0xff, 0xed, 0x8a, 0x0b, 0xff, +0xe8, 0x7f, 0x01, 0xff, 0xd6, 0x6f, 0x01, 0xff, 0xf3, 0x93, 0x21, 0xff, 0xb1, 0x38, 0x01, 0xff, +0x78, 0x4f, 0x15, 0x43, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x77, 0x44, 0x10, 0x6e, 0xd1, 0x55, 0x01, 0xff, +0xf8, 0xaa, 0x30, 0xff, 0xee, 0x8a, 0x0a, 0xff, 0xee, 0x95, 0x16, 0xff, 0xf5, 0xaa, 0x2c, 0xff, +0xf7, 0xb5, 0x38, 0xff, 0xfa, 0xbc, 0x3f, 0xff, 0xfb, 0xc2, 0x44, 0xff, 0xfc, 0xc5, 0x47, 0xff, +0xf7, 0xc2, 0x48, 0xff, 0xbc, 0x98, 0x44, 0xff, 0xbc, 0xb4, 0xa0, 0xff, 0xbc, 0xbc, 0xbc, 0xff, +0xbc, 0xb0, 0x95, 0xff, 0xbc, 0x96, 0x40, 0xff, 0xe3, 0xb1, 0x40, 0xff, 0xfb, 0xc2, 0x44, 0xff, +0xfa, 0xbc, 0x3f, 0xff, 0xf9, 0xb5, 0x39, 0xff, 0xf5, 0xaa, 0x2c, 0xff, 0xef, 0x97, 0x19, 0xff, +0xed, 0x87, 0x06, 0xff, 0xf7, 0xa3, 0x25, 0xff, 0xe0, 0x74, 0x13, 0xff, 0x77, 0x35, 0x0a, 0xa6, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x75, 0x33, 0x0a, 0xa7, +0xe5, 0x7c, 0x1a, 0xff, 0xfd, 0xc6, 0x4e, 0xff, 0xf6, 0xa4, 0x25, 0xff, 0xfa, 0xbc, 0x3f, 0xff, +0xfd, 0xca, 0x4e, 0xff, 0xfe, 0xd0, 0x54, 0xff, 0xff, 0xd6, 0x5a, 0xff, 0xff, 0xd9, 0x60, 0xff, +0xff, 0xdb, 0x5f, 0xff, 0xe5, 0xc6, 0x57, 0xff, 0xc9, 0xae, 0x4f, 0xff, 0xbb, 0xa3, 0x4e, 0xff, +0xcf, 0xb2, 0x4f, 0xff, 0xeb, 0xca, 0x58, 0xff, 0xff, 0xd9, 0x60, 0xff, 0xff, 0xd6, 0x5a, 0xff, +0xff, 0xd0, 0x54, 0xff, 0xfd, 0xca, 0x4e, 0xff, 0xf9, 0xbd, 0x3f, 0xff, 0xf4, 0xa2, 0x23, 0xff, +0xfa, 0xba, 0x3f, 0xff, 0xf2, 0x9e, 0x32, 0xff, 0x7a, 0x27, 0x05, 0xd6, 0x7a, 0x5d, 0x1b, 0x0e, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7b, 0x5d, 0x1b, 0x10, +0x77, 0x29, 0x05, 0xd0, 0xf1, 0x9b, 0x36, 0xff, 0xff, 0xdf, 0x6b, 0xff, 0xfe, 0xc9, 0x4c, 0xff, +0xff, 0xd6, 0x5c, 0xff, 0xff, 0xe0, 0x65, 0xff, 0xff, 0xe5, 0x6a, 0xff, 0xff, 0xe8, 0x6d, 0xff, +0xff, 0xeb, 0x6f, 0xff, 0xff, 0xeb, 0x74, 0xff, 0xff, 0xeb, 0x74, 0xff, 0xfc, 0xe8, 0x72, 0xff, +0xff, 0xeb, 0x74, 0xff, 0xff, 0xeb, 0x6f, 0xff, 0xff, 0xe8, 0x6d, 0xff, 0xff, 0xe5, 0x6a, 0xff, +0xff, 0xe0, 0x65, 0xff, 0xff, 0xd8, 0x5e, 0xff, 0xfd, 0xc6, 0x48, 0xff, 0xff, 0xd5, 0x61, 0xff, +0xf9, 0xba, 0x4e, 0xff, 0x95, 0x2d, 0x02, 0xef, 0x7b, 0x56, 0x17, 0x31, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x79, 0x59, 0x1a, 0x1e, 0x77, 0x28, 0x05, 0xd0, 0xef, 0x94, 0x34, 0xff, 0xff, 0xf7, 0x89, 0xff, +0xff, 0xea, 0x75, 0xff, 0xff, 0xe9, 0x6e, 0xff, 0xff, 0xf0, 0x73, 0xff, 0xff, 0xf3, 0x7b, 0xff, +0xff, 0xf4, 0x80, 0xff, 0xff, 0xf5, 0x82, 0xff, 0xff, 0xf4, 0x87, 0xff, 0xff, 0xf4, 0x87, 0xff, +0xff, 0xf5, 0x82, 0xff, 0xff, 0xf4, 0x80, 0xff, 0xff, 0xf3, 0x7c, 0xff, 0xff, 0xef, 0x79, 0xff, +0xff, 0xea, 0x6b, 0xff, 0xff, 0xe7, 0x6a, 0xff, 0xff, 0xf5, 0x85, 0xff, 0xf8, 0xb4, 0x51, 0xff, +0x94, 0x2e, 0x02, 0xed, 0x77, 0x4f, 0x15, 0x42, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x79, 0x5b, 0x1a, 0x16, 0x77, 0x2f, 0x09, 0xb3, 0xe8, 0x82, 0x2c, 0xff, +0xff, 0xee, 0x9b, 0xff, 0xff, 0xff, 0xa9, 0xff, 0xff, 0xff, 0x90, 0xff, 0xff, 0xfb, 0x85, 0xff, +0xff, 0xf7, 0x8c, 0xff, 0xfe, 0xf6, 0x94, 0xff, 0xfd, 0xf5, 0x98, 0xff, 0xfd, 0xf5, 0x98, 0xff, +0xfe, 0xf6, 0x94, 0xff, 0xff, 0xf7, 0x8e, 0xff, 0xff, 0xfa, 0x85, 0xff, 0xff, 0xfd, 0x8a, 0xff, +0xff, 0xff, 0xa2, 0xff, 0xff, 0xfb, 0xa5, 0xff, 0xef, 0x98, 0x3f, 0xff, 0x7c, 0x28, 0x05, 0xd4, +0x79, 0x54, 0x17, 0x33, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x01, 0x75, 0x39, 0x0d, 0x8c, +0xb8, 0x40, 0x01, 0xf8, 0xf1, 0xa1, 0x52, 0xff, 0xff, 0xe9, 0xaa, 0xff, 0xff, 0xff, 0xc8, 0xff, +0xff, 0xff, 0xc4, 0xff, 0xff, 0xff, 0xba, 0xff, 0xff, 0xff, 0xb2, 0xff, 0xff, 0xff, 0xb1, 0xff, +0xff, 0xff, 0xb7, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xc8, 0xff, 0xff, 0xf4, 0xb4, 0xff, +0xf7, 0xb7, 0x6a, 0xff, 0xd7, 0x56, 0x04, 0xff, 0x75, 0x34, 0x0a, 0xa3, 0x79, 0x5b, 0x1b, 0x10, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x79, 0x52, 0x18, 0x2f, 0x76, 0x36, 0x0c, 0x97, 0x97, 0x38, 0x03, 0xe4, 0xde, 0x70, 0x20, 0xff, +0xef, 0xa3, 0x5b, 0xff, 0xf7, 0xc2, 0x85, 0xff, 0xfb, 0xd6, 0x9f, 0xff, 0xfb, 0xd9, 0xa1, 0xff, +0xf9, 0xc8, 0x8d, 0xff, 0xf3, 0xad, 0x68, 0xff, 0xe4, 0x7d, 0x2f, 0xff, 0xb3, 0x43, 0x02, 0xf1, +0x78, 0x31, 0x09, 0xae, 0x78, 0x4d, 0x15, 0x46, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x79, 0x5b, 0x1b, 0x11, 0x76, 0x4c, 0x15, 0x47, +0x70, 0x3b, 0x0f, 0x7b, 0x78, 0x35, 0x0a, 0xa3, 0x7e, 0x31, 0x08, 0xb7, 0x7e, 0x31, 0x08, 0xb7, +0x7b, 0x34, 0x0a, 0xab, 0x74, 0x3a, 0x0e, 0x85, 0x75, 0x47, 0x13, 0x55, 0x79, 0x58, 0x1a, 0x1e, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, +0x7a, 0x5f, 0x1d, 0x00, 0x7a, 0x5f, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +int init_bitmap_suite(void) +{ + return 0; +} + +int clean_bitmap_suite(void) +{ + return 0; +} + +int add_bitmap_suite(void) +{ + add_test_suite(bitmap); + + add_test_function(bitmap); + + return 0; +} + +void test_bitmap(void) +{ + struct btest + { + uint8 decompressed_16x1x8[16 * 1 * 1]; + uint8 decompressed_32x32x8[32 * 32 * 1]; + uint8 decompressed_16x1x16[16 * 1 * 2]; + uint8 decompressed_32x32x16[32 * 32 * 2]; + uint8 decompressed_16x1x24[16 * 1 * 3]; + uint8 decompressed_32x32x24[32 * 32 * 3]; + uint8 decompressed_16x1x32[16 * 1 * 4]; + uint8 decompressed_32x32x32[32 * 32 * 4]; + }; + struct btest* t; + int width; + int height; + int comp_size; + int decomp_size; + int bpp; + + t = (struct btest*)malloc(sizeof(struct btest)); + width = 16; + height = 1; + bpp = 8; + comp_size = sizeof(compressed_16x1x8); + decomp_size = sizeof(decompressed_16x1x8); + CU_ASSERT(bitmap_decompress(compressed_16x1x8, t->decompressed_16x1x8, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_16x1x8, decompressed_16x1x8, + decomp_size) == 0); + + width = 32; + height = 32; + bpp = 8; + comp_size = sizeof(compressed_32x32x8); + decomp_size = sizeof(decompressed_32x32x8); + CU_ASSERT(bitmap_decompress(compressed_32x32x8, t->decompressed_32x32x8, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_32x32x8, decompressed_32x32x8, + decomp_size) == 0); + + width = 16; + height = 1; + bpp = 16; + comp_size = sizeof(compressed_16x1x16); + decomp_size = sizeof(decompressed_16x1x16); + CU_ASSERT(bitmap_decompress(compressed_16x1x16, t->decompressed_16x1x16, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_16x1x16, decompressed_16x1x16, + decomp_size) == 0); + + width = 32; + height = 32; + bpp = 16; + comp_size = sizeof(compressed_32x32x16); + decomp_size = sizeof(decompressed_32x32x16); + CU_ASSERT(bitmap_decompress(compressed_32x32x16, t->decompressed_32x32x16, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_32x32x16, decompressed_32x32x16, + decomp_size) == 0); + + width = 16; + height = 1; + bpp = 24; + comp_size = sizeof(compressed_16x1x24); + decomp_size = sizeof(decompressed_16x1x24); + CU_ASSERT(bitmap_decompress(compressed_16x1x24, t->decompressed_16x1x24, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_16x1x24, decompressed_16x1x24, + decomp_size) == 0); + + width = 32; + height = 32; + bpp = 24; + comp_size = sizeof(compressed_32x32x24); + decomp_size = sizeof(decompressed_32x32x24); + CU_ASSERT(bitmap_decompress(compressed_32x32x24, t->decompressed_32x32x24, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_32x32x24, decompressed_32x32x24, + decomp_size) == 0); + + width = 16; + height = 1; + bpp = 32; + comp_size = sizeof(compressed_16x1x32); + decomp_size = sizeof(decompressed_16x1x32); + CU_ASSERT(bitmap_decompress(compressed_16x1x32, t->decompressed_16x1x32, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_16x1x32, decompressed_16x1x32, + decomp_size) == 0); + + width = 32; + height = 32; + bpp = 32; + comp_size = sizeof(compressed_32x32x32); + decomp_size = sizeof(decompressed_32x32x32); + CU_ASSERT(bitmap_decompress(compressed_32x32x32, t->decompressed_32x32x32, + width, height, comp_size, bpp, bpp) == true); + CU_ASSERT(memcmp(t->decompressed_32x32x32, decompressed_32x32x32, + decomp_size) == 0); + + free(t); +} diff --git a/cunit/test_bitmap.h b/cunit/test_bitmap.h new file mode 100644 index 0000000..3705e09 --- /dev/null +++ b/cunit/test_bitmap.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap Unit Tests + * + * Copyright 2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_bitmap_suite(void); +int clean_bitmap_suite(void); +int add_bitmap_suite(void); + +void test_bitmap(void); diff --git a/cunit/test_channels.c b/cunit/test_channels.c new file mode 100644 index 0000000..da2cd63 --- /dev/null +++ b/cunit/test_channels.c @@ -0,0 +1,91 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Channel Manager Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "test_channels.h" + +int init_chanman_suite(void) +{ + freerdp_channels_global_init(); + return 0; +} + +int clean_chanman_suite(void) +{ + freerdp_channels_global_uninit(); + return 0; +} + +int add_chanman_suite(void) +{ + add_test_suite(chanman); + + add_test_function(chanman); + + return 0; +} + +static int test_rdp_channel_data(freerdp* instance, int chan_id, uint8* data, int data_size) +{ + printf("chan_id %d data_size %d\n", chan_id, data_size); + return 0; +} + +void test_chanman(void) +{ + rdpChannels* chan_man; + rdpSettings settings = { 0 }; + freerdp instance = { 0 }; + RDP_EVENT* event; + + settings.hostname = "testhost"; + instance.settings = &settings; + instance.SendChannelData = test_rdp_channel_data; + + chan_man = freerdp_channels_new(); + + freerdp_channels_load_plugin(chan_man, &settings, "../channels/rdpdbg/rdpdbg.so", NULL); + freerdp_channels_pre_connect(chan_man, &instance); + freerdp_channels_post_connect(chan_man, &instance); + + freerdp_channels_data(&instance, 0, "testdata", 8, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 8); + freerdp_channels_data(&instance, 0, "testdata1", 9, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 9); + freerdp_channels_data(&instance, 0, "testdata11", 10, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 10); + freerdp_channels_data(&instance, 0, "testdata111", 11, CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, 11); + + event = freerdp_event_new(RDP_EVENT_CLASS_DEBUG, 0, NULL, NULL); + freerdp_channels_send_event(chan_man, event); + + while ((event = freerdp_channels_pop_event(chan_man)) == NULL) + { + freerdp_channels_check_fds(chan_man, &instance); + } + printf("responded event_type %d\n", event->event_type); + freerdp_event_free(event); + + freerdp_channels_close(chan_man, &instance); + freerdp_channels_free(chan_man); +} diff --git a/cunit/test_channels.h b/cunit/test_channels.h new file mode 100644 index 0000000..0022d30 --- /dev/null +++ b/cunit/test_channels.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Channel Manager Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_chanman_suite(void); +int clean_chanman_suite(void); +int add_chanman_suite(void); + +void test_chanman(void); diff --git a/cunit/test_cliprdr.c b/cunit/test_cliprdr.c new file mode 100644 index 0000000..26cf6f0 --- /dev/null +++ b/cunit/test_cliprdr.c @@ -0,0 +1,248 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Clipboard Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_cliprdr.h" + +int init_cliprdr_suite(void) +{ + freerdp_channels_global_init(); + return 0; +} + +int clean_cliprdr_suite(void) +{ + freerdp_channels_global_uninit(); + return 0; +} + +int add_cliprdr_suite(void) +{ + add_test_suite(cliprdr); + + add_test_function(cliprdr); + + return 0; +} + +static const uint8 test_clip_caps_data[] = +{ + "\x07\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x01\x00\x0C\x00" + "\x02\x00\x00\x00\x0E\x00\x00\x00" +}; + +static const uint8 test_monitor_ready_data[] = +{ + "\x01\x00\x00\x00\x00\x00\x00\x00" +}; + +static const uint8 test_format_list_data[] = +{ + "\x02\x00\x00\x00\x48\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\xd0\x00\x00" + "\x48\x00\x54\x00\x4D\x00\x4C\x00\x20\x00\x46\x00\x6F\x00\x72\x00" + "\x6D\x00\x61\x00\x74\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +static const uint8 test_format_list_response_data[] = +{ + "\x03\x00\x01\x00\x00\x00\x00\x00" +}; + +static const uint8 test_data_request_data[] = +{ + "\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00" +}; + +static const uint8 test_data_response_data[] = +{ + "\x05\x00\x01\x00\x18\x00\x00\x00\x68\x00\x65\x00\x6C\x00\x6C\x00" + "\x6F\x00\x20\x00\x77\x00\x6F\x00\x72\x00\x6c\x00\x64\x00\x00\x00" +}; + +static int test_rdp_channel_data(freerdp* instance, int chan_id, uint8* data, int data_size) +{ + printf("chan_id %d data_size %d\n", chan_id, data_size); + freerdp_hexdump(data, data_size); + return 0; +} + +static int event_processed; + +static void event_process_callback(RDP_EVENT* event) +{ + printf("Event %d processed.\n", event->event_type); + event_processed = 1; +} + +void test_cliprdr(void) +{ + int i; + rdpChannels* channels; + rdpSettings settings = { 0 }; + freerdp instance = { 0 }; + RDP_EVENT* event; + RDP_CB_FORMAT_LIST_EVENT* format_list_event; + RDP_CB_DATA_REQUEST_EVENT* data_request_event; + RDP_CB_DATA_RESPONSE_EVENT* data_response_event; + + settings.hostname = "testhost"; + instance.settings = &settings; + instance.SendChannelData = test_rdp_channel_data; + + channels = freerdp_channels_new(); + + freerdp_channels_load_plugin(channels, &settings, "../channels/cliprdr/cliprdr.so", NULL); + freerdp_channels_pre_connect(channels, &instance); + freerdp_channels_post_connect(channels, &instance); + + /* server sends cliprdr capabilities and monitor ready PDU */ + freerdp_channels_data(&instance, 0, (char*)test_clip_caps_data, sizeof(test_clip_caps_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_clip_caps_data) - 1); + + freerdp_channels_data(&instance, 0, (char*)test_monitor_ready_data, sizeof(test_monitor_ready_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_monitor_ready_data) - 1); + + /* cliprdr sends clipboard_sync event to UI */ + while ((event = freerdp_channels_pop_event(channels)) == NULL) + { + freerdp_channels_check_fds(channels, &instance); + } + printf("Got event %d\n", event->event_type); + CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_MONITOR_READY); + freerdp_event_free(event); + + /* UI sends format_list event to cliprdr */ + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_FORMAT_LIST, event_process_callback, NULL); + format_list_event = (RDP_CB_FORMAT_LIST_EVENT*) event; + format_list_event->num_formats = 2; + format_list_event->formats = (uint32*) xmalloc(sizeof(uint32) * 2); + format_list_event->formats[0] = CB_FORMAT_TEXT; + format_list_event->formats[1] = CB_FORMAT_HTML; + event_processed = 0; + freerdp_channels_send_event(channels, event); + + /* cliprdr sends format list PDU to server */ + while (!event_processed) + { + freerdp_channels_check_fds(channels, &instance); + } + + /* server sends format list response PDU to cliprdr */ + freerdp_channels_data(&instance, 0, (char*)test_format_list_response_data, sizeof(test_format_list_response_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_response_data) - 1); + + /* server sends format list PDU to cliprdr */ + freerdp_channels_data(&instance, 0, (char*)test_format_list_data, sizeof(test_format_list_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_format_list_data) - 1); + + /* cliprdr sends format_list event to UI */ + while ((event = freerdp_channels_pop_event(channels)) == NULL) + { + freerdp_channels_check_fds(channels, &instance); + } + printf("Got event %d\n", event->event_type); + CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST); + if (event->event_type == RDP_EVENT_TYPE_CB_FORMAT_LIST) + { + format_list_event = (RDP_CB_FORMAT_LIST_EVENT*)event; + for (i = 0; i < format_list_event->num_formats; i++) + printf("Format: 0x%X\n", format_list_event->formats[i]); + } + freerdp_event_free(event); + + /* server sends data request PDU to cliprdr */ + freerdp_channels_data(&instance, 0, (char*)test_data_request_data, sizeof(test_data_request_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_request_data) - 1); + + /* cliprdr sends data request event to UI */ + while ((event = freerdp_channels_pop_event(channels)) == NULL) + { + freerdp_channels_check_fds(channels, &instance); + } + printf("Got event %d\n", event->event_type); + CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST); + if (event->event_type == RDP_EVENT_TYPE_CB_DATA_REQUEST) + { + data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event; + printf("Requested format: 0x%X\n", data_request_event->format); + } + freerdp_event_free(event); + + /* UI sends data response event to cliprdr */ + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_RESPONSE, event_process_callback, NULL); + data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event; + data_response_event->data = (uint8*)xmalloc(6); + strcpy((char*)data_response_event->data, "hello"); + data_response_event->size = 6; + event_processed = 0; + freerdp_channels_send_event(channels, event); + + /* cliprdr sends data response PDU to server */ + while (!event_processed) + { + freerdp_channels_check_fds(channels, &instance); + } + + /* UI sends data request event to cliprdr */ + event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_DATA_REQUEST, event_process_callback, NULL); + data_request_event = (RDP_CB_DATA_REQUEST_EVENT*)event; + data_request_event->format = CB_FORMAT_UNICODETEXT; + event_processed = 0; + freerdp_channels_send_event(channels, event); + + /* cliprdr sends data request PDU to server */ + while (!event_processed) + { + freerdp_channels_check_fds(channels, &instance); + } + + /* server sends data response PDU to cliprdr */ + freerdp_channels_data(&instance, 0, (char*)test_data_response_data, sizeof(test_data_response_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_data_response_data) - 1); + + /* cliprdr sends data response event to UI */ + while ((event = freerdp_channels_pop_event(channels)) == NULL) + { + freerdp_channels_check_fds(channels, &instance); + } + printf("Got event %d\n", event->event_type); + CU_ASSERT(event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE); + if (event->event_type == RDP_EVENT_TYPE_CB_DATA_RESPONSE) + { + data_response_event = (RDP_CB_DATA_RESPONSE_EVENT*)event; + printf("Data response size: %d\n", data_response_event->size); + freerdp_hexdump(data_response_event->data, data_response_event->size); + } + freerdp_event_free(event); + + freerdp_channels_close(channels, &instance); + freerdp_channels_free(channels); +} diff --git a/cunit/test_cliprdr.h b/cunit/test_cliprdr.h new file mode 100644 index 0000000..f1a5509 --- /dev/null +++ b/cunit/test_cliprdr.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Clipboard Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_cliprdr_suite(void); +int clean_cliprdr_suite(void); +int add_cliprdr_suite(void); + +void test_cliprdr(void); diff --git a/cunit/test_color.c b/cunit/test_color.c new file mode 100644 index 0000000..d353b6b --- /dev/null +++ b/cunit/test_color.c @@ -0,0 +1,152 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Color Conversion Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "test_color.h" + +int init_color_suite(void) +{ + return 0; +} + +int clean_color_suite(void) +{ + return 0; +} + +int add_color_suite(void) +{ + add_test_suite(color); + + add_test_function(color_GetRGB32); + add_test_function(color_GetBGR32); + add_test_function(color_GetRGB_565); + add_test_function(color_GetRGB16); + add_test_function(color_GetBGR_565); + add_test_function(color_GetBGR16); + + return 0; +} + +/* GDI Color Space Conversions: http://msdn.microsoft.com/en-us/library/ff566496(VS.85).aspx */ + +void test_color_GetRGB32(void) +{ + int r, g, b; + uint32 rgb32 = 0x00AABBCC; + GetRGB32(r, g, b, rgb32); + + CU_ASSERT(r == 0xAA); + CU_ASSERT(g == 0xBB); + CU_ASSERT(b == 0xCC); +} + +void test_color_GetBGR32(void) +{ + int r, g, b; + uint32 bgr32 = 0x00CCBBAA; + GetBGR32(r, g, b, bgr32); + + CU_ASSERT(r == 0xAA); + CU_ASSERT(g == 0xBB); + CU_ASSERT(b == 0xCC); +} + +void test_color_GetRGB_565(void) +{ + /* + R: 0x15, 10101 + G: 0x33, 110011 + B: 0x1D, 11101 + + 0xAE7D, 10101110 01111101 + */ + + int r, g, b; + uint16 rgb16 = 0xAE7D; + GetRGB_565(r, g, b, rgb16); + + CU_ASSERT(r == 0x15); + CU_ASSERT(g == 0x33); + CU_ASSERT(b == 0x1D); +} + +void test_color_GetRGB16(void) +{ + /* + R: 0x15 -> 0xAD, 10101 -> 10101101 + G: 0x33 -> 0xCF, 110011 -> 11001111 + B: 0x1D -> 0xEF, 11101 -> 11101101 + + 0xAE7D -> 0xADCFEF + 10101110 01111101 -> 10101101 11001111 11101101 + */ + + int r, g, b; + uint16 rgb16 = 0xAE7D; + GetRGB16(r, g, b, rgb16); + + CU_ASSERT(r == 0xAD); + CU_ASSERT(g == 0xCF); + CU_ASSERT(b == 0xEF); +} + +void test_color_GetBGR_565(void) +{ + /* + B: 0x1D, 11101 + G: 0x33, 110011 + R: 0x15, 10101 + + 0xEE75, 11101110 01110101 + */ + + int r, g, b; + uint16 bgr16 = 0xEE75; + GetBGR_565(r, g, b, bgr16); + + CU_ASSERT(r == 0x15); + CU_ASSERT(g == 0x33); + CU_ASSERT(b == 0x1D); +} + +void test_color_GetBGR16(void) +{ + /* + B: 0x1D -> 0xEF, 11101 -> 11101101 + G: 0x33 -> 0xCF, 110011 -> 11001111 + R: 0x15 -> 0xAD, 10101 -> 10101101 + + 0xEE75 -> 0xADCFEF + 11101110 01110101 -> 10101101 11001111 11101101 + */ + + int r, g, b; + uint16 bgr16 = 0xEE75; + GetBGR16(r, g, b, bgr16); + + CU_ASSERT(r == 0xAD); + CU_ASSERT(g == 0xCF); + CU_ASSERT(b == 0xEF); +} + diff --git a/cunit/test_color.h b/cunit/test_color.h new file mode 100644 index 0000000..227146e --- /dev/null +++ b/cunit/test_color.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Color Conversion Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_color_suite(void); +int clean_color_suite(void); +int add_color_suite(void); + +void test_color_GetRGB32(void); +void test_color_GetBGR32(void); +void test_color_GetRGB_565(void); +void test_color_GetRGB16(void); +void test_color_GetBGR_565(void); +void test_color_GetBGR16(void); diff --git a/cunit/test_drdynvc.c b/cunit/test_drdynvc.c new file mode 100644 index 0000000..f46a7ac --- /dev/null +++ b/cunit/test_drdynvc.c @@ -0,0 +1,97 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Dynamic Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_drdynvc.h" + +int init_drdynvc_suite(void) +{ + freerdp_channels_global_init(); + return 0; +} + +int clean_drdynvc_suite(void) +{ + freerdp_channels_global_uninit(); + return 0; +} + +int add_drdynvc_suite(void) +{ + add_test_suite(drdynvc); + + add_test_function(drdynvc); + + return 0; +} + +static const uint8 test_capability_request_data[] = +{ + "\x58\x00\x02\x00\x33\x33\x11\x11\x3D\x0A\xA7\x04" +}; + +static int data_received = 0; + +static int test_rdp_channel_data(freerdp* instance, int chan_id, uint8* data, int data_size) +{ + printf("chan_id %d data_size %d\n", chan_id, data_size); + freerdp_hexdump(data, data_size); + data_received = 1; + return 0; +} + +void test_drdynvc(void) +{ + rdpChannels* chan_man; + rdpSettings settings = { 0 }; + freerdp instance = { 0 }; + + settings.hostname = "testhost"; + instance.settings = &settings; + instance.SendChannelData = test_rdp_channel_data; + + chan_man = freerdp_channels_new(); + + freerdp_channels_load_plugin(chan_man, &settings, "../channels/drdynvc/drdynvc.so", NULL); + freerdp_channels_pre_connect(chan_man, &instance); + freerdp_channels_post_connect(chan_man, &instance); + + /* server sends capability request PDU */ + freerdp_channels_data(&instance, 0, (char*)test_capability_request_data, sizeof(test_capability_request_data) - 1, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, sizeof(test_capability_request_data) - 1); + + /* drdynvc sends capability response PDU to server */ + data_received = 0; + while (!data_received) + { + freerdp_channels_check_fds(chan_man, &instance); + } + + freerdp_channels_close(chan_man, &instance); + freerdp_channels_free(chan_man); +} diff --git a/cunit/test_drdynvc.h b/cunit/test_drdynvc.h new file mode 100644 index 0000000..67e0754 --- /dev/null +++ b/cunit/test_drdynvc.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Dynamic Virtual Channel Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_drdynvc_suite(void); +int clean_drdynvc_suite(void); +int add_drdynvc_suite(void); + +void test_drdynvc(void); diff --git a/cunit/test_freerdp.c b/cunit/test_freerdp.c new file mode 100644 index 0000000..33c4539 --- /dev/null +++ b/cunit/test_freerdp.c @@ -0,0 +1,226 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "test_per.h" +#include "test_ber.h" +#include "test_gcc.h" +#include "test_mcs.h" +#include "test_color.h" +#include "test_bitmap.h" +#include "test_libgdi.h" +#include "test_list.h" +#include "test_stream.h" +#include "test_utils.h" +#include "test_orders.h" +#include "test_license.h" +#include "test_channels.h" +#include "test_cliprdr.h" +#include "test_drdynvc.h" +#include "test_librfx.h" +#include "test_freerdp.h" +#include "test_rail.h" +#include "test_pcap.h" +#include "test_mppc.h" + +void dump_data(unsigned char * p, int len, int width, char* name) +{ + unsigned char *line = p; + int i, thisline, offset = 0; + + printf("\n%s[%d][%d]:\n", name, len / width, width); + while (offset < len) + { + printf("%04x ", offset); + thisline = len - offset; + if (thisline > width) + thisline = width; + + for (i = 0; i < thisline; i++) + printf("%02x ", line[i]); + + for (; i < width; i++) + printf(" "); + + printf("\n"); + offset += thisline; + line += thisline; + } + printf("\n"); +} + +void assert_stream(STREAM* s, uint8* data, int length, const char* func, int line) +{ + int i; + int actual_length; + uint8* actual_data; + + actual_data = s->data; + actual_length = stream_get_length(s); + + if (actual_length != length) + { + printf("\n %s (%d): length mismatch, actual:%d, expected:%d\n", func, line, actual_length, length); + + printf("\nActual:\n"); + freerdp_hexdump(actual_data, actual_length); + + printf("Expected:\n"); + freerdp_hexdump(data, length); + + CU_FAIL("assert_stream, length mismatch"); + return; + } + + for (i = 0; i < length; i++) + { + if (actual_data[i] != data[i]) + { + printf("\n %s (%d): buffer mismatch:\n", func, line); + + printf("\nActual:\n"); + freerdp_hexdump(actual_data, length); + + printf("Expected:\n"); + freerdp_hexdump(data, length); + + CU_FAIL("assert_stream, buffer mismatch"); + return; + } + } +} + +int main(int argc, char* argv[]) +{ + int index = 1; + int *pindex = &index; + int ret = 0; + + if (CU_initialize_registry() != CUE_SUCCESS) + return CU_get_error(); + + if (argc < *pindex + 1) + { + add_per_suite(); + add_ber_suite(); + add_gcc_suite(); + add_mcs_suite(); + add_color_suite(); + add_bitmap_suite(); + add_libgdi_suite(); + add_list_suite(); + add_orders_suite(); + add_license_suite(); + add_stream_suite(); + add_mppc_suite(); + } + else + { + while (*pindex < argc) + { + if (strcmp("rail", argv[*pindex]) == 0) + { + add_rail_suite(); + } + if (strcmp("color", argv[*pindex]) == 0) + { + add_color_suite(); + } + if (strcmp("bitmap", argv[*pindex]) == 0) + { + add_bitmap_suite(); + } + else if (strcmp("libgdi", argv[*pindex]) == 0) + { + add_libgdi_suite(); + } + else if (strcmp("list", argv[*pindex]) == 0) + { + add_list_suite(); + } + else if (strcmp("orders", argv[*pindex]) == 0) + { + add_orders_suite(); + } + else if (strcmp("license", argv[*pindex]) == 0) + { + add_license_suite(); + } + else if (strcmp("stream", argv[*pindex]) == 0) + { + add_stream_suite(); + } + else if (strcmp("utils", argv[*pindex]) == 0) + { + add_utils_suite(); + } + else if (strcmp("chanman", argv[*pindex]) == 0) + { + add_chanman_suite(); + } + else if (strcmp("cliprdr", argv[*pindex]) == 0) + { + add_cliprdr_suite(); + } + else if (strcmp("drdynvc", argv[*pindex]) == 0) + { + add_drdynvc_suite(); + } + else if (strcmp("librfx", argv[*pindex]) == 0) + { + add_librfx_suite(); + } + else if (strcmp("per", argv[*pindex]) == 0) + { + add_per_suite(); + } + else if (strcmp("pcap", argv[*pindex]) == 0) + { + add_pcap_suite(); + } + else if (strcmp("ber", argv[*pindex]) == 0) + { + add_ber_suite(); + } + else if (strcmp("gcc", argv[*pindex]) == 0) + { + add_gcc_suite(); + } + else if (strcmp("mcs", argv[*pindex]) == 0) + { + add_mcs_suite(); + } + else if (strcmp("mppc", argv[*pindex]) == 0) + { + add_mppc_suite(); + } + + *pindex = *pindex + 1; + } + } + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + ret = CU_get_number_of_failure_records(); + CU_cleanup_registry(); + + return ret; +} + diff --git a/cunit/test_freerdp.h b/cunit/test_freerdp.h new file mode 100644 index 0000000..d9d2230 --- /dev/null +++ b/cunit/test_freerdp.h @@ -0,0 +1,43 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define add_test_suite(name) \ + CU_pSuite pSuite; \ + pSuite = CU_add_suite(#name, init_##name##_suite, clean_##name##_suite); \ + if (pSuite == NULL) { \ + CU_cleanup_registry(); return CU_get_error(); \ + } + +#define add_test_function(name) \ + if (CU_add_test(pSuite, #name, test_##name) == NULL) { \ + CU_cleanup_registry(); return CU_get_error(); \ + } + +void dump_data(unsigned char * p, int len, int width, char* name); +void assert_stream(STREAM* s, uint8* data, int length, const char* func, int line); + +#define ASSERT_STREAM(_s, _data, _length) assert_stream(_s, _data, _length, __FUNCTION__, __LINE__) diff --git a/cunit/test_gcc.c b/cunit/test_gcc.c new file mode 100644 index 0000000..1b86d4b --- /dev/null +++ b/cunit/test_gcc.c @@ -0,0 +1,215 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.124 Generic Conference Control (GCC) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gcc.h" + +#include +#include +#include + +#include "test_gcc.h" + +int init_gcc_suite(void) +{ + return 0; +} + +int clean_gcc_suite(void) +{ + return 0; +} + +int add_gcc_suite(void) +{ + add_test_suite(gcc); + + add_test_function(gcc_write_conference_create_request); + add_test_function(gcc_write_client_core_data); + add_test_function(gcc_write_client_security_data); + add_test_function(gcc_write_client_cluster_data); + add_test_function(gcc_write_client_network_data); + + return 0; +} + +uint8 gcc_user_data[284] = + "\x01\xc0\xd8\x00\x04\x00\x08\x00\x00\x05\x00\x04\x01\xCA\x03\xAA" + "\x09\x04\x00\x00\xCE\x0E\x00\x00\x45\x00\x4c\x00\x54\x00\x4f\x00" + "\x4e\x00\x53\x00\x2d\x00\x44\x00\x45\x00\x56\x00\x32\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" + "\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x01\xCA\x01\x00\x00\x00\x00\x00\x18\x00\x07\x00" + "\x01\x00\x36\x00\x39\x00\x37\x00\x31\x00\x32\x00\x2d\x00\x37\x00" + "\x38\x00\x33\x00\x2d\x00\x30\x00\x33\x00\x35\x00\x37\x00\x39\x00" + "\x37\x00\x34\x00\x2d\x00\x34\x00\x32\x00\x37\x00\x31\x00\x34\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\xC0\x0C\x00\x0D\x00\x00\x00" + "\x00\x00\x00\x00\x02\xC0\x0C\x00\x1B\x00\x00\x00\x00\x00\x00\x00" + "\x03\xC0\x2C\x00\x03\x00\x00\x00\x72\x64\x70\x64\x72\x00\x00\x00" + "\x00\x00\x80\x80\x63\x6c\x69\x70\x72\x64\x72\x00\x00\x00\xA0\xC0" + "\x72\x64\x70\x73\x6e\x64\x00\x00\x00\x00\x00\xc0"; + +uint8 gcc_conference_create_request_expected[307] = + "\x00\x05\x00\x14\x7C\x00\x01\x81\x2A\x00\x08\x00\x10\x00\x01\xC0" + "\x00\x44\x75\x63\x61\x81\x1c\x01\xc0\xd8\x00\x04\x00\x08\x00\x00" + "\x05\x00\x04\x01\xCA\x03\xAA\x09\x04\x00\x00\xCE\x0E\x00\x00\x45" + "\x00\x4c\x00\x54\x00\x4f\x00\x4e\x00\x53\x00\x2d\x00\x44\x00\x45" + "\x00\x56\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + "\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xCA\x01\x00\x00" + "\x00\x00\x00\x18\x00\x07\x00\x01\x00\x36\x00\x39\x00\x37\x00\x31" + "\x00\x32\x00\x2d\x00\x37\x00\x38\x00\x33\x00\x2d\x00\x30\x00\x33" + "\x00\x35\x00\x37\x00\x39\x00\x37\x00\x34\x00\x2d\x00\x34\x00\x32" + "\x00\x37\x00\x31\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + "\xC0\x0C\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x02\xC0\x0C\x00\x1B" + "\x00\x00\x00\x00\x00\x00\x00\x03\xC0\x2C\x00\x03\x00\x00\x00\x72" + "\x64\x70\x64\x72\x00\x00\x00\x00\x00\x80\x80\x63\x6c\x69\x70\x72" + "\x64\x72\x00\x00\x00\xA0\xC0\x72\x64\x70\x73\x6e\x64\x00\x00\x00" + "\x00\x00\xc0"; + +void test_gcc_write_conference_create_request(void) +{ + STREAM* s; + STREAM user_data; + + user_data.data = gcc_user_data; + user_data.size = sizeof(gcc_user_data); + user_data.p = user_data.data + user_data.size; + + s = stream_new(sizeof(gcc_conference_create_request_expected)); + + gcc_write_conference_create_request(s, &user_data); + ASSERT_STREAM(s, (uint8*) gcc_conference_create_request_expected, sizeof(gcc_conference_create_request_expected)); +} + +uint8 gcc_client_core_data_expected[216] = + "\x01\xc0\xd8\x00\x04\x00\x08\x00\x00\x05\x00\x04\x01\xCA\x03\xAA" + "\x09\x04\x00\x00\xCE\x0E\x00\x00\x45\x00\x4c\x00\x54\x00\x4f\x00" + "\x4e\x00\x53\x00\x2d\x00\x44\x00\x45\x00\x56\x00\x32\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" + "\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x01\xCA\x01\x00\x00\x00\x00\x00\x18\x00\x07\x00" + "\x01\x00\x36\x00\x39\x00\x37\x00\x31\x00\x32\x00\x2d\x00\x37\x00" + "\x38\x00\x33\x00\x2d\x00\x30\x00\x33\x00\x35\x00\x37\x00\x39\x00" + "\x37\x00\x34\x00\x2d\x00\x34\x00\x32\x00\x37\x00\x31\x00\x34\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00"; + +void test_gcc_write_client_core_data(void) +{ + STREAM* s; + rdpSettings* settings; + + s = stream_new(512); + settings = settings_new(NULL); + + settings->width = 1280; + settings->height = 1024; + settings->rdp_version = 5; + settings->color_depth = 24; + settings->kbd_layout = 0x409; + settings->kbd_type = 0x04; + settings->kbd_fn_keys = 12; + settings->client_build = 3790; + strcpy(settings->client_hostname, "ELTONS-DEV2"); + strcpy(settings->client_product_id, "69712-783-0357974-42714"); + + gcc_write_client_core_data(s, settings); + + ASSERT_STREAM(s, (uint8*) gcc_client_core_data_expected, sizeof(gcc_client_core_data_expected)); +} + +uint8 gcc_client_security_data_expected[12] = + "\x02\xC0\x0C\x00\x1B\x00\x00\x00\x00\x00\x00\x00"; + +void test_gcc_write_client_security_data(void) +{ + STREAM* s; + rdpSettings* settings; + + s = stream_new(12); + settings = settings_new(NULL); + + settings->encryption = 1; /* turn on encryption */ + settings->encryption_method = + ENCRYPTION_METHOD_40BIT | + ENCRYPTION_METHOD_56BIT | + ENCRYPTION_METHOD_128BIT | + ENCRYPTION_METHOD_FIPS; + + gcc_write_client_security_data(s, settings); + + ASSERT_STREAM(s, (uint8*) gcc_client_security_data_expected, sizeof(gcc_client_security_data_expected)); +} + +uint8 gcc_client_cluster_data_expected[12] = + "\x04\xC0\x0C\x00\x0D\x00\x00\x00\x00\x00\x00\x00"; + +void test_gcc_write_client_cluster_data(void) +{ + STREAM* s; + rdpSettings* settings; + + s = stream_new(12); + settings = settings_new(NULL); + + gcc_write_client_cluster_data(s, settings); + + ASSERT_STREAM(s, (uint8*) gcc_client_cluster_data_expected, sizeof(gcc_client_cluster_data_expected)); +} + +uint8 gcc_client_network_data_expected[44] = + "\x03\xC0\x2C\x00\x03\x00\x00\x00\x72\x64\x70\x64\x72\x00\x00\x00" + "\x00\x00\x80\x80\x63\x6c\x69\x70\x72\x64\x72\x00\x00\x00\xA0\xC0" + "\x72\x64\x70\x73\x6e\x64\x00\x00\x00\x00\x00\xc0"; + +void test_gcc_write_client_network_data(void) +{ + STREAM* s; + rdpSettings* settings; + + s = stream_new(44); + settings = settings_new(NULL); + + settings->num_channels = 3; + memset(settings->channels, 0, sizeof(rdpChannel) * settings->num_channels); + + strcpy(settings->channels[0].name, "rdpdr"); + settings->channels[0].options = 0x80800000; + + strcpy(settings->channels[1].name, "cliprdr"); + settings->channels[1].options = 0xc0A00000; + + strcpy(settings->channels[2].name, "rdpsnd"); + settings->channels[2].options = 0xc0000000; + + gcc_write_client_network_data(s, settings); + + ASSERT_STREAM(s, (uint8*) gcc_client_network_data_expected, sizeof(gcc_client_network_data_expected)); +} diff --git a/cunit/test_gcc.h b/cunit/test_gcc.h new file mode 100644 index 0000000..2ddce03 --- /dev/null +++ b/cunit/test_gcc.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.124 Generic Conference Control (GCC) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_gcc_suite(void); +int clean_gcc_suite(void); +int add_gcc_suite(void); + +void test_gcc_write_conference_create_request(void); +void test_gcc_write_client_core_data(void); +void test_gcc_write_client_security_data(void); +void test_gcc_write_client_cluster_data(void); +void test_gcc_write_client_network_data(void); diff --git a/cunit/test_libgdi.c b/cunit/test_libgdi.c new file mode 100644 index 0000000..df352df --- /dev/null +++ b/cunit/test_libgdi.c @@ -0,0 +1,2991 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_libgdi.h" + +int init_libgdi_suite(void) +{ + return 0; +} + +int clean_libgdi_suite(void) +{ + return 0; +} + +int add_libgdi_suite(void) +{ + add_test_suite(libgdi); + + add_test_function(gdi_GetDC); + add_test_function(gdi_CreateCompatibleDC); + add_test_function(gdi_CreateBitmap); + add_test_function(gdi_CreateCompatibleBitmap); + add_test_function(gdi_CreatePen); + add_test_function(gdi_CreateSolidBrush); + add_test_function(gdi_CreatePatternBrush); + add_test_function(gdi_CreateRectRgn); + add_test_function(gdi_CreateRect); + add_test_function(gdi_GetPixel); + add_test_function(gdi_SetPixel); + add_test_function(gdi_SetROP2); + add_test_function(gdi_MoveToEx); + add_test_function(gdi_LineTo); + add_test_function(gdi_Ellipse); + add_test_function(gdi_PtInRect); + add_test_function(gdi_FillRect); + add_test_function(gdi_BitBlt_32bpp); + add_test_function(gdi_BitBlt_16bpp); + add_test_function(gdi_BitBlt_8bpp); + add_test_function(gdi_ClipCoords); + add_test_function(gdi_InvalidateRegion); + + return 0; +} + +/* BitBlt() Test Data */ + +/* source bitmap (16x16) */ +unsigned char bmp_SRC[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* destination bitmap (16x16) */ +unsigned char bmp_DST[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* pattern bitmap (8x8) */ +unsigned char bmp_PAT[64] = +{ + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF" +}; + +/* SRCCOPY (0x00CC0020) */ +unsigned char bmp_SRCCOPY[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* BLACKNESS (0x00000042) */ +unsigned char bmp_BLACKNESS[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* WHITENESS (0x00FF0062) */ +unsigned char bmp_WHITENESS[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* SRCAND (0x008800C6) */ +unsigned char bmp_SRCAND[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* SRCPAINT (0x00EE0086) */ +unsigned char bmp_SRCPAINT[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* SRCINVERT (0x00660046) */ +unsigned char bmp_SRCINVERT[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* SRCERASE (0x00440328) */ +unsigned char bmp_SRCERASE[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* NOTSRCCOPY (0x00330008) */ +unsigned char bmp_NOTSRCCOPY[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* NOTSRCERASE (0x001100A6) */ +unsigned char bmp_NOTSRCERASE[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* DSTINVERT (0x00550009) */ +unsigned char bmp_DSTINVERT[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* SPna (0x000C0324) */ +unsigned char bmp_SPna[256] = +{ + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" +}; + +/* MERGEPAINT (0x00BB0226) */ +unsigned char bmp_MERGEPAINT[256] = +{ + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +/* MERGECOPY (0x00C000CA) */ +unsigned char bmp_MERGECOPY[256] = +{ + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" +}; + +/* PATPAINT (0x00FB0A09) */ +unsigned char bmp_PATPAINT[256] = +{ + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" +}; + +/* PATCOPY (0x00F00021) */ +unsigned char bmp_PATCOPY[256] = +{ + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF\x00\x00\xFF\xFF" +}; + +/* PATINVERT (0x005A0049) */ +unsigned char bmp_PATINVERT[256] = +{ + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00\x00\x00\xFF\xFF\x00\x00\xFF\xFF" +}; + +/* LineTo() Test Data */ + +unsigned char line_to_case_1[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_2[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_case_3[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_4[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_5[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_6[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_7[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_8[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_9[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_10[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_case_11[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_BLACK[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_NOTMERGEPEN[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_MASKNOTPEN[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_NOTCOPYPEN[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_MASKPENNOT[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_NOT[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_XORPEN[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_NOTMASKPEN[256] = +{ + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" +}; + +unsigned char line_to_R2_MASKPEN[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_NOTXORPEN[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_NOP[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_MERGENOTPEN[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_COPYPEN[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_MERGEPENNOT[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_MERGEPEN[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char line_to_R2_WHITE[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* PolylineTo() Test Data */ + +unsigned char polyline_to_case_1[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF" + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +unsigned char polyline_to_case_2[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* Ellipse() Test Data */ + +unsigned char ellipse_case_1[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char ellipse_case_2[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +unsigned char ellipse_case_3[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +/* Polygon() Test Data */ + +unsigned char polygon_case_1[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF" + "\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +}; + +unsigned char polygon_case_2[256] = +{ + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" +}; + +int CompareBitmaps(HGDI_BITMAP hBmp1, HGDI_BITMAP hBmp2) +{ + int x, y; + uint8 *p1, *p2; + + int minw = (hBmp1->width < hBmp2->width) ? hBmp1->width : hBmp2->width; + int minh = (hBmp1->height < hBmp2->height) ? hBmp1->height : hBmp2->height; + + if (hBmp1->bitsPerPixel == hBmp2->bitsPerPixel) + { + p1 = hBmp1->data; + p2 = hBmp2->data; + int bpp = hBmp1->bitsPerPixel; + + if (bpp == 32) + { + for (y = 0; y < minh; y++) + { + for (x = 0; x < minw; x++) + { + if (*p1 != *p2) + return 0; + p1++; + p2++; + + if (*p1 != *p2) + return 0; + p1++; + p2++; + + if (*p1 != *p2) + return 0; + p1 += 2; + p2 += 2; + } + } + } + else if (bpp == 16) + { + for (y = 0; y < minh; y++) + { + for (x = 0; x < minw; x++) + { + if (*p1 != *p2) + return 0; + p1++; + p2++; + + if (*p1 != *p2) + return 0; + p1++; + p2++; + } + } + } + else if (bpp == 8) + { + for (y = 0; y < minh; y++) + { + for (x = 0; x < minw; x++) + { + if (*p1 != *p2) + return 0; + p1++; + p2++; + } + } + } + } + else + { + return 0; + } + + return 1; +} + +void dump_bitmap(HGDI_BITMAP hBmp, char* name) +{ + dump_data(hBmp->data, hBmp->width * hBmp->height * hBmp->bytesPerPixel, hBmp->width * hBmp->bytesPerPixel, name); +} + +void assertBitmapsEqual(HGDI_BITMAP hBmpActual, HGDI_BITMAP hBmpExpected, char *name) +{ + int bitmapsEqual = CompareBitmaps(hBmpActual, hBmpExpected); + + if (bitmapsEqual != 1) + { + printf("\n%s\n", name); + dump_bitmap(hBmpActual, "Actual"); + dump_bitmap(hBmpExpected, "Expected"); + } + + CU_ASSERT(bitmapsEqual == 1); +} + +void test_gdi_GetDC(void) +{ + HGDI_DC hdc = gdi_GetDC(); + CU_ASSERT(hdc->bytesPerPixel == 4); + CU_ASSERT(hdc->bitsPerPixel == 32); + CU_ASSERT(hdc->drawMode == GDI_R2_BLACK); +} + +void test_gdi_CreateCompatibleDC(void) +{ + HGDI_DC hdc; + HGDI_DC chdc; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 2; + hdc->bitsPerPixel = 16; + hdc->drawMode = GDI_R2_XORPEN; + + chdc = gdi_CreateCompatibleDC(hdc); + + CU_ASSERT(chdc->bytesPerPixel == hdc->bytesPerPixel); + CU_ASSERT(chdc->bitsPerPixel == hdc->bitsPerPixel); + CU_ASSERT(chdc->drawMode == hdc->drawMode); +} + +void test_gdi_CreateBitmap(void) +{ + int bpp; + int width; + int height; + uint8* data; + HGDI_BITMAP hBitmap; + + bpp = 32; + width = 32; + height = 16; + data = (uint8*) malloc(width * height * 4); + hBitmap = gdi_CreateBitmap(width, height, bpp, data); + + CU_ASSERT(hBitmap->objectType == GDIOBJECT_BITMAP); + CU_ASSERT(hBitmap->bitsPerPixel == bpp); + CU_ASSERT(hBitmap->width == width); + CU_ASSERT(hBitmap->height == height); + CU_ASSERT(hBitmap->data == data); + + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_CreateCompatibleBitmap(void) +{ + HGDI_DC hdc; + int width; + int height; + HGDI_BITMAP hBitmap; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + + width = 32; + height = 16; + hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height); + + CU_ASSERT(hBitmap->objectType == GDIOBJECT_BITMAP); + CU_ASSERT(hBitmap->bytesPerPixel == hdc->bytesPerPixel); + CU_ASSERT(hBitmap->bitsPerPixel == hdc->bitsPerPixel); + CU_ASSERT(hBitmap->width == width); + CU_ASSERT(hBitmap->height == height); + CU_ASSERT(hBitmap->data != NULL); + + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_CreatePen(void) +{ + HGDI_PEN hPen = gdi_CreatePen(GDI_PS_SOLID, 8, 0xAABBCCDD); + CU_ASSERT(hPen->style == GDI_PS_SOLID); + CU_ASSERT(hPen->width == 8); + CU_ASSERT(hPen->color == 0xAABBCCDD); + gdi_DeleteObject((HGDIOBJECT) hPen); +} + +void test_gdi_CreateSolidBrush(void) +{ + HGDI_BRUSH hBrush = gdi_CreateSolidBrush(0xAABBCCDD); + CU_ASSERT(hBrush->objectType == GDIOBJECT_BRUSH); + CU_ASSERT(hBrush->style == GDI_BS_SOLID); + CU_ASSERT(hBrush->color == 0xAABBCCDD); + gdi_DeleteObject((HGDIOBJECT) hBrush); +} + +void test_gdi_CreatePatternBrush(void) +{ + HGDI_BRUSH hBrush; + HGDI_BITMAP hBitmap; + + hBitmap = gdi_CreateBitmap(64, 64, 32, NULL); + hBrush = gdi_CreatePatternBrush(hBitmap); + + CU_ASSERT(hBrush->objectType == GDIOBJECT_BRUSH); + CU_ASSERT(hBrush->style == GDI_BS_PATTERN); + CU_ASSERT(hBrush->pattern == hBitmap); + + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_CreateRectRgn(void) +{ + int x1 = 32; + int y1 = 64; + int x2 = 128; + int y2 = 256; + + HGDI_RGN hRegion = gdi_CreateRectRgn(x1, y1, x2, y2); + + CU_ASSERT(hRegion->objectType == GDIOBJECT_REGION); + CU_ASSERT(hRegion->x == x1); + CU_ASSERT(hRegion->y == y1); + CU_ASSERT(hRegion->w == x2 - x1 + 1); + CU_ASSERT(hRegion->h == y2 - y1 + 1); + CU_ASSERT(hRegion->null == 0); + + gdi_DeleteObject((HGDIOBJECT) hRegion); +} + +void test_gdi_CreateRect(void) +{ + int x1 = 32; + int y1 = 64; + int x2 = 128; + int y2 = 256; + + HGDI_RECT hRect = gdi_CreateRect(x1, y1, x2, y2); + + CU_ASSERT(hRect->objectType == GDIOBJECT_RECT); + CU_ASSERT(hRect->left == x1); + CU_ASSERT(hRect->top == y1); + CU_ASSERT(hRect->right == x2); + CU_ASSERT(hRect->bottom == y2); + + gdi_DeleteObject((HGDIOBJECT) hRect); +} + +void test_gdi_GetPixel(void) +{ + HGDI_DC hdc; + int width = 128; + int height = 64; + HGDI_BITMAP hBitmap; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + + hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height); + gdi_SelectObject(hdc, (HGDIOBJECT) hBitmap); + + hBitmap->data[(64 * width * 4) + 32 * 4 + 0] = 0xDD; + hBitmap->data[(64 * width * 4) + 32 * 4 + 1] = 0xCC; + hBitmap->data[(64 * width * 4) + 32 * 4 + 2] = 0xBB; + hBitmap->data[(64 * width * 4) + 32 * 4 + 3] = 0xAA; + + CU_ASSERT(gdi_GetPixel(hdc, 32, 64) == 0xAABBCCDD); + + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_SetPixel(void) +{ + HGDI_DC hdc; + int width = 128; + int height = 64; + HGDI_BITMAP hBitmap; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + + hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height); + gdi_SelectObject(hdc, (HGDIOBJECT) hBitmap); + + gdi_SetPixel(hdc, 32, 64, 0xAABBCCDD); + CU_ASSERT(gdi_GetPixel(hdc, 32, 64) == 0xAABBCCDD); + + gdi_SetPixel(hdc, width - 1, height - 1, 0xAABBCCDD); + CU_ASSERT(gdi_GetPixel(hdc, width - 1, height - 1) == 0xAABBCCDD); + + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_SetROP2(void) +{ + HGDI_DC hdc = gdi_GetDC(); + gdi_SetROP2(hdc, GDI_R2_BLACK); + CU_ASSERT(hdc->drawMode == GDI_R2_BLACK); +} + +void test_gdi_MoveToEx(void) +{ + HGDI_DC hdc; + HGDI_PEN hPen; + HGDI_POINT prevPoint; + + hdc = gdi_GetDC(); + hPen = gdi_CreatePen(GDI_PS_SOLID, 8, 0xAABBCCDD); + gdi_SelectObject(hdc, (HGDIOBJECT) hPen); + gdi_MoveToEx(hdc, 128, 256, NULL); + + CU_ASSERT(hdc->pen->posX == 128); + CU_ASSERT(hdc->pen->posY == 256); + + prevPoint = (HGDI_POINT) malloc(sizeof(GDI_POINT)); + memset(prevPoint, '\0', sizeof(GDI_POINT)); + + gdi_MoveToEx(hdc, 64, 128, prevPoint); + + CU_ASSERT(prevPoint->x == 128); + CU_ASSERT(prevPoint->y == 256); + CU_ASSERT(hdc->pen->posX == 64); + CU_ASSERT(hdc->pen->posY == 128); +} + +void test_gdi_LineTo(void) +{ + HGDI_DC hdc; + HGDI_PEN pen; + uint8* data; + HGDI_BITMAP hBmp; + HGDI_BITMAP hBmp_LineTo_1; + HGDI_BITMAP hBmp_LineTo_2; + HGDI_BITMAP hBmp_LineTo_3; + HGDI_BITMAP hBmp_LineTo_4; + HGDI_BITMAP hBmp_LineTo_5; + HGDI_BITMAP hBmp_LineTo_6; + HGDI_BITMAP hBmp_LineTo_7; + HGDI_BITMAP hBmp_LineTo_8; + HGDI_BITMAP hBmp_LineTo_9; + HGDI_BITMAP hBmp_LineTo_10; + HGDI_BITMAP hBmp_LineTo_11; + HGDI_BITMAP hBmp_LineTo_R2_BLACK; + HGDI_BITMAP hBmp_LineTo_R2_NOTMERGEPEN; + HGDI_BITMAP hBmp_LineTo_R2_MASKNOTPEN; + HGDI_BITMAP hBmp_LineTo_R2_NOTCOPYPEN; + HGDI_BITMAP hBmp_LineTo_R2_MASKPENNOT; + HGDI_BITMAP hBmp_LineTo_R2_NOT; + HGDI_BITMAP hBmp_LineTo_R2_XORPEN; + HGDI_BITMAP hBmp_LineTo_R2_NOTMASKPEN; + HGDI_BITMAP hBmp_LineTo_R2_MASKPEN; + HGDI_BITMAP hBmp_LineTo_R2_NOTXORPEN; + HGDI_BITMAP hBmp_LineTo_R2_NOP; + HGDI_BITMAP hBmp_LineTo_R2_MERGENOTPEN; + HGDI_BITMAP hBmp_LineTo_R2_COPYPEN; + HGDI_BITMAP hBmp_LineTo_R2_MERGEPENNOT; + HGDI_BITMAP hBmp_LineTo_R2_MERGEPEN; + HGDI_BITMAP hBmp_LineTo_R2_WHITE; + rdpPalette* hPalette; + HCLRCONV clrconv; + int bitsPerPixel = 8; + int bytesPerPixel = 1; + + hdc = gdi_GetDC(); + hdc->bitsPerPixel = bitsPerPixel; + hdc->bytesPerPixel = bytesPerPixel; + gdi_SetNullClipRgn(hdc); + + pen = gdi_CreatePen(1, 1, 0); + gdi_SelectObject(hdc, (HGDIOBJECT) pen); + + hBmp = gdi_CreateCompatibleBitmap(hdc, 16, 16); + gdi_SelectObject(hdc, (HGDIOBJECT) hBmp); + + hPalette = (rdpPalette*) gdi_GetSystemPalette(); + + clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + clrconv->alpha = 1; + clrconv->invert = 0; + clrconv->palette = hPalette; + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_1 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_2 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_3 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_4, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_4 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_5 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_5, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_5 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_6, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_6 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_7, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_7 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_8, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_8 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_9, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_9 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_10, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_10 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_case_11, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_11 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_BLACK, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_BLACK = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTMERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOTMERGEPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKNOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MASKNOTPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTCOPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOTCOPYPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MASKPENNOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_XORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_XORPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTMASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOTMASKPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MASKPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MASKPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOTXORPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOTXORPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_NOP, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_NOP = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGENOTPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MERGENOTPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_COPYPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_COPYPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGEPENNOT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MERGEPENNOT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_MERGEPEN, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_MERGEPEN = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) line_to_R2_WHITE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_LineTo_R2_WHITE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + /* Test Case 1: (0,0) -> (15, 15) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_LineTo(hdc, 15, 15); + assertBitmapsEqual(hBmp, hBmp_LineTo_1, "Case 1"); + + /* Test Case 2: (15,15) -> (0,0) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 15, 15, NULL); + gdi_LineTo(hdc, 0, 0); + assertBitmapsEqual(hBmp, hBmp_LineTo_2, "Case 2"); + + /* Test Case 3: (15,0) -> (0,15) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 15, 0, NULL); + gdi_LineTo(hdc, 0, 15); + assertBitmapsEqual(hBmp, hBmp_LineTo_3, "Case 3"); + + /* Test Case 4: (0,15) -> (15,0) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 0, 15, NULL); + gdi_LineTo(hdc, 15, 0); + assertBitmapsEqual(hBmp, hBmp_LineTo_4, "Case 4"); + + /* Test Case 4: (0,15) -> (15,0) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 0, 15, NULL); + gdi_LineTo(hdc, 15, 0); + assertBitmapsEqual(hBmp, hBmp_LineTo_4, "Case 4"); + + /* Test Case 5: (0,8) -> (15,8) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 0, 8, NULL); + gdi_LineTo(hdc, 15, 8); + assertBitmapsEqual(hBmp, hBmp_LineTo_5, "Case 5"); + + /* Test Case 6: (15,8) -> (0,8) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 15, 8, NULL); + gdi_LineTo(hdc, 0, 8); + assertBitmapsEqual(hBmp, hBmp_LineTo_6, "Case 6"); + + /* Test Case 7: (8,0) -> (8,15) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 8, 0, NULL); + gdi_LineTo(hdc, 8, 15); + assertBitmapsEqual(hBmp, hBmp_LineTo_7, "Case 7"); + + /* Test Case 8: (8,15) -> (8,0) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 8, 15, NULL); + gdi_LineTo(hdc, 8, 0); + assertBitmapsEqual(hBmp, hBmp_LineTo_8, "Case 8"); + + /* Test Case 9: (4,4) -> (12,12) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 4, 4, NULL); + gdi_LineTo(hdc, 12, 12); + assertBitmapsEqual(hBmp, hBmp_LineTo_9, "Case 9"); + + /* Test Case 10: (12,12) -> (4,4) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_MoveToEx(hdc, 12, 12, NULL); + gdi_LineTo(hdc, 4, 4); + assertBitmapsEqual(hBmp, hBmp_LineTo_10, "Case 10"); + + /* Test Case 11: (0,0) -> (+10,+10) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_LineTo(hdc, 16 + 10, 16 + 10); + assertBitmapsEqual(hBmp, hBmp_LineTo_11, "Case 11"); + + /* Test Case 12: (0,0) -> (16,16), R2_BLACK */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_BLACK); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_BLACK, "Case 12"); + + /* Test Case 13: (0,0) -> (16,16), R2_NOTMERGEPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOTMERGEPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOTMERGEPEN, "Case 13"); + + /* Test Case 14: (0,0) -> (16,16), R2_MASKNOTPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MASKNOTPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MASKNOTPEN, "Case 14"); + + /* Test Case 15: (0,0) -> (16,16), R2_NOTCOPYPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOTCOPYPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOTCOPYPEN, "Case 15"); + + /* Test Case 16: (0,0) -> (16,16), R2_MASKPENNOT */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MASKPENNOT); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MASKPENNOT, "Case 16"); + + /* Test Case 17: (0,0) -> (16,16), R2_NOT */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOT); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOT, "Case 17"); + + /* Test Case 18: (0,0) -> (16,16), R2_XORPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_XORPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_XORPEN, "Case 18"); + + /* Test Case 19: (0,0) -> (16,16), R2_NOTMASKPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOTMASKPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOTMASKPEN, "Case 19"); + + /* Test Case 20: (0,0) -> (16,16), R2_MASKPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MASKPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MASKPEN, "Case 20"); + + /* Test Case 21: (0,0) -> (16,16), R2_NOTXORPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOTXORPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOTXORPEN, "Case 21"); + + /* Test Case 22: (0,0) -> (16,16), R2_NOP */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_NOP); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_NOP, "Case 22"); + + /* Test Case 23: (0,0) -> (16,16), R2_MERGENOTPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MERGENOTPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MERGENOTPEN, "Case 23"); + + /* Test Case 24: (0,0) -> (16,16), R2_COPYPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_COPYPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_COPYPEN, "Case 24"); + + /* Test Case 25: (0,0) -> (16,16), R2_MERGEPENNOT */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MERGEPENNOT); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MERGEPENNOT, "Case 25"); + + /* Test Case 26: (0,0) -> (16,16), R2_MERGEPEN */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_MERGEPEN); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_MERGEPEN, "Case 26"); + + /* Test Case 27: (0,0) -> (16,16), R2_WHITE */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_SetClipRgn(hdc, 0, 0, 16, 16); + gdi_MoveToEx(hdc, 0, 0, NULL); + gdi_SetROP2(hdc, GDI_R2_WHITE); + gdi_LineTo(hdc, 16, 16); + assertBitmapsEqual(hBmp, hBmp_LineTo_R2_WHITE, "Case 27"); +} + +void test_gdi_Ellipse(void) +{ + HGDI_DC hdc; + HGDI_PEN pen; + uint8* data; + HGDI_BITMAP hBmp; + HGDI_BITMAP hBmp_Ellipse_1; + HGDI_BITMAP hBmp_Ellipse_2; + HGDI_BITMAP hBmp_Ellipse_3; + rdpPalette* hPalette; + HCLRCONV clrconv; + int bitsPerPixel = 8; + int bytesPerPixel = 1; + + hdc = gdi_GetDC(); + hdc->bitsPerPixel = bitsPerPixel; + hdc->bytesPerPixel = bytesPerPixel; + gdi_SetNullClipRgn(hdc); + + pen = gdi_CreatePen(1, 1, 0); + gdi_SelectObject(hdc, (HGDIOBJECT) pen); + + hBmp = gdi_CreateCompatibleBitmap(hdc, 16, 16); + gdi_SelectObject(hdc, (HGDIOBJECT) hBmp); + + hPalette = (rdpPalette*) gdi_GetSystemPalette(); + + clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + clrconv->alpha = 1; + clrconv->invert = 0; + clrconv->palette = hPalette; + + data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_1, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_Ellipse_1 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_2, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_Ellipse_2 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) ellipse_case_3, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_Ellipse_3 = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + /* Test Case 1: (0,0) -> (16, 16) */ + gdi_BitBlt(hdc, 0, 0, 16, 16, hdc, 0, 0, GDI_WHITENESS); + gdi_Ellipse(hdc, 0, 0, 16, 16); + //assertBitmapsEqual(hBmp, hBmp_Ellipse_1, "Case 1"); +} + +void test_gdi_PtInRect(void) +{ + HGDI_RECT hRect; + int left = 20; + int top = 40; + int right = 60; + int bottom = 80; + + hRect = gdi_CreateRect(left, top, right, bottom); + + CU_ASSERT(gdi_PtInRect(hRect, 0, 0) == 0); + CU_ASSERT(gdi_PtInRect(hRect, 500, 500) == 0); + CU_ASSERT(gdi_PtInRect(hRect, 40, 100) == 0); + CU_ASSERT(gdi_PtInRect(hRect, 10, 40) == 0); + CU_ASSERT(gdi_PtInRect(hRect, 30, 50) == 1); + CU_ASSERT(gdi_PtInRect(hRect, left, top) == 1); + CU_ASSERT(gdi_PtInRect(hRect, right, bottom) == 1); + CU_ASSERT(gdi_PtInRect(hRect, right, 60) == 1); + CU_ASSERT(gdi_PtInRect(hRect, 40, bottom) == 1); +} + +void test_gdi_FillRect(void) +{ + HGDI_DC hdc; + HGDI_RECT hRect; + HGDI_BRUSH hBrush; + HGDI_BITMAP hBitmap; + GDI_COLOR color; + GDI_COLOR pixel; + GDI_COLOR rawPixel; + + int x, y; + int badPixels; + int goodPixels; + int width = 200; + int height = 300; + + int left = 20; + int top = 40; + int right = 60; + int bottom = 80; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + + hRect = gdi_CreateRect(left, top, right, bottom); + + hBitmap = gdi_CreateCompatibleBitmap(hdc, width, height); + memset(hBitmap->data, 0, width * height * hdc->bytesPerPixel); + gdi_SelectObject(hdc, (HGDIOBJECT) hBitmap); + + color = (GDI_COLOR) ARGB32(0xFF, 0xAA, 0xBB, 0xCC); + hBrush = gdi_CreateSolidBrush(color); + + gdi_FillRect(hdc, hRect, hBrush); + + badPixels = 0; + goodPixels = 0; + + for (x = 0; x < width; x++) + { + for (y = 0; y < height; y++) + { + rawPixel = gdi_GetPixel(hdc, x, y); + pixel = gdi_get_color_32bpp(hdc, rawPixel); + + if (gdi_PtInRect(hRect, x, y)) + { + if (pixel == color) { + goodPixels++; + } + else { + printf("actual:%04X expected:%04X\n", gdi_GetPixel(hdc, x, y), color); + badPixels++; + } + } + else + { + if (pixel == color) { + badPixels++; + } + else { + goodPixels++; + } + } + } + } + + CU_ASSERT(goodPixels == width * height); + CU_ASSERT(badPixels == 0); + + gdi_DeleteObject((HGDIOBJECT) hBrush); + gdi_DeleteObject((HGDIOBJECT) hBitmap); +} + +void test_gdi_BitBlt_32bpp(void) +{ + uint8* data; + HGDI_DC hdcSrc; + HGDI_DC hdcDst; + HGDI_BRUSH hBrush; + HGDI_BITMAP hBmpSrc; + HGDI_BITMAP hBmpDst; + HGDI_BITMAP hBmpPat; + HGDI_BITMAP hBmp_SPna; + HGDI_BITMAP hBmp_BLACKNESS; + HGDI_BITMAP hBmp_WHITENESS; + HGDI_BITMAP hBmp_SRCCOPY; + HGDI_BITMAP hBmp_SRCAND; + HGDI_BITMAP hBmp_SRCPAINT; + HGDI_BITMAP hBmp_SRCINVERT; + HGDI_BITMAP hBmp_SRCERASE; + HGDI_BITMAP hBmp_NOTSRCCOPY; + HGDI_BITMAP hBmp_NOTSRCERASE; + HGDI_BITMAP hBmp_DSTINVERT; + HGDI_BITMAP hBmp_MERGECOPY; + HGDI_BITMAP hBmp_MERGEPAINT; + HGDI_BITMAP hBmp_PATCOPY; + HGDI_BITMAP hBmp_PATPAINT; + HGDI_BITMAP hBmp_PATINVERT; + HGDI_BITMAP hBmpDstOriginal; + rdpPalette* hPalette; + HCLRCONV clrconv; + + int bytesPerPixel = 4; + int bitsPerPixel = 32; + + hdcSrc = gdi_GetDC(); + hdcSrc->bytesPerPixel = bytesPerPixel; + hdcSrc->bitsPerPixel = bitsPerPixel; + + hdcDst = gdi_GetDC(); + hdcDst->bytesPerPixel = bytesPerPixel; + hdcDst->bitsPerPixel = bitsPerPixel; + + hPalette = (rdpPalette*) gdi_GetSystemPalette(); + + clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + clrconv->alpha = 1; + clrconv->invert = 0; + clrconv->palette = hPalette; + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv); + hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBmpDst); + + /* SRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCCOPY) == 1) + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* BLACKNESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_BLACKNESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_BLACKNESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* WHITENESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_WHITENESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_WHITENESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCAND */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCAND); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCAND) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* DSTINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_DSTINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_DSTINVERT) == 1); + + /* select a brush for operations using a pattern */ + hBrush = gdi_CreatePatternBrush(hBmpPat); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBrush); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGECOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGECOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGECOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGEPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGEPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGEPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SPna */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SPna); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SPna) == 1) +} + +void test_gdi_BitBlt_16bpp(void) +{ + uint8* data; + HGDI_DC hdcSrc; + HGDI_DC hdcDst; + HGDI_BRUSH hBrush; + HGDI_BITMAP hBmpSrc; + HGDI_BITMAP hBmpDst; + HGDI_BITMAP hBmpPat; + HGDI_BITMAP hBmp_SPna; + HGDI_BITMAP hBmp_BLACKNESS; + HGDI_BITMAP hBmp_WHITENESS; + HGDI_BITMAP hBmp_SRCCOPY; + HGDI_BITMAP hBmp_SRCAND; + HGDI_BITMAP hBmp_SRCPAINT; + HGDI_BITMAP hBmp_SRCINVERT; + HGDI_BITMAP hBmp_SRCERASE; + HGDI_BITMAP hBmp_NOTSRCCOPY; + HGDI_BITMAP hBmp_NOTSRCERASE; + HGDI_BITMAP hBmp_DSTINVERT; + HGDI_BITMAP hBmp_MERGECOPY; + HGDI_BITMAP hBmp_MERGEPAINT; + HGDI_BITMAP hBmp_PATCOPY; + HGDI_BITMAP hBmp_PATPAINT; + HGDI_BITMAP hBmp_PATINVERT; + HGDI_BITMAP hBmpDstOriginal; + rdpPalette* hPalette; + HCLRCONV clrconv; + + int bytesPerPixel = 2; + int bitsPerPixel = 16; + + hdcSrc = gdi_GetDC(); + hdcSrc->bytesPerPixel = bytesPerPixel; + hdcSrc->bitsPerPixel = bitsPerPixel; + + hdcDst = gdi_GetDC(); + hdcDst->bytesPerPixel = bytesPerPixel; + hdcDst->bitsPerPixel = bitsPerPixel; + + hPalette = (rdpPalette*) gdi_GetSystemPalette(); + + clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + clrconv->alpha = 1; + clrconv->invert = 0; + clrconv->palette = hPalette; + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv); + hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBmpDst); + + /* SRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCCOPY) == 1) + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* BLACKNESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_BLACKNESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_BLACKNESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* WHITENESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_WHITENESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_WHITENESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCAND */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCAND); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCAND) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* DSTINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_DSTINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_DSTINVERT) == 1); + + /* select a brush for operations using a pattern */ + hBrush = gdi_CreatePatternBrush(hBmpPat); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBrush); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGECOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGECOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGECOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGEPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGEPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGEPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SPna */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SPna); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SPna) == 1) +} + +void test_gdi_BitBlt_8bpp(void) +{ + uint8* data; + HGDI_DC hdcSrc; + HGDI_DC hdcDst; + HGDI_BRUSH hBrush; + HGDI_BITMAP hBmpSrc; + HGDI_BITMAP hBmpDst; + HGDI_BITMAP hBmpPat; + HGDI_BITMAP hBmp_SPna; + HGDI_BITMAP hBmp_BLACKNESS; + HGDI_BITMAP hBmp_WHITENESS; + HGDI_BITMAP hBmp_SRCCOPY; + HGDI_BITMAP hBmp_SRCAND; + HGDI_BITMAP hBmp_SRCPAINT; + HGDI_BITMAP hBmp_SRCINVERT; + HGDI_BITMAP hBmp_SRCERASE; + HGDI_BITMAP hBmp_NOTSRCCOPY; + HGDI_BITMAP hBmp_NOTSRCERASE; + HGDI_BITMAP hBmp_DSTINVERT; + HGDI_BITMAP hBmp_MERGECOPY; + HGDI_BITMAP hBmp_MERGEPAINT; + HGDI_BITMAP hBmp_PATCOPY; + HGDI_BITMAP hBmp_PATPAINT; + HGDI_BITMAP hBmp_PATINVERT; + HGDI_BITMAP hBmpDstOriginal; + rdpPalette* hPalette; + HCLRCONV clrconv; + + int bytesPerPixel = 1; + int bitsPerPixel = 8; + + hdcSrc = gdi_GetDC(); + hdcSrc->bytesPerPixel = bytesPerPixel; + hdcSrc->bitsPerPixel = bitsPerPixel; + + hdcDst = gdi_GetDC(); + hdcDst->bytesPerPixel = bytesPerPixel; + hdcDst->bitsPerPixel = bitsPerPixel; + + hPalette = (rdpPalette*) gdi_GetSystemPalette(); + + clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + clrconv->alpha = 1; + clrconv->invert = 0; + clrconv->palette = hPalette; + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRC, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpSrc = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDst = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DST, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmpDstOriginal = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PAT, NULL, 8, 8, 8, bitsPerPixel, clrconv); + hBmpPat = gdi_CreateBitmap(8, 8, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SPna, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SPna = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_BLACKNESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_BLACKNESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_WHITENESS, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_WHITENESS = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCAND, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCAND = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_SRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_SRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_NOTSRCERASE, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_NOTSRCERASE = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_DSTINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_DSTINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGECOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGECOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_MERGEPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_MERGEPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATCOPY, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATCOPY = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATPAINT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATPAINT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + data = (uint8*) freerdp_image_convert((uint8*) bmp_PATINVERT, NULL, 16, 16, 8, bitsPerPixel, clrconv); + hBmp_PATINVERT = gdi_CreateBitmap(16, 16, bitsPerPixel, data); + + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBmpDst); + + /* SRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCCOPY) == 1) + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* BLACKNESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_BLACKNESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_BLACKNESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* WHITENESS */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_WHITENESS); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_WHITENESS) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCAND */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCAND); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCAND) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* NOTSRCERASE */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_NOTSRCERASE); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_NOTSRCERASE) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* DSTINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_DSTINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_DSTINVERT) == 1); + + /* select a brush for operations using a pattern */ + hBrush = gdi_CreatePatternBrush(hBmpPat); + gdi_SelectObject(hdcDst, (HGDIOBJECT) hBrush); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGECOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGECOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGECOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* MERGEPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_MERGEPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_MERGEPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATCOPY */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATCOPY); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATCOPY) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATINVERT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATINVERT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATINVERT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* PATPAINT */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_PATPAINT); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_PATPAINT) == 1); + + /* restore original destination bitmap */ + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpDstOriginal); + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SRCCOPY); + gdi_SelectObject(hdcSrc, (HGDIOBJECT) hBmpSrc); + + /* SPna */ + gdi_BitBlt(hdcDst, 0, 0, 16, 16, hdcSrc, 0, 0, GDI_SPna); + CU_ASSERT(CompareBitmaps(hBmpDst, hBmp_SPna) == 1) +} + +void test_gdi_ClipCoords(void) +{ + HGDI_DC hdc; + HGDI_RGN rgn1; + HGDI_RGN rgn2; + HGDI_BITMAP bmp; + int draw; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + bmp = gdi_CreateBitmap(1024, 768, 4, NULL); + gdi_SelectObject(hdc, (HGDIOBJECT) bmp); + gdi_SetNullClipRgn(hdc); + + rgn1 = gdi_CreateRectRgn(0, 0, 0, 0); + rgn2 = gdi_CreateRectRgn(0, 0, 0, 0); + rgn1->null = 1; + rgn2->null = 1; + + /* null clipping region */ + gdi_SetNullClipRgn(hdc); + gdi_SetRgn(rgn1, 20, 20, 100, 100); + gdi_SetRgn(rgn2, 20, 20, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* region all inside clipping region */ + gdi_SetClipRgn(hdc, 0, 0, 1024, 768); + gdi_SetRgn(rgn1, 20, 20, 100, 100); + gdi_SetRgn(rgn2, 20, 20, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* region all outside clipping region, on the left */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 20, 20, 100, 100); + gdi_SetRgn(rgn2, 0, 0, 0, 0); + + draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(draw == 0); + + /* region all outside clipping region, on the right */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 420, 420, 100, 100); + gdi_SetRgn(rgn2, 0, 0, 0, 0); + + draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(draw == 0); + + /* region all outside clipping region, on top */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 20, 100, 100); + gdi_SetRgn(rgn2, 0, 0, 0, 0); + + draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(draw == 0); + + /* region all outside clipping region, at the bottom */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 420, 100, 100); + gdi_SetRgn(rgn2, 0, 0, 0, 0); + + draw = gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(draw == 0); + + /* left outside, right = clip, top = clip, bottom = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 300, 300, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* left outside, right inside, top = clip, bottom = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 300, 250, 100); + gdi_SetRgn(rgn2, 300, 300, 50, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* left = clip, right outside, top = clip, bottom = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 300, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* left inside, right outside, top = clip, bottom = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 350, 300, 200, 100); + gdi_SetRgn(rgn2, 350, 300, 50, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* top outside, bottom = clip, left = clip, right = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 100, 300, 300); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* top = clip, bottom outside, left = clip, right = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 100, 200); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); + + /* top = clip, bottom = clip, top = clip, bottom = clip */ + gdi_SetClipRgn(hdc, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 100, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL); + CU_ASSERT(gdi_EqualRgn(rgn1, rgn2) == 1); +} + +void test_gdi_InvalidateRegion(void) +{ + HGDI_DC hdc; + HGDI_RGN rgn1; + HGDI_RGN rgn2; + HGDI_RGN invalid; + HGDI_BITMAP bmp; + + hdc = gdi_GetDC(); + hdc->bytesPerPixel = 4; + hdc->bitsPerPixel = 32; + bmp = gdi_CreateBitmap(1024, 768, 4, NULL); + gdi_SelectObject(hdc, (HGDIOBJECT) bmp); + gdi_SetNullClipRgn(hdc); + + hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + hdc->hwnd->invalid->null = 1; + invalid = hdc->hwnd->invalid; + + hdc->hwnd->count = 16; + hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * hdc->hwnd->count); + + rgn1 = gdi_CreateRectRgn(0, 0, 0, 0); + rgn2 = gdi_CreateRectRgn(0, 0, 0, 0); + rgn1->null = 1; + rgn2->null = 1; + + /* no previous invalid region */ + invalid->null = 1; + gdi_SetRgn(rgn1, 300, 300, 100, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* region same as invalid region */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 100, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* left outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 300, 300, 100); + gdi_SetRgn(rgn2, 100, 300, 300, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* right outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 300, 100); + gdi_SetRgn(rgn2, 300, 300, 300, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* top outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 100, 100, 300); + gdi_SetRgn(rgn2, 300, 100, 100, 300); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* bottom outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 300, 100, 300); + gdi_SetRgn(rgn2, 300, 300, 100, 300); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* left outside, right outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 300, 600, 300); + gdi_SetRgn(rgn2, 100, 300, 600, 300); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* top outside, bottom outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 100, 100, 500); + gdi_SetRgn(rgn2, 300, 100, 100, 500); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* all outside, left */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 300, 100, 100); + gdi_SetRgn(rgn2, 100, 300, 300, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* all outside, right */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 700, 300, 100, 100); + gdi_SetRgn(rgn2, 300, 300, 500, 100); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* all outside, top */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 100, 100, 100); + gdi_SetRgn(rgn2, 300, 100, 100, 300); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* all outside, bottom */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 300, 500, 100, 100); + gdi_SetRgn(rgn2, 300, 300, 100, 300); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* all outside */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 100, 100, 600, 600); + gdi_SetRgn(rgn2, 100, 100, 600, 600); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); + + /* everything */ + gdi_SetRgn(invalid, 300, 300, 100, 100); + gdi_SetRgn(rgn1, 0, 0, 1024, 768); + gdi_SetRgn(rgn2, 0, 0, 1024, 768); + + gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h); + CU_ASSERT(gdi_EqualRgn(invalid, rgn2) == 1); +} diff --git a/cunit/test_libgdi.h b/cunit/test_libgdi.h new file mode 100644 index 0000000..7b181b1 --- /dev/null +++ b/cunit/test_libgdi.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Unit Tests + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_libgdi_suite(void); +int clean_libgdi_suite(void); +int add_libgdi_suite(void); + +void test_gdi_GetDC(void); +void test_gdi_CreateCompatibleDC(void); +void test_gdi_CreateBitmap(void); +void test_gdi_CreateCompatibleBitmap(void); +void test_gdi_CreatePen(void); +void test_gdi_CreateSolidBrush(void); +void test_gdi_CreatePatternBrush(void); +void test_gdi_CreateRectRgn(void); +void test_gdi_CreateRect(void); +void test_gdi_GetPixel(void); +void test_gdi_SetPixel(void); +void test_gdi_SetROP2(void); +void test_gdi_MoveToEx(void); +void test_gdi_LineTo(void); +void test_gdi_Ellipse(void); +void test_gdi_PtInRect(void); +void test_gdi_FillRect(void); +void test_gdi_BitBlt_32bpp(void); +void test_gdi_BitBlt_16bpp(void); +void test_gdi_BitBlt_8bpp(void); +void test_gdi_ClipCoords(void); +void test_gdi_InvalidateRegion(void); diff --git a/cunit/test_librfx.c b/cunit/test_librfx.c new file mode 100644 index 0000000..8799959 --- /dev/null +++ b/cunit/test_librfx.c @@ -0,0 +1,410 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RemoteFX Codec Library Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The sample data comes from [MS-RDPRFX] 4.2.3, which is decoded into three + * vertical bands in red (21x64), green (23x64) and blue(20x64) color. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "rfx_types.h" +#include "rfx_bitstream.h" +#include "rfx_rlgr.h" +#include "rfx_differential.h" +#include "rfx_quantization.h" +#include "rfx_dwt.h" +#include "rfx_decode.h" +#include "rfx_encode.h" + +#include "test_librfx.h" + +static const uint8 y_data[] = +{ + 0x19, 0x82, 0x1d, 0x10, 0x62, 0x9d, 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb2, 0x88, + 0x52, 0xca, 0x21, 0x4b, 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb2, 0x88, 0x52, 0xca, 0x21, 0x4b, 0x28, + 0x85, 0x2c, 0xa2, 0x14, 0xb2, 0x88, 0x52, 0xca, 0x21, 0x4b, 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb2, + 0x88, 0x52, 0xca, 0x21, 0x4b, 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb2, 0x88, 0x52, 0xca, 0x21, 0x4b, + 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb2, 0x88, 0x52, 0xca, 0x21, 0x4b, 0x28, 0x85, 0x2c, 0xa2, 0x14, + 0xb2, 0x88, 0x52, 0xca, 0x21, 0x4b, 0x28, 0x85, 0x2c, 0xa2, 0x14, 0xb0, 0x00, 0x20, 0xf4, 0x40, + 0x0c, 0xc1, 0x1e, 0x20, 0x26, 0x22, 0x20, 0x33, 0x23, 0xc4, 0x23, 0x88, 0x86, 0x50, 0xf1, 0x22, + 0x68, 0x4c, 0x91, 0x85, 0x10, 0x34, 0x4c, 0x84, 0x78, 0xa2, 0x0d, 0x13, 0x21, 0x1e, 0x29, 0x06, + 0x89, 0x90, 0x8f, 0x14, 0x83, 0x44, 0xf4, 0x23, 0xc5, 0x20, 0xd1, 0x3d, 0x08, 0xf1, 0x48, 0x34, + 0x4f, 0x42, 0x3c, 0x52, 0x0d, 0x13, 0xd0, 0x8f, 0x14, 0x83, 0x44, 0xf4, 0x23, 0xc5, 0x20, 0xd1, + 0x3d, 0x08, 0xf1, 0x48, 0x34, 0x4f, 0x42, 0x3c, 0x52, 0x0d, 0x13, 0xd0, 0x8f, 0x14, 0x83, 0x44, + 0xf4, 0x23, 0xc5, 0x20, 0x00, 0x08, 0x47, 0x70, 0x15, 0x02, 0xe0, 0x7f, 0xe4, 0x9d, 0xc2, 0x51, + 0x71, 0xf4, 0x99, 0xc9, 0x57, 0xff, 0x32, 0x87, 0x9d, 0x17, 0xd6, 0x50, 0x6e, 0x06, 0x2f, 0xac, + 0xa0, 0x9c, 0x0c, 0x5f, 0x59, 0x41, 0x38, 0x18, 0xbe, 0xb2, 0x82, 0x70, 0x31, 0x7d, 0x65, 0x00, + 0x00, 0x10, 0xff, 0x9c, 0x33, 0x41, 0xf1, 0xc4, 0xb0, 0x3c, 0xff, 0xa2, 0x15, 0xbd, 0x7b, 0xea, + 0x86, 0x9b, 0x5f, 0xfc, 0x78, 0x8c, 0xf5, 0xed, 0xa8, 0x68, 0xda, 0xfd, 0x3c, 0x45, 0x7a, 0xf4, + 0xd4, 0x34, 0x6d, 0x7e, 0x9e, 0x22, 0xbd, 0x7a, 0x6a, 0x1a, 0x36, 0xbf, 0x4f, 0x11, 0x5e, 0xbd, + 0x35, 0x0d, 0x1b, 0x5f, 0xa7, 0x88, 0xaf, 0x5e, 0x9a, 0x86, 0x8d, 0xaf, 0xd3, 0xc4, 0x57, 0xaf, + 0x4d, 0x43, 0x46, 0xd7, 0xe9, 0xe2, 0x20, 0x30, 0x00 +}; + +static const uint8 cb_data[] = +{ + 0x1b, 0x04, 0x7f, 0x04, 0x31, 0x5f, 0xc2, + 0x94, 0xaf, 0x05, 0x29, 0x5e, 0x0a, 0x52, 0xbc, 0x14, 0xa5, 0x78, 0x29, 0x25, 0x78, 0x29, 0x25, + 0x78, 0x29, 0x25, 0x68, 0x52, 0x4a, 0xf0, 0x52, 0x4a, 0xf0, 0x52, 0x4a, 0xd0, 0xa4, 0x95, 0xe0, + 0xa4, 0x95, 0xe0, 0xa4, 0x95, 0xa1, 0x49, 0x2b, 0xc1, 0x49, 0x2b, 0xc1, 0x49, 0x2b, 0x42, 0x92, + 0x57, 0x82, 0x92, 0x57, 0x82, 0x92, 0x56, 0x85, 0x24, 0xaf, 0x05, 0x24, 0xaf, 0x05, 0x24, 0xad, + 0x0a, 0x49, 0x5e, 0x0a, 0x49, 0x5e, 0x0a, 0x49, 0x5a, 0x14, 0x92, 0xbc, 0x14, 0x92, 0xbc, 0x14, + 0x92, 0xb4, 0x29, 0x25, 0x78, 0x29, 0x25, 0x78, 0x00, 0x02, 0x0f, 0x02, 0x00, 0xac, 0x13, 0xfc, + 0xc0, 0x0a, 0x20, 0x10, 0x2b, 0x27, 0xf9, 0x80, 0xb0, 0x08, 0xaa, 0x3d, 0x60, 0x8c, 0x0b, 0x24, + 0xff, 0x30, 0x80, 0xc0, 0xaa, 0x13, 0xfc, 0xc2, 0x03, 0x05, 0x90, 0x9f, 0xe6, 0x10, 0x18, 0x2c, + 0x84, 0xff, 0x30, 0x81, 0x82, 0xc8, 0x4f, 0xf3, 0x08, 0x18, 0x2c, 0x84, 0xff, 0x31, 0x03, 0x05, + 0x90, 0x9f, 0xff, 0xd8, 0x40, 0x60, 0x59, 0x09, 0xfe, 0x61, 0x01, 0x81, 0x64, 0x27, 0xf9, 0x84, + 0x06, 0x0b, 0x21, 0x3f, 0xcc, 0x20, 0x30, 0x59, 0x09, 0xfe, 0x61, 0x03, 0x05, 0x90, 0x9f, 0xe6, + 0x10, 0x30, 0x59, 0x09, 0xfe, 0x62, 0x00, 0x00, 0x42, 0x15, 0x00, 0x10, 0x15, 0x01, 0xfe, 0x20, + 0x84, 0xd5, 0x01, 0x0a, 0x8f, 0xf1, 0x40, 0x33, 0x78, 0x17, 0xf9, 0xc2, 0x03, 0x83, 0x01, 0x78, + 0xe1, 0x01, 0xc1, 0x00, 0xbc, 0x70, 0x80, 0xe0, 0x80, 0x5e, 0x38, 0x40, 0x70, 0x40, 0x2f, 0x1c, + 0x20, 0x38, 0x20, 0x17, 0x8e, 0x10, 0x00, 0x00, 0x87, 0xd5, 0x08, 0x70, 0xef, 0x81, 0xa2, 0xd8, + 0xff, 0xff, 0xff, 0xfb, 0xd1, 0x2d, 0x4e, 0xa6, 0xce, 0x20, 0xa4, 0xef, 0x05, 0x78, 0x35, 0x3a, + 0x9b, 0x38, 0x82, 0x93, 0xbc, 0x15, 0xe0, 0xd4, 0xea, 0x66, 0x71, 0x05, 0x27, 0x78, 0x2b, 0xc1, + 0x29, 0xd4, 0xcc, 0xe2, 0x0a, 0x4e, 0xf0, 0x57, 0x82, 0x53, 0xa9, 0x99, 0xc4, 0x14, 0x9d, 0xe0, + 0xaf, 0x04, 0xa7, 0x53, 0x33, 0x88, 0x29, 0x3b, 0xc1, 0x5e, 0x09, 0x4e, 0xa6, 0x67, 0x10, 0x52, + 0x77, 0x82, 0xbc, 0x00, 0x18, 0x00 +}; + +static const uint8 cr_data[] = +{ + 0x1b, 0xfc, 0x11, 0xc1, 0x0f, 0x4a, 0xc1, 0x4f, 0x4a, 0xc1, + 0x4f, 0x4a, 0xa1, 0x4d, 0x95, 0x42, 0x9e, 0x95, 0x42, 0x9e, 0x95, 0x42, 0x9b, 0x2a, 0x85, 0x3d, + 0x2a, 0x85, 0x3d, 0x2a, 0x85, 0x36, 0x55, 0x0a, 0x7a, 0x55, 0x0a, 0x7a, 0x55, 0x0a, 0x6c, 0xaa, + 0x14, 0xf4, 0xaa, 0x14, 0xf4, 0xaa, 0x14, 0xd9, 0x54, 0x29, 0xe9, 0x54, 0x29, 0xe9, 0x54, 0x29, + 0xb2, 0xa8, 0x53, 0xd2, 0xa8, 0x53, 0xd2, 0xa8, 0x53, 0x65, 0x50, 0xa7, 0xa5, 0x50, 0xa7, 0xa5, + 0x50, 0xa6, 0xca, 0xa1, 0x4f, 0x4a, 0xa1, 0x4f, 0x4a, 0xa1, 0x4d, 0x95, 0x42, 0x9e, 0x95, 0x42, + 0x9e, 0x95, 0x42, 0x9b, 0x2a, 0x80, 0x00, 0x41, 0xe3, 0x80, 0x3f, 0xe2, 0x09, 0x9c, 0x00, 0x22, + 0x07, 0x03, 0xe1, 0x26, 0x70, 0x06, 0x07, 0x1f, 0x04, 0x67, 0x00, 0x61, 0xdf, 0x02, 0x67, 0x00, + 0x0c, 0x3b, 0xfe, 0x01, 0x33, 0x80, 0x06, 0x1d, 0xff, 0x00, 0x99, 0xc0, 0x03, 0x0e, 0xff, 0x80, + 0x4c, 0xe0, 0x01, 0x87, 0x7f, 0xc0, 0x26, 0x70, 0x00, 0xc3, 0xbf, 0xe0, 0x13, 0x38, 0x00, 0x61, + 0xdf, 0xf0, 0x09, 0x9c, 0x00, 0x30, 0xef, 0xf8, 0x04, 0xce, 0x00, 0x18, 0x77, 0xfc, 0x02, 0x67, + 0x00, 0x0c, 0x3b, 0xfe, 0x01, 0x33, 0x80, 0x06, 0x1d, 0xff, 0x00, 0x99, 0xc0, 0x03, 0x0e, 0xff, + 0x80, 0x4c, 0xe0, 0x01, 0x87, 0x7f, 0xc0, 0x26, 0x70, 0x00, 0x00, 0x08, 0x3c, 0x20, 0x1f, 0xf1, + 0x00, 0xf0, 0x05, 0x02, 0x93, 0x84, 0x3d, 0x20, 0xf0, 0x52, 0x81, 0xc7, 0xff, 0xff, 0xea, 0x54, + 0x01, 0x80, 0x05, 0xf5, 0x4a, 0x80, 0x30, 0x00, 0xb6, 0xa5, 0x40, 0x18, 0x00, 0x5f, 0x54, 0xa8, + 0x03, 0x00, 0x0b, 0xea, 0x95, 0x00, 0x60, 0x01, 0x6d, 0x4a, 0x80, 0x30, 0x00, 0x00, 0x22, 0x3f, + 0xba, 0x08, 0x10, 0x2b, 0x1f, 0xf2, 0x20, 0x3e, 0x49, 0x9c, 0x1f, 0x6e, 0x0f, 0x5a, 0x0f, 0xfb, + 0x18, 0x46, 0xae, 0x27, 0x9b, 0x83, 0xcb, 0x41, 0xf3, 0x18, 0x46, 0xae, 0x27, 0x9b, 0x83, 0xc5, + 0xa0, 0xf9, 0x8c, 0x22, 0xd7, 0x13, 0x8d, 0xc1, 0xe2, 0xd0, 0x7c, 0xc6, 0x11, 0x6b, 0x89, 0xc6, + 0xe0, 0xf1, 0x68, 0x3e, 0x63, 0x08, 0xb5, 0xc4, 0xe3, 0x70, 0x78, 0xb4, 0x1f, 0x31, 0x84, 0x5a, + 0xe2, 0x71, 0xb8, 0x3c, 0x5a, 0x0f, 0x98, 0xc2, 0x2d, 0x71, 0x30, 0x83, 0xc0, 0x00 +}; + +/* HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3 */ +static const unsigned int test_quantization_values[] = +{ + 6, 6, 6, 6, 7, 7, 8, 8, 8, 9 +}; + +static const uint8 rgb_scanline_data[] = +{ + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF +}; + +static uint8* rgb_data; + +int init_librfx_suite(void) +{ + return 0; +} + +int clean_librfx_suite(void) +{ + return 0; +} + +int add_librfx_suite(void) +{ + add_test_suite(librfx); + + add_test_function(bitstream); + add_test_function(bitstream_enc); + add_test_function(rlgr); + add_test_function(differential); + add_test_function(quantization); + add_test_function(dwt); + add_test_function(decode); + add_test_function(encode); + add_test_function(message); + + return 0; +} + +void test_bitstream(void) +{ + uint16 b; + RFX_BITSTREAM* bs; + + bs = xnew(RFX_BITSTREAM); + rfx_bitstream_attach(bs, (uint8*) y_data, sizeof(y_data)); + while (!rfx_bitstream_eos(bs)) + { + rfx_bitstream_get_bits(bs, 3, b); + (void) b; + //printf("%u ", b); + } + xfree(bs); + + //printf("\n"); +} + +void test_bitstream_enc(void) +{ + uint8 buffer[10]; + RFX_BITSTREAM* bs; + int i; + + bs = xnew(RFX_BITSTREAM); + memset(buffer, 0, sizeof(buffer)); + rfx_bitstream_attach(bs, buffer, sizeof(buffer)); + for (i = 0; i < 16; i++) + { + rfx_bitstream_put_bits(bs, i, 5); + } + /*for (i = 0; i < sizeof(buffer); i++) + { + printf("%X ", buffer[i]); + }*/ + xfree(bs); + + //printf("\n"); +} + +static sint16 buffer[4096]; + +void dump_buffer(sint16* buf, int n) +{ + int i; + + for (i = 0; i < n; i++) + { + if (i % 16 == 0) + printf("\n%04d ", i); + printf("% 4d ", buf[i]); + } + printf("\n"); +} + +void test_rlgr(void) +{ + int n; + + n = rfx_rlgr_decode(RLGR3, y_data, sizeof(y_data), buffer, sizeof(buffer) / sizeof(unsigned int)); + + //printf("RLGR decode %d bytes to %d values.", sizeof(y_data), n); + //dump_buffer(buffer, n); +} + +void test_differential(void) +{ + rfx_differential_decode(buffer + 4032, 64); + //dump_buffer(buffer + 4032, 64); +} + +void test_quantization(void) +{ + rfx_quantization_decode(buffer, test_quantization_values); + //dump_buffer(buffer, 4096); +} + +void test_dwt(void) +{ + RFX_CONTEXT* context; + + context = rfx_context_new(); + rfx_dwt_2d_decode(buffer, context->priv->dwt_buffer); + //dump_buffer(buffer, 4096); + rfx_context_free(context); +} + +/* Dump a .ppm image. */ +static void dump_ppm_image(uint8* image_buf) +{ + static int frame_id = 0; + char buf[100]; + FILE* fp; + + snprintf(buf, sizeof(buf), "/tmp/FreeRDP_Frame_%d.ppm", frame_id); + fp = fopen(buf, "wb"); + fwrite("P6\n", 1, 3, fp); + fwrite("# Created by FreeRDP\n", 1, 21, fp); + fwrite("64 64\n", 1, 6, fp); + fwrite("255\n", 1, 4, fp); + fwrite(image_buf, 1, 4096 * 3, fp); + fflush(fp); + fclose(fp); + frame_id++; +} + +void test_decode(void) +{ + RFX_CONTEXT* context; + uint8 decode_buffer[4096 * 3]; + STREAM* s; + + s = stream_new(sizeof(y_data) + sizeof(cb_data) + sizeof(cr_data)); + stream_write(s, y_data, sizeof(y_data)); + stream_write(s, cb_data, sizeof(cb_data)); + stream_write(s, cr_data, sizeof(cr_data)); + stream_set_pos(s, 0); + + context = rfx_context_new(); + context->mode = RLGR3; + rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB); + rfx_decode_rgb(context, s, + sizeof(y_data), test_quantization_values, + sizeof(cb_data), test_quantization_values, + sizeof(cr_data), test_quantization_values, + decode_buffer); + rfx_context_free(context); + stream_free(s); + + dump_ppm_image(decode_buffer); +} + +void test_encode(void) +{ + RFX_CONTEXT* context; + STREAM* enc_stream; + int y_size, cb_size, cr_size; + int i; + uint8 decode_buffer[4096 * 3]; + + rgb_data = (uint8 *) malloc(64 * 64 * 3); + for (i = 0; i < 64; i++) + memcpy(rgb_data + i * 64 * 3, rgb_scanline_data, 64 * 3); + //freerdp_hexdump(rgb_data, 64 * 64 * 3); + + enc_stream = stream_new(65536); + stream_clear(enc_stream); + + context = rfx_context_new(); + context->mode = RLGR3; + rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB); + + rfx_encode_rgb(context, rgb_data, 64, 64, 64 * 3, + test_quantization_values, test_quantization_values, test_quantization_values, + enc_stream, &y_size, &cb_size, &cr_size); + //dump_buffer(context->priv->cb_g_buffer, 4096); + + /*printf("*** Y ***\n"); + freerdp_hexdump(stream_get_head(enc_stream), y_size); + printf("*** Cb ***\n"); + freerdp_hexdump(stream_get_head(enc_stream) + y_size, cb_size); + printf("*** Cr ***\n"); + freerdp_hexdump(stream_get_head(enc_stream) + y_size + cb_size, cr_size);*/ + + stream_set_pos(enc_stream, 0); + rfx_decode_rgb(context, enc_stream, + y_size, test_quantization_values, + cb_size, test_quantization_values, + cr_size, test_quantization_values, + decode_buffer); + dump_ppm_image(decode_buffer); + + rfx_context_free(context); + stream_free(enc_stream); + free(rgb_data); +} + +void test_message(void) +{ + RFX_CONTEXT* context; + STREAM* s; + int i, j; + RFX_RECT rect = {0, 0, 100, 80}; + RFX_MESSAGE * message; + + rgb_data = (uint8 *) malloc(100 * 80 * 3); + for (i = 0; i < 80; i++) + memcpy(rgb_data + i * 100 * 3, rgb_scanline_data, 100 * 3); + + s = stream_new(65536); + stream_clear(s); + + context = rfx_context_new(); + context->mode = RLGR3; + context->width = 800; + context->height = 600; + rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB); + + for (i = 0; i < 1000; i++) + { + s = stream_new(65536); + stream_clear(s); + rfx_compose_message(context, s, + &rect, 1, rgb_data, 100, 80, 100 * 3); + stream_seal(s); + /*hexdump(buffer, size);*/ + stream_set_pos(s, 0); + message = rfx_process_message(context, s->p, s->size); + if (i == 0) + { + for (j = 0; j < message->num_tiles; j++) + { + dump_ppm_image(message->tiles[j]->data); + } + } + rfx_message_free(context, message); + stream_free(s); + } + + rfx_context_free(context); + free(rgb_data); +} diff --git a/cunit/test_librfx.h b/cunit/test_librfx.h new file mode 100644 index 0000000..f007816 --- /dev/null +++ b/cunit/test_librfx.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RemoteFX Codec Library Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_librfx_suite(void); +int clean_librfx_suite(void); +int add_librfx_suite(void); + +void test_bitstream(void); +void test_bitstream_enc(void); +void test_rlgr(void); +void test_differential(void); +void test_quantization(void); +void test_dwt(void); +void test_decode(void); +void test_encode(void); +void test_message(void); diff --git a/cunit/test_license.c b/cunit/test_license.c new file mode 100644 index 0000000..49e7e04 --- /dev/null +++ b/cunit/test_license.c @@ -0,0 +1,499 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Licensing Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "license.h" + +#include +#include +#include + +#include "test_license.h" + +rdpRdp* rdp; +rdpLicense* license; + +int init_license_suite(void) +{ + rdp = rdp_new(NULL); + license = rdp->license; + return 0; +} + +int clean_license_suite(void) +{ + rdp_free(rdp); + return 0; +} + +int add_license_suite(void) +{ + add_test_suite(license); + + add_test_function(license); + //add_test_function(license_generate_keys); + //add_test_function(license_encrypt_premaster_secret); + add_test_function(license_decrypt_platform_challenge); + + return 0; +} + +/* Server License Request (2200 bytes) */ + +uint8 server_license_request[2200] = + "\x01\x03\x98\x08\x84\xef\xae\x20\xb1\xd5\x9e\x36\x49\x1a\xe8\x2e" + "\x0a\x99\x89\xac\x49\xa6\x47\x4f\x33\x9b\x5a\xb9\x95\x03\xa6\xc6" + "\xc2\x3c\x3f\x61\x00\x00\x06\x00\x2c\x00\x00\x00\x4d\x00\x69\x00" + "\x63\x00\x72\x00\x6f\x00\x73\x00\x6f\x00\x66\x00\x74\x00\x20\x00" + "\x43\x00\x6f\x00\x72\x00\x70\x00\x6f\x00\x72\x00\x61\x00\x74\x00" + "\x69\x00\x6f\x00\x6e\x00\x00\x00\x08\x00\x00\x00\x41\x00\x30\x00" + "\x32\x00\x00\x00\x0d\x00\x04\x00\x01\x00\x00\x00\x03\x00\x12\x08" + "\x02\x00\x00\x80\x02\x00\x00\x00\xf5\x02\x00\x00\x30\x82\x02\xf1" + "\x30\x82\x01\xdd\xa0\x03\x02\x01\x02\x02\x08\x01\x9e\x24\xa2\xf2" + "\xae\x90\x80\x30\x09\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x30\x32" + "\x31\x30\x30\x13\x06\x03\x55\x04\x03\x1e\x0c\x00\x52\x00\x4f\x00" + "\x44\x00\x45\x00\x4e\x00\x54\x30\x19\x06\x03\x55\x04\x07\x1e\x12" + "\x00\x57\x00\x4f\x00\x52\x00\x4b\x00\x47\x00\x52\x00\x4f\x00\x55" + "\x00\x50\x30\x1e\x17\x0d\x37\x30\x30\x35\x32\x37\x30\x31\x31\x31" + "\x30\x33\x5a\x17\x0d\x34\x39\x30\x35\x32\x37\x30\x31\x31\x31\x30" + "\x33\x5a\x30\x32\x31\x30\x30\x13\x06\x03\x55\x04\x03\x1e\x0c\x00" + "\x52\x00\x4f\x00\x44\x00\x45\x00\x4e\x00\x54\x30\x19\x06\x03\x55" + "\x04\x07\x1e\x12\x00\x57\x00\x4f\x00\x52\x00\x4b\x00\x47\x00\x52" + "\x00\x4f\x00\x55\x00\x50\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86" + "\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82" + "\x01\x0a\x02\x82\x01\x01\x00\x88\xad\x7c\x8f\x8b\x82\x76\x5a\xbd" + "\x8f\x6f\x62\x18\xe1\xd9\xaa\x41\xfd\xed\x68\x01\xc6\x34\x35\xb0" + "\x29\x04\xca\x4a\x4a\x1c\x7e\x80\x14\xf7\x8e\x77\xb8\x25\xff\x16" + "\x47\x6f\xbd\xe2\x34\x3d\x2e\x02\xb9\x53\xe4\x33\x75\xad\x73\x28" + "\x80\xa0\x4d\xfc\x6c\xc0\x22\x53\x1b\x2c\xf8\xf5\x01\x60\x19\x7e" + "\x79\x19\x39\x8d\xb5\xce\x39\x58\xdd\x55\x24\x3b\x55\x7b\x43\xc1" + "\x7f\x14\x2f\xb0\x64\x3a\x54\x95\x2b\x88\x49\x0c\x61\x2d\xac\xf8" + "\x45\xf5\xda\x88\x18\x5f\xae\x42\xf8\x75\xc7\x26\x6d\xb5\xbb\x39" + "\x6f\xcc\x55\x1b\x32\x11\x38\x8d\xe4\xe9\x44\x84\x11\x36\xa2\x61" + "\x76\xaa\x4c\xb4\xe3\x55\x0f\xe4\x77\x8e\xde\xe3\xa9\xea\xb7\x41" + "\x94\x00\x58\xaa\xc9\x34\xa2\x98\xc6\x01\x1a\x76\x14\x01\xa8\xdc" + "\x30\x7c\x77\x5a\x20\x71\x5a\xa2\x3f\xaf\x13\x7e\xe8\xfd\x84\xa2" + "\x5b\xcf\x25\xe9\xc7\x8f\xa8\xf2\x8b\x84\xc7\x04\x5e\x53\x73\x4e" + "\x0e\x89\xa3\x3c\xe7\x68\x5c\x24\xb7\x80\x53\x3c\x54\xc8\xc1\x53" + "\xaa\x71\x71\x3d\x36\x15\xd6\x6a\x9d\x7d\xde\xae\xf9\xe6\xaf\x57" + "\xae\xb9\x01\x96\x5d\xe0\x4d\xcd\xed\xc8\xd7\xf3\x01\x03\x38\x10" + "\xbe\x7c\x42\x67\x01\xa7\x23\x02\x03\x01\x00\x01\xa3\x13\x30\x11" + "\x30\x0f\x06\x03\x55\x1d\x13\x04\x08\x30\x06\x01\x01\xff\x02\x01" + "\x00\x30\x09\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x03\x82\x01\x01" + "\x00\x81\xdd\xd2\xd3\x33\xd4\xa3\xb6\x8e\x6e\x7d\x9f\xfd\x73\x9f" + "\x31\x0b\xdd\x42\x82\x3f\x7e\x21\xdf\x28\xcc\x59\xca\x6a\xc0\xa9" + "\x3d\x30\x7d\xe1\x91\xdb\x77\x6b\x8b\x10\xe6\xfd\xbc\x3c\xa3\x58" + "\x48\xc2\x36\xdd\xa0\x0b\xf5\x8e\x13\xda\x7b\x04\x08\x44\xb4\xf2" + "\xa8\x0d\x1e\x0b\x1d\x1a\x3f\xf9\x9b\x4b\x5a\x54\xc5\xb3\xb4\x03" + "\x93\x75\xb3\x72\x5c\x3d\xcf\x63\x0f\x15\xe1\x64\x58\xde\x52\x8d" + "\x97\x79\x0e\xa4\x34\xd5\x66\x05\x58\xb8\x6e\x79\xb2\x09\x86\xd5" + "\xf0\xed\xc4\x6b\x4c\xab\x02\xb8\x16\x5f\x3b\xed\x88\x5f\xd1\xde" + "\x44\xe3\x73\x47\x21\xf7\x03\xce\xe1\x6d\x10\x0f\x95\xcf\x7c\xa2" + "\x7a\xa6\xbf\x20\xdb\xe1\x93\x04\xc8\x5e\x6a\xbe\xc8\x01\x5d\x27" + "\xb2\x03\x0f\x66\x75\xe7\xcb\xea\x8d\x4e\x98\x9d\x22\xed\x28\x40" + "\xd2\x7d\xa4\x4b\xef\xcc\xbf\x01\x2a\x6d\x3a\x3e\xbe\x47\x38\xf8" + "\xea\xa4\xc6\x30\x1d\x5e\x25\xcf\xfb\xe8\x3d\x42\xdd\x29\xe8\x99" + "\x89\x9e\xbf\x39\xee\x77\x09\xd9\x3e\x8b\x52\x36\xb6\xbb\x8b\xbd" + "\x0d\xb2\x52\xaa\x2c\xcf\x38\x4e\x4d\xcf\x1d\x6d\x5d\x25\x17\xac" + "\x2c\xf6\xf0\x65\x5a\xc9\xfe\x31\x53\xb4\xf0\x0c\x94\x4e\x0d\x54" + "\x8e\xfd\x04\x00\x00\x30\x82\x04\xf9\x30\x82\x03\xe5\xa0\x03\x02" + "\x01\x02\x02\x05\x01\x00\x00\x00\x02\x30\x09\x06\x05\x2b\x0e\x03" + "\x02\x1d\x05\x00\x30\x32\x31\x30\x30\x13\x06\x03\x55\x04\x03\x1e" + "\x0c\x00\x52\x00\x4f\x00\x44\x00\x45\x00\x4e\x00\x54\x30\x19\x06" + "\x03\x55\x04\x07\x1e\x12\x00\x57\x00\x4f\x00\x52\x00\x4b\x00\x47" + "\x00\x52\x00\x4f\x00\x55\x00\x50\x30\x1e\x17\x0d\x30\x37\x30\x35" + "\x32\x36\x31\x32\x34\x35\x35\x33\x5a\x17\x0d\x33\x38\x30\x31\x31" + "\x39\x30\x33\x31\x34\x30\x37\x5a\x30\x81\x92\x31\x81\x8f\x30\x23" + "\x06\x03\x55\x04\x03\x1e\x1c\x00\x6e\x00\x63\x00\x61\x00\x6c\x00" + "\x72\x00\x70\x00\x63\x00\x3a\x00\x52\x00\x4f\x00\x44\x00\x45\x00" + "\x4e\x00\x54\x30\x23\x06\x03\x55\x04\x07\x1e\x1c\x00\x6e\x00\x63" + "\x00\x61\x00\x6c\x00\x72\x00\x70\x00\x63\x00\x3a\x00\x52\x00\x4f" + "\x00\x44\x00\x45\x00\x4e\x00\x54\x30\x43\x06\x03\x55\x04\x05\x1e" + "\x3c\x00\x31\x00\x42\x00\x63\x00\x4b\x00\x65\x00\x62\x00\x68\x00" + "\x70\x00\x58\x00\x5a\x00\x74\x00\x4c\x00\x71\x00\x4f\x00\x37\x00" + "\x53\x00\x51\x00\x6e\x00\x42\x00\x70\x00\x52\x00\x66\x00\x75\x00" + "\x64\x00\x64\x00\x64\x00\x59\x00\x3d\x00\x0d\x00\x0a\x30\x82\x01" + "\x1e\x30\x09\x06\x05\x2b\x0e\x03\x02\x0f\x05\x00\x03\x82\x01\x0f" + "\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xc8\x90\x6b\xf0\xc6\x58" + "\x81\xa6\x89\x1c\x0e\xf2\xf6\xd9\x82\x12\x71\xa5\x6e\x51\xdb\xe0" + "\x32\x66\xaa\x91\x77\x0e\x88\xab\x44\xb7\xd3\x97\xda\x78\x8f\x0e" + "\x44\x26\x46\x7f\x16\xd4\xc6\x63\xeb\xca\x55\xe5\x4e\x8b\x2d\xa6" + "\x6d\x83\x95\xa7\xa8\x6a\xfa\xd0\xbe\x26\x80\xae\xab\x0a\x64\x90" + "\x32\x8c\xdf\x5c\xf8\xf9\xd0\x7e\xd1\x6b\x3a\x29\x7e\x7d\xbd\x02" + "\xa3\x86\x6c\xfd\xa5\x35\x71\xda\x21\xb4\xee\xa4\x97\xf3\xa8\xb2" + "\x12\xdb\xa4\x27\x57\x36\xc9\x08\x22\x5c\x54\xf7\x99\x7b\xa3\x2f" + "\xb8\x5c\xd5\x16\xb8\x19\x27\x6b\x71\x97\x14\x5b\xe8\x1f\x23\xe8" + "\x5c\xb8\x1b\x73\x4b\x6e\x7a\x03\x13\xff\x97\xe9\x62\xb9\x4a\xa0" + "\x51\x23\xc3\x6c\x32\x3e\x02\xf2\x63\x97\x23\x1c\xc5\x78\xd8\xfc" + "\xb7\x07\x4b\xb0\x56\x0f\x74\xdf\xc5\x56\x28\xe4\x96\xfd\x20\x8e" + "\x65\x5a\xe6\x45\xed\xc1\x05\x3e\xab\x58\x55\x40\xaf\xe2\x47\xa0" + "\x4c\x49\xa3\x8d\x39\xe3\x66\x5f\x93\x33\x6d\xf8\x5f\xc5\x54\xe5" + "\xfb\x57\x3a\xde\x45\x12\xb5\xc7\x05\x4b\x88\x1f\xb4\x35\x0f\x7c" + "\xc0\x75\x17\xc6\x67\xdd\x48\x80\xcb\x0a\xbe\x9d\xf6\x93\x60\x65" + "\x34\xeb\x97\xaf\x65\x6d\xdf\xbf\x6f\x5b\x02\x03\x01\x00\x01\xa3" + "\x82\x01\xbf\x30\x82\x01\xbb\x30\x14\x06\x09\x2b\x06\x01\x04\x01" + "\x82\x37\x12\x04\x01\x01\xff\x04\x04\x01\x00\x05\x00\x30\x3c\x06" + "\x09\x2b\x06\x01\x04\x01\x82\x37\x12\x02\x01\x01\xff\x04\x2c\x4d" + "\x00\x69\x00\x63\x00\x72\x00\x6f\x00\x73\x00\x6f\x00\x66\x00\x74" + "\x00\x20\x00\x43\x00\x6f\x00\x72\x00\x70\x00\x6f\x00\x72\x00\x61" + "\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x00\x00\x30\x81\xcd\x06\x09" + "\x2b\x06\x01\x04\x01\x82\x37\x12\x05\x01\x01\xff\x04\x81\xbc\x00" + "\x30\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x09\x04\x00\x00\x1c" + "\x00\x4a\x00\x66\x00\x4a\x00\xb0\x00\x01\x00\x33\x00\x64\x00\x32" + "\x00\x36\x00\x37\x00\x39\x00\x35\x00\x34\x00\x2d\x00\x65\x00\x65" + "\x00\x62\x00\x37\x00\x2d\x00\x31\x00\x31\x00\x64\x00\x31\x00\x2d" + "\x00\x62\x00\x39\x00\x34\x00\x65\x00\x2d\x00\x30\x00\x30\x00\x63" + "\x00\x30\x00\x34\x00\x66\x00\x61\x00\x33\x00\x30\x00\x38\x00\x30" + "\x00\x64\x00\x00\x00\x33\x00\x64\x00\x32\x00\x36\x00\x37\x00\x39" + "\x00\x35\x00\x34\x00\x2d\x00\x65\x00\x65\x00\x62\x00\x37\x00\x2d" + "\x00\x31\x00\x31\x00\x64\x00\x31\x00\x2d\x00\x62\x00\x39\x00\x34" + "\x00\x65\x00\x2d\x00\x30\x00\x30\x00\x63\x00\x30\x00\x34\x00\x66" + "\x00\x61\x00\x33\x00\x30\x00\x38\x00\x30\x00\x64\x00\x00\x00\x00" + "\x00\x00\x10\x00\x80\x64\x00\x00\x00\x00\x00\x30\x6e\x06\x09\x2b" + "\x06\x01\x04\x01\x82\x37\x12\x06\x01\x01\xff\x04\x5e\x00\x30\x00" + "\x00\x00\x00\x0e\x00\x3e\x00\x52\x00\x4f\x00\x44\x00\x45\x00\x4e" + "\x00\x54\x00\x00\x00\x37\x00\x38\x00\x34\x00\x34\x00\x30\x00\x2d" + "\x00\x30\x00\x30\x00\x36\x00\x2d\x00\x35\x00\x38\x00\x36\x00\x37" + "\x00\x30\x00\x34\x00\x35\x00\x2d\x00\x37\x00\x30\x00\x33\x00\x34" + "\x00\x37\x00\x00\x00\x57\x00\x4f\x00\x52\x00\x4b\x00\x47\x00\x52" + "\x00\x4f\x00\x55\x00\x50\x00\x00\x00\x00\x00\x30\x25\x06\x03\x55" + "\x1d\x23\x01\x01\xff\x04\x1b\x30\x19\xa1\x10\xa4\x0e\x52\x00\x4f" + "\x00\x44\x00\x45\x00\x4e\x00\x54\x00\x00\x00\x82\x05\x01\x00\x00" + "\x00\x02\x30\x09\x06\x05\x2b\x0e\x03\x02\x1d\x05\x00\x03\x82\x01" + "\x01\x00\x2e\xeb\xc7\x0d\xb8\x1d\x47\x11\x9d\x09\x88\x9b\x51\xdc" + "\x45\xdd\x56\x51\xe2\xd1\x23\x11\x39\x9b\x2d\xda\xc7\xfe\x7a\xd7" + "\x84\xe3\x3d\x54\x77\x97\x4d\x19\x92\x30\x64\xa0\x47\xc6\x2f\x6d" + "\x93\xd2\x64\x7c\x76\xc8\x26\x45\xad\x5a\x44\x54\xea\xf6\x4b\x28" + "\x77\x1f\x77\xea\xec\x74\x02\x38\x68\x9e\x79\x14\x72\x83\x34\x74" + "\x62\xd2\xc1\x0c\xa4\x0b\xf2\xa9\xb0\x38\xbb\x7c\xd0\xae\xbe\xbf" + "\x74\x47\x16\xa0\xa2\xd3\xfc\x1d\xb9\xba\x26\x10\x06\xef\xba\x1d" + "\x43\x01\x4e\x4e\x6f\x56\xca\xe0\xee\xd0\xf9\x4e\xa6\x62\x63\xff" + "\xda\x0b\xc9\x15\x61\x6c\xed\x6b\x0b\xc4\x58\x53\x86\x0f\x8c\x0c" + "\x1a\x2e\xdf\xc1\xf2\x43\x48\xd4\xaf\x0a\x78\x36\xb2\x51\x32\x28" + "\x6c\xc2\x75\x79\x3f\x6e\x99\x66\x88\x3e\x34\xd3\x7f\x6d\x9d\x07" + "\xe4\x6b\xeb\x84\xe2\x0a\xbb\xca\x7d\x3a\x40\x71\xb0\xbe\x47\x9f" + "\x12\x58\x31\x61\x2b\x9b\x4a\x9a\x49\x8f\xe5\xb4\x0c\xf5\x04\x4d" + "\x3c\xce\xbc\xd2\x79\x15\xd9\x28\xf4\x23\x56\x77\x9f\x38\x64\x3e" + "\x03\x88\x92\x04\x26\x76\xb9\xb5\xdf\x19\xd0\x78\x4b\x7a\x60\x40" + "\x23\x91\xf1\x15\x22\x2b\xb4\xe7\x02\x54\xa9\x16\x21\x5b\x60\x96" + "\xa9\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x01\x00\x00\x00\x0e\x00\x0e\x00\x6d\x69\x63\x72\x6f\x73" + "\x6f\x66\x74\x2e\x63\x6f\x6d\x00"; + +/* Client New License Request (341 bytes) */ + +uint8 client_new_license_request[341] = + "\x13\x83\x55\x01\x01\x00\x00\x00\x00\x00\x01\x04\xdc\x73\xa0\xc8" + "\x69\x25\x6b\x18\xaf\x0b\x94\x7a\xa9\xa5\x20\xaf\x8b\xbc\x0d\xcc" + "\xa3\x95\xb7\xb9\xeb\x81\x5d\xbe\x0a\x10\x9c\xd8\x02\x00\x08\x01" + "\xda\x9c\x5d\xa6\x68\x9d\xa3\x90\x67\x24\xf3\x3a\xea\xa1\xe2\x68" + "\xad\x12\xf5\xf6\x0b\x7a\xac\x92\xb1\x69\x6f\x42\x55\x8a\xa0\xe2" + "\x9b\x2c\xd0\xc7\xee\x33\x6c\x47\x79\xc3\x1e\xbf\x03\x8b\x95\x70" + "\x07\xa2\xbe\xee\x54\x02\x68\xf8\x90\xd7\xfe\x2c\x08\xe1\x6b\x2d" + "\xff\x94\x76\x72\x5f\x7a\x76\x75\x32\x55\xcc\x58\x61\x63\xa5\x64" + "\xf1\x6e\xc3\x07\x81\x82\x6f\x88\x73\x62\xfc\x28\x65\x91\xc2\xc8" + "\x9f\x05\xb0\xd3\x93\x12\xbf\x6a\x50\x18\x99\x2d\x4d\xc4\x7f\x74" + "\xd3\x30\x9f\x16\x78\xa5\xdf\xaa\x83\x65\x4f\x77\x30\x42\xe0\xd7" + "\x69\xc8\x4d\xa5\x73\x11\x59\x35\xb9\xa7\xe2\xb0\xf6\xe3\xb9\x39" + "\xc3\xd4\xe4\x6b\xca\x40\x9a\xac\x66\xe6\x1a\xa4\x1b\x39\x7e\x09" + "\xe3\x72\x99\xdd\x90\x62\x55\x97\xa9\x04\xc7\x51\xaa\xa2\x01\xcb" + "\x5a\x63\x4d\x1a\xe5\x99\xc3\xb1\x2a\x73\xe8\x9a\x00\x46\x92\x59" + "\x39\xa3\x80\xa1\xac\x90\x52\xea\x63\x81\x49\x7d\xf3\x2d\x5c\xc3" + "\x19\x9f\xed\xfe\x81\x1d\x8c\x04\x1c\xd9\x23\xd2\x6d\x80\x84\xf3" + "\x00\xf2\xb1\x69\x2f\xcd\xb3\x9f\x69\xee\x60\x3e\x4b\xb5\xbe\x5a" + "\x09\x83\x0b\xbc\x3d\x3e\x05\x47\x65\x96\x31\x8c\x6b\xc5\xe6\xa0" + "\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x0e\x00\x41\x64\x6d\x69" + "\x6e\x69\x73\x74\x72\x61\x74\x6f\x72\x00\x10\x00\x07\x00\x52\x4f" + "\x44\x45\x4e\x54\x00"; + +/* Server Platform Challenge (38 bytes) */ + +uint8 server_platform_challenge[38] = + "\x02\x03\x26\x00\xff\xff\xff\xff\x50\xf7\x0a\x00\x46\x37\x85\x54" + "\x8e\xc5\x91\x34\x97\x5d\x78\x94\xad\x3b\x81\xda\x88\x18\x56\x0f" + "\x3a\xd1\xf1\x03\xef\x35"; + +/* Client Platform Challenge Response (66 bytes) */ + +uint8 client_platform_challenge_response[66] = + "\x15\x83\x42\x00\x01\x00\x12\x00\xfa\xb4\xe8\x24\xcf\x56\xb2\x4e" + "\x80\x02\xbd\xb6\x61\xfc\xdf\xe9\x6c\x44\x01\x00\x14\x00\xf8\xb5" + "\xe8\x25\x3d\x0f\x3f\x70\x1d\xda\x60\x19\x16\xfe\x73\x1a\x45\x7e" + "\x02\x71\x38\x23\x62\x5d\x10\x8b\x93\xc3\xf1\xe4\x67\x1f\x4a\xb6" + "\x00\x0a"; + +uint8 license_server_modulus[256] = + "\x88\xad\x7c\x8f\x8b\x82\x76\x5a\xbd\x8f\x6f\x62\x18\xe1\xd9\xaa" + "\x41\xfd\xed\x68\x01\xc6\x34\x35\xb0\x29\x04\xca\x4a\x4a\x1c\x7e" + "\x80\x14\xf7\x8e\x77\xb8\x25\xff\x16\x47\x6f\xbd\xe2\x34\x3d\x2e" + "\x02\xb9\x53\xe4\x33\x75\xad\x73\x28\x80\xa0\x4d\xfc\x6c\xc0\x22" + "\x53\x1b\x2c\xf8\xf5\x01\x60\x19\x7e\x79\x19\x39\x8d\xb5\xce\x39" + "\x58\xdd\x55\x24\x3b\x55\x7b\x43\xc1\x7f\x14\x2f\xb0\x64\x3a\x54" + "\x95\x2b\x88\x49\x0c\x61\x2d\xac\xf8\x45\xf5\xda\x88\x18\x5f\xae" + "\x42\xf8\x75\xc7\x26\x6d\xb5\xbb\x39\x6f\xcc\x55\x1b\x32\x11\x38" + "\x8d\xe4\xe9\x44\x84\x11\x36\xa2\x61\x76\xaa\x4c\xb4\xe3\x55\x0f" + "\xe4\x77\x8e\xde\xe3\xa9\xea\xb7\x41\x94\x00\x58\xaa\xc9\x34\xa2" + "\x98\xc6\x01\x1a\x76\x14\x01\xa8\xdc\x30\x7c\x77\x5a\x20\x71\x5a" + "\xa2\x3f\xaf\x13\x7e\xe8\xfd\x84\xa2\x5b\xcf\x25\xe9\xc7\x8f\xa8" + "\xf2\x8b\x84\xc7\x04\x5e\x53\x73\x4e\x0e\x89\xa3\x3c\xe7\x68\x5c" + "\x24\xb7\x80\x53\x3c\x54\xc8\xc1\x53\xaa\x71\x71\x3d\x36\x15\xd6" + "\x6a\x9d\x7d\xde\xae\xf9\xe6\xaf\x57\xae\xb9\x01\x96\x5d\xe0\x4d" + "\xcd\xed\xc8\xd7\xf3\x01\x03\x38\x10\xbe\x7c\x42\x67\x01\xa7\x23"; + +uint8 license_server_exponent[4] = "\x00\x01\x00\x01"; + +uint8 terminal_server_modulus[256] = + "\xc8\x90\x6b\xf0\xc6\x58\x81\xa6\x89\x1c\x0e\xf2\xf6\xd9\x82\x12" + "\x71\xa5\x6e\x51\xdb\xe0\x32\x66\xaa\x91\x77\x0e\x88\xab\x44\xb7" + "\xd3\x97\xda\x78\x8f\x0e\x44\x26\x46\x7f\x16\xd4\xc6\x63\xeb\xca" + "\x55\xe5\x4e\x8b\x2d\xa6\x6d\x83\x95\xa7\xa8\x6a\xfa\xd0\xbe\x26" + "\x80\xae\xab\x0a\x64\x90\x32\x8c\xdf\x5c\xf8\xf9\xd0\x7e\xd1\x6b" + "\x3a\x29\x7e\x7d\xbd\x02\xa3\x86\x6c\xfd\xa5\x35\x71\xda\x21\xb4" + "\xee\xa4\x97\xf3\xa8\xb2\x12\xdb\xa4\x27\x57\x36\xc9\x08\x22\x5c" + "\x54\xf7\x99\x7b\xa3\x2f\xb8\x5c\xd5\x16\xb8\x19\x27\x6b\x71\x97" + "\x14\x5b\xe8\x1f\x23\xe8\x5c\xb8\x1b\x73\x4b\x6e\x7a\x03\x13\xff" + "\x97\xe9\x62\xb9\x4a\xa0\x51\x23\xc3\x6c\x32\x3e\x02\xf2\x63\x97" + "\x23\x1c\xc5\x78\xd8\xfc\xb7\x07\x4b\xb0\x56\x0f\x74\xdf\xc5\x56" + "\x28\xe4\x96\xfd\x20\x8e\x65\x5a\xe6\x45\xed\xc1\x05\x3e\xab\x58" + "\x55\x40\xaf\xe2\x47\xa0\x4c\x49\xa3\x8d\x39\xe3\x66\x5f\x93\x33" + "\x6d\xf8\x5f\xc5\x54\xe5\xfb\x57\x3a\xde\x45\x12\xb5\xc7\x05\x4b" + "\x88\x1f\xb4\x35\x0f\x7c\xc0\x75\x17\xc6\x67\xdd\x48\x80\xcb\x0a" + "\xbe\x9d\xf6\x93\x60\x65\x34\xeb\x97\xaf\x65\x6d\xdf\xbf\x6f\x5b"; + +uint8 terminal_server_exponent[4] = "\x00\x01\x00\x01"; + +uint8 client_random[32] = + "\xdc\x73\xa0\xc8\x69\x25\x6b\x18\xaf\x0b\x94\x7a\xa9\xa5\x20\xaf" + "\x8b\xbc\x0d\xcc\xa3\x95\xb7\xb9\xeb\x81\x5d\xbe\x0a\x10\x9c\xd8"; + +uint8 server_random[32] = + "\x84\xef\xae\x20\xb1\xd5\x9e\x36\x49\x1a\xe8\x2e\x0a\x99\x89\xac" + "\x49\xa6\x47\x4f\x33\x9b\x5a\xb9\x95\x03\xa6\xc6\xc2\x3c\x3f\x61"; + +uint8 premaster_secret[48] = + "\xcf\x7a\xdb\xcb\xfb\x0e\x15\x23\x87\x1c\x84\x81\xba\x9d\x4e\x15" + "\xbb\xd2\x56\xbd\xd8\xf7\xf3\x16\xcc\x35\x3b\xe1\x93\x42\x78\xdd" + "\x92\x9a\xe4\x7a\xe2\x99\xd4\x73\xb1\xaa\x6f\x55\x94\x3b\xc9\xbc"; + +uint8 encrypted_premaster_secret[264] = + "\xda\x9c\x5d\xa6\x68\x9d\xa3\x90\x67\x24\xf3\x3a\xea\xa1\xe2\x68" + "\xad\x12\xf5\xf6\x0b\x7a\xac\x92\xb1\x69\x6f\x42\x55\x8a\xa0\xe2" + "\x9b\x2c\xd0\xc7\xee\x33\x6c\x47\x79\xc3\x1e\xbf\x03\x8b\x95\x70" + "\x07\xa2\xbe\xee\x54\x02\x68\xf8\x90\xd7\xfe\x2c\x08\xe1\x6b\x2d" + "\xff\x94\x76\x72\x5f\x7a\x76\x75\x32\x55\xcc\x58\x61\x63\xa5\x64" + "\xf1\x6e\xc3\x07\x81\x82\x6f\x88\x73\x62\xfc\x28\x65\x91\xc2\xc8" + "\x9f\x05\xb0\xd3\x93\x12\xbf\x6a\x50\x18\x99\x2d\x4d\xc4\x7f\x74" + "\xd3\x30\x9f\x16\x78\xa5\xdf\xaa\x83\x65\x4f\x77\x30\x42\xe0\xd7" + "\x69\xc8\x4d\xa5\x73\x11\x59\x35\xb9\xa7\xe2\xb0\xf6\xe3\xb9\x39" + "\xc3\xd4\xe4\x6b\xca\x40\x9a\xac\x66\xe6\x1a\xa4\x1b\x39\x7e\x09" + "\xe3\x72\x99\xdd\x90\x62\x55\x97\xa9\x04\xc7\x51\xaa\xa2\x01\xcb" + "\x5a\x63\x4d\x1a\xe5\x99\xc3\xb1\x2a\x73\xe8\x9a\x00\x46\x92\x59" + "\x39\xa3\x80\xa1\xac\x90\x52\xea\x63\x81\x49\x7d\xf3\x2d\x5c\xc3" + "\x19\x9f\xed\xfe\x81\x1d\x8c\x04\x1c\xd9\x23\xd2\x6d\x80\x84\xf3" + "\x00\xf2\xb1\x69\x2f\xcd\xb3\x9f\x69\xee\x60\x3e\x4b\xb5\xbe\x5a" + "\x09\x83\x0b\xbc\x3d\x3e\x05\x47\x65\x96\x31\x8c\x6b\xc5\xe6\xa0" + "\x00\x00\x00\x00\x00\x00\x00\x00"; + +uint8 platform_challenge[10] = "\x54\x00\x45\x00\x53\x00\x54\x00\x00\x00"; + +void test_license(void) +{ + STREAM _s, *s; + + s = &_s; + memcpy(license->client_random, client_random, sizeof(client_random)); + memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret)); + + s->data = server_license_request; + s->p = s->data + LICENSE_PREAMBLE_LENGTH; + license_read_license_request_packet(license, s); + +#if 0 + printf("\n"); + + printf("client random:\n"); + freerdp_hexdump(license->client_random, 32); + printf("\n"); + + printf("server random:\n"); + freerdp_hexdump(license->server_random, 32); + printf("\n"); + + printf("premaster secret:\n"); + freerdp_hexdump(license->premaster_secret, 48); + printf("\n"); + + printf("master secret:\n"); + freerdp_hexdump(license->master_secret, 48); + printf("\n"); + + printf("session key blob:\n"); + freerdp_hexdump(license->session_key_blob, 48); + printf("\n"); + + printf("licensing encryption key:\n"); + freerdp_hexdump(license->licensing_encryption_key, 16); + printf("\n"); + + printf("mac salt key:\n"); + freerdp_hexdump(license->mac_salt_key, 16); + printf("\n"); + + printf("modulus:\n"); + freerdp_hexdump(license->certificate->cert_info.modulus.data, + license->certificate->cert_info.modulus.length); + printf("\n"); + + printf("exponent:\n"); + freerdp_hexdump(license->certificate->cert_info.exponent, 4); + printf("\n"); + + printf("encrypted premaster secret:\n"); + freerdp_hexdump(license->encrypted_premaster_secret->data, + license->encrypted_premaster_secret->length); + printf("\n"); +#endif + + s->data = server_platform_challenge; + s->p = s->data + LICENSE_PREAMBLE_LENGTH; + license_read_platform_challenge_packet(license, s); +} + +uint8 test_client_random[32] = + "\xdc\x73\xa0\xc8\x69\x25\x6b\x18\xaf\x0b\x94\x7a\xa9\xa5\x20\xaf" + "\x8b\xbc\x0d\xcc\xa3\x95\xb7\xb9\xeb\x81\x5d\xbe\x0a\x10\x9c\xd8"; + +uint8 test_server_random[32] = + "\x16\x7e\xf8\x71\x48\x16\x1a\x4f\xa5\x2c\xcd\x73\x63\x60\xa6\xc3" + "\xb9\x19\x1b\x4b\x6b\xb2\x0a\xb8\xec\xf1\x8d\x95\x4e\xa8\x21\xc5"; + +uint8 test_premaster_secret[48] = + "\xcf\x7a\xdb\xcb\xfb\x0e\x15\x23\x87\x1c\x84\x81\xba\x9d\x4e\x15" + "\xbb\xd2\x56\xbd\xd8\xf7\xf3\x16\xcc\x35\x3b\xe1\x93\x42\x78\xdd" + "\x92\x9a\xe4\x7a\xe2\x99\xd4\x73\xb1\xaa\x6f\x55\x94\x3b\xc9\xbc"; + +uint8 test_modulus[64] = + "\x23\xc9\xec\x0e\x9f\x1e\x0e\x1a\x78\xaf\xa5\x14\xd4\xf5\x45\xe4" + "\x04\x6e\xf4\x01\xe9\xdf\x45\xd1\xc2\xae\xf4\x7f\xd3\xb9\xcb\xf3" + "\x1a\x23\xa1\x0d\x4b\xd4\xd1\x4a\xd2\xd1\xc9\x7c\xab\x24\x8b\xb1" + "\x5a\x93\xca\x34\x44\x17\xb5\xe4\xfe\xf7\x9a\xaa\x72\x0d\x41\x95"; + +uint8 test_exponent[4] = "\x01\x00\x01\x00"; + +uint8 test_master_secret[48] = + "\xbe\x51\xee\x63\x23\x90\xd0\xf4\x3a\xce\x3a\x37\x65\xc3\xdd\xcf" + "\xed\xf0\xc8\x19\xed\x77\x33\x4e\xfd\x2b\x7d\x5a\xe2\xca\xf3\x0a" + "\xf1\x16\xe5\x0c\x78\x59\x7e\xd4\x4b\x57\xce\x17\x60\x3a\x5a\xb3"; + +uint8 test_session_key_blob[48] = + "\x07\x4f\xa0\x2e\xee\xc4\x5a\x46\x21\x8c\xae\x01\x45\x02\x26\xe4" + "\x54\x6b\x59\x10\xcc\x5b\xd1\x96\xd0\x5c\xeb\xc2\x96\x9b\x44\x7b" + "\x1c\xd9\x66\xb1\x9e\x24\xaa\x60\x4f\x89\xd1\x4e\xf8\xb9\x55\x3b"; + +uint8 test_mac_salt_key[16] = + "\x07\x4f\xa0\x2e\xee\xc4\x5a\x46\x21\x8c\xae\x01\x45\x02\x26\xe4"; + +uint8 test_licensing_encryption_key[16] = + "\xf3\xb1\xe0\x3b\xfe\xb4\xf2\xc5\x28\xa9\x48\xcd\x90\xf1\x93\xe5"; + +uint8 test_encrypted_premaster_secret[64] = + "\x6b\xbc\x77\x9f\x20\x0c\x98\x39\xc1\x85\x77\xc8\x19\x87\xd8\x82" + "\x93\xbd\x21\x69\x5f\x87\xe0\xd6\x4e\xad\x5e\x23\x13\x80\x8c\x63" + "\x3e\xd6\x6e\x60\xc9\x40\xe9\x86\x08\x8c\xd5\xaa\xa9\x54\xfe\x27" + "\x4c\x1f\x87\x57\xde\xca\xd4\xc7\x1e\x46\x9e\x00\x7a\xdb\x47\x23"; + +void test_license_generate_keys(void) +{ + STREAM _s, *s; + + s = &_s; + memcpy(license->client_random, client_random, sizeof(client_random)); + memcpy(license->server_random, test_server_random, sizeof(test_server_random)); + memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret)); + memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent)); + memcpy(license->certificate->cert_info.modulus.data, test_modulus, sizeof(test_modulus)); + license->certificate->cert_info.modulus.length = sizeof(test_modulus); + + license_generate_keys(license); + license_encrypt_premaster_secret(license); + + s->data = license->master_secret; + s->p = s->data + sizeof(test_master_secret); + ASSERT_STREAM(s, test_master_secret, sizeof(test_master_secret)); + + s->data = license->session_key_blob; + s->p = s->data + sizeof(test_session_key_blob); + ASSERT_STREAM(s, test_session_key_blob, sizeof(test_session_key_blob)); + + s->data = license->mac_salt_key; + s->p = s->data + sizeof(test_mac_salt_key); + ASSERT_STREAM(s, test_mac_salt_key, sizeof(test_mac_salt_key)); + + s->data = license->licensing_encryption_key; + s->p = s->data + sizeof(test_licensing_encryption_key); + ASSERT_STREAM(s, test_licensing_encryption_key, sizeof(test_licensing_encryption_key)); + + s->data = license->encrypted_premaster_secret->data; + s->p = s->data + sizeof(test_encrypted_premaster_secret); + ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret)); +} + +void test_license_encrypt_premaster_secret(void) +{ + STREAM _s, *s; + + s = &_s; + memcpy(license->premaster_secret, premaster_secret, sizeof(premaster_secret)); + memcpy(license->certificate->cert_info.exponent, test_exponent, sizeof(test_exponent)); + memcpy(license->certificate->cert_info.modulus.data, test_modulus, sizeof(test_modulus)); + license->certificate->cert_info.modulus.length = sizeof(test_modulus); + + s->data = license->encrypted_premaster_secret->data; + s->p = s->data + sizeof(test_encrypted_premaster_secret); + ASSERT_STREAM(s, test_encrypted_premaster_secret, sizeof(test_encrypted_premaster_secret)); +} + +uint8 test_encrypted_platform_challenge[10] = + "\x84\x0a\x42\x50\xad\x5e\xc1\x29\x30\xbd"; + +uint8 test_platform_challenge[10] = + "\x54\x00\x45\x00\x53\x00\x54\x00\x00\x00"; + +void test_license_decrypt_platform_challenge(void) +{ + STREAM _s, *s; + + s = &_s; + memcpy(license->licensing_encryption_key, test_licensing_encryption_key, + sizeof(test_licensing_encryption_key)); + + license->encrypted_platform_challenge->data = + (uint8*) xmalloc(sizeof(test_encrypted_platform_challenge)); + license->encrypted_platform_challenge->length = + sizeof(test_encrypted_platform_challenge); + + memcpy(license->encrypted_platform_challenge->data, test_encrypted_platform_challenge, + sizeof(test_encrypted_platform_challenge)); + + license_decrypt_platform_challenge(license); + + s->data = license->platform_challenge->data; + s->p = s->data + sizeof(test_platform_challenge); + + ASSERT_STREAM(s, test_platform_challenge, sizeof(test_platform_challenge)); +} diff --git a/cunit/test_license.h b/cunit/test_license.h new file mode 100644 index 0000000..83e6f12 --- /dev/null +++ b/cunit/test_license.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Licensing Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_license_suite(void); +int clean_license_suite(void); +int add_license_suite(void); + +void test_license(void); +void test_license_generate_keys(void); +void test_license_encrypt_premaster_secret(void); +void test_license_decrypt_platform_challenge(void); diff --git a/cunit/test_list.c b/cunit/test_list.c new file mode 100644 index 0000000..c5ef963 --- /dev/null +++ b/cunit/test_list.c @@ -0,0 +1,94 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * List Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "test_list.h" + +int init_list_suite(void) +{ + return 0; +} + +int clean_list_suite(void) +{ + return 0; +} + +int add_list_suite(void) +{ + add_test_suite(list); + + add_test_function(list); + + return 0; +} + +struct _my_list_item +{ + uint32 a; + uint32 b; +}; +typedef struct _my_list_item my_list_item; + +void test_list(void) +{ + LIST* list; + LIST_ITEM* list_item; + my_list_item* item; + my_list_item* item1; + my_list_item* item2; + int i; + + list = list_new(); + + for (i = 0; i < 10; i++) + { + item = xnew(my_list_item); + item->a = i; + item->b = i * i; + list_enqueue(list, item); + } + + for (i = 0, list_item = list->head; list_item; i++, list_item = list_item->next) + { + CU_ASSERT(((my_list_item*)list_item->data)->a == i); + CU_ASSERT(((my_list_item*)list_item->data)->b == i * i); + /*printf("%d %d\n", item->a, item->b);*/ + } + + item1 = xnew(my_list_item); + list_add(list, item1); + item2 = xnew(my_list_item); + list_add(list, item2); + + CU_ASSERT(list_remove(list, item1) == item1); + xfree(item1); + CU_ASSERT(list_remove(list, item2) == item2); + CU_ASSERT(list_remove(list, item2) == NULL); + xfree(item2); + + while ((item = list_dequeue(list)) != NULL) + xfree(item); + list_free(list); +} diff --git a/cunit/test_list.h b/cunit/test_list.h new file mode 100644 index 0000000..01afbb0 --- /dev/null +++ b/cunit/test_list.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * List Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_list_suite(void); +int clean_list_suite(void); +int add_list_suite(void); + +void test_list(void); diff --git a/cunit/test_mcs.c b/cunit/test_mcs.c new file mode 100644 index 0000000..eac0d05 --- /dev/null +++ b/cunit/test_mcs.c @@ -0,0 +1,115 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.125 Multipoint Communication Service (MCS) Protocol Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mcs.h" + +#include +#include +#include + +#include "test_mcs.h" + +int init_mcs_suite(void) +{ + return 0; +} + +int clean_mcs_suite(void) +{ + return 0; +} + +int add_mcs_suite(void) +{ + add_test_suite(mcs); + + add_test_function(mcs_write_connect_initial); + + return 0; +} + +uint8 gcc_CCrq[307] = + "\x00\x05\x00\x14\x7C\x00\x01\x81\x2A\x00\x08\x00\x10\x00\x01\xC0" + "\x00\x44\x75\x63\x61\x81\x1c\x01\xc0\xd8\x00\x04\x00\x08\x00\x00" + "\x05\x00\x04\x01\xCA\x03\xAA\x09\x04\x00\x00\xCE\x0E\x00\x00\x45" + "\x00\x4c\x00\x54\x00\x4f\x00\x4e\x00\x53\x00\x2d\x00\x44\x00\x45" + "\x00\x56\x00\x32\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + "\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xCA\x01\x00\x00" + "\x00\x00\x00\x18\x00\x07\x00\x01\x00\x36\x00\x39\x00\x37\x00\x31" + "\x00\x32\x00\x2d\x00\x37\x00\x38\x00\x33\x00\x2d\x00\x30\x00\x33" + "\x00\x35\x00\x37\x00\x39\x00\x37\x00\x34\x00\x2d\x00\x34\x00\x32" + "\x00\x37\x00\x31\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" + "\xC0\x0C\x00\x0D\x00\x00\x00\x00\x00\x00\x00\x02\xC0\x0C\x00\x1B" + "\x00\x00\x00\x00\x00\x00\x00\x03\xC0\x2C\x00\x03\x00\x00\x00\x72" + "\x64\x70\x64\x72\x00\x00\x00\x00\x00\x80\x80\x63\x6c\x69\x70\x72" + "\x64\x72\x00\x00\x00\xA0\xC0\x72\x64\x70\x73\x6e\x64\x00\x00\x00" + "\x00\x00\xc0"; + +uint8 mcs_connect_initial_expected[409] = + "\x7F\x65\x82\x01\x94\x04\x01\x01\x04\x01\x01\x01\x01\xFF\x30\x19" + "\x02\x01\x22\x02\x01\x02\x02\x01\x00\x02\x01\x01\x02\x01\x00\x02" + "\x01\x01\x02\x02\xFF\xFF\x02\x01\x02\x30\x19\x02\x01\x01\x02\x01" + "\x01\x02\x01\x01\x02\x01\x01\x02\x01\x00\x02\x01\x01\x02\x02\x04" + "\x20\x02\x01\x02\x30\x1C\x02\x02\xFF\xFF\x02\x02\xFC\x17\x02\x02" + "\xFF\xFF\x02\x01\x01\x02\x01\x00\x02\x01\x01\x02\x02\xFF\xFF\x02" + "\x01\x02\x04\x82\x01\x33\x00\x05\x00\x14\x7C\x00\x01\x81\x2A\x00" + "\x08\x00\x10\x00\x01\xC0\x00\x44\x75\x63\x61\x81\x1c\x01\xc0\xd8" + "\x00\x04\x00\x08\x00\x00\x05\x00\x04\x01\xCA\x03\xAA\x09\x04\x00" + "\x00\xCE\x0E\x00\x00\x45\x00\x4c\x00\x54\x00\x4f\x00\x4e\x00\x53" + "\x00\x2d\x00\x44\x00\x45\x00\x56\x00\x32\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x01\xCA\x01\x00\x00\x00\x00\x00\x18\x00\x07\x00\x01\x00\x36" + "\x00\x39\x00\x37\x00\x31\x00\x32\x00\x2d\x00\x37\x00\x38\x00\x33" + "\x00\x2d\x00\x30\x00\x33\x00\x35\x00\x37\x00\x39\x00\x37\x00\x34" + "\x00\x2d\x00\x34\x00\x32\x00\x37\x00\x31\x00\x34\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x04\xC0\x0C\x00\x0D\x00\x00\x00\x00\x00\x00" + "\x00\x02\xC0\x0C\x00\x1B\x00\x00\x00\x00\x00\x00\x00\x03\xC0\x2C" + "\x00\x03\x00\x00\x00\x72\x64\x70\x64\x72\x00\x00\x00\x00\x00\x80" + "\x80\x63\x6c\x69\x70\x72\x64\x72\x00\x00\x00\xA0\xC0\x72\x64\x70" + "\x73\x6e\x64\x00\x00\x00\x00\x00\xc0"; + +void test_mcs_write_connect_initial(void) +{ + STREAM* s; + rdpMcs* mcs; + STREAM _user_data, *user_data; + + mcs = mcs_new((rdpTransport*) NULL); + + user_data = &_user_data; + user_data->data = gcc_CCrq; + user_data->p = user_data->data + sizeof(gcc_CCrq); + + s = stream_new(512); + mcs_write_connect_initial(s, mcs, user_data); + + ASSERT_STREAM(s, (uint8*) mcs_connect_initial_expected, sizeof(mcs_connect_initial_expected)); + + stream_free(s); +} diff --git a/cunit/test_mcs.h b/cunit/test_mcs.h new file mode 100644 index 0000000..60d4295 --- /dev/null +++ b/cunit/test_mcs.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.125 Multipoint Communication Service (MCS) Protocol Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_mcs_suite(void); +int clean_mcs_suite(void); +int add_mcs_suite(void); + +void test_mcs_write_connect_initial(void); diff --git a/cunit/test_mppc.c b/cunit/test_mppc.c new file mode 100644 index 0000000..435fbd9 --- /dev/null +++ b/cunit/test_mppc.c @@ -0,0 +1,670 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Microsoft Point to Point Compression (MPPC) Unit Tests + * + * Copyright 2011 Laxmikant Rashinkar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "rdp.h" +#include "test_mppc.h" + +uint8_t compressed_rd5[] = +{ + 0x24, 0x02, 0x03, 0x09, 0x00, 0x20, 0x0c, 0x05, 0x10, 0x01, 0x40, 0x0a, 0xbf, 0xdf, 0xc3, 0x20, + 0x80, 0x00, 0x1f, 0x0a, 0x00, 0x00, 0x07, 0x43, 0x4e, 0x00, 0x68, 0x02, 0x00, 0x22, 0x00, 0x34, + 0xcb, 0xfb, 0xf8, 0x18, 0x40, 0x01, 0x00, 0x27, 0xe2, 0x90, 0x0f, 0xc3, 0x91, 0xa8, 0x00, 0x08, + 0x00, 0x00, 0x68, 0x50, 0x60, 0x65, 0xfc, 0x0e, 0xfe, 0x04, 0x00, 0x08, 0x00, 0x06, 0x0c, 0x00, + 0x01, 0x00, 0xf8, 0x40, 0x20, 0x00, 0x00, 0x90, 0x00, 0xcf, 0x95, 0x1f, 0x44, 0x90, 0x00, 0x6e, + 0x03, 0xf4, 0x40, 0x21, 0x9f, 0x26, 0x01, 0xbf, 0x88, 0x10, 0x90, 0x00, 0x08, 0x04, 0x00, 0x04, + 0x30, 0x03, 0xe4, 0xc7, 0xea, 0x05, 0x1e, 0x87, 0xf8, 0x20, 0x1c, 0x00, 0x10, 0x84, 0x22, 0x1f, + 0x71, 0x0d, 0x0e, 0xb9, 0x88, 0x9f, 0x5c, 0xee, 0x41, 0x97, 0xfb, 0xf8, 0x88, 0x68, 0x08, 0x6d, + 0xd0, 0x44, 0xfc, 0x34, 0x06, 0xe6, 0x16, 0x21, 0x04, 0x11, 0x0f, 0xb9, 0x85, 0x86, 0x5d, 0x44, + 0x4f, 0xae, 0xb7, 0x40, 0xa8, 0xcd, 0x5b, 0xed, 0x02, 0xee, 0xc2, 0x21, 0x40, 0x21, 0x21, 0x23, + 0x17, 0xb7, 0x00, 0x60, 0x00, 0x3b, 0xfd, 0xfc, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x34, 0x00, 0x33, + 0xc7, 0xe0, 0xc0, 0x0f, 0x07, 0x12, 0x42, 0x01, 0xe8, 0x6c, 0xc7, 0x83, 0x07, 0x8c, 0xd4, 0x30, + 0x07, 0x20, 0x01, 0x90, 0xa3, 0xf1, 0xdb, 0xf5, 0xd4, 0x13, 0xc2, 0x4f, 0x0f, 0xe5, 0xe2, 0xc7, + 0x87, 0xf2, 0xf0, 0x93, 0xc3, 0xf9, 0x78, 0xb0, 0x1a, 0x03, 0xe1, 0xf1, 0xd0, 0x08, 0x4c, 0x66, + 0xac, 0x32, 0x31, 0x70, 0x60, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, 0xf0, 0x36, 0x1f, 0xe5, 0xe0, + 0x6c, 0xbc, 0x26, 0xf0, 0x36, 0x5f, 0xe5, 0xe0, 0x6c, 0xbc, 0x26, 0xf0, 0x34, 0xf9, 0x94, 0x32, + 0x31, 0x74, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xbf, 0x87, 0xdf, 0xef, 0xfe, 0x4b, 0xbf, 0x02, 0xfa, + 0xde, 0xa7, 0x79, 0x32, 0x44, 0x7c, 0x20, 0x82, 0x00, 0x5f, 0xef, 0xff, 0x09, 0xe1, 0x05, 0x74, + 0x32, 0xea, 0x09, 0xe1, 0x0f, 0x55, 0x83, 0x85, 0x2a, 0xa0, 0x1d, 0x50, 0x0e, 0x0e, 0x0b, 0x01, + 0x01, 0x43, 0x06, 0x02, 0xbe, 0x5f, 0x00, 0x00, 0x0c, 0x3d, 0x4d, 0x87, 0xa6, 0x5e, 0xa6, 0xcb, + 0xc3, 0xcf, 0x53, 0x65, 0xe9, 0x97, 0xa9, 0xb2, 0xf5, 0x9b, 0xd4, 0xd3, 0xee, 0xcd, 0xc0, 0x7c, + 0xae, 0xe0, 0x65, 0x1f, 0xe5, 0xe0, 0x6c, 0xbc, 0x26, 0xf0, 0x36, 0x5f, 0xe5, 0xe0, 0x6c, 0xbc, + 0x26, 0xf0, 0x34, 0xfb, 0xb3, 0xf2, 0x41, 0x30, 0x20, 0x04, 0xa0, 0x80, 0x93, 0xf3, 0xf2, 0x1b, + 0xed, 0xf6, 0x0f, 0x04, 0x82, 0x7b, 0xcc, 0x00, 0x65, 0xef, 0x4f, 0x86, 0x02, 0xf7, 0xa7, 0xe0, + 0x0a, 0x88, 0x1c, 0x34, 0x02, 0x02, 0x02, 0x60, 0x60, 0x49, 0x40, 0xc1, 0x2f, 0x14, 0xca, 0x60, + 0xc1, 0x81, 0x80, 0x07, 0xc3, 0x00, 0x00, 0x39, 0xfa, 0x86, 0x38, 0x93, 0x47, 0x08, 0x27, 0x08, + 0xfc, 0xb8, 0x4e, 0x38, 0x47, 0xe5, 0xc2, 0x09, 0xc2, 0x3f, 0x2e, 0x13, 0x8e, 0x11, 0xf3, 0xc3, + 0x57, 0x1a, 0x88, 0x7d, 0x44, 0x3c, 0x3c, 0x04, 0x0f, 0xd4, 0x3f, 0x83, 0x8d, 0x82, 0x00, 0x25, + 0x04, 0x84, 0xdf, 0xe0, 0x17, 0xf8, 0x04, 0x03, 0xe1, 0x47, 0xc4, 0xaf, 0x9c, 0x00, 0x00, 0x31, + 0xf5, 0x4c, 0x71, 0x78, 0x8f, 0x54, 0xfb, 0x1c, 0x97, 0xa4, 0x04, 0x13, 0xd5, 0x2f, 0x77, 0xc7, + 0xb8, 0x9e, 0xef, 0xcb, 0xc2, 0x6f, 0x77, 0xe5, 0xee, 0x27, 0xbb, 0xf2, 0xf7, 0xe3, 0xdd, 0xf3, + 0xc6, 0xfb, 0x2a, 0x78, 0x6d, 0x3c, 0x34, 0x37, 0xc0, 0xaf, 0x25, 0xc7, 0x81, 0x7d, 0x6e, 0x5d, + 0x5c, 0xd6, 0xe3, 0x43, 0xc0, 0x82, 0xd0, 0x95, 0x90, 0xd8, 0xbd, 0xfc, 0x00, 0x09, 0xc0, 0x34, + 0x39, 0x46, 0x84, 0x20, 0x40, 0x38, 0xa3, 0x42, 0x12, 0xb0, 0x55, 0xbe, 0x28, 0xc0, 0x70, 0x64, + 0x28, 0xc8, 0x48, 0x42, 0x08, 0xb2, 0x1b, 0x46, 0xa6, 0x09, 0x54, 0x2e, 0x5f, 0x73, 0x84, 0xfc, + 0x28, 0x4a, 0x73, 0x79, 0xf2, 0x6c, 0x5d, 0x82, 0x82, 0x6e, 0xc2, 0x27, 0xd7, 0x6b, 0xb8, 0x4f, + 0xa4, 0xa4, 0x22, 0xee, 0x22, 0x7e, 0x10, 0x03, 0x78, 0x08, 0xf4, 0x94, 0x5e, 0x02, 0x01, 0xef, + 0x02, 0x27, 0xd7, 0x8b, 0xc8, 0x3f, 0xa4, 0xa4, 0x1a, 0xf3, 0xd1, 0x84, 0x0c, 0x32, 0x31, 0x75, + 0x60, 0x05, 0xe2, 0x30, 0xb7, 0xad, 0x5b, 0x15, 0xd5, 0xc3, 0xc0, 0x00, 0x11, 0x81, 0x81, 0x69, + 0x8f, 0x06, 0x0f, 0x14, 0xcf, 0xa6, 0xe8, 0xb1, 0x22, 0x77, 0xeb, 0xd7, 0x45, 0x89, 0xf0, 0xb6, + 0x3e, 0x23, 0x06, 0x80, 0xf8, 0x5b, 0x0f, 0x04, 0x83, 0xfc, 0x2d, 0x8f, 0x88, 0xc1, 0xa0, 0x3e, + 0x16, 0x1d, 0x00, 0x83, 0x74, 0x58, 0xa0, 0xc0, 0x10, 0xce, 0x8b, 0x17, 0xe0, 0x68, 0xff, 0x20, + 0xff, 0x03, 0x63, 0xe5, 0xcf, 0x1f, 0xa0, 0x40, 0x00, 0x00, 0x2a, 0xff, 0xd6, 0xd1, 0xc0, 0xb9, + 0xe0, 0x5f, 0x6b, 0x81, 0x73, 0xc9, 0x93, 0xd1, 0x63, 0x50, 0xf0, 0x9b, 0xf0, 0x48, 0x4f, 0xaf, + 0xe0, 0x1b, 0xef, 0x82, 0x6f, 0xc2, 0x40, 0xe0, 0xe4, 0x60, 0xa0, 0x69, 0xa1, 0xa1, 0xbe, 0xba, + 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x42, 0x00, 0x44, 0x00, 0x88, 0x01, 0x10, 0x02, + 0x21, 0x02, 0x22, 0x04, 0x44, 0x08, 0x9c, 0x8f, 0xcd, 0xe0, 0x02, 0x20, 0x88, 0x02, 0x10, 0x40, + 0x01, 0xf0, 0x60, 0x44, 0xc0, 0xce, 0xb1, 0x8f, 0xd0, 0x30, 0x00, 0x60, 0x00, 0xa0, 0x00, 0xc4, + 0x00, 0xcc, 0x01, 0x98, 0x03, 0x28, 0x03, 0x31, 0x03, 0x33, 0x06, 0x66, 0x07, 0x0e, 0x2c, 0xe3, + 0x7b, 0x18, 0x85, 0xc7, 0xd6, 0x51, 0x71, 0x0f, 0x0e, 0xb8, 0x88, 0x9f, 0x5c, 0x6e, 0x41, 0xde, + 0xeb, 0x71, 0x20, 0x5c, 0xba, 0xf7, 0xc8, 0x6f, 0xba, 0xc1, 0xf7, 0x30, 0xd0, 0xce, 0xc1, 0x31, + 0x74, 0xec, 0x13, 0x41, 0x77, 0x41, 0x13, 0xa0, 0x10, 0xbf, 0x7c, 0x45, 0xd3, 0xa5, 0xbc, 0x55, + 0x84, 0xaa, 0x41, 0xc1, 0xc1, 0xe0, 0xe0, 0x29, 0x01, 0x20, 0x81, 0x00, 0x03, 0x80, 0x07, 0xc0, + 0x0f, 0xe0, 0x06, 0xbe, 0x16, 0x75, 0xe7, 0x9f, 0xfb, 0x1e, 0x17, 0x90, 0xef, 0x0b, 0xbb, 0x15, + 0x03, 0x7c, 0x2b, 0x7e, 0x22, 0x78, 0x56, 0x83, 0xae, 0x77, 0x40, 0xcf, 0xb0, 0xf0, 0x98, 0x28, + 0x04, 0x2f, 0xaf, 0x0e, 0x40, 0xfc, 0x01, 0x1c, 0x5c, 0xb1, 0xf2, 0xbf, 0xa5, 0xd7, 0x8f, 0x97, + 0xc0, 0xfe, 0x9f, 0x02, 0xe7, 0x24, 0x79, 0xe0, 0x9b, 0xa9, 0xfd, 0x74, 0x3b, 0xaf, 0x2d, 0xf8, + 0x4b, 0xd2, 0xf7, 0x84, 0x54, 0x04, 0x2a, 0x02, 0x02, 0x01, 0xe1, 0x1e, 0xf0, 0x87, 0xff, 0x77, + 0x07, 0x00, 0x02, 0x00, 0x0d, 0xbd, 0xe1, 0xf0, 0x01, 0x1e, 0xf0, 0xfd, 0x80, 0x4c, 0x24, 0x11, + 0x2c, 0x10, 0x24, 0x02, 0x01, 0x40, 0xb0, 0x5c, 0x2c, 0x14, 0x08, 0x07, 0x1b, 0x80, 0x01, 0xa7, + 0xbd, 0x3e, 0x00, 0x27, 0xde, 0x9f, 0xb0, 0x85, 0x01, 0xfb, 0xd2, 0x04, 0x0c, 0x1c, 0x2e, 0x0e, + 0x06, 0x18, 0x03, 0xd4, 0x00, 0x00, 0x67, 0xef, 0x4f, 0x80, 0x0a, 0xf7, 0xa7, 0xe3, 0x94, 0xe0, + 0xe0, 0x10, 0x1b, 0xfd, 0xfc, 0x74, 0x62, 0xe8, 0xc0, 0x1d, 0x62, 0x00, 0x0b, 0x00, 0xb7, 0x70, + 0xe6, 0x8a, 0x68, 0x75, 0x38, 0x3c, 0x3c, 0x4c, 0x2f, 0x87, 0xef, 0x01, 0xc7, 0xb2, 0x40, 0x21, + 0xa3, 0x23, 0x0a, 0x08, 0x01, 0xa1, 0xa1, 0xe1, 0x80, 0x69, 0x40, 0xe1, 0x00, 0x00, 0x40, 0xd0, + 0xea, 0xe5, 0xe1, 0xc0, 0x81, 0x87, 0xed, 0x68, 0x1a, 0x08, 0x94, 0x0c, 0x0c, 0xf1, 0x7c, 0xbe, + 0x5f, 0x2f, 0x8f, 0x00, 0x00, 0x0d, 0x1f, 0x68, 0x7a, 0x1a, 0x04, 0x05, 0xce, 0xe6, 0x2a, 0x0c, + 0x01, 0xc2, 0x00, 0x40, 0x42, 0x61, 0xc0, 0x49, 0x41, 0x60, 0xa0, 0x80, 0x01, 0xc0, 0x03, 0xe0, + 0x07, 0xf0, 0x07, 0xfa, 0x00, 0x07, 0x3b, 0x99, 0x01, 0x0f, 0x19, 0x18, 0x54, 0x40, 0xe0, 0x60, + 0xee, 0xd0, 0x0e, 0x19, 0x0a, 0x03, 0xa5, 0x7d, 0x05, 0xd0, 0x83, 0x98, 0x5a, 0x96, 0x21, 0x4b, + 0x10, 0x10, 0xe6, 0x17, 0xaf, 0xeb, 0xaf, 0x34, 0x3c, 0xc8, 0x0f, 0xf0, 0x64, 0x3f, 0xd0, 0x0f, + 0xe0, 0x03, 0xfe, 0x10, 0x02, 0x7d, 0x47, 0x2d, 0x58, 0xfc, 0x35, 0xe0, 0xca, 0x0f, 0x19, 0x0a, + 0xf9, 0xf1, 0xe0, 0xb9, 0xc0, 0x81, 0x10, 0x03, 0xe0, 0xbd, 0x4f, 0xea, 0x61, 0xf7, 0xeb, 0xf6, + 0x02, 0xd4, 0x7a, 0xf9, 0xff, 0x15, 0x30, 0xfa, 0x88, 0x68, 0x68, 0xd8, 0x80, 0x12, 0x60, 0x50, + 0x50, 0xf0, 0x03, 0xfc, 0x01, 0xfe, 0x01, 0x7f, 0xa0, 0x7c, 0x28, 0xbf, 0xd0, 0x3e, 0x64, 0x0f, + 0x00, 0x37, 0x00, 0x08, 0x80, 0x20, 0x0b, 0x88, 0x81, 0xa5, 0x04, 0x84, 0x60, 0x40, 0x36, 0x04, + 0x1b, 0x8f, 0x88, 0x01, 0x00, 0xa1, 0x80, 0x1e, 0x00, 0x36, 0xfd, 0xb9, 0x12, 0x02, 0x4c, 0x09, + 0x08, 0x1e, 0x00, 0x61, 0x80, 0x20, 0x60, 0x44, 0x17, 0xdc, 0x7c, 0x62, 0x00, 0x03, 0x67, 0xdb, + 0x81, 0xb1, 0x30, 0x34, 0xb0, 0xa0, 0xaf, 0xa0, 0x80, 0x75, 0x35, 0x20, 0x7c, 0x49, 0xfc, 0x0f, + 0xf5, 0x0d, 0x7f, 0x7e, 0x45, 0x00, 0x53, 0x42, 0x82, 0x83, 0xc0, 0x0c, 0x28, 0x1f, 0x72, 0x3e, + 0xd3, 0xf5, 0x62, 0xd4, 0x00, 0x22, 0xa8, 0x81, 0xec, 0x67, 0x96, 0x02, 0xa0, 0x49, 0x7d, 0xfd, + 0x6b, 0xbf, 0xcc, 0x7c, 0x4a, 0xf8, 0xd0, 0x00, 0x00, 0xcf, 0xd5, 0xd2, 0x23, 0x35, 0x60, 0x01, + 0xf1, 0x60, 0x14, 0xc0, 0xb0, 0xbe, 0xb3, 0x02, 0x0f, 0x89, 0x5f, 0x1b, 0x00, 0x02, 0x0b, 0xfd, + 0x80, 0x00, 0x01, 0x9b, 0xf3, 0x40, 0x42, 0x10, 0x00, 0xd8, 0xb8, 0x0f, 0xa8, 0x17, 0xfe, 0x59, + 0xef, 0x14, 0x61, 0xf2, 0x30, 0x65, 0xfc, 0x51, 0xe2, 0xc1, 0x18, 0xc0, 0x07, 0x5e, 0x68, 0x08, + 0xe8, 0x46, 0xf8, 0x95, 0xf1, 0xb0, 0xf9, 0x13, 0x7f, 0xbc, 0x00, 0x00, 0x32, 0x7e, 0xa8, 0xeb, + 0xcd, 0x03, 0x20, 0x09, 0xa1, 0x81, 0x97, 0xfb, 0x87, 0x80, 0xb0, 0xf9, 0x19, 0x7c, 0xa8, 0x63, + 0xf3, 0xe6, 0x20, 0x22, 0xbd, 0x85, 0x9e, 0x62, 0x00, 0x8b, 0x7c, 0x87, 0x91, 0x00, 0x22, 0xff, + 0x21, 0xe2, 0xa0, 0x08, 0xc7, 0xc8, 0x78, 0x20, 0x02, 0x33, 0xf2, 0x1c, 0x10, 0x41, 0xe3, 0x40, + 0x69, 0x7c, 0x45, 0x72, 0x62, 0xf0, 0x04, 0x7f, 0x60, 0x68, 0x6f, 0x80, 0x00, 0x08, 0x1f, 0xf7, + 0xad, 0x51, 0x03, 0xf3, 0xf8, 0xa0, 0x9d, 0xa8, 0x40, 0x00, 0x23, 0x42, 0x37, 0x46, 0x0f, 0xde, + 0xa6, 0x06, 0xd3, 0x3c, 0x33, 0xe1, 0x78, 0xd8, 0x34, 0x32, 0x14, 0x67, 0xdb, 0xd2, 0x38, 0xaf, + 0xc7, 0x9c, 0xdf, 0xd0, 0x21, 0xe6, 0xd7, 0x80, 0x40, 0x22, 0x3f, 0x21, 0xe8, 0xd8, 0x12, 0xf9, + 0x0f, 0xb4, 0x01, 0x13, 0xf9, 0x0f, 0x46, 0xc0, 0xa7, 0x13, 0x37, 0x1e, 0x67, 0x07, 0x8b, 0x01, + 0xfd, 0xfe, 0x0f, 0xf7, 0x7a, 0xf0, 0x16, 0x36, 0x0a, 0x92, 0x08, 0x08, 0xc1, 0x70, 0xb8, 0x30, + 0x34, 0xf1, 0xf3, 0x72, 0x27, 0x8f, 0x4b, 0x60, 0x21, 0xc4, 0xdd, 0xe2, 0xdf, 0x0b, 0xca, 0x4f, + 0x2e, 0x4f, 0x9c, 0xde, 0x59, 0xe9, 0xf1, 0x55, 0x00, 0x8d, 0xf2, 0x20, 0x53, 0x3c, 0xc4, 0xf6, + 0x46, 0x7e, 0x24, 0xee, 0xf2, 0x0c, 0x0d, 0x81, 0x83, 0xf9, 0x98, 0x0e, 0x00, 0x02, 0x10, 0x11, + 0x01, 0x08, 0x95, 0x2a, 0xfc, 0x28, 0x95, 0x2a, 0x84, 0x80, 0xbf, 0x81, 0x06, 0x80, 0x0d, 0x00, + 0x86, 0xe0, 0x6b, 0xa5, 0xc3, 0xd8, 0x8f, 0x22, 0xa0, 0x3e, 0xe9, 0x8f, 0x90, 0xf2, 0x6b, 0x85, + 0x77, 0x57, 0x99, 0x43, 0x5c, 0x66, 0x5f, 0x9e, 0x85, 0x7c, 0x3f, 0x1f, 0xb3, 0xce, 0xc0, 0x0e, + 0x64, 0x20, 0x0e, 0x20, 0xdc, 0x7e, 0x18, 0x81, 0x90, 0xa3, 0x13, 0x4e, 0x52, 0x71, 0x81, 0x03, + 0xa4, 0x30, 0x30, 0x6c, 0x73, 0x8f, 0xc4, 0x50, 0x60, 0x16, 0x38, 0x03, 0xbf, 0x6f, 0x89, 0x3e, + 0x00, 0x77, 0x00, 0xb1, 0xc0, 0x28, 0x3d, 0x73, 0x98, 0x06, 0xfe, 0x00, 0xe9, 0x81, 0xa3, 0xb8, + 0x1c, 0x85, 0x20, 0x45, 0x45, 0xe1, 0xa1, 0x23, 0x63, 0xa0, 0x29, 0x61, 0x41, 0x27, 0xf4, 0x03, + 0xfa, 0x01, 0x02, 0x05, 0xff, 0xe1, 0x20, 0x34, 0x08, 0x08, 0x04, 0x04, 0x02, 0xff, 0xeb, 0x96, + 0x05, 0x24, 0x8e, 0x0a, 0xb1, 0xce, 0xf2, 0x06, 0xc7, 0xb9, 0x01, 0xd7, 0x20, 0x52, 0x04, 0x03, + 0xe1, 0x47, 0xc4, 0xa4, 0x0b, 0xfd, 0x03, 0x01, 0xc0, 0x47, 0xe6, 0xc0, 0x2c, 0x7c, 0x09, 0x10, + 0x1c, 0x0a, 0xfd, 0x7e, 0xc0, 0xd2, 0x94, 0x7a, 0x1a, 0x06, 0x07, 0xcf, 0x12, 0x2a, 0x8c, 0x1e, + 0xe7, 0x07, 0x08, 0x81, 0x81, 0x91, 0x90, 0x72, 0x26, 0x9e, 0x55, 0x44, 0x0e, 0x4d, 0x21, 0x00, + 0x08, 0x40, 0x02, 0x20, 0x01, 0x17, 0x2c, 0xd4, 0x22, 0x00, 0x88, 0x80, 0x44, 0x40, 0x23, 0xcd, + 0xf8, 0xf1, 0xc8, 0x9b, 0x02, 0x10, 0x0c, 0x02, 0x99, 0x30, 0x00, 0x0a, 0x06, 0x01, 0x4b, 0x18, + 0x00, 0x46, 0x00, 0x29, 0x9c, 0xa3, 0x86, 0x60, 0x11, 0x98, 0x05, 0x32, 0x80, 0xcc, 0xc0, 0xf3, + 0xc3, 0xb8, 0x7a, 0x21, 0x7d, 0xbe, 0xfa, 0xce, 0x2a, 0x9d, 0xfa, 0xa0, 0x3c, 0x32, 0xfb, 0x7d, + 0x13, 0x22, 0x05, 0xeb, 0x0b, 0xbb, 0xb8, 0x00, 0x15, 0xfe, 0xfe, 0x1a, 0x14, 0x7e, 0x1c, 0x00, + 0x01, 0x82, 0x3a, 0xa7, 0xd2, 0x6c, 0x11, 0xdd, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x18, 0x23, 0x5a, + 0x00, 0x80, 0xb0, 0x47, 0x84, 0x7c, 0xa8, 0x03, 0xa7, 0x82, 0x48, 0x83, 0x01, 0x50, 0x11, 0x2a, + 0x37, 0xfb, 0xfc, 0x03, 0x03, 0xd1, 0xa3, 0x35, 0x68, 0xcd, 0x58, 0x40, 0x03, 0xe3, 0x47, 0xc4, + 0xaf, 0x8d, 0x1f, 0x42, 0x84, 0x20, 0x81, 0x08, 0x57, 0xfb, 0xff, 0xd0, 0x98, 0x27, 0xc8, 0xaf, + 0x99, 0x1f, 0x12, 0x04, 0x3e, 0x84, 0xfe, 0x08, 0x1c, 0xc1, 0x31, 0x58, 0x80, 0x3a, 0xd1, 0x99, + 0x8a, 0x40, 0x02, 0x5a, 0x04, 0x00, 0x02, 0x1a, 0x38, 0xf3, 0x08, 0x00, 0x01, 0xda, 0xe3, 0x35, + 0x60, 0x5f, 0x88, 0x00, 0x03, 0x6e, 0xbf, 0xdf, 0xc0, 0xbe, 0x20, 0x00, 0x42, 0x80, 0x01, 0x77, + 0x9e, 0x80, 0xd0, 0x30, 0x4a, 0x32, 0x81, 0xe3, 0x94, 0x04, 0x21, 0x0a, 0x9c, 0xcc, 0x52, 0x03, + 0x7d, 0xa7, 0x0c, 0x51, 0x80, 0x6f, 0xa5, 0xc0, 0x3f, 0x3e, 0x80, 0xa0, 0x22, 0x10, 0x40, 0x68, + 0x17, 0x9f, 0x60, 0x1e, 0x9b, 0x09, 0x52, 0x03, 0x2d, 0x03, 0x81, 0x88, 0x41, 0x3c, 0x65, 0x14, + 0x98, 0xcd, 0x58, 0x6a, 0x04, 0x21, 0x80, 0x9b, 0x81, 0x45, 0x21, 0x24, 0xe1, 0x8c, 0xf1, 0x9a, + 0xb0, 0xa9, 0x38, 0xef, 0xe7, 0x90, 0xdf, 0x98, 0x00, 0x19, 0xa8, 0x18, 0x42, 0x6a, 0xc0, 0x7f, + 0xda, 0x00, 0x00, 0x2b, 0x1e, 0x36, 0x7c, 0xaa, 0xa0, 0x00, 0xc0, 0xf8, 0xa0, 0xbe, 0x60, 0x2e, + 0xb1, 0x09, 0xab, 0x60, 0x3e, 0x38, 0xf9, 0x6f, 0xa9, 0x3e, 0x08, 0x81, 0xa6, 0x8c, 0x13, 0xae, + 0x83, 0x7e, 0x0a, 0xfb, 0x0f, 0x60, 0x86, 0x3e, 0x90, 0x6d, 0xa2, 0x33, 0x56, 0x06, 0xfa, 0xcf, + 0xc5, 0x1f, 0x12, 0x38, 0x49, 0x3d, 0x04, 0x03, 0xa6, 0x42, 0x54, 0x82, 0x3e, 0xd3, 0xd1, 0xd0, + 0x08, 0x58, 0x06, 0xdc, 0x10, 0x85, 0xe8, 0xf8, 0xf8, 0x94, 0x10, 0x84, 0x21, 0xe7, 0xa3, 0x85, + 0xfe, 0xfe, 0xc1, 0xe9, 0x77, 0xa3, 0x27, 0xe7, 0xbd, 0x31, 0x98, 0x17, 0xa1, 0xe2, 0x13, 0xe8, + 0x5a, 0xf1, 0x44, 0x7c, 0x4a, 0x00, 0x00, 0x07, 0x2d, 0x03, 0x2d, 0x05, 0xa3, 0x46, 0x6a, 0xc1, + 0x9e, 0x9f, 0x9f, 0x51, 0xc0, 0x55, 0x1a, 0x13, 0x56, 0x0e, 0xf4, 0xa4, 0x85, 0xfd, 0x4c, 0x47, + 0x10, 0x0d, 0x70, 0x24, 0x9b, 0xfa, 0x45, 0x41, 0x3a, 0x33, 0xea, 0x28, 0x60, 0x00, 0x80, 0x00, + 0xbc, 0x00, 0x80, 0x7b, 0x2e, 0x43, 0x10, 0x0b, 0x00, 0xec, 0x1e, 0x98, 0x8a, 0xb4, 0x26, 0xac, + 0x5f, 0xf9, 0x20, 0x03, 0xf2, 0xc1, 0xdf, 0xca, 0x14, 0x40, 0x07, 0x40, 0x1e, 0x00, 0x3d, 0x10, + 0xe1, 0x37, 0x90, 0x64, 0x17, 0xec, 0x3d, 0x4c, 0xf5, 0x94, 0x20, 0x15, 0x80, 0xdc, 0x3e, 0x74, + 0x7f, 0x87, 0x87, 0xa9, 0xa6, 0x33, 0x56, 0x16, 0xfd, 0xcf, 0xa9, 0x1f, 0x12, 0x23, 0x35, 0x60, + 0xaf, 0xa4, 0x04, 0xf5, 0xb0, 0x1f, 0xe4, 0x3d, 0x75, 0x1c, 0x20, 0xeb, 0xd7, 0x19, 0x00, 0xb8, + 0x04, 0x21, 0x7a, 0xd3, 0xbe, 0x15, 0xeb, 0x4a, 0xf1, 0x84, 0x78, 0x52, 0x3e, 0x25, 0x03, 0x16, + 0x81, 0xc3, 0x7d, 0x59, 0x1f, 0x12, 0x30, 0x50, 0xe3, 0xe1, 0xcf, 0xc5, 0x8f, 0xa1, 0x1c, 0x0e, + 0x9e, 0xd0, 0x0d, 0x7b, 0x18, 0x14, 0xcc, 0x21, 0x04, 0x1b, 0x6a, 0x8c, 0xd5, 0x86, 0xe0, 0x31, + 0x9a, 0xb0, 0x4f, 0xc8, 0x0b, 0x7c, 0x40, 0x37, 0xc4, 0x5c, 0x22, 0x80, 0x3e, 0x54, 0x71, 0x10, + 0xbf, 0x26, 0xf9, 0xa2, 0x1c, 0x0b, 0x82, 0xf0, 0x8f, 0x22, 0x47, 0x8a, 0xab, 0xca, 0xd4, 0x31, + 0x08, 0xf1, 0xe6, 0x51, 0x9a, 0xb7, 0xcc, 0x80, 0x7f, 0xc9, 0xc2, 0x13, 0x08, 0xfd, 0x95, 0xfe, + 0x23, 0xc0, 0x14, 0x0f, 0x08, 0xe1, 0xb5, 0x5f, 0x4a, 0x38, 0x10, 0x47, 0x1b, 0x17, 0x0a, 0x07, + 0x1d, 0x38, 0xe3, 0xcb, 0x42, 0x10, 0x4f, 0x5d, 0x40, 0x3f, 0xf8, 0xe1, 0x0a, 0xe0, 0x45, 0xa8, + 0x47, 0xe0, 0x78, 0x23, 0x0f, 0x91, 0x5f, 0x4a, 0x7f, 0xe3, 0xc9, 0x11, 0xe0, 0x4a, 0x09, 0xfe, + 0x5a, 0xf0, 0xea, 0x8f, 0x21, 0x57, 0x82, 0xa3, 0xfa, 0x47, 0xc4, 0x8e, 0x0d, 0x8f, 0xcc, 0xfe, + 0x11, 0xf1, 0x22, 0x33, 0x56, 0xe1, 0xf9, 0x1f, 0x9a, 0x83, 0x79, 0x2d, 0xe3, 0xf5, 0x23, 0xf6, + 0x50, 0x64, 0x17, 0xce, 0x4f, 0x12, 0x58, 0x5f, 0xe0, 0xc4, 0x32, 0x0d, 0xfc, 0xab, 0xd5, 0x54, + 0x15, 0x04, 0xfd, 0x91, 0xf1, 0x20, 0x32, 0x0d, 0xe1, 0x48, 0xf8, 0x91, 0xe5, 0x48, 0x09, 0xfc, + 0xdb, 0x7b, 0xab, 0x84, 0x22, 0x0d, 0xfd, 0x23, 0xda, 0xd1, 0xf2, 0x20, 0x2a, 0x11, 0xfe, 0x23, + 0xe7, 0x4f, 0x8c, 0x2f, 0x80, 0xe7, 0x1f, 0x09, 0x40, 0x2f, 0x00, 0xee, 0x7f, 0xf5, 0x1f, 0x12, + 0x3c, 0x0d, 0x40, 0xff, 0xa9, 0xc3, 0x1b, 0x01, 0x42, 0xce, 0x18, 0x5b, 0x52, 0xd9, 0x8a, 0x79, + 0xa7, 0xbc, 0xc5, 0x01, 0x08, 0x41, 0x21, 0xb5, 0xfc, 0x1b, 0x93, 0x1e, 0x8f, 0x60, 0x02, 0x98, + 0xf8, 0xe0, 0x0c, 0x1c, 0x2e, 0x15, 0x00, 0xe7, 0x61, 0x08, 0x02, 0xfd, 0x16, 0x5c, 0xdb, 0xf2, + 0xb8, 0x4f, 0x03, 0xfd, 0x81, 0x8a, 0x88, 0x52, 0x05, 0x20, 0x0e, 0xe9, 0xf9, 0xaa, 0xed, 0x7f, + 0xbf, 0xd0, 0x0b, 0x0b, 0x42, 0x60, 0x85, 0xa1, 0x3f, 0x0a, 0x0b, 0x42, 0x40, 0x08, 0xa8, 0x02, + 0x04, 0xa9, 0x60, 0x46, 0x00, 0x45, 0x40, 0x5c, 0xa7, 0xa6, 0xfa, 0x5c, 0x07, 0xf0, 0xe0, 0xa4, + 0x0f, 0x94, 0xc4, 0x16, 0x82, 0x96, 0x82, 0x94, 0x83, 0x71, 0x76, 0x04, 0x94, 0x8f, 0xa1, 0xf3, + 0x40, 0x00, 0x93, 0x85, 0xa2, 0x50, 0xc0, 0x00, 0x28, 0x1c, 0xbb, 0x03, 0x09, 0x12, 0x5e, 0x91, + 0xaf, 0x21, 0x42, 0x05, 0x09, 0x6b, 0xe5, 0x59, 0x27, 0xcf, 0x8f, 0x88, 0x24, 0x00, 0x90, 0x7c, + 0x60, 0x00, 0x00, 0x17, 0x1a, 0x02, 0x40, 0x2c, 0x03, 0x94, 0x1a, 0xf8, 0x02, 0xa0, 0x80, 0xd2, + 0x15, 0xf5, 0x64, 0x00, 0xc0, 0x32, 0x01, 0x83, 0xa4, 0xc0, 0x5e, 0xb2, 0x0e, 0x70, 0x9a, 0x7b, + 0x12, 0x23, 0x35, 0x6f, 0x26, 0x43, 0x7f, 0x40, 0x6a, 0x04, 0xe8, 0x14, 0x04, 0xa4, 0xb3, 0x14, + 0x81, 0x30, 0x2f, 0x16, 0x84, 0xd0, 0x0c, 0x0b, 0x42, 0x6e, 0x14, 0x00, 0x9a, 0x00, 0x87, 0x76, + 0x80, 0x07, 0x98, 0x2c, 0x03, 0x99, 0x9c, 0xf3, 0xbb, 0x7f, 0xb8, 0xa4, 0xdb, 0xde, 0xfc, 0x4a, + 0x00, 0x05, 0xa4, 0xc2, 0x6a, 0xc0, 0xed, 0x3d, 0x15, 0xc1, 0x04, 0xe1, 0x30, 0x2e, 0x2c, 0xf1, + 0x50, 0x69, 0x84, 0xa9, 0x0f, 0xf8, 0xc2, 0xbe, 0x35, 0xa8, 0x87, 0x50, 0x10, 0x0e, 0x00, 0xe5, + 0x1e, 0xc6, 0xa9, 0x55, 0xfe, 0xff, 0x48, 0xf5, 0xe0, 0x53, 0xdc, 0x78, 0x80, 0x10, 0x51, 0x89, + 0x52, 0xc0, 0x06, 0xab, 0x03, 0x14, 0x6f, 0xed, 0x85, 0xde, 0x80, 0x03, 0x09, 0x52, 0xe5, 0xff, + 0x5e, 0x02, 0xbf, 0x8f, 0x8f, 0xc9, 0xcf, 0xe5, 0xeb, 0xf3, 0x72, 0xbb, 0x80, 0x00, 0xc6, 0x6a, + 0xd8, 0x08, 0x95, 0xf4, 0xb2, 0xf9, 0x4f, 0xa1, 0xc1, 0xc2, 0x5a, 0xef, 0xf7, 0xfa, 0x81, 0xdd, + 0xbd, 0xef, 0xee, 0xe0, 0xd1, 0xe5, 0x72, 0xc5, 0xcd, 0xf0, 0x2c, 0x00, 0x03, 0xcb, 0x98, 0xf0, + 0x7f, 0x52, 0x00 +}; + +uint8_t decompressed_rd5[] = +{ + 0x24, 0x02, 0x03, 0x09, 0x00, 0x20, 0x0c, 0x05, 0x10, 0x01, 0x40, 0x0a, 0xff, 0xff, 0x0c, 0x84, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x0d, 0x38, 0x01, 0xc0, 0x10, 0x01, 0x10, + 0x01, 0xcc, 0xff, 0x7f, 0x03, 0x08, 0x00, 0x20, 0x04, 0x05, 0x10, 0x01, 0x40, 0x0a, 0x00, 0x0c, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x01, 0x00, 0x00, 0x0d, 0x0a, + 0x0c, 0x0c, 0xff, 0x03, 0xff, 0x02, 0x00, 0x04, 0x00, 0x03, 0x06, 0x00, 0x00, 0x80, 0x00, 0x80, + 0x00, 0x02, 0x00, 0x00, 0x09, 0x00, 0x0c, 0x80, 0x00, 0x80, 0x00, 0x06, 0x00, 0x00, 0x48, 0x00, + 0x37, 0x01, 0x02, 0x00, 0x00, 0x01, 0x0c, 0x48, 0x00, 0x37, 0x01, 0x06, 0x01, 0x00, 0x00, 0x04, + 0x24, 0x00, 0x02, 0x01, 0x00, 0x01, 0x0c, 0x00, 0x04, 0x24, 0x00, 0x02, 0x00, 0x00, 0x09, 0x0a, + 0x3d, 0x0f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, + 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, + 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, + 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x09, 0x18, 0xfb, 0x70, 0x06, 0x00, 0x03, + 0xff, 0xff, 0x00, 0x03, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x00, 0x80, 0x0c, 0x00, 0x0f, + 0x00, 0x01, 0x49, 0x08, 0x07, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x72, 0x00, 0x19, + 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0xff, 0xff, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, + 0xf3, 0xf2, 0x0c, 0x08, 0x42, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, + 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x10, 0x84, 0x11, + 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x3a, 0x01, 0x09, 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0x11, 0x01, + 0x11, 0x01, 0x01, 0x01, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, + 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, + 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, + 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, + 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, + 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, + 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, + 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, + 0x0a, 0x01, 0x09, 0x19, 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0x11, 0x01, 0x11, 0x01, 0x01, 0x11, + 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xdd, 0x0c, 0xf5, + 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, + 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, + 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, + 0x0a, 0x01, 0x09, 0x19, 0x18, 0xf4, 0x60, 0x00, 0x00, 0x00, 0xd0, 0x0e, 0xd0, 0x0e, 0x0e, 0x0b, + 0x01, 0x01, 0x43, 0x06, 0x02, 0xfc, 0xfc, 0x00, 0x00, 0x30, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, + 0xf5, 0x04, 0xff, 0xff, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0x08, + 0x42, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x99, 0xd6, 0x11, 0x0f, + 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x10, 0x84, 0x11, 0x0d, 0x01, 0x0b, 0xf6, + 0x11, 0x3a, 0x01, 0x09, 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, + 0x01, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, + 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, + 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, + 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, + 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, + 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, + 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, + 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, + 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0x11, 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xdd, 0x0c, 0xf5, 0x04, 0x08, 0x42, 0x11, + 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, + 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, + 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, + 0x18, 0xf4, 0x60, 0x00, 0x00, 0x00, 0xd0, 0x0e, 0xd0, 0x0e, 0x0e, 0x13, 0x02, 0x00, 0x4a, 0x08, + 0x09, 0x3f, 0x3f, 0x21, 0xfd, 0xfd, 0x87, 0x84, 0x84, 0xfc, 0x00, 0x00, 0x00, 0x32, 0x00, 0x19, + 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0xff, 0xff, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, + 0xf3, 0xf2, 0x0c, 0x08, 0x42, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, + 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x10, 0x84, 0x11, + 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x3a, 0x01, 0x09, 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0x11, 0x01, + 0x11, 0x01, 0x01, 0x01, 0x02, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, + 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, + 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, + 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, + 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, + 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, + 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, + 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, + 0x0a, 0x01, 0x09, 0x19, 0x18, 0x54, 0x40, 0x00, 0x00, 0x00, 0x10, 0x10, 0x13, 0x03, 0x02, 0x4a, + 0x06, 0x09, 0x78, 0xcc, 0xcc, 0x18, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x73, 0x00, + 0x19, 0x0a, 0x3f, 0xdd, 0x0c, 0xf5, 0x04, 0xff, 0xff, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, + 0x3e, 0xf3, 0xf2, 0x0c, 0x08, 0x42, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, + 0x0b, 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x10, 0x84, + 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x3a, 0x01, 0x09, 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0xd1, + 0x0f, 0xd1, 0x0f, 0x0f, 0x01, 0x03, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, + 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, + 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, + 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, + 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, + 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, + 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, + 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, + 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, 0x54, 0x40, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1b, 0x04, 0x00, + 0x4a, 0x09, 0x09, 0xff, 0x80, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0xff, 0x80, 0x00, 0x00, 0x31, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, + 0xff, 0xff, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0x08, 0x42, 0x11, + 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0b, + 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x10, 0x84, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x3a, + 0x01, 0x09, 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, 0x04, 0x19, + 0x0a, 0x3f, 0xdd, 0x0c, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0d, 0x0e, 0xf3, 0x11, 0x3e, + 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0b, + 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, 0xf4, 0x0a, 0x99, 0xd6, 0x11, + 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0xcf, + 0x0d, 0xcf, 0x0d, 0x0d, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, + 0x0d, 0x0e, 0xf3, 0x11, 0x3e, 0xf3, 0xf2, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0d, 0xf4, 0x11, + 0x3f, 0x0d, 0x01, 0xf3, 0x0b, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0b, 0x0c, 0xf5, 0x11, 0x3e, 0xf5, + 0xf4, 0x0a, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0b, 0xf6, 0x11, 0x0a, 0x01, 0x09, 0x19, 0x18, 0xf4, + 0x20, 0xff, 0xff, 0x00, 0x11, 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xee, 0x34, 0x3c, 0x08, 0x2d, 0x09, 0x59, 0x0d, 0x97, + 0xff, 0x00, 0x02, 0x70, 0x0d, 0x0e, 0x51, 0xc2, 0x10, 0x20, 0x1c, 0x51, 0xc2, 0x12, 0xe0, 0xd6, + 0x51, 0xc2, 0x12, 0x30, 0x1c, 0x19, 0x0a, 0x32, 0x12, 0x10, 0x84, 0x59, 0x0d, 0xc6, 0xcc, 0x12, + 0xd0, 0xf2, 0x51, 0xc2, 0x10, 0x20, 0x1c, 0x51, 0xc2, 0x12, 0xe0, 0xd6, 0x51, 0xc2, 0x12, 0x30, + 0x1c, 0x19, 0x0a, 0x3f, 0x0a, 0x12, 0xb9, 0xf9, 0x08, 0x42, 0x11, 0x0f, 0xf6, 0x0a, 0x09, 0xf6, + 0x11, 0x3e, 0xf6, 0xf7, 0x09, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x08, 0xf7, 0x11, 0x3f, 0x08, 0x01, + 0xf8, 0x08, 0x10, 0x84, 0x11, 0x0f, 0xf8, 0x08, 0x07, 0xf8, 0x11, 0x3e, 0xf8, 0xf9, 0x07, 0x99, + 0xd6, 0x11, 0x0d, 0x01, 0x06, 0xf9, 0x11, 0x0a, 0x01, 0x06, 0x19, 0x18, 0xf5, 0x60, 0x05, 0x00, + 0x00, 0x00, 0xef, 0x5a, 0xec, 0x57, 0x57, 0x0f, 0x00, 0x00, 0x46, 0x06, 0x05, 0xcc, 0x78, 0x30, + 0x78, 0xcc, 0x00, 0x00, 0x00, 0x72, 0x00, 0x19, 0x0a, 0x3f, 0x13, 0xfe, 0xfa, 0x04, 0xff, 0xff, + 0x11, 0x0f, 0xf6, 0x0a, 0x09, 0xf6, 0x11, 0x3e, 0xf6, 0xf7, 0x09, 0x08, 0x42, 0x11, 0x0d, 0x01, + 0x08, 0xf7, 0x11, 0x3f, 0x08, 0x01, 0xf8, 0x08, 0x99, 0xd6, 0x11, 0x0f, 0xf8, 0x08, 0x07, 0xf8, + 0x11, 0x3e, 0xf8, 0xf9, 0x07, 0x10, 0x84, 0x11, 0x0d, 0x01, 0x06, 0xf9, 0x11, 0x3a, 0x01, 0x06, + 0x99, 0xd6, 0x19, 0x18, 0xf0, 0x60, 0x0c, 0x01, 0x0c, 0x01, 0x01, 0x01, 0x00, 0x19, 0x0a, 0x3f, + 0x13, 0xfe, 0xfa, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf6, 0x0a, 0x09, 0xf6, 0x11, 0x3e, 0xf6, 0xf7, + 0x09, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x08, 0xf7, 0x11, 0x3f, 0x08, 0x01, 0xf8, 0x08, 0x10, 0x84, + 0x11, 0x0f, 0xf8, 0x08, 0x07, 0xf8, 0x11, 0x3e, 0xf8, 0xf9, 0x07, 0x99, 0xd6, 0x11, 0x0d, 0x01, + 0x06, 0xf9, 0x11, 0x0a, 0x01, 0x06, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0a, 0xff, 0x0a, + 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x13, 0xfe, 0xfa, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf6, 0x0a, 0x09, + 0xf6, 0x11, 0x3e, 0xf6, 0xf7, 0x09, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x08, 0xf7, 0x11, 0x3f, 0x08, + 0x01, 0xf8, 0x08, 0x10, 0x84, 0x11, 0x0f, 0xf8, 0x08, 0x07, 0xf8, 0x11, 0x3e, 0xf8, 0xf9, 0x07, + 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x06, 0xf9, 0x11, 0x0a, 0x01, 0x06, 0x19, 0x18, 0xf4, 0x20, 0xff, + 0xff, 0x00, 0x0c, 0x01, 0x0c, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x19, 0x0a, 0x0f, 0x09, 0xfe, 0x09, 0x09, 0x19, 0x18, 0xf5, 0x60, 0x06, 0xff, 0xff, + 0x00, 0x09, 0xfe, 0x12, 0x07, 0x07, 0x23, 0x05, 0x03, 0x4d, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x88, 0x01, 0x10, 0x02, 0x20, 0x04, 0x40, 0x08, 0x88, + 0x11, 0x10, 0x22, 0x20, 0x44, 0x40, 0x00, 0x00, 0x6f, 0x00, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, + 0x1f, 0x06, 0x04, 0x4c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x60, 0x00, 0xc0, + 0x01, 0x90, 0x03, 0x30, 0x06, 0x60, 0x0c, 0xc0, 0x19, 0x90, 0x33, 0x30, 0x66, 0x60, 0x70, 0x00, + 0x19, 0x0a, 0x37, 0xe3, 0x10, 0xf1, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, + 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, + 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, + 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x60, 0x00, 0x00, + 0x00, 0xd6, 0x12, 0xd2, 0x0e, 0x0e, 0x0f, 0x07, 0x01, 0x48, 0x09, 0x04, 0x08, 0x00, 0x1c, 0x00, + 0x3e, 0x00, 0x7f, 0x00, 0x35, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x10, 0x84, 0x11, + 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x0e, 0xf1, 0xf2, 0x0e, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, + 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x0e, 0xf3, + 0xf4, 0x0c, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x0a, 0x01, 0x0b, 0x19, 0x18, 0xf0, 0x60, 0x11, + 0x01, 0x11, 0x01, 0x01, 0x01, 0x07, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, + 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, + 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, + 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, + 0xd6, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, + 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, + 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, + 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, + 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0x11, + 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, + 0x0a, 0x3f, 0xdd, 0x0e, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, + 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, + 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, + 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x60, 0x00, 0x00, + 0x00, 0xd0, 0x10, 0xd0, 0x10, 0x10, 0x0f, 0x08, 0x01, 0x48, 0x09, 0x04, 0x7f, 0x00, 0x3e, 0x00, + 0x1c, 0x00, 0x08, 0x00, 0x36, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x10, 0x84, 0x11, + 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x0e, 0xf1, 0xf2, 0x0e, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, + 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x0e, 0xf3, + 0xf4, 0x0c, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x0a, 0x01, 0x0b, 0x19, 0x18, 0xf0, 0x60, 0x11, + 0x01, 0x11, 0x01, 0x01, 0x01, 0x08, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, + 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, + 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, + 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, + 0xd6, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, + 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, + 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, + 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, + 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0x11, + 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, + 0x0a, 0x3f, 0xdd, 0x0e, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, + 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, + 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, + 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x60, 0x00, 0x00, + 0x00, 0xd0, 0x10, 0xd0, 0x10, 0x10, 0x13, 0x09, 0x04, 0x4b, 0x04, 0x09, 0x00, 0x80, 0xc0, 0xe0, + 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, + 0x04, 0x10, 0x84, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x0e, 0xf1, 0xf2, 0x0e, 0x11, 0x0d, + 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x99, 0xd6, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, + 0xf3, 0x11, 0x0e, 0xf3, 0xf4, 0x0c, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x0a, 0x01, 0x0b, 0x19, + 0x18, 0xf0, 0x60, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, 0x09, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, + 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, + 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, + 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, + 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, 0x0f, 0xff, 0x0f, 0xff, + 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, + 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, + 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, + 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x20, + 0xff, 0xff, 0x00, 0x11, 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xdd, 0x0e, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, + 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, + 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, + 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, + 0xf4, 0x60, 0x00, 0x00, 0x00, 0xd0, 0x10, 0xd0, 0x10, 0x10, 0x13, 0x0a, 0x03, 0x4b, 0x04, 0x09, + 0x00, 0x10, 0x30, 0x70, 0xf0, 0x70, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x19, 0x0a, + 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x10, 0x84, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x0e, 0xf1, + 0xf2, 0x0e, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x99, 0xd6, 0x11, + 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x0e, 0xf3, 0xf4, 0x0c, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, + 0x0a, 0x01, 0x0b, 0x19, 0x18, 0xf0, 0x60, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, 0x0a, 0x19, 0x0a, + 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, + 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, + 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, + 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, 0x19, 0x18, 0xf4, 0x20, 0x10, 0x00, 0x00, + 0x0f, 0xff, 0x0f, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0x1d, 0xfe, 0xf5, 0x04, 0x08, 0x42, 0x11, 0x0f, + 0xf1, 0x0f, 0x0e, 0xf1, 0x11, 0x3e, 0xf1, 0xf2, 0x0e, 0x99, 0xd6, 0x11, 0x0d, 0x01, 0x0d, 0xf2, + 0x11, 0x3f, 0x0d, 0x01, 0xf3, 0x0d, 0x10, 0x84, 0x11, 0x0f, 0xf3, 0x0d, 0x0c, 0xf3, 0x11, 0x3e, + 0xf3, 0xf4, 0x0c, 0xff, 0xff, 0x11, 0x0d, 0x01, 0x0b, 0xf4, 0x11, 0x3a, 0x01, 0x0b, 0x99, 0xd6, + 0x19, 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0x11, 0x01, 0x11, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, + 0x84, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xce, 0x0e, 0x01, 0x01, 0xff, 0xff, + 0x1d, 0x18, 0xf4, 0x60, 0x0e, 0xe2, 0x00, 0x0b, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0xcd, 0x0e, + 0xce, 0x0f, 0x0f, 0x13, 0x0b, 0x04, 0x4b, 0x04, 0x09, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x19, 0x0a, 0x01, 0x0d, 0x19, 0x18, 0x50, 0x40, 0x0d, + 0x0d, 0x0f, 0x0c, 0x03, 0x4a, 0x07, 0x08, 0x00, 0x02, 0x06, 0x8e, 0xdc, 0xf8, 0x70, 0x20, 0x61, + 0x00, 0x19, 0x0a, 0x01, 0x0d, 0x19, 0x18, 0x50, 0x40, 0x0d, 0x0d, 0x0f, 0x0d, 0x04, 0x4a, 0x06, + 0x06, 0x78, 0xfc, 0xfc, 0xfc, 0xfc, 0x78, 0x00, 0x00, 0x68, 0x00, 0x19, 0x0a, 0x3d, 0x0d, 0x02, + 0x02, 0x99, 0xd6, 0x19, 0x18, 0xd0, 0x60, 0x0e, 0x10, 0x02, 0x02, 0x13, 0x0e, 0x02, 0x4a, 0x0b, + 0x05, 0x04, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x3f, 0x80, 0x7f, 0xc0, 0x00, 0x00, 0x35, 0x00, 0x19, + 0x0a, 0x01, 0x0f, 0x19, 0x18, 0x54, 0x40, 0x10, 0x00, 0x00, 0x0f, 0x0f, 0x01, 0x0e, 0x19, 0x0a, + 0x03, 0xca, 0x0f, 0x19, 0x18, 0xf4, 0x20, 0xff, 0xff, 0x00, 0xcb, 0x10, 0xcb, 0x10, 0x10, 0x11, + 0xf4, 0x20, 0x10, 0x84, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x01, 0x0f, 0x19, 0x18, + 0x54, 0x40, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x13, 0x0f, 0x02, 0x4a, 0x0b, 0x05, 0x7f, 0xc0, 0x3f, + 0x80, 0x1f, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x36, 0x00, 0x19, 0x0a, 0x01, 0x0f, 0x19, + 0x18, 0x54, 0x40, 0x10, 0x00, 0x00, 0x0f, 0x0f, 0x01, 0x0f, 0x19, 0x0a, 0x01, 0x0f, 0x19, 0x18, + 0xf4, 0x20, 0xff, 0xff, 0x00, 0x10, 0x01, 0x10, 0x01, 0x01, 0x11, 0xf4, 0x20, 0x10, 0x84, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, 0x0a, 0x3f, 0xd3, 0x0f, 0xfe, 0xfe, 0xff, 0xff, 0x19, 0x18, + 0xf4, 0x60, 0x00, 0x00, 0x00, 0xd3, 0x0f, 0xd1, 0x0d, 0x0d, 0x1b, 0x10, 0x02, 0x4c, 0x0a, 0x0a, + 0x1e, 0x00, 0x7f, 0x80, 0x7f, 0x80, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0x7f, 0x80, + 0x7f, 0x80, 0x1e, 0x00, 0x6e, 0x00, 0x11, 0x00, 0x40, 0x17, 0x11, 0x03, 0x4a, 0x09, 0x08, 0x01, + 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0xc3, 0x00, 0x3c, 0x00, 0x6d, + 0x00, 0x11, 0x00, 0x40, 0x17, 0x12, 0x02, 0x4c, 0x09, 0x08, 0x1e, 0x00, 0x61, 0x80, 0x40, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x6c, 0x00, 0x11, 0x00, 0x40, 0x1b, + 0x13, 0x03, 0x4b, 0x0a, 0x0a, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x80, 0x00, 0x80, 0xc3, 0x00, 0x3c, 0x00, 0x6b, 0x00, 0x11, 0x00, 0x40, 0x1b, 0x14, + 0x01, 0x4d, 0x0a, 0x0a, 0x0f, 0x00, 0x30, 0xc0, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x80, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x6a, 0x00, 0x11, 0x54, 0x40, 0xff, 0xff, 0x00, + 0x0d, 0x0d, 0x1b, 0x15, 0x02, 0x4b, 0x09, 0x09, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, + 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0x00, 0x00, 0x67, 0x00, 0x11, 0x04, + 0x40, 0x99, 0xd6, 0x00, 0x1f, 0x16, 0x01, 0x4c, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0xff, 0xe0, + 0x00, 0x00, 0x66, 0x00, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x1b, 0x17, 0x01, 0x4c, 0x0a, 0x0a, + 0xff, 0xc0, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x65, 0x00, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x23, 0x18, 0x00, 0x4d, + 0x0d, 0x0d, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xff, 0xf8, 0x00, 0x00, 0x64, 0x00, + 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x1f, 0x19, 0x00, 0x4d, 0x0c, 0x0c, 0xff, 0xf0, 0x80, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x63, 0x00, 0x11, 0x54, 0x40, 0xff, 0xff, 0x00, 0x0d, 0x0d, 0x01, 0x15, + 0x11, 0x04, 0x40, 0x99, 0xd6, 0x00, 0x01, 0x16, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, + 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, + 0x11, 0x04, 0x40, 0x00, 0x00, 0x00, 0x0f, 0x1a, 0x03, 0x4b, 0x07, 0x08, 0x00, 0x02, 0x06, 0x8e, + 0xdc, 0xf8, 0x70, 0x20, 0x62, 0x00, 0x11, 0x54, 0x40, 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x15, + 0x11, 0x00, 0x40, 0x01, 0x16, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, 0x40, + 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, 0x11, 0x54, 0x40, + 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x15, 0x11, 0x00, 0x40, 0x01, 0x16, 0x11, 0x04, 0x40, 0x08, + 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, 0x40, 0x10, + 0x84, 0x00, 0x01, 0x19, 0x11, 0x04, 0x40, 0x00, 0x00, 0x00, 0x01, 0x1a, 0x11, 0xf4, 0x60, 0x99, + 0xd6, 0x00, 0xcc, 0x0d, 0xcc, 0x0d, 0x0d, 0x01, 0x15, 0x11, 0x00, 0x40, 0x01, 0x16, 0x11, 0x04, + 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, + 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, 0x11, 0x00, 0x40, 0x01, 0x1a, 0x19, 0x0a, 0x33, 0x0d, 0x0d, + 0x00, 0x00, 0x19, 0x18, 0x54, 0x40, 0xff, 0xff, 0x00, 0x0d, 0x0d, 0x01, 0x10, 0x11, 0x04, 0x40, + 0x99, 0xd6, 0x00, 0x01, 0x11, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x12, 0x11, 0x04, 0x40, + 0xff, 0xff, 0x00, 0x01, 0x13, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x14, 0x19, 0x0a, 0x01, + 0x0d, 0x19, 0x18, 0x54, 0x40, 0xff, 0xff, 0x00, 0x0d, 0x0d, 0x01, 0x10, 0x11, 0x04, 0x40, 0x99, + 0xd6, 0x00, 0x01, 0x11, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x12, 0x11, 0x04, 0x40, 0xff, + 0xff, 0x00, 0x01, 0x13, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x14, 0x11, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x0b, 0x1b, 0x05, 0x49, 0x04, 0x04, 0x60, 0xf0, 0xf0, 0x60, 0x69, 0x00, 0x19, 0x0a, + 0x01, 0x0d, 0x19, 0x18, 0x54, 0x40, 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x10, 0x11, 0x00, 0x40, + 0x01, 0x11, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x12, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, + 0x01, 0x13, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x14, 0x19, 0x0a, 0x01, 0x0d, 0x19, 0x18, + 0x54, 0x40, 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x10, 0x11, 0x00, 0x40, 0x01, 0x11, 0x11, 0x04, + 0x40, 0x08, 0x42, 0x00, 0x01, 0x12, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x01, 0x13, 0x11, 0x04, + 0x40, 0x10, 0x84, 0x00, 0x01, 0x14, 0x11, 0x04, 0x40, 0x00, 0x00, 0x00, 0x01, 0x1b, 0x19, 0x0a, + 0x03, 0xcc, 0x0d, 0x19, 0x18, 0xf4, 0x60, 0x99, 0xd6, 0x00, 0xcc, 0x0d, 0xcc, 0x0d, 0x0d, 0x01, + 0x10, 0x11, 0x00, 0x40, 0x01, 0x11, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x12, 0x11, 0x04, + 0x40, 0xff, 0xff, 0x00, 0x01, 0x13, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x14, 0x11, 0x00, + 0x40, 0x01, 0x1b, 0x03, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x08, 0x08, 0x81, 0x08, 0xaa, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0x09, 0x01, 0x7f, 0x02, 0x0d, 0x00, 0x1a, 0x01, 0x0d, + 0x00, 0x0d, 0x00, 0xf0, 0xff, 0xff, 0x00, 0x99, 0xd6, 0x00, 0x81, 0x19, 0x18, 0x54, 0x40, 0x99, + 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x16, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, + 0x40, 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, 0x11, 0x00, + 0x40, 0x01, 0x1a, 0x11, 0x54, 0x40, 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x15, 0x11, 0x00, 0x40, + 0x01, 0x16, 0x11, 0x04, 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, + 0x01, 0x18, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, 0x11, 0x00, 0x40, 0x01, 0x1a, 0x11, + 0x54, 0x40, 0x99, 0xd6, 0x00, 0x0d, 0x0d, 0x01, 0x15, 0x11, 0x00, 0x40, 0x01, 0x16, 0x11, 0x04, + 0x40, 0x08, 0x42, 0x00, 0x01, 0x17, 0x11, 0x04, 0x40, 0xff, 0xff, 0x00, 0x01, 0x18, 0x11, 0x04, + 0x40, 0x10, 0x84, 0x00, 0x01, 0x19, 0x11, 0x00, 0x40, 0x01, 0x1a, 0x19, 0x0a, 0x31, 0x34, 0xff, + 0xff, 0x19, 0x18, 0x54, 0x40, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x1b, 0x1c, 0x02, 0x4b, 0x09, 0x09, + 0xc1, 0x80, 0xe3, 0x80, 0x77, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x77, 0x00, 0xe3, 0x80, + 0xc1, 0x80, 0x00, 0x00, 0x72, 0x00, 0x19, 0x0a, 0x03, 0xcc, 0x0d, 0x1d, 0x18, 0xf0, 0x60, 0xa0, + 0x45, 0x45, 0xcc, 0x0d, 0xcc, 0x0d, 0x0d, 0x1b, 0x1d, 0x01, 0x4b, 0x0a, 0x09, 0x3f, 0xc0, 0x3f, + 0xc0, 0x20, 0x40, 0xff, 0x40, 0xff, 0x40, 0x81, 0xc0, 0x81, 0x00, 0x81, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x32, 0x00, 0x19, 0x0a, 0x01, 0x0d, 0x19, 0x18, 0x50, 0x40, 0x0d, 0x0d, 0x1b, 0x1e, 0x01, + 0x4c, 0x0a, 0x0a, 0xff, 0xc0, 0xff, 0xc0, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x40, 0x80, + 0x40, 0x80, 0x40, 0x80, 0x40, 0xff, 0xc0, 0x31, 0x00, 0x19, 0x0a, 0x01, 0x0d, 0x19, 0x18, 0x50, + 0x40, 0x0d, 0x0d, 0x0b, 0x1f, 0x02, 0x44, 0x07, 0x02, 0xfe, 0xfe, 0x00, 0x00, 0x30, 0x00, 0x19, + 0x0a, 0x3d, 0x0d, 0x03, 0x03, 0x99, 0xd6, 0x19, 0x18, 0xd4, 0x60, 0xff, 0xff, 0x00, 0x0e, 0x11, + 0x03, 0x03, 0x23, 0x20, 0x00, 0x4d, 0x0d, 0x0d, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, + 0x10, 0x00, 0x88, 0x00, 0x44, 0x00, 0x22, 0x00, 0x11, 0x00, 0x88, 0x80, 0x44, 0x40, 0x22, 0x20, + 0x11, 0x10, 0x00, 0x00, 0x78, 0x00, 0x11, 0x04, 0x40, 0x10, 0x84, 0x00, 0x1f, 0x21, 0x00, 0x4c, + 0x0c, 0x0c, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x30, 0x00, 0x98, 0x00, 0xcc, 0x00, + 0x66, 0x00, 0x33, 0x00, 0x99, 0x80, 0xcc, 0xc0, 0x66, 0x60, 0x79, 0x00, 0x19, 0x0a, 0x3d, 0x10, + 0xfd, 0xfd, 0xff, 0xff, 0x19, 0x18, 0xd4, 0x60, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0xfd, 0xfd, 0x13, + 0x22, 0x05, 0x4b, 0x04, 0x09, 0x00, 0x10, 0x30, 0x70, 0xf0, 0x70, 0x30, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x77, 0x00, 0x02, 0xff, 0xff, 0x0d, 0x0a, 0x3f, 0x0e, 0x00, 0x00, 0xff, 0x03, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x06, 0x02, 0x00, 0x48, 0x00, 0x37, + 0x01, 0x02, 0x02, 0x00, 0x09, 0x00, 0x0c, 0x48, 0x00, 0x37, 0x01, 0x03, 0xcf, 0x04, 0xa2, 0x0c, + 0x05, 0x40, 0x44, 0xd1, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, + 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, + 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, 0x08, 0x42, 0xff, 0xff, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, + 0xff, 0xff, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, + 0xff, 0xff, 0x99, 0xd6, 0x10, 0x84, 0x08, 0x42, 0x1c, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x75, 0xc6, 0x66, 0x29, 0x00, 0x09, 0x68, 0x10, 0x00, 0x08, 0x68, 0x10, 0x84, + 0x00, 0x20, 0x00, 0x07, 0x6b, 0x99, 0xd6, 0x05, 0x6b, 0x99, 0xd6, 0x00, 0x03, 0x6e, 0xff, 0xff, + 0x02, 0x6e, 0xff, 0xff, 0x00, 0x10, 0xc0, 0x00, 0xf7, 0xbd, 0x01, 0xc0, 0x00, 0x08, 0x42, 0xc0, + 0x00, 0xff, 0xff, 0x81, 0x08, 0x42, 0xce, 0x66, 0x29, 0x01, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, + 0x2e, 0x01, 0x81, 0x08, 0x42, 0xce, 0x66, 0x29, 0x02, 0x81, 0x10, 0x84, 0x06, 0x82, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xcd, 0x89, 0x52, 0x03, 0x2d, 0x03, 0x83, 0x10, 0x84, 0x99, 0xd6, 0x99, 0xd6, + 0xc9, 0x99, 0xd6, 0x1a, 0x82, 0x10, 0x00, 0x10, 0x00, 0x0a, 0x29, 0x09, 0x27, 0x0c, 0x67, 0x99, + 0xd6, 0x15, 0x27, 0x1d, 0x82, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x67, 0x99, 0xd6, 0x00, 0x19, 0xd0, + 0x30, 0x89, 0xd6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x99, 0xd6, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x83, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xd8, 0x89, + 0xd6, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x83, 0x99, 0xd6, 0x10, 0x00, 0x10, + 0x00, 0x1a, 0x68, 0x00, 0x00, 0x09, 0x86, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x99, 0xd6, 0x18, 0x68, 0x00, 0x00, 0x1b, 0x68, 0x99, 0xd6, 0x06, 0x86, 0x99, 0xd6, 0x10, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x99, 0xd6, 0x19, 0x6b, 0x99, 0xd6, 0x03, 0xcc, 0x89, + 0x52, 0x08, 0x68, 0x99, 0xd6, 0x05, 0x6b, 0x99, 0xd6, 0x04, 0x2c, 0x03, 0x6e, 0x08, 0x42, 0x02, + 0x6e, 0xff, 0xff, 0x02, 0x6e, 0xff, 0xff, 0x02, 0x6e, 0x08, 0x42, 0x10, 0x81, 0x08, 0x42, 0x70, + 0xff, 0xff, 0x60, 0x00, 0x08, 0x42, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0x81, 0x08, 0x42, 0xce, 0x66, + 0x29, 0x01, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, 0x2e, 0x02, 0xcd, 0x89, 0x52, 0x03, 0x89, 0x10, + 0x84, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x2d, 0x03, 0x2d, 0x05, 0xc6, 0x99, 0xd6, 0x0c, 0x84, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x99, 0xd6, 0x0a, 0xc6, 0x89, 0xd6, 0x0e, 0x82, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x84, 0x99, + 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x1c, 0x40, 0x35, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd0, 0x4e, 0x99, 0xd6, 0x03, 0x00, 0x00, 0x60, 0x00, 0x80, 0x01, 0x78, 0x01, 0x00, 0x82, + 0x10, 0x00, 0x10, 0x00, 0x0c, 0x40, 0x2c, 0x03, 0xe0, 0x05, 0x00, 0x00, 0x00, 0xd6, 0x89, 0xd6, + 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x4e, 0x99, 0xd6, 0x3b, 0x00, 0x00, 0x00, 0x28, 0x80, + 0x1d, 0x00, 0x78, 0x00, 0x86, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x0c, 0x85, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x40, 0x2b, 0x01, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x89, 0xd6, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x99, + 0xd6, 0x16, 0x86, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x0a, + 0x69, 0x99, 0xd6, 0x04, 0xcc, 0x89, 0x52, 0x07, 0x69, 0x99, 0xd6, 0x08, 0x68, 0x99, 0xd6, 0x03, + 0x6e, 0xff, 0xff, 0x02, 0x6e, 0x08, 0x42, 0x02, 0x6e, 0xff, 0xff, 0x02, 0x6e, 0xff, 0xff, 0x01, + 0x70, 0x08, 0x42, 0x70, 0xff, 0xff, 0x60, 0x00, 0x08, 0x42, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0x81, + 0x08, 0x42, 0xce, 0x66, 0x29, 0x01, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, 0x2e, 0x02, 0xcd, 0x89, + 0x52, 0x03, 0x8a, 0x10, 0x84, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x2d, 0x03, 0x8d, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x99, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x99, + 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x06, 0xc6, 0x99, 0xd6, 0x1a, 0xc6, 0x89, 0xd6, 0x0a, 0x66, 0x10, + 0x84, 0x1b, 0x6a, 0x99, 0xd6, 0x1b, 0x81, 0x99, 0xd6, 0x09, 0x6a, 0x99, 0xd6, 0x16, 0x6a, 0x99, + 0xd6, 0x06, 0x6a, 0x99, 0xd6, 0xf0, 0x94, 0x01, 0xcc, 0x89, 0x52, 0x00, 0x03, 0x6e, 0xff, 0xff, + 0x02, 0x6e, 0x08, 0x42, 0x02, 0x6e, 0xff, 0xff, 0x02, 0x6e, 0xff, 0xff, 0x01, 0x70, 0x08, 0x42, + 0x70, 0xff, 0xff, 0x60, 0x00, 0x08, 0x42, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0x81, 0x08, 0x42, 0xce, + 0x66, 0x29, 0x01, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, 0x2e, 0x02, 0xcd, 0x89, 0x52, 0x03, 0x10, + 0x2d, 0x03, 0x2d, 0x17, 0x88, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x88, 0xff, 0xff, 0xff, 0xff, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x99, 0xd6, 0xff, 0xff, 0xff, 0xff, 0x07, 0x88, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, + 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x09, 0x88, 0x99, 0xd6, 0x00, 0x00, 0x00, + 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x07, 0x88, 0x10, 0x00, 0x10, + 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, 0x10, 0x00, 0x08, 0x89, 0x10, + 0x84, 0x10, 0x84, 0xff, 0xff, 0xff, 0xff, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, 0x10, 0x84, 0x99, + 0xd6, 0x07, 0x88, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, + 0x00, 0x99, 0xd6, 0x0a, 0x86, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, + 0xd6, 0x08, 0x88, 0x99, 0xd6, 0x10, 0x00, 0x10, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, 0x10, + 0x00, 0x99, 0xd6, 0x08, 0x88, 0x99, 0xd6, 0x10, 0x84, 0x10, 0x84, 0xff, 0xff, 0xff, 0xff, 0x10, + 0x84, 0x10, 0x84, 0x99, 0xd6, 0x09, 0x86, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x99, 0xd6, 0x0c, 0x84, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x0a, 0x86, 0x99, + 0xd6, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x99, 0xd6, 0x0a, 0x86, 0x99, 0xd6, 0x10, + 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x99, 0xd6, 0x0b, 0x84, 0x99, 0xd6, 0x00, 0x00, 0x00, + 0x00, 0x99, 0xd6, 0x0d, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x84, 0x99, + 0xd6, 0x10, 0x00, 0x10, 0x00, 0x99, 0xd6, 0x0c, 0x85, 0x99, 0xd6, 0x10, 0x84, 0x10, 0x84, 0xff, + 0xff, 0xff, 0xff, 0x0b, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x86, 0x00, + 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x84, 0x10, 0x00, 0x10, + 0x00, 0x10, 0x00, 0x10, 0x00, 0x0c, 0x86, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0xff, + 0xff, 0xff, 0xff, 0x09, 0x86, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x88, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x86, 0x10, 0x00, 0x10, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, 0x10, + 0x00, 0x0a, 0x88, 0x10, 0x84, 0x10, 0x84, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, 0x10, 0x84, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x88, 0x00, 0x00, 0x00, 0x00, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, + 0xd6, 0x00, 0x00, 0x00, 0x00, 0x09, 0x6a, 0x99, 0xd6, 0x05, 0x88, 0x10, 0x00, 0x10, 0x00, 0x99, + 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x00, 0x10, 0x00, 0x08, 0x89, 0x10, 0x84, 0x10, + 0x84, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x10, 0x84, 0x10, 0x84, 0x99, 0xd6, 0x07, + 0x6a, 0x99, 0xd6, 0x16, 0x6a, 0x99, 0xd6, 0x06, 0x6a, 0x99, 0xd6, 0x14, 0x2c, 0x00, 0x03, 0x6e, + 0xff, 0xff, 0x02, 0x6e, 0x08, 0x42, 0x02, 0x6e, 0xff, 0xff, 0x02, 0xcb, 0x66, 0x29, 0x84, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x42, 0x09, 0x0d, 0xdf, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x03, 0x15, 0x00, 0xa2, 0x0c, + 0x05, 0x40, 0x40, 0x17, 0xff, 0xff, 0x00, 0x1c, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xbc, 0x0f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x0a, 0x40, + 0xc8, 0x03, 0xf4, 0x00, 0xa2, 0x0c, 0x05, 0x40, 0x40, 0xf6, 0xff, 0xff, 0xc0, 0x2c, 0x2d, 0x09, + 0x84, 0x2d, 0x09, 0x2d, 0x09, 0x2d, 0x09, 0x2d, 0x09, 0x00, 0x22, 0xc0, 0x10, 0x25, 0x4b, 0x02, + 0x30, 0x02, 0x2a, 0x02, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, 0x2e, 0x03, 0xfd, 0x2e, 0x03, 0xfd, + 0x29, 0x03, 0xcd, 0x89, 0x52, 0x03, 0x2d, 0x05, 0x2d, 0x05, 0x29, 0x06, 0xc6, 0x99, 0xd6, 0x09, + 0x29, 0x1f, 0x43, 0x03, 0x00, 0x00, 0x01, 0x27, 0x0b, 0x44, 0xc3, 0x00, 0x00, 0xc0, 0x68, 0x99, + 0xd6, 0x18, 0x48, 0xa5, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc2, 0x5a, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x81, 0x99, 0xd6, 0x48, 0x05, 0x80, 0x05, 0x00, 0x00, 0xfc, + 0x01, 0x50, 0x40, 0x69, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x80, 0x06, 0x00, + 0x00, 0x02, 0x6a, 0x99, 0xd6, 0x1c, 0x86, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0x2d, + 0x09, 0x2d, 0x09, 0x6f, 0xff, 0xff, 0x02, 0x6e, 0xff, 0xff, 0x04, 0x6e, 0xff, 0xff, 0x04, 0xc9, + 0x66, 0x29, 0x02, 0x60, 0x5e, 0x2d, 0x09, 0xc0, 0x30, 0x2d, 0x09, 0xf0, 0xc0, 0x09, 0xc0, 0x10, + 0x08, 0x42, 0x00, 0x00, 0xfd, 0xce, 0x18, 0xc6, 0x01, 0xfd, 0x2e, 0x00, 0x02, 0xcd, 0x89, 0x52, + 0x03, 0x83, 0x99, 0xd6, 0x99, 0xd6, 0x99, 0xd6, 0xc9, 0xef, 0x7b, 0x81, 0x99, 0xd6, 0x00, 0x05, + 0xc9, 0x89, 0xd6, 0x07, 0x69, 0x10, 0x84, 0x00, 0x08, 0x27, 0x09, 0x82, 0xff, 0xff, 0x99, 0xd6, + 0xd0, 0x69, 0x89, 0x52, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x51, 0x0e, 0xc0, 0x40, 0x38, 0x03, 0xa8, 0x00, 0xa2, 0x0c, 0x05, 0x40, 0x40, 0xaa, + 0xff, 0xff, 0xc8, 0x2d, 0x09, 0x00, 0x14, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0xc6, 0x25, 0x4b, 0x00, 0x1a, 0xd8, 0x18, 0xc6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf7, 0xc0, 0x01, 0x89, 0x52, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, + 0x00, 0x01, 0x99, 0xd6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd0, 0x3b, 0xef, + 0x7b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x2d, 0x09, 0x00, 0x58, 0xf3, 0x7c, + 0x0b, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x0a, 0x40, 0xc8, +}; + +int init_mppc_suite(void) +{ + return 0; +} + +int clean_mppc_suite(void) +{ + return 0; +} + +int add_mppc_suite(void) +{ + add_test_suite(mppc); + add_test_function(mppc); + return 0; +} + +void test_mppc(void) +{ + rdpRdp rdp; + struct rdp_mppc rmppc; + uint32_t roff; + uint32_t rlen; + long int dur; + + struct timeval start_time; + struct timeval end_time; + + rdp.mppc = &rmppc; + rdp.mppc->history_buf = calloc(1, RDP6_HISTORY_BUF_SIZE); + CU_ASSERT(rdp.mppc->history_buf != NULL) + rdp.mppc->history_ptr = rdp.mppc->history_buf; + + + /* save starting time */ + gettimeofday(&start_time, NULL); + + /* uncompress data */ + CU_ASSERT(decompress_rdp_5(&rdp, compressed_rd5, sizeof(compressed_rd5), + PACKET_COMPRESSED, &roff, &rlen) == true); + + /* get end time */ + gettimeofday(&end_time, NULL); + + CU_ASSERT(memcmp(decompressed_rd5, rdp.mppc->history_buf, sizeof(decompressed_rd5)) == 0); + free(rdp.mppc->history_buf); + + /* print time taken */ + dur = ((end_time.tv_sec - start_time.tv_sec) * 1000000) + (end_time.tv_usec - start_time.tv_usec); + //printf("test_mppc: decompressed data in %ld micro seconds\n", dur); +} + diff --git a/cunit/test_mppc.h b/cunit/test_mppc.h new file mode 100644 index 0000000..9059dbb --- /dev/null +++ b/cunit/test_mppc.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Microsoft Point to Point compression (MPPC) Unit Tests + * + * Copyright 2011 Laxmikant Rashinkar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_mppc_suite(void); +int clean_mppc_suite(void); +int add_mppc_suite(void); + +void test_mppc(void); diff --git a/cunit/test_orders.c b/cunit/test_orders.c new file mode 100644 index 0000000..6ae8bfd --- /dev/null +++ b/cunit/test_orders.c @@ -0,0 +1,772 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Drawing Orders Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "test_orders.h" +#include "libfreerdp-core/orders.h" +#include "libfreerdp-core/update.h" + +ORDER_INFO* orderInfo; + +int init_orders_suite(void) +{ + orderInfo = (ORDER_INFO*) malloc(sizeof(ORDER_INFO)); + return 0; +} + +int clean_orders_suite(void) +{ + free(orderInfo); + return 0; +} + +int add_orders_suite(void) +{ + add_test_suite(orders); + + add_test_function(read_dstblt_order); + add_test_function(read_patblt_order); + add_test_function(read_scrblt_order); + add_test_function(read_opaque_rect_order); + add_test_function(read_draw_nine_grid_order); + add_test_function(read_multi_opaque_rect_order); + add_test_function(read_line_to_order); + add_test_function(read_polyline_order); + add_test_function(read_glyph_index_order); + add_test_function(read_fast_index_order); + add_test_function(read_fast_glyph_order); + add_test_function(read_polygon_cb_order); + + add_test_function(read_cache_bitmap_order); + add_test_function(read_cache_bitmap_v2_order); + add_test_function(read_cache_bitmap_v3_order); + add_test_function(read_cache_brush_order); + + add_test_function(read_create_offscreen_bitmap_order); + add_test_function(read_switch_surface_order); + + add_test_function(update_recv_orders); + + return 0; +} + +uint8 dstblt_order[] = "\x48\x00\x37\x01"; + +void test_read_dstblt_order(void) +{ + STREAM _s, *s; + DSTBLT_ORDER dstblt; + + s = &_s; + s->p = s->data = dstblt_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x0C; + memset(&dstblt, 0, sizeof(DSTBLT_ORDER)); + + update_read_dstblt_order(s, orderInfo, &dstblt); + + CU_ASSERT(dstblt.nLeftRect == 0); + CU_ASSERT(dstblt.nTopRect == 0); + CU_ASSERT(dstblt.nWidth == 72); + CU_ASSERT(dstblt.nHeight == 311); + CU_ASSERT(dstblt.bRop == 0); + + CU_ASSERT(stream_get_length(s) == (sizeof(dstblt_order) - 1)); +} + +uint8 patblt_order[] = "\x1a\x00\xc3\x01\x0d\x00\x0d\x00\xf0\xff\xff\x00\x5b\xef\x00\x81"; + +void test_read_patblt_order(void) +{ + STREAM _s, *s; + PATBLT_ORDER patblt; + + s = &_s; + s->p = s->data = patblt_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x027F; + memset(&patblt, 0, sizeof(PATBLT_ORDER)); + + update_read_patblt_order(s, orderInfo, &patblt); + + CU_ASSERT(patblt.nLeftRect == 26); + CU_ASSERT(patblt.nTopRect == 451); + CU_ASSERT(patblt.nWidth == 13); + CU_ASSERT(patblt.nHeight == 13); + CU_ASSERT(patblt.bRop == 240); + CU_ASSERT(patblt.backColor == 0x00FFFF); + CU_ASSERT(patblt.foreColor == 0x00EF5B); + CU_ASSERT(patblt.brush.x == 0); + CU_ASSERT(patblt.brush.y == 0); + CU_ASSERT(patblt.brush.style == (BMF_1BPP | CACHED_BRUSH)); + + CU_ASSERT(stream_get_length(s) == (sizeof(patblt_order) - 1)); +} + +uint8 scrblt_order[] = "\x07\x00\xa1\x01\xf1\x00\xcc\x2f\x01\x8e\x00"; + +void test_read_scrblt_order(void) +{ + STREAM _s, *s; + SCRBLT_ORDER scrblt; + + s = &_s; + s->p = s->data = scrblt_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x7D; + memset(&scrblt, 0, sizeof(SCRBLT_ORDER)); + + update_read_scrblt_order(s, orderInfo, &scrblt); + + CU_ASSERT(scrblt.nLeftRect == 7); + CU_ASSERT(scrblt.nTopRect == 0); + CU_ASSERT(scrblt.nWidth == 417); + CU_ASSERT(scrblt.nHeight == 241); + CU_ASSERT(scrblt.bRop == 204); + CU_ASSERT(scrblt.nXSrc == 303); + CU_ASSERT(scrblt.nYSrc == 142); + + CU_ASSERT(stream_get_length(s) == (sizeof(scrblt_order) - 1)); +} + +uint8 opaque_rect_order[] = "\x00\x04\x00\x03\x73\x02\x06"; + +void test_read_opaque_rect_order(void) +{ + STREAM _s, *s; + OPAQUE_RECT_ORDER opaque_rect; + + s = &_s; + s->p = s->data = opaque_rect_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x7C; + memset(&opaque_rect, 0, sizeof(OPAQUE_RECT_ORDER)); + + update_read_opaque_rect_order(s, orderInfo, &opaque_rect); + + CU_ASSERT(opaque_rect.nLeftRect == 0); + CU_ASSERT(opaque_rect.nTopRect == 0); + CU_ASSERT(opaque_rect.nWidth == 1024); + CU_ASSERT(opaque_rect.nHeight == 768); + CU_ASSERT(opaque_rect.color == 0x00060273); + + CU_ASSERT(stream_get_length(s) == (sizeof(opaque_rect_order) - 1)); +} + +uint8 draw_nine_grid_order[] = "\xfb\xf9\x0d\x00"; + +void test_read_draw_nine_grid_order(void) +{ + STREAM _s, *s; + DRAW_NINE_GRID_ORDER draw_nine_grid; + + s = &_s; + s->p = s->data = draw_nine_grid_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x1C; + orderInfo->deltaCoordinates = true; + + memset(&draw_nine_grid, 0, sizeof(DRAW_NINE_GRID_ORDER)); + draw_nine_grid.srcRight = 38; + draw_nine_grid.srcBottom = 40; + + update_read_draw_nine_grid_order(s, orderInfo, &draw_nine_grid); + + CU_ASSERT(draw_nine_grid.srcLeft == 0); + CU_ASSERT(draw_nine_grid.srcTop == 0); + CU_ASSERT(draw_nine_grid.srcRight == 33); + CU_ASSERT(draw_nine_grid.srcBottom == 33); + CU_ASSERT(draw_nine_grid.bitmapId == 13); + + CU_ASSERT(stream_get_length(s) == (sizeof(draw_nine_grid_order) - 1)); +} + + +uint8 multi_opaque_rect_order[] = + "\x87\x01\x1c\x01\xf1\x00\x12\x00\x5c\xef\x04\x16\x00\x08\x40\x81" + "\x87\x81\x1c\x80\xf1\x01\x01\x01\x10\x80\xf0\x01\x10\xff\x10\x10" + "\x80\xf1\x01"; + +void test_read_multi_opaque_rect_order(void) +{ + STREAM _s, *s; + MULTI_OPAQUE_RECT_ORDER multi_opaque_rect; + + s = &_s; + s->p = s->data = multi_opaque_rect_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x01BF; + memset(&multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER)); + + update_read_multi_opaque_rect_order(s, orderInfo, &multi_opaque_rect); + + CU_ASSERT(multi_opaque_rect.nLeftRect == 391); + CU_ASSERT(multi_opaque_rect.nTopRect == 284); + CU_ASSERT(multi_opaque_rect.nWidth == 241); + CU_ASSERT(multi_opaque_rect.nHeight == 18); + CU_ASSERT(multi_opaque_rect.color == 0x0000EF5C); + CU_ASSERT(multi_opaque_rect.cbData == 22); + CU_ASSERT(multi_opaque_rect.numRectangles == 4); + + CU_ASSERT(multi_opaque_rect.rectangles[1].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[1].top == 284); + CU_ASSERT(multi_opaque_rect.rectangles[1].width == 241); + CU_ASSERT(multi_opaque_rect.rectangles[1].height == 1); + + CU_ASSERT(multi_opaque_rect.rectangles[2].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[2].top == 285); + CU_ASSERT(multi_opaque_rect.rectangles[2].width == 1); + CU_ASSERT(multi_opaque_rect.rectangles[2].height == 16); + + CU_ASSERT(multi_opaque_rect.rectangles[3].left == 631); + CU_ASSERT(multi_opaque_rect.rectangles[3].top == 285); + CU_ASSERT(multi_opaque_rect.rectangles[3].width == 1); + CU_ASSERT(multi_opaque_rect.rectangles[3].height == 16); + + CU_ASSERT(multi_opaque_rect.rectangles[4].left == 391); + CU_ASSERT(multi_opaque_rect.rectangles[4].top == 301); + CU_ASSERT(multi_opaque_rect.rectangles[4].width == 241); + CU_ASSERT(multi_opaque_rect.rectangles[4].height == 1); + + CU_ASSERT(stream_get_length(s) == (sizeof(multi_opaque_rect_order) - 1)); +} + +uint8 line_to_order[] = "\x03\xb1\x0e\xa6\x5b\xef\x00"; + +void test_read_line_to_order(void) +{ + STREAM _s, *s; + LINE_TO_ORDER line_to; + + s = &_s; + s->p = s->data = line_to_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x021E; + orderInfo->deltaCoordinates = true; + + memset(&line_to, 0, sizeof(LINE_TO_ORDER)); + line_to.nXStart = 826; + line_to.nYStart = 350; + line_to.nXEnd = 829; + line_to.nYEnd = 347; + + update_read_line_to_order(s, orderInfo, &line_to); + + CU_ASSERT(line_to.nXStart == 829); + CU_ASSERT(line_to.nYStart == 271); + CU_ASSERT(line_to.nXEnd == 843); + CU_ASSERT(line_to.nYEnd == 257); + CU_ASSERT(line_to.backColor == 0); + CU_ASSERT(line_to.bRop2 == 0); + CU_ASSERT(line_to.penStyle == 0); + CU_ASSERT(line_to.penWidth == 0); + CU_ASSERT(line_to.penColor == 0x00EF5B); + + CU_ASSERT(stream_get_length(s) == (sizeof(line_to_order) - 1)); +} + +uint8 polyline_order[] = + "\xf8\x01\xb8\x02\x00\xc0\x00\x20\x6c\x00\x00\x00\x00\x00\x04\x00" + "\x00\xff\x7e\x76\xff\x41\x6c\xff\x24\x62\xff\x2b\x59\xff\x55\x51" + "\xff\x9c\x49\x73\x43\x80\x4d\xff\xbe\x80\x99\xff\xba\x80\xcd\xff" + "\xb7\x80\xde\xff\xb6\x80\xca\xff\xb6\x80\x96\xff\xb7\x80\x48\xff" + "\xba\x6f\xff\xbe\xff\x97\x43\xff\x52\x4a\xff\x2b\x51\xff\x24\x59" + "\xff\x44\x63\xff\x81\x6c\x56\x76\x2f\x80\x82\x0a\x80\xbf\x14\x80" + "\xdd\x1e\x80\xd4\x27\x80\xab\x2f\x80\x64\x37\x0d\x3d\xff\xb3\x80" + "\x42\xff\x67\x80\x46"; + +void test_read_polyline_order(void) +{ + STREAM _s, *s; + POLYLINE_ORDER polyline; + + s = &_s; + s->p = s->data = polyline_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x73; + + memset(&polyline, 0, sizeof(POLYLINE_ORDER)); + + update_read_polyline_order(s, orderInfo, &polyline); + + CU_ASSERT(polyline.xStart == 504); + CU_ASSERT(polyline.yStart == 696); + CU_ASSERT(polyline.bRop2 == 0); + CU_ASSERT(polyline.penColor == 0x0000C000); + CU_ASSERT(polyline.numPoints == 32); + CU_ASSERT(polyline.cbData == 108); + + CU_ASSERT(polyline.points[0].x == -130); + CU_ASSERT(polyline.points[1].x == -191); + CU_ASSERT(polyline.points[2].x == -220); + CU_ASSERT(polyline.points[3].x == -213); + CU_ASSERT(polyline.points[4].x == -171); + CU_ASSERT(polyline.points[5].x == -100); + CU_ASSERT(polyline.points[6].x == -13); + CU_ASSERT(polyline.points[7].x == 77); + CU_ASSERT(polyline.points[8].x == 153); + CU_ASSERT(polyline.points[9].x == 205); + CU_ASSERT(polyline.points[10].x == 222); + CU_ASSERT(polyline.points[11].x == 202); + CU_ASSERT(polyline.points[12].x == 150); + CU_ASSERT(polyline.points[13].x == 72); + CU_ASSERT(polyline.points[14].x == -17); + CU_ASSERT(polyline.points[15].x == -105); + CU_ASSERT(polyline.points[16].x == -174); + CU_ASSERT(polyline.points[17].x == -213); + CU_ASSERT(polyline.points[18].x == -220); + CU_ASSERT(polyline.points[19].x == -188); + CU_ASSERT(polyline.points[20].x == -127); + CU_ASSERT(polyline.points[21].x == -42); + CU_ASSERT(polyline.points[22].x == 47); + CU_ASSERT(polyline.points[23].x == 130); + CU_ASSERT(polyline.points[24].x == 191); + CU_ASSERT(polyline.points[25].x == 221); + CU_ASSERT(polyline.points[26].x == 212); + CU_ASSERT(polyline.points[27].x == 171); + CU_ASSERT(polyline.points[28].x == 100); + CU_ASSERT(polyline.points[29].x == 13); + CU_ASSERT(polyline.points[30].x == -77); + CU_ASSERT(polyline.points[31].x == -153); + CU_ASSERT(polyline.points[32].x == 0); + + CU_ASSERT(stream_get_length(s) == (sizeof(polyline_order) - 1)); +} + +uint8 glyph_index_order_1[] = + "\x6a\x02\x27\x38\x00\x39\x07\x3a\x06\x3b\x07\x3c\x06\x3d\x06\x18" + "\x04\x1f\x06\x17\x02\x14\x04\x1b\x06\x19\x06\x45\x05\x18\x06\x1f" + "\x06\x1f\x02\x14\x02\x46\x06\xff\x15\x24"; + +uint8 glyph_index_order_2[] = + "\x00\xff\xff\xff\x0c\x02\x6e\x01\x4d\x02\x7b\x01\x09\x02\x6e\x01" + "\xf6\x02\x7b\x01\x0c\x02\x79\x01\x03\xfe\x04\x00"; + +void test_read_glyph_index_order(void) +{ + STREAM _s, *s; + GLYPH_INDEX_ORDER glyph_index; + + s = &_s; + s->p = s->data = glyph_index_order_1; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x200100; + orderInfo->deltaCoordinates = true; + + memset(&glyph_index, 0, sizeof(GLYPH_INDEX_ORDER)); + + update_read_glyph_index_order(s, orderInfo, &glyph_index); + + CU_ASSERT(glyph_index.bkRight == 618); + + CU_ASSERT(stream_get_length(s) == (sizeof(glyph_index_order_1) - 1)); + + s->p = s->data = glyph_index_order_2; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x383FE8; + orderInfo->deltaCoordinates = true; + + memset(&glyph_index, 0, sizeof(GLYPH_INDEX_ORDER)); + + update_read_glyph_index_order(s, orderInfo, &glyph_index); + + CU_ASSERT(glyph_index.fOpRedundant == 0); + CU_ASSERT(glyph_index.foreColor == 0x00FFFFFF); + CU_ASSERT(glyph_index.bkLeft == 524); + CU_ASSERT(glyph_index.bkTop == 366); + CU_ASSERT(glyph_index.bkRight == 589); + CU_ASSERT(glyph_index.bkBottom == 379); + CU_ASSERT(glyph_index.opLeft == 521); + CU_ASSERT(glyph_index.opTop == 366); + CU_ASSERT(glyph_index.opRight == 758); + CU_ASSERT(glyph_index.opBottom == 379); + CU_ASSERT(glyph_index.x == 524); + CU_ASSERT(glyph_index.y == 377); + + CU_ASSERT(stream_get_length(s) == (sizeof(glyph_index_order_2) - 1)); +} + +uint8 fast_index_order[] = + "\x07\x00\x03\xff\xff\x00\x74\x3b\x00\x0e\x00\x71\x00\x42\x00\x7e" + "\x00\x00\x80\x7c\x00\x15\x00\x00\x01\x06\x02\x04\x03\x08\x05\x09" + "\x06\x06\x06\x06\x07\x06\x08\x02\xff\x00\x12"; + +void test_read_fast_index_order(void) +{ + STREAM _s, *s; + FAST_INDEX_ORDER fast_index; + + s = &_s; + s->p = s->data = fast_index_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x70FF; + + memset(&fast_index, 0, sizeof(FAST_INDEX_ORDER)); + update_read_fast_index_order(s, orderInfo, &fast_index); + + CU_ASSERT(fast_index.cacheId == 7); + CU_ASSERT(fast_index.flAccel == 3); + CU_ASSERT(fast_index.ulCharInc == 0); + CU_ASSERT(fast_index.backColor == 0x0000FFFF); + CU_ASSERT(fast_index.foreColor == 0x00003B74); + CU_ASSERT(fast_index.bkLeft == 14); + CU_ASSERT(fast_index.bkTop == 113); + CU_ASSERT(fast_index.bkRight == 66); + CU_ASSERT(fast_index.bkBottom == 126); + CU_ASSERT(fast_index.opLeft == 0); + CU_ASSERT(fast_index.opTop == 0); + CU_ASSERT(fast_index.opRight == 0); + CU_ASSERT(fast_index.opBottom == 0); + CU_ASSERT(fast_index.x == -32768); + CU_ASSERT(fast_index.y == 124); + + CU_ASSERT(stream_get_length(s) == (sizeof(fast_index_order) - 1)); +} + +uint8 fast_glyph_order[] = + "\x06\x00\x03\xff\xff\x00\x8b\x00\xb1\x00\x93\x00\xbe\x00\x0d\x00" + "\xfe\x7f\x00\x80\x00\x80\xbb\x00\x13\x00\x01\x4a\x06\x0a\x80\x80" + "\x80\xb8\xc4\x84\x84\x84\x84\x84\x00\x00\x68\x00"; + +void test_read_fast_glyph_order(void) +{ + STREAM _s, *s; + FAST_GLYPH_ORDER fast_glyph; + + s = &_s; + s->p = s->data = fast_glyph_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x7EFB; + + memset(&fast_glyph, 0, sizeof(FAST_GLYPH_ORDER)); + + update_read_fast_glyph_order(s, orderInfo, &fast_glyph); + + CU_ASSERT(fast_glyph.backColor == 0); + CU_ASSERT(fast_glyph.foreColor == 0x0000FFFF); + CU_ASSERT(fast_glyph.bkLeft == 139); + CU_ASSERT(fast_glyph.bkTop == 177); + CU_ASSERT(fast_glyph.bkRight == 147); + CU_ASSERT(fast_glyph.bkBottom == 190); + CU_ASSERT(fast_glyph.opLeft == 0); + CU_ASSERT(fast_glyph.opTop == 13); + CU_ASSERT(fast_glyph.opRight == 32766); + CU_ASSERT(fast_glyph.opBottom == -32768); + CU_ASSERT(fast_glyph.x == -32768); + CU_ASSERT(fast_glyph.y == 187); + + CU_ASSERT(stream_get_length(s) == (sizeof(fast_glyph_order) - 1)); +} + +uint8 polygon_cb_order[] = + "\xea\x00\x46\x01\x0d\x01\x08\x00\x00\x04\x03\x81\x08\x03\x05\x88" + "\x09\x26\x09\x77"; + +void test_read_polygon_cb_order(void) +{ + STREAM _s, *s; + POLYGON_CB_ORDER polygon_cb; + + s = &_s; + s->p = s->data = polygon_cb_order; + + memset(orderInfo, 0, sizeof(ORDER_INFO)); + orderInfo->fieldFlags = 0x1BEF; + + memset(&polygon_cb, 0, sizeof(POLYGON_CB_ORDER)); + + update_read_polygon_cb_order(s, orderInfo, &polygon_cb); + + CU_ASSERT(polygon_cb.xStart == 234); + CU_ASSERT(polygon_cb.yStart == 326); + CU_ASSERT(polygon_cb.bRop2 == 0x0D); + CU_ASSERT(polygon_cb.fillMode == 1); + CU_ASSERT(polygon_cb.backColor == 0); + CU_ASSERT(polygon_cb.foreColor == 0x00000008); + CU_ASSERT(polygon_cb.brush.x == 4); + CU_ASSERT(polygon_cb.brush.y == 3); + CU_ASSERT(polygon_cb.brush.style == 0x81); + CU_ASSERT(polygon_cb.nDeltaEntries == 3); + CU_ASSERT(polygon_cb.cbData == 5); + + CU_ASSERT(stream_get_length(s) == (sizeof(polygon_cb_order) - 1)); +} + +uint8 cache_bitmap_order[] = "\x00\x00\x10\x01\x08\x01\x00\x00\x00\x10"; + +void test_read_cache_bitmap_order(void) +{ + STREAM _s, *s; + uint16 extraFlags; + CACHE_BITMAP_ORDER cache_bitmap; + + s = &_s; + extraFlags = 0x0400; + s->p = s->data = cache_bitmap_order; + + memset(&cache_bitmap, 0, sizeof(CACHE_BITMAP_ORDER)); + + update_read_cache_bitmap_order(s, &cache_bitmap, true, extraFlags); + + CU_ASSERT(cache_bitmap.cacheId == 0); + CU_ASSERT(cache_bitmap.bitmapWidth == 16); + CU_ASSERT(cache_bitmap.bitmapHeight == 1); + CU_ASSERT(cache_bitmap.bitmapBpp == 8); + CU_ASSERT(cache_bitmap.bitmapLength == 1); + CU_ASSERT(cache_bitmap.cacheIndex == 0); + + CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_order) - 1)); +} + +uint8 cache_bitmap_v2_order[] = + "\x20\x40\xdc\xff\xff\x85\xff\xff\x99\xd6\x99\xd6\x99\xd6\x99\xd6" + "\x06\x8b\x99\xd6\x99\xd6\x99\xd6\x10\x84\x08\x42\x08\x42\x10\x84" + "\x99\xd6\x99\xd6\x99\xd6\x99\xd6\x06\x84\x99\xd6\x99\xd6\x99\xd6" + "\xff\xff\x16\x69\x99\xd6\x06\x69\x99\xd6\x04\xcc\x89\x52\x03\x6e" + "\xff\xff\x02\x6e\x08\x42\x01\x70\x08\x42\x71\xff\xff\xce\x18\xc6" + "\x01\x81\x08\x42\xce\x66\x29\x02\xcd\x89\x52\x03\x88\x10\x84\x99" + "\xd6\x99\xd6\x99\xd6\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x99\xd6" + "\x03\xf8\x01\x00\x00\x00\x00\xf0\x66\x99\xd6\x05\x6a\x99\xd6\x00" + "\xc4\xcc\x89\x52\x03\x6e\xff\xff\x02\x6e\x08\x42\x01\x70\x08\x42" + "\x71\xff\xff\xce\x18\xc6\x01\x81\x08\x42\xce\x66\x29\x02\xcd\x89" + "\x52\x03\x00\x04\xd6\x99\xd6\xc3\x80\x61\x00\xa5\x80\x40\xec\x52" + "\x00\x5a\x00\x2d\x00\x24\x00\x12\x00\x24\x00\x12\x00\x5a\x00\x2d" + "\x00\xa5\x80\x52\x00\xc3\x80\x61\x00\x00\x00\x00\x00\xcc\x89\x52" + "\x03\x6e\xff\xff\x02\xcb\x18\xc6\x84\x08\x42\x08\x42\x08\x42\xff" + "\xff"; + +void test_read_cache_bitmap_v2_order(void) +{ + STREAM _s, *s; + uint16 extraFlags; + CACHE_BITMAP_V2_ORDER cache_bitmap_v2; + + s = &_s; + extraFlags = 0x0CA1; + s->p = s->data = cache_bitmap_v2_order; + + memset(&cache_bitmap_v2, 0, sizeof(CACHE_BITMAP_V2_ORDER)); + + update_read_cache_bitmap_v2_order(s, &cache_bitmap_v2, true, extraFlags); + + CU_ASSERT(cache_bitmap_v2.cacheId == 1); + CU_ASSERT(cache_bitmap_v2.bitmapBpp == 16); + CU_ASSERT(cache_bitmap_v2.flags == 0x19); + CU_ASSERT(cache_bitmap_v2.bitmapWidth == 32); + CU_ASSERT(cache_bitmap_v2.bitmapHeight == 32); + CU_ASSERT(cache_bitmap_v2.bitmapLength == 220); + CU_ASSERT(cache_bitmap_v2.cacheIndex == 32767); + + CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v2_order) - 1)); +} + +uint8 cache_bitmap_v3_order[] = + "\xff\x7f\x35\x50\xec\xbc\x74\x52\x65\xb7\x20\x00\x00\x00\x05\x00" + "\x02\x00\x28\x00\x00\x00\x5b\x4f\x45\xff\x5b\x4f\x45\xff\x5b\x4f" + "\x45\xff\x5b\x4f\x45\xff\x5b\x4f\x45\xff\x5b\x50\x45\xff\x5b\x50" + "\x45\xff\x5b\x50\x45\xff\x5b\x50\x45\xff\x5b\x50\x45\xff"; + +void test_read_cache_bitmap_v3_order(void) +{ + STREAM _s, *s; + uint16 extraFlags; + CACHE_BITMAP_V3_ORDER cache_bitmap_v3; + + s = &_s; + extraFlags = 0x0C30; + s->p = s->data = cache_bitmap_v3_order; + + memset(&cache_bitmap_v3, 0, sizeof(CACHE_BITMAP_V3_ORDER)); + + update_read_cache_bitmap_v3_order(s, &cache_bitmap_v3, true, extraFlags); + + CU_ASSERT(cache_bitmap_v3.cacheIndex == 32767); + CU_ASSERT(cache_bitmap_v3.key1 == 0xBCEC5035); + CU_ASSERT(cache_bitmap_v3.key2 == 0xB7655274); + CU_ASSERT(cache_bitmap_v3.bpp == 32); + + CU_ASSERT(cache_bitmap_v3.bitmapData.bpp == 32); + CU_ASSERT(cache_bitmap_v3.bitmapData.codecID == 0); + CU_ASSERT(cache_bitmap_v3.bitmapData.width == 5); + CU_ASSERT(cache_bitmap_v3.bitmapData.height == 2); + CU_ASSERT(cache_bitmap_v3.bitmapData.length == 40); + + CU_ASSERT(stream_get_length(s) == (sizeof(cache_bitmap_v3_order) - 1)); +} + +uint8 cache_brush_order[] = "\x00\x01\x08\x08\x81\x08\xaa\x55\xaa\x55\xaa\x55\xaa\x55"; + +void test_read_cache_brush_order(void) +{ + STREAM _s, *s; + CACHE_BRUSH_ORDER cache_brush; + + s = &_s; + s->p = s->data = cache_brush_order; + + memset(&cache_brush, 0, sizeof(CACHE_BRUSH_ORDER)); + + update_read_cache_brush_order(s, &cache_brush, 0); + + CU_ASSERT(cache_brush.index == 0); + CU_ASSERT(cache_brush.bpp == 1); + CU_ASSERT(cache_brush.cx == 8); + CU_ASSERT(cache_brush.cy == 8); + CU_ASSERT(cache_brush.style == 0x81); + CU_ASSERT(cache_brush.length == 8); + + CU_ASSERT(stream_get_length(s) == (sizeof(cache_brush_order) - 1)); +} + +uint8 create_offscreen_bitmap_order[] = "\x00\x80\x60\x01\x10\x00\x01\x00\x02\x00"; + +void test_read_create_offscreen_bitmap_order(void) +{ + STREAM _s, *s; + OFFSCREEN_DELETE_LIST* deleteList; + CREATE_OFFSCREEN_BITMAP_ORDER create_offscreen_bitmap; + + s = &_s; + s->p = s->data = create_offscreen_bitmap_order; + + memset(&create_offscreen_bitmap, 0, sizeof(CREATE_OFFSCREEN_BITMAP_ORDER)); + + deleteList = &(create_offscreen_bitmap.deleteList); + deleteList->cIndices = 0; + deleteList->sIndices = 16; + deleteList->indices = malloc(sizeof(uint16) * deleteList->sIndices); + + update_read_create_offscreen_bitmap_order(s, &create_offscreen_bitmap); + + CU_ASSERT(create_offscreen_bitmap.id == 0); + CU_ASSERT(create_offscreen_bitmap.cx == 352); + CU_ASSERT(create_offscreen_bitmap.cy == 16); + CU_ASSERT(create_offscreen_bitmap.deleteList.cIndices == 1); + + CU_ASSERT(stream_get_length(s) == (sizeof(create_offscreen_bitmap_order) - 1)); +} + +uint8 switch_surface_order[] = "\xff\xff"; + +void test_read_switch_surface_order(void) +{ + STREAM _s, *s; + SWITCH_SURFACE_ORDER switch_surface; + + s = &_s; + s->p = s->data = switch_surface_order; + + memset(&switch_surface, 0, sizeof(SWITCH_SURFACE_ORDER)); + + update_read_switch_surface_order(s, &switch_surface); + + CU_ASSERT(switch_surface.bitmapId == 0xFFFF); + + CU_ASSERT(stream_get_length(s) == (sizeof(switch_surface_order) - 1)); +} + +int opaque_rect_count; +int polyline_count; +int patblt_count; + +uint8 orders_update_1[] = + "\x00\x00\x33\xd0\x07\x00\x80\xba\x0d\x0a\x7f\x1e\x2c\x4d\x00\x36" + "\x02\xd3\x00\x47\x00\x4d\x00\xf0\x01\x87\x00\xc2\xdc\xff\x05\x7f" + "\x0f\x67\x01\x90\x01\x8e\x01\xa5\x01\x67\x01\x90\x01\x28\x00\x16" + "\x00\xf0\xf0\xf0\x15\x0f\xf0\x2d\x01\x19\xfe\x2d\x01\xec\xfd\x0d" + "\x16\x77\xf0\xff\xff\x01\x01\xa8\x01\x90\x01\x0d\xf0\xf0\xf0\x04" + "\x05\x66\x6b\x14\x15\x6c\x1d\x0a\x0f\xd0\x16\x64\x01\x15\xff\x50" + "\x03\x15\x0f\xf0\x65\x01\x15\xfe\x65\x01\xb0\xfd\x1d\x16\x01\xf0" + "\xff\xff\x01\x01\x7a"; + +uint8 orders_update_2[] = + "\x00\x00\x45\x62\x03\x00\x93\x14\x55\x01\x50\xff\xff\xff\x55\x01" + "\x50\x01\x01\x01\x55\x01\x50\xff\xff\xff\x16\x00\x17\x00\xea\x03" + "\xea\x03\x02\x00\x85\x02\x16\x00\x02\x00\x00\x00\x03\x00\x14\xb2"; + +void test_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +{ + opaque_rect_count++; +} + +void test_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +{ + polyline_count++; +} + +void test_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + patblt_count++; +} + +void test_update_recv_orders(void) +{ + rdpRdp* rdp; + STREAM _s, *s; + rdpUpdate* update; + + s = &_s; + rdp = rdp_new(NULL); + update = update_new(rdp); + + update->context = malloc(sizeof(rdpContext)); + update->context->rdp = rdp; + + opaque_rect_count = 0; + polyline_count = 0; + patblt_count = 0; + + update->primary->OpaqueRect = test_opaque_rect; + update->primary->Polyline = test_polyline; + update->primary->PatBlt = test_patblt; + + s->p = s->data = orders_update_1; + s->size = sizeof(orders_update_1); + + update_recv(update, s); + + CU_ASSERT(opaque_rect_count == 5); + CU_ASSERT(polyline_count == 2); + + update->primary->order_info.orderType = ORDER_TYPE_PATBLT; + s->p = s->data = orders_update_2; + s->size = sizeof(orders_update_2); + + update_recv(update, s); + + CU_ASSERT(patblt_count == 3); + + free(update->context); +} + diff --git a/cunit/test_orders.h b/cunit/test_orders.h new file mode 100644 index 0000000..eb7fb29 --- /dev/null +++ b/cunit/test_orders.h @@ -0,0 +1,48 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Drawing Orders Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_orders_suite(void); +int clean_orders_suite(void); +int add_orders_suite(void); + +void test_read_dstblt_order(void); +void test_read_patblt_order(void); +void test_read_scrblt_order(void); +void test_read_opaque_rect_order(void); +void test_read_draw_nine_grid_order(void); +void test_read_multi_opaque_rect_order(void); +void test_read_line_to_order(void); +void test_read_polyline_order(void); +void test_read_glyph_index_order(void); +void test_read_fast_index_order(void); +void test_read_fast_glyph_order(void); +void test_read_polygon_cb_order(void); + +void test_read_cache_bitmap_order(void); +void test_read_cache_bitmap_v2_order(void); +void test_read_cache_bitmap_v3_order(void); +void test_read_cache_brush_order(void); + +void test_read_create_offscreen_bitmap_order(void); +void test_read_switch_surface_order(void); + +void test_update_recv_orders(void); + diff --git a/cunit/test_pcap.c b/cunit/test_pcap.c new file mode 100644 index 0000000..4255f04 --- /dev/null +++ b/cunit/test_pcap.c @@ -0,0 +1,99 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * pcap File Format Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "test_pcap.h" + +int init_pcap_suite(void) +{ + return 0; +} + +int clean_pcap_suite(void) +{ + return 0; +} + +int add_pcap_suite(void) +{ + add_test_suite(pcap); + + add_test_function(pcap); + + return 0; +} + +uint8 test_packet_1[16] = + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"; + +uint8 test_packet_2[32] = + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB" + "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"; + +uint8 test_packet_3[64] = + "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC" + "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC" + "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC" + "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"; + +typedef struct +{ + void* data; + uint32 length; +} test_packet; + +void test_pcap(void) +{ + rdpPcap* pcap; + pcap_record record; + test_packet packets[3]; + + packets[0].data = test_packet_1; + packets[0].length = sizeof(test_packet_1); + packets[1].data = test_packet_2; + packets[1].length = sizeof(test_packet_2); + packets[2].data = test_packet_3; + packets[2].length = sizeof(test_packet_3); + + pcap = pcap_open("/tmp/test.pcap", true); + pcap_add_record(pcap, test_packet_1, sizeof(test_packet_1)); + pcap_flush(pcap); + pcap_add_record(pcap, test_packet_2, sizeof(test_packet_2)); + pcap_flush(pcap); + pcap_add_record(pcap, test_packet_3, sizeof(test_packet_3)); + pcap_close(pcap); + + pcap = pcap_open("/tmp/test.pcap", false); + + int i = 0; + while (pcap_has_next_record(pcap)) + { + pcap_get_next_record(pcap, &record); + CU_ASSERT(record.length == packets[i].length) + i++; + } + + CU_ASSERT(i == 3); + + pcap_close(pcap); +} + diff --git a/cunit/test_pcap.h b/cunit/test_pcap.h new file mode 100644 index 0000000..f506edc --- /dev/null +++ b/cunit/test_pcap.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * pcap File Format Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_pcap_suite(void); +int clean_pcap_suite(void); +int add_pcap_suite(void); + +void test_pcap(void); diff --git a/cunit/test_per.c b/cunit/test_per.c new file mode 100644 index 0000000..45a5451 --- /dev/null +++ b/cunit/test_per.c @@ -0,0 +1,64 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Packed Encoding Rules (PER) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "test_per.h" +#include "libfreerdp-core/per.h" + +int init_per_suite(void) +{ + return 0; +} + +int clean_per_suite(void) +{ + return 0; +} + +int add_per_suite(void) +{ + add_test_suite(per); + + add_test_function(per_write_length); + add_test_function(per_write_object_identifier); + + return 0; +} + +uint8 per_length_expected[2] = "\x81\x2A"; + +void test_per_write_length(void) +{ + STREAM* s = stream_new(2); + per_write_length(s, 298); + ASSERT_STREAM(s, (uint8*) per_length_expected, sizeof(per_length_expected)); +} + +uint8 per_oid[6] = { 0, 0, 20, 124, 0, 1 }; +uint8 per_oid_expected[6] = "\x05\x00\x14\x7C\x00\x01"; + +void test_per_write_object_identifier(void) +{ + STREAM* s = stream_new(6); + per_write_object_identifier(s, per_oid); + ASSERT_STREAM(s, (uint8*) per_oid_expected, sizeof(per_oid_expected)); +} diff --git a/cunit/test_per.h b/cunit/test_per.h new file mode 100644 index 0000000..30f8d6f --- /dev/null +++ b/cunit/test_per.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Packed Encoding Rules (PER) Unit Tests + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_per_suite(void); +int clean_per_suite(void); +int add_per_suite(void); + +void test_per_write_length(void); +void test_per_write_object_identifier(void); diff --git a/cunit/test_rail.c b/cunit/test_rail.c new file mode 100644 index 0000000..b271706 --- /dev/null +++ b/cunit/test_rail.c @@ -0,0 +1,891 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + RAIL(TS RemoteApp) Virtual Channel Unit Tests + + Copyright 2011 Vic Lee + Copyright 2011 Roman Barabanov + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "test_rail.h" + +#define HCF_HIGHCONTRASTON 0x00000001 +#define HCF_AVAILABLE 0x00000002 +#define HCF_HOTKEYACTIVE 0x00000004 +#define HCF_CONFIRMHOTKEY 0x00000008 +#define HCF_HOTKEYSOUND 0x00000010 +#define HCF_INDICATOR 0x00000020 +#define HCF_HOTKEYAVAILABLE 0x00000040 + + +int init_rail_suite(void) +{ + freerdp_channels_global_init(); + return 0; +} + +int clean_rail_suite(void) +{ + freerdp_channels_global_uninit(); + return 0; +} + +int add_rail_suite(void) +{ + add_test_suite(rail); + + add_test_function(rail_plugin); + + return 0; +} + + +static uint8 client_handshake[] = +{ +0x05, 0x00, 0x08, 0x00, 0xb0, 0x1d, 0x00, 0x00 +}; + +static uint8 client_info_pdu[] = +{ +0x0b, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00 +}; + +// Flags: TS_RAIL_EXEC_FLAG_EXPAND_ARGUMENTS +// ExeOrFile : ||iexplore +// WorkingDir: f:\windows\system32 +// Arguments: www.bing.com + +static uint8 client_execute_pdu[] = +{ +0x01,0x00,0x5e,0x00,0x08,0x00,0x14,0x00,0x26,0x00,0x18,0x00,0x7c,0x00, +0x7c,0x00,0x69,0x00,0x65,0x00,0x78,0x00,0x70,0x00,0x6c,0x00,0x6f,0x00, +0x72,0x00,0x65,0x00,0x66,0x00,0x3a,0x00,0x5c,0x00,0x77,0x00,0x69,0x00, +0x6e,0x00,0x64,0x00,0x6f,0x00,0x77,0x00,0x73,0x00,0x5c,0x00,0x73,0x00, +0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x6d,0x00,0x33,0x00,0x32,0x00, +0x77,0x00,0x77,0x00,0x77,0x00,0x2e,0x00,0x62,0x00,0x69,0x00,0x6e,0x00, +0x67,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x00 +}; + +static uint8 client_activate_pdu[] = +{ +0x02,0x00, +0x09,0x00, +0x8e,0x00,0x07,0x00, +0x01 +}; + + + +static uint8 client_sysparam_highcontrast_pdu[] = +{ +0x03,0x00, +0x12,0x00, +0x43,0x00,0x00,0x00, // SPI_SETHIGHCONTRAST +0x7e,0x00,0x00,0x00, // HCF_AVAILABLE | HCF_HOTKEYACTIVE | HCF_CONFIRMHOTKEY + // HCF_HOTKEYSOUND | HCF_INDICATOR | HCF_HOTKEYAVAILABLE +0x02,0x00,0x00,0x00, // Minimum length 2 +0x00,0x00 // Unicode String +}; + + +static uint8 client_sysparam_taskbarpos_pdu[] = +{ +0x03,0x00, +0x10,0x00, +0x00,0xf0,0x00,0x00, // RAIL_SPI_TASKBARPOS +0x00,0x00, // 0 +0x9a,0x03, // 0x039a +0x90,0x06, // 0x0690 +0xc2,0x03 // 0x03c2 +}; + +static uint8 client_sysparam_mousebuttonswap_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x21,0x00,0x00,0x00, // SPI_SETMOUSEBUTTONSWAP +0x00 // false +}; + + +static uint8 client_sysparam_keyboardpref_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x45,0x00,0x00,0x00, // SPI_SETKEYBOARDPREF +0x00 // false +}; + + +static uint8 client_sysparam_dragfullwindow_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x25,0x00,0x00,0x00, // SPI_SETDRAGFULLWINDOWS +0x01 // true +}; + + +static uint8 client_sysparam_keyboardcues_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x0b,0x10,0x00,0x00, //SPI_SETKEYBOARDCUES +0x00 // false +}; + +static uint8 client_sysparam_setworkarea_pdu[] = +{ +0x03,0x00, +0x10,0x00, +0x2f,0x00,0x00,0x00, //SPI_SETWORKAREA +0x00,0x00, // 0 +0x00,0x00, // 0 +0x90,0x06, // 0x0690 +0x9a,0x03 // 0x039a +}; + +static uint8 client_syscommand_pdu[] = +{ +0x04,0x00, +0x0a,0x00, +0x52,0x00,0x02,0x00, +0x20,0xf0 +}; + +static uint8 client_notify_pdu[] = +{ +0x06,0x00, +0x10,0x00, +0xaa,0x01,0x02,0x00, +0x02,0x00,0x00,0x00, +0x04,0x02,0x00,0x00 +}; + +static uint8 client_windowmove_pdu[] = +{ +0x08,0x00, +0x10,0x00, +0x20,0x00,0x02,0x00, +0x09,0x03, +0x00,0x01, +0xdb,0x05, +0x88,0x01 +}; + +static uint8 client_system_menu_pdu[] = +{ +0x0c,0x00, +0x0c,0x00, +0x22,0x01,0x09,0x00, +0xa4,0xff, +0x4a,0x02 +}; + +static uint8 client_langbar_pdu[] = +{ +0x0D,0x00,0x08,0x00,0x01,0x00,0x00,0x00 +}; + +static uint8 client_get_app_id_req_pdu[] = +{ +0x0E,0x00,0x08,0x00,0x52,0x00,0x02,0x00 +}; + +static uint8 server_handshake[] = +{ + 0x05, 0x00, 0x08, 0x00, 0xb0, 0x1d, 0x00, 0x00 +}; + +static uint8 server_exec_result_pdu[] = +{ +0x80,0x00,0x24,0x00,0x08,0x00,0x03,0x00,0x15,0x00,0x00,0x00,0x00,0x00, +0x14,0x00,0x7c,0x00,0x7c,0x00,0x57,0x00,0x72,0x00,0x6f,0x00,0x6e,0x00, +0x67,0x00,0x41,0x00,0x70,0x00,0x70,0x00 +}; + +static uint8 server_exec_result_exe_or_file[] = +{ +0x7c,0x00,0x7c,0x00,0x57,0x00,0x72,0x00,0x6f,0x00,0x6e,0x00, +0x67,0x00,0x41,0x00,0x70,0x00,0x70,0x00 +}; + +static uint8 server_sysparam1_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x77,0x00,0x00,0x00, +0x00 +}; + +static uint8 server_sysparam2_pdu[] = +{ +0x03,0x00, +0x09,0x00, +0x11,0x00,0x00,0x00, +0x00 +}; + +static uint8 server_localmovesize_start_pdu[] = +{ +0x09,0x00,0x10,0x00,0x8e,0x00,0x07,0x00,0x01,0x00,0x09,0x00,0x7e,0x01, +0x0a,0x00 +}; + +static uint8 server_localmovesize_stop_pdu[] = +{ +0x09,0x00,0x10,0x00,0x8e,0x00,0x07,0x00,0x00,0x00,0x09,0x00,0xa6,0x00, +0x44,0x00 +}; + +static uint8 server_minmaxinfo_pdu[] = +{ +0x0a,0x00,0x18,0x00,0x8e,0x00,0x07,0x00,0x08,0x04,0xd6,0x02,0x00,0x00, +0x00,0x00,0x70,0x00,0x1b,0x00,0x0c,0x04,0x0c,0x03 +}; + +static uint8 server_langbar_pdu[] = +{ +0x0D,0x00,0x08,0x00,0x01,0x00,0x00,0x00 +}; + + +static uint8 server_app_get_resp_pdu[] = +{ +0x0F,0x00,0x08,0x02,0x52,0x00,0x02,0x00,0x6d,0x00,0x69,0x00,0x63,0x00, +0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,0x00, +0x77,0x00,0x69,0x00,0x6e,0x6f,0x00,0x77,0x00,0x73,0x00,0x2e,0x00,0x6e, +0x00,0x6f,0x00,0x74,0x00,0x65,0x00,0x70,0x00,0x61,0x00,0x64,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00 +}; + +static uint8 server_app_get_resp_app_id[] = +{ +0x6d,0x00,0x69,0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00, +0x66,0x00,0x74,0x00,0x2e,0x00,0x77,0x00,0x69,0x00,0x6e,0x6f,0x00,0x77, +0x00,0x73,0x00,0x2e,0x00,0x6e,0x00,0x6f,0x00,0x74,0x00,0x65,0x00,0x70, +0x00,0x61,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00, + +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00 +}; + + +#define EMULATE_SERVER_SEND_CHANNEL_DATA(inst, byte_array) \ + emulate_server_send_channel_data(inst, byte_array, RAIL_ARRAY_SIZE(byte_array)) + +#define STREAM_EQUAL_TO_DUMP(stream, dump) \ + (stream_equal_dump((stream)->data, (stream)->size, dump, RAIL_ARRAY_SIZE(dump))) + +#define UNICODE_STRING_EQUAL_TO_DUMP(ustring, dump) \ + (stream_equal_dump((ustring)->string, (ustring)->length, dump, RAIL_ARRAY_SIZE(dump))) + +typedef struct +{ + RAIL_HANDSHAKE_ORDER handshake; + RAIL_CLIENT_STATUS_ORDER client_status; + RAIL_EXEC_ORDER exec; + RAIL_EXEC_RESULT_ORDER exec_result; + RAIL_SYSPARAM_ORDER sysparam; + RAIL_ACTIVATE_ORDER activate; + RAIL_SYSMENU_ORDER sysmenu; + RAIL_SYSCOMMAND_ORDER syscommand; + RAIL_NOTIFY_EVENT_ORDER notify_event; + RAIL_MINMAXINFO_ORDER minmaxinfo; + RAIL_LOCALMOVESIZE_ORDER localmovesize; + RAIL_WINDOW_MOVE_ORDER window_move; + RAIL_LANGBAR_INFO_ORDER langbar_info; + RAIL_GET_APPID_REQ_ORDER get_appid_req; + RAIL_GET_APPID_RESP_ORDER get_appid_resp; + +} RAIL_ORDERS; + +typedef struct +{ + RAIL_ORDERS order_info; + uint32 event_type; +} +RAIL_EVENT; + +typedef struct +{ + rdpChannels* chan_man; + freerdp* instance; + int th_count; + int th_to_finish; + + RAIL_ORDERS out_rail_orders; + + RAIL_EVENT in_events[20]; + size_t in_events_number; + + STREAM in_streams[20]; + size_t in_streams_number; + + RDP_PLUGIN_DATA plugin_data; + + +} thread_param; + +static thread_param* global_thread_params = NULL; + +//----------------------------------------------------------------------------- +int stream_equal_dump(void * dataS, size_t sizeS, void * data, size_t size) +{ + size_t i; + if (sizeS != size) + { + printf("----------------- stream_equal_dump -----------------\n"); + printf("Stream and dump have different length (%d != %d)\n", + (int) sizeS, (int) size); + printf("Stream hexdump:\n"); + freerdp_hexdump(dataS, sizeS); + + printf("Dump hexdump:\n"); + freerdp_hexdump(data, size); + + printf("----------------- stream_equal_dump -----------------\n"); + return 0; + } + + + for (i=0; i < size; i++) + { + if (((uint8*)dataS)[i] != ((uint8*)data)[i]) + { + printf("----------------- stream_equal_dump -----------------\n"); + printf("Stream and dump have different content from %d offset.\n", (int) i); + printf("Stream hexdump:\n"); + freerdp_hexdump(dataS, sizeS); + + printf("Dump hexdump:\n"); + freerdp_hexdump(data, size); + printf("----------------- stream_equal_dump -----------------\n"); + return 0; + } + } + + return 1; +} +//----------------------------------------------------------------------------- +static void test_on_free_rail_client_event(RDP_EVENT* event) +{ + if (event->event_class == RDP_EVENT_CLASS_RAIL) + { + rail_free_cloned_order(event->event_type, event->user_data); + } +} +//----------------------------------------------------------------------------- +static void send_ui_event2plugin( + rdpChannels* chan_man, + uint16 event_type, + void * data + ) +{ + RDP_EVENT* out_event = NULL; + void * payload = NULL; + + payload = rail_clone_order(event_type, data); + if (payload != NULL) + { + out_event = freerdp_event_new(RDP_EVENT_CLASS_RAIL, event_type, + test_on_free_rail_client_event, payload); + freerdp_channels_send_event(chan_man, out_event); + } +} +//----------------------------------------------------------------------------- +static void emulate_server_send_channel_data( + freerdp* instance, + void* data, + size_t size + ) +{ + static int counter = 0; + counter++; + + printf("Emulate server packet (%d packet):\n", counter); + freerdp_hexdump(data, size); + + freerdp_channels_data(instance, 0, (char*)data, size, + CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST, size); + usleep(10*1000); +} +static void save_dump(void* data, size_t size) +{ + thread_param * p = global_thread_params; + if (p->in_streams_number < RAIL_ARRAY_SIZE(p->in_streams)) + { + STREAM* s = &p->in_streams[p->in_streams_number]; + s->data = malloc(size); + s->size = size; + + memcpy(s->data, data, size); + p->in_streams_number++; + } +} +//----------------------------------------------------------------------------- +static int emulate_client_send_channel_data( + freerdp* freerdp, int channelId, uint8* data, int size + ) +{ + static int counter = 0; + counter++; + + printf("Client send to server (%d packet):\n", counter); + freerdp_hexdump(data, size); + + // add to global dumps list + save_dump(data, size); + + return 0; +} +//----------------------------------------------------------------------------- +void save_event(RDP_EVENT* event, RAIL_EVENT* rail_event) +{ + rail_event->event_type = event->event_type; + + switch (event->event_type) + { + case RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS: + printf("UI receive Get Sysparams Event\n"); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS: + { + RAIL_EXEC_RESULT_ORDER* exec_result = (RAIL_EXEC_RESULT_ORDER*)event->user_data; + printf("UI receive Exec Results Event\n"); + memcpy(&rail_event->order_info.exec_result, event->user_data, + sizeof(RAIL_EXEC_RESULT_ORDER)); + + rail_unicode_string_alloc(&rail_event->order_info.exec_result.exeOrFile, + exec_result->exeOrFile.length); + + memcpy(rail_event->order_info.exec_result.exeOrFile.string, + exec_result->exeOrFile.string, + exec_result->exeOrFile.length); + } + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM: + printf("UI receive Server Sysparam Event\n"); + memcpy(&rail_event->order_info.sysparam, event->user_data, + sizeof(RAIL_SYSPARAM_ORDER)); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO: + printf("UI receive Server Minmax Info Event\n"); + memcpy(&rail_event->order_info.minmaxinfo, event->user_data, + sizeof(RAIL_MINMAXINFO_ORDER)); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE: + printf("UI receive Server Local Movesize Event\n"); + memcpy(&rail_event->order_info.localmovesize, event->user_data, + sizeof(RAIL_LOCALMOVESIZE_ORDER)); + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP: + printf("UI receive AppId Response Event\n"); + memcpy(&rail_event->order_info.get_appid_resp, event->user_data, + sizeof(RAIL_GET_APPID_RESP_ORDER)); + + rail_event->order_info.get_appid_resp.applicationId.string = + &rail_event->order_info.get_appid_resp.applicationIdBuffer[0]; + break; + + case RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO: + printf("UI receive Language Info Event\n"); + memcpy(&rail_event->order_info.langbar_info, event->user_data, + sizeof(RAIL_LANGBAR_INFO_ORDER)); + break; + } +} +//----------------------------------------------------------------------------- +static void process_events_and_channel_data_from_plugin(thread_param* param) +{ + RDP_EVENT* event; + + param->th_count++; + while (param->th_to_finish == 0) + { + freerdp_channels_check_fds(param->chan_man, param->instance); + + while (1) + { + event = freerdp_channels_pop_event(param->chan_man); + if (event == NULL) break; + + static int counter = 0; + counter++; + + printf("UI receive event. (type=%d counter=%d).\n", + event->event_type, + counter); + + // add to global event list + if (param->in_events_number < RAIL_ARRAY_SIZE(param->in_events)) + { + save_event(event, ¶m->in_events[param->in_events_number]); + param->in_events_number++; + } + freerdp_event_free(event); + } + + usleep(1000); + } + param->th_count--; +} +//----------------------------------------------------------------------------- +void* thread_func(void* param) +{ + thread_param* th_param = (thread_param*)param; + process_events_and_channel_data_from_plugin(th_param); + pthread_detach(pthread_self()); + + return NULL; +} +//----------------------------------------------------------------------------- +void test_rail_plugin(void) +{ + thread_param param; + pthread_t thread; + + rdpChannels* chan_man; + rdpSettings settings = { 0 }; + freerdp s_inst = { 0 }; + freerdp* inst = &s_inst; + size_t sn = 0; + size_t en = 0; + STREAM* ss = NULL; + RAIL_EVENT* ee = NULL; + + printf("\n"); + + settings.hostname = "testhost"; + inst->settings = &settings; + inst->SendChannelData = emulate_client_send_channel_data; + + chan_man = freerdp_channels_new(); + + freerdp_channels_load_plugin(chan_man, &settings, "../channels/rail/rail.so", NULL); + freerdp_channels_pre_connect(chan_man, inst); + freerdp_channels_post_connect(chan_man, inst); + + memset(¶m, 0, sizeof(param)); + + param.chan_man = chan_man; + param.instance = inst; + param.th_count = 0; + param.th_to_finish = 0; + + global_thread_params = ¶m; + + pthread_create(&thread, 0, thread_func, ¶m); + + // 1. Emulate server handshake binary + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_handshake); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_exec_result_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam1_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_sysparam2_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_start_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_localmovesize_stop_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_minmaxinfo_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_langbar_pdu); + EMULATE_SERVER_SEND_CHANNEL_DATA(inst, server_app_get_resp_pdu); + + // 2. Send UI events + + param.out_rail_orders.sysparam.params = 0; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST; + param.out_rail_orders.sysparam.highContrast.flags = 0x7e; + param.out_rail_orders.sysparam.highContrast.colorScheme.length = 0; + param.out_rail_orders.sysparam.highContrast.colorScheme.string = NULL; + + param.out_rail_orders.sysparam.params |= SPI_MASK_TASKBAR_POS; + param.out_rail_orders.sysparam.taskbarPos.left = 0; + param.out_rail_orders.sysparam.taskbarPos.top = 0x039a; + param.out_rail_orders.sysparam.taskbarPos.right = 0x0690; + param.out_rail_orders.sysparam.taskbarPos.bottom = 0x03c2; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP; + param.out_rail_orders.sysparam.mouseButtonSwap = false; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF; + param.out_rail_orders.sysparam.keyboardPref = false; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS; + param.out_rail_orders.sysparam.dragFullWindows = true; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES; + param.out_rail_orders.sysparam.keyboardCues = false; + + param.out_rail_orders.sysparam.params |= SPI_MASK_SET_WORK_AREA; + param.out_rail_orders.sysparam.workArea.left = 0; + param.out_rail_orders.sysparam.workArea.top = 0; + param.out_rail_orders.sysparam.workArea.right = 0x0690; + param.out_rail_orders.sysparam.workArea.bottom = 0x039a; + + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, + ¶m.out_rail_orders.sysparam); + + param.plugin_data.size = sizeof(RDP_PLUGIN_DATA); + param.plugin_data.data[0] = "||iexplore"; + param.plugin_data.data[1] = "f:\\windows\\system32"; + param.plugin_data.data[2] = "www.bing.com"; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP, + ¶m.plugin_data); + + param.out_rail_orders.activate.enabled = true; + param.out_rail_orders.activate.windowId = 0x0007008e; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, + ¶m.out_rail_orders.activate); + + param.out_rail_orders.syscommand.windowId = 0x00020052; + param.out_rail_orders.syscommand.command = 0xf020; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, + ¶m.out_rail_orders.syscommand); + + param.out_rail_orders.notify_event.windowId = 0x000201aa; + param.out_rail_orders.notify_event.notifyIconId = 0x02; + param.out_rail_orders.notify_event.message = 0x0204; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT, + ¶m.out_rail_orders.notify_event); + + + param.out_rail_orders.window_move.windowId = 0x00020020; + param.out_rail_orders.window_move.left = 0x0309; + param.out_rail_orders.window_move.top = 0x0100; + param.out_rail_orders.window_move.right = 0x05db; + param.out_rail_orders.window_move.bottom = 0x0188; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, + ¶m.out_rail_orders.window_move); + + param.out_rail_orders.sysmenu.windowId = 0x00090122; + param.out_rail_orders.sysmenu.left = 0xffa4; // TODO: possible negative values? + param.out_rail_orders.sysmenu.top = 0x024a; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU, + ¶m.out_rail_orders.sysmenu); + + param.out_rail_orders.langbar_info.languageBarStatus = 0x00000001; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO, + ¶m.out_rail_orders.langbar_info); + + param.out_rail_orders.get_appid_req.windowId = 0x00020052; + send_ui_event2plugin(chan_man, RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ, + ¶m.out_rail_orders.get_appid_req); + + // Waiting for possible events or data + sleep(1); + + // Finishing thread and wait for it + param.th_to_finish = 1; + while (param.th_count > 0) + { + usleep(1000); + } + + // We need to collected all events and data dumps and then to. + // create CU_ASSERT series here! + sn = param.in_streams_number; + en = param.in_events_number; + ss = ¶m.in_streams[0]; + ee = ¶m.in_events[0]; + + CU_ASSERT(sn > 0 && STREAM_EQUAL_TO_DUMP(&ss[ 0], client_handshake)); + CU_ASSERT(sn > 1 && STREAM_EQUAL_TO_DUMP(&ss[ 1], client_info_pdu)); + CU_ASSERT(sn > 2 && STREAM_EQUAL_TO_DUMP(&ss[ 2], client_sysparam_highcontrast_pdu)); + CU_ASSERT(sn > 3 && STREAM_EQUAL_TO_DUMP(&ss[ 3], client_sysparam_taskbarpos_pdu)); + CU_ASSERT(sn > 4 && STREAM_EQUAL_TO_DUMP(&ss[ 4], client_sysparam_mousebuttonswap_pdu)); + CU_ASSERT(sn > 5 && STREAM_EQUAL_TO_DUMP(&ss[ 5], client_sysparam_keyboardpref_pdu)); + CU_ASSERT(sn > 6 && STREAM_EQUAL_TO_DUMP(&ss[ 6], client_sysparam_dragfullwindow_pdu)); + CU_ASSERT(sn > 7 && STREAM_EQUAL_TO_DUMP(&ss[ 7], client_sysparam_keyboardcues_pdu)); + CU_ASSERT(sn > 8 && STREAM_EQUAL_TO_DUMP(&ss[ 8], client_sysparam_setworkarea_pdu)); + CU_ASSERT(sn > 9 && STREAM_EQUAL_TO_DUMP(&ss[ 9], client_execute_pdu)); + CU_ASSERT(sn >10 && STREAM_EQUAL_TO_DUMP(&ss[10], client_activate_pdu)); + CU_ASSERT(sn >11 && STREAM_EQUAL_TO_DUMP(&ss[11], client_syscommand_pdu)); + CU_ASSERT(sn >12 && STREAM_EQUAL_TO_DUMP(&ss[12], client_notify_pdu)); + CU_ASSERT(sn >13 && STREAM_EQUAL_TO_DUMP(&ss[13], client_windowmove_pdu)); + CU_ASSERT(sn >14 && STREAM_EQUAL_TO_DUMP(&ss[14], client_system_menu_pdu)); + CU_ASSERT(sn >15 && STREAM_EQUAL_TO_DUMP(&ss[15], client_langbar_pdu)); + CU_ASSERT(sn >16 && STREAM_EQUAL_TO_DUMP(&ss[16], client_get_app_id_req_pdu)); + + CU_ASSERT(en > 0 && ee[ 0].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS); + CU_ASSERT(en > 1 && + ee[ 1].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS && + ee[ 1].order_info.exec_result.flags == 0x08 && + ee[ 1].order_info.exec_result.execResult == 0x03 && + UNICODE_STRING_EQUAL_TO_DUMP( + &ee[ 1].order_info.exec_result.exeOrFile, + server_exec_result_exe_or_file) + ); + CU_ASSERT(en > 2 && + ee[ 2].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM && + ee[ 2].order_info.sysparam.setScreenSaveSecure == false + ); + + CU_ASSERT(en > 3 && + ee[ 3].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM && + ee[ 3].order_info.sysparam.setScreenSaveActive == false + ); + + CU_ASSERT(en > 4 && + ee[ 4].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE && + ee[ 4].order_info.localmovesize.windowId == 0x0007008e && + ee[ 4].order_info.localmovesize.isMoveSizeStart == true && + ee[ 4].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE && + ee[ 4].order_info.localmovesize.posX == 0x017e && + ee[ 4].order_info.localmovesize.posY == 0x000a + ); + + CU_ASSERT(en > 5 && + ee[ 5].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE && + ee[ 5].order_info.localmovesize.windowId == 0x0007008e && + ee[ 5].order_info.localmovesize.isMoveSizeStart == false && + ee[ 5].order_info.localmovesize.moveSizeType == RAIL_WMSZ_MOVE && + ee[ 5].order_info.localmovesize.posX == 0x00a6 && + ee[ 5].order_info.localmovesize.posY == 0x0044 + ); + + CU_ASSERT(en > 6 && + ee[ 6].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO && + ee[ 6].order_info.minmaxinfo.windowId == 0x0007008e && + ee[ 6].order_info.minmaxinfo.maxWidth == 0x0408 && + ee[ 6].order_info.minmaxinfo.maxHeight == 0x02d6 && + ee[ 6].order_info.minmaxinfo.maxPosX == 0x0000 && + ee[ 6].order_info.minmaxinfo.maxPosY == 0x0000 && + ee[ 6].order_info.minmaxinfo.minTrackWidth == 0x0070 && + ee[ 6].order_info.minmaxinfo.minTrackHeight == 0x001b && + ee[ 6].order_info.minmaxinfo.maxTrackWidth == 0x040c && + ee[ 6].order_info.minmaxinfo.maxTrackHeight == 0x030c + ); + + CU_ASSERT(en > 7 && + ee[ 7].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO && + ee[ 7].order_info.langbar_info.languageBarStatus == TF_SFT_SHOWNORMAL + ); + + CU_ASSERT(en > 8 && + ee[ 8].event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP && + ee[ 8].order_info.get_appid_resp.windowId == 0x00020052 && + UNICODE_STRING_EQUAL_TO_DUMP( + &ee[ 8].order_info.get_appid_resp.applicationId, + server_app_get_resp_app_id + ) + ); + + freerdp_channels_close(chan_man, inst); + freerdp_channels_free(chan_man); +} + + + + diff --git a/cunit/test_rail.h b/cunit/test_rail.h new file mode 100644 index 0000000..a39d18e --- /dev/null +++ b/cunit/test_rail.h @@ -0,0 +1,26 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + RAIL(TS RemoteApp) Virtual Channel Unit Tests + + Copyright 2011 Roman Barabanov + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "test_freerdp.h" + +int init_rail_suite(void); +int clean_rail_suite(void); +int add_rail_suite(void); + +void test_rail_plugin(void); diff --git a/cunit/test_stream.c b/cunit/test_stream.c new file mode 100644 index 0000000..ae1a9e2 --- /dev/null +++ b/cunit/test_stream.c @@ -0,0 +1,76 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stream Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "test_stream.h" + +int init_stream_suite(void) +{ + return 0; +} + +int clean_stream_suite(void) +{ + return 0; +} + +int add_stream_suite(void) +{ + add_test_suite(stream); + + add_test_function(stream); + + return 0; +} + +void test_stream(void) +{ + STREAM * stream; + int pos; + uint32 n; + uint64 n64; + + stream = stream_new(1); + pos = stream_get_pos(stream); + + stream_write_uint8(stream, 0xFE); + + stream_check_size(stream, 14); + stream_write_uint16(stream, 0x0102); + stream_write_uint32(stream, 0x03040506); + stream_write_uint64(stream, 0x0708091011121314LL); + + /* freerdp_hexdump(stream->buffer, 15); */ + + stream_set_pos(stream, pos); + stream_seek(stream, 3); + stream_read_uint32(stream, n); + stream_read_uint64(stream, n64); + + CU_ASSERT(n == 0x03040506); + CU_ASSERT(n64 == 0x0708091011121314LL); + + stream_free(stream); +} diff --git a/cunit/test_stream.h b/cunit/test_stream.h new file mode 100644 index 0000000..32080ed --- /dev/null +++ b/cunit/test_stream.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stream Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_stream_suite(void); +int clean_stream_suite(void); +int add_stream_suite(void); + +void test_stream(void); diff --git a/cunit/test_utils.c b/cunit/test_utils.c new file mode 100644 index 0000000..31fbdf2 --- /dev/null +++ b/cunit/test_utils.c @@ -0,0 +1,672 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Utils Unit Tests + * + * Copyright 2011 Vic Lee, 2011 Shea Levy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_utils.h" + +int init_utils_suite(void) +{ + return 0; +} + +int clean_utils_suite(void) +{ + return 0; +} + +int add_utils_suite(void) +{ + add_test_suite(utils); + + add_test_function(mutex); + add_test_function(semaphore); + add_test_function(load_plugin); + add_test_function(wait_obj); + add_test_function(args); + add_test_function(passphrase_read); + add_test_function(handle_signals); + + return 0; +} + +void test_mutex(void) +{ + freerdp_mutex mutex; + + mutex = freerdp_mutex_new(); + freerdp_mutex_lock(mutex); + freerdp_mutex_unlock(mutex); + freerdp_mutex_free(mutex); +} + +void test_semaphore(void) +{ + freerdp_sem sem; + + sem = freerdp_sem_new(1); + freerdp_sem_wait(sem); + freerdp_sem_signal(sem); + freerdp_sem_free(sem); +} + +void test_load_plugin(void) +{ + void* entry; + +#ifdef _WIN32 + /* untested */ + entry = freerdp_load_plugin("..\\channels\\cliprdr\\cliprdr", "VirtualChannelEntry"); +#else + entry = freerdp_load_plugin("../channels/cliprdr/cliprdr.so", "VirtualChannelEntry"); +#endif + CU_ASSERT(entry != NULL); +} + +void test_wait_obj(void) +{ + struct wait_obj* wo; + int set; + + wo = wait_obj_new(); + + set = wait_obj_is_set(wo); + CU_ASSERT(set == 0); + + wait_obj_set(wo); + set = wait_obj_is_set(wo); + CU_ASSERT(set == 1); + + wait_obj_clear(wo); + set = wait_obj_is_set(wo); + CU_ASSERT(set == 0); + + wait_obj_select(&wo, 1, 1000); + + wait_obj_free(wo); +} + +static int process_plugin_args(rdpSettings* settings, const char* name, + RDP_PLUGIN_DATA* plugin_data, void* user_data) +{ + /*printf("load plugin: %s\n", name);*/ + return 1; +} + +static int process_ui_args(rdpSettings* settings, const char* opt, + const char* val, void* user_data) +{ + /*printf("ui arg: %s %s\n", opt, val);*/ + return 1; +} + +void test_args(void) +{ + char* argv_c[] = + { + "freerdp", "-a", "8", "-u", "testuser", "-d", "testdomain", "-g", "640x480", "address1:3389", + "freerdp", "-a", "16", "-u", "testuser", "-d", "testdomain", "-g", "1280x960", "address2:3390" + }; + char** argv = argv_c; + int argc = sizeof(argv_c) / sizeof(char*); + int i; + int c; + rdpSettings* settings; + + i = 0; + while (argc > 0) + { + settings = settings_new(NULL); + + i++; + c = freerdp_parse_args(settings, argc, argv, process_plugin_args, NULL, process_ui_args, NULL); + CU_ASSERT(c > 0); + if (c == 0) + { + settings_free(settings); + break; + } + CU_ASSERT(settings->color_depth == i * 8); + CU_ASSERT(settings->width == i * 640); + CU_ASSERT(settings->height == i * 480); + CU_ASSERT(settings->port == i + 3388); + + settings_free(settings); + argc -= c; + argv += c; + } + CU_ASSERT(i == 2); +} + +void passphrase_read_prompts_to_tty() +{ + static const int read_nbyte = 11; + int masterfd; + char* slavedevice; + char read_buf[read_nbyte]; + fd_set fd_set_write; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + char buffer[password_size]; + int slavefd; + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + if ((slavefd = open(slavedevice, O_RDWR)) == 0) + CU_FAIL_FATAL("Could not open slave end of pty"); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + close(masterfd); + freerdp_passphrase_read("Password: ", buffer, password_size); + close(slavefd); + exit(EXIT_SUCCESS); + } + } + + read_buf[read_nbyte - 1] = '\0'; + + FD_ZERO(&fd_set_write); + FD_SET(masterfd, &fd_set_write); + if (select(masterfd + 1, NULL, &fd_set_write, NULL, NULL) == -1) + CU_FAIL_FATAL("Master end of pty not writeable"); + if (read(masterfd, read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to slave end of pty"); + CU_ASSERT_STRING_EQUAL(read_buf, "Password: "); + + write(masterfd, "\n", (size_t) 2); + close(masterfd); + return; +} + +void passphrase_read_reads_from_tty() +{ + static const int read_nbyte = 11; + int masterfd; + int pipe_ends[2]; + char* slavedevice; + char read_buf[read_nbyte]; + fd_set fd_set_write; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + if (pipe(pipe_ends) != 0) + CU_FAIL_FATAL("Could not create pipe"); + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + char buffer[password_size]; + int slavefd; + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + if ((slavefd = open(slavedevice, O_RDWR)) == 0) + CU_FAIL_FATAL("Could not open slave end of pty"); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + close(masterfd); + close(pipe_ends[0]); + freerdp_passphrase_read("Password: ", buffer, password_size); + write(pipe_ends[1], buffer, password_size); + close(slavefd); + close(pipe_ends[1]); + exit(EXIT_SUCCESS); + } + } + + close(pipe_ends[1]); + read_buf[read_nbyte - 1] = '\0'; + + FD_ZERO(&fd_set_write); + FD_SET(masterfd, &fd_set_write); + if (select(masterfd + 1, NULL, &fd_set_write, NULL, NULL) == -1) + CU_FAIL_FATAL("Master end of pty not writeable"); + if (read(masterfd, read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to slave end of pty"); + + write(masterfd, "passw0rd\n", sizeof "passw0rd\n"); + if (read(pipe_ends[0], read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to pipe"); + CU_ASSERT_STRING_EQUAL(read_buf, "passw0rd"); + close(masterfd); + close(pipe_ends[0]); + return; +} + +void passphrase_read_turns_off_echo_during_read() +{ + static const int read_nbyte = 11; + int masterfd, slavefd; + char* slavedevice; + char read_buf[read_nbyte]; + fd_set fd_set_write; + struct termios term_flags; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + slavefd = open(slavedevice, O_RDWR|O_NOCTTY); + if (slavefd == -1) + CU_FAIL_FATAL("Could not open slave end of pty"); + + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + if (!(term_flags.c_lflag & ECHO)) + { + term_flags.c_lflag |= ECHO; + if (tcsetattr(slavefd, TCSANOW, &term_flags) != 0) + CU_FAIL_FATAL("Could not turn ECHO on on slave pty"); + } + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + int child_slavefd; + char buffer[password_size]; + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + if ((child_slavefd = open(slavedevice, O_RDWR)) == 0) + CU_FAIL_FATAL("Could not open slave end of pty"); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + close(masterfd); + close(slavefd); + freerdp_passphrase_read("Password: ", buffer, password_size); + close(child_slavefd); + exit(EXIT_SUCCESS); + } + } + + read_buf[read_nbyte - 1] = '\0'; + + FD_ZERO(&fd_set_write); + FD_SET(masterfd, &fd_set_write); + if (select(masterfd + 1, NULL, &fd_set_write, NULL, NULL) == -1) + CU_FAIL_FATAL("Master end of pty not writeable"); + if (read(masterfd, read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to slave end of pty"); + + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + CU_ASSERT(!(term_flags.c_lflag & ECHO)) + write(masterfd, "\n", (size_t) 2); + close(masterfd); + close(slavefd); + return; +} + +void passphrase_read_resets_terminal_after_read() +{ + static const int read_nbyte = 11; + int masterfd, slavefd, status; + char* slavedevice; + char read_buf[read_nbyte]; + fd_set fd_set_write; + struct termios term_flags; + pid_t child; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + slavefd = open(slavedevice, O_RDWR|O_NOCTTY); + if (slavefd == -1) + CU_FAIL_FATAL("Could not open slave end of pty"); + + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + if (!(term_flags.c_lflag & ECHO)) + { + term_flags.c_lflag |= ECHO; + if (tcsetattr(slavefd, TCSANOW, &term_flags) != 0) + CU_FAIL_FATAL("Could not turn ECHO on on slave pty"); + } + + switch (child = fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + int child_slavefd; + char buffer[password_size]; + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + if ((child_slavefd = open(slavedevice, O_RDWR)) == 0) + CU_FAIL_FATAL("Could not open slave end of pty"); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + close(masterfd); + close(slavefd); + freerdp_passphrase_read("Password: ", buffer, password_size); + close(child_slavefd); + exit(EXIT_SUCCESS); + } + } + + read_buf[read_nbyte - 1] = '\0'; + + FD_ZERO(&fd_set_write); + FD_SET(masterfd, &fd_set_write); + if (select(masterfd + 1, NULL, &fd_set_write, NULL, NULL) == -1) + CU_FAIL_FATAL("Master end of pty not writeable"); + if (read(masterfd, read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to slave end of pty"); + + write(masterfd, "\n", (size_t) 2); + waitpid(child, &status, WUNTRACED); + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + CU_ASSERT(term_flags.c_lflag & ECHO) + close(masterfd); + close(slavefd); + return; +} + +void passphrase_read_turns_on_newline_echo_during_read() +{ + static const int read_nbyte = 11; + int masterfd, slavefd; + char* slavedevice; + char read_buf[read_nbyte]; + fd_set fd_set_write; + struct termios term_flags; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + slavefd = open(slavedevice, O_RDWR|O_NOCTTY); + if (slavefd == -1) + CU_FAIL_FATAL("Could not open slave end of pty"); + + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + if (term_flags.c_lflag & ECHONL) + { + term_flags.c_lflag &= ~ECHONL; + if (tcsetattr(slavefd, TCSANOW, &term_flags) != 0) + CU_FAIL_FATAL("Could not turn ECHO on on slave pty"); + } + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + int child_slavefd; + char buffer[password_size]; + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + if ((child_slavefd = open(slavedevice, O_RDWR)) == 0) + CU_FAIL_FATAL("Could not open slave end of pty"); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + close(masterfd); + close(slavefd); + freerdp_passphrase_read("Password: ", buffer, password_size); + close(child_slavefd); + exit(EXIT_SUCCESS); + } + } + + read_buf[read_nbyte - 1] = '\0'; + + FD_ZERO(&fd_set_write); + FD_SET(masterfd, &fd_set_write); + if (select(masterfd + 1, NULL, &fd_set_write, NULL, NULL) == -1) + CU_FAIL_FATAL("Master end of pty not writeable"); + if (read(masterfd, read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to slave end of pty"); + + if (tcgetattr(slavefd, &term_flags) != 0) + CU_FAIL_FATAL("Could not get slave pty attributes"); + CU_ASSERT(term_flags.c_lflag & ECHONL) + write(masterfd, "\n", (size_t) 2); + close(masterfd); + close(slavefd); + return; +} + +void passphrase_read_prompts_to_stderr_when_no_tty() +{ + static const int read_nbyte = 11; + int stdin_pipe[2], stderr_pipe[2]; + char read_buf[read_nbyte]; + struct sigaction ignore, orig; + + ignore.sa_handler = SIG_IGN; + sigemptyset(&ignore.sa_mask); + + if (pipe(stdin_pipe) != 0 || pipe(stderr_pipe) != 0) + CU_FAIL_FATAL("Could not create pipe"); + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + char buffer[password_size]; + close(stderr_pipe[0]); + close(stdin_pipe[1]); + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + dup2(stdin_pipe[0], STDIN_FILENO); + dup2(stderr_pipe[1], STDERR_FILENO); + freerdp_passphrase_read("Password: ", buffer, password_size); + exit(EXIT_SUCCESS); + } + } + close(stderr_pipe[1]); + close(stdin_pipe[0]); + + read_buf[read_nbyte - 1] = '\0'; + + if (read(stderr_pipe[0], read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to pipe"); + CU_ASSERT_STRING_EQUAL(read_buf, "Password: "); + + sigaction(SIGPIPE, &ignore, &orig); + write(stdin_pipe[1], "\n", (size_t) 2); + sigaction(SIGPIPE, &orig, NULL); + close(stderr_pipe[0]); + close(stdin_pipe[1]); + return; +} + +void passphrase_read_reads_from_stdin_when_no_tty() +{ + static const int read_nbyte = 11; + int stdin_pipe[2], stderr_pipe[2], result_pipe[2]; + char read_buf[read_nbyte]; + struct sigaction ignore, orig; + + ignore.sa_handler = SIG_IGN; + sigemptyset(&ignore.sa_mask); + + if (pipe(stdin_pipe) != 0 + || pipe(stderr_pipe) != 0 + || pipe(result_pipe) !=0) + CU_FAIL_FATAL("Could not create pipe"); + + switch (fork()) + { + case -1: + CU_FAIL_FATAL("Could not fork"); + case 0: + { + static const int password_size = 512; + char buffer[password_size]; + close(stderr_pipe[0]); + close(result_pipe[0]); + close(stdin_pipe[1]); + if (setsid() == (pid_t) -1) + CU_FAIL_FATAL("Could not create new session"); + + dup2(stdin_pipe[0], STDIN_FILENO); + dup2(stderr_pipe[1], STDERR_FILENO); + freerdp_passphrase_read("Password: ", buffer, password_size); + write(result_pipe[1], buffer, strlen(buffer) + (size_t) 1); + exit(EXIT_SUCCESS); + } + } + close(stderr_pipe[1]); + close(result_pipe[1]); + close(stdin_pipe[0]); + + read_buf[read_nbyte - 1] = '\0'; + + if (read(stderr_pipe[0], read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to pipe"); + + sigaction(SIGPIPE, &ignore, &orig); + write(stdin_pipe[1], "passw0rd\n", sizeof "passw0rd\n"); + sigaction(SIGPIPE, &orig, NULL); + + if (read(result_pipe[0], read_buf, read_nbyte) == (ssize_t) -1) + CU_FAIL_FATAL("Nothing written to pipe"); + CU_ASSERT_STRING_EQUAL(read_buf, "passw0rd"); + + close(stderr_pipe[0]); + close(stdin_pipe[1]); + return; +} + +void test_passphrase_read(void) +{ + passphrase_read_prompts_to_tty(); + passphrase_read_reads_from_tty(); + passphrase_read_turns_off_echo_during_read(); + passphrase_read_resets_terminal_after_read(); + passphrase_read_turns_on_newline_echo_during_read(); + passphrase_read_prompts_to_stderr_when_no_tty(); + passphrase_read_reads_from_stdin_when_no_tty(); +} + +void handle_signals_resets_terminal(void) +{ + int status, masterfd; + char* slavedevice; + struct termios test_flags; + pid_t child_pid; + + masterfd = posix_openpt(O_RDWR|O_NOCTTY); + + if (masterfd == -1 + || grantpt (masterfd) == -1 + || unlockpt (masterfd) == -1 + || (slavedevice = ptsname (masterfd)) == NULL) + CU_FAIL_FATAL("Could not create pty"); + + terminal_fildes = open(slavedevice, O_RDWR|O_NOCTTY); + tcgetattr(terminal_fildes, &orig_flags); + new_flags = orig_flags; + new_flags.c_lflag &= ~ECHO; + tcsetattr(terminal_fildes, TCSANOW, &new_flags); + terminal_needs_reset = 1; + + if((child_pid = fork()) == 0) + { + freerdp_handle_signals(); + raise(SIGINT); + } + while(wait(&status) != -1); + tcgetattr(terminal_fildes, &test_flags); + CU_ASSERT_EQUAL(orig_flags.c_lflag, test_flags.c_lflag); + close(masterfd); + close(terminal_fildes); +} + +void test_handle_signals(void) +{ + handle_signals_resets_terminal(); +} diff --git a/cunit/test_utils.h b/cunit/test_utils.h new file mode 100644 index 0000000..1bc37d9 --- /dev/null +++ b/cunit/test_utils.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Utils Unit Tests + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test_freerdp.h" + +int init_utils_suite(void); +int clean_utils_suite(void); +int add_utils_suite(void); + +void test_mutex(void); +void test_semaphore(void); +void test_load_plugin(void); +void test_wait_obj(void); +void test_args(void); +void test_passphrase_read(void); +void test_handle_signals(void); diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..5074670 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,114 @@ +freerdp (1.0.1-1ubuntu2) precise; urgency=low + + * debian/rules: Drop -Skde, autodetection will work fine. + + -- Martin Pitt Tue, 14 Feb 2012 14:34:18 +0100 + +freerdp (1.0.1-1ubuntu1) precise; urgency=low + + * debian/control, debian/rules: Drop libavcodec-dev build dependency and + disable ffmpeg support, to avoid the banned libavcodec53 on the + installation images. Support for MMR will come back later in the planned + gstreamer rewrite. (LP: #931931) + + -- Martin Pitt Tue, 14 Feb 2012 13:26:44 +0100 + +freerdp (1.0.1-1) unstable; urgency=low + + [ Jeremy Bicha ] + * New upstream release. Closes: #659332. + * Updated symbols + + -- Otavio Salvador Sat, 11 Feb 2012 10:34:05 -0200 + +freerdp (1.0.0-2) unstable; urgency=low + + [ Jeremy Bicha ] + * Don't install the freerdp keymaps; they're provided by xkb + + -- Otavio Salvador Tue, 31 Jan 2012 23:50:40 -0200 + +freerdp (1.0.0-1) unstable; urgency=low + + [ Jeremy Bicha ] + * New upstream release. Closes: #647498. + * Updated symbols and bumped soname + * debian/control: + - Added new build dependencies + - Bump Standards-Version to 3.9.2 + * debian/source/format: Set to 3.0 (quilt) + * debian/rules: Turn on strict symbols checking + * debian/watch: Watch github + + [ Jean-Louis Dupond ] + * debian/control: Updated homepage + * debian/copyright: Reflect upstream switch to the Apache license + + [ Martin Pitt ] + * debian/libfreerdp0.symbols: Fix version number, should + be 1.0~beta5, not 1.0-beta5. + * debian/control: Add libavcodec-dev build dependency, upstream build system + checks for that. Thanks Jean-Louis Dupond! + + -- Otavio Salvador Tue, 31 Jan 2012 11:46:23 -0200 + +freerdp (0.8.2-2) unstable; urgency=low + + * freerdp-x11: recommends libfreerdp-plugins-standard. Closes: + #603462. + + -- Otavio Salvador Fri, 19 Nov 2010 19:27:45 -0200 + +freerdp (0.8.2-1) unstable; urgency=low + + * New upstream version. + + -- Otavio Salvador Sat, 13 Nov 2010 10:58:11 -0200 + +freerdp (0.8.1-2) unstable; urgency=low + + * Add symbols file to allow for correct depends. Closes: #602218. + + -- Otavio Salvador Wed, 03 Nov 2010 09:46:00 -0200 + +freerdp (0.8.1-1) unstable; urgency=low + + * New upstream release. + + -- Otavio Salvador Mon, 25 Oct 2010 14:29:02 -0200 + +freerdp (0.7.4-1) unstable; urgency=low + + * New upstream release. + - Fixes connection with VirtualBox RDP server. Closes: #592454. + * Bump standards-version; no changes needed. + + -- Otavio Salvador Thu, 26 Aug 2010 11:07:49 -0300 + +freerdp (0.7.3-1) unstable; urgency=low + + * New upstream release. + * Fix section of libfreerdp0 to follow overrides. + * Add a watch file so it is easier to track new releases. + + -- Otavio Salvador Tue, 27 Jul 2010 01:13:00 -0300 + +freerdp (0.7.2-1) unstable; urgency=low + + * New upstream release. + + -- Otavio Salvador Mon, 05 Jul 2010 14:05:26 -0300 + +freerdp (0.7.1-1) unstable; urgency=low + + * New upstream release. + * debian/copyright: add missing entries. + + -- Otavio Salvador Wed, 23 Jun 2010 21:39:09 -0300 + +freerdp (0.7.0+debian-1) unstable; urgency=low + + * Initial release. + * Rebuild upstream tarball without debian directory. + + -- Otavio Salvador Fri, 18 Jun 2010 15:09:19 -0300 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +7 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..d461a85 --- /dev/null +++ b/debian/control @@ -0,0 +1,85 @@ +Source: freerdp +Section: x11 +Priority: optional +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Otavio Salvador +Build-Depends: + debhelper (>= 7.0.50~), autotools-dev, cmake, libasound2-dev, libcups2-dev, + libpcsclite-dev, libpulse-dev, libssl-dev, libx11-dev, libxcursor-dev, + libxdamage-dev, libxext-dev, libxkbfile-dev, libxinerama-dev, libxv-dev, + pkg-config, xmlto +Standards-Version: 3.9.2 +Homepage: http://www.freerdp.com/ +Vcs-Browser: http://git.debian.org/?p=collab-maint/freerdp.git +Vcs-Git: git://git.debian.org/git/collab-maint/freerdp.git + +Package: freerdp-dbg +Section: debug +Priority: extra +Architecture: any +Depends: + ${misc:Depends}, freerdp-x11 (= ${binary:Version}), + libfreerdp1 (= ${binary:Version}), + libfreerdp-plugins-standard (= ${binary:Version}), +Description: RDP client for Windows Terminal Services (debug) + FreeRDP is a client for Windows Terminal Services implementing the Remote + Desktop Protocol (RDP). + . + This package contains the debug symbols. + +Package: freerdp-x11 +Section: x11 +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends} +Recommends: libfreerdp-plugins-standard +Provides: freerdp +Description: RDP client for Windows Terminal Services + FreeRDP is a client for Windows Terminal Services implementing the Remote + Desktop Protocol (RDP). + . + Currently, the following Windows Versions are supported: + . + * Windows NT Server + * Windows 2000 Terminal Server + * Windows XP + * Windows 2003 Server + * Windows Vista + * Windows 2008 Server + * Windows 7 + . + This package contains the X11 based client. + +Package: libfreerdp1 +Architecture: any +Section: libs +Depends: ${misc:Depends}, ${shlibs:Depends} +Suggests: xfreerdp +Description: RDP client for Windows Terminal Services (library) + FreeRDP is a client for Windows Terminal Services implementing the Remote + Desktop Protocol (RDP). + . + This package contains the shared library. + +Package: libfreerdp-plugins-standard +Architecture: any +Section: libs +Depends: ${misc:Depends}, ${shlibs:Depends} +Description: RDP client for Windows Terminal Services (plugins) + FreeRDP is a client for Windows Terminal Services implementing the Remote + Desktop Protocol (RDP). + . + This package contains the plugins available to the Channel Manager extending + the RDP core functionality, such as sounds, clipboard synchronisation, + disk/printer redirection, etc. + +Package: libfreerdp-dev +Section: libdevel +Architecture: any +Depends: + ${misc:Depends}, libfreerdp1 (= ${binary:Version}), + libfreerdp-plugins-standard (= ${binary:Version}) +Description: RDP client for Windows Terminal Services (development) + FreeRDP is a client for Windows Terminal Services implementing the Remote + Desktop Protocol (RDP). + . + This package contains the development files. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..87d01ef --- /dev/null +++ b/debian/copyright @@ -0,0 +1,40 @@ +Upstream-Contact: FreeRDP project +Upstream-Homepage: http://freerdp.sourceforge.net/ + +Files: * +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + http://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the complete text of the GNU General Public License + can be found in /usr/share/common-licenses/Apache-2.0 file. + +Files: debian/* +Copyright: (C) 2011 Rex Tsai +Copyright: (C) 2010 Otavio Salvador +License: GPL-2+ + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + . + On Debian systems, the complete text of the GNU General Public License + can be found in /usr/share/common-licenses/GPL-2 file. diff --git a/debian/freerdp-x11.install b/debian/freerdp-x11.install new file mode 100644 index 0000000..98d1583 --- /dev/null +++ b/debian/freerdp-x11.install @@ -0,0 +1,2 @@ +usr/bin +usr/share/man/man1 diff --git a/debian/libfreerdp-dev.install b/debian/libfreerdp-dev.install new file mode 100644 index 0000000..f72f502 --- /dev/null +++ b/debian/libfreerdp-dev.install @@ -0,0 +1,5 @@ +usr/include +usr/lib/*.so +#usr/lib/*.a +#usr/lib/freerdp/*.a +usr/lib/pkgconfig diff --git a/debian/libfreerdp-plugins-standard.install b/debian/libfreerdp-plugins-standard.install new file mode 100644 index 0000000..84afc47 --- /dev/null +++ b/debian/libfreerdp-plugins-standard.install @@ -0,0 +1 @@ +usr/lib/freerdp/*.so diff --git a/debian/libfreerdp1.install b/debian/libfreerdp1.install new file mode 100644 index 0000000..093956b --- /dev/null +++ b/debian/libfreerdp1.install @@ -0,0 +1 @@ +usr/lib/*.so.* diff --git a/debian/libfreerdp1.symbols b/debian/libfreerdp1.symbols new file mode 100644 index 0000000..fa869ed --- /dev/null +++ b/debian/libfreerdp1.symbols @@ -0,0 +1,1279 @@ +libfreerdp-cache.so.1.0 libfreerdp1 #MINVER# + bitmap_cache_free@Base 1.0~beta5 + bitmap_cache_get@Base 1.0~beta5 + bitmap_cache_new@Base 1.0~beta5 + bitmap_cache_put@Base 1.0~beta5 + bitmap_cache_register_callbacks@Base 1.0~beta5 + brush_cache_free@Base 1.0~beta5 + brush_cache_get@Base 1.0~beta5 + brush_cache_new@Base 1.0~beta5 + brush_cache_put@Base 1.0~beta5 + brush_cache_register_callbacks@Base 1.0~beta5 + cache_free@Base 1.0~beta5 + cache_new@Base 1.0~beta5 + glyph_cache_fragment_get@Base 1.0~beta5 + glyph_cache_fragment_put@Base 1.0~beta5 + glyph_cache_free@Base 1.0~beta5 + glyph_cache_get@Base 1.0~beta5 + glyph_cache_new@Base 1.0~beta5 + glyph_cache_put@Base 1.0~beta5 + glyph_cache_register_callbacks@Base 1.0~beta5 + offscreen_cache_delete@Base 1.0~beta5 + offscreen_cache_free@Base 1.0~beta5 + offscreen_cache_get@Base 1.0~beta5 + offscreen_cache_new@Base 1.0~beta5 + offscreen_cache_put@Base 1.0~beta5 + offscreen_cache_register_callbacks@Base 1.0~beta5 + palette_cache_free@Base 1.0~beta5 + palette_cache_get@Base 1.0~beta5 + palette_cache_new@Base 1.0~beta5 + palette_cache_put@Base 1.0~beta5 + palette_cache_register_callbacks@Base 1.0~beta5 + pointer_cache_free@Base 1.0~beta5 + pointer_cache_get@Base 1.0~beta5 + pointer_cache_new@Base 1.0~beta5 + pointer_cache_put@Base 1.0~beta5 + pointer_cache_register_callbacks@Base 1.0~beta5 + update_gdi_bitmap_update@Base 1.0~beta5 + update_gdi_cache_bitmap@Base 1.0~beta5 + update_gdi_cache_bitmap_v2@Base 1.0~beta5 + update_gdi_cache_brush@Base 1.0~beta5 + update_gdi_cache_color_table@Base 1.0~beta5 + update_gdi_cache_glyph@Base 1.0~beta5 + update_gdi_cache_glyph_v2@Base 1.0~beta5 + update_gdi_create_offscreen_bitmap@Base 1.0~beta5 + update_gdi_fast_glyph@Base 1.0~beta5 + update_gdi_fast_index@Base 1.0~beta5 + update_gdi_glyph_index@Base 1.0~beta5 + update_gdi_mem3blt@Base 1.0~beta5 + update_gdi_memblt@Base 1.0~beta5 + update_gdi_patblt@Base 1.0~beta5 + update_gdi_switch_surface@Base 1.0~beta5 + update_pointer_cached@Base 1.0~beta5 + update_pointer_color@Base 1.0~beta5 + update_pointer_new@Base 1.0~beta5 + update_pointer_position@Base 1.0~beta5 + update_pointer_system@Base 1.0~beta5 + update_process_glyph@Base 1.0~beta5 + update_process_glyph_fragments@Base 1.0~beta5 +libfreerdp-channels.so.1.0 libfreerdp1 #MINVER# + WTSCreateVirtualChannelManager@Base 1.0~beta5 + WTSDestroyVirtualChannelManager@Base 1.0~beta5 + WTSFreeMemory@Base 1.0~beta5 + WTSVirtualChannelClose@Base 1.0~beta5 + WTSVirtualChannelManagerCheckFileDescriptor@Base 1.0~beta5 + WTSVirtualChannelManagerGetFileDescriptor@Base 1.0~beta5 + WTSVirtualChannelOpenEx@Base 1.0~beta5 + WTSVirtualChannelQuery@Base 1.0~beta5 + WTSVirtualChannelRead@Base 1.0~beta5 + WTSVirtualChannelWrite@Base 1.0~beta5 + freerdp_channels_check_fds@Base 1.0~beta5 + freerdp_channels_close@Base 1.0~beta5 + freerdp_channels_data@Base 1.0~beta5 + freerdp_channels_free@Base 1.0~beta5 + freerdp_channels_get_fds@Base 1.0~beta5 + freerdp_channels_global_init@Base 1.0~beta5 + freerdp_channels_global_uninit@Base 1.0~beta5 + freerdp_channels_load_plugin@Base 1.0~beta5 + freerdp_channels_new@Base 1.0~beta5 + freerdp_channels_pop_event@Base 1.0~beta5 + freerdp_channels_post_connect@Base 1.0~beta5 + freerdp_channels_pre_connect@Base 1.0~beta5 + freerdp_channels_send_event@Base 1.0~beta5 +libfreerdp-codec.so.1.0 libfreerdp1 #MINVER# + RleDecompress16to16@Base 1.0~beta5 + RleDecompress24to24@Base 1.0~beta5 + RleDecompress8to8@Base 1.0~beta5 + bitmap_decompress@Base 1.0~beta5 + freerdp_alpha_cursor_convert@Base 1.0~beta5 + freerdp_bitmap_flip@Base 1.0~beta5 + freerdp_clrconv_free@Base 1.0.1 + freerdp_clrconv_new@Base 1.0.1 + freerdp_color_convert_bgr@Base 1.0~beta5 + freerdp_color_convert_bgr_rgb@Base 1.0~beta5 + freerdp_color_convert_rgb@Base 1.0~beta5 + freerdp_color_convert_rgb_bgr@Base 1.0~beta5 + freerdp_color_convert_var_bgr@Base 1.0~beta5 + freerdp_color_convert_var_rgb@Base 1.0~beta5 + freerdp_color_convert_var@Base 1.0.0 + freerdp_color_make_bgr@Base 1.0~beta5 + freerdp_color_make_rgb@Base 1.0~beta5 + freerdp_color_split_bgr@Base 1.0~beta5 + freerdp_color_split_rgb@Base 1.0~beta5 + freerdp_get_pixel@Base 1.0~beta5 + freerdp_glyph_convert@Base 1.0~beta5 + freerdp_icon_convert@Base 1.0~beta5 + freerdp_image_convert@Base 1.0~beta5 + freerdp_image_convert_15bpp@Base 1.0~beta5 + freerdp_image_convert_16bpp@Base 1.0~beta5 + freerdp_image_convert_24bpp@Base 1.0~beta5 + freerdp_image_convert_32bpp@Base 1.0~beta5 + freerdp_image_convert_8bpp@Base 1.0~beta5 + freerdp_image_convert_@Base 1.0~beta5 + freerdp_image_flip@Base 1.0~beta5 + freerdp_image_swap_color_order@Base 1.0~beta5 + freerdp_mono_image_convert@Base 1.0~beta5 + freerdp_set_pixel@Base 1.0~beta5 + nsc_chroma_supersample@Base 1.0~beta5 + nsc_cl_expand@Base 1.0~beta5 + nsc_colorloss_recover@Base 1.0~beta5 + nsc_combine_argb@Base 1.0~beta5 + nsc_context_destroy@Base 1.0~beta5 + nsc_context_initialize@Base 1.0~beta5 + nsc_context_new@Base 1.0~beta5 + nsc_process_message@Base 1.0~beta5 + nsc_rle_decode@Base 1.0~beta5 + nsc_rle_decompress_data@Base 1.0~beta5 + nsc_stream_initialize@Base 1.0~beta5 + nsc_ycocg_rgb@Base 1.0~beta5 + rfx_compose_message@Base 1.0~beta5 + rfx_compose_message_header@Base 1.0~beta5 + rfx_context_free@Base 1.0~beta5 + rfx_context_new@Base 1.0~beta5 + rfx_context_reset@Base 1.0~beta5 + rfx_context_set_cpu_opt@Base 1.0~beta5 + rfx_context_set_pixel_format@Base 1.0~beta5 + rfx_decode_rgb@Base 1.0~beta5 + rfx_decode_ycbcr_to_rgb@Base 1.0~beta5 + rfx_differential_decode@Base 1.0~beta5 + rfx_differential_encode@Base 1.0~beta5 + rfx_dwt_2d_decode@Base 1.0~beta5 + rfx_dwt_2d_encode@Base 1.0~beta5 + rfx_encode_rgb@Base 1.0~beta5 + rfx_encode_rgb_to_ycbcr@Base 1.0~beta5 + rfx_message_free@Base 1.0~beta5 + rfx_message_get_rect@Base 1.0~beta5 + rfx_message_get_rect_count@Base 1.0~beta5 + rfx_message_get_tile@Base 1.0~beta5 + rfx_message_get_tile_count@Base 1.0~beta5 + rfx_pool_free@Base 1.0~beta5 + rfx_pool_get_tile@Base 1.0~beta5 + rfx_pool_get_tiles@Base 1.0~beta5 + rfx_pool_new@Base 1.0~beta5 + rfx_pool_put_tile@Base 1.0~beta5 + rfx_pool_put_tiles@Base 1.0~beta5 + rfx_process_message@Base 1.0~beta5 + rfx_quantization_decode@Base 1.0~beta5 + rfx_quantization_encode@Base 1.0~beta5 + rfx_rlgr_decode@Base 1.0~beta5 + rfx_rlgr_encode@Base 1.0~beta5 +libfreerdp-core.so.1.0 libfreerdp1 #MINVER# + Bitmap_Alloc@Base 1.0~beta5 + Bitmap_Free@Base 1.0~beta5 + Bitmap_New@Base 1.0~beta5 + Bitmap_SetDimensions@Base 1.0~beta5 + Bitmap_SetRectangle@Base 1.0~beta5 + Bitmap_SetSurface@Base 1.0~beta5 + Glyph_Alloc@Base 1.0~beta5 + Glyph_BeginDraw@Base 1.0~beta5 + Glyph_Draw@Base 1.0~beta5 + Glyph_EndDraw@Base 1.0~beta5 + Glyph_Free@Base 1.0~beta5 + Glyph_New@Base 1.0~beta5 + LEChash@Base 1.0.0 + LOMhash@Base 1.0.0 + Pointer_Alloc@Base 1.0~beta5 + Pointer_Free@Base 1.0~beta5 + Pointer_New@Base 1.0~beta5 + Pointer_Set@Base 1.0~beta5 + _ber_skip_length@Base 1.0~beta5 + ber_get_content_length@Base 1.0~beta5 + ber_read_application_tag@Base 1.0~beta5 + ber_read_bit_string@Base 1.0~beta5 + ber_read_boolean@Base 1.0~beta5 + ber_read_contextual_tag@Base 1.0~beta5 + ber_read_enumerated@Base 1.0~beta5 + ber_read_integer@Base 1.0~beta5 + ber_read_integer_length@Base 1.0~beta5 + ber_read_length@Base 1.0~beta5 + ber_read_octet_string@Base 1.0~beta5 + ber_read_sequence_tag@Base 1.0~beta5 + ber_read_universal_tag@Base 1.0~beta5 + ber_skip_contextual_tag@Base 1.0~beta5 + ber_skip_integer@Base 1.0~beta5 + ber_skip_octet_string@Base 1.0~beta5 + ber_skip_sequence@Base 1.0~beta5 + ber_skip_sequence_tag@Base 1.0~beta5 + ber_write_application_tag@Base 1.0~beta5 + ber_write_boolean@Base 1.0~beta5 + ber_write_contextual_tag@Base 1.0~beta5 + ber_write_enumerated@Base 1.0~beta5 + ber_write_integer@Base 1.0~beta5 + ber_write_length@Base 1.0~beta5 + ber_write_octet_string@Base 1.0~beta5 + ber_write_octet_string_tag@Base 1.0~beta5 + ber_write_sequence_tag@Base 1.0~beta5 + ber_write_universal_tag@Base 1.0~beta5 + certificate_data_free@Base 1.0.1 + certificate_data_match@Base 1.0.1 + certificate_data_new@Base 1.0.1 + certificate_data_print@Base 1.0.1 + certificate_free@Base 1.0~beta5 + certificate_free_x509_certificate_chain@Base 1.0~beta5 + certificate_new@Base 1.0~beta5 + certificate_new_x509_certificate_chain@Base 1.0~beta5 + certificate_read_server_certificate@Base 1.0~beta5 + certificate_read_server_proprietary_certificate@Base 1.0~beta5 + certificate_read_server_x509_certificate_chain@Base 1.0~beta5 + certificate_read_x509_certificate@Base 1.0~beta5 + certificate_store_free@Base 1.0.1 + certificate_store_init@Base 1.0.1 + certificate_store_new@Base 1.0.1 + credssp_authenticate@Base 1.0~beta5 + credssp_current_time@Base 1.0~beta5 + credssp_encode_ts_credentials@Base 1.0~beta5 + credssp_encrypt_public_key@Base 1.0~beta5 + credssp_encrypt_ts_credentials@Base 1.0~beta5 + credssp_free@Base 1.0~beta5 + credssp_get_public_key@Base 1.0~beta5 + credssp_new@Base 1.0~beta5 + credssp_ntlmssp_init@Base 1.0~beta5 + credssp_rc4k@Base 1.0~beta5 + credssp_recv@Base 1.0~beta5 + credssp_send@Base 1.0~beta5 + credssp_skip_auth_info@Base 1.0~beta5 + credssp_skip_nego_token@Base 1.0~beta5 + credssp_skip_nego_tokens@Base 1.0~beta5 + credssp_skip_pub_key_auth@Base 1.0~beta5 + credssp_skip_ts_credentials@Base 1.0~beta5 + credssp_skip_ts_password_creds@Base 1.0~beta5 + credssp_skip_ts_request@Base 1.0~beta5 + credssp_verify_public_key@Base 1.0~beta5 + credssp_write_ts_credentials@Base 1.0~beta5 + credssp_write_ts_password_creds@Base 1.0~beta5 + crypto_cert_fingerprint@Base 1.0~beta5 + crypto_cert_free@Base 1.0~beta5 + crypto_cert_get_public_key@Base 1.0~beta5 + crypto_cert_issuer@Base 1.0~beta5 + crypto_cert_print_info@Base 1.0~beta5 + crypto_cert_read@Base 1.0~beta5 + crypto_cert_subject@Base 1.0~beta5 + crypto_cert_subject_alt_name@Base 1.0.1 + crypto_cert_subject_common_name@Base 1.0.1 + crypto_des3_decrypt@Base 1.0~beta5 + crypto_des3_decrypt_init@Base 1.0~beta5 + crypto_des3_encrypt@Base 1.0~beta5 + crypto_des3_encrypt_init@Base 1.0~beta5 + crypto_des3_free@Base 1.0~beta5 + crypto_get_certificate_data@Base 1.0.1 + crypto_hmac_final@Base 1.0~beta5 + crypto_hmac_free@Base 1.0~beta5 + crypto_hmac_new@Base 1.0~beta5 + crypto_hmac_sha1_init@Base 1.0~beta5 + crypto_hmac_update@Base 1.0~beta5 + crypto_md5_final@Base 1.0~beta5 + crypto_md5_init@Base 1.0~beta5 + crypto_md5_update@Base 1.0~beta5 + crypto_nonce@Base 1.0~beta5 + crypto_print_name@Base 1.0~beta5 + crypto_rc4@Base 1.0~beta5 + crypto_rc4_free@Base 1.0~beta5 + crypto_rc4_init@Base 1.0~beta5 + crypto_reverse@Base 1.0~beta5 + crypto_rsa_decrypt@Base 1.0.1 + crypto_rsa_private_decrypt@Base 1.0.1 + crypto_rsa_private_encrypt@Base 1.0.1 + crypto_rsa_public_decrypt@Base 1.0.1 + crypto_rsa_public_encrypt@Base 1.0.1 + crypto_sha1_final@Base 1.0~beta5 + crypto_sha1_init@Base 1.0~beta5 + crypto_sha1_update@Base 1.0~beta5 + decompress_rdp@Base 1.0~beta5 + decompress_rdp_4@Base 1.0~beta5 + decompress_rdp_5@Base 1.0~beta5 + decompress_rdp_61@Base 1.0~beta5 + decompress_rdp_6@Base 1.0~beta5 + extension_free@Base 1.0~beta5 + extension_new@Base 1.0~beta5 + extension_post_connect@Base 1.0~beta5 + extension_pre_connect@Base 1.0~beta5 + fastpath_free@Base 1.0~beta5 + fastpath_header_length@Base 1.0.1 + fastpath_input_pdu_init@Base 1.0~beta5 + fastpath_new@Base 1.0~beta5 + fastpath_read_header@Base 1.0~beta5 + fastpath_read_header_rdp@Base 1.0~beta5 + fastpath_read_update_header@Base 1.0~beta5 + fastpath_recv_inputs@Base 1.0~beta5 + fastpath_recv_updates@Base 1.0~beta5 + fastpath_send_input_pdu@Base 1.0~beta5 + fastpath_send_update_pdu@Base 1.0~beta5 + fastpath_update_pdu_init@Base 1.0~beta5 + fastpath_write_update_header@Base 1.0~beta5 + freerdp_channel_peer_process@Base 1.0~beta5 + freerdp_channel_process@Base 1.0~beta5 + freerdp_channel_send@Base 1.0~beta5 + freerdp_check_fds@Base 1.0~beta5 + freerdp_connect@Base 1.0~beta5 + freerdp_context_free@Base 1.0~beta5 + freerdp_context_new@Base 1.0~beta5 + freerdp_disconnect@Base 1.0~beta5 + freerdp_error_info@Base 1.0~beta5 + freerdp_free@Base 1.0~beta5 + freerdp_get_fds@Base 1.0~beta5 + freerdp_get_version@Base 1.0.0 + freerdp_listener_free@Base 1.0~beta5 + freerdp_listener_new@Base 1.0~beta5 + freerdp_new@Base 1.0~beta5 + freerdp_peer_context_free@Base 1.0~beta5 + freerdp_peer_context_new@Base 1.0~beta5 + freerdp_peer_free@Base 1.0~beta5 + freerdp_peer_new@Base 1.0~beta5 + freerdp_send_keep_alive@Base 1.0~beta5 + freerdp_shall_disconnect@Base 1.0.1 + gcc_read_client_cluster_data@Base 1.0~beta5 + gcc_read_client_core_data@Base 1.0~beta5 + gcc_read_client_data_blocks@Base 1.0~beta5 + gcc_read_client_monitor_data@Base 1.0~beta5 + gcc_read_client_network_data@Base 1.0~beta5 + gcc_read_client_security_data@Base 1.0~beta5 + gcc_read_conference_create_request@Base 1.0~beta5 + gcc_read_conference_create_response@Base 1.0~beta5 + gcc_read_server_core_data@Base 1.0~beta5 + gcc_read_server_data_blocks@Base 1.0~beta5 + gcc_read_server_network_data@Base 1.0~beta5 + gcc_read_server_security_data@Base 1.0~beta5 + gcc_read_user_data_header@Base 1.0~beta5 + gcc_write_client_cluster_data@Base 1.0~beta5 + gcc_write_client_core_data@Base 1.0~beta5 + gcc_write_client_data_blocks@Base 1.0~beta5 + gcc_write_client_monitor_data@Base 1.0~beta5 + gcc_write_client_network_data@Base 1.0~beta5 + gcc_write_client_security_data@Base 1.0~beta5 + gcc_write_conference_create_request@Base 1.0~beta5 + gcc_write_conference_create_response@Base 1.0~beta5 + gcc_write_server_core_data@Base 1.0~beta5 + gcc_write_server_data_blocks@Base 1.0~beta5 + gcc_write_server_network_data@Base 1.0~beta5 + gcc_write_server_security_data@Base 1.0~beta5 + gcc_write_user_data_header@Base 1.0~beta5 + getLECindex@Base 1.0.0 + getLOMindex@Base 1.0.0 + graphics_free@Base 1.0~beta5 + graphics_new@Base 1.0~beta5 + graphics_register_bitmap@Base 1.0~beta5 + graphics_register_glyph@Base 1.0~beta5 + graphics_register_pointer@Base 1.0~beta5 + h221_cs_key@Base 1.0~beta5 + h221_sc_key@Base 1.0~beta5 + input_free@Base 1.0~beta5 + input_new@Base 1.0~beta5 + input_recv@Base 1.0.1 + input_register_client_callbacks@Base 1.0~beta5 + input_send_extended_mouse_event@Base 1.0~beta5 + input_send_fastpath_extended_mouse_event@Base 1.0~beta5 + input_send_fastpath_keyboard_event@Base 1.0~beta5 + input_send_fastpath_mouse_event@Base 1.0~beta5 + input_send_fastpath_synchronize_event@Base 1.0~beta5 + input_send_fastpath_unicode_keyboard_event@Base 1.0~beta5 + input_send_keyboard_event@Base 1.0~beta5 + input_send_mouse_event@Base 1.0~beta5 + input_send_synchronize_event@Base 1.0~beta5 + input_send_unicode_keyboard_event@Base 1.0~beta5 + input_write_extended_mouse_event@Base 1.0~beta5 + input_write_keyboard_event@Base 1.0~beta5 + input_write_mouse_event@Base 1.0~beta5 + input_write_synchronize_event@Base 1.0~beta5 + input_write_unicode_keyboard_event@Base 1.0~beta5 + key_free@Base 1.0.1 + key_new@Base 1.0.1 + license_decrypt_platform_challenge@Base 1.0~beta5 + license_encrypt_premaster_secret@Base 1.0~beta5 + license_free@Base 1.0~beta5 + license_free_binary_blob@Base 1.0~beta5 + license_free_product_info@Base 1.0~beta5 + license_free_scope_list@Base 1.0~beta5 + license_generate_hwid@Base 1.0~beta5 + license_generate_keys@Base 1.0~beta5 + license_generate_randoms@Base 1.0~beta5 + license_new@Base 1.0~beta5 + license_new_binary_blob@Base 1.0~beta5 + license_new_product_info@Base 1.0~beta5 + license_new_scope_list@Base 1.0~beta5 + license_read_binary_blob@Base 1.0~beta5 + license_read_error_alert_packet@Base 1.0~beta5 + license_read_license_request_packet@Base 1.0~beta5 + license_read_new_license_packet@Base 1.0~beta5 + license_read_platform_challenge_packet@Base 1.0~beta5 + license_read_preamble@Base 1.0~beta5 + license_read_product_info@Base 1.0~beta5 + license_read_scope_list@Base 1.0~beta5 + license_read_upgrade_license_packet@Base 1.0~beta5 + license_recv@Base 1.0~beta5 + license_send@Base 1.0~beta5 + license_send_new_license_request_packet@Base 1.0~beta5 + license_send_platform_challenge_response_packet@Base 1.0~beta5 + license_send_stream_init@Base 1.0~beta5 + license_send_valid_client_error_packet@Base 1.0~beta5 + license_write_binary_blob@Base 1.0~beta5 + license_write_new_license_request_packet@Base 1.0~beta5 + license_write_padded_binary_blob@Base 1.0~beta5 + license_write_platform_challenge_response_packet@Base 1.0~beta5 + license_write_platform_id@Base 1.0~beta5 + license_write_preamble@Base 1.0~beta5 + mcs_free@Base 1.0~beta5 + mcs_new@Base 1.0~beta5 + mcs_print_domain_parameters@Base 1.0~beta5 + mcs_read_domain_mcspdu_header@Base 1.0~beta5 + mcs_read_domain_parameters@Base 1.0~beta5 + mcs_recv_attach_user_confirm@Base 1.0~beta5 + mcs_recv_attach_user_request@Base 1.0~beta5 + mcs_recv_channel_join_confirm@Base 1.0~beta5 + mcs_recv_channel_join_request@Base 1.0~beta5 + mcs_recv_connect_initial@Base 1.0~beta5 + mcs_recv_connect_response@Base 1.0~beta5 + mcs_recv_erect_domain_request@Base 1.0~beta5 + mcs_send_attach_user_confirm@Base 1.0~beta5 + mcs_send_attach_user_request@Base 1.0~beta5 + mcs_send_channel_join_confirm@Base 1.0~beta5 + mcs_send_channel_join_request@Base 1.0~beta5 + mcs_send_connect_initial@Base 1.0~beta5 + mcs_send_connect_response@Base 1.0~beta5 + mcs_send_disconnect_provider_ultimatum@Base 1.0~beta5 + mcs_send_erect_domain_request@Base 1.0~beta5 + mcs_write_connect_initial@Base 1.0~beta5 + mcs_write_connect_response@Base 1.0~beta5 + mcs_write_domain_mcspdu_header@Base 1.0~beta5 + mcs_write_domain_parameters@Base 1.0~beta5 + miniLEChash@Base 1.0.0 + miniLOMhash@Base 1.0.0 + mppc_free@Base 1.0~beta5 + mppc_new@Base 1.0~beta5 + nego_attempt_nla@Base 1.0~beta5 + nego_attempt_rdp@Base 1.0~beta5 + nego_attempt_tls@Base 1.0~beta5 + nego_connect@Base 1.0~beta5 + nego_enable_nla@Base 1.0~beta5 + nego_enable_rdp@Base 1.0~beta5 + nego_enable_tls@Base 1.0~beta5 + nego_free@Base 1.0~beta5 + nego_init@Base 1.0~beta5 + nego_new@Base 1.0~beta5 + nego_process_negotiation_failure@Base 1.0~beta5 + nego_process_negotiation_request@Base 1.0~beta5 + nego_process_negotiation_response@Base 1.0~beta5 + nego_read_request@Base 1.0~beta5 + nego_recv@Base 1.0~beta5 + nego_recv_response@Base 1.0~beta5 + nego_send@Base 1.0~beta5 + nego_send_negotiation_request@Base 1.0~beta5 + nego_send_negotiation_response@Base 1.0~beta5 + nego_set_cookie@Base 1.0~beta5 + nego_set_routing_token@Base 1.0~beta5 + nego_set_target@Base 1.0~beta5 + nego_tcp_connect@Base 1.0~beta5 + nego_tcp_disconnect@Base 1.0~beta5 + ntlmssp_compute_lm_hash@Base 1.0~beta5 + ntlmssp_compute_lm_response@Base 1.0~beta5 + ntlmssp_compute_lm_v2_response@Base 1.0~beta5 + ntlmssp_compute_message_integrity_check@Base 1.0~beta5 + ntlmssp_compute_ntlm_hash@Base 1.0~beta5 + ntlmssp_compute_ntlm_v2_hash@Base 1.0~beta5 + ntlmssp_compute_ntlm_v2_response@Base 1.0~beta5 + ntlmssp_decrypt_message@Base 1.0~beta5 + ntlmssp_encrypt_message@Base 1.0~beta5 + ntlmssp_encrypt_random_session_key@Base 1.0~beta5 + ntlmssp_free@Base 1.0~beta5 + ntlmssp_free_av_pairs@Base 1.0~beta5 + ntlmssp_generate_client_challenge@Base 1.0~beta5 + ntlmssp_generate_client_sealing_key@Base 1.0~beta5 + ntlmssp_generate_client_signing_key@Base 1.0~beta5 + ntlmssp_generate_exported_session_key@Base 1.0~beta5 + ntlmssp_generate_key_exchange_key@Base 1.0~beta5 + ntlmssp_generate_random_session_key@Base 1.0~beta5 + ntlmssp_generate_sealing_key@Base 1.0~beta5 + ntlmssp_generate_server_sealing_key@Base 1.0~beta5 + ntlmssp_generate_server_signing_key@Base 1.0~beta5 + ntlmssp_generate_signing_key@Base 1.0~beta5 + ntlmssp_generate_timestamp@Base 1.0~beta5 + ntlmssp_init@Base 1.0~beta5 + ntlmssp_init_rc4_seal_states@Base 1.0~beta5 + ntlmssp_input_av_pairs@Base 1.0~beta5 + ntlmssp_input_negotiate_flags@Base 1.0~beta5 + ntlmssp_new@Base 1.0~beta5 + ntlmssp_output_av_pairs@Base 1.0~beta5 + ntlmssp_output_channel_bindings@Base 1.0~beta5 + ntlmssp_output_negotiate_flags@Base 1.0~beta5 + ntlmssp_output_target_name@Base 1.0~beta5 + ntlmssp_populate_av_pairs@Base 1.0~beta5 + ntlmssp_print_av_pairs@Base 1.0~beta5 + ntlmssp_print_negotiate_flags@Base 1.0~beta5 + ntlmssp_recv@Base 1.0~beta5 + ntlmssp_recv_challenge_message@Base 1.0~beta5 + ntlmssp_send@Base 1.0~beta5 + ntlmssp_send_authenticate_message@Base 1.0~beta5 + ntlmssp_send_negotiate_message@Base 1.0~beta5 + ntlmssp_set_domain@Base 1.0~beta5 + ntlmssp_set_password@Base 1.0~beta5 + ntlmssp_set_username@Base 1.0~beta5 + ntlmssp_set_workstation@Base 1.0~beta5 + ntlmssp_uninit@Base 1.0~beta5 + per_read_choice@Base 1.0~beta5 + per_read_enumerated@Base 1.0~beta5 + per_read_integer16@Base 1.0~beta5 + per_read_integer@Base 1.0~beta5 + per_read_length@Base 1.0~beta5 + per_read_number_of_sets@Base 1.0~beta5 + per_read_numeric_string@Base 1.0~beta5 + per_read_object_identifier@Base 1.0~beta5 + per_read_octet_string@Base 1.0~beta5 + per_read_padding@Base 1.0~beta5 + per_read_selection@Base 1.0~beta5 + per_write_choice@Base 1.0~beta5 + per_write_enumerated@Base 1.0~beta5 + per_write_integer16@Base 1.0~beta5 + per_write_integer@Base 1.0~beta5 + per_write_length@Base 1.0~beta5 + per_write_number_of_sets@Base 1.0~beta5 + per_write_numeric_string@Base 1.0~beta5 + per_write_object_identifier@Base 1.0~beta5 + per_write_octet_string@Base 1.0~beta5 + per_write_padding@Base 1.0~beta5 + per_write_selection@Base 1.0~beta5 + per_write_string@Base 1.0~beta5 + rdp_capability_set_finish@Base 1.0~beta5 + rdp_capability_set_start@Base 1.0~beta5 + rdp_check_fds@Base 1.0~beta5 + rdp_client_connect@Base 1.0~beta5 + rdp_client_connect_demand_active@Base 1.0~beta5 + rdp_client_connect_finalize@Base 1.0~beta5 + rdp_client_connect_license@Base 1.0~beta5 + rdp_client_connect_mcs_attach_user_confirm@Base 1.0~beta5 + rdp_client_connect_mcs_channel_join_confirm@Base 1.0~beta5 + rdp_client_connect_mcs_connect_response@Base 1.0~beta5 + rdp_client_disconnect@Base 1.0~beta5 + rdp_client_input_pdu_init@Base 1.0~beta5 + rdp_client_redirect@Base 1.0~beta5 + rdp_data_pdu_init@Base 1.0~beta5 + rdp_decrypt@Base 1.0~beta5 + rdp_free@Base 1.0~beta5 + rdp_get_client_time_zone@Base 1.0~beta5 + rdp_new@Base 1.0~beta5 + rdp_pdu_init@Base 1.0~beta5 + rdp_print_errinfo@Base 1.0~beta5 + rdp_print_redirection_flags@Base 1.0~beta5 + rdp_read_bitmap_cache_capability_set@Base 1.0~beta5 + rdp_read_bitmap_cache_host_support_capability_set@Base 1.0~beta5 + rdp_read_bitmap_cache_v2_capability_set@Base 1.0~beta5 + rdp_read_bitmap_capability_set@Base 1.0~beta5 + rdp_read_bitmap_codecs_capability_set@Base 1.0~beta5 + rdp_read_brush_capability_set@Base 1.0~beta5 + rdp_read_cache_definition@Base 1.0~beta5 + rdp_read_capability_set_header@Base 1.0~beta5 + rdp_read_capability_sets@Base 1.0~beta5 + rdp_read_client_auto_reconnect_cookie@Base 1.0~beta5 + rdp_read_client_time_zone@Base 1.0~beta5 + rdp_read_color_cache_capability_set@Base 1.0~beta5 + rdp_read_control_capability_set@Base 1.0~beta5 + rdp_read_desktop_composition_capability_set@Base 1.0~beta5 + rdp_read_draw_gdiplus_cache_capability_set@Base 1.0~beta5 + rdp_read_draw_nine_grid_cache_capability_set@Base 1.0~beta5 + rdp_read_extended_info_packet@Base 1.0~beta5 + rdp_read_font_capability_set@Base 1.0~beta5 + rdp_read_frame_acknowledge_capability_set@Base 1.0~beta5 + rdp_read_general_capability_set@Base 1.0~beta5 + rdp_read_glyph_cache_capability_set@Base 1.0~beta5 + rdp_read_header@Base 1.0~beta5 + rdp_read_info_packet@Base 1.0~beta5 + rdp_read_input_capability_set@Base 1.0~beta5 + rdp_read_large_pointer_capability_set@Base 1.0~beta5 + rdp_read_multifragment_update_capability_set@Base 1.0~beta5 + rdp_read_offscreen_bitmap_cache_capability_set@Base 1.0~beta5 + rdp_read_order_capability_set@Base 1.0~beta5 + rdp_read_pointer_capability_set@Base 1.0~beta5 + rdp_read_remote_programs_capability_set@Base 1.0~beta5 + rdp_read_security_header@Base 1.0~beta5 + rdp_read_server_auto_reconnect_cookie@Base 1.0~beta5 + rdp_read_share_capability_set@Base 1.0~beta5 + rdp_read_share_control_header@Base 1.0~beta5 + rdp_read_share_data_header@Base 1.0~beta5 + rdp_read_sound_capability_set@Base 1.0~beta5 + rdp_read_surface_commands_capability_set@Base 1.0~beta5 + rdp_read_system_time@Base 1.0~beta5 + rdp_read_virtual_channel_capability_set@Base 1.0~beta5 + rdp_read_window_activation_capability_set@Base 1.0~beta5 + rdp_read_window_list_capability_set@Base 1.0~beta5 + rdp_recv@Base 1.0~beta5 + rdp_recv_client_font_list_pdu@Base 1.0~beta5 + rdp_recv_client_font_map_pdu@Base 1.0.0 + rdp_recv_client_info@Base 1.0~beta5 + rdp_recv_client_synchronize_pdu@Base 1.0~beta5 + rdp_recv_confirm_active@Base 1.0~beta5 + rdp_recv_control_pdu@Base 1.0~beta5 + rdp_recv_data_pdu@Base 1.0~beta5 + rdp_recv_deactivate_all@Base 1.0~beta5 + rdp_recv_demand_active@Base 1.0~beta5 + rdp_recv_enhanced_security_redirection_packet@Base 1.0~beta5 + rdp_recv_font_map_pdu@Base 1.0.0 + rdp_recv_logon_error_info@Base 1.0~beta5 + rdp_recv_logon_info_extended@Base 1.0~beta5 + rdp_recv_logon_info_v1@Base 1.0~beta5 + rdp_recv_logon_info_v2@Base 1.0~beta5 + rdp_recv_logon_plain_notify@Base 1.0~beta5 + rdp_recv_out_of_sequence_pdu@Base 1.0~beta5 + rdp_recv_redirection_packet@Base 1.0~beta5 + rdp_recv_save_session_info@Base 1.0~beta5 + rdp_recv_server_control_pdu@Base 1.0~beta5 + rdp_recv_server_font_map_pdu@Base 1.0~beta5 + rdp_recv_server_redirection_pdu@Base 1.0~beta5 + rdp_recv_server_synchronize_pdu@Base 1.0~beta5 + rdp_recv_set_error_info_data_pdu@Base 1.0~beta5 + rdp_recv_synchronize_pdu@Base 1.0.0 + rdp_send@Base 1.0~beta5 + rdp_send_channel_data@Base 1.0~beta5 + rdp_send_client_control_pdu@Base 1.0~beta5 + rdp_send_client_font_list_pdu@Base 1.0~beta5 + rdp_send_client_info@Base 1.0~beta5 + rdp_send_client_input_pdu@Base 1.0~beta5 + rdp_send_client_persistent_key_list_pdu@Base 1.0~beta5 + rdp_send_client_synchronize_pdu@Base 1.0~beta5 + rdp_send_confirm_active@Base 1.0~beta5 + rdp_send_data_pdu@Base 1.0~beta5 + rdp_send_deactivate_all@Base 1.0~beta5 + rdp_send_demand_active@Base 1.0~beta5 + rdp_send_pdu@Base 1.0~beta5 + rdp_send_server_control_cooperate_pdu@Base 1.0~beta5 + rdp_send_server_control_granted_pdu@Base 1.0~beta5 + rdp_send_server_font_map_pdu@Base 1.0~beta5 + rdp_send_server_synchronize_pdu@Base 1.0~beta5 + rdp_send_stream_init@Base 1.0~beta5 + rdp_server_accept_client_control_pdu@Base 1.0~beta5 + rdp_server_accept_client_font_list_pdu@Base 1.0~beta5 + rdp_server_accept_client_info@Base 1.0~beta5 + rdp_server_accept_client_keys@Base 1.0.1 + rdp_server_accept_confirm_active@Base 1.0~beta5 + rdp_server_accept_mcs_attach_user_request@Base 1.0~beta5 + rdp_server_accept_mcs_channel_join_request@Base 1.0~beta5 + rdp_server_accept_mcs_connect_initial@Base 1.0~beta5 + rdp_server_accept_mcs_erect_domain_request@Base 1.0~beta5 + rdp_server_accept_nego@Base 1.0~beta5 + rdp_server_reactivate@Base 1.0~beta5 + rdp_set_blocking_mode@Base 1.0~beta5 + rdp_write_bitmap_cache_capability_set@Base 1.0~beta5 + rdp_write_bitmap_cache_cell_info@Base 1.0~beta5 + rdp_write_bitmap_cache_host_support_capability_set@Base 1.0~beta5 + rdp_write_bitmap_cache_v2_capability_set@Base 1.0~beta5 + rdp_write_bitmap_capability_set@Base 1.0~beta5 + rdp_write_bitmap_codecs_capability_set@Base 1.0~beta5 + rdp_write_brush_capability_set@Base 1.0~beta5 + rdp_write_cache_definition@Base 1.0~beta5 + rdp_write_capability_set_header@Base 1.0~beta5 + rdp_write_client_auto_reconnect_cookie@Base 1.0~beta5 + rdp_write_client_control_pdu@Base 1.0~beta5 + rdp_write_client_font_list_pdu@Base 1.0~beta5 + rdp_write_client_input_pdu_header@Base 1.0~beta5 + rdp_write_client_persistent_key_list_pdu@Base 1.0~beta5 + rdp_write_client_time_zone@Base 1.0~beta5 + rdp_write_color_cache_capability_set@Base 1.0~beta5 + rdp_write_confirm_active@Base 1.0~beta5 + rdp_write_control_capability_set@Base 1.0~beta5 + rdp_write_demand_active@Base 1.0~beta5 + rdp_write_desktop_composition_capability_set@Base 1.0~beta5 + rdp_write_draw_gdiplus_cache_capability_set@Base 1.0~beta5 + rdp_write_draw_nine_grid_cache_capability_set@Base 1.0~beta5 + rdp_write_extended_info_packet@Base 1.0~beta5 + rdp_write_font_capability_set@Base 1.0~beta5 + rdp_write_frame_acknowledge_capability_set@Base 1.0~beta5 + rdp_write_gdiplus_cache_chunk_size@Base 1.0~beta5 + rdp_write_gdiplus_cache_entries@Base 1.0~beta5 + rdp_write_gdiplus_image_cache_properties@Base 1.0~beta5 + rdp_write_general_capability_set@Base 1.0~beta5 + rdp_write_glyph_cache_capability_set@Base 1.0~beta5 + rdp_write_header@Base 1.0~beta5 + rdp_write_info_packet@Base 1.0~beta5 + rdp_write_input_capability_set@Base 1.0~beta5 + rdp_write_input_event_header@Base 1.0~beta5 + rdp_write_large_pointer_capability_set@Base 1.0~beta5 + rdp_write_multifragment_update_capability_set@Base 1.0~beta5 + rdp_write_nsc_client_capability_container@Base 1.0~beta5 + rdp_write_nsc_server_capability_container@Base 1.0~beta5 + rdp_write_offscreen_bitmap_cache_capability_set@Base 1.0~beta5 + rdp_write_order_capability_set@Base 1.0~beta5 + rdp_write_persistent_list_entry@Base 1.0~beta5 + rdp_write_pointer_capability_set@Base 1.0~beta5 + rdp_write_remote_programs_capability_set@Base 1.0~beta5 + rdp_write_rfx_client_capability_container@Base 1.0~beta5 + rdp_write_rfx_server_capability_container@Base 1.0~beta5 + rdp_write_security_header@Base 1.0~beta5 + rdp_write_share_capability_set@Base 1.0~beta5 + rdp_write_share_control_header@Base 1.0~beta5 + rdp_write_share_data_header@Base 1.0~beta5 + rdp_write_sound_capability_set@Base 1.0~beta5 + rdp_write_surface_commands_capability_set@Base 1.0~beta5 + rdp_write_synchronize_pdu@Base 1.0~beta5 + rdp_write_system_time@Base 1.0~beta5 + rdp_write_virtual_channel_capability_set@Base 1.0~beta5 + rdp_write_window_activation_capability_set@Base 1.0~beta5 + rdp_write_window_list_capability_set@Base 1.0~beta5 + redirection_free@Base 1.0~beta5 + redirection_new@Base 1.0~beta5 + security_decrypt@Base 1.0~beta5 + security_encrypt@Base 1.0~beta5 + security_establish_keys@Base 1.0~beta5 + security_fips_check_signature@Base 1.0~beta5 + security_fips_decrypt@Base 1.0~beta5 + security_fips_encrypt@Base 1.0~beta5 + security_hmac_signature@Base 1.0~beta5 + security_key_update@Base 1.0~beta5 + security_licensing_encryption_key@Base 1.0~beta5 + security_mac_data@Base 1.0~beta5 + security_mac_salt_key@Base 1.0~beta5 + security_mac_signature@Base 1.0~beta5 + security_master_secret@Base 1.0~beta5 + security_md5_16_32_32@Base 1.0~beta5 + security_salted_mac_signature@Base 1.0.1 + security_session_key_blob@Base 1.0~beta5 + security_uint32_le@Base 1.0~beta5 + settings_free@Base 1.0~beta5 + settings_new@Base 1.0~beta5 + t124_02_98_oid@Base 1.0~beta5 + tcp_connect@Base 1.0~beta5 + tcp_disconnect@Base 1.0~beta5 + tcp_free@Base 1.0~beta5 + tcp_get_ip_address@Base 1.0~beta5 + tcp_get_mac_address@Base 1.0~beta5 + tcp_new@Base 1.0~beta5 + tcp_read@Base 1.0~beta5 + tcp_set_blocking_mode@Base 1.0~beta5 + tcp_set_keep_alive_mode@Base 1.0~beta5 + tcp_write@Base 1.0~beta5 + tls_accept@Base 1.0~beta5 + tls_connect@Base 1.0~beta5 + tls_disconnect@Base 1.0~beta5 + tls_free@Base 1.0~beta5 + tls_get_certificate@Base 1.0~beta5 + tls_new@Base 1.0~beta5 + tls_print_certificate_error@Base 1.0.1 + tls_print_certificate_name_mismatch_error@Base 1.0.1 + tls_print_error@Base 1.0~beta5 + tls_read@Base 1.0~beta5 + tls_verify_certificate@Base 1.0~beta5 + tls_write@Base 1.0~beta5 + tpdu_read_connection_confirm@Base 1.0~beta5 + tpdu_read_connection_request@Base 1.0~beta5 + tpdu_read_data@Base 1.0~beta5 + tpdu_read_header@Base 1.0~beta5 + tpdu_write_connection_confirm@Base 1.0~beta5 + tpdu_write_connection_request@Base 1.0~beta5 + tpdu_write_data@Base 1.0~beta5 + tpdu_write_disconnect_request@Base 1.0~beta5 + tpdu_write_header@Base 1.0~beta5 + tpkt_read_header@Base 1.0~beta5 + tpkt_verify_header@Base 1.0~beta5 + tpkt_write_header@Base 1.0~beta5 + transport_accept_nla@Base 1.0~beta5 + transport_accept_rdp@Base 1.0~beta5 + transport_accept_tls@Base 1.0~beta5 + transport_attach@Base 1.0~beta5 + transport_check_fds@Base 1.0~beta5 + transport_connect@Base 1.0~beta5 + transport_connect_nla@Base 1.0~beta5 + transport_connect_rdp@Base 1.0~beta5 + transport_connect_tls@Base 1.0~beta5 + transport_disconnect@Base 1.0~beta5 + transport_free@Base 1.0~beta5 + transport_get_fds@Base 1.0~beta5 + transport_new@Base 1.0~beta5 + transport_read@Base 1.0~beta5 + transport_recv_stream_init@Base 1.0~beta5 + transport_send_stream_init@Base 1.0~beta5 + transport_set_blocking_mode@Base 1.0~beta5 + transport_write@Base 1.0~beta5 + tssk_exponent@Base 1.0.1 + tssk_modulus@Base 1.0.1 + tssk_privateExponent@Base 1.0.1 + update_decompress_brush@Base 1.0~beta5 + update_free@Base 1.0~beta5 + update_new@Base 1.0~beta5 + update_read_2byte_signed@Base 1.0~beta5 + update_read_2byte_unsigned@Base 1.0~beta5 + update_read_4byte_unsigned@Base 1.0~beta5 + update_read_bitmap@Base 1.0~beta5 + update_read_bitmap_data@Base 1.0~beta5 + update_read_bounds@Base 1.0~beta5 + update_read_brush@Base 1.0~beta5 + update_read_cache_bitmap_order@Base 1.0~beta5 + update_read_cache_bitmap_v2_order@Base 1.0~beta5 + update_read_cache_bitmap_v3_order@Base 1.0~beta5 + update_read_cache_brush_order@Base 1.0~beta5 + update_read_cache_color_table_order@Base 1.0~beta5 + update_read_cache_glyph_order@Base 1.0~beta5 + update_read_cache_glyph_v2_order@Base 1.0~beta5 + update_read_cached_icon_info@Base 1.0~beta5 + update_read_color@Base 1.0~beta5 + update_read_color_quad@Base 1.0~beta5 + update_read_colorref@Base 1.0~beta5 + update_read_coord@Base 1.0~beta5 + update_read_create_nine_grid_bitmap_order@Base 1.0~beta5 + update_read_create_offscreen_bitmap_order@Base 1.0~beta5 + update_read_delta@Base 1.0~beta5 + update_read_delta_points@Base 1.0~beta5 + update_read_delta_rects@Base 1.0~beta5 + update_read_desktop_actively_monitored_order@Base 1.0~beta5 + update_read_desktop_non_monitored_order@Base 1.0~beta5 + update_read_draw_gdiplus_cache_end_order@Base 1.0~beta5 + update_read_draw_gdiplus_cache_first_order@Base 1.0~beta5 + update_read_draw_gdiplus_cache_next_order@Base 1.0~beta5 + update_read_draw_gdiplus_end_order@Base 1.0~beta5 + update_read_draw_gdiplus_first_order@Base 1.0~beta5 + update_read_draw_gdiplus_next_order@Base 1.0~beta5 + update_read_draw_nine_grid_order@Base 1.0~beta5 + update_read_dstblt_order@Base 1.0~beta5 + update_read_ellipse_cb_order@Base 1.0~beta5 + update_read_ellipse_sc_order@Base 1.0~beta5 + update_read_fast_glyph_order@Base 1.0~beta5 + update_read_fast_index_order@Base 1.0~beta5 + update_read_field_flags@Base 1.0~beta5 + update_read_frame_marker_order@Base 1.0~beta5 + update_read_glyph_delta@Base 1.0~beta5 + update_read_glyph_index_order@Base 1.0~beta5 + update_read_icon_info@Base 1.0~beta5 + update_read_line_to_order@Base 1.0~beta5 + update_read_mem3blt_order@Base 1.0~beta5 + update_read_memblt_order@Base 1.0~beta5 + update_read_multi_draw_nine_grid_order@Base 1.0~beta5 + update_read_multi_dstblt_order@Base 1.0~beta5 + update_read_multi_opaque_rect_order@Base 1.0~beta5 + update_read_multi_patblt_order@Base 1.0~beta5 + update_read_multi_scrblt_order@Base 1.0~beta5 + update_read_notification_icon_delete_order@Base 1.0~beta5 + update_read_notification_icon_state_order@Base 1.0~beta5 + update_read_notify_icon_infotip@Base 1.0~beta5 + update_read_opaque_rect_order@Base 1.0~beta5 + update_read_palette@Base 1.0~beta5 + update_read_patblt_order@Base 1.0~beta5 + update_read_play_sound@Base 1.0~beta5 + update_read_pointer_cached@Base 1.0~beta5 + update_read_pointer_color@Base 1.0~beta5 + update_read_pointer_new@Base 1.0~beta5 + update_read_pointer_position@Base 1.0~beta5 + update_read_pointer_system@Base 1.0~beta5 + update_read_polygon_cb_order@Base 1.0~beta5 + update_read_polygon_sc_order@Base 1.0~beta5 + update_read_polyline_order@Base 1.0~beta5 + update_read_save_bitmap_order@Base 1.0~beta5 + update_read_scrblt_order@Base 1.0~beta5 + update_read_stream_bitmap_first_order@Base 1.0~beta5 + update_read_stream_bitmap_next_order@Base 1.0~beta5 + update_read_switch_surface_order@Base 1.0~beta5 + update_read_synchronize@Base 1.0~beta5 + update_read_window_cached_icon_order@Base 1.0~beta5 + update_read_window_delete_order@Base 1.0~beta5 + update_read_window_icon_order@Base 1.0~beta5 + update_read_window_state_order@Base 1.0~beta5 + update_recv@Base 1.0~beta5 + update_recv_altsec_order@Base 1.0~beta5 + update_recv_altsec_window_order@Base 1.0~beta5 + update_recv_desktop_info_order@Base 1.0~beta5 + update_recv_notification_icon_info_order@Base 1.0~beta5 + update_recv_order@Base 1.0~beta5 + update_recv_orders@Base 1.0~beta5 + update_recv_play_sound@Base 1.0~beta5 + update_recv_pointer@Base 1.0~beta5 + update_recv_primary_order@Base 1.0~beta5 + update_recv_secondary_order@Base 1.0~beta5 + update_recv_surfcmds@Base 1.0~beta5 + update_recv_window_info_order@Base 1.0~beta5 + update_register_server_callbacks@Base 1.0~beta5 + update_reset_state@Base 1.0~beta5 + update_seek_glyph_delta@Base 1.0~beta5 + update_write_surfcmd_frame_marker@Base 1.0~beta5 + update_write_surfcmd_surface_bits_header@Base 1.0~beta5 + x509_verify_certificate@Base 1.0.1 +libfreerdp-gdi.so.1.0 libfreerdp1 #MINVER# + BitBlt_16bpp@Base 1.0~beta5 + BitBlt_32bpp@Base 1.0~beta5 + BitBlt_8bpp@Base 1.0~beta5 + BitBlt_@Base 1.0~beta5 + CreateSystemPalette@Base 1.0~beta5 + FillRect_16bpp@Base 1.0~beta5 + FillRect_32bpp@Base 1.0~beta5 + FillRect_8bpp@Base 1.0~beta5 + FillRect_@Base 1.0~beta5 + LineTo_16bpp@Base 1.0~beta5 + LineTo_32bpp@Base 1.0~beta5 + LineTo_8bpp@Base 1.0~beta5 + LineTo_@Base 1.0~beta5 + LineTo_BLACK_16bpp@Base 1.0.1 + LineTo_BLACK_32bpp@Base 1.0.1 + LineTo_BLACK_8bpp@Base 1.0.1 + LineTo_COPYPEN_16bpp@Base 1.0.1 + LineTo_COPYPEN_32bpp@Base 1.0.1 + LineTo_COPYPEN_8bpp@Base 1.0.1 + LineTo_MASKNOTPEN_16bpp@Base 1.0.1 + LineTo_MASKNOTPEN_32bpp@Base 1.0.1 + LineTo_MASKNOTPEN_8bpp@Base 1.0.1 + LineTo_MASKPENNOT_16bpp@Base 1.0.1 + LineTo_MASKPENNOT_32bpp@Base 1.0.1 + LineTo_MASKPENNOT_8bpp@Base 1.0.1 + LineTo_MASKPEN_16bpp@Base 1.0.1 + LineTo_MASKPEN_32bpp@Base 1.0.1 + LineTo_MASKPEN_8bpp@Base 1.0.1 + LineTo_MERGENOTPEN_16bpp@Base 1.0.1 + LineTo_MERGENOTPEN_32bpp@Base 1.0.1 + LineTo_MERGENOTPEN_8bpp@Base 1.0.1 + LineTo_MERGEPENNOT_16bpp@Base 1.0.1 + LineTo_MERGEPENNOT_32bpp@Base 1.0.1 + LineTo_MERGEPENNOT_8bpp@Base 1.0.1 + LineTo_MERGEPEN_16bpp@Base 1.0.1 + LineTo_MERGEPEN_32bpp@Base 1.0.1 + LineTo_MERGEPEN_8bpp@Base 1.0.1 + LineTo_NOP_16bpp@Base 1.0.1 + LineTo_NOP_32bpp@Base 1.0.1 + LineTo_NOP_8bpp@Base 1.0.1 + LineTo_NOTCOPYPEN_16bpp@Base 1.0.1 + LineTo_NOTCOPYPEN_32bpp@Base 1.0.1 + LineTo_NOTCOPYPEN_8bpp@Base 1.0.1 + LineTo_NOTMASKPEN_16bpp@Base 1.0.1 + LineTo_NOTMASKPEN_32bpp@Base 1.0.1 + LineTo_NOTMASKPEN_8bpp@Base 1.0.1 + LineTo_NOTMERGEPEN_16bpp@Base 1.0.1 + LineTo_NOTMERGEPEN_32bpp@Base 1.0.1 + LineTo_NOTMERGEPEN_8bpp@Base 1.0.1 + LineTo_NOTXORPEN_16bpp@Base 1.0.1 + LineTo_NOTXORPEN_32bpp@Base 1.0.1 + LineTo_NOTXORPEN_8bpp@Base 1.0.1 + LineTo_NOT_16bpp@Base 1.0.1 + LineTo_NOT_32bpp@Base 1.0.1 + LineTo_NOT_8bpp@Base 1.0.1 + LineTo_ROP2_16bpp@Base 1.0.1 + LineTo_ROP2_32bpp@Base 1.0.1 + LineTo_ROP2_8bpp@Base 1.0.1 + LineTo_WHITE_16bpp@Base 1.0.1 + LineTo_WHITE_32bpp@Base 1.0.1 + LineTo_WHITE_8bpp@Base 1.0.1 + LineTo_XORPEN_16bpp@Base 1.0.1 + LineTo_XORPEN_32bpp@Base 1.0.1 + LineTo_XORPEN_8bpp@Base 1.0.1 + PatBlt_16bpp@Base 1.0~beta5 + PatBlt_32bpp@Base 1.0~beta5 + PatBlt_8bpp@Base 1.0~beta5 + PatBlt_@Base 1.0~beta5 + SetPixel_BLACK_16bpp@Base 1.0~beta5 + SetPixel_BLACK_32bpp@Base 1.0~beta5 + SetPixel_BLACK_8bpp@Base 1.0~beta5 + SetPixel_COPYPEN_16bpp@Base 1.0~beta5 + SetPixel_COPYPEN_32bpp@Base 1.0~beta5 + SetPixel_COPYPEN_8bpp@Base 1.0~beta5 + SetPixel_MASKNOTPEN_16bpp@Base 1.0~beta5 + SetPixel_MASKNOTPEN_32bpp@Base 1.0~beta5 + SetPixel_MASKNOTPEN_8bpp@Base 1.0~beta5 + SetPixel_MASKPENNOT_16bpp@Base 1.0~beta5 + SetPixel_MASKPENNOT_32bpp@Base 1.0~beta5 + SetPixel_MASKPENNOT_8bpp@Base 1.0~beta5 + SetPixel_MASKPEN_16bpp@Base 1.0~beta5 + SetPixel_MASKPEN_32bpp@Base 1.0~beta5 + SetPixel_MASKPEN_8bpp@Base 1.0~beta5 + SetPixel_MERGENOTPEN_16bpp@Base 1.0~beta5 + SetPixel_MERGENOTPEN_32bpp@Base 1.0~beta5 + SetPixel_MERGENOTPEN_8bpp@Base 1.0~beta5 + SetPixel_MERGEPENNOT_16bpp@Base 1.0~beta5 + SetPixel_MERGEPENNOT_32bpp@Base 1.0~beta5 + SetPixel_MERGEPENNOT_8bpp@Base 1.0~beta5 + SetPixel_MERGEPEN_16bpp@Base 1.0~beta5 + SetPixel_MERGEPEN_32bpp@Base 1.0~beta5 + SetPixel_MERGEPEN_8bpp@Base 1.0~beta5 + SetPixel_NOP_16bpp@Base 1.0~beta5 + SetPixel_NOP_32bpp@Base 1.0~beta5 + SetPixel_NOP_8bpp@Base 1.0~beta5 + SetPixel_NOTCOPYPEN_16bpp@Base 1.0~beta5 + SetPixel_NOTCOPYPEN_32bpp@Base 1.0~beta5 + SetPixel_NOTCOPYPEN_8bpp@Base 1.0~beta5 + SetPixel_NOTMASKPEN_16bpp@Base 1.0~beta5 + SetPixel_NOTMASKPEN_32bpp@Base 1.0~beta5 + SetPixel_NOTMASKPEN_8bpp@Base 1.0~beta5 + SetPixel_NOTMERGEPEN_16bpp@Base 1.0~beta5 + SetPixel_NOTMERGEPEN_32bpp@Base 1.0~beta5 + SetPixel_NOTMERGEPEN_8bpp@Base 1.0~beta5 + SetPixel_NOTXORPEN_16bpp@Base 1.0~beta5 + SetPixel_NOTXORPEN_32bpp@Base 1.0~beta5 + SetPixel_NOTXORPEN_8bpp@Base 1.0~beta5 + SetPixel_NOT_16bpp@Base 1.0~beta5 + SetPixel_NOT_32bpp@Base 1.0~beta5 + SetPixel_NOT_8bpp@Base 1.0~beta5 + SetPixel_WHITE_16bpp@Base 1.0~beta5 + SetPixel_WHITE_32bpp@Base 1.0~beta5 + SetPixel_WHITE_8bpp@Base 1.0~beta5 + SetPixel_XORPEN_16bpp@Base 1.0~beta5 + SetPixel_XORPEN_32bpp@Base 1.0~beta5 + SetPixel_XORPEN_8bpp@Base 1.0~beta5 + gdi_BitBlt@Base 1.0~beta5 + gdi_Bitmap_Decompress@Base 1.0~beta5 + gdi_Bitmap_Free@Base 1.0~beta5 + gdi_Bitmap_New@Base 1.0~beta5 + gdi_Bitmap_Paint@Base 1.0~beta5 + gdi_Bitmap_SetSurface@Base 1.0~beta5 + gdi_CRectToCRgn@Base 1.0~beta5 + gdi_CRectToRgn@Base 1.0~beta5 + gdi_CRgnToCRect@Base 1.0~beta5 + gdi_CRgnToRect@Base 1.0~beta5 + gdi_ClipCoords@Base 1.0~beta5 + gdi_CopyOverlap@Base 1.0~beta5 + gdi_CopyRect@Base 1.0~beta5 + gdi_CreateBitmap@Base 1.0~beta5 + gdi_CreateCompatibleBitmap@Base 1.0~beta5 + gdi_CreateCompatibleDC@Base 1.0~beta5 + gdi_CreateDC@Base 1.0.1 + gdi_CreatePalette@Base 1.0~beta5 + gdi_CreatePatternBrush@Base 1.0~beta5 + gdi_CreatePen@Base 1.0~beta5 + gdi_CreateRect@Base 1.0~beta5 + gdi_CreateRectRgn@Base 1.0~beta5 + gdi_CreateSolidBrush@Base 1.0~beta5 + gdi_DeleteDC@Base 1.0~beta5 + gdi_DeleteObject@Base 1.0~beta5 + gdi_Ellipse@Base 1.0~beta5 + gdi_EqualRgn@Base 1.0~beta5 + gdi_FillRect@Base 1.0~beta5 + gdi_GetBkColor@Base 1.0~beta5 + gdi_GetBkMode@Base 1.0~beta5 + gdi_GetClipRgn@Base 1.0~beta5 + gdi_GetDC@Base 1.0~beta5 + gdi_GetPenColor_16bpp@Base 1.0~beta5 + gdi_GetPenColor_32bpp@Base 1.0~beta5 + gdi_GetPenColor_8bpp@Base 1.0~beta5 + gdi_GetPixel@Base 1.0~beta5 + gdi_GetPixel_16bpp@Base 1.0~beta5 + gdi_GetPixel_32bpp@Base 1.0~beta5 + gdi_GetPixel_8bpp@Base 1.0~beta5 + gdi_GetPointer_16bpp@Base 1.0~beta5 + gdi_GetPointer_32bpp@Base 1.0~beta5 + gdi_GetPointer_8bpp@Base 1.0~beta5 + gdi_GetROP2@Base 1.0~beta5 + gdi_GetSystemPalette@Base 1.0~beta5 + gdi_Glyph_BeginDraw@Base 1.0~beta5 + gdi_Glyph_Draw@Base 1.0~beta5 + gdi_Glyph_EndDraw@Base 1.0~beta5 + gdi_Glyph_Free@Base 1.0~beta5 + gdi_Glyph_New@Base 1.0~beta5 + gdi_InvalidateRegion@Base 1.0~beta5 + gdi_LineTo@Base 1.0~beta5 + gdi_MoveToEx@Base 1.0~beta5 + gdi_PatBlt@Base 1.0~beta5 + gdi_PolyPolygon@Base 1.0~beta5 + gdi_PolyPolyline@Base 1.0~beta5 + gdi_Polygon@Base 1.0~beta5 + gdi_Polyline@Base 1.0~beta5 + gdi_PolylineTo@Base 1.0~beta5 + gdi_PtInRect@Base 1.0~beta5 + gdi_RectToCRgn@Base 1.0~beta5 + gdi_RectToRgn@Base 1.0~beta5 + gdi_Rectangle@Base 1.0~beta5 + gdi_RgnToCRect@Base 1.0~beta5 + gdi_RgnToRect@Base 1.0~beta5 + gdi_SelectObject@Base 1.0~beta5 + gdi_SetBkColor@Base 1.0~beta5 + gdi_SetBkMode@Base 1.0~beta5 + gdi_SetClipRgn@Base 1.0~beta5 + gdi_SetNullClipRgn@Base 1.0~beta5 + gdi_SetPixel@Base 1.0~beta5 + gdi_SetPixel_16bpp@Base 1.0~beta5 + gdi_SetPixel_32bpp@Base 1.0~beta5 + gdi_SetPixel_8bpp@Base 1.0~beta5 + gdi_SetROP2@Base 1.0~beta5 + gdi_SetRect@Base 1.0~beta5 + gdi_SetRectRgn@Base 1.0~beta5 + gdi_SetRgn@Base 1.0~beta5 + gdi_SetTextColor@Base 1.0~beta5 + gdi_bitmap_free_ex@Base 1.0~beta5 + gdi_bitmap_new_ex@Base 1.0~beta5 + gdi_create_bitmap@Base 1.0~beta5 + gdi_dstblt@Base 1.0~beta5 + gdi_free@Base 1.0~beta5 + gdi_get_bitmap_pointer@Base 1.0~beta5 + gdi_get_brush_pointer@Base 1.0~beta5 + gdi_get_color_16bpp@Base 1.0~beta5 + gdi_get_color_32bpp@Base 1.0~beta5 + gdi_glyph_free@Base 1.0~beta5 + gdi_glyph_new@Base 1.0~beta5 + gdi_init@Base 1.0~beta5 + gdi_init_primary@Base 1.0~beta5 + gdi_is_mono_pixel_set@Base 1.0~beta5 + gdi_line_to@Base 1.0~beta5 + gdi_mem3blt@Base 1.0~beta5 + gdi_memblt@Base 1.0~beta5 + gdi_multi_opaque_rect@Base 1.0~beta5 + gdi_opaque_rect@Base 1.0~beta5 + gdi_palette_update@Base 1.0~beta5 + gdi_patblt@Base 1.0~beta5 + gdi_polyline@Base 1.0~beta5 + gdi_register_graphics@Base 1.0~beta5 + gdi_register_update_callbacks@Base 1.0~beta5 + gdi_resize@Base 1.0~beta5 + gdi_rop3_code@Base 1.0~beta5 + gdi_scrblt@Base 1.0~beta5 + gdi_set_bounds@Base 1.0~beta5 + gdi_surface_bits@Base 1.0~beta5 + tilenum@Base 1.0~beta5 +libfreerdp-kbd.so.1.0 libfreerdp1 #MINVER# + detect_keyboard_layout_from_locale@Base 1.0~beta5 + detect_keyboard_layout_from_xkb@Base 1.0~beta5 + find_keyboard_layout_in_xorg_rules@Base 1.0~beta5 + freerdp_kbd_get_keycode_by_scancode@Base 1.0.0 + freerdp_kbd_get_layouts@Base 1.0~beta5 + freerdp_kbd_get_scancode_by_keycode@Base 1.0~beta5 + freerdp_kbd_get_scancode_by_virtualkey@Base 1.0~beta5 + freerdp_kbd_init@Base 1.0~beta5 + get_keyboard_layouts@Base 1.0~beta5 + get_layout_name@Base 1.0~beta5 + init_keycodes_from_xkb@Base 1.0~beta5 + init_xkb@Base 1.0~beta5 + rdp_scancode_to_x_keycode@Base 1.0.0 + x_keycode_to_rdp_scancode@Base 1.0.0 +libfreerdp-rail.so.1.0 libfreerdp1 #MINVER# + icon_cache_free@Base 1.0~beta5 + icon_cache_get@Base 1.0~beta5 + icon_cache_new@Base 1.0~beta5 + icon_cache_put@Base 1.0~beta5 + print_extended_window_styles@Base 1.0~beta5 + print_window_styles@Base 1.0~beta5 + rail_CreateWindow@Base 1.0~beta5 + rail_DestroyWindow@Base 1.0~beta5 + rail_UpdateWindow@Base 1.0~beta5 + rail_free@Base 1.0~beta5 + rail_new@Base 1.0~beta5 + rail_register_update_callbacks@Base 1.0~beta5 + window_list_create@Base 1.0~beta5 + window_list_delete@Base 1.0~beta5 + window_list_free@Base 1.0~beta5 + window_list_get_by_extra_id@Base 1.0~beta5 + window_list_get_by_id@Base 1.0~beta5 + window_list_get_next@Base 1.0~beta5 + window_list_has_next@Base 1.0~beta5 + window_list_new@Base 1.0~beta5 + window_list_rewind@Base 1.0~beta5 + window_list_update@Base 1.0~beta5 + window_state_update@Base 1.0~beta5 +libfreerdp-utils.so.1.0 libfreerdp1 #MINVER# + dsp_decode_ima_adpcm@Base 1.0~beta5 + dsp_encode_ima_adpcm@Base 1.0~beta5 + dsp_resample@Base 1.0~beta5 + freerdp_append_shared_library_suffix@Base 1.0.1 + freerdp_bitmap_write@Base 1.0~beta5 + freerdp_blob_alloc@Base 1.0~beta5 + freerdp_blob_free@Base 1.0~beta5 + freerdp_check_file_exists@Base 1.0.1 + freerdp_close_library@Base 1.0.1 + freerdp_construct_path@Base 1.0.1 + freerdp_detect_development_mode@Base 1.0.1 + freerdp_detect_paths@Base 1.0.1 + freerdp_event_free@Base 1.0~beta5 + freerdp_event_new@Base 1.0~beta5 + freerdp_get_config_path@Base 1.0.1 + freerdp_get_current_path@Base 1.0.1 + freerdp_get_home_path@Base 1.0.1 + freerdp_get_library_symbol@Base 1.0.1 + freerdp_get_parent_path@Base 1.0.1 + freerdp_handle_signals@Base 1.0~beta5 + freerdp_hexdump@Base 1.0~beta5 + freerdp_load_channel_plugin@Base 1.0.1 + freerdp_load_library_symbol@Base 1.0.1 + freerdp_load_plugin@Base 1.0~beta5 + freerdp_mkdir@Base 1.0~beta5 + freerdp_mutex_free@Base 1.0~beta5 + freerdp_mutex_lock@Base 1.0~beta5 + freerdp_mutex_new@Base 1.0~beta5 + freerdp_mutex_unlock@Base 1.0~beta5 + freerdp_open_library@Base 1.0.1 + freerdp_parse_args@Base 1.0~beta5 + freerdp_passphrase_read@Base 1.0~beta5 + freerdp_path_contains_separator@Base 1.0.1 + freerdp_read_rectangle_16@Base 1.0~beta5 + freerdp_rectangle_16_free@Base 1.0~beta5 + freerdp_rectangle_16_new@Base 1.0~beta5 + freerdp_sem_free@Base 1.0~beta5 + freerdp_sem_new@Base 1.0~beta5 + freerdp_sem_signal@Base 1.0~beta5 + freerdp_sem_wait@Base 1.0~beta5 + freerdp_sleep@Base 1.0~beta5 + freerdp_string_free@Base 1.0~beta5 + freerdp_string_read_length32@Base 1.0~beta5 + freerdp_thread_free@Base 1.0~beta5 + freerdp_thread_new@Base 1.0~beta5 + freerdp_thread_start@Base 1.0~beta5 + freerdp_thread_stop@Base 1.0~beta5 + freerdp_uniconv_free@Base 1.0~beta5 + freerdp_uniconv_in@Base 1.0~beta5 + freerdp_uniconv_new@Base 1.0~beta5 + freerdp_uniconv_out@Base 1.0~beta5 + freerdp_uniconv_uppercase@Base 1.0~beta5 + freerdp_usleep@Base 1.0~beta5 + freerdp_write_rectangle_16@Base 1.0~beta5 + list_dequeue@Base 1.0~beta5 + list_enqueue@Base 1.0~beta5 + list_free@Base 1.0~beta5 + list_new@Base 1.0~beta5 + list_next@Base 1.0~beta5 + list_peek@Base 1.0~beta5 + list_remove@Base 1.0~beta5 + list_size@Base 1.0~beta5 + new_flags@Base 1.0~beta5 + orig_flags@Base 1.0~beta5 + pcap_add_record@Base 1.0~beta5 + pcap_close@Base 1.0~beta5 + pcap_flush@Base 1.0~beta5 + pcap_get_next_record@Base 1.0~beta5 + pcap_get_next_record_content@Base 1.0~beta5 + pcap_get_next_record_header@Base 1.0~beta5 + pcap_has_next_record@Base 1.0~beta5 + pcap_open@Base 1.0~beta5 + pcap_read_header@Base 1.0~beta5 + pcap_read_record@Base 1.0~beta5 + pcap_read_record_header@Base 1.0~beta5 + pcap_write_header@Base 1.0~beta5 + pcap_write_record@Base 1.0~beta5 + pcap_write_record_header@Base 1.0~beta5 + profiler_create@Base 1.0~beta5 + profiler_enter@Base 1.0~beta5 + profiler_exit@Base 1.0~beta5 + profiler_free@Base 1.0~beta5 + profiler_print@Base 1.0~beta5 + profiler_print_footer@Base 1.0~beta5 + profiler_print_header@Base 1.0~beta5 + rail_clone_order@Base 1.0~beta5 + rail_free_cloned_order@Base 1.0~beta5 + rail_read_rectangle_16@Base 1.0~beta5 + rail_read_unicode_string@Base 1.0~beta5 + rail_unicode_string_alloc@Base 1.0~beta5 + rail_unicode_string_free@Base 1.0~beta5 + rail_write_rectangle_16@Base 1.0~beta5 + rail_write_unicode_string@Base 1.0~beta5 + rail_write_unicode_string_value@Base 1.0~beta5 + registry_close@Base 1.0~beta5 + registry_create@Base 1.0~beta5 + registry_free@Base 1.0~beta5 + registry_init@Base 1.0~beta5 + registry_load@Base 1.0~beta5 + registry_new@Base 1.0~beta5 + registry_open@Base 1.0~beta5 + registry_print@Base 1.0~beta5 + registry_print_entry@Base 1.0~beta5 + registry_print_section@Base 1.0~beta5 + stopwatch_create@Base 1.0~beta5 + stopwatch_free@Base 1.0~beta5 + stopwatch_get_elapsed_time_in_seconds@Base 1.0~beta5 + stopwatch_get_elapsed_time_in_useconds@Base 1.0~beta5 + stopwatch_reset@Base 1.0~beta5 + stopwatch_start@Base 1.0~beta5 + stopwatch_stop@Base 1.0~beta5 + stream_extend@Base 1.0~beta5 + stream_free@Base 1.0~beta5 + stream_new@Base 1.0~beta5 + svc_plugin_init@Base 1.0~beta5 + svc_plugin_send@Base 1.0~beta5 + svc_plugin_send_event@Base 1.0~beta5 + terminal_fildes@Base 1.0~beta5 + terminal_needs_reset@Base 1.0~beta5 + wait_obj_clear@Base 1.0~beta5 + wait_obj_free@Base 1.0~beta5 + wait_obj_get_fds@Base 1.0~beta5 + wait_obj_is_set@Base 1.0~beta5 + wait_obj_new@Base 1.0~beta5 + wait_obj_new_with_fd@Base 1.0~beta5 + wait_obj_select@Base 1.0~beta5 + wait_obj_set@Base 1.0~beta5 + xfree@Base 1.0~beta5 + xmalloc@Base 1.0~beta5 + xrealloc@Base 1.0~beta5 + xstrdup@Base 1.0~beta5 + xzalloc@Base 1.0~beta5 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..179c91b --- /dev/null +++ b/debian/rules @@ -0,0 +1,21 @@ +#!/usr/bin/make -f + +%: + dh ${@} + +override_dh_auto_configure: + dh_auto_configure -- -DWITH_FFMPEG=OFF + +override_dh_install: + # Removing unused files + rm -f debian/tmp/usr/lib/*.la + rm -f debian/tmp/usr/lib/freerdp/*.la + rm -rf debian/tmp/usr/share/freerdp/keymaps + + dh_install --fail-missing + +override_dh_strip: + dh_strip --dbg-package=freerdp-dbg + +override_dh_makeshlibs: + dh_makeshlibs -V -- -c4 diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..a0d23a4 --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=3 + +http://sf.net/freerdp/freerdp-(.+)\.tar\.gz diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 0000000..5660fa1 --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,1515 @@ +# Doxyfile 1.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = FreeRDP + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = \ + msdn{1}="http://msdn.microsoft.com/en-us/library/\1/" + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = YES + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= NO + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = YES + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = .. + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = ../build ../cmake ../CMakeFiles ../cunit ../docs ../keymaps ../resources + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = api + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.freerdp + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) +# there is already a search function so this one should typically +# be disabled. + +SEARCHENGINE = YES + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/docs/FreeRDP.vsd b/docs/FreeRDP.vsd new file mode 100644 index 0000000000000000000000000000000000000000..e2f8cfdebc199dbf211dfb40b39496cb48e87cf3 GIT binary patch literal 214528 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

T$q%zID9Oi%DcGT)5{PMOB#H#G(5gjnnHZq`uR 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 R8.tar.gz + +Summary: Remote Desktop Protocol functionality +Name: freerdp +Version: 1.0.0 +Release: 1%{?dist} +License: Apache License 2.0 +Group: Applications/Communications +URL: http://www.freerdp.com/ +Source: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: openssl-devel +BuildRequires: libX11-devel, libXcursor-devel, libXext-devel, libXinerama-devel, libXdamage-devel, libXv-devel, libxkbfile-devel +BuildRequires: cups-devel +BuildRequires: alsa-lib-devel +BuildRequires: pcsc-lite-devel + +%description +FreeRDP is a free implementation of the Remote Desktop Protocol (RDP) +according to the Microsoft Open Specifications. + +%package -n xfreerdp +Summary: Remote Desktop Protocol client +Group: Applications/Communications +Requires: %{name}-libs = %{version}-%{release}, %{name}-plugins-standard = %{version}-%{release} +%description -n xfreerdp +FreeRDP is a free implementation of the Remote Desktop Protocol (RDP) +according to the Microsoft Open Specifications. + +%package libs +Summary: Core libraries implementing the RDP protocol +Group: Applications/Communications +%description libs +libfreerdp-core can be embedded in applications. + +libfreerdp-channels and libfreerdp-kbd might be convenient to use in X +applications together with libfreerdp-core. + +libfreerdp-core can be extended with plugins handling RDP channels. + +%package plugins-standard +Summary: Plugins for handling the standard RDP channels +Group: Applications/Communications +Requires: %{name}-libs = %{version}-%{release} +%description plugins-standard +A set of plugins to the channel manager implementing the standard virtual +channels extending RDP core functionality. For instance, sounds, clipboard +sync, disk/printer redirection, etc. + +%package devel +Summary: Libraries and header files for embedding and extending freerdp +Group: Applications/Communications +Requires: %{name}-libs = %{version}-%{release} +Requires: pkgconfig +%description devel +Header files and unversioned libraries for libfreerdp-core, libfreerdp-channels, +libfreerdp-kbd, libfreerdp-cache, libfreerdp-codec, libfreerdp-rail, +libfreerdp-gdi and libfreerdp-utils. + +%prep +%setup -q + +%build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DWITH_PCSC=ON . + +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +rm -f $RPM_BUILD_ROOT%{_libdir}/{freerdp/,lib}*.{a,la} # FIXME: They shouldn't be installed in the first place + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + +%files -n xfreerdp +%defattr(-,root,root) +%{_bindir}/xfreerdp +%{_mandir}/*/* + +%files libs +%defattr(-,root,root) +%doc LICENSE README +%{_libdir}/lib*.so.* +%dir %{_libdir}/freerdp +%{_datadir}/freerdp/ + +%files plugins-standard +%defattr(-,root,root) +%{_libdir}/freerdp/*.so + +%files devel +%defattr(-,root,root) +%{_includedir}/freerdp/ +%{_libdir}/lib*.so +%{_libdir}/pkgconfig/* + +%changelog + +* Tue Mar 16 2010 Mads Kiilerich - 0.0.1-1 +- Initial "upstream" freerdp spec - made and tested for Fedora 12 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..b7ffe72 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,30 @@ +# FreeRDP: A Remote Desktop Protocol Client +# include headers cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +file(GLOB HEADERS "freerdp/*.h") +install_files(/include/freerdp FILES ${HEADERS}) + +install(DIRECTORY freerdp/utils DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/channels DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/cache DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/gdi DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/kbd DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/rail DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/codec DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") +install(DIRECTORY freerdp/plugins DESTINATION include/freerdp FILES_MATCHING PATTERN "*.h") diff --git a/include/freerdp/altsec.h b/include/freerdp/altsec.h new file mode 100644 index 0000000..08da675 --- /dev/null +++ b/include/freerdp/altsec.h @@ -0,0 +1,217 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Alternate Secondary Drawing Orders Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_ALTSEC_H +#define __UPDATE_ALTSEC_H + +#include + +#define DSDNG_STRETCH 0x00000001 +#define DSDNG_TILE 0x00000002 +#define DSDNG_PERPIXELALPHA 0x00000004 +#define DSDNG_TRANSPARENT 0x00000008 +#define DSDNG_MUSTFLIP 0x00000010 +#define DSDNG_TRUESIZE 0x00000020 + +#define FRAME_START 0x00000000 +#define FRAME_END 0x00000001 + +#define STREAM_BITMAP_END 0x01 +#define STREAM_BITMAP_COMPRESSED 0x02 +#define STREAM_BITMAP_V2 0x04 + +struct _OFFSCREEN_DELETE_LIST +{ + uint32 sIndices; + uint32 cIndices; + uint16* indices; +}; +typedef struct _OFFSCREEN_DELETE_LIST OFFSCREEN_DELETE_LIST; + +struct _CREATE_OFFSCREEN_BITMAP_ORDER +{ + uint32 id; + uint32 cx; + uint32 cy; + OFFSCREEN_DELETE_LIST deleteList; +}; +typedef struct _CREATE_OFFSCREEN_BITMAP_ORDER CREATE_OFFSCREEN_BITMAP_ORDER; + +struct _SWITCH_SURFACE_ORDER +{ + uint32 bitmapId; +}; +typedef struct _SWITCH_SURFACE_ORDER SWITCH_SURFACE_ORDER; + +struct _NINE_GRID_BITMAP_INFO +{ + uint32 flFlags; + uint32 ulLeftWidth; + uint32 ulRightWidth; + uint32 ulTopHeight; + uint32 ulBottomHeight; + uint32 crTransparent; +}; +typedef struct _NINE_GRID_BITMAP_INFO NINE_GRID_BITMAP_INFO; + +struct _CREATE_NINE_GRID_BITMAP_ORDER +{ + uint32 bitmapBpp; + uint32 bitmapId; + uint32 cx; + uint32 cy; + NINE_GRID_BITMAP_INFO nineGridInfo; +}; +typedef struct _CREATE_NINE_GRID_BITMAP_ORDER CREATE_NINE_GRID_BITMAP_ORDER; + +struct _FRAME_MARKER_ORDER +{ + uint32 action; +}; +typedef struct _FRAME_MARKER_ORDER FRAME_MARKER_ORDER; + +struct _STREAM_BITMAP_FIRST_ORDER +{ + uint32 bitmapFlags; + uint32 bitmapBpp; + uint32 bitmapType; + uint32 bitmapWidth; + uint32 bitmapHeight; + uint32 bitmapSize; + uint32 bitmapBlockSize; + uint8* bitmapBlock; +}; +typedef struct _STREAM_BITMAP_FIRST_ORDER STREAM_BITMAP_FIRST_ORDER; + +struct _STREAM_BITMAP_NEXT_ORDER +{ + uint32 bitmapFlags; + uint32 bitmapType; + uint32 bitmapBlockSize; + uint8* bitmapBlock; +}; +typedef struct _STREAM_BITMAP_NEXT_ORDER STREAM_BITMAP_NEXT_ORDER; + +struct _DRAW_GDIPLUS_FIRST_ORDER +{ + uint32 cbSize; + uint32 cbTotalSize; + uint32 cbTotalEmfSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_FIRST_ORDER DRAW_GDIPLUS_FIRST_ORDER; + +struct _DRAW_GDIPLUS_NEXT_ORDER +{ + uint32 cbSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_NEXT_ORDER DRAW_GDIPLUS_NEXT_ORDER; + +struct _DRAW_GDIPLUS_END_ORDER +{ + uint32 cbSize; + uint32 cbTotalSize; + uint32 cbTotalEmfSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_END_ORDER DRAW_GDIPLUS_END_ORDER; + +struct _DRAW_GDIPLUS_CACHE_FIRST_ORDER +{ + uint32 flags; + uint32 cacheType; + uint32 cacheIndex; + uint32 cbSize; + uint32 cbTotalSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_CACHE_FIRST_ORDER DRAW_GDIPLUS_CACHE_FIRST_ORDER; + +struct _DRAW_GDIPLUS_CACHE_NEXT_ORDER +{ + uint32 flags; + uint32 cacheType; + uint32 cacheIndex; + uint32 cbSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_CACHE_NEXT_ORDER DRAW_GDIPLUS_CACHE_NEXT_ORDER; + +struct _DRAW_GDIPLUS_CACHE_END_ORDER +{ + uint32 flags; + uint32 cacheType; + uint32 cacheIndex; + uint32 cbSize; + uint32 cbTotalSize; + uint8* emfRecords; +}; +typedef struct _DRAW_GDIPLUS_CACHE_END_ORDER DRAW_GDIPLUS_CACHE_END_ORDER; + +typedef void (*pCreateOffscreenBitmap)(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); +typedef void (*pSwitchSurface)(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface); +typedef void (*pCreateNineGridBitmap)(rdpContext* context, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); +typedef void (*pFrameMarker)(rdpContext* context, FRAME_MARKER_ORDER* frame_marker); +typedef void (*pStreamBitmapFirst)(rdpContext* context, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); +typedef void (*pStreamBitmapNext)(rdpContext* context, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next); +typedef void (*pDrawGdiPlusFirst)(rdpContext* context, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); +typedef void (*pDrawGdiPlusNext)(rdpContext* context, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); +typedef void (*pDrawGdiPlusEnd)(rdpContext* context, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); +typedef void (*pDrawGdiPlusCacheFirst)(rdpContext* context, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); +typedef void (*pDrawGdiPlusCacheNext)(rdpContext* context, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); +typedef void (*pDrawGdiPlusCacheEnd)(rdpContext* context, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); + +struct rdp_altsec_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pCreateOffscreenBitmap CreateOffscreenBitmap; /* 16 */ + pSwitchSurface SwitchSurface; /* 17 */ + pCreateNineGridBitmap CreateNineGridBitmap; /* 18 */ + pFrameMarker FrameMarker; /* 19 */ + pStreamBitmapFirst StreamBitmapFirst; /* 20 */ + pStreamBitmapNext StreamBitmapNext; /* 21 */ + pDrawGdiPlusFirst DrawGdiPlusFirst; /* 22 */ + pDrawGdiPlusNext DrawGdiPlusNext; /* 23 */ + pDrawGdiPlusEnd DrawGdiPlusEnd; /* 24 */ + pDrawGdiPlusCacheFirst DrawGdiPlusCacheFirst; /* 25 */ + pDrawGdiPlusCacheNext DrawGdiPlusCacheNext; /* 26 */ + pDrawGdiPlusCacheEnd DrawGdiPlusCacheEnd; /* 27 */ + uint32 paddingB[32 - 28]; /* 28 */ + + /* internal */ + + CREATE_OFFSCREEN_BITMAP_ORDER create_offscreen_bitmap; + SWITCH_SURFACE_ORDER switch_surface; + CREATE_NINE_GRID_BITMAP_ORDER create_nine_grid_bitmap; + FRAME_MARKER_ORDER frame_marker; + STREAM_BITMAP_FIRST_ORDER stream_bitmap_first; + STREAM_BITMAP_FIRST_ORDER stream_bitmap_next; + DRAW_GDIPLUS_CACHE_FIRST_ORDER draw_gdiplus_cache_first; + DRAW_GDIPLUS_CACHE_NEXT_ORDER draw_gdiplus_cache_next; + DRAW_GDIPLUS_CACHE_END_ORDER draw_gdiplus_cache_end; + DRAW_GDIPLUS_FIRST_ORDER draw_gdiplus_first; + DRAW_GDIPLUS_NEXT_ORDER draw_gdiplus_next; + DRAW_GDIPLUS_END_ORDER draw_gdiplus_end; +}; +typedef struct rdp_altsec_update rdpAltSecUpdate; + +#endif /* __UPDATE_ALTSEC_H */ diff --git a/include/freerdp/api.h b/include/freerdp/api.h new file mode 100644 index 0000000..1c2ba7a --- /dev/null +++ b/include/freerdp/api.h @@ -0,0 +1,62 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Interface + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_API_H +#define __FREERDP_API_H + +#define FREERDP_INTERFACE_VERSION 4 + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef FREERDP_EXPORTS + #ifdef __GNUC__ + #define FREERDP_API __attribute__((dllexport)) + #else + #define FREERDP_API __declspec(dllexport) + #endif + #else + #ifdef __GNUC__ + #define FREERDP_API __attribute__((dllimport)) + #else + #define FREERDP_API __declspec(dllimport) + #endif + #endif +#else + #if __GNUC__ >= 4 + #define FREERDP_API __attribute__ ((visibility("default"))) + #else + #define FREERDP_API + #endif +#endif + +#ifdef _WIN32 +#define FREERDP_CC __cdecl +#else +#define FREERDP_CC +#endif + +#ifdef _WIN32 +#define INLINE __inline +#else +#define INLINE inline +#endif + +#define IFCALL(_cb, ...) do { if (_cb != NULL) { _cb( __VA_ARGS__ ); } } while (0) +#define IFCALLRET(_cb, _ret, ...) do { if (_cb != NULL) { _ret = _cb( __VA_ARGS__ ); } } while (0) + +#endif diff --git a/include/freerdp/cache/bitmap.h b/include/freerdp/cache/bitmap.h new file mode 100644 index 0000000..5455b1f --- /dev/null +++ b/include/freerdp/cache/bitmap.h @@ -0,0 +1,70 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap Cache V2 + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BITMAP_V2_CACHE_H +#define __BITMAP_V2_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct _BITMAP_V2_CELL BITMAP_V2_CELL; +typedef struct rdp_bitmap_cache rdpBitmapCache; + +#include + +struct _BITMAP_V2_CELL +{ + uint32 number; + rdpBitmap** entries; +}; + +struct rdp_bitmap_cache +{ + pMemBlt MemBlt; /* 0 */ + pMem3Blt Mem3Blt; /* 1 */ + pCacheBitmap CacheBitmap; /* 2 */ + pCacheBitmapV2 CacheBitmapV2; /* 3 */ + pCacheBitmapV3 CacheBitmapV3; /* 4 */ + pBitmapUpdate BitmapUpdate; /* 5 */ + uint32 paddingA[16 - 6]; /* 6 */ + + uint32 maxCells; /* 16 */ + BITMAP_V2_CELL* cells; /* 17 */ + uint32 paddingB[32 - 18]; /* 18 */ + + /* internal */ + + rdpBitmap* bitmap; + rdpUpdate* update; + rdpContext* context; + rdpSettings* settings; +}; + +FREERDP_API rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint32 id, uint32 index); +FREERDP_API void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint32 id, uint32 index, rdpBitmap* bitmap); + +FREERDP_API void bitmap_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpBitmapCache* bitmap_cache_new(rdpSettings* settings); +FREERDP_API void bitmap_cache_free(rdpBitmapCache* bitmap_cache); + +#endif /* __BITMAP_V2_CACHE_H */ diff --git a/include/freerdp/cache/brush.h b/include/freerdp/cache/brush.h new file mode 100644 index 0000000..ad1d547 --- /dev/null +++ b/include/freerdp/cache/brush.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Brush Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BRUSH_CACHE_H +#define __BRUSH_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct _BRUSH_ENTRY BRUSH_ENTRY; +typedef struct rdp_brush_cache rdpBrushCache; + +#include + +struct _BRUSH_ENTRY +{ + uint32 bpp; + void* entry; +}; + +struct rdp_brush_cache +{ + pPatBlt PatBlt; /* 0 */ + pCacheBrush CacheBrush; /* 1 */ + uint32 paddingA[16 - 2]; /* 2 */ + + uint32 maxEntries; /* 16 */ + uint32 maxMonoEntries; /* 17 */ + BRUSH_ENTRY* entries; /* 18 */ + BRUSH_ENTRY* monoEntries; /* 19 */ + uint32 paddingB[32 - 20]; /* 20 */ + + /* internal */ + + rdpSettings* settings; +}; + +FREERDP_API void* brush_cache_get(rdpBrushCache* brush, uint32 index, uint32* bpp); +FREERDP_API void brush_cache_put(rdpBrushCache* brush, uint32 index, void* entry, uint32 bpp); + +FREERDP_API void brush_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpBrushCache* brush_cache_new(rdpSettings* settings); +FREERDP_API void brush_cache_free(rdpBrushCache* brush); + +#endif /* __BRUSH_CACHE_H */ diff --git a/include/freerdp/cache/cache.h b/include/freerdp/cache/cache.h new file mode 100644 index 0000000..aea19a1 --- /dev/null +++ b/include/freerdp/cache/cache.h @@ -0,0 +1,52 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Caches + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CACHE_H +#define __CACHE_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct rdp_cache +{ + rdpGlyphCache* glyph; /* 0 */ + rdpBrushCache* brush; /* 1 */ + rdpPointerCache* pointer; /* 2 */ + rdpBitmapCache* bitmap; /* 3 */ + rdpOffscreenCache* offscreen; /* 4 */ + rdpPaletteCache* palette; /* 5 */ + + /* internal */ + + rdpSettings* settings; +}; + +FREERDP_API rdpCache* cache_new(rdpSettings* settings); +FREERDP_API void cache_free(rdpCache* cache); + +#endif /* __CACHE_H */ diff --git a/include/freerdp/cache/glyph.h b/include/freerdp/cache/glyph.h new file mode 100644 index 0000000..7f0c106 --- /dev/null +++ b/include/freerdp/cache/glyph.h @@ -0,0 +1,73 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Glyph Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GLYPH_CACHE_H +#define __GLYPH_CACHE_H + +#include +#include +#include +#include + +typedef struct _GLYPH_CACHE GLYPH_CACHE; +typedef struct _FRAGMENT_CACHE_ENTRY FRAGMENT_CACHE_ENTRY; +typedef struct _FRAGMENT_CACHE FRAGMENT_CACHE; +typedef struct rdp_glyph_cache rdpGlyphCache; + +#include + +struct _GLYPH_CACHE +{ + uint32 number; + uint32 maxCellSize; + rdpGlyph** entries; +}; + +struct _FRAGMENT_CACHE_ENTRY +{ + void* fragment; + uint32 size; +}; + +struct _FRAGMENT_CACHE +{ + FRAGMENT_CACHE_ENTRY* entries; +}; + +struct rdp_glyph_cache +{ + FRAGMENT_CACHE fragCache; + GLYPH_CACHE glyphCache[10]; + + rdpContext* context; + rdpSettings* settings; +}; + +FREERDP_API rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, uint32 id, uint32 index); +FREERDP_API void glyph_cache_put(rdpGlyphCache* glyph_cache, uint32 id, uint32 index, rdpGlyph* entry); + +FREERDP_API void* glyph_cache_fragment_get(rdpGlyphCache* glyph, uint32 index, uint32* count); +FREERDP_API void glyph_cache_fragment_put(rdpGlyphCache* glyph, uint32 index, uint32 count, void* entry); + +FREERDP_API void glyph_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpGlyphCache* glyph_cache_new(rdpSettings* settings); +FREERDP_API void glyph_cache_free(rdpGlyphCache* glyph); + +#endif /* __GLYPH_CACHE_H */ diff --git a/include/freerdp/cache/offscreen.h b/include/freerdp/cache/offscreen.h new file mode 100644 index 0000000..286bcf1 --- /dev/null +++ b/include/freerdp/cache/offscreen.h @@ -0,0 +1,55 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Offscreen Bitmap Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OFFSCREEN_CACHE_H +#define __OFFSCREEN_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct rdp_offscreen_cache rdpOffscreenCache; + +#include + +struct rdp_offscreen_cache +{ + uint32 maxSize; /* 0 */ + uint32 maxEntries; /* 1 */ + rdpBitmap** entries; /* 2 */ + uint32 currentSurface; /* 3 */ + + /* internal */ + + rdpUpdate* update; + rdpSettings* settings; +}; + +FREERDP_API rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint32 index); +FREERDP_API void offscreen_cache_put(rdpOffscreenCache* offscreen_cache, uint32 index, rdpBitmap* bitmap); +FREERDP_API void offscreen_cache_delete(rdpOffscreenCache* offscreen, uint32 index); + +FREERDP_API void offscreen_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings); +FREERDP_API void offscreen_cache_free(rdpOffscreenCache* offscreen); + +#endif /* __OFFSCREEN_CACHE_H */ diff --git a/include/freerdp/cache/palette.h b/include/freerdp/cache/palette.h new file mode 100644 index 0000000..d30e9cf --- /dev/null +++ b/include/freerdp/cache/palette.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Palette (Color Table) Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PALETTE_CACHE_H +#define __PALETTE_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct _PALETTE_TABLE_ENTRY PALETTE_TABLE_ENTRY; +typedef struct rdp_palette_cache rdpPaletteCache; + +#include + +struct _PALETTE_TABLE_ENTRY +{ + void* entry; +}; + +struct rdp_palette_cache +{ + uint32 maxEntries; /* 0 */ + PALETTE_TABLE_ENTRY* entries; /* 1 */ + + /* internal */ + + rdpSettings* settings; +}; + +FREERDP_API void* palette_cache_get(rdpPaletteCache* palette, uint32 index); +FREERDP_API void palette_cache_put(rdpPaletteCache* palette, uint32 index, void* entry); + +FREERDP_API void palette_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpPaletteCache* palette_cache_new(rdpSettings* settings); +FREERDP_API void palette_cache_free(rdpPaletteCache* palette_cache); + +#endif /* __PALETTE_CACHE_H */ diff --git a/include/freerdp/cache/pointer.h b/include/freerdp/cache/pointer.h new file mode 100644 index 0000000..5351c9b --- /dev/null +++ b/include/freerdp/cache/pointer.h @@ -0,0 +1,53 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Pointer Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __POINTER_CACHE_H +#define __POINTER_CACHE_H + +#include +#include +#include +#include +#include +#include + +typedef struct rdp_pointer_cache rdpPointerCache; + +#include + +struct rdp_pointer_cache +{ + uint32 cacheSize; /* 0 */ + rdpPointer** entries; /* 1 */ + + /* internal */ + + rdpUpdate* update; + rdpSettings* settings; +}; + +FREERDP_API rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, uint32 index); +FREERDP_API void pointer_cache_put(rdpPointerCache* pointer_cache, uint32 index, rdpPointer* pointer); + +FREERDP_API void pointer_cache_register_callbacks(rdpUpdate* update); + +FREERDP_API rdpPointerCache* pointer_cache_new(rdpSettings* settings); +FREERDP_API void pointer_cache_free(rdpPointerCache* pointer_cache); + +#endif /* __POINTER_CACHE_H */ diff --git a/include/freerdp/channels/channels.h b/include/freerdp/channels/channels.h new file mode 100644 index 0000000..8bc3a39 --- /dev/null +++ b/include/freerdp/channels/channels.h @@ -0,0 +1,53 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Virtual Channel Manager + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_CHANNELS_H +#define __FREERDP_CHANNELS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +FREERDP_API int freerdp_channels_global_init(void); +FREERDP_API int freerdp_channels_global_uninit(void); +FREERDP_API rdpChannels* freerdp_channels_new(void); +FREERDP_API void freerdp_channels_free(rdpChannels* channels); +FREERDP_API int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, + const char* name, void* data); +FREERDP_API int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance); +FREERDP_API int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance); +FREERDP_API int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size, + int flags, int total_size); +FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, RDP_EVENT* event); +FREERDP_API boolean freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds, + int* read_count, void** write_fds, int* write_count); +FREERDP_API boolean freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance); +FREERDP_API RDP_EVENT* freerdp_channels_pop_event(rdpChannels* channels); +FREERDP_API void freerdp_channels_close(rdpChannels* channels, freerdp* instance); + +#ifdef __cplusplus +} +#endif + +#endif /* __FREERDP_CHANNELS_H */ diff --git a/include/freerdp/channels/wtsvc.h b/include/freerdp/channels/wtsvc.h new file mode 100644 index 0000000..3756507 --- /dev/null +++ b/include/freerdp/channels/wtsvc.h @@ -0,0 +1,128 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Server Virtual Channel Interface + * + * Copyright 2011-2012 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The server-side virtual channel API follows the Microsoft Remote Desktop + * Services API functions WTSVirtualChannel* defined in: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464.aspx + * + * Difference between the MS API are documented in this header. All functions + * are implemented in and integrated with libfreerdp-channels. + * + * Unlike MS API, all functions except WTSVirtualChannelOpenEx in this + * implementation are thread-safe. + */ + +#ifndef __FREERDP_WTSVC_H +#define __FREERDP_WTSVC_H + +#include +#include + +typedef struct WTSVirtualChannelManager WTSVirtualChannelManager; + +#define WTS_CHANNEL_OPTION_DYNAMIC 0x00000001 + +typedef enum _WTS_VIRTUAL_CLASS +{ + WTSVirtualClientData, + WTSVirtualFileHandle +} WTS_VIRTUAL_CLASS; + +/** + * WTSVirtualChannelManager functions are FreeRDP extensions to the API. + */ +FREERDP_API WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client); +FREERDP_API void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm); +FREERDP_API void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, + void** fds, int* fds_count); +FREERDP_API boolean WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm); + +/** + * Opens a static or dynamic virtual channel and return the handle. If the + * operation fails, a NULL handle is returned. + * + * The original MS API has 'DWORD SessionId' as the first argument, while we + * use our WTSVirtualChannelManager object instead. + * + * This functions should be called only from the main thread. + */ +FREERDP_API void* WTSVirtualChannelOpenEx( + /* __in */ WTSVirtualChannelManager* vcm, + /* __in */ const char* pVirtualName, + /* __in */ uint32 flags); + +/** + * Returns information about a specified virtual channel. + * + * Servers use this function to gain access to a virtual channel file handle + * that can be used for asynchronous I/O. + */ +FREERDP_API boolean WTSVirtualChannelQuery( + /* __in */ void* hChannelHandle, + /* __in */ WTS_VIRTUAL_CLASS WtsVirtualClass, + /* __out */ void** ppBuffer, + /* __out */ uint32* pBytesReturned); + +/** + * Frees memory allocated by WTSVirtualChannelQuery + */ +FREERDP_API void WTSFreeMemory( + /* __in */ void* pMemory); + +/** + * Reads data from the server end of a virtual channel. + * + * FreeRDP behavior: + * + * This function will always return a complete channel data packet, i.e. chunks + * are already assembled. If BufferSize argument is smaller than the packet + * size, it will set the desired size in pBytesRead and return false. The + * caller should allocate a large enough buffer and call this function again. + * Returning false with pBytesRead set to zero indicates an error has occurred. + * If no pending packet to be read, it will set pBytesRead to zero and return + * true. + * + * TimeOut is not supported, and this function will always return immediately. + * The caller should use the file handle returned by WTSVirtualChannelQuery to + * determine whether a packet has arrived. + */ +FREERDP_API boolean WTSVirtualChannelRead( + /* __in */ void* hChannelHandle, + /* __in */ uint32 TimeOut, + /* __out */ uint8* Buffer, + /* __in */ uint32 BufferSize, + /* __out */ uint32* pBytesRead); + +/** + * Writes data to the server end of a virtual channel. + */ +FREERDP_API boolean WTSVirtualChannelWrite( + /* __in */ void* hChannelHandle, + /* __in */ uint8* Buffer, + /* __in */ uint32 Length, + /* __out */ uint32* pBytesWritten); + +/** + * Closes an open virtual channel handle. + */ +FREERDP_API boolean WTSVirtualChannelClose( + /* __in */ void* hChannelHandle); + +#endif /* __FREERDP_WTSVC_H */ diff --git a/include/freerdp/codec/bitmap.h b/include/freerdp/codec/bitmap.h new file mode 100644 index 0000000..b440eaf --- /dev/null +++ b/include/freerdp/codec/bitmap.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Compressed Bitmap + * + * Copyright 2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BITMAP_H +#define __BITMAP_H + +#include + +FREERDP_API boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, int size, int srcBpp, int dstBpp); + +#endif /* __BITMAP_H */ diff --git a/include/freerdp/codec/color.h b/include/freerdp/codec/color.h new file mode 100644 index 0000000..14f3058 --- /dev/null +++ b/include/freerdp/codec/color.h @@ -0,0 +1,264 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Color Conversion Routines + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __COLOR_H +#define __COLOR_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Color Space Conversions: http://msdn.microsoft.com/en-us/library/ff566496/ */ + +/* Color Space Conversion */ + +#define RGB_555_565(_r, _g, _b) \ + _r = _r; \ + _g = (_g << 1 & ~0x1) | (_g >> 4); \ + _b = _b; + +#define RGB_565_555(_r, _g, _b) \ + _r = _r; \ + _g = (_g >> 1); \ + _b = _b; + +#define RGB_555_888(_r, _g, _b) \ + _r = (_r << 3 & ~0x7) | (_r >> 2); \ + _g = (_g << 3 & ~0x7) | (_g >> 2); \ + _b = (_b << 3 & ~0x7) | (_b >> 2); + +#define RGB_565_888(_r, _g, _b) \ + _r = (_r << 3 & ~0x7) | (_r >> 2); \ + _g = (_g << 2 & ~0x3) | (_g >> 4); \ + _b = (_b << 3 & ~0x7) | (_b >> 2); + +#define RGB_888_565(_r, _g, _b) \ + _r = (_r >> 3); \ + _g = (_g >> 2); \ + _b = (_b >> 3); + +#define RGB_888_555(_r, _g, _b) \ + _r = (_r >> 3); \ + _g = (_g >> 3); \ + _b = (_b >> 3); + +/* RGB 15 (RGB_555) */ + +#define RGB555(_r, _g, _b) \ + ((_r & 0x1F) << 10) | ((_g & 0x1F) << 5) | (_b & 0x1F) + +#define RGB15(_r, _g, _b) \ + (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_b >> 3) & 0x1F) + +#define GetRGB_555(_r, _g, _b, _p) \ + _r = (_p & 0x7C00) >> 10; \ + _g = (_p & 0x3E0) >> 5; \ + _b = (_p & 0x1F); + +#define GetRGB15(_r, _g, _b, _p) \ + GetRGB_555(_r, _g, _b, _p); \ + RGB_555_888(_r, _g, _b); + +/* BGR 15 (BGR_555) */ + +#define BGR555(_r, _g, _b) \ + ((_b & 0x1F) << 10) | ((_g & 0x1F) << 5) | (_r & 0x1F) + +#define BGR15(_r, _g, _b) \ + (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_r >> 3) & 0x1F) + +#define GetBGR_555(_r, _g, _b, _p) \ + _b = (_p & 0x7C00) >> 10; \ + _g = (_p & 0x3E0) >> 5; \ + _r = (_p & 0x1F); + +#define GetBGR15(_r, _g, _b, _p) \ + GetBGR_555(_r, _g, _b, _p); \ + RGB_555_888(_r, _g, _b); + +/* RGB 16 (RGB_565) */ + +#define RGB565(_r, _g, _b) \ + ((_r & 0x1F) << 11) | ((_g & 0x3F) << 5) | (_b & 0x1F) + +#define RGB16(_r, _g, _b) \ + (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((_b >> 3) & 0x1F) + +#define GetRGB_565(_r, _g, _b, _p) \ + _r = (_p & 0xF800) >> 11; \ + _g = (_p & 0x7E0) >> 5; \ + _b = (_p & 0x1F); + +#define GetRGB16(_r, _g, _b, _p) \ + GetRGB_565(_r, _g, _b, _p); \ + RGB_565_888(_r, _g, _b); + +/* BGR 16 (BGR_565) */ + +#define BGR565(_r, _g, _b) \ + ((_b & 0x1F) << 11) | ((_g & 0x3F) << 5) | (_r & 0x1F) + +#define BGR16(_r, _g, _b) \ + (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((_r >> 3) & 0x1F) + +#define GetBGR_565(_r, _g, _b, _p) \ + _b = (_p & 0xF800) >> 11; \ + _g = (_p & 0x7E0) >> 5; \ + _r = (_p & 0x1F); + +#define GetBGR16(_r, _g, _b, _p) \ + GetBGR_565(_r, _g, _b, _p); \ + RGB_565_888(_r, _g, _b); + +/* RGB 24 (RGB_888) */ + +#define RGB24(_r, _g, _b) \ + (_r << 16) | (_g << 8) | _b + +#define GetRGB24(_r, _g, _b, _p) \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); + +/* BGR 24 (BGR_888) */ + +#define BGR24(_r, _g, _b) \ + (_b << 16) | (_g << 8) | _r + +#define GetBGR24(_r, _g, _b, _p) \ + _b = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _r = (_p & 0xFF); + +/* RGB 32 (ARGB_8888), alpha ignored */ + +#define RGB32(_r, _g, _b) \ + (_r << 16) | (_g << 8) | _b + +#define GetRGB32(_r, _g, _b, _p) \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); + +/* ARGB 32 (ARGB_8888) */ + +#define ARGB32(_a,_r, _g, _b) \ + (_a << 24) | (_r << 16) | (_g << 8) | _b + +#define GetARGB32(_a, _r, _g, _b, _p) \ + _a = (_p & 0xFF000000) >> 24; \ + _r = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _b = (_p & 0xFF); + +/* BGR 32 (ABGR_8888), alpha ignored */ + +#define BGR32(_r, _g, _b) \ + (_b << 16) | (_g << 8) | _r + +#define GetBGR32(_r, _g, _b, _p) \ + _b = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _r = (_p & 0xFF); + +/* BGR 32 (ABGR_8888) */ + +#define ABGR32(_a, _r, _g, _b) \ + (_a << 24) | (_b << 16) | (_g << 8) | _r + +#define GetABGR32(_a, _r, _g, _b, _p) \ + _a = (_p & 0xFF000000) >> 24; \ + _b = (_p & 0xFF0000) >> 16; \ + _g = (_p & 0xFF00) >> 8; \ + _r = (_p & 0xFF); + +/* Color Conversion */ + +#define BGR16_RGB32(_r, _g, _b, _p) \ + GetBGR16(_r, _g, _b, _p); \ + RGB_565_888(_r, _g, _b); \ + _p = RGB32(_r, _g, _b); + +#define RGB32_RGB16(_r, _g, _b, _p) \ + GetRGB32(_r, _g, _b, _p); \ + RGB_888_565(_r, _g, _b); \ + _p = RGB565(_r, _g, _b); + +#define RGB15_RGB16(_r, _g, _b, _p) \ + GetRGB_555(_r, _g, _b, _p); \ + _g = (_g << 1 & ~0x1) | (_g >> 4); \ + _p = RGB565(_r, _g, _b); + +#define RGB16_RGB15(_r, _g, _b, _p) \ + GetRGB_565(_r, _g, _b, _p); \ + _g = (_g >> 1); \ + _p = RGB555(_r, _g, _b); + +#define CLRCONV_ALPHA 1 +#define CLRCONV_INVERT 2 +/* if defined RGB555 format is used when rendering with a 16-bit frame buffer */ +#define CLRCONV_RGB555 4 + +/* Supported Internal Buffer Formats */ +#define CLRBUF_16BPP 8 +#define CLRBUF_24BPP 16 +#define CLRBUF_32BPP 32 + +struct _CLRCONV +{ + int alpha; + int invert; + int rgb555; + rdpPalette* palette; +}; +typedef struct _CLRCONV CLRCONV; +typedef CLRCONV* HCLRCONV; + +#define IBPP(_bpp) (((_bpp + 1)/ 8) % 5) + +typedef uint8* (*p_freerdp_image_convert)(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv); + +FREERDP_API uint8* freerdp_image_convert(uint8* srcData, uint8 *dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint8* freerdp_glyph_convert(int width, int height, uint8* data); +FREERDP_API void freerdp_bitmap_flip(uint8 * src, uint8 * dst, int scanLineSz, int height); +FREERDP_API uint8* freerdp_image_flip(uint8* srcData, uint8* dstData, int width, int height, int bpp); +FREERDP_API uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv); +FREERDP_API uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv); +FREERDP_API void freerdp_alpha_cursor_convert(uint8* alphaData, uint8* xorMask, uint8* andMask, int width, int height, int bpp, HCLRCONV clrconv); +FREERDP_API void freerdp_image_swap_color_order(uint8* data, int width, int height); + +FREERDP_API uint32 freerdp_color_convert_var(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_rgb_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_bgr_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_var_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); +FREERDP_API uint32 freerdp_color_convert_var_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv); + +FREERDP_API HCLRCONV freerdp_clrconv_new(uint32 flags); +FREERDP_API void freerdp_clrconv_free(HCLRCONV clrconv); + +#ifdef __cplusplus +} +#endif + +#endif /* __COLOR_H */ diff --git a/include/freerdp/codec/nsc.h b/include/freerdp/codec/nsc.h new file mode 100644 index 0000000..73e448a --- /dev/null +++ b/include/freerdp/codec/nsc.h @@ -0,0 +1,73 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * NSCodec Codec + * + * Copyright 2011 Samsung, Author Jiten Pathy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NSC_H +#define __NSC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BYTESUM(_bs) (_bs[0] + _bs[1] + _bs[2] + _bs[3]) +#define ROUND_UP_TO(_b, _n) (_b + ((~(_b & (_n-1)) + 0x1) & (_n-1))); + +/* NSCODEC_BITMAP_STREAM */ +struct _NSC_STREAM +{ + uint32 PlaneByteCount[4]; + uint8 colorLossLevel; + uint8 ChromaSubSamplingLevel; + uint16 Reserved; + STREAM* pdata; +}; +typedef struct _NSC_STREAM NSC_STREAM; + +struct _NSC_CONTEXT +{ + uint32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */ + NSC_STREAM* nsc_stream; + uint16 width; + uint16 height; + uint8* bmpdata; /* final argb values in little endian order */ + STREAM* org_buf[4]; /* Decompressed Plane Buffers in the respective order */ +}; +typedef struct _NSC_CONTEXT NSC_CONTEXT; + +FREERDP_API NSC_CONTEXT* nsc_context_new(void); +FREERDP_API void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length); +FREERDP_API void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s); +FREERDP_API void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s); +FREERDP_API void nsc_rle_decompress_data(NSC_CONTEXT* context); +FREERDP_API void nsc_ycocg_rgb_convert(NSC_CONTEXT* context); +FREERDP_API void nsc_rle_decode(STREAM* in, STREAM* out, uint32 origsz); +FREERDP_API void nsc_chroma_supersample(NSC_CONTEXT* context); +FREERDP_API void nsc_cl_expand(STREAM* stream, uint8 shiftcount, uint32 origsz); +FREERDP_API void nsc_colorloss_recover(NSC_CONTEXT* context); +FREERDP_API void nsc_ycocg_rgb(NSC_CONTEXT* context); +FREERDP_API void nsc_context_destroy(NSC_CONTEXT* context); + +#ifdef __cplusplus +} +#endif + +#endif /* __NSC_H */ diff --git a/include/freerdp/codec/rfx.h b/include/freerdp/codec/rfx.h new file mode 100644 index 0000000..2d6a0fe --- /dev/null +++ b/include/freerdp/codec/rfx.h @@ -0,0 +1,149 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_H +#define __RFX_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum _RLGR_MODE +{ + RLGR1, + RLGR3 +}; +typedef enum _RLGR_MODE RLGR_MODE; + +enum _RFX_PIXEL_FORMAT +{ + RFX_PIXEL_FORMAT_BGRA, + RFX_PIXEL_FORMAT_RGBA, + RFX_PIXEL_FORMAT_BGR, + RFX_PIXEL_FORMAT_RGB, + RFX_PIXEL_FORMAT_BGR565_LE, + RFX_PIXEL_FORMAT_RGB565_LE, + RFX_PIXEL_FORMAT_PALETTE4_PLANER, + RFX_PIXEL_FORMAT_PALETTE8 +}; +typedef enum _RFX_PIXEL_FORMAT RFX_PIXEL_FORMAT; + +struct _RFX_RECT +{ + uint16 x; + uint16 y; + uint16 width; + uint16 height; +}; +typedef struct _RFX_RECT RFX_RECT; + +struct _RFX_TILE +{ + uint16 x; + uint16 y; + uint8* data; +}; +typedef struct _RFX_TILE RFX_TILE; + +struct _RFX_MESSAGE +{ + /** + * The rects array represents the updated region of the frame. The UI + * requires to clip drawing destination base on the union of the rects. + */ + uint16 num_rects; + RFX_RECT* rects; + + /** + * The tiles array represents the actual frame data. Each tile is always + * 64x64. Note that only pixels inside the updated region (represented as + * rects described above) are valid. Pixels outside of the region may + * contain arbitrary data. + */ + uint16 num_tiles; + RFX_TILE** tiles; +}; +typedef struct _RFX_MESSAGE RFX_MESSAGE; + +typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV; + +struct _RFX_CONTEXT +{ + uint16 flags; + uint16 properties; + uint16 width; + uint16 height; + RLGR_MODE mode; + uint32 version; + uint32 codec_id; + uint32 codec_version; + RFX_PIXEL_FORMAT pixel_format; + uint8 bits_per_pixel; + + /* color palette allocated by the application */ + const uint8* palette; + + /* temporary data within a frame */ + uint32 frame_idx; + boolean header_processed; + uint8 num_quants; + uint32* quants; + uint8 quant_idx_y; + uint8 quant_idx_cb; + uint8 quant_idx_cr; + + /* routines */ + void (*decode_ycbcr_to_rgb)(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf); + void (*encode_rgb_to_ycbcr)(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf); + void (*quantization_decode)(sint16* buffer, const uint32* quantization_values); + void (*quantization_encode)(sint16* buffer, const uint32* quantization_values); + void (*dwt_2d_decode)(sint16* buffer, sint16* dwt_buffer); + void (*dwt_2d_encode)(sint16* buffer, sint16* dwt_buffer); + + /* private definitions */ + RFX_CONTEXT_PRIV* priv; +}; +typedef struct _RFX_CONTEXT RFX_CONTEXT; + +FREERDP_API RFX_CONTEXT* rfx_context_new(void); +FREERDP_API void rfx_context_free(RFX_CONTEXT* context); +FREERDP_API void rfx_context_set_cpu_opt(RFX_CONTEXT* context, uint32 cpu_opt); +FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RFX_PIXEL_FORMAT pixel_format); +FREERDP_API void rfx_context_reset(RFX_CONTEXT* context); + +FREERDP_API RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length); +FREERDP_API uint16 rfx_message_get_tile_count(RFX_MESSAGE* message); +FREERDP_API RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index); +FREERDP_API uint16 rfx_message_get_rect_count(RFX_MESSAGE* message); +FREERDP_API RFX_RECT* rfx_message_get_rect(RFX_MESSAGE* message, int index); +FREERDP_API void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message); + +FREERDP_API void rfx_compose_message_header(RFX_CONTEXT* context, STREAM* s); +FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, STREAM* s, + const RFX_RECT* rects, int num_rects, uint8* image_data, int width, int height, int rowstride); + +#ifdef __cplusplus +} +#endif + +#endif /* __RFX_H */ diff --git a/include/freerdp/constants.h b/include/freerdp/constants.h new file mode 100644 index 0000000..6f48171 --- /dev/null +++ b/include/freerdp/constants.h @@ -0,0 +1,113 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Constants + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_CONSTANTS +#define __FREERDP_CONSTANTS + +/** + * Codec IDs + */ +enum RDP_CODEC_ID +{ + CODEC_ID_NONE = 0x00, + CODEC_ID_NSCODEC = 0x01, + CODEC_ID_REMOTEFX = 0x03 +}; + +/** + * Static Virtual Channel Flags + */ +enum RDP_SVC_CHANNEL_FLAG +{ + CHANNEL_FLAG_MIDDLE = 0, + CHANNEL_FLAG_FIRST = 0x01, + CHANNEL_FLAG_LAST = 0x02, + CHANNEL_FLAG_ONLY = (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST), + CHANNEL_FLAG_SHOW_PROTOCOL = 0x10, + CHANNEL_FLAG_SUSPEND = 0x20, + CHANNEL_FLAG_RESUME = 0x40, + CHANNEL_FLAG_FAIL = 0x100 +}; + +/** + * Static Virtual Channel Options + */ +enum RDP_SVC_CHANNEL_OPTION +{ + CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000, + CHANNEL_OPTION_COMPRESS = 0x00400000, + CHANNEL_OPTION_COMPRESS_RDP = 0x00800000, + CHANNEL_OPTION_PRI_LOW = 0x02000000, + CHANNEL_OPTION_PRI_MED = 0x04000000, + CHANNEL_OPTION_PRI_HIGH = 0x08000000, + CHANNEL_OPTION_ENCRYPT_CS = 0x10000000, + CHANNEL_OPTION_ENCRYPT_SC = 0x20000000, + CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000, + CHANNEL_OPTION_INITIALIZED = 0x80000000 +}; + +/** + * Static Virtual Channel Events + */ +enum RDP_SVC_CHANNEL_EVENT +{ + CHANNEL_EVENT_INITIALIZED = 0, + CHANNEL_EVENT_CONNECTED = 1, + CHANNEL_EVENT_V1_CONNECTED = 2, + CHANNEL_EVENT_DISCONNECTED = 3, + CHANNEL_EVENT_TERMINATED = 4, + CHANNEL_EVENT_DATA_RECEIVED = 10, + CHANNEL_EVENT_WRITE_COMPLETE = 11, + CHANNEL_EVENT_WRITE_CANCELLED = 12, + CHANNEL_EVENT_USER = 1000 +}; + +/** + * Virtual Channel Constants + */ +#define CHANNEL_CHUNK_LENGTH 1600 + +/** + * CPU Optimization flags + */ +#define CPU_SSE2 0x1 + +/** + * OSMajorType + */ +#define OSMAJORTYPE_UNSPECIFIED 0x0000 +#define OSMAJORTYPE_WINDOWS 0x0001 +#define OSMAJORTYPE_OS2 0x0002 +#define OSMAJORTYPE_MACINTOSH 0x0003 +#define OSMAJORTYPE_UNIX 0x0004 + +/** + * OSMinorType + */ +#define OSMINORTYPE_UNSPECIFIED 0x0000 +#define OSMINORTYPE_WINDOWS_31X 0x0001 +#define OSMINORTYPE_WINDOWS_95 0x0002 +#define OSMINORTYPE_WINDOWS_NT 0x0003 +#define OSMINORTYPE_OS2_V21 0x0004 +#define OSMINORTYPE_POWER_PC 0x0005 +#define OSMINORTYPE_MACINTOSH 0x0006 +#define OSMINORTYPE_NATIVE_XSERVER 0x0007 +#define OSMINORTYPE_PSEUDO_XSERVER 0x0008 + +#endif diff --git a/include/freerdp/dvc.h b/include/freerdp/dvc.h new file mode 100644 index 0000000..dfa487c --- /dev/null +++ b/include/freerdp/dvc.h @@ -0,0 +1,149 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Dynamic Virtual Channel Interface + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * DVC Plugin API: See the original MS DVC Client API: + * http://msdn.microsoft.com/en-us/library/bb540880%28v=VS.85%29.aspx + * + * The FreeRDP DVC Plugin API is a simulation of the MS DVC Client API in C. + * The main difference is that every interface method must take an instance + * pointer as the first parameter. + */ + +/** + * Implemented by DRDYNVC: + * o IWTSVirtualChannelManager + * o IWTSListener + * o IWTSVirtualChannel + * + * Implemented by DVC plugin: + * o IWTSPlugin + * o IWTSListenerCallback + * o IWTSVirtualChannelCallback + * + * A basic DVC plugin implementation: + * 1. DVCPluginEntry: + * The plugin entry point, which creates and initializes a new IWTSPlugin + * instance + * 2. IWTSPlugin.Initialize: + * Call IWTSVirtualChannelManager.CreateListener with a newly created + * IWTSListenerCallback instance + * 3. IWTSListenerCallback.OnNewChannelConnection: + * Create IWTSVirtualChannelCallback instance if the new channel is accepted + */ + +#ifndef __FREERDP_DVC_H +#define __FREERDP_DVC_H + +#include + +typedef struct _IWTSVirtualChannelManager IWTSVirtualChannelManager; +typedef struct _IWTSListener IWTSListener; +typedef struct _IWTSVirtualChannel IWTSVirtualChannel; + +typedef struct _IWTSPlugin IWTSPlugin; +typedef struct _IWTSListenerCallback IWTSListenerCallback; +typedef struct _IWTSVirtualChannelCallback IWTSVirtualChannelCallback; + +struct _IWTSListener +{ + /* Retrieves the listener-specific configuration. */ + int (*GetConfiguration) (IWTSListener* pListener, + void** ppPropertyBag); +}; + +struct _IWTSVirtualChannel +{ + /* Starts a write request on the channel. */ + int (*Write) (IWTSVirtualChannel* pChannel, + uint32 cbSize, + uint8* pBuffer, + void* pReserved); + /* Closes the channel. */ + int (*Close) (IWTSVirtualChannel* pChannel); +}; + +struct _IWTSVirtualChannelManager +{ + /* Returns an instance of a listener object that listens on a specific + endpoint, or creates a static channel. */ + int (*CreateListener) (IWTSVirtualChannelManager* pChannelMgr, + const char* pszChannelName, + uint32 ulFlags, + IWTSListenerCallback* pListenerCallback, + IWTSListener** ppListener); + /* Push a virtual channel event. + This is a FreeRDP extension to standard MS API. */ + int (*PushEvent) (IWTSVirtualChannelManager* pChannelMgr, + RDP_EVENT* pEvent); +}; + +struct _IWTSPlugin +{ + /* Used for the first call that is made from the client to the plug-in. */ + int (*Initialize) (IWTSPlugin* pPlugin, + IWTSVirtualChannelManager* pChannelMgr); + /* Notifies the plug-in that the Remote Desktop Connection (RDC) client + has successfully connected to the Remote Desktop Session Host (RD + Session Host) server. */ + int (*Connected) (IWTSPlugin* pPlugin); + /* Notifies the plug-in that the Remote Desktop Connection (RDC) client + has disconnected from the RD Session Host server. */ + int (*Disconnected) (IWTSPlugin* pPlugin, + uint32 dwDisconnectCode); + /* Notifies the plug-in that the Remote Desktop Connection (RDC) client + has terminated. */ + int (*Terminated) (IWTSPlugin* pPlugin); +}; + +struct _IWTSListenerCallback +{ + /* Accepts or denies a connection request for an incoming connection to + the associated listener. */ + int (*OnNewChannelConnection) (IWTSListenerCallback* pListenerCallback, + IWTSVirtualChannel* pChannel, + uint8* Data, + int* pbAccept, + IWTSVirtualChannelCallback** ppCallback); +}; + +struct _IWTSVirtualChannelCallback +{ + /* Notifies the user about data that is being received. */ + int (*OnDataReceived) (IWTSVirtualChannelCallback* pChannelCallback, + uint32 cbSize, + uint8* pBuffer); + /* Notifies the user that the channel has been closed. */ + int (*OnClose) (IWTSVirtualChannelCallback* pChannelCallback); +}; + +/* The DVC Plugin entry points */ +typedef struct _IDRDYNVC_ENTRY_POINTS IDRDYNVC_ENTRY_POINTS; +struct _IDRDYNVC_ENTRY_POINTS +{ + int (*RegisterPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints, + const char* name, IWTSPlugin* pPlugin); + IWTSPlugin* (*GetPlugin) (IDRDYNVC_ENTRY_POINTS* pEntryPoints, + const char* name); + RDP_PLUGIN_DATA* (*GetPluginData) (IDRDYNVC_ENTRY_POINTS* pEntryPoints); +}; + +typedef int (*PDVC_PLUGIN_ENTRY) (IDRDYNVC_ENTRY_POINTS*); + +#endif diff --git a/include/freerdp/extension.h b/include/freerdp/extension.h new file mode 100644 index 0000000..17c8456 --- /dev/null +++ b/include/freerdp/extension.h @@ -0,0 +1,59 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Extensions + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDP_EXTENSION_H +#define __RDP_EXTENSION_H + +#include +#include +#include + +#define FREERDP_EXT_EXPORT_FUNC_NAME "FreeRDPExtensionEntry" + +typedef struct rdp_ext_plugin rdpExtPlugin; + +struct rdp_ext_plugin +{ + void* ext; + int (*init) (rdpExtPlugin* plugin, freerdp* instance); + int (*uninit) (rdpExtPlugin* plugin, freerdp* instance); +}; + +typedef uint32 (FREERDP_CC* PFREERDP_EXTENSION_HOOK)(rdpExtPlugin* plugin, freerdp* instance); + +typedef uint32 (FREERDP_CC* PREGISTEREXTENSION)(rdpExtPlugin* plugin); +typedef uint32 (FREERDP_CC* PREGISTERPRECONNECTHOOK)(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook); +typedef uint32 (FREERDP_CC* PREGISTERPOSTCONNECTHOOK)(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook); + +struct _FREERDP_EXTENSION_ENTRY_POINTS +{ + void* ext; /* Reference to internal instance */ + PREGISTEREXTENSION pRegisterExtension; + PREGISTERPRECONNECTHOOK pRegisterPreConnectHook; + PREGISTERPOSTCONNECTHOOK pRegisterPostConnectHook; + void* data; +}; + +typedef struct _FREERDP_EXTENSION_ENTRY_POINTS FREERDP_EXTENSION_ENTRY_POINTS; +typedef FREERDP_EXTENSION_ENTRY_POINTS* PFREERDP_EXTENSION_ENTRY_POINTS; + +typedef int (FREERDP_CC* PFREERDP_EXTENSION_ENTRY)(PFREERDP_EXTENSION_ENTRY_POINTS pEntryPoints); + +#endif /* __RDP_EXTENSION_H */ + diff --git a/include/freerdp/freerdp.h b/include/freerdp/freerdp.h new file mode 100644 index 0000000..dd993c4 --- /dev/null +++ b/include/freerdp/freerdp.h @@ -0,0 +1,124 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Interface + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_H +#define __FREERDP_H + +typedef struct rdp_rdp rdpRdp; +typedef struct rdp_gdi rdpGdi; +typedef struct rdp_rail rdpRail; +typedef struct rdp_cache rdpCache; +typedef struct rdp_channels rdpChannels; +typedef struct rdp_graphics rdpGraphics; + +typedef struct rdp_freerdp freerdp; +typedef struct rdp_context rdpContext; +typedef struct rdp_freerdp_peer freerdp_peer; + +#include +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*pContextNew)(freerdp* instance, rdpContext* context); +typedef void (*pContextFree)(freerdp* instance, rdpContext* context); + +typedef boolean (*pPreConnect)(freerdp* instance); +typedef boolean (*pPostConnect)(freerdp* instance); +typedef boolean (*pAuthenticate)(freerdp* instance, char** username, char** password, char** domain); +typedef boolean (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint); + +typedef int (*pSendChannelData)(freerdp* instance, int channelId, uint8* data, int size); +typedef int (*pReceiveChannelData)(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size); + +struct rdp_context +{ + freerdp* instance; /* 0 */ + freerdp_peer* peer; /* 1 */ + uint32 paddingA[16 - 2]; /* 2 */ + + int argc; /* 16 */ + char** argv; /* 17 */ + uint32 paddingB[32 - 18]; /* 18 */ + + rdpRdp* rdp; /* 32 */ + rdpGdi* gdi; /* 33 */ + rdpRail* rail; /* 34 */ + rdpCache* cache; /* 35 */ + rdpChannels* channels; /* 36 */ + rdpGraphics* graphics; /* 37 */ + uint32 paddingC[64 - 38]; /* 38 */ +}; + +struct rdp_freerdp +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + rdpInput* input; /* 16 */ + rdpUpdate* update; /* 17 */ + rdpSettings* settings; /* 18 */ + uint32 paddingB[32 - 19]; /* 19 */ + + size_t context_size; /* 32 */ + pContextNew ContextNew; /* 33 */ + pContextFree ContextFree; /* 34 */ + uint32 paddingC[48 - 35]; /* 35 */ + + pPreConnect PreConnect; /* 48 */ + pPostConnect PostConnect; /* 49 */ + pAuthenticate Authenticate; /* 50 */ + pVerifyCertificate VerifyCertificate; /* 51 */ + uint32 paddingD[64 - 52]; /* 52 */ + + pSendChannelData SendChannelData; /* 64 */ + pReceiveChannelData ReceiveChannelData; /* 65 */ + uint32 paddingE[80 - 66]; /* 66 */ +}; + +FREERDP_API void freerdp_context_new(freerdp* instance); +FREERDP_API void freerdp_context_free(freerdp* instance); + +FREERDP_API boolean freerdp_connect(freerdp* instance); +FREERDP_API boolean freerdp_shall_disconnect(freerdp* instance); +FREERDP_API boolean freerdp_disconnect(freerdp* instance); + +FREERDP_API boolean freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount); +FREERDP_API boolean freerdp_check_fds(freerdp* instance); + +FREERDP_API void freerdp_send_keep_alive(freerdp* instance); +FREERDP_API uint32 freerdp_error_info(freerdp* instance); + +FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision); + +FREERDP_API freerdp* freerdp_new(); +FREERDP_API void freerdp_free(freerdp* instance); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/freerdp/gdi/16bpp.h b/include/freerdp/gdi/16bpp.h new file mode 100644 index 0000000..5e0b767 --- /dev/null +++ b/include/freerdp/gdi/16bpp.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 16bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +typedef int (*pLineTo_16bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); + +FREERDP_API uint16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color); + +FREERDP_API int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); +FREERDP_API int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); +FREERDP_API int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); +FREERDP_API int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd); diff --git a/include/freerdp/gdi/32bpp.h b/include/freerdp/gdi/32bpp.h new file mode 100644 index 0000000..a843b61 --- /dev/null +++ b/include/freerdp/gdi/32bpp.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 32bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +typedef int (*pLineTo_32bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); + +FREERDP_API uint32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color); + +FREERDP_API int FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); +FREERDP_API int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); +FREERDP_API int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); +FREERDP_API int LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd); diff --git a/include/freerdp/gdi/8bpp.h b/include/freerdp/gdi/8bpp.h new file mode 100644 index 0000000..cd944dc --- /dev/null +++ b/include/freerdp/gdi/8bpp.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 8bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +typedef int (*pLineTo_8bpp)(HGDI_DC hdc, int nXEnd, int nYEnd); + +FREERDP_API uint8 gdi_get_color_8bpp(HGDI_DC hdc, GDI_COLOR color); + +FREERDP_API int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); +FREERDP_API int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); +FREERDP_API int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); +FREERDP_API int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd); diff --git a/include/freerdp/gdi/bitmap.h b/include/freerdp/gdi/bitmap.h new file mode 100644 index 0000000..75a9dee --- /dev/null +++ b/include/freerdp/gdi/bitmap.h @@ -0,0 +1,43 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Bitmap Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_BITMAP_H +#define __GDI_BITMAP_H + +#include +#include + +FREERDP_API GDI_COLOR gdi_GetPixel(HGDI_DC hdc, int nXPos, int nYPos); +FREERDP_API GDI_COLOR gdi_SetPixel(HGDI_DC hdc, int X, int Y, GDI_COLOR crColor); +FREERDP_API uint8 gdi_GetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API uint16 gdi_GetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API uint32 gdi_GetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API uint8* gdi_GetPointer_8bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API uint16* gdi_GetPointer_16bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API uint32* gdi_GetPointer_32bpp(HGDI_BITMAP hBmp, int X, int Y); +FREERDP_API void gdi_SetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y, uint8 pixel); +FREERDP_API void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, uint16 pixel); +FREERDP_API void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, uint32 pixel); +FREERDP_API HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, uint8* data); +FREERDP_API HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight); +FREERDP_API int gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); + +typedef int (*p_BitBlt)(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop); + +#endif /* __GDI_BITMAP_H */ diff --git a/include/freerdp/gdi/brush.h b/include/freerdp/gdi/brush.h new file mode 100644 index 0000000..5055059 --- /dev/null +++ b/include/freerdp/gdi/brush.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Brush Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_BRUSH_H +#define __GDI_BRUSH_H + +#include +#include + +FREERDP_API HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor); +FREERDP_API HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp); +FREERDP_API int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); + +typedef int (*p_PatBlt)(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop); + +#endif /* __GDI_BRUSH_H */ diff --git a/include/freerdp/gdi/clipping.h b/include/freerdp/gdi/clipping.h new file mode 100644 index 0000000..88fede0 --- /dev/null +++ b/include/freerdp/gdi/clipping.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Clipping Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_CLIPPING_H +#define __GDI_CLIPPING_H + +#include +#include + +FREERDP_API int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight); +FREERDP_API HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc); +FREERDP_API int gdi_SetNullClipRgn(HGDI_DC hdc); +FREERDP_API int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy); + +#endif /* __GDI_CLIPPING_H */ diff --git a/include/freerdp/gdi/dc.h b/include/freerdp/gdi/dc.h new file mode 100644 index 0000000..83fa115 --- /dev/null +++ b/include/freerdp/gdi/dc.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Device Context Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_DC_H +#define __GDI_DC_H + +#include +#include + +FREERDP_API HGDI_DC gdi_GetDC(); +FREERDP_API HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp); +FREERDP_API HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc); +FREERDP_API HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject); +FREERDP_API int gdi_DeleteObject(HGDIOBJECT hgdiobject); +FREERDP_API int gdi_DeleteDC(HGDI_DC hdc); + +#endif /* __GDI_DC_H */ diff --git a/include/freerdp/gdi/drawing.h b/include/freerdp/gdi/drawing.h new file mode 100644 index 0000000..7447450 --- /dev/null +++ b/include/freerdp/gdi/drawing.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Drawing Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_DRAWING_H +#define __GDI_DRAWING_H + +#include +#include + +FREERDP_API int gdi_GetROP2(HGDI_DC hdc); +FREERDP_API int gdi_SetROP2(HGDI_DC hdc, int fnDrawMode); +FREERDP_API GDI_COLOR gdi_GetBkColor(HGDI_DC hdc); +FREERDP_API GDI_COLOR gdi_SetBkColor(HGDI_DC hdc, GDI_COLOR crColor); +FREERDP_API int gdi_GetBkMode(HGDI_DC hdc); +FREERDP_API int gdi_SetBkMode(HGDI_DC hdc, int iBkMode); +FREERDP_API GDI_COLOR gdi_SetTextColor(HGDI_DC hdc, GDI_COLOR crColor); + +#endif /* __GDI_DRAWING_H */ diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h new file mode 100644 index 0000000..feab649 --- /dev/null +++ b/include/freerdp/gdi/gdi.h @@ -0,0 +1,283 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Library + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_H +#define __GDI_H + +#include +#include +#include +#include +#include + +/* For more information, see [MS-RDPEGDI] */ + +/* Binary Raster Operations (ROP2) */ +#define GDI_R2_BLACK 0x01 /* D = 0 */ +#define GDI_R2_NOTMERGEPEN 0x02 /* D = ~(D | P) */ +#define GDI_R2_MASKNOTPEN 0x03 /* D = D & ~P */ +#define GDI_R2_NOTCOPYPEN 0x04 /* D = ~P */ +#define GDI_R2_MASKPENNOT 0x05 /* D = P & ~D */ +#define GDI_R2_NOT 0x06 /* D = ~D */ +#define GDI_R2_XORPEN 0x07 /* D = D ^ P */ +#define GDI_R2_NOTMASKPEN 0x08 /* D = ~(D & P) */ +#define GDI_R2_MASKPEN 0x09 /* D = D & P */ +#define GDI_R2_NOTXORPEN 0x0A /* D = ~(D ^ P) */ +#define GDI_R2_NOP 0x0B /* D = D */ +#define GDI_R2_MERGENOTPEN 0x0C /* D = D | ~P */ +#define GDI_R2_COPYPEN 0x0D /* D = P */ +#define GDI_R2_MERGEPENNOT 0x0E /* D = P | ~D */ +#define GDI_R2_MERGEPEN 0x0F /* D = P | D */ +#define GDI_R2_WHITE 0x10 /* D = 1 */ + +/* Ternary Raster Operations (ROP3) */ +#define GDI_SRCCOPY 0x00CC0020 /* D = S */ +#define GDI_SRCPAINT 0x00EE0086 /* D = S | D */ +#define GDI_SRCAND 0x008800C6 /* D = S & D */ +#define GDI_SRCINVERT 0x00660046 /* D = S ^ D */ +#define GDI_SRCERASE 0x00440328 /* D = S & ~D */ +#define GDI_NOTSRCCOPY 0x00330008 /* D = ~S */ +#define GDI_NOTSRCERASE 0x001100A6 /* D = ~S & ~D */ +#define GDI_MERGECOPY 0x00C000CA /* D = S & P */ +#define GDI_MERGEPAINT 0x00BB0226 /* D = ~S | D */ +#define GDI_PATCOPY 0x00F00021 /* D = P */ +#define GDI_PATPAINT 0x00FB0A09 /* D = D | (P | ~S) */ +#define GDI_PATINVERT 0x005A0049 /* D = P ^ D */ +#define GDI_DSTINVERT 0x00550009 /* D = ~D */ +#define GDI_BLACKNESS 0x00000042 /* D = 0 */ +#define GDI_WHITENESS 0x00FF0062 /* D = 1 */ +#define GDI_DSPDxax 0x00E20746 /* D = (S & P) | (~S & D) */ +#define GDI_SPna 0x000C0324 /* D = S & ~P */ +#define GDI_DSna 0x00220326 /* D = D & ~S */ +#define GDI_PDxn 0x00A50065 /* D = D ^ ~P */ + +/* Brush Styles */ +#define GDI_BS_SOLID 0x00 +#define GDI_BS_NULL 0x01 +#define GDI_BS_HATCHED 0x02 +#define GDI_BS_PATTERN 0x03 + +/* Hatch Patterns */ +#define GDI_HS_HORIZONTAL 0x00 +#define GDI_HS_VERTICAL 0x01 +#define GDI_HS_FDIAGONAL 0x02 +#define GDI_HS_BDIAGONAL 0x03 +#define GDI_HS_CROSS 0x04 +#define GDI_HS_DIAGCROSS 0x05 + +/* Pen Styles */ +#define GDI_PS_SOLID 0x00 +#define GDI_PS_DASH 0x01 +#define GDI_PS_NULL 0x05 + +/* Background Modes */ +#define GDI_OPAQUE 0x00000001 +#define GDI_TRANSPARENT 0x00000002 + +/* GDI Object Types */ +#define GDIOBJECT_BITMAP 0x00 +#define GDIOBJECT_PEN 0x01 +#define GDIOBJECT_PALETTE 0x02 +#define GDIOBJECT_BRUSH 0x03 +#define GDIOBJECT_RECT 0x04 +#define GDIOBJECT_REGION 0x04 + +struct _GDIOBJECT +{ + uint8 objectType; +}; +typedef struct _GDIOBJECT GDIOBJECT; +typedef GDIOBJECT* HGDIOBJECT; + +/* RGB encoded as 0x00BBGGRR */ +typedef unsigned int GDI_COLOR; +typedef GDI_COLOR* LPGDI_COLOR; + +struct _GDI_RECT +{ + uint8 objectType; + int left; + int top; + int right; + int bottom; +}; +typedef struct _GDI_RECT GDI_RECT; +typedef GDI_RECT* HGDI_RECT; + +struct _GDI_RGN +{ + uint8 objectType; + int x; /* left */ + int y; /* top */ + int w; /* width */ + int h; /* height */ + int null; /* null region */ +}; +typedef struct _GDI_RGN GDI_RGN; +typedef GDI_RGN* HGDI_RGN; + +struct _GDI_BITMAP +{ + uint8 objectType; + int bytesPerPixel; + int bitsPerPixel; + int width; + int height; + int scanline; + uint8* data; +}; +typedef struct _GDI_BITMAP GDI_BITMAP; +typedef GDI_BITMAP* HGDI_BITMAP; + +struct _GDI_PEN +{ + uint8 objectType; + int style; + int width; + int posX; + int posY; + GDI_COLOR color; +}; +typedef struct _GDI_PEN GDI_PEN; +typedef GDI_PEN* HGDI_PEN; + +struct _GDI_PALETTEENTRY +{ + uint8 red; + uint8 green; + uint8 blue; +}; +typedef struct _GDI_PALETTEENTRY GDI_PALETTEENTRY; + +struct _GDI_PALETTE +{ + uint16 count; + GDI_PALETTEENTRY *entries; +}; +typedef struct _GDI_PALETTE GDI_PALETTE; +typedef GDI_PALETTE* HGDI_PALETTE; + +struct _GDI_POINT +{ + int x; + int y; +}; +typedef struct _GDI_POINT GDI_POINT; +typedef GDI_POINT* HGDI_POINT; + +struct _GDI_BRUSH +{ + uint8 objectType; + int style; + HGDI_BITMAP pattern; + GDI_COLOR color; +}; +typedef struct _GDI_BRUSH GDI_BRUSH; +typedef GDI_BRUSH* HGDI_BRUSH; + +struct _GDI_WND +{ + int count; + int ninvalid; + HGDI_RGN invalid; + HGDI_RGN cinvalid; +}; +typedef struct _GDI_WND GDI_WND; +typedef GDI_WND* HGDI_WND; + +struct _GDI_DC +{ + HGDIOBJECT selectedObject; + int bytesPerPixel; + int bitsPerPixel; + GDI_COLOR bkColor; + GDI_COLOR textColor; + HGDI_BRUSH brush; + HGDI_RGN clip; + HGDI_PEN pen; + HGDI_WND hwnd; + int drawMode; + int bkMode; + int alpha; + int invert; + int rgb555; +}; +typedef struct _GDI_DC GDI_DC; +typedef GDI_DC* HGDI_DC; + +struct gdi_bitmap +{ + rdpBitmap _p; + + HGDI_DC hdc; + HGDI_BITMAP bitmap; + HGDI_BITMAP org_bitmap; +}; +typedef struct gdi_bitmap gdiBitmap; + +struct gdi_glyph +{ + rdpBitmap _p; + + HGDI_DC hdc; + HGDI_BITMAP bitmap; + HGDI_BITMAP org_bitmap; +}; +typedef struct gdi_glyph gdiGlyph; + +struct rdp_gdi +{ + rdpContext* context; + + int width; + int height; + int dstBpp; + int srcBpp; + int cursor_x; + int cursor_y; + int bytesPerPixel; + + HGDI_DC hdc; + HCLRCONV clrconv; + gdiBitmap* primary; + gdiBitmap* drawing; + uint8* primary_buffer; + GDI_COLOR textColor; + void* rfx_context; + void* nsc_context; + gdiBitmap* tile; + gdiBitmap* image; +}; + +FREERDP_API uint32 gdi_rop3_code(uint8 code); +FREERDP_API uint8* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y); +FREERDP_API uint8* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y); +FREERDP_API int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width); +FREERDP_API void gdi_resize(rdpGdi* gdi, int width, int height); + +FREERDP_API int gdi_init(freerdp* instance, uint32 flags, uint8* buffer); +FREERDP_API void gdi_free(freerdp* instance); + +#ifdef WITH_DEBUG_GDI +#define DEBUG_GDI(fmt, ...) DEBUG_CLASS(GDI, fmt, ## __VA_ARGS__) +#else +#define DEBUG_GDI(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __GDI_H */ diff --git a/include/freerdp/gdi/line.h b/include/freerdp/gdi/line.h new file mode 100644 index 0000000..35a19fa --- /dev/null +++ b/include/freerdp/gdi/line.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Line Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_LINE_H +#define __GDI_LINE_H + +#include +#include + +FREERDP_API int gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd); +FREERDP_API int gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, int cCount); +FREERDP_API int gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints); +FREERDP_API int gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, int cCount); +FREERDP_API int gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint); + +typedef int (*p_LineTo)(HGDI_DC hdc, int nXEnd, int nYEnd); + +#endif /* __GDI_LINE_H */ diff --git a/include/freerdp/gdi/palette.h b/include/freerdp/gdi/palette.h new file mode 100644 index 0000000..d07a8d0 --- /dev/null +++ b/include/freerdp/gdi/palette.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Palette Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_PALETTE_H +#define __GDI_PALETTE_H + +#include +#include + +FREERDP_API HGDI_PALETTE gdi_CreatePalette(HGDI_PALETTE palette); +FREERDP_API HGDI_PALETTE gdi_GetSystemPalette(); + +#endif /* __GDI_PALETTE_H */ diff --git a/include/freerdp/gdi/pen.h b/include/freerdp/gdi/pen.h new file mode 100644 index 0000000..c347734 --- /dev/null +++ b/include/freerdp/gdi/pen.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Pen Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_PEN_H +#define __GDI_PEN_H + +#include +#include + +FREERDP_API HGDI_PEN gdi_CreatePen(int fnPenStyle, int nWidth, int crColor); +FREERDP_API uint8 gdi_GetPenColor_8bpp(HGDI_PEN pen); +FREERDP_API uint16 gdi_GetPenColor_16bpp(HGDI_PEN pen); +FREERDP_API uint32 gdi_GetPenColor_32bpp(HGDI_PEN pen); + +#endif /* __GDI_PEN_H */ diff --git a/include/freerdp/gdi/region.h b/include/freerdp/gdi/region.h new file mode 100644 index 0000000..09b2129 --- /dev/null +++ b/include/freerdp/gdi/region.h @@ -0,0 +1,45 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Region Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_REGION_H +#define __GDI_REGION_H + +#include +#include + +FREERDP_API HGDI_RGN gdi_CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); +FREERDP_API HGDI_RECT gdi_CreateRect(int xLeft, int yTop, int xRight, int yBottom); +FREERDP_API void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn); +FREERDP_API void gdi_CRectToRgn(int left, int top, int right, int bottom, HGDI_RGN rgn); +FREERDP_API void gdi_RectToCRgn(HGDI_RECT rect, int *x, int *y, int *w, int *h); +FREERDP_API void gdi_CRectToCRgn(int left, int top, int right, int bottom, int *x, int *y, int *w, int *h); +FREERDP_API void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect); +FREERDP_API void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect); +FREERDP_API void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom); +FREERDP_API void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom); +FREERDP_API int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy); +FREERDP_API int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom); +FREERDP_API int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight); +FREERDP_API int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); +FREERDP_API int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2); +FREERDP_API int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src); +FREERDP_API int gdi_PtInRect(HGDI_RECT rc, int x, int y); +FREERDP_API int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h); + +#endif /* __GDI_REGION_H */ diff --git a/include/freerdp/gdi/shape.h b/include/freerdp/gdi/shape.h new file mode 100644 index 0000000..4ec28e6 --- /dev/null +++ b/include/freerdp/gdi/shape.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Shape Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_SHAPE_H +#define __GDI_SHAPE_H + +#include +#include + +FREERDP_API int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); +FREERDP_API int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); +FREERDP_API int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount); +FREERDP_API int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount); +FREERDP_API int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); + +typedef int (*p_FillRect)(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr); + +#endif /* __GDI_SHAPE_H */ diff --git a/include/freerdp/graphics.h b/include/freerdp/graphics.h new file mode 100644 index 0000000..ab6c0e8 --- /dev/null +++ b/include/freerdp/graphics.h @@ -0,0 +1,162 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GRAPHICS_H +#define __GRAPHICS_H + +typedef struct rdp_bitmap rdpBitmap; +typedef struct rdp_pointer rdpPointer; +typedef struct rdp_glyph rdpGlyph; + +#include +#include +#include +#include + +/* Bitmap Class */ + +typedef void (*pBitmap_New)(rdpContext* context, rdpBitmap* bitmap); +typedef void (*pBitmap_Free)(rdpContext* context, rdpBitmap* bitmap); +typedef void (*pBitmap_Paint)(rdpContext* context, rdpBitmap* bitmap); +typedef void (*pBitmap_Decompress)(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed); +typedef void (*pBitmap_SetSurface)(rdpContext* context, rdpBitmap* bitmap, boolean primary); + +struct rdp_bitmap +{ + size_t size; /* 0 */ + pBitmap_New New; /* 1 */ + pBitmap_Free Free; /* 2 */ + pBitmap_Paint Paint; /* 3 */ + pBitmap_Decompress Decompress; /* 4 */ + pBitmap_SetSurface SetSurface; /* 5 */ + uint32 paddingA[16 - 6]; /* 6 */ + + uint32 left; /* 16 */ + uint32 top; /* 17 */ + uint32 right; /* 18 */ + uint32 bottom; /* 19 */ + uint32 width; /* 20 */ + uint32 height; /* 21 */ + uint32 bpp; /* 22 */ + uint32 flags; /* 23 */ + uint32 length; /* 24 */ + uint8* data; /* 25 */ + uint32 paddingB[32 - 26]; /* 26 */ + + boolean compressed; /* 32 */ + boolean ephemeral; /* 33 */ + uint32 paddingC[64 - 34]; /* 34 */ +}; + +FREERDP_API rdpBitmap* Bitmap_Alloc(rdpContext* context); +FREERDP_API void Bitmap_New(rdpContext* context, rdpBitmap* bitmap); +FREERDP_API void Bitmap_Free(rdpContext* context, rdpBitmap* bitmap); +FREERDP_API void Bitmap_Register(rdpContext* context, rdpBitmap* bitmap); +FREERDP_API void Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed); +FREERDP_API void Bitmap_SetRectangle(rdpContext* context, rdpBitmap* bitmap, + uint16 left, uint16 top, uint16 right, uint16 bottom); +FREERDP_API void Bitmap_SetDimensions(rdpContext* context, rdpBitmap* bitmap, uint16 width, uint16 height); +FREERDP_API void Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primary); + +/* Pointer Class */ + +typedef void (*pPointer_New)(rdpContext* context, rdpPointer* pointer); +typedef void (*pPointer_Free)(rdpContext* context, rdpPointer* pointer); +typedef void (*pPointer_Set)(rdpContext* context, rdpPointer* pointer); + +struct rdp_pointer +{ + size_t size; /* 0 */ + pPointer_New New; /* 1 */ + pPointer_Free Free; /* 2 */ + pPointer_Set Set; /* 3 */ + uint32 paddingA[16 - 4]; /* 4 */ + + uint32 xPos; /* 16 */ + uint32 yPos; /* 17 */ + uint32 width; /* 18 */ + uint32 height; /* 19 */ + uint32 xorBpp; /* 20 */ + uint32 lengthAndMask; /* 21 */ + uint32 lengthXorMask; /* 22 */ + uint8* xorMaskData; /* 23 */ + uint8* andMaskData; /* 24 */ + uint32 paddingB[32 - 25]; /* 25 */ +}; + +FREERDP_API rdpPointer* Pointer_Alloc(rdpContext* context); +FREERDP_API void Pointer_New(rdpContext* context, rdpPointer* pointer); +FREERDP_API void Pointer_Free(rdpContext* context, rdpPointer* pointer); +FREERDP_API void Pointer_Set(rdpContext* context, rdpPointer* pointer); + +/* Glyph Class */ + +typedef void (*pGlyph_New)(rdpContext* context, rdpGlyph* glyph); +typedef void (*pGlyph_Free)(rdpContext* context, rdpGlyph* glyph); +typedef void (*pGlyph_Draw)(rdpContext* context, rdpGlyph* glyph, int x, int y); +typedef void (*pGlyph_BeginDraw)(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor); +typedef void (*pGlyph_EndDraw)(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor); + +struct rdp_glyph +{ + size_t size; /* 0 */ + pGlyph_New New; /* 1 */ + pGlyph_Free Free; /* 2 */ + pGlyph_Draw Draw; /* 3 */ + pGlyph_BeginDraw BeginDraw; /* 4 */ + pGlyph_EndDraw EndDraw; /* 5 */ + uint32 paddingA[16 - 6]; /* 6 */ + + sint32 x; /* 16 */ + sint32 y; /* 17 */ + uint32 cx; /* 18 */ + uint32 cy; /* 19 */ + uint32 cb; /* 20 */ + uint8* aj; /* 21 */ + uint32 paddingB[32 - 22]; /* 22 */ +}; + +FREERDP_API rdpGlyph* Glyph_Alloc(rdpContext* context); +FREERDP_API void Glyph_New(rdpContext* context, rdpGlyph* glyph); +FREERDP_API void Glyph_Free(rdpContext* context, rdpGlyph* glyph); +FREERDP_API void Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y); +FREERDP_API void Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor); +FREERDP_API void Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor); + +/* Graphics Module */ + +struct rdp_graphics +{ + rdpContext* context; /* 0 */ + rdpBitmap* Bitmap_Prototype; /* 1 */ + rdpPointer* Pointer_Prototype; /* 2 */ + rdpGlyph* Glyph_Prototype; /* 3 */ + uint32 paddingA[16 - 4]; /* 4 */ +}; + +FREERDP_API void graphics_register_bitmap(rdpGraphics* graphics, rdpBitmap* bitmap); +FREERDP_API void graphics_register_pointer(rdpGraphics* graphics, rdpPointer* pointer); +FREERDP_API void graphics_register_glyph(rdpGraphics* graphics, rdpGlyph* glyph); + +FREERDP_API rdpGraphics* graphics_new(rdpContext* context); +FREERDP_API void graphics_free(rdpGraphics* graphics); + +#endif /* __GRAPHICS_H */ diff --git a/include/freerdp/input.h b/include/freerdp/input.h new file mode 100644 index 0000000..e59bed2 --- /dev/null +++ b/include/freerdp/input.h @@ -0,0 +1,75 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Input Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INPUT_API_H +#define __INPUT_API_H + +typedef struct rdp_input rdpInput; + +#include + +/* keyboard Flags */ +#define KBD_FLAGS_EXTENDED 0x0100 +#define KBD_FLAGS_DOWN 0x4000 +#define KBD_FLAGS_RELEASE 0x8000 + +/* Pointer Flags */ +#define PTR_FLAGS_WHEEL 0x0200 +#define PTR_FLAGS_WHEEL_NEGATIVE 0x0100 +#define PTR_FLAGS_MOVE 0x0800 +#define PTR_FLAGS_DOWN 0x8000 +#define PTR_FLAGS_BUTTON1 0x1000 +#define PTR_FLAGS_BUTTON2 0x2000 +#define PTR_FLAGS_BUTTON3 0x4000 +#define WheelRotationMask 0x01FF + +/* Extended Pointer Flags */ +#define PTR_XFLAGS_DOWN 0x8000 +#define PTR_XFLAGS_BUTTON1 0x0001 +#define PTR_XFLAGS_BUTTON2 0x0002 + +/* Keyboard Toggle Flags */ +#define KBD_SYNC_SCROLL_LOCK 0x00000001 +#define KBD_SYNC_NUM_LOCK 0x00000002 +#define KBD_SYNC_CAPS_LOCK 0x00000004 +#define KBD_SYNC_KANA_LOCK 0x00000008 + +#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4 + +typedef void (*pSynchronizeEvent)(rdpInput* input, uint32 flags); +typedef void (*pKeyboardEvent)(rdpInput* input, uint16 flags, uint16 code); +typedef void (*pUnicodeKeyboardEvent)(rdpInput* input, uint16 flags, uint16 code); +typedef void (*pMouseEvent)(rdpInput* input, uint16 flags, uint16 x, uint16 y); +typedef void (*pExtendedMouseEvent)(rdpInput* input, uint16 flags, uint16 x, uint16 y); + +struct rdp_input +{ + rdpContext* context; /* 0 */ + void* param1; /* 1 */ + uint32 paddingA[16 - 2]; /* 2 */ + + pSynchronizeEvent SynchronizeEvent; /* 16 */ + pKeyboardEvent KeyboardEvent; /* 17 */ + pUnicodeKeyboardEvent UnicodeKeyboardEvent; /* 18 */ + pMouseEvent MouseEvent; /* 19 */ + pExtendedMouseEvent ExtendedMouseEvent; /* 20 */ + uint32 paddingB[32 - 21]; /* 21 */ +}; + +#endif /* __INPUT_API_H */ diff --git a/include/freerdp/kbd/kbd.h b/include/freerdp/kbd/kbd.h new file mode 100644 index 0000000..82d1024 --- /dev/null +++ b/include/freerdp/kbd/kbd.h @@ -0,0 +1,42 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based keyboard mapping + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_KBD_H +#define __FREERDP_KBD_H + +#include +#include + +#define RDP_KEYBOARD_LAYOUT_TYPE_STANDARD 1 +#define RDP_KEYBOARD_LAYOUT_TYPE_VARIANT 2 +#define RDP_KEYBOARD_LAYOUT_TYPE_IME 4 + +typedef struct rdp_keyboard_layout +{ + uint32 code; + char name[50]; +} rdpKeyboardLayout; + +FREERDP_API rdpKeyboardLayout* freerdp_kbd_get_layouts(int types); +FREERDP_API uint32 freerdp_kbd_init(void *dpy, uint32 keyboard_layout_id); +FREERDP_API uint8 freerdp_kbd_get_scancode_by_keycode(uint8 keycode, boolean* extended); +FREERDP_API uint8 freerdp_kbd_get_keycode_by_scancode(uint8 scancode, boolean extended); +FREERDP_API uint8 freerdp_kbd_get_scancode_by_virtualkey(int vkcode, boolean* extended); + +#endif /* __FREERDP_KBD_H */ diff --git a/include/freerdp/kbd/layouts.h b/include/freerdp/kbd/layouts.h new file mode 100644 index 0000000..c92c7ac --- /dev/null +++ b/include/freerdp/kbd/layouts.h @@ -0,0 +1,184 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Keyboard layout IDs used in the RDP protocol */ + +#ifndef __LAYOUT_IDS_H +#define __LAYOUT_IDS_H + +#include +#include + +/* Keyboard layout IDs */ + +#define KBD_ARABIC_101 0x00000401 +#define KBD_BULGARIAN 0x00000402 +#define KBD_CHINESE_TRADITIONAL_US 0x00000404 +#define KBD_CZECH 0x00000405 +#define KBD_DANISH 0x00000406 +#define KBD_GERMAN 0x00000407 +#define KBD_GREEK 0x00000408 +#define KBD_US 0x00000409 +#define KBD_SPANISH 0x0000040A +#define KBD_FINNISH 0x0000040B +#define KBD_FRENCH 0x0000040C +#define KBD_HEBREW 0x0000040D +#define KBD_HUNGARIAN 0x0000040E +#define KBD_ICELANDIC 0x0000040F +#define KBD_ITALIAN 0x00000410 +#define KBD_JAPANESE 0x00000411 +#define KBD_KOREAN 0x00000412 +#define KBD_DUTCH 0x00000413 +#define KBD_NORWEGIAN 0x00000414 +#define KBD_POLISH_PROGRAMMERS 0x00000415 +#define KBD_PORTUGUESE_BRAZILIAN_ABNT 0x00000416 +#define KBD_ROMANIAN 0x00000418 +#define KBD_RUSSIAN 0x00000419 +#define KBD_CROATIAN 0x0000041A +#define KBD_SLOVAK 0x0000041B +#define KBD_ALBANIAN 0x0000041C +#define KBD_SWEDISH 0x0000041D +#define KBD_THAI_KEDMANEE 0x0000041E +#define KBD_TURKISH_Q 0x0000041F +#define KBD_URDU 0x00000420 +#define KBD_UKRAINIAN 0x00000422 +#define KBD_BELARUSIAN 0x00000423 +#define KBD_SLOVENIAN 0x00000424 +#define KBD_ESTONIAN 0x00000425 +#define KBD_LATVIAN 0x00000426 +#define KBD_LITHUANIAN_IBM 0x00000427 +#define KBD_FARSI 0x00000429 +#define KBD_VIETNAMESE 0x0000042A +#define KBD_ARMENIAN_EASTERN 0x0000042B +#define KBD_AZERI_LATIN 0x0000042C +#define KBD_FYRO_MACEDONIAN 0x0000042F +#define KBD_GEORGIAN 0x00000437 +#define KBD_FAEROESE 0x00000438 +#define KBD_DEVANAGARI_INSCRIPT 0x00000439 +#define KBD_MALTESE_47_KEY 0x0000043A +#define KBD_NORWEGIAN_WITH_SAMI 0x0000043B +#define KBD_KAZAKH 0x0000043F +#define KBD_KYRGYZ_CYRILLIC 0x00000440 +#define KBD_TATAR 0x00000444 +#define KBD_BENGALI 0x00000445 +#define KBD_PUNJABI 0x00000446 +#define KBD_GUJARATI 0x00000447 +#define KBD_TAMIL 0x00000449 +#define KBD_TELUGU 0x0000044A +#define KBD_KANNADA 0x0000044B +#define KBD_MALAYALAM 0x0000044C +#define KBD_MARATHI 0x0000044E +#define KBD_MONGOLIAN_CYRILLIC 0x00000450 +#define KBD_UNITED_KINGDOM_EXTENDED 0x00000452 +#define KBD_SYRIAC 0x0000045A +#define KBD_NEPALI 0x00000461 +#define KBD_PASHTO 0x00000463 +#define KBD_DIVEHI_PHONETIC 0x00000465 +#define KBD_LUXEMBOURGISH 0x0000046E +#define KBD_MAORI 0x00000481 +#define KBD_CHINESE_SIMPLIFIED_US 0x00000804 +#define KBD_SWISS_GERMAN 0x00000807 +#define KBD_UNITED_KINGDOM 0x00000809 +#define KBD_LATIN_AMERICAN 0x0000080A +#define KBD_BELGIAN_FRENCH 0x0000080C +#define KBD_BELGIAN_PERIOD 0x00000813 +#define KBD_PORTUGUESE 0x00000816 +#define KBD_SERBIAN_LATIN 0x0000081A +#define KBD_AZERI_CYRILLIC 0x0000082C +#define KBD_SWEDISH_WITH_SAMI 0x0000083B +#define KBD_UZBEK_CYRILLIC 0x00000843 +#define KBD_INUKTITUT_LATIN 0x0000085D +#define KBD_CANADIAN_FRENCH_LEGACY 0x00000C0C +#define KBD_SERBIAN_CYRILLIC 0x00000C1A +#define KBD_CANADIAN_FRENCH 0x00001009 +#define KBD_SWISS_FRENCH 0x0000100C +#define KBD_BOSNIAN 0x0000141A +#define KBD_IRISH 0x00001809 +#define KBD_BOSNIAN_CYRILLIC 0x0000201A + +/* Keyboard layout variant IDs */ + +#define KBD_ARABIC_102 0x00010401 +#define KBD_BULGARIAN_LATIN 0x00010402 +#define KBD_CZECH_QWERTY 0x00010405 +#define KBD_GERMAN_IBM 0x00010407 +#define KBD_GREEK_220 0x00010408 +#define KBD_UNITED_STATES_DVORAK 0x00010409 +#define KBD_SPANISH_VARIATION 0x0001040A +#define KBD_HUNGARIAN_101_KEY 0x0001040E +#define KBD_ITALIAN_142 0x00010410 +#define KBD_POLISH_214 0x00010415 +#define KBD_PORTUGUESE_BRAZILIAN_ABNT2 0x00010416 +#define KBD_RUSSIAN_TYPEWRITER 0x00010419 +#define KBD_SLOVAK_QWERTY 0x0001041B +#define KBD_THAI_PATTACHOTE 0x0001041E +#define KBD_TURKISH_F 0x0001041F +#define KBD_LATVIAN_QWERTY 0x00010426 +#define KBD_LITHUANIAN 0x00010427 +#define KBD_ARMENIAN_WESTERN 0x0001042B +#define KBD_HINDI_TRADITIONAL 0x00010439 +#define KBD_MALTESE_48_KEY 0x0001043A +#define KBD_SAMI_EXTENDED_NORWAY 0x0001043B +#define KBD_BENGALI_INSCRIPT 0x00010445 +#define KBD_SYRIAC_PHONETIC 0x0001045A +#define KBD_DIVEHI_TYPEWRITER 0x00010465 +#define KBD_BELGIAN_COMMA 0x0001080C +#define KBD_FINNISH_WITH_SAMI 0x0001083B +#define KBD_CANADIAN_MULTILINGUAL_STANDARD 0x00011009 +#define KBD_GAELIC 0x00011809 +#define KBD_ARABIC_102_AZERTY 0x00020401 +#define KBD_CZECH_PROGRAMMERS 0x00020405 +#define KBD_GREEK_319 0x00020408 +#define KBD_UNITED_STATES_INTERNATIONAL 0x00020409 +#define KBD_THAI_KEDMANEE_NON_SHIFTLOCK 0x0002041E +#define KBD_SAMI_EXTENDED_FINLAND_SWEDEN 0x0002083B +#define KBD_GREEK_220_LATIN 0x00030408 +#define KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND 0x00030409 +#define KBD_THAI_PATTACHOTE_NON_SHIFTLOCK 0x0003041E +#define KBD_GREEK_319_LATIN 0x00040408 +#define KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND 0x00040409 +#define KBD_GREEK_LATIN 0x00050408 +#define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409 +#define KBD_GREEK_POLYTONIC 0x00060408 +#define KBD_GERMAN_NEO 0xB0000407 + +/* Global Input Method Editor (IME) IDs */ + +#define KBD_CHINESE_TRADITIONAL_PHONETIC 0xE0010404 +#define KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 0xE0010411 +#define KBD_KOREAN_INPUT_SYSTEM_IME_2000 0xE0010412 +#define KBD_CHINESE_SIMPLIFIED_QUANPIN 0xE0010804 +#define KBD_CHINESE_TRADITIONAL_CHANGJIE 0xE0020404 +#define KBD_CHINESE_SIMPLIFIED_SHUANGPIN 0xE0020804 +#define KBD_CHINESE_TRADITIONAL_QUICK 0xE0030404 +#define KBD_CHINESE_SIMPLIFIED_ZHENGMA 0xE0030804 +#define KBD_CHINESE_TRADITIONAL_BIG5_CODE 0xE0040404 +#define KBD_CHINESE_TRADITIONAL_ARRAY 0xE0050404 +#define KBD_CHINESE_SIMPLIFIED_NEIMA 0xE0050804 +#define KBD_CHINESE_TRADITIONAL_DAYI 0xE0060404 +#define KBD_CHINESE_TRADITIONAL_UNICODE 0xE0070404 +#define KBD_CHINESE_TRADITIONAL_NEW_PHONETIC 0xE0080404 +#define KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE 0xE0090404 +#define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804 +#define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404 + +FREERDP_API rdpKeyboardLayout* get_keyboard_layouts(int types); +FREERDP_API const char* get_layout_name(uint32 keyboardLayoutID); + +#endif diff --git a/include/freerdp/kbd/locales.h b/include/freerdp/kbd/locales.h new file mode 100644 index 0000000..b98a06e --- /dev/null +++ b/include/freerdp/kbd/locales.h @@ -0,0 +1,328 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Detection of plausible keyboard layout id based on current locale (LANG) setting. */ + +/* + * Refer to "Windows XP/Server 2003 - List of Locale IDs, Input Locale, and Language Collection": + * http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx + */ + +#ifndef __LOCALES_H +#define __LOCALES_H + +#include +#include + +#define AFRIKAANS 0x0436 +#define ALBANIAN 0x041c +#define ALSATIAN 0x0484 +#define AMHARIC 0x045E +#define ARABIC_SAUDI_ARABIA 0x0401 +#define ARABIC_IRAQ 0x0801 +#define ARABIC_EGYPT 0x0c01 +#define ARABIC_LIBYA 0x1001 +#define ARABIC_ALGERIA 0x1401 +#define ARABIC_MOROCCO 0x1801 +#define ARABIC_TUNISIA 0x1c01 +#define ARABIC_OMAN 0x2001 +#define ARABIC_YEMEN 0x2401 +#define ARABIC_SYRIA 0x2801 +#define ARABIC_JORDAN 0x2c01 +#define ARABIC_LEBANON 0x3001 +#define ARABIC_KUWAIT 0x3401 +#define ARABIC_UAE 0x3801 +#define ARABIC_BAHRAIN 0x3c01 +#define ARABIC_QATAR 0x4001 +#define ARMENIAN 0x042b +#define ASSAMESE 0x044D +#define AZERI_LATIN 0x042c +#define AZERI_CYRILLIC 0x082c +#define BASHKIR 0x046D +#define BASQUE 0x042d +#define BELARUSIAN 0x0423 +#define BENGALI_INDIA 0x0445 +#define BOSNIAN_LATIN 0x141A +#define BRETON 0x047E +#define BULGARIAN 0x0402 +#define CATALAN 0x0403 +#define CHINESE_TAIWAN 0x0404 +#define CHINESE_PRC 0x0804 +#define CHINESE_HONG_KONG 0x0c04 +#define CHINESE_SINGAPORE 0x1004 +#define CHINESE_MACAU 0x1404 +#define CROATIAN 0x041a +#define CROATIAN_BOSNIA_HERZEGOVINA 0x101A +#define CZECH 0x0405 +#define DANISH 0x0406 +#define DARI 0x048C +#define DIVEHI 0x0465 +#define DUTCH_STANDARD 0x0413 +#define DUTCH_BELGIAN 0x0813 +#define ENGLISH_UNITED_STATES 0x0409 +#define ENGLISH_UNITED_KINGDOM 0x0809 +#define ENGLISH_AUSTRALIAN 0x0c09 +#define ENGLISH_CANADIAN 0x1009 +#define ENGLISH_NEW_ZEALAND 0x1409 +#define ENGLISH_INDIA 0x4009 +#define ENGLISH_IRELAND 0x1809 +#define ENGLISH_MALAYSIA 0x4409 +#define ENGLISH_SOUTH_AFRICA 0x1c09 +#define ENGLISH_JAMAICA 0x2009 +#define ENGLISH_CARIBBEAN 0x2409 +#define ENGLISH_BELIZE 0x2809 +#define ENGLISH_TRINIDAD 0x2c09 +#define ENGLISH_ZIMBABWE 0x3009 +#define ENGLISH_PHILIPPINES 0x3409 +#define ENGLISH_SINGAPORE 0x4809 +#define ESTONIAN 0x0425 +#define FAEROESE 0x0438 +#define FARSI 0x0429 +#define FILIPINO 0x0464 +#define FINNISH 0x040b +#define FRENCH_STANDARD 0x040c +#define FRENCH_BELGIAN 0x080c +#define FRENCH_CANADIAN 0x0c0c +#define FRENCH_SWISS 0x100c +#define FRENCH_LUXEMBOURG 0x140c +#define FRENCH_MONACO 0x180c +#define FRISIAN 0x0462 +#define GEORGIAN 0x0437 +#define GALICIAN 0x0456 +#define GERMAN_STANDARD 0x0407 +#define GERMAN_SWISS 0x0807 +#define GERMAN_AUSTRIAN 0x0c07 +#define GERMAN_LUXEMBOURG 0x1007 +#define GERMAN_LIECHTENSTEIN 0x1407 +#define GREEK 0x0408 +#define GREENLANDIC 0x046F +#define GUJARATI 0x0447 +#define HEBREW 0x040d +#define HINDI 0x0439 +#define HUNGARIAN 0x040e +#define ICELANDIC 0x040f +#define IGBO 0x0470 +#define INDONESIAN 0x0421 +#define IRISH 0x083C +#define ITALIAN_STANDARD 0x0410 +#define ITALIAN_SWISS 0x0810 +#define JAPANESE 0x0411 +#define KANNADA 0x044b +#define KAZAKH 0x043f +#define KHMER 0x0453 +#define KICHE 0x0486 +#define KINYARWANDA 0x0487 +#define KONKANI 0x0457 +#define KOREAN 0x0412 +#define KYRGYZ 0x0440 +#define LAO 0x0454 +#define LATVIAN 0x0426 +#define LITHUANIAN 0x0427 +#define LOWER_SORBIAN 0x082E +#define LUXEMBOURGISH 0x046E +#define MACEDONIAN 0x042f +#define MALAY_MALAYSIA 0x043e +#define MALAY_BRUNEI_DARUSSALAM 0x083e +#define MALAYALAM 0x044c +#define MALTESE 0x043a +#define MAPUDUNGUN 0x047A +#define MAORI 0x0481 +#define MARATHI 0x044e +#define MOHAWK 0x047C +#define MONGOLIAN 0x0450 +#define NEPALI 0x0461 +#define NORWEGIAN_BOKMAL 0x0414 +#define NORWEGIAN_NYNORSK 0x0814 +#define OCCITAN 0x0482 +#define ORIYA 0x0448 +#define PASHTO 0x0463 +#define POLISH 0x0415 +#define PORTUGUESE_BRAZILIAN 0x0416 +#define PORTUGUESE_STANDARD 0x0816 +#define PUNJABI 0x0446 +#define QUECHUA_BOLIVIA 0x046b +#define QUECHUA_ECUADOR 0x086b +#define QUECHUA_PERU 0x0c6b +#define ROMANIAN 0x0418 +#define ROMANSH 0x0417 +#define RUSSIAN 0x0419 +#define SAMI_INARI 0x243b +#define SAMI_LULE_NORWAY 0x103b +#define SAMI_LULE_SWEDEN 0x143b +#define SAMI_NORTHERN_FINLAND 0x0c3b +#define SAMI_NORTHERN_NORWAY 0x043b +#define SAMI_NORTHERN_SWEDEN 0x083b +#define SAMI_SKOLT 0x203b +#define SAMI_SOUTHERN_NORWAY 0x183b +#define SAMI_SOUTHERN_SWEDEN 0x1c3b +#define SANSKRIT 0x044f +#define SERBIAN_LATIN 0x081a +#define SERBIAN_LATIN_BOSNIA_HERZEGOVINA 0x181a +#define SERBIAN_CYRILLIC 0x0c1a +#define SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA 0x1c1a +#define SESOTHO_SA_LEBOA 0x046C +#define SINHALA 0x045B +#define SLOVAK 0x041b +#define SLOVENIAN 0x0424 +#define SPANISH_TRADITIONAL_SORT 0x040a +#define SPANISH_MEXICAN 0x080a +#define SPANISH_MODERN_SORT 0x0c0a +#define SPANISH_GUATEMALA 0x100a +#define SPANISH_COSTA_RICA 0x140a +#define SPANISH_PANAMA 0x180a +#define SPANISH_DOMINICAN_REPUBLIC 0x1c0a +#define SPANISH_VENEZUELA 0x200a +#define SPANISH_COLOMBIA 0x240a +#define SPANISH_PERU 0x280a +#define SPANISH_ARGENTINA 0x2c0a +#define SPANISH_ECUADOR 0x300a +#define SPANISH_CHILE 0x340a +#define SPANISH_UNITED_STATES 0x540A +#define SPANISH_URUGUAY 0x380a +#define SPANISH_PARAGUAY 0x3c0a +#define SPANISH_BOLIVIA 0x400a +#define SPANISH_EL_SALVADOR 0x440a +#define SPANISH_HONDURAS 0x480a +#define SPANISH_NICARAGUA 0x4c0a +#define SPANISH_PUERTO_RICO 0x500a +#define SWAHILI 0x0441 +#define SWEDISH 0x041d +#define SWEDISH_FINLAND 0x081d +#define SYRIAC 0x045a +#define TAMIL 0x0449 +#define TATAR 0x0444 +#define TELUGU 0x044a +#define THAI 0x041e +#define TIBETAN_BHUTAN 0x0851 +#define TIBETAN_PRC 0x0451 +#define TSWANA 0x0432 +#define UKRAINIAN 0x0422 +#define TURKISH 0x041f +#define TURKMEN 0x0442 +#define UIGHUR 0x0480 +#define UPPER_SORBIAN 0x042E +#define URDU 0x0420 +#define URDU_INDIA 0x0820 +#define UZBEK_LATIN 0x0443 +#define UZBEK_CYRILLIC 0x0843 +#define VIETNAMESE 0x042a +#define WELSH 0x0452 +#define WOLOF 0x0488 +#define XHOSA 0x0434 +#define YAKUT 0x0485 +#define YI 0x0478 +#define YORUBA 0x046A +#define ZULU 0x0435 + + +/* +Time zones, taken from Windows Server 2008 + +(GMT -12:00) International Date Line West +(GMT -11:00) Midway Island, Samoa +(GMT -10:00) Hawaii +(GMT -09:00) Alaska +(GMT -08:00) Pacific Time (US & Canada) +(GMT -08:00) Tijuana, Baja California +(GMT -07:00) Arizona +(GMT -07:00) Chihuahua, La Paz, Mazatlan +(GMT -07:00) Mountain Time (US & Canada) +(GMT -06:00) Central America +(GMT -06:00) Central Time (US & Canada) +(GMT -06:00) Guadalajara, Mexico City, Monterrey +(GMT -06:00) Saskatchewan +(GMT -05:00) Bogota, Lima, Quito, Rio Branco +(GMT -05:00) Eastern Time (US & Canada) +(GMT -05:00) Indiana (East) +(GMT -04:30) Caracas +(GMT -04:00) Atlantic Time (Canada) +(GMT -04:00) La Paz +(GMT -04:00) Manaus +(GMT -04:00) Santiago +(GMT -03:30) Newfoundland +(GMT -03:00) Brasilia +(GMT -03:00) Buenos Aires +(GMT -03:00) Georgetown +(GMT -03:00) Greenland +(GMT -03:00) Montevideo +(GMT -02:00) Mid-Atlantic +(GMT -01:00) Azores +(GMT -01:00) Cape Verde Is. +(GMT +00:00) Casablanca +(GMT +00:00) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London +(GMT +00:00) Monrovia, Reykjavik +(GMT +01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna +(GMT +01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague +(GMT +01:00) Brussels, Copenhagen, Madrid, Paris +(GMT +01:00) Sarajevo, Skopje, Warsaw, Zagreb +(GMT +01:00) West Central Africa +(GMT +02:00) Amman +(GMT +02:00) Athens, Bucharest, Istanbul +(GMT +02:00) Beirut +(GMT +02:00) Cairo +(GMT +02:00) Harare, Pretoria +(GMT +02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius +(GMT +02:00) Jerusalem +(GMT +02:00) Minsk +(GMT +02:00) Windhoek +(GMT +03:00) Baghdad +(GMT +03:00) Kuwait, Riyadh +(GMT +03:00) Moscow, St. Petersburg, Volgograd +(GMT +03:00) Nairobi +(GMT +03:00) Tbilisi +(GMT +03:30) Tehran +(GMT +04:00) Abu Dhabi, Muscat +(GMT +04:00) Baku +(GMT +04:00) Port Louis +(GMT +04:00) Yerevan +(GMT +04:30) Kabul +(GMT +05:00) Ekaterinburg +(GMT +05:00) Islamabad, Karachi +(GMT +05:00) Tashkent +(GMT +05:30) Chennai, Kolkata, Mumbai, New Delhi +(GMT +05:30) Sri Jayawardenepura +(GMT +05:45) Kathmandu +(GMT +06:00) Almaty, Novosibirsk +(GMT +06:00) Astana, Dhaka +(GMT +06:30) Yangon (Rangoon) +(GMT +07:00) Bangkok, Hanoi, Jakarta +(GMT +07:00) Krasnoyarsk +(GMT +08:00) Beijing, Chongqing, Hong Kong, Urumqi +(GMT +08:00) Irkutsk, Ulaan Bataar +(GMT +08:00) Kuala Lumpur, Singapore +(GMT +08:00) Perth +(GMT +08:00) Taipei +(GMT +09:00) Osaka, Sapporo, Tokyo +(GMT +09:00) Seoul +(GMT +09:00) Yakutsk +(GMT +09:30) Adelaide +(GMT +09:30) Darwin +(GMT +10:00) Brisbane +(GMT +10:00) Canberra, Melbourne, Sydney +(GMT +10:00) Guam, Port Moresby +(GMT +10:00) Hobart, Vladivostok +(GMT +11:00) Magadan, Solomon Is., New Caledonia +(GMT +12:00) Auckland, Wellington +(GMT +12:00) Fiji, Kamchatka, Marshall Is. +(GMT +13:00) Nuku'alofa +*/ + +FREERDP_API uint32 detect_keyboard_layout_from_locale(); + +#endif /* __LOCALES_H */ diff --git a/include/freerdp/kbd/vkcodes.h b/include/freerdp/kbd/vkcodes.h new file mode 100644 index 0000000..f2f87d1 --- /dev/null +++ b/include/freerdp/kbd/vkcodes.h @@ -0,0 +1,587 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Microsoft Virtual Key Code Definitions and Conversion Tables + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Microsoft Windows Virtual Key Codes: http://msdn.microsoft.com/en-us/library/ms645540.aspx */ + +#ifndef __VKCODES_H +#define __VKCODES_H + +#include +#include +#include + +/* Mouse buttons */ + +#define VK_LBUTTON 0x01 /* Left mouse button */ +#define VK_RBUTTON 0x02 /* Right mouse button */ +#define VK_CANCEL 0x03 /* Control-break processing */ +#define VK_MBUTTON 0x04 /* Middle mouse button (three-button mouse) */ +#define VK_XBUTTON1 0x05 /* Windows 2000/XP: X1 mouse button */ +#define VK_XBUTTON2 0x06 /* Windows 2000/XP: X2 mouse button */ + +/* 0x07 is undefined */ + +#define VK_BACK 0x08 /* BACKSPACE key */ +#define VK_TAB 0x09 /* TAB key */ + +/* 0x0A to 0x0B are reserved */ + +#define VK_CLEAR 0x0C /* CLEAR key */ +#define VK_RETURN 0x0D /* ENTER key */ + +/* 0x0E to 0x0F are undefined */ + +#define VK_SHIFT 0x10 /* SHIFT key */ +#define VK_CONTROL 0x11 /* CTRL key */ +#define VK_MENU 0x12 /* ALT key */ +#define VK_PAUSE 0x13 /* PAUSE key */ +#define VK_CAPITAL 0x14 /* CAPS LOCK key */ +#define VK_KANA 0x15 /* Input Method Editor (IME) Kana mode */ +#define VK_HANGUEL 0x15 /* IME Hanguel mode (maintained for compatibility; use #define VK_HANGUL) */ +#define VK_HANGUL 0x15 /* IME Hangul mode */ + +/* 0x16 is undefined */ + +#define VK_JUNJA 0x17 /* IME Junja mode */ +#define VK_FINAL 0x18 /* IME final mode */ +#define VK_HANJA 0x19 /* IME Hanja mode */ +#define VK_KANJI 0x19 /* IME Kanji mode */ + +/* 0x1A is undefined */ + +#define VK_ESCAPE 0x1B /* ESC key */ +#define VK_CONVERT 0x1C /* IME convert */ +#define VK_NONCONVERT 0x1D /* IME nonconvert */ +#define VK_ACCEPT 0x1E /* IME accept */ +#define VK_MODECHANGE 0x1F /* IME mode change request */ + +#define VK_SPACE 0x20 /* SPACEBAR */ +#define VK_PRIOR 0x21 /* PAGE UP key */ +#define VK_NEXT 0x22 /* PAGE DOWN key */ +#define VK_END 0x23 /* END key */ +#define VK_HOME 0x24 /* HOME key */ +#define VK_LEFT 0x25 /* LEFT ARROW key */ +#define VK_UP 0x26 /* UP ARROW key */ +#define VK_RIGHT 0x27 /* RIGHT ARROW key */ +#define VK_DOWN 0x28 /* DOWN ARROW key */ +#define VK_SELECT 0x29 /* SELECT key */ +#define VK_PRINT 0x2A /* PRINT key */ +#define VK_EXECUTE 0x2B /* EXECUTE key */ +#define VK_SNAPSHOT 0x2C /* PRINT SCREEN key */ +#define VK_INSERT 0x2D /* INS key */ +#define VK_DELETE 0x2E /* DEL key */ +#define VK_HELP 0x2F /* HELP key */ + +/* Digits, the last 4 bits of the code represent the corresponding digit */ + +#define VK_KEY_0 0x30 /* '0' key */ +#define VK_KEY_1 0x31 /* '1' key */ +#define VK_KEY_2 0x32 /* '2' key */ +#define VK_KEY_3 0x33 /* '3' key */ +#define VK_KEY_4 0x34 /* '4' key */ +#define VK_KEY_5 0x35 /* '5' key */ +#define VK_KEY_6 0x36 /* '6' key */ +#define VK_KEY_7 0x37 /* '7' key */ +#define VK_KEY_8 0x38 /* '8' key */ +#define VK_KEY_9 0x39 /* '9' key */ + +/* 0x3A to 0x40 are undefined */ + +/* The alphabet, the code corresponds to the capitalized letter in the ASCII code */ + +#define VK_KEY_A 0x41 /* 'A' key */ +#define VK_KEY_B 0x42 /* 'B' key */ +#define VK_KEY_C 0x43 /* 'C' key */ +#define VK_KEY_D 0x44 /* 'D' key */ +#define VK_KEY_E 0x45 /* 'E' key */ +#define VK_KEY_F 0x46 /* 'F' key */ +#define VK_KEY_G 0x47 /* 'G' key */ +#define VK_KEY_H 0x48 /* 'H' key */ +#define VK_KEY_I 0x49 /* 'I' key */ +#define VK_KEY_J 0x4A /* 'J' key */ +#define VK_KEY_K 0x4B /* 'K' key */ +#define VK_KEY_L 0x4C /* 'L' key */ +#define VK_KEY_M 0x4D /* 'M' key */ +#define VK_KEY_N 0x4E /* 'N' key */ +#define VK_KEY_O 0x4F /* 'O' key */ +#define VK_KEY_P 0x50 /* 'P' key */ +#define VK_KEY_Q 0x51 /* 'Q' key */ +#define VK_KEY_R 0x52 /* 'R' key */ +#define VK_KEY_S 0x53 /* 'S' key */ +#define VK_KEY_T 0x54 /* 'T' key */ +#define VK_KEY_U 0x55 /* 'U' key */ +#define VK_KEY_V 0x56 /* 'V' key */ +#define VK_KEY_W 0x57 /* 'W' key */ +#define VK_KEY_X 0x58 /* 'X' key */ +#define VK_KEY_Y 0x59 /* 'Y' key */ +#define VK_KEY_Z 0x5A /* 'Z' key */ + +#define VK_LWIN 0x5B /* Left Windows key (Microsoft Natural keyboard) */ +#define VK_RWIN 0x5C /* Right Windows key (Natural keyboard) */ +#define VK_APPS 0x5D /* Applications key (Natural keyboard) */ + +/* 0x5E is reserved */ + +#define VK_SLEEP 0x5F /* Computer Sleep key */ + +/* Numeric keypad digits, the last four bits of the code represent the corresponding digit */ + +#define VK_NUMPAD0 0x60 /* Numeric keypad '0' key */ +#define VK_NUMPAD1 0x61 /* Numeric keypad '1' key */ +#define VK_NUMPAD2 0x62 /* Numeric keypad '2' key */ +#define VK_NUMPAD3 0x63 /* Numeric keypad '3' key */ +#define VK_NUMPAD4 0x64 /* Numeric keypad '4' key */ +#define VK_NUMPAD5 0x65 /* Numeric keypad '5' key */ +#define VK_NUMPAD6 0x66 /* Numeric keypad '6' key */ +#define VK_NUMPAD7 0x67 /* Numeric keypad '7' key */ +#define VK_NUMPAD8 0x68 /* Numeric keypad '8' key */ +#define VK_NUMPAD9 0x69 /* Numeric keypad '9' key */ + +/* Numeric keypad operators and special keys */ + +#define VK_MULTIPLY 0x6A /* Multiply key */ +#define VK_ADD 0x6B /* Add key */ +#define VK_SEPARATOR 0x6C /* Separator key */ +#define VK_SUBTRACT 0x6D /* Subtract key */ +#define VK_DECIMAL 0x6E /* Decimal key */ +#define VK_DIVIDE 0x6F /* Divide key */ + +/* Function keys, from F1 to F24 */ + +#define VK_F1 0x70 /* F1 key */ +#define VK_F2 0x71 /* F2 key */ +#define VK_F3 0x72 /* F3 key */ +#define VK_F4 0x73 /* F4 key */ +#define VK_F5 0x74 /* F5 key */ +#define VK_F6 0x75 /* F6 key */ +#define VK_F7 0x76 /* F7 key */ +#define VK_F8 0x77 /* F8 key */ +#define VK_F9 0x78 /* F9 key */ +#define VK_F10 0x79 /* F10 key */ +#define VK_F11 0x7A /* F11 key */ +#define VK_F12 0x7B /* F12 key */ +#define VK_F13 0x7C /* F13 key */ +#define VK_F14 0x7D /* F14 key */ +#define VK_F15 0x7E /* F15 key */ +#define VK_F16 0x7F /* F16 key */ +#define VK_F17 0x80 /* F17 key */ +#define VK_F18 0x81 /* F18 key */ +#define VK_F19 0x82 /* F19 key */ +#define VK_F20 0x83 /* F20 key */ +#define VK_F21 0x84 /* F21 key */ +#define VK_F22 0x85 /* F22 key */ +#define VK_F23 0x86 /* F23 key */ +#define VK_F24 0x87 /* F24 key */ + +/* 0x88 to 0x8F are unassigned */ + +#define VK_NUMLOCK 0x90 /* NUM LOCK key */ +#define VK_SCROLL 0x91 /* SCROLL LOCK key */ + +/* 0x92 to 0x96 are OEM specific */ +/* 0x97 to 0x9F are unassigned */ + +/* Modifier keys */ + +#define VK_LSHIFT 0xA0 /* Left SHIFT key */ +#define VK_RSHIFT 0xA1 /* Right SHIFT key */ +#define VK_LCONTROL 0xA2 /* Left CONTROL key */ +#define VK_RCONTROL 0xA3 /* Right CONTROL key */ +#define VK_LMENU 0xA4 /* Left MENU key */ +#define VK_RMENU 0xA5 /* Right MENU key */ + +/* Browser related keys */ + +#define VK_BROWSER_BACK 0xA6 /* Windows 2000/XP: Browser Back key */ +#define VK_BROWSER_FORWARD 0xA7 /* Windows 2000/XP: Browser Forward key */ +#define VK_BROWSER_REFRESH 0xA8 /* Windows 2000/XP: Browser Refresh key */ +#define VK_BROWSER_STOP 0xA9 /* Windows 2000/XP: Browser Stop key */ +#define VK_BROWSER_SEARCH 0xAA /* Windows 2000/XP: Browser Search key */ +#define VK_BROWSER_FAVORITES 0xAB /* Windows 2000/XP: Browser Favorites key */ +#define VK_BROWSER_HOME 0xAC /* Windows 2000/XP: Browser Start and Home key */ + +/* Volume related keys */ + +#define VK_VOLUME_MUTE 0xAD /* Windows 2000/XP: Volume Mute key */ +#define VK_VOLUME_DOWN 0xAE /* Windows 2000/XP: Volume Down key */ +#define VK_VOLUME_UP 0xAF /* Windows 2000/XP: Volume Up key */ + +/* Media player related keys */ + +#define VK_MEDIA_NEXT_TRACK 0xB0 /* Windows 2000/XP: Next Track key */ +#define VK_MEDIA_PREV_TRACK 0xB1 /* Windows 2000/XP: Previous Track key */ +#define VK_MEDIA_STOP 0xB2 /* Windows 2000/XP: Stop Media key */ +#define VK_MEDIA_PLAY_PAUSE 0xB3 /* Windows 2000/XP: Play/Pause Media key */ + +/* Application launcher keys */ + +#define VK_LAUNCH_MAIL 0xB4 /* Windows 2000/XP: Start Mail key */ +#define VK_LAUNCH_MEDIA_SELECT 0xB5 /* Windows 2000/XP: Select Media key */ +#define VK_LAUNCH_APP1 0xB6 /* Windows 2000/XP: Start Application 1 key */ +#define VK_LAUNCH_APP2 0xB7 /* Windows 2000/XP: Start Application 2 key */ + +/* 0xB8 and 0xB9 are reserved */ + +/* OEM keys */ + +#define VK_OEM_1 0xBA /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the ';:' key */ + +#define VK_OEM_PLUS 0xBB /* Windows 2000/XP: For any country/region, the '+' key */ +#define VK_OEM_COMMA 0xBC /* Windows 2000/XP: For any country/region, the ',' key */ +#define VK_OEM_MINUS 0xBD /* Windows 2000/XP: For any country/region, the '-' key */ +#define VK_OEM_PERIOD 0xBE /* Windows 2000/XP: For any country/region, the '.' key */ + +#define VK_OEM_2 0xBF /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the '/?' key */ + +#define VK_OEM_3 0xC0 /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the '`~' key */ + +/* 0xC1 to 0xD7 are reserved */ +#define VK_ABNT_C1 0xC1 /* Brazilian (ABNT) Keyboard */ +#define VK_ABNT_C2 0xC2 /* Brazilian (ABNT) Keyboard */ + +/* 0xD8 to 0xDA are unassigned */ + +#define VK_OEM_4 0xDB /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the '[{' key */ + +#define VK_OEM_5 0xDC /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the '\|' key */ + +#define VK_OEM_6 0xDD /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the ']}' key */ + +#define VK_OEM_7 0xDE /* Used for miscellaneous characters; it can vary by keyboard. */ + /* Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key */ + +#define VK_OEM_8 0xDF /* Used for miscellaneous characters; it can vary by keyboard. */ + +/* 0xE0 is reserved */ +/* 0xE1 is OEM specific */ + +#define VK_OEM_102 0xE2 /* Windows 2000/XP: Either the angle bracket key or */ + /* the backslash key on the RT 102-key keyboard */ + +/* 0xE3 and 0xE4 are OEM specific */ + +#define VK_PROCESSKEY 0xE5 /* Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key */ + +/* 0xE6 is OEM specific */ + +#define VK_PACKET 0xE7 /* Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. */ + /* The #define VK_PACKET key is the low word of a 32-bit Virtual Key value used */ + /* for non-keyboard input methods. For more information, */ + /* see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP */ + +/* 0xE8 is unassigned */ +/* 0xE9 to 0xF5 are OEM specific */ + +#define VK_ATTN 0xF6 /* Attn key */ +#define VK_CRSEL 0xF7 /* CrSel key */ +#define VK_EXSEL 0xF8 /* ExSel key */ +#define VK_EREOF 0xF9 /* Erase EOF key */ +#define VK_PLAY 0xFA /* Play key */ +#define VK_ZOOM 0xFB /* Zoom key */ +#define VK_NONAME 0xFC /* Reserved */ +#define VK_PA1 0xFD /* PA1 key */ +#define VK_OEM_CLEAR 0xFE /* Clear key */ + +/* Use the virtual key code as an index in this array in order to get its associated scan code */ + +typedef struct _virtualKey +{ + /* Windows "scan code", aka keycode in RDP */ + unsigned char scancode; + + /* Windows "extended" flag, boolean */ + unsigned char extended; + + /* Windows virtual key name */ + char *name; + + /* XKB keyname */ + char *x_keyname; +} virtualKey; + +static const virtualKey virtualKeyboard[256 + 2] = +{ + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_LBUTTON" , NULL }, + { 0x00, 0, "VK_RBUTTON" , NULL }, + { 0x00, 0, "VK_CANCEL" , NULL }, + { 0x00, 0, "VK_MBUTTON" , NULL }, + { 0x00, 0, "VK_XBUTTON1" , NULL }, + { 0x00, 0, "VK_XBUTTON2" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x0E, 0, "VK_BACK" , "BKSP" }, + { 0x0F, 0, "VK_TAB" , "TAB" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_CLEAR" , NULL }, + { 0x1C, 0, "VK_RETURN" , "RTRN" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x2A, 0, "VK_SHIFT" , "LFSH" }, + { 0x00, 0, "VK_CONTROL" , NULL }, + { 0x38, 0, "VK_MENU" , "LALT" }, + { 0x46, 1, "VK_PAUSE" , "PAUS" }, + { 0x3A, 0, "VK_CAPITAL" , "CAPS" }, + { 0x72, 0, "VK_KANA / VK_HANGUL" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_JUNJA" , NULL }, + { 0x00, 0, "VK_FINAL" , NULL }, + { 0x71, 0, "VK_HANJA / VK_KANJI" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x01, 0, "VK_ESCAPE" , "ESC" }, + { 0x00, 0, "VK_CONVERT" , NULL }, + { 0x00, 0, "VK_NONCONVERT" , NULL }, + { 0x00, 0, "VK_ACCEPT" , NULL }, + { 0x00, 0, "VK_MODECHANGE" , NULL }, + { 0x39, 0, "VK_SPACE" , "SPCE" }, + { 0x49, 1, "VK_PRIOR" , "PGUP" }, + { 0x51, 1, "VK_NEXT" , "PGDN" }, + { 0x4F, 1, "VK_END" , "END" }, + { 0x47, 1, "VK_HOME" , "HOME" }, + { 0x4B, 1, "VK_LEFT" , "LEFT" }, + { 0x48, 1, "VK_UP" , "UP" }, + { 0x4D, 1, "VK_RIGHT" , "RGHT" }, + { 0x50, 1, "VK_DOWN" , "DOWN" }, + { 0x00, 0, "VK_SELECT" , NULL }, + { 0x37, 1, "VK_PRINT" , "PRSC" }, + { 0x37, 1, "VK_EXECUTE" , NULL }, + { 0x37, 1, "VK_SNAPSHOT" , NULL }, + { 0x52, 1, "VK_INSERT" , "INS" }, + { 0x53, 1, "VK_DELETE" , "DELE" }, + { 0x63, 0, "VK_HELP" , NULL }, + { 0x0B, 0, "VK_KEY_0" , "AE10" }, + { 0x02, 0, "VK_KEY_1" , "AE01" }, + { 0x03, 0, "VK_KEY_2" , "AE02" }, + { 0x04, 0, "VK_KEY_3" , "AE03" }, + { 0x05, 0, "VK_KEY_4" , "AE04" }, + { 0x06, 0, "VK_KEY_5" , "AE05" }, + { 0x07, 0, "VK_KEY_6" , "AE06" }, + { 0x08, 0, "VK_KEY_7" , "AE07" }, + { 0x09, 0, "VK_KEY_8" , "AE08" }, + { 0x0A, 0, "VK_KEY_9" , "AE09" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x1E, 0, "VK_KEY_A" , "AC01" }, + { 0x30, 0, "VK_KEY_B" , "AB05" }, + { 0x2E, 0, "VK_KEY_C" , "AB03" }, + { 0x20, 0, "VK_KEY_D" , "AC03" }, + { 0x12, 0, "VK_KEY_E" , "AD03" }, + { 0x21, 0, "VK_KEY_F" , "AC04" }, + { 0x22, 0, "VK_KEY_G" , "AC05" }, + { 0x23, 0, "VK_KEY_H" , "AC06" }, + { 0x17, 0, "VK_KEY_I" , "AD08" }, + { 0x24, 0, "VK_KEY_J" , "AC07" }, + { 0x25, 0, "VK_KEY_K" , "AC08" }, + { 0x26, 0, "VK_KEY_L" , "AC09" }, + { 0x32, 0, "VK_KEY_M" , "AB07" }, + { 0x31, 0, "VK_KEY_N" , "AB06" }, + { 0x18, 0, "VK_KEY_O" , "AD09" }, + { 0x19, 0, "VK_KEY_P" , "AD10" }, + { 0x10, 0, "VK_KEY_Q" , "AD01" }, + { 0x13, 0, "VK_KEY_R" , "AD04" }, + { 0x1F, 0, "VK_KEY_S" , "AC02" }, + { 0x14, 0, "VK_KEY_T" , "AD05" }, + { 0x16, 0, "VK_KEY_U" , "AD07" }, + { 0x2F, 0, "VK_KEY_V" , "AB04" }, + { 0x11, 0, "VK_KEY_W" , "AD02" }, + { 0x2D, 0, "VK_KEY_X" , "AB02" }, + { 0x15, 0, "VK_KEY_Y" , "AD06" }, + { 0x2C, 0, "VK_KEY_Z" , "AB01" }, + { 0x5B, 1, "VK_LWIN" , "LWIN" }, + { 0x5C, 1, "VK_RWIN" , "RWIN" }, + { 0x5D, 1, "VK_APPS" , "COMP" }, + { 0x00, 0, "" , NULL }, + { 0x5F, 0, "VK_SLEEP" , NULL }, + { 0x52, 0, "VK_NUMPAD0" , "KP0" }, + { 0x4F, 0, "VK_NUMPAD1" , "KP1" }, + { 0x50, 0, "VK_NUMPAD2" , "KP2" }, + { 0x51, 0, "VK_NUMPAD3" , "KP3" }, + { 0x4B, 0, "VK_NUMPAD4" , "KP4" }, + { 0x4C, 0, "VK_NUMPAD5" , "KP5" }, + { 0x4D, 0, "VK_NUMPAD6" , "KP6" }, + { 0x47, 0, "VK_NUMPAD7" , "KP7" }, + { 0x48, 0, "VK_NUMPAD8" , "KP8" }, + { 0x49, 0, "VK_NUMPAD9" , "KP9" }, + { 0x37, 0, "VK_MULTIPLY" , "KPMU" }, + { 0x4E, 0, "VK_ADD" , "KPAD" }, + { 0x00, 0, "VK_SEPARATOR" , NULL }, + { 0x4A, 0, "VK_SUBTRACT" , "KPSU" }, + { 0x53, 0, "VK_DECIMAL" , "KPDL" }, + { 0x35, 0, "VK_DIVIDE" , "KPDV" }, + { 0x3B, 0, "VK_F1" , "FK01" }, + { 0x3C, 0, "VK_F2" , "FK02" }, + { 0x3D, 0, "VK_F3" , "FK03" }, + { 0x3E, 0, "VK_F4" , "FK04" }, + { 0x3F, 0, "VK_F5" , "FK05" }, + { 0x40, 0, "VK_F6" , "FK06" }, + { 0x41, 0, "VK_F7" , "FK07" }, + { 0x42, 0, "VK_F8" , "FK08" }, + { 0x43, 0, "VK_F9" , "FK09" }, + { 0x44, 0, "VK_F10" , "FK10" }, + { 0x57, 0, "VK_F11" , "FK11" }, + { 0x58, 0, "VK_F12" , "FK12" }, + { 0x64, 0, "VK_F13" , NULL }, + { 0x65, 0, "VK_F14" , NULL }, + { 0x66, 0, "VK_F15" , NULL }, + { 0x67, 0, "VK_F16" , NULL }, + { 0x68, 0, "VK_F17" , NULL }, + { 0x69, 0, "VK_F18" , NULL }, + { 0x6A, 0, "VK_F19" , NULL }, + { 0x6B, 0, "VK_F20" , NULL }, + { 0x6C, 0, "VK_F21" , NULL }, + { 0x6D, 0, "VK_F22" , NULL }, + { 0x6E, 0, "VK_F23" , NULL }, + { 0x6F, 0, "VK_F24" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x45, 0, "VK_NUMLOCK" , "NMLK" }, + { 0x46, 0, "VK_SCROLL" , "SCLK" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x2A, 0, "VK_LSHIFT" , NULL }, + { 0x36, 0, "VK_RSHIFT" , "RTSH" }, + { 0x1D, 0, "VK_LCONTROL" , "LCTL" }, + { 0x1D, 1, "VK_RCONTROL" , "RCTL" }, + { 0x38, 0, "VK_LMENU" , NULL }, + { 0x38, 1, "VK_RMENU" , "RALT" }, + { 0x00, 0, "VK_BROWSER_BACK" , NULL }, + { 0x00, 0, "VK_BROWSER_FORWARD" , NULL }, + { 0x00, 0, "VK_BROWSER_REFRESH" , NULL }, + { 0x00, 0, "VK_BROWSER_STOP" , NULL }, + { 0x00, 0, "VK_BROWSER_SEARCH" , NULL }, + { 0x00, 0, "VK_BROWSER_FAVORITES", NULL }, + { 0x00, 0, "VK_BROWSER_HOME" , NULL }, + { 0x00, 0, "VK_VOLUME_MUTE" , NULL }, + { 0x00, 0, "VK_VOLUME_DOWN" , NULL }, + { 0x00, 0, "VK_VOLUME_UP" , NULL }, + { 0x00, 0, "VK_MEDIA_NEXT_TRACK" , NULL }, + { 0x00, 0, "VK_MEDIA_PREV_TRACK" , NULL }, + { 0x00, 0, "VK_MEDIA_STOP" , NULL }, + { 0x00, 0, "VK_MEDIA_PLAY_PAUSE" , NULL }, + { 0x00, 0, "VK_LAUNCH_MAIL" , NULL }, + { 0x00, 0, "VK_MEDIA_SELECT" , NULL }, + { 0x00, 0, "VK_LAUNCH_APP1" , NULL }, + { 0x00, 0, "VK_LAUNCH_APP2" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x27, 0, "VK_OEM_1" , "AC10" }, + { 0x0D, 0, "VK_OEM_PLUS" , "AE12" }, + { 0x33, 0, "VK_OEM_COMMA" , "AB08" }, + { 0x0C, 0, "VK_OEM_MINUS" , "AE11" }, + { 0x34, 0, "VK_OEM_PERIOD" , "AB09" }, + { 0x35, 0, "VK_OEM_2" , "AB10" }, + { 0x29, 0, "VK_OEM_3" , "TLDE" }, + { 0x73, 0, "VK_ABNT_C1" , "AB11" }, + { 0x7E, 0, "VK_ABNT_C2" , "I129" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x1A, 0, "VK_OEM_4" , "AD11" }, + { 0x2B, 0, "VK_OEM_5" , "BKSL" }, + { 0x1B, 0, "VK_OEM_6" , "AD12" }, + { 0x28, 0, "VK_OEM_7" , "AC11" }, + { 0x1D, 0, "VK_OEM_8" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x56, 0, "VK_OEM_102" , "LSGT" }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_PROCESSKEY" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_PACKET" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "" , NULL }, + { 0x00, 0, "VK_ATTN" , NULL }, + { 0x00, 0, "VK_CRSEL" , NULL }, + { 0x00, 0, "VK_EXSEL" , NULL }, + { 0x00, 0, "VK_EREOF" , NULL }, + { 0x00, 0, "VK_PLAY" , NULL }, + { 0x62, 0, "VK_ZOOM" , NULL }, + { 0x00, 0, "VK_NONAME" , NULL }, + { 0x00, 0, "VK_PA1" , NULL }, + { 0x00, 0, "VK_OEM_CLEAR" , NULL }, + { 0x00, 0, "" , NULL }, + /* end of 256 VK entries */ + { 0x54, 0, "" , "LVL3" }, + { 0x1C, 1, "" , "KPEN" }, +}; + +#endif /* __VKCODES_H */ diff --git a/include/freerdp/listener.h b/include/freerdp/listener.h new file mode 100644 index 0000000..6b0a256 --- /dev/null +++ b/include/freerdp/listener.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Listener + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_LISTENER_H +#define __FREERDP_LISTENER_H + +typedef struct rdp_freerdp_listener freerdp_listener; + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef boolean (*psListenerOpen)(freerdp_listener* instance, const char* bind_address, uint16 port); +typedef boolean (*psListenerGetFileDescriptor)(freerdp_listener* instance, void** rfds, int* rcount); +typedef boolean (*psListenerCheckFileDescriptor)(freerdp_listener* instance); +typedef void (*psListenerClose)(freerdp_listener* instance); +typedef void (*psPeerAccepted)(freerdp_listener* instance, freerdp_peer* client); + +struct rdp_freerdp_listener +{ + void* info; + void* listener; + void* param1; + void* param2; + void* param3; + void* param4; + + psListenerOpen Open; + psListenerGetFileDescriptor GetFileDescriptor; + psListenerCheckFileDescriptor CheckFileDescriptor; + psListenerClose Close; + + psPeerAccepted PeerAccepted; +}; + +FREERDP_API freerdp_listener* freerdp_listener_new(void); +FREERDP_API void freerdp_listener_free(freerdp_listener* instance); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h new file mode 100644 index 0000000..1650410 --- /dev/null +++ b/include/freerdp/peer.h @@ -0,0 +1,77 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Peer + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FREERDP_PEER_H +#define __FREERDP_PEER_H + +#include +#include +#include +#include +#include + +typedef void (*psPeerContextNew)(freerdp_peer* client, rdpContext* context); +typedef void (*psPeerContextFree)(freerdp_peer* client, rdpContext* context); + +typedef boolean (*psPeerInitialize)(freerdp_peer* client); +typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount); +typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client); +typedef void (*psPeerDisconnect)(freerdp_peer* client); +typedef boolean (*psPeerCapabilities)(freerdp_peer* client); +typedef boolean (*psPeerPostConnect)(freerdp_peer* client); +typedef boolean (*psPeerActivate)(freerdp_peer* client); + +typedef int (*psPeerSendChannelData)(freerdp_peer* client, int channelId, uint8* data, int size); +typedef int (*psPeerReceiveChannelData)(freerdp_peer* client, int channelId, uint8* data, int size, int flags, int total_size); + +struct rdp_freerdp_peer +{ + rdpContext* context; + int sockfd; + char hostname[50]; + + rdpInput* input; + rdpUpdate* update; + rdpSettings* settings; + + size_t context_size; + psPeerContextNew ContextNew; + psPeerContextFree ContextFree; + + psPeerInitialize Initialize; + psPeerGetFileDescriptor GetFileDescriptor; + psPeerCheckFileDescriptor CheckFileDescriptor; + psPeerDisconnect Disconnect; + + psPeerCapabilities Capabilities; + psPeerPostConnect PostConnect; + psPeerActivate Activate; + + psPeerSendChannelData SendChannelData; + psPeerReceiveChannelData ReceiveChannelData; +}; + +FREERDP_API void freerdp_peer_context_new(freerdp_peer* client); +FREERDP_API void freerdp_peer_context_free(freerdp_peer* client); + +FREERDP_API freerdp_peer* freerdp_peer_new(int sockfd); +FREERDP_API void freerdp_peer_free(freerdp_peer* client); + +#endif /* __FREERDP_PEER_H */ + diff --git a/include/freerdp/plugins/cliprdr.h b/include/freerdp/plugins/cliprdr.h new file mode 100644 index 0000000..2890a4b --- /dev/null +++ b/include/freerdp/plugins/cliprdr.h @@ -0,0 +1,74 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Clipboard Virtual Channel Types + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CLIPRDR_PLUGIN +#define __CLIPRDR_PLUGIN + +/** + * Event Types + */ +#define RDP_EVENT_TYPE_CB_MONITOR_READY 1 +#define RDP_EVENT_TYPE_CB_FORMAT_LIST 2 +#define RDP_EVENT_TYPE_CB_DATA_REQUEST 3 +#define RDP_EVENT_TYPE_CB_DATA_RESPONSE 4 + +/** + * Clipboard Formats + */ + +#define CB_FORMAT_RAW 0x0000 +#define CB_FORMAT_TEXT 0x0001 +#define CB_FORMAT_DIB 0x0008 +#define CB_FORMAT_UNICODETEXT 0x000D +#define CB_FORMAT_HTML 0xD010 +#define CB_FORMAT_PNG 0xD011 +#define CB_FORMAT_JPEG 0xD012 +#define CB_FORMAT_GIF 0xD013 + +/** + * Clipboard Events + */ +typedef RDP_EVENT RDP_CB_MONITOR_READY_EVENT; + +struct _RDP_CB_FORMAT_LIST_EVENT +{ + RDP_EVENT event; + uint32* formats; + uint16 num_formats; + uint8* raw_format_data; + uint32 raw_format_data_size; +}; +typedef struct _RDP_CB_FORMAT_LIST_EVENT RDP_CB_FORMAT_LIST_EVENT; + +struct _RDP_CB_DATA_REQUEST_EVENT +{ + RDP_EVENT event; + uint32 format; +}; +typedef struct _RDP_CB_DATA_REQUEST_EVENT RDP_CB_DATA_REQUEST_EVENT; + +struct _RDP_CB_DATA_RESPONSE_EVENT +{ + RDP_EVENT event; + uint8* data; + uint32 size; +}; +typedef struct _RDP_CB_DATA_RESPONSE_EVENT RDP_CB_DATA_RESPONSE_EVENT; + +#endif /* __CLIPRDR_PLUGIN */ diff --git a/include/freerdp/plugins/tsmf.h b/include/freerdp/plugins/tsmf.h new file mode 100644 index 0000000..6df4964 --- /dev/null +++ b/include/freerdp/plugins/tsmf.h @@ -0,0 +1,64 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Multimedia Redirection Virtual Channel Types + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TSMF_PLUGIN +#define __TSMF_PLUGIN + +/** + * Event Types + */ +enum RDP_EVENT_TYPE_TSMF +{ + RDP_EVENT_TYPE_TSMF_VIDEO_FRAME = 1, + RDP_EVENT_TYPE_TSMF_REDRAW +}; + +struct _RDP_VIDEO_FRAME_EVENT +{ + RDP_EVENT event; + uint8* frame_data; + uint32 frame_size; + uint32 frame_pixfmt; + sint16 frame_width; + sint16 frame_height; + sint16 x; + sint16 y; + sint16 width; + sint16 height; + uint16 num_visible_rects; + RDP_RECT* visible_rects; +}; +typedef struct _RDP_VIDEO_FRAME_EVENT RDP_VIDEO_FRAME_EVENT; + +struct _RDP_REDRAW_EVENT +{ + RDP_EVENT event; + sint16 x; + sint16 y; + sint16 width; + sint16 height; +}; +typedef struct _RDP_REDRAW_EVENT RDP_REDRAW_EVENT; + +/* RDP_VIDEO_FRAME_EVENT.frame_pixfmt */ +/* http://www.fourcc.org/yuv.php */ +#define RDP_PIXFMT_I420 0x30323449 +#define RDP_PIXFMT_YV12 0x32315659 + +#endif /* __TSMF_PLUGIN */ diff --git a/include/freerdp/pointer.h b/include/freerdp/pointer.h new file mode 100644 index 0000000..b8170fe --- /dev/null +++ b/include/freerdp/pointer.h @@ -0,0 +1,102 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Pointer Updates Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_POINTER_H +#define __UPDATE_POINTER_H + +#include + +#define PTR_MSG_TYPE_SYSTEM 0x0001 +#define PTR_MSG_TYPE_POSITION 0x0003 +#define PTR_MSG_TYPE_COLOR 0x0006 +#define PTR_MSG_TYPE_CACHED 0x0007 +#define PTR_MSG_TYPE_POINTER 0x0008 + +#define SYSPTR_NULL 0x00000000 +#define SYSPTR_DEFAULT 0x00007F00 + +struct _POINTER_POSITION_UPDATE +{ + uint32 xPos; + uint32 yPos; +}; +typedef struct _POINTER_POSITION_UPDATE POINTER_POSITION_UPDATE; + +struct _POINTER_SYSTEM_UPDATE +{ + uint32 type; +}; +typedef struct _POINTER_SYSTEM_UPDATE POINTER_SYSTEM_UPDATE; + +struct _POINTER_COLOR_UPDATE +{ + uint32 cacheIndex; + uint32 xPos; + uint32 yPos; + uint32 width; + uint32 height; + uint32 lengthAndMask; + uint32 lengthXorMask; + uint8* xorMaskData; + uint8* andMaskData; +}; +typedef struct _POINTER_COLOR_UPDATE POINTER_COLOR_UPDATE; + +struct _POINTER_NEW_UPDATE +{ + uint32 xorBpp; + POINTER_COLOR_UPDATE colorPtrAttr; +}; +typedef struct _POINTER_NEW_UPDATE POINTER_NEW_UPDATE; + +struct _POINTER_CACHED_UPDATE +{ + uint32 cacheIndex; +}; +typedef struct _POINTER_CACHED_UPDATE POINTER_CACHED_UPDATE; + +typedef void (*pPointerPosition)(rdpContext* context, POINTER_POSITION_UPDATE* pointer_position); +typedef void (*pPointerSystem)(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system); +typedef void (*pPointerColor)(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color); +typedef void (*pPointerNew)(rdpContext* context, POINTER_NEW_UPDATE* pointer_new); +typedef void (*pPointerCached)(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached); + +struct rdp_pointer_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pPointerPosition PointerPosition; /* 16 */ + pPointerSystem PointerSystem; /* 17 */ + pPointerColor PointerColor; /* 18 */ + pPointerNew PointerNew; /* 19 */ + pPointerCached PointerCached; /* 20 */ + uint32 paddingB[32 - 21]; /* 21 */ + + /* internal */ + + POINTER_POSITION_UPDATE pointer_position; + POINTER_SYSTEM_UPDATE pointer_system; + POINTER_COLOR_UPDATE pointer_color; + POINTER_NEW_UPDATE pointer_new; + POINTER_CACHED_UPDATE pointer_cached; +}; +typedef struct rdp_pointer_update rdpPointerUpdate; + +#endif /* __UPDATE_POINTER_H */ diff --git a/include/freerdp/primary.h b/include/freerdp/primary.h new file mode 100644 index 0000000..d3b7488 --- /dev/null +++ b/include/freerdp/primary.h @@ -0,0 +1,495 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Primary Drawing Orders Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_PRIMARY_H +#define __UPDATE_PRIMARY_H + +#include + +struct rdp_bounds +{ + sint32 left; + sint32 top; + sint32 right; + sint32 bottom; +}; +typedef struct rdp_bounds rdpBounds; + +struct rdp_brush +{ + uint32 x; + uint32 y; + uint32 bpp; + uint32 style; + uint32 hatch; + uint32 index; + uint8* data; + uint8 p8x8[8]; +}; +typedef struct rdp_brush rdpBrush; + +struct _ORDER_INFO +{ + uint32 orderType; + uint32 fieldFlags; + rdpBounds bounds; + sint32 deltaBoundLeft; + sint32 deltaBoundTop; + sint32 deltaBoundRight; + sint32 deltaBoundBottom; + boolean deltaCoordinates; +}; +typedef struct _ORDER_INFO ORDER_INFO; + +struct _DSTBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; +}; +typedef struct _DSTBLT_ORDER DSTBLT_ORDER; + +struct _PATBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + uint32 backColor; + uint32 foreColor; + rdpBrush brush; +}; +typedef struct _PATBLT_ORDER PATBLT_ORDER; + +struct _SCRBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + sint32 nXSrc; + sint32 nYSrc; +}; +typedef struct _SCRBLT_ORDER SCRBLT_ORDER; + +struct _OPAQUE_RECT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 color; +}; +typedef struct _OPAQUE_RECT_ORDER OPAQUE_RECT_ORDER; + +struct _DRAW_NINE_GRID_ORDER +{ + sint32 srcLeft; + sint32 srcTop; + sint32 srcRight; + sint32 srcBottom; + uint32 bitmapId; +}; +typedef struct _DRAW_NINE_GRID_ORDER DRAW_NINE_GRID_ORDER; + +struct _DELTA_RECT +{ + sint32 left; + sint32 top; + sint32 width; + sint32 height; +}; +typedef struct _DELTA_RECT DELTA_RECT; + +struct _MULTI_DSTBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + uint32 numRectangles; + uint32 cbData; + DELTA_RECT rectangles[45]; +}; +typedef struct _MULTI_DSTBLT_ORDER MULTI_DSTBLT_ORDER; + +struct _MULTI_PATBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + uint32 backColor; + uint32 foreColor; + rdpBrush brush; + uint32 numRectangles; + uint32 cbData; + DELTA_RECT rectangles[45]; +}; +typedef struct _MULTI_PATBLT_ORDER MULTI_PATBLT_ORDER; + +struct _MULTI_SCRBLT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + sint32 nXSrc; + sint32 nYSrc; + uint32 numRectangles; + uint32 cbData; + DELTA_RECT rectangles[45]; +}; +typedef struct _MULTI_SCRBLT_ORDER MULTI_SCRBLT_ORDER; + +struct _MULTI_OPAQUE_RECT_ORDER +{ + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 color; + uint32 numRectangles; + uint32 cbData; + DELTA_RECT rectangles[45]; +}; +typedef struct _MULTI_OPAQUE_RECT_ORDER MULTI_OPAQUE_RECT_ORDER; + +struct _MULTI_DRAW_NINE_GRID_ORDER +{ + sint32 srcLeft; + sint32 srcTop; + sint32 srcRight; + sint32 srcBottom; + uint32 bitmapId; + uint32 nDeltaEntries; + uint32 cbData; + uint8* codeDeltaList; +}; +typedef struct _MULTI_DRAW_NINE_GRID_ORDER MULTI_DRAW_NINE_GRID_ORDER; + +struct _LINE_TO_ORDER +{ + uint32 backMode; + sint32 nXStart; + sint32 nYStart; + sint32 nXEnd; + sint32 nYEnd; + uint32 backColor; + uint32 bRop2; + uint32 penStyle; + uint32 penWidth; + uint32 penColor; +}; +typedef struct _LINE_TO_ORDER LINE_TO_ORDER; + +struct _DELTA_POINT +{ + sint32 x; + sint32 y; +}; +typedef struct _DELTA_POINT DELTA_POINT; + +struct _POLYLINE_ORDER +{ + sint32 xStart; + sint32 yStart; + uint32 bRop2; + uint32 penColor; + uint32 numPoints; + uint32 cbData; + DELTA_POINT* points; +}; +typedef struct _POLYLINE_ORDER POLYLINE_ORDER; + +struct _MEMBLT_ORDER +{ + uint32 cacheId; + uint32 colorIndex; + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + sint32 nXSrc; + sint32 nYSrc; + uint32 cacheIndex; + rdpBitmap* bitmap; +}; +typedef struct _MEMBLT_ORDER MEMBLT_ORDER; + +struct _MEM3BLT_ORDER +{ + uint32 cacheId; + uint32 colorIndex; + sint32 nLeftRect; + sint32 nTopRect; + sint32 nWidth; + sint32 nHeight; + uint32 bRop; + sint32 nXSrc; + sint32 nYSrc; + uint32 backColor; + uint32 foreColor; + rdpBrush brush; + uint32 cacheIndex; + rdpBitmap* bitmap; +}; +typedef struct _MEM3BLT_ORDER MEM3BLT_ORDER; + +struct _SAVE_BITMAP_ORDER +{ + uint32 savedBitmapPosition; + sint32 nLeftRect; + sint32 nTopRect; + sint32 nRightRect; + sint32 nBottomRect; + uint32 operation; +}; +typedef struct _SAVE_BITMAP_ORDER SAVE_BITMAP_ORDER; + +struct _GLYPH_FRAGMENT_INDEX +{ + uint32 index; + uint32 delta; +}; +typedef struct _GLYPH_FRAGMENT_INDEX GLYPH_FRAGMENT_INDEX; + +struct _GLYPH_FRAGMENT +{ + uint32 operation; + uint32 index; + uint32 size; + uint32 nindices; + GLYPH_FRAGMENT_INDEX* indices; +}; +typedef struct _GLYPH_FRAGMENT GLYPH_FRAGMENT; + +struct _GLYPH_INDEX_ORDER +{ + uint32 cacheId; + uint32 flAccel; + uint32 ulCharInc; + uint32 fOpRedundant; + uint32 backColor; + uint32 foreColor; + sint32 bkLeft; + sint32 bkTop; + sint32 bkRight; + sint32 bkBottom; + sint32 opLeft; + sint32 opTop; + sint32 opRight; + sint32 opBottom; + rdpBrush brush; + sint32 x; + sint32 y; + uint32 cbData; + uint8 data[256]; +}; +typedef struct _GLYPH_INDEX_ORDER GLYPH_INDEX_ORDER; + +struct _FAST_INDEX_ORDER +{ + uint32 cacheId; + uint32 flAccel; + uint32 ulCharInc; + uint32 backColor; + uint32 foreColor; + sint32 bkLeft; + sint32 bkTop; + sint32 bkRight; + sint32 bkBottom; + sint32 opLeft; + sint32 opTop; + sint32 opRight; + sint32 opBottom; + boolean opaqueRect; + sint32 x; + sint32 y; + uint32 cbData; + uint8 data[256]; +}; +typedef struct _FAST_INDEX_ORDER FAST_INDEX_ORDER; + +struct _FAST_GLYPH_ORDER +{ + uint32 cacheId; + uint32 flAccel; + uint32 ulCharInc; + uint32 backColor; + uint32 foreColor; + sint32 bkLeft; + sint32 bkTop; + sint32 bkRight; + sint32 bkBottom; + sint32 opLeft; + sint32 opTop; + sint32 opRight; + sint32 opBottom; + sint32 x; + sint32 y; + uint32 cbData; + uint8 data[256]; + void* glyph_data; +}; +typedef struct _FAST_GLYPH_ORDER FAST_GLYPH_ORDER; + +struct _POLYGON_SC_ORDER +{ + sint32 xStart; + sint32 yStart; + uint32 bRop2; + uint32 fillMode; + uint32 brushColor; + uint32 nDeltaEntries; + uint32 cbData; + uint8* codeDeltaList; +}; +typedef struct _POLYGON_SC_ORDER POLYGON_SC_ORDER; + +struct _POLYGON_CB_ORDER +{ + sint32 xStart; + sint32 yStart; + uint32 bRop2; + uint32 fillMode; + uint32 backColor; + uint32 foreColor; + rdpBrush brush; + uint32 nDeltaEntries; + uint32 cbData; + uint8* codeDeltaList; +}; +typedef struct _POLYGON_CB_ORDER POLYGON_CB_ORDER; + +struct _ELLIPSE_SC_ORDER +{ + sint32 leftRect; + sint32 topRect; + sint32 rightRect; + sint32 bottomRect; + uint32 bRop2; + uint32 fillMode; + uint32 color; +}; +typedef struct _ELLIPSE_SC_ORDER ELLIPSE_SC_ORDER; + +struct _ELLIPSE_CB_ORDER +{ + sint32 leftRect; + sint32 topRect; + sint32 rightRect; + sint32 bottomRect; + uint32 bRop2; + uint32 fillMode; + uint32 backColor; + uint32 foreColor; + rdpBrush brush; +}; +typedef struct _ELLIPSE_CB_ORDER ELLIPSE_CB_ORDER; + +typedef void (*pDstBlt)(rdpContext* context, DSTBLT_ORDER* dstblt); +typedef void (*pPatBlt)(rdpContext* context, PATBLT_ORDER* patblt); +typedef void (*pScrBlt)(rdpContext* context, SCRBLT_ORDER* scrblt); +typedef void (*pOpaqueRect)(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect); +typedef void (*pDrawNineGrid)(rdpContext* context, DRAW_NINE_GRID_ORDER* draw_nine_grid); +typedef void (*pMultiDstBlt)(rdpContext* context, MULTI_DSTBLT_ORDER* multi_dstblt); +typedef void (*pMultiPatBlt)(rdpContext* context, MULTI_PATBLT_ORDER* multi_patblt); +typedef void (*pMultiScrBlt)(rdpContext* context, MULTI_SCRBLT_ORDER* multi_scrblt); +typedef void (*pMultiOpaqueRect)(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); +typedef void (*pMultiDrawNineGrid)(rdpContext* context, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); +typedef void (*pLineTo)(rdpContext* context, LINE_TO_ORDER* line_to); +typedef void (*pPolyline)(rdpContext* context, POLYLINE_ORDER* polyline); +typedef void (*pMemBlt)(rdpContext* context, MEMBLT_ORDER* memblt); +typedef void (*pMem3Blt)(rdpContext* context, MEM3BLT_ORDER* memblt); +typedef void (*pSaveBitmap)(rdpContext* context, SAVE_BITMAP_ORDER* save_bitmap); +typedef void (*pGlyphIndex)(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index); +typedef void (*pFastIndex)(rdpContext* context, FAST_INDEX_ORDER* fast_index); +typedef void (*pFastGlyph)(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph); +typedef void (*pPolygonSC)(rdpContext* context, POLYGON_SC_ORDER* polygon_sc); +typedef void (*pPolygonCB)(rdpContext* context, POLYGON_CB_ORDER* polygon_cb); +typedef void (*pEllipseSC)(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc); +typedef void (*pEllipseCB)(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb); + +struct rdp_primary_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pDstBlt DstBlt; /* 16 */ + pPatBlt PatBlt; /* 17 */ + pScrBlt ScrBlt; /* 18 */ + pOpaqueRect OpaqueRect; /* 19 */ + pDrawNineGrid DrawNineGrid; /* 20 */ + pMultiDstBlt MultiDstBlt; /* 21 */ + pMultiPatBlt MultiPatBlt; /* 22 */ + pMultiScrBlt MultiScrBlt; /* 23 */ + pMultiOpaqueRect MultiOpaqueRect; /* 24 */ + pMultiDrawNineGrid MultiDrawNineGrid; /* 25 */ + pLineTo LineTo; /* 26 */ + pPolyline Polyline; /* 27 */ + pMemBlt MemBlt; /* 28 */ + pMem3Blt Mem3Blt; /* 29 */ + pSaveBitmap SaveBitmap; /* 30 */ + pGlyphIndex GlyphIndex; /* 31 */ + pFastIndex FastIndex; /* 32 */ + pFastGlyph FastGlyph; /* 33 */ + pPolygonSC PolygonSC; /* 34 */ + pPolygonCB PolygonCB; /* 35 */ + pEllipseSC EllipseSC; /* 36 */ + pEllipseCB EllipseCB; /* 37 */ + uint32 paddingB[48 - 38]; /* 38 */ + + /* internal */ + + ORDER_INFO order_info; + DSTBLT_ORDER dstblt; + PATBLT_ORDER patblt; + SCRBLT_ORDER scrblt; + OPAQUE_RECT_ORDER opaque_rect; + DRAW_NINE_GRID_ORDER draw_nine_grid; + MULTI_DSTBLT_ORDER multi_dstblt; + MULTI_PATBLT_ORDER multi_patblt; + MULTI_SCRBLT_ORDER multi_scrblt; + MULTI_OPAQUE_RECT_ORDER multi_opaque_rect; + MULTI_DRAW_NINE_GRID_ORDER multi_draw_nine_grid; + LINE_TO_ORDER line_to; + POLYLINE_ORDER polyline; + MEMBLT_ORDER memblt; + MEM3BLT_ORDER mem3blt; + SAVE_BITMAP_ORDER save_bitmap; + GLYPH_INDEX_ORDER glyph_index; + FAST_INDEX_ORDER fast_index; + FAST_GLYPH_ORDER fast_glyph; + POLYGON_SC_ORDER polygon_sc; + POLYGON_CB_ORDER polygon_cb; + ELLIPSE_SC_ORDER ellipse_sc; + ELLIPSE_CB_ORDER ellipse_cb; +}; +typedef struct rdp_primary_update rdpPrimaryUpdate; + +#endif /* __UPDATE_PRIMARY_H */ diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h new file mode 100644 index 0000000..840e7f0 --- /dev/null +++ b/include/freerdp/rail.h @@ -0,0 +1,344 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_GLOBAL_H +#define __RAIL_GLOBAL_H + +#include + +/* RAIL PDU flags */ +#define RAIL_EXEC_FLAG_EXPAND_WORKINGDIRECTORY 0x0001 +#define RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002 +#define RAIL_EXEC_FLAG_FILE 0x0004 +#define RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008 + +/* Notification Icon Balloon Tooltip */ +#define NIIF_NONE 0x00000000 +#define NIIF_INFO 0x00000001 +#define NIIF_WARNING 0x00000002 +#define NIIF_ERROR 0x00000003 +#define NIIF_NOSOUND 0x00000010 +#define NIIF_LARGE_ICON 0x00000020 + +/* Client Execute PDU Flags */ +#define RAIL_EXEC_FLAG_EXPAND_WORKING_DIRECTORY 0x0001 +#define RAIL_EXEC_FLAG_TRANSLATE_FILES 0x0002 +#define RAIL_EXEC_FLAG_FILE 0x0004 +#define RAIL_EXEC_FLAG_EXPAND_ARGUMENTS 0x0008 + +/* Server Execute Result PDU */ +#define RAIL_EXEC_S_OK 0x0000 +#define RAIL_EXEC_E_HOOK_NOT_LOADED 0x0001 +#define RAIL_EXEC_E_DECODE_FAILED 0x0002 +#define RAIL_EXEC_E_NOT_IN_ALLOWLIST 0x0003 +#define RAIL_EXEC_E_FILE_NOT_FOUND 0x0005 +#define RAIL_EXEC_E_FAIL 0x0006 +#define RAIL_EXEC_E_SESSION_LOCKED 0x0007 + +/* Client System Parameters Update PDU */ +#define SPI_SET_DRAG_FULL_WINDOWS 0x00000025 +#define SPI_SET_KEYBOARD_CUES 0x0000100B +#define SPI_SET_KEYBOARD_PREF 0x00000045 +#define SPI_SET_MOUSE_BUTTON_SWAP 0x00000021 +#define SPI_SET_WORK_AREA 0x0000002F +#define SPI_DISPLAY_CHANGE 0x0000F001 +#define SPI_TASKBAR_POS 0x0000F000 +#define SPI_SET_HIGH_CONTRAST 0x00000043 + +/* Server System Parameters Update PDU */ +#define SPI_SET_SCREEN_SAVE_ACTIVE 0x00000011 +#define SPI_SET_SCREEN_SAVE_SECURE 0x00000077 + +/*Bit mask values for SPI_ parameters*/ +enum SPI_MASK +{ + SPI_MASK_SET_DRAG_FULL_WINDOWS = 0x00000001, + SPI_MASK_SET_KEYBOARD_CUES = 0x00000002, + SPI_MASK_SET_KEYBOARD_PREF = 0x00000004, + SPI_MASK_SET_MOUSE_BUTTON_SWAP = 0x00000008, + SPI_MASK_SET_WORK_AREA = 0x00000010, + SPI_MASK_DISPLAY_CHANGE = 0x00000020, + SPI_MASK_TASKBAR_POS = 0x00000040, + SPI_MASK_SET_HIGH_CONTRAST = 0x00000080, + SPI_MASK_SET_SCREEN_SAVE_ACTIVE = 0x00000100, + SPI_MASK_SET_SET_SCREEN_SAVE_SECURE = 0x00000200 +}; + + +/* Client System Command PDU */ +#define SC_SIZE 0xF000 +#define SC_MOVE 0xF010 +#define SC_MINIMIZE 0xF020 +#define SC_MAXIMIZE 0xF030 +#define SC_CLOSE 0xF060 +#define SC_KEYMENU 0xF100 +#define SC_RESTORE 0xF120 +#define SC_DEFAULT 0xF160 + +/* Client Notify Event PDU */ +#ifndef _WIN32 +#define WM_LBUTTONDOWN 0x00000201 +#define WM_LBUTTONUP 0x00000202 +#define WM_RBUTTONDOWN 0x00000204 +#define WM_RBUTTONUP 0x00000205 +#define WM_CONTEXTMENU 0x0000007B +#define WM_LBUTTONDBLCLK 0x00000203 +#define WM_RBUTTONDBLCLK 0x00000206 + +#define NIN_SELECT 0x00000400 +#define NIN_KEYSELECT 0x00000401 +#define NIN_BALLOONSHOW 0x00000402 +#define NIN_BALLOONHIDE 0x00000403 +#define NIN_BALLOONTIMEOUT 0x00000404 +#define NIN_BALLOONUSERCLICK 0x00000405 +#endif + +/* Client Information PDU */ +#define RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE 0x00000001 +#define RAIL_CLIENTSTATUS_AUTORECONNECT 0x00000002 + +/* HIGHCONTRAST flags values */ +#define HCF_AVAILABLE 0x00000002 +#define HCF_CONFIRMHOTKEY 0x00000008 +#define HCF_HIGHCONTRASTON 0x00000001 +#define HCF_HOTKEYACTIVE 0x00000004 +#define HCF_HOTKEYAVAILABLE 0x00000040 +#define HCF_HOTKEYSOUND 0x00000010 +#define HCF_INDICATOR 0x00000020 + +/* Server Move/Size Start PDU */ +#define RAIL_WMSZ_LEFT 0x0001 +#define RAIL_WMSZ_RIGHT 0x0002 +#define RAIL_WMSZ_TOP 0x0003 +#define RAIL_WMSZ_TOPLEFT 0x0004 +#define RAIL_WMSZ_TOPRIGHT 0x0005 +#define RAIL_WMSZ_BOTTOM 0x0006 +#define RAIL_WMSZ_BOTTOMLEFT 0x0007 +#define RAIL_WMSZ_BOTTOMRIGHT 0x0008 +#define RAIL_WMSZ_MOVE 0x0009 +#define RAIL_WMSZ_KEYMOVE 0x000A +#define RAIL_WMSZ_KEYSIZE 0x000B + +/* Language Bar Information PDU */ +#define TF_SFT_SHOWNORMAL 0x00000001 +#define TF_SFT_DOCK 0x00000002 +#define TF_SFT_MINIMIZED 0x00000004 +#define TF_SFT_HIDDEN 0x00000008 +#define TF_SFT_NOTRANSPARENCY 0x00000010 +#define TF_SFT_LOWTRANSPARENCY 0x00000020 +#define TF_SFT_HIGHTRANSPARENCY 0x00000040 +#define TF_SFT_LABELS 0x00000080 +#define TF_SFT_NOLABELS 0x00000100 +#define TF_SFT_EXTRAICONSONMINIMIZED 0x00000200 +#define TF_SFT_NOEXTRAICONSONMINIMIZED 0x00000400 +#define TF_SFT_DESKBAND 0x00000800 + +struct _UNICODE_STRING +{ + uint16 length; + uint8* string; +}; +typedef struct _UNICODE_STRING UNICODE_STRING; + +struct _HIGH_CONTRAST +{ + uint32 flags; + uint32 colorSchemeLength; + UNICODE_STRING colorScheme; +}; +typedef struct _HIGH_CONTRAST HIGH_CONTRAST; + +/* RAIL Orders */ + +struct _RAIL_HANDSHAKE_ORDER +{ + uint32 buildNumber; +}; +typedef struct _RAIL_HANDSHAKE_ORDER RAIL_HANDSHAKE_ORDER; + +struct _RAIL_CLIENT_STATUS_ORDER +{ + uint32 flags; +}; +typedef struct _RAIL_CLIENT_STATUS_ORDER RAIL_CLIENT_STATUS_ORDER; + +struct _RAIL_EXEC_ORDER +{ + uint16 flags; + UNICODE_STRING exeOrFile; + UNICODE_STRING workingDir; + UNICODE_STRING arguments; +}; +typedef struct _RAIL_EXEC_ORDER RAIL_EXEC_ORDER; + +struct _RAIL_EXEC_RESULT_ORDER +{ + uint16 flags; + uint16 execResult; + uint32 rawResult; + UNICODE_STRING exeOrFile; +}; +typedef struct _RAIL_EXEC_RESULT_ORDER RAIL_EXEC_RESULT_ORDER; + +struct _RAIL_SYSPARAM_ORDER +{ + uint32 param; + uint32 params; + boolean dragFullWindows; + boolean keyboardCues; + boolean keyboardPref; + boolean mouseButtonSwap; + RECTANGLE_16 workArea; + RECTANGLE_16 displayChange; + RECTANGLE_16 taskbarPos; + HIGH_CONTRAST highContrast; + boolean setScreenSaveActive; + boolean setScreenSaveSecure; +}; +typedef struct _RAIL_SYSPARAM_ORDER RAIL_SYSPARAM_ORDER; + +struct _RAIL_ACTIVATE_ORDER +{ + uint32 windowId; + boolean enabled; +}; +typedef struct _RAIL_ACTIVATE_ORDER RAIL_ACTIVATE_ORDER; + +struct _RAIL_SYSMENU_ORDER +{ + uint32 windowId; + uint16 left; + uint16 top; +}; +typedef struct _RAIL_SYSMENU_ORDER RAIL_SYSMENU_ORDER; + +struct _RAIL_SYSCOMMAND_ORDER +{ + uint32 windowId; + uint16 command; +}; +typedef struct _RAIL_SYSCOMMAND_ORDER RAIL_SYSCOMMAND_ORDER; + +struct _RAIL_NOTIFY_EVENT_ORDER +{ + uint32 windowId; + uint32 notifyIconId; + uint32 message; +}; +typedef struct _RAIL_NOTIFY_EVENT_ORDER RAIL_NOTIFY_EVENT_ORDER; + +struct _RAIL_MINMAXINFO_ORDER +{ + uint32 windowId; + uint16 maxWidth; + uint16 maxHeight; + uint16 maxPosX; + uint16 maxPosY; + uint16 minTrackWidth; + uint16 minTrackHeight; + uint16 maxTrackWidth; + uint16 maxTrackHeight; +}; +typedef struct _RAIL_MINMAXINFO_ORDER RAIL_MINMAXINFO_ORDER; + +struct _RAIL_LOCALMOVESIZE_ORDER +{ + uint32 windowId; + boolean isMoveSizeStart; + uint16 moveSizeType; + uint16 posX; + uint16 posY; +}; +typedef struct _RAIL_LOCALMOVESIZE_ORDER RAIL_LOCALMOVESIZE_ORDER; + +struct _RAIL_WINDOWMOVE_ORDER +{ + uint32 windowId; + uint16 left; + uint16 top; + uint16 right; + uint16 bottom; +}; +typedef struct _RAIL_WINDOWMOVE_ORDER RAIL_WINDOW_MOVE_ORDER; + +struct _RAIL_GET_APPID_REQ_ORDER +{ + uint32 windowId; +}; +typedef struct _RAIL_GET_APPID_REQ_ORDER RAIL_GET_APPID_REQ_ORDER; + +struct _RAIL_GET_APPID_RESP_ORDER +{ + uint32 windowId; + UNICODE_STRING applicationId; + uint8 applicationIdBuffer[512]; +}; +typedef struct _RAIL_GET_APPID_RESP_ORDER RAIL_GET_APPID_RESP_ORDER; + +struct _RAIL_LANGBARINFO_ORDER +{ + uint32 languageBarStatus; +}; +typedef struct _RAIL_LANGBARINFO_ORDER RAIL_LANGBAR_INFO_ORDER; + +/* RAIL Constants */ + +enum RDP_RAIL_PDU_TYPE +{ + RDP_RAIL_ORDER_EXEC = 0x0001, + RDP_RAIL_ORDER_ACTIVATE = 0x0002, + RDP_RAIL_ORDER_SYSPARAM = 0x0003, + RDP_RAIL_ORDER_SYSCOMMAND = 0x0004, + RDP_RAIL_ORDER_HANDSHAKE = 0x0005, + RDP_RAIL_ORDER_NOTIFY_EVENT = 0x0006, + RDP_RAIL_ORDER_WINDOWMOVE = 0x0008, + RDP_RAIL_ORDER_LOCALMOVESIZE = 0x0009, + RDP_RAIL_ORDER_MINMAXINFO = 0x000A, + RDP_RAIL_ORDER_CLIENTSTATUS = 0x000B, + RDP_RAIL_ORDER_SYSMENU = 0x000C, + RDP_RAIL_ORDER_LANGBARINFO = 0x000D, + RDP_RAIL_ORDER_EXEC_RESULT = 0x0080, + RDP_RAIL_ORDER_GET_APPID_REQ = 0x000E, + RDP_RAIL_ORDER_GET_APPID_RESP = 0x000F +}; + +enum RDP_EVENT_TYPE_RAIL +{ + RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS = 1, + RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO, + RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE, + RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP, + RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO, + + RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, + RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP, + RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, + RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU, + RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, + RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT, + RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, + RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ, + RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO +}; + +#endif /* __RAIL_GLOBAL_H */ + diff --git a/include/freerdp/rail/icon.h b/include/freerdp/rail/icon.h new file mode 100644 index 0000000..448434b --- /dev/null +++ b/include/freerdp/rail/icon.h @@ -0,0 +1,61 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Window Icon Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_ICON_CACHE_H +#define __RAIL_ICON_CACHE_H + +#include +#include +#include +#include +#include + +typedef struct rdp_icon rdpIcon; +typedef struct rdp_icon_cache rdpIconCache; + +#include + +struct rdp_icon +{ + ICON_INFO* entry; + boolean big; + void* extra; +}; + +struct _WINDOW_ICON_CACHE +{ + rdpIcon* entries; +}; +typedef struct _WINDOW_ICON_CACHE WINDOW_ICON_CACHE; + +struct rdp_icon_cache +{ + rdpRail* rail; + uint8 numCaches; + uint16 numCacheEntries; + WINDOW_ICON_CACHE* caches; +}; + +ICON_INFO* icon_cache_get(rdpIconCache* cache, uint8 id, uint16 index, void** extra); +void icon_cache_put(rdpIconCache* cache, uint8 id, uint16 index, ICON_INFO* entry, void* extra); + +rdpIconCache* icon_cache_new(rdpRail* rail); +void icon_cache_free(rdpIconCache* cache); + +#endif /* __RAIL_ICON_H */ diff --git a/include/freerdp/rail/rail.h b/include/freerdp/rail/rail.h new file mode 100644 index 0000000..a5b4f54 --- /dev/null +++ b/include/freerdp/rail/rail.h @@ -0,0 +1,67 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_H +#define __RAIL_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +typedef void (*railCreateWindow)(rdpRail* rail, rdpWindow* window); +typedef void (*railDestroyWindow)(rdpRail* rail, rdpWindow* window); +typedef void (*railMoveWindow)(rdpRail* rail, rdpWindow* window); +typedef void (*railShowWindow)(rdpRail* rail, rdpWindow* window, uint8 state); +typedef void (*railSetWindowText)(rdpRail* rail, rdpWindow* window); +typedef void (*railSetWindowIcon)(rdpRail* rail, rdpWindow* window, rdpIcon* icon); +typedef void (*railSetWindowRects)(rdpRail* rail, rdpWindow* window); +typedef void (*railSetWindowVisibilityRects)(rdpRail* rail, rdpWindow* window); + +struct rdp_rail +{ + void* extra; + UNICONV* uniconv; + CLRCONV* clrconv; + rdpIconCache* cache; + rdpWindowList* list; + rdpSettings* settings; + railCreateWindow rail_CreateWindow; + railDestroyWindow rail_DestroyWindow; + railMoveWindow rail_MoveWindow; + railShowWindow rail_ShowWindow; + railSetWindowText rail_SetWindowText; + railSetWindowIcon rail_SetWindowIcon; + railSetWindowRects rail_SetWindowRects; + railSetWindowVisibilityRects rail_SetWindowVisibilityRects; +}; + +FREERDP_API void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update); + +FREERDP_API rdpRail* rail_new(rdpSettings* settings); +FREERDP_API void rail_free(rdpRail* rail); + +#endif /* __RAIL_H */ diff --git a/include/freerdp/rail/window.h b/include/freerdp/rail/window.h new file mode 100644 index 0000000..43444bb --- /dev/null +++ b/include/freerdp/rail/window.h @@ -0,0 +1,77 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_WINDOW_H +#define __RAIL_WINDOW_H + +#include +#include +#include +#include +#include + +typedef struct rdp_window rdpWindow; + +#include +#include + +struct rdp_window +{ + void* extra; + void* extraId; + char* title; + rdpIcon* bigIcon; + rdpIcon* smallIcon; + uint32 fieldFlags; + rdpWindow* prev; + rdpWindow* next; + uint32 windowId; + uint32 ownerWindowId; + rdpWindow* ownerWindow; + uint32 style; + uint32 extendedStyle; + uint8 showState; + UNICODE_STRING titleInfo; + uint32 clientOffsetX; + uint32 clientOffsetY; + uint32 clientAreaWidth; + uint32 clientAreaHeight; + uint8 RPContent; + uint32 rootParentHandle; + sint32 windowOffsetX; + sint32 windowOffsetY; + uint32 windowClientDeltaX; + uint32 windowClientDeltaY; + uint32 windowWidth; + uint32 windowHeight; + uint16 numWindowRects; + RECTANGLE_16* windowRects; + uint32 visibleOffsetX; + uint32 visibleOffsetY; + uint16 numVisibilityRects; + RECTANGLE_16* visibilityRects; +}; + +FREERDP_API void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); + +FREERDP_API void rail_CreateWindow(rdpRail* rail, rdpWindow* window); +FREERDP_API void rail_UpdateWindow(rdpRail* rail, rdpWindow* window); +FREERDP_API void rail_DestroyWindow(rdpRail* rail, rdpWindow* window); + +#endif /* __RAIL_WINDOW_H */ diff --git a/include/freerdp/rail/window_list.h b/include/freerdp/rail/window_list.h new file mode 100644 index 0000000..82914a4 --- /dev/null +++ b/include/freerdp/rail/window_list.h @@ -0,0 +1,55 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Window List + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_WINDOW_LIST_H +#define __RAIL_WINDOW_LIST_H + +#include +#include +#include +#include + +typedef struct rdp_window_list rdpWindowList; + +#include +#include + +struct rdp_window_list +{ + rdpRail* rail; + rdpWindow* head; + rdpWindow* tail; + rdpWindow* iterator; +}; + +FREERDP_API void window_list_rewind(rdpWindowList* list); +FREERDP_API boolean window_list_has_next(rdpWindowList* list); +FREERDP_API rdpWindow* window_list_get_next(rdpWindowList* list); + +FREERDP_API rdpWindow* window_list_get_by_id(rdpWindowList* list, uint32 windowId); +FREERDP_API rdpWindow* window_list_get_by_extra_id(rdpWindowList* list, void* extraId); + +FREERDP_API void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +FREERDP_API void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +FREERDP_API void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo); + +FREERDP_API rdpWindowList* window_list_new(rdpRail* rail); +FREERDP_API void window_list_free(rdpWindowList* list); + +#endif /* __RAIL_WINDOW_LIST_H */ diff --git a/include/freerdp/secondary.h b/include/freerdp/secondary.h new file mode 100644 index 0000000..5bf09b0 --- /dev/null +++ b/include/freerdp/secondary.h @@ -0,0 +1,224 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Secondary Drawing Orders Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_SECONDARY_H +#define __UPDATE_SECONDARY_H + +#include + +#define GLYPH_FRAGMENT_NOP 0x00 +#define GLYPH_FRAGMENT_USE 0xFE +#define GLYPH_FRAGMENT_ADD 0xFF + +#define CBR2_HEIGHT_SAME_AS_WIDTH 0x01 +#define CBR2_PERSISTENT_KEY_PRESENT 0x02 +#define CBR2_NO_BITMAP_COMPRESSION_HDR 0x08 +#define CBR2_DO_NOT_CACHE 0x10 + +#define SCREEN_BITMAP_SURFACE 0xFFFF +#define BITMAP_CACHE_WAITING_LIST_INDEX 0x7FFF + +#define CACHED_BRUSH 0x80 + +#define BMF_1BPP 0x1 +#define BMF_8BPP 0x3 +#define BMF_16BPP 0x4 +#define BMF_24BPP 0x5 +#define BMF_32BPP 0x6 + +#ifndef _WIN32 +#define BS_SOLID 0x00 +#define BS_NULL 0x01 +#define BS_HATCHED 0x02 +#define BS_PATTERN 0x03 +#endif + +#ifndef _WIN32 +#define HS_HORIZONTAL 0x00 +#define HS_VERTICAL 0x01 +#define HS_FDIAGONAL 0x02 +#define HS_BDIAGONAL 0x03 +#define HS_CROSS 0x04 +#define HS_DIAGCROSS 0x05 +#endif + +#define SO_FLAG_DEFAULT_PLACEMENT 0x01 +#define SO_HORIZONTAL 0x02 +#define SO_VERTICAL 0x04 +#define SO_REVERSED 0x08 +#define SO_ZERO_BEARINGS 0x10 +#define SO_CHAR_INC_EQUAL_BM_BASE 0x20 +#define SO_MAXEXT_EQUAL_BM_SIDE 0x40 + +struct _CACHE_BITMAP_ORDER +{ + uint32 cacheId; + uint32 bitmapBpp; + uint32 bitmapWidth; + uint32 bitmapHeight; + uint32 bitmapLength; + uint32 cacheIndex; + boolean compressed; + uint8 bitmapComprHdr[8]; + uint8* bitmapDataStream; +}; +typedef struct _CACHE_BITMAP_ORDER CACHE_BITMAP_ORDER; + +struct _CACHE_BITMAP_V2_ORDER +{ + uint32 cacheId; + uint32 flags; + uint32 key1; + uint32 key2; + uint32 bitmapBpp; + uint32 bitmapWidth; + uint32 bitmapHeight; + uint32 bitmapLength; + uint32 cacheIndex; + boolean compressed; + uint32 cbCompFirstRowSize; + uint32 cbCompMainBodySize; + uint32 cbScanWidth; + uint32 cbUncompressedSize; + uint8* bitmapDataStream; +}; +typedef struct _CACHE_BITMAP_V2_ORDER CACHE_BITMAP_V2_ORDER; + +struct _BITMAP_DATA_EX +{ + uint32 bpp; + uint32 codecID; + uint32 width; + uint32 height; + uint32 length; + uint8* data; +}; +typedef struct _BITMAP_DATA_EX BITMAP_DATA_EX; + +struct _CACHE_BITMAP_V3_ORDER +{ + uint32 cacheId; + uint32 bpp; + uint32 flags; + uint32 cacheIndex; + uint32 key1; + uint32 key2; + BITMAP_DATA_EX bitmapData; +}; +typedef struct _CACHE_BITMAP_V3_ORDER CACHE_BITMAP_V3_ORDER; + +struct _CACHE_COLOR_TABLE_ORDER +{ + uint32 cacheIndex; + uint32 numberColors; + uint32* colorTable; +}; +typedef struct _CACHE_COLOR_TABLE_ORDER CACHE_COLOR_TABLE_ORDER; + +struct _GLYPH_DATA +{ + uint32 cacheIndex; + sint32 x; + sint32 y; + uint32 cx; + uint32 cy; + uint32 cb; + uint8* aj; +}; +typedef struct _GLYPH_DATA GLYPH_DATA; + +struct _CACHE_GLYPH_ORDER +{ + uint32 cacheId; + uint32 cGlyphs; + GLYPH_DATA* glyphData[255]; + uint8* unicodeCharacters; +}; +typedef struct _CACHE_GLYPH_ORDER CACHE_GLYPH_ORDER; + +struct _GLYPH_DATA_V2 +{ + uint32 cacheIndex; + sint32 x; + sint32 y; + uint32 cx; + uint32 cy; + uint32 cb; + uint8* aj; +}; +typedef struct _GLYPH_DATA_V2 GLYPH_DATA_V2; + +struct _CACHE_GLYPH_V2_ORDER +{ + uint32 cacheId; + uint32 flags; + uint32 cGlyphs; + GLYPH_DATA_V2* glyphData[255]; + uint8* unicodeCharacters; +}; +typedef struct _CACHE_GLYPH_V2_ORDER CACHE_GLYPH_V2_ORDER; + +struct _CACHE_BRUSH_ORDER +{ + uint32 index; + uint32 bpp; + uint32 cx; + uint32 cy; + uint32 style; + uint32 length; + uint8* data; +}; +typedef struct _CACHE_BRUSH_ORDER CACHE_BRUSH_ORDER; + +typedef void (*pCacheBitmap)(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap_order); +typedef void (*pCacheBitmapV2)(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order); +typedef void (*pCacheBitmapV3)(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order); +typedef void (*pCacheColorTable)(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table_order); +typedef void (*pCacheGlyph)(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph_order); +typedef void (*pCacheGlyphV2)(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order); +typedef void (*pCacheBrush)(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush_order); + +struct rdp_secondary_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pCacheBitmap CacheBitmap; /* 16 */ + pCacheBitmapV2 CacheBitmapV2; /* 17 */ + pCacheBitmapV3 CacheBitmapV3; /* 18 */ + pCacheColorTable CacheColorTable; /* 19 */ + pCacheGlyph CacheGlyph; /* 20 */ + pCacheGlyphV2 CacheGlyphV2; /* 21 */ + pCacheBrush CacheBrush; /* 22 */ + uint32 paddingE[32 - 23]; /* 23 */ + + /* internal */ + + boolean glyph_v2; + CACHE_BITMAP_ORDER cache_bitmap_order; + CACHE_BITMAP_V2_ORDER cache_bitmap_v2_order; + CACHE_BITMAP_V3_ORDER cache_bitmap_v3_order; + CACHE_COLOR_TABLE_ORDER cache_color_table_order; + CACHE_GLYPH_ORDER cache_glyph_order; + CACHE_GLYPH_V2_ORDER cache_glyph_v2_order; + CACHE_BRUSH_ORDER cache_brush_order; +}; +typedef struct rdp_secondary_update rdpSecondaryUpdate; + +#endif /* __UPDATE_SECONDARY_H */ diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h new file mode 100644 index 0000000..5a9acd8 --- /dev/null +++ b/include/freerdp/settings.h @@ -0,0 +1,446 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Settings + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDP_SETTINGS_H +#define __RDP_SETTINGS_H + +#include +#include +#include + +/* Performance Flags */ +#define PERF_FLAG_NONE 0x00000000 +#define PERF_DISABLE_WALLPAPER 0x00000001 +#define PERF_DISABLE_FULLWINDOWDRAG 0x00000002 +#define PERF_DISABLE_MENUANIMATIONS 0x00000004 +#define PERF_DISABLE_THEMING 0x00000008 +#define PERF_DISABLE_CURSOR_SHADOW 0x00000020 +#define PERF_DISABLE_CURSORSETTINGS 0x00000040 +#define PERF_ENABLE_FONT_SMOOTHING 0x00000080 +#define PERF_ENABLE_DESKTOP_COMPOSITION 0x00000100 + +/* Connection Types */ +#define CONNECTION_TYPE_MODEM 0x01 +#define CONNECTION_TYPE_BROADBAND_LOW 0x02 +#define CONNECTION_TYPE_SATELLITE 0x03 +#define CONNECTION_TYPE_BROADBAND_HIGH 0x04 +#define CONNECTION_TYPE_WAN 0x05 +#define CONNECTION_TYPE_LAN 0x06 + +/* Encryption Methods */ +#define ENCRYPTION_METHOD_NONE 0x00000000 +#define ENCRYPTION_METHOD_40BIT 0x00000001 +#define ENCRYPTION_METHOD_128BIT 0x00000002 +#define ENCRYPTION_METHOD_56BIT 0x00000008 +#define ENCRYPTION_METHOD_FIPS 0x00000010 + +/* Encryption Levels */ +#define ENCRYPTION_LEVEL_NONE 0x00000000 +#define ENCRYPTION_LEVEL_LOW 0x00000001 +#define ENCRYPTION_LEVEL_CLIENT_COMPATIBLE 0x00000002 +#define ENCRYPTION_LEVEL_HIGH 0x00000003 +#define ENCRYPTION_LEVEL_FIPS 0x00000004 + +/* Auto Reconnect Version */ +#define AUTO_RECONNECT_VERSION_1 0x00000001 + +/* Order Support */ +#define NEG_DSTBLT_INDEX 0x00 +#define NEG_PATBLT_INDEX 0x01 +#define NEG_SCRBLT_INDEX 0x02 +#define NEG_MEMBLT_INDEX 0x03 +#define NEG_MEM3BLT_INDEX 0x04 +#define NEG_ATEXTOUT_INDEX 0x05 +#define NEG_AEXTTEXTOUT_INDEX 0x06 +#define NEG_DRAWNINEGRID_INDEX 0x07 +#define NEG_LINETO_INDEX 0x08 +#define NEG_MULTI_DRAWNINEGRID_INDEX 0x09 +#define NEG_OPAQUE_RECT_INDEX 0x0A +#define NEG_SAVEBITMAP_INDEX 0x0B +#define NEG_WTEXTOUT_INDEX 0x0C +#define NEG_MEMBLT_V2_INDEX 0x0D +#define NEG_MEM3BLT_V2_INDEX 0x0E +#define NEG_MULTIDSTBLT_INDEX 0x0F +#define NEG_MULTIPATBLT_INDEX 0x10 +#define NEG_MULTISCRBLT_INDEX 0x11 +#define NEG_MULTIOPAQUERECT_INDEX 0x12 +#define NEG_FAST_INDEX_INDEX 0x13 +#define NEG_POLYGON_SC_INDEX 0x14 +#define NEG_POLYGON_CB_INDEX 0x15 +#define NEG_POLYLINE_INDEX 0x16 +#define NEG_FAST_GLYPH_INDEX 0x18 +#define NEG_ELLIPSE_SC_INDEX 0x19 +#define NEG_ELLIPSE_CB_INDEX 0x1A +#define NEG_GLYPH_INDEX_INDEX 0x1B +#define NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C +#define NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D +#define NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E + +/* Glyph Support Level */ +#define GLYPH_SUPPORT_NONE 0x0000 +#define GLYPH_SUPPORT_PARTIAL 0x0001 +#define GLYPH_SUPPORT_FULL 0x0002 +#define GLYPH_SUPPORT_ENCODE 0x0003 + +/* SYSTEM_TIME */ +typedef struct +{ + uint16 wYear; + uint16 wMonth; + uint16 wDayOfWeek; + uint16 wDay; + uint16 wHour; + uint16 wMinute; + uint16 wSecond; + uint16 wMilliseconds; +} SYSTEM_TIME; + +/* TIME_ZONE_INFORMATION */ +struct _TIME_ZONE_INFO +{ + uint32 bias; + char standardName[32]; + SYSTEM_TIME standardDate; + uint32 standardBias; + char daylightName[32]; + SYSTEM_TIME daylightDate; + uint32 daylightBias; +}; +typedef struct _TIME_ZONE_INFO TIME_ZONE_INFO; + +/* ARC_CS_PRIVATE_PACKET */ +typedef struct +{ + uint32 cbLen; + uint32 version; + uint32 logonId; + uint8 securityVerifier[16]; +} ARC_CS_PRIVATE_PACKET; + +/* ARC_SC_PRIVATE_PACKET */ +typedef struct +{ + uint32 cbLen; + uint32 version; + uint32 logonId; + uint8 arcRandomBits[16]; +} ARC_SC_PRIVATE_PACKET; + +/* Certificates */ + +typedef struct rdp_certificate rdpCertificate; +typedef struct rdp_key rdpKey; + +struct rdp_CertBlob +{ + uint32 length; + uint8* data; +}; +typedef struct rdp_CertBlob rdpCertBlob; + +struct rdp_X509CertChain +{ + uint32 count; + rdpCertBlob* array; +}; +typedef struct rdp_X509CertChain rdpX509CertChain; + +struct rdp_CertInfo +{ + rdpBlob modulus; + uint8 exponent[4]; +}; +typedef struct rdp_CertInfo rdpCertInfo; + +struct rdp_certificate +{ + rdpCertInfo cert_info; + rdpX509CertChain* x509_cert_chain; +}; + +/* Channels */ + +struct rdp_channel +{ + char name[8]; /* ui sets */ + int options; /* ui sets */ + int channel_id; /* core sets */ + boolean joined; /* client has joined the channel */ + void* handle; /* just for ui */ +}; +typedef struct rdp_channel rdpChannel; + +/* Extensions */ + +struct rdp_ext_set +{ + char name[256]; /* plugin name or path */ + void* data; /* plugin data */ +}; + +/* Bitmap Cache */ + +struct _BITMAP_CACHE_CELL_INFO +{ + uint16 numEntries; + uint16 maxSize; +}; +typedef struct _BITMAP_CACHE_CELL_INFO BITMAP_CACHE_CELL_INFO; + +struct _BITMAP_CACHE_V2_CELL_INFO +{ + uint32 numEntries; + boolean persistent; +}; +typedef struct _BITMAP_CACHE_V2_CELL_INFO BITMAP_CACHE_V2_CELL_INFO; + +/* Glyph Cache */ + +struct _GLYPH_CACHE_DEFINITION +{ + uint16 cacheEntries; + uint16 cacheMaximumCellSize; +}; +typedef struct _GLYPH_CACHE_DEFINITION GLYPH_CACHE_DEFINITION; + +/* Monitors */ + +struct rdp_monitor +{ + int x; + int y; + int width; + int height; + int is_primary; +}; + +/* Settings */ + +struct rdp_settings +{ + void* instance; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + /* Core Protocol Parameters */ + uint32 width; /* 16 */ + uint32 height; /* 17 */ + uint32 rdp_version; /* 18 */ + uint32 color_depth; /* 19 */ + uint32 kbd_layout; /* 20 */ + uint32 kbd_type; /* 21 */ + uint32 kbd_subtype; /* 22 */ + uint32 kbd_fn_keys; /* 23 */ + uint32 client_build; /* 24 */ + uint32 requested_protocols; /* 25 */ + uint32 selected_protocol; /* 26 */ + uint32 encryption_method; /* 27 */ + uint32 encryption_level; /* 28 */ + boolean authentication; /* 29 */ + uint32 negotiationFlags; /* 30 */ + uint32 paddingB[48 - 31]; /* 31 */ + + /* Connection Settings */ + uint32 port; /* 48 */ + boolean ipv6; /* 49 */ + char* hostname; /* 50 */ + char* username; /* 51 */ + char* password; /* 52 */ + char* domain; /* 53 */ + char* shell; /* 54 */ + char* directory; /* 55 */ + char* ip_address; /* 56 */ + char* client_dir; /* 57 */ + boolean autologon; /* 58 */ + boolean compression; /* 59 */ + uint32 performance_flags; /* 60 */ + rdpBlob* password_cookie; /* 61 */ + uint32 paddingC[80 - 62]; /* 62 */ + + /* User Interface Parameters */ + boolean sw_gdi; /* 80 */ + boolean workarea; /* 81 */ + boolean fullscreen; /* 82 */ + boolean grab_keyboard; /* 83 */ + boolean decorations; /* 84 */ + uint32 percent_screen; /* 85 */ + boolean mouse_motion; /* 86 */ + char* window_title; /* 87 */ + uint64 parent_window_xid; /* 88 */ + uint32 paddingD[112 - 89]; /* 89 */ + + /* Internal Parameters */ + char* home_path; /* 112 */ + uint32 share_id; /* 113 */ + uint32 pdu_source; /* 114 */ + UNICONV* uniconv; /* 115 */ + boolean server_mode; /* 116 */ + char* config_path; /* 117 */ + char* current_path; /* 118 */ + char* development_path; /* 119 */ + boolean development_mode; /* 120 */ + uint32 paddingE[144 - 121]; /* 121 */ + + /* Security */ + boolean encryption; /* 144 */ + boolean tls_security; /* 145 */ + boolean nla_security; /* 146 */ + boolean rdp_security; /* 147 */ + uint32 ntlm_version; /* 148 */ + boolean secure_checksum; /* 149 */ + uint32 paddingF[160 - 150]; /* 150 */ + + /* Session */ + boolean console_audio; /* 160 */ + boolean console_session; /* 161 */ + uint32 redirected_session_id; /* 162 */ + uint32 paddingG[176 - 163]; /* 163 */ + + /* Output Control */ + boolean refresh_rect; /* 176 */ + boolean suppress_output; /* 177 */ + boolean desktop_resize; /* 178 */ + uint32 paddingH[192 - 179]; /* 179 */ + + /* Reconnection */ + boolean auto_reconnection; /* 192 */ + ARC_CS_PRIVATE_PACKET* client_auto_reconnect_cookie; /* 193 */ + ARC_SC_PRIVATE_PACKET* server_auto_reconnect_cookie; /* 194 */ + uint32 paddingI[208 - 195]; /* 195 */ + + /* Time Zone */ + TIME_ZONE_INFO* client_time_zone; /* 208 */ + uint32 paddingJ[216 - 209]; /* 209 */ + + /* Capabilities */ + uint32 os_major_type; /* 216 */ + uint32 os_minor_type; /* 217 */ + uint32 vc_chunk_size; /* 218 */ + boolean sound_beeps; /* 219 */ + boolean smooth_fonts; /* 220 */ + boolean frame_marker; /* 221 */ + boolean fastpath_input; /* 222 */ + boolean fastpath_output; /* 223 */ + uint8 received_caps[32]; /* 224 (8) */ + uint8 order_support[32]; /* 232 (8) */ + boolean surface_commands; /* 240 */ + boolean disable_wallpaper; /* 241 */ + boolean disable_full_window_drag; /* 242 */ + boolean disable_menu_animations; /* 243 */ + boolean disable_theming; /* 244 */ + uint32 connection_type; /* 245 */ + uint32 multifrag_max_request_size; /* 246 */ + uint32 paddingK[248 - 247]; /* 247 */ + + /* Certificate */ + char* cert_file; /* 248 */ + char* privatekey_file; /* 249 */ + char client_hostname[32]; /* 250 (8) */ + char client_product_id[32]; /* 258 (8) */ + rdpBlob* server_random; /* 266 */ + rdpBlob* server_certificate; /* 267 */ + boolean ignore_certificate; /* 268 */ + rdpCertificate* server_cert; /* 269 */ + char* rdp_key_file; /* 270 */ + rdpKey* server_key; /* 271 */ + char* certificate_name; /* 272 */ + uint32 paddingL[280 - 273]; /* 273 */ + + /* Codecs */ + boolean rfx_codec; /* 280 */ + boolean ns_codec; /* 281 */ + uint32 rfx_codec_id; /* 282 */ + uint32 ns_codec_id; /* 283 */ + uint32 rfx_codec_mode; /* 284 */ + boolean frame_acknowledge; /* 285 */ + uint32 paddingM[296 - 286]; /* 286 */ + + /* Recording */ + boolean dump_rfx; /* 296 */ + boolean play_rfx; /* 297 */ + char* dump_rfx_file; /* 298 */ + char* play_rfx_file; /* 299 */ + uint32 paddingN[312 - 300]; /* 300 */ + + /* RemoteApp */ + boolean remote_app; /* 312 */ + uint32 num_icon_caches; /* 313 */ + uint32 num_icon_cache_entries; /* 314 */ + boolean rail_langbar_supported; /* 315 */ + uint32 paddingO[320 - 316]; /* 316 */ + + /* Pointer */ + boolean large_pointer; /* 320 */ + boolean color_pointer; /* 321 */ + uint32 pointer_cache_size; /* 322 */ + uint32 paddingP[328 - 323]; /* 323 */ + + /* Bitmap Cache */ + boolean bitmap_cache; /* 328 */ + boolean bitmap_cache_v3; /* 329 */ + boolean persistent_bitmap_cache; /* 330 */ + uint32 bitmapCacheV2NumCells; /* 331 */ + BITMAP_CACHE_V2_CELL_INFO* bitmapCacheV2CellInfo; /* 332 */ + uint32 paddingQ[344 - 333]; /* 333 */ + + /* Offscreen Bitmap Cache */ + boolean offscreen_bitmap_cache; /* 344 */ + uint32 offscreen_bitmap_cache_size; /* 345 */ + uint32 offscreen_bitmap_cache_entries; /* 346 */ + uint32 paddingR[352 - 347]; /* 347 */ + + /* Glyph Cache */ + boolean glyph_cache; /* 352 */ + uint32 glyphSupportLevel; /* 353 */ + GLYPH_CACHE_DEFINITION* glyphCache; /* 354 */ + GLYPH_CACHE_DEFINITION* fragCache; /* 355 */ + uint32 paddingS[360 - 356]; /* 356 */ + + /* Draw Nine Grid */ + boolean draw_nine_grid; /* 360 */ + uint32 draw_nine_grid_cache_size; /* 361 */ + uint32 draw_nine_grid_cache_entries; /* 362 */ + uint32 paddingT[368 - 363]; /* 363 */ + + /* Draw GDI+ */ + boolean draw_gdi_plus; /* 368 */ + boolean draw_gdi_plus_cache; /* 369 */ + uint32 paddingU[376 - 370]; /* 370 */ + + /* Desktop Composition */ + boolean desktop_composition; /* 376 */ + uint32 paddingV[384 - 377]; /* 377 */ + + /* Channels */ + int num_channels; + rdpChannel channels[16]; + + /* Monitors */ + int num_monitors; + struct rdp_monitor monitors[16]; + + /* Extensions */ + int num_extensions; + struct rdp_ext_set extensions[16]; +}; +typedef struct rdp_settings rdpSettings; + +rdpSettings* settings_new(void* instance); +void settings_free(rdpSettings* settings); + +#endif /* __RDP_SETTINGS_H */ diff --git a/include/freerdp/svc.h b/include/freerdp/svc.h new file mode 100644 index 0000000..1c3e347 --- /dev/null +++ b/include/freerdp/svc.h @@ -0,0 +1,116 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Static Virtual Channel Interface + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * MS compatible SVC plugin interface + * reference: + * http://msdn.microsoft.com/en-us/library/aa383580.aspx + */ + +#ifndef __FREERDP_SVC_H +#define __FREERDP_SVC_H + +#include +#include + +#define CHANNEL_EXPORT_FUNC_NAME "VirtualChannelEntry" + +#define CHANNEL_NAME_LEN 7 + +struct _CHANNEL_DEF +{ + char name[CHANNEL_NAME_LEN + 1]; + uint32 options; +}; +typedef struct _CHANNEL_DEF CHANNEL_DEF; +typedef CHANNEL_DEF* PCHANNEL_DEF; +typedef CHANNEL_DEF** PPCHANNEL_DEF; + +typedef void (FREERDP_CC * PCHANNEL_INIT_EVENT_FN)(void* pInitHandle, + uint32 event, void* pData, uint32 dataLength); + + +typedef void (FREERDP_CC * PCHANNEL_OPEN_EVENT_FN)(uint32 openHandle, + uint32 event, void* pData, uint32 dataLength, + uint32 totalLength, uint32 dataFlags); + +#define CHANNEL_RC_OK 0 +#define CHANNEL_RC_ALREADY_INITIALIZED 1 +#define CHANNEL_RC_NOT_INITIALIZED 2 +#define CHANNEL_RC_ALREADY_CONNECTED 3 +#define CHANNEL_RC_NOT_CONNECTED 4 +#define CHANNEL_RC_TOO_MANY_CHANNELS 5 +#define CHANNEL_RC_BAD_CHANNEL 6 +#define CHANNEL_RC_BAD_CHANNEL_HANDLE 7 +#define CHANNEL_RC_NO_BUFFER 8 +#define CHANNEL_RC_BAD_INIT_HANDLE 9 +#define CHANNEL_RC_NOT_OPEN 10 +#define CHANNEL_RC_BAD_PROC 11 +#define CHANNEL_RC_NO_MEMORY 12 +#define CHANNEL_RC_UNKNOWN_CHANNEL_NAME 13 +#define CHANNEL_RC_ALREADY_OPEN 14 +#define CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY 15 +#define CHANNEL_RC_NULL_DATA 16 +#define CHANNEL_RC_ZERO_LENGTH 17 + +#define VIRTUAL_CHANNEL_VERSION_WIN2000 1 + +typedef uint32 (FREERDP_CC * PVIRTUALCHANNELINIT)(void** ppInitHandle, + PCHANNEL_DEF pChannel, int channelCount, uint32 versionRequested, + PCHANNEL_INIT_EVENT_FN pChannelInitEventProc); +typedef uint32 (FREERDP_CC * PVIRTUALCHANNELOPEN)(void* pInitHandle, + uint32* pOpenHandle, char* pChannelName, + PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc); +typedef uint32 (FREERDP_CC * PVIRTUALCHANNELCLOSE)(uint32 openHandle); + +typedef uint32 (FREERDP_CC * PVIRTUALCHANNELWRITE)(uint32 openHandle, + void* pData, uint32 dataLength, void* pUserData); + +typedef uint32 (FREERDP_CC * PVIRTUALCHANNELEVENTPUSH)(uint32 openHandle, + RDP_EVENT* event); + +struct _CHANNEL_ENTRY_POINTS +{ + uint32 cbSize; + uint32 protocolVersion; + PVIRTUALCHANNELINIT pVirtualChannelInit; + PVIRTUALCHANNELOPEN pVirtualChannelOpen; + PVIRTUALCHANNELCLOSE pVirtualChannelClose; + PVIRTUALCHANNELWRITE pVirtualChannelWrite; +}; +typedef struct _CHANNEL_ENTRY_POINTS CHANNEL_ENTRY_POINTS; +typedef CHANNEL_ENTRY_POINTS* PCHANNEL_ENTRY_POINTS; + +typedef int (FREERDP_CC * PVIRTUALCHANNELENTRY)(PCHANNEL_ENTRY_POINTS pEntryPoints); + +struct _CHANNEL_ENTRY_POINTS_EX +{ + uint32 cbSize; + uint32 protocolVersion; + PVIRTUALCHANNELINIT pVirtualChannelInit; + PVIRTUALCHANNELOPEN pVirtualChannelOpen; + PVIRTUALCHANNELCLOSE pVirtualChannelClose; + PVIRTUALCHANNELWRITE pVirtualChannelWrite; + void* pExtendedData; /* extended data field to pass initial parameters */ + PVIRTUALCHANNELEVENTPUSH pVirtualChannelEventPush; +}; +typedef struct _CHANNEL_ENTRY_POINTS_EX CHANNEL_ENTRY_POINTS_EX; +typedef CHANNEL_ENTRY_POINTS_EX* PCHANNEL_ENTRY_POINTS_EX; + +#endif diff --git a/include/freerdp/types.h b/include/freerdp/types.h new file mode 100644 index 0000000..feed3fd --- /dev/null +++ b/include/freerdp/types.h @@ -0,0 +1,164 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Type Definitions + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDP_TYPES_H +#define __RDP_TYPES_H + +#ifdef _WIN32 +#include +#endif + +/* Base Types */ + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef HAVE_STDINT_H +#include +#endif + +#ifdef HAVE_INTTYPES_H + +#include +typedef uint8_t uint8; +typedef int8_t sint8; +typedef uint16_t uint16; +typedef int16_t sint16; +typedef uint32_t uint32; +typedef int32_t sint32; +typedef uint64_t uint64; +typedef int64_t sint64; + +#else + +typedef unsigned char uint8; +typedef signed char sint8; +typedef unsigned short uint16; +typedef signed short sint16; +typedef unsigned int uint32; +typedef signed int sint32; +#ifdef _WIN32 +typedef unsigned __int64 uint64; +typedef signed __int64 sint64; +#else +typedef unsigned long long uint64; +typedef signed long long sint64; +#endif + +#endif /* HAVE_INTTYPES_H */ + +#ifdef HAVE_STDBOOL_H + +#include + +typedef int boolean; + +#else + +#ifndef __cplusplus + +#ifndef __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 + +#define true 1 +#define false 0 + +#ifdef _WIN32 +#define boolean BOOLEAN +#else +typedef int boolean; +#endif + +#endif /* __bool_true_false_are_defined */ + +#else + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +typedef int boolean; + +#endif /* __cplusplus */ + +#endif /* HAVE_STDBOOL_H */ + +#ifndef MIN +#define MIN(x,y) (((x) < (y)) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) +#endif + +#include + +struct _RDP_PLUGIN_DATA +{ + uint16 size; + void* data[4]; +}; +typedef struct _RDP_PLUGIN_DATA RDP_PLUGIN_DATA; + +struct _RDP_RECT +{ + sint16 x; + sint16 y; + sint16 width; + sint16 height; +}; +typedef struct _RDP_RECT RDP_RECT; + +struct _RECTANGLE_16 +{ + uint16 left; + uint16 top; + uint16 right; + uint16 bottom; +}; +typedef struct _RECTANGLE_16 RECTANGLE_16; + +/* Plugin events */ +typedef struct _RDP_EVENT RDP_EVENT; + +typedef void (*RDP_EVENT_CALLBACK) (RDP_EVENT* event); + +struct _RDP_EVENT +{ + uint16 event_class; + uint16 event_type; + RDP_EVENT_CALLBACK on_event_free_callback; + void* user_data; +}; + +enum RDP_EVENT_CLASS +{ + RDP_EVENT_CLASS_DEBUG = 0, + RDP_EVENT_CLASS_CLIPRDR, + RDP_EVENT_CLASS_TSMF, + RDP_EVENT_CLASS_RAIL +}; + +#endif /* __RDP_TYPES_H */ diff --git a/include/freerdp/update.h b/include/freerdp/update.h new file mode 100644 index 0000000..c4c9afe --- /dev/null +++ b/include/freerdp/update.h @@ -0,0 +1,191 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Update Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_API_H +#define __UPDATE_API_H + +typedef struct rdp_update rdpUpdate; + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Bitmap Updates */ + +struct _BITMAP_DATA +{ + uint32 destLeft; + uint32 destTop; + uint32 destRight; + uint32 destBottom; + uint32 width; + uint32 height; + uint32 bitsPerPixel; + uint32 flags; + uint32 bitmapLength; + uint32 cbCompFirstRowSize; + uint32 cbCompMainBodySize; + uint32 cbScanWidth; + uint32 cbUncompressedSize; + uint8* bitmapDataStream; + boolean compressed; +}; +typedef struct _BITMAP_DATA BITMAP_DATA; + +struct _BITMAP_UPDATE +{ + uint32 count; + uint32 number; + BITMAP_DATA* rectangles; +}; +typedef struct _BITMAP_UPDATE BITMAP_UPDATE; + +/* Palette Updates */ + +struct _PALETTE_ENTRY +{ + uint8 red; + uint8 green; + uint8 blue; +}; +typedef struct _PALETTE_ENTRY PALETTE_ENTRY; + +struct _PALETTE_UPDATE +{ + uint32 number; + PALETTE_ENTRY entries[256]; +}; +typedef struct _PALETTE_UPDATE PALETTE_UPDATE; + +struct rdp_palette +{ + uint32 count; + PALETTE_ENTRY* entries; +}; +typedef struct rdp_palette rdpPalette; + +/* Play Sound (System Beep) Updates */ + +struct _PLAY_SOUND_UPDATE +{ + uint32 duration; + uint32 frequency; +}; +typedef struct _PLAY_SOUND_UPDATE PLAY_SOUND_UPDATE; + +/* Surface Command Updates */ + +struct _SURFACE_BITS_COMMAND +{ + uint32 cmdType; + uint32 destLeft; + uint32 destTop; + uint32 destRight; + uint32 destBottom; + uint32 bpp; + uint32 codecID; + uint32 width; + uint32 height; + uint32 bitmapDataLength; + uint8* bitmapData; +}; +typedef struct _SURFACE_BITS_COMMAND SURFACE_BITS_COMMAND; + +struct _SURFACE_FRAME_MARKER +{ + uint32 frameAction; + uint32 frameId; +}; +typedef struct _SURFACE_FRAME_MARKER SURFACE_FRAME_MARKER; + +/* Update Interface */ + +typedef void (*pBeginPaint)(rdpContext* context); +typedef void (*pEndPaint)(rdpContext* context); +typedef void (*pSetBounds)(rdpContext* context, rdpBounds* bounds); + +typedef void (*pSynchronize)(rdpContext* context); +typedef void (*pDesktopResize)(rdpContext* context); +typedef void (*pBitmapUpdate)(rdpContext* context, BITMAP_UPDATE* bitmap); +typedef void (*pPalette)(rdpContext* context, PALETTE_UPDATE* palette); +typedef void (*pPlaySound)(rdpContext* context, PLAY_SOUND_UPDATE* play_sound); + +typedef void (*pRefreshRect)(rdpContext* context, uint8 count, RECTANGLE_16* areas); +typedef void (*pSuppressOutput)(rdpContext* context, uint8 allow, RECTANGLE_16* area); + +typedef void (*pSurfaceCommand)(rdpContext* context, STREAM* s); +typedef void (*pSurfaceBits)(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command); +typedef void (*pSurfaceFrameMarker)(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker); + +struct rdp_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pBeginPaint BeginPaint; /* 16 */ + pEndPaint EndPaint; /* 17 */ + pSetBounds SetBounds; /* 18 */ + pSynchronize Synchronize; /* 19 */ + pDesktopResize DesktopResize; /* 20 */ + pBitmapUpdate BitmapUpdate; /* 21 */ + pPalette Palette; /* 22 */ + pPlaySound PlaySound; /* 23 */ + uint32 paddingB[32 - 24]; /* 24 */ + + rdpPointerUpdate* pointer; /* 32 */ + rdpPrimaryUpdate* primary; /* 33 */ + rdpSecondaryUpdate* secondary; /* 34 */ + rdpAltSecUpdate* altsec; /* 35 */ + rdpWindowUpdate* window; /* 36 */ + uint32 paddingC[48 - 37]; /* 37 */ + + pRefreshRect RefreshRect; /* 48 */ + pSuppressOutput SuppressOutput; /* 49 */ + uint32 paddingD[64 - 50]; /* 50 */ + + pSurfaceCommand SurfaceCommand; /* 64 */ + pSurfaceBits SurfaceBits; /* 65 */ + pSurfaceFrameMarker SurfaceFrameMarker; /* 66 */ + uint32 paddingE[80 - 67]; /* 67 */ + + /* internal */ + + boolean dump_rfx; + boolean play_rfx; + rdpPcap* pcap_rfx; + + BITMAP_UPDATE bitmap_update; + PALETTE_UPDATE palette_update; + PLAY_SOUND_UPDATE play_sound; + + SURFACE_BITS_COMMAND surface_bits_command; + SURFACE_FRAME_MARKER surface_frame_marker; +}; + +#endif /* __UPDATE_API_H */ + diff --git a/include/freerdp/utils/args.h b/include/freerdp/utils/args.h new file mode 100644 index 0000000..87155ad --- /dev/null +++ b/include/freerdp/utils/args.h @@ -0,0 +1,48 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Arguments Parsing + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ARGS_UTILS_H +#define __ARGS_UTILS_H + +#include +#include +#include + + +typedef enum _FREERDP_ARGS_PARSE_RESULT +{ + FREERDP_ARGS_PARSE_FAILURE = -1, + FREERDP_ARGS_PARSE_HELP = -2, + FREERDP_ARGS_PARSE_VERSION = -3, +} FREERDP_ARGS_PARSE_RESULT; + + +/* Returns 1 if succeed, otherwise returns zero */ +typedef int (*ProcessPluginArgs) (rdpSettings* settings, const char* name, + RDP_PLUGIN_DATA* plugin_data, void* user_data); + +/* Returns number of arguments processed (1 or 2), otherwise returns zero */ +typedef int (*ProcessUIArgs) (rdpSettings* settings, const char* opt, + const char* val, void* user_data); + +FREERDP_API int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, + ProcessPluginArgs plugin_callback, void* plugin_user_data, + ProcessUIArgs ui_callback, void* ui_user_data); + +#endif /* __ARGS_UTILS_H */ diff --git a/include/freerdp/utils/bitmap.h b/include/freerdp/utils/bitmap.h new file mode 100644 index 0000000..cb09474 --- /dev/null +++ b/include/freerdp/utils/bitmap.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap File Format Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_BITMAP_H +#define __UTILS_BITMAP_H + +#include + +FREERDP_API void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp); + +#endif /* __UTILS_BITMAP_H */ diff --git a/include/freerdp/utils/blob.h b/include/freerdp/utils/blob.h new file mode 100644 index 0000000..3f20e32 --- /dev/null +++ b/include/freerdp/utils/blob.h @@ -0,0 +1,35 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * BLOB Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BLOB_UTILS_H +#define __BLOB_UTILS_H + +#include + +struct rdp_blob +{ + void* data; + int length; +}; +typedef struct rdp_blob rdpBlob; + +FREERDP_API void freerdp_blob_alloc(rdpBlob* blob, int length); +FREERDP_API void freerdp_blob_free(rdpBlob* blob); + +#endif /* __BLOB_UTILS_H */ diff --git a/include/freerdp/utils/debug.h b/include/freerdp/utils/debug.h new file mode 100644 index 0000000..55fc289 --- /dev/null +++ b/include/freerdp/utils/debug.h @@ -0,0 +1,38 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Debug Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_DEBUG_H +#define __UTILS_DEBUG_H + +#include "config.h" + +#include + +#define DEBUG_NULL(fmt, ...) do { } while (0) +#define DEBUG_PRINT(_dbg_str, fmt, ...) printf(_dbg_str fmt "\n" , __FUNCTION__, __LINE__, ## __VA_ARGS__) +#define DEBUG_CLASS(_dbg_class, fmt, ...) DEBUG_PRINT("DBG_" #_dbg_class " %s (%d): ", fmt, ## __VA_ARGS__) +#define DEBUG_WARN(fmt, ...) DEBUG_PRINT("Warning %s (%d): ", fmt, ## __VA_ARGS__) + +#ifdef WITH_DEBUG +#define DEBUG(fmt, ...) DEBUG_PRINT("DBG %s (%d): ", fmt, ## __VA_ARGS__) +#else +#define DEBUG(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __UTILS_DEBUG_H */ diff --git a/include/freerdp/utils/dsp.h b/include/freerdp/utils/dsp.h new file mode 100644 index 0000000..10e799e --- /dev/null +++ b/include/freerdp/utils/dsp.h @@ -0,0 +1,42 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Digital Sound Processing + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DSP_UTILS_H +#define __DSP_UTILS_H + +#include + +struct _ADPCM +{ + sint16 last_sample[2]; + sint16 last_step[2]; +}; +typedef struct _ADPCM ADPCM; + +FREERDP_API uint8* dsp_resample(uint8* src, int bytes_per_sample, + uint32 schan, uint32 srate, int sframes, + uint32 rchan, uint32 rrate, int * prframes); + +FREERDP_API uint8* dsp_decode_ima_adpcm(ADPCM* adpcm, + uint8* src, int size, int channels, int block_size, int* out_size); +FREERDP_API uint8* dsp_encode_ima_adpcm(ADPCM* adpcm, + uint8* src, int size, int channels, int block_size, int* out_size); + +#endif /* __DSP_UTILS_H */ + diff --git a/include/freerdp/utils/event.h b/include/freerdp/utils/event.h new file mode 100644 index 0000000..e0650d2 --- /dev/null +++ b/include/freerdp/utils/event.h @@ -0,0 +1,30 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Events + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __EVENT_UTILS_H +#define __EVENT_UTILS_H + +#include +#include + +FREERDP_API RDP_EVENT* freerdp_event_new(uint16 event_class, uint16 event_type, + RDP_EVENT_CALLBACK on_event_free_callback, void* user_data); +FREERDP_API void freerdp_event_free(RDP_EVENT* event); + +#endif diff --git a/include/freerdp/utils/file.h b/include/freerdp/utils/file.h new file mode 100644 index 0000000..7922a9d --- /dev/null +++ b/include/freerdp/utils/file.h @@ -0,0 +1,39 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * File Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FILE_UTILS_H +#define __FILE_UTILS_H + +#include +#include +#include + +FREERDP_API void freerdp_mkdir(char* path); +FREERDP_API boolean freerdp_check_file_exists(char* file); +FREERDP_API char* freerdp_get_home_path(rdpSettings* settings); +FREERDP_API char* freerdp_get_config_path(rdpSettings* settings); +FREERDP_API char* freerdp_get_current_path(rdpSettings* settings); +FREERDP_API char* freerdp_construct_path(char* base_path, char* relative_path); +FREERDP_API char* freerdp_append_shared_library_suffix(char* file_path); +FREERDP_API char* freerdp_get_parent_path(char* base_path, int depth); +FREERDP_API boolean freerdp_path_contains_separator(char* path); +FREERDP_API boolean freerdp_detect_development_mode(rdpSettings* settings); +FREERDP_API void freerdp_detect_paths(rdpSettings* settings); + +#endif /* __FILE_UTILS_H */ diff --git a/include/freerdp/utils/hexdump.h b/include/freerdp/utils/hexdump.h new file mode 100644 index 0000000..4b0363b --- /dev/null +++ b/include/freerdp/utils/hexdump.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Hex Dump Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_HEXDUMP_H +#define __UTILS_HEXDUMP_H + +#include + +#define FREERDP_HEXDUMP_LINE_LENGTH 16 + +FREERDP_API void freerdp_hexdump(uint8* data, int length); + +#endif /* __UTILS_HEXDUMP_H */ diff --git a/include/freerdp/utils/list.h b/include/freerdp/utils/list.h new file mode 100644 index 0000000..de53a10 --- /dev/null +++ b/include/freerdp/utils/list.h @@ -0,0 +1,52 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Double-linked List Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIST_UTILS_H +#define __LIST_UTILS_H + +#include +#include + +typedef struct _LIST_ITEM LIST_ITEM; +struct _LIST_ITEM +{ + void* data; + LIST_ITEM* prev; + LIST_ITEM* next; +}; + +typedef struct _LIST LIST; +struct _LIST +{ + int count; + LIST_ITEM* head; + LIST_ITEM* tail; +}; + +FREERDP_API LIST* list_new(void); +FREERDP_API void list_free(LIST* list); +FREERDP_API void list_enqueue(LIST* list, void* data); +FREERDP_API void* list_dequeue(LIST* list); +FREERDP_API void* list_peek(LIST* list); +FREERDP_API void* list_next(LIST* list, void* data); +#define list_add(_l, _d) list_enqueue(_l, _d) +FREERDP_API void* list_remove(LIST* list, void* data); +FREERDP_API int list_size(LIST* list); + +#endif /* __LIST_UTILS_H */ diff --git a/include/freerdp/utils/load_plugin.h b/include/freerdp/utils/load_plugin.h new file mode 100644 index 0000000..9b698d0 --- /dev/null +++ b/include/freerdp/utils/load_plugin.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Plugin Loading Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOAD_PLUGIN_UTILS_H +#define __LOAD_PLUGIN_UTILS_H + +#include +#include + +FREERDP_API void* freerdp_open_library(const char* file); +FREERDP_API void* freerdp_get_library_symbol(void* library, const char* name); +FREERDP_API boolean freerdp_close_library(void* library); +FREERDP_API void* freerdp_load_library_symbol(const char* file, const char* name); +FREERDP_API void* freerdp_load_plugin(const char* name, const char* entry_name); +FREERDP_API void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name); + +#endif /* __LOAD_PLUGIN_UTILS_H */ diff --git a/include/freerdp/utils/memory.h b/include/freerdp/utils/memory.h new file mode 100644 index 0000000..892a7ad --- /dev/null +++ b/include/freerdp/utils/memory.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Memory Utils + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MEMORY_UTILS_H +#define __MEMORY_UTILS_H + +#include +#include + +FREERDP_API void* xmalloc(size_t size); +FREERDP_API void* xzalloc(size_t size); +FREERDP_API void* xrealloc(void* ptr, size_t size); +FREERDP_API void xfree(void* ptr); +FREERDP_API char* xstrdup(const char* str); + +#define xnew(_type) (_type*)xzalloc(sizeof(_type)) + +#endif /* __MEMORY_UTILS_H */ diff --git a/include/freerdp/utils/mutex.h b/include/freerdp/utils/mutex.h new file mode 100644 index 0000000..ffb12f8 --- /dev/null +++ b/include/freerdp/utils/mutex.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Mutex Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MUTEX_UTILS_H +#define __MUTEX_UTILS_H + +#include + +typedef void* freerdp_mutex; + +FREERDP_API freerdp_mutex freerdp_mutex_new(void); +FREERDP_API void freerdp_mutex_free(freerdp_mutex mutex); +FREERDP_API void freerdp_mutex_lock(freerdp_mutex mutex); +FREERDP_API void freerdp_mutex_unlock(freerdp_mutex mutex); + +#endif /* __MUTEX_UTILS_H */ diff --git a/include/freerdp/utils/passphrase.h b/include/freerdp/utils/passphrase.h new file mode 100644 index 0000000..44c6d0b --- /dev/null +++ b/include/freerdp/utils/passphrase.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Passphrase Handling Utils + * + * Copyright 2011 Shea Levy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_PASSPHRASE_H +#define __UTILS_PASSPHRASE_H + +#include +#include + +FREERDP_API char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz); + +#endif /* __UTILS_PASSPHRASE_H */ diff --git a/include/freerdp/utils/pcap.h b/include/freerdp/utils/pcap.h new file mode 100644 index 0000000..147b1f3 --- /dev/null +++ b/include/freerdp/utils/pcap.h @@ -0,0 +1,81 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * pcap File Format Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_PCAP_H +#define __UTILS_PCAP_H + +#include +#include + +struct _pcap_header +{ + uint32 magic_number; /* magic number */ + uint16 version_major; /* major version number */ + uint16 version_minor; /* minor version number */ + sint32 thiszone; /* GMT to local correction */ + uint32 sigfigs; /* accuracy of timestamps */ + uint32 snaplen; /* max length of captured packets, in octets */ + uint32 network; /* data link type */ +}; +typedef struct _pcap_header pcap_header; + +struct _pcap_record_header +{ + uint32 ts_sec; /* timestamp seconds */ + uint32 ts_usec; /* timestamp microseconds */ + uint32 incl_len; /* number of octets of packet saved in file */ + uint32 orig_len; /* actual length of packet */ +}; +typedef struct _pcap_record_header pcap_record_header; + +typedef struct _pcap_record pcap_record; + +struct _pcap_record +{ + pcap_record_header header; + void* data; + uint32 length; + pcap_record* next; +}; + +struct rdp_pcap +{ + FILE* fp; + char* name; + boolean write; + int file_size; + int record_count; + pcap_header header; + pcap_record* head; + pcap_record* tail; + pcap_record* record; +}; +typedef struct rdp_pcap rdpPcap; + +FREERDP_API rdpPcap* pcap_open(char* name, boolean write); +FREERDP_API void pcap_close(rdpPcap* pcap); + +FREERDP_API void pcap_add_record(rdpPcap* pcap, void* data, uint32 length); +FREERDP_API boolean pcap_has_next_record(rdpPcap* pcap); +FREERDP_API boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record); +FREERDP_API boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record); +FREERDP_API boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record); +FREERDP_API void pcap_flush(rdpPcap* pcap); + +#endif /* __UTILS_PCAP_H */ diff --git a/include/freerdp/utils/print.h b/include/freerdp/utils/print.h new file mode 100644 index 0000000..bbe02a6 --- /dev/null +++ b/include/freerdp/utils/print.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Print Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PRINT_UTILS_H +#define __PRINT_UTILS_H + +#include + +#ifdef _WIN32 +#define snprintf sprintf_s +#endif + +#endif /* __PRINT_UTILS_H */ diff --git a/include/freerdp/utils/profiler.h b/include/freerdp/utils/profiler.h new file mode 100644 index 0000000..fa367ae --- /dev/null +++ b/include/freerdp/utils/profiler.h @@ -0,0 +1,71 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Profiler Utils + * + * Copyright 2011 Stephen Erisman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_PROFILER_H +#define __UTILS_PROFILER_H + +#include + +#include "config.h" + +#include + +#include +#include + +struct _PROFILER +{ + char* name; + STOPWATCH* stopwatch; +}; +typedef struct _PROFILER PROFILER; + +FREERDP_API PROFILER* profiler_create(char* name); +FREERDP_API void profiler_free(PROFILER* profiler); + +FREERDP_API void profiler_enter(PROFILER* profiler); +FREERDP_API void profiler_exit(PROFILER* profiler); + +FREERDP_API void profiler_print_header(); +FREERDP_API void profiler_print(PROFILER* profiler); +FREERDP_API void profiler_print_footer(); + +#ifdef WITH_PROFILER +#define IF_PROFILER(then) then +#define PROFILER_DEFINE(prof) PROFILER* prof +#define PROFILER_CREATE(prof,name) prof = profiler_create(name) +#define PROFILER_FREE(prof) profiler_free(prof) +#define PROFILER_ENTER(prof) profiler_enter(prof) +#define PROFILER_EXIT(prof) profiler_exit(prof) +#define PROFILER_PRINT_HEADER profiler_print_header() +#define PROFILER_PRINT(prof) profiler_print(prof) +#define PROFILER_PRINT_FOOTER profiler_print_footer() +#else +#define IF_PROFILER(then) do { } while (0) +#define PROFILER_DEFINE(prof) void* prof +#define PROFILER_CREATE(prof,name) do { } while (0) +#define PROFILER_FREE(prof) do { } while (0) +#define PROFILER_ENTER(prof) do { } while (0) +#define PROFILER_EXIT(prof) do { } while (0) +#define PROFILER_PRINT_HEADER do { } while (0) +#define PROFILER_PRINT(prof) do { } while (0) +#define PROFILER_PRINT_FOOTER do { } while (0) +#endif + +#endif /* __UTILS_PROFILER_H */ diff --git a/include/freerdp/utils/rail.h b/include/freerdp/utils/rail.h new file mode 100644 index 0000000..1b95810 --- /dev/null +++ b/include/freerdp/utils/rail.h @@ -0,0 +1,38 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RAIL_UTILS_H +#define __RAIL_UTILS_H + +#include +#include +#include +#include + +#define RAIL_ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + +FREERDP_API void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString); +FREERDP_API void rail_unicode_string_free(UNICODE_STRING* unicode_string); +FREERDP_API void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); +FREERDP_API void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string); +FREERDP_API void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string); +FREERDP_API void* rail_clone_order(uint32 event_type, void* order); +FREERDP_API void rail_free_cloned_order(uint32 event_type, void* order); + +#endif /* __RAIL_UTILS_H */ diff --git a/include/freerdp/utils/rect.h b/include/freerdp/utils/rect.h new file mode 100644 index 0000000..530dfbb --- /dev/null +++ b/include/freerdp/utils/rect.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Rectangle Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RECT_UTILS_H +#define __RECT_UTILS_H + +#include +#include +#include + +FREERDP_API void freerdp_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); +FREERDP_API void freerdp_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16); + +FREERDP_API RECTANGLE_16* freerdp_rectangle_16_new(uint16 left, uint16 top, uint16 right, uint16 bottom); +FREERDP_API void freerdp_rectangle_16_free(RECTANGLE_16* rectangle_16); + +#endif /* __RECT_UTILS_H */ diff --git a/include/freerdp/utils/registry.h b/include/freerdp/utils/registry.h new file mode 100644 index 0000000..b3956ce --- /dev/null +++ b/include/freerdp/utils/registry.h @@ -0,0 +1,72 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Registry Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGISTRY_UTILS_H +#define __REGISTRY_UTILS_H + +typedef struct rdp_registry rdpRegistry; + +#include +#include +#include +#include +#include +#include +#include + +enum REG_TYPE +{ + REG_TYPE_NONE, + REG_TYPE_STRING, + REG_TYPE_INTEGER, + REG_TYPE_BOOLEAN, + REG_TYPE_SECTION +}; + +typedef struct +{ + uint8 type; + char* name; + uint32 length; + void* value; +} REG_ENTRY; + +typedef REG_ENTRY REG_STRING; +typedef REG_ENTRY REG_INTEGER; +typedef REG_ENTRY REG_BOOLEAN; +typedef REG_ENTRY REG_SECTION; + +struct rdp_registry +{ + FILE* fp; + char* path; + char* file; + char* home; + boolean available; + struct rdp_settings* settings; +}; + +FREERDP_API void registry_open(rdpRegistry* registry); +FREERDP_API void registry_close(rdpRegistry* registry); + +FREERDP_API void registry_init(rdpRegistry* registry); +FREERDP_API rdpRegistry* registry_new(rdpSettings* settings); +FREERDP_API void registry_free(rdpRegistry* registry); + +#endif /* __REGISTRY_UTILS_H */ diff --git a/include/freerdp/utils/semaphore.h b/include/freerdp/utils/semaphore.h new file mode 100644 index 0000000..15830eb --- /dev/null +++ b/include/freerdp/utils/semaphore.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Semaphore Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SEMAPHORE_UTILS_H +#define __SEMAPHORE_UTILS_H + +#include + +typedef void* freerdp_sem; + +FREERDP_API freerdp_sem freerdp_sem_new(int iv); +FREERDP_API void freerdp_sem_free(freerdp_sem sem); +FREERDP_API void freerdp_sem_signal(freerdp_sem sem); +FREERDP_API void freerdp_sem_wait(freerdp_sem sem); + +#endif /* __SEMAPHORE_UTILS_H */ diff --git a/include/freerdp/utils/signal.h b/include/freerdp/utils/signal.h new file mode 100644 index 0000000..eb54c3f --- /dev/null +++ b/include/freerdp/utils/signal.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Signal handling + * + * Copyright 2011 Shea Levy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_SIGNAL_H +#define __UTILS_SIGNAL_H + +#include +#ifndef _WIN32 +#include +#include + +extern volatile sig_atomic_t terminal_needs_reset; +extern int terminal_fildes; +extern struct termios orig_flags; +extern struct termios new_flags; +#endif + +FREERDP_API int freerdp_handle_signals(void); + +#endif /* __UTILS_SIGNAL_H */ diff --git a/include/freerdp/utils/sleep.h b/include/freerdp/utils/sleep.h new file mode 100644 index 0000000..a3650cc --- /dev/null +++ b/include/freerdp/utils/sleep.h @@ -0,0 +1,29 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Sleep Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SLEEP_UTILS_H +#define __SLEEP_UTILS_H + +#include +#include + +FREERDP_API void freerdp_sleep(uint32 seconds); +FREERDP_API void freerdp_usleep(uint32 useconds); + +#endif /* __SLEEP_UTILS_H */ diff --git a/include/freerdp/utils/stopwatch.h b/include/freerdp/utils/stopwatch.h new file mode 100644 index 0000000..58d7be5 --- /dev/null +++ b/include/freerdp/utils/stopwatch.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stopwatch Utils + * + * Copyright 2011 Stephen Erisman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_STOPWATCH_H +#define __UTILS_STOPWATCH_H + +#include +#include +#include +#include + +struct _STOPWATCH +{ + clock_t start; + clock_t end; + double elapsed; + clock_t count; +}; +typedef struct _STOPWATCH STOPWATCH; + +FREERDP_API STOPWATCH* stopwatch_create(); +FREERDP_API void stopwatch_free(STOPWATCH* stopwatch); + +FREERDP_API void stopwatch_start(STOPWATCH* stopwatch); +FREERDP_API void stopwatch_stop(STOPWATCH* stopwatch); +FREERDP_API void stopwatch_reset(STOPWATCH* stopwatch); + +FREERDP_API double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch); +FREERDP_API void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, uint32* sec, uint32* usec); + +#endif /* __UTILS_STOPWATCH_H */ diff --git a/include/freerdp/utils/stream.h b/include/freerdp/utils/stream.h new file mode 100644 index 0000000..c583dbd --- /dev/null +++ b/include/freerdp/utils/stream.h @@ -0,0 +1,176 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stream Utils + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __STREAM_UTILS_H +#define __STREAM_UTILS_H + +#include +#include +#include + +struct _STREAM +{ + int size; + uint8* p; + uint8* data; +}; +typedef struct _STREAM STREAM; + +FREERDP_API STREAM* stream_new(int size); +FREERDP_API void stream_free(STREAM* stream); + +#define stream_attach(_s, _buf, _size) do { \ + _s->size = _size; \ + _s->data = _buf; \ + _s->p = _buf; } while (0) +#define stream_detach(_s) memset(_s, 0, sizeof(STREAM)) +#define stream_clear(_s) memset(_s->data, 0, _s->size) + +FREERDP_API void stream_extend(STREAM* stream, int request_size); +#define stream_check_size(_s, _n) \ + while (_s->p - _s->data + (_n) > _s->size) \ + stream_extend(_s, _n) + +#define stream_get_pos(_s) (_s->p - _s->data) +#define stream_set_pos(_s,_m) _s->p = _s->data + (_m) +#define stream_seek(_s,_offset) _s->p += (_offset) +#define stream_rewind(_s,_offset) _s->p -= (_offset) +#define stream_seal(_s) _s->size = (_s->p - _s->data) +#define stream_get_mark(_s,_mark) _mark = _s->p +#define stream_set_mark(_s,_mark) _s->p = _mark +#define stream_get_head(_s) _s->data +#define stream_get_tail(_s) _s->p +#define stream_get_length(_s) (_s->p - _s->data) +#define stream_get_data(_s) (_s->data) +#define stream_get_size(_s) (_s->size) +#define stream_get_left(_s) (_s->size - (_s->p - _s->data)) + +#define stream_read_uint8(_s, _v) do { _v = *_s->p++; } while (0) +#define stream_read_uint16(_s, _v) do { _v = \ + (uint16)(*_s->p) + \ + (((uint16)(*(_s->p + 1))) << 8); \ + _s->p += 2; } while (0) +#define stream_read_uint32(_s, _v) do { _v = \ + (uint32)(*_s->p) + \ + (((uint32)(*(_s->p + 1))) << 8) + \ + (((uint32)(*(_s->p + 2))) << 16) + \ + (((uint32)(*(_s->p + 3))) << 24); \ + _s->p += 4; } while (0) +#define stream_read_uint64(_s, _v) do { _v = \ + (uint64)(*_s->p) + \ + (((uint64)(*(_s->p + 1))) << 8) + \ + (((uint64)(*(_s->p + 2))) << 16) + \ + (((uint64)(*(_s->p + 3))) << 24) + \ + (((uint64)(*(_s->p + 4))) << 32) + \ + (((uint64)(*(_s->p + 5))) << 40) + \ + (((uint64)(*(_s->p + 6))) << 48) + \ + (((uint64)(*(_s->p + 7))) << 56); \ + _s->p += 8; } while (0) +#define stream_read(_s, _b, _n) do { \ + memcpy(_b, (_s->p), (_n)); \ + _s->p += (_n); \ + } while (0) + +#define stream_write_uint8(_s, _v) do { \ + *_s->p++ = (uint8)(_v); } while (0) +#define stream_write_uint16(_s, _v) do { \ + *_s->p++ = (_v) & 0xFF; \ + *_s->p++ = ((_v) >> 8) & 0xFF; } while (0) +#define stream_write_uint32(_s, _v) do { \ + *_s->p++ = (_v) & 0xFF; \ + *_s->p++ = ((_v) >> 8) & 0xFF; \ + *_s->p++ = ((_v) >> 16) & 0xFF; \ + *_s->p++ = ((_v) >> 24) & 0xFF; } while (0) +#define stream_write_uint64(_s, _v) do { \ + *_s->p++ = (uint64)(_v) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 8) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 16) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 24) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 32) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 40) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 48) & 0xFF; \ + *_s->p++ = ((uint64)(_v) >> 56) & 0xFF; } while (0) +#define stream_write(_s, _b, _n) do { \ + memcpy(_s->p, (_b), (_n)); \ + _s->p += (_n); \ + } while (0) +#define stream_write_zero(_s, _n) do { \ + memset(_s->p, '\0', (_n)); \ + _s->p += (_n); \ + } while (0) +#define stream_set_byte(_s, _v, _n) do { \ + memset(_s->p, _v, (_n)); \ + _s->p += (_n); \ + } while (0) + +#define stream_peek_uint8(_s, _v) do { _v = *_s->p; } while (0) +#define stream_peek_uint16(_s, _v) do { _v = \ + (uint16)(*_s->p) + \ + (((uint16)(*(_s->p + 1))) << 8); \ + } while (0) +#define stream_peek_uint32(_s, _v) do { _v = \ + (uint32)(*_s->p) + \ + (((uint32)(*(_s->p + 1))) << 8) + \ + (((uint32)(*(_s->p + 2))) << 16) + \ + (((uint32)(*(_s->p + 3))) << 24); \ + } while (0) +#define stream_peek_uint64(_s, _v) do { _v = \ + (uint64)(*_s->p) + \ + (((uint64)(*(_s->p + 1))) << 8) + \ + (((uint64)(*(_s->p + 2))) << 16) + \ + (((uint64)(*(_s->p + 3))) << 24) + \ + (((uint64)(*(_s->p + 4))) << 32) + \ + (((uint64)(*(_s->p + 5))) << 40) + \ + (((uint64)(*(_s->p + 6))) << 48) + \ + (((uint64)(*(_s->p + 7))) << 56); \ + } while (0) + +#define stream_seek_uint8(_s) stream_seek(_s, 1) +#define stream_seek_uint16(_s) stream_seek(_s, 2) +#define stream_seek_uint32(_s) stream_seek(_s, 4) +#define stream_seek_uint64(_s) stream_seek(_s, 8) + +#define stream_read_uint16_be(_s, _v) do { _v = \ + (((uint16)(*_s->p)) << 8) + \ + (uint16)(*(_s->p + 1)); \ + _s->p += 2; } while (0) +#define stream_read_uint32_be(_s, _v) do { _v = \ + (((uint32)(*(_s->p))) << 8) + \ + (((uint32)(*(_s->p + 1)))) + \ + (((uint32)(*(_s->p + 2))) << 24) + \ + (((uint32)(*(_s->p + 3))) << 16); \ + _s->p += 4; } while (0) + +#define stream_write_uint16_be(_s, _v) do { \ + *_s->p++ = ((_v) >> 8) & 0xFF; \ + *_s->p++ = (_v) & 0xFF; } while (0) +#define stream_write_uint32_be(_s, _v) do { \ + stream_write_uint16_be(_s, ((_v) >> 16 & 0xFFFF)); \ + stream_write_uint16_be(_s, ((_v) & 0xFFFF)); \ + } while (0) + +#define stream_copy(_dst, _src, _n) do { \ + memcpy(_dst->p, _src->p, _n); \ + _dst->p += _n; \ + _src->p += _n; \ + } while (0) + +#endif /* __STREAM_UTILS_H */ + diff --git a/include/freerdp/utils/string.h b/include/freerdp/utils/string.h new file mode 100644 index 0000000..636b93b --- /dev/null +++ b/include/freerdp/utils/string.h @@ -0,0 +1,39 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * String Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __STRING_UTILS_H +#define __STRING_UTILS_H + +#include +#include +#include +#include + +struct rdp_string +{ + char* ascii; + char* unicode; + uint32 length; +}; +typedef struct rdp_string rdpString; + +FREERDP_API void freerdp_string_read_length32(STREAM* s, rdpString* string, UNICONV* uniconv); +FREERDP_API void freerdp_string_free(rdpString* string); + +#endif /* __STRING_UTILS_H */ diff --git a/include/freerdp/utils/svc_plugin.h b/include/freerdp/utils/svc_plugin.h new file mode 100644 index 0000000..829b09b --- /dev/null +++ b/include/freerdp/utils/svc_plugin.h @@ -0,0 +1,84 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Static Virtual Channel Interface + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SVC_PLUGIN_UTILS_H +#define __SVC_PLUGIN_UTILS_H + +/* static channel plugin base implementation */ + +#include +#include +#include +#include +#include + +typedef struct rdp_svc_plugin_private rdpSvcPluginPrivate; +typedef struct rdp_svc_plugin rdpSvcPlugin; + +struct rdp_svc_plugin +{ + CHANNEL_ENTRY_POINTS_EX channel_entry_points; + CHANNEL_DEF channel_def; + + int interval_ms; + + void (*connect_callback)(rdpSvcPlugin* plugin); + void (*receive_callback)(rdpSvcPlugin* plugin, STREAM* data_in); + void (*event_callback)(rdpSvcPlugin* plugin, RDP_EVENT* event); + void (*interval_callback)(rdpSvcPlugin* plugin); + void (*terminate_callback)(rdpSvcPlugin* plugin); + + rdpSvcPluginPrivate* priv; +}; + +FREERDP_API void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints); +FREERDP_API int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out); +FREERDP_API int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event); + +#define svc_plugin_get_data(_p) (RDP_PLUGIN_DATA*)(((rdpSvcPlugin*)_p)->channel_entry_points.pExtendedData) + +#ifdef WITH_DEBUG_SVC +#define DEBUG_SVC(fmt, ...) DEBUG_CLASS(SVC, fmt, ## __VA_ARGS__) +#else +#define DEBUG_SVC(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#define DEFINE_SVC_PLUGIN(_prefix, _name, _options) \ +\ +int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) \ +{ \ + _prefix##Plugin* _p; \ +\ + _p = xnew(_prefix##Plugin); \ +\ + _p->plugin.channel_def.options = _options; \ + strcpy(_p->plugin.channel_def.name, _name); \ +\ + _p->plugin.connect_callback = _prefix##_process_connect; \ + _p->plugin.receive_callback = _prefix##_process_receive; \ + _p->plugin.event_callback = _prefix##_process_event; \ + _p->plugin.terminate_callback = _prefix##_process_terminate; \ +\ + svc_plugin_init((rdpSvcPlugin*)_p, pEntryPoints); \ +\ + return 1; \ +} + +#endif /* __SVC_PLUGIN_UTILS_H */ diff --git a/include/freerdp/utils/thread.h b/include/freerdp/utils/thread.h new file mode 100644 index 0000000..10fe682 --- /dev/null +++ b/include/freerdp/utils/thread.h @@ -0,0 +1,60 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Thread Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __THREAD_UTILS_H +#define __THREAD_UTILS_H + +#include +#include +#include +#include +#ifndef _WIN32 +#include +#endif + +typedef struct _freerdp_thread freerdp_thread; + +struct _freerdp_thread +{ + freerdp_mutex* mutex; + + struct wait_obj* signals[5]; + int num_signals; + + int status; +}; + +FREERDP_API freerdp_thread* freerdp_thread_new(void); +FREERDP_API void freerdp_thread_start(freerdp_thread* thread, void* func, void* arg); +FREERDP_API void freerdp_thread_stop(freerdp_thread* thread); +FREERDP_API void freerdp_thread_free(freerdp_thread* thread); + +#define freerdp_thread_wait(_t) wait_obj_select(_t->signals, _t->num_signals, -1) +#define freerdp_thread_wait_timeout(_t, _timeout) wait_obj_select(_t->signals, _t->num_signals, _timeout) +#define freerdp_thread_is_stopped(_t) wait_obj_is_set(_t->signals[0]) +#define freerdp_thread_is_running(_t) (_t->status == 1) +#define freerdp_thread_quit(_t) do { \ + _t->status = -1; \ + wait_obj_clear(_t->signals[0]); } while (0) +#define freerdp_thread_signal(_t) wait_obj_set(_t->signals[1]) +#define freerdp_thread_reset(_t) wait_obj_clear(_t->signals[1]) +#define freerdp_thread_lock(_t) freerdp_mutex_lock(_t->mutex) +#define freerdp_thread_unlock(_t) freerdp_mutex_unlock(_t->mutex) + +#endif /* __THREAD_UTILS_H */ diff --git a/include/freerdp/utils/unicode.h b/include/freerdp/utils/unicode.h new file mode 100644 index 0000000..7268a8e --- /dev/null +++ b/include/freerdp/utils/unicode.h @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Unicode Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UNICODE_UTILS_H +#define __UNICODE_UTILS_H + +#include +#include +#include + +#define DEFAULT_CODEPAGE "UTF-8" +#define WINDOWS_CODEPAGE "UTF-16LE" + +#ifdef HAVE_ICONV +#include +#endif + +#ifndef ICONV_CONST +#define ICONV_CONST "" +#endif + +struct _UNICONV +{ + int iconv; +#ifdef HAVE_ICONV + iconv_t* in_iconv_h; + iconv_t* out_iconv_h; +#endif +}; +typedef struct _UNICONV UNICONV; + +FREERDP_API UNICONV* freerdp_uniconv_new(); +FREERDP_API void freerdp_uniconv_free(UNICONV *uniconv); +FREERDP_API char* freerdp_uniconv_in(UNICONV *uniconv, unsigned char* pin, size_t in_len); +FREERDP_API char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len); +FREERDP_API void freerdp_uniconv_uppercase(UNICONV *uniconv, char *wstr, int length); + +#endif /* __UNICODE_UTILS_H */ diff --git a/include/freerdp/utils/wait_obj.h b/include/freerdp/utils/wait_obj.h new file mode 100644 index 0000000..a202a25 --- /dev/null +++ b/include/freerdp/utils/wait_obj.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Virtual Channel Manager + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WAIT_OBJ_UTILS +#define __WAIT_OBJ_UTILS + +#include + +FREERDP_API struct wait_obj* wait_obj_new(void); +FREERDP_API struct wait_obj* wait_obj_new_with_fd(void* fd); +FREERDP_API void wait_obj_free(struct wait_obj* obj); +FREERDP_API int wait_obj_is_set(struct wait_obj* obj); +FREERDP_API void wait_obj_set(struct wait_obj* obj); +FREERDP_API void wait_obj_clear(struct wait_obj* obj); +FREERDP_API int wait_obj_select(struct wait_obj** listobj, int numobj, int timeout); +FREERDP_API void wait_obj_get_fds(struct wait_obj* obj, void** fds, int* count); + +#endif diff --git a/include/freerdp/window.h b/include/freerdp/window.h new file mode 100644 index 0000000..4eff0e6 --- /dev/null +++ b/include/freerdp/window.h @@ -0,0 +1,265 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Window Alternate Secondary Drawing Orders Interface API + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_WINDOW_H +#define __UPDATE_WINDOW_H + +#include + +#ifdef _WIN32 +#include +#endif + +/* Window Order Header Flags */ +#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 +#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 +#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 +#define WINDOW_ORDER_STATE_NEW 0x10000000 +#define WINDOW_ORDER_STATE_DELETED 0x20000000 +#define WINDOW_ORDER_FIELD_OWNER 0x00000002 +#define WINDOW_ORDER_FIELD_STYLE 0x00000008 +#define WINDOW_ORDER_FIELD_SHOW 0x00000010 +#define WINDOW_ORDER_FIELD_TITLE 0x00000004 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 +#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 +#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 +#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 +#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 +#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 +#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 +#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 +#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 +#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 +#define WINDOW_ORDER_ICON 0x40000000 +#define WINDOW_ORDER_CACHED_ICON 0x80000000 +#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 +#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 +#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 +#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 +#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 +#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 +#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 + +/* Window Show States */ +#define WINDOW_HIDE 0x00 +#define WINDOW_SHOW_MINIMIZED 0x02 +#define WINDOW_SHOW_MAXIMIZED 0x03 +#define WINDOW_SHOW 0x05 + +/* Window Styles */ +#ifndef _WIN32 +#define WS_BORDER 0x00800000 +#define WS_CAPTION 0x00C00000 +#define WS_CHILD 0x40000000 +#define WS_CLIPCHILDREN 0x02000000 +#define WS_CLIPSIBLINGS 0x04000000 +#define WS_DISABLED 0x08000000 +#define WS_DLGFRAME 0x00400000 +#define WS_GROUP 0x00020000 +#define WS_HSCROLL 0x00100000 +#define WS_ICONIC 0x20000000 +#define WS_MAXIMIZE 0x01000000 +#define WS_MAXIMIZEBOX 0x00010000 +#define WS_MINIMIZE 0x20000000 +#define WS_MINIMIZEBOX 0x00020000 +#define WS_OVERLAPPED 0x00000000 +#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) +#define WS_POPUP 0x80000000 +#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) +#define WS_SIZEBOX 0x00040000 +#define WS_SYSMENU 0x00080000 +#define WS_TABSTOP 0x00010000 +#define WS_THICKFRAME 0x00040000 +#define WS_VISIBLE 0x10000000 +#define WS_VSCROLL 0x00200000 +#endif + +/* Extended Window Styles */ +#ifndef _WIN32 +#define WS_EX_ACCEPTFILES 0x00000010 +#define WS_EX_APPWINDOW 0x00040000 +#define WS_EX_CLIENTEDGE 0x00000200 +#define WS_EX_COMPOSITED 0x02000000 +#define WS_EX_CONTEXTHELP 0x00000400 +#define WS_EX_CONTROLPARENT 0x00010000 +#define WS_EX_DLGMODALFRAME 0x00000001 +#define WS_EX_LAYERED 0x00080000 +#define WS_EX_LAYOUTRTL 0x00400000 +#define WS_EX_LEFT 0x00000000 +#define WS_EX_LEFTSCROLLBAR 0x00004000 +#define WS_EX_LTRREADING 0x00000000 +#define WS_EX_MDICHILD 0x00000040 +#define WS_EX_NOACTIVATE 0x08000000 +#define WS_EX_NOINHERITLAYOUT 0x00100000 +#define WS_EX_NOPARENTNOTIFY 0x00000004 +#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) +#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST) +#define WS_EX_RIGHT 0x00001000 +#define WS_EX_RIGHTSCROLLBAR 0x00000000 +#define WS_EX_RTLREADING 0x00002000 +#define WS_EX_STATICEDGE 0x00020000 +#define WS_EX_TOOLWINDOW 0x00000080 +#define WS_EX_TOPMOST 0x00000008 +#define WS_EX_TRANSPARENT 0x00000020 +#define WS_EX_WINDOWEDGE 0x00000100 +#endif + +struct _WINDOW_ORDER_INFO +{ + uint32 windowId; + uint32 fieldFlags; + uint32 notifyIconId; +}; +typedef struct _WINDOW_ORDER_INFO WINDOW_ORDER_INFO; + +struct _ICON_INFO +{ + uint32 cacheEntry; + uint32 cacheId; + uint32 bpp; + uint32 width; + uint32 height; + uint32 cbColorTable; + uint32 cbBitsMask; + uint32 cbBitsColor; + uint8* bitsMask; + uint8* colorTable; + uint8* bitsColor; +}; +typedef struct _ICON_INFO ICON_INFO; + +struct _CACHED_ICON_INFO +{ + uint32 cacheEntry; + uint32 cacheId; +}; +typedef struct _CACHED_ICON_INFO CACHED_ICON_INFO; + +struct _NOTIFY_ICON_INFOTIP +{ + uint32 timeout; + uint32 flags; + UNICODE_STRING text; + UNICODE_STRING title; +}; +typedef struct _NOTIFY_ICON_INFOTIP NOTIFY_ICON_INFOTIP; + +struct _WINDOW_STATE_ORDER +{ + uint32 ownerWindowId; + uint32 style; + uint32 extendedStyle; + uint32 showState; + UNICODE_STRING titleInfo; + uint32 clientOffsetX; + uint32 clientOffsetY; + uint32 clientAreaWidth; + uint32 clientAreaHeight; + uint32 RPContent; + uint32 rootParentHandle; + uint32 windowOffsetX; + uint32 windowOffsetY; + uint32 windowClientDeltaX; + uint32 windowClientDeltaY; + uint32 windowWidth; + uint32 windowHeight; + uint32 numWindowRects; + RECTANGLE_16* windowRects; + uint32 visibleOffsetX; + uint32 visibleOffsetY; + uint32 numVisibilityRects; + RECTANGLE_16* visibilityRects; +}; +typedef struct _WINDOW_STATE_ORDER WINDOW_STATE_ORDER; + +struct _WINDOW_ICON_ORDER +{ + ICON_INFO* iconInfo; +}; +typedef struct _WINDOW_ICON_ORDER WINDOW_ICON_ORDER; + +struct _WINDOW_CACHED_ICON_ORDER +{ + CACHED_ICON_INFO cachedIcon; +}; +typedef struct _WINDOW_CACHED_ICON_ORDER WINDOW_CACHED_ICON_ORDER; + +struct _NOTIFY_ICON_STATE_ORDER +{ + uint32 version; + UNICODE_STRING toolTip; + NOTIFY_ICON_INFOTIP infoTip; + uint32 state; + ICON_INFO icon; + CACHED_ICON_INFO cachedIcon; +}; +typedef struct _NOTIFY_ICON_STATE_ORDER NOTIFY_ICON_STATE_ORDER; + +struct _MONITORED_DESKTOP_ORDER +{ + uint32 activeWindowId; + uint32 numWindowIds; + uint32* windowIds; +}; +typedef struct _MONITORED_DESKTOP_ORDER MONITORED_DESKTOP_ORDER; + +typedef void (*pWindowCreate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +typedef void (*pWindowUpdate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state); +typedef void (*pWindowIcon)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon); +typedef void (*pWindowCachedIcon)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon); +typedef void (*pWindowDelete)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); +typedef void (*pNotifyIconCreate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef void (*pNotifyIconUpdate)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state); +typedef void (*pNotifyIconDelete)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); +typedef void (*pMonitoredDesktop)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop); +typedef void (*pNonMonitoredDesktop)(rdpContext* context, WINDOW_ORDER_INFO* orderInfo); + +struct rdp_window_update +{ + rdpContext* context; /* 0 */ + uint32 paddingA[16 - 1]; /* 1 */ + + pWindowCreate WindowCreate; /* 16 */ + pWindowUpdate WindowUpdate; /* 17 */ + pWindowIcon WindowIcon; /* 18 */ + pWindowCachedIcon WindowCachedIcon; /* 19 */ + pWindowDelete WindowDelete; /* 20 */ + pNotifyIconCreate NotifyIconCreate; /* 21 */ + pNotifyIconUpdate NotifyIconUpdate; /* 22 */ + pNotifyIconDelete NotifyIconDelete; /* 23 */ + pMonitoredDesktop MonitoredDesktop; /* 24 */ + pNonMonitoredDesktop NonMonitoredDesktop; /* 25 */ + uint32 paddingB[32 - 26]; /* 26 */ + + /* internal */ + + WINDOW_ORDER_INFO orderInfo; + WINDOW_STATE_ORDER window_state; + WINDOW_ICON_ORDER window_icon; + WINDOW_CACHED_ICON_ORDER window_cached_icon; + NOTIFY_ICON_STATE_ORDER notify_icon_state; + MONITORED_DESKTOP_ORDER monitored_desktop; +}; +typedef struct rdp_window_update rdpWindowUpdate; + +#endif /* __UPDATE_WINDOW_H */ diff --git a/keymaps/CMakeLists.txt b/keymaps/CMakeLists.txt new file mode 100644 index 0000000..b6a6c4f --- /dev/null +++ b/keymaps/CMakeLists.txt @@ -0,0 +1,3 @@ +install(FILES aliases amiga ataritt empty evdev fujitsu hp ibm macintosh macosx sony sun xfree86 xfree98 xkb.pl DESTINATION share/freerdp/keymaps) +install(DIRECTORY digital_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*") +install(DIRECTORY sgi_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*") diff --git a/keymaps/aliases b/keymaps/aliases new file mode 100644 index 0000000..e26c243 --- /dev/null +++ b/keymaps/aliases @@ -0,0 +1,17 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "qwerty" +{ +}; + +keyboard "azerty" +{ +}; + +keyboard "qwertz" +{ +}; + diff --git a/keymaps/amiga b/keymaps/amiga new file mode 100644 index 0000000..7ac2df8 --- /dev/null +++ b/keymaps/amiga @@ -0,0 +1,193 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "usa1" +{ + VK_ESCAPE <77> + VK_F1 <88> + VK_F2 <89> + VK_F3 <90> + VK_F4 <91> + VK_F5 <92> + VK_F6 <93> + VK_F7 <94> + VK_F8 <95> + VK_F9 <96> + VK_F10 <97> + VK_OEM_3 <8> + VK_KEY_1 <9> + VK_KEY_2 <10> + VK_KEY_3 <11> + VK_KEY_4 <12> + VK_KEY_5 <13> + VK_KEY_6 <14> + VK_KEY_7 <15> + VK_KEY_8 <16> + VK_KEY_9 <17> + VK_KEY_0 <18> + VK_OEM_MINUS <19> + VK_OEM_PLUS <20> + VK_OEM_5 <21> + VK_BACK <73> + VK_TAB <74> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_RETURN <76> + VK_LCONTROL <107> + VK_CAPITAL <106> + VK_KEY_A <40> + VK_KEY_S <41> + VK_KEY_D <42> + VK_KEY_F <43> + VK_KEY_G <44> + VK_KEY_H <45> + VK_KEY_J <46> + VK_KEY_K <47> + VK_KEY_L <48> + VK_OEM_1 <49> + VK_OEM_7 <50> + VK_LSHIFT <104> + VK_KEY_Z <57> + VK_KEY_X <58> + VK_KEY_C <59> + VK_KEY_V <60> + VK_KEY_B <61> + VK_KEY_N <62> + VK_KEY_M <63> + VK_OEM_COMMA <64> + VK_OEM_PERIOD <65> + VK_OEM_2 <66> + VK_RSHIFT <105> + VK_LMENU <108> + VK_SPACE <72> + VK_RMENU <109> + VK_DELETE <78> + VK_HELP <103> + VK_UP <84> + VK_LEFT <87> + VK_DOWN <85> + VK_RIGHT <86> + VK_DIVIDE <100> + VK_MULTIPLY <101> + VK_NUMPAD7 <69> + VK_NUMPAD8 <70> + VK_NUMPAD9 <71> + VK_SUBTRACT <82> + VK_NUMPAD4 <53> + VK_NUMPAD5 <54> + VK_NUMPAD6 <55> + VK_ADD <102> + VK_NUMPAD1 <37> + VK_NUMPAD2 <38> + VK_NUMPAD3 <39> + VK_NUMPAD0 <23> + VK_RETURN <75> +}; + +keyboard "de" +{ + VK_ESCAPE <77> + VK_F1 <88> + VK_F2 <89> + VK_F3 <90> + VK_F4 <91> + VK_F5 <92> + VK_F6 <93> + VK_F7 <94> + VK_F8 <95> + VK_F9 <96> + VK_F10 <97> + VK_OEM_3 <8> + VK_KEY_1 <9> + VK_KEY_2 <10> + VK_KEY_3 <11> + VK_KEY_4 <12> + VK_KEY_5 <13> + VK_KEY_6 <14> + VK_KEY_7 <15> + VK_KEY_8 <16> + VK_KEY_9 <17> + VK_KEY_0 <18> + VK_OEM_MINUS <19> + VK_OEM_PLUS <20> + VK_OEM_5 <21> + VK_BACK <73> + VK_TAB <74> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_RETURN <76> + VK_LCONTROL <107> + VK_CAPITAL <106> + VK_KEY_A <40> + VK_KEY_S <41> + VK_KEY_D <42> + VK_KEY_F <43> + VK_KEY_G <44> + VK_KEY_H <45> + VK_KEY_J <46> + VK_KEY_K <47> + VK_KEY_L <48> + VK_OEM_1 <49> + VK_OEM_7 <50> + VK_OEM_5 <51> + VK_LSHIFT <104> + VK_OEM_102 <56> + VK_KEY_Z <57> + VK_KEY_X <58> + VK_KEY_C <59> + VK_KEY_V <60> + VK_KEY_B <61> + VK_KEY_N <62> + VK_KEY_M <63> + VK_OEM_COMMA <64> + VK_OEM_PERIOD <65> + VK_OEM_2 <66> + VK_RSHIFT <105> + VK_LMENU <108> + VK_SPACE <72> + VK_RMENU <109> + VK_DELETE <78> + VK_HELP <103> + VK_UP <84> + VK_LEFT <87> + VK_DOWN <85> + VK_RIGHT <86> + VK_DIVIDE <100> + VK_MULTIPLY <101> + VK_NUMPAD7 <69> + VK_NUMPAD8 <70> + VK_NUMPAD9 <71> + VK_SUBTRACT <82> + VK_NUMPAD4 <53> + VK_NUMPAD5 <54> + VK_NUMPAD6 <55> + VK_ADD <102> + VK_NUMPAD1 <37> + VK_NUMPAD2 <38> + VK_NUMPAD3 <39> + VK_NUMPAD0 <23> + VK_RETURN <75> +}; + diff --git a/keymaps/ataritt b/keymaps/ataritt new file mode 100644 index 0000000..4229cea --- /dev/null +++ b/keymaps/ataritt @@ -0,0 +1,104 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "us" +{ + VK_ESCAPE <9> + VK_KEY_1 <10> + VK_KEY_2 <11> + VK_KEY_3 <12> + VK_KEY_4 <13> + VK_KEY_5 <14> + VK_KEY_6 <15> + VK_KEY_7 <16> + VK_KEY_8 <17> + VK_KEY_9 <18> + VK_KEY_0 <19> + VK_OEM_MINUS <20> + VK_OEM_PLUS <21> + VK_OEM_3 <49> + VK_BACK <22> + VK_TAB <23> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_RETURN <36> + VK_DELETE <91> + VK_LCONTROL <37> + VK_KEY_A <38> + VK_KEY_S <39> + VK_KEY_D <40> + VK_KEY_F <41> + VK_KEY_G <42> + VK_KEY_H <43> + VK_KEY_J <44> + VK_KEY_K <45> + VK_KEY_L <46> + VK_OEM_1 <47> + VK_OEM_7 <48> + VK_OEM_5 <51> + VK_LSHIFT <50> + VK_KEY_Z <52> + VK_KEY_X <53> + VK_KEY_C <54> + VK_KEY_V <55> + VK_KEY_B <56> + VK_KEY_N <57> + VK_KEY_M <58> + VK_OEM_COMMA <59> + VK_OEM_PERIOD <60> + VK_OEM_2 <61> + VK_RSHIFT <62> + VK_SPACE <65> + VK_CAPITAL <66> + VK_F1 <67> + VK_F2 <68> + VK_F3 <69> + VK_F4 <70> + VK_F5 <71> + VK_F6 <72> + VK_F7 <73> + VK_F8 <74> + VK_F9 <75> + VK_F10 <76> + VK_HELP <106> + VK_INSERT <90> + VK_HOME <79> + VK_UP <80> + VK_LEFT <83> + VK_DOWN <88> + VK_RIGHT <85> + VK_DIVIDE <109> + VK_MULTIPLY <110> + VK_NUMPAD7 <111> + VK_NUMPAD8 <112> + VK_NUMPAD9 <113> + VK_SUBTRACT <82> + VK_NUMPAD4 <114> + VK_NUMPAD5 <115> + VK_NUMPAD6 <116> + VK_ADD <86> + VK_NUMPAD1 <117> + VK_NUMPAD2 <118> + VK_NUMPAD3 <119> + VK_NUMPAD0 <120> + VK_RETURN <122> +}; + +keyboard "de" +: extends "ataritt(us)" +{ + VK_OEM_102 <104> +}; + diff --git a/keymaps/digital_vndr/lk b/keymaps/digital_vndr/lk new file mode 100644 index 0000000..77ff19c --- /dev/null +++ b/keymaps/digital_vndr/lk @@ -0,0 +1,197 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "lk_common" +{ + VK_F1 <86> + VK_F2 <87> + VK_F3 <88> + VK_F4 <89> + VK_F5 <90> + VK_F6 <100> + VK_F7 <101> + VK_F8 <102> + VK_F9 <103> + VK_F10 <104> + VK_F11 <113> + VK_F12 <114> + VK_UP <170> + VK_LEFT <167> + VK_DOWN <169> + VK_RIGHT <168> + VK_NUMPAD7 <157> + VK_NUMPAD8 <158> + VK_NUMPAD9 <159> + VK_NUMPAD4 <153> + VK_NUMPAD5 <154> + VK_NUMPAD6 <155> + VK_NUMPAD1 <150> + VK_NUMPAD2 <151> + VK_NUMPAD3 <152> + VK_RETURN <149> + VK_NUMPAD0 <146> + VK_DECIMAL <148> + VK_TILDE <191> + VK_KEY_1 <192> + VK_KEY_2 <197> + VK_KEY_3 <203> + VK_KEY_4 <208> + VK_KEY_5 <214> + VK_KEY_6 <219> + VK_KEY_7 <224> + VK_KEY_8 <229> + VK_KEY_9 <234> + VK_KEY_0 <239> + VK_OEM_MINUS <249> + VK_OEM_PLUS <245> + VK_BACK <188> + VK_TAB <190> + VK_KEY_Q <193> + VK_KEY_W <198> + VK_KEY_E <204> + VK_KEY_R <209> + VK_KEY_T <215> + VK_KEY_Y <220> + VK_KEY_U <225> + VK_KEY_I <230> + VK_KEY_O <235> + VK_KEY_P <240> + VK_OEM_4 <250> + VK_OEM_6 <246> + VK_RETURN <189> + VK_LCONTROL <175> + VK_CAPITAL <176> + VK_KEY_A <194> + VK_KEY_S <199> + VK_KEY_D <205> + VK_KEY_F <210> + VK_KEY_G <216> + VK_KEY_H <221> + VK_KEY_J <226> + VK_KEY_K <231> + VK_KEY_L <236> + VK_OEM_1 <242> + VK_OEM_7 <251> + VK_LSHIFT <174> + VK_KEY_Z <195> + VK_KEY_X <200> + VK_KEY_C <206> + VK_KEY_V <211> + VK_KEY_B <217> + VK_KEY_N <222> + VK_KEY_M <227> + VK_OEM_COMMA <232> + VK_OEM_PERIOD <237> + VK_OEM_2 <243> + VK_RSHIFT <171> + VK_SPACE <212> +}; + +keyboard "lkx01" +: extends "digital_vndr/lk(lk_common)" +{ + VK_LSHIFT <201> + VK_F13 <115> + VK_F14 <116> + VK_F17 <128> + VK_F18 <129> + VK_F19 <130> + VK_F20 <131> + VK_HELP <124> + VK_INSERT <139> + VK_DELETE <140> + VK_SELECT <141> + VK_PRIOR <142> + VK_NEXT <143> + VK_NUMLOCK <161> + VK_DIVIDE <162> + VK_MULTIPLY <163> + VK_SUBTRACT <164> + VK_SUBTRACT <160> + VK_ADD <156> + VK_OEM_5 <247> +}; + +keyboard "lk201" +: extends "digital_vndr/lk(lkx01)" +{ +}; + +keyboard "lk421" +: extends "digital_vndr/lk(lkx01)" +{ + VK_LMENU <172> + VK_RMENU <178> +}; + +keyboard "lk401" +: extends "digital_vndr/lk(lk421)" +{ +}; + +keyboard "lk44x" +: extends "digital_vndr/lk(lk_common)" +{ + VK_ESCAPE <85> + VK_SNAPSHOT <115> + VK_SCROLL <116> + VK_PAUSE <124> + VK_INSERT <138> + VK_HOME <139> + VK_PRIOR <140> + VK_DELETE <141> + VK_END <142> + VK_NEXT <143> + VK_NUMLOCK <161> + VK_DIVIDE <162> + VK_MULTIPLY <163> + VK_SUBTRACT <164> + VK_ADD <156> + VK_LMENU <172> + VK_RMENU <178> + VK_RCONTROL <173> +}; + +keyboard "lk443" +: extends "digital_vndr/lk(lk44x)" +{ + VK_OEM_5 <247> +}; + +keyboard "lk444" +: extends "digital_vndr/lk(lk44x)" +{ + VK_OEM_5 <201> + VK_OEM_5 <247> +}; + +keyboard "lk421aj" +: extends "digital_vndr/lk(lk421)" +{ + VK_ABNT_C1 <252> +}; + +keyboard "lk421jj" +: extends "digital_vndr/lk(lk421aj)" +{ + VK_NONCONVERT <94> + VK_KANJI <95> + VK_KANA <97> +}; + +keyboard "lk401bj" +: extends "digital_vndr/lk(lk401)" +{ + VK_NONCONVERT <94> + VK_KANJI <95> + VK_KANA <97> +}; + +keyboard "lk401jj" +: extends "digital_vndr/lk(lk401bj)" +{ + VK_ABNT_C1 <252> +}; + diff --git a/keymaps/digital_vndr/pc b/keymaps/digital_vndr/pc new file mode 100644 index 0000000..81dabb9 --- /dev/null +++ b/keymaps/digital_vndr/pc @@ -0,0 +1,192 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "pc_common" +{ + VK_F1 <9> + VK_F2 <15> + VK_F3 <23> + VK_F4 <31> + VK_F5 <39> + VK_F6 <47> + VK_F7 <55> + VK_F8 <63> + VK_F9 <71> + VK_F10 <79> + VK_F11 <86> + VK_F12 <94> + VK_UP <99> + VK_LEFT <97> + VK_DOWN <96> + VK_RIGHT <106> + VK_NUMPAD7 <108> + VK_NUMPAD8 <117> + VK_NUMPAD9 <125> + VK_NUMPAD4 <107> + VK_NUMPAD5 <115> + VK_NUMPAD6 <116> + VK_NUMPAD1 <105> + VK_NUMPAD2 <114> + VK_NUMPAD3 <122> + VK_RETURN <121> + VK_NUMPAD0 <112> + VK_DECIMAL <113> + VK_KEY_1 <22> + VK_KEY_2 <30> + VK_KEY_3 <38> + VK_KEY_4 <37> + VK_KEY_5 <46> + VK_KEY_6 <54> + VK_KEY_7 <61> + VK_KEY_8 <62> + VK_KEY_9 <70> + VK_KEY_0 <69> + VK_OEM_MINUS <78> + VK_OEM_PLUS <85> + VK_BACK <102> + VK_TAB <13> + VK_KEY_Q <21> + VK_KEY_W <29> + VK_KEY_E <36> + VK_KEY_R <45> + VK_KEY_T <44> + VK_KEY_Y <53> + VK_KEY_U <60> + VK_KEY_I <67> + VK_KEY_O <68> + VK_KEY_P <77> + VK_OEM_4 <84> + VK_OEM_6 <91> + VK_CAPITAL <20> + VK_KEY_A <28> + VK_KEY_S <27> + VK_KEY_D <35> + VK_KEY_F <43> + VK_KEY_G <52> + VK_KEY_H <51> + VK_KEY_J <59> + VK_KEY_K <66> + VK_KEY_L <75> + VK_OEM_1 <76> + VK_OEM_7 <82> + VK_RETURN <90> + VK_LSHIFT <18> + VK_KEY_Z <26> + VK_KEY_X <34> + VK_KEY_C <33> + VK_KEY_V <42> + VK_KEY_B <50> + VK_KEY_N <49> + VK_KEY_M <58> + VK_OEM_COMMA <65> + VK_OEM_PERIOD <73> + VK_OEM_2 <74> + VK_RSHIFT <89> + VK_LCONTROL <17> + VK_LMENU <25> + VK_SPACE <41> + VK_RMENU <57> +}; + +keyboard "pc10x" +: extends "digital_vndr/pc(pc_common)" +{ + VK_ESCAPE <8> + VK_TILDE <14> + VK_SNAPSHOT <87> + VK_SCROLL <95> + VK_PAUSE <98> + VK_INSERT <103> + VK_HOME <110> + VK_PRIOR <111> + VK_DELETE <100> + VK_END <101> + VK_NEXT <109> + VK_NUMLOCK <118> + VK_DIVIDE <119> + VK_MULTIPLY <126> + VK_SUBTRACT <132> + VK_ADD <124> + VK_RCONTROL <88> +}; + +keyboard "pc101" +: extends "digital_vndr/pc(pc10x)" +{ + VK_OEM_5 <92> +}; + +keyboard "pc102" +: extends "digital_vndr/pc(pc10x)" +{ + VK_OEM_5 <19> + VK_OEM_5 <83> +}; + +keyboard "pc104" +: extends "digital_vndr/pc(pc101)" +{ + VK_LWIN <139> + VK_RWIN <140> + VK_APPS <141> +}; + +keyboard "lk411_common" +: extends "digital_vndr/pc(pc_common)" +{ + VK_TILDE <8> + VK_LSHIFT <14> + VK_F13 <24> + VK_F14 <10> + VK_F17 <16> + VK_F18 <87> + VK_F19 <95> + VK_F20 <98> + VK_HELP <11> + VK_INSERT <103> + VK_DELETE <100> + VK_SELECT <101> + VK_PRIOR <111> + VK_NEXT <109> + VK_NUMLOCK <118> + VK_DIVIDE <119> + VK_MULTIPLY <126> + VK_SUBTRACT <132> + VK_SUBTRACT <19> + VK_ADD <124> +}; + +keyboard "lk411" +: extends "digital_vndr/pc(lk411_common)" +{ + VK_OEM_5 <92> +}; + +keyboard "lk450" +: extends "digital_vndr/pc(lk411)" +{ +}; + +keyboard "pcxajaa" +: extends "digital_vndr/pc(pc10x)" +{ + VK_OEM_5 <93> + VK_OEM_5 <83> + VK_ABNT_C1 <81> + VK_NONCONVERT <133> + VK_KANJI <134> + VK_KANA <135> +}; + +keyboard "lk411jj" +: extends "digital_vndr/pc(lk411_common)" +{ + VK_ABNT_C1 <81> + VK_OEM_5 <83> + VK_NONCONVERT <133> + VK_KANJI <134> + VK_KANA <135> +}; + diff --git a/keymaps/empty b/keymaps/empty new file mode 100644 index 0000000..b0c6667 --- /dev/null +++ b/keymaps/empty @@ -0,0 +1,13 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "empty" +{ +}; + +keyboard "empty" +{ +}; + diff --git a/keymaps/evdev b/keymaps/evdev new file mode 100644 index 0000000..cb78135 --- /dev/null +++ b/keymaps/evdev @@ -0,0 +1,135 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "evdev" +{ + VK_OEM_102 <94> + VK_OEM_3 <49> + VK_KEY_1 <10> + VK_KEY_2 <11> + VK_KEY_3 <12> + VK_KEY_4 <13> + VK_KEY_5 <14> + VK_KEY_6 <15> + VK_KEY_7 <16> + VK_KEY_8 <17> + VK_KEY_9 <18> + VK_KEY_0 <19> + VK_OEM_MINUS <20> + VK_OEM_PLUS <21> + VK_BACK <22> + VK_TAB <23> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_OEM_5 <51> + VK_RETURN <36> + VK_CAPITAL <66> + VK_KEY_A <38> + VK_KEY_S <39> + VK_KEY_D <40> + VK_KEY_F <41> + VK_KEY_G <42> + VK_KEY_H <43> + VK_KEY_J <44> + VK_KEY_K <45> + VK_KEY_L <46> + VK_OEM_1 <47> + VK_OEM_7 <48> + VK_LSHIFT <50> + VK_KEY_Z <52> + VK_KEY_X <53> + VK_KEY_C <54> + VK_KEY_V <55> + VK_KEY_B <56> + VK_KEY_N <57> + VK_KEY_M <58> + VK_OEM_COMMA <59> + VK_OEM_PERIOD <60> + VK_OEM_2 <61> + VK_RSHIFT <62> + VK_LMENU <64> + VK_LCONTROL <37> + VK_SPACE <65> + VK_RCONTROL <105> + VK_RMENU <108> + VK_LWIN <133> + VK_RWIN <134> + VK_APPS <135> + VK_ESCAPE <9> + VK_F1 <67> + VK_F2 <68> + VK_F3 <69> + VK_F4 <70> + VK_F5 <71> + VK_F6 <72> + VK_F7 <73> + VK_F8 <74> + VK_F9 <75> + VK_F10 <76> + VK_F11 <95> + VK_F12 <96> + VK_SNAPSHOT <107> + VK_SCROLL <78> + VK_PAUSE <127> + VK_INSERT <118> + VK_HOME <110> + VK_PRIOR <112> + VK_DELETE <119> + VK_END <115> + VK_NEXT <117> + VK_UP <111> + VK_LEFT <113> + VK_DOWN <116> + VK_RIGHT <114> + VK_NUMLOCK <77> + VK_DIVIDE <106> + VK_MULTIPLY <63> + VK_SUBTRACT <82> + VK_NUMPAD7 <79> + VK_NUMPAD8 <80> + VK_NUMPAD9 <81> + VK_ADD <86> + VK_NUMPAD4 <83> + VK_NUMPAD5 <84> + VK_NUMPAD6 <85> + VK_NUMPAD1 <87> + VK_NUMPAD2 <88> + VK_NUMPAD3 <89> + VK_RETURN <104> + VK_NUMPAD0 <90> + VK_DECIMAL <91> + VK_F13 <191> + VK_F14 <192> + VK_F15 <193> + VK_F16 <194> + VK_F17 <195> + VK_F18 <196> + VK_F19 <197> + VK_F20 <198> + VK_F21 <199> + VK_F22 <200> + VK_F23 <201> + VK_F24 <202> + VK_ABNT_C1 <97> + VK_NONCONVERT <102> + VK_KANA <99> + VK_HELP <146> +}; + +keyboard "pc98" +: extends "evdev(evdev)" +{ +}; + diff --git a/keymaps/fujitsu b/keymaps/fujitsu new file mode 100644 index 0000000..6f21368 --- /dev/null +++ b/keymaps/fujitsu @@ -0,0 +1,119 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "138" +{ + VK_ESCAPE <37> + VK_KEY_1 <38> + VK_KEY_2 <39> + VK_KEY_3 <40> + VK_KEY_4 <41> + VK_KEY_5 <42> + VK_KEY_6 <43> + VK_KEY_7 <44> + VK_KEY_8 <45> + VK_KEY_9 <46> + VK_KEY_0 <47> + VK_OEM_MINUS <48> + VK_OEM_PLUS <49> + VK_OEM_3 <50> + VK_BACK <51> + VK_TAB <61> + VK_KEY_Q <62> + VK_KEY_W <63> + VK_KEY_E <64> + VK_KEY_R <65> + VK_KEY_T <66> + VK_KEY_Y <67> + VK_KEY_U <68> + VK_KEY_I <69> + VK_KEY_O <70> + VK_KEY_P <71> + VK_OEM_4 <72> + VK_OEM_6 <73> + VK_LCONTROL <84> + VK_KEY_A <85> + VK_KEY_S <86> + VK_KEY_D <87> + VK_KEY_F <88> + VK_KEY_G <89> + VK_KEY_H <90> + VK_KEY_J <91> + VK_KEY_K <92> + VK_KEY_L <93> + VK_OEM_1 <94> + VK_OEM_7 <95> + VK_OEM_5 <96> + VK_RETURN <97> + VK_LSHIFT <107> + VK_KEY_Z <108> + VK_KEY_X <109> + VK_KEY_C <110> + VK_KEY_V <111> + VK_KEY_B <112> + VK_KEY_N <113> + VK_KEY_M <114> + VK_OEM_COMMA <115> + VK_OEM_PERIOD <116> + VK_OEM_2 <117> + VK_ABNT_C1 <52> + VK_RSHIFT <118> + VK_CAPITAL <127> + VK_LMENU <27> + VK_SPACE <129> + VK_RMENU <23> + VK_APPS <75> + VK_F1 <13> + VK_F2 <14> + VK_F3 <16> + VK_F4 <18> + VK_F5 <20> + VK_F6 <22> + VK_F7 <24> + VK_F8 <25> + VK_F9 <26> + VK_F10 <15> + VK_F11 <17> + VK_F12 <19> + VK_F13 <137> + VK_F14 <138> + VK_F15 <139> + VK_F16 <140> + VK_F17 <141> + VK_F18 <142> + VK_F19 <143> + VK_F20 <144> + VK_F21 <145> + VK_F22 <146> + VK_F23 <147> + VK_F24 <148> + VK_HELP <126> + VK_SNAPSHOT <30> + VK_PAUSE <29> + VK_PRIOR <35> + VK_HOME <32> + VK_NEXT <36> + VK_INSERT <60> + VK_UP <33> + VK_DOWN <103> + VK_LEFT <57> + VK_RIGHT <80> + VK_MULTIPLY <55> + VK_DIVIDE <54> + VK_ADD <133> + VK_SUBTRACT <79> + VK_NUMPAD7 <76> + VK_NUMPAD8 <77> + VK_NUMPAD9 <78> + VK_NUMPAD4 <99> + VK_NUMPAD5 <100> + VK_NUMPAD6 <101> + VK_NUMPAD1 <120> + VK_NUMPAD2 <121> + VK_NUMPAD3 <122> + VK_RETURN <98> + VK_NUMPAD0 <102> +}; + diff --git a/keymaps/hp b/keymaps/hp new file mode 100644 index 0000000..270d149 --- /dev/null +++ b/keymaps/hp @@ -0,0 +1,105 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "hil" +{ + VK_OEM_3 <71> + VK_KEY_1 <70> + VK_KEY_2 <69> + VK_KEY_3 <68> + VK_KEY_4 <67> + VK_KEY_5 <66> + VK_KEY_6 <65> + VK_KEY_7 <64> + VK_KEY_8 <96> + VK_KEY_9 <97> + VK_KEY_0 <98> + VK_OEM_MINUS <99> + VK_OEM_PLUS <100> + VK_BACK <101> + VK_TAB <63> + VK_KEY_Q <62> + VK_KEY_W <61> + VK_KEY_E <60> + VK_KEY_R <59> + VK_KEY_T <58> + VK_KEY_Y <57> + VK_KEY_U <56> + VK_KEY_I <104> + VK_KEY_O <105> + VK_KEY_P <106> + VK_OEM_4 <107> + VK_OEM_6 <108> + VK_OEM_5 <109> + VK_CAPITAL <55> + VK_KEY_A <53> + VK_KEY_S <52> + VK_KEY_D <51> + VK_KEY_F <50> + VK_KEY_G <49> + VK_KEY_H <48> + VK_KEY_J <112> + VK_KEY_K <113> + VK_KEY_L <114> + VK_OEM_1 <115> + VK_OEM_7 <116> + VK_RETURN <117> + VK_LSHIFT <13> + VK_KEY_Z <36> + VK_KEY_X <35> + VK_KEY_C <34> + VK_KEY_V <33> + VK_KEY_B <32> + VK_KEY_N <128> + VK_KEY_M <120> + VK_OEM_COMMA <121> + VK_OEM_PERIOD <122> + VK_OEM_2 <123> + VK_RSHIFT <12> + VK_LCONTROL <14> + VK_LMENU <11> + VK_SPACE <129> + VK_RMENU <10> + VK_SNAPSHOT <87> + VK_ESCAPE <39> + VK_F1 <84> + VK_F2 <83> + VK_F3 <82> + VK_F4 <81> + VK_APPS <80> + VK_F5 <89> + VK_F6 <90> + VK_F7 <91> + VK_F8 <92> + VK_F9 <45> + VK_F10 <41> + VK_F11 <43> + VK_F12 <47> + VK_HOME <118> + VK_PRIOR <119> + VK_NEXT <127> + VK_SELECT <125> + VK_UP <134> + VK_LEFT <132> + VK_DOWN <133> + VK_RIGHT <135> + VK_DIVIDE <25> + VK_MULTIPLY <29> + VK_ADD <27> + VK_SUBTRACT <31> + VK_NUMPAD7 <21> + VK_NUMPAD8 <17> + VK_NUMPAD9 <19> + VK_RETURN <23> + VK_NUMPAD4 <16> + VK_NUMPAD5 <18> + VK_NUMPAD6 <20> + VK_NUMPAD1 <24> + VK_NUMPAD2 <26> + VK_NUMPAD3 <28> + VK_NUMPAD0 <30> + VK_DECIMAL <44> +}; + diff --git a/keymaps/ibm b/keymaps/ibm new file mode 100644 index 0000000..be9e61b --- /dev/null +++ b/keymaps/ibm @@ -0,0 +1,5 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + diff --git a/keymaps/macintosh b/keymaps/macintosh new file mode 100644 index 0000000..8d24f7d --- /dev/null +++ b/keymaps/macintosh @@ -0,0 +1,142 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "macintosh" +: extends "xfree86" +{ + VK_F13 <182> + VK_F14 <183> + VK_F15 <184> +}; + +keyboard "old" +{ + VK_ESCAPE <61> + VK_OEM_3 <58> + VK_KEY_1 <26> + VK_KEY_2 <27> + VK_KEY_3 <28> + VK_KEY_4 <29> + VK_KEY_5 <31> + VK_KEY_6 <30> + VK_KEY_7 <34> + VK_KEY_8 <36> + VK_KEY_9 <33> + VK_KEY_0 <37> + VK_OEM_MINUS <35> + VK_OEM_PLUS <32> + VK_BACK <59> + VK_TAB <56> + VK_KEY_Q <20> + VK_KEY_W <21> + VK_KEY_E <22> + VK_KEY_R <23> + VK_KEY_T <25> + VK_KEY_Y <24> + VK_KEY_U <40> + VK_KEY_I <42> + VK_KEY_O <39> + VK_KEY_P <43> + VK_OEM_4 <41> + VK_OEM_6 <38> + VK_OEM_5 <50> + VK_CAPITAL <65> + VK_KEY_A <8> + VK_KEY_S <9> + VK_KEY_D <10> + VK_KEY_F <11> + VK_KEY_G <13> + VK_KEY_H <12> + VK_KEY_J <46> + VK_KEY_K <48> + VK_KEY_L <45> + VK_OEM_1 <49> + VK_OEM_7 <47> + VK_RETURN <44> + VK_OEM_102 <18> + VK_KEY_Z <14> + VK_KEY_X <15> + VK_KEY_C <16> + VK_KEY_V <17> + VK_KEY_B <19> + VK_KEY_N <53> + VK_KEY_M <54> + VK_OEM_COMMA <51> + VK_OEM_PERIOD <55> + VK_OEM_2 <52> + VK_SPACE <57> + VK_LCONTROL <62> + VK_LMENU <63> + VK_LSHIFT <64> + VK_RMENU <66> + VK_RSHIFT <131> + VK_RMENU <132> + VK_RCONTROL <133> + VK_F1 <130> + VK_F2 <128> + VK_F3 <107> + VK_F4 <126> + VK_F5 <104> + VK_F6 <105> + VK_F7 <106> + VK_F8 <108> + VK_F9 <109> + VK_F10 <117> + VK_F11 <111> + VK_F12 <119> + VK_SNAPSHOT <113> + VK_SCROLL <115> + VK_PAUSE <121> + VK_INSERT <122> + VK_HOME <123> + VK_PRIOR <124> + VK_DELETE <125> + VK_END <127> + VK_NEXT <129> + VK_UP <70> + VK_LEFT <67> + VK_DOWN <69> + VK_RIGHT <68> + VK_NUMLOCK <79> + VK_DIVIDE <83> + VK_MULTIPLY <75> + VK_NUMPAD7 <97> + VK_NUMPAD8 <99> + VK_NUMPAD9 <100> + VK_SUBTRACT <86> + VK_NUMPAD4 <94> + VK_NUMPAD5 <95> + VK_NUMPAD6 <96> + VK_ADD <77> + VK_NUMPAD1 <91> + VK_NUMPAD2 <92> + VK_NUMPAD3 <93> + VK_RETURN <84> + VK_NUMPAD0 <90> + VK_DECIMAL <73> +}; + +keyboard "hhk" +: extends "macintosh" +{ + VK_OEM_5 <51> + VK_LWIN <49> + VK_RWIN <208> + VK_F13 <111> + VK_F14 <78> + VK_F15 <110> +}; + +keyboard "alukbd" +: extends "xfree86" +{ + VK_F18 <129> + VK_F19 <130> +}; + +keyboard "jisevdev" +{ +}; + diff --git a/keymaps/macosx b/keymaps/macosx new file mode 100644 index 0000000..8363f81 --- /dev/null +++ b/keymaps/macosx @@ -0,0 +1,107 @@ +# This file is manually edited from the "macintosh" keymap +# X11.app is a special case, and xfreerdp on Mac OS X uses this hard-coded keymap instead + +keyboard "macosx" +{ + VK_ESCAPE <61> + VK_OEM_3 <58> + VK_KEY_1 <26> + VK_KEY_2 <27> + VK_KEY_3 <28> + VK_KEY_4 <29> + VK_KEY_5 <31> + VK_KEY_6 <30> + VK_KEY_7 <34> + VK_KEY_8 <36> + VK_KEY_9 <33> + VK_KEY_0 <37> + VK_OEM_MINUS <35> + VK_OEM_PLUS <32> + VK_BACK <59> + VK_TAB <56> + VK_KEY_Q <20> + VK_KEY_W <21> + VK_KEY_E <22> + VK_KEY_R <23> + VK_KEY_T <25> + VK_KEY_Y <24> + VK_KEY_U <40> + VK_KEY_I <42> + VK_KEY_O <39> + VK_KEY_P <43> + VK_OEM_4 <41> + VK_OEM_6 <38> + VK_OEM_5 <50> + VK_CAPITAL <65> + VK_KEY_A <8> + VK_KEY_S <9> + VK_KEY_D <10> + VK_KEY_F <11> + VK_KEY_G <13> + VK_KEY_H <12> + VK_KEY_J <46> + VK_KEY_K <48> + VK_KEY_L <45> + VK_OEM_1 <49> + VK_OEM_7 <47> + VK_RETURN <44> + VK_OEM_102 <18> + VK_KEY_Z <14> + VK_KEY_X <15> + VK_KEY_C <16> + VK_KEY_V <17> + VK_KEY_B <19> + VK_KEY_N <53> + VK_KEY_M <54> + VK_OEM_COMMA <51> + VK_OEM_PERIOD <55> + VK_OEM_2 <52> + VK_SPACE <57> + VK_LCONTROL <67> + VK_LMENU <66> + VK_LSHIFT <64> + VK_RMENU <69> + VK_RSHIFT <68> + VK_F1 <130> + VK_F2 <128> + VK_F3 <107> + VK_F4 <126> + VK_F5 <104> + VK_F6 <105> + VK_F7 <106> + VK_F8 <108> + VK_F9 <109> + VK_F10 <117> + VK_F11 <111> + VK_F12 <119> + VK_SNAPSHOT <113> + VK_SCROLL <115> + VK_PAUSE <121> + VK_INSERT <122> + VK_HOME <123> + VK_PRIOR <124> + VK_DELETE <125> + VK_END <127> + VK_NEXT <129> + VK_UP <134> + VK_LEFT <131> + VK_DOWN <133> + VK_RIGHT <132> + VK_NUMLOCK <79> + VK_DIVIDE <83> + VK_MULTIPLY <75> + VK_NUMPAD7 <97> + VK_NUMPAD8 <99> + VK_NUMPAD9 <100> + VK_SUBTRACT <86> + VK_NUMPAD4 <94> + VK_NUMPAD5 <95> + VK_NUMPAD6 <96> + VK_ADD <77> + VK_NUMPAD1 <91> + VK_NUMPAD2 <92> + VK_NUMPAD3 <93> + VK_RETURN <84> + VK_NUMPAD0 <90> + VK_DECIMAL <73> +}; diff --git a/keymaps/sgi_vndr/indigo b/keymaps/sgi_vndr/indigo new file mode 100644 index 0000000..6a79b21 --- /dev/null +++ b/keymaps/sgi_vndr/indigo @@ -0,0 +1,116 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "pc101" +{ + VK_OEM_3 <62> + VK_KEY_1 <15> + VK_KEY_2 <21> + VK_KEY_3 <22> + VK_KEY_4 <29> + VK_KEY_5 <30> + VK_KEY_6 <37> + VK_KEY_7 <38> + VK_KEY_8 <45> + VK_KEY_9 <46> + VK_KEY_0 <53> + VK_OEM_MINUS <54> + VK_OEM_PLUS <61> + VK_BACK <68> + VK_TAB <16> + VK_KEY_Q <17> + VK_KEY_W <23> + VK_KEY_E <24> + VK_KEY_R <31> + VK_KEY_T <32> + VK_KEY_Y <39> + VK_KEY_U <40> + VK_KEY_I <47> + VK_KEY_O <48> + VK_KEY_P <55> + VK_OEM_4 <56> + VK_OEM_6 <63> + VK_RETURN <58> + VK_CAPITAL <11> + VK_KEY_A <18> + VK_KEY_S <19> + VK_KEY_D <25> + VK_KEY_F <26> + VK_KEY_G <33> + VK_KEY_H <34> + VK_KEY_J <41> + VK_KEY_K <42> + VK_KEY_L <49> + VK_OEM_1 <50> + VK_OEM_7 <57> + VK_LSHIFT <13> + VK_KEY_Z <27> + VK_KEY_X <28> + VK_KEY_C <35> + VK_KEY_V <36> + VK_KEY_B <43> + VK_KEY_N <44> + VK_KEY_M <51> + VK_OEM_COMMA <52> + VK_OEM_PERIOD <59> + VK_OEM_2 <60> + VK_RSHIFT <12> + VK_OEM_5 <64> + VK_LMENU <91> + VK_LCONTROL <10> + VK_SPACE <90> + VK_RCONTROL <93> + VK_RMENU <92> + VK_ESCAPE <14> + VK_F1 <94> + VK_F2 <95> + VK_F3 <96> + VK_F4 <97> + VK_F5 <98> + VK_F6 <99> + VK_F7 <100> + VK_F8 <101> + VK_F9 <102> + VK_F10 <103> + VK_F11 <104> + VK_F12 <105> + VK_SNAPSHOT <106> + VK_SCROLL <107> + VK_PAUSE <108> + VK_INSERT <109> + VK_HOME <110> + VK_PRIOR <111> + VK_DELETE <69> + VK_END <112> + VK_NEXT <113> + VK_UP <88> + VK_LEFT <80> + VK_DOWN <81> + VK_RIGHT <87> + VK_NUMLOCK <114> + VK_DIVIDE <115> + VK_MULTIPLY <116> + VK_SUBTRACT <83> + VK_NUMPAD7 <74> + VK_NUMPAD8 <75> + VK_NUMPAD9 <82> + VK_ADD <117> + VK_NUMPAD4 <70> + VK_NUMPAD5 <76> + VK_NUMPAD6 <77> + VK_NUMPAD1 <65> + VK_NUMPAD2 <71> + VK_NUMPAD3 <72> + VK_RETURN <89> + VK_NUMPAD0 <66> + VK_DECIMAL <73> +}; + +keyboard "pc102" +: extends "sgi_vndr/indigo(pc101)" +{ + VK_OEM_102 <118> +}; + diff --git a/keymaps/sgi_vndr/indy b/keymaps/sgi_vndr/indy new file mode 100644 index 0000000..e451926 --- /dev/null +++ b/keymaps/sgi_vndr/indy @@ -0,0 +1,148 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "universal" +{ + VK_OEM_5 <91> + VK_OEM_5 <100> + VK_OEM_5 <101> +}; + +keyboard "pc101" +{ + VK_OEM_3 <22> + VK_KEY_1 <30> + VK_KEY_2 <38> + VK_KEY_3 <46> + VK_KEY_4 <45> + VK_KEY_5 <54> + VK_KEY_6 <62> + VK_KEY_7 <69> + VK_KEY_8 <70> + VK_KEY_9 <78> + VK_KEY_0 <77> + VK_OEM_MINUS <86> + VK_OEM_PLUS <93> + VK_BACK <110> + VK_TAB <21> + VK_KEY_Q <29> + VK_KEY_W <37> + VK_KEY_E <44> + VK_KEY_R <53> + VK_KEY_T <52> + VK_KEY_Y <61> + VK_KEY_U <68> + VK_KEY_I <75> + VK_KEY_O <76> + VK_KEY_P <85> + VK_OEM_4 <92> + VK_OEM_6 <99> + VK_RETURN <98> + VK_CAPITAL <28> + VK_KEY_A <36> + VK_KEY_S <35> + VK_KEY_D <43> + VK_KEY_F <51> + VK_KEY_G <60> + VK_KEY_H <59> + VK_KEY_J <67> + VK_KEY_K <74> + VK_KEY_L <83> + VK_OEM_1 <84> + VK_OEM_7 <90> + VK_LSHIFT <26> + VK_KEY_Z <34> + VK_KEY_X <42> + VK_KEY_C <41> + VK_KEY_V <50> + VK_KEY_B <58> + VK_KEY_N <57> + VK_KEY_M <66> + VK_OEM_COMMA <73> + VK_OEM_PERIOD <81> + VK_OEM_2 <82> + VK_RSHIFT <97> + VK_OEM_5 <100> + VK_LMENU <33> + VK_LCONTROL <25> + VK_SPACE <49> + VK_RCONTROL <96> + VK_RMENU <65> + VK_ESCAPE <16> + VK_F1 <15> + VK_F2 <23> + VK_F3 <31> + VK_F4 <39> + VK_F5 <47> + VK_F6 <55> + VK_F7 <63> + VK_F8 <71> + VK_F9 <79> + VK_F10 <87> + VK_F11 <94> + VK_F12 <102> + VK_SNAPSHOT <95> + VK_SCROLL <103> + VK_PAUSE <106> + VK_INSERT <111> + VK_HOME <118> + VK_PRIOR <119> + VK_DELETE <108> + VK_END <109> + VK_NEXT <117> + VK_UP <107> + VK_LEFT <105> + VK_DOWN <104> + VK_RIGHT <114> + VK_NUMLOCK <126> + VK_DIVIDE <127> + VK_MULTIPLY <134> + VK_SUBTRACT <140> + VK_NUMPAD7 <116> + VK_NUMPAD8 <125> + VK_NUMPAD9 <133> + VK_ADD <132> + VK_NUMPAD4 <115> + VK_NUMPAD5 <123> + VK_NUMPAD6 <124> + VK_NUMPAD1 <113> + VK_NUMPAD2 <122> + VK_NUMPAD3 <130> + VK_RETURN <129> + VK_NUMPAD0 <120> + VK_DECIMAL <121> +}; + +keyboard "pc102" +{ + VK_OEM_102 <27> +}; + +keyboard "pc104" +: extends "sgi_vndr/indy(pc101)" +{ + VK_LWIN <147> + VK_RWIN <148> + VK_APPS <149> +}; + +keyboard "pc105" +{ +}; + +keyboard "jp106" +{ + VK_ABNT_C1 <89> + VK_OEM_5 <91> +}; + +keyboard "overlayKeypad" +{ +}; + +keyboard "shiftLock" +{ +}; + diff --git a/keymaps/sgi_vndr/iris b/keymaps/sgi_vndr/iris new file mode 100644 index 0000000..2b2fa55 --- /dev/null +++ b/keymaps/sgi_vndr/iris @@ -0,0 +1,10 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "iris" +: extends "sgi_vndr/indigo(pc101)" +{ +}; + diff --git a/keymaps/sony b/keymaps/sony new file mode 100644 index 0000000..f65782a --- /dev/null +++ b/keymaps/sony @@ -0,0 +1,103 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "nwp5461" +{ + VK_ESCAPE <18> + VK_KEY_1 <19> + VK_KEY_2 <20> + VK_KEY_3 <21> + VK_KEY_4 <22> + VK_KEY_5 <23> + VK_KEY_6 <24> + VK_KEY_7 <25> + VK_KEY_8 <26> + VK_KEY_9 <27> + VK_KEY_0 <28> + VK_OEM_MINUS <29> + VK_OEM_PLUS <30> + VK_OEM_5 <31> + VK_BACK <32> + VK_TAB <33> + VK_KEY_Q <34> + VK_KEY_W <35> + VK_KEY_E <36> + VK_KEY_R <37> + VK_KEY_T <38> + VK_KEY_Y <39> + VK_KEY_U <40> + VK_KEY_I <41> + VK_KEY_O <42> + VK_KEY_P <43> + VK_OEM_4 <44> + VK_OEM_6 <45> + VK_DELETE <46> + VK_LCONTROL <47> + VK_KEY_A <48> + VK_KEY_S <49> + VK_KEY_D <50> + VK_KEY_F <51> + VK_KEY_G <52> + VK_KEY_H <53> + VK_KEY_J <54> + VK_KEY_K <55> + VK_KEY_L <56> + VK_OEM_1 <57> + VK_OEM_7 <58> + VK_OEM_3 <59> + VK_RETURN <60> + VK_LSHIFT <61> + VK_KEY_Z <62> + VK_KEY_X <63> + VK_KEY_C <64> + VK_KEY_V <65> + VK_KEY_B <66> + VK_KEY_N <67> + VK_KEY_M <68> + VK_OEM_COMMA <69> + VK_OEM_PERIOD <70> + VK_OEM_2 <71> + VK_ABNT_C1 <72> + VK_RSHIFT <73> + VK_LMENU <74> + VK_CAPITAL <75> + VK_SPACE <77> + VK_F1 <8> + VK_F2 <9> + VK_F3 <10> + VK_F4 <11> + VK_F5 <12> + VK_F6 <13> + VK_F7 <14> + VK_F8 <15> + VK_F9 <16> + VK_F10 <17> + VK_F11 <111> + VK_F12 <112> + VK_HELP <113> + VK_INSERT <114> + VK_PRIOR <116> + VK_NEXT <117> + VK_UP <95> + VK_LEFT <98> + VK_DOWN <99> + VK_RIGHT <100> + VK_MULTIPLY <107> + VK_DIVIDE <108> + VK_ADD <89> + VK_NUMPAD7 <82> + VK_NUMPAD8 <83> + VK_NUMPAD9 <84> + VK_SUBTRACT <85> + VK_NUMPAD4 <86> + VK_NUMPAD5 <87> + VK_NUMPAD6 <88> + VK_NUMPAD1 <90> + VK_NUMPAD2 <91> + VK_NUMPAD3 <92> + VK_RETURN <97> + VK_NUMPAD0 <94> +}; + diff --git a/keymaps/sun b/keymaps/sun new file mode 100644 index 0000000..1eecd1b --- /dev/null +++ b/keymaps/sun @@ -0,0 +1,618 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "type4" +{ + VK_ESCAPE <36> + VK_KEY_1 <37> + VK_KEY_2 <38> + VK_KEY_3 <39> + VK_KEY_4 <40> + VK_KEY_5 <41> + VK_KEY_6 <42> + VK_KEY_7 <43> + VK_KEY_8 <44> + VK_KEY_9 <45> + VK_KEY_0 <46> + VK_OEM_MINUS <47> + VK_OEM_PLUS <48> + VK_OEM_3 <49> + VK_BACK <50> + VK_TAB <60> + VK_KEY_Q <61> + VK_KEY_W <62> + VK_KEY_E <63> + VK_KEY_R <64> + VK_KEY_T <65> + VK_KEY_Y <66> + VK_KEY_U <67> + VK_KEY_I <68> + VK_KEY_O <69> + VK_KEY_P <70> + VK_OEM_4 <71> + VK_OEM_6 <72> + VK_DELETE <73> + VK_LCONTROL <83> + VK_KEY_A <84> + VK_KEY_S <85> + VK_KEY_D <86> + VK_KEY_F <87> + VK_KEY_G <88> + VK_KEY_H <89> + VK_KEY_J <90> + VK_KEY_K <91> + VK_KEY_L <92> + VK_OEM_1 <93> + VK_OEM_7 <94> + VK_OEM_5 <95> + VK_RETURN <96> + VK_LSHIFT <106> + VK_KEY_Z <107> + VK_KEY_X <108> + VK_KEY_C <109> + VK_KEY_V <110> + VK_KEY_B <111> + VK_KEY_N <112> + VK_KEY_M <113> + VK_OEM_COMMA <114> + VK_OEM_PERIOD <115> + VK_OEM_2 <116> + VK_RSHIFT <117> + VK_HELP <125> + VK_CAPITAL <126> + VK_LMENU <26> + VK_SPACE <128> + VK_APPS <74> + VK_F1 <12> + VK_F2 <13> + VK_F3 <15> + VK_F4 <17> + VK_F5 <19> + VK_F6 <21> + VK_F7 <23> + VK_F8 <24> + VK_F9 <25> + VK_F10 <14> + VK_F11 <16> + VK_F12 <18> + VK_SNAPSHOT <29> + VK_SCROLL <30> + VK_PAUSE <28> + VK_NUMLOCK <105> + VK_DIVIDE <53> + VK_MULTIPLY <54> + VK_SUBTRACT <78> + VK_NUMPAD7 <75> + VK_NUMPAD8 <76> + VK_NUMPAD9 <77> + VK_ADD <132> + VK_NUMPAD4 <98> + VK_NUMPAD5 <99> + VK_NUMPAD6 <100> + VK_NUMPAD1 <119> + VK_NUMPAD2 <120> + VK_NUMPAD3 <121> + VK_RETURN <97> + VK_NUMPAD0 <101> + VK_DECIMAL <57> +}; + +keyboard "type5" +{ + VK_ESCAPE <36> + VK_KEY_1 <37> + VK_KEY_2 <38> + VK_KEY_3 <39> + VK_KEY_4 <40> + VK_KEY_5 <41> + VK_KEY_6 <42> + VK_KEY_7 <43> + VK_KEY_8 <44> + VK_KEY_9 <45> + VK_KEY_0 <46> + VK_OEM_MINUS <47> + VK_OEM_PLUS <48> + VK_OEM_3 <49> + VK_BACK <50> + VK_TAB <60> + VK_KEY_Q <61> + VK_KEY_W <62> + VK_KEY_E <63> + VK_KEY_R <64> + VK_KEY_T <65> + VK_KEY_Y <66> + VK_KEY_U <67> + VK_KEY_I <68> + VK_KEY_O <69> + VK_KEY_P <70> + VK_OEM_4 <71> + VK_OEM_6 <72> + VK_DELETE <73> + VK_APPS <74> + VK_LCONTROL <83> + VK_KEY_A <84> + VK_KEY_S <85> + VK_KEY_D <86> + VK_KEY_F <87> + VK_KEY_G <88> + VK_KEY_H <89> + VK_KEY_J <90> + VK_KEY_K <91> + VK_KEY_L <92> + VK_OEM_1 <93> + VK_OEM_7 <94> + VK_OEM_5 <95> + VK_RETURN <96> + VK_LSHIFT <106> + VK_KEY_Z <107> + VK_KEY_X <108> + VK_KEY_C <109> + VK_KEY_V <110> + VK_KEY_B <111> + VK_KEY_N <112> + VK_KEY_M <113> + VK_OEM_COMMA <114> + VK_OEM_PERIOD <115> + VK_OEM_2 <116> + VK_RSHIFT <117> + VK_LMENU <26> + VK_CAPITAL <126> + VK_SPACE <128> + VK_F1 <12> + VK_F2 <13> + VK_F3 <15> + VK_F4 <17> + VK_F5 <19> + VK_F6 <21> + VK_F7 <23> + VK_F8 <24> + VK_F9 <25> + VK_F10 <14> + VK_F11 <16> + VK_F12 <18> + VK_SNAPSHOT <29> + VK_SCROLL <30> + VK_PAUSE <28> + VK_NUMLOCK <105> + VK_DIVIDE <53> + VK_MULTIPLY <54> + VK_SUBTRACT <78> + VK_NUMPAD7 <75> + VK_NUMPAD8 <76> + VK_NUMPAD9 <77> + VK_ADD <132> + VK_NUMPAD4 <98> + VK_NUMPAD5 <99> + VK_NUMPAD6 <100> + VK_NUMPAD1 <119> + VK_NUMPAD2 <120> + VK_NUMPAD3 <121> + VK_RETURN <97> + VK_NUMPAD0 <101> + VK_DECIMAL <57> + VK_UP <27> + VK_LEFT <31> + VK_DOWN <34> + VK_RIGHT <35> + VK_INSERT <51> + VK_HOME <59> + VK_END <81> + VK_PRIOR <103> + VK_NEXT <130> + VK_HELP <125> +}; + +keyboard "type4tuv" +: extends "sun(type4)" +{ + VK_OEM_102 <131> +}; + +keyboard "type4_ca" +: extends "sun(type4)" +{ + VK_OEM_102 <131> +}; + +keyboard "type4_jp" +: extends "sun(type4)" +{ + VK_KANJI <123> +}; + +keyboard "type4_euro" +: extends "sun(type4)" +{ + VK_OEM_102 <131> +}; + +keyboard "type5tuv" +: extends "sun(type5)" +{ + VK_OEM_102 <131> +}; + +keyboard "type5_jp" +: extends "sun(type5)" +{ + VK_KANJI <123> +}; + +keyboard "type5_euro" +: extends "sun(type5)" +{ + VK_OEM_102 <131> +}; + +keyboard "type5hobo" +{ + VK_ESCAPE <36> + VK_KEY_1 <37> + VK_KEY_2 <38> + VK_KEY_3 <39> + VK_KEY_4 <40> + VK_KEY_5 <41> + VK_KEY_6 <42> + VK_KEY_7 <43> + VK_KEY_8 <44> + VK_KEY_9 <45> + VK_KEY_0 <46> + VK_OEM_MINUS <47> + VK_OEM_PLUS <48> + VK_OEM_3 <49> + VK_BACK <50> + VK_TAB <60> + VK_KEY_Q <61> + VK_KEY_W <62> + VK_KEY_E <63> + VK_KEY_R <64> + VK_KEY_T <65> + VK_KEY_Y <66> + VK_KEY_U <67> + VK_KEY_I <68> + VK_KEY_O <69> + VK_KEY_P <70> + VK_OEM_4 <71> + VK_OEM_6 <72> + VK_DELETE <73> + VK_APPS <74> + VK_LCONTROL <83> + VK_KEY_A <84> + VK_KEY_S <85> + VK_KEY_D <86> + VK_KEY_F <87> + VK_KEY_G <88> + VK_KEY_H <89> + VK_KEY_J <90> + VK_KEY_K <91> + VK_KEY_L <92> + VK_OEM_1 <93> + VK_OEM_7 <94> + VK_OEM_5 <95> + VK_RETURN <96> + VK_LSHIFT <106> + VK_KEY_Z <107> + VK_KEY_X <108> + VK_KEY_C <109> + VK_KEY_V <110> + VK_KEY_B <111> + VK_KEY_N <112> + VK_KEY_M <113> + VK_OEM_COMMA <114> + VK_OEM_PERIOD <115> + VK_OEM_2 <116> + VK_RSHIFT <117> + VK_LMENU <26> + VK_CAPITAL <126> + VK_SPACE <128> + VK_F1 <12> + VK_F2 <13> + VK_F3 <15> + VK_F4 <17> + VK_F5 <19> + VK_F6 <21> + VK_F7 <23> + VK_F8 <24> + VK_F9 <25> + VK_F10 <14> + VK_F11 <16> + VK_F12 <18> + VK_SNAPSHOT <29> + VK_SCROLL <30> + VK_PAUSE <28> + VK_NUMLOCK <105> + VK_DIVIDE <53> + VK_MULTIPLY <54> + VK_SUBTRACT <78> + VK_NUMPAD7 <75> + VK_NUMPAD8 <76> + VK_NUMPAD9 <77> + VK_ADD <132> + VK_NUMPAD4 <98> + VK_NUMPAD5 <99> + VK_NUMPAD6 <100> + VK_NUMPAD1 <119> + VK_NUMPAD2 <120> + VK_NUMPAD3 <121> + VK_RETURN <97> + VK_NUMPAD0 <101> + VK_DECIMAL <57> + VK_UP <27> + VK_LEFT <31> + VK_DOWN <34> + VK_RIGHT <35> + VK_INSERT <51> + VK_HOME <59> + VK_END <81> + VK_PRIOR <103> + VK_NEXT <130> + VK_HELP <125> +}; + +keyboard "type5tuvhobo" +: extends "sun(type5hobo)" +{ + VK_OEM_102 <131> +}; + +keyboard "type5_jphobo" +: extends "sun(type5hobo)" +{ + VK_KANJI <123> +}; + +keyboard "type6" +: extends "sun(type5)" +{ +}; + +keyboard "type6tuv" +: extends "sun(type5tuv)" +{ +}; + +keyboard "type6unix" +: extends "sun(type5)" +{ +}; + +keyboard "type6_jp" +: extends "sun(type5_jp)" +{ +}; + +keyboard "type6_euro" +: extends "sun(type5_euro)" +{ +}; + +keyboard "type6_usb" +: extends "xfree86" +{ + VK_HELP <245> +}; + +keyboard "type6tuv_usb" +: extends "sun(type6_usb)" +{ + VK_OEM_102 <94> + VK_OEM_5 <51> +}; + +keyboard "type6_jp_usb" +: extends "sun(type6_usb)" +{ +}; + +keyboard "type5_se" +{ + VK_HELP <125> + VK_ESCAPE <36> + VK_F1 <12> + VK_F2 <13> + VK_F3 <15> + VK_F4 <17> + VK_F5 <19> + VK_F6 <21> + VK_F7 <23> + VK_F8 <24> + VK_F9 <25> + VK_F10 <14> + VK_F11 <16> + VK_F12 <18> + VK_SNAPSHOT <29> + VK_SCROLL <30> + VK_PAUSE <28> + VK_TILDE <49> + VK_KEY_1 <37> + VK_KEY_2 <38> + VK_KEY_3 <39> + VK_KEY_4 <40> + VK_KEY_5 <41> + VK_KEY_6 <42> + VK_KEY_7 <43> + VK_KEY_8 <44> + VK_KEY_9 <45> + VK_KEY_0 <46> + VK_OEM_MINUS <47> + VK_OEM_PLUS <48> + VK_BACK <50> + VK_INSERT <51> + VK_HOME <59> + VK_PRIOR <103> + VK_NUMLOCK <105> + VK_DIVIDE <53> + VK_MULTIPLY <54> + VK_SUBTRACT <78> + VK_KEY_Q <61> + VK_KEY_W <62> + VK_KEY_E <63> + VK_KEY_R <64> + VK_KEY_T <65> + VK_KEY_Y <66> + VK_KEY_U <67> + VK_KEY_I <68> + VK_KEY_O <69> + VK_KEY_P <70> + VK_OEM_4 <71> + VK_OEM_6 <72> + VK_DELETE <73> + VK_END <81> + VK_NEXT <130> + VK_NUMPAD7 <75> + VK_NUMPAD8 <76> + VK_NUMPAD9 <77> + VK_ADD <132> + VK_KEY_A <84> + VK_KEY_S <85> + VK_KEY_D <86> + VK_KEY_F <87> + VK_KEY_G <88> + VK_KEY_H <89> + VK_KEY_J <90> + VK_KEY_K <91> + VK_KEY_L <92> + VK_OEM_1 <93> + VK_OEM_7 <94> + VK_OEM_5 <95> + VK_RETURN <96> + VK_NUMPAD4 <98> + VK_NUMPAD5 <99> + VK_NUMPAD6 <100> + VK_LSHIFT <106> + VK_LSHIFT <131> + VK_KEY_Z <107> + VK_KEY_X <108> + VK_KEY_C <109> + VK_KEY_V <110> + VK_KEY_B <111> + VK_KEY_N <112> + VK_KEY_M <113> + VK_OEM_COMMA <114> + VK_OEM_PERIOD <115> + VK_OEM_2 <116> + VK_RSHIFT <117> + VK_UP <27> + VK_NUMPAD1 <119> + VK_NUMPAD2 <120> + VK_NUMPAD3 <121> + VK_RETURN <97> + VK_LCONTROL <83> + VK_LMENU <26> + VK_SPACE <128> + VK_APPS <74> + VK_LEFT <31> + VK_DOWN <34> + VK_RIGHT <35> + VK_NUMPAD0 <101> + VK_DECIMAL <57> +}; + +keyboard "type5c_se" +: extends "sun(type5_se)" +{ +}; + +keyboard "type4__se" +{ + VK_F1 <12> + VK_F2 <13> + VK_F3 <15> + VK_F4 <17> + VK_F5 <19> + VK_F6 <21> + VK_F7 <23> + VK_F8 <24> + VK_F9 <25> + VK_F10 <14> + VK_F11 <16> + VK_F12 <18> + VK_DELETE <73> + VK_PAUSE <28> + VK_SNAPSHOT <29> + VK_SCROLL <30> + VK_NUMLOCK <105> + VK_TILDE <36> + VK_KEY_1 <37> + VK_KEY_2 <38> + VK_KEY_3 <39> + VK_KEY_4 <40> + VK_KEY_5 <41> + VK_KEY_6 <42> + VK_KEY_7 <43> + VK_KEY_8 <44> + VK_KEY_9 <45> + VK_KEY_0 <46> + VK_OEM_MINUS <47> + VK_OEM_PLUS <48> + VK_BACK <50> + VK_DIVIDE <53> + VK_MULTIPLY <54> + VK_SUBTRACT <78> + VK_KEY_Q <61> + VK_KEY_W <62> + VK_KEY_E <63> + VK_KEY_R <64> + VK_KEY_T <65> + VK_KEY_Y <66> + VK_KEY_U <67> + VK_KEY_I <68> + VK_KEY_O <69> + VK_KEY_P <70> + VK_OEM_4 <71> + VK_OEM_6 <72> + VK_NUMPAD7 <75> + VK_NUMPAD8 <76> + VK_NUMPAD9 <77> + VK_ADD <132> + VK_KEY_A <84> + VK_KEY_S <85> + VK_KEY_D <86> + VK_KEY_F <87> + VK_KEY_G <88> + VK_KEY_H <89> + VK_KEY_J <90> + VK_KEY_K <91> + VK_KEY_L <92> + VK_OEM_1 <93> + VK_OEM_7 <94> + VK_OEM_5 <49> + VK_RETURN <96> + VK_NUMPAD4 <98> + VK_NUMPAD5 <99> + VK_NUMPAD6 <100> + VK_LSHIFT <106> + VK_LSHIFT <131> + VK_KEY_Z <107> + VK_KEY_X <108> + VK_KEY_C <109> + VK_KEY_V <110> + VK_KEY_B <111> + VK_KEY_N <112> + VK_KEY_M <113> + VK_OEM_COMMA <114> + VK_OEM_PERIOD <115> + VK_OEM_2 <116> + VK_RSHIFT <117> + VK_NUMPAD1 <119> + VK_NUMPAD2 <120> + VK_NUMPAD3 <121> + VK_RETURN <97> + VK_HELP <125> + VK_LMENU <26> + VK_SPACE <128> + VK_APPS <74> + VK_NUMPAD0 <101> + VK_DECIMAL <57> +}; + +keyboard "type4_se" +{ +}; + +keyboard "type4_se_swapctl" +{ +}; + diff --git a/keymaps/xfree86 b/keymaps/xfree86 new file mode 100644 index 0000000..63d5c2e --- /dev/null +++ b/keymaps/xfree86 @@ -0,0 +1,152 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "xfree86" +: extends "xfree86(basic)" +{ + VK_OEM_5 <51> + VK_OEM_102 <94> +}; + +keyboard "basic" +{ + VK_OEM_3 <49> + VK_KEY_1 <10> + VK_KEY_2 <11> + VK_KEY_3 <12> + VK_KEY_4 <13> + VK_KEY_5 <14> + VK_KEY_6 <15> + VK_KEY_7 <16> + VK_KEY_8 <17> + VK_KEY_9 <18> + VK_KEY_0 <19> + VK_OEM_MINUS <20> + VK_OEM_PLUS <21> + VK_BACK <22> + VK_TAB <23> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_RETURN <36> + VK_CAPITAL <66> + VK_KEY_A <38> + VK_KEY_S <39> + VK_KEY_D <40> + VK_KEY_F <41> + VK_KEY_G <42> + VK_KEY_H <43> + VK_KEY_J <44> + VK_KEY_K <45> + VK_KEY_L <46> + VK_OEM_1 <47> + VK_OEM_7 <48> + VK_LSHIFT <50> + VK_KEY_Z <52> + VK_KEY_X <53> + VK_KEY_C <54> + VK_KEY_V <55> + VK_KEY_B <56> + VK_KEY_N <57> + VK_KEY_M <58> + VK_OEM_COMMA <59> + VK_OEM_PERIOD <60> + VK_OEM_2 <61> + VK_RSHIFT <62> + VK_LMENU <64> + VK_LCONTROL <37> + VK_SPACE <65> + VK_RCONTROL <109> + VK_RMENU <113> + VK_LWIN <115> + VK_RWIN <116> + VK_APPS <117> + VK_ESCAPE <9> + VK_F1 <67> + VK_F2 <68> + VK_F3 <69> + VK_F4 <70> + VK_F5 <71> + VK_F6 <72> + VK_F7 <73> + VK_F8 <74> + VK_F9 <75> + VK_F10 <76> + VK_F11 <95> + VK_F12 <96> + VK_SNAPSHOT <111> + VK_SCROLL <78> + VK_PAUSE <110> + VK_INSERT <106> + VK_HOME <97> + VK_PRIOR <99> + VK_DELETE <107> + VK_END <103> + VK_NEXT <105> + VK_UP <98> + VK_LEFT <100> + VK_DOWN <104> + VK_RIGHT <102> + VK_NUMLOCK <77> + VK_DIVIDE <112> + VK_MULTIPLY <63> + VK_SUBTRACT <82> + VK_NUMPAD7 <79> + VK_NUMPAD8 <80> + VK_NUMPAD9 <81> + VK_ADD <86> + VK_NUMPAD4 <83> + VK_NUMPAD5 <84> + VK_NUMPAD6 <85> + VK_NUMPAD1 <87> + VK_NUMPAD2 <88> + VK_NUMPAD3 <89> + VK_RETURN <108> + VK_NUMPAD0 <90> + VK_DECIMAL <91> + VK_F13 <118> + VK_F14 <119> + VK_F15 <120> + VK_F16 <121> + VK_F17 <122> + VK_ABNT_C1 <211> +}; + +keyboard "102" +: extends "xfree86(xfree86)" +{ + VK_RMENU <122> + VK_RCONTROL <123> + VK_SNAPSHOT <121> + VK_PAUSE <118> + VK_INSERT <131> + VK_HOME <135> + VK_PRIOR <119> + VK_DELETE <129> + VK_END <130> + VK_NEXT <134> + VK_UP <128> + VK_LEFT <132> + VK_DOWN <120> + VK_RIGHT <133> + VK_DIVIDE <125> + VK_RETURN <124> +}; + +keyboard "thinkpadz60" +: extends "xfree86(xfree86)" +{ + VK_APPS <227> +}; + diff --git a/keymaps/xfree98 b/keymaps/xfree98 new file mode 100644 index 0000000..6e3bae6 --- /dev/null +++ b/keymaps/xfree98 @@ -0,0 +1,106 @@ +# This file was generated with xkb.pl (Wed Aug 11 09:09:10 2010) +# and is based on the X Keyboard Configuration Database version 1.9 +# Please use xkb.pl to re-export newer versions of XKB + + +keyboard "pc98" +{ + VK_ESCAPE <8> + VK_KEY_1 <9> + VK_KEY_2 <10> + VK_KEY_3 <11> + VK_KEY_4 <12> + VK_KEY_5 <13> + VK_KEY_6 <14> + VK_KEY_7 <15> + VK_KEY_8 <16> + VK_KEY_9 <17> + VK_KEY_0 <18> + VK_OEM_MINUS <19> + VK_OEM_PLUS <20> + VK_OEM_5 <21> + VK_BACK <22> + VK_TAB <23> + VK_KEY_Q <24> + VK_KEY_W <25> + VK_KEY_E <26> + VK_KEY_R <27> + VK_KEY_T <28> + VK_KEY_Y <29> + VK_KEY_U <30> + VK_KEY_I <31> + VK_KEY_O <32> + VK_KEY_P <33> + VK_OEM_4 <34> + VK_OEM_6 <35> + VK_RETURN <36> + VK_LCONTROL <124> + VK_CAPITAL <121> + VK_KEY_A <37> + VK_KEY_S <38> + VK_KEY_D <39> + VK_KEY_F <40> + VK_KEY_G <41> + VK_KEY_H <42> + VK_KEY_J <43> + VK_KEY_K <44> + VK_KEY_L <45> + VK_OEM_1 <46> + VK_OEM_7 <47> + VK_OEM_5 <48> + VK_LSHIFT <120> + VK_KEY_Z <49> + VK_KEY_X <50> + VK_KEY_C <51> + VK_KEY_V <52> + VK_KEY_B <53> + VK_KEY_N <54> + VK_KEY_M <55> + VK_OEM_COMMA <56> + VK_OEM_PERIOD <57> + VK_OEM_2 <58> + VK_ABNT_C1 <59> + VK_LMENU <123> + VK_SPACE <60> + VK_SNAPSHOT <105> + VK_F1 <106> + VK_F2 <107> + VK_F3 <108> + VK_F4 <109> + VK_F5 <110> + VK_F6 <111> + VK_F7 <112> + VK_F8 <113> + VK_F9 <114> + VK_F10 <115> + VK_F11 <90> + VK_F12 <91> + VK_F13 <92> + VK_F14 <93> + VK_F15 <94> + VK_INSERT <64> + VK_DELETE <65> + VK_PRIOR <63> + VK_NEXT <62> + VK_UP <66> + VK_LEFT <67> + VK_RIGHT <68> + VK_DOWN <69> + VK_HOME <70> + VK_HELP <71> + VK_SUBTRACT <72> + VK_DIVIDE <73> + VK_NUMPAD7 <74> + VK_NUMPAD8 <75> + VK_NUMPAD9 <76> + VK_MULTIPLY <77> + VK_NUMPAD4 <78> + VK_NUMPAD5 <79> + VK_NUMPAD6 <80> + VK_ADD <81> + VK_NUMPAD1 <82> + VK_NUMPAD2 <83> + VK_NUMPAD3 <84> + VK_NUMPAD0 <86> +}; + diff --git a/keymaps/xkb.pl b/keymaps/xkb.pl new file mode 100755 index 0000000..9faa5a0 --- /dev/null +++ b/keymaps/xkb.pl @@ -0,0 +1,303 @@ +#!/usr/bin/perl + +# FreeRDP: A Remote Desktop Protocol client. +# XKB database conversion script + +# Copyright 2009 Marc-Andre Moreau + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Description: +# Script to export XKB configuration files to keycode -> virtual key code keymaps that are +# easy to use in FreeRDP. This makes keymap maintenance easier to make as all bugs can +# simply be reported to the XKB Configuration Database project, and then this script can +# be used to export newer (and fixed) version of the XKB Configuration Database. + +use Cwd; + +my %sym2virt = ( + "AE00" => "VK_TILDE", + "AE01" => "VK_KEY_1", + "AE02" => "VK_KEY_2", + "AE03" => "VK_KEY_3", + "AE04" => "VK_KEY_4", + "AE05" => "VK_KEY_5", + "AE06" => "VK_KEY_6", + "AE07" => "VK_KEY_7", + "AE08" => "VK_KEY_8", + "AE09" => "VK_KEY_9", + "AE10" => "VK_KEY_0", + "AE11" => "VK_OEM_MINUS", + "AE12" => "VK_OEM_PLUS", + + "AD01" => "VK_KEY_Q", + "AD02" => "VK_KEY_W", + "AD03" => "VK_KEY_E", + "AD04" => "VK_KEY_R", + "AD05" => "VK_KEY_T", + "AD06" => "VK_KEY_Y", + "AD07" => "VK_KEY_U", + "AD08" => "VK_KEY_I", + "AD09" => "VK_KEY_O", + "AD10" => "VK_KEY_P", + "AD11" => "VK_OEM_4", + "AD12" => "VK_OEM_6", + + "AC01" => "VK_KEY_A", + "AC02" => "VK_KEY_S", + "AC03" => "VK_KEY_D", + "AC04" => "VK_KEY_F", + "AC05" => "VK_KEY_G", + "AC06" => "VK_KEY_H", + "AC07" => "VK_KEY_J", + "AC08" => "VK_KEY_K", + "AC09" => "VK_KEY_L", + "AC10" => "VK_OEM_1", + "AC11" => "VK_OEM_7", + "AC12" => "VK_OEM_5", + + "AB00" => "VK_LSHIFT", + "AB01" => "VK_KEY_Z", + "AB02" => "VK_KEY_X", + "AB03" => "VK_KEY_C", + "AB04" => "VK_KEY_V", + "AB05" => "VK_KEY_B", + "AB06" => "VK_KEY_N", + "AB07" => "VK_KEY_M", + "AB08" => "VK_OEM_COMMA", + "AB09" => "VK_OEM_PERIOD", + "AB10" => "VK_OEM_2", + "AB11" => "VK_ABNT_C1", + + "FK01" => "VK_F1", + "FK02" => "VK_F2", + "FK03" => "VK_F3", + "FK04" => "VK_F4", + "FK05" => "VK_F5", + "FK06" => "VK_F6", + "FK07" => "VK_F7", + "FK08" => "VK_F8", + "FK09" => "VK_F9", + "FK10" => "VK_F10", + "FK11" => "VK_F11", + "FK12" => "VK_F12", + "FK13" => "VK_F13", + "FK14" => "VK_F14", + "FK15" => "VK_F15", + "FK16" => "VK_F16", + "FK17" => "VK_F17", + "FK18" => "VK_F18", + "FK19" => "VK_F19", + "FK20" => "VK_F20", + "FK21" => "VK_F21", + "FK22" => "VK_F22", + "FK23" => "VK_F23", + "FK24" => "VK_F24", + + "KP0" => "VK_NUMPAD0", + "KP1" => "VK_NUMPAD1", + "KP2" => "VK_NUMPAD2", + "KP3" => "VK_NUMPAD3", + "KP4" => "VK_NUMPAD4", + "KP5" => "VK_NUMPAD5", + "KP6" => "VK_NUMPAD6", + "KP7" => "VK_NUMPAD7", + "KP8" => "VK_NUMPAD8", + "KP9" => "VK_NUMPAD9", + + "KPDV" => "VK_DIVIDE", + "KPMU" => "VK_MULTIPLY", + "KPSU" => "VK_SUBTRACT", + "KPAD" => "VK_ADD", + "KPDL" => "VK_DECIMAL", + "KPEN" => "VK_RETURN", + + "RTRN" => "VK_RETURN", + "SPCE" => "VK_SPACE", + "BKSP" => "VK_BACK", + "BKSL" => "VK_OEM_5", + "LSGT" => "VK_OEM_102", + "ESC" => "VK_ESCAPE", + "TLDE" => "VK_OEM_3", + "CAPS" => "VK_CAPITAL", + "TAB" => "VK_TAB", + "LFSH" => "VK_LSHIFT", + "RTSH" => "VK_RSHIFT", + "LCTL" => "VK_LCONTROL", + "RCTL" => "VK_RCONTROL", + "LWIN" => "VK_LWIN", + "RWIN" => "VK_RWIN", + "LALT" => "VK_LMENU", + "RALT" => "VK_RMENU", + "COMP" => "VK_APPS", + "MENU" => "VK_APPS", + "UP" => "VK_UP", + "DOWN" => "VK_DOWN", + "LEFT" => "VK_LEFT", + "RGHT" => "VK_RIGHT", + "INS" => "VK_INSERT", + "DELE" => "VK_DELETE", + "PGUP" => "VK_PRIOR", + "PGDN" => "VK_NEXT", + "HOME" => "VK_HOME", + "END" => "VK_END", + "PAUS" => "VK_PAUSE", + "NMLK" => "VK_NUMLOCK", + "SCLK" => "VK_SCROLL", + + # This page helps understanding the keys that follow: + # http://www.stanford.edu/class/cs140/projects/pintos/specs/kbd/scancodes-7.html + + "KANJ" => "VK_KANJI", + "HANJ" => "VK_HANJA", + "MUHE" => "VK_NONCONVERT", + "HIRA" => "VK_KANA", + "PRSC" => "VK_SNAPSHOT", + + "KPF1" => "VK_NUMLOCK", + "KPF2" => "VK_DIVIDE", + "KPF3" => "VK_MULTIPLY", + "KPF4" => "VK_SUBTRACT", + "KPCO" => "VK_ADD", + + "HELP" => "VK_HELP", + "SELE" => "VK_SELECT", + + # We can ignore LDM (Lock Down Modifier) + # What are LCMP/RCMP? + # DO, FIND? + +); + +my $inDir; +my $outDir; + +if(@ARGV < 1) { + $inDir = getcwd() . "/"; + $outDir = $inDir; +} elsif(@ARGV == 1) { + $inDir = $ARGV[0]; + $outDir = getcwd() . "/"; +} elsif(@ARGV == 2) { + $inDir = $ARGV[0]; + $outDir = $ARGV[1]; +} else { + print "Error: Too many arguments\n" . + "Usage:\n" . + "perl xkb.pl \n" . + "perl xkb.pl \n\n" . + "In Linux, the XKB directory usually is /usr/share/X11/xkb/\n" . + "The latest version of XKB can always be downloaded at:\n" . + "http://freedesktop.org/wiki/Software/XKeyboardConfig\n"; + exit 0; +} + + + +open("SPEC", $inDir . "xkeyboard-config.spec"); + +$xkbVersion = ""; +while($line = ) { + if($line =~ m/Version:\s+(.\..)/) { + $xkbVersion = "version $1"; + } +} + +# Create directory if it does not exists +if(not -e $outDir) { + mkdir $outDir or die("Error: Can't create directory $outDir\n"); +} + +open("KCD", $inDir . "keycodes/keycodes.dir") or die("Error: Can't open $inDir" . "keycodes/keycodes.dir\n"); + +$previousFile = ""; +while($line = ) { + if($line =~ m/........ -------- (.+)\((.+)\)/) { + if($1 ne $previousFile) { + push(@keymapFiles, $1); + $previousFile = $1; + } + } +} +close("KCD"); + +foreach $keymapFile (@keymapFiles) { + + print "File $keymapFile:\n"; + + @directories = split(/\//, $keymapFile); + splice(@directories, @directories - 1, 1); + + if(@directories > 0) { + $directory = $outDir; + for($i = 0; $i < @directories; $i++) { + $directory .= $directories[$i] . "/"; + if(not -e $directory) { + mkdir $directory or die("Can't create directory $directory\n"); + } + } + } + + open("IN", $inDir . "keycodes/" . $keymapFile); + open("OUT", ">" . "$outDir" . $keymapFile); + + print OUT "# This file was generated with xkb.pl\n"; + print OUT "# and is based on the X Keyboard Configuration Database $xkbVersion\n"; + print OUT "# Please use xkb.pl to re-export newer versions of XKB\n"; + print OUT "\n\n"; + + while($line = ) { + if($line =~ m/xkb_keycodes \"(\w+)\"/) { + + print "Exporting \"$1\"\n"; + print OUT "keyboard \"$1\""; + + + while($line = ) { + if($line =~ m/include\W+\"(.+)\"/) { + print OUT "\n: extends \"$1\""; + last; + } else { + last; + } + } + print OUT "\n{\n"; + + while($line = ) { + if($line =~ m/<(\w{1,4})>\W+=\W+(\w+);/) { + if($sym2virt{$1} ne undef) { + $vkcode = $sym2virt{$1}; + print OUT "\t$vkcode"; + + if(length($vkcode) < 8) { + print OUT "\t"; + } + print OUT "\t<$2>\n"; + } else { + # If undef, then this symbolic key code is + # missing from the sym2virt hash table + # print "\t$1\t$2\n"; + } + } elsif($line =~ m/};/) { + print OUT "};\n\n"; + last; + } + } + } + } + + close("IN"); + close("OUT"); +} + diff --git a/libfreerdp-cache/CMakeLists.txt b/libfreerdp-cache/CMakeLists.txt new file mode 100644 index 0000000..17769e3 --- /dev/null +++ b/libfreerdp-cache/CMakeLists.txt @@ -0,0 +1,36 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-cache cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_CACHE_SRCS + brush.c + pointer.c + bitmap.c + offscreen.c + palette.c + glyph.c + cache.c) + +add_library(freerdp-cache ${FREERDP_CACHE_SRCS}) + +set_target_properties(freerdp-cache PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +target_link_libraries(freerdp-cache freerdp-core) +target_link_libraries(freerdp-cache freerdp-utils) + +install(TARGETS freerdp-cache DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-cache/bitmap.c b/libfreerdp-cache/bitmap.c new file mode 100644 index 0000000..652a391 --- /dev/null +++ b/libfreerdp-cache/bitmap.c @@ -0,0 +1,282 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap Cache V2 + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +void update_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +{ + rdpBitmap* bitmap; + rdpCache* cache = context->cache; + + if (memblt->cacheId == 0xFF) + bitmap = offscreen_cache_get(cache->offscreen, memblt->cacheIndex); + else + bitmap = bitmap_cache_get(cache->bitmap, (uint8) memblt->cacheId, memblt->cacheIndex); + + memblt->bitmap = bitmap; + IFCALL(cache->bitmap->MemBlt, context, memblt); +} + +void update_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) +{ + rdpBitmap* bitmap; + rdpCache* cache = context->cache; + + if (mem3blt->cacheId == 0xFF) + bitmap = offscreen_cache_get(cache->offscreen, mem3blt->cacheIndex); + else + bitmap = bitmap_cache_get(cache->bitmap, (uint8) mem3blt->cacheId, mem3blt->cacheIndex); + + mem3blt->bitmap = bitmap; + IFCALL(cache->bitmap->Mem3Blt, context, mem3blt); +} + +void update_gdi_cache_bitmap(rdpContext* context, CACHE_BITMAP_ORDER* cache_bitmap) +{ + rdpBitmap* bitmap; + rdpBitmap* prevBitmap; + rdpCache* cache = context->cache; + + bitmap = Bitmap_Alloc(context); + + Bitmap_SetDimensions(context, bitmap, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight); + + bitmap->Decompress(context, bitmap, + cache_bitmap->bitmapDataStream, cache_bitmap->bitmapWidth, cache_bitmap->bitmapHeight, + cache_bitmap->bitmapBpp, cache_bitmap->bitmapLength, cache_bitmap->compressed); + + bitmap->New(context, bitmap); + + prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex); + + if (prevBitmap != NULL) + Bitmap_Free(context, prevBitmap); + + bitmap_cache_put(cache->bitmap, cache_bitmap->cacheId, cache_bitmap->cacheIndex, bitmap); +} + +void update_gdi_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) +{ + rdpBitmap* bitmap; + rdpBitmap* prevBitmap; + rdpCache* cache = context->cache; + + bitmap = Bitmap_Alloc(context); + + Bitmap_SetDimensions(context, bitmap, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight); + + if (cache_bitmap_v2->bitmapBpp == 0) + { + /* Workaround for Windows 8 bug where bitmapBpp is not set */ + cache_bitmap_v2->bitmapBpp = context->instance->settings->color_depth; + } + + bitmap->Decompress(context, bitmap, + cache_bitmap_v2->bitmapDataStream, cache_bitmap_v2->bitmapWidth, cache_bitmap_v2->bitmapHeight, + cache_bitmap_v2->bitmapBpp, cache_bitmap_v2->bitmapLength, cache_bitmap_v2->compressed); + + bitmap->New(context, bitmap); + + prevBitmap = bitmap_cache_get(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex); + + if (prevBitmap != NULL) + Bitmap_Free(context, prevBitmap); + + bitmap_cache_put(cache->bitmap, cache_bitmap_v2->cacheId, cache_bitmap_v2->cacheIndex, bitmap); +} + +void update_gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap_update) +{ + int i; + rdpBitmap* bitmap; + BITMAP_DATA* bitmap_data; + boolean reused = true; + rdpCache* cache = context->cache; + + if (cache->bitmap->bitmap == NULL) + { + cache->bitmap->bitmap = Bitmap_Alloc(context); + cache->bitmap->bitmap->ephemeral = true; + reused = false; + } + + bitmap = cache->bitmap->bitmap; + + for (i = 0; i < (int) bitmap_update->number; i++) + { + bitmap_data = &bitmap_update->rectangles[i]; + + bitmap->bpp = bitmap_data->bitsPerPixel; + bitmap->length = bitmap_data->bitmapLength; + bitmap->compressed = bitmap_data->compressed; + + Bitmap_SetRectangle(context, bitmap, + bitmap_data->destLeft, bitmap_data->destTop, + bitmap_data->destRight, bitmap_data->destBottom); + + Bitmap_SetDimensions(context, bitmap, bitmap_data->width, bitmap_data->height); + + bitmap->Decompress(context, bitmap, + bitmap_data->bitmapDataStream, bitmap_data->width, bitmap_data->height, + bitmap_data->bitsPerPixel, bitmap_data->bitmapLength, bitmap_data->compressed); + + if (reused) + bitmap->Free(context, bitmap); + else + reused = true; + + bitmap->New(context, bitmap); + + bitmap->Paint(context, bitmap); + } +} + +rdpBitmap* bitmap_cache_get(rdpBitmapCache* bitmap_cache, uint32 id, uint32 index) +{ + rdpBitmap* bitmap; + + if (id > bitmap_cache->maxCells) + { + printf("get invalid bitmap cell id: %d\n", id); + return NULL; + } + + if (index == BITMAP_CACHE_WAITING_LIST_INDEX) + index = bitmap_cache->cells[id].number - 1; + + if (index > bitmap_cache->cells[id].number) + { + printf("get invalid bitmap index %d in cell id: %d\n", index, id); + return NULL; + } + + bitmap = bitmap_cache->cells[id].entries[index]; + + return bitmap; +} + +void bitmap_cache_put(rdpBitmapCache* bitmap_cache, uint32 id, uint32 index, rdpBitmap* bitmap) +{ + if (id > bitmap_cache->maxCells) + { + printf("put invalid bitmap cell id: %d\n", id); + return; + } + + if (index == BITMAP_CACHE_WAITING_LIST_INDEX) + index = bitmap_cache->cells[id].number - 1; + + if (index > bitmap_cache->cells[id].number) + { + printf("put invalid bitmap index %d in cell id: %d\n", index, id); + return; + } + + bitmap_cache->cells[id].entries[index] = bitmap; +} + +void bitmap_cache_register_callbacks(rdpUpdate* update) +{ + rdpCache* cache = update->context->cache; + + cache->bitmap->MemBlt = update->primary->MemBlt; + cache->bitmap->Mem3Blt = update->primary->Mem3Blt; + + update->primary->MemBlt = update_gdi_memblt; + update->primary->Mem3Blt = update_gdi_mem3blt; + + update->secondary->CacheBitmap = update_gdi_cache_bitmap; + update->secondary->CacheBitmapV2 = update_gdi_cache_bitmap_v2; + + update->BitmapUpdate = update_gdi_bitmap_update; +} + +rdpBitmapCache* bitmap_cache_new(rdpSettings* settings) +{ + int i; + rdpBitmapCache* bitmap_cache; + + bitmap_cache = (rdpBitmapCache*) xzalloc(sizeof(rdpBitmapCache)); + + if (bitmap_cache != NULL) + { + bitmap_cache->settings = settings; + bitmap_cache->update = ((freerdp*) settings->instance)->update; + bitmap_cache->context = bitmap_cache->update->context; + + bitmap_cache->maxCells = 5; + + settings->bitmap_cache = false; + settings->bitmapCacheV2NumCells = 5; + settings->bitmapCacheV2CellInfo[0].numEntries = 600; + settings->bitmapCacheV2CellInfo[0].persistent = false; + settings->bitmapCacheV2CellInfo[1].numEntries = 600; + settings->bitmapCacheV2CellInfo[1].persistent = false; + settings->bitmapCacheV2CellInfo[2].numEntries = 2048; + settings->bitmapCacheV2CellInfo[2].persistent = false; + settings->bitmapCacheV2CellInfo[3].numEntries = 4096; + settings->bitmapCacheV2CellInfo[3].persistent = false; + settings->bitmapCacheV2CellInfo[4].numEntries = 2048; + settings->bitmapCacheV2CellInfo[4].persistent = false; + + bitmap_cache->cells = (BITMAP_V2_CELL*) xzalloc(sizeof(BITMAP_V2_CELL) * bitmap_cache->maxCells); + + for (i = 0; i < (int) bitmap_cache->maxCells; i++) + { + bitmap_cache->cells[i].number = settings->bitmapCacheV2CellInfo[i].numEntries; + bitmap_cache->cells[i].entries = (rdpBitmap**) xzalloc(sizeof(rdpBitmap*) * bitmap_cache->cells[i].number); + } + } + + return bitmap_cache; +} + +void bitmap_cache_free(rdpBitmapCache* bitmap_cache) +{ + int i, j; + rdpBitmap* bitmap; + + if (bitmap_cache != NULL) + { + for (i = 0; i < (int) bitmap_cache->maxCells; i++) + { + for (j = 0; j < (int) bitmap_cache->cells[i].number; j++) + { + bitmap = bitmap_cache->cells[i].entries[j]; + + if (bitmap != NULL) + { + Bitmap_Free(bitmap_cache->context, bitmap); + } + } + + xfree(bitmap_cache->cells[i].entries); + } + + if (bitmap_cache->bitmap != NULL) + Bitmap_Free(bitmap_cache->context, bitmap_cache->bitmap); + + xfree(bitmap_cache->cells); + xfree(bitmap_cache); + } +} diff --git a/libfreerdp-cache/brush.c b/libfreerdp-cache/brush.c new file mode 100644 index 0000000..2aabfe8 --- /dev/null +++ b/libfreerdp-cache/brush.c @@ -0,0 +1,185 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Brush Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +void update_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + uint8 style; + rdpBrush* brush = &patblt->brush; + rdpCache* cache = context->cache; + + style = brush->style; + + if (brush->style & CACHED_BRUSH) + { + brush->data = brush_cache_get(cache->brush, brush->index, &brush->bpp); + brush->style = 0x03; + } + + IFCALL(cache->brush->PatBlt, context, patblt); + brush->style = style; +} + +void update_gdi_cache_brush(rdpContext* context, CACHE_BRUSH_ORDER* cache_brush) +{ + rdpCache* cache = context->cache; + brush_cache_put(cache->brush, cache_brush->index, cache_brush->data, cache_brush->bpp); +} + +void* brush_cache_get(rdpBrushCache* brush, uint32 index, uint32* bpp) +{ + void* entry; + + if (*bpp == 1) + { + if (index > brush->maxMonoEntries) + { + printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); + return NULL; + } + + *bpp = brush->monoEntries[index].bpp; + entry = brush->monoEntries[index].entry; + } + else + { + if (index > brush->maxEntries) + { + printf("invalid brush (%d bpp) index: 0x%04X\n", *bpp, index); + return NULL; + } + + *bpp = brush->entries[index].bpp; + entry = brush->entries[index].entry; + } + + if (entry == NULL) + { + printf("invalid brush (%d bpp) at index: 0x%04X\n", *bpp, index); + return NULL; + } + + return entry; +} + +void brush_cache_put(rdpBrushCache* brush, uint32 index, void* entry, uint32 bpp) +{ + void* prevEntry; + + if (bpp == 1) + { + if (index > brush->maxMonoEntries) + { + printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + return; + } + + prevEntry = brush->monoEntries[index].entry; + + if (prevEntry != NULL) + xfree(prevEntry); + + brush->monoEntries[index].bpp = bpp; + brush->monoEntries[index].entry = entry; + } + else + { + if (index > brush->maxEntries) + { + printf("invalid brush (%d bpp) index: 0x%04X\n", bpp, index); + return; + } + + prevEntry = brush->entries[index].entry; + + if (prevEntry != NULL) + xfree(prevEntry); + + brush->entries[index].bpp = bpp; + brush->entries[index].entry = entry; + } +} + +void brush_cache_register_callbacks(rdpUpdate* update) +{ + rdpCache* cache = update->context->cache; + + cache->brush->PatBlt = update->primary->PatBlt; + + update->primary->PatBlt = update_gdi_patblt; + update->secondary->CacheBrush = update_gdi_cache_brush; +} + +rdpBrushCache* brush_cache_new(rdpSettings* settings) +{ + rdpBrushCache* brush; + + brush = (rdpBrushCache*) xzalloc(sizeof(rdpBrushCache)); + + if (brush != NULL) + { + brush->settings = settings; + + brush->maxEntries = 64; + brush->maxMonoEntries = 64; + + brush->entries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxEntries); + brush->monoEntries = (BRUSH_ENTRY*) xzalloc(sizeof(BRUSH_ENTRY) * brush->maxMonoEntries); + } + + return brush; +} + +void brush_cache_free(rdpBrushCache* brush) +{ + int i; + + if (brush != NULL) + { + if (brush->entries != NULL) + { + for (i = 0; i < (int) brush->maxEntries; i++) + { + if (brush->entries[i].entry != NULL) + xfree(brush->entries[i].entry); + } + + xfree(brush->entries); + } + + if (brush->monoEntries != NULL) + { + for (i = 0; i < (int) brush->maxMonoEntries; i++) + { + if (brush->monoEntries[i].entry != NULL) + xfree(brush->monoEntries[i].entry); + } + + xfree(brush->monoEntries); + } + + xfree(brush); + } +} diff --git a/libfreerdp-cache/cache.c b/libfreerdp-cache/cache.c new file mode 100644 index 0000000..3756765 --- /dev/null +++ b/libfreerdp-cache/cache.c @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Caches + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +rdpCache* cache_new(rdpSettings* settings) +{ + rdpCache* cache; + + cache = (rdpCache*) xzalloc(sizeof(rdpCache)); + + if (cache != NULL) + { + cache->settings = settings; + cache->glyph = glyph_cache_new(settings); + cache->brush = brush_cache_new(settings); + cache->pointer = pointer_cache_new(settings); + cache->bitmap = bitmap_cache_new(settings); + cache->offscreen = offscreen_cache_new(settings); + cache->palette = palette_cache_new(settings); + } + + return cache; +} + +void cache_free(rdpCache* cache) +{ + if (cache != NULL) + { + glyph_cache_free(cache->glyph); + brush_cache_free(cache->brush); + pointer_cache_free(cache->pointer); + bitmap_cache_free(cache->bitmap); + offscreen_cache_free(cache->offscreen); + palette_cache_free(cache->palette); + xfree(cache); + } +} diff --git a/libfreerdp-cache/glyph.c b/libfreerdp-cache/glyph.c new file mode 100644 index 0000000..fc33266 --- /dev/null +++ b/libfreerdp-cache/glyph.c @@ -0,0 +1,513 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Glyph Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +void update_process_glyph(rdpContext* context, uint8* data, int* index, + int* x, int* y, uint32 cacheId, uint32 ulCharInc, uint32 flAccel) +{ + int offset; + rdpGlyph* glyph; + uint32 cacheIndex; + rdpGraphics* graphics; + rdpGlyphCache* glyph_cache; + + graphics = context->graphics; + glyph_cache = context->cache->glyph; + + cacheIndex = data[*index]; + + glyph = glyph_cache_get(glyph_cache, cacheId, cacheIndex); + + if ((ulCharInc == 0) && (!(flAccel & SO_CHAR_INC_EQUAL_BM_BASE))) + { + (*index)++; + offset = data[*index]; + + if (offset & 0x80) + { + offset = data[*index + 1] | (data[*index + 2] << 8); + (*index)++; + (*index)++; + } + + if (flAccel & SO_VERTICAL) + *y += offset; + else + *x += offset; + } + + if (glyph != NULL) + { + Glyph_Draw(context, glyph, glyph->x + *x, glyph->y + *y); + + if (flAccel & SO_CHAR_INC_EQUAL_BM_BASE) + *x += glyph->cx; + } +} + +void update_process_glyph_fragments(rdpContext* context, uint8* data, uint32 length, + uint32 cacheId, uint32 ulCharInc, uint32 flAccel, uint32 bgcolor, uint32 fgcolor, int x, int y, + int bkX, int bkY, int bkWidth, int bkHeight, int opX, int opY, int opWidth, int opHeight) +{ + int n; + uint32 id; + uint32 size; + int index = 0; + uint8* fragments; + rdpGraphics* graphics; + rdpGlyphCache* glyph_cache; + + graphics = context->graphics; + glyph_cache = context->cache->glyph; + + if (opWidth > 0 && opHeight > 0) + Glyph_BeginDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor); + else + Glyph_BeginDraw(context, 0, 0, 0, 0, bgcolor, fgcolor); + + while (index < (int) length) + { + switch (data[index]) + { + case GLYPH_FRAGMENT_USE: + + if (index + 2 > (int) length) + { + /* at least one byte need to follow */ + index = length = 0; + break; + } + + id = data[index + 1]; + fragments = (uint8*) glyph_cache_fragment_get(glyph_cache, id, &size); + + if (fragments != NULL) + { + if ((ulCharInc == 0) && (!(flAccel & SO_CHAR_INC_EQUAL_BM_BASE))) + { + if (flAccel & SO_VERTICAL) + y += data[index + 2]; + else + x += data[index + 2]; + } + + for (n = 0; n < (int) size; n++) + { + update_process_glyph(context, fragments, &n, &x, &y, cacheId, ulCharInc, flAccel); + } + } + + index += (index + 2 < (int) length) ? 3 : 2; + length -= index; + data = &(data[index]); + index = 0; + + break; + + case GLYPH_FRAGMENT_ADD: + + if (index + 3 > (int) length) + { + /* at least two bytes need to follow */ + index = length = 0; + break; + } + + id = data[index + 1]; + size = data[index + 2]; + + fragments = (uint8*) xmalloc(size); + memcpy(fragments, data, size); + glyph_cache_fragment_put(glyph_cache, id, size, fragments); + + index += 3; + length -= index; + data = &(data[index]); + index = 0; + + break; + + default: + update_process_glyph(context, data, &index, &x, &y, cacheId, ulCharInc, flAccel); + index++; + break; + } + } + + if (opWidth > 0 && opHeight > 0) + Glyph_EndDraw(context, opX, opY, opWidth, opHeight, bgcolor, fgcolor); + else + Glyph_EndDraw(context, bkX, bkY, bkWidth, bkHeight, bgcolor, fgcolor); +} + +void update_gdi_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index) +{ + rdpGlyphCache* glyph_cache; + + glyph_cache = context->cache->glyph; + update_process_glyph_fragments(context, glyph_index->data, glyph_index->cbData, + glyph_index->cacheId, glyph_index->ulCharInc, glyph_index->flAccel, + glyph_index->backColor, glyph_index->foreColor, glyph_index->x, glyph_index->y, + glyph_index->bkLeft, glyph_index->bkTop, + glyph_index->bkRight - glyph_index->bkLeft, glyph_index->bkBottom - glyph_index->bkTop, + glyph_index->opLeft, glyph_index->opTop, + glyph_index->opRight - glyph_index->opLeft, glyph_index->opBottom - glyph_index->opTop); +} + +void update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fast_index) +{ + sint32 opLeft, opTop, opRight, opBottom; + sint32 x, y; + rdpGlyphCache* glyph_cache; + + glyph_cache = context->cache->glyph; + + opLeft = fast_index->opLeft; + opTop = fast_index->opTop; + opRight = fast_index->opRight; + opBottom = fast_index->opBottom; + x = fast_index->x; + y = fast_index->y; + + if (opBottom == -32768) + { + uint8 flags = (uint8) (opTop & 0x0F); + + if (flags & 0x01) + opBottom = fast_index->bkBottom; + if (flags & 0x02) + opRight = fast_index->bkRight; + if (flags & 0x04) + opTop = fast_index->bkTop; + if (flags & 0x08) + opLeft = fast_index->bkLeft; + } + + if (opLeft == 0) + opLeft = fast_index->bkLeft; + + if (opRight == 0) + opRight = fast_index->bkRight; + + if (x == -32768) + x = fast_index->bkLeft; + + if (y == -32768) + y = fast_index->bkTop; + + update_process_glyph_fragments(context, fast_index->data, fast_index->cbData, + fast_index->cacheId, fast_index->ulCharInc, fast_index->flAccel, + fast_index->backColor, fast_index->foreColor, x, y, + fast_index->bkLeft, fast_index->bkTop, + fast_index->bkRight - fast_index->bkLeft, fast_index->bkBottom - fast_index->bkTop, + opLeft, opTop, + opRight - opLeft, opBottom - opTop); +} + +void update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fast_glyph) +{ + sint32 opLeft, opTop, opRight, opBottom; + sint32 x, y; + GLYPH_DATA_V2* glyph_data; + rdpGlyph* glyph; + rdpCache* cache = context->cache; + uint8 text_data[2]; + + opLeft = fast_glyph->opLeft; + opTop = fast_glyph->opTop; + opRight = fast_glyph->opRight; + opBottom = fast_glyph->opBottom; + x = fast_glyph->x; + y = fast_glyph->y; + + if (opBottom == -32768) + { + uint8 flags = (uint8) (opTop & 0x0F); + + if (flags & 0x01) + opBottom = fast_glyph->bkBottom; + if (flags & 0x02) + opRight = fast_glyph->bkRight; + if (flags & 0x04) + opTop = fast_glyph->bkTop; + if (flags & 0x08) + opLeft = fast_glyph->bkLeft; + } + + if (opLeft == 0) + opLeft = fast_glyph->bkLeft; + + if (opRight == 0) + opRight = fast_glyph->bkRight; + + if (x == -32768) + x = fast_glyph->bkLeft; + + if (y == -32768) + y = fast_glyph->bkTop; + + if (fast_glyph->glyph_data != NULL) + { + /* got option font that needs to go into cache */ + glyph_data = (GLYPH_DATA_V2*) (fast_glyph->glyph_data); + glyph = Glyph_Alloc(context); + glyph->x = glyph_data->x; + glyph->y = glyph_data->y; + glyph->cx = glyph_data->cx; + glyph->cy = glyph_data->cy; + glyph->aj = glyph_data->aj; + glyph->cb = glyph_data->cb; + Glyph_New(context, glyph); + glyph_cache_put(cache->glyph, fast_glyph->cacheId, fast_glyph->data[0], glyph); + xfree(fast_glyph->glyph_data); + fast_glyph->glyph_data = NULL; + } + + text_data[0] = fast_glyph->data[0]; + text_data[1] = 0; + + update_process_glyph_fragments(context, text_data, 1, + fast_glyph->cacheId, fast_glyph->ulCharInc, fast_glyph->flAccel, + fast_glyph->backColor, fast_glyph->foreColor, x, y, + fast_glyph->bkLeft, fast_glyph->bkTop, + fast_glyph->bkRight - fast_glyph->bkLeft, fast_glyph->bkBottom - fast_glyph->bkTop, + opLeft, opTop, + opRight - opLeft, opBottom - opTop); +} + +void update_gdi_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph) +{ + int i; + rdpGlyph* glyph; + GLYPH_DATA* glyph_data; + rdpCache* cache = context->cache; + + for (i = 0; i < (int) cache_glyph->cGlyphs; i++) + { + glyph_data = cache_glyph->glyphData[i]; + + glyph = Glyph_Alloc(context); + + glyph->x = glyph_data->x; + glyph->y = glyph_data->y; + glyph->cx = glyph_data->cx; + glyph->cy = glyph_data->cy; + glyph->aj = glyph_data->aj; + glyph->cb = glyph_data->cb; + Glyph_New(context, glyph); + + glyph_cache_put(cache->glyph, cache_glyph->cacheId, glyph_data->cacheIndex, glyph); + + cache_glyph->glyphData[i] = NULL; + xfree(glyph_data); + } +} + +void update_gdi_cache_glyph_v2(rdpContext* context, CACHE_GLYPH_V2_ORDER* cache_glyph_v2) +{ + int i; + rdpGlyph* glyph; + GLYPH_DATA_V2* glyph_data; + rdpCache* cache = context->cache; + + for (i = 0; i < (int) cache_glyph_v2->cGlyphs; i++) + { + glyph_data = cache_glyph_v2->glyphData[i]; + + glyph = Glyph_Alloc(context); + + glyph->x = glyph_data->x; + glyph->y = glyph_data->y; + glyph->cx = glyph_data->cx; + glyph->cy = glyph_data->cy; + glyph->aj = glyph_data->aj; + glyph->cb = glyph_data->cb; + Glyph_New(context, glyph); + + glyph_cache_put(cache->glyph, cache_glyph_v2->cacheId, glyph_data->cacheIndex, glyph); + + cache_glyph_v2->glyphData[i] = NULL; + xfree(glyph_data); + } +} + +rdpGlyph* glyph_cache_get(rdpGlyphCache* glyph_cache, uint32 id, uint32 index) +{ + rdpGlyph* glyph; + + if (id > 9) + { + printf("invalid glyph cache id: %d\n", id); + return NULL; + } + + if (index > glyph_cache->glyphCache[id].number) + { + printf("invalid glyph cache index: %d in cache id: %d\n", index, id); + return NULL; + } + + glyph = glyph_cache->glyphCache[id].entries[index]; + + if (glyph == NULL) + { + printf("invalid glyph at cache index: %d in cache id: %d\n", index, id); + } + + return glyph; +} + +void glyph_cache_put(rdpGlyphCache* glyph_cache, uint32 id, uint32 index, rdpGlyph* glyph) +{ + rdpGlyph* prevGlyph; + + if (id > 9) + { + printf("invalid glyph cache id: %d\n", id); + return; + } + + if (index > glyph_cache->glyphCache[id].number) + { + printf("invalid glyph cache index: %d in cache id: %d\n", index, id); + return; + } + + prevGlyph = glyph_cache->glyphCache[id].entries[index]; + + if (prevGlyph != NULL) + { + Glyph_Free(glyph_cache->context, prevGlyph); + xfree(prevGlyph->aj); + xfree(prevGlyph); + } + + glyph_cache->glyphCache[id].entries[index] = glyph; +} + +void* glyph_cache_fragment_get(rdpGlyphCache* glyph_cache, uint32 index, uint32* size) +{ + void* fragment; + + fragment = glyph_cache->fragCache.entries[index].fragment; + *size = (uint8) glyph_cache->fragCache.entries[index].size; + + if (fragment == NULL) + { + printf("invalid glyph fragment at index:%d\n", index); + } + + return fragment; +} + +void glyph_cache_fragment_put(rdpGlyphCache* glyph_cache, uint32 index, uint32 size, void* fragment) +{ + void* prevFragment; + + prevFragment = glyph_cache->fragCache.entries[index].fragment; + + glyph_cache->fragCache.entries[index].fragment = fragment; + glyph_cache->fragCache.entries[index].size = size; + + if (prevFragment != NULL) + { + xfree(prevFragment); + } +} + +void glyph_cache_register_callbacks(rdpUpdate* update) +{ + update->primary->GlyphIndex = update_gdi_glyph_index; + update->primary->FastIndex = update_gdi_fast_index; + update->primary->FastGlyph = update_gdi_fast_glyph; + update->secondary->CacheGlyph = update_gdi_cache_glyph; + update->secondary->CacheGlyphV2 = update_gdi_cache_glyph_v2; +} + +rdpGlyphCache* glyph_cache_new(rdpSettings* settings) +{ + rdpGlyphCache* glyph; + + glyph = (rdpGlyphCache*) xzalloc(sizeof(rdpGlyphCache)); + + if (glyph != NULL) + { + int i; + + glyph->settings = settings; + glyph->context = ((freerdp*) settings->instance)->update->context; + + if (settings->glyph_cache) + settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; + + for (i = 0; i < 10; i++) + { + glyph->glyphCache[i].number = settings->glyphCache[i].cacheEntries; + glyph->glyphCache[i].maxCellSize = settings->glyphCache[i].cacheMaximumCellSize; + glyph->glyphCache[i].entries = (rdpGlyph**) xzalloc(sizeof(rdpGlyph*) * glyph->glyphCache[i].number); + } + + glyph->fragCache.entries = xzalloc(sizeof(FRAGMENT_CACHE_ENTRY) * 256); + } + + return glyph; +} + +void glyph_cache_free(rdpGlyphCache* glyph_cache) +{ + if (glyph_cache != NULL) + { + int i; + void* fragment; + + for (i = 0; i < 10; i++) + { + int j; + + for (j = 0; j < (int) glyph_cache->glyphCache[i].number; j++) + { + rdpGlyph* glyph; + + glyph = glyph_cache->glyphCache[i].entries[j]; + + if (glyph != NULL) + { + Glyph_Free(glyph_cache->context, glyph); + xfree(glyph->aj); + xfree(glyph); + } + } + xfree(glyph_cache->glyphCache[i].entries); + } + + for (i = 0; i < 255; i++) + { + fragment = glyph_cache->fragCache.entries[i].fragment; + xfree(fragment); + } + + xfree(glyph_cache->fragCache.entries); + xfree(glyph_cache); + } +} diff --git a/libfreerdp-cache/offscreen.c b/libfreerdp-cache/offscreen.c new file mode 100644 index 0000000..c4eb018 --- /dev/null +++ b/libfreerdp-cache/offscreen.c @@ -0,0 +1,169 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Offscreen Bitmap Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void update_gdi_create_offscreen_bitmap(rdpContext* context, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + int i; + uint16 index; + rdpBitmap* bitmap; + rdpCache* cache = context->cache; + + bitmap = Bitmap_Alloc(context); + + bitmap->width = create_offscreen_bitmap->cx; + bitmap->height = create_offscreen_bitmap->cy; + + bitmap->New(context, bitmap); + + offscreen_cache_delete(cache->offscreen, create_offscreen_bitmap->id); + offscreen_cache_put(cache->offscreen, create_offscreen_bitmap->id, bitmap); + + if(cache->offscreen->currentSurface == create_offscreen_bitmap->id) + Bitmap_SetSurface(context, bitmap, false); + + for (i = 0; i < (int) create_offscreen_bitmap->deleteList.cIndices; i++) + { + index = create_offscreen_bitmap->deleteList.indices[i]; + offscreen_cache_delete(cache->offscreen, index); + } +} + +void update_gdi_switch_surface(rdpContext* context, SWITCH_SURFACE_ORDER* switch_surface) +{ + rdpCache* cache = context->cache; + + if (switch_surface->bitmapId == SCREEN_BITMAP_SURFACE) + { + Bitmap_SetSurface(context, NULL, true); + } + else + { + rdpBitmap* bitmap; + bitmap = offscreen_cache_get(cache->offscreen, switch_surface->bitmapId); + Bitmap_SetSurface(context, bitmap, false); + } + + cache->offscreen->currentSurface = switch_surface->bitmapId; +} + +rdpBitmap* offscreen_cache_get(rdpOffscreenCache* offscreen_cache, uint32 index) +{ + rdpBitmap* bitmap; + + if (index > offscreen_cache->maxEntries) + { + printf("invalid offscreen bitmap index: 0x%04X\n", index); + return NULL; + } + + bitmap = offscreen_cache->entries[index]; + + if (bitmap == NULL) + { + printf("invalid offscreen bitmap at index: 0x%04X\n", index); + return NULL; + } + + return bitmap; +} + +void offscreen_cache_put(rdpOffscreenCache* offscreen, uint32 index, rdpBitmap* bitmap) +{ + if (index > offscreen->maxEntries) + { + printf("invalid offscreen bitmap index: 0x%04X\n", index); + return; + } + + offscreen_cache_delete(offscreen, index); + offscreen->entries[index] = bitmap; +} + +void offscreen_cache_delete(rdpOffscreenCache* offscreen, uint32 index) +{ + rdpBitmap* prevBitmap; + + if (index > offscreen->maxEntries) + { + printf("invalid offscreen bitmap index (delete): 0x%04X\n", index); + return; + } + + prevBitmap = offscreen->entries[index]; + + if (prevBitmap != NULL) + Bitmap_Free(offscreen->update->context, prevBitmap); + + offscreen->entries[index] = NULL; +} + +void offscreen_cache_register_callbacks(rdpUpdate* update) +{ + update->altsec->CreateOffscreenBitmap = update_gdi_create_offscreen_bitmap; + update->altsec->SwitchSurface = update_gdi_switch_surface; +} + +rdpOffscreenCache* offscreen_cache_new(rdpSettings* settings) +{ + rdpOffscreenCache* offscreen_cache; + + offscreen_cache = (rdpOffscreenCache*) xzalloc(sizeof(rdpOffscreenCache)); + + if (offscreen_cache != NULL) + { + offscreen_cache->settings = settings; + offscreen_cache->update = ((freerdp*) settings->instance)->update; + + offscreen_cache->currentSurface = SCREEN_BITMAP_SURFACE; + offscreen_cache->maxSize = 7680; + offscreen_cache->maxEntries = 100; + + settings->offscreen_bitmap_cache_size = offscreen_cache->maxSize; + settings->offscreen_bitmap_cache_entries = offscreen_cache->maxEntries; + + offscreen_cache->entries = (rdpBitmap**) xzalloc(sizeof(rdpBitmap*) * offscreen_cache->maxEntries); + } + + return offscreen_cache; +} + +void offscreen_cache_free(rdpOffscreenCache* offscreen_cache) +{ + int i; + rdpBitmap* bitmap; + + if (offscreen_cache != NULL) + { + for (i = 0; i < (int) offscreen_cache->maxEntries; i++) + { + bitmap = offscreen_cache->entries[i]; + + if (bitmap != NULL) + Bitmap_Free(offscreen_cache->update->context, bitmap); + } + + xfree(offscreen_cache->entries); + xfree(offscreen_cache); + } +} diff --git a/libfreerdp-cache/palette.c b/libfreerdp-cache/palette.c new file mode 100644 index 0000000..8998f78 --- /dev/null +++ b/libfreerdp-cache/palette.c @@ -0,0 +1,92 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Palette (Color Table) Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void update_gdi_cache_color_table(rdpContext* context, CACHE_COLOR_TABLE_ORDER* cache_color_table) +{ + rdpCache* cache = context->cache; + palette_cache_put(cache->palette, cache_color_table->cacheIndex, (void*) cache_color_table->colorTable); +} + +void* palette_cache_get(rdpPaletteCache* palette_cache, uint32 index) +{ + void* entry; + + if (index > palette_cache->maxEntries) + { + printf("invalid color table index: 0x%04X\n", index); + return NULL; + } + + entry = palette_cache->entries[index].entry; + + if (entry == NULL) + { + printf("invalid color table at index: 0x%04X\n", index); + return NULL; + } + + return entry; +} + +void palette_cache_put(rdpPaletteCache* palette_cache, uint32 index, void* entry) +{ + if (index > palette_cache->maxEntries) + { + printf("invalid color table index: 0x%04X\n", index); + return; + } + + palette_cache->entries[index].entry = entry; +} + +void palette_cache_register_callbacks(rdpUpdate* update) +{ + update->secondary->CacheColorTable = update_gdi_cache_color_table; +} + +rdpPaletteCache* palette_cache_new(rdpSettings* settings) +{ + rdpPaletteCache* palette_cache; + + palette_cache = (rdpPaletteCache*) xzalloc(sizeof(rdpPaletteCache)); + + if (palette_cache != NULL) + { + palette_cache->settings = settings; + palette_cache->maxEntries = 6; + palette_cache->entries = (PALETTE_TABLE_ENTRY*) xzalloc(sizeof(PALETTE_TABLE_ENTRY) * palette_cache->maxEntries); + } + + return palette_cache; +} + +void palette_cache_free(rdpPaletteCache* palette_cache) +{ + if (palette_cache != NULL) + { + xfree(palette_cache->entries); + xfree(palette_cache); + } +} + diff --git a/libfreerdp-cache/pointer.c b/libfreerdp-cache/pointer.c new file mode 100644 index 0000000..86d2f30 --- /dev/null +++ b/libfreerdp-cache/pointer.c @@ -0,0 +1,155 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Glyph Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void update_pointer_position(rdpContext* context, POINTER_POSITION_UPDATE* pointer_position) +{ + +} + +void update_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) +{ + +} + +void update_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color) +{ + +} + +void update_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new) +{ + rdpPointer* pointer; + rdpCache* cache = context->cache; + + pointer = Pointer_Alloc(context); + + if (pointer != NULL) + { + pointer->xorBpp = pointer_new->xorBpp; + pointer->xPos = pointer_new->colorPtrAttr.xPos; + pointer->yPos = pointer_new->colorPtrAttr.yPos; + pointer->width = pointer_new->colorPtrAttr.width; + pointer->height = pointer_new->colorPtrAttr.height; + pointer->lengthAndMask = pointer_new->colorPtrAttr.lengthAndMask; + pointer->lengthXorMask = pointer_new->colorPtrAttr.lengthXorMask; + pointer->xorMaskData = pointer_new->colorPtrAttr.xorMaskData; + pointer->andMaskData = pointer_new->colorPtrAttr.andMaskData; + + pointer->New(context, pointer); + pointer_cache_put(cache->pointer, pointer_new->colorPtrAttr.cacheIndex, pointer); + Pointer_Set(context, pointer); + } +} + +void update_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached) +{ + rdpPointer* pointer; + rdpCache* cache = context->cache; + + pointer = pointer_cache_get(cache->pointer, pointer_cached->cacheIndex); + + if (pointer != NULL) + Pointer_Set(context, pointer); +} + +rdpPointer* pointer_cache_get(rdpPointerCache* pointer_cache, uint32 index) +{ + rdpPointer* pointer; + + if (index >= pointer_cache->cacheSize) + { + printf("invalid pointer index:%d\n", index); + return NULL; + } + + pointer = pointer_cache->entries[index]; + + return pointer; +} + +void pointer_cache_put(rdpPointerCache* pointer_cache, uint32 index, rdpPointer* pointer) +{ + rdpPointer* prevPointer; + + if (index >= pointer_cache->cacheSize) + { + printf("invalid pointer index:%d\n", index); + return; + } + + prevPointer = pointer_cache->entries[index]; + + if (prevPointer != NULL) + Pointer_Free(pointer_cache->update->context, prevPointer); + + pointer_cache->entries[index] = pointer; +} + +void pointer_cache_register_callbacks(rdpUpdate* update) +{ + rdpPointerUpdate* pointer = update->pointer; + + pointer->PointerPosition = update_pointer_position; + pointer->PointerSystem = update_pointer_system; + pointer->PointerColor = update_pointer_color; + pointer->PointerNew = update_pointer_new; + pointer->PointerCached = update_pointer_cached; +} + +rdpPointerCache* pointer_cache_new(rdpSettings* settings) +{ + rdpPointerCache* pointer_cache; + + pointer_cache = (rdpPointerCache*) xzalloc(sizeof(rdpPointerCache)); + + if (pointer_cache != NULL) + { + pointer_cache->settings = settings; + pointer_cache->cacheSize = settings->pointer_cache_size; + pointer_cache->update = ((freerdp*) settings->instance)->update; + pointer_cache->entries = (rdpPointer**) xzalloc(sizeof(rdpPointer*) * pointer_cache->cacheSize); + } + + return pointer_cache; +} + +void pointer_cache_free(rdpPointerCache* pointer_cache) +{ + if (pointer_cache != NULL) + { + int i; + rdpPointer* pointer; + + for (i = 0; i < (int) pointer_cache->cacheSize; i++) + { + pointer = pointer_cache->entries[i]; + + if (pointer != NULL) + Pointer_Free(pointer_cache->update->context, pointer); + } + + xfree(pointer_cache->entries); + xfree(pointer_cache); + } +} diff --git a/libfreerdp-channels/CMakeLists.txt b/libfreerdp-channels/CMakeLists.txt new file mode 100644 index 0000000..55a139a --- /dev/null +++ b/libfreerdp-channels/CMakeLists.txt @@ -0,0 +1,32 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-chanman cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_CHANNELS_SRCS + libchannels.c + libchannels.h + wtsvc.c + wtsvc.h) + +add_library(freerdp-channels ${FREERDP_CHANNELS_SRCS}) + +set_target_properties(freerdp-channels PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") +target_link_libraries(freerdp-channels freerdp-utils) + +install(TARGETS freerdp-channels DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/libfreerdp-channels/libchannels.c b/libfreerdp-channels/libchannels.c new file mode 100644 index 0000000..cb0a06b --- /dev/null +++ b/libfreerdp-channels/libchannels.c @@ -0,0 +1,988 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Virtual Channel Manager + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * MS compatible plugin interface + * reference: + * http://msdn.microsoft.com/en-us/library/aa383580.aspx + * + * Notes on threads: + * Many virtual channel plugins are built using threads. + * Non main threads may call MyVirtualChannelOpen, + * MyVirtualChannelClose, or MyVirtualChannelWrite. + * Since the plugin's VirtualChannelEntry function is called + * from the main thread, MyVirtualChannelInit has to be called + * from the main thread. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libchannels.h" + +#define CHANNEL_MAX_COUNT 30 + +struct lib_data +{ + PVIRTUALCHANNELENTRY entry; /* the one and only exported function */ + PCHANNEL_INIT_EVENT_FN init_event_proc; + void* init_handle; +}; + +struct channel_data +{ + char name[CHANNEL_NAME_LEN + 1]; + int open_handle; + int options; + int flags; /* 0 nothing 1 init 2 open */ + PCHANNEL_OPEN_EVENT_FN open_event_proc; +}; + +struct sync_data +{ + void* data; + uint32 data_length; + void* user_data; + int index; +}; + +typedef struct rdp_init_handle rdpInitHandle; +struct rdp_init_handle +{ + rdpChannels* channels; +}; + +struct rdp_channels +{ + /** + * Only the main thread alters these arrays, before any + * library thread is allowed in(post_connect is called) + * so no need to use mutex locking + * After post_connect, each library thread can only access it's + * own array items + * ie, no two threads can access index 0, ... + */ + + struct lib_data libs_data[CHANNEL_MAX_COUNT]; + int num_libs_data; + + struct channel_data channels_data[CHANNEL_MAX_COUNT]; + int num_channels_data; + + rdpInitHandle init_handles[CHANNEL_MAX_COUNT]; + int num_init_handles; + + /* control for entry into MyVirtualChannelInit */ + int can_call_init; + rdpSettings* settings; + + /* true once freerdp_chanman_post_connect is called */ + int is_connected; + + /* used for locating the channels for a given instance */ + freerdp* instance; + + /* signal for incoming data or event */ + struct wait_obj* signal; + + /* used for sync write */ + freerdp_mutex sync_data_mutex; + LIST* sync_data_list; + + /* used for sync event */ + freerdp_sem event_sem; + RDP_EVENT* event; +}; + +/** + * The current channel manager reference passes from VirtualChannelEntry to + * VirtualChannelInit for the pInitHandle. + */ +static rdpChannels* g_init_channels; + +/* The list of all channel managers. */ +typedef struct rdp_channels_list rdpChannelsList; +struct rdp_channels_list +{ + rdpChannels* channels; + rdpChannelsList* next; +}; + +static rdpChannelsList* g_channels_list; + +/* To generate unique sequence for all open handles */ +static int g_open_handle_sequence; + +/* For locking the global resources */ +static freerdp_mutex g_mutex_init; +static freerdp_mutex g_mutex_list; + +/* returns the channels for the open handle passed in */ +static rdpChannels* freerdp_channels_find_by_open_handle(int open_handle, int* pindex) +{ + int lindex; + rdpChannels* channels; + rdpChannelsList* channels_list; + + freerdp_mutex_lock(g_mutex_list); + + for (channels_list = g_channels_list; channels_list; channels_list = channels_list->next) + { + channels = channels_list->channels; + + for (lindex = 0; lindex < channels->num_channels_data; lindex++) + { + if (channels->channels_data[lindex].open_handle == open_handle) + { + freerdp_mutex_unlock(g_mutex_list); + *pindex = lindex; + return channels; + } + } + } + + freerdp_mutex_unlock(g_mutex_list); + + return NULL; +} + +/* returns the channels for the rdp instance passed in */ +static rdpChannels* freerdp_channels_find_by_instance(freerdp* instance) +{ + rdpChannels* channels; + rdpChannelsList* channels_list; + + freerdp_mutex_lock(g_mutex_list); + + for (channels_list = g_channels_list; channels_list; channels_list = channels_list->next) + { + channels = channels_list->channels; + if (channels->instance == instance) + { + freerdp_mutex_unlock(g_mutex_list); + return channels; + } + } + + freerdp_mutex_unlock(g_mutex_list); + + return NULL; +} + +/* returns struct channel_data for the channel name passed in */ +static struct channel_data* freerdp_channels_find_channel_data_by_name(rdpChannels* channels, const char* channel_name, int* pindex) +{ + int lindex; + struct channel_data* lchannel_data; + + for (lindex = 0; lindex < channels->num_channels_data; lindex++) + { + lchannel_data = channels->channels_data + lindex; + + if (strcmp(channel_name, lchannel_data->name) == 0) + { + if (pindex != 0) + *pindex = lindex; + + return lchannel_data; + } + } + + return NULL; +} + +/* returns rdpChannel for the channel id passed in */ +static rdpChannel* freerdp_channels_find_channel_by_id(rdpChannels* channels, rdpSettings* settings, int channel_id, int* pindex) +{ + int lindex; + int lcount; + rdpChannel* lrdp_channel; + + lcount = settings->num_channels; + + for (lindex = 0; lindex < lcount; lindex++) + { + lrdp_channel = settings->channels + lindex; + + if (lrdp_channel->channel_id == channel_id) + { + if (pindex != 0) + *pindex = lindex; + + return lrdp_channel; + } + } + + return NULL; +} + +/* returns rdpChannel for the channel name passed in */ +static rdpChannel* freerdp_channels_find_channel_by_name(rdpChannels* channels, + rdpSettings* settings, const char* channel_name, int* pindex) +{ + int lindex; + int lcount; + rdpChannel* lrdp_channel; + + lcount = settings->num_channels; + + for (lindex = 0; lindex < lcount; lindex++) + { + lrdp_channel = settings->channels + lindex; + + if (strcmp(channel_name, lrdp_channel->name) == 0) + { + if (pindex != 0) + *pindex = lindex; + + return lrdp_channel; + } + } + + return NULL; +} + +/** + * must be called by same thread that calls freerdp_chanman_load_plugin + * according to MS docs + * only called from main thread + */ +static uint32 FREERDP_CC MyVirtualChannelInit(void** ppInitHandle, PCHANNEL_DEF pChannel, + int channelCount, uint32 versionRequested, PCHANNEL_INIT_EVENT_FN pChannelInitEventProc) +{ + int index; + rdpChannels* channels; + struct lib_data* llib; + rdpChannel* lrdp_channel; + PCHANNEL_DEF lchannel_def; + struct channel_data* lchannel_data; + + channels = g_init_channels; + channels->init_handles[channels->num_init_handles].channels = channels; + *ppInitHandle = &channels->init_handles[channels->num_init_handles]; + channels->num_init_handles++; + + DEBUG_CHANNELS("enter"); + + if (!channels->can_call_init) + { + DEBUG_CHANNELS("error not in entry"); + return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; + } + + if (ppInitHandle == 0) + { + DEBUG_CHANNELS("error bad pphan"); + return CHANNEL_RC_BAD_INIT_HANDLE; + } + + if (channels->num_channels_data + channelCount >= CHANNEL_MAX_COUNT) + { + DEBUG_CHANNELS("error too many channels"); + return CHANNEL_RC_TOO_MANY_CHANNELS; + } + + if (pChannel == 0) + { + DEBUG_CHANNELS("error bad pchan"); + return CHANNEL_RC_BAD_CHANNEL; + } + + if (channels->is_connected) + { + DEBUG_CHANNELS("error already connected"); + return CHANNEL_RC_ALREADY_CONNECTED; + } + + if (versionRequested != VIRTUAL_CHANNEL_VERSION_WIN2000) + { + DEBUG_CHANNELS("warning version"); + } + + for (index = 0; index < channelCount; index++) + { + lchannel_def = pChannel + index; + if (freerdp_channels_find_channel_data_by_name(channels, lchannel_def->name, 0) != 0) + { + DEBUG_CHANNELS("error channel already used"); + return CHANNEL_RC_BAD_CHANNEL; + } + } + + llib = channels->libs_data + channels->num_libs_data; + llib->init_event_proc = pChannelInitEventProc; + llib->init_handle = *ppInitHandle; + channels->num_libs_data++; + + for (index = 0; index < channelCount; index++) + { + lchannel_def = pChannel + index; + lchannel_data = channels->channels_data + channels->num_channels_data; + + freerdp_mutex_lock(g_mutex_list); + lchannel_data->open_handle = g_open_handle_sequence++; + freerdp_mutex_unlock(g_mutex_list); + + lchannel_data->flags = 1; /* init */ + strncpy(lchannel_data->name, lchannel_def->name, CHANNEL_NAME_LEN); + lchannel_data->options = lchannel_def->options; + + if (channels->settings->num_channels < 16) + { + lrdp_channel = channels->settings->channels + channels->settings->num_channels; + strncpy(lrdp_channel->name, lchannel_def->name, 7); + lrdp_channel->options = lchannel_def->options; + channels->settings->num_channels++; + } + else + { + DEBUG_CHANNELS("warning more than 16 channels"); + } + + channels->num_channels_data++; + } + + return CHANNEL_RC_OK; +} + +/** + * can be called from any thread + * thread safe because no 2 threads can have the same channel name registered + */ +static uint32 FREERDP_CC MyVirtualChannelOpen(void* pInitHandle, uint32* pOpenHandle, + char* pChannelName, PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc) +{ + int index; + rdpChannels* channels; + struct channel_data* lchannel_data; + + DEBUG_CHANNELS("enter"); + + channels = ((rdpInitHandle*) pInitHandle)->channels; + + if (pOpenHandle == 0) + { + DEBUG_CHANNELS("error bad chanhan"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + if (pChannelOpenEventProc == 0) + { + DEBUG_CHANNELS("error bad proc"); + return CHANNEL_RC_BAD_PROC; + } + + if (!channels->is_connected) + { + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + lchannel_data = freerdp_channels_find_channel_data_by_name(channels, pChannelName, &index); + + if (lchannel_data == 0) + { + DEBUG_CHANNELS("error chan name"); + return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; + } + + if (lchannel_data->flags == 2) + { + DEBUG_CHANNELS("error chan already open"); + return CHANNEL_RC_ALREADY_OPEN; + } + + lchannel_data->flags = 2; /* open */ + lchannel_data->open_event_proc = pChannelOpenEventProc; + *pOpenHandle = lchannel_data->open_handle; + + return CHANNEL_RC_OK; +} + +/** + * can be called from any thread + * thread safe because no 2 threads can have the same openHandle + */ +static uint32 FREERDP_CC MyVirtualChannelClose(uint32 openHandle) +{ + int index; + rdpChannels* channels; + struct channel_data* lchannel_data; + + DEBUG_CHANNELS("enter"); + + channels = freerdp_channels_find_by_open_handle(openHandle, &index); + + if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) + { + DEBUG_CHANNELS("error bad channels"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + lchannel_data = channels->channels_data + index; + + if (lchannel_data->flags != 2) + { + DEBUG_CHANNELS("error not open"); + return CHANNEL_RC_NOT_OPEN; + } + + lchannel_data->flags = 0; + + return CHANNEL_RC_OK; +} + +/* can be called from any thread */ +static uint32 FREERDP_CC MyVirtualChannelWrite(uint32 openHandle, void* pData, uint32 dataLength, void* pUserData) +{ + int index; + rdpChannels* channels; + struct sync_data* item; + struct channel_data* lchannel_data; + + channels = freerdp_channels_find_by_open_handle(openHandle, &index); + + if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) + { + DEBUG_CHANNELS("error bad chanhan"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + if (!channels->is_connected) + { + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + if (pData == 0) + { + DEBUG_CHANNELS("error bad pData"); + return CHANNEL_RC_NULL_DATA; + } + + if (dataLength == 0) + { + DEBUG_CHANNELS("error bad dataLength"); + return CHANNEL_RC_ZERO_LENGTH; + } + + lchannel_data = channels->channels_data + index; + + if (lchannel_data->flags != 2) + { + DEBUG_CHANNELS("error not open"); + return CHANNEL_RC_NOT_OPEN; + } + + freerdp_mutex_lock(channels->sync_data_mutex); /* lock channels->sync* vars */ + + if (!channels->is_connected) + { + freerdp_mutex_unlock(channels->sync_data_mutex); + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + item = xnew(struct sync_data); + item->data = pData; + item->data_length = dataLength; + item->user_data = pUserData; + item->index = index; + list_enqueue(channels->sync_data_list, item); + freerdp_mutex_unlock(channels->sync_data_mutex); + + /* set the event */ + wait_obj_set(channels->signal); + + return CHANNEL_RC_OK; +} + +static uint32 FREERDP_CC MyVirtualChannelEventPush(uint32 openHandle, RDP_EVENT* event) +{ + int index; + rdpChannels* channels; + struct channel_data* lchannel_data; + + channels = freerdp_channels_find_by_open_handle(openHandle, &index); + + if ((channels == NULL) || (index < 0) || (index >= CHANNEL_MAX_COUNT)) + { + DEBUG_CHANNELS("error bad chanhan"); + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + } + + if (!channels->is_connected) + { + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + if (event == NULL) + { + DEBUG_CHANNELS("error bad event"); + return CHANNEL_RC_NULL_DATA; + } + + lchannel_data = channels->channels_data + index; + + if (lchannel_data->flags != 2) + { + DEBUG_CHANNELS("error not open"); + return CHANNEL_RC_NOT_OPEN; + } + + freerdp_sem_wait(channels->event_sem); /* lock channels->event */ + + if (!channels->is_connected) + { + freerdp_sem_signal(channels->event_sem); + DEBUG_CHANNELS("error not connected"); + return CHANNEL_RC_NOT_CONNECTED; + } + + channels->event = event; + /* set the event */ + wait_obj_set(channels->signal); + + return CHANNEL_RC_OK; +} + +/** + * this is called shortly after the application starts and + * before any other function in the file + * called only from main thread + */ +int freerdp_channels_global_init(void) +{ + g_init_channels = NULL; + g_channels_list = NULL; + g_open_handle_sequence = 1; + g_mutex_init = freerdp_mutex_new(); + g_mutex_list = freerdp_mutex_new(); + + return 0; +} + +int freerdp_channels_global_uninit(void) +{ + while (g_channels_list) + freerdp_channels_free(g_channels_list->channels); + + freerdp_mutex_free(g_mutex_init); + freerdp_mutex_free(g_mutex_list); + + return 0; +} + +rdpChannels* freerdp_channels_new(void) +{ + rdpChannels* channels; + rdpChannelsList* channels_list; + + channels = xnew(rdpChannels); + + channels->sync_data_mutex = freerdp_mutex_new(); + channels->sync_data_list = list_new(); + + channels->event_sem = freerdp_sem_new(1); + channels->signal = wait_obj_new(); + + /* Add it to the global list */ + channels_list = xnew(rdpChannelsList); + channels_list->channels = channels; + + freerdp_mutex_lock(g_mutex_list); + channels_list->next = g_channels_list; + g_channels_list = channels_list; + freerdp_mutex_unlock(g_mutex_list); + + return channels; +} + +void freerdp_channels_free(rdpChannels* channels) +{ + rdpChannelsList* list; + rdpChannelsList* prev; + + freerdp_mutex_free(channels->sync_data_mutex); + list_free(channels->sync_data_list); + + freerdp_sem_free(channels->event_sem); + wait_obj_free(channels->signal); + + /* Remove from global list */ + + freerdp_mutex_lock(g_mutex_list); + + for (prev = NULL, list = g_channels_list; list; prev = list, list = list->next) + { + if (list->channels == channels) + break; + } + + if (list) + { + if (prev) + prev->next = list->next; + else + g_channels_list = list->next; + xfree(list); + } + + freerdp_mutex_unlock(g_mutex_list); + + xfree(channels); +} + +/** + * this is called when processing the command line parameters + * called only from main thread + */ +int freerdp_channels_load_plugin(rdpChannels* channels, rdpSettings* settings, const char* name, void* data) +{ + int ok; + struct lib_data* lib; + CHANNEL_ENTRY_POINTS_EX ep; + + DEBUG_CHANNELS("%s", name); + + if (channels->num_libs_data + 1 >= CHANNEL_MAX_COUNT) + { + DEBUG_CHANNELS("too many channels"); + return 1; + } + + lib = channels->libs_data + channels->num_libs_data; + lib->entry = (PVIRTUALCHANNELENTRY) freerdp_load_plugin(name, CHANNEL_EXPORT_FUNC_NAME); + //lib->entry = (PVIRTUALCHANNELENTRY) freerdp_load_channel_plugin(settings, name, CHANNEL_EXPORT_FUNC_NAME); + + if (lib->entry == NULL) + { + DEBUG_CHANNELS("failed to find export function"); + return 1; + } + + ep.cbSize = sizeof(ep); + ep.protocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000; + ep.pVirtualChannelInit = MyVirtualChannelInit; + ep.pVirtualChannelOpen = MyVirtualChannelOpen; + ep.pVirtualChannelClose = MyVirtualChannelClose; + ep.pVirtualChannelWrite = MyVirtualChannelWrite; + ep.pExtendedData = data; + ep.pVirtualChannelEventPush = MyVirtualChannelEventPush; + + /* enable MyVirtualChannelInit */ + channels->can_call_init = 1; + channels->settings = settings; + + freerdp_mutex_lock(g_mutex_init); + + g_init_channels = channels; + ok = lib->entry((PCHANNEL_ENTRY_POINTS) &ep); + g_init_channels = NULL; + + freerdp_mutex_unlock(g_mutex_init); + + /* disable MyVirtualChannelInit */ + channels->settings = 0; + channels->can_call_init = 0; + + if (!ok) + { + DEBUG_CHANNELS("export function call failed"); + return 1; + } + + return 0; +} + +/** + * go through and inform all the libraries that we are initialized + * called only from main thread + */ +int freerdp_channels_pre_connect(rdpChannels* channels, freerdp* instance) +{ + int index; + void* dummy; + struct lib_data* llib; + CHANNEL_DEF lchannel_def; + + DEBUG_CHANNELS("enter"); + channels->instance = instance; + + /** + * If rdpsnd is registered but not rdpdr, it's necessary to register a fake + * rdpdr channel to make sound work. This is a workaround for Window 7 and + * Windows 2008 + */ + if (freerdp_channels_find_channel_data_by_name(channels, "rdpsnd", 0) != 0 && + freerdp_channels_find_channel_data_by_name(channels, "rdpdr", 0) == 0) + { + lchannel_def.options = CHANNEL_OPTION_INITIALIZED | + CHANNEL_OPTION_ENCRYPT_RDP; + strcpy(lchannel_def.name, "rdpdr"); + channels->can_call_init = 1; + channels->settings = instance->settings; + freerdp_mutex_lock(g_mutex_init); + g_init_channels = channels; + MyVirtualChannelInit(&dummy, &lchannel_def, 1, + VIRTUAL_CHANNEL_VERSION_WIN2000, 0); + g_init_channels = NULL; + freerdp_mutex_unlock(g_mutex_init); + channels->can_call_init = 0; + channels->settings = 0; + DEBUG_CHANNELS("registered fake rdpdr for rdpsnd."); + } + + for (index = 0; index < channels->num_libs_data; index++) + { + llib = channels->libs_data + index; + + if (llib->init_event_proc != 0) + llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_INITIALIZED, 0, 0); + } + + return 0; +} + +/** + * go through and inform all the libraries that we are connected + * this will tell the libraries that its ok to call MyVirtualChannelOpen + * called only from main thread + */ +int freerdp_channels_post_connect(rdpChannels* channels, freerdp* instance) +{ + int index; + char* hostname; + int hostname_len; + struct lib_data* llib; + + channels->is_connected = 1; + hostname = instance->settings->hostname; + hostname_len = strlen(hostname); + + DEBUG_CHANNELS("hostname [%s] channels->num_libs [%d]", hostname, channels->num_libs_data); + + for (index = 0; index < channels->num_libs_data; index++) + { + llib = channels->libs_data + index; + + if (llib->init_event_proc != 0) + llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_CONNECTED, hostname, hostname_len); + } + + return 0; +} + +/** + * data comming from the server to the client + * called only from main thread + */ +int freerdp_channels_data(freerdp* instance, int channel_id, void* data, int data_size, int flags, int total_size) +{ + int index; + rdpChannels* channels; + rdpChannel* lrdp_channel; + struct channel_data* lchannel_data; + + channels = freerdp_channels_find_by_instance(instance); + + if (channels == 0) + { + DEBUG_CHANNELS("could not find channel manager"); + return 1; + } + + lrdp_channel = freerdp_channels_find_channel_by_id(channels, instance->settings, + channel_id, &index); + if (lrdp_channel == 0) + { + DEBUG_CHANNELS("could not find channel id"); + return 1; + } + + lchannel_data = freerdp_channels_find_channel_data_by_name(channels, lrdp_channel->name, &index); + + if (lchannel_data == 0) + { + DEBUG_CHANNELS("could not find channel name"); + return 1; + } + + if (lchannel_data->open_event_proc != 0) + { + lchannel_data->open_event_proc(lchannel_data->open_handle, + CHANNEL_EVENT_DATA_RECEIVED, data, data_size, total_size, flags); + } + + return 0; +} + +static const char* event_class_to_name_table[] = +{ + "rdpdbg", /* RDP_EVENT_CLASS_DEBUG */ + "cliprdr", /* RDP_EVENT_CLASS_CLIPRDR */ + "tsmf", /* RDP_EVENT_CLASS_TSMF */ + "rail", /* RDP_EVENT_CLASS_RAIL */ + NULL +}; + +/** + * Send a plugin-defined event to the plugin. + * called only from main thread + * @param channels the channel manager instance + * @param event an event object created by freerdp_event_new() + */ +FREERDP_API int freerdp_channels_send_event(rdpChannels* channels, RDP_EVENT* event) +{ + int index; + const char* name; + struct channel_data* lchannel_data; + + name = event_class_to_name_table[event->event_class]; + + if (name == NULL) + { + DEBUG_CHANNELS("unknown event_class %d", event->event_class); + freerdp_event_free(event); + return 1; + } + + lchannel_data = freerdp_channels_find_channel_data_by_name(channels, name, &index); + + if (lchannel_data == NULL) + { + DEBUG_CHANNELS("could not find channel name %s", name); + freerdp_event_free(event); + return 1; + } + + if (lchannel_data->open_event_proc != NULL) + { + lchannel_data->open_event_proc(lchannel_data->open_handle, + CHANNEL_EVENT_USER, + event, sizeof(RDP_EVENT), sizeof(RDP_EVENT), 0); + } + + return 0; +} + +/** + * called only from main thread + */ +static void freerdp_channels_process_sync(rdpChannels* channels, freerdp* instance) +{ + struct sync_data* item; + rdpChannel* lrdp_channel; + struct channel_data* lchannel_data; + + while (channels->sync_data_list->head != NULL) + { + freerdp_mutex_lock(channels->sync_data_mutex); + item = (struct sync_data*)list_dequeue(channels->sync_data_list); + freerdp_mutex_unlock(channels->sync_data_mutex); + + lchannel_data = channels->channels_data + item->index; + lrdp_channel = freerdp_channels_find_channel_by_name(channels, instance->settings, + lchannel_data->name, &item->index); + + if (lrdp_channel != NULL) + instance->SendChannelData(instance, lrdp_channel->channel_id, item->data, item->data_length); + + if (lchannel_data->open_event_proc != 0) + { + lchannel_data->open_event_proc(lchannel_data->open_handle, + CHANNEL_EVENT_WRITE_COMPLETE, + item->user_data, sizeof(void *), sizeof(void *), 0); + } + xfree(item); + } +} + +/** + * called only from main thread + */ +boolean freerdp_channels_get_fds(rdpChannels* channels, freerdp* instance, void** read_fds, + int* read_count, void** write_fds, int* write_count) +{ + wait_obj_get_fds(channels->signal, read_fds, read_count); + return true; +} + +/** + * called only from main thread + */ +boolean freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance) +{ + if (wait_obj_is_set(channels->signal)) + { + wait_obj_clear(channels->signal); + freerdp_channels_process_sync(channels, instance); + } + + return true; +} + +RDP_EVENT* freerdp_channels_pop_event(rdpChannels* channels) +{ + RDP_EVENT* event; + + if (channels->event == NULL) + return NULL; + + event = channels->event; + channels->event = NULL; + + freerdp_sem_signal(channels->event_sem); /* release channels->event */ + + return event; +} + +void freerdp_channels_close(rdpChannels* channels, freerdp* instance) +{ + int index; + struct lib_data* llib; + + DEBUG_CHANNELS("closing"); + channels->is_connected = 0; + freerdp_channels_check_fds(channels, instance); + + /* tell all libraries we are shutting down */ + for (index = 0; index < channels->num_libs_data; index++) + { + llib = channels->libs_data + index; + + if (llib->init_event_proc != 0) + llib->init_event_proc(llib->init_handle, CHANNEL_EVENT_TERMINATED, 0, 0); + } +} diff --git a/libfreerdp-channels/libchannels.h b/libfreerdp-channels/libchannels.h new file mode 100644 index 0000000..27058e3 --- /dev/null +++ b/libfreerdp-channels/libchannels.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Virtual Channel Manager + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBCHANNELS_H +#define __LIBCHANNELS_H + +#include + +#ifdef WITH_DEBUG_CHANNELS +#define DEBUG_CHANNELS(fmt, ...) DEBUG_CLASS(CHANNELS, fmt, ## __VA_ARGS__) +#else +#define DEBUG_CHANNELS(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __LIBCHANNELS_H */ diff --git a/libfreerdp-channels/wtsvc.c b/libfreerdp-channels/wtsvc.c new file mode 100644 index 0000000..03a91b4 --- /dev/null +++ b/libfreerdp-channels/wtsvc.c @@ -0,0 +1,372 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Server Virtual Channel Interface + * + * Copyright 2011-2012 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#include "wtsvc.h" + +typedef struct wts_data_item +{ + uint16 channel_id; + uint8* buffer; + uint32 length; +} wts_data_item; + +static void wts_data_item_free(wts_data_item* item) +{ + xfree(item->buffer); + xfree(item); +} + +static void WTSProcessChannelData(rdpPeerChannel* channel, int channelId, uint8* data, int size, int flags, int total_size) +{ + wts_data_item* item; + + if (flags & CHANNEL_FLAG_FIRST) + { + stream_set_pos(channel->receive_data, 0); + } + + stream_check_size(channel->receive_data, size); + stream_write(channel->receive_data, data, size); + + if (flags & CHANNEL_FLAG_LAST) + { + if (stream_get_length(channel->receive_data) != total_size) + { + printf("WTSProcessChannelData: read error\n"); + } + if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_DVC) + { + /* TODO: Receive DVC channel data */ + } + else + { + item = xnew(wts_data_item); + item->length = stream_get_length(channel->receive_data); + item->buffer = xmalloc(item->length); + memcpy(item->buffer, stream_get_head(channel->receive_data), item->length); + + freerdp_mutex_lock(channel->mutex); + list_enqueue(channel->receive_queue, item); + freerdp_mutex_unlock(channel->mutex); + + wait_obj_set(channel->receive_event); + } + stream_set_pos(channel->receive_data, 0); + } +} + +static int WTSReceiveChannelData(freerdp_peer* client, int channelId, uint8* data, int size, int flags, int total_size) +{ + int i; + boolean result = false; + rdpPeerChannel* channel; + + for (i = 0; i < client->settings->num_channels; i++) + { + if (client->settings->channels[i].channel_id == channelId) + break; + } + if (i < client->settings->num_channels) + { + channel = (rdpPeerChannel*) client->settings->channels[i].handle; + if (channel != NULL) + { + WTSProcessChannelData(channel, channelId, data, size, flags, total_size); + result = true; + } + } + + return result; +} + +WTSVirtualChannelManager* WTSCreateVirtualChannelManager(freerdp_peer* client) +{ + WTSVirtualChannelManager* vcm; + + vcm = xnew(WTSVirtualChannelManager); + if (vcm != NULL) + { + vcm->client = client; + vcm->send_event = wait_obj_new(); + vcm->send_queue = list_new(); + vcm->mutex = freerdp_mutex_new(); + + client->ReceiveChannelData = WTSReceiveChannelData; + } + + return vcm; +} + +void WTSDestroyVirtualChannelManager(WTSVirtualChannelManager* vcm) +{ + wts_data_item* item; + + if (vcm != NULL) + { + if (vcm->drdynvc_channel != NULL) + { + WTSVirtualChannelClose(vcm->drdynvc_channel); + vcm->drdynvc_channel = NULL; + } + + wait_obj_free(vcm->send_event); + while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL) + { + wts_data_item_free(item); + } + list_free(vcm->send_queue); + freerdp_mutex_free(vcm->mutex); + xfree(vcm); + } +} + +void WTSVirtualChannelManagerGetFileDescriptor(WTSVirtualChannelManager* vcm, + void** fds, int* fds_count) +{ + wait_obj_get_fds(vcm->send_event, fds, fds_count); +} + +boolean WTSVirtualChannelManagerCheckFileDescriptor(WTSVirtualChannelManager* vcm) +{ + boolean result = true; + wts_data_item* item; + + wait_obj_clear(vcm->send_event); + + freerdp_mutex_lock(vcm->mutex); + while ((item = (wts_data_item*) list_dequeue(vcm->send_queue)) != NULL) + { + if (vcm->client->SendChannelData(vcm->client, item->channel_id, item->buffer, item->length) == false) + { + result = false; + } + wts_data_item_free(item); + if (result == false) + break; + } + freerdp_mutex_unlock(vcm->mutex); + + return result; +} + +void* WTSVirtualChannelOpenEx( + /* __in */ WTSVirtualChannelManager* vcm, + /* __in */ const char* pVirtualName, + /* __in */ uint32 flags) +{ + int i; + int len; + rdpPeerChannel* channel; + const char* channel_name; + freerdp_peer* client = vcm->client; + + channel_name = ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0 ? "drdynvc" : pVirtualName); + + len = strlen(channel_name); + if (len > 8) + return NULL; + + for (i = 0; i < client->settings->num_channels; i++) + { + if (client->settings->channels[i].joined && + strncmp(client->settings->channels[i].name, channel_name, len) == 0) + { + break; + } + } + if (i >= client->settings->num_channels) + return NULL; + + channel = (rdpPeerChannel*) client->settings->channels[i].handle; + if (channel == NULL) + { + channel = xnew(rdpPeerChannel); + channel->vcm = vcm; + channel->client = client; + channel->channel_id = client->settings->channels[i].channel_id; + channel->index = i; + channel->receive_data = stream_new(client->settings->vc_chunk_size); + if ((flags & WTS_CHANNEL_OPTION_DYNAMIC) != 0) + { + channel->channel_type = RDP_PEER_CHANNEL_TYPE_DVC; + vcm->drdynvc_channel = channel; + } + else + { + channel->channel_type = RDP_PEER_CHANNEL_TYPE_SVC; + channel->receive_event = wait_obj_new(); + channel->receive_queue = list_new(); + channel->mutex = freerdp_mutex_new(); + } + + client->settings->channels[i].handle = channel; + } + if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_DVC) + { + /* TODO: do DVC channel initialization here using pVirtualName */ + /* A sub-channel should be created and returned, instead of using the main drdynvc channel */ + /* Set channel->index to num_channels */ + } + + return channel; +} + +boolean WTSVirtualChannelQuery( + /* __in */ void* hChannelHandle, + /* __in */ WTS_VIRTUAL_CLASS WtsVirtualClass, + /* __out */ void** ppBuffer, + /* __out */ uint32* pBytesReturned) +{ + void* fds[10]; + int fds_count = 0; + boolean result = false; + rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + + switch (WtsVirtualClass) + { + case WTSVirtualFileHandle: + wait_obj_get_fds(channel->receive_event, fds, &fds_count); + *ppBuffer = xmalloc(sizeof(void*)); + memcpy(*ppBuffer, &fds[0], sizeof(void*)); + *pBytesReturned = sizeof(void*); + result = true; + break; + + default: + break; + } + return result; +} + +void WTSFreeMemory( + /* __in */ void* pMemory) +{ + xfree(pMemory); +} + +boolean WTSVirtualChannelRead( + /* __in */ void* hChannelHandle, + /* __in */ uint32 TimeOut, + /* __out */ uint8* Buffer, + /* __in */ uint32 BufferSize, + /* __out */ uint32* pBytesRead) +{ + wts_data_item* item; + rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + + item = (wts_data_item*) list_peek(channel->receive_queue); + if (item == NULL) + { + wait_obj_clear(channel->receive_event); + *pBytesRead = 0; + return true; + } + *pBytesRead = item->length; + if (item->length > BufferSize) + return false; + + /* remove the first element (same as what we just peek) */ + freerdp_mutex_lock(channel->mutex); + list_dequeue(channel->receive_queue); + if (channel->receive_queue->head == NULL) + wait_obj_clear(channel->receive_event); + freerdp_mutex_unlock(channel->mutex); + + memcpy(Buffer, item->buffer, item->length); + + return true; +} + +boolean WTSVirtualChannelWrite( + /* __in */ void* hChannelHandle, + /* __in */ uint8* Buffer, + /* __in */ uint32 Length, + /* __out */ uint32* pBytesWritten) +{ + uint32 written = 0; + wts_data_item* item; + boolean result = false; + rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + WTSVirtualChannelManager* vcm = channel->vcm; + + if (channel == NULL) + return false; + + if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC) + { + item = xnew(wts_data_item); + item->channel_id = channel->channel_id; + item->buffer = xmalloc(Length); + item->length = Length; + memcpy(item->buffer, Buffer, Length); + + freerdp_mutex_lock(vcm->mutex); + list_enqueue(vcm->send_queue, item); + freerdp_mutex_unlock(vcm->mutex); + + wait_obj_set(vcm->send_event); + + written = Length; + result = true; + } + else + { + /* TODO: Send to DVC channel */ + } + + if (pBytesWritten != NULL) + *pBytesWritten = written; + return result; +} + +boolean WTSVirtualChannelClose( + /* __in */ void* hChannelHandle) +{ + wts_data_item* item; + rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; + + if (channel != NULL) + { + if (channel->index < channel->client->settings->num_channels) + channel->client->settings->channels[channel->index].handle = NULL; + stream_free(channel->receive_data); + if (channel->receive_event) + wait_obj_free(channel->receive_event); + if (channel->receive_queue) + { + while ((item = (wts_data_item*) list_dequeue(channel->receive_queue)) != NULL) + { + wts_data_item_free(item); + } + list_free(channel->receive_queue); + } + if (channel->mutex) + freerdp_mutex_free(channel->mutex); + xfree(channel); + } + + return true; +} diff --git a/libfreerdp-channels/wtsvc.h b/libfreerdp-channels/wtsvc.h new file mode 100644 index 0000000..11110d4 --- /dev/null +++ b/libfreerdp-channels/wtsvc.h @@ -0,0 +1,61 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Server Virtual Channel Interface + * + * Copyright 2011-2012 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WTSVC_H +#define __WTSVC_H + +#include +#include +#include +#include +#include +#include + +enum +{ + RDP_PEER_CHANNEL_TYPE_SVC = 0, + RDP_PEER_CHANNEL_TYPE_DVC = 1, + RDP_PEER_CHANNEL_TYPE_DVC_SUB = 2 +}; + +typedef struct rdp_peer_channel +{ + WTSVirtualChannelManager* vcm; + freerdp_peer* client; + uint16 channel_id; + uint16 channel_type; + uint16 index; + + STREAM* receive_data; + struct wait_obj* receive_event; + LIST* receive_queue; + freerdp_mutex mutex; +} rdpPeerChannel; + +struct WTSVirtualChannelManager +{ + freerdp_peer* client; + struct wait_obj* send_event; + LIST* send_queue; + freerdp_mutex mutex; + + rdpPeerChannel* drdynvc_channel; +}; + +#endif /* __WTSVC_H */ diff --git a/libfreerdp-codec/CMakeLists.txt b/libfreerdp-codec/CMakeLists.txt new file mode 100644 index 0000000..7562a91 --- /dev/null +++ b/libfreerdp-codec/CMakeLists.txt @@ -0,0 +1,66 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-codec cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_CODEC_SRCS + bitmap.c + color.c + rfx_bitstream.h + rfx_constants.h + rfx_decode.c + rfx_decode.h + rfx_differential.c + rfx_differential.h + rfx_dwt.c + rfx_dwt.h + rfx_encode.c + rfx_encode.h + rfx_pool.c + rfx_pool.h + rfx_quantization.c + rfx_quantization.h + rfx_rlgr.c + rfx_rlgr.h + rfx_types.h + rfx.c + nsc.c +) + +if(WITH_SSE2) + set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} + rfx_sse2.c + rfx_sse2.h +) + set_property(SOURCE rfx_sse2.c PROPERTY COMPILE_FLAGS "-msse2") +endif() + +if(WITH_NEON) + set(FREERDP_CODEC_SRCS ${FREERDP_CODEC_SRCS} + rfx_neon.c + rfx_neon.h +) + set_property(SOURCE rfx_neon.c PROPERTY COMPILE_FLAGS "-mfpu=neon -mfloat-abi=softfp") +endif() + +add_library(freerdp-codec ${FREERDP_CODEC_SRCS}) + +set_target_properties(freerdp-codec PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") +target_link_libraries(freerdp-codec freerdp-utils) + +install(TARGETS freerdp-codec DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/libfreerdp-codec/bitmap.c b/libfreerdp-codec/bitmap.c new file mode 100644 index 0000000..dc21a4f --- /dev/null +++ b/libfreerdp-codec/bitmap.c @@ -0,0 +1,471 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Compressed Bitmap + * + * Copyright 2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +/* + RLE Compressed Bitmap Stream (RLE_BITMAP_STREAM) + http://msdn.microsoft.com/en-us/library/cc240895%28v=prot.10%29.aspx + pseudo-code + http://msdn.microsoft.com/en-us/library/dd240593%28v=prot.10%29.aspx +*/ + +#define REGULAR_BG_RUN 0x00 +#define MEGA_MEGA_BG_RUN 0xF0 +#define REGULAR_FG_RUN 0x01 +#define MEGA_MEGA_FG_RUN 0xF1 +#define LITE_SET_FG_FG_RUN 0x0C +#define MEGA_MEGA_SET_FG_RUN 0xF6 +#define LITE_DITHERED_RUN 0x0E +#define MEGA_MEGA_DITHERED_RUN 0xF8 +#define REGULAR_COLOR_RUN 0x03 +#define MEGA_MEGA_COLOR_RUN 0xF3 +#define REGULAR_FGBG_IMAGE 0x02 +#define MEGA_MEGA_FGBG_IMAGE 0xF2 +#define LITE_SET_FG_FGBG_IMAGE 0x0D +#define MEGA_MEGA_SET_FGBG_IMAGE 0xF7 +#define REGULAR_COLOR_IMAGE 0x04 +#define MEGA_MEGA_COLOR_IMAGE 0xF4 +#define SPECIAL_FGBG_1 0xF9 +#define SPECIAL_FGBG_2 0xFA +#define SPECIAL_WHITE 0xFD +#define SPECIAL_BLACK 0xFE + +#define BLACK_PIXEL 0x000000 +#define WHITE_PIXEL 0xFFFFFF + +typedef uint32 PIXEL; + +static const uint8 g_MaskBit0 = 0x01; /* Least significant bit */ +static const uint8 g_MaskBit1 = 0x02; +static const uint8 g_MaskBit2 = 0x04; +static const uint8 g_MaskBit3 = 0x08; +static const uint8 g_MaskBit4 = 0x10; +static const uint8 g_MaskBit5 = 0x20; +static const uint8 g_MaskBit6 = 0x40; +static const uint8 g_MaskBit7 = 0x80; /* Most significant bit */ + +static const uint8 g_MaskSpecialFgBg1 = 0x03; +static const uint8 g_MaskSpecialFgBg2 = 0x05; + +static const uint8 g_MaskRegularRunLength = 0x1F; +static const uint8 g_MaskLiteRunLength = 0x0F; + +/** + * Reads the supplied order header and extracts the compression + * order code ID. + */ +static uint32 ExtractCodeId(uint8 bOrderHdr) +{ + int code; + + switch (bOrderHdr) + { + case MEGA_MEGA_BG_RUN: + case MEGA_MEGA_FG_RUN: + case MEGA_MEGA_SET_FG_RUN: + case MEGA_MEGA_DITHERED_RUN: + case MEGA_MEGA_COLOR_RUN: + case MEGA_MEGA_FGBG_IMAGE: + case MEGA_MEGA_SET_FGBG_IMAGE: + case MEGA_MEGA_COLOR_IMAGE: + case SPECIAL_FGBG_1: + case SPECIAL_FGBG_2: + case SPECIAL_WHITE: + case SPECIAL_BLACK: + return bOrderHdr; + } + code = bOrderHdr >> 5; + switch (code) + { + case REGULAR_BG_RUN: + case REGULAR_FG_RUN: + case REGULAR_COLOR_RUN: + case REGULAR_FGBG_IMAGE: + case REGULAR_COLOR_IMAGE: + return code; + } + return bOrderHdr >> 4; +} + +/** + * Extract the run length of a compression order. + */ +static uint32 ExtractRunLength(uint32 code, uint8* pbOrderHdr, uint32* advance) +{ + uint32 runLength; + uint32 ladvance; + + ladvance = 1; + runLength = 0; + switch (code) + { + case REGULAR_FGBG_IMAGE: + runLength = (*pbOrderHdr) & g_MaskRegularRunLength; + if (runLength == 0) + { + runLength = (*(pbOrderHdr + 1)) + 1; + ladvance += 1; + } + else + { + runLength = runLength * 8; + } + break; + case LITE_SET_FG_FGBG_IMAGE: + runLength = (*pbOrderHdr) & g_MaskLiteRunLength; + if (runLength == 0) + { + runLength = (*(pbOrderHdr + 1)) + 1; + ladvance += 1; + } + else + { + runLength = runLength * 8; + } + break; + case REGULAR_BG_RUN: + case REGULAR_FG_RUN: + case REGULAR_COLOR_RUN: + case REGULAR_COLOR_IMAGE: + runLength = (*pbOrderHdr) & g_MaskRegularRunLength; + if (runLength == 0) + { + /* An extended (MEGA) run. */ + runLength = (*(pbOrderHdr + 1)) + 32; + ladvance += 1; + } + break; + case LITE_SET_FG_FG_RUN: + case LITE_DITHERED_RUN: + runLength = (*pbOrderHdr) & g_MaskLiteRunLength; + if (runLength == 0) + { + /* An extended (MEGA) run. */ + runLength = (*(pbOrderHdr + 1)) + 16; + ladvance += 1; + } + break; + case MEGA_MEGA_BG_RUN: + case MEGA_MEGA_FG_RUN: + case MEGA_MEGA_SET_FG_RUN: + case MEGA_MEGA_DITHERED_RUN: + case MEGA_MEGA_COLOR_RUN: + case MEGA_MEGA_FGBG_IMAGE: + case MEGA_MEGA_SET_FGBG_IMAGE: + case MEGA_MEGA_COLOR_IMAGE: + runLength = ((uint16) pbOrderHdr[1]) | ((uint16) (pbOrderHdr[2] << 8)); + ladvance += 2; + break; + } + *advance = ladvance; + return runLength; +} + +#define UNROLL_COUNT 4 +#define UNROLL(_exp) do { _exp _exp _exp _exp } while (0) + +#undef DESTWRITEPIXEL +#undef DESTREADPIXEL +#undef SRCREADPIXEL +#undef DESTNEXTPIXEL +#undef SRCNEXTPIXEL +#undef WRITEFGBGIMAGE +#undef WRITEFIRSTLINEFGBGIMAGE +#undef RLEDECOMPRESS +#undef RLEEXTRA +#define DESTWRITEPIXEL(_buf, _pix) (_buf)[0] = (uint8)(_pix) +#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] +#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] +#define DESTNEXTPIXEL(_buf) _buf += 1 +#define SRCNEXTPIXEL(_buf) _buf += 1 +#define WRITEFGBGIMAGE WriteFgBgImage8to8 +#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage8to8 +#define RLEDECOMPRESS RleDecompress8to8 +#define RLEEXTRA +#include "include/bitmap.c" + +#undef DESTWRITEPIXEL +#undef DESTREADPIXEL +#undef SRCREADPIXEL +#undef DESTNEXTPIXEL +#undef SRCNEXTPIXEL +#undef WRITEFGBGIMAGE +#undef WRITEFIRSTLINEFGBGIMAGE +#undef RLEDECOMPRESS +#undef RLEEXTRA +#define DESTWRITEPIXEL(_buf, _pix) ((uint16*)(_buf))[0] = (uint16)(_pix) +#define DESTREADPIXEL(_pix, _buf) _pix = ((uint16*)(_buf))[0] +#define SRCREADPIXEL(_pix, _buf) _pix = ((uint16*)(_buf))[0] +#define DESTNEXTPIXEL(_buf) _buf += 2 +#define SRCNEXTPIXEL(_buf) _buf += 2 +#define WRITEFGBGIMAGE WriteFgBgImage16to16 +#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage16to16 +#define RLEDECOMPRESS RleDecompress16to16 +#define RLEEXTRA +#include "include/bitmap.c" + +#undef DESTWRITEPIXEL +#undef DESTREADPIXEL +#undef SRCREADPIXEL +#undef DESTNEXTPIXEL +#undef SRCNEXTPIXEL +#undef WRITEFGBGIMAGE +#undef WRITEFIRSTLINEFGBGIMAGE +#undef RLEDECOMPRESS +#undef RLEEXTRA +#define DESTWRITEPIXEL(_buf, _pix) do { (_buf)[0] = (uint8)(_pix); \ + (_buf)[1] = (uint8)((_pix) >> 8); (_buf)[2] = (uint8)((_pix) >> 16); } while (0) +#define DESTREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | \ + ((_buf)[2] << 16) +#define SRCREADPIXEL(_pix, _buf) _pix = (_buf)[0] | ((_buf)[1] << 8) | \ + ((_buf)[2] << 16) +#define DESTNEXTPIXEL(_buf) _buf += 3 +#define SRCNEXTPIXEL(_buf) _buf += 3 +#define WRITEFGBGIMAGE WriteFgBgImage24to24 +#define WRITEFIRSTLINEFGBGIMAGE WriteFirstLineFgBgImage24to24 +#define RLEDECOMPRESS RleDecompress24to24 +#define RLEEXTRA +#include "include/bitmap.c" + +#define IN_UINT8_MV(_p) (*((_p)++)) + +/** + * decompress an RLE color plane + * RDP6_BITMAP_STREAM + */ +static int process_rle_plane(uint8* in, int width, int height, uint8* out, int size) +{ + int indexw; + int indexh; + int code; + int collen; + int replen; + int color; + int x; + int revcode; + uint8* last_line; + uint8* this_line; + uint8* org_in; + uint8* org_out; + + org_in = in; + org_out = out; + last_line = 0; + indexh = 0; + while (indexh < height) + { + out = (org_out + width * height * 4) - ((indexh + 1) * width * 4); + color = 0; + this_line = out; + indexw = 0; + if (last_line == 0) + { + while (indexw < width) + { + code = IN_UINT8_MV(in); + replen = code & 0xf; + collen = (code >> 4) & 0xf; + revcode = (replen << 4) | collen; + if ((revcode <= 47) && (revcode >= 16)) + { + replen = revcode; + collen = 0; + } + while (collen > 0) + { + color = IN_UINT8_MV(in); + *out = color; + out += 4; + indexw++; + collen--; + } + while (replen > 0) + { + *out = color; + out += 4; + indexw++; + replen--; + } + } + } + else + { + while (indexw < width) + { + code = IN_UINT8_MV(in); + replen = code & 0xf; + collen = (code >> 4) & 0xf; + revcode = (replen << 4) | collen; + if ((revcode <= 47) && (revcode >= 16)) + { + replen = revcode; + collen = 0; + } + while (collen > 0) + { + x = IN_UINT8_MV(in); + if (x & 1) + { + x = x >> 1; + x = x + 1; + color = -x; + } + else + { + x = x >> 1; + color = x; + } + x = last_line[indexw * 4] + color; + *out = x; + out += 4; + indexw++; + collen--; + } + while (replen > 0) + { + x = last_line[indexw * 4] + color; + *out = x; + out += 4; + indexw++; + replen--; + } + } + } + indexh++; + last_line = this_line; + } + return (int) (in - org_in); +} + +/** + * process a raw color plane + */ +static int process_raw_plane(uint8* srcData, int width, int height, uint8* dstData, int size) +{ + int x, y; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + dstData[(((height - y - 1) * width) + x) * 4] = srcData[((y * width) + x)]; + } + } + + return (width * height); +} + +/** + * 4 byte bitmap decompress + * RDP6_BITMAP_STREAM + */ +static boolean bitmap_decompress4(uint8* srcData, uint8* dstData, int width, int height, int size) +{ + int RLE; + int code; + int NoAlpha; + int bytes_processed; + int total_processed; + + code = IN_UINT8_MV(srcData); + RLE = code & 0x10; + + total_processed = 1; + NoAlpha = code & 0x20; + + if (NoAlpha == 0) + { + bytes_processed = process_rle_plane(srcData, width, height, dstData + 3, size - total_processed); + total_processed += bytes_processed; + srcData += bytes_processed; + } + + if (RLE != 0) + { + bytes_processed = process_rle_plane(srcData, width, height, dstData + 2, size - total_processed); + total_processed += bytes_processed; + srcData += bytes_processed; + + bytes_processed = process_rle_plane(srcData, width, height, dstData + 1, size - total_processed); + total_processed += bytes_processed; + srcData += bytes_processed; + + bytes_processed = process_rle_plane(srcData, width, height, dstData + 0, size - total_processed); + total_processed += bytes_processed; + } + else + { + bytes_processed = process_raw_plane(srcData, width, height, dstData + 2, size - total_processed); + total_processed += bytes_processed; + srcData += bytes_processed; + + bytes_processed = process_raw_plane(srcData, width, height, dstData + 1, size - total_processed); + total_processed += bytes_processed; + srcData += bytes_processed; + + bytes_processed = process_raw_plane(srcData, width, height, dstData + 0, size - total_processed); + total_processed += bytes_processed + 1; + } + + return (size == total_processed) ? true : false; +} + + +/** + * bitmap decompression routine + */ +boolean bitmap_decompress(uint8* srcData, uint8* dstData, int width, int height, int size, int srcBpp, int dstBpp) +{ + if (srcBpp == 16 && dstBpp == 16) + { + RleDecompress16to16(srcData, size, dstData, width * 2, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 2, height); + } + else if (srcBpp == 32 && dstBpp == 32) + { + if (!bitmap_decompress4(srcData, dstData, width, height, size)) + return false; + } + else if (srcBpp == 15 && dstBpp == 15) + { + RleDecompress16to16(srcData, size, dstData, width * 2, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 2, height); + } + else if (srcBpp == 8 && dstBpp == 8) + { + RleDecompress8to8(srcData, size, dstData, width, width, height); + freerdp_bitmap_flip(dstData, dstData, width, height); + } + else if (srcBpp == 24 && dstBpp == 24) + { + RleDecompress24to24(srcData, size, dstData, width * 3, width, height); + freerdp_bitmap_flip(dstData, dstData, width * 3, height); + } + else + { + return false; + } + + return true; +} diff --git a/libfreerdp-codec/color.c b/libfreerdp-codec/color.c new file mode 100644 index 0000000..97187f8 --- /dev/null +++ b/libfreerdp-codec/color.c @@ -0,0 +1,1061 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Color Conversion Routines + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +int freerdp_get_pixel(uint8 * data, int x, int y, int width, int height, int bpp) +{ + int start; + int shift; + uint16 *src16; + uint32 *src32; + int red, green, blue; + + switch (bpp) + { + case 1: + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; + case 8: + return data[y * width + x]; + case 15: + case 16: + src16 = (uint16*) data; + return src16[y * width + x]; + case 24: + data += y * width * 3; + data += x * 3; + red = data[0]; + green = data[1]; + blue = data[2]; + return RGB24(red, green, blue); + case 32: + src32 = (uint32*) data; + return src32[y * width + x]; + default: + break; + } + + return 0; +} + +void freerdp_set_pixel(uint8* data, int x, int y, int width, int height, int bpp, int pixel) +{ + int start; + int shift; + int *dst32; + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + if (pixel) + data[start] = data[start] | (0x80 >> shift); + else + data[start] = data[start] & ~(0x80 >> shift); + } + else if (bpp == 32) + { + dst32 = (int*) data; + dst32[y * width + x] = pixel; + } +} + +INLINE void freerdp_color_split_rgb(uint32* color, int bpp, uint8* red, uint8* green, uint8* blue, uint8* alpha, HCLRCONV clrconv) +{ + *red = *green = *blue = 0; + *alpha = (clrconv->alpha) ? 0xFF : 0x00; + + switch (bpp) + { + case 32: + if (clrconv->alpha) + { + GetARGB32(*alpha, *red, *green, *blue, *color); + } + else + { + GetRGB32(*red, *green, *blue, *color); + } + break; + + case 24: + GetRGB24(*red, *green, *blue, *color); + break; + + case 16: + GetRGB16(*red, *green, *blue, *color); + break; + + case 15: + GetRGB15(*red, *green, *blue, *color); + break; + + case 8: + *color &= 0xFF; + *red = clrconv->palette->entries[*color].red; + *green = clrconv->palette->entries[*color].green; + *blue = clrconv->palette->entries[*color].blue; + break; + + case 1: + if (*color != 0) + { + *red = 0xFF; + *green = 0xFF; + *blue = 0xFF; + } + break; + + default: + break; + } +} + +INLINE void freerdp_color_split_bgr(uint32* color, int bpp, uint8* red, uint8* green, uint8* blue, uint8* alpha, HCLRCONV clrconv) +{ + *red = *green = *blue = 0; + *alpha = (clrconv->alpha) ? 0xFF : 0x00; + + switch (bpp) + { + case 32: + if (clrconv->alpha) + { + GetABGR32(*alpha, *red, *green, *blue, *color); + } + else + { + GetBGR32(*red, *green, *blue, *color); + } + break; + + case 24: + GetBGR24(*red, *green, *blue, *color); + break; + + case 16: + GetBGR16(*red, *green, *blue, *color); + break; + + case 15: + GetBGR15(*red, *green, *blue, *color); + break; + + case 8: + *color &= 0xFF; + *red = clrconv->palette->entries[*color].red; + *green = clrconv->palette->entries[*color].green; + *blue = clrconv->palette->entries[*color].blue; + break; + + case 1: + if (*color != 0) + { + *red = 0xFF; + *green = 0xFF; + *blue = 0xFF; + } + break; + + default: + break; + } +} + +INLINE void freerdp_color_make_rgb(uint32* color, int bpp, uint8* red, uint8* green, uint8* blue, uint8* alpha, HCLRCONV clrconv) +{ + switch (bpp) + { + case 32: + *color = ARGB32(*alpha, *red, *green, *blue); + break; + + case 24: + *color = RGB24(*red, *green, *blue); + break; + + case 16: + if (clrconv->rgb555) + { + *color = RGB15(*red, *green, *blue); + } + else + { + *color = RGB16(*red, *green, *blue); + } + break; + + case 15: + *color = RGB15(*red, *green, *blue); + break; + + case 8: + *color = RGB24(*red, *green, *blue); + break; + + case 1: + if ((*red != 0) || (*green != 0) || (*blue != 0)) + *color = 1; + break; + + default: + break; + } +} + +INLINE void freerdp_color_make_bgr(uint32* color, int bpp, uint8* red, uint8* green, uint8* blue, uint8* alpha, HCLRCONV clrconv) +{ + switch (bpp) + { + case 32: + *color = ABGR32(*alpha, *red, *green, *blue); + break; + + case 24: + *color = BGR24(*red, *green, *blue); + break; + + case 16: + if (clrconv->rgb555) + { + *color = BGR15(*red, *green, *blue); + } + else + { + *color = BGR16(*red, *green, *blue); + } + break; + + case 15: + *color = BGR15(*red, *green, *blue); + break; + + case 8: + *color = BGR24(*red, *green, *blue); + break; + + case 1: + if ((*red != 0) || (*green != 0) || (*blue != 0)) + *color = 1; + break; + + default: + break; + } +} + +uint32 freerdp_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + uint8 red = 0; + uint8 green = 0; + uint8 blue = 0; + uint8 alpha = 0xFF; + uint32 dstColor = 0; + + freerdp_color_split_rgb(&srcColor, srcBpp, &red, &green, &blue, &alpha, clrconv); + freerdp_color_make_rgb(&dstColor, dstBpp, &red, &green, &blue, &alpha, clrconv); + + return dstColor; +} + +uint32 freerdp_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + uint8 red = 0; + uint8 green = 0; + uint8 blue = 0; + uint8 alpha = 0xFF; + uint32 dstColor = 0; + + freerdp_color_split_bgr(&srcColor, srcBpp, &red, &green, &blue, &alpha, clrconv); + freerdp_color_make_bgr(&dstColor, dstBpp, &red, &green, &blue, &alpha, clrconv); + + return dstColor; +} + +uint32 freerdp_color_convert_rgb_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + uint8 red = 0; + uint8 green = 0; + uint8 blue = 0; + uint8 alpha = 0xFF; + uint32 dstColor = 0; + + freerdp_color_split_rgb(&srcColor, srcBpp, &red, &green, &blue, &alpha, clrconv); + freerdp_color_make_bgr(&dstColor, dstBpp, &red, &green, &blue, &alpha, clrconv); + + return dstColor; +} + +uint32 freerdp_color_convert_bgr_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + uint8 red = 0; + uint8 green = 0; + uint8 blue = 0; + uint8 alpha = 0xFF; + uint32 dstColor = 0; + + freerdp_color_split_bgr(&srcColor, srcBpp, &red, &green, &blue, &alpha, clrconv); + freerdp_color_make_rgb(&dstColor, dstBpp, &red, &green, &blue, &alpha, clrconv); + + return dstColor; +} + +uint32 freerdp_color_convert_var(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + if (clrconv->invert) + return freerdp_color_convert_var_bgr(srcColor, srcBpp, dstBpp, clrconv); + else + return freerdp_color_convert_var_rgb(srcColor, srcBpp, dstBpp, clrconv); +} + +uint32 freerdp_color_convert_var_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + if (srcBpp > 16) + return freerdp_color_convert_bgr_rgb(srcColor, srcBpp, 32, clrconv); + else + return freerdp_color_convert_rgb(srcColor, srcBpp, 32, clrconv); +} + +uint32 freerdp_color_convert_var_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + if (srcBpp > 16) + return freerdp_color_convert_bgr(srcColor, srcBpp, 32, clrconv); + else + return freerdp_color_convert_rgb_bgr(srcColor, srcBpp, 32, clrconv); +} + +uint8* freerdp_image_convert_8bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + int i; + uint8 red; + uint8 green; + uint8 blue; + uint32 pixel; + uint8 *src8; + uint16 *dst16; + uint32 *dst32; + + if (dstBpp == 8) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height); + + memcpy(dstData, srcData, width * height); + return dstData; + } + else if (dstBpp == 15 || (dstBpp == 16 && clrconv->rgb555)) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + dst16 = (uint16 *) dstData; + for (i = width * height; i > 0; i--) + { + pixel = *srcData; + srcData++; + red = clrconv->palette->entries[pixel].red; + green = clrconv->palette->entries[pixel].green; + blue = clrconv->palette->entries[pixel].blue; + pixel = (clrconv->invert) ? BGR15(red, green, blue) : RGB15(red, green, blue); + *dst16 = pixel; + dst16++; + } + return dstData; + } + else if (dstBpp == 16) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + dst16 = (uint16 *) dstData; + for (i = width * height; i > 0; i--) + { + pixel = *srcData; + srcData++; + red = clrconv->palette->entries[pixel].red; + green = clrconv->palette->entries[pixel].green; + blue = clrconv->palette->entries[pixel].blue; + pixel = (clrconv->invert) ? BGR16(red, green, blue) : RGB16(red, green, blue); + *dst16 = pixel; + dst16++; + } + return dstData; + } + else if (dstBpp == 32) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + src8 = (uint8*) srcData; + dst32 = (uint32*) dstData; + for (i = width * height; i > 0; i--) + { + pixel = *src8; + src8++; + red = clrconv->palette->entries[pixel].red; + green = clrconv->palette->entries[pixel].green; + blue = clrconv->palette->entries[pixel].blue; + pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + *dst32 = pixel; + dst32++; + } + return dstData; + } + + return srcData; +} + +uint8* freerdp_image_convert_15bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + int i; + uint8 red; + uint8 green; + uint8 blue; + uint32 pixel; + uint16 *src16; + uint16 *dst16; + uint32 *dst32; + + if (dstBpp == 15 || (dstBpp == 16 && clrconv->rgb555)) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + memcpy(dstData, srcData, width * height * 2); + + return dstData; + } + else if (dstBpp == 32) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + src16 = (uint16 *) srcData; + dst32 = (uint32 *) dstData; + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR15(red, green, blue, pixel); + pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + *dst32 = pixel; + dst32++; + } + return dstData; + } + else if (dstBpp == 16) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + src16 = (uint16 *) srcData; + dst16 = (uint16 *) dstData; + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetRGB_555(red, green, blue, pixel); + RGB_555_565(red, green, blue); + pixel = (clrconv->invert) ? BGR565(red, green, blue) : RGB565(red, green, blue); + *dst16 = pixel; + dst16++; + } + return dstData; + } + + return srcData; +} + +uint8* freerdp_image_convert_16bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + if (srcBpp == 15) + return freerdp_image_convert_15bpp(srcData, dstData, width, height, srcBpp, dstBpp, clrconv); + + if (dstBpp == 16) + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + if (clrconv->rgb555) + { + int i; + uint8 red, green, blue; + uint16* src16 = (uint16 *) srcData; + uint16* dst16 = (uint16 *) dstData; + + for (i = width * height; i > 0; i--) + { + GetRGB_565(red, green, blue, (*src16)); + RGB_565_555(red, green, blue); + (*dst16) = (clrconv->invert) ? BGR555(red, green, blue) : RGB555(red, green, blue); + src16++; + dst16++; + } + } + else + { + memcpy(dstData, srcData, width * height * 2); + } + + return dstData; + } + else if (dstBpp == 24) + { + int i; + uint8 *dst8; + uint16 *src16; + uint8 red, green, blue; + + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 3); + + dst8 = (uint8*) dstData; + src16 = (uint16*) srcData; + + for (i = width * height; i > 0; i--) + { + GetBGR16(red, green, blue, *src16); + src16++; + + if (clrconv->invert) + { + *dst8++ = blue; + *dst8++ = green; + *dst8++ = red; + } + else + { + *dst8++ = red; + *dst8++ = green; + *dst8++ = blue; + } + } + return dstData; + } + else if (dstBpp == 32) + { + int i; + uint32 pixel; + uint16* src16; + uint32* dst32; + uint8 red, green, blue; + + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + src16 = (uint16*) srcData; + dst32 = (uint32*) dstData; + + for (i = width * height; i > 0; i--) + { + pixel = *src16; + src16++; + GetBGR16(red, green, blue, pixel); + pixel = (clrconv->invert) ? RGB32(red, green, blue) : BGR32(red, green, blue); + *dst32 = pixel; + dst32++; + } + return dstData; + } + + return srcData; +} + +uint8* freerdp_image_convert_24bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + int i; + + if (dstBpp == 32) + { + uint8 *dstp; + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + dstp = dstData; + for (i = width * height; i > 0; i--) + { + *(dstp++) = *(srcData++); + *(dstp++) = *(srcData++); + *(dstp++) = *(srcData++); + *(dstp++) = 0xFF; + } + return dstData; + } + + return srcData; +} + +uint8* freerdp_image_convert_32bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + if (dstBpp == 16) + { + int index; + uint16 *dst16; + uint32 *src32; + uint8 red, green, blue; + + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 2); + + dst16 = (uint16*) dstData; + src32 = (uint32*) srcData; + + for (index = 0; index < width * height; index++) + { + GetBGR32(blue, green, red, *src32); + *dst16 = (clrconv->invert) ? BGR16(red, green, blue) : RGB16(red, green, blue); + src32++; + dst16++; + } + return dstData; + } + else if (dstBpp == 24) + { + uint8 *dstp; + int index; + uint8 red, green, blue; + + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 3); + + dstp = dstData; + for (index = 0; index < width * height; index++) + { + red = *(srcData++); + green = *(srcData++); + blue = *(srcData++); + + if (clrconv->invert) + { + *dstp++ = blue; + *dstp++ = green; + *dstp++ = red; + } + else + { + *dstp++ = red; + *dstp++ = green; + *dstp++ = blue; + } + + srcData++; + } + return dstData; + } + else if (dstBpp == 32) + { + if (clrconv->alpha) + { + int x, y; + uint8 *dstp; + + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + memcpy(dstData, srcData, width * height * 4); + + dstp = dstData; + for (y = 0; y < height; y++) + { + for (x = 0; x < width * 4; x += 4) + { + dstp += 3; + *dstp = 0xFF; + dstp++; + } + } + } + else + { + if (dstData == NULL) + dstData = (uint8*) malloc(width * height * 4); + + memcpy(dstData, srcData, width * height * 4); + } + + return dstData; + } + + return srcData; +} + +p_freerdp_image_convert freerdp_image_convert_[5] = +{ + NULL, + freerdp_image_convert_8bpp, + freerdp_image_convert_16bpp, + freerdp_image_convert_24bpp, + freerdp_image_convert_32bpp +}; + +uint8* freerdp_image_convert(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv) +{ + p_freerdp_image_convert _p_freerdp_image_convert = freerdp_image_convert_[IBPP(srcBpp)]; + + if (_p_freerdp_image_convert != NULL) + return _p_freerdp_image_convert(srcData, dstData, width, height, srcBpp, dstBpp, clrconv); + else + return 0; +} + +void freerdp_bitmap_flip(uint8 * src, uint8 * dst, int scanLineSz, int height) +{ + int i; + + uint8 * bottomLine = dst + (scanLineSz * (height - 1)); + uint8 * topLine = src; + + /* Special processing if called for flip-in-place. */ + if (src == dst) + { + /* Allocate a scanline buffer. + * (FIXME: xmalloc / xfree below should be replaced by "get/put + * scanline buffer from a pool/Q of fixed buffers" to reuse + * fixed size buffers (of max scanline size (or adaptative?) ) + * -- would be much faster). + */ + uint8 * tmpBfr = xmalloc(scanLineSz); + int half = height / 2; + /* Flip buffer in place by line permutations through the temp + * scan line buffer. + * Not that if height has an odd number of line, we don't need + * to move the center scanline anyway. + * Also note that in place flipping takes three memcpy() calls + * to process two scanlines while src to distinct dest would + * only requires two memcpy() calls for two scanlines. + */ + height--; + for (i = 0; i < half ; i++) + { + memcpy(tmpBfr, topLine, scanLineSz); + memcpy(topLine, bottomLine, scanLineSz); + memcpy(bottomLine, tmpBfr, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + height--; + } + xfree(tmpBfr); + } + /* Flip from source buffer to destination buffer. */ + else + { + + for (i = 0; i < height; i++) + { + memcpy(bottomLine, topLine, scanLineSz); + topLine += scanLineSz; + bottomLine -= scanLineSz; + } + } + +} + +uint8* freerdp_image_flip(uint8* srcData, uint8* dstData, int width, int height, int bpp) +{ + int scanline; + + scanline = width * (bpp / 8); + + if (dstData == NULL) + dstData = (uint8*) xmalloc(width * height * (bpp / 8)); + + freerdp_bitmap_flip(srcData, dstData, scanline, height); + return dstData; +} + +uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv) +{ + int x, y; + int pixel; + uint8* data; + uint8 bmask; + uint32 pmask; + uint32* icon; + + pixel = 0; + data = freerdp_image_flip(srcData, dstData, width, height, bpp); + dstData = freerdp_image_convert(data, NULL, width, height, bpp, 32, clrconv); + + free(data); + bmask = mask[pixel]; + icon = (uint32*) dstData; + + if (bpp < 32) + { + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + if (pixel % 8 == 0) + bmask = mask[pixel / 8]; + else + bmask <<= 1; + + pmask = (bmask & 0x80) ? 0x00000000 : 0xFF000000; + + *icon++ |= pmask; + + pixel++; + } + } + } + + free(mask); + + return dstData; +} + +uint8* freerdp_glyph_convert(int width, int height, uint8* data) +{ + int x, y; + uint8 *srcp; + uint8 *dstp; + uint8 *dstData; + int scanline; + + /* + * converts a 1-bit-per-pixel glyph to a one-byte-per-pixel glyph: + * this approach uses a little more memory, but provides faster + * means of accessing individual pixels in blitting operations + */ + + scanline = (width + 7) / 8; + dstData = (uint8*) malloc(width * height); + memset(dstData, 0, width * height); + dstp = dstData; + + for (y = 0; y < height; y++) + { + srcp = data + (y * scanline); + + for (x = 0; x < width; x++) + { + if ((*srcp & (0x80 >> (x % 8))) != 0) + *dstp = 0xFF; + dstp++; + + if (((x + 1) % 8 == 0) && x != 0) + srcp++; + } + } + + return dstData; +} + +uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv) +{ + int index; + uint16* dst16; + uint32* dst32; + uint8* dstData; + uint8 bitMask; + int bitIndex; + uint8 redBg, greenBg, blueBg; + uint8 redFg, greenFg, blueFg; + + switch (srcBpp) + { + case 8: + bgcolor &= 0xFF; + redBg = clrconv->palette->entries[bgcolor].red; + greenBg = clrconv->palette->entries[bgcolor].green; + blueBg = clrconv->palette->entries[bgcolor].blue; + + fgcolor &= 0xFF; + redFg = clrconv->palette->entries[fgcolor].red; + greenFg = clrconv->palette->entries[fgcolor].green; + blueFg = clrconv->palette->entries[fgcolor].blue; + break; + + case 16: + GetRGB16(redBg, greenBg, blueBg, bgcolor); + GetRGB16(redFg, greenFg, blueFg, fgcolor); + break; + + case 15: + GetRGB15(redBg, greenBg, blueBg, bgcolor); + GetRGB15(redFg, greenFg, blueFg, fgcolor); + break; + + default: + GetRGB32(redBg, greenBg, blueBg, bgcolor); + GetRGB32(redFg, greenFg, blueFg, fgcolor); + break; + } + + if (dstBpp == 16) + { + if (clrconv->rgb555) + { + if (srcBpp == 16) + { + /* convert 15-bit colors to 16-bit colors */ + RGB16_RGB15(redBg, greenBg, blueBg, bgcolor); + RGB16_RGB15(redFg, greenFg, blueFg, fgcolor); + } + } + else + { + if (srcBpp == 15) + { + /* convert 15-bit colors to 16-bit colors */ + RGB15_RGB16(redBg, greenBg, blueBg, bgcolor); + RGB15_RGB16(redFg, greenFg, blueFg, fgcolor); + } + } + + dstData = (uint8*) malloc(width * height * 2); + dst16 = (uint16*) dstData; + + for (index = height; index > 0; index--) + { + /* each bit encodes a pixel */ + bitMask = *srcData; + for (bitIndex = 7; bitIndex >= 0; bitIndex--) + { + if ((bitMask >> bitIndex) & 0x01) + { + *dst16 = bgcolor; + } + else + { + *dst16 = fgcolor; + } + dst16++; + } + srcData++; + } + return dstData; + } + else if (dstBpp == 32) + { + dstData = (uint8*) malloc(width * height * 4); + dst32 = (uint32*) dstData; + + for (index = height; index > 0; index--) + { + /* each bit encodes a pixel */ + bitMask = *srcData; + + for (bitIndex = 7; bitIndex >= 0; bitIndex--) + { + if ((bitMask >> bitIndex) & 0x01) + { + *dst32 = (clrconv->invert) ? BGR32(redBg, greenBg, blueBg) : RGB32(redBg, greenBg, blueBg); + } + else + { + *dst32 = (clrconv->invert) ? BGR32(redFg, greenFg, blueFg) : RGB32(redFg, greenFg, blueFg); + } + dst32++; + } + srcData++; + } + return dstData; + } + + return srcData; +} + +void freerdp_alpha_cursor_convert(uint8* alphaData, uint8* xorMask, uint8* andMask, int width, int height, int bpp, HCLRCONV clrconv) +{ + int xpixel; + int apixel; + int i, j, jj; + + for (j = 0; j < height; j++) + { + jj = (bpp == 1) ? j : (height - 1) - j; + for (i = 0; i < width; i++) + { + xpixel = freerdp_get_pixel(xorMask, i, jj, width, height, bpp); + xpixel = freerdp_color_convert_rgb(xpixel, bpp, 32, clrconv); + apixel = freerdp_get_pixel(andMask, i, jj, width, height, 1); + + if (apixel != 0) + { + if ((xpixel & 0xffffff) == 0xffffff) + { + /* use pattern (not solid black) for xor area */ + xpixel = (i & 1) == (j & 1); + xpixel = xpixel ? 0xFFFFFF : 0; + xpixel |= 0xFF000000; + } + else if (xpixel == 0xFF000000) + { + xpixel = 0; + } + } + + freerdp_set_pixel(alphaData, i, j, width, height, 32, xpixel); + } + } +} + +void freerdp_image_swap_color_order(uint8* data, int width, int height) +{ + int x, y; + uint32* pixel; + uint8 a, r, g, b; + + pixel = (uint32*) data; + + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + GetARGB32(a, r, g, b, *pixel); + *pixel = ABGR32(a, r, g, b); + pixel++; + } + } +} + +HCLRCONV freerdp_clrconv_new(uint32 flags) +{ + HCLRCONV clrconv = xnew(CLRCONV); + + clrconv->alpha = (flags & CLRCONV_ALPHA) ? true : false; + clrconv->invert = (flags & CLRCONV_INVERT) ? true : false; + clrconv->rgb555 = (flags & CLRCONV_RGB555) ? true : false; + clrconv->palette = xnew(rdpPalette); + + return clrconv; +} + +void freerdp_clrconv_free(HCLRCONV clrconv) +{ + if (clrconv != NULL) + { + if (clrconv->palette != NULL) + xfree(clrconv->palette); + + xfree(clrconv); + } +} diff --git a/libfreerdp-codec/include/bitmap.c b/libfreerdp-codec/include/bitmap.c new file mode 100644 index 0000000..23f021a --- /dev/null +++ b/libfreerdp-codec/include/bitmap.c @@ -0,0 +1,567 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RLE Compressed Bitmap Stream + * + * Copyright 2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* do not compile the file directly */ + +/** + * Write a foreground/background image to a destination buffer. + */ +static uint8* WRITEFGBGIMAGE(uint8* pbDest, uint32 rowDelta, + uint8 bitmask, PIXEL fgPel, uint32 cBits) +{ + PIXEL xorPixel; + + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit0) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit1) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit2) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit3) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit4) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit5) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit6) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + DESTREADPIXEL(xorPixel, pbDest - rowDelta); + if (bitmask & g_MaskBit7) + { + DESTWRITEPIXEL(pbDest, xorPixel ^ fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, xorPixel); + } + DESTNEXTPIXEL(pbDest); + } + } + } + } + } + } + } + return pbDest; +} + +/** + * Write a foreground/background image to a destination buffer + * for the first line of compressed data. + */ +static uint8* WRITEFIRSTLINEFGBGIMAGE(uint8* pbDest, uint8 bitmask, + PIXEL fgPel, uint32 cBits) +{ + if (bitmask & g_MaskBit0) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit1) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit2) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit3) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit4) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit5) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit6) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + cBits = cBits - 1; + if (cBits > 0) + { + if (bitmask & g_MaskBit7) + { + DESTWRITEPIXEL(pbDest, fgPel); + } + else + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + } + DESTNEXTPIXEL(pbDest); + } + } + } + } + } + } + } + return pbDest; +} + +/** + * Decompress an RLE compressed bitmap. + */ +void RLEDECOMPRESS(uint8* pbSrcBuffer, uint32 cbSrcBuffer, uint8* pbDestBuffer, + uint32 rowDelta, uint32 width, uint32 height) +{ + uint8* pbSrc = pbSrcBuffer; + uint8* pbEnd = pbSrcBuffer + cbSrcBuffer; + uint8* pbDest = pbDestBuffer; + + PIXEL temp; + PIXEL fgPel = WHITE_PIXEL; + boolean fInsertFgPel = false; + boolean fFirstLine = true; + + uint8 bitmask; + PIXEL pixelA, pixelB; + + uint32 runLength; + uint32 code; + + uint32 advance; + + RLEEXTRA + + while (pbSrc < pbEnd) + { + /* Watch out for the end of the first scanline. */ + if (fFirstLine) + { + if ((uint32)(pbDest - pbDestBuffer) >= rowDelta) + { + fFirstLine = false; + fInsertFgPel = false; + } + } + + /* + Extract the compression order code ID from the compression + order header. + */ + code = ExtractCodeId(*pbSrc); + + /* Handle Background Run Orders. */ + if (code == REGULAR_BG_RUN || code == MEGA_MEGA_BG_RUN) + { + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + if (fFirstLine) + { + if (fInsertFgPel) + { + DESTWRITEPIXEL(pbDest, fgPel); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + } + else + { + if (fInsertFgPel) + { + DESTREADPIXEL(temp, pbDest - rowDelta); + DESTWRITEPIXEL(pbDest, temp ^ fgPel); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTREADPIXEL(temp, pbDest - rowDelta); + DESTWRITEPIXEL(pbDest, temp); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTREADPIXEL(temp, pbDest - rowDelta); + DESTWRITEPIXEL(pbDest, temp); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + } + /* A follow-on background run order will need a foreground pel inserted. */ + fInsertFgPel = true; + continue; + } + + /* For any of the other run-types a follow-on background run + order does not need a foreground pel inserted. */ + fInsertFgPel = false; + + switch (code) + { + /* Handle Foreground Run Orders. */ + case REGULAR_FG_RUN: + case MEGA_MEGA_FG_RUN: + case LITE_SET_FG_FG_RUN: + case MEGA_MEGA_SET_FG_RUN: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + if (code == LITE_SET_FG_FG_RUN || code == MEGA_MEGA_SET_FG_RUN) + { + SRCREADPIXEL(fgPel, pbSrc); + SRCNEXTPIXEL(pbSrc); + } + if (fFirstLine) + { + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTWRITEPIXEL(pbDest, fgPel); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTWRITEPIXEL(pbDest, fgPel); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + } + else + { + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTREADPIXEL(temp, pbDest - rowDelta); + DESTWRITEPIXEL(pbDest, temp ^ fgPel); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTREADPIXEL(temp, pbDest - rowDelta); + DESTWRITEPIXEL(pbDest, temp ^ fgPel); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + } + break; + + /* Handle Dithered Run Orders. */ + case LITE_DITHERED_RUN: + case MEGA_MEGA_DITHERED_RUN: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + SRCREADPIXEL(pixelA, pbSrc); + SRCNEXTPIXEL(pbSrc); + SRCREADPIXEL(pixelB, pbSrc); + SRCNEXTPIXEL(pbSrc); + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTWRITEPIXEL(pbDest, pixelA); + DESTNEXTPIXEL(pbDest); + DESTWRITEPIXEL(pbDest, pixelB); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTWRITEPIXEL(pbDest, pixelA); + DESTNEXTPIXEL(pbDest); + DESTWRITEPIXEL(pbDest, pixelB); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + break; + + /* Handle Color Run Orders. */ + case REGULAR_COLOR_RUN: + case MEGA_MEGA_COLOR_RUN: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + SRCREADPIXEL(pixelA, pbSrc); + SRCNEXTPIXEL(pbSrc); + while (runLength >= UNROLL_COUNT) + { + UNROLL( + DESTWRITEPIXEL(pbDest, pixelA); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + DESTWRITEPIXEL(pbDest, pixelA); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + break; + + /* Handle Foreground/Background Image Orders. */ + case REGULAR_FGBG_IMAGE: + case MEGA_MEGA_FGBG_IMAGE: + case LITE_SET_FG_FGBG_IMAGE: + case MEGA_MEGA_SET_FGBG_IMAGE: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + if (code == LITE_SET_FG_FGBG_IMAGE || code == MEGA_MEGA_SET_FGBG_IMAGE) + { + SRCREADPIXEL(fgPel, pbSrc); + SRCNEXTPIXEL(pbSrc); + } + if (fFirstLine) + { + while (runLength > 8) + { + bitmask = *pbSrc; + pbSrc = pbSrc + 1; + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, 8); + runLength = runLength - 8; + } + } + else + { + while (runLength > 8) + { + bitmask = *pbSrc; + pbSrc = pbSrc + 1; + pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, 8); + runLength = runLength - 8; + } + } + if (runLength > 0) + { + bitmask = *pbSrc; + pbSrc = pbSrc + 1; + if (fFirstLine) + { + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, bitmask, fgPel, runLength); + } + else + { + pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, bitmask, fgPel, runLength); + } + } + break; + + /* Handle Color Image Orders. */ + case REGULAR_COLOR_IMAGE: + case MEGA_MEGA_COLOR_IMAGE: + runLength = ExtractRunLength(code, pbSrc, &advance); + pbSrc = pbSrc + advance; + while (runLength >= UNROLL_COUNT) + { + UNROLL( + SRCREADPIXEL(temp, pbSrc); + SRCNEXTPIXEL(pbSrc); + DESTWRITEPIXEL(pbDest, temp); + DESTNEXTPIXEL(pbDest); ); + runLength = runLength - UNROLL_COUNT; + } + while (runLength > 0) + { + SRCREADPIXEL(temp, pbSrc); + SRCNEXTPIXEL(pbSrc); + DESTWRITEPIXEL(pbDest, temp); + DESTNEXTPIXEL(pbDest); + runLength = runLength - 1; + } + break; + + /* Handle Special Order 1. */ + case SPECIAL_FGBG_1: + pbSrc = pbSrc + 1; + if (fFirstLine) + { + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg1, fgPel, 8); + } + else + { + pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg1, fgPel, 8); + } + break; + + /* Handle Special Order 2. */ + case SPECIAL_FGBG_2: + pbSrc = pbSrc + 1; + if (fFirstLine) + { + pbDest = WRITEFIRSTLINEFGBGIMAGE(pbDest, g_MaskSpecialFgBg2, fgPel, 8); + } + else + { + pbDest = WRITEFGBGIMAGE(pbDest, rowDelta, g_MaskSpecialFgBg2, fgPel, 8); + } + break; + + /* Handle White Order. */ + case SPECIAL_WHITE: + pbSrc = pbSrc + 1; + DESTWRITEPIXEL(pbDest, WHITE_PIXEL); + DESTNEXTPIXEL(pbDest); + break; + + /* Handle Black Order. */ + case SPECIAL_BLACK: + pbSrc = pbSrc + 1; + DESTWRITEPIXEL(pbDest, BLACK_PIXEL); + DESTNEXTPIXEL(pbDest); + break; + } + } +} diff --git a/libfreerdp-codec/nsc.c b/libfreerdp-codec/nsc.c new file mode 100644 index 0000000..a39bdd3 --- /dev/null +++ b/libfreerdp-codec/nsc.c @@ -0,0 +1,380 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * NSCodec Codec + * + * Copyright 2011 Samsung, Author Jiten Pathy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +/* we store the 9th bits at the end of stream as bitstream */ +void nsc_cl_expand(STREAM* stream, uint8 shiftcount, uint32 origsz) +{ + uint8* sbitstream; + uint8* temptr; + uint8 sign,bitoff; + uint32 bitno; + sbitstream = stream->data + origsz; + + do + { + sign = (*(stream->p) << (shiftcount - 1)) & 0x80; + bitno = stream->p - stream->data; + *(stream->p++) <<= shiftcount; + temptr = sbitstream + ((bitno) >> 3); + bitoff = bitno % 0x8; + (*temptr) |= (sign >> bitoff); + } + while (((uint32)(stream->p - stream->data)) < origsz); + + stream->p = stream->data; +} + +void nsc_chroma_supersample(NSC_CONTEXT* context) +{ + int i; + uint8* cur; + uint8* tptr; + uint8* nbitstream; + uint8* sbitstream; + uint8 val, bitoff, sign; + uint16 w, h, pw, row; + uint32 alloclen, orglen, bytno; + STREAM* new_s; + STREAM* temp; + + w = context->width; + h = context->height; + alloclen = orglen = w * h; + pw = ROUND_UP_TO(context->width, 8); + temp = stream_new(0); + + for (i = 0; i < 3; i++) + { + if (i != 0) + alloclen = orglen + ((orglen & 0x7) ? (orglen >> 3) + 0x1 : (orglen >> 3)); + + new_s = stream_new(alloclen); + stream_attach(temp, context->org_buf[i]->data, context->org_buf[i]->size); + + sbitstream = temp->data + context->OrgByteCount[i]; + nbitstream = new_s->data + orglen; + cur = new_s->p; + + if (i == 1) + pw >>= 1; + + while (((uint32)(temp->p - temp->data)) < context->OrgByteCount[i]) + { + bytno = temp->p - temp->data; + bitoff = bytno % 0x8; + stream_read_uint8(temp, val); + *cur = val; + row = (temp->p - temp->data) % pw; + + if (i == 0) + { + cur++; + if (row >= w) + stream_seek(temp, pw-row); + } + else + { + tptr = sbitstream + ((bytno) >> 3); + sign = ((*tptr) << bitoff) & 0x80; + bytno = cur - new_s->data; + bitoff = bytno % 8; + *(nbitstream + (bytno >> 3)) |= (sign >> bitoff); + + if ((bytno+w) < orglen) + { + *(cur + w) = val; + bitoff = (bytno + w) % 8; + *(nbitstream + ((bytno + w) >> 3)) |= (sign >> bitoff); + } + + if ((bytno+1) % w) + { + *(cur+1) = val; + bitoff = (bytno + 1) % 8; + *(nbitstream + ((bytno + 1) >> 3)) |= (sign >> bitoff); + if ((bytno+w) < orglen) + { + *(cur+w+1) = val; + bitoff = (bytno + w + 1) % 8; + *(nbitstream + ((bytno + w + 1) >> 3)) |= (sign >> bitoff); + } + } + + cur += 2; + bytno = cur - new_s->data; + + if (((bytno/w) < h) && ((bytno) % w) < 2 ) + { + if (w % 2) + cur += w-1; + else + cur += w; + } + + if ((row*2) >= w) + stream_seek(temp, pw-row); + } + } + + xfree(temp->data); + stream_detach(temp); + stream_attach(context->org_buf[i], new_s->data, new_s->size); + context->OrgByteCount[i] = orglen; + } +} + +void nsc_ycocg_rgb(NSC_CONTEXT* context) +{ + uint8* sbitstream[2]; + uint8 bitoff, sign[2], i, val, tmp; + sint16 rgb[3], ycocg[3]; + uint32 bytno, size; + size = context->OrgByteCount[0]; + + for (i = 1; i < 3; i++) + sbitstream[i-1] = context->org_buf[i]->data + context->OrgByteCount[i]; + + do + { + for (i = 0; i < 3; i++) + ycocg[i] = *(context->org_buf[i]->p); + + for (i = 1; i < 3; i++) + { + bytno = context->OrgByteCount[i] - size; + bitoff = bytno % 8; + sign[i-1] = (*(sbitstream[i-1] + (bytno >> 3)) >> (7 - bitoff)) & 0x1; + ycocg[i] = (((sint16)(0 - sign[i-1])) << 8) | ycocg[i]; + } + + rgb[0] = ycocg[0] + (ycocg[1] >> 1) - (ycocg[2] >> 1); + rgb[1] = ycocg[0] + (ycocg[2] >> 1); + rgb[2] = ycocg[0] - (ycocg[1] >> 1) - (ycocg[2] >> 1); + + for (i = 0; i < 3; i++) + { + tmp = (rgb[i] >> 8) & 0xff; + if (tmp == 0xff) + val = 0x00; + else if (tmp == 0x1) + val = 0xff; + else + val = (uint8) rgb[i]; + + stream_write_uint8(context->org_buf[i], val); + } + + size--; + } + while (size); + + for (i = 0; i < 3; i++) + context->org_buf[i]->p = context->org_buf[i]->data; +} + +void nsc_colorloss_recover(NSC_CONTEXT* context) +{ + int i; + uint8 cllvl; + cllvl = context->nsc_stream->colorLossLevel; + + for (i = 1; i < 3; i++) + nsc_cl_expand(context->org_buf[i], cllvl, context->OrgByteCount[i]); +} + +void nsc_rle_decode(STREAM* in, STREAM* out, uint32 origsz) +{ + uint32 i; + uint8 value; + i = origsz; + + while (i > 4) + { + stream_read_uint8(in, value); + + if (i == 5) + { + stream_write_uint8(out,value); + i-=1; + } + else if (value == *(in->p)) + { + stream_seek(in, 1); + + if (*(in->p) < 0xFF) + { + uint8 len; + stream_read_uint8(in, len); + stream_set_byte(out, value, len+2); + i -= (len+2); + } + else + { + uint32 len; + stream_seek(in, 1); + stream_read_uint32(in, len); + stream_set_byte(out, value, len); + i -= len; + } + } + else + { + stream_write_uint8(out, value); + i -= 1; + } + } + + stream_copy(out, in, 4); +} + +void nsc_rle_decompress_data(NSC_CONTEXT* context) +{ + STREAM* rles; + uint16 i; + uint32 origsize; + rles = stream_new(0); + rles->p = rles->data = context->nsc_stream->pdata->p; + rles->size = context->nsc_stream->pdata->size; + + for (i = 0; i < 4; i++) + { + origsize = context->OrgByteCount[i]; + + if (i == 3 && context->nsc_stream->PlaneByteCount[i] == 0) + stream_set_byte(context->org_buf[i], 0xff, origsize); + else if (context->nsc_stream->PlaneByteCount[i] < origsize) + nsc_rle_decode(rles, context->org_buf[i], origsize); + else + stream_copy(context->org_buf[i], rles, origsize); + + context->org_buf[i]->p = context->org_buf[i]->data; + } +} + +void nsc_combine_argb(NSC_CONTEXT* context) +{ + int i; + uint8* bmp; + bmp = context->bmpdata; + + for (i = 0; i < (context->width * context->height); i++) + { + stream_read_uint8(context->org_buf[2], *bmp++); + stream_read_uint8(context->org_buf[1], *bmp++); + stream_read_uint8(context->org_buf[0], *bmp++); + stream_read_uint8(context->org_buf[3], *bmp++); + } +} + +void nsc_stream_initialize(NSC_CONTEXT* context, STREAM* s) +{ + int i; + + for (i = 0; i < 4; i++) + stream_read_uint32(s, context->nsc_stream->PlaneByteCount[i]); + + stream_read_uint8(s, context->nsc_stream->colorLossLevel); + stream_read_uint8(s, context->nsc_stream->ChromaSubSamplingLevel); + stream_seek(s, 2); + + context->nsc_stream->pdata = stream_new(0); + stream_attach(context->nsc_stream->pdata, s->p, BYTESUM(context->nsc_stream->PlaneByteCount)); +} + +void nsc_context_initialize(NSC_CONTEXT* context, STREAM* s) +{ + int i; + uint32 tempsz; + nsc_stream_initialize(context, s); + context->bmpdata = xzalloc(context->width * context->height * 4); + + for (i = 0; i < 4; i++) + context->OrgByteCount[i]=context->width * context->height; + + if (context->nsc_stream->ChromaSubSamplingLevel > 0) /* [MS-RDPNSC] 2.2 */ + { + uint32 tempWidth,tempHeight; + tempWidth = ROUND_UP_TO(context->width, 8); + context->OrgByteCount[0] = tempWidth * context->height; + tempWidth = tempWidth >> 1 ; + tempHeight = ROUND_UP_TO(context->height, 2); + tempHeight = tempHeight >> 1; + context->OrgByteCount[1] = tempWidth * tempHeight; + context->OrgByteCount[2] = tempWidth * tempHeight; + } + for (i = 0; i < 4; i++) + { + tempsz = context->OrgByteCount[i]; + + if (i == 1 || i == 2) + tempsz += (tempsz & 0x7) ? (tempsz >> 3) + 0x1 : (tempsz >> 3); /* extra bytes/8 bytes for bitstream to store the 9th bit after colorloss recover */ + + context->org_buf[i] = stream_new(tempsz); + } +} + +void nsc_context_destroy(NSC_CONTEXT* context) +{ + int i; + + for (i = 0;i < 4; i++) + stream_free(context->org_buf[i]); + + stream_detach(context->nsc_stream->pdata); + xfree(context->bmpdata); +} + +NSC_CONTEXT* nsc_context_new(void) +{ + NSC_CONTEXT* nsc_context; + nsc_context = xnew(NSC_CONTEXT); + nsc_context->nsc_stream = xnew(NSC_STREAM); + return nsc_context; +} + +void nsc_process_message(NSC_CONTEXT* context, uint8* data, uint32 length) +{ + STREAM* s; + s = stream_new(0); + stream_attach(s, data, length); + nsc_context_initialize(context, s); + + /* RLE decode */ + nsc_rle_decompress_data(context); + + /* colorloss recover */ + nsc_colorloss_recover(context); + + /* Chroma supersample */ + if (context->nsc_stream->ChromaSubSamplingLevel > 0) + nsc_chroma_supersample(context); + + /* YCoCg to RGB Convert */ + nsc_ycocg_rgb(context); + + /* Combine ARGB planes */ + nsc_combine_argb(context); +} diff --git a/libfreerdp-codec/rfx.c b/libfreerdp-codec/rfx.c new file mode 100644 index 0000000..9a62ddb --- /dev/null +++ b/libfreerdp-codec/rfx.c @@ -0,0 +1,894 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rfx_constants.h" +#include "rfx_types.h" +#include "rfx_pool.h" +#include "rfx_decode.h" +#include "rfx_encode.h" +#include "rfx_quantization.h" +#include "rfx_dwt.h" + +#ifdef WITH_SSE2 +#include "rfx_sse2.h" +#endif + +#ifdef WITH_NEON +#include "rfx_neon.h" +#endif + +#ifndef RFX_INIT_SIMD +#define RFX_INIT_SIMD(_rfx_context) do { } while (0) +#endif + +/** + * The quantization values control the compression rate and quality. The value + * range is between 6 and 15. The higher value, the higher compression rate + * and lower quality. + * + * This is the default values being use by the MS RDP server, and we will also + * use it as our default values for the encoder. It can be overrided by setting + * the context->num_quants and context->quants member. + * + * The order of the values are: + * LL3, LH3, HL3, HH3, LH2, HL2, HH2, LH1, HL1, HH1 + */ +static const uint32 rfx_default_quantization_values[] = +{ + 6, 6, 6, 6, 7, 7, 8, 8, 8, 9 +}; + +static void rfx_profiler_create(RFX_CONTEXT* context) +{ + PROFILER_CREATE(context->priv->prof_rfx_decode_rgb, "rfx_decode_rgb"); + PROFILER_CREATE(context->priv->prof_rfx_decode_component, "rfx_decode_component"); + PROFILER_CREATE(context->priv->prof_rfx_rlgr_decode, "rfx_rlgr_decode"); + PROFILER_CREATE(context->priv->prof_rfx_differential_decode, "rfx_differential_decode"); + PROFILER_CREATE(context->priv->prof_rfx_quantization_decode, "rfx_quantization_decode"); + PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode"); + PROFILER_CREATE(context->priv->prof_rfx_decode_ycbcr_to_rgb, "rfx_decode_ycbcr_to_rgb"); + PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb, "rfx_decode_format_rgb"); + + PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb"); + PROFILER_CREATE(context->priv->prof_rfx_encode_component, "rfx_encode_component"); + PROFILER_CREATE(context->priv->prof_rfx_rlgr_encode, "rfx_rlgr_encode"); + PROFILER_CREATE(context->priv->prof_rfx_differential_encode, "rfx_differential_encode"); + PROFILER_CREATE(context->priv->prof_rfx_quantization_encode, "rfx_quantization_encode"); + PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_encode, "rfx_dwt_2d_encode"); + PROFILER_CREATE(context->priv->prof_rfx_encode_rgb_to_ycbcr, "rfx_encode_rgb_to_ycbcr"); + PROFILER_CREATE(context->priv->prof_rfx_encode_format_rgb, "rfx_encode_format_rgb"); +} + +static void rfx_profiler_free(RFX_CONTEXT* context) +{ + PROFILER_FREE(context->priv->prof_rfx_decode_rgb); + PROFILER_FREE(context->priv->prof_rfx_decode_component); + PROFILER_FREE(context->priv->prof_rfx_rlgr_decode); + PROFILER_FREE(context->priv->prof_rfx_differential_decode); + PROFILER_FREE(context->priv->prof_rfx_quantization_decode); + PROFILER_FREE(context->priv->prof_rfx_dwt_2d_decode); + PROFILER_FREE(context->priv->prof_rfx_decode_ycbcr_to_rgb); + PROFILER_FREE(context->priv->prof_rfx_decode_format_rgb); + + PROFILER_FREE(context->priv->prof_rfx_encode_rgb); + PROFILER_FREE(context->priv->prof_rfx_encode_component); + PROFILER_FREE(context->priv->prof_rfx_rlgr_encode); + PROFILER_FREE(context->priv->prof_rfx_differential_encode); + PROFILER_FREE(context->priv->prof_rfx_quantization_encode); + PROFILER_FREE(context->priv->prof_rfx_dwt_2d_encode); + PROFILER_FREE(context->priv->prof_rfx_encode_rgb_to_ycbcr); + PROFILER_FREE(context->priv->prof_rfx_encode_format_rgb); +} + +static void rfx_profiler_print(RFX_CONTEXT* context) +{ + PROFILER_PRINT_HEADER; + + PROFILER_PRINT(context->priv->prof_rfx_decode_rgb); + PROFILER_PRINT(context->priv->prof_rfx_decode_component); + PROFILER_PRINT(context->priv->prof_rfx_rlgr_decode); + PROFILER_PRINT(context->priv->prof_rfx_differential_decode); + PROFILER_PRINT(context->priv->prof_rfx_quantization_decode); + PROFILER_PRINT(context->priv->prof_rfx_dwt_2d_decode); + PROFILER_PRINT(context->priv->prof_rfx_decode_ycbcr_to_rgb); + PROFILER_PRINT(context->priv->prof_rfx_decode_format_rgb); + + PROFILER_PRINT(context->priv->prof_rfx_encode_rgb); + PROFILER_PRINT(context->priv->prof_rfx_encode_component); + PROFILER_PRINT(context->priv->prof_rfx_rlgr_encode); + PROFILER_PRINT(context->priv->prof_rfx_differential_encode); + PROFILER_PRINT(context->priv->prof_rfx_quantization_encode); + PROFILER_PRINT(context->priv->prof_rfx_dwt_2d_encode); + PROFILER_PRINT(context->priv->prof_rfx_encode_rgb_to_ycbcr); + PROFILER_PRINT(context->priv->prof_rfx_encode_format_rgb); + + PROFILER_PRINT_FOOTER; +} + +RFX_CONTEXT* rfx_context_new(void) +{ + RFX_CONTEXT* context; + + context = xnew(RFX_CONTEXT); + context->priv = xnew(RFX_CONTEXT_PRIV); + context->priv->pool = rfx_pool_new(); + + /* initialize the default pixel format */ + rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_BGRA); + + /* align buffers to 16 byte boundary (needed for SSE/SSE2 instructions) */ + context->priv->y_r_buffer = (sint16*)(((uintptr_t)context->priv->y_r_mem + 16) & ~ 0x0F); + context->priv->cb_g_buffer = (sint16*)(((uintptr_t)context->priv->cb_g_mem + 16) & ~ 0x0F); + context->priv->cr_b_buffer = (sint16*)(((uintptr_t)context->priv->cr_b_mem + 16) & ~ 0x0F); + + context->priv->dwt_buffer = (sint16*)(((uintptr_t)context->priv->dwt_mem + 16) & ~ 0x0F); + + /* create profilers for default decoding routines */ + rfx_profiler_create(context); + + /* set up default routines */ + context->decode_ycbcr_to_rgb = rfx_decode_ycbcr_to_rgb; + context->encode_rgb_to_ycbcr = rfx_encode_rgb_to_ycbcr; + context->quantization_decode = rfx_quantization_decode; + context->quantization_encode = rfx_quantization_encode; + context->dwt_2d_decode = rfx_dwt_2d_decode; + context->dwt_2d_encode = rfx_dwt_2d_encode; + + return context; +} + +void rfx_context_set_cpu_opt(RFX_CONTEXT* context, uint32 cpu_opt) +{ + /* enable SIMD CPU acceleration if detected */ + if (cpu_opt & CPU_SSE2) + RFX_INIT_SIMD(context); +} + +void rfx_context_free(RFX_CONTEXT* context) +{ + xfree(context->quants); + + rfx_pool_free(context->priv->pool); + + rfx_profiler_print(context); + rfx_profiler_free(context); + + xfree(context->priv); + xfree(context); +} + +void rfx_context_set_pixel_format(RFX_CONTEXT* context, RFX_PIXEL_FORMAT pixel_format) +{ + context->pixel_format = pixel_format; + switch (pixel_format) + { + case RFX_PIXEL_FORMAT_BGRA: + case RFX_PIXEL_FORMAT_RGBA: + context->bits_per_pixel = 32; + break; + case RFX_PIXEL_FORMAT_BGR: + case RFX_PIXEL_FORMAT_RGB: + context->bits_per_pixel = 24; + break; + case RFX_PIXEL_FORMAT_BGR565_LE: + case RFX_PIXEL_FORMAT_RGB565_LE: + context->bits_per_pixel = 16; + break; + case RFX_PIXEL_FORMAT_PALETTE4_PLANER: + context->bits_per_pixel = 4; + break; + case RFX_PIXEL_FORMAT_PALETTE8: + context->bits_per_pixel = 8; + break; + default: + context->bits_per_pixel = 0; + break; + } +} + +void rfx_context_reset(RFX_CONTEXT* context) +{ + context->header_processed = false; + context->frame_idx = 0; +} + +static void rfx_process_message_sync(RFX_CONTEXT* context, STREAM* s) +{ + uint32 magic; + + /* RFX_SYNC */ + stream_read_uint32(s, magic); /* magic (4 bytes), 0xCACCACCA */ + + if (magic != WF_MAGIC) + { + DEBUG_WARN("invalid magic number 0x%X", magic); + return; + } + + stream_read_uint16(s, context->version); /* version (2 bytes), WF_VERSION_1_0 (0x0100) */ + + if (context->version != WF_VERSION_1_0) + { + DEBUG_WARN("unknown version number 0x%X", context->version); + return; + } + + DEBUG_RFX("version 0x%X", context->version); +} + +static void rfx_process_message_codec_versions(RFX_CONTEXT* context, STREAM* s) +{ + uint8 numCodecs; + + stream_read_uint8(s, numCodecs); /* numCodecs (1 byte), must be set to 0x01 */ + + if (numCodecs != 1) + { + DEBUG_WARN("numCodecs: %d, expected:1", numCodecs); + return; + } + + /* RFX_CODEC_VERSIONT */ + stream_read_uint8(s, context->codec_id); /* codecId (1 byte) */ + stream_read_uint8(s, context->codec_version); /* version (2 bytes) */ + + DEBUG_RFX("id %d version 0x%X.", context->codec_id, context->codec_version); +} + +static void rfx_process_message_channels(RFX_CONTEXT* context, STREAM* s) +{ + uint8 channelId; + uint8 numChannels; + + stream_read_uint8(s, numChannels); /* numChannels (1 byte), must bet set to 0x01 */ + + /* In RDVH sessions, numChannels will represent the number of virtual monitors + * configured and does not always be set to 0x01 as [MS-RDPRFX] said. + */ + if (numChannels < 1) + { + DEBUG_WARN("numChannels:%d, expected:1", numChannels); + return; + } + + /* RFX_CHANNELT */ + stream_read_uint8(s, channelId); /* channelId (1 byte) */ + stream_read_uint16(s, context->width); /* width (2 bytes) */ + stream_read_uint16(s, context->height); /* height (2 bytes) */ + + /* Now, only the first monitor can be used, therefore the other channels will be ignored. */ + stream_seek(s, 5 * (numChannels - 1)); + + DEBUG_RFX("numChannels %d id %d, %dx%d.", + numChannels, channelId, context->width, context->height); +} + +static void rfx_process_message_context(RFX_CONTEXT* context, STREAM* s) +{ + uint8 ctxId; + uint16 tileSize; + uint16 properties; + + stream_read_uint8(s, ctxId); /* ctxId (1 byte), must be set to 0x00 */ + stream_read_uint16(s, tileSize); /* tileSize (2 bytes), must be set to CT_TILE_64x64 (0x0040) */ + stream_read_uint16(s, properties); /* properties (2 bytes) */ + + DEBUG_RFX("ctxId %d tileSize %d properties 0x%X.", ctxId, tileSize, properties); + + context->properties = properties; + context->flags = (properties & 0x0007); + + if (context->flags == CODEC_MODE) + DEBUG_RFX("codec is in image mode."); + else + DEBUG_RFX("codec is in video mode."); + + switch ((properties & 0x1E00) >> 9) + { + case CLW_ENTROPY_RLGR1: + context->mode = RLGR1; + DEBUG_RFX("RLGR1."); + break; + + case CLW_ENTROPY_RLGR3: + context->mode = RLGR3; + DEBUG_RFX("RLGR3."); + break; + + default: + DEBUG_WARN("unknown RLGR algorithm."); + break; + } +} + +static void rfx_process_message_frame_begin(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +{ + uint32 frameIdx; + uint16 numRegions; + + stream_read_uint32(s, frameIdx); /* frameIdx (4 bytes), if codec is in video mode, must be ignored */ + stream_read_uint16(s, numRegions); /* numRegions (2 bytes) */ + + DEBUG_RFX("RFX_FRAME_BEGIN: frameIdx:%d numRegions:%d", frameIdx, numRegions); +} + +static void rfx_process_message_frame_end(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +{ + DEBUG_RFX("RFX_FRAME_END"); +} + +static void rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +{ + int i; + + stream_seek_uint8(s); /* regionFlags (1 byte) */ + stream_read_uint16(s, message->num_rects); /* numRects (2 bytes) */ + + if (message->num_rects < 1) + { + DEBUG_WARN("no rects."); + return; + } + + if (message->rects != NULL) + message->rects = (RFX_RECT*) xrealloc(message->rects, message->num_rects * sizeof(RFX_RECT)); + else + message->rects = (RFX_RECT*) xmalloc(message->num_rects * sizeof(RFX_RECT)); + + /* rects */ + for (i = 0; i < message->num_rects; i++) + { + /* RFX_RECT */ + stream_read_uint16(s, message->rects[i].x); /* x (2 bytes) */ + stream_read_uint16(s, message->rects[i].y); /* y (2 bytes) */ + stream_read_uint16(s, message->rects[i].width); /* width (2 bytes) */ + stream_read_uint16(s, message->rects[i].height); /* height (2 bytes) */ + + DEBUG_RFX("rect %d (%d %d %d %d).", + i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height); + } +} + +static void rfx_process_message_tile(RFX_CONTEXT* context, RFX_TILE* tile, STREAM* s) +{ + uint8 quantIdxY; + uint8 quantIdxCb; + uint8 quantIdxCr; + uint16 xIdx, yIdx; + uint16 YLen, CbLen, CrLen; + + /* RFX_TILE */ + stream_read_uint8(s, quantIdxY); /* quantIdxY (1 byte) */ + stream_read_uint8(s, quantIdxCb); /* quantIdxCb (1 byte) */ + stream_read_uint8(s, quantIdxCr); /* quantIdxCr (1 byte) */ + stream_read_uint16(s, xIdx); /* xIdx (2 bytes) */ + stream_read_uint16(s, yIdx); /* yIdx (2 bytes) */ + stream_read_uint16(s, YLen); /* YLen (2 bytes) */ + stream_read_uint16(s, CbLen); /* CbLen (2 bytes) */ + stream_read_uint16(s, CrLen); /* CrLen (2 bytes) */ + + DEBUG_RFX("quantIdxY:%d quantIdxCb:%d quantIdxCr:%d xIdx:%d yIdx:%d YLen:%d CbLen:%d CrLen:%d", + quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx, YLen, CbLen, CrLen); + + tile->x = xIdx * 64; + tile->y = yIdx * 64; + + rfx_decode_rgb(context, s, + YLen, context->quants + (quantIdxY * 10), + CbLen, context->quants + (quantIdxCb * 10), + CrLen, context->quants + (quantIdxCr * 10), + tile->data); +} + +static void rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* message, STREAM* s) +{ + int i; + uint16 subtype; + uint32 blockLen; + uint32 blockType; + uint32 tilesDataSize; + uint32* quants; + uint8 quant; + int pos; + + stream_read_uint16(s, subtype); /* subtype (2 bytes) must be set to CBT_TILESET (0xCAC2) */ + + if (subtype != CBT_TILESET) + { + DEBUG_WARN("invalid subtype, expected CBT_TILESET."); + return; + } + + stream_seek_uint16(s); /* idx (2 bytes), must be set to 0x0000 */ + stream_seek_uint16(s); /* properties (2 bytes) */ + + stream_read_uint8(s, context->num_quants); /* numQuant (1 byte) */ + stream_seek_uint8(s); /* tileSize (1 byte), must be set to 0x40 */ + + if (context->num_quants < 1) + { + DEBUG_WARN("no quantization value."); + return; + } + + stream_read_uint16(s, message->num_tiles); /* numTiles (2 bytes) */ + + if (message->num_tiles < 1) + { + DEBUG_WARN("no tiles."); + return; + } + + stream_read_uint32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ + + if (context->quants != NULL) + context->quants = (uint32*) xrealloc((void*) context->quants, context->num_quants * 10 * sizeof(uint32)); + else + context->quants = (uint32*) xmalloc(context->num_quants * 10 * sizeof(uint32)); + quants = context->quants; + + /* quantVals */ + for (i = 0; i < context->num_quants; i++) + { + /* RFX_CODEC_QUANT */ + stream_read_uint8(s, quant); + *quants++ = (quant & 0x0F); + *quants++ = (quant >> 4); + stream_read_uint8(s, quant); + *quants++ = (quant & 0x0F); + *quants++ = (quant >> 4); + stream_read_uint8(s, quant); + *quants++ = (quant & 0x0F); + *quants++ = (quant >> 4); + stream_read_uint8(s, quant); + *quants++ = (quant & 0x0F); + *quants++ = (quant >> 4); + stream_read_uint8(s, quant); + *quants++ = (quant & 0x0F); + *quants++ = (quant >> 4); + + DEBUG_RFX("quant %d (%d %d %d %d %d %d %d %d %d %d).", + i, context->quants[i * 10], context->quants[i * 10 + 1], + context->quants[i * 10 + 2], context->quants[i * 10 + 3], + context->quants[i * 10 + 4], context->quants[i * 10 + 5], + context->quants[i * 10 + 6], context->quants[i * 10 + 7], + context->quants[i * 10 + 8], context->quants[i * 10 + 9]); + } + + message->tiles = rfx_pool_get_tiles(context->priv->pool, message->num_tiles); + + /* tiles */ + for (i = 0; i < message->num_tiles; i++) + { + /* RFX_TILE */ + stream_read_uint16(s, blockType); /* blockType (2 bytes), must be set to CBT_TILE (0xCAC3) */ + stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ + + pos = stream_get_pos(s) - 6 + blockLen; + + if (blockType != CBT_TILE) + { + DEBUG_WARN("unknown block type 0x%X, expected CBT_TILE (0xCAC3).", blockType); + break; + } + + rfx_process_message_tile(context, message->tiles[i], s); + + stream_set_pos(s, pos); + } +} + +RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length) +{ + int pos; + STREAM* s; + uint32 blockLen; + uint32 blockType; + RFX_MESSAGE* message; + + s = stream_new(0); + message = xnew(RFX_MESSAGE); + stream_attach(s, data, length); + + while (stream_get_left(s) > 6) + { + /* RFX_BLOCKT */ + stream_read_uint16(s, blockType); /* blockType (2 bytes) */ + stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ + + DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); + + if (blockLen == 0) + { + DEBUG_WARN("zero blockLen"); + break; + } + + pos = stream_get_pos(s) - 6 + blockLen; + + if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) + { + /* RFX_CODEC_CHANNELT */ + /* codecId (1 byte) must be set to 0x01 */ + /* channelId (1 byte) must be set to 0x00 */ + stream_seek(s, 2); + } + + switch (blockType) + { + case WBT_SYNC: + rfx_process_message_sync(context, s); + break; + + case WBT_CODEC_VERSIONS: + rfx_process_message_codec_versions(context, s); + break; + + case WBT_CHANNELS: + rfx_process_message_channels(context, s); + break; + + case WBT_CONTEXT: + rfx_process_message_context(context, s); + break; + + case WBT_FRAME_BEGIN: + rfx_process_message_frame_begin(context, message, s); + break; + + case WBT_FRAME_END: + rfx_process_message_frame_end(context, message, s); + break; + + case WBT_REGION: + rfx_process_message_region(context, message, s); + break; + + case WBT_EXTENSION: + rfx_process_message_tileset(context, message, s); + break; + + default: + DEBUG_WARN("unknown blockType 0x%X", blockType); + break; + } + + stream_set_pos(s, pos); + } + + stream_detach(s); + stream_free(s); + + return message; +} + +uint16 rfx_message_get_tile_count(RFX_MESSAGE* message) +{ + return message->num_tiles; +} + +RFX_TILE* rfx_message_get_tile(RFX_MESSAGE* message, int index) +{ + return message->tiles[index]; +} + +uint16 rfx_message_get_rect_count(RFX_MESSAGE* message) +{ + return message->num_rects; +} + +RFX_RECT* rfx_message_get_rect(RFX_MESSAGE* message, int index) +{ + return &message->rects[index]; +} + +void rfx_message_free(RFX_CONTEXT* context, RFX_MESSAGE* message) +{ + if (message != NULL) + { + xfree(message->rects); + + if (message->tiles != NULL) + { + rfx_pool_put_tiles(context->priv->pool, message->tiles, message->num_tiles); + xfree(message->tiles); + } + + xfree(message); + } +} + +static void rfx_compose_message_sync(RFX_CONTEXT* context, STREAM* s) +{ + stream_write_uint16(s, WBT_SYNC); /* BlockT.blockType */ + stream_write_uint32(s, 12); /* BlockT.blockLen */ + stream_write_uint32(s, WF_MAGIC); /* magic */ + stream_write_uint16(s, WF_VERSION_1_0); /* version */ +} + +static void rfx_compose_message_codec_versions(RFX_CONTEXT* context, STREAM* s) +{ + stream_write_uint16(s, WBT_CODEC_VERSIONS); /* BlockT.blockType */ + stream_write_uint32(s, 10); /* BlockT.blockLen */ + stream_write_uint8(s, 1); /* numCodecs */ + stream_write_uint8(s, 1); /* codecs.codecId */ + stream_write_uint16(s, WF_VERSION_1_0); /* codecs.version */ +} + +static void rfx_compose_message_channels(RFX_CONTEXT* context, STREAM* s) +{ + stream_write_uint16(s, WBT_CHANNELS); /* BlockT.blockType */ + stream_write_uint32(s, 12); /* BlockT.blockLen */ + stream_write_uint8(s, 1); /* numChannels */ + stream_write_uint8(s, 0); /* Channel.channelId */ + stream_write_uint16(s, context->width); /* Channel.width */ + stream_write_uint16(s, context->height); /* Channel.height */ +} + +static void rfx_compose_message_context(RFX_CONTEXT* context, STREAM* s) +{ + uint16 properties; + + stream_write_uint16(s, WBT_CONTEXT); /* CodecChannelT.blockType */ + stream_write_uint32(s, 13); /* CodecChannelT.blockLen */ + stream_write_uint8(s, 1); /* CodecChannelT.codecId */ + stream_write_uint8(s, 0); /* CodecChannelT.channelId */ + stream_write_uint8(s, 0); /* ctxId */ + stream_write_uint16(s, CT_TILE_64x64); /* tileSize */ + + /* properties */ + properties = context->flags; /* flags */ + properties |= (COL_CONV_ICT << 3); /* cct */ + properties |= (CLW_XFORM_DWT_53_A << 5); /* xft */ + properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 9); /* et */ + properties |= (SCALAR_QUANTIZATION << 13); /* qt */ + stream_write_uint16(s, properties); + + /* properties in tilesets: note that this has different format from the one in TS_RFX_CONTEXT */ + properties = 1; /* lt */ + properties |= (context->flags << 1); /* flags */ + properties |= (COL_CONV_ICT << 4); /* cct */ + properties |= (CLW_XFORM_DWT_53_A << 6); /* xft */ + properties |= ((context->mode == RLGR1 ? CLW_ENTROPY_RLGR1 : CLW_ENTROPY_RLGR3) << 10); /* et */ + properties |= (SCALAR_QUANTIZATION << 14); /* qt */ + context->properties = properties; +} + +void rfx_compose_message_header(RFX_CONTEXT* context, STREAM* s) +{ + stream_check_size(s, 12 + 10 + 12 + 13); + + rfx_compose_message_sync(context, s); + rfx_compose_message_context(context, s); + rfx_compose_message_codec_versions(context, s); + rfx_compose_message_channels(context, s); + + context->header_processed = true; +} + +static void rfx_compose_message_frame_begin(RFX_CONTEXT* context, STREAM* s) +{ + stream_check_size(s, 14); + + stream_write_uint16(s, WBT_FRAME_BEGIN); /* CodecChannelT.blockType */ + stream_write_uint32(s, 14); /* CodecChannelT.blockLen */ + stream_write_uint8(s, 1); /* CodecChannelT.codecId */ + stream_write_uint8(s, 0); /* CodecChannelT.channelId */ + stream_write_uint32(s, context->frame_idx); /* frameIdx */ + stream_write_uint16(s, 1); /* numRegions */ + + context->frame_idx++; +} + +static void rfx_compose_message_region(RFX_CONTEXT* context, STREAM* s, + const RFX_RECT* rects, int num_rects) +{ + int size; + int i; + + size = 15 + num_rects * 8; + stream_check_size(s, size); + + stream_write_uint16(s, WBT_REGION); /* CodecChannelT.blockType */ + stream_write_uint32(s, size); /* set CodecChannelT.blockLen later */ + stream_write_uint8(s, 1); /* CodecChannelT.codecId */ + stream_write_uint8(s, 0); /* CodecChannelT.channelId */ + stream_write_uint8(s, 1); /* regionFlags */ + stream_write_uint16(s, num_rects); /* numRects */ + + for (i = 0; i < num_rects; i++) + { + stream_write_uint16(s, rects[i].x); + stream_write_uint16(s, rects[i].y); + stream_write_uint16(s, rects[i].width); + stream_write_uint16(s, rects[i].height); + } + + stream_write_uint16(s, CBT_REGION); /* regionType */ + stream_write_uint16(s, 1); /* numTilesets */ +} + +static void rfx_compose_message_tile(RFX_CONTEXT* context, STREAM* s, + uint8* tile_data, int tile_width, int tile_height, int rowstride, + const uint32* quantVals, int quantIdxY, int quantIdxCb, int quantIdxCr, + int xIdx, int yIdx) +{ + int YLen = 0; + int CbLen = 0; + int CrLen = 0; + int start_pos, end_pos; + + stream_check_size(s, 19); + start_pos = stream_get_pos(s); + + stream_write_uint16(s, CBT_TILE); /* BlockT.blockType */ + stream_seek_uint32(s); /* set BlockT.blockLen later */ + stream_write_uint8(s, quantIdxY); + stream_write_uint8(s, quantIdxCb); + stream_write_uint8(s, quantIdxCr); + stream_write_uint16(s, xIdx); + stream_write_uint16(s, yIdx); + + stream_seek(s, 6); /* YLen, CbLen, CrLen */ + + rfx_encode_rgb(context, tile_data, tile_width, tile_height, rowstride, + quantVals + quantIdxY * 10, quantVals + quantIdxCb * 10, quantVals + quantIdxCr * 10, + s, &YLen, &CbLen, &CrLen); + + DEBUG_RFX("xIdx=%d yIdx=%d width=%d height=%d YLen=%d CbLen=%d CrLen=%d", + xIdx, yIdx, tile_width, tile_height, YLen, CbLen, CrLen); + + end_pos = stream_get_pos(s); + + stream_set_pos(s, start_pos + 2); + stream_write_uint32(s, 19 + YLen + CbLen + CrLen); /* BlockT.blockLen */ + stream_set_pos(s, start_pos + 13); + stream_write_uint16(s, YLen); + stream_write_uint16(s, CbLen); + stream_write_uint16(s, CrLen); + + stream_set_pos(s, end_pos); +} + +static void rfx_compose_message_tileset(RFX_CONTEXT* context, STREAM* s, + uint8* image_data, int width, int height, int rowstride) +{ + int size; + int start_pos, end_pos; + int i; + int numQuants; + const uint32* quantVals; + const uint32* quantValsPtr; + int quantIdxY; + int quantIdxCb; + int quantIdxCr; + int numTiles; + int numTilesX; + int numTilesY; + int xIdx; + int yIdx; + int tilesDataSize; + + if (context->num_quants == 0) + { + numQuants = 1; + quantVals = rfx_default_quantization_values; + quantIdxY = 0; + quantIdxCb = 0; + quantIdxCr = 0; + } + else + { + numQuants = context->num_quants; + quantVals = context->quants; + quantIdxY = context->quant_idx_y; + quantIdxCb = context->quant_idx_cb; + quantIdxCr = context->quant_idx_cr; + } + + numTilesX = (width + 63) / 64; + numTilesY = (height + 63) / 64; + numTiles = numTilesX * numTilesY; + + size = 22 + numQuants * 5; + stream_check_size(s, size); + start_pos = stream_get_pos(s); + + stream_write_uint16(s, WBT_EXTENSION); /* CodecChannelT.blockType */ + stream_seek_uint32(s); /* set CodecChannelT.blockLen later */ + stream_write_uint8(s, 1); /* CodecChannelT.codecId */ + stream_write_uint8(s, 0); /* CodecChannelT.channelId */ + stream_write_uint16(s, CBT_TILESET); /* subtype */ + stream_write_uint16(s, 0); /* idx */ + stream_write_uint16(s, context->properties); /* properties */ + stream_write_uint8(s, numQuants); /* numQuants */ + stream_write_uint8(s, 0x40); /* tileSize */ + stream_write_uint16(s, numTiles); /* numTiles */ + stream_seek_uint32(s); /* set tilesDataSize later */ + + quantValsPtr = quantVals; + for (i = 0; i < numQuants * 5; i++) + { + stream_write_uint8(s, quantValsPtr[0] + (quantValsPtr[1] << 4)); + quantValsPtr += 2; + } + + DEBUG_RFX("width:%d height:%d rowstride:%d", width, height, rowstride); + + end_pos = stream_get_pos(s); + for (yIdx = 0; yIdx < numTilesY; yIdx++) + { + for (xIdx = 0; xIdx < numTilesX; xIdx++) + { + rfx_compose_message_tile(context, s, + image_data + yIdx * 64 * rowstride + xIdx * 8 * context->bits_per_pixel, + (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64, + (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64, + rowstride, quantVals, quantIdxY, quantIdxCb, quantIdxCr, xIdx, yIdx); + } + } + tilesDataSize = stream_get_pos(s) - end_pos; + size += tilesDataSize; + end_pos = stream_get_pos(s); + + stream_set_pos(s, start_pos + 2); + stream_write_uint32(s, size); /* CodecChannelT.blockLen */ + stream_set_pos(s, start_pos + 18); + stream_write_uint32(s, tilesDataSize); + + stream_set_pos(s, end_pos); +} + +static void rfx_compose_message_frame_end(RFX_CONTEXT* context, STREAM* s) +{ + stream_check_size(s, 8); + + stream_write_uint16(s, WBT_FRAME_END); /* CodecChannelT.blockType */ + stream_write_uint32(s, 8); /* CodecChannelT.blockLen */ + stream_write_uint8(s, 1); /* CodecChannelT.codecId */ + stream_write_uint8(s, 0); /* CodecChannelT.channelId */ +} + +static void rfx_compose_message_data(RFX_CONTEXT* context, STREAM* s, + const RFX_RECT* rects, int num_rects, uint8* image_data, int width, int height, int rowstride) +{ + rfx_compose_message_frame_begin(context, s); + rfx_compose_message_region(context, s, rects, num_rects); + rfx_compose_message_tileset(context, s, image_data, width, height, rowstride); + rfx_compose_message_frame_end(context, s); +} + +FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, STREAM* s, + const RFX_RECT* rects, int num_rects, uint8* image_data, int width, int height, int rowstride) +{ + /* Only the first frame should send the RemoteFX header */ + if (context->frame_idx == 0 && !context->header_processed) + rfx_compose_message_header(context, s); + + rfx_compose_message_data(context, s, rects, num_rects, image_data, width, height, rowstride); +} + diff --git a/libfreerdp-codec/rfx_bitstream.h b/libfreerdp-codec/rfx_bitstream.h new file mode 100644 index 0000000..29368f6 --- /dev/null +++ b/libfreerdp-codec/rfx_bitstream.h @@ -0,0 +1,86 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Bit Stream + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_BITSTREAM_H +#define __RFX_BITSTREAM_H + +#include + +struct _RFX_BITSTREAM +{ + uint8* buffer; + int nbytes; + int byte_pos; + int bits_left; +}; +typedef struct _RFX_BITSTREAM RFX_BITSTREAM; + +#define rfx_bitstream_attach(bs, _buffer, _nbytes) do { \ + bs->buffer = (uint8*) (_buffer); \ + bs->nbytes = (_nbytes); \ + bs->byte_pos = 0; \ + bs->bits_left = 8; } while (0) + +#define rfx_bitstream_get_bits(bs, _nbits, _r) do { \ + int nbits = _nbits; \ + int b; \ + uint16 n = 0; \ + while (bs->byte_pos < bs->nbytes && nbits > 0) \ + { \ + b = nbits; \ + if (b > bs->bits_left) \ + b = bs->bits_left; \ + if (n) \ + n <<= b; \ + n |= (bs->buffer[bs->byte_pos] >> (bs->bits_left - b)) & ((1 << b) - 1); \ + bs->bits_left -= b; \ + nbits -= b; \ + if (bs->bits_left == 0) \ + { \ + bs->bits_left = 8; \ + bs->byte_pos++; \ + } \ + } \ + _r = n; } while (0) + +#define rfx_bitstream_put_bits(bs, _bits, _nbits) do { \ + uint16 bits = (_bits); \ + int nbits = (_nbits); \ + int b; \ + while (bs->byte_pos < bs->nbytes && nbits > 0) \ + { \ + b = nbits; \ + if (b > bs->bits_left) \ + b = bs->bits_left; \ + bs->buffer[bs->byte_pos] &= ~(((1 << b) - 1) << (bs->bits_left - b)); \ + bs->buffer[bs->byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs->bits_left - b); \ + bs->bits_left -= b; \ + nbits -= b; \ + if (bs->bits_left == 0) \ + { \ + bs->bits_left = 8; \ + bs->byte_pos++; \ + } \ + } } while (0) + +#define rfx_bitstream_eos(_bs) ((_bs)->byte_pos >= (_bs)->nbytes) +#define rfx_bitstream_left(_bs) ((_bs)->byte_pos >= (_bs)->nbytes ? 0 : ((_bs)->nbytes - (_bs)->byte_pos - 1) * 8 + (_bs)->bits_left) +#define rfx_bitstream_get_processed_bytes(_bs) ((_bs)->bits_left < 8 ? (_bs)->byte_pos + 1 : (_bs)->byte_pos) + +#endif /* __RFX_BITSTREAM_H */ diff --git a/libfreerdp-codec/rfx_constants.h b/libfreerdp-codec/rfx_constants.h new file mode 100644 index 0000000..bf12886 --- /dev/null +++ b/libfreerdp-codec/rfx_constants.h @@ -0,0 +1,60 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - API Header + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_CONSTANTS_H +#define __RFX_CONSTANTS_H + +/* sync */ +#define WF_MAGIC 0xCACCACCA +#define WF_VERSION_1_0 0x0100 + +/* blockType */ +#define WBT_SYNC 0xCCC0 +#define WBT_CODEC_VERSIONS 0xCCC1 +#define WBT_CHANNELS 0xCCC2 +#define WBT_CONTEXT 0xCCC3 +#define WBT_FRAME_BEGIN 0xCCC4 +#define WBT_FRAME_END 0xCCC5 +#define WBT_REGION 0xCCC6 +#define WBT_EXTENSION 0xCCC7 +#define CBT_REGION 0xCAC1 +#define CBT_TILESET 0xCAC2 +#define CBT_TILE 0xCAC3 + +/* tileSize */ +#define CT_TILE_64x64 0x0040 + +/* properties.flags */ +#define CODEC_MODE 0x02 + +/* properties.cct */ +#define COL_CONV_ICT 0x1 + +/* properties.xft */ +#define CLW_XFORM_DWT_53_A 0x1 + +/* properties.et */ +#define CLW_ENTROPY_RLGR1 0x01 +#define CLW_ENTROPY_RLGR3 0x04 + +/* properties.qt */ +#define SCALAR_QUANTIZATION 0x1 + +#endif /* __RFX_CONSTANTS_H */ + diff --git a/libfreerdp-codec/rfx_decode.c b/libfreerdp-codec/rfx_decode.c new file mode 100644 index 0000000..f778661 --- /dev/null +++ b/libfreerdp-codec/rfx_decode.c @@ -0,0 +1,194 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Decode + * + * Copyright 2011 Vic Lee + * Copyright 2011 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "rfx_types.h" +#include "rfx_rlgr.h" +#include "rfx_differential.h" +#include "rfx_quantization.h" +#include "rfx_dwt.h" + +#include "rfx_decode.h" + +static void rfx_decode_format_rgb(sint16* r_buf, sint16* g_buf, sint16* b_buf, + RFX_PIXEL_FORMAT pixel_format, uint8* dst_buf) +{ + sint16* r = r_buf; + sint16* g = g_buf; + sint16* b = b_buf; + uint8* dst = dst_buf; + int i; + + switch (pixel_format) + { + case RFX_PIXEL_FORMAT_BGRA: + for (i = 0; i < 4096; i++) + { + *dst++ = (uint8) (*b++); + *dst++ = (uint8) (*g++); + *dst++ = (uint8) (*r++); + *dst++ = 0xFF; + } + break; + case RFX_PIXEL_FORMAT_RGBA: + for (i = 0; i < 4096; i++) + { + *dst++ = (uint8) (*r++); + *dst++ = (uint8) (*g++); + *dst++ = (uint8) (*b++); + *dst++ = 0xFF; + } + break; + case RFX_PIXEL_FORMAT_BGR: + for (i = 0; i < 4096; i++) + { + *dst++ = (uint8) (*b++); + *dst++ = (uint8) (*g++); + *dst++ = (uint8) (*r++); + } + break; + case RFX_PIXEL_FORMAT_RGB: + for (i = 0; i < 4096; i++) + { + *dst++ = (uint8) (*r++); + *dst++ = (uint8) (*g++); + *dst++ = (uint8) (*b++); + } + break; + default: + break; + } +} + +#define MINMAX(_v,_l,_h) ((_v) < (_l) ? (_l) : ((_v) > (_h) ? (_h) : (_v))) + +void rfx_decode_ycbcr_to_rgb(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf) +{ + /* sint32 is used intentionally because we calculate with shifted factors! */ + sint32 y, cb, cr; + sint32 r, g, b; + int i; + + /** + * The decoded YCbCr coeffectients are represented as 11.5 fixed-point numbers: + * + * 1 sign bit + 10 integer bits + 5 fractional bits + * + * However only 7 integer bits will be actually used since the value range is [-128.0, 127.0]. + * In other words, the decoded coeffectients is scaled by << 5 when intepreted as sint16. + * It was scaled in the quantization phase, so we must scale it back here. + */ + for (i = 0; i < 4096; i++) + { + y = y_r_buf[i]; + cb = cb_g_buf[i]; + cr = cr_b_buf[i]; + +#if 0 + /** + * This is the slow floating point version kept here for reference + */ + + y = y + 4096; /* 128<<5=4096 so that we can scale the sum by >> 5 */ + + r = y + cr*1.403f; + g = y - cb*0.344f - cr*0.714f; + b = y + cb*1.770f; + + y_r_buf[i] = MINMAX(r>>5, 0, 255); + cb_g_buf[i] = MINMAX(g>>5, 0, 255); + cr_b_buf[i] = MINMAX(b>>5, 0, 255); +#else + /** + * We scale the factors by << 16 into 32-bit integers in order to avoid slower + * floating point multiplications. Since the final result needs to be scaled + * by >> 5 we will extract only the upper 11 bits (>> 21) from the final sum. + * Hence we also have to scale the other terms of the sum by << 16. + * + * R: 1.403 << 16 = 91947 + * G: 0.344 << 16 = 22544, 0.714 << 16 = 46792 + * B: 1.770 << 16 = 115998 + */ + + y = (y+4096)<<16; + + r = y + cr*91947; + g = y - cb*22544 - cr*46792; + b = y + cb*115998; + + y_r_buf[i] = MINMAX(r>>21, 0, 255); + cb_g_buf[i] = MINMAX(g>>21, 0, 255); + cr_b_buf[i] = MINMAX(b>>21, 0, 255); +#endif + } +} + +static void rfx_decode_component(RFX_CONTEXT* context, const uint32* quantization_values, + const uint8* data, int size, sint16* buffer) +{ + PROFILER_ENTER(context->priv->prof_rfx_decode_component); + + PROFILER_ENTER(context->priv->prof_rfx_rlgr_decode); + rfx_rlgr_decode(context->mode, data, size, buffer, 4096); + PROFILER_EXIT(context->priv->prof_rfx_rlgr_decode); + + PROFILER_ENTER(context->priv->prof_rfx_differential_decode); + rfx_differential_decode(buffer + 4032, 64); + PROFILER_EXIT(context->priv->prof_rfx_differential_decode); + + PROFILER_ENTER(context->priv->prof_rfx_quantization_decode); + context->quantization_decode(buffer, quantization_values); + PROFILER_EXIT(context->priv->prof_rfx_quantization_decode); + + PROFILER_ENTER(context->priv->prof_rfx_dwt_2d_decode); + context->dwt_2d_decode(buffer, context->priv->dwt_buffer); + PROFILER_EXIT(context->priv->prof_rfx_dwt_2d_decode); + + PROFILER_EXIT(context->priv->prof_rfx_decode_component); +} + +void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, + int y_size, const uint32 * y_quants, + int cb_size, const uint32 * cb_quants, + int cr_size, const uint32 * cr_quants, uint8* rgb_buffer) +{ + PROFILER_ENTER(context->priv->prof_rfx_decode_rgb); + + rfx_decode_component(context, y_quants, stream_get_tail(data_in), y_size, context->priv->y_r_buffer); /* YData */ + stream_seek(data_in, y_size); + rfx_decode_component(context, cb_quants, stream_get_tail(data_in), cb_size, context->priv->cb_g_buffer); /* CbData */ + stream_seek(data_in, cb_size); + rfx_decode_component(context, cr_quants, stream_get_tail(data_in), cr_size, context->priv->cr_b_buffer); /* CrData */ + stream_seek(data_in, cr_size); + + PROFILER_ENTER(context->priv->prof_rfx_decode_ycbcr_to_rgb); + context->decode_ycbcr_to_rgb(context->priv->y_r_buffer, context->priv->cb_g_buffer, context->priv->cr_b_buffer); + PROFILER_EXIT(context->priv->prof_rfx_decode_ycbcr_to_rgb); + + PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb); + rfx_decode_format_rgb(context->priv->y_r_buffer, context->priv->cb_g_buffer, context->priv->cr_b_buffer, + context->pixel_format, rgb_buffer); + PROFILER_EXIT(context->priv->prof_rfx_decode_format_rgb); + + PROFILER_EXIT(context->priv->prof_rfx_decode_rgb); +} diff --git a/libfreerdp-codec/rfx_decode.h b/libfreerdp-codec/rfx_decode.h new file mode 100644 index 0000000..874ad2e --- /dev/null +++ b/libfreerdp-codec/rfx_decode.h @@ -0,0 +1,33 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Decode + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_DECODE_H +#define __RFX_DECODE_H + +#include + +void rfx_decode_ycbcr_to_rgb(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf); + +void rfx_decode_rgb(RFX_CONTEXT* context, STREAM* data_in, + int y_size, const uint32 * y_quants, + int cb_size, const uint32 * cb_quants, + int cr_size, const uint32 * cr_quants, uint8* rgb_buffer); + +#endif /* __RFX_DECODE_H */ + diff --git a/libfreerdp-codec/rfx_differential.c b/libfreerdp-codec/rfx_differential.c new file mode 100644 index 0000000..7a1d49e --- /dev/null +++ b/libfreerdp-codec/rfx_differential.c @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Differential Encoding + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "rfx_differential.h" + +void rfx_differential_decode(sint16* buffer, int buffer_size) +{ + sint16* src; + sint16* dst; + + for (src = buffer, dst = buffer + 1; buffer_size > 1; src++, dst++, buffer_size--) + { + *dst += *src; + } +} + +void rfx_differential_encode(sint16* buffer, int buffer_size) +{ + sint16 n1, n2; + sint16* dst; + + for (n1 = *buffer, dst = buffer + 1; buffer_size > 1; dst++, buffer_size--) + { + n2 = *dst; + *dst -= n1; + n1 = n2; + } +} diff --git a/libfreerdp-codec/rfx_differential.h b/libfreerdp-codec/rfx_differential.h new file mode 100644 index 0000000..58b08b9 --- /dev/null +++ b/libfreerdp-codec/rfx_differential.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Differential Encoding + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_DIFFERENTIAL_H +#define __RFX_DIFFERENTIAL_H + +#include + +void rfx_differential_decode(sint16* buffer, int buffer_size); +void rfx_differential_encode(sint16* buffer, int buffer_size); + +#endif /* __RFX_DIFFERENTIAL_H */ diff --git a/libfreerdp-codec/rfx_dwt.c b/libfreerdp-codec/rfx_dwt.c new file mode 100644 index 0000000..e870b18 --- /dev/null +++ b/libfreerdp-codec/rfx_dwt.c @@ -0,0 +1,194 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - DWT + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "rfx_dwt.h" + +static void rfx_dwt_2d_decode_block(sint16* buffer, sint16* idwt, int subband_width) +{ + sint16 *dst, *l, *h; + sint16 *l_dst, *h_dst; + sint16 *hl, *lh, *hh, *ll; + int total_width; + int x, y; + int n; + + total_width = subband_width << 1; + + /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */ + /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */ + /* The lower part L uses LL(3) and HL(0). */ + /* The higher part H uses LH(1) and HH(2). */ + + ll = buffer + subband_width * subband_width * 3; + hl = buffer; + l_dst = idwt; + + lh = buffer + subband_width * subband_width; + hh = buffer + subband_width * subband_width * 2; + h_dst = idwt + subband_width * subband_width * 2; + + for (y = 0; y < subband_width; y++) + { + /* Even coefficients */ + l_dst[0] = ll[0] - ((hl[0] + hl[0] + 1) >> 1); + h_dst[0] = lh[0] - ((hh[0] + hh[0] + 1) >> 1); + for (n = 1; n < subband_width; n++) + { + x = n << 1; + l_dst[x] = ll[n] - ((hl[n-1] + hl[n] + 1) >> 1); + h_dst[x] = lh[n] - ((hh[n-1] + hh[n] + 1) >> 1); + } + + /* Odd coefficients */ + for (n = 0; n < subband_width-1; n++) + { + x = n << 1; + l_dst[x + 1] = (hl[n] << 1) + ((l_dst[x] + l_dst[x + 2]) >> 1); + h_dst[x + 1] = (hh[n] << 1) + ((h_dst[x] + h_dst[x + 2]) >> 1); + } + x = n << 1; + l_dst[x + 1] = (hl[n] << 1) + (l_dst[x]); + h_dst[x + 1] = (hh[n] << 1) + (h_dst[x]); + + ll += subband_width; + hl += subband_width; + l_dst += total_width; + + lh += subband_width; + hh += subband_width; + h_dst += total_width; + } + + /* Inverse DWT in vertical direction, results are stored in original buffer. */ + for (x = 0; x < total_width; x++) + { + /* Even coefficients */ + for (n = 0; n < subband_width; n++) + { + y = n << 1; + dst = buffer + y * total_width + x; + l = idwt + n * total_width + x; + h = l + subband_width * total_width; + dst[0] = *l - (((n > 0 ? *(h - total_width) : *h) + (*h) + 1) >> 1); + } + + /* Odd coefficients */ + for (n = 0; n < subband_width; n++) + { + y = n << 1; + dst = buffer + y * total_width + x; + l = idwt + n * total_width + x; + h = l + subband_width * total_width; + dst[total_width] = (*h << 1) + ((dst[0] + dst[n < subband_width - 1 ? 2 * total_width : 0]) >> 1); + } + } +} + +void rfx_dwt_2d_decode(sint16* buffer, sint16* dwt_buffer) +{ + rfx_dwt_2d_decode_block(buffer + 3840, dwt_buffer, 8); + rfx_dwt_2d_decode_block(buffer + 3072, dwt_buffer, 16); + rfx_dwt_2d_decode_block(buffer, dwt_buffer, 32); +} + +static void rfx_dwt_2d_encode_block(sint16* buffer, sint16* dwt, int subband_width) +{ + sint16 *src, *l, *h; + sint16 *l_src, *h_src; + sint16 *hl, *lh, *hh, *ll; + int total_width; + int x, y; + int n; + + total_width = subband_width << 1; + + /* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */ + for (x = 0; x < total_width; x++) + { + for (n = 0; n < subband_width; n++) + { + y = n << 1; + l = dwt + n * total_width + x; + h = l + subband_width * total_width; + src = buffer + y * total_width + x; + + /* H */ + *h = (src[total_width] - ((src[0] + src[n < subband_width - 1 ? 2 * total_width : 0]) >> 1)) >> 1; + + /* L */ + *l = src[0] + (n == 0 ? *h : (*(h - total_width) + *h) >> 1); + } + } + + /* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order, stored in original buffer. */ + /* The lower part L generates LL(3) and HL(0). */ + /* The higher part H generates LH(1) and HH(2). */ + + ll = buffer + subband_width * subband_width * 3; + hl = buffer; + l_src = dwt; + + lh = buffer + subband_width * subband_width; + hh = buffer + subband_width * subband_width * 2; + h_src = dwt + subband_width * subband_width * 2; + + for (y = 0; y < subband_width; y++) + { + /* L */ + for (n = 0; n < subband_width; n++) + { + x = n << 1; + + /* HL */ + hl[n] = (l_src[x + 1] - ((l_src[x] + l_src[n < subband_width - 1 ? x + 2 : x]) >> 1)) >> 1; + /* LL */ + ll[n] = l_src[x] + (n == 0 ? hl[n] : (hl[n - 1] + hl[n]) >> 1); + } + + /* H */ + for (n = 0; n < subband_width; n++) + { + x = n << 1; + + /* HH */ + hh[n] = (h_src[x + 1] - ((h_src[x] + h_src[n < subband_width - 1 ? x + 2 : x]) >> 1)) >> 1; + /* LH */ + lh[n] = h_src[x] + (n == 0 ? hh[n] : (hh[n - 1] + hh[n]) >> 1); + } + + ll += subband_width; + hl += subband_width; + l_src += total_width; + + lh += subband_width; + hh += subband_width; + h_src += total_width; + } +} + +void rfx_dwt_2d_encode(sint16* buffer, sint16* dwt_buffer) +{ + rfx_dwt_2d_encode_block(buffer, dwt_buffer, 32); + rfx_dwt_2d_encode_block(buffer + 3072, dwt_buffer, 16); + rfx_dwt_2d_encode_block(buffer + 3840, dwt_buffer, 8); +} diff --git a/libfreerdp-codec/rfx_dwt.h b/libfreerdp-codec/rfx_dwt.h new file mode 100644 index 0000000..cfdc4bc --- /dev/null +++ b/libfreerdp-codec/rfx_dwt.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - DWT + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_DWT_H +#define __RFX_DWT_H + +#include + +void rfx_dwt_2d_decode(sint16* buffer, sint16* dwt_buffer); +void rfx_dwt_2d_encode(sint16* buffer, sint16* dwt_buffer); + +#endif /* __RFX_DWT_H */ diff --git a/libfreerdp-codec/rfx_encode.c b/libfreerdp-codec/rfx_encode.c new file mode 100644 index 0000000..578866d --- /dev/null +++ b/libfreerdp-codec/rfx_encode.c @@ -0,0 +1,280 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Encode + * + * Copyright 2011 Vic Lee + * Copyright 2011 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "rfx_types.h" +#include "rfx_rlgr.h" +#include "rfx_differential.h" +#include "rfx_quantization.h" +#include "rfx_dwt.h" + +#include "rfx_encode.h" + +#define MINMAX(_v,_l,_h) ((_v) < (_l) ? (_l) : ((_v) > (_h) ? (_h) : (_v))) + +static void rfx_encode_format_rgb(const uint8* rgb_data, int width, int height, int rowstride, + RFX_PIXEL_FORMAT pixel_format, const uint8* palette, sint16* r_buf, sint16* g_buf, sint16* b_buf) +{ + int x, y; + int x_exceed; + int y_exceed; + const uint8* src; + sint16 r, g, b; + sint16 *r_last, *g_last, *b_last; + + x_exceed = 64 - width; + y_exceed = 64 - height; + + for (y = 0; y < height; y++) + { + src = rgb_data + y * rowstride; + + switch (pixel_format) + { + case RFX_PIXEL_FORMAT_BGRA: + for (x = 0; x < width; x++) + { + *b_buf++ = (sint16) (*src++); + *g_buf++ = (sint16) (*src++); + *r_buf++ = (sint16) (*src++); + src++; + } + break; + case RFX_PIXEL_FORMAT_RGBA: + for (x = 0; x < width; x++) + { + *r_buf++ = (sint16) (*src++); + *g_buf++ = (sint16) (*src++); + *b_buf++ = (sint16) (*src++); + src++; + } + break; + case RFX_PIXEL_FORMAT_BGR: + for (x = 0; x < width; x++) + { + *b_buf++ = (sint16) (*src++); + *g_buf++ = (sint16) (*src++); + *r_buf++ = (sint16) (*src++); + } + break; + case RFX_PIXEL_FORMAT_RGB: + for (x = 0; x < width; x++) + { + *r_buf++ = (sint16) (*src++); + *g_buf++ = (sint16) (*src++); + *b_buf++ = (sint16) (*src++); + } + break; + case RFX_PIXEL_FORMAT_BGR565_LE: + for (x = 0; x < width; x++) + { + *b_buf++ = (sint16) (((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5)); + *g_buf++ = (sint16) ((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3)); + *r_buf++ = (sint16) ((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07)); + src += 2; + } + break; + case RFX_PIXEL_FORMAT_RGB565_LE: + for (x = 0; x < width; x++) + { + *r_buf++ = (sint16) (((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5)); + *g_buf++ = (sint16) ((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3)); + *b_buf++ = (sint16) ((((*src) & 0x1F) << 3) | (((*src) >> 2) & 0x07)); + src += 2; + } + break; + case RFX_PIXEL_FORMAT_PALETTE4_PLANER: + if (!palette) + break; + for (x = 0; x < width; x++) + { + int shift; + uint8 idx; + + shift = (7 - (x % 8)); + idx = ((*src) >> shift) & 1; + idx |= (((*(src + 1)) >> shift) & 1) << 1; + idx |= (((*(src + 2)) >> shift) & 1) << 2; + idx |= (((*(src + 3)) >> shift) & 1) << 3; + idx *= 3; + *r_buf++ = (sint16) palette[idx]; + *g_buf++ = (sint16) palette[idx + 1]; + *b_buf++ = (sint16) palette[idx + 2]; + if (shift == 0) + src += 4; + } + break; + case RFX_PIXEL_FORMAT_PALETTE8: + if (!palette) + break; + for (x = 0; x < width; x++) + { + int idx = (*src) * 3; + + *r_buf++ = (sint16) palette[idx]; + *g_buf++ = (sint16) palette[idx + 1]; + *b_buf++ = (sint16) palette[idx + 2]; + src++; + } + break; + default: + break; + } + /* Fill the horizontal region outside of 64x64 tile size with the right-most pixel for best quality */ + if (x_exceed > 0) + { + r = *(r_buf - 1); + g = *(g_buf - 1); + b = *(b_buf - 1); + + for (x = 0; x < x_exceed; x++) + { + *r_buf++ = r; + *g_buf++ = g; + *b_buf++ = b; + } + } + } + + /* Fill the vertical region outside of 64x64 tile size with the last line. */ + if (y_exceed > 0) + { + r_last = r_buf - 64; + g_last = g_buf - 64; + b_last = b_buf - 64; + + while (y_exceed > 0) + { + memcpy(r_buf, r_last, 64 * sizeof(sint16)); + memcpy(g_buf, g_last, 64 * sizeof(sint16)); + memcpy(b_buf, b_last, 64 * sizeof(sint16)); + r_buf += 64; + g_buf += 64; + b_buf += 64; + y_exceed--; + } + } +} + +void rfx_encode_rgb_to_ycbcr(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf) +{ + /* sint32 is used intentionally because we calculate with shifted factors! */ + int i; + sint32 r, g, b; + sint32 y, cb, cr; + + /** + * The encoded YCbCr coefficients are represented as 11.5 fixed-point numbers: + * + * 1 sign bit + 10 integer bits + 5 fractional bits + * + * However only 7 integer bits will be actually used since the value range is [-128.0, 127.0]. + * In other words, the encoded coefficients is scaled by << 5 when interpreted as sint16. + * It will be scaled down to original during the quantization phase. + */ + for (i = 0; i < 4096; i++) + { + r = y_r_buf[i]; + g = cb_g_buf[i]; + b = cr_b_buf[i]; + + /* + * We scale the factors by << 15 into 32-bit integers in order to avoid slower + * floating point multiplications. Since the terms need to be scaled by << 5 we + * simply scale the final sum by >> 10 + * + * Y: 0.299000 << 15 = 9798, 0.587000 << 15 = 19235, 0.114000 << 15 = 3735 + * Cb: 0.168935 << 15 = 5535, 0.331665 << 15 = 10868, 0.500590 << 15 = 16403 + * Cr: 0.499813 << 15 = 16377, 0.418531 << 15 = 13714, 0.081282 << 15 = 2663 + */ + + y = (r * 9798 + g * 19235 + b * 3735) >> 10; + cb = (r * -5535 + g * -10868 + b * 16403) >> 10; + cr = (r * 16377 + g * -13714 + b * -2663) >> 10; + + y_r_buf[i] = MINMAX(y - 4096, -4096, 4095); + cb_g_buf[i] = MINMAX(cb, -4096, 4095); + cr_b_buf[i] = MINMAX(cr, -4096, 4095); + } +} + +static void rfx_encode_component(RFX_CONTEXT* context, const uint32* quantization_values, + sint16* data, uint8* buffer, int buffer_size, int* size) +{ + PROFILER_ENTER(context->priv->prof_rfx_encode_component); + + PROFILER_ENTER(context->priv->prof_rfx_dwt_2d_encode); + context->dwt_2d_encode(data, context->priv->dwt_buffer); + PROFILER_EXIT(context->priv->prof_rfx_dwt_2d_encode); + + PROFILER_ENTER(context->priv->prof_rfx_quantization_encode); + context->quantization_encode(data, quantization_values); + PROFILER_EXIT(context->priv->prof_rfx_quantization_encode); + + PROFILER_ENTER(context->priv->prof_rfx_differential_encode); + rfx_differential_encode(data + 4032, 64); + PROFILER_EXIT(context->priv->prof_rfx_differential_encode); + + PROFILER_ENTER(context->priv->prof_rfx_rlgr_encode); + *size = rfx_rlgr_encode(context->mode, data, 4096, buffer, buffer_size); + PROFILER_EXIT(context->priv->prof_rfx_rlgr_encode); + + PROFILER_EXIT(context->priv->prof_rfx_encode_component); +} + +void rfx_encode_rgb(RFX_CONTEXT* context, const uint8* rgb_data, int width, int height, int rowstride, + const uint32* y_quants, const uint32* cb_quants, const uint32* cr_quants, + STREAM* data_out, int* y_size, int* cb_size, int* cr_size) +{ + sint16* y_r_buffer = context->priv->y_r_buffer; + sint16* cb_g_buffer = context->priv->cb_g_buffer; + sint16* cr_b_buffer = context->priv->cr_b_buffer; + + PROFILER_ENTER(context->priv->prof_rfx_encode_rgb); + + PROFILER_ENTER(context->priv->prof_rfx_encode_format_rgb); + rfx_encode_format_rgb(rgb_data, width, height, rowstride, + context->pixel_format, context->palette, y_r_buffer, cb_g_buffer, cr_b_buffer); + PROFILER_EXIT(context->priv->prof_rfx_encode_format_rgb); + + PROFILER_ENTER(context->priv->prof_rfx_encode_rgb_to_ycbcr); + context->encode_rgb_to_ycbcr(context->priv->y_r_buffer, context->priv->cb_g_buffer, context->priv->cr_b_buffer); + PROFILER_EXIT(context->priv->prof_rfx_encode_rgb_to_ycbcr); + + /* Ensure the buffer is reasonably large enough */ + stream_check_size(data_out, 4096); + rfx_encode_component(context, y_quants, context->priv->y_r_buffer, + stream_get_tail(data_out), stream_get_left(data_out), y_size); + stream_seek(data_out, *y_size); + + stream_check_size(data_out, 4096); + rfx_encode_component(context, cb_quants, context->priv->cb_g_buffer, + stream_get_tail(data_out), stream_get_left(data_out), cb_size); + stream_seek(data_out, *cb_size); + + stream_check_size(data_out, 4096); + rfx_encode_component(context, cr_quants, context->priv->cr_b_buffer, + stream_get_tail(data_out), stream_get_left(data_out), cr_size); + stream_seek(data_out, *cr_size); + + PROFILER_EXIT(context->priv->prof_rfx_encode_rgb); +} diff --git a/libfreerdp-codec/rfx_encode.h b/libfreerdp-codec/rfx_encode.h new file mode 100644 index 0000000..6fa1e95 --- /dev/null +++ b/libfreerdp-codec/rfx_encode.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Encode + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_ENCODE_H +#define __RFX_ENCODE_H + +#include + +void rfx_encode_rgb_to_ycbcr(sint16* y_r_buf, sint16* cb_g_buf, sint16* cr_b_buf); + +void rfx_encode_rgb(RFX_CONTEXT* context, const uint8* rgb_data, int width, int height, int rowstride, + const uint32* y_quants, const uint32* cb_quants, const uint32* cr_quants, + STREAM* data_out, int* y_size, int* cb_size, int* cr_size); + +#endif + diff --git a/libfreerdp-codec/rfx_neon.c b/libfreerdp-codec/rfx_neon.c new file mode 100644 index 0000000..5a57a2f --- /dev/null +++ b/libfreerdp-codec/rfx_neon.c @@ -0,0 +1,352 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + RemoteFX Codec Library - NEON Optimizations + + Copyright 2011 Martin Fleisz + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#if defined(__ARM_NEON__) + +#include +#include +#include +#include + +#include "rfx_types.h" +#include "rfx_neon.h" + +#if defined(ANDROID) +#include +#endif + + +void rfx_decode_YCbCr_to_RGB_NEON(sint16 * y_r_buffer, sint16 * cb_g_buffer, sint16 * cr_b_buffer) +{ + int16x8_t zero = vdupq_n_s16(0); + int16x8_t max = vdupq_n_s16(255); + int16x8_t y_add = vdupq_n_s16(128); + + int16x8_t* y_r_buf = (int16x8_t*)y_r_buffer; + int16x8_t* cb_g_buf = (int16x8_t*)cb_g_buffer; + int16x8_t* cr_b_buf = (int16x8_t*)cr_b_buffer; + + int i; + for (i = 0; i < 4096 / 8; i++) + { + int16x8_t y = vld1q_s16((sint16*)&y_r_buf[i]); + y = vaddq_s16(y, y_add); + + int16x8_t cr = vld1q_s16((sint16*)&cr_b_buf[i]); + + // r = between((y + cr + (cr >> 2) + (cr >> 3) + (cr >> 5)), 0, 255); + int16x8_t r = vaddq_s16(y, cr); + r = vaddq_s16(r, vshrq_n_s16(cr, 2)); + r = vaddq_s16(r, vshrq_n_s16(cr, 3)); + r = vaddq_s16(r, vshrq_n_s16(cr, 5)); + r = vminq_s16(vmaxq_s16(r, zero), max); + vst1q_s16((sint16*)&y_r_buf[i], r); + + // cb = cb_g_buf[i]; + int16x8_t cb = vld1q_s16((sint16*)&cb_g_buf[i]); + + // g = between(y - (cb >> 2) - (cb >> 4) - (cb >> 5) - (cr >> 1) - (cr >> 3) - (cr >> 4) - (cr >> 5), 0, 255); + int16x8_t g = vsubq_s16(y, vshrq_n_s16(cb, 2)); + g = vsubq_s16(g, vshrq_n_s16(cb, 4)); + g = vsubq_s16(g, vshrq_n_s16(cb, 5)); + g = vsubq_s16(g, vshrq_n_s16(cr, 1)); + g = vsubq_s16(g, vshrq_n_s16(cr, 3)); + g = vsubq_s16(g, vshrq_n_s16(cr, 4)); + g = vsubq_s16(g, vshrq_n_s16(cr, 5)); + g = vminq_s16(vmaxq_s16(g, zero), max); + vst1q_s16((sint16*)&cb_g_buf[i], g); + + // b = between((y + cb + (cb >> 1) + (cb >> 2) + (cb >> 6)), 0, 255); + int16x8_t b = vaddq_s16(y, cb); + b = vaddq_s16(b, vshrq_n_s16(cb, 1)); + b = vaddq_s16(b, vshrq_n_s16(cb, 2)); + b = vaddq_s16(b, vshrq_n_s16(cb, 6)); + b = vminq_s16(vmaxq_s16(b, zero), max); + vst1q_s16((sint16*)&cr_b_buf[i], b); + } + +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_quantization_decode_block_NEON(sint16 * buffer, const int buffer_size, const uint32 factor) +{ + if (factor <= 6) + return; + int16x8_t quantFactors = vdupq_n_s16(factor - 6); + int16x8_t* buf = (int16x8_t*)buffer; + int16x8_t* buf_end = (int16x8_t*)(buffer + buffer_size); + + do + { + int16x8_t val = vld1q_s16((sint16*)buf); + val = vshlq_s16(val, quantFactors); + vst1q_s16((sint16*)buf, val); + buf++; + } + while(buf < buf_end); +} + +void +rfx_quantization_decode_NEON(sint16 * buffer, const uint32 * quantization_values) +{ + rfx_quantization_decode_block_NEON(buffer, 1024, quantization_values[8]); /* HL1 */ + rfx_quantization_decode_block_NEON(buffer + 1024, 1024, quantization_values[7]); /* LH1 */ + rfx_quantization_decode_block_NEON(buffer + 2048, 1024, quantization_values[9]); /* HH1 */ + rfx_quantization_decode_block_NEON(buffer + 3072, 256, quantization_values[5]); /* HL2 */ + rfx_quantization_decode_block_NEON(buffer + 3328, 256, quantization_values[4]); /* LH2 */ + rfx_quantization_decode_block_NEON(buffer + 3584, 256, quantization_values[6]); /* HH2 */ + rfx_quantization_decode_block_NEON(buffer + 3840, 64, quantization_values[2]); /* HL3 */ + rfx_quantization_decode_block_NEON(buffer + 3904, 64, quantization_values[1]); /* LH3 */ + rfx_quantization_decode_block_NEON(buffer + 3968, 64, quantization_values[3]); /* HH3 */ + rfx_quantization_decode_block_NEON(buffer + 4032, 64, quantization_values[0]); /* LL3 */ +} + + + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_horiz_NEON(sint16 * l, sint16 * h, sint16 * dst, int subband_width) +{ + int y, n; + sint16 * l_ptr = l; + sint16 * h_ptr = h; + sint16 * dst_ptr = dst; + + for (y = 0; y < subband_width; y++) + { + /* Even coefficients */ + for (n = 0; n < subband_width; n+=8) + { + // dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); + int16x8_t l_n = vld1q_s16(l_ptr); + + int16x8_t h_n = vld1q_s16(h_ptr); + int16x8_t h_n_m = vld1q_s16(h_ptr - 1); + + if (n == 0) + { + int16_t first = vgetq_lane_s16(h_n_m, 1); + h_n_m = vsetq_lane_s16(first, h_n_m, 0); + } + + int16x8_t tmp_n = vaddq_s16(h_n, h_n_m); + tmp_n = vaddq_s16(tmp_n, vdupq_n_s16(1)); + tmp_n = vshrq_n_s16(tmp_n, 1); + + int16x8_t dst_n = vsubq_s16(l_n, tmp_n); + + vst1q_s16(l_ptr, dst_n); + + l_ptr+=8; + h_ptr+=8; + } + l_ptr -= subband_width; + h_ptr -= subband_width; + + /* Odd coefficients */ + for (n = 0; n < subband_width; n+=8) + { + // dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); + + int16x8_t h_n = vld1q_s16(h_ptr); + + h_n = vshlq_n_s16(h_n, 1); + + int16x8x2_t dst_n; + dst_n.val[0] = vld1q_s16(l_ptr); + int16x8_t dst_n_p = vld1q_s16(l_ptr + 1); + if (n == subband_width - 8) + { + int16_t last = vgetq_lane_s16(dst_n_p, 6); + dst_n_p = vsetq_lane_s16(last, dst_n_p, 7); + } + + dst_n.val[1] = vaddq_s16(dst_n_p, dst_n.val[0]); + dst_n.val[1] = vshrq_n_s16(dst_n.val[1], 1); + + dst_n.val[1] = vaddq_s16(dst_n.val[1], h_n); + + vst2q_s16(dst_ptr, dst_n); + + l_ptr+=8; + h_ptr+=8; + dst_ptr+=16; + } + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_vert_NEON(sint16 * l, sint16 * h, sint16 * dst, int subband_width) +{ + int x, n; + sint16 * l_ptr = l; + sint16 * h_ptr = h; + sint16 * dst_ptr = dst; + + int total_width = subband_width + subband_width; + + /* Even coefficients */ + for (n = 0; n < subband_width; n++) + { + for (x = 0; x < total_width; x+=8) + { + // dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); + + int16x8_t l_n = vld1q_s16(l_ptr); + int16x8_t h_n = vld1q_s16(h_ptr); + + int16x8_t tmp_n = vaddq_s16(h_n, vdupq_n_s16(1));; + if (n == 0) + tmp_n = vaddq_s16(tmp_n, h_n); + else + { + int16x8_t h_n_m = vld1q_s16((h_ptr - total_width)); + tmp_n = vaddq_s16(tmp_n, h_n_m); + } + tmp_n = vshrq_n_s16(tmp_n, 1); + + int16x8_t dst_n = vsubq_s16(l_n, tmp_n); + vst1q_s16(dst_ptr, dst_n); + + l_ptr+=8; + h_ptr+=8; + dst_ptr+=8; + } + dst_ptr+=total_width; + } + + h_ptr = h; + dst_ptr = dst + total_width; + + /* Odd coefficients */ + for (n = 0; n < subband_width; n++) + { + for (x = 0; x < total_width; x+=8) + { + // dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); + int16x8_t h_n = vld1q_s16(h_ptr); + int16x8_t dst_n_m = vld1q_s16(dst_ptr - total_width); + + h_n = vshlq_n_s16(h_n, 1); + + int16x8_t tmp_n = dst_n_m; + if (n == subband_width - 1) + tmp_n = vaddq_s16(tmp_n, dst_n_m); + else + { + int16x8_t dst_n_p = vld1q_s16((dst_ptr + total_width)); + tmp_n = vaddq_s16(tmp_n, dst_n_p); + } + tmp_n = vshrq_n_s16(tmp_n, 1); + + int16x8_t dst_n = vaddq_s16(tmp_n, h_n); + vst1q_s16(dst_ptr, dst_n); + + h_ptr+=8; + dst_ptr+=8; + } + dst_ptr+=total_width; +} +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_NEON(sint16 * buffer, sint16 * idwt, int subband_width) +{ + sint16 * hl, * lh, * hh, * ll; + sint16 * l_dst, * h_dst; + + /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */ + /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */ + /* The lower part L uses LL(3) and HL(0). */ + /* The higher part H uses LH(1) and HH(2). */ + + ll = buffer + subband_width * subband_width * 3; + hl = buffer; + l_dst = idwt; + + rfx_dwt_2d_decode_block_horiz_NEON(ll, hl, l_dst, subband_width); + + lh = buffer + subband_width * subband_width; + hh = buffer + subband_width * subband_width * 2; + h_dst = idwt + subband_width * subband_width * 2; + + rfx_dwt_2d_decode_block_horiz_NEON(lh, hh, h_dst, subband_width); + + /* Inverse DWT in vertical direction, results are stored in original buffer. */ + rfx_dwt_2d_decode_block_vert_NEON(l_dst, h_dst, buffer, subband_width); +} + +void +rfx_dwt_2d_decode_NEON(sint16 * buffer, sint16 * dwt_buffer) +{ + rfx_dwt_2d_decode_block_NEON(buffer + 3840, dwt_buffer, 8); + rfx_dwt_2d_decode_block_NEON(buffer + 3072, dwt_buffer, 16); + rfx_dwt_2d_decode_block_NEON(buffer, dwt_buffer, 32); +} + + + +int isNeonSupported() +{ +#if defined(ANDROID) + if (android_getCpuFamily() != ANDROID_CPU_FAMILY_ARM) + { + DEBUG_RFX("NEON optimization disabled - No ARM CPU found"); + return 0; + } + + uint64_t features = android_getCpuFeatures(); + if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7)) + { + if (features & ANDROID_CPU_ARM_FEATURE_NEON) + { + DEBUG_RFX("NEON optimization enabled!"); + return 1; + } + DEBUG_RFX("NEON optimization disabled - CPU not NEON capable"); + } + else + DEBUG_RFX("NEON optimization disabled - No ARMv7 CPU found"); + + return 0; +#else + return 1; +#endif +} + + +void rfx_init_neon(RFX_CONTEXT * context) +{ + + + if(isNeonSupported()) + { + DEBUG_RFX("Using NEON optimizations"); + + IF_PROFILER(context->priv->prof_rfx_decode_ycbcr_to_rgb->name = "rfx_decode_YCbCr_to_RGB_NEON"); + IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_NEON"); + IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_NEON"); + + context->decode_ycbcr_to_rgb = rfx_decode_YCbCr_to_RGB_NEON; + context->quantization_decode = rfx_quantization_decode_NEON; + context->dwt_2d_decode = rfx_dwt_2d_decode_NEON; + } +} + +#endif // __ARM_NEON__ + diff --git a/libfreerdp-codec/rfx_neon.h b/libfreerdp-codec/rfx_neon.h new file mode 100644 index 0000000..28dbc36 --- /dev/null +++ b/libfreerdp-codec/rfx_neon.h @@ -0,0 +1,38 @@ +/* + FreeRDP: A Remote Desktop Protocol client. + RemoteFX Codec Library - NEON Optimizations + + Copyright 2011 Martin Fleisz + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef __RFX_NEON_H +#define __RFX_NEON_H + +#include + +#if defined(__ARM_NEON__) + +void rfx_init_neon(RFX_CONTEXT * context); + +#ifndef RFX_INIT_SIMD + #if defined(WITH_NEON) + #define RFX_INIT_SIMD(_rfx_context) rfx_init_neon(_rfx_context) + #endif +#endif + +#endif // __ARM_NEON__ + +#endif /* __RFX_NEON_H */ + diff --git a/libfreerdp-codec/rfx_pool.c b/libfreerdp-codec/rfx_pool.c new file mode 100644 index 0000000..12e703c --- /dev/null +++ b/libfreerdp-codec/rfx_pool.c @@ -0,0 +1,112 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Memory Pool + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "rfx_pool.h" + +RFX_POOL* rfx_pool_new() +{ + RFX_POOL* pool; + + pool = xnew(RFX_POOL); + + pool->size = 64; + pool->tiles = (RFX_TILE**) xzalloc(sizeof(RFX_TILE*) * pool->size); + + return pool; +} + +void rfx_pool_free(RFX_POOL* pool) +{ + int i; + RFX_TILE* tile; + + for (i = 0; i < pool->count; i++) + { + tile = pool->tiles[i]; + + if (tile != NULL) + { + if (tile->data != NULL) + xfree(tile->data); + + xfree(tile); + } + } + + xfree(pool->tiles); + xfree(pool); +} + +void rfx_pool_put_tile(RFX_POOL* pool, RFX_TILE* tile) +{ + if (pool->count >= pool->size) + { + pool->size *= 2; + pool->tiles = (RFX_TILE**) xrealloc((void*) pool->tiles, sizeof(RFX_TILE*) * pool->size); + } + + pool->tiles[(pool->count)++] = tile; +} + +RFX_TILE* rfx_pool_get_tile(RFX_POOL* pool) +{ + RFX_TILE* tile; + + if (pool->count < 1) + { + tile = xnew(RFX_TILE); + tile->data = (uint8*) xmalloc(4096 * 4); /* 64x64 * 4 */ + } + else + { + tile = pool->tiles[--(pool->count)]; + } + + return tile; +} + +void rfx_pool_put_tiles(RFX_POOL* pool, RFX_TILE** tiles, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + rfx_pool_put_tile(pool, tiles[i]); + } +} + +RFX_TILE** rfx_pool_get_tiles(RFX_POOL* pool, int count) +{ + int i; + RFX_TILE** tiles; + + tiles = (RFX_TILE**) xmalloc(sizeof(RFX_TILE*) * count); + + for (i = 0; i < count; i++) + { + tiles[i] = rfx_pool_get_tile(pool); + } + + return tiles; +} diff --git a/libfreerdp-codec/rfx_pool.h b/libfreerdp-codec/rfx_pool.h new file mode 100644 index 0000000..4f1ff81 --- /dev/null +++ b/libfreerdp-codec/rfx_pool.h @@ -0,0 +1,40 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Memory Pool + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_POOL_H +#define __RFX_POOL_H + +#include + +struct _RFX_POOL +{ + int size; + int count; + RFX_TILE** tiles; +}; +typedef struct _RFX_POOL RFX_POOL; + +RFX_POOL* rfx_pool_new(); +void rfx_pool_free(RFX_POOL* pool); +void rfx_pool_put_tile(RFX_POOL* pool, RFX_TILE* tile); +RFX_TILE* rfx_pool_get_tile(RFX_POOL* pool); +void rfx_pool_put_tiles(RFX_POOL* pool, RFX_TILE** tiles, int count); +RFX_TILE** rfx_pool_get_tiles(RFX_POOL* pool, int count); + +#endif /* __RFX_POOL_H */ diff --git a/libfreerdp-codec/rfx_quantization.c b/libfreerdp-codec/rfx_quantization.c new file mode 100644 index 0000000..617818f --- /dev/null +++ b/libfreerdp-codec/rfx_quantization.c @@ -0,0 +1,82 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Quantization + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rfx_quantization.h" + +static void rfx_quantization_decode_block(sint16* buffer, int buffer_size, uint32 factor) +{ + sint16* dst; + + if (factor == 0) + return; + + for (dst = buffer; buffer_size > 0; dst++, buffer_size--) + { + *dst <<= factor; + } +} + +void rfx_quantization_decode(sint16* buffer, const uint32* quantization_values) +{ + /* Scale the values so that they are represented as 11.5 fixed-point number */ + rfx_quantization_decode_block(buffer, 4096, 5); + + rfx_quantization_decode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */ + rfx_quantization_decode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ + rfx_quantization_decode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ + rfx_quantization_decode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ + rfx_quantization_decode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ + rfx_quantization_decode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ + rfx_quantization_decode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ + rfx_quantization_decode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ + rfx_quantization_decode_block(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ + rfx_quantization_decode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ +} + +static void rfx_quantization_encode_block(sint16* buffer, int buffer_size, uint32 factor) +{ + sint16* dst; + sint16 half; + + if (factor == 0) + return; + + half = (1 << (factor - 1)); + for (dst = buffer; buffer_size > 0; dst++, buffer_size--) + { + *dst = (*dst + half) >> factor; + } +} + +void rfx_quantization_encode(sint16* buffer, const uint32* quantization_values) +{ + rfx_quantization_encode_block(buffer, 1024, quantization_values[8] - 6); /* HL1 */ + rfx_quantization_encode_block(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ + rfx_quantization_encode_block(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ + rfx_quantization_encode_block(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ + rfx_quantization_encode_block(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ + rfx_quantization_encode_block(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ + rfx_quantization_encode_block(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ + rfx_quantization_encode_block(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ + rfx_quantization_encode_block(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ + rfx_quantization_encode_block(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ + + /* The coefficients are scaled by << 5 at RGB->YCbCr phase, so we round it back here */ + rfx_quantization_encode_block(buffer, 4096, 5); +} diff --git a/libfreerdp-codec/rfx_quantization.h b/libfreerdp-codec/rfx_quantization.h new file mode 100644 index 0000000..9fbfa51 --- /dev/null +++ b/libfreerdp-codec/rfx_quantization.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - Quantization + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_QUANTIZATION_H +#define __RFX_QUANTIZATION_H + +#include + +void rfx_quantization_decode(sint16* buffer, const uint32* quantization_values); +void rfx_quantization_encode(sint16* buffer, const uint32* quantization_values); + +#endif /* __RFX_QUANTIZATION_H */ diff --git a/libfreerdp-codec/rfx_rlgr.c b/libfreerdp-codec/rfx_rlgr.c new file mode 100644 index 0000000..b20c89b --- /dev/null +++ b/libfreerdp-codec/rfx_rlgr.c @@ -0,0 +1,431 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - RLGR + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This implementation of RLGR refers to + * [MS-RDPRFX] 3.1.8.1.7.3 RLGR1/RLGR3 Pseudocode + */ + +#include +#include +#include +#include +#include "rfx_bitstream.h" + +#include "rfx_rlgr.h" + +/* Constants used within the RLGR1/RLGR3 algorithm */ +#define KPMAX (80) /* max value for kp or krp */ +#define LSGR (3) /* shift count to convert kp to k */ +#define UP_GR (4) /* increase in kp after a zero run in RL mode */ +#define DN_GR (6) /* decrease in kp after a nonzero symbol in RL mode */ +#define UQ_GR (3) /* increase in kp after nonzero symbol in GR mode */ +#define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */ + +/* Gets (returns) the next nBits from the bitstream */ +#define GetBits(nBits, r) rfx_bitstream_get_bits(bs, nBits, r) + +/* From current output pointer, write "value", check and update buffer_size */ +#define WriteValue(value) \ +{ \ + if (buffer_size > 0) \ + *dst++ = (value); \ + buffer_size--; \ +} + +/* From current output pointer, write next nZeroes terms with value 0, check and update buffer_size */ +#define WriteZeroes(nZeroes) \ +{ \ + int nZeroesWritten = (nZeroes); \ + if (nZeroesWritten > buffer_size) \ + nZeroesWritten = buffer_size; \ + if (nZeroesWritten > 0) \ + { \ + memset(dst, 0, nZeroesWritten * sizeof(sint16)); \ + dst += nZeroesWritten; \ + } \ + buffer_size -= (nZeroes); \ +} + +/* Returns the least number of bits required to represent a given value */ +#define GetMinBits(_val, _nbits) \ +{ \ + uint32 _v = _val; \ + _nbits = 0; \ + while (_v) \ + { \ + _v >>= 1; \ + _nbits++; \ + } \ +} + +/* Converts from (2 * magnitude - sign) to integer */ +#define GetIntFrom2MagSign(twoMs) (((twoMs) & 1) ? -1 * (sint16)(((twoMs) + 1) >> 1) : (sint16)((twoMs) >> 1)) + +/* + * Update the passed parameter and clamp it to the range [0, KPMAX] + * Return the value of parameter right-shifted by LSGR + */ +#define UpdateParam(_param, _deltaP, _k) \ +{ \ + _param += _deltaP; \ + if (_param > KPMAX) \ + _param = KPMAX; \ + if (_param < 0) \ + _param = 0; \ + _k = (_param >> LSGR); \ +} + +/* Outputs the Golomb/Rice encoding of a non-negative integer */ +#define GetGRCode(krp, kr, vk, _mag) \ + vk = 0; \ + _mag = 0; \ + /* chew up/count leading 1s and escape 0 */ \ + do { \ + GetBits(1, r); \ + if (r == 1) \ + vk++; \ + else \ + break; \ + } while (1); \ + /* get next *kr bits, and combine with leading 1s */ \ + GetBits(*kr, _mag); \ + _mag |= (vk << *kr); \ + /* adjust krp and kr based on vk */ \ + if (!vk) { \ + UpdateParam(*krp, -2, *kr); \ + } \ + else if (vk != 1) { \ + UpdateParam(*krp, vk, *kr); /* at 1, no change! */ \ + } + +int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* buffer, int buffer_size) +{ + int k; + int kp; + int kr; + int krp; + uint16 r; + sint16* dst; + RFX_BITSTREAM* bs; + + int vk; + uint16 mag16; + + bs = xnew(RFX_BITSTREAM); + rfx_bitstream_attach(bs, data, data_size); + dst = buffer; + + /* initialize the parameters */ + k = 1; + kp = k << LSGR; + kr = 1; + krp = kr << LSGR; + + while (!rfx_bitstream_eos(bs) && buffer_size > 0) + { + int run; + if (k) + { + int mag; + uint32 sign; + + /* RL MODE */ + while (!rfx_bitstream_eos(bs)) + { + GetBits(1, r); + if (r) + break; + /* we have an RL escape "0", which translates to a run (1< 0) \ + { \ + _n = *data++; \ + data_size--; \ + } \ + else \ + { \ + _n = 0; \ + } \ +} + +/* Emit bitPattern to the output bitstream */ +#define OutputBits(numBits, bitPattern) rfx_bitstream_put_bits(bs, bitPattern, numBits) + +/* Emit a bit (0 or 1), count number of times, to the output bitstream */ +#define OutputBit(count, bit) \ +{ \ + uint16 _b = (bit ? 0xFFFF : 0); \ + int _c = (count); \ + for (; _c > 0; _c -= 16) \ + rfx_bitstream_put_bits(bs, _b, (_c > 16 ? 16 : _c)); \ +} + +/* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 : 0) and returns it */ +#define Get2MagSign(input) ((input) >= 0 ? 2 * (input) : -2 * (input) - 1) + +/* Outputs the Golomb/Rice encoding of a non-negative integer */ +#define CodeGR(krp, val) rfx_rlgr_code_gr(bs, krp, val) + +static void rfx_rlgr_code_gr(RFX_BITSTREAM* bs, int* krp, uint32 val) +{ + int kr = *krp >> LSGR; + + /* unary part of GR code */ + + uint32 vk = (val) >> kr; + OutputBit(vk, 1); + OutputBit(1, 0); + + /* remainder part of GR code, if needed */ + if (kr) + { + OutputBits(kr, val & ((1 << kr) - 1)); + } + + /* update krp, only if it is not equal to 1 */ + if (vk == 0) + { + UpdateParam(*krp, -2, kr); + } + else if (vk > 1) + { + UpdateParam(*krp, vk, kr); + } +} + +int rfx_rlgr_encode(RLGR_MODE mode, const sint16* data, int data_size, uint8* buffer, int buffer_size) +{ + int k; + int kp; + int krp; + RFX_BITSTREAM* bs; + int processed_size; + + bs = xnew(RFX_BITSTREAM); + rfx_bitstream_attach(bs, buffer, buffer_size); + + /* initialize the parameters */ + k = 1; + kp = 1 << LSGR; + krp = 1 << LSGR; + + /* process all the input coefficients */ + while (data_size > 0) + { + int input; + + if (k) + { + int numZeros; + int runmax; + int mag; + int sign; + + /* RUN-LENGTH MODE */ + + /* collect the run of zeros in the input stream */ + numZeros = 0; + GetNextInput(input); + while (input == 0 && data_size > 0) + { + numZeros++; + GetNextInput(input); + } + + // emit output zeros + runmax = 1 << k; + while (numZeros >= runmax) + { + OutputBit(1, 0); /* output a zero bit */ + numZeros -= runmax; + UpdateParam(kp, UP_GR, k); /* update kp, k */ + runmax = 1 << k; + } + + /* output a 1 to terminate runs */ + OutputBit(1, 1); + + /* output the remaining run length using k bits */ + OutputBits(k, numZeros); + + /* note: when we reach here and the last byte being encoded is 0, we still + need to output the last two bits, otherwise mstsc will crash */ + + /* encode the nonzero value using GR coding */ + mag = (input < 0 ? -input : input); /* absolute value of input coefficient */ + sign = (input < 0 ? 1 : 0); /* sign of input coefficient */ + + OutputBit(1, sign); /* output the sign bit */ + CodeGR(&krp, mag ? mag - 1 : 0); /* output GR code for (mag - 1) */ + + UpdateParam(kp, -DN_GR, k); + } + else + { + /* GOLOMB-RICE MODE */ + + if (mode == RLGR1) + { + uint32 twoMs; + + /* RLGR1 variant */ + + /* convert input to (2*magnitude - sign), encode using GR code */ + GetNextInput(input); + twoMs = Get2MagSign(input); + CodeGR(&krp, twoMs); + + /* update k, kp */ + /* NOTE: as of Aug 2011, the algorithm is still wrongly documented + and the update direction is reversed */ + if (twoMs) + { + UpdateParam(kp, -DQ_GR, k); + } + else + { + UpdateParam(kp, UQ_GR, k); + } + } + else /* mode == RLGR3 */ + { + uint32 twoMs1; + uint32 twoMs2; + uint32 sum2Ms; + uint32 nIdx; + + /* RLGR3 variant */ + + /* convert the next two input values to (2*magnitude - sign) and */ + /* encode their sum using GR code */ + + GetNextInput(input); + twoMs1 = Get2MagSign(input); + GetNextInput(input); + twoMs2 = Get2MagSign(input); + sum2Ms = twoMs1 + twoMs2; + + CodeGR(&krp, sum2Ms); + + /* encode binary representation of the first input (twoMs1). */ + GetMinBits(sum2Ms, nIdx); + OutputBits(nIdx, twoMs1); + + /* update k,kp for the two input values */ + + if (twoMs1 && twoMs2) + { + UpdateParam(kp, -2 * DQ_GR, k); + } + else if (!twoMs1 && !twoMs2) + { + UpdateParam(kp, 2 * UQ_GR, k); + } + } + } + } + + processed_size = rfx_bitstream_get_processed_bytes(bs); + xfree(bs); + + return processed_size; +} diff --git a/libfreerdp-codec/rfx_rlgr.h b/libfreerdp-codec/rfx_rlgr.h new file mode 100644 index 0000000..b470bd5 --- /dev/null +++ b/libfreerdp-codec/rfx_rlgr.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - RLGR + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_RLGR_H +#define __RFX_RLGR_H + +#include + +int rfx_rlgr_decode(RLGR_MODE mode, const uint8* data, int data_size, sint16* buffer, int buffer_size); +int rfx_rlgr_encode(RLGR_MODE mode, const sint16* data, int data_size, uint8* buffer, int buffer_size); + +#endif /* __RFX_RLGR_H */ diff --git a/libfreerdp-codec/rfx_sse2.c b/libfreerdp-codec/rfx_sse2.c new file mode 100644 index 0000000..cdf92ae --- /dev/null +++ b/libfreerdp-codec/rfx_sse2.c @@ -0,0 +1,669 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - SSE2 Optimizations + * + * Copyright 2011 Stephen Erisman + * Copyright 2011 Norbert Federa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "rfx_types.h" +#include "rfx_sse2.h" + +#ifdef _MSC_VER +#define __attribute__(...) +#endif + +#define CACHE_LINE_BYTES 64 + +#define _mm_between_epi16(_val, _min, _max) \ + do { _val = _mm_min_epi16(_max, _mm_max_epi16(_val, _min)); } while (0) + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_prefetch_buffer(char * buffer, int num_bytes) +{ + __m128i * buf = (__m128i*) buffer; + int i; + for (i = 0; i < (num_bytes / sizeof(__m128i)); i+=(CACHE_LINE_BYTES / sizeof(__m128i))) + { + _mm_prefetch((char*)(&buf[i]), _MM_HINT_NTA); + } +} + +static void rfx_decode_ycbcr_to_rgb_sse2(sint16* y_r_buffer, sint16* cb_g_buffer, sint16* cr_b_buffer) +{ + __m128i zero = _mm_setzero_si128(); + __m128i max = _mm_set1_epi16(255); + + __m128i* y_r_buf = (__m128i*) y_r_buffer; + __m128i* cb_g_buf = (__m128i*) cb_g_buffer; + __m128i* cr_b_buf = (__m128i*) cr_b_buffer; + + __m128i y; + __m128i cr; + __m128i cb; + __m128i r; + __m128i g; + __m128i b; + + int i; + + __m128i r_cr = _mm_set1_epi16(22986); // 1.403 << 14 + __m128i g_cb = _mm_set1_epi16(-5636); // -0.344 << 14 + __m128i g_cr = _mm_set1_epi16(-11698); // -0.714 << 14 + __m128i b_cb = _mm_set1_epi16(28999); // 1.770 << 14 + __m128i c4096 = _mm_set1_epi16(4096); + + for (i = 0; i < (4096 * sizeof(sint16) / sizeof(__m128i)); i += (CACHE_LINE_BYTES / sizeof(__m128i))) + { + _mm_prefetch((char*)(&y_r_buf[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&cb_g_buf[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&cr_b_buf[i]), _MM_HINT_NTA); + } + for (i = 0; i < (4096 * sizeof(sint16) / sizeof(__m128i)); i++) + { + /* + In order to use SSE2 signed 16-bit integer multiplication we need to convert + the floating point factors to signed int without loosing information. + The result of this multiplication is 32 bit and we have two SSE instructions + that return either the hi or lo word. + Thus we will multiply the factors by the highest possible 2^n, take the + upper 16 bits of the signed 32-bit result (_mm_mulhi_epi16) and correct this + result by multiplying it by 2^(16-n). + For the given factors in the conversion matrix the best possible n is 14. + + Example for calculating r: + r = (y>>5) + 128 + (cr*1.403)>>5 // our base formula + r = (y>>5) + 128 + (HIWORD(cr*(1.403<<14)<<2))>>5 // see above + r = (y+4096)>>5 + (HIWORD(cr*22986)<<2)>>5 // simplification + r = ((y+4096)>>2 + HIWORD(cr*22986)) >> 3 + */ + + /* y = (y_r_buf[i] + 4096) >> 2 */ + y = _mm_load_si128(&y_r_buf[i]); + y = _mm_add_epi16(y, c4096); + y = _mm_srai_epi16(y, 2); + /* cb = cb_g_buf[i]; */ + cb = _mm_load_si128(&cb_g_buf[i]); + /* cr = cr_b_buf[i]; */ + cr = _mm_load_si128(&cr_b_buf[i]); + + /* (y + HIWORD(cr*22986)) >> 3 */ + r = _mm_add_epi16(y, _mm_mulhi_epi16(cr, r_cr)); + r = _mm_srai_epi16(r, 3); + /* y_r_buf[i] = MINMAX(r, 0, 255); */ + _mm_between_epi16(r, zero, max); + _mm_store_si128(&y_r_buf[i], r); + + /* (y + HIWORD(cb*-5636) + HIWORD(cr*-11698)) >> 3 */ + g = _mm_add_epi16(y, _mm_mulhi_epi16(cb, g_cb)); + g = _mm_add_epi16(g, _mm_mulhi_epi16(cr, g_cr)); + g = _mm_srai_epi16(g, 3); + /* cb_g_buf[i] = MINMAX(g, 0, 255); */ + _mm_between_epi16(g, zero, max); + _mm_store_si128(&cb_g_buf[i], g); + + /* (y + HIWORD(cb*28999)) >> 3 */ + b = _mm_add_epi16(y, _mm_mulhi_epi16(cb, b_cb)); + b = _mm_srai_epi16(b, 3); + /* cr_b_buf[i] = MINMAX(b, 0, 255); */ + _mm_between_epi16(b, zero, max); + _mm_store_si128(&cr_b_buf[i], b); + } +} + +/* The encodec YCbCr coeffectients are represented as 11.5 fixed-point numbers. See rfx_encode.c */ +static void rfx_encode_rgb_to_ycbcr_sse2(sint16* y_r_buffer, sint16* cb_g_buffer, sint16* cr_b_buffer) +{ + __m128i min = _mm_set1_epi16(-128 << 5); + __m128i max = _mm_set1_epi16(127 << 5); + + __m128i* y_r_buf = (__m128i*) y_r_buffer; + __m128i* cb_g_buf = (__m128i*) cb_g_buffer; + __m128i* cr_b_buf = (__m128i*) cr_b_buffer; + + __m128i y; + __m128i cr; + __m128i cb; + __m128i r; + __m128i g; + __m128i b; + + __m128i y_r = _mm_set1_epi16(9798); // 0.299000 << 15 + __m128i y_g = _mm_set1_epi16(19235); // 0.587000 << 15 + __m128i y_b = _mm_set1_epi16(3735); // 0.114000 << 15 + __m128i cb_r = _mm_set1_epi16(-5535); // -0.168935 << 15 + __m128i cb_g = _mm_set1_epi16(-10868); // -0.331665 << 15 + __m128i cb_b = _mm_set1_epi16(16403); // 0.500590 << 15 + __m128i cr_r = _mm_set1_epi16(16377); // 0.499813 << 15 + __m128i cr_g = _mm_set1_epi16(-13714); // -0.418531 << 15 + __m128i cr_b = _mm_set1_epi16(-2663); // -0.081282 << 15 + + int i; + + for (i = 0; i < (4096 * sizeof(sint16) / sizeof(__m128i)); i += (CACHE_LINE_BYTES / sizeof(__m128i))) + { + _mm_prefetch((char*)(&y_r_buf[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&cb_g_buf[i]), _MM_HINT_NTA); + _mm_prefetch((char*)(&cr_b_buf[i]), _MM_HINT_NTA); + } + for (i = 0; i < (4096 * sizeof(sint16) / sizeof(__m128i)); i++) + { + /* + In order to use SSE2 signed 16-bit integer multiplication we need to convert + the floating point factors to signed int without loosing information. + The result of this multiplication is 32 bit and using SSE2 we get either the + product's hi or lo word. + Thus we will multiply the factors by the highest possible 2^n and take the + upper 16 bits of the signed 32-bit result (_mm_mulhi_epi16). + Since the final result needs to be scaled by << 5 and also in in order to keep + the precision within the upper 16 bits we will also have to scale the RGB + values used in the multiplication by << 5+(16-n). + */ + + /* r = y_r_buf[i]; */ + r = _mm_load_si128(&y_r_buf[i]); + + /* g = cb_g_buf[i]; */ + g = _mm_load_si128(&cb_g_buf[i]); + + /* b = cr_b_buf[i]; */ + b = _mm_load_si128(&cr_b_buf[i]); + + /* r<<6; g<<6; b<<6 */ + r = _mm_slli_epi16(r, 6); + g = _mm_slli_epi16(g, 6); + b = _mm_slli_epi16(b, 6); + + /* y = HIWORD(r*y_r) + HIWORD(g*y_g) + HIWORD(b*y_b) + min */ + y = _mm_mulhi_epi16(r, y_r); + y = _mm_add_epi16(y, _mm_mulhi_epi16(g, y_g)); + y = _mm_add_epi16(y, _mm_mulhi_epi16(b, y_b)); + y = _mm_add_epi16(y, min); + /* y_r_buf[i] = MINMAX(y, 0, (255 << 5)) - (128 << 5); */ + _mm_between_epi16(y, min, max); + _mm_store_si128(&y_r_buf[i], y); + + /* cb = HIWORD(r*cb_r) + HIWORD(g*cb_g) + HIWORD(b*cb_b) */ + cb = _mm_mulhi_epi16(r, cb_r); + cb = _mm_add_epi16(cb, _mm_mulhi_epi16(g, cb_g)); + cb = _mm_add_epi16(cb, _mm_mulhi_epi16(b, cb_b)); + /* cb_g_buf[i] = MINMAX(cb, (-128 << 5), (127 << 5)); */ + _mm_between_epi16(cb, min, max); + _mm_store_si128(&cb_g_buf[i], cb); + + /* cr = HIWORD(r*cr_r) + HIWORD(g*cr_g) + HIWORD(b*cr_b) */ + cr = _mm_mulhi_epi16(r, cr_r); + cr = _mm_add_epi16(cr, _mm_mulhi_epi16(g, cr_g)); + cr = _mm_add_epi16(cr, _mm_mulhi_epi16(b, cr_b)); + /* cr_b_buf[i] = MINMAX(cr, (-128 << 5), (127 << 5)); */ + _mm_between_epi16(cr, min, max); + _mm_store_si128(&cr_b_buf[i], cr); + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_quantization_decode_block_sse2(sint16* buffer, const int buffer_size, const uint32 factor) +{ + __m128i a; + __m128i * ptr = (__m128i*) buffer; + __m128i * buf_end = (__m128i*) (buffer + buffer_size); + + if (factor == 0) + return; + + do + { + a = _mm_load_si128(ptr); + a = _mm_slli_epi16(a, factor); + _mm_store_si128(ptr, a); + + ptr++; + } while(ptr < buf_end); +} + +static void rfx_quantization_decode_sse2(sint16* buffer, const uint32* quantization_values) +{ + _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16)); + + rfx_quantization_decode_block_sse2(buffer, 4096, 5); + + rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */ + rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ + rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ + rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ + rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ + rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ + rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ + rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ + rfx_quantization_decode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ + rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_quantization_encode_block_sse2(sint16* buffer, const int buffer_size, const uint32 factor) +{ + __m128i a; + __m128i* ptr = (__m128i*) buffer; + __m128i* buf_end = (__m128i*) (buffer + buffer_size); + __m128i half; + + if (factor == 0) + return; + + half = _mm_set1_epi16(1 << (factor - 1)); + do + { + a = _mm_load_si128(ptr); + a = _mm_add_epi16(a, half); + a = _mm_srai_epi16(a, factor); + _mm_store_si128(ptr, a); + + ptr++; + } while(ptr < buf_end); +} + +static void rfx_quantization_encode_sse2(sint16* buffer, const uint32* quantization_values) +{ + _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16)); + + rfx_quantization_encode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */ + rfx_quantization_encode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */ + rfx_quantization_encode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */ + rfx_quantization_encode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */ + rfx_quantization_encode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */ + rfx_quantization_encode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */ + rfx_quantization_encode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */ + rfx_quantization_encode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */ + rfx_quantization_encode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */ + rfx_quantization_encode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */ + + rfx_quantization_encode_block_sse2(buffer, 4096, 5); +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_horiz_sse2(sint16* l, sint16* h, sint16* dst, int subband_width) +{ + int y, n; + sint16* l_ptr = l; + sint16* h_ptr = h; + sint16* dst_ptr = dst; + int first; + int last; + __m128i l_n; + __m128i h_n; + __m128i h_n_m; + __m128i tmp_n; + __m128i dst_n; + __m128i dst_n_p; + __m128i dst1; + __m128i dst2; + + for (y = 0; y < subband_width; y++) + { + /* Even coefficients */ + for (n = 0; n < subband_width; n+=8) + { + /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */ + + l_n = _mm_load_si128((__m128i*) l_ptr); + + h_n = _mm_load_si128((__m128i*) h_ptr); + h_n_m = _mm_loadu_si128((__m128i*) (h_ptr - 1)); + if (n == 0) + { + first = _mm_extract_epi16(h_n_m, 1); + h_n_m = _mm_insert_epi16(h_n_m, first, 0); + } + + tmp_n = _mm_add_epi16(h_n, h_n_m); + tmp_n = _mm_add_epi16(tmp_n, _mm_set1_epi16(1)); + tmp_n = _mm_srai_epi16(tmp_n, 1); + + dst_n = _mm_sub_epi16(l_n, tmp_n); + + _mm_store_si128((__m128i*) l_ptr, dst_n); + + l_ptr+=8; + h_ptr+=8; + } + l_ptr -= subband_width; + h_ptr -= subband_width; + + /* Odd coefficients */ + for (n = 0; n < subband_width; n+=8) + { + /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */ + + h_n = _mm_load_si128((__m128i*) h_ptr); + + h_n = _mm_slli_epi16(h_n, 1); + + dst_n = _mm_load_si128((__m128i*) (l_ptr)); + dst_n_p = _mm_loadu_si128((__m128i*) (l_ptr + 1)); + if (n == subband_width - 8) + { + last = _mm_extract_epi16(dst_n_p, 6); + dst_n_p = _mm_insert_epi16(dst_n_p, last, 7); + } + + tmp_n = _mm_add_epi16(dst_n_p, dst_n); + tmp_n = _mm_srai_epi16(tmp_n, 1); + + tmp_n = _mm_add_epi16(tmp_n, h_n); + + dst1 = _mm_unpacklo_epi16(dst_n, tmp_n); + dst2 = _mm_unpackhi_epi16(dst_n, tmp_n); + + _mm_store_si128((__m128i*) dst_ptr, dst1); + _mm_store_si128((__m128i*) (dst_ptr + 8), dst2); + + l_ptr+=8; + h_ptr+=8; + dst_ptr+=16; + } + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_vert_sse2(sint16* l, sint16* h, sint16* dst, int subband_width) +{ + int x, n; + sint16* l_ptr = l; + sint16* h_ptr = h; + sint16* dst_ptr = dst; + __m128i l_n; + __m128i h_n; + __m128i tmp_n; + __m128i h_n_m; + __m128i dst_n; + __m128i dst_n_m; + __m128i dst_n_p; + + int total_width = subband_width + subband_width; + + /* Even coefficients */ + for (n = 0; n < subband_width; n++) + { + for (x = 0; x < total_width; x+=8) + { + /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */ + + l_n = _mm_load_si128((__m128i*) l_ptr); + h_n = _mm_load_si128((__m128i*) h_ptr); + + tmp_n = _mm_add_epi16(h_n, _mm_set1_epi16(1));; + if (n == 0) + tmp_n = _mm_add_epi16(tmp_n, h_n); + else + { + h_n_m = _mm_loadu_si128((__m128i*) (h_ptr - total_width)); + tmp_n = _mm_add_epi16(tmp_n, h_n_m); + } + tmp_n = _mm_srai_epi16(tmp_n, 1); + + dst_n = _mm_sub_epi16(l_n, tmp_n); + _mm_store_si128((__m128i*) dst_ptr, dst_n); + + l_ptr+=8; + h_ptr+=8; + dst_ptr+=8; + } + dst_ptr+=total_width; + } + + h_ptr = h; + dst_ptr = dst + total_width; + + /* Odd coefficients */ + for (n = 0; n < subband_width; n++) + { + for (x = 0; x < total_width; x+=8) + { + /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */ + + h_n = _mm_load_si128((__m128i*) h_ptr); + dst_n_m = _mm_load_si128((__m128i*) (dst_ptr - total_width)); + h_n = _mm_slli_epi16(h_n, 1); + + tmp_n = dst_n_m; + if (n == subband_width - 1) + tmp_n = _mm_add_epi16(tmp_n, dst_n_m); + else + { + dst_n_p = _mm_loadu_si128((__m128i*) (dst_ptr + total_width)); + tmp_n = _mm_add_epi16(tmp_n, dst_n_p); + } + tmp_n = _mm_srai_epi16(tmp_n, 1); + + dst_n = _mm_add_epi16(tmp_n, h_n); + _mm_store_si128((__m128i*) dst_ptr, dst_n); + + h_ptr+=8; + dst_ptr+=8; + } + dst_ptr+=total_width; + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_decode_block_sse2(sint16* buffer, sint16* idwt, int subband_width) +{ + sint16 *hl, *lh, *hh, *ll; + sint16 *l_dst, *h_dst; + + _mm_prefetch_buffer((char*) idwt, subband_width * 4 * sizeof(sint16)); + + /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */ + /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */ + /* The lower part L uses LL(3) and HL(0). */ + /* The higher part H uses LH(1) and HH(2). */ + + ll = buffer + subband_width * subband_width * 3; + hl = buffer; + l_dst = idwt; + + rfx_dwt_2d_decode_block_horiz_sse2(ll, hl, l_dst, subband_width); + + lh = buffer + subband_width * subband_width; + hh = buffer + subband_width * subband_width * 2; + h_dst = idwt + subband_width * subband_width * 2; + + rfx_dwt_2d_decode_block_horiz_sse2(lh, hh, h_dst, subband_width); + + /* Inverse DWT in vertical direction, results are stored in original buffer. */ + rfx_dwt_2d_decode_block_vert_sse2(l_dst, h_dst, buffer, subband_width); +} + +static void rfx_dwt_2d_decode_sse2(sint16* buffer, sint16* dwt_buffer) +{ + _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16)); + + rfx_dwt_2d_decode_block_sse2(buffer + 3840, dwt_buffer, 8); + rfx_dwt_2d_decode_block_sse2(buffer + 3072, dwt_buffer, 16); + rfx_dwt_2d_decode_block_sse2(buffer, dwt_buffer, 32); +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_encode_block_vert_sse2(sint16* src, sint16* l, sint16* h, int subband_width) +{ + int total_width; + int x; + int n; + __m128i src_2n; + __m128i src_2n_1; + __m128i src_2n_2; + __m128i h_n; + __m128i h_n_m; + __m128i l_n; + + total_width = subband_width << 1; + + for (n = 0; n < subband_width; n++) + { + for (x = 0; x < total_width; x += 8) + { + src_2n = _mm_load_si128((__m128i*) src); + src_2n_1 = _mm_load_si128((__m128i*) (src + total_width)); + if (n < subband_width - 1) + src_2n_2 = _mm_load_si128((__m128i*) (src + 2 * total_width)); + else + src_2n_2 = src_2n; + + /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */ + + h_n = _mm_add_epi16(src_2n, src_2n_2); + h_n = _mm_srai_epi16(h_n, 1); + h_n = _mm_sub_epi16(src_2n_1, h_n); + h_n = _mm_srai_epi16(h_n, 1); + + _mm_store_si128((__m128i*) h, h_n); + + if (n == 0) + h_n_m = h_n; + else + h_n_m = _mm_load_si128((__m128i*) (h - total_width)); + + /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */ + + l_n = _mm_add_epi16(h_n_m, h_n); + l_n = _mm_srai_epi16(l_n, 1); + l_n = _mm_add_epi16(l_n, src_2n); + + _mm_store_si128((__m128i*) l, l_n); + + src += 8; + l += 8; + h += 8; + } + src += total_width; + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_encode_block_horiz_sse2(sint16* src, sint16* l, sint16* h, int subband_width) +{ + int y; + int n; + int first; + __m128i src_2n; + __m128i src_2n_1; + __m128i src_2n_2; + __m128i h_n; + __m128i h_n_m; + __m128i l_n; + + for (y = 0; y < subband_width; y++) + { + for (n = 0; n < subband_width; n += 8) + { + /* The following 3 Set operations consumes more than half of the total DWT processing time! */ + src_2n = _mm_set_epi16(src[14], src[12], src[10], src[8], src[6], src[4], src[2], src[0]); + src_2n_1 = _mm_set_epi16(src[15], src[13], src[11], src[9], src[7], src[5], src[3], src[1]); + src_2n_2 = _mm_set_epi16(n == subband_width - 8 ? src[14] : src[16], + src[14], src[12], src[10], src[8], src[6], src[4], src[2]); + + /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */ + + h_n = _mm_add_epi16(src_2n, src_2n_2); + h_n = _mm_srai_epi16(h_n, 1); + h_n = _mm_sub_epi16(src_2n_1, h_n); + h_n = _mm_srai_epi16(h_n, 1); + + _mm_store_si128((__m128i*) h, h_n); + + h_n_m = _mm_loadu_si128((__m128i*) (h - 1)); + if (n == 0) + { + first = _mm_extract_epi16(h_n_m, 1); + h_n_m = _mm_insert_epi16(h_n_m, first, 0); + } + + /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */ + + l_n = _mm_add_epi16(h_n_m, h_n); + l_n = _mm_srai_epi16(l_n, 1); + l_n = _mm_add_epi16(l_n, src_2n); + + _mm_store_si128((__m128i*) l, l_n); + + src += 16; + l += 8; + h += 8; + } + } +} + +static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +rfx_dwt_2d_encode_block_sse2(sint16* buffer, sint16* dwt, int subband_width) +{ + sint16 *hl, *lh, *hh, *ll; + sint16 *l_src, *h_src; + + _mm_prefetch_buffer((char*) dwt, subband_width * 4 * sizeof(sint16)); + + /* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */ + + l_src = dwt; + h_src = dwt + subband_width * subband_width * 2; + + rfx_dwt_2d_encode_block_vert_sse2(buffer, l_src, h_src, subband_width); + + /* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order, stored in original buffer. */ + /* The lower part L generates LL(3) and HL(0). */ + /* The higher part H generates LH(1) and HH(2). */ + + ll = buffer + subband_width * subband_width * 3; + hl = buffer; + + lh = buffer + subband_width * subband_width; + hh = buffer + subband_width * subband_width * 2; + + rfx_dwt_2d_encode_block_horiz_sse2(l_src, ll, hl, subband_width); + rfx_dwt_2d_encode_block_horiz_sse2(h_src, lh, hh, subband_width); +} + +static void rfx_dwt_2d_encode_sse2(sint16* buffer, sint16* dwt_buffer) +{ + _mm_prefetch_buffer((char*) buffer, 4096 * sizeof(sint16)); + + rfx_dwt_2d_encode_block_sse2(buffer, dwt_buffer, 32); + rfx_dwt_2d_encode_block_sse2(buffer + 3072, dwt_buffer, 16); + rfx_dwt_2d_encode_block_sse2(buffer + 3840, dwt_buffer, 8); +} + +void rfx_init_sse2(RFX_CONTEXT* context) +{ + DEBUG_RFX("Using SSE2 optimizations"); + + IF_PROFILER(context->priv->prof_rfx_decode_ycbcr_to_rgb->name = "rfx_decode_ycbcr_to_rgb_sse2"); + IF_PROFILER(context->priv->prof_rfx_encode_rgb_to_ycbcr->name = "rfx_encode_rgb_to_ycbcr_sse2"); + IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2"); + IF_PROFILER(context->priv->prof_rfx_quantization_encode->name = "rfx_quantization_encode_sse2"); + IF_PROFILER(context->priv->prof_rfx_dwt_2d_decode->name = "rfx_dwt_2d_decode_sse2"); + IF_PROFILER(context->priv->prof_rfx_dwt_2d_encode->name = "rfx_dwt_2d_encode_sse2"); + + context->decode_ycbcr_to_rgb = rfx_decode_ycbcr_to_rgb_sse2; + context->encode_rgb_to_ycbcr = rfx_encode_rgb_to_ycbcr_sse2; + context->quantization_decode = rfx_quantization_decode_sse2; + context->quantization_encode = rfx_quantization_encode_sse2; + context->dwt_2d_decode = rfx_dwt_2d_decode_sse2; + context->dwt_2d_encode = rfx_dwt_2d_encode_sse2; +} diff --git a/libfreerdp-codec/rfx_sse2.h b/libfreerdp-codec/rfx_sse2.h new file mode 100644 index 0000000..b9a9a2a --- /dev/null +++ b/libfreerdp-codec/rfx_sse2.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library - SSE2 Optimizations + * + * Copyright 2011 Stephen Erisman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_SSE2_H +#define __RFX_SSE2_H + +#include + +void rfx_init_sse2(RFX_CONTEXT* context); + +#ifndef RFX_INIT_SIMD +#define RFX_INIT_SIMD(_rfx_context) rfx_init_sse2(_rfx_context) +#endif + +#endif /* __RFX_SSE2_H */ diff --git a/libfreerdp-codec/rfx_types.h b/libfreerdp-codec/rfx_types.h new file mode 100644 index 0000000..a18034e --- /dev/null +++ b/libfreerdp-codec/rfx_types.h @@ -0,0 +1,73 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RemoteFX Codec Library + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RFX_TYPES_H +#define __RFX_TYPES_H + +#include "config.h" +#include +#include + +#ifdef WITH_DEBUG_RFX +#define DEBUG_RFX(fmt, ...) DEBUG_CLASS(RFX, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RFX(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#include "rfx_pool.h" + +struct _RFX_CONTEXT_PRIV +{ + /* pre-allocated buffers */ + + RFX_POOL* pool; /* memory pool */ + + sint16 y_r_mem[4096 + 8]; /* 4096 = 64x64 (+ 8x2 = 16 for mem align) */ + sint16 cb_g_mem[4096 + 8]; /* 4096 = 64x64 (+ 8x2 = 16 for mem align) */ + sint16 cr_b_mem[4096 + 8]; /* 4096 = 64x64 (+ 8x2 = 16 for mem align) */ + + sint16* y_r_buffer; + sint16* cb_g_buffer; + sint16* cr_b_buffer; + + sint16 dwt_mem[32 * 32 * 2 * 2 + 8]; /* maximum sub-band width is 32 */ + + sint16* dwt_buffer; + + /* profilers */ + PROFILER_DEFINE(prof_rfx_decode_rgb); + PROFILER_DEFINE(prof_rfx_decode_component); + PROFILER_DEFINE(prof_rfx_rlgr_decode); + PROFILER_DEFINE(prof_rfx_differential_decode); + PROFILER_DEFINE(prof_rfx_quantization_decode); + PROFILER_DEFINE(prof_rfx_dwt_2d_decode); + PROFILER_DEFINE(prof_rfx_decode_ycbcr_to_rgb); + PROFILER_DEFINE(prof_rfx_decode_format_rgb); + + PROFILER_DEFINE(prof_rfx_encode_rgb); + PROFILER_DEFINE(prof_rfx_encode_component); + PROFILER_DEFINE(prof_rfx_rlgr_encode); + PROFILER_DEFINE(prof_rfx_differential_encode); + PROFILER_DEFINE(prof_rfx_quantization_encode); + PROFILER_DEFINE(prof_rfx_dwt_2d_encode); + PROFILER_DEFINE(prof_rfx_encode_rgb_to_ycbcr); + PROFILER_DEFINE(prof_rfx_encode_format_rgb); +}; + +#endif /* __RFX_TYPES_H */ diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt new file mode 100644 index 0000000..939a9cf --- /dev/null +++ b/libfreerdp-core/CMakeLists.txt @@ -0,0 +1,111 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-core cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_definitions(-DEXT_PATH="/usr/lib/freerdp/extensions") +include_directories(${OPENSSL_INCLUDE_DIR}) +include_directories(${ZLIB_INCLUDE_DIRS}) + +set(LIBFREERDP_CORE_SRCS + activation.c + activation.h + extension.c + extension.h + ber.c + ber.h + gcc.c + gcc.h + mcs.c + mcs.h + nego.c + nego.h + info.c + info.h + input.c + input.h + crypto.c + crypto.h + credssp.c + credssp.h + ntlmssp.c + ntlmssp.h + license.c + license.h + errinfo.c + errinfo.h + security.c + security.h + settings.c + orders.c + orders.h + freerdp.c + graphics.c + capabilities.c + capabilities.h + certificate.c + certificate.h + connection.c + connection.h + redirection.c + redirection.h + rdp.c + rdp.h + per.c + per.h + tcp.c + tcp.h + tls.c + tls.h + tpdu.c + tpdu.h + tpkt.c + tpkt.h + fastpath.c + fastpath.h + surface.c + surface.h + transport.c + transport.h + update.c + update.h + channel.c + channel.h + window.c + window.h + listener.c + listener.h + peer.c + peer.h + mppc.c +) + +add_library(freerdp-core ${LIBFREERDP_CORE_SRCS}) + +set_target_properties(freerdp-core PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +if(WIN32) + target_link_libraries(freerdp-core ws2_32) +else() + target_link_libraries(freerdp-core ${ZLIB_LIBRARIES}) +endif() + +target_link_libraries(freerdp-core ${OPENSSL_LIBRARIES}) +target_link_libraries(freerdp-core freerdp-utils) +target_link_libraries(freerdp-core freerdp-codec) + +install(TARGETS freerdp-core DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-core/activation.c b/libfreerdp-core/activation.c new file mode 100644 index 0000000..f93e75d --- /dev/null +++ b/libfreerdp-core/activation.c @@ -0,0 +1,340 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Activation Sequence + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "activation.h" + +/* +static const char* const CTRLACTION_STRINGS[] = +{ + "", + "CTRLACTION_REQUEST_CONTROL", + "CTRLACTION_GRANTED_CONTROL", + "CTRLACTION_DETACH", + "CTRLACTION_COOPERATE" +}; +*/ + +void rdp_write_synchronize_pdu(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */ + stream_write_uint16(s, settings->pdu_source); /* targetUser (2 bytes) */ +} + +boolean rdp_recv_synchronize_pdu(rdpRdp* rdp, STREAM* s) +{ + if (rdp->settings->server_mode) + return rdp_recv_server_synchronize_pdu(rdp, s); + else + return rdp_recv_client_synchronize_pdu(rdp, s); +} + +boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s) +{ + rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU; + return true; +} + +boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + + rdp_write_synchronize_pdu(s, rdp->settings); + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id); + + return true; +} + +boolean rdp_recv_client_synchronize_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 messageType; + + rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU; + + if (stream_get_left(s) < 4) + return false; + + stream_read_uint16(s, messageType); /* messageType (2 bytes) */ + + if (messageType != SYNCMSGTYPE_SYNC) + return false; + + /* targetUser (2 bytes) */ + stream_seek_uint16(s); + + return true; +} + +boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + + rdp_write_synchronize_pdu(s, rdp->settings); + + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id); +} + +boolean rdp_recv_control_pdu(STREAM* s, uint16* action) +{ + if (stream_get_left(s) < 8) + return false; + + stream_read_uint16(s, *action); /* action (2 bytes) */ + stream_seek_uint16(s); /* grantId (2 bytes) */ + stream_seek_uint32(s); /* controlId (4 bytes) */ + + return true; +} + +void rdp_write_client_control_pdu(STREAM* s, uint16 action) +{ + stream_write_uint16(s, action); /* action (2 bytes) */ + stream_write_uint16(s, 0); /* grantId (2 bytes) */ + stream_write_uint32(s, 0); /* controlId (4 bytes) */ +} + +boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 action; + + rdp_recv_control_pdu(s, &action); + + switch (action) + { + case CTRLACTION_COOPERATE: + rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU; + break; + + case CTRLACTION_GRANTED_CONTROL: + rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU; + break; + } + + return true; +} + +boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + + stream_write_uint16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */ + stream_write_uint16(s, 0); /* grantId (2 bytes) */ + stream_write_uint32(s, 0); /* controlId (4 bytes) */ + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); + + return true; +} + +boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + + stream_write_uint16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */ + stream_write_uint16(s, rdp->mcs->user_id); /* grantId (2 bytes) */ + stream_write_uint32(s, 0x03EA); /* controlId (4 bytes) */ + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); + + return true; +} + +boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + rdp_write_client_control_pdu(s, action); + + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); +} + +void rdp_write_persistent_list_entry(STREAM* s, uint32 key1, uint32 key2) +{ + stream_write_uint32(s, key1); /* key1 (4 bytes) */ + stream_write_uint32(s, key2); /* key2 (4 bytes) */ +} + +void rdp_write_client_persistent_key_list_pdu(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 0); /* numEntriesCache0 (2 bytes) */ + stream_write_uint16(s, 0); /* numEntriesCache1 (2 bytes) */ + stream_write_uint16(s, 0); /* numEntriesCache2 (2 bytes) */ + stream_write_uint16(s, 0); /* numEntriesCache3 (2 bytes) */ + stream_write_uint16(s, 0); /* numEntriesCache4 (2 bytes) */ + stream_write_uint16(s, 0); /* totalEntriesCache0 (2 bytes) */ + stream_write_uint16(s, 0); /* totalEntriesCache1 (2 bytes) */ + stream_write_uint16(s, 0); /* totalEntriesCache2 (2 bytes) */ + stream_write_uint16(s, 0); /* totalEntriesCache3 (2 bytes) */ + stream_write_uint16(s, 0); /* totalEntriesCache4 (2 bytes) */ + stream_write_uint8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */ + stream_write_uint8(s, 0); /* pad1 (1 byte) */ + stream_write_uint16(s, 0); /* pad3 (2 bytes) */ + + /* entries */ +} + +boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + rdp_write_client_persistent_key_list_pdu(s, rdp->settings); + + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id); +} + +boolean rdp_recv_client_font_list_pdu(STREAM* s) +{ + if (stream_get_left(s) < 8) + return false; + + return true; +} + +void rdp_write_client_font_list_pdu(STREAM* s, uint16 flags) +{ + stream_write_uint16(s, 0); /* numberFonts (2 bytes) */ + stream_write_uint16(s, 0); /* totalNumFonts (2 bytes) */ + stream_write_uint16(s, flags); /* listFlags (2 bytes) */ + stream_write_uint16(s, 50); /* entrySize (2 bytes) */ +} + +boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + rdp_write_client_font_list_pdu(s, flags); + + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id); +} + +boolean rdp_recv_font_map_pdu(rdpRdp* rdp, STREAM* s) +{ + if (rdp->settings->server_mode) + return rdp_recv_server_font_map_pdu(rdp, s); + else + return rdp_recv_client_font_map_pdu(rdp, s); +} + +boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s) +{ + rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU; + return true; +} + +boolean rdp_recv_client_font_map_pdu(rdpRdp* rdp, STREAM* s) +{ + rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU; + + stream_seek_uint16(s); /* numberEntries (2 bytes) */ + stream_seek_uint16(s); /* totalNumEntries (2 bytes) */ + stream_seek_uint16(s); /* mapFlags (2 bytes) */ + stream_seek_uint16(s); /* entrySize (2 bytes) */ + + return true; +} + +boolean rdp_send_server_font_map_pdu(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_data_pdu_init(rdp); + + stream_write_uint16(s, 0); /* numberEntries (2 bytes) */ + stream_write_uint16(s, 0); /* totalNumEntries (2 bytes) */ + stream_write_uint16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */ + stream_write_uint16(s, 4); /* entrySize (2 bytes) */ + + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->user_id); +} + +boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) +{ + uint16 lengthSourceDescriptor; + + /* + * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain + * the following fields. + */ + if (stream_get_left(s) > 0) + { + stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ + stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ + } + + rdp->state = CONNECTION_STATE_CAPABILITY; + + while (rdp->state != CONNECTION_STATE_ACTIVE) + { + if (rdp_check_fds(rdp) < 0) + return false; + if (rdp->disconnect) + break; + } + + return true; +} + +boolean rdp_send_deactivate_all(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_pdu_init(rdp); + + stream_write_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ + stream_write_uint16(s, 1); /* lengthSourceDescriptor (2 bytes) */ + stream_write_uint8(s, 0); /* sourceDescriptor (should be 0x00) */ + + return rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->user_id); +} + +boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 action; + + if (!rdp_recv_control_pdu(s, &action)) + return false; + if (action == CTRLACTION_REQUEST_CONTROL) + { + if (!rdp_send_server_control_granted_pdu(rdp)) + return false; + } + return true; +} + +boolean rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, STREAM* s) +{ + if (!rdp_recv_client_font_list_pdu(s)) + return false; + if (!rdp_send_server_font_map_pdu(rdp)) + return false; + + return true; +} + diff --git a/libfreerdp-core/activation.h b/libfreerdp-core/activation.h new file mode 100644 index 0000000..2589171 --- /dev/null +++ b/libfreerdp-core/activation.h @@ -0,0 +1,65 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Activation Sequence + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ACTIVATION_H +#define __ACTIVATION_H + +#include "rdp.h" + +#include +#include + +#define SYNCMSGTYPE_SYNC 0x0001 + +#define CTRLACTION_REQUEST_CONTROL 0x0001 +#define CTRLACTION_GRANTED_CONTROL 0x0002 +#define CTRLACTION_DETACH 0x0003 +#define CTRLACTION_COOPERATE 0x0004 + +#define PERSIST_FIRST_PDU 0x01 +#define PERSIST_LAST_PDU 0x02 + +#define FONTLIST_FIRST 0x0001 +#define FONTLIST_LAST 0x0002 + +boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s); +boolean rdp_send_deactivate_all(rdpRdp* rdp); + +boolean rdp_recv_synchronize_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp); +boolean rdp_recv_client_synchronize_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp); +boolean rdp_recv_control_pdu(STREAM* s, uint16* action); +boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp); +boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp); +boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action); +boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp); +boolean rdp_recv_client_font_list_pdu(STREAM* s); +boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags); +boolean rdp_recv_font_map_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_recv_client_font_map_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_send_server_font_map_pdu(rdpRdp* rdp); + +boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, STREAM* s); + +#endif /* __ACTIVATION_H */ diff --git a/libfreerdp-core/ber.c b/libfreerdp-core/ber.c new file mode 100644 index 0000000..86b69f5 --- /dev/null +++ b/libfreerdp-core/ber.c @@ -0,0 +1,432 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * ASN.1 Basic Encoding Rules (BER) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ber.h" + +void ber_read_length(STREAM* s, int* length) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x80) + { + byte &= ~(0x80); + + if (byte == 1) + stream_read_uint8(s, *length); + if (byte == 2) + stream_read_uint16_be(s, *length); + } + else + { + *length = byte; + } +} + +/** + * Write BER length. + * @param s stream + * @param length length + */ + +int ber_write_length(STREAM* s, int length) +{ + if (length > 0x7F) + { + stream_write_uint8(s, 0x82); + stream_write_uint16_be(s, length); + return 3; + } + else + { + stream_write_uint8(s, length); + return 1; + } +} + +int _ber_skip_length(int length) +{ + if (length > 0x7F) + return 3; + else + return 1; +} + +int ber_get_content_length(int length) +{ + if (length - 1 > 0x7F) + return length - 4; + else + return length - 2; +} + +/** + * Read BER Universal tag. + * @param s stream + * @param tag BER universally-defined tag + * @return + */ + +boolean ber_read_universal_tag(STREAM* s, uint8 tag, boolean pc) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte != (BER_CLASS_UNIV | BER_PC(pc) | (BER_TAG_MASK & tag))) + return false; + + return true; +} + +/** + * Write BER Universal tag. + * @param s stream + * @param tag BER universally-defined tag + * @param pc primitive (false) or constructed (true) + */ + +void ber_write_universal_tag(STREAM* s, uint8 tag, boolean pc) +{ + stream_write_uint8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); +} + +/** + * Read BER Application tag. + * @param s stream + * @param tag BER application-defined tag + * @param length length + */ + +boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length) +{ + uint8 byte; + + if (tag > 30) + { + stream_read_uint8(s, byte); + + if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) + return false; + + stream_read_uint8(s, byte); + + if (byte != tag) + return false; + + ber_read_length(s, length); + } + else + { + stream_read_uint8(s, byte); + + if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag))) + return false; + + ber_read_length(s, length); + } + + return true; +} + +/** + * Write BER Application tag. + * @param s stream + * @param tag BER application-defined tag + * @param length length + */ + +void ber_write_application_tag(STREAM* s, uint8 tag, int length) +{ + if (tag > 30) + { + stream_write_uint8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK); + stream_write_uint8(s, tag); + ber_write_length(s, length); + } + else + { + stream_write_uint8(s, (BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)); + ber_write_length(s, length); + } +} + +boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte != ((BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag))) + { + stream_rewind(s, 1); + return false; + } + + ber_read_length(s, length); + + return true; +} + +int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc) +{ + stream_write_uint8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); + return ber_write_length(s, length) + 1; +} + +int ber_skip_contextual_tag(int length) +{ + return _ber_skip_length(length) + 1; +} + +boolean ber_read_sequence_tag(STREAM* s, int* length) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte != ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF))) + return false; + + ber_read_length(s, length); + + return true; +} + +/** + * Write BER SEQUENCE tag. + * @param s stream + * @param length length + */ + +int ber_write_sequence_tag(STREAM* s, int length) +{ + stream_write_uint8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); + return ber_write_length(s, length) + 1; +} + +int ber_skip_sequence(int length) +{ + return 1 + _ber_skip_length(length) + length; +} + +int ber_skip_sequence_tag(int length) +{ + return 1 + _ber_skip_length(length); +} + +boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count) +{ + int length; + + ber_read_universal_tag(s, BER_TAG_ENUMERATED, false); + ber_read_length(s, &length); + + if (length == 1) + stream_read_uint8(s, *enumerated); + else + return false; + + /* check that enumerated value falls within expected range */ + if (*enumerated + 1 > count) + return false; + + return true; +} + +void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count) +{ + ber_write_universal_tag(s, BER_TAG_ENUMERATED, false); + ber_write_length(s, 1); + stream_write_uint8(s, enumerated); +} + +boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding) +{ + ber_read_universal_tag(s, BER_TAG_BIT_STRING, false); + ber_read_length(s, length); + stream_read_uint8(s, *padding); + + return true; +} + +boolean ber_read_octet_string(STREAM* s, int* length) +{ + ber_read_universal_tag(s, BER_TAG_OCTET_STRING, false); + ber_read_length(s, length); + + return true; +} + +/** + * Write a BER OCTET_STRING + * @param s stream + * @param oct_str octet string + * @param length string length + */ + +void ber_write_octet_string(STREAM* s, const uint8* oct_str, int length) +{ + ber_write_universal_tag(s, BER_TAG_OCTET_STRING, false); + ber_write_length(s, length); + stream_write(s, oct_str, length); +} + +int ber_write_octet_string_tag(STREAM* s, int length) +{ + ber_write_universal_tag(s, BER_TAG_OCTET_STRING, false); + ber_write_length(s, length); + return 1 + _ber_skip_length(length); +} + +int ber_skip_octet_string(int length) +{ + return 1 + _ber_skip_length(length) + length; +} + +/** + * Read a BER BOOLEAN + * @param s + * @param value + */ + +boolean ber_read_boolean(STREAM* s, boolean* value) +{ + int length; + uint8 v; + + if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, false)) + return false; + ber_read_length(s, &length); + if (length != 1) + return false; + stream_read_uint8(s, v); + *value = (v ? true : false); + return true; +} + +/** + * Write a BER BOOLEAN + * @param s + * @param value + */ + +void ber_write_boolean(STREAM* s, boolean value) +{ + ber_write_universal_tag(s, BER_TAG_BOOLEAN, false); + ber_write_length(s, 1); + stream_write_uint8(s, (value == true) ? 0xFF : 0); +} + +boolean ber_read_integer(STREAM* s, uint32* value) +{ + int length; + + ber_read_universal_tag(s, BER_TAG_INTEGER, false); + ber_read_length(s, &length); + + if (value == NULL) + { + stream_seek(s, length); + return true; + } + + if (length == 1) + stream_read_uint8(s, *value); + else if (length == 2) + stream_read_uint16_be(s, *value); + else if (length == 3) + { + uint8 byte; + stream_read_uint8(s, byte); + stream_read_uint16_be(s, *value); + *value += (byte << 16); + } + else if (length == 4) + stream_read_uint32_be(s, *value); + else + return false; + + return true; +} + +/** + * Write a BER INTEGER + * @param s + * @param value + */ + +int ber_write_integer(STREAM* s, uint32 value) +{ + ber_write_universal_tag(s, BER_TAG_INTEGER, false); + + if (value <= 0xFF) + { + ber_write_length(s, 1); + stream_write_uint8(s, value); + return 2; + } + else if (value < 0xFF80) + { + ber_write_length(s, 2); + stream_write_uint16_be(s, value); + return 3; + } + else if (value < 0xFF8000) + { + ber_write_length(s, 3); + stream_write_uint8(s, (value >> 16)); + stream_write_uint16_be(s, (value & 0xFFFF)); + return 4; + } + else if (value <= 0xFFFFFFFF) + { + ber_write_length(s, 4); + stream_write_uint32_be(s, value); + return 5; + } + + return 0; +} + +int ber_skip_integer(uint32 value) +{ + if (value <= 0xFF) + { + return _ber_skip_length(1) + 2; + } + else if (value <= 0xFFFF) + { + return _ber_skip_length(2) + 3; + } + else if (value <= 0xFFFFFFFF) + { + return _ber_skip_length(4) + 5; + } + + return 0; +} + +boolean ber_read_integer_length(STREAM* s, int* length) +{ + ber_read_universal_tag(s, BER_TAG_INTEGER, false); + ber_read_length(s, length); + return true; +} diff --git a/libfreerdp-core/ber.h b/libfreerdp-core/ber.h new file mode 100644 index 0000000..5b2e1e9 --- /dev/null +++ b/libfreerdp-core/ber.h @@ -0,0 +1,83 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * ASN.1 Basic Encoding Rules (BER) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __BER_H +#define __BER_H + +#include +#include + +/* BER type */ + +/* Class - bits 8 and 7 */ +#define BER_CLASS_MASK 0xC0 +#define BER_CLASS_UNIV 0x00 /* 0 0 */ +#define BER_CLASS_APPL 0x40 /* 0 1 */ +#define BER_CLASS_CTXT 0x80 /* 1 0 */ +#define BER_CLASS_PRIV 0xC0 /* 1 1 */ + +/* P/C - bit 6 */ +#define BER_PC_MASK 0x20 +#define BER_PRIMITIVE 0x00 /* 0 */ +#define BER_CONSTRUCT 0x20 /* 1 */ + +/* Tag - bits 5 to 1 */ +#define BER_TAG_MASK 0x1F +#define BER_TAG_BOOLEAN 0x01 +#define BER_TAG_INTEGER 0x02 +#define BER_TAG_BIT_STRING 0x03 +#define BER_TAG_OCTET_STRING 0x04 +#define BER_TAG_OBJECT_IDENFIER 0x06 +#define BER_TAG_ENUMERATED 0x0A +#define BER_TAG_SEQUENCE 0x10 +#define BER_TAG_SEQUENCE_OF 0x10 + +#define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE) + +void ber_read_length(STREAM* s, int* length); +int ber_write_length(STREAM* s, int length); +int _ber_skip_length(int length); +int ber_get_content_length(int length); +boolean ber_read_universal_tag(STREAM* s, uint8 tag, boolean pc); +void ber_write_universal_tag(STREAM* s, uint8 tag, boolean pc); +boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length); +void ber_write_application_tag(STREAM* s, uint8 tag, int length); +boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length); +boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count); +void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count); +boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc); +int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc); +int ber_skip_contextual_tag(int length); +boolean ber_read_sequence_tag(STREAM* s, int* length); +int ber_write_sequence_tag(STREAM* s, int length); +int ber_skip_sequence(int length); +int ber_skip_sequence_tag(int length); +boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding); +boolean ber_read_octet_string(STREAM* s, int* length); +void ber_write_octet_string(STREAM* s, const uint8* oct_str, int length); +int ber_write_octet_string_tag(STREAM* s, int length); +int ber_skip_octet_string(int length); +boolean ber_read_boolean(STREAM* s, boolean* value); +void ber_write_boolean(STREAM* s, boolean value); +boolean ber_read_integer(STREAM* s, uint32* value); +int ber_write_integer(STREAM* s, uint32 value); +boolean ber_read_integer_length(STREAM* s, int* length); +int ber_skip_integer(uint32 value); + +#endif /* __BER_H */ diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c new file mode 100644 index 0000000..6db2411 --- /dev/null +++ b/libfreerdp-core/capabilities.c @@ -0,0 +1,2086 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Capability Sets + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "capabilities.h" + +/* +static const char* const CAPSET_TYPE_STRINGS[] = +{ + "Unknown", + "General", + "Bitmap", + "Order", + "Bitmap Cache", + "Control", + "Unknown", + "Window Activation", + "Pointer", + "Share", + "Color Cache", + "Unknown", + "Sound", + "Input", + "Font", + "Brush", + "Glyph Cache", + "Offscreen Bitmap Cache", + "Bitmap Cache Host Support", + "Bitmap Cache v2", + "Virtual Channel", + "DrawNineGrid Cache", + "Draw GDI+ Cache", + "Remote Programs", + "Window List", + "Desktop Composition", + "Multifragment Update", + "Large Pointer", + "Surface Commands", + "Bitmap Codecs", + "Frame Acknowledge" +}; +*/ + +/* CODEC_GUID_REMOTEFX 0x76772F12BD724463AFB3B73C9C6F7886 */ +#define CODEC_GUID_REMOTEFX "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86" + +/* CODEC_GUID_NSCODEC 0xCA8D1BB9000F154F589FAE2D1A87E2D6 */ +#define CODEC_GUID_NSCODEC "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6" + +void rdp_read_capability_set_header(STREAM* s, uint16* length, uint16* type) +{ + stream_read_uint16(s, *type); /* capabilitySetType */ + stream_read_uint16(s, *length); /* lengthCapability */ +} + +void rdp_write_capability_set_header(STREAM* s, uint16 length, uint16 type) +{ + stream_write_uint16(s, type); /* capabilitySetType */ + stream_write_uint16(s, length); /* lengthCapability */ +} + +uint8* rdp_capability_set_start(STREAM* s) +{ + uint8* header; + + stream_get_mark(s, header); + stream_write_zero(s, CAPSET_HEADER_LENGTH); + + return header; +} + +void rdp_capability_set_finish(STREAM* s, uint8* header, uint16 type) +{ + uint16 length; + uint8* footer; + + footer = s->p; + length = footer - header; + stream_set_mark(s, header); + + rdp_write_capability_set_header(s, length, type); + stream_set_mark(s, footer); +} + +/** + * Read general capability set.\n + * @msdn{cc240549} + * @param s stream + * @param settings settings + */ + +void rdp_read_general_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint16 extraFlags; + uint8 refreshRectSupport; + uint8 suppressOutputSupport; + + if (settings->server_mode) + { + stream_read_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */ + stream_read_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */ + } + else + { + stream_seek_uint16(s); /* osMajorType (2 bytes) */ + stream_seek_uint16(s); /* osMinorType (2 bytes) */ + } + stream_seek_uint16(s); /* protocolVersion (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */ + stream_seek_uint16(s); /* generalCompressionTypes (2 bytes) */ + stream_read_uint16(s, extraFlags); /* extraFlags (2 bytes) */ + stream_seek_uint16(s); /* updateCapabilityFlag (2 bytes) */ + stream_seek_uint16(s); /* remoteUnshareFlag (2 bytes) */ + stream_seek_uint16(s); /* generalCompressionLevel (2 bytes) */ + stream_read_uint8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */ + stream_read_uint8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */ + + if (!(extraFlags & FASTPATH_OUTPUT_SUPPORTED)) + settings->fastpath_output = false; + + if (refreshRectSupport == false) + settings->refresh_rect = false; + + if (suppressOutputSupport == false) + settings->suppress_output = false; +} + +/** + * Write general capability set.\n + * @msdn{cc240549} + * @param s stream + * @param settings settings + */ + +void rdp_write_general_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 extraFlags; + + header = rdp_capability_set_start(s); + + extraFlags = LONG_CREDENTIALS_SUPPORTED | NO_BITMAP_COMPRESSION_HDR; + + if (settings->auto_reconnection) + extraFlags |= AUTORECONNECT_SUPPORTED; + + if (settings->fastpath_output) + extraFlags |= FASTPATH_OUTPUT_SUPPORTED; + + if (settings->server_mode) + { + /* not yet supported server-side */ + settings->refresh_rect = false; + settings->suppress_output = false; + } + + stream_write_uint16(s, settings->os_major_type); /* osMajorType (2 bytes) */ + stream_write_uint16(s, settings->os_minor_type); /* osMinorType (2 bytes) */ + stream_write_uint16(s, CAPS_PROTOCOL_VERSION); /* protocolVersion (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ + stream_write_uint16(s, 0); /* generalCompressionTypes (2 bytes) */ + stream_write_uint16(s, extraFlags); /* extraFlags (2 bytes) */ + stream_write_uint16(s, 0); /* updateCapabilityFlag (2 bytes) */ + stream_write_uint16(s, 0); /* remoteUnshareFlag (2 bytes) */ + stream_write_uint16(s, 0); /* generalCompressionLevel (2 bytes) */ + stream_write_uint8(s, settings->refresh_rect); /* refreshRectSupport (1 byte) */ + stream_write_uint8(s, settings->suppress_output); /* suppressOutputSupport (1 byte) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL); +} + +/** + * Read bitmap capability set.\n + * @msdn{cc240554} + * @param s stream + * @param settings settings + */ + +void rdp_read_bitmap_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint8 drawingFlags; + uint16 desktopWidth; + uint16 desktopHeight; + uint16 desktopResizeFlag; + uint16 preferredBitsPerPixel; + + stream_read_uint16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + stream_seek_uint16(s); /* receive1BitPerPixel (2 bytes) */ + stream_seek_uint16(s); /* receive4BitsPerPixel (2 bytes) */ + stream_seek_uint16(s); /* receive8BitsPerPixel (2 bytes) */ + stream_read_uint16(s, desktopWidth); /* desktopWidth (2 bytes) */ + stream_read_uint16(s, desktopHeight); /* desktopHeight (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + stream_read_uint16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + stream_seek_uint16(s); /* bitmapCompressionFlag (2 bytes) */ + stream_seek_uint8(s); /* highColorFlags (1 byte) */ + stream_read_uint8(s, drawingFlags); /* drawingFlags (1 byte) */ + stream_seek_uint16(s); /* multipleRectangleSupport (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */ + + if (!settings->server_mode && preferredBitsPerPixel != settings->color_depth) + { + /* The client must respect the actual color depth used by the server */ + settings->color_depth = preferredBitsPerPixel; + } + + if (desktopResizeFlag == false) + settings->desktop_resize = false; + + if (!settings->server_mode && settings->desktop_resize) + { + /* The server may request a different desktop size during Deactivation-Reactivation sequence */ + settings->width = desktopWidth; + settings->height = desktopHeight; + } +} + +/** + * Write bitmap capability set.\n + * @msdn{cc240554} + * @param s stream + * @param settings settings + */ + +void rdp_write_bitmap_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint8 drawingFlags; + uint16 desktopResizeFlag; + uint16 preferredBitsPerPixel; + + header = rdp_capability_set_start(s); + + drawingFlags = 0; + + if (settings->rdp_version > 5) + preferredBitsPerPixel = settings->color_depth; + else + preferredBitsPerPixel = 8; + + desktopResizeFlag = settings->desktop_resize; + + stream_write_uint16(s, preferredBitsPerPixel); /* preferredBitsPerPixel (2 bytes) */ + stream_write_uint16(s, 1); /* receive1BitPerPixel (2 bytes) */ + stream_write_uint16(s, 1); /* receive4BitsPerPixel (2 bytes) */ + stream_write_uint16(s, 1); /* receive8BitsPerPixel (2 bytes) */ + stream_write_uint16(s, settings->width); /* desktopWidth (2 bytes) */ + stream_write_uint16(s, settings->height); /* desktopHeight (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + stream_write_uint16(s, desktopResizeFlag); /* desktopResizeFlag (2 bytes) */ + stream_write_uint16(s, 1); /* bitmapCompressionFlag (2 bytes) */ + stream_write_uint8(s, 0); /* highColorFlags (1 byte) */ + stream_write_uint8(s, drawingFlags); /* drawingFlags (1 byte) */ + stream_write_uint16(s, 1); /* multipleRectangleSupport (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsB (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP); +} + +/** + * Read order capability set.\n + * @msdn{cc240556} + * @param s stream + * @param settings settings + */ + +void rdp_read_order_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + int i; + uint16 orderFlags; + uint8 orderSupport[32]; + uint16 orderSupportExFlags; + + stream_seek(s, 16); /* terminalDescriptor (16 bytes) */ + stream_seek_uint32(s); /* pad4OctetsA (4 bytes) */ + stream_seek_uint16(s); /* desktopSaveXGranularity (2 bytes) */ + stream_seek_uint16(s); /* desktopSaveYGranularity (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */ + stream_seek_uint16(s); /* maximumOrderLevel (2 bytes) */ + stream_seek_uint16(s); /* numberFonts (2 bytes) */ + stream_read_uint16(s, orderFlags); /* orderFlags (2 bytes) */ + stream_read(s, orderSupport, 32); /* orderSupport (32 bytes) */ + stream_seek_uint16(s); /* textFlags (2 bytes) */ + stream_read_uint16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ + stream_seek_uint32(s); /* pad4OctetsB (4 bytes) */ + stream_seek_uint32(s); /* desktopSaveSize (4 bytes) */ + stream_seek_uint16(s); /* pad2OctetsC (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsD (2 bytes) */ + stream_seek_uint16(s); /* textANSICodePage (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsE (2 bytes) */ + + for (i = 0; i < 32; i++) + { + if (orderSupport[i] == false) + settings->order_support[i] = false; + } +} + +/** + * Write order capability set.\n + * @msdn{cc240556} + * @param s stream + * @param settings settings + */ + +void rdp_write_order_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 orderFlags; + uint16 orderSupportExFlags; + uint16 textANSICodePage; + + header = rdp_capability_set_start(s); + + /* see [MSDN-CP]: http://msdn.microsoft.com/en-us/library/dd317756 */ + textANSICodePage = 65001; /* Unicode (UTF-8) */ + + orderSupportExFlags = 0; + orderFlags = NEGOTIATE_ORDER_SUPPORT | ZERO_BOUNDS_DELTA_SUPPORT | COLOR_INDEX_SUPPORT; + + if (settings->bitmap_cache_v3) + { + orderSupportExFlags |= CACHE_BITMAP_V3_SUPPORT; + orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT; + } + + if (settings->frame_marker) + { + orderSupportExFlags |= ALTSEC_FRAME_MARKER_SUPPORT; + orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT; + } + + stream_write_zero(s, 16); /* terminalDescriptor (16 bytes) */ + stream_write_uint32(s, 0); /* pad4OctetsA (4 bytes) */ + stream_write_uint16(s, 1); /* desktopSaveXGranularity (2 bytes) */ + stream_write_uint16(s, 20); /* desktopSaveYGranularity (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ + stream_write_uint16(s, 1); /* maximumOrderLevel (2 bytes) */ + stream_write_uint16(s, 0); /* numberFonts (2 bytes) */ + stream_write_uint16(s, orderFlags); /* orderFlags (2 bytes) */ + stream_write(s, settings->order_support, 32); /* orderSupport (32 bytes) */ + stream_write_uint16(s, 0); /* textFlags (2 bytes) */ + stream_write_uint16(s, orderSupportExFlags); /* orderSupportExFlags (2 bytes) */ + stream_write_uint32(s, 0); /* pad4OctetsB (4 bytes) */ + stream_write_uint32(s, 230400); /* desktopSaveSize (4 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsC (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsD (2 bytes) */ + stream_write_uint16(s, 0); /* textANSICodePage (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsE (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER); +} + +/** + * Read bitmap cache capability set.\n + * @msdn{cc240559} + * @param s stream + * @param settings settings + */ + +void rdp_read_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint32(s); /* pad1 (4 bytes) */ + stream_seek_uint32(s); /* pad2 (4 bytes) */ + stream_seek_uint32(s); /* pad3 (4 bytes) */ + stream_seek_uint32(s); /* pad4 (4 bytes) */ + stream_seek_uint32(s); /* pad5 (4 bytes) */ + stream_seek_uint32(s); /* pad6 (4 bytes) */ + stream_seek_uint16(s); /* Cache0Entries (2 bytes) */ + stream_seek_uint16(s); /* Cache0MaximumCellSize (2 bytes) */ + stream_seek_uint16(s); /* Cache1Entries (2 bytes) */ + stream_seek_uint16(s); /* Cache1MaximumCellSize (2 bytes) */ + stream_seek_uint16(s); /* Cache2Entries (2 bytes) */ + stream_seek_uint16(s); /* Cache2MaximumCellSize (2 bytes) */ +} + +/** + * Write bitmap cache capability set.\n + * @msdn{cc240559} + * @param s stream + * @param settings settings + */ + +void rdp_write_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + int bpp; + uint16 size; + uint8* header; + + header = rdp_capability_set_start(s); + + bpp = (settings->color_depth + 7) / 8; + + stream_write_uint32(s, 0); /* pad1 (4 bytes) */ + stream_write_uint32(s, 0); /* pad2 (4 bytes) */ + stream_write_uint32(s, 0); /* pad3 (4 bytes) */ + stream_write_uint32(s, 0); /* pad4 (4 bytes) */ + stream_write_uint32(s, 0); /* pad5 (4 bytes) */ + stream_write_uint32(s, 0); /* pad6 (4 bytes) */ + + size = bpp * 256; + stream_write_uint16(s, 200); /* Cache0Entries (2 bytes) */ + stream_write_uint16(s, size); /* Cache0MaximumCellSize (2 bytes) */ + + size = bpp * 1024; + stream_write_uint16(s, 600); /* Cache1Entries (2 bytes) */ + stream_write_uint16(s, size); /* Cache1MaximumCellSize (2 bytes) */ + + size = bpp * 4096; + stream_write_uint16(s, 1000); /* Cache2Entries (2 bytes) */ + stream_write_uint16(s, size); /* Cache2MaximumCellSize (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE); +} + +/** + * Read control capability set.\n + * @msdn{cc240568} + * @param s stream + * @param settings settings + */ + +void rdp_read_control_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* controlFlags (2 bytes) */ + stream_seek_uint16(s); /* remoteDetachFlag (2 bytes) */ + stream_seek_uint16(s); /* controlInterest (2 bytes) */ + stream_seek_uint16(s); /* detachInterest (2 bytes) */ +} + +/** + * Write control capability set.\n + * @msdn{cc240568} + * @param s stream + * @param settings settings + */ + +void rdp_write_control_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint16(s, 0); /* controlFlags (2 bytes) */ + stream_write_uint16(s, 0); /* remoteDetachFlag (2 bytes) */ + stream_write_uint16(s, 2); /* controlInterest (2 bytes) */ + stream_write_uint16(s, 2); /* detachInterest (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL); +} + +/** + * Read window activation capability set.\n + * @msdn{cc240569} + * @param s stream + * @param settings settings + */ + +void rdp_read_window_activation_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* helpKeyFlag (2 bytes) */ + stream_seek_uint16(s); /* helpKeyIndexFlag (2 bytes) */ + stream_seek_uint16(s); /* helpExtendedKeyFlag (2 bytes) */ + stream_seek_uint16(s); /* windowManagerKeyFlag (2 bytes) */ +} + +/** + * Write window activation capability set.\n + * @msdn{cc240569} + * @param s stream + * @param settings settings + */ + +void rdp_write_window_activation_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint16(s, 0); /* helpKeyFlag (2 bytes) */ + stream_write_uint16(s, 0); /* helpKeyIndexFlag (2 bytes) */ + stream_write_uint16(s, 0); /* helpExtendedKeyFlag (2 bytes) */ + stream_write_uint16(s, 0); /* windowManagerKeyFlag (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION); +} + +/** + * Read pointer capability set.\n + * @msdn{cc240562} + * @param s stream + * @param settings settings + */ + +void rdp_read_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint16 colorPointerFlag; + uint16 colorPointerCacheSize; + uint16 pointerCacheSize; + + stream_read_uint16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + stream_read_uint16(s, colorPointerCacheSize); /* colorPointerCacheSize (2 bytes) */ + stream_read_uint16(s, pointerCacheSize); /* pointerCacheSize (2 bytes) */ + + if (colorPointerFlag == false) + settings->color_pointer = false; + + if (settings->server_mode) + { + settings->pointer_cache_size = pointerCacheSize; + } +} + +/** + * Write pointer capability set.\n + * @msdn{cc240562} + * @param s stream + * @param settings settings + */ + +void rdp_write_pointer_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 colorPointerFlag; + + header = rdp_capability_set_start(s); + + colorPointerFlag = (settings->color_pointer) ? 1 : 0; + + stream_write_uint16(s, colorPointerFlag); /* colorPointerFlag (2 bytes) */ + stream_write_uint16(s, settings->pointer_cache_size); /* colorPointerCacheSize (2 bytes) */ + + if (settings->large_pointer) + { + stream_write_uint16(s, settings->pointer_cache_size); /* pointerCacheSize (2 bytes) */ + } + + rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER); +} + +/** + * Read share capability set.\n + * @msdn{cc240570} + * @param s stream + * @param settings settings + */ + +void rdp_read_share_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* nodeId (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ +} + +/** + * Write share capability set.\n + * @msdn{cc240570} + * @param s stream + * @param settings settings + */ + +void rdp_write_share_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 nodeId; + + header = rdp_capability_set_start(s); + + nodeId = (settings->server_mode) ? 0x03EA : 0; + + stream_write_uint16(s, nodeId); /* nodeId (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE); +} + +/** + * Read color cache capability set.\n + * @msdn{cc241564} + * @param s stream + * @param settings settings + */ + +void rdp_read_color_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* colorTableCacheSize (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ +} + +/** + * Write color cache capability set.\n + * @msdn{cc241564} + * @param s stream + * @param settings settings + */ + +void rdp_write_color_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint16(s, 6); /* colorTableCacheSize (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE); +} + +/** + * Read sound capability set.\n + * @msdn{cc240552} + * @param s stream + * @param settings settings + */ + +void rdp_read_sound_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint16 soundFlags; + + stream_read_uint16(s, soundFlags); /* soundFlags (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */ + + settings->sound_beeps = (soundFlags & SOUND_BEEPS_FLAG) ? true : false; +} + +/** + * Write sound capability set.\n + * @msdn{cc240552} + * @param s stream + * @param settings settings + */ + +void rdp_write_sound_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 soundFlags; + + header = rdp_capability_set_start(s); + + soundFlags = (settings->sound_beeps) ? SOUND_BEEPS_FLAG : 0; + + stream_write_uint16(s, soundFlags); /* soundFlags (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND); +} + +/** + * Read input capability set.\n + * @msdn{cc240563} + * @param s stream + * @param settings settings + */ + +void rdp_read_input_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint16 inputFlags; + + stream_read_uint16(s, inputFlags); /* inputFlags (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */ + + if (settings->server_mode) + { + stream_read_uint32(s, settings->kbd_layout); /* keyboardLayout (4 bytes) */ + stream_read_uint32(s, settings->kbd_type); /* keyboardType (4 bytes) */ + stream_read_uint32(s, settings->kbd_subtype); /* keyboardSubType (4 bytes) */ + stream_read_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKeys (4 bytes) */ + } + else + { + stream_seek_uint32(s); /* keyboardLayout (4 bytes) */ + stream_seek_uint32(s); /* keyboardType (4 bytes) */ + stream_seek_uint32(s); /* keyboardSubType (4 bytes) */ + stream_seek_uint32(s); /* keyboardFunctionKeys (4 bytes) */ + } + + stream_seek(s, 64); /* imeFileName (64 bytes) */ + + if (settings->server_mode != true) + { + if (inputFlags & INPUT_FLAG_FASTPATH_INPUT) + { + /* advertised by RDP 5.0 and 5.1 servers */ + } + else if (inputFlags & INPUT_FLAG_FASTPATH_INPUT2) + { + /* avertised by RDP 5.2, 6.0, 6.1 and 7.0 servers */ + } + else + { + /* server does not support fastpath input */ + settings->fastpath_input = false; + } + } +} + +/** + * Write input capability set.\n + * @msdn{cc240563} + * @param s stream + * @param settings settings + */ + +void rdp_write_input_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 inputFlags; + + header = rdp_capability_set_start(s); + + inputFlags = INPUT_FLAG_SCANCODES | INPUT_FLAG_MOUSEX | INPUT_FLAG_UNICODE; + + if (settings->fastpath_input) + { + inputFlags |= INPUT_FLAG_FASTPATH_INPUT; + inputFlags |= INPUT_FLAG_FASTPATH_INPUT2; + } + + stream_write_uint16(s, inputFlags); /* inputFlags (2 bytes) */ + stream_write_uint16(s, 0); /* pad2OctetsA (2 bytes) */ + stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout (4 bytes) */ + stream_write_uint32(s, settings->kbd_type); /* keyboardType (4 bytes) */ + stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType (4 bytes) */ + stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKeys (4 bytes) */ + stream_write_zero(s, 64); /* imeFileName (64 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT); +} + +/** + * Read font capability set.\n + * @msdn{cc240571} + * @param s stream + * @param settings settings + */ + +void rdp_read_font_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + if (length > 4) + stream_seek_uint16(s); /* fontSupportFlags (2 bytes) */ + + if (length > 6) + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ +} + +/** + * Write font capability set.\n + * @msdn{cc240571} + * @param s stream + * @param settings settings + */ + +void rdp_write_font_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint16(s, FONTSUPPORT_FONTLIST); /* fontSupportFlags (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT); +} + +/** + * Read brush capability set.\n + * @msdn{cc240564} + * @param s stream + * @param settings settings + */ + +void rdp_read_brush_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint32(s); /* brushSupportLevel (4 bytes) */ +} + +/** + * Write brush capability set.\n + * @msdn{cc240564} + * @param s stream + * @param settings settings + */ + +void rdp_write_brush_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint32(s, BRUSH_COLOR_FULL); /* brushSupportLevel (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH); +} + +/** + * Read cache definition (glyph).\n + * @msdn{cc240566} + * @param s stream + */ +void rdp_read_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition) +{ + stream_read_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + stream_read_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ +} + +/** + * Write cache definition (glyph).\n + * @msdn{cc240566} + * @param s stream + */ +void rdp_write_cache_definition(STREAM* s, GLYPH_CACHE_DEFINITION* cache_definition) +{ + stream_write_uint16(s, cache_definition->cacheEntries); /* cacheEntries (2 bytes) */ + stream_write_uint16(s, cache_definition->cacheMaximumCellSize); /* cacheMaximumCellSize (2 bytes) */ +} + +/** + * Read glyph cache capability set.\n + * @msdn{cc240565} + * @param s stream + * @param settings settings + */ + +void rdp_read_glyph_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint16 glyphSupportLevel; + + stream_seek(s, 40); /* glyphCache (40 bytes) */ + stream_seek_uint32(s); /* fragCache (4 bytes) */ + stream_read_uint16(s, glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + + settings->glyphSupportLevel = glyphSupportLevel; +} + +/** + * Write glyph cache capability set.\n + * @msdn{cc240565} + * @param s stream + * @param settings settings + */ + +void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + /* glyphCache (40 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[0])); /* glyphCache0 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[1])); /* glyphCache1 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[2])); /* glyphCache2 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[3])); /* glyphCache3 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[4])); /* glyphCache4 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[5])); /* glyphCache5 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[6])); /* glyphCache6 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[7])); /* glyphCache7 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[8])); /* glyphCache8 (4 bytes) */ + rdp_write_cache_definition(s, &(settings->glyphCache[9])); /* glyphCache9 (4 bytes) */ + + rdp_write_cache_definition(s, settings->fragCache); /* fragCache (4 bytes) */ + + stream_write_uint16(s, settings->glyphSupportLevel); /* glyphSupportLevel (2 bytes) */ + + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE); +} + +/** + * Read offscreen bitmap cache capability set.\n + * @msdn{cc240550} + * @param s stream + * @param settings settings + */ + +void rdp_read_offscreen_bitmap_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint32 offscreenSupportLevel; + + stream_read_uint32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + stream_read_uint16(s, settings->offscreen_bitmap_cache_size); /* offscreenCacheSize (2 bytes) */ + stream_read_uint16(s, settings->offscreen_bitmap_cache_entries); /* offscreenCacheEntries (2 bytes) */ + + if (offscreenSupportLevel & true) + settings->offscreen_bitmap_cache = true; +} + +/** + * Write offscreen bitmap cache capability set.\n + * @msdn{cc240550} + * @param s stream + * @param settings settings + */ + +void rdp_write_offscreen_bitmap_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 offscreenSupportLevel = false; + + header = rdp_capability_set_start(s); + + if (settings->offscreen_bitmap_cache) + offscreenSupportLevel = true; + + stream_write_uint32(s, offscreenSupportLevel); /* offscreenSupportLevel (4 bytes) */ + stream_write_uint16(s, settings->offscreen_bitmap_cache_size); /* offscreenCacheSize (2 bytes) */ + stream_write_uint16(s, settings->offscreen_bitmap_cache_entries); /* offscreenCacheEntries (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE); +} + +/** + * Read bitmap cache host support capability set.\n + * @msdn{cc240557} + * @param s stream + * @param settings settings + */ + +void rdp_read_bitmap_cache_host_support_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint8 cacheVersion; + + stream_read_uint8(s, cacheVersion); /* cacheVersion (1 byte) */ + stream_seek_uint8(s); /* pad1 (1 byte) */ + stream_seek_uint16(s); /* pad2 (2 bytes) */ + + if (cacheVersion & BITMAP_CACHE_V2) + settings->persistent_bitmap_cache = true; +} + +/** + * Write bitmap cache host support capability set.\n + * @msdn{cc240557} + * @param s stream + * @param settings settings + */ + +void rdp_write_bitmap_cache_host_support_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint8(s, BITMAP_CACHE_V2); /* cacheVersion (1 byte) */ + stream_write_uint8(s, 0); /* pad1 (1 byte) */ + stream_write_uint16(s, 0); /* pad2 (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT); +} + +void rdp_write_bitmap_cache_cell_info(STREAM* s, BITMAP_CACHE_V2_CELL_INFO* cellInfo) +{ + uint32 info; + + /** + * numEntries is in the first 31 bits, while the last bit (k) + * is used to indicate a persistent bitmap cache. + */ + + info = (cellInfo->numEntries | (cellInfo->persistent << 31)); + stream_write_uint32(s, info); +} + +/** + * Read bitmap cache v2 capability set.\n + * @msdn{cc240560} + * @param s stream + * @param settings settings + */ + +void rdp_read_bitmap_cache_v2_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* cacheFlags (2 bytes) */ + stream_seek_uint8(s); /* pad2 (1 byte) */ + stream_seek_uint8(s); /* numCellCaches (1 byte) */ + stream_seek(s, 4); /* bitmapCache0CellInfo (4 bytes) */ + stream_seek(s, 4); /* bitmapCache1CellInfo (4 bytes) */ + stream_seek(s, 4); /* bitmapCache2CellInfo (4 bytes) */ + stream_seek(s, 4); /* bitmapCache3CellInfo (4 bytes) */ + stream_seek(s, 4); /* bitmapCache4CellInfo (4 bytes) */ + stream_seek(s, 12); /* pad3 (12 bytes) */ +} + +/** + * Write bitmap cache v2 capability set.\n + * @msdn{cc240560} + * @param s stream + * @param settings settings + */ + +void rdp_write_bitmap_cache_v2_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 cacheFlags; + + header = rdp_capability_set_start(s); + + cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG; + + if (settings->persistent_bitmap_cache) + cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG; + + stream_write_uint16(s, cacheFlags); /* cacheFlags (2 bytes) */ + stream_write_uint8(s, 0); /* pad2 (1 byte) */ + stream_write_uint8(s, settings->bitmapCacheV2NumCells); /* numCellCaches (1 byte) */ + rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[0]); /* bitmapCache0CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[1]); /* bitmapCache1CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[2]); /* bitmapCache2CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[3]); /* bitmapCache3CellInfo (4 bytes) */ + rdp_write_bitmap_cache_cell_info(s, &settings->bitmapCacheV2CellInfo[4]); /* bitmapCache4CellInfo (4 bytes) */ + stream_write_zero(s, 12); /* pad3 (12 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2); +} + +/** + * Read virtual channel capability set.\n + * @msdn{cc240551} + * @param s stream + * @param settings settings + */ + +void rdp_read_virtual_channel_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint32 flags; + uint32 VCChunkSize; + + stream_read_uint32(s, flags); /* flags (4 bytes) */ + + if (length > 8) + stream_read_uint32(s, VCChunkSize); /* VCChunkSize (4 bytes) */ + else + VCChunkSize = 1600; + + if (settings->server_mode != true) + settings->vc_chunk_size = VCChunkSize; +} + +/** + * Write virtual channel capability set.\n + * @msdn{cc240551} + * @param s stream + * @param settings settings + */ + +void rdp_write_virtual_channel_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 flags; + + header = rdp_capability_set_start(s); + + flags = (settings->server_mode) ? VCCAPS_COMPR_CS_8K : VCCAPS_NO_COMPR; + + stream_write_uint32(s, flags); /* flags (4 bytes) */ + stream_write_uint32(s, settings->vc_chunk_size); /* VCChunkSize (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL); +} + +/** + * Read drawn nine grid cache capability set.\n + * @msdn{cc241565} + * @param s stream + * @param settings settings + */ + +void rdp_read_draw_nine_grid_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint32 drawNineGridSupportLevel; + + stream_read_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + stream_read_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */ + stream_read_uint16(s, settings->draw_nine_grid_cache_entries); /* drawNineGridCacheEntries (2 bytes) */ + + if ((drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED) || + (drawNineGridSupportLevel & DRAW_NINEGRID_SUPPORTED_V2)) + settings->draw_nine_grid = true; +} + +/** + * Write drawn nine grid cache capability set.\n + * @msdn{cc241565} + * @param s stream + * @param settings settings + */ + +void rdp_write_draw_nine_grid_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 drawNineGridSupportLevel; + + header = rdp_capability_set_start(s); + + drawNineGridSupportLevel = (settings->draw_nine_grid) ? DRAW_NINEGRID_SUPPORTED : DRAW_NINEGRID_NO_SUPPORT; + + stream_write_uint32(s, drawNineGridSupportLevel); /* drawNineGridSupportLevel (4 bytes) */ + stream_write_uint16(s, settings->draw_nine_grid_cache_size); /* drawNineGridCacheSize (2 bytes) */ + stream_write_uint16(s, settings->draw_nine_grid_cache_entries); /* drawNineGridCacheEntries (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE); +} + +void rdp_write_gdiplus_cache_entries(STREAM* s, uint16 gce, uint16 bce, uint16 pce, uint16 ice, uint16 ace) +{ + stream_write_uint16(s, gce); /* gdipGraphicsCacheEntries (2 bytes) */ + stream_write_uint16(s, bce); /* gdipBrushCacheEntries (2 bytes) */ + stream_write_uint16(s, pce); /* gdipPenCacheEntries (2 bytes) */ + stream_write_uint16(s, ice); /* gdipImageCacheEntries (2 bytes) */ + stream_write_uint16(s, ace); /* gdipImageAttributesCacheEntries (2 bytes) */ +} + +void rdp_write_gdiplus_cache_chunk_size(STREAM* s, uint16 gccs, uint16 obccs, uint16 opccs, uint16 oiaccs) +{ + stream_write_uint16(s, gccs); /* gdipGraphicsCacheChunkSize (2 bytes) */ + stream_write_uint16(s, obccs); /* gdipObjectBrushCacheChunkSize (2 bytes) */ + stream_write_uint16(s, opccs); /* gdipObjectPenCacheChunkSize (2 bytes) */ + stream_write_uint16(s, oiaccs); /* gdipObjectImageAttributesCacheChunkSize (2 bytes) */ +} + +void rdp_write_gdiplus_image_cache_properties(STREAM* s, uint16 oiccs, uint16 oicts, uint16 oicms) +{ + stream_write_uint16(s, oiccs); /* gdipObjectImageCacheChunkSize (2 bytes) */ + stream_write_uint16(s, oicts); /* gdipObjectImageCacheTotalSize (2 bytes) */ + stream_write_uint16(s, oicms); /* gdipObjectImageCacheMaxSize (2 bytes) */ +} + +/** + * Read GDI+ cache capability set.\n + * @msdn{cc241566} + * @param s stream + * @param settings settings + */ + +void rdp_read_draw_gdiplus_cache_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint32 drawGDIPlusSupportLevel; + uint32 drawGdiplusCacheLevel; + + stream_read_uint32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + stream_seek_uint32(s); /* GdipVersion (4 bytes) */ + stream_read_uint32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + stream_seek(s, 10); /* GdipCacheEntries (10 bytes) */ + stream_seek(s, 8); /* GdipCacheChunkSize (8 bytes) */ + stream_seek(s, 6); /* GdipImageCacheProperties (6 bytes) */ + + if (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) + settings->draw_gdi_plus = true; + + if (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) + settings->draw_gdi_plus_cache = true; +} + +/** + * Write GDI+ cache capability set.\n + * @msdn{cc241566} + * @param s stream + * @param settings settings + */ + +void rdp_write_draw_gdiplus_cache_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 drawGDIPlusSupportLevel; + uint32 drawGdiplusCacheLevel; + + header = rdp_capability_set_start(s); + + drawGDIPlusSupportLevel = (settings->draw_gdi_plus) ? DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT; + drawGdiplusCacheLevel = (settings->draw_gdi_plus) ? DRAW_GDIPLUS_CACHE_LEVEL_ONE : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT; + + stream_write_uint32(s, drawGDIPlusSupportLevel); /* drawGDIPlusSupportLevel (4 bytes) */ + stream_write_uint32(s, 0); /* GdipVersion (4 bytes) */ + stream_write_uint32(s, drawGdiplusCacheLevel); /* drawGdiplusCacheLevel (4 bytes) */ + rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2); /* GdipCacheEntries (10 bytes) */ + rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64); /* GdipCacheChunkSize (8 bytes) */ + rdp_write_gdiplus_image_cache_properties(s, 4096, 256, 128); /* GdipImageCacheProperties (6 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS); +} + +/** + * Read remote programs capability set.\n + * @msdn{cc242518} + * @param s stream + * @param settings settings + */ + +void rdp_read_remote_programs_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint32 railSupportLevel; + + stream_read_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + + if ((railSupportLevel & RAIL_LEVEL_SUPPORTED) == 0) + { + if (settings->remote_app == true) + { + /* RemoteApp Failure! */ + settings->remote_app = false; + } + } +} + +/** + * Write remote programs capability set.\n + * @msdn{cc242518} + * @param s stream + * @param settings settings + */ + +void rdp_write_remote_programs_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 railSupportLevel; + + header = rdp_capability_set_start(s); + + railSupportLevel = RAIL_LEVEL_SUPPORTED; + + if (settings->rail_langbar_supported) + railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED; + + stream_write_uint32(s, railSupportLevel); /* railSupportLevel (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL); +} + +/** + * Read window list capability set.\n + * @msdn{cc242564} + * @param s stream + * @param settings settings + */ + +void rdp_read_window_list_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint32(s); /* wndSupportLevel (4 bytes) */ + stream_seek_uint8(s); /* numIconCaches (1 byte) */ + stream_seek_uint16(s); /* numIconCacheEntries (2 bytes) */ +} + +/** + * Write window list capability set.\n + * @msdn{cc242564} + * @param s stream + * @param settings settings + */ + +void rdp_write_window_list_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 wndSupportLevel; + + header = rdp_capability_set_start(s); + + wndSupportLevel = WINDOW_LEVEL_SUPPORTED_EX; + + stream_write_uint32(s, wndSupportLevel); /* wndSupportLevel (4 bytes) */ + stream_write_uint8(s, settings->num_icon_caches); /* numIconCaches (1 byte) */ + stream_write_uint16(s, settings->num_icon_cache_entries); /* numIconCacheEntries (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW); +} + +/** + * Read desktop composition capability set.\n + * @msdn{cc240855} + * @param s stream + * @param settings settings + */ + +void rdp_read_desktop_composition_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* compDeskSupportLevel (2 bytes) */ +} + +/** + * Write desktop composition capability set.\n + * @msdn{cc240855} + * @param s stream + * @param settings settings + */ + +void rdp_write_desktop_composition_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 compDeskSupportLevel; + + header = rdp_capability_set_start(s); + + compDeskSupportLevel = (settings->desktop_composition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED; + + stream_write_uint16(s, compDeskSupportLevel); /* compDeskSupportLevel (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK); +} + +/** + * Read multifragment update capability set.\n + * @msdn{cc240649} + * @param s stream + * @param settings settings + */ + +void rdp_read_multifragment_update_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_read_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */ +} + +/** + * Write multifragment update capability set.\n + * @msdn{cc240649} + * @param s stream + * @param settings settings + */ + +void rdp_write_multifragment_update_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint32(s, settings->multifrag_max_request_size); /* MaxRequestSize (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE); +} + +/** + * Read large pointer capability set.\n + * @msdn{cc240650} + * @param s stream + * @param settings settings + */ + +void rdp_read_large_pointer_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint16(s); /* largePointerSupportFlags (2 bytes) */ +} + +/** + * Write large pointer capability set.\n + * @msdn{cc240650} + * @param s stream + * @param settings settings + */ + +void rdp_write_large_pointer_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint16 largePointerSupportFlags; + + header = rdp_capability_set_start(s); + + largePointerSupportFlags = (settings->large_pointer) ? LARGE_POINTER_FLAG_96x96 : 0; + + stream_write_uint16(s, largePointerSupportFlags); /* largePointerSupportFlags (2 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER); +} + +/** + * Read surface commands capability set.\n + * @msdn{dd871563} + * @param s stream + * @param settings settings + */ + +void rdp_read_surface_commands_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint32(s); /* cmdFlags (4 bytes) */ + stream_seek_uint32(s); /* reserved (4 bytes) */ + + settings->surface_commands = true; +} + +/** + * Write surface commands capability set.\n + * @msdn{dd871563} + * @param s stream + * @param settings settings + */ + +void rdp_write_surface_commands_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint32 cmdFlags; + + header = rdp_capability_set_start(s); + + cmdFlags = SURFCMDS_FRAME_MARKER | + SURFCMDS_SET_SURFACE_BITS | + SURFCMDS_STREAM_SURFACE_BITS; + + stream_write_uint32(s, cmdFlags); /* cmdFlags (4 bytes) */ + stream_write_uint32(s, 0); /* reserved (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS); +} + +/** + * Read bitmap codecs capability set.\n + * @msdn{dd891377} + * @param s stream + * @param settings settings + */ + +void rdp_read_bitmap_codecs_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + uint8 bitmapCodecCount; + uint16 codecPropertiesLength; + + stream_read_uint8(s, bitmapCodecCount); /* bitmapCodecCount (1 byte) */ + + if (settings->server_mode) + { + settings->rfx_codec = false; + settings->ns_codec = false; + } + + while (bitmapCodecCount > 0) + { + if (settings->server_mode && strncmp((char*)stream_get_tail(s), CODEC_GUID_REMOTEFX, 16) == 0) + { + stream_seek(s, 16); /* codecGUID (16 bytes) */ + stream_read_uint8(s, settings->rfx_codec_id); + settings->rfx_codec = true; + } + else if (settings->server_mode && strncmp((char*)stream_get_tail(s),CODEC_GUID_NSCODEC, 16) == 0) + { + stream_seek(s, 16); /*codec GUID (16 bytes) */ + stream_read_uint8(s, settings->ns_codec_id); + settings->ns_codec = true; + } + else + { + stream_seek(s, 16); /* codecGUID (16 bytes) */ + stream_seek_uint8(s); /* codecID (1 byte) */ + } + + stream_read_uint16(s, codecPropertiesLength); /* codecPropertiesLength (2 bytes) */ + stream_seek(s, codecPropertiesLength); /* codecProperties */ + + bitmapCodecCount--; + } +} + +/** + * Write RemoteFX Client Capability Container.\n + * @param s stream + * @param settings settings + */ +void rdp_write_rfx_client_capability_container(STREAM* s, rdpSettings* settings) +{ + uint32 captureFlags; + uint8 codecMode; + + captureFlags = settings->dump_rfx ? 0 : CARDP_CAPS_CAPTURE_NON_CAC; + codecMode = settings->rfx_codec_mode; + + stream_write_uint16(s, 49); /* codecPropertiesLength */ + + /* TS_RFX_CLNT_CAPS_CONTAINER */ + stream_write_uint32(s, 49); /* length */ + stream_write_uint32(s, captureFlags); /* captureFlags */ + stream_write_uint32(s, 37); /* capsLength */ + + /* TS_RFX_CAPS */ + stream_write_uint16(s, CBY_CAPS); /* blockType */ + stream_write_uint32(s, 8); /* blockLen */ + stream_write_uint16(s, 1); /* numCapsets */ + + /* TS_RFX_CAPSET */ + stream_write_uint16(s, CBY_CAPSET); /* blockType */ + stream_write_uint32(s, 29); /* blockLen */ + stream_write_uint8(s, 0x01); /* codecId (MUST be set to 0x01) */ + stream_write_uint16(s, CLY_CAPSET); /* capsetType */ + stream_write_uint16(s, 2); /* numIcaps */ + stream_write_uint16(s, 8); /* icapLen */ + + /* TS_RFX_ICAP (RLGR1) */ + stream_write_uint16(s, CLW_VERSION_1_0); /* version */ + stream_write_uint16(s, CT_TILE_64x64); /* tileSize */ + stream_write_uint8(s, codecMode); /* flags */ + stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */ + stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + stream_write_uint8(s, CLW_ENTROPY_RLGR1); /* entropyBits */ + + /* TS_RFX_ICAP (RLGR3) */ + stream_write_uint16(s, CLW_VERSION_1_0); /* version */ + stream_write_uint16(s, CT_TILE_64x64); /* tileSize */ + stream_write_uint8(s, codecMode); /* flags */ + stream_write_uint8(s, CLW_COL_CONV_ICT); /* colConvBits */ + stream_write_uint8(s, CLW_XFORM_DWT_53_A); /* transformBits */ + stream_write_uint8(s, CLW_ENTROPY_RLGR3); /* entropyBits */ +} + +/** + * Write NSCODEC Client Capability Container.\n + * @param s stream + * @param settings settings + */ +void rdp_write_nsc_client_capability_container(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 3); /* codecPropertiesLength */ + + /* TS_NSCODEC_CAPABILITYSET */ + stream_write_uint8(s, 1); /* fAllowDynamicFidelity */ + stream_write_uint8(s, 1); /* fAllowSubsampling */ + stream_write_uint8(s, 3); /* colorLossLevel */ +} + +/** + * Write RemoteFX Server Capability Container.\n + * @param s stream + * @param settings settings + */ +void rdp_write_rfx_server_capability_container(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 4); /* codecPropertiesLength */ + stream_write_uint32(s, 0); /* reserved */ +} + +/** + * Write NSCODEC Server Capability Container.\n + * @param s stream + * @param settings settings + */ +void rdp_write_nsc_server_capability_container(STREAM* s, rdpSettings* settings) +{ + stream_write_uint16(s, 4); /* codecPropertiesLength */ + stream_write_uint32(s, 0); /* reserved */ +} + + +/** + * Write bitmap codecs capability set.\n + * @msdn{dd891377} + * @param s stream + * @param settings settings + */ + +void rdp_write_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + uint8 bitmapCodecCount; + + header = rdp_capability_set_start(s); + + bitmapCodecCount = 0; + if (settings->rfx_codec) + bitmapCodecCount++; + if (settings->ns_codec) + bitmapCodecCount++; + + stream_write_uint8(s, bitmapCodecCount); + + if (settings->rfx_codec) + { + stream_write(s, CODEC_GUID_REMOTEFX, 16); /* codecGUID */ + + if (settings->server_mode) + { + stream_write_uint8(s, 0); /* codecID is defined by the client */ + rdp_write_rfx_server_capability_container(s, settings); + } + else + { + stream_write_uint8(s, CODEC_ID_REMOTEFX); /* codecID */ + rdp_write_rfx_client_capability_container(s, settings); + } + } + if (settings->ns_codec) + { + stream_write(s, CODEC_GUID_NSCODEC, 16); + if (settings->server_mode) + { + stream_write_uint8(s, 0); /* codecID is defined by the client */ + rdp_write_nsc_server_capability_container(s, settings); + } + else + { + stream_write_uint8(s, CODEC_ID_NSCODEC); /* codecID */ + rdp_write_nsc_client_capability_container(s, settings); + } + } + rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS); +} + +/** + * Read frame acknowledge capability set.\n + * @param s stream + * @param settings settings + */ + +void rdp_read_frame_acknowledge_capability_set(STREAM* s, uint16 length, rdpSettings* settings) +{ + stream_seek_uint32(s); /* (4 bytes) */ +} + +/** + * Write frame acknowledge capability set.\n + * @param s stream + * @param settings settings + */ + +void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings) +{ + uint8* header; + + header = rdp_capability_set_start(s); + + stream_write_uint32(s, 2); /* (4 bytes) */ + + rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE); +} + +boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 numberCapabilities) +{ + uint16 type; + uint16 length; + uint8 *bm, *em; + + while (numberCapabilities > 0) + { + stream_get_mark(s, bm); + + rdp_read_capability_set_header(s, &length, &type); + //printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length); + settings->received_caps[type] = true; + em = bm + length; + + if (stream_get_left(s) < length - 4) + { + printf("error processing stream\n"); + return false; + } + + switch (type) + { + case CAPSET_TYPE_GENERAL: + rdp_read_general_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BITMAP: + rdp_read_bitmap_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_ORDER: + rdp_read_order_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BITMAP_CACHE: + rdp_read_bitmap_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_CONTROL: + rdp_read_control_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_ACTIVATION: + rdp_read_window_activation_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_POINTER: + rdp_read_pointer_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_SHARE: + rdp_read_share_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_COLOR_CACHE: + rdp_read_color_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_SOUND: + rdp_read_sound_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_INPUT: + rdp_read_input_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_FONT: + rdp_read_font_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BRUSH: + rdp_read_brush_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_GLYPH_CACHE: + rdp_read_glyph_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_OFFSCREEN_CACHE: + rdp_read_offscreen_bitmap_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT: + rdp_read_bitmap_cache_host_support_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BITMAP_CACHE_V2: + rdp_read_bitmap_cache_v2_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_VIRTUAL_CHANNEL: + rdp_read_virtual_channel_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_DRAW_NINE_GRID_CACHE: + rdp_read_draw_nine_grid_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_DRAW_GDI_PLUS: + rdp_read_draw_gdiplus_cache_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_RAIL: + rdp_read_remote_programs_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_WINDOW: + rdp_read_window_list_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_COMP_DESK: + rdp_read_desktop_composition_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE: + rdp_read_multifragment_update_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_LARGE_POINTER: + rdp_read_large_pointer_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_SURFACE_COMMANDS: + rdp_read_surface_commands_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_BITMAP_CODECS: + rdp_read_bitmap_codecs_capability_set(s, length, settings); + break; + + case CAPSET_TYPE_FRAME_ACKNOWLEDGE: + rdp_read_frame_acknowledge_capability_set(s, length, settings); + break; + + default: + printf("unknown capability type %d\n", type); + break; + } + + if (s->p != em) + { + printf("incorrect offset, type:0x%02X actual:%d expected:%d\n", + type, (int) (s->p - bm), (int) (em - bm)); + } + + stream_set_mark(s, em); + numberCapabilities--; + } + + return true; +} + +boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s) +{ + uint16 length; + uint16 channelId; + uint16 pduType; + uint16 pduLength; + uint16 pduSource; + uint16 numberCapabilities; + uint16 lengthSourceDescriptor; + uint16 lengthCombinedCapabilities; + uint16 securityFlags; + + if (!rdp_read_header(rdp, s, &length, &channelId)) + return false; + + if (rdp->disconnect) + return true; + + if (rdp->settings->encryption) + { + rdp_read_security_header(s, &securityFlags); + if (securityFlags & SEC_ENCRYPT) + { + if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return false; + } + } + } + + if (channelId != MCS_GLOBAL_CHANNEL_ID) + { + printf("channelId bad\n"); + return false; + } + + if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) + { + printf("rdp_read_share_control_header failed\n"); + return false; + } + + rdp->settings->pdu_source = pduSource; + + if (pduType != PDU_TYPE_DEMAND_ACTIVE) + { + printf("pduType bad\n"); + return false; + } + + stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ + stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ + stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + + /* capabilitySets */ + if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) + { + printf("rdp_read_capability_sets failed\n"); + return false; + } + + rdp->update->secondary->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? true : false; + + return true; +} + +void rdp_write_demand_active(STREAM* s, rdpSettings* settings) +{ + uint8 *bm, *em, *lm; + uint16 numberCapabilities; + uint16 lengthCombinedCapabilities; + + stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */ + stream_write_uint16(s, 4); /* lengthSourceDescriptor (2 bytes) */ + + stream_get_mark(s, lm); + stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */ + stream_write(s, "RDP", 4); /* sourceDescriptor */ + + stream_get_mark(s, bm); + stream_seek_uint16(s); /* numberCapabilities (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + numberCapabilities = 14; + rdp_write_general_capability_set(s, settings); + rdp_write_bitmap_capability_set(s, settings); + rdp_write_order_capability_set(s, settings); + rdp_write_pointer_capability_set(s, settings); + rdp_write_input_capability_set(s, settings); + rdp_write_virtual_channel_capability_set(s, settings); + rdp_write_bitmap_cache_host_support_capability_set(s, settings); + rdp_write_share_capability_set(s, settings); + rdp_write_font_capability_set(s, settings); + rdp_write_multifragment_update_capability_set(s, settings); + rdp_write_large_pointer_capability_set(s, settings); + rdp_write_desktop_composition_capability_set(s, settings); + rdp_write_surface_commands_capability_set(s, settings); + rdp_write_bitmap_codecs_capability_set(s, settings); + + stream_get_mark(s, em); + + stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ + lengthCombinedCapabilities = (em - bm); + stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + + stream_set_mark(s, bm); /* go back to numberCapabilities */ + stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + + stream_set_mark(s, em); + + stream_write_uint32(s, 0); /* sessionId */ +} + +boolean rdp_send_demand_active(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_pdu_init(rdp); + + rdp->settings->share_id = 0x10000 + rdp->mcs->user_id; + + rdp_write_demand_active(s, rdp->settings); + + rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->user_id); + + return true; +} + +boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s) +{ + uint16 length; + uint16 channelId; + uint16 pduType; + uint16 pduLength; + uint16 pduSource; + uint16 lengthSourceDescriptor; + uint16 lengthCombinedCapabilities; + uint16 numberCapabilities; + uint16 securityFlags; + + if (!rdp_read_header(rdp, s, &length, &channelId)) + return false; + + if (rdp->settings->encryption) + { + rdp_read_security_header(s, &securityFlags); + if (securityFlags & SEC_ENCRYPT) + { + if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return false; + } + } + } + + if (channelId != MCS_GLOBAL_CHANNEL_ID) + return false; + + if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) + return false; + + rdp->settings->pdu_source = pduSource; + + if (pduType != PDU_TYPE_CONFIRM_ACTIVE) + return false; + + stream_seek_uint32(s); /* shareId (4 bytes) */ + stream_seek_uint16(s); /* originatorId (2 bytes) */ + stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ + stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ + stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + + if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) + return false; + + return true; +} + +void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) +{ + uint8 *bm, *em, *lm; + uint16 numberCapabilities; + uint16 lengthSourceDescriptor; + uint16 lengthCombinedCapabilities; + + lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR); + + stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */ + stream_write_uint16(s, 0x03EA); /* originatorId (2 bytes) */ + stream_write_uint16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */ + + stream_get_mark(s, lm); + stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */ + stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */ + + stream_get_mark(s, bm); + stream_seek_uint16(s); /* numberCapabilities (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + + /* Capability Sets */ + numberCapabilities = 15; + rdp_write_general_capability_set(s, settings); + rdp_write_bitmap_capability_set(s, settings); + rdp_write_order_capability_set(s, settings); + + if (settings->rdp_version >= 5) + rdp_write_bitmap_cache_v2_capability_set(s, settings); + else + rdp_write_bitmap_cache_capability_set(s, settings); + + rdp_write_pointer_capability_set(s, settings); + rdp_write_input_capability_set(s, settings); + rdp_write_brush_capability_set(s, settings); + rdp_write_glyph_cache_capability_set(s, settings); + rdp_write_virtual_channel_capability_set(s, settings); + rdp_write_sound_capability_set(s, settings); + rdp_write_share_capability_set(s, settings); + rdp_write_font_capability_set(s, settings); + rdp_write_control_capability_set(s, settings); + rdp_write_color_cache_capability_set(s, settings); + rdp_write_window_activation_capability_set(s, settings); + + if (settings->offscreen_bitmap_cache) + { + numberCapabilities++; + rdp_write_offscreen_bitmap_cache_capability_set(s, settings); + } + + if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER]) + { + if (settings->large_pointer) + { + numberCapabilities++; + rdp_write_large_pointer_capability_set(s, settings); + } + } + + if (settings->remote_app) + { + numberCapabilities += 2; + rdp_write_remote_programs_capability_set(s, settings); + rdp_write_window_list_capability_set(s, settings); + } + + if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE]) + { + numberCapabilities++; + rdp_write_multifragment_update_capability_set(s, settings); + } + + if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS]) + { + numberCapabilities++; + rdp_write_surface_commands_capability_set(s, settings); + } + + if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS]) + { + numberCapabilities++; + rdp_write_bitmap_codecs_capability_set(s, settings); + } + + if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE]) + { + if (settings->frame_acknowledge) + { + numberCapabilities++; + rdp_write_frame_acknowledge_capability_set(s, settings); + } + } + + stream_get_mark(s, em); + + stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ + lengthCombinedCapabilities = (em - bm); + stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ + + stream_set_mark(s, bm); /* go back to numberCapabilities */ + stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ + + stream_set_mark(s, em); +} + +boolean rdp_send_confirm_active(rdpRdp* rdp) +{ + STREAM* s; + + s = rdp_pdu_init(rdp); + + rdp_write_confirm_active(s, rdp->settings); + + return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); +} + diff --git a/libfreerdp-core/capabilities.h b/libfreerdp-core/capabilities.h new file mode 100644 index 0000000..420d69c --- /dev/null +++ b/libfreerdp-core/capabilities.h @@ -0,0 +1,173 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Capability Sets + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CAPABILITIES_H +#define __CAPABILITIES_H + +#include "rdp.h" + +#include +#include +#include +#include + +/* Capability Set Types */ +#define CAPSET_TYPE_GENERAL 0x0001 +#define CAPSET_TYPE_BITMAP 0x0002 +#define CAPSET_TYPE_ORDER 0x0003 +#define CAPSET_TYPE_BITMAP_CACHE 0x0004 +#define CAPSET_TYPE_CONTROL 0x0005 +#define CAPSET_TYPE_ACTIVATION 0x0007 +#define CAPSET_TYPE_POINTER 0x0008 +#define CAPSET_TYPE_SHARE 0x0009 +#define CAPSET_TYPE_COLOR_CACHE 0x000A +#define CAPSET_TYPE_SOUND 0x000C +#define CAPSET_TYPE_INPUT 0x000D +#define CAPSET_TYPE_FONT 0x000E +#define CAPSET_TYPE_BRUSH 0x000F +#define CAPSET_TYPE_GLYPH_CACHE 0x0010 +#define CAPSET_TYPE_OFFSCREEN_CACHE 0x0011 +#define CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT 0x0012 +#define CAPSET_TYPE_BITMAP_CACHE_V2 0x0013 +#define CAPSET_TYPE_VIRTUAL_CHANNEL 0x0014 +#define CAPSET_TYPE_DRAW_NINE_GRID_CACHE 0x0015 +#define CAPSET_TYPE_DRAW_GDI_PLUS 0x0016 +#define CAPSET_TYPE_RAIL 0x0017 +#define CAPSET_TYPE_WINDOW 0x0018 +#define CAPSET_TYPE_COMP_DESK 0x0019 +#define CAPSET_TYPE_MULTI_FRAGMENT_UPDATE 0x001A +#define CAPSET_TYPE_LARGE_POINTER 0x001B +#define CAPSET_TYPE_SURFACE_COMMANDS 0x001C +#define CAPSET_TYPE_BITMAP_CODECS 0x001D +#define CAPSET_TYPE_FRAME_ACKNOWLEDGE 0x001E + +#define CAPSET_HEADER_LENGTH 4 + +#define SOURCE_DESCRIPTOR "FREERDP" + +/* Capabilities Protocol Version */ +#define CAPS_PROTOCOL_VERSION 0x0200 + +/* General Capability Flags */ +#define FASTPATH_OUTPUT_SUPPORTED 0x0001 +#define NO_BITMAP_COMPRESSION_HDR 0x0400 +#define LONG_CREDENTIALS_SUPPORTED 0x0004 +#define AUTORECONNECT_SUPPORTED 0x0008 +#define ENC_SALTED_CHECKSUM 0x0010 + +/* Drawing Flags */ +#define DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY 0x02 +#define DRAW_ALLOW_COLOR_SUBSAMPLING 0x04 +#define DRAW_ALLOW_SKIP_ALPHA 0x08 + +/* Order Flags */ +#define NEGOTIATE_ORDER_SUPPORT 0x0002 +#define ZERO_BOUNDS_DELTA_SUPPORT 0x0008 +#define COLOR_INDEX_SUPPORT 0x0020 +#define SOLID_PATTERN_BRUSH_ONLY 0x0040 +#define ORDER_FLAGS_EXTRA_SUPPORT 0x0080 + +/* Extended Order Flags */ +#define CACHE_BITMAP_V3_SUPPORT 0x0002 +#define ALTSEC_FRAME_MARKER_SUPPORT 0x0004 + +/* Sound Flags */ +#define SOUND_BEEPS_FLAG 0x0001 + +/* Input Flags */ +#define INPUT_FLAG_SCANCODES 0x0001 +#define INPUT_FLAG_MOUSEX 0x0004 +#define INPUT_FLAG_FASTPATH_INPUT 0x0008 +#define INPUT_FLAG_UNICODE 0x0010 +#define INPUT_FLAG_FASTPATH_INPUT2 0x0020 + +/* Font Support Flags */ +#define FONTSUPPORT_FONTLIST 0x0001 + +/* Brush Support Level */ +#define BRUSH_DEFAULT 0x00000000 +#define BRUSH_COLOR_8x8 0x00000001 +#define BRUSH_COLOR_FULL 0x00000002 + +/* Bitmap Cache Version */ +#define BITMAP_CACHE_V2 0x01 + +/* Bitmap Cache V2 Flags */ +#define PERSISTENT_KEYS_EXPECTED_FLAG 0x0001 +#define ALLOW_CACHE_WAITING_LIST_FLAG 0x0002 + +/* Virtual Channel Flags */ +#define VCCAPS_NO_COMPR 0x00000000 +#define VCCAPS_COMPR_SC 0x00000001 +#define VCCAPS_COMPR_CS_8K 0x00000002 + +/* Draw Nine Grid Support Level */ +#define DRAW_NINEGRID_NO_SUPPORT 0x00000000 +#define DRAW_NINEGRID_SUPPORTED 0x00000001 +#define DRAW_NINEGRID_SUPPORTED_V2 0x00000002 + +/* Draw GDI+ Support Level */ +#define DRAW_GDIPLUS_DEFAULT 0x00000000 +#define DRAW_GDIPLUS_SUPPORTED 0x00000001 + +/* Draw GDI+ Cache Level */ +#define DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT 0x00000000 +#define DRAW_GDIPLUS_CACHE_LEVEL_ONE 0x00000001 + +/* RAIL Support Level */ +#define RAIL_LEVEL_SUPPORTED 0x00000001 +#define RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED 0x00000002 + +/* Window Support Level */ +#define WINDOW_LEVEL_NOT_SUPPORTED 0x00000000 +#define WINDOW_LEVEL_SUPPORTED 0x00000001 +#define WINDOW_LEVEL_SUPPORTED_EX 0x00000002 + +/* Desktop Composition Support Level */ +#define COMPDESK_NOT_SUPPORTED 0x0000 +#define COMPDESK_SUPPORTED 0x0001 + +/* Large Pointer Support Flags */ +#define LARGE_POINTER_FLAG_96x96 0x00000001 + +/* Surface Commands Flags */ +#define SURFCMDS_SET_SURFACE_BITS 0x00000002 +#define SURFCMDS_FRAME_MARKER 0x00000010 +#define SURFCMDS_STREAM_SURFACE_BITS 0x00000040 + +/* Bitmap Codec Constants */ +#define CARDP_CAPS_CAPTURE_NON_CAC 0x00000001 +#define CBY_CAPS 0xCBC0 +#define CBY_CAPSET 0xCBC1 +#define CLY_CAPSET 0xCFC0 +#define CLW_VERSION_1_0 0x0100 +#define CT_TILE_64x64 0x0040 +#define CLW_COL_CONV_ICT 0x1 +#define CLW_XFORM_DWT_53_A 0x1 +#define CLW_ENTROPY_RLGR1 0x01 +#define CLW_ENTROPY_RLGR3 0x04 + +boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s); +void rdp_write_demand_active(STREAM* s, rdpSettings* settings); +boolean rdp_send_demand_active(rdpRdp* rdp); +boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s); +void rdp_write_confirm_active(STREAM* s, rdpSettings* settings); +boolean rdp_send_confirm_active(rdpRdp* rdp); + +#endif /* __CAPABILITIES_H */ diff --git a/libfreerdp-core/certificate.c b/libfreerdp-core/certificate.c new file mode 100644 index 0000000..69fcf1d --- /dev/null +++ b/libfreerdp-core/certificate.c @@ -0,0 +1,760 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Certificate Handling + * + * Copyright 2011 Jiten Pathy + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include + +static const char certificate_store_dir[] = "certs"; +static const char certificate_known_hosts_file[] = "known_hosts"; + +#include "certificate.h" + +/** + * + * X.509 Certificate Structure + * + * Certificate ::= SEQUENCE + * { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT_STRING + * } + * + * TBSCertificate ::= SEQUENCE + * { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * subjectUniqueId [2] IMPLICIT UniqueIdentifier OPTIONAL, + * extensions [3] EXPLICIT Extensions OPTIONAL + * } + * + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * + * CertificateSerialNumber ::= INTEGER + * + * AlgorithmIdentifier ::= SEQUENCE + * { + * algorithm OBJECT_IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * Name ::= CHOICE { RDNSequence } + * + * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + * + * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE + * { + * type AttributeType, + * value AttributeValue + * } + * + * AttributeType ::= OBJECT_IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + * + * Validity ::= SEQUENCE + * { + * notBefore Time, + * notAfter Time + * } + * + * Time ::= CHOICE + * { + * utcTime UTCTime, + * generalTime GeneralizedTime + * } + * + * UniqueIdentifier ::= BIT_STRING + * + * SubjectPublicKeyInfo ::= SEQUENCE + * { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT_STRING + * } + * + * RSAPublicKey ::= SEQUENCE + * { + * modulus INTEGER + * publicExponent INTEGER + * } + * + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * + * Extension ::= SEQUENCE + * { + * extnID OBJECT_IDENTIFIER + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET_STRING + * } + * + */ + +/** + * Read X.509 Certificate + * @param certificate certificate module + * @param cert X.509 certificate + */ + +void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) +{ + STREAM* s; + int length; + uint8 padding; + uint32 version; + int modulus_length; + int exponent_length; + + s = stream_new(0); + stream_attach(s, cert->data, cert->length); + + ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */ + + ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */ + + /* Explicit Contextual Tag [0] */ + ber_read_contextual_tag(s, 0, &length, true); + ber_read_integer(s, &version); /* version (INTEGER) */ + version++; + + /* serialNumber */ + ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */ + + /* signature */ + ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ + stream_seek(s, length); + + /* issuer */ + ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ + stream_seek(s, length); + + /* validity */ + ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */ + stream_seek(s, length); + + /* subject */ + ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ + stream_seek(s, length); + + /* subjectPublicKeyInfo */ + ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */ + + /* subjectPublicKeyInfo::AlgorithmIdentifier */ + ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ + stream_seek(s, length); + + /* subjectPublicKeyInfo::subjectPublicKey */ + ber_read_bit_string(s, &length, &padding); /* BIT_STRING */ + + /* RSAPublicKey (SEQUENCE) */ + ber_read_sequence_tag(s, &length); /* SEQUENCE */ + + ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */ + + /* skip zero padding, if any */ + do + { + stream_peek_uint8(s, padding); + + if (padding == 0) + { + stream_seek(s, 1); + modulus_length--; + } + } + while (padding == 0); + + freerdp_blob_alloc(&info->modulus, modulus_length); + stream_read(s, info->modulus.data, modulus_length); + + ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */ + stream_read(s, &info->exponent[4 - exponent_length], exponent_length); + crypto_reverse(info->modulus.data, modulus_length); + crypto_reverse(info->exponent, 4); + + stream_detach(s); + stream_free(s); +} + +/** + * Instantiate new X.509 Certificate Chain. + * @param count certificate chain count + * @return new X.509 certificate chain + */ + +rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count) +{ + rdpX509CertChain* x509_cert_chain; + + x509_cert_chain = (rdpX509CertChain*) xmalloc(sizeof(rdpX509CertChain)); + + x509_cert_chain->count = count; + x509_cert_chain->array = (rdpCertBlob*) xzalloc(sizeof(rdpCertBlob) * count); + + return x509_cert_chain; +} + +/** + * Free X.509 Certificate Chain. + * @param x509_cert_chain X.509 certificate chain to be freed + */ + +void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain) +{ + int i; + + if (x509_cert_chain != NULL) + { + for (i = 0; i < (int) x509_cert_chain->count; i++) + { + if (x509_cert_chain->array[i].data != NULL) + xfree(x509_cert_chain->array[i].data); + } + + xfree(x509_cert_chain->array); + xfree(x509_cert_chain); + } +} + +static boolean certificate_process_server_public_key(rdpCertificate* certificate, STREAM* s, uint32 length) +{ + uint8 magic[4]; + uint32 keylen; + uint32 bitlen; + uint32 datalen; + uint32 modlen; + + stream_read(s, magic, 4); + if (memcmp(magic, "RSA1", 4) != 0) + { + printf("gcc_process_server_public_key: magic error\n"); + return false; + } + + stream_read_uint32(s, keylen); + stream_read_uint32(s, bitlen); + stream_read_uint32(s, datalen); + stream_read(s, certificate->cert_info.exponent, 4); + modlen = keylen - 8; + freerdp_blob_alloc(&(certificate->cert_info.modulus), modlen); + stream_read(s, certificate->cert_info.modulus.data, modlen); + /* 8 bytes of zero padding */ + stream_seek(s, 8); + + return true; +} + +static boolean certificate_process_server_public_signature(rdpCertificate* certificate, uint8* sigdata, int sigdatalen, STREAM* s, uint32 siglen) +{ + uint8 md5hash[CRYPTO_MD5_DIGEST_LENGTH]; + uint8 encsig[TSSK_KEY_LENGTH + 8]; + uint8 sig[TSSK_KEY_LENGTH]; + CryptoMd5 md5ctx; + int i, sum; + + md5ctx = crypto_md5_init(); + crypto_md5_update(md5ctx, sigdata, sigdatalen); + crypto_md5_final(md5ctx, md5hash); + + stream_read(s, encsig, siglen); + + /* Last 8 bytes shall be all zero. */ + + for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++) + sum += encsig[i]; + + if (sum != 0) + { + printf("certificate_process_server_public_signature: invalid signature\n"); + //return false; + } + + siglen -= 8; + + crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig); + + /* Verify signature. */ + if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) + { + printf("certificate_process_server_public_signature: invalid signature\n"); + //return false; + } + + /* + * Verify rest of decrypted data: + * The 17th byte is 0x00. + * The 18th through 62nd bytes are each 0xFF. + * The 63rd byte is 0x01. + */ + + for (sum = 0, i = 17; i < 62; i++) + sum += sig[i]; + + if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) + { + printf("certificate_process_server_public_signature: invalid signature\n"); + //return false; + } + + return true; +} + +/** + * Read a Server Proprietary Certificate.\n + * @param certificate certificate module + * @param s stream + */ + +boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s) +{ + uint32 dwSigAlgId; + uint32 dwKeyAlgId; + uint32 wPublicKeyBlobType; + uint32 wPublicKeyBlobLen; + uint32 wSignatureBlobType; + uint32 wSignatureBlobLen; + uint8* sigdata; + int sigdatalen; + + /* -4, because we need to include dwVersion */ + sigdata = stream_get_tail(s) - 4; + stream_read_uint32(s, dwSigAlgId); + stream_read_uint32(s, dwKeyAlgId); + if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA)) + { + printf("certificate_read_server_proprietary_certificate: parse error 1\n"); + return false; + } + stream_read_uint16(s, wPublicKeyBlobType); + if (wPublicKeyBlobType != BB_RSA_KEY_BLOB) + { + printf("certificate_read_server_proprietary_certificate: parse error 2\n"); + return false; + } + stream_read_uint16(s, wPublicKeyBlobLen); + if (!certificate_process_server_public_key(certificate, s, wPublicKeyBlobLen)) + { + printf("certificate_read_server_proprietary_certificate: parse error 3\n"); + return false; + } + sigdatalen = stream_get_tail(s) - sigdata; + stream_read_uint16(s, wSignatureBlobType); + if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB) + { + printf("certificate_read_server_proprietary_certificate: parse error 4\n"); + return false; + } + stream_read_uint16(s, wSignatureBlobLen); + if (wSignatureBlobLen != 72) + { + printf("certificate_process_server_public_signature: invalid signature length (got %d, expected %d)\n", wSignatureBlobLen, 64); + return false; + } + if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen)) + { + printf("certificate_read_server_proprietary_certificate: parse error 5\n"); + return false; + } + + return true; +} + +/** + * Read an X.509 Certificate Chain.\n + * @param certificate certificate module + * @param s stream + */ + +boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s) +{ + int i; + uint32 certLength; + uint32 numCertBlobs; + + DEBUG_CERTIFICATE("Server X.509 Certificate Chain"); + + stream_read_uint32(s, numCertBlobs); /* numCertBlobs */ + + certificate->x509_cert_chain = certificate_new_x509_certificate_chain(numCertBlobs); + + for (i = 0; i < (int) numCertBlobs; i++) + { + stream_read_uint32(s, certLength); + + DEBUG_CERTIFICATE("\nX.509 Certificate #%d, length:%d", i + 1, certLength); + + certificate->x509_cert_chain->array[i].data = (uint8*) xmalloc(certLength); + stream_read(s, certificate->x509_cert_chain->array[i].data, certLength); + certificate->x509_cert_chain->array[i].length = certLength; + + if (numCertBlobs - i == 2) + { + rdpCertInfo cert_info; + DEBUG_CERTIFICATE("License Server Certificate"); + certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &cert_info); + DEBUG_LICENSE("modulus length:%d", cert_info.modulus.length); + freerdp_blob_free(&cert_info.modulus); + } + else if (numCertBlobs - i == 1) + { + DEBUG_CERTIFICATE("Terminal Server Certificate"); + certificate_read_x509_certificate(&certificate->x509_cert_chain->array[i], &certificate->cert_info); + DEBUG_CERTIFICATE("modulus length:%d", certificate->cert_info.modulus.length); + } + } + + return true; +} + +/** + * Read a Server Certificate.\n + * @param certificate certificate module + * @param server_cert server certificate + * @param length certificate length + */ + +boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length) +{ + STREAM* s; + uint32 dwVersion; + + s = stream_new(0); + stream_attach(s, server_cert, length); + + if (length < 1) + { + printf("null server certificate\n"); + return false; + } + + stream_read_uint32(s, dwVersion); /* dwVersion (4 bytes) */ + + switch (dwVersion & CERT_CHAIN_VERSION_MASK) + { + case CERT_CHAIN_VERSION_1: + certificate_read_server_proprietary_certificate(certificate, s); + break; + + case CERT_CHAIN_VERSION_2: + certificate_read_server_x509_certificate_chain(certificate, s); + break; + + default: + printf("invalid certificate chain version:%d\n", dwVersion & CERT_CHAIN_VERSION_MASK); + break; + } + + xfree(s); + return true; +} + +rdpKey* key_new(const char* keyfile) +{ + rdpKey* key; + RSA *rsa; + FILE *fp; + + key = (rdpKey*) xzalloc(sizeof(rdpKey)); + + if (key == NULL) + return NULL; + + fp = fopen(keyfile, "r"); + + if (fp == NULL) + { + printf("unable to load RSA key from %s: %s.", keyfile, strerror(errno)); + return NULL; + } + + rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); + + if (rsa == NULL) + { + ERR_print_errors_fp(stdout); + fclose(fp); + return NULL; + } + + fclose(fp); + + switch (RSA_check_key(rsa)) + { + case 0: + RSA_free(rsa); + printf("invalid RSA key in %s", keyfile); + return NULL; + + case 1: + /* Valid key. */ + break; + + default: + ERR_print_errors_fp(stdout); + RSA_free(rsa); + return NULL; + } + + if (BN_num_bytes(rsa->e) > 4) + { + RSA_free(rsa); + printf("RSA public exponent too large in %s", keyfile); + return NULL; + } + + freerdp_blob_alloc(&key->modulus, BN_num_bytes(rsa->n)); + BN_bn2bin(rsa->n, key->modulus.data); + crypto_reverse(key->modulus.data, key->modulus.length); + freerdp_blob_alloc(&key->private_exponent, BN_num_bytes(rsa->d)); + BN_bn2bin(rsa->d, key->private_exponent.data); + crypto_reverse(key->private_exponent.data, key->private_exponent.length); + memset(key->exponent, 0, sizeof(key->exponent)); + BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e)); + crypto_reverse(key->exponent, sizeof(key->exponent)); + + RSA_free(rsa); + + return key; +} + +void key_free(rdpKey* key) +{ + if (key != NULL) + { + freerdp_blob_free(&key->modulus); + freerdp_blob_free(&key->private_exponent); + xfree(key); + } +} + +void certificate_store_init(rdpCertificateStore* certificate_store) +{ + char* config_path; + rdpSettings* settings; + + settings = certificate_store->settings; + + config_path = freerdp_get_config_path(settings); + certificate_store->path = freerdp_construct_path(config_path, (char*) certificate_store_dir); + + if (freerdp_check_file_exists(certificate_store->path) == false) + { + freerdp_mkdir(certificate_store->path); + printf("creating directory %s\n", certificate_store->path); + } + + certificate_store->file = freerdp_construct_path(config_path, (char*) certificate_known_hosts_file); + + if (freerdp_check_file_exists(certificate_store->file) == false) + { + certificate_store->fp = fopen((char*) certificate_store->file, "w+"); + + if (certificate_store->fp == NULL) + { + printf("certificate_store_open: error opening [%s] for writing\n", certificate_store->file); + return; + } + + fflush(certificate_store->fp); + } + else + { + certificate_store->fp = fopen((char*) certificate_store->file, "r+"); + } +} + +int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) +{ + FILE* fp; + int length; + char* data; + char* pline; + int match = 1; + long int size; + + fp = certificate_store->fp; + + if (!fp) + return match; + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (size < 1) + return match; + + data = (char*) xmalloc(size + 2); + + if (fread(data, size, 1, fp) != 1) + { + xfree(data); + return match; + } + + data[size] = '\n'; + data[size + 1] = '\0'; + pline = strtok(data, "\n"); + + while (pline != NULL) + { + length = strlen(pline); + + if (length > 0) + { + length = strcspn(pline, " \t"); + pline[length] = '\0'; + + if (strcmp(pline, certificate_data->hostname) == 0) + { + pline = &pline[length + 1]; + + if (strcmp(pline, certificate_data->fingerprint) == 0) + match = 0; + else + match = -1; + break; + } + } + + pline = strtok(NULL, "\n"); + } + xfree(data); + + return match; +} + +void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data) +{ + FILE* fp; + + /* reopen in append mode */ + fp = fopen(certificate_store->file, "a"); + + if (!fp) + return; + + fprintf(certificate_store->fp,"%s %s\n", certificate_data->hostname, certificate_data->fingerprint); + fclose(fp); +} + +rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint) +{ + rdpCertificateData* certdata; + + certdata = (rdpCertificateData*) xzalloc(sizeof(rdpCertificateData)); + + if (certdata != NULL) + { + certdata->hostname = xstrdup(hostname); + certdata->fingerprint = xstrdup(fingerprint); + } + + return certdata; +} + +void certificate_data_free(rdpCertificateData* certificate_data) +{ + if (certificate_data != NULL) + { + xfree(certificate_data->hostname); + xfree(certificate_data->fingerprint); + xfree(certificate_data); + } +} + +rdpCertificateStore* certificate_store_new(rdpSettings* settings) +{ + rdpCertificateStore* certificate_store; + + certificate_store = (rdpCertificateStore*) xzalloc(sizeof(rdpCertificateStore)); + + if (certificate_store != NULL) + { + certificate_store->settings = settings; + certificate_store_init(certificate_store); + } + + return certificate_store; +} + +void certificate_store_free(rdpCertificateStore* certstore) +{ + if (certstore != NULL) + { + if (certstore->fp != NULL) + fclose(certstore->fp); + + xfree(certstore->path); + xfree(certstore->file); + xfree(certstore); + } +} + +/** + * Instantiate new certificate module.\n + * @param rdp RDP module + * @return new certificate module + */ + +rdpCertificate* certificate_new() +{ + rdpCertificate* certificate; + + certificate = (rdpCertificate*) xzalloc(sizeof(rdpCertificate)); + + if (certificate != NULL) + { + certificate->x509_cert_chain = NULL; + } + + return certificate; +} + +/** + * Free certificate module. + * @param certificate certificate module to be freed + */ + +void certificate_free(rdpCertificate* certificate) +{ + if (certificate != NULL) + { + certificate_free_x509_certificate_chain(certificate->x509_cert_chain); + + if (certificate->cert_info.modulus.data != NULL) + freerdp_blob_free(&(certificate->cert_info.modulus)); + + xfree(certificate); + } +} diff --git a/libfreerdp-core/certificate.h b/libfreerdp-core/certificate.h new file mode 100644 index 0000000..2451dd4 --- /dev/null +++ b/libfreerdp-core/certificate.h @@ -0,0 +1,98 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Certificate Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CERTIFICATE_H +#define __CERTIFICATE_H + +typedef struct rdp_certificate_data rdpCertificateData; +typedef struct rdp_certificate_store rdpCertificateStore; + +#include "rdp.h" +#include "ber.h" +#include "crypto.h" + +#include +#include +#include +#include + +/* Certificate Version */ +#define CERT_CHAIN_VERSION_1 0x00000001 +#define CERT_CHAIN_VERSION_2 0x00000002 +#define CERT_CHAIN_VERSION_MASK 0x7FFFFFFF +#define CERT_PERMANENTLY_ISSUED 0x00000000 +#define CERT_TEMPORARILY_ISSUED 0x80000000 + +#define SIGNATURE_ALG_RSA 0x00000001 +#define KEY_EXCHANGE_ALG_RSA 0x00000001 + +#define BB_RSA_KEY_BLOB 6 +#define BB_RSA_SIGNATURE_BLOB 8 + +struct rdp_key +{ + rdpBlob modulus; + rdpBlob private_exponent; + uint8 exponent[4]; +}; + +struct rdp_certificate_data +{ + char* hostname; + char* fingerprint; +}; + +struct rdp_certificate_store +{ + FILE* fp; + char* path; + char* file; + rdpSettings* settings; + rdpCertificateData* certificate_data; +}; + +rdpCertificateData* certificate_data_new(char* hostname, char* fingerprint); +void certificate_data_free(rdpCertificateData* certificate_data); +rdpCertificateStore* certificate_store_new(rdpSettings* settings); +void certificate_store_free(rdpCertificateStore* certificate_store); +int certificate_data_match(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data); +void certificate_data_print(rdpCertificateStore* certificate_store, rdpCertificateData* certificate_data); + +void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info); + +rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count); +void certificate_free_x509_certificate_chain(rdpX509CertChain* x509_cert_chain); + +boolean certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s); +boolean certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s); +boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length); + +rdpCertificate* certificate_new(); +void certificate_free(rdpCertificate* certificate); + +rdpKey* key_new(const char *keyfile); +void key_free(rdpKey* key); + +#ifdef WITH_DEBUG_CERTIFICATE +#define DEBUG_CERTIFICATE(fmt, ...) DEBUG_CLASS(CERTIFICATE, fmt, ## __VA_ARGS__) +#else +#define DEBUG_CERTIFICATE(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __CERTIFICATE_H */ diff --git a/libfreerdp-core/channel.c b/libfreerdp-core/channel.c new file mode 100644 index 0000000..e92a0a8 --- /dev/null +++ b/libfreerdp-core/channel.c @@ -0,0 +1,116 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Virtual Channels + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rdp.h" +#include "channel.h" + +boolean freerdp_channel_send(rdpRdp* rdp, uint16 channel_id, uint8* data, int size) +{ + STREAM* s; + uint32 flags; + int i, left; + int chunk_size; + rdpChannel* channel = NULL; + + for (i = 0; i < rdp->settings->num_channels; i++) + { + if (rdp->settings->channels[i].channel_id == channel_id) + { + channel = &rdp->settings->channels[i]; + break; + } + } + + if (channel == NULL) + { + printf("freerdp_channel_send: unknown channel_id %d\n", channel_id); + return false; + } + + flags = CHANNEL_FLAG_FIRST; + left = size; + while (left > 0) + { + s = rdp_send_stream_init(rdp); + + if (left > (int) rdp->settings->vc_chunk_size) + { + chunk_size = rdp->settings->vc_chunk_size; + } + else + { + chunk_size = left; + flags |= CHANNEL_FLAG_LAST; + } + if ((channel->options & CHANNEL_OPTION_SHOW_PROTOCOL)) + { + flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + } + + stream_write_uint32(s, size); + stream_write_uint32(s, flags); + stream_check_size(s, chunk_size); + stream_write(s, data, chunk_size); + + rdp_send(rdp, s, channel_id); + + data += chunk_size; + left -= chunk_size; + flags = 0; + } + + return true; +} + +void freerdp_channel_process(freerdp* instance, STREAM* s, uint16 channel_id) +{ + uint32 length; + uint32 flags; + int chunk_length; + + stream_read_uint32(s, length); + stream_read_uint32(s, flags); + chunk_length = stream_get_left(s); + + IFCALL(instance->ReceiveChannelData, instance, + channel_id, stream_get_tail(s), chunk_length, flags, length); +} + +void freerdp_channel_peer_process(freerdp_peer* client, STREAM* s, uint16 channel_id) +{ + uint32 length; + uint32 flags; + int chunk_length; + + stream_read_uint32(s, length); + stream_read_uint32(s, flags); + chunk_length = stream_get_left(s); + + IFCALL(client->ReceiveChannelData, client, + channel_id, stream_get_tail(s), chunk_length, flags, length); +} diff --git a/libfreerdp-core/channel.h b/libfreerdp-core/channel.h new file mode 100644 index 0000000..3632247 --- /dev/null +++ b/libfreerdp-core/channel.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Virtual Channels + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CHANNEL_H +#define __CHANNEL_H + +boolean freerdp_channel_send(rdpRdp* rdp, uint16 channel_id, uint8* data, int size); +void freerdp_channel_process(freerdp* instance, STREAM* s, uint16 channel_id); +void freerdp_channel_peer_process(freerdp_peer* client, STREAM* s, uint16 channel_id); + +#endif /* __CHANNEL_H */ diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c new file mode 100644 index 0000000..fb4fde3 --- /dev/null +++ b/libfreerdp-core/connection.c @@ -0,0 +1,700 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Connection Sequence + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "per.h" +#include "info.h" +#include "input.h" + +#include "connection.h" + +/** + * Connection Sequence + * client server + * | | + * |-----------------------X.224 Connection Request PDU--------------------->| + * |<----------------------X.224 Connection Confirm PDU----------------------| + * |-------MCS Connect-Initial PDU with GCC Conference Create Request------->| + * |<-----MCS Connect-Response PDU with GCC Conference Create Response-------| + * |------------------------MCS Erect Domain Request PDU-------------------->| + * |------------------------MCS Attach User Request PDU--------------------->| + * |<-----------------------MCS Attach User Confirm PDU----------------------| + * |------------------------MCS Channel Join Request PDU-------------------->| + * |<-----------------------MCS Channel Join Confirm PDU---------------------| + * |----------------------------Security Exchange PDU----------------------->| + * |-------------------------------Client Info PDU-------------------------->| + * |<---------------------License Error PDU - Valid Client-------------------| + * |<-----------------------------Demand Active PDU--------------------------| + * |------------------------------Confirm Active PDU------------------------>| + * |-------------------------------Synchronize PDU-------------------------->| + * |---------------------------Control PDU - Cooperate---------------------->| + * |------------------------Control PDU - Request Control------------------->| + * |--------------------------Persistent Key List PDU(s)-------------------->| + * |--------------------------------Font List PDU--------------------------->| + * |<------------------------------Synchronize PDU---------------------------| + * |<--------------------------Control PDU - Cooperate-----------------------| + * |<-----------------------Control PDU - Granted Control--------------------| + * |<-------------------------------Font Map PDU-----------------------------| + * + */ + +/** + * Establish RDP Connection.\n + * @msdn{cc240452} + * @param rdp RDP module + */ + +boolean rdp_client_connect(rdpRdp* rdp) +{ + boolean status; + uint32 selectedProtocol; + rdpSettings* settings = rdp->settings; + + nego_init(rdp->nego); + nego_set_target(rdp->nego, settings->hostname, settings->port); + nego_set_cookie(rdp->nego, settings->username); + nego_enable_rdp(rdp->nego, settings->rdp_security); + nego_enable_nla(rdp->nego, settings->nla_security); + nego_enable_tls(rdp->nego, settings->tls_security); + + if (nego_connect(rdp->nego) != true) + { + printf("Error: protocol security negotiation failure\n"); + return false; + } + + selectedProtocol = rdp->nego->selected_protocol; + + if ((selectedProtocol & PROTOCOL_TLS) || (selectedProtocol == PROTOCOL_RDP)) + { + if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0))) + settings->autologon = true; + } + + status = false; + if (selectedProtocol & PROTOCOL_NLA) + status = transport_connect_nla(rdp->transport); + else if (selectedProtocol & PROTOCOL_TLS) + status = transport_connect_tls(rdp->transport); + else if (selectedProtocol == PROTOCOL_RDP) /* 0 */ + status = transport_connect_rdp(rdp->transport); + + if (status != true) + return false; + + rdp_set_blocking_mode(rdp, false); + rdp->state = CONNECTION_STATE_NEGO; + rdp->finalize_sc_pdus = 0; + + if (mcs_send_connect_initial(rdp->mcs) != true) + { + printf("Error: unable to send MCS Connect Initial\n"); + return false; + } + + while (rdp->state != CONNECTION_STATE_ACTIVE) + { + if (rdp_check_fds(rdp) < 0) + return false; + } + + return true; +} + +boolean rdp_client_disconnect(rdpRdp* rdp) +{ + return transport_disconnect(rdp->transport); +} + +boolean rdp_client_redirect(rdpRdp* rdp) +{ + rdpSettings* settings = rdp->settings; + rdpRedirection* redirection = rdp->redirection; + + rdp_client_disconnect(rdp); + + mcs_free(rdp->mcs); + nego_free(rdp->nego); + license_free(rdp->license); + transport_free(rdp->transport); + rdp->transport = transport_new(settings); + rdp->license = license_new(rdp); + rdp->nego = nego_new(rdp->transport); + rdp->mcs = mcs_new(rdp->transport); + + rdp->transport->layer = TRANSPORT_LAYER_TCP; + settings->redirected_session_id = redirection->sessionID; + + if (redirection->flags & LB_LOAD_BALANCE_INFO) + { + nego_set_routing_token(rdp->nego, &redirection->loadBalanceInfo); + } + else + { + if (redirection->flags & LB_TARGET_NET_ADDRESS) + { + xfree(settings->hostname); + settings->hostname = xstrdup(redirection->targetNetAddress.ascii); + } + else if (redirection->flags & LB_TARGET_FQDN) + { + xfree(settings->hostname); + settings->hostname = xstrdup(redirection->targetFQDN.ascii); + } + else if (redirection->flags & LB_TARGET_NETBIOS_NAME) + { + xfree(settings->hostname); + settings->hostname = xstrdup(redirection->targetNetBiosName.ascii); + } + } + + if (redirection->flags & LB_USERNAME) + { + xfree(settings->username); + settings->username = xstrdup(redirection->username.ascii); + } + + if (redirection->flags & LB_DOMAIN) + { + xfree(settings->domain); + settings->domain = xstrdup(redirection->domain.ascii); + } + + if (redirection->flags & LB_PASSWORD) + { + settings->password_cookie = &redirection->password_cookie; + } + + return rdp_client_connect(rdp); +} + +static boolean rdp_client_establish_keys(rdpRdp* rdp) +{ + uint8 client_random[CLIENT_RANDOM_LENGTH]; + uint8 crypt_client_random[256 + 8]; + uint32 key_len; + uint8* mod; + uint8* exp; + uint32 length; + STREAM* s; + + if (rdp->settings->encryption == false) + { + /* no RDP encryption */ + return true; + } + + /* encrypt client random */ + memset(crypt_client_random, 0, sizeof(crypt_client_random)); + crypto_nonce(client_random, sizeof(client_random)); + key_len = rdp->settings->server_cert->cert_info.modulus.length; + mod = rdp->settings->server_cert->cert_info.modulus.data; + exp = rdp->settings->server_cert->cert_info.exponent; + crypto_rsa_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random); + + /* send crypt client random to server */ + length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; + s = transport_send_stream_init(rdp->mcs->transport, length); + rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); + rdp_write_security_header(s, SEC_EXCHANGE_PKT); + length = key_len + 8; + stream_write_uint32(s, length); + stream_write(s, crypt_client_random, length); + if (transport_write(rdp->mcs->transport, s) < 0) + { + return false; + } + + /* now calculate encrypt / decrypt and update keys */ + if (!security_establish_keys(client_random, rdp)) + { + return false; + } + + rdp->do_crypt = true; + if (rdp->settings->secure_checksum) + rdp->do_secure_checksum = true; + + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + { + uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; + rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); + rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); + + rdp->fips_hmac = crypto_hmac_new(); + return true; + } + + rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); + rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); + + return true; +} + +static boolean rdp_server_establish_keys(rdpRdp* rdp, STREAM* s) +{ + uint8 client_random[64]; /* Should be only 32 after successfull decryption, but on failure might take up to 64 bytes. */ + uint8 crypt_client_random[256 + 8]; + uint32 rand_len, key_len; + uint16 channel_id, length, sec_flags; + uint8* mod; + uint8* priv_exp; + + if (rdp->settings->encryption == false) + { + /* No RDP Security. */ + return true; + } + + if (!rdp_read_header(rdp, s, &length, &channel_id)) + { + printf("rdp_server_establish_keys: invalid RDP header\n"); + return false; + } + rdp_read_security_header(s, &sec_flags); + if ((sec_flags & SEC_EXCHANGE_PKT) == 0) + { + printf("rdp_server_establish_keys: missing SEC_EXCHANGE_PKT in security header\n"); + return false; + } + stream_read_uint32(s, rand_len); + key_len = rdp->settings->server_key->modulus.length; + if (rand_len != key_len + 8) + { + printf("rdp_server_establish_keys: invalid encrypted client random length\n"); + return false; + } + memset(crypt_client_random, 0, sizeof(crypt_client_random)); + stream_read(s, crypt_client_random, rand_len); + /* 8 zero bytes of padding */ + stream_seek(s, 8); + mod = rdp->settings->server_key->modulus.data; + priv_exp = rdp->settings->server_key->private_exponent.data; + crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random); + + /* now calculate encrypt / decrypt and update keys */ + if (!security_establish_keys(client_random, rdp)) + { + return false; + } + + rdp->do_crypt = true; + if (rdp->settings->secure_checksum) + rdp->do_secure_checksum = true; + + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + { + uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; + rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); + rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); + + rdp->fips_hmac = crypto_hmac_new(); + return true; + } + + rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); + rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); + + return true; +} + +boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_recv_connect_response(rdp->mcs, s)) + { + printf("rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n"); + return false; + } + if (!mcs_send_erect_domain_request(rdp->mcs)) + return false; + if (!mcs_send_attach_user_request(rdp->mcs)) + return false; + + rdp->state = CONNECTION_STATE_MCS_ATTACH_USER; + + return true; +} + +boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_recv_attach_user_confirm(rdp->mcs, s)) + return false; + + if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->user_id)) + return false; + + rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN; + + return true; +} + +boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s) +{ + int i; + uint16 channel_id; + boolean all_joined = true; + + if (!mcs_recv_channel_join_confirm(rdp->mcs, s, &channel_id)) + return false; + + if (!rdp->mcs->user_channel_joined) + { + if (channel_id != rdp->mcs->user_id) + return false; + rdp->mcs->user_channel_joined = true; + + if (!mcs_send_channel_join_request(rdp->mcs, MCS_GLOBAL_CHANNEL_ID)) + return false; + } + else if (!rdp->mcs->global_channel_joined) + { + if (channel_id != MCS_GLOBAL_CHANNEL_ID) + return false; + rdp->mcs->global_channel_joined = true; + + if (rdp->settings->num_channels > 0) + { + if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[0].channel_id)) + return false; + + all_joined = false; + } + } + else + { + for (i = 0; i < rdp->settings->num_channels; i++) + { + if (rdp->settings->channels[i].joined) + continue; + + if (rdp->settings->channels[i].channel_id != channel_id) + return false; + + rdp->settings->channels[i].joined = true; + break; + } + if (i + 1 < rdp->settings->num_channels) + { + if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[i + 1].channel_id)) + return false; + + all_joined = false; + } + } + + if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined) + { + if (!rdp_client_establish_keys(rdp)) + return false; + if (!rdp_send_client_info(rdp)) + return false; + rdp->state = CONNECTION_STATE_LICENSE; + } + + return true; +} + +boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s) +{ + if (!license_recv(rdp->license, s)) + return false; + + if (rdp->license->state == LICENSE_STATE_ABORTED) + { + printf("license connection sequence aborted.\n"); + return false; + } + + if (rdp->license->state == LICENSE_STATE_COMPLETED) + { + rdp->state = CONNECTION_STATE_CAPABILITY; + } + + return true; +} + +boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s) +{ + uint8* mark; + uint16 width; + uint16 height; + + width = rdp->settings->width; + height = rdp->settings->height; + + stream_get_mark(s, mark); + + if (!rdp_recv_demand_active(rdp, s)) + { + stream_set_mark(s, mark); + stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + + if (rdp_recv_out_of_sequence_pdu(rdp, s) != true) + return false; + + return true; + } + + if (rdp->disconnect) + return true; + + if (!rdp_send_confirm_active(rdp)) + return false; + + input_register_client_callbacks(rdp->input); + + /** + * The server may request a different desktop size during Deactivation-Reactivation sequence. + * In this case, the UI should be informed and do actual window resizing at this point. + */ + if (width != rdp->settings->width || height != rdp->settings->height) + { + IFCALL(rdp->update->DesktopResize, rdp->update->context); + } + + rdp->state = CONNECTION_STATE_FINALIZATION; + update_reset_state(rdp->update); + + rdp_client_connect_finalize(rdp); + + return true; +} + +boolean rdp_client_connect_finalize(rdpRdp* rdp) +{ + /** + * [MS-RDPBCGR] 1.3.1.1 - 8. + * The client-to-server PDUs sent during this phase have no dependencies on any of the server-to- + * client PDUs; they may be sent as a single batch, provided that sequencing is maintained. + */ + + if (!rdp_send_client_synchronize_pdu(rdp)) + return false; + if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE)) + return false; + if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL)) + return false; + + rdp->input->SynchronizeEvent(rdp->input, 0); + + if (!rdp_send_client_persistent_key_list_pdu(rdp)) + return false; + if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST)) + return false; + + return true; +} + +boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) +{ + boolean ret; + + transport_set_blocking_mode(rdp->transport, true); + + if (!nego_read_request(rdp->nego, s)) + return false; + + rdp->nego->selected_protocol = 0; + + printf("Requested protocols:"); + if ((rdp->nego->requested_protocols & PROTOCOL_TLS)) + { + printf(" TLS"); + if (rdp->settings->tls_security) + { + printf("(Y)"); + rdp->nego->selected_protocol |= PROTOCOL_TLS; + } + else + printf("(n)"); + } + if ((rdp->nego->requested_protocols & PROTOCOL_NLA)) + { + printf(" NLA"); + if (rdp->settings->nla_security) + { + printf("(Y)"); + rdp->nego->selected_protocol |= PROTOCOL_NLA; + } + else + printf("(n)"); + } + printf(" RDP"); + if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0) + { + printf("(Y)"); + rdp->nego->selected_protocol = PROTOCOL_RDP; + } + else + printf("(n)"); + printf("\n"); + + if (!nego_send_negotiation_response(rdp->nego)) + return false; + + ret = false; + if (rdp->nego->selected_protocol & PROTOCOL_NLA) + ret = transport_accept_nla(rdp->transport); + else if (rdp->nego->selected_protocol & PROTOCOL_TLS) + ret = transport_accept_tls(rdp->transport); + else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */ + ret = transport_accept_rdp(rdp->transport); + + if (!ret) + return false; + + transport_set_blocking_mode(rdp->transport, false); + + rdp->state = CONNECTION_STATE_NEGO; + + return true; +} + +boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s) +{ + int i; + + if (!mcs_recv_connect_initial(rdp->mcs, s)) + return false; + + printf("Accepted client: %s\n", rdp->settings->client_hostname); + printf("Accepted channels:"); + for (i = 0; i < rdp->settings->num_channels; i++) + { + printf(" %s", rdp->settings->channels[i].name); + } + printf("\n"); + + if (!mcs_send_connect_response(rdp->mcs)) + return false; + + rdp->state = CONNECTION_STATE_MCS_CONNECT; + + return true; +} + +boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_recv_erect_domain_request(rdp->mcs, s)) + return false; + + rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN; + + return true; +} + +boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_recv_attach_user_request(rdp->mcs, s)) + return false; + + if (!mcs_send_attach_user_confirm(rdp->mcs)) + return false; + + rdp->state = CONNECTION_STATE_MCS_ATTACH_USER; + + return true; +} + +boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s) +{ + int i; + uint16 channel_id; + boolean all_joined = true; + + if (!mcs_recv_channel_join_request(rdp->mcs, s, &channel_id)) + return false; + + if (!mcs_send_channel_join_confirm(rdp->mcs, channel_id)) + return false; + + if (channel_id == rdp->mcs->user_id) + rdp->mcs->user_channel_joined = true; + else if (channel_id == MCS_GLOBAL_CHANNEL_ID) + rdp->mcs->global_channel_joined = true; + + for (i = 0; i < rdp->settings->num_channels; i++) + { + if (rdp->settings->channels[i].channel_id == channel_id) + rdp->settings->channels[i].joined = true; + + if (!rdp->settings->channels[i].joined) + all_joined = false; + } + + if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined) + rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN; + + return true; +} + +boolean rdp_server_accept_client_keys(rdpRdp* rdp, STREAM* s) +{ + + if (!rdp_server_establish_keys(rdp, s)) + return false; + + rdp->state = CONNECTION_STATE_ESTABLISH_KEYS; + + return true; +} + +boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s) +{ + + if (!rdp_recv_client_info(rdp, s)) + return false; + + if (!license_send_valid_client_error_packet(rdp->license)) + return false; + + rdp->state = CONNECTION_STATE_LICENSE; + + return true; +} + +boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s) +{ + if (!rdp_recv_confirm_active(rdp, s)) + return false; + + rdp->state = CONNECTION_STATE_ACTIVE; + update_reset_state(rdp->update); + + if (!rdp_send_server_synchronize_pdu(rdp)) + return false; + + if (!rdp_send_server_control_cooperate_pdu(rdp)) + return false; + + return true; +} + +boolean rdp_server_reactivate(rdpRdp* rdp) +{ + if (!rdp_send_deactivate_all(rdp)) + return false; + + rdp->state = CONNECTION_STATE_LICENSE; + + if (!rdp_send_demand_active(rdp)) + return false; + + return true; +} + diff --git a/libfreerdp-core/connection.h b/libfreerdp-core/connection.h new file mode 100644 index 0000000..eb5c046 --- /dev/null +++ b/libfreerdp-core/connection.h @@ -0,0 +1,68 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Connection Sequence + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONNECTION_H +#define __CONNECTION_H + +#include "rdp.h" +#include "tpkt.h" +#include "tpdu.h" +#include "nego.h" +#include "mcs.h" +#include "transport.h" +#include "activation.h" + +#include +#include + +enum CONNECTION_STATE +{ + CONNECTION_STATE_INITIAL = 0, + CONNECTION_STATE_NEGO, + CONNECTION_STATE_MCS_CONNECT, + CONNECTION_STATE_MCS_ERECT_DOMAIN, + CONNECTION_STATE_MCS_ATTACH_USER, + CONNECTION_STATE_MCS_CHANNEL_JOIN, + CONNECTION_STATE_ESTABLISH_KEYS, + CONNECTION_STATE_LICENSE, + CONNECTION_STATE_CAPABILITY, + CONNECTION_STATE_FINALIZATION, + CONNECTION_STATE_ACTIVE +}; + +boolean rdp_client_connect(rdpRdp* rdp); +boolean rdp_client_redirect(rdpRdp* rdp); +boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_finalize(rdpRdp* rdp); + +boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_client_keys(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s); +boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s); +boolean rdp_server_reactivate(rdpRdp* rdp); + +#endif /* __CONNECTION_H */ diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c new file mode 100644 index 0000000..e269a21 --- /dev/null +++ b/libfreerdp-core/credssp.c @@ -0,0 +1,670 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Credential Security Support Provider (CredSSP) + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _WIN32 +#include +#endif + +#include +#include "ntlmssp.h" + +#include "credssp.h" +/** + * TSRequest ::= SEQUENCE { + * version [0] INTEGER, + * negoTokens [1] NegoData OPTIONAL, + * authInfo [2] OCTET STRING OPTIONAL, + * pubKeyAuth [3] OCTET STRING OPTIONAL + * } + * + * NegoData ::= SEQUENCE OF NegoDataItem + * + * NegoDataItem ::= SEQUENCE { + * negoToken [0] OCTET STRING + * } + * + * TSCredentials ::= SEQUENCE { + * credType [0] INTEGER, + * credentials [1] OCTET STRING + * } + * + * TSPasswordCreds ::= SEQUENCE { + * domainName [0] OCTET STRING, + * userName [1] OCTET STRING, + * password [2] OCTET STRING + * } + * + * TSSmartCardCreds ::= SEQUENCE { + * pin [0] OCTET STRING, + * cspData [1] TSCspDataDetail, + * userHint [2] OCTET STRING OPTIONAL, + * domainHint [3] OCTET STRING OPTIONAL + * } + * + * TSCspDataDetail ::= SEQUENCE { + * keySpec [0] INTEGER, + * cardName [1] OCTET STRING OPTIONAL, + * readerName [2] OCTET STRING OPTIONAL, + * containerName [3] OCTET STRING OPTIONAL, + * cspName [4] OCTET STRING OPTIONAL + * } + * + */ + +/** + * Initialize NTLMSSP authentication module. + * @param credssp + */ + +int credssp_ntlmssp_init(rdpCredssp* credssp) +{ + freerdp* instance; + NTLMSSP* ntlmssp = credssp->ntlmssp; + rdpSettings* settings = credssp->transport->settings; + instance = (freerdp*) settings->instance; + + if ((settings->password == NULL) || (settings->username == NULL)) + { + if(instance->Authenticate) + { + boolean proceed = instance->Authenticate(instance, + &settings->username, &settings->password, &settings->domain); + if (!proceed) + return 0; + } + } + + if (settings->ntlm_version == 2) + ntlmssp->ntlm_v2 = 1; + + ntlmssp_set_password(ntlmssp, settings->password); + ntlmssp_set_username(ntlmssp, settings->username); + + if (ntlmssp->ntlm_v2) + { + ntlmssp_set_workstation(ntlmssp, "WORKSTATION"); + } + + if (settings->domain != NULL) + { + if (strlen(settings->domain) > 0) + ntlmssp_set_domain(ntlmssp, settings->domain); + } + else + { + ntlmssp_set_domain(ntlmssp, NULL); + } + + ntlmssp_generate_client_challenge(ntlmssp); + ntlmssp_generate_random_session_key(ntlmssp); + ntlmssp_generate_exported_session_key(ntlmssp); + + return 1; +} + +/** + * Get TLS public key. + * @param credssp + */ + +int credssp_get_public_key(rdpCredssp* credssp) +{ + int status; + CryptoCert cert; + + cert = tls_get_certificate(credssp->transport->tls); + + if (cert == NULL) + { + printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n"); + return 0; + } + + if (!tls_verify_certificate(credssp->transport->tls, cert, credssp->transport->settings->hostname)) + tls_disconnect(credssp->transport->tls); + + status = crypto_cert_get_public_key(cert, &credssp->public_key); + crypto_cert_free(cert); + + return status; +} + +/** + * Authenticate with server using CredSSP. + * @param credssp + * @return 1 if authentication is successful + */ + +int credssp_authenticate(rdpCredssp* credssp) +{ + NTLMSSP* ntlmssp = credssp->ntlmssp; + STREAM* s = stream_new(0); + uint8* negoTokenBuffer = (uint8*) xmalloc(2048); + + if (credssp_ntlmssp_init(credssp) == 0) + return 0; + + if (credssp_get_public_key(credssp) == 0) + return 0; + + /* NTLMSSP NEGOTIATE MESSAGE */ + stream_attach(s, negoTokenBuffer, 2048); + ntlmssp_send(ntlmssp, s); + credssp->negoToken.data = stream_get_head(s); + credssp->negoToken.length = stream_get_length(s); + credssp_send(credssp, &credssp->negoToken, NULL, NULL); + + /* NTLMSSP CHALLENGE MESSAGE */ + if (credssp_recv(credssp, &credssp->negoToken, NULL, NULL) < 0) + return -1; + + stream_attach(s, credssp->negoToken.data, credssp->negoToken.length); + ntlmssp_recv(ntlmssp, s); + + freerdp_blob_free(&credssp->negoToken); + + /* NTLMSSP AUTHENTICATE MESSAGE */ + stream_attach(s, negoTokenBuffer, 2048); + ntlmssp_send(ntlmssp, s); + + /* The last NTLMSSP message is sent with the encrypted public key */ + credssp->negoToken.data = stream_get_head(s); + credssp->negoToken.length = stream_get_length(s); + credssp_encrypt_public_key(credssp, &credssp->pubKeyAuth); + credssp_send(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth); + freerdp_blob_free(&credssp->pubKeyAuth); + + /* Encrypted Public Key +1 */ + if (credssp_recv(credssp, &credssp->negoToken, NULL, &credssp->pubKeyAuth) < 0) + return -1; + + if (credssp_verify_public_key(credssp, &credssp->pubKeyAuth) == 0) + { + /* Failed to verify server public key echo */ + return 0; /* DO NOT SEND CREDENTIALS! */ + } + + freerdp_blob_free(&credssp->negoToken); + freerdp_blob_free(&credssp->pubKeyAuth); + + /* Send encrypted credentials */ + credssp_encode_ts_credentials(credssp); + credssp_encrypt_ts_credentials(credssp, &credssp->authInfo); + credssp_send(credssp, NULL, &credssp->authInfo, NULL); + freerdp_blob_free(&credssp->authInfo); + + xfree(s); + + return 1; +} + +/** + * Encrypt TLS public key using CredSSP. + * @param credssp + * @param s + */ + +void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d) +{ + uint8* p; + uint8 signature[16]; + rdpBlob encrypted_public_key; + NTLMSSP *ntlmssp = credssp->ntlmssp; + + freerdp_blob_alloc(d, credssp->public_key.length + 16); + ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature); + +#ifdef WITH_DEBUG_NLA + printf("Public Key (length = %d)\n", credssp->public_key.length); + freerdp_hexdump(credssp->public_key.data, credssp->public_key.length); + printf("\n"); + + printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length); + freerdp_hexdump(encrypted_public_key.data, encrypted_public_key.length); + printf("\n"); + + printf("Signature\n"); + freerdp_hexdump(signature, 16); + printf("\n"); +#endif + + p = (uint8*) d->data; + memcpy(p, signature, 16); /* Message Signature */ + memcpy(&p[16], encrypted_public_key.data, encrypted_public_key.length); /* Encrypted Public Key */ + + freerdp_blob_free(&encrypted_public_key); +} + +/** + * Verify TLS public key using CredSSP. + * @param credssp + * @param s + * @return 1 if verification is successful, 0 otherwise + */ + +int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d) +{ + uint8 *p1, *p2; + uint8* signature; + rdpBlob public_key; + rdpBlob encrypted_public_key; + + signature = d->data; + encrypted_public_key.data = (void*) (signature + 16); + encrypted_public_key.length = d->length - 16; + + ntlmssp_decrypt_message(credssp->ntlmssp, &encrypted_public_key, &public_key, signature); + + p1 = (uint8*) credssp->public_key.data; + p2 = (uint8*) public_key.data; + + p2[0]--; + + if (memcmp(p1, p2, public_key.length) != 0) + { + printf("Could not verify server's public key echo\n"); + return 0; + } + + p2[0]++; + freerdp_blob_free(&public_key); + return 1; +} + +/** + * Encrypt and sign TSCredentials structure. + * @param credssp + * @param s + */ + +void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d) +{ + uint8* p; + uint8 signature[16]; + rdpBlob encrypted_ts_credentials; + NTLMSSP* ntlmssp = credssp->ntlmssp; + + freerdp_blob_alloc(d, credssp->ts_credentials.length + 16); + ntlmssp_encrypt_message(ntlmssp, &credssp->ts_credentials, &encrypted_ts_credentials, signature); + +#ifdef WITH_DEBUG_NLA + printf("TSCredentials (length = %d)\n", credssp->ts_credentials.length); + freerdp_hexdump(credssp->ts_credentials.data, credssp->ts_credentials.length); + printf("\n"); + + printf("Encrypted TSCredentials (length = %d)\n", encrypted_ts_credentials.length); + freerdp_hexdump(encrypted_ts_credentials.data, encrypted_ts_credentials.length); + printf("\n"); + + printf("Signature\n"); + freerdp_hexdump(signature, 16); + printf("\n"); +#endif + + p = (uint8*) d->data; + memcpy(p, signature, 16); /* Message Signature */ + memcpy(&p[16], encrypted_ts_credentials.data, encrypted_ts_credentials.length); /* Encrypted TSCredentials */ + + freerdp_blob_free(&encrypted_ts_credentials); +} + +int credssp_skip_ts_password_creds(rdpCredssp* credssp) +{ + int length; + int ts_password_creds_length = 0; + + length = ber_skip_octet_string(credssp->ntlmssp->domain.length); + length += ber_skip_contextual_tag(length); + ts_password_creds_length += length; + + length = ber_skip_octet_string(credssp->ntlmssp->username.length); + length += ber_skip_contextual_tag(length); + ts_password_creds_length += length; + + length = ber_skip_octet_string(credssp->ntlmssp->password.length); + length += ber_skip_contextual_tag(length); + ts_password_creds_length += length; + + length = ber_skip_sequence(ts_password_creds_length); + + return length; +} + +void credssp_write_ts_password_creds(rdpCredssp* credssp, STREAM* s) +{ + int length; + + length = credssp_skip_ts_password_creds(credssp); + + /* TSPasswordCreds (SEQUENCE) */ + length = ber_get_content_length(length); + ber_write_sequence_tag(s, length); + + /* [0] domainName (OCTET STRING) */ + ber_write_contextual_tag(s, 0, credssp->ntlmssp->domain.length + 2, true); + ber_write_octet_string(s, credssp->ntlmssp->domain.data, credssp->ntlmssp->domain.length); + + /* [1] userName (OCTET STRING) */ + ber_write_contextual_tag(s, 1, credssp->ntlmssp->username.length + 2, true); + ber_write_octet_string(s, credssp->ntlmssp->username.data, credssp->ntlmssp->username.length); + + /* [2] password (OCTET STRING) */ + ber_write_contextual_tag(s, 2, credssp->ntlmssp->password.length + 2, true); + ber_write_octet_string(s, credssp->ntlmssp->password.data, credssp->ntlmssp->password.length); +} + +int credssp_skip_ts_credentials(rdpCredssp* credssp) +{ + int length; + int ts_password_creds_length; + int ts_credentials_length = 0; + + length = ber_skip_integer(0); + length += ber_skip_contextual_tag(length); + ts_credentials_length += length; + + ts_password_creds_length = credssp_skip_ts_password_creds(credssp); + length = ber_skip_octet_string(ts_password_creds_length); + length += ber_skip_contextual_tag(length); + ts_credentials_length += length; + + length = ber_skip_sequence(ts_credentials_length); + + return length; +} + +void credssp_write_ts_credentials(rdpCredssp* credssp, STREAM* s) +{ + int length; + int ts_password_creds_length; + + length = credssp_skip_ts_credentials(credssp); + ts_password_creds_length = credssp_skip_ts_password_creds(credssp); + + /* TSCredentials (SEQUENCE) */ + length = ber_get_content_length(length); + length -= ber_write_sequence_tag(s, length); + + /* [0] credType (INTEGER) */ + length -= ber_write_contextual_tag(s, 0, 3, true); + length -= ber_write_integer(s, 1); + + /* [1] credentials (OCTET STRING) */ + length -= 1; + length -= ber_write_contextual_tag(s, 1, length, true); + length -= ber_write_octet_string_tag(s, ts_password_creds_length); + + credssp_write_ts_password_creds(credssp, s); +} + +/** + * Encode TSCredentials structure. + * @param credssp + */ + +void credssp_encode_ts_credentials(rdpCredssp* credssp) +{ + STREAM* s; + int length; + + s = stream_new(0); + length = credssp_skip_ts_credentials(credssp); + freerdp_blob_alloc(&credssp->ts_credentials, length); + stream_attach(s, credssp->ts_credentials.data, length); + + credssp_write_ts_credentials(credssp, s); + stream_detach(s); + stream_free(s); +} + +int credssp_skip_nego_token(int length) +{ + length = ber_skip_octet_string(length); + length += ber_skip_contextual_tag(length); + return length; +} + +int credssp_skip_nego_tokens(int length) +{ + length = credssp_skip_nego_token(length); + length += ber_skip_sequence_tag(length); + length += ber_skip_sequence_tag(length); + length += ber_skip_contextual_tag(length); + return length; +} + +int credssp_skip_pub_key_auth(int length) +{ + length = ber_skip_octet_string(length); + length += ber_skip_contextual_tag(length); + return length; +} + +int credssp_skip_auth_info(int length) +{ + length = ber_skip_octet_string(length); + length += ber_skip_contextual_tag(length); + return length; +} + +int credssp_skip_ts_request(int length) +{ + length += ber_skip_integer(2); + length += ber_skip_contextual_tag(3); + length += ber_skip_sequence_tag(length); + return length; +} + +/** + * Send CredSSP message. + * @param credssp + * @param negoToken + * @param authInfo + * @param pubKeyAuth + */ + +void credssp_send(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdpBlob* pubKeyAuth) +{ + STREAM* s; + int length; + int ts_request_length; + int nego_tokens_length; + int pub_key_auth_length; + int auth_info_length; + + nego_tokens_length = (negoToken != NULL) ? credssp_skip_nego_tokens(negoToken->length) : 0; + pub_key_auth_length = (pubKeyAuth != NULL) ? credssp_skip_pub_key_auth(pubKeyAuth->length) : 0; + auth_info_length = (authInfo != NULL) ? credssp_skip_auth_info(authInfo->length) : 0; + + length = nego_tokens_length + pub_key_auth_length + auth_info_length; + ts_request_length = credssp_skip_ts_request(length); + + s = stream_new(ts_request_length); + + /* TSRequest */ + length = ber_get_content_length(ts_request_length); + ber_write_sequence_tag(s, length); /* SEQUENCE */ + ber_write_contextual_tag(s, 0, 3, true); /* [0] version */ + ber_write_integer(s, 2); /* INTEGER */ + + /* [1] negoTokens (NegoData) */ + if (nego_tokens_length > 0) + { + length = ber_get_content_length(nego_tokens_length); + length -= ber_write_contextual_tag(s, 1, length, true); /* NegoData */ + length -= ber_write_sequence_tag(s, length); /* SEQUENCE OF NegoDataItem */ + length -= ber_write_sequence_tag(s, length); /* NegoDataItem */ + length -= ber_write_contextual_tag(s, 0, length, true); /* [0] negoToken */ + ber_write_octet_string(s, negoToken->data, length); /* OCTET STRING */ + } + + /* [2] authInfo (OCTET STRING) */ + if (auth_info_length > 0) + { + length = ber_get_content_length(auth_info_length); + length -= ber_write_contextual_tag(s, 2, length, true); + ber_write_octet_string(s, authInfo->data, authInfo->length); + } + + /* [3] pubKeyAuth (OCTET STRING) */ + if (pub_key_auth_length > 0) + { + length = ber_get_content_length(pub_key_auth_length); + length -= ber_write_contextual_tag(s, 3, length, true); + ber_write_octet_string(s, pubKeyAuth->data, length); + } + + transport_write(credssp->transport, s); + stream_free(s); +} + +/** + * Receive CredSSP message. + * @param credssp + * @param negoToken + * @param authInfo + * @param pubKeyAuth + * @return + */ + +int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdpBlob* pubKeyAuth) +{ + STREAM* s; + int length; + int status; + uint32 version; + + s = transport_recv_stream_init(credssp->transport, 2048); + status = transport_read(credssp->transport, s); + + if (status < 0) + return -1; + + /* TSRequest */ + ber_read_sequence_tag(s, &length); + ber_read_contextual_tag(s, 0, &length, true); + ber_read_integer(s, &version); + + /* [1] negoTokens (NegoData) */ + if (ber_read_contextual_tag(s, 1, &length, true) != false) + { + ber_read_sequence_tag(s, &length); /* SEQUENCE OF NegoDataItem */ + ber_read_sequence_tag(s, &length); /* NegoDataItem */ + ber_read_contextual_tag(s, 0, &length, true); /* [0] negoToken */ + ber_read_octet_string(s, &length); /* OCTET STRING */ + freerdp_blob_alloc(negoToken, length); + stream_read(s, negoToken->data, length); + } + + /* [2] authInfo (OCTET STRING) */ + if (ber_read_contextual_tag(s, 2, &length, true) != false) + { + ber_read_octet_string(s, &length); /* OCTET STRING */ + freerdp_blob_alloc(authInfo, length); + stream_read(s, authInfo->data, length); + } + + /* [3] pubKeyAuth (OCTET STRING) */ + if (ber_read_contextual_tag(s, 3, &length, true) != false) + { + ber_read_octet_string(s, &length); /* OCTET STRING */ + freerdp_blob_alloc(pubKeyAuth, length); + stream_read(s, pubKeyAuth->data, length); + } + + return 0; +} + +/** + * Encrypt the given plain text using RC4 and the given key. + * @param key RC4 key + * @param length text length + * @param plaintext plain text + * @param ciphertext cipher text + */ + +void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext) +{ + CryptoRc4 rc4; + + /* Initialize RC4 cipher with key */ + rc4 = crypto_rc4_init((void*) key, 16); + + /* Encrypt plaintext with key */ + crypto_rc4(rc4, length, (void*) plaintext, (void*) ciphertext); + + /* Free RC4 Cipher */ + crypto_rc4_free(rc4); +} + +/** + * Get current time, in tenths of microseconds since midnight of January 1, 1601. + * @param[out] timestamp 64-bit little-endian timestamp + */ + +void credssp_current_time(uint8* timestamp) +{ + uint64 time64; + + /* Timestamp (8 bytes), represented as the number of tenths of microseconds since midnight of January 1, 1601 */ + time64 = time(NULL) + 11644473600LL; /* Seconds since January 1, 1601 */ + time64 *= 10000000; /* Convert timestamp to tenths of a microsecond */ + + memcpy(timestamp, &time64, 8); /* Copy into timestamp in little-endian */ +} + +/** + * Create new CredSSP state machine. + * @param transport + * @return new CredSSP state machine. + */ + +rdpCredssp* credssp_new(rdpTransport* transport) +{ + rdpCredssp* self; + + self = (rdpCredssp*) xzalloc(sizeof(rdpCredssp)); + + if (self != NULL) + { + self->transport = transport; + self->send_seq_num = 0; + self->ntlmssp = ntlmssp_new(); + self->settings = transport->settings; + } + + return self; +} + +/** + * Free CredSSP state machine. + * @param credssp + */ + +void credssp_free(rdpCredssp* credssp) +{ + if (credssp != NULL) + { + freerdp_blob_free(&credssp->public_key); + freerdp_blob_free(&credssp->ts_credentials); + + ntlmssp_free(credssp->ntlmssp); + xfree(credssp); + } +} diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h new file mode 100644 index 0000000..3277425 --- /dev/null +++ b/libfreerdp-core/credssp.h @@ -0,0 +1,67 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Credential Security Support Provider (CredSSP) + * + * Copyright 2010 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CREDSSP_H +#define __CREDSSP_H + +typedef struct rdp_credssp rdpCredssp; + +#include "tls.h" +#include "ber.h" +#include "crypto.h" +#include "transport.h" +#include +#include +#include +#include +#include + +#include "ntlmssp.h" + +struct rdp_credssp +{ + rdpBlob negoToken; + rdpBlob pubKeyAuth; + rdpBlob authInfo; + int send_seq_num; + rdpBlob public_key; + rdpBlob ts_credentials; + rdpSettings* settings; + CryptoRc4 rc4_seal_state; + struct _NTLMSSP *ntlmssp; + struct rdp_transport* transport; +}; + +int credssp_authenticate(rdpCredssp* credssp); + +void credssp_send(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdpBlob* pubKeyAuth); +int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdpBlob* pubKeyAuth); + +void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d); +void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d); +int credssp_verify_public_key(rdpCredssp* credssp, rdpBlob* d); +void credssp_encode_ts_credentials(rdpCredssp* credssp); + +void credssp_current_time(uint8* timestamp); +void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext); + +rdpCredssp* credssp_new(rdpTransport* transport); +void credssp_free(rdpCredssp* credssp); + +#endif /* __CREDSSP_H */ diff --git a/libfreerdp-core/crypto.c b/libfreerdp-core/crypto.c new file mode 100644 index 0000000..2d24da5 --- /dev/null +++ b/libfreerdp-core/crypto.c @@ -0,0 +1,541 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Cryptographic Abstraction Layer + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "crypto.h" + +CryptoSha1 crypto_sha1_init(void) +{ + CryptoSha1 sha1 = xmalloc(sizeof(*sha1)); + SHA1_Init(&sha1->sha_ctx); + return sha1; +} + +void crypto_sha1_update(CryptoSha1 sha1, const uint8* data, uint32 length) +{ + SHA1_Update(&sha1->sha_ctx, data, length); +} + +void crypto_sha1_final(CryptoSha1 sha1, uint8* out_data) +{ + SHA1_Final(out_data, &sha1->sha_ctx); + xfree(sha1); +} + +CryptoMd5 crypto_md5_init(void) +{ + CryptoMd5 md5 = xmalloc(sizeof(*md5)); + MD5_Init(&md5->md5_ctx); + return md5; +} + +void crypto_md5_update(CryptoMd5 md5, const uint8* data, uint32 length) +{ + MD5_Update(&md5->md5_ctx, data, length); +} + +void crypto_md5_final(CryptoMd5 md5, uint8* out_data) +{ + MD5_Final(out_data, &md5->md5_ctx); + xfree(md5); +} + +CryptoRc4 crypto_rc4_init(const uint8* key, uint32 length) +{ + CryptoRc4 rc4 = xmalloc(sizeof(*rc4)); + RC4_set_key(&rc4->rc4_key, length, key); + return rc4; +} + +void crypto_rc4(CryptoRc4 rc4, uint32 length, const uint8* in_data, uint8* out_data) +{ + RC4(&rc4->rc4_key, length, in_data, out_data); +} + +void crypto_rc4_free(CryptoRc4 rc4) +{ + xfree(rc4); +} + +CryptoDes3 crypto_des3_encrypt_init(const uint8* key, const uint8* ivec) +{ + CryptoDes3 des3 = xmalloc(sizeof(*des3)); + EVP_CIPHER_CTX_init(&des3->des3_ctx); + EVP_EncryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec); + EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0); + return des3; +} + +CryptoDes3 crypto_des3_decrypt_init(const uint8* key, const uint8* ivec) +{ + CryptoDes3 des3 = xmalloc(sizeof(*des3)); + EVP_CIPHER_CTX_init(&des3->des3_ctx); + EVP_DecryptInit_ex(&des3->des3_ctx, EVP_des_ede3_cbc(), NULL, key, ivec); + EVP_CIPHER_CTX_set_padding(&des3->des3_ctx, 0); + return des3; +} + +void crypto_des3_encrypt(CryptoDes3 des3, uint32 length, const uint8* in_data, uint8* out_data) +{ + int len; + EVP_EncryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length); +} + +void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, const uint8* in_data, uint8* out_data) +{ + int len; + EVP_DecryptUpdate(&des3->des3_ctx, out_data, &len, in_data, length); + + if (length != len) + abort(); /* TODO */ +} + +void crypto_des3_free(CryptoDes3 des3) +{ + EVP_CIPHER_CTX_cleanup(&des3->des3_ctx); + xfree(des3); +} + +CryptoHmac crypto_hmac_new(void) +{ + CryptoHmac hmac = xmalloc(sizeof(*hmac)); + HMAC_CTX_init(&hmac->hmac_ctx); + return hmac; +} + +void crypto_hmac_sha1_init(CryptoHmac hmac, const uint8* data, uint32 length) +{ + HMAC_Init_ex(&hmac->hmac_ctx, data, length, EVP_sha1(), NULL); +} + +void crypto_hmac_update(CryptoHmac hmac, const uint8* data, uint32 length) +{ + HMAC_Update(&hmac->hmac_ctx, data, length); +} + +void crypto_hmac_final(CryptoHmac hmac, uint8* out_data, uint32 length) +{ + HMAC_Final(&hmac->hmac_ctx, out_data, &length); +} + +void crypto_hmac_free(CryptoHmac hmac) +{ + HMAC_CTX_cleanup(&hmac->hmac_ctx); + xfree(hmac); +} + +CryptoCert crypto_cert_read(uint8* data, uint32 length) +{ + CryptoCert cert = xmalloc(sizeof(*cert)); + /* this will move the data pointer but we don't care, we don't use it again */ + cert->px509 = d2i_X509(NULL, (D2I_X509_CONST uint8 **) &data, length); + return cert; +} + +void crypto_cert_free(CryptoCert cert) +{ + X509_free(cert->px509); + xfree(cert); +} + +boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key) +{ + uint8* p; + int length; + boolean status = true; + EVP_PKEY* pkey = NULL; + + pkey = X509_get_pubkey(cert->px509); + + if (!pkey) + { + printf("crypto_cert_get_public_key: X509_get_pubkey() failed\n"); + status = false; + goto exit; + } + + length = i2d_PublicKey(pkey, NULL); + + if (length < 1) + { + printf("crypto_cert_get_public_key: i2d_PublicKey() failed\n"); + status = false; + goto exit; + } + + freerdp_blob_alloc(public_key, length); + p = (uint8*) public_key->data; + i2d_PublicKey(pkey, &p); + +exit: + if (pkey) + EVP_PKEY_free(pkey); + + return status; +} + +/* + * Terminal Services Signing Keys. + * Yes, Terminal Services Private Key is publicly available. + */ + +const uint8 tssk_modulus[] = +{ + 0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9, + 0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb, + 0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2, + 0xd7, 0xb7, 0x6b, 0x9a, 0xf2, 0x52, 0x45, 0x95, + 0xce, 0x63, 0x65, 0x6b, 0x58, 0x3a, 0xfe, 0xef, + 0x7c, 0xe7, 0xbf, 0xfe, 0x3d, 0xf6, 0x5c, 0x7d, + 0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb, + 0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87 +}; + +const uint8 tssk_privateExponent[] = +{ + 0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55, + 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8, + 0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94, + 0xcf, 0x92, 0xcc, 0x33, 0x99, 0xe8, 0x08, 0x60, + 0x17, 0x9a, 0x12, 0x9f, 0x24, 0xdd, 0xb1, 0x24, + 0x99, 0xc7, 0x3a, 0xb8, 0x0a, 0x7b, 0x0d, 0xdd, + 0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3, + 0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f +}; + +const uint8 tssk_exponent[] = +{ + 0x5b, 0x7b, 0x88, 0xc0 +}; + +static void crypto_rsa_common(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, int exponent_size, uint8* output) +{ + BN_CTX* ctx; + int output_length; + uint8* input_reverse; + uint8* modulus_reverse; + uint8* exponent_reverse; + BIGNUM mod, exp, x, y; + + input_reverse = (uint8*) xmalloc(2 * key_length + exponent_size); + modulus_reverse = input_reverse + key_length; + exponent_reverse = modulus_reverse + key_length; + + memcpy(modulus_reverse, modulus, key_length); + crypto_reverse(modulus_reverse, key_length); + memcpy(exponent_reverse, exponent, exponent_size); + crypto_reverse(exponent_reverse, exponent_size); + memcpy(input_reverse, input, length); + crypto_reverse(input_reverse, length); + + ctx = BN_CTX_new(); + BN_init(&mod); + BN_init(&exp); + BN_init(&x); + BN_init(&y); + + BN_bin2bn(modulus_reverse, key_length, &mod); + BN_bin2bn(exponent_reverse, exponent_size, &exp); + BN_bin2bn(input_reverse, length, &x); + BN_mod_exp(&y, &x, &exp, &mod, ctx); + + output_length = BN_bn2bin(&y, output); + crypto_reverse(output, output_length); + + if (output_length < (int) key_length) + memset(output + output_length, 0, key_length - output_length); + + BN_free(&y); + BN_clear_free(&x); + BN_free(&exp); + BN_free(&mod); + BN_CTX_free(ctx); + xfree(input_reverse); +} + +static void crypto_rsa_public(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output) +{ + crypto_rsa_common(input, length, key_length, modulus, exponent, EXPONENT_MAX_SIZE, output); +} + +static void crypto_rsa_private(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output) +{ + + crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output); +} + +void crypto_rsa_public_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output) +{ + + crypto_rsa_public(input, length, key_length, modulus, exponent, output); +} + +void crypto_rsa_public_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output) +{ + + crypto_rsa_public(input, length, key_length, modulus, exponent, output); +} + +void crypto_rsa_private_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output) +{ + + crypto_rsa_private(input, length, key_length, modulus, private_exponent, output); +} + +void crypto_rsa_private_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output) +{ + + crypto_rsa_private(input, length, key_length, modulus, private_exponent, output); +} + +void crypto_rsa_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output) +{ + + crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output); +} + +void crypto_reverse(uint8* data, int length) +{ + int i, j; + uint8 temp; + + for (i = 0, j = length - 1; i < j; i++, j--) + { + temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } +} + +void crypto_nonce(uint8* nonce, int size) +{ + RAND_bytes((void*) nonce, size); +} + +char* crypto_cert_fingerprint(X509* xcert) +{ + int i = 0; + char* p; + char* fp_buffer; + uint32 fp_len; + uint8 fp[EVP_MAX_MD_SIZE]; + + X509_digest(xcert, EVP_sha1(), fp, &fp_len); + + fp_buffer = (char*) xzalloc(3 * fp_len); + p = fp_buffer; + + for (i = 0; i < (int) (fp_len - 1); i++) + { + sprintf(p, "%02x:", fp[i]); + p = &fp_buffer[i * 3]; + } + sprintf(p, "%02x", fp[i]); + + return fp_buffer; +} + +char* crypto_print_name(X509_NAME* name) +{ + char* buffer = NULL; + BIO* outBIO = BIO_new(BIO_s_mem()); + + if (X509_NAME_print_ex(outBIO, name, 0, XN_FLAG_ONELINE) > 0) + { + unsigned long size = BIO_number_written(outBIO); + buffer = xzalloc(size + 1); + memset(buffer, 0, size + 1); + BIO_read(outBIO, buffer, size); + } + + BIO_free(outBIO); + return buffer; +} + + +char* crypto_cert_subject(X509* xcert) +{ + return crypto_print_name(X509_get_subject_name(xcert)); +} + +char* crypto_cert_subject_common_name(X509* xcert, int* length) +{ + int index; + uint8* common_name; + X509_NAME* subject_name; + X509_NAME_ENTRY* entry; + ASN1_STRING* entry_data; + + subject_name = X509_get_subject_name(xcert); + + if (subject_name == NULL) + return NULL; + + index = X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1); + + if (index < 0) + return NULL; + + entry = X509_NAME_get_entry(subject_name, index); + + if (entry == NULL) + return NULL; + + entry_data = X509_NAME_ENTRY_get_data(entry); + + if (entry_data == NULL) + return NULL; + + *length = ASN1_STRING_to_UTF8(&common_name, entry_data); + + if (*length < 0) + return NULL; + + return (char*) common_name; +} + +char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths) +{ + int index; + int length; + char** strings; + uint8* string; + int num_subject_alt_names; + GENERAL_NAMES* subject_alt_names; + GENERAL_NAME* subject_alt_name; + + *count = 0; + subject_alt_names = X509_get_ext_d2i(xcert, NID_subject_alt_name, 0, 0); + + if (!subject_alt_names) + return NULL; + + num_subject_alt_names = sk_GENERAL_NAME_num(subject_alt_names); + strings = (char**) malloc(sizeof(char*) * num_subject_alt_names); + *lengths = (int*) malloc(sizeof(int*) * num_subject_alt_names); + + for (index = 0; index < num_subject_alt_names; ++index) + { + subject_alt_name = sk_GENERAL_NAME_value(subject_alt_names, index); + + if (subject_alt_name->type == GEN_DNS) + { + length = ASN1_STRING_to_UTF8(&string, subject_alt_name->d.dNSName); + strings[*count] = (char*) string; + *lengths[*count] = length; + (*count)++; + } + } + + if (*count < 1) + return NULL; + + return strings; +} + +char* crypto_cert_issuer(X509* xcert) +{ + return crypto_print_name(X509_get_issuer_name(xcert)); +} + +boolean x509_verify_certificate(CryptoCert cert, char* certificate_store_path) +{ + X509_STORE_CTX* csc; + boolean status = false; + X509_STORE* cert_ctx = NULL; + X509_LOOKUP* lookup = NULL; + X509* xcert = cert->px509; + + cert_ctx = X509_STORE_new(); + + if (cert_ctx == NULL) + goto end; + + OpenSSL_add_all_algorithms(); + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); + + if (lookup == NULL) + goto end; + + lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); + + if (lookup == NULL) + goto end; + + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + if (certificate_store_path != NULL) + { + X509_LOOKUP_add_dir(lookup, certificate_store_path, X509_FILETYPE_ASN1); + } + + csc = X509_STORE_CTX_new(); + + if (csc == NULL) + goto end; + + X509_STORE_set_flags(cert_ctx, 0); + + if (!X509_STORE_CTX_init(csc, cert_ctx, xcert, 0)) + goto end; + + if (X509_verify_cert(csc) == 1) + status = true; + + X509_STORE_CTX_free(csc); + X509_STORE_free(cert_ctx); + +end: + return status; +} + +rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname) +{ + char* fp; + rdpCertificateData* certdata; + + fp = crypto_cert_fingerprint(xcert); + certdata = certificate_data_new(hostname, fp); + xfree(fp); + + return certdata; +} + +void crypto_cert_print_info(X509* xcert) +{ + char* fp; + char* issuer; + char* subject; + + subject = crypto_cert_subject(xcert); + issuer = crypto_cert_issuer(xcert); + fp = crypto_cert_fingerprint(xcert); + + printf("Certificate details:\n"); + printf("\tSubject: %s\n", subject); + printf("\tIssuer: %s\n", issuer); + printf("\tThumbprint: %s\n", fp); + printf("The above X.509 certificate could not be verified, possibly because you do not have " + "the CA certificate in your certificate store, or the certificate has expired. " + "Please look at the documentation on how to create local certificate store for a private CA.\n"); + + xfree(subject); + xfree(issuer); + xfree(fp); +} + diff --git a/libfreerdp-core/crypto.h b/libfreerdp-core/crypto.h new file mode 100644 index 0000000..15afca8 --- /dev/null +++ b/libfreerdp-core/crypto.h @@ -0,0 +1,140 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Cryptographic Abstraction Layer + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CRYPTO_H +#define __CRYPTO_H + +#ifdef _WIN32 +#include "tcp.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) +#define D2I_X509_CONST const +#else +#define D2I_X509_CONST +#endif + +#define EXPONENT_MAX_SIZE 4 +#define MODULUS_MAX_SIZE 256 + +#include +#include +#include + +struct crypto_sha1_struct +{ + SHA_CTX sha_ctx; +}; + +struct crypto_md5_struct +{ + MD5_CTX md5_ctx; +}; + +struct crypto_rc4_struct +{ + RC4_KEY rc4_key; +}; + +struct crypto_des3_struct +{ + EVP_CIPHER_CTX des3_ctx; +}; + +struct crypto_hmac_struct +{ + HMAC_CTX hmac_ctx; +}; + +struct crypto_cert_struct +{ + X509 * px509; +}; + +#define CRYPTO_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH +typedef struct crypto_sha1_struct* CryptoSha1; +CryptoSha1 crypto_sha1_init(void); +void crypto_sha1_update(CryptoSha1 sha1, const uint8* data, uint32 length); +void crypto_sha1_final(CryptoSha1 sha1, uint8* out_data); + +#define CRYPTO_MD5_DIGEST_LENGTH MD5_DIGEST_LENGTH +typedef struct crypto_md5_struct* CryptoMd5; +CryptoMd5 crypto_md5_init(void); +void crypto_md5_update(CryptoMd5 md5, const uint8* data, uint32 length); +void crypto_md5_final(CryptoMd5 md5, uint8* out_data); + +typedef struct crypto_rc4_struct* CryptoRc4; +CryptoRc4 crypto_rc4_init(const uint8* key, uint32 length); +void crypto_rc4(CryptoRc4 rc4, uint32 length, const uint8* in_data, uint8* out_data); +void crypto_rc4_free(CryptoRc4 rc4); + +typedef struct crypto_des3_struct* CryptoDes3; +CryptoDes3 crypto_des3_encrypt_init(const uint8* key, const uint8* ivec); +CryptoDes3 crypto_des3_decrypt_init(const uint8* key, const uint8* ivec); +void crypto_des3_encrypt(CryptoDes3 des3, uint32 length, const uint8 *in_data, uint8 *out_data); +void crypto_des3_decrypt(CryptoDes3 des3, uint32 length, const uint8 *in_data, uint8* out_data); +void crypto_des3_free(CryptoDes3 des3); + +typedef struct crypto_hmac_struct* CryptoHmac; +CryptoHmac crypto_hmac_new(void); +void crypto_hmac_sha1_init(CryptoHmac hmac, const uint8 *data, uint32 length); +void crypto_hmac_update(CryptoHmac hmac, const uint8 *data, uint32 length); +void crypto_hmac_final(CryptoHmac hmac, uint8 *out_data, uint32 length); +void crypto_hmac_free(CryptoHmac hmac); + +typedef struct crypto_cert_struct* CryptoCert; + +#include "certificate.h" + +CryptoCert crypto_cert_read(uint8* data, uint32 length); +char* crypto_cert_fingerprint(X509* xcert); +char* crypto_cert_subject(X509* xcert); +char* crypto_cert_subject_common_name(X509* xcert, int* length); +char** crypto_cert_subject_alt_name(X509* xcert, int* count, int** lengths); +char* crypto_cert_issuer(X509* xcert); +void crypto_cert_print_info(X509* xcert); +void crypto_cert_free(CryptoCert cert); + +boolean x509_verify_certificate(CryptoCert cert, char* certificate_store_path); +rdpCertificateData* crypto_get_certificate_data(X509* xcert, char* hostname); +boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key); + +#define TSSK_KEY_LENGTH 64 +extern const uint8 tssk_modulus[]; +extern const uint8 tssk_privateExponent[]; +extern const uint8 tssk_exponent[]; + +void crypto_rsa_public_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output); +void crypto_rsa_public_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output); +void crypto_rsa_private_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output); +void crypto_rsa_private_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output); +void crypto_reverse(uint8* data, int length); +void crypto_nonce(uint8* nonce, int size); + +#endif /* __CRYPTO_H */ diff --git a/libfreerdp-core/errinfo.c b/libfreerdp-core/errinfo.c new file mode 100644 index 0000000..bd6899c --- /dev/null +++ b/libfreerdp-core/errinfo.c @@ -0,0 +1,453 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Error Info + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "errinfo.h" + +/* Protocol-independent codes */ + +#define ERRINFO_RPC_INITIATED_DISCONNECT_STRING \ + "The disconnection was initiated by an administrative tool on the server in another session." + +#define ERRINFO_RPC_INITIATED_LOGOFF_STRING \ + "The disconnection was due to a forced logoff initiated by an administrative tool on the server in another session." + +#define ERRINFO_IDLE_TIMEOUT_STRING \ + "The idle session limit timer on the server has elapsed." + +#define ERRINFO_LOGON_TIMEOUT_STRING \ + "The active session limit timer on the server has elapsed." + +#define ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION_STRING \ + "Another user connected to the server, forcing the disconnection of the current connection." + +#define ERRINFO_OUT_OF_MEMORY_STRING \ + "The server ran out of available memory resources." + +#define ERRINFO_SERVER_DENIED_CONNECTION_STRING \ + "The server denied the connection." + +#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES_STRING \ + "The user cannot connect to the server due to insufficient access privileges." + +#define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED_STRING \ + "The server does not accept saved user credentials and requires that the user enter their credentials for each connection." + +#define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER_STRING \ + "The disconnection was initiated by an administrative tool on the server running in the user's session." + +/* Protocol-independent licensing codes */ + +#define ERRINFO_LICENSE_INTERNAL_STRING \ + "An internal error has occurred in the Terminal Services licensing component." + +#define ERRINFO_LICENSE_NO_LICENSE_SERVER_STRING \ + "A Remote Desktop License Server ([MS-RDPELE] section 1.1) could not be found to provide a license." + +#define ERRINFO_LICENSE_NO_LICENSE_STRING \ + "There are no Client Access Licenses ([MS-RDPELE] section 1.1) available for the target remote computer." + +#define ERRINFO_LICENSE_BAD_CLIENT_MSG_STRING \ + "The remote computer received an invalid licensing message from the client." + +#define ERRINFO_LICENSE_HWID_DOESNT_MATCH_LICENSE_STRING \ + "The Client Access License ([MS-RDPELE] section 1.1) stored by the client has been modified." + +#define ERRINFO_LICENSE_BAD_CLIENT_LICENSE_STRING \ + "The Client Access License ([MS-RDPELE] section 1.1) stored by the client is in an invalid format." + +#define ERRINFO_LICENSE_CANT_FINISH_PROTOCOL_STRING \ + "Network problems have caused the licensing protocol ([MS-RDPELE] section 1.3.3) to be terminated." + +#define ERRINFO_LICENSE_CLIENT_ENDED_PROTOCOL_STRING \ + "The client prematurely ended the licensing protocol ([MS-RDPELE] section 1.3.3)." + +#define ERRINFO_LICENSE_BAD_CLIENT_ENCRYPTION_STRING \ + "A licensing message ([MS-RDPELE] sections 2.2 and 5.1) was incorrectly encrypted." + +#define ERRINFO_LICENSE_CANT_UPGRADE_LICENSE_STRING \ + "The Client Access License ([MS-RDPELE] section 1.1) stored by the client could not be upgraded or renewed." + +#define ERRINFO_LICENSE_NO_REMOTE_CONNECTIONS_STRING \ + "The remote computer is not licensed to accept remote connections." + +/* RDP specific codes */ + +#define ERRINFO_UNKNOWN_DATA_PDU_TYPE_STRING \ + "Unknown pduType2 field in a received Share Data Header (section 2.2.8.1.1.1.2)." + +#define ERRINFO_UNKNOWN_PDU_TYPE_STRING \ + "Unknown pduType field in a received Share Control Header (section 2.2.8.1.1.1.1)." + +#define ERRINFO_DATA_PDU_SEQUENCE_STRING \ + "An out-of-sequence Slow-Path Data PDU (section 2.2.8.1.1.1.1) has been received." + +#define ERRINFO_CONTROL_PDU_SEQUENCE_STRING \ + "An out-of-sequence Slow-Path Non-Data PDU (section 2.2.8.1.1.1.1) has been received." + +#define ERRINFO_INVALID_CONTROL_PDU_ACTION_STRING \ + "A Control PDU (sections 2.2.1.15 and 2.2.1.16) has been received with an invalid action field." + +#define ERRINFO_INVALID_INPUT_PDU_TYPE_STRING \ + "(a) A Slow-Path Input Event (section 2.2.8.1.1.3.1.1) has been received with an invalid messageType field.\n" \ + "(b) A Fast-Path Input Event (section 2.2.8.1.2.2) has been received with an invalid eventCode field." + +#define ERRINFO_INVALID_INPUT_PDU_MOUSE_STRING \ + "(a) A Slow-Path Mouse Event (section 2.2.8.1.1.3.1.1.3) or Extended Mouse Event " \ + "(section 2.2.8.1.1.3.1.1.4) has been received with an invalid pointerFlags field.\n" \ + "(b) A Fast-Path Mouse Event (section 2.2.8.1.2.2.3) or Fast-Path Extended Mouse Event " \ + "(section 2.2.8.1.2.2.4) has been received with an invalid pointerFlags field." + +#define ERRINFO_INVALID_REFRESH_RECT_PDU_STRING \ + "An invalid Refresh Rect PDU (section 2.2.11.2) has been received." + +#define ERRINFO_CREATE_USER_DATA_FAILED_STRING \ + "The server failed to construct the GCC Conference Create Response user data (section 2.2.1.4)." + +#define ERRINFO_CONNECT_FAILED_STRING \ + "Processing during the Channel Connection phase of the RDP Connection Sequence " \ + "(see section 1.3.1.1 for an overview of the RDP Connection Sequence phases) has failed." + +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_SHAREID_STRING \ + "A Confirm Active PDU (section 2.2.1.13.2) was received from the client with an invalid shareId field." + +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_ORIGINATOR_STRING \ + "A Confirm Active PDU (section 2.2.1.13.2) was received from the client with an invalid originatorId field." + +#define ERRINFO_PERSISTENT_KEY_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process a Persistent Key List PDU (section 2.2.1.17)." + +#define ERRINFO_PERSISTENT_KEY_PDU_ILLEGAL_FIRST_STRING \ + "A Persistent Key List PDU (section 2.2.1.17) marked as PERSIST_PDU_FIRST (0x01) was received after the reception " \ + "of a prior Persistent Key List PDU also marked as PERSIST_PDU_FIRST." + +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_TOTAL_KEYS_STRING \ + "A Persistent Key List PDU (section 2.2.1.17) was received which specified a total number of bitmap cache entries larger than 262144." + +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_CACHE_KEYS_STRING \ + "A Persistent Key List PDU (section 2.2.1.17) was received which specified an invalid total number of keys for a bitmap cache " \ + "(the number of entries that can be stored within each bitmap cache is specified in the Revision 1 or 2 Bitmap Cache Capability Set " \ + "(section 2.2.7.1.4) that is sent from client to server)." + +#define ERRINFO_INPUT_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process Input Event PDU Data (section 2.2.8.1.1.3.1) or a Fast-Path Input Event PDU (section 2.2.8.1.2)." \ + +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process the shareDataHeader, NumInfoBlocks, " \ + "Pad1, and Pad2 fields of the Bitmap Cache Error PDU Data ([MS-RDPEGDI] section 2.2.2.3.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT_STRING \ + "(a) The dataSignature field of the Fast-Path Input Event PDU (section 2.2.8.1.2) does not contain enough data.\n" \ + "(b) The fipsInformation and dataSignature fields of the Fast-Path Input Event PDU (section 2.2.8.1.2) do not contain enough data." + +#define ERRINFO_VCHANNEL_DATA_TOO_SHORT_STRING \ + "(a) There is not enough data in the Client Network Data (section 2.2.1.3.4) to read the virtual channel configuration data.\n" \ + "(b) There is not enough data to read a complete Channel PDU Header (section 2.2.6.1.1)." + +#define ERRINFO_SHARE_DATA_TOO_SHORT_STRING \ + "(a) There is not enough data to process Control PDU Data (section 2.2.1.15.1).\n" \ + "(b) There is not enough data to read a complete Share Control Header (section 2.2.8.1.1.1.1).\n" \ + "(c) There is not enough data to read a complete Share Data Header (section 2.2.8.1.1.1.2) of a Slow-Path Data PDU (section 2.2.8.1.1.1.1).\n" \ + "(d) There is not enough data to process Font List PDU Data (section 2.2.1.18.1)." + +#define ERRINFO_BAD_SUPPRESS_OUTPUT_PDU_STRING \ + "(a) There is not enough data to process Suppress Output PDU Data (section 2.2.11.3.1).\n" \ + "(b) The allowDisplayUpdates field of the Suppress Output PDU Data (section 2.2.11.3.1) is invalid." + +#define ERRINFO_CONFIRM_ACTIVE_PDU_TOO_SHORT_STRING \ + "(a) There is not enough data to read the shareControlHeader, shareId, originatorId, lengthSourceDescriptor, " \ + "and lengthCombinedCapabilities fields of the Confirm Active PDU Data (section 2.2.1.13.2.1).\n" \ + "(b) There is not enough data to read the sourceDescriptor, numberCapabilities, pad2Octets, and capabilitySets " \ + "fields of the Confirm Active PDU Data (section 2.2.1.13.2.1)." + +#define ERRINFO_CAPABILITY_SET_TOO_SMALL_STRING \ + "There is not enough data to read the capabilitySetType and the lengthCapability fields in a received Capability Set (section 2.2.1.13.1.1.1)." + +#define ERRINFO_CAPABILITY_SET_TOO_LARGE_STRING \ + "A Capability Set (section 2.2.1.13.1.1.1) has been received with a lengthCapability " \ + "field that contains a value greater than the total length of the data received." + +#define ERRINFO_NO_CURSOR_CACHE_STRING \ + "(a) Both the colorPointerCacheSize and pointerCacheSize fields in the Pointer Capability Set (section 2.2.7.1.5) are set to zero.\n" \ + "(b) The pointerCacheSize field in the Pointer Capability Set (section 2.2.7.1.5) is not present, and the colorPointerCacheSize field is set to zero." + +#define ERRINFO_BAD_CAPABILITIES_STRING \ + "The capabilities received from the client in the Confirm Active PDU (section 2.2.1.13.2) were not accepted by the server." + +#define ERRINFO_VIRTUAL_CHANNEL_DECOMPRESSION_STRING \ + "An error occurred while using the bulk compressor (section 3.1.8 and [MS-RDPEGDI] section 3.1.8) to decompress a Virtual Channel PDU (section 2.2.6.1)" + +#define ERRINFO_INVALID_VC_COMPRESSION_TYPE_STRING \ + "An invalid bulk compression package was specified in the flags field of the Channel PDU Header (section 2.2.6.1.1)." + +#define ERRINFO_INVALID_CHANNEL_ID_STRING \ + "An invalid MCS channel ID was specified in the mcsPdu field of the Virtual Channel PDU (section 2.2.6.1)." + +#define ERRINFO_VCHANNELS_TOO_MANY_STRING \ + "The client requested more than the maximum allowed 31 static virtual channels in the Client Network Data (section 2.2.1.3.4)." + +#define ERRINFO_REMOTEAPP_NOT_ENABLED_STRING \ + "The INFO_RAIL flag (0x00008000) MUST be set in the flags field of the Info Packet (section 2.2.1.11.1.1) " \ + "as the session on the remote server can only host remote applications." + +#define ERRINFO_CACHE_CAP_NOT_SET_STRING \ + "The client sent a Persistent Key List PDU (section 2.2.1.17) without including the prerequisite Revision 2 Bitmap Cache " \ + "Capability Set (section 2.2.7.1.4.2) in the Confirm Active PDU (section 2.2.1.13.2)." + +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH2_STRING \ + "The NumInfoBlocks field in the Bitmap Cache Error PDU Data is inconsistent with the amount of data in the " \ + "Info field ([MS-RDPEGDI] section 2.2.2.3.1.1)." + +#define ERRINFO_OFFSCREEN_CACHE_ERROR_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process an Offscreen Bitmap Cache Error PDU ([MS-RDPEGDI] section 2.2.2.3.2)." + +#define ERRINFO_DRAWNINEGRID_CACHE_ERROR_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process a DrawNineGrid Cache Error PDU ([MS-RDPEGDI] section 2.2.2.3.3)." + +#define ERRINFO_GDIPLUS_PDU_BAD_LENGTH_STRING \ + "There is not enough data to process a GDI+ Error PDU ([MS-RDPEGDI] section 2.2.2.3.4)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT2_STRING \ + "There is not enough data to read a Basic Security Header (section 2.2.8.1.1.2.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT3_STRING \ + "There is not enough data to read a Non-FIPS Security Header (section 2.2.8.1.1.2.2) or FIPS Security Header (section 2.2.8.1.1.2.3)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT4_STRING \ + "There is not enough data to read the basicSecurityHeader and length fields of the Security Exchange PDU Data (section 2.2.1.10.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT5_STRING \ + "There is not enough data to read the CodePage, flags, cbDomain, cbUserName, cbPassword, cbAlternateShell, " \ + "cbWorkingDir, Domain, UserName, Password, AlternateShell, and WorkingDir fields in the Info Packet (section 2.2.1.11.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT6_STRING \ + "There is not enough data to read the CodePage, flags, cbDomain, cbUserName, cbPassword, cbAlternateShell, " \ + "and cbWorkingDir fields in the Info Packet (section 2.2.1.11.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT7_STRING \ + "There is not enough data to read the clientAddressFamily and cbClientAddress fields in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT8_STRING \ + "There is not enough data to read the clientAddress field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT9_STRING \ + "There is not enough data to read the cbClientDir field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT10_STRING \ + "There is not enough data to read the clientDir field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT11_STRING \ + "There is not enough data to read the clientTimeZone field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT12_STRING \ + "There is not enough data to read the clientSessionId field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT13_STRING \ + "There is not enough data to read the performanceFlags field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT14_STRING \ + "There is not enough data to read the cbAutoReconnectLen field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT15_STRING \ + "There is not enough data to read the autoReconnectCookie field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT16_STRING \ + "The cbAutoReconnectLen field in the Extended Info Packet (section 2.2.1.11.1.1.1) contains a value " \ + "which is larger than the maximum allowed length of 128 bytes." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT17_STRING \ + "There is not enough data to read the clientAddressFamily and cbClientAddress fields in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT18_STRING \ + "There is not enough data to read the clientAddress field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT19_STRING \ + "There is not enough data to read the cbClientDir field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT20_STRING \ + "There is not enough data to read the clientDir field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT21_STRING \ + "There is not enough data to read the clientTimeZone field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT22_STRING \ + "There is not enough data to read the clientSessionId field in the Extended Info Packet (section 2.2.1.11.1.1.1)." + +#define ERRINFO_SECURITY_DATA_TOO_SHORT23_STRING \ + "There is not enough data to read the Client Info PDU Data (section 2.2.1.11.1)." + +#define ERRINFO_BAD_MONITOR_DATA_STRING \ + "The monitorCount field in the Client Monitor Data (section 2.2.1.3.6) is invalid." + +#define ERRINFO_VC_DECOMPRESSED_REASSEMBLE_FAILED_STRING \ + "The server-side decompression buffer is invalid, or the size of the decompressed VC data exceeds " \ + "the chunking size specified in the Virtual Channel Capability Set (section 2.2.7.1.10)." + +#define ERRINFO_VC_DATA_TOO_LONG_STRING \ + "The size of a received Virtual Channel PDU (section 2.2.6.1) exceeds the chunking size specified " \ + "in the Virtual Channel Capability Set (section 2.2.7.1.10)." + +#define ERRINFO_GRAPHICS_MODE_NOT_SUPPORTED_STRING \ + "The graphics mode requested by the client is not supported by the server." + +#define ERRINFO_GRAPHICS_SUBSYSTEM_RESET_FAILED_STRING \ + "The server-side graphics subsystem failed to reset." + +#define ERRINFO_UPDATE_SESSION_KEY_FAILED_STRING \ + "An attempt to update the session keys while using Standard RDP Security mechanisms (section 5.3.7) failed." + +#define ERRINFO_DECRYPT_FAILED_STRING \ + "(a) Decryption using Standard RDP Security mechanisms (section 5.3.6) failed.\n" \ + "(b) Session key creation using Standard RDP Security mechanisms (section 5.3.5) failed." + +#define ERRINFO_ENCRYPT_FAILED_STRING \ + "Encryption using Standard RDP Security mechanisms (section 5.3.6) failed." + +#define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH_STRING \ + "Failed to find a usable Encryption Method (section 5.3.2) in the encryptionMethods field of the Client Security Data (section 2.2.1.4.3)." + +#define ERRINFO_DECRYPT_FAILED2_STRING \ + "Unencrypted data was encountered in a protocol stream which is meant to be encrypted with Standard RDP Security mechanisms (section 5.3.6)." + +/* Special codes */ +#define ERRINFO_SUCCESS_STRING "Success." +#define ERRINFO_NONE_STRING "" + +static const ERRINFO ERRINFO_CODES[] = +{ + ERRINFO_DEFINE(SUCCESS), + + /* Protocol-independent codes */ + ERRINFO_DEFINE(RPC_INITIATED_DISCONNECT), + ERRINFO_DEFINE(RPC_INITIATED_LOGOFF), + ERRINFO_DEFINE(IDLE_TIMEOUT), + ERRINFO_DEFINE(LOGON_TIMEOUT), + ERRINFO_DEFINE(DISCONNECTED_BY_OTHER_CONNECTION), + ERRINFO_DEFINE(OUT_OF_MEMORY), + ERRINFO_DEFINE(SERVER_DENIED_CONNECTION), + ERRINFO_DEFINE(SERVER_INSUFFICIENT_PRIVILEGES), + ERRINFO_DEFINE(SERVER_FRESH_CREDENTIALS_REQUIRED), + ERRINFO_DEFINE(RPC_INITIATED_DISCONNECT_BY_USER), + + /* Protocol-independent licensing codes */ + ERRINFO_DEFINE(LICENSE_INTERNAL), + ERRINFO_DEFINE(LICENSE_NO_LICENSE_SERVER), + ERRINFO_DEFINE(LICENSE_NO_LICENSE), + ERRINFO_DEFINE(LICENSE_BAD_CLIENT_MSG), + ERRINFO_DEFINE(LICENSE_HWID_DOESNT_MATCH_LICENSE), + ERRINFO_DEFINE(LICENSE_BAD_CLIENT_LICENSE), + ERRINFO_DEFINE(LICENSE_CANT_FINISH_PROTOCOL), + ERRINFO_DEFINE(LICENSE_CLIENT_ENDED_PROTOCOL), + ERRINFO_DEFINE(LICENSE_BAD_CLIENT_ENCRYPTION), + ERRINFO_DEFINE(LICENSE_CANT_UPGRADE_LICENSE), + ERRINFO_DEFINE(LICENSE_NO_REMOTE_CONNECTIONS), + + /* RDP specific codes */ + ERRINFO_DEFINE(UNKNOWN_DATA_PDU_TYPE), + ERRINFO_DEFINE(UNKNOWN_PDU_TYPE), + ERRINFO_DEFINE(DATA_PDU_SEQUENCE), + ERRINFO_DEFINE(CONTROL_PDU_SEQUENCE), + ERRINFO_DEFINE(INVALID_CONTROL_PDU_ACTION), + ERRINFO_DEFINE(INVALID_INPUT_PDU_TYPE), + ERRINFO_DEFINE(INVALID_INPUT_PDU_MOUSE), + ERRINFO_DEFINE(INVALID_REFRESH_RECT_PDU), + ERRINFO_DEFINE(CREATE_USER_DATA_FAILED), + ERRINFO_DEFINE(CONNECT_FAILED), + ERRINFO_DEFINE(CONFIRM_ACTIVE_HAS_WRONG_SHAREID), + ERRINFO_DEFINE(CONFIRM_ACTIVE_HAS_WRONG_ORIGINATOR), + ERRINFO_DEFINE(PERSISTENT_KEY_PDU_BAD_LENGTH), + ERRINFO_DEFINE(PERSISTENT_KEY_PDU_ILLEGAL_FIRST), + ERRINFO_DEFINE(PERSISTENT_KEY_PDU_TOO_MANY_TOTAL_KEYS), + ERRINFO_DEFINE(PERSISTENT_KEY_PDU_TOO_MANY_CACHE_KEYS), + ERRINFO_DEFINE(INPUT_PDU_BAD_LENGTH), + ERRINFO_DEFINE(BITMAP_CACHE_ERROR_PDU_BAD_LENGTH), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT), + ERRINFO_DEFINE(VCHANNEL_DATA_TOO_SHORT ), + ERRINFO_DEFINE(SHARE_DATA_TOO_SHORT), + ERRINFO_DEFINE(BAD_SUPPRESS_OUTPUT_PDU), + ERRINFO_DEFINE(CONFIRM_ACTIVE_PDU_TOO_SHORT), + ERRINFO_DEFINE(CAPABILITY_SET_TOO_SMALL), + ERRINFO_DEFINE(CAPABILITY_SET_TOO_LARGE), + ERRINFO_DEFINE(NO_CURSOR_CACHE), + ERRINFO_DEFINE(BAD_CAPABILITIES), + ERRINFO_DEFINE(VIRTUAL_CHANNEL_DECOMPRESSION), + ERRINFO_DEFINE(INVALID_VC_COMPRESSION_TYPE), + ERRINFO_DEFINE(INVALID_CHANNEL_ID), + ERRINFO_DEFINE(VCHANNELS_TOO_MANY), + ERRINFO_DEFINE(REMOTEAPP_NOT_ENABLED), + ERRINFO_DEFINE(CACHE_CAP_NOT_SET), + ERRINFO_DEFINE(BITMAP_CACHE_ERROR_PDU_BAD_LENGTH2), + ERRINFO_DEFINE(OFFSCREEN_CACHE_ERROR_PDU_BAD_LENGTH), + ERRINFO_DEFINE(DRAWNINEGRID_CACHE_ERROR_PDU_BAD_LENGTH), + ERRINFO_DEFINE(GDIPLUS_PDU_BAD_LENGTH), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT2), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT3), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT4), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT5), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT6), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT7), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT8), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT9), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT10), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT11), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT12), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT13), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT14), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT15), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT16), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT17), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT18), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT19), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT20), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT21), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT22), + ERRINFO_DEFINE(SECURITY_DATA_TOO_SHORT23), + ERRINFO_DEFINE(BAD_MONITOR_DATA), + ERRINFO_DEFINE(VC_DECOMPRESSED_REASSEMBLE_FAILED), + ERRINFO_DEFINE(VC_DATA_TOO_LONG), + ERRINFO_DEFINE(GRAPHICS_MODE_NOT_SUPPORTED), + ERRINFO_DEFINE(GRAPHICS_SUBSYSTEM_RESET_FAILED), + ERRINFO_DEFINE(UPDATE_SESSION_KEY_FAILED), + ERRINFO_DEFINE(DECRYPT_FAILED), + ERRINFO_DEFINE(ENCRYPT_FAILED), + ERRINFO_DEFINE(ENCRYPTION_PACKAGE_MISMATCH), + ERRINFO_DEFINE(DECRYPT_FAILED2), + + ERRINFO_DEFINE(NONE) +}; + +void rdp_print_errinfo(uint32 code) +{ + const ERRINFO* errInfo; + + errInfo = &ERRINFO_CODES[0]; + + while (errInfo->code != ERRINFO_NONE) + { + if (code == errInfo->code) + { + printf("%s (0x%08X):\n%s\n", errInfo->name, code, errInfo->info); + return; + } + + errInfo++; + } + + printf("ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code); +} + diff --git a/libfreerdp-core/errinfo.h b/libfreerdp-core/errinfo.h new file mode 100644 index 0000000..d63f078 --- /dev/null +++ b/libfreerdp-core/errinfo.h @@ -0,0 +1,136 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Error Info + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ERRINFO_H +#define __ERRINFO_H + +#include + +/* Protocol-independent codes */ +#define ERRINFO_RPC_INITIATED_DISCONNECT 0x00000001 +#define ERRINFO_RPC_INITIATED_LOGOFF 0x00000002 +#define ERRINFO_IDLE_TIMEOUT 0x00000003 +#define ERRINFO_LOGON_TIMEOUT 0x00000004 +#define ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION 0x00000005 +#define ERRINFO_OUT_OF_MEMORY 0x00000006 +#define ERRINFO_SERVER_DENIED_CONNECTION 0x00000007 +#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x00000009 +#define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED 0x0000000A +#define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER 0x0000000B + +/* Protocol-independent licensing codes */ +#define ERRINFO_LICENSE_INTERNAL 0x00000100 +#define ERRINFO_LICENSE_NO_LICENSE_SERVER 0x00000101 +#define ERRINFO_LICENSE_NO_LICENSE 0x00000102 +#define ERRINFO_LICENSE_BAD_CLIENT_MSG 0x00000103 +#define ERRINFO_LICENSE_HWID_DOESNT_MATCH_LICENSE 0x00000104 +#define ERRINFO_LICENSE_BAD_CLIENT_LICENSE 0x00000105 +#define ERRINFO_LICENSE_CANT_FINISH_PROTOCOL 0x00000106 +#define ERRINFO_LICENSE_CLIENT_ENDED_PROTOCOL 0x00000107 +#define ERRINFO_LICENSE_BAD_CLIENT_ENCRYPTION 0x00000108 +#define ERRINFO_LICENSE_CANT_UPGRADE_LICENSE 0x00000109 +#define ERRINFO_LICENSE_NO_REMOTE_CONNECTIONS 0x0000010A + +/* RDP specific codes */ +#define ERRINFO_UNKNOWN_DATA_PDU_TYPE 0x000010C9 +#define ERRINFO_UNKNOWN_PDU_TYPE 0x000010CA +#define ERRINFO_DATA_PDU_SEQUENCE 0x000010CB +#define ERRINFO_CONTROL_PDU_SEQUENCE 0x000010CD +#define ERRINFO_INVALID_CONTROL_PDU_ACTION 0x000010CE +#define ERRINFO_INVALID_INPUT_PDU_TYPE 0x000010CF +#define ERRINFO_INVALID_INPUT_PDU_MOUSE 0x000010D0 +#define ERRINFO_INVALID_REFRESH_RECT_PDU 0x000010D1 +#define ERRINFO_CREATE_USER_DATA_FAILED 0x000010D2 +#define ERRINFO_CONNECT_FAILED 0x000010D3 +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_SHAREID 0x000010D4 +#define ERRINFO_CONFIRM_ACTIVE_HAS_WRONG_ORIGINATOR 0x000010D5 +#define ERRINFO_PERSISTENT_KEY_PDU_BAD_LENGTH 0x000010DA +#define ERRINFO_PERSISTENT_KEY_PDU_ILLEGAL_FIRST 0x000010DB +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_TOTAL_KEYS 0x000010DC +#define ERRINFO_PERSISTENT_KEY_PDU_TOO_MANY_CACHE_KEYS 0x000010DD +#define ERRINFO_INPUT_PDU_BAD_LENGTH 0x000010DE +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH 0x000010DF +#define ERRINFO_SECURITY_DATA_TOO_SHORT 0x000010E0 +#define ERRINFO_VCHANNEL_DATA_TOO_SHORT 0x000010E1 +#define ERRINFO_SHARE_DATA_TOO_SHORT 0x000010E2 +#define ERRINFO_BAD_SUPPRESS_OUTPUT_PDU 0x000010E3 +#define ERRINFO_CONFIRM_ACTIVE_PDU_TOO_SHORT 0x000010E5 +#define ERRINFO_CAPABILITY_SET_TOO_SMALL 0x000010E7 +#define ERRINFO_CAPABILITY_SET_TOO_LARGE 0x000010E8 +#define ERRINFO_NO_CURSOR_CACHE 0x000010E9 +#define ERRINFO_BAD_CAPABILITIES 0x000010EA +#define ERRINFO_VIRTUAL_CHANNEL_DECOMPRESSION 0x000010EC +#define ERRINFO_INVALID_VC_COMPRESSION_TYPE 0x000010ED +#define ERRINFO_INVALID_CHANNEL_ID 0x000010EF +#define ERRINFO_VCHANNELS_TOO_MANY 0x000010F0 +#define ERRINFO_REMOTEAPP_NOT_ENABLED 0x000010F3 +#define ERRINFO_CACHE_CAP_NOT_SET 0x000010F4 +#define ERRINFO_BITMAP_CACHE_ERROR_PDU_BAD_LENGTH2 0x000010F5 +#define ERRINFO_OFFSCREEN_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F6 +#define ERRINFO_DRAWNINEGRID_CACHE_ERROR_PDU_BAD_LENGTH 0x000010F7 +#define ERRINFO_GDIPLUS_PDU_BAD_LENGTH 0x000010F8 +#define ERRINFO_SECURITY_DATA_TOO_SHORT2 0x00001111 +#define ERRINFO_SECURITY_DATA_TOO_SHORT3 0x00001112 +#define ERRINFO_SECURITY_DATA_TOO_SHORT4 0x00001113 +#define ERRINFO_SECURITY_DATA_TOO_SHORT5 0x00001114 +#define ERRINFO_SECURITY_DATA_TOO_SHORT6 0x00001115 +#define ERRINFO_SECURITY_DATA_TOO_SHORT7 0x00001116 +#define ERRINFO_SECURITY_DATA_TOO_SHORT8 0x00001117 +#define ERRINFO_SECURITY_DATA_TOO_SHORT9 0x00001118 +#define ERRINFO_SECURITY_DATA_TOO_SHORT10 0x00001119 +#define ERRINFO_SECURITY_DATA_TOO_SHORT11 0x0000111A +#define ERRINFO_SECURITY_DATA_TOO_SHORT12 0x0000111B +#define ERRINFO_SECURITY_DATA_TOO_SHORT13 0x0000111C +#define ERRINFO_SECURITY_DATA_TOO_SHORT14 0x0000111D +#define ERRINFO_SECURITY_DATA_TOO_SHORT15 0x0000111E +#define ERRINFO_SECURITY_DATA_TOO_SHORT16 0x0000111F +#define ERRINFO_SECURITY_DATA_TOO_SHORT17 0x00001120 +#define ERRINFO_SECURITY_DATA_TOO_SHORT18 0x00001121 +#define ERRINFO_SECURITY_DATA_TOO_SHORT19 0x00001122 +#define ERRINFO_SECURITY_DATA_TOO_SHORT20 0x00001123 +#define ERRINFO_SECURITY_DATA_TOO_SHORT21 0x00001124 +#define ERRINFO_SECURITY_DATA_TOO_SHORT22 0x00001125 +#define ERRINFO_SECURITY_DATA_TOO_SHORT23 0x00001126 +#define ERRINFO_BAD_MONITOR_DATA 0x00001129 +#define ERRINFO_VC_DECOMPRESSED_REASSEMBLE_FAILED 0x0000112A +#define ERRINFO_VC_DATA_TOO_LONG 0x0000112B +#define ERRINFO_GRAPHICS_MODE_NOT_SUPPORTED 0x0000112D +#define ERRINFO_GRAPHICS_SUBSYSTEM_RESET_FAILED 0x0000112E +#define ERRINFO_UPDATE_SESSION_KEY_FAILED 0x00001191 +#define ERRINFO_DECRYPT_FAILED 0x00001192 +#define ERRINFO_ENCRYPT_FAILED 0x00001193 +#define ERRINFO_ENCRYPTION_PACKAGE_MISMATCH 0x00001194 +#define ERRINFO_DECRYPT_FAILED2 0x00001195 + +#define ERRINFO_SUCCESS 0x00000000 +#define ERRINFO_NONE 0xFFFFFFFF + +struct _ERRINFO +{ + uint32 code; + char* name; + char* info; +}; +typedef struct _ERRINFO ERRINFO; + +#define ERRINFO_DEFINE(_code) { ERRINFO_##_code , "ERRINFO_" #_code , ERRINFO_##_code##_STRING } + +void rdp_print_errinfo(uint32 code); + +#endif diff --git a/libfreerdp-core/extension.c b/libfreerdp-core/extension.c new file mode 100644 index 0000000..3aa0088 --- /dev/null +++ b/libfreerdp-core/extension.c @@ -0,0 +1,214 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Extension Plugin Interface + * + * Copyright 2010-2011 Vic Lee + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#include "extension.h" + +#ifdef _WIN32 +#define DLOPEN(f) LoadLibraryA(f) +#define DLSYM(f, n) GetProcAddress(f, n) +#define DLCLOSE(f) FreeLibrary(f) +#define PATH_SEPARATOR '\\' +#define PLUGIN_EXT "dll" +#else +#include +#define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY) +#define DLSYM(f, n) dlsym(f, n) +#define DLCLOSE(f) dlclose(f) +#define PATH_SEPARATOR '/' + +#ifdef __APPLE__ +#define PLUGIN_EXT "dylib" +#else +#define PLUGIN_EXT "so" +#endif + +#endif + +static uint32 FREERDP_CC extension_register_plugin(rdpExtPlugin* plugin) +{ + rdpExtension* ext = (rdpExtension*) plugin->ext; + + if (ext->num_plugins >= FREERDP_EXT_MAX_COUNT) + { + printf("extension_register_extension: maximum number of plugins reached.\n"); + return 1; + } + + ext->plugins[ext->num_plugins++] = plugin; + return 0; +} + +static uint32 FREERDP_CC extension_register_pre_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook) +{ + rdpExtension* ext = (rdpExtension*) plugin->ext; + + if (ext->num_pre_connect_hooks >= FREERDP_EXT_MAX_COUNT) + { + printf("extension_register_pre_connect_hook: maximum plugin reached.\n"); + return 1; + } + + ext->pre_connect_hooks[ext->num_pre_connect_hooks] = hook; + ext->pre_connect_hooks_instances[ext->num_pre_connect_hooks] = plugin; + ext->num_pre_connect_hooks++; + return 0; +} + +static uint32 FREERDP_CC extension_register_post_connect_hook(rdpExtPlugin* plugin, PFREERDP_EXTENSION_HOOK hook) +{ + rdpExtension* ext = (rdpExtension*) plugin->ext; + + if (ext->num_post_connect_hooks >= FREERDP_EXT_MAX_COUNT) + { + printf("extension_register_post_connect_hook: maximum plugin reached.\n"); + return 1; + } + + ext->post_connect_hooks[ext->num_post_connect_hooks] = hook; + ext->post_connect_hooks_instances[ext->num_post_connect_hooks] = plugin; + ext->num_post_connect_hooks++; + + return 0; +} + +static int extension_load_plugins(rdpExtension* extension) +{ + int i; + void* han; + char path[256]; + rdpSettings* settings; + PFREERDP_EXTENSION_ENTRY entry; + FREERDP_EXTENSION_ENTRY_POINTS entryPoints; + + settings = extension->instance->settings; + + entryPoints.ext = extension; + entryPoints.pRegisterExtension = extension_register_plugin; + entryPoints.pRegisterPreConnectHook = extension_register_pre_connect_hook; + entryPoints.pRegisterPostConnectHook = extension_register_post_connect_hook; + + for (i = 0; settings->extensions[i].name[0]; i++) + { + if (strchr(settings->extensions[i].name, PATH_SEPARATOR) == NULL) + snprintf(path, sizeof(path), EXT_PATH "/%s." PLUGIN_EXT, settings->extensions[i].name); + else + snprintf(path, sizeof(path), "%s", settings->extensions[i].name); + + han = DLOPEN(path); + printf("extension_load_plugins: %s\n", path); + if (han == NULL) + { + printf("extension_load_plugins: failed to load %s\n", path); + continue; + } + + entry = (PFREERDP_EXTENSION_ENTRY) DLSYM(han, FREERDP_EXT_EXPORT_FUNC_NAME); + if (entry == NULL) + { + DLCLOSE(han); + printf("extension_load_plugins: failed to find export function in %s\n", path); + continue; + } + + entryPoints.data = extension->instance->settings->extensions[i].data; + if (entry(&entryPoints) != 0) + { + DLCLOSE(han); + printf("extension_load_plugins: %s entry returns error.\n", path); + continue; + } + } + + return 0; +} + +static int extension_init_plugins(rdpExtension* extension) +{ + int i; + + for (i = 0; i < extension->num_plugins; i++) + extension->plugins[i]->init(extension->plugins[i], extension->instance); + + return 0; +} + +static int extension_uninit_plugins(rdpExtension* extension) +{ + int i; + + for (i = 0; i < extension->num_plugins; i++) + extension->plugins[i]->uninit(extension->plugins[i], extension->instance); + + return 0; +} + + +int extension_pre_connect(rdpExtension* extension) +{ + int i; + + for (i = 0; i < extension->num_pre_connect_hooks; i++) + extension->pre_connect_hooks[i](extension->pre_connect_hooks_instances[i], extension->instance); + + return 0; +} + +int extension_post_connect(rdpExtension* ext) +{ + int i; + + for (i = 0; i < ext->num_post_connect_hooks; i++) + ext->post_connect_hooks[i](ext->post_connect_hooks_instances[i], ext->instance); + + return 0; +} + +rdpExtension* extension_new(freerdp* instance) +{ + rdpExtension* extension = NULL; + + if (instance != NULL) + { + extension = xnew(rdpExtension); + + extension->instance = instance; + + extension_load_plugins(extension); + extension_init_plugins(extension); + } + + return extension; +} + +void extension_free(rdpExtension* extension) +{ + if (extension != NULL) + { + extension_uninit_plugins(extension); + xfree(extension); + } +} diff --git a/libfreerdp-core/extension.h b/libfreerdp-core/extension.h new file mode 100644 index 0000000..35f34cb --- /dev/null +++ b/libfreerdp-core/extension.h @@ -0,0 +1,55 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Extension Plugin Interface + * + * Copyright 2010-2011 Vic Lee + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __EXTENSION_H +#define __EXTENSION_H + +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#define FREERDP_EXT_MAX_COUNT 16 + +struct rdp_extension +{ + freerdp* instance; + rdpExtPlugin* plugins[FREERDP_EXT_MAX_COUNT]; + int num_plugins; + PFREERDP_EXTENSION_HOOK pre_connect_hooks[FREERDP_EXT_MAX_COUNT]; + rdpExtPlugin* pre_connect_hooks_instances[FREERDP_EXT_MAX_COUNT]; + int num_pre_connect_hooks; + PFREERDP_EXTENSION_HOOK post_connect_hooks[FREERDP_EXT_MAX_COUNT]; + rdpExtPlugin* post_connect_hooks_instances[FREERDP_EXT_MAX_COUNT]; + int num_post_connect_hooks; +}; +typedef struct rdp_extension rdpExtension; + +FREERDP_API int extension_pre_connect(rdpExtension* extension); +FREERDP_API int extension_post_connect(rdpExtension* extension); + +FREERDP_API rdpExtension* extension_new(freerdp* instance); +FREERDP_API void extension_free(rdpExtension* extension); + +#endif /* __EXTENSION_H */ + diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c new file mode 100644 index 0000000..c915666 --- /dev/null +++ b/libfreerdp-core/fastpath.c @@ -0,0 +1,680 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Fast Path + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "orders.h" +#include "per.h" +#include "update.h" +#include "surface.h" + +#include "fastpath.h" + +/** + * Fast-Path packet format is defined in [MS-RDPBCGR] 2.2.9.1.2, which revises + * server output packets from the first byte with the goal of improving + * bandwidth. + * + * Slow-Path packet always starts with TPKT header, which has the first + * byte 0x03, while Fast-Path packet starts with 2 zero bits in the first + * two less significant bits of the first byte. + */ + +#define FASTPATH_MAX_PACKET_SIZE 0x3FFF + +/* + * The fastpath header may be two or three bytes long. + * This function assumes that at least two bytes are available in the stream + * and doesn't touch third byte. + */ +uint16 fastpath_header_length(STREAM* s) +{ + uint8 length1; + + stream_seek_uint8(s); + stream_read_uint8(s, length1); + stream_rewind(s, 2); + + return ((length1 & 0x80) != 0 ? 3 : 2); +} + +/** + * Read a Fast-Path packet header.\n + * @param s stream + * @param encryptionFlags + * @return length + */ +uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s) +{ + uint8 header; + uint16 length; + + stream_read_uint8(s, header); + + if (fastpath != NULL) + { + fastpath->encryptionFlags = (header & 0xC0) >> 6; + fastpath->numberEvents = (header & 0x3C) >> 2; + } + + per_read_length(s, &length); + + return length; +} + +INLINE void fastpath_read_update_header(STREAM* s, uint8* updateCode, uint8* fragmentation, uint8* compression) +{ + uint8 updateHeader; + + stream_read_uint8(s, updateHeader); + *updateCode = updateHeader & 0x0F; + *fragmentation = (updateHeader >> 4) & 0x03; + *compression = (updateHeader >> 6) & 0x03; +} + +INLINE void fastpath_write_update_header(STREAM* s, uint8 updateCode, uint8 fragmentation, uint8 compression) +{ + uint8 updateHeader = 0; + + updateHeader |= updateCode & 0x0F; + updateHeader |= (fragmentation & 0x03) << 4; + updateHeader |= (compression & 0x03) << 6; + stream_write_uint8(s, updateHeader); +} + +uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s) +{ + uint8 header; + uint16 length; + + stream_read_uint8(s, header); + + if (fastpath != NULL) + { + fastpath->encryptionFlags = (header & 0xC0) >> 6; + fastpath->numberEvents = (header & 0x3C) >> 2; + } + + per_read_length(s, &length); + + return length - stream_get_length(s); +} + +static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s) +{ + rdpUpdate* update = fastpath->rdp->update; + uint16 numberOrders; + + stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */ + + while (numberOrders > 0) + { + update_recv_order(update, s); + numberOrders--; + } +} + +static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s) +{ + uint16 updateType; + rdpUpdate* update = fastpath->rdp->update; + rdpContext* context = update->context; + + stream_read_uint16(s, updateType); /* updateType (2 bytes) */ + + switch (updateType) + { + case UPDATE_TYPE_BITMAP: + update_read_bitmap(update, s, &update->bitmap_update); + IFCALL(update->BitmapUpdate, context, &update->bitmap_update); + break; + + case UPDATE_TYPE_PALETTE: + update_read_palette(update, s, &update->palette_update); + IFCALL(update->Palette, context, &update->palette_update); + break; + } +} + +static void fastpath_recv_update_synchronize(rdpFastPath* fastpath, STREAM* s) +{ + stream_seek_uint16(s); /* size (2 bytes), must be set to zero */ +} + +static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32 size, STREAM* s) +{ + rdpUpdate* update = fastpath->rdp->update; + rdpContext* context = fastpath->rdp->update->context; + rdpPointerUpdate* pointer = update->pointer; + + switch (updateCode) + { + case FASTPATH_UPDATETYPE_ORDERS: + fastpath_recv_orders(fastpath, s); + break; + + case FASTPATH_UPDATETYPE_BITMAP: + case FASTPATH_UPDATETYPE_PALETTE: + fastpath_recv_update_common(fastpath, s); + break; + + case FASTPATH_UPDATETYPE_SYNCHRONIZE: + fastpath_recv_update_synchronize(fastpath, s); + IFCALL(update->Synchronize, context); + break; + + case FASTPATH_UPDATETYPE_SURFCMDS: + update_recv_surfcmds(update, size, s); + break; + + case FASTPATH_UPDATETYPE_PTR_NULL: + pointer->pointer_system.type = SYSPTR_NULL; + IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + break; + + case FASTPATH_UPDATETYPE_PTR_DEFAULT: + update->pointer->pointer_system.type = SYSPTR_DEFAULT; + IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + break; + + case FASTPATH_UPDATETYPE_PTR_POSITION: + update_read_pointer_position(s, &pointer->pointer_position); + IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); + break; + + case FASTPATH_UPDATETYPE_COLOR: + update_read_pointer_color(s, &pointer->pointer_color); + IFCALL(pointer->PointerColor, context, &pointer->pointer_color); + break; + + case FASTPATH_UPDATETYPE_CACHED: + update_read_pointer_cached(s, &pointer->pointer_cached); + IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); + break; + + case FASTPATH_UPDATETYPE_POINTER: + update_read_pointer_new(s, &pointer->pointer_new); + IFCALL(pointer->PointerNew, context, &pointer->pointer_new); + break; + + default: + DEBUG_WARN("unknown updateCode 0x%X", updateCode); + break; + } +} + +static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s) +{ + uint16 size; + int next_pos; + uint32 totalSize; + uint8 updateCode; + uint8 fragmentation; + uint8 compression; + uint8 compressionFlags; + STREAM* update_stream; + STREAM* comp_stream; + rdpRdp *rdp; + uint32 roff; + uint32 rlen; + + rdp = fastpath->rdp; + + fastpath_read_update_header(s, &updateCode, &fragmentation, &compression); + + if (compression == FASTPATH_OUTPUT_COMPRESSION_USED) + stream_read_uint8(s, compressionFlags); + else + compressionFlags = 0; + + stream_read_uint16(s, size); + next_pos = stream_get_pos(s) + size; + comp_stream = s; + + if (compressionFlags & PACKET_COMPRESSED) + { + if (decompress_rdp(rdp, s->p, size, compressionFlags, &roff, &rlen)) + { + comp_stream = stream_new(0); + comp_stream->data = rdp->mppc->history_buf + roff; + comp_stream->p = comp_stream->data; + comp_stream->size = rlen; + size = comp_stream->size; + } + else + { + printf("decompress_rdp() failed\n"); + stream_seek(s, size); + } + } + + update_stream = NULL; + if (fragmentation == FASTPATH_FRAGMENT_SINGLE) + { + totalSize = size; + update_stream = comp_stream; + } + else + { + if (fragmentation == FASTPATH_FRAGMENT_FIRST) + stream_set_pos(fastpath->updateData, 0); + + stream_check_size(fastpath->updateData, size); + stream_copy(fastpath->updateData, comp_stream, size); + + if (fragmentation == FASTPATH_FRAGMENT_LAST) + { + update_stream = fastpath->updateData; + totalSize = stream_get_length(update_stream); + stream_set_pos(update_stream, 0); + } + } + + if (update_stream) + fastpath_recv_update(fastpath, updateCode, totalSize, update_stream); + + stream_set_pos(s, next_pos); + + if (comp_stream != s) + xfree(comp_stream); +} + +boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s) +{ + rdpUpdate* update = fastpath->rdp->update; + + IFCALL(update->BeginPaint, update->context); + + while (stream_get_left(s) >= 3) + { + fastpath_recv_update_data(fastpath, s); + } + + IFCALL(update->EndPaint, update->context); + + return true; +} + +static boolean fastpath_read_input_event_header(STREAM* s, uint8* eventFlags, uint8* eventCode) +{ + uint8 eventHeader; + + if (stream_get_left(s) < 1) + return false; + + stream_read_uint8(s, eventHeader); /* eventHeader (1 byte) */ + + *eventFlags = (eventHeader & 0x1F); + *eventCode = (eventHeader >> 5); + + return true; +} + +static boolean fastpath_recv_input_event_scancode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) +{ + uint16 flags; + uint16 code; + + if (stream_get_left(s) < 1) + return false; + + stream_read_uint8(s, code); /* keyCode (1 byte) */ + + flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAGS_RELEASE; + else + flags |= KBD_FLAGS_DOWN; + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) + flags |= KBD_FLAGS_EXTENDED; + + IFCALL(fastpath->rdp->input->KeyboardEvent, fastpath->rdp->input, flags, code); + + return true; +} + +static boolean fastpath_recv_input_event_mouse(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) +{ + uint16 pointerFlags; + uint16 xPos; + uint16 yPos; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */ + stream_read_uint16(s, xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, yPos); /* yPos (2 bytes) */ + + IFCALL(fastpath->rdp->input->MouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos); + + return true; +} + +static boolean fastpath_recv_input_event_mousex(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) +{ + uint16 pointerFlags; + uint16 xPos; + uint16 yPos; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */ + stream_read_uint16(s, xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, yPos); /* yPos (2 bytes) */ + + IFCALL(fastpath->rdp->input->ExtendedMouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos); + + return true; +} + +static boolean fastpath_recv_input_event_sync(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) +{ + IFCALL(fastpath->rdp->input->SynchronizeEvent, fastpath->rdp->input, eventFlags); + + return true; +} + +static boolean fastpath_recv_input_event_unicode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags) +{ + uint16 unicodeCode; + uint16 flags; + + if (stream_get_left(s) < 2) + return false; + + stream_read_uint16(s, unicodeCode); /* unicodeCode (2 bytes) */ + + flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAGS_RELEASE; + else + flags |= KBD_FLAGS_DOWN; + + IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, flags, unicodeCode); + + return true; +} + +static boolean fastpath_recv_input_event(rdpFastPath* fastpath, STREAM* s) +{ + uint8 eventFlags; + uint8 eventCode; + + if (!fastpath_read_input_event_header(s, &eventFlags, &eventCode)) + return false; + + switch (eventCode) + { + case FASTPATH_INPUT_EVENT_SCANCODE: + if (!fastpath_recv_input_event_scancode(fastpath, s, eventFlags)) + return false; + break; + + case FASTPATH_INPUT_EVENT_MOUSE: + if (!fastpath_recv_input_event_mouse(fastpath, s, eventFlags)) + return false; + break; + + case FASTPATH_INPUT_EVENT_MOUSEX: + if (!fastpath_recv_input_event_mousex(fastpath, s, eventFlags)) + return false; + break; + + case FASTPATH_INPUT_EVENT_SYNC: + if (!fastpath_recv_input_event_sync(fastpath, s, eventFlags)) + return false; + break; + + case FASTPATH_INPUT_EVENT_UNICODE: + if (!fastpath_recv_input_event_unicode(fastpath, s, eventFlags)) + return false; + break; + + default: + printf("Unknown eventCode %d\n", eventCode); + break; + } + + return true; +} + +boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s) +{ + uint8 i; + + if (fastpath->numberEvents == 0) + { + /** + * If numberEvents is not provided in fpInputHeader, it will be provided + * as one additional byte here. + */ + + if (stream_get_left(s) < 1) + return false; + + stream_read_uint8(s, fastpath->numberEvents); /* eventHeader (1 byte) */ + } + + for (i = 0; i < fastpath->numberEvents; i++) + { + if (!fastpath_recv_input_event(fastpath, s)) + return false; + } + + return true; +} + +static uint32 fastpath_get_sec_bytes(rdpRdp* rdp) +{ + uint32 sec_bytes; + + if (rdp->do_crypt) + { + sec_bytes = 8; + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + sec_bytes += 4; + } + else + sec_bytes = 0; + return sec_bytes; +} + +STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode) +{ + rdpRdp *rdp; + STREAM* s; + + rdp = fastpath->rdp; + + s = transport_send_stream_init(rdp->transport, 256); + stream_seek(s, 3); /* fpInputHeader, length1 and length2 */ + if (rdp->do_crypt) { + rdp->sec_flags |= SEC_ENCRYPT; + if (rdp->do_secure_checksum) + rdp->sec_flags |= SEC_SECURE_CHECKSUM; + } + stream_seek(s, fastpath_get_sec_bytes(rdp)); + stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */ + return s; +} + +boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s) +{ + rdpRdp *rdp; + uint16 length; + uint8 eventHeader; + int sec_bytes; + + rdp = fastpath->rdp; + + length = stream_get_length(s); + if (length > 127) + { + printf("Maximum FastPath PDU length is 127\n"); + return false; + } + + eventHeader = FASTPATH_INPUT_ACTION_FASTPATH; + eventHeader |= (1 << 2); /* numberEvents */ + if (rdp->sec_flags & SEC_ENCRYPT) + eventHeader |= (FASTPATH_INPUT_ENCRYPTED << 6); + if (rdp->sec_flags & SEC_SECURE_CHECKSUM) + eventHeader |= (FASTPATH_INPUT_SECURE_CHECKSUM << 6); + + stream_set_pos(s, 0); + stream_write_uint8(s, eventHeader); + sec_bytes = fastpath_get_sec_bytes(fastpath->rdp); + /* + * We always encode length in two bytes, eventhough we could use + * only one byte if length <= 0x7F. It is just easier that way, + * because we can leave room for fixed-length header, store all + * the data first and then store the header. + */ + stream_write_uint16_be(s, 0x8000 | (length + sec_bytes)); + + if (sec_bytes > 0) + { + uint8* ptr; + + ptr = stream_get_tail(s) + sec_bytes; + if (rdp->sec_flags & SEC_SECURE_CHECKSUM) + security_salted_mac_signature(rdp, ptr, length - 3, true, stream_get_tail(s)); + else + security_mac_signature(rdp, ptr, length - 3, stream_get_tail(s)); + security_encrypt(ptr, length - 3, rdp); + } + + rdp->sec_flags = 0; + + stream_set_pos(s, length + sec_bytes); + if (transport_write(fastpath->rdp->transport, s) < 0) + return false; + + return true; +} + +STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath) +{ + STREAM* s; + s = transport_send_stream_init(fastpath->rdp->transport, FASTPATH_MAX_PACKET_SIZE); + stream_seek(s, 3); /* fpOutputHeader, length1 and length2 */ + stream_seek(s, fastpath_get_sec_bytes(fastpath->rdp)); + stream_seek(s, 3); /* updateHeader, size */ + return s; +} + +boolean fastpath_send_update_pdu(rdpFastPath* fastpath, uint8 updateCode, STREAM* s) +{ + rdpRdp *rdp; + uint8* bm; + uint8* ptr; + int fragment; + int sec_bytes; + uint16 length; + boolean result; + uint16 pduLength; + uint16 maxLength; + uint32 totalLength; + uint8 fragmentation; + uint8 header; + STREAM* update; + + result = true; + + rdp = fastpath->rdp; + sec_bytes = fastpath_get_sec_bytes(rdp); + maxLength = FASTPATH_MAX_PACKET_SIZE - 6 - sec_bytes; + totalLength = stream_get_length(s) - 6 - sec_bytes; + stream_set_pos(s, 0); + update = stream_new(0); + + for (fragment = 0; totalLength > 0; fragment++) + { + length = MIN(maxLength, totalLength); + totalLength -= length; + pduLength = length + 6 + sec_bytes; + + if (totalLength == 0) + fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST; + else + fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT; + + stream_get_mark(s, bm); + header = 0; + if (sec_bytes > 0) + header |= (FASTPATH_OUTPUT_ENCRYPTED << 6); + stream_write_uint8(s, header); /* fpOutputHeader (1 byte) */ + stream_write_uint8(s, 0x80 | (pduLength >> 8)); /* length1 */ + stream_write_uint8(s, pduLength & 0xFF); /* length2 */ + if (sec_bytes > 0) + stream_seek(s, sec_bytes); + fastpath_write_update_header(s, updateCode, fragmentation, 0); + stream_write_uint16(s, length); + + stream_attach(update, bm, pduLength); + stream_seek(update, pduLength); + if (sec_bytes > 0) + { + ptr = bm + 3 + sec_bytes; + if (rdp->sec_flags & SEC_SECURE_CHECKSUM) + security_salted_mac_signature(rdp, ptr, length + 3, true, bm + 3); + else + security_mac_signature(rdp, ptr, length + 3, bm + 3); + security_encrypt(ptr, length + 3, rdp); + } + if (transport_write(fastpath->rdp->transport, update) < 0) + { + stream_detach(update); + result = false; + break; + } + stream_detach(update); + + /* Reserve 6+sec_bytes bytes for the next fragment header, if any. */ + stream_seek(s, length - 6 - sec_bytes); + } + + stream_free(update); + + return result; +} + +rdpFastPath* fastpath_new(rdpRdp* rdp) +{ + rdpFastPath* fastpath; + + fastpath = xnew(rdpFastPath); + fastpath->rdp = rdp; + fastpath->updateData = stream_new(4096); + + return fastpath; +} + +void fastpath_free(rdpFastPath* fastpath) +{ + stream_free(fastpath->updateData); + xfree(fastpath); +} diff --git a/libfreerdp-core/fastpath.h b/libfreerdp-core/fastpath.h new file mode 100644 index 0000000..428ce55 --- /dev/null +++ b/libfreerdp-core/fastpath.h @@ -0,0 +1,122 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Fast Path + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FASTPATH_H +#define __FASTPATH_H + +#include "rdp.h" +#include + +typedef struct rdp_fastpath rdpFastPath; + +enum FASTPATH_INPUT_ACTION_TYPE +{ + FASTPATH_INPUT_ACTION_FASTPATH = 0x0, + FASTPATH_INPUT_ACTION_X224 = 0x3 +}; + +enum FASTPATH_OUTPUT_ACTION_TYPE +{ + FASTPATH_OUTPUT_ACTION_FASTPATH = 0x0, + FASTPATH_OUTPUT_ACTION_X224 = 0x3 +}; + +enum FASTPATH_INPUT_ENCRYPTION_FLAGS +{ + FASTPATH_INPUT_SECURE_CHECKSUM = 0x1, + FASTPATH_INPUT_ENCRYPTED = 0x2 +}; + +enum FASTPATH_OUTPUT_ENCRYPTION_FLAGS +{ + FASTPATH_OUTPUT_SECURE_CHECKSUM = 0x1, + FASTPATH_OUTPUT_ENCRYPTED = 0x2 +}; + +enum FASTPATH_UPDATETYPE +{ + FASTPATH_UPDATETYPE_ORDERS = 0x0, + FASTPATH_UPDATETYPE_BITMAP = 0x1, + FASTPATH_UPDATETYPE_PALETTE = 0x2, + FASTPATH_UPDATETYPE_SYNCHRONIZE = 0x3, + FASTPATH_UPDATETYPE_SURFCMDS = 0x4, + FASTPATH_UPDATETYPE_PTR_NULL = 0x5, + FASTPATH_UPDATETYPE_PTR_DEFAULT = 0x6, + FASTPATH_UPDATETYPE_PTR_POSITION = 0x8, + FASTPATH_UPDATETYPE_COLOR = 0x9, + FASTPATH_UPDATETYPE_CACHED = 0xA, + FASTPATH_UPDATETYPE_POINTER = 0xB +}; + +enum FASTPATH_FRAGMENT +{ + FASTPATH_FRAGMENT_SINGLE = 0x0, + FASTPATH_FRAGMENT_LAST = 0x1, + FASTPATH_FRAGMENT_FIRST = 0x2, + FASTPATH_FRAGMENT_NEXT = 0x3 +}; + +enum FASTPATH_OUTPUT_COMPRESSION +{ + FASTPATH_OUTPUT_COMPRESSION_USED = 0x2 +}; + +/* FastPath Input Events */ +enum FASTPATH_INPUT_EVENT_CODE +{ + FASTPATH_INPUT_EVENT_SCANCODE = 0x0, + FASTPATH_INPUT_EVENT_MOUSE = 0x1, + FASTPATH_INPUT_EVENT_MOUSEX = 0x2, + FASTPATH_INPUT_EVENT_SYNC = 0x3, + FASTPATH_INPUT_EVENT_UNICODE = 0x4 +}; + +/* FastPath Keyboard Event Flags */ +enum FASTPATH_INPUT_KBDFLAGS +{ + FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01, + FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02 +}; + +struct rdp_fastpath +{ + rdpRdp* rdp; + uint8 encryptionFlags; + uint8 numberEvents; + STREAM* updateData; +}; + +uint16 fastpath_header_length(STREAM* s); +uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s); +uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s); +boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s); +boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s); + +STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode); +boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s); + +STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath); +boolean fastpath_send_update_pdu(rdpFastPath* fastpath, uint8 updateCode, STREAM* s); + +boolean fastpath_send_surfcmd_frame_marker(rdpFastPath* fastpath, uint16 frameAction, uint32 frameId); + +rdpFastPath* fastpath_new(rdpRdp* rdp); +void fastpath_free(rdpFastPath* fastpath); + +#endif diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c new file mode 100644 index 0000000..3109822 --- /dev/null +++ b/libfreerdp-core/freerdp.c @@ -0,0 +1,229 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Core + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdp.h" +#include "input.h" +#include "update.h" +#include "surface.h" +#include "transport.h" +#include "connection.h" +#include "extension.h" + +#include +#include + +boolean freerdp_connect(freerdp* instance) +{ + rdpRdp* rdp; + boolean status = false; + + rdp = instance->context->rdp; + + extension_pre_connect(rdp->extension); + + IFCALLRET(instance->PreConnect, status, instance); + + if (status != true) + { + printf("freerdp_pre_connect failed\n"); + return false; + } + + status = rdp_client_connect(rdp); + + if (status) + { + if (instance->settings->dump_rfx) + { + instance->update->pcap_rfx = pcap_open(instance->settings->dump_rfx_file, true); + if (instance->update->pcap_rfx) + instance->update->dump_rfx = true; + } + + extension_post_connect(rdp->extension); + + IFCALLRET(instance->PostConnect, status, instance); + + if (status != true) + { + printf("freerdp_post_connect failed\n"); + return false; + } + + if (instance->settings->play_rfx) + { + STREAM* s; + rdpUpdate* update; + pcap_record record; + + s = stream_new(1024); + instance->update->pcap_rfx = pcap_open(instance->settings->play_rfx_file, false); + if (instance->update->pcap_rfx) + instance->update->play_rfx = true; + update = instance->update; + + while (instance->update->play_rfx && pcap_has_next_record(update->pcap_rfx)) + { + pcap_get_next_record_header(update->pcap_rfx, &record); + + s->data = xrealloc(s->data, record.length); + record.data = s->data; + s->size = record.length; + + pcap_get_next_record_content(update->pcap_rfx, &record); + stream_set_pos(s, 0); + + update->BeginPaint(update->context); + update_recv_surfcmds(update, s->size, s); + update->EndPaint(update->context); + } + + xfree(s->data); + return true; + } + } + + return status; +} + +boolean freerdp_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) +{ + rdpRdp* rdp; + + rdp = instance->context->rdp; + transport_get_fds(rdp->transport, rfds, rcount); + + return true; +} + +boolean freerdp_check_fds(freerdp* instance) +{ + int status; + rdpRdp* rdp; + + rdp = instance->context->rdp; + + status = rdp_check_fds(rdp); + + if (status < 0) + return false; + + return true; +} + +void freerdp_send_keep_alive(freerdp* instance) +{ + input_send_synchronize_event(instance->context->rdp->input, 0); +} + +static int freerdp_send_channel_data(freerdp* instance, int channel_id, uint8* data, int size) +{ + return rdp_send_channel_data(instance->context->rdp, channel_id, data, size); +} + +boolean freerdp_disconnect(freerdp* instance) +{ + rdpRdp* rdp; + + rdp = instance->context->rdp; + transport_disconnect(rdp->transport); + + return true; +} + +boolean freerdp_shall_disconnect(freerdp* instance) +{ + + return instance->context->rdp->disconnect; +} + +void freerdp_get_version(int* major, int* minor, int* revision) +{ + if (major != NULL) + *major = FREERDP_VERSION_MAJOR; + + if (minor != NULL) + *minor = FREERDP_VERSION_MINOR; + + if (revision != NULL) + *revision = FREERDP_VERSION_REVISION; +} + +void freerdp_context_new(freerdp* instance) +{ + rdpRdp* rdp; + + rdp = rdp_new(instance); + instance->input = rdp->input; + instance->update = rdp->update; + instance->settings = rdp->settings; + + instance->context = (rdpContext*) xzalloc(instance->context_size); + instance->context->graphics = graphics_new(instance->context); + instance->context->instance = instance; + instance->context->rdp = rdp; + + instance->update->context = instance->context; + instance->update->pointer->context = instance->context; + instance->update->primary->context = instance->context; + instance->update->secondary->context = instance->context; + instance->update->altsec->context = instance->context; + + instance->input->context = instance->context; + + IFCALL(instance->ContextNew, instance, instance->context); +} + +void freerdp_context_free(freerdp* instance) +{ + IFCALL(instance->ContextFree, instance, instance->context); + + rdp_free(instance->context->rdp); + graphics_free(instance->context->graphics); + xfree(instance->context); +} + +uint32 freerdp_error_info(freerdp* instance) +{ + return instance->context->rdp->errorInfo; +} + +freerdp* freerdp_new() +{ + freerdp* instance; + + instance = xzalloc(sizeof(freerdp)); + + if (instance != NULL) + { + instance->context_size = sizeof(rdpContext); + instance->SendChannelData = freerdp_send_channel_data; + } + + return instance; +} + +void freerdp_free(freerdp* freerdp) +{ + if (freerdp) + { + freerdp_context_free(freerdp); + xfree(freerdp); + } +} diff --git a/libfreerdp-core/gcc.c b/libfreerdp-core/gcc.c new file mode 100644 index 0000000..ebea2d4 --- /dev/null +++ b/libfreerdp-core/gcc.c @@ -0,0 +1,1169 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.124 Generic Conference Control (GCC) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "gcc.h" +#include "certificate.h" + +/** + * T.124 GCC is defined in: + * + * http://www.itu.int/rec/T-REC-T.124-199802-S/en + * ITU-T T.124 (02/98): Generic Conference Control + */ + +/** + * ConnectData ::= SEQUENCE + * { + * t124Identifier Key, + * connectPDU OCTET_STRING + * } + * + * Key ::= CHOICE + * { + * object OBJECT_IDENTIFIER, + * h221NonStandard H221NonStandardIdentifier + * } + * + * ConnectGCCPDU ::= CHOICE + * { + * conferenceCreateRequest ConferenceCreateRequest, + * conferenceCreateResponse ConferenceCreateResponse, + * conferenceQueryRequest ConferenceQueryRequest, + * conferenceQueryResponse ConferenceQueryResponse, + * conferenceJoinRequest ConferenceJoinRequest, + * conferenceJoinResponse ConferenceJoinResponse, + * conferenceInviteRequest ConferenceInviteRequest, + * conferenceInviteResponse ConferenceInviteResponse, + * ... + * } + * + * ConferenceCreateRequest ::= SEQUENCE + * { + * conferenceName ConferenceName, + * convenerPassword Password OPTIONAL, + * password Password OPTIONAL, + * lockedConference BOOLEAN, + * listedConference BOOLEAN, + * conductibleConference BOOLEAN, + * terminationMethod TerminationMethod, + * conductorPrivileges SET OF Privilege OPTIONAL, + * conductedPrivileges SET OF Privilege OPTIONAL, + * nonConductedPrivileges SET OF Privilege OPTIONAL, + * conferenceDescription TextString OPTIONAL, + * callerIdentifier TextString OPTIONAL, + * userData UserData OPTIONAL, + * ..., + * conferencePriority ConferencePriority OPTIONAL, + * conferenceMode ConferenceMode OPTIONAL + * } + * + * ConferenceCreateResponse ::= SEQUENCE + * { + * nodeID UserID, + * tag INTEGER, + * result ENUMERATED + * { + * success (0), + * userRejected (1), + * resourcesNotAvailable (2), + * rejectedForSymmetryBreaking (3), + * lockedConferenceNotSupported (4) + * }, + * userData UserData OPTIONAL, + * ... + * } + * + * ConferenceName ::= SEQUENCE + * { + * numeric SimpleNumericString + * text SimpleTextString OPTIONAL, + * ... + * } + * + * SimpleNumericString ::= NumericString (SIZE (1..255)) (FROM ("0123456789")) + * + * UserData ::= SET OF SEQUENCE + * { + * key Key, + * value OCTET_STRING OPTIONAL + * } + * + * H221NonStandardIdentifier ::= OCTET STRING (SIZE (4..255)) + * + * UserID ::= DynamicChannelID + * + * ChannelID ::= INTEGER (1..65535) + * StaticChannelID ::= INTEGER (1..1000) + * DynamicChannelID ::= INTEGER (1001..65535) + * + */ + +/* + * OID = 0.0.20.124.0.1 + * { itu-t(0) recommendation(0) t(20) t124(124) version(0) 1 } + * v.1 of ITU-T Recommendation T.124 (Feb 1998): "Generic Conference Control" + */ +uint8 t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 }; + +uint8 h221_cs_key[4] = "Duca"; +uint8 h221_sc_key[4] = "McDn"; + +/** + * Read a GCC Conference Create Request.\n + * @msdn{cc240836} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_conference_create_request(STREAM* s, rdpSettings* settings) +{ + uint16 length; + uint8 choice; + uint8 number; + uint8 selection; + + /* ConnectData */ + if (!per_read_choice(s, &choice)) + return false; + if (!per_read_object_identifier(s, t124_02_98_oid)) + return false; + + /* ConnectData::connectPDU (OCTET_STRING) */ + if (!per_read_length(s, &length)) + return false; + + /* ConnectGCCPDU */ + if (!per_read_choice(s, &choice)) + return false; + if (!per_read_selection(s, &selection)) + return false; + + /* ConferenceCreateRequest::conferenceName */ + if (!per_read_numeric_string(s, 1)) /* ConferenceName::numeric */ + return false; + if (!per_read_padding(s, 1)) /* padding */ + return false; + + /* UserData (SET OF SEQUENCE) */ + if (!per_read_number_of_sets(s, &number) || number != 1) /* one set of UserData */ + return false; + if (!per_read_choice(s, &choice) || choice != 0xC0) /* UserData::value present + select h221NonStandard (1) */ + return false; + + /* h221NonStandard */ + if (!per_read_octet_string(s, h221_cs_key, 4, 4)) /* h221NonStandard, client-to-server H.221 key, "Duca" */ + return false; + + /* userData::value (OCTET_STRING) */ + if (!per_read_length(s, &length)) + return false; + if (stream_get_left(s) < length) + return false; + if (!gcc_read_client_data_blocks(s, settings, length)) + return false; + + return true; +} + +/** + * Write a GCC Conference Create Request.\n + * @msdn{cc240836} + * @param s stream + * @param user_data client data blocks + */ + +void gcc_write_conference_create_request(STREAM* s, STREAM* user_data) +{ + /* ConnectData */ + per_write_choice(s, 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */ + per_write_object_identifier(s, t124_02_98_oid); /* ITU-T T.124 (02/98) OBJECT_IDENTIFIER */ + + /* ConnectData::connectPDU (OCTET_STRING) */ + per_write_length(s, stream_get_length(user_data) + 14); /* connectPDU length */ + + /* ConnectGCCPDU */ + per_write_choice(s, 0); /* From ConnectGCCPDU select conferenceCreateRequest (0) of type ConferenceCreateRequest */ + per_write_selection(s, 0x08); /* select optional userData from ConferenceCreateRequest */ + + /* ConferenceCreateRequest::conferenceName */ + per_write_numeric_string(s, (uint8*)"1", 1, 1); /* ConferenceName::numeric */ + per_write_padding(s, 1); /* padding */ + + /* UserData (SET OF SEQUENCE) */ + per_write_number_of_sets(s, 1); /* one set of UserData */ + per_write_choice(s, 0xC0); /* UserData::value present + select h221NonStandard (1) */ + + /* h221NonStandard */ + per_write_octet_string(s, h221_cs_key, 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */ + + /* userData::value (OCTET_STRING) */ + per_write_octet_string(s, user_data->data, stream_get_length(user_data), 0); /* array of client data blocks */ +} + +boolean gcc_read_conference_create_response(STREAM* s, rdpSettings* settings) +{ + uint16 length; + uint32 tag; + uint16 nodeID; + uint8 result; + uint8 choice; + uint8 number; + + /* ConnectData */ + per_read_choice(s, &choice); + per_read_object_identifier(s, t124_02_98_oid); + + /* ConnectData::connectPDU (OCTET_STRING) */ + per_read_length(s, &length); + + /* ConnectGCCPDU */ + per_read_choice(s, &choice); + + /* ConferenceCreateResponse::nodeID (UserID) */ + per_read_integer16(s, &nodeID, 1001); + + /* ConferenceCreateResponse::tag (INTEGER) */ + per_read_integer(s, &tag); + + /* ConferenceCreateResponse::result (ENUMERATED) */ + per_read_enumerated(s, &result, MCS_Result_enum_length); + + /* number of UserData sets */ + per_read_number_of_sets(s, &number); + + /* UserData::value present + select h221NonStandard (1) */ + per_read_choice(s, &choice); + + /* h221NonStandard */ + if (!per_read_octet_string(s, h221_sc_key, 4, 4)) /* h221NonStandard, server-to-client H.221 key, "McDn" */ + return false; + + /* userData (OCTET_STRING) */ + per_read_length(s, &length); + if (!gcc_read_server_data_blocks(s, settings, length)) + { + printf("gcc_read_conference_create_response: gcc_read_server_data_blocks failed\n"); + return false; + } + + return true; +} + +void gcc_write_conference_create_response(STREAM* s, STREAM* user_data) +{ + /* ConnectData */ + per_write_choice(s, 0); + per_write_object_identifier(s, t124_02_98_oid); + + /* ConnectData::connectPDU (OCTET_STRING) */ + per_write_length(s, stream_get_length(user_data) + 2); + + /* ConnectGCCPDU */ + per_write_choice(s, 0x14); + + /* ConferenceCreateResponse::nodeID (UserID) */ + per_write_integer16(s, 0x79F3, 1001); + + /* ConferenceCreateResponse::tag (INTEGER) */ + per_write_integer(s, 1); + + /* ConferenceCreateResponse::result (ENUMERATED) */ + per_write_enumerated(s, 0, MCS_Result_enum_length); + + /* number of UserData sets */ + per_write_number_of_sets(s, 1); + + /* UserData::value present + select h221NonStandard (1) */ + per_write_choice(s, 0xC0); + + /* h221NonStandard */ + per_write_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */ + + /* userData (OCTET_STRING) */ + per_write_octet_string(s, user_data->data, stream_get_length(user_data), 0); /* array of server data blocks */ +} + +boolean gcc_read_client_data_blocks(STREAM* s, rdpSettings* settings, int length) +{ + uint16 type; + uint16 blockLength; + int pos; + + while (length > 0) + { + pos = stream_get_pos(s); + gcc_read_user_data_header(s, &type, &blockLength); + + switch (type) + { + case CS_CORE: + if (!gcc_read_client_core_data(s, settings, blockLength - 4)) + return false; + break; + + case CS_SECURITY: + if (!gcc_read_client_security_data(s, settings, blockLength - 4)) + return false; + break; + + case CS_NET: + if (!gcc_read_client_network_data(s, settings, blockLength - 4)) + return false; + break; + + case CS_CLUSTER: + if (!gcc_read_client_cluster_data(s, settings, blockLength - 4)) + return false; + break; + + case CS_MONITOR: + if (!gcc_read_client_monitor_data(s, settings, blockLength - 4)) + return false; + break; + + default: + break; + } + + length -= blockLength; + stream_set_pos(s, pos + blockLength); + } + + return true; +} + +void gcc_write_client_data_blocks(STREAM* s, rdpSettings* settings) +{ + gcc_write_client_core_data(s, settings); + gcc_write_client_cluster_data(s, settings); + gcc_write_client_security_data(s, settings); + gcc_write_client_network_data(s, settings); + + /* extended client data supported */ + + if (settings->negotiationFlags) + gcc_write_client_monitor_data(s, settings); +} + +boolean gcc_read_server_data_blocks(STREAM* s, rdpSettings* settings, int length) +{ + uint16 type; + uint16 offset = 0; + uint16 blockLength; + uint8* holdp; + + while (offset < length) + { + holdp = s->p; + + if (!gcc_read_user_data_header(s, &type, &blockLength)) + { + printf("gcc_read_server_data_blocks: gcc_read_user_data_header failed\n"); + return false; + } + + switch (type) + { + case SC_CORE: + if (!gcc_read_server_core_data(s, settings)) + { + printf("gcc_read_server_data_blocks: gcc_read_server_core_data failed\n"); + return false; + } + break; + + case SC_SECURITY: + if (!gcc_read_server_security_data(s, settings)) + { + printf("gcc_read_server_data_blocks: gcc_read_server_security_data failed\n"); + return false; + } + break; + + case SC_NET: + if (!gcc_read_server_network_data(s, settings)) + { + printf("gcc_read_server_data_blocks: gcc_read_server_network_data failed\n"); + return false; + } + break; + + default: + printf("gcc_read_server_data_blocks: ignoring type=%hu\n", type); + break; + } + offset += blockLength; + s->p = holdp + blockLength; + } + + return true; +} + +void gcc_write_server_data_blocks(STREAM* s, rdpSettings* settings) +{ + gcc_write_server_core_data(s, settings); + gcc_write_server_network_data(s, settings); + gcc_write_server_security_data(s, settings); +} + +boolean gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length) +{ + stream_read_uint16(s, *type); /* type */ + stream_read_uint16(s, *length); /* length */ + + if (*length < 4) + return false; + + if (stream_get_left(s) < *length - 4) + return false; + + return true; +} + +/** + * Write a user data header (TS_UD_HEADER).\n + * @msdn{cc240509} + * @param s stream + * @param type data block type + * @param length data block length + */ + +void gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length) +{ + stream_write_uint16(s, type); /* type */ + stream_write_uint16(s, length); /* length */ +} + +/** + * Read a client core data block (TS_UD_CS_CORE).\n + * @msdn{cc240510} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_client_core_data(STREAM* s, rdpSettings* settings, uint16 blockLength) +{ + uint32 version; + uint16 colorDepth = 0; + uint16 postBeta2ColorDepth = 0; + uint16 highColorDepth = 0; + uint16 supportedColorDepths = 0; + uint16 earlyCapabilityFlags = 0; + uint32 serverSelectedProtocol = 0; + char* str; + + /* Length of all required fields, until imeFileName */ + if (blockLength < 128) + return false; + + stream_read_uint32(s, version); /* version */ + settings->rdp_version = (version == RDP_VERSION_4 ? 4 : 7); + + stream_read_uint16(s, settings->width); /* desktopWidth */ + stream_read_uint16(s, settings->height); /* desktopHeight */ + stream_read_uint16(s, colorDepth); /* colorDepth */ + stream_seek_uint16(s); /* SASSequence (Secure Access Sequence) */ + stream_read_uint32(s, settings->kbd_layout); /* keyboardLayout */ + stream_read_uint32(s, settings->client_build); /* clientBuild */ + + /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ + str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 32); + stream_seek(s, 32); + snprintf(settings->client_hostname, sizeof(settings->client_hostname), "%s", str); + xfree(str); + + stream_read_uint32(s, settings->kbd_type); /* keyboardType */ + stream_read_uint32(s, settings->kbd_subtype); /* keyboardSubType */ + stream_read_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */ + + stream_seek(s, 64); /* imeFileName */ + + blockLength -= 128; + + /** + * The following fields are all optional. If one field is present, all of the preceding + * fields MUST also be present. If one field is not present, all of the subsequent fields + * MUST NOT be present. + * We must check the bytes left before reading each field. + */ + + do + { + if (blockLength < 2) + break; + stream_read_uint16(s, postBeta2ColorDepth); /* postBeta2ColorDepth */ + blockLength -= 2; + + if (blockLength < 2) + break; + stream_seek_uint16(s); /* clientProductID */ + blockLength -= 2; + + if (blockLength < 4) + break; + stream_seek_uint32(s); /* serialNumber */ + blockLength -= 4; + + if (blockLength < 2) + break; + stream_read_uint16(s, highColorDepth); /* highColorDepth */ + blockLength -= 2; + + if (blockLength < 2) + break; + stream_read_uint16(s, supportedColorDepths); /* supportedColorDepths */ + blockLength -= 2; + + if (blockLength < 2) + break; + stream_read_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ + blockLength -= 2; + + if (blockLength < 64) + break; + str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64); + stream_seek(s, 64); + snprintf(settings->client_product_id, sizeof(settings->client_product_id), "%s", str); + xfree(str); + blockLength -= 64; + + if (blockLength < 1) + break; + stream_read_uint8(s, settings->performance_flags); /* connectionType */ + blockLength -= 1; + + if (blockLength < 1) + break; + stream_seek_uint8(s); /* pad1octet */ + blockLength -= 1; + + if (blockLength < 4) + break; + stream_read_uint32(s, serverSelectedProtocol); /* serverSelectedProtocol */ + blockLength -= 4; + + if (settings->selected_protocol != serverSelectedProtocol) + return false; + } while (0); + + if (highColorDepth > 0) + settings->color_depth = highColorDepth; + else if (postBeta2ColorDepth > 0) + { + switch (postBeta2ColorDepth) + { + case RNS_UD_COLOR_4BPP: + settings->color_depth = 4; + break; + case RNS_UD_COLOR_8BPP: + settings->color_depth = 8; + break; + case RNS_UD_COLOR_16BPP_555: + settings->color_depth = 15; + break; + case RNS_UD_COLOR_16BPP_565: + settings->color_depth = 16; + break; + case RNS_UD_COLOR_24BPP: + settings->color_depth = 24; + break; + default: + return false; + } + } + else + { + switch (colorDepth) + { + case RNS_UD_COLOR_4BPP: + settings->color_depth = 4; + break; + case RNS_UD_COLOR_8BPP: + settings->color_depth = 8; + break; + default: + return false; + } + } + + return true; +} + +/** + * Write a client core data block (TS_UD_CS_CORE).\n + * @msdn{cc240510} + * @param s stream + * @param settings rdp settings + */ + +void gcc_write_client_core_data(STREAM* s, rdpSettings* settings) +{ + uint32 version; + char* clientName; + size_t clientNameLength; + uint8 connectionType; + uint16 highColorDepth; + uint16 supportedColorDepths; + uint16 earlyCapabilityFlags; + char* clientDigProductId; + size_t clientDigProductIdLength; + + gcc_write_user_data_header(s, CS_CORE, 216); + + version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; + clientName = freerdp_uniconv_out(settings->uniconv, settings->client_hostname, &clientNameLength); + clientDigProductId = freerdp_uniconv_out(settings->uniconv, settings->client_product_id, &clientDigProductIdLength); + + stream_write_uint32(s, version); /* version */ + stream_write_uint16(s, settings->width); /* desktopWidth */ + stream_write_uint16(s, settings->height); /* desktopHeight */ + stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* colorDepth, ignored because of postBeta2ColorDepth */ + stream_write_uint16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ + stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout */ + stream_write_uint32(s, settings->client_build); /* clientBuild */ + + /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ + if (clientNameLength > 30) + { + clientNameLength = 30; + clientName[clientNameLength] = 0; + clientName[clientNameLength + 1] = 0; + } + stream_write(s, clientName, clientNameLength + 2); + stream_write_zero(s, 32 - clientNameLength - 2); + xfree(clientName); + + stream_write_uint32(s, settings->kbd_type); /* keyboardType */ + stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */ + stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */ + + stream_write_zero(s, 64); /* imeFileName */ + + stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ + stream_write_uint16(s, 1); /* clientProductID */ + stream_write_uint32(s, 0); /* serialNumber (should be initialized to 0) */ + + highColorDepth = MIN(settings->color_depth, 24); + + supportedColorDepths = + RNS_UD_24BPP_SUPPORT | + RNS_UD_16BPP_SUPPORT | + RNS_UD_15BPP_SUPPORT; + + connectionType = settings->connection_type; + earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; + + if (settings->rfx_codec) + connectionType = CONNECTION_TYPE_LAN; + + if (connectionType != 0) + earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; + + if (settings->color_depth == 32) + { + supportedColorDepths |= RNS_UD_32BPP_SUPPORT; + earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; + } + + stream_write_uint16(s, highColorDepth); /* highColorDepth */ + stream_write_uint16(s, supportedColorDepths); /* supportedColorDepths */ + + stream_write_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ + + /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 30 characters) */ + if (clientDigProductIdLength > 62) + { + clientDigProductIdLength = 62; + clientDigProductId[clientDigProductIdLength] = 0; + clientDigProductId[clientDigProductIdLength + 1] = 0; + } + stream_write(s, clientDigProductId, clientDigProductIdLength + 2); + stream_write_zero(s, 64 - clientDigProductIdLength - 2); + xfree(clientDigProductId); + + stream_write_uint8(s, connectionType); /* connectionType */ + stream_write_uint8(s, 0); /* pad1octet */ + + stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */ +} + +boolean gcc_read_server_core_data(STREAM* s, rdpSettings* settings) +{ + uint32 version; + uint32 clientRequestedProtocols; + + stream_read_uint32(s, version); /* version */ + stream_read_uint32(s, clientRequestedProtocols); /* clientRequestedProtocols */ + + if (version == RDP_VERSION_4 && settings->rdp_version > 4) + settings->rdp_version = 4; + else if (version == RDP_VERSION_5_PLUS && settings->rdp_version < 5) + settings->rdp_version = 7; + + return true; +} + +void gcc_write_server_core_data(STREAM* s, rdpSettings* settings) +{ + gcc_write_user_data_header(s, SC_CORE, 12); + + stream_write_uint32(s, settings->rdp_version == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS); + stream_write_uint32(s, settings->requested_protocols); /* clientRequestedProtocols */ +} + +/** + * Read a client security data block (TS_UD_CS_SEC).\n + * @msdn{cc240511} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_client_security_data(STREAM* s, rdpSettings* settings, uint16 blockLength) +{ + if (blockLength < 8) + return false; + + if (settings->encryption) + { + stream_read_uint32(s, settings->encryption_method); /* encryptionMethods */ + if (settings->encryption_method == 0) + stream_read_uint32(s, settings->encryption_method); /* extEncryptionMethods */ + } + else + { + stream_seek(s, 8); + } + return true; +} + +/** + * Write a client security data block (TS_UD_CS_SEC).\n + * @msdn{cc240511} + * @param s stream + * @param settings rdp settings + */ + +void gcc_write_client_security_data(STREAM* s, rdpSettings* settings) +{ + gcc_write_user_data_header(s, CS_SECURITY, 12); + + if (settings->encryption) + { + stream_write_uint32(s, settings->encryption_method); /* encryptionMethods */ + stream_write_uint32(s, 0); /* extEncryptionMethods */ + } + else + { + /* French locale, disable encryption */ + stream_write_uint32(s, 0); /* encryptionMethods */ + stream_write_uint32(s, settings->encryption_method); /* extEncryptionMethods */ + } +} + +boolean gcc_read_server_security_data(STREAM* s, rdpSettings* settings) +{ + uint8* data; + uint32 length; + uint32 serverRandomLen; + uint32 serverCertLen; + + stream_read_uint32(s, settings->encryption_method); /* encryptionMethod */ + stream_read_uint32(s, settings->encryption_level); /* encryptionLevel */ + + if (settings->encryption_method == 0 && settings->encryption_level == 0) + { + /* serverRandom and serverRandom must not be present */ + settings->encryption = false; + settings->encryption_method = ENCRYPTION_METHOD_NONE; + settings->encryption_level = ENCRYPTION_LEVEL_NONE; + return true; + } + + stream_read_uint32(s, serverRandomLen); /* serverRandomLen */ + stream_read_uint32(s, serverCertLen); /* serverCertLen */ + + if (serverRandomLen > 0) + { + /* serverRandom */ + freerdp_blob_alloc(settings->server_random, serverRandomLen); + stream_read(s, settings->server_random->data, serverRandomLen); + } + else + { + return false; + } + + if (serverCertLen > 0) + { + /* serverCertificate */ + freerdp_blob_alloc(settings->server_certificate, serverCertLen); + stream_read(s, settings->server_certificate->data, serverCertLen); + certificate_free(settings->server_cert); + settings->server_cert = certificate_new(); + data = settings->server_certificate->data; + length = settings->server_certificate->length; + + if (!certificate_read_server_certificate(settings->server_cert, data, length)) + return false; + } + else + { + return false; + } + + return true; +} + +static const uint8 initial_signature[] = +{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01 +}; + +void gcc_write_server_security_data(STREAM* s, rdpSettings* settings) +{ + CryptoMd5 md5; + uint8* sigData; + int expLen, keyLen, sigDataLen; + uint8 encryptedSignature[TSSK_KEY_LENGTH]; + uint8 signature[sizeof(initial_signature)]; + uint32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; + + if (!settings->encryption) + { + settings->encryption_method = ENCRYPTION_METHOD_NONE; + settings->encryption_level = ENCRYPTION_LEVEL_NONE; + } + else if ((settings->encryption_method & ENCRYPTION_METHOD_FIPS) != 0) + { + settings->encryption_method = ENCRYPTION_METHOD_FIPS; + } + else if ((settings->encryption_method & ENCRYPTION_METHOD_128BIT) != 0) + { + settings->encryption_method = ENCRYPTION_METHOD_128BIT; + } + else if ((settings->encryption_method & ENCRYPTION_METHOD_40BIT) != 0) + { + settings->encryption_method = ENCRYPTION_METHOD_40BIT; + } + + if (settings->encryption_method != ENCRYPTION_METHOD_NONE) + settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + + headerLen = 12; + keyLen = 0; + wPublicKeyBlobLen = 0; + serverRandomLen = 0; + serverCertLen = 0; + + if (settings->encryption_method != ENCRYPTION_METHOD_NONE || + settings->encryption_level != ENCRYPTION_LEVEL_NONE) + { + serverRandomLen = 32; + + keyLen = settings->server_key->modulus.length; + expLen = sizeof(settings->server_key->exponent); + wPublicKeyBlobLen = 4; /* magic (RSA1) */ + wPublicKeyBlobLen += 4; /* keylen */ + wPublicKeyBlobLen += 4; /* bitlen */ + wPublicKeyBlobLen += 4; /* datalen */ + wPublicKeyBlobLen += expLen; + wPublicKeyBlobLen += keyLen; + wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ + + serverCertLen = 4; /* dwVersion */ + serverCertLen += 4; /* dwSigAlgId */ + serverCertLen += 4; /* dwKeyAlgId */ + serverCertLen += 2; /* wPublicKeyBlobType */ + serverCertLen += 2; /* wPublicKeyBlobLen */ + serverCertLen += wPublicKeyBlobLen; + serverCertLen += 2; /* wSignatureBlobType */ + serverCertLen += 2; /* wSignatureBlobLen */ + serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ + serverCertLen += 8; /* 8 bytes of zero padding */ + + headerLen += sizeof(serverRandomLen); + headerLen += sizeof(serverCertLen); + headerLen += serverRandomLen; + headerLen += serverCertLen; + } + + gcc_write_user_data_header(s, SC_SECURITY, headerLen); + + stream_write_uint32(s, settings->encryption_method); /* encryptionMethod */ + stream_write_uint32(s, settings->encryption_level); /* encryptionLevel */ + + if (settings->encryption_method == ENCRYPTION_METHOD_NONE && + settings->encryption_level == ENCRYPTION_LEVEL_NONE) + { + return; + } + + stream_write_uint32(s, serverRandomLen); /* serverRandomLen */ + stream_write_uint32(s, serverCertLen); /* serverCertLen */ + + freerdp_blob_alloc(settings->server_random, serverRandomLen); + crypto_nonce(settings->server_random->data, serverRandomLen); + stream_write(s, settings->server_random->data, serverRandomLen); + + sigData = stream_get_tail(s); + + stream_write_uint32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ + stream_write_uint32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ + stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ + stream_write_uint16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ + + stream_write_uint16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ + stream_write(s, "RSA1", 4); /* magic */ + stream_write_uint32(s, keyLen + 8); /* keylen */ + stream_write_uint32(s, keyLen * 8); /* bitlen */ + stream_write_uint32(s, keyLen - 1); /* datalen */ + + stream_write(s, settings->server_key->exponent, expLen); + stream_write(s, settings->server_key->modulus.data, keyLen); + stream_write_zero(s, 8); + + sigDataLen = stream_get_tail(s) - sigData; + + stream_write_uint16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ + stream_write_uint16(s, keyLen + 8); /* wSignatureBlobLen */ + + memcpy(signature, initial_signature, sizeof(initial_signature)); + + md5 = crypto_md5_init(); + crypto_md5_update(md5, sigData, sigDataLen); + crypto_md5_final(md5, signature); + + crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, + tssk_modulus, tssk_privateExponent, encryptedSignature); + + stream_write(s, encryptedSignature, sizeof(encryptedSignature)); + stream_write_zero(s, 8); +} + +/** + * Read a client network data block (TS_UD_CS_NET).\n + * @msdn{cc240512} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_client_network_data(STREAM* s, rdpSettings* settings, uint16 blockLength) +{ + int i; + + if (blockLength < 4) + return false; + + stream_read_uint32(s, settings->num_channels); /* channelCount */ + if (blockLength < 4 + settings->num_channels * 12) + return false; + if (settings->num_channels > 16) + return false; + + /* channelDefArray */ + for (i = 0; i < settings->num_channels; i++) + { + /* CHANNEL_DEF */ + stream_read(s, settings->channels[i].name, 8); /* name (8 bytes) */ + stream_read_uint32(s, settings->channels[i].options); /* options (4 bytes) */ + settings->channels[i].channel_id = MCS_GLOBAL_CHANNEL_ID + 1 + i; + } + + return true; +} + +/** + * Write a client network data block (TS_UD_CS_NET).\n + * @msdn{cc240512} + * @param s stream + * @param settings rdp settings + */ + +void gcc_write_client_network_data(STREAM* s, rdpSettings* settings) +{ + int i; + uint16 length; + + if (settings->num_channels > 0) + { + length = settings->num_channels * 12 + 8; + gcc_write_user_data_header(s, CS_NET, length); + + stream_write_uint32(s, settings->num_channels); /* channelCount */ + + /* channelDefArray */ + for (i = 0; i < settings->num_channels; i++) + { + /* CHANNEL_DEF */ + stream_write(s, settings->channels[i].name, 8); /* name (8 bytes) */ + stream_write_uint32(s, settings->channels[i].options); /* options (4 bytes) */ + } + } +} + +boolean gcc_read_server_network_data(STREAM* s, rdpSettings* settings) +{ + int i; + uint16 MCSChannelId; + uint16 channelCount; + uint16 channelId; + + stream_read_uint16(s, MCSChannelId); /* MCSChannelId */ + stream_read_uint16(s, channelCount); /* channelCount */ + + if (channelCount != settings->num_channels) + { + printf("requested %d channels, got %d instead\n", + settings->num_channels, channelCount); + } + + for (i = 0; i < channelCount; i++) + { + stream_read_uint16(s, channelId); /* channelId */ + settings->channels[i].channel_id = channelId; + } + + if (channelCount % 2 == 1) + stream_seek(s, 2); /* padding */ + + return true; +} + +void gcc_write_server_network_data(STREAM* s, rdpSettings* settings) +{ + int i; + + gcc_write_user_data_header(s, SC_NET, 8 + settings->num_channels * 2 + (settings->num_channels % 2 == 1 ? 2 : 0)); + + stream_write_uint16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */ + stream_write_uint16(s, settings->num_channels); /* channelCount */ + + for (i = 0; i < settings->num_channels; i++) + { + stream_write_uint16(s, settings->channels[i].channel_id); + } + + if (settings->num_channels % 2 == 1) + stream_write_uint16(s, 0); +} + +/** + * Read a client cluster data block (TS_UD_CS_CLUSTER).\n + * @msdn{cc240514} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_client_cluster_data(STREAM* s, rdpSettings* settings, uint16 blockLength) +{ + uint32 flags; + + if (blockLength < 8) + return false; + + stream_read_uint32(s, flags); /* flags */ + + if ((flags | REDIRECTED_SESSIONID_FIELD_VALID)) + stream_read_uint32(s, settings->redirected_session_id); /* redirectedSessionID */ + + return true; +} + +/** + * Write a client cluster data block (TS_UD_CS_CLUSTER).\n + * @msdn{cc240514} + * @param s stream + * @param settings rdp settings + */ + +void gcc_write_client_cluster_data(STREAM* s, rdpSettings* settings) +{ + uint32 flags; + + gcc_write_user_data_header(s, CS_CLUSTER, 12); + + flags = REDIRECTION_SUPPORTED | (REDIRECTION_VERSION4 << 2); + + if (settings->console_session || settings->redirected_session_id) + flags |= REDIRECTED_SESSIONID_FIELD_VALID; + + stream_write_uint32(s, flags); /* flags */ + stream_write_uint32(s, settings->redirected_session_id); /* redirectedSessionID */ +} + +/** + * Read a client monitor data block (TS_UD_CS_MONITOR).\n + * @msdn{dd305336} + * @param s stream + * @param settings rdp settings + */ + +boolean gcc_read_client_monitor_data(STREAM* s, rdpSettings* settings, uint16 blockLength) +{ + printf("CS_MONITOR\n"); + return true; +} + +/** + * Write a client monitor data block (TS_UD_CS_MONITOR).\n + * @msdn{dd305336} + * @param s stream + * @param settings rdp settings + */ + +void gcc_write_client_monitor_data(STREAM* s, rdpSettings* settings) +{ + int i; + uint16 length; + uint32 left, top, right, bottom, flags; + + if (settings->num_monitors > 1) + { + length = (20 * settings->num_monitors) + 12; + gcc_write_user_data_header(s, CS_MONITOR, length); + + stream_write_uint32(s, 0); /* flags */ + stream_write_uint32(s, settings->num_monitors); /* monitorCount */ + + for (i = 0; i < settings->num_monitors; i++) + { + left = settings->monitors[i].x; + top = settings->monitors[i].y; + right = settings->monitors[i].x + settings->monitors[i].width - 1; + bottom = settings->monitors[i].y + settings->monitors[i].height - 1; + flags = settings->monitors[i].is_primary ? MONITOR_PRIMARY : 0; + + stream_write_uint32(s, left); /* left */ + stream_write_uint32(s, top); /* top */ + stream_write_uint32(s, right); /* right */ + stream_write_uint32(s, bottom); /* bottom */ + stream_write_uint32(s, flags); /* flags */ + } + } +} + diff --git a/libfreerdp-core/gcc.h b/libfreerdp-core/gcc.h new file mode 100644 index 0000000..f93b337 --- /dev/null +++ b/libfreerdp-core/gcc.h @@ -0,0 +1,111 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.124 Generic Conference Control (GCC) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GCC_H +#define __GCC_H + +#include "per.h" +#include "mcs.h" + +#include +#include +#include + +/* Client to Server (CS) data blocks */ +#define CS_CORE 0xC001 +#define CS_SECURITY 0xC002 +#define CS_NET 0xC003 +#define CS_CLUSTER 0xC004 +#define CS_MONITOR 0xC005 + +/* Server to Client (SC) data blocks */ +#define SC_CORE 0x0C01 +#define SC_SECURITY 0x0C02 +#define SC_NET 0x0C03 + +/* RDP version */ +#define RDP_VERSION_4 0x00080001 +#define RDP_VERSION_5_PLUS 0x00080004 + +/* Color depth */ +#define RNS_UD_COLOR_4BPP 0xCA00 +#define RNS_UD_COLOR_8BPP 0xCA01 +#define RNS_UD_COLOR_16BPP_555 0xCA02 +#define RNS_UD_COLOR_16BPP_565 0xCA03 +#define RNS_UD_COLOR_24BPP 0xCA04 + +/* Secure Access Sequence */ +#define RNS_UD_SAS_DEL 0xAA03 + +/* Supported Color Depths */ +#define RNS_UD_24BPP_SUPPORT 0x0001 +#define RNS_UD_16BPP_SUPPORT 0x0002 +#define RNS_UD_15BPP_SUPPORT 0x0004 +#define RNS_UD_32BPP_SUPPORT 0x0008 + +/* Early Capability Flags */ +#define RNS_UD_CS_SUPPORT_ERRINFO_PDU 0x0001 +#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002 +#define RNS_UD_CS_SUPPORT_STATUSINFO_PDU 0x0004 +#define RNS_UD_CS_STRONG_ASYMMETRIC_KEYS 0x0008 +#define RNS_UD_CS_VALID_CONNECTION_TYPE 0x0020 +#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040 + +/* Cluster Information Flags */ +#define REDIRECTION_SUPPORTED 0x00000001 +#define REDIRECTED_SESSIONID_FIELD_VALID 0x00000002 +#define REDIRECTED_SMARTCARD 0x00000040 + +#define REDIRECTION_VERSION1 0x00 +#define REDIRECTION_VERSION2 0x01 +#define REDIRECTION_VERSION3 0x02 +#define REDIRECTION_VERSION4 0x03 +#define REDIRECTION_VERSION5 0x04 + +/* Monitor Flags */ +#define MONITOR_PRIMARY 0x00000001 + +boolean gcc_read_conference_create_request(STREAM* s, rdpSettings* settings); +void gcc_write_conference_create_request(STREAM* s, STREAM* user_data); +boolean gcc_read_conference_create_response(STREAM* s, rdpSettings* settings); +void gcc_write_conference_create_response(STREAM* s, STREAM* user_data); +boolean gcc_read_client_data_blocks(STREAM* s, rdpSettings *settings, int length); +void gcc_write_client_data_blocks(STREAM* s, rdpSettings *settings); +boolean gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length); +void gcc_write_server_data_blocks(STREAM* s, rdpSettings *settings); +boolean gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length); +void gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length); +boolean gcc_read_client_core_data(STREAM* s, rdpSettings *settings, uint16 blockLength); +void gcc_write_client_core_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_server_core_data(STREAM* s, rdpSettings *settings); +void gcc_write_server_core_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_client_security_data(STREAM* s, rdpSettings *settings, uint16 blockLength); +void gcc_write_client_security_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings); +void gcc_write_server_security_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_client_network_data(STREAM* s, rdpSettings *settings, uint16 blockLength); +void gcc_write_client_network_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_server_network_data(STREAM* s, rdpSettings *settings); +void gcc_write_server_network_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_client_cluster_data(STREAM* s, rdpSettings *settings, uint16 blockLength); +void gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings); +boolean gcc_read_client_monitor_data(STREAM* s, rdpSettings *settings, uint16 blockLength); +void gcc_write_client_monitor_data(STREAM* s, rdpSettings *settings); + +#endif /* __GCC_H */ diff --git a/libfreerdp-core/graphics.c b/libfreerdp-core/graphics.c new file mode 100644 index 0000000..f6b3bab --- /dev/null +++ b/libfreerdp-core/graphics.c @@ -0,0 +1,224 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +/* Bitmap Class */ + +rdpBitmap* Bitmap_Alloc(rdpContext* context) +{ + rdpBitmap* bitmap; + rdpGraphics* graphics; + + graphics = context->graphics; + bitmap = (rdpBitmap*) xmalloc(graphics->Bitmap_Prototype->size); + + if (bitmap != NULL) + { + memcpy(bitmap, context->graphics->Bitmap_Prototype, sizeof(rdpBitmap)); + bitmap->data = NULL; + } + + return bitmap; +} + +void Bitmap_New(rdpContext* context, rdpBitmap* bitmap) +{ + +} + +void Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +{ + if (bitmap != NULL) + { + bitmap->Free(context, bitmap); + + if (bitmap->data != NULL) + xfree(bitmap->data); + + xfree(bitmap); + } +} + +void Bitmap_SetRectangle(rdpContext* context, rdpBitmap* bitmap, uint16 left, uint16 top, uint16 right, uint16 bottom) +{ + bitmap->left = left; + bitmap->top = top; + bitmap->right = right; + bitmap->bottom = bottom; +} + +void Bitmap_SetDimensions(rdpContext* context, rdpBitmap* bitmap, uint16 width, uint16 height) +{ + bitmap->width = width; + bitmap->height = height; +} + +/* static method */ +void Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primary) +{ + context->graphics->Bitmap_Prototype->SetSurface(context, bitmap, primary); +} + +void graphics_register_bitmap(rdpGraphics* graphics, rdpBitmap* bitmap) +{ + memcpy(graphics->Bitmap_Prototype, bitmap, sizeof(rdpBitmap)); +} + +/* Pointer Class */ + +rdpPointer* Pointer_Alloc(rdpContext* context) +{ + rdpPointer* pointer; + rdpGraphics* graphics; + + graphics = context->graphics; + pointer = (rdpPointer*) xmalloc(graphics->Pointer_Prototype->size); + + if (pointer != NULL) + { + memcpy(pointer, context->graphics->Pointer_Prototype, sizeof(rdpPointer)); + } + + return pointer; +} + +void Pointer_New(rdpContext* context, rdpPointer* pointer) +{ + +} + +void Pointer_Free(rdpContext* context, rdpPointer* pointer) +{ + if (pointer != NULL) + { + pointer->Free(context, pointer); + + if (pointer->xorMaskData) + xfree(pointer->xorMaskData); + + if (pointer->andMaskData) + xfree(pointer->andMaskData); + + xfree(pointer); + } +} + +/* static method */ +void Pointer_Set(rdpContext* context, rdpPointer* pointer) +{ + context->graphics->Pointer_Prototype->Set(context, pointer); +} + +void graphics_register_pointer(rdpGraphics* graphics, rdpPointer* pointer) +{ + memcpy(graphics->Pointer_Prototype, pointer, sizeof(rdpPointer)); +} + +/* Glyph Class */ + +rdpGlyph* Glyph_Alloc(rdpContext* context) +{ + rdpGlyph* glyph; + rdpGraphics* graphics; + + graphics = context->graphics; + glyph = (rdpGlyph*) xmalloc(graphics->Glyph_Prototype->size); + + if (glyph != NULL) + { + memcpy(glyph, context->graphics->Glyph_Prototype, sizeof(rdpGlyph)); + } + + return glyph; +} + +void Glyph_New(rdpContext* context, rdpGlyph* glyph) +{ + context->graphics->Glyph_Prototype->New(context, glyph); +} + +void Glyph_Free(rdpContext* context, rdpGlyph* glyph) +{ + context->graphics->Glyph_Prototype->Free(context, glyph); +} + +void Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) +{ + context->graphics->Glyph_Prototype->Draw(context, glyph, x, y); +} + +void Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + context->graphics->Glyph_Prototype->BeginDraw(context, x, y, width, height, bgcolor, fgcolor); +} + +void Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + context->graphics->Glyph_Prototype->EndDraw(context, x, y, width, height, bgcolor, fgcolor); +} + +void graphics_register_glyph(rdpGraphics* graphics, rdpGlyph* glyph) +{ + memcpy(graphics->Glyph_Prototype, glyph, sizeof(rdpGlyph)); +} + +/* Graphics Module */ + +rdpGraphics* graphics_new(rdpContext* context) +{ + rdpGraphics* graphics; + + graphics = (rdpGraphics*) xzalloc(sizeof(rdpGraphics)); + + if (graphics != NULL) + { + graphics->context = context; + + graphics->Bitmap_Prototype = (rdpBitmap*) xzalloc(sizeof(rdpBitmap)); + graphics->Bitmap_Prototype->size = sizeof(rdpBitmap); + graphics->Bitmap_Prototype->New = Bitmap_New; + graphics->Bitmap_Prototype->Free = Bitmap_Free; + + graphics->Pointer_Prototype = (rdpPointer*) xzalloc(sizeof(rdpPointer)); + graphics->Pointer_Prototype->size = sizeof(rdpPointer); + graphics->Pointer_Prototype->New = Pointer_New; + graphics->Pointer_Prototype->Free = Pointer_Free; + + graphics->Glyph_Prototype = (rdpGlyph*) xzalloc(sizeof(rdpGlyph)); + graphics->Glyph_Prototype->size = sizeof(rdpGlyph); + graphics->Glyph_Prototype->New = Glyph_New; + graphics->Glyph_Prototype->Free = Glyph_Free; + } + + return graphics; +} + +void graphics_free(rdpGraphics* graphics) +{ + if (graphics != NULL) + { + xfree(graphics->Bitmap_Prototype); + xfree(graphics->Pointer_Prototype); + xfree(graphics->Glyph_Prototype); + xfree(graphics); + } +} diff --git a/libfreerdp-core/info.c b/libfreerdp-core/info.c new file mode 100644 index 0000000..21a7d4f --- /dev/null +++ b/libfreerdp-core/info.c @@ -0,0 +1,726 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Client Info + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "info.h" + +#define INFO_TYPE_LOGON 0x00000000 +#define INFO_TYPE_LOGON_LONG 0x00000001 +#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002 +#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003 + +/* +static const char* const INFO_TYPE_LOGON_STRINGS[] = +{ + "Logon Info V1", + "Logon Info V2", + "Logon Plain Notify", + "Logon Extended Info" +}; +*/ + +/** + * Read SYSTEM_TIME structure (TS_SYSTEMTIME).\n + * @msdn{cc240478} + * @param s stream + * @param system_time system time structure + */ + +void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time) +{ + stream_read_uint16(s, system_time->wYear); /* wYear, must be set to 0 */ + stream_read_uint16(s, system_time->wMonth); /* wMonth */ + stream_read_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */ + stream_read_uint16(s, system_time->wDay); /* wDay */ + stream_read_uint16(s, system_time->wHour); /* wHour */ + stream_read_uint16(s, system_time->wMinute); /* wMinute */ + stream_read_uint16(s, system_time->wSecond); /* wSecond */ + stream_read_uint16(s, system_time->wMilliseconds); /* wMilliseconds */ +} + +/** + * Write SYSTEM_TIME structure (TS_SYSTEMTIME).\n + * @msdn{cc240478} + * @param s stream + * @param system_time system time structure + */ + +void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time) +{ + stream_write_uint16(s, system_time->wYear); /* wYear, must be set to 0 */ + stream_write_uint16(s, system_time->wMonth); /* wMonth */ + stream_write_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */ + stream_write_uint16(s, system_time->wDay); /* wDay */ + stream_write_uint16(s, system_time->wHour); /* wHour */ + stream_write_uint16(s, system_time->wMinute); /* wMinute */ + stream_write_uint16(s, system_time->wSecond); /* wSecond */ + stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */ +} + +/** + * Get client time zone information.\n + * @param s stream + * @param settings settings + */ + +void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings) +{ + time_t t; + struct tm* local_time; + TIME_ZONE_INFO* clientTimeZone; + + time(&t); + local_time = localtime(&t); + clientTimeZone = settings->client_time_zone; + +#if defined(sun) + if(local_time->tm_isdst > 0) + clientTimeZone->bias = (uint32) (altzone / 3600); + else + clientTimeZone->bias = (uint32) (timezone / 3600); +#elif defined(HAVE_TM_GMTOFF) + if(local_time->tm_gmtoff >= 0) + clientTimeZone->bias = (uint32) (local_time->tm_gmtoff / 60); + else + clientTimeZone->bias = (uint32) ((-1 * local_time->tm_gmtoff) / 60 + 720); +#else + clientTimeZone->bias = 0; +#endif + + if(local_time->tm_isdst > 0) + { + clientTimeZone->standardBias = clientTimeZone->bias - 60; + clientTimeZone->daylightBias = clientTimeZone->bias; + } + else + { + clientTimeZone->standardBias = clientTimeZone->bias; + clientTimeZone->daylightBias = clientTimeZone->bias + 60; + } + + strftime(clientTimeZone->standardName, 32, "%Z, Standard Time", local_time); + clientTimeZone->standardName[31] = 0; + strftime(clientTimeZone->daylightName, 32, "%Z, Summer Time", local_time); + clientTimeZone->daylightName[31] = 0; +} + +/** + * Read client time zone information (TS_TIME_ZONE_INFORMATION).\n + * @msdn{cc240477} + * @param s stream + * @param settings settings + */ + +boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings) +{ + char* str; + TIME_ZONE_INFO* clientTimeZone; + + if (stream_get_left(s) < 172) + return false; + + clientTimeZone = settings->client_time_zone; + + stream_read_uint32(s, clientTimeZone->bias); /* Bias */ + + /* standardName (64 bytes) */ + str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64); + stream_seek(s, 64); + strncpy(clientTimeZone->standardName, str, sizeof(clientTimeZone->standardName)); + xfree(str); + + rdp_read_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ + stream_read_uint32(s, clientTimeZone->standardBias); /* StandardBias */ + + /* daylightName (64 bytes) */ + str = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), 64); + stream_seek(s, 64); + strncpy(clientTimeZone->daylightName, str, sizeof(clientTimeZone->daylightName)); + xfree(str); + + rdp_read_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ + stream_read_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */ + + return true; +} + +/** + * Write client time zone information (TS_TIME_ZONE_INFORMATION).\n + * @msdn{cc240477} + * @param s stream + * @param settings settings + */ + +void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) +{ + size_t length; + uint8* standardName; + uint8* daylightName; + size_t standardNameLength; + size_t daylightNameLength; + TIME_ZONE_INFO* clientTimeZone; + + rdp_get_client_time_zone(s, settings); + clientTimeZone = settings->client_time_zone; + + standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length); + standardNameLength = length; + + daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length); + daylightNameLength = length; + + if (standardNameLength > 62) + standardNameLength = 62; + + if (daylightNameLength > 62) + daylightNameLength = 62; + + stream_write_uint32(s, clientTimeZone->bias); /* Bias */ + + /* standardName (64 bytes) */ + stream_write(s, standardName, standardNameLength); + stream_write_zero(s, 64 - standardNameLength); + + rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ + stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */ + + /* daylightName (64 bytes) */ + stream_write(s, daylightName, daylightNameLength); + stream_write_zero(s, 64 - daylightNameLength); + + rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ + stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */ + + xfree(standardName); + xfree(daylightName); +} + +/** + * Read Server Auto Reconnect Cookie (ARC_SC_PRIVATE_PACKET).\n + * @msdn{cc240540} + * @param s stream + * @param settings settings + */ + +void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) +{ + ARC_SC_PRIVATE_PACKET* autoReconnectCookie; + autoReconnectCookie = settings->server_auto_reconnect_cookie; + + stream_read_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + stream_read_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */ + stream_read_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + stream_read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ +} + +/** + * Read Client Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n + * @msdn{cc240541} + * @param s stream + * @param settings settings + */ + +boolean rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) +{ + ARC_CS_PRIVATE_PACKET* autoReconnectCookie; + autoReconnectCookie = settings->client_auto_reconnect_cookie; + + if (stream_get_left(s) < 28) + return false; + + stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */ + stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ + + return true; +} + +/** + * Write Client Auto Reconnect Cookie (ARC_CS_PRIVATE_PACKET).\n + * @msdn{cc240541} + * @param s stream + * @param settings settings + */ + +void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings) +{ + ARC_CS_PRIVATE_PACKET* autoReconnectCookie; + autoReconnectCookie = settings->client_auto_reconnect_cookie; + + stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ + stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */ + stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ + stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */ +} + +/** + * Read Extended Info Packet (TS_EXTENDED_INFO_PACKET).\n + * @msdn{cc240476} + * @param s stream + * @param settings settings + */ + +boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings) +{ + uint16 clientAddressFamily; + uint16 cbClientAddress; + uint16 cbClientDir; + uint16 cbAutoReconnectLen; + + stream_read_uint16(s, clientAddressFamily); /* clientAddressFamily */ + stream_read_uint16(s, cbClientAddress); /* cbClientAddress */ + + settings->ipv6 = (clientAddressFamily == ADDRESS_FAMILY_INET6 ? true : false); + if (stream_get_left(s) < cbClientAddress) + return false; + settings->ip_address = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientAddress); + stream_seek(s, cbClientAddress); + + stream_read_uint16(s, cbClientDir); /* cbClientDir */ + if (stream_get_left(s) < cbClientDir) + return false; + if (settings->client_dir) + xfree(settings->client_dir); + settings->client_dir = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbClientDir); + stream_seek(s, cbClientDir); + + if (!rdp_read_client_time_zone(s, settings)) + return false; + + stream_seek_uint32(s); /* clientSessionId, should be set to 0 */ + stream_read_uint32(s, settings->performance_flags); /* performanceFlags */ + + stream_read_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ + + if (cbAutoReconnectLen > 0) + return rdp_read_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ + + /* reserved1 (2 bytes) */ + /* reserved2 (2 bytes) */ + + return true; +} + +/** + * Write Extended Info Packet (TS_EXTENDED_INFO_PACKET).\n + * @msdn{cc240476} + * @param s stream + * @param settings settings + */ + +void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings) +{ + size_t length; + uint16 clientAddressFamily; + uint8* clientAddress; + uint16 cbClientAddress; + uint8* clientDir; + uint16 cbClientDir; + uint16 cbAutoReconnectLen; + + clientAddressFamily = settings->ipv6 ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET; + + clientAddress = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->ip_address, &length); + cbClientAddress = length; + + clientDir = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->client_dir, &length); + cbClientDir = length; + + cbAutoReconnectLen = settings->client_auto_reconnect_cookie->cbLen; + + stream_write_uint16(s, clientAddressFamily); /* clientAddressFamily */ + + stream_write_uint16(s, cbClientAddress + 2); /* cbClientAddress */ + + if (cbClientAddress > 0) + stream_write(s, clientAddress, cbClientAddress); /* clientAddress */ + stream_write_uint16(s, 0); + + stream_write_uint16(s, cbClientDir + 2); /* cbClientDir */ + + if (cbClientDir > 0) + stream_write(s, clientDir, cbClientDir); /* clientDir */ + stream_write_uint16(s, 0); + + rdp_write_client_time_zone(s, settings); /* clientTimeZone */ + + stream_write_uint32(s, 0); /* clientSessionId, should be set to 0 */ + stream_write_uint32(s, settings->performance_flags); /* performanceFlags */ + + stream_write_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ + + if (cbAutoReconnectLen > 0) + rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ + + /* reserved1 (2 bytes) */ + /* reserved2 (2 bytes) */ + + xfree(clientAddress); + xfree(clientDir); +} + +/** + * Read Info Packet (TS_INFO_PACKET).\n + * @msdn{cc240475} + * @param s stream + * @param settings settings + */ + +boolean rdp_read_info_packet(STREAM* s, rdpSettings* settings) +{ + uint32 flags; + uint16 cbDomain; + uint16 cbUserName; + uint16 cbPassword; + uint16 cbAlternateShell; + uint16 cbWorkingDir; + + stream_seek_uint32(s); /* CodePage */ + stream_read_uint32(s, flags); /* flags */ + + settings->autologon = ((flags & INFO_AUTOLOGON) ? true : false); + settings->remote_app = ((flags & INFO_RAIL) ? true : false); + settings->console_audio = ((flags & INFO_REMOTECONSOLEAUDIO) ? true : false); + settings->compression = ((flags & INFO_COMPRESSION) ? true : false); + + stream_read_uint16(s, cbDomain); /* cbDomain */ + stream_read_uint16(s, cbUserName); /* cbUserName */ + stream_read_uint16(s, cbPassword); /* cbPassword */ + stream_read_uint16(s, cbAlternateShell); /* cbAlternateShell */ + stream_read_uint16(s, cbWorkingDir); /* cbWorkingDir */ + + if (stream_get_left(s) < cbDomain + 2) + return false; + if (cbDomain > 0) + { + settings->domain = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbDomain); + stream_seek(s, cbDomain); + } + stream_seek(s, 2); + + if (stream_get_left(s) < cbUserName + 2) + return false; + if (cbUserName > 0) + { + settings->username = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbUserName); + stream_seek(s, cbUserName); + } + stream_seek(s, 2); + + if (stream_get_left(s) < cbPassword + 2) + return false; + if (cbPassword > 0) + { + settings->password = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbPassword); + stream_seek(s, cbPassword); + } + stream_seek(s, 2); + + if (stream_get_left(s) < cbAlternateShell + 2) + return false; + if (cbAlternateShell > 0) + { + settings->shell = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbAlternateShell); + stream_seek(s, cbAlternateShell); + } + stream_seek(s, 2); + + if (stream_get_left(s) < cbWorkingDir + 2) + return false; + if (cbWorkingDir > 0) + { + settings->directory = freerdp_uniconv_in(settings->uniconv, stream_get_tail(s), cbWorkingDir); + stream_seek(s, cbWorkingDir); + } + stream_seek(s, 2); + + if (settings->rdp_version >= 5) + return rdp_read_extended_info_packet(s, settings); /* extraInfo */ + + return true; +} + +/** + * Write Info Packet (TS_INFO_PACKET).\n + * @msdn{cc240475} + * @param s stream + * @param settings settings + */ + +void rdp_write_info_packet(STREAM* s, rdpSettings* settings) +{ + size_t length; + uint32 flags; + uint8* domain; + uint16 cbDomain; + uint8* userName; + uint16 cbUserName; + uint8* password; + uint16 cbPassword; + size_t passwordLength; + uint8* alternateShell; + uint16 cbAlternateShell; + uint8* workingDir; + uint16 cbWorkingDir; + boolean usedPasswordCookie = false; + + flags = INFO_MOUSE | + INFO_UNICODE | + INFO_LOGONERRORS | + INFO_LOGONNOTIFY | + INFO_MAXIMIZESHELL | + INFO_ENABLEWINDOWSKEY | + INFO_DISABLECTRLALTDEL | + RNS_INFO_AUDIOCAPTURE; + + if (settings->autologon) + flags |= INFO_AUTOLOGON; + + if (settings->remote_app) + flags |= INFO_RAIL; + + if (settings->console_audio) + flags |= INFO_REMOTECONSOLEAUDIO; + + if (settings->compression) + flags |= INFO_COMPRESSION | INFO_PACKET_COMPR_TYPE_64K; + + domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length); + cbDomain = length; + + userName = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->username, &length); + cbUserName = length; + + if (settings->password_cookie && settings->password_cookie->length > 0) + { + usedPasswordCookie = true; + password = (uint8*)settings->password_cookie->data; + passwordLength = settings->password_cookie->length; + cbPassword = passwordLength - 2; + } + else + { + password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &passwordLength); + cbPassword = passwordLength; + } + + alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length); + cbAlternateShell = length; + + workingDir = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->directory, &length); + cbWorkingDir = length; + + stream_write_uint32(s, 0); /* CodePage */ + stream_write_uint32(s, flags); /* flags */ + + stream_write_uint16(s, cbDomain); /* cbDomain */ + stream_write_uint16(s, cbUserName); /* cbUserName */ + stream_write_uint16(s, cbPassword); /* cbPassword */ + stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */ + stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */ + + if (cbDomain > 0) + stream_write(s, domain, cbDomain); + stream_write_uint16(s, 0); + + if (cbUserName > 0) + stream_write(s, userName, cbUserName); + stream_write_uint16(s, 0); + + if (cbPassword > 0) + stream_write(s, password, passwordLength); + stream_write_uint16(s, 0); + + if (cbAlternateShell > 0) + stream_write(s, alternateShell, cbAlternateShell); + stream_write_uint16(s, 0); + + if (cbWorkingDir > 0) + stream_write(s, workingDir, cbWorkingDir); + stream_write_uint16(s, 0); + + xfree(domain); + xfree(userName); + xfree(alternateShell); + xfree(workingDir); + + if (!usedPasswordCookie) + xfree(password); + + if (settings->rdp_version >= 5) + rdp_write_extended_info_packet(s, settings); /* extraInfo */ +} + +/** + * Read Client Info PDU (CLIENT_INFO_PDU).\n + * @msdn{cc240474} + * @param rdp RDP module + * @param s stream + */ + +boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s) +{ + uint16 length; + uint16 channelId; + uint16 securityFlags; + + if (!rdp_read_header(rdp, s, &length, &channelId)) + return false; + + rdp_read_security_header(s, &securityFlags); + if ((securityFlags & SEC_INFO_PKT) == 0) + return false; + + if (rdp->settings->encryption) + { + if (securityFlags & SEC_REDIRECTION_PKT) + { + printf("Error: SEC_REDIRECTION_PKT unsupported\n"); + return false; + } + if (securityFlags & SEC_ENCRYPT) + { + if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return false; + } + } + } + + return rdp_read_info_packet(s, rdp->settings); +} + +/** + * Send Client Info PDU (CLIENT_INFO_PDU).\n + * @msdn{cc240474} + * @param rdp RDP module + */ + +boolean rdp_send_client_info(rdpRdp* rdp) +{ + STREAM* s; + + //rdp->settings->crypt_flags |= SEC_INFO_PKT; + rdp->sec_flags |= SEC_INFO_PKT; + s = rdp_send_stream_init(rdp); + rdp_write_info_packet(s, rdp->settings); + return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); +} + +void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s) +{ + uint32 cbDomain; + uint32 cbUserName; + + stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */ + stream_seek(s, 52); /* domain (52 bytes) */ + stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */ + stream_seek(s, 512); /* userName (512 bytes) */ + stream_seek_uint32(s); /* sessionId (4 bytes) */ +} + +void rdp_recv_logon_info_v2(rdpRdp* rdp, STREAM* s) +{ + uint32 cbDomain; + uint32 cbUserName; + + stream_seek_uint16(s); /* version (2 bytes) */ + stream_seek_uint32(s); /* size (4 bytes) */ + stream_seek_uint32(s); /* sessionId (4 bytes) */ + stream_read_uint32(s, cbDomain); /* cbDomain (4 bytes) */ + stream_read_uint32(s, cbUserName); /* cbUserName (4 bytes) */ + stream_seek(s, 558); /* pad */ + stream_seek(s, cbDomain); /* domain */ + stream_seek(s, cbUserName); /* userName */ +} + +void rdp_recv_logon_plain_notify(rdpRdp* rdp, STREAM* s) +{ + stream_seek(s, 576); /* pad */ +} + +void rdp_recv_logon_error_info(rdpRdp* rdp, STREAM* s) +{ + uint32 errorNotificationType; + uint32 errorNotificationData; + + stream_read_uint32(s, errorNotificationType); /* errorNotificationType (4 bytes) */ + stream_read_uint32(s, errorNotificationData); /* errorNotificationData (4 bytes) */ +} + +void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s) +{ + uint32 cbFieldData; + uint32 fieldsPresent; + uint16 Length; + + stream_read_uint16(s, Length); /* The total size in bytes of this structure */ + stream_read_uint32(s, fieldsPresent); /* fieldsPresent (4 bytes) */ + + /* logonFields */ + + if (fieldsPresent & LOGON_EX_AUTORECONNECTCOOKIE) + { + stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */ + rdp_read_server_auto_reconnect_cookie(s, rdp->settings); + } + + if (fieldsPresent & LOGON_EX_LOGONERRORS) + { + stream_read_uint32(s, cbFieldData); /* cbFieldData (4 bytes) */ + rdp_recv_logon_error_info(rdp, s); + } + + stream_seek(s, 570); /* pad */ +} + +boolean rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s) +{ + uint32 infoType; + + stream_read_uint32(s, infoType); /* infoType (4 bytes) */ + + //printf("%s\n", INFO_TYPE_LOGON_STRINGS[infoType]); + + switch (infoType) + { + case INFO_TYPE_LOGON: + rdp_recv_logon_info_v1(rdp, s); + break; + + case INFO_TYPE_LOGON_LONG: + rdp_recv_logon_info_v2(rdp, s); + break; + + case INFO_TYPE_LOGON_PLAIN_NOTIFY: + rdp_recv_logon_plain_notify(rdp, s); + break; + + case INFO_TYPE_LOGON_EXTENDED_INF: + rdp_recv_logon_info_extended(rdp, s); + break; + + default: + break; + } + + return true; +} + diff --git a/libfreerdp-core/info.h b/libfreerdp-core/info.h new file mode 100644 index 0000000..e46582b --- /dev/null +++ b/libfreerdp-core/info.h @@ -0,0 +1,90 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Client Info + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INFO_H +#define __INFO_H + +#include "rdp.h" + +#include +#include + +/* Client Address Family */ +#define ADDRESS_FAMILY_INET 0x0002 +#define ADDRESS_FAMILY_INET6 0x0017 + +/* Client Info Packet Flags */ +#define INFO_MOUSE 0x00000001 +#define INFO_DISABLECTRLALTDEL 0x00000002 +#define INFO_AUTOLOGON 0x00000008 +#define INFO_UNICODE 0x00000010 +#define INFO_MAXIMIZESHELL 0x00000020 +#define INFO_LOGONNOTIFY 0x00000040 +#define INFO_COMPRESSION 0x00000080 +#define INFO_ENABLEWINDOWSKEY 0x00000100 +#define INFO_REMOTECONSOLEAUDIO 0x00002000 +#define INFO_FORCE_ENCRYPTED_CS_PDU 0x00004000 +#define INFO_RAIL 0x00008000 +#define INFO_LOGONERRORS 0x00010000 +#define INFO_MOUSE_HAS_WHEEL 0x00020000 +#define INFO_PASSWORD_IS_SC_PIN 0x00040000 +#define INFO_NOAUDIOPLAYBACK 0x00080000 +#define INFO_USING_SAVED_CREDS 0x00100000 +#define RNS_INFO_AUDIOCAPTURE 0x00200000 +#define RNS_INFO_VIDEO_DISABLE 0x00400000 +#define INFO_CompressionTypeMask 0x00001E00 +#define INFO_PACKET_COMPR_TYPE_8K 0x00000100 +#define INFO_PACKET_COMPR_TYPE_64K 0x00000200 +#define INFO_PACKET_COMPR_TYPE_RDP6 0x00000400 +#define INFO_PACKET_COMPR_TYPE_RDP61 0x00000600 + +/* Logon Information Types */ +#define INFO_TYPE_LOGON 0x00000000 +#define INFO_TYPE_LOGON_LONG 0x00000001 +#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002 +#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003 + +/* Extended Logon Info */ +#define LOGON_EX_AUTORECONNECTCOOKIE 0x00000001 +#define LOGON_EX_LOGONERRORS 0x00000002 + +/* Logon Error Info */ +#define LOGON_FAILED_BAD_PASSWORD 0x00000000 +#define LOGON_FAILED_UPDATE_PASSWORD 0x00000001 +#define LOGON_FAILED_OTHER 0x00000002 +#define LOGON_WARNING 0x00000003 + +void rdp_read_system_time(STREAM* s, SYSTEM_TIME* system_time); +void rdp_write_system_time(STREAM* s, SYSTEM_TIME* system_time); +void rdp_get_client_time_zone(STREAM* s, rdpSettings* settings); +boolean rdp_read_client_time_zone(STREAM* s, rdpSettings* settings); +void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings); +void rdp_read_server_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); +boolean rdp_read_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); +void rdp_write_client_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); +void rdp_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings); +boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings); +void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings); +boolean rdp_read_info_packet(STREAM* s, rdpSettings* settings); +void rdp_write_info_packet(STREAM* s, rdpSettings* settings); +boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s); +boolean rdp_send_client_info(rdpRdp* rdp); +boolean rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s); + +#endif /* __INFO_H */ diff --git a/libfreerdp-core/input.c b/libfreerdp-core/input.c new file mode 100644 index 0000000..b7336ed --- /dev/null +++ b/libfreerdp-core/input.c @@ -0,0 +1,403 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Input PDUs + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "input.h" + +void rdp_write_client_input_pdu_header(STREAM* s, uint16 number) +{ + stream_write_uint16(s, 1); /* numberEvents (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ +} + +void rdp_write_input_event_header(STREAM* s, uint32 time, uint16 type) +{ + stream_write_uint32(s, time); /* eventTime (4 bytes) */ + stream_write_uint16(s, type); /* messageType (2 bytes) */ +} + +STREAM* rdp_client_input_pdu_init(rdpRdp* rdp, uint16 type) +{ + STREAM* s; + s = rdp_data_pdu_init(rdp); + rdp_write_client_input_pdu_header(s, 1); + rdp_write_input_event_header(s, 0, type); + return s; +} + +void rdp_send_client_input_pdu(rdpRdp* rdp, STREAM* s) +{ + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_INPUT, rdp->mcs->user_id); +} + +void input_write_synchronize_event(STREAM* s, uint32 flags) +{ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ + stream_write_uint32(s, flags); /* toggleFlags (4 bytes) */ +} + +void input_send_synchronize_event(rdpInput* input, uint32 flags) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SYNC); + input_write_synchronize_event(s, flags); + rdp_send_client_input_pdu(rdp, s); +} + +void input_write_keyboard_event(STREAM* s, uint16 flags, uint16 code) +{ + stream_write_uint16(s, flags); /* keyboardFlags (2 bytes) */ + stream_write_uint16(s, code); /* keyCode (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ +} + +void input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_SCANCODE); + input_write_keyboard_event(s, flags, code); + rdp_send_client_input_pdu(rdp, s); +} + +void input_write_unicode_keyboard_event(STREAM* s, uint16 flags, uint16 code) +{ + stream_write_uint16(s, flags); /* keyboardFlags (2 bytes) */ + stream_write_uint16(s, code); /* unicodeCode (2 bytes) */ + stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ +} + +void input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + STREAM* s; + uint16 keyboardFlags = 0; + rdpRdp* rdp = input->context->rdp; + + /* + * According to the specification, the slow path Unicode Keyboard Event + * (TS_UNICODE_KEYBOARD_EVENT) contains KBD_FLAGS_RELEASE flag when key + * is released, but contains no flags when it is pressed. + * This is different from the slow path Keyboard Event + * (TS_KEYBOARD_EVENT) which does contain KBD_FLAGS_DOWN flag when the + * key is pressed. + * There is no KBD_FLAGS_EXTENDED flag in TS_UNICODE_KEYBOARD_EVENT. + */ + keyboardFlags |= (flags & KBD_FLAGS_RELEASE) ? KBD_FLAGS_RELEASE : 0; + + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_UNICODE); + input_write_unicode_keyboard_event(s, flags, code); + rdp_send_client_input_pdu(rdp, s); +} + +void input_write_mouse_event(STREAM* s, uint16 flags, uint16 x, uint16 y) +{ + stream_write_uint16(s, flags); /* pointerFlags (2 bytes) */ + stream_write_uint16(s, x); /* xPos (2 bytes) */ + stream_write_uint16(s, y); /* yPos (2 bytes) */ +} + +void input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSE); + input_write_mouse_event(s, flags, x, y); + rdp_send_client_input_pdu(rdp, s); +} + +void input_write_extended_mouse_event(STREAM* s, uint16 flags, uint16 x, uint16 y) +{ + stream_write_uint16(s, flags); /* pointerFlags (2 bytes) */ + stream_write_uint16(s, x); /* xPos (2 bytes) */ + stream_write_uint16(s, y); /* yPos (2 bytes) */ +} + +void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = rdp_client_input_pdu_init(rdp, INPUT_EVENT_MOUSEX); + input_write_extended_mouse_event(s, flags, x, y); + rdp_send_client_input_pdu(rdp, s); +} + +void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + /* The FastPath Synchronization eventFlags has identical values as SlowPath */ + s = fastpath_input_pdu_init(rdp->fastpath, (uint8) flags, FASTPATH_INPUT_EVENT_SYNC); + fastpath_send_input_pdu(rdp->fastpath, s); +} + +void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + STREAM* s; + uint8 eventFlags = 0; + rdpRdp* rdp = input->context->rdp; + + eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; + eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0; + s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE); + stream_write_uint8(s, code); /* keyCode (1 byte) */ + fastpath_send_input_pdu(rdp->fastpath, s); +} + +void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + STREAM* s; + uint8 eventFlags = 0; + rdpRdp* rdp = input->context->rdp; + + eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0; + s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_UNICODE); + stream_write_uint16(s, code); /* unicodeCode (2 bytes) */ + fastpath_send_input_pdu(rdp->fastpath, s); +} + +void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSE); + input_write_mouse_event(s, flags, x, y); + fastpath_send_input_pdu(rdp->fastpath, s); +} + +void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + STREAM* s; + rdpRdp* rdp = input->context->rdp; + + s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX); + input_write_extended_mouse_event(s, flags, x, y); + fastpath_send_input_pdu(rdp->fastpath, s); +} + +static boolean input_recv_sync_event(rdpInput* input, STREAM* s) +{ + uint32 toggleFlags; + + if (stream_get_left(s) < 6) + return false; + + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + stream_read_uint32(s, toggleFlags); /* toggleFlags (4 bytes) */ + + IFCALL(input->SynchronizeEvent, input, toggleFlags); + + return true; +} + +static boolean input_recv_keyboard_event(rdpInput* input, STREAM* s) +{ + uint16 keyboardFlags, keyCode; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ + stream_read_uint16(s, keyCode); /* keyCode (2 bytes) */ + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + + IFCALL(input->KeyboardEvent, input, keyboardFlags, keyCode); + + return true; +} + +static boolean input_recv_unicode_keyboard_event(rdpInput* input, STREAM* s) +{ + uint16 keyboardFlags, unicodeCode; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, keyboardFlags); /* keyboardFlags (2 bytes) */ + stream_read_uint16(s, unicodeCode); /* unicodeCode (2 bytes) */ + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + + /* + * According to the specification, the slow path Unicode Keyboard Event + * (TS_UNICODE_KEYBOARD_EVENT) contains KBD_FLAGS_RELEASE flag when key + * is released, but contains no flags when it is pressed. + * This is different from the slow path Keyboard Event + * (TS_KEYBOARD_EVENT) which does contain KBD_FLAGS_DOWN flag when the + * key is pressed. + * Set the KBD_FLAGS_DOWN flag if the KBD_FLAGS_RELEASE flag is missing. + */ + + if ((keyboardFlags & KBD_FLAGS_RELEASE) == 0) + keyboardFlags |= KBD_FLAGS_DOWN; + + IFCALL(input->UnicodeKeyboardEvent, input, keyboardFlags, unicodeCode); + + return true; +} + +static boolean input_recv_mouse_event(rdpInput* input, STREAM* s) +{ + uint16 pointerFlags, xPos, yPos; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */ + stream_read_uint16(s, xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, yPos); /* yPos (2 bytes) */ + + IFCALL(input->MouseEvent, input, pointerFlags, xPos, yPos); + + return true; +} + +static boolean input_recv_extended_mouse_event(rdpInput* input, STREAM* s) +{ + uint16 pointerFlags, xPos, yPos; + + if (stream_get_left(s) < 6) + return false; + + stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */ + stream_read_uint16(s, xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, yPos); /* yPos (2 bytes) */ + + IFCALL(input->ExtendedMouseEvent, input, pointerFlags, xPos, yPos); + + return true; +} + +static boolean input_recv_event(rdpInput* input, STREAM* s) +{ + uint16 messageType; + + if (stream_get_left(s) < 4) + return false; + + stream_seek(s, 4); /* eventTime (4 bytes), ignored by the server */ + stream_read_uint16(s, messageType); /* messageType (2 bytes) */ + + switch (messageType) + { + case INPUT_EVENT_SYNC: + if (!input_recv_sync_event(input, s)) + return false; + break; + + case INPUT_EVENT_SCANCODE: + if (!input_recv_keyboard_event(input, s)) + return false; + break; + + case INPUT_EVENT_UNICODE: + if (!input_recv_unicode_keyboard_event(input, s)) + return false; + break; + + case INPUT_EVENT_MOUSE: + if (!input_recv_mouse_event(input, s)) + return false; + break; + + case INPUT_EVENT_MOUSEX: + if (!input_recv_extended_mouse_event(input, s)) + return false; + break; + + default: + printf("Unknown messageType %u\n", messageType); + /* Each input event uses 6 bytes. */ + stream_seek(s, 6); + break; + } + + return true; +} + +boolean input_recv(rdpInput* input, STREAM* s) +{ + uint16 i, numberEvents; + + if (stream_get_left(s) < 4) + return false; + + stream_read_uint16(s, numberEvents); /* numberEvents (2 bytes) */ + stream_seek(s, 2); /* pad2Octets (2 bytes) */ + + /* Each input event uses 6 exactly bytes. */ + if (stream_get_left(s) < 6 * numberEvents) + return false; + + for (i = 0; i < numberEvents; i++) + { + if (!input_recv_event(input, s)) + return false; + } + + return true; +} + +void input_register_client_callbacks(rdpInput* input) +{ + rdpRdp* rdp = input->context->rdp; + + if (rdp->settings->fastpath_input) + { + input->SynchronizeEvent = input_send_fastpath_synchronize_event; + input->KeyboardEvent = input_send_fastpath_keyboard_event; + input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event; + input->MouseEvent = input_send_fastpath_mouse_event; + input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event; + } + else + { + input->SynchronizeEvent = input_send_synchronize_event; + input->KeyboardEvent = input_send_keyboard_event; + input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event; + input->MouseEvent = input_send_mouse_event; + input->ExtendedMouseEvent = input_send_extended_mouse_event; + } +} + +rdpInput* input_new(rdpRdp* rdp) +{ + rdpInput* input; + + input = (rdpInput*) xzalloc(sizeof(rdpInput)); + + if (input != NULL) + { + + } + + return input; +} + +void input_free(rdpInput* input) +{ + if (input != NULL) + { + xfree(input); + } +} diff --git a/libfreerdp-core/input.h b/libfreerdp-core/input.h new file mode 100644 index 0000000..41b8b67 --- /dev/null +++ b/libfreerdp-core/input.h @@ -0,0 +1,59 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Input PDUs + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __INPUT_H +#define __INPUT_H + +#include "rdp.h" +#include "fastpath.h" + +#include +#include +#include +#include + +/* Input Events */ +#define INPUT_EVENT_SYNC 0x0000 +#define INPUT_EVENT_SCANCODE 0x0004 +#define INPUT_EVENT_UNICODE 0x0005 +#define INPUT_EVENT_MOUSE 0x8001 +#define INPUT_EVENT_MOUSEX 0x8002 + +#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4 + +void input_send_synchronize_event(rdpInput* input, uint32 flags); +void input_send_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void input_send_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void input_send_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); + +void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags); +void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); + +boolean input_recv(rdpInput* input, STREAM* s); + +void input_register_client_callbacks(rdpInput* input); + +rdpInput* input_new(rdpRdp* rdp); +void input_free(rdpInput* input); + +#endif /* __INPUT_H */ diff --git a/libfreerdp-core/license.c b/libfreerdp-core/license.c new file mode 100644 index 0000000..60b9f93 --- /dev/null +++ b/libfreerdp-core/license.c @@ -0,0 +1,938 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Licensing + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "redirection.h" + +#include "license.h" + +#ifdef WITH_DEBUG_LICENSE +static const char* const LICENSE_MESSAGE_STRINGS[] = +{ + "", + "License Request", + "Platform Challenge", + "New License", + "Upgrade License", + "", "", "", "", "", "", + "", "", "", "", "", "", + "", + "License Info", + "New License Request", + "", + "Platform Challenge Response", + "", "", "", "", "", "", "", "", "", + "Error Alert" +}; + +static const char* const error_codes[] = +{ + "ERR_UNKNOWN", + "ERR_INVALID_SERVER_CERTIFICATE", + "ERR_NO_LICENSE", + "ERR_INVALID_MAC", + "ERR_INVALID_SCOPE", + "ERR_UNKNOWN", + "ERR_NO_LICENSE_SERVER", + "STATUS_VALID_CLIENT", + "ERR_INVALID_CLIENT", + "ERR_UNKNOWN", + "ERR_UNKNOWN", + "ERR_INVALID_PRODUCT_ID", + "ERR_INVALID_MESSAGE_LENGTH" +}; + +static const char* const state_transitions[] = +{ + "ST_UNKNOWN", + "ST_TOTAL_ABORT", + "ST_NO_TRANSITION", + "ST_RESET_PHASE_TO_START", + "ST_RESEND_LAST_MESSAGE" +}; +#endif + +/** + * Read a licensing preamble.\n + * @msdn{cc240480} + * @param s stream + * @param bMsgType license message type + * @param flags message flags + * @param wMsgSize message size + */ + +void license_read_preamble(STREAM* s, uint8* bMsgType, uint8* flags, uint16* wMsgSize) +{ + /* preamble (4 bytes) */ + stream_read_uint8(s, *bMsgType); /* bMsgType (1 byte) */ + stream_read_uint8(s, *flags); /* flags (1 byte) */ + stream_read_uint16(s, *wMsgSize); /* wMsgSize (2 bytes) */ +} + +/** + * Write a licensing preamble.\n + * @msdn{cc240480} + * @param s stream + * @param bMsgType license message type + * @param flags message flags + * @param wMsgSize message size + */ + +void license_write_preamble(STREAM* s, uint8 bMsgType, uint8 flags, uint16 wMsgSize) +{ + /* preamble (4 bytes) */ + stream_write_uint8(s, bMsgType); /* bMsgType (1 byte) */ + stream_write_uint8(s, flags); /* flags (1 byte) */ + stream_write_uint16(s, wMsgSize); /* wMsgSize (2 bytes) */ +} + +/** + * Initialize a license packet stream.\n + * @param license license module + * @return stream + */ + +STREAM* license_send_stream_init(rdpLicense* license) +{ + STREAM* s; + s = transport_send_stream_init(license->rdp->transport, 4096); + stream_seek(s, LICENSE_PACKET_HEADER_MAX_LENGTH); + return s; +} + +/** + * Send an RDP licensing packet.\n + * @msdn{cc240479} + * @param license license module + * @param s stream + */ + +boolean license_send(rdpLicense* license, STREAM* s, uint8 type) +{ + int length; + uint8 flags; + uint16 wMsgSize; + uint16 sec_flags; + + DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]); + + length = stream_get_length(s); + stream_set_pos(s, 0); + + sec_flags = SEC_LICENSE_PKT; + wMsgSize = length - LICENSE_PACKET_HEADER_MAX_LENGTH + 4; + /** + * Using EXTENDED_ERROR_MSG_SUPPORTED here would cause mstsc to crash when + * running in server mode! This flag seems to be incorrectly documented. + */ + flags = PREAMBLE_VERSION_3_0; + + rdp_write_header(license->rdp, s, length, MCS_GLOBAL_CHANNEL_ID); + rdp_write_security_header(s, sec_flags); + license_write_preamble(s, type, flags, wMsgSize); + +#ifdef WITH_DEBUG_LICENSE + printf("Sending %s Packet, length %d\n", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize); + freerdp_hexdump(s->p - 4, wMsgSize); +#endif + + stream_set_pos(s, length); + if (transport_write(license->rdp->transport, s) < 0) + return false; + + return true; +} + +/** + * Receive an RDP licensing packet.\n + * @msdn{cc240479} + * @param license license module + * @param s stream + */ + +boolean license_recv(rdpLicense* license, STREAM* s) +{ + uint16 length; + uint16 channelId; + uint16 sec_flags; + uint8 flags; + uint8 bMsgType; + uint16 wMsgSize; + + if (!rdp_read_header(license->rdp, s, &length, &channelId)) + { + printf("Incorrect RDP header.\n"); + return false; + } + + rdp_read_security_header(s, &sec_flags); + if (!(sec_flags & SEC_LICENSE_PKT)) + { + stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); + if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != true) + { + printf("Unexpected license packet.\n"); + return false; + } + return true; + } + + license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */ + + DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]); + + switch (bMsgType) + { + case LICENSE_REQUEST: + license_read_license_request_packet(license, s); + license_send_new_license_request_packet(license); + break; + + case PLATFORM_CHALLENGE: + license_read_platform_challenge_packet(license, s); + license_send_platform_challenge_response_packet(license); + break; + + case NEW_LICENSE: + license_read_new_license_packet(license, s); + break; + + case UPGRADE_LICENSE: + license_read_upgrade_license_packet(license, s); + break; + + case ERROR_ALERT: + license_read_error_alert_packet(license, s); + break; + + default: + printf("invalid bMsgType:%d\n", bMsgType); + return false; + } + + return true; +} + +void license_generate_randoms(rdpLicense* license) +{ +#if 0 + crypto_nonce(license->client_random, CLIENT_RANDOM_LENGTH); /* ClientRandom */ + crypto_nonce(license->premaster_secret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ +#else + memset(license->client_random, 0, CLIENT_RANDOM_LENGTH); /* ClientRandom */ + memset(license->premaster_secret, 0, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ +#endif +} + +/** + * Generate License Cryptographic Keys. + * @param license license module + */ + +void license_generate_keys(rdpLicense* license) +{ + security_master_secret(license->premaster_secret, license->client_random, + license->server_random, license->master_secret); /* MasterSecret */ + + security_session_key_blob(license->master_secret, license->client_random, + license->server_random, license->session_key_blob); /* SessionKeyBlob */ + + security_mac_salt_key(license->session_key_blob, license->client_random, + license->server_random, license->mac_salt_key); /* MacSaltKey */ + + security_licensing_encryption_key(license->session_key_blob, license->client_random, + license->server_random, license->licensing_encryption_key); /* LicensingEncryptionKey */ + +#ifdef WITH_DEBUG_LICENSE + printf("ClientRandom:\n"); + freerdp_hexdump(license->client_random, CLIENT_RANDOM_LENGTH); + + printf("ServerRandom:\n"); + freerdp_hexdump(license->server_random, SERVER_RANDOM_LENGTH); + + printf("PremasterSecret:\n"); + freerdp_hexdump(license->premaster_secret, PREMASTER_SECRET_LENGTH); + + printf("MasterSecret:\n"); + freerdp_hexdump(license->master_secret, MASTER_SECRET_LENGTH); + + printf("SessionKeyBlob:\n"); + freerdp_hexdump(license->session_key_blob, SESSION_KEY_BLOB_LENGTH); + + printf("MacSaltKey:\n"); + freerdp_hexdump(license->mac_salt_key, MAC_SALT_KEY_LENGTH); + + printf("LicensingEncryptionKey:\n"); + freerdp_hexdump(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); +#endif +} + +/** + * Generate Unique Hardware Identifier (CLIENT_HARDWARE_ID).\n + * @param license license module + */ + +void license_generate_hwid(rdpLicense* license) +{ + CryptoMd5 md5; + uint8* mac_address; + + memset(license->hwid, 0, HWID_LENGTH); + mac_address = license->rdp->transport->tcp->mac_address; + + md5 = crypto_md5_init(); + crypto_md5_update(md5, mac_address, 6); + crypto_md5_final(md5, &license->hwid[HWID_PLATFORM_ID_LENGTH]); +} + +void license_encrypt_premaster_secret(rdpLicense* license) +{ + uint8* encrypted_premaster_secret; +#if 0 + int key_length; + uint8* modulus; + uint8* exponent; + rdpCertificate *certificate; + + if (license->server_certificate->length) + certificate = license->certificate; + else + certificate = license->rdp->settings->server_cert; + + exponent = certificate->cert_info.exponent; + modulus = certificate->cert_info.modulus.data; + key_length = certificate->cert_info.modulus.length; + +#ifdef WITH_DEBUG_LICENSE + printf("modulus (%d bits):\n", key_length * 8); + freerdp_hexdump(modulus, key_length); + + printf("exponent:\n"); + freerdp_hexdump(exponent, 4); +#endif + + encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE); + memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE); + + crypto_rsa_public_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH, + key_length, modulus, exponent, encrypted_premaster_secret); + + license->encrypted_premaster_secret->type = BB_RANDOM_BLOB; + license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH; + license->encrypted_premaster_secret->data = encrypted_premaster_secret; +#else + encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE); + memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE); + + license->encrypted_premaster_secret->type = BB_RANDOM_BLOB; + license->encrypted_premaster_secret->length = PREMASTER_SECRET_LENGTH; + license->encrypted_premaster_secret->data = encrypted_premaster_secret; +#endif +} + +void license_decrypt_platform_challenge(rdpLicense* license) +{ + CryptoRc4 rc4; + + license->platform_challenge->data = + (uint8*) xmalloc(license->encrypted_platform_challenge->length); + license->platform_challenge->length = + license->encrypted_platform_challenge->length; + + rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); + + crypto_rc4(rc4, license->encrypted_platform_challenge->length, + license->encrypted_platform_challenge->data, + license->platform_challenge->data); + +#ifdef WITH_DEBUG_LICENSE + printf("encrypted_platform challenge:\n"); + freerdp_hexdump(license->encrypted_platform_challenge->data, + license->encrypted_platform_challenge->length); + + printf("platform challenge:\n"); + freerdp_hexdump(license->platform_challenge->data, license->platform_challenge->length); +#endif + + crypto_rc4_free(rc4); +} + +/** + * Read Product Information (PRODUCT_INFO).\n + * @msdn{cc241915} + * @param s stream + * @param productInfo product information + */ + +void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo) +{ + stream_read_uint32(s, productInfo->dwVersion); /* dwVersion (4 bytes) */ + + stream_read_uint32(s, productInfo->cbCompanyName); /* cbCompanyName (4 bytes) */ + + productInfo->pbCompanyName = (uint8*) xmalloc(productInfo->cbCompanyName); + stream_read(s, productInfo->pbCompanyName, productInfo->cbCompanyName); + + stream_read_uint32(s, productInfo->cbProductId); /* cbProductId (4 bytes) */ + + productInfo->pbProductId = (uint8*) xmalloc(productInfo->cbProductId); + stream_read(s, productInfo->pbProductId, productInfo->cbProductId); +} + +/** + * Allocate New Product Information (PRODUCT_INFO).\n + * @msdn{cc241915} + * @return new product information + */ + +PRODUCT_INFO* license_new_product_info() +{ + PRODUCT_INFO* productInfo; + + productInfo = (PRODUCT_INFO*) xmalloc(sizeof(PRODUCT_INFO)); + + productInfo->dwVersion = 0; + productInfo->cbCompanyName = 0; + productInfo->pbCompanyName = NULL; + productInfo->cbProductId = 0; + productInfo->pbProductId = NULL; + + return productInfo; +} + +/** + * Free Product Information (PRODUCT_INFO).\n + * @msdn{cc241915} + * @param productInfo product information + */ + +void license_free_product_info(PRODUCT_INFO* productInfo) +{ + if (productInfo->pbCompanyName != NULL) + xfree(productInfo->pbCompanyName); + + if (productInfo->pbProductId != NULL) + xfree(productInfo->pbProductId); + + xfree(productInfo); +} + +/** + * Read License Binary Blob (LICENSE_BINARY_BLOB).\n + * @msdn{cc240481} + * @param s stream + * @param blob license binary blob + */ + +void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob) +{ + uint16 wBlobType; + + stream_read_uint16(s, wBlobType); /* wBlobType (2 bytes) */ + stream_read_uint16(s, blob->length); /* wBlobLen (2 bytes) */ + + /* + * Server can choose to not send data by setting len to 0. + * If so, it may not bother to set the type, so shortcut the warning + */ + if (blob->type != BB_ANY_BLOB && blob->length == 0) + return; + + if (blob->type != wBlobType && blob->type != BB_ANY_BLOB) + { + printf("license binary blob type (%x) does not match expected type (%x).\n", wBlobType, blob->type); + } + + blob->type = wBlobType; + blob->data = (uint8*) xmalloc(blob->length); + + stream_read(s, blob->data, blob->length); /* blobData */ +} + +/** + * Write License Binary Blob (LICENSE_BINARY_BLOB).\n + * @msdn{cc240481} + * @param s stream + * @param blob license binary blob + */ + +void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob) +{ + stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */ + stream_write_uint16(s, blob->length); /* wBlobLen (2 bytes) */ + + if (blob->length > 0) + stream_write(s, blob->data, blob->length); /* blobData */ +} + +void license_write_padded_binary_blob(STREAM* s, LICENSE_BLOB* blob) +{ + uint16 pad_len; + + pad_len = 72 % blob->length; + stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */ + stream_write_uint16(s, blob->length + pad_len); /* wBlobLen (2 bytes) */ + + if (blob->length > 0) + stream_write(s, blob->data, blob->length); /* blobData */ + + stream_write_zero(s, pad_len); +} + +/** + * Allocate New License Binary Blob (LICENSE_BINARY_BLOB).\n + * @msdn{cc240481} + * @return new license binary blob + */ + +LICENSE_BLOB* license_new_binary_blob(uint16 type) +{ + LICENSE_BLOB* blob; + + blob = (LICENSE_BLOB*) xmalloc(sizeof(LICENSE_BLOB)); + blob->type = type; + blob->length = 0; + blob->data = NULL; + + return blob; +} + +/** + * Free License Binary Blob (LICENSE_BINARY_BLOB).\n + * @msdn{cc240481} + * @param blob license binary blob + */ + +void license_free_binary_blob(LICENSE_BLOB* blob) +{ + if (blob->data != NULL) + xfree(blob->data); + + xfree(blob); +} + +/** + * Read License Scope List (SCOPE_LIST).\n + * @msdn{cc241916} + * @param s stream + * @param scopeList scope list + */ + +void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList) +{ + uint32 i; + uint32 scopeCount; + + stream_read_uint32(s, scopeCount); /* ScopeCount (4 bytes) */ + + scopeList->count = scopeCount; + scopeList->array = (LICENSE_BLOB*) xmalloc(sizeof(LICENSE_BLOB) * scopeCount); + + /* ScopeArray */ + for (i = 0; i < scopeCount; i++) + { + scopeList->array[i].type = BB_SCOPE_BLOB; + license_read_binary_blob(s, &scopeList->array[i]); + } +} + +/** + * Allocate New License Scope List (SCOPE_LIST).\n + * @msdn{cc241916} + * @return new scope list + */ + +SCOPE_LIST* license_new_scope_list() +{ + SCOPE_LIST* scopeList; + + scopeList = (SCOPE_LIST*) xmalloc(sizeof(SCOPE_LIST)); + scopeList->count = 0; + scopeList->array = NULL; + + return scopeList; +} + +/** + * Free License Scope List (SCOPE_LIST).\n + * @msdn{cc241916} + * @param scopeList scope list + */ + +void license_free_scope_list(SCOPE_LIST* scopeList) +{ + uint32 i; + + for (i = 0; i < scopeList->count; i++) + { + license_free_binary_blob(&scopeList->array[i]); + } + + xfree(scopeList); +} + +/** + * Read a LICENSE_REQUEST packet.\n + * @msdn{cc241914} + * @param license license module + * @param s stream + */ + +void license_read_license_request_packet(rdpLicense* license, STREAM* s) +{ + /* ServerRandom (32 bytes) */ + stream_read(s, license->server_random, 32); + + /* ProductInfo */ + license_read_product_info(s, license->product_info); + + /* KeyExchangeList */ + license_read_binary_blob(s, license->key_exchange_list); + + /* ServerCertificate */ + license_read_binary_blob(s, license->server_certificate); + + /* ScopeList */ + license_read_scope_list(s, license->scope_list); + + /* Parse Server Certificate */ + certificate_read_server_certificate(license->certificate, + license->server_certificate->data, license->server_certificate->length); + + license_generate_keys(license); + license_generate_hwid(license); + license_encrypt_premaster_secret(license); +} + +/** + * Read a PLATFORM_CHALLENGE packet.\n + * @msdn{cc241921} + * @param license license module + * @param s stream + */ + +void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) +{ + DEBUG_LICENSE("Receiving Platform Challenge Packet"); + + stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */ + + /* EncryptedPlatformChallenge */ + license->encrypted_platform_challenge->type = BB_ANY_BLOB; + license_read_binary_blob(s, license->encrypted_platform_challenge); + license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB; + + /* MACData (16 bytes) */ + stream_seek(s, 16); + + license_decrypt_platform_challenge(license); +} + +/** + * Read a NEW_LICENSE packet.\n + * @msdn{cc241926} + * @param license license module + * @param s stream + */ + +void license_read_new_license_packet(rdpLicense* license, STREAM* s) +{ + DEBUG_LICENSE("Receiving New License Packet"); + license->state = LICENSE_STATE_COMPLETED; +} + +/** + * Read an UPGRADE_LICENSE packet.\n + * @msdn{cc241924} + * @param license license module + * @param s stream + */ + +void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s) +{ + DEBUG_LICENSE("Receiving Upgrade License Packet"); + license->state = LICENSE_STATE_COMPLETED; +} + +/** + * Read an ERROR_ALERT packet.\n + * @msdn{cc240482} + * @param license license module + * @param s stream + */ + +void license_read_error_alert_packet(rdpLicense* license, STREAM* s) +{ + uint32 dwErrorCode; + uint32 dwStateTransition; + + stream_read_uint32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ + stream_read_uint32(s, dwStateTransition); /* dwStateTransition (4 bytes) */ + license_read_binary_blob(s, license->error_info); /* bbErrorInfo */ + +#ifdef WITH_DEBUG_LICENSE + printf("dwErrorCode: %s, dwStateTransition: %s\n", + error_codes[dwErrorCode], state_transitions[dwStateTransition]); +#endif + + if (dwErrorCode == STATUS_VALID_CLIENT) + { + license->state = LICENSE_STATE_COMPLETED; + return; + } + + switch (dwStateTransition) + { + case ST_TOTAL_ABORT: + license->state = LICENSE_STATE_ABORTED; + break; + + case ST_NO_TRANSITION: + license->state = LICENSE_STATE_COMPLETED; + break; + + case ST_RESET_PHASE_TO_START: + license->state = LICENSE_STATE_AWAIT; + break; + + case ST_RESEND_LAST_MESSAGE: + break; + + default: + break; + } +} + +/** + * Write Platform ID.\n + * @msdn{cc241918} + * @param license license module + * @param s stream + */ + +void license_write_platform_id(rdpLicense* license, STREAM* s) +{ + stream_write_uint8(s, 0); /* Client Operating System Version */ + stream_write_uint8(s, 0); /* Independent Software Vendor (ISV) */ + stream_write_uint16(s, 0); /* Client Software Build */ +} + +/** + * Write a NEW_LICENSE_REQUEST packet.\n + * @msdn{cc241918} + * @param license license module + * @param s stream + */ + +void license_write_new_license_request_packet(rdpLicense* license, STREAM* s) +{ + stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* PreferredKeyExchangeAlg (4 bytes) */ + license_write_platform_id(license, s); /* PlatformId (4 bytes) */ + stream_write(s, license->client_random, 32); /* ClientRandom (32 bytes) */ + license_write_padded_binary_blob(s, license->encrypted_premaster_secret); /* EncryptedPremasterSecret */ + license_write_binary_blob(s, license->client_user_name); /* ClientUserName */ + license_write_binary_blob(s, license->client_machine_name); /* ClientMachineName */ +} + +/** + * Send a NEW_LICENSE_REQUEST packet.\n + * @msdn{cc241918} + * @param license license module + */ + +void license_send_new_license_request_packet(rdpLicense* license) +{ + STREAM* s; + char* username; + + s = license_send_stream_init(license); + + if (license->rdp->settings->username != NULL) + username = license->rdp->settings->username; + else + username = "username"; + + license->client_user_name->data = (uint8*) username; + license->client_user_name->length = strlen(username) + 1; + + license->client_machine_name->data = (uint8*) license->rdp->settings->client_hostname; + license->client_machine_name->length = strlen(license->rdp->settings->client_hostname) + 1; + + license_write_new_license_request_packet(license, s); + + license_send(license, s, NEW_LICENSE_REQUEST); + + license->client_user_name->data = NULL; + license->client_user_name->length = 0; + + license->client_machine_name->data = NULL; + license->client_machine_name->length = 0; +} + +/** + * Write Client Challenge Response Packet.\n + * @msdn{cc241922} + * @param license license module + * @param s stream + * @param mac_data signature + */ + +void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, uint8* mac_data) +{ + /* EncryptedPlatformChallengeResponse */ + license_write_binary_blob(s, license->encrypted_platform_challenge); + + /* EncryptedHWID */ + license_write_binary_blob(s, license->encrypted_hwid); + + /* MACData */ + stream_write(s, mac_data, 16); +} + +/** + * Send Client Challenge Response Packet.\n + * @msdn{cc241922} + * @param license license module + */ + +void license_send_platform_challenge_response_packet(rdpLicense* license) +{ + STREAM* s; + int length; + uint8* buffer; + CryptoRc4 rc4; + uint8 mac_data[16]; + + s = license_send_stream_init(license); + DEBUG_LICENSE("Sending Platform Challenge Response Packet"); + + license->encrypted_platform_challenge->type = BB_DATA_BLOB; + length = license->platform_challenge->length + HWID_LENGTH; + buffer = (uint8*) xmalloc(length); + memcpy(buffer, license->platform_challenge->data, license->platform_challenge->length); + memcpy(&buffer[license->platform_challenge->length], license->hwid, HWID_LENGTH); + security_mac_data(license->mac_salt_key, buffer, length, mac_data); + xfree(buffer); + + buffer = (uint8*) xmalloc(HWID_LENGTH); + rc4 = crypto_rc4_init(license->licensing_encryption_key, LICENSING_ENCRYPTION_KEY_LENGTH); + crypto_rc4(rc4, HWID_LENGTH, license->hwid, buffer); + crypto_rc4_free(rc4); + +#ifdef WITH_DEBUG_LICENSE + printf("Licensing Encryption Key:\n"); + freerdp_hexdump(license->licensing_encryption_key, 16); + + printf("HardwareID:\n"); + freerdp_hexdump(license->hwid, 20); + + printf("Encrypted HardwareID:\n"); + freerdp_hexdump(buffer, 20); +#endif + + license->encrypted_hwid->type = BB_DATA_BLOB; + license->encrypted_hwid->data = buffer; + license->encrypted_hwid->length = HWID_LENGTH; + + license_write_platform_challenge_response_packet(license, s, mac_data); + + license_send(license, s, PLATFORM_CHALLENGE_RESPONSE); +} + +/** + * Send Server License Error - Valid Client Packet.\n + * @msdn{cc241922} + * @param license license module + */ + +boolean license_send_valid_client_error_packet(rdpLicense* license) +{ + STREAM* s; + + s = license_send_stream_init(license); + + stream_write_uint32(s, STATUS_VALID_CLIENT); /* dwErrorCode */ + stream_write_uint32(s, ST_NO_TRANSITION); /* dwStateTransition */ + + license_write_binary_blob(s, license->error_info); + + license_send(license, s, ERROR_ALERT); + + return true; +} + +/** + * Instantiate new license module. + * @param rdp RDP module + * @return new license module + */ + +rdpLicense* license_new(rdpRdp* rdp) +{ + rdpLicense* license; + + license = (rdpLicense*) xzalloc(sizeof(rdpLicense)); + + if (license != NULL) + { + license->rdp = rdp; + license->state = LICENSE_STATE_AWAIT; + //license->certificate = certificate_new(rdp); + license->certificate = certificate_new(); + license->product_info = license_new_product_info(); + license->error_info = license_new_binary_blob(BB_ERROR_BLOB); + license->key_exchange_list = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB); + license->server_certificate = license_new_binary_blob(BB_CERTIFICATE_BLOB); + license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB); + license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB); + license->platform_challenge = license_new_binary_blob(BB_ANY_BLOB); + license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB); + license->encrypted_premaster_secret = license_new_binary_blob(BB_ANY_BLOB); + license->encrypted_hwid = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB); + license->scope_list = license_new_scope_list(); + license_generate_randoms(license); + } + + return license; +} + +/** + * Free license module. + * @param license license module to be freed + */ + +void license_free(rdpLicense* license) +{ + if (license != NULL) + { + certificate_free(license->certificate); + license_free_product_info(license->product_info); + license_free_binary_blob(license->error_info); + license_free_binary_blob(license->key_exchange_list); + license_free_binary_blob(license->server_certificate); + license_free_binary_blob(license->client_user_name); + license_free_binary_blob(license->client_machine_name); + license_free_binary_blob(license->platform_challenge); + license_free_binary_blob(license->encrypted_platform_challenge); + license_free_binary_blob(license->encrypted_premaster_secret); + license_free_binary_blob(license->encrypted_hwid); + license_free_scope_list(license->scope_list); + xfree(license); + } +} + diff --git a/libfreerdp-core/license.h b/libfreerdp-core/license.h new file mode 100644 index 0000000..0fe1de6 --- /dev/null +++ b/libfreerdp-core/license.h @@ -0,0 +1,205 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Licensing + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LICENSE_H +#define __LICENSE_H + +typedef struct rdp_license rdpLicense; + +#include "rdp.h" +#include "crypto.h" +#include "certificate.h" + +#include +#include +#include + +/* Licensing Packet Types */ +#define LICENSE_REQUEST 0x01 +#define PLATFORM_CHALLENGE 0x02 +#define NEW_LICENSE 0x03 +#define UPGRADE_LICENSE 0x04 +#define LICENSE_INFO 0x12 +#define NEW_LICENSE_REQUEST 0x13 +#define PLATFORM_CHALLENGE_RESPONSE 0x15 +#define ERROR_ALERT 0xFF + +#define LICENSE_PKT_CS_MASK (LICENSE_INFO | NEW_LICENSE_REQUEST | PLATFORM_CHALLENGE_RESPONSE | ERROR_ALERT) +#define LICENSE_PKT_SC_MASK (LICENSE_REQUEST | PLATFORM_CHALLENGE | NEW_LICENSE | UPGRADE_LICENSE | ERROR_ALERT) +#define LICENSE_PKT_MASK (LICENSE_PKT_CS_MASK | LICENSE_PKT_SC_MASK) + +#define LICENSE_PREAMBLE_LENGTH 4 +#define LICENSE_PACKET_HEADER_MAX_LENGTH (RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + LICENSE_PREAMBLE_LENGTH) + +/* Cryptographic Lengths */ +#define CLIENT_RANDOM_LENGTH 32 +#define SERVER_RANDOM_LENGTH 32 +#define MASTER_SECRET_LENGTH 48 +#define PREMASTER_SECRET_LENGTH 48 +#define SESSION_KEY_BLOB_LENGTH 48 +#define MAC_SALT_KEY_LENGTH 16 +#define LICENSING_ENCRYPTION_KEY_LENGTH 16 +#define HWID_PLATFORM_ID_LENGTH 4 +#define HWID_UNIQUE_DATA_LENGTH 16 +#define HWID_LENGTH 20 +#define LICENSING_PADDING_SIZE 8 + +/* Licensing Preamble Flags */ +#define PREAMBLE_VERSION_2_0 0x02 +#define PREAMBLE_VERSION_3_0 0x03 +#define LicenseProtocolVersionMask 0x0F +#define EXTENDED_ERROR_MSG_SUPPORTED 0x80 + +/* Licensing Binary Blob Types */ +#define BB_ANY_BLOB 0x0000 +#define BB_DATA_BLOB 0x0001 +#define BB_RANDOM_BLOB 0x0002 +#define BB_CERTIFICATE_BLOB 0x0003 +#define BB_ERROR_BLOB 0x0004 +#define BB_ENCRYPTED_DATA_BLOB 0x0009 +#define BB_KEY_EXCHG_ALG_BLOB 0x000D +#define BB_SCOPE_BLOB 0x000E +#define BB_CLIENT_USER_NAME_BLOB 0x000F +#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010 + +/* Key Exchange Algorithms */ +#define KEY_EXCHANGE_ALG_RSA 0x00000001 + +/* Licensing Error Codes */ +#define ERR_INVALID_SERVER_CERTIFICATE 0x00000001 +#define ERR_NO_LICENSE 0x00000002 +#define ERR_INVALID_MAC 0x00000003 +#define ERR_INVALID_SCOPE 0x00000004 +#define ERR_NO_LICENSE_SERVER 0x00000006 +#define STATUS_VALID_CLIENT 0x00000007 +#define ERR_INVALID_CLIENT 0x00000008 +#define ERR_INVALID_PRODUCT_ID 0x0000000B +#define ERR_INVALID_MESSAGE_LENGTH 0x0000000C + +/* Licensing State Transition Codes */ +#define ST_TOTAL_ABORT 0x00000001 +#define ST_NO_TRANSITION 0x00000002 +#define ST_RESET_PHASE_TO_START 0x00000003 +#define ST_RESEND_LAST_MESSAGE 0x00000004 + +typedef struct +{ + uint32 dwVersion; + uint32 cbCompanyName; + uint8* pbCompanyName; + uint32 cbProductId; + uint8* pbProductId; +} PRODUCT_INFO; + +typedef struct +{ + uint16 type; + uint16 length; + uint8* data; +} LICENSE_BLOB; + +typedef struct +{ + uint32 count; + LICENSE_BLOB* array; +} SCOPE_LIST; + +typedef enum +{ + LICENSE_STATE_AWAIT, + LICENSE_STATE_PROCESS, + LICENSE_STATE_ABORTED, + LICENSE_STATE_COMPLETED +} LICENSE_STATE; + +struct rdp_license +{ + LICENSE_STATE state; + struct rdp_rdp* rdp; + struct rdp_certificate* certificate; + uint8 hwid[HWID_LENGTH]; + uint8 modulus[MODULUS_MAX_SIZE]; + uint8 exponent[EXPONENT_MAX_SIZE]; + uint8 client_random[CLIENT_RANDOM_LENGTH]; + uint8 server_random[SERVER_RANDOM_LENGTH]; + uint8 master_secret[MASTER_SECRET_LENGTH]; + uint8 premaster_secret[PREMASTER_SECRET_LENGTH]; + uint8 session_key_blob[SESSION_KEY_BLOB_LENGTH]; + uint8 mac_salt_key[MAC_SALT_KEY_LENGTH]; + uint8 licensing_encryption_key[LICENSING_ENCRYPTION_KEY_LENGTH]; + PRODUCT_INFO* product_info; + LICENSE_BLOB* error_info; + LICENSE_BLOB* key_exchange_list; + LICENSE_BLOB* server_certificate; + LICENSE_BLOB* client_user_name; + LICENSE_BLOB* client_machine_name; + LICENSE_BLOB* platform_challenge; + LICENSE_BLOB* encrypted_premaster_secret; + LICENSE_BLOB* encrypted_platform_challenge; + LICENSE_BLOB* encrypted_hwid; + SCOPE_LIST* scope_list; +}; + +boolean license_recv(rdpLicense* license, STREAM* s); +boolean license_send(rdpLicense* license, STREAM* s, uint8 type); +STREAM* license_send_stream_init(rdpLicense* license); + +void license_generate_randoms(rdpLicense* license); +void license_generate_keys(rdpLicense* license); +void license_generate_hwid(rdpLicense* license); +void license_encrypt_premaster_secret(rdpLicense* license); +void license_decrypt_platform_challenge(rdpLicense* license); + +PRODUCT_INFO* license_new_product_info(); +void license_free_product_info(PRODUCT_INFO* productInfo); +void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo); + +LICENSE_BLOB* license_new_binary_blob(uint16 type); +void license_free_binary_blob(LICENSE_BLOB* blob); +void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob); +void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob); + +SCOPE_LIST* license_new_scope_list(); +void license_free_scope_list(SCOPE_LIST* scopeList); +void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList); + +void license_read_license_request_packet(rdpLicense* license, STREAM* s); +void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s); +void license_read_new_license_packet(rdpLicense* license, STREAM* s); +void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s); +void license_read_error_alert_packet(rdpLicense* license, STREAM* s); + +void license_write_new_license_request_packet(rdpLicense* license, STREAM* s); +void license_send_new_license_request_packet(rdpLicense* license); + +void license_write_platform_challenge_response_packet(rdpLicense* license, STREAM* s, uint8* mac_data); +void license_send_platform_challenge_response_packet(rdpLicense* license); + +boolean license_send_valid_client_error_packet(rdpLicense* license); + +rdpLicense* license_new(rdpRdp* rdp); +void license_free(rdpLicense* license); + +#ifdef WITH_DEBUG_LICENSE +#define DEBUG_LICENSE(fmt, ...) DEBUG_CLASS(LICENSE, fmt, ## __VA_ARGS__) +#else +#define DEBUG_LICENSE(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __LICENSE_H */ diff --git a/libfreerdp-core/listener.c b/libfreerdp-core/listener.c new file mode 100644 index 0000000..ee3f98c --- /dev/null +++ b/libfreerdp-core/listener.c @@ -0,0 +1,230 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Listener + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include +#else +#define close(_fd) closesocket(_fd) +#endif + +#include "listener.h" + +static boolean freerdp_listener_open(freerdp_listener* instance, const char* bind_address, uint16 port) +{ + rdpListener* listener = (rdpListener*)instance->listener; + int status; + int sockfd; + char servname[10]; + struct addrinfo hints = { 0 }; + struct addrinfo* res; + struct addrinfo* ai; + int option_value; + void* sin_addr; + char buf[50]; +#ifdef _WIN32 + u_long arg; +#endif + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (bind_address == NULL) + hints.ai_flags = AI_PASSIVE; + + snprintf(servname, sizeof(servname), "%d", port); + status = getaddrinfo(bind_address, servname, &hints, &res); + if (status != 0) + { + perror("getaddrinfo"); + return false; + } + + for (ai = res; ai && listener->num_sockfds < 5; ai = ai->ai_next) + { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + + sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sockfd == -1) + { + perror("socket"); + continue; + } + + option_value = 1; + + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*) &option_value, sizeof(option_value)) == -1) + perror("setsockopt"); + +#ifndef _WIN32 + fcntl(sockfd, F_SETFL, O_NONBLOCK); +#else + arg = 1; + ioctlsocket(sockfd, FIONBIO, &arg); +#endif + + status = bind(sockfd, ai->ai_addr, ai->ai_addrlen); + if (status != 0) + { + perror("bind"); + close(sockfd); + continue; + } + + status = listen(sockfd, 10); + if (status != 0) + { + perror("listen"); + close(sockfd); + continue; + } + + listener->sockfds[listener->num_sockfds++] = sockfd; + + if (ai->ai_family == AF_INET) + sin_addr = &(((struct sockaddr_in*)ai->ai_addr)->sin_addr); + else + sin_addr = &(((struct sockaddr_in6*)ai->ai_addr)->sin6_addr); + + printf("Listening on %s port %s.\n", inet_ntop(ai->ai_family, sin_addr, buf, sizeof(buf)), servname); + } + + freeaddrinfo(res); + + return (listener->num_sockfds > 0 ? true : false); +} + +static void freerdp_listener_close(freerdp_listener* instance) +{ + int i; + + rdpListener* listener = (rdpListener*)instance->listener; + + for (i = 0; i < listener->num_sockfds; i++) + { + close(listener->sockfds[i]); + } + listener->num_sockfds = 0; +} + +static boolean freerdp_listener_get_fds(freerdp_listener* instance, void** rfds, int* rcount) +{ + rdpListener* listener = (rdpListener*)instance->listener; + int i; + + if (listener->num_sockfds < 1) + return false; + + for (i = 0; i < listener->num_sockfds; i++) + { + rfds[*rcount] = (void*)(long)(listener->sockfds[i]); + (*rcount)++; + } + + return true; +} + +static boolean freerdp_listener_check_fds(freerdp_listener* instance) +{ + rdpListener* listener = (rdpListener*)instance->listener; + struct sockaddr_storage peer_addr; + socklen_t peer_addr_size; + int peer_sockfd; + int i; + freerdp_peer* client; + void* sin_addr; + + if (listener->num_sockfds < 1) + return false; + + for (i = 0; i < listener->num_sockfds; i++) + { + peer_addr_size = sizeof(peer_addr); + peer_sockfd = accept(listener->sockfds[i], (struct sockaddr *)&peer_addr, &peer_addr_size); + + if (peer_sockfd == -1) + { +#ifdef _WIN32 + int wsa_error = WSAGetLastError(); + + /* No data available */ + if (wsa_error == WSAEWOULDBLOCK) + continue; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) + continue; +#endif + perror("accept"); + return false; + } + + client = freerdp_peer_new(peer_sockfd); + + if (peer_addr.ss_family == AF_INET) + sin_addr = &(((struct sockaddr_in*)&peer_addr)->sin_addr); + else + sin_addr = &(((struct sockaddr_in6*)&peer_addr)->sin6_addr); + inet_ntop(peer_addr.ss_family, sin_addr, client->hostname, sizeof(client->hostname)); + + IFCALL(instance->PeerAccepted, instance, client); + } + + return true; +} + +freerdp_listener* freerdp_listener_new(void) +{ + freerdp_listener* instance; + rdpListener* listener; + + instance = xnew(freerdp_listener); + instance->Open = freerdp_listener_open; + instance->GetFileDescriptor = freerdp_listener_get_fds; + instance->CheckFileDescriptor = freerdp_listener_check_fds; + instance->Close = freerdp_listener_close; + + listener = xnew(rdpListener); + listener->instance = instance; + + instance->listener = (void*)listener; + + return instance; +} + +void freerdp_listener_free(freerdp_listener* instance) +{ + rdpListener* listener; + + listener = (rdpListener*)instance->listener; + xfree(listener); + + xfree(instance); +} + diff --git a/libfreerdp-core/listener.h b/libfreerdp-core/listener.h new file mode 100644 index 0000000..78a7552 --- /dev/null +++ b/libfreerdp-core/listener.h @@ -0,0 +1,37 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Listener + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LISTENER_H +#define __LISTENER_H + +typedef struct rdp_listener rdpListener; + +#include "rdp.h" +#include + +struct rdp_listener +{ + freerdp_listener* instance; + + int sockfds[5]; + int num_sockfds; +}; + +#endif + diff --git a/libfreerdp-core/mcs.c b/libfreerdp-core/mcs.c new file mode 100644 index 0000000..b2524c6 --- /dev/null +++ b/libfreerdp-core/mcs.c @@ -0,0 +1,837 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.125 Multipoint Communication Service (MCS) Protocol + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gcc.h" + +#include "mcs.h" +#include "tpdu.h" +#include "tpkt.h" + +/** + * T.125 MCS is defined in: + * + * http://www.itu.int/rec/T-REC-T.125-199802-I/ + * ITU-T T.125 Multipoint Communication Service Protocol Specification + */ + +/** + * Connect-Initial ::= [APPLICATION 101] IMPLICIT SEQUENCE + * { + * callingDomainSelector OCTET_STRING, + * calledDomainSelector OCTET_STRING, + * upwardFlag BOOLEAN, + * targetParameters DomainParameters, + * minimumParameters DomainParameters, + * maximumParameters DomainParameters, + * userData OCTET_STRING + * } + * + * DomainParameters ::= SEQUENCE + * { + * maxChannelIds INTEGER (0..MAX), + * maxUserIds INTEGER (0..MAX), + * maxTokenIds INTEGER (0..MAX), + * numPriorities INTEGER (0..MAX), + * minThroughput INTEGER (0..MAX), + * maxHeight INTEGER (0..MAX), + * maxMCSPDUsize INTEGER (0..MAX), + * protocolVersion INTEGER (0..MAX) + * } + * + * Connect-Response ::= [APPLICATION 102] IMPLICIT SEQUENCE + * { + * result Result, + * calledConnectId INTEGER (0..MAX), + * domainParameters DomainParameters, + * userData OCTET_STRING + * } + * + * Result ::= ENUMERATED + * { + * rt-successful (0), + * rt-domain-merging (1), + * rt-domain-not-hierarchical (2), + * rt-no-such-channel (3), + * rt-no-such-domain (4), + * rt-no-such-user (5), + * rt-not-admitted (6), + * rt-other-user-id (7), + * rt-parameters-unacceptable (8), + * rt-token-not-available (9), + * rt-token-not-possessed (10), + * rt-too-many-channels (11), + * rt-too-many-tokens (12), + * rt-too-many-users (13), + * rt-unspecified-failure (14), + * rt-user-rejected (15) + * } + * + * ErectDomainRequest ::= [APPLICATION 1] IMPLICIT SEQUENCE + * { + * subHeight INTEGER (0..MAX), + * subInterval INTEGER (0..MAX) + * } + * + * AttachUserRequest ::= [APPPLICATION 10] IMPLICIT SEQUENCE + * { + * } + * + * AttachUserConfirm ::= [APPLICATION 11] IMPLICIT SEQUENCE + * { + * result Result, + * initiator UserId OPTIONAL + * } + * + * ChannelJoinRequest ::= [APPLICATION 14] IMPLICIT SEQUENCE + * { + * initiator UserId, + * channelId ChannelId + * } + * + * ChannelJoinConfirm ::= [APPLICATION 15] IMPLICIT SEQUENCE + * { + * result Result, + * initiator UserId, + * requested ChannelId, + * channelId ChannelId OPTIONAL + * } + * + * SendDataRequest ::= [APPLICATION 25] IMPLICIT SEQUENCE + * { + * initiator UserId, + * channelId ChannelId, + * dataPriority DataPriority, + * segmentation Segmentation, + * userData OCTET_STRING + * } + * + * DataPriority ::= CHOICE + * { + * top NULL, + * high NULL, + * medium NULL, + * low NULL, + * ... + * } + * + * Segmentation ::= BIT_STRING + * { + * begin (0), + * end (1) + * } (SIZE(2)) + * + * SendDataIndication ::= SEQUENCE + * { + * initiator UserId, + * channelId ChannelId, + * reliability BOOLEAN, + * domainReferenceID INTEGER (0..65535) OPTIONAL, + * dataPriority DataPriority, + * segmentation Segmentation, + * userData OCTET_STRING, + * totalDataSize INTEGER OPTIONAL, + * nonStandard SEQUENCE OF NonStandardParameter OPTIONAL, + * ... + * } + * + */ + +static const uint8 callingDomainSelector[1] = "\x01"; +static const uint8 calledDomainSelector[1] = "\x01"; + +/* +static const char* const mcs_result_enumerated[] = +{ + "rt-successful", + "rt-domain-merging", + "rt-domain-not-hierarchical", + "rt-no-such-channel", + "rt-no-such-domain", + "rt-no-such-user", + "rt-not-admitted", + "rt-other-user-id", + "rt-parameters-unacceptable", + "rt-token-not-available", + "rt-token-not-possessed", + "rt-too-many-channels", + "rt-too-many-tokens", + "rt-too-many-users", + "rt-unspecified-failure", + "rt-user-rejected" +}; +*/ + +/** + * Read a DomainMCSPDU header. + * @param s stream + * @param domainMCSPDU DomainMCSPDU type + * @param length TPKT length + * @return + */ + +boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, uint16* length) +{ + uint8 choice; + enum DomainMCSPDU MCSPDU; + + *length = tpkt_read_header(s); + + if (tpdu_read_data(s) == 0) + return false; + + MCSPDU = *domainMCSPDU; + per_read_choice(s, &choice); + *domainMCSPDU = (choice >> 2); + + if (*domainMCSPDU != MCSPDU) + return false; + + return true; +} + +/** + * Write a DomainMCSPDU header. + * @param s stream + * @param domainMCSPDU DomainMCSPDU type + * @param length TPKT length + */ + +void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, uint16 length, uint8 options) +{ + tpkt_write_header(s, length); + tpdu_write_data(s); + per_write_choice(s, (domainMCSPDU << 2) | options); +} + +/** + * Initialize MCS Domain Parameters. + * @param domainParameters domain parameters + * @param maxChannelIds max channel ids + * @param maxUserIds max user ids + * @param maxTokenIds max token ids + * @param maxMCSPDUsize max MCS PDU size + */ + +static void mcs_init_domain_parameters(DomainParameters* domainParameters, + uint32 maxChannelIds, uint32 maxUserIds, uint32 maxTokenIds, uint32 maxMCSPDUsize) +{ + domainParameters->maxChannelIds = maxChannelIds; + domainParameters->maxUserIds = maxUserIds; + domainParameters->maxTokenIds = maxTokenIds; + domainParameters->maxMCSPDUsize = maxMCSPDUsize; + + domainParameters->numPriorities = 1; + domainParameters->minThroughput = 0; + domainParameters->maxHeight = 1; + domainParameters->protocolVersion = 2; +} + +/** + * Read MCS Domain Parameters. + * @param s stream + * @param domainParameters domain parameters + */ + +boolean mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters) +{ + int length; + ber_read_sequence_tag(s, &length); + ber_read_integer(s, &(domainParameters->maxChannelIds)); + ber_read_integer(s, &(domainParameters->maxUserIds)); + ber_read_integer(s, &(domainParameters->maxTokenIds)); + ber_read_integer(s, &(domainParameters->numPriorities)); + ber_read_integer(s, &(domainParameters->minThroughput)); + ber_read_integer(s, &(domainParameters->maxHeight)); + ber_read_integer(s, &(domainParameters->maxMCSPDUsize)); + ber_read_integer(s, &(domainParameters->protocolVersion)); + + return true; +} + +/** + * Write MCS Domain Parameters. + * @param s stream + * @param domainParameters domain parameters + */ + +void mcs_write_domain_parameters(STREAM* s, DomainParameters* domainParameters) +{ + int length; + STREAM* tmps; + + tmps = stream_new(stream_get_size(s)); + ber_write_integer(tmps, domainParameters->maxChannelIds); + ber_write_integer(tmps, domainParameters->maxUserIds); + ber_write_integer(tmps, domainParameters->maxTokenIds); + ber_write_integer(tmps, domainParameters->numPriorities); + ber_write_integer(tmps, domainParameters->minThroughput); + ber_write_integer(tmps, domainParameters->maxHeight); + ber_write_integer(tmps, domainParameters->maxMCSPDUsize); + ber_write_integer(tmps, domainParameters->protocolVersion); + + length = stream_get_length(tmps); + ber_write_sequence_tag(s, length); + stream_write(s, stream_get_head(tmps), length); + stream_free(tmps); +} + +/** + * Print MCS Domain Parameters. + * @param domainParameters domain parameters + */ + +void mcs_print_domain_parameters(DomainParameters* domainParameters) +{ + printf("DomainParameters {\n"); + printf("\tmaxChannelIds:%d\n", domainParameters->maxChannelIds); + printf("\tmaxUserIds:%d\n", domainParameters->maxUserIds); + printf("\tmaxTokenIds:%d\n", domainParameters->maxTokenIds); + printf("\tnumPriorities:%d\n", domainParameters->numPriorities); + printf("\tminThroughput:%d\n", domainParameters->minThroughput); + printf("\tmaxHeight:%d\n", domainParameters->maxHeight); + printf("\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize); + printf("\tprotocolVersion:%d\n", domainParameters->protocolVersion); + printf("}\n"); +} + +/** + * Read an MCS Connect Initial PDU.\n + * @msdn{cc240508} + * @param mcs MCS module + * @param s stream + */ + +boolean mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s) +{ + int length; + boolean upwardFlag; + + tpkt_read_header(s); + + if (tpdu_read_data(s) == 0) + return false; + + if (!ber_read_application_tag(s, MCS_TYPE_CONNECT_INITIAL, &length)) + return false; + + /* callingDomainSelector (OCTET_STRING) */ + if (!ber_read_octet_string(s, &length)) + return false; + stream_seek(s, length); + + /* calledDomainSelector (OCTET_STRING) */ + if (!ber_read_octet_string(s, &length)) + return false; + stream_seek(s, length); + + /* upwardFlag (BOOLEAN) */ + if (!ber_read_boolean(s, &upwardFlag)) + return false; + + /* targetParameters (DomainParameters) */ + mcs_read_domain_parameters(s, &mcs->targetParameters); + + /* minimumParameters (DomainParameters) */ + mcs_read_domain_parameters(s, &mcs->minimumParameters); + + /* maximumParameters (DomainParameters) */ + mcs_read_domain_parameters(s, &mcs->maximumParameters); + + if (!ber_read_octet_string(s, &length)) + return false; + + if (!gcc_read_conference_create_request(s, mcs->transport->settings)) + return false; + + return true; +} + +/** + * Write an MCS Connect Initial PDU.\n + * @msdn{cc240508} + * @param s stream + * @param mcs MCS module + * @param user_data GCC Conference Create Request + */ + +void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data) +{ + int length; + STREAM* tmps; + + tmps = stream_new(stream_get_size(s)); + + /* callingDomainSelector (OCTET_STRING) */ + ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector)); + + /* calledDomainSelector (OCTET_STRING) */ + ber_write_octet_string(tmps, calledDomainSelector, sizeof(calledDomainSelector)); + + /* upwardFlag (BOOLEAN) */ + ber_write_boolean(tmps, true); + + /* targetParameters (DomainParameters) */ + mcs_write_domain_parameters(tmps, &mcs->targetParameters); + + /* minimumParameters (DomainParameters) */ + mcs_write_domain_parameters(tmps, &mcs->minimumParameters); + + /* maximumParameters (DomainParameters) */ + mcs_write_domain_parameters(tmps, &mcs->maximumParameters); + + /* userData (OCTET_STRING) */ + ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data)); + + length = stream_get_length(tmps); + /* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */ + ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length); + stream_write(s, stream_get_head(tmps), length); + stream_free(tmps); +} + +/** + * Write an MCS Connect Response PDU.\n + * @msdn{cc240508} + * @param s stream + * @param mcs MCS module + * @param user_data GCC Conference Create Response + */ + +void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data) +{ + int length; + STREAM* tmps; + + tmps = stream_new(stream_get_size(s)); + ber_write_enumerated(tmps, 0, MCS_Result_enum_length); + ber_write_integer(tmps, 0); /* calledConnectId */ + mcs->domainParameters = mcs->targetParameters; + mcs_write_domain_parameters(tmps, &(mcs->domainParameters)); + /* userData (OCTET_STRING) */ + ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data)); + + length = stream_get_length(tmps); + ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length); + stream_write(s, stream_get_head(tmps), length); + stream_free(tmps); +} + +/** + * Send MCS Connect Initial.\n + * @msdn{cc240508} + * @param mcs mcs module + */ + +boolean mcs_send_connect_initial(rdpMcs* mcs) +{ + STREAM* s; + int length; + uint8 *bm, *em; + STREAM* gcc_CCrq; + STREAM* client_data; + int status; + + client_data = stream_new(512); + gcc_write_client_data_blocks(client_data, mcs->transport->settings); + + gcc_CCrq = stream_new(512); + gcc_write_conference_create_request(gcc_CCrq, client_data); + length = stream_get_length(gcc_CCrq) + 7; + + s = transport_send_stream_init(mcs->transport, 1024); + stream_get_mark(s, bm); + stream_seek(s, 7); + + mcs_write_connect_initial(s, mcs, gcc_CCrq); + stream_get_mark(s, em); + length = (em - bm); + stream_set_mark(s, bm); + + tpkt_write_header(s, length); + tpdu_write_data(s); + stream_set_mark(s, em); + + status = transport_write(mcs->transport, s); + + stream_free(gcc_CCrq); + stream_free(client_data); + + return (status < 0 ? false : true); +} + +/** + * Read MCS Connect Response.\n + * @msdn{cc240501} + * @param mcs mcs module + */ + +boolean mcs_recv_connect_response(rdpMcs* mcs, STREAM* s) +{ + int length; + uint8 result; + uint32 calledConnectId; + + tpkt_read_header(s); + + if (tpdu_read_data(s) == 0) + return false; + + ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length); + ber_read_enumerated(s, &result, MCS_Result_enum_length); + ber_read_integer(s, &calledConnectId); + + if (!mcs_read_domain_parameters(s, &(mcs->domainParameters))) + return false; + + ber_read_octet_string(s, &length); + + if (!gcc_read_conference_create_response(s, mcs->transport->settings)) + { + printf("mcs_recv_connect_response: gcc_read_conference_create_response failed\n"); + return false; + } + + return true; +} + +/** + * Send MCS Connect Response.\n + * @msdn{cc240501} + * @param mcs mcs module + */ + +boolean mcs_send_connect_response(rdpMcs* mcs) +{ + STREAM* s; + int length; + uint8 *bm, *em; + STREAM* gcc_CCrsp; + STREAM* server_data; + + server_data = stream_new(512); + gcc_write_server_data_blocks(server_data, mcs->transport->settings); + + gcc_CCrsp = stream_new(512); + gcc_write_conference_create_response(gcc_CCrsp, server_data); + length = stream_get_length(gcc_CCrsp) + 7; + + s = transport_send_stream_init(mcs->transport, 1024); + stream_get_mark(s, bm); + stream_seek(s, 7); + + mcs_write_connect_response(s, mcs, gcc_CCrsp); + stream_get_mark(s, em); + length = (em - bm); + stream_set_mark(s, bm); + + tpkt_write_header(s, length); + tpdu_write_data(s); + stream_set_mark(s, em); + + transport_write(mcs->transport, s); + + stream_free(gcc_CCrsp); + stream_free(server_data); + + return true; +} + +/** + * Read MCS Erect Domain Request.\n + * @msdn{cc240523} + * @param mcs + * @param s stream + */ + +boolean mcs_recv_erect_domain_request(rdpMcs* mcs, STREAM* s) +{ + uint16 length; + enum DomainMCSPDU MCSPDU; + + MCSPDU = DomainMCSPDU_ErectDomainRequest; + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return false; + + return true; +} + +/** + * Send MCS Erect Domain Request.\n + * @msdn{cc240523} + * @param mcs + */ + +boolean mcs_send_erect_domain_request(rdpMcs* mcs) +{ + STREAM* s; + uint16 length = 12; + s = transport_send_stream_init(mcs->transport, length); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ErectDomainRequest, length, 0); + + per_write_integer(s, 0); /* subHeight (INTEGER) */ + per_write_integer(s, 0); /* subInterval (INTEGER) */ + + if (transport_write(mcs->transport, s) < 0) + return false; + + return true; +} + +/** + * Read MCS Attach User Request.\n + * @msdn{cc240524} + * @param mcs mcs module + * @param s stream + */ + +boolean mcs_recv_attach_user_request(rdpMcs* mcs, STREAM* s) +{ + uint16 length; + enum DomainMCSPDU MCSPDU; + + MCSPDU = DomainMCSPDU_AttachUserRequest; + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return false; + + return true; +} + +/** + * Send MCS Attach User Request.\n + * @msdn{cc240524} + * @param mcs mcs module + */ + +boolean mcs_send_attach_user_request(rdpMcs* mcs) +{ + STREAM* s; + uint16 length = 8; + s = transport_send_stream_init(mcs->transport, length); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0); + + if (transport_write(mcs->transport, s) < 0) + return false; + + return true; +} + +/** + * Read MCS Attach User Confirm.\n + * @msdn{cc240525} + * @param mcs mcs module + */ + +boolean mcs_recv_attach_user_confirm(rdpMcs* mcs, STREAM* s) +{ + uint16 length; + uint8 result; + enum DomainMCSPDU MCSPDU; + + MCSPDU = DomainMCSPDU_AttachUserConfirm; + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return false; + + per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ + per_read_integer16(s, &(mcs->user_id), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + + return true; +} + +/** + * Send MCS Attach User Confirm.\n + * @msdn{cc240525} + * @param mcs mcs module + */ + +boolean mcs_send_attach_user_confirm(rdpMcs* mcs) +{ + STREAM* s; + uint16 length = 11; + + s = transport_send_stream_init(mcs->transport, length); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2); + + per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */ + mcs->user_id = 1002; + per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + + transport_write(mcs->transport, s); + + return true; +} + +/** + * Read MCS Channel Join Request.\n + * @msdn{cc240526} + * @param mcs mcs module + * @param s stream + */ + +boolean mcs_recv_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id) +{ + uint16 length; + enum DomainMCSPDU MCSPDU; + uint16 user_id; + + MCSPDU = DomainMCSPDU_ChannelJoinRequest; + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return false; + + if (!per_read_integer16(s, &user_id, MCS_BASE_CHANNEL_ID)) + return false; + if (user_id != mcs->user_id) + return false; + if (!per_read_integer16(s, channel_id, 0)) + return false; + + return true; +} + +/** + * Send MCS Channel Join Request.\n + * @msdn{cc240526} + * @param mcs mcs module + * @param channel_id channel id + */ + +boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id) +{ + STREAM* s; + uint16 length = 12; + s = transport_send_stream_init(mcs->transport, 12); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinRequest, length, 0); + + per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); + per_write_integer16(s, channel_id, 0); + + if (transport_write(mcs->transport, s) < 0) + return false; + + return true; +} + +/** + * Read MCS Channel Join Confirm.\n + * @msdn{cc240527} + * @param mcs mcs module + */ + +boolean mcs_recv_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id) +{ + uint16 length; + uint8 result; + uint16 initiator; + uint16 requested; + enum DomainMCSPDU MCSPDU; + + MCSPDU = DomainMCSPDU_ChannelJoinConfirm; + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return false; + + per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ + per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + per_read_integer16(s, &requested, 0); /* requested (ChannelId) */ + per_read_integer16(s, channel_id, 0); /* channelId */ + + return true; +} + +/** + * Send MCS Channel Join Confirm.\n + * @msdn{cc240527} + * @param mcs mcs module + */ + +boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id) +{ + STREAM* s; + uint16 length = 15; + s = transport_send_stream_init(mcs->transport, 15); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_ChannelJoinConfirm, length, 2); + + per_write_enumerated(s, 0, MCS_Result_enum_length); /* result */ + per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + per_write_integer16(s, channel_id, 0); /* requested (ChannelId) */ + per_write_integer16(s, channel_id, 0); /* channelId */ + + transport_write(mcs->transport, s); + + return true; +} + +/** + * Send MCS Disconnect Provider Ultimatum PDU.\n + * @param mcs mcs module + */ + +boolean mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs) +{ + STREAM* s; + uint16 length = 9; + s = transport_send_stream_init(mcs->transport, 9); + + mcs_write_domain_mcspdu_header(s, DomainMCSPDU_DisconnectProviderUltimatum, length, 1); + + per_write_enumerated(s, 0, 0); /* reason */ + + transport_write(mcs->transport, s); + + return true; +} + +/** + * Instantiate new MCS module. + * @param transport transport + * @return new MCS module + */ + +rdpMcs* mcs_new(rdpTransport* transport) +{ + rdpMcs* mcs; + + mcs = (rdpMcs*) xzalloc(sizeof(rdpMcs)); + + if (mcs != NULL) + { + mcs->transport = transport; + mcs_init_domain_parameters(&mcs->targetParameters, 34, 2, 0, 0xFFFF); + mcs_init_domain_parameters(&mcs->minimumParameters, 1, 1, 1, 0x420); + mcs_init_domain_parameters(&mcs->maximumParameters, 0xFFFF, 0xFC17, 0xFFFF, 0xFFFF); + } + + return mcs; +} + +/** + * Free MCS module. + * @param mcs MCS module to be freed + */ + +void mcs_free(rdpMcs* mcs) +{ + if (mcs != NULL) + { + xfree(mcs); + } +} diff --git a/libfreerdp-core/mcs.h b/libfreerdp-core/mcs.h new file mode 100644 index 0000000..a92d9dc --- /dev/null +++ b/libfreerdp-core/mcs.h @@ -0,0 +1,156 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * T.125 Multipoint Communication Service (MCS) Protocol + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MCS_H +#define __MCS_H + +#include "ber.h" +#include "transport.h" + +#include +#include + +#define MCS_BASE_CHANNEL_ID 1001 +#define MCS_GLOBAL_CHANNEL_ID 1003 + +enum MCS_Result +{ + MCS_Result_successful = 0, + MCS_Result_domain_merging = 1, + MCS_Result_domain_not_hierarchical = 2, + MCS_Result_no_such_channel = 3, + MCS_Result_no_such_domain = 4, + MCS_Result_no_such_user = 5, + MCS_Result_not_admitted = 6, + MCS_Result_other_user_id = 7, + MCS_Result_parameters_unacceptable = 8, + MCS_Result_token_not_available = 9, + MCS_Result_token_not_possessed = 10, + MCS_Result_too_many_channels = 11, + MCS_Result_too_many_tokens = 12, + MCS_Result_too_many_users = 13, + MCS_Result_unspecified_failure = 14, + MCS_Result_user_rejected = 15, + MCS_Result_enum_length = 16 +}; + +enum DomainMCSPDU +{ + DomainMCSPDU_PlumbDomainIndication = 0, + DomainMCSPDU_ErectDomainRequest = 1, + DomainMCSPDU_MergeChannelsRequest = 2, + DomainMCSPDU_MergeChannelsConfirm = 3, + DomainMCSPDU_PurgeChannelsIndication = 4, + DomainMCSPDU_MergeTokensRequest = 5, + DomainMCSPDU_MergeTokensConfirm = 6, + DomainMCSPDU_PurgeTokensIndication = 7, + DomainMCSPDU_DisconnectProviderUltimatum = 8, + DomainMCSPDU_RejectMCSPDUUltimatum = 9, + DomainMCSPDU_AttachUserRequest = 10, + DomainMCSPDU_AttachUserConfirm = 11, + DomainMCSPDU_DetachUserRequest = 12, + DomainMCSPDU_DetachUserIndication = 13, + DomainMCSPDU_ChannelJoinRequest = 14, + DomainMCSPDU_ChannelJoinConfirm = 15, + DomainMCSPDU_ChannelLeaveRequest = 16, + DomainMCSPDU_ChannelConveneRequest = 17, + DomainMCSPDU_ChannelConveneConfirm = 18, + DomainMCSPDU_ChannelDisbandRequest = 19, + DomainMCSPDU_ChannelDisbandIndication = 20, + DomainMCSPDU_ChannelAdmitRequest = 21, + DomainMCSPDU_ChannelAdmitIndication = 22, + DomainMCSPDU_ChannelExpelRequest = 23, + DomainMCSPDU_ChannelExpelIndication = 24, + DomainMCSPDU_SendDataRequest = 25, + DomainMCSPDU_SendDataIndication = 26, + DomainMCSPDU_UniformSendDataRequest = 27, + DomainMCSPDU_UniformSendDataIndication = 28, + DomainMCSPDU_TokenGrabRequest = 29, + DomainMCSPDU_TokenGrabConfirm = 30, + DomainMCSPDU_TokenInhibitRequest = 31, + DomainMCSPDU_TokenInhibitConfirm = 32, + DomainMCSPDU_TokenGiveRequest = 33, + DomainMCSPDU_TokenGiveIndication = 34, + DomainMCSPDU_TokenGiveResponse = 35, + DomainMCSPDU_TokenGiveConfirm = 36, + DomainMCSPDU_TokenPleaseRequest = 37, + DomainMCSPDU_TokenPleaseConfirm = 38, + DomainMCSPDU_TokenReleaseRequest = 39, + DomainMCSPDU_TokenReleaseConfirm = 40, + DomainMCSPDU_TokenTestRequest = 41, + DomainMCSPDU_TokenTestConfirm = 42, + DomainMCSPDU_enum_length = 43 +}; + +typedef struct +{ + uint32 maxChannelIds; + uint32 maxUserIds; + uint32 maxTokenIds; + uint32 numPriorities; + uint32 minThroughput; + uint32 maxHeight; + uint32 maxMCSPDUsize; + uint32 protocolVersion; +} DomainParameters; + +struct rdp_mcs +{ + uint16 user_id; + struct rdp_transport* transport; + DomainParameters domainParameters; + DomainParameters targetParameters; + DomainParameters minimumParameters; + DomainParameters maximumParameters; + + boolean user_channel_joined; + boolean global_channel_joined; +}; +typedef struct rdp_mcs rdpMcs; + +#define MCS_SEND_DATA_HEADER_MAX_LENGTH 8 + +#define MCS_TYPE_CONNECT_INITIAL 0x65 +#define MCS_TYPE_CONNECT_RESPONSE 0x66 + +void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data); +void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data); + +boolean mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s); +boolean mcs_send_connect_initial(rdpMcs* mcs); +boolean mcs_recv_connect_response(rdpMcs* mcs, STREAM* s); +boolean mcs_send_connect_response(rdpMcs* mcs); +boolean mcs_recv_erect_domain_request(rdpMcs* mcs, STREAM* s); +boolean mcs_send_erect_domain_request(rdpMcs* mcs); +boolean mcs_recv_attach_user_request(rdpMcs* mcs, STREAM* s); +boolean mcs_send_attach_user_request(rdpMcs* mcs); +boolean mcs_recv_attach_user_confirm(rdpMcs* mcs, STREAM* s); +boolean mcs_send_attach_user_confirm(rdpMcs* mcs); +boolean mcs_recv_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id); +boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id); +boolean mcs_recv_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id); +boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id); +boolean mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs); +boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, uint16* length); +void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, uint16 length, uint8 options); + +rdpMcs* mcs_new(rdpTransport* transport); +void mcs_free(rdpMcs* mcs); + +#endif /* __MCS_H */ diff --git a/libfreerdp-core/mppc.c b/libfreerdp-core/mppc.c new file mode 100644 index 0000000..8e66eb3 --- /dev/null +++ b/libfreerdp-core/mppc.c @@ -0,0 +1,1292 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Implements Microsoft Point to Point Compression (MPPC) protocol + * + * Copyright 2011 Laxmikant Rashinkar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdp.h" + +#if 0 +static uint8 HuffLengthLEC[] = +{ + 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x8, 0x8, 0x8, 0x8, + 0x8, 0x8, 0x8, 0x9, 0x8, 0x9, 0x9, 0x9, 0x9, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, + 0x8, 0x9, 0x9, 0xa, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, + 0x9, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0x9, 0xa, 0x9, 0x9, + 0x8, 0x9, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x8, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, + 0x7, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xd, 0xa, 0xa, 0xa, 0xa, + 0xa, 0xa, 0xb, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, + 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, + 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, + 0x8, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0x8, 0x7, + 0xd, 0xd, 0x7, 0x7, 0xa, 0x7, 0x7, 0x6, 0x6, 0x6, 0x6, 0x5, 0x6, 0x6, 0x6, 0x5, + 0x6, 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, + 0x8, 0x5, 0x6, 0x7, 0x7 +}; +#endif + +static uint16 HuffIndexLEC[512] = +{ + 0x007b, 0xff1f, 0xff0d, 0xfe27, 0xfe00, 0xff05, 0xff17, 0xfe68, 0x00c5, 0xfe07, 0xff13, 0xfec0, 0xff08, 0xfe18, 0xff1b, 0xfeb3, + 0xfe03, 0x00a2, 0xfe42, 0xff10, 0xfe0b, 0xfe02, 0xfe91, 0xff19, 0xfe80, 0x00e9, 0xfe3a, 0xff15, 0xfe12, 0x0057, 0xfed7, 0xff1d, + 0xff0e, 0xfe35, 0xfe69, 0xff22, 0xff18, 0xfe7a, 0xfe01, 0xff23, 0xff14, 0xfef4, 0xfeb4, 0xfe09, 0xff1c, 0xfec4, 0xff09, 0xfe60, + 0xfe70, 0xff12, 0xfe05, 0xfe92, 0xfea1, 0xff1a, 0xfe0f, 0xff07, 0xfe56, 0xff16, 0xff02, 0xfed8, 0xfee8, 0xff1e, 0xfe1d, 0x003b, + 0xffff, 0xff06, 0xffff, 0xfe71, 0xfe89, 0xffff, 0xffff, 0xfe2c, 0xfe2b, 0xfe20, 0xffff, 0xfebb, 0xfecf, 0xfe08, 0xffff, 0xfee0, + 0xfe0d, 0xffff, 0xfe99, 0xffff, 0xfe04, 0xfeaa, 0xfe49, 0xffff, 0xfe17, 0xfe61, 0xfedf, 0xffff, 0xfeff, 0xfef6, 0xfe4c, 0xffff, + 0xffff, 0xfe87, 0xffff, 0xff24, 0xffff, 0xfe3c, 0xfe72, 0xffff, 0xffff, 0xfece, 0xffff, 0xfefe, 0xffff, 0xfe23, 0xfebc, 0xfe0a, + 0xfea9, 0xffff, 0xfe11, 0xffff, 0xfe82, 0xffff, 0xfe06, 0xfe9a, 0xfef5, 0xffff, 0xfe22, 0xfe4d, 0xfe5f, 0xffff, 0xff03, 0xfee1, + 0xffff, 0xfeca, 0xfecc, 0xffff, 0xfe19, 0xffff, 0xfeb7, 0xffff, 0xffff, 0xfe83, 0xfe29, 0xffff, 0xffff, 0xffff, 0xfe6c, 0xffff, + 0xfeed, 0xffff, 0xffff, 0xfe46, 0xfe5c, 0xfe15, 0xffff, 0xfedb, 0xfea6, 0xffff, 0xffff, 0xfe44, 0xffff, 0xfe0c, 0xffff, 0xfe95, + 0xfefc, 0xffff, 0xffff, 0xfeb8, 0x16c9, 0xffff, 0xfef0, 0xffff, 0xfe38, 0xffff, 0xffff, 0xfe6d, 0xfe7e, 0xffff, 0xffff, 0xffff, + 0xffff, 0xfe5b, 0xfedc, 0xffff, 0xffff, 0xfeec, 0xfe47, 0xfe1f, 0xffff, 0xfe7f, 0xfe96, 0xffff, 0xffff, 0xfea5, 0xffff, 0xfe10, + 0xfe40, 0xfe32, 0xfebf, 0xffff, 0xffff, 0xfed4, 0xfef1, 0xffff, 0xffff, 0xffff, 0xfe75, 0xffff, 0xffff, 0xfe8d, 0xfe31, 0xffff, + 0xfe65, 0xfe1b, 0xffff, 0xfee4, 0xfefb, 0xffff, 0xffff, 0xfe52, 0xffff, 0xfe0e, 0xffff, 0xfe9d, 0xfeaf, 0xffff, 0xffff, 0xfe51, + 0xfed3, 0xffff, 0xff20, 0xffff, 0xfe2f, 0xffff, 0xffff, 0xfec1, 0xfe8c, 0xffff, 0xffff, 0xffff, 0xfe3f, 0xffff, 0xffff, 0xfe76, + 0xffff, 0xfefa, 0xfe53, 0xfe25, 0xffff, 0xfe64, 0xfee5, 0xffff, 0xffff, 0xfeae, 0xffff, 0xfe13, 0xffff, 0xfe88, 0xfe9e, 0xffff, + 0xfe43, 0xffff, 0xffff, 0xfea4, 0xfe93, 0xffff, 0xffff, 0xffff, 0xfe3d, 0xffff, 0xffff, 0xfeeb, 0xfed9, 0xffff, 0xfe14, 0xfe5a, + 0xffff, 0xfe28, 0xfe7d, 0xffff, 0xffff, 0xfe6a, 0xffff, 0xffff, 0xff01, 0xfec6, 0xfec8, 0xffff, 0xffff, 0xfeb5, 0xffff, 0xffff, + 0xffff, 0xfe94, 0xfe78, 0xffff, 0xffff, 0xffff, 0xfea3, 0xffff, 0xffff, 0xfeda, 0xfe58, 0xffff, 0xfe1e, 0xfe45, 0xfeea, 0xffff, + 0xfe6b, 0xffff, 0xffff, 0xfe37, 0xffff, 0xffff, 0xffff, 0xfe7c, 0xfeb6, 0xffff, 0xffff, 0xfef8, 0xffff, 0xffff, 0xffff, 0xfec7, + 0xfe9b, 0xffff, 0xffff, 0xffff, 0xfe50, 0xffff, 0xffff, 0xfead, 0xfee2, 0xffff, 0xfe1a, 0xfe63, 0xfe4e, 0xffff, 0xffff, 0xfef9, + 0xffff, 0xfe73, 0xffff, 0xffff, 0xffff, 0xfe30, 0xfe8b, 0xffff, 0xffff, 0xfebd, 0xfe2e, 0x0100, 0xffff, 0xfeee, 0xfed2, 0xffff, + 0xffff, 0xffff, 0xfeac, 0xffff, 0xffff, 0xfe9c, 0xfe84, 0xffff, 0xfe24, 0xfe4f, 0xfef7, 0xffff, 0xffff, 0xfee3, 0xfe62, 0xffff, + 0xffff, 0xffff, 0xffff, 0xfe8a, 0xfe74, 0xffff, 0xffff, 0xfe3e, 0xffff, 0xffff, 0xffff, 0xfed1, 0xfebe, 0xffff, 0xffff, 0xfe2d, + 0xffff, 0xfe4a, 0xfef3, 0xffff, 0xffff, 0xfedd, 0xfe5e, 0xfe16, 0xffff, 0xfe48, 0xfea8, 0xffff, 0xfeab, 0xfe97, 0xffff, 0xffff, + 0xfed0, 0xffff, 0xffff, 0xfecd, 0xfeb9, 0xffff, 0xffff, 0xffff, 0xfe2a, 0xffff, 0xffff, 0xfe86, 0xfe6e, 0xffff, 0xffff, 0xffff, + 0xfede, 0xffff, 0xffff, 0xfe5d, 0xfe4b, 0xfe21, 0xffff, 0xfeef, 0xfe98, 0xffff, 0xffff, 0xfe81, 0xffff, 0xffff, 0xffff, 0xfea7, + 0xffff, 0xfeba, 0xfefd, 0xffff, 0xffff, 0xffff, 0xfecb, 0xffff, 0xffff, 0xfe6f, 0xfe39, 0xffff, 0xffff, 0xffff, 0xfe85, 0xffff, + 0x010c, 0xfee6, 0xfe67, 0xfe1c, 0xffff, 0xfe54, 0xfeb2, 0xffff, 0xffff, 0xfe9f, 0xffff, 0xffff, 0xffff, 0xfe59, 0xfeb1, 0xffff, + 0xfec2, 0xffff, 0xffff, 0xfe36, 0xfef2, 0xffff, 0xffff, 0xfed6, 0xfe77, 0xffff, 0xffff, 0xffff, 0xfe33, 0xffff, 0xffff, 0xfe8f, + 0xfe55, 0xfe26, 0x010a, 0xff04, 0xfee7, 0xffff, 0x0121, 0xfe66, 0xffff, 0xffff, 0xffff, 0xfeb0, 0xfea0, 0xffff, 0x010f, 0xfe90, + 0xffff, 0xffff, 0xfed5, 0xffff, 0xffff, 0xfec3, 0xfe34, 0xffff, 0xffff, 0xffff, 0xfe8e, 0xffff, 0x0111, 0xfe79, 0xfe41, 0x010b +}; + +static uint16 LECHTab[] = +{ + 511, 0, 508, 448, 494, 347, 486, 482 +}; + +#if 0 +static uint8 HuffLenLOM[] = +{ + 0x4, 0x2, 0x3, 0x4, 0x3, 0x4, 0x4, 0x5, 0x4, 0x5, 0x5, 0x6, 0x6, 0x7, 0x7, 0x8, + 0x7, 0x8, 0x8, 0x9, 0x9, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9 +}; +#endif + +static uint16 HuffIndexLOM[] = +{ + 0x0fe1, 0x0fe0, 0x0fe2, 0x0fe8, 0x000e, 0x0fe5, 0x0fe4, 0x0fea, 0x0ff1, 0x0fe3, 0x0015, 0x0fe7, 0x0fef, 0x0046, 0x0ff0, 0x0fed, + 0x0fff, 0x0ff7, 0x0ffb, 0x0019, 0x0ffd, 0x0ff4, 0x012c, 0x0feb, 0x0ffe, 0x0ff6, 0x0ffa, 0x0089, 0x0ffc, 0x0ff3, 0x0ff8, 0x0ff2 +}; + +static uint8 LOMHTab[] = +{ + 0, 4, 10, 19 +}; + +#if 0 +static uint8 CopyOffsetBitsLUT[] = +{ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 +}; + +static uint32 CopyOffsetBaseLUT[] = +{ + 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, + 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153, 65537 +}; + +static uint8 LoMBitsLUT[] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 8, 8, 14, 14 +}; + +static uint16 LoMBaseLUT[] = +{ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 22, 26, 30, + 34, 42, 50, 58, 66, 82, 98, 114, 130, 194, 258, 514, 2, 2 +}; +#endif + +uint16 LEChash(uint16 key) +{ + return ((key & 0x1ff) ^ (key >> 9) ^ (key >> 4) ^ (key >> 7)); +} + +uint16 LOMhash(uint16 key) +{ + return ((key & 0x1f) ^ (key >> 5) ^ (key >> 9)); +} + +uint16 miniLEChash(uint16 key) +{ + uint16 h; + h = ((((key >> 8) ^ (key & 0xff)) >> 2) & 0xf); + if(key >> 9) + h = ~h; + return (h % 12); +} + +uint8 miniLOMhash(uint16 key) +{ + return ((key >> 4) ^ (key >> 6) ^ (key >> 7)); +} + +uint16 getLECindex(uint16 huff) +{ + uint16 h = HuffIndexLEC[LEChash(huff)]; + if((h ^ huff) >> 9) + return h & 0x1ff; + else + return HuffIndexLEC[LECHTab[miniLEChash(huff)]]; +} + +uint16 getLOMindex(uint16 huff) +{ + uint16 h = HuffIndexLOM[LOMhash(huff)]; + if((h ^ huff) >> 5) + { + return h & 0x1f; + } + else + return HuffIndexLOM[LOMHTab[miniLOMhash(huff)]]; +} + +int decompress_rdp(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen) +{ + int type = ctype & 0x0f; + + switch (type) + { + case PACKET_COMPR_TYPE_8K: + return decompress_rdp_4(rdp, cbuf, len, ctype, roff, rlen); + break; + + case PACKET_COMPR_TYPE_64K: + return decompress_rdp_5(rdp, cbuf, len, ctype, roff, rlen); + break; + + case PACKET_COMPR_TYPE_RDP6: + return decompress_rdp_6(rdp, cbuf, len, ctype, roff, rlen); + break; + + case PACKET_COMPR_TYPE_RDP61: + return decompress_rdp_61(rdp, cbuf, len, ctype, roff, rlen); + break; + + default: + printf("mppc.c: invalid RDP compression code 0x%2.2x\n", type); + return false; + } +} + +/** + * decompress RDP 4 data + * + * @param rdp per session information + * @param cbuf compressed data + * @param len length of compressed data + * @param ctype compression flags + * @param roff starting offset of uncompressed data + * @param rlen length of uncompressed data + * + * @return True on success, False on failure + */ + +int decompress_rdp_4(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen) +{ + uint8* history_buf; /* uncompressed data goes here */ + uint8* history_ptr; /* points to next free slot in history_buf */ + uint32 d32; /* we process 4 compressed bytes at a time */ + uint16 copy_offset; /* location to copy data from */ + uint16 lom; /* length of match */ + uint8* src_ptr; /* used while copying compressed data */ + uint8* cptr; /* points to next byte in cbuf */ + uint8 cur_byte; /* last byte fetched from cbuf */ + int bits_left; /* bits left in d34 for processing */ + int cur_bits_left; /* bits left in cur_byte for processing */ + int tmp; + uint32 i32; + + printf("decompress_rdp_4:\n"); + + if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL)) + { + printf("decompress_rdp_4: null\n"); + return false; + } + + src_ptr = 0; + cptr = cbuf; + copy_offset = 0; + lom = 0; + bits_left = 0; + cur_bits_left = 0; + d32 = 0; + cur_byte = 0; + *rlen = 0; + + /* get start of history buffer */ + history_buf = rdp->mppc->history_buf; + + /* get next free slot in history buffer */ + history_ptr = rdp->mppc->history_ptr; + *roff = history_ptr - history_buf; + + if (ctype & PACKET_AT_FRONT) + { + /* place compressed data at start of history buffer */ + history_ptr = rdp->mppc->history_buf; + rdp->mppc->history_ptr = rdp->mppc->history_buf; + *roff = 0; + } + + if (ctype & PACKET_FLUSHED) + { + /* re-init history buffer */ + history_ptr = rdp->mppc->history_buf; + memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE); + *roff = 0; + } + + if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED) + { + /* data in cbuf is not compressed - copy to history buf as is */ + memcpy(history_ptr, cbuf, len); + history_ptr += len; + *rlen = history_ptr - rdp->mppc->history_ptr; + rdp->mppc->history_ptr = history_ptr; + return true; + } + + /* load initial data */ + tmp = 24; + while (cptr < cbuf + len) + { + i32 = *cptr++; + d32 |= i32 << tmp; + bits_left += 8; + tmp -= 8; + if (tmp < 0) + { + break; + } + } + + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + + /* + ** start uncompressing data in cbuf + */ + + while (bits_left >= 8) + { + /* + value 0xxxxxxx = literal, not encoded + value 10xxxxxx = literal, encoded + value 1111xxxx = copy offset 0 - 63 + value 1110xxxx = copy offset 64 - 319 + value 110xxxxx = copy offset 320 - 8191 + */ + + /* + at this point, we are guaranteed that d32 has 32 bits to + be processed, unless we have reached end of cbuf + */ + + copy_offset = 0; + + if ((d32 & 0x80000000) == 0) + { + /* got a literal */ + *history_ptr++ = d32 >> 24; + d32 <<= 8; + bits_left -= 8; + } + else if ((d32 & 0xc0000000) == 0x80000000) + { + /* got encoded literal */ + d32 <<= 2; + *history_ptr++ = (d32 >> 25) | 0x80; + d32 <<= 7; + bits_left -= 9; + } + else if ((d32 & 0xf0000000) == 0xf0000000) + { + /* got copy offset in range 0 - 63, */ + /* with 6 bit copy offset */ + d32 <<= 4; + copy_offset = d32 >> 26; + d32 <<= 6; + bits_left -= 10; + } + else if ((d32 & 0xf0000000) == 0xe0000000) + { + /* got copy offset in range 64 - 319, */ + /* with 8 bit copy offset */ + d32 <<= 4; + copy_offset = d32 >> 24; + copy_offset += 64; + d32 <<= 8; + bits_left -= 12; + } + else if ((d32 & 0xe0000000) == 0xc0000000) + { + /* got copy offset in range 320 - 8191, */ + /* with 13 bits copy offset */ + d32 <<= 3; + copy_offset = d32 >> 19; + copy_offset += 320; + d32 <<= 13; + bits_left -= 16; + } + + /* + ** get more bits before we process length of match + */ + + /* how may bits do we need to get? */ + tmp = 32 - bits_left; + + while (tmp) + { + if (cur_bits_left < tmp) + { + /* we have less bits than we need */ + i32 = cur_byte >> (8 - cur_bits_left); + d32 |= i32 << ((32 - bits_left) - cur_bits_left); + bits_left += cur_bits_left; + tmp -= cur_bits_left; + if (cptr < cbuf + len) + { + /* more compressed data available */ + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + /* no more compressed data available */ + tmp = 0; + cur_bits_left = 0; + } + } + else if (cur_bits_left > tmp) + { + /* we have more bits than we need */ + d32 |= cur_byte >> (8 - tmp); + cur_byte <<= tmp; + cur_bits_left -= tmp; + bits_left = 32; + break; + } + else + { + /* we have just the right amount of bits */ + d32 |= cur_byte >> (8 - tmp); + bits_left = 32; + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + break; + } + } + + if (!copy_offset) + { + continue; + } + + /* + ** compute Length of Match + */ + + /* + lengh of match Encoding (binary header + LoM bits + -------------- ---------------------------------- + 3 0 + 4...7 10 + 2 lower bits of L-o-M + 8...15 110 + 3 lower bits of L-o-M + 16...31 1110 + 4 lower bits of L-o-M + 32...63 11110 + 5 lower bits of L-o-M + 64...127 111110 + 6 lower bits of L-o-M + 128...255 1111110 + 7 lower bits of L-o-M + 256...511 11111110 + 8 lower bits of L-o-M + 512...1023 111111110 + 9 lower bits of L-o-M + 1024...2047 1111111110 + 10 lower bits of L-o-M + 2048...4095 11111111110 + 11 lower bits of L-o-M + 4096...8191 111111111110 + 12 lower bits of L-o-M + */ + + if ((d32 & 0x80000000) == 0) + { + /* lom is fixed to 3 */ + lom = 3; + d32 <<= 1; + bits_left -= 1; + } + else if ((d32 & 0xc0000000) == 0x80000000) + { + /* 2 lower bits of LoM */ + lom = ((d32 >> 28) & 0x03) + 4; + d32 <<= 4; + bits_left -= 4; + } + else if ((d32 & 0xe0000000) == 0xc0000000) + { + /* 3 lower bits of LoM */ + lom = ((d32 >> 26) & 0x07) + 8; + d32 <<= 6; + bits_left -= 6; + } + else if ((d32 & 0xf0000000) == 0xe0000000) + { + /* 4 lower bits of LoM */ + lom = ((d32 >> 24) & 0x0f) + 16; + d32 <<= 8; + bits_left -= 8; + } + else if ((d32 & 0xf8000000) == 0xf0000000) + { + /* 5 lower bits of LoM */ + lom = ((d32 >> 22) & 0x1f) + 32; + d32 <<= 10; + bits_left -= 10; + } + else if ((d32 & 0xfc000000) == 0xf8000000) + { + /* 6 lower bits of LoM */ + lom = ((d32 >> 20) & 0x3f) + 64; + d32 <<= 12; + bits_left -= 12; + } + else if ((d32 & 0xfe000000) == 0xfc000000) + { + /* 7 lower bits of LoM */ + lom = ((d32 >> 18) & 0x7f) + 128; + d32 <<= 14; + bits_left -= 14; + } + else if ((d32 & 0xff000000) == 0xfe000000) + { + /* 8 lower bits of LoM */ + lom = ((d32 >> 16) & 0xff) + 256; + d32 <<= 16; + bits_left -= 16; + } + else if ((d32 & 0xff800000) == 0xff000000) + { + /* 9 lower bits of LoM */ + lom = ((d32 >> 14) & 0x1ff) + 512; + d32 <<= 18; + bits_left -= 18; + } + else if ((d32 & 0xffc00000) == 0xff800000) + { + /* 10 lower bits of LoM */ + lom = ((d32 >> 12) & 0x3ff) + 1024; + d32 <<= 20; + bits_left -= 20; + } + else if ((d32 & 0xffe00000) == 0xffc00000) + { + /* 11 lower bits of LoM */ + lom = ((d32 >> 10) & 0x7ff) + 2048; + d32 <<= 22; + bits_left -= 22; + } + else if ((d32 & 0xfff00000) == 0xffe00000) + { + /* 12 lower bits of LoM */ + lom = ((d32 >> 8) & 0xfff) + 4096; + d32 <<= 24; + bits_left -= 24; + } + + /* now that we have copy_offset and LoM, process them */ + + src_ptr = history_ptr - copy_offset; + if (src_ptr >= rdp->mppc->history_buf) + { + /* data does not wrap around */ + while (lom > 0) + { + *history_ptr++ = *src_ptr++; + lom--; + } + } + else + { + src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf)); + src_ptr++; + while (lom && (src_ptr <= rdp->mppc->history_buf_end)) + { + *history_ptr++ = *src_ptr++; + lom--; + } + + src_ptr = rdp->mppc->history_buf; + while (lom > 0) + { + *history_ptr++ = *src_ptr++; + lom--; + } + } + + /* + ** get more bits before we restart the loop + */ + + /* how may bits do we need to get? */ + tmp = 32 - bits_left; + + while (tmp) + { + if (cur_bits_left < tmp) + { + /* we have less bits than we need */ + i32 = cur_byte >> (8 - cur_bits_left); + d32 |= i32 << ((32 - bits_left) - cur_bits_left); + bits_left += cur_bits_left; + tmp -= cur_bits_left; + if (cptr < cbuf + len) + { + /* more compressed data available */ + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + /* no more compressed data available */ + tmp = 0; + cur_bits_left = 0; + } + } + else if (cur_bits_left > tmp) + { + /* we have more bits than we need */ + d32 |= cur_byte >> (8 - tmp); + cur_byte <<= tmp; + cur_bits_left -= tmp; + bits_left = 32; + break; + } + else + { + /* we have just the right amount of bits */ + d32 |= cur_byte >> (8 - tmp); + bits_left = 32; + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + break; + } + } + } /* end while (bits_left >= 8) */ + + *rlen = history_ptr - rdp->mppc->history_ptr; + + rdp->mppc->history_ptr = history_ptr; + + return true; +} + +/** + * decompress RDP 5 data + * + * @param rdp per session information + * @param cbuf compressed data + * @param len length of compressed data + * @param ctype compression flags + * @param roff starting offset of uncompressed data + * @param rlen length of uncompressed data + * + * @return True on success, False on failure + */ + +int decompress_rdp_5(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen) +{ + uint8* history_buf; /* uncompressed data goes here */ + uint8* history_ptr; /* points to next free slot in bistory_buf */ + uint32 d32; /* we process 4 compressed bytes at a time */ + uint16 copy_offset; /* location to copy data from */ + uint16 lom; /* length of match */ + uint8* src_ptr; /* used while copying compressed data */ + uint8* cptr; /* points to next byte in cbuf */ + uint8 cur_byte; /* last byte fetched from cbuf */ + int bits_left; /* bits left in d32 for processing */ + int cur_bits_left; /* bits left in cur_byte for processing */ + int tmp; + uint32 i32; + + if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL)) + { + printf("decompress_rdp_5: null\n"); + return false; + } + + src_ptr = 0; + cptr = cbuf; + copy_offset = 0; + lom = 0; + bits_left = 0; + cur_bits_left = 0; + d32 = 0; + cur_byte = 0; + *rlen = 0; + + /* get start of history buffer */ + history_buf = rdp->mppc->history_buf; + + /* get next free slot in history buffer */ + history_ptr = rdp->mppc->history_ptr; + *roff = history_ptr - history_buf; + + if (ctype & PACKET_AT_FRONT) + { + /* place compressed data at start of history buffer */ + history_ptr = rdp->mppc->history_buf; + rdp->mppc->history_ptr = rdp->mppc->history_buf; + *roff = 0; + } + + if (ctype & PACKET_FLUSHED) + { + /* re-init history buffer */ + history_ptr = rdp->mppc->history_buf; + memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE); + *roff = 0; + } + + if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED) + { + /* data in cbuf is not compressed - copy to history buf as is */ + memcpy(history_ptr, cbuf, len); + history_ptr += len; + *rlen = history_ptr - rdp->mppc->history_ptr; + rdp->mppc->history_ptr = history_ptr; + return true; + } + + /* load initial data */ + tmp = 24; + while (cptr < cbuf + len) + { + i32 = *cptr++; + d32 |= i32 << tmp; + bits_left += 8; + tmp -= 8; + if (tmp < 0) + { + break; + } + } + + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + + /* + ** start uncompressing data in cbuf + */ + + while (bits_left >= 8) + { + /* + value 0xxxxxxx = literal, not encoded + value 10xxxxxx = literal, encoded + value 11111xxx = copy offset 0 - 63 + value 11110xxx = copy offset 64 - 319 + value 1110xxxx = copy offset 320 - 2367 + value 110xxxxx = copy offset 2368+ + */ + + /* + at this point, we are guaranteed that d32 has 32 bits to + be processed, unless we have reached end of cbuf + */ + + copy_offset = 0; + + if ((d32 & 0x80000000) == 0) + { + /* got a literal */ + *history_ptr++ = d32 >> 24; + d32 <<= 8; + bits_left -= 8; + } + else if ((d32 & 0xc0000000) == 0x80000000) + { + /* got encoded literal */ + d32 <<= 2; + *history_ptr++ = (d32 >> 25) | 0x80; + d32 <<= 7; + bits_left -= 9; + } + else if ((d32 & 0xf8000000) == 0xf8000000) + { + /* got copy offset in range 0 - 63, */ + /* with 6 bit copy offset */ + d32 <<= 5; + copy_offset = d32 >> 26; + d32 <<= 6; + bits_left -= 11; + } + else if ((d32 & 0xf8000000) == 0xf0000000) + { + /* got copy offset in range 64 - 319, */ + /* with 8 bit copy offset */ + d32 <<= 5; + copy_offset = d32 >> 24; + copy_offset += 64; + d32 <<= 8; + bits_left -= 13; + } + else if ((d32 & 0xf0000000) == 0xe0000000) + { + /* got copy offset in range 320 - 2367, */ + /* with 11 bits copy offset */ + d32 <<= 4; + copy_offset = d32 >> 21; + copy_offset += 320; + d32 <<= 11; + bits_left -= 15; + } + else if ((d32 & 0xe0000000) == 0xc0000000) + { + /* got copy offset in range 2368+, */ + /* with 16 bits copy offset */ + d32 <<= 3; + copy_offset = d32 >> 16; + copy_offset += 2368; + d32 <<= 16; + bits_left -= 19; + } + + /* + ** get more bits before we process length of match + */ + + /* how may bits do we need to get? */ + tmp = 32 - bits_left; + + while (tmp) + { + if (cur_bits_left < tmp) + { + /* we have less bits than we need */ + i32 = cur_byte >> (8 - cur_bits_left); + d32 |= i32 << ((32 - bits_left) - cur_bits_left); + bits_left += cur_bits_left; + tmp -= cur_bits_left; + if (cptr < cbuf + len) + { + /* more compressed data available */ + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + /* no more compressed data available */ + tmp = 0; + cur_bits_left = 0; + } + } + else if (cur_bits_left > tmp) + { + /* we have more bits than we need */ + d32 |= cur_byte >> (8 - tmp); + cur_byte <<= tmp; + cur_bits_left -= tmp; + bits_left = 32; + break; + } + else + { + /* we have just the right amount of bits */ + d32 |= cur_byte >> (8 - tmp); + bits_left = 32; + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + break; + } + } + + if (!copy_offset) + { + continue; + } + + /* + ** compute Length of Match + */ + + /* + lengh of match Encoding (binary header + LoM bits + -------------- ---------------------------------- + 3 0 + 4..7 10 + 2 lower bits of LoM + 8..15 110 + 3 lower bits of LoM + 16..31 1110 + 4 lower bits of LoM + 32..63 1111-0 + 5 lower bits of LoM + 64..127 1111-10 + 6 lower bits of LoM + 128..255 1111-110 + 7 lower bits of LoM + 256..511 1111-1110 + 8 lower bits of LoM + 512..1023 1111-1111-0 + 9 lower bits of LoM + 1024..2047 1111-1111-10 + 10 lower bits of LoM + 2048..4095 1111-1111-110 + 11 lower bits of LoM + 4096..8191 1111-1111-1110 + 12 lower bits of LoM + 8192..16383 1111-1111-1111-0 + 13 lower bits of LoM + 16384..32767 1111-1111-1111-10 + 14 lower bits of LoM + 32768..65535 1111-1111-1111-110 + 15 lower bits of LoM + */ + + if ((d32 & 0x80000000) == 0) + { + /* lom is fixed to 3 */ + lom = 3; + d32 <<= 1; + bits_left -= 1; + } + else if ((d32 & 0xc0000000) == 0x80000000) + { + /* 2 lower bits of LoM */ + lom = ((d32 >> 28) & 0x03) + 4; + d32 <<= 4; + bits_left -= 4; + } + else if ((d32 & 0xe0000000) == 0xc0000000) + { + /* 3 lower bits of LoM */ + lom = ((d32 >> 26) & 0x07) + 8; + d32 <<= 6; + bits_left -= 6; + } + else if ((d32 & 0xf0000000) == 0xe0000000) + { + /* 4 lower bits of LoM */ + lom = ((d32 >> 24) & 0x0f) + 16; + d32 <<= 8; + bits_left -= 8; + } + else if ((d32 & 0xf8000000) == 0xf0000000) + { + /* 5 lower bits of LoM */ + lom = ((d32 >> 22) & 0x1f) + 32; + d32 <<= 10; + bits_left -= 10; + } + else if ((d32 & 0xfc000000) == 0xf8000000) + { + /* 6 lower bits of LoM */ + lom = ((d32 >> 20) & 0x3f) + 64; + d32 <<= 12; + bits_left -= 12; + } + else if ((d32 & 0xfe000000) == 0xfc000000) + { + /* 7 lower bits of LoM */ + lom = ((d32 >> 18) & 0x7f) + 128; + d32 <<= 14; + bits_left -= 14; + } + else if ((d32 & 0xff000000) == 0xfe000000) + { + /* 8 lower bits of LoM */ + lom = ((d32 >> 16) & 0xff) + 256; + d32 <<= 16; + bits_left -= 16; + } + else if ((d32 & 0xff800000) == 0xff000000) + { + /* 9 lower bits of LoM */ + lom = ((d32 >> 14) & 0x1ff) + 512; + d32 <<= 18; + bits_left -= 18; + } + else if ((d32 & 0xffc00000) == 0xff800000) + { + /* 10 lower bits of LoM */ + lom = ((d32 >> 12) & 0x3ff) + 1024; + d32 <<= 20; + bits_left -= 20; + } + else if ((d32 & 0xffe00000) == 0xffc00000) + { + /* 11 lower bits of LoM */ + lom = ((d32 >> 10) & 0x7ff) + 2048; + d32 <<= 22; + bits_left -= 22; + } + else if ((d32 & 0xfff00000) == 0xffe00000) + { + /* 12 lower bits of LoM */ + lom = ((d32 >> 8) & 0xfff) + 4096; + d32 <<= 24; + bits_left -= 24; + } + else if ((d32 & 0xfff80000) == 0xfff00000) + { + /* 13 lower bits of LoM */ + lom = ((d32 >> 6) & 0x1fff) + 8192; + d32 <<= 26; + bits_left -= 26; + } + else if ((d32 & 0xfffc0000) == 0xfff80000) + { + /* 14 lower bits of LoM */ + lom = ((d32 >> 4) & 0x3fff) + 16384; + d32 <<= 28; + bits_left -= 28; + } + else if ((d32 & 0xfffe0000) == 0xfffc0000) + { + /* 15 lower bits of LoM */ + lom = ((d32 >> 2) & 0x7fff) + 32768; + d32 <<= 30; + bits_left -= 30; + } + + /* now that we have copy_offset and LoM, process them */ + + src_ptr = history_ptr - copy_offset; + if (src_ptr >= rdp->mppc->history_buf) + { + /* data does not wrap around */ + while (lom > 0) + { + *history_ptr++ = *src_ptr++; + lom--; + } + } + else + { + src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf)); + src_ptr++; + while (lom && (src_ptr <= rdp->mppc->history_buf_end)) + { + *history_ptr++ = *src_ptr++; + lom--; + } + + src_ptr = rdp->mppc->history_buf; + while (lom > 0) + { + *history_ptr++ = *src_ptr++; + lom--; + } + } + + /* + ** get more bits before we restart the loop + */ + + /* how may bits do we need to get? */ + tmp = 32 - bits_left; + + while (tmp) + { + if (cur_bits_left < tmp) + { + /* we have less bits than we need */ + i32 = cur_byte >> (8 - cur_bits_left); + d32 |= i32 << ((32 - bits_left) - cur_bits_left); + bits_left += cur_bits_left; + tmp -= cur_bits_left; + if (cptr < cbuf + len) + { + /* more compressed data available */ + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + /* no more compressed data available */ + tmp = 0; + cur_bits_left = 0; + } + } + else if (cur_bits_left > tmp) + { + /* we have more bits than we need */ + d32 |= cur_byte >> (8 - tmp); + cur_byte <<= tmp; + cur_bits_left -= tmp; + bits_left = 32; + break; + } + else + { + /* we have just the right amount of bits */ + d32 |= cur_byte >> (8 - tmp); + bits_left = 32; + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + break; + } + } + + } /* end while (cptr < cbuf + len) */ + + *rlen = history_ptr - rdp->mppc->history_ptr; + + rdp->mppc->history_ptr = history_ptr; + + return true; +} + +/** + * decompress RDP 6 data + * + * @param rdp per session information + * @param cbuf compressed data + * @param len length of compressed data + * @param ctype compression flags + * @param roff starting offset of uncompressed data + * @param rlen length of uncompressed data + * + * @return True on success, False on failure + */ + +int decompress_rdp_6(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen) +{ + uint8* history_buf; /* uncompressed data goes here */ + uint16* offset_cache; /* Copy Offset cache */ + uint8* history_ptr; /* points to next free slot in bistory_buf */ + uint32 d32; /* we process 4 compressed bytes at a time */ + uint16 copy_offset; /* location to copy data from */ + uint16 lom; /* length of match */ + uint8* src_ptr; /* used while copying compressed data */ + uint8* cptr; /* points to next byte in cbuf */ + uint8 cur_byte; /* last byte fetched from cbuf */ + int bits_left; /* bits left in d32 for processing */ + int cur_bits_left; /* bits left in cur_byte for processing */ + int tmp; + uint32 i32; + + if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL)) + { + printf("decompress_rdp_6: null\n"); + return false; + } + + src_ptr = 0; + cptr = cbuf; + copy_offset = 0; + lom = 0; + bits_left = 0; + cur_bits_left = 0; + d32 = 0; + cur_byte = 0; + *rlen = 0; + + /* get start of history buffer */ + history_buf = rdp->mppc->history_buf; + + /* get start of offset_cache */ + offset_cache = rdp->mppc->offset_cache; + + /* get next free slot in history buffer */ + history_ptr = rdp->mppc->history_ptr; + *roff = history_ptr - history_buf; + + if (ctype & PACKET_AT_FRONT) + { + printf("need to look later\n"); + /* slid history_buf and reset history_buf to middle */ + memcpy(history_buf, (history_buf + 32768), (history_ptr -history_buf - 32768)); + memcpy((history_buf + (history_ptr - history_buf - 32768)), cbuf, len); + history_ptr = history_buf + 32768; + *roff = 32768; + } + + if (ctype & PACKET_FLUSHED) + { + /* re-init history buffer */ + history_ptr = rdp->mppc->history_buf; + memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE); + memset(offset_cache, 0, RDP6_OFFSET_CACHE_SIZE); + *roff = 0; + } + + if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED) + { + /* data in cbuf is not compressed - copy to history buf as is */ + memcpy(history_ptr, cbuf, len); + history_ptr += len; + *rlen = history_ptr - rdp->mppc->history_ptr; + rdp->mppc->history_ptr = history_ptr; + return true; + } + + /* load initial data */ + tmp = 24; + while (cptr < cbuf + len) + { + i32 = *cptr++; + d32 |= i32 << tmp; + bits_left += 8; + tmp -= 8; + if (tmp < 0) + { + break; + } + } + + if (cptr < cbuf + len) + { + cur_byte = *cptr++; + cur_bits_left = 8; + } + else + { + cur_bits_left = 0; + } + + /* + ** start uncompressing data in cbuf + */ + + + return true; +} + +/** + * decompress RDP 6.1 data + * + * @param rdp per session information + * @param cbuf compressed data + * @param len length of compressed data + * @param ctype compression flags + * @param roff starting offset of uncompressed data + * @param rlen length of uncompressed data + * + * @return True on success, False on failure + */ + +int decompress_rdp_61(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen) +{ + return false; +} + +/** + * allocate space to store history buffer + * + * @param rdp rdp struct that contains rdp_mppc struct + * @return pointer to new struct, or NULL on failure + */ + +struct rdp_mppc* mppc_new(rdpRdp* rdp) +{ + struct rdp_mppc* ptr; + + ptr = (struct rdp_mppc*) xmalloc(sizeof(struct rdp_mppc)); + + if (!ptr) + { + printf("mppc_new(): system out of memory\n"); + return NULL; + } + + ptr->history_buf = (uint8*) xmalloc(RDP6_HISTORY_BUF_SIZE); + ptr->offset_cache = (uint16*) xzalloc(RDP6_OFFSET_CACHE_SIZE); + + if (!ptr->history_buf) + { + printf("mppc_new(): system out of memory\n"); + xfree(ptr); + return NULL; + } + + ptr->history_ptr = ptr->history_buf; + ptr->history_buf_end = ptr->history_buf + RDP6_HISTORY_BUF_SIZE - 1; + + return ptr; +} + +/** + * free history buffer + * + * @param rdp rdp struct that contains rdp_mppc struct + */ + +void mppc_free(rdpRdp* rdp) +{ + if (!rdp->mppc) + { + return; + } + + if (rdp->mppc->history_buf) + { + xfree(rdp->mppc->history_buf); + rdp->mppc->history_buf = NULL; + rdp->mppc->history_ptr = NULL; + } + + if (rdp->mppc->offset_cache) + { + xfree(rdp->mppc->offset_cache); + } + + xfree(rdp->mppc); +} diff --git a/libfreerdp-core/mppc.h b/libfreerdp-core/mppc.h new file mode 100644 index 0000000..c3d00fa --- /dev/null +++ b/libfreerdp-core/mppc.h @@ -0,0 +1,45 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Implements Microsoft Point to Point Compression (MPPC) protocol + * + * Copyright 2011 Laxmikant Rashinkar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPPC_H +#define __MPPC_H + +#include + +#define RDP6_HISTORY_BUF_SIZE 65536 +#define RDP6_OFFSET_CACHE_SIZE 4 + +struct rdp_mppc +{ + uint8 *history_buf; + uint16 *offset_cache; + uint8 *history_buf_end; + uint8 *history_ptr; +}; + +// forward declarations +int decompress_rdp(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *); +int decompress_rdp_4(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *); +int decompress_rdp_5(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *); +int decompress_rdp_6(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *); +int decompress_rdp_61(rdpRdp *, uint8 *, int, int, uint32 *, uint32 *); +struct rdp_mppc *mppc_new(rdpRdp *rdp); +void mppc_free(rdpRdp *rdp); + +#endif diff --git a/libfreerdp-core/nego.c b/libfreerdp-core/nego.c new file mode 100644 index 0000000..7eb810b --- /dev/null +++ b/libfreerdp-core/nego.c @@ -0,0 +1,720 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Protocol Security Negotiation + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include "tpkt.h" + +#include "nego.h" + +static const char* const NEGO_STATE_STRINGS[] = +{ + "NEGO_STATE_INITIAL", + "NEGO_STATE_NLA", + "NEGO_STATE_TLS", + "NEGO_STATE_RDP", + "NEGO_STATE_FAIL", + "NEGO_STATE_FINAL" +}; + +static const char PROTOCOL_SECURITY_STRINGS[3][4] = +{ + "RDP", + "TLS", + "NLA" +}; + +/** + * Negotiate protocol security and connect. + * @param nego + * @return + */ + +boolean nego_connect(rdpNego* nego) +{ + if (nego->state == NEGO_STATE_INITIAL) + { + if (nego->enabled_protocols[PROTOCOL_NLA] > 0) + nego->state = NEGO_STATE_NLA; + else if (nego->enabled_protocols[PROTOCOL_TLS] > 0) + nego->state = NEGO_STATE_TLS; + else if (nego->enabled_protocols[PROTOCOL_RDP] > 0) + nego->state = NEGO_STATE_RDP; + else + nego->state = NEGO_STATE_FAIL; + } + + do + { + DEBUG_NEGO("state: %s", NEGO_STATE_STRINGS[nego->state]); + + nego_send(nego); + + if (nego->state == NEGO_STATE_FAIL) + { + DEBUG_NEGO("Protocol Security Negotiation Failure"); + nego->state = NEGO_STATE_FINAL; + return false; + } + } + while (nego->state != NEGO_STATE_FINAL); + + DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]); + + /* update settings with negotiated protocol security */ + nego->transport->settings->requested_protocols = nego->requested_protocols; + nego->transport->settings->selected_protocol = nego->selected_protocol; + nego->transport->settings->negotiationFlags = nego->flags; + + if(nego->selected_protocol == PROTOCOL_RDP) + { + nego->transport->settings->encryption = true; + nego->transport->settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + nego->transport->settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + } + + return true; +} + +/** + * Connect TCP layer. + * @param nego + * @return + */ + +boolean nego_tcp_connect(rdpNego* nego) +{ + if (nego->tcp_connected == 0) + { + if (transport_connect(nego->transport, nego->hostname, nego->port) == false) + { + nego->tcp_connected = 0; + return false; + } + else + { + nego->tcp_connected = 1; + return true; + } + } + + return true; +} + +/** + * Disconnect TCP layer. + * @param nego + * @return + */ + +int nego_tcp_disconnect(rdpNego* nego) +{ + if (nego->tcp_connected) + transport_disconnect(nego->transport); + + nego->tcp_connected = 0; + return 1; +} + +/** + * Attempt negotiating NLA + TLS security. + * @param nego + */ + +void nego_attempt_nla(rdpNego* nego) +{ + nego->requested_protocols = PROTOCOL_NLA | PROTOCOL_TLS; + + DEBUG_NEGO("Attempting NLA security"); + + if (!nego_tcp_connect(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_send_negotiation_request(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_recv_response(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (nego->state != NEGO_STATE_FINAL) + { + nego_tcp_disconnect(nego); + + if (nego->enabled_protocols[PROTOCOL_TLS] > 0) + nego->state = NEGO_STATE_TLS; + else if (nego->enabled_protocols[PROTOCOL_RDP] > 0) + nego->state = NEGO_STATE_RDP; + else + nego->state = NEGO_STATE_FAIL; + } +} + +/** + * Attempt negotiating TLS security. + * @param nego + */ + +void nego_attempt_tls(rdpNego* nego) +{ + nego->requested_protocols = PROTOCOL_TLS; + + DEBUG_NEGO("Attempting TLS security"); + + if (!nego_tcp_connect(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_send_negotiation_request(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_recv_response(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (nego->state != NEGO_STATE_FINAL) + { + nego_tcp_disconnect(nego); + + if (nego->enabled_protocols[PROTOCOL_RDP] > 0) + nego->state = NEGO_STATE_RDP; + else + nego->state = NEGO_STATE_FAIL; + } +} + +/** + * Attempt negotiating standard RDP security. + * @param nego + */ + +void nego_attempt_rdp(rdpNego* nego) +{ + nego->requested_protocols = PROTOCOL_RDP; + + DEBUG_NEGO("Attempting RDP security"); + + if (!nego_tcp_connect(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_send_negotiation_request(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } + + if (!nego_recv_response(nego)) + { + nego->state = NEGO_STATE_FAIL; + return; + } +} + +/** + * Wait to receive a negotiation response + * @param nego + */ + +boolean nego_recv_response(rdpNego* nego) +{ + STREAM* s = transport_recv_stream_init(nego->transport, 1024); + if (transport_read(nego->transport, s) < 0) + return false; + return nego_recv(nego->transport, s, nego->transport->recv_extra); +} + +/** + * Receive protocol security negotiation message.\n + * @msdn{cc240501} + * @param transport transport + * @param s stream + * @param extra nego pointer + */ + +boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra) +{ + uint8 li; + uint8 type; + rdpNego* nego = (rdpNego*) extra; + + if (tpkt_read_header(s) == 0) + return false; + + li = tpdu_read_connection_confirm(s); + + if (li > 6) + { + /* rdpNegData (optional) */ + + stream_read_uint8(s, type); /* Type */ + + switch (type) + { + case TYPE_RDP_NEG_RSP: + nego_process_negotiation_response(nego, s); + break; + + case TYPE_RDP_NEG_FAILURE: + nego_process_negotiation_failure(nego, s); + break; + } + } + else + { + nego->state = NEGO_STATE_FINAL; + } + + return true; +} + +/** + * Read protocol security negotiation request message.\n + * @param nego + * @param s stream + */ + +boolean nego_read_request(rdpNego* nego, STREAM* s) +{ + uint8 li; + uint8 c; + uint8 type; + + tpkt_read_header(s); + li = tpdu_read_connection_request(s); + if (li != stream_get_left(s) + 6) + { + printf("Incorrect TPDU length indicator.\n"); + return false; + } + + if (stream_get_left(s) > 8) + { + /* Optional routingToken or cookie, ending with CR+LF */ + while (stream_get_left(s) > 0) + { + stream_read_uint8(s, c); + if (c != '\x0D') + continue; + stream_peek_uint8(s, c); + if (c != '\x0A') + continue; + + stream_seek_uint8(s); + break; + } + } + + if (stream_get_left(s) >= 8) + { + /* rdpNegData (optional) */ + + stream_read_uint8(s, type); /* Type */ + if (type != TYPE_RDP_NEG_REQ) + { + printf("Incorrect negotiation request type %d\n", type); + return false; + } + + nego_process_negotiation_request(nego, s); + } + + return true; +} + +/** + * Send protocol security negotiation message. + * @param nego + */ + +void nego_send(rdpNego* nego) +{ + if (nego->state == NEGO_STATE_NLA) + nego_attempt_nla(nego); + else if (nego->state == NEGO_STATE_TLS) + nego_attempt_tls(nego); + else if (nego->state == NEGO_STATE_RDP) + nego_attempt_rdp(nego); + else + DEBUG_NEGO("invalid negotiation state for sending"); +} + +/** + * Send RDP Negotiation Request (RDP_NEG_REQ).\n + * @msdn{cc240500}\n + * @msdn{cc240470} + * @param nego + */ + +boolean nego_send_negotiation_request(rdpNego* nego) +{ + STREAM* s; + int length; + uint8 *bm, *em; + + s = transport_send_stream_init(nego->transport, 256); + length = TPDU_CONNECTION_REQUEST_LENGTH; + stream_get_mark(s, bm); + stream_seek(s, length); + + if (nego->routing_token != NULL) + { + stream_write(s, nego->routing_token->data, nego->routing_token->length); + length += nego->routing_token->length; + } + else if (nego->cookie != NULL) + { + int cookie_length = strlen(nego->cookie); + stream_write(s, "Cookie: mstshash=", 17); + stream_write(s, (uint8*)nego->cookie, cookie_length); + stream_write_uint8(s, 0x0D); /* CR */ + stream_write_uint8(s, 0x0A); /* LF */ + length += cookie_length + 19; + } + + if (nego->requested_protocols > PROTOCOL_RDP) + { + /* RDP_NEG_DATA must be present for TLS and NLA */ + stream_write_uint8(s, TYPE_RDP_NEG_REQ); + stream_write_uint8(s, 0); /* flags, must be set to zero */ + stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ + stream_write_uint32(s, nego->requested_protocols); /* requestedProtocols */ + length += 8; + } + + stream_get_mark(s, em); + stream_set_mark(s, bm); + tpkt_write_header(s, length); + tpdu_write_connection_request(s, length - 5); + stream_set_mark(s, em); + + if (transport_write(nego->transport, s) < 0) + return false; + + return true; +} + +/** + * Process Negotiation Request from Connection Request message. + * @param nego + * @param s + */ + +void nego_process_negotiation_request(rdpNego* nego, STREAM* s) +{ + uint8 flags; + uint16 length; + + DEBUG_NEGO("RDP_NEG_REQ"); + + stream_read_uint8(s, flags); + stream_read_uint16(s, length); + stream_read_uint32(s, nego->requested_protocols); + + nego->state = NEGO_STATE_FINAL; +} + +/** + * Process Negotiation Response from Connection Confirm message. + * @param nego + * @param s + */ + +void nego_process_negotiation_response(rdpNego* nego, STREAM* s) +{ + uint16 length; + + DEBUG_NEGO("RDP_NEG_RSP"); + + stream_read_uint8(s, nego->flags); + stream_read_uint16(s, length); + stream_read_uint32(s, nego->selected_protocol); + + nego->state = NEGO_STATE_FINAL; +} + +/** + * Process Negotiation Failure from Connection Confirm message. + * @param nego + * @param s + */ + +void nego_process_negotiation_failure(rdpNego* nego, STREAM* s) +{ + uint8 flags; + uint16 length; + uint32 failureCode; + + DEBUG_NEGO("RDP_NEG_FAILURE"); + + stream_read_uint8(s, flags); + stream_read_uint16(s, length); + stream_read_uint32(s, failureCode); + + switch (failureCode) + { + case SSL_REQUIRED_BY_SERVER: + DEBUG_NEGO("Error: SSL_REQUIRED_BY_SERVER"); + break; + case SSL_NOT_ALLOWED_BY_SERVER: + DEBUG_NEGO("Error: SSL_NOT_ALLOWED_BY_SERVER"); + break; + case SSL_CERT_NOT_ON_SERVER: + DEBUG_NEGO("Error: SSL_CERT_NOT_ON_SERVER"); + break; + case INCONSISTENT_FLAGS: + DEBUG_NEGO("Error: INCONSISTENT_FLAGS"); + break; + case HYBRID_REQUIRED_BY_SERVER: + DEBUG_NEGO("Error: HYBRID_REQUIRED_BY_SERVER"); + break; + default: + DEBUG_NEGO("Error: Unknown protocol security error %d", failureCode); + break; + } + + nego->state = NEGO_STATE_FAIL; +} + +/** + * Send RDP Negotiation Response (RDP_NEG_RSP).\n + * @param nego + */ + +boolean nego_send_negotiation_response(rdpNego* nego) +{ + STREAM* s; + rdpSettings* settings; + int length; + uint8 *bm, *em; + boolean ret; + + ret = true; + settings = nego->transport->settings; + + s = transport_send_stream_init(nego->transport, 256); + length = TPDU_CONNECTION_CONFIRM_LENGTH; + stream_get_mark(s, bm); + stream_seek(s, length); + + if (nego->selected_protocol > PROTOCOL_RDP) + { + /* RDP_NEG_DATA must be present for TLS and NLA */ + stream_write_uint8(s, TYPE_RDP_NEG_RSP); + stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ + stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ + stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */ + length += 8; + } + else if (!settings->rdp_security) + { + stream_write_uint8(s, TYPE_RDP_NEG_FAILURE); + stream_write_uint8(s, 0); /* flags */ + stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ + /* + * TODO: Check for other possibilities, + * like SSL_NOT_ALLOWED_BY_SERVER. + */ + printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); + stream_write_uint32(s, SSL_REQUIRED_BY_SERVER); + length += 8; + ret = false; + } + + stream_get_mark(s, em); + stream_set_mark(s, bm); + tpkt_write_header(s, length); + tpdu_write_connection_confirm(s, length - 5); + stream_set_mark(s, em); + + if (transport_write(nego->transport, s) < 0) + return false; + + if (ret) + { + /* update settings with negotiated protocol security */ + settings->requested_protocols = nego->requested_protocols; + settings->selected_protocol = nego->selected_protocol; + + if (settings->selected_protocol == PROTOCOL_RDP) + { + settings->tls_security = false; + settings->nla_security = false; + settings->rdp_security = true; + settings->encryption = true; + settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + } + else if (settings->selected_protocol == PROTOCOL_TLS) + { + settings->tls_security = true; + settings->nla_security = false; + settings->rdp_security = false; + settings->encryption = false; + settings->encryption_method = ENCRYPTION_METHOD_NONE; + settings->encryption_level = ENCRYPTION_LEVEL_NONE; + } + else if (settings->selected_protocol == PROTOCOL_NLA) + { + settings->tls_security = true; + settings->nla_security = true; + settings->rdp_security = false; + settings->encryption = false; + settings->encryption_method = ENCRYPTION_METHOD_NONE; + settings->encryption_level = ENCRYPTION_LEVEL_NONE; + } + } + + return ret; +} + +/** + * Initialize NEGO state machine. + * @param nego + */ + +void nego_init(rdpNego* nego) +{ + nego->state = NEGO_STATE_INITIAL; + nego->requested_protocols = PROTOCOL_RDP; + nego->transport->recv_callback = nego_recv; + nego->transport->recv_extra = (void*) nego; + nego->flags = 0; +} + +/** + * Create a new NEGO state machine instance. + * @param transport + * @return + */ + +rdpNego* nego_new(struct rdp_transport * transport) +{ + rdpNego* nego = (rdpNego*) xzalloc(sizeof(rdpNego)); + + if (nego != NULL) + { + nego->transport = transport; + nego_init(nego); + } + + return nego; +} + +/** + * Free NEGO state machine. + * @param nego + */ + +void nego_free(rdpNego* nego) +{ + xfree(nego); +} + +/** + * Set target hostname and port. + * @param nego + * @param hostname + * @param port + */ + +void nego_set_target(rdpNego* nego, char* hostname, int port) +{ + nego->hostname = hostname; + nego->port = port; +} + +/** + * Enable RDP security protocol. + * @param nego pointer to the negotiation structure + * @param enable_rdp whether to enable normal RDP protocol (true for enabled, false for disabled) + */ + +void nego_enable_rdp(rdpNego* nego, boolean enable_rdp) +{ + DEBUG_NEGO("Enabling RDP security: %s", enable_rdp ? "true" : "false"); + nego->enabled_protocols[PROTOCOL_RDP] = enable_rdp; +} + +/** + * Enable TLS security protocol. + * @param nego pointer to the negotiation structure + * @param enable_tls whether to enable TLS + RDP protocol (true for enabled, false for disabled) + */ +void nego_enable_tls(rdpNego* nego, boolean enable_tls) +{ + DEBUG_NEGO("Enabling TLS security: %s", enable_tls ? "true" : "false"); + nego->enabled_protocols[PROTOCOL_TLS] = enable_tls; +} + + +/** + * Enable NLA security protocol. + * @param nego pointer to the negotiation structure + * @param enable_nla whether to enable network level authentication protocol (true for enabled, false for disabled) + */ + +void nego_enable_nla(rdpNego* nego, boolean enable_nla) +{ + DEBUG_NEGO("Enabling NLA security: %s", enable_nla ? "true" : "false"); + nego->enabled_protocols[PROTOCOL_NLA] = enable_nla; +} + +/** + * Set routing token. + * @param nego + * @param routing_token + */ + +void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token) +{ + nego->routing_token = routing_token; +} + +/** + * Set cookie. + * @param nego + * @param cookie + */ + +void nego_set_cookie(rdpNego* nego, char* cookie) +{ + nego->cookie = cookie; +} diff --git a/libfreerdp-core/nego.h b/libfreerdp-core/nego.h new file mode 100644 index 0000000..800b3b4 --- /dev/null +++ b/libfreerdp-core/nego.h @@ -0,0 +1,120 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Protocol Security Negotiation + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NEGO_H +#define __NEGO_H + +#include "transport.h" +#include +#include +#include +#include +#include + +/* Protocol Security Negotiation Protocols */ +enum RDP_NEG_PROTOCOLS +{ + PROTOCOL_RDP = 0x00000000, + PROTOCOL_TLS = 0x00000001, + PROTOCOL_NLA = 0x00000002 +}; + +/* Protocol Security Negotiation Failure Codes */ +enum RDP_NEG_FAILURE_FAILURECODES +{ + SSL_REQUIRED_BY_SERVER = 0x00000001, + SSL_NOT_ALLOWED_BY_SERVER = 0x00000002, + SSL_CERT_NOT_ON_SERVER = 0x00000003, + INCONSISTENT_FLAGS = 0x00000004, + HYBRID_REQUIRED_BY_SERVER = 0x00000005 +}; + +enum _NEGO_STATE +{ + NEGO_STATE_INITIAL, + NEGO_STATE_NLA, /* Network Level Authentication (TLS implicit) */ + NEGO_STATE_TLS, /* TLS Encryption without NLA */ + NEGO_STATE_RDP, /* Standard Legacy RDP Encryption */ + NEGO_STATE_FAIL, /* Negotiation failure */ + NEGO_STATE_FINAL +}; +typedef enum _NEGO_STATE NEGO_STATE; + +/* RDP Negotiation Messages */ +enum RDP_NEG_MSG +{ + /* X224_TPDU_CONNECTION_REQUEST */ + TYPE_RDP_NEG_REQ = 0x1, + /* X224_TPDU_CONNECTION_CONFIRM */ + TYPE_RDP_NEG_RSP = 0x2, + TYPE_RDP_NEG_FAILURE = 0x3 +}; + +#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 + +struct rdp_nego +{ + int port; + uint32 flags; + char* hostname; + char* cookie; + NEGO_STATE state; + int tcp_connected; + rdpBlob* routing_token; + uint32 selected_protocol; + uint32 requested_protocols; + uint8 enabled_protocols[3]; + rdpTransport* transport; +}; +typedef struct rdp_nego rdpNego; + +boolean nego_connect(rdpNego* nego); + +void nego_attempt_nla(rdpNego* nego); +void nego_attempt_tls(rdpNego* nego); +void nego_attempt_rdp(rdpNego* nego); + +void nego_send(rdpNego* nego); +boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra); +boolean nego_recv_response(rdpNego* nego); +boolean nego_read_request(rdpNego* nego, STREAM* s); + +boolean nego_send_negotiation_request(rdpNego* nego); +void nego_process_negotiation_request(rdpNego* nego, STREAM* s); +void nego_process_negotiation_response(rdpNego* nego, STREAM* s); +void nego_process_negotiation_failure(rdpNego* nego, STREAM* s); +boolean nego_send_negotiation_response(rdpNego* nego); + +rdpNego* nego_new(struct rdp_transport * transport); +void nego_free(rdpNego* nego); +void nego_init(rdpNego* nego); +void nego_set_target(rdpNego* nego, char* hostname, int port); +void nego_enable_rdp(rdpNego* nego, boolean enable_rdp); +void nego_enable_nla(rdpNego* nego, boolean enable_nla); +void nego_enable_tls(rdpNego* nego, boolean enable_tls); +void nego_set_routing_token(rdpNego* nego, rdpBlob* routing_token); +void nego_set_cookie(rdpNego* nego, char* cookie); + +#ifdef WITH_DEBUG_NEGO +#define DEBUG_NEGO(fmt, ...) DEBUG_CLASS(NEGO, fmt, ## __VA_ARGS__) +#else +#define DEBUG_NEGO(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __NEGO_H */ diff --git a/libfreerdp-core/ntlmssp.c b/libfreerdp-core/ntlmssp.c new file mode 100644 index 0000000..e285836 --- /dev/null +++ b/libfreerdp-core/ntlmssp.c @@ -0,0 +1,1897 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * NT LAN Manager Security Support Provider (NTLMSSP) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ntlmssp.h" + +#define NTLMSSP_NEGOTIATE_56 0x80000000 /* W (0) */ +#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 /* V (1) */ +#define NTLMSSP_NEGOTIATE_128 0x20000000 /* U (2) */ +#define NTLMSSP_RESERVED1 0x10000000 /* r1 (3) */ +#define NTLMSSP_RESERVED2 0x08000000 /* r2 (4) */ +#define NTLMSSP_RESERVED3 0x04000000 /* r3 (5) */ +#define NTLMSSP_NEGOTIATE_VERSION 0x02000000 /* T (6) */ +#define NTLMSSP_RESERVED4 0x01000000 /* r4 (7) */ +#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 /* S (8) */ +#define NTLMSSP_RESERVEDEQUEST_NON_NT_SESSION_KEY 0x00400000 /* R (9) */ +#define NTLMSSP_RESERVED5 0x00200000 /* r5 (10) */ +#define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 /* Q (11) */ +#define NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY 0x00080000 /* P (12) */ +#define NTLMSSP_RESERVED6 0x00040000 /* r6 (13) */ +#define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 /* O (14) */ +#define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 /* N (15) */ +#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 /* M (16) */ +#define NTLMSSP_RESERVED7 0x00004000 /* r7 (17) */ +#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000 /* L (18) */ +#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000 /* K (19) */ +#define NTLMSSP_NEGOTIATE_ANONYMOUS 0x00000800 /* J (20) */ +#define NTLMSSP_RESERVED8 0x00000400 /* r8 (21) */ +#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 /* H (22) */ +#define NTLMSSP_RESERVED9 0x00000100 /* r9 (23) */ +#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 /* G (24) */ +#define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 /* F (25) */ +#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 /* E (26) */ +#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 /* D (27) */ +#define NTLMSSP_RESERVED10 0x00000008 /* r10 (28) */ +#define NTLMSSP_REQUEST_TARGET 0x00000004 /* C (29) */ +#define NTLMSSP_NEGOTIATE_OEM 0x00000002 /* B (30) */ +#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 /* A (31) */ + +#define WINDOWS_MAJOR_VERSION_5 0x05 +#define WINDOWS_MAJOR_VERSION_6 0x06 +#define WINDOWS_MINOR_VERSION_0 0x00 +#define WINDOWS_MINOR_VERSION_1 0x01 +#define WINDOWS_MINOR_VERSION_2 0x02 +#define NTLMSSP_REVISION_W2K3 0x0F + +static const char ntlm_signature[] = "NTLMSSP"; +static const char lm_magic[] = "KGS!@#$%"; + +static const char client_sign_magic[] = "session key to client-to-server signing key magic constant"; +static const char server_sign_magic[] = "session key to server-to-client signing key magic constant"; +static const char client_seal_magic[] = "session key to client-to-server sealing key magic constant"; +static const char server_seal_magic[] = "session key to server-to-client sealing key magic constant"; + +static const char* const NTLMSSP_NEGOTIATE_STRINGS[] = +{ + "NTLMSSP_NEGOTIATE_56", + "NTLMSSP_NEGOTIATE_KEY_EXCH", + "NTLMSSP_NEGOTIATE_128", + "NTLMSSP_RESERVED1", + "NTLMSSP_RESERVED2", + "NTLMSSP_RESERVED3", + "NTLMSSP_NEGOTIATE_VERSION", + "NTLMSSP_RESERVED4", + "NTLMSSP_NEGOTIATE_TARGET_INFO", + "NTLMSSP_REQUEST_NON_NT_SESSION_KEY", + "NTLMSSP_RESERVED5", + "NTLMSSP_NEGOTIATE_IDENTIFY", + "NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY", + "NTLMSSP_RESERVED6", + "NTLMSSP_TARGET_TYPE_SERVER", + "NTLMSSP_TARGET_TYPE_DOMAIN", + "NTLMSSP_NEGOTIATE_ALWAYS_SIGN", + "NTLMSSP_RESERVED7", + "NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED", + "NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED", + "NTLMSSP_NEGOTIATE_ANONYMOUS", + "NTLMSSP_RESERVED8", + "NTLMSSP_NEGOTIATE_NTLM", + "NTLMSSP_RESERVED9", + "NTLMSSP_NEGOTIATE_LM_KEY", + "NTLMSSP_NEGOTIATE_DATAGRAM", + "NTLMSSP_NEGOTIATE_SEAL", + "NTLMSSP_NEGOTIATE_SIGN", + "NTLMSSP_RESERVED10", + "NTLMSSP_REQUEST_TARGET", + "NTLMSSP_NEGOTIATE_OEM", + "NTLMSSP_NEGOTIATE_UNICODE" +}; + +static const char* const AV_PAIRS_STRINGS[] = +{ + "MsvAvEOL", + "MsvAvNbComputerName", + "MsvAvNbDomainName", + "MsvAvDnsComputerName", + "MsvAvDnsDomainName", + "MsvAvDnsTreeName", + "MsvAvFlags", + "MsvAvTimestamp", + "MsvAvRestrictions", + "MsvAvTargetName", + "MsvChannelBindings" +}; + +/** + * Set NTLMSSP username. + * @param ntlmssp + * @param username username + */ + +void ntlmssp_set_username(NTLMSSP* ntlmssp, char* username) +{ + freerdp_blob_free(&ntlmssp->username); + + if (username != NULL) + { + ntlmssp->username.data = freerdp_uniconv_out(ntlmssp->uniconv, username, (size_t*) &(ntlmssp->username.length)); + } +} + +/** + * Set NTLMSSP domain name. + * @param ntlmssp + * @param domain domain name + */ + +void ntlmssp_set_domain(NTLMSSP* ntlmssp, char* domain) +{ + freerdp_blob_free(&ntlmssp->domain); + + if (domain != NULL) + { + ntlmssp->domain.data = freerdp_uniconv_out(ntlmssp->uniconv, domain, (size_t*) &(ntlmssp->domain.length)); + } +} + +/** + * Set NTLMSSP password. + * @param ntlmssp + * @param password password + */ + +void ntlmssp_set_password(NTLMSSP* ntlmssp, char* password) +{ + freerdp_blob_free(&ntlmssp->password); + + if (password != NULL) + { + ntlmssp->password.data = freerdp_uniconv_out(ntlmssp->uniconv, password, (size_t*) &(ntlmssp->password.length)); + } +} + +/** + * Set NTLMSSP workstation. + * @param ntlmssp + * @param workstation workstation + */ + +void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation) +{ + freerdp_blob_free(&ntlmssp->workstation); + + if (workstation != NULL) + { + ntlmssp->workstation.data = freerdp_uniconv_out(ntlmssp->uniconv, workstation, (size_t*) &(ntlmssp->workstation.length)); + } +} + +/** + * Generate client challenge (8-byte nonce). + * @param ntlmssp + */ + +void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp) +{ + /* ClientChallenge in computation of LMv2 and NTLMv2 responses */ + crypto_nonce(ntlmssp->client_challenge, 8); +} + +/** + * Generate KeyExchangeKey (the 128-bit SessionBaseKey).\n + * @msdn{cc236710} + * @param ntlmssp + */ + +void ntlmssp_generate_key_exchange_key(NTLMSSP* ntlmssp) +{ + /* In NTLMv2, KeyExchangeKey is the 128-bit SessionBaseKey */ + memcpy(ntlmssp->key_exchange_key, ntlmssp->session_base_key, 16); +} + +/** + * Generate RandomSessionKey (16-byte nonce). + * @param ntlmssp + */ + +void ntlmssp_generate_random_session_key(NTLMSSP* ntlmssp) +{ + crypto_nonce(ntlmssp->random_session_key, 16); +} + +/** + * Generate ExportedSessionKey (the RandomSessionKey, exported) + * @param ntlmssp + */ + +void ntlmssp_generate_exported_session_key(NTLMSSP* ntlmssp) +{ + memcpy(ntlmssp->exported_session_key, ntlmssp->random_session_key, 16); +} + +/** + * Encrypt RandomSessionKey (RC4-encrypted RandomSessionKey, using KeyExchangeKey as the key). + * @param ntlmssp + */ + +void ntlmssp_encrypt_random_session_key(NTLMSSP* ntlmssp) +{ + /* In NTLMv2, EncryptedRandomSessionKey is the ExportedSessionKey RC4-encrypted with the KeyExchangeKey */ + credssp_rc4k(ntlmssp->key_exchange_key, 16, ntlmssp->random_session_key, ntlmssp->encrypted_random_session_key); +} + +/** + * Generate timestamp for AUTHENTICATE_MESSAGE. + * @param ntlmssp + */ + +void ntlmssp_generate_timestamp(NTLMSSP* ntlmssp) +{ + credssp_current_time(ntlmssp->timestamp); + + if (ntlmssp->ntlm_v2) + { + if (ntlmssp->av_pairs->Timestamp.length == 8) + { + memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8); + return; + } + } + else + { + if (ntlmssp->av_pairs->Timestamp.length != 8) + { + ntlmssp->av_pairs->Timestamp.length = 8; + ntlmssp->av_pairs->Timestamp.value = xmalloc(ntlmssp->av_pairs->Timestamp.length); + } + memcpy(ntlmssp->av_pairs->Timestamp.value, ntlmssp->timestamp, 8); + } +} + +/** + * Generate signing key.\n + * @msdn{cc236711} + * @param exported_session_key ExportedSessionKey + * @param sign_magic Sign magic string + * @param signing_key Destination signing key + */ + +void ntlmssp_generate_signing_key(uint8* exported_session_key, rdpBlob* sign_magic, uint8* signing_key) +{ + int length; + uint8* value; + CryptoMd5 md5; + + length = 16 + sign_magic->length; + value = (uint8*) xmalloc(length); + + /* Concatenate ExportedSessionKey with sign magic */ + memcpy(value, exported_session_key, 16); + memcpy(&value[16], sign_magic->data, sign_magic->length); + + md5 = crypto_md5_init(); + crypto_md5_update(md5, value, length); + crypto_md5_final(md5, signing_key); + + xfree(value); +} + +/** + * Generate client signing key (ClientSigningKey).\n + * @msdn{cc236711} + * @param ntlmssp + */ + +void ntlmssp_generate_client_signing_key(NTLMSSP* ntlmssp) +{ + rdpBlob sign_magic; + sign_magic.data = (void*) client_sign_magic; + sign_magic.length = sizeof(client_sign_magic); + ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->client_signing_key); +} + +/** + * Generate server signing key (ServerSigningKey).\n + * @msdn{cc236711} + * @param ntlmssp + */ + +void ntlmssp_generate_server_signing_key(NTLMSSP* ntlmssp) +{ + rdpBlob sign_magic; + sign_magic.data = (void*) server_sign_magic; + sign_magic.length = sizeof(server_sign_magic); + ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &sign_magic, ntlmssp->server_signing_key); +} + +/** + * Generate sealing key.\n + * @msdn{cc236712} + * @param exported_session_key ExportedSessionKey + * @param seal_magic Seal magic string + * @param sealing_key Destination sealing key + */ + +void ntlmssp_generate_sealing_key(uint8* exported_session_key, rdpBlob* seal_magic, uint8* sealing_key) +{ + uint8* p; + CryptoMd5 md5; + rdpBlob blob; + + freerdp_blob_alloc(&blob, 16 + seal_magic->length); + p = (uint8*) blob.data; + + /* Concatenate ExportedSessionKey with seal magic */ + memcpy(p, exported_session_key, 16); + memcpy(&p[16], seal_magic->data, seal_magic->length); + + md5 = crypto_md5_init(); + crypto_md5_update(md5, blob.data, blob.length); + crypto_md5_final(md5, sealing_key); + + freerdp_blob_free(&blob); +} + +/** + * Generate client sealing key (ClientSealingKey).\n + * @msdn{cc236712} + * @param ntlmssp + */ + +void ntlmssp_generate_client_sealing_key(NTLMSSP* ntlmssp) +{ + rdpBlob seal_magic; + seal_magic.data = (void*) client_seal_magic; + seal_magic.length = sizeof(client_seal_magic); + ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->client_sealing_key); +} + +/** + * Generate server sealing key (ServerSealingKey).\n + * @msdn{cc236712} + * @param ntlmssp + */ + +void ntlmssp_generate_server_sealing_key(NTLMSSP* ntlmssp) +{ + rdpBlob seal_magic; + seal_magic.data = (void*) server_seal_magic; + seal_magic.length = sizeof(server_seal_magic); + ntlmssp_generate_signing_key(ntlmssp->exported_session_key, &seal_magic, ntlmssp->server_sealing_key); +} + +/** + * Initialize RC4 stream cipher states for sealing. + * @param ntlmssp + */ + +void ntlmssp_init_rc4_seal_states(NTLMSSP* ntlmssp) +{ + ntlmssp->send_rc4_seal = crypto_rc4_init(ntlmssp->client_sealing_key, 16); + ntlmssp->recv_rc4_seal = crypto_rc4_init(ntlmssp->server_sealing_key, 16); +} + +/** + * Get bit from a byte buffer using a bit offset. + * @param buffer byte buffer + * @param bit bit offset + * @return bit value + */ + +static int get_bit(char* buffer, int bit) +{ + return (buffer[(bit - (bit % 8)) / 8] >> (7 - bit % 8) & 1); +} + +/** + * Set bit in a byte buffer using a bit offset. + * @param buffer byte buffer + * @param bit bit offset + * @param value bit value + */ + +static void set_bit(char* buffer, int bit, int value) +{ + buffer[(bit - (bit % 8)) / 8] |= value << (7 - bit % 8); +} + +static void ntlmssp_compute_des_key(char* text, char* des_key) +{ + int i, j; + int bit; + int nbits; + + /* Convert the 7 bytes into a bit stream, and insert a parity-bit (odd parity) after every seven bits. */ + + memset(des_key, '\0', 8); + + for (i = 0; i < 8; i++) + { + nbits = 0; + + for (j = 0; j < 7; j++) + { + /* copy 7 bits, and count the number of bits that are set */ + + bit = get_bit(text, i*7 + j); + set_bit(des_key, i*7 + i + j, bit); + nbits += bit; + } + + /* insert parity bit (odd parity) */ + + if (nbits % 2 == 0) + set_bit(des_key, i*7 + i + j, 1); + } +} + +void ntlmssp_compute_lm_hash(char* password, char* hash) +{ + int i; + int maxlen; + char text[14]; + char des_key1[8]; + char des_key2[8]; + des_key_schedule ks; + + /* LM("password") = E52CAC67419A9A224A3B108F3FA6CB6D */ + + maxlen = (strlen(password) < 14) ? strlen(password) : 14; + + /* convert to uppercase */ + for (i = 0; i < maxlen; i++) + { + if ((password[i] >= 'a') && (password[i] <= 'z')) + text[i] = password[i] - 32; + else + text[i] = password[i]; + } + + /* pad with nulls up to 14 bytes */ + for (i = maxlen; i < 14; i++) + text[i] = '\0'; + + ntlmssp_compute_des_key(text, des_key1); + ntlmssp_compute_des_key(&text[7], des_key2); + + DES_set_key((const_DES_cblock*)des_key1, &ks); + DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)hash, &ks, DES_ENCRYPT); + + DES_set_key((const_DES_cblock*)des_key2, &ks); + DES_ecb_encrypt((const_DES_cblock*) lm_magic, (DES_cblock*)&hash[8], &ks, DES_ENCRYPT); +} + +void ntlmssp_compute_ntlm_hash(rdpBlob* password, char* hash) +{ + /* NTLMv1("password") = 8846F7EAEE8FB117AD06BDD830B7586C */ + + MD4_CTX md4_ctx; + + /* Password needs to be in unicode */ + + /* Apply the MD4 digest algorithm on the password in unicode, the result is the NTLM hash */ + + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, password->data, password->length); + MD4_Final((void*) hash, &md4_ctx); +} + +void ntlmssp_compute_ntlm_v2_hash(NTLMSSP* ntlmssp, char* hash) +{ + char* p; + rdpBlob blob; + char ntlm_hash[16]; + + freerdp_blob_alloc(&blob, ntlmssp->username.length + ntlmssp->domain.length); + p = (char*) blob.data; + + /* First, compute the NTLMv1 hash of the password */ + ntlmssp_compute_ntlm_hash(&ntlmssp->password, ntlm_hash); + + /* Concatenate(Uppercase(username),domain)*/ + memcpy(p, ntlmssp->username.data, ntlmssp->username.length); + freerdp_uniconv_uppercase(ntlmssp->uniconv, p, ntlmssp->username.length / 2); + + memcpy(&p[ntlmssp->username.length], ntlmssp->domain.data, ntlmssp->domain.length); + + /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */ + HMAC(EVP_md5(), (void*) ntlm_hash, 16, blob.data, blob.length, (void*) hash, NULL); + + freerdp_blob_free(&blob); +} + +void ntlmssp_compute_lm_response(char* password, char* challenge, char* response) +{ + char hash[21]; + char des_key1[8]; + char des_key2[8]; + char des_key3[8]; + des_key_schedule ks; + + /* A LM hash is 16-bytes long, but the LM response uses a LM hash null-padded to 21 bytes */ + memset(hash, '\0', 21); + ntlmssp_compute_lm_hash(password, hash); + + /* Each 7-byte third of the 21-byte null-padded LM hash is used to create a DES key */ + ntlmssp_compute_des_key(hash, des_key1); + ntlmssp_compute_des_key(&hash[7], des_key2); + ntlmssp_compute_des_key(&hash[14], des_key3); + + /* Encrypt the LM challenge with each key, and concatenate the result. This is the LM response (24 bytes) */ + DES_set_key((const_DES_cblock*)des_key1, &ks); + DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)response, &ks, DES_ENCRYPT); + + DES_set_key((const_DES_cblock*)des_key2, &ks); + DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[8], &ks, DES_ENCRYPT); + + DES_set_key((const_DES_cblock*)des_key3, &ks); + DES_ecb_encrypt((const_DES_cblock*)challenge, (DES_cblock*)&response[16], &ks, DES_ENCRYPT); +} + +void ntlmssp_compute_lm_v2_response(NTLMSSP* ntlmssp) +{ + char *response; + char value[16]; + char ntlm_v2_hash[16]; + + /* Compute the NTLMv2 hash */ + ntlmssp_compute_ntlm_v2_hash(ntlmssp, ntlm_v2_hash); + + /* Concatenate the server and client challenges */ + memcpy(value, ntlmssp->server_challenge, 8); + memcpy(&value[8], ntlmssp->client_challenge, 8); + + freerdp_blob_alloc(&ntlmssp->lm_challenge_response, 24); + response = (char*) ntlmssp->lm_challenge_response.data; + + /* Compute the HMAC-MD5 hash of the resulting value using the NTLMv2 hash as the key */ + HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) value, 16, (void*) response, NULL); + + /* Concatenate the resulting HMAC-MD5 hash and the client challenge, giving us the LMv2 response (24 bytes) */ + memcpy(&response[16], ntlmssp->client_challenge, 8); +} + +/** + * Compute NTLMv2 Response.\n + * NTLMv2_RESPONSE @msdn{cc236653}\n + * NTLMv2 Authentication @msdn{cc236700} + * @param ntlmssp + */ + +void ntlmssp_compute_ntlm_v2_response(NTLMSSP* ntlmssp) +{ + uint8* blob; + uint8 ntlm_v2_hash[16]; + uint8 nt_proof_str[16]; + rdpBlob ntlm_v2_temp; + rdpBlob ntlm_v2_temp_chal; + + freerdp_blob_alloc(&ntlm_v2_temp, ntlmssp->target_info.length + 28); + + memset(ntlm_v2_temp.data, '\0', ntlm_v2_temp.length); + blob = (uint8*) ntlm_v2_temp.data; + + /* Compute the NTLMv2 hash */ + ntlmssp_compute_ntlm_v2_hash(ntlmssp, (char*) ntlm_v2_hash); + +#ifdef WITH_DEBUG_NLA + printf("Password (length = %d)\n", ntlmssp->password.length); + freerdp_hexdump(ntlmssp->password.data, ntlmssp->password.length); + printf("\n"); + + printf("Username (length = %d)\n", ntlmssp->username.length); + freerdp_hexdump(ntlmssp->username.data, ntlmssp->username.length); + printf("\n"); + + printf("Domain (length = %d)\n", ntlmssp->domain.length); + freerdp_hexdump(ntlmssp->domain.data, ntlmssp->domain.length); + printf("\n"); + + printf("Workstation (length = %d)\n", ntlmssp->workstation.length); + freerdp_hexdump(ntlmssp->workstation.data, ntlmssp->workstation.length); + printf("\n"); + + printf("NTOWFv2, NTLMv2 Hash\n"); + freerdp_hexdump(ntlm_v2_hash, 16); + printf("\n"); +#endif + + /* Construct temp */ + blob[0] = 1; /* RespType (1 byte) */ + blob[1] = 1; /* HighRespType (1 byte) */ + /* Reserved1 (2 bytes) */ + /* Reserved2 (4 bytes) */ + memcpy(&blob[8], ntlmssp->av_pairs->Timestamp.value, 8); /* Timestamp (8 bytes) */ + memcpy(&blob[16], ntlmssp->client_challenge, 8); /* ClientChallenge (8 bytes) */ + /* Reserved3 (4 bytes) */ + memcpy(&blob[28], ntlmssp->target_info.data, ntlmssp->target_info.length); + +#ifdef WITH_DEBUG_NLA + printf("NTLMv2 Response Temp Blob\n"); + freerdp_hexdump(ntlm_v2_temp.data, ntlm_v2_temp.length); + printf("\n"); +#endif + + /* Concatenate server challenge with temp */ + freerdp_blob_alloc(&ntlm_v2_temp_chal, ntlm_v2_temp.length + 8); + blob = (uint8*) ntlm_v2_temp_chal.data; + memcpy(blob, ntlmssp->server_challenge, 8); + memcpy(&blob[8], ntlm_v2_temp.data, ntlm_v2_temp.length); + + HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, (void*) ntlm_v2_temp_chal.data, + ntlm_v2_temp_chal.length, (void*) nt_proof_str, NULL); + + /* NtChallengeResponse, Concatenate NTProofStr with temp */ + freerdp_blob_alloc(&ntlmssp->nt_challenge_response, ntlm_v2_temp.length + 16); + blob = (uint8*) ntlmssp->nt_challenge_response.data; + memcpy(blob, nt_proof_str, 16); + memcpy(&blob[16], ntlm_v2_temp.data, ntlm_v2_temp.length); + + /* Compute SessionBaseKey, the HMAC-MD5 hash of NTProofStr using the NTLMv2 hash as the key */ + HMAC(EVP_md5(), (void*) ntlm_v2_hash, 16, + (void*) nt_proof_str, 16, (void*) ntlmssp->session_base_key, NULL); + + freerdp_blob_free(&ntlm_v2_temp); + freerdp_blob_free(&ntlm_v2_temp_chal); +} + +/** + * Input NegotiateFlags, a 4-byte bit map. + * @param s + * @param flags + */ + +void ntlmssp_input_negotiate_flags(STREAM* s, uint32* flags) +{ + *flags = 0; + stream_read_uint32(s, *flags); +} + +/** + * Output NegotiateFlags, a 4-byte bit map. + * @param s + * @param flags + */ + +void ntlmssp_output_negotiate_flags(STREAM* s, uint32 flags) +{ + stream_write_uint32(s, flags); +} + +void ntlmssp_print_negotiate_flags(uint32 flags) +{ + int i; + const char* str; + + printf("negotiateFlags \"0x%08X\"{\n", flags); + + for (i = 31; i >= 0; i--) + { + if ((flags >> i) & 1) + { + str = NTLMSSP_NEGOTIATE_STRINGS[(31 - i)]; + printf("\t%s (%d),\n", str, (31 - i)); + } + } + + printf("}\n"); +} + +/** + * Output Restriction_Encoding.\n + * Restriction_Encoding @msdn{cc236647} + * @param ntlmssp + */ + +static void ntlmssp_output_restriction_encoding(NTLMSSP* ntlmssp) +{ + AV_PAIR *restrictions = &ntlmssp->av_pairs->Restrictions; + STREAM* s = stream_new(0); + + uint8 machineID[32] = + "\x3A\x15\x8E\xA6\x75\x82\xD8\xF7\x3E\x06\xFA\x7A\xB4\xDF\xFD\x43" + "\x84\x6C\x02\x3A\xFD\x5A\x94\xFE\xCF\x97\x0F\x3D\x19\x2C\x38\x20"; + + restrictions->value = xmalloc(48); + restrictions->length = 48; + + s->data = restrictions->value; + s->size = restrictions->length; + s->p = s->data; + + stream_write_uint32(s, 48); /* Size */ + stream_write_zero(s, 4); /* Z4 (set to zero) */ + + /* IntegrityLevel (bit 31 set to 1) */ + stream_write_uint8(s, 1); + stream_write_zero(s, 3); + + stream_write_uint32(s, 0x00002000); /* SubjectIntegrityLevel */ + stream_write(s, machineID, 32); /* MachineID */ + + xfree(s); +} + +/** + * Output TargetName.\n + * @param ntlmssp + */ + +void ntlmssp_output_target_name(NTLMSSP* ntlmssp) +{ + STREAM* s = stream_new(0); + AV_PAIR* target_name = &ntlmssp->av_pairs->TargetName; + + /* + * TODO: No idea what should be set here (observed MsvAvTargetName = MsvAvDnsComputerName or + * MsvAvTargetName should be the name of the service be accessed after authentication) + * here used: "TERMSRV/192.168.0.123" in unicode (Dmitrij Jasnov) + */ + uint8 name[42] = + "\x54\x00\x45\x00\x52\x00\x4d\x00\x53\x00\x52\x00\x56\x00\x2f\x00\x31\x00\x39\x00\x32" + "\x00\x2e\x00\x31\x00\x36\x00\x38\x00\x2e\x00\x30\x00\x2e\x00\x31\x00\x32\x00\x33\x00"; + + target_name->length = 42; + target_name->value = (uint8*) xmalloc(target_name->length); + + s->data = target_name->value; + s->size = target_name->length; + s->p = s->data; + + stream_write(s, name, target_name->length); + + xfree(s); +} + +/** + * Output ChannelBindings.\n + * @param ntlmssp + */ + +void ntlmssp_output_channel_bindings(NTLMSSP* ntlmssp) +{ + STREAM* s = stream_new(0); + AV_PAIR* channel_bindings = &ntlmssp->av_pairs->ChannelBindings; + + channel_bindings->value = (uint8*) xmalloc(48); + channel_bindings->length = 16; + + s->data = channel_bindings->value; + s->size = channel_bindings->length; + s->p = s->data; + + stream_write_zero(s, 16); /* an all-zero value of the hash is used to indicate absence of channel bindings */ + + xfree(s); +} + +/** + * Populate array of AV_PAIRs.\n + * AV_PAIR @msdn{cc236646} + * @param ntlmssp + */ + +void ntlmssp_populate_av_pairs(NTLMSSP* ntlmssp) +{ + STREAM* s; + rdpBlob target_info; + AV_PAIRS *av_pairs = ntlmssp->av_pairs; + + /* MsvAvFlags */ + av_pairs->Flags = 0x00000002; /* Indicates the present of a Message Integrity Check (MIC) */ + + /* Restriction_Encoding */ + ntlmssp_output_restriction_encoding(ntlmssp); + + /* TargetName */ + ntlmssp_output_target_name(ntlmssp); + + /* ChannelBindings */ + ntlmssp_output_channel_bindings(ntlmssp); + + s = stream_new(0); + s->data = xmalloc(ntlmssp->target_info.length + 512); + s->p = s->data; + + ntlmssp_output_av_pairs(ntlmssp, s); + freerdp_blob_alloc(&target_info, s->p - s->data); + memcpy(target_info.data, s->data, target_info.length); + + ntlmssp->target_info.data = target_info.data; + ntlmssp->target_info.length = target_info.length; +} + +/** + * Input array of AV_PAIRs.\n + * AV_PAIR @msdn{cc236646} + * @param ntlmssp + * @param s + */ + +void ntlmssp_input_av_pairs(NTLMSSP* ntlmssp, STREAM* s) +{ + AV_ID AvId; + uint16 AvLen; + uint8* value; + AV_PAIRS* av_pairs = ntlmssp->av_pairs; + +#ifdef WITH_DEBUG_NLA + printf("AV_PAIRS = {\n"); +#endif + + do + { + value = NULL; + stream_read_uint16(s, AvId); + stream_read_uint16(s, AvLen); + + if (AvLen > 0) + { + if (AvId != MsvAvFlags) + { + value = xmalloc(AvLen); + stream_read(s, value, AvLen); + } + else + { + stream_read_uint32(s, av_pairs->Flags); + } + } + + switch (AvId) + { + case MsvAvNbComputerName: + av_pairs->NbComputerName.length = AvLen; + av_pairs->NbComputerName.value = value; + break; + + case MsvAvNbDomainName: + av_pairs->NbDomainName.length = AvLen; + av_pairs->NbDomainName.value = value; + break; + + case MsvAvDnsComputerName: + av_pairs->DnsComputerName.length = AvLen; + av_pairs->DnsComputerName.value = value; + break; + + case MsvAvDnsDomainName: + av_pairs->DnsDomainName.length = AvLen; + av_pairs->DnsDomainName.value = value; + break; + + case MsvAvDnsTreeName: + av_pairs->DnsTreeName.length = AvLen; + av_pairs->DnsTreeName.value = value; + break; + + case MsvAvTimestamp: + av_pairs->Timestamp.length = AvLen; + av_pairs->Timestamp.value = value; + break; + + case MsvAvRestrictions: + av_pairs->Restrictions.length = AvLen; + av_pairs->Restrictions.value = value; + break; + + case MsvAvTargetName: + av_pairs->TargetName.length = AvLen; + av_pairs->TargetName.value = value; + break; + + case MsvChannelBindings: + av_pairs->ChannelBindings.length = AvLen; + av_pairs->ChannelBindings.value = value; + break; + + default: + if (value != NULL) + xfree(value); + break; + } + +#ifdef WITH_DEBUG_NLA + if (AvId < 10) + printf("\tAvId: %s, AvLen: %d\n", AV_PAIRS_STRINGS[AvId], AvLen); + else + printf("\tAvId: %s, AvLen: %d\n", "Unknown", AvLen); + + freerdp_hexdump(value, AvLen); +#endif + } + while (AvId != MsvAvEOL); + +#ifdef WITH_DEBUG_NLA + printf("}\n"); +#endif +} + +/** + * Output array of AV_PAIRs.\n + * AV_PAIR @msdn{cc236646} + * @param ntlmssp + * @param s + */ + +void ntlmssp_output_av_pairs(NTLMSSP* ntlmssp, STREAM* s) +{ + AV_PAIRS* av_pairs = ntlmssp->av_pairs; + + if (av_pairs->NbDomainName.length > 0) + { + stream_write_uint16(s, MsvAvNbDomainName); /* AvId */ + stream_write_uint16(s, av_pairs->NbDomainName.length); /* AvLen */ + stream_write(s, av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); /* Value */ + } + + if (av_pairs->NbComputerName.length > 0) + { + stream_write_uint16(s, MsvAvNbComputerName); /* AvId */ + stream_write_uint16(s, av_pairs->NbComputerName.length); /* AvLen */ + stream_write(s, av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); /* Value */ + } + + if (av_pairs->DnsDomainName.length > 0) + { + stream_write_uint16(s, MsvAvDnsDomainName); /* AvId */ + stream_write_uint16(s, av_pairs->DnsDomainName.length); /* AvLen */ + stream_write(s, av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); /* Value */ + } + + if (av_pairs->DnsComputerName.length > 0) + { + stream_write_uint16(s, MsvAvDnsComputerName); /* AvId */ + stream_write_uint16(s, av_pairs->DnsComputerName.length); /* AvLen */ + stream_write(s, av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); /* Value */ + } + + if (av_pairs->DnsTreeName.length > 0) + { + stream_write_uint16(s, MsvAvDnsTreeName); /* AvId */ + stream_write_uint16(s, av_pairs->DnsTreeName.length); /* AvLen */ + stream_write(s, av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); /* Value */ + } + + if (av_pairs->Timestamp.length > 0) + { + stream_write_uint16(s, MsvAvTimestamp); /* AvId */ + stream_write_uint16(s, av_pairs->Timestamp.length); /* AvLen */ + stream_write(s, av_pairs->Timestamp.value, av_pairs->Timestamp.length); /* Value */ + } + + if (av_pairs->Flags > 0) + { + stream_write_uint16(s, MsvAvFlags); /* AvId */ + stream_write_uint16(s, 4); /* AvLen */ + stream_write_uint32(s, av_pairs->Flags); /* Value */ + } + + if (av_pairs->Restrictions.length > 0) + { + stream_write_uint16(s, MsvAvRestrictions); /* AvId */ + stream_write_uint16(s, av_pairs->Restrictions.length); /* AvLen */ + stream_write(s, av_pairs->Restrictions.value, av_pairs->Restrictions.length); /* Value */ + } + + if (av_pairs->ChannelBindings.length > 0) + { + stream_write_uint16(s, MsvChannelBindings); /* AvId */ + stream_write_uint16(s, av_pairs->ChannelBindings.length); /* AvLen */ + stream_write(s, av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); /* Value */ + } + + if (av_pairs->TargetName.length > 0) + { + stream_write_uint16(s, MsvAvTargetName); /* AvId */ + stream_write_uint16(s, av_pairs->TargetName.length); /* AvLen */ + stream_write(s, av_pairs->TargetName.value, av_pairs->TargetName.length); /* Value */ + } + + /* This indicates the end of the AV_PAIR array */ + stream_write_uint16(s, MsvAvEOL); /* AvId */ + stream_write_uint16(s, 0); /* AvLen */ + + if (ntlmssp->ntlm_v2) + { + stream_write_zero(s, 8); + } +} + +/** + * Print array of AV_PAIRs.\n + * AV_PAIR @msdn{cc236646} + * @param ntlmssp + * @param s + */ + +void ntlmssp_print_av_pairs(NTLMSSP* ntlmssp) +{ + AV_PAIRS* av_pairs = ntlmssp->av_pairs; + + printf("AV_PAIRS = {\n"); + + if (av_pairs->NbDomainName.length > 0) + { + printf("\tAvId: MsvAvNbDomainName AvLen: %d\n", av_pairs->NbDomainName.length); + freerdp_hexdump(av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); + } + + if (av_pairs->NbComputerName.length > 0) + { + printf("\tAvId: MsvAvNbComputerName AvLen: %d\n", av_pairs->NbComputerName.length); + freerdp_hexdump(av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); + } + + if (av_pairs->DnsDomainName.length > 0) + { + printf("\tAvId: MsvAvDnsDomainName AvLen: %d\n", av_pairs->DnsDomainName.length); + freerdp_hexdump(av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); + } + + if (av_pairs->DnsComputerName.length > 0) + { + printf("\tAvId: MsvAvDnsComputerName AvLen: %d\n", av_pairs->DnsComputerName.length); + freerdp_hexdump(av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); + } + + if (av_pairs->DnsTreeName.length > 0) + { + printf("\tAvId: MsvAvDnsTreeName AvLen: %d\n", av_pairs->DnsTreeName.length); + freerdp_hexdump(av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); + } + + if (av_pairs->Timestamp.length > 0) + { + printf("\tAvId: MsvAvTimestamp AvLen: %d\n", av_pairs->Timestamp.length); + freerdp_hexdump(av_pairs->Timestamp.value, av_pairs->Timestamp.length); + } + + if (av_pairs->Flags > 0) + { + printf("\tAvId: MsvAvFlags AvLen: %d\n", 4); + printf("0x%08X\n", av_pairs->Flags); + } + + if (av_pairs->Restrictions.length > 0) + { + printf("\tAvId: MsvAvRestrictions AvLen: %d\n", av_pairs->Restrictions.length); + freerdp_hexdump(av_pairs->Restrictions.value, av_pairs->Restrictions.length); + } + + if (av_pairs->ChannelBindings.length > 0) + { + printf("\tAvId: MsvChannelBindings AvLen: %d\n", av_pairs->ChannelBindings.length); + freerdp_hexdump(av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); + } + + if (av_pairs->TargetName.length > 0) + { + printf("\tAvId: MsvAvTargetName AvLen: %d\n", av_pairs->TargetName.length); + freerdp_hexdump(av_pairs->TargetName.value, av_pairs->TargetName.length); + } + + printf("}\n"); +} + +/** + * Free array of AV_PAIRs.\n + * AV_PAIR @msdn{cc236646} + * @param ntlmssp + */ + +void ntlmssp_free_av_pairs(NTLMSSP* ntlmssp) +{ + AV_PAIRS *av_pairs = ntlmssp->av_pairs; + + if (av_pairs != NULL) + { + if (av_pairs->NbComputerName.value != NULL) + xfree(av_pairs->NbComputerName.value); + if (av_pairs->NbDomainName.value != NULL) + xfree(av_pairs->NbDomainName.value); + if (av_pairs->DnsComputerName.value != NULL) + xfree(av_pairs->DnsComputerName.value); + if (av_pairs->DnsDomainName.value != NULL) + xfree(av_pairs->DnsDomainName.value); + if (av_pairs->DnsTreeName.value != NULL) + xfree(av_pairs->DnsTreeName.value); + if (av_pairs->Timestamp.value != NULL) + xfree(av_pairs->Timestamp.value); + if (av_pairs->Restrictions.value != NULL) + xfree(av_pairs->Restrictions.value); + if (av_pairs->TargetName.value != NULL) + xfree(av_pairs->TargetName.value); + if (av_pairs->ChannelBindings.value != NULL) + xfree(av_pairs->ChannelBindings.value); + + xfree(av_pairs); + } + + ntlmssp->av_pairs = NULL; +} + +/** + * Output VERSION structure.\n + * VERSION @msdn{cc236654} + * @param s + */ + +static void ntlmssp_output_version(STREAM* s) +{ + /* The following version information was observed with Windows 7 */ + + stream_write_uint8(s, WINDOWS_MAJOR_VERSION_6); /* ProductMajorVersion (1 byte) */ + stream_write_uint8(s, WINDOWS_MINOR_VERSION_1); /* ProductMinorVersion (1 byte) */ + stream_write_uint16(s, 7600); /* ProductBuild (2 bytes) */ + stream_write_zero(s, 3); /* Reserved (3 bytes) */ + stream_write_uint8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */ +} + +void ntlmssp_compute_message_integrity_check(NTLMSSP* ntlmssp) +{ + HMAC_CTX hmac_ctx; + + /* + * Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE, + * CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey + */ + + HMAC_CTX_init(&hmac_ctx); + HMAC_Init_ex(&hmac_ctx, ntlmssp->exported_session_key, 16, EVP_md5(), NULL); + HMAC_Update(&hmac_ctx, ntlmssp->negotiate_message.data, ntlmssp->negotiate_message.length); + HMAC_Update(&hmac_ctx, ntlmssp->challenge_message.data, ntlmssp->challenge_message.length); + HMAC_Update(&hmac_ctx, ntlmssp->authenticate_message.data, ntlmssp->authenticate_message.length); + HMAC_Final(&hmac_ctx, ntlmssp->message_integrity_check, NULL); +} + +/** + * Encrypt and sign message using NTLMSSP.\n + * GSS_WrapEx() @msdn{cc236718}\n + * EncryptMessage() @msdn{aa375378} + * @param ntlmssp + * @param[in] msg message to encrypt + * @param[out] encrypted_msg encrypted message + * @param[out] signature destination signature + */ + +void ntlmssp_encrypt_message(NTLMSSP* ntlmssp, rdpBlob* msg, rdpBlob* encrypted_msg, uint8* signature) +{ + HMAC_CTX hmac_ctx; + uint8 digest[16]; + uint8 checksum[8]; + uint32 version = 1; + + /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */ + HMAC_CTX_init(&hmac_ctx); + HMAC_Init_ex(&hmac_ctx, ntlmssp->client_signing_key, 16, EVP_md5(), NULL); + HMAC_Update(&hmac_ctx, (void*) &ntlmssp->send_seq_num, 4); + HMAC_Update(&hmac_ctx, msg->data, msg->length); + HMAC_Final(&hmac_ctx, digest, NULL); + + /* Allocate space for encrypted message */ + freerdp_blob_alloc(encrypted_msg, msg->length); + + /* Encrypt message using with RC4 */ + crypto_rc4(ntlmssp->send_rc4_seal, msg->length, msg->data, encrypted_msg->data); + + /* RC4-encrypt first 8 bytes of digest */ + crypto_rc4(ntlmssp->send_rc4_seal, 8, digest, checksum); + + /* Concatenate version, ciphertext and sequence number to build signature */ + memcpy(signature, (void*) &version, 4); + memcpy(&signature[4], (void*) checksum, 8); + memcpy(&signature[12], (void*) &(ntlmssp->send_seq_num), 4); + + HMAC_CTX_cleanup(&hmac_ctx); + + ntlmssp->send_seq_num++; +} + +/** + * Decrypt message and verify signature using NTLMSSP.\n + * GSS_UnwrapEx() @msdn{cc236703}\n + * DecryptMessage() @msdn{aa375211} + * @param ntlmssp + * @param[in] encrypted_msg encrypted message + * @param[out] msg decrypted message + * @param[in] signature signature + * @return + */ + +int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* msg, uint8* signature) +{ + HMAC_CTX hmac_ctx; + uint8 digest[16]; + uint8 checksum[8]; + uint32 version = 1; + uint8 expected_signature[16]; + + /* Allocate space for encrypted message */ + freerdp_blob_alloc(msg, encrypted_msg->length); + + /* Encrypt message using with RC4 */ + crypto_rc4(ntlmssp->recv_rc4_seal, encrypted_msg->length, encrypted_msg->data, msg->data); + + /* Compute the HMAC-MD5 hash of ConcatenationOf(seq_num,msg) using the client signing key */ + HMAC_CTX_init(&hmac_ctx); + HMAC_Init_ex(&hmac_ctx, ntlmssp->server_signing_key, 16, EVP_md5(), NULL); + HMAC_Update(&hmac_ctx, (void*) &ntlmssp->recv_seq_num, 4); + HMAC_Update(&hmac_ctx, msg->data, msg->length); + HMAC_Final(&hmac_ctx, digest, NULL); + + /* RC4-encrypt first 8 bytes of digest */ + crypto_rc4(ntlmssp->recv_rc4_seal, 8, digest, checksum); + + /* Concatenate version, ciphertext and sequence number to build signature */ + memcpy(expected_signature, (void*) &version, 4); + memcpy(&expected_signature[4], (void*) checksum, 8); + memcpy(&expected_signature[12], (void*) &(ntlmssp->recv_seq_num), 4); + + if (memcmp(signature, expected_signature, 16) != 0) + { + /* signature verification failed! */ + printf("signature verification failed, something nasty is going on!\n"); + return 0; + } + + HMAC_CTX_cleanup(&hmac_ctx); + + ntlmssp->recv_seq_num++; + return 1; +} + +/** + * Send NTLMSSP NEGOTIATE_MESSAGE.\n + * NEGOTIATE_MESSAGE @msdn{cc236641} + * @param ntlmssp + * @param s + */ + +void ntlmssp_send_negotiate_message(NTLMSSP* ntlmssp, STREAM* s) +{ + int length; + uint32 negotiateFlags = 0; + + stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */ + stream_write_uint32(s, 1); /* MessageType */ + + if (ntlmssp->ntlm_v2) + { + DEBUG_NLA("Negotiating NTLMv2"); + /* observed: B7 82 08 E2 (0xE20882B7) (Dmitrij Jasnov) */ + negotiateFlags |= NTLMSSP_NEGOTIATE_56; + negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + negotiateFlags |= NTLMSSP_NEGOTIATE_128; + negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION; + negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; + negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; + negotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY; + negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; + negotiateFlags |= NTLMSSP_REQUEST_TARGET; + negotiateFlags |= NTLMSSP_NEGOTIATE_OEM; + negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; + } + else + { + negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + negotiateFlags |= NTLMSSP_NEGOTIATE_128; + negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; + negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; + negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; + negotiateFlags |= NTLMSSP_REQUEST_TARGET; + negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; + } + + ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */ + +#ifdef WITH_DEBUG_NLA + ntlmssp_print_negotiate_flags(negotiateFlags); +#endif + + /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */ + + /* DomainNameFields (8 bytes) */ + stream_write_uint16(s, 0); /* DomainNameLen */ + stream_write_uint16(s, 0); /* DomainNameMaxLen */ + stream_write_uint32(s, 0); /* DomainNameBufferOffset */ + + /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */ + + /* WorkstationFields (8 bytes) */ + stream_write_uint16(s, 0); /* WorkstationLen */ + stream_write_uint16(s, 0); /* WorkstationMaxLen */ + stream_write_uint32(s, 0); /* WorkstationBufferOffset */ + + if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION) + { + /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */ + ntlmssp_output_version(s); + +#ifdef WITH_DEBUG_NLA + printf("Version (length = 8)\n"); + freerdp_hexdump((s->p - 8), 8); + printf("\n"); +#endif + } + + length = s->p - s->data; + freerdp_blob_alloc(&ntlmssp->negotiate_message, length); + memcpy(ntlmssp->negotiate_message.data, s->data, length); + +#ifdef WITH_DEBUG_NLA + printf("NEGOTIATE_MESSAGE (length = %d)\n", length); + freerdp_hexdump(s->data, length); + printf("\n"); +#endif + + ntlmssp->state = NTLMSSP_STATE_CHALLENGE; +} + +/** + * Receive NTLMSSP CHALLENGE_MESSAGE.\n + * CHALLENGE_MESSAGE @msdn{cc236642} + * @param ntlmssp + * @param s + */ + +void ntlmssp_recv_challenge_message(NTLMSSP* ntlmssp, STREAM* s) +{ + uint8* p; + int length; + uint8* start_offset; + uint8* payload_offset; + uint16 targetNameLen; + uint16 targetNameMaxLen; + uint32 targetNameBufferOffset; + uint16 targetInfoLen; + uint16 targetInfoMaxLen; + uint32 targetInfoBufferOffset; + + start_offset = s->p - 12; + + /* TargetNameFields (8 bytes) */ + stream_read_uint16(s, targetNameLen); /* TargetNameLen (2 bytes) */ + stream_read_uint16(s, targetNameMaxLen); /* TargetNameMaxLen (2 bytes) */ + stream_read_uint32(s, targetNameBufferOffset); /* TargetNameBufferOffset (4 bytes) */ + + ntlmssp_input_negotiate_flags(s, &(ntlmssp->negotiate_flags)); /* NegotiateFlags (4 bytes) */ + +#ifdef WITH_DEBUG_NLA + ntlmssp_print_negotiate_flags(ntlmssp->negotiate_flags); +#endif + + stream_read(s, ntlmssp->server_challenge, 8); /* ServerChallenge (8 bytes) */ + stream_seek(s, 8); /* Reserved (8 bytes), should be ignored */ + + /* TargetInfoFields (8 bytes) */ + stream_read_uint16(s, targetInfoLen); /* TargetInfoLen (2 bytes) */ + stream_read_uint16(s, targetInfoMaxLen); /* TargetInfoMaxLen (2 bytes) */ + stream_read_uint32(s, targetInfoBufferOffset); /* TargetInfoBufferOffset (4 bytes) */ + + /* only present if NTLMSSP_NEGOTIATE_VERSION is set */ + + if (ntlmssp->negotiate_flags & NTLMSSP_NEGOTIATE_VERSION) + { + stream_seek(s, 8); /* Version (8 bytes), can be ignored */ + } + + /* Payload (variable) */ + payload_offset = s->p; + + if (targetNameLen > 0) + { + p = start_offset + targetNameBufferOffset; + freerdp_blob_alloc(&ntlmssp->target_name, targetNameLen); + memcpy(ntlmssp->target_name.data, p, targetNameLen); + +#ifdef WITH_DEBUG_NLA + printf("targetName (length = %d, offset = %d)\n", targetNameLen, targetNameBufferOffset); + freerdp_hexdump(ntlmssp->target_name.data, ntlmssp->target_name.length); + printf("\n"); +#endif + } + + if (targetInfoLen > 0) + { + p = start_offset + targetInfoBufferOffset; + freerdp_blob_alloc(&ntlmssp->target_info, targetInfoLen); + memcpy(ntlmssp->target_info.data, p, targetInfoLen); + +#ifdef WITH_DEBUG_NLA + printf("targetInfo (length = %d, offset = %d)\n", targetInfoLen, targetInfoBufferOffset); + freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length); + printf("\n"); +#endif + + if (ntlmssp->ntlm_v2) + { + s->p = p; + ntlmssp_input_av_pairs(ntlmssp, s); + } + } + + length = (payload_offset - start_offset) + targetNameLen + targetInfoLen; + + freerdp_blob_alloc(&ntlmssp->challenge_message, length); + memcpy(ntlmssp->challenge_message.data, start_offset, length); + +#ifdef WITH_DEBUG_NLA + printf("CHALLENGE_MESSAGE (length = %d)\n", length); + freerdp_hexdump(start_offset, length); + printf("\n"); +#endif + + /* AV_PAIRs */ + if (ntlmssp->ntlm_v2) + ntlmssp_populate_av_pairs(ntlmssp); + + /* Timestamp */ + ntlmssp_generate_timestamp(ntlmssp); + + /* LmChallengeResponse */ + ntlmssp_compute_lm_v2_response(ntlmssp); + + if (ntlmssp->ntlm_v2) + memset(ntlmssp->lm_challenge_response.data, '\0', 24); + + /* NtChallengeResponse */ + ntlmssp_compute_ntlm_v2_response(ntlmssp); + + /* KeyExchangeKey */ + ntlmssp_generate_key_exchange_key(ntlmssp); + + /* EncryptedRandomSessionKey */ + ntlmssp_encrypt_random_session_key(ntlmssp); + + /* Generate signing keys */ + ntlmssp_generate_client_signing_key(ntlmssp); + ntlmssp_generate_server_signing_key(ntlmssp); + + /* Generate sealing keys */ + ntlmssp_generate_client_sealing_key(ntlmssp); + ntlmssp_generate_server_sealing_key(ntlmssp); + + /* Initialize RC4 seal state using client sealing key */ + ntlmssp_init_rc4_seal_states(ntlmssp); + +#ifdef WITH_DEBUG_NLA + printf("ClientChallenge\n"); + freerdp_hexdump(ntlmssp->client_challenge, 8); + printf("\n"); + + printf("ServerChallenge\n"); + freerdp_hexdump(ntlmssp->server_challenge, 8); + printf("\n"); + + printf("SessionBaseKey\n"); + freerdp_hexdump(ntlmssp->session_base_key, 16); + printf("\n"); + + printf("KeyExchangeKey\n"); + freerdp_hexdump(ntlmssp->key_exchange_key, 16); + printf("\n"); + + printf("ExportedSessionKey\n"); + freerdp_hexdump(ntlmssp->exported_session_key, 16); + printf("\n"); + + printf("RandomSessionKey\n"); + freerdp_hexdump(ntlmssp->random_session_key, 16); + printf("\n"); + + printf("ClientSignKey\n"); + freerdp_hexdump(ntlmssp->client_signing_key, 16); + printf("\n"); + + printf("ClientSealingKey\n"); + freerdp_hexdump(ntlmssp->client_sealing_key, 16); + printf("\n"); + + printf("Timestamp\n"); + freerdp_hexdump(ntlmssp->timestamp, 8); + printf("\n"); +#endif + + ntlmssp->state = NTLMSSP_STATE_AUTHENTICATE; +} + +/** + * Send NTLMSSP AUTHENTICATE_MESSAGE.\n + * AUTHENTICATE_MESSAGE @msdn{cc236643} + * @param ntlmssp + * @param s + */ + +void ntlmssp_send_authenticate_message(NTLMSSP* ntlmssp, STREAM* s) +{ + int length; + uint32 negotiateFlags = 0; + uint8* mic_offset = NULL; + + uint16 DomainNameLen; + uint16 UserNameLen; + uint16 WorkstationLen; + uint16 LmChallengeResponseLen; + uint16 NtChallengeResponseLen; + uint16 EncryptedRandomSessionKeyLen; + + uint32 PayloadBufferOffset; + uint32 DomainNameBufferOffset; + uint32 UserNameBufferOffset; + uint32 WorkstationBufferOffset; + uint32 LmChallengeResponseBufferOffset; + uint32 NtChallengeResponseBufferOffset; + uint32 EncryptedRandomSessionKeyBufferOffset; + + uint8* UserNameBuffer; + uint8* DomainNameBuffer; + uint8* WorkstationBuffer; + uint8* EncryptedRandomSessionKeyBuffer; + + WorkstationLen = ntlmssp->workstation.length; + WorkstationBuffer = ntlmssp->workstation.data; + + if (ntlmssp->ntlm_v2 < 1) + WorkstationLen = 0; + + DomainNameLen = ntlmssp->domain.length; + DomainNameBuffer = ntlmssp->domain.data; + + UserNameLen = ntlmssp->username.length; + UserNameBuffer = ntlmssp->username.data; + + LmChallengeResponseLen = ntlmssp->lm_challenge_response.length; + NtChallengeResponseLen = ntlmssp->nt_challenge_response.length; + + EncryptedRandomSessionKeyLen = 16; + EncryptedRandomSessionKeyBuffer = ntlmssp->encrypted_random_session_key; + + if (ntlmssp->ntlm_v2) + { + /* observed: 35 82 88 e2 (0xE2888235) */ + negotiateFlags |= NTLMSSP_NEGOTIATE_56; + negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + negotiateFlags |= NTLMSSP_NEGOTIATE_128; + negotiateFlags |= NTLMSSP_NEGOTIATE_VERSION; + negotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO; + negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; + negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; + negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; + negotiateFlags |= NTLMSSP_REQUEST_TARGET; + negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; + } + else + { + negotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + negotiateFlags |= NTLMSSP_NEGOTIATE_128; + negotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY; + negotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + negotiateFlags |= NTLMSSP_NEGOTIATE_NTLM; + negotiateFlags |= NTLMSSP_NEGOTIATE_SEAL; + negotiateFlags |= NTLMSSP_NEGOTIATE_SIGN; + negotiateFlags |= NTLMSSP_REQUEST_TARGET; + negotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; + } + + if (ntlmssp->ntlm_v2) + PayloadBufferOffset = 80; /* starting buffer offset */ + else + PayloadBufferOffset = 64; /* starting buffer offset */ + + if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION) + PayloadBufferOffset += 8; + + DomainNameBufferOffset = PayloadBufferOffset; + UserNameBufferOffset = DomainNameBufferOffset + DomainNameLen; + WorkstationBufferOffset = UserNameBufferOffset + UserNameLen; + LmChallengeResponseBufferOffset = WorkstationBufferOffset + WorkstationLen; + NtChallengeResponseBufferOffset = LmChallengeResponseBufferOffset + LmChallengeResponseLen; + EncryptedRandomSessionKeyBufferOffset = NtChallengeResponseBufferOffset + NtChallengeResponseLen; + + stream_write(s, ntlm_signature, 8); /* Signature (8 bytes) */ + stream_write_uint32(s, 3); /* MessageType */ + + /* LmChallengeResponseFields (8 bytes) */ + stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseLen */ + stream_write_uint16(s, LmChallengeResponseLen); /* LmChallengeResponseMaxLen */ + stream_write_uint32(s, LmChallengeResponseBufferOffset); /* LmChallengeResponseBufferOffset */ + + /* NtChallengeResponseFields (8 bytes) */ + stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseLen */ + stream_write_uint16(s, NtChallengeResponseLen); /* NtChallengeResponseMaxLen */ + stream_write_uint32(s, NtChallengeResponseBufferOffset); /* NtChallengeResponseBufferOffset */ + + /* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */ + + /* DomainNameFields (8 bytes) */ + stream_write_uint16(s, DomainNameLen); /* DomainNameLen */ + stream_write_uint16(s, DomainNameLen); /* DomainNameMaxLen */ + stream_write_uint32(s, DomainNameBufferOffset); /* DomainNameBufferOffset */ + + /* UserNameFields (8 bytes) */ + stream_write_uint16(s, UserNameLen); /* UserNameLen */ + stream_write_uint16(s, UserNameLen); /* UserNameMaxLen */ + stream_write_uint32(s, UserNameBufferOffset); /* UserNameBufferOffset */ + + /* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */ + + /* WorkstationFields (8 bytes) */ + stream_write_uint16(s, WorkstationLen); /* WorkstationLen */ + stream_write_uint16(s, WorkstationLen); /* WorkstationMaxLen */ + stream_write_uint32(s, WorkstationBufferOffset); /* WorkstationBufferOffset */ + + /* EncryptedRandomSessionKeyFields (8 bytes) */ + stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyLen */ + stream_write_uint16(s, EncryptedRandomSessionKeyLen); /* EncryptedRandomSessionKeyMaxLen */ + stream_write_uint32(s, EncryptedRandomSessionKeyBufferOffset); /* EncryptedRandomSessionKeyBufferOffset */ + + ntlmssp_output_negotiate_flags(s, negotiateFlags); /* NegotiateFlags (4 bytes) */ + +#ifdef WITH_DEBUG_NLA + ntlmssp_print_negotiate_flags(negotiateFlags); +#endif + + if (negotiateFlags & NTLMSSP_NEGOTIATE_VERSION) + { + /* Only present if NTLMSSP_NEGOTIATE_VERSION is set */ + ntlmssp_output_version(s); + +#ifdef WITH_DEBUG_NLA + printf("Version (length = 8)\n"); + freerdp_hexdump((s->p - 8), 8); + printf("\n"); +#endif + } + + if (ntlmssp->ntlm_v2) + { + /* Message Integrity Check */ + mic_offset = s->p; + stream_write_zero(s, 16); + } + + /* DomainName */ + if (DomainNameLen > 0) + { + stream_write(s, DomainNameBuffer, DomainNameLen); +#ifdef WITH_DEBUG_NLA + printf("DomainName (length = %d, offset = %d)\n", DomainNameLen, DomainNameBufferOffset); + freerdp_hexdump(DomainNameBuffer, DomainNameLen); + printf("\n"); +#endif + } + + /* UserName */ + stream_write(s, UserNameBuffer, UserNameLen); + +#ifdef WITH_DEBUG_NLA + printf("UserName (length = %d, offset = %d)\n", UserNameLen, UserNameBufferOffset); + freerdp_hexdump(UserNameBuffer, UserNameLen); + printf("\n"); +#endif + + /* Workstation */ + if (WorkstationLen > 0) + { + stream_write(s, WorkstationBuffer, WorkstationLen); +#ifdef WITH_DEBUG_NLA + printf("Workstation (length = %d, offset = %d)\n", WorkstationLen, WorkstationBufferOffset); + freerdp_hexdump(WorkstationBuffer, WorkstationLen); + printf("\n"); +#endif + } + + /* LmChallengeResponse */ + stream_write(s, ntlmssp->lm_challenge_response.data, LmChallengeResponseLen); + +#ifdef WITH_DEBUG_NLA + printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset); + freerdp_hexdump(ntlmssp->lm_challenge_response.data, LmChallengeResponseLen); + printf("\n"); +#endif + + /* NtChallengeResponse */ + stream_write(s, ntlmssp->nt_challenge_response.data, NtChallengeResponseLen); + +#ifdef WITH_DEBUG_NLA + if (ntlmssp->ntlm_v2) + { + ntlmssp_print_av_pairs(ntlmssp); + + printf("targetInfo (length = %d)\n", ntlmssp->target_info.length); + freerdp_hexdump(ntlmssp->target_info.data, ntlmssp->target_info.length); + printf("\n"); + } +#endif + +#ifdef WITH_DEBUG_NLA + printf("NtChallengeResponse (length = %d, offset = %d)\n", NtChallengeResponseLen, NtChallengeResponseBufferOffset); + freerdp_hexdump(ntlmssp->nt_challenge_response.data, NtChallengeResponseLen); + printf("\n"); +#endif + + /* EncryptedRandomSessionKey */ + stream_write(s, EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen); + +#ifdef WITH_DEBUG_NLA + printf("EncryptedRandomSessionKey (length = %d, offset = %d)\n", EncryptedRandomSessionKeyLen, EncryptedRandomSessionKeyBufferOffset); + freerdp_hexdump(EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen); + printf("\n"); +#endif + + length = s->p - s->data; + freerdp_blob_alloc(&ntlmssp->authenticate_message, length); + memcpy(ntlmssp->authenticate_message.data, s->data, length); + + if (ntlmssp->ntlm_v2) + { + /* Message Integrity Check */ + ntlmssp_compute_message_integrity_check(ntlmssp); + + s->p = mic_offset; + stream_write(s, ntlmssp->message_integrity_check, 16); + s->p = s->data + length; + +#ifdef WITH_DEBUG_NLA + printf("MessageIntegrityCheck (length = 16)\n"); + freerdp_hexdump(mic_offset, 16); + printf("\n"); +#endif + } + +#ifdef WITH_DEBUG_NLA + printf("AUTHENTICATE_MESSAGE (length = %d)\n", length); + freerdp_hexdump(s->data, length); + printf("\n"); +#endif + + ntlmssp->state = NTLMSSP_STATE_FINAL; +} + +/** + * Send NTLMSSP message. + * @param ntlmssp + * @param s + * @return + */ + +int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s) +{ + if (ntlmssp->state == NTLMSSP_STATE_INITIAL) + ntlmssp->state = NTLMSSP_STATE_NEGOTIATE; + + if (ntlmssp->state == NTLMSSP_STATE_NEGOTIATE) + ntlmssp_send_negotiate_message(ntlmssp, s); + else if (ntlmssp->state == NTLMSSP_STATE_AUTHENTICATE) + ntlmssp_send_authenticate_message(ntlmssp, s); + + return (ntlmssp->state == NTLMSSP_STATE_FINAL) ? 0 : 1; +} + +/** + * Receive NTLMSSP message. + * @param ntlmssp + * @param s + * @return + */ + +int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s) +{ + char signature[8]; /* Signature, "NTLMSSP" */ + uint32 messageType; /* MessageType */ + + stream_read(s, signature, 8); + stream_read_uint32(s, messageType); + + if (messageType == 2 && ntlmssp->state == NTLMSSP_STATE_CHALLENGE) + ntlmssp_recv_challenge_message(ntlmssp, s); + + return 1; +} + +/** + * Create new NTLMSSP state machine instance. + * @return + */ + +NTLMSSP* ntlmssp_new() +{ + NTLMSSP* ntlmssp = (NTLMSSP*) xmalloc(sizeof(NTLMSSP)); + + if (ntlmssp != NULL) + { + memset(ntlmssp, '\0', sizeof(NTLMSSP)); + ntlmssp->av_pairs = (AV_PAIRS*) xmalloc(sizeof(AV_PAIRS)); + memset(ntlmssp->av_pairs, 0, sizeof(AV_PAIRS)); + ntlmssp_init(ntlmssp); + } + + return ntlmssp; +} + +/** + * Initialize NTLMSSP state machine. + * @param ntlmssp + */ + +void ntlmssp_init(NTLMSSP* ntlmssp) +{ + ntlmssp->state = NTLMSSP_STATE_INITIAL; + ntlmssp->uniconv = freerdp_uniconv_new(); +} + +/** + * Finalize NTLMSSP state machine. + * @param ntlmssp + */ + +void ntlmssp_uninit(NTLMSSP* ntlmssp) +{ + freerdp_blob_free(&ntlmssp->username); + freerdp_blob_free(&ntlmssp->password); + freerdp_blob_free(&ntlmssp->domain); + + freerdp_blob_free(&ntlmssp->spn); + freerdp_blob_free(&ntlmssp->workstation); + freerdp_blob_free(&ntlmssp->target_info); + freerdp_blob_free(&ntlmssp->target_name); + + freerdp_blob_free(&ntlmssp->negotiate_message); + freerdp_blob_free(&ntlmssp->challenge_message); + freerdp_blob_free(&ntlmssp->authenticate_message); + + freerdp_blob_free(&ntlmssp->lm_challenge_response); + freerdp_blob_free(&ntlmssp->nt_challenge_response); + + ntlmssp_free_av_pairs(ntlmssp); + freerdp_uniconv_free(ntlmssp->uniconv); + + ntlmssp->state = NTLMSSP_STATE_FINAL; +} + +/** + * Free NTLMSSP state machine. + * @param ntlmssp + */ + +void ntlmssp_free(NTLMSSP* ntlmssp) +{ + ntlmssp_uninit(ntlmssp); + + if (ntlmssp->send_rc4_seal) + crypto_rc4_free(ntlmssp->send_rc4_seal); + if (ntlmssp->recv_rc4_seal) + crypto_rc4_free(ntlmssp->recv_rc4_seal); + xfree(ntlmssp); +} diff --git a/libfreerdp-core/ntlmssp.h b/libfreerdp-core/ntlmssp.h new file mode 100644 index 0000000..a9dce67 --- /dev/null +++ b/libfreerdp-core/ntlmssp.h @@ -0,0 +1,166 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * NT LAN Manager Security Support Provider (NTLMSSP) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NTLMSSP_H +#define __NTLMSSP_H + +#include "credssp.h" + +#include +#include +#include +#include + +struct _AV_PAIR +{ + uint16 length; + uint8* value; +}; +typedef struct _AV_PAIR AV_PAIR; + +struct _AV_PAIRS +{ + AV_PAIR NbComputerName; + AV_PAIR NbDomainName; + AV_PAIR DnsComputerName; + AV_PAIR DnsDomainName; + AV_PAIR DnsTreeName; + AV_PAIR Timestamp; + AV_PAIR Restrictions; + AV_PAIR TargetName; + AV_PAIR ChannelBindings; + uint32 Flags; +}; +typedef struct _AV_PAIRS AV_PAIRS; + +enum _AV_ID +{ + MsvAvEOL, + MsvAvNbComputerName, + MsvAvNbDomainName, + MsvAvDnsComputerName, + MsvAvDnsDomainName, + MsvAvDnsTreeName, + MsvAvFlags, + MsvAvTimestamp, + MsvAvRestrictions, + MsvAvTargetName, + MsvChannelBindings +}; +typedef enum _AV_ID AV_ID; + +enum _NTLMSSP_STATE +{ + NTLMSSP_STATE_INITIAL, + NTLMSSP_STATE_NEGOTIATE, + NTLMSSP_STATE_CHALLENGE, + NTLMSSP_STATE_AUTHENTICATE, + NTLMSSP_STATE_FINAL +}; +typedef enum _NTLMSSP_STATE NTLMSSP_STATE; + +struct _NTLMSSP +{ + NTLMSSP_STATE state; + rdpBlob password; + rdpBlob username; + rdpBlob domain; + rdpBlob workstation; + rdpBlob target_info; + rdpBlob target_name; + rdpBlob spn; + UNICONV *uniconv; + uint32 negotiate_flags; + uint8 timestamp[8]; + uint8 server_challenge[8]; + uint8 client_challenge[8]; + uint8 session_base_key[16]; + uint8 key_exchange_key[16]; + uint8 random_session_key[16]; + uint8 exported_session_key[16]; + uint8 encrypted_random_session_key[16]; + uint8 client_signing_key[16]; + uint8 client_sealing_key[16]; + uint8 server_signing_key[16]; + uint8 server_sealing_key[16]; + uint8 message_integrity_check[16]; + rdpBlob nt_challenge_response; + rdpBlob lm_challenge_response; + rdpBlob negotiate_message; + rdpBlob challenge_message; + rdpBlob authenticate_message; + CryptoRc4 send_rc4_seal; + CryptoRc4 recv_rc4_seal; + AV_PAIRS *av_pairs; + int send_seq_num; + int recv_seq_num; + int ntlm_v2; +}; +typedef struct _NTLMSSP NTLMSSP; + +void ntlmssp_set_username(NTLMSSP* ntlmssp, char* username); +void ntlmssp_set_domain(NTLMSSP* ntlmssp, char* domain); +void ntlmssp_set_password(NTLMSSP* ntlmssp, char* password); +void ntlmssp_set_workstation(NTLMSSP* ntlmssp, char* workstation); + +void ntlmssp_generate_client_challenge(NTLMSSP* ntlmssp); +void ntlmssp_generate_key_exchange_key(NTLMSSP* ntlmssp); +void ntlmssp_generate_random_session_key(NTLMSSP* ntlmssp); +void ntlmssp_generate_exported_session_key(NTLMSSP* ntlmssp); +void ntlmssp_encrypt_random_session_key(NTLMSSP* ntlmssp); + +void ntlmssp_generate_timestamp(NTLMSSP* ntlmssp); +void ntlmssp_generate_client_signing_key(NTLMSSP* ntlmssp); +void ntlmssp_generate_server_signing_key(NTLMSSP* ntlmssp); +void ntlmssp_generate_client_sealing_key(NTLMSSP* ntlmssp); +void ntlmssp_generate_server_sealing_key(NTLMSSP* ntlmssp); +void ntlmssp_init_rc4_seal_states(NTLMSSP* ntlmssp); + +void ntlmssp_compute_lm_hash(char* password, char* hash); +void ntlmssp_compute_ntlm_hash(rdpBlob* password, char* hash); +void ntlmssp_compute_ntlm_v2_hash(NTLMSSP* ntlmssp, char* hash); + +void ntlmssp_compute_lm_response(char* password, char* challenge, char* response); +void ntlmssp_compute_lm_v2_response(NTLMSSP* ntlmssp); +void ntlmssp_compute_ntlm_v2_response(NTLMSSP* ntlmssp); + +void ntlmssp_populate_av_pairs(NTLMSSP* ntlmssp); +void ntlmssp_input_av_pairs(NTLMSSP* ntlmssp, STREAM* s); +void ntlmssp_output_av_pairs(NTLMSSP* ntlmssp, STREAM* s); +void ntlmssp_free_av_pairs(NTLMSSP* ntlmssp); + +void ntlmssp_compute_message_integrity_check(NTLMSSP* ntlmssp); + +void ntlmssp_encrypt_message(NTLMSSP* ntlmssp, rdpBlob* msg, rdpBlob* encrypted_msg, uint8* signature); +int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* msg, uint8* signature); + +int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s); +int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s); + +NTLMSSP* ntlmssp_new(); +void ntlmssp_init(NTLMSSP* ntlmssp); +void ntlmssp_free(NTLMSSP* ntlmssp); + +#ifdef WITH_DEBUG_NLA +#define DEBUG_NLA(fmt, ...) DEBUG_CLASS(NLA, fmt, ## __VA_ARGS__) +#else +#define DEBUG_NLA(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __NTLMSSP_H */ diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c new file mode 100644 index 0000000..c555fab --- /dev/null +++ b/libfreerdp-core/orders.c @@ -0,0 +1,2020 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Drawing Orders + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "window.h" +#include +#include +#include + +#include "orders.h" + +#ifdef WITH_DEBUG_ORDERS + +static const char* const PRIMARY_DRAWING_ORDER_STRINGS[] = +{ + "DstBlt", + "PatBlt", + "ScrBlt", + "", "", "", "", + "DrawNineGrid", + "MultiDrawNineGrid", + "LineTo", + "OpaqueRect", + "SaveBitmap", + "", + "MemBlt", + "Mem3Blt", + "MultiDstBlt", + "MultiPatBlt", + "MultiScrBlt", + "MultiOpaqueRect", + "FastIndex", + "PolygonSC", + "PolygonCB", + "Polyline", + "", + "FastGlyph", + "EllipseSC", + "EllipseCB", + "GlyphIndex" +}; + +#define PRIMARY_DRAWING_ORDER_COUNT (sizeof(PRIMARY_DRAWING_ORDER_STRINGS) / sizeof(PRIMARY_DRAWING_ORDER_STRINGS[0])) + +static const char* const SECONDARY_DRAWING_ORDER_STRINGS[] = +{ + "Cache Bitmap", + "Cache Color Table", + "Cache Bitmap (Compressed)", + "Cache Glyph", + "Cache Bitmap V2", + "Cache Bitmap V2 (Compressed)", + "", + "Cache Brush", + "Cache Bitmap V3" +}; + +#define SECONDARY_DRAWING_ORDER_COUNT (sizeof(SECONDARY_DRAWING_ORDER_STRINGS) / sizeof(SECONDARY_DRAWING_ORDER_STRINGS[0])) + +static const char* const ALTSEC_DRAWING_ORDER_STRINGS[] = +{ + "Switch Surface", + "Create Offscreen Bitmap", + "Stream Bitmap First", + "Stream Bitmap Next", + "Create NineGrid Bitmap", + "Draw GDI+ First", + "Draw GDI+ Next", + "Draw GDI+ End", + "Draw GDI+ Cache First", + "Draw GDI+ Cache Next", + "Draw GDI+ Cache End", + "Windowing", + "Desktop Composition", + "Frame Marker" +}; + +#define ALTSEC_DRAWING_ORDER_COUNT (sizeof(ALTSEC_DRAWING_ORDER_STRINGS) / sizeof(ALTSEC_DRAWING_ORDER_STRINGS[0])) + +#endif /* WITH_DEBUG_ORDERS */ + +static const uint8 PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = +{ + DSTBLT_ORDER_FIELD_BYTES, + PATBLT_ORDER_FIELD_BYTES, + SCRBLT_ORDER_FIELD_BYTES, + 0, 0, 0, 0, + DRAW_NINE_GRID_ORDER_FIELD_BYTES, + MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES, + LINE_TO_ORDER_FIELD_BYTES, + OPAQUE_RECT_ORDER_FIELD_BYTES, + SAVE_BITMAP_ORDER_FIELD_BYTES, + 0, + MEMBLT_ORDER_FIELD_BYTES, + MEM3BLT_ORDER_FIELD_BYTES, + MULTI_DSTBLT_ORDER_FIELD_BYTES, + MULTI_PATBLT_ORDER_FIELD_BYTES, + MULTI_SCRBLT_ORDER_FIELD_BYTES, + MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES, + FAST_INDEX_ORDER_FIELD_BYTES, + POLYGON_SC_ORDER_FIELD_BYTES, + POLYGON_CB_ORDER_FIELD_BYTES, + POLYLINE_ORDER_FIELD_BYTES, + 0, + FAST_GLYPH_ORDER_FIELD_BYTES, + ELLIPSE_SC_ORDER_FIELD_BYTES, + ELLIPSE_CB_ORDER_FIELD_BYTES, + GLYPH_INDEX_ORDER_FIELD_BYTES +}; + +static const uint8 CBR2_BPP[] = +{ + 0, 0, 0, 8, 16, 24, 32 +}; + +static const uint8 CBR23_BPP[] = +{ + 0, 0, 0, 8, 16, 24, 32 +}; + +static const uint8 BMF_BPP[] = +{ + 0, 1, 0, 8, 16, 24, 32 +}; + +INLINE void update_read_coord(STREAM* s, sint32* coord, boolean delta) +{ + sint8 lsi8; + sint16 lsi16; + + if (delta) + { + stream_read_uint8(s, lsi8); + *coord += lsi8; + } + else + { + stream_read_uint16(s, lsi16); + *coord = lsi16; + } +} + +INLINE void update_read_color(STREAM* s, uint32* color) +{ + uint8 byte; + + stream_read_uint8(s, byte); + *color = byte; + stream_read_uint8(s, byte); + *color |= (byte << 8); + stream_read_uint8(s, byte); + *color |= (byte << 16); +} + +INLINE void update_read_colorref(STREAM* s, uint32* color) +{ + uint8 byte; + + stream_read_uint8(s, byte); + *color = byte; + stream_read_uint8(s, byte); + *color |= (byte << 8); + stream_read_uint8(s, byte); + *color |= (byte << 16); + stream_seek_uint8(s); +} + +INLINE void update_read_color_quad(STREAM* s, uint32* color) +{ + uint8 byte; + + stream_read_uint8(s, byte); + *color = (byte << 16); + stream_read_uint8(s, byte); + *color |= (byte << 8); + stream_read_uint8(s, byte); + *color |= byte; + stream_seek_uint8(s); +} + +INLINE void update_read_2byte_unsigned(STREAM* s, uint32* value) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x80) + { + *value = (byte & 0x7F) << 8; + stream_read_uint8(s, byte); + *value |= byte; + } + else + { + *value = (byte & 0x7F); + } +} + +INLINE void update_read_2byte_signed(STREAM* s, sint32* value) +{ + uint8 byte; + boolean negative; + + stream_read_uint8(s, byte); + + negative = (byte & 0x40) ? true : false; + + *value = (byte & 0x3F); + + if (byte & 0x80) + { + stream_read_uint8(s, byte); + *value = (*value << 8) | byte; + } + + if (negative) + *value *= -1; +} + +INLINE void update_read_4byte_unsigned(STREAM* s, uint32* value) +{ + uint8 byte; + uint8 count; + + stream_read_uint8(s, byte); + + count = (byte & 0xC0) >> 6; + + switch (count) + { + case 0: + *value = (byte & 0x3F); + break; + + case 1: + *value = (byte & 0x3F) << 8; + stream_read_uint8(s, byte); + *value |= byte; + break; + + case 2: + *value = (byte & 0x3F) << 16; + stream_read_uint8(s, byte); + *value |= (byte << 8); + stream_read_uint8(s, byte); + *value |= byte; + break; + + case 3: + *value = (byte & 0x3F) << 24; + stream_read_uint8(s, byte); + *value |= (byte << 16); + stream_read_uint8(s, byte); + *value |= (byte << 8); + stream_read_uint8(s, byte); + *value |= byte; + break; + + default: + break; + } +} + +INLINE void update_read_delta(STREAM* s, sint32* value) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x40) + *value = (byte | ~0x3F); + else + *value = (byte & 0x3F); + + if (byte & 0x80) + { + stream_read_uint8(s, byte); + *value = (*value << 8) | byte; + } +} + +INLINE void update_read_glyph_delta(STREAM* s, uint16* value) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte == 0x80) + stream_read_uint16(s, *value); + else + *value = (byte & 0x3F); +} + +INLINE void update_seek_glyph_delta(STREAM* s) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x80) + stream_seek_uint8(s); +} + +INLINE void update_read_brush(STREAM* s, rdpBrush* brush, uint8 fieldFlags) +{ + if (fieldFlags & ORDER_FIELD_01) + stream_read_uint8(s, brush->x); + + if (fieldFlags & ORDER_FIELD_02) + stream_read_uint8(s, brush->y); + + if (fieldFlags & ORDER_FIELD_03) + stream_read_uint8(s, brush->style); + + if (fieldFlags & ORDER_FIELD_04) + stream_read_uint8(s, brush->hatch); + + if (brush->style & CACHED_BRUSH) + { + brush->index = brush->hatch; + + brush->bpp = BMF_BPP[brush->style & 0x0F]; + + if (brush->bpp == 0) + brush->bpp = 1; + } + + if (fieldFlags & ORDER_FIELD_05) + { + brush->data = (uint8*) brush->p8x8; + stream_read_uint8(s, brush->data[7]); + stream_read_uint8(s, brush->data[6]); + stream_read_uint8(s, brush->data[5]); + stream_read_uint8(s, brush->data[4]); + stream_read_uint8(s, brush->data[3]); + stream_read_uint8(s, brush->data[2]); + stream_read_uint8(s, brush->data[1]); + brush->data[0] = brush->hatch; + } +} + +INLINE void update_read_delta_rects(STREAM* s, DELTA_RECT* rectangles, int number) +{ + int i; + uint8 flags = 0; + uint8* zeroBits; + int zeroBitsSize; + + if (number > 45) + number = 45; + + zeroBitsSize = ((number + 1) / 2); + + stream_get_mark(s, zeroBits); + stream_seek(s, zeroBitsSize); + + memset(rectangles, 0, sizeof(DELTA_RECT) * (number + 1)); + + for (i = 1; i < number + 1; i++) + { + if ((i - 1) % 2 == 0) + flags = zeroBits[(i - 1) / 2]; + + if (~flags & 0x80) + update_read_delta(s, &rectangles[i].left); + + if (~flags & 0x40) + update_read_delta(s, &rectangles[i].top); + + if (~flags & 0x20) + update_read_delta(s, &rectangles[i].width); + else + rectangles[i].width = rectangles[i - 1].width; + + if (~flags & 0x10) + update_read_delta(s, &rectangles[i].height); + else + rectangles[i].height = rectangles[i - 1].height; + + rectangles[i].left = rectangles[i].left + rectangles[i - 1].left; + rectangles[i].top = rectangles[i].top + rectangles[i - 1].top; + + flags <<= 4; + } +} + +INLINE void update_read_delta_points(STREAM* s, DELTA_POINT* points, int number, sint16 x, sint16 y) +{ + int i; + uint8 flags = 0; + uint8* zeroBits; + int zeroBitsSize; + + zeroBitsSize = ((number + 3) / 4); + + stream_get_mark(s, zeroBits); + stream_seek(s, zeroBitsSize); + + memset(points, 0, sizeof(DELTA_POINT) * number); + + for (i = 0; i < number; i++) + { + if (i % 4 == 0) + flags = zeroBits[i / 4]; + + if (~flags & 0x80) + update_read_delta(s, &points[i].x); + + if (~flags & 0x40) + update_read_delta(s, &points[i].y); + + flags <<= 2; + } +} + +/* Primary Drawing Orders */ + +void update_read_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &dstblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &dstblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &dstblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &dstblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, dstblt->bRop); +} + +void update_read_patblt_order(STREAM* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &patblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &patblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &patblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &patblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, patblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_color(s, &patblt->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_color(s, &patblt->foreColor); + + update_read_brush(s, &patblt->brush, orderInfo->fieldFlags >> 7); +} + +void update_read_scrblt_order(STREAM* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &scrblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &scrblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &scrblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &scrblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, scrblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_coord(s, &scrblt->nXSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &scrblt->nYSrc, orderInfo->deltaCoordinates); +} + +void update_read_opaque_rect_order(STREAM* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect) +{ + uint8 byte; + + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &opaque_rect->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &opaque_rect->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &opaque_rect->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &opaque_rect->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + { + stream_read_uint8(s, byte); + opaque_rect->color = (opaque_rect->color & 0xFFFFFF00) | byte; + } + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + { + stream_read_uint8(s, byte); + opaque_rect->color = (opaque_rect->color & 0xFFFF00FF) | (byte << 8); + } + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint8(s, byte); + opaque_rect->color = (opaque_rect->color & 0xFF00FFFF) | (byte << 16); + } +} + +void update_read_draw_nine_grid_order(STREAM* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &draw_nine_grid->srcLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &draw_nine_grid->srcTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &draw_nine_grid->srcRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &draw_nine_grid->srcBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint16(s, draw_nine_grid->bitmapId); +} + +void update_read_multi_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &multi_dstblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &multi_dstblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &multi_dstblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &multi_dstblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, multi_dstblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, multi_dstblt->numRectangles); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint16(s, multi_dstblt->cbData); + update_read_delta_rects(s, multi_dstblt->rectangles, multi_dstblt->numRectangles); + } +} + +void update_read_multi_patblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &multi_patblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &multi_patblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &multi_patblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &multi_patblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, multi_patblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_color(s, &multi_patblt->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_color(s, &multi_patblt->foreColor); + + update_read_brush(s, &multi_patblt->brush, orderInfo->fieldFlags >> 7); + + if (orderInfo->fieldFlags & ORDER_FIELD_13) + stream_read_uint8(s, multi_patblt->numRectangles); + + if (orderInfo->fieldFlags & ORDER_FIELD_14) + { + stream_read_uint16(s, multi_patblt->cbData); + update_read_delta_rects(s, multi_patblt->rectangles, multi_patblt->numRectangles); + } +} + +void update_read_multi_scrblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &multi_scrblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &multi_scrblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &multi_scrblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &multi_scrblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, multi_scrblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_coord(s, &multi_scrblt->nXSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &multi_scrblt->nYSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + stream_read_uint8(s, multi_scrblt->numRectangles); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + { + stream_read_uint16(s, multi_scrblt->cbData); + update_read_delta_rects(s, multi_scrblt->rectangles, multi_scrblt->numRectangles); + } +} + +void update_read_multi_opaque_rect_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + uint8 byte; + + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &multi_opaque_rect->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &multi_opaque_rect->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &multi_opaque_rect->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &multi_opaque_rect->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + { + stream_read_uint8(s, byte); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFFFF00) | byte; + } + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + { + stream_read_uint8(s, byte); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFFFF00FF) | (byte << 8); + } + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint8(s, byte); + multi_opaque_rect->color = (multi_opaque_rect->color & 0xFF00FFFF) | (byte << 16); + } + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + stream_read_uint8(s, multi_opaque_rect->numRectangles); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + { + stream_read_uint16(s, multi_opaque_rect->cbData); + update_read_delta_rects(s, multi_opaque_rect->rectangles, multi_opaque_rect->numRectangles); + } +} + +void update_read_multi_draw_nine_grid_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &multi_draw_nine_grid->srcLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &multi_draw_nine_grid->srcTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &multi_draw_nine_grid->srcRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &multi_draw_nine_grid->srcBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint16(s, multi_draw_nine_grid->bitmapId); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, multi_draw_nine_grid->nDeltaEntries); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint16(s, multi_draw_nine_grid->cbData); + stream_seek(s, multi_draw_nine_grid->cbData); + } +} + +void update_read_line_to_order(STREAM* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint16(s, line_to->backMode); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &line_to->nXStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &line_to->nYStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &line_to->nXEnd, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &line_to->nYEnd, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_color(s, &line_to->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + stream_read_uint8(s, line_to->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + stream_read_uint8(s, line_to->penStyle); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + stream_read_uint8(s, line_to->penWidth); + + if (orderInfo->fieldFlags & ORDER_FIELD_10) + update_read_color(s, &line_to->penColor); +} + +void update_read_polyline_order(STREAM* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &polyline->xStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &polyline->yStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + stream_read_uint8(s, polyline->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + stream_seek_uint16(s); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_color(s, &polyline->penColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, polyline->numPoints); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint8(s, polyline->cbData); + + if (polyline->points == NULL) + polyline->points = (DELTA_POINT*) xmalloc(sizeof(DELTA_POINT) * polyline->numPoints); + else + polyline->points = (DELTA_POINT*) xrealloc(polyline->points, sizeof(DELTA_POINT) * polyline->numPoints); + + update_read_delta_points(s, polyline->points, polyline->numPoints, polyline->xStart, polyline->yStart); + } +} + +void update_read_memblt_order(STREAM* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint16(s, memblt->cacheId); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &memblt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &memblt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &memblt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &memblt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, memblt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &memblt->nXSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + update_read_coord(s, &memblt->nYSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + stream_read_uint16(s, memblt->cacheIndex); + + memblt->colorIndex = (memblt->cacheId >> 8); + memblt->cacheId = (memblt->cacheId & 0xFF); +} + +void update_read_mem3blt_order(STREAM* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint16(s, mem3blt->cacheId); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &mem3blt->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &mem3blt->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &mem3blt->nWidth, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &mem3blt->nHeight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, mem3blt->bRop); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &mem3blt->nXSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + update_read_coord(s, &mem3blt->nYSrc, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + update_read_color(s, &mem3blt->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_10) + update_read_color(s, &mem3blt->foreColor); + + update_read_brush(s, &mem3blt->brush, orderInfo->fieldFlags >> 10); + + if (orderInfo->fieldFlags & ORDER_FIELD_16) + stream_read_uint16(s, mem3blt->cacheIndex); + + mem3blt->colorIndex = (mem3blt->cacheId >> 8); + mem3blt->cacheId = (mem3blt->cacheId & 0xFF); +} + +void update_read_save_bitmap_order(STREAM* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint32(s, save_bitmap->savedBitmapPosition); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &save_bitmap->nLeftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &save_bitmap->nTopRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &save_bitmap->nRightRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &save_bitmap->nBottomRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, save_bitmap->operation); +} + +void update_read_glyph_index_order(STREAM* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint8(s, glyph_index->cacheId); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + stream_read_uint8(s, glyph_index->flAccel); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + stream_read_uint8(s, glyph_index->ulCharInc); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + stream_read_uint8(s, glyph_index->fOpRedundant); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_color(s, &glyph_index->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_color(s, &glyph_index->foreColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + stream_read_uint16(s, glyph_index->bkLeft); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + stream_read_uint16(s, glyph_index->bkTop); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + stream_read_uint16(s, glyph_index->bkRight); + + if (orderInfo->fieldFlags & ORDER_FIELD_10) + stream_read_uint16(s, glyph_index->bkBottom); + + if (orderInfo->fieldFlags & ORDER_FIELD_11) + stream_read_uint16(s, glyph_index->opLeft); + + if (orderInfo->fieldFlags & ORDER_FIELD_12) + stream_read_uint16(s, glyph_index->opTop); + + if (orderInfo->fieldFlags & ORDER_FIELD_13) + stream_read_uint16(s, glyph_index->opRight); + + if (orderInfo->fieldFlags & ORDER_FIELD_14) + stream_read_uint16(s, glyph_index->opBottom); + + update_read_brush(s, &glyph_index->brush, orderInfo->fieldFlags >> 14); + + if (orderInfo->fieldFlags & ORDER_FIELD_20) + stream_read_uint16(s, glyph_index->x); + + if (orderInfo->fieldFlags & ORDER_FIELD_21) + stream_read_uint16(s, glyph_index->y); + + if (orderInfo->fieldFlags & ORDER_FIELD_22) + { + stream_read_uint8(s, glyph_index->cbData); + memcpy(glyph_index->data, s->p, glyph_index->cbData); + stream_seek(s, glyph_index->cbData); + } +} + +void update_read_fast_index_order(STREAM* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint8(s, fast_index->cacheId); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + { + stream_read_uint8(s, fast_index->ulCharInc); + stream_read_uint8(s, fast_index->flAccel); + } + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_color(s, &fast_index->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_color(s, &fast_index->foreColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &fast_index->bkLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_coord(s, &fast_index->bkTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &fast_index->bkRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + update_read_coord(s, &fast_index->bkBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + update_read_coord(s, &fast_index->opLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_10) + update_read_coord(s, &fast_index->opTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_11) + update_read_coord(s, &fast_index->opRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_12) + update_read_coord(s, &fast_index->opBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_13) + update_read_coord(s, &fast_index->x, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_14) + update_read_coord(s, &fast_index->y, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_15) + { + stream_read_uint8(s, fast_index->cbData); + memcpy(fast_index->data, s->p, fast_index->cbData); + stream_seek(s, fast_index->cbData); + } +} + +void update_read_fast_glyph_order(STREAM* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph) +{ + GLYPH_DATA_V2* glyph; + uint8* phold; + + if (orderInfo->fieldFlags & ORDER_FIELD_01) + stream_read_uint8(s, fast_glyph->cacheId); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + { + stream_read_uint8(s, fast_glyph->ulCharInc); + stream_read_uint8(s, fast_glyph->flAccel); + } + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_color(s, &fast_glyph->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_color(s, &fast_glyph->foreColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_coord(s, &fast_glyph->bkLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_coord(s, &fast_glyph->bkTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_coord(s, &fast_glyph->bkRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + update_read_coord(s, &fast_glyph->bkBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_09) + update_read_coord(s, &fast_glyph->opLeft, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_10) + update_read_coord(s, &fast_glyph->opTop, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_11) + update_read_coord(s, &fast_glyph->opRight, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_12) + update_read_coord(s, &fast_glyph->opBottom, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_13) + update_read_coord(s, &fast_glyph->x, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_14) + update_read_coord(s, &fast_glyph->y, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_15) + { + stream_read_uint8(s, fast_glyph->cbData); + memcpy(fast_glyph->data, s->p, fast_glyph->cbData); + phold = s->p; + stream_seek(s, 1); + if ((fast_glyph->cbData > 1) && (fast_glyph->glyph_data == NULL)) + { + /* parse optional glyph data */ + glyph = (GLYPH_DATA_V2*) xmalloc(sizeof(GLYPH_DATA_V2)); + glyph->cacheIndex = fast_glyph->data[0]; + update_read_2byte_signed(s, &glyph->x); + update_read_2byte_signed(s, &glyph->y); + update_read_2byte_unsigned(s, &glyph->cx); + update_read_2byte_unsigned(s, &glyph->cy); + glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; + glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; + glyph->aj = (uint8*) xmalloc(glyph->cb); + stream_read(s, glyph->aj, glyph->cb); + fast_glyph->glyph_data = glyph; + } + s->p = phold + fast_glyph->cbData; + } +} + +void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &polygon_sc->xStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &polygon_sc->yStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + stream_read_uint8(s, polygon_sc->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + stream_read_uint8(s, polygon_sc->fillMode); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_color(s, &polygon_sc->brushColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, polygon_sc->nDeltaEntries); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + { + stream_read_uint8(s, polygon_sc->cbData); + stream_seek(s, polygon_sc->cbData); + } +} + +void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &polygon_cb->xStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &polygon_cb->yStart, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + stream_read_uint8(s, polygon_cb->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + stream_read_uint8(s, polygon_cb->fillMode); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + update_read_color(s, &polygon_cb->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + update_read_color(s, &polygon_cb->foreColor); + + update_read_brush(s, &polygon_cb->brush, orderInfo->fieldFlags >> 6); + + if (orderInfo->fieldFlags & ORDER_FIELD_12) + stream_read_uint8(s, polygon_cb->nDeltaEntries); + + if (orderInfo->fieldFlags & ORDER_FIELD_13) + { + stream_read_uint8(s, polygon_cb->cbData); + stream_seek(s, polygon_cb->cbData); + } +} + +void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &ellipse_sc->leftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &ellipse_sc->topRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &ellipse_sc->rightRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &ellipse_sc->bottomRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, ellipse_sc->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, ellipse_sc->fillMode); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_color(s, &ellipse_sc->color); +} + +void update_read_ellipse_cb_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb) +{ + if (orderInfo->fieldFlags & ORDER_FIELD_01) + update_read_coord(s, &ellipse_cb->leftRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_02) + update_read_coord(s, &ellipse_cb->topRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_03) + update_read_coord(s, &ellipse_cb->rightRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_04) + update_read_coord(s, &ellipse_cb->bottomRect, orderInfo->deltaCoordinates); + + if (orderInfo->fieldFlags & ORDER_FIELD_05) + stream_read_uint8(s, ellipse_cb->bRop2); + + if (orderInfo->fieldFlags & ORDER_FIELD_06) + stream_read_uint8(s, ellipse_cb->fillMode); + + if (orderInfo->fieldFlags & ORDER_FIELD_07) + update_read_color(s, &ellipse_cb->backColor); + + if (orderInfo->fieldFlags & ORDER_FIELD_08) + update_read_color(s, &ellipse_cb->foreColor); + + update_read_brush(s, &ellipse_cb->brush, orderInfo->fieldFlags >> 8); +} + +/* Secondary Drawing Orders */ + +void update_read_cache_bitmap_order(STREAM* s, CACHE_BITMAP_ORDER* cache_bitmap_order, boolean compressed, uint16 flags) +{ + stream_read_uint8(s, cache_bitmap_order->cacheId); /* cacheId (1 byte) */ + stream_seek_uint8(s); /* pad1Octet (1 byte) */ + stream_read_uint8(s, cache_bitmap_order->bitmapWidth); /* bitmapWidth (1 byte) */ + stream_read_uint8(s, cache_bitmap_order->bitmapHeight); /* bitmapHeight (1 byte) */ + stream_read_uint8(s, cache_bitmap_order->bitmapBpp); /* bitmapBpp (1 byte) */ + stream_read_uint16(s, cache_bitmap_order->bitmapLength); /* bitmapLength (2 bytes) */ + stream_read_uint16(s, cache_bitmap_order->cacheIndex); /* cacheIndex (2 bytes) */ + + if (compressed) + { + if ((flags & NO_BITMAP_COMPRESSION_HDR) == 0) + { + uint8* bitmapComprHdr = (uint8*) &(cache_bitmap_order->bitmapComprHdr); + stream_read(s, bitmapComprHdr, 8); /* bitmapComprHdr (8 bytes) */ + cache_bitmap_order->bitmapLength -= 8; + } + stream_get_mark(s, cache_bitmap_order->bitmapDataStream); + stream_seek(s, cache_bitmap_order->bitmapLength); + } + else + { + stream_get_mark(s, cache_bitmap_order->bitmapDataStream); + stream_seek(s, cache_bitmap_order->bitmapLength); /* bitmapDataStream */ + } + cache_bitmap_order->compressed = compressed; +} + +void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, boolean compressed, uint16 flags) +{ + uint8 bitsPerPixelId; + + cache_bitmap_v2_order->cacheId = flags & 0x0003; + cache_bitmap_v2_order->flags = (flags & 0xFF80) >> 7; + + bitsPerPixelId = (flags & 0x0078) >> 3; + cache_bitmap_v2_order->bitmapBpp = CBR2_BPP[bitsPerPixelId]; + + if (cache_bitmap_v2_order->flags & CBR2_PERSISTENT_KEY_PRESENT) + { + stream_read_uint32(s, cache_bitmap_v2_order->key1); /* key1 (4 bytes) */ + stream_read_uint32(s, cache_bitmap_v2_order->key2); /* key2 (4 bytes) */ + } + + if (cache_bitmap_v2_order->flags & CBR2_HEIGHT_SAME_AS_WIDTH) + { + update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth); /* bitmapWidth */ + cache_bitmap_v2_order->bitmapHeight = cache_bitmap_v2_order->bitmapWidth; + } + else + { + update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapWidth); /* bitmapWidth */ + update_read_2byte_unsigned(s, &cache_bitmap_v2_order->bitmapHeight); /* bitmapHeight */ + } + + update_read_4byte_unsigned(s, &cache_bitmap_v2_order->bitmapLength); /* bitmapLength */ + update_read_2byte_unsigned(s, &cache_bitmap_v2_order->cacheIndex); /* cacheIndex */ + + if (cache_bitmap_v2_order->flags & CBR2_DO_NOT_CACHE) + cache_bitmap_v2_order->cacheIndex = BITMAP_CACHE_WAITING_LIST_INDEX; + + if (compressed) + { + if (!(cache_bitmap_v2_order->flags & CBR2_NO_BITMAP_COMPRESSION_HDR)) + { + stream_read_uint16(s, cache_bitmap_v2_order->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbScanWidth); /* cbScanWidth (2 bytes) */ + stream_read_uint16(s, cache_bitmap_v2_order->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + cache_bitmap_v2_order->bitmapLength = cache_bitmap_v2_order->cbCompMainBodySize; + } + + stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream); + stream_seek(s, cache_bitmap_v2_order->bitmapLength); + } + else + { + stream_get_mark(s, cache_bitmap_v2_order->bitmapDataStream); + stream_seek(s, cache_bitmap_v2_order->bitmapLength); + } + cache_bitmap_v2_order->compressed = compressed; +} + +void update_read_cache_bitmap_v3_order(STREAM* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, boolean compressed, uint16 flags) +{ + uint8 bitsPerPixelId; + BITMAP_DATA_EX* bitmapData; + + cache_bitmap_v3_order->cacheId = flags & 0x00000003; + cache_bitmap_v3_order->flags = (flags & 0x0000FF80) >> 7; + + bitsPerPixelId = (flags & 0x00000078) >> 3; + cache_bitmap_v3_order->bpp = CBR23_BPP[bitsPerPixelId]; + + stream_read_uint16(s, cache_bitmap_v3_order->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint32(s, cache_bitmap_v3_order->key1); /* key1 (4 bytes) */ + stream_read_uint32(s, cache_bitmap_v3_order->key2); /* key2 (4 bytes) */ + + bitmapData = &cache_bitmap_v3_order->bitmapData; + + stream_read_uint8(s, bitmapData->bpp); + stream_seek_uint8(s); /* reserved1 (1 byte) */ + stream_seek_uint8(s); /* reserved2 (1 byte) */ + stream_read_uint8(s, bitmapData->codecID); /* codecID (1 byte) */ + stream_read_uint16(s, bitmapData->width); /* width (2 bytes) */ + stream_read_uint16(s, bitmapData->height); /* height (2 bytes) */ + stream_read_uint32(s, bitmapData->length); /* length (4 bytes) */ + + if (bitmapData->data == NULL) + bitmapData->data = (uint8*) xmalloc(bitmapData->length); + else + bitmapData->data = (uint8*) xrealloc(bitmapData->data, bitmapData->length); + + stream_read(s, bitmapData->data, bitmapData->length); +} + +void update_read_cache_color_table_order(STREAM* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, uint16 flags) +{ + int i; + uint32* colorTable; + + stream_read_uint8(s, cache_color_table_order->cacheIndex); /* cacheIndex (1 byte) */ + stream_read_uint8(s, cache_color_table_order->numberColors); /* numberColors (2 bytes) */ + + colorTable = cache_color_table_order->colorTable; + + if (colorTable == NULL) + colorTable = (uint32*) xmalloc(cache_color_table_order->numberColors * 4); + else + colorTable = (uint32*) xrealloc(colorTable, cache_color_table_order->numberColors * 4); + + for (i = 0; i < (int) cache_color_table_order->numberColors; i++) + { + update_read_color_quad(s, &colorTable[i]); + } + + cache_color_table_order->colorTable = colorTable; +} + +void update_read_cache_glyph_order(STREAM* s, CACHE_GLYPH_ORDER* cache_glyph_order, uint16 flags) +{ + int i; + sint16 lsi16; + GLYPH_DATA* glyph; + + stream_read_uint8(s, cache_glyph_order->cacheId); /* cacheId (1 byte) */ + stream_read_uint8(s, cache_glyph_order->cGlyphs); /* cGlyphs (1 byte) */ + + for (i = 0; i < (int) cache_glyph_order->cGlyphs; i++) + { + if (cache_glyph_order->glyphData[i] == NULL) + { + cache_glyph_order->glyphData[i] = (GLYPH_DATA*) xmalloc(sizeof(GLYPH_DATA)); + } + glyph = cache_glyph_order->glyphData[i]; + + stream_read_uint16(s, glyph->cacheIndex); + stream_read_uint16(s, lsi16); + glyph->x = lsi16; + stream_read_uint16(s, lsi16); + glyph->y = lsi16; + stream_read_uint16(s, glyph->cx); + stream_read_uint16(s, glyph->cy); + + glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; + glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; + + glyph->aj = (uint8*) xmalloc(glyph->cb); + + stream_read(s, glyph->aj, glyph->cb); + } + + if (flags & CG_GLYPH_UNICODE_PRESENT) + stream_seek(s, cache_glyph_order->cGlyphs * 2); +} + +void update_read_cache_glyph_v2_order(STREAM* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, uint16 flags) +{ + int i; + GLYPH_DATA_V2* glyph; + + cache_glyph_v2_order->cacheId = (flags & 0x000F); + cache_glyph_v2_order->flags = (flags & 0x00F0) >> 4; + cache_glyph_v2_order->cGlyphs = (flags & 0xFF00) >> 8; + + for (i = 0; i < (int) cache_glyph_v2_order->cGlyphs; i++) + { + if (cache_glyph_v2_order->glyphData[i] == NULL) + { + cache_glyph_v2_order->glyphData[i] = (GLYPH_DATA_V2*) xmalloc(sizeof(GLYPH_DATA_V2)); + } + glyph = cache_glyph_v2_order->glyphData[i]; + + stream_read_uint8(s, glyph->cacheIndex); + update_read_2byte_signed(s, &glyph->x); + update_read_2byte_signed(s, &glyph->y); + update_read_2byte_unsigned(s, &glyph->cx); + update_read_2byte_unsigned(s, &glyph->cy); + + glyph->cb = ((glyph->cx + 7) / 8) * glyph->cy; + glyph->cb += ((glyph->cb % 4) > 0) ? 4 - (glyph->cb % 4) : 0; + + glyph->aj = (uint8*) xmalloc(glyph->cb); + + stream_read(s, glyph->aj, glyph->cb); + } + + if (flags & CG_GLYPH_UNICODE_PRESENT) + stream_seek(s, cache_glyph_v2_order->cGlyphs * 2); +} + +void update_decompress_brush(STREAM* s, uint8* output, uint8 bpp) +{ + int index; + int x, y, k; + uint8 byte = 0; + uint8* palette; + int bytesPerPixel; + + palette = s->p + 16; + bytesPerPixel = ((bpp + 1) / 8); + + for (y = 7; y >= 0; y--) + { + for (x = 0; x < 8; x++) + { + if ((x % 4) == 0) + stream_read_uint8(s, byte); + + index = ((byte >> ((3 - (x % 4)) * 2)) & 0x03); + + for (k = 0; k < bytesPerPixel; k++) + { + output[((y * 8 + x) * bytesPerPixel) + k] = palette[(index * bytesPerPixel) + k]; + } + } + } +} + +void update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_order, uint16 flags) +{ + int i; + int size; + uint8 iBitmapFormat; + boolean compressed = false; + + stream_read_uint8(s, cache_brush_order->index); /* cacheEntry (1 byte) */ + + stream_read_uint8(s, iBitmapFormat); /* iBitmapFormat (1 byte) */ + cache_brush_order->bpp = BMF_BPP[iBitmapFormat]; + + stream_read_uint8(s, cache_brush_order->cx); /* cx (1 byte) */ + stream_read_uint8(s, cache_brush_order->cy); /* cy (1 byte) */ + stream_read_uint8(s, cache_brush_order->style); /* style (1 byte) */ + stream_read_uint8(s, cache_brush_order->length); /* iBytes (1 byte) */ + + if ((cache_brush_order->cx == 8) && (cache_brush_order->cy == 8)) + { + size = (cache_brush_order->bpp == 1) ? 8 : 8 * 8 * cache_brush_order->bpp; + + cache_brush_order->data = (uint8*) xmalloc(size); + + if (cache_brush_order->bpp == 1) + { + if (cache_brush_order->length != 8) + { + printf("incompatible 1bpp brush of length:%d\n", cache_brush_order->length); + return; + } + + /* rows are encoded in reverse order */ + + for (i = 7; i >= 0; i--) + { + stream_read_uint8(s, cache_brush_order->data[i]); + } + } + else + { + if ((iBitmapFormat == BMF_8BPP) && (cache_brush_order->length == 20)) + compressed = true; + else if ((iBitmapFormat == BMF_16BPP) && (cache_brush_order->length == 24)) + compressed = true; + else if ((iBitmapFormat == BMF_32BPP) && (cache_brush_order->length == 32)) + compressed = true; + + if (compressed != false) + { + /* compressed brush */ + update_decompress_brush(s, cache_brush_order->data, cache_brush_order->bpp); + } + else + { + /* uncompressed brush */ + int scanline = (cache_brush_order->bpp / 8) * 8; + + for (i = 7; i >= 0; i--) + { + stream_read(s, &cache_brush_order->data[i * scanline], scanline); + } + } + } + } +} + +/* Alternate Secondary Drawing Orders */ + +void update_read_create_offscreen_bitmap_order(STREAM* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap) +{ + uint16 flags; + boolean deleteListPresent; + OFFSCREEN_DELETE_LIST* deleteList; + + stream_read_uint16(s, flags); /* flags (2 bytes) */ + create_offscreen_bitmap->id = flags & 0x7FFF; + deleteListPresent = (flags & 0x8000) ? true : false; + + stream_read_uint16(s, create_offscreen_bitmap->cx); /* cx (2 bytes) */ + stream_read_uint16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */ + + deleteList = &(create_offscreen_bitmap->deleteList); + if (deleteListPresent) + { + int i; + + stream_read_uint16(s, deleteList->cIndices); + + if (deleteList->cIndices > deleteList->sIndices) + { + deleteList->sIndices = deleteList->cIndices; + deleteList->indices = xrealloc(deleteList->indices, deleteList->sIndices * 2); + } + + for (i = 0; i < (int) deleteList->cIndices; i++) + { + stream_read_uint16(s, deleteList->indices[i]); + } + } + else + { + deleteList->cIndices = 0; + } +} + +void update_read_switch_surface_order(STREAM* s, SWITCH_SURFACE_ORDER* switch_surface) +{ + stream_read_uint16(s, switch_surface->bitmapId); /* bitmapId (2 bytes) */ +} + +void update_read_create_nine_grid_bitmap_order(STREAM* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap) +{ + NINE_GRID_BITMAP_INFO* nineGridInfo; + + stream_read_uint8(s, create_nine_grid_bitmap->bitmapBpp); /* bitmapBpp (1 byte) */ + stream_read_uint16(s, create_nine_grid_bitmap->bitmapId); /* bitmapId (2 bytes) */ + + nineGridInfo = &(create_nine_grid_bitmap->nineGridInfo); + stream_read_uint32(s, nineGridInfo->flFlags); /* flFlags (4 bytes) */ + stream_read_uint16(s, nineGridInfo->ulLeftWidth); /* ulLeftWidth (2 bytes) */ + stream_read_uint16(s, nineGridInfo->ulRightWidth); /* ulRightWidth (2 bytes) */ + stream_read_uint16(s, nineGridInfo->ulTopHeight); /* ulTopHeight (2 bytes) */ + stream_read_uint16(s, nineGridInfo->ulBottomHeight); /* ulBottomHeight (2 bytes) */ + update_read_colorref(s, &nineGridInfo->crTransparent); /* crTransparent (4 bytes) */ +} + +void update_read_frame_marker_order(STREAM* s, FRAME_MARKER_ORDER* frame_marker) +{ + stream_read_uint32(s, frame_marker->action); /* action (4 bytes) */ +} + +void update_read_stream_bitmap_first_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first) +{ + stream_read_uint8(s, stream_bitmap_first->bitmapFlags); /* bitmapFlags (1 byte) */ + stream_read_uint8(s, stream_bitmap_first->bitmapBpp); /* bitmapBpp (1 byte) */ + stream_read_uint16(s, stream_bitmap_first->bitmapType); /* bitmapType (2 bytes) */ + stream_read_uint16(s, stream_bitmap_first->bitmapWidth); /* bitmapWidth (2 bytes) */ + stream_read_uint16(s, stream_bitmap_first->bitmapHeight); /* bitmapHeigth (2 bytes) */ + + if (stream_bitmap_first->bitmapFlags & STREAM_BITMAP_V2) + stream_read_uint32(s, stream_bitmap_first->bitmapSize); /* bitmapSize (4 bytes) */ + else + stream_read_uint16(s, stream_bitmap_first->bitmapSize); /* bitmapSize (2 bytes) */ + + stream_read_uint16(s, stream_bitmap_first->bitmapBlockSize); /* bitmapBlockSize (2 bytes) */ + stream_seek(s, stream_bitmap_first->bitmapBlockSize); /* bitmapBlock */ +} + +void update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next) +{ + stream_read_uint8(s, stream_bitmap_next->bitmapFlags); /* bitmapFlags (1 byte) */ + stream_read_uint16(s, stream_bitmap_next->bitmapType); /* bitmapType (2 bytes) */ + stream_read_uint16(s, stream_bitmap_next->bitmapBlockSize); /* bitmapBlockSize (2 bytes) */ + stream_seek(s, stream_bitmap_next->bitmapBlockSize); /* bitmapBlock */ +} + +void update_read_draw_gdiplus_first_order(STREAM* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first) +{ + stream_seek_uint8(s); /* pad1Octet (1 byte) */ + stream_read_uint16(s, draw_gdiplus_first->cbSize); /* cbSize (2 bytes) */ + stream_read_uint32(s, draw_gdiplus_first->cbTotalSize); /* cbTotalSize (4 bytes) */ + stream_read_uint32(s, draw_gdiplus_first->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ + stream_seek(s, draw_gdiplus_first->cbSize); /* emfRecords */ +} + +void update_read_draw_gdiplus_next_order(STREAM* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next) +{ + stream_seek_uint8(s); /* pad1Octet (1 byte) */ + stream_read_uint16(s, draw_gdiplus_next->cbSize); /* cbSize (2 bytes) */ + stream_seek(s, draw_gdiplus_next->cbSize); /* emfRecords */ +} + +void update_read_draw_gdiplus_end_order(STREAM* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end) +{ + stream_seek_uint8(s); /* pad1Octet (1 byte) */ + stream_read_uint16(s, draw_gdiplus_end->cbSize); /* cbSize (2 bytes) */ + stream_read_uint32(s, draw_gdiplus_end->cbTotalSize); /* cbTotalSize (4 bytes) */ + stream_read_uint32(s, draw_gdiplus_end->cbTotalEmfSize); /* cbTotalEmfSize (4 bytes) */ + stream_seek(s, draw_gdiplus_end->cbSize); /* emfRecords */ +} + +void update_read_draw_gdiplus_cache_first_order(STREAM* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first) +{ + stream_read_uint8(s, draw_gdiplus_cache_first->flags); /* flags (1 byte) */ + stream_read_uint16(s, draw_gdiplus_cache_first->cacheType); /* cacheType (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_first->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_first->cbSize); /* cbSize (2 bytes) */ + stream_read_uint32(s, draw_gdiplus_cache_first->cbTotalSize); /* cbTotalSize (4 bytes) */ + stream_seek(s, draw_gdiplus_cache_first->cbSize); /* emfRecords */ +} + +void update_read_draw_gdiplus_cache_next_order(STREAM* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next) +{ + stream_read_uint8(s, draw_gdiplus_cache_next->flags); /* flags (1 byte) */ + stream_read_uint16(s, draw_gdiplus_cache_next->cacheType); /* cacheType (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_next->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_next->cbSize); /* cbSize (2 bytes) */ + stream_seek(s, draw_gdiplus_cache_next->cbSize); /* emfRecords */ +} + +void update_read_draw_gdiplus_cache_end_order(STREAM* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end) +{ + stream_read_uint8(s, draw_gdiplus_cache_end->flags); /* flags (1 byte) */ + stream_read_uint16(s, draw_gdiplus_cache_end->cacheType); /* cacheType (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_end->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint16(s, draw_gdiplus_cache_end->cbSize); /* cbSize (2 bytes) */ + stream_read_uint32(s, draw_gdiplus_cache_end->cbTotalSize); /* cbTotalSize (4 bytes) */ + stream_seek(s, draw_gdiplus_cache_end->cbSize); /* emfRecords */ +} + +void update_read_field_flags(STREAM* s, uint32* fieldFlags, uint8 flags, uint8 fieldBytes) +{ + int i; + uint8 byte; + + if (flags & ORDER_ZERO_FIELD_BYTE_BIT0) + fieldBytes--; + + if (flags & ORDER_ZERO_FIELD_BYTE_BIT1) + { + if (fieldBytes > 1) + fieldBytes -= 2; + else + fieldBytes = 0; + } + + *fieldFlags = 0; + for (i = 0; i < fieldBytes; i++) + { + stream_read_uint8(s, byte); + *fieldFlags |= byte << (i * 8); + } +} + +void update_read_bounds(STREAM* s, rdpBounds* bounds) +{ + uint8 flags; + + stream_read_uint8(s, flags); /* field flags */ + + if (flags & BOUND_LEFT) + update_read_coord(s, &bounds->left, false); + else if (flags & BOUND_DELTA_LEFT) + update_read_coord(s, &bounds->left, true); + + if (flags & BOUND_TOP) + update_read_coord(s, &bounds->top, false); + else if (flags & BOUND_DELTA_TOP) + update_read_coord(s, &bounds->top, true); + + if (flags & BOUND_RIGHT) + update_read_coord(s, &bounds->right, false); + else if (flags & BOUND_DELTA_RIGHT) + update_read_coord(s, &bounds->right, true); + + if (flags & BOUND_BOTTOM) + update_read_coord(s, &bounds->bottom, false); + else if (flags & BOUND_DELTA_BOTTOM) + update_read_coord(s, &bounds->bottom, true); +} + +void update_recv_primary_order(rdpUpdate* update, STREAM* s, uint8 flags) +{ + ORDER_INFO* orderInfo; + rdpContext* context = update->context; + rdpPrimaryUpdate* primary = update->primary; + + orderInfo = &(primary->order_info); + + if (flags & ORDER_TYPE_CHANGE) + stream_read_uint8(s, orderInfo->orderType); /* orderType (1 byte) */ + + update_read_field_flags(s, &(orderInfo->fieldFlags), flags, + PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]); + + if (flags & ORDER_BOUNDS) + { + if (!(flags & ORDER_ZERO_BOUNDS_DELTAS)) + update_read_bounds(s, &orderInfo->bounds); + + IFCALL(update->SetBounds, context, &orderInfo->bounds); + } + + orderInfo->deltaCoordinates = (flags & ORDER_DELTA_COORDINATES) ? true : false; + +#ifdef WITH_DEBUG_ORDERS + if (orderInfo->orderType < PRIMARY_DRAWING_ORDER_COUNT) + printf("%s Primary Drawing Order (0x%02X)\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType], orderInfo->orderType); + else + printf("Unknown Primary Drawing Order (0x%02X)\n", orderInfo->orderType); +#endif + + switch (orderInfo->orderType) + { + case ORDER_TYPE_DSTBLT: + update_read_dstblt_order(s, orderInfo, &(primary->dstblt)); + IFCALL(primary->DstBlt, context, &primary->dstblt); + break; + + case ORDER_TYPE_PATBLT: + update_read_patblt_order(s, orderInfo, &(primary->patblt)); + IFCALL(primary->PatBlt, context, &primary->patblt); + break; + + case ORDER_TYPE_SCRBLT: + update_read_scrblt_order(s, orderInfo, &(primary->scrblt)); + IFCALL(primary->ScrBlt, context, &primary->scrblt); + break; + + case ORDER_TYPE_OPAQUE_RECT: + update_read_opaque_rect_order(s, orderInfo, &(primary->opaque_rect)); + IFCALL(primary->OpaqueRect, context, &primary->opaque_rect); + break; + + case ORDER_TYPE_DRAW_NINE_GRID: + update_read_draw_nine_grid_order(s, orderInfo, &(primary->draw_nine_grid)); + IFCALL(primary->DrawNineGrid, context, &primary->draw_nine_grid); + break; + + case ORDER_TYPE_MULTI_DSTBLT: + update_read_multi_dstblt_order(s, orderInfo, &(primary->multi_dstblt)); + IFCALL(primary->MultiDstBlt, context, &primary->multi_dstblt); + break; + + case ORDER_TYPE_MULTI_PATBLT: + update_read_multi_patblt_order(s, orderInfo, &(primary->multi_patblt)); + IFCALL(primary->MultiPatBlt, context, &primary->multi_patblt); + break; + + case ORDER_TYPE_MULTI_SCRBLT: + update_read_multi_scrblt_order(s, orderInfo, &(primary->multi_scrblt)); + IFCALL(primary->MultiScrBlt, context, &primary->multi_scrblt); + break; + + case ORDER_TYPE_MULTI_OPAQUE_RECT: + update_read_multi_opaque_rect_order(s, orderInfo, &(primary->multi_opaque_rect)); + IFCALL(primary->MultiOpaqueRect, context, &primary->multi_opaque_rect); + break; + + case ORDER_TYPE_MULTI_DRAW_NINE_GRID: + update_read_multi_draw_nine_grid_order(s, orderInfo, &(primary->multi_draw_nine_grid)); + IFCALL(primary->MultiDrawNineGrid, context, &primary->multi_draw_nine_grid); + break; + + case ORDER_TYPE_LINE_TO: + update_read_line_to_order(s, orderInfo, &(primary->line_to)); + IFCALL(primary->LineTo, context, &primary->line_to); + break; + + case ORDER_TYPE_POLYLINE: + update_read_polyline_order(s, orderInfo, &(primary->polyline)); + IFCALL(primary->Polyline, context, &primary->polyline); + break; + + case ORDER_TYPE_MEMBLT: + update_read_memblt_order(s, orderInfo, &(primary->memblt)); + IFCALL(primary->MemBlt, context, &primary->memblt); + break; + + case ORDER_TYPE_MEM3BLT: + update_read_mem3blt_order(s, orderInfo, &(primary->mem3blt)); + IFCALL(primary->Mem3Blt, context, &primary->mem3blt); + break; + + case ORDER_TYPE_SAVE_BITMAP: + update_read_save_bitmap_order(s, orderInfo, &(primary->save_bitmap)); + IFCALL(primary->SaveBitmap, context, &primary->save_bitmap); + break; + + case ORDER_TYPE_GLYPH_INDEX: + update_read_glyph_index_order(s, orderInfo, &(primary->glyph_index)); + IFCALL(primary->GlyphIndex, context, &primary->glyph_index); + break; + + case ORDER_TYPE_FAST_INDEX: + update_read_fast_index_order(s, orderInfo, &(primary->fast_index)); + IFCALL(primary->FastIndex, context, &primary->fast_index); + break; + + case ORDER_TYPE_FAST_GLYPH: + update_read_fast_glyph_order(s, orderInfo, &(primary->fast_glyph)); + IFCALL(primary->FastGlyph, context, &primary->fast_glyph); + break; + + case ORDER_TYPE_POLYGON_SC: + update_read_polygon_sc_order(s, orderInfo, &(primary->polygon_sc)); + IFCALL(primary->PolygonSC, context, &primary->polygon_sc); + break; + + case ORDER_TYPE_POLYGON_CB: + update_read_polygon_cb_order(s, orderInfo, &(primary->polygon_cb)); + IFCALL(primary->PolygonCB, context, &primary->polygon_cb); + break; + + case ORDER_TYPE_ELLIPSE_SC: + update_read_ellipse_sc_order(s, orderInfo, &(primary->ellipse_sc)); + IFCALL(primary->EllipseSC, context, &primary->ellipse_sc); + break; + + case ORDER_TYPE_ELLIPSE_CB: + update_read_ellipse_cb_order(s, orderInfo, &(primary->ellipse_cb)); + IFCALL(primary->EllipseCB, context, &primary->ellipse_cb); + break; + + default: + break; + } + + if (flags & ORDER_BOUNDS) + { + IFCALL(update->SetBounds, context, NULL); + } +} + +void update_recv_secondary_order(rdpUpdate* update, STREAM* s, uint8 flags) +{ + uint8* next; + uint8 orderType; + uint16 extraFlags; + uint16 orderLength; + rdpContext* context = update->context; + rdpSecondaryUpdate* secondary = update->secondary; + + stream_read_uint16(s, orderLength); /* orderLength (2 bytes) */ + stream_read_uint16(s, extraFlags); /* extraFlags (2 bytes) */ + stream_read_uint8(s, orderType); /* orderType (1 byte) */ + + next = s->p + ((sint16) orderLength) + 7; + +#ifdef WITH_DEBUG_ORDERS + if (orderType < SECONDARY_DRAWING_ORDER_COUNT) + printf("%s Secondary Drawing Order (0x%02X)\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType], orderType); + else + printf("Unknown Secondary Drawing Order (0x%02X)\n", orderType); +#endif + + switch (orderType) + { + case ORDER_TYPE_BITMAP_UNCOMPRESSED: + update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), false, extraFlags); + IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); + break; + + case ORDER_TYPE_CACHE_BITMAP_COMPRESSED: + update_read_cache_bitmap_order(s, &(secondary->cache_bitmap_order), true, extraFlags); + IFCALL(secondary->CacheBitmap, context, &(secondary->cache_bitmap_order)); + break; + + case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2: + update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), false, extraFlags); + IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); + break; + + case ORDER_TYPE_BITMAP_COMPRESSED_V2: + update_read_cache_bitmap_v2_order(s, &(secondary->cache_bitmap_v2_order), true, extraFlags); + IFCALL(secondary->CacheBitmapV2, context, &(secondary->cache_bitmap_v2_order)); + break; + + case ORDER_TYPE_BITMAP_COMPRESSED_V3: + update_read_cache_bitmap_v3_order(s, &(secondary->cache_bitmap_v3_order), true, extraFlags); + IFCALL(secondary->CacheBitmapV3, context, &(secondary->cache_bitmap_v3_order)); + break; + + case ORDER_TYPE_CACHE_COLOR_TABLE: + update_read_cache_color_table_order(s, &(secondary->cache_color_table_order), extraFlags); + IFCALL(secondary->CacheColorTable, context, &(secondary->cache_color_table_order)); + break; + + case ORDER_TYPE_CACHE_GLYPH: + if (secondary->glyph_v2) + { + update_read_cache_glyph_v2_order(s, &(secondary->cache_glyph_v2_order), extraFlags); + IFCALL(secondary->CacheGlyphV2, context, &(secondary->cache_glyph_v2_order)); + } + else + { + update_read_cache_glyph_order(s, &(secondary->cache_glyph_order), extraFlags); + IFCALL(secondary->CacheGlyph, context, &(secondary->cache_glyph_order)); + } + break; + + case ORDER_TYPE_CACHE_BRUSH: + update_read_cache_brush_order(s, &(secondary->cache_brush_order), extraFlags); + IFCALL(secondary->CacheBrush, context, &(secondary->cache_brush_order)); + break; + + default: + break; + } + + s->p = next; +} + +void update_recv_altsec_order(rdpUpdate* update, STREAM* s, uint8 flags) +{ + uint8 orderType; + rdpContext* context = update->context; + rdpAltSecUpdate* altsec = update->altsec; + + orderType = flags >>= 2; /* orderType is in higher 6 bits of flags field */ + +#ifdef WITH_DEBUG_ORDERS + if (orderType < ALTSEC_DRAWING_ORDER_COUNT) + printf("%s Alternate Secondary Drawing Order (0x%02X)\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType], orderType); + else + printf("Unknown Alternate Secondary Drawing Order: 0x%02X\n", orderType); +#endif + + switch (orderType) + { + case ORDER_TYPE_CREATE_OFFSCREEN_BITMAP: + update_read_create_offscreen_bitmap_order(s, &(altsec->create_offscreen_bitmap)); + IFCALL(altsec->CreateOffscreenBitmap, context, &(altsec->create_offscreen_bitmap)); + break; + + case ORDER_TYPE_SWITCH_SURFACE: + update_read_switch_surface_order(s, &(altsec->switch_surface)); + IFCALL(altsec->SwitchSurface, context, &(altsec->switch_surface)); + break; + + case ORDER_TYPE_CREATE_NINE_GRID_BITMAP: + update_read_create_nine_grid_bitmap_order(s, &(altsec->create_nine_grid_bitmap)); + IFCALL(altsec->CreateNineGridBitmap, context, &(altsec->create_nine_grid_bitmap)); + break; + + case ORDER_TYPE_FRAME_MARKER: + update_read_frame_marker_order(s, &(altsec->frame_marker)); + IFCALL(altsec->FrameMarker, context, &(altsec->frame_marker)); + break; + + case ORDER_TYPE_STREAM_BITMAP_FIRST: + update_read_stream_bitmap_first_order(s, &(altsec->stream_bitmap_first)); + IFCALL(altsec->StreamBitmapFirst, context, &(altsec->stream_bitmap_first)); + break; + + case ORDER_TYPE_STREAM_BITMAP_NEXT: + update_read_stream_bitmap_next_order(s, &(altsec->stream_bitmap_next)); + IFCALL(altsec->StreamBitmapNext, context, &(altsec->stream_bitmap_next)); + break; + + case ORDER_TYPE_GDIPLUS_FIRST: + update_read_draw_gdiplus_first_order(s, &(altsec->draw_gdiplus_first)); + IFCALL(altsec->DrawGdiPlusFirst, context, &(altsec->draw_gdiplus_first)); + break; + + case ORDER_TYPE_GDIPLUS_NEXT: + update_read_draw_gdiplus_next_order(s, &(altsec->draw_gdiplus_next)); + IFCALL(altsec->DrawGdiPlusNext, context, &(altsec->draw_gdiplus_next)); + break; + + case ORDER_TYPE_GDIPLUS_END: + update_read_draw_gdiplus_end_order(s, &(altsec->draw_gdiplus_end)); + IFCALL(altsec->DrawGdiPlusEnd, context, &(altsec->draw_gdiplus_end)); + break; + + case ORDER_TYPE_GDIPLUS_CACHE_FIRST: + update_read_draw_gdiplus_cache_first_order(s, &(altsec->draw_gdiplus_cache_first)); + IFCALL(altsec->DrawGdiPlusCacheFirst, context, &(altsec->draw_gdiplus_cache_first)); + break; + + case ORDER_TYPE_GDIPLUS_CACHE_NEXT: + update_read_draw_gdiplus_cache_next_order(s, &(altsec->draw_gdiplus_cache_next)); + IFCALL(altsec->DrawGdiPlusCacheNext, context, &(altsec->draw_gdiplus_cache_next)); + break; + + case ORDER_TYPE_GDIPLUS_CACHE_END: + update_read_draw_gdiplus_cache_end_order(s, &(altsec->draw_gdiplus_cache_end)); + IFCALL(altsec->DrawGdiPlusCacheEnd, context, &(altsec->draw_gdiplus_cache_end)); + break; + + case ORDER_TYPE_WINDOW: + update_recv_altsec_window_order(update, s); + break; + + case ORDER_TYPE_COMPDESK_FIRST: + break; + + default: + break; + } +} + +void update_recv_order(rdpUpdate* update, STREAM* s) +{ + uint8 controlFlags; + + stream_read_uint8(s, controlFlags); /* controlFlags (1 byte) */ + + if (!(controlFlags & ORDER_STANDARD)) + update_recv_altsec_order(update, s, controlFlags); + else if (controlFlags & ORDER_SECONDARY) + update_recv_secondary_order(update, s, controlFlags); + else + update_recv_primary_order(update, s, controlFlags); +} + diff --git a/libfreerdp-core/orders.h b/libfreerdp-core/orders.h new file mode 100644 index 0000000..5e85024 --- /dev/null +++ b/libfreerdp-core/orders.h @@ -0,0 +1,233 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Drawing Orders + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ORDERS_H +#define __ORDERS_H + +#include "rdp.h" +#include +#include +#include + +/* Order Control Flags */ +#define ORDER_STANDARD 0x01 +#define ORDER_SECONDARY 0x02 +#define ORDER_BOUNDS 0x04 +#define ORDER_TYPE_CHANGE 0x08 +#define ORDER_DELTA_COORDINATES 0x10 +#define ORDER_ZERO_BOUNDS_DELTAS 0x20 +#define ORDER_ZERO_FIELD_BYTE_BIT0 0x40 +#define ORDER_ZERO_FIELD_BYTE_BIT1 0x80 + +/* Bound Field Flags */ +#define BOUND_LEFT 0x01 +#define BOUND_TOP 0x02 +#define BOUND_RIGHT 0x04 +#define BOUND_BOTTOM 0x08 +#define BOUND_DELTA_LEFT 0x10 +#define BOUND_DELTA_TOP 0x20 +#define BOUND_DELTA_RIGHT 0x40 +#define BOUND_DELTA_BOTTOM 0x80 + +/* Field Presence Flags */ +#define ORDER_FIELD_01 0x000001 +#define ORDER_FIELD_02 0x000002 +#define ORDER_FIELD_03 0x000004 +#define ORDER_FIELD_04 0x000008 +#define ORDER_FIELD_05 0x000010 +#define ORDER_FIELD_06 0x000020 +#define ORDER_FIELD_07 0x000040 +#define ORDER_FIELD_08 0x000080 +#define ORDER_FIELD_09 0x000100 +#define ORDER_FIELD_10 0x000200 +#define ORDER_FIELD_11 0x000400 +#define ORDER_FIELD_12 0x000800 +#define ORDER_FIELD_13 0x001000 +#define ORDER_FIELD_14 0x002000 +#define ORDER_FIELD_15 0x004000 +#define ORDER_FIELD_16 0x008000 +#define ORDER_FIELD_17 0x010000 +#define ORDER_FIELD_18 0x020000 +#define ORDER_FIELD_19 0x040000 +#define ORDER_FIELD_20 0x080000 +#define ORDER_FIELD_21 0x100000 +#define ORDER_FIELD_22 0x200000 +#define ORDER_FIELD_23 0x400000 + +/* Bitmap Cache Flags */ +#define CBR2_8BPP 0x3 +#define CBR2_16BPP 0x4 +#define CBR2_24BPP 0x5 +#define CBR2_32BPP 0x6 + +#define CBR23_8BPP 0x3 +#define CBR23_16BPP 0x4 +#define CBR23_24BPP 0x5 +#define CBR23_32BPP 0x6 + +#define CBR3_IGNORABLE_FLAG 0x08 +#define CBR3_DO_NOT_CACHE 0x10 + +/* Primary Drawing Orders */ +#define ORDER_TYPE_DSTBLT 0x00 +#define ORDER_TYPE_PATBLT 0x01 +#define ORDER_TYPE_SCRBLT 0x02 +#define ORDER_TYPE_DRAW_NINE_GRID 0x07 +#define ORDER_TYPE_MULTI_DRAW_NINE_GRID 0x08 +#define ORDER_TYPE_LINE_TO 0x09 +#define ORDER_TYPE_OPAQUE_RECT 0x0A +#define ORDER_TYPE_SAVE_BITMAP 0x0B +#define ORDER_TYPE_MEMBLT 0x0D +#define ORDER_TYPE_MEM3BLT 0x0E +#define ORDER_TYPE_MULTI_DSTBLT 0x0F +#define ORDER_TYPE_MULTI_PATBLT 0x10 +#define ORDER_TYPE_MULTI_SCRBLT 0x11 +#define ORDER_TYPE_MULTI_OPAQUE_RECT 0x12 +#define ORDER_TYPE_FAST_INDEX 0x13 +#define ORDER_TYPE_POLYGON_SC 0x14 +#define ORDER_TYPE_POLYGON_CB 0x15 +#define ORDER_TYPE_POLYLINE 0x16 +#define ORDER_TYPE_FAST_GLYPH 0x18 +#define ORDER_TYPE_ELLIPSE_SC 0x19 +#define ORDER_TYPE_ELLIPSE_CB 0x1A +#define ORDER_TYPE_GLYPH_INDEX 0x1B + +/* Primary Drawing Orders Fields */ +#define DSTBLT_ORDER_FIELDS 5 +#define PATBLT_ORDER_FIELDS 12 +#define SCRBLT_ORDER_FIELDS 7 +#define DRAW_NINE_GRID_ORDER_FIELDS 5 +#define MULTI_DRAW_NINE_GRID_ORDER_FIELDS 7 +#define LINE_TO_ORDER_FIELDS 10 +#define OPAQUE_RECT_ORDER_FIELDS 7 +#define SAVE_BITMAP_ORDER_FIELDS 6 +#define MEMBLT_ORDER_FIELDS 9 +#define MEM3BLT_ORDER_FIELDS 16 +#define MULTI_DSTBLT_ORDER_FIELDS 7 +#define MULTI_PATBLT_ORDER_FIELDS 14 +#define MULTI_SCRBLT_ORDER_FIELDS 9 +#define MULTI_OPAQUE_RECT_ORDER_FIELDS 9 +#define FAST_INDEX_ORDER_FIELDS 15 +#define POLYGON_SC_ORDER_FIELDS 7 +#define POLYGON_CB_ORDER_FIELDS 13 +#define POLYLINE_ORDER_FIELDS 7 +#define FAST_GLYPH_ORDER_FIELDS 15 +#define ELLIPSE_SC_ORDER_FIELDS 7 +#define ELLIPSE_CB_ORDER_FIELDS 13 +#define GLYPH_INDEX_ORDER_FIELDS 22 + +/* Primary Drawing Orders Field Bytes */ +#define DSTBLT_ORDER_FIELD_BYTES 1 +#define PATBLT_ORDER_FIELD_BYTES 2 +#define SCRBLT_ORDER_FIELD_BYTES 1 +#define DRAW_NINE_GRID_ORDER_FIELD_BYTES 1 +#define MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES 1 +#define LINE_TO_ORDER_FIELD_BYTES 2 +#define OPAQUE_RECT_ORDER_FIELD_BYTES 1 +#define SAVE_BITMAP_ORDER_FIELD_BYTES 1 +#define MEMBLT_ORDER_FIELD_BYTES 2 +#define MEM3BLT_ORDER_FIELD_BYTES 3 +#define MULTI_DSTBLT_ORDER_FIELD_BYTES 1 +#define MULTI_PATBLT_ORDER_FIELD_BYTES 2 +#define MULTI_SCRBLT_ORDER_FIELD_BYTES 2 +#define MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES 2 +#define FAST_INDEX_ORDER_FIELD_BYTES 2 +#define POLYGON_SC_ORDER_FIELD_BYTES 1 +#define POLYGON_CB_ORDER_FIELD_BYTES 2 +#define POLYLINE_ORDER_FIELD_BYTES 1 +#define FAST_GLYPH_ORDER_FIELD_BYTES 2 +#define ELLIPSE_SC_ORDER_FIELD_BYTES 1 +#define ELLIPSE_CB_ORDER_FIELD_BYTES 2 +#define GLYPH_INDEX_ORDER_FIELD_BYTES 3 + +/* Secondary Drawing Orders */ +#define ORDER_TYPE_BITMAP_UNCOMPRESSED 0x00 +#define ORDER_TYPE_CACHE_COLOR_TABLE 0x01 +#define ORDER_TYPE_CACHE_BITMAP_COMPRESSED 0x02 +#define ORDER_TYPE_CACHE_GLYPH 0x03 +#define ORDER_TYPE_BITMAP_UNCOMPRESSED_V2 0x04 +#define ORDER_TYPE_BITMAP_COMPRESSED_V2 0x05 +#define ORDER_TYPE_CACHE_BRUSH 0x07 +#define ORDER_TYPE_BITMAP_COMPRESSED_V3 0x08 + +/* Alternate Secondary Drawing Orders */ +#define ORDER_TYPE_SWITCH_SURFACE 0x00 +#define ORDER_TYPE_CREATE_OFFSCREEN_BITMAP 0x01 +#define ORDER_TYPE_STREAM_BITMAP_FIRST 0x02 +#define ORDER_TYPE_STREAM_BITMAP_NEXT 0x03 +#define ORDER_TYPE_CREATE_NINE_GRID_BITMAP 0x04 +#define ORDER_TYPE_GDIPLUS_FIRST 0x05 +#define ORDER_TYPE_GDIPLUS_NEXT 0x06 +#define ORDER_TYPE_GDIPLUS_END 0x07 +#define ORDER_TYPE_GDIPLUS_CACHE_FIRST 0x08 +#define ORDER_TYPE_GDIPLUS_CACHE_NEXT 0x09 +#define ORDER_TYPE_GDIPLUS_CACHE_END 0x0A +#define ORDER_TYPE_WINDOW 0x0B +#define ORDER_TYPE_COMPDESK_FIRST 0x0C +#define ORDER_TYPE_FRAME_MARKER 0x0D + +#define CG_GLYPH_UNICODE_PRESENT 0x0010 + +void update_recv_order(rdpUpdate* update, STREAM* s); + +void update_read_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, DSTBLT_ORDER* dstblt); +void update_read_patblt_order(STREAM* s, ORDER_INFO* orderInfo, PATBLT_ORDER* patblt); +void update_read_scrblt_order(STREAM* s, ORDER_INFO* orderInfo, SCRBLT_ORDER* scrblt); +void update_read_opaque_rect_order(STREAM* s, ORDER_INFO* orderInfo, OPAQUE_RECT_ORDER* opaque_rect); +void update_read_draw_nine_grid_order(STREAM* s, ORDER_INFO* orderInfo, DRAW_NINE_GRID_ORDER* draw_nine_grid); +void update_read_multi_dstblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_DSTBLT_ORDER* multi_dstblt); +void update_read_multi_patblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_PATBLT_ORDER* multi_patblt); +void update_read_multi_scrblt_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_SCRBLT_ORDER* multi_scrblt); +void update_read_multi_opaque_rect_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect); +void update_read_multi_draw_nine_grid_order(STREAM* s, ORDER_INFO* orderInfo, MULTI_DRAW_NINE_GRID_ORDER* multi_draw_nine_grid); +void update_read_line_to_order(STREAM* s, ORDER_INFO* orderInfo, LINE_TO_ORDER* line_to); +void update_read_polyline_order(STREAM* s, ORDER_INFO* orderInfo, POLYLINE_ORDER* polyline); +void update_read_memblt_order(STREAM* s, ORDER_INFO* orderInfo, MEMBLT_ORDER* memblt); +void update_read_mem3blt_order(STREAM* s, ORDER_INFO* orderInfo, MEM3BLT_ORDER* mem3blt); +void update_read_save_bitmap_order(STREAM* s, ORDER_INFO* orderInfo, SAVE_BITMAP_ORDER* save_bitmap); +void update_read_glyph_index_order(STREAM* s, ORDER_INFO* orderInfo, GLYPH_INDEX_ORDER* glyph_index); +void update_read_fast_index_order(STREAM* s, ORDER_INFO* orderInfo, FAST_INDEX_ORDER* fast_index); +void update_read_fast_glyph_order(STREAM* s, ORDER_INFO* orderInfo, FAST_GLYPH_ORDER* fast_glyph); +void update_read_polygon_sc_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_SC_ORDER* polygon_sc); +void update_read_polygon_cb_order(STREAM* s, ORDER_INFO* orderInfo, POLYGON_CB_ORDER* polygon_cb); +void update_read_ellipse_sc_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_SC_ORDER* ellipse_sc); +void update_read_ellipse_cb_order(STREAM* s, ORDER_INFO* orderInfo, ELLIPSE_CB_ORDER* ellipse_cb); + +void update_read_cache_bitmap_order(STREAM* s, CACHE_BITMAP_ORDER* cache_bitmap_order, boolean compressed, uint16 flags); +void update_read_cache_bitmap_v2_order(STREAM* s, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2_order, boolean compressed, uint16 flags); +void update_read_cache_bitmap_v3_order(STREAM* s, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3_order, boolean compressed, uint16 flags); +void update_read_cache_color_table_order(STREAM* s, CACHE_COLOR_TABLE_ORDER* cache_color_table_order, uint16 flags); +void update_read_cache_glyph_order(STREAM* s, CACHE_GLYPH_ORDER* cache_glyph_order, uint16 flags); +void update_read_cache_glyph_v2_order(STREAM* s, CACHE_GLYPH_V2_ORDER* cache_glyph_v2_order, uint16 flags); +void update_read_cache_brush_order(STREAM* s, CACHE_BRUSH_ORDER* cache_brush_order, uint16 flags); + +void update_read_create_offscreen_bitmap_order(STREAM* s, CREATE_OFFSCREEN_BITMAP_ORDER* create_offscreen_bitmap); +void update_read_switch_surface_order(STREAM* s, SWITCH_SURFACE_ORDER* switch_surface); +void update_read_create_nine_grid_bitmap_order(STREAM* s, CREATE_NINE_GRID_BITMAP_ORDER* create_nine_grid_bitmap); +void update_read_frame_marker_order(STREAM* s, FRAME_MARKER_ORDER* frame_marker); +void update_read_stream_bitmap_first_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_first); +void update_read_stream_bitmap_next_order(STREAM* s, STREAM_BITMAP_FIRST_ORDER* stream_bitmap_next); +void update_read_draw_gdiplus_first_order(STREAM* s, DRAW_GDIPLUS_FIRST_ORDER* draw_gdiplus_first); +void update_read_draw_gdiplus_next_order(STREAM* s, DRAW_GDIPLUS_NEXT_ORDER* draw_gdiplus_next); +void update_read_draw_gdiplus_end_order(STREAM* s, DRAW_GDIPLUS_END_ORDER* draw_gdiplus_end); +void update_read_draw_gdiplus_cache_first_order(STREAM* s, DRAW_GDIPLUS_CACHE_FIRST_ORDER* draw_gdiplus_cache_first); +void update_read_draw_gdiplus_cache_next_order(STREAM* s, DRAW_GDIPLUS_CACHE_NEXT_ORDER* draw_gdiplus_cache_next); +void update_read_draw_gdiplus_cache_end_order(STREAM* s, DRAW_GDIPLUS_CACHE_END_ORDER* draw_gdiplus_cache_end); + +#endif /* __ORDERS_H */ diff --git a/libfreerdp-core/peer.c b/libfreerdp-core/peer.c new file mode 100644 index 0000000..01253e5 --- /dev/null +++ b/libfreerdp-core/peer.c @@ -0,0 +1,355 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Peer + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "peer.h" + +static boolean freerdp_peer_initialize(freerdp_peer* client) +{ + client->context->rdp->settings->server_mode = true; + client->context->rdp->state = CONNECTION_STATE_INITIAL; + if (client->context->rdp->settings->rdp_key_file != NULL) { + client->context->rdp->settings->server_key = + key_new(client->context->rdp->settings->rdp_key_file); + } + + return true; +} + +static boolean freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) +{ + rfds[*rcount] = (void*)(long)(client->context->rdp->transport->tcp->sockfd); + (*rcount)++; + + return true; +} + +static boolean freerdp_peer_check_fds(freerdp_peer* client) +{ + rdpRdp* rdp; + int status; + + rdp = client->context->rdp; + + status = rdp_check_fds(rdp); + if (status < 0) + return false; + + return true; +} + +static boolean peer_recv_data_pdu(freerdp_peer* client, STREAM* s) +{ + uint8 type; + uint16 length; + uint32 share_id; + uint8 compressed_type; + uint16 compressed_len; + + + if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) + return false; + + switch (type) + { + case DATA_PDU_TYPE_SYNCHRONIZE: + if (!rdp_recv_client_synchronize_pdu(client->context->rdp, s)) + return false; + break; + + case DATA_PDU_TYPE_CONTROL: + if (!rdp_server_accept_client_control_pdu(client->context->rdp, s)) + return false; + break; + + case DATA_PDU_TYPE_INPUT: + if (!input_recv(client->context->rdp->input, s)) + return false; + break; + + case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: + /* TODO: notify server bitmap cache data */ + break; + + case DATA_PDU_TYPE_FONT_LIST: + if (!rdp_server_accept_client_font_list_pdu(client->context->rdp, s)) + return false; + if (client->PostConnect) + { + if (!client->PostConnect(client)) + return false; + /** + * PostConnect should only be called once and should not be called + * after a reactivation sequence. + */ + client->PostConnect = NULL; + } + if (client->Activate) + { + /* Activate will be called everytime after the client is activated/reactivated. */ + if (!client->Activate(client)) + return false; + } + break; + + case DATA_PDU_TYPE_SHUTDOWN_REQUEST: + mcs_send_disconnect_provider_ultimatum(client->context->rdp->mcs); + return false; + + default: + printf("Data PDU type %d\n", type); + break; + } + + return true; +} + +static boolean peer_recv_tpkt_pdu(freerdp_peer* client, STREAM* s) +{ + rdpRdp *rdp; + uint16 length; + uint16 pduType; + uint16 pduLength; + uint16 pduSource; + uint16 channelId; + uint16 securityFlags; + + rdp = client->context->rdp; + + if (!rdp_read_header(rdp, s, &length, &channelId)) + { + printf("Incorrect RDP header.\n"); + return false; + } + + if (rdp->settings->encryption) + { + rdp_read_security_header(s, &securityFlags); + if (securityFlags & SEC_ENCRYPT) + { + if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return false; + } + } + } + + if (channelId != MCS_GLOBAL_CHANNEL_ID) + { + freerdp_channel_peer_process(client, s, channelId); + } + else + { + if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) + return false; + + client->settings->pdu_source = pduSource; + + switch (pduType) + { + case PDU_TYPE_DATA: + if (!peer_recv_data_pdu(client, s)) + return false; + break; + + default: + printf("Client sent pduType %d\n", pduType); + return false; + } + } + + return true; +} + +static boolean peer_recv_fastpath_pdu(freerdp_peer* client, STREAM* s) +{ + uint16 length; + rdpRdp* rdp; + rdpFastPath* fastpath; + + rdp = client->context->rdp; + fastpath = rdp->fastpath; + length = fastpath_read_header_rdp(fastpath, s); + + if (length == 0 || length > stream_get_left(s)) + { + printf("incorrect FastPath PDU header length %d\n", length); + return false; + } + + if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED) + { + rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0); + } + + return fastpath_recv_inputs(fastpath, s); +} + +static boolean peer_recv_pdu(freerdp_peer* client, STREAM* s) +{ + if (tpkt_verify_header(s)) + return peer_recv_tpkt_pdu(client, s); + else + return peer_recv_fastpath_pdu(client, s); +} + +static boolean peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra) +{ + freerdp_peer* client = (freerdp_peer*) extra; + + switch (client->context->rdp->state) + { + case CONNECTION_STATE_INITIAL: + if (!rdp_server_accept_nego(client->context->rdp, s)) + return false; + break; + + case CONNECTION_STATE_NEGO: + if (!rdp_server_accept_mcs_connect_initial(client->context->rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_CONNECT: + if (!rdp_server_accept_mcs_erect_domain_request(client->context->rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_ERECT_DOMAIN: + if (!rdp_server_accept_mcs_attach_user_request(client->context->rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_ATTACH_USER: + if (!rdp_server_accept_mcs_channel_join_request(client->context->rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_CHANNEL_JOIN: + if (client->context->rdp->settings->encryption) { + if (!rdp_server_accept_client_keys(client->context->rdp, s)) + return false; + break; + } + client->context->rdp->state = CONNECTION_STATE_ESTABLISH_KEYS; + /* FALLTHROUGH */ + + case CONNECTION_STATE_ESTABLISH_KEYS: + if (!rdp_server_accept_client_info(client->context->rdp, s)) + return false; + IFCALL(client->Capabilities, client); + if (!rdp_send_demand_active(client->context->rdp)) + return false; + break; + + case CONNECTION_STATE_LICENSE: + if (!rdp_server_accept_confirm_active(client->context->rdp, s)) + { + /** + * During reactivation sequence the client might sent some input or channel data + * before receiving the Deactivate All PDU. We need to process them as usual. + */ + stream_set_pos(s, 0); + return peer_recv_pdu(client, s); + } + break; + + case CONNECTION_STATE_ACTIVE: + if (!peer_recv_pdu(client, s)) + return false; + break; + + default: + printf("Invalid state %d\n", client->context->rdp->state); + return false; + } + + return true; +} + +static void freerdp_peer_disconnect(freerdp_peer* client) +{ + transport_disconnect(client->context->rdp->transport); +} + +static int freerdp_peer_send_channel_data(freerdp_peer* client, int channelId, uint8* data, int size) +{ + return rdp_send_channel_data(client->context->rdp, channelId, data, size); +} + +void freerdp_peer_context_new(freerdp_peer* client) +{ + rdpRdp* rdp; + + rdp = rdp_new(NULL); + client->input = rdp->input; + client->update = rdp->update; + client->settings = rdp->settings; + + client->context = (rdpContext*) xzalloc(client->context_size); + client->context->rdp = rdp; + client->context->peer = client; + + client->update->context = client->context; + client->input->context = client->context; + + update_register_server_callbacks(client->update); + + transport_attach(rdp->transport, client->sockfd); + + rdp->transport->recv_callback = peer_recv_callback; + rdp->transport->recv_extra = client; + transport_set_blocking_mode(rdp->transport, false); + + IFCALL(client->ContextNew, client, client->context); +} + +void freerdp_peer_context_free(freerdp_peer* client) +{ + IFCALL(client->ContextFree, client, client->context); +} + +freerdp_peer* freerdp_peer_new(int sockfd) +{ + freerdp_peer* client; + + client = xnew(freerdp_peer); + + if (client != NULL) + { + client->sockfd = sockfd; + client->context_size = sizeof(rdpContext); + client->Initialize = freerdp_peer_initialize; + client->GetFileDescriptor = freerdp_peer_get_fds; + client->CheckFileDescriptor = freerdp_peer_check_fds; + client->Disconnect = freerdp_peer_disconnect; + client->SendChannelData = freerdp_peer_send_channel_data; + } + + return client; +} + +void freerdp_peer_free(freerdp_peer* client) +{ + if (client) + { + rdp_free(client->context->rdp); + xfree(client); + } +} + diff --git a/libfreerdp-core/peer.h b/libfreerdp-core/peer.h new file mode 100644 index 0000000..eb9ed63 --- /dev/null +++ b/libfreerdp-core/peer.h @@ -0,0 +1,27 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * RDP Server Peer + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PEER +#define __PEER + +#include "rdp.h" +#include + +#endif /* __PEER */ + diff --git a/libfreerdp-core/per.c b/libfreerdp-core/per.c new file mode 100644 index 0000000..aa4d1d0 --- /dev/null +++ b/libfreerdp-core/per.c @@ -0,0 +1,455 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * ASN.1 Packed Encoding Rules (BER) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "per.h" + +/** + * Read PER length. + * @param s stream + * @param length length + * @return + */ + +boolean per_read_length(STREAM* s, uint16* length) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte & 0x80) + { + byte &= ~(0x80); + *length = (byte << 8); + stream_read_uint8(s, byte); + *length += byte; + } + else + { + *length = byte; + } + + return true; +} + +/** + * Write PER length. + * @param s stream + * @param length length + */ + +void per_write_length(STREAM* s, int length) +{ + if (length > 0x7F) + stream_write_uint16_be(s, (length | 0x8000)); + else + stream_write_uint8(s, length); +} + +/** + * Read PER choice. + * @param s stream + * @param choice choice + * @return + */ + +boolean per_read_choice(STREAM* s, uint8* choice) +{ + stream_read_uint8(s, *choice); + return true; +} + +/** + * Write PER CHOICE. + * @param s stream + * @param choice index of chosen field + */ + +void per_write_choice(STREAM* s, uint8 choice) +{ + stream_write_uint8(s, choice); +} + +/** + * Read PER selection. + * @param s stream + * @param selection selection + * @return + */ + +boolean per_read_selection(STREAM* s, uint8* selection) +{ + stream_read_uint8(s, *selection); + return true; +} + +/** + * Write PER selection for OPTIONAL fields. + * @param s stream + * @param selection bit map of selected fields + */ + +void per_write_selection(STREAM* s, uint8 selection) +{ + stream_write_uint8(s, selection); +} + +/** + * Read PER number of sets. + * @param s stream + * @param number number of sets + * @return + */ + +boolean per_read_number_of_sets(STREAM* s, uint8* number) +{ + stream_read_uint8(s, *number); + return true; +} + +/** + * Write PER number of sets for SET OF. + * @param s stream + * @param number number of sets + */ + +void per_write_number_of_sets(STREAM* s, uint8 number) +{ + stream_write_uint8(s, number); +} + +/** + * Read PER padding with zeros. + * @param s stream + * @param length + */ + +boolean per_read_padding(STREAM* s, int length) +{ + stream_seek(s, length); + + return true; +} + +/** + * Write PER padding with zeros. + * @param s stream + * @param length + */ + +void per_write_padding(STREAM* s, int length) +{ + int i; + + for (i = 0; i < length; i++) + stream_write_uint8(s, 0); +} + +/** + * Read PER INTEGER. + * @param s stream + * @param integer integer + * @return + */ + +boolean per_read_integer(STREAM* s, uint32* integer) +{ + uint16 length; + + per_read_length(s, &length); + + if (length == 1) + stream_read_uint8(s, *integer); + else if (length == 2) + stream_read_uint16_be(s, *integer); + else + return false; + + return true; +} + +/** + * Write PER INTEGER. + * @param s stream + * @param integer integer + */ + +void per_write_integer(STREAM* s, uint32 integer) +{ + if (integer <= 0xFF) + { + per_write_length(s, 1); + stream_write_uint8(s, integer); + } + else if (integer <= 0xFFFF) + { + per_write_length(s, 2); + stream_write_uint16_be(s, integer); + } + else if (integer <= 0xFFFFFFFF) + { + per_write_length(s, 4); + stream_write_uint32_be(s, integer); + } +} + +/** + * Read PER INTEGER (uint16). + * @param s stream + * @param integer integer + * @param min minimum value + * @return + */ + +boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min) +{ + stream_read_uint16_be(s, *integer); + + if (*integer + min > 0xFFFF) + return false; + + *integer += min; + + return true; +} + +/** + * Write PER INTEGER (uint16). + * @param s stream + * @param integer integer + * @param min minimum value + */ + +void per_write_integer16(STREAM* s, uint16 integer, uint16 min) +{ + stream_write_uint16_be(s, integer - min); +} + +/** + * Read PER ENUMERATED. + * @param s stream + * @param enumerated enumerated + * @param count enumeration count + * @return + */ + +boolean per_read_enumerated(STREAM* s, uint8* enumerated, uint8 count) +{ + stream_read_uint8(s, *enumerated); + + /* check that enumerated value falls within expected range */ + if (*enumerated + 1 > count) + return false; + + return true; +} + +/** + * Write PER ENUMERATED. + * @param s stream + * @param enumerated enumerated + * @param count enumeration count + * @return + */ + +void per_write_enumerated(STREAM* s, uint8 enumerated, uint8 count) +{ + stream_write_uint8(s, enumerated); +} + +/** + * Read PER OBJECT_IDENTIFIER (OID). + * @param s stream + * @param oid object identifier (OID) + * @return + */ + +boolean per_read_object_identifier(STREAM* s, uint8 oid[6]) +{ + uint8 t12; + uint16 length; + uint8 a_oid[6]; + + + per_read_length(s, &length); /* length */ + + if (length != 5) + return false; + + stream_read_uint8(s, t12); /* first two tuples */ + a_oid[0] = (t12 >> 4); + a_oid[1] = (t12 & 0x0F); + + stream_read_uint8(s, a_oid[2]); /* tuple 3 */ + stream_read_uint8(s, a_oid[3]); /* tuple 4 */ + stream_read_uint8(s, a_oid[4]); /* tuple 5 */ + stream_read_uint8(s, a_oid[5]); /* tuple 6 */ + + if ((a_oid[0] == oid[0]) && (a_oid[1] == oid[1]) && + (a_oid[2] == oid[2]) && (a_oid[3] == oid[3]) && + (a_oid[4] == oid[4]) && (a_oid[5] == oid[5])) + { + return true; + } + else + { + return false; + } +} + +/** + * Write PER OBJECT_IDENTIFIER (OID) + * @param s stream + * @param oid object identifier (oid) + */ + +void per_write_object_identifier(STREAM* s, uint8 oid[6]) +{ + uint8 t12 = (oid[0] << 4) & (oid[1] & 0x0F); + stream_write_uint8(s, 5); /* length */ + stream_write_uint8(s, t12); /* first two tuples */ + stream_write_uint8(s, oid[2]); /* tuple 3 */ + stream_write_uint8(s, oid[3]); /* tuple 4 */ + stream_write_uint8(s, oid[4]); /* tuple 5 */ + stream_write_uint8(s, oid[5]); /* tuple 6 */ +} + +/** + * Write PER string. + * @param s stream + * @param str string + * @param length string length + */ + +void per_write_string(STREAM* s, uint8* str, int length) +{ + int i; + + for (i = 0; i < length; i++) + stream_write_uint8(s, str[i]); +} + +/** + * Read PER OCTET_STRING. + * @param s stream + * @param oct_str octet string + * @param length string length + * @param min minimum length + * @return + */ + +boolean per_read_octet_string(STREAM* s, uint8* oct_str, int length, int min) +{ + int i; + uint16 mlength; + uint8* a_oct_str; + + per_read_length(s, &mlength); + + if (mlength + min != length) + return false; + + a_oct_str = s->p; + stream_seek(s, length); + + for (i = 0; i < length; i++) + { + if (a_oct_str[i] != oct_str[i]) + return false; + } + + return true; +} + +/** + * Write PER OCTET_STRING + * @param s stream + * @param oct_str octet string + * @param length string length + * @param min minimum string length + */ + +void per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min) +{ + int i; + int mlength; + + mlength = (length - min >= 0) ? length - min : min; + + per_write_length(s, mlength); + + for (i = 0; i < length; i++) + stream_write_uint8(s, oct_str[i]); +} + +/** + * Read PER NumericString. + * @param s stream + * @param num_str numeric string + * @param length string length + * @param min minimum string length + */ + +boolean per_read_numeric_string(STREAM* s, int min) +{ + int i; + int length; + uint16 mlength; + + per_read_length(s, &mlength); + + length = mlength + min; + + for (i = 0; i < length; i += 2) + { + stream_seek(s, 1); + } + + return true; +} + +/** + * Write PER NumericString. + * @param s stream + * @param num_str numeric string + * @param length string length + * @param min minimum string length + */ + +void per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min) +{ + int i; + int mlength; + uint8 num, c1, c2; + + mlength = (length - min >= 0) ? length - min : min; + + per_write_length(s, mlength); + + for (i = 0; i < length; i += 2) + { + c1 = num_str[i]; + c2 = ((i + 1) < length) ? num_str[i + 1] : 0x30; + + c1 = (c1 - 0x30) % 10; + c2 = (c2 - 0x30) % 10; + num = (c1 << 4) | c2; + + stream_write_uint8(s, num); /* string */ + } +} diff --git a/libfreerdp-core/per.h b/libfreerdp-core/per.h new file mode 100644 index 0000000..f246cfe --- /dev/null +++ b/libfreerdp-core/per.h @@ -0,0 +1,48 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * ASN.1 Packed Encoding Rules (BER) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PER_H +#define __PER_H + +#include + +boolean per_read_length(STREAM* s, uint16* length); +void per_write_length(STREAM* s, int length); +boolean per_read_choice(STREAM* s, uint8* choice); +void per_write_choice(STREAM* s, uint8 choice); +boolean per_read_selection(STREAM* s, uint8* selection); +void per_write_selection(STREAM* s, uint8 selection); +boolean per_read_number_of_sets(STREAM* s, uint8* number); +void per_write_number_of_sets(STREAM* s, uint8 number); +boolean per_read_padding(STREAM* s, int length); +void per_write_padding(STREAM* s, int length); +boolean per_read_integer(STREAM* s, uint32* integer); +boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min); +void per_write_integer(STREAM* s, uint32 integer); +void per_write_integer16(STREAM* s, uint16 integer, uint16 min); +boolean per_read_enumerated(STREAM* s, uint8* enumerated, uint8 count); +void per_write_enumerated(STREAM* s, uint8 enumerated, uint8 count); +void per_write_object_identifier(STREAM* s, uint8 oid[6]); +boolean per_read_object_identifier(STREAM* s, uint8 oid[6]); +boolean per_read_octet_string(STREAM* s, uint8* oct_str, int length, int min); +void per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min); +boolean per_read_numeric_string(STREAM* s, int min); +void per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min); + +#endif /* __PER_H */ diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c new file mode 100644 index 0000000..8d499e8 --- /dev/null +++ b/libfreerdp-core/rdp.c @@ -0,0 +1,919 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Core + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdp.h" + +#include "info.h" +#include "per.h" +#include "redirection.h" + +static const char* const DATA_PDU_TYPE_STRINGS[] = +{ + "", "", /* 0x00 - 0x01 */ + "Update", /* 0x02 */ + "", "", "", "", "", "", "", "", /* 0x03 - 0x0A */ + "", "", "", "", "", "", "", "", "", /* 0x0B - 0x13 */ + "Control", /* 0x14 */ + "", "", "", "", "", "", /* 0x15 - 0x1A */ + "Pointer", /* 0x1B */ + "Input", /* 0x1C */ + "", "", /* 0x1D - 0x1E */ + "Synchronize", /* 0x1F */ + "", /* 0x20 */ + "Refresh Rect", /* 0x21 */ + "Play Sound", /* 0x22 */ + "Suppress Output", /* 0x23 */ + "Shutdown Request", /* 0x24 */ + "Shutdown Denied", /* 0x25 */ + "Save Session Info", /* 0x26 */ + "Font List", /* 0x27 */ + "Font Map", /* 0x28 */ + "Set Keyboard Indicators", /* 0x29 */ + "", /* 0x2A */ + "Bitmap Cache Persistent List", /* 0x2B */ + "Bitmap Cache Error", /* 0x2C */ + "Set Keyboard IME Status", /* 0x2D */ + "Offscreen Cache Error", /* 0x2E */ + "Set Error Info", /* 0x2F */ + "Draw Nine Grid Error", /* 0x30 */ + "Draw GDI+ Error", /* 0x31 */ + "ARC Status", /* 0x32 */ + "", "", "", /* 0x33 - 0x35 */ + "Status Info", /* 0x36 */ + "Monitor Layout" /* 0x37 */ + "", "", "", /* 0x38 - 0x40 */ + "", "", "", "", "", "" /* 0x41 - 0x46 */ +}; + +/** + * Read RDP Security Header.\n + * @msdn{cc240579} + * @param s stream + * @param flags security flags + */ + +void rdp_read_security_header(STREAM* s, uint16* flags) +{ + /* Basic Security Header */ + stream_read_uint16(s, *flags); /* flags */ + stream_seek(s, 2); /* flagsHi (unused) */ +} + +/** + * Write RDP Security Header.\n + * @msdn{cc240579} + * @param s stream + * @param flags security flags + */ + +void rdp_write_security_header(STREAM* s, uint16 flags) +{ + /* Basic Security Header */ + stream_write_uint16(s, flags); /* flags */ + stream_write_uint16(s, 0); /* flagsHi (unused) */ +} + +boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id) +{ + /* Share Control Header */ + stream_read_uint16(s, *length); /* totalLength */ + + if (*length - 2 > stream_get_left(s)) + return false; + + stream_read_uint16(s, *type); /* pduType */ + *type &= 0x0F; /* type is in the 4 least significant bits */ + + if (*length > 4) + stream_read_uint16(s, *channel_id); /* pduSource */ + else /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ + *channel_id = 0; + + return true; +} + +void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint16 channel_id) +{ + length -= RDP_PACKET_HEADER_MAX_LENGTH; + + /* Share Control Header */ + stream_write_uint16(s, length); /* totalLength */ + stream_write_uint16(s, type | 0x10); /* pduType */ + stream_write_uint16(s, channel_id); /* pduSource */ +} + +boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id, + uint8 *compressed_type, uint16 *compressed_len) +{ + if (stream_get_left(s) < 12) + return false; + + /* Share Data Header */ + stream_read_uint32(s, *share_id); /* shareId (4 bytes) */ + stream_seek_uint8(s); /* pad1 (1 byte) */ + stream_seek_uint8(s); /* streamId (1 byte) */ + stream_read_uint16(s, *length); /* uncompressedLength (2 bytes) */ + stream_read_uint8(s, *type); /* pduType2, Data PDU Type (1 byte) */ + + if (*type & 0x80) + { + stream_read_uint8(s, *compressed_type); /* compressedType (1 byte) */ + stream_read_uint16(s, *compressed_len); /* compressedLength (2 bytes) */ + } + else + { + stream_seek(s, 3); + *compressed_type = 0; + *compressed_len = 0; + } + + return true; +} + +void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 share_id) +{ + length -= RDP_PACKET_HEADER_MAX_LENGTH; + length -= RDP_SHARE_CONTROL_HEADER_LENGTH; + length -= RDP_SHARE_DATA_HEADER_LENGTH; + + /* Share Data Header */ + stream_write_uint32(s, share_id); /* shareId (4 bytes) */ + stream_write_uint8(s, 0); /* pad1 (1 byte) */ + stream_write_uint8(s, STREAM_LOW); /* streamId (1 byte) */ + stream_write_uint16(s, length); /* uncompressedLength (2 bytes) */ + stream_write_uint8(s, type); /* pduType2, Data PDU Type (1 byte) */ + stream_write_uint8(s, 0); /* compressedType (1 byte) */ + stream_write_uint16(s, 0); /* compressedLength (2 bytes) */ +} + +static int rdp_security_stream_init(rdpRdp* rdp, STREAM* s) +{ + if (rdp->do_crypt) + { + stream_seek(s, 12); + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + stream_seek(s, 4); + rdp->sec_flags |= SEC_ENCRYPT; + if (rdp->do_secure_checksum) + rdp->sec_flags |= SEC_SECURE_CHECKSUM; + } + else if (rdp->sec_flags != 0) + { + stream_seek(s, 4); + } + return 0; +} + +/** + * Initialize an RDP packet stream.\n + * @param rdp rdp module + * @return + */ + +STREAM* rdp_send_stream_init(rdpRdp* rdp) +{ + STREAM* s; + + s = transport_send_stream_init(rdp->transport, 2048); + stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_security_stream_init(rdp, s); + + return s; +} + +STREAM* rdp_pdu_init(rdpRdp* rdp) +{ + STREAM* s; + s = transport_send_stream_init(rdp->transport, 2048); + stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_security_stream_init(rdp, s); + stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); + return s; +} + +STREAM* rdp_data_pdu_init(rdpRdp* rdp) +{ + STREAM* s; + s = transport_send_stream_init(rdp->transport, 2048); + stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_security_stream_init(rdp, s); + stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); + stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH); + return s; +} + +/** + * Read an RDP packet header.\n + * @param rdp rdp module + * @param s stream + * @param length RDP packet length + * @param channel_id channel id + */ + +boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_id) +{ + uint16 initiator; + enum DomainMCSPDU MCSPDU; + + MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataRequest : DomainMCSPDU_SendDataIndication; + mcs_read_domain_mcspdu_header(s, &MCSPDU, length); + + if (*length - 8 > stream_get_left(s)) + return false; + + if (MCSPDU == DomainMCSPDU_DisconnectProviderUltimatum) + { + uint8 reason; + + (void) per_read_enumerated(s, &reason, 0); + + rdp->disconnect = true; + + return true; + } + + per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + per_read_integer16(s, channel_id, 0); /* channelId */ + stream_seek(s, 1); /* dataPriority + Segmentation (0x70) */ + per_read_length(s, length); /* userData (OCTET_STRING) */ + + if (*length > stream_get_left(s)) + return false; + + return true; +} + +/** + * Write an RDP packet header.\n + * @param rdp rdp module + * @param s stream + * @param length RDP packet length + * @param channel_id channel id + */ + +void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id) +{ + int body_length; + enum DomainMCSPDU MCSPDU; + + MCSPDU = (rdp->settings->server_mode) ? DomainMCSPDU_SendDataIndication : DomainMCSPDU_SendDataRequest; + + if ((rdp->sec_flags & SEC_ENCRYPT) && (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)) + { + int pad; + + body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16; + pad = 8 - (body_length % 8); + if (pad != 8) + length += pad; + } + + mcs_write_domain_mcspdu_header(s, MCSPDU, length, 0); + per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */ + per_write_integer16(s, channel_id, 0); /* channelId */ + stream_write_uint8(s, 0x70); /* dataPriority + segmentation */ + /* + * We always encode length in two bytes, eventhough we could use + * only one byte if length <= 0x7F. It is just easier that way, + * because we can leave room for fixed-length header, store all + * the data first and then store the header. + */ + length = (length - RDP_PACKET_HEADER_MAX_LENGTH) | 0x8000; + stream_write_uint16_be(s, length); /* userData (OCTET_STRING) */ +} + +static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) +{ + uint8* data; + uint32 sec_flags; + uint32 pad = 0; + + sec_flags = rdp->sec_flags; + + if (sec_flags != 0) + { + rdp_write_security_header(s, sec_flags); + + if (sec_flags & SEC_ENCRYPT) + { + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + { + data = s->p + 12; + + length = length - (data - s->data); + stream_write_uint16(s, 0x10); /* length */ + stream_write_uint8(s, 0x1); /* TSFIPS_VERSION 1*/ + + /* handle padding */ + pad = 8 - (length % 8); + + if (pad == 8) + pad = 0; + if (pad) + memset(data+length, 0, pad); + + stream_write_uint8(s, pad); + + security_hmac_signature(data, length, s->p, rdp); + stream_seek(s, 8); + security_fips_encrypt(data, length + pad, rdp); + } + else + { + data = s->p + 8; + length = length - (data - s->data); + if (sec_flags & SEC_SECURE_CHECKSUM) + security_salted_mac_signature(rdp, data, length, true, s->p); + else + security_mac_signature(rdp, data, length, s->p); + stream_seek(s, 8); + security_encrypt(s->p, length, rdp); + } + } + + rdp->sec_flags = 0; + } + + return pad; +} + +static uint32 rdp_get_sec_bytes(rdpRdp* rdp) +{ + uint32 sec_bytes; + + if (rdp->sec_flags & SEC_ENCRYPT) + { + sec_bytes = 12; + + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + sec_bytes += 4; + } + else if (rdp->sec_flags != 0) + { + sec_bytes = 4; + } + else + { + sec_bytes = 0; + } + + return sec_bytes; +} + +/** + * Send an RDP packet.\n + * @param rdp RDP module + * @param s stream + * @param channel_id channel id + */ + +boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id) +{ + uint16 length; + uint32 sec_bytes; + uint8* sec_hold; + + length = stream_get_length(s); + stream_set_pos(s, 0); + + rdp_write_header(rdp, s, length, channel_id); + + sec_bytes = rdp_get_sec_bytes(rdp); + sec_hold = s->p; + stream_seek(s, sec_bytes); + + s->p = sec_hold; + length += rdp_security_stream_out(rdp, s, length); + + stream_set_pos(s, length); + if (transport_write(rdp->transport, s) < 0) + return false; + + return true; +} + +boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) +{ + uint16 length; + uint32 sec_bytes; + uint8* sec_hold; + + length = stream_get_length(s); + stream_set_pos(s, 0); + + rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); + + sec_bytes = rdp_get_sec_bytes(rdp); + sec_hold = s->p; + stream_seek(s, sec_bytes); + + rdp_write_share_control_header(s, length - sec_bytes, type, channel_id); + + s->p = sec_hold; + length += rdp_security_stream_out(rdp, s, length); + + stream_set_pos(s, length); + if (transport_write(rdp->transport, s) < 0) + return false; + + return true; +} + +boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id) +{ + uint16 length; + uint32 sec_bytes; + uint8* sec_hold; + + length = stream_get_length(s); + stream_set_pos(s, 0); + + rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); + + sec_bytes = rdp_get_sec_bytes(rdp); + sec_hold = s->p; + stream_seek(s, sec_bytes); + + rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id); + rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->share_id); + + s->p = sec_hold; + length += rdp_security_stream_out(rdp, s, length); + + stream_set_pos(s, length); + if (transport_write(rdp->transport, s) < 0) + return false; + + return true; +} + +void rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, STREAM* s) +{ + stream_read_uint32(s, rdp->errorInfo); /* errorInfo (4 bytes) */ + + if (rdp->errorInfo != ERRINFO_SUCCESS) + rdp_print_errinfo(rdp->errorInfo); +} + +void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) +{ + uint8 type; + uint16 length; + uint32 share_id; + uint8 compressed_type; + uint16 compressed_len; + + rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len); + +#ifdef WITH_DEBUG_RDP + if (type != DATA_PDU_TYPE_UPDATE) + printf("recv %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); +#endif + + switch (type) + { + case DATA_PDU_TYPE_UPDATE: + update_recv(rdp->update, s); + break; + + case DATA_PDU_TYPE_CONTROL: + rdp_recv_server_control_pdu(rdp, s); + break; + + case DATA_PDU_TYPE_POINTER: + update_recv_pointer(rdp->update, s); + break; + + case DATA_PDU_TYPE_INPUT: + break; + + case DATA_PDU_TYPE_SYNCHRONIZE: + rdp_recv_synchronize_pdu(rdp, s); + break; + + case DATA_PDU_TYPE_REFRESH_RECT: + break; + + case DATA_PDU_TYPE_PLAY_SOUND: + update_recv_play_sound(rdp->update, s); + break; + + case DATA_PDU_TYPE_SUPPRESS_OUTPUT: + break; + + case DATA_PDU_TYPE_SHUTDOWN_REQUEST: + break; + + case DATA_PDU_TYPE_SHUTDOWN_DENIED: + break; + + case DATA_PDU_TYPE_SAVE_SESSION_INFO: + rdp_recv_save_session_info(rdp, s); + break; + + case DATA_PDU_TYPE_FONT_LIST: + break; + + case DATA_PDU_TYPE_FONT_MAP: + rdp_recv_font_map_pdu(rdp, s); + break; + + case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: + break; + + case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: + break; + + case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: + break; + + case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: + break; + + case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: + break; + + case DATA_PDU_TYPE_SET_ERROR_INFO: + rdp_recv_set_error_info_data_pdu(rdp, s); + break; + + case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: + break; + + case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: + break; + + case DATA_PDU_TYPE_ARC_STATUS: + break; + + case DATA_PDU_TYPE_STATUS_INFO: + break; + + case DATA_PDU_TYPE_MONITOR_LAYOUT: + break; + + default: + break; + } +} + +boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 type; + uint16 length; + uint16 channelId; + + rdp_read_share_control_header(s, &length, &type, &channelId); + + if (type == PDU_TYPE_DATA) + { + rdp_recv_data_pdu(rdp, s); + return true; + } + else if (type == PDU_TYPE_SERVER_REDIRECTION) + { + rdp_recv_enhanced_security_redirection_packet(rdp, s); + return true; + } + else + { + return false; + } +} + +/** + * Decrypt an RDP packet.\n + * @param rdp RDP module + * @param s stream + * @param length int + */ + +boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, uint16 securityFlags) +{ + uint8 cmac[8], wmac[8]; + + if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) + { + uint16 len; + uint8 version, pad; + uint8 *sig; + + stream_read_uint16(s, len); /* 0x10 */ + stream_read_uint8(s, version); /* 0x1 */ + stream_read_uint8(s, pad); + + sig = s->p; + stream_seek(s, 8); /* signature */ + + length -= 12; + + if (!security_fips_decrypt(s->p, length, rdp)) + { + printf("FATAL: cannot decrypt\n"); + return false; /* TODO */ + } + + if (!security_fips_check_signature(s->p, length - pad, sig, rdp)) + { + printf("FATAL: invalid packet signature\n"); + return false; /* TODO */ + } + + /* is this what needs adjusting? */ + s->size -= pad; + return true; + } + + stream_read(s, wmac, sizeof(wmac)); + length -= sizeof(wmac); + security_decrypt(s->p, length, rdp); + if (securityFlags & SEC_SECURE_CHECKSUM) + security_salted_mac_signature(rdp, s->p, length, false, cmac); + else + security_mac_signature(rdp, s->p, length, cmac); + if (memcmp(wmac, cmac, sizeof(wmac)) != 0) + { + printf("WARNING: invalid packet signature\n"); + /* + * Because Standard RDP Security is totally broken, + * and cannot protect against MITM, don't treat signature + * verification failure as critical. This at least enables + * us to work with broken RDP clients and servers that + * generate invalid signatures. + */ + //return false; + } + return true; +} + +/** + * Process an RDP packet.\n + * @param rdp RDP module + * @param s stream + */ + +static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 length; + uint16 pduType; + uint16 pduLength; + uint16 pduSource; + uint16 channelId; + uint16 securityFlags; + + if (!rdp_read_header(rdp, s, &length, &channelId)) + { + printf("Incorrect RDP header.\n"); + return false; + } + + if (rdp->settings->encryption) + { + rdp_read_security_header(s, &securityFlags); + if (securityFlags & (SEC_ENCRYPT|SEC_REDIRECTION_PKT)) + { + if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return false; + } + } + if (securityFlags & SEC_REDIRECTION_PKT) + { + /* + * [MS-RDPBCGR] 2.2.13.2.1 + * - no share control header, nor the 2 byte pad + */ + s->p -= 2; + rdp_recv_enhanced_security_redirection_packet(rdp, s); + return true; + } + } + + if (channelId != MCS_GLOBAL_CHANNEL_ID) + { + freerdp_channel_process(rdp->instance, s, channelId); + } + else + { + rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource); + + rdp->settings->pdu_source = pduSource; + + switch (pduType) + { + case PDU_TYPE_DATA: + rdp_recv_data_pdu(rdp, s); + break; + + case PDU_TYPE_DEACTIVATE_ALL: + if (!rdp_recv_deactivate_all(rdp, s)) + return false; + break; + + case PDU_TYPE_SERVER_REDIRECTION: + rdp_recv_enhanced_security_redirection_packet(rdp, s); + break; + + default: + printf("incorrect PDU type: 0x%04X\n", pduType); + break; + } + } + + return true; +} + +static boolean rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 length; + rdpFastPath* fastpath; + + fastpath = rdp->fastpath; + length = fastpath_read_header_rdp(fastpath, s); + + if (length == 0 || length > stream_get_left(s)) + { + printf("incorrect FastPath PDU header length %d\n", length); + return false; + } + + if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED) + { + rdp_decrypt(rdp, s, length, (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0); + } + + return fastpath_recv_updates(rdp->fastpath, s); +} + +static boolean rdp_recv_pdu(rdpRdp* rdp, STREAM* s) +{ + if (tpkt_verify_header(s)) + return rdp_recv_tpkt_pdu(rdp, s); + else + return rdp_recv_fastpath_pdu(rdp, s); +} + +/** + * Receive an RDP packet.\n + * @param rdp RDP module + */ + +void rdp_recv(rdpRdp* rdp) +{ + STREAM* s; + + s = transport_recv_stream_init(rdp->transport, 4096); + transport_read(rdp->transport, s); + + rdp_recv_pdu(rdp, s); +} + +static boolean rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra) +{ + rdpRdp* rdp = (rdpRdp*) extra; + + switch (rdp->state) + { + case CONNECTION_STATE_NEGO: + if (!rdp_client_connect_mcs_connect_response(rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_ATTACH_USER: + if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s)) + return false; + break; + + case CONNECTION_STATE_MCS_CHANNEL_JOIN: + if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s)) + return false; + break; + + case CONNECTION_STATE_LICENSE: + if (!rdp_client_connect_license(rdp, s)) + return false; + break; + + case CONNECTION_STATE_CAPABILITY: + if (!rdp_client_connect_demand_active(rdp, s)) + { + printf("rdp_client_connect_demand_active failed\n"); + return false; + } + break; + + case CONNECTION_STATE_FINALIZATION: + if (!rdp_recv_pdu(rdp, s)) + return false; + if (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE) + rdp->state = CONNECTION_STATE_ACTIVE; + break; + + case CONNECTION_STATE_ACTIVE: + if (!rdp_recv_pdu(rdp, s)) + return false; + break; + + default: + printf("Invalid state %d\n", rdp->state); + return false; + } + + return true; +} + +int rdp_send_channel_data(rdpRdp* rdp, int channel_id, uint8* data, int size) +{ + return freerdp_channel_send(rdp, channel_id, data, size); +} + +/** + * Set non-blocking mode information. + * @param rdp RDP module + * @param blocking blocking mode + */ +void rdp_set_blocking_mode(rdpRdp* rdp, boolean blocking) +{ + rdp->transport->recv_callback = rdp_recv_callback; + rdp->transport->recv_extra = rdp; + transport_set_blocking_mode(rdp->transport, blocking); +} + +int rdp_check_fds(rdpRdp* rdp) +{ + return transport_check_fds(rdp->transport); +} + +/** + * Instantiate new RDP module. + * @return new RDP module + */ + +rdpRdp* rdp_new(freerdp* instance) +{ + rdpRdp* rdp; + + rdp = (rdpRdp*) xzalloc(sizeof(rdpRdp)); + + if (rdp != NULL) + { + rdp->instance = instance; + rdp->settings = settings_new((void*) instance); + if (instance != NULL) + instance->settings = rdp->settings; + rdp->extension = extension_new(instance); + rdp->transport = transport_new(rdp->settings); + rdp->license = license_new(rdp); + rdp->input = input_new(rdp); + rdp->update = update_new(rdp); + rdp->fastpath = fastpath_new(rdp); + rdp->nego = nego_new(rdp->transport); + rdp->mcs = mcs_new(rdp->transport); + rdp->redirection = redirection_new(); + rdp->mppc = mppc_new(rdp); + } + + return rdp; +} + +/** + * Free RDP module. + * @param rdp RDP module to be freed + */ + +void rdp_free(rdpRdp* rdp) +{ + if (rdp != NULL) + { + extension_free(rdp->extension); + settings_free(rdp->settings); + transport_free(rdp->transport); + license_free(rdp->license); + input_free(rdp->input); + update_free(rdp->update); + fastpath_free(rdp->fastpath); + nego_free(rdp->nego); + mcs_free(rdp->mcs); + redirection_free(rdp->redirection); + mppc_free(rdp); + xfree(rdp); + } +} + diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h new file mode 100644 index 0000000..4a295f1 --- /dev/null +++ b/libfreerdp-core/rdp.h @@ -0,0 +1,205 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Core + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RDP_H +#define __RDP_H + +#include "mcs.h" +#include "tpkt.h" +#include "fastpath.h" +#include "tpdu.h" +#include "nego.h" +#include "input.h" +#include "update.h" +#include "license.h" +#include "errinfo.h" +#include "extension.h" +#include "security.h" +#include "transport.h" +#include "connection.h" +#include "redirection.h" +#include "capabilities.h" +#include "channel.h" +#include "mppc.h" + +#include +#include +#include +#include + +/* Security Header Flags */ +#define SEC_EXCHANGE_PKT 0x0001 +#define SEC_ENCRYPT 0x0008 +#define SEC_RESET_SEQNO 0x0010 +#define SEC_IGNORE_SEQNO 0x0020 +#define SEC_INFO_PKT 0x0040 +#define SEC_LICENSE_PKT 0x0080 +#define SEC_LICENSE_ENCRYPT_CS 0x0200 +#define SEC_LICENSE_ENCRYPT_SC 0x0200 +#define SEC_REDIRECTION_PKT 0x0400 +#define SEC_SECURE_CHECKSUM 0x0800 +#define SEC_FLAGSHI_VALID 0x8000 + +#define SEC_PKT_CS_MASK (SEC_EXCHANGE_PKT | SEC_INFO_PKT) +#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT) +#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK) + +#define RDP_SECURITY_HEADER_LENGTH 4 +#define RDP_SHARE_CONTROL_HEADER_LENGTH 6 +#define RDP_SHARE_DATA_HEADER_LENGTH 12 +#define RDP_PACKET_HEADER_MAX_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_MAX_LENGTH) + +#define PDU_TYPE_DEMAND_ACTIVE 0x1 +#define PDU_TYPE_CONFIRM_ACTIVE 0x3 +#define PDU_TYPE_DEACTIVATE_ALL 0x6 +#define PDU_TYPE_DATA 0x7 +#define PDU_TYPE_SERVER_REDIRECTION 0xA + +#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01 +#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02 +#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04 +#define FINALIZE_SC_FONT_MAP_PDU 0x08 +#define FINALIZE_SC_COMPLETE 0x0F + +/* Data PDU Types */ +#define DATA_PDU_TYPE_UPDATE 0x02 +#define DATA_PDU_TYPE_CONTROL 0x14 +#define DATA_PDU_TYPE_POINTER 0x1B +#define DATA_PDU_TYPE_INPUT 0x1C +#define DATA_PDU_TYPE_SYNCHRONIZE 0x1F +#define DATA_PDU_TYPE_REFRESH_RECT 0x21 +#define DATA_PDU_TYPE_PLAY_SOUND 0x22 +#define DATA_PDU_TYPE_SUPPRESS_OUTPUT 0x23 +#define DATA_PDU_TYPE_SHUTDOWN_REQUEST 0x24 +#define DATA_PDU_TYPE_SHUTDOWN_DENIED 0x25 +#define DATA_PDU_TYPE_SAVE_SESSION_INFO 0x26 +#define DATA_PDU_TYPE_FONT_LIST 0x27 +#define DATA_PDU_TYPE_FONT_MAP 0x28 +#define DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS 0x29 +#define DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST 0x2B +#define DATA_PDU_TYPE_BITMAP_CACHE_ERROR 0x2C +#define DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS 0x2D +#define DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR 0x2E +#define DATA_PDU_TYPE_SET_ERROR_INFO 0x2F +#define DATA_PDU_TYPE_DRAW_NINEGRID_ERROR 0x30 +#define DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR 0x31 +#define DATA_PDU_TYPE_ARC_STATUS 0x32 +#define DATA_PDU_TYPE_STATUS_INFO 0x36 +#define DATA_PDU_TYPE_MONITOR_LAYOUT 0x37 + +/* Compression Types */ +#define PACKET_COMPRESSED 0x20 +#define PACKET_AT_FRONT 0x40 +#define PACKET_FLUSHED 0x80 +#define PACKET_COMPR_TYPE_8K 0x00 +#define PACKET_COMPR_TYPE_64K 0x01 +#define PACKET_COMPR_TYPE_RDP6 0x02 +#define PACKET_COMPR_TYPE_RDP61 0x03 +#define CompressionTypeMask 0x0F + +/* Stream Identifiers */ +#define STREAM_UNDEFINED 0x00 +#define STREAM_LOW 0x01 +#define STREAM_MED 0x02 +#define STREAM_HI 0x04 + +struct rdp_rdp +{ + int state; + freerdp* instance; + struct rdp_mcs* mcs; + struct rdp_nego* nego; + struct rdp_input* input; + struct rdp_update* update; + struct rdp_fastpath* fastpath; + struct rdp_license* license; + struct rdp_redirection* redirection; + struct rdp_settings* settings; + struct rdp_transport* transport; + struct rdp_extension* extension; + struct rdp_mppc* mppc; + struct crypto_rc4_struct* rc4_decrypt_key; + int decrypt_use_count; + struct crypto_rc4_struct* rc4_encrypt_key; + int encrypt_use_count; + struct crypto_des3_struct* fips_encrypt; + struct crypto_des3_struct* fips_decrypt; + struct crypto_hmac_struct* fips_hmac; + uint32 sec_flags; + boolean do_crypt; + boolean do_secure_checksum; + uint8 sign_key[16]; + uint8 decrypt_key[16]; + uint8 encrypt_key[16]; + uint8 decrypt_update_key[16]; + uint8 encrypt_update_key[16]; + int rc4_key_len; + uint8 fips_sign_key[20]; + uint8 fips_encrypt_key[24]; + uint8 fips_decrypt_key[24]; + uint32 errorInfo; + uint32 finalize_sc_pdus; + boolean disconnect; +}; + +void rdp_read_security_header(STREAM* s, uint16* flags); +void rdp_write_security_header(STREAM* s, uint16 flags); + +boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id); +void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint16 channel_id); + +boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id, + uint8 *compressed_type, uint16 *compressed_len); + +void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 share_id); + +STREAM* rdp_send_stream_init(rdpRdp* rdp); + +boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_id); +void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id); + +STREAM* rdp_pdu_init(rdpRdp* rdp); +boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id); + +STREAM* rdp_data_pdu_init(rdpRdp* rdp); +boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id); +void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s); + +boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id); +void rdp_recv(rdpRdp* rdp); + +int rdp_send_channel_data(rdpRdp* rdp, int channel_id, uint8* data, int size); + +boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s); + +void rdp_set_blocking_mode(rdpRdp* rdp, boolean blocking); +int rdp_check_fds(rdpRdp* rdp); + +rdpRdp* rdp_new(freerdp* instance); +void rdp_free(rdpRdp* rdp); + +#ifdef WITH_DEBUG_RDP +#define DEBUG_RDP(fmt, ...) DEBUG_CLASS(RDP, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RDP(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, uint16 securityFlags); + +#endif /* __RDP_H */ diff --git a/libfreerdp-core/redirection.c b/libfreerdp-core/redirection.c new file mode 100644 index 0000000..113c65a --- /dev/null +++ b/libfreerdp-core/redirection.c @@ -0,0 +1,225 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Server Redirection + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "connection.h" + +#include "redirection.h" + +void rdp_print_redirection_flags(uint32 flags) +{ + printf("redirectionFlags = {\n"); + + if (flags & LB_TARGET_NET_ADDRESS) + printf("\tLB_TARGET_NET_ADDRESS\n"); + if (flags & LB_LOAD_BALANCE_INFO) + printf("\tLB_LOAD_BALANCE_INFO\n"); + if (flags & LB_USERNAME) + printf("\tLB_USERNAME\n"); + if (flags & LB_DOMAIN) + printf("\tLB_DOMAIN\n"); + if (flags & LB_PASSWORD) + printf("\tLB_PASSWORD\n"); + if (flags & LB_DONTSTOREUSERNAME) + printf("\tLB_DONTSTOREUSERNAME\n"); + if (flags & LB_SMARTCARD_LOGON) + printf("\tLB_SMARTCARD_LOGON\n"); + if (flags & LB_NOREDIRECT) + printf("\tLB_NOREDIRECT\n"); + if (flags & LB_TARGET_FQDN) + printf("\tLB_TARGET_FQDN\n"); + if (flags & LB_TARGET_NETBIOS_NAME) + printf("\tLB_TARGET_NETBIOS_NAME\n"); + if (flags & LB_TARGET_NET_ADDRESSES) + printf("\tLB_TARGET_NET_ADDRESSES\n"); + if (flags & LB_CLIENT_TSV_URL) + printf("\tLB_CLIENT_TSV_URL\n"); + if (flags & LB_SERVER_TSV_CAPABLE) + printf("\tLB_SERVER_TSV_CAPABLE\n"); + + printf("}\n"); +} + +boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 flags; + uint16 length; + rdpRedirection* redirection = rdp->redirection; + + stream_read_uint16(s, flags); /* flags (2 bytes) */ + stream_read_uint16(s, length); /* length (2 bytes) */ + stream_read_uint32(s, redirection->sessionID); /* sessionID (4 bytes) */ + stream_read_uint32(s, redirection->flags); /* redirFlags (4 bytes) */ + + DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID); + +#ifdef WITH_DEBUG_REDIR + rdp_print_redirection_flags(redirection->flags); +#endif + + if (redirection->flags & LB_TARGET_NET_ADDRESS) + { + freerdp_string_read_length32(s, &redirection->targetNetAddress, rdp->settings->uniconv); + DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii); + } + + if (redirection->flags & LB_LOAD_BALANCE_INFO) + { + uint32 loadBalanceInfoLength; + stream_read_uint32(s, loadBalanceInfoLength); + freerdp_blob_alloc(&redirection->loadBalanceInfo, loadBalanceInfoLength); + stream_read(s, redirection->loadBalanceInfo.data, loadBalanceInfoLength); +#ifdef WITH_DEBUG_REDIR + DEBUG_REDIR("loadBalanceInfo:"); + freerdp_hexdump(redirection->loadBalanceInfo.data, redirection->loadBalanceInfo.length); +#endif + } + + if (redirection->flags & LB_USERNAME) + { + freerdp_string_read_length32(s, &redirection->username, rdp->settings->uniconv); + DEBUG_REDIR("username: %s", redirection->username.ascii); + } + + if (redirection->flags & LB_DOMAIN) + { + freerdp_string_read_length32(s, &redirection->domain, rdp->settings->uniconv); + DEBUG_REDIR("domain: %s", redirection->domain.ascii); + } + + if (redirection->flags & LB_PASSWORD) + { + uint32 passwordLength; + stream_read_uint32(s, passwordLength); + freerdp_blob_alloc(&redirection->password_cookie, passwordLength); + stream_read(s, redirection->password_cookie.data, passwordLength); + +#ifdef WITH_DEBUG_REDIR + DEBUG_REDIR("password_cookie:"); + freerdp_hexdump(redirection->password_cookie.data, redirection->password_cookie.length); +#endif + } + + if (redirection->flags & LB_TARGET_FQDN) + { + freerdp_string_read_length32(s, &redirection->targetFQDN, rdp->settings->uniconv); + DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii); + } + + if (redirection->flags & LB_TARGET_NETBIOS_NAME) + { + freerdp_string_read_length32(s, &redirection->targetNetBiosName, rdp->settings->uniconv); + DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii); + } + + if (redirection->flags & LB_CLIENT_TSV_URL) + { + freerdp_string_read_length32(s, &redirection->tsvUrl, rdp->settings->uniconv); + DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii); + } + + if (redirection->flags & LB_TARGET_NET_ADDRESSES) + { + int i; + uint32 count; + uint32 targetNetAddressesLength; + + stream_read_uint32(s, targetNetAddressesLength); + + stream_read_uint32(s, redirection->targetNetAddressesCount); + count = redirection->targetNetAddressesCount; + + redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString)); + + for (i = 0; i < (int) count; i++) + { + freerdp_string_read_length32(s, &redirection->targetNetAddresses[i], rdp->settings->uniconv); + DEBUG_REDIR("targetNetAddresses: %s", (&redirection->targetNetAddresses[i])->ascii); + } + } + + stream_seek(s, 8); /* pad (8 bytes) */ + + if (redirection->flags & LB_NOREDIRECT) + return true; + else + return rdp_client_redirect(rdp); +} + +boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s) +{ + rdp_recv_server_redirection_pdu(rdp, s); + return true; +} + +boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s) +{ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + rdp_recv_server_redirection_pdu(rdp, s); + stream_seek_uint8(s); /* pad2Octets (1 byte) */ + return true; +} + +rdpRedirection* redirection_new() +{ + rdpRedirection* redirection; + + redirection = (rdpRedirection*) xzalloc(sizeof(rdpRedirection)); + + if (redirection != NULL) + { + + } + + return redirection; +} + +void redirection_free(rdpRedirection* redirection) +{ + if (redirection != NULL) + { + //these four have already been freed in settings_free() and freerdp_string_free() checks for NULL + redirection->username.ascii = NULL; + redirection->domain.ascii = NULL; + redirection->targetNetAddress.ascii = NULL; + redirection->targetNetBiosName.ascii = NULL; + + freerdp_string_free(&redirection->tsvUrl); + freerdp_string_free(&redirection->username); + freerdp_string_free(&redirection->domain); + freerdp_blob_free(&redirection->password_cookie); + freerdp_string_free(&redirection->targetFQDN); + freerdp_string_free(&redirection->targetNetBiosName); + freerdp_string_free(&redirection->targetNetAddress); + freerdp_blob_free(&redirection->loadBalanceInfo); + + if (redirection->targetNetAddresses != NULL) + { + int i; + + for (i = 0; i < (int) redirection->targetNetAddressesCount; i++) + freerdp_string_free(&redirection->targetNetAddresses[i]); + + xfree(redirection->targetNetAddresses); + } + + xfree(redirection); + } +} + + diff --git a/libfreerdp-core/redirection.h b/libfreerdp-core/redirection.h new file mode 100644 index 0000000..efbb13d --- /dev/null +++ b/libfreerdp-core/redirection.h @@ -0,0 +1,75 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Server Redirection + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REDIRECTION_H +#define __REDIRECTION_H + +#include "rdp.h" + +#include +#include +#include +#include +#include + +/* Redirection Flags */ +#define LB_TARGET_NET_ADDRESS 0x00000001 +#define LB_LOAD_BALANCE_INFO 0x00000002 +#define LB_USERNAME 0x00000004 +#define LB_DOMAIN 0x00000008 +#define LB_PASSWORD 0x00000010 +#define LB_DONTSTOREUSERNAME 0x00000020 +#define LB_SMARTCARD_LOGON 0x00000040 +#define LB_NOREDIRECT 0x00000080 +#define LB_TARGET_FQDN 0x00000100 +#define LB_TARGET_NETBIOS_NAME 0x00000200 +#define LB_TARGET_NET_ADDRESSES 0x00000800 +#define LB_CLIENT_TSV_URL 0x00001000 +#define LB_SERVER_TSV_CAPABLE 0x00002000 + +struct rdp_redirection +{ + uint32 flags; + uint32 sessionID; + rdpString tsvUrl; + rdpString username; + rdpString domain; + rdpBlob password_cookie; + rdpString targetFQDN; + rdpBlob loadBalanceInfo; + rdpString targetNetBiosName; + rdpString targetNetAddress; + uint32 targetNetAddressesCount; + rdpString* targetNetAddresses; +}; +typedef struct rdp_redirection rdpRedirection; + +boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s); +boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s); + +rdpRedirection* redirection_new(); +void redirection_free(rdpRedirection* redirection); + +#ifdef WITH_DEBUG_REDIR +#define DEBUG_REDIR(fmt, ...) DEBUG_CLASS(REDIR, fmt, ## __VA_ARGS__) +#else +#define DEBUG_REDIR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __REDIRECTION_H */ diff --git a/libfreerdp-core/security.c b/libfreerdp-core/security.c new file mode 100644 index 0000000..8df8a65 --- /dev/null +++ b/libfreerdp-core/security.c @@ -0,0 +1,525 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "security.h" + +/* 0x36 repeated 40 times */ +static const uint8 pad1[40] = +{ + "\x36\x36\x36\x36\x36\x36\x36\x36" + "\x36\x36\x36\x36\x36\x36\x36\x36" + "\x36\x36\x36\x36\x36\x36\x36\x36" + "\x36\x36\x36\x36\x36\x36\x36\x36" + "\x36\x36\x36\x36\x36\x36\x36\x36" +}; + +/* 0x5C repeated 48 times */ +static const uint8 pad2[48] = +{ + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" + "\x5C\x5C\x5C\x5C\x5C\x5C\x5C\x5C" +}; + +static const uint8 +fips_reverse_table[256] = +{ + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +static const uint8 +fips_oddparity_table[256] = +{ + 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07, + 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e, + 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16, + 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f, + 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26, + 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f, + 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37, + 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e, + 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, + 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f, + 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57, + 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e, + 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67, + 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e, + 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76, + 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f, + 0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86, + 0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f, + 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97, + 0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e, + 0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7, + 0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae, + 0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6, + 0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf, + 0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7, + 0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce, + 0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6, + 0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf, + 0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6, + 0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef, + 0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7, + 0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe +}; + +static void security_salted_hash(uint8* salt, uint8* input, int length, uint8* salt1, uint8* salt2, uint8* output) +{ + CryptoMd5 md5; + CryptoSha1 sha1; + uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH]; + + /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */ + + /* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */ + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, input, length); /* Input */ + crypto_sha1_update(sha1, salt, 48); /* Salt (48 bytes) */ + crypto_sha1_update(sha1, salt1, 32); /* Salt1 (32 bytes) */ + crypto_sha1_update(sha1, salt2, 32); /* Salt2 (32 bytes) */ + crypto_sha1_final(sha1, sha1_digest); + + /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */ + md5 = crypto_md5_init(); + crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */ + crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ + crypto_md5_final(md5, output); +} + +static void security_premaster_hash(char* input, int length, uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + /* PremasterHash(Input) = SaltedHash(PremasterSecret, Input, ClientRandom, ServerRandom) */ + security_salted_hash(premaster_secret, (uint8*)input, length, client_random, server_random, output); +} + +void security_master_secret(uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + /* MasterSecret = PremasterHash('A') + PremasterHash('BB') + PremasterHash('CCC') */ + security_premaster_hash("A", 1, premaster_secret, client_random, server_random, &output[0]); + security_premaster_hash("BB", 2, premaster_secret, client_random, server_random, &output[16]); + security_premaster_hash("CCC", 3, premaster_secret, client_random, server_random, &output[32]); +} + +static void security_master_hash(char* input, int length, uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + /* MasterHash(Input) = SaltedHash(MasterSecret, Input, ServerRandom, ClientRandom) */ + security_salted_hash(master_secret, (uint8*)input, length, server_random, client_random, output); +} + +void security_session_key_blob(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + /* MasterHash = MasterHash('A') + MasterHash('BB') + MasterHash('CCC') */ + security_master_hash("A", 1, master_secret, client_random, server_random, &output[0]); + security_master_hash("BB", 2, master_secret, client_random, server_random, &output[16]); + security_master_hash("CCC", 3, master_secret, client_random, server_random, &output[32]); +} + +void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output) +{ + /* MacSaltKey = First128Bits(SessionKeyBlob) */ + memcpy(output, session_key_blob, 16); +} + +void security_md5_16_32_32(uint8* in0, uint8* in1, uint8* in2, uint8* output) +{ + CryptoMd5 md5; + + md5 = crypto_md5_init(); + crypto_md5_update(md5, in0, 16); + crypto_md5_update(md5, in1, 32); + crypto_md5_update(md5, in2, 32); + crypto_md5_final(md5, output); +} + +void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output) +{ + /* LicensingEncryptionKey = MD5(Second128Bits(SessionKeyBlob) + ClientRandom + ServerRandom)) */ + security_md5_16_32_32(&session_key_blob[16], client_random, server_random, output); +} + +void security_uint32_le(uint8* output, uint32 value) +{ + output[0] = (value) & 0xFF; + output[1] = (value >> 8) & 0xFF; + output[2] = (value >> 16) & 0xFF; + output[3] = (value >> 24) & 0xFF; +} + +void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output) +{ + CryptoMd5 md5; + CryptoSha1 sha1; + uint8 length_le[4]; + uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH]; + + /* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */ + + security_uint32_le(length_le, length); /* length must be little-endian */ + + /* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */ + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */ + crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ + crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ + crypto_sha1_update(sha1, data, length); /* data */ + crypto_sha1_final(sha1, sha1_digest); + + /* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */ + md5 = crypto_md5_init(); + crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */ + crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ + crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ + crypto_md5_final(md5, output); +} + +void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output) +{ + CryptoMd5 md5; + CryptoSha1 sha1; + uint8 length_le[4]; + uint8 md5_digest[CRYPTO_MD5_DIGEST_LENGTH]; + uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH]; + + security_uint32_le(length_le, length); /* length must be little-endian */ + + /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ + crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ + crypto_sha1_update(sha1, data, length); /* data */ + crypto_sha1_final(sha1, sha1_digest); + + /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ + md5 = crypto_md5_init(); + crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ + crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ + crypto_md5_final(md5, md5_digest); + + memcpy(output, md5_digest, 8); +} + +void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output) +{ + CryptoMd5 md5; + CryptoSha1 sha1; + uint8 length_le[4]; + uint8 use_count_le[4]; + uint8 md5_digest[CRYPTO_MD5_DIGEST_LENGTH]; + uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH]; + + security_uint32_le(length_le, length); /* length must be little-endian */ + if (encryption) + security_uint32_le(use_count_le, rdp->encrypt_use_count); + else + { + /* + * We calculate checksum on plain text, so we must have already + * decrypt it, which means decrypt_use_count is off by one. + */ + security_uint32_le(use_count_le, rdp->decrypt_use_count - 1); + } + + /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ + crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ + crypto_sha1_update(sha1, data, length); /* data */ + crypto_sha1_update(sha1, use_count_le, sizeof(use_count_le)); /* encryptionCount */ + crypto_sha1_final(sha1, sha1_digest); + + /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ + md5 = crypto_md5_init(); + crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */ + crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ + crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */ + crypto_md5_final(md5, md5_digest); + + memcpy(output, md5_digest, 8); +} + +static void security_A(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + security_premaster_hash("A", 1, master_secret, client_random, server_random, &output[0]); + security_premaster_hash("BB", 2, master_secret, client_random, server_random, &output[16]); + security_premaster_hash("CCC", 3, master_secret, client_random, server_random, &output[32]); +} + +static void security_X(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output) +{ + security_premaster_hash("X", 1, master_secret, client_random, server_random, &output[0]); + security_premaster_hash("YY", 2, master_secret, client_random, server_random, &output[16]); + security_premaster_hash("ZZZ", 3, master_secret, client_random, server_random, &output[32]); +} + +static void fips_expand_key_bits(uint8* in, uint8* out) +{ + uint8 buf[21], c; + int i, b, p, r; + + /* reverse every byte in the key */ + for (i = 0; i < 21; i++) + buf[i] = fips_reverse_table[in[i]]; + + /* insert a zero-bit after every 7th bit */ + for (i = 0, b = 0; i < 24; i++, b += 7) + { + p = b / 8; + r = b % 8; + if (r == 0) + { + out[i] = buf[p] & 0xfe; + } + else + { + /* c is accumulator */ + c = buf[p] << r; + c |= buf[p + 1] >> (8 - r); + out[i] = c & 0xfe; + } + } + + /* reverse every byte */ + /* alter lsb so the byte has odd parity */ + for (i = 0; i < 24; i++) + out[i] = fips_oddparity_table[fips_reverse_table[out[i]]]; +} + +boolean security_establish_keys(uint8* client_random, rdpRdp* rdp) +{ + uint8 pre_master_secret[48]; + uint8 master_secret[48]; + uint8 session_key_blob[48]; + uint8* server_random; + uint8 salt40[] = { 0xD1, 0x26, 0x9E }; + rdpSettings* settings; + + settings = rdp->settings; + server_random = settings->server_random->data; + + if (settings->encryption_method == ENCRYPTION_METHOD_FIPS) + { + CryptoSha1 sha1; + uint8 client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; + uint8 client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1]; + + printf("FIPS Compliant encryption level.\n"); + + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, client_random + 16, 16); + crypto_sha1_update(sha1, server_random + 16, 16); + crypto_sha1_final(sha1, client_encrypt_key_t); + + client_encrypt_key_t[20] = client_encrypt_key_t[0]; + fips_expand_key_bits(client_encrypt_key_t, rdp->fips_encrypt_key); + + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, client_random, 16); + crypto_sha1_update(sha1, server_random, 16); + crypto_sha1_final(sha1, client_decrypt_key_t); + + client_decrypt_key_t[20] = client_decrypt_key_t[0]; + fips_expand_key_bits(client_decrypt_key_t, rdp->fips_decrypt_key); + + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, client_decrypt_key_t, 20); + crypto_sha1_update(sha1, client_encrypt_key_t, 20); + crypto_sha1_final(sha1, rdp->fips_sign_key); + } + + memcpy(pre_master_secret, client_random, 24); + memcpy(pre_master_secret + 24, server_random, 24); + + security_A(pre_master_secret, client_random, server_random, master_secret); + security_X(master_secret, client_random, server_random, session_key_blob); + + memcpy(rdp->sign_key, session_key_blob, 16); + + if (rdp->settings->server_mode) { + security_md5_16_32_32(&session_key_blob[16], client_random, + server_random, rdp->encrypt_key); + security_md5_16_32_32(&session_key_blob[32], client_random, + server_random, rdp->decrypt_key); + } else { + security_md5_16_32_32(&session_key_blob[16], client_random, + server_random, rdp->decrypt_key); + security_md5_16_32_32(&session_key_blob[32], client_random, + server_random, rdp->encrypt_key); + } + + if (settings->encryption_method == 1) /* 40 and 56 bit */ + { + memcpy(rdp->sign_key, salt40, 3); /* TODO 56 bit */ + memcpy(rdp->decrypt_key, salt40, 3); /* TODO 56 bit */ + memcpy(rdp->encrypt_key, salt40, 3); /* TODO 56 bit */ + rdp->rc4_key_len = 8; + } + else if (settings->encryption_method == 2) /* 128 bit */ + { + rdp->rc4_key_len = 16; + } + + memcpy(rdp->decrypt_update_key, rdp->decrypt_key, 16); + memcpy(rdp->encrypt_update_key, rdp->encrypt_key, 16); + + return true; +} + +boolean security_key_update(uint8* key, uint8* update_key, int key_len) +{ + uint8 sha1h[CRYPTO_SHA1_DIGEST_LENGTH]; + CryptoMd5 md5; + CryptoSha1 sha1; + CryptoRc4 rc4; + uint8 salt40[] = { 0xD1, 0x26, 0x9E }; + + sha1 = crypto_sha1_init(); + crypto_sha1_update(sha1, update_key, key_len); + crypto_sha1_update(sha1, pad1, sizeof(pad1)); + crypto_sha1_update(sha1, key, key_len); + crypto_sha1_final(sha1, sha1h); + + md5 = crypto_md5_init(); + crypto_md5_update(md5, update_key, key_len); + crypto_md5_update(md5, pad2, sizeof(pad2)); + crypto_md5_update(md5, sha1h, sizeof(sha1h)); + crypto_md5_final(md5, key); + + rc4 = crypto_rc4_init(key, key_len); + crypto_rc4(rc4, key_len, key, key); + crypto_rc4_free(rc4); + + if (key_len == 8) + memcpy(key, salt40, 3); /* TODO 56 bit */ + + return true; +} + +boolean security_encrypt(uint8* data, int length, rdpRdp* rdp) +{ + if (rdp->encrypt_use_count >= 4096) + { + security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len); + crypto_rc4_free(rdp->rc4_encrypt_key); + rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); + rdp->encrypt_use_count = 0; + } + crypto_rc4(rdp->rc4_encrypt_key, length, data, data); + rdp->encrypt_use_count += 1; + return true; +} + +boolean security_decrypt(uint8* data, int length, rdpRdp* rdp) +{ + if (rdp->decrypt_use_count >= 4096) + { + security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len); + crypto_rc4_free(rdp->rc4_decrypt_key); + rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); + rdp->decrypt_use_count = 0; + } + crypto_rc4(rdp->rc4_decrypt_key, length, data, data); + rdp->decrypt_use_count += 1; + return true; +} + +void security_hmac_signature(uint8* data, int length, uint8* output, rdpRdp* rdp) +{ + uint8 buf[20]; + uint8 use_count_le[4]; + + security_uint32_le(use_count_le, rdp->encrypt_use_count); + + crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20); + crypto_hmac_update(rdp->fips_hmac, data, length); + crypto_hmac_update(rdp->fips_hmac, use_count_le, 4); + crypto_hmac_final(rdp->fips_hmac, buf, 20); + + memmove(output, buf, 8); +} + +boolean security_fips_encrypt(uint8* data, int length, rdpRdp* rdp) +{ + crypto_des3_encrypt(rdp->fips_encrypt, length, data, data); + rdp->encrypt_use_count++; + return true; +} + +boolean security_fips_decrypt(uint8* data, int length, rdpRdp* rdp) +{ + crypto_des3_decrypt(rdp->fips_decrypt, length, data, data); + return true; +} + +boolean security_fips_check_signature(uint8* data, int length, uint8* sig, rdpRdp* rdp) +{ + uint8 buf[20]; + uint8 use_count_le[4]; + + security_uint32_le(use_count_le, rdp->decrypt_use_count); + + crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20); + crypto_hmac_update(rdp->fips_hmac, data, length); + crypto_hmac_update(rdp->fips_hmac, use_count_le, 4); + crypto_hmac_final(rdp->fips_hmac, buf, 20); + + rdp->decrypt_use_count++; + + if (memcmp(sig, buf, 8)) + return false; + + return true; +} diff --git a/libfreerdp-core/security.h b/libfreerdp-core/security.h new file mode 100644 index 0000000..7f338d3 --- /dev/null +++ b/libfreerdp-core/security.h @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Security + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SECURITY_H +#define __SECURITY_H + +#include "rdp.h" +#include "crypto.h" + +#include +#include + +void security_master_secret(uint8* premaster_secret, uint8* client_random, uint8* server_random, uint8* output); +void security_session_key_blob(uint8* master_secret, uint8* client_random, uint8* server_random, uint8* output); +void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output); +void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output); +void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output); + +void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output); +void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output); +boolean security_establish_keys(uint8* client_random, rdpRdp* rdp); + +boolean security_encrypt(uint8* data, int length, rdpRdp* rdp); +boolean security_decrypt(uint8* data, int length, rdpRdp* rdp); + +void security_hmac_signature(uint8* data, int length, uint8* output, rdpRdp* rdp); +boolean security_fips_encrypt(uint8* data, int length, rdpRdp* rdp); +boolean security_fips_decrypt(uint8* data, int length, rdpRdp* rdp); +boolean security_fips_check_signature(uint8* data, int length, uint8* sig, rdpRdp* rdp); + +#endif /* __SECURITY_H */ diff --git a/libfreerdp-core/settings.c b/libfreerdp-core/settings.c new file mode 100644 index 0000000..dbafa5b --- /dev/null +++ b/libfreerdp-core/settings.c @@ -0,0 +1,217 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RDP Settings + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include "capabilities.h" +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +static const char client_dll[] = "C:\\Windows\\System32\\mstscax.dll"; + +rdpSettings* settings_new(void* instance) +{ + rdpSettings* settings; + + settings = (rdpSettings*) xzalloc(sizeof(rdpSettings)); + + if (settings != NULL) + { + settings->instance = instance; + + settings->width = 1024; + settings->height = 768; + settings->workarea = false; + settings->fullscreen = false; + settings->grab_keyboard = true; + settings->decorations = true; + settings->rdp_version = 7; + settings->color_depth = 16; + settings->nla_security = true; + settings->tls_security = true; + settings->rdp_security = true; + settings->client_build = 2600; + settings->kbd_type = 0; + settings->kbd_subtype = 0; + settings->kbd_fn_keys = 0; + settings->kbd_layout = 0; + settings->encryption = false; + settings->secure_checksum = false; + settings->port = 3389; + settings->desktop_resize = true; + + settings->performance_flags = + PERF_DISABLE_FULLWINDOWDRAG | + PERF_DISABLE_MENUANIMATIONS | + PERF_DISABLE_WALLPAPER; + + settings->auto_reconnection = true; + + settings->encryption_method = ENCRYPTION_METHOD_NONE; + settings->encryption_level = ENCRYPTION_LEVEL_NONE; + + settings->authentication = true; + + settings->order_support[NEG_DSTBLT_INDEX] = true; + settings->order_support[NEG_PATBLT_INDEX] = true; + settings->order_support[NEG_SCRBLT_INDEX] = true; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = true; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = true; + settings->order_support[NEG_MULTIPATBLT_INDEX] = true; + settings->order_support[NEG_MULTISCRBLT_INDEX] = true; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = true; + settings->order_support[NEG_LINETO_INDEX] = true; + settings->order_support[NEG_POLYLINE_INDEX] = true; + settings->order_support[NEG_MEMBLT_INDEX] = true; + settings->order_support[NEG_MEM3BLT_INDEX] = true; + settings->order_support[NEG_SAVEBITMAP_INDEX] = true; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_INDEX_INDEX] = true; + settings->order_support[NEG_FAST_GLYPH_INDEX] = true; + settings->order_support[NEG_POLYGON_SC_INDEX] = true; + settings->order_support[NEG_POLYGON_CB_INDEX] = true; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = true; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = true; + + settings->color_pointer = true; + settings->large_pointer = true; + settings->pointer_cache_size = 20; + settings->sound_beeps = true; + settings->disable_wallpaper = false; + settings->disable_full_window_drag = false; + settings->disable_menu_animations = false; + settings->disable_theming = false; + settings->connection_type = 0; + + settings->draw_gdi_plus = false; + + settings->frame_marker = false; + settings->bitmap_cache_v3 = false; + + settings->bitmap_cache = true; + settings->persistent_bitmap_cache = false; + settings->bitmapCacheV2CellInfo = xzalloc(sizeof(BITMAP_CACHE_V2_CELL_INFO) * 6); + + settings->refresh_rect = true; + settings->suppress_output = true; + + settings->glyph_cache = true; + settings->glyphSupportLevel = GLYPH_SUPPORT_NONE; + settings->glyphCache = xzalloc(sizeof(GLYPH_CACHE_DEFINITION) * 10); + settings->fragCache = xnew(GLYPH_CACHE_DEFINITION); + settings->glyphCache[0].cacheEntries = 254; + settings->glyphCache[0].cacheMaximumCellSize = 4; + settings->glyphCache[1].cacheEntries = 254; + settings->glyphCache[1].cacheMaximumCellSize = 4; + settings->glyphCache[2].cacheEntries = 254; + settings->glyphCache[2].cacheMaximumCellSize = 8; + settings->glyphCache[3].cacheEntries = 254; + settings->glyphCache[3].cacheMaximumCellSize = 8; + settings->glyphCache[4].cacheEntries = 254; + settings->glyphCache[4].cacheMaximumCellSize = 16; + settings->glyphCache[5].cacheEntries = 254; + settings->glyphCache[5].cacheMaximumCellSize = 32; + settings->glyphCache[6].cacheEntries = 254; + settings->glyphCache[6].cacheMaximumCellSize = 64; + settings->glyphCache[7].cacheEntries = 254; + settings->glyphCache[7].cacheMaximumCellSize = 128; + settings->glyphCache[8].cacheEntries = 254; + settings->glyphCache[8].cacheMaximumCellSize = 256; + settings->glyphCache[9].cacheEntries = 64; + settings->glyphCache[9].cacheMaximumCellSize = 256; + settings->fragCache->cacheEntries = 256; + settings->fragCache->cacheMaximumCellSize = 256; + + settings->offscreen_bitmap_cache = true; + settings->offscreen_bitmap_cache_size = 7680; + settings->offscreen_bitmap_cache_entries = 100; + + settings->draw_nine_grid_cache_size = 2560; + settings->draw_nine_grid_cache_entries = 256; + + settings->client_dir = xstrdup(client_dll); + + settings->num_icon_caches = 3; + settings->num_icon_cache_entries = 12; + + settings->vc_chunk_size = CHANNEL_CHUNK_LENGTH; + + settings->multifrag_max_request_size = 0x200000; + + settings->fastpath_input = true; + settings->fastpath_output = true; + + settings->uniconv = freerdp_uniconv_new(); + gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1); + settings->mouse_motion = true; + + settings->client_auto_reconnect_cookie = xnew(ARC_CS_PRIVATE_PACKET); + settings->server_auto_reconnect_cookie = xnew(ARC_SC_PRIVATE_PACKET); + + settings->client_time_zone = xnew(TIME_ZONE_INFO); + settings->server_random = xnew(rdpBlob); + settings->server_certificate = xnew(rdpBlob); + + freerdp_detect_paths(settings); + } + + return settings; +} + +void settings_free(rdpSettings* settings) +{ + if (settings != NULL) + { + freerdp_uniconv_free(settings->uniconv); + xfree(settings->hostname); + xfree(settings->username); + xfree(settings->password); + xfree(settings->domain); + xfree(settings->shell); + xfree(settings->directory); + xfree(settings->ip_address); + xfree(settings->client_dir); + xfree(settings->cert_file); + xfree(settings->privatekey_file); + freerdp_blob_free(settings->server_random); + freerdp_blob_free(settings->server_certificate); + xfree(settings->server_random); + xfree(settings->server_certificate); + xfree(settings->rdp_key_file); + certificate_free(settings->server_cert); + xfree(settings->client_auto_reconnect_cookie); + xfree(settings->server_auto_reconnect_cookie); + xfree(settings->client_time_zone); + xfree(settings->bitmapCacheV2CellInfo); + xfree(settings->glyphCache); + xfree(settings->fragCache); + key_free(settings->server_key); + xfree(settings->config_path); + xfree(settings->current_path); + xfree(settings->development_path); + xfree(settings); + } +} diff --git a/libfreerdp-core/surface.c b/libfreerdp-core/surface.c new file mode 100644 index 0000000..a398c85 --- /dev/null +++ b/libfreerdp-core/surface.c @@ -0,0 +1,128 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Surface Commands + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "surface.h" + +static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s) +{ + int pos; + SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; + + stream_read_uint16(s, cmd->destLeft); + stream_read_uint16(s, cmd->destTop); + stream_read_uint16(s, cmd->destRight); + stream_read_uint16(s, cmd->destBottom); + stream_read_uint8(s, cmd->bpp); + stream_seek(s, 2); /* reserved1, reserved2 */ + stream_read_uint8(s, cmd->codecID); + stream_read_uint16(s, cmd->width); + stream_read_uint16(s, cmd->height); + stream_read_uint32(s, cmd->bitmapDataLength); + pos = stream_get_pos(s) + cmd->bitmapDataLength; + cmd->bitmapData = stream_get_tail(s); + + IFCALL(update->SurfaceBits, update->context, cmd); + + stream_set_pos(s, pos); + + return 20 + cmd->bitmapDataLength; +} + +static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s) +{ + SURFACE_FRAME_MARKER* marker = &update->surface_frame_marker; + + stream_read_uint16(s, marker->frameAction); + stream_read_uint32(s, marker->frameId); + + IFCALL(update->SurfaceFrameMarker, update->context, marker); + + return 6; +} + +boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s) +{ + uint8* mark; + uint16 cmdType; + uint32 cmdLength; + + while (size > 2) + { + stream_get_mark(s, mark); + + stream_read_uint16(s, cmdType); + size -= 2; + + switch (cmdType) + { + case CMDTYPE_SET_SURFACE_BITS: + case CMDTYPE_STREAM_SURFACE_BITS: + cmdLength = update_recv_surfcmd_surface_bits(update, s); + break; + + case CMDTYPE_FRAME_MARKER: + cmdLength = update_recv_surfcmd_frame_marker(update, s); + break; + + default: + DEBUG_WARN("unknown cmdType 0x%X", cmdType); + return false; + } + + size -= cmdLength; + + if (update->dump_rfx) + { + pcap_add_record(update->pcap_rfx, mark, cmdLength + 2); + pcap_flush(update->pcap_rfx); + } + } + return true; +} + +void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd) +{ + stream_check_size(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH); + + stream_write_uint16(s, CMDTYPE_STREAM_SURFACE_BITS); + + stream_write_uint16(s, cmd->destLeft); + stream_write_uint16(s, cmd->destTop); + stream_write_uint16(s, cmd->destRight); + stream_write_uint16(s, cmd->destBottom); + stream_write_uint8(s, cmd->bpp); + stream_write_uint16(s, 0); /* reserved1, reserved2 */ + stream_write_uint8(s, cmd->codecID); + stream_write_uint16(s, cmd->width); + stream_write_uint16(s, cmd->height); + stream_write_uint32(s, cmd->bitmapDataLength); +} + +void update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId) +{ + stream_check_size(s, SURFCMD_FRAME_MARKER_LENGTH); + + stream_write_uint16(s, CMDTYPE_FRAME_MARKER); + + stream_write_uint16(s, frameAction); + stream_write_uint32(s, frameId); +} + diff --git a/libfreerdp-core/surface.h b/libfreerdp-core/surface.h new file mode 100644 index 0000000..c19ed0d --- /dev/null +++ b/libfreerdp-core/surface.h @@ -0,0 +1,48 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Surface Commands + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SURFACE +#define __SURFACE + +#include "rdp.h" +#include + +#define SURFCMD_SURFACE_BITS_HEADER_LENGTH 22 +#define SURFCMD_FRAME_MARKER_LENGTH 8 + +enum SURFCMD_CMDTYPE +{ + CMDTYPE_SET_SURFACE_BITS = 0x0001, + CMDTYPE_FRAME_MARKER = 0x0004, + CMDTYPE_STREAM_SURFACE_BITS = 0x0006 +}; + +enum SURFCMD_FRAMEACTION +{ + SURFACECMD_FRAMEACTION_BEGIN = 0x0000, + SURFACECMD_FRAMEACTION_END = 0x0001 +}; + +boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s); + +void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd); +void update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId); + +#endif /* __SURFACE */ + diff --git a/libfreerdp-core/tcp.c b/libfreerdp-core/tcp.c new file mode 100644 index 0000000..095f369 --- /dev/null +++ b/libfreerdp-core/tcp.c @@ -0,0 +1,332 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transmission Control Protocol (TCP) + * + * Copyright 2011 Vic Lee + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#ifndef TCP_KEEPIDLE +#define TCP_KEEPIDLE TCP_KEEPALIVE +#endif +#endif + +#else +#define SHUT_RDWR SD_BOTH +#define close(_fd) closesocket(_fd) +#endif + +#include +#include +#include + +#include "tcp.h" + +void tcp_get_ip_address(rdpTcp * tcp) +{ + uint8* ip; + socklen_t length; + struct sockaddr_in sockaddr; + + length = sizeof(sockaddr); + + if (getsockname(tcp->sockfd, (struct sockaddr*) &sockaddr, &length) == 0) + { + ip = (uint8*) (&sockaddr.sin_addr); + snprintf(tcp->ip_address, sizeof(tcp->ip_address), + "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + } + else + { + strncpy(tcp->ip_address, "127.0.0.1", sizeof(tcp->ip_address)); + } + + tcp->ip_address[sizeof(tcp->ip_address) - 1] = 0; + + tcp->settings->ipv6 = 0; + tcp->settings->ip_address = xstrdup(tcp->ip_address); +} + +void tcp_get_mac_address(rdpTcp * tcp) +{ +#ifdef LINUX + uint8* mac; + struct ifreq if_req; + struct if_nameindex* ni; + + ni = if_nameindex(); + mac = tcp->mac_address; + + while (ni->if_name != NULL) + { + if (strcmp(ni->if_name, "lo") != 0) + break; + + ni++; + } + + strncpy(if_req.ifr_name, ni->if_name, IF_NAMESIZE); + + if (ioctl(tcp->sockfd, SIOCGIFHWADDR, &if_req) != 0) + { + printf("failed to obtain MAC address\n"); + return; + } + + memmove((void*) mac, (void*) &if_req.ifr_ifru.ifru_hwaddr.sa_data[0], 6); +#endif + + /* printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */ +} + +boolean tcp_connect(rdpTcp* tcp, const char* hostname, uint16 port) +{ + int status; + char servname[10]; + uint32 option_value; + socklen_t option_len; + struct addrinfo hints = { 0 }; + struct addrinfo * res, * ai; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + snprintf(servname, sizeof(servname), "%d", port); + status = getaddrinfo(hostname, servname, &hints, &res); + + if (status != 0) + { + printf("transport_connect: getaddrinfo (%s)\n", gai_strerror(status)); + return false; + } + + tcp->sockfd = -1; + for (ai = res; ai; ai = ai->ai_next) + { + tcp->sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + + if (tcp->sockfd < 0) + continue; + + if (connect(tcp->sockfd, ai->ai_addr, ai->ai_addrlen) == 0) + { + printf("connected to %s:%s\n", hostname, servname); + break; + } + + close(tcp->sockfd); + tcp->sockfd = -1; + } + freeaddrinfo(res); + + if (tcp->sockfd == -1) + { + printf("unable to connect to %s:%s\n", hostname, servname); + return false; + } + + tcp_get_ip_address(tcp); + tcp_get_mac_address(tcp); + + option_value = 1; + option_len = sizeof(option_value); + setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len); + + /* receive buffer must be a least 32 K */ + if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0) + { + if (option_value < (1024 * 32)) + { + option_value = 1024 * 32; + option_len = sizeof(option_value); + setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len); + } + } + + tcp_set_keep_alive_mode(tcp); + + return true; +} + +int tcp_read(rdpTcp* tcp, uint8* data, int length) +{ + int status; + + status = recv(tcp->sockfd, data, length, 0); + + if (status == 0) + { + /* Peer disconnected. */ + return -1; + } + else if (status < 0) + { +#ifdef _WIN32 + int wsa_error = WSAGetLastError(); + + /* No data available */ + if (wsa_error == WSAEWOULDBLOCK) + return 0; + + printf("recv() error: %d\n", wsa_error); +#else + /* No data available */ + if (errno == EAGAIN || errno == EWOULDBLOCK) + return 0; + + perror("recv"); +#endif + return -1; + } + + return status; +} + +int tcp_write(rdpTcp* tcp, uint8* data, int length) +{ + int status; + + status = send(tcp->sockfd, data, length, MSG_NOSIGNAL); + + if (status < 0) + { +#ifdef _WIN32 + int wsa_error = WSAGetLastError(); + + /* No data available */ + if (wsa_error == WSAEWOULDBLOCK) + status = 0; + else + perror("send"); +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) + status = 0; + else + perror("send"); +#endif + } + + return status; +} + +boolean tcp_disconnect(rdpTcp * tcp) +{ + if (tcp->sockfd != -1) + { + shutdown(tcp->sockfd, SHUT_RDWR); + close(tcp->sockfd); + tcp->sockfd = -1; + } + + return true; +} + +boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking) +{ +#ifndef _WIN32 + int flags; + flags = fcntl(tcp->sockfd, F_GETFL); + + if (flags == -1) + { + printf("tcp_set_blocking_mode: fcntl failed.\n"); + return false; + } + + if (blocking == true) + fcntl(tcp->sockfd, F_SETFL, flags & ~(O_NONBLOCK)); + else + fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK); +#else + u_long arg = blocking; + ioctlsocket(tcp->sockfd, FIONBIO, &arg); + tcp->wsa_event = WSACreateEvent(); + WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ); +#endif + + return true; +} + +boolean tcp_set_keep_alive_mode(rdpTcp* tcp) +{ +#ifndef _WIN32 + uint32 option_value; + socklen_t option_len; + + option_value = 1; + option_len = sizeof(option_value); + + if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_KEEPALIVE, (void*) &option_value, option_len) < 0) + { + perror("setsockopt() SOL_SOCKET, SO_KEEPALIVE:"); + return false; + } + +#ifdef TCP_KEEPIDLE + option_value = 5; + option_len = sizeof(option_value); + + if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_KEEPIDLE, (void*) &option_value, option_len) < 0) + { + perror("setsockopt() IPPROTO_TCP, SO_KEEPIDLE:"); + return false; + } +#endif +#endif + + return true; +} + +rdpTcp* tcp_new(rdpSettings* settings) +{ + rdpTcp* tcp; + + tcp = (rdpTcp*) xzalloc(sizeof(rdpTcp)); + + if (tcp != NULL) + { + tcp->sockfd = -1; + tcp->settings = settings; + } + + return tcp; +} + +void tcp_free(rdpTcp* tcp) +{ + if (tcp != NULL) + { + xfree(tcp); + } +} diff --git a/libfreerdp-core/tcp.h b/libfreerdp-core/tcp.h new file mode 100644 index 0000000..6d0cd5b --- /dev/null +++ b/libfreerdp-core/tcp.h @@ -0,0 +1,61 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transmission Control Protocol (TCP) + * + * Copyright 2011 Vic Lee + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TCP_H +#define __TCP_H + +#ifdef _WIN32 +#include +#include +#include +#endif + +#include +#include +#include + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +typedef struct rdp_tcp rdpTcp; + +struct rdp_tcp +{ + int sockfd; + char ip_address[32]; + uint8 mac_address[6]; + struct rdp_settings* settings; +#ifdef _WIN32 + WSAEVENT wsa_event; +#endif +}; + +boolean tcp_connect(rdpTcp* tcp, const char* hostname, uint16 port); +boolean tcp_disconnect(rdpTcp* tcp); +int tcp_read(rdpTcp* tcp, uint8* data, int length); +int tcp_write(rdpTcp* tcp, uint8* data, int length); +boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking); +boolean tcp_set_keep_alive_mode(rdpTcp* tcp); + +rdpTcp* tcp_new(rdpSettings* settings); +void tcp_free(rdpTcp* tcp); + +#endif /* __TCP_H */ diff --git a/libfreerdp-core/tls.c b/libfreerdp-core/tls.c new file mode 100644 index 0000000..3d49068 --- /dev/null +++ b/libfreerdp-core/tls.c @@ -0,0 +1,434 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transport Layer Security + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "tls.h" + +boolean tls_connect(rdpTls* tls) +{ + int connection_status; + + tls->ctx = SSL_CTX_new(TLSv1_client_method()); + + if (tls->ctx == NULL) + { + printf("SSL_CTX_new failed\n"); + return false; + } + + /* + * This is necessary, because the Microsoft TLS implementation is not perfect. + * SSL_OP_ALL enables a couple of workarounds for buggy TLS implementations, + * but the most important workaround being SSL_OP_TLS_BLOCK_PADDING_BUG. + * As the size of the encrypted payload may give hints about its contents, + * block padding is normally used, but the Microsoft TLS implementation + * won't recognize it and will disconnect you after sending a TLS alert. + */ + SSL_CTX_set_options(tls->ctx, SSL_OP_ALL); + + tls->ssl = SSL_new(tls->ctx); + + if (tls->ssl == NULL) + { + printf("SSL_new failed\n"); + return false; + } + + if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) + { + printf("SSL_set_fd failed\n"); + return false; + } + + connection_status = SSL_connect(tls->ssl); + + if (connection_status <= 0) + { + if (tls_print_error("SSL_connect", tls->ssl, connection_status)) + return false; + } + + return true; +} + +boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) +{ + int connection_status; + + tls->ctx = SSL_CTX_new(TLSv1_server_method()); + + if (tls->ctx == NULL) + { + printf("SSL_CTX_new failed\n"); + return false; + } + + if (SSL_CTX_use_RSAPrivateKey_file(tls->ctx, privatekey_file, SSL_FILETYPE_PEM) <= 0) + { + printf("SSL_CTX_use_RSAPrivateKey_file failed\n"); + return false; + } + + tls->ssl = SSL_new(tls->ctx); + + if (tls->ssl == NULL) + { + printf("SSL_new failed\n"); + return false; + } + + if (SSL_use_certificate_file(tls->ssl, cert_file, SSL_FILETYPE_PEM) <= 0) + { + printf("SSL_use_certificate_file failed\n"); + return false; + } + + if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) + { + printf("SSL_set_fd failed\n"); + return false; + } + + connection_status = SSL_accept(tls->ssl); + + if (connection_status <= 0) + { + if (tls_print_error("SSL_accept", tls->ssl, connection_status)) + return false; + } + + printf("TLS connection accepted\n"); + + return true; +} + +boolean tls_disconnect(rdpTls* tls) +{ + SSL_shutdown(tls->ssl); + return true; +} + +int tls_read(rdpTls* tls, uint8* data, int length) +{ + int status; + + status = SSL_read(tls->ssl, data, length); + + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + tls_print_error("SSL_read", tls->ssl, status); + status = -1; + break; + } + + return status; +} + +int tls_write(rdpTls* tls, uint8* data, int length) +{ + int status; + + status = SSL_write(tls->ssl, data, length); + + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + tls_print_error("SSL_write", tls->ssl, status); + status = -1; + break; + } + + return status; +} + +boolean tls_print_error(char* func, SSL* connection, int value) +{ + switch (SSL_get_error(connection, value)) + { + case SSL_ERROR_ZERO_RETURN: + printf("%s: Server closed TLS connection\n", func); + return true; + + case SSL_ERROR_WANT_READ: + printf("SSL_ERROR_WANT_READ\n"); + return false; + + case SSL_ERROR_WANT_WRITE: + printf("SSL_ERROR_WANT_WRITE\n"); + return false; + + case SSL_ERROR_SYSCALL: + printf("%s: I/O error\n", func); + return true; + + case SSL_ERROR_SSL: + printf("%s: Failure in SSL library (protocol error?)\n", func); + return true; + + default: + printf("%s: Unknown error\n", func); + return true; + } +} + +CryptoCert tls_get_certificate(rdpTls* tls) +{ + CryptoCert cert; + X509* server_cert; + + server_cert = SSL_get_peer_certificate(tls->ssl); + + if (!server_cert) + { + printf("ssl_verify: failed to get the server SSL certificate\n"); + cert = NULL; + } + else + { + cert = xmalloc(sizeof(*cert)); + cert->px509 = server_cert; + } + + return cert; +} + +boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname) +{ + int match; + int index; + char* common_name; + int common_name_length; + char** alt_names; + int alt_names_count; + int* alt_names_lengths; + boolean certificate_status; + boolean hostname_match = false; + rdpCertificateData* certificate_data; + + /* ignore certificate verification if user explicitly required it (discouraged) */ + if (tls->settings->ignore_certificate) + return true; /* success! */ + + /* if user explicitly specified a certificate name, use it instead of the hostname */ + if (tls->settings->certificate_name) + hostname = tls->settings->certificate_name; + + /* attempt verification using OpenSSL and the ~/.freerdp/certs certificate store */ + certificate_status = x509_verify_certificate(cert, tls->certificate_store->path); + + /* verify certificate name match */ + certificate_data = crypto_get_certificate_data(cert->px509, hostname); + + /* extra common name and alternative names */ + common_name = crypto_cert_subject_common_name(cert->px509, &common_name_length); + alt_names = crypto_cert_subject_alt_name(cert->px509, &alt_names_count, &alt_names_lengths); + + /* compare against common name */ + + if (common_name != NULL) + { + if (strlen(hostname) == common_name_length) + { + if (memcmp((void*) hostname, (void*) common_name, common_name_length) == 0) + hostname_match = true; + } + } + + /* compare against alternative names */ + + if (alt_names != NULL) + { + for (index = 0; index < alt_names_count; index++) + { + if (strlen(hostname) == alt_names_lengths[index]) + { + if (memcmp((void*) hostname, (void*) alt_names[index], alt_names_lengths[index]) == 0) + hostname_match = true; + } + } + } + + /* if the certificate is valid and the certificate name matches, verification succeeds */ + if (certificate_status && hostname_match) + return true; /* success! */ + + /* if the certificate is valid but the certificate name does not match, warn user, do not accept */ + if (certificate_status && !hostname_match) + tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); + + /* verification could not succeed with OpenSSL, use known_hosts file and prompt user for manual verification */ + + if (!certificate_status) + { + char* issuer; + char* subject; + char* fingerprint; + boolean accept_certificate = false; + boolean verification_status = false; + + issuer = crypto_cert_issuer(cert->px509); + subject = crypto_cert_subject(cert->px509); + fingerprint = crypto_cert_fingerprint(cert->px509); + + /* search for matching entry in known_hosts file */ + match = certificate_data_match(tls->certificate_store, certificate_data); + + if (match == 1) + { + /* no entry was found in known_hosts file, prompt user for manual verification */ + + freerdp* instance = (freerdp*) tls->settings->instance; + + if (!hostname_match) + tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count); + + if (instance->VerifyCertificate) + accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint); + + if (!accept_certificate) + { + /* user did not accept, abort and do not add entry in known_hosts file */ + verification_status = false; /* failure! */ + } + else + { + /* user accepted certificate, add entry in known_hosts file */ + certificate_data_print(tls->certificate_store, certificate_data); + verification_status = true; /* success! */ + } + } + else if (match == -1) + { + /* entry was found in known_hosts file, but fingerprint does not match */ + tls_print_certificate_error(hostname, fingerprint); + verification_status = false; /* failure! */ + } + else if (match == 0) + { + verification_status = true; /* success! */ + } + + xfree(issuer); + xfree(subject); + xfree(fingerprint); + + return verification_status; + } + + return false; +} + +void tls_print_certificate_error(char* hostname, char* fingerprint) +{ + printf("The host key for %s has changed\n", hostname); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + printf("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @\n"); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + printf("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"); + printf("Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"); + printf("It is also possible that a host key has just been changed.\n"); + printf("The fingerprint for the host key sent by the remote host is\n%s\n", fingerprint); + printf("Please contact your system administrator.\n"); + printf("Add correct host key in ~/.freerdp/known_hosts to get rid of this message.\n"); + printf("Host key for %s has changed and you have requested strict checking.\n", hostname); + printf("Host key verification failed.\n"); +} + +void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count) +{ + int index; + + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + printf("@ WARNING: CERTIFICATE NAME MISMATCH! @\n"); + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + printf("The hostname used for this connection (%s) \n", hostname); + + if (alt_names_count < 1) + { + printf("does not match the name given in the certificate:\n"); + printf("%s\n", common_name); + } + else + { + printf("does not match the names given in the certificate:\n"); + printf("%s", common_name); + + for (index = 0; index < alt_names_count; index++) + { + printf(", %s", alt_names[index]); + } + + printf("\n"); + } + + printf("A valid certificate for the wrong name should NOT be trusted!\n"); +} + +rdpTls* tls_new(rdpSettings* settings) +{ + rdpTls* tls; + + tls = (rdpTls*) xzalloc(sizeof(rdpTls)); + + if (tls != NULL) + { + SSL_load_error_strings(); + SSL_library_init(); + + tls->settings = settings; + tls->certificate_store = certificate_store_new(settings); + } + + return tls; +} + +void tls_free(rdpTls* tls) +{ + if (tls != NULL) + { + if (tls->ssl) + SSL_free(tls->ssl); + + if (tls->ctx) + SSL_CTX_free(tls->ctx); + + certificate_store_free(tls->certificate_store); + + xfree(tls); + } +} diff --git a/libfreerdp-core/tls.h b/libfreerdp-core/tls.h new file mode 100644 index 0000000..c3f2f59 --- /dev/null +++ b/libfreerdp-core/tls.h @@ -0,0 +1,60 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transport Layer Security + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TLS_H +#define __TLS_H + +#include "crypto.h" +#include "certificate.h" + +#include +#include + +#include +#include + +typedef struct rdp_tls rdpTls; + +struct rdp_tls +{ + SSL* ssl; + int sockfd; + SSL_CTX* ctx; + rdpSettings* settings; + rdpCertificateStore* certificate_store; +}; + +boolean tls_connect(rdpTls* tls); +boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file); +boolean tls_disconnect(rdpTls* tls); + +int tls_read(rdpTls* tls, uint8* data, int length); +int tls_write(rdpTls* tls, uint8* data, int length); + +CryptoCert tls_get_certificate(rdpTls* tls); +boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname); +void tls_print_certificate_error(char* hostname, char* fingerprint); +void tls_print_certificate_name_mismatch_error(char* hostname, char* common_name, char** alt_names, int alt_names_count); + +boolean tls_print_error(char* func, SSL* connection, int value); + +rdpTls* tls_new(rdpSettings* settings); +void tls_free(rdpTls* tls); + +#endif /* __TLS_H */ diff --git a/libfreerdp-core/tpdu.c b/libfreerdp-core/tpdu.c new file mode 100644 index 0000000..c1e0ffa --- /dev/null +++ b/libfreerdp-core/tpdu.c @@ -0,0 +1,223 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X.224 Transport Protocol Data Units (TPDUs) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "tpdu.h" + +/** + * TPDUs are defined in: + * + * http://www.itu.int/rec/T-REC-X.224-199511-I/ + * X.224: Information technology - Open Systems Interconnection - Protocol for providing the connection-mode transport service + * + * RDP uses only TPDUs of class 0, the "simple class" defined in section 8 of X.224 + * + * TPDU Header + * ____________________ byte + * | | + * | LI | 1 + * |____________________| + * | | + * | Code | 2 + * |____________________| + * | | + * | | 3 + * |_______DST-REF______| + * | | + * | | 4 + * |____________________| + * | | + * | | 5 + * |_______SRC-REF______| + * | | + * | | 6 + * |____________________| + * | | + * | Class | 7 + * |____________________| + * | ... | + */ + +/** + * Read TPDU header. + * @param s stream + * @param code variable pointer to receive TPDU code + * @return TPDU length indicator (LI) + */ + +uint8 +tpdu_read_header(STREAM* s, uint8* code) +{ + uint8 li; + + stream_read_uint8(s, li); /* LI */ + stream_read_uint8(s, *code); /* Code */ + + if (*code == X224_TPDU_DATA) + { + /* EOT (1 byte) */ + stream_seek(s, 1); + } + else + { + /* DST-REF (2 bytes) */ + /* SRC-REF (2 bytes) */ + /* Class 0 (1 byte) */ + stream_seek(s, 5); + } + + return li; +} + +/** + * Write TDPU header. + * @param s stream + * @param length length + * @param code TPDU code + */ + +void +tpdu_write_header(STREAM* s, uint16 length, uint8 code) +{ + stream_write_uint8(s, length); /* LI */ + stream_write_uint8(s, code); /* code */ + + if (code == X224_TPDU_DATA) + { + stream_write_uint8(s, 0x80); /* EOT */ + } + else + { + stream_write_uint16(s, 0); /* DST-REF */ + stream_write_uint16(s, 0); /* SRC-REF */ + stream_write_uint8(s, 0); /* Class 0 */ + } +} + +/** + * Read Connection Request TPDU + * @param s stream + * @return length indicator (LI) + */ + +uint8 tpdu_read_connection_request(STREAM* s) +{ + uint8 li; + uint8 code; + + li = tpdu_read_header(s, &code); + + if (code != X224_TPDU_CONNECTION_REQUEST) + { + printf("Error: expected X224_TPDU_CONNECTION_REQUEST\n"); + return 0; + } + + return li; +} + +/** + * Write Connection Request TPDU. + * @param s stream + * @param length TPDU length + */ + +void +tpdu_write_connection_request(STREAM* s, uint16 length) +{ + tpdu_write_header(s, length, X224_TPDU_CONNECTION_REQUEST); +} + +/** + * Read Connection Confirm TPDU. + * @param s stream + * @return length indicator (LI) + */ + +uint8 +tpdu_read_connection_confirm(STREAM* s) +{ + uint8 li; + uint8 code; + + li = tpdu_read_header(s, &code); + + if (code != X224_TPDU_CONNECTION_CONFIRM) + { + printf("Error: expected X224_TPDU_CONNECTION_CONFIRM\n"); + return 0; + } + + return li; +} + +/** + * Write Connection Confirm TPDU. + * @param s stream + * @param length TPDU length + */ + +void +tpdu_write_connection_confirm(STREAM* s, uint16 length) +{ + tpdu_write_header(s, length, X224_TPDU_CONNECTION_CONFIRM); +} + +/** + * Write Disconnect Request TPDU. + * @param s stream + * @param length TPDU length + */ + +void +tpdu_write_disconnect_request(STREAM* s, uint16 length) +{ + tpdu_write_header(s, length, X224_TPDU_DISCONNECT_REQUEST); +} + +/** + * Write Data TPDU. + * @param s stream + */ + +void +tpdu_write_data(STREAM* s) +{ + tpdu_write_header(s, 2, X224_TPDU_DATA); +} + +/** + * Read Data TPDU. + * @param s stream + */ + +uint16 +tpdu_read_data(STREAM* s) +{ + uint8 code; + uint16 li; + + li = tpdu_read_header(s, &code); + + if (code != X224_TPDU_DATA) + return 0; + + return li; +} diff --git a/libfreerdp-core/tpdu.h b/libfreerdp-core/tpdu.h new file mode 100644 index 0000000..c85273c --- /dev/null +++ b/libfreerdp-core/tpdu.h @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X.224 Transport Protocol Data Units (TPDUs) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TPDU_H +#define __TPDU_H + +#include + +enum X224_TPDU_TYPE +{ + X224_TPDU_CONNECTION_REQUEST = 0xE0, + X224_TPDU_CONNECTION_CONFIRM = 0xD0, + X224_TPDU_DISCONNECT_REQUEST = 0x80, + X224_TPDU_DATA = 0xF0, + X224_TPDU_ERROR = 0x70 +}; + +#define TPDU_DATA_HEADER_LENGTH 3 +#define TPDU_CONNECTION_REQUEST_HEADER_LENGTH 7 +#define TPDU_CONNECTION_CONFIRM_HEADER_LENGTH 7 +#define TPDU_DISCONNECT_REQUEST_HEADER_LENGTH 7 + +#define TPDU_DATA_LENGTH (TPKT_HEADER_LENGTH + TPDU_DATA_HEADER_LENGTH) +#define TPDU_CONNECTION_REQUEST_LENGTH (TPKT_HEADER_LENGTH + TPDU_CONNECTION_REQUEST_HEADER_LENGTH) +#define TPDU_CONNECTION_CONFIRM_LENGTH (TPKT_HEADER_LENGTH + TPDU_CONNECTION_CONFIRM_HEADER_LENGTH) +#define TPDU_DISCONNECT_REQUEST_LENGTH (TPKT_HEADER_LENGTH + TPDU_DISCONNECT_REQUEST_HEADER_LENGTH) + +uint8 tpdu_read_header(STREAM* s, uint8* code); +void tpdu_write_header(STREAM* s, uint16 length, uint8 code); +uint8 tpdu_read_connection_request(STREAM* s); +void tpdu_write_connection_request(STREAM* s, uint16 length); +uint8 tpdu_read_connection_confirm(STREAM* s); +void tpdu_write_connection_confirm(STREAM* s, uint16 length); +void tpdu_write_disconnect_request(STREAM* s, uint16 length); +uint16 tpdu_read_data(STREAM* s); +void tpdu_write_data(STREAM* s); + +#endif /* __TPDU_H */ diff --git a/libfreerdp-core/tpkt.c b/libfreerdp-core/tpkt.c new file mode 100644 index 0000000..449a2ae --- /dev/null +++ b/libfreerdp-core/tpkt.c @@ -0,0 +1,111 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transport Packets (TPKTs) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tpdu.h" + +#include "tpkt.h" + +/** + * TPKTs are defined in: + * + * http://tools.ietf.org/html/rfc1006/ + * RFC 1006 - ISO Transport Service on top of the TCP + * + * http://www.itu.int/rec/T-REC-T.123/ + * ITU-T T.123 (01/2007) - Network-specific data protocol stacks for multimedia conferencing + * + * TPKT Header + * ____________________ byte + * | | + * | 3 (version) | 1 + * |____________________| + * | | + * | Reserved | 2 + * |____________________| + * | | + * | Length (MSB) | 3 + * |____________________| + * | | + * | Length (LSB) | 4 + * |____________________| + * | | + * | X.224 TPDU | 5 - ? + * .... + * + * A TPKT header is of fixed length 4, and the following X.224 TPDU is at least three bytes long. + * Therefore, the minimum TPKT length is 7, and the maximum TPKT length is 65535. Because the TPKT + * length includes the TPKT header (4 bytes), the maximum X.224 TPDU length is 65531. + */ + +/** + * Verify if a packet has valid TPKT header.\n + * @param s + * @return boolean + */ + +boolean tpkt_verify_header(STREAM* s) +{ + uint8 version; + + stream_peek_uint8(s, version); + if (version == 3) + return true; + else + return false; +} + +/** + * Read a TPKT header.\n + * @param s + * @return length + */ + +uint16 tpkt_read_header(STREAM* s) +{ + uint8 version; + uint16 length; + + stream_peek_uint8(s, version); + + if (version == 3) + { + stream_seek(s, 2); + stream_read_uint16_be(s, length); + } + else + { + /* not a TPKT header */ + length = 0; + } + + return length; +} + +/** + * Write a TPKT header.\n + * @param s + * @param length + */ + +void tpkt_write_header(STREAM* s, uint16 length) +{ + stream_write_uint8(s, 3); /* version */ + stream_write_uint8(s, 0); /* reserved */ + stream_write_uint16_be(s, length); /* length */ +} diff --git a/libfreerdp-core/tpkt.h b/libfreerdp-core/tpkt.h new file mode 100644 index 0000000..331bafd --- /dev/null +++ b/libfreerdp-core/tpkt.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Transport Packets (TPKTs) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TPKT_H +#define __TPKT_H + +#include "tpdu.h" +#include "transport.h" + +#include + +#define TPKT_HEADER_LENGTH 4 + +boolean tpkt_verify_header(STREAM* s); +uint16 tpkt_read_header(STREAM* s); +void tpkt_write_header(STREAM* s, uint16 length); + +#endif /* __TPKT_H */ diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c new file mode 100644 index 0000000..0bfc62f --- /dev/null +++ b/libfreerdp-core/transport.c @@ -0,0 +1,417 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Network Transport Layer + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef _WIN32 +#include +#include +#endif + +#include "tpkt.h" +#include "fastpath.h" +#include "credssp.h" +#include "transport.h" + +#define BUFFER_SIZE 16384 + +STREAM* transport_recv_stream_init(rdpTransport* transport, int size) +{ + STREAM* s = transport->recv_stream; + stream_check_size(s, size); + stream_set_pos(s, 0); + return s; +} + +STREAM* transport_send_stream_init(rdpTransport* transport, int size) +{ + STREAM* s = transport->send_stream; + stream_check_size(s, size); + stream_set_pos(s, 0); + return s; +} + +boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port) +{ + return tcp_connect(transport->tcp, hostname, port); +} + +void transport_attach(rdpTransport* transport, int sockfd) +{ + transport->tcp->sockfd = sockfd; +} + +boolean transport_disconnect(rdpTransport* transport) +{ + if (transport->layer == TRANSPORT_LAYER_TLS) + tls_disconnect(transport->tls); + return tcp_disconnect(transport->tcp); +} + +boolean transport_connect_rdp(rdpTransport* transport) +{ + /* RDP encryption */ + + return true; +} + +boolean transport_connect_tls(rdpTransport* transport) +{ + if (transport->tls == NULL) + transport->tls = tls_new(transport->settings); + + transport->layer = TRANSPORT_LAYER_TLS; + transport->tls->sockfd = transport->tcp->sockfd; + + if (tls_connect(transport->tls) != true) + return false; + + return true; +} + +boolean transport_connect_nla(rdpTransport* transport) +{ + if (transport->tls == NULL) + transport->tls = tls_new(transport->settings); + + transport->layer = TRANSPORT_LAYER_TLS; + transport->tls->sockfd = transport->tcp->sockfd; + + if (tls_connect(transport->tls) != true) + return false; + + /* Network Level Authentication */ + + if (transport->settings->authentication != true) + return true; + + if (transport->credssp == NULL) + transport->credssp = credssp_new(transport); + + if (credssp_authenticate(transport->credssp) < 0) + { + printf("Authentication failure, check credentials.\n" + "If credentials are valid, the NTLMSSP implementation may be to blame.\n"); + + credssp_free(transport->credssp); + return false; + } + + credssp_free(transport->credssp); + + return true; +} + +boolean transport_accept_rdp(rdpTransport* transport) +{ + /* RDP encryption */ + + return true; +} + +boolean transport_accept_tls(rdpTransport* transport) +{ + if (transport->tls == NULL) + transport->tls = tls_new(transport->settings); + + transport->layer = TRANSPORT_LAYER_TLS; + transport->tls->sockfd = transport->tcp->sockfd; + + if (tls_accept(transport->tls, transport->settings->cert_file, transport->settings->privatekey_file) != true) + return false; + + return true; +} + +boolean transport_accept_nla(rdpTransport* transport) +{ + if (transport->tls == NULL) + transport->tls = tls_new(transport->settings); + + transport->layer = TRANSPORT_LAYER_TLS; + transport->tls->sockfd = transport->tcp->sockfd; + + if (tls_accept(transport->tls, transport->settings->cert_file, transport->settings->privatekey_file) != true) + return false; + + /* Network Level Authentication */ + + if (transport->settings->authentication != true) + return true; + + /* Blocking here until NLA is complete */ + + return true; +} + +int transport_read(rdpTransport* transport, STREAM* s) +{ + int status = -1; + + while (true) + { + if (transport->layer == TRANSPORT_LAYER_TLS) + status = tls_read(transport->tls, stream_get_tail(s), stream_get_left(s)); + else if (transport->layer == TRANSPORT_LAYER_TCP) + status = tcp_read(transport->tcp, stream_get_tail(s), stream_get_left(s)); + + if (status == 0 && transport->blocking) + { + freerdp_usleep(transport->usleep_interval); + continue; + } + + break; + } + +#ifdef WITH_DEBUG_TRANSPORT + if (status > 0) + { + printf("Local < Remote\n"); + freerdp_hexdump(s->data, status); + } +#endif + + return status; +} + +static int transport_read_nonblocking(rdpTransport* transport) +{ + int status; + + stream_check_size(transport->recv_buffer, 4096); + status = transport_read(transport, transport->recv_buffer); + + if (status <= 0) + return status; + + stream_seek(transport->recv_buffer, status); + + return status; +} + +int transport_write(rdpTransport* transport, STREAM* s) +{ + int status = -1; + int length; + + length = stream_get_length(s); + stream_set_pos(s, 0); + +#ifdef WITH_DEBUG_TRANSPORT + if (length > 0) + { + printf("Local > Remote\n"); + freerdp_hexdump(s->data, length); + } +#endif + + while (length > 0) + { + if (transport->layer == TRANSPORT_LAYER_TLS) + status = tls_write(transport->tls, stream_get_tail(s), length); + else if (transport->layer == TRANSPORT_LAYER_TCP) + status = tcp_write(transport->tcp, stream_get_tail(s), length); + + if (status < 0) + break; /* error occurred */ + + if (status == 0) + { + /* blocking while sending */ + freerdp_usleep(transport->usleep_interval); + + /* when sending is blocked in nonblocking mode, the receiving buffer should be checked */ + if (!transport->blocking) + { + /* and in case we do have buffered some data, we set the event so next loop will get it */ + if (transport_read_nonblocking(transport) > 0) + wait_obj_set(transport->recv_event); + } + } + + length -= status; + stream_seek(s, status); + } + + if (status < 0) + { + /* A write error indicates that the peer has dropped the connection */ + transport->layer = TRANSPORT_LAYER_CLOSED; + } + + return status; +} + +void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount) +{ + rfds[*rcount] = (void*)(long)(transport->tcp->sockfd); + (*rcount)++; + wait_obj_get_fds(transport->recv_event, rfds, rcount); +} + +int transport_check_fds(rdpTransport* transport) +{ + int pos; + int status; + uint16 length; + STREAM* received; + + wait_obj_clear(transport->recv_event); + + status = transport_read_nonblocking(transport); + + if (status < 0) + return status; + + while ((pos = stream_get_pos(transport->recv_buffer)) > 0) + { + stream_set_pos(transport->recv_buffer, 0); + if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */ + { + /* Ensure the TPKT header is available. */ + if (pos <= 4) + { + stream_set_pos(transport->recv_buffer, pos); + return 0; + } + length = tpkt_read_header(transport->recv_buffer); + } + else /* Fast Path */ + { + /* Ensure the Fast Path header is available. */ + if (pos <= 2) + { + stream_set_pos(transport->recv_buffer, pos); + return 0; + } + /* Fastpath header can be two or three bytes long. */ + length = fastpath_header_length(transport->recv_buffer); + if (pos < length) + { + stream_set_pos(transport->recv_buffer, pos); + return 0; + } + length = fastpath_read_header(NULL, transport->recv_buffer); + } + + if (length == 0) + { + printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); + freerdp_hexdump(stream_get_head(transport->recv_buffer), pos); + return -1; + } + + if (pos < length) + { + stream_set_pos(transport->recv_buffer, pos); + return 0; /* Packet is not yet completely received. */ + } + + /* + * A complete packet has been received. In case there are trailing data + * for the next packet, we copy it to the new receive buffer. + */ + received = transport->recv_buffer; + transport->recv_buffer = stream_new(BUFFER_SIZE); + + if (pos > length) + { + stream_set_pos(received, length); + stream_check_size(transport->recv_buffer, pos - length); + stream_copy(transport->recv_buffer, received, pos - length); + } + + stream_set_pos(received, length); + stream_seal(received); + stream_set_pos(received, 0); + + if (transport->recv_callback(transport, received, transport->recv_extra) == false) + status = -1; + + stream_free(received); + + if (status < 0) + return status; + } + + return 0; +} + +boolean transport_set_blocking_mode(rdpTransport* transport, boolean blocking) +{ + transport->blocking = blocking; + return tcp_set_blocking_mode(transport->tcp, blocking); +} + +rdpTransport* transport_new(rdpSettings* settings) +{ + rdpTransport* transport; + + transport = (rdpTransport*) xzalloc(sizeof(rdpTransport)); + + if (transport != NULL) + { + transport->tcp = tcp_new(settings); + transport->settings = settings; + + /* a small 0.1ms delay when transport is blocking. */ + transport->usleep_interval = 100; + + /* receive buffer for non-blocking read. */ + transport->recv_buffer = stream_new(BUFFER_SIZE); + transport->recv_event = wait_obj_new(); + + /* buffers for blocking read/write */ + transport->recv_stream = stream_new(BUFFER_SIZE); + transport->send_stream = stream_new(BUFFER_SIZE); + + transport->blocking = true; + + transport->layer = TRANSPORT_LAYER_TCP; + } + + return transport; +} + +void transport_free(rdpTransport* transport) +{ + if (transport != NULL) + { + stream_free(transport->recv_buffer); + stream_free(transport->recv_stream); + stream_free(transport->send_stream); + wait_obj_free(transport->recv_event); + if (transport->tls) + tls_free(transport->tls); + tcp_free(transport->tcp); + xfree(transport); + } +} diff --git a/libfreerdp-core/transport.h b/libfreerdp-core/transport.h new file mode 100644 index 0000000..977c837 --- /dev/null +++ b/libfreerdp-core/transport.h @@ -0,0 +1,80 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Network Transport Layer + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TRANSPORT_H +#define __TRANSPORT_H + +typedef enum +{ + TRANSPORT_LAYER_TCP, + TRANSPORT_LAYER_TLS, + TRANSPORT_LAYER_CLOSED +} TRANSPORT_LAYER; + +typedef struct rdp_transport rdpTransport; + +#include "tcp.h" +#include "tls.h" +#include "credssp.h" + +#include +#include +#include +#include +#include + +typedef boolean (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra); + +struct rdp_transport +{ + STREAM* recv_stream; + STREAM* send_stream; + TRANSPORT_LAYER layer; + struct rdp_tcp* tcp; + struct rdp_tls* tls; + struct rdp_settings* settings; + struct rdp_credssp* credssp; + uint32 usleep_interval; + void* recv_extra; + STREAM* recv_buffer; + TransportRecv recv_callback; + struct wait_obj* recv_event; + boolean blocking; +}; + +STREAM* transport_recv_stream_init(rdpTransport* transport, int size); +STREAM* transport_send_stream_init(rdpTransport* transport, int size); +boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 port); +void transport_attach(rdpTransport* transport, int sockfd); +boolean transport_disconnect(rdpTransport* transport); +boolean transport_connect_rdp(rdpTransport* transport); +boolean transport_connect_tls(rdpTransport* transport); +boolean transport_connect_nla(rdpTransport* transport); +boolean transport_accept_rdp(rdpTransport* transport); +boolean transport_accept_tls(rdpTransport* transport); +boolean transport_accept_nla(rdpTransport* transport); +int transport_read(rdpTransport* transport, STREAM* s); +int transport_write(rdpTransport* transport, STREAM* s); +void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount); +int transport_check_fds(rdpTransport* transport); +boolean transport_set_blocking_mode(rdpTransport* transport, boolean blocking); +rdpTransport* transport_new(rdpSettings* settings); +void transport_free(rdpTransport* transport); + +#endif diff --git a/libfreerdp-core/update.c b/libfreerdp-core/update.c new file mode 100644 index 0000000..17122ad --- /dev/null +++ b/libfreerdp-core/update.c @@ -0,0 +1,580 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Update Data PDUs + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "update.h" +#include "surface.h" +#include +#include + +/* +static const char* const UPDATE_TYPE_STRINGS[] = +{ + "Orders", + "Bitmap", + "Palette", + "Synchronize" +}; +*/ + +void update_recv_orders(rdpUpdate* update, STREAM* s) +{ + uint16 numberOrders; + + stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */ + stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */ + stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */ + + while (numberOrders > 0) + { + update_recv_order(update, s); + numberOrders--; + } +} + +void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data) +{ + stream_read_uint16(s, bitmap_data->destLeft); + stream_read_uint16(s, bitmap_data->destTop); + stream_read_uint16(s, bitmap_data->destRight); + stream_read_uint16(s, bitmap_data->destBottom); + stream_read_uint16(s, bitmap_data->width); + stream_read_uint16(s, bitmap_data->height); + stream_read_uint16(s, bitmap_data->bitsPerPixel); + stream_read_uint16(s, bitmap_data->flags); + stream_read_uint16(s, bitmap_data->bitmapLength); + + if (bitmap_data->flags & BITMAP_COMPRESSION) + { + if (!(bitmap_data->flags & NO_BITMAP_COMPRESSION_HDR)) + { + stream_read_uint16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */ + stream_read_uint16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */ + stream_read_uint16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */ + stream_read_uint16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */ + bitmap_data->bitmapLength = bitmap_data->cbCompMainBodySize; + } + + bitmap_data->compressed = true; + stream_get_mark(s, bitmap_data->bitmapDataStream); + stream_seek(s, bitmap_data->bitmapLength); + } + else + { + bitmap_data->compressed = false; + stream_get_mark(s, bitmap_data->bitmapDataStream); + stream_seek(s, bitmap_data->bitmapLength); + } +} + +void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update) +{ + int i; + + stream_read_uint16(s, bitmap_update->number); /* numberRectangles (2 bytes) */ + + if (bitmap_update->number > bitmap_update->count) + { + uint16 count; + + count = bitmap_update->number * 2; + + bitmap_update->rectangles = (BITMAP_DATA*) xrealloc(bitmap_update->rectangles, + sizeof(BITMAP_DATA) * count); + + memset(&bitmap_update->rectangles[bitmap_update->count], 0, + sizeof(BITMAP_DATA) * (count - bitmap_update->count)); + + bitmap_update->count = count; + } + + /* rectangles */ + for (i = 0; i < (int) bitmap_update->number; i++) + { + update_read_bitmap_data(s, &bitmap_update->rectangles[i]); + } +} + +void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update) +{ + int i; + PALETTE_ENTRY* entry; + + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + stream_read_uint32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */ + + if (palette_update->number > 256) + palette_update->number = 256; + + /* paletteEntries */ + for (i = 0; i < (int) palette_update->number; i++) + { + entry = &palette_update->entries[i]; + + stream_read_uint8(s, entry->blue); + stream_read_uint8(s, entry->green); + stream_read_uint8(s, entry->red); + } +} + +void update_read_synchronize(rdpUpdate* update, STREAM* s) +{ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + + /** + * The Synchronize Update is an artifact from the + * T.128 protocol and should be ignored. + */ +} + +void update_read_play_sound(STREAM* s, PLAY_SOUND_UPDATE* play_sound) +{ + stream_read_uint32(s, play_sound->duration); /* duration (4 bytes) */ + stream_read_uint32(s, play_sound->frequency); /* frequency (4 bytes) */ +} + +void update_recv_play_sound(rdpUpdate* update, STREAM* s) +{ + update_read_play_sound(s, &update->play_sound); + IFCALL(update->PlaySound, update->context, &update->play_sound); +} + +void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position) +{ + stream_read_uint16(s, pointer_position->xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, pointer_position->yPos); /* yPos (2 bytes) */ +} + +void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system) +{ + stream_read_uint32(s, pointer_system->type); /* systemPointerType (4 bytes) */ +} + +void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color) +{ + stream_read_uint16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */ + stream_read_uint16(s, pointer_color->xPos); /* xPos (2 bytes) */ + stream_read_uint16(s, pointer_color->yPos); /* yPos (2 bytes) */ + stream_read_uint16(s, pointer_color->width); /* width (2 bytes) */ + stream_read_uint16(s, pointer_color->height); /* height (2 bytes) */ + stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */ + stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */ + + if (pointer_color->lengthXorMask > 0) + { + pointer_color->xorMaskData = (uint8*) xmalloc(pointer_color->lengthXorMask); + stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); + } + + if (pointer_color->lengthAndMask > 0) + { + pointer_color->andMaskData = (uint8*) xmalloc(pointer_color->lengthAndMask); + stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask); + } + + if (stream_get_left(s) > 0) + stream_seek_uint8(s); /* pad (1 byte) */ +} + +void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new) +{ + stream_read_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ + update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */ +} + +void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached) +{ + stream_read_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ +} + +void update_recv_pointer(rdpUpdate* update, STREAM* s) +{ + uint16 messageType; + rdpContext* context = update->context; + rdpPointerUpdate* pointer = update->pointer; + + stream_read_uint16(s, messageType); /* messageType (2 bytes) */ + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + + switch (messageType) + { + case PTR_MSG_TYPE_POSITION: + update_read_pointer_position(s, &pointer->pointer_position); + IFCALL(pointer->PointerPosition, context, &pointer->pointer_position); + break; + + case PTR_MSG_TYPE_SYSTEM: + update_read_pointer_system(s, &pointer->pointer_system); + IFCALL(pointer->PointerSystem, context, &pointer->pointer_system); + break; + + case PTR_MSG_TYPE_COLOR: + update_read_pointer_color(s, &pointer->pointer_color); + IFCALL(pointer->PointerColor, context, &pointer->pointer_color); + break; + + case PTR_MSG_TYPE_POINTER: + update_read_pointer_new(s, &pointer->pointer_new); + IFCALL(pointer->PointerNew, context, &pointer->pointer_new); + break; + + case PTR_MSG_TYPE_CACHED: + update_read_pointer_cached(s, &pointer->pointer_cached); + IFCALL(pointer->PointerCached, context, &pointer->pointer_cached); + break; + + default: + break; + } +} + +void update_recv(rdpUpdate* update, STREAM* s) +{ + uint16 updateType; + rdpContext* context = update->context; + + stream_read_uint16(s, updateType); /* updateType (2 bytes) */ + + //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]); + + IFCALL(update->BeginPaint, context); + + switch (updateType) + { + case UPDATE_TYPE_ORDERS: + update_recv_orders(update, s); + break; + + case UPDATE_TYPE_BITMAP: + update_read_bitmap(update, s, &update->bitmap_update); + IFCALL(update->BitmapUpdate, context, &update->bitmap_update); + break; + + case UPDATE_TYPE_PALETTE: + update_read_palette(update, s, &update->palette_update); + IFCALL(update->Palette, context, &update->palette_update); + break; + + case UPDATE_TYPE_SYNCHRONIZE: + update_read_synchronize(update, s); + IFCALL(update->Synchronize, context); + break; + } + + IFCALL(update->EndPaint, context); + + if (stream_get_left(s) > RDP_SHARE_DATA_HEADER_LENGTH) + { + uint16 pduType; + uint16 length; + uint16 source; + + rdp_read_share_control_header(s, &length, &pduType, &source); + + if (pduType != PDU_TYPE_DATA) + return; + + rdp_recv_data_pdu(update->context->rdp, s); + } +} + +void update_reset_state(rdpUpdate* update) +{ + rdpPrimaryUpdate* primary = update->primary; + rdpAltSecUpdate* altsec = update->altsec; + + memset(&primary->order_info, 0, sizeof(ORDER_INFO)); + memset(&primary->dstblt, 0, sizeof(DSTBLT_ORDER)); + memset(&primary->patblt, 0, sizeof(PATBLT_ORDER)); + memset(&primary->scrblt, 0, sizeof(SCRBLT_ORDER)); + memset(&primary->opaque_rect, 0, sizeof(OPAQUE_RECT_ORDER)); + memset(&primary->draw_nine_grid, 0, sizeof(DRAW_NINE_GRID_ORDER)); + memset(&primary->multi_dstblt, 0, sizeof(MULTI_DSTBLT_ORDER)); + memset(&primary->multi_patblt, 0, sizeof(MULTI_PATBLT_ORDER)); + memset(&primary->multi_scrblt, 0, sizeof(MULTI_SCRBLT_ORDER)); + memset(&primary->multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER)); + memset(&primary->multi_draw_nine_grid, 0, sizeof(MULTI_DRAW_NINE_GRID_ORDER)); + memset(&primary->line_to, 0, sizeof(LINE_TO_ORDER)); + memset(&primary->polyline, 0, sizeof(POLYLINE_ORDER)); + memset(&primary->memblt, 0, sizeof(MEMBLT_ORDER)); + memset(&primary->mem3blt, 0, sizeof(MEM3BLT_ORDER)); + memset(&primary->save_bitmap, 0, sizeof(SAVE_BITMAP_ORDER)); + memset(&primary->glyph_index, 0, sizeof(GLYPH_INDEX_ORDER)); + memset(&primary->fast_index, 0, sizeof(FAST_INDEX_ORDER)); + memset(&primary->fast_glyph, 0, sizeof(FAST_GLYPH_ORDER)); + memset(&primary->polygon_sc, 0, sizeof(POLYGON_SC_ORDER)); + memset(&primary->polygon_cb, 0, sizeof(POLYGON_CB_ORDER)); + memset(&primary->ellipse_sc, 0, sizeof(ELLIPSE_SC_ORDER)); + memset(&primary->ellipse_cb, 0, sizeof(ELLIPSE_CB_ORDER)); + + primary->order_info.orderType = ORDER_TYPE_PATBLT; + altsec->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE; + IFCALL(altsec->SwitchSurface, update->context, &(altsec->switch_surface)); +} + +static void update_begin_paint(rdpContext* context) +{ + +} + +static void update_end_paint(rdpContext* context) +{ + +} + +static void update_write_refresh_rect(STREAM* s, uint8 count, RECTANGLE_16* areas) +{ + int i; + + stream_write_uint8(s, count); /* numberOfAreas (1 byte) */ + stream_seek(s, 3); /* pad3Octets (3 bytes) */ + + for (i = 0; i < count; i++) + freerdp_write_rectangle_16(s, &areas[i]); +} + +static void update_send_refresh_rect(rdpContext* context, uint8 count, RECTANGLE_16* areas) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = rdp_data_pdu_init(rdp); + update_write_refresh_rect(s, count, areas); + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id); +} + +static void update_write_suppress_output(STREAM* s, uint8 allow, RECTANGLE_16* area) +{ + stream_write_uint8(s, allow); /* allowDisplayUpdates (1 byte) */ + stream_seek(s, 3); /* pad3Octets (3 bytes) */ + + if (allow > 0) + freerdp_write_rectangle_16(s, area); +} + +static void update_send_suppress_output(rdpContext* context, uint8 allow, RECTANGLE_16* area) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = rdp_data_pdu_init(rdp); + update_write_suppress_output(s, allow, area); + + rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id); +} + +static void update_send_surface_command(rdpContext* context, STREAM* s) +{ + STREAM* update; + rdpRdp* rdp = context->rdp; + + update = fastpath_update_pdu_init(rdp->fastpath); + stream_check_size(update, stream_get_length(s)); + stream_write(update, stream_get_head(s), stream_get_length(s)); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update); +} + +static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + stream_check_size(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength); + update_write_surfcmd_surface_bits_header(s, surface_bits_command); + stream_write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); +} + +static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s); +} + +static void update_send_synchronize(rdpContext* context) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + stream_write_zero(s, 2); /* pad2Octets (2 bytes) */ + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s); +} + +static void update_send_desktop_resize(rdpContext* context) +{ + rdp_server_reactivate(context->rdp); +} + +static void update_send_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + + stream_write_uint16(s, 1); /* numberOrders (2 bytes) */ + stream_write_uint8(s, ORDER_STANDARD | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */ + stream_write_uint8(s, ORDER_TYPE_SCRBLT); /* orderType (1 byte) */ + stream_write_uint8(s, 0x7F); /* fieldFlags (variable) */ + + stream_write_uint16(s, scrblt->nLeftRect); + stream_write_uint16(s, scrblt->nTopRect); + stream_write_uint16(s, scrblt->nWidth); + stream_write_uint16(s, scrblt->nHeight); + stream_write_uint8(s, scrblt->bRop); + stream_write_uint16(s, scrblt->nXSrc); + stream_write_uint16(s, scrblt->nYSrc); + + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s); +} + +static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) +{ + STREAM* s; + uint8 updateCode; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + if (pointer_system->type == SYSPTR_NULL) + updateCode = FASTPATH_UPDATETYPE_PTR_NULL; + else + updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT; + fastpath_send_update_pdu(rdp->fastpath, updateCode, s); +} + +static void update_write_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color) +{ + stream_check_size(s, 15 + (int) pointer_color->lengthAndMask + (int) pointer_color->lengthXorMask); + stream_write_uint16(s, pointer_color->cacheIndex); + stream_write_uint16(s, pointer_color->xPos); + stream_write_uint16(s, pointer_color->yPos); + stream_write_uint16(s, pointer_color->width); + stream_write_uint16(s, pointer_color->height); + stream_write_uint16(s, pointer_color->lengthAndMask); + stream_write_uint16(s, pointer_color->lengthXorMask); + if (pointer_color->lengthXorMask > 0) + stream_write(s, pointer_color->xorMaskData, pointer_color->lengthXorMask); + if (pointer_color->lengthAndMask > 0) + stream_write(s, pointer_color->andMaskData, pointer_color->lengthAndMask); + stream_write_uint8(s, 0); /* pad (1 byte) */ +} + +static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + update_write_pointer_color(s, pointer_color); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s); +} + +static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + stream_write_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */ + update_write_pointer_color(s, &pointer_new->colorPtrAttr); + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s); +} + +static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached) +{ + STREAM* s; + rdpRdp* rdp = context->rdp; + + s = fastpath_update_pdu_init(rdp->fastpath); + stream_write_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */ + fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s); +} + +void update_register_server_callbacks(rdpUpdate* update) +{ + update->BeginPaint = update_begin_paint; + update->EndPaint = update_end_paint; + update->Synchronize = update_send_synchronize; + update->DesktopResize = update_send_desktop_resize; + update->RefreshRect = update_send_refresh_rect; + update->SuppressOutput = update_send_suppress_output; + update->SurfaceBits = update_send_surface_bits; + update->SurfaceFrameMarker = update_send_surface_frame_marker; + update->SurfaceCommand = update_send_surface_command; + update->primary->ScrBlt = update_send_scrblt; + update->pointer->PointerSystem = update_send_pointer_system; + update->pointer->PointerColor = update_send_pointer_color; + update->pointer->PointerNew = update_send_pointer_new; + update->pointer->PointerCached = update_send_pointer_cached; +} + +rdpUpdate* update_new(rdpRdp* rdp) +{ + rdpUpdate* update; + + update = (rdpUpdate*) xzalloc(sizeof(rdpUpdate)); + + if (update != NULL) + { + OFFSCREEN_DELETE_LIST* deleteList; + + update->bitmap_update.count = 64; + update->bitmap_update.rectangles = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * update->bitmap_update.count); + + update->pointer = xnew(rdpPointerUpdate); + update->primary = xnew(rdpPrimaryUpdate); + update->secondary = xnew(rdpSecondaryUpdate); + update->altsec = xnew(rdpAltSecUpdate); + update->window = xnew(rdpWindowUpdate); + + deleteList = &(update->altsec->create_offscreen_bitmap.deleteList); + deleteList->sIndices = 64; + deleteList->indices = xmalloc(deleteList->sIndices * 2); + deleteList->cIndices = 0; + + update->SuppressOutput = update_send_suppress_output; + } + + return update; +} + +void update_free(rdpUpdate* update) +{ + if (update != NULL) + { + OFFSCREEN_DELETE_LIST* deleteList; + deleteList = &(update->altsec->create_offscreen_bitmap.deleteList); + xfree(deleteList->indices); + + xfree(update->bitmap_update.rectangles); + xfree(update->pointer); + xfree(update->primary); + xfree(update->secondary); + xfree(update->altsec); + xfree(update->window); + xfree(update); + } +} + diff --git a/libfreerdp-core/update.h b/libfreerdp-core/update.h new file mode 100644 index 0000000..a7119e5 --- /dev/null +++ b/libfreerdp-core/update.h @@ -0,0 +1,57 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Update Data PDUs + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UPDATE_H +#define __UPDATE_H + +#include "rdp.h" +#include "orders.h" +#include +#include +#include +#include + +#define UPDATE_TYPE_ORDERS 0x0000 +#define UPDATE_TYPE_BITMAP 0x0001 +#define UPDATE_TYPE_PALETTE 0x0002 +#define UPDATE_TYPE_SYNCHRONIZE 0x0003 + +#define BITMAP_COMPRESSION 0x0001 +#define NO_BITMAP_COMPRESSION_HDR 0x0400 + +rdpUpdate* update_new(rdpRdp* rdp); +void update_free(rdpUpdate* update); +void update_free_bitmap(BITMAP_UPDATE* bitmap_update); +void update_reset_state(rdpUpdate* update); + +void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update); +void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update); +void update_recv_play_sound(rdpUpdate* update, STREAM* s); +void update_recv_pointer(rdpUpdate* update, STREAM* s); +void update_recv(rdpUpdate* update, STREAM* s); + +void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position); +void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system); +void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color); +void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new); +void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached); + +void update_register_server_callbacks(rdpUpdate* update); + +#endif /* __UPDATE_H */ diff --git a/libfreerdp-core/window.c b/libfreerdp-core/window.c new file mode 100644 index 0000000..3505819 --- /dev/null +++ b/libfreerdp-core/window.c @@ -0,0 +1,341 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windowing Alternate Secondary Orders + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "window.h" + +void update_read_icon_info(STREAM* s, ICON_INFO* icon_info) +{ + stream_read_uint16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */ + stream_read_uint8(s, icon_info->cacheId); /* cacheId (1 byte) */ + stream_read_uint8(s, icon_info->bpp); /* bpp (1 byte) */ + stream_read_uint16(s, icon_info->width); /* width (2 bytes) */ + stream_read_uint16(s, icon_info->height); /* height (2 bytes) */ + + /* cbColorTable is only present when bpp is 1, 2 or 4 */ + if (icon_info->bpp == 1 || icon_info->bpp == 2 || icon_info->bpp == 4) + stream_read_uint16(s, icon_info->cbColorTable); /* cbColorTable (2 bytes) */ + else + icon_info->cbColorTable = 0; + + stream_read_uint16(s, icon_info->cbBitsMask); /* cbBitsMask (2 bytes) */ + stream_read_uint16(s, icon_info->cbBitsColor); /* cbBitsColor (2 bytes) */ + + /* bitsMask */ + if (icon_info->bitsMask == NULL) + icon_info->bitsMask = (uint8*) xmalloc(icon_info->cbBitsMask); + else + icon_info->bitsMask = (uint8*) xrealloc(icon_info->bitsMask, icon_info->cbBitsMask); + stream_read(s, icon_info->bitsMask, icon_info->cbBitsMask); + + /* colorTable */ + if (icon_info->colorTable == NULL) + icon_info->colorTable = (uint8*) xmalloc(icon_info->cbColorTable); + else + icon_info->colorTable = (uint8*) xrealloc(icon_info->colorTable, icon_info->cbColorTable); + stream_read(s, icon_info->colorTable, icon_info->cbColorTable); + + /* bitsColor */ + if (icon_info->bitsColor == NULL) + icon_info->bitsColor = (uint8*) xmalloc(icon_info->cbBitsColor); + else + icon_info->bitsColor = (uint8*) xrealloc(icon_info->bitsColor, icon_info->cbBitsColor); + stream_read(s, icon_info->bitsColor, icon_info->cbBitsColor); +} + +void update_read_cached_icon_info(STREAM* s, CACHED_ICON_INFO* cached_icon_info) +{ + stream_read_uint16(s, cached_icon_info->cacheEntry); /* cacheEntry (2 bytes) */ + stream_read_uint8(s, cached_icon_info->cacheId); /* cacheId (1 byte) */ +} + +void update_read_notify_icon_infotip(STREAM* s, NOTIFY_ICON_INFOTIP* notify_icon_infotip) +{ + stream_read_uint32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */ + stream_read_uint32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */ + rail_read_unicode_string(s, ¬ify_icon_infotip->text); /* infoTipText */ + rail_read_unicode_string(s, ¬ify_icon_infotip->title); /* title */ +} + +void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + int i; + int size; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) + stream_read_uint32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) + { + stream_read_uint32(s, window_state->style); /* style (4 bytes) */ + stream_read_uint32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) + stream_read_uint8(s, window_state->showState); /* showState (1 byte) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) + rail_read_unicode_string(s, &window_state->titleInfo); /* titleInfo */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + stream_read_uint32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */ + stream_read_uint32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + stream_read_uint32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */ + stream_read_uint32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) + stream_read_uint8(s, window_state->RPContent); /* RPContent (1 byte) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) + stream_read_uint32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + stream_read_uint32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */ + stream_read_uint32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + stream_read_uint32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */ + stream_read_uint32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) + { + stream_read_uint32(s, window_state->windowWidth); /* windowWidth (4 bytes) */ + stream_read_uint32(s, window_state->windowHeight); /* windowHeight (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + stream_read_uint16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */ + + size = sizeof(RECTANGLE_16) * window_state->numWindowRects; + window_state->windowRects = (RECTANGLE_16*) xmalloc(size); + + /* windowRects */ + for (i = 0; i < (int) window_state->numWindowRects; i++) + { + freerdp_read_rectangle_16(s, &window_state->windowRects[i]); + } + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + stream_read_uint32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */ + stream_read_uint32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */ + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + stream_read_uint16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */ + + size = sizeof(RECTANGLE_16) * window_state->numVisibilityRects; + window_state->visibilityRects = (RECTANGLE_16*) xmalloc(size); + + /* visibilityRects */ + for (i = 0; i < (int) window_state->numVisibilityRects; i++) + { + freerdp_read_rectangle_16(s, &window_state->visibilityRects[i]); + } + } +} + +void update_read_window_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon) +{ + window_icon->iconInfo = (ICON_INFO*) xzalloc(sizeof(ICON_INFO)); + update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */ +} + +void update_read_window_cached_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon) +{ + update_read_cached_icon_info(s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */ +} + +void update_read_window_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + /* window deletion event */ +} + +void update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + rdpContext* context = update->context; + rdpWindowUpdate* window = update->window; + + stream_read_uint32(s, orderInfo->windowId); /* windowId (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) + { + DEBUG_WND("Window Icon Order"); + update_read_window_icon_order(s, orderInfo, &window->window_icon); + IFCALL(window->WindowIcon, context, orderInfo, &window->window_icon); + } + else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) + { + DEBUG_WND("Window Cached Icon Order"); + update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon); + IFCALL(window->WindowCachedIcon, context, orderInfo, &window->window_cached_icon); + } + else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) + { + DEBUG_WND("Window Deleted Order"); + update_read_window_delete_order(s, orderInfo); + IFCALL(window->WindowDelete, context, orderInfo); + } + else + { + DEBUG_WND("Window State Order"); + update_read_window_state_order(s, orderInfo, &window->window_state); + + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + IFCALL(window->WindowCreate, context, orderInfo, &window->window_state); + else + IFCALL(window->WindowUpdate, context, orderInfo, &window->window_state); + } +} + +void update_read_notification_icon_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) +{ + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + stream_read_uint32(s, notify_icon_state->version); /* version (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + rail_read_unicode_string(s, ¬ify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + update_read_notify_icon_infotip(s, ¬ify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + stream_read_uint32(s, notify_icon_state->state); /* state (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_ICON) + update_read_icon_info(s, ¬ify_icon_state->icon); /* icon (ICON_INFO) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON) + update_read_cached_icon_info(s, ¬ify_icon_state->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */ +} + +void update_read_notification_icon_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + /* notification icon deletion event */ +} + +void update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + rdpContext* context = update->context; + rdpWindowUpdate* window = update->window; + + stream_read_uint32(s, orderInfo->windowId); /* windowId (4 bytes) */ + stream_read_uint32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED) + { + DEBUG_WND("Delete Notification Icon Deleted Order"); + update_read_notification_icon_delete_order(s, orderInfo); + IFCALL(window->NotifyIconDelete, context, orderInfo); + } + else + { + DEBUG_WND("Notification Icon State Order"); + update_read_notification_icon_state_order(s, orderInfo, &window->notify_icon_state); + + if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW) + IFCALL(window->NotifyIconCreate, context, orderInfo, &window->notify_icon_state); + else + IFCALL(window->NotifyIconUpdate, context, orderInfo, &window->notify_icon_state); + } +} + +void update_read_desktop_actively_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop) +{ + int i; + int size; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + stream_read_uint32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */ + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + stream_read_uint8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */ + + size = sizeof(uint32) * monitored_desktop->numWindowIds; + + if (monitored_desktop->windowIds == NULL) + monitored_desktop->windowIds = (uint32*) xmalloc(size); + else + monitored_desktop->windowIds = (uint32*) xrealloc(monitored_desktop->windowIds, size); + + /* windowIds */ + for (i = 0; i < (int) monitored_desktop->numWindowIds; i++) + { + stream_read_uint32(s, monitored_desktop->windowIds[i]); + } + } +} + +void update_read_desktop_non_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + /* non-monitored desktop notification event */ +} + +void update_recv_desktop_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo) +{ + rdpContext* context = update->context; + rdpWindowUpdate* window = update->window; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE) + { + DEBUG_WND("Non-Monitored Desktop Order"); + update_read_desktop_non_monitored_order(s, orderInfo); + IFCALL(window->NonMonitoredDesktop, context, orderInfo); + } + else + { + DEBUG_WND("Actively Monitored Desktop Order"); + update_read_desktop_actively_monitored_order(s, orderInfo, &window->monitored_desktop); + IFCALL(window->MonitoredDesktop, context, orderInfo, &window->monitored_desktop); + } +} + +void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s) +{ + uint16 orderSize; + rdpWindowUpdate* window = update->window; + + stream_read_uint16(s, orderSize); /* orderSize (2 bytes) */ + stream_read_uint32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */ + + if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW) + update_recv_window_info_order(update, s, &window->orderInfo); + else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY) + update_recv_notification_icon_info_order(update, s, &window->orderInfo); + else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP) + update_recv_desktop_info_order(update, s, &window->orderInfo); +} + diff --git a/libfreerdp-core/window.h b/libfreerdp-core/window.h new file mode 100644 index 0000000..3ee0dff --- /dev/null +++ b/libfreerdp-core/window.h @@ -0,0 +1,36 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Windowing Alternate Secondary Orders + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Roman Barabanov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WINDOW_H +#define __WINDOW_H + +#include "update.h" + +#include + +void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s); + +#ifdef WITH_DEBUG_WND +#define DEBUG_WND(fmt, ...) DEBUG_CLASS(WND, fmt, ## __VA_ARGS__) +#else +#define DEBUG_WND(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __WINDOW_H */ diff --git a/libfreerdp-gdi/16bpp.c b/libfreerdp-gdi/16bpp.c new file mode 100644 index 0000000..70f41ca --- /dev/null +++ b/libfreerdp-gdi/16bpp.c @@ -0,0 +1,1024 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 16bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +uint16 gdi_get_color_16bpp(HGDI_DC hdc, GDI_COLOR color) +{ + uint8 r, g, b; + uint16 color16; + + GetBGR32(r, g, b, color); + + if (hdc->rgb555) + { + if (hdc->invert) + { + color16 = BGR15(r, g, b); + } + else + { + color16 = RGB15(r, g, b); + } + } + else + { + if (hdc->invert) + { + color16 = BGR16(r, g, b); + } + else + { + color16 = RGB16(r, g, b); + } + } + + return color16; +} + +int FillRect_16bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr) +{ + int x, y; + uint16 *dstp; + int nXDest, nYDest; + int nWidth, nHeight; + + uint16 color16; + + gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight); + + if (gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + + color16 = gdi_get_color_16bpp(hdc, hbr->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = color16; + dstp++; + } + } + } + + gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight); + return 0; +} + +static int BitBlt_BLACKNESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0, nWidth * hdcDest->bytesPerPixel); + } + + return 0; +} + +static int BitBlt_WHITENESS_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel); + } + + return 0; +} + +static int BitBlt_SRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int y; + uint8* srcp; + uint8* dstp; + + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || + gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) + { + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + + return 0; + } + + if (nYSrc < nYDest) + { + /* copy down (bottom to top) */ + for (y = nHeight - 1; y >= 0; y--) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else if (nYSrc > nYDest || nXSrc > nXDest) + { + /* copy up or left (top top bottom) */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else + { + /* copy straight right */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + + return 0; +} + +static int BitBlt_NOTSRCCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSTINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*dstp); + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = *srcp & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_NOTSRCERASE_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCAND_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp &= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp |= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSPDxax_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint16* dstp; + uint16 src16; + uint16 color16; + HGDI_BITMAP hSrcBmp; + + /* D = (S & P) | (~S & D) */ + /* DSPDxax, used to draw glyphs */ + + color16 = gdi_get_color_16bpp(hdcDest, hdcDest->textColor); + + hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject; + + if (hdcSrc->bytesPerPixel != 1) + { + printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel); + return 0; + } + + for (y = 0; y < nHeight; y++) + { + srcp = (uint8*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + src16 = (*srcp << 8) | *srcp; + *dstp = (src16 & color16) | (~src16 & *dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SPna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + uint16* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *srcp & ~(*patp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PDxn_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint16* dstp; + uint16* patp; + + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *dstp ^ ~(*patp); + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSna_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & (*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + + +static int BitBlt_MERGECOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + uint16* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *srcp & *patp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_MERGEPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) | *dstp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PATCOPY_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint16* dstp; + uint16* patp; + uint16 color16; + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = color16; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *patp; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATINVERT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint16* dstp; + uint16* patp; + uint16 color16; + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color16 = gdi_get_color_16bpp(hdcDest, hdcDest->brush->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= color16; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *patp ^ *dstp; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATPAINT_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint16* srcp; + uint16* dstp; + uint16* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint16*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint16*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint16*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *dstp | (*patp | ~(*srcp)); + srcp++; + dstp++; + } + } + } + + return 0; +} + +int BitBlt_16bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) +{ + if (hdcSrc != NULL) + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0) + return 0; + } + else + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + } + + gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); + + switch (rop) + { + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCCOPY: + return BitBlt_SRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SPna: + return BitBlt_SPna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSna: + return BitBlt_DSna_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSPDxax: + return BitBlt_DSPDxax_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCCOPY: + return BitBlt_NOTSRCCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCERASE: + return BitBlt_SRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCERASE: + return BitBlt_NOTSRCERASE_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCINVERT: + return BitBlt_SRCINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCAND: + return BitBlt_SRCAND_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCPAINT: + return BitBlt_SRCPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGECOPY: + return BitBlt_MERGECOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGEPAINT: + return BitBlt_MERGEPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_PATCOPY: + return BitBlt_PATCOPY_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATPAINT: + return BitBlt_PATPAINT_16bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + } + + printf("BitBlt: unknown rop: 0x%08X\n", rop); + return 1; +} + +int PatBlt_16bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop) +{ + if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + + gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight); + + switch (rop) + { + case GDI_PATCOPY: + return BitBlt_PATCOPY_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PDxn: + return BitBlt_PDxn_16bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + default: + break; + } + + printf("PatBlt: unknown rop: 0x%08X\n", rop); + + return 1; +} + +INLINE void SetPixel_BLACK_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = 0 */ + *pixel = 0; +} + +INLINE void SetPixel_NOTMERGEPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = ~(D | P) */ + *pixel = ~(*pixel | *pen); +} + +INLINE void SetPixel_MASKNOTPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = D & ~P */ + *pixel &= ~(*pen); +} + +INLINE void SetPixel_NOTCOPYPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = ~P */ + *pixel = ~(*pen); +} + +INLINE void SetPixel_MASKPENNOT_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = P & ~D */ + *pixel = *pen & ~*pixel; +} + +INLINE void SetPixel_NOT_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = ~D */ + *pixel = ~(*pixel); +} + +INLINE void SetPixel_XORPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = D ^ P */ + *pixel = *pixel ^ *pen; +} + +INLINE void SetPixel_NOTMASKPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = ~(D & P) */ + *pixel = ~(*pixel & *pen); +} + +INLINE void SetPixel_MASKPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = D & P */ + *pixel &= *pen; +} + +INLINE void SetPixel_NOTXORPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = ~(D ^ P) */ + *pixel = ~(*pixel ^ *pen); +} + +INLINE void SetPixel_NOP_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = D */ +} + +INLINE void SetPixel_MERGENOTPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = D | ~P */ + *pixel |= ~(*pen); +} + +INLINE void SetPixel_COPYPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = P */ + *pixel = *pen; +} + +INLINE void SetPixel_MERGEPENNOT_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = P | ~D */ + *pixel = *pen | ~(*pixel); +} + +INLINE void SetPixel_MERGEPEN_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = P | D */ + *pixel |= *pen; +} + +INLINE void SetPixel_WHITE_16bpp(uint16 *pixel, uint16 *pen) +{ + /* D = 1 */ + *pixel = 0xFFFF; +} + +#define PIXEL_TYPE uint16 +#define GDI_GET_POINTER gdi_GetPointer_16bpp +#define GDI_GET_PEN_COLOR gdi_GetPenColor_16bpp + +#define LINE_TO LineTo_BLACK_16bpp +#define SET_PIXEL_ROP2 SetPixel_BLACK_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMERGEPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMERGEPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKNOTPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_MASKNOTPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTCOPYPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOTCOPYPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPENNOT_16bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPENNOT_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOT_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOT_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_XORPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_XORPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMASKPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMASKPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTXORPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOTXORPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOP_16bpp +#define SET_PIXEL_ROP2 SetPixel_NOP_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGENOTPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_MERGENOTPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_COPYPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_COPYPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPENNOT_16bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPENNOT_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPEN_16bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPEN_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_WHITE_16bpp +#define SET_PIXEL_ROP2 SetPixel_WHITE_16bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#undef PIXEL_TYPE +#undef GDI_GET_POINTER +#undef GDI_GET_PEN_COLOR + +pLineTo_16bpp LineTo_ROP2_16bpp[32] = +{ + LineTo_BLACK_16bpp, + LineTo_NOTMERGEPEN_16bpp, + LineTo_MASKNOTPEN_16bpp, + LineTo_NOTCOPYPEN_16bpp, + LineTo_MASKPENNOT_16bpp, + LineTo_NOT_16bpp, + LineTo_XORPEN_16bpp, + LineTo_NOTMASKPEN_16bpp, + LineTo_MASKPEN_16bpp, + LineTo_NOTXORPEN_16bpp, + LineTo_NOP_16bpp, + LineTo_MERGENOTPEN_16bpp, + LineTo_COPYPEN_16bpp, + LineTo_MERGEPENNOT_16bpp, + LineTo_MERGEPEN_16bpp, + LineTo_WHITE_16bpp +}; + +int LineTo_16bpp(HGDI_DC hdc, int nXEnd, int nYEnd) +{ + pLineTo_16bpp _LineTo; + int rop2 = gdi_GetROP2(hdc) - 1; + + _LineTo = LineTo_ROP2_16bpp[rop2]; + + if (_LineTo != NULL) + return _LineTo(hdc, nXEnd, nYEnd); + else + return 0; +} diff --git a/libfreerdp-gdi/32bpp.c b/libfreerdp-gdi/32bpp.c new file mode 100644 index 0000000..728215a --- /dev/null +++ b/libfreerdp-gdi/32bpp.c @@ -0,0 +1,1053 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 32bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +uint32 gdi_get_color_32bpp(HGDI_DC hdc, GDI_COLOR color) +{ + uint32 color32; + uint8 a, r, g, b; + + a = 0xFF; + GetBGR32(r, g, b, color); + + if (hdc->invert) + { + color32 = ABGR32(a, r, g, b); + } + else + { + color32 = ARGB32(a, r, g, b); + } + + return color32; +} + +int FillRect_32bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr) +{ + int x, y; + uint32 *dstp; + uint32 color32; + int nXDest, nYDest; + int nWidth, nHeight; + + gdi_RectToCRgn(rect, &nXDest, &nYDest, &nWidth, &nHeight); + + if (gdi_ClipCoords(hdc, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + + color32 = gdi_get_color_32bpp(hdc, hbr->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdc, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = color32; + dstp++; + } + } + } + + gdi_InvalidateRegion(hdc, nXDest, nYDest, nWidth, nHeight); + return 0; +} + +static int BitBlt_BLACKNESS_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + if (hdcDest->alpha) + { + int x, y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = 0; + dstp++; + + *dstp = 0; + dstp++; + + *dstp = 0; + dstp++; + + *dstp = 0xFF; + dstp++; + } + } + } + } + else + { + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0, nWidth * hdcDest->bytesPerPixel); + } + } + + return 0; +} + +static int BitBlt_WHITENESS_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel); + } + + return 0; +} + +static int BitBlt_SRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int y; + uint8* srcp; + uint8* dstp; + + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || + gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) + { + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + + return 0; + } + + if (nYSrc < nYDest) + { + /* copy down (bottom to top) */ + for (y = nHeight - 1; y >= 0; y--) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else if (nYSrc > nYDest || nXSrc > nXDest) + { + /* copy up or left (top top bottom) */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else + { + /* copy straight right */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + + return 0; +} + +static int BitBlt_NOTSRCCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSTINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*dstp); + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = *srcp & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_NOTSRCERASE_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCAND_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp &= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp |= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSPDxax_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + uint8* patp; + uint32 color32; + HGDI_BITMAP hSrcBmp; + + /* D = (S & P) | (~S & D) */ + /* DSPDxax, used to draw glyphs */ + + color32 = gdi_get_color_32bpp(hdcDest, hdcDest->textColor); + + hSrcBmp = (HGDI_BITMAP) hdcSrc->selectedObject; + srcp = hSrcBmp->data; + + if (hdcSrc->bytesPerPixel != 1) + { + printf("BitBlt_DSPDxax expects 1 bpp, unimplemented for %d\n", hdcSrc->bytesPerPixel); + return 0; + } + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint8*) &color32; + + *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); + dstp++; + patp++; + + *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); + dstp++; + patp++; + + *dstp = (*srcp & *patp) | (~(*srcp) & *dstp); + dstp += 2; + srcp++; + } + } + } + + return 0; +} + +static int BitBlt_SPna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + uint32* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *srcp & ~(*patp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSna_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & (*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PDxn_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint32* dstp; + uint32* patp; + + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *dstp ^ ~(*patp); + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_MERGECOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + uint32* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *srcp & *patp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_MERGEPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) | *dstp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PATCOPY_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint32* dstp; + uint32* patp; + uint32 color32; + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = color32; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *patp; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATINVERT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint32* dstp; + uint32* patp; + uint32 color32; + + if (hdcDest->brush->style == GDI_BS_SOLID) + { + color32 = gdi_get_color_32bpp(hdcDest, hdcDest->brush->color); + + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= color32; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *patp ^ *dstp; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATPAINT_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint32* srcp; + uint32* dstp; + uint32* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = (uint32*) gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = (uint32*) gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = (uint32*) gdi_get_brush_pointer(hdcDest, x, y); + *dstp = *dstp | (*patp | ~(*srcp)); + srcp++; + dstp++; + } + } + } + + return 0; +} + +int BitBlt_32bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) +{ + if (hdcSrc != NULL) + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0) + return 0; + } + else + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + } + + gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); + + switch (rop) + { + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCCOPY: + return BitBlt_SRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SPna: + return BitBlt_SPna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSna: + return BitBlt_DSna_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSPDxax: + return BitBlt_DSPDxax_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCCOPY: + return BitBlt_NOTSRCCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCERASE: + return BitBlt_SRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCERASE: + return BitBlt_NOTSRCERASE_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCINVERT: + return BitBlt_SRCINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCAND: + return BitBlt_SRCAND_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCPAINT: + return BitBlt_SRCPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGECOPY: + return BitBlt_MERGECOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGEPAINT: + return BitBlt_MERGEPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_PATCOPY: + return BitBlt_PATCOPY_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATPAINT: + return BitBlt_PATPAINT_32bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + } + + printf("BitBlt: unknown rop: 0x%08X\n", rop); + return 1; +} + +int PatBlt_32bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop) +{ + if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + + gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight); + + switch (rop) + { + case GDI_PATCOPY: + return BitBlt_PATCOPY_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PDxn: + return BitBlt_PDxn_32bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + default: + break; + } + + printf("PatBlt: unknown rop: 0x%08X\n", rop); + + return 1; +} + +INLINE void SetPixel_BLACK_32bpp(uint32* pixel, uint32* pen) +{ + /* D = 0 */ + *pixel = 0; +} + +INLINE void SetPixel_NOTMERGEPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = ~(D | P) */ + *pixel = ~(*pixel | *pen); +} + +INLINE void SetPixel_MASKNOTPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = D & ~P */ + *pixel &= ~(*pen); +} + +INLINE void SetPixel_NOTCOPYPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = ~P */ + *pixel = ~(*pen); +} + +INLINE void SetPixel_MASKPENNOT_32bpp(uint32* pixel, uint32* pen) +{ + /* D = P & ~D */ + *pixel = *pen & ~*pixel; +} + +INLINE void SetPixel_NOT_32bpp(uint32* pixel, uint32* pen) +{ + /* D = ~D */ + *pixel = ~(*pixel); +} + +INLINE void SetPixel_XORPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = D ^ P */ + *pixel = *pixel ^ *pen; +} + +INLINE void SetPixel_NOTMASKPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = ~(D & P) */ + *pixel = ~(*pixel & *pen); +} + +INLINE void SetPixel_MASKPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = D & P */ + *pixel &= *pen; +} + +INLINE void SetPixel_NOTXORPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = ~(D ^ P) */ + *pixel = ~(*pixel ^ *pen); +} + +INLINE void SetPixel_NOP_32bpp(uint32* pixel, uint32* pen) +{ + /* D = D */ +} + +INLINE void SetPixel_MERGENOTPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = D | ~P */ + *pixel |= ~(*pen); +} + +INLINE void SetPixel_COPYPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = P */ + *pixel = *pen; +} + +INLINE void SetPixel_MERGEPENNOT_32bpp(uint32* pixel, uint32* pen) +{ + /* D = P | ~D */ + *pixel = *pen | ~(*pixel); +} + +INLINE void SetPixel_MERGEPEN_32bpp(uint32* pixel, uint32* pen) +{ + /* D = P | D */ + *pixel |= *pen; +} + +INLINE void SetPixel_WHITE_32bpp(uint32* pixel, uint32* pen) +{ + /* D = 1 */ + *pixel = 0xFFFFFF; +} + +#define PIXEL_TYPE uint32 +#define GDI_GET_POINTER gdi_GetPointer_32bpp +#define GDI_GET_PEN_COLOR gdi_GetPenColor_32bpp + +#define LINE_TO LineTo_BLACK_32bpp +#define SET_PIXEL_ROP2 SetPixel_BLACK_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMERGEPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMERGEPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKNOTPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_MASKNOTPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTCOPYPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOTCOPYPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPENNOT_32bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPENNOT_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOT_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOT_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_XORPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_XORPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMASKPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMASKPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTXORPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOTXORPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOP_32bpp +#define SET_PIXEL_ROP2 SetPixel_NOP_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGENOTPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_MERGENOTPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_COPYPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_COPYPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPENNOT_32bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPENNOT_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPEN_32bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPEN_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_WHITE_32bpp +#define SET_PIXEL_ROP2 SetPixel_WHITE_32bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#undef PIXEL_TYPE +#undef GDI_GET_POINTER +#undef GDI_GET_PEN_COLOR + +pLineTo_32bpp LineTo_ROP2_32bpp[32] = +{ + LineTo_BLACK_32bpp, + LineTo_NOTMERGEPEN_32bpp, + LineTo_MASKNOTPEN_32bpp, + LineTo_NOTCOPYPEN_32bpp, + LineTo_MASKPENNOT_32bpp, + LineTo_NOT_32bpp, + LineTo_XORPEN_32bpp, + LineTo_NOTMASKPEN_32bpp, + LineTo_MASKPEN_32bpp, + LineTo_NOTXORPEN_32bpp, + LineTo_NOP_32bpp, + LineTo_MERGENOTPEN_32bpp, + LineTo_COPYPEN_32bpp, + LineTo_MERGEPENNOT_32bpp, + LineTo_MERGEPEN_32bpp, + LineTo_WHITE_32bpp +}; + +int LineTo_32bpp(HGDI_DC hdc, int nXEnd, int nYEnd) +{ + pLineTo_32bpp _LineTo; + int rop2 = gdi_GetROP2(hdc) - 1; + + _LineTo = LineTo_ROP2_32bpp[rop2]; + + if (_LineTo != NULL) + return _LineTo(hdc, nXEnd, nYEnd); + else + return 0; +} diff --git a/libfreerdp-gdi/8bpp.c b/libfreerdp-gdi/8bpp.c new file mode 100644 index 0000000..d5a8a00 --- /dev/null +++ b/libfreerdp-gdi/8bpp.c @@ -0,0 +1,933 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI 8bpp Internal Buffer Routines + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +int FillRect_8bpp(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr) +{ + /* TODO: Implement 8bpp FillRect() */ + return 0; +} + +static int BitBlt_BLACKNESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0, nWidth * hdcDest->bytesPerPixel); + } + + return 0; +} + +static int BitBlt_WHITENESS_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + memset(dstp, 0xFF, nWidth * hdcDest->bytesPerPixel); + } + + return 0; +} + +static int BitBlt_SRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int y; + uint8* srcp; + uint8* dstp; + + if ((hdcDest->selectedObject != hdcSrc->selectedObject) || + gdi_CopyOverlap(nXDest, nYDest, nWidth, nHeight, nXSrc, nYSrc) == 0) + { + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memcpy(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + + return 0; + } + + if (nYSrc < nYDest) + { + /* copy down (bottom to top) */ + for (y = nHeight - 1; y >= 0; y--) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else if (nYSrc > nYDest || nXSrc > nXDest) + { + /* copy up or left (top top bottom) */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + else + { + /* copy straight right */ + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (srcp != 0 && dstp != 0) + memmove(dstp, srcp, nWidth * hdcDest->bytesPerPixel); + } + } + + return 0; +} + +static int BitBlt_NOTSRCCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSTINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*dstp); + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = *srcp & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_NOTSRCERASE_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & ~(*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCAND_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp &= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_SRCPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp |= *srcp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSPDxax_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + /* TODO: Implement 8bpp DSPDxax BitBlt */ + return 0; +} + +static int BitBlt_SPna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + uint8* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *srcp & ~(*patp); + patp++; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PDxn_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint8* dstp; + uint8* patp; + + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *dstp ^ ~(*patp); + patp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_DSna_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) & (*dstp); + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_MERGECOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + uint8* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *srcp & *patp; + patp++; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_MERGEPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = ~(*srcp) | *dstp; + srcp++; + dstp++; + } + } + } + + return 0; +} + +static int BitBlt_PATCOPY_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint8* dstp; + uint8* patp; + uint8 palIndex; + + if(hdcDest->brush->style == GDI_BS_SOLID) + { + palIndex = ((hdcDest->brush->color >> 16) & 0xFF); + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp = palIndex; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *patp; + patp++; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATINVERT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight) +{ + int x, y; + uint8* dstp; + uint8* patp; + uint8 palIndex; + + if(hdcDest->brush->style == GDI_BS_SOLID) + { + palIndex = ((hdcDest->brush->color >> 16) & 0xFF); + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + *dstp ^= palIndex; + dstp++; + } + } + } + } + else + { + for (y = 0; y < nHeight; y++) + { + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *patp ^ *dstp; + patp++; + dstp++; + } + } + } + } + + return 0; +} + +static int BitBlt_PATPAINT_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc) +{ + int x, y; + uint8* srcp; + uint8* dstp; + uint8* patp; + + for (y = 0; y < nHeight; y++) + { + srcp = gdi_get_bitmap_pointer(hdcSrc, nXSrc, nYSrc + y); + dstp = gdi_get_bitmap_pointer(hdcDest, nXDest, nYDest + y); + + if (dstp != 0) + { + for (x = 0; x < nWidth; x++) + { + patp = gdi_get_brush_pointer(hdcDest, x, y); + + *dstp = *dstp | (*patp | ~(*srcp)); + patp++; + srcp++; + dstp++; + } + } + } + + return 0; +} + +int BitBlt_8bpp(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) +{ + if (hdcSrc != NULL) + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, &nXSrc, &nYSrc) == 0) + return 0; + } + else + { + if (gdi_ClipCoords(hdcDest, &nXDest, &nYDest, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + } + + gdi_InvalidateRegion(hdcDest, nXDest, nYDest, nWidth, nHeight); + + switch (rop) + { + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCCOPY: + return BitBlt_SRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SPna: + return BitBlt_SPna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSna: + return BitBlt_DSna_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSPDxax: + return BitBlt_DSPDxax_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCCOPY: + return BitBlt_NOTSRCCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_SRCERASE: + return BitBlt_SRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_NOTSRCERASE: + return BitBlt_NOTSRCERASE_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCINVERT: + return BitBlt_SRCINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCAND: + return BitBlt_SRCAND_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_SRCPAINT: + return BitBlt_SRCPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGECOPY: + return BitBlt_MERGECOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_MERGEPAINT: + return BitBlt_MERGEPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + + case GDI_PATCOPY: + return BitBlt_PATCOPY_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight); + break; + + case GDI_PATPAINT: + return BitBlt_PATPAINT_8bpp(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc); + break; + } + + printf("BitBlt: unknown rop: 0x%08X\n", rop); + return 1; +} + +int PatBlt_8bpp(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop) +{ + if (gdi_ClipCoords(hdc, &nXLeft, &nYLeft, &nWidth, &nHeight, NULL, NULL) == 0) + return 0; + + gdi_InvalidateRegion(hdc, nXLeft, nYLeft, nWidth, nHeight); + + switch (rop) + { + case GDI_PATCOPY: + return BitBlt_PATCOPY_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PATINVERT: + return BitBlt_PATINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_DSTINVERT: + return BitBlt_DSTINVERT_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_BLACKNESS: + return BitBlt_BLACKNESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_WHITENESS: + return BitBlt_WHITENESS_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + case GDI_PDxn: + return BitBlt_PDxn_8bpp(hdc, nXLeft, nYLeft, nWidth, nHeight); + break; + + default: + break; + } + + printf("PatBlt: unknown rop: 0x%08X\n", rop); + return 1; +} + +INLINE void SetPixel_BLACK_8bpp(uint8* pixel, uint8* pen) +{ + /* D = 0 */ + *pixel = 0; +} + +INLINE void SetPixel_NOTMERGEPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = ~(D | P) */ + *pixel = ~(*pixel | *pen); +} + +INLINE void SetPixel_MASKNOTPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = D & ~P */ + *pixel &= ~(*pen); +} + +INLINE void SetPixel_NOTCOPYPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = ~P */ + *pixel = ~(*pen); +} + +INLINE void SetPixel_MASKPENNOT_8bpp(uint8* pixel, uint8* pen) +{ + /* D = P & ~D */ + *pixel = *pen & ~*pixel; +} + +INLINE void SetPixel_NOT_8bpp(uint8* pixel, uint8* pen) +{ + /* D = ~D */ + *pixel = ~(*pixel); +} + +INLINE void SetPixel_XORPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = D ^ P */ + *pixel = *pixel ^ *pen; +} + +INLINE void SetPixel_NOTMASKPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = ~(D & P) */ + *pixel = ~(*pixel & *pen); +} + +INLINE void SetPixel_MASKPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = D & P */ + *pixel &= *pen; +} + +INLINE void SetPixel_NOTXORPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = ~(D ^ P) */ + *pixel = ~(*pixel ^ *pen); +} + +INLINE void SetPixel_NOP_8bpp(uint8* pixel, uint8* pen) +{ + /* D = D */ +} + +INLINE void SetPixel_MERGENOTPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = D | ~P */ + *pixel |= ~(*pen); +} + +INLINE void SetPixel_COPYPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = P */ + *pixel = *pen; +} + +INLINE void SetPixel_MERGEPENNOT_8bpp(uint8* pixel, uint8* pen) +{ + /* D = P | ~D */ + *pixel = *pen | ~(*pixel); +} + +INLINE void SetPixel_MERGEPEN_8bpp(uint8* pixel, uint8* pen) +{ + /* D = P | D */ + *pixel |= *pen; +} + +INLINE void SetPixel_WHITE_8bpp(uint8* pixel, uint8* pen) +{ + /* D = 1 */ + *pixel = 0xFF; +} + +#define PIXEL_TYPE uint8 +#define GDI_GET_POINTER gdi_GetPointer_8bpp +#define GDI_GET_PEN_COLOR gdi_GetPenColor_8bpp + +#define LINE_TO LineTo_BLACK_8bpp +#define SET_PIXEL_ROP2 SetPixel_BLACK_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMERGEPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMERGEPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKNOTPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_MASKNOTPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTCOPYPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOTCOPYPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPENNOT_8bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPENNOT_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOT_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOT_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_XORPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_XORPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTMASKPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOTMASKPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MASKPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_MASKPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOTXORPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOTXORPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_NOP_8bpp +#define SET_PIXEL_ROP2 SetPixel_NOP_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGENOTPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_MERGENOTPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_COPYPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_COPYPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPENNOT_8bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPENNOT_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_MERGEPEN_8bpp +#define SET_PIXEL_ROP2 SetPixel_MERGEPEN_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#define LINE_TO LineTo_WHITE_8bpp +#define SET_PIXEL_ROP2 SetPixel_WHITE_8bpp +#include "include/line.c" +#undef LINE_TO +#undef SET_PIXEL_ROP2 + +#undef PIXEL_TYPE +#undef GDI_GET_POINTER +#undef GDI_GET_PEN_COLOR + +pLineTo_8bpp LineTo_ROP2_8bpp[32] = +{ + LineTo_BLACK_8bpp, + LineTo_NOTMERGEPEN_8bpp, + LineTo_MASKNOTPEN_8bpp, + LineTo_NOTCOPYPEN_8bpp, + LineTo_MASKPENNOT_8bpp, + LineTo_NOT_8bpp, + LineTo_XORPEN_8bpp, + LineTo_NOTMASKPEN_8bpp, + LineTo_MASKPEN_8bpp, + LineTo_NOTXORPEN_8bpp, + LineTo_NOP_8bpp, + LineTo_MERGENOTPEN_8bpp, + LineTo_COPYPEN_8bpp, + LineTo_MERGEPENNOT_8bpp, + LineTo_MERGEPEN_8bpp, + LineTo_WHITE_8bpp +}; + +int LineTo_8bpp(HGDI_DC hdc, int nXEnd, int nYEnd) +{ + pLineTo_8bpp _LineTo; + int rop2 = gdi_GetROP2(hdc) - 1; + + _LineTo = LineTo_ROP2_8bpp[rop2]; + + if (_LineTo != NULL) + return _LineTo(hdc, nXEnd, nYEnd); + else + return 0; +} diff --git a/libfreerdp-gdi/CMakeLists.txt b/libfreerdp-gdi/CMakeLists.txt new file mode 100644 index 0000000..5991348 --- /dev/null +++ b/libfreerdp-gdi/CMakeLists.txt @@ -0,0 +1,47 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-gdi cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_GDI_SRCS + 8bpp.c + 16bpp.c + 32bpp.c + bitmap.c + brush.c + clipping.c + dc.c + drawing.c + line.c + palette.c + pen.c + region.c + shape.c + graphics.c + graphics.h + gdi.c + gdi.h) + +add_library(freerdp-gdi ${FREERDP_GDI_SRCS}) + +target_link_libraries(freerdp-gdi freerdp-core) +target_link_libraries(freerdp-gdi freerdp-cache) +target_link_libraries(freerdp-gdi freerdp-codec) + +set_target_properties(freerdp-gdi PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +install(TARGETS freerdp-gdi DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-gdi/bitmap.c b/libfreerdp-gdi/bitmap.c new file mode 100644 index 0000000..6c52149 --- /dev/null +++ b/libfreerdp-gdi/bitmap.c @@ -0,0 +1,189 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Bitmap Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +p_BitBlt BitBlt_[5] = +{ + NULL, + BitBlt_8bpp, + BitBlt_16bpp, + NULL, + BitBlt_32bpp +}; + +/** + * Get pixel at the given coordinates.\n + * @msdn{dd144909} + * @param hdc device context + * @param nXPos pixel x position + * @param nYPos pixel y position + * @return pixel color + */ + +INLINE GDI_COLOR gdi_GetPixel(HGDI_DC hdc, int nXPos, int nYPos) +{ + HGDI_BITMAP hBmp = (HGDI_BITMAP) hdc->selectedObject; + GDI_COLOR* colorp = (GDI_COLOR*)&(hBmp->data[(nYPos * hBmp->width * hdc->bytesPerPixel) + nXPos * hdc->bytesPerPixel]); + return (GDI_COLOR) *colorp; +} + +INLINE uint8 gdi_GetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return *((uint8*)&(hBmp->data[(Y * hBmp->width) + X])); +} + +INLINE uint16 gdi_GetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return *((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2])); +} + +INLINE uint32 gdi_GetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return *((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4])); +} + +INLINE uint8* gdi_GetPointer_8bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return ((uint8*)&(hBmp->data[(Y * hBmp->width) + X])); +} + +INLINE uint16* gdi_GetPointer_16bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return ((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2])); +} + +INLINE uint32* gdi_GetPointer_32bpp(HGDI_BITMAP hBmp, int X, int Y) +{ + return ((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4])); +} + +/** + * Set pixel at the given coordinates.\n + * @msdn{dd145078} + * @param hdc device context + * @param X pixel x position + * @param Y pixel y position + * @param crColor new pixel color + * @return + */ + +INLINE GDI_COLOR gdi_SetPixel(HGDI_DC hdc, int X, int Y, GDI_COLOR crColor) +{ + HGDI_BITMAP hBmp = (HGDI_BITMAP) hdc->selectedObject; + *((GDI_COLOR*)&(hBmp->data[(Y * hBmp->width * hdc->bytesPerPixel) + X * hdc->bytesPerPixel])) = crColor; + return 0; +} + +INLINE void gdi_SetPixel_8bpp(HGDI_BITMAP hBmp, int X, int Y, uint8 pixel) +{ + *((uint8*)&(hBmp->data[(Y * hBmp->width) + X])) = pixel; +} + +INLINE void gdi_SetPixel_16bpp(HGDI_BITMAP hBmp, int X, int Y, uint16 pixel) +{ + *((uint16*)&(hBmp->data[(Y * hBmp->width * 2) + X * 2])) = pixel; +} + +INLINE void gdi_SetPixel_32bpp(HGDI_BITMAP hBmp, int X, int Y, uint32 pixel) +{ + *((uint32*)&(hBmp->data[(Y * hBmp->width * 4) + X * 4])) = pixel; +} + +/** + * Create a new bitmap with the given width, height, color format and pixel buffer.\n + * @msdn{dd183485} + * @param nWidth width + * @param nHeight height + * @param cBitsPerPixel bits per pixel + * @param data pixel buffer + * @return new bitmap + */ + +HGDI_BITMAP gdi_CreateBitmap(int nWidth, int nHeight, int cBitsPerPixel, uint8* data) +{ + HGDI_BITMAP hBitmap = (HGDI_BITMAP) malloc(sizeof(GDI_BITMAP)); + hBitmap->objectType = GDIOBJECT_BITMAP; + hBitmap->bitsPerPixel = cBitsPerPixel; + hBitmap->bytesPerPixel = (cBitsPerPixel + 1) / 8; + hBitmap->scanline = nWidth * hBitmap->bytesPerPixel; + hBitmap->width = nWidth; + hBitmap->height = nHeight; + hBitmap->data = data; + return hBitmap; +} + +/** + * Create a new bitmap of the given width and height compatible with the current device context.\n + * @msdn{dd183488} + * @param hdc device context + * @param nWidth width + * @param nHeight height + * @return new bitmap + */ + +HGDI_BITMAP gdi_CreateCompatibleBitmap(HGDI_DC hdc, int nWidth, int nHeight) +{ + HGDI_BITMAP hBitmap = (HGDI_BITMAP) malloc(sizeof(GDI_BITMAP)); + hBitmap->objectType = GDIOBJECT_BITMAP; + hBitmap->bytesPerPixel = hdc->bytesPerPixel; + hBitmap->bitsPerPixel = hdc->bitsPerPixel; + hBitmap->width = nWidth; + hBitmap->height = nHeight; + hBitmap->data = malloc(nWidth * nHeight * hBitmap->bytesPerPixel); + hBitmap->scanline = nWidth * hBitmap->bytesPerPixel; + return hBitmap; +} + +/** + * Perform a bit blit operation on the given pixel buffers.\n + * @msdn{dd183370} + * @param hdcDest destination device context + * @param nXDest destination x1 + * @param nYDest destination y1 + * @param nWidth width + * @param nHeight height + * @param hdcSrc source device context + * @param nXSrc source x1 + * @param nYSrc source y1 + * @param rop raster operation code + * @return 1 if successful, 0 otherwise + */ + +int gdi_BitBlt(HGDI_DC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HGDI_DC hdcSrc, int nXSrc, int nYSrc, int rop) +{ + p_BitBlt _BitBlt = BitBlt_[IBPP(hdcDest->bitsPerPixel)]; + + if (_BitBlt != NULL) + return _BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, rop); + else + return 0; +} diff --git a/libfreerdp-gdi/brush.c b/libfreerdp-gdi/brush.c new file mode 100644 index 0000000..c93b29e --- /dev/null +++ b/libfreerdp-gdi/brush.c @@ -0,0 +1,96 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Brush Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* GDI Brush Functions: http://msdn.microsoft.com/en-us/library/dd183395/ */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +p_PatBlt PatBlt_[5] = +{ + NULL, + PatBlt_8bpp, + PatBlt_16bpp, + NULL, + PatBlt_32bpp +}; + +/** + * Create a new solid brush.\n + * @msdn{dd183518} + * @param crColor brush color + * @return new brush + */ + +HGDI_BRUSH gdi_CreateSolidBrush(GDI_COLOR crColor) +{ + HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH)); + hBrush->objectType = GDIOBJECT_BRUSH; + hBrush->style = GDI_BS_SOLID; + hBrush->color = crColor; + return hBrush; +} + +/** + * Create a new pattern brush.\n + * @msdn{dd183508} + * @param hbmp pattern bitmap + * @return new brush + */ + +HGDI_BRUSH gdi_CreatePatternBrush(HGDI_BITMAP hbmp) +{ + HGDI_BRUSH hBrush = (HGDI_BRUSH) malloc(sizeof(GDI_BRUSH)); + hBrush->objectType = GDIOBJECT_BRUSH; + hBrush->style = GDI_BS_PATTERN; + hBrush->pattern = hbmp; + return hBrush; +} + +/** + * Perform a pattern blit operation on the given pixel buffer.\n + * @msdn{dd162778} + * @param hdc device context + * @param nXLeft x1 + * @param nYLeft y1 + * @param nWidth width + * @param nHeight height + * @param rop raster operation code + * @return 1 if successful, 0 otherwise + */ + +int gdi_PatBlt(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight, int rop) +{ + p_PatBlt _PatBlt = PatBlt_[IBPP(hdc->bitsPerPixel)]; + + if (_PatBlt != NULL) + return _PatBlt(hdc, nXLeft, nYLeft, nWidth, nHeight, rop); + else + return 0; +} diff --git a/libfreerdp-gdi/clipping.c b/libfreerdp-gdi/clipping.c new file mode 100644 index 0000000..c805a43 --- /dev/null +++ b/libfreerdp-gdi/clipping.c @@ -0,0 +1,172 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Clipping Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include + +#include + +int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight) +{ + return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight); +} + +/** + * Get the current clipping region.\n + * @msdn{dd144866} + * @param hdc device context + * @return clipping region + */ + +HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc) +{ + return hdc->clip; +} + +/** + * Set the current clipping region to null. + * @param hdc device context + * @return + */ + +int gdi_SetNullClipRgn(HGDI_DC hdc) +{ + gdi_SetClipRgn(hdc, 0, 0, 0, 0); + hdc->clip->null = 1; + return 0; +} + +/** + * Clip coordinates according to clipping region + * @param hdc device context + * @param x x1 + * @param y y1 + * @param w width + * @param h height + * @param srcx source x1 + * @param srcy source y1 + * @return 1 if there is something to draw, 0 otherwise + */ + +int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy) +{ + GDI_RECT bmp; + GDI_RECT clip; + GDI_RECT coords; + HGDI_BITMAP hBmp; + + int dx = 0; + int dy = 0; + int draw = 1; + + if (hdc == NULL) + return 0; + + hBmp = (HGDI_BITMAP) hdc->selectedObject; + + if (hBmp != NULL) + { + if (hdc->clip->null) + { + gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &clip); + } + else + { + gdi_RgnToRect(hdc->clip, &clip); + gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &bmp); + + if (clip.left < bmp.left) + clip.left = bmp.left; + + if (clip.right > bmp.right) + clip.right = bmp.right; + + if (clip.top < bmp.top) + clip.top = bmp.top; + + if (clip.bottom > bmp.bottom) + clip.bottom = bmp.bottom; + } + } + else + { + gdi_RgnToRect(hdc->clip, &clip); + } + + gdi_CRgnToRect(*x, *y, *w, *h, &coords); + + if (coords.right >= clip.left && coords.left <= clip.right && + coords.bottom >= clip.top && coords.top <= clip.bottom) + { + /* coordinates overlap with clipping region */ + + if (coords.left < clip.left) + { + dx = (clip.left - coords.left) + 1; + coords.left = clip.left; + } + + if (coords.right > clip.right) + coords.right = clip.right; + + if (coords.top < clip.top) + { + dy = (clip.top - coords.top) + 1; + coords.top = clip.top; + } + + if (coords.bottom > clip.bottom) + coords.bottom = clip.bottom; + } + else + { + /* coordinates do not overlap with clipping region */ + + coords.left = 0; + coords.right = 0; + coords.top = 0; + coords.bottom = 0; + draw = 0; + } + + if (srcx != NULL) + { + if (dx > 0) + { + *srcx += dx - 1; + } + } + + if (srcy != NULL) + { + if (dy > 0) + { + *srcy += dy - 1; + } + } + + gdi_RectToCRgn(&coords, x, y, w, h); + + return draw; +} diff --git a/libfreerdp-gdi/dc.c b/libfreerdp-gdi/dc.c new file mode 100644 index 0000000..b4f4ced --- /dev/null +++ b/libfreerdp-gdi/dc.c @@ -0,0 +1,232 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Device Context Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +/** + * Get the current device context (a new one is created each time).\n + * @msdn{dd144871} + * @return current device context + */ + +HGDI_DC gdi_GetDC() +{ + HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC)); + hDC->bytesPerPixel = 4; + hDC->bitsPerPixel = 32; + hDC->drawMode = GDI_R2_BLACK; + hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->clip->null = 1; + hDC->hwnd = NULL; + return hDC; +} + +/** + * Create a device context.\n + * @msdn{dd144871} + * @return new device context + */ + +HGDI_DC gdi_CreateDC(HCLRCONV clrconv, int bpp) +{ + HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC)); + + hDC->drawMode = GDI_R2_BLACK; + hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->clip->null = 1; + hDC->hwnd = NULL; + + hDC->bitsPerPixel = bpp; + hDC->bytesPerPixel = bpp / 8; + + hDC->alpha = clrconv->alpha; + hDC->invert = clrconv->invert; + hDC->rgb555 = clrconv->rgb555; + + hDC->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->hwnd->invalid->null = 1; + + hDC->hwnd->count = 32; + hDC->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * hDC->hwnd->count); + hDC->hwnd->ninvalid = 0; + + return hDC; +} + +/** + * Create a new device context compatible with the given device context.\n + * @msdn{dd183489} + * @param hdc device context + * @return new compatible device context + */ + +HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc) +{ + HGDI_DC hDC = (HGDI_DC) malloc(sizeof(GDI_DC)); + hDC->bytesPerPixel = hdc->bytesPerPixel; + hDC->bitsPerPixel = hdc->bitsPerPixel; + hDC->drawMode = hdc->drawMode; + hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0); + hDC->clip->null = 1; + hDC->hwnd = NULL; + hDC->alpha = hdc->alpha; + hDC->invert = hdc->invert; + hDC->rgb555 = hdc->rgb555; + return hDC; +} + +/** + * Select a GDI object in the current device context.\n + * @msdn{dd162957} + * @param hdc device context + * @param hgdiobject new selected GDI object + * @return previous selected GDI object + */ + +HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject) +{ + HGDIOBJECT previousSelectedObject = hdc->selectedObject; + + if (hgdiobject == NULL) + return NULL; + + if (hgdiobject->objectType == GDIOBJECT_BITMAP) + { + hdc->selectedObject = hgdiobject; + } + else if (hgdiobject->objectType == GDIOBJECT_PEN) + { + previousSelectedObject = (HGDIOBJECT) hdc->pen; + hdc->pen = (HGDI_PEN) hgdiobject; + } + else if (hgdiobject->objectType == GDIOBJECT_BRUSH) + { + previousSelectedObject = (HGDIOBJECT) hdc->brush; + hdc->brush = (HGDI_BRUSH) hgdiobject; + } + else if (hgdiobject->objectType == GDIOBJECT_REGION) + { + hdc->selectedObject = hgdiobject; + } + else if (hgdiobject->objectType == GDIOBJECT_RECT) + { + hdc->selectedObject = hgdiobject; + } + else + { + /* Unknown GDI Object Type */ + return 0; + } + + return previousSelectedObject; +} + +/** + * Delete a GDI object.\n + * @msdn{dd183539} + * @param hgdiobject GDI object + * @return 1 if successful, 0 otherwise + */ + +int gdi_DeleteObject(HGDIOBJECT hgdiobject) +{ + if (hgdiobject == NULL) + return 0; + + if (hgdiobject->objectType == GDIOBJECT_BITMAP) + { + HGDI_BITMAP hBitmap = (HGDI_BITMAP) hgdiobject; + + if (hBitmap->data != NULL) + free(hBitmap->data); + + free(hBitmap); + } + else if (hgdiobject->objectType == GDIOBJECT_PEN) + { + HGDI_PEN hPen = (HGDI_PEN) hgdiobject; + free(hPen); + } + else if (hgdiobject->objectType == GDIOBJECT_BRUSH) + { + HGDI_BRUSH hBrush = (HGDI_BRUSH) hgdiobject; + + if(hBrush->style == GDI_BS_PATTERN) + { + if (hBrush->pattern != NULL) + gdi_DeleteObject((HGDIOBJECT) hBrush->pattern); + } + + free(hBrush); + } + else if (hgdiobject->objectType == GDIOBJECT_REGION) + { + free(hgdiobject); + } + else if (hgdiobject->objectType == GDIOBJECT_RECT) + { + free(hgdiobject); + } + else + { + /* Unknown GDI Object Type */ + free(hgdiobject); + return 0; + } + + return 1; +} + +/** + * Delete device context.\n + * @msdn{dd183533} + * @param hdc device context + * @return 1 if successful, 0 otherwise + */ + +int gdi_DeleteDC(HGDI_DC hdc) +{ + if (hdc->hwnd) + { + if (hdc->hwnd->cinvalid != NULL) + free(hdc->hwnd->cinvalid); + + if (hdc->hwnd->invalid != NULL) + free(hdc->hwnd->invalid); + + free(hdc->hwnd); + } + + free(hdc->clip); + free(hdc); + + return 1; +} diff --git a/libfreerdp-gdi/drawing.c b/libfreerdp-gdi/drawing.c new file mode 100644 index 0000000..98f50c3 --- /dev/null +++ b/libfreerdp-gdi/drawing.c @@ -0,0 +1,131 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Drawing Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* GDI Drawing Functions: http://msdn.microsoft.com/en-us/library/dd162760/ */ + +#include +#include +#include + +#include +#include + +#include + +/** + * Set current foreground draw mode.\n + * @msdn{dd144922} + * @param hdc device context + * @return draw mode + */ + +int gdi_GetROP2(HGDI_DC hdc) +{ + return hdc->drawMode; +} + +/** + * Set current foreground draw mode.\n + * @msdn{dd145088} + * @param hdc device context + * @param fnDrawMode draw mode + * @return previous draw mode + */ + +int gdi_SetROP2(HGDI_DC hdc, int fnDrawMode) +{ + int prevDrawMode = hdc->drawMode; + + if (fnDrawMode > 0 && fnDrawMode <= 16) + hdc->drawMode = fnDrawMode; + + return prevDrawMode; +} + +/** + * Get the current background color.\n + * @msdn{dd144852} + * @param hdc device context + * @return background color + */ + +GDI_COLOR gdi_GetBkColor(HGDI_DC hdc) +{ + return hdc->bkColor; +} + +/** + * Set the current background color.\n + * @msdn{dd162964} + * @param hdc device color + * @param crColor new background color + * @return previous background color + */ + +GDI_COLOR gdi_SetBkColor(HGDI_DC hdc, GDI_COLOR crColor) +{ + GDI_COLOR previousBkColor = hdc->bkColor; + hdc->bkColor = crColor; + return previousBkColor; +} + +/** + * Get the current background mode.\n + * @msdn{dd144853} + * @param hdc device context + * @return background mode + */ + +int gdi_GetBkMode(HGDI_DC hdc) +{ + return hdc->bkMode; +} + +/** + * Set the current background mode.\n + * @msdn{dd162965} + * @param hdc device context + * @param iBkMode background mode + * @return + */ + +int gdi_SetBkMode(HGDI_DC hdc, int iBkMode) +{ + if (iBkMode == GDI_OPAQUE || iBkMode == GDI_TRANSPARENT) + hdc->bkMode = iBkMode; + else + hdc->bkMode = GDI_OPAQUE; + + return 0; +} + +/** + * Set the current text color.\n + * @msdn{dd145093} + * @param hdc device context + * @param crColor new text color + * @return previous text color + */ + +GDI_COLOR gdi_SetTextColor(HGDI_DC hdc, GDI_COLOR crColor) +{ + GDI_COLOR previousTextColor = hdc->textColor; + hdc->textColor = crColor; + return previousTextColor; +} diff --git a/libfreerdp-gdi/gdi.c b/libfreerdp-gdi/gdi.c new file mode 100644 index 0000000..77c1384 --- /dev/null +++ b/libfreerdp-gdi/gdi.c @@ -0,0 +1,937 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Library + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gdi.h" + +/* Ternary Raster Operation Table */ +static const uint32 rop3_code_table[] = +{ + 0x00000042, /* 0 */ + 0x00010289, /* DPSoon */ + 0x00020C89, /* DPSona */ + 0x000300AA, /* PSon */ + 0x00040C88, /* SDPona */ + 0x000500A9, /* DPon */ + 0x00060865, /* PDSxnon */ + 0x000702C5, /* PDSaon */ + 0x00080F08, /* SDPnaa */ + 0x00090245, /* PDSxon */ + 0x000A0329, /* DPna */ + 0x000B0B2A, /* PSDnaon */ + 0x000C0324, /* SPna */ + 0x000D0B25, /* PDSnaon */ + 0x000E08A5, /* PDSonon */ + 0x000F0001, /* Pn */ + 0x00100C85, /* PDSona */ + 0x001100A6, /* DSon */ + 0x00120868, /* SDPxnon */ + 0x001302C8, /* SDPaon */ + 0x00140869, /* DPSxnon */ + 0x001502C9, /* DPSaon */ + 0x00165CCA, /* PSDPSanaxx */ + 0x00171D54, /* SSPxDSxaxn */ + 0x00180D59, /* SPxPDxa */ + 0x00191CC8, /* SDPSanaxn */ + 0x001A06C5, /* PDSPaox */ + 0x001B0768, /* SDPSxaxn */ + 0x001C06CA, /* PSDPaox */ + 0x001D0766, /* DSPDxaxn */ + 0x001E01A5, /* PDSox */ + 0x001F0385, /* PDSoan */ + 0x00200F09, /* DPSnaa */ + 0x00210248, /* SDPxon */ + 0x00220326, /* DSna */ + 0x00230B24, /* SPDnaon */ + 0x00240D55, /* SPxDSxa */ + 0x00251CC5, /* PDSPanaxn */ + 0x002606C8, /* SDPSaox */ + 0x00271868, /* SDPSxnox */ + 0x00280369, /* DPSxa */ + 0x002916CA, /* PSDPSaoxxn */ + 0x002A0CC9, /* DPSana */ + 0x002B1D58, /* SSPxPDxaxn */ + 0x002C0784, /* SPDSoax */ + 0x002D060A, /* PSDnox */ + 0x002E064A, /* PSDPxox */ + 0x002F0E2A, /* PSDnoan */ + 0x0030032A, /* PSna */ + 0x00310B28, /* SDPnaon */ + 0x00320688, /* SDPSoox */ + 0x00330008, /* Sn */ + 0x003406C4, /* SPDSaox */ + 0x00351864, /* SPDSxnox */ + 0x003601A8, /* SDPox */ + 0x00370388, /* SDPoan */ + 0x0038078A, /* PSDPoax */ + 0x00390604, /* SPDnox */ + 0x003A0644, /* SPDSxox */ + 0x003B0E24, /* SPDnoan */ + 0x003C004A, /* PSx */ + 0x003D18A4, /* SPDSonox */ + 0x003E1B24, /* SPDSnaox */ + 0x003F00EA, /* PSan */ + 0x00400F0A, /* PSDnaa */ + 0x00410249, /* DPSxon */ + 0x00420D5D, /* SDxPDxa */ + 0x00431CC4, /* SPDSanaxn */ + 0x00440328, /* SDna */ + 0x00450B29, /* DPSnaon */ + 0x004606C6, /* DSPDaox */ + 0x0047076A, /* PSDPxaxn */ + 0x00480368, /* SDPxa */ + 0x004916C5, /* PDSPDaoxxn */ + 0x004A0789, /* DPSDoax */ + 0x004B0605, /* PDSnox */ + 0x004C0CC8, /* SDPana */ + 0x004D1954, /* SSPxDSxoxn */ + 0x004E0645, /* PDSPxox */ + 0x004F0E25, /* PDSnoan */ + 0x00500325, /* PDna */ + 0x00510B26, /* DSPnaon */ + 0x005206C9, /* DPSDaox */ + 0x00530764, /* SPDSxaxn */ + 0x005408A9, /* DPSonon */ + 0x00550009, /* Dn */ + 0x005601A9, /* DPSox */ + 0x00570389, /* DPSoan */ + 0x00580785, /* PDSPoax */ + 0x00590609, /* DPSnox */ + 0x005A0049, /* DPx */ + 0x005B18A9, /* DPSDonox */ + 0x005C0649, /* DPSDxox */ + 0x005D0E29, /* DPSnoan */ + 0x005E1B29, /* DPSDnaox */ + 0x005F00E9, /* DPan */ + 0x00600365, /* PDSxa */ + 0x006116C6, /* DSPDSaoxxn */ + 0x00620786, /* DSPDoax */ + 0x00630608, /* SDPnox */ + 0x00640788, /* SDPSoax */ + 0x00650606, /* DSPnox */ + 0x00660046, /* DSx */ + 0x006718A8, /* SDPSonox */ + 0x006858A6, /* DSPDSonoxxn */ + 0x00690145, /* PDSxxn */ + 0x006A01E9, /* DPSax */ + 0x006B178A, /* PSDPSoaxxn */ + 0x006C01E8, /* SDPax */ + 0x006D1785, /* PDSPDoaxxn */ + 0x006E1E28, /* SDPSnoax */ + 0x006F0C65, /* PDSxnan */ + 0x00700CC5, /* PDSana */ + 0x00711D5C, /* SSDxPDxaxn */ + 0x00720648, /* SDPSxox */ + 0x00730E28, /* SDPnoan */ + 0x00740646, /* DSPDxox */ + 0x00750E26, /* DSPnoan */ + 0x00761B28, /* SDPSnaox */ + 0x007700E6, /* DSan */ + 0x007801E5, /* PDSax */ + 0x00791786, /* DSPDSoaxxn */ + 0x007A1E29, /* DPSDnoax */ + 0x007B0C68, /* SDPxnan */ + 0x007C1E24, /* SPDSnoax */ + 0x007D0C69, /* DPSxnan */ + 0x007E0955, /* SPxDSxo */ + 0x007F03C9, /* DPSaan */ + 0x008003E9, /* DPSaa */ + 0x00810975, /* SPxDSxon */ + 0x00820C49, /* DPSxna */ + 0x00831E04, /* SPDSnoaxn */ + 0x00840C48, /* SDPxna */ + 0x00851E05, /* PDSPnoaxn */ + 0x008617A6, /* DSPDSoaxx */ + 0x008701C5, /* PDSaxn */ + 0x008800C6, /* DSa */ + 0x00891B08, /* SDPSnaoxn */ + 0x008A0E06, /* DSPnoa */ + 0x008B0666, /* DSPDxoxn */ + 0x008C0E08, /* SDPnoa */ + 0x008D0668, /* SDPSxoxn */ + 0x008E1D7C, /* SSDxPDxax */ + 0x008F0CE5, /* PDSanan */ + 0x00900C45, /* PDSxna */ + 0x00911E08, /* SDPSnoaxn */ + 0x009217A9, /* DPSDPoaxx */ + 0x009301C4, /* SPDaxn */ + 0x009417AA, /* PSDPSoaxx */ + 0x009501C9, /* DPSaxn */ + 0x00960169, /* DPSxx */ + 0x0097588A, /* PSDPSonoxx */ + 0x00981888, /* SDPSonoxn */ + 0x00990066, /* DSxn */ + 0x009A0709, /* DPSnax */ + 0x009B07A8, /* SDPSoaxn */ + 0x009C0704, /* SPDnax */ + 0x009D07A6, /* DSPDoaxn */ + 0x009E16E6, /* DSPDSaoxx */ + 0x009F0345, /* PDSxan */ + 0x00A000C9, /* DPa */ + 0x00A11B05, /* PDSPnaoxn */ + 0x00A20E09, /* DPSnoa */ + 0x00A30669, /* DPSDxoxn */ + 0x00A41885, /* PDSPonoxn */ + 0x00A50065, /* PDxn */ + 0x00A60706, /* DSPnax */ + 0x00A707A5, /* PDSPoaxn */ + 0x00A803A9, /* DPSoa */ + 0x00A90189, /* DPSoxn */ + 0x00AA0029, /* D */ + 0x00AB0889, /* DPSono */ + 0x00AC0744, /* SPDSxax */ + 0x00AD06E9, /* DPSDaoxn */ + 0x00AE0B06, /* DSPnao */ + 0x00AF0229, /* DPno */ + 0x00B00E05, /* PDSnoa */ + 0x00B10665, /* PDSPxoxn */ + 0x00B21974, /* SSPxDSxox */ + 0x00B30CE8, /* SDPanan */ + 0x00B4070A, /* PSDnax */ + 0x00B507A9, /* DPSDoaxn */ + 0x00B616E9, /* DPSDPaoxx */ + 0x00B70348, /* SDPxan */ + 0x00B8074A, /* PSDPxax */ + 0x00B906E6, /* DSPDaoxn */ + 0x00BA0B09, /* DPSnao */ + 0x00BB0226, /* DSno */ + 0x00BC1CE4, /* SPDSanax */ + 0x00BD0D7D, /* SDxPDxan */ + 0x00BE0269, /* DPSxo */ + 0x00BF08C9, /* DPSano */ + 0x00C000CA, /* PSa */ + 0x00C11B04, /* SPDSnaoxn */ + 0x00C21884, /* SPDSonoxn */ + 0x00C3006A, /* PSxn */ + 0x00C40E04, /* SPDnoa */ + 0x00C50664, /* SPDSxoxn */ + 0x00C60708, /* SDPnax */ + 0x00C707AA, /* PSDPoaxn */ + 0x00C803A8, /* SDPoa */ + 0x00C90184, /* SPDoxn */ + 0x00CA0749, /* DPSDxax */ + 0x00CB06E4, /* SPDSaoxn */ + 0x00CC0020, /* S */ + 0x00CD0888, /* SDPono */ + 0x00CE0B08, /* SDPnao */ + 0x00CF0224, /* SPno */ + 0x00D00E0A, /* PSDnoa */ + 0x00D1066A, /* PSDPxoxn */ + 0x00D20705, /* PDSnax */ + 0x00D307A4, /* SPDSoaxn */ + 0x00D41D78, /* SSPxPDxax */ + 0x00D50CE9, /* DPSanan */ + 0x00D616EA, /* PSDPSaoxx */ + 0x00D70349, /* DPSxan */ + 0x00D80745, /* PDSPxax */ + 0x00D906E8, /* SDPSaoxn */ + 0x00DA1CE9, /* DPSDanax */ + 0x00DB0D75, /* SPxDSxan */ + 0x00DC0B04, /* SPDnao */ + 0x00DD0228, /* SDno */ + 0x00DE0268, /* SDPxo */ + 0x00DF08C8, /* SDPano */ + 0x00E003A5, /* PDSoa */ + 0x00E10185, /* PDSoxn */ + 0x00E20746, /* DSPDxax */ + 0x00E306EA, /* PSDPaoxn */ + 0x00E40748, /* SDPSxax */ + 0x00E506E5, /* PDSPaoxn */ + 0x00E61CE8, /* SDPSanax */ + 0x00E70D79, /* SPxPDxan */ + 0x00E81D74, /* SSPxDSxax */ + 0x00E95CE6, /* DSPDSanaxxn */ + 0x00EA02E9, /* DPSao */ + 0x00EB0849, /* DPSxno */ + 0x00EC02E8, /* SDPao */ + 0x00ED0848, /* SDPxno */ + 0x00EE0086, /* DSo */ + 0x00EF0A08, /* SDPnoo */ + 0x00F00021, /* P */ + 0x00F10885, /* PDSono */ + 0x00F20B05, /* PDSnao */ + 0x00F3022A, /* PSno */ + 0x00F40B0A, /* PSDnao */ + 0x00F50225, /* PDno */ + 0x00F60265, /* PDSxo */ + 0x00F708C5, /* PDSano */ + 0x00F802E5, /* PDSao */ + 0x00F90845, /* PDSxno */ + 0x00FA0089, /* DPo */ + 0x00FB0A09, /* DPSnoo */ + 0x00FC008A, /* PSo */ + 0x00FD0A0A, /* PSDnoo */ + 0x00FE02A9, /* DPSoo */ + 0x00FF0062 /* 1 */ +}; + +/* GDI Helper Functions */ + +INLINE uint32 gdi_rop3_code(uint8 code) +{ + return rop3_code_table[code]; +} + +INLINE uint8* gdi_get_bitmap_pointer(HGDI_DC hdcBmp, int x, int y) +{ + uint8* p; + HGDI_BITMAP hBmp = (HGDI_BITMAP) hdcBmp->selectedObject; + + if (x >= 0 && x < hBmp->width && y >= 0 && y < hBmp->height) + { + p = hBmp->data + (y * hBmp->width * hdcBmp->bytesPerPixel) + (x * hdcBmp->bytesPerPixel); + return p; + } + else + { + printf("gdi_get_bitmap_pointer: requesting invalid pointer: (%d,%d) in %dx%d\n", x, y, hBmp->width, hBmp->height); + return 0; + } +} + +INLINE uint8* gdi_get_brush_pointer(HGDI_DC hdcBrush, int x, int y) +{ + uint8 * p; + + if (hdcBrush->brush != NULL) + { + if (hdcBrush->brush->style == GDI_BS_PATTERN) + { + HGDI_BITMAP hBmpBrush = hdcBrush->brush->pattern; + + if (x >= 0 && y >= 0) + { + x = x % hBmpBrush->width; + y = y % hBmpBrush->height; + p = hBmpBrush->data + (y * hBmpBrush->scanline) + (x * hBmpBrush->bytesPerPixel); + return p; + } + } + } + + p = (uint8*) &(hdcBrush->textColor); + return p; +} + +INLINE int gdi_is_mono_pixel_set(uint8* data, int x, int y, int width) +{ + int byte; + int shift; + + width = (width + 7) / 8; + byte = (y * width) + (x / 8); + shift = x % 8; + + return (data[byte] & (0x80 >> shift)) != 0; +} + +gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph) +{ + uint8* extra; + gdiBitmap* gdi_bmp; + + gdi_bmp = (gdiBitmap*) malloc(sizeof(gdiBitmap)); + + gdi_bmp->hdc = gdi_GetDC(); + gdi_bmp->hdc->bytesPerPixel = 1; + gdi_bmp->hdc->bitsPerPixel = 1; + + extra = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj); + gdi_bmp->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, extra); + gdi_bmp->bitmap->bytesPerPixel = 1; + gdi_bmp->bitmap->bitsPerPixel = 1; + + gdi_SelectObject(gdi_bmp->hdc, (HGDIOBJECT) gdi_bmp->bitmap); + gdi_bmp->org_bitmap = NULL; + + return gdi_bmp; +} + +void gdi_glyph_free(gdiBitmap *gdi_bmp) +{ + if (gdi_bmp != 0) + { + gdi_SelectObject(gdi_bmp->hdc, (HGDIOBJECT) gdi_bmp->org_bitmap); + gdi_DeleteObject((HGDIOBJECT) gdi_bmp->bitmap); + gdi_DeleteDC(gdi_bmp->hdc); + free(gdi_bmp); + } +} + +gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data) +{ + gdiBitmap* bitmap; + + bitmap = (gdiBitmap*) malloc(sizeof(gdiBitmap)); + bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc); + + DEBUG_GDI("gdi_bitmap_new: width:%d height:%d bpp:%d", width, height, bpp); + + if (data == NULL) + bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, width, height); + else + bitmap->bitmap = gdi_create_bitmap(gdi, width, height, bpp, data); + + gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->bitmap); + bitmap->org_bitmap = NULL; + + return bitmap; +} + +void gdi_bitmap_free_ex(gdiBitmap* bitmap) +{ + if (bitmap != NULL) + { + gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap); + gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap); + gdi_DeleteDC(bitmap->hdc); + free(bitmap); + } +} + +void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) +{ + rdpGdi* gdi = context->gdi; + gdi->clrconv->palette->count = palette->number; + gdi->clrconv->palette->entries = palette->entries; +} + +void gdi_set_bounds(rdpContext* context, rdpBounds* bounds) +{ + rdpGdi* gdi = context->gdi; + + if (bounds != NULL) + { + gdi_SetClipRgn(gdi->drawing->hdc, bounds->left, bounds->top, + bounds->right - bounds->left + 1, bounds->bottom - bounds->top + 1); + } + else + { + gdi_SetNullClipRgn(gdi->drawing->hdc); + } +} + +void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt) +{ + rdpGdi* gdi = context->gdi; + + gdi_BitBlt(gdi->drawing->hdc, dstblt->nLeftRect, dstblt->nTopRect, + dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop)); +} + +void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) +{ + uint8* data; + rdpBrush* brush; + HGDI_BRUSH originalBrush; + rdpGdi* gdi = context->gdi; + + brush = &patblt->brush; + + if (brush->style == GDI_BS_SOLID) + { + uint32 color; + originalBrush = gdi->drawing->hdc->brush; + + color = freerdp_color_convert_rgb(patblt->foreColor, gdi->srcBpp, 32, gdi->clrconv); + gdi->drawing->hdc->brush = gdi_CreateSolidBrush(color); + + gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)); + + gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush); + gdi->drawing->hdc->brush = originalBrush; + } + else if (brush->style == GDI_BS_PATTERN) + { + HGDI_BITMAP hBmp; + + if (brush->bpp > 1) + { + data = freerdp_image_convert(brush->data, NULL, 8, 8, gdi->srcBpp, gdi->dstBpp, gdi->clrconv); + } + else + { + data = freerdp_mono_image_convert(brush->data, 8, 8, gdi->srcBpp, gdi->dstBpp, + patblt->backColor, patblt->foreColor, gdi->clrconv); + } + + hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); + + originalBrush = gdi->drawing->hdc->brush; + gdi->drawing->hdc->brush = gdi_CreatePatternBrush(hBmp); + + gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, + patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)); + + gdi_DeleteObject((HGDIOBJECT) gdi->drawing->hdc->brush); + gdi->drawing->hdc->brush = originalBrush; + } + else + { + printf("unimplemented brush style:%d\n", brush->style); + } +} + +void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) +{ + rdpGdi* gdi = context->gdi; + + gdi_BitBlt(gdi->drawing->hdc, scrblt->nLeftRect, scrblt->nTopRect, + scrblt->nWidth, scrblt->nHeight, gdi->primary->hdc, + scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop)); +} + +void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) +{ + GDI_RECT rect; + HGDI_BRUSH hBrush; + uint32 brush_color; + rdpGdi *gdi = context->gdi; + + gdi_CRgnToRect(opaque_rect->nLeftRect, opaque_rect->nTopRect, + opaque_rect->nWidth, opaque_rect->nHeight, &rect); + + brush_color = freerdp_color_convert_var_bgr(opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + + hBrush = gdi_CreateSolidBrush(brush_color); + gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); + + gdi_DeleteObject((HGDIOBJECT) hBrush); +} + +void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect) +{ + int i; + GDI_RECT rect; + HGDI_BRUSH hBrush; + uint32 brush_color; + DELTA_RECT* rectangle; + rdpGdi *gdi = context->gdi; + + for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++) + { + rectangle = &multi_opaque_rect->rectangles[i]; + + gdi_CRgnToRect(rectangle->left, rectangle->top, + rectangle->width, rectangle->height, &rect); + + brush_color = freerdp_color_convert_var_bgr(multi_opaque_rect->color, gdi->srcBpp, 32, gdi->clrconv); + + hBrush = gdi_CreateSolidBrush(brush_color); + gdi_FillRect(gdi->drawing->hdc, &rect, hBrush); + + gdi_DeleteObject((HGDIOBJECT) hBrush); + } +} + +void gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +{ + uint32 color; + HGDI_PEN hPen; + rdpGdi *gdi = context->gdi; + + color = freerdp_color_convert_rgb(line_to->penColor, gdi->srcBpp, 32, gdi->clrconv); + hPen = gdi_CreatePen(line_to->penStyle, line_to->penWidth, (GDI_COLOR) color); + gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); + gdi_SetROP2(gdi->drawing->hdc, line_to->bRop2); + + gdi_MoveToEx(gdi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); + gdi_LineTo(gdi->drawing->hdc, line_to->nXEnd, line_to->nYEnd); + + gdi_DeleteObject((HGDIOBJECT) hPen); +} + +void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) +{ + int i; + uint32 color; + HGDI_PEN hPen; + DELTA_POINT* points; + rdpGdi* gdi = context->gdi; + sint32 x; + sint32 y; + + color = freerdp_color_convert_rgb(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv); + hPen = gdi_CreatePen(GDI_PS_SOLID, 1, (GDI_COLOR) color); + gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); + gdi_SetROP2(gdi->drawing->hdc, polyline->bRop2); + + x = polyline->xStart; + y = polyline->yStart; + gdi_MoveToEx(gdi->drawing->hdc, x, y, NULL); + + points = polyline->points; + for (i = 0; i < (int) polyline->numPoints; i++) + { + x += points[i].x; + y += points[i].y; + gdi_LineTo(gdi->drawing->hdc, x, y); + gdi_MoveToEx(gdi->drawing->hdc, x, y, NULL); + } + + gdi_DeleteObject((HGDIOBJECT) hPen); +} + +void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) +{ + gdiBitmap* bitmap; + rdpGdi* gdi = context->gdi; + + bitmap = (gdiBitmap*) memblt->bitmap; + + gdi_BitBlt(gdi->drawing->hdc, memblt->nLeftRect, memblt->nTopRect, + memblt->nWidth, memblt->nHeight, bitmap->hdc, + memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop)); +} + +void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) +{ + +} + +int tilenum = 0; + +void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command) +{ + int i, j; + int tx, ty; + char* tile_bitmap; + RFX_MESSAGE* message; + rdpGdi* gdi = context->gdi; + RFX_CONTEXT* rfx_context = (RFX_CONTEXT*) gdi->rfx_context; + NSC_CONTEXT* nsc_context = (NSC_CONTEXT*) gdi->nsc_context; + + DEBUG_GDI("destLeft %d destTop %d destRight %d destBottom %d " + "bpp %d codecID %d width %d height %d length %d", + surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->destRight, surface_bits_command->destBottom, + surface_bits_command->bpp, surface_bits_command->codecID, + surface_bits_command->width, surface_bits_command->height, + surface_bits_command->bitmapDataLength); + + tile_bitmap = (char*) xzalloc(32); + + if (surface_bits_command->codecID == CODEC_ID_REMOTEFX) + { + message = rfx_process_message(rfx_context, + surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + + DEBUG_GDI("num_rects %d num_tiles %d", message->num_rects, message->num_tiles); + + /* blit each tile */ + for (i = 0; i < message->num_tiles; i++) + { + tx = message->tiles[i]->x + surface_bits_command->destLeft; + ty = message->tiles[i]->y + surface_bits_command->destTop; + + freerdp_image_convert(message->tiles[i]->data, gdi->tile->bitmap->data, 64, 64, 32, 32, gdi->clrconv); + +#ifdef DUMP_REMOTEFX_TILES + sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++); + freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32); +#endif + + for (j = 0; j < message->num_rects; j++) + { + gdi_SetClipRgn(gdi->primary->hdc, + surface_bits_command->destLeft + message->rects[j].x, + surface_bits_command->destTop + message->rects[j].y, + message->rects[j].width, message->rects[j].height); + + gdi_BitBlt(gdi->primary->hdc, tx, ty, 64, 64, gdi->tile->hdc, 0, 0, GDI_SRCCOPY); + } + } + + gdi_SetNullClipRgn(gdi->primary->hdc); + rfx_message_free(rfx_context, message); + } + else if (surface_bits_command->codecID == CODEC_ID_NSCODEC) + { + nsc_context->width = surface_bits_command->width; + nsc_context->height = surface_bits_command->height; + nsc_process_message(nsc_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength); + gdi->image->bitmap->width = surface_bits_command->width; + gdi->image->bitmap->height = surface_bits_command->height; + gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp; + gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8; + gdi->image->bitmap->data = (uint8*) xrealloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4); + freerdp_image_flip(nsc_context->bmpdata, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); + nsc_context_destroy(nsc_context); + } + else if (surface_bits_command->codecID == CODEC_ID_NONE) + { + gdi->image->bitmap->width = surface_bits_command->width; + gdi->image->bitmap->height = surface_bits_command->height; + gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp; + gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8; + + gdi->image->bitmap->data = (uint8*) xrealloc(gdi->image->bitmap->data, + gdi->image->bitmap->width * gdi->image->bitmap->height * 4); + + if ((surface_bits_command->bpp != 32) || (gdi->clrconv->alpha == true)) + { + uint8* temp_image; + + freerdp_image_convert(surface_bits_command->bitmapData, gdi->image->bitmap->data, + gdi->image->bitmap->width, gdi->image->bitmap->height, + gdi->image->bitmap->bitsPerPixel, 32, gdi->clrconv); + + surface_bits_command->bpp = 32; + surface_bits_command->bitmapData = gdi->image->bitmap->data; + + temp_image = (uint8*) xmalloc(gdi->image->bitmap->width * gdi->image->bitmap->height * 4); + freerdp_image_flip(gdi->image->bitmap->data, temp_image, gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + xfree(gdi->image->bitmap->data); + gdi->image->bitmap->data = temp_image; + } + else + { + freerdp_image_flip(surface_bits_command->bitmapData, gdi->image->bitmap->data, + gdi->image->bitmap->width, gdi->image->bitmap->height, 32); + } + + gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, + surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY); + } + else + { + printf("Unsupported codecID %d\n", surface_bits_command->codecID); + } + + if (tile_bitmap != NULL) + xfree(tile_bitmap); +} + +/** + * Register GDI callbacks with libfreerdp-core. + * @param inst current instance + * @return + */ + +void gdi_register_update_callbacks(rdpUpdate* update) +{ + rdpPrimaryUpdate* primary = update->primary; + + update->Palette = gdi_palette_update; + update->SetBounds = gdi_set_bounds; + + primary->DstBlt = gdi_dstblt; + primary->PatBlt = gdi_patblt; + primary->ScrBlt = gdi_scrblt; + primary->OpaqueRect = gdi_opaque_rect; + primary->DrawNineGrid = NULL; + primary->MultiDstBlt = NULL; + primary->MultiPatBlt = NULL; + primary->MultiScrBlt = NULL; + primary->MultiOpaqueRect = gdi_multi_opaque_rect; + primary->MultiDrawNineGrid = NULL; + primary->LineTo = gdi_line_to; + primary->Polyline = gdi_polyline; + primary->MemBlt = gdi_memblt; + primary->Mem3Blt = gdi_mem3blt; + primary->SaveBitmap = NULL; + primary->GlyphIndex = NULL; + primary->FastIndex = NULL; + primary->FastGlyph = NULL; + primary->PolygonSC = NULL; + primary->PolygonCB = NULL; + primary->EllipseSC = NULL; + primary->EllipseCB = NULL; + + update->SurfaceBits = gdi_surface_bits; +} + +void gdi_init_primary(rdpGdi* gdi) +{ + gdi->primary = gdi_bitmap_new_ex(gdi, gdi->width, gdi->height, gdi->dstBpp, gdi->primary_buffer); + gdi->primary_buffer = gdi->primary->bitmap->data; + + if (gdi->drawing == NULL) + gdi->drawing = gdi->primary; + + gdi->primary->hdc->hwnd = (HGDI_WND) malloc(sizeof(GDI_WND)); + gdi->primary->hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0); + gdi->primary->hdc->hwnd->invalid->null = 1; + + gdi->primary->hdc->hwnd->count = 32; + gdi->primary->hdc->hwnd->cinvalid = (HGDI_RGN) malloc(sizeof(GDI_RGN) * gdi->primary->hdc->hwnd->count); + gdi->primary->hdc->hwnd->ninvalid = 0; +} + +void gdi_resize(rdpGdi* gdi, int width, int height) +{ + if (gdi && gdi->primary) + { + if (gdi->width != width || gdi->height != height) + { + if (gdi->drawing == gdi->primary) + gdi->drawing = NULL; + + gdi->width = width; + gdi->height = height; + gdi_bitmap_free_ex(gdi->primary); + gdi_init_primary(gdi); + } + } +} + +/** + * Initialize GDI + * @param inst current instance + * @return + */ + +int gdi_init(freerdp* instance, uint32 flags, uint8* buffer) +{ + rdpGdi* gdi; + rdpCache* cache; + + gdi = (rdpGdi*) malloc(sizeof(rdpGdi)); + memset(gdi, 0, sizeof(rdpGdi)); + + instance->context->gdi = gdi; + cache = instance->context->cache; + + gdi->width = instance->settings->width; + gdi->height = instance->settings->height; + gdi->srcBpp = instance->settings->color_depth; + gdi->primary_buffer = buffer; + + /* default internal buffer format */ + gdi->dstBpp = 32; + gdi->bytesPerPixel = 4; + + if (gdi->srcBpp > 16) + { + if (flags & CLRBUF_32BPP) + { + gdi->dstBpp = 32; + gdi->bytesPerPixel = 4; + } + else if (flags & CLRBUF_24BPP) + { + gdi->dstBpp = 24; + gdi->bytesPerPixel = 3; + } + else if (flags & CLRBUF_16BPP) + { + gdi->dstBpp = 16; + gdi->bytesPerPixel = 2; + } + } + else + { + if (flags & CLRBUF_16BPP) + { + gdi->dstBpp = 16; + gdi->bytesPerPixel = 2; + } + else if (flags & CLRBUF_32BPP) + { + gdi->dstBpp = 32; + gdi->bytesPerPixel = 4; + } + } + + gdi->hdc = gdi_GetDC(); + gdi->hdc->bitsPerPixel = gdi->dstBpp; + gdi->hdc->bytesPerPixel = gdi->bytesPerPixel; + + gdi->clrconv = (HCLRCONV) malloc(sizeof(CLRCONV)); + gdi->clrconv->alpha = (flags & CLRCONV_ALPHA) ? 1 : 0; + gdi->clrconv->invert = (flags & CLRCONV_INVERT) ? 1 : 0; + gdi->clrconv->rgb555 = (flags & CLRCONV_RGB555) ? 1 : 0; + gdi->clrconv->palette = (rdpPalette*) malloc(sizeof(rdpPalette)); + + gdi->hdc->alpha = gdi->clrconv->alpha; + gdi->hdc->invert = gdi->clrconv->invert; + gdi->hdc->rgb555 = gdi->clrconv->rgb555; + + gdi_init_primary(gdi); + + gdi->tile = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL); + gdi->image = gdi_bitmap_new_ex(gdi, 64, 64, 32, NULL); + + if (cache == NULL) + { + cache = cache_new(instance->settings); + instance->context->cache = cache; + } + + gdi_register_update_callbacks(instance->update); + + brush_cache_register_callbacks(instance->update); + glyph_cache_register_callbacks(instance->update); + bitmap_cache_register_callbacks(instance->update); + offscreen_cache_register_callbacks(instance->update); + palette_cache_register_callbacks(instance->update); + + gdi_register_graphics(instance->context->graphics); + + gdi->rfx_context = rfx_context_new(); + gdi->nsc_context = nsc_context_new(); + + return 0; +} + +void gdi_free(freerdp* instance) +{ + rdpGdi* gdi = instance->context->gdi; + + if (gdi) + { + gdi_bitmap_free_ex(gdi->primary); + gdi_bitmap_free_ex(gdi->tile); + gdi_bitmap_free_ex(gdi->image); + gdi_DeleteDC(gdi->hdc); + rfx_context_free((RFX_CONTEXT*)gdi->rfx_context); + free(gdi->clrconv); + free(gdi); + } + + instance->context->gdi = (rdpGdi*) NULL; +} + diff --git a/libfreerdp-gdi/gdi.h b/libfreerdp-gdi/gdi.h new file mode 100644 index 0000000..99fa736 --- /dev/null +++ b/libfreerdp-gdi/gdi.h @@ -0,0 +1,28 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Library + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_CORE_H +#define __GDI_CORE_H + +#include "graphics.h" + +gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, uint8* data); +void gdi_bitmap_free_ex(gdiBitmap* gdi_bmp); + +#endif /* __GDI_CORE_H */ diff --git a/libfreerdp-gdi/graphics.c b/libfreerdp-gdi/graphics.c new file mode 100644 index 0000000..0481633 --- /dev/null +++ b/libfreerdp-gdi/graphics.c @@ -0,0 +1,239 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "graphics.h" + +/* Bitmap Class */ + +HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8* data) +{ + uint8* bmpData; + HGDI_BITMAP bitmap; + + bmpData = freerdp_image_convert(data, NULL, width, height, gdi->srcBpp, bpp, gdi->clrconv); + bitmap = gdi_CreateBitmap(width, height, gdi->dstBpp, bmpData); + + return bitmap; +} + +void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap) +{ + gdiBitmap* gdi_bitmap; + rdpGdi* gdi = context->gdi; + + gdi_bitmap = (gdiBitmap*) bitmap; + gdi_bitmap->hdc = gdi_CreateCompatibleDC(gdi->hdc); + + if (bitmap->data == NULL) + gdi_bitmap->bitmap = gdi_CreateCompatibleBitmap(gdi->hdc, bitmap->width, bitmap->height); + else + gdi_bitmap->bitmap = gdi_create_bitmap(gdi, bitmap->width, bitmap->height, gdi->dstBpp, bitmap->data); + + gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->bitmap); + gdi_bitmap->org_bitmap = NULL; +} + +void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap) +{ + gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap; + + if (gdi_bitmap != NULL) + { + gdi_SelectObject(gdi_bitmap->hdc, (HGDIOBJECT) gdi_bitmap->org_bitmap); + gdi_DeleteObject((HGDIOBJECT) gdi_bitmap->bitmap); + gdi_DeleteDC(gdi_bitmap->hdc); + } +} + +void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) +{ + int width, height; + gdiBitmap* gdi_bitmap = (gdiBitmap*) bitmap; + + width = bitmap->right - bitmap->left + 1; + height = bitmap->bottom - bitmap->top + 1; + + gdi_BitBlt(context->gdi->primary->hdc, bitmap->left, bitmap->top, + width, height, gdi_bitmap->hdc, 0, 0, GDI_SRCCOPY); +} + +void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed) +{ + uint16 size; + + size = width * height * (bpp + 7) / 8; + + if (bitmap->data == NULL) + bitmap->data = (uint8*) xmalloc(size); + else + bitmap->data = (uint8*) xrealloc(bitmap->data, size); + + if (compressed) + { + boolean status; + + status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); + + if (status != true) + { + printf("Bitmap Decompression Failed\n"); + } + } + else + { + freerdp_image_flip(data, bitmap->data, width, height, bpp); + + } + + bitmap->width = width; + bitmap->height = height; + bitmap->compressed = false; + bitmap->length = size; + bitmap->bpp = bpp; +} + +void gdi_Bitmap_SetSurface(rdpContext* context, rdpBitmap* bitmap, boolean primary) +{ + rdpGdi* gdi = context->gdi; + + if (primary) + gdi->drawing = gdi->primary; + else + gdi->drawing = (gdiBitmap*) bitmap; +} + +/* Glyph Class */ + +void gdi_Glyph_New(rdpContext* context, rdpGlyph* glyph) +{ + uint8* data; + gdiGlyph* gdi_glyph; + + gdi_glyph = (gdiGlyph*) glyph; + + gdi_glyph->hdc = gdi_GetDC(); + gdi_glyph->hdc->bytesPerPixel = 1; + gdi_glyph->hdc->bitsPerPixel = 1; + + data = freerdp_glyph_convert(glyph->cx, glyph->cy, glyph->aj); + gdi_glyph->bitmap = gdi_CreateBitmap(glyph->cx, glyph->cy, 1, data); + gdi_glyph->bitmap->bytesPerPixel = 1; + gdi_glyph->bitmap->bitsPerPixel = 1; + + gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT) gdi_glyph->bitmap); + gdi_glyph->org_bitmap = NULL; +} + +void gdi_Glyph_Free(rdpContext* context, rdpGlyph* glyph) +{ + gdiGlyph* gdi_glyph; + + gdi_glyph = (gdiGlyph*) glyph; + + if (gdi_glyph != 0) + { + gdi_SelectObject(gdi_glyph->hdc, (HGDIOBJECT) gdi_glyph->org_bitmap); + gdi_DeleteObject((HGDIOBJECT) gdi_glyph->bitmap); + gdi_DeleteDC(gdi_glyph->hdc); + } +} + +void gdi_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) +{ + gdiGlyph* gdi_glyph; + rdpGdi* gdi = context->gdi; + + gdi_glyph = (gdiGlyph*) glyph; + + gdi_BitBlt(gdi->drawing->hdc, x, y, gdi_glyph->bitmap->width, + gdi_glyph->bitmap->height, gdi_glyph->hdc, 0, 0, GDI_DSPDxax); +} + +void gdi_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + GDI_RECT rect; + HGDI_BRUSH brush; + rdpGdi* gdi = context->gdi; + + bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); + fgcolor = freerdp_color_convert_var_bgr(fgcolor, gdi->srcBpp, 32, gdi->clrconv); + + gdi_CRgnToRect(x, y, width, height, &rect); + + brush = gdi_CreateSolidBrush(fgcolor); + + gdi_FillRect(gdi->drawing->hdc, &rect, brush); + + gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor); +} + +void gdi_Glyph_EndDraw(rdpContext* context, int x, int y, int width, int height, uint32 bgcolor, uint32 fgcolor) +{ + rdpGdi* gdi = context->gdi; + + bgcolor = freerdp_color_convert_var_bgr(bgcolor, gdi->srcBpp, 32, gdi->clrconv); + gdi->textColor = gdi_SetTextColor(gdi->drawing->hdc, bgcolor); +} + +/* Graphics Module */ + +void gdi_register_graphics(rdpGraphics* graphics) +{ + rdpBitmap* bitmap; + rdpGlyph* glyph; + + bitmap = xnew(rdpBitmap); + bitmap->size = sizeof(gdiBitmap); + + bitmap->New = gdi_Bitmap_New; + bitmap->Free = gdi_Bitmap_Free; + bitmap->Paint = gdi_Bitmap_Paint; + bitmap->Decompress = gdi_Bitmap_Decompress; + bitmap->SetSurface = gdi_Bitmap_SetSurface; + + graphics_register_bitmap(graphics, bitmap); + xfree(bitmap); + + glyph = xnew(rdpGlyph); + glyph->size = sizeof(gdiGlyph); + + glyph->New = gdi_Glyph_New; + glyph->Free = gdi_Glyph_Free; + glyph->Draw = gdi_Glyph_Draw; + glyph->BeginDraw = gdi_Glyph_BeginDraw; + glyph->EndDraw = gdi_Glyph_EndDraw; + + graphics_register_glyph(graphics, glyph); + xfree(glyph); +} + diff --git a/libfreerdp-gdi/graphics.h b/libfreerdp-gdi/graphics.h new file mode 100644 index 0000000..3940a44 --- /dev/null +++ b/libfreerdp-gdi/graphics.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Graphical Objects + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GDI_GRAPHICS_H +#define __GDI_GRAPHICS_H + +#include +#include + +HGDI_BITMAP gdi_create_bitmap(rdpGdi* gdi, int width, int height, int bpp, uint8* data); + +void gdi_Bitmap_New(rdpContext* context, rdpBitmap* bitmap); +void gdi_Bitmap_Free(rdpContext* context, rdpBitmap* bitmap); +void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, + uint8* data, int width, int height, int bpp, int length, boolean compressed); +void gdi_register_graphics(rdpGraphics* graphics); + +#endif /* __GDI_GRAPHICS_H */ diff --git a/libfreerdp-gdi/include/line.c b/libfreerdp-gdi/include/line.c new file mode 100644 index 0000000..ab35d1e --- /dev/null +++ b/libfreerdp-gdi/include/line.c @@ -0,0 +1,110 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI LineTo + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* do not include this file directly! */ + +int LINE_TO(HGDI_DC hdc, int nXEnd, int nYEnd) +{ + int x, y; + int x1, y1; + int x2, y2; + int e, e2; + int dx, dy; + int sx, sy; + int bx1, by1; + int bx2, by2; + PIXEL_TYPE pen; + PIXEL_TYPE* pixel; + HGDI_BITMAP bmp; + + x1 = hdc->pen->posX; + y1 = hdc->pen->posY; + x2 = nXEnd; + y2 = nYEnd; + + dx = (x1 > x2) ? x1 - x2 : x2 - x1; + dy = (y1 > y2) ? y1 - y2 : y2 - y1; + + sx = (x1 < x2) ? 1 : -1; + sy = (y1 < y2) ? 1 : -1; + + e = dx - dy; + + x = x1; + y = y1; + + bmp = (HGDI_BITMAP) hdc->selectedObject; + + if (hdc->clip->null) + { + bx1 = (x1 < x2) ? x1 : x2; + by1 = (y1 < y2) ? y1 : y2; + bx2 = (x1 > x2) ? x1 : x2; + by2 = (y1 > y2) ? y1 : y2; + } + else + { + bx1 = hdc->clip->x; + by1 = hdc->clip->y; + bx2 = bx1 + hdc->clip->w - 1; + by2 = by1 + hdc->clip->h - 1; + } + + pen = GDI_GET_PEN_COLOR(hdc->pen); + + while (1) + { + if (!(x == x2 && y == y2)) + { + if ((x >= bx1 && x <= bx2) && (y >= by1 && y <= by2)) + { + pixel = GDI_GET_POINTER(bmp, x, y); + SET_PIXEL_ROP2(pixel, &pen); + } + } + else + { + break; + } + + e2 = 2 * e; + + if (e2 > -dy) + { + e -= dy; + x += sx; + } + + if (e2 < dx) + { + e += dx; + y += sy; + } + } + + return 1; +} + +/* +#undef LINE_TO +#undef PIXEL_TYPE +#undef SET_PIXEL_ROP2 +#undef GDI_GET_POINTER +#undef GDI_GET_PEN_COLOR +*/ diff --git a/libfreerdp-gdi/line.c b/libfreerdp-gdi/line.c new file mode 100644 index 0000000..014e904 --- /dev/null +++ b/libfreerdp-gdi/line.c @@ -0,0 +1,152 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Line Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +p_LineTo LineTo_[5] = +{ + NULL, + LineTo_8bpp, + LineTo_16bpp, + NULL, + LineTo_32bpp +}; + +/** + * Draw a line from the current position to the given position.\n + * @msdn{dd145029} + * @param hdc device context + * @param nXEnd ending x position + * @param nYEnd ending y position + * @return 1 if successful, 0 otherwise + */ + +int gdi_LineTo(HGDI_DC hdc, int nXEnd, int nYEnd) +{ + p_LineTo _LineTo = LineTo_[IBPP(hdc->bitsPerPixel)]; + + if (_LineTo != NULL) + return _LineTo(hdc, nXEnd, nYEnd); + else + return 0; +} + +/** + * Draw one or more straight lines + * @param hdc device context + * @param lppt array of points + * @param cCount number of points + * @return + */ +int gdi_PolylineTo(HGDI_DC hdc, GDI_POINT *lppt, int cCount) +{ + int i; + + for (i = 0; i < cCount; i++) + { + gdi_LineTo(hdc, lppt[i].x, lppt[i].y); + gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL); + } + + return 1; +} + +/** + * Draw one or more straight lines + * @param hdc device context + * @param lppt array of points + * @param cPoints number of points + * @return + */ +int gdi_Polyline(HGDI_DC hdc, GDI_POINT *lppt, int cPoints) +{ + if (cPoints > 0) + { + int i; + GDI_POINT pt; + + gdi_MoveToEx(hdc, lppt[0].x, lppt[0].y, &pt); + + for (i = 0; i < cPoints; i++) + { + gdi_LineTo(hdc, lppt[i].x, lppt[i].y); + gdi_MoveToEx(hdc, lppt[i].x, lppt[i].y, NULL); + } + + gdi_MoveToEx(hdc, pt.x, pt.y, NULL); + } + + return 1; +} + +/** + * Draw multiple series of connected line segments + * @param hdc device context + * @param lppt array of points + * @param lpdwPolyPoints array of numbers of points per series + * @param cCount count of entries in lpdwPolyPoints + * @return + */ +int gdi_PolyPolyline(HGDI_DC hdc, GDI_POINT *lppt, int *lpdwPolyPoints, int cCount) +{ + int cPoints; + int i, j = 0; + + for (i = 0; i < cCount; i++) + { + cPoints = lpdwPolyPoints[i]; + gdi_Polyline(hdc, &lppt[j], cPoints); + j += cPoints; + } + + return 1; +} + +/** + * Move pen from the current device context to a new position. + * @param hdc device context + * @param X x position + * @param Y y position + * @return 1 if successful, 0 otherwise + */ + +int gdi_MoveToEx(HGDI_DC hdc, int X, int Y, HGDI_POINT lpPoint) +{ + if (lpPoint != NULL) + { + lpPoint->x = hdc->pen->posX; + lpPoint->y = hdc->pen->posY; + } + + hdc->pen->posX = X; + hdc->pen->posY = Y; + + return 1; +} diff --git a/libfreerdp-gdi/palette.c b/libfreerdp-gdi/palette.c new file mode 100644 index 0000000..1df08d9 --- /dev/null +++ b/libfreerdp-gdi/palette.c @@ -0,0 +1,106 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Palette Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* GDI Palette Functions: http://msdn.microsoft.com/en-us/library/dd183454/ */ + +#include +#include +#include + +#include +#include + +#include + +static HGDI_PALETTE hSystemPalette = NULL; + +static const GDI_PALETTEENTRY default_system_palette[20] = +{ + /* First 10 entries */ + { 0x00, 0x00, 0x00 }, + { 0x80, 0x00, 0x00 }, + { 0x00, 0x80, 0x00 }, + { 0x80, 0x80, 0x00 }, + { 0x00, 0x00, 0x80 }, + { 0x80, 0x00, 0x80 }, + { 0x00, 0x80, 0x80 }, + { 0xC0, 0xC0, 0xC0 }, + { 0xC0, 0xDC, 0xC0 }, + { 0xA6, 0xCA, 0xF0 }, + + /* Last 10 entries */ + { 0xFF, 0xFB, 0xF0 }, + { 0xA0, 0xA0, 0xA4 }, + { 0x80, 0x80, 0x80 }, + { 0xFF, 0x00, 0x00 }, + { 0x00, 0xFF, 0x00 }, + { 0xFF, 0xFF, 0x00 }, + { 0x00, 0x00, 0xFF }, + { 0xFF, 0x00, 0xFF }, + { 0x00, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF } +}; + +/** + * Create a new palette.\n + * @msdn{dd183507} + * @param original palette + * @return new palette + */ + +HGDI_PALETTE gdi_CreatePalette(HGDI_PALETTE palette) +{ + HGDI_PALETTE hPalette = (HGDI_PALETTE) malloc(sizeof(GDI_PALETTE)); + hPalette->count = palette->count; + hPalette->entries = (GDI_PALETTEENTRY*) malloc(sizeof(GDI_PALETTEENTRY) * hPalette->count); + memcpy(hPalette->entries, palette->entries, sizeof(GDI_PALETTEENTRY) * hPalette->count); + return hPalette; +} + +/** + * Create system palette\n + * @return system palette + */ + +HGDI_PALETTE CreateSystemPalette() +{ + HGDI_PALETTE palette = (HGDI_PALETTE) malloc(sizeof(GDI_PALETTE)); + + palette->count = 256; + palette->entries = (GDI_PALETTEENTRY*) malloc(sizeof(GDI_PALETTEENTRY) * 256); + memset(palette->entries, 0, sizeof(GDI_PALETTEENTRY) * 256); + + memcpy(&palette->entries[0], &default_system_palette[0], 10 * sizeof(GDI_PALETTEENTRY)); + memcpy(&palette->entries[256 - 10], &default_system_palette[10], 10 * sizeof(GDI_PALETTEENTRY)); + + return palette; +} + +/** + * Get system palette\n + * @return system palette + */ + +HGDI_PALETTE gdi_GetSystemPalette() +{ + if (hSystemPalette == NULL) + hSystemPalette = CreateSystemPalette(); + + return hSystemPalette; +} diff --git a/libfreerdp-gdi/pen.c b/libfreerdp-gdi/pen.c new file mode 100644 index 0000000..735f159 --- /dev/null +++ b/libfreerdp-gdi/pen.c @@ -0,0 +1,70 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Pen Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* GDI Pen Functions: http://msdn.microsoft.com/en-us/library/dd162790 */ + +#include +#include +#include + +#include +#include +#include + +#include + +/** + * Create a new pen.\n + * @msdn{dd183509} + * @param fnPenStyle pen style + * @param nWidth pen width + * @param crColor pen color + * @return new pen + */ + +HGDI_PEN gdi_CreatePen(int fnPenStyle, int nWidth, int crColor) +{ + HGDI_PEN hPen = (HGDI_PEN) malloc(sizeof(GDI_PEN)); + hPen->objectType = GDIOBJECT_PEN; + hPen->style = fnPenStyle; + hPen->color = crColor; + hPen->width = nWidth; + return hPen; +} + +INLINE uint8 gdi_GetPenColor_8bpp(HGDI_PEN pen) +{ + /* TODO: implement conversion using palette */ + return 0xFF; +} + +INLINE uint16 gdi_GetPenColor_16bpp(HGDI_PEN pen) +{ + uint16 p; + int r, g, b; + GetRGB32(r, g, b, pen->color); + RGB_888_565(r, g, b); + p = RGB16(r, g, b); + return p; +} + +INLINE uint32 gdi_GetPenColor_32bpp(HGDI_PEN pen) +{ + return pen->color; +} diff --git a/libfreerdp-gdi/region.c b/libfreerdp-gdi/region.c new file mode 100644 index 0000000..e9d0447 --- /dev/null +++ b/libfreerdp-gdi/region.c @@ -0,0 +1,423 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Region Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include + +#include + +/** + * Create a region from rectangular coordinates.\n + * @msdn{dd183514} + * @param nLeftRect x1 + * @param nTopRect y1 + * @param nRightRect x2 + * @param nBottomRect y2 + * @return new region + */ + +HGDI_RGN gdi_CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) +{ + HGDI_RGN hRgn = (HGDI_RGN) malloc(sizeof(GDI_RGN)); + hRgn->objectType = GDIOBJECT_REGION; + hRgn->x = nLeftRect; + hRgn->y = nTopRect; + hRgn->w = nRightRect - nLeftRect + 1; + hRgn->h = nBottomRect - nTopRect + 1; + hRgn->null = 0; + return hRgn; +} + +/** + * Create a new rectangle. + * @param xLeft x1 + * @param yTop y1 + * @param xRight x2 + * @param yBottom y2 + * @return new rectangle + */ + +HGDI_RECT gdi_CreateRect(int xLeft, int yTop, int xRight, int yBottom) +{ + HGDI_RECT hRect = (HGDI_RECT) malloc(sizeof(GDI_RECT)); + hRect->objectType = GDIOBJECT_RECT; + hRect->left = xLeft; + hRect->top = yTop; + hRect->right = xRight; + hRect->bottom = yBottom; + return hRect; +} + +/** + * Convert a rectangle to a region. + * @param rect source rectangle + * @param rgn destination region + */ + +INLINE void gdi_RectToRgn(HGDI_RECT rect, HGDI_RGN rgn) +{ + rgn->x = rect->left; + rgn->y = rect->top; + rgn->w = rect->right - rect->left + 1; + rgn->h = rect->bottom - rect->top + 1; +} + +/** + * Convert rectangular coordinates to a region. + * @param left x1 + * @param top y1 + * @param right x2 + * @param bottom y2 + * @param rgn destination region + */ + +INLINE void gdi_CRectToRgn(int left, int top, int right, int bottom, HGDI_RGN rgn) +{ + rgn->x = left; + rgn->y = top; + rgn->w = right - left + 1; + rgn->h = bottom - top + 1; +} + +/** + * Convert a rectangle to region coordinates. + * @param rect source rectangle + * @param x x1 + * @param y y1 + * @param w width + * @param h height + */ + +INLINE void gdi_RectToCRgn(HGDI_RECT rect, int *x, int *y, int *w, int *h) +{ + *x = rect->left; + *y = rect->top; + *w = rect->right - rect->left + 1; + *h = rect->bottom - rect->top + 1; +} + +/** + * Convert rectangular coordinates to region coordinates. + * @param left x1 + * @param top y1 + * @param right x2 + * @param bottom y2 + * @param x x1 + * @param y y1 + * @param w width + * @param h height + */ + +INLINE void gdi_CRectToCRgn(int left, int top, int right, int bottom, int *x, int *y, int *w, int *h) +{ + *x = left; + *y = top; + *w = right - left + 1; + *h = bottom - top + 1; +} + +/** + * Convert a region to a rectangle. + * @param rgn source region + * @param rect destination rectangle + */ + +INLINE void gdi_RgnToRect(HGDI_RGN rgn, HGDI_RECT rect) +{ + rect->left = rgn->x; + rect->top = rgn->y; + rect->right = rgn->x + rgn->w - 1; + rect->bottom = rgn->y + rgn->h - 1; +} + +/** + * Convert region coordinates to a rectangle. + * @param x x1 + * @param y y1 + * @param w width + * @param h height + * @param rect destination rectangle + */ + +INLINE void gdi_CRgnToRect(int x, int y, int w, int h, HGDI_RECT rect) +{ + rect->left = x; + rect->top = y; + rect->right = x + w - 1; + rect->bottom = y + h - 1; +} + +/** + * Convert a region to rectangular coordinates. + * @param rgn source region + * @param left x1 + * @param top y1 + * @param right x2 + * @param bottom y2 + */ + +INLINE void gdi_RgnToCRect(HGDI_RGN rgn, int *left, int *top, int *right, int *bottom) +{ + *left = rgn->x; + *top = rgn->y; + *right = rgn->x + rgn->w - 1; + *bottom = rgn->y + rgn->h - 1; +} + +/** + * Convert region coordinates to rectangular coordinates. + * @param x x1 + * @param y y1 + * @param w width + * @param h height + * @param left x1 + * @param top y1 + * @param right x2 + * @param bottom y2 + */ + +INLINE void gdi_CRgnToCRect(int x, int y, int w, int h, int *left, int *top, int *right, int *bottom) +{ + *left = x; + *top = y; + *right = x + w - 1; + *bottom = y + h - 1; +} + +/** + * Check if copying would involve overlapping regions + * @param x x1 + * @param y y1 + * @param width width + * @param height height + * @param srcx source x1 + * @param srcy source y1 + * @return 1 if there is an overlap, 0 otherwise + */ + +INLINE int gdi_CopyOverlap(int x, int y, int width, int height, int srcx, int srcy) +{ + GDI_RECT dst; + GDI_RECT src; + + gdi_CRgnToRect(x, y, width, height, &dst); + gdi_CRgnToRect(srcx, srcy, width, height, &src); + + return (dst.right > src.left && dst.left < src.right && + dst.bottom > src.top && dst.top < src.bottom) ? 1 : 0; +} + +/** + * Set the coordinates of a given rectangle.\n + * @msdn{dd145085} + * @param rc rectangle + * @param xLeft x1 + * @param yTop y1 + * @param xRight x2 + * @param yBottom y2 + * @return 1 if successful, 0 otherwise + */ + +INLINE int gdi_SetRect(HGDI_RECT rc, int xLeft, int yTop, int xRight, int yBottom) +{ + rc->left = xLeft; + rc->top = yTop; + rc->right = xRight; + rc->bottom = yBottom; + return 1; +} + +/** + * Set the coordinates of a given region. + * @param hRgn region + * @param nXLeft x1 + * @param nYLeft y1 + * @param nWidth width + * @param nHeight height + * @return + */ + +INLINE int gdi_SetRgn(HGDI_RGN hRgn, int nXLeft, int nYLeft, int nWidth, int nHeight) +{ + hRgn->x = nXLeft; + hRgn->y = nYLeft; + hRgn->w = nWidth; + hRgn->h = nHeight; + hRgn->null = 0; + return 0; +} + +/** + * Convert rectangular coordinates to a region + * @param hRgn destination region + * @param nLeftRect x1 + * @param nTopRect y1 + * @param nRightRect x2 + * @param nBottomRect y2 + * @return + */ + +INLINE int gdi_SetRectRgn(HGDI_RGN hRgn, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) +{ + gdi_CRectToRgn(nLeftRect, nTopRect, nRightRect, nBottomRect, hRgn); + hRgn->null = 0; + return 0; +} + +/** + * Compare two regions for equality.\n + * @msdn{dd162700} + * @param hSrcRgn1 first region + * @param hSrcRgn2 second region + * @return 1 if both regions are equal, 0 otherwise + */ + +INLINE int gdi_EqualRgn(HGDI_RGN hSrcRgn1, HGDI_RGN hSrcRgn2) +{ + if ((hSrcRgn1->x == hSrcRgn2->x) && + (hSrcRgn1->y == hSrcRgn2->y) && + (hSrcRgn1->w == hSrcRgn2->w) && + (hSrcRgn1->h == hSrcRgn2->h)) + { + return 1; + } + + return 0; +} + +/** + * Copy coordinates from a rectangle to another rectangle + * @param dst destination rectangle + * @param src source rectangle + * @return 1 if successful, 0 otherwise + */ + +INLINE int gdi_CopyRect(HGDI_RECT dst, HGDI_RECT src) +{ + dst->left = src->left; + dst->top = src->top; + dst->right = src->right; + dst->bottom = src->bottom; + return 1; +} + +/** + * Check if a point is inside a rectangle.\n + * @msdn{dd162882} + * @param rc rectangle + * @param x point x position + * @param y point y position + * @return 1 if the point is inside, 0 otherwise + */ + +INLINE int gdi_PtInRect(HGDI_RECT rc, int x, int y) +{ + /* + * points on the left and top sides are considered in, + * while points on the right and bottom sides are considered out + */ + + if (x >= rc->left && x <= rc->right) + { + if (y >= rc->top && y <= rc->bottom) + { + return 1; + } + } + + return 0; +} + +/** + * Invalidate a given region, such that it is redrawn on the next region update.\n + * @msdn{dd145003} + * @param hdc device context + * @param x x1 + * @param y y1 + * @param w width + * @param h height + * @return + */ + +INLINE int gdi_InvalidateRegion(HGDI_DC hdc, int x, int y, int w, int h) +{ + GDI_RECT inv; + GDI_RECT rgn; + HGDI_RGN invalid; + HGDI_RGN cinvalid; + + if (hdc->hwnd == NULL) + return 0; + + if (hdc->hwnd->invalid == NULL) + return 0; + + cinvalid = hdc->hwnd->cinvalid; + + if (hdc->hwnd->ninvalid + 1 > hdc->hwnd->count) + { + hdc->hwnd->count *= 2; + cinvalid = (HGDI_RGN) realloc(cinvalid, sizeof(GDI_RGN) * (hdc->hwnd->count)); + } + + gdi_SetRgn(&cinvalid[hdc->hwnd->ninvalid++], x, y, w, h); + hdc->hwnd->cinvalid = cinvalid; + + invalid = hdc->hwnd->invalid; + + if (invalid->null) + { + invalid->x = x; + invalid->y = y; + invalid->w = w; + invalid->h = h; + invalid->null = 0; + return 0; + } + + gdi_CRgnToRect(x, y, w, h, &rgn); + gdi_RgnToRect(invalid, &inv); + + if (rgn.left < 0) + rgn.left = 0; + + if (rgn.top < 0) + rgn.top = 0; + + if (rgn.left < inv.left) + inv.left = rgn.left; + + if (rgn.top < inv.top) + inv.top = rgn.top; + + if (rgn.right > inv.right) + inv.right = rgn.right; + + if (rgn.bottom > inv.bottom) + inv.bottom = rgn.bottom; + + gdi_RectToRgn(&inv, invalid); + + return 0; +} diff --git a/libfreerdp-gdi/shape.c b/libfreerdp-gdi/shape.c new file mode 100644 index 0000000..4ae449a --- /dev/null +++ b/libfreerdp-gdi/shape.c @@ -0,0 +1,223 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * GDI Shape Functions + * + * Copyright 2010-2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +p_FillRect FillRect_[5] = +{ + NULL, + FillRect_8bpp, + FillRect_16bpp, + NULL, + FillRect_32bpp +}; + +static void Ellipse_Bresenham(HGDI_DC hdc, int x1, int y1, int x2, int y2) +{ + int i; + long e, e2; + long dx, dy; + int a, b, c; + + HGDI_BITMAP bmp; + uint8 pixel8; + uint16 pixel16; + uint32 pixel32; + int bpp = hdc->bitsPerPixel; + + a = (x1 < x2) ? x2 - x1 : x1 - x2; + b = (y1 < y2) ? y2 - y1 : y1 - y2; + c = b & 1; + + dx = 4 * (1 - a) * b * b; + dy = 4 * (c + 1) * a * a; + e = dx + dy + c * a * a; + + if (x1 > x2) + { + x1 = x2; + x2 += a; + } + + if (y1 > y2) + y1 = y2; + + y1 += (b + 1) / 2; + y2 = y1 - c; + + a *= 8 * a; + c = 8 * b * b; + + pixel8 = 0; + pixel16 = 0; + pixel32 = 0; + bmp = (HGDI_BITMAP) hdc->selectedObject; + + do + { + if (bpp == 32) + { + gdi_SetPixel_32bpp(bmp, x2, y1, pixel32); + gdi_SetPixel_32bpp(bmp, x1, y1, pixel32); + gdi_SetPixel_32bpp(bmp, x1, y2, pixel32); + gdi_SetPixel_32bpp(bmp, x2, y2, pixel32); + } + else if (bpp == 16) + { + gdi_SetPixel_16bpp(bmp, x2, y1, pixel16); + gdi_SetPixel_16bpp(bmp, x1, y1, pixel16); + gdi_SetPixel_16bpp(bmp, x1, y2, pixel16); + gdi_SetPixel_16bpp(bmp, x2, y2, pixel16); + } + else if (bpp == 8) + { + for (i = x1; i < x2; i++) + { + gdi_SetPixel_8bpp(bmp, i, y1, pixel8); + gdi_SetPixel_8bpp(bmp, i, y2, pixel8); + } + + for (i = y1; i < y2; i++) + { + gdi_SetPixel_8bpp(bmp, x1, i, pixel8); + gdi_SetPixel_8bpp(bmp, x2, i, pixel8); + } + } + + e2 = 2 * e; + + if (e2 >= dx) + { + x1++; + x2--; + e += dx += c; + } + + if (e2 <= dy) + { + y1++; + y2--; + e += dy += a; + } + } + while (x1 <= x2); + + while (y1 - y2 < b) + { + if (bpp == 32) + { + gdi_SetPixel_32bpp(bmp, x1 - 1, ++y1, pixel32); + gdi_SetPixel_32bpp(bmp, x1 - 1, --y2, pixel32); + } + else if (bpp == 16) + { + gdi_SetPixel_16bpp(bmp, x1 - 1, ++y1, pixel16); + gdi_SetPixel_16bpp(bmp, x1 - 1, --y2, pixel16); + } + else if (bpp == 8) + { + gdi_SetPixel_8bpp(bmp, x1 - 1, ++y1, pixel8); + gdi_SetPixel_8bpp(bmp, x1 - 1, --y2, pixel8); + } + } +} + +/** + * Draw an ellipse + * @param hdc device context + * @param nLeftRect x1 + * @param nTopRect y1 + * @param nRightRect x2 + * @param nBottomRect y2 + * @return + */ +int gdi_Ellipse(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) +{ + Ellipse_Bresenham(hdc, nLeftRect, nTopRect, nRightRect, nBottomRect); + return 1; +} + +/** + * Fill a rectangle with the given brush.\n + * @msdn{dd162719} + * @param hdc device context + * @param rect rectangle + * @param hbr brush + * @return 1 if successful, 0 otherwise + */ + +int gdi_FillRect(HGDI_DC hdc, HGDI_RECT rect, HGDI_BRUSH hbr) +{ + p_FillRect _FillRect = FillRect_[IBPP(hdc->bitsPerPixel)]; + + if (_FillRect != NULL) + return _FillRect(hdc, rect, hbr); + else + return 0; +} + +/** + * + * @param hdc device context + * @param lpPoints array of points + * @param nCount number of points + * @return + */ +int gdi_Polygon(HGDI_DC hdc, GDI_POINT *lpPoints, int nCount) +{ + return 1; +} + +/** + * Draw a series of closed polygons + * @param hdc device context + * @param lpPoints array of series of points + * @param lpPolyCounts array of number of points in each series + * @param nCount count of number of points in lpPolyCounts + * @return + */ +int gdi_PolyPolygon(HGDI_DC hdc, GDI_POINT *lpPoints, int *lpPolyCounts, int nCount) +{ + return 1; +} + +/** + * Draw a rectangle + * @param hdc device context + * @param nLeftRect x1 + * @param nTopRect y1 + * @param nRightRect x2 + * @param nBottomRect y2 + * @return + */ +int gdi_Rectangle(HGDI_DC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) +{ + return 1; +} diff --git a/libfreerdp-kbd/CMakeLists.txt b/libfreerdp-kbd/CMakeLists.txt new file mode 100644 index 0000000..e16fd78 --- /dev/null +++ b/libfreerdp-kbd/CMakeLists.txt @@ -0,0 +1,53 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-kbd cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_KBD_SRCS + locales.c + layouts.c + layouts_xkb.c + layouts_xkb.h + x_layout_id_table.c + x_layout_id_table.h + libkbd.c + libkbd.h) + +add_library(freerdp-kbd ${FREERDP_KBD_SRCS}) + +find_suggested_package(X11) +if(WITH_X11) + target_link_libraries(freerdp-kbd ${X11_LIBRARIES}) +endif() + +if(NOT APPLE) + find_suggested_package(XKBFile) + if(WITH_X11) + if(WITH_XKBFILE) + add_definitions(-DWITH_XKBFILE) + include_directories(${XKBFILE_INCLUDE_DIRS}) + target_link_libraries(freerdp-kbd ${XKBFILE_LIBRARIES}) + endif() + endif() +endif() + +add_definitions(-DKEYMAP_PATH="${FREERDP_KEYMAP_PATH}") + +set_target_properties(freerdp-kbd PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +install(TARGETS freerdp-kbd DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/libfreerdp-kbd/layouts.c b/libfreerdp-kbd/layouts.c new file mode 100644 index 0000000..1f8a5ae --- /dev/null +++ b/libfreerdp-kbd/layouts.c @@ -0,0 +1,300 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "libkbd.h" + +#include + +typedef struct +{ + /* Keyboard layout code */ + unsigned int code; + + /* Keyboard layout name */ + char name[50]; + +} keyboardLayout; + +/* + * In Windows XP, this information is available in the system registry at + * HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet001/Control/Keyboard Layouts/ + */ + +static const keyboardLayout keyboardLayouts[] = +{ + { KBD_ARABIC_101, "Arabic (101)" }, + { KBD_BULGARIAN, "Bulgarian" }, + { KBD_CHINESE_TRADITIONAL_US, "Chinese (Traditional) - US Keyboard" }, + { KBD_CZECH, "Czech" }, + { KBD_DANISH, "Danish" }, + { KBD_GERMAN, "German" }, + { KBD_GREEK, "Greek" }, + { KBD_US, "US" }, + { KBD_SPANISH, "Spanish" }, + { KBD_FINNISH, "Finnish" }, + { KBD_FRENCH, "French" }, + { KBD_HEBREW, "Hebrew" }, + { KBD_HUNGARIAN, "Hungarian" }, + { KBD_ICELANDIC, "Icelandic" }, + { KBD_ITALIAN, "Italian" }, + { KBD_JAPANESE, "Japanese" }, + { KBD_KOREAN, "Korean" }, + { KBD_DUTCH, "Dutch" }, + { KBD_NORWEGIAN, "Norwegian" }, + { KBD_POLISH_PROGRAMMERS, "Polish (Programmers)" }, + { KBD_PORTUGUESE_BRAZILIAN_ABNT,"Portuguese (Brazilian ABNT)" }, + { KBD_ROMANIAN, "Romanian" }, + { KBD_RUSSIAN, "Russian" }, + { KBD_CROATIAN, "Croatian" }, + { KBD_SLOVAK, "Slovak" }, + { KBD_ALBANIAN, "Albanian" }, + { KBD_SWEDISH, "Swedish" }, + { KBD_THAI_KEDMANEE, "Thai Kedmanee" }, + { KBD_TURKISH_Q, "Turkish Q" }, + { KBD_URDU, "Urdu" }, + { KBD_UKRAINIAN, "Ukrainian" }, + { KBD_BELARUSIAN, "Belarusian" }, + { KBD_SLOVENIAN, "Slovenian" }, + { KBD_ESTONIAN, "Estonian" }, + { KBD_LATVIAN, "Latvian" }, + { KBD_LITHUANIAN_IBM, "Lithuanian IBM" }, + { KBD_FARSI, "Farsi" }, + { KBD_VIETNAMESE, "Vietnamese" }, + { KBD_ARMENIAN_EASTERN, "Armenian Eastern" }, + { KBD_AZERI_LATIN, "Azeri Latin" }, + { KBD_FYRO_MACEDONIAN, "FYRO Macedonian" }, + { KBD_GEORGIAN, "Georgian" }, + { KBD_FAEROESE, "Faeroese" }, + { KBD_DEVANAGARI_INSCRIPT, "Devanagari - INSCRIPT" }, + { KBD_MALTESE_47_KEY, "Maltese 47-key" }, + { KBD_NORWEGIAN_WITH_SAMI, "Norwegian with Sami" }, + { KBD_KAZAKH, "Kazakh" }, + { KBD_KYRGYZ_CYRILLIC, "Kyrgyz Cyrillic" }, + { KBD_TATAR, "Tatar" }, + { KBD_BENGALI, "Bengali" }, + { KBD_PUNJABI, "Punjabi" }, + { KBD_GUJARATI, "Gujarati" }, + { KBD_TAMIL, "Tamil" }, + { KBD_TELUGU, "Telugu" }, + { KBD_KANNADA, "Kannada" }, + { KBD_MALAYALAM, "Malayalam" }, + { KBD_MARATHI, "Marathi" }, + { KBD_MONGOLIAN_CYRILLIC, "Mongolian Cyrillic" }, + { KBD_UNITED_KINGDOM_EXTENDED, "United Kingdom Extended" }, + { KBD_SYRIAC, "Syriac" }, + { KBD_NEPALI, "Nepali" }, + { KBD_PASHTO, "Pashto" }, + { KBD_DIVEHI_PHONETIC, "Divehi Phonetic" }, + { KBD_LUXEMBOURGISH, "Luxembourgish" }, + { KBD_MAORI, "Maori" }, + { KBD_CHINESE_SIMPLIFIED_US, "Chinese (Simplified) - US Keyboard" }, + { KBD_SWISS_GERMAN, "Swiss German" }, + { KBD_UNITED_KINGDOM, "United Kingdom" }, + { KBD_LATIN_AMERICAN, "Latin American" }, + { KBD_BELGIAN_FRENCH, "Belgian French" }, + { KBD_BELGIAN_PERIOD, "Belgian (Period)" }, + { KBD_PORTUGUESE, "Portuguese" }, + { KBD_SERBIAN_LATIN, "Serbian (Latin)" }, + { KBD_AZERI_CYRILLIC, "Azeri Cyrillic" }, + { KBD_SWEDISH_WITH_SAMI, "Swedish with Sami" }, + { KBD_UZBEK_CYRILLIC, "Uzbek Cyrillic" }, + { KBD_INUKTITUT_LATIN, "Inuktitut Latin" }, + { KBD_CANADIAN_FRENCH_LEGACY, "Canadian French (legacy)" }, + { KBD_SERBIAN_CYRILLIC, "Serbian (Cyrillic)" }, + { KBD_CANADIAN_FRENCH, "Canadian French" }, + { KBD_SWISS_FRENCH, "Swiss French" }, + { KBD_BOSNIAN, "Bosnian" }, + { KBD_IRISH, "Irish" }, + { KBD_BOSNIAN_CYRILLIC, "Bosnian Cyrillic" } +}; + + +typedef struct +{ + /* Keyboard layout code */ + unsigned int code; + + /* Keyboard variant ID */ + unsigned short id; + + /* Keyboard layout variant name */ + char name[50]; + +} keyboardLayoutVariant; + + +static const keyboardLayoutVariant keyboardLayoutVariants[] = +{ + { KBD_ARABIC_102, 0x0028, "Arabic (102)" }, + { KBD_BULGARIAN_LATIN, 0x0004, "Bulgarian (Latin)" }, + { KBD_CZECH_QWERTY, 0x0005, "Czech (QWERTY)" }, + { KBD_GERMAN_IBM, 0x0012, "German (IBM)" }, + { KBD_GREEK_220, 0x0016, "Greek (220)" }, + { KBD_UNITED_STATES_DVORAK, 0x0002, "United States-Dvorak" }, + { KBD_SPANISH_VARIATION, 0x0086, "Spanish Variation" }, + { KBD_HUNGARIAN_101_KEY, 0x0006, "Hungarian 101-key" }, + { KBD_ITALIAN_142, 0x0003, "Italian (142)" }, + { KBD_POLISH_214, 0x0007, "Polish (214)" }, + { KBD_PORTUGUESE_BRAZILIAN_ABNT2, 0x001D, "Portuguese (Brazilian ABNT2)" }, + { KBD_RUSSIAN_TYPEWRITER, 0x0008, "Russian (Typewriter)" }, + { KBD_SLOVAK_QWERTY, 0x0013, "Slovak (QWERTY)" }, + { KBD_THAI_PATTACHOTE, 0x0021, "Thai Pattachote" }, + { KBD_TURKISH_F, 0x0014, "Turkish F" }, + { KBD_LATVIAN_QWERTY, 0x0015, "Latvian (QWERTY)" }, + { KBD_LITHUANIAN, 0x0027, "Lithuanian" }, + { KBD_ARMENIAN_WESTERN, 0x0025, "Armenian Western" }, + { KBD_HINDI_TRADITIONAL, 0x000C, "Hindi Traditional" }, + { KBD_MALTESE_48_KEY, 0x002B, "Maltese 48-key" }, + { KBD_SAMI_EXTENDED_NORWAY, 0x002C, "Sami Extended Norway" }, + { KBD_BENGALI_INSCRIPT, 0x002A, "Bengali (Inscript)" }, + { KBD_SYRIAC_PHONETIC, 0x000E, "Syriac Phonetic" }, + { KBD_DIVEHI_TYPEWRITER, 0x000D, "Divehi Typewriter" }, + { KBD_BELGIAN_COMMA, 0x001E, "Belgian (Comma)" }, + { KBD_FINNISH_WITH_SAMI, 0x002D, "Finnish with Sami" }, + { KBD_CANADIAN_MULTILINGUAL_STANDARD, 0x0020, "Canadian Multilingual Standard" }, + { KBD_GAELIC, 0x0026, "Gaelic" }, + { KBD_ARABIC_102_AZERTY, 0x0029, "Arabic (102) AZERTY" }, + { KBD_CZECH_PROGRAMMERS, 0x000A, "Czech Programmers" }, + { KBD_GREEK_319, 0x0018, "Greek (319)" }, + { KBD_UNITED_STATES_INTERNATIONAL, 0x0001, "United States-International" }, + { KBD_THAI_KEDMANEE_NON_SHIFTLOCK, 0x0022, "Thai Kedmanee (non-ShiftLock)" }, + { KBD_SAMI_EXTENDED_FINLAND_SWEDEN, 0x002E, "Sami Extended Finland-Sweden" }, + { KBD_GREEK_220_LATIN, 0x0017, "Greek (220) Latin" }, + { KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND, 0x001A, "United States-Dvorak for left hand" }, + { KBD_THAI_PATTACHOTE_NON_SHIFTLOCK, 0x0023, "Thai Pattachote (non-ShiftLock)" }, + { KBD_GREEK_319_LATIN, 0x0011, "Greek (319) Latin" }, + { KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND, 0x001B, "United States-Dvorak for right hand" }, + { KBD_GREEK_LATIN, 0x0019, "Greek Latin" }, + { KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L, 0x000B, "US English Table for IBM Arabic 238_L" }, + { KBD_GREEK_POLYTONIC, 0x001F, "Greek Polytonic" }, + { KBD_GERMAN_NEO, 0x00C0, "German Neo" } +}; + +/* Input Method Editor (IME) */ + +typedef struct +{ + /* Keyboard layout code */ + unsigned int code; + + /* IME file name */ + char fileName[32]; + + /* Keyboard layout name */ + char name[50]; + +} keyboardIME; + + +/* Global Input Method Editors (IME) */ + +static const keyboardIME keyboardIMEs[] = +{ + { KBD_CHINESE_TRADITIONAL_PHONETIC, "phon.ime", "Chinese (Traditional) - Phonetic" }, + { KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, "imjp81.ime", "Japanese Input System (MS-IME2002)" }, + { KBD_KOREAN_INPUT_SYSTEM_IME_2000, "imekr61.ime", "Korean Input System (IME 2000)" }, + { KBD_CHINESE_SIMPLIFIED_QUANPIN, "winpy.ime", "Chinese (Simplified) - QuanPin" }, + { KBD_CHINESE_TRADITIONAL_CHANGJIE, "chajei.ime", "Chinese (Traditional) - ChangJie" }, + { KBD_CHINESE_SIMPLIFIED_SHUANGPIN, "winsp.ime", "Chinese (Simplified) - ShuangPin" }, + { KBD_CHINESE_TRADITIONAL_QUICK, "quick.ime", "Chinese (Traditional) - Quick" }, + { KBD_CHINESE_SIMPLIFIED_ZHENGMA, "winzm.ime", "Chinese (Simplified) - ZhengMa" }, + { KBD_CHINESE_TRADITIONAL_BIG5_CODE, "winime.ime", "Chinese (Traditional) - Big5 Code" }, + { KBD_CHINESE_TRADITIONAL_ARRAY, "winar30.ime", "Chinese (Traditional) - Array" }, + { KBD_CHINESE_SIMPLIFIED_NEIMA, "wingb.ime", "Chinese (Simplified) - NeiMa" }, + { KBD_CHINESE_TRADITIONAL_DAYI, "dayi.ime", "Chinese (Traditional) - DaYi" }, + { KBD_CHINESE_TRADITIONAL_UNICODE, "unicdime.ime", "Chinese (Traditional) - Unicode" }, + { KBD_CHINESE_TRADITIONAL_NEW_PHONETIC, "TINTLGNT.IME", "Chinese (Traditional) - New Phonetic" }, + { KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE, "CINTLGNT.IME", "Chinese (Traditional) - New ChangJie" }, + { KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3, "pintlgnt.ime", "Chinese (Traditional) - Microsoft Pinyin IME 3.0" }, + { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" } +}; + + +rdpKeyboardLayout* get_keyboard_layouts(int types) +{ + int num, len, i; + rdpKeyboardLayout * layouts; + + num = 0; + layouts = (rdpKeyboardLayout *) malloc((num + 1) * sizeof(rdpKeyboardLayout)); + + if ((types & RDP_KEYBOARD_LAYOUT_TYPE_STANDARD) != 0) + { + len = sizeof(keyboardLayouts) / sizeof(keyboardLayout); + layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); + for (i = 0; i < len; i++, num++) + { + layouts[num].code = keyboardLayouts[i].code; + strcpy(layouts[num].name, keyboardLayouts[i].name); + } + } + if ((types & RDP_KEYBOARD_LAYOUT_TYPE_VARIANT) != 0) + { + len = sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); + layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); + for (i = 0; i < len; i++, num++) + { + layouts[num].code = keyboardLayoutVariants[i].code; + strcpy(layouts[num].name, keyboardLayoutVariants[i].name); + } + } + if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0) + { + len = sizeof(keyboardIMEs) / sizeof(keyboardIME); + layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); + + for (i = 0; i < len; i++, num++) + { + layouts[num].code = keyboardIMEs[i].code; + strcpy(layouts[num].name, keyboardIMEs[i].name); + } + } + + memset(&layouts[num], 0, sizeof(rdpKeyboardLayout)); + + return layouts; +} + +const char* get_layout_name(unsigned int keyboardLayoutID) +{ + int i; + + for (i = 0; i < sizeof(keyboardLayouts) / sizeof(keyboardLayout); i++) + { + if (keyboardLayouts[i].code == keyboardLayoutID) + return keyboardLayouts[i].name; + } + + for (i = 0; i < sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); i++) + { + if (keyboardLayoutVariants[i].code == keyboardLayoutID) + return keyboardLayoutVariants[i].name; + } + + for (i = 0; i < sizeof(keyboardIMEs) / sizeof(keyboardIME); i++) + { + if (keyboardIMEs[i].code == keyboardLayoutID) + return keyboardIMEs[i].name; + } + + return "unknown"; +} diff --git a/libfreerdp-kbd/layouts_xkb.c b/libfreerdp-kbd/layouts_xkb.c new file mode 100644 index 0000000..2e8a965 --- /dev/null +++ b/libfreerdp-kbd/layouts_xkb.c @@ -0,0 +1,418 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#ifdef WITH_XKBFILE +#include +#include +#include +#include +#endif + +#include "libkbd.h" +#include +#include "x_layout_id_table.h" + +#include "layouts_xkb.h" + +#ifndef KEYMAP_PATH +#define KEYMAP_PATH "/usr/local/freerdp/keymaps" +#endif + +#ifdef WITH_XKBFILE + +int init_xkb(void* dpy) +{ + return XkbQueryExtension(dpy, NULL, NULL, NULL, NULL, NULL); +} + +/* return substring starting after nth comma, ending at following comma */ +static char* comma_substring(char* s, int n) +{ + char *p; + + if (!s) + return ""; + + while (n-- > 0) + { + if (!(p = strchr(s, ','))) + break; + + s = p + 1; + } + + if ((p = strchr(s, ','))) + *p = 0; + + return s; +} + +unsigned int detect_keyboard_layout_from_xkb(void* dpy) +{ + char *layout, *variant; + unsigned int keyboard_layout = 0, group = 0; + XkbRF_VarDefsRec rules_names; + XKeyboardState coreKbdState; + XkbStateRec state; + + DEBUG_KBD("display: %p", dpy); + + if (dpy && XkbRF_GetNamesProp(dpy, NULL, &rules_names)) + { + DEBUG_KBD("layouts: %s", rules_names.layout ? rules_names.layout : ""); + DEBUG_KBD("variants: %s", rules_names.variant ? rules_names.variant : ""); + + XGetKeyboardControl(dpy, &coreKbdState); + + if (XkbGetState(dpy, XkbUseCoreKbd, &state) == Success) + group = state.group; + + DEBUG_KBD("group: %d", state.group); + + layout = comma_substring(rules_names.layout, group); + variant = comma_substring(rules_names.variant, group); + + DEBUG_KBD("layout: %s", layout ? layout : ""); + DEBUG_KBD("variant: %s", variant ? variant : ""); + + keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); + + free(rules_names.model); + free(rules_names.layout); + free(rules_names.variant); + free(rules_names.options); + } + + return keyboard_layout; +} + +int init_keycodes_from_xkb(void* dpy, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]) +{ + int ret = 0; + XkbDescPtr xkb; + + if (dpy && (xkb = XkbGetMap(dpy, 0, XkbUseCoreKbd))) + { + if (XkbGetNames(dpy, XkbKeyNamesMask, xkb) == Success) + { + int i, j; + char buf[5] = {42, 42, 42, 42, 0}; /* end-of-string at pos 5 */ + + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) + { + memcpy(buf, xkb->names->keys[i].name, 4); + + /* TODO: Use more efficient search ... but it is so fast that it doesn't matter */ + j = sizeof(virtualKeyboard) / sizeof(virtualKeyboard[0]) - 1; + + while (j >= 0) + { + if (virtualKeyboard[j].x_keyname && !strcmp(buf, virtualKeyboard[j].x_keyname)) + break; + j--; + } + + if (j >= 0) + { + DEBUG_KBD("X keycode %3d has keyname %-4s -> RDP scancode %d/%d", + i, buf, virtualKeyboard[j].extended, virtualKeyboard[j].scancode); + + x_keycode_to_rdp_scancode[i].extended = virtualKeyboard[j].extended; + x_keycode_to_rdp_scancode[i].keycode = virtualKeyboard[j].scancode; + x_keycode_to_rdp_scancode[i].keyname = virtualKeyboard[j].x_keyname; + + if (x_keycode_to_rdp_scancode[i].extended) + rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][1] = i; + else + rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][0] = i; + } + else + { + DEBUG_KBD("X key code %3d has keyname %-4s -> ??? - not found", i, buf); + } + } + ret = 1; + } + XkbFreeKeyboard(xkb, 0, 1); + } + return ret; +} + +#else + +/* Default built-in keymap */ +static const KeycodeToVkcode defaultKeycodeToVkcode = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x30, 0xBD, 0xBB, 0x08, 0x09, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, + 0x4F, 0x50, 0xDB, 0xDD, 0x0D, 0xA2, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0xBA, + 0xDE, 0xC0, 0xA0, 0x00, 0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0xBC, 0xBE, 0xBF, 0xA1, 0x6A, + 0x12, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x67, + 0x68, 0x69, 0x6D, 0x64, 0x65, 0x66, 0x6B, 0x61, 0x62, 0x63, 0x60, 0x6E, 0x00, 0x00, 0x00, 0x7A, + 0x7B, 0x24, 0x26, 0x21, 0x25, 0x00, 0x27, 0x23, 0x28, 0x22, 0x2D, 0x2E, 0x0D, 0xA3, 0x13, 0x2C, + 0x6F, 0x12, 0x00, 0x5B, 0x5C, 0x5D, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static int load_xkb_keyboard(KeycodeToVkcode map, char* kbd) +{ + char* pch; + char *beg, *end; + char* home; + char buffer[1024] = ""; + char xkbfile[256] = ""; + char xkbfilepath[512] = ""; + char xkbmap[256] = ""; + char xkbinc[256] = ""; + + FILE* fp; + int kbdFound = 0; + + int i = 0; + int keycode = 0; + char keycodeString[32] = ""; + char vkcodeName[128] = ""; + + beg = kbd; + + /* Extract file name and keymap name */ + if ((end = strrchr(kbd, '(')) != NULL) + { + strncpy(xkbfile, &kbd[beg - kbd], end - beg); + + beg = end + 1; + if ((end = strrchr(kbd, ')')) != NULL) + { + strncpy(xkbmap, &kbd[beg - kbd], end - beg); + xkbmap[end - beg] = '\0'; + } + } + else + { + /* The keyboard name is the same as the file name */ + strcpy(xkbfile, kbd); + strcpy(xkbmap, kbd); + } + + /* Get path to file relative to freerdp's directory */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "keymaps/%s", xkbfile); + DEBUG_KBD("Loading keymap %s, first trying %s", kbd, xkbfilepath); + + /* + * Open the file for reading only + * It can happen that the same file is opened twice at the same time + * in order to load multiple keyboard maps from the same file, but + * it does not matter: files can be opened as many times as we want + * when it is for reading only. + */ + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* Look first in path given at compile time (install path) */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "%s/%s", KEYMAP_PATH, xkbfile); + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* If ran from the root of the source tree */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "./keymaps/%s", xkbfile); + + /* If ran from the client directory */ + if((fp = fopen(xkbfilepath, "r")) == NULL) + snprintf(xkbfilepath, sizeof(xkbfilepath), "../../keymaps/%s", xkbfile); + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* File wasn't found in the source tree, try ~/.freerdp/ folder */ + if ((home = getenv("HOME")) == NULL) + return 0; + + /* Get path to file in ~/.freerdp/ folder */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "%s/.freerdp/keymaps/%s", home, xkbfile); + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* Try /usr/share/freerdp folder */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "/usr/share/freerdp/keymaps/%s", xkbfile); + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* Try /usr/local/share/freerdp folder */ + snprintf(xkbfilepath, sizeof(xkbfilepath), "/usr/local/share/freerdp/keymaps/%s", xkbfile); + + if ((fp = fopen(xkbfilepath, "r")) == NULL) + { + /* Error: Could not find keymap */ + DEBUG_KBD("keymaps for %s not found", xkbfile); + return 0; + } + } + } + } + } + } + + DEBUG_KBD("xkbfilepath: %s", xkbfilepath); + + while(fgets(buffer, sizeof(buffer), fp) != NULL) + { + if (buffer[0] == '#') + { + continue; /* Skip comments */ + } + + if (kbdFound) + { + /* Closing curly bracket and semicolon */ + if ((pch = strstr(buffer, "};")) != NULL) + { + break; + } + else if ((pch = strstr(buffer, "VK_")) != NULL) + { + /* The end is delimited by the first white space */ + end = strcspn(pch, " \t\n\0") + pch; + + /* We copy the virtual key code name in a string */ + beg = pch; + strncpy(vkcodeName, beg, end - beg); + vkcodeName[end - beg] = '\0'; + + /* Now we want to extract the virtual key code itself which is in between '<' and '>' */ + if ((beg = strchr(pch + 3, '<')) == NULL) + break; + else + beg++; + + if ((end = strchr(beg, '>')) == NULL) + break; + + /* We copy the string representing the number in a string */ + strncpy(keycodeString, beg, end - beg); + keycodeString[end - beg] = '\0'; + + /* Convert the string representing the code to an integer */ + keycode = atoi(keycodeString); + + /* Make sure it is a valid keycode */ + if (keycode < 0 || keycode > 255) + break; + + /* Load this key mapping in the keyboard mapping */ + for(i = 0; i < sizeof(virtualKeyboard) / sizeof(virtualKey); i++) + { + if (strcmp(vkcodeName, virtualKeyboard[i].name) == 0) + { + map[keycode] = i; + } + } + } + else if ((pch = strstr(buffer, ": extends")) != NULL) + { + /* + * This map extends another keymap We extract its name + * and we recursively load the keymap we need to include. + */ + + if ((beg = strchr(pch + sizeof(": extends"), '"')) == NULL) + break; + beg++; + + if ((end = strchr(beg, '"')) == NULL) + break; + + strncpy(xkbinc, beg, end - beg); + xkbinc[end - beg] = '\0'; + + load_xkb_keyboard(map, xkbinc); /* Load included keymap */ + } + } + else if ((pch = strstr(buffer, "keyboard")) != NULL) + { + /* Keyboard map identifier */ + if ((beg = strchr(pch + sizeof("keyboard"), '"')) == NULL) + break; + beg++; + + if ((end = strchr(beg, '"')) == NULL) + break; + + pch = beg; + buffer[end - beg] = '\0'; + + /* Does it match our keymap name? */ + if (strncmp(xkbmap, pch, strlen(xkbmap)) == 0) + kbdFound = 1; + } + } + + fclose(fp); /* Don't forget to close file */ + + return 1; +} + +void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile) +{ + char* kbd; + char* xkbfileEnd; + int keymapLoaded = 0; + + memset(keycodeToVkcode, 0, sizeof(keycodeToVkcode)); + + kbd = xkbfile; + xkbfileEnd = xkbfile + strlen(xkbfile); + +#ifdef __APPLE__ + /* Apple X11 breaks XKB detection */ + keymapLoaded += load_xkb_keyboard(keycodeToVkcode, "macosx(macosx)"); +#else + do + { + /* Multiple maps are separated by '+' */ + int kbdlen = strcspn(kbd + 1, "+") + 1; + kbd[kbdlen] = '\0'; + + /* Load keyboard map */ + keymapLoaded += load_xkb_keyboard(keycodeToVkcode, kbd); + + kbd += kbdlen + 1; + } + while (kbd < xkbfileEnd); +#endif + + DEBUG_KBD("loaded %d keymaps", keymapLoaded); + if (keymapLoaded <= 0) + { + /* No keymap was loaded, load default hard-coded keymap */ + DEBUG_KBD("using default keymap"); + memcpy(keycodeToVkcode, defaultKeycodeToVkcode, sizeof(keycodeToVkcode)); + } +} + +#endif diff --git a/libfreerdp-kbd/layouts_xkb.h b/libfreerdp-kbd/layouts_xkb.h new file mode 100644 index 0000000..dc0c769 --- /dev/null +++ b/libfreerdp-kbd/layouts_xkb.h @@ -0,0 +1,44 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAYOUTS_XKB_H +#define __LAYOUTS_XKB_H + +typedef unsigned char KeycodeToVkcode[256]; + +typedef struct +{ + unsigned char extended; + unsigned char keycode; + char* keyname; +} RdpKeycodeRec, RdpScancodes[256]; + +#ifdef WITH_XKBFILE + +int init_xkb(void *dpy); +unsigned int detect_keyboard_layout_from_xkb(void *dpy); +int init_keycodes_from_xkb(void* dpy, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]); + +#else + +void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile); + +#endif + +#endif diff --git a/libfreerdp-kbd/libkbd.c b/libfreerdp-kbd/libkbd.c new file mode 100644 index 0000000..156b30f --- /dev/null +++ b/libfreerdp-kbd/libkbd.c @@ -0,0 +1,168 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "libkbd.h" + +#include +#include +#include +#include "layouts_xkb.h" + +/* + * The actual mapping from X keycodes to RDP keycodes, initialized from xkb keycodes or similar. + * Used directly by freerdp_kbd_get_scancode_by_keycode. The mapping is a global variable, + * but it only depends on which keycodes the X servers keyboard driver uses and is thus very static. + */ + +RdpScancodes x_keycode_to_rdp_scancode; + +uint8 rdp_scancode_to_x_keycode[256][2]; + +#ifndef WITH_XKBFILE + +static unsigned int detect_keyboard(void* dpy, unsigned int keyboardLayoutID, char* xkbfile, size_t xkbfilelength) +{ + xkbfile[0] = '\0'; + + if (keyboardLayoutID != 0) + DEBUG_KBD("keyboard layout configuration: %X", keyboardLayoutID); + +#if defined(sun) + if (keyboardLayoutID == 0) + { + keyboardLayoutID = detect_keyboard_type_and_layout_sunos(xkbfile, xkbfilelength); + DEBUG_KBD("detect_keyboard_type_and_layout_sunos: %X %s", keyboardLayoutID, xkbfile); + } +#endif + + if (keyboardLayoutID == 0) + { + keyboardLayoutID = detect_keyboard_layout_from_locale(); + DEBUG_KBD("detect_keyboard_layout_from_locale: %X", keyboardLayoutID); + } + + if (keyboardLayoutID == 0) + { + keyboardLayoutID = 0x0409; + DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID); + } + + if (xkbfile[0] == '\0') + { + strncpy(xkbfile, "base", xkbfilelength); + DEBUG_KBD("using default keyboard layout: %s", xkbfile); + } + + return keyboardLayoutID; +} + +#endif + +/* + * Initialize global keyboard mapping and return the suggested server side layout. + * dpy must be a X Display* or NULL. + */ + +unsigned int freerdp_kbd_init(void* dpy, unsigned int keyboard_layout_id) +{ + memset(x_keycode_to_rdp_scancode, 0, sizeof(x_keycode_to_rdp_scancode)); + memset(rdp_scancode_to_x_keycode, '\0', sizeof(rdp_scancode_to_x_keycode)); + +#ifdef WITH_XKBFILE + if (!init_xkb(dpy)) + { + DEBUG_KBD("Error initializing xkb"); + return 0; + } + if (keyboard_layout_id == 0) + { + keyboard_layout_id = detect_keyboard_layout_from_xkb(dpy); + DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboard_layout_id); + } + init_keycodes_from_xkb(dpy, x_keycode_to_rdp_scancode, rdp_scancode_to_x_keycode); +#else + int vkcode; + int keycode; + char xkbfile[256]; + KeycodeToVkcode keycodeToVkcode; + + if (keyboard_layout_id == 0) + keyboard_layout_id = detect_keyboard(dpy, keyboard_layout_id, xkbfile, sizeof(xkbfile)); + + DEBUG_KBD("Using keyboard layout 0x%X with xkb name %s and xkbfile %s", + keyboard_layout_id, get_layout_name(keyboard_layout_id), xkbfile); + + load_keyboard_map(keycodeToVkcode, xkbfile); + + for (keycode = 0; keycode < 256; keycode++) + { + vkcode = keycodeToVkcode[keycode]; + + DEBUG_KBD("X keycode %3d VK %3d %-19s-> RDP scancode %d/%d", + keycode, vkcode, virtualKeyboard[vkcode].name, + virtualKeyboard[vkcode].extended, virtualKeyboard[vkcode].scancode); + + x_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode; + x_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended; + x_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name; + + if (x_keycode_to_rdp_scancode[keycode].extended) + rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][1] = keycode; + else + rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][0] = keycode; + } +#endif + + return keyboard_layout_id; +} + +rdpKeyboardLayout* freerdp_kbd_get_layouts(int types) +{ + return get_keyboard_layouts(types); +} + +uint8 freerdp_kbd_get_scancode_by_keycode(uint8 keycode, boolean* extended) +{ + DEBUG_KBD("%2x %4s -> %d/%d", keycode, x_keycode_to_rdp_scancode[keycode].keyname, + x_keycode_to_rdp_scancode[keycode].extended, x_keycode_to_rdp_scancode[keycode].keycode); + + *extended = x_keycode_to_rdp_scancode[keycode].extended; + + return x_keycode_to_rdp_scancode[keycode].keycode; +} + +uint8 freerdp_kbd_get_keycode_by_scancode(uint8 scancode, boolean extended) +{ + if (extended) + return rdp_scancode_to_x_keycode[scancode][1]; + else + return rdp_scancode_to_x_keycode[scancode][0]; +} + +uint8 freerdp_kbd_get_scancode_by_virtualkey(int vkcode, boolean* extended) +{ + *extended = virtualKeyboard[vkcode].extended; + return virtualKeyboard[vkcode].scancode; +} diff --git a/libfreerdp-kbd/libkbd.h b/libfreerdp-kbd/libkbd.h new file mode 100644 index 0000000..ffd561e --- /dev/null +++ b/libfreerdp-kbd/libkbd.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBKBD_H +#define __LIBKBD_H + +#include + +#ifdef WITH_DEBUG_KBD +#define DEBUG_KBD(fmt, ...) DEBUG_CLASS(KBD, fmt, ## __VA_ARGS__) +#else +#define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __LIBKBD_H */ diff --git a/libfreerdp-kbd/locales.c b/libfreerdp-kbd/locales.c new file mode 100644 index 0000000..653b990 --- /dev/null +++ b/libfreerdp-kbd/locales.c @@ -0,0 +1,510 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "libkbd.h" + +#include + +typedef struct +{ + /* Two or three letter language code */ + char language[4]; + + /* Two or three letter country code (Sometimes with Cyrl_ prefix) */ + char country[10]; + + /* 32-bit unsigned integer corresponding to the locale */ + unsigned int code; + +} locale; + +/* + * Refer to MSDN article "Locale Identifier Constants and Strings": + * http://msdn.microsoft.com/en-us/library/ms776260.aspx + */ + +static const locale locales[] = +{ + { "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */ + { "sq", "AL", ALBANIAN }, /* Albanian (Albania) */ + { "gsw", "FR", ALSATIAN }, /* Windows Vista and later: Alsatian (France) */ + { "am", "ET", AMHARIC }, /* Windows Vista and later: Amharic (Ethiopia) */ + { "ar", "DZ", ARABIC_ALGERIA }, /* Arabic (Algeria) */ + { "ar", "BH", ARABIC_BAHRAIN }, /* Arabic (Bahrain) */ + { "ar", "EG", ARABIC_EGYPT }, /* Arabic (Egypt) */ + { "ar", "IQ", ARABIC_IRAQ }, /* Arabic (Iraq) */ + { "ar", "JO", ARABIC_JORDAN }, /* Arabic (Jordan) */ + { "ar", "KW", ARABIC_KUWAIT }, /* Arabic (Kuwait) */ + { "ar", "LB", ARABIC_LEBANON }, /* Arabic (Lebanon) */ + { "ar", "LY", ARABIC_LIBYA }, /* Arabic (Libya) */ + { "ar", "MA", ARABIC_MOROCCO }, /* Arabic (Morocco) */ + { "ar", "OM", ARABIC_OMAN }, /* Arabic (Oman) */ + { "ar", "QA", ARABIC_QATAR }, /* Arabic (Qatar) */ + { "ar", "SA", ARABIC_SAUDI_ARABIA }, /* Arabic (Saudi Arabia) */ + { "ar", "SY", ARABIC_SYRIA }, /* Arabic (Syria) */ + { "ar", "TN", ARABIC_TUNISIA }, /* Arabic (Tunisia) */ + { "ar", "AE", ARABIC_UAE }, /* Arabic (U.A.E.) */ + { "ar", "YE", ARABIC_YEMEN }, /* Arabic (Yemen) */ + { "az", "AZ", AZERI_LATIN }, /* Azeri (Latin) */ + { "az", "Cyrl_AZ", AZERI_CYRILLIC }, /* Azeri (Cyrillic) */ + { "hy", "AM", ARMENIAN }, /* Windows 2000 and later: Armenian (Armenia) */ + { "as", "IN", ASSAMESE }, /* Windows Vista and later: Assamese (India) */ + { "ba", "RU", BASHKIR }, /* Windows Vista and later: Bashkir (Russia) */ + { "eu", "ES", BASQUE }, /* Basque (Basque) */ + { "be", "BY", BELARUSIAN }, /* Belarusian (Belarus) */ + { "bn", "IN", BENGALI_INDIA }, /* Windows XP SP2 and later: Bengali (India) */ + { "br", "FR", BRETON }, /* Breton (France) */ + { "bs", "BA", BOSNIAN_LATIN }, /* Bosnian (Latin) */ + { "bg", "BG", BULGARIAN }, /* Bulgarian (Bulgaria) */ + { "ca", "ES", CATALAN }, /* Catalan (Catalan) */ + { "zh", "HK", CHINESE_HONG_KONG }, /* Chinese (Hong Kong SAR, PRC) */ + { "zh", "MO", CHINESE_MACAU }, /* Windows 98/Me, Windows XP and later: Chinese (Macao SAR) */ + { "zh", "CN", CHINESE_PRC }, /* Chinese (PRC) */ + { "zh", "SG", CHINESE_SINGAPORE }, /* Chinese (Singapore) */ + { "zh", "TW", CHINESE_TAIWAN }, /* Chinese (Taiwan) */ + { "hr", "BA", CROATIAN_BOSNIA_HERZEGOVINA }, /* Windows XP SP2 and later: Croatian (Bosnia and Herzegovina, Latin) */ + { "hr", "HR", CROATIAN }, /* Croatian (Croatia) */ + { "cs", "CZ", CZECH }, /* Czech (Czech Republic) */ + { "da", "DK", DANISH }, /* Danish (Denmark) */ + { "prs", "AF", DARI }, /* Windows XP and later: Dari (Afghanistan) */ + { "dv", "MV", DIVEHI }, /* Windows XP and later: Divehi (Maldives) */ + { "nl", "BE", DUTCH_BELGIAN }, /* Dutch (Belgium) */ + { "nl", "NL", DUTCH_STANDARD }, /* Dutch (Netherlands) */ + { "en", "AU", ENGLISH_AUSTRALIAN }, /* English (Australia) */ + { "en", "BZ", ENGLISH_BELIZE }, /* English (Belize) */ + { "en", "CA", ENGLISH_CANADIAN }, /* English (Canada) */ + { "en", "CB", ENGLISH_CARIBBEAN }, /* English (Carribean) */ + { "en", "IN", ENGLISH_INDIA }, /* Windows Vista and later: English (India) */ + { "en", "IE", ENGLISH_IRELAND }, /* English (Ireland) */ + { "en", "JM", ENGLISH_JAMAICA }, /* English (Jamaica) */ + { "en", "MY", ENGLISH_MALAYSIA }, /* Windows Vista and later: English (Malaysia) */ + { "en", "NZ", ENGLISH_NEW_ZEALAND }, /* English (New Zealand) */ + { "en", "PH", ENGLISH_PHILIPPINES }, /* Windows 98/Me, Windows 2000 and later: English (Philippines) */ + { "en", "SG", ENGLISH_SINGAPORE }, /* Windows Vista and later: English (Singapore) */ + { "en", "ZA", ENGLISH_SOUTH_AFRICA }, /* English (South Africa) */ + { "en", "TT", ENGLISH_TRINIDAD }, /* English (Trinidad and Tobago) */ + { "en", "GB", ENGLISH_UNITED_KINGDOM }, /* English (United Kingdom) */ + { "en", "US", ENGLISH_UNITED_STATES }, /* English (United States) */ + { "en", "ZW", ENGLISH_ZIMBABWE }, /* Windows 98/Me, Windows 2000 and later: English (Zimbabwe) */ + { "et", "EE", ESTONIAN }, /* Estonian (Estonia) */ + { "fo", "FO", FAEROESE }, /* Faroese (Faroe Islands) */ + { "fil", "PH", FILIPINO }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Filipino (Philippines) */ + { "fi", "FI", FINNISH }, /* Finnish (Finland) */ + { "fr", "BE", FRENCH_BELGIAN }, /* French (Belgium) */ + { "fr", "CA", FRENCH_CANADIAN }, /* French (Canada) */ + { "fr", "FR", FRENCH_STANDARD }, /* French (France) */ + { "fr", "LU", FRENCH_LUXEMBOURG }, /* French (Luxembourg) */ + { "fr", "MC", FRENCH_MONACO }, /* French (Monaco) */ + { "fr", "CH", FRENCH_SWISS }, /* French (Switzerland) */ + { "fy", "NL", FRISIAN }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Frisian (Netherlands) */ + { "gl", "ES", GALICIAN }, /* Windows XP and later: Galician (Spain) */ + { "ka", "GE", GEORGIAN }, /* Windows 2000 and later: Georgian (Georgia) */ + { "de", "AT", GERMAN_AUSTRIAN }, /* German (Austria) */ + { "de", "DE", GERMAN_STANDARD }, /* German (Germany) */ + { "de", "LI", GERMAN_LIECHTENSTEIN }, /* German (Liechtenstein) */ + { "de", "LU", GERMAN_LUXEMBOURG }, /* German (Luxembourg) */ + { "de", "CH", GERMAN_SWISS }, /* German (Switzerland) */ + { "el", "GR", GREEK }, /* Greek (Greece) */ + { "kl", "GL", GREENLANDIC }, /* Windows Vista and later: Greenlandic (Greenland) */ + { "gu", "IN", GUJARATI }, /* Windows XP and later: Gujarati (India) */ + { "he", "IL", HEBREW }, /* Hebrew (Israel) */ + { "hi", "IN", HINDI }, /* Windows 2000 and later: Hindi (India) */ + { "hu", "HU", HUNGARIAN }, /* Hungarian (Hungary) */ + { "is", "IS", ICELANDIC }, /* Icelandic (Iceland) */ + { "ig", "NG", IGBO }, /* Igbo (Nigeria) */ + { "id", "ID", INDONESIAN }, /* Indonesian (Indonesia) */ + { "ga", "IE", IRISH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Irish (Ireland) */ + { "it", "IT", ITALIAN_STANDARD }, /* Italian (Italy) */ + { "it", "CH", ITALIAN_SWISS }, /* Italian (Switzerland) */ + { "ja", "JP", JAPANESE }, /* Japanese (Japan) */ + { "kn", "IN", KANNADA }, /* Windows XP and later: Kannada (India) */ + { "kk", "KZ", KAZAKH }, /* Windows 2000 and later: Kazakh (Kazakhstan) */ + { "kh", "KH", KHMER }, /* Windows Vista and later: Khmer (Cambodia) */ + { "qut", "GT", KICHE }, /* Windows Vista and later: K'iche (Guatemala) */ + { "rw", "RW", KINYARWANDA }, /* Windows Vista and later: Kinyarwanda (Rwanda) */ + { "kok", "IN", KONKANI }, /* Windows 2000 and later: Konkani (India) */ + { "ko", "KR", KOREAN }, /* Korean (Korea) */ + { "ky", "KG", KYRGYZ }, /* Windows XP and later: Kyrgyz (Kyrgyzstan) */ + { "lo", "LA", LAO }, /* Windows Vista and later: Lao (Lao PDR) */ + { "lv", "LV", LATVIAN }, /* Latvian (Latvia) */ + { "lt", "LT", LITHUANIAN }, /* Lithuanian (Lithuania) */ + { "dsb", "DE", LOWER_SORBIAN }, /* Windows Vista and later: Lower Sorbian (Germany) */ + { "lb", "LU", LUXEMBOURGISH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Luxembourgish (Luxembourg) */ + { "mk", "MK", MACEDONIAN }, /* Windows 2000 and later: Macedonian (Macedonia, FYROM) */ + { "ms", "BN", MALAY_BRUNEI_DARUSSALAM }, /* Windows 2000 and later: Malay (Brunei Darussalam) */ + { "ms", "MY", MALAY_MALAYSIA }, /* Windows 2000 and later: Malay (Malaysia) */ + { "ml", "IN", MALAYALAM }, /* Windows XP SP2 and later: Malayalam (India) */ + { "mt", "MT", MALTESE }, /* Windows XP SP2 and later: Maltese (Malta) */ + { "mi", "NZ", MAORI }, /* Windows XP SP2 and later: Maori (New Zealand) */ + { "arn", "CL", MAPUDUNGUN }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Mapudungun (Chile) */ + { "mr", "IN", MARATHI }, /* Windows 2000 and later: Marathi (India) */ + { "moh", "CA", MOHAWK }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Mohawk (Canada) */ + { "mn", "MN", MONGOLIAN }, /* Mongolian */ + { "ne", "NP", NEPALI }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Nepali (Nepal) */ + { "nb", "NO", NORWEGIAN_BOKMAL }, /* Norwegian (Bokmal, Norway) */ + { "nn", "NO", NORWEGIAN_NYNORSK }, /* Norwegian (Nynorsk, Norway) */ + { "oc", "FR", OCCITAN }, /* Occitan (France) */ + { "or", "IN", ORIYA }, /* Oriya (India) */ + { "ps", "AF", PASHTO }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Pashto (Afghanistan) */ + { "fa", "IR", FARSI }, /* Persian (Iran) */ + { "pl", "PL", POLISH }, /* Polish (Poland) */ + { "pt", "BR", PORTUGUESE_BRAZILIAN }, /* Portuguese (Brazil) */ + { "pt", "PT", PORTUGUESE_STANDARD }, /* Portuguese (Portugal) */ + { "pa", "IN", PUNJABI }, /* Windows XP and later: Punjabi (India) */ + { "quz", "BO", QUECHUA_BOLIVIA }, /* Windows XP SP2 and later: Quechua (Bolivia) */ + { "quz", "EC", QUECHUA_ECUADOR }, /* Windows XP SP2 and later: Quechua (Ecuador) */ + { "quz", "PE", QUECHUA_PERU }, /* Windows XP SP2 and later: Quechua (Peru) */ + { "ro", "RO", ROMANIAN }, /* Romanian (Romania) */ + { "rm", "CH", ROMANSH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Romansh (Switzerland) */ + { "ru", "RU", RUSSIAN }, /* Russian (Russia) */ + { "smn", "FI", SAMI_INARI }, /* Windows XP SP2 and later: Sami (Inari, Finland) */ + { "smj", "NO", SAMI_LULE_NORWAY }, /* Windows XP SP2 and later: Sami (Lule, Norway) */ + { "smj", "SE", SAMI_LULE_SWEDEN }, /* Windows XP SP2 and later: Sami (Lule, Sweden) */ + { "se", "FI", SAMI_NORTHERN_FINLAND }, /* Windows XP SP2 and later: Sami (Northern, Finland) */ + { "se", "NO", SAMI_NORTHERN_NORWAY }, /* Windows XP SP2 and later: Sami (Northern, Norway) */ + { "se", "SE", SAMI_NORTHERN_SWEDEN }, /* Windows XP SP2 and later: Sami (Northern, Sweden) */ + { "sms", "FI", SAMI_SKOLT }, /* Windows XP SP2 and later: Sami (Skolt, Finland) */ + { "sma", "NO", SAMI_SOUTHERN_NORWAY }, /* Windows XP SP2 and later: Sami (Southern, Norway) */ + { "sma", "SE", SAMI_SOUTHERN_SWEDEN }, /* Windows XP SP2 and later: Sami (Southern, Sweden) */ + { "sa", "IN", SANSKRIT }, /* Windows 2000 and later: Sanskrit (India) */ + { "sr", "SP", SERBIAN_LATIN }, /* Serbian (Latin) */ + { "sr", "SIH", SERBIAN_LATIN_BOSNIA_HERZEGOVINA }, /* Serbian (Latin) (Bosnia and Herzegovina) */ + { "sr", "Cyrl_SP", SERBIAN_CYRILLIC }, /* Serbian (Cyrillic) */ + { "sr", "Cyrl_SIH", SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA }, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ + { "ns", "ZA", SESOTHO_SA_LEBOA }, /* Windows XP SP2 and later: Sesotho sa Leboa/Northern Sotho (South Africa) */ + { "tn", "ZA", TSWANA }, /* Windows XP SP2 and later: Setswana/Tswana (South Africa) */ + { "si", "LK", SINHALA }, /* Windows Vista and later: Sinhala (Sri Lanka) */ + { "sk", "SK", SLOVAK }, /* Slovak (Slovakia) */ + { "sl", "SI", SLOVENIAN }, /* Slovenian (Slovenia) */ + { "es", "AR", SPANISH_ARGENTINA }, /* Spanish (Argentina) */ + { "es", "BO", SPANISH_BOLIVIA }, /* Spanish (Bolivia) */ + { "es", "CL", SPANISH_CHILE }, /* Spanish (Chile) */ + { "es", "CO", SPANISH_COLOMBIA }, /* Spanish (Colombia) */ + { "es", "CR", SPANISH_COSTA_RICA }, /* Spanish (Costa Rica) */ + { "es", "DO", SPANISH_DOMINICAN_REPUBLIC }, /* Spanish (Dominican Republic) */ + { "es", "EC", SPANISH_ECUADOR }, /* Spanish (Ecuador) */ + { "es", "SV", SPANISH_EL_SALVADOR }, /* Spanish (El Salvador) */ + { "es", "GT", SPANISH_GUATEMALA }, /* Spanish (Guatemala) */ + { "es", "HN", SPANISH_HONDURAS }, /* Spanish (Honduras) */ + { "es", "MX", SPANISH_MEXICAN }, /* Spanish (Mexico) */ + { "es", "NI", SPANISH_NICARAGUA }, /* Spanish (Nicaragua) */ + { "es", "PA", SPANISH_PANAMA }, /* Spanish (Panama) */ + { "es", "PY", SPANISH_PARAGUAY }, /* Spanish (Paraguay) */ + { "es", "PE", SPANISH_PERU }, /* Spanish (Peru) */ + { "es", "PR", SPANISH_PUERTO_RICO }, /* Spanish (Puerto Rico) */ + { "es", "ES", SPANISH_MODERN_SORT }, /* Spanish (Spain) */ + { "es", "ES", SPANISH_TRADITIONAL_SORT }, /* Spanish (Spain, Traditional Sort) */ + { "es", "US", SPANISH_UNITED_STATES }, /* Windows Vista and later: Spanish (United States) */ + { "es", "UY", SPANISH_URUGUAY }, /* Spanish (Uruguay) */ + { "es", "VE", SPANISH_VENEZUELA }, /* Spanish (Venezuela) */ + { "sw", "KE", SWAHILI }, /* Windows 2000 and later: Swahili (Kenya) */ + { "sv", "FI", SWEDISH_FINLAND }, /* Swedish (Finland) */ + { "sv", "SE", SWEDISH }, /* Swedish (Sweden) */ + { "syr", "SY", SYRIAC }, /* Windows XP and later: Syriac (Syria) */ + { "ta", "IN", TAMIL }, /* Windows 2000 and later: Tamil (India) */ + { "tt", "RU", TATAR }, /* Windows XP and later: Tatar (Russia) */ + { "te", "IN", TELUGU }, /* Windows XP and later: Telugu (India) */ + { "th", "TH", THAI }, /* Thai (Thailand) */ + { "bo", "BT", TIBETAN_BHUTAN }, /* Windows Vista and later: Tibetan (Bhutan) */ + { "bo", "CN", TIBETAN_PRC }, /* Windows Vista and later: Tibetan (PRC) */ + { "tr", "TR", TURKISH }, /* Turkish (Turkey) */ + { "tk", "TM", TURKMEN }, /* Windows Vista and later: Turkmen (Turkmenistan) */ + { "ug", "CN", UIGHUR }, /* Windows Vista and later: Uighur (PRC) */ + { "uk", "UA", UKRAINIAN }, /* Ukrainian (Ukraine) */ + { "wen", "DE", UPPER_SORBIAN }, /* Windows Vista and later: Upper Sorbian (Germany) */ + { "tr", "IN", URDU_INDIA }, /* Urdu (India) */ + { "ur", "PK", URDU }, /* Windows 98/Me, Windows 2000 and later: Urdu (Pakistan) */ + { "uz", "UZ", UZBEK_LATIN }, /* Uzbek (Latin) */ + { "uz", "Cyrl_UZ", UZBEK_CYRILLIC }, /* Uzbek (Cyrillic) */ + { "vi", "VN", VIETNAMESE }, /* Windows 98/Me, Windows NT 4.0 and later: Vietnamese (Vietnam) */ + { "cy", "GB", WELSH }, /* Windows XP SP2 and later: Welsh (United Kingdom) */ + { "wo", "SN", WOLOF }, /* Windows Vista and later: Wolof (Senegal) */ + { "xh", "ZA", XHOSA }, /* Windows XP SP2 and later: Xhosa/isiXhosa (South Africa) */ + { "sah", "RU", YAKUT }, /* Windows Vista and later: Yakut (Russia) */ + { "ii", "CN", YI }, /* Windows Vista and later: Yi (PRC) */ + { "yo", "NG", YORUBA }, /* Windows Vista and later: Yoruba (Nigeria) */ + { "zu", "ZA", ZULU } /* Windows XP SP2 and later: Zulu/isiZulu (South Africa) */ +}; + + +typedef struct +{ + /* Locale ID */ + unsigned int locale; + + /* Array of associated keyboard layouts */ + unsigned int keyboardLayouts[5]; + +} localeAndKeyboardLayout; + +/* TODO: Use KBD_* defines instead of hardcoded values */ + +static const localeAndKeyboardLayout defaultKeyboardLayouts[] = +{ + { AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, + { ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } }, + { ARABIC_SAUDI_ARABIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_IRAQ, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_EGYPT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_LIBYA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } }, + { ARABIC_ALGERIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } }, + { ARABIC_MOROCCO, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } }, + { ARABIC_TUNISIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } }, + { ARABIC_OMAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_YEMEN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_SYRIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_JORDAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_LEBANON, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_KUWAIT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_UAE, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_BAHRAIN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARABIC_QATAR, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } }, + { ARMENIAN, { 0x0000042b, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { AZERI_LATIN, { 0x0000042c, 0x0000082c, 0x00000419, 0x0, 0x0 } }, + { AZERI_CYRILLIC, { 0x0000082c, 0x0000042c, 0x00000419, 0x0, 0x0 } }, + { BASQUE, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } }, + { BELARUSIAN, { 0x00000423, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { BENGALI_INDIA, { 0x00000445, 0x00000409, 0x0, 0x0, 0x0 } }, + { BOSNIAN_LATIN, { 0x0000141A, 0x00000409, 0x0, 0x0, 0x0 } }, + { BULGARIAN, { 0x00000402, 0x00000409, 0x0, 0x0, 0x0 } }, + { CATALAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } }, + { CHINESE_TAIWAN, { 0x00000404, 0xe0080404, 0xE0010404, 0x0, 0x0 } }, + { CHINESE_PRC, { 0x00000804, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } }, + { CHINESE_HONG_KONG, { 0x00000409, 0xe0080404, 0x0, 0x0, 0x0 } }, + { CHINESE_SINGAPORE, { 0x00000409, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } }, + { CHINESE_MACAU, { 0x00000409, 0xe00e0804, 0xe0020404, 0xe0080404 } }, + { CROATIAN, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } }, + { CROATIAN_BOSNIA_HERZEGOVINA, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } }, + { CZECH, { 0x00000405, 0x00000409, 0x0, 0x0, 0x0 } }, + { DANISH, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } }, + { DIVEHI, { 0x00000409, 0x00000465, 0x0, 0x0, 0x0 } }, + { DUTCH_STANDARD, { 0x00020409, 0x00000413, 0x00000409, 0x0, 0x0 } }, + { DUTCH_BELGIAN, { 0x00000813, 0x00000409, 0x0, 0x0, 0x0 } }, + { ENGLISH_UNITED_STATES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_UNITED_KINGDOM, { 0x00000809, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_AUSTRALIAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_CANADIAN, { 0x00000409, 0x00011009, 0x00001009, 0x0, 0x0 } }, + { ENGLISH_NEW_ZEALAND, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_IRELAND, { 0x00001809, 0x00011809, 0x0, 0x0, 0x0 } }, + { ENGLISH_SOUTH_AFRICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_JAMAICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_CARIBBEAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_BELIZE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_TRINIDAD, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_ZIMBABWE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ENGLISH_PHILIPPINES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { ESTONIAN, { 0x00000425, 0x0, 0x0, 0x0, 0x0 } }, + { FAEROESE, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } }, + { FARSI, { 0x00000409, 0x00000429, 0x00000401, 0x0, 0x0 } }, + { FINNISH, { 0x0000040b, 0x00000409, 0x0, 0x0, 0x0 } }, + { FRENCH_STANDARD, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } }, + { FRENCH_BELGIAN, { 0x0000080c, 0x00000409, 0x0, 0x0, 0x0 } }, + { FRENCH_CANADIAN, { 0x00000C0C, 0x00011009, 0x00000409, 0x0, 0x0 } }, + { FRENCH_SWISS, { 0x0000100c, 0x00000409, 0x0, 0x0, 0x0 } }, + { FRENCH_LUXEMBOURG, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } }, + { FRENCH_MONACO, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } }, + { GEORGIAN, { 0x00000437, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { GALICIAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } }, + { GERMAN_STANDARD, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } }, + { GERMAN_SWISS, { 0x00000807, 0x00000409, 0x0, 0x0, 0x0 } }, + { GERMAN_AUSTRIAN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } }, + { GERMAN_LUXEMBOURG, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } }, + { GERMAN_LIECHTENSTEIN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } }, + { GREEK, { 0x00000408, 0x00000409, 0x0, 0x0, 0x0 } }, + { GUJARATI, { 0x00000409, 0x00000447, 0x00010439, 0x0, 0x0 } }, + { HEBREW, { 0x00000409, 0x0000040d, 0x0, 0x0, 0x0 } }, + { HINDI, { 0x00000409, 0x00010439, 0x00000439, 0x0, 0x0 } }, + { HUNGARIAN, { 0x0000040e, 0x00000409, 0x0, 0x0, 0x0 } }, + { ICELANDIC, { 0x0000040f, 0x00000409, 0x0, 0x0, 0x0 } }, + { INDONESIAN, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, + { ITALIAN_STANDARD, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } }, + { ITALIAN_SWISS, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } }, + { JAPANESE, { 0xe0010411, 0x0, 0x0, 0x0, 0x0 } }, + { KANNADA, { 0x00000409, 0x0000044b, 0x00010439, 0x0, 0x0 } }, + { KAZAKH, { 0x0000043f, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { KONKANI, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } }, + { KOREAN, { 0xE0010412, 0x0, 0x0, 0x0, 0x0 } }, + { KYRGYZ, { 0x00000440, 0x00000409, 0x0, 0x0, 0x0 } }, + { LATVIAN, { 0x00010426, 0x0, 0x0, 0x0, 0x0 } }, + { LITHUANIAN, { 0x00010427, 0x0, 0x0, 0x0, 0x0 } }, + { MACEDONIAN, { 0x0000042f, 0x00000409, 0x0, 0x0, 0x0 } }, + { MALAY_MALAYSIA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { MALAY_BRUNEI_DARUSSALAM, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { MALAYALAM, { 0x00000409, 0x0000044c, 0x0, 0x0, 0x0 } }, + { MALTESE, { 0x00000409, 0x0000043a, 0x0, 0x0, 0x0 } }, + { MAORI, { 0x00000409, 0x00000481, 0x0, 0x0, 0x0 } }, + { MARATHI, { 0x00000409, 0x0000044e, 0x00000439, 0x0, 0x0 } }, + { MONGOLIAN, { 0x00000450, 0x00000409, 0x0, 0x0, 0x0 } }, + { NORWEGIAN_BOKMAL, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } }, + { NORWEGIAN_NYNORSK, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } }, + { POLISH, { 0x00010415, 0x00000415, 0x00000409, 0x0, 0x0 } }, + { PORTUGUESE_BRAZILIAN, { 0x00000416, 0x00000409, 0x0, 0x0, 0x0 } }, + { PORTUGUESE_STANDARD, { 0x00000816, 0x00000409, 0x0, 0x0, 0x0 } }, + { PUNJABI, { 0x00000409, 0x00000446, 0x00010439, 0x0, 0x0 } }, + { QUECHUA_BOLIVIA, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } }, + { QUECHUA_ECUADOR, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } }, + { QUECHUA_PERU, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } }, + { ROMANIAN, { 0x00000418, 0x00000409, 0x0, 0x0, 0x0 } }, + { RUSSIAN, { 0x00000419, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_INARI, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_LULE_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_LULE_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_NORTHERN_FINLAND, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_NORTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_NORTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_SKOLT, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_SOUTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SAMI_SOUTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SANSKRIT, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } }, + { SERBIAN_LATIN, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SERBIAN_LATIN_BOSNIA_HERZEGOVINA, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SERBIAN_CYRILLIC, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SLOVAK, { 0x0000041b, 0x00000409, 0x0, 0x0, 0x0 } }, + { SLOVENIAN, { 0x00000424, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_TRADITIONAL_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_MEXICAN, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_MODERN_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_GUATEMALA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_COSTA_RICA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_PANAMA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_DOMINICAN_REPUBLIC, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_VENEZUELA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_COLOMBIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_PERU, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_ARGENTINA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_ECUADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_CHILE, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_URUGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_PARAGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_BOLIVIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_EL_SALVADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_HONDURAS, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_NICARAGUA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SPANISH_PUERTO_RICO, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } }, + { SWAHILI, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } }, + { SWEDISH, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } }, + { SWEDISH_FINLAND, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } }, + { SYRIAC, { 0x00000409, 0x0000045a, 0x0, 0x0, 0x0 } }, + { TAMIL, { 0x00000409, 0x00000449, 0x0, 0x0, 0x0 } }, + { TATAR, { 0x00000444, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { TELUGU, { 0x00000409, 0x0000044a, 0x00010439, 0x0, 0x0 } }, + { THAI, { 0x00000409, 0x0000041e, 0x0, 0x0, 0x0 } }, + { TSWANA, { 0x00000409, 0x0000041f, 0x0, 0x0, 0x0 } }, + { UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } }, + { TURKISH, { 0x0000041f, 0x0000041f, 0x0, 0x0, 0x0 } }, + { UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } }, + { URDU, { 0x00000401, 0x00000409, 0x0, 0x0, 0x0 } }, + { UZBEK_LATIN, { 0x00000409, 0x00000843, 0x00000419, 0x0, 0x0 } }, + { UZBEK_CYRILLIC, { 0x00000843, 0x00000409, 0x00000419, 0x0, 0x0 } }, + { VIETNAMESE, { 0x00000409, 0x0000042a, 0x0, 0x0, 0x0 } }, + { WELSH, { 0x00000452, 0x00000809, 0x0, 0x0, 0x0 } }, + { XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, +}; + +unsigned int detect_keyboard_layout_from_locale() +{ + int dot; + int i, j, k; + int underscore; + char language[4]; + char country[10]; + + /* LANG = _. */ + char* envLang = getenv("LANG"); /* Get locale from environment variable LANG */ + + if (envLang == NULL) + return 0; /* LANG environment variable was not set */ + + underscore = strcspn(envLang, "_"); + + if (underscore > 3) + return 0; /* The language name should not be more than 3 letters long */ + else + { + /* Get language code */ + strncpy(language, envLang, underscore); + language[underscore] = '\0'; + } + + /* + * There is always the special case of "C" or "POSIX" as locale name + * In this case, use a U.S. keyboard and a U.S. keyboard layout + */ + + if ((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0)) + return ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */ + + dot = strcspn(envLang, "."); + + /* Get country code */ + if (dot > underscore) + { + strncpy(country, &envLang[underscore + 1], dot - underscore - 1); + country[dot - underscore - 1] = '\0'; + } + else + return 0; /* Invalid locale */ + + for (i = 0; i < sizeof(locales) / sizeof(locale); i++) + { + if ((strcmp(language, locales[i].language) == 0) && (strcmp(country, locales[i].country) == 0)) + break; + } + + DEBUG_KBD("Found locale : %s_%s", locales[i].language, locales[i].country); + + for (j = 0; j < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); j++) + { + if (defaultKeyboardLayouts[j].locale == locales[i].code) + { + /* Locale found in list of default keyboard layouts */ + for (k = 0; k < 5; k++) + { + if (defaultKeyboardLayouts[j].keyboardLayouts[k] == ENGLISH_UNITED_STATES) + { + continue; /* Skip, try to get a more localized keyboard layout */ + } + else if (defaultKeyboardLayouts[j].keyboardLayouts[k] == 0) + { + break; /* No more keyboard layouts */ + } + else + { + return defaultKeyboardLayouts[j].keyboardLayouts[k]; + } + } + + /* + * If we skip the ENGLISH_UNITED_STATES keyboard layout but there are no + * other possible keyboard layout for the locale, we end up here with k > 1 + */ + + if (k >= 1) + return ENGLISH_UNITED_STATES; + else + return 0; + } + } + + return 0; /* Could not detect the current keyboard layout from locale */ +} diff --git a/libfreerdp-kbd/x_layout_id_table.c b/libfreerdp-kbd/x_layout_id_table.c new file mode 100644 index 0000000..42ee135 --- /dev/null +++ b/libfreerdp-kbd/x_layout_id_table.c @@ -0,0 +1,1172 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "libkbd.h" +#include + +#include "x_layout_id_table.h" + +typedef struct +{ + /* XKB Keyboard layout variant */ + const char* variant; + + /* Keyboard Layout ID */ + unsigned int keyboardLayoutID; + +} xkbVariant; + +typedef struct +{ + /* XKB Keyboard layout */ + const char* layout; + + /* Keyboard Layout ID */ + unsigned int keyboardLayoutID; + + const xkbVariant* variants; + +} xkbLayout; + +/* Those have been generated automatically and are waiting to be filled by hand */ + +/* USA */ +static const xkbVariant us_variants[] = +{ + { "chr", 0 }, /* Cherokee */ + { "euro", 0 }, /* With EuroSign on 5 */ + { "intl", KBD_UNITED_STATES_INTERNATIONAL }, /* International (with dead keys) */ + { "alt-intl", KBD_UNITED_STATES_INTERNATIONAL }, /* Alternative international (former us_intl) */ + { "colemak", 0 }, /* Colemak */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "dvorak-intl", KBD_UNITED_STATES_DVORAK }, /* Dvorak international */ + { "dvorak-l", KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND }, /* Left handed Dvorak */ + { "dvorak-r", KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND }, /* Right handed Dvorak */ + { "dvorak-classic", KBD_UNITED_STATES_DVORAK }, /* Classic Dvorak */ + { "dvp", KBD_UNITED_STATES_DVORAK }, /* Programmer Dvorak */ + { "rus", 0 }, /* Russian phonetic */ + { "mac", KBD_US }, /* Macintosh */ + { "altgr-intl", KBD_UNITED_STATES_INTERNATIONAL }, /* International (AltGr dead keys) */ + { "olpc2", KBD_US }, /* Group toggle on multiply/divide key */ + { "", 0 }, +}; + +/* Afghanistan */ +static const xkbVariant af_variants[] = +{ + { "ps", KBD_PASHTO }, /* Pashto */ + { "uz", KBD_UZBEK_CYRILLIC }, /* Southern Uzbek */ + { "olpc-ps", KBD_PASHTO }, /* OLPC Pashto */ + { "olpc-fa", 0 }, /* OLPC Dari */ + { "olpc-uz", KBD_UZBEK_CYRILLIC }, /* OLPC Southern Uzbek */ + { "", 0 }, +}; + +/* Arabic */ +static const xkbVariant ara_variants[] = +{ + { "azerty", KBD_ARABIC_102_AZERTY }, /* azerty */ + { "azerty_digits", KBD_ARABIC_102_AZERTY }, /* azerty/digits */ + { "digits", KBD_ARABIC_102_AZERTY }, /* digits */ + { "qwerty", KBD_ARABIC_101 }, /* qwerty */ + { "qwerty_digits", KBD_ARABIC_101 }, /* qwerty/digits */ + { "buckwalter", KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L }, /* Buckwalter */ + { "", 0 }, +}; + +/* Armenia */ +static const xkbVariant am_variants[] = +{ + { "phonetic", 0 }, /* Phonetic */ + { "phonetic-alt", 0 }, /* Alternative Phonetic */ + { "eastern", KBD_ARMENIAN_EASTERN }, /* Eastern */ + { "western", KBD_ARMENIAN_WESTERN }, /* Western */ + { "eastern-alt", KBD_ARMENIAN_EASTERN }, /* Alternative Eastern */ + { "", 0 }, +}; + +/* Azerbaijan */ +static const xkbVariant az_variants[] = +{ + { "cyrillic", KBD_AZERI_CYRILLIC }, /* Cyrillic */ + { "", 0 }, +}; + +/* Belarus */ +static const xkbVariant by_variants[] = +{ + { "winkeys", KBD_BELARUSIAN }, /* Winkeys */ + { "latin", KBD_BELARUSIAN }, /* Latin */ + { "", 0 }, +}; + +/* Belgium */ +static const xkbVariant be_variants[] = +{ + { "oss", KBD_BELGIAN_FRENCH }, /* Alternative */ + { "oss_latin9", KBD_BELGIAN_FRENCH }, /* Alternative, latin-9 only */ + { "oss_sundeadkeys", KBD_BELGIAN_PERIOD }, /* Alternative, Sun dead keys */ + { "iso-alternate", KBD_BELGIAN_COMMA }, /* ISO Alternate */ + { "nodeadkeys", KBD_BELGIAN_COMMA }, /* Eliminate dead keys */ + { "sundeadkeys", KBD_BELGIAN_PERIOD }, /* Sun dead keys */ + { "wang", KBD_BELGIAN_FRENCH }, /* Wang model 724 azerty */ + { "", 0 }, +}; + +/* Bangladesh */ +static const xkbVariant bd_variants[] = +{ + { "probhat", KBD_BENGALI_INSCRIPT }, /* Probhat */ + { "", 0 }, +}; + +/* India */ +static const xkbVariant in_variants[] = +{ + { "ben", KBD_BENGALI }, /* Bengali */ + { "ben_probhat", KBD_BENGALI_INSCRIPT }, /* Bengali Probhat */ + { "guj", KBD_GUJARATI }, /* Gujarati */ + { "guru", 0 }, /* Gurmukhi */ + { "jhelum", 0 }, /* Gurmukhi Jhelum */ + { "kan", KBD_KANNADA }, /* Kannada */ + { "mal", KBD_MALAYALAM }, /* Malayalam */ + { "mal_lalitha", KBD_MALAYALAM }, /* Malayalam Lalitha */ + { "ori", 0 }, /* Oriya */ + { "tam_unicode", KBD_TAMIL }, /* Tamil Unicode */ + { "tam_TAB", KBD_TAMIL }, /* Tamil TAB Typewriter */ + { "tam_TSCII", KBD_TAMIL }, /* Tamil TSCII Typewriter */ + { "tam", KBD_TAMIL }, /* Tamil */ + { "tel", KBD_TELUGU }, /* Telugu */ + { "urd-phonetic", KBD_URDU }, /* Urdu, Phonetic */ + { "urd-phonetic3", KBD_URDU }, /* Urdu, Alternative phonetic */ + { "urd-winkeys", KBD_URDU }, /* Urdu, Winkeys */ + { "bolnagri", KBD_HINDI_TRADITIONAL }, /* Hindi Bolnagri */ + { "hin-wx", KBD_HINDI_TRADITIONAL }, /* Hindi Wx */ + { "", 0 }, +}; + +/* Bosnia and Herzegovina */ +static const xkbVariant ba_variants[] = +{ + { "alternatequotes", KBD_BOSNIAN }, /* Use guillemets for quotes */ + { "unicode", KBD_BOSNIAN }, /* Use Bosnian digraphs */ + { "unicodeus", KBD_BOSNIAN }, /* US keyboard with Bosnian digraphs */ + { "us", KBD_BOSNIAN_CYRILLIC }, /* US keyboard with Bosnian letters */ + { "", 0 }, +}; + +/* Brazil */ +static const xkbVariant br_variants[] = +{ + { "nodeadkeys", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "nativo", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo */ + { "nativo-us", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for USA keyboards */ + { "nativo-epo", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for Esperanto */ + { "", 0 }, +}; + +/* Bulgaria */ +static const xkbVariant bg_variants[] = +{ + { "phonetic", KBD_BULGARIAN_LATIN }, /* Traditional Phonetic */ + { "bas_phonetic", KBD_BULGARIAN_LATIN }, /* Standard Phonetic */ + { "", 0 }, +}; + +/* Morocco */ +static const xkbVariant ma_variants[] = +{ + { "french", KBD_FRENCH }, /* French */ + { "tifinagh", 0 }, /* Tifinagh */ + { "tifinagh-alt", 0 }, /* Tifinagh Alternative */ + { "tifinagh-alt-phonetic", 0 }, /* Tifinagh Alternative Phonetic */ + { "tifinagh-extended", 0 }, /* Tifinagh Extended */ + { "tifinagh-phonetic", 0 }, /* Tifinagh Phonetic */ + { "tifinagh-extended-phonetic", 0 }, /* Tifinagh Extended Phonetic */ + { "", 0 }, +}; + +/* Canada */ +static const xkbVariant ca_variants[] = +{ + { "fr-dvorak", KBD_UNITED_STATES_DVORAK }, /* French Dvorak */ + { "fr-legacy", KBD_CANADIAN_FRENCH }, /* French (legacy) */ + { "multix", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual */ + { "multi", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, first part */ + { "multi-2gr", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, second part */ + { "ike", KBD_INUKTITUT_LATIN }, /* Inuktitut */ + { "shs", 0 }, /* Secwepemctsin */ + { "kut", 0 }, /* Ktunaxa */ + { "eng", KBD_US }, /* English */ + { "", 0 }, +}; + +/* China */ +static const xkbVariant cn_variants[] = +{ + { "tib", 0 }, /* Tibetan */ + { "tib_asciinum", 0 }, /* Tibetan (with ASCII numerals) */ + { "", 0 }, +}; + +/* Croatia */ +static const xkbVariant hr_variants[] = +{ + { "alternatequotes", KBD_CROATIAN }, /* Use guillemets for quotes */ + { "unicode", KBD_CROATIAN }, /* Use Croatian digraphs */ + { "unicodeus", KBD_CROATIAN }, /* US keyboard with Croatian digraphs */ + { "us", KBD_CROATIAN }, /* US keyboard with Croatian letters */ + { "", 0 }, +}; + +/* Czechia */ +static const xkbVariant cz_variants[] = +{ + { "bksl", KBD_CZECH_PROGRAMMERS }, /* With <\|> key */ + { "qwerty", KBD_CZECH_QWERTY }, /* qwerty */ + { "qwerty_bksl", KBD_CZECH_QWERTY }, /* qwerty, extended Backslash */ + { "ucw", KBD_CZECH }, /* UCW layout (accented letters only) */ + { "", 0 }, +}; + +/* Denmark */ +static const xkbVariant dk_variants[] = +{ + { "nodeadkeys", KBD_DANISH }, /* Eliminate dead keys */ + { "mac", KBD_DANISH }, /* Macintosh */ + { "mac_nodeadkeys", KBD_DANISH }, /* Macintosh, eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "", 0 }, +}; + +/* Netherlands */ +static const xkbVariant nl_variants[] = +{ + { "sundeadkeys", KBD_SWISS_FRENCH }, /* Sun dead keys */ + { "mac", KBD_SWISS_FRENCH }, /* Macintosh */ + { "std", KBD_SWISS_FRENCH }, /* Standard */ + { "", 0 }, +}; + +/* Estonia */ +static const xkbVariant ee_variants[] = +{ + { "nodeadkeys", KBD_US }, /* Eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "us", KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Estonian letters */ + { "", 0 }, +}; + +/* Iran */ +static const xkbVariant ir_variants[] = +{ + { "pro", 0 }, /* Pro */ + { "keypad", 0 }, /* Keypad */ + { "pro_keypad", 0 }, /* Pro Keypad */ + { "ku", 0 }, /* Kurdish, Latin Q */ + { "ku_f", 0 }, /* Kurdish, (F) */ + { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */ + { "ku_ara", 0 }, /* Kurdish, Arabic-Latin */ + { "", 0 }, +}; + +/* Iraq */ +static const xkbVariant iq_variants[] = +{ + { "ku", 0 }, /* Kurdish, Latin Q */ + { "ku_f", 0 }, /* Kurdish, (F) */ + { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */ + { "ku_ara", 0 }, /* Kurdish, Arabic-Latin */ + { "", 0 }, +}; + +/* Faroe Islands */ +static const xkbVariant fo_variants[] = +{ + { "nodeadkeys", 0 }, /* Eliminate dead keys */ + { "", 0 }, +}; + +/* Finland */ +static const xkbVariant fi_variants[] = +{ + { "nodeadkeys", 0 }, /* Eliminate dead keys */ + { "smi", 0 }, /* Northern Saami */ + { "classic", 0 }, /* Classic */ + { "mac", 0 }, /* Macintosh */ + { "", 0 }, +}; + +/* France */ +static const xkbVariant fr_variants[] = +{ + { "nodeadkeys", 0 }, /* Eliminate dead keys */ + { "sundeadkeys", 0 }, /* Sun dead keys */ + { "oss", 0 }, /* Alternative */ + { "oss_latin9", 0 }, /* Alternative, latin-9 only */ + { "oss_nodeadkeys", 0 }, /* Alternative, eliminate dead keys */ + { "oss_sundeadkeys", 0 }, /* Alternative, Sun dead keys */ + { "latin9", 0 }, /* (Legacy) Alternative */ + { "latin9_nodeadkeys", 0 }, /* (Legacy) Alternative, eliminate dead keys */ + { "latin9_sundeadkeys", 0 }, /* (Legacy) Alternative, Sun dead keys */ + { "bepo", 0 }, /* Bepo, ergonomic, Dvorak way */ + { "bepo_latin9", 0 }, /* Bepo, ergonomic, Dvorak way, latin-9 only */ + { "dvorak", 0 }, /* Dvorak */ + { "mac", 0 }, /* Macintosh */ + { "bre", 0 }, /* Breton */ + { "oci", 0 }, /* Occitan */ + { "geo", 0 }, /* Georgian AZERTY Tskapo */ + { "", 0 }, +}; + +/* Ghana */ +static const xkbVariant gh_variants[] = +{ + { "generic", 0 }, /* Multilingual */ + { "akan", 0 }, /* Akan */ + { "ewe", 0 }, /* Ewe */ + { "fula", 0 }, /* Fula */ + { "ga", 0 }, /* Ga */ + { "hausa", 0 }, /* Hausa */ + { "", 0 }, +}; + +/* Georgia */ +static const xkbVariant ge_variants[] = +{ + { "ergonomic", 0 }, /* Ergonomic */ + { "mess", 0 }, /* MESS */ + { "ru", 0 }, /* Russian */ + { "os", 0 }, /* Ossetian */ + { "", 0 }, +}; + +/* Germany */ +static const xkbVariant de_variants[] = +{ + { "deadacute", KBD_GERMAN }, /* Dead acute */ + { "deadgraveacute", KBD_GERMAN }, /* Dead grave acute */ + { "nodeadkeys", KBD_GERMAN }, /* Eliminate dead keys */ + { "ro", KBD_GERMAN }, /* Romanian keyboard with German letters */ + { "ro_nodeadkeys", KBD_GERMAN }, /* Romanian keyboard with German letters, eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "sundeadkeys", KBD_GERMAN }, /* Sun dead keys */ + { "neo", KBD_GERMAN_NEO }, /* Neo 2 */ + { "mac", KBD_GERMAN }, /* Macintosh */ + { "mac_nodeadkeys", KBD_GERMAN }, /* Macintosh, eliminate dead keys */ + { "dsb", KBD_GERMAN }, /* Lower Sorbian */ + { "dsb_qwertz", KBD_GERMAN }, /* Lower Sorbian (qwertz) */ + { "qwerty", KBD_GERMAN_IBM }, /* qwerty */ + { "", 0 }, +}; + +/* Greece */ +static const xkbVariant gr_variants[] = +{ + { "simple", KBD_GREEK_220 }, /* Simple */ + { "extended", KBD_GREEK_319 }, /* Extended */ + { "nodeadkeys", KBD_GREEK_319}, /* Eliminate dead keys */ + { "polytonic", KBD_GREEK_POLYTONIC }, /* Polytonic */ + { "", 0 }, +}; + +/* Hungary */ +static const xkbVariant hu_variants[] = +{ + { "standard", KBD_HUNGARIAN_101_KEY }, /* Standard */ + { "nodeadkeys", KBD_HUNGARIAN_101_KEY }, /* Eliminate dead keys */ + { "qwerty", KBD_HUNGARIAN_101_KEY }, /* qwerty */ + { "101_qwertz_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Dead keys */ + { "101_qwertz_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Eliminate dead keys */ + { "101_qwertz_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Dead keys */ + { "101_qwertz_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Eliminate dead keys */ + { "101_qwerty_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Dead keys */ + { "101_qwerty_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Eliminate dead keys */ + { "101_qwerty_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Dead keys */ + { "101_qwerty_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Eliminate dead keys */ + { "102_qwertz_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Dead keys */ + { "102_qwertz_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Eliminate dead keys */ + { "102_qwertz_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Dead keys */ + { "102_qwertz_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Eliminate dead keys */ + { "102_qwerty_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Dead keys */ + { "102_qwerty_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Eliminate dead keys */ + { "102_qwerty_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Dead keys */ + { "102_qwerty_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Eliminate dead keys */ + { "", 0 }, +}; + +/* Iceland */ +static const xkbVariant is_variants[] = +{ + { "Sundeadkeys", KBD_ICELANDIC }, /* Sun dead keys */ + { "nodeadkeys", KBD_ICELANDIC }, /* Eliminate dead keys */ + { "mac", KBD_ICELANDIC }, /* Macintosh */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "", 0 }, +}; + +/* Israel */ +static const xkbVariant il_variants[] = +{ + { "lyx", KBD_HEBREW }, /* lyx */ + { "phonetic", KBD_HEBREW }, /* Phonetic */ + { "biblical", KBD_HEBREW }, /* Biblical Hebrew (Tiro) */ + { "", 0 }, +}; + +/* Italy */ +static const xkbVariant it_variants[] = +{ + { "nodeadkeys", KBD_ITALIAN_142 }, /* Eliminate dead keys */ + { "mac", KBD_ITALIAN }, /* Macintosh */ + { "geo", KBD_GEORGIAN }, /* Georgian */ + { "", 0 }, +}; + +/* Japan */ +static const xkbVariant jp_variants[] = +{ + { "kana", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Kana */ + { "OADG109A", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* OADG 109A */ + { "", 0 }, +}; + +/* Kyrgyzstan */ +static const xkbVariant kg_variants[] = +{ + { "phonetic", KBD_KYRGYZ_CYRILLIC }, /* Phonetic */ + { "", 0 }, +}; + +/* Kazakhstan */ +static const xkbVariant kz_variants[] = +{ + { "ruskaz", KBD_KAZAKH }, /* Russian with Kazakh */ + { "kazrus", KBD_KAZAKH }, /* Kazakh with Russian */ + { "", 0 }, +}; + +/* Latin America */ +static const xkbVariant latam_variants[] = +{ + { "nodeadkeys", KBD_LATIN_AMERICAN }, /* Eliminate dead keys */ + { "deadtilde", KBD_LATIN_AMERICAN }, /* Include dead tilde */ + { "sundeadkeys", KBD_LATIN_AMERICAN }, /* Sun dead keys */ + { "", 0 }, +}; + +/* Lithuania */ +static const xkbVariant lt_variants[] = +{ + { "std", KBD_LITHUANIAN }, /* Standard */ + { "us", KBD_LITHUANIAN_IBM }, /* US keyboard with Lithuanian letters */ + { "ibm", KBD_LITHUANIAN_IBM }, /* IBM (LST 1205-92) */ + { "lekp", KBD_LITHUANIAN }, /* LEKP */ + { "lekpa", KBD_LITHUANIAN }, /* LEKPa */ + { "balticplus", KBD_LITHUANIAN }, /* Baltic+ */ + { "", 0 }, +}; + +/* Latvia */ +static const xkbVariant lv_variants[] = +{ + { "apostrophe", KBD_LATVIAN }, /* Apostrophe (') variant */ + { "tilde", KBD_LATVIAN }, /* Tilde (~) variant */ + { "fkey", KBD_LATVIAN }, /* F-letter (F) variant */ + { "", 0 }, +}; + +/* Montenegro */ +static const xkbVariant me_variants[] = +{ + { "cyrillic", 0 }, /* Cyrillic */ + { "cyrillicyz", 0 }, /* Cyrillic, Z and ZHE swapped */ + { "latinunicode", 0 }, /* Latin unicode */ + { "latinyz", 0 }, /* Latin qwerty */ + { "latinunicodeyz", 0 }, /* Latin unicode qwerty */ + { "cyrillicalternatequotes", 0 }, /* Cyrillic with guillemets */ + { "latinalternatequotes", 0 }, /* Latin with guillemets */ + { "", 0 }, +}; + +/* Macedonia */ +static const xkbVariant mk_variants[] = +{ + { "nodeadkeys", KBD_FYRO_MACEDONIAN }, /* Eliminate dead keys */ + { "", 0 }, +}; + +/* Malta */ +static const xkbVariant mt_variants[] = +{ + { "us", KBD_MALTESE_48_KEY }, /* Maltese keyboard with US layout */ + { "", 0 }, +}; + +/* Norway */ +static const xkbVariant no_variants[] = +{ + { "nodeadkeys", KBD_NORWEGIAN }, /* Eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "smi", KBD_NORWEGIAN_WITH_SAMI }, /* Northern Saami */ + { "smi_nodeadkeys", KBD_SAMI_EXTENDED_NORWAY }, /* Northern Saami, eliminate dead keys */ + { "mac", KBD_NORWEGIAN }, /* Macintosh */ + { "mac_nodeadkeys", KBD_SAMI_EXTENDED_NORWAY }, /* Macintosh, eliminate dead keys */ + { "", 0 }, +}; + +/* Poland */ +static const xkbVariant pl_variants[] = +{ + { "qwertz", KBD_POLISH_214 }, /* qwertz */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "dvorak_quotes", KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on quotemark key */ + { "dvorak_altquotes", KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on key 1 */ + { "csb", 0 }, /* Kashubian */ + { "ru_phonetic_dvorak", KBD_UNITED_STATES_DVORAK }, /* Russian phonetic Dvorak */ + { "", 0 }, +}; + +/* Portugal */ +static const xkbVariant pt_variants[] = +{ + { "nodeadkeys", KBD_PORTUGUESE }, /* Eliminate dead keys */ + { "sundeadkeys", KBD_PORTUGUESE }, /* Sun dead keys */ + { "mac", KBD_PORTUGUESE }, /* Macintosh */ + { "mac_nodeadkeys", KBD_PORTUGUESE }, /* Macintosh, eliminate dead keys */ + { "mac_sundeadkeys", KBD_PORTUGUESE }, /* Macintosh, Sun dead keys */ + { "nativo", KBD_PORTUGUESE }, /* Nativo */ + { "nativo-us", KBD_PORTUGUESE }, /* Nativo for USA keyboards */ + { "nativo-epo", KBD_PORTUGUESE }, /* Nativo for Esperanto */ + { "", 0 }, +}; + +/* Romania */ +static const xkbVariant ro_variants[] = +{ + { "cedilla", KBD_ROMANIAN }, /* Cedilla */ + { "std", KBD_ROMANIAN }, /* Standard */ + { "std_cedilla", KBD_ROMANIAN }, /* Standard (Cedilla) */ + { "winkeys", KBD_ROMANIAN }, /* Winkeys */ + { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */ + { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */ + { "crh_dobruca1", KBD_TATAR }, /* Crimean Tatar (Dobruca-1 Q) */ + { "crh_dobruca2", KBD_TATAR }, /* Crimean Tatar (Dobruca-2 Q) */ + { "", 0 }, +}; + +/* Russia */ +static const xkbVariant ru_variants[] = +{ + { "phonetic", KBD_RUSSIAN }, /* Phonetic */ + { "phonetic_winkeys", KBD_RUSSIAN }, /* Phonetic Winkeys */ + { "typewriter", KBD_RUSSIAN_TYPEWRITER }, /* Typewriter */ + { "legacy", KBD_RUSSIAN }, /* Legacy */ + { "tt", KBD_TATAR }, /* Tatar */ + { "os_legacy", 0 }, /* Ossetian, legacy */ + { "os_winkeys", 0 }, /* Ossetian, Winkeys */ + { "cv", 0 }, /* Chuvash */ + { "cv_latin", 0 }, /* Chuvash Latin */ + { "udm", 0 }, /* Udmurt */ + { "kom", 0 }, /* Komi */ + { "sah", 0 }, /* Yakut */ + { "xal", 0 }, /* Kalmyk */ + { "dos", 0 }, /* DOS */ + { "", 0 }, +}; + +/* Serbia */ +static const xkbVariant rs_variants[] = +{ + { "yz", KBD_SERBIAN_CYRILLIC }, /* Z and ZHE swapped */ + { "latin", KBD_SERBIAN_LATIN }, /* Latin */ + { "latinunicode", KBD_SERBIAN_LATIN }, /* Latin Unicode */ + { "latinyz", KBD_SERBIAN_LATIN }, /* Latin qwerty */ + { "latinunicodeyz", KBD_SERBIAN_LATIN }, /* Latin Unicode qwerty */ + { "alternatequotes", KBD_SERBIAN_CYRILLIC }, /* With guillemets */ + { "latinalternatequotes", KBD_SERBIAN_LATIN }, /* Latin with guillemets */ + { "", 0 }, +}; + +/* Slovenia */ +static const xkbVariant si_variants[] = +{ + { "alternatequotes", KBD_SLOVENIAN }, /* Use guillemets for quotes */ + { "us", KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Slovenian letters */ + { "", 0 }, +}; + +/* Slovakia */ +static const xkbVariant sk_variants[] = +{ + { "bksl", KBD_SLOVAK }, /* Extended Backslash */ + { "qwerty", KBD_SLOVAK_QWERTY }, /* qwerty */ + { "qwerty_bksl", KBD_SLOVAK_QWERTY }, /* qwerty, extended Backslash */ + { "", 0 }, +}; + +/* Spain */ +static const xkbVariant es_variants[] = +{ + { "nodeadkeys", KBD_SPANISH_VARIATION }, /* Eliminate dead keys */ + { "deadtilde", KBD_SPANISH_VARIATION }, /* Include dead tilde */ + { "sundeadkeys", KBD_SPANISH }, /* Sun dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "ast", KBD_SPANISH_VARIATION }, /* Asturian variant with bottom-dot H and bottom-dot L */ + { "cat", KBD_SPANISH_VARIATION }, /* Catalan variant with middle-dot L */ + { "mac", KBD_SPANISH }, /* Macintosh */ + { "", 0 }, +}; + +/* Sweden */ +static const xkbVariant se_variants[] = +{ + { "nodeadkeys", KBD_SWEDISH }, /* Eliminate dead keys */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "rus", KBD_RUSSIAN }, /* Russian phonetic */ + { "rus_nodeadkeys", KBD_RUSSIAN }, /* Russian phonetic, eliminate dead keys */ + { "smi", KBD_SWEDISH_WITH_SAMI }, /* Northern Saami */ + { "mac", KBD_SWEDISH }, /* Macintosh */ + { "svdvorak", KBD_UNITED_STATES_DVORAK }, /* Svdvorak */ + { "", 0 }, +}; + +/* Switzerland */ +static const xkbVariant ch_variants[] = +{ + { "de_nodeadkeys", KBD_SWISS_GERMAN }, /* German, eliminate dead keys */ + { "de_sundeadkeys", KBD_SWISS_GERMAN }, /* German, Sun dead keys */ + { "fr", KBD_SWISS_FRENCH }, /* French */ + { "fr_nodeadkeys", KBD_SWISS_FRENCH }, /* French, eliminate dead keys */ + { "fr_sundeadkeys", KBD_SWISS_FRENCH }, /* French, Sun dead keys */ + { "fr_mac", KBD_SWISS_FRENCH }, /* French (Macintosh) */ + { "de_mac", KBD_SWISS_GERMAN }, /* German (Macintosh) */ + { "", 0 }, +}; + +/* Syria */ +static const xkbVariant sy_variants[] = +{ + { "syc", KBD_SYRIAC }, /* Syriac */ + { "syc_phonetic", KBD_SYRIAC_PHONETIC }, /* Syriac phonetic */ + { "ku", 0 }, /* Kurdish, Latin Q */ + { "ku_f", 0 }, /* Kurdish, (F) */ + { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */ + { "", 0 }, +}; + +/* Tajikistan */ +static const xkbVariant tj_variants[] = +{ + { "legacy", 0 }, /* Legacy */ + { "", 0 }, +}; + +/* Sri Lanka */ +static const xkbVariant lk_variants[] = +{ + { "tam_unicode", KBD_TAMIL }, /* Tamil Unicode */ + { "tam_TAB", KBD_TAMIL }, /* Tamil TAB Typewriter */ + { "", 0 }, +}; + +/* Thailand */ +static const xkbVariant th_variants[] = +{ + { "tis", KBD_THAI_KEDMANEE_NON_SHIFTLOCK }, /* TIS-820.2538 */ + { "pat", KBD_THAI_PATTACHOTE }, /* Pattachote */ + { "", 0 }, +}; + +/* Turkey */ +static const xkbVariant tr_variants[] = +{ + { "f", KBD_TURKISH_F }, /* (F) */ + { "alt", KBD_TURKISH_Q }, /* Alt-Q */ + { "sundeadkeys", KBD_TURKISH_F }, /* Sun dead keys */ + { "ku", 0 }, /* Kurdish, Latin Q */ + { "ku_f", 0 }, /* Kurdish, (F) */ + { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */ + { "intl", KBD_TURKISH_F }, /* International (with dead keys) */ + { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */ + { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */ + { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */ + { "", 0 }, +}; + +/* Ukraine */ +static const xkbVariant ua_variants[] = +{ + { "phonetic", KBD_UKRAINIAN }, /* Phonetic */ + { "typewriter", KBD_UKRAINIAN }, /* Typewriter */ + { "winkeys", KBD_UKRAINIAN }, /* Winkeys */ + { "legacy", KBD_UKRAINIAN }, /* Legacy */ + { "rstu", KBD_UKRAINIAN }, /* Standard RSTU */ + { "rstu_ru", KBD_UKRAINIAN }, /* Standard RSTU on Russian layout */ + { "homophonic", KBD_UKRAINIAN }, /* Homophonic */ + { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */ + { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */ + { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */ + { "", 0 }, +}; + +/* United Kingdom */ +static const xkbVariant gb_variants[] = +{ + { "extd", KBD_UNITED_KINGDOM_EXTENDED }, /* Extended - Winkeys */ + { "intl", KBD_UNITED_KINGDOM_EXTENDED }, /* International (with dead keys) */ + { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ + { "dvorakukp", KBD_UNITED_STATES_DVORAK }, /* Dvorak (UK Punctuation) */ + { "mac", KBD_UNITED_KINGDOM }, /* Macintosh */ + { "colemak", 0 }, /* Colemak */ + { "", 0 }, +}; + +/* Uzbekistan */ +static const xkbVariant uz_variants[] = +{ + { "latin", 0 }, /* Latin */ + { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */ + { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */ + { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */ + { "", 0 }, +}; + +/* Korea, Republic of */ +static const xkbVariant kr_variants[] = +{ + { "kr104", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* 101/104 key Compatible */ + { "", 0 }, +}; + +/* Ireland */ +static const xkbVariant ie_variants[] = +{ + { "CloGaelach", KBD_GAELIC }, /* CloGaelach */ + { "UnicodeExpert", KBD_GAELIC }, /* UnicodeExpert */ + { "ogam", KBD_GAELIC }, /* Ogham */ + { "ogam_is434", KBD_GAELIC }, /* Ogham IS434 */ + { "", 0 }, +}; + +/* Pakistan */ +static const xkbVariant pk_variants[] = +{ + { "urd-crulp", 0 }, /* CRULP */ + { "urd-nla", 0 }, /* NLA */ + { "ara", KBD_ARABIC_101 }, /* Arabic */ + { "", 0 }, +}; + +/* Esperanto */ +static const xkbVariant epo_variants[] = +{ + { "legacy", 0 }, /* displaced semicolon and quote (obsolete) */ + { "", 0 }, +}; + +/* Nigeria */ +static const xkbVariant ng_variants[] = +{ + { "igbo", 0 }, /* Igbo */ + { "yoruba", 0 }, /* Yoruba */ + { "hausa", 0 }, /* Hausa */ + { "", 0 }, +}; + +/* Braille */ +static const xkbVariant brai_variants[] = +{ + { "left_hand", 0 }, /* Left hand */ + { "right_hand", 0 }, /* Right hand */ + { "", 0 }, +}; + +/* Turkmenistan */ +static const xkbVariant tm_variants[] = +{ + { "alt", KBD_TURKISH_Q }, /* Alt-Q */ + { "", 0 }, +}; + +static const xkbLayout xkbLayouts[] = +{ + { "us", KBD_US, us_variants }, /* USA */ + { "ad", 0, NULL }, /* Andorra */ + { "af", KBD_FARSI, af_variants }, /* Afghanistan */ + { "ara", KBD_ARABIC_101, ara_variants }, /* Arabic */ + { "al", 0, NULL }, /* Albania */ + { "am", KBD_ARMENIAN_EASTERN, am_variants }, /* Armenia */ + { "az", KBD_AZERI_CYRILLIC, az_variants }, /* Azerbaijan */ + { "by", KBD_BELARUSIAN, by_variants }, /* Belarus */ + { "be", KBD_BELGIAN_FRENCH, be_variants }, /* Belgium */ + { "bd", KBD_BENGALI, bd_variants }, /* Bangladesh */ + { "in", KBD_HINDI_TRADITIONAL, in_variants }, /* India */ + { "ba", KBD_CROATIAN, ba_variants }, /* Bosnia and Herzegovina */ + { "br", KBD_PORTUGUESE_BRAZILIAN_ABNT, br_variants }, /* Brazil */ + { "bg", KBD_BULGARIAN_LATIN, bg_variants }, /* Bulgaria */ + { "ma", KBD_FRENCH, ma_variants }, /* Morocco */ + { "mm", 0, NULL }, /* Myanmar */ + { "ca", KBD_US, ca_variants }, /* Canada */ + { "cd", 0, NULL }, /* Congo, Democratic Republic of the */ + { "cn", KBD_CHINESE_TRADITIONAL_PHONETIC, cn_variants }, /* China */ + { "hr", KBD_CROATIAN, hr_variants }, /* Croatia */ + { "cz", KBD_CZECH, cz_variants }, /* Czechia */ + { "dk", KBD_DANISH, dk_variants }, /* Denmark */ + { "nl", KBD_DUTCH, nl_variants }, /* Netherlands */ + { "bt", 0, NULL }, /* Bhutan */ + { "ee", KBD_ESTONIAN, ee_variants }, /* Estonia */ + { "ir", 0, ir_variants }, /* Iran */ + { "iq", 0, iq_variants }, /* Iraq */ + { "fo", 0, fo_variants }, /* Faroe Islands */ + { "fi", KBD_FINNISH, fi_variants }, /* Finland */ + { "fr", KBD_FRENCH, fr_variants }, /* France */ + { "gh", 0, gh_variants }, /* Ghana */ + { "gn", 0, NULL }, /* Guinea */ + { "ge", KBD_GEORGIAN, ge_variants }, /* Georgia */ + { "de", KBD_GERMAN, de_variants }, /* Germany */ + { "gr", KBD_GREEK, gr_variants }, /* Greece */ + { "hu", KBD_HUNGARIAN, hu_variants }, /* Hungary */ + { "is", KBD_ICELANDIC, is_variants }, /* Iceland */ + { "il", KBD_HEBREW, il_variants }, /* Israel */ + { "it", KBD_ITALIAN, it_variants }, /* Italy */ + { "jp", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, jp_variants }, /* Japan */ + { "kg", 0, kg_variants }, /* Kyrgyzstan */ + { "kh", 0, NULL }, /* Cambodia */ + { "kz", KBD_KAZAKH, kz_variants }, /* Kazakhstan */ + { "la", 0, NULL }, /* Laos */ + { "latam", KBD_LATIN_AMERICAN, latam_variants }, /* Latin America */ + { "lt", KBD_LITHUANIAN, lt_variants }, /* Lithuania */ + { "lv", KBD_LATVIAN, lv_variants }, /* Latvia */ + { "mao", KBD_MAORI, NULL }, /* Maori */ + { "me", KBD_SERBIAN_LATIN, me_variants }, /* Montenegro */ + { "mk", KBD_FYRO_MACEDONIAN, mk_variants }, /* Macedonia */ + { "mt", KBD_MALTESE_48_KEY, mt_variants }, /* Malta */ + { "mn", KBD_MONGOLIAN_CYRILLIC, NULL }, /* Mongolia */ + { "no", KBD_NORWEGIAN, no_variants }, /* Norway */ + { "pl", KBD_POLISH_214, pl_variants }, /* Poland */ + { "pt", KBD_PORTUGUESE, pt_variants }, /* Portugal */ + { "ro", KBD_ROMANIAN, ro_variants }, /* Romania */ + { "ru", KBD_RUSSIAN, ru_variants }, /* Russia */ + { "rs", KBD_SERBIAN_LATIN, rs_variants }, /* Serbia */ + { "si", KBD_SLOVENIAN, si_variants }, /* Slovenia */ + { "sk", KBD_SLOVAK, sk_variants }, /* Slovakia */ + { "es", KBD_SPANISH, es_variants }, /* Spain */ + { "se", KBD_SWEDISH, se_variants }, /* Sweden */ + { "ch", KBD_SWISS_FRENCH, ch_variants }, /* Switzerland */ + { "sy", KBD_SYRIAC, sy_variants }, /* Syria */ + { "tj", 0, tj_variants }, /* Tajikistan */ + { "lk", 0, lk_variants }, /* Sri Lanka */ + { "th", KBD_THAI_KEDMANEE, th_variants }, /* Thailand */ + { "tr", KBD_TURKISH_Q, tr_variants }, /* Turkey */ + { "ua", KBD_UKRAINIAN, ua_variants }, /* Ukraine */ + { "gb", KBD_UNITED_KINGDOM, gb_variants }, /* United Kingdom */ + { "uz", KBD_UZBEK_CYRILLIC, uz_variants }, /* Uzbekistan */ + { "vn", KBD_VIETNAMESE, NULL }, /* Vietnam */ + { "kr", KBD_KOREAN_INPUT_SYSTEM_IME_2000, kr_variants }, /* Korea, Republic of */ + { "ie", KBD_UNITED_KINGDOM, ie_variants }, /* Ireland */ + { "pk", 0, pk_variants }, /* Pakistan */ + { "mv", 0, NULL }, /* Maldives */ + { "za", 0, NULL }, /* South Africa */ + { "epo", 0, epo_variants }, /* Esperanto */ + { "np", KBD_NEPALI, NULL }, /* Nepal */ + { "ng", 0, ng_variants }, /* Nigeria */ + { "et", 0, NULL }, /* Ethiopia */ + { "sn", 0, NULL }, /* Senegal */ + { "brai", 0, brai_variants }, /* Braille */ + { "tm", KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */ +}; + +/* OpenSolaris 2008.11 and 2009.06 keyboard layouts + * + * While OpenSolaris comes with Xorg and XKB, it maintains a set of keyboard layout + * names that map directly to a particular keyboard layout in XKB. Fortunately for us, + * this way of doing things comes from Solaris, which is XKB unaware. The same keyboard + * layout naming system is used in Solaris, so we can use the same XKB configuration as + * we would on OpenSolaris and get an accurate keyboard layout detection :) + * + * We can check for the current keyboard layout using the "kbd -l" command: + * + * type=6 + * layout=33 (0x21) + * delay(ms)=500 + * rate(ms)=40 + * + * We can check at runtime if the kbd utility is present, parse the output, and use the + * keyboard layout indicated by the index given (in this case, 33, or US-English). + */ + + +typedef struct _SunOSKeyboard +{ + /* Sun keyboard type */ + int type; + + /* Layout */ + int layout; + + /* XKB keyboard */ + char* xkbType; + + /* XKB keyboard layout */ + unsigned int keyboardLayoutID; +} SunOSKeyboard; + + +static const SunOSKeyboard SunOSKeyboards[] = +{ + { 4, 0, "sun(type4)", KBD_US }, /* US4 */ + { 4, 1, "sun(type4)", KBD_US }, /* US4 */ + { 4, 2, "sun(type4tuv)", KBD_FRENCH }, /* FranceBelg4 */ + { 4, 3, "sun(type4_ca)", KBD_US }, /* Canada4 */ + { 4, 4, "sun(type4tuv)", KBD_DANISH }, /* Denmark4 */ + { 4, 5, "sun(type4tuv)", KBD_GERMAN }, /* Germany4 */ + { 4, 6, "sun(type4tuv)", KBD_ITALIAN }, /* Italy4 */ + { 4, 7, "sun(type4tuv)", KBD_DUTCH }, /* Netherland4 */ + { 4, 8, "sun(type4tuv)", KBD_NORWEGIAN }, /* Norway4 */ + { 4, 9, "sun(type4tuv)", KBD_PORTUGUESE }, /* Portugal4 */ + { 4, 10, "sun(type4tuv)", KBD_SPANISH }, /* SpainLatAm4 */ + { 4, 11, "sun(type4tuv)", KBD_SWEDISH }, /* SwedenFin4 */ + { 4, 12, "sun(type4tuv)", KBD_SWISS_FRENCH }, /* Switzer_Fr4 */ + { 4, 13, "sun(type4tuv)", KBD_SWISS_GERMAN }, /* Switzer_Ge4 */ + { 4, 14, "sun(type4tuv)", KBD_UNITED_KINGDOM }, /* UK4 */ + { 4, 16, "sun(type4)", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* Korea4 */ + { 4, 17, "sun(type4)", KBD_CHINESE_TRADITIONAL_PHONETIC }, /* Taiwan4 */ + { 4, 32, "sun(type4jp)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan4 */ + { 4, 19, "sun(type5)", KBD_US }, /* US101A_PC */ + { 4, 33, "sun(type5)", KBD_US }, /* US5 */ + { 4, 34, "sun(type5unix)", KBD_US }, /* US_UNIX5 */ + { 4, 35, "sun(type5tuv)", KBD_FRENCH }, /* France5 */ + { 4, 36, "sun(type5tuv)", KBD_DANISH }, /* Denmark5 */ + { 4, 37, "sun(type5tuv)", KBD_GERMAN }, /* Germany5 */ + { 4, 38, "sun(type5tuv)", KBD_ITALIAN }, /* Italy5 */ + { 4, 39, "sun(type5tuv)", KBD_DUTCH }, /* Netherland5 */ + { 4, 40, "sun(type5tuv)", KBD_NORWEGIAN }, /* Norway5 */ + { 4, 41, "sun(type5tuv)", KBD_PORTUGUESE }, /* Portugal5 */ + { 4, 42, "sun(type5tuv)", KBD_SPANISH }, /* Spain5 */ + { 4, 43, "sun(type5tuv)", KBD_SWEDISH }, /* Sweden5 */ + { 4, 44, "sun(type5tuv)", KBD_SWISS_FRENCH }, /* Switzer_Fr5 */ + { 4, 45, "sun(type5tuv)", KBD_SWISS_GERMAN }, /* Switzer_Ge5 */ + { 4, 46, "sun(type5tuv)", KBD_UNITED_KINGDOM }, /* UK5 */ + { 4, 47, "sun(type5)", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* Korea5 */ + { 4, 48, "sun(type5)", KBD_CHINESE_TRADITIONAL_PHONETIC }, /* Taiwan5 */ + { 4, 49, "sun(type5jp)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan5 */ + { 4, 50, "sun(type5tuv)", KBD_CANADIAN_FRENCH }, /* Canada_Fr5 */ + { 4, 51, "sun(type5tuv)", KBD_HUNGARIAN }, /* Hungary5 */ + { 4, 52, "sun(type5tuv)", KBD_POLISH_214 }, /* Poland5 */ + { 4, 53, "sun(type5tuv)", KBD_CZECH }, /* Czech5 */ + { 4, 54, "sun(type5tuv)", KBD_RUSSIAN }, /* Russia5 */ + { 4, 55, "sun(type5tuv)", KBD_LATVIAN }, /* Latvia5 */ + { 4, 57, "sun(type5tuv)", KBD_GREEK }, /* Greece5 */ + { 4, 59, "sun(type5tuv)", KBD_LITHUANIAN }, /* Lithuania5 */ + { 4, 63, "sun(type5tuv)", KBD_CANADIAN_FRENCH }, /* Canada_Fr5_TBITS5 */ + { 4, 56, "sun(type5tuv)", KBD_TURKISH_Q }, /* TurkeyQ5 */ + { 4, 58, "sun(type5tuv)", KBD_ARABIC_101 }, /* Arabic5 */ + { 4, 60, "sun(type5tuv)", KBD_BELGIAN_FRENCH }, /* Belgian5 */ + { 4, 62, "sun(type5tuv)", KBD_TURKISH_F }, /* TurkeyF5 */ + { 4, 80, "sun(type5hobo)", KBD_US }, /* US5_Hobo */ + { 4, 81, "sun(type5hobo)", KBD_US }, /* US_UNIX5_Hobo */ + { 4, 82, "sun(type5tuvhobo)", KBD_FRENCH }, /* France5_Hobo */ + { 4, 83, "sun(type5tuvhobo)", KBD_DANISH }, /* Denmark5_Hobo */ + { 4, 84, "sun(type5tuvhobo)", KBD_GERMAN }, /* Germany5_Hobo */ + { 4, 85, "sun(type5tuvhobo)", KBD_ITALIAN }, /* Italy5_Hobo */ + { 4, 86, "sun(type5tuvhobo)", KBD_DUTCH }, /* Netherland5_Hobo */ + { 4, 87, "sun(type5tuvhobo)", KBD_NORWEGIAN }, /* Norway5_Hobo */ + { 4, 88, "sun(type5tuvhobo)", KBD_PORTUGUESE }, /* Portugal5_Hobo */ + { 4, 89, "sun(type5tuvhobo)", KBD_SPANISH }, /* Spain5_Hobo */ + { 4, 90, "sun(type5tuvhobo)", KBD_SWEDISH }, /* Sweden5_Hobo */ + { 4, 91, "sun(type5tuvhobo)", KBD_SWISS_FRENCH }, /* Switzer_Fr5_Hobo */ + { 4, 92, "sun(type5tuvhobo)", KBD_SWISS_GERMAN }, /* Switzer_Ge5_Hobo */ + { 4, 93, "sun(type5tuvhobo)", KBD_UNITED_KINGDOM }, /* UK5_Hobo */ + { 4, 94, "sun(type5hobo)", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* Korea5_Hobo */ + { 4, 95, "sun(type5hobo)", KBD_CHINESE_TRADITIONAL_PHONETIC }, /* Taiwan5_Hobo */ + { 4, 96, "sun(type5jphobo)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan5_Hobo */ + { 4, 97, "sun(type5tuvhobo)", KBD_CANADIAN_FRENCH }, /* Canada_Fr5_Hobo */ + { 101, 1, "digital_vndr/pc(pc104)", KBD_US }, /* US101A_x86 */ + { 101, 34, "digital_vndr/pc(pc104)", KBD_US }, /* J3100_x86 */ + { 101, 35, "digital_vndr/pc(pc104)", KBD_FRENCH }, /* France_x86 */ + { 101, 36, "digital_vndr/pc(pc104)", KBD_DANISH }, /* Denmark_x86 */ + { 101, 37, "digital_vndr/pc(pc104)", KBD_GERMAN }, /* Germany_x86 */ + { 101, 38, "digital_vndr/pc(pc104)", KBD_ITALIAN }, /* Italy_x86 */ + { 101, 39, "digital_vndr/pc(pc104)", KBD_DUTCH }, /* Netherland_x86 */ + { 101, 40, "digital_vndr/pc(pc104)", KBD_NORWEGIAN }, /* Norway_x86 */ + { 101, 41, "digital_vndr/pc(pc104)", KBD_PORTUGUESE }, /* Portugal_x86 */ + { 101, 42, "digital_vndr/pc(pc104)", KBD_SPANISH }, /* Spain_x86 */ + { 101, 43, "digital_vndr/pc(pc104)", KBD_SWEDISH }, /* Sweden_x86 */ + { 101, 44, "digital_vndr/pc(pc104)", KBD_SWISS_FRENCH }, /* Switzer_Fr_x86 */ + { 101, 45, "digital_vndr/pc(pc104)", KBD_SWISS_GERMAN }, /* Switzer_Ge_x86 */ + { 101, 46, "digital_vndr/pc(pc104)", KBD_UNITED_KINGDOM }, /* UK_x86 */ + { 101, 47, "digital_vndr/pc(pc104)", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* Korea_x86 */ + { 101, 48, "digital_vndr/pc(pc104)", KBD_CHINESE_TRADITIONAL_PHONETIC }, /* Taiwan_x86 */ + { 101, 49, "digital_vndr/pc(lk411jj)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan_x86 */ + { 101, 50, "digital_vndr/pc(pc104)", KBD_CANADIAN_FRENCH }, /* Canada_Fr2_x86 */ + { 101, 51, "digital_vndr/pc(pc104)", KBD_HUNGARIAN }, /* Hungary_x86 */ + { 101, 52, "digital_vndr/pc(pc104)", KBD_POLISH_214 }, /* Poland_x86 */ + { 101, 53, "digital_vndr/pc(pc104)", KBD_CZECH }, /* Czech_x86 */ + { 101, 54, "digital_vndr/pc(pc104)", KBD_RUSSIAN }, /* Russia_x86 */ + { 101, 55, "digital_vndr/pc(pc104)", KBD_LATVIAN }, /* Latvia_x86 */ + { 101, 56, "digital_vndr/pc(pc104)", KBD_TURKISH_Q }, /* Turkey_x86 */ + { 101, 57, "digital_vndr/pc(pc104)", KBD_GREEK }, /* Greece_x86 */ + { 101, 59, "digital_vndr/pc(pc104)", KBD_LITHUANIAN }, /* Lithuania_x86 */ + { 101, 1001, "digital_vndr/pc(pc104)", KBD_US }, /* MS_US101A_x86 */ + { 6, 6, "sun(type6tuv)", KBD_DANISH }, /* Denmark6_usb */ + { 6, 7, "sun(type6tuv)", KBD_FINNISH }, /* Finnish6_usb */ + { 6, 8, "sun(type6tuv)", KBD_FRENCH }, /* France6_usb */ + { 6, 9, "sun(type6tuv)", KBD_GERMAN }, /* Germany6_usb */ + { 6, 14, "sun(type6tuv)", KBD_ITALIAN }, /* Italy6_usb */ + { 6, 15, "sun(type6jp)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan7_usb */ + { 6, 16, "sun(type6)", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* Korea6_usb */ + { 6, 18, "sun(type6tuv)", KBD_DUTCH }, /* Netherland6_usb */ + { 6, 19, "sun(type6tuv)", KBD_NORWEGIAN }, /* Norway6_usb */ + { 6, 22, "sun(type6tuv)", KBD_PORTUGUESE }, /* Portugal6_usb */ + { 6, 23, "sun(type6tuv)", KBD_RUSSIAN }, /* Russia6_usb */ + { 6, 25, "sun(type6tuv)", KBD_SPANISH }, /* Spain6_usb */ + { 6, 26, "sun(type6tuv)", KBD_SWEDISH }, /* Sweden6_usb */ + { 6, 27, "sun(type6tuv)", KBD_SWISS_FRENCH }, /* Switzer_Fr6_usb */ + { 6, 28, "sun(type6tuv)", KBD_SWISS_GERMAN }, /* Switzer_Ge6_usb */ + { 6, 30, "sun(type6)", KBD_CHINESE_TRADITIONAL_PHONETIC }, /* Taiwan6_usb */ + { 6, 32, "sun(type6tuv)", KBD_UNITED_KINGDOM }, /* UK6_usb */ + { 6, 33, "sun(type6)", KBD_US }, /* US6_usb */ + { 6, 1, "sun(type6tuv)", KBD_ARABIC_101 }, /* Arabic6_usb */ + { 6, 2, "sun(type6tuv)", KBD_BELGIAN_FRENCH }, /* Belgian6_usb */ + { 6, 31, "sun(type6tuv)", KBD_TURKISH_Q }, /* TurkeyQ6_usb */ + { 6, 35, "sun(type6tuv)", KBD_TURKISH_F }, /* TurkeyF6_usb */ + { 6, 271, "sun(type6jp)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Japan6_usb */ + { 6, 264, "sun(type6tuv)", KBD_ALBANIAN }, /* Albanian6_usb */ + { 6, 261, "sun(type6tuv)", KBD_BELARUSIAN }, /* Belarusian6_usb */ + { 6, 260, "sun(type6tuv)", KBD_BULGARIAN }, /* Bulgarian6_usb */ + { 6, 259, "sun(type6tuv)", KBD_CROATIAN }, /* Croatian6_usb */ + { 6, 5, "sun(type6tuv)", KBD_CZECH }, /* Czech6_usb */ + { 6, 4, "sun(type6tuv)", KBD_CANADIAN_FRENCH }, /* French-Canadian6_usb */ + { 6, 12, "sun(type6tuv)", KBD_HUNGARIAN }, /* Hungarian6_usb */ + { 6, 10, "sun(type6tuv)", KBD_GREEK }, /* Greek6_usb */ + { 6, 17, "sun(type6)", KBD_LATIN_AMERICAN }, /* Latin-American6_usb */ + { 6, 265, "sun(type6tuv)", KBD_LITHUANIAN }, /* Lithuanian6_usb */ + { 6, 266, "sun(type6tuv)", KBD_LATVIAN }, /* Latvian6_usb */ + { 6, 267, "sun(type6tuv)", KBD_FYRO_MACEDONIAN }, /* Macedonian6_usb */ + { 6, 263, "sun(type6tuv)", KBD_MALTESE_47_KEY }, /* Malta_UK6_usb */ + { 6, 262, "sun(type6tuv)", KBD_MALTESE_48_KEY }, /* Malta_US6_usb */ + { 6, 21, "sun(type6tuv)", KBD_POLISH_214 }, /* Polish6_usb */ + { 6, 257, "sun(type6tuv)", KBD_SERBIAN_LATIN }, /* Serbia-And-Montenegro6_usb */ + { 6, 256, "sun(type6tuv)", KBD_SLOVENIAN }, /* Slovenian6_usb */ + { 6, 24, "sun(type6tuv)", KBD_SLOVAK }, /* Slovakian6_usb */ + { 6, 3, "sun(type6)", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Canada_Bi6_usb */ + { 6, 272, "sun(type6)", KBD_PORTUGUESE_BRAZILIAN_ABNT } /* Brazil6_usb */ +}; + +unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant) +{ + int i; + int j; + + if ((layout == NULL) || (variant == NULL)) + return 0; + + DEBUG_KBD("xkbLayout: %s\txkbVariant: %s\n", layout, variant); + + for (i = 0; i < sizeof(xkbLayouts) / sizeof(xkbLayout); i++) + { + if (strcmp(xkbLayouts[i].layout, layout) == 0) + { + for (j = 0; xkbLayouts[i].variants[j].variant != NULL && strlen(xkbLayouts[i].variants[j].variant) > 0; j++) + { + if (strcmp(xkbLayouts[i].variants[j].variant, variant) == 0) + { + return xkbLayouts[i].variants[j].keyboardLayoutID; + } + } + + return xkbLayouts[i].keyboardLayoutID; + } + } + + return 0; +} + +#if defined(sun) + +unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) +{ + FILE* kbd; + + int i; + int type = 0; + int layout = 0; + + char* pch; + char* beg; + char* end; + + char buffer[1024]; + + /* + Sample output for "kbd -t -l" : + + USB keyboard + type=6 + layout=3 (0x03) + delay(ms)=500 + rate(ms)=40 + */ + + kbd = popen("kbd -t -l", "r"); + + if (kbd < 0) + return 0; + + while(fgets(buffer, sizeof(buffer), kbd) != NULL) + { + if((pch = strstr(buffer, "type=")) != NULL) + { + beg = pch + sizeof("type=") - 1; + end = strchr(beg, '\n'); + end[0] = '\0'; + type = atoi(beg); + } + else if((pch = strstr(buffer, "layout=")) != NULL) + { + beg = pch + sizeof("layout=") - 1; + end = strchr(beg, ' '); + end[0] = '\0'; + layout = atoi(beg); + } + } + pclose(kbd); + + for(i = 0; i < sizeof(SunOSKeyboards) / sizeof(SunOSKeyboard); i++) + { + if(SunOSKeyboards[i].type == type) + { + if(SunOSKeyboards[i].layout == layout) + { + strncpy(xkbfile, SunOSKeyboards[i].xkbType, length); + return SunOSKeyboards[i].keyboardLayoutID; + } + } + } + + return 0; +} + +#endif diff --git a/libfreerdp-kbd/x_layout_id_table.h b/libfreerdp-kbd/x_layout_id_table.h new file mode 100644 index 0000000..11db11a --- /dev/null +++ b/libfreerdp-kbd/x_layout_id_table.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * Copyright 2009 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* Hardcoded mapping from xkb layout names and variants to RDP layout ids */ + +#ifndef __LAYOUTS_X_H +#define __LAYOUTS_X_H + +unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant); + +#if defined(sun) +unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); +#endif + +#endif diff --git a/libfreerdp-rail/CMakeLists.txt b/libfreerdp-rail/CMakeLists.txt new file mode 100644 index 0000000..b864852 --- /dev/null +++ b/libfreerdp-rail/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-rail cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(FREERDP_RAIL_SRCS + window_list.c + window.c + icon.c + rail.c + librail.h) + +add_library(freerdp-rail ${FREERDP_RAIL_SRCS}) + +set_target_properties(freerdp-rail PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +target_link_libraries(freerdp-rail freerdp-utils) + +install(TARGETS freerdp-rail DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-rail/icon.c b/libfreerdp-rail/icon.c new file mode 100644 index 0000000..3a9e167 --- /dev/null +++ b/libfreerdp-rail/icon.c @@ -0,0 +1,112 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Window Icon Cache + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include + +ICON_INFO* icon_cache_get(rdpIconCache* cache, uint8 id, uint16 index, void** extra) +{ + ICON_INFO* entry; + + if (id >= cache->numCaches) + { + printf("invalid window icon cache id:%d\n", id); + return (ICON_INFO*) NULL; + } + + if (index >= cache->numCacheEntries) + { + printf("invalid window icon cache index:%d in cache id:%d\n", index, id); + return (ICON_INFO*) NULL; + } + + entry = cache->caches[id].entries[index].entry; + + if (extra != NULL) + *extra = cache->caches[id].entries[index].extra; + + return entry; +} + +void icon_cache_put(rdpIconCache* cache, uint8 id, uint16 index, ICON_INFO* entry, void* extra) +{ + if (id >= cache->numCaches) + { + printf("invalid window icon cache id:%d\n", id); + return; + } + + if (index >= cache->numCacheEntries) + { + printf("invalid window icon cache index:%d in cache id:%d\n", index, id); + return; + } + + cache->caches[id].entries[index].entry = entry; + + if (extra != NULL) + cache->caches[id].entries[index].extra = extra; +} + +rdpIconCache* icon_cache_new(rdpRail* rail) +{ + rdpIconCache* cache; + + cache = (rdpIconCache*) xzalloc(sizeof(rdpIconCache)); + + if (cache != NULL) + { + int i; + + cache->rail = rail; + cache->numCaches = (uint8) rail->settings->num_icon_cache_entries; + cache->numCacheEntries = rail->settings->num_icon_cache_entries; + + cache->caches = xzalloc(cache->numCaches * sizeof(WINDOW_ICON_CACHE)); + + for (i = 0; i < cache->numCaches; i++) + { + cache->caches[i].entries = xzalloc(cache->numCacheEntries * sizeof(rdpIconCache)); + } + } + + return cache; +} + +void icon_cache_free(rdpIconCache* cache) +{ + if (cache != NULL) + { + int i; + + for (i = 0; i < cache->numCaches; i++) + { + xfree(cache->caches[i].entries); + } + + xfree(cache->caches); + + xfree(cache); + } +} + diff --git a/libfreerdp-rail/librail.h b/libfreerdp-rail/librail.h new file mode 100644 index 0000000..50bd07b --- /dev/null +++ b/libfreerdp-rail/librail.h @@ -0,0 +1,31 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LIBRAIL_H +#define __LIBRAIL_H + +#include + +#ifdef WITH_DEBUG_RAIL +#define DEBUG_RAIL(fmt, ...) DEBUG_CLASS(RAIL, fmt, ## __VA_ARGS__) +#else +#define DEBUG_RAIL(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + +#endif /* __LIBRAIL_H */ diff --git a/libfreerdp-rail/rail.c b/libfreerdp-rail/rail.c new file mode 100644 index 0000000..ead0cc3 --- /dev/null +++ b/libfreerdp-rail/rail.c @@ -0,0 +1,149 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "librail.h" + +#include +#include + +static void rail_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpRail* rail = context->rail; + window_list_create(rail->list, orderInfo, window_state); +} + +static void rail_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpRail* rail = context->rail; + window_list_update(rail->list, orderInfo, window_state); +} + +static void rail_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +{ + rdpRail* rail = context->rail; + window_list_delete(rail->list, orderInfo); +} + +static void rail_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon) +{ + rdpIcon* icon; + rdpWindow* window; + rdpRail* rail = context->rail; + + if (window_icon->iconInfo->cacheEntry != 0xFFFF) + { + /* cache icon */ + } + + window = window_list_get_by_id(rail->list, orderInfo->windowId); + + icon = (rdpIcon*) xzalloc(sizeof(rdpIcon)); + icon->entry = window_icon->iconInfo; + icon->big = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? true : false; + + DEBUG_RAIL("Window Icon: %dx%d@%dbpp cbBitsColor:%d cbBitsMask:%d cbColorTable:%d", + window_icon->iconInfo->width, window_icon->iconInfo->height, window_icon->iconInfo->bpp, + window_icon->iconInfo->cbBitsColor, window_icon->iconInfo->cbBitsMask, window_icon->iconInfo->cbColorTable); + + if (icon->big) + window->bigIcon = icon; + else + window->smallIcon = icon; + + IFCALL(rail->rail_SetWindowIcon, rail, window, icon); +} + +static void rail_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon) +{ + +} + +static void rail_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) +{ + +} + +static void rail_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state) +{ + +} + +static void rail_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +{ + +} + +static void rail_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop) +{ + +} + +static void rail_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo) +{ + +} + +void rail_register_update_callbacks(rdpRail* rail, rdpUpdate* update) +{ + rdpWindowUpdate* window = update->window; + + window->WindowCreate = rail_WindowCreate; + window->WindowUpdate = rail_WindowUpdate; + window->WindowDelete = rail_WindowDelete; + window->WindowIcon = rail_WindowIcon; + window->WindowCachedIcon = rail_WindowCachedIcon; + window->NotifyIconCreate = rail_NotifyIconCreate; + window->NotifyIconUpdate = rail_NotifyIconUpdate; + window->NotifyIconDelete = rail_NotifyIconDelete; + window->MonitoredDesktop = rail_MonitoredDesktop; + window->NonMonitoredDesktop = rail_NonMonitoredDesktop; +} + +rdpRail* rail_new(rdpSettings* settings) +{ + rdpRail* rail; + + rail = (rdpRail*) xzalloc(sizeof(rdpRail)); + + if (rail != NULL) + { + rail->settings = settings; + rail->cache = icon_cache_new(rail); + rail->list = window_list_new(rail); + rail->uniconv = freerdp_uniconv_new(); + rail->clrconv = (CLRCONV*) xzalloc(sizeof(CLRCONV)); + } + + return rail; +} + +void rail_free(rdpRail* rail) +{ + if (rail != NULL) + { + icon_cache_free(rail->cache); + window_list_free(rail->list); + freerdp_uniconv_free(rail->uniconv); + xfree(rail->clrconv); + xfree(rail); + } +} diff --git a/libfreerdp-rail/window.c b/libfreerdp-rail/window.c new file mode 100644 index 0000000..39e7cb7 --- /dev/null +++ b/libfreerdp-rail/window.c @@ -0,0 +1,384 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Windows + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "librail.h" + +#include + +struct _WINDOW_STYLE +{ + uint32 style; + const char* name; + boolean multi; +}; +typedef struct _WINDOW_STYLE WINDOW_STYLE; + +static const WINDOW_STYLE WINDOW_STYLES[] = +{ + { WS_BORDER, "WS_BORDER", false }, + { WS_CAPTION, "WS_CAPTION", false }, + { WS_CHILD, "WS_CHILD", false }, + { WS_CLIPCHILDREN, "WS_CLIPCHILDREN", false }, + { WS_CLIPSIBLINGS, "WS_CLIPSIBLINGS", false }, + { WS_DISABLED, "WS_DISABLED", false }, + { WS_DLGFRAME, "WS_DLGFRAME", false }, + { WS_GROUP, "WS_GROUP", false }, + { WS_HSCROLL, "WS_HSCROLL", false }, + { WS_ICONIC, "WS_ICONIC", false }, + { WS_MAXIMIZE, "WS_MAXIMIZE", false }, + { WS_MAXIMIZEBOX, "WS_MAXIMIZEBOX", false }, + { WS_MINIMIZE, "WS_MINIMIZE", false }, + { WS_MINIMIZEBOX, "WS_MINIMIZEBOX", false }, + { WS_OVERLAPPED, "WS_OVERLAPPED", false }, + { WS_OVERLAPPEDWINDOW, "WS_OVERLAPPEDWINDOW", true }, + { WS_POPUP, "WS_POPUP", false }, + { WS_POPUPWINDOW, "WS_POPUPWINDOW", true }, + { WS_SIZEBOX, "WS_SIZEBOX", false }, + { WS_SYSMENU, "WS_SYSMENU", false }, + { WS_TABSTOP, "WS_TABSTOP", false }, + { WS_THICKFRAME, "WS_THICKFRAME", false }, + { WS_VISIBLE, "WS_VISIBLE", false } +}; + +static const WINDOW_STYLE EXTENDED_WINDOW_STYLES[] = +{ + { WS_EX_ACCEPTFILES, "WS_EX_ACCEPTFILES", false }, + { WS_EX_APPWINDOW, "WS_EX_APPWINDOW", false }, + { WS_EX_CLIENTEDGE, "WS_EX_CLIENTEDGE", false }, + { WS_EX_COMPOSITED, "WS_EX_COMPOSITED", false }, + { WS_EX_CONTEXTHELP, "WS_EX_CONTEXTHELP", false }, + { WS_EX_CONTROLPARENT, "WS_EX_CONTROLPARENT", false }, + { WS_EX_DLGMODALFRAME, "WS_EX_DLGMODALFRAME", false }, + { WS_EX_LAYERED, "WS_EX_LAYERED", false }, + { WS_EX_LAYOUTRTL, "WS_EX_LAYOUTRTL", false }, + { WS_EX_LEFT, "WS_EX_LEFT", false }, + { WS_EX_LEFTSCROLLBAR, "WS_EX_LEFTSCROLLBAR", false }, + { WS_EX_LTRREADING, "WS_EX_LTRREADING", false }, + { WS_EX_MDICHILD, "WS_EX_MDICHILD", false }, + { WS_EX_NOACTIVATE, "WS_EX_NOACTIVATE", false }, + { WS_EX_NOINHERITLAYOUT, "WS_EX_NOINHERITLAYOUT", false }, + { WS_EX_NOPARENTNOTIFY, "WS_EX_NOPARENTNOTIFY", false }, + { WS_EX_OVERLAPPEDWINDOW, "WS_EX_OVERLAPPEDWINDOW", true }, + { WS_EX_PALETTEWINDOW, "WS_EX_PALETTEWINDOW", true }, + { WS_EX_RIGHT, "WS_EX_RIGHT", false }, + { WS_EX_RIGHTSCROLLBAR, "WS_EX_RIGHTSCROLLBAR", false }, + { WS_EX_RTLREADING, "WS_EX_RTLREADING", false }, + { WS_EX_STATICEDGE, "WS_EX_STATICEDGE", false }, + { WS_EX_TOOLWINDOW, "WS_EX_TOOLWINDOW", false }, + { WS_EX_TOPMOST, "WS_EX_TOPMOST", false }, + { WS_EX_TRANSPARENT, "WS_EX_TRANSPARENT", false }, + { WS_EX_WINDOWEDGE, "WS_EX_WINDOWEDGE", false } +}; + +void print_window_styles(uint32 style) +{ + int i; + + printf("Window Styles:\n{\n"); + for (i = 0; i < sizeof(WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++) + { + if (style & WINDOW_STYLES[i].style) + { + if (WINDOW_STYLES[i].multi) + { + if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style) + continue; + } + + printf("\t%s\n", WINDOW_STYLES[i].name); + } + } + printf("}\n"); +} + +void print_extended_window_styles(uint32 style) +{ + int i; + + printf("Extended Window Styles:\n{\n"); + for (i = 0; i < sizeof(EXTENDED_WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++) + { + if (style & EXTENDED_WINDOW_STYLES[i].style) + { + if (EXTENDED_WINDOW_STYLES[i].multi) + { + if ((style & EXTENDED_WINDOW_STYLES[i].style) != EXTENDED_WINDOW_STYLES[i].style) + continue; + } + + printf("\t%s\n", EXTENDED_WINDOW_STYLES[i].name); + } + } + printf("}\n"); +} + +void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + window->fieldFlags = orderInfo->fieldFlags; + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER) + { + window->ownerWindowId = window_state->ownerWindowId; + DEBUG_RAIL("ownerWindowId:0x%08X", window->ownerWindowId); + } + + DEBUG_RAIL("windowId=0x%X ownerWindowId=0x%X", + window->windowId, window->ownerWindowId); + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE) + { + window->style = window_state->style; + window->extendedStyle = window_state->extendedStyle; + +#ifdef WITH_DEBUG_RAIL + print_window_styles(window->style); + print_extended_window_styles(window->extendedStyle); +#endif + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW) + { + window->showState = window_state->showState; + DEBUG_RAIL("ShowState:%d", window->showState); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) + { + window->titleInfo.length = window_state->titleInfo.length; + window->titleInfo.string = xmalloc(window_state->titleInfo.length); + memcpy(window->titleInfo.string, window_state->titleInfo.string, window->titleInfo.length); + +#ifdef WITH_DEBUG_RAIL + freerdp_hexdump(window->titleInfo.string, window->titleInfo.length); +#endif + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + window->clientOffsetX = window_state->clientOffsetX; + window->clientOffsetY = window_state->clientOffsetY; + + DEBUG_RAIL("Client Area Offset: (%d, %d)", + window->clientOffsetX, window->clientOffsetY); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + window->clientAreaWidth = window_state->clientAreaWidth; + window->clientAreaHeight = window_state->clientAreaHeight; + + DEBUG_RAIL("Client Area Size: (%d, %d)", + window->clientAreaWidth, window->clientAreaHeight); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + window->RPContent = window_state->RPContent; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + window->rootParentHandle = window_state->rootParentHandle; + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + window->windowOffsetX = window_state->windowOffsetX; + window->windowOffsetY = window_state->windowOffsetY; + + DEBUG_RAIL("Window Offset: (%d, %d)", + window->windowOffsetX, window->windowOffsetY); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + window->windowClientDeltaX = window_state->windowClientDeltaX; + window->windowClientDeltaY = window_state->windowClientDeltaY; + + DEBUG_RAIL("Window Client Delta: (%d, %d)", + window->windowClientDeltaX, window->windowClientDeltaY); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) + { + window->windowWidth = window_state->windowWidth; + window->windowHeight = window_state->windowHeight; + + DEBUG_RAIL("Window Size: (%d, %d)", + window->windowWidth, window->windowHeight); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + int i; + + if (window->windowRects != NULL) + xfree(window->windowRects); + + window->windowRects = window_state->windowRects; + window->numWindowRects = window_state->numWindowRects; + + for (i = 0; i < (int) window_state->numWindowRects; i++) + { + DEBUG_RAIL("Window Rect #%d: left:%d top:%d right:%d bottom:%d", i, + window_state->windowRects[i].left, window_state->windowRects[i].top, + window_state->windowRects[i].right, window_state->windowRects[i].bottom); + } + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + window->visibleOffsetX = window_state->visibleOffsetX; + window->visibleOffsetY = window_state->visibleOffsetY; + + DEBUG_RAIL("Window Visible Offset: (%d, %d)", + window->visibleOffsetX, window->visibleOffsetY); + } + + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + int i; + + if (window->visibilityRects != NULL) + xfree(window->visibilityRects); + + window->visibilityRects = window_state->visibilityRects; + window->numVisibilityRects = window_state->numVisibilityRects; + + for (i = 0; i < (int) window_state->numVisibilityRects; i++) + { + DEBUG_RAIL("Visibility Rect #%d: left:%d top:%d right:%d bottom:%d", i, + window_state->visibilityRects[i].left, window_state->visibilityRects[i].top, + window_state->visibilityRects[i].right, window_state->visibilityRects[i].bottom); + } + } +} + +void rail_CreateWindow(rdpRail* rail, rdpWindow* window) +{ + if (window->titleInfo.length > 0) + { + window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length); + } + else + { + window->title = (char*) xmalloc(sizeof("RAIL")); + memcpy(window->title, "RAIL", sizeof("RAIL")); + } + + IFCALL(rail->rail_CreateWindow, rail, window); + + if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + IFCALL(rail->rail_SetWindowRects, rail, window); + } + if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + IFCALL(rail->rail_SetWindowVisibilityRects, rail, window); + } +} + +void rail_UpdateWindow(rdpRail* rail, rdpWindow* window) +{ + if (window->fieldFlags & WINDOW_ORDER_FIELD_OWNER) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_STYLE) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_SHOW) + { + IFCALL(rail->rail_ShowWindow, rail, window, window->showState); + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_TITLE) + { + if (window->title != NULL) + xfree(window->title); + + window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length); + + IFCALL(rail->rail_SetWindowText, rail, window); + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + + } + + if ((window->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || + (window->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)) + { + IFCALL(rail->rail_MoveWindow, rail, window); + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + { + IFCALL(rail->rail_SetWindowRects, rail, window); + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + + } + + if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) + { + IFCALL(rail->rail_SetWindowVisibilityRects, rail, window); + } +} + +void rail_DestroyWindow(rdpRail* rail, rdpWindow* window) +{ + IFCALL(rail->rail_DestroyWindow, rail, window); + + if (window != NULL) + { + xfree(window); + } +} diff --git a/libfreerdp-rail/window_list.c b/libfreerdp-rail/window_list.c new file mode 100644 index 0000000..3408011 --- /dev/null +++ b/libfreerdp-rail/window_list.c @@ -0,0 +1,200 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * RAIL Window List + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "librail.h" + +#include + +void window_list_rewind(rdpWindowList* list) +{ + list->iterator = list->head; +} + +boolean window_list_has_next(rdpWindowList* list) +{ + if (list->iterator != NULL) + { + if (list->iterator != NULL) + return true; + } + + return false; +} + +rdpWindow* window_list_get_next(rdpWindowList* list) +{ + rdpWindow* next = NULL; + + if (list->iterator != NULL) + { + next = list->iterator; + list->iterator = list->iterator->next; + } + + return next; +} + +rdpWindow* window_list_get_by_extra_id(rdpWindowList* list, void* extraId) +{ + rdpWindow* window; + + window = list->head; + + if (window == NULL) + return NULL; + + while (window != NULL) + { + if (window->extraId == extraId) + return window; + + window = window->next; + } + + return NULL; +} + +rdpWindow* window_list_get_by_id(rdpWindowList* list, uint32 windowId) +{ + rdpWindow* window; + + window = list->head; + + if (window == NULL) + return NULL; + + while (window != NULL) + { + if (window->windowId == windowId) + return window; + + window = window->next; + } + + return NULL; +} + +void window_list_create(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpWindow* window; + + window = (rdpWindow*) xzalloc(sizeof(rdpWindow)); + + if (window == NULL) + return; + + window->windowId = orderInfo->windowId; + + if (list->head == NULL) + { + list->head = list->tail = window; + window->prev = NULL; + window->next = NULL; + } + else + { + window->prev = list->tail; + list->tail->next = window; + window->next = NULL; + list->tail = window; + } + + window->windowId = orderInfo->windowId; + + window_state_update(window, orderInfo, window_state); + + rail_CreateWindow(list->rail, window); +} + +void window_list_update(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state) +{ + rdpWindow* window; + + window = window_list_get_by_id(list, orderInfo->windowId); + + if (window == NULL) + return; + + window_state_update(window, orderInfo, window_state); + + rail_UpdateWindow(list->rail, window); +} + +void window_list_delete(rdpWindowList* list, WINDOW_ORDER_INFO* orderInfo) +{ + rdpWindow* prev; + rdpWindow* next; + rdpWindow* window; + + window = window_list_get_by_id(list, orderInfo->windowId); + + if (window == NULL) + return; + + prev = window->prev; + next = window->next; + + if (prev != NULL) + prev->next = next; + + if (next != NULL) + next->prev = prev; + + if (list->head == list->tail) + { + list->head = list->tail = NULL; + } + else + { + if (list->head == window) + list->head = next; + + if (list->tail == window) + list->tail = prev; + } + + rail_DestroyWindow(list->rail, window); +} + +rdpWindowList* window_list_new(rdpRail* rail) +{ + rdpWindowList* list; + + list = (rdpWindowList*) xzalloc(sizeof(rdpWindowList)); + + if (list != NULL) + { + list->head = NULL; + list->tail = NULL; + list->rail = rail; + } + + return list; +} + +void window_list_free(rdpWindowList* list) +{ + if (list != NULL) + { + xfree(list); + } +} diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt new file mode 100644 index 0000000..6757afc --- /dev/null +++ b/libfreerdp-utils/CMakeLists.txt @@ -0,0 +1,67 @@ +# FreeRDP: A Remote Desktop Protocol Client +# libfreerdp-utils cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(CMAKE_THREAD_PREFER_PTHREAD) +find_required_package(Threads) + +set(FREERDP_UTILS_SRCS + args.c + blob.c + dsp.c + event.c + bitmap.c + hexdump.c + list.c + file.c + load_plugin.c + memory.c + mutex.c + passphrase.c + pcap.c + profiler.c + rail.c + rect.c + registry.c + semaphore.c + signal.c + sleep.c + stopwatch.c + stream.c + string.c + svc_plugin.c + thread.c + unicode.c + wait_obj.c) + +add_definitions(-DPLUGIN_PATH="${FREERDP_PLUGIN_PATH}") + +add_library(freerdp-utils ${FREERDP_UTILS_SRCS}) + +set_target_properties(freerdp-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") + +target_link_libraries(freerdp-utils ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS}) + +if(WIN32) + target_link_libraries(freerdp-utils ws2_32) +endif() +if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) + target_link_libraries(freerdp-utils rt) +endif() + +install(TARGETS freerdp-utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c new file mode 100644 index 0000000..cf10519 --- /dev/null +++ b/libfreerdp-utils/args.c @@ -0,0 +1,695 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Arguments Parsing + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include + +/** + * Parse command-line arguments and update rdpSettings members accordingly. + * @param settings pointer to rdpSettings struct to be updated. + * @param argc number of arguments available. + * @param argv string array of the arguments. + * @param plugin_callback function to be called when a plugin needs to be loaded. + * @param plugin_user_data pointer to be passed to the plugin_callback function. + * @param ui_callback function to be called when a UI-specific argument is being processed. + * @param ui_user_data pointer to be passed to the ui_callback function. + * @return number of arguments that were parsed, or FREERDP_ARGS_PARSE_RESULT on failure or --version/--help + */ +int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, + ProcessPluginArgs plugin_callback, void* plugin_user_data, + ProcessUIArgs ui_callback, void* ui_user_data) +{ + int t; + char* p; + int i, j; + int index = 1; + int num_extensions = 0; + RDP_PLUGIN_DATA* plugin_data; + + while (index < argc) + { + if ((strcmp("-h", argv[index]) == 0 ) || (strcmp("--help", argv[index]) == 0 )) + { + printf("\n" + "FreeRDP - A Free Remote Desktop Protocol Client\n" + "See http://www.freerdp.com for more information\n" + "\n" + "Usage: %s [options] server:port\n" + " -0: connect to console session\n" + " -a: set color depth in bit, default is 16\n" + " -c: initial working directory\n" + " -D: hide window decorations\n" + " -T: window title\n" + " -d: domain\n" + " -f: fullscreen mode\n" + " -g: set geometry, using format WxH or X%% or 'workarea', default is 1024x768\n" + " -h: print this help\n" + " -k: set keyboard layout ID\n" + " -K: do not interfere with window manager bindings\n" + " -m: don't send mouse motion events\n" + " -n: hostname\n" + " -o: console audio\n" + " -p: password\n" + " -s: set startup-shell\n" + " -t: alternative port number, default is 3389\n" + " -u: username\n" + " -x: performance flags (m[odem], b[roadband] or l[an])\n" + " -X: embed into another window with a given XID.\n" + " -z: enable compression\n" + " --app: RemoteApp connection. This implies -g workarea\n" + " --ext: load an extension\n" + " --no-auth: disable authentication\n" + " --no-fastpath: disable fast-path\n" + " --gdi: graphics rendering (hw, sw)\n" + " --no-osb: disable offscreen bitmaps\n" + " --no-bmp-cache: disable bitmap cache\n" + " --plugin: load a virtual channel plugin\n" + " --rfx: enable RemoteFX\n" + " --rfx-mode: RemoteFX operational flags (v[ideo], i[mage]), default is video\n" + " --nsc: enable NSCodec (experimental)\n" + " --disable-wallpaper: disables wallpaper\n" + " --composition: enable desktop composition\n" + " --disable-full-window-drag: disables full window drag\n" + " --disable-menu-animations: disables menu animations\n" + " --disable-theming: disables theming\n" + " --no-rdp: disable Standard RDP encryption\n" + " --no-tls: disable TLS encryption\n" + " --no-nla: disable network level authentication\n" + " --ntlm: force NTLM authentication protocol version (1 or 2)\n" + " --ignore-certificate: ignore verification of logon certificate\n" + " --sec: force protocol security (rdp, tls or nla)\n" + " --secure-checksum: use salted checksums with Standard RDP encryption\n" + " --version: print version information\n" + "\n", argv[0]); + return FREERDP_ARGS_PARSE_HELP; //TODO: What is the correct return + } + else if (strcmp("-a", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing color depth\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->color_depth = atoi(argv[index]); + } + else if (strcmp("-u", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing username\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->username = xstrdup(argv[index]); + } + else if (strcmp("-p", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing password\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->password = xstrdup(argv[index]); + settings->autologon = 1; + + /* + * Overwrite original password which could be revealed by a simple "ps aux" command. + * This approach won't hide the password length, but it is better than nothing. + */ + + memset(argv[index], '*', strlen(argv[index])); + } + else if (strcmp("-d", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing domain\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->domain = xstrdup(argv[index]); + } + else if (strcmp("-s", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing shell\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->shell = xstrdup(argv[index]); + } + else if (strcmp("-c", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing directory\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->directory = xstrdup(argv[index]); + } + else if (strcmp("-g", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing dimensions\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + + if (strncmp("workarea", argv[index], 1) == 0) + { + settings->workarea = true; + } + else + { + settings->width = (uint16) strtol(argv[index], &p, 10); + + if (*p == 'x') + { + settings->height = (uint16) strtol(p + 1, &p, 10); + } + if (*p == '%') + { + settings->percent_screen = settings->width; + if (settings->percent_screen <= 0 || settings->percent_screen > 100) + { + printf("invalid geometry percentage\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else + { + if (ui_callback != NULL) + ui_callback(settings, "-g", p, ui_user_data); + } + } + } + else if (strcmp("-f", argv[index]) == 0) + { + settings->fullscreen = true; + } + else if (strcmp("-D", argv[index]) == 0) + { + settings->decorations = false; + } + else if (strcmp("-T", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing window title\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + + settings->window_title = xstrdup(argv[index]); + } + else if (strcmp("-t", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing port number\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->port = atoi(argv[index]); + } + else if (strcmp("-k", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing keyboard layout id\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + sscanf(argv[index], "%X", &(settings->kbd_layout)); + } + else if (strcmp("-K", argv[index]) == 0) + { + settings->grab_keyboard = false; + } + else if (strcmp("-n", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing client hostname\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + strncpy(settings->client_hostname, argv[index], sizeof(settings->client_hostname) - 1); + settings->client_hostname[sizeof(settings->client_hostname) - 1] = 0; + } + else if (strcmp("-o", argv[index]) == 0) + { + settings->console_audio = true; + } + else if (strcmp("-0", argv[index]) == 0) + { + settings->console_session = true; + } + else if (strcmp("-z", argv[index]) == 0) + { + settings->compression = true; + } + else if (strcmp("--ntlm", argv[index]) == 0) + { + index++; + + settings->ntlm_version = atoi(argv[index]); + + if (settings->ntlm_version != 2) + settings->ntlm_version = 1; + } + else if (strcmp("--no-glyph-cache", argv[index]) == 0) + { + settings->glyph_cache = false; + } + else if (strcmp("--no-osb", argv[index]) == 0) + { + settings->offscreen_bitmap_cache = false; + } + else if (strcmp("--no-bmp-cache", argv[index]) == 0) + { + settings->bitmap_cache = false; + } + else if (strcmp("--no-auth", argv[index]) == 0) + { + settings->authentication = false; + } + else if (strcmp("--ignore-certificate", argv[index]) == 0) + { + settings->ignore_certificate = true; + } + else if (strcmp("--certificate-name", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing certificate name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + + settings->certificate_name = xstrdup(argv[index]); + } + else if (strcmp("--no-fastpath", argv[index]) == 0) + { + settings->fastpath_input = false; + settings->fastpath_output = false; + } + else if (strcmp("--gdi", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing GDI backend\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + if (strncmp("sw", argv[index], 1) == 0) /* software */ + { + settings->sw_gdi = true; + } + else if (strncmp("hw", argv[index], 1) == 0) /* hardware */ + { + settings->sw_gdi = false; + } + else + { + printf("unknown GDI backend\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else if (strcmp("--rfx", argv[index]) == 0) + { + settings->rfx_codec = true; + settings->fastpath_output = true; + settings->color_depth = 32; + settings->frame_acknowledge = false; + settings->performance_flags = PERF_FLAG_NONE; + settings->large_pointer = true; + } + else if (strcmp("--rfx-mode", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing RemoteFX mode flag\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + if (argv[index][0] == 'v') /* video */ + { + settings->rfx_codec_mode = 0x00; + } + else if (argv[index][0] == 'i') /* image */ + { + settings->rfx_codec_mode = 0x02; + } + else + { + printf("unknown RemoteFX mode flag\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else if (strcmp("--nsc", argv[index]) == 0) + { + settings->ns_codec = true; + } + else if (strcmp("--dump-rfx", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing file name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->dump_rfx_file = xstrdup(argv[index]); + settings->dump_rfx = true; + } + else if (strcmp("--play-rfx", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing file name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + settings->play_rfx_file = xstrdup(argv[index]); + settings->play_rfx = true; + } + else if (strcmp("--fonts", argv[index]) == 0) + { + settings->smooth_fonts = true; + } + else if (strcmp("--disable-wallpaper", argv[index]) == 0) + { + settings->disable_wallpaper = true; + } + else if (strcmp("--disable-full-window-drag", argv[index]) == 0) + { + settings->disable_full_window_drag = true; + } + else if (strcmp("--disable-menu-animations", argv[index]) == 0) + { + settings->disable_menu_animations = true; + } + else if (strcmp("--disable-theming", argv[index]) == 0) + { + settings->disable_theming = true; + } + else if (strcmp("--composition", argv[index]) == 0) + { + settings->desktop_composition = true; + } + else if (strcmp("--no-motion", argv[index]) == 0) + { + settings->mouse_motion = false; + } + else if (strcmp("--app", argv[index]) == 0) + { + settings->remote_app = true; + settings->rail_langbar_supported = true; + settings->workarea = true; + settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG; + } + else if (strcmp("-x", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing performance flag\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + if (argv[index][0] == 'm') /* modem */ + { + settings->performance_flags = PERF_DISABLE_WALLPAPER | + PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS | + PERF_DISABLE_THEMING; + + settings->connection_type = CONNECTION_TYPE_MODEM; + } + else if (argv[index][0] == 'b') /* broadband */ + { + settings->performance_flags = PERF_DISABLE_WALLPAPER; + settings->connection_type = CONNECTION_TYPE_BROADBAND_HIGH; + } + else if (argv[index][0] == 'l') /* lan */ + { + settings->performance_flags = PERF_FLAG_NONE; + settings->connection_type = CONNECTION_TYPE_LAN; + } + else + { + settings->performance_flags = strtol(argv[index], 0, 16); + } + } + else if (strcmp("-X", argv[index]) == 0) + { + index++; + + if (index == argc) + { + printf("missing parent window XID\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + + settings->parent_window_xid = strtoul(argv[index], NULL, 16); + + if (settings->parent_window_xid == 0) + { + printf("invalid parent window XID\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else if (strcmp("--no-rdp", argv[index]) == 0) + { + settings->rdp_security = false; + } + else if (strcmp("--no-tls", argv[index]) == 0) + { + settings->tls_security = false; + } + else if (strcmp("--no-nla", argv[index]) == 0) + { + settings->nla_security = false; + } + else if (strcmp("--sec", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing protocol security\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + if (strncmp("rdp", argv[index], 1) == 0) /* Standard RDP */ + { + settings->rdp_security = true; + settings->tls_security = false; + settings->nla_security = false; + settings->encryption = true; + settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; + settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; + } + else if (strncmp("tls", argv[index], 1) == 0) /* TLS */ + { + settings->rdp_security = false; + settings->tls_security = true; + settings->nla_security = false; + } + else if (strncmp("nla", argv[index], 1) == 0) /* NLA */ + { + settings->rdp_security = false; + settings->tls_security = false; + settings->nla_security = true; + } + else + { + printf("unknown protocol security\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else if (strcmp("--plugin", argv[index]) == 0) + { + index++; + t = index; + if (index == argc) + { + printf("missing plugin name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + plugin_data = NULL; + if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0) + { + index += 2; + i = 0; + while (index < argc && strcmp("--", argv[index]) != 0) + { + if (plugin_data == NULL) + plugin_data = (RDP_PLUGIN_DATA*) xmalloc(sizeof(RDP_PLUGIN_DATA) * (i + 2)); + else + plugin_data = (RDP_PLUGIN_DATA*) xrealloc(plugin_data, sizeof(RDP_PLUGIN_DATA) * (i + 2)); + + plugin_data[i].size = sizeof(RDP_PLUGIN_DATA); + plugin_data[i].data[0] = NULL; + plugin_data[i].data[1] = NULL; + plugin_data[i].data[2] = NULL; + plugin_data[i].data[3] = NULL; + plugin_data[i + 1].size = 0; + + for (j = 0, p = argv[index]; j < 4 && p != NULL; j++) + { + if (*p == '\'') + { + plugin_data[i].data[j] = p + 1; + p = strchr(p + 1, '\''); + if (p) + *p++ = 0; + } + else + plugin_data[i].data[j] = p; + + p = strchr(p, ':'); + if (p != NULL) + *p++ = 0; + } + index++; + i++; + } + } + + if (plugin_callback != NULL) + { + if (!plugin_callback(settings, argv[t], plugin_data, plugin_user_data)) + return FREERDP_ARGS_PARSE_FAILURE; + } + } + else if (strcmp("--ext", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing extension name\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + if (num_extensions >= sizeof(settings->extensions) / sizeof(struct rdp_ext_set)) + { + printf("maximum extensions reached\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + snprintf(settings->extensions[num_extensions].name, + sizeof(settings->extensions[num_extensions].name), + "%s", argv[index]); + settings->extensions[num_extensions].data = NULL; + if (index < argc - 1 && strcmp("--data", argv[index + 1]) == 0) + { + index += 2; + settings->extensions[num_extensions].data = argv[index]; + i = 0; + while (index < argc && strcmp("--", argv[index]) != 0) + { + index++; + i++; + } + } + num_extensions++; + } + else if (strcmp("--secure-checksum", argv[index]) == 0) + { + settings->secure_checksum = true; + } + else if (strcmp("--version", argv[index]) == 0) + { + printf("This is FreeRDP version %s\n", FREERDP_VERSION_FULL); + return FREERDP_ARGS_PARSE_VERSION; + } + else if (argv[index][0] != '-') + { + if (argv[index][0] == '[' && (p = strchr(argv[index], ']')) + && (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':')))) + { + /* Either "[...]" or "[...]:..." with at most one : after the brackets */ + settings->hostname = xstrdup(argv[index] + 1); + if ((p = strchr((char*)settings->hostname, ']'))) + { + *p = 0; + if (p[1] == ':') + settings->port = atoi(p + 2); + } + } + else + { + /* Port number is cut off and used if exactly one : in the string */ + settings->hostname = xstrdup(argv[index]); + if ((p = strchr((char*)settings->hostname, ':')) && !strchr(p + 1, ':')) + { + *p = 0; + settings->port = atoi(p + 1); + } + } + /* server is the last argument for the current session. arguments + followed will be parsed for the next session. */ + index++; + + if (settings->smooth_fonts) + settings->performance_flags |= PERF_ENABLE_FONT_SMOOTHING; + + if (settings->desktop_composition) + settings->performance_flags |= PERF_ENABLE_DESKTOP_COMPOSITION; + + if (settings->disable_wallpaper) + settings->performance_flags |= PERF_DISABLE_WALLPAPER; + + if (settings->disable_full_window_drag) + settings->performance_flags |= PERF_DISABLE_FULLWINDOWDRAG; + + if (settings->disable_menu_animations) + settings->performance_flags |= PERF_DISABLE_MENUANIMATIONS; + + if (settings->disable_theming) + settings->performance_flags |= PERF_DISABLE_THEMING; + + return index; + } + else + { + if (ui_callback != NULL) + { + t = ui_callback(settings, argv[index], (index + 1 < argc && argv[index + 1][0] != '-' ? + argv[index + 1] : NULL), ui_user_data); + if (t == 0) + { + printf("invalid option: %s\n", argv[index]); + return FREERDP_ARGS_PARSE_FAILURE; + } + index += t - 1; + } + } + index++; + } + printf("missing server name\n"); + return FREERDP_ARGS_PARSE_FAILURE; +} diff --git a/libfreerdp-utils/bitmap.c b/libfreerdp-utils/bitmap.c new file mode 100644 index 0000000..bbcfbdb --- /dev/null +++ b/libfreerdp-utils/bitmap.c @@ -0,0 +1,105 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Bitmap File Format Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + +typedef struct +{ + uint8 magic[2]; +} bmpfile_magic; + +typedef struct +{ + uint32 filesz; + uint16 creator1; + uint16 creator2; + uint32 bmp_offset; +} bmpfile_header; + +typedef struct +{ + uint32 header_sz; + sint32 width; + sint32 height; + uint16 nplanes; + uint16 bitspp; + uint32 compress_type; + uint32 bmp_bytesz; + sint32 hres; + sint32 vres; + uint32 ncolors; + uint32 nimpcolors; +} BITMAPINFOHEADER; + +void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp) +{ + FILE* fp; + bmpfile_magic magic; + bmpfile_header header; + BITMAPINFOHEADER info_header; + + fp = fopen(filename, "w+b"); + + if (fp == NULL) + { + printf("failed to open file %s\n", filename); + return; + } + + magic.magic[0] = 'B'; + magic.magic[1] = 'M'; + + header.creator1 = 0; + header.creator2 = 0; + + header.bmp_offset = + sizeof(bmpfile_magic) + + sizeof(bmpfile_header) + + sizeof(BITMAPINFOHEADER); + + info_header.bmp_bytesz = width * height * (bpp / 8); + + header.filesz = + header.bmp_offset + + info_header.bmp_bytesz; + + info_header.width = width; + info_header.height = (-1) * height; + info_header.nplanes = 1; + info_header.bitspp = bpp; + info_header.compress_type = 0; + info_header.hres = width; + info_header.vres = height; + info_header.ncolors = 0; + info_header.nimpcolors = 0; + info_header.header_sz = sizeof(BITMAPINFOHEADER); + + fwrite((void*) &magic, sizeof(bmpfile_magic), 1, fp); + fwrite((void*) &header, sizeof(bmpfile_header), 1, fp); + fwrite((void*) &info_header, sizeof(BITMAPINFOHEADER), 1, fp); + fwrite((void*) data, info_header.bmp_bytesz, 1, fp); + + fclose(fp); +} + diff --git a/libfreerdp-utils/blob.c b/libfreerdp-utils/blob.c new file mode 100644 index 0000000..b08c6e0 --- /dev/null +++ b/libfreerdp-utils/blob.c @@ -0,0 +1,47 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * BLOB Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +/** + * Allocate memory for data blob. + * @param blob blob structure + * @param length memory length + */ + +void freerdp_blob_alloc(rdpBlob* blob, int length) +{ + blob->data = xmalloc(length); + blob->length = length; +} + +/** + * Free memory allocated for data blob. + * @param blob + */ + +void freerdp_blob_free(rdpBlob* blob) +{ + if (blob->data) + xfree(blob->data); + + blob->length = 0; +} diff --git a/libfreerdp-utils/dsp.c b/libfreerdp-utils/dsp.c new file mode 100644 index 0000000..c7d013f --- /dev/null +++ b/libfreerdp-utils/dsp.c @@ -0,0 +1,336 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Digital Sound Processing + * + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include + +uint8* dsp_resample(uint8* src, int bytes_per_sample, + uint32 schan, uint32 srate, int sframes, + uint32 rchan, uint32 rrate, int * prframes) +{ + uint8* dst; + uint8* p; + int rframes; + int rsize; + int i, j; + int n1, n2; + int sbytes, rbytes; + + sbytes = bytes_per_sample * schan; + rbytes = bytes_per_sample * rchan; + rframes = sframes * rrate / srate; + *prframes = rframes; + rsize = rbytes * rframes; + dst = (uint8*) xzalloc(rsize); + + p = dst; + for (i = 0; i < rframes; i++) + { + n1 = i * srate / rrate; + if (n1 >= sframes) + n1 = sframes - 1; + n2 = (n1 * rrate == i * srate || n1 == sframes - 1 ? n1 : n1 + 1); + for (j = 0; j < rbytes; j++) + { + /* Nearest Interpolation, probably the easiest, but works */ + *p++ = (i * srate - n1 * rrate > n2 * rrate - i * srate ? + src[n2 * sbytes + (j % sbytes)] : + src[n1 * sbytes + (j % sbytes)]); + } + } + + return dst; +} + +/** + * Microsoft IMA ADPCM specification: + * + * http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM + * http://wiki.multimedia.cx/index.php?title=IMA_ADPCM + */ + +static const sint16 ima_step_index_table[] = +{ + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 +}; + +static const sint16 ima_step_size_table[] = +{ + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +static uint16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm, + int channel, uint8 sample) +{ + sint32 ss; + sint32 d; + + ss = ima_step_size_table[adpcm->last_step[channel]]; + d = (ss >> 3); + if (sample & 1) + d += (ss >> 2); + if (sample & 2) + d += (ss >> 1); + if (sample & 4) + d += ss; + if (sample & 8) + d = -d; + d += adpcm->last_sample[channel]; + + if (d < -32768) + d = -32768; + else if (d > 32767) + d = 32767; + + adpcm->last_sample[channel] = (sint16) d; + + adpcm->last_step[channel] += ima_step_index_table[sample]; + if (adpcm->last_step[channel] < 0) + adpcm->last_step[channel] = 0; + else if (adpcm->last_step[channel] > 88) + adpcm->last_step[channel] = 88; + + return (uint16) d; +} + +uint8* dsp_decode_ima_adpcm(ADPCM* adpcm, + uint8* src, int size, int channels, int block_size, int* out_size) +{ + uint8* out; + uint8* dst; + uint8 sample; + uint16 decoded; + int channel; + int i; + + *out_size = size * 4; + out = (uint8 *) xzalloc(*out_size); + dst = out; + while (size > 0) + { + if (size % block_size == 0) + { + adpcm->last_sample[0] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8)); + adpcm->last_step[0] = (sint16) (*(src + 2)); + src += 4; + size -= 4; + *out_size -= 16; + if (channels > 1) + { + adpcm->last_sample[1] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8)); + adpcm->last_step[1] = (sint16) (*(src + 2)); + src += 4; + size -= 4; + *out_size -= 16; + } + } + + if (channels > 1) + { + for (i = 0; i < 8; i++) + { + channel = (i < 4 ? 0 : 1); + sample = ((*src) & 0x0f); + decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample); + dst[((i & 3) << 3) + (channel << 1)] = (decoded & 0xff); + dst[((i & 3) << 3) + (channel << 1) + 1] = (decoded >> 8); + sample = ((*src) >> 4); + decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample); + dst[((i & 3) << 3) + (channel << 1) + 4] = (decoded & 0xff); + dst[((i & 3) << 3) + (channel << 1) + 5] = (decoded >> 8); + src++; + } + dst += 32; + size -= 8; + } + else + { + sample = ((*src) & 0x0f); + decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample); + *dst++ = (decoded & 0xff); + *dst++ = (decoded >> 8); + sample = ((*src) >> 4); + decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample); + *dst++ = (decoded & 0xff); + *dst++ = (decoded >> 8); + src++; + size--; + } + } + return out; +} + +/** + * 0 1 2 3 + * 2 0 6 4 10 8 14 12 + * + * 4 5 6 7 + * 3 1 7 5 11 9 15 13 + */ +static const struct +{ + uint8 byte_num; + uint8 byte_shift; +} ima_stereo_encode_map[] = +{ + { 0, 0 }, + { 4, 0 }, + { 0, 4 }, + { 4, 4 }, + { 1, 0 }, + { 5, 0 }, + { 1, 4 }, + { 5, 4 }, + { 2, 0 }, + { 6, 0 }, + { 2, 4 }, + { 6, 4 }, + { 3, 0 }, + { 7, 0 }, + { 3, 4 }, + { 7, 4 } +}; + +static uint8 dsp_encode_ima_adpcm_sample(ADPCM* adpcm, + int channel, sint16 sample) +{ + sint32 e; + sint32 d; + sint32 ss; + uint8 enc; + sint32 diff; + + ss = ima_step_size_table[adpcm->last_step[channel]]; + d = e = sample - adpcm->last_sample[channel]; + diff = ss >> 3; + enc = 0; + if (e < 0) + { + enc = 8; + e = -e; + } + if (e >= ss) + { + enc |= 4; + e -= ss; + } + ss >>= 1; + if (e >= ss) + { + enc |= 2; + e -= ss; + } + ss >>= 1; + if (e >= ss) + { + enc |= 1; + e -= ss; + } + + if (d < 0) + diff = d + e - diff; + else + diff = d - e + diff; + + diff += adpcm->last_sample[channel]; + if (diff < -32768) + diff = -32768; + else if (diff > 32767) + diff = 32767; + adpcm->last_sample[channel] = (sint16) diff; + + adpcm->last_step[channel] += ima_step_index_table[enc]; + if (adpcm->last_step[channel] < 0) + adpcm->last_step[channel] = 0; + else if (adpcm->last_step[channel] > 88) + adpcm->last_step[channel] = 88; + + return enc; +} + +uint8* dsp_encode_ima_adpcm(ADPCM* adpcm, + uint8* src, int size, int channels, int block_size, int* out_size) +{ + uint8* out; + uint8* dst; + sint16 sample; + uint8 encoded; + int i; + + out = (uint8*) xzalloc(size / 2); + dst = out; + while (size > 0) + { + if ((dst - out) % block_size == 0) + { + *dst++ = adpcm->last_sample[0] & 0xff; + *dst++ = (adpcm->last_sample[0] >> 8) & 0xff; + *dst++ = (uint8) adpcm->last_step[0]; + *dst++ = 0; + if (channels > 1) + { + *dst++ = adpcm->last_sample[1] & 0xff; + *dst++ = (adpcm->last_sample[1] >> 8) & 0xff; + *dst++ = (uint8) adpcm->last_step[1]; + *dst++ = 0; + } + } + + if (channels > 1) + { + memset(dst, 0, 8); + for (i = 0; i < 16; i++) + { + sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8)); + src += 2; + encoded = dsp_encode_ima_adpcm_sample(adpcm, i % 2, sample); + dst[ima_stereo_encode_map[i].byte_num] |= encoded << ima_stereo_encode_map[i].byte_shift; + } + dst += 8; + size -= 32; + } + else + { + sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8)); + src += 2; + encoded = dsp_encode_ima_adpcm_sample(adpcm, 0, sample); + sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8)); + src += 2; + encoded |= dsp_encode_ima_adpcm_sample(adpcm, 0, sample) << 4; + *dst++ = encoded; + size -= 4; + } + } + *out_size = dst - out; + return out; +} + diff --git a/libfreerdp-utils/event.c b/libfreerdp-utils/event.c new file mode 100644 index 0000000..b3f0cdc --- /dev/null +++ b/libfreerdp-utils/event.c @@ -0,0 +1,167 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Events + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static RDP_EVENT* freerdp_cliprdr_event_new(uint16 event_type) +{ + RDP_EVENT* event = NULL; + + switch (event_type) + { + case RDP_EVENT_TYPE_CB_MONITOR_READY: + event = (RDP_EVENT*) xnew(RDP_CB_MONITOR_READY_EVENT); + break; + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + event = (RDP_EVENT*) xnew(RDP_CB_FORMAT_LIST_EVENT); + break; + case RDP_EVENT_TYPE_CB_DATA_REQUEST: + event = (RDP_EVENT*) xnew(RDP_CB_DATA_REQUEST_EVENT); + break; + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + event = (RDP_EVENT*) xnew(RDP_CB_DATA_RESPONSE_EVENT); + break; + } + + return event; +} + +static RDP_EVENT* freerdp_tsmf_event_new(uint16 event_type) +{ + RDP_EVENT* event = NULL; + + switch (event_type) + { + case RDP_EVENT_TYPE_TSMF_VIDEO_FRAME: + event = (RDP_EVENT*) xnew(RDP_VIDEO_FRAME_EVENT); + break; + case RDP_EVENT_TYPE_TSMF_REDRAW: + event = (RDP_EVENT*) xnew(RDP_REDRAW_EVENT); + break; + } + + return event; +} + +static RDP_EVENT* freerdp_rail_event_new(uint16 event_type) +{ + RDP_EVENT* event = NULL; + event = xnew(RDP_EVENT); + return event; +} + +RDP_EVENT* freerdp_event_new(uint16 event_class, uint16 event_type, + RDP_EVENT_CALLBACK on_event_free_callback, void* user_data) +{ + RDP_EVENT* event = NULL; + + switch (event_class) + { + case RDP_EVENT_CLASS_DEBUG: + event = xnew(RDP_EVENT); + break; + case RDP_EVENT_CLASS_CLIPRDR: + event = freerdp_cliprdr_event_new(event_type); + break; + case RDP_EVENT_CLASS_TSMF: + event = freerdp_tsmf_event_new(event_type); + break; + case RDP_EVENT_CLASS_RAIL: + event = freerdp_rail_event_new(event_type); + break; + } + + if (event != NULL) + { + event->event_class = event_class; + event->event_type = event_type; + event->on_event_free_callback = on_event_free_callback; + event->user_data = user_data; + } + + return event; +} + +static void freerdp_cliprdr_event_free(RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_CB_FORMAT_LIST: + { + RDP_CB_FORMAT_LIST_EVENT* cb_event = (RDP_CB_FORMAT_LIST_EVENT*)event; + xfree(cb_event->formats); + xfree(cb_event->raw_format_data); + } + break; + case RDP_EVENT_TYPE_CB_DATA_RESPONSE: + { + RDP_CB_DATA_RESPONSE_EVENT* cb_event = (RDP_CB_DATA_RESPONSE_EVENT*)event; + xfree(cb_event->data); + } + break; + } +} + +static void freerdp_tsmf_event_free(RDP_EVENT* event) +{ + switch (event->event_type) + { + case RDP_EVENT_TYPE_TSMF_VIDEO_FRAME: + { + RDP_VIDEO_FRAME_EVENT* vevent = (RDP_VIDEO_FRAME_EVENT*)event; + xfree(vevent->frame_data); + xfree(vevent->visible_rects); + } + break; + } +} + +static void freerdp_rail_event_free(RDP_EVENT* event) +{ +} + +void freerdp_event_free(RDP_EVENT* event) +{ + if (event != NULL) + { + if (event->on_event_free_callback != NULL) + event->on_event_free_callback(event); + + switch (event->event_class) + { + case RDP_EVENT_CLASS_CLIPRDR: + freerdp_cliprdr_event_free(event); + break; + case RDP_EVENT_CLASS_TSMF: + freerdp_tsmf_event_free(event); + break; + case RDP_EVENT_CLASS_RAIL: + freerdp_rail_event_free(event); + break; + } + xfree(event); + } +} diff --git a/libfreerdp-utils/file.c b/libfreerdp-utils/file.c new file mode 100644 index 0000000..91746bb --- /dev/null +++ b/libfreerdp-utils/file.c @@ -0,0 +1,261 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * File Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#else +#include +#define getcwd _getcwd +#endif + +#include + +#ifndef _WIN32 +#define PATH_SEPARATOR_STR "/" +#define PATH_SEPARATOR_CHR '/' +#define HOME_ENV_VARIABLE "HOME" +#else +#include +#define PATH_SEPARATOR_STR "\\" +#define PATH_SEPARATOR_CHR '\\' +#define HOME_ENV_VARIABLE "HOMEPATH" +#endif + +#ifdef _WIN32 +#define SHARED_LIB_SUFFIX ".dll" +#elif __APPLE__ +#define SHARED_LIB_SUFFIX ".dylib" +#else +#define SHARED_LIB_SUFFIX ".so" +#endif + +#define FREERDP_CONFIG_DIR ".freerdp" + +#define PARENT_PATH ".." PATH_SEPARATOR_STR + +void freerdp_mkdir(char* path) +{ +#ifndef _WIN32 + mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR); +#else + CreateDirectoryA(path, 0); +#endif +} + +boolean freerdp_check_file_exists(char* file) +{ + struct stat stat_info; + + if (stat(file, &stat_info) != 0) + return false; + + return true; +} + +char* freerdp_get_home_path(rdpSettings* settings) +{ + if (settings->home_path == NULL) + settings->home_path = getenv(HOME_ENV_VARIABLE); + + return settings->home_path; +} + +char* freerdp_get_config_path(rdpSettings* settings) +{ + char* path; + + path = (char*) xmalloc(strlen(settings->home_path) + sizeof(FREERDP_CONFIG_DIR) + 2); + sprintf(path, "%s/%s", settings->home_path, FREERDP_CONFIG_DIR); + + if (!freerdp_check_file_exists(path)) + freerdp_mkdir(path); + + settings->config_path = path; + + return path; +} + +char* freerdp_get_current_path(rdpSettings* settings) +{ + if (settings->current_path == NULL) + settings->current_path = getcwd(NULL, 0); + + return settings->current_path; +} + +char* freerdp_construct_path(char* base_path, char* relative_path) +{ + char* path; + int length; + int base_path_length; + int relative_path_length; + + base_path_length = strlen(base_path); + relative_path_length = strlen(relative_path); + length = base_path_length + relative_path_length + 1; + + path = xmalloc(length + 1); + sprintf(path, "%s" PATH_SEPARATOR_STR "%s", base_path, relative_path); + + return path; +} + +char* freerdp_append_shared_library_suffix(char* file_path) +{ + char* p; + char* path = NULL; + int file_path_length; + int shared_lib_suffix_length; + + if (file_path == NULL) + return NULL; + + file_path_length = strlen(file_path); + shared_lib_suffix_length = strlen(SHARED_LIB_SUFFIX); + + if (file_path_length >= shared_lib_suffix_length) + { + p = &file_path[file_path_length - shared_lib_suffix_length]; + + if (strcmp(p, SHARED_LIB_SUFFIX) != 0) + { + path = xmalloc(file_path_length + shared_lib_suffix_length + 1); + sprintf(path, "%s%s", file_path, SHARED_LIB_SUFFIX); + } + else + { + path = xstrdup(file_path); + } + } + else + { + path = xstrdup(file_path); + } + + return path; +} + +char* freerdp_get_parent_path(char* base_path, int depth) +{ + int i; + char* p; + char* path; + int length; + int base_length; + + if (base_path == NULL) + return NULL; + + if (depth <= 0) + return xstrdup(base_path); + + base_length = strlen(base_path); + + p = &base_path[base_length]; + + for (i = base_length - 1; ((i >= 0) && (depth > 0)); i--) + { + if (base_path[i] == PATH_SEPARATOR_CHR) + { + p = &base_path[i]; + depth--; + } + } + + length = (p - base_path); + + path = (char*) xmalloc(length + 1); + memcpy(path, base_path, length); + path[length] = '\0'; + + return path; +} + +boolean freerdp_path_contains_separator(char* path) +{ + if (path == NULL) + return false; + + if (strchr(path, PATH_SEPARATOR_CHR) == NULL) + return false; + + return true; +} + +/* detects if we are running from the source tree */ + +boolean freerdp_detect_development_mode(rdpSettings* settings) +{ + int depth = 0; + char* current_path; + char* development_path = NULL; + boolean development_mode = false; + + if (freerdp_check_file_exists(".git")) + { + depth = 0; + development_mode = true; + } + else if (freerdp_check_file_exists(PARENT_PATH ".git")) + { + depth = 1; + development_mode = true; + } + else if (freerdp_check_file_exists(PARENT_PATH PARENT_PATH ".git")) + { + depth = 2; + development_mode = true; + } + + current_path = freerdp_get_current_path(settings); + + if (development_mode) + development_path = freerdp_get_parent_path(current_path, depth); + + settings->development_mode = development_mode; + settings->development_path = development_path; + + return settings->development_mode; +} + +void freerdp_detect_paths(rdpSettings* settings) +{ + freerdp_get_home_path(settings); + freerdp_get_config_path(settings); + freerdp_detect_development_mode(settings); + +#if 0 + printf("home path: %s\n", settings->home_path); + printf("config path: %s\n", settings->config_path); + printf("current path: %s\n", settings->current_path); + + if (settings->development_mode) + printf("development path: %s\n", settings->development_path); +#endif +} diff --git a/libfreerdp-utils/hexdump.c b/libfreerdp-utils/hexdump.c new file mode 100644 index 0000000..1db8cd6 --- /dev/null +++ b/libfreerdp-utils/hexdump.c @@ -0,0 +1,56 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Hex Dump Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + +void freerdp_hexdump(uint8* data, int length) +{ + uint8* p = data; + int i, line, offset = 0; + + while (offset < length) + { + printf("%04x ", offset); + + line = length - offset; + + if (line > FREERDP_HEXDUMP_LINE_LENGTH) + line = FREERDP_HEXDUMP_LINE_LENGTH; + + for (i = 0; i < line; i++) + printf("%02x ", p[i]); + + for (; i < FREERDP_HEXDUMP_LINE_LENGTH; i++) + printf(" "); + + for (i = 0; i < line; i++) + printf("%c", (p[i] >= 0x20 && p[i] < 0x7F) ? p[i] : '.'); + + printf("\n"); + + offset += line; + p += line; + } +} + diff --git a/libfreerdp-utils/list.c b/libfreerdp-utils/list.c new file mode 100644 index 0000000..9f7990b --- /dev/null +++ b/libfreerdp-utils/list.c @@ -0,0 +1,151 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Double-linked List Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +static LIST_ITEM* list_item_new(void* data) +{ + LIST_ITEM* item; + + item = xnew(LIST_ITEM); + item->data = data; + return item; +} + +static LIST_ITEM* list_item_find(LIST* list, void* data) +{ + LIST_ITEM* item; + + for (item = list->head; item; item = item->next) + { + if (item->data == data) + return item; + } + return NULL; +} + +LIST* list_new(void) +{ + LIST* list; + + list = xnew(LIST); + list->count = 0; + return list; +} + +void list_free(LIST* list) +{ + while (list->head) + list_dequeue(list); + xfree(list); +} + +void list_enqueue(LIST* list, void* data) +{ + LIST_ITEM* item; + + item = list_item_new(data); + if (list->tail == NULL) + { + list->head = item; + list->tail = item; + } + else + { + item->prev = list->tail; + list->tail->next = item; + list->tail = item; + } + list->count++; +} + +void* list_dequeue(LIST* list) +{ + LIST_ITEM* item; + void* data = NULL; + + item = list->head; + if (item != NULL) + { + list->head = item->next; + if (list->head == NULL) + list->tail = NULL; + else + list->head->prev = NULL; + + data = item->data; + xfree(item); + list->count--; + } + return data; +} + +void* list_peek(LIST* list) +{ + LIST_ITEM* item; + + item = list->head; + return item ? item->data : NULL; +} + +void* list_next(LIST* list, void* data) +{ + LIST_ITEM* item; + + item = list_item_find(list, data); + data = NULL; + if (item != NULL) + { + if (item->next != NULL) + data = item->next->data; + } + return data; +} + +void* list_remove(LIST* list, void* data) +{ + LIST_ITEM* item; + + item = list_item_find(list, data); + if (item != NULL) + { + if (item->prev != NULL) + item->prev->next = item->next; + if (item->next != NULL) + item->next->prev = item->prev; + if (list->head == item) + list->head = item->next; + if (list->tail == item) + list->tail = item->prev; + xfree(item); + list->count--; + } + else + data = NULL; + return data; +} + +int list_size(LIST* list) +{ + return list->count; +} diff --git a/libfreerdp-utils/load_plugin.c b/libfreerdp-utils/load_plugin.c new file mode 100644 index 0000000..adab66e --- /dev/null +++ b/libfreerdp-utils/load_plugin.c @@ -0,0 +1,209 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Plugin Loading Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 + +#include +#define DLOPEN(f) LoadLibraryA(f) +#define DLSYM(f, n) GetProcAddress(f, n) +#define DLCLOSE(f) FreeLibrary(f) +#define DLERROR() "" + +#else + +#include +#include +#define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY) +#define DLSYM(f, n) dlsym(f, n) +#define DLCLOSE(f) dlclose(f) +#define DLERROR() dlerror() + +#endif + +void* freerdp_open_library(const char* file) +{ + void* library; + + library = DLOPEN(file); + + if (library == NULL) + { + printf("freerdp_load_library: failed to open %s: %s\n", file, DLERROR()); + return NULL; + } + + return library; +} + +void* freerdp_get_library_symbol(void* library, const char* name) +{ + void* symbol; + + symbol = DLSYM(library, name); + + if (symbol == NULL) + { + printf("freerdp_get_library_symbol: failed to load %s: %s\n", name, DLERROR()); + return NULL; + } + + return symbol; +} + +boolean freerdp_close_library(void* library) +{ + int status; + + status = DLCLOSE(library); + +#ifdef _WIN32 + if (status != 0) +#else + if (status == 0) +#endif + { + printf("freerdp_free_library: failed to close: %s\n", DLERROR()); + return false; + } + + return true; +} + +void* freerdp_load_library_symbol(const char* file, const char* name) +{ + void* library; + void* symbol; + + library = DLOPEN(file); + + if (library == NULL) + { + printf("freerdp_load_library_symbol: failed to open %s: %s\n", file, DLERROR()); + return NULL; + } + + symbol = DLSYM(library, name); + + if (symbol == NULL) + { + printf("freerdp_load_library_symbol: failed to load %s: %s\n", file, DLERROR()); + return NULL; + } + + return symbol; +} + +void* freerdp_load_plugin(const char* name, const char* entry_name) +{ + char* path; + void* entry; + char* suffixed_name; + + suffixed_name = freerdp_append_shared_library_suffix((char*) name); + + if (!freerdp_path_contains_separator(suffixed_name)) + { + /* no explicit path given, use default path */ + path = freerdp_construct_path(PLUGIN_PATH, suffixed_name); + } + else + { + /* explicit path given, use it instead of default path */ + path = xstrdup(suffixed_name); + } + + entry = freerdp_load_library_symbol(path, entry_name); + + xfree(suffixed_name); + xfree(path); + + if (entry == NULL) + { + printf("freerdp_load_plugin: failed to load %s/%s\n", name, entry_name); + return NULL; + } + + return entry; +} + +void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name) +{ + char* path; + void* entry; + char* suffixed_name; + + suffixed_name = freerdp_append_shared_library_suffix((char*) name); + + if (!freerdp_path_contains_separator(suffixed_name)) + { + /* no explicit path given, use default path */ + + if (!settings->development_mode) + { + path = freerdp_construct_path(PLUGIN_PATH, suffixed_name); + } + else + { + char* dot; + char* plugin_name; + char* channels_path; + char* channel_subpath; + + dot = strrchr(suffixed_name, '.'); + plugin_name = xmalloc((dot - suffixed_name) + 1); + strncpy(plugin_name, suffixed_name, (dot - suffixed_name)); + plugin_name[(dot - suffixed_name)] = '\0'; + + channels_path = freerdp_construct_path(settings->development_path, "channels"); + channel_subpath = freerdp_construct_path(channels_path, plugin_name); + + path = freerdp_construct_path(channel_subpath, suffixed_name); + + xfree(plugin_name); + xfree(channels_path); + xfree(channel_subpath); + } + } + else + { + /* explicit path given, use it instead of default path */ + path = xstrdup(suffixed_name); + } + + entry = freerdp_load_library_symbol(path, entry_name); + + xfree(suffixed_name); + xfree(path); + + if (entry == NULL) + { + printf("freerdp_load_channel_plugin: failed to load %s/%s\n", name, entry_name); + return NULL; + } + + return entry; +} diff --git a/libfreerdp-utils/memory.c b/libfreerdp-utils/memory.c new file mode 100644 index 0000000..d4d17a6 --- /dev/null +++ b/libfreerdp-utils/memory.c @@ -0,0 +1,133 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Memory Utils + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +/** + * Allocate memory. + * @param size + */ + +void* xmalloc(size_t size) +{ + void* mem; + + if (size < 1) + size = 1; + + mem = malloc(size); + + if (mem == NULL) + { + perror("xmalloc"); + printf("xmalloc: failed to allocate memory of size: %d\n", (int) size); + } + + return mem; +} + +/** + * Allocate memory initialized to zero. + * @param size + */ + +void* xzalloc(size_t size) +{ + void* mem; + + if (size < 1) + size = 1; + + mem = calloc(1, size); + + if (mem == NULL) + { + perror("xzalloc"); + printf("xzalloc: failed to allocate memory of size: %d\n", (int) size); + } + + return mem; +} + +/** + * Reallocate memory. + * @param ptr + * @param size + */ + +void* xrealloc(void* ptr, size_t size) +{ + void* mem; + + if (size < 1) + size = 1; + + if (ptr == NULL) + { + printf("xrealloc: null pointer given\n"); + return NULL; + } + + mem = realloc(ptr, size); + + if (mem == NULL) + perror("xrealloc"); + + return mem; +} + +/** + * Free memory. + * @param mem + */ + +void xfree(void* ptr) +{ + if (ptr != NULL) + free(ptr); +} + +/** + * Duplicate a string in memory. + * @param str + * @return + */ + +char* xstrdup(const char* str) +{ + char* mem; + + if (str == NULL) + return NULL; + +#ifdef _WIN32 + mem = _strdup(str); +#else + mem = strdup(str); +#endif + + if (mem == NULL) + perror("strdup"); + + return mem; +} diff --git a/libfreerdp-utils/mutex.c b/libfreerdp-utils/mutex.c new file mode 100644 index 0000000..38cd226 --- /dev/null +++ b/libfreerdp-utils/mutex.c @@ -0,0 +1,71 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Mutex Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#ifdef _WIN32 +#include +#define freerdp_mutex_t HANDLE +#else +#include +#define freerdp_mutex_t pthread_mutex_t +#endif + +freerdp_mutex freerdp_mutex_new(void) +{ +#ifdef _WIN32 + freerdp_mutex_t mutex; + mutex = CreateMutex(NULL, FALSE, NULL); + return (freerdp_mutex) mutex; +#else + freerdp_mutex_t* mutex; + mutex = xnew(freerdp_mutex_t); + pthread_mutex_init(mutex, 0); + return mutex; +#endif +} + +void freerdp_mutex_free(freerdp_mutex mutex) +{ +#ifdef _WIN32 + CloseHandle((freerdp_mutex_t) mutex); +#else + pthread_mutex_destroy((freerdp_mutex_t*) mutex); + xfree(mutex); +#endif +} + +void freerdp_mutex_lock(freerdp_mutex mutex) +{ +#ifdef _WIN32 + WaitForSingleObject((freerdp_mutex_t) mutex, INFINITE); +#else + pthread_mutex_lock(mutex); +#endif +} + +void freerdp_mutex_unlock(freerdp_mutex mutex) +{ +#ifdef _WIN32 + ReleaseMutex((freerdp_mutex_t) mutex); +#else + pthread_mutex_unlock(mutex); +#endif +} diff --git a/libfreerdp-utils/passphrase.c b/libfreerdp-utils/passphrase.c new file mode 100644 index 0000000..d207cc8 --- /dev/null +++ b/libfreerdp-utils/passphrase.c @@ -0,0 +1,124 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Passphrase Handling Utils + * + * Copyright 2011 Shea Levy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#ifdef _WIN32 +char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz) +{ + errno=ENOSYS; + return NULL; +} +#else +#include +#include +#include +#include +#include +#include +#include + +char* freerdp_passphrase_read(const char* prompt, char* buf, size_t bufsiz) +{ + char read_char; + char* buf_iter; + char term_name[L_ctermid]; + int term_file, write_file; + ssize_t nbytes; + size_t read_bytes = 0; + + if (bufsiz == 0) + { + errno = EINVAL; + return NULL; + } + + ctermid(term_name); + if(strcmp(term_name, "") == 0 + || (term_file = open(term_name, O_RDWR)) == -1) + { + write_file = STDERR_FILENO; + terminal_fildes = STDIN_FILENO; + } + else + { + write_file = term_file; + terminal_fildes = term_file; + } + + if (tcgetattr(terminal_fildes, &orig_flags) != -1) + { + new_flags = orig_flags; + new_flags.c_lflag &= ~ECHO; + new_flags.c_lflag |= ECHONL; + terminal_needs_reset = 1; + if (tcsetattr(terminal_fildes, TCSAFLUSH, &new_flags) == -1) + terminal_needs_reset = 0; + } + + if (write(write_file, prompt, strlen(prompt)) == (ssize_t) -1) + goto error; + + buf_iter = buf; + while ((nbytes = read(terminal_fildes, &read_char, sizeof read_char)) == (sizeof read_char)) + { + if (read_char == '\n') + break; + if (read_bytes < (bufsiz - (size_t) 1)) + { + read_bytes++; + *buf_iter = read_char; + buf_iter++; + } + } + *buf_iter = '\0'; + buf_iter = NULL; + read_char = '\0'; + if (nbytes == (ssize_t) -1) + goto error; + + if (terminal_needs_reset) + { + if (tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags) == -1) + goto error; + terminal_needs_reset = 0; + } + + if (terminal_fildes != STDIN_FILENO) + { + if (close(terminal_fildes) == -1) + goto error; + } + + return buf; + + error: + { + int saved_errno = errno; + buf_iter = NULL; + read_char = '\0'; + if (terminal_needs_reset) + tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags); + if (terminal_fildes != STDIN_FILENO) + close(terminal_fildes); + errno = saved_errno; + return NULL; + } +} +#endif diff --git a/libfreerdp-utils/pcap.c b/libfreerdp-utils/pcap.c new file mode 100644 index 0000000..6de19a6 --- /dev/null +++ b/libfreerdp-utils/pcap.c @@ -0,0 +1,217 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * pcap File Format Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#ifndef _WIN32 +#include +#else +#include +#include + +#if !defined(__MINGW32__) && !defined(__MINGW64__) +struct timeval +{ + long tv_sec; + long tv_usec; +}; +#endif + +int gettimeofday(struct timeval* tp, void* tz) +{ + struct _timeb timebuffer; + _ftime (&timebuffer); + tp->tv_sec = (long) timebuffer.time; + tp->tv_usec = timebuffer.millitm * 1000; + return 0; +} +#endif + +#include +#include + +#include + +#define PCAP_MAGIC 0xA1B2C3D4 + +void pcap_read_header(rdpPcap* pcap, pcap_header* header) +{ + fread((void*) header, sizeof(pcap_header), 1, pcap->fp); +} + +void pcap_write_header(rdpPcap* pcap, pcap_header* header) +{ + fwrite((void*) header, sizeof(pcap_header), 1, pcap->fp); +} + +void pcap_read_record_header(rdpPcap* pcap, pcap_record_header* record) +{ + fread((void*) record, sizeof(pcap_record_header), 1, pcap->fp); +} + +void pcap_write_record_header(rdpPcap* pcap, pcap_record_header* record) +{ + fwrite((void*) record, sizeof(pcap_record_header), 1, pcap->fp); +} + +void pcap_read_record(rdpPcap* pcap, pcap_record* record) +{ + pcap_read_record_header(pcap, &record->header); + record->length = record->header.incl_len; + record->data = xmalloc(record->length); + fread(record->data, record->length, 1, pcap->fp); +} + +void pcap_write_record(rdpPcap* pcap, pcap_record* record) +{ + pcap_write_record_header(pcap, &record->header); + fwrite(record->data, record->length, 1, pcap->fp); +} + +void pcap_add_record(rdpPcap* pcap, void* data, uint32 length) +{ + pcap_record* record; + struct timeval tp; + + if (pcap->tail == NULL) + { + pcap->tail = (pcap_record*) xzalloc(sizeof(pcap_record)); + pcap->head = pcap->tail; + pcap->record = pcap->head; + record = pcap->tail; + } + else + { + record = (pcap_record*) xzalloc(sizeof(pcap_record)); + pcap->tail->next = record; + pcap->tail = record; + } + + if (pcap->record == NULL) + pcap->record = record; + + record->data = data; + record->length = length; + record->header.incl_len = length; + record->header.orig_len = length; + + gettimeofday(&tp, 0); + record->header.ts_sec = tp.tv_sec; + record->header.ts_usec = tp.tv_usec; +} + +boolean pcap_has_next_record(rdpPcap* pcap) +{ + if (pcap->file_size - (ftell(pcap->fp)) <= 16) + return false; + + return true; +} + +boolean pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record) +{ + if (pcap_has_next_record(pcap) != true) + return false; + + pcap_read_record_header(pcap, &record->header); + record->length = record->header.incl_len; + record->data = xmalloc(record->length); + + return true; +} + +boolean pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record) +{ + fread(record->data, record->length, 1, pcap->fp); + return true; +} + +boolean pcap_get_next_record(rdpPcap* pcap, pcap_record* record) +{ + if (pcap_has_next_record(pcap) != true) + return false; + + pcap_read_record(pcap, record); + + return true; +} + +rdpPcap* pcap_open(char* name, boolean write) +{ + rdpPcap* pcap; + + FILE *pcap_fp = fopen(name, write ? "w+" : "r"); + if (pcap_fp == NULL) + { + perror("opening pcap dump"); + return NULL; + } + + pcap = (rdpPcap*) xzalloc(sizeof(rdpPcap)); + + if (pcap != NULL) + { + pcap->name = name; + pcap->write = write; + pcap->record_count = 0; + pcap->fp = pcap_fp; + + if (write) + { + pcap->header.magic_number = 0xA1B2C3D4; + pcap->header.version_major = 2; + pcap->header.version_minor = 4; + pcap->header.thiszone = 0; + pcap->header.sigfigs = 0; + pcap->header.snaplen = 0xFFFFFFFF; + pcap->header.network = 0; + pcap_write_header(pcap, &pcap->header); + } + else + { + fseek(pcap->fp, 0, SEEK_END); + pcap->file_size = (int) ftell(pcap->fp); + fseek(pcap->fp, 0, SEEK_SET); + pcap_read_header(pcap, &pcap->header); + } + } + + return pcap; +} + +void pcap_flush(rdpPcap* pcap) +{ + while (pcap->record != NULL) + { + pcap_write_record(pcap, pcap->record); + pcap->record = pcap->record->next; + } + + if (pcap->fp != NULL) + fflush(pcap->fp); +} + +void pcap_close(rdpPcap* pcap) +{ + pcap_flush(pcap); + + if (pcap->fp != NULL) + fclose(pcap->fp); +} diff --git a/libfreerdp-utils/profiler.c b/libfreerdp-utils/profiler.c new file mode 100644 index 0000000..13b560c --- /dev/null +++ b/libfreerdp-utils/profiler.c @@ -0,0 +1,72 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Profiler Utils + * + * Copyright 2011 Stephen Erisman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +PROFILER* profiler_create(char* name) +{ + PROFILER* profiler; + + profiler = (PROFILER*) xmalloc(sizeof(PROFILER)); + + profiler->name = name; + profiler->stopwatch = stopwatch_create(); + + return profiler; +} + +void profiler_free(PROFILER* profiler) +{ + stopwatch_free(profiler->stopwatch); + + xfree(profiler); +} + +void profiler_enter(PROFILER* profiler) +{ + stopwatch_start(profiler->stopwatch); +} + +void profiler_exit(PROFILER* profiler) +{ + stopwatch_stop(profiler->stopwatch); +} + +void profiler_print_header() +{ + printf("\n"); + printf(" |-----------------------|\n" ); + printf(" PROFILER | elapsed seconds |\n" ); + printf("|--------------------------------------------|-----------------------|\n" ); + printf("| code section | iterations | total | avg. |\n" ); + printf("|-------------------------------|------------|-----------|-----------|\n" ); +} + +void profiler_print(PROFILER* profiler) +{ + double elapsed_sec = stopwatch_get_elapsed_time_in_seconds(profiler->stopwatch); + double avg_sec = elapsed_sec / (double) profiler->stopwatch->count; + + printf("| %-30.30s| %'10lu | %'9f | %'9f |\n", profiler->name, profiler->stopwatch->count, elapsed_sec, avg_sec); +} + +void profiler_print_footer() +{ + printf("|--------------------------------------------------------------------|\n" ); +} diff --git a/libfreerdp-utils/rail.c b/libfreerdp-utils/rail.c new file mode 100644 index 0000000..a89329c --- /dev/null +++ b/libfreerdp-utils/rail.c @@ -0,0 +1,184 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Remote Applications Integrated Locally (RAIL) Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +void rail_unicode_string_alloc(UNICODE_STRING* unicode_string, uint16 cbString) +{ + unicode_string->length = cbString; + unicode_string->string = xzalloc(cbString); +} + +void rail_unicode_string_free(UNICODE_STRING* unicode_string) +{ + unicode_string->length = 0; + + if (unicode_string->string != NULL) + xfree(unicode_string->string); +} + +void rail_read_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +{ + stream_read_uint16(s, unicode_string->length); /* cbString (2 bytes) */ + + if (unicode_string->string == NULL) + unicode_string->string = (uint8*) xmalloc(unicode_string->length); + else + unicode_string->string = (uint8*) xrealloc(unicode_string->string, unicode_string->length); + + stream_read(s, unicode_string->string, unicode_string->length); +} + +void rail_write_unicode_string(STREAM* s, UNICODE_STRING* unicode_string) +{ + stream_check_size(s, 2 + unicode_string->length); + stream_write_uint16(s, unicode_string->length); /* cbString (2 bytes) */ + stream_write(s, unicode_string->string, unicode_string->length); /* string */ +} + +void rail_write_unicode_string_value(STREAM* s, UNICODE_STRING* unicode_string) +{ + if (unicode_string->length > 0) + { + stream_check_size(s, unicode_string->length); + stream_write(s, unicode_string->string, unicode_string->length); /* string */ + } +} + +void rail_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_read_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_read_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_read_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_read_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +void rail_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_write_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_write_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_write_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_write_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +void* rail_clone_order(uint32 event_type, void* order) +{ + struct + { + uint32 type; + uint32 size; + } ordersize_table[] = + { + {RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS, sizeof(RAIL_SYSPARAM_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS, sizeof(RAIL_EXEC_RESULT_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_SYSPARAM, sizeof(RAIL_SYSPARAM_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_MINMAXINFO, sizeof(RAIL_MINMAXINFO_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_SERVER_LOCALMOVESIZE, sizeof(RAIL_LOCALMOVESIZE_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP, sizeof(RAIL_GET_APPID_RESP_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CHANNEL_LANGBARINFO, sizeof(RAIL_LANGBAR_INFO_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS, sizeof(RAIL_SYSPARAM_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_EXEC_REMOTE_APP, sizeof(RDP_PLUGIN_DATA)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_ACTIVATE, sizeof(RAIL_ACTIVATE_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_SYSMENU, sizeof(RAIL_SYSMENU_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_SYSCOMMAND, sizeof(RAIL_SYSCOMMAND_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_NOTIFY_EVENT, sizeof(RAIL_NOTIFY_EVENT_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_WINDOW_MOVE, sizeof(RAIL_WINDOW_MOVE_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_APPID_REQ, sizeof(RAIL_GET_APPID_REQ_ORDER)}, + {RDP_EVENT_TYPE_RAIL_CLIENT_LANGBARINFO, sizeof(RAIL_LANGBAR_INFO_ORDER)}, + }; + size_t i = 0; + size_t order_size = 0; + void* new_order = NULL; + + for (i = 0; i < RAIL_ARRAY_SIZE(ordersize_table); i++) + { + if (event_type == ordersize_table[i].type) + { + order_size = ordersize_table[i].size; + break; + } + } + + // Event type not found. + if (order_size == 0) return NULL; + + new_order = xmalloc(order_size); + memcpy(new_order, order, order_size); + + //printf("rail_clone_order: type=%d order=%p\n", event_type, new_order); + + // Create copy of variable data for some orders + if ((event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS) || + (event_type == RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS)) + { + RAIL_SYSPARAM_ORDER* new_sysparam = (RAIL_SYSPARAM_ORDER*)new_order; + RAIL_SYSPARAM_ORDER* old_sysparam = (RAIL_SYSPARAM_ORDER*)order; + + rail_unicode_string_alloc(&new_sysparam->highContrast.colorScheme, + old_sysparam->highContrast.colorScheme.length); + + memcpy(new_sysparam->highContrast.colorScheme.string, + old_sysparam->highContrast.colorScheme.string, + old_sysparam->highContrast.colorScheme.length); + } + + if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS) + { + RAIL_EXEC_RESULT_ORDER* new_exec_result = (RAIL_EXEC_RESULT_ORDER*)new_order; + RAIL_EXEC_RESULT_ORDER* old_exec_result = (RAIL_EXEC_RESULT_ORDER*)order; + + rail_unicode_string_alloc(&new_exec_result->exeOrFile, + old_exec_result->exeOrFile.length); + + memcpy(new_exec_result->exeOrFile.string, + old_exec_result->exeOrFile.string, + old_exec_result->exeOrFile.length); + } + + if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_APPID_RESP) + { + RAIL_GET_APPID_RESP_ORDER* new_app_resp = (RAIL_GET_APPID_RESP_ORDER*)new_order; + + new_app_resp->applicationId.string = &new_app_resp->applicationIdBuffer[0]; + } + + return new_order; +} + +void rail_free_cloned_order(uint32 event_type, void* order) +{ + //printf("rail_free_cloned_order: type=%d order=%p\n", event_type, order); + if ((event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_GET_SYSPARAMS) || + (event_type == RDP_EVENT_TYPE_RAIL_CLIENT_SET_SYSPARAMS)) + { + RAIL_SYSPARAM_ORDER* sysparam = (RAIL_SYSPARAM_ORDER*)order; + rail_unicode_string_free(&sysparam->highContrast.colorScheme); + } + + if (event_type == RDP_EVENT_TYPE_RAIL_CHANNEL_EXEC_RESULTS) + { + RAIL_EXEC_RESULT_ORDER* exec_result = (RAIL_EXEC_RESULT_ORDER*)order; + rail_unicode_string_free(&exec_result->exeOrFile); + } + xfree(order); +} diff --git a/libfreerdp-utils/rect.c b/libfreerdp-utils/rect.c new file mode 100644 index 0000000..08cdea7 --- /dev/null +++ b/libfreerdp-utils/rect.c @@ -0,0 +1,56 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Rectangle Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +void freerdp_read_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_read_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_read_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_read_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_read_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +void freerdp_write_rectangle_16(STREAM* s, RECTANGLE_16* rectangle_16) +{ + stream_write_uint16(s, rectangle_16->left); /* left (2 bytes) */ + stream_write_uint16(s, rectangle_16->top); /* top (2 bytes) */ + stream_write_uint16(s, rectangle_16->right); /* right (2 bytes) */ + stream_write_uint16(s, rectangle_16->bottom); /* bottom (2 bytes) */ +} + +RECTANGLE_16* freerdp_rectangle_16_new(uint16 left, uint16 top, uint16 right, uint16 bottom) +{ + RECTANGLE_16* rectangle_16 = xnew(RECTANGLE_16); + + rectangle_16->left = left; + rectangle_16->top = top; + rectangle_16->right = right; + rectangle_16->bottom = bottom; + + return rectangle_16; +} + +void freerdp_rectangle_16_free(RECTANGLE_16* rectangle_16) +{ + xfree(rectangle_16); +} diff --git a/libfreerdp-utils/registry.c b/libfreerdp-utils/registry.c new file mode 100644 index 0000000..04a8352 --- /dev/null +++ b/libfreerdp-utils/registry.c @@ -0,0 +1,194 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Registry Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +static const char registry_dir[] = "freerdp"; +static const char registry_file[] = "config.txt"; + +static REG_SECTION global[] = +{ + { REG_TYPE_SECTION, "global", 0, NULL }, + { REG_TYPE_BOOLEAN, "fast_path", 1, "1" }, + { REG_TYPE_STRING, "resolution", 8, "1024x768" }, + { REG_TYPE_INTEGER, "performance_flags", 4, "0xFFFF" }, + { REG_TYPE_NONE, "", 0, NULL } +}; + +static REG_SECTION licensing[] = +{ + { REG_TYPE_SECTION, "licensing", 0, NULL }, + { REG_TYPE_STRING, "platform_id", 1, "0x000201" }, + { REG_TYPE_STRING, "hardware_id", 16, "0xe107d9d372bb6826bd81d3542a419d6" }, + { REG_TYPE_NONE, "", 0, NULL } +}; + +static REG_SECTION* sections[] = +{ + (REG_SECTION*) &global, + (REG_SECTION*) &licensing, + (REG_SECTION*) NULL +}; + +void registry_print_entry(REG_ENTRY* entry, FILE* fp) +{ + uint8* value; + value = (uint8*) entry->value; + fprintf(fp, "%s = %s\n", entry->name, value); +} + +void registry_print_section(REG_SECTION* section, FILE* fp) +{ + int i = 0; + REG_ENTRY* entries = (REG_ENTRY*) §ion[1]; + + fprintf(fp, "\n"); + fprintf(fp, "[%s]\n", section->name); + + while (entries[i].type != REG_TYPE_NONE) + { + registry_print_entry(&entries[i], fp); + i++; + } +} + +void registry_print(rdpRegistry* registry, FILE* fp) +{ + int i = 0; + + fprintf(fp, "# FreeRDP Configuration Registry\n"); + + while (sections[i] != NULL) + { + registry_print_section(sections[i], fp); + i++; + } + + fprintf(fp, "\n"); +} + +void registry_create(rdpRegistry* registry) +{ + registry->fp = fopen((char*)registry->file, "w+"); + + if (registry->fp == NULL) + { + printf("registry_create: error opening [%s] for writing\n", registry->file); + return; + } + + registry_print(registry, registry->fp); + fflush(registry->fp); +} + +void registry_load(rdpRegistry* registry) +{ + registry->fp = fopen((char*) registry->file, "r+"); +} + +void registry_open(rdpRegistry* registry) +{ + struct stat stat_info; + + if (stat((char*)registry->file, &stat_info) != 0) + registry_create(registry); + else + registry_load(registry); +} + +void registry_close(rdpRegistry* registry) +{ + if (registry->fp != NULL) + fclose(registry->fp); +} + +void registry_init(rdpRegistry* registry) +{ + int length; + char* home_path; + struct stat stat_info; + + if (registry->settings->home_path == NULL) + home_path = getenv("HOME"); + else + home_path = registry->settings->home_path; + + if (home_path == NULL) + { + printf("could not get home path\n"); + registry->available = false; + return; + } + + registry->available = true; + + if (home_path == NULL) + { + printf("could not get home path\n"); + registry->available = false; + return; + } + + registry->home = (char*) xstrdup(home_path); + printf("home path: %s\n", registry->home); + + registry->path = (char*) xmalloc(strlen(registry->home) + strlen("/.") + strlen(registry_dir) + 1); + sprintf(registry->path, "%s/.%s", registry->home, registry_dir); + printf("registry path: %s\n", registry->path); + + if (stat(registry->path, &stat_info) != 0) + { + freerdp_mkdir(registry->path); + printf("creating directory %s\n", registry->path); + } + + length = strlen(registry->path); + registry->file = (char*) xmalloc(strlen(registry->path) + strlen("/") + strlen(registry_file) + 1); + sprintf(registry->file, "%s/%s", registry->path, registry_file); + printf("registry file: %s\n", registry->file); + + registry_open(registry); +} + +rdpRegistry* registry_new(rdpSettings* settings) +{ + rdpRegistry* registry = (rdpRegistry*) xzalloc(sizeof(rdpRegistry)); + + if (registry != NULL) + { + registry->settings = settings; + registry_init(registry); + } + + return registry; +} + +void registry_free(rdpRegistry* registry) +{ + if (registry != NULL) + { + registry_close(registry); + xfree(registry->path); + xfree(registry->file); + xfree(registry->home); + xfree(registry); + } +} diff --git a/libfreerdp-utils/semaphore.c b/libfreerdp-utils/semaphore.c new file mode 100644 index 0000000..e5a6aa3 --- /dev/null +++ b/libfreerdp-utils/semaphore.c @@ -0,0 +1,96 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Semaphore Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#if defined __APPLE__ + +#include +#include +#include +#include +#include +#define freerdp_sem_t semaphore_t + +#elif defined _WIN32 + +#include +#define freerdp_sem_t HANDLE + +#else + +#include +#include +#define freerdp_sem_t sem_t + +#endif + +freerdp_sem freerdp_sem_new(int iv) +{ + freerdp_sem_t* sem; + + sem = xnew(freerdp_sem_t); + +#if defined __APPLE__ + semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, iv); +#elif defined _WIN32 + *sem = CreateSemaphore(NULL, 0, iv, NULL); +#else + sem_init(sem, 0, iv); +#endif + + return sem; +} + +void freerdp_sem_free(freerdp_sem sem) +{ +#if defined __APPLE__ + semaphore_destroy(mach_task_self(), *((freerdp_sem_t*)sem)); +#elif defined _WIN32 + CloseHandle(*((freerdp_sem_t*)sem)); +#else + sem_destroy((freerdp_sem_t*)sem); +#endif + + xfree(sem); +} + +void freerdp_sem_signal(freerdp_sem sem) +{ +#if defined __APPLE__ + semaphore_signal(*((freerdp_sem_t*)sem)); +#elif defined _WIN32 + ReleaseSemaphore(*((freerdp_sem_t*)sem), 1, NULL); +#else + sem_post((freerdp_sem_t*)sem); +#endif +} + +void freerdp_sem_wait(freerdp_sem sem) +{ +#if defined __APPLE__ + semaphore_wait(*((freerdp_sem_t*)sem)); +#elif defined _WIN32 + WaitForSingleObject(*((freerdp_sem_t*)sem), INFINITE); +#else + sem_wait((freerdp_sem_t*)sem); +#endif +} + diff --git a/libfreerdp-utils/signal.c b/libfreerdp-utils/signal.c new file mode 100644 index 0000000..8f9f675 --- /dev/null +++ b/libfreerdp-utils/signal.c @@ -0,0 +1,115 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Signal handling + * + * Copyright 2011 Shea Levy + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#ifdef _WIN32 +#include +int freerdp_handle_signals(void) +{ + errno = ENOSYS; + return -1; +} +#else +volatile sig_atomic_t terminal_needs_reset = 0; +int terminal_fildes = 0; +struct termios orig_flags; +struct termios new_flags; + +static void fatal_handler(int signum) +{ + struct sigaction default_sigaction; + sigset_t this_mask; + + if (terminal_needs_reset) + tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags); + + default_sigaction.sa_handler = SIG_DFL; + sigfillset(&(default_sigaction.sa_mask)); + default_sigaction.sa_flags = 0; + + sigaction(signum, &default_sigaction, NULL); + + sigemptyset(&this_mask); + sigaddset(&this_mask, signum); + pthread_sigmask(SIG_UNBLOCK, &this_mask, NULL); + raise(signum); +} + +int freerdp_handle_signals(void) +{ + const int fatal_signals[] = { + SIGABRT, + SIGALRM, + SIGBUS, + SIGFPE, + SIGHUP, + SIGILL, + SIGINT, + SIGKILL, + SIGPIPE, + SIGQUIT, + SIGSEGV, + SIGSTOP, + SIGTERM, + SIGTSTP, + SIGTTIN, + SIGTTOU, + SIGUSR1, + SIGUSR2, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGSYS + SIGSYS, +#endif + SIGTRAP, +#ifdef SIGVTALRM + SIGVTALRM, +#endif + SIGXCPU, + SIGXFSZ + }; + int signal_index; + sigset_t orig_set; + struct sigaction orig_sigaction, fatal_sigaction; + + sigfillset(&(fatal_sigaction.sa_mask)); + sigdelset(&(fatal_sigaction.sa_mask), SIGCONT); + pthread_sigmask(SIG_BLOCK, &(fatal_sigaction.sa_mask), &orig_set); + + fatal_sigaction.sa_handler = fatal_handler; + fatal_sigaction.sa_flags = 0; + + for (signal_index = 0; + signal_index < (sizeof fatal_signals / sizeof fatal_signals[0]); + signal_index++) + if (sigaction(fatal_signals[signal_index], + NULL, &orig_sigaction) == 0) + if (orig_sigaction.sa_handler != SIG_IGN) + sigaction(fatal_signals[signal_index], + &fatal_sigaction, NULL); + + pthread_sigmask(SIG_SETMASK, &orig_set, NULL); + return 0; +} +#endif diff --git a/libfreerdp-utils/sleep.c b/libfreerdp-utils/sleep.c new file mode 100644 index 0000000..3612fb5 --- /dev/null +++ b/libfreerdp-utils/sleep.c @@ -0,0 +1,58 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Sleep Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#ifndef _WIN32 +#define _XOPEN_SOURCE 500 +#include +#else +#include +#endif + +void freerdp_sleep(uint32 seconds) +{ +#ifndef _WIN32 + sleep(seconds); +#else + Sleep(seconds * 1000); +#endif +} + +void freerdp_usleep(uint32 useconds) +{ +#ifndef _WIN32 + usleep(useconds); +#else + uint64 t1; + uint64 t2; + uint64 freq; + + QueryPerformanceCounter((LARGE_INTEGER*) &t1); + QueryPerformanceCounter((LARGE_INTEGER*) &freq); + + do + { + QueryPerformanceCounter((LARGE_INTEGER*) &t2); + } + while ((t2 - t1) < useconds); +#endif +} diff --git a/libfreerdp-utils/stopwatch.c b/libfreerdp-utils/stopwatch.c new file mode 100644 index 0000000..daf1641 --- /dev/null +++ b/libfreerdp-utils/stopwatch.c @@ -0,0 +1,77 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stopwatch Utils + * + * Copyright 2011 Stephen Erisman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +STOPWATCH* stopwatch_create() +{ + STOPWATCH* sw; + + sw = (STOPWATCH*) xmalloc(sizeof(STOPWATCH)); + stopwatch_reset(sw); + + return sw; +} + +void stopwatch_free(STOPWATCH* stopwatch) +{ + xfree(stopwatch); +} + +void stopwatch_start(STOPWATCH* stopwatch) +{ + stopwatch->start = clock(); + stopwatch->count++; +} + +void stopwatch_stop(STOPWATCH* stopwatch) +{ + stopwatch->end = clock(); + stopwatch->elapsed += (stopwatch->end - stopwatch->start); +} + +void stopwatch_reset(STOPWATCH* stopwatch) +{ + stopwatch->start = 0; + stopwatch->end = 0; + stopwatch->elapsed = 0; + stopwatch->count = 0; +} + +double stopwatch_get_elapsed_time_in_seconds(STOPWATCH* stopwatch) +{ + return ((double) stopwatch->elapsed) / CLOCKS_PER_SEC; +} + +void stopwatch_get_elapsed_time_in_useconds(STOPWATCH* stopwatch, uint32* sec, uint32* usec) +{ + double uelapsed; + double clocks_per_usec; + + *sec = ((uint32) stopwatch->elapsed) / CLOCKS_PER_SEC; + uelapsed = stopwatch->elapsed - ((double)(*sec) * CLOCKS_PER_SEC); + + clocks_per_usec = (CLOCKS_PER_SEC / 1000000); + + if (clocks_per_usec > 0.0) + *usec = (uint32)(uelapsed / clocks_per_usec); + else + *usec = 0; +} + diff --git a/libfreerdp-utils/stream.c b/libfreerdp-utils/stream.c new file mode 100644 index 0000000..5435175 --- /dev/null +++ b/libfreerdp-utils/stream.c @@ -0,0 +1,76 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Stream Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +STREAM* stream_new(int size) +{ + STREAM* stream; + + stream = xnew(STREAM); + + if (stream != NULL) + { + if (size != 0) + { + size = size > 0 ? size : 0x400; + stream->data = (uint8*) xzalloc(size); + stream->p = stream->data; + stream->size = size; + } + } + + return stream; +} + +void stream_free(STREAM* stream) +{ + if (stream != NULL) + { + if (stream->data != NULL) + xfree(stream->data); + + xfree(stream); + } +} + +void stream_extend(STREAM* stream, int request_size) +{ + int pos; + int original_size; + int increased_size; + + pos = stream_get_pos(stream); + original_size = stream->size; + increased_size = (request_size > original_size ? request_size : original_size); + stream->size += increased_size; + + if (original_size == 0) + stream->data = (uint8*) xmalloc(stream->size); + else + stream->data = (uint8*) xrealloc(stream->data, stream->size); + + memset(stream->data + original_size, 0, increased_size); + stream_set_pos(stream, pos); +} diff --git a/libfreerdp-utils/string.c b/libfreerdp-utils/string.c new file mode 100644 index 0000000..c3b2a3a --- /dev/null +++ b/libfreerdp-utils/string.c @@ -0,0 +1,39 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * String Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +void freerdp_string_read_length32(STREAM* s, rdpString* string, UNICONV* uniconv) +{ + stream_read_uint32(s, string->length); + string->unicode = (char*) xmalloc(string->length); + stream_read(s, string->unicode, string->length); + string->ascii = freerdp_uniconv_in(uniconv, (uint8*) string->unicode, string->length); +} + +void freerdp_string_free(rdpString* string) +{ + if (string->unicode != NULL) + xfree(string->unicode); + + if (string->ascii != NULL) + xfree(string->ascii); +} diff --git a/libfreerdp-utils/svc_plugin.c b/libfreerdp-utils/svc_plugin.c new file mode 100644 index 0000000..72379d5 --- /dev/null +++ b/libfreerdp-utils/svc_plugin.c @@ -0,0 +1,410 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Static Virtual Channel Interface + * + * Copyright 2009-2011 Jay Sorg + * Copyright 2010-2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The list of all plugin instances. */ +typedef struct rdp_svc_plugin_list rdpSvcPluginList; +struct rdp_svc_plugin_list +{ + rdpSvcPlugin* plugin; + rdpSvcPluginList* next; +}; + +static rdpSvcPluginList* g_svc_plugin_list = NULL; + +/* For locking the global resources */ +static freerdp_mutex g_mutex = NULL; + +/* Queue for receiving packets */ +struct _svc_data_in_item +{ + STREAM* data_in; + RDP_EVENT* event_in; +}; +typedef struct _svc_data_in_item svc_data_in_item; + +static void svc_data_in_item_free(svc_data_in_item* item) +{ + if (item->data_in) + { + stream_free(item->data_in); + item->data_in = NULL; + } + if (item->event_in) + { + freerdp_event_free(item->event_in); + item->event_in = NULL; + } + xfree(item); +} + +struct rdp_svc_plugin_private +{ + void* init_handle; + uint32 open_handle; + STREAM* data_in; + + LIST* data_in_list; + freerdp_thread* thread; +}; + +static rdpSvcPlugin* svc_plugin_find_by_init_handle(void* init_handle) +{ + rdpSvcPluginList * list; + rdpSvcPlugin * plugin; + + freerdp_mutex_lock(g_mutex); + for (list = g_svc_plugin_list; list; list = list->next) + { + plugin = list->plugin; + if (plugin->priv->init_handle == init_handle) + { + freerdp_mutex_unlock(g_mutex); + return plugin; + } + } + freerdp_mutex_unlock(g_mutex); + return NULL; +} + +static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle) +{ + rdpSvcPluginList * list; + rdpSvcPlugin * plugin; + + freerdp_mutex_lock(g_mutex); + for (list = g_svc_plugin_list; list; list = list->next) + { + plugin = list->plugin; + if (plugin->priv->open_handle == open_handle) + { + freerdp_mutex_unlock(g_mutex); + return plugin; + } + } + freerdp_mutex_unlock(g_mutex); + return NULL; +} + +static void svc_plugin_remove(rdpSvcPlugin* plugin) +{ + rdpSvcPluginList* list; + rdpSvcPluginList* prev; + + /* Remove from global list */ + freerdp_mutex_lock(g_mutex); + for (prev = NULL, list = g_svc_plugin_list; list; prev = list, list = list->next) + { + if (list->plugin == plugin) + break; + } + if (list) + { + if (prev) + prev->next = list->next; + else + g_svc_plugin_list = list->next; + xfree(list); + } + freerdp_mutex_unlock(g_mutex); +} + +static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, uint32 dataLength, + uint32 totalLength, uint32 dataFlags) +{ + STREAM* data_in; + svc_data_in_item* item; + + if (dataFlags & CHANNEL_FLAG_FIRST) + { + if (plugin->priv->data_in != NULL) + stream_free(plugin->priv->data_in); + plugin->priv->data_in = stream_new(totalLength); + } + + data_in = plugin->priv->data_in; + stream_check_size(data_in, (int) dataLength); + stream_write(data_in, pData, dataLength); + + if (dataFlags & CHANNEL_FLAG_LAST) + { + if (stream_get_size(data_in) != stream_get_length(data_in)) + { + printf("svc_plugin_process_received: read error\n"); + } + + plugin->priv->data_in = NULL; + stream_set_pos(data_in, 0); + + item = xnew(svc_data_in_item); + item->data_in = data_in; + + freerdp_thread_lock(plugin->priv->thread); + list_enqueue(plugin->priv->data_in_list, item); + freerdp_thread_unlock(plugin->priv->thread); + + freerdp_thread_signal(plugin->priv->thread); + } +} + +static void svc_plugin_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event_in) +{ + svc_data_in_item* item; + + item = xnew(svc_data_in_item); + item->event_in = event_in; + + freerdp_thread_lock(plugin->priv->thread); + list_enqueue(plugin->priv->data_in_list, item); + freerdp_thread_unlock(plugin->priv->thread); + + freerdp_thread_signal(plugin->priv->thread); +} + +static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData, uint32 dataLength, + uint32 totalLength, uint32 dataFlags) +{ + rdpSvcPlugin* plugin; + + DEBUG_SVC("openHandle %d event %d dataLength %d totalLength %d dataFlags %d", + openHandle, event, dataLength, totalLength, dataFlags); + + plugin = (rdpSvcPlugin*)svc_plugin_find_by_open_handle(openHandle); + if (plugin == NULL) + { + printf("svc_plugin_open_event: error no match\n"); + return; + } + switch (event) + { + case CHANNEL_EVENT_DATA_RECEIVED: + svc_plugin_process_received(plugin, pData, dataLength, totalLength, dataFlags); + break; + case CHANNEL_EVENT_WRITE_COMPLETE: + stream_free((STREAM*)pData); + break; + case CHANNEL_EVENT_USER: + svc_plugin_process_event(plugin, (RDP_EVENT*)pData); + break; + } +} + +static void svc_plugin_process_data_in(rdpSvcPlugin* plugin) +{ + svc_data_in_item* item; + + while (1) + { + /* terminate signal */ + if (freerdp_thread_is_stopped(plugin->priv->thread)) + break; + + freerdp_thread_lock(plugin->priv->thread); + item = list_dequeue(plugin->priv->data_in_list); + freerdp_thread_unlock(plugin->priv->thread); + + if (item != NULL) + { + /* the ownership of the data is passed to the callback */ + if (item->data_in) + IFCALL(plugin->receive_callback, plugin, item->data_in); + if (item->event_in) + IFCALL(plugin->event_callback, plugin, item->event_in); + xfree(item); + } + else + break; + } +} + +static void* svc_plugin_thread_func(void* arg) +{ + rdpSvcPlugin* plugin = (rdpSvcPlugin*)arg; + + DEBUG_SVC("in"); + + IFCALL(plugin->connect_callback, plugin); + + while (1) + { + if (plugin->interval_ms > 0) + freerdp_thread_wait_timeout(plugin->priv->thread, plugin->interval_ms); + else + freerdp_thread_wait(plugin->priv->thread); + + if (freerdp_thread_is_stopped(plugin->priv->thread)) + break; + + freerdp_thread_reset(plugin->priv->thread); + svc_plugin_process_data_in(plugin); + + if (plugin->interval_ms > 0) + IFCALL(plugin->interval_callback, plugin); + } + + freerdp_thread_quit(plugin->priv->thread); + + DEBUG_SVC("out"); + + return 0; +} + +static void svc_plugin_process_connected(rdpSvcPlugin* plugin, void* pData, uint32 dataLength) +{ + uint32 error; + + error = plugin->channel_entry_points.pVirtualChannelOpen(plugin->priv->init_handle, + &plugin->priv->open_handle, plugin->channel_def.name, svc_plugin_open_event); + + if (error != CHANNEL_RC_OK) + { + printf("svc_plugin_process_connected: open failed\n"); + return; + } + + plugin->priv->data_in_list = list_new(); + plugin->priv->thread = freerdp_thread_new(); + + freerdp_thread_start(plugin->priv->thread, svc_plugin_thread_func, plugin); +} + +static void svc_plugin_process_terminated(rdpSvcPlugin* plugin) +{ + svc_data_in_item* item; + + freerdp_thread_stop(plugin->priv->thread); + freerdp_thread_free(plugin->priv->thread); + + plugin->channel_entry_points.pVirtualChannelClose(plugin->priv->open_handle); + xfree(plugin->channel_entry_points.pExtendedData); + + svc_plugin_remove(plugin); + + while ((item = list_dequeue(plugin->priv->data_in_list)) != NULL) + svc_data_in_item_free(item); + list_free(plugin->priv->data_in_list); + + if (plugin->priv->data_in != NULL) + { + stream_free(plugin->priv->data_in); + plugin->priv->data_in = NULL; + } + xfree(plugin->priv); + plugin->priv = NULL; + + IFCALL(plugin->terminate_callback, plugin); +} + +static void svc_plugin_init_event(void* pInitHandle, uint32 event, void* pData, uint32 dataLength) +{ + rdpSvcPlugin* plugin; + + DEBUG_SVC("event %d", event); + + plugin = (rdpSvcPlugin*)svc_plugin_find_by_init_handle(pInitHandle); + if (plugin == NULL) + { + printf("svc_plugin_init_event: error no match\n"); + return; + } + switch (event) + { + case CHANNEL_EVENT_CONNECTED: + svc_plugin_process_connected(plugin, pData, dataLength); + break; + case CHANNEL_EVENT_DISCONNECTED: + break; + case CHANNEL_EVENT_TERMINATED: + svc_plugin_process_terminated(plugin); + break; + } +} + +void svc_plugin_init(rdpSvcPlugin* plugin, CHANNEL_ENTRY_POINTS* pEntryPoints) +{ + rdpSvcPluginList* list; + + /** + * The channel manager will guarantee only one thread can call + * VirtualChannelInit at a time. So this should be safe. + */ + if (g_mutex == NULL) + g_mutex = freerdp_mutex_new(); + + memcpy(&plugin->channel_entry_points, pEntryPoints, pEntryPoints->cbSize); + + plugin->priv = xnew(rdpSvcPluginPrivate); + + /* Add it to the global list */ + list = xnew(rdpSvcPluginList); + list->plugin = plugin; + + freerdp_mutex_lock(g_mutex); + list->next = g_svc_plugin_list; + g_svc_plugin_list = list; + freerdp_mutex_unlock(g_mutex); + + plugin->channel_entry_points.pVirtualChannelInit(&plugin->priv->init_handle, + &plugin->channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, svc_plugin_init_event); +} + +int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out) +{ + uint32 error = 0; + + DEBUG_SVC("length %d", stream_get_length(data_out)); + + error = plugin->channel_entry_points.pVirtualChannelWrite(plugin->priv->open_handle, + stream_get_data(data_out), stream_get_length(data_out), data_out); + if (error != CHANNEL_RC_OK) + { + stream_free(data_out); + printf("svc_plugin_send: VirtualChannelWrite failed %d\n", error); + } + + return error; +} + +int svc_plugin_send_event(rdpSvcPlugin* plugin, RDP_EVENT* event) +{ + uint32 error = 0; + + DEBUG_SVC("event_type %d", event->event_type); + + error = plugin->channel_entry_points.pVirtualChannelEventPush(plugin->priv->open_handle, event); + + if (error != CHANNEL_RC_OK) + printf("svc_plugin_send_event: VirtualChannelEventPush failed %d\n", error); + + return error; +} diff --git a/libfreerdp-utils/thread.c b/libfreerdp-utils/thread.c new file mode 100644 index 0000000..14b6d58 --- /dev/null +++ b/libfreerdp-utils/thread.c @@ -0,0 +1,95 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Thread Utils + * + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#ifdef _MSC_VER +#include +#endif +#endif + +#include +#include +#include + +freerdp_thread* freerdp_thread_new(void) +{ + freerdp_thread* thread; + + thread = xnew(freerdp_thread); + thread->mutex = freerdp_mutex_new(); + thread->signals[0] = wait_obj_new(); + thread->signals[1] = wait_obj_new(); + thread->num_signals = 2; + + return thread; +} + +void freerdp_thread_start(freerdp_thread* thread, void* func, void* arg) +{ + thread->status = 1; + +#ifdef _WIN32 + { +# ifdef _MSC_VER + CloseHandle((HANDLE)_beginthreadex(NULL, 0, func, arg, 0, NULL)); +#else + CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, NULL)); +#endif + } +#else + { + pthread_t th; + pthread_create(&th, 0, func, arg); + pthread_detach(th); + } +#endif +} + +void freerdp_thread_stop(freerdp_thread* thread) +{ + int i = 0; + + wait_obj_set(thread->signals[0]); + + while (thread->status > 0 && i < 1000) + { + i++; + freerdp_usleep(100000); + } +} + +void freerdp_thread_free(freerdp_thread* thread) +{ + int i; + + for (i = 0; i < thread->num_signals; i++) + wait_obj_free(thread->signals[i]); + thread->num_signals = 0; + + freerdp_mutex_free(thread->mutex); + thread->mutex = NULL; + + xfree(thread); +} diff --git a/libfreerdp-utils/unicode.c b/libfreerdp-utils/unicode.c new file mode 100644 index 0000000..6524a35 --- /dev/null +++ b/libfreerdp-utils/unicode.c @@ -0,0 +1,240 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Unicode Utils + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +/* Convert pin/in_len from WINDOWS_CODEPAGE - return like xstrdup, 0-terminated */ + +char* freerdp_uniconv_in(UNICONV* uniconv, unsigned char* pin, size_t in_len) +{ + unsigned char *conv_pin = pin; + size_t conv_in_len = in_len; + char *pout = xmalloc(in_len * 2 + 1), *conv_pout = pout; + size_t conv_out_len = in_len * 2; + +#ifdef HAVE_ICONV + if (iconv(uniconv->in_iconv_h, (ICONV_CONST char **) &conv_pin, &conv_in_len, &conv_pout, &conv_out_len) == (size_t) - 1) + { + /* TODO: xrealloc if conv_out_len == 0 - it shouldn't be needed, but would allow a smaller initial alloc ... */ + printf("freerdp_uniconv_in: iconv failure\n"); + return 0; + } +#else + while (conv_in_len >= 2) + { + unsigned int wc; + + wc = (unsigned int)(unsigned char)(*conv_pin++); + wc += ((unsigned int)(unsigned char)(*conv_pin++)) << 8; + conv_in_len -= 2; + + if (wc >= 0xD800 && wc <= 0xDFFF && conv_in_len >= 2) + { + /* Code points U+10000 to U+10FFFF using surrogate pair */ + wc = ((wc - 0xD800) << 10) + 0x10000; + wc += (unsigned int)(unsigned char)(*conv_pin++); + wc += ((unsigned int)(unsigned char)(*conv_pin++) - 0xDC) << 8; + conv_in_len -= 2; + } + + if (wc <= 0x7F) + { + *conv_pout++ = (char)wc; + conv_out_len--; + } + else if (wc <= 0x07FF) + { + *conv_pout++ = (char)(0xC0 + (wc >> 6)); + *conv_pout++ = (char)(0x80 + (wc & 0x3F)); + conv_out_len -= 2; + } + else if (wc <= 0xFFFF) + { + *conv_pout++ = (char)(0xE0 + (wc >> 12)); + *conv_pout++ = (char)(0x80 + ((wc >> 6) & 0x3F)); + *conv_pout++ = (char)(0x80 + (wc & 0x3F)); + conv_out_len -= 3; + } + else + { + *conv_pout++ = (char)(0xF0 + (wc >> 18)); + *conv_pout++ = (char)(0x80 + ((wc >> 12) & 0x3F)); + *conv_pout++ = (char)(0x80 + ((wc >> 6) & 0x3F)); + *conv_pout++ = (char)(0x80 + (wc & 0x3F)); + conv_out_len -= 4; + } + } +#endif + + if (conv_in_len > 0) + { + printf("freerdp_uniconv_in: conversion failure - %d chars left\n", (int) conv_in_len); + } + + *conv_pout = 0; + return pout; +} + +/* Convert str from DEFAULT_CODEPAGE to WINDOWS_CODEPAGE and return buffer like xstrdup. + * Buffer is 0-terminated but that is not included in the returned length. */ + +char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len) +{ + size_t ibl; + size_t obl; + char* pin; + char* pout; + char* pout0; + + if (str == NULL) + { + *pout_len = 0; + return NULL; + } + + ibl = strlen(str); + obl = 2 * ibl; + pin = str; + pout0 = xmalloc(obl + 2); + pout = pout0; + +#ifdef HAVE_ICONV + if (iconv(uniconv->out_iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) + { + printf("freerdp_uniconv_out: iconv() error\n"); + return NULL; + } +#else + while ((ibl > 0) && (obl > 0)) + { + unsigned int wc; + + wc = (unsigned int)(unsigned char)(*pin++); + ibl--; + if (wc >= 0xF0) + { + wc = (wc - 0xF0) << 18; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80) << 12; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80) << 6; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80); + ibl -= 3; + } + else if (wc >= 0xE0) + { + wc = (wc - 0xE0) << 12; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80) << 6; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80); + ibl -= 2; + } + else if (wc >= 0xC0) + { + wc = (wc - 0xC0) << 6; + wc += ((unsigned int)(unsigned char)(*pin++) - 0x80); + ibl -= 1; + } + + if (wc <= 0xFFFF) + { + *pout++ = (char)(wc & 0xFF); + *pout++ = (char)(wc >> 8); + obl -= 2; + } + else + { + wc -= 0x10000; + *pout++ = (char)((wc >> 10) & 0xFF); + *pout++ = (char)((wc >> 18) + 0xD8); + *pout++ = (char)(wc & 0xFF); + *pout++ = (char)(((wc >> 8) & 0x03) + 0xDC); + obl -= 4; + } + } +#endif + + if (ibl > 0) + { + printf("freerdp_uniconv_out: string not fully converted - %d chars left\n", (int) ibl); + } + + *pout_len = pout - pout0; + *pout++ = 0; /* Add extra double zero termination */ + *pout = 0; + + return pout0; +} + +/* Uppercase a unicode string */ + +void freerdp_uniconv_uppercase(UNICONV *uniconv, char *wstr, int length) +{ + int i; + unsigned char* p; + unsigned int wc, uwc; + + p = (unsigned char*)wstr; + for (i = 0; i < length; i++) + { + wc = (unsigned int)(*p); + wc += (unsigned int)(*(p + 1)) << 8; + uwc = towupper(wc); + if (uwc != wc) + { + *p = uwc & 0xFF; + *(p + 1) = (uwc >> 8) & 0xFF; + } + p += 2; + } +} + +UNICONV* freerdp_uniconv_new() +{ + UNICONV *uniconv = xnew(UNICONV); + +#ifdef HAVE_ICONV + uniconv->iconv = 1; + uniconv->in_iconv_h = iconv_open(DEFAULT_CODEPAGE, WINDOWS_CODEPAGE); + if (errno == EINVAL) + { + printf("Error opening iconv converter to %s from %s\n", DEFAULT_CODEPAGE, WINDOWS_CODEPAGE); + } + uniconv->out_iconv_h = iconv_open(WINDOWS_CODEPAGE, DEFAULT_CODEPAGE); + if (errno == EINVAL) + { + printf("Error opening iconv converter to %s from %s\n", WINDOWS_CODEPAGE, DEFAULT_CODEPAGE); + } +#endif + + return uniconv; +} + +void freerdp_uniconv_free(UNICONV *uniconv) +{ + if (uniconv != NULL) + { +#ifdef HAVE_ICONV + iconv_close(uniconv->in_iconv_h); + iconv_close(uniconv->out_iconv_h); +#endif + xfree(uniconv); + } +} diff --git a/libfreerdp-utils/wait_obj.c b/libfreerdp-utils/wait_obj.c new file mode 100644 index 0000000..a2ba5b9 --- /dev/null +++ b/libfreerdp-utils/wait_obj.c @@ -0,0 +1,225 @@ +/** + * FreeRDP: A Remote Desktop Protocol client. + * Virtual Channel Manager + * + * Copyright 2009-2011 Jay Sorg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "config.h" +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#else +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +struct wait_obj +{ +#ifdef _WIN32 + HANDLE event; +#else + int pipe_fd[2]; +#endif + int attached; +}; + +struct wait_obj* +wait_obj_new(void) +{ + struct wait_obj* obj; + + obj = xnew(struct wait_obj); + + obj->attached = 0; +#ifdef _WIN32 + obj->event = CreateEvent(NULL, TRUE, FALSE, NULL); +#else + obj->pipe_fd[0] = -1; + obj->pipe_fd[1] = -1; + if (pipe(obj->pipe_fd) < 0) + { + printf("wait_obj_new: pipe failed\n"); + xfree(obj); + return NULL; + } +#endif + + return obj; +} + +struct wait_obj* wait_obj_new_with_fd(void* fd) +{ + struct wait_obj* obj; + + obj = xnew(struct wait_obj); + + obj->attached = 1; +#ifdef _WIN32 + obj->event = fd; +#else + obj->pipe_fd[0] = (int)(long)fd; + obj->pipe_fd[1] = -1; +#endif + + return obj; +} + +void +wait_obj_free(struct wait_obj* obj) +{ + if (obj) + { + + if (obj->attached == 0) + { +#ifdef _WIN32 + if (obj->event) + { + CloseHandle(obj->event); + obj->event = NULL; + } +#else + if (obj->pipe_fd[0] != -1) + { + close(obj->pipe_fd[0]); + obj->pipe_fd[0] = -1; + } + if (obj->pipe_fd[1] != -1) + { + close(obj->pipe_fd[1]); + obj->pipe_fd[1] = -1; + } +#endif + } + + xfree(obj); + } +} + +int +wait_obj_is_set(struct wait_obj* obj) +{ +#ifdef _WIN32 + return (WaitForSingleObject(obj->event, 0) == WAIT_OBJECT_0); +#else + fd_set rfds; + int num_set; + struct timeval time; + + FD_ZERO(&rfds); + FD_SET(obj->pipe_fd[0], &rfds); + memset(&time, 0, sizeof(time)); + num_set = select(obj->pipe_fd[0] + 1, &rfds, 0, 0, &time); + return (num_set == 1); +#endif +} + +void +wait_obj_set(struct wait_obj* obj) +{ +#ifdef _WIN32 + SetEvent(obj->event); +#else + int len; + + if (wait_obj_is_set(obj)) + return; + len = write(obj->pipe_fd[1], "sig", 4); + if (len != 4) + printf("wait_obj_set: error\n"); +#endif +} + +void +wait_obj_clear(struct wait_obj* obj) +{ +#ifdef _WIN32 + ResetEvent(obj->event); +#else + int len; + + while (wait_obj_is_set(obj)) + { + len = read(obj->pipe_fd[0], &len, 4); + if (len != 4) + printf("wait_obj_clear: error\n"); + } +#endif +} + +int +wait_obj_select(struct wait_obj** listobj, int numobj, int timeout) +{ +#ifndef _WIN32 + int max; + int sock; + int index; +#endif + fd_set fds; + int status; + struct timeval time; + struct timeval* ptime; + + ptime = 0; + if (timeout >= 0) + { + time.tv_sec = timeout / 1000; + time.tv_usec = (timeout * 1000) % 1000000; + ptime = &time; + } + +#ifndef _WIN32 + max = 0; + FD_ZERO(&fds); + if (listobj) + { + for (index = 0; index < numobj; index++) + { + sock = listobj[index]->pipe_fd[0]; + FD_SET(sock, &fds); + + if (sock > max) + max = sock; + } + } + status = select(max + 1, &fds, 0, 0, ptime); +#else + status = select(0, &fds, 0, 0, ptime); +#endif + + return status; +} + +void wait_obj_get_fds(struct wait_obj* obj, void** fds, int* count) +{ +#ifdef _WIN32 + fds[*count] = (void*) obj->event; +#else + if (obj->pipe_fd[0] == -1) + return; + + fds[*count] = (void*)(long) obj->pipe_fd[0]; +#endif + (*count)++; +} diff --git a/resources/FreeRDP-fav.ico b/resources/FreeRDP-fav.ico new file mode 100644 index 0000000000000000000000000000000000000000..258c083037b8589305b6b0274a1a5dd5f0fd8e0d GIT binary patch literal 1150 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 M<8nS#V_JvwKd)_Y9smFU literal 0 HcmV?d00001 diff --git a/resources/FreeRDP_Icon_256px.h b/resources/FreeRDP_Icon_256px.h new file mode 100644 index 0000000..497048b --- /dev/null +++ b/resources/FreeRDP_Icon_256px.h @@ -0,0 +1,8195 @@ +static unsigned long FreeRDP_Icon_256px_prop [] = { + 256, 256 + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 541756835u , 1615498659u + , 2152369571u , 2940898723u , 3209334179u , 3209334179u , 3209334179u , 2940898723u , 2152369571u , 1078627747u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 541756835u , 2152369571u , 3746205091u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 3746205091u , 1883934115u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 541756835u , 2672463267u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 2940898723u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 541756835u + , 2672463267u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 2672463267u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 2152369571u , 4014640547u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 810192291u , 3477769635u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2940898723u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4014640547u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 273321379u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 810192291u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 810192291u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1615498659u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 2404027811u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2672463267u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 273321379u , 3477769635u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 273321379u , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 541756835u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 273321379u , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 273321379u , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3209334179u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 273321379u + , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2404027811u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 273321379u , 3477769635u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1615498659u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 273321379u , 3477769635u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 541756835u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 273321379u , 3477769635u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 3477769635u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 273321379u , 3477769635u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 2404027811u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2940898723u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 810192291u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2672463267u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 3746205091u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 2404027811u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 2404027811u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 810192291u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1347063203u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 3746205091u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 810192291u , 4014640547u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 1883934115u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 273321379u , 3746205091u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 273321379u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 3477769635u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 2672463267u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 2672463267u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 1078627747u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1883934115u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3746205091u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1615498659u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 541756835u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4014640547u , 273321379u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2152369571u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2672463267u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 273321379u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1615498659u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2672463267u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 810192291u , 4014640547u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 810192291u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 273321379u , 3477769635u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3477769635u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2672463267u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1615498659u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 273321379u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 541756835u , 4014640547u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 2940898723u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3477769635u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 1347063203u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2404027811u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 273321379u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 2940898723u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 273321379u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 1615498659u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2940898723u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 541756835u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1615498659u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 3477769635u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 541756835u , 4014640547u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 2404027811u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 1347063203u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 1883934115u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 273321379u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 541756835u , 4014640547u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 3477769635u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 2404027811u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1883934115u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 1347063203u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 541756835u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 541756835u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3746205091u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2940898723u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 273321379u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2152369571u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2940898723u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1078627747u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 273321379u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 273321379u , 3746205091u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4014640547u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 2152369571u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3209334179u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 810192291u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 2404027811u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1883934115u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 1078627747u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 273321379u , 4014640547u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 273321379u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2404027811u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 3211638728u , 3211638728u + , 3211638728u , 2154674120u , 275625928u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 810192291u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283668652u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4016945096u , 1617803208u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283800239u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1349367752u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1347063203u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284261046u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 275625928u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284392888u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284788159u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 544061384u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 273321379u + , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284919745u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 2672463267u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 544061384u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 541756835u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3211638728u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283536810u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 1078627747u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283668652u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 3748509640u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283800239u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1347063203u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283800238u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4016945096u , 275625928u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280836731u , 4284524473u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2674767816u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280573046u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4282417045u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 3480074184u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278992474u , 4284524473u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1886238664u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u , 4280309360u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 275625928u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278860632u , 4278597203u , 4278597203u , 4278597203u + , 4283273123u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278992474u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4281165439u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4283668395u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1615498659u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4279453282u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u + , 544061384u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 3746205091u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4282219924u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 2943203272u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 1078627747u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1349367752u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3748509640u , 275625928u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 810192291u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282417045u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2672463267u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4284985281u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 812496840u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 541756835u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280704632u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1617803208u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279453282u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 275625928u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278992474u , 4284524473u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 541756835u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3480074184u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4283668395u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4279453282u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u + , 544061384u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 2672463267u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4284985281u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1349367752u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 4014640547u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3748509640u , 275625928u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 1347063203u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284524473u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2404027811u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 544061384u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3746205091u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 810192291u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1349367752u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1883934115u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4282219924u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284129202u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 275625928u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 2940898723u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 4014640547u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4284524473u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 275625928u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 810192291u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 1615498659u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4279453282u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 275625928u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 2672463267u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278860632u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4283273123u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1886238664u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3477769635u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280704632u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 1078627747u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 2674767816u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 1615498659u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280309617u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4280704632u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4016945096u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2404027811u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280836731u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280836731u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2406332360u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 3746205091u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4281429125u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3480074184u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1347063203u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4282812574u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282417045u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 1886238664u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2406332360u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 2404027811u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278860632u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 3480074184u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3477769635u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284129202u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280836731u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280836731u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4281956239u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1347063203u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4278860632u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4279716967u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2404027811u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4280309617u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283207845u , 4283668652u , 4283800239u , 4284261046u , 4284261046u , 4284524474u , 4284788159u , 4284788159u + , 4284788159u , 4284788159u , 4285117123u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284524473u + , 4283668395u , 4283668395u , 4283668395u , 4283668395u , 4282417045u , 4282021774u , 4282021774u , 4280309360u + , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283536810u , 4283800239u , 4284261046u , 4284656316u , 4284919745u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284985281u , 4283668395u , 4282417045u , 4281560710u , 4280309360u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2943203272u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3209334179u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283207845u , 4283800239u , 4284392888u + , 4284788159u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4284129202u , 4282417045u , 4280704632u , 4278992474u , 4278597203u , 4282021774u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283207845u , 4283800239u , 4284392888u , 4285117123u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4284524473u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 1349367752u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283339432u , 4284063667u + , 4284788159u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 544061384u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283536810u , 4284392888u , 4285117123u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3748509640u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283339432u , 4284063667u , 4284919745u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2674767816u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 541756835u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283800239u , 4284656316u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1349367752u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283207845u , 4284261046u , 4285117123u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3748509640u , 1617803208u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283339432u , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 1617803208u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283668652u + , 4284788159u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3211638728u , 1080932296u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283668652u , 4284788159u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u + , 275625928u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283668652u , 4284788159u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4016945096u , 1349367752u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1615498659u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283339432u , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 2943203272u , 275625928u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283207845u + , 4284261046u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 1349367752u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283800239u , 4285117123u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2406332360u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283339432u , 4284788159u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3480074184u , 275625928u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4284261046u , 4285248710u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u + , 812496840u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283536810u , 4284919745u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4016945096u , 1617803208u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4284063667u , 4285248710u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 1617803208u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283207845u , 4284788159u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283668652u , 4285248710u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284261046u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283207845u , 4284656316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283536810u , 4284919745u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283668652u , 4285248710u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 1617803208u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283932081u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284261046u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4016945096u , 812496840u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284524474u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 3480074184u , 275625928u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284524474u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 2943203272u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4283076003u , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1886238664u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4283076003u , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 812496840u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4283076003u , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 275625928u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4283076003u + , 4284524474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2406332360u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283076003u , 4284524474u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283076003u , 4283932081u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u + , 275625928u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283076003u , 4283932081u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2152369571u , 4283076003u , 4283536810u , 4285248710u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 544061384u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4283207845u , 4285248710u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1078627747u , 4284919745u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2406332360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 3748509640u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1617803208u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 1617803208u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 544061384u , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3480074184u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1617803208u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 2154674120u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3748509640u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 812496840u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1617803208u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3480074184u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3480074184u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2154674120u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 544061384u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 3211638728u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284985281u , 4282021774u , 4281560710u , 4280309360u , 4280309360u , 4280309360u + , 4280309360u , 4280309360u , 4280309360u , 4280309360u , 4280309360u , 4282021774u , 4282417045u , 540702606u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1349367752u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280704632u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4010161747u + , 805713491u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3748509640u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 3473290835u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 1611019859u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 275625928u , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 3204855379u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 268842579u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 275625928u , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 1342584403u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 2147890771u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 275625928u + , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4283273123u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 2667984467u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 2154674120u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284985281u , 4283668395u , 4282812316u , 4282021774u , 4282021774u , 4282021774u + , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4282812316u , 4283668395u , 4284985281u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282021774u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 3204855379u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 3748509640u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4282812316u + , 4281165439u , 4279453282u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u + , 4280704632u , 4282417045u , 4284524473u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284524473u , 4281165439u , 4279453282u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278992474u , 2402578311u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 1617803208u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4282812316u , 4280309360u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4282417045u , 4284985281u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4284985281u , 4283668395u , 4283273123u , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4283668395u + , 4284129202u , 4285380552u , 3748509640u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 3211638728u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4284524473u , 4282021774u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4284524473u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 544061384u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 544061384u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u + , 4282021774u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4281165439u , 4284524473u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 1886238664u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 2406332360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283273123u , 4278992474u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278992474u , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 2943203272u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 4016945096u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4280704632u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4284524473u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 1349367752u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4278992474u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4283273123u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 812496840u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 2674767816u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1617803208u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 4016945096u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4282673278u , 4284711316u , 4286815145u + , 4286815145u , 4283725193u , 4282673278u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 1349367752u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u + , 4284711316u , 4288853183u , 4292929258u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4292929258u , 4288853183u , 4284711316u + , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4281165439u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3480074184u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 2674767816u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283725193u , 4289839305u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4289839305u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4281560710u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 3748509640u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283668395u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4284711316u , 4292929258u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967033u + , 4294901234u , 4294900973u , 4294900972u , 4292863195u , 4284711052u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 812496840u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4278992474u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4281687155u , 4290891220u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294901235u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4291876815u , 4280635239u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1886238664u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1886238664u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4285763230u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967031u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4293914854u , 4285763230u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279453282u , 4284985281u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2943203272u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282417045u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4289839305u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294900974u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294967033u + , 4288853183u , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281560710u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3211638728u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284524473u , 4278992474u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4291877343u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4288853183u , 4283724934u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294901235u + , 4294967295u , 4291877343u , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 812496840u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4291877343u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4292929258u , 4282673278u , 4278597203u , 4282673273u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4291876817u + , 4288853183u , 4294967295u , 4291877343u , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 544061384u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1617803208u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284524473u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4291877343u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4291877343u , 4279649118u , 4278597203u , 4278597203u , 4280635238u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4290825158u + , 4278597203u , 4284711316u , 4294967295u , 4291877343u , 4279649118u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 2674767816u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4289839305u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4291877343u + , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4291876815u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4287800745u + , 4278597203u , 4278597203u , 4284711316u , 4294967295u , 4288853183u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279453282u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 3211638728u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4284524473u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4285763230u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4293915380u , 4279649118u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283724931u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4280635238u + , 4278597203u , 4278597203u , 4278597203u , 4288853183u , 4294967295u , 4285763230u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4282021774u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4281687155u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4284711316u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4286749088u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4284711052u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4293915380u , 4293915380u , 4280635241u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280704632u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3211638728u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 812496840u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4279453282u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4290891220u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4292929258u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283724931u + , 4291876815u , 4294900972u , 4294900972u , 4294900972u , 4290825158u , 4282673273u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4285763230u , 4294967295u , 4290891220u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 1080932296u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4284129202u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4283725193u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4285763230u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4282673273u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4294967295u , 4294967295u , 4282673278u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4282021774u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4291877343u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4280635241u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4290891220u , 4294967295u , 4290891220u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4280704632u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1080932296u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2406332360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4293915380u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4286815145u , 4294967295u , 4294967295u + , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278992474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 1617803208u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3211638728u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4288853183u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284711316u , 4294967295u , 4294967295u + , 4288853183u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2154674120u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3211638728u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283668395u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4293915380u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 2674767816u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283725193u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283725193u , 4294967295u , 4294967295u + , 4294967295u , 4283725193u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 3211638728u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282021774u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4287801268u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4291877343u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4286815145u , 4294967295u , 4294967295u + , 4294967295u , 4287801268u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4016945096u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4281560710u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4291877343u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4279649118u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4288853183u , 4294967295u , 4294967295u + , 4294967295u , 4290891220u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4283725193u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4292929258u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 812496840u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280635241u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4288853183u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278992474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4280635241u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4290891220u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 1617803208u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4283725193u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278992474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4285763230u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4280635241u , 4293915380u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4281560710u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4284711316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4279649118u , 4291877343u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280309360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282021774u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4286815145u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4281687155u , 4293915380u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4280704632u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4291877343u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u , 4287801268u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4280635241u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4282021774u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 3748509640u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283668395u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4291877343u , 4285763230u , 4281687155u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4280635241u , 4283725193u , 4288853183u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4292929258u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4291877343u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4289839305u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4288853183u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278992474u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283668395u , 4283668395u , 4282021774u + , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4282021774u , 4282021774u + , 4282417045u , 4283668395u , 4283668395u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 544061384u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 1080932296u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4282021774u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4285763230u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4284711316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4280704632u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4284524473u , 4282812316u , 4281165439u , 4279848553u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4280635238u , 4282673273u , 4286749088u , 4286749088u , 4286749088u , 4286749088u , 4285762966u , 4282673273u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279453282u , 4281165439u , 4284985281u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 812496840u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4284129202u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280635241u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4280635241u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4282417045u , 4279848553u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279648861u , 4286749088u , 4292862937u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u + , 4293914850u , 4287800745u , 4279648861u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4279453282u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4291877343u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4291877343u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284524473u , 4281165439u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281686896u , 4293914850u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4289838780u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283273123u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1080932296u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4282021774u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4285763230u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4284711316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4284524473u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4292862937u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4290825158u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282021774u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 1617803208u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 4016945096u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4284524473u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279649118u + , 4293915380u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4293915380u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4282021774u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4292862937u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u + , 4294900972u , 4293914850u , 4283724931u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3211638728u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4286815145u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4286815145u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284524473u , 4280309360u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281686896u , 4291876815u , 4294900972u , 4294900972u + , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4294900972u , 4293914850u + , 4288787123u , 4280635238u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284524473u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 3211638728u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284524473u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4279649118u , 4293915380u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4292929258u , 4279649118u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4278992474u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281686896u , 4285762966u + , 4287800745u , 4290825158u , 4290825158u , 4290825158u , 4287800745u , 4286749088u , 4282673273u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4281165439u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4284711316u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4283725193u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u , 4278992474u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 2154674120u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4278992474u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4290891220u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4289839305u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 1080932296u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282417045u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4279649118u , 4293915380u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4292929258u , 4279649118u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281560710u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4284524473u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4284985281u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 812496840u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4281687155u , 4293915380u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4293915380u , 4281687155u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279453282u , 4284985281u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4281560710u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4279848553u , 4284985281u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2943203272u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4278992474u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284711316u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4283725193u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4279848553u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 3480074184u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4284711316u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4284711316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4279453282u , 4284985281u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 2674767816u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4293915380u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4293915380u , 4281687155u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4281560710u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278992474u , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1886238664u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281687155u + , 4291877343u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4291877343u + , 4280635241u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4281165439u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4282021774u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u + , 4284129202u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 3211638728u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 1080932296u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4282812316u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4286815145u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4286815145u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4281165439u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4280309360u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4284129202u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2406332360u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4282812316u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4281687155u , 4290891220u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u , 4280635241u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282417045u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4282812316u , 4279453282u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4283668395u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 3480074184u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4279453282u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282673278u , 4289839305u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4288853183u , 4282673278u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278992474u , 4283273123u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4281165439u + , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 2406332360u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284985281u , 4280704632u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4280635241u , 4285763230u + , 4290891220u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u + , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4294967295u , 4290891220u + , 4285763230u , 4279649118u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4280309360u , 4284524473u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4283273123u , 4281165439u , 4278992474u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 1617803208u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4283273123u , 4279453282u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4282673278u , 4285763230u , 4287801268u , 4290891220u , 4290891220u , 4290891220u + , 4290891220u , 4290891220u , 4290891220u , 4286815145u , 4285763230u , 4282673278u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278992474u , 4282417045u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4284129202u , 4281560710u , 4279453282u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u , 4278597203u + , 4278597203u , 4278597203u , 4278597203u , 4282812316u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u , 4285380552u + , 4285380552u , 2154674120u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u + , 0u , 0u , 0u , 0u , 0u , 0u , 0u , 0u +}; diff --git a/resources/FreeRDP_Icon_256px.png b/resources/FreeRDP_Icon_256px.png new file mode 100644 index 0000000000000000000000000000000000000000..b43d8c5cd5f859c02e4b7e6929e8c7430b20de1b GIT binary patch literal 6586 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 c #60A7B9", +", c #245C76", +"' c #205670", +") c #174C67", +"! c #063653", +"~ c #407F95", +"{ c #0C3E5A", +"] c #0A3B58", +"^ c #4D8FA3", +"/ c #67AFC1", +"( c #2D667F", +"_ c #5397AB", +": c #134662", +"< c #3D7D94", +"[ c #3A778E", +"} c #39778F", +"| c #5A9FB2", +"1 c #265E78", +"2 c #46879C", +"3 c #205771", +"4 c #316C85", +"5 c #46889E", +"6 c #194E69", +"7 c #4C90A5", +"8 c #60A7BA", +"9 c #69B2C3", +"0 c #62AABC", +"a c #336E86", +"b c #4E92A8", +"c c #599FB3", +"d c #6BB4C6", +"e c #579DB1", +"f c #346F87", +"g c #44687E", +"h c #638194", +"i c #839BA9", +"j c #547589", +"k c #16435E", +"l c #A2B4BF", +"m c #E0E6EA", +"n c #FFFFFF", +"o c #B1C0C9", +"p c #FFFEF9", +"q c #FEFDF2", +"r c #FEFCED", +"s c #FEFCEC", +"t c #DFE4DB", +"u c #63808C", +"v c #355C73", +"w c #C1CDD4", +"x c #FEFDF3", +"y c #D0D7CF", +"z c #254F67", +"A c #738E9E", +"B c #FFFEF7", +"C c #EFF0E6", +"D c #FEFCEE", +"E c #D0D9DF", +"F c #547486", +"G c #446879", +"H c #D0D7D1", +"I c #254F66", +"J c #C0CBC6", +"K c #92A5A9", +"L c #EFF2F4", +"M c #547483", +"N c #8299A0", +"O c #254F69", +"P c #92A7B4", +"Q c #738D96", +"R c #16425D", +"S c #DFE3D9", +"T c #EFF0E2", +"U c #355B70", +"V c #B1BEBC", +"W c #A1B2B3", +" ....... ", +" ............. ", +" ................. ", +" .................... ", +" ...................... ", +" ........................ ", +" .......................... ", +" ........................... ", +" ............................ ", +" ............................. ", +" ............................... ", +" ................................ ", +" ................................. ", +" .................................. ", +" ................................... ", +" .................................... ", +" ..................................... ", +" ..................................... ", +" ...................................... ", +" ....................................... ", +" ........................................ ", +" ........................................ ", +" ......................................... ", +" .......................................... ", +" ......................................... ", +" .......................................... ", +" .......................................... ", +" ........................................... ", +" ............................................ ", +" ............................................ ", +" ............................................ ", +" ............................................ ", +" ............................................. ", +" .............................................. ", +" .............................................. ", +" .............................................. ", +" .............................................. ", +" ............................................... ", +" ............................................... ", +" ............................................... ", +" ................................................ ", +" ................................................ ", +" ................................................. ", +" ................................................. ", +" ................................................. ", +" .................................................. ", +" .................................................. ", +" ................................................... ", +" ................................................... ", +" ................................................... ", +" .................................................... ", +" ..................................................... ", +" .................................................... ", +" ..................................................... ", +" ...................................................... ", +" ...................................................... ", +" ....................................................... ", +" ....................................................... ", +" ....................................................... ", +" ........................................................ ", +" ......................................................... ", +" ......................................................... ", +" ......................................................... ", +" ......................................................... ", +" .......................................................... ", +" ...........................................................++++ ", +" ..........................................................@+++++ ", +" ...........................................................#++++++ ", +" ...........................................................$+++++++ ", +" ............................................................%++++++++ ", +" .............................................................&++++++++ ", +" .............................................................*+++++++++ ", +" ..............................................................++++++++++ ", +" ..............................................................+++++++++++ ", +" ..............................................................=+++++++++++ ", +" ..............................................................@++++++++++++ ", +" ...............................................................#+++++++++++++ ", +" ...............................................................-+++++++++++++ ", +" ................................................................;>+++++++++++++ ", +" ................................................................,'+++++++++++++ ", +" .................................................................)!~+++++++++++++ ", +" .................................................................)!{>++++++++++++ ", +" ..................................................................)!!'+++++++++++++ ", +" ..................................................................]!!!^+++++++++++++ ", +" ...................................................................!!!!{/++++++++++++ ", +" ...................................................................!!!!!(+++++++++++++ ", +" ....................................................................!!!!!!_+++++++++++++ ", +" ....................................................................!!!!!!:/++++++++++++ ", +" ....................................................................++++++++++++ ", +" ........................................................................}!!!!!!!!!!!!!'+++++++++++++ ", +" .........................................................................}!!!!!!!!!!!!!!_+++++++++++++ ", +" .........................................................................}!!!!!!!!!!!!!!:+++++++++++++ ", +" .........................................................................}!!!!!!!!!!!!!!![+++++++++++++ ", +" ..........................................................................}!!!!!!!!!!!!!!!{/++++++++++++ ", +" ..........................................................................}!!!!!!!!!!!!!!!!(+++++++++++++ ", +" ..........................................................................}!!!!!!!!!!!!!!!!!>+++++++++++++ ", +" ...........................................................................}!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" ...........................................................................}!!!!!!!!!!!!!!!!!!_+++++++++++++ ", +" ...........................................................................}!!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" ...........................................................................+++++++++++++ ", +" .............................................................................!!!!!!!!!!!!!!!!!!!![++++++++++++++ ", +" .............................................................................!!!!!!!!!!!!!!!!!!!!:++++++++++++++ ", +" ..............................................................................]!!!!!!!!!!!!!!!!!!!!^+++++++++++++ ", +" ..............................................................................)!!!!!!!!!!!!!!!!!!!!1++++++++++++++ ", +" ..............................................................................)!!!!!!!!!!!!!!!!!!!!!/+++++++++++++ ", +" ..............................................................................)!!!!!!!!!!!!!!!!!!!!!2++++++++++++++ ", +" ..............................................................................3!!!!!!!!!!!!!!!!!!!!!1++++++++++++++ ", +" ...............................................................................;!!!!!!!!!!!!!!!!!!!!!!/+++++++++++++ ", +" ...............................................................................;!!!!!!!!!!!!!!!!!!!!!!2++++++++++++++ ", +" ...............................................................................4!!!!!!!!!!!!!!!!!!!!!!(++++++++++++++ ", +" ...............................................................................}!!!!!!!!!!!!!!!!!!!!!!{++++++++++++++ ", +" ...............................................................................}!!!!!!!!!!!!!!!!!!!!!!!|+++++++++++++ ", +" ...............................................................................5!!!!!!!!!!!!!!!!!!!!!!!~+++++++++++++ ", +" .................................................................................!!!!!!!!!!!!!!!!!!!!!!!(++++++++++++++ ", +" .................................................................................]!!!!!!!!!!!!!!!!!!!!!!6++++++++++++++ ", +" .................................................................................)!!!!!!!!!!!!!!!!!!!!!!!++++++++++++++ ", +" .................................................................................)!!!!!!!!!!!!!!!!!!!!!!!|+++++++++++++ ", +" .................................................................................;!!!!!!!!!!!!!!!!!!!!!!!_+++++++++++++ ", +" .................................................................................;!!!!!!!!!!!!!!!!!!!!!!![+++++++++++++ ", +" .................................................................................}!!!!!!!!!!!!!!!!!!!!!!![+++++++++++++ ", +" .................................................................................}!!!!!!!!!!!!!!!!!!!!!!![+++++++++++++ ", +" ..................................................................................!!!!!!!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" ...................................................................................]!!!!!!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" ...................................................................................)!!!!!!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" ...................................................................................3!!!!!!!!!!!!!!!!!!!!!!'+++++++++++++ ", +" .....................................................................7@#$$8&&&&9++++>____~[[''!!!!!!!!!!!!(+++++++++++++ ", +" ...............................................................=#$0*+++++++++++++++++++++++++++/_~a'!!!!!![+++++++++++++ ", +" ..........................................................7#%&+++++++++++++++++++++++++++++++++++++++|~1{![+++++++++++++ ", +" ......................................................7#%9+++++++++++++++++++++++++++++++++++++++++++++++|>++++++++++++ ", +" ...................................................bc&+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ................................................=%9++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .............................................bc*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ...........................................#0+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ........................................7$9++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ......................................b8+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ....................................@&+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..................................@&+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ................................@&++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..............................b8++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .............................7$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ............................#9++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..........................b&+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .........................$d+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .......................=*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ......................cd++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ....................7&++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ...................@d++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..................$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ................70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ...............=*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..............@d++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .............e+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ............$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ...........8+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..........8+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .........8++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ........8++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .......8++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ......8++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" .....8+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ....e+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ...e+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ..=d+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" 7d+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/[a''''''''[~ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++1!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!! ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!! ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++(!!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++{!!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++^!!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/_2[[[[[[[2_/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[!!!!!!!!!!!!!! ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++++++/2(:!!!!!!!!!!!!!{1~>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>(:!!!!!!!!!{f ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++++/2'!!!!!!!!!!!!!!!!!!!!!6~/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++/_^[[[[_|++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++>[{!!!!!!!!!!!!!!!!!!!!!!!!!!(>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++/[{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++^{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++/1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++|{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{^++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!![+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!!!!!!!!!!!!gghiijgg!!!!!!!!!!!!!!!!!!!(+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!!!!!!!!khlmnnnnnnnnnnmlhk!!!!!!!!!!!!!!!(++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!!!!!!!jonnnnnnnnnnnnnnnnnnog!!!!!!!!!!!!!!a+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++_!!!!!!!!!!!!hmnnnnnnnnnnnnnnnnnnpqrstu!!!!!!!!!!!!!2++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++/{!!!!!!!!!!vwnnnnnnnnnnnnnnnnnnnxssssssyz!!!!!!!!!!!!|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!AnnnnnnnnnnnnnnnnnnnnBssssssssCA!!!!!!!!!!!:/+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++~!!!!!!!!!konnnnnnnnnnnnnnnnnnnnnDsssssssssplk!!!!!!!!!!a+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++>{!!!!!!!!kEnnnnnnnnnnnnnnnnnnnnlFssssssssssxnEk!!!!!!!!!!_++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++(!!!!!!!!kEnnnnnnnnnnnnnnnnnnnmg!GssssssssssHlnEk!!!!!!!!!6++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++>!!!!!!!!kEnnnnnnnnnnnnnnnnnnnEk!!IssssssssssJ!hnEk!!!!!!!!!2+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++(!!!!!!!!onnnnnnnnnnnnnnnnnnnEk!!!!ysssssssssK!!hnl!!!!!!!!!:++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++>!!!!!!!!AnnnnnnnnnnnnnnnnnnnLk!!!!!MsssssssssI!!!lnA!!!!!!!!!_+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++[!!!!!!!vnnnnnnnnnnnnnnnnnnnnh!!!!!!!Nsssssssu!!!!kLLO!!!!!!!!1+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++:!!!!!!!wnnnnnnnnnnnnnnnnnnnm!!!!!!!!!MysssJG!!!!!!Anw!!!!!!!!!/++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++|!!!!!!!jnnnnnnnnnnnnnnnnnnnnA!!!!!!!!!!!!G!!!!!!!!!knng!!!!!!!!2++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++[!!!!!!!EnnnnnnnnnnnnnnnnnnnnO!!!!!!!!!!!!!!!!!!!!!!!wnw!!!!!!!!1++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++'!!!!!!gnnnnnnnnnnnnnnnnnnnnL!!!!!!!!!!!!!!!!!!!!!!!!inng!!!!!!!{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++!!!!!!!lnnnnnnnnnnnnnnnnnnnnw!!!!!!!!!!!!!!!!!!!!!!!!hnnl!!!!!!!!|++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++_!!!!!!knnnnnnnnnnnnnnnnnnnnnw!!!!!!!!!!!!!!!!!!!!!!!!gnnL!!!!!!!!2++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++2!!!!!!jnnnnnnnnnnnnnnnnnnnnnw!!!!!!!!!!!!!!!!!!!!!!!!jnnnj!!!!!!![++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++[!!!!!!PnnnnnnnnnnnnnnnnnnnnnE!!!!!!!!!!!!!!!!!!!!!!!!innnP!!!!!!!'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++a!!!!!!Ennnnnnnnnnnnnnnnnnnnnnk!!!!!!!!!!!!!!!!!!!!!!!lnnnw!!!!!!!'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++'!!!!!!nnnnnnnnnnnnnnnnnnnnnnnj!!!!!!!!!!!!!!!!!!!!!!!mnnnn!!!!!!!'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++'!!!!!Onnnnnnnnnnnnnnnnnnnnnnnl!!!!!!!!!!!!!!!!!!!!!!gnnnnn!!!!!!!{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++'!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnO!!!!!!!!!!!!!!!!!!!!!wnnnnng!!!!!!!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++'!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnw!!!!!!!!!!!!!!!!!!!!jnnnnnng!!!!!!{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++'!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnnA!!!!!!!!!!!!!!!!!!OLnnnnnng!!!!!!'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++a!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnnnh!!!!!!!!!!!!!!!!kEnnnnnnng!!!!!!'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++[!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnnnni!!!!!!!!!!!!!!vLnnnnnnnng!!!!!!1+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++2!!!!!gnnnnnnnnnnnnnnnnnnnnnnnnnnnnEg!!!!!!!!!!kPnnnnnnnnnnO!!!!!![+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++_!!!!!!nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnEAv!!!!Ojlnnnnnnnnnnnn!!!!!!!2+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++!!!!!!mnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnE!!!!!!!|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++'!!!!!onnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnl!!!!!!{++++++++++++++++++++++++++++++++++++++++++++++++++++__[[[[[[[[[~__++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++[!!!!!Annnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnh!!!!!!1+++++++++++++++++++++++++++++++++++++++++++++++>2(6!!!!IGNNNNQG!!!!:(/++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++|!!!!!OnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnO!!!!!!2++++++++++++++++++++++++++++++++++++++++++++/~6!!!!!RNSssssssssTKR!!!6++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++:!!!!!EnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnE!!!!!!!/++++++++++++++++++++++++++++++++++++++++++>(!!!!!!!UTssssssssssssV!!!!^+++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++[!!!!!Annnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnh!!!!!!(+++++++++++++++++++++++++++++++++++++++++>(!!!!!!!!!SsssssssssssssJ!!!![+++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++>!!!!!kLnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnL!!!!!!!_++++++++++++++++++++++++++++++++++++++++[{!!!!!!!!!!SssssssssssssTM!!!!2++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++(!!!!!innnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnni!!!!!!6+++++++++++++++++++++++++++++++++++++++>'!!!!!!!!!!!!UysssssssssTWI!!!!!>++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++>!!!!!kLnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmk!!!!!!2++++++++++++++++++++++++++++++++++++++|{!!!!!!!!!!!!!!!UQKJJJKNG!!!!!!!6+++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++(!!!!!hnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnj!!!!!!'++++++++++++++++++++++++++++++++++++++2{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2+++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++/{!!!!!wnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnno!!!!!!!_+++++++++++++++++++++++++++++++++++++|!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++~!!!!!kLnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnmk!!!!!!a+++++++++++++++++++++++++++++++++++++>{!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6/++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++'!!!!!vLnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnLv!!!!!!:/+++++++++++++++++++++++++++++++++++++a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6/+++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++/{!!!!!hnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnj!!!!!!!|++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6/++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++|!!!!!!hnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnh!!!!!!!2+++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:/+++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++2!!!!!!gLnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnLv!!!!!!!a++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!{|++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++2!!!!!!vEnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnEO!!!!!!!(+++++++++++++++++++++++++++++++++++++++++[!!!!!!!!!!!!!!!!!!!!!!!!!!!!{|+++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++2!!!!!!!innnnnnnnnnnnnnnnnnnnnnnnnnnni!!!!!!!!(+++++++++++++++++++++++++++++++++++++++++++'!!!!!!!!!!!!!!!!!!!!!!!!!!{|++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++2{!!!!!!vwnnnnnnnnnnnnnnnnnnnnnnnnwO!!!!!!!!~+++++++++++++++++++++++++++++++++++++++++++++2:!!!!!!!!!!!!!!!!!!!!!!!!_+++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++|:!!!!!!!gonnnnnnnnnnnnnnnnnnnnlg!!!!!!!!{^++++++++++++++++++++++++++++++++++++++++++++++++|({!!!!!!!!!!!!!!!!!!!!2++++++++++++++++++++ ", +" ++++++++++++++++++++++++++++++++++++++++++++++++++/1!!!!!!!!OAwnnnnnnnnnnnnnnwAk!!!!!!!!!'>++++++++++++++++++++++++++++++++++++++++++++++++++++^({!!!!!!!!!!!!!!!!2+++++++++++++++++++++ ", +" +++++++++++++++++++++++++++++++++++++++++++++++++++^:!!!!!!!!!!gAPwwwwwwiAg!!!!!!!!!!!{~+++++++++++++++++++++++++++++++++++++++++++++++++++++++++|a:!!!!!!!!!!!!2++++++++++++++++++++++ "}; diff --git a/resources/FreeRDP_Logo_Icon.ai b/resources/FreeRDP_Logo_Icon.ai new file mode 100644 index 0000000..f7e55c3 --- /dev/null +++ b/resources/FreeRDP_Logo_Icon.ai @@ -0,0 +1,4650 @@ +%PDF-1.5 %âãÏÓ +1 0 obj <>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + FreeRDP_Logo_Icon + + + + + 2011-08-01T20:34:57+02:00 + 2011-08-01T20:34:57+02:00 + 2011-08-01T20:34:57+02:00 + Adobe Illustrator CS5.1 + + + + 256 + 204 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAzAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FVskkccbSSMEjQF ndiAAAKkknoBirxbz7+aN5qM8mn6JK1tpyEo9yhKyT9qgjdU9up7+GZ+HTgbnm6fU6wyNR5IT8nh dv5yVomb0lgla6oTQpSg5f7NlyWprgY6C/E+D3bNc7p2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku xV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV5J+bnnhnkfy5p0lI0/46Mqn7TdRCCOw/a+7xzN0 2L+Iur12p/gHxeV5mOre1fktoa22hz6vIv76/cpEfCKIkbfN+VfkMwNVOzXc7ns/HUOLvei5iue7 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 xL0/5VZzXj9qo4/719fpx/ffikj8p+OJ/9k= + + + + + + uuid:3f9dfa49-13c5-43ef-b449-19dceef32d35 + xmp.did:A52CEDF16CBCE011BC36B4B7420BD8A9 + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:29e17876-faee-8948-9286-1741a44a591b + xmp.did:F77F11740720681188C6A5613A2C864B + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:A52CEDF16CBCE011BC36B4B7420BD8A9 + 2011-08-01T20:34:52+02:00 + Adobe Illustrator CS5.1 + / + + + + + + Document + Print + + + False + False + 1 + + 210.001652 + 296.999959 + Millimeters + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + White + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 0.000000 + + + Black + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 100.000000 + + + CMYK Red + CMYK + PROCESS + 0.000000 + 100.000000 + 100.000000 + 0.000000 + + + CMYK Yellow + CMYK + PROCESS + 0.000000 + 0.000000 + 100.000000 + 0.000000 + + + CMYK Green + CMYK + PROCESS + 100.000000 + 0.000000 + 100.000000 + 0.000000 + + + CMYK Cyan + CMYK + PROCESS + 100.000000 + 0.000000 + 0.000000 + 0.000000 + + + CMYK Blue + CMYK + PROCESS + 100.000000 + 100.000000 + 0.000000 + 0.000000 + + + CMYK Magenta + CMYK + PROCESS + 0.000000 + 100.000000 + 0.000000 + 0.000000 + + + C=15 M=100 Y=90 K=10 + CMYK + PROCESS + 14.999998 + 100.000000 + 90.000004 + 10.000002 + + + C=0 M=90 Y=85 K=0 + CMYK + PROCESS + 0.000000 + 90.000004 + 84.999996 + 0.000000 + + + C=0 M=80 Y=95 K=0 + CMYK + PROCESS + 0.000000 + 80.000001 + 94.999999 + 0.000000 + + + C=0 M=50 Y=100 K=0 + CMYK + PROCESS + 0.000000 + 50.000000 + 100.000000 + 0.000000 + + + C=0 M=35 Y=85 K=0 + CMYK + PROCESS + 0.000000 + 35.000002 + 84.999996 + 0.000000 + + + C=5 M=0 Y=90 K=0 + CMYK + PROCESS + 5.000001 + 0.000000 + 90.000004 + 0.000000 + + + C=20 M=0 Y=100 K=0 + CMYK + PROCESS + 19.999999 + 0.000000 + 100.000000 + 0.000000 + + + C=50 M=0 Y=100 K=0 + CMYK + PROCESS + 50.000000 + 0.000000 + 100.000000 + 0.000000 + + + C=75 M=0 Y=100 K=0 + CMYK + PROCESS + 75.000000 + 0.000000 + 100.000000 + 0.000000 + + + C=85 M=10 Y=100 K=10 + CMYK + PROCESS + 84.999996 + 10.000002 + 100.000000 + 10.000002 + + + C=90 M=30 Y=95 K=30 + CMYK + PROCESS + 90.000004 + 30.000001 + 94.999999 + 30.000001 + + + C=75 M=0 Y=75 K=0 + CMYK + PROCESS + 75.000000 + 0.000000 + 75.000000 + 0.000000 + + + C=80 M=10 Y=45 K=0 + CMYK + PROCESS + 80.000001 + 10.000002 + 44.999999 + 0.000000 + + + C=70 M=15 Y=0 K=0 + CMYK + PROCESS + 69.999999 + 14.999998 + 0.000000 + 0.000000 + + + C=85 M=50 Y=0 K=0 + CMYK + PROCESS + 84.999996 + 50.000000 + 0.000000 + 0.000000 + + + C=100 M=95 Y=5 K=0 + CMYK + PROCESS + 100.000000 + 94.999999 + 5.000001 + 0.000000 + + + C=100 M=100 Y=25 K=25 + CMYK + PROCESS + 100.000000 + 100.000000 + 25.000000 + 25.000000 + + + C=75 M=100 Y=0 K=0 + CMYK + PROCESS + 75.000000 + 100.000000 + 0.000000 + 0.000000 + + + C=50 M=100 Y=0 K=0 + CMYK + PROCESS + 50.000000 + 100.000000 + 0.000000 + 0.000000 + + + C=35 M=100 Y=35 K=10 + CMYK + PROCESS + 35.000002 + 100.000000 + 35.000002 + 10.000002 + + + C=10 M=100 Y=50 K=0 + CMYK + PROCESS + 10.000002 + 100.000000 + 50.000000 + 0.000000 + + + C=0 M=95 Y=20 K=0 + CMYK + PROCESS + 0.000000 + 94.999999 + 19.999999 + 0.000000 + + + C=25 M=25 Y=40 K=0 + CMYK + PROCESS + 25.000000 + 25.000000 + 39.999998 + 0.000000 + + + C=40 M=45 Y=50 K=5 + CMYK + PROCESS + 39.999998 + 44.999999 + 50.000000 + 5.000001 + + + C=50 M=50 Y=60 K=25 + CMYK + PROCESS + 50.000000 + 50.000000 + 60.000002 + 25.000000 + + + C=55 M=60 Y=65 K=40 + CMYK + PROCESS + 55.000001 + 60.000002 + 64.999998 + 39.999998 + + + C=25 M=40 Y=65 K=0 + CMYK + PROCESS + 25.000000 + 39.999998 + 64.999998 + 0.000000 + + + C=30 M=50 Y=75 K=10 + CMYK + PROCESS + 30.000001 + 50.000000 + 75.000000 + 10.000002 + + + C=35 M=60 Y=80 K=25 + CMYK + PROCESS + 35.000002 + 60.000002 + 80.000001 + 25.000000 + + + C=40 M=65 Y=90 K=35 + CMYK + PROCESS + 39.999998 + 64.999998 + 90.000004 + 35.000002 + + + C=40 M=70 Y=100 K=50 + CMYK + PROCESS + 39.999998 + 69.999999 + 100.000000 + 50.000000 + + + C=50 M=70 Y=80 K=70 + CMYK + PROCESS + 50.000000 + 69.999999 + 80.000001 + 69.999999 + + + + + + Grays + 1 + + + + C=0 M=0 Y=0 K=100 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 100.000000 + + + C=0 M=0 Y=0 K=90 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 89.999402 + + + C=0 M=0 Y=0 K=80 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 79.998797 + + + C=0 M=0 Y=0 K=70 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 69.999701 + + + C=0 M=0 Y=0 K=60 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 59.999102 + + + C=0 M=0 Y=0 K=50 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 50.000000 + + + C=0 M=0 Y=0 K=40 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 39.999402 + + + C=0 M=0 Y=0 K=30 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 29.998803 + + + C=0 M=0 Y=0 K=20 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 19.999701 + + + C=0 M=0 Y=0 K=10 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 9.999102 + + + C=0 M=0 Y=0 K=5 + CMYK + PROCESS + 0.000000 + 0.000000 + 0.000000 + 4.998803 + + + + + + Brights + 1 + + + + C=0 M=100 Y=100 K=0 + CMYK + PROCESS + 0.000000 + 100.000000 + 100.000000 + 0.000000 + + + C=0 M=75 Y=100 K=0 + CMYK + PROCESS + 0.000000 + 75.000000 + 100.000000 + 0.000000 + + + C=0 M=10 Y=95 K=0 + CMYK + PROCESS + 0.000000 + 10.000002 + 94.999999 + 0.000000 + + + C=85 M=10 Y=100 K=0 + CMYK + PROCESS + 84.999996 + 10.000002 + 100.000000 + 0.000000 + + + C=100 M=90 Y=0 K=0 + CMYK + PROCESS + 100.000000 + 90.000004 + 0.000000 + 0.000000 + + + C=60 M=90 Y=0 K=0 + CMYK + PROCESS + 60.000002 + 90.000004 + 0.003099 + 0.003099 + + + + + + + + + Adobe PDF library 9.90 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 12 0 R/TrimBox[0.0 0.0 595.28 841.89]/Type/Page>> endobj 8 0 obj <>stream +H‰”—ÍŽ¹„ïõ|.‘Éÿ«eÀ'Ã0|ð lïA»ÀZÀz{‘dwW[´ÂÓÍ®"™?‘‘‘þö1|øëÇþôçáøýˆa”tŽ꬧pÛËÿþëøgøíøðñ1¼}ñœ³ó¿ë_á½xæVBøüÆ;áÿ|>~)DþRH±ž}´ŒC£Þ~=ôè׃í‡z¦”C*g‹%”³6 ï‡åÓÌX¦ŠaÄ iœ–{(õ±†ÔÏgx;Ê8{2­ëcž³R:{«aÚYS +ã̕[î/EgΒÂ,ç(ÓMÏ¡ð1-Ü*«Á›¹ž•ÓXÞ‚ öÍp˜S×ÃÚÙ±àVN\ +–Îœ›V•“ޏ[Ng+=ÜúiØψí·t–\<"oÇ¿¿‘ >Ìã!\ỄMÇôAxz?sïå6àÈ|žêŽ×q•Ë'×LÙ¢ ¥eÁÍ?9Qs¸apœò’/­~àõQ!¯ G¸¸´p˜‰žÇù¾½´ÓZû¦jX/cræ¦ÒɗñòÍ@‡BÄcb$»¿l¿¿«óvšb\;àÑõwßçiUá,gIä¹F6›¤ÔÈ¥yÎ<ªšð¡©cÖ YɝøûéPã¸üð˶q¸yž ‚ ñý+˙‹å‰ŒE uIÛϑ¨xݒB‚‰y‚_¬0®!u,s$¬)Ÿ‰è]9v#ꦨ7vՐ[J…îãMsTꕽ"?¬s½¯¯ÿÒf;§'±NÞ²KâB¬ÔuDz³Ù¨Fî%ÖùŒ”pé“ênÔo +¯b׏cÙزŒÃtK¬ë9û &C8²×ƒuÇqjŋOáVj‡Nπœ…íZ ¥Ãª@Ʋ&¯ÒÖMw9س9јiÅI"…f.s¼D§+Z„Ná±é›¾$,3;eQ †&¾zĈ{'þ«*&À+¾‚ôB«Û<£3KS˜”_"Ósè«n)F‡A“£–04GÀŒ8)p¬à@´’P%±Vò=x6ìë + kcÖˆGà§Øκ×M瓷²*J¿xzWIq@‚uwù%ŽàëíÀÄmA@*=â‚ÅüN®¡Gá>)Xg¢]-áJ¬YNëq3™ÀÍ5ê +%‹ì˜R¿6|T¹¿M’@±È“Ò—¬ÚDÚ_V¶Ò_ ô¥†(áäÙ<Ìvö¢ÕðD³cÕëbŒhEŸ¼ ¤êmXè׊¿ùgє8ô²”fqyxkBÕô$ásìj&Üߢ„jNkRóí¨æ’}Žò«H·¦Ð4-Эπ*>CÚì/*õt»õ•ª~1…ˆG¸¹¸d’ªkì$Þèë]Ó_¼ª‡PãßT:$£)„˜å"‰ERz_Ì[”ÄÇ¿ü̘¹?uX†æLró‰-×"¡V×½ÄC2°úHCª¤¶¡#z\%œ½JBLc9 M0"ÁÖà£ÙFt­8Mdɹ(»+ðE³Œä$BÙ|òØaOûÀ3½*sÊ¡s,Ֆª´­8‡Í‘äååëŸ' :RïJë$——$-®ŠêEJ!' ­C*vÉrjr ƒÒzMÖ4låDRÕ„*f1Õx’äòy”J¿[m‹²TƒÍªÃ¦š~V_)9ƒ”9±Á^; ëÎv\,&d.)ü³>ÖÂ=™÷7TÒëó„½vªØßïöÖÿ;ûyô¾|ÿïû~Hp—f¹é`]õyu­ø 'í0EÙº¶?Ÿkî/ŠýóX±öçþµt¿ÖW VæÛ|W»—òjÝ»ˆ÷m?›?ð-ѧð(ͬW'%/§š‹*×·>©ÚîZk-càÒó @ë¹ï^«5ø×ýûÚä{Úãн\­K÷:îMßê¼ô HY˜#\"]{a}ÓHæùØÀ€¶©ü÷£ˆ3$’<Åâ uúÇ9Hx+Ë¡,™‰¼„¨Ǎ‹4Q¶é;×AK*ÕäOÅÉX%=üñ£¹nœ«ò$hђõß~¥!nÀ©±${~¥¸¦“@WGC»êz?P5ɛX3©GQ–] o*Ãtª –šéЕgàÖ*A×A‡P{,­+¡˜«_$èyÓ¤ð=íïë-IZ©åäý[c+êfÎ,þP扊ìhº¬tæ«ÚHN¿c2כöÿ(/c$„BˆöžÂ#øP;–Èۛ·ñ;6V „°û–pÛBtJ›Ø3¼|è¶Ìbò=3ژ`oï-àCá™2Ð+§ð pV#f CæKGç²c¯ßÍx¤¸ã”ž]g˜ÈZßŒ¦É0@œuŠ‡² A•T,S˜"È8ÓVk§ÀµPŸ¹ôˆ*ʶ¹Iöi§žU Á;®z(Ã9sÑþ[4b¢:ý—ƒpFb‹U;4–†îLPíP"«[EA¸«5º¸ûyyOۇ*îÛ5‡—WÆ<# +endstream endobj 12 0 obj <>stream +8;Z]!4-mc<#XqBgbZ%I$`CQ70UZG2bD.`isr'QVTG6:%!30AicDB:bt>?G!0=BJ[- +kRk7i$@1fA.^Zmbah-pd9r-tn9o^X4pdQR,j<;35Lab?;q,MgeWfg0cnbSOkJjblM*"YdI#.3gUf?WDUba*S.Yk=\.Bt4ip1@0%81@3&dMaX +V9Ok[QC8#BG"t@:oP9JU$7Dt-bDbm8+!;@t8nSa0m^J@c6@D$HD9)6iT3mbF9&39* +(#sQ`KGY5KPFQQoOn)R\Km5i%Q$*M"b,J4Kk' +/1`>'rd"DN!*0i#D?~> +endstream endobj 13 0 obj [/Indexed/DeviceRGB 255 14 0 R] endobj 14 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 5 0 obj <> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 11 0 obj <> endobj 10 0 obj [/ICCBased 17 0 R] endobj 17 0 obj <>stream +H‰””uTÔKÇtKˆ”ˆKJI,‚t(݋»4ìKÇÒÝ%Ò¹´H—4J#‚Ò’‚(H +w¹÷þqÏyïyßó~Ï3çù̙gÎ<3ó̄Y9El +@¸ ]äÕ!OÔÌ-@ãÀà\€ˆ¹¥+BVKK Àè:øOX×~òþ¿ÿWCa®–iHKL€…À0qÍY¦–Ë `ø5àcü€Âæk–Ë +XŠ]¶x=†äß ðš8¯ÙÚÜ üX€„Ŀ׽ƒ>Ÿ.Èf’‡›#aP§®¡¦Èünæ óD^{y8ÂËÅÖÚ  €d¡p H×Ë stå©:Yò€Äô׬cxc IŽVÈ?SÂÅ!þ:óè_úÃÆî¼9[ÂYbQ’PÒ~²+rA +SÊhª¦›«·HhÀ´†t^ôé ·'0±ß…€Â™kYæX¯ØY9îYq†q•p÷ólÝ'äãäW°Œ£…z„EÎÅèÄE$´%D>,–ê‘^|t*K)Ç%/§`¢è¦¯\¦Ò«úùñ‰•:¯†¼&D ®¦“¥[«7¨¿dplDa5–|ªmbõÌÓ4Ê,óy•y‡Å{Ëe辶5• «­œ½Žƒ©£µ“3Üìã’âš…,t+w¯ñhòl÷êõðõóõA  ö½ î é m k +¯‹xYU“›H„&%«¥È¤ +¥q¼ O'M¿zù3ãKæTÖ@v[NUnn^\¾o]¡a‘b±Tr£ä¢t»lºümE]e~Uü+¿jûאåZÑ:¶zª a·q®i ¹¡¥°5¡Íÿ};¤C¹S¤‹¥›¢û²ç[ï\_ÿۆw…ý‰þƒCa…¾Qº1¬±÷ŸÆ;>”L$Lz}4ÿ¤:%8M7Ìl̎ÎÕΧ/ø}¶XT^â]¦X>\™Ym[Ëùâ³n¸!´ycsk«ûkƶóŽÊ·;ßöv{¿§ýpßÓßúIþsû ÷0ëÈõXõ„éäàôݯÔ3ós®ó‹’ß&—$—õWÆWW˜*ØÂ)ÁãÅ!è$Ü$Æ%¡!e$cºÁHNOAKIMEq“„—úâÖÍí ÝýÃâíƕ;KLów§@˜‡YúX;ؚÙë8^Ý+çDspçñäðfßÏàKåOˆÅTC˜P°p J%†’D=ðè+å+íûÈO%$*©«˜¤”®œ¡’©šý8÷I¡Z½\£Z³^«U»K§_wLï“þ´Á¬á¼Ñ"dÙxíé¦Éö³]Ó}³£ç§æ–†»²º°>³9µ=²;°ßsøî¸ã´_G¬8/ºÌ¹N!GÝzÝ[<ª=‹½2½|B}½ýàþP”Q€z lH0Wc(EèeØnø|ÄPds::5&8Ö9îy¼F‚T"oÒídâ䳔¯©³iƒ/ZÓK^&gd:fg«äˆæ²çQçãælÎ ·£kJÐ¥™e‰åá¨J*ø+ëê篍kôj5ëÔêU”›š[”ZUÚ¿Ñh×é0ì|ÖeÙm×ãÒëÓò6ê]BÚ@ö`ñPÕpãHçèÀØÄû…ñûçñ?QM1MsψÍ*Ìiϛ.ØöZ [JYÎZ)X-]«úR»Þ¸ÑºÙ¾ÕõµwûãÎú·£ï¸?¨ö@û¼?Åä5Ž ǖ'v§N¿àgçÐ ƒß +—üW´×÷‡3ƒgƒÿŽŸL¬C#u!ó¼áMîMáMéEåvAms˔F‡V‘NŒž‹Aø¶£ÌGL’w…A¼Ì¬,ô¬äl¸l¿Ø¿s¬Ý›ááêænä©àͽŸÌÎï+€„‚!Bê²"¢¢ 'R&k?¾ÿ´3?Ã4+:§6o¾€ü¾˜¾T²\·Ò±Ú¿6úåÃúÄÆøæÈVß×ÖíʝÌoá»ðïF?LöžîüT;:ä>¢::>ž:©;ýeqÆvx^saõ›òwÝ¥úåʕóŸï'_E˜F”O\D’KšLtAnF¡F)FÅ|“èæõÔ­6š\Ú`º@z?äm+Fý;²L¼wiAh›y’¥͖Àîͽ§Á)ÁÅÎMÁý›g›wú~_ Ž@Œ ØZH_XA,Ê"F)Ž%¾/±*9ù ïaƒZ:ýQ”ŒŸ,\ÎB^_AUñ¡’€2« +­*‰êÕãƒ'[j êão5[´ª´óuR1uà­ïh`f¨m$1æxJgBdrölÇtÁläy»y¥E¦e$Ôfe¥g-g#`ËdGbwj¿î0áØáTOC9;¸¸Ê ¹Ü¨ÜÎÝ¿xŒz6zåx‡ù8ùøIû³£ÈP‡ó=A¥Á±!.¡†aÂAxۑü÷ϊ³‹˜Œ}bŽG-ø‘Þ’Ä“ª”‘•x–`—G˜/™ššê›Ôœ¿ªž–Ÿƒ q¡_¢O£?¤0¥"¦§§ý¨ó©êªâ«Û¬Õ­Ð®Ë¯Ç°Ä±Â²Á³Á´ÂµÅ¶È·Í¸Ó¹Ûºã»í¼ø¾¿À Á0Â@ÃRÄfÅzƏǦȾÉÖÊñÌ Í*ÎGÏcЀџҿÓàÕÖ'×LØsٛÚÄÛïÝÞFßsà¡áÏãäMå™æçè6é†êØì+í€î×ð1ñòïôMõª÷øZù«úöü:ý{þ»ÿÿÿ€€å´ÍTÌ?¥~òŒ”~i˜ž~L}ãÁ~cbAþ~’Da€dþ€ü¸~t‹yä~W‰²ÊÛ~Oˆ±>~\†´—/~‚…›|“~¾„º`éƒôC–ƒx¢€äƒßú£}%—âH}”1ÉX}%‘z¯Î}K•Ö}† {N}׋<_´~7‰‰AË~Àˆ-ψø¿|¢°à‚|žÉDz|+›®E|[—£”s|«”¦z} ‘æ^•}wO@¶}ÿ-Œ~ċÉ÷ {G®uÞÚ{D©zÆ{]¤Ä¬Ò{– f“{êœZxÚ|[˜»]ˆ|ϕM?¹}R’‹<}Ǝðõ…zªº]ÝYzŸ´Hħz³®‹«|zð©=‘â{L¤Nw²{ÀŸº\‹|=›>Ó|¼˜v|ېIô8z/ÆrÜ z¿;Ãbz'¸sªMzd²6ßzɬqvÒ{D§[®{À¢0> |;Ÿ| óyÑÒÈÚñy´ÊaÂIy¸Â©?yð»açzY´ÎvzÝ®Æ[{^©‡=c{ФÓI{Rò*yŒß„ÙýyfÕÓÁUy`Ìî¨Vy”Äâyþ½’uKz†·Zi{ ±Ü<Ú{z©%žzȎíí‰~+Ö~ˆ}±¾Í‡}W¦µ†0}3Ž…„}HtЄü}ŒZk„›}è=Ž„Ÿ~‹‹†z€ëɇ®‰Ն£‡}½…¹†!¥~„ø…ŒÐ„d„*s}ƒôƒˆYƒ¨ƒ<9ƒ¸‚àù…w„éû†p“øÓS…w‘u¼„œ¤ƒõ‹‰ƒu‹VrUƒ‰ÕWÿ‚؈|;,‚뇔ˆ„{‡¨èR…sžøѲ„ƒ›ºƒ²˜;¢¡ƒ•:Š8‚ ’¡q)‚PCV÷‚Ž:4‚.Œ–8ƒ‰ŠÉæȄªªÐ2ƒ»¥­¹‚ñ¡‚¡?‚U¤ˆîãšp £–çVu“ÿ9S†’ ‚šŒçåc„ µbÎփ°·µ‚Rªê ¹¦.‡ÕN¡Æný ¼U€ãš38‰€ó˜8¼ŒAä/ƒ‹ÀÚͬ‚œº‚¶’Î´zžô6®ß†è€Ó©°n1€“¤íT\€e Ø7݀tžXT‹·ã)ƒ$̯̕‚6Å;µ˜e¾Cž€Ê·Ë† €i±Ýmw€3¬Sƀ¨V7M€ +£\®€l‹GâN‚ÐØ»ËځæÐN´ÄÈa5€tÁ…N€ºzlÕß´ÍS<º°H6Ѽ¥*ôŠîÝ<’a|˜Çkz|C±VŽ²|šÇ|ƒ—‹·|IkžŠ‚|±Ru‰ˆ}26Ž‰'~2‹ÖÞÛF‘-†ËƏB…„°*ƒ„o™²‹üƒ‚ƒŠ­‚òjŒ‰‚ˆQ^ˆ£‚@5zˆI‚`Š˜ƒ†Ù³‘$ĝŽ"Ží®ýŒcŒß˜€Šñ‹&U‰³‰²ijˆ¦ˆ|PJ‡Ë‡v4v‡y‡ú‰V†»ØG›’Ã.2˜{­‹†•——Š’ý€ˆè¾hS‡æŽ¼O[‡Œÿ3†ÂŒˆ(‰„ÖéŽJ¦Áьx¢&¬$ŠÔžs•Ò‰h› +~æˆ2—êgK‡>•-N}†o’Ì2ن‘Á N‡%ˆÿÕ§±°ÇÀ›‹â¬ªöŠ>§w”´ˆÖ£A}⇤Ÿ\fX†§›ÚMµ…ݘù2,…Š—ò ¨†KˆÔ3»¥¿’‹g¶©ò‰Â°¦“¾ˆ[«¤} +‡0§ež†6¢çM …_Ÿ¯1… ? …—ˆ1Ó£ŒËÆǾ³‹ÀI©‰^º’ç‡ô´I|B†Ì¯dö…ܪwL‡…§e1$„¢¡: ®…‡æÒàŒrÒW½ûŠ°Êñ¨]‰ Ãá’1‡£½S{†z·|di…‹²ÇL „½®g0·„\ ð U„Ž‡©Ìû›ò{[¸“™G{!£ö–¸{ ŽÞ”`{&y’E{xbie{ùJrŽÚ|“/cŽ5}~ +~ÀË:šâ„ý·f˜#ƒç£•™‚üú“M‚Kx+‘CØa|ušI~÷.yWã ώ›ƒÉәߎ­¶—%ŒÂ¡å”˜ŠøŒá’[‰‰w!^ˆT`ƒŽž‡^H˜*† -§ŒŒ† 5G…èȨ˜ç˜Ž´ã–=•Î §“½“4‹»‘rív†Žÿ_ÒRG±Œf‹û,ދ̋ͯŒ…ßÇ|˜,¢†³Æ•„žúŸ{“ ›¬Š„Ò˜ªtìŽÙ•ô^1“ Fî‹Å‘Ä,;‹'‘¾<‹!…‘Æ_—›¬¥²²”õ¨Yžl’~¤J‰„J tŽS#]¸Œš'FA‹4—÷+®Š”—;ۊL…PÅf—&¶ì±É”€±Þ‰’­ˆªÕ¨šs@å¤]Œ0¡E±Š´žÓ+:Š›ÈևSS 𧠨ŒêjVPp,<XQ)‚XVl€(Js•&ÂJ!ÒûK{é½@B€ÐEŠ. œe°íÙWqQ䆓³â½ý~3ßÌ7ßÌçF£HI^ý\¨¯§¬ÁïÓ¡ƒåœ+j&YÅöÉbƒdMLÅÑÅ{#©©úè÷)Fø£ÛAŠ;q²ïT0Œ±_à ^¿£9IݤšxÖº¶Æ¢YFh“9ՅÆhX;Jõ²Æl¬ äÀín+jÅÄ¡®(Ým,Ö¼Jƒî(Va÷V/ÀÈÄaؑ”@ÈQ~.æ8_]±Èš7]ñÕÕÌÃãõÚgÕ|ÓFÕ) -—/ªºMH—|­Š¼øP´œ8™%èoFxàCÿ­<÷ªR×l® AÒ^«™ ÷QÊlÚÁzÙrJAUžUÿá™ÿd*ÿùüîNî$iÜÉ #Ÿv b7FÚ*4ނ÷ú¯ + Ëû§pv€iâx֖¼÷ŒÁIªão¥‡ìžËÝJÛ±á#ç +í¾ËW—àh…Ô‰Šlý"ùkx wVjGá“Dzˆ–ç*¸ÇߜxŸWÁŠ:Æ©d¿ÙPÀîæ$¹üЍjÀ4W·Mž¨[ÎÝ,]¢Ê«$ˆ–ÈWæî$I×&®åNˆ¬‘}ì7¨ sØþ»‹1@À9‡TɎ.íEÙÓzN¾Dfº*uwr þ„úØ ˆ *ª#Øùòë­,¥h؅Ãð"ä8=”³NÍ ¡%ƒ=(‰p¤â…QuÃ9søLӓ(î&Ãâˆwì¥Ú¾õ?±‚ER AHi.RÚ~ ԄË6õ ØÑâ¿:Ò*tД3*»–¿Û±ôx#ç‰m?r~3×û2ÿ+Êwù‰¾šp¸ÞÇ6‹yXaœTOÃ#Œã +U‹Â¼<·_)ÂIø(»Œ}¹ÓW2SÎX U€àwü õ¦ M¨–f›_T‰)•úà“Ÿ?k–YYF…ôK8ãÁu;J$óÀþ*1T…>,ë#h›%TÓ,…QÛ¥{[ëõsˆ:˜ü9󅼓¼&^!Փ˜a£â@Ò!ßÍ" yð +µ´.—÷Jl6mçHj†uÁ,béU6£+s©ì ýhܸdœ-Ê¥ª}…wiÀ-s´un=0ŠÄ½äi-_ˆ*)UÞâ_ˈ“âÚãb$ôöna+;ϧTø;pçpA7Û¨¾¨CÈ4åÏ.*·Iߥ›a‡8õ°MÌæm.‚þôACiü“€7»\j|fi³¹Õœ¹•Ô«)Ö÷]Þ­°jö¤À¡Ê„ÃÑâUò]¡3(íž ðwhöJÐÛcÉh-®4x7–“öh׿*P0¿H됎L‡žŠ®ëž‡Ú¡uê‰Õ¾°…Å×Ú,Ë{ÏBz}§…8¦v¶gÊgŸÒ²¤d[û!XTZçZ.ø·vlµA°¿g­Ñ +{;SÂm¶`vâîØ¿`~È?g¥a.œ +3žÃŒì{§­Çæ†L¨^–»¡¦ÔÅåW€ƒ¹¾ÍY¥eÆ4õ‚]¸Lû7oÞðýák˜õ¦ö!w·™™ð«Iý~»Ir»a^=¥Cë#ZÀ»hçÓ`Wï‡u}p¨Ãçê)¸À"®zœ7ff&²3© ’ß$ß©ôF’ø‘ÓÒJ8Ò¶5ãùÞmµ +u´®Râ_,^V¹àS&åaR´~PfÄÜLL_Dw¸ž*Ž‹`\Í-¦9]qîõ®¯¡ ¦Ý Â–Çô¹T¸Ií6)ÿ>u6 DÝ`eÍ¢/»–¢xq¶Y%¤9ÖÛʜ¼;«Ã¥Oêd\˾ÊP…&eRËzïç;¡]¥¹‹é.íRµ<oªÊΡù]öP{?¯:¦ r̨\˜µÝÊ»b õÒ¤â3|ª×íâm ¨s¢ØŸîÛÖW°9¢¨ñµæoZt]Rn“ÏÅ\½c…Wö#+…n•I&õgϽØÝy¸œAjsÑN‹06”HiD­±¸È'@ÿ¥ðõJ+¦ša5V~€cRˆIµõÌ«ïvwtUÓc[3+?F|l(ÑÑiÆÚU—žøô¥^+O—?Rí°Þs©šÿÿ—1ûHqilÑè$Wþhü›û™=¨ƒÀ(ÎRE +ØÁ1¯B›¹vџ¡®nÛ˜F/±ã BsßG³åÄÄÃMœYø«ëç9>£Ü–3……È—qIôƒ Ú£±¿5ƒµ¨ÕV‡Ü_À1È£¿Î²œåiÃñ¬JiXû0ÛWV–ÁîH[8g„«_î/ü¡£ +n3¥ `€ ¤Ðþ38A.|«f|ј0Iõ½6Öbå v«%Ó&ý ;Y®ý㿜Õ҄#ç‘dÿ–D.)Âì.p‚'ãï3ËJî›12K[DÌuÉ¥$s8·I<ÁR¨i©mì£J·¨8Ž}†ÿf€Ó ²åDJ¼Æ€àºƒws€!ÃÊ«®ŒÄr—æ¢RXÔÊ-\y^Í*Ó̏Ld'¨é›²9?) "Øqé×^…¦5µ/<4þ§i +¨ýQ<ŸÁÑÇ +›˜;/¹¥Ô±ìJB"¬‘ü7þØt͚ù©,mºóXdÚ¾^ë;촞Žñ&sà`«YÑ"à놠ÑYŸüŠ™¯{>ƊÕ.õßÀz^48¯‰e!¹ôR‘6}ØõvcûöìÆMiŸozî²Úoñ0¢'“=˜~µ¯Âi,3Ã:?-‹©Ý?oS,Ùõô9áÎüwß¼„µ¹þ#îÎRçOaƒìÙü£˜˜—ô;Æ ?àþäïŒåpïÍBäÒ­À +±ÖžI̝¼üO´ ݟ÷e#}Ô¯èN$í\êŠl?¼],÷ý Å·y,ÜÑ>&РôŠîä©øq]Âyhâ0AqñâK)ĝBÍF¶“ҍcH:ñì—-h-ñǟcȵêf)¯K9T£ã127]çÑä÷q·EjLˆâí•<>hÁ‹;ù|ãU +Ÿþ¼øםà”dÜp‚G +Æ«½`¹&!…Ïä8aðÉlû³›`83>Ì.‘òq„ŸÉ‚æn睅ŽÚÀ¤Aß9 +;èœ ï ¡‹­ê`¨¦H†ÚBÕyåg¼ Þ KBý ¯*kï㰗2fF„=#Ÿ OMã· éeT? +m­òTmê_¡å“ãOBۊV¡¸<ɆF('—n3u£G~†È®#Æ7Њö9•Á[ÃÙ¡`NísÞ.°P..콤 'Knpƒ–FÙ‚\„? ÇB>ƒöÆ-àî±Êõ`’ñ†½¯NÂèWßOŸOW«BƒªÊl¯f°¡xßìW ^ÐÔbžÚú-_Œx&*/¹ê(Œj´•‚µ_…=߆󑊢æŸzF–“´`éLd¯ßE:»¬—SN¸±ʔ@S 0Óþ¢3•|TÖO¹Ko³kÈÄtëßo}bF†Ùz$4á«â-ÕÐç,¨.mŒä'j*J¨œ|)JË6²Bµü¤‘°P ^Ã3ewÜ«pXúÁò.þ”*íù,0ÓÅ7xP­Ú³Å:2¿XOTç21|"7ùÄ=Ç0ãžß´©ãŽy}ĸB)Hä[èöžÝðFs´ ²òV¡+Ÿ±ò̯+Y(IŠ•™(º³‘Àx&Úá9JAIìÏã'tXmyœGÄ=œX[8éTK³)¦2œí©“<ÇTSRüv¥x£ã€lȓGO¤|Òg‚/÷{Ø>ãºÑ4Öù/’gËRçáŠF–ȶíà&æAÓ5”š2Ü uЯ*B<óiò뾘0Ògµr+OÍåA¸¾,0Ÿíî™-ŸbÅu¤g[ï\~¨-ôÛÙÐ4:I>幃A¾ÕuF‡ÇžÑ§©™ué¼DÅùº)B©,©*í?nÀ` 'qQIzÁ—K֗ö4Ž{ áB_g‡6Ÿ8­#ªÊ‰2.Aî$69¤!Ä̒Ñub1&Dð3Qxƒ"Þ >ɏnÞïνxüVG¿&•±TÛ¨ü†ö’Ó)©sx·d-5ºÄKx‹¢ÊÊàߣD&®1ä§ÁŸÂ±”¾œjðdû€GjJ•Ü|¨JÚ¹{ÅÛZ¢‹— Þ²Þf6ó½˜/vTñp̄ubšÙ ¼…P ½mBU#g«ëåB©gË·’)‘×-*ÔE +ar†Žæ>Ý>Ƶrn®[É­äFÓ-I ÊõByѸPå”=ÕþĶKâUC w…òG ùDéÁ}óØâ¤íñœ"¿µvN¯à.p•]ò]QÊÿ8uÊYµí{Ö#q¯éCÃáv}saü·¦x_o±òyÂiN™rÞÚœâ›À(« d8aÅw™2CöQç}Vš8ÓUWO\²g®……æ éÓ\«Ãôyk—@°¸d‚ óc…ê”Zñ‹t¨¿š9$ÜÙu +p†-œàú1ÏÝÛz(þ=Ôf) +‚vŠë¦ě9øØ¡Ö2ƒ w uûþ煼çïתÑõ#è…­Á{P6„+DÉËq3HIiŽû·Ù%„ûBóC‚’b¨!ÔÖÔkc5‡&U ):X®$܎–ºˆ[®Èb‰2¤*@ÀPkcӘ‚dÓoT©B_L1Uwi"É)ÉÌ=2#ù‹˜pI9, RêO>‡T@>è;¬bn¿Ðø¢€DÈþPuCý«ë›ŠfkÚéã^´^ü°\ÀŒG~•  »o—LÃRc¬HqÜ®=-8^5Ońµy*9‹û:-\òg8:T<á?*ÞýŽ´C;¢¶[‚µ·y¿XªÍïµ+±•ÙÊI©;÷lRLß­“$Dõ‹vYþTQ6üDyƒ€VmÖÛfy%/sIsƒ†mXP1ªLռȭ’¥«òvow)„QBµb™†ÐÀ_L¢V˜wuÅp§õ¦¶eėšõŽO*Ò“|Î+é]£(uH¼×°4ÊW¸U‹õ.ã{ Ê4Ó\ÿm.Q¿¿w‘ª¾ÒÕR~MAiÃçÀRz+%µBô‡ýóÈK‚ëzçª?'à{Àèñó kÏ҉ßaãêa§{ºèÛH]ÅþsX}dŠÁ°°a~ø3훧_•auƒ¹«Qz‚ ô ö‘¦žú˜VM\ĵv5I0ïL¾M£)ñºÇ„€pžæÂ1¿ý:5¡Ùð,ˆ&ºý©á4¨í %¦®Ã!$}o±“®cªÞ¤ã¨Aí]R^x„º‡T◬M&/BÔ:D¥wAêŒë2û4öÝÄÊ?šcîd&g]5¬b”¢’4³ôëa?«úèßû…iÐǐ»„ ìïĈÔý.OA 6Çvfv™sïd¡õ(5yTéÃHʐÍ/Põ”=…(¤a…›;zUs” ÎbÅWµã¶xéDa„)Eìʼ¤ $«sgÂPJár¿eÊYè3 wƒ€`¨cƒ™FÉo0|U[j5kÑçŒ.•5³Jç¡à&ª†åø°eŠT™Èo‘r …¨ÃˆÂ´´}I l­pàjC­á–û8cñ‡Ì5ÚJ=gç%U’®oó¤|L5çç­8E" +ِÿ®ß[Ak]Ùíûí„åJÛó‚͆áVBÆMí"{íNrÜòãæùQÕ¿òihЦ@€Y?ü 6³ñ^ß«ZWÙ¯î]Ø°¼c؋h¶KSLj:>®O ɲ…Õ÷.þÚáÝ°™µQŸ{5mm<Ù·?^Öv"ïÌ}Ùъw£÷9«ðOãØ&šv…ÄXÎ7‘km[ È,70nΒ7|÷éeÙážPÒÖ\I;<±çuë^`u‚!ËÍ$P´øŽ…B +ET9¢¤Ù²FÞW¬Àc»ƒã¹ám$úµ="G +}KÜe‹š6±~֔G_å³ÒìMËDÔ¿µs`± gî]£v¥p-9§\Nôžd{:´:Žgv¶HÖ_3fC;}ÐƓ PŸƒýNƒËp—H¯‹ídŠU9uÎ;ÂÁ´9$8wÈô ÿÜú3†rþ#¬AÄFÔiD1únŽà˜Ô-}õÉtþeÂÜÚ“D´í‡HÒ!5$Éš,IŠQ:¤È–RÂÜÏ1Ï3ÏÌ<Ï7ÇÇ ãj†1Œ[ÎЊTªÝmõ¾¨WwzU»xßù|öøþøÕ¾+ք{×úÈâöõW¿–>öò®p•ªœ:ʤùJRqY®ø¡^Éôê`ǯª<à~ó‰jûØ!mœr.ÜB­+‹Ù'«Ž”OyY+«äfN*żt ©WÑ$þ¨W\½2ï°Ôù½M_ê½c[ëgÕøñÿªjjö%WuU{{­,_¨°pêWœ–n%}P¬I^©WÑ|nˆ;c!¾p°…éu¼cʨÌN!k#¥´å)k„ì¯sdŸµ5nøŽû6Q{H10À×ëUì +œ¯è‡-£"{⠇TZG ôˆRØ,†ÍɇjࣶZw8j ICFöêÕ:½b [ Æ\+å?ˆ +èþ™oA n'a + +ÚôO¦j0ÀÕä`ê%µ|¶^é/si×_¦XÇ£ýLqiÔw]–Iç©Î­÷D"J¤î‘!y½!ñÔ¶®nˆ0²Rá zå WC¯³câcúh™üÈÅ«KÒ_R [úÓ*)! OSo‘©u©µ¶OÕ·Ó܌WÖãíze¯WÞCΓña½²¼ìÈϝ’Lê·Í÷/ÏQB´o³_“£kÇ/cg£ªÊ&MV?ÇÿÖ«5zõÝ !gÇôÌë"?wœ–P͚—IÏQ"´Î§ÈP­AdtE)q4þ±jŒðúGÁsƒÆÕnñ»{"” ‘óí}e®ÔUMÑrkÊùzvi89C}´ø®XóLB1W¾".ꕝ^M ”ÔûÄût?WK¢LÛwÕDP]t£U‘揊1r»J«ð·ÓÕ¸KÎÿV¹—ÈÿGM;phÌÕ·m æ‡v>èÀ-wgØõ©ë¡FNý ŒÊcIÜPþ#q‡òW• ŽÐËI –˜;ÇNáÙ¶þÅAÐ)ŃÞH~¡7iÛ tòhlƒ~ýÁ~dz²YË CûþåÎxŸ2>*c&Ÿm‰b›‰­ä{9f¢1X*²L˜ ß#>àíú + V@÷…¤g蒼]7n249=MÅÌÞìK% ¬;™’,ÙÓéœøFÎ\j˜ ð1ÅÑkl·Zå‚i¢×Ó؊’áíôœ²Î¡.|Q¼…9˜ŸÐ°¦$_.!“Ë;¤Ì¿¼l€ÎôEË,€ž²ûÉ¥Di­ùõ‡´¦êŽ}D‰É3^Êa`Y5Åg{J=mãìɳØéËyž3¸¢‰C¤M'¼jMê£-iŒÐ¦ÑmêÜ »n5? ÌSJÙE+U~ ô;·ˆí™Åq.t¶Xd÷¤Þ~œ˜Í~p*QÐeS¯¤%·.‘ŽÐ‹œ"Æ°ºöBs¡ª…ZÏ6-çîøÄ•6[\d;¤^z4’`;64藸ùú¤æͱw¶àô;ùŒÝ|ì+&®A©f¬LUàŽ3¬å¦åŸXòT»ßm°åô–¾)lãFí'l óVæɺÃgcGÙObßbɜ9ª;v \ºCƇL,Ž >B?ÝKGC¬·e"°z -@¼E´É£³Hûù»ILp<÷5¥À‘­ƒÄ'ðÐ҉¤èôàÞ$>ÜÖ8#ê„gäLÑ2®mš Áæc«ð¯Ü꨼1 èÀc‘ ®ðF¤w)™P¡ì+ÑrâkC q’p/Âu8#å!î*g‰…°ÈPaœ`vïu¡Ÿ@¾åo¡H`"Ž¤þ:üz–‹Ö_•‘Q<,DÒ>'Ӆ©ÓWP“²ó”§ .ÙÊÿ¾`¿xåW˜Ä3±|!6õ… » +£5„æù Elœ["Þ,0Ê eØòµÙ[Ozò‰Ì0~lúUO¤›+ùÓÚë&x£ì®kPù²c|uÉÙ$kþ.™?Ý{Qp""kÉí÷óÃÊrš6ÿisVûa‹ÄÏ=~‚@Wí_® +.<Ë7ª +­Å2Ë#h?c~¥m'r°ÕEÂ_ªxs…ë6‡ò¾øÍa»‰¥ÝÙü±¶Gµ+øš¶K 1¢þ4Œªä‰L^kUpø^^ù•_–ñmÓS^d‘Ш…§Ä'º­ùàµ>µ»Û}¦à5¶¾­—ð$:τ!EîÏ[«búJx&Õn› tº(ÒçmÀ;ZÿÏsF5u¦qX´.¡Õ‚£BqKPÁ € *£‚¢¸ l‚†„%{¸Ù“{³'÷æf';›,TT,¢bÁŠâhë¾Uqµ2Z”¹çŒ3çýü;ç}þžóüóT9Ävw´ÂRñR;GDž + Kû*ÃË/@hUvŽ„«…‰¯$÷jœ!@ጠÃvyבmŠû´,W²|-Í¢ –^¥ Õ~€Dô„²_Áô†­’"Æüĉâºàø#cØ禘Ï*íX/‡¸Ïœ“e>Ü|õXHÍù;û:˜Å)Ý÷‹d9gƖâ4àaBŒÈŸÿQ4óEÓ»w‘,C +Û¯B UÊ#à>ÉSV§$Lì-íÏ5gˆV ϯ*¢BüüÂ#‚ß}¶ npÃ¾Òtd½­¼ U˜$Dõb&$^¡\^Ò&Z"/˺+Ü-}¼Ò%è‚Z眅:}ðû9•‡ÆA‚ºYu§À æírTÜlP0Ô"šî·â~! Î͚*@5Kâ?óß«Zæ-â¿PÍó÷˜³µ=jô³>—Üˆ¬[üO?)¼a5û +®™›÷ñ?é¯ÆWóÓÐUs»ù‘°yÌ5^(ge›${C­‰âÏm>² "¤éÝG¸Õ£+Ú$Ø踿©—Ï«&¼æ XwÎÝÍÓêÆãÊ8?´Ígž‚,'ō=Ò"‚·—–/xÕúÏÂNþƒ¦îM)üïê'Ôòöº–ÌåÍEFÆÔq§rfÔ CįQ9ZY‘$r!ñ¤Òê6m†)–4¼ Ö÷V®9 k­Jˆ$#…Õ Fьê…X†³Ù¥úCŽ”pÐ[ç¤èģ)C¥ŒS¨;rFP#õIÊm„K£G<ƒÃh/ÜÈUÚ-,C€ÓO² kOKžYYµ;èMH-¾t–þ%û^NªŽÎ¾œB€‹Ø7" +´ãÙO²ají×X†_84ÍV(N“à-{D)´éF¡0«$½!àoJþÃdv/_øõ(ÿǀñÚUØH8ÞB§c×1•·ÅÉf¦b5u­Á&ë*®Ò½—nÛ2s ™«G4 0:¼\=Y2è߯ ”$bi”8亵Mß$ҙ:utŠNÎ)êÓEh²¶Dhªd«j£21|²*Téç¯VûË°îÀÀTª5È®M7-´^¢èSÌø¢84Te›µhRÒ¨jé[ìUîGþ»U±²Ÿ1•ààK{“Nh6vÕgÖ¨Ñ+Î…G?Ûõì` lݔ$Rq-ß.Þ¦2ÞóSòeÍ8pSՖïk!ÁXÖþCÍ\”z0µ0 nlhÉòjÂ<~Iª©®‹ý,K¿r²L„)ÀIM­ËàØ9M â_ˆùõc+"vҜݤôL©í¹$>ɺ¼’zÑü¾j>>¢îXå9,ZL-j‰«Ibk¤×ȉ8÷˚?vÎtÀ”òÌëx”žš‡©ÒP¾IO}„_ay@Äæ:à ãñì|VeÃ6Ö覫‡ubd/eÙ3<Ö­¬zÍtžÕeÌaÝÁ'˜cØLaM +Šlz&,f^ª_! ì?ãlâÛóŸÛ2x2¦X’yÎèåńÜ3Dó㌼)Ø\?ÈyÌež ~°ã4äÍOª+9$æ É +™á´øEˆV¿D<ŠO0ä‰Vbj&¦¾mLBÎ2Z܈öb9êðU¿È;nµ©â6L0 ƒ+–êoˇCrÑE.~µ>TüSؓÔ7X¬³‰®?MMå!ö½†Ô¼u–Oèôt›ñ’÷P Cbt;´·ðièñÈ•Þ°Ìãaøº@gWÙÛ#Û@ë¼ô4cœ9.Dõ¦æo‘ z2>M÷5¶þi—~Òu0¬ ¶qºsæwî®´QÃ9çǸLt–ý삟‘Mz)>©ûßkɝ£ûËI÷;º”îioï"’²›U)úÆ]$Yԏ†L >á$Ÿöíò$Tîÿ¢¢:gUo$÷öUK÷¨Ú,ÕCÙ`sCMAJMĚ×KŸ»C(ÕÁg]‘õ¸Ù®9ÔsÿUìGß0?“ˆ‡­Lóž5­ÅÌÙQM%Ìì”0O³léç5&Üéè`ÚƑ1,ÇÕxä'¾šä{ˆÄk+èmYÉ}“ÕßË-Jîs#\ÿ¥d‡“ó:Øi/àNûKõþÏäÂ\8©H½£›ŽstQ#Åá-­ND¥)….s*ŠZÆØõyžmÏnÏf›³Í\†1lØÅÂä’{¥Ž(Eé=õVGW¥Û9êsÞ:ïç“?àûów¶½’ÇŸœQûZºsCÈÕ6ªôAò1óöìƃ‡ë6KÌ@8ëõOUYå^ŠÊ`‰ßì7Ÿ„¶¯Šóºù³j6ù@£9?,yŽ‰¢Ðt4&Ë}"ÖT×ç- +ü\Y&kñâëVÉî»x—ë…£3ª¢9µô1ÙµqQ±=ébÃeMq\—Áª¨¯Žêî©`/nņ|ƒËþ2†ð͌Jkz¦DºmÍ«ŒIR4ü\~5NlðÔօ›ôÇKɁZ]TÉC¯3ål•Ì…©…Dî3jSS©)’tÍêWw$IXß[›wºV Ÿ +WT™«úUòŠw^PÙeU±‹®ô‚hÝWEµ^ؓ~WÓcÊhŽÿ¾s ±s£õI›g‘ù¨ƒ¶`Šÿw…¶gäs (€5£ªè×ßmrâÑÎÀæ] †¡ ÏB`7JfåAÞÖ°ÃaAÝ3Ɠ¥ïG³Îáê»þ?{¼O[ ü?ÌxËjø/´ÄæÄZ„*7¿e…xÍ÷XÎzà Ά¥î})¸ƒCÎûð?`ŸœKã‡cŒM£ÈúŒÕŒ¢´&)¢ð°š¡YÞ5õŒJ]q':]$ƒØžÖ]Yv xÖ(¾ƒŽµÐı¨ò†H1Æãe½U¬˜¥¬>Ì_0£b»?*ñ¸¨Žä¿bÏÚ÷ç¤،²•èæôÜD”±Þ;W´xm]|Næ¬7UÏù13* ;¦è.´=¹ð>ÖÒÂSÏÜj)¡CMŠü>”½.¤ÀeñI£¿ÜÛ1²²™/QßvÝНÄýÜ6T¾kk+Æœn\\‚F£F‹í¨V#§ˆ¹Xdˆ–£eº&~ûWEùÜ7á"Úbjª°Íúu‚•^I@ïj@ébQ× W´»kåò8ÇöŠwüÛ_ÕD …Ÿ^Áz‹¸ÙÚ x’Z‹KA Å_`‚T}Ú] +xÆ}ÃЁ‚M0Sõ,r„™ùV+ K¿×O&ÿƈ´`¨;­E{irf0F™]©— w86fŠ ÿÏðfm_8ÌèƒÍc3„™ß÷V“<)¦r1¿¯pˆêÀÇ +h‰Ès|pј!QÁéP'ïՂúÞʛËÏó¢ºÇ2òrõÓ¤eÒ×j4Y“ r©î’À, ÊrÞ?4‹! Uø÷qð]fÀ(œ¦*&umM+ª;”1® +-°•cœ8òC¹êÌj¢L=L«Î1þTDJ—º»7ÅÆë>©Òê²Î)BHå*£cúHY}~ñxI,{é©Æ7‚W…îûjWÖÞ§…ʇçãh¿g»_óÀ·YovÜMKiÖN>ü”˜ QÕÖRÒÒòǧ}È¥Aû–Qžj^¢©G ¿s› yJG"ñ?txt,LýÕ>«Öp°±_‘˜>ÞPo$¦Õ^<…%}¨ÊØK¦D”ÔS4¥ +·*S’<ܖÒyñd;’šÔéIJ»Ó~J®Mn>ÉÌȸcI6ðu¯¢†É–Ú˜€å䩊i77Ê_’5WŽ2' 9­øtÆ^}/ü˜8%wdáÉó0kšò)¹…ͦñ¢F9ÀôÆœk—ëÞihóà3úSh›ËPB“UÕLz¦ìs€±’'0®$Yá/L3Áª‚—oø“ól¼„ƒ|‘Éf ôɪ\AW#ësiŒÞSè-ãO^ÛIÓÌ+Ú3åÑ6¸Àxasíì îø…@MÜä +¤A h­ämŽ4™5VÑ-âî' ѵÈ1¦¿ð•S+ ž» ~* £%~kÓ¾ï˝×ʉl Ø*¿ +à lكÄ=ô3¹þ»_2~”–­OgP³¥s +˜C¢‚þÕÔcº¾ÆdÚú²[ÚaÚے{<Ð¥ùƒjÔA {! ߲ۓ¬Èñ;O'Èá9+wEHŸEÞÀµž¡&†J¯ÒVé?fáiÓº j0¢5瀶bhW”ZxÝo=”¥Æº 0–ˆÂz‰äöhK5å’m¢ä•oçÑv (Y€Ouô±óà¿t¹;‡ÁËe=¾ðRÉ*ÍïyMVõn²,¡$v:•ÄQçÚ³EãÔ.›yŒVlò;æsvn·Ö,ôõWi.[¡÷ÂÉ¢@•¦­„¤34SüD_!“ÔMú›ßF‰>J柣ND ü»@$ÊYÀ~³-³’µïCÎMu (+lBpБÌÈ^úâ#$œ~÷2è /@Ì£ë6 3nðhÛ +ž;÷ª¡û‘Ûª.âþ—«¬æÞæŠ3F¸¿q3ã™Ü\َvÞZnþZ"/ËvNF”ÜüÖNŽJ2V{œ#ΚV¹sØâÏÈe_쑮àTˆöa“8C¢°!ΗÌ÷>FîÎL¡ó\ÞþM{û—ü5®ìeH~7;FÎã Ù ²AäúÁ³»¤—B?³ÿÈV¬ùÂYš=Û©‹»Q i9ÌJ.sÓ¿c%–è•FVb‘dÕ¥iL–º`Ûa)kD麛=W®Á³Èœ¸œ‚ãÍ \nÀèçÃeÕ>ŠN¸X7Ƒ†2Iª¾Yf-Òto7±¶«/®~ÁòUýè„as[š†`W›®*v3_”`~©û‡æ:kêÌâÑjêR(" E +*Š€‚ +è´¢e)DDIØÙss³Ü,÷f_n6Â"¸€Š:hm±h+Ô]Aqñ•ÑQq¡âSaž¤Àç9ï{~8ç|³~bÌh6âG«îíZĠםN\Èh´ü+„Ë(E3§0ï~Ýùô–ÞÀ†kô–T‘MGºÎ²¼èüÎ1ü:zk›a'LáøG‚±¨‘2‡>ˆºýÅ,gt ÉÎîX&¥@Ù?e%œ +ýœ¸ˆ=@€ÆIhÆs¨ˆ²á)H…ÞU§OeX^mÈÁ7R7Ê~Ë,ñûê,é ñ\jí´±»¿J„ÔŒfÌͬíÝð¥ð8!*¥]˜JR:æ‚öWâRÖ]ÓMˆÉš” ‹PöœZ«ð;¨¸JÃNÞ.8ɦ®ÏÙÆÀ,Á[¶r*ýΑ¶]MˆòŒM"waX)Lbjd‘`ç>:ÿ?ü¾íù|:?uƒ>^ÒÏGÁ©û$˜ÖfaŸâ.Š +Ê¥_àƒS‹ø%²EDð–´8½ ¤J¶Æ=£Ä•K¢Àâ©{ƒ·À´Ü6r zþGÄãGêò«‰  ‰Þ óÆU‘ií<‘‚—ÄK’gçå"÷¦¶^ €qŒ +ü£ôùI6±°¬±vP¦¶‘éWÜy^,š†u¯c/5ÚÓ@¹:ǹ+[ùŠN¬þ+ðlÛiÁ{ÞŽPò#^¨Æy†úìïvë,ñ±Üæãþï¹-ÚÍNÕü˜ѳH×⺣<Ö¡gäx ­ÝVÈ</·Ýænb¬äæ6Ðýë¸ó´³œªÎ¡ ¤+nhB˾â¾PÑËoT(§W–æ#ò#ĉTwÄZU} ñ w-„ävòÄTç½½Öç-9Oá­ºHIãz)¿®Ž®ø ï zí9äR'·dÁI5ÃÑa²ÎZ©ïGS˟êag‰ÕW=Ÿ™.÷P1ٜ y?³¥ƒä2‡òÂóX¾)rÙ4VaGº¥òåÈX¬ò©æËBe`9üQ1‡ß͚@8ü5åŸÃàÉݤ·ÀÜäß$×ÁÏW?‘Dò}¿”zò†ÿ2‡*È +ƒŒÂÌ÷pt¬ +ü°;Br\ܕì'> ¬Þ-övø÷C¹NeʔÛô²ÈL-ʌ•qÔçK×H½”¯r Ä7ÉIÐ d<òŽ¤ù¤BðgNelB^փRγF2èÒAÓqCR€&ätŠƒô³7߄ü´{" D9š·Þÿu)—òCð­’w²¡æ1úˆt³}?"þ¥¾'Ç[Ý7oÉÌ©«~ž1…{Ÿ>Rìu*ô ‚íʖdÌCãôlÉÈÁuøtqf‹2[ÍlÒ~{S4Ã>±J$Œ«÷÷.nQ¸nlåPÝ#üxÛò])By`r+ÙwÞð²âçLH?‡˜ºñ¹VD:º|«æiU·G¹þ~Õªÿ+öå&+RµÜbö gPâÑ>Êú}¡úÆêàŒWÚÔ¹÷k–Qǖ]WSkqÚwÔ×ÎZ +ÔDæQ§žd¶¡‚‘V„Óídè24¥Œ±ÄKªGÌMËv«ü˜U35«˜KJ~Ù4&j´’w·J àÑ÷*µóy¡;˜êXà߉˔ÝÀOá÷£@›û5•hw)Œñ˜´•ÛoØ-9E:¦ó_ÀÓ̂îo¿¥òƒæ&˜6#¼Vþ£(ѽSé-te$ íפp}ô4Õ%Ò4m¼rn¶z‰üôöhe4‚KX*¯‡KÑð÷î2ù9‰Ê©à~Ô×ü'Ǥ»l|O5ÍB† +§;•^§ jÆ㛑Qõ`ØexHý³;±JË\*Ë`lú¬Ë´KÄh¦×k +&”ƒ–ñtùˆéF|(²Ý8VÇ¡‹Ü·ÁR×€§:ϳû´oÛG*UjSKk¨ÌnR¥“ï±gl¸ ÷Ûޅ-‘6¹ûÉ&¥±Nŗ´ÍÇÇÖÄ7Oâ4”ÑrGm´òO[du_T’×vYÖ{‚ ̏IyØ\ëaR Ky¶¼&•Pï7ݪJ)éløƒ¼"—Wÿ5Å{K¤å åÓÚS_õ¥àå¦j0WSW;¨wèixêÆF1Í^lÓО伴^£'¤1ï¢ÛÖbŒ%ôOAÏÐƬÕXÂhq)Ló7ÀŽj¥}=€9PXŸÎ=‘“n¹`ŠŸÉ—KX#Cù…A *7{È ãjœŠWÜ´TœByÕÑö¯‹ufכéÂñd=úA˜¿f±Á]蔧ÿFè…íÕ=à_u*`¨q›²‚·¥+î_i݋\Ê^`BaEò|ÔS&Ž¹¨Ÿ%Z® ‘a´8á—ª°+Qˆüg½Qÿ[ñIK«Î-Ëj¼£IKr2T¯cjuñª=A ´ʧØQÍ"7—ò²{Ù®“ûêם*æX|,YƦ¸¤zêˆñÑÊѽý¢Ž‹}ªÆˆf:÷jCo[>™]×ãx^¼ÒìhŠÚõílhNrÓϳEDkþªcÕCúÙØǪ ת9Öýc —ðîH›t<)…Ó}ÛzËÝ!ÇhE~DBÓ³Ê2ßS͆Êòi{;éo•×u…˜IøõpÉ??砃4™6Ùº«ê^"©¹€Ü±¾1•Rêû¸±…’<í“-–êš65s²jžpCµ‹óÝÚSjqi6dzھİÆ紈† 4ï‹†1Ú.·ë$Ã5E©Gü9ßãÇ:Øï=µ­oØ÷Òbšµì¾„ v#»Å[éÿx¬ï¯¦ÀAFë+T㳌€¢Œ³€Ô(C@RQFöº7¹7ã2€°I$Á^a$ÌEqƒ >µ.ôAEõµbŠëõiÿ€ï÷O0‚ž®Œœ]Т™K5ΫPیG„´æ˜ ãÖ ÃéÒðžZªdÖ¨J’ºË*¼$dôýò·’ó ^ª}E¾*Ö¤Á>?‡°©‰ÄëçƄŸ¨áæÄø¯­$d«ÝO”£³ è_t¦l‰%¦Ô$^7¯Š[“KüñSú‹ECq´zŒ"$]Ý*óûµB]øÊ}›ÎWö zT[Rk­"‰ƒç®å®n¾]¿EãçU—Yv¯ÚFUãW\þBÙí6£-RBè^M¿ì´e¶2Bœ4¯èÇ/wÕͺÍhú4EèõkÙ5˖’<1òU‘¼Î[¦táþÝD°Å>îQ!˜.kR¿Ï涧ä7˜uÆJµ­cû>òcªÂ +lûªˆ/ûüi^¸á3;i÷°š‚éڐÝ0ƒæsÜèÁôĀ­˜ZÛnÃSÆ +¥»ÀqW7ÏN³“p:ó([ˆ½Ý5Ì6‡8·½„Vùi•AFޜì~h¹9£PÚldüjì2îdO +²+íÄñŸ¿6Âü1Ÿ--üß1Eú×üwvø¦ þ=JCH«šW¼3ž’4܏&ŒxÝñ½8,¸Ëà&ºëãÐÔ#RcŠ3Dåvzý6‘…RS„¨yuè´_N/nm÷كØÐvTÖÃàòÖ¥Y˼?êåRF×°KzÁnª¡9ó¯ã•ÉþQ®æ4ùgœC×^Ù5l`ºP\ܲº€âýG£&ÿ¦¡Þ«`÷² õ±9ÏP¨ÒñÔҞٲXÜÊÎrÕ6Ô«Œ +V4,ùÖ{²a Ø„ÑÖý\tcY`]lÎÇ¿Ô¾¿a®§°r‡é´¯Ø=bèÖ!ÁÊ&ÖÉûYÃb Ó^[\ºaYt­$w +¥êø[ÝÄR¨)¡§§iÛìº[ô{$™ì7f"¥˜o ŒÓò“¢X‡‚p +»Àz¶BzðÎÒŽ'hºO|Ō4ǐ§|-•já +:ž•É}Ì´a«%Tvœƒ5ÛÚY9QK¦ üd0 ?ˆ$˜äćH|õ#òuäD3µ päôh¤éÔrÆdì@,@XmíÝVKY¯É@oò„Ûu‰°([µš´8#!OM~.…7SoJn%< çI¶îdZ‹ó=ž1ËD3‹!P#4÷£“ö(|:]SYd…„_škG’äõ²ïRh¹+OtÐB²«÷%Ð/eý䱖á&]·hऽr5¥slÿor šQ¾¥êÎ"F”,bՓ÷*2~®£:ʼ÷Šiõ®[ˆ´©¼«‹ÌtéÂ˦“ŸíÛ~M +ªUé6§DUÎeõ"udPO:ª¶Ç]£x+¿ì ¶GºÿB½®˜]´€q:óÊ¥—'ý:¶-ML3\ÑF$ç7…Kà3êCÄô*sü2µÜzÏFÊsõ'÷Ôû¥ñ  ‡Ì¼K¤„ÞsŸ§æÌӚŽ¤wER§” Ã!`%aTÆãH—êvçR¶W¸õSPÚƅTÆòÌ}FVArB«[ŒïSS &ñ™}pù`Ç ¦~ˆãºÓ_íŽàÙ1{Ý,yãàªo„‚ àÜÀŸþ{ó30…é[ÇbŒ K™¶È:wœ3Ùã¡MnÞÁµ†e6òsz/0OGò°" +Ü3NÝÃ|›ó/Ð'ëèO¬-R_—1Vh&׺ N’Pz8de™ºî 勊ZTH;X‚†ÐåŠQÊ6Æ}™ñ˜+°¢ 'h´Ï_î|ȋ¶ÆCc’“˜¤©u¨ýHù¶j£BA,·NÛOS«§È{é3ª÷Ñ L’è `]Ñç³Ì1ÆÚ> Aº¯Ç ªÚrxÓ´ü*E^ÿ.¢×ؐ`ú†Š“Q5 šv{`=W6뼟ñ\9aõ®’ÄvGOÞXc& võÈ1äÏÆw‚~êÖæâ0Wÿ:ʎ~µˆfª–: 0¾/˵‚§%þm äKRKåAÁüšÂï‘ÄcˆR %㠟P“#CS£éߥÞfÚmD¥5ÎoEx–…1‚7B«¬ðæ»0ìóÇù<&ÏæßôøYdø8"1²üwÜ¡5˜Á TaaJ3p˜†5œÛ¹î7îA>®‰+ç…ñœy¨”Iž–Má¯ã½ôcðuüð Zd?ÒBê†k1ÃËÄx-—Šr·sVˆ†9s¥H6p]DÎGâ¸g…O| y»„5ŽS¼$a´E˜`$íLs +[•¤YmÎ Ê~uå8Áíp`6*I ߕÎ`S8‚Ì»8s™nŽû9O3nX¬OE /7f•^ê…lËbNÖ[®PBµF¦O¬‚.Ü9¬€ó·ïZç¾_.Í5¡>¥F ›õ S¹µÌ‰µR×'}ΪѬ`_dÿXš|ê{´dâÐHXÔ¾3šQlZe7Pã©R¡ªq¸Ø´³O5¬ºOkZþÏrx5u`aǂ:‚£*`ØT–)›¨,¬ +DPQÊ®²²°dߓ——¼ìûJÈŠ ƒ£Rk=H+ +*­#u)£èèh§Õ) …Á)B§6ü¿sï9߹瞏øïHªZGòµzçG’†ÍTø"9ªÕ3hŠD×ͺ ³Ïs¡îr|ÆÅbã4þÅy ¤$”õTK ºá•"ù$×IÚÖ~Î$v(ˆBìÖ#].²ïqiÁ?­C°¹N ù–ú¯ñ~úÞ±Ë|ìíÜ·àLcOÀnÎö¯T~ø³ÜýäþvxjºÀ̦5<.ïÇf\K<ÏÞ2pô:CpËõá•Sây,66‘ê>|zŸC +Œ“¨ëE +T)ÔÈf/À•:X1È}J+Üç>¢½Œ_Éý…~–˜éQ;Ù^Çõㆪvs&¸Û¸>œ.®k“7‡ÆyZþ˜SÃù:‡Ë©ãœ£rØݖۜçœåÆaKaŸ³”!l–è.g5û ð7ÜKv¤0 ì!;ڗ­fï´îîe§ þ¼%‰]"XëTÖ –J3©aÕªõlwV²j=v†å§ ”αÖÉÞe=bùI/ìög…H&ü†™ ’:§²°˜g,(y 27°>a™b°aÌ8ýËÒ8fŒöVV®qßÕɌT‡ùµ0†ãNÕöŠ±Ðù‹ìãɉB¦‚ÑåÀ`( š_"f´˜o!• Ðt}WgüŸ_0}Hµ¸¬X Î9»,‰QÕÓÈxÏØÚ=Ž~JÙ¹§x‰>Ö€ô£ÿÓ±eç9úM«Ý÷2mFõ¥Séî)×Vk ¹µö-eZF«FÙ¥btøg0Éì¦O?‘DàžÇ%7eyÈښ6þ‘WªÎS¥C‘ÒyÜeäUS}Ýñló`a‰8i ˆèg"1лJÂ"ô|P¬KڝÒc¤,¿$¼Žì+Î&ÕÞÕPš°„vꖴGBoj_t4I òvq¨f熚(ñeÖßCÔË!οbÇ×¼†^°SŸ†bØYi1‚Óì¨;2ûˆWä`/7u¬h?4 +®†Šï!Œàzõœ@#(˜ãóT ¿œ¿6ªŒ ^ó¢ð!§R S”¼#Ð>E/áSÁq9¥z_ /G%ӈ0Câ9Æ[Û¼‚@”(Ù©”ÝP•é À, }ð¾XŸT…Ok‘‡p¼µQÈ«U¥G6 ª€ ¯x2¿e,¸Ú>¬áÛ -?Ï­°ÊQÞ¬Yzð/ÑTº·è5ÌFLÉä†^`ƒtÞ©‚Ì3ó\#¿¶»¨¥¬ê̬Dðª:¶,ŒvÓÞÏw[mDWÑ¿¡…›)½ãTB¦ÉZ½‰Þ`0Ֆ`3tÿBQ˟kkðûs4ë1yÉ ê`ì\è¸Þ¸ÂcV#þ‘z`XÄHhwõA¸0­Ú†FTy¦úqӵܫ*F˪¤%€¥*Éøµ/>Ó9 +ÖgS'µ"b'zL=Nª)c¨‘s×*æÈ÷“bä¿Rˆ¡ëä÷)W<ü#–S ²µç™›)Kê÷Ìý £ª +&¡ô”âLã¾\¹Œ9WËtÌW!Y1󏲫¬å«ä7i*ø%”ÕþêúwJ_°½ä¦Ü îÌ閥ñnÁWJñ„!pÉåþ³ä-0éT`¿:K6BÆ+»¥SõÅzÉl‰¯L,~“³J#ZL´HBEeÛ߈E÷q1 +Ú¸¬ÂTD}é­bB;º*OÑTCÒnՍlŒ$OYŸ¸Qœ®0m·‰z7ÝoŠ„9NÅ» |hý–DV¤[V¢’eÆÖ©b7ɍ£Y¯ÅZÖ¥H¦Çlþ¤Ûä~Iè)Ü»¬J•5§ø¤ÍòoO–Õݑù´©%(ûŽ,¾hÞZ°GøÊÒ¼mR˜d´¹ë!¤ð/NEWutV57z;ÂjôÇÿj¬s·ý»^’^lDçǾ0-a®û­_a®ÏLí؁ŠówÚûö44簍b^³ppi‡ú̍úô&nÓXì ã¾æûþuÆ»-«Ý‚ ž-cÎY4Œ½_Œ´¦¶³šg ?ÚjºGìIãfHõ±ú ¤%ÿÃJ҂[ö%Ï©¨C6OzvWÛzåÑoZ©tËA¦±˜þ$õ?z€°ã;ÝÆؼÅØéFT2÷/+˜å0…™ñ@ßÑ@S<@>0bð¢SëuqÜw;j4SÜ'°/4sÜïÝÊE®Õ©(P[¿øú×V‚^¡5ƊH’õk„g/´Û„«wø©û  0¥Ú*ÜìÖ­ ƒaËjƒyBýÍ5ÙTC› ÅJ(¿_©ÈFà4©òü˜!ÕmÙ, RÕÊNº Ë?SœŠü¹9³õ :×´Ê–Oèÿf¸“OÐVê×"յڇ1ÕÊí,V)Sâö@æ._ +Óú°#ý‘Qî`”Kõá¶ò|ͨ%cï˜j¨Í/&\™Û: [­øFƒtû^Z"ªqÕÙ¤Jm•ë™ŠjMarחµ`VCg +ªžw" ~><¡Ã óŠ8Éièú½µ}×XåT8°Ç³QÙ†VY<…Ä<ÏJ=áÀEÀۏ7G8v6Á¼Z:¢%¿·¶hBòò94^™Ô¥m!1¼ˆOD>íp%¬HüÙÞGè‡ÙðÄ/Ã›`rqÑ;¨±N…mï~MýÓñs§\©‡/žˆ¢Zh:•(¶í¦¥…MXžÐ°^FÛ.꜋‹.–Y½¬þÏs}5™`aŽ Òö(ƒ(X0ˆTˆ+JS°‚ Š4©&¡¤~ù’|iB!! !)$ô)Ê°Ž‹ ºØWFÆY]EÁ±ë¸Ž3x,Àó˽ç}ï¹›å|d´ðcâ +õ“|ï°i-‚¿0ÐWs…÷ +Q_Gå½pRjŠyÓ0˜òÑ׿’t¶©¤øj²ÑT̎óԍŠî‡‰D1·ëڅ”ڍ›NÊ:ka? ¦øç7•eê“棆k–Ø_µ%]a;ëזו¯F«=Ë9™Ô-b= &¿óMm0-­vDÅ'^Çj´Û+µ¡/5(erÀ^õ+E·çL F1ä$¨1KŠæ•×WE|fÔ×O£õFMK¬º¡¦ömèí:ƒ:1`»Ú¥fÂóƒŠXýЩMÕ*i€9ÈÊ +l?+Lw?-NxÕÃ͈Ôwɳ\C0–óÙ瑃f ÎsÒŠë·M;iđ`°Ê$èöµµO»“0zúÁ*RÙ¹œB9é@Â"´k¬5ÏÚíÛçvÀü~•.lð³B?îugØ]Ãedº¢†…è8J³AÞjý­Ù͹umÌ.­ÕD›O–ü^^ÁÕv:‹y;Á³skeÄæ+,LȶvÖ²­ÅíàæÒ¼½Ø®¥™Ã‚ÁdÃü_¾ë5÷ZüŒ¥ƒ;q®#k>ÓêÇÕ ¥MU\ƒÛJ“”«¶{l*͟¿’Ò‘¯3Doéü¹èyüèÉÂ"UDcû†¢ÍÁuÍÏ#HŠ)BPäæitèì½/ vÀ`Ó_êSʝã{Ìeù5mpñPpyÓ=±-2Ýè[Úëæm¸+v·Ï6*.WÛ¿©ÉSǔáñ]ã +^DMk„œ,2ý.#£÷ɲÝ\õ³Ò!{®^âƒI4ßԈåµ.~°Ã§ælDc‹BU\bò«"c äj¤Ûvý‚ÊÃöJGÉ|ÏH`_ÕÈ2ÜrÔÜÉ넧ëæH»³Ñ¥ä ¸§tøŽHH®†BaGŸ :‚ú‹ýBÖfšó°{–'ñª9 +[ˆj¥øaЧøñe +&hè´°z6FdÄy?¢>g¦Û‘x&él$¦ŠÙÜ^œåÎ:¬¶Áæ³^Šèøn¶‰úŽx-'-µ¸’û]èO 5×⽜äØÛÎ@Sä UÞڏy]°Tu à_,zŠáWPT„|BJ,ɕ}`8Çß´y?pŸ7gË¢uóŠÏ\JO(_ØâŽvOUue4•öÙ+Q±¸Œbi²?A.jÞÿ´Cxy“˜´R¸ÊÖJì駥þPÕÝt㸲rðƒTôúfd½d$ÖºâFR>Pâ¶aºL·ñ'ˆv÷¥¥äê2M—Òë*‰¨×µ¾TÕ]`WÖÝ*ßcDÜ*åûhøA¹e#ï"ûɆKO9öJ“ùíKL‹Ò2š¹JÍñçø( KgK3jԉf¬Z¶÷nLåå5‹ýo•‡M(½_ø¸×>éFO‡‘—ÚÓ¹Gi}<´ÃÄ@w¶¬#Ndº­áÙhoo4öYÜ Ì¾¨FÙ¸2¬…—ºÁYÔAƒšz$ÃW±„Öœ5ÃÃCoplâiÆÂ\ ³ˆÞ3Ä2‚l„;…òaá¶<;šSç?B»>‰zü“pr§j–Ðs m»ß1tôZÏcÌ¥Œë{¹sì”/¡‡þJ{™Äcü*Í#»3ûóހf–Ï¡ne£ãæhúœ-»>Bc9SJ ÿå"¬Õ¹O8á'•8ހ `yHÉϤu¼-œ*`”· x[c')OyÁ»ÖÐ\x!ë¯Qïñ­S9q*;ÿ$;Éd'=–NYÝÌ ,|ܶ3Û4§¾”ù±q¦T˜=©ka%â´õ™h±s¤€ä¬ººÖU¯X7Fl«”[õå oµš1apuxf¼9µäQ¶Gk4³;e +˸€7荇ß5ôîxB:¤y¿î¡¬Zd¥Í«,¼`2²—?_Ía[0Å~9iY Fs®3öÿ˜g¹× ¸Ã‹9u¤¾ ò<,yxí87¼þ© ´1‡‘‹¯¨JaÆ¥¢,O€@/g½½ÐOÙ㔛Ñ94 ð|.]»1÷6ýè'Å^Ô¹@1'¬èp:XtŸ±„Á€ðŒwL,j–ùVÜ÷á¬Qv@àwl{ݞ­Ì±ù¤ò\õ?R^ç½UVÐ\¸GIœ+¡­¤¯åž9ÞÏðäÎD…0×æ»ø3oæ¬yÉdç[R<ƒ""ˆ’" +.´¥2…}”´"!<ý4t¢H~(®-rñç2¢æ5DºH@ùÜlÚÀ"K”»““îæ¿£,“¼/S}ÊëÓÎÒÂÊ"+ ïÅ~w ¥™«£—F}V dRz™,¸¨:Èw&?­ÚC~Fq¨ôJ}JÝ¢ð‹˜¢ÊJý’i¤´ÕrjzEÒgUÿ#±Úp]ZFšÖã%‘Õ+Èþ [íPjewÄVjlõÊíW©7ªà«wRüœ/*žð¼C%µ%íj…òG€xÓ @EFH)&0_ýËõáՕÇ|Xuˆ +D¥¸àRNXAÐ\0JSŠ¤£H‡é30ý½7å͛7½3 C•Wc+–ÅU#Ær# aQOL4E³Ñ™?às~¿{ïïÞs¿I§èªÖyô?›y>ßҒLŽÔÖ¸Kd-Þ£J1Êvñ*fH ¢6§àh¸æÞöñz²+~BÜOó:IÝøQqöZ³¡UՍÊP±[àU’åD#ÔBMË Ó>$Î ãz|”ð?Ìë^‘¢Ìó• º!J0ÌèW8µN¼  ¼WÃzX›òfÁÏØщ@'hƒá<ð¼ +%sdŸR۔eï[þ$z,¨åZù2ÁH5ŸÿˆÊ[&Ht LÁÑ ‹UàOà ì·¯Ë<Äu–ºÉŽrEðᾀ{i¼,8+ןwM2ßÀO–œ\ŸÏ7I8Ïùi’l»2Ýewkv"9kÔr6±ªŒU\¬RšÍ*¤q¹oäGCxxy¨‡„;€:j™œY°E)a»Ô²Î°!Xidÿj¸” q(ú ¸8ÎSí“Ð=œ÷Úl(ŽPíø9Iueé&¾åk)«­‰W1Éþ¬Ñ=k˜Z¦b;8˜zBÈCŽ³ùƒû4›«ڕa¾vþÀ?àsuú¯UuPݝæŠ\Vf»>+›5Ð2ÁŽj&…PØ6»šuR»É®Ô! +aÑ+árù‘Òkô!¹o©4 í«É`¡ÌܗëP)fíô%ù¬VñœôQñ‡T™èFÂ(ZÖ]sŠö‹,”ÔTR‡|O)O?‡¨hŸoÑ# ]¿6yÄл£)ôéOçU ,FœéÙ ¯´›ÑE})gŽsá©ÚÙ´GðyÖҘp/kw~˖»¶I'Y¿Ù;TdÀÜg‚YÉUž•Ò'áñƒ‹I8ÿ@Fâ*ð‹ ”8 $¸I¸à+A2((²+yª8O¬æϋW‰»È—EÄ {Õ¢ýbÚWÕ"@œ}@‰C׌Štâe®Y¢¢gv…Öˆœ•üHáÅùoÂfE`áea±±gbN›_¥ÁÇÌ4Ê!/¼e%¥³ÁÐO;m¯ÅÈht§ÄWv6¨º·ú›´[©ÛÌiô¹˜¦åÌÅÁyF˜yÃËÓ4ʔaêt V„]ÑÍ auãƒõ ¬#ùëÌÎ쪭QÏYm3rMè/q{Ž~äÁtjÈüD»¢ ×7†Š•fàiÓƒ¾É· ‹Á„èºÀê ¶. =[ôn`4æŠêÈqSháæBéžrÐx_º5wԐ Ï%ÇènÀQˆ…ó‚ðš~x“'G[ ×`+qb«]Q›2Ô¸²iÃ=UGnŽ~»òç¤ڋJÏ(¬†£à¬ýAݪÈôd«Ç È‰E7ªÍKÊz +MÿÊ]¡ã’ˆš!}ïæ j–nh-CÕ¦_èé­º¦Ùç䃊ûíŠò›a¦Ù­¬DÙfrÎjï6–$-Ó4ôn®UõZ×F)¯Zpï•×ux'º@ü]U•ïÏ/ìÙ³¢Û¿Ø3íUg`iUì¡}…åÚ°ßÛUÖL¶»W©–Îuœ¯òù+ëÕSïØUå‰î[¸Ýû;u•¯ÓÌû¨„žXJP“v§åOâŀ©–{$•KFÛ,qƒQÏÕÞr¨uÏHìÝ.ûúÈ}iÞmõ”×ÛfZšh~a¢æåtŸ€ÛM—訅BÇb0*€ÛiW­ÎÌC䶧µ‚¯jZ®×mÙÆn¬›[nKfi c¬+.º&oV.£ô&Ê­Æ{•ÿ¤5›_°s¬9†dë¸mÿüIëA. Í*sÑ5: ‚1ù ¨Å®Ê m!â¼|f‹—¸l'Û6#NÞ +Z§Ä>øÿó\ßoMŸkÀCZ8à)* µ€bEE@¥§(2ÂÌÎ7{“IÈ" $!¬„0a…=+vU©ZŁ`-x´E½ ŠJUǺ +êðùå~®ë~ï7¹TÕSîs¦‚V6·÷¸ÉÏØØiŒ1=2J眆Jhê@ UÍ•æu¤;·¶7!³0 +ß½Ù\Ó醮õý¢ý¬—«±ƒ%-;Øþ=.ÒÜeÏ/©TÖ7DŒ$v°{·.Ê«“‚–µÂ|ÃZÑ®³mcDÖ²+-C¤Åu_Ïï{¯>ë1H±1]ÿ"—D^n×R¾ ÞÙº“:êëÖÜE3ƒ[²h9¶»¬ÏèÂÅ ‰Ù7–TJOW+3 v«œLimc @ï6'³é[Öcì`Ǧ8v§­ª!“ó÷b‘RÝ{•Ð1Ï_Óµåòu‘¶Íoù³PµE°2Øð\@;4"›mOÕÙ §Óÿüm{·Ä ߺE1Ñd‘ÄA‘¡’}C=W²¼®¾B¶}[3']\PJäG5ØV¯ò‡mnY¡G XyÊahdÃ'J„[U~ v¯óWæۅWoÌ]¼Wn÷G¥n½R°¶²9H7ÑѨÔ¡Au Ú1¢v£ö‚ëÛZmˆ]lU§rñÏTØV¨A +sjÊ6lŠhm,M†Ôy•4Aˆ–À’*0¤æ¯ÂÛv”J–²RÈ?¨ï ˜Ä´>ëîÄ2C!*Ë#±q0êMJ!:ŏÖCö‰ÜÂÀRÇ|ÿdüF¿a?Àµ2Î݂ÅcÙh3¡«dBš‘z¨ŸSIÎt?¸%‚Lý›mïëF[ÁAÚãxÁY‘Gâҏ0mê;GY1űh%[Ÿsጒ@×9é q·_8ùG>r˜ íWó¾nêå¦Ü)jod€E“…z¤Cö.qúJviN&¶IfÅÔð8b›øgŸ + ñŸv|ïs÷‰d¡ò©%:uTÉÓÛfü‘û—è&òL®ˆ0Ñç~–pï¢èÝË.(R½ŸâU +; _)§w%$ò‹Õ/à÷ Ýt#é« +~ö#œu`u[ëwø.–¥qÜsÆ‹ååYìü_•-þ‡Ç*'̳ɩåßk/§––)2* iø9¤¼$é°7fU‘zÏfl¡“×cô9}£]´¬,툏WYCÌIëê÷kSÒ-¡§t¼y7>‘T!¢ž˜ÆÌ Àä×26ŠÔ¶‰ÓKݲáç mÄ&c‡•Ó£h’¸£Œ' Ù..+œupCë6Ì&@j“5Üt«¡™døëÌåêP–0«Ÿô–=ŽÙI™Ë‚Ä–Óú¹ä +úC¨{Þ¶$tR:(Ï­uO¹ÖR4›ÞÜâ$=ðjl¥÷¡Äuq—1?פþç9î”ùSèi|cåõqÎF!¨_z^žSÂêK}¡Ÿ`d¢%DÎT íwVŸ>Å;à¿<É'’V=(è5HÁ%jú»à¸WMÑó±…VÆ#àß9ÛY‘D2ÕÊ֓Òîp~¡žˆžá~J ÚÉ}ÎD»]ážgN¾Süs•jJmƒn-‚>,v¡g&SÔLëlê#–’ãíÆ>ŸÅÝ^Åiææ¸á8®ñÊž®°%Ùñª4'ÉùR‘’JD“Ãh¯RN0hBëA0ó”(rÛ0K+úaõæ‘þ’²MõÀYÙò|"±E¶G¸ƒŒ”E_R^ÉvÁÏÒ4²/ì¢?”ùm[˨•y¬N`ØK/5[™7«1äÁ€[G„Ø’'¼ 'æ铯RªGöËhqꭁÚ]Õø>£úiI‹±Xà +5€'”\ãGBŠ „Ä‡…ÓÉÎdƒ^u•ò¿x +•¢ë[¨^Úá%e¸‰ ¨Öªúp»«xEÀò +À œ6…%!ItãÞ¨@ò•Ò¾#% Ô §¸¾ß:¶é™*‹h$rßà7שðׁ«55‰×ˆÙæՑ'I×+6‘Ý*ЮwÈ°¢Ñ%U”#¼›zDá+JÈtàü šBùa²Uؕ 6âíøñ}ñ¹uOÎrÆç7¥ñdôÿïåP˜À›Â þCu}FEuæa7£RVÍ"KS‘ª‚‚T‘¢Ò20 E†éåNŸ{§÷^˜Älkìëƕ$vWš(¨,¢F7–b ˢÞ¿ÜOÏï¼ïyÿ÷¾÷<"_–³)“ÖÉ.kîh˜àÀ[n ‚9Wñ?gÜçڈ7¢ºyș¾*¾œôöÓ¼‚uA@ ¾OpšáIäRùŒrPý(ó$e[i<ËH›—±¦££¼Ø/€\ßt®/ýâGõinQ­Àaˆ@ûšq–Iïaî¯{èYʒ]Že–°?D˜§98ߙ¬çìéy©­dx,¥8¡?“½¨½Peí1ÚNˆWŒ¦wAíi‚N,» Bçà=Ì%P—K©ÔÄò~þ҈œGò!OʽÑßR=e’"!Í]:™:BûIê\†¢MJ1ðj Gò›K)b 'xL"W?D\GêԝCÃÈ{µæÂAÊA ?u#U Þñ•ªÆÁãèUJê´òÆÃǹ— H{ÁF[Å5h’ÚÒ[N6˜á){((ãÛ%Âø>ƒVªYâR +nñÖ#ܼ°ë(a¡«ºFìqì&mqü3%—\g?ñ%ÙӆñÙM5«Ÿ¸”ø¶X‹D3‘b$ʁW×ö Ÿ‹¡öÆ¿‹5&͔D4Ó®Kƒ°ãc²ØᏊ ˆ. +úë1Zëšo +^`ú~¿`Ç6z ëq¯©Â „ãaX‘Œø½Ç°ø)±ýӼ܄'À¹84 n"Db.ƒâÊð¹yC<K¹³ú d§Í},ð§õ{œ*h® +Ú¸»hè>¼¹ôwMv^ cö¦8ÞIÆ»õ(~óÆj?¾’¥ +eðo²®y†¨l/—‚Dl5¯€úžãŻרãpùy1œùÎܣܵü‡«´Ü^004€{ ñØÃïí.™·%CÔA2¼ù2ë¡dÿWuìõ’šœQö>‰oÂkL<ÒÍßòò‚Å5.Å¿È iñ”f¦¯fh³7S­ñ-ßÉ|¥^–³Š…T¡jX[•wCòY©*¸sG^1­Ve֗ä+À˃€˜…åó·L³²·3“ —â/2y†èà{Œ†¹ì+ò½.Å;Cçt‚äJ ¢}¢þ Ðáô-³¯>Ù«y6q<ƒÁ³Í ý–£W±·åx¬Añ_P¢Z? ‹Q ŸÞy¡ÀËÍØ1ì>yîÊKö”Ð\.ë!¾O—qÈM±î² +0Cî¤l…ËçÓ];¤S¥k)ÃÍ=RZ@Õ[É·ô5…ù‘¾JBe„ǐ$ÆÿNi"ã0 -ÃºìR4HœÅ~€9.☫|DϸahÑ·-Í)²r~"êåeùoMòæÃÈâþôÝKÝ%4 _7ý"ŠÂ‘e +QD~Ÿ0Täæ.¾Œ>"x*õO¼>é…§…ã.Ey+HVy55R”ƒ•Ws•éùÑÐEk*êPxEGBü¦ß;(J³ Xâéµ(8h©iqãmh¹‘^™ Í0`óö€}ú´”_APWµDèÒüLü£Z¬‹]Š<–·4âÁzGÖ¦`Œíoy©üZÃR|½u^ŠŸg™ôCð˜F#ÌnŸr)ÜÌVaåô5ëƪwˆ–Ššó9³­nój®yIÃÁÅtó¶Æ +xI«®1bªIyâ>}•‚›-A–ðÚ¯ÑÁæõOShãšìKF¦xµŸá6xq†qQ +Ž3“°SóU„‘›\kaÆþ椚̩ÌDi©~ ·?{‘>¾J¯3mátߐÈðZƒ„øtªÝÔ»]ªY §‘N¡ju]äɒÍÚï©QYílZZÂsˆNÑ´Ñ·À“´Wé>Sã§Ý¥0ÕBÌÂj»æëËâõ+Ö7ëºÔqì҄fU7û»ð™ªmì ¸·ºœÝ:Õ8ŠÁé¿^Ó;õ#ðeÕ¿Õ+ ‚â*,Ä_ç©ì†ôñCÊY3ì®â´õMåÿßSšªU*™¶ªLùXÆ.jQ†È–g²_I¯ÅWËJ5a"9Rª†'ÈC¥\y׳qH)ÒåVÍUü¢-Z®Ö.Î\+Ñ¤Æ/—aÕÃenš/|F¥[•¯?S âPkr¿"Ô +^”YÊ×>”•˜ÝVŽH9 &yaŠòùI‚ÖxýQÕ<èzU1\–µ¥ +Ù½þl§*7ù}ûô±hu;Twfa^Çåúcn²Îü†YS q;)oZ¹uÞG!öuTÕU¬Orþ§›lk;ÛHF´-Àx/,uþ sÔm¸í>fdêä}é+] +U×.oÊ.ýÕˆù=·Ûq»-y¶]†[õÌv¿iáR»ßçîgëÄÿk*ï`/p©êþ¶LBuéû±+çºÍAº²ßÚ@‰Â[»)‡î·&P®¸ÇYQÃ?æù˜iåm/¤‹K,¶Y*g…u€±(iÐ2¢`æ½Ì؀VË"f¨ûJSsèÓ=çRU@ë÷»7+ÄËÎ>d‰ãْ¦§¼s‘m¦Y¼áš)–wÉ=U?οþÇ3D¾´Äó‹í– qjv¡é™8<ñ…Ñ!zgØ)ºbèýì^ª[$zð™RYjTõÅËÍ)ªÔ¬1ãcå?M…2qÙ=½@éæ? ”Ü£5Ûew?SIfƒq´ØÓD7þÊú kò\ãL24A<D1` (T@@+½“7{½Ùd°I؁ 3*8ŠåœÕ:@-ím©âq´*îÊå8ràýþü><÷uÝÿÿݹã\•‡id‹ÈXmümÍÝJ´ñ¬×ÛJÇÊö’²¬"§ÏUúžjb'm_êz$bï"ì¶uOì÷ðßbûM¬q_'Ñis¤äͼ?M#mp_=~müù=ÃÄ°­§í+È¡ëŠ:¢Lùâ;48lÈþmbå3ï埒-mÛ$õY|H—™nÚú]ÇcÀkk{>3Ç×½} »Ö1Ár†@vÿÁy:{­EÍ©Ô¡.öÞ¸Î,珈®¶~žCH{kâsÆvš_l‹æ¯@š”"ølûORÉ."0ÞƧFl´]]Càְ˧²Å¾±ÞMÍfˆü‹i n´q”Ø˶QÅóð{Ö5ÊìàÇÍ6ef÷ e l¬¹[I‚€u·ÔY_(i«»&;¶Àª×t„ïo¾¢é ئ±ù¬¶5•°k–ûÿßýÞZ§ü‘/”¿ jÀÆîj‘Àpíî~Ch°Å⨿íãÜ䦿ëiRês!Gª-…¹Ÿ«”Ö ŠªØ5ÍõÅá ËÕ +Çàâ¦Åå&wó«òïa7W”ÆAÆ«X…æÏU÷î²Ûr8„Î+}E)ÆoV¦ÓƒIÌ}ÀqZlúÛhˆ<Ëgw® +àˆ¹Aæ°ø?ï=‹ê$ù6-ÁÞ¡|,)!<¥*‘ǘ*z!­•³8í߀ϸu”ùPpÕÆD|èŜeÿ=s˜m4' ²¹Ò¢÷ؽüYaPøOZ(ù„èvj?VGÜgxI=V¦–-ƒ̹¬ u¾MCJÆëÕH_é-Cª]ö‹ÔûB~‘2A\¢8°¯*÷E8PóTª•Î”¯To¡ 9/Õw„¦Äh¾©½“ž¨‰Óýˆü aƒß£šbòy\Ÿ¦'ÅF,Ռ…o%¯ÌwðU/åÕª—äßnëMê*ÁÖT Ƌ{µ5NJ¦ÅÖìÔ¢TÒ9L·¡;y _fXÖD\¤ïóuÀ¿Ö·AÅêõ:x«"¬)¯V%V/*´¥]1•ˆÎ# ŒÎÄ)ԋŠžä@ìX¹"ÌSVåӅ“—™¡4u¢.Éfˆ?ÐÜUÕ¹k%¥àNj´ù¹È;cº~?]Pۺ˄áWßÞҌ=VÕ듍1ý +E© ºÖ»qd{qÕ׉Ï;’ +²N­Âæô‘–¥„ÇYH‹d×fttcâ– Çì»â#&®vŠPótQÖÚjd¡©‹ 1ùo˜ øù­ìR)Ê½@}”Áï<7õ ç³&—ßè8³w¯àyóyÒb¢ÌH¢¦04·èô͂@>ðo` °•‰µœ~î½Mž<¨Àa9‹‹úÎ(ÉènŽ…­°c9̼4òß<o˜–/ˆÂE1”Ì÷â“áìÉ:ïã¬ɕ¥Ô7e¢þ ®.{Šó“Õ‡ˆPi WEî—Y±Ž´xùޝr¨è +¥EJ…7ˆTöÏæ¶Ù|4ëê'¥r41—œ“„ãæžâ¬ nÏsÆÌ#?ÊCśhkòº6¤/Ï»¿¬——7›n Œ áHIT¶ƒ¡‚c6èß±=ðzz!ñ?z·¸_)þºc¼)¯uÚe‰T»®}nSê3ÒØ&iq4r¾‘¬ŒE¥UÂYÑX\ùKÔ¼ì—88IXú`}7yIi¦× +¢ôSëÕiG›¼‹r3æ8Eiօú$f ú·ÚÌl+n º.¶’ð®*d}0QeÊó:FŽ¨œœSµ¯S”퍆Éô°Ö¯äSȺ–8æÔ~‹%;[ژŒl0~{‰à^ÿÞ KbV+æT †sIÓÛx)èoe¯øÏqÃÀra5),k±xUõÝ°‰Q"—ØYNîפƒ¬¡ÙܾWu8GøQ‡d!Hû9í´2”'Ë¬31cÂC\ïà!Q-ž;UüŸ9£ ¦dÚZ¦oá8CÂN’T1+¹hڟl-?63ˆ‹zÆ,å=]ŽàÛAw7!üz6·û*HŠ„H*[|Cü‘¾_@m¥˜ô¬s2Uôr]^9ñnµüÅÂÙû0¡"ž°PuTó’t$‡#:HõÍù@¡Ð±jyúb€¯~°=å™›±ö*‹kuÛÄUçŠæ¦QîŠmÓ9æ]'pu „¤—ÚÛd€ºSۖHgiÛ¬€‹6r-ð×»>`Oi#çTÙ2´¥"-÷!NSn\ z•$™É¥SÔC%“QïèÉ%;‚þ¢O»ö±z‹cçT)!ûM½.wf².PàŠo¨1ŸæU=Bœ¦l1åFá©#F0HD“\u̞rڜ*¹™uÜjQ÷ O5·òu8–E$®7:"âÉІ¥‘ï(Uu£ANägulWàYEãœ*ZÖ"cT\‰õŠk—öáTx»lŒx)™$Ÿ¢<ŒhTÂè',Ê·À —ãêóÌy³={V?$¸N€)ÃDëÉPŽVl Žàìà¿Ò]:é|ædø„̏ãà"»Èíw1*§¸=3*gB'æãòë|–'#ÐsB±FáS^PR“8†?¾ +$ mþ:ð¤è@®•Ïöl¡ÆÚ(蕉9 Ea,·_܎iàǀ/O IýÂ4ÂaÜßS8!ûÙ%UJ’õÍý«à8C¢(”&2¥J:ð;{»ÊMጫ~J¸ÂÃådméâ«rFW øjg°Yý?ªë;®©s8Ҁ€Ò´Š€Z6\Fq€D,²ÃH Y'{“ÍÉ$a@QÜÞkÕ^½÷ºÐ¶ŠÕrõªh¥Ò"jÅ}+ˆmÁjÂôßóy¾ŸsÎû¾Ÿçù½Ó™Mµƒ°D]Å_CJQw’)Áê/ʹÀ5õ®¬×´2µsµ7§v†½¡}§Þå7Ä TëVÊÓøS¯†€6~Gú„”oLF¢ø YHÀ©²ŠKmÖkÂv»õ¿~öUÝô.+ýjpâo8Ɖ$Â5û)Ô\R‹‘¹²´¾(ùàgÝ–H¾m}ìw”5jœN) ++¶¢£‰›„ÛïüŒp·vO[n™ŽHj©ÍŒ%=hº• ’Ï4‡^"‹ýl’q:iƒ“Òç%S,˜ŒPîÀûË=ªÆ‹äG°±›²Tü²åï” ‡B†ULR8LW÷˜äêÒÏ$GÅxLcLSƒÀ},ù?þEÑ;ð8Q¿±Eª$?\.”e£!&¹õ¬KKûç¥øJ¬øÛéG„‹È7°ˆ|_ ÿÒžl8!>Ë8Žè“(Y«BæIúY·`[å}ì®.úB”Áõb ѼT–²ú$¿=U8OÉŧ yˆPá¿-x¯ð$¶]ú¥0Æý_Âù¬ +ájûˆ(³“sO¼¤À‹ûH|/=wKRŸØÁ—ƒÁ•¼ç`ì p±túl>f*ºÓ¡œþuU‰þ<‰=¬T­§s®(·&zpK”½A?sLÊo`N0M¥q+~*m¥î-¥‡~F7‚^ÈôÓ5惬H]ò${žö|›-Ò¶9Y&í=X'¸V£u+^°Ï–Eñ m®ÿ² +¤·Y/ç0ŽX® c˜ÍïøAæùdPcÜü_X˜ª ™VŸRx­6²ŽÔb¯|Cã6‡å‘éÚÆî´^FeC]¼…¡oÀ-¾F?f7Á˜ Q3éVÌ>͝y­Fsõ•£y]ŸÝ¯M©F®½¥íÁ͊¾£kã^NÕ¶¾¿I¥’¹öë#F›Z‡.À7¨¿Æ†–Qêfã®eÏ«CJ×n®;AjˆB JFÀ€æw +îýmԗîê6êÕt¢”Žã(úI5¥beE‘•¨l ²×X•ôè¨Q•…´¨ÍŒôõ™û i,)…6QS ƒ1zJŠezVBfžì Û¹ú¬œÊ¹•/¿Ëí HQ8¸9ê…SnE%Šoòþ‡-“4ðNJ±`¤`,£Ü)ü~u¸tŽÈyQŠ“Nˆº]çvØ­p‡´¯š+e„"“x©ìææNñ6yä*µøœ©”,“7Á$'äx×\˜Îç”Cü‹ÐQL¿ º[8.d@}›çïCõɏE)1⍑àD?@晹—ÀÛbîÄ$ó?7£ + ‚Y¦ÞMÐä• N­|ÙØÏÒ _ÏTd'wa£}†Ó0Zð„÷“ãî¦ùü<ûÑä9|•Ý3Áµ¯†Ã閗3~o=§ØY>Ûú¬l0Wb=P1‰ÜjmE ‚¬XòR[lÍo¾uv:.öC=æú;.Îa.©œBřá˜S[þnºWƒJ3ÇŸNì1='\XrÉü–8á»Û²Ÿè:KìX÷»j¶6â‰e †g΀aép£´%z"¨±K†1ê¤ï.c1õɇzÉ­°G´TàRi’VB“eßÔòþë-)K@iͬ­!÷uì@_ƒ`»&2ˆq«ê u¿p%P——õ +áéS­Ð§|NüWP´ !€ì¢o-t_àš Šƒn…y­úV|¾Ø¤ö“賐êe`HʏêE =>\½‰Tǀ¯|ÑêcҎ™kˆIS¼T!‹”…ª¦Ì%Gu,%[IRý'®ëý““Áß+#Tç}mÊëê•3ú \ªï/Êßê¯df)‚õ`Š·ü•n2Ž#ÿ·î\°MŽÖû–(ªµCQëd¹6f‘—lÀ—qGö®žµvŸì²µ).Z&²æ¤w¬I¾ùò¿¶ÌTe{Ú‹¹õ­¯JQéæÖÂòܕQ­ž•¿E\m•`¼p–`öÏÒ´ìÁÚ\éz[•v7OV¤o9ݜQõÓú¾¦}ÕØ$SSFMWÐdÂÜny„ï˜u£Ñà:¼ ·*éoœ[“ž3Ø ÅëýO ¬·FRJøˆã0ÙÐÕ¸›l÷ô¶õ€+­L+û&ò†oÛEÊ+dŒ- +­@Ô?¦ý^f›E¿ko¦oó\fyÉÜíJ×Óó«8Åz‘‰ÊΰÒXmi Ëö¿– -NwØ}‹…‹„OYÏpz&˜@>ÚÕg¼ÝªHcþ‡ .«Ã «×]7MŠü£¦z‘#Œf¢ŠàÃæe"“g¦æÎ\ÃÂaã°ì@Ö\ãqyºJc™\„¨3ܔ·‡Á Íò½ðý†r«'W§QVüEá Dè|¦ÉP½L½­‡sõ\h_h—í…#ôÐ9ÏZ-ÍTúdóÊL´>˼!õ„îWS/bžn­iAè3­ÖÑ.1Fx@Ç §3UNåN^nýPOZñ¦dÚ t<¦jGLyÁâs=‚Š³>»vW¾O&-8ךs§»hvöö‡eSȉ•`wPU_´cÛaÌéřÝ=Õ·}öm`«<<ìƒ$•+­»UV×6Ì6dòÖìÁ¤oº88{ÔÝ絁çºzkG}Ú»®Š<<ê7Ó\õÒÓjvg!5M×Á!®wž&—GmpfS¬ÙÎg€·O3x?Ì÷Ø +wZs«LRûqê/ë~lŸK]QÓVÉع¿õ:ÓoÑïmùÌ<Që'ÌÃÆ R]çAMXyÀu¢¨ º^¨ƒÈ©¢€œá ä$÷}ß!ä 9LHÈÁaH8«µh¥¥Ê¡rTtD-Å*ÐífY]]wu¤®Š¢²®u[bgÚÿßg޼ߛ÷û¾Ÿ"î÷ÕȹÚÔ I7ù•ŒØH”R·7ŒH§B—Hðu»£d¿të ÷*µá²²=e¢ JŽ¯t­jŽ|먾 á¹#T­¾•ÎIõ/¨¥W?þ{úΝ¥¯O»^ëŸÆ'º`ú·‘£õv½'$»^®óEÖ=7¨IÉÜßÖTF×2˵”­õ7-¯â^Ô'Zú"[x ;ìü“Åæ[U‹7ã–,©”þQyWrrÛ9†õE†—6cày'I§ ÀgIR“mŠ 2›¹¯Z½Q¸¾ý´ +ç{0K”,è^ÊH©/>€>G’@l`á—Tîë=FZ‹àÓðnZ¢H ¨Ñ³$mžÂ¯鵩K¬AÝ3D;w³¨Å×7⾎ԫŏw·‘^J<á«È`i$ M_¤xÐò8w¿ˆU-,ì/h!Ó»pbPê÷ 1²ª|*¾k _U¾;ìÁ£Nè“45‡ü²’”jûõÍX£šç_€:Õ]¸‘$ %¯Í«X³+éè óÃMiwzô‘z{7í”Ñ`fOEêÃù5Fo´hÆX„}»fLÏ}ƒ¼k%ºJŽq¡_b£Œ_†ôAÆ5ú¥4WK­àÌÕ»ª'h?É:lÓØTHƒmm. ÞmÕ&Æ"öX7…rÑãV7à²Þ×ïžßl̨b§]r+• ÙOë¯pKó[œ{0ƒEÃuwrf ÓµçFaëjCCP§k®ÆtïM»Ý»’Vwô[FRçû(¥YÙ-Vî²¼åÍE8£‘™Ó Á»ÿ™à€PÜð?¿)™p>ÜÐ͛ö5˜ #ÿTÈtäF%‘ú“ÌÑ3ª qhkü”Æ ¡;ã`¼LVOp¿œƒZìۓ. ºÛj¾&ü\CÊ¡ <¿*Ùgü!½°r)JÌü‹¼;ȁ³–&x§K0äNÁ\“úB¼&æ­£Ô³¶‡ùï$¥bԍ7fùp¹è¤t(Å0ú±HÉ2Š€—ª3¤Ó²G1d?źµûè +ùbßVֆ|­°®ÿ­\[æ†w+™tj§j?b7–¤öÏhÄ«§wJñCmÐmê#Íb.^V÷äBõ–ÂDR¹bÑ8¥¡E]4œJ… 7LGÏc.Xd£°à¼/ÅaÏ&ڎè ù@›é¡¢«˜zQuֈ4TÒq¨i˽èèb˕ 4ù3˽Ê~,ãyýmoθ³[ü 0þ ˜ +€l«} ûÞTóCÚuäLõBt 2¿úZÐò¬ã°WÙ>¤´EhÃ@+[‚Řüê¦yŠµÈÝ0= +ósç¦U"r]á;îû]÷(üºÌ{…Ó‚®¬eù ÃE=œm˜òa^2þ'FKv¥~.ôОmŸµ0O­j(›eñs¶ßº´€ ÕPk*!“þ3ùIËBЦŠñs4å{^§|{6ÏÆk\* à}XÌYž¥Ç å©ú‰DÆ=A %ŒÍ$’hǹW‹øŒÇ‚ORV°Ž‰ü· ²ÜâÖUB›øꯪ¢¦rÏç+C°a6¯‰ ¯ ‘ãK‡ÀÔ£eàä :ZÚ¿u6&»à?ÀWË&ïk‹).”Ù]%¯ä]Ü,l”b7MX]Þ[H"}ªìØWL)RI·rÉfõr?Aâ­ÆYÈ&íI¹~_ÂIBåë$Ø{XŒîlÿZ·°·—X¯E¾&|¯wø#ùºßþ؆û`ˆ¥_vºß¢fã–õØu¨·æ3ù—°füÞõømæ¨È8—9Ç?ÿ˜9ð£ +̟¯ë”NûՎ²º`çjz1*äÛêöüíè.Ç@’ë爎܋¹ì`øoåÙ’¼J_™·±™+-—4α6@’Ð/DWEÞjE}HRæDl¹‡†;Y+ï öÛÏz•®‰/‡–…þˆÿ1†Dçѓ(z)oι&ù;éÝ.§4š¸aZú#Ùg—êsÍbÎZ+úX½Wi;ç<~†næ"¯(Á ô´µ ¢MŒ'‰“b6›·!G ãúùlP<á^\ÌÙnM8-—-aœ G+dyXPä^Ž‡s:û¯•÷0q \p3bˆ¾ññW¬u.æ,Rå&År§„m„òž#<„HeÊĸìvQél‚˜Ã.ˍÀ±ïJ>«Ò›Þs)·àlej…(‘^ Ÿ¥,—=…/¥¡€¬FVù’ø6fjùðÆ;eð‘­²x•â%ºD³‰Ÿãk¾%!FW@aäæŠo2QT‡vs¼ §5‡Ãhí0ðŽB¦{âUò÷H—iGCO˜®ïãzL' pb¢Ižq”¼Í‹+'_1…¯¤Lvà +‰‰ÿQ¥ÁAÕÉÜÓ%ǃÄ$Ìû[H~‡}{†1Øf½KÔÙ²Â:HmWS +µ¥Ã«d}Ð2w7ñÔõá j¾¾‡­<ø ½O¯›Œ­Æ7ÖiÂ2‰GêÖ;SW•Ý’Ê!Ø@YâsœZ~ß*âî¦ÞPƐ6îx¤QþÜ¡Ž§/9iø7cñGªöHV‹fÑ3ÌáR>K•ÌüŸí2jêZãxH"Z‚"²)ûvH€Dö} ‚@ز} YÈJ64ˆT(P_Ý(*¨C]žŽ¢mi­öéSžJq·OZÑg­Aåé(nœy8}wν3÷Îÿ7÷œï;ó?߇‹*x"Dü’Ö6²Hae¢Z +Ä5Kü e +tE=H÷º·—±ÿš\ƒ·W¢8 Žù7¹¡2ƒy÷èm¡ü]L´ËŠyô‹ÚÄ ªß1N<å8͍¸@û±û±“ù:ï> Å>›Ë6p·„ü›ãÈÓ¹à¹<ÞAМš*ìµ®‹5M +àåN5Ðøƒåg¨Á³Ü¿ÑÝ]7ïcðDþ!\Æ÷¢ÖO¢Û6Nê(©·•bž¯‡H´õ‰éÖ²r¯t1gž‚“u¡ÿNÝ'w„ߢËeÎGrºÍuŒbÞJ1îÖaÔ#øgøiõ|™ÑGcŸƒ"½ÐÀÐ á'xù¾&ÚYH;£¡Ùª4›T1}‹Ï®;cÚV*¯‡™Ü²w¦f”™´Æ|œH2;ÛR±Æl›Õ{í‡ÝKÿ²*²óGÜùZPgìÖ׸z *Û¿ù©?ʗÖÁ +¦×“:ÌN£”Íæ9u¼ö”•¢L7Ûo©­¹Û|jëBñjEV—QRªî!Ū¢Ú;~;ÔZüZûËÚÝxÙ²ž +ì(Åñ†œ¦qìƒê’ïªÁE蠟ëV¥‡Éñ7å:b¹Ÿg3ìh\yˆœ²¬gå.:OšîÇé«ðÜ0ˆ7ºÒ¢›¦bÞ4=¢Nø¶Hdto{¥<ƒî¾¬çWZgHåNR•üRZ\á¨às†W*Zxˆù Æ»QÍ®ñ™l<ÆI³‘Ts|—õâX)‚…c?®€p \BÁ —ÉK‰àuðç¢eüÁ|0|/aì½hBÈ|樕ª—ÐsEG±¶ÌMâÁüs¬Mâdû‚Ä?ê*G,õ°ïHÞÁæ…ýRÀg®[)|å3…¬CëQÌå{0b•‰Iט%9*–ùXÙáÝÌôR‚MñÇU)+ë^Ü ¹P,¤põy*šŸ~uR½Hw,r„~L×îõ;í_º“°vN§øˆ"¹í¿—“‡Û¿Ê]¤ðÌ//S{̑‘êͶË^¨Áæ0X 7Õ4¼’ªžÓ㊈Å#úޒ{Y´<mg¨$…Œµ5`·ÊVs-*l¬Û»¬gÆùr¯’iŠË•[ šÉÊöL¹–X#DEhgq!N-_׸Îêc YP‹a ˆ!wÖú¯Ê|Emí±"¬ÒŸž¡PþDŽOUHSðr5¸a»+[ý– m×þ• +äWh¥*Â¥{I/1YwûôJyõ׸jùkú@p[³†ñÈåzó3*RÝeñŸñµRXwq3¯0´©Œu%­BÍAŒ%\NÐC)šWí’'5ð꡵ +&ð™F+U,ŒŒd5ò…gR "JãrØVDB‹SDO]V‰[EסdyVӃ•1,+åIevù"þŒì`Ê‚WrwÄKa¯œ¸Gø…|—óÞÆ`¹Ú%+TˆVR¥C¸Fœ÷œ{Ys*¥š÷Zó5â߬±Rùe³s¦ Q3 +ÅÉöjáQA¬4Ӌ<>ÇÆô$ù.7Ã$C$p¯ç¹ãçõ¼Aã)h©ì„îéJªè¹ewáTÑÂ*Fmž´èK™g-‹ØlïŠm„Ê*{íö{•¯–ºÑv\ܲžsØJa>3_*ݑ¹Ùüہ>ÑîVµ5ü|»¦æœWG_Ç>ÁâR÷óR_YL¢!ì´R…Fã›jz†§ Sû5fځO›2Í’<ï¶Þ `¿¶}I\:ÁõXêi Zk³R–—H*‰Ñ4„‡Ùè[(ßxúÔX›á$u|I9̺TkV—ÿ…z––œ×l£_‰×¼g¢C½µ%¬*íw¬XR ‘õnY)N.õ9+•wZñ[”ºE9ÊľW¡øŒ¡J%ðw«p`Nj“ ˜[ÅÊæ.Èb|JOsd“W,®ùRÓ~ø#Å* Ľ±yFâdwC‰’pÌûˆ*‘L(8ÉOeÅò¬lL±Ç˞)A›ÞÈ Š·vÜf¾ˆ¶F¶’ʹ.¾£Kn•dë~Aò¥¾º]ðDi‚ã(iÔÕÙ]YʯíJ½õ™Þߟ“?‚>Úwó[ä¾¾Å7ü†ûKK“6Èw"ËÊ!eýç°DÈp”ô5‚µV* Ý3VEa{:KoEDôôcɾ˜ÞôJš#¯oOU4ä“—š4¨å¨ä›l¬TjF·k…,>±{SÕ?ý»SkÁ>‰ÝSu»×ïÞñ=Î|­ëj}à€‹Š­T +¿SU÷.nkç.ü«°“„ƒÞômâc‡Å®)RxØbÛTÈ<ÀTÕV*y Ã™<+î`R‚C³;SÅ^ýŸúÓ0û-ëitp¿ù<ȗº2I—Z_0ñÈ¡¶VVKHWÛol¶—­9“=ëfdÿ j…ðb€¹%}D¹C¡ˆyã{Ásø‚I*”{ZLߏ¯›1šÀ½†óâr`n}+©D¥îŒÔ×_•*áUzÄ3Êð¹ôÀº}†i7˜§7‡ÿ9_‰kµÃjxÌLË+u ¦;¤FxLë.«mÖm×áÔQ`sK›zñÏ´¸ø¿›K#—> ¥&ÁôñõޗxiB½VÝ^Í\sË3Ú_X»è€X_ïرá¤ÓC˜+Ò­j£|SŸû kžÏ½ƒ|j|[ýŽúßX +ΆÓBL¡ûÃ.„?Ž\ÃD˜‘C±ãq÷ãߢ7nŽO(Mä&™“¿JO½Ÿ¶á˜š•™ËiÊݖw0ÿ¿ë÷ÃIÝJ÷LM,NCOYPoQ†RœS²TÉUßVöX Y#Z:[Q\f]x^Š_›`­a¾bÏcàdñfgh#i3jBkRl^mgnqozpƒqŒr”sœt£uªv±w·x½yÃzÈ{Í|Î}Í~ÌˀɁǂф¿…»†·‡³ˆ®‰©Š¤‹žŒ˜‘Ž†{p‘d’X“L”@•3–&—˜ ˜ÿ™òšä›ÖœÈ»ž­ŸŸ Ž¡|¢j£W¤E¥3¦ §§ü¨ê©×ªÅ«³¬¡­®}¯k°Y±G²6³$´µµí¶Ú·È¸µ¹£º»~¼k½Y¾G¿5À"ÁÁþÂìÃÚÄÇŵƣǑÈ~ÉlÊYËDÌ.ÍÎÎëÏÕоѧҐÓyÔaÕIÖ1×ØØæÙÍڲۘÜ}ÝbÞGß,ààôáØâ»ãžä{åWæ3ççèèÁéšêqëHììðíÃî–ïvðUñ3òòêóÃôœõsöI÷÷óøÆù•úaû)ûëü§ý\þ þ´ÿZÿÿè§,„¿ç +    üóæØÌÖÞááßÛÖ Ñ!Ë"Ä#¾$¸%³&®'ª(¦)¢* +ž,-š.•/‘01‰2†3ƒ45678€9‚:;~<|=|>|?}@A‚B…C‰DE’F˜GšH›IJŸK£L¦MªN¯O´PºQÀRÇSÎTÕU×VÙWÛXÞYàZã[ç\ê]í^ñ_õ`øaücdeeÿfügúhøiõjókðlîmënèoåpáqÞrÚsÖtÍuÃv¹w¯x¥y›z{…|z}o~dX€MA‚5ƒ)„……þ†í‡ÛˆÊ‰¸Š¦‹•ŒƒqŽ`N=‘,’“ +“ú”é•Ù–É—º˜§™“š€›mœZHž6Ÿ% ¡¡õ¢æ£Ø¤Ê¥½¦±§¦¨›©‘ª‡«¬w­o®g¯`°Z±T²O³L´IµF¶E·D¸E¹FºH»J¼N½R¾W¿]ÀcÁjÂrÃ{ĄŊƐǖȝɥʭ˶̿ÍÈÎÒÏÜÐæÑñÒûÔÕÖ×*Ø7ÙDÚQÛ^ÜkÝyކߔàœá¢â¨ã­ä²å¶æºç½èÀéÃêÔëåìõîïð ñ,ò8óCôNõYöc÷jønùoúlûdüVýDþ/ÿÿÿØhÆ 2 +R e r xzzzyuph^RE7)4=@?:4 ,!#"#$$ù%î&ã'Ø(Ì)Á*¶+«,Ÿ-“.‡/|0p1d2Y3M4A566+7!89 ::ö;í<ã=Û>Ó?Ë@ÄA½B·C²D¬E¦F¡GœH—I”JKŽL‹MŠN‰OˆPˆQ‰RˆSˆTˆUˆV‰WŠX‹YZ[‘\“]–^˜_›`aŸb c¡d£e¤f¦g§h¨i©jªkªl«m«n«o«p©q¨r¥s£t uv™w•x‘yŒz‡{‚||}v~oi€aZ‚QƒH„>…5†+‡!ˆ‰ ŠŠ÷‹íŒâØŽÍÃ¹‘¯’¥“œ”’•‰–€—x˜p™jšc›^œYUžRŸP O¡O¢P£R¤U¥Y¦_§f¨n©xª‚«Ž¬œ­«®»¯Ì°ß±ó³ ´ µ8¶Q·l¸‡¹¤ºÂ»á½¾!¿CÀeÁ‡ÂªÃÎÄñÆÇ9È^ɂʦËÊÌíÎÏ2ÐTÑtҔӲÔÏÕë×ØÙ6ÚLÛaÜt݇ޘߧà³á¾âÇãÍäÑåÒæÐçÌèÄéºê¬ë›ì‡íoîXï\ð[ñVòLó=ô*õõööÖ÷³øùbú/úôû±üfýý³þMþáÿqÿÿٍ T– ¡ +¤ Ÿ “ ‚p_L7! ðÖ»Ÿƒ}tfUA, ê!Ó"½#¦$%z&d'N(9)%**ý+ê,×-Ä.±/ž0Œ1y2g3U4D526"788ñ9â:Ó;Ä<µ=¦>˜?Š@}AoBbCUDIE~% ô€ÛÂ‚¨ƒ„r…W†;‡ ˆˆê‰ÏŠ³‹˜Œ}bŽG-ø‘Þ’Ä“ª”‘•x–`—G˜/™ššê›Ôœ¿ªž–Ÿƒ q¡_¢O£?¤0¥"¦§§ý¨ó©êªâ«Û¬Õ­Ð®Ë¯Ç°Ä±Â²Á³Á´ÂµÅ¶È·Í¸Ó¹Ûºã»í¼ø¾¿À Á0Â@ÃRÄfÅzƏǦȾÉÖÊñÌ Í*ÎGÏcЀџҿÓàÕÖ'×LØsٛÚÄÛïÝÞFßsà¡áÏãäMå™æçè6é†êØì+í€î×ð1ñòïôMõª÷øZù«úöü:ý{þ»ÿÿÿ€€æOÎX͙¨~Í´Ú™~yœ£~eƒLÆ~…j…þ~ÀQ¿€c=9€üÅ~|‹4äµ~c‰lÌ@~]‡Ì³š~n†fšØ~˜…C‚~لOiZ/ƒgP®¯‚¡8€væú¼}6–qâû}0“’ÊË}>Ï²:}iŽ^™“}¬Œ,€ï~Š ׉_L‰p‹´²‡K­-~~,*éü„~ŠÄ&E()D9ÒvüªyoŽw¿yóæÍ=ÓTS3ÝwI÷!¦D)ŠJ²ª%»­„ßOBvÿ‹ïwýN6ìÏ4àø;ç>ý¿FVWíñÑm¬Ž +Sý^ÖD±iéÀ*÷¬bPk‡ÙÙà†ÔÀpØ©È?³%"È1ˆ#!ϼK`ùµŽL±<ín-eª2*þÀÊ+Ý) X䥂C@µv2l Q?ñþ‹í(=ì0Éqåç½ Mzï«ÇƒIãz·¶¹¤7MEïY;ª¦ä Yµ¥@K (×-ì¸\ó»÷Uðù¸Ÿýžºõ&>©røäðŸIª^»¶ï“2ôò¢ÕIãMe;Ya•àÛ"·ÐVà®Né½,SÙ;¸²oª_%sœáD;»õfÞƎ. ±çìãR?l ;0Dq¶>´™á8z‹DÎKG)ò3oÁ”+Á&ï<4ý§@n͗0ÏEÐÉO¨9ò4©‘#ÖçҐµ°ð nƒW9 Âb¨å¾_Þ‡7}B¯2±yːvú„è/ąJH삻Ȧ³Õp$±È«ވy;ØÆÈÕÉǘ¯fþþo虔¸F¨LsŠà²I¦Ž‘,Kh€W2î!¡A˜×jHE^°Ï„ØâÁ¨ _ÛwÑd¯lX÷gÔgÁΩr!jU)þ[%ÊB¾†\D¿ÄCf‚pû <_€Ì\?ØkŽ,.©¯ë†wäŸÈ²ƒ²²¬irJ·Œïä½R›žñâݐ=>0Á+cvØÕñZˆ{HlÓlÏLÔø×VAåc™Û …ù‚ ^{6oÌCҏŸÎãSõˆäمðbȏã‘ï:sz à 7ÇjôP@ÝQ¯ùÚÕË;[Øw‰g“|z3Ï0Uq`!ÏP¶Óîž-~|ÜôàX·3ô°+°z2lIђ¼¨:ê_<ãòÌØaîXþ’S5\}úçýEÜ^…ÿöîGêÑè +ÉXÞùJ4†^¿Æ¬w¤ï¤/€ûI!5 +Šbnñ#ÙF§Œ‰Oìüý®æÈìŽ`.ܙ‘-âJ\Õ!gZ0¿ +)ýÝ¥q A߀«½O’°kðVÂô¬Ã^B™Ûf8KĈza>p-Fð„þOÚJ*€ŠÆÉYr(º—¨".À°Ož˜'š±ýºqÚ䦨ÚéfÕårC¡üRJ'–dc~¤‹híÕ!€Î?‰`ƒÔÆ}WÑzBd;…hѲG¯„ϲåm½T •ÖSAi©j9š<î „ +ߨ×ø%É@`æÅ8xL¢®T­qė=¬,Mk $hJÔü®ìöd˜ôÓþ€x_§r¢Ì°gʱÀ­ht­G,ÒK±ÝytomVK0õ¥¢¼XÇ?R<¬J%žämqþ–=Џ ¥]ٛ¿“aÛò`sÊ Ç7ÕàÕg&Gr§ŀç?>ÝÄr&Åz`øb>&ø“ôz¶Ë%¿•sxÛbwì®&å{ô~¤Ú…ÜÈ]"WÁR©%¼c"z•D “¡ÐãzA ´Ýýßr¶™Æs!֝=jcf]­‡rm“ýA¦¡NJl$Îäے™#ؑ é>ÜëøwTfáGF£F69¸9<×µ.ù'S³Z*¯Ëº#½-ýJl.ÑàZÆZxä‚%m*Ø|ìÿùÁí ño± Ç2Ðӝ_TÚÿWÊK4™eRsu33'jRF–B¾ÌþüWl|ôÿ +ÝíF§øgml0L×1¥, ©œ—¯Ïy¤+•HuÑÌ2‘‹f;Ë[¸T½0BEÍÊ{Ž:‘¯Åqn¶ø´àõtoÑT†]o®´”•–úkI, + „îLgV_R:­Kϋ0¢dêP?= ËÆv¿ÀE̷փ(M4èm”‹šÖ\—ùT·k׉o–ƒ´”‰,ôHœ§=³Ãù”‡¦Þïé¤Zµ»w/³®E½Iñ-LQ¦ÿµ¢[ú©ùÇ ¾8¦F/˜g֖'$‚?‡[òçu~fÄgõÔîhÜXÒjšñݚ-³ VIñmíK˜ÂՀ,%išbÁŒQŽþç*e9à7‡·ˆƒÀ—®ÏèWK«‹üÜM™YiHtÑXÆT÷¤ÅBUD”ÚúwÜ-Å4ïþ9#i¯Ô—/ñr]£hGވÕ/¤ + +lD2 h§Â‘Œ%TTòT*FÞÃédw">ö­âGüðY?é"ì°Ï[f r5ˆÌʊ4€Û`ÝùTAoº‡4H5”rWôS¨8ÂÖXy˜ ;$YrŒÿÜ'‚q ævUPñåV&Š×çèÌ4mù/5LJ¸òEÊ:•ªSË7Æì’HvŸy..ø› økâP¬X¬¸Al…¢â`Èå¥ +Ȩ,eª‘: EÁ$@B’KrÉå².!{A$AÂ,ÈCåY[EA;|Š TJkU>°ý¸4í1aÕƜdžcT.Ð×ÿéîUs Rã&ùBc±h»R¢)¿‰’¥Ä +† Pd;‘ÆÝʟH«b¯‡ŸÄl?1;_Ñ:i»^«½mùMh9Ӝ+,—xê+(‘‡j3ö=P6uü>§¯a}Ú&¨‰¿bß (ƒúÒ0ô€®=ªá.À<ø’2&îmÎ%ë…u9¶’_ª~z¼Œƒ•­L½å!îS`(ð6͟>Õ©Váú”l¼ûW䨸¤m5y‡pgó!ì2¾·<îÉ PêR%wCý>èÅuþb€v…Õï«bšFñ.0¬¯ÃUKÒ$áK¾;¤Ø‚ÿPà,ž!ôrAÔ5­Ñ%\×ÚvüÈò"Ú +[2Ég”wãõdx©ŽJú±æ“:”_Ú'ßEښ_+^CژÌÜ íŽÞÂI! vüÎ,­¶V7—2UJ§¦÷Œ÷ìL­‚N¨ITUÒK×ɎIy/R+“=+(Ö¨§°Œ²vÇð6™×â°Èø·!Mܨ²ñ ¼‹@P¶B‘%…R-›—-â3’ì|4Ý-ÊÆþ”ï˜)#Í¯Í Òwòƒ¨á.ËܘŒ<Ç;”ü b»ä#‡’;*œ…>$eó†˜G£Èì +º>à3ÆêïÍñæ"íو~A•ÉZ¡±Ë$xOU¼¬x›ä äf𜓜x;Ù¥QùÐ h XÅ(îZ”¦·–ã²x=É`dšàÆ 8…b‘†i¿•dç, ϐÉÄ!îenZ +b°èî /šÞ²ÔÔІ‘þ ßÜ2ÁôPß0~‡ “+µ›1ÙbâaŽŠkÜþtTÉö ð ? g›)¦Ô˧¤9ºÇ С¾`.ޓ§`>'4ºä\DRdí‰åÜPaxԗИ°‰®¥?i|Ü9,¾t §¥Ä´˜q]•Œ"¼ë·m-¾9«O™D Ä'ˆ«¡ExÕ>÷#BãÄÍÓÎàz6¿ºõÉNkî%­¬tmҍß6BDzV®âQ÷GÃq,2ˆO:â× yÔ{i¾îHcy[]èvòaËZÚ÷TÃ5 ºÈ¨±R 3§ä4Š5Nß@qü‚G!ýfYXr‘º³ý{î3^¼ëëM7HX1­Ÿey«ŸƒÁ™õ²ëôÖ8´¨‚¶7ҙ;NðßÂü•ÂP9†Åtn§/Dê=ÌÅüñŠ}*÷ðIƒ:œý2s›Ì‹%‹óþÜñG{êŸÄ¢7©ÿaìbÍ“œæTÓB•m…6ÛºÒ4JZmüIçÀ׶ªFÑהzé\F…D*ríE²yΓðք¿ Ì£ÝV¦µ-ï8ˉi±Ú#ˆ7•æXmŽîZ®LW:2 +$Iâ·±d­`UÄ+¸ƒíæßzÓ3„Ó 8"}×åY\úE^û\Qñ¼íܵ‚³¦)<&uZ«!FM)V×…"çڟ}ÎÃçˆ&à/éíÎå ﶻ ‹­¶5ÄÏ Öÿ¬›O546ƒPWä눤0ð ÒfŸGlEýbd¼c ­´'œÆªžrûŠÓ¬[©ò{K(ÔÔ"M/y%•“Á0=²Ÿœâ»zFŽBx}霚{w6{Y5¹í0Ëóº%,ËÇ4ù0œR}ԓ´vTôp>¬K@¥fùR¡$Ê7HìU( ¸ÞÅàªÃ/1¹¯0’f<,È÷1äB§S>¨ý˜Ù¨RI3#&ì&ÿÿ´pßaÖ5j¬àé•Å1€Ð9#yTõ®õ±H†9cùIÀÏû[ßÎÕ§Œ©jÙ¨’U̟Ã~á¡?óýÄÊÖ À+Ý7ÀÞNŒzMÕ`k†|-ækËqJÞ}(Ҙ2¨œçþÊSØÁaÓ¼Gài¿ æ;ຠíÊbË:`uǤayU“}T“€ 2÷ÉûòFtmâ̔%OpuDìÁ‰›ãU0m~L-_°¨·±µ:ÛqÞÒW¥²gÜ0~æhuwÞ-] NVº‰rPå =<×]x;Y×ýÎ1Ëiw@á­í8,áÝÐnœù™«\(zºÆq²¸ö‹ø˜„b“ !$zB³§&5d©øníÈ6ç1Q&ß &ô «ÊC¯Àu÷Ўy#«À†­c%$7ý]w'z\½‘×0Lük{8 ú;ªËfºG‘Sè —Fx¬P‹~ž®Kƒ’÷†Êm %t3ÒM÷ö€êcúúcM(¡ª¹bCÙB·§$ _Ú œÈJ±,âÿË@ø՜ †¬%Ó¸Zš;ó‘˜.6„’B˜š)éPé˜é Tï~¿û~÷Ùù:_÷«tH·NI¥TØS„‘c„ÖΤ5Ùýþ_Ø3¡ðšÂb¿Oö6É-[o­ Ã7ÿ$ý–Œc†nú•ú“:¸zN‚q–³n¨E2~Œ7\NíöTº¨ö'ë ²"[–fTT°Ë^2Fþ›©í©²&µ¿+¥Ì—ô®ác5r~ԕ¿Í(ôìÑ÷jæ÷é¼ûl 4´8mWDC]X¸#Œä×<˜¶ñÇn”_ ÖT™¸ 45 øC0 V€‹~ mñ€&AGçAø¾­ã7w¦¬Žø@Ïw‚«ØóŠ;˜½ÖQ8‚à îQ³  òä´?d‚ä9¯€÷#1ó·yÊ•q¼_eS]y|ždÌ*Ø&6Q¿ô3 0J(¡WG>ÂHêãËN§ vøµ×Ag÷¯+Ü[éo:y1ډ²GümªUVá'p´J{"„¥âíÞM@3íåX­Çÿ|Ëñ*ñ¿oƙÑޞÌ%sfJ¹<·Ìߔ§ù[ÓþÎß-0R'G äiÞ++q¢ãNPFæ¼\ÅÖÔ&ÞíàXT~yýkÎPÉxÉ>®¢àŽÂ–—ýŒ·ƒ›þç ~u2LX'»äP î MŸO±W· ÇrØ© Z?qöU·ïäü·\+wå>-”q}y/sRÂQQúú÷„ÞJ‡Ó@737ÇÊîK­a[tÌ·š°»›„Eû8X­¥,œ›T¾ÈÑñpý•°¾!ëã‰PÁïêVûK$³`ù¹üΚì×µœbÇu~*LàìlB¤z-ì÷<ËR&,Žœ+?þAP«]²oœÅèãLâKžÙ 'y¼¦¯ð ¼Yý?± +~”t-"XÏnÃv&Ãô­°ç„?úøÍÀVAìG³˜+¿‚™¢Ï7¢WÑûÑh¤KüµDâYùèZÄ%4YF¶g£[öÐ äÄC_ÔMæ6ЅLJ®¥!˜¨)¯9ÍÕ!6ÔÛ-²‡l?¯@œ±W …Ÿ³?‹t`k¦;Ýé½ýæpŸö}ý +P»ç†À>Šf†{Ë’i8DbÒÃ̯Mp/Ų›FñÊ_<`w½[ßUèq®°. ÊÏËY!é'i7ÓL'‰ ƒRüz$û‡§v]²cÁ-äÞ©%HYÙ~“ٕ­ªç Ï鞀ws{)WðaÖñ˹Ðúԑ`è¬ÊùØ{¨[zÀÎ ö¥ä“Ï¡•ö½Á¢Z¨& ­èËz +-ù† ƒòU‰Ï@uÖBP.8›jz …Bä£{G tϤ1˜Þ•q# Üßò¸^×oÍ2†ªN*`®D—èZçm錞cß@QYîÕ@ÕÌðÄOàÉÁùžy`þ†Å•^ £Í)ÓH¬?€?˜Ês %Àý¢ðÀJð@öf»à-ëÞHˆ%ª{#}řìPKn@Åu±5w:=ŒYæX9ýŒôÒ(5#p ü9#ôô½AÄv(~”-Ñ"]íQb'ä ¡y¦Ñ÷a +­¦Æàè‹ÏÉ'ðÏ玣· +¸ÅvO@¾Ù%ö7_ß*Z-r*Çé~z Ցê 4ˆŽ!ñøwÄBp‰°ÂõG-q.Öa+Ãî¡cÃÃ"wmqk=½¨ÞWfB +k^ƒ²«0‡ø¤>n‰puŸ5àÝ㞃= «m]0oüüÊÄæ-1ô·:ǒ~ê³ô%ui¤„¢;ÕpÜVœ”Où/a3’î;0†oó½KܼL·—Å6Ÿ¢EÎÅõd@þZU%¡{ òñÔô‡±^Ø Í°ÿyÌO‘íV‡NHLm®¢©uƒ?ÑuM¡äB•EQ1\úIُOéu¸iÎ@L–’‘ï7‰Nk\ÝÐddƒ [i‹|ª¯í‹ÆlRÜ°¢è3"²ú¾rW^ üˆ +¹1ë°Í9ö~±(Vì¶ýZQjsf¶ü•b÷5~Nlï, $LAE ¾±Æ\ù–ÝûY†vÄø¡‡3kŽô"³*ÆÆIežö´¦.²gj4uœä¼D•’k"Õ*TÜ~~ˆ¬œgˆ^– ò›~½¼<|ƒ1â­c©Px7 í‚kFÔ84‘K(/AIƒ\%óH©âG;‰'¡â6‹¾€æ ½à`kK’…¬ï +Ôè¸Z¯J¤äAÔFqµŒKšqÓ$5„GT´è#.öa<±ñC]”s¶zOŒ£9ÇÔÕÄ@yQђí-–D¥RPÒÇÉßGªD{˜Ÿnš¦ªùoˆ«^Â7é°PµëvU±vºƒ²ôT_F"éT‹Øe⠊ñˆ^‘9ùì¡^‹9®¯É(Zi•í*³¢”JŽ|1¿"Ë]º˜ýœ.˜g:±ÆE¼TIÄFzNõË÷%T„|ƒk&ñJ´lÅÇãIùõ3ʌª+År^¹qfŠ”SNM‰‹òX»™eÝÆ $’vî{ò…ꢫ?I¬Bð-”º-Oi×0iX’oª È葚T\£¬Å.%kR&-?(ümš¥=ó€Ôþ?~3ÂJncu ¦/·mS<ìøÐ,»ÙLeØH:ëi¢_+MSVüaù kò@\Ѓ*ÕÃ+w¸­qDS!h”²e +ô4€–9"(hÂd}+ɗ½7Œ°)T« Þ b¹ÇªÔªhmõê`Y­Õ»÷ÿ ís<ª†-´,@˜­Í‹ÀŸ‘þ¸ÏSCg—ZwÓñN² CUëcªÜWš’š¤Ê-JGm\Q²ìA]Q†]Æh&D‹¶0±íÐZvnw %’õÎá0†°zºÊMT“XÈI¶ÂÉò:¤Ól¿ŒÅ<›7åaÍ` çù™5æP` ±Ý°Dh“k?Ø(ªbþø Ÿü?²`Fº‚gÝÏ—ñÖűàîy¬¸À=î‹4EJ‹í­ú0 GvQ³O4À©W²‘Šd SAšnMÿCäÄí€ +Ò±|`ïŠ7ø_·ÎvY—£¦Io©«ÙRÅyYqE¨,Dò;É&Q‰\éBÑxWì¡rÀ‡­v tÑ Û[€¶Ë\"]£º©ËU¬ÐØˋ¥ ʤÅâwÒ髐±<¶ |Mc+…éÂåç ÛZê¬9Ú(WZ¦Ê³Í°Âäf“ïø¨t‘Ž~X)†Uái—á?¤m±ð;1 pš't.t-SSUn;Qñ›à¹Y(sўè§Ð*ÊMº8=÷œâ +BHZ# ƒ–GcDáSŒ¬ä{d'Ù,UÚt†£‚lÓ=í´,}¼*–¯vËcrÓ+Ð]‰(_ý1rœÃ˜@?A[ã˜ã±K£Dl¡v'”oî>=¦ëԏ’‡ÕÔÓ•[‹µ¨?úQÔ ¤ôn!ܘå€ÚÊeÖÞæoø…ÆiÇÜéB]²u3ùˆªßPzP'ߧ–%•4É4Qw‘ Ñ L7@ì?;ˆgSVjgoÞhoùpê7í´sy‘ªÄüRö\7”ø¹äˆâVÔ%xL| 3¬nëÛ|å´2Q|ûí-ÓÜGo¯tž©uÙV֘³Gkî}¯©fdã'å‰Ì°yQ/;^¿Ò+bÆ#Û&™~Ìôæ„úي2‡—¹¼(ßÊ<•c 3ß;¤n`9ðã2[Lqztö.˜ÿ)ô<äÍ×ßlJàaËnìæš X>ãîɚÑ×pöòTֆ‡ø)Òð$œDrƒu:5¢zøjë,|·~›û0T\~È>®*,6Y +]è·7E9!À¡7ùëÂ;aˆ—¢ÕuŒ*Àñ­8Y?ÃäÒ¢Úã#ö±¦àWñfÅiAö~ª\âûÐmB\ø$ôžOÒwDh°E©•16:_«ºçÙJä³ qBšùR%–Ÿ*Xð÷ø3 á!‚ýO»Ëþ:Ü`Iª»è¤š©o¬ßk×ì2¦+õ™}šYñºü'1ß%Y õG¬‡°ÂPMJ{rK ´²Ùæüwà˜³¢žµæ_‘æ µúL¶&N¹‹è‘óÑ øNñyA'…Õ³mﺾo4gz"ëv;L® j•eΐ† %ƜÌÃê{š¢N¾S6òÿU'*ÈÍ@†dÙÀÚjNcÏÍvêo^=‡Bi ­ŽÉ7¹95¹©Ïlµ€AÇÀⶫ62ý7ùIÒØÛÅCçkëyV_}BÕË.I=ëYR2¿ÂU^ÿcê°ÕÌ~÷oîß\Ƙa3Ƹ2Œ«è@e»ÔæU*Tl©çm«cÕÓ±½ý¾Ÿïå~í x˜¬¨„–ÿn’ÂN¾îú«ÈÚïûU¨Ÿ)o`Iχa]é¯ÚþÀæP£³ÐFÊŚVTC&ÊÏ£Ö࿋Yè=ßd]/æ§Ã.ãó.FÈBX´s+$íé=­}buMÃ>‹RWm6“Å–6ᢐÅFX ÷5ç½x{v*ñÇØÇîýj;‹zv­²<½¡¥_~‹ú•ýA¢”VUJϐ‰²^IjˆQ…x‰ï½¼uÂQ¯oÁ=l°K§_ÎÚՑ¬EÒkZ\4³¨sêqU7¥ÔvOa ëJ?èÂQ)›4C«ƒ^ŠÅÂì\ç¤ñk[{»Á3½¦y¿~ÕõÔMí|JµÍ'g¹¢4Ay,$µ0œ( j§H†¼lò:Q"V҉”1X¡í&eº½©»°ƒúí© ùs)M•Zœì(éW ×|ÒϹÙ\¯‡ò8Ñ8&ít³ícýp¦ÓҔÞÞaö ’ê…Í”«•‹ô ò­’C¹›CŠ GU®$^îfb¦·³|8u´ÓÈ̸ÇÍûÇ&áÑØA֍ü9kÕe€7”;Î㥦ì…æñk¢oÁ›ÁÕAv¤úò´…Տ0o5±‡Ÿöyœ'ð‡ò—Üø¹ŠÆ€ÿâ<ä!îÉûÁ¹HôÎ÷P’4þˆ|yÆÜCÈ{_³2eî§ÅlTrÉsôâ*¥·Idg_à¯'V +Fvz|"ïƞ¯¦Ò©n2=µ3[ï°"s¬¥ŸÙtÕ ù}Nâ8«”ûž`†ùñÒÌ1`X¼iý]àx¬£½(®U2\o[v1·d%JOO&rؗ´ß0ܵ9³YxÅݨ \–´€¼D‡m§¹ÖÄ]=Hßjíovfd—¥˜)Ì:ÓtíbèdH9\”Øϛ®YÉ?«8°Þ <%þ}ÈçdV‹Û•hšÁnuŒÓ»kV˜¶3+ª¥(+µ$ŠÞÁ-¼›¸Š‹ë¼#¯ð£Õ‹®‚QÒ°ÁØì·ÚåЖžÙãX@ßâh-NdðëÜ$Ìa«š>•M3¿¡q—œ"yÿÕè$À[YÚ@S¶õšgÏÓ=ݎÆÚP‡³±˜1·)L<Æd×"´döìrՕsÎÈÝñžW¬í ˆìDJÿ +tÃýbêÆ µcèj¥è*º!®Aq +hGÐ|î3j zŸO‰ôÀ¶öú|·Nƒ +»°*ªÏ€› òÂÓðÔ%2#ÐǓ™H¼7!¹ ;v¤¡‡'ì;äéOð­ôëÎ~hµÄ¥î%”,v6ÄBÕ¢ÕÂTxŠðDv"Lt¤Ã¯K"N#œ¶.ecÍ}fÀ‘˺ŒçdÖ&ƒTÙù R¡øASˆ;Yq!óþ¹ö–¤E,ƒŸ‹ëü‘AAúm?~•±çÜÌÐ[ý7ªÒ[“ö> \¦!ýB;U¬ø!ˆ)/×À»¥¸ÿC$NøþÖ$ïAå³uüe–uU}ü,3Y'äß/JÀœcùð .8_[O¨Íá®ÐùN-<"N¹ù™·¡awG¨…mý¼_+•yj~P™]Å¿^\y¼ XÀÚ,r-¯|à㒒›¡Ü³ííã<§æÛL^T}½ö,Ï^eDRø»,êãn€kqց%Àë|r,ø!gÿJx´±×Î=~ép{"·î\ee÷E«N;“·ÃžŸá=©òÊ$øöÒ{q@Qá¦í_À†\?¿/иLe–´>­u£ä#²¼M²œÉÑpÄ'Y¶Æn²_e<…q㼅¼±íRa8pÖLB“=ƒ’(àYK—[l¢«`BK´´‚½B#4;cŠð;HñS’ ^±íOA<è·J°¹~¹I4,ºÖì$"‰œË,B\HV'&fಀ/pO_*ø¯Û_‚_Ã#¶¥à&l”ôWcÂK B«Zí(ü¥|Zú½à b“ê+|°ñKpTœ¶ +ÿAr3vŸ*>¼õö§ð>Ʉ½x\œ+¨0lk¤àïôçÍOðÔ¼`ÅöFÓÀÓcfupê.Œ®øwlCÄnÍÂöKJIi]¨ïšÀÊ&Âðõf£©³½äXPA·ýnÍ1Ú©©©FÛTK·ÎBoI!èÑÓ®…øæZ£ý f°)~‰¹XÞ“h™ÎyŽÆ¾9ú ݨOñC5§¶´¡‡&Ò|´T2«óÖÓ²¶¾ón˜SLB5eD0ºØ:‹³yPÂ;…Ü(ìßwéÓ9m¡¡ÎªnßWhŒÔåÂKŒu¾¬Þ½{Ú`”£wØk“ØùÈÉ +û‘kH¦éÍ>*çÚ²éÈ1ùö£ ¥wÏp5õ´Èê…êQº¶àªÝŒß$Š;¬ÌÛòLvvJ1ƒóf¯›ÔÊ3nž*ÙäøTŠg@oO#9|}•¯ª˜?V0Mù5.‘Û€zÆ{" NÖK?C”_$ PÑ&B̆e>ˆ(q´ªIÁu›‹ò¨`«þ£|oùb|ã_²0l2©WꂝßsCü¦Ü´LT÷Iæa?µf(/+¬ŠP¹Iw‘¸B WÊhÿg°ÌšH ¼»EiÝÅ®´ ®(G6 +¢€®‹¢" À +"(®H2™Ì™™dfrß $ˆxàZEP>ŠÅ£ŠºµúéÖóC¬ÔÇÿáû~ì׋EÎF½:}< ï\{ +š„‚ƒ¢%“àø± rHÐ6N$(ß«Nᷘ_%ó1š¢«ƒÑ]²2Î:$ŸÈÜØoƯ-†8È¥ I-qt;ù'kŠã¾TjJW^Â}ôkÀôŽfQUr\ùuî¦lôƒNkHn᫂æH¾‚÷õ*‰W¶ã¯ø¦˜Æd6™¸M2 *{¶®¼`ÌV%¥…VR£oJJ‰²À÷`+"èyO|s8ÙÎÃñ®6ÅVÌËy8‡ µ:+¿‡˜;ÄÐ9Ýî´ɨÒ=Ú.q“qŸ‚›Ñ=¸ôàÉ¥­ñ¨^ӏöw÷ld¯‹ÞGÁ­å;<¡bShÚ ¨ˆ®(÷ÀÛàŸ±%]Û çªN™}uAܹ² õ`MV󨬵—?gê=ò&¨o:R¼ÉãüÒ(£tWS-{66Cð¢S¥ø ‰«ýšÿ”¤U®ÆÜfoEIã½òhzEœ'ûܜ–¬&úÁQÉ8,Œgÿ]-2tœ×%€ÁF@}S|†èQJĜ¦h&S콧†bor 2wàqò|éoÀÃÈÏØ/À$Û Ĭý7´AÒ£±êŽIÛMXIc>Œf–¹äH^Î2®Ø`•zBÂÈ³Ø ÅžO€*×{M2MoRŽ0øi†¦¸ü:ªTï~%Ë$œ9ED~cÃj<}‰£ð${.œ-ù—+P]cœÐ=VzëÃpwz\SÍ;!?¬ìØC:èGÛF¤ÝòÅI×±¿q‘YÈŞ ݇>;ÕÇ]„‚¶ý†m§SÌ)¼yr½¥ÔEz©_n˕²aI"lµ|säGºŽíð‡öªº®vm§Âßµ¤îØ_7e]Ö­¥>„ÓГýÿUý)i:ÊøD΂ÿGº}±V WÚ5*ßÞ{Úfüà?Ñ +ë(¯ÿ$Ëp\)9D$ZYÙr|§¾öçç(¨4D܁OÊH¶»äʳ ;Ü«òévÛ±j‡xÒLr_rû µµ©;Wi·Ô nV¨|ªRé›üu«ÊdܦÂ;þ@ðÈÑú–ç YÖNþÁl-ÌQôÈïnJ¦úȲ¸cä/øÓðËø14™µÑC:Ã'K£&‡ŒÛ̕BOÝJ{ß´z‘fŒsWñƒÊ|F-§Ùq2˜ì ?Š¯Á}Y[pXdY<\‰ävÃ+ǁM{Á¶i©rš¼8µÌ~í£LJÞ¯´ÇŨ ávlL:ÀÚ ?@Ö¢ÌoÓ[gŒ`¶²}ý>?Ur‹ǛI2¾ËL•k.Æ}GpI8‰QäRV%܂L0/PU³ ûEÕñ ?´É¹TÙÂcÍÛ¼Ûf¢HÓësÖÄ^QMò½C!º¤)Ã$ ‚; Òej¸ íuIy õWïêîË6„ÏÏ#LÜÆMi9ºÄ¦Í±å«æšPœ*ŒøHˆÊ˜…¢FÉgˆ]Ÿm¯¾ßnÝ+|“·ÄX$Z6K'Ú»OñQÔJÊq Üþømì(B~—ljçÀSu‡Z áÅ¥–bhW®ÓP"¹žz@³U’»V±¼JÈ΂\ÿ,<\H»¿Až ö·5’çë¶ÄO¥af΍ÔC75O ¡þ±ó˜UÝ®¸xà7€óÌõªF›õÜ>QöóL‹ª~:Ê¥ÿ#ï]ð[eTSì2»Œ%…Ác• žüÔÆ~EWמgØ9ÌÌiíå÷%¾3W4ފ: }Þ¼0Ä_ÁX|¡¢-ðƣ鵼‡„‚ÿV”u×8H{»àßYêF¸"qĔ-´F95E!L¸èŽ/ŸÈÁ3z„—óLw@éå“"‰œÒF‚Ÿ²Rm¨O´·éQ&õ[Ð#¤ŠÎ¿ö–ZÅO¡î/©xðºË¤Öró~9žT0ä0b³³Ü¬ ò4±ÁPߋbÔ>_nMFY%÷ý<ñip +Ê;R¯xÑðá@ý¤|‹ëŠüqj#ßlºjù?Ape¢Ü[Çۊíx¶{ý +ÑsäHýt-bM—#¢²¥t8fÆÜß5ó}sßcÌÁ0†f0 CcB¤KèRê•mc³EÑíµÕÖk÷ýÿ×¥ÿJH×[ÅۢŚéžãýMOÔa±î†N¥$ʡ˖~ &(Ÿ‹$~çÅ>ø°žü–tÕBM%^i¦Õï3®¢Ï§Ef8UB ô¸ƒà™ß'`-èicIaͨ“ô+°¬ ¹Ø¯Rž€î†§´= Z¨¥Ÿ‡¢È¾ÌèŁÀ=¸5ÑU#ÚÈ5H«îþâRžûå¤>njky/§¥¦Œs6öÑH؃âE oLº†y‹ÙþìCßGØà/¨ñ?QE%Šá‹Fâv¹—MMz)=ZáB.ßçϡƋèÄ/ô¹Â•ûç3¦ùÎíûO¼èˆ8•Ý5&éY¾ÕõŸžKìÕ¬(—STî e‹ÒðŠ¶ZV•Ëð‘x'ôxaVø4ÔËÉ*H®]z~¸h~ £i0d,ÛKëý8ÍäCZyÑ{j¦êCF')’b™|x´…ñNJ>ÇVÞ{½0Ùêeí#|S—¥ÛEì¯1b狛*_…RÚË"÷Ñ–ÆÇ37ÊÝ€ÃBßÛâ“oξìõ(p¶3_<Ý¥%-ãèt±·É« B÷eÐòtßƓ·”px H¥ÿuRuɵ)H?§mü©ð£ãŠæÁf@£IzË͂qrgM_æõ«þDü|Ceû +†ˆÓ¯_–ùw•CՄYK/¼–Ô¨ ä½¨/²“êY0ƒ¼£ý–yŸÕ̸7Í.]Â*ѳ°þÚa Œ!ëd™[ëm ˜9­„Â#{-ô;˜Wà[¡¸Ìï ·›UŽ$‡mb?ciŸ3¸Ø˜s’™Œqê6ÿĂTÀ tùÖ }ù® µdl†¨êÇv¤å­{ÂF©yt/Ù¼Žtú„¤ÇÜÌ°‹‹KŠ™Q8Ü°„ Nº"þ‡½4ÈÊ»ûcü'׸NÏâs6ôÿI½« <ó–fWϚvЕ*§Ò‡ÁT² –ï9á ÔI#Ò{Á ÑÇmVx—@µ. ™åŽ\¹EyT³©}€ÚWå*€fÒ¿S¸Ñµ:'ØÀhP³ofŽ•Ä§/7ÈÞnÛ u‹3Ö­FèüÄËc”åÖȶT—úÍ5멦yòŴѪàý“žLÂÄiÃӔ€¹¤%vÂI‡¾Gæ —ɒ3îm?PH-k« ©;?ÉvÒbkk€ôãՉy“Œ^ýÃ4o B[Ž*‚BoÁ¡åR 9¨§Þ^Fñtþb¼Iyd¯’š¨W›™$ګږ¼ÆNãêT3óVYzl ((ñmƒ‰"Uïa.\˜vzŒëCˆ5H8Hó$?sZŠ6Žœ¢=:ÈhhêB…!É8 +`,ä g6ô$cNúŠæ!LÄp©<Šb<ïÀ™Nz;¶0y%€ )°è"Î «DÜB@Ž ;€.aÿÒ$G=ØW+²ØïØvÑFöv-­‹ý…Ý|d%ºŠÝ¿ÇîgOŨÐÔ;$KF“»î²lbšu#«^$(ŸbÕ ¥‚,‡ ”jdMð[sÃÙkx÷vÿ͆¹ïc–³?sÝB–¡fl¶S ¥ÿkø€ ªMe͈Ly˜i’Ã3òTZuøgÖvñàî#¬áøV'{ÿFð,ºË8+„5Žå%\©ŸÑY`kY o¾­ÙC¾ˆ,VQÕ"˜B½k”5WjؚÃê aëx·­ÐhÝkË"è© ÕA³Æ›Ü/ðŠŠd˜XöÃ!xJ±ë(}¶~ÏÚ&¹|–ÊÿËé íh‰®?í·¾Ò.„òê¸ñøÿÁXSàªçÕýqX×}|Ö#CiÁchÙK™ÈVF @ d’·w^ÞËNH L +jkÅuÖjµ­³ˆV´JE)ž­£Çý¿swmºü^ ´«VQe¢’^*ð…¡7”cô¸·Su›5Ô.›:’Õ5!{3°A/—ýu@vÉ?êaD§åUNCþkùŒH2)ú 1¡z%­9ì­U鱛ý»éÐÊçvò¹°—Ë!ÆkšÕ0>][#À?¬wÏsb‚÷Ä,4U²á¤_ fà)…ýEêďÛ* uä6Go7°6ɵêèù¦{¹¿ Èæ'C¶É‚Ga‡â+Á¯ðRUõA=±@ù¾5_ªrgs1OU¸ŠGÿ£*ŠƒÊšëO¨&øÂQÍ¡Á4ÒÜ%¸¥©×€°nl¡c=ú%Z¨ ÷v¥Y ÿZe‚ëਝ4í‹? eC‹ƒÁ—`…àØ Þ_‚ªÙwvĦ10áKÌB/§ê*BrâvÎ4όwMèñ  0ù›à¸rë“ ó³–`ø¤ñ$½Ðï’÷C‘ܝŠGàa6;g-N_&É° .` ¸`ß0üØùM/s\¢Pœ’MƒfóªŠ`p‰¾3ÛìåÖÆå $‚ˆA7° iÚç —î¬c±û(y <ÓNÉâÀù·ò6¶ôe/ü ëcÿPOj± mê+”YЪCËzÏÂXa-…¶T‘Ñ`ao¦t°tÜ._ ,qgõªO˜ïÄöªI]@«f"µ ´?4|T¹]ÿT7[úr¾5+í¬D4UffNÕ]Ϭ¦ç‹'¢Md’dõæù¸YÚã%A'-í:›x–>œj˜‡”±Ó Æ5!’U¥iMSDÆ-rBŠFL„É&¿ÁÚÍ^:O•ãò…F¯-TüÆ4Šw ³è÷ÊèÒõT©²3c q]µ2ªRÙôdó/3²µùU›\;?åãØUp=ÔÀÔ@Óbê +TYRJ¦€3éÝøO )*+sWÀu¯.˜ê[ìL6—Ǽ§ÝAš. Ç귒ßhñ‘‚oN_…=Cÿˆ|€òHW  Gz}ýžw\ÒÜ2Œh{?ÝUàÅr_סä,[<§™¼4ÛDmˆD‘ø〷ðòú’C/ÍFÇlö MÙr_ò‘¹¾ög"ÇP\T‹MñIiÿD­¬wä$™ú=` öÆI¯Ó ü§}ÓßíÆ6Ò.íÃjYîx^›†ÿh}]ø¶Ûø"µ]Ëßÿl +¾«8"ӽ΃ǐ«öLúÁ¥ì"êHï”ڝü°k›è:^֖T¢Ïm©©éÈÆøÏ·.À‰©^—@1Š~qxT¼ÅÇlùUä¾æóÕ#U7‘¢Öü5º:ÓöLÎE|4â™&W2Ëÿ5e•¶xzãß*̖̆;õŸâÙÖMâ0™ÕdoØ^•lpm¬ÍëâaIòSö7©kD#Óùß'͊$Ï"lL­?båA˜ÑüDI§¹ò«•NÝmEhž —«8‘¬ÔŒ*ó"vÒ±ªEþßýª»ž¶ ù݌5Zž5‡¤‹ ¾`zÅ~xŸ[«MN&Ïaî|Äbª(÷Âǁ$Ïch¤ ±øãè|cq«)Mï‹_¨ðá¾Æ†w>bSО$ ýé ¿Dòp«¾ÒzŽ!G@o3ÇñƒÈÃÜÉa]PnÑN2);K4 U•´ö"¨p+q ëð7bÒáùùÒóËLíÖø…a“y¡$‚04”»iCøc9“Ì(û6ñ>E3aá{ˆ R䏡ï0`Ý?às0Âí7y9'`LÔq·ñ`SîécLr&MŸˆP.Ú½áü,ýÒ_†rÄÚu°ÙÁå/÷FÀõ»º°Æ=܏ÎÄ=1ltËŜ ô¸9>1Šlם +›ÁKX_ÿt+ ¬ €=‘çÐ#¬Ø«Líø³ +u¶uWçKìñ¢Ø̹– u)±F£@Œ†´ó»ïû…jÔRÎý_$ Ð®ÝYuBśöGõbQl+$Ö»·,o8“qÜl¸Åègš!) ÷ÛÁˆnî2QùãήÒßUÎ>YtÍwŽ(Ùþ¢^ëù'Y¦ÝòÑغŸ!…Ú %à—GËU¸û9¼·ù¾¼ã, ¿Ô&>¨YcwU­± ¨Mé÷Éj"æÿ“Zòo6VÝéWF9Õ=æa“Àl mÄyù–Ö¬¿šnqA/2æAäIºÌŠ¬Žiâþï +qÑÔAN?!9NxlÅbÀO°¹Î{ìeÙi‡Y“Q½Ì¶>S¸Òô€ZŸîª‡ .&ŒsÃÞ¿búÑj?1_ñ¡Ç¡P´Ãékœåٟè¿°x²`дY»!í¸n”ù6f®VJ•?ffãoýš‰n”ð0¡‰°šÒ6l¿)ó±7ØB¹u‰yMAƒÑ¢˜&×mæ>>ÃNjÔÁ#4J%ûÄ&|žÇòE]ۊ:íÒiû2g¢0ÀÒio*ð6zXŠÓÂø†¬h +æ҂÷Ò3;üšñ1"Æã2ҍÔ+Oô?©ˆ¨Kܳja½÷´ðÿú÷èY|£‚nßMHŸpüA/šLsI5§•cu¿*ΐDx„!W‹ {|m¯pq%ªØqeh¦rÁYb¢Bt M7»uA-™ +w%5»”,xë+ zî!Ί}|%­¿w¬pÈ©™xe¥Xx|Y üy$Mœ}yòA—Üzè5À“{ù+=Ž}5"6‰~‹{άq~„p^¨Q~Md¨¤~*XŸÄ~,L¹›U~S@é–Æ~“5½’ ~å+f2T"ˆPÒ{p«U…Ip§<„ŠdG£ƒÓX]ž¶ƒ'LzšJ‚˜@À•Ï‚5·‘)¬+‡ŒgI"ۇ¥€ó{ª~Œo³¦eŠ¾cþ¢,‰dXØˆ L;™o†»@¡”ò…}5³^„E+£‹¶ƒ#‡ízЩג–oy¥»ÃcÆ¡zŽÁWܝŒ­L˜»Š£@ƒ”Eˆ¢5·¬†¥+½‹„¦#N†¡‚ÁzŸ©O˜ïoK¥/–Šc“ è“ÝW©œˆ‘ K՘$ŽB@W“¼‹|5¨%ˆÀ+׊œ†#x†Aƒqzt¨ùŸ&oM¤Éœ9c l˜ÇWŽ›ò•Kׂ‘‚@V“Ž5³Ž¨Š‘+éŠ@‡)#š…õ„q¹£hÜf«µj’[Å°1lmPʪÿnpEÐ¥ip¢; Ÿs 0ò™Xuœ'£’éxzŒr{‡qD¸äo×f«´pÈ[Ô¯qñP䩪sNEñ¤tã;=ž%v¬15˜x™( +‘®zÄ W‹W} q(·¢vsf€²ÊvÉ[º­°wLP̨OxE뢳y +;NœÞz11c–Ò{v(_•|è ׊b~mq¶C|ÏfL±o|¢[y¬[|™P£§|ÃEÒ¡t};O›²}›1…•¼~/(¦~ä!E‰§pÞµƒf&°B‚p[Q«/àPt¥ÛgEÁ S;Pš¦€è1£”Æ€Ã(ãŽÄ€·!£ˆÞ€ºp¸´,‰Rf¯Oˆ6[Bª5‡Pc¤á…õE°Ÿ`„ð;U™·„1¾“ëƒ*)Ž‚^!ðˆH§p—³y`f ®‹È[>©fŒ P[¤ŠAE©ž—ˆŒ;Z˜ø†é1ٓ0…U)FjƒÒ"0‡Î‚op~²õ•7f ­ð“![B¨¼ÀPY£_ŽEEŸé‹Ü;T˜\‰…1撠‡C)kŒç…"d‡jƒpm²–šÙf­r˜=[M¨,•1P\¢Ç‘üE£SŽÜ;`—ЋÔ1ð’'ˆå)}Œ„†"‡ƒ›Î¡mfú»ènìi=¨µp­kq”êr^mœ€µtoÎlVuÚrX w¿tDyßw'0É|Yz>̾j´qźjlÁrä§`n­t“¾p‹u0¤rnvgkbtgw³WIv~yCtxÏz›0b{x|bÊùh§|~¸´jÒ|¥èlä|’^næ|¶~ppò|ój\s}AVtu[}–B×wÚ}û0z¬~lÉ;fׇ ¶øi† +¤9kD…ëmh„5})oœƒviNqꂿU¥tX‚BEvÿ=/·y÷€VǧeP‘{µqg¦‹¢¶i卞|l‹»{õno‰èhLpãˆ(Tâsu†SAÁv@„Z/ryX‚Æ_d›Ö´2f}™¡}hƖŽMk“/zámtLgdoþjT3r²ŠxAKuœ‡I/8xσ´Å[c&¦³5e¢[ }gܞrQj.šxyýl¥–†f¥oD’ˆSŸr Žd@êu‰þ/x\…ębp° ²vdÜ«Ÿ²g%¦”Œ€iw¡„y3køœyeøn¬—bSq‰’@—t Œo.àwý†UÄa÷¹ë±ôd`´RŸfŸ®W‹Øhè¨-x‘kk¢emn)›ÐR§q•\@?t@ŽŒ.Àw°‡ZÀ‚tÿf4¯uþh¦åvÿjõ‹xxm0xŠyosekz.qÐR|{itP?Ä|Öw-Ó~zK¿'rÈp{®sÿqԜãu#sŠ„vFtgw£wtu½dx¾w*QÏz%x®?E{Äzb-Ž}¯|X½¯pÑzŸ¬êr'zò›ssj{@‰(t¯{™vxv|c£wy|Qy +}>ºzÓ}œ-R|ä~H¼(o„™«Yp‚ƒþ™éq݃^‡Ûs=‚ÁuPtº‚;b°vS¼PPx <>Ayû€¶-|0€º»mŸŽ{©øo˜p‹‹z†r‰èt?s“ˆ^aÌuQ†âO¦w+…T=Ôy>ƒ¨,ï{“Â¹’lu˜S¨Ômü–—oou“†…{púùsGr Žlatq‹ÝOvk‰?=tx†j,É{ ƒ@¸¦kˆ¢ §èmžÜ–‚n’›l„–p—ÝrxqؔM`Ws¼¯N“uȌï=&xˆñ,©z„·÷j׫˜§4lg§ˆ•ÁmᣃÔomž‚q¿q0™å_¹s*•9N uI_<âw¥‹6,z@…¯·†ja´è¦³kí¯í•)m\ª|ƒ2nà¤Ïq)p¥Ÿ _|2s§o„|­u]Ê}@v¬LO}êxT;"~Âz-*æÕ|L°œy(xá¡*y«yr‘ z$yù ÖgWT€aË¢¨Ä®kTd@D\dPPp-HGÀ„&]¤30Àô¹½ß;s§Cg(†  1DE²*nº6ܵaïzê*«&šå<ŸÞ//6è± ¤O?ƒýQ}Ð0$ 8 _„·{¡Žˆ[w¨ ¢/«¾!f›UmxrIŒWBø”´5À(Öµ¼Š)2 ØÏ.$½Ý5U±o¶}Zƒ!O¹O“·ªæq‹‹mªÇÌõÔ õº>’>P‰3 ­Ä¸g| ú,ûXñ¦“ÿ`£ÏS$š>BG”‹ çDǕu†”#êiÚï#§þ܌-ý`­óœxJâò!wÙûÊúم:‘Î(‡«‹ÁŠ`[HÑW¥¿eQÊ2U‚áFDƒº‚‡¶`à|ö™§:CÍèd¥õŽ2Á~Tv­±Êkêè¢dEeUb2¯Ì½…èp ʠÿ†¶£½~íè[ô‡Ë@›šQd€³F!•œ7•ŒHÙÙ$‰ÌùŒäÐÑ Žˆ…Ú#—Èd¿Ltæ!BOáKš*áŸÌG-i°ÙäC–ÃrƒBú.ÒUålmO¼>Æ †,Bæ2Wü<+Õ3¡6¹7¡›µß›íÐ@µÑ ´)¤Û &KO¶ 0ޏûÏÔOþ igmúŠ82=DÈ É4FB[†ÌÓ!AãIb4½~—¤ü£Z—í *†â¤fz\½ÕOÚt®æF&”ˆíÏÁӝN&3xôàFÜê[®H–jûŠýz°¹&3n14µÂ¼böMá ­zB¹Ð!Õ Ÿœ|‡®+¿å +/—hw{ìûV³\lÞs—ýT¾jçgæ?қ¾ú¼â©ÛŸÔu «ê¹®¨D­}û”.ƒ5ïʺÄ(wM’ °ýÒ±=ÉL·üÄÎjúe³o(u\ý›» yÚPµXû³üžæƒÆ¢8ùp2¥¶¤©23Î2"uhì0 Á;ý(3˜àû-ybÝ·‘3àÑÊÕWd÷‰sFÂ@wÖ É,¾É8#åóè¿!ÆØH*9¾ã)iF^ +¿P7÷½DšgÛÄ3Iœ33D_Âè«ôºâ)ÔJœQNdOÌm2‘tØa':‰=ÂûÄJÜê.ÆÛ±¡ +sÞ`d³é+úuu—-Š ǵ‰i—ȵ\L +±kw„á/iƒð®&GÜ1|91É:Hÿ^ÙÈ£gWü¢ú@-µEí¤¯ifš?Q®·F?Â/óKvüßř„MØkzÔ݈uNÖ0:ӎ3BJ]÷PU@âÕ׊VV’z±¸D‹ñPCÿöãØ9>R¨ÅTl‡{=EŽY^ScíôyjNËå9Ûþ¿Â6b~mwj[™íŠ Zl'±d}¯°[¡YïގM¢:tU9‡±—óWI“-#…dî=ÓsÑ£½S ¯ÄI‘KuÊÆ·6i/JO{×sýŠ{®˜c@6o°©ŠP³U,Þ'9cV–~ÉM6²åíI½Qš1ÀWÉwoÍ×T+ã¼ml³ºF0‡î…\´O­·d­È?Ío䉳iº¢4çÁM™•4M·C%ŠHÑf©M[×r0pÑ[Ï€„‚pê|R»Â’¥Ã/Ld/_c8]Ï׍Àó ùYpFøKM(ÜøŒEwoŒ@Újjê£I0/¢¦Àkad[™H’>Ùþ|/ѓðLóŽð §¹|0ð0S‡ïõVRŸ±×‚V2C¸Ã¦¹üaˆÑv”é4x«ö,'LÈÓ82Ã'ú7âô¿&n­„Š&CÄ¿ñÎÍf]9é-f]i{Ÿè‹ÌT÷¾¤¦à×aéÎ4EeNٟ±¯¬¨äή"“VöÐ_ªÇ”3½Úµtõf6š‡ú5¥ÙÒ·µ¤,®  jP“úÑ6E‘«±x)ͻ֣UüSu©@Œ×6M6ødµŽ‘Àõˆ½®¨“FÔÌþ›ÏV€»SˬGÀÞØŦwÐÆ û†uÐyÿ@>.õŠåTȆÕ×éVäOdj­?#驺syc¶¿ãA)w,zl<æ¨ñÿþ÷ـ»B–*€7Ši€j,\‡©€P#„õ€;}}™~ˆÝr4–ñˆfx”O‡"Zh‘ †NMŽð…BeŒ@„(7‰—ƒ8,i†õ‚A#F„aN}˜®Îqǖ*Žlf “‰ŒÍZÛ‹ MõŽ2‰HB-‹Œ‡†7ˆß…Ç,y†Yƒý#pƒç‚9|½˜–•q—•ž”¨eےï’NYƐ*µMº}"AîŠíŠ˜6؈Uˆ,€…Û…#’ƒ„‚ý||—´(qW•,š¦e•’s—ŒY¦”!MŒö¾ANJje6ÇâŠ,…}†Ã#®ƒ5ƒtë©PcèjO¥ãf=_`¢rh¡TžÐkH¹šîm¾=o–Ùp2¾’ŸsŒ(ÀŽHvÙ "‰øzbtu¨5k#j¤¸lº_-¡$nnSÿjpDH©™ƒrB=t•ytn2ݑOv½)yL žˆÛ|t¦¼riŸ£Is ^ٟµtS±›ýuSHt˜#v­=_”.x02ëyÎ)B‹ö{›! +‡â}~s¬¥Ùt(‚o.wþº]^”«©©`c’—˜CcHl†Vf+Ž;t)i0Œaèld‰çOþȯµ>tsw…[-òwn‚¿¹w\-ž¦¨®_A›®—Mb0˜‰…ke#•SsShA’!a7k‘ŽçO|o‹’>#rሠ-Ðvö„0¸±[D¨n§ð^a¤Œ–‹aS h„ªdLœ%r›g{—ç`˜j哟On‚-=ÜrfŠv-µv’…m¸3Z¤±ê§p]­ •û`®§Ü„c¤¢r f؝C` jR—ëNŸn’b=‘qþŒŽ-ŸvB†wµ~o®`^¥£q&cc•rfBƒÇti qõu£kÚ_ôwInÅN1yqØ<¸{u8,-}py´mjy¤”nÎlp”ptnR‚Þrp/qsÏr_;u¨tMžw§v2€ãû>ƒŸ@?ÈnÀíòC)…HKс#èEu·ä$þ%à펭û¡`^>[» +ø(?`~¤^xúÍ0¬¬ÈÏ_©+“OË´§v&"YÀ˜DŠ>sÝ5x'²±]¢¹£«~¨Ð-ç€iÀfð¡~…>NF" P²ØžÙñ^O—ÌGî# » ëǖ´ªî ëª0Í<”7íӆ 7 :sÊÓÃXL’‡!kݱrÂÄçá×x{6ÜR¦tå"+·¨@ö‰q£ú*§7k—1Ç÷U誘Y‰}(­Ù~\HÝë`J䞂æ“à·\áµâ¼ +±ÒÓþ5ç£2[{Fõ;‹On·–çÛúÝ¦Ûà *Cæª{2H<¡è¬N-ßS´º2ÍUråÓu÷UKm¹³5ųBuœ• +}£·ñÏÄ3À!ãJ÷H$‡œ#h^Qv¾0ªqÓUô·ºY:‘Ê«ªa¯Z=V.ˆ¿ }VÒZ¦Ÿfsôy îå½ÝÃÖ§¹MîßÑP¬8Û:Æx-kîÕ¶(+’rÞ©ãªGãSµIå²Ð­€¥øºO ø¹ùw÷ðiιþ9јy»¸—€³Ÿ’—&÷†z8,kÊ.$†äxì=rmRMêï¼ÎRŽ€Øíu×Mb;d—íw0yÁ â2Ö¤˜Tý{¢œ¾§—¨WƊñ6m|ˆ+±8êEC`ð òGd]íÄMm²µ"ˆæWürS禜D¿ò²~AêÿSƒ‹‚»° ¨Ä+ïG6W#èÿjnA>p€ÕuÂw0ì‚D(ÃMHOÖB$õ™ŽüŽvKÑ»X¬—{Š½®'VáíÕ' 5ôc + +èshø]T4ÚIÏÌ ƒÿDµG§Ã£TDÐ(2BNlz9“eB_ Ý«.ë#­J³UÿÒbGŽ³ºÐôà¿É°€Œ¯¢ú¡ îPÌc36õ ûè߅!Ø3Š¬ü•?ào/Ë¼á ½¥4Ta1l-vKWZ§¢’¡õæAÁpšÉ¾©éã<„˜‚>\©Ð©æðހkía8¸Z5$¯GÊï§çd¥W#‡À{{à¨ß¢ßÄ! ¦eÂ8l&ÓVé¨lu4õèʚ‡ @Ô¸Q®žÔú¥½×÷WJ"­àçû׆Ò쎛’àÿò…)è9(©6gf ¦yÙ'ô¼1?·Jöî¡L)­ábåÉ¡ì­¢ü­©l’º]4ÂLþkۘëPpñuîï²¹ô)nCA ÐŶ+2d‹ØõEHÊ'æœêHøm&Y3¹uó õÑ·ÁÕkïѽˆ‹ýÓ­Š¡Ž1‰ênÝ]ú_Z—<Ú®£Rvӛ‰ðpjÊm9G݂–Š¾§®À#j}d£ÆAù-uÚ í¡¢¡û +¨0”\C"‚°ÉdhK>م¶‹ÈŒ©Ù¸Æ:IF“qž\BVhFˆ'$—[Iœ&3’—äæ°B¢™tÙâK\ DåÄ'â`;™I [¿"–ð%„#þÖôNã‡÷š\÷¾ÀëI +|?·a×ü8+ñş3"-AûöשÕ_ZZ„K±O%u6`·îÄÎX{cçͯw1Ø ÞÙÿ$¾Ñè+ÊÁO±M{›'±øšEØ],¸j¹z6¶¸¼+§ý°~¢ ›Qœ½k a=â_ˆµò/E ¸—q¦ÀŒ¿bVškÐÞ&S ß7füg\"Å&]ÐÇKOÑ:´ %ije¿B>ä%¼à™j†:l=®ºT1e~ ª/ðߪg¸ ‹”ƒI0^YÕV) <õ^Åϑë% +·Õ¦ÕQS-WõÓGpaθDû8¥ß 9•D֑ՃðXM'Ð +ÕóUÊÈJ•]Iå"­—mtª¿euuE²)ÓÌ-3`ŒÒŒù SoOŠÓÕýŸ£™«™‚6Ju@$¨Z­ZÏùǚ᧌š;œþåoŒÃö–üúaëõm>݄92)@m¯{«Öêþ†¶¡š‘»”>Õ-ÆV³|¥°³— À•´WUæ>rß$Ó²]ªqّ¸ÿÆz–EYuɔÅÛ>üGT@蚩©\Þ'ßÇ}њGÊý¡9¤mp.d.@L4c&,·”r;b ӂãá îdýlúÚÎÍt3Ñݦ©]Q<äbžÌ-w °ô©ŸNÂkÃð” kÍ búKâ%áï´ÃíH»„“@ j™à"ŠW4ñ²sfœ‘|Aêa{¨à8Âc%ŠJ@bœ W’Õ\“þEÛÔæ':EhsÓřØ=®}âó9fǹú¼T¾ÍWÿ !3ߔô% פԘÝ]YzĀ&XIkWdPÍيØb§]±9g‹ý bIêëiù ¢Æä“Ï$ õOþ1wu_)¾‰xª®S$Pî)m/þUI Ã.mÔpsf5œUwl}oyøhÓ 4á;=DUóIKSž€DSÊjŒj:?è2ž*w¼0P²Ï4‚¿oýŧ+G„Ë4O6‚jµeu˜æ ÙH”W)ϛ=öƒøݮȆŒ¢sœ51û  oº½ÕkæܨaÈIÈӽ֒WoÐ0Õ%>­ª#}?Vþ5NÚÏÁ_ÏÛØû r}¹ë%é7¥­ +ßÔ¼‚Ñ{Ä!`åD}°üÂK_á4ˆ +‰!ƒ¶ªQ\üîHÒ½¼ÏzȔôHçNÚ>«uA-^á²°²bg¦¹%+kÌ5‚ž°8ýWâ #ýwi+‹¯öqéÇ0ÞîŸk…hcûuTT™[ÀÖÁÎ`î5ØZ[›`ËJ¯ &º¶œ-áêvÍ**–öcs0”®Î:¿-Š7•Øôo‡3G„(ÖZ!žd ©¡ ‘z Q}v°x“'EÁ¬éð}èà–aQ#*ÚÕ'–Áévi½Æ·|'iÞnˆ’Ž…˵Y²çø;½eR{ñ‚îEÒ1ÌÜv–ôiúk·Y¶èTË2Ἂ¬æ4o—/Šõ;äªðKšù |O cÿê +Rr_´ñT—Ó'›Uät£Kyγ•zØa“L™= z”s#k–)Æð|O¿ŠèĀŠÜ‡­ý:aúxÓim&ò™ã¼&^c½®†ÂŽoIѓ` +‘¦îWÊñ8Ï2K/ÖױϬ˽ßòŸñ^º¯i©ÁùÊáp‘u£€óÔO£ßè:JD­:WtG±Š<Ü8YJ] + ՄÑy¬iZPí-|xm«4×Är¦Qe¼`þdZ´H ;4°SÉìí¹X1̚å`¯±wªŠªŸp¼u>Ê7¢ Hô²2ìã%¡C‚d>«zES³?«É+éæ&ÓÎeð{™\ÄQ>‡Ý+)ú ”^T9ZîPàäåF­ê†ëü«‰ðV+ú@Á£¸Š®l@ A ˆŠB„ +r‡3„„“L2÷$“™$ €x ¸¨ë‚Õ*,^-àÚ·[]ëù<**è–R®ÚíßðýôIˆnpdkŸ ŻΫ ‘:ÈÃà„£©‰Cö‚û­ÆÐâ>ÛKXi­õ<¼_ŒTTŠ‡¤Õ–¼¬qùcsØ.žJmZ¹E›ÂŒ¨„Æ:ó^΄¢œúhsVIbm8tS”äX&^ a*Ɋ‘ÍÚnð^Ým‘îšãæ=A2äs§ó^»mICca|k‘é°`‡K±…{©"YÙ¡:nf¿,Ú±šW xØ_n~  ª¨ +!fÓ睥üÜ#ƒ ÞäA¶É§oÖ(u´ +gį›Vg攷ÔÏçE)Õ?nî/Ø  bd£éSûu3ßQ·¼Q¸–ùI»B`×\áC!ž’ÄdÑ +ÙPÜ,ÎÀˆ2QC³—ë[PŸ¶å‘Ò»µnª`±žRŸ”ºƒ£šXYUé^í”Ò'ý,|Y5G 4-}Ä<¸Ÿí«kÀC÷ûÈfގoÊۆ3¨²«¯«7‚á%ÍRÍëôå/4ç…ä!=öa¯'‘mý»´fUgÉLˆ•¬(CfU]@::& Ô +¬wo²¦ß¿“ÙD[D$ú”<ÏÞHÜ×½k”¨ÕUÞÒ*Iï#;He6Åi*µø80C¥¤ÕTÎN/h%ø u£hvLµ5'‹Æ­s*=%s+Ä:V9˲OÙ%ç›û‹ž(LWӖ¨sÏwœÐn0~~ I`¼ÙÛñFÚÛ嵃v®¸¿&“äK^U÷*^Ê6U>,ŠVœµ{¦:T5zG‰Fd„Ÿ„šìx|“×4ZšÙ²ÅÖ êuÍ'úʦœ¤"¥œWw±°[þ°f^ª'0X·cxÕ…×Àþšˆ2ª›rKìJÛJáD»Œà”·¾“Jm®äB®|CÁ=ç€55oc/ƒ¼ªàðhÐÏNÁŠL9õ'0ßjIÁî.ÆÖᔑÑÂëùÿ =$!_û3²sÛ^è>pX0µ]SÐc¸„†Ô¹`giœ9ˆ¦Q?”+©,OÄ|ekòÞákC)6b«ŠÞf!),ÌM÷î§úð¯jQ­›ì‰ÉZ¬FÖÀ_û¤Y[-Éۈfiv&¿ÃþmÞHø!‰¡ÏÈÿ`5oõ—I¯šxu¿d€“P#ôF» +î”P&ÒÍÇàÓh_2ˆnÁnm½‡MsC¯?’™¬…ºÿê¾wøƒäÏôOêºtí[P¢k+Ój®ènæöA ú»Ç¹ú”­úHßځÏê§Yº*£zÒל`˜L﵋TL˜ø0ïäü®ý³1|w:4Å4oý™¡¥ð(ºÅ%úªøò±jҨ̨5YÀJ_ÑÿÔ|ÛÑ©f¥•ôò´y†l0û‡Ê0—±š•DúÓO+/Ê.5ÂT­"»á$8¨¼[g)T`MHö³?ŒÆ“”Ú\»fިÕyL/Ø\ZÌüŸáúðjò@Ν(­WÚ¢u”Ó‚d>ÂP"Y’d'$„$ßʗïËì©V¬J+W·>pG‹ž[„ç^ˆºGÚ»ßñãªß2|M 5òòkÚci{‘ÝZJb«»ILF<†fB>òP­óCº­R7<]'äwÂçõ‹KÖÍúÜQXb¦Ãã*Š +Öÿ$f»‡~ ^¬Í„:¡)É]È•}‚pèæA(žŸ+…R ©´X¨zE©‚ÌÐ;b1tš!‚óá9ÚÝ ÈB”jü`™ dã>› Àµ!×L7g¥Þåh%³ÆëÒ7n·ׅ¬§á ô_Qg1ÃR2Ǽĸ:@“nè\ÖKžXù¦å°Ÿ)Â'€WIØC0hݤù!XL}†¾»É4œ‰l5É Vh2–°,ú–?ƒžbLb#(sÀyÌtk]:ibP _"ÏÈ2S&‚FþŒ ߆*:Ü/~‰·Ù5ülÒ6ÄÄþfÝ»¡ ²¯Ó óð¯©vÍô(l1‘Êïu’™;8ãíŸqžµ·ŒóÒi¿7mœL[Ú@¨ÅWxlâäg™ÑñË íY<€#nMDý«yYùZOÃEÑXê;/C<_í•IfG‰ªuÛúR›äÄOè…M­++cØ7šS«ò +4ƊaZ²÷é­ÔƒîŠœøÍÎuª¤í¶ Mߊ]–>]o°¶ÓÐ/ôm^&=ÂNh̕.®g*>d_ò$«¥ +]ókÜñßÙoj-¤½Ö]ºŽwðzýí`ùg`¹@ÝXRËê¯ïÖÐèžSZ^6Ãu¸VŸîø^×ïo«×ÿÔg±„~X—ñQðô Èæ¿®¡ïa%{s Tú·Æp4{®³ÖHLydWû)YUÀ&R?îçFDš/€'ƒgÑHÅ7yOÃÌG +âS0᪄ïg :¤poÊ›)·-.XF:€eÙæ¸*diÌåG{.㯙nwn.ètº±ÓY€½Í<’"³þ`ö¡ôâ7ÑdÒìsSC„»!¦x$¼ì©g‰ó:SîÚíøX9ÛÍY¶»Öá•å‰%r_‚']4KÌÊ ‡. q cÈYvã.㏢‚MrÎÓm½ÜúŒìÎ*ADbW냊ä•M1âDq½by¡Ô9 ¾þm­T'bu÷q…7¶Oñƒr€®÷Âé ßö}¢y‰XKˆ8‹œÜ`”ŠÚå¾®â.;²´ÔÀ«¿~1Kü}wù¡ÂÒ­³•ÏrB;ªҏ¶Þ’ &–6 åRrº÷*?jÄÅÒ䆑luµgðICkþ¶ñMú»|¥Úþv²œ®hùZY˜Hn8£V’×zšƒQ3N?Ý?ÃôÖ«zGPöÖø‘ÙÓ5¬|Noî(RGÐJ[Ý5ªô°&Hs)qq}^í&2Õý•n:z¹ý®þÇ°–kFmPÆ03;7ÕNÑsÛÞèi+ZêŒiӍ±úµ Ó^Ãòzçsã7ÑTÛm ,ì þŒzb–@Æûp…¾°õ2¸2{¦9¤§6„‚Ê„ûž/À=ä Ç4ø)šcýñ x +t&8…3µ¯Bõã-ã(;û^S‚éeÚÙúdSyÂ7yG^íH@¶Es­¹7<ëA–³Q|•áh“[ß\j‰²–eÿÚZŠÒŽy1|iÂ-—ÞM»']£ý‚š¦|§k!¾¨õ3h{ß&«Õm¹›5&[K¨iªƒK%Ú}UEüÞÚk̀Êåu hTñô[Ÿ*îF‰÷´kkOÆÆZ £e¸è ³œe€v]G ‰Ø¼;ÀG­¼LÉÞWݺ[ä“àñº…d;oä‡àošô3xòÿ‚°¦ÀêY{OEk[@Œ|lÄ‚2„€ì„ý²^ò’¼—÷òF6a ò¹9«uUQ[¨EÎmË'*u€WA¨»ä³wÿï:^WfA×w:¨Ržcºè $DZ9-Ná±7¬É×~c +» +?µí;”A¯34VfO× –ý–ßæ 5âœÄ*DvƒÿUe_ÑRqr…_ê°ü¨«pMv–‡]€ö½{ûқ[;¶õfÕ4¯( Ìc5ڑGìùõ÷d›xþµ±…»EÒjOª˜®ü-n +|⚠ë†g8žî KƒöٶŲˆ]ï{r3ÚJ¨(°ù?Ò±’µq…lá÷u;S7¢êÇqWA}ÅÇ°³†ÃÎé=·Åo +¢nÉœxgº|ŒGCT˜pŽT§aHžìÓ͗O¥0áU`llÚ¤»Cçltîî0Ájþhý~±¯pÚ±Yú_é,xü'ù,ÉIU·jnÁ\Í[Møæ z©ÎóÆÈDBéb<Ô¾Ó]ò«ÜT7S0CùoÛ}ñ2õ%ýsÙF͘¸MQ«óÏ ś¡!¤7füSѕ&.!m›àôéFk´¼õ†(+OÐ ãºóâOȏ¢í@ ê•Wª1ù¦f­ÙôG Û0J¸èZ¬’âî-#¢=¾ÅýÄqËb>@@Ñg¤IxFzŸ|˜û½âÅÞ´\“E=ˆY®g6ÒatÀÒº*ÿ¡SYõŒÝçô5û—T9vh÷ øŽ Æ%2{}n€ü´}Iò90Ýv zRf‹¢›Ð8kOËʼ™¨jV‘oõ:*¡xÚýH3Ê_ 6ˆWWxç4Ç\;“5juÙêèK:«ã:iì²7‹rʶ‡»YAd§«~XÃâõ×:J1<Œœ¥²;îäeªî +(ú;èMÙsºÅÈrlÚªÜU[y5ÿ»¶ýävw‹(k +-Í×Olí—ÖHº«¢WeG㐣ü݆L9s›¸ªè‚ŠFp6§ i&xëÁÙИp0üC2}ÉTxmÌCûÀôH#îѽZy—Ú‡†m{ìç+ËEŠAaî­ö‘ìWÏÓd¼V¨Sy%Ûې®™8bôש"SLL„¶òé1å4Ø$BsùÈ&±¿Bµ—j±ê±&©d@ãÜYˆÒ?O¬€+82}­£ù-D^½—†„ÎݒDÝÚ(ûËP¤˜Rœ„{¹ÔÑ¬.íús¢!Ê$Š˜4Žá´PüêÛÚ£ü§¦o\á„iÒ(“ÜÆëä#Àu"„»Dùž8Ï +Ф:¡]ïC­Œ¸€¼¥>Ð6àÞæášÚ’‹¶ÇöÜÒ׶û*ö±‘ûÈÂm@1GQm ÊlìOrus¬g#ö tk-Û¤²ò<‡Šÿv+lŸUÙw +]õ@‘äV9È9'ç¹Ò3Õ«Êè ¡Pç?#Ü0eDãaã¶ÃÕSœº†#Ö[%ëÀó™µLYŸø”‡Æ‰U‡U•_n¸¢¥ÊFÀ†η4FÙ/V[ØäŽ&+‡;Õk¨+å4e[D7\ì~YCm[†D¹¯úÄ·æÏÊó»ë4MÑn/ýé«9Ó0ÌÑéÆ:/[Òo¬¥`ŸK½Ó˜Ž(Öá +™ƒT™Þo…Ír M­8«ÍæFECw…LhT¯–l¿…ç¢ÂíÈ ¥;=í×ÑL×t¹Ì^r%´¢Ë|ÊTXN©£dñR3O>¢Ö«Ä^º°¹àž¡Gû)­ y®·¯ýۂ„2ãbþ+žPgˆDWŒB¤Á;TäÑ+ô4Q”v—¡§€¡{ˆ§…À9è¼µ;Œ¯°!f»é6~/ė|@Ír~’½EÃMíŠ$,<ª²`ÿ2Á‹¦+ù´oM­Ò¿$ȵkë¤†éÄÆ)<$‚\nnu|”LXìÀ·´«¯+z-]‰:Ör"ï‚æ®åXꗺ.KWü;øªå–YFC² Ê:ÃAǔ+ÐIéU× u€œåŠ+íU>.+͋;ËSN@]Ž“ñ— ÏìãLUÛ†Èñ÷¶X»Kx»6 ͑8=Ó*ðUµ±4^qÃݗۥ>S韒¢+—Å» ‰eÝL®ñsf»í v?Á¥ímÆ!±»ñ'Õ粈€Yþ¢v0—«zæْ2GãîÏÒwTÄ1×µe{BªðHÇóMœ,Ø Ï&fr(yÑÁË)©% ­ßPÉÒùÉÍ Ehl§% +$EVDĶ¡¥Ôt o§Á \~6-s‡ð/€/²›‰EÊÔä 2<뤪tñ ‘Åù:¨ÝÚmb“Õp®´V÷±ÊçÈn(Q®7: ÏziZ¢“îàN½l*é3ÄÔmôiИ¥‹`® ß sµ‘ÒnX +ýUœ‚\ПÈb¡i0™¤Ä^Kcà=Ÿ!!{pwp y€ÄK´™H´ö&ôȘ/ùU¯DµáÆgõ#M@’êÁ1“¦¢“¡&®ÓÁyf_s‘IrÈÚùÚŔ\ ýBcŸ×¨7¬H˜eßxÔXl¶Åtbuæ!†ÿhI +&)¥å Ö©êršbp›s³˜Ô;î²Cu GFæqÝ~~c6RbOŒñ 'l—"<͖¼‹üÃz [ª”TÿÏ0}°5y Vá|E­W¹rŒ„Ñ„\˜2”aAA‚¬0 „¬/É·W&aã€A +¨åÅAK]מ ñq\k‹P­µžU´"ÎJÑ»÷?¼Wåù¶{¥¯j#¬'rG”^–‚ô$U¤Ù)~VÓHDäÎTup©áéæ7©ðe’ÖÊ⚊–˜R³"«I˜›^Çw0Ó^Ô+m¯âO©ïX¾‹ÖiM£Ái†-T‡ß5ȝ°©'ˆ†œNÙ]¢~{e‘œ ÃÄr¢©Ä5Ճè-wŽ»Aœ•…„ºÏ-œäV•˜YF~¨UgÐÖBOÙJt¼8yÇ0¶´¬.{KªèOÁ(Ùë¸vlJ¡ uÁSëœ0ü¾ÖƒyØkØ^?‘6W­…c+Ý +ÂC²½ÙlÄ]œÂEškoÆ% ¾õݼ§è„¦™“‰õg}“h0š[[¡ÑãˆtVۃw,ÑíÇU™£À^|}²X?†½Šõ4:a<X… sšá%˜Ã×هU)¦Õ<‹@Z§Q›/ç[µ6ÓóÌ Ý.ú ÿ0A=¹fˆ œxãIҗ³’Q¾lä3\¨P©BoJ]Ô´ã\>[3Ô²õ­ö‚­Œ?,·ôÆЛMOyIÆOi>§ œ'»|“àÄ2ÓökŽ¤x¥Ío»ç6‡–oy*—¸Zo×9‰—XYÊýi£¾ŠŸ”fNP?ž1…kÏð¾ £€Á *ÙÐã_BàïûÄuøpÖ²B[’ š”¶Å4XŸÑ×õÑÔφ“¼}äã렐‘P¼¿•Ø73‚d"ÎdÙ®&Ä<¥ÕÐîăTô>º–üx4ñY´…"ƒþGðÑXF%N£góÍt2®õS 8.h¢ªpq¢„܏¯#~Âð2‰Hlò’eÒ¢ü€(j =äû™‰~ðn$¢± Y9P²KàÚÐC‰/íq䢘Ö¢&lÁŒâr³èSøÁ1åË|ˆ8Óû+üìûýáÛºþǝp5q ¶Z­«‚ô‰(õQÓ¸©AX‚‚!\Ž$$$CîsrL2É$™LîÂ%,‡ –*OQ–uÁ«OłúŠBuUX뵊]‹x®¶V‘î~á£nš,ÿŠ[™|ÏnCÖ +-ÀbY@ªX?(Ûe±92í"Õ¯)fÃmˆ€6@>íÄ_æ|ÓXȼ ½ÿæL N§+VJ2¥v&¿Áœ’Ç‚•ÙgÕa:yÊ*=>ˆC¦,꽅…zq¨¡©øwΣa™çáVîbP$©àßԆ3H¦ ‰ìµ* +|™tšc^Œ7½Cûv›ó¼fÝC¦›ïºUʆNì\ƒAœ X)ŒM¢×Ȋ¬ÅQËr’K{¥ãÄFۏeÍ"jùó%§§h·¥C¿ŠùÀªi¸24¿Ô.$ÛÒ²–ɹ™DÑüÓ®Â?2ª»ðÏ]HMtî—Ôa¡¥»PZé¸+CØÍ9èJ*™á_r%QNÊH®4Òrõ{W)þ |Õem}˜^…e «ÎÙ» +¶.év–¬ö_.e'TÞ)ñV4û¦(FéïoÉÿUgzfðÓ0Õ=ÛrûºÆ£Õ[(hÃØGjKÝÝÒ¢žÚy‚}¬÷¡%ë€]Áʟ%ö€(yì­¬À¿0Üóæ·àÒL1Á½™sÚR1w^N³JÛO÷7ö „ÌنyÅoxõ™”OÅãÕ`òi0) Â¿6Tù„­@JŸ­ŽJL#†Ù×´©²C‰¿[!ì)º«9!ËÊêw+“Ž™î@,Ü&TŽ›Qö0GU5ÌËãýaãò¯ +ê5\1(ù¢â¡-è9]³‚¶¶¸†¨›s4ú±Æ1y3¿Æyʍ©ý©À/Ì ÉÈG䇫~IÄ´41î¬ñ_Þ35g%@‘ØÉ.1N§” N¸Ì¡þP°ïi'„7ó×ëŸÈ4Û˜@rÂzË8äZ?ˆ ìêiþ;Îfç +ÑcÞEÃNéO‚ri@ñDüœ¡Ž“ï¤úu{Aî6.ѱ>1óáë_Ù:,¡ ƒûJf?È/•Lèí¢CòNÉNÙç*E]Ù­!ç½×ø ämqú=pñ)²¹¿ݍî +œc«F±M¼Hõ´Œ?¨£b;t•%› 7órÁ~ãû´£ÎL&ž3>µÅﰞÁ~6slD'9ã?´ÿ6š‰T­æϙ‡¥^ 5÷;Õ +k[ }€Î»ágX0^h™q$WâKJm3ÖqV/fÔ̔¿Æ&„í|ª}3ãø¶½1—ªèsÌO[­9ï¨"6Á‘εñ6 Ç9àK¦ÿæ+´|dÔøæjÒ8aÞ&Ák ËɐˆŒž=9wåUžÍ©ÏÔ?º¯ƒ®Û¿Ó|ÍáµÒÔ0,Œ’«¡lug™³z®äeU,}*Ì ”åe-þˆÔ^u„ïG¢SÁëßoyˆž7ž¦7æñbC#Q½•Ýşánª½[Ú,( õçl•^ 6¤¢ !ùúâʌø>ó"ï:Ïj°®èbiq¼‡„¹Æå2š$V1¦\$›åÝǕwŠökGÔ£þ£îQÊ“Ž%´[ÿ„ôÅÎ`çѐ½J¦ Ή `·¼]–ªæ…+Yº)úu—!*ó5´Ñ(HáId„Ða¾oEâlw1¶•7£ïÓÈáhY³xЈr—ÈãM·èyªA39S¢ÝcLYgèBل*d‹ŽlQö·¶ å¥ÖÓP/ð…¤Ç…m¶ðòl)ÅÖIëRÆ`i™ÿ?Ğ‘¦ôAû‚Y訌ó :§Íe‡»ët¹/Ý Òyüsn琸ÛM ­‘º>dìSG¹&HÃP³ëÁe*p‹ûÖ:éê´v°¾FëòÊÓ«´}9àà|%*öC…‡d•ÚŒíàŸ•T¯»ám ؍ýžÎ¸SVØÝký‚q¬ª½Å~V÷Q< „×f±Ï +ÓC‚B¦´'ÌøL†HÉ?— 6¦û¶ÇZWzªÍjxAñ|õ+cs£hi„#aÝ43¾ü ËKÑZr?Ú'H:‚µmø2ÇèAŒÄ½ ÙešÐ­d€cÐM^ðkÃ^þCÖj#,®¤ž@DòL2Ëâ‰I~tHGÇ«íøJ̀ó¶eñ Ô W`_qÕZ•bµ¬ +„"pÄp߄CH„æ I&Çd2÷LÂ)x‚ʪ­°*j±XEtJ×J]«EZ_=@±XžºY¥¨íî÷#>§(§Uûª÷TªÊ#tgåÛE Àíª¬ÌU¦O4E±Á]cD®•ix`FfÁ¬åøw0b(½”ÑU +Õ•Yâ®ù]sAˆêvjßfh€w@A,búÆx#‚iù”ðu+•ÝE¹†Ì_÷X™¯x˼U-ÆEŸW'šÒ_ë½@ÿØc˜e2b1(·ž h±^EN±Ø +¬`V´[@-k…¤b½’°nÎ_PëáÅéeÚ:øÿ60ŽŒ„š³Ðñ€èl–u-'\õåj|Dþme;±®tHÞGDæ˪&ˆø´‡Õ¡D!ߪ¿@Ðá—M…Ä?Bâ=ër›äéΕt<‘GHß8šJd öÿlûM¹×žiÜlv>Swžo2ŽYê©!Ö;DL…é¢Å¾]²¡ò®†’±ŸÖ˶íRÔÖþœ¬f;Ë·¾Ò-rü®0Ìۏ첸ÛR}Ö"‹¨?5#ðÍmk+3§(¸¸­(.ÏõÇRÄÝÉxP{K$ ‘™ê~?uXÅ m‹ÁµÒÂ(U$C[Kží·–Il9v˜®ŒLæ"çF¿À«]C2qƒ.ÍOI®6Ž1žQÐçªxã É1i™QÑZxlµe_³Ì)O&uZõê±èCÈj7$6ôøÕã} âA~««8zXþ°ÜÓÀ¯âm¿b|®nÍ^i>¢]œäfQêë¢ùÖBchÈJDj^ðû k‚æ½]èr¥ou‡ö#I¸î”îšh +8ЂTc£1)±Ã¼ßüWÞ+Ë-Ë*îkxƒuße´I÷~€ßÁPEŒ:À¼±LR] &‹‚t-¬^à*$MŒ4-µb¼› îãÎB è¿Ÿc˜œéŽ³ñA9ZµuÿKíDۄ§«§Ñù¬T}–•pËp;dz›…x0w +ú Þï7 ? r™©ØâŽlJÁ§ûÄÑU/è3B®¥K3hÿ f@ jçm1©¨RîזD*Øï¿pù–©Á֓ƒ2ÃÿOö(VvÔÚ +n¨‹œd¦³úmMAOßëˆá¹;í1ÜS`§Mà÷Òú-a6 —)²ÂN߲,ž£_ +ßl[có.Hûі%¶Å–Ø´+#]l‡åcÙ¶ŸÕã¾ö$ ÒsÔ~’&ªÂÞbâ~In^™Yö6-Šìª¸ÊŸ£–É/FŒRˆêa` ýŽçÛEi|à•o Îò$Ô³¬¥h:)=’kÇZvö¥6ãÁŠg|V'E´Úë;ÈRèûˆÊ¥^ýt\"ZWÉÊ +Y°»ânN'⢒¤ü†LiøKÑ[ºž!6bؘƒÿjnf¯$= + *™.Ӄ¹ÆöK›vIöchP÷*%Õz˜Ùډ,1-ŠpGsÀ¨ÀDì8D±C7x†¡&µXš¸Ó8e¸!j5kLÌì4ð–Y›ü Ä·&Xqˆ¾ÏY¿LA)$•]€sÐ_g‰^.®[“…³Æfx™ ×́{’sÀÓHqÌ ‰® ¶Ž£¿Šöo¶“à݌ǃ KåúˆFa­a)1$PoגיDO̐Ѹþwèq?0$×°›ÑñÞ®xYZòNÛâ8$ôÕ8‚ _ُ$ý`‚l·cZÁ­6Ÿðݐ?ÝȇY´+û0šH5z‡á‰”kQ}Ö!•±¾~QQüýº2ñ&P{BúcH˜ó…|ó7g¢zŠ9^sy”×lïÎ÷Ûïä­u^ÚA¥ œ;ÊRâckUó>®)’§‡¬vÜQá 8ä:oV¤cƒñ‘ÇsûKèÄö6û¨8#7Æ>^nNk·_ª<wÒ*>ÙÜmç¨Ú¹3¶§Ú"Ψ­ÏÅ¢lÝ`ª§ÂÖ D#ÔýÊîö”¤Þ£7W-ó¡#Ôã›óhŽöî<ãLÐqf6«Ÿ6@”ç0}¹þª•ÙƒÄiÍÆÔhâ­ ¶• Õӛ—“RÃ$÷0Ùa–pž’s–¬—T9¼Û˟ú sJЫú’lO¬˜Iùw7±A8j^Տßork‰lèç17øx&Ôäe¤Üñ˜‚oáó U°¹d!SQ2ñïb+¬Ú(k…m\5†ôø/ÃÇÐ>ÉDÎô:G"DxA4 >…¹èXò(² â× 6b³Ü-X>ù»à®Ä*þ'qÀk’xOºäOXÚ+ë{è5íž| fP|~NE‰ãÔz®EÉy?¬’|êSãä-Æ2¢<“3¾÷}îñôÌ=ö‚‘`·[‘ç~³£´#l²é®Üt¥ÑG¾—P«§ûj_º ëœ_ÓÙß·,ˆúÒò›Ÿcñä®n±$kŠ“aš†³²ÁMê=U¹lMíQ‹÷"g¾ñɆ 5iЉì5Mó%7R›%q£þvÞLýS¹G˜[]]ÕãMÖÚÐê vKÍsàw‰ã>Èõˆq|Ç + 7épÊL=º³#.´®[ÑÌCjϨŽ†^wÖUOl’Õè€Tv·CeúÚû¤½Êöè¶Íÿ]òŠj2Íã0–uuFfÆÕ±®ŒÊªè:„AƆ"E©*‚±S¤¤'_ +!„ôZ:„¢ˆQpt±Œ4»â7Ÿrv÷윽Ys›ÿ9ÏÅ{÷<¿óžFràù׃dË+G1 F†~ /b¶m1¡&ªÂ&x“¼Æ,Š ^ù LtZn‰·D<ót"Œ„7º4Æ"¨Ž»×£.9Ô¯¢m£-±‘6§ñIq¬5£¸±£•5.1gù)œj†‡ßé⬌¹»ã!0ýÊOD<%në…{?ns žˆ³þû±Èê8¶Y°œ…£F<¼p ›œárÆwPq’DºÃ!\ üˆíFìÌÆKA®´^‚…¡ZØŨ·ËØ èR÷÷ŠíœƒõEÝÙᏥ¡†l±a¨·¶«±óÑ?ÛøaZÐ뵘lt—U¦³tÅW˜zŒŸ…þ‡ðs1¶Ð͘iea1Íâ¿ï½§MŸ1ó«¯g͞ó—¹ó¾ùv¾åwßÿ°à¯ ý¸xÉÒeËWüm¥ÕO«V¯±þûÚuëm6lüǦŸmav¿ØovøuËÖmÛw8îÜå´ÛÙÅÕmÏ^wO/oŸ}ûøôó?tøÈÑcÇNž :|úÌÙsç/\ ¿u9:&öJ\|B"D¡1X Iä¤dJÊÕÔ´ôk™YÔìœÜëyù´Bz£˜Ébs¸<¾ D(K¤2¹¢T©*+¯¨¬RWkjjë´ºz}CcSsKk[{‡¡³«»çÆÍÞ[}·wîöÜûíþƒ>z4üøÉÓg¿?ŸxñòÕë7oß½ÿ0ù´˜6múô3fB|=kÖìÙs æΛ÷ 4Å|KËï 5~Xí±p´Èâ%Ð&Ð(Ð*Ð,Ð.Ð0Ÿ–ù<ÍÔ6çó6Ð4^Þûöûô?|äX@`Pð™sBÂ#¢b®$ PX<1‰’šžA͹žO£3˜l.O I¤rù¹ñO‰SŸ#?UB™P' +•B©PëàT;üê}ú *~>22 +EOL¼€º_½~ýæÍ[¨ýý‡““Íý g ,vó˜,òcy]âzFÞþlç(§‘}FVύPÕq㫪¹ØÚJ6©AÅ$µ*ŠH¹·$ÒÏΡ™ŠÙÁì`v0;˜Ìf³Ã—9¸zL2¼‚ÆٞQC|¼QàM5ð±›x§¤zA¨R+Œ­Ô” k*x½ŠGj‘sH%Ť^VaÒݼ¼´û¦r~…LÈ¡Ø3hœã5$؋»#òÈìú2›…'$ ’ó +,ª¼F‘P].ÁÖˤV!‡ØÉfoÒèDc&2`* ÷_'ǹ{# Ý°w%{2º¥>ŒÙaQ“*Xª¯ SV*â5r1V/‚¸\‚¡ˆôä2·Òèd£©L9¸x~dºŸœà»E ‹]0ý +çôÕ^z[ÙAKm€°º<¬L!¯‰± |±¥˜t䳁®,&p#…Aºe* ×aʁ½'pBàré±Ì }¯Ü1µ·zw¾AçÁÒj$ª²° +±,¾Ž9°Kͅ| -—‹7\cÝÉLâ Sy r฾íRꈼ_½bl؞ÝÒ°—U¡KTáU|YB[ŒÓ3„@S¾ßJåãÛÓ¸€!‰Cì2•)gOç|â¥dgسò­‰u¤þûôºzw®¬2PÉW^R³d‰µÅ\=M4æ +æ Ðz•Oh'óˆ¦ò7Ã@önOPàðJ¾-äyõæ¸áV;Lg·]f¹Î“'¨R±”‘j†^[(ÅëòĀž +y¤C”B I@l3o?å ÜqìM™Ãù±zÛ¨{·6ÀõöT©Ö‡Ï*?]FW^VÓˆš|¾.Gè2 T¡!YHl" Iͦ +~œ]ž tˑ·Õ¶Á:6^ìüm5ºÂàÃÕúò +Ï)ó”ÑU¹ +¤&GŽ¯Í’êÒ¥ÝU ¡>ILÔŤSKì` `›;¨‚m\¬oÀêœöÞjœ¨c{.]wˆ{]}Až][žUŠ¬ÎTà5×䄚T9±–"#֑¥$-QJ֙ +(²…R;×7µë¼îõ®òn^¢°§ìœ†£¬ÌÚaº:VžVT¥•áËST@e²’ &—«‰ +’PkL”l‚ëvw¬ØÙ6´Ô·ì¹U8{`>§Û5#½õ8-EʦhcÉ5Iƒ–jŒ ¯ÆɱUxº(EU•¦Ê×ÃÆ–Ùu=X°U=±ôï¹uxî}{tjŸG +¹ó•Øš4Çaã™(=œ¨Gràõ(n‚Ë×âøqZ¼ÀTÞi–­ííÿvUí肝Âɇ F7†¤ :&|ðؾ“ôÐôĮȬ8CLNlG\nt{BÞåvx~T2?²]ъ¡™Êíî¹?Öÿþí:éäB':¸ÚÿÚ û³¤§n‘èA¿øýSè+ý€Ëw.‘"nG%…÷ÅPBûâRBz®^ìML½p‘zþ&*ÍT@æ–õ ÝmHÛïÿ®hÿÙæØ‡¬ƒDcññì΢³¬&Z¤T_Wj ð5yI5•¢­LOї§¤5«Èm + Ç ÇÒ»Eèâž/Åì`v0;˜Ìf‡ÿË¡pŸß;†Ï™Ö¾ØA΂‘}„ÚUÌl¦‡Kôô8¥¶SQC#kÔדtY”FUÚÕVErºAF̾!ÆÝâb7¿”ÏEŸ|üÞ{ŸeûÄ òöw¸þYÝ쓌æE‘¾8¦TË@VÔ4U4²®<7©I™Ii—¥¦öˆ“²û¸š‘A(êýRþí@÷öûƒý: j:¿ã8þ¸öÑÎvÚ®ug–±«Ö*t´âE@EQ‹€*—r ëŸ„B’î;ä !„rI†C@V@Å]îºŠÝ_³¶µÓ‡äQøàýü5ßù<ùnˆÒ.>—¥UßWÃ/)³aÅYØ/-Ry%•F·¤Þ2"Æ  InK/iÜÈ"‡tôY£{¦p—8dþ|´Q\ĐxÀi'6Ä©/ä©U÷Uiø¯5ÇÛgÔ§ye¾bLYª÷(kÍe“Í&‡\1qÜ(h©¹-³¢®ÎEv;w©‹Î›6 þ!5kC‚(x¡H¹ö@ƒÀÞÖm›ÕäNêþ&וôy UF·eÖaœf5n\+#„$Ê,—Û¾Èìá.µwò¢íƒA€Èڐ&ç¿T%_}ؗŒY6"ès¦ ö”9G°ª&†¯jƒ æÆ¡ü½R9a²WLšé„éót~Ï-‡·mï ‚ˆA˜’õNv$ï¥&©ò‘! ½2p„¶0t¬{z$›?5Z uTj¬–º]Ä ÐÆ`9ì–Âtù& f,Üùhâ؈!á%g¾S$æ½Ò&T<6n¼cK /¹ó'z&¼ùbÛp¹Î`F*õ§8bà( @‡š¢ˆH3x!}'ìŠ: yo8ÄI™ÿP&\ø»þPùËÁ†{ÎCÄå@RËt(³Ûéɓ‡ÊŒ*rH1𵐗¥‚&ÚäÐd³”x'¦McȨû`$fü >”ûm|éSÛ~䃱ؕ¹$Òx0ƒmq]Pª­e&‰ iƒ#ŽeF6AWB~’œ8‰“QChiëT´ɞ <|ÈÚøó¯ö]zîÚ[u*¾nz!žb÷gôö9òԒÁr3lª³q X«r3"· © >’’4SPh=m@ú£áÐA 8 {ϾŽ+\÷Ǖ--íFŽÍí§Ç3a™£@ì4³Mõ6–;Ò©'¸Zûª–8JԐÆpjŠ­j6 ÛDƒzßQ0°'ûåè®ÜÕ¹=Á»;QÖéøv…ï„€ï(ÔôX¯™ºÌ ÖN#ÎÎ0-z¢“¬#¹‰}Íœ–2ŠÑÒ¢Èÿ¤ûã>ñƾ#óAhûÉw¶•8Vw 5áC°/[Àr«:mU†5ÐfÆYéýÕH´7H‚žìÄë)N¬ŽæŠ6 øS PÅýX¶'>ó}™<·¼5Ó½þe©~y'NNdtOäðÛݗdô‘jM‹ ¥§Z±ý̓x3ÁYðÄA¬™dE›ÈCM&ª-ڀjG ÐoûÎõž¥Åßíõ>ْm\©-ïÆuÍ ÚZƒçÙTßÙS#%º”xG“;‚Ñ¢í8]ã0^ß`#ê‡Hƺ¡æ¨š¯b~Úºãnø×øÙAóë-9’õ¯*ºV÷¡ióéTR8· +–ö`'ªyM>¤ a¬ATçm#GђZVZãÆ˪ݐ¼ÊETDèÿÃÖõ‰_l ®}²mð»Ï’do¿8Ëz¶»”¶–PÝÎÂcò)¨ÙÒVdøjGÍT ³*„ì¾:YϪ ¢z*‚Mìò†SÀqKýPÔ}ëüôW7–öKÛ«Ov*Áo°ßm;C¹¯zœz­qít}ÝJ¦úöe¨òV©l±Š|e¡–ryI½t³žV2‡j)žk¢Íb腳ØÖh ‡ú“‘‡?ÿ|º«lIl»N^Îmz‘Qr}ý\Eå£üê+Š¯—¬•ÕÝ«l(¼[ÕXp§¶1ٔ¿Z‡Î[m@_XiÄä® ±Ñà¿üp“övôfžyÍ?qé)œ¼Ë?GZä3Ã=•‚@WƒÊÛ =T³«µÕê 2lvsdÏrÚ°÷Pì±¢¤Þzµ×E    ÿ÷†Þ Ç€—qæ5œYòTp +yOC¼Å»Øæ”ÃRéeb &Ùìl§[GhmÃÃÍÔí¶b9£ƒMð˜%ó”>]8îóˆ!pÒ€Ÿ~æ{áñ’g¢¬ëkâl’ðBÇ4ï2?È©VŒ±õžn¢ÙÙI³Ž´Òí6 +Ãe%2G-8¶o ûûQ²€¥˜P6n¾c÷ÀÇN/J/þF’Q»&= }-9ß>#,ê ò+å>n½ÎÃƙ,ŠÕЍ µ´z,Í>3¾'Џ„ԍ’´I£åþÍÿ6ôM‚´Óo$G‹¾‘¥×ÜWdáoËsÚf¥ùܐ¨T:×jGyh““K²Ú»)k[‹×Leøû›Ù“¢ø†#¾ceA>VØlï ¼ˆ—–„©Ùo¤iEÏǪ¨2p˪lúMe.{J~Iì—T©½"”ÑCƒvn³c°‹æ5µ3ü}-¬’"ÐhšI'ِ,¸ÙþkHM"Dö[YjásUZÕCM:f¥ïD˂ö+¬)U• +Ÿ²Nç–aìÈa␽Zfk@ÞÎ é¼0›,œî"IBL’tr³AlĐ øˆ N9õVžrñ…:õÚ#ÝQôª1ƒºhÌaÎ x!c¹ÄoDªÜjԀE‚éã½òš_ÀdLqœi&]8ÓN“LµS¥“›íƒNI’äSÊä‹/µ)WÒï˜ÓÉK–lƜ5==\[jTv]½Ù¨@(…WØKñsØm!fwO¸)œii“LÑÚ¤¡Íö?鑓ª#¯tɕOLÔ=ë?Ù¯“¨¦ï€ã‡9Íë,oÚ9̳³´tž‡Ú2ÏâÀ¨UAÙÅPÙ×@C6²‡¬„-!d!ûž@ BB6²BØĂQDÁŽˆk«§ãop¦Ï9ÿç4Ÿû÷úM§Üre²—½9ó¾*¡ßӍš›†ûŒ—RMð‹dÔ0WÜ:ËrçBÙ5*G1GëRÎBd; âib"P'dþh8^øý`Bõ–5yϕJ\ ž¡¯L¶Î„*nWÎ2Ò bÞß­¦L¶)˜3tç*E&' ”sd¾r* ‹Þiˆ²„@sìì?ûâ/=:Vùh,~ߗ‚½;{–´ôu15®àÛÆkµ}6¸EnA;øýxo‡bhéS$uÇ,N%œÃɕ³8©jª· òã'€îè™×q/¬qåO=Ç`›S)ˆÛËçг ù,÷T™Àì­×¨ísïÖÞ=@o5’-zê$^˚Fk¸3(l¥UAä?5(ã€!ö4°ÎÛv¹ò(_uw1­fáf:Þw-»}hâŠXë©ÓKvz†q¶®A²›ÙOñQŒÔ NϜ@ë:&‘zá$B/† Èÿ$Gc€*î8è?”ñÚz0û;ߗ—î]/ZZ‡…V’É#sY]°X&q×zlK×NC»™ìd P¶ÂGÚF¡ê½ÀµŒî‰ÞœÚ=¿¶;Îóø³ÓèjéÚ!,çz“5—Ï¥…+D”`ƒŒèCª°^ŒíÁé‘n‚á"áNJ£“f‚9˜0 2 ü˜?ÝóÌñÙâ­ßî}øɉÁí=y²­èΝ£Æòi*ùë‹m„¹JnóL€š„÷6M $_…še Aœ (êü$e­¯EUí£««½ Ȁáӏ^9þ±²ôþ‡þ»¢,¯>I–oGæs}YEßHBWÏš—‹hÈÅÊÖ¯®ÕµÃæ»ê朚YTwÕL3¯r×S1Mà—O“eS-ÂÒ)*d`ø¿[ŸûÕ¡û¿ùhhûÃ%؝ÒýjßÆÓ£¥„Í“õè\$|­[«œX½RK©¼Ñ@-_‚ÓJ—Œ’oЌ+כ™Å‹8VÑ"¡õò™]ø?¸üå/&—ßûõÈË÷ÿ¬ØÏ{’˜¯d_$]B?É,kÜʯ©¾¹¡üÛ2xÉF5¢x½uùn#ºðsé¢ùâ +[°†ÁÜÆâòoðy«DÈÂs?ÿ™íÎ{hÀowóÁÇ1,°÷8 Äf L?ßðCVAÕ÷yE%Ï +K.?)-¿ô¨²²àamUÞÃúš [5¹[ðڜˆºœȺìMtýùMì0¨€ðo»?ásÐ}*ðϜ|-ÌÌ.Ì©Ü ×{JZV¸u (álIneêCô6“¿¥Ëâ%ñFÆñ‚Q¶×æÁÈìn”j̍Ð;\Mƒ{“’w ïÞ5üŸ6ˆÞ4Ýq@pê$Í{Þ{¾bK”‡XQVxÕ œ&á\^fÓôA{ÀOëò’»­ã¾m§ÁîÆÈ.”ÚéBö¦ç0b’· ¼“±@”‘ħ/¼d–?”ä4mˆ/’o +ËÛy0Á£wõA6kÀÇloáŒzˆ=vVätbd.RãCô{,“Ç„4¹¡¢˜]@°ÓГ zÓӁ4#÷¥ìLÙ#yüž,xK|…}]XÿÊCÈÂ>ØA𵲇Çi6‰çpàDî1Œ|܎Òù,H£ÏˆêóêPý(@c‘€Ÿ Äii@–žûRqªô±2³ñ[eaU^ÈúFRÁ›6J§zšµ!Åäë` {˜ív'…ëà ½¶f…­Qú€mô)0}^(Þ6Rc$5 (Òr~P,y¢9ÓðwMî¶:Ÿ¹¬(å^“Ö‰gDHõD±ßÏ¡yØl»ƒÆñØÈ"ß0A4át!5F’5üblŸŠ· ”#@šœ +”)Ùۚô+Ou§`÷õ™Ø;ú\ú mqׂªZ4+‡+'Å8ƒ¿‡bqu2Ǭ¬NÏ ­ÇßG‘†t$턧â ÞèƒôFïÂ7 ÉG€,)¨’³·µ©ÅO 'ë6ûÎbîögSoö¶/+øWu²°£÷ˆˆ–Q.ml°½Íc`rjš($oQM +ˆš0¨rIF?ÿiˆ¢¤#@ž˜ÔIç_éSŠžõ¥×>8Z7g‘W-[—ÌåÜ«½ J?&Á[Ìü–1Ck\Õ֐°B†"Ìmф;[ô¡Žƒ + þ©¡7q§áD +Ð$fýØtù;Sj͖%qÏzŽ¸fÏg,ÛË;¦-°^¡Q`-}"ҘŠG÷HºÚüvÞ—- ·35Slº.ÔJ7 øoÉÃ@‘ þŝ5pŸNgÚmwº³ÓÙ±•Ù™mu»£ë±*ꊸ‚€Š¹/#7H äNH  Ž@HB€„\ä$77!áP¡ˆŠx¢EÐ.øo´vŸÉ[öáóþßOⶩ8—¸¦¹¹bD>±†æÏ÷ÄßîΠÙõ°«)Q‹ðÚ6AYÀ-ía×WÚj™LGU-o¸¼F7k1FjÒ@3äééÆ\=ۉï <ä„'¾Š#Gޙ¾?±Øùu×êߎ·oí à¿q¥¯xeP I÷Éøh1ênzY=‘Wu MÏÇÕ¦ÝÌg¦ŽÔ¥ŒÕ'Ý(e]-gCGi.Š];^÷üå‹É¹Ï>ï~ñ×o”[?)û µoOÄP^žM!=†aÇ à øì¹tRæl69m^œrUš4¥\û O…Þ%–%Þ-,O¸]T›B‹›*sÉ;ãŽ?MÞúôw½+ŸíPmîÜÓv{ւC)›§#H뉘ÕðÔÜ¥¸ëO¡¹)‹iˆ¤…ëhè£\LâC.á!ÿKˆ›'bç‰ù1÷ ‰Ñ÷‹HQs¥.™´ÿá·ýwþø{õϟï‚/÷2À·Tpü øc6ƒ#s6"âÓ×b¡I¯ )‰«©iñ+™±Ë°ÌèexVÔâzä:;â9þ –ŸsåYAnØS²KúG?ùvö“O›ÁŸÝêÀW{ÊÀþ£$àé…þça øR*½º÷óÕ¨è·É1‘oÒãÂ7²â¯lÀÂÖá ¡ëˆÄ˯‘WC^£¯†¬á ÁkhÐñš+óð€qf7¨ :êB|ëJÈ+*þu}Bæ2#½P“Cž«ÄѦˋ˜S%eÜñÂ*Á‘Ñ:Šg· c¥ChÜli·çµ)á +Õ`®FmË5©{òÌÛökï ÿ· ôÿ5„ÿ·!>s™™Œ^ ÃÈsUXÚt™9UJ厓«šÞ7ŒàYΆ™-PØß7 $*gƒz0W«î‡›Ô]yÛ÷¡él`\:XA>€s9ø7<î5'&c™E=ffÎÑӕDædyiÃx M8ZHë¥6°.¼à"4F½m IzÙžó¬9ÿ°)©d¶1»ú źŠF+)mjuû@a½¶7Ÿg°âDfFiUcԝR¬ÚڊÓX„x­i»>6|XþGÏß/@@+$âßâ k¯ÄaÙÏÅÑØQbќ0ƒö/¯n‚MàÒ‹Åí]%µ:c!רËZTxY§ §êjq4ÖF‚Ö¼]XÎöywÀ?çþÝ=5a'ïÎv:î´u»]»»ãŒµº¶u=©¢«,‚"È@n9 „$$!„+äàÊEä€@ÈAHGBB€p„„EA.±"( hAÅ P×뷙±Ó—}ÉЇÏûw¾ +oPùE¼i„­·„ ×ԑ9Ôq‹Í©¬[ üq)Q<\UØh.gêºY}‰°WS(35Qû•EJÖYj)zS µÝh/PókƒÈë¨ó<”^~ É'ü­Ú?aS„|¢‹ ¬´AÉ :8}F/¿RŸ+¶ˆ¨Ý|š®­Œcha +Œ 4±Y^¬´H‹´ÖjªÖZU 7 +Ûûìõ[C­ç1 ?w¨<}A‹wØ{­_ÜKýyēŽðŒû]Pâm¢p\‹+¿Ø-¶ T酟ˠäðŒRVYĐ[…tõ¯X;À-ië¯(iï³×Ç7[Ã9GPïq4zøgè‡6ŸØÍÎ@ø£ž0Ì=4kֈ \ÕcÊ-M±ANTij ´Ê*†AÂ+7V— Í|¶ÌZQÚ4Àf¶°mýl†Þd/ ²5ÔØÄŽ@áî +šÝ½Ö#ø]‡w̋ž€¤Usri07mN¥ w¢ËŒ|­®!W¥’Q´RQI§°Šcä fWlerUôòÖ:Gg¡³õ&{ýÖ q? +”n. ÅÍ ´¹½éòŠ|fò0–rg$u͚B¶ö 8†6œ¨¥9»A®$µVˊ:¹bVoi ÏLŠ,EUŠ‚Jí@!Og)ªÐ›íõ±áÌ@êv4œ>4§=A‡[À+£gøÚ $fy4"nv,9r1™ÔgJcë:±5J-AYÛLÔð +:J匞Y¹‰*©îϗȭy­5¿Zg!WêÍöµ¿6È΍®Î@çâºÎ@6,ÁGüÃîÎD†OMBӆF`ù+¢´Ù˜^-íÄ+*u¹j¶š¢/i¢u‘UcnC¥9K)ëÇ7hú³êÚúsÅz³½€ØÖ ²5È]ÍÎN ÝÙí­ÑÅûÙ°;äÁTd~>T©J”4& *íêo‡w‚Î}»Ÿ ïÙuóö?¿»¼zðXï‹cÞêçΑ’ggS¹+~™ô¥P2u.ž–÷3‚M˜ÆVà&³éãÄ*ä¥1Z,‚_eˆ“¯°%I#\iâˆP–pYRg/Pphý×ö×ýßm¿sãYÙý}ïÆ~'õkGˆä•s4÷ù¹Túj`ùޅ¼ÜX~>­3‹e¢n؈™¼2ø4¹"yª ›¤ñ'™‚ø‰²Ê¸q~t¼Zh/ Úû5èÚùõƒkùòêƒoþfÜصOýa¿‹8ús߸FÓ_ø$“‡¦ç¬@3qË°<ôR ±€¡Âïd%Íç'ÎåÓnQéq·Š±³4fÌM+úçòÒ¨|¶½€îÛÏ׆·n›û|‹qý›íj°ëpå‚ChïÝ#È/ⳟ_€c×bQˆG0lÊ +û%=+á>>'n9;7ö^^^Ì=1ú.5?j©ˆ¹D'_X,¥D,–QíµnúòÓÑñ?ýÁtÿ‹/ÔàïßJÀžÃ\pø œò&ï ìw!‘˜×‘±©±0؋¤”øgˆTèStZô*j€Ž|œ“ñ˜ˆ D„=¢bCáBÒ3‚WYx{oùÄt}Ë5›[ÿ,ÛwòÀéÀñ$ ¸Í4LBÞA# oaQQÿ…Ç\x„†¿Âą½Êˆ}IHÙÌNÞÌK Úȇß À× “ÖK’íeºúÙ'­sŸ}*_}Å;vÐÁ¾½$pâ¸;¡€ï™$pþ\,÷Ž1~ Á?$Äù € + +˜à€ ñ™! +9¡~òÂ|?Â}ÞSíØ·‚R—€éwpƒÿøá^@òž—·YH{ÊÆVDòrqQÉ"…Åž'VpoåTUÞ$ÔVÏdÈD×±Jñtz“t +Ý*›Bµ×M"{ä“i–ú1äÅúËèa¹=~oø½áÿض†R[ßÖ ó•Q!ïñq/¹ð´§e˜ÌUV.y™VH[(`²çIåÜÙÜʪY¢š¼L<SJ§0Mu“èVùª£~Ù«˜@(® ‡Céö[ÇÖÀñ=着0Ä#‚?¡±/0ÄS.2s•C -3)´…bgŽÂáß$ò…395µÓ©t2C!ŸÀ6+ÆÓµÊkhCÃ5”Iuý?Fç;ªé;ø»×?úz½Ñ{w½ö]-¯ï¼³UÔ§U‹ ""{*(CF˜ +DF$L„@ Ù;½Ç/‰d:!á¢Zu]õ{©øwþøüÿT •*Üïʇƒ FfflÀ9xɉï¹éY¯Ø9EÌÂÊG4vµ£ž¸ØŠï˜?ÛƸÞ@çÎÖ±…ÓÕBÉÕJ¹|©î/7)ǘª±²Õb@Ջ<¯†*¼óá@ñèž;Îð€ é¤f¼æe>å 1KêWiÕÄE2®c¾¹•9‡£rg0]¢«µÙD•¬g©Q])·¨ÇÊܚd¿Æ]ѯµWöiMU}:oªç@õ:£vN¬?ćѱ£@”œþF˜qê?±Î.ª[cTà—(˜öy‘1‡oçM70œh~÷8J¦«Ðh.#lºQDŸ®¯Ò­·W¹õF”[¯­öÎÇ3j;àEïÂØ#@’¤ÇO¾•¤<ÃÊ~œª½Ç.;»ÔYKžïhêœk&ñ¦qtÉd=·çrT}¡J£ª°ú+zPU¯ÑX}Ψ®9gTÔözÐ<šçйð#ý€8:Èââ€<1õÝ)y/ä™%O$yÕ„ðÆevUëm:–>Cnæ^!R$£,Å@½Pë®í18Q„r™ Õ.³ºÖeîF»ÌÒºs&o|<°#¶A„DÝ1±@q4ù7剜_•éðNJœÊ5yvATÑ<ËÆPÇhxî0‰,íÃw*\µ^j4¢5]­ÍªD;­ò:§UŒqZ—WÝs ÿ~÷ÂðŸ€,â0PDÅuü‰·š¤¬gڴ‡ÚlIJª}³»âì8Maâ¸îŽ)ÔBU™ð,½¶QdRbÖnŒÉ&Á8ì¬ÃÆmpZ9.‹7>8a¾@ºȁ*2 +hc“^ë3~1¦Ü3ÁJŒE¨i¢é¢¸†ÒÏÆr!:Aj$“Uê†^Nà›ÅMr›§·s!ˆ…ƒìÌ&§•Ñä´xtþ~8踡ۀøÈ>Ð4á‘@sìWóÑ´Ÿm)9«PVÑ-kQŸ¶¬iPŽ¢8ùõS×Y©šFRÉÈ4½°•cæ4Kl] ÔI°C4<Q •à´zãáÓsàÙ¤!{2ä Ѕ…ÿfŠNxfKH~èJμëÎΟuœF^4”à܊Ê«ÍÑp¥rf³J@ëг:ºÌô6‘BRBd’ÅÑÖ +Am-[[‹Óꍏþám@¼¨ChØ[kdì†+>é~rÚÂ`vöä¹Sˆ!ËœCƒìÐËkØÝB¬DÈÅ+Y]d=­“a&Óø¶JD ˜„;Dlw؛É›7cû_Ãsoò æÐ` + y툈zÜŸ°6š’tk4 6֗è³7Z åí*Š-–ÕKØ¢&%×ª#qèfB׆cÊ¡¦Â2 GƒìMT‡ÍÂC?€žƒ».ÈX¿è [Ž‹ZžH™¹œ‘5:˜Wît6è­¥d™¾’ÅU¡EôîFIҬŋ(¦ËZǗØkxZ¨šÙÑ,‡­žé´z0=¦ç >ø=PØŒ~„?‹Y˜9=1žžy~4§ÔÚ«t–V$“a¨¶i°Ýx%Aé!jäLs¥LdEÈÔ¶r™ÃV!tZQ<§Å Ës`úiÀ öß ,{߸÷?¹xÄåÚQ¿ë·#/N§e¸Æ`%º‘‚zÉyx+ËUÞÙnGññ–z)ÆxVY­'i‘ºNC©V`‚k•æ"Ý|FyÎT&ó`yÜ߹߁î'_ùíz>°ûÞÕ#»n/Fï›\LŒ¸‘zÒ2•ïËCs/)ƒ¥Tb%Ӌ¡\8y¹£U ‡èšBˆ¯+€ú|Ȫ/°¸õ…:ï¶ç ðß{7ӞÞ¸ÜöhÌoëí;A[¯®„Œ,ÇÅ8NœÔÞÌ(ÎäVÓ'O7µŒ•±—*¨ µÜòœ¨x¸UzjˆÞ;ÄWdõ(aCV%l`P™ãPyp<ñ¾õîï€}ç捑ÿ^¼±gÓՕ€ÃB‚kQG5wãa…gèóÕÍ7òpØkÅ­¨Y¥lª–ŸhdŸ¾ÒÂË¿Lä^b‹²/IÄ°K§(ãâÔ€ç9Èw} Û¿yÝ÷ý7«S[¾šZÞñÝðºßh=(Lý0ì¸ð~l.}-±”¸’ZƒYÊn@Ý."–ß@´Á¯ÕP +gèSDFîd{Wöƒ5ÁãdŽË¸ã:nú8ä ð”¾ÿо\¿¼éo3K>^÷Ý=Ý»_½%ø%4…ö$&ø8±ó ½ªj%·¾| ŽƒßA +oÕ´äßĶå^Ƿî‘:²f©ÔŒ&íä Ÿž6-ïLÖzH|ÿ ›ÿúbð«?ÍÝùâӑuŸ¯¡—[}U¯ö +^ÆÐ^…¦_Æåb6’‹QëYˆÒûù¨âU8úÔ2“¿Tݘ³ˆi‚-4á3ï4Òo“‰'çiÍ©·ºZRn +Z“oÊHÞÊ͟½sþóÓ¹©Ï?}ôÅçöW>ߪÞmÝÉ¿7ˆ +‚bˆï#’1¯e¡ž§”nÀŠ ”æ?‚#s"*a÷Q¨Ì{u5ék µi«xtêJK}Ê +“¼LÿËjHºË÷ +0}ùÉì…Ïþ0:÷Çÿ³[gAM vÇít»v§3ítÛљvZuÕ®]ïÕu‘Cî;r†CDD @ !`BBHHBî„r;€ \BñÀêZP´X‹Šnŋuåß Ý÷ø؇}ø¾f~/¿Ÿ÷¾ùô76Ø°Q Û÷ˆá@BbhŸ\ñ™Y²œu¬èun^þR!êø lQöwLÖs6ó—±H-M{ÊÀ#ŸÖRŸpËRžʒKʓÄéÖ7k׌MürMßô'¿°Áï?ÕÂg›Ä°kúS!"œ q8@&¡ ™ûþxæ±w¨¬¬ï‹³3–KsÒޖG¾!禼®:‘üš–—ôŠ‘Ÿø²® á%§àð’…X~Hç<¯é½¾vmñWkaýïÄ°uö~A…ÀýDˆ +(Dh>¤FåÀ‘Ø,ÈA¤C~ÐI)€óžo|J"”§&‰€ª´x ¦Å­Ô¤Ç®03bÞ×gF¿ç}P½ã­±M}ô3-üz­þð[6|þǓ°oKî@Cø—' î룐éA©’¹¡ PŽtD`#c¡Ô{xÊ¢¢ä˜H¨Š‰jl80bÀ÷!sÛ'À<¸jc¶/q/Ӄ@” Â|ä +¯8ç-» ý‚QMxFeU>¦ðiHRæ|™Šý¯ãÞ/1òç°ÖÆ{—ð.ºK<[Ô'™-<+™AIgPW¤7 ¯K¯¡ÿ ÿg–×ÀŠÞ +‚„½ N ÉÑŸH]iDç¼åâÑ/XÂ"IY¨æÑÿE–°æ‰Mœo®Ô(¸‡µ +g‹]âYt·d¦¨_6]8ìí‚|ªpR~ =)›ÀLÊ}¬UÃz¨ÚÂÃ{@† yf4HsRAŒ:öVPRô¢¾‚°X[CY qè«Du*ܹr­à.Þ šÅY%3X—lsZ~= œ*UN^išÄ\U^,¾Út{ÅgPç5Ôy ÜÈ- AìEr(Ó£A‘²¼ìeQqᯜ°È>IY`ÔÕ<<)`?¨”ñî5ÂY‚^2]b‘ßÁ¶+§0gšn£Ïªn]T_Ç\Vc/«=¸Ëš³%>¶×Àöx[@¿šýA…Œ‚¦#I Ì=º,-B- ñøg ”ÊVmÍ<Ç¾_%áß­P‰fÊZewJ-ÊÛ¸Õ?Š{5·Ð#Ú˜ í%ì„ÖSr©y°ô’®ï»UC½× ˆØ Š¸Ý >ìšäФ'‚úXÖ÷ʂ‚—Rlé³FyC§Ï×rØsT¶²I†¸0%Å­˜Ò¯ÙǞëóŠþ݌!ÜW’ªîˆiÌë õüKÌFÙM¡vWéZ†ÈfC?±½­§¼ßÜ]>jq‘F-Vò¨ÅTyÎl ø¸?d^ƒ6bè#¿Sl0˜bÞY‘ÉK–¬£O̹ÿ4¢KftDòuE5s¼‘É÷px²!¦DÓGS·vWL•v‹“|Új'»mm•›¡ÊcÕUZµÕ£_­¼EÈ&ЅmcÄ~0ǁ õ֑’øܙ™ñÈyüãW퇿kž:nv}Üþv ásv$4¢ðy4A֏‹K磻°ž2ùŒn¶˜ÔÅÏÂuJ¨ÎüüÈUaDG¥2¬óª2´ëž2ôqwQ؃®º€RÛpaÿWPgòõ’ú‡M/ú ×uL˜nmÖXíiœµ³¬™vu:3éí_0%yN䍡I/ˆÉ´Q:‡8šÌnj¤ £‡%bäPž,|ðTvè@™¢ûÖɈÎ^@qñ†«;$¸¹ËÝ8ΐîáBOGhO©ÜÛòtºòP_¯¼__ïäò—úrøÛ:!͆Ûi`ù=lŒ£Ài_(x1÷¤¥Ärìa q²µ#Ьó¨$ÚØÛƸ¶Ç ý˜ ˆ´$vº@²±°m¶³dx™‚8Ð$ö F{€€¼8ä +;»œ("½Ëa¼¡)^STÉó±çSæ• ¾–7‹½’ö +Ә>ƒ¾ÉŸAµdL£ ¦búcè!Á3쨠÷bUÿoø³¥m`kRŒ´S2i€ÈÂí@Šò1Òȏ©lìr²ü>>›ñ†^˜¸@=͚#KÕ+¸³øÚ´W¸+ülcÆ4æ–`}_8…ꎣž‰†1C¢§¸Q~uÀÖ6¤hxŽF ö0…l? È µy´;Hñ ¤!?ò’°Ë)|ò»$YÜ"3?ižVœ¢¡œå¾Š­HŸ!ÖfLãë„SØë¢I̝ÌIt«xÝ#ÁŠ{ðÃâv¤MHù³!ý¸!ÈÜM@0‡¼cér¬?HÈ+ñØe.—üŽ%f¾NÈMžcœH¥–¦Í/dLk„“„ºÌ Ü ñV-Ç<–¾ÀöIûðÏ¥„AÙÃØÁ¬û±«‚Ô=jµ2 !ÛÍò}ÿ…A¶P€t…<´dÇF¬d20Ëé)ä·©Bæë$9KÃTr_ÑKøӔrádlMæ¡N2ŽÿYöےõ۝=€Èî$d·Æ>“«Iý9wÈ«û_GÛ ²7…ë^Pú„6Pæ…ÑÈ%„¯È¨˜eaù-Ï\`ËXšÄÞLÜéŒ)jYæ©Fú’XŸõþ¦| ך3ŒëÍé"ö紒újroî/”ÞÜ&êꀣmàjÄv;!ÏÅNz™A1ŠƒàÒ +1¡+¹dÔ)“ôVÀaÎsÅìYV.o*¾X0N?'£TgÄÖå<'ÞTôZsŸ{óZI=yw)=ù?SŸ4О\¥¯¸ÚžÕÛ …ÎÆpÊã¨|Ž€*ÐN‡{­£‚?(‰Ñ‹ +Q#eÇMeX¿qåiÃÉJѳøRéSF…¼‹z9·ÜXÐFR¶’º”w©O”M´nåUzwÑOqÝÊKqOVgüþKx}E5åqcuÇî(ƒ:ãŠÊ¢2à‚ R¥‡^Œ´P)R @JHƒôC¨"BE0 A\а ¸êèg–ñnև}ŒŸ÷ï9÷üï9? ÷^Çÿ!HŒyY“‘ô”ŽÉz@-ÄüF*#ÜÂ1KÇóøcH9}¡b_ÉR×h2/s/gÜàõfÝ䩼 97y¹7¹ HóþßPå´ðÝö‰ça ÷±ŠçÅÚ0Ï÷Šè€WRXä3aìA *ýv=A)%Þ(¢‘¯âj*5ybf?ª¾¦7÷¯ Ñ+è@\´åMHƒ@‰2è ¾ü ÑÔPôã7€á¸]÷™ÇAPëeêýB<Þ*#ýæëÂËáq¿ +ràì|ôh%‰x…\Né/bÒzð|VVÎièø-¨¡ +5(n@éÅ +Œ^$͉°¡k˜ +÷­$»€ub»î +wk ¶ÔßdÎ߁z×ý ÉÝf¡ÍËîú¬ãóî0×û]1>“­ç£F•é)Ò\d7KheR«¨UŠr:[Dáòx%2Q5I%euÊè¤aYI+£‘tÒJ’^ü%Ÿ(G-÷¸i÷þl \~NúSíyäU¿ý“þ0Çß.FyëÛa‘ÃM𔋵d»CPq d»”&¢Ó؜ʳL,¢Q¤ådµœJÖÈ)­ŒBÖJ)d„B֋Í$SCÙ ÀwØN»Êyߧ6×Æ®Ó6/úýŽ> +q˜êôëJˆhMIîlÈÊm–£ðµ"YÄ+¦qªËÙ &‹WQ%‘+ë¤Å•mò¢ÊËòÂʲ¢ +­”T®“Êõbs@±©¡ÂÖ¶‚º»@³ÓžEµËoûÜ­Ÿùº-Ð~b0üÌÕÞøð‹ê䤶挥2'‘ç—rą• >•UÎepKªyÂB–B‚c^å3ûäX–VVÀÐIqUz1þ >7Ðþ±ˆí·åO;Aë‰ïºö¾tûþé¨Ï÷¿Žùÿ¨†zöÇB;»›~ICț¼†¼F-¡¢LZÊ,Ó8G€åKÅ(^“4—×#ËáJ‘]­cØz‘9 ÄÔ@·Y¤ö›A£ýÐî°ë}ßO»_\;¹û‘ÁÓê–ÞÏnäz˜GßPLhÛ%¬®ž%lÏƲ. Iå*\Y±²˜Ž¯«¨Æ(ؼ™X˜%m§K»$i²k’ ‰^œ-!øãBs@©i뱯 +Ó?Õl·u©ëØö·ûíÏô?ovµÔßô9ªÑ†¸wŽD«†Î%HúS2ª{31ÈÂâö| +®µˆ†n)c!š˜5é*!/µQ)Hjì&ª†…I AªÂ €Ë |sÙÔPsp¨3ÝF›í¦…>›M/Gl|tûĺκì¾>ímÛw3È­U¨¸ÇN‚Óӑ¥ý98üżbt±,»‹Bƒw2˜I‚j˜ºž¯Vsã:†L&9çZ&9°&óÕÔÀ·^ MïÑa½áݕ¿ÿíɤõêé‡vë´Oî¼ëeÓq'ÐEy+Ü_hˆbhÏ'“GáÙøDzCȺB(kÈÔÄAzE¿*f Ž5ÐΌÔ0"4ӌ¨Þ)ft÷ËPnjø´Xû±o]+o?سBû쨅手e÷ã36Mœ$³Poö(u +vŽ0™š†žÈÎÉ2`òRõüy=¹0^G/‰Öñɺz*T×N Ók¨¡ã·©a#3åÐᙠ+sÝr%¨Û¿ +¨­V¾»ºeùÌÝ Ë´Ï÷¬œ?²¥sÎiŸê™Ç1ñߓ¬ÇA¾Ô‡a„ñqèûÉI™w3ÓSY*v†œ5Ã(€Îð¡³õ„àY51讆toŠ4ý¨0xòQ‘9€ûírÐlµ|±ÓWӆuís‹¯^ïY§~m»³á•ãÑKwæ¿|NQ^ùáç#B‘óqÑés‰ç’æғæi1s¸Ìˆ¹’ìÐ9ZnÐ0/GûÏ·`üæ{ò|ç®åùÎßÏó{úcn[:6-›º¶2vk-äò»oV´÷ZÔm-…FÇC £ûq²Ñ÷Þâƒ4F¥c͉ÑqÆ´ø(c jÄ&†‹Rߕ¥ž}ËLó{#Èð}£Èôù½9Ëû÷®,¯×W²Ï¼3 ¨, Sý«!×ÇVCúfi´}ؼªîþMüG¬è‹N‡K?z8à–üOæ.{—Âý`Ÿbc?ø[BD/b¢>býÿSç»P™àýoö9¯¿„°3)Î{þ©J<ý¾#Éã}Yw:W@F4« ÇWAZï­Y¦Û¾æ‚ý[hÀΪ8,žvàë˜ +]Ô#ÄxAÌ7¤ú‚Ì€³èòƒ}@aˆ ‡zZ˜`CÝ? ÂO-É"ܖ#Ý>6›5Ú·Ò;²Ò2µ"{·þ+øvM%°Þ\ ì-±Àyp·I^vqàìñˆÿ2_gQM¦gÇ9Ž=Ç¥=Ggè¨ã>â(*(¨ÈŽ¬²;²H„„„ìd%| ä ,심²‰ê@EEœRµVOU–‚ ‚0Ž‚l*Žöéw¼o®{ñ»ÿ_¼ïó¾„;‡CŒÛi zC¢g нýíã|_Hõóù)OÈô÷m€;˜Ý 0Èʃ]¡Ê¬Ž›_Y4õ®²(ùÊ"6¬ÒÀö5p`ƒì63Àq' Ü­ðàc‡~„3‡ƒ!Ê>Gý þ¸P¼€~Â؎Àwr±³+ ..€º:ÊÍrÜN@¾»šuᎅEùc ãô*‹lظ +­àÕzÜHûMQà´õ xì¿Ýþ²ÇÂözAÔ¾“€ßïDkW p†¤ƒNÀ8t8‡@`s$¶Ç@fkèa;P±­Ylµèöë€én "¿b HäQÆºˆêù¡…±Œoc.᮳cºÙ‹Ñ÷9 Ñýܹè1î¯1“ܸ—ÜÑسþ?ö` v뀍5ˆ}w²äG!¸Bj¢/ðY¡À‘DÅ}¦éˆ¿S +È+¤³Ô÷ñ5ôwqŒåØ桍½ˆ»ÁYˆéæ.Äôð棇x¯cÆy/q“¼1Â4o(v†7÷¿kHÆx®– õÞAûAn8ìx‘|Aœ +‘õ“Æe=ä1ùíıô.êóŒŽ$ó€³{5p°¹Ã× qÝ +&+ȶü0ȋ9 †ø€55l eãæÔ„ßÄJÚtJ{’UÈK®?Mj>¡´"ƒäkò>ÒíŒG¤>EOâsE7åڙôý+í©ò2Ý<àb )‡×ƒâØאãòä{ÅA¡øÌ1(Šrû˜ë·hH<=«fDÏ ÂøH:í™XÃNÉô±KS2jd¿Ðš2îSBïQº”w)½™ÝÔÑÌ봑¬6úHV+c$«‰ið°í:ÈÄþÕFç-Pä½Ê¬¡,ÔþSY„Ër Þg¶€2m¤GŽkøq#(BíC²8Äzáý”Bé]NEz7³½•Ü’ÕI¿¦ºN¿£î ©/3†ÕÍÌau#kX]Ëy¢2x»VƒèÐ:ȶßyΛ¡Ôk”ŸÚ•Á‡?T†9¾­ˆ>ùk1`¢0)쉑Kx¤’P{ +Î]D#ú›Ø„t +J2:xՙíœ&ÕV›¦•ù³ö"ó_ºóìëê8CÚj‚7¬1R°ÉÁuØÓ² +œ6ÁYÏPå»÷sM ÍÒ¹½>÷×Éj‚ïèYÊéÇù,BOŽz;[ÆéRd‰:½¬MR h–g7óë5¼V]=÷†¾–{__ÍЗósʃºbÁÖàc ÒkA‡í½ENßBv?k¼÷|¬ó?0ßj7Óá8ÞH89PE +í-aàoç¦Poꤜ«Y¨ø²B#k–å¢ ©¥ÙçÄ5Ú*a³¾\pÕP&¸k,ö +Eú|ñ€>O<¨3çKb½ôXC‰ãŸ¡Êm+Ôyî~Þoߛæ`›©–°££b<Ö&„ü£œŽ»UÈ¥\5Š9—´é¢¦¬lYÂ€VɋTgÓ*uÅ©ç ’6cž¤ÛdJí3¥ýFƒt@Ÿ“6˜cv®ùþµ`°Åö^GK¨qݍ;—š}¬^] +´žh;c;ØåÞÛH é®NÂ]/eS®ä Ù ˆ¨V«”UfëÐRe¾ª ã¬Î$¯7èe—MZYW®Fþ0W-ï3ªåý•|@oΗ† lÇ1a ؜ªuÞü©ÉmÛü%¯]ÓíþVÏ;B=ºévïB\pW-%¦½‚™Ø\Ìg×åKE•R¢S£y*“ʐUªÓ(ϲѓíÌEÑ_0}&í7¢Š½9 ÄÐÖ@žÍŸ  +›SõŽß®\tùn¶ÍcûÔu¿O:ƒ>hpý{+!èZ#9úRM2¹¡œÇª* KòåHž)ÍÑT*m‘N©®6¤«šM2ÕµÜ4Õý\DÕgB²û²¬½9_2÷®›?Bõñ pÞÁòÝ%ÇM¿u¸mžøÙwËÀ­€ÿ¼îÒuØÖLŠºÐ@#ÕÔp˜¥åBA^ ’–S¨Tü—Ï:§:ßã8þ³·iQªi£mŠŠlY"ŽÝYÇYœÅ9Ž}Ï^ãPd9(RÒ6¡Å ê–D©)L¥í†I3ƒ %Í8‡îÜ)Ûûž¿îüñüûóúãóø|¿'r2$E9)yçó¥W âro•¶?(}S—Ó‘ŸÕ) âÖ© CO§¶ÏÇ¥]‹ðãî%c7M–5Y,íi±Yñê!iËãF²yÃ-_RM-Ï»¢RÌ?{9,¤èRlŒô|RRF©$5õtÖÑäâYqE¥ÒèÂËù…7  )¼É<ޑ×) â Y4P¢¸SFš“5;Êî/x´W³û©åòg-ŽÍÍ^f7ï2œ®ÝâÒ.Ԋ¸ÅU!AyW££2*R/}8éBfzì¹üc¥%9¡gÊ¥AgjóÄ¥:ó‚NwJC‹ºrgƒECîzuœÛ6W·ÏûzsëüáæmsûÚw©¿~a®ÝòäÀ¦†Ç¦5ÍôeJÉmNÁ qæõȈԪ¸¸Äk‡Rb®‘„WH•Ÿ:&*»”í_V“Ë/»ŸË+ÿwŽÿÅ_rDgßfÏIkU¯«†‹[4Pe 1vGO}°MOµ»Ó@íٛ½K›_Øo¼ùÔmϕÚþ³Yž'î ˜Yw…’úðÐÄÅFÇÜHN«M?x=Gâ_sò·úb§º:“Uݔɬy•É®|—É­˜¯RA‘b/+ôÕ¦êtUÿ|¸J¥÷Í +¥W¿mR}Üm²øN§ÝúªW®ÆÛ)6'Ÿøºå´ð|Òð’„ŠcîDŽ…6%ňÓâw³“ýŠ3ï\HeÜ©’Ð%Þw_Jè·{Òµ¿§1®Ï GV(£d2*uTþnÐVîy¾€xÕ«E´ôé«5öš.¬ýÝvmy·³áéN²¥ô5ƒ”þҏ’Ü.bÆ< á‡>‰üœÊo“DrZ³c}[‹âè-¨­U‰”ÖÆ$rÛËDòãþ$jÓû”Ù {™.¬TBí2¥·æ/^Ï#.SjПS3°giù{ݒ>'ÃüOó£¿Ñ’ßqÜbº…´Ð_B˜]Ñ\~g¢Ý‘&ftä{wœ £t\ ÷ꨎðèlŠtïzáÞ9éÑþ)z68±D W–oæÏZç?uÎ#ꇗ«T ,¸ôiÏÊÓCÖzҏNFé<,’iöQL— ¾—°?ЛÛéËìO`ÓûS¹Ôþ,W¡Ð}àœÈuàšØeð¶Øy°ULúÐ+véûSìÒ;3œÕ$~­S'žÞÓ šŸj·ÞÍ#*eß©]”o^T,7Y+·ÑO“;'Ê=Ì#e4Û@ӑ/ã¹rdbO†,œB“ô&ËùxȏúºÊóY¤Ñ¶ãh™ŸÃØu®ýX#wÿ—vžÝ— +C3ê¹¢L<»­FÜ{¨FÜx©A\ÖT:÷ύ¢¯Û´²¿š®‘|³ÕO'íŒw7S­xã [Öׁ>!r¢L„:{NF»ºN&º“&%ž¦²ÉöS…»é³T›éË´}P<4ÓMt«éç +/fô¢V™¸wW•¨kS%*º4ˆÒ©ÅÊÇ¡;÷ µRa¾:6Ãp`«®F~ ›0àcFÇÒþÖn´uF¸#ÚÛ#ÅÁG÷!×É +E$Kœs¶@…‹9ª]ÍÐ0«û·”‰ÚÊDù âT‘eÊØ8çv,ŽÉÊ`X­`¿ ¤ÍÞðØîÚN70Iàî>¡É~›Ú rï>ę["ÅÂé–fȱ2Eá>œ±Þƒ¬w£Òf6uw•ˆ²Ÿ ¢¸‹ rþ3W)˕¡«Í Ä0Òâbï +¬WSà ã— $xé9À[ßLkp·XB¸ÕAÛ̾ݱ†{´c7$;ŸC#äí@±±!ÎïšMùOŠù/ âX/A¤bÒAh)c¥Šë5˜Ø2Ÿ +ãEî0Ó"ÁZÛ+làò xÿÈ­Žj=”ûœir›ß$ù5w«ûÕë÷ ù/îU΢rèc3úƒÀ\¡¶Ë嬃hòD1w!Ì߁av%8Ÿî?)¬b|ÏùÀ§ÜôJ¼ëØ Õs¦©Í~S”6î$ù oÜë=ï¿äO¼QÊï3MƤòþð›øŠ¶¢Ad¦‰pmÄ:éà ×fÄ2ŒÉ·@H°Äq$øKÜÁË¡€Sä æYeLøT²§éµ~S´zîµ™7I}§t ¾’_(¿h#‚t™ !üÊõŸ ŠÎNuˆM5e­xÇuHð،xº1b¹´Cp ‡= È¢‚{‚v)ÌKìiÆ5¿)ŸZÞ¤w=‚ö@0A}êÿúNø7åƒPFû,¢ÿ`ȄݾrѦ<`&è©ÂOÑl¢‰X+m$9¬CŠ›’iFˆg›#Zd‡Ð“= Ì ‚WÀ§„5ÍúÁoÊ÷*o’Q+˜ ßñ÷~(üF{.ú‡Ú0Fû0LÿðÞw$àsDüš% lgËgEw‡:Âv/@¼Å2Ú¿©.úøžb„Öÿø®Ï°¦î=€ãl.R«¨-Õ:¨{R¥U¬¸p#V†$BBÈÞ Y$9Y’$Œ0BŒaod‚ˆ¢ (PW+^!,EŠ^íµÖëÕûïyú>÷Åç9/Ï÷yþçwÎù}øq“zPù!€ q©ˆO±Æè( úCTö=¢÷gd þóW o#ˆoŸ_F¼ M"æˆ#Q/IÃѯȷP¯(7bì¸5.³Í 0w~áýB~`9PXT?ú9â; Æ<ÒqÀä„ü— +…¿'jïp1ÿƘ0oÐE¸×¨*ü«¨Fⲓ<‹è£Ì ~¥L!f(#Q¿Q‡P/iý1sôkè9ú•Ø9†= nÀmqœíŸ©ÿbø5Ð_ 4!ۀú¼?PÄìÿ(Æ}ÏcžyËJ MKB¾$¥¡gãsâf°ü³Ø2ÒdLeÕNµE÷ÒF£ïÓ£žÑc~cÜDϲº1³¬ì vKœ}76¹¾¯'Pì^4û—Ôc«Aê™-àB¸ßǔè} 7bjðŸ6Ö#§èÚØqr&î)ÞDÁQa«é÷c›™ÃènÖ ú.{=ÁéÅÌpº°3ÜVÜsnCüsnÞ>@XíÈ\þ¯Vïò©?,† ¼ñ“!tÇ»4äÞ×Ì¡Y%éÔ´”jH#uìz:~˜’C¾C´ÐoáËX}¸:No\{Â5ìMÞUì¿÷Œß?ͯÅOó+‰Óürâ3»þn ­w’Íó€f×B`Øç ²áÙÈ9µþ½ñœï›¬HÿY}Là”–pü©Šuö¡Dˆ(0·9ZÂMFõ5ŸÙM.ät+yí„&A þª° ?,ª'LŠªˆ“¢2ò¤¨ˆ2%´þ€ø `¬u²Mà‚ߐð%È;¼ü“éĚ·¦Ísyá~ÓÆè€QC|Ð íì%Ù'‘bzjb7ÖÆ2²›éæ„zj© –R—XMþI\Iº-)'KŠ¨b mB\@ŸḨOÚHß8ÖW ØèÒw~r–€‚CËþsñ¨ÏkËé 3–s¾63ÒÿQ6æÈÝ4rÈÍ6¢[!¶KÄ&¡–~™—Á©æäó˙…¢F•¤Þ"½D»]¤?L ›4—9.5²Æ%Y¬ ±=7páóHÚø`Ø1äï],ÞY1W|rÍTñÙMO¬çwå£÷eCº/0mÉ|Lƒ"ÖHÕô +Q§˜o\J¸˜hæ”Kóٍ²ÖU¹‘}_žÉ“¸6HϵIÓ¹ã{nàù¸€ä î žOó¯O…?|ñ{ÉÁe/ʏ­²U¯{P¶ë¶u¨''þL‡Ù KÀT«ÅÄ2…’^é¸fq¦ OhgóK  ^\ÏëR¤ñ©üQ¹Ž?&Ó +lLjüÉwxÇѬwÆížÀò݂Å{ÿ«"ÐûYMв֞\;TêwÓ}°Ë„ nʦDÖ¤³cËtB¢5YN7)S¸92½ Cš'NÃE¢EŠ¨C™,PªGI‰£ò¤Ä1YR¢ ²PàÑJ [ïr¿¬»çÿYöý¹š}‹'}ùKý±5Uçvö” ´Y°§/ç‘Ηg1c­é|‚I'¥SÔCRšà‚Â(N‘Yd*¨R!‡Z•2¨_ɞ*!hTAc2™ÔÙ¨pƒx¹3H]çò}=@‘ŸçÛÊ]ó_ÔïY0Ö¸è^ÓÑÕ}µgwt•# cOU™ E¹ttAVÁ¨Óô©JŽN«¨S²ÄrµY&U•+UÍJ¡ê†Jô¾ŽÊEÊ1™Haƒì´UÎ@ú5¼÷ÂóiÞêþ¿Òí¯kwxN·ìö|Ò¹Çk°5ÈçzCÈö¶êóûëÊÐ'K­ñáÍԘœ<^Ÿ-¢j3äì$½†/K5ˆu&ˆ¯-Qp5 J¶æš’­Qr4£rnò˜,AmƒìŒ•Î@7dÀïìK[Ü>TluÙ°Õ}¢s‡ûëþ oýtxՕ–`ߦËû*«P'¬¥¸°¼B2Êp‘¯5 (ª\ˆÕåR' ÏGÑ&×w5\gZ×»Œ^ßì<|}÷ç½ÝW´wœÞVÛPr9꘩{.³œ¥+aÄ%òÈR‹˜!(Pq9ù„Œ<£˜’c…ˆ952|N§<>÷gÞ83mR²aÜ.°Ì $åráç¢tóï >ÎSWV:ýrkµÓí>¿ùW®XÞØ}rKEGèK 2È؀9›ZG@$UÓb¥\‚ TDc+Ø´B-hÍâ.YÄK•}©6(E[Æ%XÓ¸$.wBlÀ÷×y;ó +§OU+æÚ¼Gû½†î®r꽳ݳ­ÿҚÇ7õüèŸÛy(½¬n‰€)(A=Ç®’¨52:¡ZÃÆVf$ +̂èŠJ²¢]„¨¼#Š¬˜EO‰PÖ)¡=@ò…Ð/qÖ¯ßÕ/qxÜãépoÈÓ¡ÿÞrÇΟ}=ê¼KŽ®+èñ3ôF¦ô NȺãÎ :ÉVMiçãð­ ӒLC5˜ˆævDS7¬©Ú<›â†]~žQmP.rF/Pîåð¸mžÃ`¯‡Cß½yݏ—:6ýºÅ½âў%–ûGVg «½ ¿uDЏ fõ‘B)7ˆø^^Lìu)6úZ2>²ÇðÝuÕ䝆üc Ъh](VED$ +È*›¬²dý’/ûFI¡ +¢ ÖâŒb­Ö#ngT-.uGÜ·ºÎ0µn€ +£BŠ€„ê39½˜+rñ»þ?ïù¿ï“%ºRC]9œË»R·„¼zÇêU.y¡;w®;ßl˜`ýWâñqâþyâú-g¢á?cˆS­_Ùiç¼ïyÄÄíÏ=*³|Ë BKZä±ÿJO6>Ìbë›ó)MS‘XÑT*—4V¨Uj^cu:·ñZvc½–ÕtWËnêÈ`>èÓ³~íË´[ÇÏ9N;W/9çî¹'ž%j:f8ìéð³­#Âmã«ϲ—Lßâ¼àüviTv›:^ۖ™œÖšÇ”·.çŠ[Wó©Öïdë1§u—„ÕV#e´‘¥¶ß´j•¥´¾“%?PØbªv$šk‰«õ4¢î¨mv!˜&Øí2yÒ¶šü]7tGº۝8«¨›é›×Í Ìì/Ôt)£]º8IWN¢ «0™×µ’Áé^ËbvWrR»·s“Lûy‰¦cü„?øñ=÷¨øž*ÎÔË·åß âú/ÄÙâèm±ï‘ ±ãý$»ÍÞ΁ãKÍQîËÌ ž¹æTºÞLú¥ ŠeƒŠPÑ`F80+ŠcÉ_Ä´ŦXJãU$& U%Å ïJŽ>”=r25jä"#òC##âÃK›nÕD]=qäš=±§É‘øáågDåGwûï>ѝW!p|!Âݲ7=É^Jp|ÄøRùq¡^À„>(9!‹Q’…±( ÆÆÈHüŽÝÑa¨YŠ“1!¸Œ;±¶ÔÿBG.Äî;QõȞX?2În ¦ÚÁÛ)~c3:Qè/¥Hœ&à r"ïd(|¡¡Ç!ó/1ÈñBá¼”ø…¡Ì?­ÇÈTúã`ŽÏGMGë bÏ ‚Øò Ö¶ÄjŒ·+„›}<ÓAw‘#`¬ 'p3‰ÅnI`ºÇƒœÑ´(ȦG@=# :dÏ ÂRÏÏòïy¨˜=[¼éØ9Çû}æ Æ¦½—­óß·¾ÿ„ V˜í‰|Œ³Óa¢½S„ðtä‚—D„}‹è±ÑHp GÊøP°'ƒÿň'úC>i>ԓ}¡Ÿ<9S|Pà6%_z¡ÌÝÜ=P5uvØ1Ýü Ä¡ÎP/r….É ™Ü™ÐIéHÏ@Z^(ä%Q| áæDðJ¹/Ü&8ÇX`ŸaƒÕÀó:Œ$ÏI¤¾á!µ÷aæ ²†x½ìa²‹;Â{KŽîÿ¤!ÎȈr…a±²93aÓ¡Õ@“ +eq¤åqýu1ÛSÀÛËyˆn-œÓ\°H°nðÀläƒÑfÕÅÿÄ裆XƒT?gˆo"‡ù¼aªÃHè i9Cé +c‚rY3aÒaH @FVҖECþm<$›’ ü1Ôn&xÙ k¹àž&Áiàƒ}ƒV3æ ëêš#¬~Á{Pði¼æ Ú©aa5, ¤>. Aè C¸+–Ĺ!Ÿá<Š£2úÌ0¤DCµ:²õÉoe@XÍu€ ÞQÈS|pÏSà\€Ó(üÄn°»Dö{Ñ;rPô†o½ ,â'Â!Éï6@fÍ ñ§Aà cØ8ÄLÁש(äû _î£6 ú¼h¤¯L€j] +䛙üāhÂÃÔ'ê¸à#¿NôwYŸŸ3ò‚Çaù¢)X‘<Åä,“úa©&Fc42‹Q–ò)mkD±’í¦,’B³øgñ€ð´¤_Ð íܒ½£ZäÝT§ü OÖ.Pü&6+%ƒª_eÕ- Ÿã•/ _'E‰µë}“4ßp¼±R4ËÓBoˆþ`,LÊ\jÖV°ûÕ[x½ª‚Å~±IvXÚ%=!+9§x-¾¦ì7+_Š_)[ÅïT-’õ=™YsSnÖ\V˜Ó/*G…5ƒf. 9sPlí8¥‘“P–øÊY^X#ðÅ*EðP‘.r`i^|onIª)k-ç­®’ÿßôEêÝҗªƒòvE­ò¹ülÚSÙeõcÙM‹ì…¦Y֓~Gþ>ãªò½¶Aõ^W—Ö¯;«”ÞÐú8"߇†UcPñ¾wGÃëøs-å²}«5á¦bcÜëÂå)¯òÖpÚ³×SÏ2«$¿kwÊ[4ûUՇ5ª“÷•çµw•·t·•Oô7T]úKª¾Ìzu¯á”¦×p<½×p,ctPY3dz;¢ÐÚ/Jý?GÅ Øë†Ê”C›È9}ëÅ~ÝkUa¥†˜¶ÉO¾^ÅiÉ[+h2VJﶩnë«57µ×^KÿYEsÆpI}%낺)ûŸšÎì3é=Æã=Æ£Úc®'ûþݨ6ÛÙ^Ž(²ö‹òùŸaS˜+6ÇLþX•4í}ÛËô7oçFyPë:}Ôo¥K’šVqî.[#¼¹´B~5wsÚ¥ìç {õõúš¬³ºÆSÚÿÑ]_QM¦iÇßPŽÊXPÇÆ2*:Š‚ +‚Ô қR éɗ’ ÐIh’¡%t!€Q"ʂh„ãx”wÇ#IY –fçÛoö:^ü®Ÿç¼åâßOèŽ×»âçˆí˜ERSâ"±»H¬ÃýN¨ý +8ÙáïæLAöȲ5ƒ…Ç,á2§õ_*\7ÿ»Â{û|ùŽ³%a?<ˏ=õˆ?ÿ òJI ¾ÃäEÞ¢Ĩȥ˜¢ۅoÄwà:ˆ­Øäfì0E¦4à(²¤7”*ü²„°HÅÿw #­•jcç\ —Ø[À•§¾Y’ºX-Tylý­Ê×fº"Øn¢(êäƒ<¬Û=Å·?|#åjd7+'æT”ÐJ­À5‘k‰Är¡‡ZC¸K«&<¦K‰:Z%IO‘¨¥ä7Ù8é+ê6¤9‘³(8°.?b¾\å°ú­ì̺ù:·M/ê¼·ý, °Õ”]r`\ûsH¾×3A]iœÈ¶+üØ&vAB£,IF¯"I©rj%¥‹^N€Ê(ãP)õ5TLÕх4=M@[ ~Ì¦#½™¾Ãî3…+™}‘·Xlp\óJá¼~ZîþÝ#™ÿÁ‘ʈ꒸sªB<º+‡Ԛ™)¿šSËÉM¨J)ÆW²Å¤2f=µê€P£zÈÌg¼dä1´P.SGÏaêiª!p2›ôo;Ò:È•Ú­Xª?f®k:a1Ûvz͓f7ë‡õ~îV…ï+9§,Æù´PsX2^ZŒ$=+AÄà‹S+ȅ)µ´¼äV(›­bòÙ#,^ò &/YËÈLÖA™ÉzÚ×ÀXäØHóf}g—!ÿ´ÆÖôüðŠ×mG͞wž°œhsÝ:¢¸° 6ôÇ^I´K»(Ñ[^L +”0"Ĺ©1eY¼af>?½ŒœVMËä63®rz™\Î?Yî BËàr´—££s9zš!p2;iÎk#¸|·ñrÝ“ß[þaò[×!Óg=Ç,Æ®¹l¹×‚Þw³1øXWÍeçf Æ«VDÓÃË)ÑÂütL^Nn?«„”ΓÒ8™rFJF7‹q—ÅÊxŠ˜g°3´PrºŽž|UO3& ³S¿5‚ó·¢`±Ñ—ƽÆúŽ}Æ/®0~¬²_5ªtÞ<Ðá³··9ðh[C䙆šxO©$É_TN –²£r‹Ò0µ¡ó–»\åg'í9YÚåšßŽAóZð-œÕ˜M«¿O¬ÍÁád%LM59¦º…U}ƒv¹ú!â5Jº@©X Ä–¿1f¯GÁyëP°døвpÄ.O8öûó0vï9˜´ßf< smOÁÙvÿc»ÎÃbÞ÷8€fZˆpµ(%-Ú$TÔ,ÍÚ,5ÓìK3Í4íëHDuQ¤P"KٗdéZN<¸9–ÇÅå\—ãv²updi“ä}Ïý{žïóú>¿ç÷Ïçýûþþù¾Q㊆€ œ– `´á>á7«ZN‘HM‰ùí$RåC©¸Ã†´ãGdaªî”øÙ+2Z‚ˆ±BÐ'pÁ™Ä‚p2ñS£ š¾úáHr]ŒŒ™¡°Ì +Áj· ¬›€yhðôCÓ_œšãƒK^Þh³êàybþ5bþ=©è‰´lО”†±# p¶QÁ•,Á[üí8XàG*èc–‚íÁ¸E_ùOó¡ãD¢NòC®³VNöš)ž¨šêúi³Ñ8ÍG§»á„U;ۈù·‰ùÿ&‘²_’HfPHZŒ!IñÓ!qÌ"ÓáE‰„¿mBì"Ì~>"íÁpðg¤#½!åù(OhgÃèè†ôÑ3aã‚ÕNÓQî4›ÇNÁBÃ8kãC{¾-„!v,t€’ê5×J‰ d ¤ù@T~Ù|p7‡‚µc1˜?‡#úHÍKAoí*áV¨© ¾"tÓ@í' Ó@ìƒ P{™ }dY¾7Ü` +bƒí u€:Ò ZŽ34b(µ¥ø@¼,¢¿…€¿i!¸ÛÃÀÞÖ¡%`žŒDô¹(0~¡‚ÑNýáô¿}„ïôï â‰úG6ï9Öý?CL ’ [(B [â=Ë q.Ш= 4ûBšqq„‹ÀßÞî%àˆûxØg¨`]¢yæ=¢;£{¢‡ˆ5Àã‡xÃó5,k 2ý)ùÛBlÄp'˜˜Î0‰\ Wx@cô…2;ÒU ._ QM;#ÁßÞ¸Ítp[à\û6s˜ýŒùÝÅúÊþÂêcc~æ€õŽöËpþË×ç’çGÒÏú{˜ÃœÊ˜„TÁ ˜e0è}¡Í‚ª ²5alZ‚¸º(ˆöÐ~›ß'¢‡øgYßb.³cn²ûy8=¼×œO¼Oœ1ƒì·1àv +À{*DÌ¿Dà[‘!އ·-Ló쑾h ²h‘Å›ôøÙHÖú 1%:Kè°º8|H±!rPº…6 ÙÉèïcöÆa‰=Íù,ºÀý(¼Îëþ“÷^ø‚×%ìæ½~åwÇBx/¢[bëëE†Ü‹=!ÕÏ9¡£a‰š grãܑ©òN6š²Cûõ…á=ÚµQŸTUônEó/Ùö»øƒÜ?%'bºÄçø¯ÅW/ÅwâÁsñᓸØâá¸Û’âRˆ¯È¬C‘AåI†Éƒ‚L;ä‡8bå’ñXɜ‚á¬!‹|n–>àsZzès~ÄÛĒ¨7 ѯ4[؝ªÜÅ>þsùQáSY‹è‰ôrìãø_ãÆ?ߓ¾ߑöÇ·K‡¥WäÃҋŠaÙy¥uÏ!CçNF +Ñ;óæÚ¢0xŠÃÇ¡„á™Ø|Ѹ#ùŽi{òKcmJqkjobMZŸ¡:­Oo tÄ÷gw%Ñ;×yª¼È}µþ¶ïw,pèÜ>ú·zºóÝ­B÷›äþ¿”ë/M¡6小­\!8´¼D¼ß²^¾7§ZՐU¯«ÏüÙP›q̸%½5©:½=iszGRUÆgÓÆÌcefobEf¯Áâ +bƒ,g¬":ïz×ÄÕÃæË_Jמ Û獡#ì¢Nº¹ïv¥F:¯u£náérsÔ±ÒLvSQ¾ ±pµxWÁZy}þ&õ6K­®&w¡*ç°©2û¬yCöõäòìgæu9ÝIër¿˜ÖæöËr{­A"ñrˆ¾YLtފ#¾os³éÞåeórŸùɁ`‡»{£&^ßɛu±6ÞïLµfáñJSdSy:«qM¿¡¤P\·ºT¶ee…ºª`KBE~Cbù²¦¤2Ëis©åjr‰åqòÿؤϷ&Ó,ãç%!Tª€€ ; (]@Š”Ð{ï:!PŠRƒB( R'ÒDD H‘*" ˆ °ŠºŽîêŽqwöšPagë™÷ȇßçû9ç9¼œß’‹s×ÙÅ9I$–(˜¤BÞãVK” ¬S%>žÐ ~íÒ"^õéˆ=ê7‘¸yÆ^a¡ÃsÇÔÉ`ýÑ&¦Eÿ÷‰Œ®šT·S•Y¾ÍåùAü’âðÚâʨcGùqå…'yÜ3좂sœÂ‚ùnÁÔî/.wÍ-XOâl°DÁde1Ì%ßP®D _™øý”*ñs:ñbhqИv£ÏN~Và¡qþt Þ`ë~óî¦xûv>ǵ¥6Ç_•TSq4¼¢üïÌÒÒºØ"މDn±€W4ÌÉ9z)åpÑ}Òÿ8ÙEïÙÙGדrŽl°DÁ²¯@`åVÀFExß¡³JðdT¸=bH»2`#7Õë¦>"ØÝÛaÖÑk{¢‰íÂ?~л¦>;°¢¶0¬¤ªŒy¤²&6¿¢)!»¼3)«l09£l:å`ÙÒ9éeëìŒÒõ¤Ì’ –(˜Fî Pž¼yÀyX햅—#Òð`\ÇôÅ/X˜pQèõÓí„™ž<cÓÐÆr®9‘æUÑt(€×PZø=/2¯®*æPmC|zu;+­êlrJÕ'¹ê&I˜Ì©Zg§Tn$¥Vl°DÁt²_$ X' Ú¤áE¿¬Œm‚Û“Jper7ujÜRzdÔYµgÐg穾P“Æ3QÖµ]‰Ž§SÀÝN€…A&&Èþ¼t.‹CË#I¨.Ç^h‹ñž›Òó´—Ízæ±-õ;XO#vÆ>‰Õc>N6œn¼’k°Rlí³rÌÆk¥ÉÞ}¥‹áúxÔÁåñ‚£ó“g.+¿98=úÃÉñá7Q’;¸Þ pa`` ãº4Ý£AõRP.ÜF}£CÉycJOÚÊ$ ]ㅾjQÂPÍpa´vˆ¥ð:MÏ÷õaC/áa…©«oî,lßëøfÀÂáÍ´%ã?wHo, »×Ÿ­DY\œ$û—o‰Á±Ç4(^“†‚U5"kU—’ºfJg­Ùl‰YsVˆXóV^ R x»_Ãçmœ¦çÛd-÷·;]Þåé:¾ãíf¼«Ö³{ßl`ó^`h½>jdµ~ÙØrãégc‹÷"Íô t^hX¨x@@á¿Ä!ûƒü°`ÿ©C‰ýӘùÑJ*䣃tÀ'w9ŸO~[=>‡*¹~fnsúœ êð…³ÝîK¦ú¾¯ù;¬¾–jZ|­ûÎü[«–é·í=8¾ÓtŒñ#Š42Bö/’ýkdÿ@Ás€Ìu:pPâQ•ˆD-JêSýьæ…6t7tÚ䌞[Ð_ÚCe÷!SÎ +ãö"g«f(š`¾’–*`ŠžTݍ=ª»ðœš.În×Áe‘ä4.ýÛùO¼Hü"Q(¡¨Dø£†˜'êP\Јê€æâ¶hC³FG t£›¡}Ja¸”FKé!kÓ.<°y'ælÑÂbé¿aµŒ&6Ëj`鬜:Ž‹Ô:7¢Óictì5A‡á=Ș0EƬÙ_l×WXÓið?M±1Š2¶qäс€‘J$¤Þˆ„:&$ôé*eQyPÔEY+:긺ë ì¢(«¢#ŠŠ Î~×ÊÅïúœ÷|ßÍ „G ÜE†ÀíòÁ 3N:8ͺƒã´;8OzîýÀí@¶5š­!8ÇÕøÞ&Àc˜G´Ấ®´ªÚ +|5;ÀGk ¤:{ðnq¯ã»Áó´#xö9Çgð¸í Äã€8†ÓßãfˆÓ¸/à<…æ ù.o½ÀuÜû[@²1?´s‡!píŒ@ˆ3‰§ ˆif ào^ˆ9°â-€‘j þy;Rf¾5@nrŸv' tR/ÊÒï2ï}ÃeÎû¡ë_^£®SÞï\?zqý€fLxÞ7$À¿ð½Ï>hš•p¬ A¸Ã¤N‹AF\2ʐr6€hújіÀI²†€,[ íš÷¯tœ£Ö;ÍRZq3~.Ó¾g\¿ø^Ø3EÀ&ÿŠŸ$àߑßâßøNá_“Áí%Ï|Áý +Ÿ,ÈÖèÛ @`iRkCÙ½ÂÝV@8y5„l€ ±9Hä–:¡Òf†§¶›fìž +(wúĬÁMқ\?ÐÚñþ'÷¾ó?ëö–zÙí uðš:Lów¥~v¡Î{ SÀó‘?xýJ¯;ôoe;ºêºÔ5C¶B„ý"ˆÁ/ƒoSˆ¢¯ŸlþKlñYk3)N¶Ÿd;¾åáÆ9•®¯Øuøÿ´ºtž3{ܟ1þN|ʸIü/ã‰ÇïŒWŸ¼ÐçI÷èàs‹ >@þe@³Ð>ê™AængkJ—¥ ôX©ÛO]û%–³i2Búӟ¡‘Ö¯eìǤ鎣â—§Â2üøՄ!nñ §Ýó1»Ûë!«Ïûk€tõÀçkÌçkÒ÷:Kç7ÀJ?(}\ œ[0·êƒøG}EbÑ=l Aåd<ŸL0™R‘×¼?ÀÜ8/Úò":Ìê©<Þn($Åé_AÙ{w…µ^ƒ‚fÒ-þqò ^ß5^?e€{›z…;Bíç½ó¿À›¡õñ€Ö#Z·h] ¶¹>HQçŒ@[ô!½MÚ®ÅÓé{–½W{­zê¿n4‰¿yX)Ûþ(6Úî~äç;ajüÍà<âµ ¯«Ò*Ÿ+õ¾ýâ6êEÑIÿóÂ>ú9á?½Ânj3¢qf·è ³KÌ10Û$H 0¾<”_†ú^ ꝉhŸ4 ]–­ÑÇ\ܒñ\w“Ñ,_³!5{ÓoªÀmw”rûqûqQÉ{/Ë3=.†iH}!å¾½²jϾ&Ú)iãd`OÀ‰Àˬã÷Øícì6é'v‹ØMû€U¬º€åE]sÿz=HÙ¤™[õ§ó­ þ<ä°èE!~鰆dú[6ó‡AµÈòZrˆÝå„܅øngcÒ<{¢r}ºåŔa´ŽÐ:Æ߂ÛX­²nN³ì·Iv‹× {Æ« þÀ=¬ãV‡§*8•¡ÀþˆP~¹™$ =ÔQï4×ûXh©ÿªÔÖp¤Üyñ£bUw +h¯eó-/©ƒìú’#{(ܺɞq™äö ¥5ªŒ~4¢& A~”]ÞÉ­ ;˯ +»&¨ hÃ'ø‡Ãçøeòy^©|ž[ñ-¬ÓƒHÔ7“PïÌ\¯§Ólқ(Ý¢÷¢ÂJÿÊ]‹î•»w£ˆºár>×¢/Kj{Fîܕ·÷XR¢gk‚šÜ´?—ZWL¯‰©dUE7p´QÇøå‘=’È_DőE…Qo……Q3‚CÑ:~A´ŽW=ÿ ¢ü1¨ï%£Þ™³û«höF»IïiÍV½ÖØ Vº™\-ó[¡ýSO¾xgWV¨S{zôÞæT¥gƒ*•|$1‹Z•pˆqXq˜U_Ë-ŠkhbO‰òc/‰scˆsâ^‹r⦅Ùñs‚ìx!„Þ!n꽫QßZƒM•}½üy6Tÿv¿n§áõjüŠþ +òºÞҀ­' …;ŽåË›³#ñõû=ªÓT>)éÔ2U>£(±”¥I¨ææ*›ي.Q†â¢$]qW¢V¾«•S¢4åœá§)u߀`”_vP¯Â@cŠMjM±çµ¦Øã¦õØ`£áÕ:×åç«IkOk[Ž— +lZ +÷í®Ï—ï©Î‰#j3I%éi”Ci¹ô¼ÔbVvr/]Õ$8˜Ô)NIC5ŽÞCǝ¼†/: ‡;Ã/‰î1êÈìn&ýK¤ `ŏ‹ÌéX4jFt¢è‘M@-ýè + aÈPÁ” ÆBŒzVÆYúa²åLÌçƒYㅘkÅÇ|kOÜbÃÁ¶X3ÁÙ±±Í~Þ&çÀ6r6ÜÈ»OúO’žG˜…6 ÅÉ DWŠ9Ôô¢¡Íƒi"”Ó½QE ŽÁÃh˜î˜Æœ ,Ü0Ûb*®e9ã·,'ÜaéˆÕ–S°ÎÒ›ˆ3c”’3°ñùÿ{¤ÿÀDúQï4H…0´)ځ§PüqE„! +¨<Q=0€ÊƪÊi®¨¢¹`Í 4L OÂtº=.¦Ûa.ÃÿÊ°Á"¢œaÕDíìCE©ˆ†Š™4TùÓQÂDU8 Ãc¬P™f‡Š¬É([åˆÒ .RìŠÁn(®žŽA‡ØÔÀÆÀSîxÖÛÉX·9ðøxG r09£Äçÿã¢ç—þ˜AæCú„Ú—ŽZ1µJj Ö¨I±Gբɖç„ò‚©8«hJ¿›Ž’*²µî\ïÁ'8(>M\ä¢øñ£'ŠŸotŒ b`”‚…‘‘Ö8ÛdÚLTíŒÊõ®¨ø;YúR6Ê*ÝqÖ~œu˜ƒÒF.J›=QrŽ‡’ˆNÞ¨äþ°¤›?(éãõKGy½Rä” àƒ…ï$èõ%”zQQÅ£¢ŽGC½Ž1þ Œ•±0VgÑñö•á€º¯œQ»f†Î@e‰;†íä b/CxbèQÞ¨ü$DÞ*ø,¿,’ß È ûä]Âß彂wòá9zõÈЧ[†¢—ò±0”OE-‡Šz cÉ ¾ L”Z`¢Æ +ãcì16Í£³\0j…ê +Ø#Ú­œaM™çzo0|?@uDЧjö*[¼>*/x}PÞô~¯|èÝ£|éÝ¥úèõBùYôß0œù< }Ÿ…¡ßc%ú •\*ÎfS1–¼wM\¦’ýH ¶Àt¥¦èíÐdrÏtŠÍqˆþƽ7j÷Cd ï½n§à]į7¼{´G}^kNútiÚD/5×D/4D¿j=Õ|ðýfØÿ‘~Rcà5ÝýÛuÕԙÇqüIDÅQ‹¸âŠˆȾCHrsH Ä’„„}‹ì;‚ + +#x Z¤Ê´êiëÒZëÔ±u´ÕZÛ>sûxñ9ç¾|Îïß|ƒ–ƒûñŠµnø.<ŒÙoã±{°`‚÷ZÈ$™ýÎÛúkT¬åÿ"¹»:-´~*?ô"Xuô9µâØ"Zü{J«ÝS¤çÄ·ÈûÇ䱓É3_“î:Þ'/:._;}Núèæ5YöM–AJŠ"KA¶ €Â5à©î© Áí*#p£ÑL6¯#-»pͶ†z7Ó¦úóÚÔJWn]Rc£Ô&ØËÕÜSÙ¥î"•Ä;£HáÏ+,%p jHœüVJ¢be)®Q™Ša^bß(,Dò y)˜¼|ÌZ)qà®n˜­3כ ÁX›)¸Øa zÚmVµ´º¬­oöÛR¡G,KëÃö)k£È«™vٕɎÂò³®|­Ø3­LV&–V™%ÍäXU?…¡š@£UwÐÕ(1Å¿!1ŐÌ(Z¦‚eÜW0Wi¦ Àx«ê6}=ÛA{ÏaƒÆ.'ãÊŸMê6ÒeKȞÜ&ú!‰>Î6³!é$¯.ݙ[+tOªÎñfUùÅU”FWœ#ÒËûȑåW‘ˆòyÌäÝ{R„’"µ¸äãÀwyÜÕp£þьÝôõ‚ös 8€¯>ï°ZÓﵡ°7È"·›f•Õi-hgMoK´KiIuHl¸Ä7IÝz¥7½QëÑÐÖÐCi +n˜ +®\÷+‚k—{'à«B>«àº®´p¾€6¬?‡7‚êË{qeÃv†…C·d]@?Éߓv>ú §e“Лb×Ãwˆî–8Gv廝îÔxwÔ{S;º|)WüŽ[˜E?rÛ/~äV迒g9Øjfjk`°€Ž¿ûs€òñõ@=a…SN3Èw1_õ3ã"ܑНìÿ³]§QM^iÀïû†@Aö’…H ,!! „  aÈ¢ˆµŠ ÇÑÓѶÚN­£ŽÓjkkGfܵ"¨hE . ˆâq´­ŠÊj«²ŠÊâ3·Ç/sпÏÿç½ÿ{Ï{ž“¹ü¢sfW/Î=¾4Ìrl•4óØ:¹ùè&eÊÑ¢ŒUûԉU'bª±µ¡r(ÆPñV_ÚÉî}‰P#>ëN„ŽâöWüùý8ÿ,Ö×9¢uõ ´º>üK½Ü~i]ìԅ“Ü‹/¤ÓçœÏa坟Ýy®DU»D˜^»R”jý<ÔhÝžhÝ.·î•é­Õ2µA®·>‘éÎ ÉãNODÆÖÀ{Zñ\ø¡êÝü¡¸ƒoO#´þ"‰V7ÑЊw´ìŸXÔN)iQÓæ¶ÄOÍ¿jr˹jñʺZà“Þ\Ì25/æ$7¯à'6}&ˆoÚ Ô7}×´G¤m:¬i¾Œ=iƒc®Œ‡ª l²ËÛ:…;øwP^…ÐÖœ¡Õ´ì Ϳ㌊Û|Q¡MDäÛ”[œ}–Íè”fËpNµåºۊ<ÚzÇ·•1tmk|cm_³blÛüԶݜ¨»Ç¸ª»—°v®ª­«üõ ?ò6øOvwP;øÏ„¶á;ðõyœ¡e­ôÑ*èpA¹LdéRÒÔ©¶3vΰOèJuˆïÊvÒuåOí*vÑt/vî^é®ê^ëÙ³ÙKÞ³Ã[Ösˆ.í=͐ö^cHz»’îa†¤kü=Uøì>ŒðýGhùwùK[šw‡@9©(ë…+Jïc¢Ô¾"©_LÆ÷+)qZ;Í@U=h²̦Eæ;ȇŠ#†J$릊‡¿pþ§KðËòi¢‘ +× ‘Z×À‘V7á«n7áˁ÷ìÅïp;¾ƒ¬8¿á]~QB–‡™úiÈ8êŠ c>H7Æ'´ã""zBJ*'T¤ü­–"}k „CŠ]dRƒ!—EöBXd/€•4øß8p¡Ü‘Ž~p֑ ͎,xðžñÜx¡5—qþuœoC(ç'u"4cŒŠ´à‚¢Á )…d $L„‚„‚ÄË.9t¤?$’\0Qü ›Â‚ŠÌ·£C™|nç ›©ðÕPÝ «}Ïfü>­Çù×Þågµ#”Ð…f!8w + +WÞ(Ï|Ä!Á‚…gñÁ5áq„žÅ ̤+Ì$a.9“Nð éë)°•BƒrŠ=ìH$$(ÂHˆ“-¥@´Ê¢õTP™i ÌwÅg­péZwlò„ðï¼!ü_tïÁ1 쨄ý‚Õb ¾v{„ý cã¾ãbðƒïh01Öd³U!$Ą’  §€VaÚ8*ĤÒ@=Ë ¢>re™(>õù/}K‡ˆ ˆØåÒØ_œÀÎ2AR]Ã`O™’!æ¨tŒùZ +ÌWR`H€ýR~“ç«E$ÄbºP +èev0CK‘q'й@Ì7ˆþ«'¨þæ Ê- ˆÜîŠr\Ã>&ȳ@~ «aƒüÖÌ—ÛØ£òö+ù{X>Ê”ƒß€8ýràöɀ7(q¶VH‚ ’pIj*$&ÐÀ9f̙ºÝ!v¥hÖâê7ú€z+¢bMDíbGd©*ýFU'9oTµœ×ª+œÕ-Πª“Ó§êç<‹åü®ÞSø÷ª@ÐóÎôÿê?óýIH䓐‚ç0‹)¦¢‚IOƒó0æMƒÄˆ_î=®_ã3ª[Ï|·…5»Ý略œ3¤ÝËÔæhŽóú5gx/4—xÏ57x¿kžðºµ}¼ÍÿÇ10½=„c ðþ€ÖŸ€.)~¤ HÈ¡€EnÙZ{È4:½M³L5yŒ$—Ò‡’Vùö'¬c½0lô{¿•ûnj¼§ú]ü^ýAÿn}•—î” SwQðDMЮ$øMÿ|úÝëÀ[:ÝÔAð8nƒÉ@ó,ҘÌäHB>î#/Ú~|–ÁqĒî2Uàñ<}ý©¹Ì·;u »3ù+îãÞ£¤ïý&îÜOØp/¡Bh3œüÕPxËÐtÓp_t=ᙨÙð*¤Ñ€ÿK_Â걺IÀÀ&ÀÄ À‚åã³(œNBQ(e¼(’:\çð¢ Ź77ǽ#g½={ ó·ŒU[ÚZþmóß7S¿ÞHù!ðzÊ¿E-É‚›•!ÆšÐ+Æú°Ëƛâºäñ9ã°Äjéi¬&"N}} ÈÀ{o®7sñY”ðˆ· ‚ÈáRʳùjû®âÄ)ís³\ïΞMÿoÞBVkN·Å²ZДõ¥°!c“èRú֐º´aÌ»Åç̇$VÓqéSmDéªìÓcYµi@~Ô<¡¨4ƒâVñJ' ïœs<”0,b¯KÄó%!dW©ÂîÁ"½Ãíùf×ëŹô¦Âböå‚R~]Þʀs³> ²Îü*ä´åâSÙßINf패ÎÜ';–Q©¨Ì¨‰<’Ñ <œqOy0ã¹jæ¨jo&¨ö`»³@9˜= ˜…÷Ýyî>Æs,õAƒeÔ½"€x°BBÞZ®uh)MžÖ°ÐB¿XRȶÎ[ȯ)\.<9û“ÿq]§QMÝiÀß$ì((H•* ‚"›ì@V,¸Êf„5@ !LK„@Ø÷°Ëæ(¢´¨Œöh5x˜9Óöˆ2Î§™NGǶsçöØȇ߹ç~zî}ÿï¹÷<‡gS*}.1UGfÎ5L%w]H҇Œ%MFçÆo‡ëŸû_{“Þ{’bw2ÞõNØfÈt)hßc£ÏQho…;à;±<—ì…5‰7öˆh~·8Úf™Öq‘›òÑ|^ŽÛåœB™¬ÒÓRßq–Â$M4”Ú2ÒKècŽ†w3.Gt2–";ImŒoI-Ì#uL$²9‰@›¶@ìa¡}/} ü(þþrÞ¾”9Á#™'vå<ÁlYes½$Îa¶èœóÅÂL· N¾ÇXžÀkˆ]æ;]ЛYܕÑڑÞÞÊŠÐ¥M“šÒɍi÷)ê´ Jër= !Õ§#‘ªw"6C’lÉÄR€‡7%xxQŽ‡õ +<<©r€ûU˜Ûò`³E)Õz®ì¤ÃLiâî Å,·a>Ûc €çÕË)õë̓´å*‚u9‚6»¨Éˆ¬Ïœ ×e^£*3W¨ŠÌuZMÖ?©ÕY¿Pª³2Š´r}ÿìm€ð¬àob øZfkÕVðPaå~ÌRM é|%Qz|Ǹ$~÷(ŵO˜íÞ%ànãûê +%ZnU°šSOP嵕¹½¤jö8¥’=G«`ß¡ËØ_Ò¥¹¯hÒܟ)Ò<„üÒfA®%¼˜Ãz¹)¬UšÃ#¥%Ü«³ƒe•f¡îˆÉeE䶉ª˜íò3»úÊ.â ÷ÖÒ¼ÃMB¾¯Z Pñ+‚•¼Ú°ê¦9·›$åŽP%œ+´2Î-ºˆ³%âþ&âþDqŠ¨ýól¤Z¡»`ߗàà+© kÌàs•9lá¦Ú3×àk2­"Z*?¶ï¯Šû°«"yo«”u@+a{6ˆ }jKKü«K¤ÁòbA*hŒuEü!j x÷iTo5ªˆÿ½ˆÿ–&à#YPô>„e~L`C°&ÇÁƒZSXQ›Ár£5\kÚ—´Þ¸qM˜¥¾>Ê®»ö”SkMâmeêþúŠìCJ)×»ª¼Ø_V& *WÄ"5QXÚN”è©<á ½@¸Å>B½ s…oh\!B-"y3$ÃÞò0ðT`¬Æ½z¸­5:<̶ì†É–øáæP‹ÞFšm[ɝZUüGõJæ>EMæÁʪ|o©¼èHY…8¨T*œWyå-$®¤Ÿ’W6Ec—-ÒsÊFå”ý½¾Fï*Š‚"o†dãà¥í½R€J,48XÒá`¾Íf:œ`¬ã ¶¿-ؼ£…bÓÜtÌ¡¡ñŒ³BÍp“ק{œ¯Ëõ+y~šÒ@~µ,¤ ª6<_ÞÉ®è¥dULÐ2d ôtÙçt–ì[Zºì?ÔtBɐ!䭐\€oJžÈÑÞ©ÂÀrÚ1p©Ë Æ{@ßãŽíê0Óu’ðêöèÊÖ¸]r]²Ky뀨1dzX]àÃkúsTçƒÙu +BV­–˜®ì&¥*Æ)LÅU*CqÆP|CeÔü›Â¬AÈ¿!m†pÖ˾¨øLpí~WÐþy¡ ƒz{èÖïô1Õô·){ÚË»O9•w&î)íHÝWԖu° …㕧øå4K3´Õ!iš0†¦3"Y3JJTϑãÕ+¨ r|䄆ÿ‘ê‘È­^ñþ€žÃý:€OuWÑü)´ÿ ¢ý«{ôhsÁhF}pÊ‚¥|˜f+<áX¢?»›ßÏpáôe`÷äÊêæ{³ºÄ~ÌÎÊÀ䎆„öv™öáð¸¶+±mÔ3bl뿈±-¿ b¬î}FÏáqÕ»,v\DóG†ºÐþÕi˜íèÐÍÔÍZ@՜#HçÝ1¢¹Á\„%wöcö•Ø홗Ò.¥:3.f»$Íp÷ÅÏÝ㦥‡NNÕz›jñžÔû¼è5y˟>õ•?}â•?íÂO´q$€6†nfDgpG p =ƒI=ÀÀ@+š¯B;¨ôD7í xÉxK>ؼ¥0³ì›4+ÖÍ6Ìgí“Žñ‹ž¾žï|êº`ïñ…r·èŁ¨…fÚµþC”k3žä…eOÒÂ=IW_zFοõŠ˜C¼#fßw¯ÝÃv€™~€¡Q€Ži´¢ùr´ +oá€s¹+» kå †µ„c®L“V¢-ãïÆáãî&۞¼Ë²?f`;Dx;£ e»¨†jg²A»'Òз—h˜v 7|âfø½køg/] ·ÿëz Ù¿Õ¯{x¥`ÝÁ®)Í,@å €Ò[œß™@ÚC 8÷Ø’Œ®`ôÁœ6°§Œ4“ãÆf1ƳGÌm4c–5Åȵ4–ÚW+·‡­jv„®ö8¯Nî Z]ÚøäÉÎ ã÷Ž_;{  zàÙ ¤ à†LpA8"—4`ƒö`…Î`"à’½pÐÌP, ÔRFC` +ÅÀlŠÂ¥àzb'±¨&jÆA©'…^R +½¥4TxÑP®¤£—†ŽžQ ôHÕGÉ</c¢h­ºm6F·Ý&èVjŠÂrâ +µlž&š‰âñœèe +‡Ù#nÈ#DÎÐÿ™ +e¤¯SèëNC¥áCCß@:*"è=S½æ ,ߥkŒPºÉ%;LQRÌB÷ýlt¯$jÌÐý„Šˆs_%nsFÅœ÷ΐûÙ€ÍÞ»£9ÁísG^Ÿx<”“¾RH¡?1YLÃ)ބšŽþÓõÐ/A}u¨øܽW™ ×W¦èµ…žElôÜk†²”UGɷԛÊΘ”]2‘ÝàÉþkÞ/ë6ë9hÞã‰Ü72´è–!¿K†–¡ÏXߙB51UHC'áOÇÀªcõqJ:ý¡ß2ST®e¡o¡ÙGŸœ?}ŠÍ?(ös‡•Ü!E oPq’7 hä½W4óú­¼^Å#^·â5ï•Ï€Å Z>W ÕSoÛ-¸Tj}'¨Ü润Êö–æ¸Ý M£ýuÍyûVÍM‡– g—ƒú/hF›5èÒDœÓ ëDdEa0–˜$L!g‘*¢S½i=ÉjÆËÄ0ƒŽøD£G3t¬Ñ9æ¿G.çߌøÒêzØF›ÖéßØþZd-t¯Ãm…ã%mÓ…Zçó!?9ÿÒârNÛîú£¶GØ q;¥EQ=QGÔN€Z À(òîM4LãfÚÀ°Î™êÑI©ç™Jz{z°Þý”X£[3ÓØ­ Ù¼kqyV—cWÙ\ŒYg×ýµCSÔǟ"÷8Ÿ‰(s9~PØ~ÔíTxƒ¨>좸6ì®øxx§û‘ð!IM8JE ¤úo`iǒ7gŠ`YÏáûl;x‘í +æÊ©ßgêý[at5#‰}!Ugє¼Pp6i‰íé„Õ ñëêã6»ÔÆ-‹)‰>$©‰®“VG7yTE_—UF?—UÄôËÊcPö=±LìxIÚ ¦€dsØ0<Ÿ¯Z@{Ž-ÜΑR¿.˜Â¸œjøóì8ö]ºECF¶ .-×îDÊ +Ç£É_:NÚ ¬NÜ&ú!¡È½2~Ÿ´"¾RVwÌs܏^ûâZä¥qOä%ñïäÅñ(ߓ€òoÐk"Œ!ídc@1ŒÌ3ÞE¦ð4—wóøкXD]Êõcœ[lظ †]—lq|ö,ëú…öՙùŽ3 +\+ÒÖ¹•§º—¥ìîM.‘}7ó€×ž¤ÃÞEIÿRìNºì³+©ÍgÇÌ^Ÿí3?*¾IÆ1ބüS8Ä́!9&¼Î1€¶<&Ü_b7–ráÊ2Wªi©½1_ì͍dÍIäUÏÏTfgÛ˜“ëT6k¹ë^ÝQIæÉ·Û<þ™^äµ3­Ì{{j•Ï¶Ô:ß-©ç•…©w•_§u+7¥ønJGŸé¨˜ãÈ=èCÿ<´çÒáÎR}¸¹ÂZVr y•œ^)§×.ŸjpdI«*/ŽWñyš`ÿÂÙv¥ósœŠç-q-š[ Ú5gdû¬BÙVÝ.¯ÍY¥ŠMY•¾2O(×g6©þ‘yKµ.«ÓomÖåZú>a"“Ü^.ø#ŸNúzðK\ü‚ g×8@ýž´£U+´¦Ëb¹eùÉV%y:»¢Eówåä¹n_°B´uþÿÈ.Ϩ¨Î<ÿîÌPDš ½H)#LQA£, "  t¤ÃІFpFš ‚RDŠŠ *‚1XÝQp]÷¸fƒ%'nìf‹‰=Gß}ýæÃsîÇçþÛ=÷WâR™¤à*êxåñ-^òønAIܐ°8î¼·4î†wQüSQQü;aQPø_B6ª€Ä1xüCÂÂTßÉT0^ª…¯Ë,p¢Ì•Õ_â­Ú-]©ÙQ¬×šnܔm^Ÿ`U“™fW™žë¤H+v)O­à–m«áÉRš½Š’»I¢¼¤³Þ’¤)ŸÜ¤ÇÞ¹ÉoE¹ÉD˜›BþLH$ oA÷€æ­26.Ê98»]æ¨pfõnªt–.ŸÛ*[;¯©h½Q]Á&³ê¼8+eî6»òœlDz¬BY¦œ[”QÅ+Hoò’¤u²SûE™©g|2R¯ù¤§>ôÉH{-ÊH#BŠàKÈ&àE20\—ߖ±p¾‚QÅ )qXéÄt)ø*û+ü4öÈWë֕†VË"ÍÒ­ ¶&ۖäg:Jóò $¥\IîN^vNƒWFv» -ëˆh[ÖiŸ”¬ Ÿä¬Q^‰R²ˆ"øKž³0½T꺭¤bQ’¬Ö#¾¸•¿UÚ+Œ‘‹¢¥ñÞ,½ï-})Š.ú$Œ)" +&¯€{ÙÀd1pqð5õ¯£¹k7ÐÙ¨‹Ö&+46rÙ5 ÞjŠúšò:±^qí:£üê(³œªX«Ì)¶©Ê,ÇdE¡Kü9wkE5/º¼ÙsÓönA¤ü„p£ü¢h£ü}þOQöQQFø_ò,…ޝÕ2ڃJàõ÷Óüw ™fÏm4¶š£¶Õ…¥lªÈ›ý5¤{Vëæ5…d7D˜¤ïÞb‘RŸd¸+Ã>¶6Ï)¦¦ÔuSu墈ª&ކÊ.Ïu•Cü°Êq~hå÷üНÿá‡)÷ +S’ÏxÎägz“7è.^ú܃Zàõ÷ìZiÜÝ>5ÆPt:2e^iûRuIÛ*­¬ýÒKÝn”Ôm¿7ÞrKsªÍæ=¹ö‘M2§ J—°ÆnHC§{pà OÜpÁCÜpËC¼ûßâúâ:ÂïšÍ=zW?÷  +¦þÃ-4ûµ ]@e*Ê{磤ϖ)ìsgçö.VÍèY97¥[¬“pp½þÖ®(£è±f‘)–áÙÖë:¤v!í;ƒÚê®ikwýªí¨ÛªýçÜÛnºî{áØúžØBþÀßé.^RÐÔÓ=¤õlöRMPz”æ¿A]H-‘u̕IrýÕbVύ>ªu4BcÿÃuG’LBŽdš.X°æP¹õW‡vÙÚï°¢¯ßqyß7Nþ}7ý{Ÿ;úõ¼sòë& ýÎæíÁ9:ƒtþ½´þ}ºC@ŐHÑĶQc$Ž:2±£ž¬˜Ñ%œ¨Ñ@µð‘`u#´BF6띊×_s*ÍpÕpžqÀp™éò“5~'[-—žÇˆíL.Ø¡óï õ7Çhþ2h½ ‚è1=D[!b܍Y?.b…Ž/珯Q‡©¯Ôߪ¹r#áØicÁؤ±ðÂ#þù7&üsÄÔë,1›É7ôö]Ô¿‡ú+©_6dâǁˆË„\ÕDÐU#ˆ¯ÙcÍ$«&3“+Y+&ÅlÿÉõœ¥“›U}'Ô|¦2爦Š4SJM¯©&-©mÞÔ)÷ë:îS´]{­Ã½úqw‚èÍäx+Ð}€îíõP2 +dŸ.‘W€à)6nªcémm,¹m +ßï°øŸiÀšèb1„91‡ ±q‚áBŸð¡G|¡KV@›ˆ¡EÂ1—Äaɂ:‘3j¤Q!9N¹À°ÉÄ,vP>õ'SÔߨŸÖ¾ŒÖîùXø°þ°ü˜êÔ¤N]ê›O}&ÔgI}¶ÔçD]\¨Òwa“% ¤„R¢)i…~=>BOŽÍ‚8º2Äٙ!.g.C¼XÄ~‹Ø®eë6±JàËl±Q”*Äâÿ\×iTS×ð“@H.!y`bÈ ´FdA@A™ 4 aJ˜"cD'(Š‚ +Š(‚
P눕¢Ï±´Úê+•ê‡§€â¸ß±ë}`ñá·Îþ¶ï:{¯uî¿«ÁêµÀ²I ,cÇé`ñ#ց]ÅîÐÁ²{I·|OÿdùEëƒÐ?XcÔˆ©€{“< +8b¯µ3þ7*ðý5€®3â5Á.ClU4°-¥§B 8Û°::pöaÍØQpÚ±³X'v“1Îée|â 2F9ï#¶ôa[ †lA{ˆÌ·SÉ¥À,œsì0\;‹ð¹€ +"_ †h€@ª |9 fæрW¬¼2:p·b5 àîa|áî'&¸Gˆqî bŒ{šø̽D|ä^'F¹‰aîñ†7B¼æMh¿äóXƒØt'î=çÜo¬) Æõ<<›yb*Ìõ¢Âœ p–h¬$8*µ¾ éãÂuŒÏä&â#¹ø@îÒìÓ~'8¨="he N2‡Ì7‚næÉ{Ìäsæsr˜ù79ÎzJ´'$°c}$èM³¿ö6§À3 +¸áoqŸ‰áy¸-¤‚ žÇüpÍ1q¼Ö‡oÒéïçä3†go7j¿qÞÂ|í\Ã|åT¯ó©IgÐéˆÎ€Së¹Ó9Ö3§«¬~çVŸó3^ç¡iœÆõî;þ¯N0½Ç ~™âŸþ.Æ܍,²À+çâ‹wÓ{>uÜË[cÔ}™æ[ŒÖk×ú —•ÄÀµö³ùk™ýó*tžÎ«f=ïbõ‰tÿÔýS|lÚù§ÙÌídߟ{‡Ý#î×»-š~C§Ü;çÞP‘,ôIÂF/£ PŸÄݓÐ-‰ µ;j1­3"”¸Ã:’¤wjY†ÁÉà<㶠U¦Ç—®3k]RaÑXmu8 Îú`À~ÎÿVÛýþgíý»íÙï xk¿;`bÆ®@°ÿjç°÷ƹ7‚ÞGhPªþ–²ÐýXCt3Ž‡ºbçR/IÑÎF?®ˆÒm‹Œ×o —¶„)M…ªÌšCŠ-š–o°Ú·¬Òfopm}Pƒ]]Ðá;ƒNrkƒ~âíú·-è¯*xŒ·5x[—wË@à; ¡Mô4Vý;A ݓè¶Lu%Ù¡ IÎÔÓ2Z{| Ñ* Ó=ó­~st’QãŠt“†¨óúµU]x©Íΰïmw„UÛo ÝÍ­ +iæm ião¹ä°)ä‡ïCÊC?ñË€¿1 fNKhø(h?/½2*êI¡¡[©tԝÊF6è´\DiKuÕlIò#šeËYñý=±ñFuR¹imŒÒbGtUµd5gëŠ v›£*gTDÖòÊ#ù"Ž ÖGœ'×FÜ"K#Ÿ“k"?J¢Àáÿø“A0M¬@èiB÷SpîUh îtº’®‹ÎdX¢¶L’Ò’>_³YáÍؗÄڝ©W›(5ܞdZ—nQ›cU!-ä”[j¿!¦‚».zûÌ5Ñ{Š%-d‘äŒp•ä_ŽjI¿£:ú½Päw1 À§Ãd_ŸØáh„áÌwWÐµL*º¢ÔDç•:臕fèèJ>¥Y)ÖhÈô¢×¥êÔ(ÂôªSc +“e&Iró2™Òj}‚ŠS_l_WÆ-Š­âÆÖ TÒCÂ|é)Ç3I¹] Ü'ŒË:&ŠÍº(’fÝÃ^ãzL›dÜ/ñ.<Às¸–ý?¶ë=Ê|ø÷¹ ƸŽËĽË3bf0F‘QœPI…’.Š“­])’ˆ)¤èB[(%]ä²Û•êìn‰v·­Dm¯¶vŽT[ÑUJ—ßù:ûê¼´¯óÇû5ó×|žßç÷{žy¾ÿLÅ2°ƒ,œ9Ðîl#(ÒJ¡@«¢r³=Ùì,½u™!©SM’Ó£ÌW¬/I[`°æ²…©Iö RÒbWç8Î[µ]9'y¯ó¬äj×è¤sê™É­ê™IO\g& ¸D'g¤êþ|€ÖÁ³ˆœIDz±œÿÊPQ®ä ƒ¼<'*;o$³.gŒnêÆ A҆0ãeÚéf‰YsD‹ÖÇYÅg.–Æe¬°·n 7'];äXBV¡œJ/ÔÐ)£y+·ò—nžd˜°)Âô˼h‹¿çÎÏÏYh=wã2Ù¬ )vQÚ,y¤vËðiÙ%Š)Y‡•aYõªÉYWÐCÕäõo”a™db¨»ƒÏ„d€³¸ß`þ¡ÍØΠ…Û6îàAf‘Ҋí`u± µ¢Ø‹M,§»hÇÁ‚íSb·E çn±˜U/Ž*H´Ž,X%›¶%Ó.ls>š¿ËabþAǐüSNÁù—‚7=p Éëw +É%Ž!9ŸkųxÏá)-v€ùû¶bE8{⺮`u©¬,“ÀÒ= +*¡ÌƒŽ/óãŖéŔ„ f—L7ŽÚ=[¹+Î"|W‚hÊW+­Bw¦K'çÙÛý­¸’ ,:Áýˆº¹€í}ò€mD°õs—±ƒsë±ì¾×^RŒà(’shRÀ’X\)‚øƒwPCÅTŽffUò¢*'êEL;mV1ß$´b¡Ù„ýË-‚ö¥‰÷m´W¾Câ_^!S~\æ[~ uI}÷¼’ù–ŸÒÿ²ý¤q-v P…ëß»`G)@N9@ΡKÄÕ°Sk +³km ºN3ê<©ˆ:fjm0orm˜îÄÚüÚ¹‚ñ5ñ†5KŒÇÖ¤˜úUkÍ|ª·YxWï³ü¢ú‘WõE‘×ÑNѨª—âQ‡?óJw0ï%»™w’rf@Rɼ•eú%ǘג3LŸ´‘y)½Æ<“v2O¤½Ì²·ìCáݗî?éET6@\$Ȉ+^‡ZFRÄُ"ʉ4qšA“á±ô‡Df@¾šyÃe2¯¹\¦+d^rÅì ®”}ÎígŸrGØ^®ŽíáN³¹ïÙGÜö×ÁvÉ{Øù[v9ÑýMNôîÊ ÿÎ_WÌֈð(YñÀkñt@¸#q?4ã©wêit¿Ëú¥óBæ™jÓ«LcŸ(µì#e>ûP¹÷@±‹w_±—wOq×¥¨áu*Nò:”ßòڕ—yw•í¼[ÊÝ6å~‹Šè_UÁ%1øù/ˆ;æ{x¡Ñb ¾Ø…>Žö ú¿K=÷ ¥ŸŒŒ¢ŽˆcºÝÙ.÷Ul‡&ƒ×®ÉáýæV sÇ­Xç¶[©î-u…îMu•^›ú˜ÞuõY~‹Û%þU·ÛüŸ4ôÿÃu¥yæqÿx"ˆŠ*Ê¡™ív²“lC5Þ¨x €€ˆ‚ŠxŃ¼ˆJs`Vm\Ícl®ÑT“ÉÕf3iwšN»Ùl¦×¶™Ý´M»›nûîc·™µùã3ïûßwæ÷<Ïû>ß›¾÷]ل‘¯mÂü–‘¥ÿ¡¼„qÛîØN +`ÉTÀRi€¥°àyòFxºsî³.îq|þãr·‡Ûµ„÷¶ÕyÜßÖêyo«Õ띭}Þw8Ã>·9û|nrŽol™ö½¾å„ïʖÒµ-ˤeÎ=òUΧ䋜o)‹Ìƒœç`ó¯À¶£ì"Ê&¡#Þ3©ð<#¾äÆ“´ÍðQZ2î½Ô\ü½äb$•ÇÍD½×õÞ+ mÄk ݾKñvÒÕxùrü~¿Kq”·âf(âÎø/Ä]˜»p6§âŸQÇÿ4ÿñ3ë` (;Å eû–í /rüà«*<æEŸy¯Ã»Ùq¸[¼Lüjfa9£Ôó +Wã})­†¸˜j&-¤ZÈó)=”³Éýþg’GN% <‘4IK:4›t!x&i5äXÒЩ䧡G“HÆÂ\ȑ5)XèKX’7`\wÀrÜáß>xÃ> ÞçÁ]á¸.äà–©øKü<÷ ¹Å^ó9e>gx:ÒÉ,£ßñÌfÿٌŽ€™ õMî`Ð×ü‡tWèDúL˜+ýípúí`úýðé_„ïãþ+ÂÉÅÂǐÑ5ÿ‡¥ |¾ ¾Uˆƒ‡"wxPä w‹`EĄ+â͸EQ"þ\!ÏýdA¡×œ°”8#P“§ó ”É܆€‰œVê‘kð¡ì=!ã¼½aûyã4gÖTøh֩ȑ¬ËtGÖ]úïú ï;z6¶&Òþ +,}²sQçDŸö‡%¨óIÝà¶ÔV%~pYJ‡ÙFÜii~NÂu?V,ðš•'Š”äÃZÿñüÚÀýBsS` ô„9øƒ´¡¼}yt{Þ\T_ÞbôŒÞ¼¿1zøßDwó±5Q]‚ŸÑ_Zûµ|#x„~s÷Kn)ñ°¢$ÀU9 ”48UöÌ*·â§å©„‰Ò\¯CÒ"⁒R²³Xí?"֋ꃋZBû ­´¾‚=¶‚zOþᨮüFgþyfGþ*˒ÿV{Á3f{ÁOŒ¶BlMôzà 4ƒe¨ë Îµ¢FO‡ å>pZ³`JýÞUžD/ãy:ùĽr y¨´Ì¿_ª Ü#© ¶•˜C{Š-4k±-¢CFûàêË(±õ^Ô½fjpp´–Q0f|7\»ÍÍ^âa3d{wUåûîҕøµi•M Õ¤© ©¯0ьê]‘Õå}Qúò¦NåbWªŽÇT¨.ŪU÷¿ÇV¨^°+Ê1Â\ïË"€”hÐü¯ üù:Ôùеg=ՓÁÙŽÆ×pö¾·>ÉÝjÌô²Ô +ˆ-Õb²Ù ÷oЫ©Æ*CHµ®¦×µGhµ¶(M¥ƒ¡®<ÌRifc”š‹± +Í;Èç±JÍ¿ÙJ ÆZS¦Á˜/}ŽÎÃtÝZE3¸ˆrÏ î7ƒ®€.ôÜg&£) ú›7€­é÷x«9Ðnâz67äMõEäº:™±œª¯­ +ÖÕԅijZ#Ê«»ée†!†BUªŸ‰‘êc%úÛÈgèý{¶´ +cɪ0æzO¤ï¢«ç2šÁ…F´Z¦Ú §£•ö¶`èmgƒµ}®½-ŽÐԚæÑВãcl. š$¹,°Ò¤ V7ֆ–54‡Ë뭑²ºhIÝf±ñ[d\ˆ)2ÞD>A¾c‹j1¯ó‡Û:´õçšQï´LtŒì°wxBOg tZÐf݈kêÜîVߙâ^ÓÁóÒïµ–b²º]á¯jÓP­Õ!²SXIsG„¸ÙN/lÚÇÈ7O3…æy–À|ƒ-0?a LÏYBÆ6bŒõ>@ëp½à-3ê(ÿÍ.Ôûº‘ž7°ôR ÅFÓîßâêvsðÕ¶D‚®7ó¢‡ï£ê‘Ý2?YWy€Äªw6„vXhŽ¾þ®±¨Ü]“Ñٖ³ že•É³Ñ˜úJ‘gý‘g]§È³fPìQÍ%Ãí§üLÊÿË^`}Åa`a­ÁQ íPDþ0÷Q ã)¼›Fal“7¼šLs:ž§ãàq&†3sàޜ·æ0ªe \[¶À¥%ú³%ÌùìI8·´Ã¹ù s>ý‚páÙ´ï¾úðiíû¢ +à]ʞQKù @Ä Ê?›ÜÏI¡oUÂ鲎Wôp¼ê‡«ã »6DC{=ö7fÁþf:47—BsëÏPßÞ uÛ~¨Úª`ÛvÊÛ?ÁöÖ lo>månV•¿¥±¿GãžAÙ 'ð&À¿ð:Œnœ®1ØߒBÓ¡‚ºC U§¶(»| è„¼Û YO"$=3!î™QÏ2°ž @÷ׄBzèæ=HÐÛ÷Úfº´ºXò0¿˜IÙñ”FÙã)Ûó_€Ëu@wPßlP ( PC2 …hÀèM¼ˆ? âÈtBô" ‡Ï¸A +¤ §äÜkSþRÚsïӚ¿Esž@Ùa”=î2`¸8·öí”ÝȨlñ3€q}ÛðJCè÷Hb >$˜L$)„^Šœ>Š8ͧÍÇéÐqZt^ñwKÆÐ-¨×uô·÷×D‚«'3®šÅ¸2qŲ’¬'›Év’A²—ç‘BpùaRNªH^ɛñB~ CòôËðXÎñHÁñPÁÙCåÿãnžànðÑDOµŒð£ZÂÀu TÏ Æ5ï2®^H–“ÉF²•ì"™$—°Wê셺„=WÅ3užª›Ð¯¾ŽGênj6{é’ΆF.fƒ#W°'úµì‘~#{¨ßÊúô;ÙýÖ«Ïe=úÖ¥?Ä:õå¬CœÝןd÷ô­ìöÈNvÃ¥_¸â…VW.ºD.ºrñ…a¸åûêh+iÁýœ ­‰ß8ú†—ÞñôJc=ßa} X¯aë2¬b†õì¾ak7lcwÝ¿fwܳØm÷ЗH=_2p5Y‚‹Ir4'jqb²j“Q•<‰ULž*”%Í'¾'9”°@f‰ÿȦ0n…¢ n2?öÛ¼Ø/T{cvØåÄdj²bòí3cŠµ{bª´1§t¹£ÛûØaG,wøŠlãºáx0”´O¥~‹ñgÓ4¥JñCŠªSGáèôñ(É§& –iiâý)s¥ùSß·Ù;e¡<'y™2kòJUfÒZõî¤ÏþCu™5}¦qüûK¸o„\¨µõ Z­ŠŠ€€ÜH!„ @‘„+€îû–Ã9¼T]Ä«µžuÜ{»ÝÙît§Û§ÛîÑm×µûÛÇÙ±Ò?>3oòÏ7Ïó>ÏäýxŽDöxGŽð#ûôGžó퍼â×yßù1¿3êK~{Ô·Ëo‹fý–ÆÒ_Õÿ»$òÞTà¹ßíT.n¤¸á²TˆwR7à\êvæ¤4œ3•g7‘œæp$Iå4–˜ë2’ wŠ7y ÄY<ûâ¬Þ=±¼®ØAߎ˜£~m1§ý[b~(hŽ¹-hŠýHhý\Ð÷œ`ýëÿÿ%lði<ðå?"ﻝAïìtWäΰ)ø8“¾3éAÌqÅ^Îaù»QYŠÃpZºÓ€4Û¥WªsëN)ñèL®ðjKªãµ$µú4%öùYÇýëgu 煵‰·D–ÄŸ‹ªŸŠª“ž «’Øÿ—|ü1ø™‚œSÜP“kÐ_îy¥Îdú`ZµÇT[0žÂVFr2zÒeN +•K»<×­E¦÷hJ3y5¤YxS}k¥]|‹tDP%VHçEféu±Iúc‰Qú™Ø˜úo‘1•}¼ä‹ºêÁc%õ€¼ïª–ÞÙ9ôÎUs0“í…cšÓlƐfÓ§çveÅÙ·©¤ŽÍ™.J[}FG]z©—%½’W¥¨÷­PtðÍò!A™|BT*Ÿ˗$ùã½üS‰^ñµX¯`E„аŒ§t¿–Pý7)ÿr>0Oœ¤ó„Öc¹ åm@oî6¦SÊmÍ9`ߨIv¬ÏV8ת³\«³òÜ+U¯r•™g̬ó-Ílõ/VôÊ£¢BåY‰N¹¯ü€xBüK’¯dńˆ¾ä3šÅ_Ò Ü£Ú¯é€‹…ÀÙ"`’~ǸÎCBô®GGAÓ¢ÛñæGÙÕå%8XrӜ+µ™®æœwcN‘g‰ÆÈ3d×øe7ó Ô}Â|õaQ®ú´$G}%@£~Hü‰øJ¢Q³bB”³Œ'RÚšƒÛyÀ"eÛèÉs’8Bça½+zõ|tÖ Ù°•iÐïâÔEØUÆ9”HŒ.%:»!_çY˜Wê­Ë«òÍËmäks{í¸H­=%Qi/djï þ)ÉÔ²b•–-ç÷´‹in—({ÖHÎWFÎGçÞ'´—ú ¹ì5ԗ25e;8•¥a\sIŒ}iq²£Á p)2¨Ýtú|¼¢b +ŸìÂ~VA— ³`T”¡;!Vè.J亻rÝ'Ä?$ +Kß±¢åü–îá!Ýýu=Í"åŸ!ÿ¤{¸Ks°HÏ_[p¢«"çª$ï¬bP[í‰*‹æšõ(« b –ÝœBË~»üêxmuªSv•Ò%«2ÇMYYè™^aô–•×ø¤–·òS̃‚$ó¤0ÁôŽ(Þôž8Îôq¼éKQ¼ñ[Q‚‘&”½â'à]êÁ%3í£…¼³¬Z‰Z:WtCYƒ?Š֠Ⱥ…ÑYwr´ÖpnvCŒ}V}²£²^á¬8¨v•Ìw—Ö•z&×Vók›}ãjúù15þ,ó‚(Ë-a”åW¨ê/ÑUÏ V]Éú¿äÍÿuºÿóTÿ©zò>+ÐC4å¤Å-Î(lõA~Û*hÛ7#»};£jåd´Eqm‰öim2Gi«Ê9©%×5¡Åà×\áy ÙêÕÔ볿é¨_xã,?¬ñ:_ã/øaÖÏùa ÿá‡Õ³ßãõ`ú>GùSÍ´ -ä]­ä=mä]]@^7š^/dõ‰‘Ù¿éýAõ‡0©ýœäþXnbŸÔ>¾/Ã!¦WãÝ[èÙcv ï©÷Ø×Ýå¹·û°÷îî³¼î%Þ®îŸòB:ŸòB:žù„´³ß㦉f‘z~š²tÐ.tVÊ.ïòÉ=ŠQ7¤ñ![äñ@$ŒoGÜx(3͉OäFŽÉì"ƲìÃÆòöŽ–9í­uÞ5ÚáºctÔmûÈi÷m#‹Á#?r>ô÷àáo<‚YÏå,Ð ÌQý“”}¨hï§Pv e猲c@¤b¦¼=%FÔô:ìŸÞŠˆ™]› gBgb˜=3)œ™ ÎΙîÛÓ»mÓUö?˜nqxkzØqëô §7§/œÞœú³Sàñ¯'X—Àc¯¸@ +v’ê§ì>ʵ’šº sH:D’&îuÃî9_ìš[‰s°c>oχ`Û|‚mq²¥2oÙTÌ›Žh3q6٬܍¶~î¶I»õ¶‹vël÷íÖÍ?ᮝýÊní9Ö~íÙWœ¥ücÀÐíÂÀ2 NÙg€Ô9à©áž‹@ðe.¶,x pÍ «°iq6.aÃÕ]xãjÖ_Çº%Ö,eãõ%V/Y˜UKÌÊ¥#LÀµyFrí6#Yú„‘,þ/<爯°ß1Eù#T{'õ¼Žt´”²µó€œrcIICm׀Í75ï9`åwÜñ…äÎ +ˆï®ƒèîïí€à^üïł_¿û9ð}PŸVð Áûá)x=¼χÂëÁ_áuï¼î²ß1>F»H}o ÚM³´€ô+@Ü°ïå¿ lzxý> þ×õÕ¹Åüﶰlˆe£ DË‚((`¤W%ÑÄØ 1`A,H @DņŠ(Š< âàC‰-ŠO1D!âŒODQDʝÑïgã0¿¹³;Ë=ç;{÷ûÎ9ÍÁ¢F Õ9ÌêÔPÔY“Þ0­s C ¯Y½Ò¿#ÉDHþN„øb:Dó ¼X +AC¸†FrŸ<û(g3Jßù,Zû”=ÀXŠ=æOZÕÿ8àðÐû `] hêÅ%Ò+"ˆ6ª!¸j°€&;àÚ@à:5¨Í£©1Šnþ@hóm¡¾… +}k7¡Ýj æíöGK(þœ]À4ªû8Zw }Äë0ø`Wè.–Õe@~5ƒîGn™Ðÿ+€Ûj M Üé ´÷î:÷‡¾kÔRsôˆäG´ù?Î:©àô€=¡@ON}”DoÍØGû­=˜b{¦øç}Ðó`ј]$7®•b·“ïu)ŽŒb˜Ñ½5t?+àÕä…ðʼ¦fõ 5ŒêÁ(F?¶‘ÐCÇÊ?bÚ>`ÝhÎUŗ`RšwÅ®`0„’oÉ4’H%$‹¬"ëH>)Äk£ »ðxŽCxŠjt¢©hè¯¯(möÖýÏ0k0«ž”QéÀÌìÁL‡€É¼ÁLÁDcÁ„“ÈO”WI%KÉr¼æW£‹ß€—|žóExÊÿŽN®¸ýèàþƒûÜyÜån¢ë@߅ÛB†VÿëѬ»5˜¥Õ»<ÌûRMœ)OÊÇHùD‚É¿#3ðZ> ]ò…x)[‚ç²,<•­ÄÙ:tÊ6ᑬÒá¾t7îJ+Ñ&­B«ôZ¤7pCö×ä]h2ehT¼sEÁ¸˜Î¬—9å¡¡|(—î¶T—þ”åãƒ7š¼TÇâ©j +:U3ñP•„ªÅ¸§Ê@»ê7ÜQå¢M•‡Ven)wà¦rš•{q]yMÊüWՌõCÔkºp^øZsƝ{¯æ=fK±m•`½‰­éf£ë9/ºÇcë<°ŠB»åw¸­m"nhçãº6 MÚehÔ®ÀíZ\ÖnÂ%í6\Ԗ ^»,¡Öò4j¬špÊúWýEwü ÆëÎøªÏ°~f`}å`v¦`ö*ºjñ¦Ÿ ž|ùîõvC«šu!¸ª‹Åå^“ÑÐ+õº9¸ [„ZÝÔ貸³º•ÜiÝz€;©ÛÁU۔qÇmþàŽÙœàªz_âÛ¶ól_*m™`_&Øۇ +>Áì)¾ƒÌQæDy P¡ó+K´ÙÙâz?'\îç‰z½?Îé#qÆnþ²›ÆUÛÍäŽë“¸cúî¨>;¢ÏæësùCú üýVþ}‰ Ò®B°×ÂܾUXfÿLXêÀD%L¼ó3lÅw¦Ÿé`φˆÑ1H†6Gû[¡ÎÑg\qÒÙǜƒqÄy,wÈy"·ßy_é”ÀïsšÇW8-ìqÊ”;-ìv\#,sÌ–:‰Jœv‹v:;9ß:wšlqf’‚L²™äâm|ÚN:Üh{u® â’AŠÚ!æ8éb‹£nqÐm*Ýü¹ +·®Üõ[¾Ìu_êò£ Äe–p§K²°Ø**2,m7¬֛l1l5)0ü.É7TJ6ª¥ W¥ë\:dk\^ËV»2YîgØ`ÚÚ(vËšùFµ#9œ.Æ % ï‰}#úcÏw”ðåJFsÅÃcøíž…žS…[†Å‹6›-Î÷X Þè‘f’ç‘%Yç±ZºÖ=_¶Ú½X¾Êýßò•U¦9 ¦¿ »§ÈÖ¥ÈÆþÏtÙ'˜+m¿¿‘¶÷Z#PMŽúñ88Ê>Ö(óÕc§ŸE¾ÞÜVß~³O8¿qT¬ oÔDѺ‘ÓÅk¼6Éõž+Yé•"Íñʐ-÷ʑg{å™fzmS,õÚmö«×aeº×yeš÷å/Þ/•©ÞL™:’™}ê•?>4sЬD}>͟ûÇP¯o”¢ÔØ ;ú`kÀ@äxryþ£ùµÆ`A®1Z¸òëñ¢œÑ“ÅÙ£ãL2ý¥Ëü’e¾iòtß,Ešï³TŸ-ÊŸRÕBßê¾gÕó}[ÕÉ~ÏÕóü˜ê=å©×híç(ö1:æöӑ»‡Ž™Ò Š‚Ô(¶Á†X2”Ë Ååd† 3lj2Æ|/N˜&I øIšê?WžâŸbºÐ¸Ôl¾q•rž1_5׸S3ÛX©™e°ÂâÇÀj‹¸ fòÄ<.ˆiÞSÐæGßCp" +80(§Ù¯˜®[èu^”¹ÑÖȉé‡Ì˜AȈñäÒ¢}ùÅQ‚…‘¢äˆXqRÄ÷’9áÓ¤³Â–'„ÍSÌ ûE–­Š ]¯™ºÝ|jè‹)¡Ç»Mk"-&‡1s¢ùT‹?pžjPEq÷§Ð췍®ÇÒ¼3NŽå±Z,û¦Ò¿qBj¬;·(vŸ<.@0wl˜pvLŒ8!f‚ÉÌè)Òøèxy\ÔÅô¨åÔ¨Lõäȵš" ÿÇuyGEu¦qøwgfd`€™ÁÅ.誈Ši*e60ƒ U‚RUZbì2ÇXYKˆ(nŒQ@M\)GOÔ-–h²®kÁ²nŒQ¹û“ã9ùã9÷Þ9s¿ç{ßû}÷¾¯ÖÙìbˆ<Õ31òŸ=uO\u]ÚD¨1èDõ[~:s[<ס='ˍyÜÄëµú¨ÖkPž0e £P”0I(ÐûHòôҜøy2sœÎ&3.Nž›Ô#56CiŠÉuXSìhŒ©vNŒÞ ÖGïÔÆGp‰>Ñ36úoäÏ_kã¢E Q¿åŸÃYÆ|Œñ7³ìjdÿYÏc¯?4Øb¥Ñ¥IýQ˜4ùI„\ãtÁlœ-É4„ÈÒ 6)‰1òäDƒ")!ÍΐcŸ /TÅë+bõëÔÑñÛµ ã›\¢âÛzêâ/“Nž¿ÒFŋ¢~Ë>‡Ó\Ÿ3þ¦T`'ٔ¬âuy²%&G,5õE^ŠrRÆ!+ešaò—¤š‚¤ÉÉa6IÉѶ†E +ý¢»¸$³}LÒRÕ¤r'±Vaܦ 7îw 3wY`¼ä²ÀðÐ%ÌðRf5áQý–‹|'€Ã&`_°Ô¥³ïå;€I 2ŒÛ­‚çî^Û8cGbtã8Œ²Nş¬þi ÂkÜ­z ·¦a˜5_b­[7 ÿ¼W`=.¸Z¯ +®׆—×]âï4T[è]MoÉ:À¼‘ë`+×ÀÇ@È.Àß +LÞ Œýp? ÇÐf' iî…A̓0ðà 8è ׃SÑÿú +Æ{‡tè{Ȁ>-fôn)Eϖ:¸´4@Ûrš–o¡9tšæÐ…·XÖr0ߌy ÛÑTÆ»˜Oï¬&`ÛRÏÀí3`àQ ÷19´­*hZ] nu…sÛp2Nm“àÔî U{0‰‚C{2ìOäAy¢ +víõP´7AÞþ%¹ÉóÇP´ýJ^u³qW×ó}@w&cNÜ„7sÞGè§×í80 èu +p>-ÀþœŠó*ÈÏka{¾lÎ…ìÂ(H/xArÁ‡A$üupÓupÃ}ÍDwPÐÁA;Îñú6yDžt³Š±3çæ=€ñSîþ-€ÞiôŽ¥w8½ýO.¼Õ±°û]’°è°#ŽÀ÷Zàr_àÊ`àêHD€¼)PY^ãKø:_À×KôõFà»ÁÁnÜ ·»)kàûp°ˆ9×}Î5ØÊøOô= ¼G¯æ;Àá ¿ÿ„·ã¦ø¡pKŦ@ ü؋…©+pÇ ¸ëÉBy:ð€óxÀy<äK°“¾“Iïd²;ÿB¾$gºÉcîM|Þ ¿‚èžþWúÏÓÿ Ðç"sO¯’^éï-ò/r—ü‡Ü#÷méP²AaNk€§Ìɳ!Àó1À Ì/Y$½Š^óãóšóèâ†ëbà]LzWs7¢Óˆªþíˆ0"ÜÉDâKBI I&Y¤€”¡ Ux…5x‰õx-øÛð ø{ð?|Šÿâ3¹÷DM?ˆÎ} :[žK‡ñWO2ƒ1 ¼F.~EG+§ë#þɗáK¾Ÿó q_Š¿ò«p›oÂ-~#nðÛð™ª×T]¸¢:†Ëª^ô©nâbÿ§èðç +8Kœ!N˜×>ÞC”ÇðøÙ¾<O}'ãá iøÇ dÜ”Ž[ƒ¸á[„k¾å¸â;—ü¡Ï¯Ÿø­ÆE¿f\¼ ½ƒwâüàNœrg†œÅ©!×pò/Ñ3ô¿Ì94L`º½ô"Œ"}*/¿–â§@%žSüßÂçþãpkØû¸6\‹K͸8†ÞNœQ‚³³p:  +§jp2`9N¬Å±€õè ØÂÙÎy€éy’9ØÇt>`:G}ËvŒúƒm›Þ(/»½cH?ˆ®5•¸'ã©ôIp?P;¾¸2z4.Ž™„óc§á´: 'Õi8¦¶ã¨ÚÃêèVW0Õó™.õbf¿z³WÝÈtª[Ùõ¶=h/ÛÔÃî +ºÀî ºÇn{ç¹h˸_E›Æ â¼´zy¥ÿ’ÊɓÉTb5À­É ®OàÐ7®?ÎO‚ßEOH…hq`âtì ÉDgˆƒé)`ÚCʘÝ!³Ù]ÁÕìŽàZv{ð*vkp³hsðѦàÅ­!‡ÄCΉׇÜ7OüZÒ4ñgIÃ{ÂÿYûÂ*w¤}? ¸Aåµ/‚zýPg&óè™2ÝSÕØ:¡Qh MÂÎP3³}ªÙ:5Ù<µˆý@SÎnÔTŠ6hŠZ4uâušq“¦UÒ Ù%Y£éâVkNq+5W¥õSŸH—OýQZ*H—yYêå‡ITꩤމ&ý8šùbiÞ¡'çH¸ûÃ}Ñ1 +»"'b{d86GjÑi`6D¤3-vv]„‹m /­ Ÿ%^^%^¶DR¶’[ÖÂ- Û&­ Û+[v\^Þ'_þH¾ â{BWG²7ù&”ž3Ò¿|œœ º)Þ-F{ôlM±ã±16ͱÑhŒIbÖƤ2«¢­l}´C´<º@´,ªL\5G²$jW3­NºpZ£¬zÚfyÕ´ŸyQG}*£.*æD=P̎þNQ-øx‘¿æyO |JOÜiÍ:D'Åm”ÇÖxZüѬS£Q7«u‘¨Oˆgê ÌÒx »$>[T£uŠj‹ÅÕZ¤*®Š›W+›·F^×êã‰kS”ÇRΌëU–i¿àgh¿U–jÿP”Æ ¯ðyÍj9nÒÚ/LŽ§]ÄnŠ·Òs·!I‰¦ä!X“2õ)!¨K CmJ,S“œÌ,HNeç'eŠæ%9ĕ‰’Ù‰eܬÄJiyb¬L·R^ª[¯(ÑíTéò…‰çø‚Ä»ªüÄ|~ÒïÊü$Añ&é \ÓÓ9 í£4{î±ÐÌIñFò£Ñ Ǫé¾Xn‰Z㻨1†b1Š©2ê˜ÊéÓÙÙ‹h–![\npIÊô%\©¾BZ¬_ +Ô/÷É×7+Ü)ەN}Ÿ§?£ÊÕß&ž¿ñ¹zAI(^s?¸dN‘~7µ_m™ÔçS¼Î¬Jå°Ì<‹Íñ íT¥MAeZ$SaÖ2s +[–jfKS­¢âÔ\q¡©Ë7•K]¦*™Ó´Ì'×Ô¤È1nåíÆ}ª,Ó)âF?›é?ôý•Ï2 J/ŠWü<¿h¦³Hú]ÙÔçSÛ³žâ5iÔ禋P“ÞÕþ˜›1³3߃'# e1LIF"[”nd Ò3Dîô±Ó’/ɵ”Is,sevK­O–¥AaMÛÂg¦uªÒ-õK·\'žQü ŸnøŒ4AùšÛ´½´îÒï̶؁&ŠW‹)—ù6s²†`VÖۘ™ŒÒ¬PeE1ùY ŒËf`ól‘Ö-¶Û\’l[)g³Î‘eZû¤[×(Ò¬›xsæUªõ„Êd½ÚÏdý·Ê”ù3Ÿš)¼BùšÏÈó³¤uØ´çÑ̙KP\Kí×|ÊgvŽå9~(uŒD‘c< +r5påF2y-ãp¤°v‡Y”å°‰­9y’ŒœbΒS!3ç,’›ì«F{«Ò`ÿ×ۏ©R엉§*½ý'^Ÿ-(_aðr…袙“h!êÔkS.s(§™N9Š]Qà—;yîIÈq‡#ÛËØÜIl¦ÛĦ»3Ein‡8ÕU(1º}‹ +$pöGn‘?ìÅcUkÉûÈ(‰b,% Œ¹ÄÀšJ,¢éÅv±¾Ø-I..㋪¤ Euòø¢Ÿ¸Â݊ØÂ#ʘÂO‰Çʘ‚—ÊØA›ÿ'“GHo­ÅtˆEÄ,¢þ9g0°—ñ°ÎŒŒò@X<ãaöh`òDÂèÑ2O +“â1³I›HçqŠãËK%qå•\LùRiÔÿÈ.ó°(¯+ÿ¾Ù„afØÔÔaQA¢â׺<ØTµ5Ú¨E£A¶ ¢ÀŒEE†qA&.TD0j]S4‰VmšX×Zc4DMòõ'á±>éï3ÌÂ}ï9÷ÞóݓTà84ɬŒOÚOZ”qIÿPÆ/yªŒ_,*ã‰Ê·º8Âì¥o{PÄë÷z’NóýÜØ÷-gߑ¢ÄÔn˜’Ú“Òô˜ñé1—>cÓÇ £Ó§#Ó% iïJ‡¥-”¾•–,‹KÍRĦæw‹I­pˆ^±—4;D­¸éòÄ!:ùg‡èåâk˜{ëRž‡e܋$“$Ó»0˜• +Lg«6)CŽ·×8cl¦7FgaTV?ŒÈ„„ìx Ï…¡Ù„øìéB\ö,IlÖ|ÉଥҨ¬Õ²Ye‘YÛ䙵ŠðÌ&rM¾æ±"<ã'"*ÂWýB[ +X—IYIoRðºÙ¢M^ËÞs=£ÂÐ\wÄçõD\žCŒáˆ5Æ`ã0DÇ"Ê83…ƹB„q±fL—ô7æJú·HCóvKCòŽviHÎ#iȆe!ëÅ×Ô¦°.e°.¯²I +ÿ^˜ ̦{êö~F`8[֘B99c@±"‹uˆ(AxI$ %±è_2ýJÞF_ÓT„šf!Ø´zS²ÐÛ´Nèe*Kv +º»PrQÐ? +_H +Ä×ì\ la –›dð5i÷!݉tOÜÌø‹ØR r+ZáˆàJWô©ìŽÞ•èeE9æXèÌ 0‡¿eü,sÐò¾–Õð±äÃÛb—å ´–3КïB[Ñm¹(xuQù!ëbÏ#IÉåYØÄ}XLa[8º ˆ«lú5Nð±ºÂÛê /«ÚÚxÖFÀ£6îµ#àn›7ÛL¸ÚæÃŖ-‡l…Ú¶*Û ¨joAe}u͏Dì¤t#Ï#s½*Ÿg¡˜ó1÷á6®Jï Ýô×Ò¿ð­< pnPBÝèU£NþP6êá؇Æt³€Â>2ûï µ¿‰‹kgBíæC©žü•ÜfQú–ttR@ïZ°| 0Ÿ1ÏäO'0Þá6 z?Ðï ý €Ï'€ûQ@Ó86Ë!=¡æ¥Ã•x-~¤ ã0h兠•ãV>€ÚxèÚ¸¹Ú\[ 9ÆÏ/“‘Gä0ß+ÍÀ"Æ<ÛÊ5`¼#ÑßHÿa ÿÒý8àÚ¨ÚÅiðÂAÎu#œÇyÎ㼖➼ õâŜ—äÏíœG;/"WXð¯ð _åB_-'{Ï9àȍN2¸ÖIŒ{¿šF÷(Æ;˜Þ¾ü™Ž^¯S€Ë@y\¢»|N¾ ×äÀu'^Ê5ÀMw6'݁¯t¼$¿jV¢€;¼ ßáÅà. ñ=ø{\ôû\äû ôþr²“˜žyÌù Æ=†î˜fÆß +0^-½z»½ò~I8m|E¾&ߦwŽÍœŸ³>çáÁ½ñ‚‰ɤ¿¬ëDtò…Ø­;D¼¢éM"ÉP2ž$’ydIÆOÈÀK¬Ã äáä£Åøex†JVғ…;؀ÛØDW!-¥tUÐUÅñ­¸†Ü2Gq§ñ?¹Œãžã"G½@οèêÌ\¨!ªˆ“Û/ë"éÅo™ã8Æ9ŽÎiôͦë=z–ГÂQ3pk¹Mrpq«ÓUF™ŽjF¿g¹§ÑŠSÜÄmå$3Ù‘O"š%ÿCôpb.đh8®‰ÒÏ!x ‹Â×ÒܒNÂuY"®Êæào²…¸$[Š òTœ“¯ÆYù:œ‘çáSùfœ’›Ð*/G‹|š6üEр&E Ž:´ãˆã=؝~@ƒJDý¯½dœ j¥|å<\5x¢ñÄ]•7•\u‚Kª18§ú ΨÞÁ)õ<´ªßG‹zšÕi8®^ƒ&͇8¦Ùˆ#š"֔Á®ÙŽFõÎõ8è|\Ú±Ïõln/`uQã.b÷ˆ>ôûòؐ<Þ·=¸Í||©ñÂE×>8í6­îÃpÜc<ŽyLÇaÏÙ°{þ ž‹Pï¹ =Óq@›‰ýÚ Ø§ý{´&ؼ*`õªÆnï:T{7a§÷ETù܁ŧ•¾¢PÑEy"rËÊ]–¸½Y‚t.ú:ଗ+Z|p¬GØ{Æâß(ÔùMÆ^¿DØüޅÕÿ=Ôø/Fµ2vù¯ÄÿlTùçb{@,e¨ ¨ByÀa›î°P¦;+”~#˜‚ž ÅA¢PD +ß@ dü!ôXjYî?e©=¡—¢)PÆ Ôõƞ>QÓgvéÇ¡J?ÛõïÀ¬Ÿ‹ +ý”ë—`«>eú ¡T¿NøX¿I(ћ„¢`³Pl67HòCNI6…Ü’CŸHrCEIίx̲\fimc™?Æ×Æpöž}aëçêþ¨2„ÁlˆE¹a$ÊÂ&¢4lL†Y(6ÌC¡áOBa©oø/ÓåÕ}†ñç\öì)A55ŠJ ²Â.à®{]8ÀËîÂ.Ë.·]n r[‘ÛŠ(—­Â%Œ¦*X“èèÔ±mSÓ¦i3¶Î´vò!m¦Ó´“t2M3Mš¶il¶/2füð›ÿ9çËó¼ïùߞ>f&m˜™J›`O¥fO¦-±'ö_æŽï¿É…÷¿É¥¿Ë¤ ©¿"¢Ü±Çø˜jÿ}6p/¸{ˆòVp¼\ÉàqéÀzœÏ܊5)˜Óhð¼FÓ+" ӚjLjÜÌIMs"³•ÏìfÙ!v43ÌgNsC™óÜ æ"Ò\ç4wýY¿Sôe}¬èÉ~@DùÇùPCÇéÿÔܦ£î+äå;t/åÄám"Îh“ÉUc*7'sMÏέdFµNfXëa†´Íì ¶ƒ i{Ù~í0ק=Å÷hgùníKŠ.íUEgî…ŽÜ_ í¹ íyÿÚò¢ŠÇyŸ´î“îÝBÊàrpžŽ™e®CëÑmÀ¤nNèSÖgcD¯ÇÞ‚A}Òۘ~‹éÕùØ#ºÛ¥ë悺£\‡nœoӝQ´êÎ ~Ý+B‹î¶²Y_Ù¤ÿ+ñ…Ш>B±Ê¨æ·I÷N1õ@¤œQDúäç,ù˜6ª0aL@Ø´ æ½4g"dÎGŸÙŒ“Èt›*™ ÉÁt˜UVG•–5„U~BµÞ$íåZʜ5”·ˆ!òÓM^Zé{£“ƒ§&®ÚMpÖî€Ýµ6W&dw*Ý&”»‹É]Á”º¬è®g‹]Îêêá ]£ +³+"˜\ç”F×5¥ÁuWep½«2ÔþCi¨ýJi¬‰ +øÕzÃE{Rp†âÀqb€ÞÛÉS#uôÝé‰EuýS¨ònC…wÊ}j”ù¢Ôw¢Ï‚b_cõ٘BŸ›5ûšY“¯‹3ø†x½wZ¡ó. ‡¼¯ +ùÞוyÞw”ùõŸùõÿy¢_s‡j½J`‰˜&FˆÂOÔy]Ë妔7¯Giófˆ-»PìO…ÕŸ‹ÿ +f˜"Œ™1j½¿‘=äïdóüƒ\®’?è_Tä´¼¬Ènù"Ûÿ[ÿ®Èn~ ÈiŠ~Í-ªûJ#0GLÞQ;‰ºŠ;Z€ŠPÒÆÃڇŽ0wn‡)¸†àj¡ï2@×eE~W9òºŒ¶ËËätµ±YÁVœà2‚s܁àwyuð6Ÿü5¯îü¯îø’W·GyuÛ7H÷¢ŸÖ鍽ôÜJxZ)st~P@1Éлº¾ä÷oA^ÿnhRqp@ƒœP>²Cfd…J  U!#ä†:Ô¤‡z˜´Ðq65ô<»o`™Mø>qŸMéÿˆMéû‚Kér)=k¼Ju.µÓžÐFë‘Æ ÑDÚ5¤-õ–ʞ[µÃ +dÄ!st#2ƶãÀؤ¥c8ia=RÃ|+,a_؉”pö„ƒH0»Ã§™]á ÌÎðM&)|IûIù7“4e“†Ö¸LZ³Äq¢h릐¶´Åc€qÈ=dL©“O ej=öN'â¹é$$O§`÷Œ»fbçŒI‘"ìˆÈØqãÙH+¶FBØ™Â3‘sHŒ\ÇÓ3oFâÔçHœŒ2‰§Ö8O1p¦Ö#ÑMύ!Z¤-‘vÁ87 dRLL=ìžeñì\,¶Î'`Ëüf<³„Í )H\8€§µØ´hÄÆÅlX´ã©Å|sñÖ/Ž#~qžxq‹o ná=<9ÿ)âç þ…èCæ†h_$Í¢u˜Ö­ª¹h +П²fIH^¶6]àp)ñË D"ž\ށ¸•½„ßXÑ"vŌu+žX©EÌJʕAËß¿|ìò-p—~I|îâgė‰PŸGÂ@ÕÜp°SÍ%giÎ9¤»Ÿâiò%Ò¿Lú/믱וPþŸë²«1Mãøÿ}ßSÑÇQQB_CŠRJ…SNéÛ铏hª©¤¦¢”HER !„|ÖdB¾2Ñ9>¢¢eȲZfǚ±ƒ5š5Ë0ŒÏżó¯mwí\]¿ÎÛõžžÿÿ¾Ÿç¹Ÿûњ@ҚCÔ€ eS¬eSªE؈éxèêxè¸Áuœ`E´ Dû994|Cݬ`®óóìµ@cž\ „0^_êºïœøo¶ €å!Àô(`ô ×$' ‰’ôNòRp’>šÙœ6³9m¡V†­<Z¹Ñ[9É­ ®u;ßáçyr“Ï÷»)ÚÀ½°˜É˜§ñ+Æ«f¬£´À0jÚRÓ¢ P6½‚ø€×76À +à}œ£óæ@»›R;àNlÌØ_¦ËlL:X;¸ù:8Ñ ²ƒu'íäF7yۀ´Ü‹û€ou½ŽQÿ`Óô= ˜PSŸÖyä¸äÏä +¹*_õ¾6®™ßX°A¶æE—•Ûl–ïÐÇ÷<˜ï²ðßÍâŠsÒÉDwî' ®óL7Œ;áçà0Ìx½ï0êZSלV/Rõ¾"×ÉßÈ­þN¾'w97?ÐË=àG3àsò—Ǽ´üBOٌ<ãÁóœÅî݋*à%…_꺑¥þaуBF’qd‰$ñ$o‘…×ÈÅ+â%–â9VâÖâ)6â *ñ5ø»ñõø Gp-ø'.âÍþƒoàéîï úò·Y]>ìˆ C‚ñ+"ð/Äà’¨•N­yÔYˆG(¢Î2ꬢÎ:êl¢Î§ÔØÁq÷á´¸&ÜÄ9¦î[þ<`_áGíâ¯äz²¡)s¡ä“ 1'‰#Þ`uý©Î¦Q/žZ)ÔʤN§`uŠ©SJÕÔYØÂ1·ákìâÔÕsÉ4rù´áŸ.Òáf­£ÿÙز~/È¢!ÿêӝ‹7°§î:WáG„P3‚ÙŒ¦V"uÒCþ‚¸Š.Ïbê,§Îêl N%Î3_¢gpˆšqŠoZ躙Y<Éù8I•ï +õ ÷᧾dÁ”¹À¹JÝQŒÏŸ¹Ó0’©ÔŠåhIô>›žK\êP§§±­\͜““ÌE×Å140M\íts :á´Âk4ˆ2JÿC斒¹Åe.éçFžâŽ`†¢ ®J.¸$A»"gѦ˜ŽV½84ë%ã„^:Žëeã˜^.õãˆþRÖ/ƒN¿Zƒ*4؉zƒzìïu u½Ïa¯áwØcô3v¿E­‰Œ=ì 2·Ò–˜,wwȍ>®õ6Âå^ýX‚ã´±;šMÆá¸I(M"pX2 ʏqP™Žze6>Wæ£N¹ûú”bOŸrìî³µ¦Û±Ãt?¶›6â3³/QmvU揱µ¯Œ-ýxNõ°‰È,+? bIa‰»J.ðùl?=´™*qÂ|Žö]?o°ý쵘‚ݖѨµœ–)Øn™ËyØf¹Õý‹QÕ%*ûW`‹U56YíÅƇQ1  ë^Gù ‡Xmý«¬ånÊzxjÃ3”%ˆGÎyg–{GöúöÀÑFhh:ë!Øm3;m}PcŒjÛ÷Qe‰­v±Øl—ˆMv©Ø`7v9Xg¿kí—a}9VÙoEÙ{µXñ^–nAéà+Â'Cî %¯…bY(z‡Ô¿áÊø=þ}Übi«§Ÿ}zØ5Ä 56øt¨3¶8zc££?*ðÎ1åŽÓ±Úé#”9ÍÄJ§YXR§<,u*B‰S™Pۓ÷ C¬ñ臣ì±ÌÓ%žÞ(òôC¡g( +<'b¡g$òµÒLŸCR¢Ïi†ïmE‚ï/R‚¯üÄ.®ø§©¯ a‚õÇóÎǜ|â+¢ÐW‰…㬰@=óÕ®˜«Lµ?2Ô¡HWOÄ,õT¤ªc¢N’ÕiB’:[Hô+ü–‹ñ~¥üvH±þZEŒùNíÿ„ÈÒ»\bÜÍ¡\‡l{¶±«àóJza»ŽÅ|—7ÞóÇ[ +ÀΘà‰´_¤!90I“…ñB|àÇB\`¦˜/Æ.“> \/EÖ(¦TL :¥ˆ ú–<&¿J‘AòigŽ³ÝÙÇV£2œ9àóRz)d>rIv°!æ›cvˆ RCœ⎙!c1#Ä !aˆ ™ˆØHÄ„Æ +Ñ¡IBTh†0=4WŒ -‘¦†®•¦„mSL +«'-Šˆ°kzaøù–ÈR“ÈYÎA#[Œ]dóû¼ëÐK½ä3Ùô’f€´ ¦Hž0‰$h\§ñF¬FhM0¢4ᘮ™ŒiáÑBdx¢0%|–09_#Müë2‹ºÌãøç73Š¢(à‘Bj‚+Š7&‚‚Š +"ǃ0#2L*Œ8©‰£­°©yð2×T¼2E¬Ìõ$³\³CtÝ2_Û®í¦f©­«™F»•m³o^R¯Ýýã=Ìïù|¯çy¾ß”-–´Ô}–ÔÔ–”Ô‹ÍRR¿âó¿-©)>óϜ"3¥ä*¬’{ž$³±efªEim4%íå§wW^z¤éQÊM¦ é ʶ&ËfÍP¦ÕndX§VëL#Íê1¥Z—šÆ[W™“­›,ã2öZ’2ŽÃ¸cI²þ>ó¸&ÞÄ÷ý6j!‹<@<…MsùûLì)À.gf€ò2Û˞ÕU9YÊΨ,[Œ2m#eµ%)ݖ®´ì¥d;ñÙӍäìbSR¶×”˜½Â<&{£ytv%!»>€Û–Ûóh›ï!Y>óq4öM `,e,xŠ°¥Ûòùì˜à¯ 9Á²å„*#·‡¬¹ý”f¢T{œRìc•lOÕ8‡MIŽïEà,‘²Ñö¨%ÒÐeÒÆÄF´î+¥ÕÍÕam€Ú­k§àu!¦ u‘ +¬Š‚áj[5Vm8ìªòպʭVU‹å_µZ-Öm—ߺCò[[7ä·¦A-Vÿôsèy¡\ÄÛ¾HJÇç1eRl¥4Ý^kЯBƒÔn£Ôfs µªn£–ÕíÔ¢:D~Õaj^)Kõ`™«ãeÚÊổÃf+]M"«Ë·ìƒ“4(…Ûð-ÒwZ^ÊÝ…Ä;ÿiöâr) Ÿãž“¢ÐínwFÔÎ[¥àèï’Zîi&sMk.:ƒšâ½B8ô‘jiÊj¹pk¹xjÙäµu-‹×âHíN~sÎñÜp¾ÑRb]ŒÏÓ05g9à§#ž§э܆þ‹èïA¿V +xEò{M\0pÈ°ãvƎÃ4äGÂhˆ±ã á1.ÿ:û:6zI®Ã¹:bQG,Ž½Á ¸¥…Ïr/¬’òÖ±Ë>¨¦Ðí[#…½Œ>šA‡¤VG%ËëhŸ€·š8ٜ¨Íh[ém†“ӝiÊhÊßml҉GccPÏ¡_ONêIt=‰­ß.ýœâ󸤹ë9_ ñ9é%Îtz²ÎuR šþ¤Ðà½gàl€óf1Ñ3¨] &;Jw•>é%}Š—iB®PWf2ÄPäWIðU„®Ì«8rõ´f`ÖDböª4ò05€nt;¡xZjñ~“ÞyÀlý þ—€ÒÒ§p>³HŸûK×o“[Ôȝékòrfä>Ï7vߐü’Ý@a5쇃L½í ¨‰Ð úB,$B&äé'fÝš¥ïåÑ¿´Hßêi5¨\÷µB÷˜u¿Öz}¥Mº£íº­=ºÅ¼û¥êtCïê:Æ~ή±Â5Vûìÿð)Ú@C(ô‚ÇÑMà©44sћ‚Ö ÝÕ4棱XׯuSè¬Dg-:Xs‹®êE]Ö>”®ßëc}¨‹Xô+]`åF>ü/j·h Ñ ã×ÐŽãð ½M@'_\h¸Ñ(Ac«{)ÓezO•è<‡ÆzÖ߬“ÄâM½¬7tT¯£~ kâÍaý¾ÿÁG)ùô3͉sþvÄÏ0ý™X\ 穋³²¢cgµÉh<†¶ê<õ¢S†Îot„Ú8DN‹ª¡*ê~½•ö’½D¸¥Fö4ác‹ûšQºl±/Ë[~øˆn(1ŒÀ¯Á¬0­dt²ðŁíSXy:n¢]¢Wµ%è,W-5ZCNv‹]zI;±bÑØfœ×VÓ U[´ÅâÓæfÙ>¶Ó=¶ÓlíK5äÈ9cnEžÚ鄩›Žý‡ézjò>ãþý¥^¨TPnB„Hȅ’@B.@!BÂ- !"ŠBAQDTëýRu¶ÎºÖÖεgë™Ýéz¶³Óý³ûé™Ývvºn«Ý¥]öˆžýñ9oòþó|óæ=Ïïyžâîª2|kµ¯®1áæ;n¬mÆõµm¸¶¶W׆p%f.ŌâbÌ^œ™ÁÙçpæùeœ^w§ÖÝÂÉõ÷qbýpü…GXŒ}Œ£qQ,M¦¶B­ö!µ¹ïRÛ}›òÜ[‹;ë“q+67âD¸§Ä•8.n0ãüÎnpã̆vœŽïÂr|'ã‡p"~ŽÇïÇbü!MX‘„‹8œp‡ßÂÁÄ1»ñSÌlúӛ£+¦žù,øeµ¡àj÷w¸´÷ѽW6­ÁµÄ\ڔs›xi³§’ÔXJªÆñ$+“±Ü‚ùd'wc.¹“#˜Ý2™-³˜Þºˆý[Ïb_Ê7°7å ìI}ˆ‰´O0žþv¥G1öQݟP{WH{¯€Ž1jm—脶÷ ¸}=ÛÇÑ]8ƒÎÂc,PxuÝb¾¢Ì'úký…µ‰¾&Ñÿùˆj~GIÿ¿‚F²(£}‹²LÓs™1ì.ŠÃ¨( Qvˆ 0 .EŸ¸!q‚bzŠëÐ]ìBg±âNt÷ÁW2Š¶’)ÖZ²À¼¥çXKéM於C~ʚ%Ÿ‘¯X“$º¢™|@5敏—É)p¸œêS–=eÀ勔®Ç d#ú$éJrÑ#¡K*C@Z¿ÔŸÔ‚v©­enxË:à) Â-‹°fÙ$sÉæ™Sþk”ßà4Èßæ8?&"ÿfE”9äO½O5_×Ð{HcÏq2KcØ^Ê2F9†)_¿<Ayºå)(²Ñ¡¢]QŠVE9¼Ê*´(Mp+ëФtÁ¥lƒ³¼ å;˜£|‚ÙUs¬^µÌlªë«úùˆü‘cQÿ‹®QfU=õÕ|ÆŒsdLÑè3NY†)GåëQ­F@Ÿ:­ê,xÔùp«ÅhRËáRW¢±Â€† + °WzPWÙ [å³jƙEs€ÕjN1“æǨ}ƒ|Hþ@þÉ1j¢O°'Pݛzà49D&ÉNº7@9zˆ_ÃЦ‰…G³ ÍÚt¸´|4j áÐJQ¯UÁ¦­‚­ªÖ*;,:7Ì:?Lº>fԏ±ý «Ö/1½þ*Goø6Ggø!ù=G§ÿ‰rôO±û4â\§Q|‰Ì’ÝÕ´oѽ =?eiÕѬ©_§> †TÔx° +`5”À\­@mµ¦j#Œ5u¨©iBuc:ãNVeœfZãq¦1^áTïr*LÉ#N…ñKúåTÖ¬`o+&à™&£¤ŸîuÒóh¥<͔«ÑƒzSyÃ(ôŽCèC÷ x¿IÞeùÞ_3ç¯LÐòVÐeî(»Ú%“dˆtSÍVÒ@uÍ´ªé[hæ§UIѶ +ÒöX”ú6¢¸# âD(ò£Ð¯Àv¿B¿ ‚€ù/ò½È ì?0‹œÀ2²¯€x€mŸƒçÿ¼Ž¯Y¶/ºâýsdœêõ?q»éð5­€¦êûi÷ë¢Ý§g„½ñô&#?ÈE^Ü`!ø! rB*d‡ à…lØnFf¸Üð2ÂSH/!-|©¡ûH }ŒÔàŸ‘ÖûÒz¢+NR­i2Bzé÷¶'Õ6û€ª@m’ ÕïòW7‹¬¡Dd§€;œ…Œá<¤GDH‹È©DJĄ­‘$´#i¤›GöbÓÈ"6F®à¿\—yTd‡¢"\¶ \ÙT.j:Z™S:*抢¢‚ ²ª ‹+\Ü—Ä\REG'·r­IsLçè˜:Ž§ÒFs§±´qî<z:ýñçpï÷{·ïýÞ×-{¿\³ÏÉ-ë®Ü2ŸÊ=Ãú3Ëð³ÒÑLVáh÷Gû5֢]2¤PÖŀY’O~+y8«u»< +¼e* {a˜Ü +#åZØ~/cÑ`¹Å˹h²œŠfɱ¨L…52î–}Á'2|#ÜïåÿLyV-J¡! ’‰wìdb€ö›éR,)r¦–'¢?WòXÀXb''‹³-&ð–ƒ%PKGÙ[̲³ô–­¥¿ZZF¨…%Y6– 5³Ì'áÕRévv̒+4Ä»ðxªB✓ÐM˜J̐ÞÎ&øl.@ÝÀ…è—¢¿ýå’c…­l+eSÉ0º’w¥/qÁƪxø«hòU4–jŠ«:•¿q¢jŸÙû>灼€ÍÍi06“»@¼ÿ0›{€Ï]1½ºK%ï’‰5Õe•dX+µ¨aXo/m` ßàÆ£ËP¼;61”Ö2üÔòð×Ñèë†@Ì:X»vò¹ãp ¾ã{”•KO"Þ£ó¥˜br€Ï¯.–ÂË¥ *ôÑ4­—œqÁ~³d³%dÔ³Õ³|à$í$;‰Gƒñ؍=€‡g~Iރs{ˆEc¿ÿÄïÓpnk*>'͓†•|þ]%5ˆ¹!èúðqw4ê¥V èîBÉB%}lÀN:èÈPÎBpØ$aIø˜¡øvg9Îãs‚Ë~‚DŸDè$Á<Ɂ'ø¢ =óâóëïQµÜÁ÷%_BfjD¿d{=¾ÂÂÅYpNÁ'ð)|FLN“›3Ää,19ç%]`a¸ˆ—B.ó(}IN®PäWʤ«8x§®d±8¡DÊuè:ú1>¿JŒ;¡ëŸ‡Ð§„[oÒû ÎÂp¡‰‹p ¾„«p¥ñùùŠ…í&¹ù§¿t;î1(Þãá¹Ïå{@}> °nâñp/§œ›p_…®Ðbô?Åê'vÌ5Q5Mß+[4[ÿR‘jî³cÞÓr}Ç®{Gï±·ÖêEsS{õµŽ²Ã^Ð þó=Ñß9ñכ°Ê `.àAèF¢ÛÝþhC+qè¤ê¶Òõ­rÐÈC£H_i!eœW®kªÖÕè2[ïEíBý ¡;­¿ðɳœt†Ó‹UvÐZ‚£þ+“~~vÔuGóMôéDç]쟀F3ÐÈA#bÃŽ³Z̙¤m e²‰î |öé??æ[±#(Fé×XI㠞¨ñ5µ¶h»HÒÜKS?´†àË(4ÑH¡ÓИÁé9häñb4qæR<_©ZÇõق»ÉÈ5bå.²Ô@dPÛù+^è?ƒûjFıؤóÄâsbñguCë ×|†Æh4’¸š)ڏ$/{±£;vk.ç—rîrÕkµ¶‹müµ…O×qR-YÛ¤k#™Þˆê žë?†;@ÇÐ_e‹Ÿ.hza}þD Õ­¾è Bc¸>ÀŽر¼lέر;ꔏÆ<Î-ÓzU‰­å«ùv5«¢ZV’áJ*­åçTÀ®Ó®)Wû ×êxËç­À€®+š>hv@ÏÌI½Ñy _bÐŽÆh4’¸ÐICg†V)BÎ^¤ŠfËUÞl–ÙlÖ›F-n~T––—Tj{O¥­žªÄŽ÷²‰\åë´·ÓhÓú÷Òîh{õ¶NÚÖÜCµ-ýµ¡U'­³ë¦5v¯k•}?UÙV¥ý­0īܐ¤e†-5LÑbC¦Êf«ÔažJ–h¡ã*Íw¬Õ\§Ý*v:ª"§Ë*p~ 9.ϔïbU¾ñnñܜoG‹åÉÙE»ßچ§{Ö[¨ÆÉE«Ûh¥s°V¸Dh¹±‡–û¨ÌØ_¥ÆwTb©…Æ-pMÖ<×I*v®"׸jŽ[©òÜVj–ÛFÍtoPŽûGÊ6]T–Ç}e´~֟™×üh¹¶¤DÙ(9ÊI‰Q&1·S¼9DqæpŚ»jdt/ î«aÑ44zˆ†tÓà®cÓ-Mƒºåh`÷yн\ÿgºÌ£¢:Ï0þŒ+*"àŽEP”E†a†eXT7Æ( +.ǚb´¥š&Zš¤q_cÆŒ5Ö¥1Ñx¬ñXÍÒ¨ÑZMÒäD§? æøÇï\†{ï÷¼ßû¾÷Þ÷É0¾¬tã^ƒÍø>|߂ûšñ3ÖÁs°æ1þTG9y™%ÑÝ41ÆW…1~¨ü˜PåŌV®1VÙÆ$ٍ6es”[ ŒØ2¥Ç͔-îWJ3-Wª©AÖøMJ‰Ý`‰?f°˜¯r¼îŸ1¹ 6Ó Œk`TÃþ7ƒ8¦“bŽEqgò–ÃÔO9¦Á²›†+Ë®ŒøhÙâÍ`Uš9K©æq²&”(%a†,‰ó•Ìpœ”¸F‰IÍJHÚc0'…+ð ¸ ‰?ó:cx#Ô%S˜3ù=•|K!1å'tTN¢—쉽•‘è/[ÒP¥%”5)J)Iq²$[”œœ¡¤d‡-“”`™.sÊ\ŧ<+SJ½â¬MŠµî2ÄZŒÖËïbS‚»•žIÆð•°ªÀ ¥ÄQÎg[Ú)#ÅSi)¾²Zýd±Q²5D‰©‘JH5ʜš¨ø4›Li¹ŠK+R¬mªŒ¶9Š±-QtzÆ¦oԘôÐ¢¨ôKïjŒí0­¥¹µÕÊ;1Uªe ¯† +˜Êï‰üßv~§Û˜7m]•œî­ÄŒ~2g V|F°â2Û-c¦Y1YVEgÙ56«@cì“e¯Ðh»K‘ö•Š°oPxöv…e† +³ÿGáö +Ïr+^eý†ti)̇Œâ¥ ÀÎ߶LUvyWMP*§¼ªªÕ½j4ʳrºUS·9×ä9û¾ºÏ~ înÕ¢µf@ ¶p¿‘¼WKžXÕN/`^‚õ¥ ¿Šÿ@‰£‘8šˆ£)‚¡a3/™fš«‘fl^˹-ð×~ä¢ñž**Éuvï4Ï{Ž¬•‚W¡nŸuè£Ù•-thF›t2àK¯ Æ` ùØÊP¾y;ÃèNâØŲ‹ÍnþÝ{7‰ÝM.v7ñÿ7€\ìºÄµ7TN‹(WÖRjÀžÇü–g€p­GŸË½_–º¼&h'Œƒ?ìmãMØ×^Úï!½…A9€18ÈP~ˆ!ý0q¼ËÒÂG°…¾…BAè‹·l†ƒp.ª„|çžµžç‘ì7ݾ\æ½ýGšûà‚x¯£ð`K:Ž9:Aœ$'§©Íß1 +ÇG fó:GMÎÑhçIòù Àâçކã* ß¿ç]ÐÈ{€Ý.ù¡ëCûvy¬ùHç8œZZgÚ8 ”Uçàø|J}®Ð'×|¤/ü¤¯‚¥ëFé„›ÔäkŠ~‹»E’o#v{n¯;tkÃü`Œ3¤ãóõ?M—NñÎÒ=üå]üå|îm-Ó-­ÐM<æ ­ÕW8Ë/ñ™Ÿãt?ÓºªÃºBà—9sIߦ»•‹m|Òêy= Câ魇 +ЏÉFý¯{ùoèk•ê:þòKüåçøËkÄñOâ¸B—õ<õº u:¯ú˜æ=KÑ[Dp\§¹êџDáÄœlAOЕýúpå@öÌÞF½=+ä¡1É¤ÞI *ô!q|@#ŽÓÄq’8þªÕ´Ç‹”¯™–ÙB)÷’‰½Ão“±ƒdõJOòXÿÜWGt½Èaö€Þ(öƒV2:™hä³£‰:FG‰ãq¼K]k!íº„õ—³æ*íWm¼õWxŒvjgv‘…úBÛõ­¶¡ø˜­m1<„{ð/¸H.ΐ‹“äâ}ñž"Ñ1±++ÙYëO䱜LµËY–vÇNâØAÛTúuÚLMþ¤&¢Ø¢MÜñG2Ó¤OÕøžË<¦íóŒãŸJ‚‰pßW0`6Ø`À`6`ƒÁÜÀ +$¡&!Is±MÒ4I›&kÔf]zd=Uu«¢®«¶µÓŽvÕ6µÕ¤ýQ©ÒºNÝ:mk·UíŽvÞ·d­¬Þ÷÷Úz¿ß÷ðó{>ÔI}ÎRþ’/Öÿ‘xW¼%^Õ½ø¡îŋº7ÈÓZÊ¥c×:š´ŸæïÖü\—Gåãù¸&ßdQû¤qXóžÔÍ<¯pz…ËúÕ}šá^íÖݐóÚés:ñóÒþ’DÁïv)^‰VˆY =·HÓ¨5¥K¯H:Ò©Õ »¥Ñ. fÆ¨4&¹$åã^íÇöKcEÿ’»ô¹Äi¹;¥:©Ûp\'zL»}Lçñ5iÉÞÞTx{Y<¯ðò”ž¯+ì='Í$éeK«D³Y¥ãäž5ίéàî¨ g£85Êé¨0w®½•“k8¾vÇ¢±}'G×ÝÃáuW9¸þIîXÿûc~ξ[Þc_ìÇ,oˆ°÷ÿ¼£ÐúS…ùçÅã)z­(Ä]Qxùº!šË·¸'&™s±yÜ[Æ© ՜ÜØÀñ-ÛØÉÊÆŽÆ p8nŒCqSÜ7ρ¸Eöö³l8ÆÃyn7<ÈRü슁Ûâ_gaÓûì4~Êcä+ÞTh)çæ«æê_ÊÔë43 1œŠ7r|S+Æ"-4:8àbBË ~ö&ô²;aˆÛÆYLœfWâN÷²#é(ۓÎ2—t…ÙÍיI¾Átò«L§¼Ç¶”O˜J|ÅkzýÂÃJA.©=«çyJ-ä爼J6p 9™å”\v§˜XJ­b1µŽÛR›YHõ²#-Àö´si#̦M2“>ÇtúSé gœb"ó㙏²5ë;Œeý„Ñìß2’ó±ˆ|Å+ +çO›ôúçÄ =.VÊ%?{åewV,‹Y ,de°#»ùl3³ÙÕÌäÔ3ãa*§pN7“9Œçnekî4£y Œäíg(ÿƒù(¸FÁsôþˆPá;„Šþ."7)ŒðR¹î .‹ÓJŎ¨].ƒ%ùY—ë˜Ëg¦ …m¹„ K˜(¬d¼ÐÁX¡‹Ñ¢V†‹ü õ2X4Lq˜¾â턶ì¥GIP°äݦ‡è2=K ôeñ6þÒ¿‰ˆú7¹Q×¾H¿”úÔ_ÒØNy›•—™’5„Kâ/Ib¬$“SC¦rM6úMNúJÝô–úè)í&X:@wÙ8]e³øËo§³üæs´[®â³<ƒ·ââ7âCñ_Ák‰ðœÒ«6Ý¥Gı ±Yy™Ò¾Lh_Fͱ ™ ˜Óè3çÑk6´TÒmqÐeiÄoi¥Ó⧣"D{Å(¾Ê¼U»h­:D‹õ,ëxlOá¶}ŸfÛ¯Å_Õÿ\DVyFšW”fœ•/ªÛäk\û2,ªÖªŠ'X•L—5¿µ˜«™v« ŸÕI›ÕM«­[žêaÜÕS4×,Ðd¿—ý Ž+48ž/QïxKüEýÏDd•'¤{©VwQiÆ>± fô<¡ñaùë¯QÍS³–@M5‰øìxí´ÚKñØ+qÛ4;\49ÚpÕvÑX;HCÝ$õu;p:÷SçÑ©ñ6µn5z¢q¶¨mIÄޚNuk>¶VÖ¶JªÚT¶¹¨ðz±xƒ˜½#”ûf(ó-Qê[Á仗’öGÙÒ~C¼Îß(ñý“7²Êý_”eJ¿÷¶À¼˜ƒ"(¼¢YåRƒÒâZŸòþö X;ŒTv¤Pљƒ¹³˜òN3eÕ”úë1ù[(ñؤ80EQ`…#.ßõ°xž¼®×È ¼O~àS +ü‘U.¶ê.HgIÜ*­1Ñ'üÒô´ký*•j;Á€Šîʃñ”“(éÉ`KO>Å=&Šzª(ì­¥ ·™üÞòzûÈ MÚIvè Y¡»É =DFèÛ¤‡~&~OFï'döDÈwKë ´Ĕô†DP´K·IºN•®ÕAé÷‚©?Š¢ ÉL!w(‡œ¡"²‡Ìd U“9Ü@ÆpéÃA҆GI™#yd›GΈ«$ ?KâðÅ»$ }ÌæÁÈ*wJkY©ÿœôÆE¿H·M%ZcØU¶V¨ö‚¢QÕ[cȘ06‘HêD:)“y$O–°y²‚¤ÉZ'Ý$„ýbcxšMáÝćOb_O7ù²xÃÄGÆ?#~<Š´µÎi1"ÍÑ¡5»UžÕI»JåQ٘ôUžä†!}z I³±$ÌmÂ8·™Ms™ÄÏ`˜/6âæØ8ïeÃ|/±óÄÌßÆúù£¬›¿HôÜu¢æ^díìDÏ~@ô­ÿcºL ¢<¯0ü"‹"2  +*ƒ ²ˆ5®"(Ȧ((ˆ² (8* +Ž+¢ŽË©â‚©1n&ÑDŒQc“Ô%§iŒ[5±Ç¦­MjÔ¨IÛ4©Ñ4>99=žÇ™ÿgþûÞïÞû}ÿ½ßÁTÇ:+Ñ+„Hϖs©ÃÍ'ì'- ŏ;øq?>Ə›øqƒ)öSè&ÅÕªtÞÓûüâ"Þ_Ðu•~ïuú Ÿy®®ú§zè±üYWzÑú+±øTXG¾OÃ~>á/Â~ö«°¿ûµØ·b-v7RÛ(“=z›B>C,Nóÿ)V|«íú^ÑÃÁ‰ÿóá)¶P+[©]GñðÙ9DF¡xÐÁ!‡úáNg‰uÓ%y³Öab QhŒ@#ûÉØÎ`›ä°5óõ2yi£>ZUýƏƒøq@ëÈÄVŽf*ã%Ž”cDåÇËu²ôX;õØ;Ùúà–£äM,Þ$Ç©‹WˆŽ™5Ä 1 +û㱟ŒýLV˜ý<½HîÁfü؅;ñ£I+µÚøÿoå—[°²‰ˆm${•»ž +_v£ƒ'ý l©SŽ#§º8ÈiaìÓtÂÑŠÆüNÀr +ö3¨¾l4ò´?6ᇍ¼l >UG$Öòo‹Vãá*V°‚Ì[Éèrª¹žª«cÇÕ£ßÁ_ºKïs¬œ4 Íg [{/Ç^³º£g¤ºÐ A' +áhŒEc)hd²²ÑÈcå³Ñ)E£ +»‹µŒ«ZV¾„È,""[Ã.¨vº­ê._iós°wr#í ÇkGý>>wp½•ãe³‡³l®­wòUƒS Vw ÕJçhYG¨Þ%Vu.‰ZꚢZ×L-qÍÑ"×|Y܊TãV®j·ÍïZ¯ª®ªèÖ¤yî-*s?¦R÷wTÒýc•xJ1›”l×Dó%™G(1,V a‰–¦øAي /иðrÅF,Ö؈‰lÒèÈCuR#£~÷ùþ=Ø;iAo mÆ +Úá…1Ä +ùžÇ½lü˜Šé09ÂC“"ŒJŠè­ ý•ªøˆ(ÅEÓ¸Èъ¯±Q)5U£çkTt©FF[4bȽ0d»†Ç¼¤a1íó|Á÷§`×ð!víòS\7”yŠa&äpo +K#.Éø“ÝM Ñÿ£ºÌ£¢>¯0üdQv•MvD}†}GEepcÄ `Ԉ\“Ƹ ¨‰5q‰¦iFk¢¤U“ظ/MjzbNsšÖ5MÚSÓÖTk7ãôIOûÇsf`fî{¿{ï÷ý¾×K9‰YƒeIŒPfR¬ÌIIÊHJWzr¶Ò’‹•–R%SJ½Œ©MJM]¢ãj%7)ÉôŠMG”`ºŸóþ¾’ŒŽA¶£õ,Wà}ÀžÌzÞ×@¹óy>¯9©ÎÊJõT¦q”ÌÆ¥Ãd2Ž—ј T“I)&‹’Ó +`²’Ò§)1Ý®„ŒEŠÏX©‰gÞ­Xóš`>·xÿ7Åe8نV7ºm\›3¤™0*ù»òùÌÊë¤ôǔ‘á.S†R3Æ(Å;[Ñ9%ŠÊ©VdîLEä¶(}t Íè·à±j®Kœ4l)w)·‹W—že 7Úv2ílí {Emgíó¡6Ãk|÷m~snãžæ²Öé0Š(…z§²æ8»E B×°Hò~Rr_&¹,çÒK8­p.£+©Å*.]«¹ðtqáèæÒæ‡Ã­‡Aïaa=°§ èGϾÓÏw1«]_ð»¯5 Í©PFŸs([Ú\ö!kŽ\ˆ>ºZéõiÄJÉ©mì*si-ñµä±Ž<ÖS Qòè zt!êãaØGOú¸>jÑÇbúº`;Ÿ’6úÑ{[ èV‘fõ6S²DÖEÊÁèV¡¿Fr{Íõ° ¶À6xh¯¾ç$íà2þóÞÒ.æc}ÙËÅc³±žìcÈöÑÔ}ü¿¾ǹÀ}7TG½KH1‹±IaÍ1Ôyë5 ë¹‘ÚoÒz vÃ^xƒùá2 +ûá†à 3ò#jr˜Kú‘ yô3ý6ý Y+0›ý;Š“ég6~¨ÉK8“ÑN[Á °æÐuÌ?£ãEÉ\vih2@oÂÑ!ނŸÀ18ïÀIúó59͌œ# ì• </²W/RôK Õ¥ Òe_&Øå“*F;íDjÁšÇ’¢7»¬ïàæ€ÖñøpjÀ”ÁY`›ë\‚Ÿ šUé +ü‚þ\eN>aF®Ñ—ß2£×éÉglø ÛM†ëæVéżu§õØ ïuÈ <ÀÆÁ=”wš'-Õ]UëŽêõ'üÔmüÔðu¿Ç×}›úœr Çuvxaù”Æ}‚kü˜‚}¤Ó¸Ý_ëC<ÞωüÁá <Òÿ74}t÷WEé/JD3½|t*ШÅ-6¿‘ø¿•øKˆßAüNâwë}üÝeâE|æy\ëY"ƒ·qyW(ãõ®Ð2Ç9ö?9<„{Î=õ;ô™Bõ¼î¯¨ÅDz¢QDüJÊ^GùtŽ<ΐÇ)òø)y¼‹³|‡XËû5î<Ò\‡iÕ0w´|ÑòG'X4’ÑHG# |4Jô’Ë=¶Í« ãOÓÜ»¶[;iì$Nb'Ž'±sqb×±sq“ØiRçÒÄMš‹Ó6½¥Zï:íÒum·U¥]K+T(L\¤Mh  B€6þá&B Ć m0ډ3?Ú?~:ßwü}~Î{ÎùÎû¼˜ýŒcûc/ßËÔVˆ0³î¬–Ö]ÔbÎ -ä|Qóë_‡75—ûŽæòþ©¹üO «op”}ãý©æœãú$Çì1Æs´4WG + :œkÑ¡\»öçÕi5Ï«½ù~íÎj%?¢LÁ€– F´X0¦…Âií*œ×\ъv­i¶ø´fŠ/hGɋš*¹§É’×5Qú&¼£”á>dò +éö³e¤E¬ÐãïÇi׸?€-Ye,«Æí-5j¥ÔªåÒJ-–ºµËЬyC»æ =ÚiˆjÖ׌!©Ɣ¦iM—5a<¨íNjÌÄ®1]ר鞒¦×”0¿¥ó»ð‘F,YÚ¬^F÷ºƒz¯’ø«Ð§ÝË}†c~‘±,lZ§s±æLf¥Íåš1;5mnД¹E“æ¥Ìam·ôiÜ2¤1˘F-ÓJn\ÐÈÆU c>¶nzRqëU ZïjÀöuõÛ~¤þ²?ÂÈ>ä.š/8™lجÇ>Xæz{˜f,3Œqږ¯)«Q)ë&Û³ÕiÔæUÒÖ¦„-¨‘²ˆ†Ê´µ,¡xù„Êwªónõm~LъÇÕk¿¢ˆýsÚâxUaÇà +WÞ§ÍÒÇy…ÞEÒüi—tÈ-­À<×3ôM2¶s3îÈÑ6{©’f ÛË5dw*n¯× Ý§G»ú=Š9bŠV©·r\‘ªYm©Ê(T½¦žêO©Ûù¼‚5wÔUóŠ:k¾oÇÜgòZçIñǘìè"Ìr=Iß8ce^Fː³HƒÕÔ_mUÌéPÔY§^g£¶8[®éR¨&¢žšAu׎*X;­®ºEuÔT»ëŒîËò»o«Í͉[ÿ=µÖÿ–ö¥?«kh=îRü˜‡io¤Þ¡˜yd,}®èTckDžÖ¸ÚÆTߖ–Û¿G.Ljÿ¼j7Tø2|[ÎÀ/ißW­ÿ?Õ³èœ@sµuÀ~NBâ£/ ]Ðmþ|ùü5ùÍj ”ɨRCÀ%w{äj©®c@µ£ªéœ‘³sE՝GTÕõ”*»^”£ëeٻހ_pý7úþ­Êάžæ¿øÚY‡jN~î#?÷„©¦ÎyºJäšä +ZU´«¦»VÎnª»ÛTÕTeOLŽžÙCSª-isè°ÊCO¨,| ¾$[ø[²†&[è=•…>Vy¹ý54–ИÁVˆA: …RÅÛ#Շ¨}…rn1ª*bQe¤\ŽHµì½nUôú´¹·Ce½Ù¢C²FSÚ]€CÚ;'KìªÌ±{ðM™b?‘9úWY¢ÿ’¥7«3hïÇzÏ£3N Að£Û„%nˆà»£RU_®*úKT>`RـUÖA»6 Öjã`#øe ɐ)>s2Æ÷Ãâ/À]•Æ_SIüÇ´ïÊ0ø²:ŽÎtfÃ|0„^ BÐ-½’'Fü”)ՃR¥›u¸P–„Aæ„E¦D¹6$«dLºeHú K¥É˜J’ 'w¨(¹[…Éã*H^T^ò¶r“¯*7ñCå%~(äcFg‰§ÐJ D HÌ~´½h»âè¡O™b¥l3åɘ*QIʤâÔ&¥ì*LÕª Õ¨¼T@¹a­ŸØªuL.…ä…ëELê%ø*P¤l§Ö܎‹Üþ‘ö¡3×Ç% C„Ñe{ˇvý°äLJöm’Åϳ‡Ë?åÝ¿À}í"Î ô´JH†ï%æ:bvÌ ®™RÑ°$®Hë÷®ã@ÁøíÃpíÇìÀhĈ²ó‘‘`Ö¼>¶5&ym xyõX{†g(b᜾âÝ5‹Þ s/w¦¤æ)ö1Wӏ®‰0JW©AJëc6ƒ£Ô”G1¡ÇÇ ã#óuÊÆ¡KÂ?C"<˚œeße.Îî o-ëqæ3<ƒ{>MÑzêmx_ShŽB?óÝÍ´µ¦Ù |ƒôÑ5¡[ByÇÐ=g¿Â®’ìr¤'™§¨oϳ.Ï0Žg™KŒã2{ã9ÀçØà— ò2{ó2r‰õ¸„{¿øüœçÿ¬ †8Ä|oa¾<æ!æj¶ ]Óq©øŒ”ó8zlk =ï?4ݸWáӘñ녘r ò öÇÍÿDöèöÆÖä›î6B·Ðÿ4-ëq‹õ¸EUsówJ2ß1æ»sgÔ‘ÊþÇt¹@5yžqü_!1&@€p 7ä"   ¼Vê}Z«V[;«S×nÖUë¥u®¶^ê”Z§­½¸YÙº^Ö9»ºº¶®gëtk×é¶sºZ§5ûa³çwø¾/Éóÿ¿Ïû¼ï÷>Œ×„nøZr¿1¨÷xvÀ·šщfK´0ß4&{C¥ýääYææÇÔi>ú¨>椏ÅÕÇ û~˜õqè°>ýJµ³%?ùÎAÛ¹B²>ˆþzôƸ%¨9 µöÝjÂø]çà…cÁFéõú2ur’¹9ÅA½ŸCa?/á~곟B;Øi÷ƒ8Ý'U¹„9@ÛõmÖcŽÂâ°íAÝg‚š|•FW´(ćWá$ü ^ƒ~øE°a{3ظž!'ïâã}òqžý=/…X€RlÝ $÷I¼pˆ.G·&°ê&ýÝ åҝúõ…jèK›t™>æoê¢Kšª‹š¥OèlþH·ó1ÝϺ¡éÆÎӝ£S{—Îô7$ïÖۘ~S¿Åâèõ §à¸ÝÃMúÌ«2ґZøv’>§×ýŒóϪ@§VÐOS;ñ»tF=ğIü»õ–è |¼ŽŸÓݞ¦pOÑ©þ”¢y•ïe× \¼¨¿0]×¹ Üâ¶i"±'kº£ãÝL>ÕR¶ŽXÒÈÆfæ)®Ž°½ôÃ'Z‡ê:´ÿÇ%t,óe¶v+Œ-ÀHü|';í!›ø…Ä.'v5±ë‰ÝLìqTa'±&3òiÌB/±mt9.Öh¿XI´dn9³·LïÁ?à¦îE€³Á¥v(¸Ý ,ËÍäâr±‘5²^qÄOÖCr1—Ê/$v9Ûuñë˜ý&â·q'“éÌÆ-æï[|c!.©yds.3:— +ž£Oán1°¼Ã.¶þ̓¾ÙŠ×¼ +¨‹U2 E|ñÄÏ$¾—èEÄ/×"|,ÀÇ||ÌÃÇ\òq7õÑ˺½‹§³øÕLÜOgTÓáT2ÝCe÷èOð…ºÑà8[ÚS6óú[÷³Õ.çÙR^‹Ù/i8:4ðìD# <4ŠÐ(G£J3ð1y™J}ôP§Ý\M曓´„»ÕTÌ÷p÷$™:¤ª½ƒ¤ùè`vàá [Ù6¶÷ ¼jV˜Ïý^?½á!š=8-:qèØÑHCÃÍhóÐ(f…–£S­‰wÔ«óŽMÔ¡öAS4>ä. Y¤ÖÁ«Ô2øa Ý©æЃj +=©Æ!çÔv®A@{ÐÜÄql5[ê=0f±ÍOã5Ü3\ê6„ª;Ü IC¢tg˜UaɚæR{X¶ÆõiÜе ­Tkøhµ„7ª9|œš†u©qØ 5D,P}ÄJÕEnÔèȪ‰<¨jÃIø\ëÐhn8zŒ`üÇfB7×]<ëÄK^:ŒCÕn0jœ!F­†x58ÔlÈP“!G†1”ªÞX¥:c½j­mœ¨êáÓUeš¯‘¦ûTiÚ¨ +ó•™ÂI•šß‡ª4êkîÙ#Ð[c#;zyÕöÀ\·s,kã³¼4G‡¨Ù¡F“I æ8ՙíª5§j´9KÕf¯ªÌÅU¡‘Q£UÕ¬òè•E÷È3G%1ËTlùŽŠ,ÛT{^‘/ö=¸Âõ hZ÷£»WìLŽ¤“ Zìœ1yހ¿:¼ÔƆ©ÆbT•%Z#-6UZ’Uaq©Ì’­ÒXŸü±¥*‰­RqÜƍSÁˆÉòYg+ßÊJ²­U®m«râ÷);þ%8 çþ:ô0Z+МËQt*¯ØNhåº1mž×ðy>GÚBTa‹T™Õ,¿5VŶDٜ*´eªÀæ•/¾Hyñ•ò&Ô)7¡U9‰]ÊNœ%}±ÜIk”•ô˜2“ö*#ù„\Égàs®ÿó€Ö£³ÝÞTú=Ž€íÐ õÜWó|$^h)UŠ—b{¸ +íFùìÑʳÛäµ'+מ®œ¤le'ùäI.“;¹FY)ÍÊLéT†c†Ò‹”æ|P©ÎÍr:Ÿ–#õx>“3õÏzÅhÎL§9þµeHcø_#yV†—òRùŽ!ò: Êq˜åqÄ)ˑ¨L‡SÎ,¹œyJO-QZZ•RÓåLï#}šR\ ”ìz@I®GeÏØǕ˜ñ6|ÊõW<h5ú ћ–É<ÀXŽuPÅu9~Šù¬/^ÈN‘Û¡ —I.WŒÒ\6¥ºRäÌpɑ‘£”Ì"%gV*)«Aö¬ñJt÷(Á=OñîU²y¾/«çGáù ¼•Õ}U6w@+ј‹f·›yðPP•Üû¡€Ï¼à†LîÓÝCåôåðD)Ù3BI»ìÙiJÌö(!Û§øœrÙrjeÍmӈÜ)ŠË£Xï}²xQŒw7U´÷ ¸Äõ—²ä´ŒØ½hN¢%iãèÙUPE<˸ré{ Ū¤¼H%䙟o‘-?AÖ|‡Fäg*Η§XŸ__b +Æ*º KQ½2.‡ïÊT¸ ž—±ð—^pQ¦‚C@KП‰ÞDڑ±P •P>ȅLÚÇÔ|ô}ô^…ƒd+ +W\±Q–âhŔX]’¤¨’tȑÙ_$“4ÉèŸ(cé,J—*²t=ìT„ÿ°†ùOÃÇ\ÿK‘%7´±ME£F4ª¡ Š gžÿR]æAQßg¸Ø]w‘EЪ(* +È-,»¸‡«» ˆ +BÁŒmªÄƒÄD3iÔFƒ¹¦Ui;1&ͤšÄNk’NÇcšÌ´éL56iµÓÖ£­c³ý,îdÒ?žY–ýýÞç½¾ï÷}øÌF¦L+ƒ¿‚Ý©`«ŠWJµQ‡Ødv|dÉäȕÑQ ìJvú”ä\*ƒ³C Î~Å;·+ιO±ÎcŠq¼§XÇïç¸þ¥^8V±„ÕÛœ`>(ù §Ý÷”*i¢ýådÿ_+³;IFYIžñJôdÈàÉT‚'[ñžÅy*ãu)ڋ€õ®ˆ'/ыpð| <è<Ï_h¾Ûê&¾åðáq;(ó@1τ;³~$Jš ~d›Ù«äʼnJð›°**À@0àô ¨:3ˆž"$ƒ© ú*€¦ –ˆ!ÿyð¸­U•ÒRxP Jí­lÌL_€öqÿ~Lš‘lÉu1JXbPt|ïR.·Fz#ì‘CÜH  Ñ –‚N€˜jÜų#aÖðKðgpK-ðÔ/p€ +PHÌ9ĜE̓}èO?üµð/¿QŠ_ƵœEgKO ËF+—k+:w%—KƒµÃÖF.Ú(\/¶Q¶u`;Ï°-®D¸µþ°M·ÜT\~àvPBÌsˆy&1O Â_?¼æf4`‹‡9†‹V§AZM.ºð£?ÖP“Ãpxøs {ÈEÆz–êÑ3ÈïÏñr [d÷§àïªç¨!måÄ\@̳p}jƒ”Ϋ)ðšÚ$C‡Ý7¦XÓlàaüX‡ëñ£?X†6N`àÂÝLM6s°6“‹Íôæ¦U|RM»y†žØðSp‰w®+§TQç"Í¡|™ÄÌÕ«^3uK a·A?À ¹XWY<Á£Ôe0þþ":„ÛÈÇò1Ì%7ÌÀ¦é‡ p£;q|'õØq¥…žØöøL~xÔ¹”|çÑÂӉ9c5ü=’‘Æmˆp> +¶‚í‘Åûqð„î/âO=äärò, êwéÓ}øq€KùCðM~€Âî'™ûq~gôù£<÷>¸,ùžO¾ ڙ…äzb/üÄk„—u?#|ažgåD:a/€Caq0&ŽXÒÉÉkôêðãu¥7F‚£4Ú(¹8¶!Åù8ÊÃGÞâ¹ä ¿ŠàÎ&M“¤ñÀÿ˜æÝá s½A¯Æ ";`4"hu©ô&x›ú¼ƒ`x?NsfOÓ§8§)øûœÓ÷èÍw â/Ÿ:©r¸óà΄;˜Mä6îÙïH„óhD…9pù¦ÒɈH#¥ú88rúpüužÚ\ÀË,b—©É%ý% +~±O +y‰À.þ…¡¯!˜M÷ÐwÿAÏÜQ‰þ¡jÝ@Ç|Î½†:¹Šª+¥OQ8¿ç|‚¢»Œ»HÓü–❧I~E?"ˆsp‡Ïè×hºë¸Bå„p;ÄC¤-ô>ÜU”n¢3o ï>×$}†ž¹ª|ýQúX5º€Î=¯:ì7j öÀ~ö{°¿û›°=Hj¶“¢=¤k? +óUxŽ“Â3z]WÀ]R¢tè+päk>ü\P\fýFi¤3®Ò[G¥P'Ø^„ÿuz›|¼…Â:êzö:~üùCüE©Õ0-³¥{/ŽÑJ'iÙ : ÓŒ‡Aøó ¸ïßƸE¶¤Ÿ+Z§d$†üŸˆý,¢˜ƒß%ض㷋–\D›ÔêôåK¨ÉèË”à!ØAüøž6“­Ÿ]Täyï«xs‚cuåù9ú/Ÿ¡¯pޏ#­ôN¤õŽÈÀ[f|·a +Gböó±]Šm;V]Øöa;ˆíl/Ãn«vãÇSø±‹º<Φ7vÀ²·#‚­dr ´E·Aè+|2»ðòþ‘;ú1Ø7bۊítìf‚ÙØ.Àv#ʎíØ^ˆí¶ë±ÕDZéÊ=B]¾¥FÛ •yBðz€ÌõÓ}d»Èûô%á,œÇã%2vžŽŒ¿íäbˆ\lQ*¶'a{:¶sυØ.#ÛUŒíì{±ïÇ~=Ñ7Q‰•ŒõÕêåByˆ§ÄÓ5d«‹Œ®¦¢ôf'Þ©ƒÐ~á.Â=Ëß$8#ý²`; ۓ±=äb¿ûeدÂ~ºñ£ ?:ñ£CÍZEŸ¶óKo·’‹Îê +êrz³™SÓLõ›9ñÍð‡q,ŠøãǬƒ`#£v£¿—ÿ÷pFØH±oÅ~:ö§b&'2ŽB".ƒ£ +Ž8¼p°Ù@w¬àÔtÒ±kµ„ªÔÓuÔ£–jéö §.¨¿‚»€3ÂHÝÃxßÂU32Ý_ Vq ¶ÇG©-*3VÇÑG&³àȃcŒeðTÁ³<µx²Œ¬´k1Qø舅ÔÃK‡yèt7§Í͉w3 Üô¦öùsW;#µ—k·#¼ñw3×p¿5&Ū1>Y 1ÕGÙT5IÁ¨i +DeË=G‹£‹´(º\¾˜jycÜòÄøåŽm+¶U5qÝrÆ È?¤êø½²'¼¬ª„ªL8®€›ª4ÜÓ^ø¶°zô¥¿íþJÖÄßKXkñ'€/S¼üIF-6Xå3¤Ék˜,!K.Ãl-HÌWMb±œ‰óåHªQu’Oö¤zU&¯Ðüä.UûUfR©q¯JL/«ØtBE¦Àp |©'áú6¼½\³pÅ-õÀÏõïãÿ^~w[¢å6ä2™UcJ‘Ó”®jÓTÙM3TeÊÕ|S¡*Ìå*7W«ÌìU©¹VÅ㖫hÜjͳô©À²Uù–½šk}Es¬o*Ïú!¸îð=¤pmÌ`­cmázk°ï.|q⛃¼ØSbUeMR¥Å¢ +‹Må–I*µNS‰5[ÅÖ¹*²«ÐZ©‚—òSš;¾IyãW)7urR¿£Ù©O+Ûö’fÙÞÐLÛ9pÜá{HCð÷ÁÙÁ +ØÌúU |ÀÅwä“*ñ¥_ÊñµÔ– ’T“ŠRST˜:A©“575Ksl¹Ê³*×V®DÐì´Eʞ°T³ÒÛ5#}­²2˜.»5-cD™Ç55ã,øß! ¿Îö°4`õò$“|ÿÓeÔä}Çño…Jx  b I€ðä5AI*‘ˆˆà;–ùœ¢ÎVÛYKífµn¾”Vúb»›UQ«óÚy­UÛÎÎÛº›uÕ¶»]ﶹ—ž]·›×énÝÖ9ö d½÷½'yÂóûþ^ÿÏïÛÀýz|©Á—*|­ÌW…%Ye–ty-Y*±ä©ÈR O®GîÜr¹òjU˜×(§µEk‡ +&-V¾­_vÛÙl»4É~PVû÷•g¿~«<ÛmYm£ÚÇj8! :œh0 LõÜ«æ·Jü)çÿJA±Í Í(·Í¤B[Ž6p©ÀîU¾½JöüÙò§kRA»¬Ž…Ês¬R®ã~Yœ;•ã|Vfç)e;ßוí¸%³ã?ÚÇ +øzXûÚ]ô ›p €îUò[(Áp9&ÊéHQ#]vG¶lN«¬N(V^¡O¹ˆS‹kšr\m2»{”í^¡,Ï&ezvÈäyFž“à¢Ò=¿V†û¯2¹ïhö‹•oh*¢ÿ¸ÖÉøSJøÝœ|ÎwÇÉæI’ÕcTn‘I–"‹rŠòe.r+»¸\YŵÊ, ÊTÒªŒ’ùÊðö)Ý»QiÞoÊè'”ê}üܔ±ä ­ÅöRøæSp’ Àµø@)>”ß¬È8Ki‚Ì¥©Ê*ËPf™Y¦²IÊ(/Tz¹T) ±j¬hQjE'èUŠo@ɾA%ù†”è;ªÄŠs2T\åú©’*>W?öa;‚íæR©ԃÉ|ǤJ€ pϊ|³THÙ¾x™&')½Ê¨´ªLiØÔªP¤”*Ÿ’«ýJªnRbuD†êŚX³Fw×lU|õ^ÅU¿¨ Õ¯+|þDñU·µûݬ¼mØo  ø¸W +<ÀÉw›íƒLÈF¾™jâ”V—¨ª’üJô›eð۔àwi¢¿LñþÅùƒš@ÀØ£+¢,€Xð#ü,ç~o?Ûcý-õb¿“Øfªä6WBQ9(.îåÝW -üõRZ N)S 24¦êî`ºâ¢‡Xƒ$HÓ)ZBh«B6„€ ¡)B›Ú&ȖD$4¾>·´Ž±…ÁTP *1Q +<|.¨¡HF3ńٴF4P(N†iÅOç;J˜N3‡X3ÃÛ.kᡖ&€˜lAĵ )š³0‚(Ìö4ýà–æÃ1‹ø¦¨æ{ ½å$f[ƒ”3þüÓàK†–»7“E£•ü,^®m¼øf“‹v²Ã)¬‡#Ô#²€ÏˆÈvël¶µÙ/ñ dÛïxþ–:ˆ¯4‚z0^o€³¤Q&R1´&·J ȵ „¦¹è¨N–yÑ=/Ùù¼äº­ã‡MÔƒÁœîéä>‚²›žèÞËÿ!»góØæç}¦6blSà¬å|ös>iÌm†¦d„7yp.Ü]€6Ó­E,`‹ñc 5YŠ½Ñ„šôQ“>¾‚ö9€fêq/¢r9br9Ûc/[ü²yî¦fgÎ0™Ï%Äì æÜ.mÃùmÔã¡ýÒÖã,°ùÿëšo€:ûH—»Cš„»YÄk„7±f-Åÿ×æØÒýPl,ƒ`Ø'í&'ß¡O÷Q—!ztˆ~ˆÁ"È'(â~ØÇ¿—sbÏ«üï5’ï*ò]ÜMsvü¤,!Ê{_Œ3Ê÷hlù<&Bh-ÖTlDŽÉ0 ň2é»ää=r?FèÑâì(¹8 +Á‘­Òa:tüPu¸V·ƒŸrŸ4ò›°%Æû-°ì‹ñ|Éé4.ÎF©&‘1B¤Jg蓳øqº\à偃èE?OÏAr–3óì!pF•p»áÎãvúRâ#<¿+Æ;ã<ãa¬u:ƇQôx\Œ›(±.ŽA]¦6ïáÇÌìûÔä}fõ‰¿J‘ß#È+¼{‚í^ÿ‡8¬£iþ‰¾û=syS~}ŠŽ¹¡™ú=*â:ú+”ÍG É/P]Wiԟ£%.£«~Já~BÁ.éi\:¬·Ðop÷¼þ¤s0¼^/càü_€¿ƒ¿ ­>Q\f¸ +ô4æGªÖ5tÌ»jÂÒLý?~„ʹˆòy -óJòCá†ÑxЙOEµØö‚ÛðÞ㱍—öh­4¼7ÓjvP„}¶ëhÅ©ø߄ÿ3ô,jñiÔÞ0Úî)á“(Ò'´ +ÛØÞL5¶ÓÒ{ðä #uŠÌ¼M›ß`”ïpEW€íàãhë€óàT¬ÕŸW<~§`;Û¹Øv0‚Å´i%ëômüx}¹ %ùêrǘªí¢ as9ÇÆjÆj=ÇÈ7ø{L`e º¬RÒ5ã:ú%.ÇZ;ÚöÏÅÆ}÷ØQ`ÀO#6³€ÕZˆm/®¤Úu؞‚í{°ÝŒíVlE°Ý¥ø±º è«TeÇê Ÿöе/àÙi²ôŽVқ«àŽbõXŽø÷öØ1¸™\ÜG.¾®t욱k.l{±]‰íZŽÐ쇰ÆV+¶#é]LÊb¼ø +YÇä:†ã1~6➏Íktv Ø5bׄE ÈgÜØ÷ª?–áÇRüX¢ aì¶2)sèÒnþ–áM?Ó³‰ŽÙ®:e•Ž05&9¢ÏÀ(÷F©ýøñ»•ãdè}¼{¹·”\,æ¼XH. &=ôFóڍóñc~tªŽ!셱ۦvî¶á,¼n¥/fÙ:´™z43UaêïKý‹ï£âH}$AÚÈ+oX&²fp¯‹ß:9/:¨ÉjQ6ö­LC8Já¨dRÿËr¹À¶u–aøÄ‰c;ǗÄNì8NìÄvlDZs¿:MÛ$m×´ ½ÐKÖ­ô¶¶bíºBJ©ÖA·VëS·¡©ÝVº1D¥ëm0Æ؀A h*hš6&.ZQÉÐPG‚'e=:Ççüç¿ÿþ½íèô 3HÃ¬Þ1VÎ*fížì —¦ÔÏ îc%õ±šûX½z>†ÿéA4§lsGÿX 㰔gKH —˜´¨°;µ;Ѩ$þ:uè4¢“ 2èt ÓÇo>õ.&¢ zg=;ì6Þì%ʯÒcÂ³ìx/ÁUø|ªû8fw—“´Ÿcn–ÀÿËïç•iž¥L¹"‡Ì.õ™|ê5Õ¨Ç\¯nsL]æ”:ÍYuv«½0§¶¢µ-W¦x­ZŠ·(mÙ£fËA¥,ǔ´œVÂr ¦áÜдv¢¹ÁMß{æRÓaâÿG^ï{걫ÇjSW©¡ŽÚKªÔVZ«liD™Ò¸ZJÓJ[;ÔlíWʺPɲ1%ÊÖ(nÛ¬˜m¢¶ƒj´Sƒý´"öË +Û§áÜÐ:ÛÐ\G8N +6 +CÜ÷C7Ç]'±´c«aV«£DY»]-v§ÒöJ¥ì~%íuJØ£j²§w´)æèUÔ±@ Ž1EÊ×(llV±G!ã~Տ*h<§ãG +W¹^‡kú›Ð[í›KÍBzøßNUyŽÉç9-¯ç²¼îßÃuùÜ7µ ;Ð\MZLÊ3 ÿ¹v@–giÞ%‰§‰r1OÝ5¸m +» Õ»+rW«Ö]§ 'ªO³òWäT]¹HU•+äóÞ©Jï.UøØq}Èíû¶\¾Kry§áïr{oj'“荓Ž@.Èpmƒ4ñ$x#–FÊEˆ¥Þ[¨×ª ×¡€×¥j¯WU¾ Dä«JÊ[Õ¦Êê~UTÈ㟐ۿA®Àçå |EFàpJ偋r®ÈáÿPåþOtkÑ#ÝZý!ú€kRÄç]„‰'Dفü~‹ªvy†*ªøå©©—»&.W0#g°GÎڅ2j—«<4)Gh§ì¡/Ãò…žRYè¼–­öcm¦þÕè݆]‚hƒ44O#ïÂ"ž¨âYe¨PžP™\u9ëÜrÖWɨ¯Uy}£á4tÊž'[d©Ê"kdlUidJ%‘#²DNÀ *Žü\Åád ¤Ô¿½EسAè‚,$!†=ˆð®‚P •ˀ91B†4B¶6LÖºð"üog4ŠÆt@ mM@÷µm̆Ôݍ>º¶œTÂ𚱮âÔib‹8d‰ã6âcL–ͼlìl&ôō˜àãqÆc|-0'–3/—§<~wé4\×|tz¡ÓèF¹Öaɪ{Y´× 6t-#’‰ªHb¨Æá3ı‚8VÇjâXCëˆc’1™dÑOÒ“T¾ž +Ö3ë¶oíc”e}~–Œzõ‡ÊÑÎ.hE7Á5LØÚ\=5Ð-C·h,¯I5$sÔëo%{sIߌËF¯Mı…8¶17v0&;XÔÛØíTºàï¢ð¶½ÒVæÄæåfÖç¦ÔßÏô¤H3׆Aæ!sÜÈà+º…+óš³z ))"ßö[‰/:@ënúdw±t/óô ıƒv?›û~ޗèÜ}ìS¬) +ñk”yRÚ{žòÓ꣯³ŒsŒ"!Úì¥ÍíµRÜt{^sk^ën¸h +ƂzóÉ8K!LŽt?Iñ!ÒÃÄq”8fe‘ep¢ò#Tx÷p˜lþöªC¯©ƒþN.a0ÆU´ÙX‡þRÁÖ|ûîÉëíÏë¼e€ø>oHº–Ô]Ø)aþ0K$æÇ›“¬—S¬•gX'Ï0ٟ¦“Ÿ¢qßÚ%=y„2¬ãçÕ²œ1@ۏ¶k#ãÏVR°+¯{ ¯ù@^ëëy3òxޔͺT'áé¼Y{.o¿?$Ž ôÇ%ýKŒÉE&Üúâ<{ŋÌÍsì™gŸWí Ú´mlé¦}y³õ`¾}ò{ސ͚¢çó:Lmý`VKs†‘%OÊ,ý~¿€·ˆcš½cšú·l:Wè‹ß ú{ś4썓d÷ºÅ§pþƒ·úOó/yÉþCú/s ü/dì"oGñGçÛ,’ßá~®à§~ͤy“IúKÚëL–WéÀW°ã^/ë¡}_%Ô¿é,jgàœ€'à¿èހ üUf½§yw?ó6sZ)ý +—ð:â§Äñ2q¼„¹„Óº€{‘Esx–ÉûqœÁ­~—Éó&̳ÿg¹ÌcÛ¼Ë8þõmÇ~í×v|Åñ;Ž׉8i§¹ê´Mš£é‘¶ëµµ¬´)ëF‡=¦±C¨¨Ý Ó$@ •c“ÇL †´ILHC‰Cô©ˆCêÚÁ„Ð$PøäPõéë÷}ó~Ÿç÷{žßï÷<$ÈËé%<ù¦þÈt~´nû+ký|>Äî¸ ¿Ýœ¾7å¡3 0†(_fôѯ¢=„öÚM´gP^ <ûÐ?ˆþQRã$úgH“GH—‹X†ô¹¡xú< rõ/0Òç°{ >OÃß°y ކ×áûë!·ã»Ý$ð=‡~7óVÃÿ!Rd ÝíŒcºsŒe Ýe:Ê#hŸ$…Ïêª>‰+xñyÒëKÌÊ+Dègtž·á°Š—«ÌØ*s½‘B?ØLm* ô×Òу®_×éu¯ÑÛ]Sµ2º5t·âÿ¨ž¤›ü,Ýßôv“#WȑËøq?>­2ãSü{Rý#Œâaø¼ÞÕCdÚCØþ¬À/6Óük›Ëà*< 3—™‹‹ô˜ÉϋJ³\;Ñ-£[Cw‘6Н@wÍY4Ù:0 G‰ÈÇtš7òå)T 2÷ÅdÔ ýV×9ßÝûµÍ-hm[¸°¹=c¬0g‰ÉÅ!´ËX¨¢=ÀˆGÐG¿‰æ š‹x°Ìl'[Ïp¼<ÊÝSxö<üÙó:Gϟá#~¯®Ã)Ê|¯{Ã6Û¾o 'äàhò¢€VtaEÐ.“‰UôÐF ½&™1KT–ðä0{Šl9O¤.óô:¾H½¿æøÿ€ëê:7°ÅŽ¥µ­ñãëv9Vá ì—]7Šº&DÐnƒ,úÍãÇnõ¢_G½q´§É9þߏGÇ5Å,NÁ 2iœxŒù1öŠ1vœ1v¥q|X‹ÿc3g9òŽ³¥-s]‚yŽãÝlû³äÅ.µ íG;Qô“ègYl”±QÅÆz t'ÉÖ]üÚC”îóYIÈâ§È ø«oÃp þͳU=½óspôôQÞÀÌZyÖ²QªM:,š°¸Ð÷¢ï×6rc”e­4ԁ6Êب¡7ˆî6f¥©~f©HՈj•xô²2{ÈúŠ¾?†ßÀ]ø¯>ƒ­3Ø=ÂѲ³Ð„qŽ¼QžàϰǦ!‡[[­†-&vÂ؉c'…vŠØ©`§;ÃüšÔf°L$»‰G‰S´\V—åY<þ:üށ¿Ãô(¶Naó ÇÊí¦|íayÛjiÏȓ*ʝªÊ•‘3ݔ=½$[愬™‡eÉpf(HӝiúÍÔàŽcc{S”àÃPƒ2(ÿ:xž†$¾Ä!š´(œ´*Øn—?í’/ãUKÖ/w6$gGLŽŽ”읲æ*²äè)r“ „F%Oƒ’§9Ès*ä© r¯…gÇïá}-ck†¶lÍÑë@%·!“ƒ4ï’øçÚ +AÞhߌ‚M-]N9K-²u³Éma©°À*$MG+],ljèjùž@ÓÔÃiÜCeP¡–®P où)àCù®Нê$PƒnèÄNÏS€÷!ž6Jô@e«œ‡¬½4U6ó]?MÅS'hu>ªÓ[Õéwë4quš˜:Õ@z¾ŸJ¥Ÿ†¤Ê±†µ{š-´hAz Äï<Ï2ØLrr®YÆ~û´°ÎšEÖ~ÖÚAœ!–aüh„66˜“×@¬A<ã0ǀfq„&mø&А ýŽឦ ]ú` ta/Çç)®qîà ÇÄ®Q“óa×E{HY´a“¥Na·V䡇6 ¿ÿ3]®ÁQÕg6{ËîžÝì9»›½d7›l²’˜²„[ˆ Pb F +*Ãe(P*ˆS­S +J‘Ò/PÊ¥j-2È Ê´:ÓÚ±jõ 3öú¥H«m-Óéø¡Ûßɞét˜‡äœÍ¾Ïûoÿ÷¡ýµ’el?VáÇ~¬å‚YÇpYKb×r 5ã c̉ջø»c,NÔÑÕÏY{àÄÏ&ΜâÌ&¡38¯Ïæ]ìp~ÙᣴX¢±á,¿kÀ:gÞHL6³˜}?¶Ñ¯Ò'ÒÔÛ ðv ?€±m÷I[ÉÇýÌË-¨š¯¿¥~x;g’rœ!Öq68¯w©sΕΒmó­QQ]·Ú˨#r–s[ ì 7»é—Çðc?}²&{Œ€ï‡€¹‡Ïî—v±ÍïdVí¸¬ÉÄ»H˜²Œ³Ø"òÏ8ñÜíœs­ÃIKiø&xÄA;Á.GÙâd¿#’#¶h¡^Ÿe~œ WN0?H“ç°ÇHæ3î(ýqe3~VípçáNÀÁEïj'®[œóٜ;ÀnGˆØ<¶$”¬êضH9®ªX< žWU¸Ò~ºH<^£W^ef\¢.‹ ÷euîqDæIàNÁ…Û¿Á‰ïÃï^pÐá³¹ŽýϏU‰6×Kà<`ìˆ,®D$ô+ð5ò>õñµñ>ïÉ¿JŸ¾Kbß&¿>Âf-ý | +þþ‰¶º…Îü”ÝùïìïOl¿ÝúÛûïØð¯£.> I®Q¬¿Aa½M¡¾…2zõ÷ øüó2zâ’àÖQÜ{uõºÎ¢k~Šž8Ž‚Ãà p Þ¿‚àÏà÷àºz]uq-óÛù›lð¯£$.ãÇ%ü¸Èî~Åuž¦9Gñže‡m÷~~|?žDë~—bz‚":À©÷é'¤ö—ð~BiUhŸ +^VˆXe‚û]ðš“ÚSNڟ&ãhÝq4æ8Zæj%vØ¢Ç‰Ç~†ö>ö^çôån†×.×NÝC)­¦u¾†Ž}€vÝ×!¸~D‰_Òvý·<¬ÐâmvÙ\p¸Ç²ß;Ñvâd`ÁIЈÝ"v;±;»eZu&v‡°;»#”óbl/£"VÒÎc(¼Íp<¤ 4ïz"µŽŒ­%³kЙcp¯_/;muÐi÷Gœ–Ü:ўµØŠ ¤@»ENØA´{°;»Ó±;ˆÝaªrX„íeŒÒQþ­Ã›­‘¹‹ì¬ “ËÉörݲW¡ª+b› ¶Õñf¼Î8›Sü a¯Ä@䩾"¶;°=Û}ØÀællÃ>B•~ ¥¹‚*YÅo›ðêa®šýTÎ1²v®ú|*8äŒ=¦çÄØ·¯{LÚcz™\ØócÏQlç‰z+¶Û±Ýí>l`o6 ;¨’¥š‡§s±:Ìé>GÅÜNU QuCtôº~»œ1lóEÕëо¦ìkÙ¾² Tc× Á~û­ØoÇ~öû°;@Vñd»ˆjY®dg:Yà¤ÓÈG™®-Óåe:²¬ÿ€ÊÄ5c_ £Œ÷;¹~‚σaWuM™C,‰Ålr2›Ú˜…³T2ØÏc¿ûíØïÆ^Ÿúy;u£õÅ)TE “ÉG7Y»èþ.ýü›wm…kŒUh9WÿÂÚêJ4fò<ÀûiøS&ýÔçTr2•Ú˜JöáG¯àh‚£ŽvìMÆnY·ám'±è ¢ídvQn£ÒKt\‰iUdò™~E&q 6qݏr½-e¤/`53ø½ z¹nzð§ÛW£n·ûAì‡AŽI8²p4ÁQÄ^'ÿ÷âÑtµ¡UR ÍTxý‘'óy&@#5ÑÈThÔG<¦õðßïBVÒa֟Y  ¦ðÜ:ølþ´<*ùjUò„TtGÔꊂ¸ +®”š]9x +ðLÂf·]eå\s”u¨Áu§2®U`‹Ò®tøðyãƒò$î;±B5‰ur%X|Ü –±øE€ÎŠ}¤¥ṗs&ëo/èEÐÌ»,HãK}Ü¥xÌ#+æ“iÕªDbñ ‚‰°jë£òÕÇä­O˓Ì˝lSMªG®;lq’fú¦¹Ò܆i–ßÔ €I|HÞÔbx†SÈGdQh- Ï»|Iñy"Q£XÂ+3îSD~õµ +&ƒò§ y2Õ4Xr5ðÇ 9œg—Ï¢)²ˆ¥K{¡caÍq+æX³ÜÔY–φ«$ú/ú"\C¬Þedj(fžsø‘I>'ݲê=Š&=Š#íU0ã—?;ÇðÈÓ¼MvÅ«_nFã5#\›O&~¨ÀmXàflÞؒšð! |¬|e6’¬÷;A+hâ9‹/)>«O»&ˆd\2²5 +æÜòç½r73D ÓV£:HJW §ÛØãÛÐxmˆÇ¶A€ÖlcŸoC•¸%Kˆ"›K+>´|¢¹pNç+=`hi¤y׀)üˆóÓޅÿË~™F5}faüX5 àZÜëZ«"ˆ +nUƱ®3hÝ:£ÕŠ­Z+neœ¶J;š=ˆ²HYB6BIH€@€°„PÙ !Ѻ/ÓÅNíT;Õ¶ÏK2çÌx:Ûɇù0pÎ=!üïóüÞû¾ï½ø?}fÀé^”÷LÌR³pÐφŽ¹`@Vr¸¡€ñ…@¬GæÝ ôòAÞw"0<¢ŸŸ‡A!ÃÇ\¬ÅœÔª©X<71 1 ï'#×hñGŒÂïÃñw_à¥ã±C0" š 5m ṫŽ`ø Á",BÁ",Bñ P¬Gèb†ÈP ­!ÜBpS/ ¶³æt²Á¨3ðϞ‹˜‰ß§"×$䋍÷Øî”/°Ò0ªá¦¼` %¾„Á¥»:–BÇrèXa`F6;X„Ap؆ٕæVb€\½ñr>i:ù¥_PKðüùˆÙøø ä›-ãñ:ïGÀ¯/òҐ÷9’c+.q|Äh"ð|èX… ~5.û5¨uбßFlª 0²a|x=†ÊuèÖÃç04¾‚.zõE4)÷¨àš‡x ù¦CË$¼úãýHl-¹ y½×±;'åjn€ i´\ W8tl-бk²Û°ØŽ‡nAà ÛpNlEMla¢Yã²6â{ר`ä +€ÔYð;¯ãày8ûÂï0ä´Ï_õw97º= Ec‰g»@Ҁî“=Ð Ñбõ¹¿QøR$Ή ´{P»1¨îj§æÃëÜù`€× ðBà΃í…Vݕ‹ ‰Y”k`Ոö¢°õ(,7U +UØ+Ø'F|`—€… + ^›EMBîÑðÍ@n/âù›+iúQ¾ýÃ'B/ p¼aT‚/DŽ;—¡C!ÈàXŽ¨BÔ"È0‹cˆr¢>ºQ8ô8/l0݊ûÃMÄÐ?þxy~nÈ0áë7|ä¨Ñcüǎ›0qÒä)S§MŸùâ¬ÙsæÍ^¸(dñ’¥Ë^^±2lÕ/W¯Y»nýÆ_ýzÓæW·lÛ¾ãµßîܵ{Ïï"¢ÞˆÞûÖ¾ýo|çÐá#G½ûû?¼÷þ§â>üãé3L6‡Ëğ=w>1)åBêÇé™Y"±D–-ÏÉUæ©5ùڂ¢âCi¹±¢²ÚTSûÉź†Æ¦f‹µµÝfïpvv]êé½|åê§×nܼuçî½ûŸ}þŗ_ýùëoþòí£ïþúý“~üOüÿŸû÷D%–}ày1ý<\'¶_ ¾gÀøKÄù"0X„8d$ D„‰”0QŠŠPÑ‹žp)#`ª@ÆLÐÔ6-€ÓFè8žnðé#€®ƒÐm‚èO„Ñ@zH(=&˜žþðc̾Ødݽã¬ôz¶~æýßxý °Fì‹ìßû—ÀžáEyy äí= † %€áãã ÃGŒ £Ç‡ÿXé'$`( ,„K?W-=C¦ ¸„o"[ ;éõ=QÑoî;p0æȱØïŸúð4“Ï?—˜œš–!Idr¶ Ù-úbXìwøŒAWMô1 —° Ÿ0 +§°zûÌÞ»»Ÿ}Ã_>xðŠä뇿ïo=züø;xÿþɓ§Oðßk¡M¼×ê·ü¾uDT_“_²¥ba~CٖsñªJÝÉ:CÏR¬àÚ ³¹Z ¯G#â÷©³â¯æe&\Wfœ¿©HK¾ãi hÐ0 a@À† 4ü·Ñ wÛ|—Ýk…†fßdKe°¦¡üUhØ_ݯAųès¹ö94H¡AÌïSe ®*…g¯) A–žxËӀ† · án›_To‹O²¥*HSoÜTb.ÙW]¡û Þ âZŠ A ùР†%4(„ñײ3nˆ¡ÃÓ膆ëí>Ën·ûEõ´ø$YLó !Ü`*Ù_mԝ¬/Qs­…Р… 4ä‰y—"þy–àSIfüuaƹžÑÐgc,»ióê¶0’,5šºŠpCuñ~S9Ñ riȇ•”۝+á]–‹xW¤Yü«"¡àZ:êÂÓ¸d¥Mèµ3–^µûDv æ9ùŸ7•V0•éN6CC4¨åœN¥ŒÛ#áöÊÄÜ>1tdBG*êÂÓè²ÒÆ÷@C¯Ã'Òie$5›çhÍÆÍ¥Åo×t§ôРÍåØUrŽS!ã\ʖrz$N¯:Ò #{ÄÓ脆îƒn#¢ÃÊHi¬ Кʷ”õkJ´§ +¡A“˱)sØNy6»K"cwgIÙ=éÐq:E‚+ž†³•6¾ ºœŒ›…žZg +ÔU•o-/Ó4CƒTРÈa;¤rV§(›Õ•©Ð‘„u9'æ_ö4­ôqÆb§“Ùf¡¥Õš‚ *ʶ—ô‡Ì…Ú¸Æ|5Ç¢T²Û³,»8‡åȄŽ¡#Eƾt^Ê鎗ò{<Ž6úX‡“jwУ-VZ†©zQQYÙkF}QL­V× ††œöϋÄIšÀh4ÐX¢ñ$›&’}4Éô¸9ß»µÄöwí?ÿ÷Èc‡Wƒ{YEË«¶¬ñ}£?‰éºãQ – +˱lpËûð’WDLÒ|rÊÍáV\„`Ɖ‰çÈмVÖêmÓ°iØ4l6 ÿ†m†Î{†Pdžºg0|ǐûÖ0þ­aÚÍåV]ց‰ç¡F!ʺ[KnÛ¹–lï¼{ž`¬¿¥²¦?Ã)`èŠo”èh@†½l‚îǧÜ"¢êäsf\Þ¼-R¸tɌ)êíN²¹m-¹³ónü‘ëá=Àð +•5¿çeŒ'#1=0h±tH…ŽùhÉ#EËîA¬âìÇg"²F ¸‹V®hÅ•­èIÅb½mî0;;×6 ‘ŸÃËö¬ùÀð7`ø2>¬ÇÒA :æS¢ã´vI±‡¯QÄ¢UÌ]1‹„W Bé% O±Xo·™æ¶ÛL[çÄn`ø «`ËQ/c×ñˆÍµhÞ«F'ÜJ´â”cs”_´‘+æ!Þ£DtU3(½¤˗êí³µívjÃððáÕáÇYyÛ`xN+1™€-xµè¤[VJ¬fûÌ ¶ªAÆ»¢âÿC)º,•È—êífjkÛ­Tkçíä®Ã«Ñ³òÔKŽ¬õ/cþk$f¼˜ LÀˆÖGùz›(6lœjÜ;^i<”)7²m©}UðÜÿÉ°Ìw>&õtÇ%4”»a†ï‚Sœ&œHs¢ĉe!–e;ˆl¯ƒÌÕ[±Ô°¥0ݸ/Wi<ê™kêQ•ž– %ߤCüç£ý¾®X¿Ž o¾Ñü¶üÆ®O„W÷}Ž/€áê>{âcI_ᜲkôsíÅ,Ëp!Ýmú,Õg9Ï@ÖOØv.‰Rg“u6AØÏ$Ⱥ[µ5¯‡éX÷=õښëWǖͯðsòé´ül€‘w‡rl$&ÅÑ"’Ù—;$øù&,úaqÉÇœðöJ'½=ʲ§[_vwî»MæaÓ°iøß7ìîX÷?ùښû¹c˖—9Å_è´â 0t…ãJddD†'‡%x:,&rA>'ïçðŠ>\0îEE“h`Šî“NÓ½ªŠ³GW±÷è§î·õpkózøáŽõÀ^`xöø’å€ §üà¿+WÁ±¨c"R,ÀÇB¢èãq&<$¯LcÂi7Ò_uAÒ[=këÓVÍ}ºéûí;ú—Ç—¬/ Œêb$®fÇ¢*Œ ˱\P‚åýýø¸W@–i.wÚEfœ˜x΁Hçm°jÞi«HW¹ßÖ#-Íë‘]ëÁ`ø0¼(Ì©þ §Iõ…HLÓÖ`© H±¢w›¤EÄ´‹Ï™qrxsvB¼@áÒEª¬é͌Ñý‡ý:ynò¾ã8~ ^°‡¤I3„¶¦mÂÒfځ„6MmҔKÛ IJÙ q°CŒwIÖ£çy¤Gû¾ï»­åѾoÖbK¶l˖%[^ p(t™4u†U}\Ú?àÉ©ïûk¾¿ßå3·ÿöÕýûŽ¯»µ¯Xb†?<1¨{B1 )ÖÀ通ðÊ )—žu +¨e;©Ž²5+ƒ»j¦K×´4Œ’ª^S5óx{z¶µ~q_=°a8ˆÞ £ie‡/©éÅ´„xX§ýj(ïQ@Ó¨š³‹áʨ€V³ò«f÷ =[rSÉPÔ¤tuE‚hÊx{~¶õñ {¯»¶/¼ÉÍ©0ƒêª/©½Šé‡â!=”ñk¡¼[Í8åPÙ&…­ÚªYÌü âÝV $7¥yMÄRU„LMoþgn`†#˜á#4­n÷%uŸ…b†DÈ@ÉøtPÁ­f*haTI­™åȚ^ʸ¥’°þ,—Šo‰„òe>OUåqÕ xà -"ßÝ÷8¸çøºgÿƒ3h.ù’†ÎPÌԗ™€ŒÏMºôЬ] U,*¸¦WPWÕ2ÚM©”~K(ãÝÈd+\‘²Ê¨+x{ÙòÄڍ^o_=ŒN£iÝoÒØŠYz!ËpÆg†'Ø¦³b£ +ZÒ(¡e™^Êik{£¬°dÊE–DUÁۆáaä…}B»Ž­{_k_¶ý”—ÓœB3†sޔåJ(6úy +¿à%‹¦<$iÑCPM»‡ôÓöAcqdÐ<‰§ºk[cݍœûÔGÞÄ ¿ê«ÈÛ¤Yѧ®´¤Û—’‚ 9J©‰°6ä"Y?“1ᣱ&=·è„3.’tÖET•ì]ÉJ0L ¦)<Õ݆˜áuÌp¤í®á—} ñ'®´ôº/% Æ”hT'Ãbj&À§ûØHÁCgÝ0g¥æœdé¼sX]¶’´sF’aFG2Má©îÞÚP÷`3Œn»c8Þ¿ ?)ËJ®¸Òò._JÑŒ«È±ˆN…¤pÖ/¤æ½\ڔ›IŸAi¬9Ä_°S¤Õ²ªb$kçµdýŒŠlœÂSݳax3¼öÄ`<Ö_Vœ”夗]iÅ5_JÕûovç+¸éÀãøµ 5R!¬äڃBÒ¦nñu\¹#ô.Ò@33lpŒ1–%Y²þKÛÖ´¬½÷´öÖ_Ë[¶lË6˜$„Ù4é¥ Žö_1®}Eo}ÈÃ÷å÷ð»O(®ìˆE”"9_72èáÓò®NƘƒÉž°Ñx%+,™ÑCò’Tå ¶ õ#•„yž{hXûÈ`{ë‰a¿4'ùĝ–7øPeK(®"ÇÂ*$Ã}ÞxØ-B +N½hã°J&.¹ªFä%9¢*J`mA ëG*é‘ÁûâZÌýó‡Ü]ýŽÇi­;­8ëEUÍ¡˜škàt@ ÷{dðˆKŒŒÙ…´) 9kìä~¦a÷Ìəò醪(¢k Bš~¤’þgx¥l؂»kØN(Ê?åd'Üiåi/ªi +Å´„xX ¦ýjx W:epÑÚC›1u3¯éD¼r~Ϝ¸K6-ä('ø,ÍeS—¯$̻챡·l°o~lPì•åäÇÜu՝ÅôøxXOÍøuð`¯.8”ð¤YN›ÕJ×dbö=ñ5P:Ãã)'»º4c]¾’|kˆ—ŒÛEåû²œâˆ+£ý؋êƒ1SKµ³"mnfˆâ¥:üp€~0HõA¡\^‘0ÙK “¼ôÑÌ<¬h%§«ž™\°|l|á†èç‹Þ5ýõ¹Zñõ—س52¾»ÊCõRj³²=wIM̶iñ¢¾5M6´¤(Ƌ(ÕԌæ IÈҔ„-Ÿ&hÖÆ8ÃVIùlÕ÷G‡,M”üÂú%;%÷_<Äùúµ3ÐÍmɟï!‘®ÛJ§è-Å΅±&nc¡…~/lÈEõ#íâ³Ãñ™ajÏé!Prj–Ö ÒdŸ 0+j oþ÷ÐËUËì7¼*ÖoíÂ6îï×¢|»ó$á«?6´Ü:ÒÜx½_ÿÙÒé¹ó”º«ÍÀÉÙK`íL|bš„Ÿ¦Ð>*QéÇJ ýØÌ82Eg™`±*)=Põ×ô3Ë؏6r±µ[hØ/·w`¿}ð¯ßïoùç¾£ç¾=\[÷ÍñÓuªá£»çÞnj:|«¥ùÐͶ‹oZp7ȗ|ImýðKÿáu¿ÿ:£mßlB%aæ5ó0ó†˜as5¦Þ±ë¾ìµwDGI³¼^ž{I—åvxÒ\š/ÕÅ$ٝ¡‰Ãüh ÆcâD”,IFIòd„¨B#mZ4‚7¦"­¶T Õ>mß¾3üÿV?1¼YiÞ¯½-:Bšá×óóÜ}†Kñ¤yˆ/Åe’N(ÁèŠÄ^, +ãюîd„,A#$9Z6¤ÂmÚtoJ‡Zmio«=õ´a–²Áò³˜qS5¦Ý¾ëž|OííîÃíӂS‚aþc†Oò¤0ƒÉ.v8ÎêŒÆhÜxâ'#TQ*LéI‡H²Lˆ¨Ê†Út٠ޜõâ­Yޖ~Ú0˪²aý +Ìôаm×=ÅćÈÓ“Â!A£)# xÒBª1B 3ã°ãQFg2óR!@˜ RÄÙ`», ªú}¿oîw¶YrÖ6[æiì+çaÖuÏc¦7ª1ÝÖ'†ƒ”R÷ áðœ9#lõ¤D²›úãõÕä}Çq¼N¤Ýܱó‚­ëqZÛӝNÅU»zœuu«k«@ÕzW¼¡ÈEAAP ÷äIž\ÈBx $„ÜóäFî$@Bȅ„„pAEV×Ôº9;¢mý-ʶ¿óÇûÿ×ùœï?ß««»Žíõ°¹½ôú€‹*9ÉMý‚8bÇÉ¢v¬:jÂh"(VVãÐ@ªýß ÝøõTòeÁ´ði¢ù4EJtäªÕßLpø„°»avwñk}n§ÏÅ䅜4~¿ÜµÄ1+¾=nÆ*ã(NUã´ý +<Lµ—ý;såö¬YINÁ´èiBx‰6£æ +«_ˆsøZ¨îîfFGÀìíäÕœµÜ°®Z)HÜB':ò!¯TãUr‚¦_JDƒ©ôoÎt$ ŸÌÄH¢\$Ò\ˆ„åV¿¨ÆéQÜÝ"Faø]|VÈÁaG­ ^¼j2“Ä#(Q6¢"*r¢*&!i"­$]0Õæ kæ ª¤Aš]0ݺ4!>‚DZòрè¢Õ/®rz[Iž®Vº×-¤÷9Œ~ë`q‡L4Á5Ôz]E–Ž¶“åCmdULDÑD„](ՀþÀðÂðû¤áOICVátÛ^ÒDÛA$"ÊCâ V[¥Ó+Á{º$°¯SL:šèQ Ÿ1hâ°GõŒ† 5M|CF•^k¥Ê‡Z¨Êx3UA¨ºPªÃi/ è ²¬Âén҄di=‰ۊ¬~i¹Ó+ÃzºdÏ%C6ë@èÃ>k\ËáOÉX¢["†d¬™Þ>ŒÐ•q]i ëB©6gx;iØ°¨·% » +gd9Ä Ù$*ÉMM¾Å//uxU‚Üë”Ãa«Ž›Äôkºfæ¤á×R×2Ùȕ\o`·Ô×*ëXê(© §0,OƤAÿÂðqÖÙÎÂù.â„<§1*;¬ ÊO[úTů¦ÂãÑà{j8lQƒ¨ ¾.3&…Bö×aËí:AÛ8—/áð W=ÀæhûS ÿgÈÜ4ICû΢優/Š}ڐ:·£=k÷JÝ]Æ*¯…ú *8¡l§]Khü¤ƒ-nHÖ6Îj–Ž²å &_cÖiúS 3Ҁiõr`xaؚõDþyÑ]õüMݧ 1M¶&¬ßo +Zr-½Žs.‡éj¯)ùkjT´A©AdÐGOÐÛ¸7`©p–HGáùܤŒÃM$Հé¥!ÖoÚ?fÍ*wÞÓmÇÝ2~\?hü‹2bÛ©z¾2»ln“©Ê¯Kî ×@1‘’’à'¬äTYíYÖ0F‘‹G)2ù¥U‡„êhªÓ²4`^•Œë2nKÖ¬f{Á}ãVÌmû&îpç‡ÒÞ-Zwç›ÉZÜ¥5UûUz(Ô¦…¢MjJŒ§‚ m’3GˆrÞA ”’A¡Œ%êhªóÒ4Ðñ› `Z› ÐÍÙÏЭùlVÝéyŸ1>°º©»g›Áä<âÔX.t+L5½2hA)á-áh ºš§¨ƒD{¯âbÕÂ8V#‹aUêhªŽ%iÀ²2˜ßÏú²4ÿ!ï_]¿+ÿ.¶Šx»Åìùk‡ÚqÂÕn¹Ø-1c|­Fȏ ` +…juÔ~X G(ZF”¨­ÀixX­ Z£Eªuò”–ÅiÀúÖ2`y/7eÿäZ{ü~dUÑðÔb‚kà·"UW¶YâÈs‰­e]-Ø¡ò5˜ ?×H 0 ´ M‡((#DDYa<Ê cÑú0EÂÕúÖPªÛ¯æûŠeÀöîz`]·óQ`Õþ±É%y¾©¥$4–)lóîÖ ùÄVîn´b»”ž:3ÕÇ6Óz&ØO3Òý#£ddõ ìÎÀ ` cs_ªÇ¢ùÀ¹|)p¬^ÿ´g՟oM,ÞÑwÉ9óԛ$Ib“ îiç{ÏèëÜe–:'Æɳ“Ý+µ‹e¡õÐ;`/­ƒá…ÌLÙÌòÍlÞÌíŚë{1f/Õw.œÿ“{ɒçî·Ö}›x}cøî뻬2 +dwÖàÇ6³¹ñÝMµáÓf_©’é«ÒÂ=8=ÔM4‘Û~ |ùy؟“Ž~uâùéƒGð¦? ß÷ÏÓ·mÿýHÓëè¾ozŽíýº÷øÞ¯'ö|%:ùÁWÒS»Ÿ¨Úë 8þ#à^½87Ѐí÷ñ`óSÍÉӏTç”]·=Ær‘{L&‡Êu”ë…~C*ßgNç{­i‚ë%8® Áòdp¦?ƒ3 §£ø¥x¥×׆ Ï\”aheøeh¤ šŸjOœy¤é`~¦î”ÜR²M×OU!ƒKrUœ”h“¡>•˜ÒD¯u”àÚ38ljâ,J0œÆpzÃè—ÑTÍ~¹¸Þ¡{ã&`jm™Óë˜Õµ³îkÎ˦Õt˸Šï«("¤R™(HÕɼX—&ÆQœoAq®ËqœÙ˓Í2¹,Îaôh6EeãŒËX=7eð¼NÞ¦ ;63e0´uÌêO°îëÎɧ4]¶«jn ¬ÅHµ"Q«RĀvÐߌ帶l–ãÌa,/Ž1 £Gð#‚ÇÑŒaõ†žܔÁñ>ehi3~Ø1k<ʞ1tȧ´±iØPQÓ'5²D^©LRMé±lŸ)‡ñl8Æq(˛G¡|šä㠄ˆ0#x˜ËÖeX¼+)Ãz¤ –æÖ9ó¡ŽYs{ÆxJ1©?o¯é¡¢–'u’d^­Hã2šk³˜Àˆ£Ãq2,9ʄ‹qæ0‰0‘|˜Áìh®ž€ç™aheØ>o°옵fϘ+&;júîpQNjôâ$¡•â +%–Ðàh¿>ŸéµiŽ³”fÊqf¨Œ°àbˆ5\ð³ÂÉæêéߊyƒsÛ&`Ý`ÎÖÚ1kû{ÆÚ¦˜4ŸvTá¢/û“„AšÉ©åYLª"2B™î5—“=Î+ v°:̂*;\òq`r¨!œ=Ñ\=ï ËÏÚyƒ­éÀœ£¹cÖÑʚq’OZO:ªæóᢉ/˜ù)Â,Édu²ªPÒbM9É7ÕFz\W¶ÿj¬z{Be7&¹HÞ΋æê ø(ƒÿÿ†­ À¾¯un°é̬³™ußyP>é8â¨Z?­]ñ‚µ'…[E(f”à£jY1)QUããµoh"Àõ^âjN^¨lÖ^$oæGsõ4o -ÞßҀ‹28ö´>uí9óȽyh¿lÊuØ^s´‡KöOâ3…;(jçÓzIyD. “A¾sÚÅ÷\·ó5KT1÷ÁE£É¼žž7¼×w·>uï>ýÈûã3ßé”ç€mÌu *¹Î].¸»“¸›‡¡NQ!iWcZÉDXª»ë Þ²=7ŒBÿ˜^Ut¢pQ+.hD¼ž€Ÿ2–-¾·hÀMœ;[¾õìlÿ§'ýAp—d:Ðd¹ê;,{OÅHÿ…îg¢¨¯¯p‹jˆ]<í5êÿjT:îhåCj©ÿªJ +]QIÂ%¥d¸@­•¨§ç [€»±å[ߎöA;.}ï߆w™®…[|•pRBÎ\ÎG;ÓُA¢š×-œÒÙ¤÷”û¹Þ}S¦ñKUÁªT*Kå0)“!D=eRÿoh`ˆ2xÞoþ.¸íäcxk×Ãè{ýwãÛt#;]µds¨š=cÉ?§bv> k6¯`BîÝ:·E÷M‘É{M¤ÔDZ¨"VÃE± +É×Ó¼áµg†w€oëþ‡¶œø2º¹óoÉMü{Ù Êir³e¬¸Ó‡¢Å¢#ç3P„S + ®ü}ãðfïjª×;8Áwy¯ñm±>3tE`—úuÅzAÊQ†Àðlnw›¾G6{’xç¹õœÏ«kE“7Öë³ù]ÁHúèH ~Šôäí° ¬5±_8Îóɯsü¦ëœ€g¼Ç¨q¡+®¬>~ïöŠ?Õ>].LŒm´ˆ–Ð`º=a¹ˆšcܜ>"Èˑ~R‹J½ai…VUXaS…–/Áþò%(\bxa²ž@è§ @øՅ ô«e ´nH¼Ñø„\Ùtzù±‡K?ÉÜY)†Æ¶X ƒf´#fHv§uq¦ŽõãÒ¨Fą^DJö +‹¬a]‘‰XH:â$»?y.Ôÿd€_Y«–Èë¿ËѶ<¼ñêöñ‡/Æþ±ô"|gõÀàøv³±tÈ£ÅÏÂêL÷eUŠ›”'™¸돉sü¨”àF;ªÉ3£‚µô˜ ¿õõ†ü@^~ ¯\RËÖ|Q{iíõK¶æ¾|¹ ù;­ËywÈp£Q§ª~èÏz¥D74å ý(/Æí‹÷¤… vj ÉHÊR—’ÊtwB;ڕ0Ž^LØG;“žt=Èâ@ô¥A”öÚrɊəūˆÇKÿÃ~5ŸÇ­l;ëÎζëЙŽíÎtwfeíìvu¦V@D@9…°\"¹IH"$! ¹þä" I„r‘‘TÄ£ Ò]Ô­.¨ã®€þúÇ:}^öE_|ß^<ó<ó˜~ú$¯ýñgÕÂåoX7ãXMsÙÂËS¥Rê8JIÁj‚ç'éÐC”îšÁË=Õ r€Õ[ák1^ò Œ}bc™O¹£€å7»€õ£_my~{`aaßGÃOÞ?dÞú8Võê9Гך¿;Ž£-%PÈ·rÄ¥Ü|%¿öjMkõ VŒœ"H+&ImåTyÙx£¢dœ¡,c·òT…£ +1*Sï¤öÐ]ÀñÁ¾S¡ûwB?6oí?¬¿†¶>Oo~~´ú¯˜ŠúÕÔZÜJ^]ÍrùrjùªÆÒ[µôâEóۛbÌ.¸Aå\¸ÞԒwÉͽÆáåÌ xYóbþNºëÞ²8¼ww`î—{-CÃÔàÃpŒlI¤nFœ'¼LÈǬŸ/F>Í-/û,zT‚B¬^ªÍÿ¾“÷›ûO>{¥¾.뙐ù€Vþ~1ã“”v¯…tnYHÞI×½{Bc{C¬·ö„ªßü: >g‚ÏŽPÀ‘¨:}¦$%_z–^´‘UðS~nÞË¢üìeˆÌç…Ϫ‹ÒÖÑÅçÖq%©k„Ò”IeÉ?R˒ž6^L|Ê,OxÒri' î ±ÎîÞ¥^y/ïÿŽ >9Ø}Ǿ®Ñ+ñ‘2â2AnB:@$¥‚’”dPžšô™–ø•ž°…Ɉßğ?³Ǐ۠d~u9;æ3'úç–ܝd}/Ds;d~±—>ÜO`Áá?T‚£.á@ìWYàìÑ4v,dG$‚ü¨xPt2\ŒŽ•11 ЧO|Ü @<(ñ‘ 1>0ŽnâN\x??Ý„GÃÿô€“ š)›ÍeÏUÈÇMu„•ËÔÆ¥ç6‘-Òk8‘b#SÍ¢š™•v¥íš®Ò馐†î©J³~²Ò®Ÿ¬ðèÇ*õä`w°þoø2ð`ôi(€`ƒàô!Ð8)ìÄ:«²êWÿ€Þ@¿K£óØâëD¾|ŽÐªºŠ—j§±ò®)´ª{²¶£g¥3ŒWzÇ«ÌÆqd¿q é1ú«½½>”×,À‡ ­°A„°›¸y©-ß"Ö8åÕYhÒýfóNS£à%›oà¶_%BÚ)‚X7‰oëǶ÷Ž¡;L£µº¾‘ƒye¶ŒT;-þ—Åç¨ ìßD°A  ØÀƒ ¼œÔ ¢p[ŠZåT“ï± Í·˜4èzS>KkÑL7tD‘aŒ 3â•fø„Y¯`ºlÚ^{ Æjªí·{Ðýö~8 &x@Äï ­±‡?= +²R7 +×øE¨UneÃ2Ç^dQDóL†r¦‘Ó9Iå÷Œ‘[M#D©%@P؆ñš~?Vçô£N­ÍéÁØ8 ÆÞoÂö @°A$o á@ ŒÔ (§pMˆ@­ò/6,qkً¢xŽÕ¤šf°u㍼Þ*d %v½ÂéÇk\CØn׺ÏåÅØ\ý›Ó‚µ9X»£gïh… Ò?…)lń(9 +ˆÒR7D™…k­P«PqÿŠ³ÀÅKf9Tõ$«Y?Êàö. íñcˆ(w á5îA¬Þ3€¶x‹ÛŒµº{±6—gsváíŽ`ý× ;òƒèl¤¤lHÓk’lÔª¨ a *ç,ðђY.I3Á¡÷Œ°8–aº ßO¹‰rϾÃ7€íõ91fŸköpouiñ6§¦ÎîÁÙ¶á›0 Žâ„( KJÙlK-Xo;_½*Í%/‰K8 P•ä*¿®c‚K3\iaY‡™<Ç rÚ|^|ǐk2ãLƒ=ø>_Þâí¨³ºU›SI°;‚Ä°¡ 6´mN…é™H OHÞT$¬+ÏU=Td’–Û웒rÉl+Z3! ®ð6?»Å9Ð(ôzI²!7¾3`Áz¼Ñ¯­ëPÌ^e½Õ-'ڜ2¢Ý¬·ù¶á¯a@d§#€òLҖ*1ÿ™:ùHF¼×žÓ¼(/ÍJ‘ê ÞpEH³úy,—Áp‘¥Wúëtãú:ý¨†Ð;¬¬7 ¶Í^)Éâ“m.Ù3È· '¿ò˜ Š=ûZs&ï¹6±âqg +á¾6q[“Í·—µO¶ÕèG$$‹_ÄpyØ¿"žì!hgTÄîñ6’! !›E f_+ÅâRl.ÅîÖ[ƒbÛðuÂÅ©ã@ø¦36÷….®ü}"~¥'¥ñ®>‹]WØ6£­èSãLà +ªÃ 1¦fñŒ’¢™Su<*šqˆOëóñh—fuqi6g°€ôA±m8ñ%h?ñw =™ºOe¿4Ĕ=1Åa¾·$P–­©ì[¶ÜÖk¶匭¶sH_g7)hv!oFÀVÏ·0»&9Œž6ÃègÓûØt³—Ýdu³›lÎ`½5(· _…YT8PG]‘ñÀ•ùs߉â5{4ê‘;®~eðlãòH&{a¬L0âEjmŒ­£‹<,P°¦é2Õ|£ sª‰«¥sz‡élÓ eö1š-Óê +Á?Nû¿Ù­ó·¤<€ãø´ÛèöT3ÍîÎT¶ÏTNóÔÔؔŽfšWZi[¢y噡r‰x Š((¨x¡à‰J¹š ¨¥!x$š)¦™æef5­•5M§Ÿýî>ósüûÃû÷׏oÄP‰ʝ~™Ã¨w8 Jÿ÷W1¯4G£—u'¨‹CžôÙñ0ÆàVЮ#ÕÔ«š%JFWV]ÖãRÙ-fEí`º¸¾%lèa*º2 +”œ¼& 7·Ym((C Uÿ5XšB¥ý~¸dgr[7h±õ~¯± }Ñëùhč87w*A?åËÕ‡‰ä:’Lڞ¤6³4œ^or]ÑÍÄúÚþäªú¾Ô҆¦Xѝ&jìL/RiY‚¦vCAù©…)TÙþu6‡Ae}ì£Ú +½¢³ñ{4â8=ç„Ó?p¥kï¢ùòÁéõ¨ÚbÄPÐÂVg(3»éò]¢¼BGi¸¬K”É{h•ŠnzicgªX©eˆTCýÏPý½ T!Ù¡} ·´†ÖƒN¯¯t[¶>59wèìÀ#;’vމ)¿ã‘/)+F š$ev+«•ÕÌÓ¤(󻒔’.ŠRÖ«PtSj]ÔêÆΤ +eGr©Jc(¨D 5f&P}Àj-~„&s‹wûlŸèÍ&çÌÝn.Y„hžÚÄ)æYÒQtÁ…Ð²üÒE~­£Nkb´r[iWrÔÔa;¥¥¢=¶¹VCjRic.«´ñ—Tڄj•ÆP E ²&Pó³)4üô´í6_¾±ëàÔÌ.«›K{OkVœW<>D‘Î:±Ew¼òóôa’¬>rç:­–ÙÁlHÖd(ÔÙÍqm‚–˜6Ér[uKT[ý|ks+Au¥•tÙpP.í0™ùVhúaÇëîí»f'¶™ ,í´Õ¬ìñR¼:!]:œ œseåŒûäp‡1"ö@L)ãF¢”¦K•%t³þەYݑ×@ìÉ Ú29¾ã¢Û!—‡kZÃÛÔb¨ýÎ.ïúæ£zۖ…‘¯7.nÞ­YÙá¨ø´Ç[úÊ"BôÄ>žߝ‘1íÏcŽEäÑG¢‹¨C â¸z)¹?­"êWŠïãWc{5:± £«Dª•ïUՄö¨/ +j¿DAÝ?Œ¡iÛWÏú7lZØð7íÊ·û«;œ¥°Ï[ôú†ÿÌ%š½ˆNJd&ÍDrâ'IYäñø\âhRî6£0r˜-ÄÜʺ6”WªŠCô¥’`}UI¾¾$Pß,1ÔoDAÖ/V:׍þe­öņ-ŠÕÍû¥`æ,„žÙoíƒY/ݱ)Ï|ÈÔÇ! 1ÃiÄûÄTܽشˆÙDöù™ιét^È73h’Ÿ0!àûß-Îñ/Ïñ—åúŒ]6(Ö£àê†5ú~c#턉‰üӗ¦R05Ânûl°:™¾êâCçLyí!½ Áa—1Q˜_ñäsOÉq!)” %5à#Ñ‘ä÷03Ùg!—îý 0å̃âTÏûå©èû2†¡^6£†:×¢4C_Éç¿XW ›L‹à»³ÀÜ: ìœipÂ=<ÑÄU_ßðAçޝþð[T˜ßëXŒÏ+j„÷Jr¤×K&ý‚óx‘‰?ý<—pj¹xrYåþï +’¡FÚÖ ÚuF5Œ¯1ªx»n]!üýÛL03c‚…y8Z‘áø,œvïcApÖÝBÿéá^€G£äubϜ‚É>'>±ýŽäùûsÖõCa€Ëûâ@Ci4kP z#Tù=”‘Ösaó¦Tؽ•–;‰`»ÎæÁàfáVgÀÇ ¶§ ôˆ;`ÜëxˆN®@vvø£G!ÑÅ R\!í˜pŽÛÿ„¸J®C¡Êï¢Py¿¡Œ8°ñOtغ.̾Š„½ß„€¥©?Øm?.»Nƒûî“à¹÷8øš»BÐþ£pî€Dt¼¥=~±ƒ8+[ Zú!H³±Žðÿ[Cëk#`ïX ––«0¼- -Ø Ò"<€A +|G§F¼¢1£—©<êSJ^ÊR¬0ý!Y’±@*çÝ'VeÏ.åÜÃÕçÎaù³‘Í³× +f»3áý‚éðaÁíÈÛCØÏ÷Ã6bÈ@ ÄÀF LÄÀr†Œp`E½eR°+)©1Ïhœ¤ÇÔÆ"¥0ãAlqæ<¹ŒT•;K¼˜?C¨LãESØáT¤Z8q]41(ÅÞ ân oào‰>dl2.bà"† ÄÀ>c ¼@gàaЫ\Bðï¬XÜK&=îהŒä%?}*àÎÇ_àÏŖæ͐¥‚iÒÅ¢IbhßX<»"¾‹Õ õJF±ƒ’Aü ¸—0(é&~>à ÞöµÀC ×ïëe ÙÎÀC¯fáƒßpcð/Ø´ø§LVÊbJû-?k.A”7_"˜Š©NDˊǣê%c„Æ’1üÕÒ;¸Ž²;¸þ²AÂͲ^bYgT™†ôù€‹2Cbà!†,OKÈ=ë yçЫ¹Øà7ÙÑøçÜDÊvZêC&3OÏãÏ&L%H„qâ1²¬ä©®|4JYq›ÐZy›Ð-Õû¤½¤>i'’:ºOÚJþ|ÀCÞ> 1d#†LЃ¶Ÿ3‚Ñ«ùáÁor‰„çٔ„ÇÜTæ›Ã›cääM'M$ŠÅc”òÒÑؚŠr]Õ0IU=u­fˆØ#ëî©é ÷È®ÅôÈZTÿ!¼Î¢š<Ð0ŽãŒZO¶sj­Óžq©kuÜQj-Š‚¸€"eA‚‚€` @XB$d%!@VI ûö%$lj@A¨˜A‹ VªÖGíè;ߙéuzñ¿ÿݼç‹Ù¦$ˆDbR«žf©äÖw9Wi­ÁQ^c²UT›-U3…f5URmÆJ*¢÷0P 5p¶Ì‡ÆK@¾ý Þ± »üCö?ï +ê ;61|âøµþ„Œ®î3$½-ƒ!ÓášxÊUF1‰xöÜ&µó‚Àà(â‘b¦ÙJfX,¥t«©´Úf(«FôނÚOg5p}çƒÈo1(¶­­ßf°îØùºÓÏãþý÷|Sv/¹%½³V}Æ)Ö$;͚ÓF».Meם“ÛuçEmvC‡'èh÷°QCÝ¢Yаésh]÷×,šî^½trxÝ77nû®í›úÎß9µ7Lwÿ@¢ìî‘,ÞDdu,BºžÆÌ ²Ü%â³kä§{êÉ=ê–Äîe’Õ¥:­u©S•.uºÜ¥Êt*½ôß ÉÚ¿BÛ·ó³/ûÛÔÀ’7&V,tOmÜäxº}Ÿöñîéà o*ä<í^DAñxbyލôì0“>P,8ÓOkĸ¹¢D·Tœà6ˆã.÷HO:{å‰æ9FÛ#OV{x¨AˆšW~Æ%Ÿ=½´à3Ï­/?uÿ²l©ýåúmšWۂ%/¾æ=J¦=:’U|?šHœÀ”deP2<øê”ëELÌ…“pY?ØÀhœ´ñ¸1û…±} ñÖ¾Foà/>дp¨Ïyãœ7gÔ3w¦{jþ<äÕÒUíïÖm—¼ÛvûÎ?š6œTòäXq*6;‰ÉϸAJ¹•S†+¤$Œ–Óâ<ôê˜uôè #j¤½6rÄÁˆ`D 3£ÜÃ,op®HÎÓçéûøOî±¹³m¯¾\ †ekÄ°~'üÐ ¢äÍá“Ä‘g²ŸÄg¤=Ä`O?H'œšÄOÞ½P{‡\3A+‰ú‰EŽ¸%,ûa\^~l\ƒf/¿ZvllÌk úØÚæÍéœãsipŽíÞÜ9*XðU,_ƍ۩°#°‚Ž߇EcßDǧMÇ'%¿HNIxšž÷+ö\Ì£¼¬¨‡$lÄ/¸ptl…ýÌ%ý¹17ô~K^È} 1dÒN<d8⇃ȀXˆ ‰<&(G¾‡dl±Â1À?’È ʨÀ÷¹1òù¿3?ðÎë÷Ö÷ÝÛ3vë¼à€jjqBÙn8 J¦–:j`ÙG'`Ý21|»š ;7Ð`ß&øo‹ƒPÏhß1ÞG a}C )ȁeðž¿dD#O«/¨‚ö6ØŠƒ½Áâ ÖP{]¸äˆªéF¡ Ã(”þ䠀åKù°öc¸.#»Kq¤ÀgK±°æ£hpuþÜ?ŀ׊@Ø¿òtACèê}¶Æ"×îc_zAÂW;°Þ(v@ò×ہõ;ð\·B†ÛPnÜ ¹ß :»w…#°×-ÖöyÀ˜a®~ÌÒ ¾À¦C'’Øz6þ UC™§Ñ_‘ŒŒ¹Ä +æ B û9þtú ®‘;“ÐÄ{–p™?ß*˜ŽëNÅÞNÄߎ&Œ nã +nÙéÿÇðåàlw–Ÿ pŽ¸?Æ8_àQC€Í< +LqÜ;FVâkú)ê+ª>eŽRƜ%Y8ωÕÜg„zþ4¾Q0…kMa?M¸–ñ4¾7ãqüŒ1콌!Ü}ñ ÂXÆu;1pC:b`û­Þ!7Ey‚‹!%x©‘Ø„·Liž¡¦¿¤¤ÍRKØ33ošT-˜"֋ž2žà›$“¸+ÒIl›l2¡_þ;$»‹¿'»I•õ$ŽÊ»‰‹ü厐Ž¸ˆƒ„7Fz‚, „Œ¨\ö GNþ-M•ò"Eǚ¡¸ÓT“`ŠR%~Bª“L&6È.dNà¯(&pÊGØå~H98¢ø…8¬l' +Ûì‚åÀ]ë¼mÎÀE ’P7ȌðE2‰&G½rp¿ó¤I/Ù9©³iγ”"ÁSz¹x2É*}L®Ë|DjPŽ'^81NhÎ~ˆïʾ¿•}‹8”ÝKÊé ßÉi¡ÜÉi¶1ÿ»U vƒ¬pÈ9Ž†lÔè ÿZ$¢ÎñN0gØy¼©4½x2¥L6A«TŒ'Õf=$7ä< þ¨KlÉ#ôåÞ&æö’sÛ)ƒê' ª/S՗ì¢Ï@°Æ „ˆAì» +N¹‚*ÌÔ1hÈÅb ‡½ dàç¥|Ú Q&ëO%xÂΗL¤–(Ɠ+²ÐjU÷) êQÒÅS÷ˆ×4w‰75}”M{Ҁ¶™6 ½DÐ6%hÏ'h ĈAˆDˆAºœ pÍá ‹òm|(œ"F-œ¤ãç•lú¬Tže '¹Zù8«8kŒaVÒm§F’µÃäËùwIÝýI7 +Úiýú«ô~ýÅä~ý¹”~}ãFÁY;AÆ2ýÍ ÄîΠðq¼ƒß@Á¡íP±ôÇB ù^“„›W¥Ñf•ΔT!žªÒ sF™¦¼‘›î.õýJsѯ”¾âz¯áJr¯á£×ИÚk8“ÖW\Çì+ªe^_4 1b †,oÐøŠB·!Ì ‘APwô}A"öµ†NUqØSJ©xBrR9ÆÏÏaµCŒšÂÛ´s%ƒIme]ôž²+ŒnãùÔnãYf·±žÕSVÃî)µ²)©äô ¤ˆ!cµHÃɽ_€Þo”ºCÆŒáP%Øøß ÉI/´ ֔J z¤P*ï‹5êaniÁíԚ’›ô¦ò>Z§ù*£Ó|ŽÙa9Ãê°Ø8fkz—ÉÂí.7q{Êʹ=¥‹²O@‚dˆA½û (F¯£ÿ0ïËa°DY0ÅÿÍH ÍÓR'uÁ˜Jª¸£P©¯‹ + ;Ó-ÆÖ´³WS›­çXmÖzN›µŠÛfµðÚ+Êù–2~§©DÐ]ntëƒ1ȃÆk%”ú~f¿o¡2À ª0~PŽy]ý܊Å?¶é÷K™é· +ÄòՉ¼ÖLMÑeQ©©‰k«jä\´Õr¶Uð[kÊתK…mVƒ¨½²HÔaыºLzqWùb1ÈCæÖO@·ës0ú¬ƒ +ô&¨ö÷„Úß·uaÁsõQáOëããԑÉÿ©Leõ”ðå-ZyÞÅUqƒ¼ÐR+®¬± +ÿYg¶Ô•ˆ[j‹2Zkô’kUù’6«NÒQ¡•tšµ’.ÓbA&b#åVgÐïüL{×BÕþPë·ÎzÏ7òöÃÑCÎÅF7’ð}µÉÌV3Gv±HœwV“e¨ÎÑU”+ÊmŲœ.5ŸÖÉ[ê4òŸm§ä­Õyò6kž¼½R-ï4Ûë†UNµÅŠ#rH½¹äŽñü€¶ñ|jÓx>­A2࣠9Û1PÞRíÊë¦îoÆ<œÝ‚x­.ßñNWóÖ@øÆƲè5΅ÿʃ˜ü‘vz!0$lŜŠ œKHð›ÉH"N¥â_Ô¤y=ïH÷zñgþá—04™Aìy’éÛñŸ,¿›’ÁEyŠÐÝÙ¬,õ´G} ‹ô¿Þ"}ó³ºbãg}ÊOX£Âe«¬eœKò²'!v™D _¦0YïÙÇ©o£"ȋñÑąôÓø¿sã¼^–Ÿõ˜kJ86׍zšà99“àõ`æ¼÷Ðt2~@2ȓC ByvK¹ß¿靐EÚ?)ÈÔ¯ìÞ&XÕ׺¼Š5Î\µµL^sv:³æå±F"±¾ÐþeùŠd?œ Æ¿K õ\⇻¿)Št{]uÂe±5Úyñn4nq2Úuîe´ûäüI÷Ç 1’@á&dº ƒŒt®Gº‡e¶ÉRµðÓÆRÐ؞Z`n˜væ±àbžÎ, ºS!OþÁ"ú¬†“½¿Ÿ +ðøšHuû rùœKÇ}*e:.×°Ž~¼Ávøx—cÿñOÎÑ¥Žãë$Z"ÈØoäöi¤eLMoºʲ—@[™ F{áˆ^ ؙ„ΜîÖð±÷Š˜.žzìD{¸@œ—ú…,‚ýËDÛµr’ÍZ¯õê ?«Õ²ÕÊ8Ùrå™DÍÒ݁A® bÊǤðËfL6¨lLÅ0V;fšÁ`¥Kƒ£†dp3%ë d 7 ýê l+G·q@Ÿ#[8ko ©G-ïx +œ, =‚j]Ìຠî¸b¡O¢žrí‚TŒ!HÞ4‚d€¼T2¨­-¹pÐSb‚±j˜©û€¦'àtÜÀC>Àÿ ZÇØÂMŽÀISsˆ?„…”Ç k +—ÍL ÔÜDFÐrÄÚ$jí@ç#Hî$‚¤½C´!×±AU&46Aw«'˜(¹‚ÅvG°UµÜNkpßõ+àÕÍÁo5SÓB´Œ!JÛb÷„D}àîӃœýºP¤»*ôöC•D•}èüqI™E3€ a°QŠòÚá*ëq°GÆt7Zƒñ¦#`&gV[ÃVpV0wEÀÿ¤¾Jz@Ù¦ å}²}/DîІØš¨¢.£Ý£¶r%‚`U 0µ¤j(6 +ÀpUa/S Í1f´-ÐÏá€ÆuÊ%oð/&¹Ü|Eþ@j ü ¶R×|Úi«„ÛA«„ú +~ŒñÍû9ã_ïyÆü"ã á-cžøŽ>CzϐBT0ÀBh2@EØÎjp¿BŒ „eœ(;`žuzºP/€Rè þeþ@®¢¬ùÖSWI-A+ÄvúwŸÛÌï>¬o„¬/øìeü<{Ég‘½@|˚õ]b=ó{ǖŽ£ lMi2Ø4kÁí„p/ˆð7‚0¦„DØ'Θ©^Ä'µ€ ”Rʚ¿¶B®§÷ka~ómg}#Ýæ|%ñù#ø3a&ä½Ïüÿè®Ï°&ï5Žãñˆ==-œ:+ZÇQÔ£uTD+Ôʅ¨uáBf!„ì„ ²HŒ,’'$!ÈÒ ("e¨«(U(‚L©x@eˆ¢(λO}Ÿß÷ŸÏsý7ùiÈ ©/l˜Ô>B¶G/`‡¡ŸXŒ/Ш[ÌÛ DÙˆÕ„.3ò#6'ú=¦0æ]Ä ÂÛð3ĉ°jқÐ:òëk”ñÃ÷¨cÁiÃ!iÿ{J펢¶FӚ0#Nê¬I@Zè +øï݀èçñžÀÝ뼐µÀö…xr Ð9{€"=qéáŸðHÔ{\vÌ[laSBzYF¯¢½ +»Hz1ÒÊ|ÒÇ`öD>eØ1ƒÌ¦¨¡øëXç 5Q5P7y7À„»½@¼„?Hˆ „øø½@O< ””ÈqzÜ»Ø,Â\>é5ÖF}…)£¿Œ¬bŽ…_d½»Á íä< Äy€`Û£žpnaŸp¯E?áÖãœtôݦ,p…8ÔÀÜèÿ9 Ù¹’¬i„$⷏,~È'º<ê=E‹Ÿˆ3“Æcóh/qǘcØÓ¬ç˜*Îh䥄g·xƒ=ü?1xöè~þM\¿ !¦_ð;¾_ð[¬ó€¨¨´Ò 8> ùyÈ·/å¾5  õYt ˆÉAÀc‡|bI°oéé„×#åe\ó¾˜=Š;•0‚­ cê…Ñ͢G˜ÞÄV\_â͘>ñ•Ø‡’:ÂCɹ¸>q%Ñy?Ãhó]ŒøÞî óûÒƒzÏjPo‚4L È A f„~ä ¢'ØJâ8=ƒþ‚leÆò†ñ§„CÑ5â§Q ÒÇQíIí¸^éM|or=áìñ¬Šô@v–Ü›|šÜ›ä,`¡:j ®pƒÄÜ!uÓlÐ,ý®ïAp#èÂ@³䐏bvô/‰øŠ¥f<§™¹#¤|á`l©ä î\ò¶QރëR܎íV^ŽëN9OêJ© t¥”Q»•'i= +­Gî,`Ow&ºã˜ËÝ iÍ× Þ8 ÿ…`Ú¹Ìû} 3Ô Ñ»ÞkˆÁãJ&ö¹DDâ§0³ ¼Gôñ’MÖI¨T:ð ©wc;Óê‰éçÈíªrj»ª”Þ‘nct¦3:S ˜])ÎúlˆG ìen GïÞ Ÿ™`Þ2²w,‡ì o°o~g‰üå•1öàˆ–ŠAg[ÜÃ$³K åÛÙi½PyƒR¦úƒT«©'5kk¨ÝºCWÂlÓÇ·iòYíêÅäjl|©¬(9U˜¯Ñ±r³´œ“frÎ% 5»ÙÄ0Ý3²„£oÕ'è:ž¦Mã,þÇs&ö[W8ŠnºR¯)UK¦]^6õaÓ·Ö– Ó›—Ö6ýX~%dgñEl¨õ|AWIg)ÊE§¤ +Ö •šb³è ÇKŒ1¶‹F|q B̳(ÖV=ÝìÐ1ŒmÚxC»ÚYˆÄè†0 ¡;â̂Écµó&÷ßüε³k±ëíŽõß\¶,®º³Ççčàí¹ ˜`ärlLj•žxžÃcW‹¥”Ê´|…Yuö¸6¢¢NQîÐaK:|a›6.÷¾†”Ý®¦X:ҝbMŸfôí*™7éCõÌIC×<\:»ÜÿÑôç’ÉW{}ÜÏwù/<íص®àÞÁSSø~ՍŒô™øÝuÕä•ÇqüƒuDPÊQTŒ(»¤böåIžl$$,DÀ*0Š:ŒZ;NµZµŽ:n•±ÇµZP*®ã¸á2í)¸UdKˆŠüæ9}m^|^ßïýŸûâþK.å7V¬Èú©z•¡aëZúÂÁõª†újêBK5}ª¹F_Û\c<Ô\“¹¯¥ÚòmËzG°Ši¨af±Ó›àØÒÜ0†Ü»=†Ü|îÅj|4ú쳨ñǞ$MýW?l{‹œ»ñ ê¡I]voqfÁÝ"köíò¢Œ[Õ¥ô­m+•·UÈnŸ¯”ÞzZ©h|¼š:Û^EŸh[£­m[£?ÔQÈè¡ITÁ”"Åbžŋx¨¦ Fœ„­R.öÉp\‡ËTÜÈ*þm?•Ôÿ;•Ò1¤t¤e!Wr¦Î‰¹îD¾ýyùjx,k#ü]×!Ô³Q>ňXŒ…Á&ðgk ™§€*ŠY>cùȎc–„d”%rQ•‡)ó±#5Ò¢q’…+éQhåG¢Ÿ3bwèF-!?œ&äH#!»î²¹EjàÍZÿQ¥q_‚°qYˆ™¤×_…ÔiR‚ÏHš #‡‹Ü°8΋Ŋˆh¬ŒÀÑóðMÌ\Œ ÃÉsp1nÄqÐïÈ9fGβó!›~%dÍ 3Y /ÖRLtÎF€kÓ¡Æ\ObÆ ÀõICªo2„“ ÷Ÿ: Æ©‘ÌÂ:K§‡ayUÁ¡Ø4c&¶Ïœý³Bp,4?ÎÆ Ž#GÏ2ç_%dãBþü”R¸+>aáí¤†³.|þ sÜ퇏¤xF€ï=’qs@Ÿ ݄Y0ÿ)։AX戊ISQí€-~Ÿb÷äOqpŠ?Žû;²û"sÿ;„T¶R4HH6Ñ•%ƒ‹Ït¤0 ‹`—Hp\ç"b4óGÏ—‚vøn»M…Ò-Ú1þÈ3Vw_,ûÄ•Qí1_Ž€žŽ@?Å ê`gÈÂ]!ŽgCêØzzt–Ph +á.…r=3þ¿'CúM*${yæCô½ÂÓBêEXtY þm ø­R¤w2¤ïù6©MðVÚ/z/钼—vH†?ꏚi3 ²lhS¼`ù¨DFf(ôЬ\õ_¡Üœùv¤ÿäCrHñ1D§%Ö3Oõ² ‚;r,j—ƒß¥ø°h@aدEvy·äü7é;ÅSÙÇÁ0Ù ¦A1ÏÊùlzÁ,ðƒ™ +„É8ÆüHè—ÇA³6 ªM©PnK‡|²ƒbHÿ-ä” âz9DWÞUB𘂠›z' ~Ù¨©]ùBf§ÚåoU‡ ¦Aä %Ó@Ç°‘™äl¾rÈ2p`^cI<ô«B³ÕW(w‹¡8 …¬Vé)%$uÄWT5©!zJ _Ñ6ñÝ+¤_(lt»rHó e×ý&ó¦fÐ|U7h¾ì2}`t†–ã‚ì06 +c½P’ì‹2A J•¢±$7‹?OCÖj!Lä0lSA»Gú°~DuÜøAYgV\7¿•?²¼Q¼´tR½–6º?«Iû:û?úœK†œ 9õÀÌ4d0 ³\`å°Qå‰rî$T¦OC…l6Vh£ñ¹%o eÏÙÄLp»ñqŸ¥__›Ó«ýÁÚ£¹’×I7ç?ÑþŸíúŒkòÚã~‚"Ô-­ÖÚj¹W‹u”ºDd‰ !’Iž 2 hˆìÈ‚•QP­(TëhI Š Ç­{{îóâ¾Ì‹ïçyy~ÏÿyÎùÿÏ$éAø¥'b*¡3êµ7EmŠžJ¨ÇO%\ÂOŚx4Cšðí ¢ b'iݑ/éí¸Œfü F}ÌKF-á%½:v2±2v’fŒAçi:OÇ¡s=½_Hœì`úž0ãÈZ¨:±*¶J?³÷,Úm:™ìý‚Ë 20%áà Êè§qùqC„²„hmâݨ6foT?«'jœÝ†Ÿà4Æ9uÄ NUÜ»<ÞÄ*‰ÁА^š _b`4šâ0ò6YAù÷¶PõÓ2˜í²æß4—ã·í]fˆó”2Òe\w|DÌ xŒÃ˜Š˜~j&¹‡T˜x‹XÍú…p%©=æ6òsŒŽ×@4ðjâ ¼r’ѐǓ +)㜠[`b™cí1ï` ië,¡p£<»Õf;/êÃ_ý·à˜Ã +|§ÔA;ÇsÃ÷ëT!5஘‹íáI 7XçÚó˜- eI$-¿>¾CX?˜\Ij(c‚ªžŸO3 ¹4#7›6ÎÉNœ0 ÿŸ±ÆŠÑZdü{Ìß½\ù±ÄmÍl©×·¦ÿm#Å¡ÎC¹Ñîýä€.9 Û!ƶðÔ˜LV£©¢]–Q[Åj¿¤6,ÎKeÓDŽ™ =ÿ<Àd0ŒÜ Æx’9hËÇ@ZöjK˜²Þf¡{£p—Ý?¥û–½«pùj²ú˜ƒ¾Æw˓òS?Þ+ˆ<ڕçß¡¤c›S‘X­8…Z-P²K¹j~!»B”Ïl’æ0{R2Y:©Š=,V²G“ÏrÆé=/mDP\s`z¿Š[k “ÐsBŽfÉýÎjv,œ«t^<{ñÀŠ ­Ûj]½×7ªwÿZ‚uë¼@ð¿šE מãÄVÊET$£æ²x¥b%RŸ’ν)S ¦È$¥"£B¢ç˸DÆ5ŕñhÚ·xèþHGû¸z³,߾ோ;í^5ìY¢ovYñ¸ÉcSÿ%ÿ]7+δjð~õjrXU“P¬Pó©l•,S.)’ÈDu2qrgªHô\&餢äa±H8š,Œ DOÄ7"æ@š‚Ö@¸Ò*Ñ,…ßXþSµÕúÖi©y—­®}ï’-îz.ûíh¯ um¬ÀùÖǟѨé1yÙH‚J%e+Îfð%Š b~jŒ›Ú–Ê‘ÿ!K’餈tXŒHF“yâ1_dàñ“ ˆ9´iè9%FŸçWa`ÉF‹¹ÚÍ󦛭ôíN֏oü¸¸¿ÝÍáÆUß®6œ>\w1Ò§¬"6T­¡âUŠ"OÄeå!ª<3£2%QÙ*£f<”%žÕIi#b–|TȖ 8)GjD́dtm†½”-ÇÀôÿ,_‡ù«ÞÁÂtmƒ…®k³Åƒ®]_t_w]×ÖæíÔÐ|ê`eöDAmLpf—VÆ"‰Š…tn‚KÏÏRòÊ%q¹Í)±y¿I㲇%dՈˆznLHK×óé +B—¹æ@ +º6¥X†êåÖ¬ÂÌ6Ûcô7W‚Gýë0}wvØ]ï:¼¦ùº×֋íû5-až9ÑAéZR„¸–NäVñ¨ô +›TšÉ#””$ãJšÄ‘%ý"\ÑhrLþ˜˜­çǟ7ðÈJ#—rn<ɘ€®Ï[ŠÊ%/sÚ¥àY‡-xÔg ~»ÿ5æö=§…?÷X¥íñt,»éÿS~g¨»òZ”Ÿ´…x¹BÃÓ/sI$­4IŎ¨Õ gj/óCêúø¡5z¶ÔÀ‹*4 ÑùF.!gœCȚ0 ÒÐ÷-ÂÀ¬Eàm…-xÚl®Û€»÷l@÷З }pëüƁ}öU÷Ü7ôžÜ­ê>í"»áÍ¿{ŠÑIŒÚ81øk¶5ƒÒRÌji`¶ö²šMìàKìÐÊ vX©‰QdbF¼0 ÒÑ ©và³Ú<­µ÷[æƒ_oÍ7l@ûóå é™£UÍçeE¿»mÈzè½]~?h¿àn¸³/æ$ù%8¦‡Åv‹£Cº2ˆ]Å$¿®²ow/Åçö4åäµWԀÆW´ K“´ÓÕ¯h!æAÎbô;,Ã¥` Á +t·YŽkÐ2´4ŒÙcªÇ­‹G—f»®Mûó„cò³Àݬ?ÂQáÅ ‘}#ف!ƒâÀ‡á'Gz6⼆úpǧq^½o Þ7Þ}¯½Žó»ò:Îÿò¬Y0y!˜Î`°º¯X‚¶NKÐØg jŸ,e¦ULÿ²9or^!Ÿp]/?îÈ4úí$BöâõQ.X=É㴞å0&òõÕ+¼ô…Ažm°‡±;ØÝð2Ø]÷>ÄãÁ‡0ÏÞØã·ÞGzýbLà©€;Z hkµ ·,AÕ}kPd´¹³k-•³[me³{Vòg]Ö1f=·ÄϜtÂÍØ{j†xÈ&ÑÕ{–ïî9›æéþ:ÏëÈëjïÃoÚ|½}î{ðõ׉ϾGtŸýÜ~ÿ;àèÀ߁æŒåp·€ŽF:0 ¼×¨YócÒ>:̓|üޖûÉy9íÓ¡¯‰ŸÜ7FÎy:¸-p.ìßÿÑ]gQMžyÀ? qµ +.,* ‹l!!!{ I „7Šk¬KGw©KUªŒ#-êX+:–uŽíA=zÎL[·ê8¸ ‚ +B|潚«ô|çwñ]=Ïû¿““ÿhi²l´*5{¬.]0ÖÀáºwp3ÜG²ØN RqU˜‚ç"֘[”>aæs¢bOn¡¨ï¾"ùç)ªùŠÚ{ƒ¢>»G£6bÚ¸Õ¢-GÔx}íHŸYÁœ|HC4ЄÊaX(AQ”åÑ<ÔÆf`u|¶$$c_R"Ž³âñmJn¦Æ¢/-H‹'Ç<ë> ÚñóaœÛÄ@TNš•“ý±qÊ ìòýGý¦ãë©Óq‰¸2͓ý$¿›äß¡(çŠ2»)*%`Ò8¦z¥ d±¥E!Ê; qÞó‘L›.}6DŒÈ3¡e|“Ï4Ø|üàòñEs262'aqˆhöê/È¢h²èÈf3 å2¡Ìñ…*Ϫ¢ (\¡ÖGAòi,Ä; <As +ø§R‘u– ÞÅtð:3À½ÆAæÝLd>Íç 1Êy™ïà +‘ùJ ®'ÿï J¦CšÊ€‚ÄFâ ­ÖKTaPÔ-‚´!’ÆDˆ›XK…à/lðÏd€ßÎAV'ɺÆï.ÜgÄ Ivg‘|ž›Þ[xýbd=“xM°ä‘4d'Ñ¡`1 IgB'öƒ^9Úòp¨—GCñI<¤Û’!ٟ +ñÑtˆNf@x&‚v.Yàwg!ë>Y½ð†·äƒß/ày„ÿ‘Bä ´¤ƒ‚t&xCÈ€. £À&EŒ†èí ‘[õÚD(¶¦@¶‡œ/8ÈnáBܖÑ>„B»E<ÿ’¤¾Càˆ!îρø™ ُäÜQx†Ü /(#hPÆy#o1&žŠ¤°èBPPCUòꓠù4 ʝÈò =ÎGÎ×BH¾#»3â눒Óö‘“ KG³ÝÒ×Rä9ßË é&'}HNõJ1&QÈÆO”nÕ=µ[}KûAݝ ÍÕ<Ï #4¤ƒ>Ò–(:ìqLT°}áùÃ¥ +A¹1ö’Å(ªIy †-|èv‹‘{8šTgP^R¹WÕï¿hÞʟkï4OÔïµw´£yÿÌÓý¨wë:ó?è.Ù)´á4˜Â½a#*¢}P›2Ëø3±LŒ}*‹ÃQ™Š’ºÌÖáhA£dÄÐ$§?¦ÒµjÞäžÏ}­íÌëÓÜÔõjžèz´oõ¿æºõïW £¦Ë¦QӅ‚Qã9³g0"7ŒËÊx£&ŠºäÉXśUÒ@|œŽe渱jGÊ°s)w°tèuñVé+Ëne¯ù°ö©±E×c8“ÿ8ÿ²á‘¾Ûx_ÿØø³~° Ëð®ðï¦aK»yØr®pØÒf.lµŽ˜=‘tГ|Ù{]Ċ:Ö&NÄ'œéؐ=ëÕ¡#«1ƒ+m¬WµU™Ï]õ¢žò²GöFÍýâ&ÝK³ñ_æ¯ +n´[nš®Z¯›ýd(î0ÙÎ[mmEC¶SÅCÅ-¶·Å_–¼³zÓl/çyÁA¾‹²o®"÷ñ‡øñؔî‡-ÂY#›óô‹z×Y’þ[ïäü¶|¹è×%ëå·+¶æÞpì2\+9TøcqKÑ?¬gK:-ßÛ;,·J/Y_8þZ4àhµ 8NØJ•¾±),9ä²y‚ÒÁL~#œd+È·±.”†Í±LlK2Úȟ9Ð( êý£váãÍ‹ïmp°o¯ª]_±JùSMƒîŠk{A‡s_Ñ%ÇQû{kÙ7%í㶮Š¶’žŠ“ö¾ŠfGŸópYùò×eMÎÇ>ç»'( »¦•d»È¾WOz4Ì£a[4;Y‡öp§½Ø›=ëñnÕü»†˜[›mì® .ѕÕ+”+×ëۗn)ü¦z§ítåAG«³¥âdÙ9׉²+ÕÍe¿Uá|YõyÅ+׾ʾŠÝ®~ç.×ë²®‡'0“ÓFfQCö½5¤Ï&2“‘Þï÷%Žï?1åÉAáŒd·÷袻¶[Ó~ØìýmC­êüšÕù§?Þh9µ|{ɉÚýåǪ›]‡]mK¸:jš\¿Ôî­ê]²³úEõŸ–¼tm_ÒW±íl—y8ÕyƟ³8–¥H%C¥E¡S‰²f_˖¥‡ã88‹­9v!Œ5d¡l!‘Ò´ÕôÖeFišìK4ÓLóÌï÷ýóüñùû¾¯ûþ^ßë¹ÃXYá‹A¢@ƒÐæ»3A…„™êÄîü‚²Z¾—6]M—ú©ÖDî»j+µ§¥.;øìÍfšw¥‡9´&G»7Æ%úÖƞgTF².ò«8¸MÜ<îm^÷?›7ÅÍäO‡gðg9éü9v:>$·, +ô%tƒ”IIl¾bó樒þ¾¨I^¬Ö¥NÔï{å ô‹:‹+vô—xÑo˜·f‡:4¤ ÜkR„¾e iŒ"anH^lYXVt/#ê¦à\Ԉ 5ú=/%z*"9z&,9j649j>$)j%Š=°Ö“0æ¿{‹È"_…ô©Bƒ4{Y›üS“.u´EÍp£™ê@­Ãöî +Ãk%§ÍóYö5_qO–fÄúžKf|•”’‘Pžw™— ¼.ˆF +ã&ùBáWøåLxÜÙYN\ì;.v% +ô#<°ÿ¿{Ï+­‡•UÒäÕͤ·íÛHß´ï“zÔrL¥¯ÁNûú¥“M~ÇjK‚ìÊ +ÂOæDûdg%2Ò22YIçŠÂ„)—xÑÉí‚È䇑‚” ~dÒ7*a:<:~–7ǎ.°DþDaDñr€Ùò€¥ò°xY~nS‚Ñ›j¤á®½í&Ê·šmµZÜö_¾äs´¢2ÐæÂÅP×ì"wZ~ܙ„œôàØìŽ ³Š‘Ñ*àd 8çᇧOq#RgÂy)³~Ò[¸Àž&ý„ÕÞø `À㞣A  OžË_Bý¨'=¸Áöà®q/n&¸Êyàd,@؆%`mYŠ ºå`îY…€ƒn`u£Ûþg=áw¿»4Ð{½@ð‚ï¸7|I:¼H¾á5 ï?BHÃI ‚t`{RÁñ¥"‚n>Ó|¶¢bf/s/m!Âó?Û삐OV"x·‚¬F`‡'˜ÿ¤!à,ɹê Æ0z}áßOX ҂AÁg,ô7¡ð{Ɇ_g"D.³ǃ +žQÞvˆñ·Glˆ„üYˆMtBtÊ"ðsÁ+]ð*W„5¬Fh+ !‡½À:æÖi__¤#è;?=öGÐ+b„ÀŸ¬¡ðà à¿á`>ã‚ù˜7ø¤ÃҁO=íà3â@$ñfAœà„õb³–"ºh%ø[WƒWG·Ùámtp:ýÀéf€}6aיû™è DØ @+Ìþ5zÎëq$X?ñr'j"D‘­Éu§"֕ +±›¤žS g8@> J¡dòÅHJ[Q¾+âÊ<³Í‚:ø­ D¶3q,¼ÓÁà]bûkœû,d„;2È{Çêç!´—ö8?Dƒs3œë“€ÀÙüU¶HXA…ŒP»ÛAKŸ +}Ø,èNÐ&-†*ÅòunH2Ñ ²Ð_Çx+l´Æ´Ew„ŒºÃ†ç؃Q7ÙýQ9/¯9}‚ñð§pïŀw3Wâq>ç&Ò!†ü?“È{¨ÉÖÔ¯²ÃZ{d±>@V¤#֊A¯rAr†»UUà=,7ûJ¶$6°^‹ZÂ^%´s^Ä[Ó÷%÷¹ð*·7î!ïqÜ+ÞC¡•;Q× 8/†àËDN&AÐ-™±d_Ɠ|ҶЙä-֑{äÎ@w. …ÖlÙ²Át½[¿ÞàýR[Âøª"¸WQöT¶;ü±¤ûKRgÄñIþO¢‹‚»¢{‚[âÑ7Åc±—!ì‘ î„qÇe•#¶C1„$WLhÙb-‘»Œ +#¹G‘ÿ4³g æ_4®¿egy?Y»ñH_κŸ¼s[½+▲%êßòö˜²ãÂkҞø+’o.J{ÎI‡E§eW@Ü©‚è°¢ƒj$´©ÿ>đ|)É֑‘³Àä6¦UT”ùN-gÍì7G8õ•Æ/yZ¤\ùИN»³n}À÷™%¡7Ò,Ü«ºíQ—´ÿˆ=¯ÙVÝ!þJy2é´ò²ä„òɪ7Ò£ê·ÒvÍ[Éí»¤V-÷¥@¼gˆ_Bî°Àidg¬'=Š—ØÀ¼Üö­…6åM%sz_eøœ_-Ñ ~6K]n™t^7 +r˜— …ìó9戞ŒªèÓé;âOè÷Š?O9$éÒ—w&­8’|[Ù®ý]ٖ2¦hÑ[åͩ㲦ԷÒÆ´wI “ø³ƒšdg’Q@zlZhËR›ájwêËZ¿©OkCf>¨áÿýVE¢Ëu³†v¡$ƒÙ³!}*¯$ò‹\KlWv­¨#£Ir8}¿ü`Z§jêMk귚½©}šÝé#ꆵ£ªVE}Ƹ|{Æ[)!yD‹mìHî@6oñ<l&}ª–Ø Ô­°ým——Ý£Fæ´ëyNßÔ$,»P¡¤}UžÆì.Íå+*âw˜…‡ÖW‰ädïS6gÖ4ežÐ6d\Kٙ٫­ËN®ÍQ×dªªs¬ŠªœqYUöDH$¿[G² dë”Î¥ Â‘2V»€òr×G6Oš]mï5Ón6†;^ª.í©‘{vWèº6g³?Ûh䷙6 +[ ++›Ûey»U; Ÿjks?×Õ¬»¨¯Î}¢ûØ0”RiN®0Œª-†1åVƒU¾Õ0.{$ómJÞ ŸlÞ²ÙTÍ¡ îp¤<ß½€ò°ÕÙæV«ÏÔ«{ØóÎ5Æ8Ÿ¬—xtÕhWf°lYÏßWf6•nIÜY\#¯-lTWìO©0vé·äZn|”Z^0¨3 iÍÆM™qTU–?¦(Ë·Êßyûµ³ÿ¿{)ØL|2‹Òß8›òkËÊ݃‹(7xÙ_h {¦Yðáñ†ÄÕGêՌ¶šô°½çF6Z +…õåæĚ²*yeéNõfSkʦâÎԒâž4Sñý´bÓ:SñÖT4¢1ŽªLƦ Ö   ßa&É.&»×òå÷ú”‡{¦Sî·Í |ß>ŸråÇ”³m¬ÙÝ­ü%Í"·ƒJ¿};ô¡µÙuÕÆØêʍb‹¥BfÞ\¯.1ïM),û,Õ¸éLZ^ُĀ>ӐÖX:¬)(U˜Æ”LVÅû &ßBٜ¥3(CUÓÈ沧Üi™F¹uh:å›'Ê¿Ž¸Ûjú[W[Ä¢öÖx×Ö=rzSS +«nW&·º./fk­I´iÛViqU­ÊXÙ¬5XÚõ9–S©Y–ïˆ×ºœ-CÚuåÃyTeØ4¦\¿ÑªøÛuÕä™ÅüæMBXEA«„aIXÖE@0€qWëz”ŽZ´D¥ +RŠEAPAܵEܗ#n=3Óv +cÇNUԞ‹,òŸg¦g¾À|øó~zþ÷yî}?ÜѐÃf¡À”Í‚1=ÛŧoéA­ˆî4ÓµV+ºØâÁok2?ÖmW{$QRYkð+;”£.þb‘î“Š‚¸Â}ëõë˶¤­ÞSœ±¢´"{qIÝüü’Óyy%÷˜×óówöç,Úñ>{IÑ@ÖÒmƒ˶\6‡«Eô~Ÿ¾ÛÃу*!Ý®3¢®ãFt¹mu´M原T™Õµh'lšéöy}ªOqÝÜàOjó# «—Ǭ;¸&aÕ…)Ë*>K_X¾?+wÿ᜜}móæî»Íôådï}Ÿ=×@V^ñ`æ‚O‡2òw Í YÖóéÙ§D÷ñèN€®6èâ uœ1§Ö³.ÜÑ3þ&Õí“öŸŒsÞՒ"/jÊT6慮;ºT·ªnuÜÒÛfå×î˜=¯¦,=³úËÌôê“sÓªo2/³ Uƒ™åƒYeCs²w§ç”FÃRևÍDßï"º_IÔUǧ Mµ·óèø%Sª¿,æÕ\RU\µ,=ã°½CïQØ>ÇwÝ©yÁ'G,iY5-¯yc\vSѬŒc{“SkR“N’oô / ú£Ã†”/?R«>¤*FÒÒËGRGC€žo#zTFt£šèb=ÚØî×t–G_]Ò¡k¶TÞ%”^ 1ßþM´má•D—µ—Òd+/dû/>¿08÷ìÊð¹g6èÒ;¶ÅÌ>½'^º:1¡½Uúº>¾ý…>î’f6#9ñ(’õ‡‘œTƒ¤Ñ°Žè‡Dw]ùŠ¨½‰èÛ½j/qTyÈÊîM¤’{î\Ñ]¥Éæۑ×ފ³_q3ÅmÑõ,Ùük |³ºV®®S§\Ý1«s·6¾³zڌÎÖé1×™Ó£¯ vÚyÄÅ´#>¶3ãšÇúåÏD÷]­!êh`÷?ÁòÏUtr´ë®ˆŠžšÓ–§Ž¼O}„«Ÿ„Ž[þ8Æ:ÿ‘Þ>çá—Œ‡¹©Ý˼’º×ú&<تŒ}°;húƒêèîV¶û†F×ýByÿCxø]DFvAu:íyDöÃgD7Ùœ«#jnfù§‰Ê¯•ÜâӖ‡"ÚÐkNkzż•½rþ➠ãù=Z‹¬žkCOš]JOŽxVÏ×øžÜcz>–F÷”ȵ=U޽͊ðt2ÿT„þ8èòw(CþŠ@u7‚5÷2Úýω.Õµ4>Åò/í¼NôñŽÖü͈V¾´¤Å/y¹/eü¹¯TF†WfɯfŒOx•dחa3½/ÏN×·Â!²oƒcØëí.ê×û܂ßÔM |{F¢úõ‘Dùæ7‰ò$þ/!õÿò€Ÿà5Zç!¢“õDul+XvvÞ'úÓ_ˆ=7¢Üß-)«_Ì3ô{pÉý~‚„÷j£Z“èx³¨ÁÙáƒY4Cùƒ‡ +¬UC›lü‡wÚú~¨´óùÐdï5òµƒÏIJáA±lbY?ñhí¬GXœaùD›î|K”÷#Qæ;#JÅÒÎ7n:¼øZ(᪡3 +B¼H‰c?dšø`©ã¤Øl.A‰ÅTšàŠVK\ŸèŒ_¬œ0låü_õLj*ÙPü5Ë¿C´ò)Ñ<–?ûg¢D(¤ƒ5E@ÌSÝ „現j¾Q)fÜ1Kè +ƒÐóŒÄX.š‚"[Ûà ñ$´˜X£ËÄ +Ϙ÷ LG«b3Pr™hó-¢Oˆrzˆ’žż#ŠQ(L(ˆ½…?&ñ|X2¸ñ$ðä¹BÁ9AÅ9@ÃÙAË·A,ß +I|KdðÇc¡ÀkfØ.0E…ЍBcœŠÐÍ<£ôëÿM–ÿø|=»¿¶HÍòUŒÉ`JŒ'WöŽ˜Â›'ž «Å +RÞxó,À‡ÎQœ±[9B6³œÙÌ'”2ÕÌq¦c „°=/ÀŸƒJÉGp £ P'D@¢~™&P,6‡÷:Kȋ¬áYf󶐱ƒ´e +¤öð¸â[Ì1<~bÞ8Âc€Áÿˆ!eäìÛNʱ f5(ý8ûñ¡auhBPG /‚*Ýùðûh"['Á{÷dxWÚÁë°=¼š ocg_t„üšäÝNõ:CÖÇô3pf¹ÿá/F—a?¸öŒ„½/‚C8«#"P€ð0!Bgˆ I5CHîxXAU8Åvð/·‡_¾ Žð=áß³ÎP|ãÅ]6"ß3/Ü xnj0ì|ßÿr +€û;ÜßA2BY !Þ"¼8è¼ùˆö@"„nšÚd3DæL@ø²IÐl°EÈv{íuDP•3ë\ jv…ªÝ ÊKS¡¼áåæ¹Ê_™! Xæˆ +’Á@H †ç+5<Ÿ‡B6ÂÜ9„ÉX¾”CŒ'±ÞÄ +ÅÆ+ab2,1m‘ ´k¦ r‹ỜVîŠÐš©ÐÔK iõ€ú¬êNæ¾'Ô½ž#êמCêÏ~ <WCþVï…Á§7>ßE…pVCÔ¿É.ó ¦Ï4Ž¿áY¨EjE­Ö­( Š"Aäø%¿œœ ®„#@¸#rÈ A(Ð"HêM׫­X­³VG+VW—ÑZë]Ýgߝý/ûÇgæýïûÌó|gÞùà]Ðךß$žƒïi ¼VÀcØjDœ0•Ë!D³ +hzG¬[»ÚÖC€q nü@=âüžú­Ë_þ\ßøßr}As}F}íú„ +nsþàþ[xÜ +Ï«Aày9øÿ*Φ9â|ìºüÕfú…9D¸Y@„DÛB(Ï„ÑK€—´âßÕê÷Dñº·Ì*§×ŒFç—!.†ômz<âöŒvlóï´i÷'´k¹?~å1Kƒ­wƒÀëZl»Dïi&xŸbÁ6S À‘Œ•àaç [nb<ÄÅ$^ó@`1셢—¼ —®x!JsüC¿þ)Wï?2aÇ4;N°aÇ1vŒ“àk +ìZC狰o‰—R ï#ÑÉä– ÷³~—H·{/px*Ù½â_Ñ +LJ‘j§Ù°b×»¢ªÍ·û=oò:½~æöy_#¿ò™!§|ä\Üq™¼çwž|¾ó ÔÓ$|ÀQ>P‡@‚¿)ŒwÀÅÙØuâ°sÉW`ßÀ÷Qn2«ô¶ú#5hÁœ‚óéyÔò»R™ã/’ô×£5n3Qº-߇¼/†5ûžuûM üÏ +ÆN Îî:!¸x\ð$hBð6&ÚP(õ‡APo8ö„Ã.S€Ž3‹)mOÄEHÁód¬¦ü¥Ú`ö\íiùX½Óf6“iK¶ì'Eœã²dç Rµût¬vÛ阽¾'Äõ;'£Ú¾‰è :>|$l*äë°èÃáèƒáïý@ï‰zg„´‹!¸U 4S€µ ÷»V,ö …=vÅØû–S^jÖRæ +\Íg ·[ÝÔÛͨË.¦Ç¬=—"w9™”î9)ÓxOHKýŽÄU|%i¤ Åt… D0ûĬ^ñyÂ(žewE¿&:b€hÙ ÌF 0$@¯“@ˆ)ÀÁ=ˆÄ®%ÅΩÄs¨?Aï ÐïşS~+[ov«l‹åLqàÇòÉ¥gr"§2¥.GÓRÃIZÿYEࡄºc|;³+î»#v”l•œá6Knscÿ$â€S„A +¬j)0«¤@7¸øbœ-Ç®“çȳC¯ŠíÑc½ºS¹ŠòSåf‹‹zê‚3%쥓aŽã¹±.#ª¤->½J µ;¹,¨3©†Þ*o&e=d}â0¯6áߐp]PøŒW%n… 8år ôr`édÀ0ø¸»q¶ÂÊ½-ü=Ó-@÷«ìЍ}ËÐ÷†Mçªü>š*g./­.Œqî×È<ÙJŸÎ¬jkF­Q¹—Q—ÒÀ®I>À­L”'꒮ËO¥ÉÀ+I²Xì"¦) Ä]ŒµEú7ô!Ç=*™nïµFÿØgƒfÐßœÍOÖúÚNTÓF*ø«ûËÄÎ=ERώüŸæ\µ>»€fP陕µ}z;¯DÙ/Ô*'DÊË¡ùÊ9a~ð5iÀÕ(ƒakRe +„-D}/Í +=Ë·D·u–èzõ|œo.5-Bgš7˜ß¿Ýf´6xñ@ w•qoäÆ]œGSIÒö:m†u~­<¯”YšSÃѪ[xU¯0'k,Tu!T•õH¤R}¨²€§ÊRlu:¦@îB¢‚L tOKA7*,ЕÚy8>šn³G߶a6Þ²Íz¨1hQoge§!Ì©©Râ^[.÷®*Kóחäk‹UìM/+Ï(LÏ Uæ~šš÷P”š÷^ Ì^Z6éj`§«€0¢pöX WÙØù°wÎT™£‹ –hºu:yÀMt­5éÜ2¿¯-à“®&bEKƒh}]mŒ[UMÂ6]eŠ_Q…*P£+¤«K+ˆŒ’njQ·@¡ɵgCeÚû"yÑ;ÁžBüÛä©Ð;9S w!™‚æ!tCÐå}fhºÙì´@nj ÐèÁՔ£‡UO—ÿÂÖægõ­‚uUMbW]CüVmÂ7ϐ ªÎN«Ô±u¤¬¼“/Õ ãô§D±ú{ÂXý[~|pŠLÔ[V„)‹» Dè×B¼ƒ½w‚Nµ›£c=fh´Ï þœr°ßͲýßÇûô¥Õ]¼5ºŽgm[¬Gn˞íYéþʆܠ¤úRzB­ˆÝ×NÆùQ†üHÃ~TÍ®¸ +Ș +àHt@ĖːZ¢—Yý‚ïpـp±{  ÑC |i…/CC._úØÖ¦-Ö÷‘+µ½aN¹ÆÝn™Ý‰[S¤úÊ;²©ñmŴݭՌ¨–V"¬ù0GÔö)js23ñ²Ö½Ë^;B|–3$tÌoL>,u—õ'{ÅRùF÷j©+EÆæ^O?ƒì™drŒ7œî— N0¸­Àà7]X!¦@*Bw´]ªAèd BcÝ öãü‘ÿù_ݤªžt¤èŽ{Ì+<¶sAöÃ!ý(ÿsÅX亄#qΒѤÍQÿa»N£š:Ó8€?÷&l +‘°C ³DÂaI°)Te´Z=z¬Smµ:í±g\jíÇj­=Ž¶.ŶÐZ7w‹‚ÖÁ:V2Ö±. ”©VD¨ úŸ×±ý ·߹÷Óý?ïó>÷ÃóÕkÆÊ/—¦–7¼›áªÿÐZT_ksÔ7å6¸mŸæäïDna-r[;~Óóúc³x|ÑþÍD_|J´íó§ûßÚŽÞ>êKˎEћÇԂEG->¯±‹çv…Í8T)ýÃÁ©ŠÌN˜Ð²@]Úò¦n|ó;)ŽææüæÚT{s£%·¹35§q0Ͷ¶ÝÈÌm@¦½îyW–µ³´Ô5°;ØþdÿdûßÚ&¢•GyúS»-<Dó¿çæž6zÌÊvcŠ_֍YcÒo,°ô¼dîYbìÙjèm×ÿt"\ßÛžÜý8\ۅHM¤êkˆ©™ÝÁÎíD›Ù ¬ÛÃò²üDs;ˆ¦^ ª¸,¤ÒÛþ4þ¶„·ã¹¼~o»cdÞɦ 8=Æ Tx™îV{îÎöÑ .­\æ;vh½H5´mL¯ûý•÷.ˆ•CwÅñÇ÷C׏À‘ê·ma3ð>›Á•ˆ^gùsX~µ›¨ôG¢Â[BÊ‘íQ(e>Ž¡´Ç*Î Ÿ ¯ƒM †C„ra¦xÄa–‡¯yFc…— xGa‡w$xKpÍ'÷ø„ÿÛØ l`3øvËoùg‰&_$*¾B”ÓM”ù# |Ʉ@ÒCBZ(( *.É\,Ì\ ²xòøHóᨄ`† óX&cƒÐŸ ÇࠇW˜!ÏÙÈfpU3ë+Ñl–?颢«DÖ"ó±\" ¼Hų:ˆ ¢I‚x +C =€qœ?¬œœ/Ê8Tóž˜Ë ±”籎簝'ìcÎ??g5û—|óÛùÿMä¼ÎÎþ˾Eì¼Är‰b˜(xSü(b +Dù³ZDÑhĒTä ñ¬/Äj!8˜‰ÌKÌ"f5SÃìdZžm‡$=m2] +{¦ +”-€²HE•bfy"z¡¤Ë} ];ҏ|!ÝêiÒ¯Æ ª‘9ꏨÓÌbDõ2w˜a1¤xÂÿdì]†Ä òžÔ ÑñÐkyXz“ÚLVG¡'zB9à q ¼ûÖh(þâ ÅF䏁|‡?äõbÈ÷2 ?ɜgßìfn3ž~_ÁrŸ +B,‚Ç#dXù,èT’Õ<ŒI¬•ìiÒ b@o÷€¶Ìêi^;oToø"q• ëý‘P#F¶(wB¹+Ê&æx0”ÌUæ&s/ ø]”NDØPÂïŽ}’9¤0© <ÒT<Ò5<,¬©6˜]ž0Nñ†aÎh$¿.‚n¹?´ €æà h>†zGÔõÌÞP¨…A}Š¹Äô1ƒa4{ÀÜW#‚‰Ð"òf2¢úôςå‹çËÁÇ#;‘‡Í @v¦²žÈ¨ôAÚK¾H?æ¥0­‚q}Œ5¡HÙŽ”ºpvEÀÐ,¡UòÈðOÉà ɯ)’ãcI +¢n »e@t 1W͈¹<îY0*Y¾œƒ-šCSÀêph(´‘Ÿç {™r¦ú!{®Y‹ƒ±<ôqúšðáôÓ6GÞO«ºg©—YöI-Gd–Èn[®Ëþ“Ö/ëµ<Š¹a¢Ë‚¸«Œ;ñg3&óYHeçϖrȗpp2.VO)›R“®lO÷s’h¸pVÀ½üWCíKÃrޑôÛÖGýbû›ìföÖ蟳ëbú¬_Ë{­ä=ÖSŠ®ìW²‰½dVº­H<ŸU‡ª“6¨Žå@ud¤³³ÛÙÞë eÙÌD‡*%ªd*Ó=†'ø •Uˆî”¼x«x^h_ÑIc¹´»pMôµ‚ò+ù›c/ç×Æ]Êkˆ¿hoRºí'ÎÛ/%väÝR¶?T·Ù¡iµC{$Úæh÷B³gX£8²³$å¦°^LUp˜6–0Õ,¨¶yߜäò멚xmâì°Ëå¯F^,]}Áµ*ö\ñ{ʳã?JÃ1úҴʀ﫧‡Ÿ4OömåbEۄ?+[+ÞM:Vö¾æHiîPÉv}‹«>¥ÉÕdÜïj3íq]3írÝ57”`ÜÌg¥0o/ƒiK9ŒŸŒ€<Öÿ’ÿr]žQMgyþ%DŠ +*2¢Ž2XP¤H€„TA¤D ‰@(¡„J¨¡†Þ”¢ AÇBÇ6™=»ãŠíìì–³sfçìκ»Þ½¿€žÏïÿÜ÷½÷üì{¦€b— OòøMbCx-µ'¾”I?&sÖ>›ßÄXߎMÜ9#ÛsãdÞþkQ¥Ž“5ÎáÍn—B»ÝÇN y\8¡ó ™£ …<¡œ;ñ µ?QûB¥+ yµ‡#ÏÖpä!¯ùãóÁ®u»NþñxŸ²ÞʶÀ« [ŸÒ] ÒX&w¤ÇÌg“£¬¿²™<%Ý«‹Ï:0Æ/<8Sî6|²ž¬nó:9@틼H뉸AïŠxÌh|K×D~ ·F!ZS4¢ª£¥.y} + +Àç¶|&€×âüõðt3øI¾ žäl}Ž#ñŽœfr+ãȦéÔ0k4Öf,9ÉnD$sÐ&äº JÜ{ãj<»b›©í1=ôVÞ³™7Åjä=`×ó~f×Åü—YËGŒj>¢Uñ‘wQ1”• Àå°k Œà½Äþ–n‹ÙÆð$o<.°„»öÄÅx:‡»érVȖQÏF›"´žvìI–»v$’5 +Js‚š¦t0kãµìš¸ NeÜNEüOUü{¶J€X¥Ä( Z±¿0D] +Ú(ÚïÀÞ¦ái–ü 0‚ÇE&p¿ØæJìˆ×”žFºߍ£yÇ· Ê£lú2v2±£&%ݵIª «Å¥”3ɵôªD K%ð)^òU +çý +…/ý +E¿s +ÃÌ!ºB„h`¼žü/ ॠ{o. +×Àýc¸­2‡ëå{WTî†KØ´EV}Šˆ9±{[äI ©®µ²rUª’ª:]M/‘6³ %}…ø¢_®ø7[¼È͖üÓ7[‚|äĒ‹CžŒ_ÛdD[ :·ÈøU°˜…½7Ÿ÷JHðu¹!ܪÚ“5¶„ñ*·5ÃL³þ²ËNe莖˜=j…С&ç´K…<‹\šYH)ʨ +d ìì´nßÌÔQnzÊ ÿ´Ô1¿ù¥¥!Y*bÉRSvÑ1´• 0¼…x€¿¦ü{ç·JÜ.7€[Õ$˜®5ƒËõ; çëœ×œ­¡›vUþ¼¥<ä uéÉÝÕÊST…bçâüt÷‚<%7GEϒ׳dYœ”Ìa®$óš¿8ó̯~âLđd"¶41¥2Dÿ‰·ð +÷ðXp§;O¦ëˆ kX£MÛa°Ñ‰Ô­¦®ÓÔq-Ô5Ç·UWFíR•ÇïW–%T§ÊVæze–ÐRókYE;')Oë'̝âžÊ{„ùÅ/!ùs[”˜‰Yˆþ)(šÿJúØÃÃ"ìØûj& p¡Õ´kèÕ0hkñZÛÐÄ1¯i8f­ª ÿ²è ß.¯Zä˜U™â*+—{H˔ԤÒj†°¸•¯<竼ê£|ˆù»/_‰|b +.1ãó]»°$Å[Ä=ÜÅgp³{W#vÏV€ÁôvYB{×>bc'Ù¸¦½Q¥9jUÔº#·‰·'³!á@j½ÄYR›é.:Sà%¨®¤ñ«š™'+|¢*'8•8ï|"*;R…˜Ñ%ˆÁS"¯h5Ë[øK€¾àãL«Æq¾¶ ûf`34ì&œéw3Tõ1L‹z–Ó²-£#Ê6¥-Þ.Y“ì(l‘¹Ä5+ȼ&•WdC#-¬¡¢¾Ì n¸Ç +V¿a×#Fp¢‡V#ZXþ+*_Í¿E{¸Wp㠀®`ç÷ö´`ÿ©ÞÕ#6„²áƒ¤Â!êÚl­Ÿyú¹ +é@ĉý±»Nõ‰öñ{S£»s\»JÝC:՞A=”ÀŽqï€Î;Þ¯©mˆ Aԣ͈zL(Au«yƒ{øoq¾`w0Šý³¿ í@-vвñu ¼´—ì‰òq£´1¶©øâQ á…Ð-q£¼/xçl#GNï –Û*v:ª­s9¬í>ÄՎ¹ûi¿q÷\rçœý@æ ²o/"s;Ù¿}5¯2¿G×ëp€sÝgê—ó±æN‘ kÚdÓ» ÒiWRâÝX0åo3¼9êj”UØÕømÁWÄ;'2w™(ÚËÕÕîç躰t˜ºÛŽLݒcüƒ} 9Ó. Æra®æø 檮´ ut 4Œ”ã|Å$@êMHœ3áüvÌ;bæ=IQó>ÆasëƒçÂ7›å[™M²äΦ[sf +¶³fjvÒg:¾ôž¹`Kýږ:³dëuóÏëȎüÚç1…ö{\Eö+¹W†w¸ÜA'Þ@?@ίXΟH» ¼mÑŒ!üáf[°…BÐÍਞ»Æ_l쫏^ÇÖ'˜1ô)iú¼Í}ågžú6K²þ¼•û£y+wýÏVnÿ³ÕåÚî|í8xÙ8Ý]ÍMÜÁØòðh¨È_ο…ó¿Áú-‚¾3¿'ëÁ÷©pžîŸÅCæ"ƒHvÄÀûY(Éë9ßÐãy’Ñ¡çY&®/J×9¿hZïôrÐÔñåu3‡W/Ìžý¾Á~™ïŠ,ö=AŸÛ}‚nyø´á;Pó –ógîD.~àógЗLÁ{É(¯mÁóµ#¸¿ñ ¸½aœß!:½ 5pxÇ7ø?ÙõՙÆü¹Sa†20À ÌÐf`Fª°P¤ˆ"JQ,X"q%±žUc jtíE±¬=¢Á.Y{ÔuíƏƵG"%( +þ÷!çäØýð;ïOÿç}î}ï'´~¬$¸~²ÔØ0Ofh¨¼Ú#×ÿv^®õRîÿ+äþu°ó«ƒBW e{;ø ¬ÝF´è;¢mù§ˆ†_ x(ã6QÒ}¢Ø§D›Èú֍"Þj)ü]…5GPps¬`|Ÿ(|Hü?ô´-"ŸÖÑ"ïÖ)bϏ߈5X/vÇ~‰nHÜ>6JÔ-«ß³æŽ*ù .ÞC4“ó'œæü‹D¹¼÷´»DÝÙ8?¼‘( + +†Š А:ÒÁH>0Z¤ArCOÁY‚ +y‚JL”X R`ƒÈEv¸%’£‘áÿ,ÝM4‹óËÚò/qþ-¢TÞ{Âc¢ˆçDAõD òƒ„38Ӆ<àAjt"ø“‚Èá¤@4Éэ$H%þ“ΊB+g•l»Àjٛæðùû‚û?¢-ÿQ +ï=–³9ߧ•È“kpg.\‡3”œéDö\‹ î$†7çù1# g1,‰e²|Æ/AÌb|ø±ƒ}Ï~è̂"F‹à×Mï414¹b¸C=A×l[Á*¥pݪdpÝϾg?È ¾"‡ú«cM mdpãk7ØñµÜa߁!\@ˆY@˜‰µ][ELA—,†o1: •À«TÍ4V.…f)«A³‰í”CSÍÛAsÒžØ=ö‚5²V;xáOöLO(áý?Œœo +,À*Àl!$F„ bf‹¡/ÀoŒÚIl¶ ÚErhW±õvÐnµ‡¶ŠígGОc7Ø3ö›ºÅG­:([tphÑ‘W§·þ!”s-FQ¬^ùw¤MË'b˜3Ä͓ x¤Æ 2¦Ëa˜oÃ2î_…†MJv(Xí€À#0œbWaxäØbhpl6¾wh2Âñw#œ P1—×F¸¾ êáœoÓ ˆñç/ –ëˆã^Äòýèœ"†u€‘Ce°Œ“#|Š=Ìs0/r€i•#L•l«S«©Ê¹ÅtÀùƒé˜s³é_ª&Ó}Õó¯Î æwÎ/Íp­3Á­Ö÷ÿ˜àñÌ ‡á!*€s}té$ Käz’Âxåg³[w1ñ¥ˆË—!v”]kt™òCçéï:Ïszk[êü»mêm£Ëkë×WÖj×kºÞzV]gûIýÜVëúÄöÖí‘ š[áõ³Þ÷ØM¼¯tîÑ:Î÷â\BO–¢$ 5J„ä®bôL“¾ïž+oJ,¶ýI©CC×)Î/»ÌVÕvYèú"a…úyÂ:·g [ܟÄïvÈãaÂi ?zÜMx¡¹ßä}->—㡽È.ÄCw&º“] mqm{w'ô♯·šåEÈæ^d›„Ö¬QSzÉ«´ly]jâyòhÇ'½¾P=ì9]}¿G¹û½îK4w’V{ÞJÜèu#qg§ë‰û|®&ó½œxÉ÷BÒSí¹ÄF¿Ó‰ÐŸHDÀ1öv( û»Cߺjxÿmù#ºTFtf’ˆNL‘PÍÉ®ó¨¨î+à÷ÍÀ( †}߆}fö‘ÊDTDDY‡aVePY”M* X´&F«Œ¶±M0.59îÑ´1iÐh’“ÛKsÚíŸóæøÎïÞûÞ¼[ą3r •{°ªõî ×îʏ2hËÝnڒ½Ûª1Sb_›‘ǯ–ÈÝ*Òª=ËR›Dò”nïÂäa_YÒ9¿¼¤ýs“¿öËMFïÜô""ú,ÈMBÏÅ0Rå߯iç›ËPÒÞ÷QÀt &ËVÀX¹) —»²úÊü—w•¬Ñj+Š\Ù¼w›I½l—å¾¼T»Êœl~Yv‘›<³Òs¯´Q”ŸqØ;GrÜ/+}Ò_š~Ý?#ý¹_†äŸ Š¥IÓQ(MCÏÅ0 +`~'Àý4€Tƒ?PþL)í<åã•j0RmÕ|Vw•ï²¶ŠnsÙzýº’­Æ5Å;-Ê “mK +2Šd®²<…gnn½(3§Ý[’=蛚uÆ?%kÖ?9ë™_röÏ>)Ù(NÉBQj& +S¥(Xla¾¦ûᮔö^ªÁÅÚ;éÕë4í>#û80Pk=uŽL{­˜Ó¼/xE}õZÝêŠhžBg./Ûc³·$Ã1¯8ß%«¨Ô#£p¿0µ Uœ$ë÷M”öK]ñO=¡ëO>»d(NÌGQb. +wç `1ÜJ³D}ȸºP:ÿ™}'iÿh`AÏ=èh²cZUë‚4ªëÂuû£ ‹kbMeՉV9•iöҊ~š¢Ø-¹¬FXÚâ_rÔ'N>î+¿ä+D×½·£8®E; +Q¸³‹ýB³ð`¡ù4ԃs5ԃzÚ{ÐÞÑÐvHš[­˜úCìêƒje-¡ZEM‘+ócŒ³â-$u)¶)µYŽ»÷º$ÔTzÄU7 ·Uõxm©õŽ®¼è]ùÀ;ºâ­xsŠ6—£pk +bJÐs±—ñŸS” 5¨¤PþH3@/í ­ô*ÜØɅÚ.3¨êre•vú.+ìÑÌk_§›Ù¶Ù0íÐÓ¤ƒ{,wµdØíh’9Å(wÙÒØ辩¡KÙpB´¾ár_´¾þáú:l¨EÏÈôØXµÔ z.ÍÑ,^.£ì¥üV€Ã´6ôTõªƒ¢ò~G¦ ÏK5§÷=õŒ£Z)G¢ôv÷Äòâ»M·w¥[ní̳>\êÙQç¼®ý°kDûˆ{xû°ö¿¹‡µ¾v;„îaÑ=¼Ý"—z˜NϤB€ 4ƒMC”ßÝ Ðr f hˆ ²a]ȱéˆ';m$€³gxFÂЭ¸ã[õbŽÅF¦˜lÌ6_7 ·ŽèßoÚßîÒ7ä´ºšÜÏ)¸÷Õä¯êAçUÝ輺ù‹ÝÉ¡ûQA5h8Aù½”ßz v ”V’,ÚÓNs!eÂöL83 Þì¸ÓÁœ˜Óï«GŸÚÄÝx*NgÝøýˆñLÃбB㐱³U£m +›²»kpò•µÿoÑÖoíü†È±¥>^˜êÁøAêåwP~Ã1Ú?OäŸHØ1ŁØi=ˆ™±Í3LÔL{ÃÌÕµ3–…OǨ¯™Þ¥¹zZ¢ýÞtnàT•¾ÿÔ!Ÿ©ACï©ßóÄÓ·yâóóF¢sh"œD3ÁïÐ\p-»Ds8Ió?Dýï¦ü¦ã´žM¤ŸØy`Ó%6¼U"®ò lÖBgE¢ b‚•áì e”J 2Žã§L^î£ÌU++„ÊfMOe?×ãÚY-÷k7µÜgçµ]¯ ®ËeÔw¾„+ù¡Ábç©G)¿…ò«Föž¡ü)€ø‹”O+aø5ÝX¾s\ð™3ï› ¾)¯Ï‚@x+‚܊fÅ֟ æbãtÿõÑüµRýk(¿j/™¡ü˔? ú'€ÀOD·TÀå up~  ü‡æàøÈ ‹Àþñ»`÷$lžFƒõÓÆò™”±xVÊ2ûª™eúüËøù–Ñ‹‡,£§?³xOÍ{Œ*†Pu±AÊo§üý”_t–ò? ú_ˆú#Àš?øßð¼àô%€í7j`ý­X~Çóï¬ÀôŸ|0þ^¼ù@0˜ýWA÷õNx絔ÑùAÁh¿ie´Þž`¸ogÉ?Í×ÈhΓï—ê¤ù¯§|9åg|Hùtö7Bæ|î¸Ý°{`þÀä'𐠨 zhï %h£pÑ4Ñ40Ôppè‡X%ÀB0H…Æ1B‡Âo þŸFš¿ʗRïã¯Q>Õ=ø€ø  šX=àQ¾þ[ L Ìå”É…¨Cy+)ÏØhEÿˉH #[½!ý`¡ƒ¢’|E~\BAùY”Ÿpò©îÁŸSï8R¶ÙBö7”û(èœË‰ +rèoÕ —è}bL¬ Ÿx‘`B/Hb¤Ò͇Cä<ùËhâÆ …3ƒ–Ä̕A#ƒzþ jý†AÍM,ÔH`¡Z&)&5¤™t’>2LÆÈ$¹À ÚUò)}~D^’· ªã°þKÙK˜»0híÈ  ±¢]×̝ACoúÁ êl`¡örÓI©$¤!ÇÈ 2A¦È%rƒ|IþNÞü•eýJµÿ‡µƒvv :Ø2hO»®õÂ÷ Z1È[Ë•ÛX¨—ÌBÝ\RJjÙ¨ÛB: ÕBw˜®ãä,ù\'÷þÅu}GEugq¿SF…A†"3Àu +DÊPAd¨2”¡30€ ½Š€"Š, ÅBKÀ5êZWc‹îšM¢=–hbY-ñæb'œýãsÞûýuß»÷÷Îû}9(zÀy'úóV„œ×&ïq_™ ðÿßûúN”q%]e´v ^Hi¶óØh­d£e-r8hQÂAó:²Š¬'›¹hÞÃE‹Ýä"§¹¿[|Ë}mqûBüœûLŒ¼§bä?ã¸Ç–( zÅ¨÷ëïëË-Ý,ˆ˜ØÚrwýÕØ( e£}¥”è¨o•Üw’Ü?$kxo%¼7’­¼W’ü—’½ü’Cüç’ügҋü_¥wø?Û=ãß·{'¸+Eá;ÛõoKQ˜Ü’¢Á(”[Ñ'e8s21œEÏ3‹fâNóPx³pz]£8oåÉÜW.Zî ¦„÷?¦–ÿ”YÉ̬÷ ³YðˆéüÌô 0÷˜/õî2çõ†]†7\ž +¿gÞéÿÛ'\eÐð +ƒ/“‹ä‚Ëßpú@w Ç$@/#@oZûP/æÐ^õšÍzãáÏ~>+ŒóÄ]Å}ôA&ïÁÌþݙ‚;ŠÁ°¢Uï'E‡ð†b‹ð‡;ÆÿwÆ>ýë3ë_›qÖàŠâ¦ÁÅÃ)þ0úJÆ§(:©@““3Ðä8]Ñz~@ïîI¹wŽ}҆€ô<4“{øí£é¬Ç~Þ¬>Áœ;ÞÑܛs’ùߨ\÷Z&¼êU£Ù³Ùà¢g›á7'žóødÒY>£¯=ŒÏxüÓø”Ç5Ñqχ&G<ޚ~áf‡²ËÅ#z}Ñbûø!Õô©Ï\ ¯C áaˆ ÜZd×C¦ÁÅ_öÙE y§ÆèN68”=qh~¡ñ¡y&sL®ž²?°Ý¢?`«xOÀn«>ÿAë]þg¬wüd³-à¹MwN݈6]±ÞˆVÇ@êAå½`€Wal¸¯äÂ-¥†•pM9ÎG2p:ҋ},b>H©.ŽŸp ,ݨ?$ÏäÓEËÌv/¬6ß¹ Ér{ðZëžàÍ6ÝA½¶[‚öK:ƒŽK7]·ÛôÄîã`”®'ë‚QÒŒ¶kàÔ±ÐOø×/&”²ýf~ŒeÁµ%<¸«疈à¤JGT³Øƒqüý±¡Â=ѱ†»¢’{#4¦=Êó­áå–]‹ë­7…µØnm—¶‡tÛ¯Ùã°6äˆlMÈ%YKÈ#ÙªÐwÍ¡hOìšÂPÚ†’c ÿ8ÚO”7c¾¥¼q>‘_'òádâ$8œ,…d»_íÇ۝¸P¸=>Ò°;.AÔµ$ÝlSl®EGt±Õú¨ê©m‘MÒֈ6ûe—¬Y¹Ë©1üsCø9çzåç:åïNµ(#5hWÒ±0¸àe¾ï¨þ7ÉgRYp"• ‡S'Àg6°7c{gº7¯'u¾pKJ¸áFuœ¨=1Ŭ-![ܪÒY·Ä•Û6/Yn·"¶UV³Ñ©6º—©ŠþÌ¥2ú+yyô]—²˜7Li :•Æ¢Œ8н}I ڍ™ÃÛ0€Û”ù®¨)o¥Sæ£Ì1”ņ,؛m ;s䬞l/^gÖ\á†ÌPÃué1¢ÖÔ$³U)™â&u¾MCR‰¤.±Ö¾:a¥cE|»s©ªÇe™j¿kQÜ)Wj˜¼vÑÅ£3q$2 +íǝÍxêAe õµ¹ýZ!ìÌ3‡ž|gVgþlnG®¿^[΢ «³£DÍY f iâºt­MuZ‘¤<µÊ¾$¹É±H½ŽÑ©»åùIý®¹I'Ü´I7ÝrÔ/åZ52ĉȴIè0.x82êÁÙL€cTûe¿}» +ÆAO¡)tÉX…îÜ6Ÿ eið„Æ<¥q}nœYuNŠ¸"[c]ª)g–Ûd48楯erҺ䚴OÝ2Ó¾œ–‘öƒ[FÚ yF2Ä)3 3SQFFa텑½˜ +p:‡z@õôQþÛV́Ît”Ú±ÚJœ–ŸqÅó ê +UébM˖&YçgZëòòmóµ¥öڜzGMv+“¡Ù,OÕìvKÖ™¦Ö|ç¦ÖʟŸÔPýjÊ=µ†°ªÞVÔËÙµuž¼ŠZaIõBC]U„(¯Re–Sž*Î,˶I+-”¨Kª–5;Åw01E½ò¨¢Ï]#‹.“§ò¨BdˆS´c +PFFý ðŸ‘9P¾ £g?Õï­è\Nõšõay“Ô4;³Ê›fq‹ý+‚ ´ áFšúØÉéujóäÚ,«Äš‚©qÕåҘªFYdåÇNʊmLXÅ KhÅ—ÐòÇLX9:‡•¡ãâR”…— ÃX÷U—è[<^H¹“Žá}õݍí͍”kW  ¢ÕJ×8° +×(8ù­ÞüìÕóÆg´„¦¬Š6NZ™`ªjN·ˆmú“ðzŠ²NÃþü?f`˜afnÃMP¹ÄEES“²¼”¬k¹ÙºÖÉn–]6e”¦y¿¡‰Z(¸*ÈX® +Æ)J¶«Y†ŠY®šµÒØ»µÛÎž³‡ó;0Ïÿ}ßï›ùÞ'úMZðBäø׋£Ç½¶2î®â-ñc‹÷$Œ)nJójGüó%þÎW¤?ō'±…=´vß¼pU¬ëB`ý›ìÅç¯àîµJÃì56<¹ÖYki3×dé^S`˜¶ºÐgꪉ~E+§øß·bzß + ·|NXá²ùc–.‹µtsôÈ¥Õ±KÄ,i)X,1‹$fÄ=bao§y-~À¼ËÙÿ…ù¥K€UÌ^Èõè¥îÜ)5cFi(ޔ ¦mJצ–æë‹JGîÛxiüÆÉæqoM³nx$p̆Ùö;ÖÏ .X¿$lhIix^IUDnIcDðܵ‘³Z"sVIdîÊގ±5¼þ«^ç½Èüu+7×rÌ~vð'î¢l3`JyŠ*¢qE²šX‘­Ý[Q »»¼Ðslù$ïÑåS}Fn›a¾í)kþÖ¹9[÷ÉÞúVßÌ­•öŒ­Ú3ʮ؇¼-Áé›%$}“„¦—öÖ0‡=à5PÁü·¸’-gíÅ¥œ÷ÐÇʁi\Ñ&TwW›QX‚±®þãJÃ(W®á¥ wÝ£Ëwyæº2d»f3]/ø¤»šÓªKüR\;-ƒ]³ ®¾lI®úÉ6h— Ü)wHŸžp»8ÿÍÌ_Íü¬ýÏ\ɞà:½¸P¸—;`yµVäÖöCÎûNd¿²êò‘Q7F¥××Òê§j)õ3uÉõÏêÖ{&Õ¯ñrÖo7$1÷T½(cÿ×1ñf`î6àɝÀÃ.`2Wûùf6hô‘ŽX‘t$ ‰Gãá<šgSŽFÿcwüAÄŸ¥¢ÏUQÍË´Èæ2-âãZ-¢ù¢~¬Ë£ßQÑõ;"ú°Ä³§ræo`þRæ¿ÌÞ?ÍÚÿøPTÃúëYÿ@ƇÀÀ& îcÂOò¹!g‚|&Á_$#¨%ö–;`?;}ÏMCŸóO"ðü«h-ÿ…Ý°}Ù Ûùï`;+ÊÚBgDëi#ó—3~ðÌn`k/b݅ ÀÐF ÙIÑ'Ð3@à9=.›a»k[,m±03æöLøvŒ€©ã^¯Nƒ÷·OÃй^×6Am?t¡uނvUàÑÞÛ*æ3N5ïýÌ?Œev³SO §€Hfl¿o|oaêòƒ÷ðú1:w4”;p§ÓPâ¡ûAàßüݶ›7—û µ‘ð÷½-`þs̟ɹÿŽµ2;—Ùƒ?eï[€°VÖþ`þ'`ì ·½x@‰7BÍd£¾Nq”L9ćᇡðÂ7\á….,P.‘›äW/òÚ{”³Ÿr˜ùÍÌgÝÉ̎¹ X¯>̽þýoéÉØã,vŠ$'eÐhšB| öCØÙGÿ ³¿{"$(žúCË ˆiˆáJ0Ž~OÒz™ÑJÚÀcl¡rª¤÷è}j¤Oé]§[ô¾B˜ á9â þ<“9•çÈSb(T¢/âyf(ў¦¹ô:-£µTªD•AÔª¦ýÔ@'øŸ/R'¹áæ‰ÝyN”[ߛ„3?’;nD$¤_ûÒ}öš­Ä-&ö¸ž¶P9UÒ^ªçxšè<~4^ÅÆ.Ü0‰ºá#ê;ߟi¿%æG‡÷\¿÷ãëÐîù ô)Pâça™I³‰½°°–¥´†6R™ºeÙ¡Ü—ê²Ôª›ÖÔ k‹ê´¶«ëMõM´6Ñ®ø‹ÇåÿAb™ÛßN} ±Ýø:–×Fç‘Ç9Ur¿’ éꧠǕÛþ¼ºiEý`_¤¾·¯PßÙKÔuûfÕT®¾ ªÒ:‚ökíA‡µ+ÁŸi_·© !7µó!âq6Tt-¡¢ÿâ?Îô A$²þb@÷kö"q$>“空¢Ç«ï£P׏¨«ŽÙZ»ã%­ÍñšvÙ±D»äX­}åب]t”i;µÖ¨½Ú¹¨´–¨SÚéè+ŸDßÔ7Ljç±ñ:#†#Ý¢{“¼¥-Á¾T3$¯Ó8—”8t%§âúÀ|t$ªË‰“ÕW‰Óµ ‰kçœÏi-Η=>w¾áqÚ¹\wÒY¢û»s‹î„s»¾ÙéÒsÖy6%6{6&]òjHúÁû`’ë’ÄT›$>5ÝÅç@’ÌÚÓ| ·qïÌ4A²yž¬@ü+#Wӝ¸t[ZÓF⋴ñêdÚډ´™ÇSŸÒ5¥¾¨?’úªgcêb¯Ã)+ )¼¥”yLÙe¬KÙgªMi4Hm5íM½î»'UüvSUªX*iîIÒXûægk{³Öø¾›YjveVøíÎÜc©ÌÃÛ5ì SÕ°ç|w ç·cèËöüe¶òüÿmyï”åU¾WóoªË5¨é+ ão"á äJb­ZµŠµÅEŒ(á ˜„K€!@¸„k¸‚á¢@E‚(¥µÞ¸ÔjëÝuÛnk·n»³Ž³Û±Ýévv»îtÝíöì;Óad?üæü¿=sž÷9ÿsæô¾™§¤ß°NJbMH kì˜) ^ ك{x ð »ç“±s%¹Á' ð0!n%½ï&ï¦,%¤^JRÐ/È5Œ…Ä|Ϲ„RŸÙø¿3ñÍÓqS²£Á“²։ةñØùPGì2{4ö!çxìWœ!Ùs΀Œ°ûe$ ±ÿk²gƒõŸ¤|¢Â¾£¢À½Ct¸™+J\V卵WI©ó*9}V™Æ8šë=¥0úM¦TL$[‚Æ’Û˜£I=!ÇåC¡CòœÄYž=ñ2¿/ñ.ÿHâŸùÝòù]rÂ³É ×–Dظ†®…ìÃëT†àuûYêcç¹¥ÁΕAƒåt_¸˜É—fåMMõtf<ýT†ÒãDz–·#­ÀDmZLU< lbÙu²ûRíܞT¿K1#èT¼Ö¡¸)´*ž[SkI%„‡pÂ^…àuÿ^oOqÿ¡öì<ï╻ˆëÅl/Xвá¬n38u‘Ô“¹é­Âc8;Ã{0Kço×öeš™=–[º•s8íϚ6,hUO ›ÔçD ªëâzõïÅõ÷¢º4†ÂE8«Ìᷘ?d`×AÝ÷°{. >vŸ…<œÉgÁTÁF˜0즎ÄЇò“ýyjï^]Žw®!°S[ÊlÏ© mÍná6guñ4Caͤ¨&s>¼*óIeæ#‰Yó¸BCDH˜YCøá®Bâ¾>„9ÌÂΉú×°{^.p!g é0e ‚‰b ŒGP‹ö¹5&0z +•Þ†,ÿö}`k~ ³I_ZŸ×È­Óuò«sû…f털\;')ÍY–”h?ÚP¬ý[x±–ˆJ´$  |„·ÊsœÃ—j€ß¢ÿ7 èA öÞR€7‘© +Œ›`¸Lƒå¯RúʢܺKeî‡M +¯¶’ ¿æ"]`½ÑȬ3V„VÖs͆v~YÁQaIþ˜¸H?+)Ô/n(Ѐ|+)Ð1"4è‰á#¼U¾—cpуëØû.—ã °{FÆñû¸ÙªÐ[µ•ÒUµ‡ÖQyнŜìÕXžæ[W¦]_]j6›ÊBÊJj9%Åm|cq¯ÐP4*ÖÏHtÆ+r¿Þ 5~#Ñç‰0·t…„¿–¿§`²î¡ï”aç«Bð 8Y0ŒO0{©ã‚Ͳ™ÒnyÖ\³®¾VîQS£ò©¬Î +(¯Ê2UšXEæj¶¡¢™§/ïË-唞ה^’d–Þ—d”þ×ÿŠ3MD¨1A–‰ð³J^ðW%fA‡ç=X¬ÄÔÌ4 ˆÝÐÝà‡›B ­y#45ï¢ZšöÑ«ã ©Þ¥õ™~E–¼@C]S_kÍ­iäf×Øšê!az•S¬®z;\Yuù:\Yù“HUIÂTf"P› _]Ax«k¹Š˜Cý“¨?4 +`Cíz'fà,@î€Òw +;ékW½ âj0ì\ŽÅ-ðêÒnؾ$…mˉ°uY [–u”MËe”—Wš¨/­Ø©’•)ZøÊšxåM¼ôƒ›è*¡ ¯uÂËÄ]xéçpþNÔAß{&q38ÔÎ; ¾p;è@Ä5€Í7h~ËD·‚@t[Âۛ ìNîDÿnðî¥÷^>pîWû¾ BïCȃóÀzð`Ýû…u‡P˜· •y“ÐÖ2ƒúcc}8óÜ»y3€Úi‹¨õtïuÔ`ÓÑ€ÐÜ ðcOxþØàÿ©ü>ݾ¿û>øñùÌޏë;x}~l‰Fຕ@¥öéCqÝ šè \íÙÖ¥)û§ÛÀö„±bðJî‡çr:žÉ£P-gã±< å<ܗçáž\„;òJܖ×ᦼU¶ûpÝö8®Ø^ÃE»'¨Ð 霽Î:é'¡8óáÅø^vMm ó-öø,Uîò)QîôÙ¬Úîó½j›ïiÕfßÛêM~/¬÷šµ´æ-ß¿-4ŒË©ÂŸS§Ù۟*p£µ•-lQá犓­|PÞ:‡Ma(ó‘öú÷UìöOUìðÏ°ØfÊRn1MPm6MW—šf«7™ +l0­Ô¬7m°\kÚeYbúÑêþ×­Vø×h—ù ë%µ´‹? Z+jãs¹¹Þ¸À©íl gÚXâØgzjûö~Ší:J[ÛEJ›ã,6PnLW­ ¡. «)˜l¹ÚœkµÒ\ ]n^b½Ô¼Æf‰y«\dþ·\h¾,Ï7WÛÛ9µäüaSßÛøâsæ\ NqÙ+çõH +eíuØìŽ-?Á?;µ—Öw +W”tŠ±XÝ1Qµ¢cJƒe†j–tÈ´* +ÎÖO³Y4KžTh;7hµ.?¨Ô~vP™}^P…}nÐ#ûÁÂ~z°Ð‘]N-Û:â3.mµKîžûŽvʺ{:+°=TFiXC¬÷Eq„YZªX¥, +Sv–fU6ÌzΣåY_L²ý.4W—:Ï~FÈrǜ ú©!{œ¦„œvšzßiB¨ÐŽdOºú„¸Ï%îãâ¹·Ï´•Ÿ7uÑbM7g¬ŠjŽ¥ÝÛH‹ºwP,ˆêª,ˆê©ÎL´Ì떢ÙuˆÍŒ®£lsºdë¦vÉq˜‘¯Ÿ±Ø);|­a\øNãØðÆÑwŒYo _G=9’Ù×7YƒŸ#Y.ù{{3~,°‘ŸK¢`E=÷ôÂÂ^&© W{Åì^•ßõŒVo™Óc€vJ4yRôp» ÝÇØÓ}²ãب<§¬ÈBcfd±óÈÈm.#"Ë]†EÞtɈzëғã°HáPç)Ç`e8p’¹ˆv$pŸÈøñÀŠÞ(ŠµÇüxÌéÓJÊë¨ø¶O¨2'>R=9®·åÄØ$ëìØAòØÞ_ٍîõµCfÏ ú‘=s Ãcæ;³ÊeH¹~ÙãˆkZL½tN‹r"}zŒp¬ó˜ýp©pŒùïcü-µï4CJb¾ó€Äe®ý6¹%%pë›p…j\ú&#’„éëÜéÌù€}ˆõßÎø¸åYI ¹%Åû)֘šêŒ‰ƒ›!;Í_3øÃT#R£4ƒb­† J²IOd—úÝeÕô•†á7 1P’°„,,.¸V°:,õˆU±‚HÁA@ÙÙ*›‚`-‹k1X«b]Q´êQD˜Îè´#UëѱêèØrԊÖÝ:õÎk+ڙsüãá—@¸Ïw¿ïÞÜûŤÚÆ,ÈÕF/(ÖGFWÙύÚä8;j—SxT‹ÓQWÈc‡ð(a>_è#æ ÑöÐÅ}xŠk°…ùßÏ+èö$ö|dmýŒ¥8Á…IZä%BNò(If²—4-y’YrR€"!1Ôbaâ\eLBŒUt|’Mä¢,»9‹–ê"VÂâ6:„Æíp ‰kv +Žûž Aˆ>0^舶‡K¼úgÝųô×f²ï]̐¼ Þ¹ù>-Û)9½‘˜;‹r=$±¹ãeѹ~òȜŠ9Ùaّʰ¬…êÌ4› ÌÙ$Khzè˜Ç:°ö œw=}ÕlIVæ…|¦²ï(fïYbŽ¹¥Ì.sFx™ ÂÊ<%!e¥3˦Ê˂äÓKÃþ¥Q~Ë-'-ÏVy—[M(Ycó^I­­WÉÍؒSš±Ëîڎ]*l½ŠH!)6=g°;ؖm^¬!ËI.ÝI¥À¼•ì}*$®´BP•#«† `Õh¼¿ÊKâ¿ÊWê·jºlÒªP3Ÿªyò‰U ïUeXxUYŽ©¬RzVnQyTîW»W¶«Ý+î¨Ý>j·„•Û +aå^öšcÜ{™s½Æ2 |s@Ò鎭ÂWëÙÿU[`ò |7ôƒq8¼î˜P3ãk¦HÆÕ̐Ž­ —Ž©Y ó¨I‘»ó{6–+Þ1n2w5î5w1¶™»l¸mîò‰xkÄ:²VXŽXóšƒ\s;Ø}FïZ:K+œ* ­ê<ºƒÙùmÆoÆÔªàY§‡G]¸×€[½þ\?£MþxÇ,iš+q1ÅKÞ6åH‡™VȆšjdCL»Í›NÈ×ß2T+䃶ˆ^7“Ï„¢‡=¬{ýÕtW¬ +èMÝDofm¦Õ·žÛ×]2 kPãO  Ý3CöŒÀུwîõǀÆPôoŒ†scú6.CŸ}ë$Nû¶K÷ýEâØØ%qÜó\ê°[Hv ™ÃÎ×l£#ç½z÷ÛÒ,zÒaèõÙ ¼ËžÔu?0ø Ðç°†&5ôM:èöƒîè0h›Ý`×<šcþ°=Fâ`Ӓë–rX·ÖBÝz„\…Uó3X°>"$d3ýë8÷2Î;÷sÖà `î. ¨ðý’ù§×õ00è(лв]µ:!‡e› +mv0oë EÛ2 +½NŽƒü¤?ÌÚÃ!k‡´½’vN®}'Ðñ5Ÿ·‰à) i{Mõ'܋Ÿòû¨HÞDrÎAôúÒû.½.ô ×ñ iT€ù·€ä¬5/Zà\àüà/Ç_\Jy¸ÄCð2¿h/—ð`æ¯pB—/ðù˜ˆÿ¡‚뭐yOåÜç3ß3ÐO¯çWÀÛô:赦×ò;ÀìŸàXä_à*ã¸Æ8®kx!vº7\[cÛŒ£›‡@77þ€»,ð]Nêî¿ùþ)ŸâKéOgÍ£p4“þx0mÃځ¾Ì=½jz/¼×ȏä¹I~"ÝrŽ©~¶æÅT<ì<<ãEùWÊÏy ~ +n:ÁÅ-ZÉUòð‹€˜C@(ÿ4™nOÎyØiÖþ×/ÇqCù¹.× (Ï+ŽŸ÷Ý+»ì»7&‰·FÁ‹¨,(,ȲܖEvvå²ìrY–Ë‚+  "²ˆ.!xCƒEƒ—h¢&Fmc›Æ6ÓIf:i:MS§M[§vÚ´}zâ˜é‡ß<ï¼_þç9çÌyÎ>|e >X6·—ÍÂÍeà½å7àÆòpmÅï©Å•O©K«½€\@Îÿ$” dê‡âXÁqû·u,x¼FVÊà‹e«àÓ +øÙ*üøU-Ü]ï¯)ƒ[kkàݵMp=Øï{©«ÁýÔåàaj1d‚ºrŒºr–¾r…ž_w~kÝoè7CŸ°fC ë$r"”°ãùCÈkKãä©GmŽoµŸ‡³áWkðqðKp/4 n¯RàZ¸.G˜áR„•ZˆpPçÍÔ9E;}VÑCÏ)öÓg~Ö¬â(ë”b–}Bq‘}Lq›=£øŒ=ùWΑHØH¸ãÈ둄óCHƉ£W‰Ï Ž×‡ÈG1÷7rá}…®G­Å͛`!:Î)3aNi¤Î(-Ô)¥>¡¬§)w²f”ìiå^öQåg2z‚{8ú8w}Hca klœ!Mw0¹…7¼›ßŸ¼WЧ>(ìU ìQϊ¼ê·™.õ=¦CýӞüOQ[2 ô$á÷<ê%žbÞ¿Æ{?Ì@ω¾ïlÔÇsc9•Ê…™49Lføv3ø3©áÌ ú@fk¿ÖÌîזsú´5¼ÞŒF~OF«À›Þ-ìLß/jOñ¤ïJ[¸Ó>´¤})iNÿ‡Ø•ND„"BWÚO°þ_¦àz“p}ßbè·0–éL +&tRݱ†õ‘p@Gùô©tŸ>›Õ«/`wg[¸]Ù6^Çg@ێÂÖ¬Î@wV?Ӓå»t3ÒFݼ¬^wKæÔýZV—õw©#‹ˆÆ¡#"$ð9põÁÜ7\Gß·`Â=¿` +c™Ðãži`à@îJ0†CŸ1ö“)¯QÇê0æ±Û󊸞<+ߝ[ВëºrÚE 9{ÅNÈÄa˜’ÕޒWÞ•Û ŸÉm†'2›H1ÂØõD„>ãìÃO1wŒWÌè9KŽ¡ÿ›(D}ü7˜û +—A¯) ºÍÑÐiÞNµ›3X­&{§ÉÄm.,ã5VÔ4ë +ZE5ù=âªü!©Í8)³çäåÆëAeÆ_•¿•—‰´ÌHÄS–GDÏùÖá瘃[xÿ·qõz½ßž~\ñ__‘zŠ_‚Î’h·l‚V‹ŠÚiI£]–lvcI>ÇYbá9Jl5ÅN¡½È-ª,òŠ+̃ÒRóaY‰éLP±éZÙüIÙôXn6i‘‰H¦¨ˆžó;¬ÃÌû Ô\¨À>´bð<ˆ±ôaN¼¥<Ø]&OÅp[#¡Ùºj´jhg…Žå¨ÈãTWñìåրÊr‡°¼¬ETZÚ)..š-ã²Bˬ<ßr%Èhùù‹Üh!Òü"A˜übÂÑ3¾À:ÜÇú_CÍyÖÁŽ~ ρJÔÇXÚ¬,pÛ¤Ðlÿ4V…ƒ³:–rT'ÑÕUZ–½*‡mµ›¸åör¾ÅV-(¶5š+w3•û$Fë˜,×zRn°.Êõ֟"–é+ˆ‘Ê ó=¢g|Ž}w뿈šsµèwj†«Ñï mO žµ 8+ ¶n=T;£ÁæL ¬Î4º¬.›m©+à9,<“ÃPPÛ Ì«õˆrjöŠ³kü’¬êã2]õ%™¶ú'ȟdÚ*"ɬ"âL;atv"Òٖxˆ}wW΋¨uºëàD¿Q‡9@ZzüWÓö¦—Áê +rW”ºâ¨—†6»t¬BW;¿©ˆ›Ûdåšê²ÝB]㑶aXœÞ0#ImX¦4ܗjêÿ(IqqJaRëˆ(Õñ‚Øw×1ó¨}­€¿ û  iÀo{ ú7,»dPÜú*˜=áP艁|Ïv*ϓAçxô,}k!;«µŒ“ÙZÃËØՐºË+Ô¸‡Õîif»û<“è¾Ë$¸1‰-ÿ%6Q¢‹nFÓw1—±s¨?åFߋV q#µ¸Ž—¶˜:(0v2Ûµr¼¡ ÷n‚ÝñÕ­¡2»ut†×H§yKد£ö6q·wuðU]ûâº&ۺΠc»îc;¿Æîþ·0¶cۈ`«ç7±ÿðγ€qÔëGv#Mí¶Ôï0ôèú±/ÒûWCª/R|JÐøA=N% è©DŸ‰Vù*Xq>';Öçá(}ýÜ-¾Ã¼ÍýgyQ¾Û¼¨þ¯xQ}ßñ£z ?jÒó‚«Xó³xßc^€‘.€=È.üv v)jçõd¨Ґ0Â@üÈ+w(¶RÀV,Äú“ Ư…èÑ\Ø2ZBm­¦6Žî¤þ^V¸ŒµÁ†µÞÿ{½ÿ·¬°‘±ÃNØrà1糨{¤{íi'҈ߕ>Ìjï@k¤ˆ›Ø<ɃȣP]S!> ¦·ÂkÓjX?­ƒ°7þÇvy@E}eaüûOpè}P,ˆ ƒ…±€ +(¢q]×äèÑՠƂ»¸ADET,ŠNPXªÔh{,G$1®qu]{ÖXëۏâîêÙÃùñ¨ï{·¼ûî‰@óx˜g £y±ägΑڛ‹%_ó>É`þQ2lú]f(2C¾¾ü/•)€™šë©·4‹yÀõ³ÕÀ赌A.çÏ| b3õ‹8~¥Zø–9ÀPæ Ÿrx—ë¼;<+"áQ1îír\é\—Êp®4骎Up,§2!9ýµ’VŠ3y³™‹ÔLYÇ»HÝ?çÜÄR·O VFý* gSÝ€cµíjõ°¯u#`WDÂak‰„Î26–1ÐZ¦CcI…Ú²*K%”–£\ï@]+ ©!ÕÚ=­¬bÐ×ԝC݉ÔEݸr ß6À¸‹úÕÔ¯Ü÷_¶ßÈ ª×AVï©Áhð6#GØüádeáµò²Y™PV:ÒÊ ¬—ÉSþ^¼Åú ¼ ÀjO-ÆPwmä¿ë€.û߃€k= ?Øä§À†CIl3ÀYwÒ8ߕÍÓF6eل\dáiâ…kbR5љß&·É+"þCV!ïâV`zïmþÈDQ7Œº+à|°; ¨ÎRûùžü@.óWtl†õlÈ]€ë>À 7Ù þLÜb¾Å|›I›I}g'á&w!¯‰h!…y6ƒ±·Ní(ÚF{;Q׋ºŽç]# »DÍÉuòOr“üLhûvÀ/ôÉCÆæ±?ð[7à›“çlŒžOåð ÷‚1yI#_ҐW÷Éã’èûñôûh÷Úv<xòÏôÔÕ¼ÑmÖ¼EîšÁxDžßÈ3‰àµ=‡—桍°i<‡àÃ,øðæ†`ÐÏ!Pq±¡k¡6@À‡ðkA‘?‘ $‘Ì#©dYM6RDJÉvRK¾!§Éuò/¼Æ+~ˆ·xIžµ!쨭ó„PpÎWø’®¤;H†“±ä32‹$“t²‚䐍du¶rß +¼À.ãž2ižà.ó'øW¿’Gÿ¡§¶½ „Æ™ß5ãÑæ‹H?2„|B>¥N"uæâ9R¸kC°’:k©ñ%÷2S£„VoÃÔà>ê©~ŽéòCø„ŸÓG´¬7ßA8RW¯‡°m!ç +—¶˜¼Gz‘jŽ ÞXjMf|ÎtX@Tjdⲩ±žûçs¿"Ü@#° Ç~¦ðIü ×p‰'ûž4q7Fï \¨ëhK_h®ZGž¥9&ŒÛ‡ÔíGÍxê}L­ñԙŠ0&ד«HÃæÆeæÆ%ärÿM¼ºÅ8O_œ…ߊSŒÇ žø8£t”»Z%#Rëúá®ã9”ôST¯‚hgGŸ8ã¥ÚåA´¯'5£qUŽË²Ñh’%à‚|:ÎÉçàŒbN+ÒqJ±'”98¦ÌƒUY„ê +4¨jpHՀƒš&|­½‡½ºW°Ø2cíjÞAxQŸeN¸W^/'žëíñÀÖ7´~¸¬}6}pV7§lGâ¸ÝXµ›ŒÃö3Ñ`?‡ìã`»¥8Ðnöës±W¿uú2Ô:ìAµC=ö84a‡ÓT9¿F…‹@Y¥ÎBzƒð¥¶7ˈ¥†Üðn.yJ\µ·C£½;N;tÆQ§î¨w€®Ã°ÏíÔ¹GûT{$a·ÇìôLÃÏåØ敃*¯|Tx£Ì{J½ Äç¶îHfÃKi“¯ +IA3!å·!üZËÉ=–Øk,÷»ð `™;孁ÕýýPgè†êö}°³Ã l÷ÊŽcPRÿé(ñŸbÿdl H—ŠVJæ€ Òæ³TX)åÖIy'e¹~’­ëôL–ÓYÈ֐՝ÞF¿R÷Kë…0à©Ÿ3Oöv´Çî@olë„ò®=P4[ÞŠ¯‚Gasð8O–òƒgHy!s¥!)² !™²õ!9²µ!ò5!¥òU!Õò쐣ò¬ÐëŠe¡OKC…"#TțYò?¼ þ]êÿÐ8iâÌG,=Ùc~ÀÙ3X‡²P7líó‡a(ë‡<ã`äG`½q´´Ö8AZcœ"[eL’eʳŒéòåƕŠLãFE†q«2ݸSù…±^•~E•þXµ(\(›IŠŒ­< æԝÏn_>ÿ|rë8nï”õŠÃUØÜÝ ù=ýÛ+ëLXcŠF¶i˜”e%-7•eš&Ê2L‰òtÓ\Eš)E‘jZ¦L1­S-Š0«FlSϏ8 ™gjÒÌ1=ÔÌ6 õ,“Pe ­<¤½W{ÓÔ>ÀÙs× Î:ÑÀW|j +{KÈí­ÇÚ¾>X„¬¨XÖ? +ýã¤ôþ#¤´þ£e‹£&Èÿ5E‘•¤\•¬š™¡ž¹F3+²Póyd…vfä>›ÄÈó6Ó#h§E ÍÔ(¡ž)Tm(›¹O|ǧÞJíºx Š òbØcòç«ûÛaÅ@OdFwƒ˜0¤ÅöÅâØXiQìG²…±£dócÇÉçÆNR̎™¡LŠ™§š“¦NŒÎÖN‹Î³™]ª›mÑMŠþV71úž.!Fh¢…†¨‰*a`+·"Ú}ˆÚÕÃÙc“‚¡œ·âØcòËbuX2Ø©qþHÒ Éñ&̏(͍—ÍŽ)KŠ#Ÿÿ©"qÈ4å´!³ÕSâR4“âVhâþÍu™GEyaüùfav .D‹&¢è‘¨(Ú((Š"¢¬Ã0Ì ÌŒÀ° (‹Åq¡âh]\Q0.cMðhš›4rZ=&©Ic\kmŽmš¸&úõAÆäœþñ;ßý8Ã}îû¾÷Þï}ÚÔyI¯ir“ŽjIŸjíI·4ö¤Çj{’¨²'ŠJ¢xÊUîƒ?3ÝÔ~ƒíF[Ÿ6¶aëØþ>ð¤(Ñ ˆº´Ô¦‡£Ú…*C¬PnH ’Òt‹´$=WV”^PV©ÈO«Wæ¦5©úMß¡ÍÖÑYôgÈM­YÿHc֋*‹^TZREÅS.qžaŽQû ؑläZVóÝÃuÔd¨ÍDµñ9TfŽC¹i*ÊL³—iPlJ“š²¤N“]–—Y(_˜Y®°eº•Ùƕj‹q£&˸K›™ñ†Î˜qZ—‘qC›‘ñ³&#CT ¢Ò¢—‹ñ}mðÛf`6½Ž•9àx%×RÏuԘTfõÇbK0ʬcQb‚¢ì™BAö>dÝßbüûJxŠyhêI%)à{Ûrs™ãâ~0”AZy(R+‘R‰¤Ê9H¬LT¦ ñ•I\Ež4¶¢L6»Â-ŸUÑ]Þª˜^¾WYþ>ùJ¹ø®"r‘¨ˆ,¢J‰«ÌÁáB “­÷Æ2`y)PKÊ8Î]LßWAß³H^ªFBÍ@̯}ñµa˜çž‚¹îhĺã0ǝ"ĸ3…™n»d†»X宖Ns/—½èn‘O©}M>¹ö¸<Âý…<¢æŽ<¢Z”G,!U¢|²Ÿw™óÔ•ÖÐK½REŠøžCíôZ ±ŽÞ§AŠ˜ßõÃÌÆ!ˆn…Ë&`ú²©ˆòÄ Ò³Sy_ôX…)§á©&z%<ë¥ã=Ò<ïHÃ<ç¤a?HÃDiØˤþWÞd®÷Tó<Ôp/.¥ï$‹H.µ³¨L›6×ÌXEÿ¹Z…É́ˆhƤæј¸f"Â×Db‚wÆ{ñ‚׈0¯c½¥ã­B½^a”·]é}KYÛ#„¬ù^±Z”Œh"«DIˆŸ®*ލ/ë빩¹„ò=»‘5XÄ7Ñkè¿Öã7҃µhºy Fm†‘­cÒ:#Z#ñ|[,žkKÆð63†µ9ñ›-Õº¥ C¶ló[|¼åµÞFP‹(m"Ɇ>öP{Û +Þ Œµ~÷u´†ÆÕ@‚ˆÙÀø7hYGo†· ڥŠŽ$;Fc@G8;#É\<Ó©GÿÎôÛ] +Ýî² ÚÝû î<Mç hw=†n§];ÙÑG;õ65+¨¹„P×üÖ`0‡ºÓ^ÂہÐN`Ø`ð~ — jŸŠCp(òC¡ùÂ!ñEAðÍãeÃïãaóqCùè1}ôº¾£ä›úÜC"? ¤«6j®e¬õ¤”º¶6րñÆí¢v÷1þ.êû€Aoý8•ê]@8¦âÅB{|a#üÞhBû>›Ÿn~p»és»yÀ»™èn±ûuòù󘈿°º+¶2Œ7Ÿº™ÔÏXg&Qs45ƒ©9à=@{Ÿ?0ä# pZM¸Ž¹Ž3ÁlF{›ápà3®ã,?Ægyٟå!ïa±{(pöm>/’»‹¿Ð´÷Á. d/`=Èf½CýãÌ70”šÔ§É'ÔþŒü…ü•œ€óJà‚ø"¸H£ò5›ôKãË\Ç~Œ®ò¿ƍ ¿Îb^?EnûD|B]kÀ4åR¨CÝIÔÅXŸ=ÃÚ +(züšŸ“¯É%ò-¹B®‘Rà&kóOæä»ÁÀm•ïÇ?rwØÜåÞ¸÷p¿…0Á>&üÇ?6ê”2«j4âhÇGìÇØLü¿AÜãšÜÅI¼Ã¾x×qï1’Gx“•»É¾ñPý¨ÜR*Ǎê+°GÇsMµÔÎ†PSÇÎ20›l<@ÿ±?F-5š©ÑAÕ¸Í½Å½ÉÞ¸Á5¹ÆZ¼Á¾xWXwq‰+0"<Á°¨â¢¤â‚üMTŽ8UK¾<á¨yÌX>–Ʊ¦þÌsî ‹qW\†·¥ ¼%åá¦ìÀu¥W7®hZpYӉQŸ\òéňïv ûâ¸C8?î ΍¿Œ3n§&<ĉIŸãØdGÈáo¡N¡~·:Gܧ¿ äøӊx0nîúâöøù¸11W&%atrF&Û0¬-Á­ 絜õóâŒ_Nù­ÇI¿~÷GýàHÀ) +øü^ø†?Ç` Š½STì!»Ç|†:ãlGæ˹0§§¦áä´›V„#ӝ84£ߛш3Û±æj웹 C³v`pÖöÌ>†Ý³‡10ûvÍù%¶¿ô™°å%Uè'›ŸÓ÷œ¯8V? â¨_LýHjóȹÂ{ß<µ3&â̬)8>'‡çÆàà¼$¼ör&†æçcp¾{T`÷‚: 5cgP'v­Ã¶ ~akð¡?øÐ|^è ¾.l +ù©°>ä/ÂڅªÐCք|“/˜÷¨û@܎Fcy¤GÑßñØ9¤Á¡ ¼2ƒ¡á؏]‹Ò±cq6¶-.À–ðRlw¡/Ü#ô†· û… ½Âºˆ]bOÄ~quÄi±;âŠØñ¾ØùX\ù/±=R}FÄÿø4”ÇõßåX¿–Lk¡§6c9ì£ ×b r&¶G/Ėú–$£W—…º|¬×Ù±VW.ôèj…Õ±ÍÂ*]§Ø¥[/vê¶Iº!©-ö„Ô;*·Äޕ›bÿ$7ÆþSjˆUÇ=cèžñ˜õÿ·;Þ3Ҙ?Ÿ’¨Ío¬ÉvÝ$ô/ŠÞ¸Ø°, +ëôX“n}ºô…Â+úRa¥Þ%´ë=¢Wß.¶ê×HÍ ›¥Æ„½²'á¨ìNQêô?Rjô”jýWrµ^•\ ÿEãkpŸùß4rýiӊ 2–)ô˜¬I¯~<Ö'¾€ž¤yèNGWJVRÑn0¡Í/´B³¡Bl4ԉC«ä6¬’ê ½ráUÅe8¬T.j* w4e†ß“(Nƒ*;STéë<Œ§ý¡æUڍ³fրög€±ô§Ó_±&k t§ú¡3m6:2BáÍС،&ãr4s±Hpb­±F¬66IUÆN¹Â¸Q.3îTJ3jJ2¾¯qoù؍5vãߕâ U~Jº*ٟóëDÚ2j^¶'í9¶1–MŒ¥‡5é2ŠèX®Ekæ 4g£Á Y·9µæl¡ÚlªÌ+Ä +s•XnöHNs‡\bZ§8LەbÓ~M¡éœOé¦Íô[«éKÕ¤*Ö,U&’5S•lä#æú5/åGòè±i763–µŒ¥+“w.Ö§Ù< 9Sá¶ÌG­%Õ¹ñ¨ÊMEe^–Pž—/8óìbIn…èÈuKŹmranbËݪX-û4y–3>ËuŸ˯Èš‹ªää¨ò–lUã'¬ù j^,à^°±hË71žnÆÓFÖȘÜyP“ÿ"\Ö¹¨´-B¹-΂d”,NJ‹`/(Š +œbAA­dµµHy¶Õ²ÅÖ¯dۆ4fÛiŸ,Û5ŸLÛÏ}2­ÓdZU%3_•³ÆÈS¥1î1׫Ô=W̽H;¾µXÇx:O#c©ã³ªÀåEþpÏFIñB8ì1°Ûõ(r¤£Ð‘-Ø6!ßQ"æÚ«Å{“d¶wÉYö>eyñ &£ø¤&½ø MšýCMZñMZ‘ª¤ªrúª4Æ;¬ùejŸ\ì¥ï³ó®A¼Œ©–ß+ùÛéáX¡EqÉ –Á挄Տü2r˲S–/d—ÙSY¥˜élŒÎN)ݹINuîVRœÇ5ÉÎ×5IÎ4‰¥Ÿ)I%ªœ´â)R’C•’ÉmÖ|„úGiÁJ%¬i"•¤„ß‹ÊkÅ$äUN¥jrª!Û¥ƒÉ•„,—Ë]]EBº«LHu¹ÅW»”äÚ é]ò²ª£r|Õ¨纯ÄUýUŽ«Tå¸ +UŠ+W¥ø²gÜ`í/”³*¸øì!mÄMœüVXEÏ] ˜kÇ#«ÎËݳáFz}Òêã‘êIEŠÇ„d‰žAï©–yZÅ8ÏZ1¶~‡´¤þ°SIŠªOŠrÿYŠªS¥¨ZUŠ®!ÕϸÂ\ÏR㻤ÏŽ@šH5ß5¼÷¹¬ ­IFJód$µLEbË<è[ð¬u ⽉ˆóf`©×‚X.ào¥ím¢¼ÝB„w«¸Ø{P ó‹¡Þ»bhë'bh‹*†6‘FU {ί'ê¹ÔZÏëa©'å|/¤¶¹™ú^@ß,í%¯ø#¦k&¢» jU8"W-EĪd„¯ÊÄ¢n+ºKÿÍu™G×|¦qüû»‰X²YĖ•,–$–›&ni‡©žÃTUk_Šp’ +"‚ˆ$ÉDäԒPJ‹ ÌÔ2‡ŒUcÌLU«ÆÑÚjj‰:Jû›Ï•˜:óÇGr#y¾Ïò¾Ïû<꒕¬È¬ …g³*°¬]FhÖI#tÞM#4Ó4B3`Ži M7-a° ­*tŠfpY Sa*ŒágCÑ~mŽÔw®·@Š^dQÔbOEäú*<7Ps#Ô)7Fayñ +Í믐¼Á +Ρ üÉ +̟¥ù¹jŸ_®vù;\yß)`ñÏj›cmAvÕ3yfó.°f ™øüN5`={e!ñ/–bò¥ˆ¥Rpqµ/ñR»?µ- T@i„Ú”ÆÊ¿4A~¥äkS>ö±jmŸ¦Vöùò¶ÛÕÒ¾U^ö#ò´_‘WÉOjYÌQËx?‹¾„Vv&g¦ó¨ùìžÙRÿ\)¡ý"ôKÑ/“Ê¥Ök›ÈËá%O‡¯<åî‡XµpØÔÜ1PÍoËmÝ$5q¤ÉÕQ ‹cäøXFåç²Tޕe­)× +SMÖ4PIŒ…¬Yh¦Àx>]B –I¶öϕRä)ˆ51 JjµIòØb‘Û¶2¶1 oc­†¯êžR P ¾†ÆRC¡k(b ÎWovÌm7á)˜ÄÊ +é ̉äzørjÀŸôE·§ý èo–ÚTKÞ;$÷]’++«>vöÛ½ Æûðc~ìǏZ†Z}-Í¥–b×b¼–jÀWüÎ#0ÿG±çièŽ%Ïo ûêFɺUê‚ëÁhú$µÜ/5?(Ÿ ÿGøÔ ~ŏcäã¸Ã0ü§é$~œb9E³¯ã¢×Qà:ꢮ¾‡_À|F^}ÝIÄ;l 5à×âwKÝö¡¦ÿaÉ M·ch’JV±ä0ÃøÌE:Û\:Ç¢tž%áB{é ôKøñuàñ¹Ìå¿L‘/¯—¾©…‹ðÌgds2yý¡4]Û!©ûòTò=AíOI.§õÎÁ?úH+‹˜X£¤«MXPÜ¥ëääËʆå»øq‡ù>gãA*K‡»ž×c¼þÀúzM#ßc©ï/ñv?Ž>º>Äé~Ûçá_zN­oá:p´tîÀp0©›JÉÉSjc² ˜ Ç&C’ÉÙ0¹ð&51I¶I1Í/àgÀ³ה_ã÷q0ބ10fÀXùP+` ¬‡-°öë6ПÙPŸàðOl°ùésÂà&\wî¼ò…V´†6=  ‚0’a&ÌÅ~¶žj ö‹±[†ÊZ=ÒìW«^»u_Ÿš:Rt½ûúž¿zÎmø®Àe§.Þü랍ø4æ¢+ÄÃkÄ4”xÆ “ˆF +)OÃþ<ì/Â~v—ë–VW%qmÒwÚ¡kÚ§ë:Gç6¥|"gÖ¿lä"\€óNš:u›ƒ[ãזÏjòDÑì‰æ+D1ˆ²¿ƒÎx4¦bº®j6ö³°Ÿƒýì–plVcwv·R…õ¹ø+—è4ñgý¨SX> ίu/`¶@Ûàhȉ+¸“ËÖÄ„f7rÞ}­!ø>wõ7%é,gãŒÒ¹¢YØÏÁn!öK¹¾ktœšÕvÚÈ>Ö <¹¤ƒº«Z¬€ÚÿäŘ® >üâ<ÖrÑ jr…sqQÐëAöKP_à ٤÷ùŸ4Ö*—3ZïzC·Çªljjm3S/`ÒRÁ _Z€-ö +¿N¸º§¯!Úë­ÝMúh§Ûoµ½Ùªn6\[›Óæ‰ÚÔbš6ºÏR•û\­wϑÃc™*=V©ÂcƒÊ=?ÐjÏCZéyF+¼n©Ôû©–{ó>¼@<¡½ÞiGK ¦†ÐþiùOó)r÷ÔN϶ªñ +ז–½´Ñ»ŸªZ½.G«¡ZÛz¤Ö´ž rŸ©Zå3]+}fk…ïÙ}—¨ÄÏ®b?‡Šüj´Ô¿Vþ§•ßæºrž(§­©EÏ hà!úפϣxzº ήA{ÛցgÕ¯™6ùúhˆ*ºkuÛx•µë/{ûÁ*é0LÅFkYljZÚ1I©Z˜©¼ å+'¨BÙÁ[´0x¯æŸÔ¼kÊ }¬ŒPº¤‡üÊÄ~©+OQéìˆfç×uø²6ÄPy ·V·WIH¤–…õRa§¾ZÒi ò:ÑâðáZ>NÙá‰Z‘¢ù³5/bæF*#r•Ò#7i‘{ŒYQǍԨ+ƌ¨GÆô(ÓHyNd7xòÏñ´‹gß{‰=Ê6ŸWvg¾"7Å*Œl£¼.aÊé£ìn ZЭ¿²ºÒÜ跔=Js¢'jvL’ÒbR53fž‘“g̈Ya¤ÄTïÅì2’c?5’b/ScSbM#ÑI̯\%î¿ ˜ñgûˌ\}¤2|)â©)ˆe÷Œn®E1>š¤¹=»*£—Ué½ú)­÷@Íì=D©Öáša§éÖ)šfn$[çIÖcªu¹‘huX&Åí°LŒ;by7ñqÀ´Œ‹3qÖFz›ÆWhD{ÿo¤ÍŒåýˆÏù ìqÌÚ½]•iõVúK4+>B© =5#Á¦”>4­Ï`%ۆ)É6ZSm“ŒDÛ{Æd[š1ѶИ`+²Œ³UXÆÚj,£m‡\FÙλŒ´Ý³Œ°™ ô1g$˜Æb>†þžùªÿå¹ÌãªÎ0þÞ{ KHe‰ KÃ"˜I&ËL2IfÂLB&Û$$C!² “"IT¤BR, ø@¥!µ(}¤Âc©ÐVª«V­Ëc] +B­ûÒÛ_Hê¿gî½3sÞïûÎ9÷|/>ƒ¶£Xî$–æEø êҐ®ºÅcU›8E5IsT¼@UÉ-wdªÒ‘« +G@åŽ2#èXa”:ÖŎ;ÌBG§YàØnæ;ö[yŽc–ßqÎò9.YK¶¹$¹_’môqgœìŽø.jÀõ]ÄÓL,k‰c ­a­c¸ªS®UUê +¥ÍTEÚ<•§'©,Ý© Ó£g¾Šœ¥F¡s¹Qà¬3òëL¿³Ýô¥w[¹éû,óq+Çù'+ÛyÑÊN·Í+¤ÙfNj?gÑ8žIËK+¼ÝMÍuñÜJ,«‰£†ÚT¥‡©ÒyÊ]̈QifœŠ3©È¦€;Kn¿òÝEFž»Âð¹k\÷m¦Ç½ÑÌvo³²Ü[™î£V†û¬år_°\™¶ÙGF¸ú9Æ±ÖlƒMÙԀxꉧ†º,'žr÷`•fE¨8;J…9SU3GK= ”çqÈïɔϛ«\o@^o¹‘ã­1²¼Mf¦gƒéò<`9={¬4ÏcVªçy+Å󱕒c›}¤fCV?§Ð8š+õÀ/žn¥-¿…xBÄRÆg±ÇT7\ù¹cå_-Ÿo–r}óäõ'Êãw*ÇïQ–?_nÐÈð¯0œþ#ͧ™âßb&ûw[Iþ^+ÑÚZìÿÈ\ìû¯¹x‰m&æàµÍä}$=é—î¥o…†%ô¹PF<…Üçó/o¸¼ù£•³t¢² ¦Ë]§Ì‚eRå +d)=àWZ X)å†#°ÚH +´˜‹›Í„À.sAà°x>0ã ¾7ã—Úf|>äÙæxŠü°–²hÃ×A,‡BðóeVVQ˜2Š#å*ŽRzÉT¥•ÌVjé|¥”&)¹Ô¥¤`®ƒ- +V(!x‹± ØlÌÞcÌ î4o2cƒ§ÌØÒ÷ÍؒïÌØbی-²Í¸"ۈ+´cèì/bOÒ~o€&ôj`×ù<÷–H™´ÄiåƒäX®¤Š1J¬˜¤E•Ó•P§…• ZJU|([óCùš +êæÐJņn3æ„ڍ١Y¡ƒÆÌÐ÷Œ•ß3–ÙÆÌòÊlã1tzJٓЂÞ¨‚Rî}eø¾eèWJ‹«ð>ÕC5oå(Í]¥›k¦(®æFÅÖÌӜU‰š½Ê¥WåjÖª"ͬ­ÒôÚFÅÔnÔ´ÚnM©= ÉµÏ(zÕۚ\óµ1¹Ú6&¯ègJ•m<ŠÆh‡ÛÊñ|PÁu<Ø´ôø¬ëüZé¦Õƒ4«>\3®Õô† Ši˜¦7ÎÑ´ÆxMmthJc–¢óuCÓ2MjªÓ„¦6ý¨i«¢šöi|ÓqkzCã¾Ôøz[Qk`µmDÕÙÆ#hl#ÇõËY‹°‚àçy&-ù)‹tS“4‹Ýsó!&áÍñEš²‹:ŸTK—Xܗ’.SÄË p™8.¦j–káaÖáãRº3нþ”AŽWŸeÜ4ûôހ·Rbc¥‡ð/¸L³>e~>g|…Aùƒ`Ïš›ÉfNìû€„mÄìáÜÞh5@ßõ8˜ +q ÙPË`%ÔÃ:Xí°¶ÁèÁ³>¢ïqßáB¿¡x_ë]}¥Ïô%ß~1À%øޅ·úü&¾ÒVø#â˜7B¸À%B£–ñ›¿™ñ70vãÞ¯ÏÕ¥ÿh§>Åg^Æ}~¢£”æ$%zEs÷ÿü`@û}xÎËWbCa„ADA ÌzÙè,E£LÿÖ +F¬Ó­eü;{ãv0-[˜žnrÛÅtí#¿ÃLÝq½®³úßþ•j¼Ähÿç8§¯ÄЧm>Gçuäælꖀž“iÏE£Pï0'o©šeX§×ˆã?Lýéåí…á¸0?gÊpj‘ÇÃJðê‹U˜^lÂÔb‡·àPx;†wã@xû#F°7b;&"öawÄQì\r㑗±#ò¶G~-QÅX´„MÿÇ7ÔÿšÏÌg«Ø÷¦Q;…O-ý¼ÆñSQóp2"G#q$*‡¢óq`i9ö-­ÆÄ2 v/kÂΘVŒÇø°#¶Ûc×akì6ÇíÆXÜŒ.#Ë/a8þ6Äÿë¾Ã`¢„þÇCj~Éòãc>1ï1½ŸÍŽÓÏÇ_¦—Cq‹±y,ö$È°31;VcÛÊJlYiÄæ$+6%90šìÁH²ÃÉA¬OÁPÊKL=ˆPêISßAŸì&ze?ÅZÙ#t§IÌ ›%UÂoWó9R2yÀ¹ÔWP›~Xža½ìJy;R¢±U–„±496®*Àpz9Ö§ë1´ÚŒÁÕv d¸Ìð¡?£}™ëѓ¹ݙûC—üMøä7Ð!ÿíY†'K‚Gþ=2%|Å'å>KŸËäL!×Ïrl/ýŒç°ç¢—Í™s1š‰ ò e¥c [‰àšô¯©DoŽ=9 èV8PxáWt£S9ˆåڕ{àQN£Uy^¸•ˆ–Ü g#÷?¡”ðÅ3¾¤Þm>óK,;&Y±ÆÍgßɸl`\á*cї›ŠµyÙäŸ_Î‚jø +Ìè(´Ã[Ø +OaZ ƒp«6Â¥Ú‡jJ4«Î »êš°©>ª‡ÂªzB$a-œ¥@ŸSïf÷Ïü4™(c¯CO#ô²Ž± 1.½…aèV-EWQ|řh/΃·D¶’*´–á.m„«Ô§ºÍê^4©‡aS¿$¬ê—EƒúŒ°¨¯³ú¾0©ÿ êÔÿu¥Ò3J$a"?¤ÞõJžE>ñ‡ÉN–Å›èiˆ^ú—µ¤«t!:ÔQð”%¢µ,îr\ÅpVhЬ©E“¦v6VíZÔk‡`Ñn&íAaÔ¾& Ú÷EöQ­ý½¨Öü‹H¢ºâ5咸OÍ«zà4KáI²½Š='=駛qñfܚ%pi—ÃQ)CSU6ìU…hԕêӣAgF½Þ³¾&}Fý ú­¢F@èõ§„Nÿž¨ÔßZýòO¡ÕIB[%‰Ê*%q—š—X'{Éæjîé¡}´ñ»‹¿›õá°UÇÀZ“Œ†šLXjó`®-…ÉP…:ƒFC#j -¨1tBo Ag•Æ}Bcr:#Ýƒ¬®•w¥#³K Vû5H÷æ·Að 5ЇäÀf$&±"p‰ëˆ|ÿwHìdÅꓰb† çÝ|—¨³• .â&7P[Ó³MÊó³÷`븪oRû#‘Ò‡äþ$3±2˜‹ÁR$uHYjA\¨±¡, íÅÒÐiD‡®"*ôcD¿AtŸ„¥½³ôH8ÅõMžEÒNÄLm]'{ϐÏé¿L—wXÕçÇ¿ *óÊpʐ%DqE¢ˆ×¸¨ /Bˆ«ÆE‰yj¢MlœµÆ`֓&­¶‰Ñ8ÒÖª16Mn?HõÏÃ}~ü~ï÷œóž÷=çô~ý¹’_¡¼ŠäY⦎%Þò( »)Dn¦(è/WS¢:˜ÆË`ʖ‹©@Φ%r2m”£é ìKÎʡ䶋–Ó|‹œ­2L—ÌhÂL˜cxöò,ö WŠžƒþ<ô‹$ßRÉk3`…\ÌÎr2»ËÑì#s ìÍ¡jgŽQ[ó ٙ“ekž,3ƛùÀ¼vsðZ+Ô*ŸPébË[¨åµ…OœÊï¤ÇΗú˜Ðgß +©S3`ä¼ÌVíjeSˌ[ۑCÕh€ê(Âuš:.–:».X¤n0g®<Êû̙+úË[¨F«_sa +¿SðyH1g`^.õ@×÷UÉsú«$§µ’Ýzß 4݁fp“'E—†g Ç +m=E¸ž‹­ž¤®'˜õ•°ÿ½Å{—xÿ€þÆÊK¸›Ñ4ÂbXÆ94sÐ퉮ïj©#š†M’C½dƒ;Œs¢‘ærÎ]ر;ö½Ø±;hŠ(|F‰u€l¨…]pšw¾år¦›ß‡ {é)ñ5Ò“‡Õœƒåä º½Ðõ݌>š4ÛïA³p…&ŸB‡á‚£4çÇhΏ{H¿c_N`G#I#ů‘KæÉuŠX4²`ã;ð1°'-ÍÌc³Ù®quÜë¸x-t»äÉžû%—CR[«Ö1Y~ւ÷à}8€³6Ò9‚ó4ã.ûHbÇUš(€Mö¦ém™&>ºv ~‹f³¿“ت¤×ÙâŽnÀÛäéc8!µ;ݪu.4@¬W¡ ®Á§ð9|ÉÐöé¹ú ù-ì¸M“ôÅçùyw¡t±{ñÞé>SÝý”½ƒûӆã˜#äÀIÉ? {çY÷r«¦Uë ø +nGL_ÃMÀ%݁{ց 0´=&&OVþۃA’ý…ÂcáÐYØp ¶²ÜdÒrƒ­Xw‚@ˆ€þ0ÆC̄9P ePË`•~ašûYõ̍;õ¦ÁÙ¼'ú€ óK=Ö=⭇­Ü¿Áð‰uޔœÀ±õ¯Õ_…8 £ l4rô”9÷ sîcìx„ÿƎiµþ© úž)ð>sæ]÷Žu› ~˯›|ù «| ×á\KÍ68€Ø´þµÚä Ýñ+’/û£—ˆýcÑHgýi¬?›µ ؂Ö.cÝ*üZÎÚk˜l7âùÒ£49ŠÖY}Äæ]ÅZ«æŸZ9ïÃéflAÿ‡›M¢ç‡O¡èÅ¢÷:#õWöäϚ¢ÏdÔÇØÑD<®²/W°ã2v\Ž Z«sÚÂ.ì$•ßæB§‰ˆ|¯“Dò*Vޅ£p¸Ù†gúO›Sª-±3à“7û„V8~$`ûP]dOÎ)•ã˜F֞Â\Ö.fÍ2ײ VG´žµ·r…ì×!ž¼…eˆØ~²dJVö¶²ç9Ã]¸Þ|äñÉ_|ñ#ht¢‘Èú£Y"f°¾Q±£;öcÇ^ìØ£jí"GßÔ&½A,¶“[Y¥6ÝM¨YÙü¿ê߶i9æl¾숗Xu—üèƒNöÒnÎÉNaý‰¬ŸÁúF½Ž[ȏÍ2‘ •dæ2"ñ­Ó62äP¹YËá]Án¯@õyžråßáÊÿ”«ö,ßåŠ9lk½’ÐtŧÎdX´"ÑIÀ‡Áh$¡14429ÓÑÈÓJ²æB²b‰–¢ü*_T*öc1‘­´¹­ +Û§*oC²{Æ´¯SöÎÃ1Êήڝ<ÛA ØÚÆß<8ù~Zg¢Õ¶ÑZÙf€VØ Õ²¶ÉZÚnœjÚMRuû©ªj?Sfû9ª´/Q…ýb•9Ôj¡Ã&-pÜ-“ãQ;]T‘ó-ºüԈçøŽ«¬ÉÒá‹>eo{gÊ)ÏÖQ~ÖÚh£AµN^Z椗0U¹Äi±áEUUn­E&h¡ë•ºerÍU±ë|Íw+W¡Ûr¸mз]Êw?¢<÷‹Êõ¸­Ÿ5«£¥n ký0¼I²!€vߙ‹òWÕ_ín/³›»*Ü}µ¨c°J;öU‰ç *ê4Xó;Ð<¯1*ðJÓ¯,å{ÏTž÷\åú,PŽOfú¬ÓŒÎoÈØù·šÖùœ¦v¹©¬®?)³«E™]žñ×ùïC)Ë!´°*mžU2÷aËÂ.mTêÓAE½5¯kæú†)ß7Vy~•ë7L9þɚå?^3º¥kz7£ŒÝò”P¬¬³2VkJà6¥Ò¤À3J ú»&=UjE©Ïø°7%ŸÖg¬‡¥a´z<+Ŗ¢žô7Äfn€³^ ôÔì Íê¢ÝûjzMë9XÙ=G(«çeöJSF¯,¥÷ÊÑäàB¥W(5x¥&„Ôk\ÈA yOcB®+%ä‰F‡XZ¶(.E²QÒ6XU´¥<+Ė|lÉ%69Ášì¦i!]55´‡2{‡+£wœÒû Ôä>Ã4)l”&†MPjX†&„Íиð /SJø +ŠØ¬äˆ%EœÒˆˆ¯à  †C˜E#à\ ç0–6–C9ñ,{rhÉa”ÖV™á®šá­É‘J‹ì­‰}£5¡ï 5D㢒46j¬R¢'kt´QÉÑù½@#b–jxÌF½³OCcNjHÌçð, Q-œ‰§½ƒ× À\ZãZ#mP¶¤GÙjR´‹Rc<5>Ö_ãbƒ5&.R)qñÕo’û%jd¿%ŧix|¶ãó4,Þ¤¡ñ5œðš^JØ£Nh`Â'ðPâ-ø?ªË<*ÊóŠÃ?we1 $€’n "Ê"ë° Ã2£,Š0QˆNHAAÔ(Š±ÖŒMªqµZ5qÁ4Õ¦‰M¢¡‰6mzš¦õĸÖ&©žÆš˜X§Ãüaç9óßÜß}ï½ïûÞï"ΡÓÉÔl‚åÐó’X?m‡ _fàK1ŸSÜU˜è£üÄ@Y’Æ(/i‚r’'+;Ù ³Á¤,ƒE&C‘2 2¦ÌUZJ£RSÚdHéPRÊ>%¦œRBÊNJOù·â %$»HrèíïÎTö#,…g¡–¿= 3ð§ +ùœb¬Üoe§Ȝ6R¦´pe¦E+#=IÆt£ÒÓs•jœªãLŒÕJ26(Á¸\ñÆMšœ±G±'qAÑÆ;ŠNw(¦‡4‡bS:Fë» Ö@‹QšU<—Cqóäñl6)c¨22ŸPzfÒL¡J5M”Á¯ä¬T%e™•˜U ó ř«4ÙlWŒy©¢Ì4ɼK‘æš`þnkB–C‘&Èìå0#ÑOa4Âé`…0eIFs¥f{Ȑ㣤œ@%æŽVBn„ârc59/Y±y™ŠÉ›¢è¼M²ÌÒDK½&XZaY§pË…YŽ)ÔÒ _+4Ï¡°\Èqh\¶CÌR,‡¨r(†)ŒJ¦æ¾5IVc’wU^56=VS¯¡5ËäYÓ!šýr«>—å>ç¾<ªò¬ìeëk…z˜¥P¦éÄíØ +)‚ilúŒu’Oýy-ðÔPû0yڇËÃ>ÆËÝ+7{ªÛó4È>]í5êo_¤¾öŸpðí‚S$œlþ7êSO7=Ï¡~°z&ûj¡Í"Èá9ÍFf3ûÍAŸñ(hú ÐŽ¬©ŸÜšÝ4 ÙK}ši~ši<š¹ü[¸dZ8ÐZØL-P kyÚág¼Ãຈ¡má ‹lêåyÖh‡*^/ƒ|ž3Xs"kžÄšCç£ß ù7IÚ%Ï%m’ú®,µ1ϵÑx­¤ÑXE#²Š‹¶ ¯C­ ÕN0Û1Ò¾¶ðÿC¼ËÙÆPØö"p8iFë™jòÀz§ñ™Íš õÔ î‡5JÁèúcÂ{¹ä±J¸†¦—Ðj}? ùÜ@ã·?6áÇfüè¥ à’éäp뤰;YT'†:×ñ¿½p†÷®óþ¾çpòzµÄyŸbF¬cIá¬7x…ä·ZòZ+¹oúw ½^B«mø±x¼BP\ûžáwŒíÝF³z‚w>…{¼ïpbGsÖØ ©ÃŜCÄ9‚ô…°V¿Mè¿(¹¡×gš»áU8¿€ƒ@xu˜æüˆ»ôšÍõq?NÒxœäâ;ÉAÓEqu‹®ÀO¾/øš÷Nj[9——±W’â<‘×F¡ëË^”òW]ZG€’¢Mg€_Á›p¯Þb x›˜œ%7ïÒ ŸÃó ,\~ÝÔgw-ÐîíÀ—»/“M·CO¿À½HªŒÄ9†‡¢;b?ùÿ%ú=š].­ßÀ;Àz‡¡ßÇpÁ9œ‰ÁAe€ôW•Kä/ðã +MÐÕ éõy"»±ˆÅujóúMžï©”5çàZåÁzƒÐõa»Ÿqi¾çÒûÈ¥ÁöÖgð7×`x®Àµža naÖ”»ÔÈw4Æ÷©ÑïÙ'?PŸü_‚×à\cÒ +žàázö§ â òa:̂¹`‡&h…6¦·5zÀ´õ=Ø}æ»o™­þÔx—$}£‹L™_éŽê6o÷pþ Û9oºÁ@èƒÁ ` DA +dcaª~P•º§:ì۱߄ýVì¶é_øñ“ß?™ÿÁ4zƒ"ºJ"¯¼Ë<}®ït K=|ÀYxËéC?çÜÛKWL|Y[0ëϚâÐ2¢cA£ûåدÂj¾ÀÏñãïøñ~|Ê´ù SèÙ¼™T?ÒQJæ zÒ9"ñ>–ßuqNÁ §ú?¾%wˆÅ—̺7‰Å5fÝ/”ŒN–þLN>V 1,Çv¶çb{%Ó¨ßáÇ;øñ[­¥|;Ñx…R>ÀêâçprWJU}ÑóÄs_ÖD¾ÂщÅ÷T½MNΨ@¿Æ7𣋼œÀãøñ:~ŏÃZ‰íu[±¿›Ê8¢}D|E¼› îBm'ô|î€í.85Égo‰ÿÁ¹ó-/Ö€Î(t"шÇZ:ös°_ˆíl—ñÙØ®Åæ|l6bs‰¶©ll¤2¶9=قÇlâÍdsŠ¡ç÷ýÛ®­öëè"GÙ'Ù#ûõ$:¡èD¡‘„Õ ìçb¿]P‚ýrìÏÆþ\l.`w,$ +ϓ‘µTÇV½À·W“UD²Ì® ª—£»âîr¼]æê9Ç÷Æ Ž]®€Ÿ;åA¬é1ôü°B†Ãñ9 ™(䲬h”°êr4*ѨÃf,ÖRþºÏãy ZDd²+ÉG#ºr‹ëæ"Çü›pvrÔ¾ÄÑ¿…+`³Üµ^Þè Gk4:‘èıŽT-“éT—iL\ç…ƒ±YÌn0Ë°/ÌÃ2,ÃÀ3,3˜±1ŒÙ ãÝÁ$¶Çv°c¥ëxKÒÊ­k7é’Vê´ª*«R¥¶R¤U~µ•ªV­¢.Q*µJ—Ûc;RۏîÌÝÎ{¿ûÝ÷;G:½šƒÒ r‚qéÌè+YâȦc¬n:ÃJÄFÜd)ò‹‘ï±°ùÌG}ÄüVu™ÿáWj폴ì~U¼®eï³Zr6Ôf_T=/ÄFð|Tg"S8½%›S[K8]ͱèŽlsrx[‡¶÷±²}ˆå˜½,ÅLr f…ØÄcŸe.vƒ™¸LÅÝg2î=&â> ÿ1ãñÆÿñ¾,Ðwvi9Tk¿¦í%ý?k‚5Õt2Y$Dq"nGâÓ9oæàŽr–j8à`!ÁE8ÑÃ\¢™ÄÓIãL&Í1‘´B(i±ä‹ìK¾ÎÞä{SHù9#©3œjü—õJ³–Cq'_vDœÕïSyʝªi%SKµ,'Çr %…pj6³iÅL§U1¹³ž‰­„Ò݌§÷2–±›ÑŒQöfL4-0`ØtžÝ™¯2˜y_æ» dþŒþ¬èË2žÐÿ˜LƒG²_d}>'.Èz¬i{Xû–dçU˜j™ÉŒf*3‘ýY&Æwå³/»œÑìöä4Ìi'ÛÃp®¡Ü ƒyûñç-0w”þ¼sôš_Ácþ=æoÑmþ)]ùƝoà6t=&Ïà»ezå²X✖ûãÚ.kߜ,ȔjÙ¯ZÆ͛ٗÏsü† J*¨fwa=þÂV|EnŠúè+¦·x Oñ=Å«t?‡»ä*%oÒ^òΒÓVòGa<ÁYü”we…ßй +ÖŪ˜×ÿIíW=£› Æf¸8–Ý%ÉøK³(-¤¿¬‚Þ²Z¼å<å.z*Öº•ýº"±tÇQޓDY‰Ò3%žRŠ=V +=xÚÉ÷z1{GÈõN’ã]a—÷92½ŸÁäýéÞï±ÓûkÒ=ŸÑc`ê~Ê5Ùî3ât¦ÅááRLrH»®[ú(þm $`H#Ï·‹\_!9¾ +²}uìÒàeù»1ùÉð³Ó¿Hšÿ4)þ«$ûï’è(~I¢ïï$ È=÷Ë5Š«ÒXë‚E±_Z#¢_t ½^ꓬ}ÒWt,RTÉŠ$k$S ‘Œ@:;¹¤ŠI T“h$9è")ØObp/ ÁyvO¼L\ðMb‚ß&&ð¾ø+±#r®ÃròCõ|Ç¥ûÄ ÐpÒ!Ò®‘¶Zjä”öBêØVCq$„’…‰øY”ª!6ÔBL¨‡í¡a¢CSl a‹‚Tdè¡o1þñ'"Çää÷lg¥qHL‰ Ý¢Õ§9(íJi+"åJ_±1uBp:’ع¢Ã D…SÙÎbs¸€ˆ°…Ma}Ôa½Ü°nËBywîšx f•kf?T#”ƒ›‘“œVJÙ­ïaH=AÛaÑ+\úß8¢9°JöI_ñÈ4)³ÒŸ‡ØÅMD”ùZ‘áY‘ÙXI׃(ORS_US[ÕǶª\µª[UÎ\=%®êø=«ð¶¢@vP5,O8"Y=ç¨Ô%]Ú6ë™mzæ²I0ÏH_º)K¯¸¸ý0l>.³wR¹ò¤ ×)ÕñŒŒÆZ†šL®-vëj°ëú¨Ö5ë!¡‹Ö/êøçÅC«pøÌ'ºV5œ4X–Ö„†,(zõÛ©g®›Ö Cþ¢ô¥›|Dú' z "ž•þ9ñü&5x¾óªãÅZpTÇ%Õñ’ü -vz'—5Ñ7ô` BïcㆎSç} óÿ&TÃyéiê0(:5Ö :½ò H×tRúëw¢ÎK÷’¸Âc£©ÿ)¯j<®)ß^×x¼¦÷rSïå–긭…÷ŽšßMìÛz°Û¼[¯ˆ¯è9ø›ªá5ƒYi…Gcݲª9 S OkþI7é‚Þýe½.•¹Ö5âÎӍB ²í2â‹“{2å÷ceˆù×eõyÆñ¯(”K–kÁ]XXXv]`9DPEEE-â}Ö3±ÑªÕ68ƨÑǚ&5UcըʹMššúG϶&iLšLâ9šl?“qòÇg~¿eÙçû}Ÿ÷yG¯ã£ YµÑÆ&×Fa·‘ÔVÒÊ[Oó?Ÿr‰§&û4ݑ ©CÊƹšäߢÑíÏû½Ô©Õ~á?­pÞÒª·à¼ 'ºK§ÈÉi.Äg¹¾Ëè]¼ól穋 Lè…hƒ¿óÝ·àS cÊüº)+¥·úC7`?ú¯vj¾ Çá$üÎur.Â{ðgxþ—hV.37Ÿ«¬•kz×ÙànPÜ7ÖI7ÉÅMº©›Ôæ;*ßD2f;y6ñUÄ+Ô6ýŽ¶«Só|§Î€}ý.¥¥ÂU¸„¤•’XzºM|;Ôé]jôsrŸEø€5ò‚zH]< ðƒ›t9} ô†¾Ð"Á vð@ Œ‚Z˜3a,ÒtSé|ÑÙ=¤»¯t—‚ùŽ‰û–ä}Mù•>¥Ó|¤Ûü¢«ð\„sOzÞîOúÞü BÁVȆB}¯24F£QG·Ö@ü™úÿÃǗøø‚û9 ç3ºÏÿЕþ‹b½Aá\ÕRu…”Ý!u>}³pŽ?ñ Ÿà^0zÝ£×½C.¾¡ÇüRCÐ('~nâã>®Ð_~¬fb/Ô%||ˆ÷µ¦î%Æù +Óx½¿âä6§Oïtò´Âk?ñÀÎÅøüS n)ŒqGŠ>¡ÇüH^òWBéÔŸðqçèsϨ‘سuŠîõÝçÛø8¦Mhl§”÷‘‰6´Îêu¢½F¡ô*üöÁÞ§<°k1N161´‚){:&Ê2lâÖQ|¼‰#ª&öxÆÇ!MgÄM:ˆäc¿Ö ñw’ƒÚÅ/wõEªcj/ÀvØÏwz¸×YΗ:—ÛIrq”\¡.+ vâ»Ù* +¨¸aڃÝøØIîÐ$bNgkbw%[éz\´h3n6i#‘7P›ë©ÍçP]ßIûû4ou.íw:·ö­h?¹ØK.viþðnEÃAü\âñG{4•XK¼IěNšõ¬–°RÖj5û*"¬ â/Èärfu)«f)ºOóUû’ïÊØáp—Ž-ql'¿eüZ!Œ#š1˜Ñ°¡‘ÉŒçi >Vác%>VåÌË2æe ëe‘摍šÏ¯æil¦JfSQM¬¤Ÿ£û4×9öαͷÂháóf¶þ xú%{ÆZ1žp"Æ¡“„ï4-¦6²o,P¥š« +4jИ€ÆTÍâmnq<ÌMe>¨¢Éì“ô_x ¾ù­ýÇÌËy-°÷5Å+8Þ{wÑÒn}W0z‘h%¨¹KŠšºdhVW—fvËWc·!šÞ½LÓºRƒß8Mñ›¬I~³Tßc¡&ôX«ºž[UÛs¯Æõ<¢1=/ª¦÷gªñ¤jßjàb(GÇˋlía5ï‹Ã¸öphÆßì?Íî Y½CÔè­iþf5ô±iJ_§&õÍU}ßM (Q]ÀH¨Ñ¸€‰8C5 T¸FU[U¸Wo¨<ð=ú¾ߏœ2pôFqˆæZ#-á9‡Ï3#¹þágjõҔŸ©>(B‚ŒlQmpºÆöË֘~Õô+Öè~eªê_¥ÊþãUÑšÊCæª,d¥†‡lÖ°ÝÚª!¡Tú¹ŠÃ~ï帧ýêÃq¿æÁ >Oáïõø©ÃËø𮪠И°U‡Ekt¸I£"©2¡‘9*P J4<²B¥‘cUÂåshäl–«Ðð+v*ßpX^Ã9y¢n)/ê1ON"Cm \e8æŸ3‘³Ô ¼OàoãðSƒ—Ñx©Šê£Ê¨~*ŽÔˆèx ±¨4&]Ãb³44Ö£!qÅ*Ž¡Â¸jÄÕ+ß8K^ãå×+ǸC.ã!eǟQVü¿áp;8„æ6Žøµ\E@#ÔÃØ$´ù®#ñRßS¥ñA*‰×ЄX4«h MlÊQ¾©P^S©òÌUÊ5×Émn”˼HY‰ëäLÜ.G"»\âi¥'ބ‡²›}OÈ0ùt½­É\{­ÔLå8žg5G~/ÃK)^†&vWQb€ +’B48)J^K‚<–åYìÊMv)'9_®äe§T(3¥VΔiÊH™¯ô”g”fÝ&›õ ¬ÖSJ±^ãù@ÖŸ%w°½Mè.³Ñï¥rdž±PÉç2(áûbü ¯µò¬ÁÊ4@n›Q.[’²l©ÊL͔3Õ#Gj±2R˕Nc’–Ö [Ú\YÓÖ(9íyYÒ(1í„ÌiWà¾S}JjÇæÓntÖsõ\œN-Ú©¨†r>—@ßåã)—§;½·²Òƒ”i“Ó£Œ “ìV¥gd(͑£TG¡9ÊduÔ(Ù9Yg³«drþF ÎýŠwþAFçÇ2:î)ÞáSBØ}ځγ´$óô:PË´†ó^ ùàæû,žgÙ3•–Õ_©YÙ²â5(Û¢”ìt%ggËâÊW’k˜Ì®*™\õJp5Éèf‡uoQŒûeE¹Ëຬ(×]Egûž“åS ±Wg²ђL†1P%P¹àÌæ¾é’RÝ]eÍé£äÜ`Yr#””+sžY¦<›æ9•àÉS¼gˆâ<ŠõÔ)Ú;Sï2Ez7+Âû;…y*ÔsIažïžçSDn[ÐXŽÆ,4&rý­‚áP ^pVÅæ‘,´oæÁ½4° Pñ!2W˜ ØÂdÅÚU薡¨P‘E#Q4NáE +-Z¢þEÿ'»Ìƒ¢>Ï8þdY–]p9d¡j F¼¸äÞEv À‚Ç®" «!ˆfRÏzD§1j5Œ6É$ñHӚ£‰1‰ZsØLµ5‡GÚ´4u¬Svœ´Ù~·íLúLJ=øíó}žç}Þ÷}ž­J,}Z¶Ò—e-=/kÉMيé\!iZP[O»ÑhÍgÀ€J(†<ÈE{,Ú#‹é»K¥!å‘ʨ4+ÝiSš3E©ÎL¥8³”ì#»+W]EJr¹dsÕËêZ W—,®ÍŠwýXf×Q™\gç¼.s%kÅ=~€FG!ç":õP eP“idzÑUFüè3ª8ª¤dwŒ’ ‹$ٌ4Y!J0FÈbŒW¼1Uñ5劫©‘©Æ§ØšvÅëe<¡HãyEgé¹ +_+ÊTtuP«ÐX\Â~ ÆZpA ŸóxÍA{ ÚÃ]è36:º~û°Ô0h.CM& l–XÑo‹–¶Óˆî`]~„»ñ£‡‹®‡5顸{ô Ù½ ¨‰]¿à¹k4NÁ>æ ébrK $ÏßéB]Ë)f:[`ììk¸i8`o¸g‰¤gÉÉ~rr€µ9H}¦;Â¥{„ÃïEv‘Ã$ðÐø9ÏP™,zé)YªJ\œBÌcÈóÐUì?t-ij=¬¹7¬³†çáø¼L0­cQÒqÖæ-öË)ü8Å¥|Šú<ÉBŸ$À$ïÄ!`=Þº!½ùÜÄ\DÌÙÄ|ÿf)x­»ÑR÷†æOàhXãux3<Òª_Â;ðœ L çY›ðãcöÊ'¬ÉE¸K÷e +é2A]ÁؕKpSåë9 Èõ(bΠljÏP!ݟÂ+aÍp:¬ñ+ø5œ ‡ÂÇpH¯>¶?ctÍ$Ý`]¾¤9¼ÉÅs‹Mx›B»à@w~DŽ ‘q`… +£a2”B5ÔÁXX¦±Q¾f“ÜeÂû…z‡¢¹E¡|©^&ª—õW½ÍTó¹þÂ_ð‹?ÃxNÂá™÷D„ýH„ x&@“Q³©G·Õ ¯ðãoLNיë®1É]e +ú?>Ǐ?±Y>c2ý”ºDÑ|„ÊoIÖ9Ýd¦ ê8Çá8ú>¨//w•@<)Ä3½Ñ̤‰£ûNìL® ú?>ďß0՝ãÐú?ÎâÇ{Ìwg˜RO³yNé9Êæ%¼x‡%½ªcdí5^…à ìÿ–œ\ä®ñ˜õ{%‡ƒ¼e¡3)Ø/&³.lØ®ÇöllÏÃn应Ìw±E¾ÏVوÆv¶Ï“:Äß^ž<@ÁìG!¤¹ž†½Ðöá¸.§óð®b(÷Ê?ÁhŒDcy›Ší2ìĶÛuDڄ]?Sm+Ù_Êqхò*ì?J&v±µ÷ñ÷%ªä}í Â(nóCØ +ÿDó:\êÓfk÷m÷tÌä*tìÓ3zßs¨¶Þ7ò]ÿ›/µøRk3É°Z嶥jºm°\‰ÃåL£Ê¤ïª"iªÊ’ŠUšäTÉÀZM8K…[T`ïTž}¦Øwj’ý9M´¿®ûEå$ßQnr°‰vÎJôˤþ“®ÙùÐ3i“ ¾¯Æ—éøR•-g²E)v•¥8Tš:LÅ©#5-u¼ŠÒ&©0­PùiåÊäєA^MÔ¬‰éíÊI_­ éە¾OãÒ_ÓØô ë¸ÅkÏ÷x +­G‡Ò‚ÒŠ.¢ œ õ`ð¹Šï+ñ­œÜ”9"Tâ0kš#Q…i*È¢¼Ìáú7Ûeõy†ñG (—‚A–uY`wÙ]`e…]•]6ˆ¬xâM0žxD£†â ‰Æh´ä›hÔ¦:±­©M“š4¦‰=Ò$ÅΤÓvÚI›ÔÛ´¶;³ýÿ^3æ7{ðß÷y¿÷{¿ã©Íwi¬©J>S¼¦ªMMª,˜)OÁ"•tÊ]Ð-§ù)•šËn~]6óÇp¢²Då€o ³ã}=׿%؃¹Ð +M|žÌ÷!ò©§.ãÀoNP­9M¾1#U3&_Õ«ª,UVÈSèSEᕆ嶶Êi] ‡u¥ìÖ.•Xw«ÈzH…ÖÈb=·x•µpgÐيælA»S¡‘Ï!®ƒãùŸŸ|Æòœ·(^UEÃUYœ©Šâ\•—ŒQY‰Mî’29m^•ÚÆÉa›,›-¢û<ٗ«Ð¾Yû.™íe²¿ª|û9¸)“-ª0—pv Óæ*½ˆ-˜M0 &ð]Ôðÿ*¨pĪ̑,Wiºœ¥Ù*-5Éî,’ÍéT‰³RÅ®:¹&ªÐ5UW›Ìî¥2¹7j´{§òÜ/h”û¤²Ý*Ûu]9®¨rƒìFc3×Îe.æKFB€ï|P eàä;GY¢låi*.ÏRQyž¬VØe©(—ÙãS§^&O“F{f)×Ó¡Q•”]ù¸FV>¯LÏ+áy®ñ>ª¬Š¨F–GµƒØˆ½¤¯ÍÔÆ󾪡©„«©µ*^–ꙫ3Tà͑É[ |o±F׸”[S­Q5ã”SÓ¨û|3”åkW¦o2|ەîÛ¯4ß ¯ù\UZ ·FoTéÕQ=Füµh.&þ ¸Bà‡ð€³ +}/Þ«P06F£k“”[—¦–²ýyºÏoÑH¿CY2uÊLRz`šÒ •X£ámJ<«¤Àq%Î(ÑYIþ{J®‹*¥6ª-h¬¬–棁˜µPe`GÛZ‹>Ö-oþcB¼2ƒ)Êf(=˜ &¥…Š•rkxȧ”PPÉ¡f%…æ*!´BCC݊íS\ð¨b‚o+6ø¸«¸znŽ¢ÚŒ5]ŠÆ®ÞÍ0Pp¢]Œ¶›’W>ÖmĤX¥6&*%œªäp¦’¹J[4,ìÐÐp¥¾(.ܨ˜0/¼6Þ&|„fÃ,4b¹96Dx¨Ž5‰ÆŒ@=ïë Ü|¶¡mA{ôDô'£–R›b”45AC[Rá@‰pÀDØT#EƒMaP’†Ÿ˜†¯‰<¨Æ0‚·iáÖÔBS£¬Bcþþ“a<Ÿ}PÁ{{˜$å7 eÌhÆ6©uˆâgrјÅÁ?›v6ʜœÁM¾¥ncÒښ  0“mÛx¯9c8ûü™ßGXÂøfØHê¨â½“1[sþ)»ýVô)mâ)nœql( Ò".‹É£=‹ƒžÃ¥ƒM¾ƒÅÞÁ$w¨c:<_åÿO&µý¿¹ä°(ª…è´Ó§ ãõñê&ý⩒iúXÕ tSæKÃ(kÌèRˆpÀp [Áeg%yt2'«9d×r¸¬cNÖõ/8&s-Å[»Ö³ïŒäjÌi'7ùUÑÚÐjá±ÆëçÕC­m¤^0}ƛŽnr‡¿ ]¬"W4yØÃ&걙zt‘G7õØB=ôÆV6à­,ê­Ô¢‡öðãží\¹1oÁÀvÁaM]QÍD¯™:×óêåÑR¦o ig3Þtt“:¥Ø~͍Ð[`+<„äªÆ(fð"ú$ý±‡<ö‘G/r/~/ «—~½°—[óÞ׸¸q›Þ}p±Ô¹ÝZjí^LRçZ(ÝD–TL¿æ£†ˋkòàś©åò?x§Õ0ÒAjrˆ¹ùfªô-ò8FcNŽÑÜGgñÝZ.Ïxé;\ qS‡Y‡¸S¢;žZ{–Ó«¥\ê›ÞÍøûÇù„¡Ù¯·¿_XâbS«ã@H Ø Ax^ç‚þ—ÑÓäqš÷4Ý[4ُz“õq +qê]øüC“˜&é9³©‡õÏx“Ðò¬1¶~Íc†ÎIÝ2è7e§á8c•~³ö!|D¿^ K¬ÙKŒ—Xð}4YÔ×+]$ØÅ>¸£À#œI̯e'{5N¡®±‡1¾bh¾ofì=Cc@~ áW†ad 0®ŸÁÉã*órÞ¸ÎžqƒMæ&µ¸ÉäÞ:$Ýfϼýɀç$`8dA>Ø ÆA´Îd,Á-­Ô=œÏßqBÃÝÅ~‰#¼M“ÜÀµ]Å[}®wuŸùO|ʯ~gá ¼ ¯Árøýy¤AXÀ…–zýEaÝÁ±Ü «äñNí +në2.ïSÎïY4¿£y­½”åy] ˜çõC4ÏëÝbš¢ú9¼ehŸ€ãÿ'‡{øÌ»Ja,#tZ\S ZŒ£–ø!}‚ŸêÃ5}Lá°Îâº>ÀU¾ÇÆñ3òø õxG;h“^Úåms·{†V½¬ï3šï¡ò]8 +‡áÀåÀJe|âIé·†NSÆ4hTÉO[„ˆ}?±#ĞIìy´êbZg)±Wã*7êeõÐÆ»ôïj‡¨ÅAªr€™zÁÐ}ž†}FwûÛúŒ–ㄧ ShÇäžGîV4\Ô­šØ~b‡ˆ&öTbÏ n•_Äò}Ø«õ ýÑ«mÄŠ¿ÚM-vé§,õϵÅ'`| …/>g,³“Æ’8B-^T*ñG²™ˆ_L|7¹{Ù¢üÄ»‘m«™˜Ó‰9‡˜‹Ø:—w [i³ò¸ºÉ¨‹ åFµ™™Ü¤¿ò`< WÐ;k,÷—áExö²NžT2yg?‡øfâۈ_F¥½tŸŸøAâ7 +ñZ™…9#‹9N–³Z֓I:Y'«¨Ö +ª¹\ïÓ9×yþåÔØv÷Û2»È?œø™ÄÏ#¾…Èâ—ßKÕýIJBÐh&þtª0—Uûjg´‹ÁBF5ŸÎ׏éžËp¢ÿ¦Ûù6ÇðþX¶f¶ûŽŸÍƱ¸–ZtR‹•ú'ÓeÛæ]Æñoâæ¶;v.çpì8qœÄNlçpšØ9쎛&MÓôN¶v-m³vëJWšrT+[§v êh5­´¬[‘@ÝQZXA\š¦1& + þà‚ +!:Ì'©‘øã£×ïë÷ý}Ÿßù<_+ñ–£Qˌ7 ÑŠFQ4âìÔ$íMÁ,«cŽ]³O›‰x½™aö¦YEVWòÏá^e¾Nº{‰Ô{®ˆ´JÚ;ÂõQÒÎ>žï!®ÝÊctMèØè‡:^FݏNÅtúÑf6R´;ÍI¶ha†Ó:fmœÑM²‚ÇØE£¬¼QÝÓÚ£^C÷"Çú)RîQX€Ý¯s<ÛÎÛ +²µuM!}*F«jTêÑò¡ÓÆ tj"«Wë²5ž=¦dö¤Æ²7kÄ𰆠7,jÈpV†Ëê7ÜPÌðE×,+šs_ÑÜ´bð%4—J˜{JÂCvJ.ØÁïYžm\)W‰eʘ£©£&ó¬šÈ+W*ß©d~ƒÆ +Z4ZÔHAD‰Â˜â…Ã*œÐ@#S4¯hтúŠŽk­ñŒ"ÆËê6ÞP§ñø“:MAZ]Æ´® wšRðIJãýôfaŠû žó’X’æ<™Ì1ٔ097»4dnҀ9 ~s§bÅ}ŠÇÕkIi­eF˜º, ê°WÈrFAËeµY¾*¿å]ù­²´YÒzÿéõðJ9ZMÙ `÷£<ñĉeȖ­Á’" X-Š•”«¯¤V½¶­µµ(b ©ÛÖ£.û€:ìc +Û7(hß¡öÒ} +”Ské³j.½¤¦Ò7ä-}G¥Ë\Óܓá<:ŸBó %àC¤ØYXcÜÇ)Oø/Æ;Qbé-ÏSO™Y‘r»ºÊ«ÔYáV¸¢I¡Š6+»Ô^U rD~ǤZ[ÕìØ«&ÇÇÕèxFNjr;^—Ëñ¶êäúîɊpãhî§ìÚáƒÀ8$¸ï‡¾:jâ‰0.ÕkÔQmR¨ºDí5j«q*PÓ m«ZjÃj®í•Ï—×9¡FçfyœÈí|BuÎÏÊé|A5ÎWUå| þqO…PËٍÆQ4÷` ¶z°=”^£0Èï>žE “ÿü×^—¥€«P­.‹Z\¥jvW«É]/¯Û§Æúv5ÔGT_?(·g\.Ï&9=«Æó¸ªÃA6Á2Þ¡3|43 »#7ó96ÕÚ4Uëô_ø.½Ê4&ab1æðÛ¸zésV•£W6t‹Ñ-š”ri’bAÚL±³…"c+Ƕ•DObÛIò™cNæ9TæYPs46LJs;á0ÿc`w^ã@Æn¿ËwéUf 5…Vœ1!®¾aÉ5&9°f6¦ÔŒná&<àV´·Ã<»ˆcw.‡,㱗8öÇî‡ÿ‡Éº@c ³Ëلnîތæc+Zð$_-xI¸ð™L|Š1y†¹y–uz–8–ˆc‰}²Äæ:Ç`?G£giäÌs®×yïǼÿOéé´&èï ºôÙ·=0Ïþۃ>º9g4Od´NÁi8“)À—à<|.[O—“+Äq•8®‘ô¯±O^a¿ÌX\¥á«üÅ«¼ÃšøÎîRZ#Œu}öÓgã\Æøš¢"Ó¿Ó½ç3Æã0¥”¨+FHØa¾˜“Wá øÅðMÖê›Äq›Ä›Ã÷MÝ7èä-:uqóïýSu_ýÌqp?ûaª`ûÓßÜә>^Èh^͐ëÿӎ; çsô͌Iû.¼•1ŒïÂÖêûœï³_Ê^ý “}‡þùC~wõÞ=u³e|Šš“’•­“>£ûrÆô½,!݆ïÀŠ!yûÿtVLâX1KÀ/áWð[ø–»ì•eÓ2c±Ì¦Z^äً@'î~°êyyð_¦Ë=¶Í« ãOÒ8Çv?;NDZãØñ%‰Än;7çžzI›¤m’vݺ6[E‹Öª]ÛÑ ½±B«ªÒ(° Ê À*•kÇT.ÓØT`ã@“Æ`—¢mŒ–2¶™ŸsQôS>þü¼ïwÎ{Îy+8À!h…n† Xëõ‹ó_8žwp@7)Ö8£¿ã2ßÂ}¾ÁÄ]cÂ^eàþ̽¤?èøÌ«üò +<߅oÃ7á9ü‡â|N¨ƒFb-C¡OoãcÞÀ¹\#Wp9/ã|^Âu½È¹Š|Ž<~K¿¡hM‘^Ñ#8Ìï0lO1|ÕeÔ.åc¾_ú¿ރwà&¼©2â؉ãÖ_ð3/ã©^P'ú=‹Cú%îéiœÎ/pZOà¾~†»Œ|œÍâ1òø!Åü} +ù"“zARBéLÎy½»û,|>ŸÎçðOø°séyxŸù4cñ$cñsyy‡0åÖÊ;¤ÐîG{í ´W¡=‡öíhϳ<¶â*wònûY6e6N“ÅY–ìâ]adÞZˆyNÀÇá8°Kð΋eôT¾¼/·df©¼… }?åedÛÐNëaÆãóA{í)tgÙ"Ö£=¯Säq’y9Á¦ò ¢Ü¯3ú +Ç¥èOÌTnƒðaدïwð“ü’ûj~ùŸ‘ m+ÕåÐ'ñº§`¹6¡@;vía´³hO²…Íè0y$ÌË>íf{;¢{ùÕn2¿‡ÅµSÏ°ÝހÜÛa<—_֜êúB~Ëc7EÿE]ÁëÆëÂëTúÍÚK÷2/{¨Ó]B?‹æJŽ5h®g¥ÜIÛ8Zö±rŽs̜áÎy²û)«éuþçþË&x"¿<”ߏ参½ ǃ‰Ü-hÛQtýú1ôè§Ðï£"‡ˆ‘Eo’•2K•n B>@6»X=Gµ–‘œ£Rf©Öf}†•6CìÙ<ßËo»'óGÛôÂqÈ։JúeäkC¿}7ǶŸaŽð1’¬Œ1úˆ1ŒÞ-ŒÄ4+fÕ:O¥l#«¬¢¨à‡©ž <ñ+xr ŒÃù¶dŽ™û8òö”rD–.¶w-¶ +·2k‹9ês†9YÃÞµšÚXEN³f'Ù;VR+¨ ÖË8WYž\N¦cÔço5ÌÌRÁTù#ß¯× Çõ"g‰ùÛé~Žþm0ëa–{«i ¦Égª°”XVÔÄqÇÇ;‰ÓHœV"·«›ä/‹î4­gt6«—ù覲º¨ð4«+ÅúèdgëdGè$~ +>K¼c´@» ZûbK¶†ëIç~–ï—›—hy‰Y£E6Vh¨°Fƒ…~ , )³¤Y}E õ¥ÔS”Q·iT]¦I¥LkÕiºSíÅ;•,>ªDñƒj+>§VÓ%µ˜®ª¥øºâ%9µÀib"î6Ž·NÞ&!Ëç½ßË€µXf‹2e†z˪Ôc®U—9 ´9ªTy‹:Ë;ÔQÞ£eåÃJZV¨Í2§V˼â–j¶Q“åAE-ç±\RÈrU!ëu…­9Eàqös íèmo«hnáÿ0ôÓ*÷ò]7ÏtÙ Ôµ´Ti›U)›C¶jµÛꔴ…”XSÛÒ¤ZnÅiþcƄšŒYEy…j0Ž*h|JõÆ×TgüX>ãEùìÿà:'?'Ænâ݅=XKÛ³’ö|”ÿÐý49u_;Ï-s)é(WÂa¨ÕQ©¸£V±Š€š+ÕTѦhEJg¿Âάœkpn”¿r»ê*Ë[yZžÊsrW^Ruå pSngN5pñwoc-u@[>CÐ )¶V­äÓB.1W©š«ljtU(êr+RíW¨:¬†ê¸‚Õí +¸ûäÇøÜ«äuo§æn¹kÊUsJ•5_–Óý#9ÜÏ«Â}ƒëœ*«s:„þÝÄ»v|ÚOýA?tñ¹´bq¾o&ŸFò‰xL +y,j¨µ+P[¥úZ¯üÞ ê¼Mòy“ªõuËã‘Û7)—ï6Uù>(gÝ9|'e÷="Ã÷Ù|¿×Rßuޜìpý-ĺ•V|e€:„^è„$÷Z ‰œ"ÐÀs¡ü~³|õKå­wª¶¾Fž@½Üˆª­rÒª Êd%×ÉÜ"#¸O¶à Yƒ_”%xQåÁgTxS–J}NBw3ñæhù&hÅ¡Ú¡•{Í…ðƒ—ûžP‰Üa«\a»ªÂ.UF|rFBªˆÄäˆtÈí——-:'kt³,Ñ=2GïWYô!•D.ȹ¢âÈ5•„ßWi8§{ˆ¿ Ý5سl„y€× ˆCcˆ~àå;7­zUS‘œÍårÄ ÙcN1d‹5ÊOÊïQy|Læøj•Æ7©8¾SEñc*ŒÓüÇhŠct ±×UÐü® +›9?Ñހöڣس^è€V>7C„ï‚Pǵ§Irag+Z +e´•Ê–°ÊšpȒp©œÂ1“xi²E%ɔL˜Æ%ÉI$1ILY’Ó(‰ IpB'žÄP½ø¬¶œ¶oÚ+h{Ñï‚$×qhä~ü\×r߅uc ÊHÊÖ^"sÊ¢’”!SÊ©%) +S jŠ¤ñVé `Óø«ôVà4NaRRRlœÖäÐIّÓ]hÏ Å†d “ë6hŽ3/÷«ø/¤LH/ÝS/9ôätï5þH’ÐÎu ÷‘i࿏{îvâw¿ Ø#™±±¦ÛA<ÌÊ0úˆsqsc,Ƹ1’|Írl7ßãmF1f#—ùÍ+ð>¿Ïiú<>]äsœ÷ óßÏçš4ñy%ƒ¸Ö©lH*åP_ŽŸËràsÀN0+8t&ÙܧØH¦(²)^bª˜)<Þäv ;[‰i[A×:A=Aã8Þm9d E¼–¬êùìA¢²Ÿøĵ·$+"ùo¦Ë<8ÊúŒãߐ;ÙݼÙl’Ýdw³»Ù쒓¡!¹ SAn +Š Gñ@e" +ÅJG‡CÀ)ãØ)R¨ÖZ§ÌСPflÇik©RA Te¬jÙ~ÞìÛNÿøξ×>ßç÷¿ßóe`À.˜ÉÑ†³ñ£?:ñ£›œô˜…ÖMðº'òх˜í¢.;qÄö+ü\̎©•õ ð 'Îü†)'/aÌåï¼™S‰}«É 0ÇPc7ñ!gÎ †Œyø±?QK9d–’“%Ö .ÁéÅó5±ˆ‰u!Óóüù}ñ0ókl‚¯žõVë’ÐO)å²^ތ6)±®“`Š{`©5ô=Â0¶‚úXI}¬ÆuæaÌÆÞK}ö’Ðu\‹ÓkWr@nãzcÕy¾GY<ÓD^%ÎÃù-ćiô ë5àM‡7áa‹ó»&X90ìÆOsðÝ6‚§Á&jä³>괟d+ÁV곟Xl!y}K؟“6Sϟ’žû’!ˆs=¼U|R<‹¤¹ð/²Öhr®뭁H(!0° XBŒÎqaðCð*5²?Ò+8pÐlûIì>’··—÷|ôê ¾ýLÚ}_cˆuM;9`ͅÄ9›ø¦¯°x7Zœ}—Éóò€ÂØk å-Ǹ(dD\,£FNàÇÛø?#'')ò3qË¥·ú¥£|xäßþCul¥åó©b³Šú3×»ÉZ§¹>¶W„]œËäyÃD&ÏQp°$½ ÞU\0±!V¥sÔÈ%êãµq‘ú¼@ÒϓÜsÏ ,QTg~)¾®!Ä»î<òjgÍ Û¬˜š¢çÅÉ13 BMž÷[ ’IéŒÉ>—ÀïÁÁeðWð9ñ¸IÏÞàнÁFsÆºFA}ÉpåC&ký’@&0@>‚r0Œ€Öuô-ys%ô ÊñkTåm’÷År‹Þ YWIδÕeý·þ‰{1܏é-S׀Cà¿üìXØ5‘ȵéG6(пјwUÇH}‰røúá:~\e£ø”†½ŒúúúMó! s?ΣiÎjéØOZŽÀ{šðÝ$U1Ò#¥1J ]v[>Ü_ƒ¯Àmpmu }÷)ºêôÌ'hªÐ—Q*çðã ñ8Ífy +Õõ>ºî=à»è™wðã$ñø) tŒ¦9Ïa|ƒ$ÆÓ×љ¯Y¼;Á6ÐîÂù¸f¥ð‚•â_)ûÙú…ÜØb¿ Û5خǶ©Ú&b{¶gb»ƒÖxû µOË)¥5dâÚt;m´G/QÀß'*;ˆä÷àì›ÀÓà)p ¾¿Xåô¾Uæf{&‡ÐwѺИ¯¡íöP¯àÇnâñã.ÞN”ߏíÔÈVjd ~ôÍêEá=×Kxó:\?דDtœO€Õ`X >¶Êú¤ÕÞû¬-`‡ˆU±2°›K«ú@ ¶+°\£g©§Q”Q´¨‘õÔH/5²?ÖàÇãz ûOR­ýz”æ^Nô–é·l·ß°ÅǨ Ùc~g­¶;hµ$»ñíi=±è• »ÙlYnlá þWÀPƒí:l7`{¶'Ñ!­ØnÇî-àn_Ï%sˆÅƒtAz·›Šî†×D—…w¬mÀÜ_P|û¬ت°”Ž]>ç`ÛtdûØJÔa¿ûã°7‰#u:ÕÑIDæQ±R-4ƒ,M§GZYm‹þþbÿÛVì͵›Çy,™GÛöÀ1ÙC,ºˆE'9é 'ÔF;5:KQµáÇLü˜Ž­ä¥…¼L£>¦ðf2ž™‘™HôšÉà6øñl°ãôðˆqÇ~+þë9ò–3’Ì=\·ss”°†AØOǾûٚÊÞ5E^8BpDéÒJ8jà‰½ÑØnV_ÁÛÑD¬‘¬¢*ë©àïPé#©ü‘úĸc7|›8æV¦3‚püw1ŠÌäwGðä”øÈ6Q)pd‘Gnà‡§žRxªà©…§›M؟LdÚ4‚HÖR1èÍ:g(UWÍ^1DwAŒû˜¶Ã½ÞÆxÀ÷ÇK›#>6sßÄó1ø3:m“ÒԐ`‡Ë€)®¸𔰓—ÃU W\£ášˆýxÖC”–òö v—~¼ÝÇnwœè]·Al}¶øè³Ð`ÌãhiÍ`,÷ Y̹¼«ÃŸ™I‘–¡á)Õ&;U“”¯¡É^U'‡4$y°ªRªT™R«ò”•¥LPij«¢©ÝŠ¤.V8uŠS_T(u)GÁ9%ßRQÊ}¥²_Á±ιŒ_mŒ>“@êxVË»ü©ÎJPµ=Eՙ™’a¨2Ã¥ŠLÊ2‹TšY¢Á¶rEm5ŠØ궍W±­EA{—öÅòÛ×Ékߢû^yìÇ䶝U¾í¦òíßrÓF8–Á×ÃXÞÊ¸Ñ ÁHjF¡JޗãO™‘¨²¬4•:ììÈVđ§’,ŸÂYÅ*Î*UЪ"ÄÏ î3¦©Ðè’ÇX¢|£W¹F¿\Æ~9ãÊ6>çú>`ßÄþb¸:ɧ2ó0ہZ®«yVJñ)Ê7W‚JœI*vf*äÌRÐéRÀY N@¾œ¨¼9U*È!k¬ò]S”çêËµHN×Ze»^”áÚ+‡ë˜ì®³à¦9÷ALk°=¾YH¤IŒ;cÒQ5ÜW‚Rü‰ð> BøÈK?/M¾<» +ó*Èϗ'ß'·;¬ÀÈÙ¦A׃A˜çAà‡·à?L— p”å†ßÍewÉ^òg³¹’;¹ï†ìn² ¹,$„$Ð\ TÄ ‘’ +„‹­ãD¡8Vª^¬µ”BqÅ2¥…Z†N¥ö6¥#Œ2ÚÒ¢±í ØÙ>òÛq˜—Í;ïùÎ9ßùÎËo÷Òyn”'È[鐫Ú%gÀ+{ ]Il% +e VPÈ!ÀüdŽ"Z‚ˆ¤ º"ø8Œá<À<]ÕLpUq-Ãî@™Ô‰håܛ_!˜ +²¸öc> )ë $ÈUc—£Ö¥¤ &ÄSÜa +(ŒÁH w#Éâ)Â<a–s2…9¥C§>ÔÞq-ÁîüJò€íFP ª¸.ã~1¾äñ›Íµ¿~L{‘ ®MŽH²ëiô 4Ú©“ -JG l”¢šl+@È5¡¯¢c`œ÷*oð >40E70¥c»Û­ Ô +¹WŠ/üæpí¯¿ýdK©—,1!ÊÛÌa7“¥•fÞF3ÑÐbl¢‹ál m› ¨‰B&†xjG¸´ä›؄øÐ׶;@ˆ€ |øRÄo.×ð¦ÕÁ”<“å)Æá> ?:ðc‡m9é&'½4´^6O/±èÅáòÑ3˜Jº™ÎºŠs™Üº˜bçàCg\½Øo3@¾jÊi¿y\g6À¯^g›”8 9¶@/˜}øÑoúø1DNÑØQÄCÄb¨…wDì&¶A„ÛÀù†zè‹kN#á ¬³·Ëá-à:‹²Nc½nx_âüÊÄ`ƒ=°Ü'Ðd6–âÇ2üá!'#ÓFW°?–óâr&ÄeÔåR¦çá‹Rô‡;㚅›Í¬³žÔUÃ[Ìuv ~Öë&•v–À°6ÉIZFùPêŒIú`%XEnîE㮥>Öã‡yl¤>7’Ô ,f=FÖñâ5±–º\ý3KTÕh\íð5çéíÔ!©Ë%Î>Öë擤!sÖ`¹ÂⵆÎ1kø½ÏD°†ñ- ^[ñcœ½²æêsœX|ÃÛ0´•>ñÐÞCMlFY} ˆs¡ª$ÖùóéA ‘n–¸ÔZã¨5d›||ÎXÆ÷`«5ˆ?b ¤ß%bŒ—ž&&Ï°o_`¯¼Àa°ŸMö<~ãûÖH{xy7ÓôÎß1ÐßR”XûØÄ:ƒ8{¨WYëü†ÅIøÅˆþ%@‰#_&…ÑAð’%”Ž€WLႧðã$ûäuŠý8±x‚WXÄQ>8B>¬0uUJ É&Ö^¶pòKd˜ë|GÃ|Fw³UVÂ3¦]ö“ÚÎ6ÚKD“_PâŸLpo÷ƒûÀFpÕ*%“û„U~/N”£ ›)ڇ®ÚGNö¢ívSOáÇøñ8õñjïQôåvšø85òmjd+~Ɵ9 D¹®!žMǧš)‰ª±;Lr+ªj›OU¶,UÚòà*†«‚.V_½¦ÙZUbëR±mP…¶¥*°­Qží!ªy7^ÿœ'’q~ãú&÷À¹ˆ±§—£>š@¨å^gU ÂcS…;Y))*wzTæ0Tj÷«Äž£b{¡Š¥*tTàˆ(ßѬÏjž-Jõì”×sH÷OÁUð/×ZlÃÓÇ(ÜÁ¨Ñ " Tr¯ ”àOï¤%*ÏHV^ªSSSÝÊõÊIõ++5W™©ÅÊ0*å7BòMJ3:eòKå1VËml–ËxRSŒ—å4NËa\ŸÉ‘JßÆöbøæ1ǐ' ªA9÷J@!Ïóñ%7=A9¾$eùìÊô¥(Ãç•ßç“Ï—­´ôP&#}º¼éòøcrûçÉõ?¦Ë8Ê« +Ão6»Ù$›,›Ífw“ýI6›l~vIHBHè&@˜J$ +†$•AkJJÁJ¥´RZ•j¬Å¢¢ÌXµÕZdZQ¨µ t:0ÕVªv¤Ú–aèV;èúÜìçè0/ûåÛ½ç=÷œsÏ}o +|ŸÓ·Cy¾d÷}K¹¥Çe+½ ï{²y¹3°½¾ë‘À݌‹sÁlP⼫¾¯À—`™Mþ2»|eyýù*ñËðÈ(!ªUh+ت‚`—œÁ>9‚ò7ÊœRN-àF Æ¢®‚Œ6`|K‘ZiÐ +’ Ä—¢|A|ñlòrå :ä)wÊr©(4K®P© +ùQ~¸RÎpBŽp³ìáNÙˆö/B׏܆hD †Ñ²!|½ÊÆPNc%|½aÎ#hŽpøŒƒJF¥0ߕãK Å¼›bxLq㤸Sˆ÷Ôn~ǐÐÈ Ð€ (ÙúŒ†ª¥%„¯“‘¬Ôóç]%\a8 ”gïÝ|ïJHùlÓÞH“Oq¹4d›i ­X´‹6´5òÑÆàÚÆ|ՆžoexhE©´0WÌ!ÍøДÑ./Än{y೎¿«áŠÂY|<—ðÞ ¯ ³Îsc‚ZlØŏvüè0— ý:r’楉EšEéÀ0›¦&ÒÔåuÓüŽÙ¦ó0kþ@3¼ÆúŒúÓØnIžkñ%ÆòŸeð–ðÞ o!¼y˜Ìa|å²ÄHs©vãÇBüèÁÅæÂ!'KÍA#KY¸d>`˜]‚*YÌ ÕËՃr\tŽu¨úL-³1Gêšùl œkàŒ€ËKx_ o¼ö8I/9kAàè!Šh.\òËðcÀ•½øÉÉ <ÈFV²x%ùXÉP¹b“´œ³1ÀÀ¸ì4"sq}F (ßvxšØgœU œ¿½mìÞxm”7‚%ËÙg‰#rVZ‚Ç®5ÄdÂc?ÆÌ%DNÆ)¦q63†ã£äc= +qÅ´õ¼öyÖ¼# 3Á×6\/5ð†ø»”ð¹áÍï™Qÿã´øŒÐûˆ%úÆ,áiD e§ ÄÆ$~l¡6¶“[)°Íl&`“,Ø4Åoö!š˜$>öë2ꄯ•ýÖóMSÄÙÍ~†w9XeqrđìÿÇ&Áf°ÕâÛÁíàNjänüø µq/õ¹‡Xì¦6ï,ºƒéaç“Òôo¤©©“ý¦øºš=puV?ü&¾kÁ¨Åy“ÅG«C&gð–åÈ3Üd…¹L(9!éQjägöÔÆêóky?ۇÁG>-}‘žýà)éþwÕžk)Û +öì!Îù#–¸°„î6ko,c\ɊðÿòAü(øª²f¥ï‚Cà~åÌå²y†Cv„Í&¨‡ړäã{OKß¹¨Fê*Jˆ¼¤ªÐìy“W³Ï=烀%¢ÅÍ †çqe‡#3 pÜHáÇå†\“΀³äåjô<9y™¢{‰@Ÿ&°/|N:‰gT ·î"bcö|'àkÖìðuÐâ4Ãà•Jg-®_€-¾__ƒßƒ?×Á[àmÎËrr™³z‰‚{Ò¿î”þr€ßGQ +•-¦@¡t¥÷˜%þ®"}€vĮ̂N£|S tÏLF×8$P¬ï3\¥PßE¿¿M/3y^b}ƒ¹ê"Éú3ɹ #LV¿Ô9¬ž˜™ë2l+C +3l3ÃԑÁ–Ä)e­X›Å%üx?þÁ<ó>jø*Šù + +þ-tûëL4¯áÇ&¹ßqXÏsh^¦x_¢xOãNjøqJ»tR{õLÇ(Ž£ú™žÖßPõÊ&˽Üvƒ+p^¯Z!¤‹3ûNe–8ËqŽYæ ÚýÓÄóøñSâqŒ†u”Æñ êsÝašÅ(æCº™2ù”ž ˆ¿Mñ~“]äô +¥{mfß{ÌL¶ƒmà5øÎ:'“`6Í?š)³=Å|wˆœ|_APŎê±ÛL„籟.ìöÎL²ûi$_¦y=Bãz?"÷kŠ£zûÝDZ}‚§“p_!B%•‹}'ö]À Jà)ƒ§ž(<5ükÄn öçÅt”ª¤b£ä#BŅ9!:Nˆ®¢w‡àƒ­pÜç’ôCȎnÐæ€$ïê‘îµ|_ã´)nÏSÜV êœ"xfÁã…ÇOž*xØlâ¯yœâ…x·ŒH­%k7ñ«xüxœSþspdø;£I쯇o9r£·8+Ñ[@ +ԁ8ïc Ò•£h¡C‘ü|Eò\ +;Š¶{²ûTn‚¨‚ö¸ö¤üö6•Ù»ä³÷©4wXÞ܍*ɝ’ÇöyyrÃûgÁEðo²šÑØ/óè(Ë3Š?³döoæ›%3“™¬$$`BH@¢¤ˆ ‹€U°d“­ì(Q¡"‹¨EED +TP‘M(ˆÈ–º€- âZµ"¢‚"K¦¿wæ;=§žþÑþ4œs3_æýîsï»Ýgü}àêÂߖ6¥(M@ÏrAˆk&ÉЬõØ%êvJÄé^ ;’î KÈ— gœM@™ø ú³Z|ÎâuÍ9I<Ž9âv,—}“¸l‰+팸¬ O8:ê¬Câ_ ªmkÌ÷<bÔõ™$ìµJº×.!Í)AÍ-A&.~OHtOÈŸ§H¼ZsÑ´ÖâѪŭÝ$N­VÚ±i³%M["VϱxˆÙsRÌî„Ü¢Úx:À{u€>4ù ›gqéºYBzšt»ø}NÑ}.ѽñz½âõDóEÄ£gqé%âÔ+Ä¡·›~ƒ¤éÅ¢“NÔéy}d8/aÇKbñrgÀß¾*bNEˆ} +Aß3A ƒß"¿Mü~‡èºK¼º[4¿[<~MÜ¿¸éâ ÄÄÈ[°©¤[Š%ØVÌA²[ärÈNjð?‚„ôåý]༆–¤e˜y|Î1žG@(h’`À*þ€]ô€S¼@î Kœ!Mìé>±…ƒb GÅÎs˜Ì)4 N¼§_„(| §SCú¼ø,u%¤7á­$ú–Ñ’4øœÅ³ ¦–`‚6уvñ-dwºCœa§Ø¢±Ä¼bŠ1a1Äéñâ€æ1NS§aȤϋ„Õ8!5FÎ -EÏSw'Ã:À{Uû!Æ<€\>Çy¥–ô0¤§‰?Ý*> …­âŽ¤‰3Ã&¶˜C̙"Ù,ì\&57˜œK?‘GÓš× +´4J¹C96g! -dSCI23!Ýrmœ3™ò‹AÈæ{ŒZ"ÔŠ˜%ô¨I´ “¸cfqdZ$-Ë*æÒ<˜|6xcw!^"ª0›Ã…ù("ËqëÒkÖNåƤ”‚5Œ!96"Mç%¤3±¿ CÊs˜þo²¨#ƒ:ÂÔÁ2ÏÏÜüÖÁï¬È4ås¡4æ/¢Ž¦¦%žÔÁRLZšJk¢”¸M[³‰üŽf¥˜è +öESjh’ërٓ¼³‚\¾gRG¾Ðùì…×Íßì¼ÖB Ë%ÁxPÂEWjI],-™“VÌI^T0‰ ªàG š¿‘FZќ^IRkA#VNŠ,c.š'äZ–Ï• À‘Wœ:ÂÀÏg/Ï\ðÚhÕÌL1—$ã’iêRU—kkuÑRG[ê¨bNÚ±ÙÚáE«ÊAΚh˺¼†ýنäTI‚n}RÉ»Ë@S´å3$Î(õøìå¹ Þ4Å[f\âÈ"˜À h /\4 š¹éD×SGwêèΆê†݊¹+yލC€F¶3‰­gDõv6gTû„T” Ÿa[>uÄá Áë…ׯµ¥¡µÒ4UFÀéh„®Fèºô4¥B@?ÖhöI| búaX_ôá¬êMbêõˆHŒù†Ð”–ð”°tŠ¨%Þ0>ëøìB¯¥ÒSí Î. ›¶z$Ãf*|Õ¨j@8‚:F³FÇ0'£YP£yùHŒ`ÐpΪ¡¬‰Á4°·ÐM LH9:K˜²Fðf°ý­áççæöÉ ™âT{|´«„j¡…HÀÛÀh#OSÀ4puÌdÎd¯ÞÃäÎàåÓq'óqém*i~R½Èø³RŽÞBæ7“ù ೛%lîjۛ ÎZƒo¤ÁÅ£‰Iq©@>CRMÉ}’jPØ~D&š%êx’µ±˜õù8þ(“ššD˜ç¬šÇ|Ì9*Ŭ«Üvœ‡h֘Ws/ƒw°¡QqN2ø×, ‚ðàAI5F¼Ž¨(´SBƒ)RV‰$›—M„ÂÍì׍l²ux±’Uˆy–—¬d.ß/ù¬«(ǘn+Çí‘Д¥<npÎ5øK:ٔ­+Ás’jU³†¬dÓ¨š·Ý’jb€Ù+ï1'Xøo#øMˆöðò½c[ò:ñóÈ>ÌЬBî݆Ö’j>—Ú׍l[ ® Þà{Tœà3ð8؂rš99Åú<Áäc¢Bv‚OUñÿùÏd±¦ÙN—[óúü`(‰Æâ™Y9¹y +6izEq³Òæe-Z^YqÕÕ­Õ暶UíÚ_WݱS—ë»v¿á×7öèÙ«wŸ¾ýú8¨vð­C† 1rÔè1¿7~¤ÉSn¿cÚo§ß5ãž{gκoöýs~?ïù.xè‘?.|ôñEO<¹ä©¥Ë–¯xzå3Ï®Zýü k^Z»~ÃƗ7ÿyËÖm¯nß±s×îú¿¼þÆ[{÷ýõoû¼óî{‡>øð£Oþþégÿøâ𑯎~ýí±ãß}òÔéϜ=ÿϟ.\Jü¯ÿôÿÂõ›ÌJ±]Iö YW¢ÓQ¡dg+Ýù/RÊK”ôr´·Râ+•úk‘ßAéïŒݔ7) nƃeÂ-ʅ¡Øp›òa¬2b"NLUV܉w+3~§Ü˜‹P~<¬ y G+Kþ¤<©Ã”ç”+/bË:åË&eÌ+8óš²fòæMÌy[¹sPÙó>þ|¬ ú‡¾T}£<:I?(—Î)›.^JŒ>¹\Í»%À~¾þË÷_¸_b2™Í‹lv»ÃáÄ·Ç£a…O×ý¸ áG8‚#1<Á\Á|ÁåLҚ”7?3'é Öt뮶;©fÀ Ú[‡¿mÔØq&O6}ƽ³fϝ7Áà [´xÉÒe+êØ.j·¬[È¤ÆŸILiLŠT*‘‰N„¢©hýòj~Þo¡ø»'¾Gô©~8î3gϞ;wí?]¸pñâ¥ý‰ºÆ¶ÄÓeÞÄÊÊhbm‡üÄÖ®-;zW_Ú5¨æÔîaãï3ûЖñ‹ö®›¼j×꩛¶­œ¶sÓ²»ÞZ»dæÁÕOÌý¸î±…G. 54ÔÐPCC 54ÔÐPCC ÿw +ž¡†u%^¡†]½ª/Ô¬9ùúÐ _ԏºÿ½×Æ-~kóÄçw®¼eë ·ïÞðܝûV¯¸ûåOÝ÷Ñ¢'æ~¹HÖPG ÏVFë©áÕ®å‰=½ªÏ¿1 ÿ‰}C&|±wäœwëÇ>ùÆöñ/n{y■/MÙµzÕo.¯›¾Ѳ{ß_°dî'—‹×°Š6RÃk]Ë/¾Þ³ú̾þýïÿ{t–tžp|g¦™v§zf¦šfgÚi;f§ûiçéØîÌNÔìд2/AñoF)TLP.Áðå EÅ["-¯µ´ÌÌ)'-û߶gÞ/¼õÅ÷ýçy¾Þ˜áŽ€¤N"_£ +)“U£k„aê"a¸>WÑ~›ՓĢ™¬ ð?J!ƒìÔ& vøeÞàzz¶ÓÃcòÁ-Ì£>ÿ$CkS®F–ŠkCe\ ¦)Æj3Jñ-)|’‘ʉ鱶d(;¼ÔØnZÔÚÿs®ÝõôË>w'C71}f¿DmäßäÄX4 >J´6 ÝüÙ3ÃæO;F·.×Ìþ^²h»ƒÎÊÎÜWã}®FÍ]ÇÏ…Þ +{óEÍü‘¯"‚f(/cƒ`Ó4„µ½Ñ¬ÿ¤çñ7Ÿh¦^!}wø>8¾5œÞKÇhàʙHàí€AΡ Ô5à.-F\ |é{Gq÷{ëá»ïim=Æ/ÿ¤Zý©táçUpàûpdK*8¹+Øï#€K‡ÑÀëD0€Ÿ +¨3þ{ÎàÏû’7ˆ²÷1ö7ÕÁÚ@ÁæÏAþî•àÞÁoàäPa·È.57œd0ß~DˆK2qH9íyžþµBCO¬mHLUÖÅ1tՔlƒ„Ì2Š"8–¶dX2,– K†%Ãÿe(€ %6@d¨u= +äםçëüý¦j„áò°”^A³µ€\¢ËŽ‘*´†ºÔ$,!­µ2.«KÃêãGv[ÚÃ=ÈÀú×ZP +$Aê=]æüüž+‚#†¤zwþ^ ‡X¦aFÕ*²b«ÓZ*SR»D ™&^\¾™Ëîµ4Àúh`C¡Í@v~'¨¿x¨<\æÕ¾þÏÕAÄGµ¡i]8¶^@(W±IŠÚ<Ê}IÕXžAï-ed›YÍÜDV¿¥ýa(„ e¡úü „ —·Zÿg:8éQCHz§,¬¨I^ÕÀPÕQš%ìx£Iï-ÊÊ0ç2˜™¿˜,탡2Ad¨ j—£‹ºk.sú[°g-‘ƒH†Qæê$Xi}y„J&¤èE|š‘ËNîe2æÌæ@ZFÉÒû£ÊOü ÔA†F—# zw—×/؄9Ќ¸Ýވâ©ë0RYe¸J($é9J;“CëÉ`ÑMô‚œ‡ÉÌ“¥}0° ïÀPäç·/69ùÝàæòªã&ìIÙl„ßÑ됼:y¨¤¬*LYT~?W@l»Í¥t%Æ÷SYŒÔBf¿¥ýaàC†*ÈPnû;½Ó‘×íW_ôހ™}ÈÝ]·ÕMÁœ*ª‚'Å(˜b¬öN)¾%…O2Æqbzȅ)}¤¢Ì^K…›þgX $'Öå¹mo N‡_u_qžð„ y“[»r=¢PØ"fU‡ÖdV†©è¢p­„Ø=!ð:qÜ´.Kû``ïZJ ƒìøú÷šsÛ^·9zñà²Óøè5ÓÈ-’®–&i *ઑ¥9u(Iº#O¬À©bDQHnƖP èâ”VKE¡2÷jÿðVwnëËÎ '†\G&ÜüÚǼˆõý°Ô²Ö ¼m0ÿNJœ\‹–ÆÉ°u‘Uø†ðŠH Z« %4Yà@†"È Þÿ5PÿëoÍgÿ1iºp`䉳ãÀôߦq/‚ÄìŸÄí€gÝÕ³é(M‰Eɱ•„Z¼,¬šT"V $´KÜMË2TíÿjA}ü»)ãÙÍÏö™ž9;g/û(žÞĖ>ò£æ÷ÀÓíȜ„f+Z‡á5Øb¬Š m ‰ŠèÊ@9µÊÒ2v~ jö­š½lí˜é̆¾q»ý†'GíÜ%¯Šç7BÙ#~ä̇ð„äސ´Øt&© ›nÀ磛#XÈûäB¸.† ÓÒx–—ю?¿Sî]1a<úuÿ°í†–)»ýÊß/ØW/¸zòfnÀïNøcSG‚Èqƒ(j¤9, ߏO ë%¦¡ºÉŒàÎèŒÀj–¿1!ÛÒ@ÉÆπtû/õ¿,7î]iøûuÕ䁇a\ŎUÇq\¦3:Z§¶:.gÆ +8g܁: +ElA–,DBHHB@¾„- @„%1, { „E¬¥Š" +ZDÐÖÿ|§íñ>^õ‹çþwõžó>±ýL³pæP8:HÁå"ÿ•—Oêl@Hü4†@D E> E…ߧÐñ÷h Ìx 3ø{ =–p—Ã~ß@¾ÃbI»ËbüÆΆ)Ëõšy›µ`o%†³6…àâ”öÖË5~)ð +}çOztõGr(î ‹yÊÀ‡ÌĆ¡ŸÄ_ x ÷{œL|ß@¹mÅTÿæåÆÉí+5s7*àÄNØȁ3GRà¼]xž£څøçŠÿ)Üó†|9x‰æ…^d\ \dyû¿bûø.pP¨…dß÷m®ký²Ûk—µÎm_¥ËÍ"8²ƒ'÷qÀÁ*œáò)Úc{&ÂÏB¤£?P|ñ5 +b} þüà¸\¤÷ÎhX½L3ùÇå5ðéj1|¹‰‡¶%À±/h`·?œbàÒ!4øöƒÐ£( ÷†ˆ^@9é ´S—aã±6îÀ¶½‰ïäïørö¯²Õ%'¶‚ä«ÝPíb 5—íAà¶(Å=‘)|FÌøìëIÉS|F¹!†'ÓÑòÝAcI¤n#V¶´ê4j¼Bkn    ¿{C.bÈE ¥ˆ¡ÒaԞ·…‡=Ôú»½’aƒg*"©÷tî­VîP*GhHL­ÒÅf)º¢sUíQ…ÍšH¡¶%¢²£‘PÝYµ¦ÝÜ~5ì[y‡6‚èøV!†zgkhpw€¿K +Lèy}\DMå3 û3Ù]WÑŸ¦ÖÆdkšijJ©®‘$ÕË#d=U$y—¹AÁŽ•‡ +¬7BÙñ-P¿¶Õ%P¡Ü_6†`ׅ3Æ$äô‘âè}N¬¬+5A¥ILÖ6±2ºUŒîóê`ì#%yWFÊSE½ E[V\Ks2§[•˜nh`çÔ±ÅCbšx¨˜.Õ è•½æ|Џ +Cű- °ÿÔNÖÐâæðVãí>ߊÆ=jÂÇÞVy& ¥¼»˜Þ Ée¶©³¹=™†š”Àή0šÛ¯†½k@ˆäGÿ +*ÄÐîh¹Ô÷ý\¿‡ÇÌ°O؃ì^LA›– m¸Ù(UÐ4Å2fw®„­O'p…¼¡xaé0³°|€YPa47(üt%ðƒ1Ô µÝΟ;Ï\0^°›vwŸºívgԟÝg ÉoBþ®¼™Ø l ´æÕÐ;Óe¬^Ž”cdUd˜¢Ë éâò~šPb07(úÍPf¹G?»Ï^÷œ;87ärzú¶›ûĸ~äŽ_|‡)8Wх­·„Õå5›S䶜ÞS«’rûI’ì’TdŒ¬’èÍíC!b¨@ õˆAsú/õç<»qÞvòž«ÛÝ—q†ïýXMCAÙRFÄ×àªÓ¯Tìbkt-¹#²šÖsUÆêÃV%ë±Uù}8Y±ÎÜ@€Šö®©åŸ@ydóëŽÓ;fÎþûјó©û/¸ Oy`ÛðQ\Gg”êCٝ8 §•P£&*)ÊÈ&bµWÇl ©Mì@×fvÖæ˜#b\MG6Íël·OžÝ?þÀñäw3.®}ÏÜCU(šä&:©Àš›Ò‡+au*¨mDYD+¹6¬™ZQÇ(ƒ®±¯ù«ÒÔ~ʌ&sƒÄPºçcP|¹öMÛá 3¶[ÆÇ¿Ú3òØñ”þ¹ËE͋KAòIT¤` —9ŠIK0ás¢ á…ä^RéÕŠ×E«î`JÛØ2_mŠ¥M«67n·€ò®ՁÕ/tÿ]wï¦ÍæáI‡}ºYÇSšÅóßÔ½tóN£Âxh*w ǼIHŠº‘N¦d… Òr0Œü #‹ïoH,BéSŠ}úÒÌĈA¾û£7šýarÐúã‘ûÇ>Ñ=sØß¼töDí[gçò×nžyÏQAÉÓAÖ$ŽL½N'3 cÔ8ìFBÈm}‹Íõÿ.)u#=Õg4Ãì b›4~nñ¬o·ÅèøÞUº™c[šíöËáÌQ8ý¯Ü¾MYByÅ͇ÐfÃBHOI8Âtû8š:K +šŒ |˜Hñ{…šÈ ùLdšTý}Å«¶íËoÝݸ\7½gMÓ«£[e`³·þÃG›p=ÇÔêÏ¡nÄ×Oü"ɳ@E¿dø¡çYþsì@¿\4êyj÷lf°÷lVˆ¹ê/Ëo˜Ö.Ó=Ù´Býjï:Þ*€»ÿÏn½Æ%}¨¯ã¶êl­ÎNmg[­µ¶ÖÉS›e—é²ÖJKÉÊnÞ/T^ð†¯ ‚ˆP@QQQ@@PA/]ì,«Yiåén­›múìÿéôÙûÿ»ó¢¿÷ßÏóâyžRؽ‘ +û·eƒ[ +„ìÁCä>ÄyE@²÷)H;ˆ…¬Ãaã”#Ás´£sEÇfKûϖ¡î?æ…ó,£‹æµ?_öV3|ó~lú¶¯ÎEfAx8䌃ÀíáX·HÜ©?BÆîÈþÉròê_(Ø{Jîh3[ÌÓ^^0_¾S ë3`ãòp^A€¾ˆ½kO÷úðÝØoýçtâ7‡$磐Š”¾ådmñòÖзíА +P¥+ß²£Š6/… +äfÕì^ GŸpÖ„1~Ïù)‘Ø$ÂT1|RB¿’Í.»˜Î玦ÔTMª¯Iˆ†â千±š¦è.Yo„AŽ¦7†7†7†ÿSCÙkCɦ¥ÀC µ»?‰—#4wÆPO¨Çù?­NÆÝãfo0©”qZãbNYÅùLnõ¢ ~(¹VbOKmñ²k¬ZeÄu¨õ8MÀB ̵‹€‰üՕÛ?„ú?©§#Ȏº‚,ØkNøD”s§:#ã:'‡>V\À9OeÔ “ØâtžÌšR­2'‰ÚLø掞8µN£éhmנ镡1”!?mb#ù~GPqEfVô¸ 7UO$ó²K.”R+‡é… ¶\f‹9³\cL­Ôu%×uë›MêXy¯ߪoNhkG°WüÏÀF 5ˆA²k(ö9‚ÚÇԁ˜ÙÖÓÁZâð·$)9—«3ËΕçíÅ4©™R¬éÉfôi¼ÞNb]Ÿ6µÙ*MZÄIÊnAӉ¦W†2ÄÀùv ·-‡&Ä Ú·Ú»€6ó[ÛɐiuLâ Ye¬>3ÂÏYKó”ƺÎ@eõèòæ6r½U‘ÙÔ/"4õ SÆjb«MÊCb"5bè@ þ˜ØÐ‡í¸¤IUBþEI*w¨:SÒW‘«î.+Ô·•[iÜ>9EØߔ+±U§Kør7Se@p^*6¾õˆA¶ó3Ðx¬Ý!—Yƒæ™!,ô!*y¢-žvANàÛEéM&AŽºƒCÓ«˜ £´cÓýuԆnv£C’›Ù$eš^X_/.bm[rÄ õøºüÞí‹yb ½gŒ \×ÅÑÏ)ÖÆ´&} I­æQõRV‘©Á²Ôñm•ôz;›ÒhgæÉúyÊn4½6,bhغ ;WB;bè>èòÒtóØv»/œðKWtá:A`jNmÒÖgªå‚\}CE±†Å´ð˜6N‰ÐΠ7Ò¤}…4Eš 1°1ˆƒ1t"“÷÷/,Ç1ÓýAa·úO¥\4FÙ´ñC A¢§·J„d°2ßÈ«(±°8ƒUm§3©ÅR µHaD”êðÊ Ø°$[ÿ­n+Aï¾î÷¾ß?³ÃÜ + ›°cSΙ# ͺØÊvU’D֜ÖZא­ã )F– ¨¯˜Ïê/à +(ÜF;¹Lj!—¶Ñô§¡ +14!Û +èrÿf¦³ýס£^wÎû‡Ž„¦ YÃéÝ]1|•6¡Q¬HUU5gv²Å¹=Åuts¾°ÔšSͳe׈2xRKFE‹MP8ˆ¡1H·|Z·OgîkŸÙ1Ûž÷ñ¼5æzq4„`µŸ.èèÅñdz¼XØFPV(3ÚKdä®ü&Z/¹‘aÉsû‰b‘P+íK©VÑôÊPþÕB¨ÝðÈCǎOfÌ{¿~4ìµõÎåÃû¯]=|æRP²ñÌIZ«-ŠÛ`Šñ I-Ìö´¶|M¶ž¤¢ô¤)Šz“圾¹Ð‚—ÉÌx‰¢MÀE ˆ¡þßï‚Òùos†?éß»æóÍIo±ÉcA¶«‰?c)ґŽÀ]Ç쉗RtI­™ZbAeÀ«òº£•EÆHE¹)B)2âÔ*š€‡¸ˆAìøWÐ8/™1îøèÁðž/o\ñü#ÿ=Øs#¯ǒëF#˜l{t%­/N”Õ“ %è ʸŽtM”–Ô~ºÚ¦aèB4|}˜¶¡MÀG ü5  Ùqtl^üØúÃò›ö¬º4éá4rãa¹ï ½ãÓ8–Á‹((>ÍÊŒç§õ' Ì) 1¦tIDIz²‹*5+‚ åÊ@}ª ò¨ùç; X¿p¦gÓ»·G\—^ººkåðm'ó#Œ»îñ!_Ù´_DÕTXréµõR,-s4A8K`ǧqqƒY•á9UX[~Mˆµ¸6Ю÷·ðQUˆAôåÛ ]÷ötÿw ®\ÞüÞðÔ®U¦Gî›Úg<÷´6º`**9{".#u<‰œp™HË,ˆú™\xú¥;Jg„œg”žå°üÏòÙháÇÙj‡Ý_9LŒ®q¾é´Ä4½kuÛ˽NÍsûwÕÎy(ÿÍϗþôdyI¼‡K¼’;•NÀÝ$Ã'sÓOMäg„]/Ì +¾Æ$^åýÇy9h‚:ÄжrþíÁæL~æ`švú@óÒí ìÞ(W6x»ÓÁϛ<{òq&: ñYBHì“TlÔãÌÓáÈ§¦)‘؇¸ÐÅÑÁ÷Kcî•ÇùßåÇ£ ¤ËçÿÚ»tÞÙK°_gaMßYǙñq­ZGÛuœ©ÖºUjQ°µâV n ˆ¬²‚,Â!„²Bd! K „,dåD©ÛPZ´–qð©:ZÛZ¥´g~Õyæ:ÞÍE/¾÷Ÿ»óž7\ìß™§ûÙ}E;ìY+/Wþ¨ +ü÷CøA"ÄûfÞ?²Oâ /8áעг¿”…ÅÎVž:ósMxô #âôL]dä‹Æ¨ˆç‚Ó¯ÓŒy©ËÈå….ýÿZòíìÚrp_Á‡OþF‡ýËàà6ߙ a»ñ·©^ñå ¹c àP4”Ž‚Š#‘@94ßp`ù…çX(ð^«û<ëØ|ͳ¥”º…<ضœ«JÀsmxoƒŸk¹ÅBŒûiÀ팄ôÃ°ëä}…»C¡Ä3ȞÁPµ'¨{µ÷$°÷½N}ƒs]Ôÿ˜ëÒ +Ëæðà݅TØòf¸½ »VãàÀ;±pd}l …ðÍÁûþIÀm €tאý?än;$Tá‡Ç äC? »ùE}­€Šöeó {,æî· Ñk ˆ|7(Ô„±^ÀÃû›ùœ^–ø”BÍ|XÆλ_À+ù'QTy—ÐZs'³1™Þ]û%¾§~"ÕÜ0žâàÞÄ]á_‰¿,p¶ß ¿þ/ ÕÈPá¾Xè¿àþ× ñÑ/àãO'7ê'fiÒwÕÔ¬åuùӅܲ)¢ò5¡•6™ÕÎú2]ɞHëiOíåÞJq>Ç 7 '8ÐÖ́j´');–m{Á§k åè&h ò€–ho'üÂ'DÿX_”úˆA!NW1K¿)áÔLæóY¹’†[ÿFf—èZº¶y on½š: Lõ㆚ èÈPƒ 5ۗ@ÃÇ+@t௠=² ä ò†¶¤ÀYIVìS~AÆ·õ…ST*e’\W;^Äå^'‰ÄcçÚÚF²:Û/§«—ð¦n΢¶¤ôwñç¥Ît´£¨È@s[\d ƒüðFPœôE¤t$ÍH3Î>çeOsËJï0)ô/(ÌÆk¥Éh¾@>œÓ¬Ên× f¨ôv¼ÑhN1é{ÒúºÕövgÆo´'ÈÀÿh9´ì_ ÈÐàÝ>Ðu6øEgZücinÎ=aqÅWõu7h4á(¹N~ =ç‰"½ãœÜl'h0SF¦I7˜º21MG¶Mál/ 4d`¡ÿB€ mÈ 8´4'<@sÊgVü¬;5ñQç9âTså nyÃç¬êÖá*¦r°¬Qç(–˜¬íFR÷iÚ¾Ž,&#˜{Zs¬JgæKÃ|¨Ý¶„È Û·”‡6@¿èÂ|ftgB¾×&'=Te“îÊHÔ[ÂþH}¥ü®²UÕë{˚Ìúâ6‹¶°ËªÈÓØZs´}¢I/ÊëS9ÛKØÈ Úù'hß· +T7€á¸û¯ÆPŸŸŒ1!O I¸û=ù·;sécâáPc¹ÜƪQ™¨µm%·WY.éë(í°I‹ÔýMÈÁÏ7¹…˜Úـµú•¡þƒÅ A†dÐ|LÇÜg±Ÿ±èGX"nJŸVx«+›9ÜJÚ%rS}•ZÃd5LV%´¶THûÅd•½¡Hm¯/6˜Ø%˜ÖÙ^ÈÀA†fdPì] =ÈÐ{Ì}Æìó½-*ä[[|òSJј*“9(#6aâ"¹–[¡R°©)ƒ‰©|« ºÅÎ¥t9Xe*³\of’{{œí•ý8 ®o@ËÎeЅ úÏփÅoÇs{÷“Èé¸ä WtE›ÁìïÌi2´ȕMe*icµAÄfa<&×ZO—Øki*¥ÛQCÑõÖPÌ:gƒZd`"Ú<–A72‘Áæ·ãÙ` ÷¿/F„L]8“|ÖT4dHc`JB“FF’É%%*± RÏmd`lÇʨÚkêäŽJF·ƒL×a4³ÎÙþgà!ƒÌãMPïù ˜}ޝµûnÿáÒI¯#§‚ï\ŠI¾êH(t˜SéM–@¡ ÊZ¤EÝ< Y_'¤öÒølkWÐOn”:JTŽâºKI­IïlP‡ ,d¸.92h÷ü0Ÿu/}ݾ øtúZXÐÄèiÜð…ø‚¾¾šÚÁ—ªs¤MJ¶¬LGk­6WJX}¥"ž­PÔbÏ©ìy¼ ©Ñ¤w6¨[õÊ Üº:ÑíÔïy{Öæ³ö‡‹G·=º~bÿÔxHàõkQIƒÃqùFŽÚ‰¥sÅB+GCê¢+K´UÆb9#É­¹2‰ SÚ²›uAdÒ;°‘¡ö½ù ÞººÜ—€Éó­çÞè¶/znß½ìÁ¨×ʯ'm¸yÏ×óòtÀ‰¾©SqªÛф–ñøò†ëÉ̚Ñt^ñÅìæsç‰ò4{¡g%wÇ÷Q5g,lm´EˆêÒÄÚ¬Jgƒd୛ ›çÙmÁ“‹»–Ü?°âÆÔg‡øzÚúû÷܍‘Ý‹Nç“PÀø*µ’|3“I;ÇÉ! R‡‹Å‰C䖸 5mÑçke‘çyòðÿ°_goMžiÇ#֊NǺ_¶Öъ bÝZ…ÔŠ"ˆ(² Dö KØ! ـ˜!!Á@BB Š€‚"ua¨Â(nXQ•–¢HU¼û^½æòhÞ? ßóÏÑóܿʪ€ê@ºÂÊ×þ¬-gº¶Î{òŸó~¿´oÜÙ¦ów7¬iòÈaݯ¾'Ê^â EãQ‰ÜG¤Ììû ÌäáTå¿Yü˜›Ì‚ÈŸ¹Ea|1¾¿Hx]&õ¿®’ù]«-E”"͚¹`^?÷eŸõÜ¡û¶óúžaWtL´mšqu¨~ãöñ)~?™;I Ð_)©O©Ô„Çéi¤_hYÄ=âA.3ôž€…¿+âݑq†+rýnW£äË- nµÅôù/çÜ^2§ï©í§ç¦°«gl´}'Ÿ=ì$šõqϛÅû2þ ¥½¦„&þž÷[ftôƒõ‚Cž2.LÀ?+N +z*£Œ)SüžhSѪesÀ¼ s«ß +óÓØ‹ö)[+ã,vU%8ZËÀy‡pßsÁû ð¸T zÄÅ;v6ُø.3 ò-#0l†ò&Ÿ. ž‡¾. x¥ ÷›ÒD  êþ…ꞏ¹|cæì«es`Ó"5ì^Y{×åƒÓ¸íJO‡DÞ'"EÕ5 2p!À8Œö‘ È;Bó©çq(÷òµ7ÚnŸ±Ä\ìýÓv{>F+,U°y‘v.Ïû5Ùก +.›Ià±- +v…AÄî“@²†Dl ¤î €¬ü€¹ï8p}!ßÑ„û½¡ø€”:ê.uXbÌ×,15£óç(`Õ¼b°Yȅ­K2àÛUñ°w œ×‡‚»õ ðµõü_ ØyCÜ7^¸ÍR·ƒÌí@ßqX;o§;ðw†¢]8|‹6sÏ\Œî¦Fþ‡•…V[²aý‚4°ý,¶/û•A°õqp[ãžk=À;œ\ƒÈ¯Ý fƒ+7¸@¢õ!H±þ26:C6Óæ pmœ ßmƒlúÆO ù+8{ƒÀqˆ\ׁØÇD!öP@r†üÔ£Àaù¿g +BÞdI¯RËâ&“Ô‰ñº”qõéã±MYÏ¢Ûhc„.Ɠ¨ÞœGýì{a·87NsÑô·áoÃÿ5díX¼Ý‹¡`ßJ#†o;àíA㠂”cÀcžxË⇿¦ÇL¦ŸN˜HV¥vL™žù „™7(àI¯±…½ô’ª åús©U g’ F3õLcåL£.¾S¯Iê©TSûÊÑ<ÄÀF |dãHwü*°Ë@çô4 £7vÆ„›lˆ ¯%Ç=T'ÓeY«…,ÙÅ<¾ªƒ%ªn£•Ö5gª †ôÚ¦º´–fmR[³Šz®A‘Ò­-KëU¢é£A°i”"µÃ2¨=°Œn›gM^ØiS n¢)<èq},ùŽ&‘q½,]xQ̐ux*3¯@gd•Ôëé +cuvu³&«Ñ¤Hom9vÖ(Ë8_-ͼ¤Bä"ΆyP€äہÆa)Ô!†f·ÍïZ=¦Úpã­¡ÁÑ”: +ã²2EØ)˖™‹Ø*Ÿ¯«á×kXòF%³ÒTƨo‘ÑÌæâ¬3M"ZWMí¢M‹ì,Î×ó ÐöS(C UöK¡áÀ—Ðâºi¦ÝÃá·sþ¸±öà»¦¨øëz2£»’*h“gʌ¦ª¦0O§æ֗çÊeœ +“„]k±[ÌF[³ §³öTNM¸ˆA„ˆAg¿Œû¿€6WÛ鮣ö//wíÄ µERú $zGu¢ Y™.«-¥«*Å\]Y¡ ¾D i,ÊW˜„y:3?¯¹•Çi5ñ¸z·[‹&ÈûŸ¡1T oe­ýçмÿ‹÷g]l^uÙó¼××m¤;8h =‚ÜÓCo«?ÕP™"ՖgW”—²ªK$üúBQq#¿Pnâ µf¶ÐØÊä›[˜üŽº~·MxˆAb3Ԉ¡nÏçÐâ¸úm‡ËÆÉÞ#»Ç®ú¸Üí ¼ÚFî4iÍ +_§£–(ÕJ©‚ù'ûuÕäÆq<,2ˆ´ZµVP”\Q JUd—}‘=„5@ !a ;D‚HD‚ÈŽ¬¢ìЂ VŠX«ˆ EtÄ>󞞹'—s1ŸûïÅ{Þçÿ«Î.bŠX…Ü›Œ|þmz^y3-¯¾9ÛÜDÍ^鮒d L¤‡4T ÿëä~·îþÔm®¾8d{ê嘳Ùø‡Ç@_h[;žV'Í(«‹Ìç×PJ¸I•¬kiµ)%œFš€'¦\½ÖWTÛÍonŠåuÔÅåwWIØÈæe©É¹U'à–®Òz‡Á÷+ýfjoÆl´§Ç/ŒŽºcº}IâÎÀÄê6K ŽÈËmˆ+Ψ¥U\®f\§V²ëãÊónF••ˆÉe×o‡•·ŠÃ…wE‚î*IüÝÀ> ¤áºæfh:­¸Ö¥¿óÝ°™ê˧֚Ï.šþünñ&Öõã(¥ÁéíáÜÌæ袔[‰¥ÔÆËÕ1õ¬Z²(§>D$h ÕÜ$ˆšƒkîÕ+{*%™ßKGuÕå î¸ü×öS[—ÎoŸ{dª<5mq|셽q÷¤««ø‘¾jÄ?Ž?ˆgpzB9ŒÎ(µƒRÓF/oeV[¸×ƒš¯ÖâZªEþ-M¢€Û]5¸†¾rI@Ö.iÈÙ' å7Á­crk]:›_ß×SzöÜp÷؜…æÀœ­q봋sí¤®dÅ ¤§2h¿DäÄ Æ†õӋƒû˜¥¸>n¹_¯ Ò§·ªÊ«W\åÝÓ[îÓ1(”\Ax*²P£& ­‡eµä¦~ûQaì¥Ñžþ·æšwÞØ5¼rr,›Å` ¦±¡ì)||òdh2e"š1žÈ!>LÎÁ¦øŽpøžÃW1CBzè†Àm¨Mà><\( àî”ò¦¬W•þØyPzæÑ¿dÆfµ·ö-ª´-›ŸhxomPñÎÁŽÿƒá¼ñÃ1^‡Rç#¢£gã¦iI„©””€IVšïD6Óë)/óD˜‰~Rå:.Îrï’äòÝÒЬ,õÇÐN©/T¤û´ÛV ÷Ö­]Ð,[µÒãÿyÑâÊ +Æ)uÅ߃öä»‰'/RBHo“ƒþHôŸgÇø¾âÆy½äQ0³Å èÙ +ªëL=ÍùE‹D€·] +DßI­ô(¡>݂ê]Ø+ÛòQë[ÑWý½¥_MŽ¬[èf­Û1ÖÝ-©ëþc×C\ÿDaˆŸ)Þø5:6`5Í»’‰óùäµ\ˆÇ,Ðï+ˆ®ïE$çEqˆ$ ìÔrëVÔýŸ7£z߂jZÛ'W ÚۄpN%Œ4X`®E»3@D‚ß…P Y Ò&(öþäà ©NÞÀvö® æ/ž›ûWÚm½ÜÝåË Œó—FI,ÕË£FîýÕ9"/*J×À~ùÐú– º?¤þ*\8 ¶'CÁå|Ïà X d}ˆ5ôš1RL܁iêœ ®kæ|s'Z8B•¥ˆ¬$1Ú"‹ºÛ³ uó±ªò¯od®‚šü8®”:;ãáœr8˜ €•†8ñÏãÀDCˆ–+Dê8CüN@;å)§/Sײ~²ƒœŸl¡ðŒ ÏZC¥DîݑA5ü"ƒ*{&#UÛd8p@>ý3Nl Ý]80Øã æ{Ñ`·ßÜÔÀç àÔm¤a äCVsØŽX@Òs`5æQd˜3…Üc&À?.‰Æn)TÙC*בֿ¶Ë$²\¨)àˆ¢/ò]¸ÃÙN`¼Ë,w[ƒÃ€V6/SðW1 ½F@Úgáû JUâTÏC¢ªÐ÷Ÿƒ4û€$€¢"1‡ä Bg $ê*AŠÁH·P ' `újAjÈ9HŽ7Zª $d;A, Q¥^ëäjì¿Cë>ÅAk„6Â*¾‹¸8òÞ$lû(|ÞgŠ<ã59åñjCÿoø_j@nE¬†DioK§• õüÈ0W, `{k“¨ŒX3 _¶*ÇâyžëÑBìçˆJÜZ˜ˆ°JºEZ n û€ï$/F.ŒD¿Æ>Ž™õy;é5?î5³HøoCìIH>¥,½À1S®½d{jCþ<°¢, 5Éè˜ujöSœ h5ª<äù:y)´!j‘Ø»@¸Ky4@ÇÝ¿4ã÷$iÂgŠ>æ3MöMØ$" qÈû…‚¼ã:Šyî;àš*C¾äa´‹Ó‡,²°¨.1Ò½?'qƒþLà‡.Å\‹|Q÷&¬Žúš$NzE¸sùePê äOøýÊÅN¤úM%÷úO_ÚP÷È@<Ґ¨©éÈÖ»‚ì¬<eàÛh@!Zòý €jY·u&Ão5…C\¢D.ÄS^GU$ͅß`̐n1§ƒÛÙÏñýœßpïû=àŒ³»p“©SÉù»‚4\:¦ÈÆÉ9»xÆÊ °V«a ¡€dû…ƒYˤ~Hg‡/$çÆÏ'Ñg£KÓ'×d= iäNÛó%  õáît=ÌnÃ?e5&S74¤!i Ý ™HC²³ŠŒ÷€ÐJ®9ë@‰Ñ—«û‘^Ë\Zð;=zž‘4Cã1§â„ÙO#ª +†Ô FI­%ÃÄ>aOЀð~¨¨9x,÷&i<³ž4ÁÜА͛€lÞËG6Ù8`Û…HÙ7KÝùŸ +¤Aï±êNmüÝta×Ls ç¤)û¤öJŒMŒï’ +îòòè¦ + +§¶„.ÒQY2%Y¨®")u"bŸßbää¶Øù] +q@À$Ù8ö@ášÿ50áöE Ú¿ª¬úØpÒõùü®—­þžæ0Ì¿b¢ûõ‰øv9¾ Y˜C¯ã°uå7DŠ’r™˜V©®,’é8d½I6…÷ªRr¿¨”<ĵÈH i(ß´ÄÛ‚™×µG>ÿÃtrÛVï/,Ø£O[C0LÑÑ]5×Òî¨SI ÒÌ=ŸÈV°¯ Eå ¯”«fKt šÖXBk¨¦ÑîUS©jµOL£~WiÏ_ €‰¼ 鶅 Û÷ Ô^9k>ñåÌ=ï퓝˜#Ûƒý͑Q–›q©Mz±ZA(VIòXb>YÈå”Èʙ,uIr- µ‘Rz³ºÑV]@·j +齒Bú ß  dW'`#g!Ûæ ƽŸÀ­ÃŸ½o=¾îUǹ­½˜C;‚|{Z#"[o]M©¯IÊ×jñÅRE6‹')” oTWV¨(¾ŽÄVòX5Æ֝ê¦U“[Ñ+Í+äÛ”Õh(Úà\¤A±Õjöº|l>´ümû±/^ôžýêé ï7¶îK>Ööðˆfs,Îؐ'¯N¥ñµYJdXÊ®KɆ2_ÄÓf dz‚ÀhÀ ÌF<ߪ!ðz¥ÜA=P„4ÐÖ;A%rê¯@ýžEsw¾]úºÓkÍäЙM? _pïï8·#,¼¾-:Ym¾–+jÀQYµåņ<YKçªèò G*—h“ez}¢¼IŸ$·jp’^iŠxo\GJÖ9‚ÐÕt[æƒi—ó»v÷O§ú=Wþ{ìÔúŽyè´ù{7÷†„­Q‰UmqYœ–d +݄/¥4ä°së +„šb)ÎÈR$Ī8ƒV}ÅpKsÅØ©ŠÓô‰ãUƒ•öu_8‚tƒ#TovúóöÎùÓÝý4â±tìÇã_öŸÛ×6Š=sӬꋈçw]É`X ŠÚҊsïdU¤·¸ÉÍ4a|S…$Ö$’EÝÒÈ#LòËM²ÈúaTí× ! LdN)Öσ†Mó~kßêøóÐîùcãîKž_o}vvoÓ8æ”~,è’x8<¶â»˜4jÿµ¼¼ž”¢ô®Ì’äbyœ•Æ‰¾_QyÙ"„Z4û¢`k§0¤mˆz{˜iŽÞ4èþ†þhހþµ×ýèÉ&ǁç—ÝqܵyòÌÞê ß²§9OÂ"n|@½F Œ¤ä'gR®> ݈²Ñèá6fY°M\dÓ2m&VÀp73pp¤,°g”nÐW¢A²ÊêÖ8¼µ¬vx2¶ 5ðÜÍÉòêàŠ¦éc/Oï‘O÷äýp>Dþ962{"1>m"—øS^úÕgEYQϹáϸĐ§Ò‚ µä€ñzÊÅñ6 +v|˜‚yô˜l”¯@ƒj…ÃGórÔè€ j`b™Cû´ÛÓoî+ o=]«ÞœÚÅý÷áÒ×þ§È3a¾93WÓg’C“§3"㧉1±ÓÔ¸Èé²ká¯xI!/¥¸ )uJàTmªÿ söE7óËC»€¿Ôj?EX¢z‡¢Úf–£?l^¤Ÿs_)óØÀž;±­xöÜþÂًÙ³a'Óf¯œKšÅùÄÍf`cf‰‘³ÔK—çʂCgy!Á$a—~W‡¼¯Ž¸øÞ‰}g‰ô{×e(]P£æù¨®Ž¨;# Q7ÿølž¶¸ˆaÿÊ +8´Ž +ÇÜòáì`öá äÛxˆõˆ…d¯( œ¸ y§Br&ègƒ€í¢ó ¸pô>¨÷õƒ;~¾`ÅØó}ÕÕê„jéuBÕüàŒRÂ*G!lu)ƒÝË)à¾6<קÀi·xðÝ A;/CԞPHØ i‚ Ë=Hßøõ‡1À=â bPz\ÃQohô<-^öô˜Ð(³Åe´ÍCUM-tàÁZ':¸-"Áö%ä,áÈÚX8±.λÿ¦ی…Ø-~øµà·^€ìm灴ý\ßqJwžÖ®Ó Øud»O€~Ïq¨µË|2ô P’G( £‹a­c>lpNƒ¯Çý—ýòêj2[°Ke쎻8vGEłH "Š„BH)$$Ò{$!H‘*(( ŒX°À€¢.lˆ"(Ê3öÁÃ{¾å¹9W™?p.žëïY{ío¿ï›fFûœ0ðœþ Á¡Å dI_ê±Ë}³ÜRœ¼€¼b/ÐWx"xðWîéÊ] ^µ «<À²úŸ¨¸„|¿sÜ8ųqãø0}<æNÀÃbû8øÁ!œ§—‡ÀcVx}ï s¼àÐwª¢ƒ[‹1ñ,b]•Y¥Êä•HùÒ¡Leäéôúl‹QuÒ¬`ÕZdY-IV›Q¾£gu‹DYø¶@Æé< ␋üŸ…›¾ƒ +÷™_Îx:Ÿ÷[9pá Ë£ó!Þí5QÁ-eè¸ó'ð©Õ& +㤞É-Pq$F™D¥kô +É(á›…Üš|·9ŸÇ»eâñnkx¼n1—ûP`  #•±|"ȜìÀ„̍âŸà”ÛôçöÌjò]Ñwéà¦{MÁû®×E»P™[[’L(Ï'1¬F:רgK´j¡J®PêERƒ‘+.4³Å§ò3ÅM7óXâN-Kt_Â>Úâ›kéDP"ga^c¥'qö®q÷ÜÁK>˞^=ðSgs×•úãGÏ×ÄŜ*OJ)*J¥çåS9ZS¦XžËW +tr]¶:ǐ¡,È£+*,4EC>UuӜ®ìÐ¥ËïKÓeÝ"[q`/™jä, +·ªâÇI£g·M¹¸kö@«÷â‡76Þº|tïŦðÀÚ³1Ñ¥Õ|~y +M_LaË­L‘ÀÂQ°M-àͥæXL$}™9UÎBȹn&ê;t$í=)YÓ-²0Ç™ºe pÕD¨Þ`ÿ©ÑÅaèŠÇŒç¿{9výî¿áZk gÃoaGª£Q…uèdC Žª¬ g Kév1[F?!RS +Ôz‚ÅdH¶œ4%Yêò0ùÿa¾Nÿ©Îû8ŽÿŽý¢˜²u‰©)¦H ‘­dß9„sç8gáœ[ölIƒJÅ´\u]I㚚¢G£1´h™h’êjs´P²„+]Õ¼¯ß\À¹}ÝxÞþ¾nü~ÇçÝsDrü^½ôûG{¥«TAÙPIþ ä=uzµ:Ú¬5>tÛk¿½ã¢7øØͤ﾿Mw/ukÛ zDs7›u´#)yÿÏ)òª6YAÉO9e;Ï푷TÖ¦þP{@Üüý!AsS¿¹µ‘wæZCRsÿÁ?U O>©R…¦j¨&;Žš«áŸß¨}ºü­úäM[¡‡öZ +W£}×^îwÿ±76ôÄMãàU¾°ºK,ÛՑ–»³=«8ãRA…ôbyµ¨­¦–ßÚ°Ÿsáԁ„Ö õÌÖ«õ ­uìŸTqZžV¨‚"²¡ÎD 'Í(¸`A™í^IyÝ¿’20d«uû•»Q琯Uë“P—¦è Æßãi5w¸ü²["I^OjfƵÌ<ɕüawY9¯«¦*¡³¡šÑyê;zç…Z×Õïè]ÿªŽk^wi°T”ï4¢ Ù„ò¥Ý”xwg 10dB¹õÖV»ó»IÛ°¯Õ™—!NG£|÷=‰‹ªxÈaåò~iªäw¹\p7?—ÛW^Àì­)Žëm,ím*‹îm+ßÞw4XºýƋÂèk/ TA¥!G—Rpn ñôª.qï¾.qstå× [ÝÖqÓ3c>VÇF÷¿¡nÛ=RøŠõRÄL{‘Æ e‹øŠ"I‚bw:C±/ƒ¦8’­hΎº˜CºžñB‘ñh$3bà­\ÔPpJŸxÖ®Côõü…èy¨Kü2c¦~þß띞q_vdÚËrßT€]åûp·Â÷tŸìInpú¤˜šF¼"äSÜpè},t–66û!l"F©ÒÿMlàÛë ÅIéÈð3Ff„9²X«‘!±AúN{H+‘RïñßƍQgèS‘“´ÙÈw´yª*’wŸlHÚ¨ƒTG=ÈÝ ícŒÜpsìdX"[´ò,GÈÊ\‘Zç É$7@t6ÂK¡Hê ¿‡ +/ìûÑó¬Á˜ÙøáØiÆmœ>MKÿH{·­ +D6XkB´A2]d» ÏÛ¡æ(¤["O@~bN{@¶×i‡ 9‚ä–ˆZ£ ìˆFÒõØ?x¿Ñç9ýŒ ϙÓÌaÖc<áMÜ ûãcüóøyš*“·K"ِ²^rò¦ÎÛ¬"/c”›cWŒŠø—ü­È¬òƒ¬>iÇ©œŽFò9úÑÏñŸݬ…ÄۜÜ{¼é„çü1æHÒHü„@Á˜æ?ŽŸåô³”ñªü¯!i­&R×i#gƒ.ŠœõQêi„ò@sTn·BÇÅäçz!§<èyõ“¬1v>õï eJ û?¢VÞ¬ #éCbhšw/eŒ=(}Íz›ú,~L:Àœõ%|H¼Åžc«‚d²A@6ÈÈ}“GnÞR§Å¨Üj„=˱—j…*–ÊÅn_J2}ò‹Ãærªcf32gҎñ¦$MÂIñٔqÁ¥´Q~÷Ž7ÜÞÌל¡ìGÌ᜻ ïvÜfOJ¯s¦E]¼Y¾*H±P‡¼éåk´P´N•äæÝëaˆZ¿åØn…ZÆÆÏÕwe…ÌÿCI~äT~%c"«Ž7*kHN¤¿ÉT$žßùŒ÷KácîÍ¢ܧEwØ/ ¯sG²»xïvtð'¥—g„ª@B6$“7ýù®Ï°&Ï5àoÂTÜÚ#¢G­¢Û:«âi)E¦ ‘ed“ÁY„„$oH I؄¡ld)C@+R´­´§Ç>}/¿Ã‡ßçç½Ï}¿×ó§Ö0Ò7…Hç•^Ú’0iöƟRÝO~ù™¾O$Ø,òi®³,ŽÏKš0ô)QN|BÈ¢`•ŒÁ¬Á zÎ@`·/àA\—ÿ$·%à%£!è5åvð›Èê_±kä]7Öt¹ Ò7S.l»€ÂÖø£Âõäût³9ÖnFåñ füÂà…=¤ˆÉ÷‰©ôÞ°œØ|܁Uǵ‡6ó[Bú!ã‚ڐgœªÐiznŽTŒ[$ãß®ês†°ƒÚ€‰ôÍx¤oʐÝÈ8¿dgøWžÍÁ¥—os0f3iAö“’p¯ÇZà‡Ö“@é¢ÊbÚ¢2ÙMq?…• nêÔø.a~DXŠÊ+"¼ˆU†ÍPóÂ"֐ ‘´ é›"d&R¾©0Ù òÍw~T]ùò·ÇãsJ/³)…¿Ãh +Þk0‘x—Ï ¿ÃæQšbF-•£&çð*ˆE ¥‘jQQDkbaÄ 8?RŸ9ÅQ_Ñ3£æ‰kỵ@Òó`„™‰ôãú ïܦOªË_,•Zí_¬t86]âaªÉ¿e?œõ¼'#¶‹èa <˜RÃN`V0epIt&¿ªæ‘+ÄÙ¤FI©7)ƒüD”F™ä¦P^2’)³$9enUH4 ïÓqé!uL(Ïnø_©ÙŽß+Ü;WcÿõT…û¥•]vˆgGjx@c5¬FÈ¢”óøLGçŦ 1¹¢ôèRI +­.INë–Ê迈“è< ýE¬˜þš²d  ÿþ^mŒdÈùF1øPaºí]í{fê펎«¯_.õ¶íÎòhÎ"Ô&“ÃÊ% J¡ËÌå‹àL8YÂVˆ¤±E1³F*dޑ Y“bÇñ±S,Aì u-Ÿ3АýŒGr¤kƒü¯uAééõKê‹[~²0zÑd{d´îڅþ +ŒÍU€{}.ο2ƒHP%G“s%F†(– ¤1/S”ÀUJøpµŒ ·É`î—«‰‡á) ¿ŠFÐV"Ð€ŽÌ¥ɑŽì‡ò¨Îÿ+O­û½îÂ湖ïvN¶YzØàr¾G}ú¹ÔÏM­Äú•dGàóÒ©äŒäX†\ʇŁ@˜.âÆçKX‚ +CÐ,‹ Êñc LÁ3˜ÉEGD¯æs†‘#9²h¢ÿhÿ©>¡÷®ÉdëócVÆ÷[œL:ê<¯ÔWÞº^^r«  —™M&É31‰©\_.âs¤)"†$WB—I)‰ 2’¸_F‘Œ ©‰“0U8M_ "X»Ð ¹“ä=SvXk¥î˜Î›ö³ëž÷šn¹kyð^»ãٖF+u­kQEov1›¢ŒŠJÌ¥Óù +›‘À£§ÉÈ) +11¹8)<¹^JH¹'HFÈ'¹‘Ò阵€(ä|x'ȑ,ùûРÊý¾é+í×=§t'†Înê·ø²³ÛáL}››eYƒ·K^m€wZ%.DRÉ/¢ÑXJVlt¾€KÊIŠÏÎá*qˆâ¶$XÑ- Íb3'a\ÚtÌZ ÉÀû Ò ‘Þ¹õ×íý¨·‡Ð/†¾Ò}tzcßÐ÷ûZúìOUw¹Z¶aœ2ý0ҺРAMx»ŠBŽ.gÆD•Æ± Åb^HQz| ªP觪ùªºD~Śxå3N`î4}-€bˆ ÛQ ë_(PfˆZiڍší3BMhö †Ÿœ4è1ÿwý°í‰Ò~óœ/yÇ-„Ö`?vÝ@Š$ÖÅPñµ\FpM"ÛOÆõ®.àcªÕ/u‡àFÍxÜÍÊç,ï’ÚZù’m(·5Û¡_;·@šÑ Ѓ©=¨»“'Ö5ǩª[SðÐéRꠇ¨ÏǾèݍ"vñ¸;tbP;L¹Õ*¢cZS™ž-,÷5ûzkûz›†åÖ4M÷¸=KFVØÈù)[ P¼šn2€Fz×CCÿ5€z¦÷¢›_žZ¯~nf¨š´:’©¹j"u³ä>ºéHàAÆúà‰÷£±¾pøѽ?ìÚ¯¤ºô«iΝ4§ûTçÞ¹(—Î…p—ŽÅUÁ&Pl„¦ªõ ŸÛô¡¾}¨kÂjœÛ¯U5{j£êµÙ®ÌW–‡%/í¿{îz9ææJÔ¤¿#î)Ö-pœˆñ§ûÞÐpÜ5‰Á×4éX'M!þª¦–à0ÞM°ŸxŠw[Ä^}ø[ðZ@’4¯Ò†ÕëB÷:t¡¶a}¨~~ªüÝå»o7¥¿½´K¼haÌ]°9óæÚ¹¨yÌeü|€eð<ÞÆoŽäà=Çpöšã¹ºÍIÜ®Ígx:Ïz]¯Á8¼¹ƒ±_¹i÷fþ¦íô˜µü™©V¢¡{ÚPsT3¢•¬lEå.ë¦.ŸÞ$\¾¸“³üý~Ú²õ‘ˆe§ãØ%¯3Kþç}—p¦7—IæžË ÷å8K×e±•óJºµãJ­ÃJ¥Ý‡f{Ûý6Ÿ;Xø±´ªñBê«ECM­ZPՀ6T¨Ñƒ²>í@Ë?Ñü}b#óo“$`¾®ìWù÷£à{Ì„žtC +É5@;ã ØçA‚‰_°Ùm@ñ%kPkjÚÍ~Cf–àõeK0»ªÁJjn@A•Ý((ÿg4”:£I€á?|—kXÌyÇI*§xè ‡¢$%ÏçRtšæÔšfš™f¦fjjš¦3Q*jS$¬b…°Ž­ÇéZ\«ua÷bí®­'¤„q˜(Õ÷ùïîëñâóúþ\×}ÿîßý¶Ë Tp0ÊÄzS¼çs¼ˆŽ( 2â­ãA·Ù îòh¤¯ŒB–mT«Â‰c4Û탱Û!û× ÝÑ]Ž~è^닧¯q¹‹D:ÞM"µÞ!‘ê#‘¶M)†ùÔXë‹ag˜ +'ãd¸›&Án,ÂD#fa$ȋÂÀøO0¸K!´ðG¦¥”–>(¶òB¥µ'j—º£ÙÆ ‡m6 s™+.\ÔIç9¢þM©î‰´¥D*€ñ9æN`± Ë (°7Œ…‹ÑFx‡!À$áfþˆ™ãƒ„¹^ Íókžxó]‘¾Àòë 2_K,GT-t@ýB{´,Zö¯Òö_¢þ]¢þ$’ò‰$ÅÌ)\˜N¥aþ´8XèE= …ÃŒ¸zÃs¦ü\2Ë‘ÆNØl숄Ù Î^ ¦‰RMVBd²2ÓePšÚ ØÌ•fV¨ý*`ÿuÒ}P\¦ƒµÁ\cðB瀿Ù<æ¤JmÀQۂµÝÌG0Úց~Ì´Ó® ^ÚÊ 7Pz<ôØä^O$¾ðB°7âßyÇi}>Ǎúhc'|>ÄB'ÿ:8èƒæ<WC𼍑2‚Mæ0,À—Ø€›oN¥X»×‚ÙêŒä£® w¹vÑ´kž þäʯÞHúËä¾H|å;‘ ñ×úÄúˆ›ð×ÄÁWH^: á4©.†x#=hÄ1æÓ, -GšrR·:"¥Öœ– `qó„'’ÏyƒqÅôÛ~ =õÏ@$=š &j‚µ ڐw c!o&ƒ‡¨ 0 *áÀr4ßÙb÷YÈ0CÆFsȒ,!M[t…=¥NàU»"µÉ)‡¼Áþά3`^DòÍ`0~폰Iê³ð±¤¡-Y©I‰|89Hž  #Dÿ:Øë#eDN3±aäþfȎ\E¢%ä©+‘!_q‘ „Uîà7xƒwÀ܎ pN…‚}!Ìk‘Hþ) +Œ'Ñc´þ-uh“&éÝæWä‘؁¤/1Ï(ˆê£"B`÷pà÷´„È7Y®³ëke¸9ò⬐˶E¶Ô™ù®TxAT€´æðGLroœàœùÂîŽcþ?šüK¢–ÞO~K¢ RÞSŸS?‘{i_â§cÓ#:¢u6ᐼJ‚UÙO‡ÒÅjoS„š£p³ +’í'r‚"DzR¿qÉΐ1QcÔç´ÖM#¼öø)'ÉبïXךäækF/û%m˜ÓG{Ï~B¡?dŒ%ÝKžˆ¿ËD¬.À±š¶­±võ¡X5êu3QâiŠ²`sl‰¶BÕE|çq•Üë³¢0H+«Œz/©‹}+ÜK~Í?Hâc½dŸæ¾`vóŸ1n ûèOÒÿ¤ ¥?dhø=L-ç6k”q“=N¹Æ™LÔRî +=d,×GžJœfb«‡ *`[”%¶‘íƶ¦¸h‹¥>U^Ø°¢ló`æÊóô=Ì>þ¾Ô§ÜÃÂßٝ’G¬ó¿0odÞg>õ$Èn±Þ¤_ç¼ç_Iá\âŽ2ÎsÇ)º—pàÙFn£‡[lu4Äv·ÙØé?5–c5ñvw°Ö¿)ù eGõ+ ŸÊ˙%5¼‡¢oD÷ÒHîò:2ïp»²~Léξɹ£¸ÆéÍéæÉΧ¾å}àâ°O¤2t.‘ñKõ °ÖC ‘7·™·†˜Ë:ßyã»Ã,´ ›ìÞÔÒ×Tñz·dÄüVG¹Ÿ[ʾ›µ=íVF½ø¦¸9óªðPÖiÇs.ñÏ)/ð®çãýšwšÿ"ç„`8ã˜P#ì~ä}bé©„C:1—J"ón!ú±“ȼõëÐè=çsSÈbMs´íËFêú¾])¶‰c~.SPnrn(ËW²«%3äç¤û§Åíʓ¢®üNáêcž‚Q¿ê[ñ ü øµø€ä=¿T›¢ ð,¦BBxäy³‚èÉ®Õhtž9Ñâeú±5hÑp[Ԋþ²Ë“vÀ½jaÌ­J9åj©Šs© Tð}Þvi—¢.ë¸|oîÑÌCª#Òã‡$ +Û$·ŠZ¥½…-™Š½™¯2šdA£ìCª.þqÈ êþ{‰™¨'Þió:ÃÑ&šC ŽD,{ږ°îÁ^¦ÿíú´è«;2(+r9gJ‹' +*¤GUÕY‡s”²[ó÷eu-þFv½¤Aþ¸dOöse}ö¬Nñ6½Vñž¯ ð Ùâi(&ØAìÌ;}ì_;c䰛ñp‡ßüþï­‰sº»Ÿá£‘}¹V’t¦*›ÓY®´—–IVeï˯W6嵨÷ä~[T—sªd—âJiuÎýÒje¿j§òeÖåkq•ò@H[2YDÖ,%¨!æ¢i¥ÞäAGƒ®Fƒ>sÿ:jùàhìÚ[i~Wš¹¿ß#J:Q#g·Wå Ú*J¤-e•ÙÅ»”uMêjõÁâ*Ugi¥êrY…ª§¬Bý?u…z@Q®––«5B]üã ø;sÔýŸîúŠk:Ëâ~“#-‚€  £4)ÒA)¢Ô¡¦Zˆ ¡I -¤¡ +ˆ *HDPŠ¢]@?«®ŽÀ8*£ ~ÆYѳÿÝ}ÎÃ÷sÏïžsîÁvÞ:Â× {ˆ:,¥—{íþÙç²ý~'ÍøöÅ ×B½zj£Z«øÜƲԨ3ÅY Õù‚ò¼i%9ՙÙç²ÅÂö‘p0W(œ‹D/‹DË)¢ì·‰ÙÙïy’@4–!M?a{g6—-—KRï.›‘~°‘4à¤q·‡j4Úh¥™ëÙ^åß\“À­«:Y]ž_^š+(.*NË/¨Êå×g·ædˆûÅéâ)ñ±üŒ¼åԌ¼·ü ñŸ±’@Œ:ŽmÁC–ã–§yþSçnÂë~câó+™‡×Ôǯxï¹Þ`×Ýìq±é°_ýÙ8ΩZAdùÉô¸¢ +ё¼òÂTaiEfFñajÑŜä¾Ü#Eã¹É%/„ÉÅKiG ß$¥¬ÄI±Ø;8®Œ‡Ò-88½ wà>\ÖÂ/é~½e*=3rpëÍAOƒþ^?Û¶¶[cK8£¶™Çþ¹!)¢èLj¬¸F˜”UŸ’^Y–‘\Q›Å/?/Š/¿œ[>–_ñL˜ðóRZbٛ$þ‰•8I ›Á÷Þrԫ⾶oý؁{q{nvÒhã䘽Úõa½î†õ…^–k]g¨Oå¥hVñ…Ä0qÓј¬†ÌÄ´³âdÁ™Òô„ÚêL^M“0êTWöᚢõO„Ñ5Ki1Õo’xU+q’@6‡\ET)á I}îQFË£Êè×{*èÞ´!éæ¤Ý–þ17ݶaŸ½ ƒLçê¾jiO$3¯#>$«M•Úr,îȅœ#qÍÅ)ÑMUéç2CÎuç6Žd7Ím\N ;û–~æÏ8I «ý“jÐ÷ôû€TDôˆ×fl”»¦\µšoÓ,jo:” {åFøeõDzS{““zÒbb»²ã#; „¶Wå´×§jëHjNgv̦³Ú_ Ø-ï8çßó$t¬%dõòèi×F4;$îݑFSÉh䑎Tïì^Ŗ8í¬›ö6©˜òÛ_p›í& £§ŽÆò‡ùÁ¼¡ÔðÃׄÑ!ƒq쁊DæÕú$ÿ«í߁!c`Và7ð61 ÷=/°{5J’qP)‹^^ ¢Ù>º;JB·f6¢ágdt噡mÁB¾á±ƒF՜§AÑCƾìû,Ç´™POþÝhޝÄÀˆÉ6wBš(ˆ¯ˆò¯¡wðhãñԉ9mb%š~óc„ÏÈçPI _}8-…æۤН«Ðè <F=¯Që+©†ß¬äO¾8°µø¹»Žè)Ý4miËÂuŠyåþ(<Ÿâ4' ôŸ+d1æ*9´¹s\Ê\gˆ×ühˆç£'عìýË_lï{³$2ZhBhº›€F®I¡+“DÔ>/Î¿QÆÕý¡·¡òKrák{5áï.š©ËTƒÄå@ó˜%®uøR”=w1щµ˜ê°˜íá»XäE_¬¢Rè^K>KC ÷å˜× ÷Å/>î/×i’¼¬Eèþ%„Fûð¨o”€Zgˆ¨aAÕ¬©áË× HùkäÌU»-É«ÎÛãV½´"WýôCW9FœÕH³ Õ«€Õ”}¾«B[úZÁ~ÊZůµ³/9º}¼êôã§)g×OÿrvùôÁÙeíßN’ü‚õàfB½ƒ8Ô2ŽGu³R¨bE•|Õ ä|Õ#¥5“ã¯ÛlŽYwT [÷Ð`¯Ów®iù} ÓõùÆÓ£}xÏØãù=×Øý{©ÉPcæMæÎÐeáC–0cy^aÞ[I2ކP_B-7:=ƒPÙåÃ&\hŽ‚Ά80’‰€½dØÌWPÔhà¿ÍØØ'Ì bpÁN'ÈÔt„<­ƒP¦m§uì༮-tëÚÀõÝÖ0yª'I7Vÿ:V¡Òy„DË8t p|PÃGÁ."ôIL0“a€<7y€»¢+ДœÀ_ÙØ*ö¶ÅbTm€¯¶Ò·ZAÎV (Ùf§ÔM¡QÝÚ4L _ÃnHt©« ¡’ Ÿ#”Dd\(ãY Nðm" In`!í ¶2ÁQÖÜ䬁"o¾d `n2ƒàM&¡`±Š† PԇÌÍ»!³”+iC­’4+kB»Du£Øý±d- Ä_F( +†ÎëTðn°àÚRûÁ¸Ì7X‚5Éì7óFp—ÖŠ´.0d´!PF8²;!\vÄÊj€@ndÊ©XNNÈ«ÀI‰€¡CŠ‰ø˜o€@+°öËÀ!W2°hJÄQf¼:düþ…šà{RçvƒO«>Ð/}Ðhc{€6mÔÇÆ@]Ĭ˜õ£ P¾˜eݼÁtó·7˜|‘|µÿŸÁϔA–$àØÊי ÁT%à°ÔàOX黀™¯ »Áÿ¬>ø]4ß.#`\5ƨ øL™‚ϬÐ_šý­9ÐÖ,€ö—P×-¿RÁò ,?SÁü“ÿË@5–‚"°ÍIb-aŽdóV‚¦p£·'EåêBP™>0OïÿÐ]¦QM^[“T«§zYuQЪâÀ  Š ¢ Æ9! IÈ@¾ @ æ‘A@£‚(rUZëP´º¬½ºœE¯ +*È°ïwû;ýñüÞï9û]笇ظmÞ@èXø  ªo#Dõûî‰/àÞúÁþa‹ÿ$vÒløî¿a,ø|ÂÂFk~¹`WÛeµ0½ã;xۜ€·{!p .ÀáºB ²i+nü hkrx[6é¤Ïûá²?nnüÃ̀QŸ'q–-–ý“[Fö֏8āÿûhœ—=н€³Æøç€0È Dá Aåq1ßOö#pR=•³%€~ÈhÍþ@mß ä3@ê Òµ­@¼¦ez$‰|†eÐ[IZ؀ wÏsîü“˜*ÊCfýèVæ=zGÌÚ%v?íç&õçWú0ëæêeÖ ¡'öw³aO"¬ñw6êx’ïí ½ Ú Ã†9è<“³cÉXÎ^÷Oš×;-Ï÷U¢,øiBrÄâ3p÷Fòm^ýVì!æuv3û։ثÌó¼ËŒ>~/ãϸ‹Ì÷¼nÎólì$¥ƒ;C8ɬ™ û¬T7[àºÚ|©úõفa•䮛 ÆÍN…!ßFº½Ë#{½4°ýiÅ!÷U‘¿!º¨_¥Ù”>‘‰ñoA%»‡WÏíæ‹;Ç9-<þ$ê`÷‹O²DfÞhl<º%nŠ|TQG€³ÐÐ ÿwNê::ô>rÐ~®uœ.ö›;ZºmÑ`Ù.×W&‚ç£<¦ßïAȍԄȾD ¾W‘Aí–ç3ÏJJb;DÕ|³ IØÎo·òÎKŽñ®I›yO¥ÍÂḑ%¦^×H>ˆJÿŠ­’Ž3*dSä +Ù4ÉÀpµ1:?õ­,Ôy‹Ð7«ÜËásõ†Ùïëœ_ÔïpyP]y«”êÛWÀÙ~1GyF¯ÀŸÔ¦ÐŽ'XGÔùÜE‰ 6¡&¾ZÖ,«”žL(“ô %Ò;HiÂ{I 2Â+F,,ò…jB&)Ö&:W‚ún*J.º“âe¶ÓWÙ×{;¾iÚ4ïIsȒßëö®¸VIö¹T|Ö(ˆ0gËñ-ú$Z“.U—’íN2 +TUñ%ʹ iC +nE>rSiT½‘՟âò՟Ùyê zžú Õóíß¾§C7uÞ27ۉZ»¡¦5/[|çüÙ²íÛ[‘Wjˆ»Ê™ÛN™ø»[ó¥QMÙ*jm†–U•–É-M-š4åcR<7±U‘¥>«4¨¯©2“_%di> +35£±™šñèLÍÝÀA»€,²tÔy ]l ÊÕÆrx¹í»OûgæõŽwۂ_;ñCO=aCçAÆÖ¶2îîfS<®Ö¨ TæhX%™ÜB}¾0/­D’¥=$קUèR:U©)?«RµÏîƒH§û‹«ÓŽ1tÚñhkíuNšãÀ¨ùÎf¤ÙÍæõ ÛGkfõ›·,ºÚºkyWSÔ:s-=èhUì®úRÑþ*S¥¤ ‰Y˜—››#0d¤e”§è›Ié§Uêô+*•þ±"É0$NÊá%ëǘÉúq†5€ö@:g6š£t1f¦î_˜­Km^t¸ÛÜ?çép½#`á¥áË:á¼7R·4Ô²wVW °¥e2ra±š‘S¤Í(Èhó‹â“r+åªìF$!ˬ”eõª¤Ù”HîP<’3ÂSd[XŠì1¦5@€î ÙÙòæc bf¢qæ݉ŘÇ]K0·»WÚ÷Û4¿ët˜›¹ »öÈQrÀ¡FVXY_aµ„˜S©ŒÖ—¥pRK q‰Œb¤¨\&-¬O´+„=JAÁ]¥Ø4_8̗-,‰qŒi £çOýÆ +œ1PíŒ=ö fàÌ<Ìý^g̍Kv½üœ;φº¶žÚ»úp;iSe #ÔÔÌÝ“Û &èëZJMrŒú`:/¡2O_^*”ÕÊy¥ÇNi7Â.»ð*Åü²a^\‰…W<Æ´HÑ=¤;aà€f¤~.æaûl̽ós0ýW0}W–Ûuõú8™/l_Út.Ò³ºƒàWl¦ÿî:jòÊÃ~IH  ²("›ì ;ÃBBB’@aG(‹¢âVÔ©#.­u¨Sw +µ,ƒ0Et«¢VEq=žc= ¨£•bÁʎϼÇOýùð;ç~¹çýŸûÜóžû|}&G°³±P¶µn­jãéÍé¥'ÿ’Stbo~~́¢œêêÕՍ¥šêÎҴ껥? eUåeÏÌ>6‘® ÖS9ìšG¦‘g?2ɃVéù™Env“KÝ´³7üŒ®r­k. Ü^H +Ø÷/uÄÎsYq[[ 7üsbMóFuaÓ¶Œ¼ÆÝ9Y ßækê« +Uõ EÉõÅÊúÞ┆¡uý9©§&ÓÓNMitÁæùû ÉÀ÷tò°‘InŸ3 ×.3ÉÅ^9w©^SÇ°öV¸Õ‘|§ýפœŠ®”Э3¢7\X%XÓQ"ù¼½L‘{~«:ãÜ®ôԶʬä¶ã¹ò³õy²³í«¤m½«dmC9ò³Š–éTeóŒZl7$chäI-Üif+í ÒqAÎÞ3$M‘SØÌc÷CVöÅÚïê{n»­ ØЭ _}#/¦àzq|εõâô«åIª«JŕJ•¬«*-±«A#êêHO¸r—ò{š¸kJ•xñ£BrA7좑þ£„Ü­£‘«­tÒ~NZn2Iý##r¢ß’ëw×ÿöY°Éî§QÖ۞7<–{—7óú…”›{c··ôD¥­ÜÑfå†k”nNS¦2ØÓKÈ¿R2LH.$ &zrX艨³àÃY? +^Œø3C±Â \–?bY>.‡Ôˆd#hŒÝkìŒâyË°q¾¾œo‡oLlqÄd)jMlpÆÔ-:¡2Ø{›-O)zIHÆ8!J"†‰Ã½HXÑ>ƒ--Ît?xÒ9ðÑg#ˆá†0† ¸Œeˆe:@À´ƒ„i¥5Ò !—e‰–96±Ì°Ãpõ\€C†¦8ªâÝhˆñՇ" `Bʂ,ÚR±)ÓÌ!*²BÂk÷Ø þ;[ð«íÁ¯s@\‹#âÎ/ï’x7)÷Á¤üîÞ{Ê4æ<ǃ“.Ÿfàqèqô!ócB±‚E”1ä"SÈTæ,Bâ¦%WØ"á€=„UŽœ^Ájo›3âv¡›+øw)ýnà¿¡ü×ü) +>ùH™áÃmŠW]  fà{Ó!ñև‡‰” T\c¤M¡PšC¾j1de6î°Câß!>êQ­ D®Hhuƒ°Ã«Þñ„à)å5‚Qʤðš£L ÀžÀãƒîº@èJƒM‡Œ­”å ¤° ‰0†&Þj¹Tً‘¼ÖŠíHúÚ ²C®Ö¸CRç‰Ä6Äç½ ¾ä Q÷rˆqðÒ ZŸÙ„qß鄏¾ ðý gLïQغ|šAìA‡ÒCil2} fŒlž)2¥HÏ ®Y‰Ô_8!e·+”< 8“Ë!û‡¤­¾vúCòKÀÇľÀ™Ä Iñpðñ‡1ñ\Èh"G$ð–ÂwH +Ž.Hp¡AêF‡Ú•ŽLwò8(Xa„‚hSä‹-‘§^‚ìdltf‡'Ôß,ÿ˜rØw6¹&`FQ4%o™L::!»öAz;ü½ô׈Qɛ•o%ï¹CÒ¹ˆ7I{-GÈKŸ+௠DÎ4ȝéÐPý*êy…ÞL”a5×%B )mPëø1o­ûLö6ïɌ=~ãi‚Þ«…Ž¥Ô†&7rG­Qoå1ÃI×yC²‡üWÒWñ/dcüùlL¿Üg)¢BèCBt˜š!őŽ,ªï:飔Êc}€!Ê"LPÆ·À:™Í̚ §ñ¢bϱüM¾ïrþü6s_øæ`äkõ÷ÿc»Nƒš¼Ö8€Ÿ„MEqk­K©ëXܪêŠ {HÈ’„ì @ bØ ›ÙB-@"D@ÙD– +A°^µ£VP¯ÖöÖ¶ö^µuãÜ×ïùð›9ߞ3çù¿ïÌßç)­1à ŌyDêÆ>$ …< Ýù‘ø‹ô{“ú>pš}n0¡—• 1á[ n32Þ+øÔù»$lw€Ê}  êðb¨:¹ò»î•‚±ùX‘Û¯QòƒÏÄ)Gó²¼rŠüï…U`î0kq·è&üL¨…xƒÖOš¤“­Ôû”1ê ò÷Œ·¸Q f#ôêç@O[ a#²ù’O}k½Tmµ‡ê=Ž0ÍÃù}ډÿÓ­}‘BÝüs"o×£X©Ç}i¢ç¿$߁6h’WŒ»ÆÑÆØõäÑ°Vê0³+ô +sˆ~™1Íèe9•X”E«T2KãËØÅò^Qì9A~ÌE‘6fL”óH˜ÿŠ•¯ø@ËS@‚V±¶@ö((Cú^ò +dŸ!o5ê•Þõ¼n3úaÓNû™úÃKǪý]/—wtë˜ÍùüãÍ9Q~uqÁŠXžšN-Qå1‹’J8yŠj^NB³03¾Sœ?*ÖÄ?g$ý—“©zš©„$ÎŽä é{êåæ­°ôsðòìð羚P?¶l³›lúÎe¤Öw]O~{Gý€IÇ=VŸákȉŔe&ti§¨§r˜¹©:Nf²ž§Q…©J‹8Y9$Q)ïJRR^†«ÕïèêÔy²:âm<$ò¥H–X¸|¨\^Ô¯s­«Àæ­v-îK.O®íªÁ}ݪ§í7–rŽVëÄ>åѝVAÈÏN¥fgf1ÒӋØjMOuª^˜¨>/NPJâÔ·$Š´?¸IéïIéóeÄÛH\Ì@è\Àkƒ ø¥ÙÜëX +¦:¶ GÛ.î5y¯ioÀnm>KÙW£g®(žÔKƒò‹âñÙɔ4m#%'Ÿ”]ƍϬÄf´‰eýiÆ´$:û7ž<ç-3.û#%. lb$ ŸzoöðæÌb0[·Ü=·Üê\&:7¡;ö/êj;ñE« ³¥¾¼W_v¨¤Šï•_U*є(ÉɧÓèŠB-K^P•åDjωÄÚ^±H;)–äÿʋ*|˔|¤Jó Á‰d!ÙÉÂ"ð¤ÒÜ5.7Í ÁäEg0ri=ª·{ßÂvËñUæÀMÕ-ÄÝ¥ ‚:®gvÄ_cˆÁªô‰Ä„r5-¦4‡uFÇ—xüb“€«»$ä[…Ü’ç\Aé?LQÉGª¨l2d§‚¿ŠÀ=ƒ˜ivÖ'pµoèÿÕٻǩåâѕµü7”·ãwµ†Ì6qŽišD>ªYP|]>º&…Q*4…q«ô–¾™ËÔwóèú £ê‡mø›Á©š§„WB‚-PŽ¼A†˜;ƒ?ÔÚk«#étƒö {h5h»âæÐ0ph¹¾×ÇUw·-§“ú¦ƒuHy^à×å/;,1©ðüæ +»±0”i¬dҌ,Š±‹M6Ž³ÉOÃhoht#$1êaˆ-0Ñ ¼Ôp·€ÉF;0rÞô]²Ãö mì3`Ûfouw)ö^£ÄlÑô“w+{™ßÊ/ñŽJ»#¼E]±þÜ J ˒BïÈ'Q:*(Äv#-¤½3×>ŽxJ÷¿!ÛaÉ ƒm©Ì`ú,ß· AŸ ,ýhÐrÕÔO-†©Íè’ëûi¯ÿ~%æs0ɇv9-€t9ƒ(ÇaŒxÌ@!p`ñ9¿Á÷à l °åÏ,n—0a ßŒ¤û™†ì@Õ”Ývº;®(ííݎš[G–%Ýô];ƒÛ1MÛοÁÞÞ Oʾ£\O%ö¾(wà¡Æ‹¥¼°fÂdlà‰fGì§ÚmÚršÞŸ~‹nÐü^BL Ѿ"4› I\‰ðdLC÷pfb˜ˆcù!™Åƒ5R–lOhÙî0²ÝP¡E‘ój9Nhà8b#¶ØMÀN› ŠdBËB¥ˆgC™b…ÔrÍDd9CVéI½;Äö„hód¤ïðFúoÛ¸¶Oðõí®ú@p‹ê£žSc>âÿÑÿk“˜Î ᳐E©¦³¡N²C¶Øªì‰P¸@^ᆌE­œ égސlçBòÕˆ÷ù@|Ø¢<ˆ:©ËS!ê¦RƒÔ¨/Doé/þG Þ[1|lùï ²h””fº;èÓ U:A=Ó*Ë$(j=‘õ'oÈ×s‘Ù背f2öN…ì /d~~C]ô‡ô'ê^¤O©aêMÀ)^ÉàÿR¿q|m$‚ y$ êr¢Ùȋ³ƒAàC–rr] 3»CSãõ2.TkyPþÅŠ~ÈÚ€¬¶@ȏA~Šú6˜¶ÛdþJõ‡¾Î +Ï|:’‰Ða9‚‡äz‘…[ gBƄ>”c8¦i¦8 0à ù:W‹=7ß9õ>Эòƒvc4ۂ nAöÞP¨†Au,â­òläååȗŠ›Q£Š¾è!ÅïÑ¿)^E*ùT…ð'*„ d#d@ýGÑ4ÁL‚X( aaV4æD{˜%1K튢|OÌå"¿ÖƏßæ­ y³%ü¥~Gä¸nwô¨v?DsdڐúTì õ…¸ß³Š–ý`F¿êùŒ¾ì—ñ5ˆ} EÌ=¢zõˆ°òºƒ&L´ã•°`‰dcn¼=æ +'¢\áŠÙyž0—ù¼.©ö+\2lZñb憘ç†ÆØg¹MñOs¾NÐÿ=ɪíHéӞK{¤¹*¸¯¾+¼£y&¸­O¹™ƒ„î\Äýœ‡ØÄÜ0þTAt¾LÓÞiñ£½/Œ±v¨NuĂ —7óužcżsæšëÂJ>æ?.\ÿ0sÒ}ãöÔ»y»ÒÍmßÎ9,¹©?-íÖwÉnèog\Ó?‘]Í}oDÚå|$u™0ãRâ.`ú» ¡ïÏ÷aÂÌ¥ùS™¨¡÷¨á .Éá͇瑲=ž/4ñúç[‚–/Œº[¶$þö¬•É¿¯Ü(Ü*ºnÚ)ý1wÆ÷ÆòËƎ¬K†Nåw†ëÊæ=RvÎÎ<[ñ7Eœ)FÊé$œ²zºƒ".Ú5«é,uL,¦÷Xo?²Tè4¸8˽o‘Á§÷ýҐžªù17*êfühiH½Rö‰èRéF酒ÆÌóEMŠs…-ª3‡Ô§L§4'L]Úc¦;Ú£ϳۋßd)…øˆ‚”!…J~r}˜Eóçý§oÑY–Ð{|Æ_Ëy¾"űo¹Ìíî2ý”îú¢àkµsù—«k.Ì_œÖY±B|Ʋ.ãäì͊cæíªöÒ/5‡KöëÍ9P|>wñϹ­%úVóKeëd´Z n)‡€J{Œ4·Œæ/ ÷#/x ¬ +b}Íî_›`ß»FìܽRÍý¡Á|±~vLç‡U §kêÇ,“´W®–ªøTy |«zߜº–Ù_çì);”÷•ùŒq—ùc“ù‘¡É2ªi®@Vs%dM•}Q ỐOsçÐüÚ·–ÐYVp¯Öø3? c>ØËéÙ tº¶Få}i¥1è\CiÌÉÅóÚëÞú`±´márùÞkU{*7iwÍû<狹_æí(o3~n9‘ßhé2mµôšþ:oHßXÕ¶ÿf»>£šLÓ0?Iè‚‚Ž8X€UA)ғ`B(@¡(ˆ =j¨ÁjèAš@PÔ((²2눸zÖQÇ 3{fËŠ{vV|÷ýçÇõû>_îçûNnü…MF˜»*Ä1& 8¼µxxóæot~ |ªÚNøµÎŒð¦ÑŠ´Xç´áQuëTYÙ­üÓö9É.}|¾gWF>UžVJoO©ò“&51›/×'ô…Ö&ÜàÔÄßçTÅ¿ +«NZ ’¤ ßÚ4D•¤#/ÌC +ÇÏ¿+2T¾Vk·Âró·ðRº‡¸ÐtLg¦–¼åveàî뢰%1Gz ;ry³r)R~1½)£Ü¿>½ŽY“ÚƪLéa‹“¯…‰’&ÃK“—ÂE©¿±Ä¼u¿òsèæ->‡¼T¡ÜC"Þ{٘p#¬WÀ¿7ÁÛ Æ°ØnAœ“:hO6zIüw V°­zE'í:JâÛ Ó9Uù¾ç*Τ‰%ÁIeÒÐQ'Nt=ü´hû‰/þÄL¬@Œ¤ +ä“TŽ¨ªPî![ –˞ד`¡]tkÀô ¸5°®]µRëíwҗ]&okîô7—ÈBŠÛ£ìK¤qÎù-IÙM”Œ†­7Þ9±'ÕýLW–÷©ÎBŸÈŽrß0y£¨L, +’M1e?0Y²~¡rDãÈ…#CdUˆðVð—€&z 0Œ·_ÿ@Ç]=h»»‹ÐxÇV³r⸁pÜÇD0`Æ¿Îޟ:esöZœÃé¡dçè¾÷jûJ•¥h *d¾þŠAC1…½bø)VO(¾P˜ýÈ óTµŠ{økÀœànÀÞ~ýx{Éo¡eFêg·CåÌ5á='ݼioãs“~¦)wC,âïD쏹k5‘t$ìÖ9ǐ›— ñ27ÿñzOß1™7ml€â36Eñÿ|blՋ6Š<è£È•~WõN°P0-¸Ñ  Âù7š§HP5¯ ¢#(^ØCÌ}l¯•ñgIó´­q‚LO΅›sž²d?8{ øÏ&`V`ǘ9Ðfê©32gòÌ ‹÷촋×ìï™ÎÞ÷‘#ù:JžþÚR%Àì€ñn€+Wqþ œ÷gåC5(~¢Ù/õÿr!õ…µZ í˜çƒÈçƜ%¶ ëYôÎÀgñf~ÏÒ÷Ðóöù,ž·"/Öò|&³öx6dã¶tÏÖméG·ÅU·§ëÖnߣCnO¾6ßp»`  sçãýY9P´@þ -HUÂYå.B¬ò )RyL“£ôØÀRÒ7*ƒ71”[hÊÓßP•)ÛÉÊ,SOeÉNweÍn×å6s—e……óÏw,œ~^´p\þ·…ãO¿›;¾CdòÀÐe€.|‡-¸ƒŠ{2ž!aYb3‚¨÷»œ÷V¤à÷öêþï]5é+ꊟ®÷J¨¾çJ”Ûê™MÇWӌœVóŒ}(Ûâð¡ñûÛì>o;¼6kb»öÎÄöãÊ6ە/úÊî ßa+~*§pþ<@úÀéבk:Àù¼‚>ï ø}ÞK¤­ÛÈëŽêëî®_|4¿økC¡:(rƒ:£k‹Òô!þT¾Ñ +5ìCÝ–è†á^ôûÑpZÅ>}¥w ½Žóñ <H[ˆÅùì_˜HȨhÁ ™\Ñ~¢:L:ŠIvÈMÍQÔ"†º +Ö°Dáš{PŒ¦9JÖڍr´w¢2í¨IÇué|‹†u¶£© &è9öæ+møªïàü‡8ÿ)@ Îg)èk¤îHœ‘EÛ vȜ`ö­ Ñòÿd×YTÓgðþˆŠì;Av‘5&@ $$$6!²)6Ù7Ù, à€ŠˆE*n8R†A[EQÇ}k=Å¥ã©ÓŠÖ­®Uq‘Ê3_ۙ›xñ;¹ÈÅóæ}¿srpig0 b’òÉ´A$Ó +ñZHÕ2E¶¶1Ê´ ±JÛYèeéc€¥‡ƒÄÈ'6ŒPTÝ9’•¢ÒI~Ü’ý”¢‚¦(ʵ€ì“ÌáFæpÃö [83ؘǰ„'à hðiCӐÑzˆ¤u±ˆžŽ%ÌiÈcj¡’ÉÄ&v&½ÄÎO€çNÃ߃†Ðƒ‰`ÂO B Jðπ_¶.xzà®Öǂ6p¶‚³“0‚Ï~b˜8A\4†Ïuâñœxg΁ÿ3üƒOü>CÀ|Áó™x\-ˆ…,‡é@˜0êYà—êï޾ë á»Ù¼íÆàõ{MÀ;H3÷œ)¸Wˆ;¦à=%ÞÉwøÔ/Œ§x0þȃ‘&ø’|á<BæÎD¨d,Hå:Äτ(}‚Š XiˆÀctš `«)ø»ÍÀ$˜ƒÄþ§‰ËÄ- ø?&^[€?iñæˆ >ÌÞÿÉTüÝhˆ\H>æÊD¸§”þ,„Ku ™ YªBò !®2†¨ÉÁmæî¶@Т߽V"þi áEkn°§ٓÂWì÷Âì·B°_ a5ËW²ÐÁ\R'’ïH#’ôݘùZXÈc!F¤ƒ¨](ë#,Ëò2S„Ö›C¶ÎÒMÖÙʆd·Í”dpöGñÛßÄ#vÄgí&ÄWì߉îڏ‹ux!žpx.†ÝS lŸH`ó8ìG!°Ö„`gr{Qv4bÉgمŠ£D¡)t±0Þ1&ˆ*4ŸŠ¨±š _c3ÖfûE·ý;ùv‡7¡{œ^‡îu~%;4ç¥ì„Ë é·sŸIÇ\IŸ¹>½Ÿ{7s~–Ãé¶c +ØÝRÀV$4”³ˆeÓPͦ‘2‡‰4/-¤ñ§!E:‹£ >&¦š¾Ïµ|3Soÿ"j­ÓóˆÎ9O•=®Ãw¹ý60ÿâ÷åG=ïÊ/xߑßôþIþÄûÅ;ïÃávM ×+˜3 çï"ᨠ¡¶ D[1`Á@*é»ä&™ä™äËD3>¤+õߤ©L_$«­ŸªŠì~YTã|?®Ñõç˜V÷±è.¯Ÿ¢z}nFþ•s#bˆ{=b˜wUyÚwTyÕï²ò¡ß¥ˆ7Ü Qð>³ áv&®§cᢠa$7ŽôÞdÒ;3,È!7É#÷È÷ўÈLÏ Õ{šgú c ûNÚr‡“ËçÞPÕ¹_Khößȹ×Íû&v‡ß……ýüs1ûÎD <}Ip"ú¶àXÌˀ‘Øß|Äƒs8žÃ‰p'Ü4!â÷Î¹„t¾l2K %Îôd©s¼ÔoÚãbɬ»Ñ&?æ$³¯«3¾K/šw)­Úó|ò*Ι¤µ¼“ªÿã‰=GíŽ :PôuÜiñ¸ïÅû㟈ö&LîUÁw( œ¡dx ¥ÀC¢Iîb’¿Ì€B¾ …R2Ó +{ƛ*WúI5GûneЌ›eJãÑ¢Dö¥åéNg³óÜN¨Ë½Ž¦¯ä^Òäw0µ5ð@r—p_R¯hhñÉ j_Ȁ꘴?ñ²lwâÙî¤wÁ}©èKƒoßpú–Â[bÉ RH~6é[EFV˜Q“µlƯuNŒûõîÌ×èŒV+Œ.”ÇYŸ*Ns:šŸív(·Èû@VoŸºž?˜Ñ,øréÆà=Kº%}©;¥;RC·¥ Ë·¦œWô$ßVô¤‡ô¤Cؓÿ/ÔàMˆ7&wУ°œ(#³ÔQoÌ©G³©±¿¸0®6úN»X'3åZõñˆõÕȖ¬gaks&%ë–C¸>üõä_GTä·«Iß+&ªgR¯VéRZfQ·6èQ£mvŒó­>¬ã-"ýƒ–{ë9ôצÍÛU™åÕ[^ÈÛRZÁï*^ÔQØ$ސ¿A¶.o³¢9wGxSîß#VçŒD5ä\ŽjÈ}¤\?!m,DPSÖÃO’È;ÈÒ!oQ‡z½R‡[3º¹~:õ¯ö™Ô7³©S½´·éío³hŒ³ßUŸâÚ»RíÕ]Çí\QÊo+¯®/]%n.Y'k*Ú¤XU¸MYW0Y›?U“)ººàaDmñ{Ùg¥ՕAP_¾&¤ýç²(T°¨ûõLêf ‹ºÖ¦CnšAÛlMÛä¡õU»`Ö`«Ü|wóB»mMIs»2<;?Ëån¨-ö_[])XSY/^]Ñ,­+oWԖ~¡¬*鏬(9]Vrž¸UQþ.´rÄՕÖT¯ iääiQo«hjl5M]_§M:Ï4êÒç:ÔÉ-–Ôp÷|æ¾®ÝþöP³í­Ñ¶[ZT.k–zlX½ ¥¡Ð¿©®Bаò¿l×iT“Wðç}" a‰Q‹(”B @ؑm( ‘‚¢€"Š‚"PYdYŠ¨ˆ(.PÅjg: eÚñLm 8§§ËÈ¢õTEg®Ç™3=a>üÎýð~øßsïÿžó>9 +½f–ûí?pfÃތ¶ Ý=!)÷B’3&‚wüÝ7- •éÙèºï:«Ã­ÀT~!3ß·…Œ”1áó ײ ¿~\­·btžqÒj©ñZVWdx¢,Ò¬¬d‹°èX‚]~a²ãáüt—¬¼,÷ŒÃù^é¹Ç}w:œ}.()»;x{öÄìB’ržû%FeÊT¤A¹:Œ']Hxœ ðuE:À€áÓL8˄ëM|èj2§Û$ì†Z%ÿä©ÀÕåÕá&E•›­óËâŹ¥;¥™ÅiÎûtK+ÌóL)(ñI:Z㟘ןח7¼5ïQp|þo~ ¨Ü^ˆŠ¤B”«ÃD&¼Øð}€ê8™ûjh¸]πÍ4\nåAG« ÝÔb¯yºÑWYïoP|&lmþ©M–95q¢ƒU;öUì–í.ÏpÝu<×c{i‘÷GÅÕ~[‹bŠ.n.Š.zSüÔ7¶dAW‚Šm¥(W‡I?eü½àϕ@:@ÁÍF +ºÛ:Îë@Ëycª¶C̪nsÕ-9竟ßj”s6Êü@}¬pomâúÔÓ)Ò¤“ûä 5‡q'>Vn©ªôÞTÕàUyÁ?²²? ¢òë€ÈªŸ«æ=¢«Ñus5:«Ã€‰r%÷jú®œ8OfŸæ.-¨»lHè²a–^tætz/ÏéZ} =b]Zëf«ä–xÛÍ;íã÷:ƞ͒G7(¢êË=Âëê½Âê:}Bëú|BêFÉ:íV7ç^‡òˆ:”©{–Nºxàó +€ÛµW›:?y›OæÏ^T]ׇÒ^+FÁ5);§Çƒ—ѽAO×ïﺴÉ4ñBœU\çۘó{ì>ìȔF|rTÖ^æÒ^çØvÞ= ­Ï# }Ô# mJØ6'jE§àV”ªû‘ÜÃHÀ]r×.’;h¹HæO2ÿ•õÓpl`)0¥²?µcíïWh§öù-Kºjðэ¨÷c¯ÇšD÷&Zn¼–*øàêQèÕ<»ÀžãÿžZGß+2ïž[2¯žQ™÷•)'Ÿî9‰O7Úû^F;uߑ.> gÐ_ÐEî µ“ÌŸdþ+¿?Ā¬ûÚpàþØ{߆‘ü™L3ñž—NÜpóp„~ÔÝÃð; Æ¡wRL‚†2,†ŽXû– +½km•ƒb÷Á>±ûÐßÄî·§Eîó¶îŸ¢ !T§*քðñ!ô‰>±¦üž8Ð^“®LI Åd𗩍lÙT,Çq*‰+™N׶›>¬³~ºLW4Ó g3s‰'|:DŒñÓÏx‚Éžà ê©»ÔÐDÞa5é`áÉ¿°‹äÇþ | è9ü_òÁû•!(_™SŠW"Úy֑vœuc8¼öaÚ½Ö½‰Ô°y³…e=·c‰å\º¦ù\Ût¾‚m2ßÄY·ÐÍY»pOË'´ŒçãÍÍ-ÒBÞa éàÇýÿËßò-ÀŸÆ|P¢&(Pœq%HÑìђ¡ˆ¢”¶BWÚ=iS `¬Å0†F3 1¹ +Ә+ñ°Æ{X®±YËñ2kY|üu‘S—Žõ‘þ}ö.?æ@È€çOò߁ä2ÁµÁù``AöaŠæ”1 +©5¸žZ…ŽÔJTP+Л^†4#h=Œ¥upÍÅ,†–08XKt0ØØËÐÄ»‹“75LòU$ÿ;€àxü ™#€€0Ç%°uÀ—ÂjÔ}4„åd/KÑ ôP@領ÒF)ÅAWJ½) ¦(Œ¢ˆt"¬ ê‰öEÐƖF;R!Ž"²Jh¯`¢8€…¶—  A­ÒÙhy„ƒǵÐâÑH´sÑüqè'î*.ZŒ‘o¿ω7rÐò,þɖXÑèD8ÛÐ(³g £œ‰?ÚE,Añ66Úîá 0G …Å\œ êµQÐJ\ ®·´ÑúY¿ ?ψ×r„ȝÿ/j©ÃõÖ:YÐèB(È>\E t‘1QîÍB§0M”ƲÑ!Y í2¹¸¾PÅäèÏͺ(îÐEQÑK è¡èñ ñ£ŠgôijºoĨ;K¼£ÎËÿx¡,(”›RèfB£Òœ0ÐSÊD% ݂5Ñ%šƒÎ;¸è´_ótÉ߸Jkx(i Z—¢äÑÃG‡>b˜áÏ9<æÏJ¦ø/$/ùÏ%È&Á¥Oߒ"oæ½?B§·ùÆzQèóo®Ë3ªÉ4 Ãoh""£‰ Ušt %„„ÞB 5@B ‘¦TYëX8¸VÔ;zгë¨cûXÈè¨<ûÎ?—×ù~ÞÏyïûûqY«Aè:5[¯¡tMÞ¨ ¬D`f/†ðð¯^ 4…>ÐÚ üz¾ù }¥Ž­ú‹zÈø3uÒøõŒñ<õ +qŽz—øŽú’øš:O|Iãç~`üÌV=¥Ñ.hÖ`™ t "ð7ÊN ¢qQTMˆ ֆ›—AH†ç¯ü$2øĪ3šl5žcî ~è[ý>`Äô-cŸéÆÑ5¯éSfÐÿeþ‚~Ëü ý¹Å#Ɯù}Ƃٽ0½Ã“ÛL þ— Ƌ†B°çF cJ€øµjˆûHÀ}Ä1—@LIJÏQÉz#rô߇¯zVMü#¤ÁôÅ•Ù³àn‹'A–¿³F­²­}xÜæ·ÀiÛ»×íþøÄn–õÁæzЂõL0X^ÛæW6ÀšË!`º`áÜðU8ߐ‰øŽ4|ï3¤þ-¦5Ÿªó.!qƒ§1ÄGQkîGÊ,î†7[ßÞ¸ÝæVØN»ÙÐa‡¡{×ýrÔq&ä¤ÓՐËΗBî;_ yë4öÕáìF°=Ö§#ÀòTX`Ì¿6àÜMØ{ãW"H7BÀÁdÛ²]Ôæ²¼5_g.}ʎÖ{šføk"Ïäf|±ùõØ*ëk1õvW¢Z~Þ´Ãñbä.çó‘#®ç"¸ Ÿt?>í1>Kúgø ÉÈO.Qàx,ìÅ€ÍÑ°^ „`3ÎÿÛù8úxÆØ»,ó|Â+>Iýq®ÿ’»Üð峜DÃöÓK©–’ËmÎ%Ö8œŽopšŠks=±¹Ë}2f€43J>}ØópôIÊ¡¨«^¢~÷Ú3GÞ ®ãñà4žÛÅ@„‚xì{ìåØ;W`ç2@_ŠV£·BkÂc¡³Ú"_Íù!º—y±†ç³Ù¦§9<«ŸØB»É4±ã±™Ëáä&÷C‰íäý ½ž{ㇽÆâ÷{ô‰»HŽ»GŒç5˜¸@LׁpH‡Å@~ƒ$ì{[0||GÑ +ô±Ô=/7A÷*l 7Ê)—ŠYºçQ†SüÓɜ,«#Ùö9eNû2$ncìzÒ?ÒZ×ïNÝá5˜Òïӟzw, –;XýȒpÖð>úIóÀ«–dY>¸-’–á-Ð\!B÷Eݔj oÕBWÚhº‘ˆN(œÔŽÈ}µ÷ɂWŽÔDû+“,z*2m;ÊxŽª’B·a¹±°†"4øÖå«hR~/C’·‡)Î;ªțf•çÝc‰ò?ø‹à]Y뫊À]²HÑÆ[@èY1B¿Vaß©SG—šèB³:Ùj„&ZÔ4y/Ù#g­¨‹$öHÌ;$l›61×±¹¢Àµ¡¬”TW*¡H‹ë}$B%M\ÔÍ(/ÜÍ,üÈ +Î n½§—ƒOY x–—‚Çb íï- ô;ßÍj„®ÊÕp¾:£ÔDÇUè°ÊŽ0®ô\2ÔÌÔÛÙ¾ªckœY›,ͦ©&k\Âw‘U“ªEbÏʊ:Ÿòò¿’²NFQé³ ä ‹_r*(¯äVP~é[† |Á·°(B0ßl5ôg>B¿U t]†«‘€Î*Õщvut´c%Úß±–0ÒNÖêkc,ïl 3R5n^ÓԐb]¿•ãP+Ëu‘H‹ûd÷¥³³|&3ùeæûþÞ#3ï¾0ÞÊÊx«’=©öKvçH–å»ÏÛUì=kç¿i;m_’ë0õptò¡n.ðÈ>¸Ä'³n…_Zmé}íWŠÄÚ +¥®¶>H[Û4î@o¶Æ¤ÐÕ`€®ýGºLspf=À1Zƒýe_ïØLýRsŸî`6ó`aË(˜ßâËÌnQ±§5Çñ ›õ¢üSÙ≧òí²›Š3›æJÓ¾ýÐUÿí_Ü×zŽküÒ;¾qolc½oLcéó9aò‰9ŽÞ1 è5Rk)íC:Ì{ ÀPðõWžXÒÂÀÜó\(n·†¢vW(hdòÚDzsÛµÜñíé‚ ãDQª±Ð:Ù8[¢3.²O0–8ĵ}êݶYÙ¶G¦1Ö»Œ5]ƶõ¹D´š\"ΡKø÷Ô¼‰ÎÁ€Ê +€­Õ§þ*ê/= 0· ð"&\BÖ¿l!£ÃÒ:‚!¥#š•Ô‘ÄÖufq:'óâ:§ ¢;#;?²ŒèüØ:¬k£XݵÛ&´ë°$äF«$¤«WÜ1h|í‚~ú£zó =¸}?ÀúÃÔo¤þê¦þ çô? ±Û´ÝnÐ3b{˜¨ÞXFӛ̊èÏV÷åsBû¦sƒû>à)ûKøýk÷ þ÷«„~÷…òׅòþÇByï ߎôyVüãÀÇæ÷?Kýv€‚Ë@ïx ö¡D?•€æ™ Ÿù€ú¹BžG0ÊqLà‹dÆ0‹%Ìcù Mc{ ½ÏöxùgŽûËu7Óv®‹©†+{uš+}u‹+5=åJ‡Þpñ_›ÏÀA€ÕÔ_Fý9¦\Èèw`l7@Ø0èÊJt€tôT€ªa4F1n¨ed˜Æ8ãÆ Yö8Ÿe‹bI°”eƒÛI Û›É52@¿csÀ'´ÿ?2÷ þ5€ôŸâîP»@ñ` ²ÀEԔPÓ\ÑœÑ Ðì1l1 l0¬1‘±ÄLFˆ“>Îb¸¸”a㧠ƒûÀcäú/ç£ßjÊ׃Êw‘JRCŽ“ä,¹Hn‘¯åƒ“ßï‚!? ’ÿ†šÛž Fz0åEüY¥f¡&žƒá\TOáaÈl>/ r¥*× Qù…ÛD¨('U¤Ž³DE³åï +£å°¢Óò¥¢Oô\ù\ôDù»è‘EÉùM‰Â‘0ŒúQn ƹ2ïÎà8_BëÍÆX=£&òP3]€ …^"°O,ߨ×[½VeõJ½ÓÚ¤ª°RU‹UGÄ/Tâgªs⧪+⇪nñ}õSq¯ú¸[â{j´¾öVwF@¹/ePëÄ`}¦Ð\¤Ðzèi=u\Ԏçc|¡Åpì<Ñ˘¥VtS°~U*~µÑæQäVÉ@d™íoš}v÷5uvýšû^ÍûÍ¥Qw5¿Žº¥y2êFäkûŽH´»…¶Wɕ(”›·aŒŒú€z{ÀtG³h.ÆÓÉR±0#Ž3œšÊ{‘œgñ$i¦å€n‘u¿¶DÒ;nµÝ½„ÏíïÆovø%n‡ãí¸=N7c«oÄÖK;bOI¯Ç¶Ë®Äޖ]Š}$»7,5Æ£Sk<:žOÀQçÐþû0Á‘Ž³-õmèHÓ8&É󼜤d½ÌÕ°Ÿd'òdåXôdYÞI›gs3e©]§~…õ¤5NW7HL4¸\ÒírýA·×­][ëÞ¦m}^ûÇ9íU3Ú~fݐ{S"º6&¡ìd2:ŸHF'âø6ÔQ7úÙtï̓Мº©ÐyT bõæÇq~ÉËtåæ[]͙i{iüB‡öÌåέé«\Î¥•ºMÝ8útêæ”2¯&}•w£þÏ }“ïqýùÑä_åGRžùJEϺ4t¯KG×Út”Õf ôm˜LÝ,+zºwN¥qÛ›éNðx†ôLdnG²*Òó/äZµN~Ïî»Ió[rËþMu¹G5}žqüI•K„@H &á8L¼  Ã5! !!!!BÂ-DÈý~A§uØm·γžÓMízº®ívqw—HEêÈӒÛÕÔ«|­9×Â0ñú‚¸“¡µÜ;áFîzx5÷OÕ¼×ðQQ€ŒBägÌC$kPÊû¾|½sKM„gZ;ø¸Üé>€™°  ·›.=·w¬$Ñe@Éqï‘ó<;ebï6©‚tU¢!›Å•ÔFQ=­.¯•Q#ì©Œ…U"t‚G¬rÁ V¹ðMˆNô¿“ú|D­#2ÆÏ”fƒoà+)À ì;Ÿi ðDok•vpßà‹a¶2Ôv\wzÏ`Y¼s·:íP{qŽG«2Ïˬù6“ëd:jÔH343ôâë!ZñHXiþ\„:ÿ!«$;²Dü0uÁÏt–Ê𯟠ù[ƒ8?^á¿Ûì|ØûWáAµ ,Õ€9£a²†i;d8åУ;Ð^žrðjiÖÑ&µÀ«¾¸À·F¥ô7•QõŠ*šVnbh +ÛCJdCáJé,K!½)—þ.R.û>¼Hþ_†R‚T +DQ!²5(à{îA‰½W °iÀÎe$ÀJæë÷Á/©§Ûô£wwT_ÜßZÉþ IŸq¤®<÷xu™Ø§B£ð/Wk(¥%•´’â†RÕ"W„K‹¦Y’¢{‘â¢O#ÅÊoà T?1eÅ(¨°Q0dkP6¾ î¡;Î`͈½»ß"vŸ™&'3{Â@x½1ÊþZ}ì¾&ãe·ºjÎá*÷˜¾BtB«/ôS——PTZ}¢¬Ž.+m –húÂDê©¡z™ÅW?ä«¿‰–þ›)*E´ü2D—¡kß~[¥OªpõKfì]-ã­{`°õt·R‰m-»Ì泎uñ.UõilÏR£Ð»¤ZJ*ªRÊ%•Æ“¢Š¦@ßÊÓM„çèîFdë>aeë¾çêÿÅäé-·Qù(Àšw€—ø=|¦ÃÔÜkXhÅރýk°}twK™ÐÜfWßvzoUkœ³®%ù ÆœyTeâ—7J|¤ EþùueTam5-×hfäÔt…d֌‡¥Wß ¿RýóUXz͏ŒŒ”eDL€5Ïø÷ðÉû;h¸‹çÏ´Œ`íê!@[¯+˜{} õ=LÛª®_9”w^ܧîHr+²pËÚ¸ž’V‘wÞU9)·ECÎi6P3Í&§©“‘Ú4œlºÂ6m„&™þ’lúžbB©&fBdkþ*Ã=à[\ŸÎÿž?ޅÝ;`ë@ãð¨öÃðI¢v0ʾd ÖQџà\ЛvPԓ}„ß-<Æí’zg]/&q:+È© Tv{;-±}„ß¾À¸Ô¾Îˆ³¼fÄ[Þ%X%± ‘1~Ö¼Äïái%ÎwpϿэ;èèh˜0L9‚nê(h¦(åT¸máäiñxœ“p,م7šq0k”8}Dâ™:¬ôbé|ëü. Z. QÎÌÆ<Ƽ¢Æö¿ 8߇ü/ô!Æך?”á êV®ÜÄûà°ƒ6OTÍbÿœ·ƒ¢7(\ðÉ“˜7mÇ»uÞ!kî²SúÜçԛ\7ölþ¡ÄYőK3Zϋ3µ^±Ó×Nœô==}‹3½F:5ýŠtjê­OÌ$:ñŽ™@^Ö<Ãwð ß!îïß;Š;ÀjœÃþµ ]®îþª'pW ™«DÎê»”ÕK»“î¥ìM¸—µ/nExàŠÌõܲæà™å÷SË­G¢—<¢–ç<"—×ÍbðnV€¾Å>hÕÃÄÖÉ0¾-<Ûâm[ãñ8—u{\Àºrˆ#?’óZ_#É3úM/âeÈȐñîo ewbp‚š8S-Ô]ƒYÔÄr¨NçÐaU‹y¨,"_“M|Tn'U¤šÔZú¾Ž\&M¼aåSހ²›×¯àúTÈë%=ÿÓýOÙz{½U z9ÐgªIOë1!€EÝ4ª1…C×¹z. 銌ÞéÖý¥ÝhÔ¯-öiw {µû…=Úákí a—öœð¥öº°CÛ,üC÷RøD÷NئCãò +Gõgû§„s¯ùY‚g.¶û/1nó_nÚâ÷•è‘ﳇ¾ß˜ß7ìwÏ°_Üd8"i4œ’Ü6Ô[4îX\3<³¸ìÛoqÉ%ýP|Áǝ÷CósïÁɔ;eàT3À(ª#–jšnC±îLo´7ÓÌ> åµ„¥ †Î3¾7%_Ôü…ù­ â›A_K®n”^ ,·¼PiõsÀëú€c² ?ÉÎ\—×´ÉÏtËN¢õ‰ ´¬ Béñ`”ñhD¹SE”oOu̐&Ê¡'Q Ï<™Ö8æÁôH®1&ÉèFT–é•È…æ?G|&¹^(=7µØª.¬Dv6l³ütèv›S!{lO„VԆœ´û!ä’òûûªšÊÃaƒ¶ÃP~`*Z«êp”Ž†¡æ€Ó„€qtîL¢:RÍ ¦þL•CsŠšR|˜I¡¼_ã„ÒEuq¹âÓ±KOÆ,±®^&?µÊöè´uŠšÈ-ÊѪƒûª#¾wü6¢N½/►*♺2ò­jw*vE¡ME4ʈõhn +ÃÒµ³ÐŸÆƒŽL#ø#ÓZ3Äp'S×2'2õ¼º´há©ÔÑñä,ÉÑď,¿›Q ;ÿ¹mu\‘ݾé«U{¦¯w¨ŒÝæ¸+¦ÊigÌaÍö˜Ë£¯¸lnsÙÛ§.›ŽöeqhW¶D>FŽô`  }À£lîåAÓ¸–mstÌÙl®6+Bx4s†èPz†dÚ\«½©yòʔŊŠ¤BåŽÄb‡òÄõÖ›5e Λâ«]7Äw+¯w_ÿÈcmB·KI"ªK’PU’ŒvÄv4ŒæÑ tÒ6×L睦y 4,àÃõùB¸8ßÎ,pcŽÏ7p5¹aFrâD{ç̔ìž=ÇjGæù¶Œ|Ŗ´ª6Ï\î¸!uµSiÊzçµ)å®k’÷º¯N>ê±*éœveò]]qÊ+÷âÔaMñLtX™†*b7Æ2€)Ô:óýF[\ÃB:ïäqP¿ˆ?åY@íÇÎP“çÃU/œbT5?F´37Y²-g–UYv®|cVž¢töbÕÚY…Žk2‹5ÿÊXë²2}‹Û—i•ËÓ¾Ó-K;ë¹4íÖøÂôNíҌA—¥™¨^6 í‰r´‘uè› ÐšÐHùW?¡wý|êò98™/†#j8¯g«> ì̛fúÍÂâM Ò-KçeËKr?R|•“¯Z•ý¹ãŠ9Eš¢¬5.Ëfoú/ÛuÕä™Åüÿ†²$‚FÙ!‚@èn”ª u lJA@ö5@Xö­YE#¨ ¢à.`ǕxZÇjUl«ÝFë2©ŽZ;s¦nÔg.õœ8g>ü>åäüŸçÞû&ïu)ß1»$~¿»*þ¤‡2~DVÿÐ]™ðÊY•È$ÅILLl'báoûpk¼9Àù@[D;W‡"!ö+í°»HÆÛ^à««Q¶ç†Mm•G‹š²Ìê3Ó­>Êȵ­NSÚW¦V:–¥¬u.NÞà¢LÞæVÔï¡H:.ËKº$ËMºï‘—òr–"•9æ§1{b7‹P¾Ï.ÓÎõ‰8E¯Cä`‰{JmÐ]âÎiŠênT¶„«¦×åśÕä¤XVʳmʲ ÅÅY咢LµSAF«K^z§›:kÍÐQ;‹k«ñÖi¬Z2E]±\PUnZV=CUœ`Q¨J·VåÚåª$YÕNéùM.)ù›g')v¹'(dñŠs²8Å]ٚü»&ä3§Ä&I*`â‰FÇga¼4g˨”}˜öÏ=õ@W½:êEh[+åšêæè¨ÕïéWÕ•V‡š(«¢Dù•ñæ¹å©VÙerیÒ"‡Ô’JiRqì5ªM®±ª·åhå'*o{D«þåºZŜb‹™„ˆ'z”|K}øŒjpšvÏAÊß×H{WÐA¯¡­ëLÑØlõ:O^U“niC€aÑÚ¡¢nå4¹:vfæGɖiµY6I5â5Õå’تz§èÊv—¨ŠîÙ++¹ETœu¯¸éQñO—•Lºª‚9DU0ñD÷R€/i?¥WS (»·èl£üõÀÚ BÔ¶Û rƒW²~>¿°ÍoJnë +㬖“ôu1¢ä¦D³„Æ «¸…mÌÚRûUõjÇÈúõNauÛg}PwÀ5¸n˜|ï¬þÅù5s U3b7ÑêÃ%z†©Ctÿ}­ÀŽvÚ=7õ[€*J5Pjfqùoù–Ez›ƒ S:B‰›¢Lã6ÆψiO3Úk¹¾Ø6¬­VÒÖ*YÑÚ%]Öºß)¨õŒs`ë7΁-σZ˜Ã²f&^ÞÌl'ú–~“þLÏÁ êÿ!Êß½ÐPvK'í^Ûe·.=ӑÓ#Af'—ÚíÃOìЏÛl³=Rµ-Ö4²+Y֕mÒYd±bkµuÐÖfÛM§Ø_³ÏÞOsÚa‰æk‡%[FÅ~›ßØúmf6þÌz¢‘ñÔÒPýû(›h§U¤¾(¥Õ(«Hí"yŸ5öÍæâöÍåE÷/æ¯ê_¦ÑfÚm¼7A¸|o¦iàžÑÒ=•3ýz›Ìõj,}{û­Þí=eíÓ{ÝÊg÷¨•ÏÎ7–>=ÌâÝf>ÑyzÓ  üÊßLwoÚTöÑþy€ö¯#@ÌàD Š°rH‚ˆ!O.tȇ<´TgÅ`°nÐàJý€Á8ÿÁT£Åy‚÷ʦú 4˜.8ºeú¼£}¢¹GOŠ¼®‰¼ŒŠ¼¿yb"¯ƒ“¡¥u°—ò·î ÐÝkh+: d ±´‹†žæ°lX€ a ¼¯uF€vüµ¾Üm ·HÊóÕ~¨³P›¨;_›­7W[<ÅK[gðí&COí#™ö„±ÇÙ¯Œ<†Ÿ»Ÿ~#p;Ån'™p¢c4û}”¿ò×S¾šî® Ð?K;è9¾õ0ÿ’ æ]²ÂÜËÎð¾<^W|1çJ Þ¹Æy^YÍyŒ¤òÜFòy®#Õ:.#øÎ#»øNW?æK¯~Á—^yÊw¼4¦'ùœéK.N¶Ÿæ¯›ò7R~ýA „îž}XCÙáç(ÿà{ðú’ÙßÀéÆTHoX@zS +ǛžüàCàp+ö·WC|;¶wT°¹ÓÀYßíä,ïâ,îžçÌïüƒ3¿õ‚3ÿñÌnN¶“úßAù ”_z ÓÝ×|Jù”ý>eû|¼ó5àr°¿£ ÛBØ<˜«‡¶°xè óGž˜ùhfüìÑãL{Ó'é0yZLÖA8Ú á³c<» +ãÑÇ0~2ãŸÙ$Êo¢üòœaÊ?Où”@Ù ([ö@z°ù0ÌÃÌçF=7…é 3˜¼°…𥂗î0zå ƒ×‹ ÿz9øcQÐù- ¼7ÅÀö́²1jîØ5ò„Œ‘ßþ«™ò+)?W $ÐÝïK¯ó(ۍ²(Ûâ0ý`ò +2=˜1 ™ ô™|f Ž‰æL<ÉB€ß_ý!3zøýè3:£B³‹äÞ$Ք¯ üDú(â+Àÿ;`.e»þ °»ª3eÓэ)߀z„Çøô]" &DD,‰=q!^d1 !ô¢Ìè‘5.BCÏNMÂÄ´[:8¿eçÊ1 OŽM[À1“Ž "8fœÀ1Ã3(%u¤c[ÈÒKö“ŽM9AΒÏÉwä>ù…¼mµo0îÿ’8qLJûå8 ÃƍcæÞ›áGg ¥³Äñ˜0‹¨H YG6’.²“ôÑY“cä ùŒ\#'£ÜÁ+q/…ÿóâ?d×yTSWðûÞK¾„!/@Ô Zª* ,²Ê¾…H€HXHØÔ¸ ˆ¢êТH݊Š8µmµÚ©£ãîà^ENµw~ÌŽžÎŸóNþúÝ÷ýÝûr€ÝÅOqþw¢)Ð^/  “(sÓHl—CbŽÔh&±M+è_€°Ãà<ñÞæŸÄ8ç ñšó–xÅÁÄKð‚ƒÉç¶ÿK„O>ÂŽÐNÈcÊtÈfô' ú“HbG‰ùÐZdACô6ò=½“|Gw“¿Ñ½ä8}˜|KŸ ßÐߑ¯èŸÉgôcr”?F>âcò!S˜ºîMà€§Aí\„=íàiOÈc†áOgØ#ˆÀSbH¸ýØ5—|'.¡ÆÅ5ԘhõZ´Žz%ÚB½µSÏE]Ô3QõDt€£‹NSEW¨»âGÔ-ñÆM1füìŠ×ÁOà¸úì u?³AxáÙ„}aM>nðۓÀÞóˆ÷žÄÛO“É_§)©çS ¨'zê±ÇRÆCÉ*Æ}I ãžd+ãŽdó¶äÏÌ[’}̛’~æ?$'™7$—XW<°.z¼6º0€sà;pv*f} τú¾–p¬-ö·†#k +€,æIÐøœÙÄKŸ`btVù`¦ŒºóY.uË»„ñ‹w5ó†×2ÖU¯&Öß½6]òÜn|ѳÓøÏ“óžMF<MÏy~ozÆë¶ÙI¯fCÞ¿›ðƦÇÁ€76ù#ì uç™Am„ƒa¡G‹ÑÓùÓÑý€¹Ä-ÿâƼòò\%ãÇ9ZÖy¿%FçüjMÎú®0=í»Öì”ÏfóaŸv‹o}¾°ø‹O¯å O¿Õ€Ï)«c>׬¿ñµ>èû›Õ~?lùµ¶èóÃæûü°ÙÇð\¨Ȃº „Ãa‘h<‚ž„ÓèN¨;º: ý-4„ ‰£Î˘'¨Œ‡™Îכ Ö[ 0Xö4[ößÂ>èßa³ß¿›óµÿ~Û}þ'l÷ú_°ëñ¿o×0ÆÙ'([wb+`Ù5ÿ0ñþð¹Š@hl‰FcYèqŒºe®F9¡ Ñ3ЙèâÛ¨(ÆñÈ֑p…Éá°<ó u–}¡•Ö½¡KÙ{BVq¾ +n±ín³ßÔÉí +Úë°+èogÐY^GÐ-º=øw[¶k ÅÀÖ[?‚0^õcºŸø_’t-‰…®Ä›¡‘:•èçýñaŒqñFûbe¦=‹²-º£µV»£Ê؝‘Õœvk¸íᛶ…No ëæo ;(Ø6ì¸1ì'ǖðgüõ¿;¬Äö͑ض9 +Û|ì¿/‘=‚ú7SºœŽÐ…tú>՝LµCÒOÐ!él¢/5˜Ñ“c´;)Õ´31ÓbG‚Úº=®ˆÓ[n×[ÇÝcàm\ÔL¯_Ô&XÝåØÝ'\=è¼*ú¢óÊè 1ïø†Xì쁭! ÞBwaî¼²¡ó0óœÎ$Ñ°œ‰³Ñ¡ 1êÍð&ºåT§,Ò¨Cšhº-MfٚšÍޔ¬á´$•Ø7'V94%6Ò«ÖVÆovZ¿C¸,nKCÜQQ}܈¨.þK]¸c]"¦ë’0Ø»Iûàiq'ú AýþR„úàúÕ :J™¨µÔm(sEM¥^¤¡ÄŸÑP¼Ð¸¶(Ƭ² Ų\+g—j²m‹óµÜ‚üRZ“W#P« BUîQVîW…ª×-SuÂ=#÷*x!ÊTc'… ”jLÞ¤Q8×'ú •ë\C÷T"Ô ¶ê ÔRÁFM.ÈP1hÐÏaÔ, 1ª(‹6-+I²ÔédìÂâ,[MQ¾½ºPÇSV ² +–;ej׻ȵŸ‹eš=nRÍq÷4íew©ö™8]‹…²,X\€iÀ›ôPŠÐ%ô28Zû 2¨ƒ À˜×ÔX¡µN¨¡vQSãK髂X¥•‘&Å æZ½Ô:¯\ÁQ-QÛg•9(J+øò’F§ô’uÎiºí¢ÝW®Iºcn‰º‹à©(Y÷»SŠ ªÃ¼IwàÊyÎÁôàpB{ëa4ÂÜ· ¡¦„–7X úFU7þ‰(o˜E–42 ëÍóëbÍrkS,³kälEµÊV^UÀM¯*ç¥U.$W4 *Ú\âôÝ¢XýqŒþ0ê«ÿ¾ë4ª©k ð»3€!ˆ„A4¨(ADqž—óp—U«Ö©½Z‡«­ +X+ +8"8Kl‰Uk+“âÕ.DéÕÚ:¬ÖZÀ«uÀ}_»Z¥þ¸?ž•äÏy÷÷í}rÎç?hžôL1+¦'Ǫ¦$Å;LZÞ_3~ùPí¸ecŒ^:A?òÓižÃ–Ìñ²8Ágàâ~ý³üû&îhÚ;±ÀØ+ñœ±Wƒ&½^úõI>äÝ7AþR9™ûÀ°ï{™¿u{À±dÕ*`}œªÂ¬4=f¤15½˜”©x/µ‹j\jÇÑ«;ø|¤vØÊñ †¬œ¢øÙG û­XèÕ{E²wϔLßø”m»¥nÜ5ålã®É÷ýº%½ðé–$ ݓ¤W÷åoçÁ×óy?²ÿ»8ŠlJeҁ¤5œý29ûeïg»aÂ:_Œ_„qëڋQÙqÊáÙ=ÔC³8֐9NÛwíûn½×ÎÒõX³À£Ûšåž]2ÖxuÊØjˆË8ä›Qæ»úgClús¯¸4و<ë+al܃½¬?/ ÈböÊ, q=0›³èDŽGcr5™ÛÃó04/ƒó"ÅÀ¼®Š~¹}T½s‡¨{æŽrì¾e‚¦ë–é.ræºÅå,ÕEç¬vÜœ«ï°ù GDΏˆÍ÷ôáŸëÃ7H}øzéQÏIÞ¸ï;˜¿q-¾Žç€ÙóriÛ9îâüÇѨŸÕ }¬>èmm‰žV â­±¢›5^t±öWt²SÆYÿ¡Ž¶NqˆÌŸí‘¿X–ŸæbÎߢm—¿_Û6ÿ´¶íž*mè®ç®¡;¥k莿+àÈgÿs˜¿–µ'ç ·³vöÃ÷}8 ®À±þˆ.B”- ‘¶8DØz Ü6P„ÙF ³m¢¢­m–²m‘ªµm¥ÚdÛ¤²}éÐêh‰º•Í®nyä™cà!éxP:Õ·çn+ó³9 +®dí ;¬À¤ýÀH΢ýl@—ã@‡“¡…„éѺÈÁEA0[T‹V%=вdKÆ Eé4++J“DÓÒu¢I©UøŸ>%üKïˆÆÅ¿+ü +¥ÒïÔTÙÁü ÌOÍ–°ï³¿&3{ÇÑþ_3ÿ[桧À«à_î ß îð©ðwE .†R¼.uC£Káɗ†•Óàñý"èÿ“÷ËÛ¡»rœ®AWY ÝE ]…º ombþjæ/eï?fíSX÷hf÷?Åü â rh^øUž?¨¡»åÝmw¸Ýñ¡fp½íݸػÀÙ>šª±pªšûb¨í™PÙ­P؋!ìv êIÀþÖæ/ßÃ3x˜ÊÚG³îþ¥Üÿ³@ûïS`üð¾ +诮·—j'hjÝàXëU5@‰Â¨#ñ¥¤†ãÞø5¼ékxÐk¿ ^øñ]zB/ÞHfþž¹Žñ,d~Љٖ‹@«Ë€ÿO¬ý&Ðàà|P×Ê:¼t^¸’;5âo +¤¶@] ðªñaôŠë\‡ä:$¹d‘’–wÞXÈü鮹€NR]åÕïã%žü±Š§ +RJŽ:çR¼p¾„§ÎU¨u~Œßœ%¹Hüª•x¨•â]²…/d ²…×ÁϦ¯{̽‰Ÿj  ©ç~¸O¥9Ä^è’D.U¼ÔeŠçºâ™.O<ÕíOtûÄc µºBTëÊñPw÷Ük`w%î襸M·þt³ÔÒ䤇lÉÏVìGKž‹f®§#dã¾<3#ÄKï‰âwï™â‰a¾¨5,Նâ‘!]üjÈ¿rÄ}Ãvñ³a¯¨2vÃ7âŽá¼¸á}[üèS-.û¼R\ò•Š +º@åï!ÌnӀ\!CuÄ~´a/ZólEâY`<7"Œ¦Š{ÆÙÂn\$n—‰›ÆÏÅ ãq͸AühÌ?÷ˆËÆŠJã Åŀ2EyÀuŹf¿)Ï4«S–6—Êb*¢B:UlË|³ ¤Å 2œëçšÚû Î܏ۚñ0¤#ªZ÷Å­àâ§à âŠi†¨4ÍUT˜å¦$Åw¦Tå9S¦ò¬i“²Ì´MuÚ´WUb*P™ŠÔ…¦JõÉàêcÁÏŽ¶–­¥ú~‡ Ó2W ©„Œá:b\Qíêq¯}n„EàŠ%‹󖱢Ì2YQjùPYlž¯:e^¬úƜ¬>iNs8aÎr8Ö.Çñh»Ž¶vûŽ˜O82ŸÓ0ßÕ|aù¯Æj‘š|‹tÚm‘Ž¯íªGF8BFñ¯"xÞY º³ª;ºÂ£ÇÕ¨&(n‡³1PÓO|3Bq"z¼ò«èÔQÿt8õ/ǃ‘KœöG¦höE¦ÿé2 jë¼Âð‘Ī}Eb±'{¼Åc\jl!ƒB¬!„$K€@$6±Ib·Ø±@Œ… Æ8ÂÄX$vl'®×Y&‰ÓvÆíL“Ž=iÓ&“I:MÓÔmšôö43ûÇ3÷þ{ïyÏ9÷û^ê+b?uU¼L»$¾L¿(¾Î8/~›?b.ü†±”JÐϤ´ÅT‚ºJÄ> ‘FþIÿ‰ l€Ç +|,‚ßKið #ޖí‚_ÈÒà¦LAº–YB e"®dÔD­±G_’¶Åž—vQƒéÚËéãŒeÉ sI²ÀZ”¬°OKBœ€äÇ/yȝKÿš3›þkFJ0§¥}únö3‡ÑƒL̽ø{T€¹óçƒ +¼Ÿ÷røð†r\Ëý9¬çf’W•” 9e‘AEEôr¶5öŒ¼‰º ï ²z˜þ¬!֜l’=+;ŝÎ\æù2×øS™·ÞÌ‚ Ù‚ñ¬ï¹cr‚0GåãY)kXÿŸPû!æ¾Jî«îEÀÍBl½kªd¸ J'Ÿ+RRΖDž.0ÄøóÍԓyõô™ÜÆ ¥‹5©ìçÏãŽçLóG ‚aÅŸ!Å5¡Gñ®h@ñ™h@ùDЯ$¸ý¹a!Ì0ÿ÷à«\̜¨ÿ/÷ñ¨»Ü(#AḦ́˚Ͱ¢y –4i¤Ó¥rÊ)uQäL‰6ÆWl¢zUúDQs´°=\ØÍ,â+˜ôçÏ {óƒ¢îüxwþ/\ùœÿ: >Âul„æG<Ú>G~‡¹ó=<òï˜ðž„ðýr9‚º8£ß óz1iV—Iñ•çEזƌ•¨Ã3ÝSZÏP·°ûJ\ܞ’¾»x"ÎY|RÔ¡ZŽoS­'¶ªî&¶¨>Ij)þ{|K !hQ<‡šà ì0ß*°èÁ¯õèAÀ-3æ^d­ hŒ…E“ü¦í0cJ!M¥”ñ£ÊÈaCq´G_Ní×UÐ{Ê­Ì.m#Û©mçv”õòÛ4£B‡fFÔ¤YJh,]K´—ÞN²i~»É¦ù[‚­ŒÚ´ß®%¸'Ì7؇Ç€1wÞ­F0w]©Å¼cXªŠ¿™ÓÕ[ÁkN&U&VfG TF÷˜4±nãQZçÑjF»ÁÆn5´r›õ]üFýÐ®óÅ×ëkË/'Yt·6Õè~ƒü5±Fÿ_¡EO,‚g5Ü0_ã.|\Ž}ÀºßDýWë1÷Úñ®Ïy+¦­ðZ·À¨u/iВFEtUçG9ÍêØö*=ÍQYÉh®¬c5T4sm&¿ÎäZŒ“ñÕÆ@b•ñbR¥ñÆ&“ñ#ä«Ä +ӏ¢J!@xU&‚æKîöþ>zpu¯6¢͘7ð9‹×o=Fl›ÁcÛ ½61Ù]ŸAé¨SFµÖÇ4[Ë© – +†­Æʪ­näXª;ùÕ恸Jóq‘©ÊŸp´ê|’¾êú&]ՇȗIzó"ƒ™ˆCøGÍ/Ì_p…3øúu×8mxßÇ 8ل™§‰ǚ¡§y¸šRHíéGƒ"²Ñ^m³—QëlFº¥¾†Y]gçTÖµóLµ}q†Úq‘Î:— µ“4Ö×6•ZßG¾HÔXÿ#*³qeµ_k%xa>Å}ügð6Ö¼ú—:Î:1wvŒâw ´Ò »MζmÐ֖Ljn=Lnh•GÔ; +¢­-¥±ÕÍZe³™ijªg[¹ºÆnAYè°Ô>_b9Qe5©Èþ^R¡ýs|ÿ^¤²‚b;ÁGxaþ€}xçà&Ö¼Žú+˜?º1s Çð[Ü®hhwñÁá~Ý{I6W*¹Ö•I©væFVvǘ:Ë©†Ž +zy{-«¬­™£nsóŠ[‡ã +[gDùŽåøÒ­ŽÄÁ­dZ–$¡EÉ,¸”,…siœJ÷Á±ôg˜ÔÃ|XHæCBr<(dÍò–s r€Å뀯ó‰Àhf'07Š¹!™_ÌüRÀãÐâ¤å:ØW˜ÈƊ¶°«ôƒ¡2ˆúB_}Õ(ØVM‚®* 6U« ­Ú MÕ º Me´åâä0?ƒù©›É;Ï‹€ÄÌgns­e@‡@›Ó€s%`°½¤„æ²-T—MP^q…âŠ7äW;AºT÷á†(ŽÃÑĉ¶ff>X×xãkU@íc^_“ø “c?‡ãž\È÷p/0„ÙQÿz:ŸÚU­ÎŽÃe@û+ ¿n:Ô¤n™€ßZpCìÉ͐7¦Ý€›3¶ã!Ûñˆ/þão)¨caë؉ºÀïÏ?˜Ç±ŸÊڏã×CK€þìswöُMö>´ü0U³ïµ€ò&³ïЃ÷)yoïcêÍÀ“ÖÀÓöܤû¯¸Q}ÍE¹‹Ñ.>o9á¼Ý¼ÛG윸öÁ´ÝÀxÖ~ØQ`³»Ÿ:±ÏžWXûÀxƒ}¿Í¼{ô~§çï½ —ôš5i`MÞÚ󞬉ð"¿¦C‹àFQ°‚íl‡`á‹.~ œ¼ Ì<_šÈà ¡²@€ç]„Q }Fãi +ͦ…”IÙ´†6Ò6*¤½TL'éÝÁ;<¡wxËßÞPß-ÝÙôÖl ùÙ¦-„â/ü¦õ§!ô9M¢J£%´œrhåSíaÖÞ· ¯q–%ºÉRÕ³doð”ß6zò'D+7·l9º²¬‡­/„6BÙBÏÿIhêûZ, ¥´’=ÌeB3·2³ÏX‹'(ar9‡íóç!^ññ¸ßH¸÷„»3DG¶ÃÂÙÌz´‚pèÀštÐs1ãE;w<öêˆ;A¸Þ&WÛ ÆE÷‘8ç>Uî“Qá1§=æH?y,’NxdJÇ<²¥2uÒQÏ-R‰ç.©Øóì°×iÙ¯›²½ÞOeEÞB¾‡v½Wøá§jz•­ä/Ã+«/ü xàã„ëí=ñK{+Î~†rK NX†¢Ì2Z*µLŠ-ÉÒ!KŠì€e®l¿%]¶Ï’%ûÁ’#/²äÉ÷X +ä»|ö* +}Ž)vú\Uló­Slñ}§Ì÷ŠM…bc#ß?4esZ à4ÄéþÕtU£¦“çü\qª³/ÊüƒQì]â¥}þŸIEþcd»ý¿”úO‘ï´Î”ï°¦)¶[+¶ZW(7[sUùÖͪÖÝê Ö#êõÖsê5þ÷ÕÿôoPçtêU]„*»‰²™èÊ60ÿ>§´k½€‹t&TŽÊ Ž˜QÔ?wÃ÷ÝÃQØ=F*N”m %ß4N¾)h¢"/èÊõ_«ÖÎWçf¨Wdkr6h³vج Øo³"ð´nYàoºÌ 6ABûm°ÐúcùõÌ¿ÉåîB$ÏQÀñ~<ó„)p0ÔEaøW¯ÎØ‚üðHiC¯xÙÚ°áòܰъœž_(³{NV­ ®^šªÉ +]d“²L—’k»$d‹>=¤H¿(ä˜aAh­a^èS}ZO¡#›¹=…vn˜Ð4ݛ–¹jfWpj/Äs'Ï ?FJØÓ׀‚7äGúbCdr#ûH91²•ýåËûPfö£Ê蛤^Ò'Y›Þg¦ÍÂÞiºù½3lÓz¯2Ì ßh—¾Ë8;¼Ô8«÷û™½ëíRú}J_¡#Ò6{Æ܎~fþÉÁÜçó췏×ÝlËö:lŒvÁژȉ醕1aRVtYFt¼bñ€aʅýÿªšß¼&-j¢ö›¨iºÙ‘©¶³"Ó )+ì¦G¬7N‹ØišqØ4%ò¼Cräcû¿G ;ғî=›FÿáøתâYžûöcþPæ'p¯§FnœÙñÞXoEF|ˆ”×O¶ v"-6QùÍ ªÙÇhfLÒΈIÖM‹™©Ÿ=ߐeœ½Æ41z»ÃWÑ“¢«èCRÌ[cÒ@a [Ò5{Ì砚}>•ÈðÜ÷Ãî³)8÷ú +|—`BV¢– ñÃÂÄ`)-¡·,5!Z>ëÓÁʔÁÃUӏÖL¯MŽŸ¤›7]?1n®Ý—±öbW›þ»Åq\ì>óØØró˜¸{ŽcâìÇÆ ;ғm³û|/²ÇÙÿƒ#Y.õÛh=?góo™ÃŒX<¼5æÿ/ÛeÔä™Æñ®‡Ö ©GAkµÐ¢ˆÊ!¢†#@‰ AåðâÐz@TªBt]O »®°µÖZa»Ý]ÇÚ-3Ýum«µèn­­Õ~û×êL§“ùÍ _¾|ÿ÷ù?ïû~ψµi¯ŠªÓ扫t‹$å©ñ¥))2kŠÁ±89ǹ0¹ÐՒ´J‘—T«2k7¹gk[=LڃžYÚSšLí^í &3iH™$¨²’%QùS™‡èû{Œý Kž·rèÙ»œµ>¯5é•Ø`‰:Ãd¬1ÌUæŠKõ‘kÆR‡âô$iAzºc~šÉ97Í⚣[©X®«Vuî†ÔúÔžé©'4i©ý^ºÔ›š4Ý#ušNpK× J¢æ×â?˜ÿsYÀIjËöç³çËe¿C?Öå¨1ù Ê4«LÓ±Òôº¨Ø¸P\µØ!?k™Ôœ©sÌÎÌr2ò\² V¹A¿Z™¡¯w×émꔌýžÉÇ5Iú‹^Zý ŽÔIzÁ-Y/(‰b˜kÌÃÀیû8µ²ß(b¿Áq£¨1;£Â¬A©y<¬¹/£È,²˜ÃŹ9‹$Ù9 RSvŠ,3Ûà¤_nvI_^,י*•)¦ nZc³:ѸÏ#ÁøM¼ñ‚&ÎøÇûêx£à–`”D1̧ÌÃÅLžŒ»‹Ú¿·²çbI¾c­¨°HQbQ£¨` ,È-˜-Ê)›,Q’LËR}~’,=?Ã15/Û99¯ÐU›W®HÌ]§ŠËÝæ¾ÄÜîkîòŒÉ=O®yƘT/6 *¢Œ5 Ša®pݝ§' ˜‡恥ø.–Ÿ›8VrVb±ªk}9%“`* BfI¨H_²Pœf•¤Z—I“W¤É–­09%[\âŠKå±Euʘ¢-nÑE{Ý# ;ÕEç<]UGþàQ(¨" ed æï\ÿg¹ŽSëµÛVÍk€zŽeÔçµìr9²*¼a¨ðGFå4è*CD)•á⤊EâĊx‡øòéÒòLÇÅ«r­*q‰*«–/,Û¤œ_¶[^vÌ-¬ì,ùÔ-¬ôž*¬TPÎ[É +m¥ ¦Ÿt3Œûµ[k7Ö²ï!%uÔçÿµNH­õ@rÝXh됸vâë或ÖEˆc떈cjµ’èÚ iDmŽlAÍ +§ðšÕÎsk]C«[å¯WQ„TÿYR3 YsW²Zאªçœ§'J#Ôo§nË ¡XÝ‘L¢m!®Q‰%#Û41MÓÝ‚¨¦pQDÓ"т¦qx“NÖhrm,”¾ÖX! n¨wšÝ°ÓyfÃa— †^— »Ì¨¿ã¦Â¤c>˜Øᇠx±c&ü;æb|Gü:1®S±ùÝY‰Q›1²³#:ÿßÎáÛñµÈ÷è‘ÏAìsø9‡š€Ýô|Ûž‰Œ¹ÌÎÒ©w Xг=|™}鄓ÀèÓ2øv«àÓí ïîqðê~ šî xö́GO4Ô=Ë î5Â½× +·ÞõPõ¶BÙÛEïE(z¡<ó”§(O=§Þ·Ð÷zú]ɸ-ÔÖw "N!§©ß ¼ÈötÔ;€æ<àö¾ ®ýJ¸ôiàÜ7N}“àØ7²þPHû£I2$ý9÷—CÔ¿èçƒûÎp¼Âñ;ò˜¿°“Þ7µqÐóBƝIíÄSÔï¡þÛôÿàÿ0ò"àñ@ù!àtIÑeà²ñâKo4pe" ¡WX²0û„/ã#ÜtÜpLòÀò.ùœÜ#?áo0ï5Ìw1cÏbÜËz©Ïxƒ©;…º~Ôõýà~ 3 é'þM®J€ÿp×T,†=/^`Qî|9•…Y0ÈyÜâËðüÛ\t·ß$o‘>r|O~|FÝ!žÇüÊDϵg¹/P¿d¼c©ëE]Õcªû¹An’ArKĂܑ©øÆlÈX î÷Y,?`‘ø/ƒG|ñàb‡hôE†þE>{F)×[6S•DÏ£¨̘.cþ xò6o“>ÕýŠÜ&ߦw -CÁ}1µœù<%ðăÍ=&‘Y„EºÀy<Œ…„›N é Î>Cp Ám49qÉ42‡,&©$›¬ Ud=ÙLZțÄN’rœô 乎ŸqOð?Â/ ý +Á“ý­z%qâßx:)$„D-É"d©% d+ÙAöPg?uã1º¨q +ðâ¯x€«´ékÚõøžÜ%w~…àíAãE?4ô‚t¯N"³È|G҉™XŸyñë8ÿ&>y;uvQ§ ?àuŽRã8ŸÛƒoñ>Õ?ƹpnóŽAþò+ró7Fx@ðq§nT¾\ü9æCô41$™±©[À§•1žjêl Îfê4ãh¥Ž:©Ó…/éÅu¼‹Ïñ®Ë<¨É;ãß÷HòæTê}Pem:–X5 $p 1$Œ$"B<Šâx-ÞJ=pQ¼ê¹žÕjkkÕ¶êV«cÕÚÚuWÇíÚÑm;Ý뻏«Î:ýã3¿¼ï̛çúý~Ïó½€Û´‰oÑ7(S×韮W™°Ï_'Û}Ք%åCC¾P>"úQmCTŽÆoB +~•ZðïÂC¾ øjü«Ã]¾ßóóñ¿·ùøFҊ›’6\—lÇUÉ~\–Ç_¤çqQö¾á¼BÄY¥ˆOU"Îü1J±¿”üà F* ö!ŸzR}ºÀ/Ãñ£&4ø›ºwÔ|£öãkuWÕa\QÏƗ긤þ#.hVãsÍ|¦ÙŠsš=ø´Ó1|ÒùNwþ'#ãøk"Žuq¤‹Èþb Ù€ç $?¢ø-2z÷Áýîƒp§ëÛ¸Ñ%Wºæàb7;>ïæŹîU8Ó½÷˜Žz4âÞÍ8Ù³'z®Åñ^m8ÖkŽô:ˆC½Oã`ïkØ×çŸÌî¾O˜]‘"³ãÛ_áǘ®Ù§ƒéØ÷1¸-ÇÝÈÎøºO$.EÅù×Çà“þ&œêŸQ…8åÑèEOÁŸ£g`ôf_ôBfOôræ½ï2»lav ØËlp‚éx‘ixŸm‹ù7»1Fd7ë‰w_AB> ¥«'–®ÚÀ ]ûÃ8\ŽQà|L|4hŽ¿9‡'ã€6{µ6¼§õ`§¶œÙ®­f:´S™-ڙL»v.»Y»„ݤ]ÅnÔnb×kwr­ÚÃܺ!g¹5C¾çVý™_>Tä–-È¡ÿG<&»w銿6ø‚ZÎY=ðñ[|0,‡†Ga_ìpìҍÅ6 [tyجs0›t%ÌzŸmÕÙuº:vMl·*¶‰[ÛÂ/må[b·J–Æî—,ѝ–.Òݒ6x,m!Jæ?‡Ÿ÷ +OÈþ?Èþ­$Ò[F²M|@¿Æ380Jƒ]£ûb«^‹Íq£±!ވÖø,fM\³2®]WʶÄUqKõ“¹ÅúiüB}£¤Y¿HÒ¤_%§o“ÍÑï–5êO³õW„†¸‡Â̸§²ñ¢”¼ÊO£¨%Rë¥kýLÍù™À!jy{“Io$(ñ'ClHüÖ&ÀÊ$–%™˜¥IfQ¢mNôpM‰åܦ$Š2BZó +â©¦P ÌÀ)Ҟ‡s=´n#ڌ2´¦tŪÔh´¤Çâ´1hNMaæ§f3sR­ìì÷NŠ—Ÿa¬ä§C’°1,­36 +µÉKä5Éë¡äe0ùj’ñ¼*`¼§ +¤üG11EÙ«ü`®SÜgÉöññÀ~+ÅOëfz^—Áb¹)K2ú¡9sæ™G£1sӐ™ÁÌÈÈcøº 7_k*“Ô˜Ґiª¬:½A¤/”OL_­¬LoWU¤P—§ŸQ—™î¿*ËL¢¼,Ch•½ä>åürp:Ÿ´>»iìØBëzòeE6él šrú 1çM4侍鹦>'™š“ÃÖd[¹P¶‹¯ÎòJY•Òª¬É2Ö ¡Üܤð™W(½æ6u‰y¯¦8ë´Æ“u‡øEåÉ„œ^òWÚ(æ“6ҜN`g!å€XK- ù5?O…Yù=1#?áño¡vüÔä™`¾™ äå³UyvΟçáË-RŸ%(óZÂB±e®Â“»LU”»QíÊÝ­qZ>Ô8,·;9,?«y¢Â™'ʝQxÉ·T÷ódë8ÙÜGÚ³£˜ô±²X@~Í*P`š­¦Ú¢Q3a‚6=¶$¦Òfb+ +rÙ²WZPėX}5 +²Ö .k£Âa]ª²[׫mÖ]šëÉNVëMâ_j«UTXEù „gܤ:œ![GÉæî Ý´-^šõ]4ë:¥¨u¾†³&¹´¨rD…ÓÀøœiŒ×™Í;¬œÛáâ ^‰ÓQ%µÛk›}–Âj_¬ooUçÙwj,öš\ûuâ±Úb•„‚Â3¾²Ð^ ¤Øw–ÑY¨ ÍGãðâr`¦‡ô†›Cµ»3ªÜ}Qáye¼ž1L±ÇȸÝfÖåÎçœnowKlE~©µ¨FÈ/zGn)\¨Ì)\§Ê*Ü®6½¯É,úŠx¤2‰Js¡¨ ä„ðŒKtNRöSìÛ*©4~®$š'õô®ºð—jà+텒Òx|ÃQ䋃Ë7Žqø2Ø ¥¶ t7¾ÔÍ畖Kr½!Y¶wºÜì] Èð®Q¦{;TiÞ£êTï—ďªÔQ‘V"Ê_ <ã3:ïS öPìí4v¶†¨“¹´N¡±ÜOï½~%ÜþnpUFÁQ9ªF¢ ÊÀX«Ò˜üÊlÖRiår* ù¬JŸ$Ã?IšîËRýóåFÿ*ErÅVe’ÿˆ*ÑI•XñP™T!*’ÊE9!Œ{Á:‡©;)ö¶`õTҝu´i ’/>òÅ”aB0ÁHŒ½¼¹¡1șld²B™Lf(Ÿ5…\Z¨„O N”$ë¤IÁ¹2Cp…0¶º]<¤ˆ^PÄUÿ ŸôTˆŸ$ +ñQö’S”ƒýoÙß&Ý7h"i4L#ÝUOsƒÜ: ²ë{Â\?™áa0…G!=œˆÔp:c ç0ãÂ66)ìa õ~nLý>®¾ñ¿\—yT”×Ɵ°Œ3,² +ʦ0 ‡'Æ-DkÕ$F­5O465"¸eE© 8€¸ÂHÝpjÜ%Š±©§‰&*.ÚTÓ¨(1Þ> +&©üÎÇ÷÷y—{ßû¾ª¾™EêÔÌ +9³^“œÙ¬Iθ­Ižÿ³&9]hÌéBmž×Á^îÁ]ôu õKY²+Ç¢ùVæÏwÈÛdX¶'†äø!-'¯Yã0ØÚƒ¬ý0Àš†þÖèg#Y¬¤Tëû²Ù:Ga²f)’r +”/çlV&æ¸TƜä¦Ò˜õXe\*TÆ%¿RÏ=PC_7f1³&¬àyÈeVr¬âì•Œ ƒódô³ia±¢¯=©ö¤ØÍH¶÷‡É>}òßBRþ8ôΟ,í³$ƒ}‘o·É½ìäX{­c?&Çؾ“cò~RĬäv°‹ywÒ÷RŽ@ùÔ´ÚƒÆ`5÷GÕQk×‹WÖI%0–ê‘PCi4âKˆ+MA/Ç@ôt C¬c4b嘆HGº;ráX/us씇¥°ÒëRغv)´XH¡k…üœ­ô}/²q ©;“z“8¢Žåxøû@ÿM€i3_ôpz"©G¸3Ý*£ViDhe +B*"¸r8‚*Ç¢kÕ$T͆UüªŠá[U}•ºÊVè·<„¾B@_.¤ç”S}·YԞÃqp +5ÇQod%0¨0o¥þ6 r'ÌùÔ·î%è\:­+’àã2“Aðv€—k<]SááʄÆeƒÊUe]#9Kî@UûêÝâŒ{!ãm¥ßéôyê`<5ßäX:xõkƒ‹þ7AŸzŽª>Ðô†¢ÉRS0‹\$1θل¹yáºYèÝ<ðn&ú ;¸|Æ&íy@Ä/¬a®—Ó÷Ìr`:}ž@í·ê€×ê©OÍø=@÷ý@àA@wð:(ƒ†ø_àíh¦Í´ã´8C;Îð2na±oa‘iá&o¡ƒ-\´å ¹Íß?$Ož±’9_HßgÔéó¨FêÓWó Î „Óô€c€ö$àñ9µÏ’¿“ój6@ÞÀWzàBW6¥À·.³Ao¥­¼Œ®òò»Ê¢w¿Æä^ÛÇæñKr‹üøŒÅN`Ãôî'¬ÔN£¿fêö¢nuýNÞ_Ð÷§š_“oÉÒJV\Wp(y ¸©es̘|ÂA%šÍzpvÜccpŸ…ø>‹Þ&ý7Vlc<Ú.=c6÷Ù$æz ã=ä0Â8÷¤¿¡ôWO]Ï Ô¹Ô©yÜ$ÿ&ߓ»äBwp_Éõ<vð˜1=H"aÃ,h‡`1Ü¢„0肉îgŸ0ÏPð¤B œD“Dò*Nþ@Þ#3IÉ"¹¤€“2RNªÉNÒ@šÈI<Á7ø™Æ>F;~â—vò¨óù[„.˜vB¨»ò-¨ÓŽx’J†Ñd"ù€Ì%‹ˆ•¬"«©SB Ô© N 5jñ{ð‡qç¢á¿|»Ë¿¾Cž?ŸòŸN„¯?D_/‚§„b"ƒÈäOd +µfRg>u–  Ëp6êQ§”)ÙÈõ\s;SU[ŒÅwh¦W˜Âp•ÿ}•«´’+\îDøë ôZÆÂBӅ9 à×îÄH^!¿£æêM¤?Ó¨3›ÑÍÄmæä&–SǎXC56síjnŸÝ¸ÈX|£8¯ð%­:ÇU¾àj-äÌ ˆ@oÚáÁX¨ ´^ÞzÚÂXH±Œo2ýLÍ7¨7ŽZ“©3¶ÏåñX€ Ȧ +êä󸮥F5*pš±hf,Nc<ÌGiéaæãõþ& ¸ÿUÓnOâG;ôŒ‡Ö<#pW€ + .+†â¢âmœW¾ƒsÊ)hQÍÀ窏pJµ'T98¦ÊÅQu«KpH½nu5šÔuد9€½§±Çó:½ÚPï#à"uOÑ +Ôv"©ÚA;öý®*< ·µhõŠÄ?½’pÖ{š}†ã¸ÏXÑNÄ!íûpkg¢I;û»,ÂÞ.VüU—‡OuEhЕáuú]¨ÕïÃ.ý)l÷½Ž­þm¨ +p’-/ XbEwõ(àKËeë‹Á*\Ðyã¬>'üâðY@*šº¾Ž½o¢1ð¨zuAS±;hv§cGðbl ^†š;ªCŠQ² ÎÐT„6`sØQl +»„²n?JŽp!•’’!­û "–¥¬'õ,ƒ½YÊù<Å÷ã8æ‡}á‘hˆHBm÷þØÑcj"G£:r<œQ“QõÊ£>Ħ¨ lˆZŠ¿D­ÀúèB©4z½T픊£ë¤51n©(æ¼T{G²÷²ä‘UHOicÙ{ø†WÞé¾À‘T^o}Økd4Æh±»g7ÔÄPßåñiØh‰2ÃX8 PbxņéÒÃiuB¦T˜#å'äI¶„b9/a³¼2a‡¼"aŸ¼ÜxFñqâ-ENâcEv¢³:YÚÉ=–ÓkÔ=ןóÖ@Î|¤áU –×߶Þ^pöĦ¤X¬ïcBIŸXc†Õ¦QÈ7ƒÍ4QZeú³”kš!­0}$-3-–­¦år¶©P‘e*S,1mU,65*šN*$ßPf˜)盅"ýîšêŸJ£ÿC€Æ¡ìqùs5¿•§¨±>ÅÅ}{`µ%v‹«,iȵŒÄ2ËÉj/e[&IK-ÓäŖ兖 y%[‘a±)Ó-%Êy§j®Å¥úÑeÕy†ñçޙ{D ŠK] ¢qÁD–pFf`¹âf–Ù•ÀD +5.ŒKãq-5zŒX›˜TkÔÚĜ4§mz‚5m<96ij4Iۓdú1ùãwî=÷<ßû¼ßýîûÔ/¸*×&~,×$~#Õ$…´Õýhªû¹¿€Ÿá…쁸heý¤3xÙÄ9[/ ˜‰­)ã°I?-†8¬7°Ö`Ás†l¡Ù' ý|Âzßeí—mìA6³G#¼îËäŒÉulI„–…£ð¼1kLsÐlJF£É„U&›à3-ꌡÖX,V—‹UÆZM¥±I[aÜ(•wÈc»Îm<©+1¾Vlú y¨+6…ä"SH"Úâø?ñ7©w‰Úgø‰íÌ:xÝÃu¼H?6š#°Æ<Mæ‰Xm‰Eƒ%õ–4ÔX2„EðZò„ +‹S,7{Ä2ó +Û¼Z[b~^*6o“]æýºBó‰°e–Ka–?’º‚ŒL¤KÚ^þÊZ¯eÝÔ}%Ÿs¾ƒ™“4¨Ž…k¬ah´EƒíIÔÙ¦¡Ú‡*›¶t”Û²m©Pj+Kl¥b‘Í«qÙ´…ÖµRu‹l·îÕåÛ:ÃòlÃsm¶/ÂÔ¬œkëCzÌÜ¿åÈužú]˸9Š¾D¶q-ë¹®Æl-ê³#Q£Œ…W™‚ +eʔ$¸#J”L¡HY"8»X¨‰Êr]©×æ+~)WÙ$/U~®ËQŽ‡)ʅpEy'<[ùœ÷!‘‰ô˜Û܃—YóÙöÁżÅ1t7Ùìžãº|üۊ¥ƒQ¡ŽB™Ru&ŠÕ¸ÔTª¡@Íjž¯:Å\µL£ª5ÚµIRԀ¼XÝ­ËR…YÕóäVx¦úO^¿×YՐL¤Çܢߗ¨ušúÇJÙû@¼o¤/ÕìK¹} Jí#PdŸ§c:–9âápè‘ïHGž#KPªãX&.q¸5َš,G£Öjo‘2ì;uûÙq.,Ýq3l‘ã>¯ßÉéöP/’ùÞÎá^ ÖÉà0GOÆ4l¯ä^\NèG×Vâ G¡3 +ÎñÈw>ƒ<×\¨®$丌Xâʲ]9Âb—C´¹JÄL—Wcq­Ò¦»6H&g›ltÒ¥¹^Õ¥º®“Ou©Îoå4gH꣰Ÿ+y|'‹˜{©ßáåûÀX²…¬[Ôrz²¬TB^i$ÔÒ1ÈqO‚➉ŞdyRaõXéÉ,ž|!ÝS$.òTˆFOƒ&ͽNkpo—RÜr²ûŒœä¹FîÉIîÿII¥¡>’KBÚ^Þ gŽSÿ@-ûÀH þz¸Š¹“¾dW BVåHX+' Ã; ï<˜½)XTe‚©Ê†…UªVU(¼ebŠ·NLò®Ñ,ðnÕÎ÷ÔÆ{OKqÞ«ä)®ò¿Ú¸Ê6®â'.ÒïSÔ8\Ç>¬âûÀ8²4’Ê•Ì] Ì\¥nÕ …±~ÖOFªo ¾è}©HñYäSès >·ï«çùšÅ¹¾ÍšÙ¾ýš™¾SšXß[äïšØúÿhbëBšØڟ8Çt²þöÕÀ®f`£ÈÚ5Ü ÄÃû|?`ãï ›4HnŒÄæ‘XÐ< ÍS1ß?ñþ$Ìó›0×oÃ.fù‹0Óïfø…iþ„©þ½â—8ÙYŒñßcš¿cž õ1¹±ŸÓìûQêï£Þöu@ËfύìC PD–3I&s[Â1«ef¶ŒÆŒ–hLoi­q˜ÚªÇ3­fL (˜(@L с<؈ =x*Ð)Œü†ô`|ËWÂø ¡~Ö÷óKúÝÁšwQ{s+=ØÔoÊ^ì[éÁ6 •Q1žLßLjˆ§Û¢0±m,&´MÂSÁX<ŒÇø`*Æ30–ìè`1Fkð³àZŒØنá;aXð"¢‚FԎG¶=„aÛÈ֐ÐËQêïeÝÛ©ÝBÍFêT'£¡²‡ùï%`Á^ võ÷ãˆÑ>ÃÛ£0¬} ¢Ú£1´}†tÌ'iˆì°á‰;w,Ç ŽF ì؂ˆö h?‹ðö[?øøûCˆØ×ÏAzdݛX§'Ï$ÆÁb꩹_f³1G©Þ Džqrº¢ ë¹+RW,´] »Lz?¾] „Ÿ ¾Æ|ûÚd8pa™D8vs éæ0ÐÍC¾›‡K77[7E.°˜ ̹Þç3_oI¨¬}ý^ÙÎ3™ÚvÖi=èEýW©ËG£ºA—ù €a…:-‰®Drâ:®Žå0ÈÁü‡Ãë‰À 3áGà_üløÝü]¿BèÅõGä»>Zé{#=¯`ݬ7‹º†óÔ§æ¤_£_†¼ DðQÍÛÔ¾Iþ@Þ!ïj€ÛáÀ{ƒ÷‡r ü‰aáCçя =üÞaOîpÃßaƒïÐȞߓ{¼ÔG{]EÏ Y÷bj§²ÖÙ¬5šµŽú{ÞßêÕ#´‘ᎄ|Däc‰ƒ1=¹GO>Üg`ù|C ýxÀóî/yØ=dOÒì‡4öá r·jÚãbíÊE í20ç*õ©;’ºƒoÓû¨ñ!ééÕ"\>Ã'uÈgä_äßäKòH¾üŸì2ŠêÊÂðÿÞkDTÅ} ** ¨‘EZ nèÆnh蚥YDQA@ ¸×B"2¸¡b¹M0š1ŽÆrRV&NÍRV¥œ8ff\*5qÜ¢o~T¨™êúêÝ÷ªúþçž{î=缤O~âÞÈldÚ!³H’™ˆåu„Á'3Àen²üù²ãDö·ãٍöÃ^ӉYD¢‰…d’åd©"õd3ÙAv“ý¤ƒt“Sä"ùoq?ÑØ×xWüò’¼ä?äßä" ÙÁƒ£~Æ Ú1‡ 1‘t’KŠÉ²žl¤F3Þ`'5Ú¨qsÆsçügñ#>£Æmjü O9zÂ<&È¿Ÿ?eg7ÈN®&ýÏqd™OTÄ@’¨•EꬤF5j8s#5¶P£…{8g;çìâVõà!}ñ×iÁ_2:¯¹2Ãèÿ‘G;C5²äÄ·QĝL%ïó_AԌÂ3Äs»Ó¨“CBj¬¢F%5j©ÑH-Ôø˜óíÅ_¹'ÆQîB/¾¦/îð}Å ºMËoqÖ~¾$7‡ » §/DÆÃÁc¸ øâ9}ñr]*|=¾c\| ur©QDUÔ¨¤F-5>¢ÆVÎßÊ9÷ãwèd4œÄo鋫¸Ë´°û”»wi0Z†"¡6¯;ٙ0¤eG'¼\©;‰kô¦æBü‰qñ5ŒÔJ¡N&gÍ£—‹p «y]Uâ +ê¨ÓDíÔhÃîÉ9ÆçYþÎВSœ¡G|ŒÒkwql˜Œ£Cyœe¥ç䑏¯›ÆãžäŽo$Oü^17Á¸æ Ã‡xô ³âÒ°,\pÌÇ9Çbœu,ǙáU85|zœ6ã„S Ž9íG÷ˆ#èqGF^ÁáQß Ãù1Ú]Þâ  sÔhž¤!ȓ¨ÏëíŸÓx吻|¿ã!â+Æȍ‘ãpÕy~ãâ‡ó.áè­Ç)×DœpMÃ1×lt»-C—[ :ÝÖà·jt¸mD»û6toÃ÷O°Ïã$öxô¡mÌ´Ž}„–qo°c<óÙ6„WL7OfRߛÚ7æ0L.OtÀ%wWôŽ†“ã|Ñ=^‰Î ‘蘋ö‰˜”}“–`老M.Å®ÉkÑ:¹-Sš°cJ ¶O9ˆ­S¢yêlžv Mï=D£ç+4xÊBý yÆ4óÀ—×𦠏Ïó¼îO3 ž˜: +]Ó& Ãs6L÷ÃÞ*욍gš°sf2¶Ï´a«×R4{b“Wš¼*ÑèU†Y[Q?kP7«S¨Ý+¬Ÿ}]¨žs_¨šó\¨ð–…uÿÃS^ë÷¨}‹)æ³Öù¼ZO.º˜†;¼±Žv{{bçûs±í%š}4hò1 Ñ' >VlðÍD­oj|‹Pí[Ž*ßõB¥o“°Î·UX3÷P>·G\=÷ªX6rޏbé|Y,y‡P<È÷\÷¨{-œ©]Í~‹t…±¾S²ï\ `ç*‚a­RƒÕJ=ʔñX©LA‰ÒŽ"e®°BY$,W– ˔µb¾r‹˜«Ü+-]Ô--YtIʾ#e?!²”,‹C¹Gÿ߈.1Õ÷0ÍvƲ×1-ZÖ¸´£.Ø UÁc°6Ä«C}PˆUŠT:ªŒ(P™±L•†y!E˜å_H”¥«Ü÷^ú¿‹šXòµäò<’jŽ‹éú#5Y‚%Ù É`JžcŠ/bS`H …Þ…ÅÖD[ÍÐZӅ(ëRAc-"¬Ub¸u“¨²î•B­Ç¤Ô+Rpê·R°õ9‘¥”_èã¾÷PëpûÞ|Þ l6’ +Ž iG}’dc͝> +1éc ÏxÑÞÐÙ@k[„H›Ûb¨íñˆ°[fÏBí+„û:q‘ý#1ÈÞ&.´•헥€Ì{R€ý™h“Å2Þq‘ë<–Í3IÍÝ+Øs±¨#kþËv™Ç×x¦aø>ÇY›=–Dö…lvBP&-~˜¶ª´Ú,È"d“’åˆ%‘ÄžåXƒÄVjI ¥5bÔ´Æc´1ÓZÚi«CƒªvZ3ß\‘Ìoü1\rç{ïçyÞ÷{Þçæólb™>Kz »4&ÞVqñ.ß]#‚4"!RÃhXâ0Å&>§¡‰“øŠ'ÎÔÀÄdӀĦ~‰ËM}’ªÌ½“ö˜£“Þ5G%]3G%>4G%æèVâÛhdö ³e®T‘Á>` + 3“³8ßE<ˆgTJÅ&;iHŠ§bRü48%LSûh@jŒú§ŽT¿´±ê›6Q}Ò¦+:m–¢Ò²‘¶ÄÔ+­ÂÔ3m—),í„)tîUShêShŠñ„°dÃÜÊAr¬Cc#º«±†Ë° Jsùùz®ô2“ƒ÷ãÿûgÚ©O–‹zguStV ¢²Â™Ý_Ù± +ώSÏì +˙¢ÐœçÌSPŽE9kåŸS+¿œcò͹,ßìûòÍ2L¾™†É/£·R¹ŸX¿ݲ|އB¼§…}€©0ß ƒ±ŒÑf…8*¤À]AÞ +, V@a¤ü ÂùZƨ‡e¢|,3ämIU7Ë"uµ¬”—e›<-ò°\”Ga‹<ó™XóÚð‚Ô|Ó"i z˗З–QƒbjP"M‚1+¤Xè aà·ÂFÝJÔµÔC]J}äU"ϲ(y” ’{ÙH¹•—kù«r)O’syŽž)/‘SÙf9–’CÙy9”~#ǒÇr*az.nc[5(¢XÒÅhda “Vñ>®‘ÆcËF®g øWàA+%×êŽr²:ÉÑê!«„ÈÞ-;kŒl­qêl}Q­3dcMW‡êÅ2UóP¦¶ +#[yðº†LëÛØ@î«Ñ^¾RÊE7­_Wá?7Hq›ØƒÍRÄ)`+ú5èo—kÍêTg/S·Î |!°Žadg,ŒÉ@£©ãPՑXÖâuw\ êöŸÁxº2îèÕìÚs­ìš/£õü)k¹S +܍>i¸ì“ޖlâoaHa1Œî~R=Ci}_šCP ¸æÛÀo Ðõ,^ÏÇÏÁ×<÷OXI½-äAÎ ÛèGhŽFoz‘<€^—Ã’s£dwT2GÿÝvNÇIâ8EïaÞg0?Ý:Ǚg +šhrMÙ@-šH¬‰Î| -ðßý·Š/‹:'‘ó´Ç†Ö£¦?¥ó†¿<ŕÖlíd˜løÔlÛëÑÍj֟œž%§ñhMFg&³õ…Ò9ÙäG–Eúq\#Ž«ªdÍÍú“êôGÐç(À+tƒŠ|Ç+e¨éÿ`؛ØŽ†Ô‡=ßvEÓÍHr‚Þsh½@¯¢ñ:sØét4²ÑÈC£ÕjQµN«Fïi-¤9­cä֋]DN£Èg:“Й¦CŠGaoA:»ŸƒN:KÑ(gÝJm§5¦½Úb>ªÍÎi£Í-mèøP՝ UÙª|ŠÇ´”û´ÚÊU¸Àçˆël';êà®c¿ðWCÇ(ìÅÊï±N‹zÔèMßýÊõ=©~W”íO™þ†2Àÿ|Íu{¹7WØéØ é?w1Ԅã¹ÍZßÃY«üº«Ô?TÅ}µ40VEq* §ü ‰Ê zM ƒf*7h–§+;8WYÁEÊY¥y!•²GsC+-ô¢)%ì®)¹§ašó_ÂÚ¸ŵ7+x(×û0flØ#Yiók¨ÍŠP- õ”%,@ù=#µ°× åö¡œ^£•þ+e„OÒüðiJWZxŠR#2•Qð¢Ë>ªéëŒãß_ê +h- ZåE%¼Hy!„@$ ’$µBТm«”´µõ… õ•«N»!´ÎZµ­Ò­Ç͵{œ¶ÛéÖÍ3ÏÚnÖu;í֞vNûZØñÏ!ü~Éý>÷¹Ï½÷û`͊àO= šS‰&ùÂ'¿,V¥Ý iw‰ô¹$þ àuLësŽ×쯸£ä0¯þ^5õù®K>[R£Ñ)G{Z +6¤g¡-=­é…X—aÁڌ +¬ÎpŸQ¦ ?|™mX•¹ ™Ï +oæ^áÉ:"ÜY§Dâ’X©ø\Ôfß!’¨U<ຒ¶ƒš§‹X´`ƒd?¯¹|ÖÍÜlΈö¬H´) E±k³Ó°:;Í9:ørLhÌ)GCN¼9uðäúàÎ]‡ºÜQ›Û-\Ê°¨QŠjåIY•ê¢Ì¡úTæP/*ITÇ80Œ´TfÚ?Ú¯>²§ØÎ8žb팣E5ªyhV-†O½ jêÕùð¨ Q§¶`ež®<œy ¨É[ƒêüváÈß&*ów »¦_Ø4#2«ö]Y¹ö&ùŽHâ4c¼O79÷‘rZM;렂—ìƱ™¹ ð½_3š9ðjâáÖ&c¥6.­N­Õ:ªtåpèªQ©÷À®÷æ_/¬ú'EYÁQZÐ'³ Ë̆wd%†ä["ÝG”Œñ+æà õ†¨?XÅu ;i¿ºøÿ& }6ó±Ê0î‚(ԁӰÕ9†lT4° +a+,…µ°åƕ(5ú`1„¹h‹(.z^˜ŠɊLC2£iTVhú#ù†H÷…Ec¼[LÛËy¿Bí~'°×ÅZ$[«ésùÜÏ8ܦIpšf¡Êƒ +ÓbØLËa5e¡¬XÒâXŠÍ0—ØQRâBqÉ*™[`4…Áüœ(0zËOd:Ëy™¶ôc™Öò/"É´fIèÆ¥ÆÉJžGÔ=L+ÞëžsÓë×Òë3ŒÃY&Pa‰€Õò0ÊJÂRš si:ŠK•0•éPTf‚±ÌŠÂòʽЗ?]y‡ÐXŸùÖ}"Ïz\¨loÉT¶È×Be•Æ(—„š¼me-Ðr¡þA/°{"Áz`-ãòò]c,³M‡Ùb{,ŠìKQhO…Áž‚Š|è+ŒÐU”A[Y…üJò*WC]Ù¥£[ä:öŠlÇ1¡pœYU×D–ã+~–„¢òg9þíæ ۀ}M¬Úð.¶G}\ÆáfN*KqõC0TGB_]Í"hj–!¿&y5*¨P9ÍP:+ëZ‰lW3® Ètu‰ W¯H«=*äµgDjíUòO!wIBî§F¯³Žsþ/QwÏZîÉǀ'Ɇ5ìyøÌÕ0½(ôȐ_µ{”î8云í‘CáÉA–G‹L õV¤×;‘V߈ÔúVxŸÂ2oR¼/#Ù{Z$y¯ Éû¥Hª—D’GÉ÷qKâUÎó(爺=®C÷$ ðs[‚*Æe^ èO¶o*2}QH÷ÍGZÓ"țRÚ”M*,o6`Y³ÉÍUHjö"Ñ¿Kü[ð¨'ûà?……þ÷Ém$4ßCB“„Ÿ$‘!Îsúû×;Ú¹›¸'ÉZ¶gîÇ[#cR3¦ôÖ Hi‰@RË$¶Äbië,i]G[XܪÁ¢€ ;âuˆ ¬Fl  Û1¿­1m¯anÛ%Ì Ü¼Öÿ"¦EB̺1Žqž}Ôéíà~ØÌux‚ë@šˆs `á3]9 Ë;Ùv<„¸ŽYˆíœ‹G:ã± 3ó;åˆéÌż -˜¬Áì ÑÁÇ !2x³‚ؼˆ™ŸcfÇ0kÝó}6Jøõ÷sül»·Oó\ê<ÄNŒDIäd ‰%sº§"*‰ÈÐ\™¡$’ŽˆŠ1#dÇôSC-˜ڊɡ=˜Ô}ºÏcâӟ¯1©KÂämcôqž½[™ƒï‡g¶í<؎Uï`ì4»€ ’Hâv³íf…'`Zï LîÂÄp &„ Â4Baö—½¼ü{yù„¹©Ã,¢0æ`=ìïzÞàæ¿ +ìbc¸ë'.ýÀ¾.þ¡v7u7RÇj÷ð#%L-[Jଓ¯¦ßpm¾c£r‡ù¸«î±6îñ0”¸%&^ââJïËìö¢I$‰"³É|’Hÿ£ºLÀš¾Ï8þxË¥^È©œI @’„@ ‚\*""^ ¦bÅ2T@©W=j­ó>gm©­t´³]í3ë6»v[Ÿéö´«N»ÖvݦsýïËñTûø|ž?Dò~¿ïû;þïK ÄNŠH©#«H3i#ϑm¤—ì%‡È1|ÏIð1çÌG,ÜCšý¾å¤ÉyŠ|G»ä3ò—Áy~Äg_2•„)ѐ,’OÊÈ"ƯgüFü—óåCldüÆïbüçñOì£ÚajœÄWœL¿Äîá#–è>îð[_0Âçäoä6ù¹9äaOƒ #5 &±$…dP/—:jTàι_¡ñ›¹•ñ72~ãw1þN.Ï~æv·p–Ëö:þˆkø˜ߤËß0ڍ>$÷†®É%œ¦‹×q®Î±Rg¹r§©rŠœaðgaô°ö¿·ôÈ¿oj²^ԓ2Ÿ4j™˜‹…ŒZŠ×èã}\¤ ôqŽ>ÎÐÇ)tâvpgîÇÏp/ó/^â·_ğYop€jûGØ7‚0Žú¼êîò8ÝâÕû=]ÇæèO͙xÑԓ3’ç‘I<î87+]J…j®übfÜ@Fê´Rcãnã)Ù͇¹CÎòÔ\ÁvîV¸›{³kð4‰žðWÊßy”? äõC~9èç•wyÔDîì)ŒBÍ8ê%3¢Ž§/ DìåÆÞQ¥ØíU^µèõjÀöÑMè½]c:°uÌtŽ=ˆŽ±'±yÜe´ÿ›&ÞÃÆIÑæ-`ÃS< îm^i¿æõ:À«¾?_˜Æ× ¯Ýã|px\LˆÄމR윤B¯·=ÞVtù8°ÕǃNŸ2tøTã9Ÿ%h÷]g}›±Ñw6øvcß>´úG‹šý¯cíäûhš" ‘¬x^Q¼Žy­ö‘³1À±H௸}^ØåçÿYØ:9?"Çæ56±qj66LubÝTZ§ÎGKàB<¸kW£)hVubå´]X1í¦¿‚eÓßGýŒ;¨›ùKf ?â6õ¯Iø:’çÔçóE1g ~ÞÊsš7Ú§¡mFÖÍ£eV +ž™•Ž5Áf4ç`Up>VÌ.ÆòÙX6»õ!ËQҌ%!íXº5¡‡°0ì<„_Euøg¨Šx„ÊáG|L½w’ø +æ«öd*g>÷° éIàÌǚl–°)X>«#¢±"B††ÈTÔGP™…ÚÈ\,žSˆEsæaáœjTÏ­CÕÜFTÎmCyTæG@Yô̋ ·QûoÇ +Oˆá}Åö«ŸÚ؂Õ±Õ!½|Õu² iKdŸ煕Q~X=u1‘¨cQl2ÆjPkDeœ qN̏ó ,®¥ñ‹Q¿Å⟠H¼nÉ (”œDô +ò¥ŸÂ•ðà’>áµ.SÿLç ¶>{H·h§%°’kS'öF$ $¡¨”Æ \*C™4¥ z”$d¢(ÁOB܉¥(L\€|Ù2¸dÍpÊ:àïF®ü8ìŠ7`Oú9IßaÅ0ï²Íx•ú'29g°ÝI¶°ýiãgk譞>È' B>eò`”Èç¢H![‘ŒB…ùIF¸’lp&9áH*F^r%ìÉK‘“²Ù)í°)w"KyUŸÈ¢ú(Sõ€ƒ`¥€¾Únæ:ظv`é`볎>VÑG-}”+Ç¢$Ååt(#àRÆÁ¡”#O• +»J•Ùª\ØRÝ°¦–#+­–´F˜ÕϤî…QsD”¡yUdÐÞ _AdÐüú©sŽ¹¿Ì6x¯ƒëàä:ðْÃ>Ÿµá‡í(¨}áT"O +»:ÙêX5)°h´Ä„Lm6ÌÚ˜ÒKaL¯A†nôº6ètۑ®? ­þ’Hc¸NþA‘F?ŒV'ˆ.³§©÷µw°ý/äÌÉçZþ¾”õ¨d=Üô‘§÷FŽ.V}0,ú9ÈԋaÒ+`Ô§!ЃÁ +}†ºŒ¤Bk\µq=ÒLÝH5‚Ê|Q¤4@îA¤4 "Õ F¯±'˜÷Aj?ÏxK1Ï#ŸMQóó2úËÏâÌgž€LÓd˜L3aŠ€Á Y†t³ +Z³šL ԙyH³!ÕRUÖ2¤dµ"9k’¬¡°^€Üú>dÖ{|~y–0„‚¼BcÌ{?µwp$é(ã^ «J¸ô5Ïřë”i½ÕéÖ h­!PÛ¢f“"Ֆ U¶ÊlR²íHÊqC‘SyÎRÈìÍH´oÔ¾’Üsç¾GîBlÿ$v’œaÎ3×#Ì{/u»+9ïTq/𹼜ýþ<ö»ü¿\z1:EPçyC•€”¼YH΋D’# +‡rGdŽ $:m:ó!q•AìªE¼k-b]ˆÉÑùg••|A#Ú% Ú9ÌiÆ?ÄüwQ{Û"î…î>ë9*VÐK!G½èè%Ù=²B$º§Aê…Ä ±;ñžÄyÒë± Æã@TQ æÕ`NQ#"‹7#¼xŠO!´ømò9B‹!¬H@˜‡+9Κ ~/µ;9­_ +4’ÿs]æQQXWþe‘ueߑEã=Ä-—º¢ˆfQ¶(̸ â`T 0q×8Q£U bÕ¦­AÁlVMM“`L›6{bÝCRc4ÖhÜú±äÄöoö¹¿wï»ï¾{ xmÌcîb-£×fJ½M”`ôP¼ÑW±Æ`Ř¢ÕՔ hSE™(Ò4\ãž‘¦°Œl…dZœ¹R™[¹_þ™Çå—yEþ`¢ƒoÁجloCk£i…Y²Î§6BŽ…}à3¶UÃXOÿ|)‘uFç¸(<ÇK¡9]’ªàœå$*0·Ÿr‡È?w´ürSÕ%/C¾y…òÉ{IÞy›dÈ«•WÞ{òÌ»$Cî2ä0MÌicvíEÒF±•ÅìC û™Œ©©¼µð]oÖǺÂÀÏì*_³üåc—·%NËӐ$OËó,ËL¹[òåf)•«e­\,{äd©—“ù39›oÉ¥ˆ.¾°×Ñ߸Hª\Ây`[¸ŒÀt˜CËÈHà»HokG¹[ÝåjõV'k \¬‘r¶v““µ:Z«ƒu´¬$š•M´â„µ’Dß °¥\„ßÀC “-i–×`·|91†Í]%™^&*¤‘üõYH„hð¨r“ÍU6/É֙ 4>6— ¢V•ÜvЫæÁ +œdά<Ȇ3D¾Ü$­ºÍ­lÀ×J´—aÛb“²WS×2®—m”zAWڄþfô_•œ0'»Ðxn¡é³ÓÚií]¡'Ð Ø)ôvba'©ílî–uPC!d Ý|îRš[Y¿å¯pÐÍÝÀ 1þ5Îâ6©Ïv)–ñ4˜0úì”ÜwIw£ÿ¨všòjÖQÍ:jXG àÞ.@ Z.ÿZŠ}-»–äÞK€÷b¬¦Žßÿnaç14«íü,À·tt“цN_tb«ÑßËþï“\÷K„’æžKþø3Ž4@ o²/uìËaöåñh j !j 6pøˆENÖc¨þ$\bqä'-%¾ó¶r?£= Ýçk¥gøY,zAèÐëô&Z‡¡ÞÂÉÈ@ÖÎq†µ.ÒI†…¥XÇÇ4iÃ=9]lúi‚Úx„ç3ðo¸'3áÉÚ#MF{ºýñ-Í ~FK.çwÚuNéЇv>QË@$M1p2 uÎ1(}ÁÞ\®°Ž«4§×¸ô¾¤7qț|Ám‘¦¿3Ø}¥lÒdêêÚIèÆ¿…>_{—[4ÿÒ®÷)üÎÁyøWëP(]†«ð%| ×á[òõ6ÃÓ]?é>ùñ€FùÍÑCÎê#ác6þ1¢qðÇF¦./ðlÇ~ ½`0Œ)`‚(„b°ÂJ°ÁzØ¢Ÿ˜ò~dÂ|ÄÔùiôsæú‚Yö;}Ï/îÀà\óp¶eÞd¾¥Z ¸‚„AwH‚0¦£‘Å´˜}³îk1öË°_Ž}¶×ë¶ìºÅÄù-Óî ÷:‰ó5ÖÄã5þuµ]û|g ±u Nà‚Žíñ„|êƒOCЃ©x“®›Ì¹7T€} –c¿ ûåضa{ƒ.0éž×.ýSûññ0“îŸI— èÝÑév͏áC8 ÇZ× ÿá‘ÜðÍŸ"ð§ZIúJÃña/`߈ýÙøñ"ihÁ~1ö­Ø/Ƕ Ûõ¶¡\M¿¡?éŽÐ§<~£·ˆb*-ÔÃa8ôk¸7刦©ÈNÆ Õ­AèŒBc")š†}ögc¿ûfìcߪ£¬£^¯¨N›±½ƒÝØÇ*êȎSDå2ï½Pó-ÚT+ünKëK­éï†_¾è…¯´ú±³Ï¡1šL›„Õ4ʓI¿g¿#?ªEhX±¿Š¬Ñrc;YÅvþ½O^ÃÖÌ}µ5ƒá1%÷;JÝUÊîç<Ÿf §È‹cäÅQù£?=ÑIBg~ŒE#ëihÑÈæ4ä£S„N1ÊehTh¹±oÖ±²5­ÑùHUD¸’ÓR‰nÅ|O¹¿FIùåí”7åc]OÉ;Ä99(o4ƒÑ‹Õ¯Ù“í€ÎpÖ>–h§°óiœ#:Ùèä£cFg1v—Õœ\;¯ªµ keìàÒ§.«´Ã]•:6k ”8µqÝW:DyåÚ{›+çeöŸÕPvw9º“]Ñ ×Ƨºim‡¾ZÝqªG¨ÂiœV9¥h¥sšV8õ’s¶Ê\ +´Ôe¾J]¬*éT¡âN›´Ðu·¸þA·2»_T‘Ç=z6kÞ\F·‘«ÿÝXôᷔ×Ýaôw”Ú͆§´ÎÍSUnþZå¥=´Ì£Ÿ¬žƒUê9R%žã´Ø3E‹¼¦i—IÙ …*4,Ö\ÃJ½hX¯|ïÊó~C9>Ç5Çç¢fûÞSvçæVfµsÍ÷¸¾¸öpåîN”¶ÆÓ_Fъp®ôuQ™·–ø„¨Ø7N :÷’¥s’Šº<§y]Fin—ñ*ðKUžßtåúeiŽ_¾fûÏ×,ÿeÊ +X­Œ€m2îWzà»J:§Áw4#„Š÷Ÿ ÿ^o®c®–Z ×Ÿ¡­à½­»´‚R¿$´ƒxª(0@sƒ¢”Ü]¹Á}5'd f‡ Ó¬ÐÑÊ MVFèTCӕ6[3à +5=|‰¦…Wê…»¦FÔjJäQ¥F~¦ÉQ·59º¹¨6>Ä÷£h@ h;ì™3¸bʹvK‰É|ö§ Â]9¾ÊŽ UVd¬2¢ž–1ª¿fF ֌èš=ViÑ)š=MSºf)µkRbŠ5)¦\c7+9®ZããŽh|ü‹¿©qݚyþ…÷ñ»Ý}´;†ƒ¡Ä`síØ¢¾ô—¬#;ÎE¦Xo¥Çjz\”Òâºkj|M‰V“ã‡*%~”&u› änS5¡›Qãr5.aÆt_®ÑÝ7èW=öhTbF&6jdÏѳ¹•‘‰mû/×åu™Æñ¯—T@T@Så¢Èý2à 0 È]`H°ä²¨1¨ `yä ^ÖK$ëZf*h¹YÞ)=æZֶɶ—vÝ:¶µk%Ö´Ü“›®Š¥³Ÿ€ÝãÙ?>ç÷ƒ™yžç}žç}ßç˚á£ÆŽLô¬ã}%q4Çbb\9\ö0Í ó‘-Ü_EáÓU¥‚ˆåG$+7ªœˆ\eGڔY®ÙQ5ʌª—5ºEéÑíJ‹éTjl·,±ïÉ÷5ÜãÝù?N“ÿÃøܛEr˜±a #NJ æ+âø q”‡-z´ +£Ç)?z²r£ƒ”¦¬˜X͎1*#&UÖØ,¥Ç*-ήԸjYâ—Ê¿R)†ÍJNØ¥¤„£2%öȘx~àÝ)SÂ'ÉýFàNÆÏmŒ›É[ó©q8ˆ­’8æGÁE9ñ^Ê2LT¦aª¬†J3D)Ր KBŠÌ ™JI,Prâ\%ͪ”iVŒÆ'4˸Q‰¦2˜ːô®â“.Á÷¼;ùßÇñ³?—^À÷Öb¤€9Ÿ1ô1âA¶éaòa£VÙ¦Ê0ŽQšÑG£ŸÌÆ%#”dŠ—É”$cRºf%å*1¹D ɏȐR«ø”fř¦óE[*Êò| wø›)É<@75؇¿øÞÂè¹~²ˆgא2jSHd¦“Åì®dó8™Ì“d4*Ñ£Àì‹åyS~ùNùC@žSûKèüoÅ÷Æޖt/ÏÚ*zXlȤ,bI&–XÛPÍ,­é…cR4QÁE +*š¡À¢(M+NÔÔâTçÈÏV¢)¶ +M¶-Ճ%«4±¤CJöɧ䔼K>áyC¾6§&35‹äÿ¹JzY¸îQ΅Zz-¦ˆ§€X҉oyaë+Ø>J¥ò+¯)¥“5Ù¨Iö0=hÓD{²&Ø3åSV$ï²ù_V«qåOjly»¼Ê÷ʳü¤<ÊÏ˳ì:8åe  ûÏ,â\¨ã~Zʹ€4\öS©š÷¹H£lâ2óy1†’Ÿ€ª!šPé&ïJO¯ôÕ¸J?­ HyU%ʳ*UcªòäQe—{Õ"®n’[õF¹Ví–KÕ«UõøF.•wåZá”ìÄþVümh È ÆF΅ǩï…ËéÅzr@LÄ´ýI¬ãê†ËÃ1Zí˜(7ÇT¹:BåâˆÕ(G²FÖe遺 ¯«ÒÐ: ;л¥ñXÛ_ÁméQg?Ûñߎ¿µÍÔáI©~%g#Ìã=Ržb«Óù|J“ä cš†Ê¥ÉUÛйMÞÀÒÄÐ\€\<l¨F +ØHà-4Âöñ—9xp!̖ßbhpj+ëވ¯V¾ÖÔJx«¥ùmÒH25”§?ÿ÷F¹ÂÐ5  m [m €m¾ÀàÓÆ%ÛÆEÜÆ%ØÆfn£‘WSÄÕ,b5:³õ.Ã_B±å†´ÊÙO;òo-¶W’®eë9›7°6q&m–ŒOIá0|Á3.Oã ƒoúv‹ 0€naí`ðêð‡ .þ×6tÇ#|NA·¬“žÞ¯‘øs4à5ƒ{àÔ|·âw9>kð1¯ƒ>$mIÈÒÈg¥iໝüSÎQ;ð½vÿâØM»ÉG'ùè$]ÄÑÊ0ÂP´‡‹`ÏC@ÓuQàN wäûôÄî+ +}àÔ|7²¶Å[ًøËÃO +áFwJ]øß#yÂ‘ûðùPR¸ƒˆƒƒÔåúaô#> eÔ¥›8º º¹tºÙÔÝ4v7‹íÆà1êq”zýîjÅÏiW|?ü-/҃ø +܏ÿWðOØÁ×1xNÀÉA^‡S€I½ANÞ$'g¨ÍÛãR‰ã,áY†ƒú³§h¼žmÀþèyÏþ×µ„u/`ͅ¬35Æb¥ÿº%÷ãÒ°“ƒ>ÞZ™ÀïÁ ҅Á\âèOpn„ô!µùp8>cûœá"5éec÷Ò½,¶ý†KªÜK²f+¡Å³Î`ÖéËÚÜߐ†¼…ÍßÀoá÷ÀOô!|…¿Áøz-§Kp…ú\uCÀÑ«×é É7Rn±Wosøܦ©ûHv‰¼ý;”–;¸ âãÀÂÁ™PeP h€fhµ(ÈMº‹²ûEyEև¾»…¶º‰bü7:󺮢gïéßþ‘Kp>€÷û5ïHCaxÂ$˜q`\,<¤ïÑu}èÜ[ªÃörl¯ÐwÄq8¾%Ž¢þ®¢Ì¾F^F)^Bg~I¿ AùÕgXú>?ÂYøu º!ƒyñaMÓðÉZŒøÊÄÇì—êŠ`{!¶—`{9¶›)E ¶×êïh̏Q»çÙÀh¥;Ê:ÏÐ.çi›o‰fÀï»p^‡ÿ'Ѻ7/}£ÉúJ3ðG©ÍøÈÆ~1í`×9UÐ~ YKmÒ@k6Ó¢?ªÚµzGOѺÛðÑ©ÓläSäâ$ß8Aä¯Q©n<ä¼r_ wà_pYÃX›;þ|ôrñ¾"𓈏4ìçê-ÙØ"el• +Ö±ûì×c¿ û«Xù:V;•ØŽý½tÆý’ˆ^Àâ*ׅ·ÎûØ5·ëhíú·š 9óÂß$Ö‚Ÿ— V,æa߆};öplՐõZ|Ô㣠»-Ø]¯çéÑç¨É³|k¹øÓÕÓæyF„;lÌݘ؀±m°°¹Ù@°an_€L áb ’…Ê-÷¤Mš&kš¶k«^¢5´SWU•v‘¶6Ò¤jšTišViÓ¤®Ý´n«¶UßNCÔíÇÑû}ï>ç}žç}.Wy’Ëôä%zù"Y/ç¯_{•ÂO™b> +Û»þï3>wi‹·J>EOOUE79¼ä𓣛}¸Ž!\£Ž+Ôq‰~¹€FÆ6¶øeƒÿõ­³Êè;K ¯0š—Éûÿø"ŽWœ©íÒ½÷€×úMêy…÷åޑÛÈ`¤ç‘ËHžRžÅÅsxx/YÚ±É8]§Ž§¨c•~9ËøXÆze TtšŠç™ÔOÒ¢³ø„QüB|„éÇøŒ¥æc–š29w¯²xzž£¶°8ž-™çRðLò˜ÉSγ¸hqy¼äi'Ooi=ÄlØfÂf1¾ŒÉðsß÷ Æö½„cï`4ò!F¢?Çјop4VÄðcü:‹öW»y,=Äó|¾¡`oŔ>1 ëѬD¤`1*§£u˜‹±`6Ǝ™ØjLÅzŠóa"Ώñ¸nÀhüFâ§0œpC L¸ŽÃ’{ì¢_ò‡ÿŒCI"éÿð±šå†%ÿM–—{ÄM–»«l‰¶˜bŸdK° ‹ÄII¦%é˜LTc,QcI%‘:0,­APڀ!i ŽH;0 ëE¿l‡dcdsèI^EwòUtÊïâ ümä¿DGÊçð§Šð§‰{+ñ3òïšè¶wˆëLíçYfV €3Ô7C;Éã1"—#˜’#) ¤¡/ՆC©•ÒêГքî´6t¦wâ`z?:ÒGàϘÁ÷2–Ñ–y­YwàËz ^Åω?¡9ûBü’ï¾ x±œ6`¹¿ÌuƒïKlÉfi“qú'˜þL)„¬ ô(ÔèRâ Â‚@v9üÙN´g»Ñ¦ô¢UéG‹²ޜ!4çLâÀþE4î?‡Õ-xÔoÀ­þ êsÿ@ü‡¿Ãyö×Éý<ËüŽ‹m–“6¨à¼Ç6(dᜡgmÏG—J‚€*í*%ÚÔ´ªð©­ðæVà@n šrјۊ†¼.¸ó£> uù§Q«ÙDµö\Ú×à,øø NÝ¿‘Ï{x—mð«ä½Íÿt°M¬°œc[:ÎoƒÔÑCíšx´hdðj2q@£F£VÖ ·¶ õZ'ê +ܨ-ð¢Z€K×gá1TΡR¿‡avÃ+(7~@üŽøšÁN<à™_&ÿ-7p…%~ƒXâó îRÇudŒø Ñh,L‚GŸ†z}jõTëp¬p¨2Ô¢Ò؄ +c;E즣(3@©y6óuX-/£Äò>Š‹Kü%Å"ßY™‰û´ÿ=rÞ`Ûw©™ó±p€s†¦:üÔÑT:“Õ&9œ&*M¹p˜ a7›Qn.C™Å…RKlÅm°÷ ¤$ˆâ’iX¬ga¶]ƒÉöŒ¥ïŸGQ©ˆ"›È}op¹Kþcmß*qš-ù$µ RG7u´2V<ŒU§5« åÖ ”Y÷ÃfÕÂj-B‰Í†b[,¥n˜K}0•u¢¨lÆò åËÐÛ¯@g¿‡Ǐ uü†ëWÐ9Dî‰($^#Ï/c¡­¾Ÿ£H0Ïuœï´G'}ãcŒÔ1fìöØìI(±§¢Ø®„Ùž“Ý€"G Œ µÐW4£°2]å +ª& ©ZB¾óòœw‘ë|j×'Äßø,r¨ñò‹P֊ü&âEÚý&ù.wëã‘mç ×¾ l…Ûi“&úÇIßX9¾éëã¡­—BSŸ†üúä¹5Èu¡vÛ òT!ÇãÒӆì†^(F‘Ùp +ÛHo¼´Æ"¥é!R¿ä³ˆô†=Ü%Çù.p$[;ÌÜx„ñÈu¸Ÿw’£I¿¹©Åј©E덂ª99Ír(›³Ý¬†Â«C–ׂL¯éÞ:¤ù|Hõu!Å7 yËI$·lBÖr ҖûHlýI-_ðY„Ì·‡Û´ýÓä?7¸7žÎs,› †‚Œêi¦–jÚ¥”Z ôQn Yþ8¤ù¥Hõ§!ů„ÜŸd¿2¿pAÚф¤Ž;! Ì !°†øÀ3ˆ ¼Ž˜ÀO¹þqÿF¼_|„gÉ…|›£ÀAfÇYˆã¼“#¼üVA}ÚFK=Jþ}ª io{eD$‚ + Bâ ℠+Ä +D íˆú!L`Ÿ°‚0ó•À!Jà Ôû{âëe7ß#b‡ɽ6ɼ0ÅX˜a,LÓ|öq¯†zJù] PSSm$;†„á8D'!b8û‚ +„¿-,F‚I>È d0éÌ ÿ1Èy7ȹfˆÃÜÐ{¼ôœ5¿"ØIq[ä\9 œš§N‡¹úç€î98™ˆÐ|¸§á_%~ ‡/ .Ë) ._ì»ï‘\Zá!„,8 ]àu'0ÅòÃB(5w•N““ æ§FO3˜žæœœ¡>ÏÐdÎPØgôÙÝ<ÏòY Å]ÕÏqpÀÇ8­ð…Ãç{þÃNž‡Ç!dù†çÔ¹‘^Z±Ø>\Ò¤‹Ää}jäCtü‰Áôrºt…œ\åŒ\¥È¯èk¿Æ®µ©¿KàÎÝÇ8DÄ??8{=ä<éä<çäé°Þwâçrx\Ÿ€OÁ êõ&5òy¹Í v‡áìîh©} øÚqºàµÿŠ-Ç t=€ð!À’À P Fƒj0ÌìؔþÍfó/¶ìTÿd»»ÏVù [Ù=¶ÏvÐ]Ð׿­¿éK¾u‹_}®ƒKà7à펝ץcïí„+ð XA¦¾S¥Ø‹íZÝQvgê+tÜBÇèøœ-ìïl€7Ø?c¿kÓn¸Žèc’ögþ®òËËXû¼ëä>NthÐàŽo¾ð…ò+|Éø‹ýáú+{n›* ÷Â^§k踂Ž?¢ãt\BÇ{l†Ùu¯mø¹29®wttÞÔ"w†7Á1pü†ûày¹©ÞðâG\VxÒõå¡¿ۏa» +Û°]‡íx:Û ðk %´ß^ÖÏi opÂtDoq¤>!;ßp¼(cv;Áöïiø¸ ®w”™|¾ú-±8¯8,ØáÈÆ~>^À‡rlWa»†©Ø¯Çþ°¿@­Zª=ZAÛXÇf8Zµ•_m&:-D´¶`ƒkÁwp~ >s–÷…ŽãÖŸzãK?¸"à‰'f)XËÁ~v¡cñØN^¶©F[4E›ÐтŽ&tlÐ2­£™¯!'«ùæ*,4±2ù"Ñ^ï÷qÎ6çQ{œr¶›×¨‹½ê_\1øa…#b¹€P Gcᨆc2¬õpÌÁîӜ”çõŸ.EÝÔÿ˜(>£©œ;ÀÒÿáFø¹vÎÑfó|ö¤únüÚ Ÿüá3a#<àH‡#Ž8Šñ¸ ž +-FÇ"tðÃ)¶Ír±k†K†¦wÉÕ´®ªëZ¬)®ešìZ©‰®TÛmºjºÍÕøîKUÕ}•*{lVEσÓó¬F»]W¹û=àx„óð‹æú2²÷‚u¼ndy>˜ÑƒøÌóêªÙnžšÞÓOuný5¥W´&õ²h‚{’jÜ3T힫qCUå1Bc=ÊUá9^£=§¨Üó •y.R©×J•xµh¤×÷~KÅÞm*ò¾*òqt¥éS¡â>TÔg††õY¨Bß*ðݨ|¿V ñ{Syþ+¯ï·Àñ¿0w^óÛ¿ÖsÍ6ò|–ÿš;ÇÃ:rTè¢ +?O•ûùj”_°Jü#5Òߤbÿ*ꛪa}sTØwˆ†+? \Cª•×ošõ›§ÜÀç50h²ƒv++ø¤2ƒ¯*3䞲Bð#èÞêëu £èŠ j€ýv®}˜Läê­$7£‚ÝTè­áA* 2¨ (FùÁåÛ588CƒB)7¤P9!¥Êî_©¬Ð)Ê £tÃ2¥1Œ¥†íRJØq%‡ڕáàéP +x¿wÁۜC¸^_‹²•§¡£åÔIqD7¼”gðÓ C°"”§ì°De†¥(#<[éáùJ‹¡Ôˆ +¥DNRRälÙ£–ȵZ¢wÈ}L֘Kàp(щCpí€Ã`é¥<é9°ñk6£àd>«²FÃB£‹r£<”é£Ì¨~J2(-*F)QñJŽ¶+):Cö˜Á²Å ׀Ør%ÆÖÊjœ©ã"ÅÇ­’Ù´]&ÓÏgzWqæÛ2™üïà}‡àó6ø×1¯däZžÊ§yo":*Ð1CБç¦T£·’þ²Cd3F*Ñ'k\¢¬¦T%˜Êb.T¼¹Læøj™âëe´<­XK£b¶*:ᨢ¬À—Š¶::“àP+±ßç«Ã½‹¨Ö£yé´Ô £EÔÊ r–fí.›ÅS‰_%Xe±„Él‰•)!Aq Ɋ³fËh-Plb‰¢Ç)jÀ㊰@¶…Û¶È`?¢PûïÀ-^;Âmí&ö-ð¿Â¸·¼„õ¤”zäù8ZÆ›2>†ÎÔkJJ%ؾý¾ÿóÿïó¾ïÿQ·ÑC”|¼`jK0­ó~Ïa||ø}ÚXÉz¨fžäŒXŽd/“,`0èÉo—JfJ€jü_5µ¨¦«¦ «¦é¨î ØT«¨E‹© +ÁWQÌ%+@3‚ÃT.¤Vބð;@_Küڕ|VKš«ÙH× Ò˜ƒF©7×D`aÀÐLr¸µ_hvÈ£<È£<iÄ™“F¼F6·w‚¯§Àõ›h Ðes-ô*Í*Ÿêë¨1Ë×2eXÑI˜ä3b3IÀüsøm2þƒÀQð"@òz­cn^‘N°VN “èó$‡À)ÀI&ñOœâþ/\¿T Üyp‡×²Ÿ½° ~ †é„éàhÿ +x ð©Nwà 8 ^oÜ7hð:9Ϛ¹ˆQ¸L3xm\á¼Ê|pZ¼÷+À×>VÁ4÷XÆ9Înpšá 9ö癎·Ë +ãûÀ%p¼˜b]7ÀÇàïäñ9õ¸Eƒ|›Fäkõ.›ß=tq‚ߣp_¼‰Ë ~ @èz! 8Àd +ñ¨%8¥b&qOêœÖ×,”¯´ ï¸7·G÷˜¼;¸Õ[çs}„»úF7Û}ø#8Þ¿>ÒýoD€XÐô׏xÌo•Çb绀ØEÄ.!î}FŸ’Ç'äñW\àG¸Â8Ä?#Öëˆç} +y 7{•//ñx§ƒû8xéÿäðƒBõ/üÝ?”¨»xÝÛxÌÏd!¾]Ê¥?ÉÃ8 +ôò¸J—q‘q`ïâ2ϓÇ9­cʚô¦v鷈ùuXÎðßi²<©ï˜^Ÿ^GÁó õ¡~_[ÌÍ'22–8}@-®á1/iñ­äï š›zˆ]@ì"bÏ#v9±1®¥:¦:fà)dÜ̲ù%•8 ×)=‡`ÚÙAØ€}`7x¦#vL*%¸Èêºx[f¸áéE„Aä>š¥‘Nìlb»‰=•èӉïeæç2žùįÔ~òxV«aßÈv²];aÜA-¶±…Š63Ú§am›ÁFÀn‰fÄü±”:–ÖiôyŒZ¥G”ÌúÂ1”øc´W6—ÍÜÄÏ!~>ñg¡Äbâ—»E,C ÚÀÆú™¬%ÛF¢Ö3“«QV¼µXnÁù8×±wl=‡¨Å>tñ ÖÈ3ê¡mÌI³†Á‘Bþ6òwh=úX§)päÁ1Žb8æ{±Vò·œ –òe5µ¨¢Š‹YЕ(¬އq#ˆ%ÆØYÊ/²Õ>ø`ëݍ.¶²F¶(†ñ$ÁÕ žp< +G + 68¬§jÈ£ZÓ´„<‘Gëå ž”“UJ©\ #›‹J‹õ7Ía¥Í{6h¿^b{?Ëvö[É!®{8v¶‘϶ºõ +!J$õŠ£ºÉDí Ï@Æ2Ž-DåÊ‚Ç ÏxòP¨žâW²“¬`–Ök•,@9ùÌGó‘§Y?À[ñԟöã0GÌ^ŽÝméí8rÖК¬¢.5~aŒÍ_\Ýô¸ú0žAð ‡ÇO:¬YTÀ W*NüÙÄ.gõÔðd ÙmÕ$¿VMô{Mnÿ+rޓ+È÷ÎÂ}´GXo|/ØÂýž­ìDëA]ýU¡9fyý;kfÀÏTØWùƒ5-h„rƒ,šlSN°C“ƒÝšâ‘;d–\¡%šºXã «•mh–#ì€ìaǕ~I™wõ˜Ñw™à[ùá~É8êÁŽÛ:ZÚ²…´Eó¨‰7*HùáFyÂb”ž¤Éá=41¢Ÿ\ƒåŒ© ÆT3f(Û8NYÆɲGNWfd±2"+”Y«´¨&YMû•j:.‹é²,æ/€ï>RÁ+ð·Ñ†îâhkk‡â÷Ònт”Ò–Q“|æk²9TÎ(“Æ›â•mêª,S/ÙMýõ˜y¨2Ì£d3[•n¶ËíÒØè\¥F)%fÆĬШØÍ»W#â^Öð¸wõhü ÷ý„8Þ÷ӂî%mâh«§õYÊÿ y>—šÌ NSiœ•kTFì¿Ù.¨¨Ï+Š_£‚Šl#Û 0 3Àΰƒl +(0.£D4DÃwq©;hc¬¨9©&Ù¬i’&VLlkšXS£i›&=iÏñ´Zcܲµ‰UÓtúœÛÓÎ=ÌÿÏðÞ}ï»ß÷½kPqˆQE! µ«0Ô©‚Ð,å…å+7l´F„SNx¥²Ãë”1WÆUJ3nUª©K)¦ƒrFž7äŒr+%ò.^¦önrïÆÓn-dÀòìóŒÿä߂Y?=N‘¸Ð#£_<&0Š–Ò§z’ÎÚØsú+&ÃOQAŠÌ•1#RV…g&),3]¡Yù +É*Õ°¬I2dÏPpö<å´(0§C9ûå?â(8/ÿœ›<39‚§ÈÓAþMØÓÖª»ÖlîTi&ÏSy?žžŒæ;¹pM¡gqô$*ÂrškPHn„†åÅȐ— à¼åP`~‰òÇË¿ ̖¦qHA»>+ßÂ#àC *üBƒ ܼgŽ¡ÞíŒþ«9›¦£G0»ÏÅs%\*èË(¾“E¯’Y³XÖ'btŠýT¤€¢P%ÿb›†—_q–†Òà’qò-©’OI£”,Wÿ’­êWҍ¸1 %¿åógàŸº¯Ø­Nò·Õ Ç:iV¨4‡xž Ÿû±iù|‡åU<}‰¢/!㤀òAò+ Р2ƒ|ˌò)³h`y¢ú—§ë¾r„\áršYþX +0“嘵rŒCÆ ìSÀWæÖ.jÞBÎõõ܍豉óÔ4°¼/ƖdÃ%žø„Ó› BûMñÕÀÉþêç +æã0wEß=Ì\°.ìBD.„å¢×"°c'1!MdbšÈô6ÜÚ1‹;‚œ-s8›æKópG`O+y‹ɇK*üâøžéaÉ@È¡3$Ÿxºé µ\òµ µ\ú5\t5\@5™×дŠ¬!`u+Ø-MÃ_M;…à¯"88Lu«m6{’¼«›ÑÂÎ&P»˜ð\´ýÈß U á»þðòjbÈibÀhÄ[6ҋ†PÀÒÀÓ@/ØDõ¬G=«§ÈúÕl¶ˆ¡›y‚Cø2¸ƒðÜÚD›Ö-ã\XÁ:¬äÏ` +Ÿï¹XÃáÀÂßÃXÒà G}‡Å ‚‹3Œ5ã9pÁ5Û½XÄᲈõXÄ¢.$ÈÂml|Œå|Ìê<ÌàÜ[\ +nm ×Ú5ÒÒÊ¡]ÓÖ±@!H]/YùÎû@à &ïÁóÜ +Vx´ÒVx´Â£ŸÛÊ%ÓÂå×RÓZºöq.|æj&çULÒ+q4+ÜZO¬XÐ9HfúF$‚|‹6K[ЈÀw+ù(ƒ¡ƒÝ‹¶ïÀº´ â<Úáяí dÛ¹x·£‹vzю°Ú(¶­“8èrë96ÃçÀ­5ä]@Î:r¸ˆ;zgA‡”°K2>Aÿ‘‘ÿ†‰àb{û†îÿ婋žt¡Ó} ÆÝðèA=ð=¶=ô¢‘u“hß à$ß½ÂÿÝV3uÌ"o%9Kɓ³‡ó˜˜FbvI9Vú†ýçÿŠá#ò=ü u̐ôŠÇœôc@E«?e¿b(íE½¬Éa.¢^zÑË¢CœU‡>_¨Z§>ÉQAÞ\ò%!ÓóÔ¿_pÀßû5Ðë5AG¼øøyŸ1“~ ÞÇÁ[à”/Æ gÚßåâ?‹>Ïq¼Ç&8Ç¢ž%øYzqö¢ªÉ]ÑÃ9@êŠ"g Ë5à 7çÞ<Ǽ±=fð/΀wÁ9¯Q|Pšþè5X›Ëðø„½r…Ëÿ*ú¼Æ¹Ž.®Sø Ý8ÙçyïÁøƒP  Œãq«êÜÊüÃ-œÆM\Ç׸ž¯p@ÃE~‰û_õ).ô: x•~Bƒ>ÖG¸«¿ë"QþâñUàmp¼þ›ƒƒA0ˆÒ·ø™Ûx̯5’øc‰=‰ØUº‚›¹ Kðø+<.à$ÿŒë;?á1?R‡>@¨ïk?íéÅeþšŸ«´Î­Óàx¼ +^ú?ni 5è3|Õ5¼îezqA#ˆ_Lì +ý^.ê¨Ò{ð8 3øºw𗿂ÇÛð8‰#=ŽC=†·:ªn$ó2µƒÉyÒ?t,¯àY°ï?8ÜìVrŠšüôÈEžr¤?ŸØ£éì8ýGàñ:ërX³ˆÝDìùÄ^‚³]MÖÇØ2mú›ù~žƒAÂ馲.²= ö€Ý ÃËá&¸æ•‘GZ§ÑÅq’+œžYȑLüLV·€­8†ØDžDì©ÔRKü‡©§‘øóX%Ä_ƒ"6’c§vñv'¬¶³iÚPÄ6Ô´…¬ül_‘óøÀ+uÏö:¬~ÔãG-rE¢.9ÄÏ¢²BŽ«1į þDâW¿†c³Žø Ї2— …ø›Y™NŽõçy: ³ß°Z_j%yWxñ=ð19çÝvž-ÿª÷ê¡{ÑE'{¤Cfò$ÃIÔløêqÖå1•¡Â ä˜BŽjrԑãßd—kLÛçÆî7ÛØÆ6Æ`0`n&&`CbH'@B(ÈHB¸Œ„[Fi.K›¤¹@š%Yše (m×fiÔ6AZ·N]5mÓº}˜¦mŸ6MÓ¦MÛª}ؤjÒÚ¥Õ4ïG.S¥ =zí?¿ÏyÏ9ï9σ『ðw fùå ¾8À©¦‰è$7e‚l‡{àW”ú('ß¡Ü¿$xýqéýê֐§™ó8áÉ× îÉ1Uaû#ÜÊf<ߦg¸·3Øq;¦ˆËù±Ÿ§cX5Ê#DfˆÝ=úÙü ˆ‘MðSÚÌw)ï÷h5¯±Þàû졅pÎ$v1ÂiåL.x +8K)gYÃBðDài†§žmðô`ÁÓð ³÷$Ÿ«Ÿ]vàÉ>N×K<¶n²¿î'ø2LYÿ%u )tY¶€='±e¿Ì*•³™à³í\v/ä÷q~Jüþ¶¢íŒ êM5¨+É¢mIÙښìQ{r‘ڒ˵9%¨M)aES՜USj‡6¤õª1m"éãZŸ~Dõ ªËXR(ãžj ?Rá/ª1~ +bª÷áü:mí:rã"8…œ+GS ‘¿ˆðIñږ™¬VƒQQƒUͧ6¼Ú`(Vƒ±BãZ­7Ö«Þ¸Qu¦6…Mݪ5íRiŸª3)˜yNUæ› +˜ßV¥ùUX>T¥å3S¼ÿËÕÒKH…²‹õß'‘bCØ·©ÜE¼Úȓ&Kš"æL­3ÛTgÎUØ\ Z³_5–€ÖZjUm‰(h‰ªÊÚ©€µ_•ÖQ•gͪ,ëùm×Ub{SÅöªÈþg;>S‰#¦{LoÀ·&‘çÂÇYgù¾Ÿç{ø ¯(ãC$;I!›Qk³,ª¶ekÍ­*[‘*m媰W«Ü^¯2G“J[åÏîSIöŠœ3ò9O©Q–ŸsWޜïËãú£¼®ÊwÅâ6ç¾ ÷%æÈ3š¬3ŒIcuèKZ~vlÁF9Õ{âÌIW¥3SåN›Êœ.ùù*Éñ«8' "WH>×涩 ·Gùyƒòº§åv?¯<÷U¹™åʬª‘©ªQÆ5í`‡ ÁQ¥)-¸¨Ôê[J®þ&øø›R‚ÿVj0¦œÿ²ûÌvƟ^îDw¢‡;ÁX҃][ðK> ‘'ø¤Ÿ¸êâd­MSfI¦š,kr@¾ µ¥Ê¨­Vz(¢ÔP«RB=J +)1<«øðÙGƒC˜ÎF%„™-Ÿ*.„–ÿE8O#»çwr'EÆXw3ªnçy~iÀ–jlõãñq0:™R”±Þ¨´õ¥F²•ñ()R¢ÄH•â#õŠkˆòÃÕ‚/Ó-ÝÀ ù ø+`ތ ¥àY„óä€tdw‚ŸŒ²îâûSN’¬Ýû0›çuØRÉ;ØãäHfb•ŽM ýˆŸ~fº/Ðäwà‹ø¢_ôዾÕKÁíãÂõaxõÎÚ†¸í eÝØÐÓ"Ü'qÕ!›a$ý|Þ:xĞâqb€M¶ÊÀG‰#œæÊaƾÂ{i°{™s÷ÒpñÅ Åmx â´A±çY€2`¨Û͐¸ëÁѐb: ß þ}ø0q8Âk¬]‡ÙAî(ånìÊbL4ðn"ÐLÇ„àvLaÇvL"„&i0“øb’K4A<&è‡?Ã¥C)î{—Ãþ†Æü1ˆéœÇŽJÏ®Ðw‚Ú ցJàå™í9>£«Àóøc;æ±cžÜ˜§áÏÓüçɋ9.Ò‰?7FÒ³ááëBîçÁ_HÏþƒˆéùçx| +ó¸:;_ ˜ÚÀU®:G;0‚€ ¦ ê‘Ø\|üùHäÇv,bÇb É,RØ(2 $Ôy{žœ8G^žå~žù;¢õ?š‡o’½سóEi㗩—¹‡W¨ÀH*Ç_…ã%p p ŒÿǍ' 67ÉÓ%ìXæž,“e +Ê2¾X&±–8äÒ«¼ó>_{ ðîÅ´n¸šá¨a¿"ör܄Ÿ²·*ô_üŒañ î|n]ÅàîãÁäMð>¹gV°c´B~®PøWðÅ +I·Ñʊtÿç¼÷‘†9c/gÛgè–TW6\Æۏ÷_ݛ²Â¸†ï€oƒo=^I/ÂGéÎ!†R6òä¿\—{tÓåƟÒ6½%inmzK›¦÷¦4I¡IKK EZ.¥ÊE ‡¥\„1AA‚È Û‡ŒÊ ásˆ²)Ê`âe2Ïq2&‡s“ÉӝéYöiOÎæöÇs~é/éû<ï÷ò¾ßçÔÈYzö,µÑG¯ž£G΋>ۇ“é;®h +{mfŸ5¼*c?™ìÅô,küòôs¼5‚§Á™¨1#¥ê‹šÄ àbÔ°þ¼>«œ_×8?ÿ@}^§GnÐx7Øüu6vý̀çý/b@2°(CAw6·Ú¦Ïq-gÒ¿ƒ³¹£º…óùÇu7ôg¼ÝÇ8Î?R<7´{—{B¿GÜeýEï³R?.€ŸƒÁÁÿj臤êKüÝ?ðwðv·TÃú¬=:‘uïч踂ŽË8®÷9,ÞCÇ%t¼ƒ¯z gz‘â½@ý{–཮kz _ó«¿å>üŸ†/À߈ÅMá³ó_¹p•ê·ªÒ»øÜ·t—ÞÀɜGGñ8ƒŽ×qy§qa¯â6†ŽWÐqR›Øý6ÒØKùü'HíÛz–ȁé0Øvƒ]_Ñp|ܟ>ðüݛøªóÄâ,Þî´¼:…Ÿ:©áú)îìtGÇs¸®c8¾£8À#øÜÃè8ˆŽZ‹»Ü¬}äd/ µ‡_õR@»ôm!B¾‰à#ê_Ây \—¢åõªbá3Áe‡'Ž"Ö¯¤M‚z†ÚØG<ö’—ïS»q™½šÁú¬?_;µ„õWh‡Ö‰²²‹ +9È1ö’%c›ôيP9œ`-¸ çïÀђïo±c-™Ä^,p9õ=å±R ëûô˜BÚN<¾£Q¬?–õ[92ÛÙõtÖïdýn=L<ÖéAÖßȑ¾]«Xe»¹¿»\Ÿh¼÷E±ô󟧢­x8zõ‹'¨‹môH2ÙG>eè÷k=:BÇêt5ý²J´R“ÈÂ=pt±€n¹ˆ¬Ñ½(\ÈæSÝ°té*ôO²ù.r”œŠ—ž?àä˜b¿Ì˜×C"œföã€'›½ÀQÆê~ôÙm½«m†§žIšG<º4›µ¡æªv³ƒ·û©âŸPAo“½Û ¢É ÿyš#äy®™ƒ©Ònžs´mE×»o +œö” ž8ÊáðÃÔ,ÕÁÓOUÑB$Úá™ÉúóP´”Ê]£»‰ä*§…,§£ÆéOdñ_ 2€“\ùGð³{?vòìáˆßÀX´-Ë•s^tSŸsd…+ž\x +á)‡Çcž:ª³Êh†«ž©¬ÝÉ_‹P¶’ +~”êÙÅ/k$?‚f§OþàyFŽŒ>OqÅm›¸r¿ÁѺ¼!.s¹Sc‰£>;\™°ä±§"öã¥üp᪇«®±pMdíptóv¹†‘Zª«f ³^Ðéw@dGÝ\‰øȝÅä¬çó +Þ-a4œÇuÓAL&cÔjHÖ¸A©ð9àʂÍ͞Šàò*P}LHuƒÂª4Z5±Œªê¸9Âàˆ_'üùâŸÑ`ÃKª0\REÂ-U$Fpˆ+mw¹´£‚äª_ÃÕ²¼„±‹q¬ÓÅlIŽî&&cÌqjHNQ8Á¢:Cšj²U“¯`b±ª+4$±JUIµ +$5ȗ4V•ÉíªHž%oÊ•¥¬U©q»ŠO«ÈxB…ÆwU`º¥BSDEàüOùèÆ®GÀê³m%ã#P1iï×É×(ê¤ÞbPµÉ¨!F«ÆtùŒ9ª4y4ØT*¯©Rå¦j•™†«Äܤbs› +Í*H½WžÔ5r[¶)Ïò´\–ʱ\’ËzD” öÃÿ$#Fžöá#ϯñw泥¯8!7#kȍߚ¨ +‹Yå›J-*±äªÈR¨BK¹ +¬UòX‡)ß:Jn[«rm3ä²/T¶}•²ìßR†cŸœŽ•îxGéi•3-»ˆöÂ÷Ü[×Õ1n‚ÅŒ€sð¶ÓÐÑJnFS'džR¯ƒñ*¶U`·ÈcO“Ûž¥<{¾r%r9|ÊI );­AYé㕙>MNg·Ò+åÈØ*{Æ^Ù2^5óMð©l™ÙÁöý¼›ñ³kûî‹°HŒ=S°l-~ò@­ £Fª¨‘òÜy2“”ë4+ÇiS–Ó©ÌŒ\P¨ŒÌ +93‡*=+¬4L¡={ŠlÙ]²æ< KÎ7•êÚ#³ë¸L®_Oø̔zÙÿvx75RxÚeXՅ|ž…¦v¾‡Æꤖz P#¥äÆí6(Ëe”3Ç¢´œ49\ÙÀ#»«L¶Ü*YóêeÉk’ÅÝ.³{ŽLùËddHOñô*ÙsLIžsà#>¡”|îo¸¾ ï#øØÕcð`Ÿ;Ð3 mc‰ÑHrSCn|Ĥ„˜ä–Ä*½ Y¶|³¬ùvY<™À­TO‰Ì>™ +ke,¼K)EmJ.š¥¤â¯+¡x£ ÅßU\ñQÅŸáy|Î;îröÜÃÈ» °ª…žÝã±chiCG3#àt†Ð2˜˜Ò7ÙÄÄ^ž ÔR“L%V™JÓe,u)… %— VRYH å2”·*ÎÛ¡XïÅx×K^n"/·¢—ÚË´àýŒä2K°ç-p®gä]9‘ž]mØÁ œ èjF_-CF2ó֓bâ$&Ö@¼Œ>£’*-J¨L“Á—­x_b}^ òSH~‚ègCéÓÀc˜c ê~†cÿU€×óE´þÍp>4™óq*=æNÁsµÓ¼–aXFßh©ˆ˜å11×Æ+)”¢¸`ªb‚A‘ M¤h‚PˆÂñ¡i`À†0MA Cá?ÈÄV†jæ)x6Á»–‘{ùLzÌӐßÂû‘Ø£êVB†V7ùq7 õ“Ò§¸‘É$ŠK%l\xaÖ0¦©Ãt˜‡Ù\xÀÛ ÇÄ Ç¸ÔcBê¯Huh¨cžCæÆ걓zœCO€N0yy@Ë0¾÷—"´d£×F\Œè1ŒãR‹¿ƒ¯kæRivHMdM4p…ÛġӄØ&’Û4›€â5GoÅLíLk£.KhhŒh öký\éÁni)![€ š9ŸÚ<ÚÒºh#;’?é;: “û6ÎçÖëá¶æ·+X¯¹ÌyŒ#ƒtóöp÷Ò ¨30hs¼1 ¾×;áÿü 9éâ¼tG7Úè¦&Ý4¶nrх¨ºèU]Gyî,¿A—ûÿ¡U»‘œEpܳŸÖÅ:^Jæ<ÿaÖ<2h6¶’ƺ £õÿð’gG£‡I'¨M/uéE½è³FÛG.úYë¥'ßṿª†½•À; ¾1p¥a0œpÖö¯{ðLߐ {%€W@æCa„!WŒ®Ò›ÄÑOý c *ôÍr1@áØÔö_RûœÉÛqpfÂËL´tL¬ôR€ãl`íóþuÁ€ü¦tÈ^o$6hVßӐqü ø-ø„8.sf¯pé†>¯rF®qØ®Rà+Ü_W.0Yë€ āt0R·™Î¿gj¿‰sø;Îå®éÄ×ø˜¿pH¿ÂÙ}ÁA¹Ž#ûGøGÄs"^¡@Ÿà ¯·õ‘¾ÄaùÍGÈ>|­Túp¾ˆ!X·ð4ÿT |ÉpåàŠÆ²~kÏÒg8‹Ë8K8ßÇG¸®‰ã<ÕûÄñNô]<ÍEüÝD4ËÏ(Ìy}¬×YÕÏýZ€ûYðã;bà6×ßÎÔ®OñÀÛ}¨<ý +Ÿûnâ-ÜÌÏqSýäãMâ8ûz{Ž†õSâx8Nk{ÜM)»(é3Hé4’z¹~=ÈëÇ1pÄp;ÀÍTÁþ¤_+Œ}Xኁ' Ž,ý?u§ô +Îæq¼@>zñS'ñuÏã/ŸÃ >£zŽÍ:=E;¦§N*Ò£nž<¨7ÈÌUí#Ëû`Ý :À.ðœ_ORòËìܠԍpÙùµ/±ç°öh=‰kë!G¨Ë!Ü^7îï ÊY¿ŠöñJ¨gýõz\›áhçßÚ×ÓDt†*½bn¨ÞÐ 6ëù^ Èþ489x,Ã؋®h2šG»ÊÕâØM>:p“í¸¾6üåNèv4²­¶Ç#Ô¥Y ¬¿E‰fƒŽUŸÖRÁÕ0®‚weõÀÏÿ ÀmªíàX åu’‹Ç8#» ‡ŽtâÏe‡£ÉöD®ŠítØŽ2­!ŽUÔeÿ/ç‰Z"\B.jÈäƒ(f§¤mVÃ]ÀÛþ£O{í jþÖÈ­7­\´ÈÌ~ìð¸©tûÈ þ\âχc“9Óà)„§ž2xªY»Å®C-­Z@öæ³³R\ Ú,F}óàö£œçŠ9Å(ô48ĵ×É5¼‹xèêƒWã:EÀiU5YJϨá¼.&Žjâ¨$Ž +‡çn1 öBxæÁSÎÿ¢Ú(fYjç›C(¨—êõÓi>'{·ogžçÊïáºÝG;kç}+ñl$n9¸Cà5Á¥…r²§xx’ÙK<¹ðŒ¢sG“ášÎ‰¹®x*‰jê]r¶ñí~"}ŽnwUL%oß NqÅOà*c}œëe;WÝ&âYC›¯%/‹×P8¼fòfc_1ì)žö” k.\ùp‡«®™ṕg•ªáÓÕt¸ÔÉSOñY:ïຎo'ÿž`ôúQ:9-xÛâ©w3Ӑ—…þQ‘zݯ>;\±p%°'/\™p ‡k4\5†hò‰r¹È#{#PN. +ÆiÊædgqeê—dñÏʺèYŒ‡³¥½Ã1@3¯åz©MaL$?óÉÉr2ìC¤&…X5>È¡1A.å%jTPªFgiDð «a!w+'t†²C‹”V¡Œ°:¥…7)5¼C)áO(Ù𲒠å1|!OÄwòDútÎ.®÷ÝX‚m )‘1—‘›PANŠ©O!õºÇç´†*ßdT^„U¹‡r .eGx”‘¦Œˆ¥GŽRZäyS•bœ­dS¹<¦¥J07*Þü¨Üæ¹Ì/)Ö|Q1–ëà{ÅZ|zþýxÈÆÏ- ‘k~ïkˁ撧™Ôf2µKmFØ•i1)Ý¥Ts´¼æ8%›“•dɐÇ2\ –±Š·(ÎZ(—µL±Ö%rF5(ÚÖ.‡í¨ì¶—e³]_‚[¼÷©¾}ØÃvÆ­–IŒœ¼Öãm3–ßlò4Lb ÉÇ ‹ RšÝ Í¢„(›â¢bä¶%Èeó*֖£[¾œö»mŸ%‡£TvGlŽõ²F·Ã²D¿(Sô™œ’Ùù/ÞûtþN¸Û𳛱ˆëA¶ ›4Ÿ8î§6SÑÉ42’ÚdS›wˆâœFÅ8¬r:ŠŽv˝,»3äÉ木¨˜é²ÆË»Hf×™\ÛéîR„»Wáî~Ü×ÀM>ãþdß{àÝÁ¸×< =‚ZìQ1•ð]!µ™2ŠYäQ›,j“LN\ñr¸,²¹ìŠrÅÊêNi²Ä —9~œLñSeL˜«È„*W*,q‹B=ì9¡ Ï +N¼¾UH¢O]pí†wûLúÂ,úXÆߕ|VLl÷’£)Ôf9É#'äÄCNœÞPEyL²xl2{œ2yâeLJUDÒ0’Ç(-U3å¤Ui0Ÿôv½|:É®Lô1v™ +Í¥B+×tʵr‚)—ØD]᥊yÐÙ +ݸü~0)\ü*°á¢Ö¸É½¯Ã»{‰œXfm…Õ°Èÿ³Ù2É÷V¤á|ÒßµÈ=růËĔèT£±MÐTÆÛ©ª±jE¤Z­WíÁj©^v›q–¹q˜*ËBÕ˄ΆKZã[µo¹5Öc[­¥_ƒU°`¥8,õŠïGñÑ ¶ôbK‚^2ٓ:£±hhÓ5“i|1•/jöZ­VXA>üÒך–Ï_Ùìé,Nš7Ѧ _\Êõš[=_Ôi¼uš`xÔÑD@Öyyö°_Í2%Í´¤ÍxÁ>r‡Ö؏{Ô¹r“œ`jãf>Øè+¶T±e$9 `cöäðU:› I ~Š%‰‡‹Ù±ˆ/袁/“ñh¼… _è°òs)q¾©qž…lî‡îÑ×â¾Úêµý´K·3[èj¶’ ›ù¾M¹ìL_ß>Ôüì7\;Ö²c­˜4²£Q“kTT×((kˆx¤[í«w +ôሕ¦æ¦Èå¸Kk4‘ëU»ø@ú®ò{.ÔJ£1P╢4à™ öŗqEÛÚ`ÜƎ­ü±U®nÕ\¶ÒÅɼE±ÙÌi›]lÓÁˆ'$à“Ó{.þyìÙˆǵ°ð1€Ja}ü€ ˆ ð¹!»ã÷…Ïš¿:mfG3m4‹I3]4óE35q^“÷'€Ç$ã;‚ði츎[Éuñ är@ +1³T÷ƒ<ȸѹm¸ µüa‘éÀ-ÿí߉MKvǀz«˜´(j-|ÑBL‡9÷ðÏ~×àô¢3ÿp.ÇQ3 xÔ­ê€GònÃ߶dÜÇàN¸;¹|ܛü}áï6Ü÷'Ѷ$œ3'ÙqRý<%&§4ãS|qJ~œDzRÍ>ù”çދ•x/Ã9×ÅÒf ž|®Ê¸'y®Òj= kÍâٱ ]øý0¸’Õ!,£‹Ú£p~ †œ¥Ó³´qÎ0rNÝ<ÇçˆïüQððٗcž;ÖÞ¥¸Ë`|øº<˜\ø¾“äø^ò\e>´›ö¥Pë³ÆF<?WŠÃO£cq|”€x™¯ª£¯iøoÐç›räM‰ö_¼a«{ý “u| ©= Ø&RÿŠKâïæ忚—Û6¤¿˜ÛßW$þdvÿƒ}ê÷öºßÙ*ß1?ÿšX߶¥½i¿{…#_â¬ú\ü–YŸÅ3Nmc}¾ §àË6ü>±Ó|d†ÿÀüþ¾)ü]“ú;¦ø_šì_³Ãü‚/±ã…ê9ûÔ³ +Å3¶±§%êOl»OIœ' ø•3d,‹ÓmB¹ñ²=âE;ÕÏbW8{¼;Ô +Ã,g_æì…Î^êìUÎþ*IltþB¸›t®‡l®î ¾xÀÛ÷Åý×Çá(´À¡¤ Ÿ$¹/¶‡³“gáÊÃÓÇ ç—:{¬³'Äivœ—6½l`÷ÛÄîµégÇÝvÌ;Åå˜Ýêö8hûCºžŒ›ãûÒûQú§Oõ)ØÍ s‰'éÀÓI©=Ò.ù \¹xºãèëü¡ÎÅþ±Îïì)îñç×9žó)#+œ¿ÖùyáJ×ø¹9š¼½Û‰»xs'5íÀ󠒡 Tªx>)í3ÉtSI½•‚/ WBé)t~ÿø¦-ívì·Ñí£kè´É~¹ÇÆ»›FvÑÈNZÝÁÛí™ÛâªØâM¬ÞÀsëEp]ü†z>óDk;áùdŠµ¥ßédI8š,yùb¿iŽ|ENàü­b”¨WÄVûåf{Šc–ÍrŽVրco¬“5Û(¥É‡¨÷žX‚e1/âýÜ sÐSG j+ƒG’¥Yùv¿œ™øºáꎣ7Žb%8ÊpTȊ*J¨Á3ÏL¸JYß–ËÙ²œ_h9õæ +ukŠ<©¡q쨔+cåìv”Ç0•´ ×jk*®zç/jWÎPY2„ÂÑÄ@º8~ïRø¿¡5î3~Þ¦µnÌ0^iÛè³5Ə%Fõ9F€|2™fÆ¥eàÍƙÀW€µ®~î5ˆÃñÆUƒùbµSåÚì'ƒúRYo9Z¤öRm U…ÂNÿˆÂuo‹Ýí€Öº¶û{={V 1ŽòI=ŸL3¦N ›±9)1ªkב–%©‰Ò© ¥ÅÀ”þQœ2$ú§²(µ"út½Ó¦GQÚÜ(L_=Ó7E÷Œæ(È8ù§#/ã|$2ގD—#ÑUÏÀy‹Õl¿uàjãÎ6¿×EWØmçóÉlqšb}'6åt2"·s ÎîºæD¿ŒDôÉèE]zG¯.ÅQØuXôì::zdVEAfmäg]yYË#‘µ1r³›àHädŸŽìœó‘•ó|äïÖ8†ÿÐZ¨”•#èåþ_æóyì›)N“è¤RlF‹Í0±)N¤EQnfôÈ΍îÙyQÝ3ò³ûF^ÎàHä”F·œ±‘›;9rrë"»ÛÒÈêöõÈLì‰.‰Ã‘‘8é‰Ç#-ñ*|èïÖ¸ߍVÃkZ;'}ý^kŸ\ʖ9[CŒ¤Åëkä(±)›þ=;EaAzä%²påFn·‚ÈIAqü—ý2®ñÚâø¹Id"‘¸‘AB’(‰7Q\³ „! bŠ ©)D1‰éQ5 mQ㫚Õؾš§˜ªUZ´EÍJI'÷Ïûn¼÷Ö[Ëëzß^k¯{“½ï9{ÿÏŸ³w)‡Ê¢¤c aë¨ÖeZ«2ÑÂRÛ[Xh‡ sí¡q’ý¬ö$z}&fûDöUŸY‹™¶šÀˆÈÔ[SÎFÏÙè8›0ñ…¯*á\ÎL8”µ¥´öÂV[FØ8¹k'OaUÖOX– Îu„¹s3¡qahuaq¥—u¥1v¥Ùteæu92_¸<ÓÉ;“}G2 ¦ÝKB»ñ½#ÿ‹ ¶&`T—q©&˜€I%ÆYwøªõ4vî6ÂÆÍNXº9 + 7gaæV^hÊa,¹ÝÓ½)C"ƒ¡Gú`C³îÁ‹äÁÌëA—àN îyb*ùcß4ZïÌ²IhW¾GóóV ‰LêgMb©g½Xޅ8|ÍDIQÂËNh<)OŠÇòz”DòDïF(½´73–Ï@tßi–½iN½i6½ˆÁ3OLfÿ1ì;¼ïCuIËمïQáÌ|ÄÒ{b _âð€?Zøj`&¬Þ±.v?._ŠÆ ×û¤Žþ€éςþñ(3–ÿ8”—яWҗÛ>Tz.²Ø?ƒ½‡µ¥.­7ãi<Ÿ¿%ÿoD,!`R•8¼—\à‰)ÚÖÐó`.Ð .¯jÄÈ¥HB–@H‘1°%Ú폎á@TèªXb¨’/&f:û¦.c¨K4®#1ðwsb©‹=˜8|ÁÄL´¤fÇҖœ§µxxC¹ÐCxìtœ‡ŽóÐÁ $2Nºæ(‹ê˜mt †5&j0T?ŒCpmG2Žaôè×EˆhË9K(ñU/0q&{–´ž@âAkõÁ¢XÔ =—ˆžóÐà =‡§ÇYÏ&zfͺ ·uÞêЭÕ>Hð¡VË^iPfPwމžÄЋº¤”ÂùŸž¸‚ˆ¯˜¸±Œ¸ØlxH9,4œÙ²…5 Á‹f`Ñ ,ÂxÃ808Æ!†qÐMÙ )]I†ÉÆ l„Þ"‡1Ó0BTIýà##P$CcbÑa«Ü’—2ÄS’c5#&šƒF¡Ä&ÚG;Τ-gҖ‰‹Hê#’óˆ„D‘¼ ‹´¡>[3ØFÐ5¶b( ¿Aüb${¦¼išz¡Ñз9×&žl^}„p"F;b2!µ{asÃE‚‚­ +D&Žxâˆ#Ž8j$,byüb!p,dêLðY¼õÃ]ّ!1š‰¢C¾H£l‡p…õÊÏøŒÂñ¢Á„\q .»÷…°àçâU%NšLH„ö-Rø‘dch€’Ê +Ñ^ô¡û@äDˆ•À½3Hvägxíq™|òDêp–„*Ýжhc´æHêuå»}û§6¸ñŠ7jê«ÊŒ› +?R‰#•3Iõ3<†Ã ôP€ŠSÊ,§>Ÿ†ˆÅ ؞„Eé†q…„Ž‡™\·¨=ß-øR'6û†¦;Ûø9IA³Š”zɆٜI6—|XdAî,@œÄW°æÖ¾+Y?†µ[ð»Ú“©C ÷iB”F-¦›ý™(¡ÓŠ †-A[(Äã÷¹¯üožq@jÆ †âÈ¡^s8“j$,A¨E$½hú~?‰Xhڊ½ôìÈ>Øǁõ-æוaÏ0|É!äStÅ+ŸR)5ÚDÁ@*zm«ah’CãFø±nl¢V7q¹m‹Íp›nÂyÓQњ+£{±ŸOš#Ok ¹ßRã>«ŒëÊ5yî]…€Nb‹ñs›0 ©;P¨^84~…îEš±JˆcÜÇi¡¶Âlª)ûÁŒ%dátÍU¶Ÿ[ÛPYúÕÊ‹#Œ¥Wq†¢ý€rF‡tÅGz]‹¢âî(9dj_8ôºª`¿Õî…]Äü¨à°­ìK‡J7HŠÓK‡wsÿÙþä“Ø—1TTÖ..Œ(r°Û®”ÅÝõéѵ}­4fŽ>¦z±‹{–ÏŸ·à£µ»LÝAª¨òïÊÏ»sƌzfÊzkfL°½(¿Ö„ýÔäCõ ~ h?›j¤}«CJö§3ëÕEÐ%‡/c_TV¹ÙJÓ*½p°ÎT°_ëú²xEêì×y\Íùð_’^HÙÚ¨;WiˆÙÉÅ Y¡A›"ÝÒ­[öˆl£!¤I²vå–^يRª9­$ÊV¦d2öåþnqÕy>ÏÏ=/÷™—ë<öy÷;ßsÎóýžç+N˜Èw $— ӟ°ümWy0¦’ù\°*c »†<0gלˆuNä@§Bö„‡É!“ˆÉ ‰·ñ¯+‘‹G[Yš›uï?Rê|÷^î—Èrr¯ÝýH®¬/¯坑žíëªüŸÝí,´~$¾åÒKý]×Kn±`ÅÀÿôlëï¥ò‡Á=ê»Zò5ö[7ì‹q|g‰Unr§¯Ä"~²F§8ð—ß›-cYþ¸ÙÞ đ\ೖ-K1¿EsÁÁ÷Ø)–`[ƒ©‘ŠË>©ºzy·H–•™‘™]PúF(볫Êܤ;ËdqÁóF™µV –Lk-²ÒzßPߔJäùK{×wÜWÇy~Ç×P®'C8Ød,ß´.ü†“®õ Á:ÚöÝJô£@7 òdØzqFÙ@ˆˆ` €Và"°¤ 6X˜ €#‚Ÿð¥#Î ¤Ž Z¼ÈÃÍÅÙe¾WŔõùÕíԃáþN~ÒaÉ~¿qfuÝÐ#E".Ýlßйy.ó’?XÏŠÕ µä;®ïmÛ HK¶=‡`(tu4äG!g‡ÔnÞð×_˜à:‚±^!ˆïB@——zhCÌLZ8ÄlÐ$@®ò +®²+è @ ‚eŠ°!¦OÜ¶ €Ax âCŒ8ÎÊÖ~ⷎNs]=¼/‘˜I•õûÖ£ü3Ñ¡¶M*{q6lî°jï¾K~!}9Y¯áËÖÅm!ÞóÐ!í€Û_œ7òHlêÞ°ˆ(­®Qpp†‚j¢`Ö0G°ÀXs,Dà`+‚¡ØÔÀ/xŠGÐF°@ó§ÒšSШ +sÐ=ét¢®##URuMÝTÄü„¤ó—³ò‹Ëî?|òšÇÊúôzq+[:¨º³ÖsâÀê‚åMžnþÖ´áÛÚËòú›ä‚¹3´‹å3šoƒ\P…¡7.‚B ¬<¤L 0 +wzB¨ýFÁ1¶Ê2 +òȆ×èˆ ÀDG­r€ <ƒ6§Xà`3 +üˆž83ð|6 Ô~!Æ]{=i¶»ï’5á»$€²>¡*²OE®t³OˆªŽ¯œ1À°Ñûoâï,Nõ4•ÿªðGO\ٞ~Ùêpc݌)ì àGàRÂÀ0X»èÏQAÁl²(fà4ˆ¦ ƒM<ÒAoc0n¦`—¹¿á"ú§0E°€>‚§“)hŒ@<×¹L"]ÉNÒÚJY¨·ùs·Á®«r ,¨'ùé’%‹ßìçhݹv +ÍÓÔ ݆/¢UÄ)ã öÐ|›íáJËæn¡×P‡¡W›‰ +Øx ì£À—•°k’àFÁEà‚Q®…`0|”=t€[“ 1x}Ôf«pÓÁc3Ü°A&€ŠÑ਎pJñù  ~ ˆò7%µ1ˆû¦¸ú,Û°ëPRN¹Dª,^ïHýU0u€©±Žf>Š‡èÏ7웻ñ]zQàÏZV «¸ÊÁqúˆ6 S𠎬d`Ç0  XA#ø º°G¼V´Jè[ò(ØÉÀ9 +RÔ¡àWvHýoÃ^0¢x¸3À bx +p`+gQ€£(^±£‚1£ö¦¤¡×±ÇûÙ>¡±—9¨½Ú–ã騬ÿ¡*ó®^¾œxú§ø#qb ,Y2aHwcýVMëOüb’/f=-Đȁ/} Öô‚-ö ´£`=·œç€¾}’ék஄)˜ÏÀ +Âð§à4ÎÜì€`"þ¶ Cø!À)çp3:ÊmðÄuŠ@ÁXoQÄv£ ¸£þÀn¢gn3»”ñÀŸåw:sõö+*ë÷ªòŒÓq‘ÛÂBV- ü›—‡ë¼M$Nre®O{®}v“ ¨R`ÍÅ Â8 3J°yM˜OÁ4ì)X͌ZGøyºšQðj{âDM {ÙÏ_πÑøøY ‚ÂöžÌ¸ÇÓºª|)ýweýŸUefÂᨈðÐÕËë.Aó]]éãdci¬§I~\w°„í<Á—€‹8ðº/–t•î èP°¿gÛ+÷ùe >*7E`S# Á Œñ3\ƒG„ëHpχHâŽn aKS[çÕK 5Úuîk;Åmɶc™Õ×Vùރ iEÞHDÊúòêíÓ_+ïß¾U\”'û9GVXJ¬Ýë¹9MŸ<~̨áƒô±´èփ™I+Õÿ¾qøÖ¤ij‹L9%ý¸Añ©„0pŒ‚cF"((…`¢77QØÈÅ#¦'q»Üù h[:à-H,õn#*Z_YXOõ +=V…yí!´pÁ’°Ýñ‹ñLYÊú´zY*K;—x2þð˜}{"wîü7ûeÔrÇñ„"Iwž:G”Sy¼\šV[´<¬6'RÜÜÕ¹n%Ü:溬'5Ém¥¤ÖDtbè¸Z·¦òºL\·&$ +³–ܾŸï~v珿ן{¿¶}ß»Ïç÷ùœ<%E…„&Ýg™§‡›ËÔIN£†¡DHÁJÓê"ÔNƄdDè]ƒ Qè!öcØ@ +°d *¨°>7 º8P°W% \ò² h¢`3‚^l:®9º3â Ðc<…ÍxWo67µü!ÌõúÊʺî¡Ìó·[ñЈZÙÒI‘ü4Ÿz{z?cŸvTäg‹„‚C |Þ®ø¸˜Xî.þqDh\â1ÓyâXǶC>¨M|;…“egA¸ ¨ð:܂ 8XJæ[7XôIÐ|0|ÿ—ú›¤N‹7€¿ áõw[{çEkvËàŠcàJȬÅþìÈýi%J-žöQ–#¿u¯Ý|FBòËéѵµ<~ÐÔ V©Tõwž|“„ä_¥JvV’—{J,Î͓ɯ)›ál/`¯ ¤ûùR|Vx¯ð¡®fmß „œ96 þpL1c½ÐÆ3Y0†Ïߜ,‡§/ÿ–™N‹ÎPà[@õ¶Q†t´+eK¢TÙeæ9ۏ-pó +âÈ®|BpWãù©×$ˆ ¨ï¿%IHþOÞ¿y­Óé:ß~0?_(g¦‰D¢ô,ñ™¢rE}K¾cШ+)ÊJ_*=ˆÍI,€?!ñ4Ðl=ŗ[ P½Õ®¿=¸м [˜Í÷þö ©}gö˜… OZO$oê!xLõá=é¥5ØdbBCö) ÉO¡Õ´¶>ñRÛIðrþ\šš’r"#;¯@V©2[ƒÙk©þ«‚˜›cç›Ìlz½Œi5a#*¹XÝmþ?”;¼6ñ2.Þ#œ:ĉ֙Li­Ã’¿«ßÌðü_8L+ +endstream endobj 9 0 obj <> endobj 18 0 obj <> endobj 19 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 15.0 +%%AI8_CreatorVersion: 15.1.0 +%%For: (Ben) () +%%Title: (Untitled-1) +%%CreationDate: 8/1/2011 8:34 PM +%%Canvassize: 16383 +%%BoundingBox: 82 -553 493 -229 +%%HiResBoundingBox: 82.7622 -552.2969 492.2744 -229.4507 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 11.0 +%AI12_BuildNumber: 39 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%CMYKProcessColor: 1 1 1 1 ([Registration]) +%AI3_Cropmarks: 0 -841.8896 595.2803 0 +%AI3_TemplateBox: 298.5 -421.5 298.5 -421.5 +%AI3_TileBox: 0.040039 -841.9355 595.0596 -0.075195 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 1 +%AI9_ColorModel: 2 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -687 184 0.5 1252 619 18 0 0 271 129 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-8 -817 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 20 0 obj <>stream +%%BoundingBox: 82 -553 493 -229 +%%HiResBoundingBox: 82.7622 -552.2969 492.2744 -229.4507 +%AI7_Thumbnail: 128 104 8 +%%BeginData: 15054 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD0FFF7E5A3584FD7BFF59352F3559FD7AFF353535592F84FD79FF +%35352F592F357DFD78FF5935355A355A35FD78FF59352F592F592F5AFD77 +%FF8435355A3559353584FD76FFA8592F352F592F352FFD77FF84355A355A +%355A3584FD76FFA82F592F592F592F357DFD76FF5935355A3559355A3584 +%FD75FF7D352F352F592F352F593584FD73FFA95A355A355A355A355A355A +%5AFD73FF840D592F592F592F592F592E605AFD72FF5959355A3559355A35 +%592F282F6084FD70FF7D352F352F592F352F592F3505065960A8FD6FFF84 +%355A355A355A355A355A2F2E052F60A9FD52FFA8FD1BFFA92F592F592F59 +%2F592F5935350506055A5AAFFD4DFFA9595A2F3535A9FD19FF8435355A35 +%59355A3559355A352E05282F6084FD4CFF8435352F5A353559FD19FF842F +%352F592F352F592F352F590606002E5A60A8FD49FFA85A0D352F352F592F +%35A8FD18FF5A35355A355A355A355A355A352E052806605AAFFD48FFA95A +%2F5A355A355A355A35FD19FF5A2F592F592F592F592F352F59060500062F +%6084FD47FFA8592F592F592F592F592F59A8FD18FF595A3559355A355935 +%5A5960595A2F592E5A60AFFD46FFA8592F5A3559355A3559355A59FD18FF +%A9592F592F352F5A596059605A605A605A605960A8FD45FFA8592F592F59 +%2F352F592F350D84FD19FF355A3559356060845A8460605A8460605A8460 +%6084FD44FF7E355A355A355A355A355A355AA8FD19FF592F5959605A605A +%605A605A605A605A605A605A605AFD42FF7E2F592F592F592F592F592F35 +%35FD1AFF5959598460605A845A605A845A605A845A605A845A6084FD40FF +%843559355A3559355A3559355A3584FD19FFA859596059605A6059605A60 +%59605A6059605A6059605A5A84FD3EFFA82F592F352F592F352F592F352F +%59A8FD1AFF5A605A8460605A8460605A8460605A8460605A8460605A60AF +%FD3DFF355A355A355A355A355A355A35365AFD1AFF84605A605A605A605A +%605A605A605A605A605A605A605A605A85FD3CFF59352F592F592F592F59 +%2F592F592FA9FD19FFAF605A845A605A846060608460605A845A605A845A +%605A845A2F06A8FD3AFF7E353559355A3559355A3559355A355AFD1AFF84 +%356059605A605A60595935605A6059605A6059605A605960060528FD39FF +%A8352F592F352F592F352F592F352F3559FD1AFF60605A84FD04602E0605 +%280659608460605A8460605A8460605984FD39FF5A355A355A355A355A35 +%5A355A355A35A8FD19FF84605A605A605A590528537E532E052F5A605A60 +%5A605A605A605A605AFD38FF842F592F592F592F592F592F592F592F59A8 +%FD19FF845A845A605A600652FFFFA8A8FF53055960845A605A845A605A84 +%5A60A8FD36FFAF2F5A3559355A3559355A3559355A355959FD1AFF5A6059 +%605A602E28FFFFFF2E0552282E066059605A6059605A60596059A9FD36FF +%59352F592F352F592F352F592F352F592F7EFD1AFF605A846084602E53FF +%FFFF0628052E53065A8460605A8460605A84606084FD35FF8435355A355A +%355A355A355A355A355A35357EFD1AFF5A605A605A60067DFFFFFF530505 +%28A8055A5A605A605A605A6059605A84FD34FFA8592F592F592F592F592F +%592F592F592F592FA8FD1AFF845A605A84602E53FD04FF7E59FF7D2E5A60 +%5A845A605A5A5984596084FD34FF842F5A3559355A3559355A3559355A35 +%59355A5A85FD19FF59605A6059602E52FD07FF5306605A605960352E057D +%A72E2F84FD33FFAF2F352F592F352F592F352F592F352F592F352F603584 +%FD18FF8460605A846084067DFD05FFA8066060605A84602E052806282E84 +%84FD33FF5935355A355A355A355A355A355A355A355A355A5A605AFD18FF +%84605A605A605A5A0653A8A9A87D05355A605A605A602F28050606605A84 +%FD32FF84352F592F592F592F592F592F592F592F592F5935605A6084FD17 +%FFAF5A845A605A8460602E2F2E2E0C5A60605A845A605A84605906606060 +%84FD32FF7E2F5A3559355A3559355A3559355A3559355A355959845A60A8 +%FD16FFA86059605A6059605A6059605A605A605A6059605A6059605A2F35 +%605984FD31FFA82F352F592F352F592F352F592F352F592F352F592E2E5A +%605984FD17FF846060605A8460605A8460605A8460605A8460605A846060 +%2860606084FD31FF5935355A355A355A355A355A355A355A355A355A352F +%055A60605AAFFD16FFA935605A605A605A605A605A605A605A605A605A60 +%5A60352859605AAFFD30FFA8352F592F592F592F592F592F592F592F592F +%592F5A2E0506605A605AFD17FF845A845A605A845A605A845A605A845A60 +%5A845A60602F2F845A84FD31FF7E2F5A3559355A3559355A3559355A3559 +%355A3559352F05062E855A6084FD16FF846059605A6059605A6059605A60 +%59605A6059605A2F06605A607EFD30FFAF2F352F592F352F592F352F592F +%352F592F352F592F590606050635605A60A8FD16FF5A6060605A8460605A +%8460605A8460605A8460602E6060605AFD31FF7E35355A355A355A355A35 +%5A355A355A355A355A355A352F0506052F60845A85FD16FFA935605A605A +%605A605A605A605A605A605A605A5A5A605A84FD30FFA95A2F592F592F59 +%2F592F592F592F592F592F592F592F59060605060559606035A9FD16FF84 +%5A845A605A845A605A845A605A845A605A8460605A60A9FD30FFA92F5A35 +%59355A3559355A3559355A3559355A3559355A352F05280606068460605A +%FD16FFA86059605A6059605A6059605A6059605A6059605A605AFD31FF59 +%352F592F352F592F352F592F352F592F352F592F352F592E06050605062E +%605A607EFD16FF846060605A8460605A8460605A8460605A8460605AFD32 +%FF5A355A355A355A355A355A355A355A355A355A355A355A592F05280606 +%052E60845A60AFFD16FF5A605A605A605A605A605A605A605A605A605A84 +%FD32FF2F352F592F592F592F592F592F592F592F592F592F592F5A2E0605 +%060506055960603584FD17FF5A605A605A845A605A845A605A845A605A84 +%FD32FF84593559355A3559355A3559355A3559355A3559355A3559353505 +%06052806062E8460605AFD17FF8435605A6059605A6059605A6059605A60 +%84FD32FF840D592F352F592F352F592F352F592F352F592F352F592F592E +%0605060506050659605A6084FD16FFAF8460605A8460605A8460605A8460 +%6084FD33FF5A36355A355A355A355A355A355A355A355A355A355A355A35 +%590606052E0606055A60605A85FD17FF5A605A605A605A605A605A605A60 +%5AAFFD33FF5A2F592F592F592F592F592F592F592F592F592F592F592F59 +%2F060506050605062E845A605AFD17FFA95A845A605A845A605A845A605A +%84FD34FF5959355A3559355A3559355A3559355A3559355A3559355A3559 +%062806060528052F5A845A60AFFD16FF846059605A6059605A6059605A60 +%7EFD33FFA8592F352F592F352F592F352F592F352F592F352F592F352F59 +%2F06050605060506066059605AFD17FFAF5A8460605A8460605A8460605A +%60A9FD33FF3559355A355A355A355A355A355A355A355A355A3559355A35 +%5A062805280528052E5A846084AFFD16FF84605A605A605A605A605A605A +%603584FD32FFA8592F592F592F592F592F592F592F592F592F352F593559 +%355A59352E2F282E050606605A605AFD17FFAF5A605A845A605A845A605A +%8460602FFD32FFA92F5A3559355A3559355A3559355A3559355A5A605A84 +%60605A84608460845A602F595A605A84FD17FF5A605A6059605A6059605A +%6059605A3559FD31FF84352F592F352F592F352F592F352F5A596059605A +%6059605A6059605A6059605A605A605A607EFD16FFAF8460605A8460605A +%8460605A8460845935A8FD30FFA8355A355A355A355A355A355A59846084 +%5A8460605A8460605A8460605A8460605A8460605A84A8FD15FFA959605A +%605A605A605A605A605A605A5A2F5AFD30FF84352F592F592F592F352F5A +%5A605A605A605A605A605A605A605A605A605A605A605A605A60596060AF +%FD13FF84605A845A605A845A605A845A605A84605A2F84FD2FFFA8355935 +%5A35592F5A59605A845A605A845A605A845A605A845A605A845A605A845A +%605A845A605A605AAFFD11FFA8845A6059605A6059605A6059605A605960 +%35352FAFFD2EFF7D352F352F592F5935605A6059605A6059605A6059605A +%6059605A6059605A6059605A6059605A6059603584FD11FF60605A846060 +%5A8460605A8460605A846060353659FD2EFFA8355A355A355A5A8460605A +%8460605A8460605A8460605A8460605A8460605A8460605A8460605A8460 +%605A85FD0FFF84605A605A605A605A605A605A605A605A605A592F3584FD +%2DFF7E352F352F5A5A605A605A605A605A605A605A605A605A605A605A60 +%5A605A605A605A605A605A605A605A603584FD0EFF845A845A605A845A60 +%5A845A605A845A605A8459592F5AA9FD2CFF842F5A35605A845A605A845A +%605A845A605A845A605A845A605A845A605A845A605A845A605A845A605A +%845A605AAFFD0DFF5A6059605A6059605A6059605A6059605A6059602F35 +%2F5AFD09FFA984845A845AA9FD1CFF7E352F5A5A6059605A6059605A6059 +%605A6059605A6059605A6059605A6059605A6059605A6059605A6059605A +%6035AFFD0BFFA9605A8460605A8460605A8460605A8460605A84605A355A +%3584FD06FFAF845A605A605AAFFD1DFF842F6060605A8460605A8460605A +%8460605A8460605A8460605A8460605A8460605A8460605A8460605A8460 +%605A6060FD0BFF855A605A605A605A605A605A605A605A605A605A603535 +%2F592FA8FD04FFA8605A605A605A84FD1EFF7E355A605A605A605A605A60 +%5A605A605A605A605A605A605A605A605A605A605A605A605A605A605A60 +%5A605A605A6084FD0AFF60605A605A845A605A845A605A845A605A845A60 +%5A603559355A35A9FFFFAF605A845A605A6060FD1EFFA95A605A845A605A +%845A605A845A605A845A605A845A605A845A605A845A605A845A605A845A +%605A845A605A845A605A60AFFD08FFA96059605A6059605A6059605A6059 +%605A6059605A6035592F352F352FA9FF84356059605A60596084FD1DFF5A +%605A6059605A6059605A6059605A6059605A6059605A6059605A6059605A +%6059605A6059605A6059605A6059605A603584FD08FFAF5A8460605A8460 +%605A8460605A8460605A8460605A60355A355A353559FF84605A8460605A +%845A84FD1CFF846060605A8460605A8460605A8460605A8460605A846060 +%5A8460605A8460605A8460605A8460605A8460605A846084608560FD08FF +%A8605A605A605A605A605A605A605A605A605A605A6059592F592F592F35 +%2F605A605A605A605A605AA9FD1AFFA8605A605A605A605A605A605A605A +%605A605A605A605A605A605A605A605A605A605A605A605A605A605A605A +%605A6059352E3559FD07FFAF5A605A845A605A845A605A845A605A845A60 +%5A846060355A3559355A3559356060605A845A605A6084FD1AFF845A605A +%845A605A845A605A845A605A845A605A845A605A845A605A845A605A845A +%605A845A605A845A605A845A60602F050605287DFD06FF84605A6059605A +%6059605A6059605A6059605A60596059352F592F352F592F352F605A6059 +%605A605960A8FD18FFA935605A6059605A6059605A6059605A6059605A60 +%5A605A6059605A6059605A6059605A6059605A6059605A6059605A602E06 +%05060052FD06FFAF5A605A8460605A8460605A8460605A8460605A846060 +%355A355A355A355A355A59605A8460605A8460FD19FFFD04605A8460605A +%8460605A846084608459592F593560608560605A8460605A8460605A8460 +%605A8460605A8460605A602828052828FD06FF84605A605A605A605A605A +%605A605A605A605A605A6059352F592F592F592F592F5935605A605A605A +%60A9FD17FFA8605A605A605A605A605A605A605A845A2F06060506050605 +%2E2F605A605A605A605A605A605A605A605A605A605A605A605A602F2F2E +%5AFD06FFAF5A845A605A845A605A845A605A845A605A845A605A5A355935 +%5A3559355A3559355A5A605A845A6084FD18FF855A605A845A605A845A60 +%5A8460842F2E05060528052805280506066060605A845A605A845A605A84 +%5A605A845A605A845A605A8460605AFD06FFA86059605A6059605A605960 +%5A6059605A6059605A602F592F352F592F352F592F352F595A6059605AFD +%19FF59605A6059605A6059605A6059602F06000605282852282E05060505 +%055A5A6059605A6059605A6059605A6059605A6059605A6059605A6084FD +%06FF5A8460605A6084845A8460605A8460605A8460845A5A355A355A355A +%355A355A355A35605A6084FD19FFA86060605A8460605A8460605A853528 +%05282EA8FD05FFA8532805280660608460605A8460605A8460605A846060 +%5A8460605A8460605AAFFD06FF8459605A6059A95A605A605A605A605A60 +%5A605A5A2F592F592F592F592F592F592F593584A8FD1AFF8435605A605A +%605A605A605A603506050653FD07FFCFFFA828050606605A605A605A605A +%605A605A605A605A605A605A605A605A605AFD06FF84605A845A6084855A +%605A845A605A845A605A845959355A3559355A3559355A35593559A8FD1B +%FF84605A845A605A845A605A84602F05287DFD05FFA82E7DFFCFA8532E05 +%282F845A845A605A845A605A845A605A845A605A845A605A845A84FD06FF +%AF5960596059A97E605A6059605A6059605A6059592F352F592F352F592F +%352F592F350D84FD1AFFA8605A6059605A6059605A605A5A05052EFD06FF +%2E0052CFFF28285306002E5A6059605A6059605A6059605A6059605A6059 +%605A6059605AFD06FFAF605A846060A8AF5A605A8460605A84FD04602F5A +%355A355A355A355A355A355A355A59FD1BFF60605A8460605A8460605A85 +%2F2806FD06FFA80528052E2828057D5228065A608460605A8460605A8460 +%605A8460605A8460605A846060A9FD06FF60605A605AAF84605A605A605A +%605A605A602F2E2F592F592F592F592F592F592F592F5AFD1AFFA8605A60 +%5A605A605A605A605A2F0052FD06FF5306050605060506527E05062F605A +%605A605A605A605A605A605A605A605A605A605A605AA9FD06FFAF5A605A +%60A9AF5A845A605A845A605A84602F062F2F59355A3559355A3559355A35 +%3559FD1AFFAF5A845A605A845A605A84606006287DFD06FF7E0506052806 +%06057DFF28053560605A845A605A845A605A845A605A845A605A845A605A +%6084FD06FFA8605A6035A9A96059605A6059605A605A5A062E062E2E352F +%592F352F592F352F592F7EFD1AFF846059605A6059605A6059605A060084 +%FD06FFA8280506050605067DFF05052E605A6059605A6059605A6059605A +%6059605A6059605A603584FD07FF84605A60A8FF5A8460605A8460605A85 +%2F2F2E2F2F592F5A355A355A355A355A35357EFD1AFFAF5A8460605A8460 +%605A84606006287EFD07FF7E060528052853FFFF2E055960605A8460605A +%8460605A8460605A8460845A8460605A6084FD07FFAF5A6035A9FF845960 +%5A605A605A60592F062F2F5935592F592F592F592F592F592FA8FD1AFF84 +%605A605A605A605A605A605A2E007EFD08FFA85328537DFFFFFF05062E84 +%5A605A605A605A605A605A605A605A60355A35605A605984FD08FF845A60 +%84FF84605A845A605A846059062F2F5A355A3559355A3559355A35592F5A +%FD1BFFAF5A605A845A605A845A605A852F2853FD0FFFA828055A5A845A60 +%5A845A605A845A6060602F2F2E7E7D7D2E5960605AFD08FF84605984FFAF +%596059605A605A5A0C2E0C592F352F592F352F592F352F592F357EFD1BFF +%84605A6059605A6059605A605A5A052EFD0FFF53002E5A6059605A605960 +%5A605960592E052728FFCFFFCF2805605A60FD09FF84605AFFAF605A8460 +%605A852F2F2E35355A355A355A355A355A355A353559FD1CFFAF5A605A84 +%60605A8460605A84602F05A8FD0EFF06282F845A8460605A8460605A8559 +%2E0528062E527E5352052F60845AFD09FFAF5A60A8FF5A605A605A602F2E +%062E2E5935592F592F592F592F592F3559FD1DFFA8605A605A605A605A60 +%5A605A60350605FD0DFF520506605A605A605A605A605A60592E05060506 +%05060506000659605A60FD0AFFAF5AAFFFA95A605A8559060528062E2E5A +%3559355A3559355A353559FD1FFF5A605A605A845A605A845A605A842F28 +%28FD0BFF5328065A60845A605A845A605A84605A0528060605280606052E +%59845A845AFD08FFA87E535A60FFA8605A602F0605060506050606593559 +%2F592F350D3559FD20FF8435605A6059605A6059605A6059602E0505A8FD +%08FF2E0505595A6059605A6059605A605960592E05060506050605063560 +%5A605960FD07FF7D2E0528062F7DFF59592E2E0506052E06060528062F2F +%352F595384A8FD21FF846060605A8460605A8460605A8460842F2E055259 +%A8A8A87D530628066060605A8460605A8460605A84608460602F2E052806 +%06358560605A8460FD04FFA87E2E06050605280005052800050506050600 +%28050605282853537EA8FD24FFA935605A6059605A6059605A6059605A60 +%352F050600060506052E2F605A605A6059605A6059605A6059605A605A60 +%5A5906062F6059605A605960FD04FF7E282E282E282E28532E53537D2E2E +%062E2E53537E7DA8A8FD2AFF845A8460845A8460845A8460845A84608460 +%8459592E592F5A5A8560845A8460845A8460845A8460845A8460845A8460 +%84068460845A84608460FD04FFA8FD43FFA8FFFFFFA8FFFFFFA8FFFFFFA8 +%FFFFFFAFFD07FFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFFFFA8FFFF +%FFA8FFFFFFA8FFFFFF +%%EndData + +endstream endobj 21 0 obj <>stream +ø×µ`«×šYnÄrrŠ‡FG&FC蛺v:^愈. $/Œ.ÓYtÏÈ…‹n¯ÿ"†ÕO>γ$FZ§Êç´ ›Ï€VàÖłq7_<}B¬äí¬uk7iPà ¾:‹ëž@köZy[+r¶VqƞLlÒÎæZÖúHh¨ ÔçÊ·°x¾µE7wçäd4‡îLµämfNf³[müMk¶ù³ôâPϨþ"ÝñÙ´åFŽ;βj[Oü‰À|.š_H;o÷Gt`^3x7ùÔkë:߈älxÈÖè-ëKÌYÆÍ¿mõ…¸<-–½ÑmkÜgÈ$¨å¨jaƺdS,‚œŸã,y?Ó^ºr‰Ö¡rí.JʕË5¦ØµYŸba·šý"=Ð4Ô7—ßÎp>(EÌëÒZ>žÇd#>ŽÐ­ÿÜc…0Þ̵CÑIÎ4þ“‡ž¿ió „e£*úË\é £Vs*ýÚPfœ°»©£¡ù™žLV®s£¬Ô®›¶Ü¼ìä9'ç“ö¼M:ð™,ôE}ò½êäUºb“þ“úYþ%Î×Jém- ÷áê^§ëü#²ï ö'øäo›Kå½^!tÞfͤfaõyoوV'v3qž`uUsW/cÆéù6.Ž³gا˜¾(Ê£úg×Âw²8äéauñ‹t)‘²–IOÛ$(R'´*ÚÍ^EüZ–QúEz€Vr1¢]Ë7ÔÕÞgµ²ôÃa“löâg}ÞÞæÓ»WîNÖi¾Ç–3¨Ùҍ“Gϝ9Îkyϟ¨Gb:›NN C™.GÖ´‡7Ñå£/™£M(ÚÄ»ý56†WbÄEµ¬Ë1B­‹;B½{2â{.6Úm?Ø8_)•ÇŒ„—~‘£u(¬ƒhÞ?ïéש_|Ox>Ï»zA9m:Ýï~ V×ÕhgÍ:Çô0xÖòÐ樧!ò—QE}:šÖŠ E~,ó‰Ñ²LÉBWtÀþqìFíûh÷l~G…Ê°$” \‹Ÿˆ[Ž¯V_%Æ)óe¡¬¹˜0¾ŸKÂø›¶ŽY¢ë_Äù ?V[8ºNOåç1Wk^÷Øg}Ú,®om—썍®é£éÏÉ·¡·xaëŠÆÍëõ´:ÐÓZÀðò"I“®f©€ôu1Ö²”ê8!Þ¨ð¡|#¾zQ®±…ìÙÖ!ÖÙÖ³ðfVRàTv\悋YÊ(ü"FÊ3ô>ôüÏÙ¨onž‡—í½0Ëî߸½ø»wàˆY[“iÞ[¶Øè®“Ì œÃŸQiVº‚ø´®OIyq*3Rü݌ĵÌÊãí¨½ Ÿ0{âºåå«wáÔÃöÍÎ78÷œ«Ã*QÃ>»Ìꡇ}Îy ㎃0Æ«PbBŠ(²íSøEŒŒ½Ò }¹Ÿcòfý½4¼]6:F×PÉ߯Ƨ²³œ—náÆu¾éÏ¿³ñ£‚L§Þ¡ö“‡V[mé»}Ð"©ü5¥Q‰fü5ñ–Ü-\¹ìB“ŽÌR=†«Ñ¬™iyÛû=z;©ôv,ßƘ¬§—âø$…!EпdŸ&[¾o‹WΟXÌû°EÚþöÞXž×ß/z°ùHߙ*غµªYóMÐ<ΎŸÚ{¼¿°üN‡ÉR².·Dæ¾'GGdÀ=7⍓µ°•Î|ìav ¿FÏ‚³´¿Oz ªã25:¹Ýþ¹Z™ôÏéáFÂfŽ:´Í%Ð_<¾þ½Ì+ÐÓ+¾€ëFHggӏ–,µ²²kÃxË֜ƒ×ó™Ôö¶Ó½½Éáj™L•(ˆÔFâF%øàU¤¸ùôƱÆ`%1äw¤ !7ùYeK&¥+U*Q¿*‘rºÓÚdC(I½G駴—œr b¡_åæH²u~s‡½O|Êêm§ø×ë:éõΫãÞö–óoÚ³]Ϛ¦êc¸ªèPi%÷¼ÎIr«p|Ƚs£ +ídWh~¶àlèÇ=f%n‡Ã!*D)´ã…é¨Û¯©ð™lJhØkO ´k<ôv·»¨ˆD\͝ºÆ»aY,öÚ´Œf䑮ƟìÇ¡ç0£Ï—W‡¥ëó6döúÊ0mä_ …Àϊä>§ ‘7ÍÍè’3}¡1Öbî(KH…·ö`§,ûô¸%qÔ¤FMúõsI#ñ=š½Î>t{»ú› "×qs&Þîê£Îpß>v†Ö;é¬oƒÖD4ùŹÛ{+d㨍3ß_̪Q3¶F+á¾Óu7jÿ¹}J¼X¼Å>zµ€à˜l÷ÒÓEîԋ}   +ƒ:À¡,~½~óGk+ç1`ŽÁòp½È»­•k<jcÞìÖ½,sz ~»‡¦\;@¿#JY¬›r~ý._ÊÒ¼TÊrú 8,ìQv †¥.ÙM¯þ󓓉òÍ7›ôkHi•gP½RX-¦4ï–p¤ðù4ó"ynÂÇ'rÁÖîBÃ¸ r™,5é}¼0H!…MIñÿÉõ.o?™Û6 +fU½4Þ.Ÿò6³Lï5å›å¦Iô1ЭF1`q l˜oú“ÄÒ£dÖF¢¤ÄV£ïÙ!£¯žŒ¢/Kg Aôíº›èÛCý”Q”²K×û–£/‰7SFÝèÛXRn雚µYŠjG_¼|KђèKCéÓ$žB·þÅÏjþ¯ßü'Ê7Ç 4IC}«i¨†š‹’X@£ÄÛ4¢d”ÐQÒ"¥èûÖôè{ùì£ï•º§¬Óµ^¿hôÝU*)\úŸî–äÏjv76úî‹é›ö¬–²w¢¯G§oò.Pô½“µ³o¦óq â?0Ýjû_ÄÀ…Žb°5M㤵 øI©f‰jàòÀb@)¤U§™(ùÚJ”¾«(™wQ".ŸY=ÝúR§”2k¦œzQÚ˦4G)búŽI–›–Ë»ý9õ2úÙ´ZÙø&Fû}•»o±ïòéÝùáu‘.í_¤QNÒPm;ò~øÆàᐤ/ßi°]ÁFÆ`î Āj10¥Ö1À¯¯?yè>ð‰f/ý©¹¬¦<;1€ctJ–›Æ 9è–刋õÙÄùý¡ˆ[XdœüëZÜTžjñ³i{y2'mGìÜÃÁ ý—t5_¤a™Q ¡ç”Þ=ã“ÄДÉJ§íf õát(t&1¸–Œ”N»$[ VÙ$ +úá$©òAáŽøù>Wƒ·$ž²fí]ÁBù¥Lù«Þh;ÏÙ\<=Ë ¹÷Ä\ùF)X+XߋÝƟŸÓ×øPbÑüE ~Ý0†”×'†|8Šs0 ƹήü“R%ÐNœ«rL +%†Ô›凷}xx¬/|½¦ãEò¼oLäÙBv•‡N¹ÍûÇÝw“¹nßýG¸Ñ%P¹gܘª´ówjü¹–"=OÅo6¾9iÊ ?¾înýH´&ÕC+sCc¿ˆ!ÎOCýÀŸ4ÀzêZÏÅ0ˆVS8"ν¶\´%®J(úCí¥_óñ~7wK0³AáÍš`Ã›ß ï8y¿°œ—®ã¯Q¿\Zóö9èªýscep§9¸™ßÌ{y$<âè%ýëAÖ£¼Ï¯ƒÚN¨l*»‚o”·Ç©\܊ ¶ð—t5?Ët[‚i”C<ò4úþ'‘º¢~ÒÒ½ˆOì[ù ì#ŒyþDU%@®~•ÊÖú|£úÞia×£ñD^‡¸ƒ% žó¨c^«di»=«àÝÝþN1»bK™lïÐÞ\¾ÂÓ½AëÜúY{VÖí•WrBjUp–¥%’‘ÿEœ«”Ò8O\œ†è1ãÅ?E³ùî5»Ãþnˆ¯ö=A +í€'Þµòí²'½¹všyÃeÉÜs¼Ý&ŸÓVüÛæºö?›:ü†Üù@×Ïù#$LÚNhŒÓM4Õ^ ÑÃjÍKÑ*—|²fqµPìœÏ€M/<@¿ˆs *²™}Keðã<˕âüf[e­<úàñ<‚œ[/¥rp*p{¿/»25oü€Èš5W$ÆZï½]ç£=öW>ú6å_+<&+˜¹!g=«æÌf‰éòËsþ²4üs7”×L–¢ßåBN׺y0øÅÏyó¥Qª³0݌ÙòC|X·Ýç>Ðǟ@˜¿ß§ÂCnà»ÄW7Á«@¬ßÇÍÀ±zâئ/ÍéŠñŠ†Å/ž¶yðŸûåù蝗Uìú4¦ÜíçÊîö Ñ[9¸¶Ð¹^Ñù®å9™ë´o˜Dš½ëç4ÛgAÍþˆ@Êøû‹Nېtk®?Ÿ£pMn[ø}ö±P<ŸçðpnGëìFþ!÷À¯;i\únðb€:±#ÔíÁ!¬}´˜âB-ežR u€ëú¼Z‹÷Ü-ˆ z“ûïSs@8Ñ ¢\˜1«{ÀåTÞU6jAn¾¦Gv›o¦Gù˜LFð͈~ÃÂìç«Ïï#F¦7ÿ4ŸϝÉvs¤NÃÍa¸Cݝt3=÷%LžŽ]hƒ«m–¬Ru…/•a4š0«¹]„¬+ÌcJWæ@•™k±gìØ©{“¸¨…„§å…¹gTä@{ôeu`êr³¢Üä&QLä&ӌeõÌþðùE [‹ðçV„Q‡nÛJr¹ÌÅý‘(ÇC¿þjw6øåF›4\' éëM›ç¬~ø>D+zGÛµæ_dLjk·1œm§‰ zâCQ‹Û@ŸböÞQj†ãÉêm“Ö&óó&’ÂjXº³vGŒñ@Wcq‰ñ܋¤n~2Þ¿øÙñïÀì„Áˆ .'“ð¶ÞÎGíÝä2]nx~±6“Ÿ[ßv^³ŽVy&¿ŒGt¢w.Îmy\×`7ßV=9=c£\¿ìH¾½»ÓÉóV3&Rӕzyì$®úí×x=æƹݺ1Ú +Ýш+5ö£­ ¿Æ0Êes ‡Ê"Ìxý"Îç¯ñώ¿ú9õt¤û³Í¾lû«ÍcÕÒ×ÑÎRí20,‘íî–Í|.ЉЋæNy Ïö TVÇÓ}sZÍ ,Ÿv·kÔäeä8é#\E©·¾j"ez«ñp¾M# +ŸÁ»¡ÔîTùSxexÉÜ»ü¹j?„’‘vYÆþÎxþ"Îqr_—Èlß\ðCópÈ)wlLË5ÎÝÌʪH#‹å­»zظ^æÎ]zkҀԲï J0`+²ö­µ&ÄäJH¤°¦Ez¸Æ ))#¾=ԅƒ2Úð籔Í;Èù¬quï\dïã!ÅjXßæ}ã¦Â9äüýëÅùÁ÷ù‹?(W-ø'sòÜï|i½y"SkÝ÷‹•Çe³,§F^f‡À‚ÊIƒ:U|Þ¿Ê­ æåv+IÑùZaÑo:Cr´oàŒpÄJ"Aa 0 ‡Å/l‹ê„Œîê†`Kä0½¨/B‰|æÝÑŒgº¶µÞ=~V?ÃOPj<®GZ]ïvòøå¸Kœ±œ\²_XÒ,–Åº#-¨yE׶_|¯ž¢¯¯Ü|ó#wr]HZáOTìØRYY¨HÖ»VþÒ| ¹¸&xVÙVt°˜.p? -|‹FàÐ@î:û~ªýu¯a¿Á<‡ÖtrÿÅ3„üçÕ쯇üBÊæ¶Û6ƒ³¦˜–µ:´}yŸœä…ÝóymǞgêY÷ÝiýdŸåΑ~J«/ôáê +y'®$H|¥Î+­O››ÕÎ}vQryf™7•á +ЗçcîèM²Ë†Q4ÒN jÿ™â”`4ÊC؝^U_ôk<3n¿xôoú㬏›Ç½Èã7ôLǁՂeUQaaýÙDÛ½ÇCuâ’åÑä³bX™˜Òžd_ˁ˜/ŸÑ¸?ƒ„Š£Ü}ü­°/Öo1Ê%‡«h ÖO^¢·>³HÛW~C•rzЗ¸@^dƒT¤ú”¼ž±C_]žý“÷¾S%Ê>ÍÏò/·­Kߏvtóvµ9ºYÛ ¶^NÐj©½kóýéHªŒçi¥]xŒ&Ö2šKƒVâŽ÷³ËyTæO^­t¿\ëˆæY¸—‡ nf!Tƒ|‘И÷ÏNuÖ¯æ˜5YÿŽ/=Þ}»¯mµÚ}íJ“îˌ÷=pž½»~|d¿ð¥$ +¼ýb±ß,ŒïÖaˆIöU]-ÝRŸš&h_QÓm!­{+"VF²%(UõÀ=¥nÀ. ÅÓß¼Àá`u( bZ¥‹M¾Ma’ê× +-læÓ^%ínbN„źټƒDmU;Éw'Ü}`þ$¬¦q'"usûÅY·çݕî×ßÙy»?ëe»%›óme9Sk±=ž€˜LÎU¯'Ô×'žÇ÷¹ìÖ7û‘5c£ñi8¼<Ÿt´Žé£å¨J\î×;é®ÅI¢×ë´L·WoÈÕ"ÍΰÆÚÛÙ.ls-k#!,´‘k¼ms°zO™ßÛێqû!]Í߇ú}òL¼÷8áÒ2N0Ð%{ø¢³SªJ‡¯O¬öA3÷íÒûà·&Ý{ˆû«lÞݨØl!…fC‘ƒúç¬Éu²š¶¸ö¬ÔhÜGj´ÔÀ«áVÝÞûVޏAuxØüéj~–ΆFOæ &v:XSY%Y2ùzÍƉ\¯”c£k©GêB¹AäénÖ^¹Ù&·ÍFTÃ8±R£+mŒzL@Ûº×:ÐçÃÚp²oZªå¤G¥Ê¢â5¡"<ï&v":gLÊ¿ ó¶} Ó6Nù +Eײl<‚²,_ü_Xòsêéßr°ÑJ`ɑ]_ŒORá–ÞOñà0W¤ðm"P«ø ð +õØéª(u/bâUÃ*q¥‹U‘Õ¨ì{¡VžjÝuŠu.7è$,=°A¾¤]7â›ÌŠz¢iEâT9¬Ê2.Á0Ë@¡ÉH0ќѤœ ¶û¸ýÂXÚÉV;èM[1zܟ¬>÷éâàðز¤A¸½Îþ¾iàÍÓµT±R¾2ÆÝ\éÑdòÅðOÍmq âýB<áøB?Pä` t<×hîÜ<#[}"Ht‚óž×läG³=›iü>C_>cç,ùK®ê®4£'\Þ¯_¤«™ïfª;m…KóOb¿s äÁ± +¤á~éŽð}´š‹u\©1¹N«¦W¡¢Ñþ&À'Q”aê=d·¯ÓùóÂæNjž_`N…'»Å24¶n®á„YE4‡‹/ÐhP9H®M :±<Ї/K ŸŸ· +ùÅ€Lš^Ê>L9~þ2}̯+‰Ëu^oCÓaa_É%Tg:¥Bžh|ôbÖÞTùe¯TnS¸Ðçüá í›™2|qv-Xø½œÊÙ$4Oú !3Àš,ÐÇy1e7ú-t"]Râ/Ðo+ ß©1ÿ“6µïŠa™"Ðï¡4Ð'1÷“ܦ¾ðGk6ªƒ ڊÐ>7ZdÃ<Z•£2ª”Ú‚† ƒï̏Øñ®Êšk"Ij—ˆùYMs®¦)§!4ô”jî[)™†ÚȂžLRîé6lõ¼”Óû?U½$ ¬sÑÓx'éIÌ)zíQ²ßßjn£Ëý?X›@¾GßNÿ}á%Å»'ÅV·ł!Dq?Ò¢˜¢×)î)åûˆbSƹ»˜òªGqí¤PtÊ:«„ŒâNÍLÙ_¢˜(Räôw„Uø̦ôÿ$òÁ=ˆ÷í?ä(¬4ΧñŽ¾‹[.ú?OáEß¼HFqpEñ­±HÑܔWºÖ{ý•2R\$åUŽâ#ÚHé)‹aJ8‰âÓ ó”øQ|æ¿Ñj²)|†M±øáéj~–ávÝ/ü"˜( PO‚ÿÀ¼ƒtãi¼^þ%TPnDß󅎾FAŒ¾,³H9l¢/Wº¦péGê™ÀϧéÝÑèK¢•”ž2#SNlôícJŠjFÔ:¹~`µ½bî]2±ÂëLæЗô ÑWåðü'1p)ÜâtØüÉCüxÒx7×O=º{,Jâ¤%vƒ‰’ñT‰’Öٌ Ý¥ŒÒυyQ”TàôªôÊ=íÕ"¨1jÜnjüäÛK&܅W),@và] ÏŸGk ÝßÝz×ãz'<½E#¹Y¥^þf8ü—,Wƒ·üÔZ×ô§FŠ–î$püÎÇ`»QpLÆÀÒþù>i€ûj1ÐÀí(‡áÞ©wüt<Ù{½—á÷ÕÆðërӊ¯®WŸÁk×z6‰3™R_öѦêÊÝpgέ¯>ïA®&>kÁÈU8žáË Ó¡‹xd³Ä_0…Î×z'ùK‘Fy§¯1„Žýªë÷âÁ$†H²CÁ㙊†ák ]~K«©þª¼ýěÌîÑé0—ûrÊÜoñcœ Øo«¹ހÐBƒaÏÁ‚Ü7À}ŽŽÈ«·­ +×:5Ίq>_àá}øTࡧډ·zŽcZБvZá/bð˧ÑqZŠ¢û?õÐá÷ç*töf)†|¿ù)l§ÝWPƒú7¼aïä@oà—Uø͚>³›kéÕ=œ} »œ@óyÒ:µèø2qðØIz…ƒ9àj2·êy6fE}{w.»;¾gùÛñ8ˆ7ç‹óÙTkâÛõoƒç¿H£4o1tÝqK·JnÑ˾:çÖçb(åZ¥ç<Kw«‚xYëyÅò +uzìPöhÐé`uï3Ï¡|ӃÒñàž‰î‡Ý¾y÷w…Åëµ=h²-[ t#tÝ †zßUóumÝ:)žC|NOÛâOo»_X?WÉqq_9¢”7?Ë¿ÄÐv—˜Mž[÷.*YÎ÷œû”Èðì0è–»>× +ð…NL+¨2QßoGyb'|‚ÁVL‚ñF÷Š{«ïu·9ÞdyõürÜ;!²?;ÝÑåa[ç÷×î˵Âʹ ø*‡9‹5Ǝ)xçëò„žKñåߖ˜¾ó3®KÌ=û‰s¹sº5çþ9†›{8AÙ§y|NÓƒ„—¬Þù>,_ãþØCs +…MÝiÖÖ¯:Ðq>¥'mó'ށõd5n5kkn- yl7æ¨}:/OÊõ±Äîqb(ízɨ…«ìñ8}Fö‹ç1ðNù6ÿÀ?ã’qž/·Éé/qnpOã}Â~8©ü›ûÀ¿<“–—†gÍ9Ú ìݱZ>m¦aôZë—Uv鴓‡®Ü}§fñíoË×ïäò<¾³†ÏîÆF}åNu <,/âì.:Ö+]õóûÔ²/¸ÕV‘ÙÐ@ +φççzìuo䫺cٓº“Åãéjþ¾ˆsÎë’înêqO*ó­/Ö¼Õ靜µ#€’ê:?äØQçî#7Žµé^m腄–иCË 7E€æ«ú£K¶ïRœGp4œ“”µžš½†fø–38ÉoU¾]¾LK:šŽ{û’rvZ”2¢¦RílOJuøc÷—ŸÃ󩯠ƒ/Êñú¸œ{ï’W¶ÊšMC¼Ÿg5Vœ0œ›Ò´ç3>-³ÿÈ:·0‰´œÙ…fˆX,ªE6®N1êÚRjĺ'«êš™Š¡•_«…Y²÷ót0}qS詖ÊÁwZA¶°R{)E¹ k“ö oIKÏjÕÅU¡žvSé8×ë˜#֖‚yoAØöÊü©P E²!šî…Q^ßel2Ü¿D|‘{Ý6Óùþî{–‡jãùæ~räµéYëi3T2ώ=04m2^|b͘ƒ¹žñ•üqzoŠËo×Ûɤ#À°Ô¼Š"Õ;ÔÆkÛ'F[ã0!7_Šg_祼ã®3êÁ)¸²7cÅe)ÕzÎ09Eªî8eÑÚr×'½Épÿòö®ìâþ¸:¡æîl´4W÷ʼnÉo Z6’\DÝ7§ÏÙŒ?&«é=î•FW8ÿ”]ŸkÉäÏhÎàxxçF»VºK5J#¾ÏW†ç”½¦±w`ç2/øå3‹=Ÿc:£Ít´šÎ,¾—-óê½]7¡5‹ï +ÿEö(I‹%Ï>¶Ä¶‡áõ¾ÜN½‚¶¶HA¶óñV0eþNéuæƒâ~0ۛ<½,-Ci¼Ewb”Š‰Ü=}j/Ÿã|]ŠG…2 e¤Qä«¥r›2ÕljVë—YæµhM‡“±‡½‡~|``?½Í<çƒïe¾’eÇšãã:ÃùË#šUϗÛ*ÜxèÝ66ób¢9ΑU¬Si!϶™is'ë3a7 §WŒ)Mm MŒ[͖ø¶oœÕy$ԇwA,ã^F + §ÂjŸ ƼÉwgµƒARHz^6i÷Jé|}S»DkÓùþ*+í¥™UCoÙ@¬±ÎpþrwÑé´ $gw¦†ÛíšÍ†mÅTe¤/šyV*­°#?;YÊEUN¡9f“¥;*.¹lÓzw«¥}–gñ•0!|ÌÓ¡NiØo;ø`P·(šmmÆÔ^~èTá^õúbKûôË!Ñè—?Ô´ԋkªðjÿ`S>ø/n¿É‚#¸¨¬¶j1Ö¿ÑV%´¨,qu8Z€c†šúè­"/n \ú2 Jt‹kiŒò³¹pÆ$‡Wl|ÏáÄ÷ÌvšþéUÜϐ*Ð`˜ 4‡ŠuÊ£Õ¬2¥êªy¥œ9YÓ›Þ­›—ê·Pí©IEîÝțCÖ¬œCÊfÿ—ÚâÁã•ïjÓ¦Z†½u¬¹éÓ¹©nJõ‘†¦TY—gYÚN¢‰Ru¼;•ˆÑxÚá…j»£r÷{ÅdõÉ×eLá~Ò70íMó9>¡=íŸ[ƒ*é×úDlŸÌÕî"xlˆN<‰å+ˆåå+lõlºñédØÝÅ ø/΋×m»»ŒÏ«õŠÈ«Q8_,[Ämº€zA•w_‚ôRitõØÓß,¿†ìûö™0Öğá°°;{ê› +Ó %æ˜{ÿÒcb2 ûpïÑm—»o¼Ù""¢?$HUvìçe݁ˆÆ­íFbÛ½}Ä„.¬”­Ý¡¹kJÏ[ýå#÷çžNº&£¥éE]'Ÿ E+¼m^ió)"“a{je˜‰­K‡ b8¬Nø×ÔUºèó…=x·¯`ü‘œÕé ·(·ÂîÁ"µ‹À4›œÐÏæ³i³kUnyp`·ŠB+ÀOÅw?ÿ‡®û\T[ÛF},˜³˜ÈA2"DE$(挂žÿv÷ªµ{¯÷υU5çô)&Ê7ÏÔßEêbPk« ç_läjnå&Of¹”äȞE3pj²l<¹’§'[D¿Ã—KÖpImy¶Ld¹M¶^G‚˜à% OO÷:ö Kôí4äãW÷UnÜ`&WŠ¡5–[¢ÙÔ]–è·Ö¦ÜS¿Çy¯ãR§îM©Vº7¶%võ«>ïêá2kTîê˩ݽ&îòAÏ?»«â_-º·ÙÂJg¦>jæ”ñ|“g%)÷B9kþîЛڽ‚›¨Ÿ ñ!¬ D;é"ß+A!t_“aßZ™p)þ]^…â²ìÜè8h–òQ¬€ž6lÖ»÷5 w¢ÝLè ÍxÆgiÚZ»ÚbŸñçrâ‡ÐqÏ]þ ש/<û8,­¬ìekBáDÕÕéS‘äõÜòwb‰2ùÈé ?K |j¨^x$ƒV·XîŸî\¯ß¦DïVxI=} Ýgµ»ÓÝxÓy7ísSwopyKJ`êuÛù–}Ðs+øDz‹[Ia«2äZ†d›á%œ5E"°›boùoþ2 æd/Í`ú°&7®8yª(hh™bVßLž¬výTj%HzŸ_qƒ{‚”—{·ýv·Ðf.“v»¤Ðֆ¬s-!7T[Ճ»hî”׺)ƒ½K³‘̾1ùh6ÀÞJB¿ô) $]*îZ+ååY›)6Q^)œÊÛya¼­‡ИFù+T¬æ{ª˜rny’3ï›-ð‚…0‹'€†­eÊ0Ð%æÿÁŠÉbKÅ¿áÙO¿ÇSŠÚ'1@ ¨‰‚Í.zï[áKê7zñ¬âT#KË%mu.ÊCáT8÷Ç¥Bç`7òF{ÖÎY5¹ ¼G`ç•Ëv¡¬”ÃÀ®ÃWʧ`·€°ûØpx®ÛðÆÐLI¶Þlf½ƒ¿íuV§rmÊO8lɊԱ0b¡ ƒKƒåŽ¬´ê‡I®5q%ï7¥ZÍ¿Æoù’{Nü(‡ÄP>}¦Z À÷½Z +ÝJÑz¿§yÜ ¶ù”‰ùœ  ýÍV1å„dËÞ¦ÿ€ð{€@Ùg 0W¼æþA{ {³«Ý0ƒ´ÖҍœŽvÖÝ¡ªËfS9¬KÕ88Êe´›ûã#÷¸£/@7€è€ÿà_­²ê¥ÜѲÞ_kï'[ÆA=Ô*üÕÚûëB6ÓCð0[7þ;›FîâoÝÆ_ ão­¹Ž?æÏ?…0ˆnÆñ-¼Ä±ôJâ˜ÖSNHÓa<œe‹Ñ§ÛhÇL7HQŽ)Þ=åÇ1ÛȧPÕ Ly¢qÌa|Ê+ýžÝ¥£8Ê@Œï.Ÿÿ“ìi~øÚò.…MKՈMü +i©ôɏ“Ó>Œ“Eó'8—“jЊã]’–êi©îjÇ^ÞNÁÓ:-eŸâ]Sž¯8ž5€¦òûߌô;Çg(ŽÕ>“rµÒ*‰ðý•…ëËïы­Ð¯Ûޯ҇ý›rEŽÿc-Ý¥±°Ž¿:H‹…‚øóÒb§àá—ÜÂBŠa1N.åNœØ4'š/Ɖ^5SøUÊz—ò¹Æ‰Ôz¥ ¿)V)åЈ¹ØK1q҅·Û9™/öUÞD5§vy6}0K§qóýPÑÚû&Àÿ$Y˜Œ¹NÉ~Zoo7rZ¾¶º¦GDúýj•ø£ÝøƒØdüiÇRü©iŠãþþ7åç.&ÅÏ%Î5êÑ{8®'ï"8È¿8©¼*}¾‰–Ò‹êȖ|Ž–Åѣà W·éc¸»¾át0‡­GÏˇ>.N¾ÿ¹kÝþðKn=“‡U>2½Pd7¬Ë!Æí(ÊD.þ†Z=þŠ»Aü¤ãø|9/½Öûxòª–ò³¨Q˯žÊ¨ºyœÏÃc2An÷ÛÝþ¹=_¿[°nf6®ïϺâtƒ½ä;Æü´É{›£®¯‡¶ÅŸ÷“¸{ÜwíêawÇ¿û‘äê—M’냔—äÈ(ý#Õ>%¹Aú:Êå7¿ÕÒ£¡õ.+f:Ësiôq¹—É»9/ð·™(×8ª™—oR^\h²é] +9t{fâtÚlèû©Vâ£[…ÄÜÞm܊™õÜn +½] (\³Çæf]ÖHrbœÖ¶ŒÓRÃÈKò|Ÿ¢\~MÉ1“_Ñ(.ä}N/Ý0k\\¯Þ;Wªô¸ÎÔA•ÖÙB3{}¼VvëVßÁýób;·nn˜ÄÏM¸\Oa.×zn† ¬ƒÑ\sbzί#ªé©çuFËÐÕÏbàö'¤¿zvûÞ¿Hr·FøË¡+ù´J®í'ùÀ8ü"՘ù8ç䬝o‹åþ|)ÃÇñ°ª|öƒþ¦¸}_ìzèLÍîÆ[˜è¦x7éuå¥ñ„™JPÿl¦¾Bílï<Ûù^'¹d³5÷æTî ÁæWÖxÓuÞ7~´tüÅb™/oÛ Ï.Õ%çÇb} –Hòö:É« 7É¿øõ[HGÂOmO¯žÚT^_¿!¼8Ʌ_;Ï.²ã üž£ó¦ôÚ¼‚äý1ªW<ÔA×DÄÁ*²Ub…•ëì,ՋÚþéÇüöãÑÃm®{%×¢#2~Gç&.¼á–yî‡Ë¢\OÆòû9?änßÙ)Þ­ëîY}xՙN'6l¾î>eb͍`,ՋfÛ(ûÝèÃfu£NÊSã:qm®¶üD ­IV3uÿæ¦ÿ")4ðyݬÜkñ¸œ25ÚRÝTå ÛäÂ_áø:»â±dÔµ¹ØFŽ;o÷¥Ðº]Óô¹ïFæ{]úçU0ÈèQÕ=ðjëþ Ò*ʕœˆ—DTõ‚¦¶ÈŸÛ³ã¸£rŠþ¼ŠÑpt¥<[J?zþnÄL·f†ñ‡ß½¿aÂ97Hlº#*%yS«5‡þåÆ¡Þ öºÎ—ïì ×.ÇîxÖ}æ­i4‰\Ón5Ï:㠍_¢YÔdû„óêáR¯¨í^OF}X¹É¡2¨ŠÊȒç3ù}z„2ÞEßÒç’ãÞG’s ¦†ä¾­åúxëÈuRÄ?ØÇÂ%‹Tÿî†ÿª:õ(Aæ;,ŦChXº"MBÛ±%ÄmCïAóƒ]:ó=¶Ö?htsßhçü[ýì}¿õ³O×êÖìÖ»à¨Ýn ¡f¼^P‡,¨ZAåTE8¨ÄÕJ·²¸BŸÒNى۟ò·Ü%ʟ«1*BE.;$.ýaEìÜäŠKc¢_ʈ¡/×öøЏ¶=⺸4Ð\}ŸÝ·6h̓¨³¶§Öúžë‘öªh÷á•é ܔ‚ÎõX +º`Tbïb¾T^…Íb8,À)2W‹;­(¶)?}#8Ü {©FýQhFs#š —üiag/ÏüIȅ¦MÿÅ´à^§šzªO”|­! +Û¤ú £dGIº¹m¯:hÃÍo+÷Võ>8Ô{¢¹©,»/·S§Xw¦Aþìϳ×M¾[žŸs·ëã3Œz!7 Ä`ùé¸Q@æš ëö6e›ÈfҐ+9[m ÷r@DÇ"ýºÇañ½er†â\øìÓã~‘9ãNT‚œô=Ícf«q…PæÞMù.]jSq·/{@m]ÜÎOA¡-MýÜ é»ÚÇÂõ døP©üPcTPçÚÐ;ËXõ›]Å°žµ°~ë`ä0i/˜¬y6e³pÀfý)€ùnð‡ñây˜ˆÇÏNdÉáuHžÃ7†Ò…¸××Üe¤ýÓ8ݝGuAå/¿º'Šum—»§k]’é*Ï·ƒ¾.ÆõÒ"æzÀ‚}ÀÞPÀ‹6 àLºgqë港?ü×ü]DñnDÉyÈ7~‘j§BöZüA’×¥»|Ö8ªuHtµ§¾Þš`½ÝZ.©¬ò{Iè­.ïô:J÷ èîÒÿzrpˆ}ü -?9´¬E¾zåÿʨ ` D/ʖs@øψAýϊ¿.dˆ$ïüºíf}ȋÎâÏ괊?¦kÇh4ûõܞ0+Ž“·ÇäyǹMÙGqLc•” ÇÃæ0e¬¤Ó/fªn +•~cœS¶Ï”Ï'ŽÙn1Ej¤¬Óoã*TÊü¯€˜ï±]Õ.)Ñ_îû+o’÷ªiÇÿ‹ø[Üøó½.Ó¢—óøSÀÌ8áŠFosó´ÄNâÞÓ[…”)øW )´˜²ÒSbûŸXšß§,®)çWZ` HÁ+12­÷ª>ÞÔáƾ|´^Ì5ؼJpøçãöUký‘u©þç?â¯P^Å_ü±Hëu­ø#sFº_;)sщÌÝÅñ횖jÖÓg¥¹_‚§ÕÌ?ûu7M +­RMl—ølÈñþ +üõMíùçËoII´é²¹¨jjµ§ôÚôŸ%=”¯3»_è³× +ïí½œÃ{÷ôÜÞîê!üñwS[ÆßÅk–ëñgÇý~7ŸÕ|轊À!NÖP'‹e)Nðk;Nz=,Åäc{ïc µ3ßôäb¿üûÝ{•›ÇuTëlvOÙ؜Çhw€è%¾÷ÈkþfúµÖõUžeSÜ+*ÆÚe™g¼ 0SÂó°Lm΅p°>®øæèÝõ Ô\¤”ÓRÏW#þN=þj€ hì9þŒ´Wüå8W½¶^AfV"Qr±çh0SˆN}¯ÞuådÞ—ëâ÷îõõ,„W )/K»y¿ä(9‡jõl +ÄáP•ô{ˆùÎ(@Ëí“+Ø[«œŽPàëc¾õ}¶2løƒÙP;¥—>‚=0}„NZþx“îsÿòö‹ò3Ú¾šÉã|8çïƒÚ¢r}¯'­Ëg7é_r§ vf:Öð´6ñ¸YÊᰜdñá3¬ýDqœÝí²^ïÄû¼µ¼V¼E§¹ù’-ví·‡z°éaVPu[S7,N}¹ð6}éu3þÏñ22S@=ÉÕ5;Éål÷¯T}µ~ g`ýЖØæ†voû ]±®'d^‡1ÓÒ÷ Ziµjílõ҃‰ÀB‚¦éÍ*`ùM¡"ŒÖþvf¬Ëƒ³Kàï>¥‹/oͼ7>5² ’nÏa¤Õ4o˜Î‹¥t “ËDÌ«Hr¤¹H¡$·4­$ú‹weӛ¿Ä=°¸Oµµv¡££z•k÷XCÞƒ ÃÆujÙ5‚uà×â ëy¨TüV»ÞòT­Ó÷:=sõé^=Þ¢¸š.–šóú†s›å§%<—¤VhÙÅ!K/¸µ?™o«Úx.ÞÇãyÝd•y]&F?Ò§ùmÿ)О½« mÝbfÍ_üæ—<ó’Fœ9Â÷ý•H†EÊëõrhù‡MgåM¦ýkLZç•e¶"g1¯–ŸO»¸¤ê2á›A©lȱX/%jQÍM„ùÖÛjóF齜)b?k×€ÕEEdj,O’ÕOŠiÙD”¹”!þ!É%»E’G¿Ît”sعƒ–@èn¶V³ëžÛ˜ú´7ÌÁêûǑB»÷•¢¬ÐŽb-¿‘äÚ¾Žl 9-ª—Ám.÷ðxvœÒùYûLT,­Ë¶§wSL§1aFê&}Ö[d6Ôv ¢°}ê+~’-˜¡ç9Vcኤ•‹E1Cø¿*Ÿšü2¯…Í[9ôY›Þ’‹Þpì³µ®)݊w-ì«y~/Ýþ†µË›Íx¾ùÖL­þ&ì–^ƒéƒïÍÅ^LÔ"ÃN؏bQ§=½¥ÒXûDOÂ0šÔh¦îK›ƒÚÔgõñ8ªcЗ„ ^¹²«\Çüñ» þ}^Y§Cѐ·ŽÒ#×ۀøDj¸Ïæ,ï$Q¯lÏ8?ÔjøL=ƒÂô Tó &é/î°·\;}Ó+Öܭƍ‚ó$\»ÏI½~սͮFOÁ³=îT‹¨¢Ó-vô8m4åüº»yy>ea^8El“1üCtÜÐó[.?2~yyX +¤¡Š}w ŽãÙí +6¸¹yë>ªZ7˜ï£NŽ®Š:Óªß#­‰ÔêتR-ºã³\َ;Añ¤ô·¹çÈÊç>ò›mWel9èHNN"$Ò;(¢Wn-Åáõ‰Eã·½°¦i6c˜AýòÇóÚ#—Š^×v¸îsëÆËÅ=¹õÕ<®ÛBæéÜ4žFà§`â~±­ûõ¢ñ—3iÈgQmsÛì´6îJÞT°Æbd-'ž¼ð¤PúÄüI¢%½©™‹ïMSàñå·nWॡ3çҗç™;„ý6w¸¾hîð)3¨ ò)\ËN§ƒûÑBŸ‘YÿZÑñU"¬ûKövoÌOÀ °Qø0¾žúÑٞU›ì֋¾:¦ bÜý0Ì(òIŽ— UƟUS¢â¼-úÝØKÓüNàÏù+¿ë¶³Kß|CF«œr÷ÙKgð]³j0wh½gÌâ¶Á˜%gîJ@gÄî—ÌÆNR6‚1ÞCqǝZ}»žß4f½³ù5 Β[½Ü«¼&òºQ_›Õ–bު𵾤Lh'Ñ£$²¼­ +‚lšü.Ðl¾Y1nL͎ìÅ÷#¶›œ +ŒI•;ÃÈ'È!Z^©tz¶ÚжŒTèøQÏ2›t‹C”‘¿Gø¹½Î÷Èiµ˜×w>Ãðåºh ægp֘¾«* ³ït^Ð œûX8_J659ñ6=ÉV˜ÈeJ¾tÖAÌï!BæNXoh±Z¹Ì„¶ ¤³÷áì9ÍÑöeÞ  À¨Õ“Q´ûT‹œŠ^ Ê-¶ð ì¿ ;Ûïí×y€o€Y-“nKUª?3H¹a:ИìwÎ~Ü ΣyØ}ɤ‚¥bmŠ˜ðû{ãN'€æ:²Èöë…™*/cøÚ¼ì!VÖô’)Ÿi`e‡UØs5’+N!²¼)ˆD¨ù.!öý<“AÊ'Ë·'–þá,-9+d½ä÷±ãxb‹X(&>°¬ƒÐ4ˍo³-ÚqÛI¼¹‰Ü÷ø¤Pã•JÒá&aò•d¬ú‰¾™P¦?‚«Ñ¤ëÎ)¯úT?IÎބ¸¨”ñýwØÇG«=·†¬KÌo±ƒ^Š‘øÈwÐ äÇ S1LÜ·2KÞÊs­€@¿0Z¯:­ÜèåCÉsåµ°Ý¡G^™³/nâèEÖðç-&*Ð0ÎÍqú[Ò³Q'MªHy®®’ë…8%+_uEHôræá;;Ï"ÖyÕ»èm®3è Z›¡ƒZ;F@ÔA ’A3ô¶Tþ‹ýÌ\h¿«%+g6Ïrh[.~ș9Ǒ_=[Ÿœœ·¡ W‡ÓÀë–5À‰|,7ŒC®N\—¦Û#”bkCŠÜŒ8¬®‡ +Ñؑ&>.Kì‰!z§F7t௳”™Ur Sۍ×ÆO÷'lw l—Ú(œNR.ü‡­Û¡&¾Ñ¢%Ç—Üğ”…Þè/ŒV{—g^ k÷=§C‡™=õléÉ!±™žh·vŠé‚U¯Pe»’"Ї‰=Ü'ðSú;ÄA³.aÚ«££æ­2C^ƒ~€ cò úè­ž‡&DÏàôL˜ÚÀÿlnÿ>k üG… +µR¶ªU¶…ÿð»mÍ« ´¬ÕGܼwM×û"¿0Z™?ák\˜yèºt±WwÉð]ْuž{£•ÃÏйwÔsÓÓ}>ô¯ƒxüæ‘ôô§ÂË(gÁ9°âAC>8‹‹ûáÅ©õE½ŽõöÏ©Ú;äíso’½}pG2àÞ~~„þœ…ÝxE7Ëò⤌k~Úþ.áUì#¢Ô¾-{ «ÀO”î}˜Ï¡¨Ö »ç-°‡u: ŠT YDJ Ág;ɚ€óäKߞoÊ`?Íþx;ýSßõ›|u/€ó[_ ËÑν4wŒPØw ‡­u ã‚t iw ʇþàYom¼ Ádôë37=ÃjŠë£Š]ž¶Å,ٙÐxRµRb¦³° ßÍúàÒÝ@AɺCeaû¤ƒéê@8 :ý}‡ûM¡z§ž%öÀ©§uµ÷Ùî<ˆb؁¦ðœ½åvBäàö˜ŽÚ„ÇnÛČ­µ²·¾‰ µ¾W3Üþ¶?V«»ãç# ýkN €—õ.‡Ë!ß #åð}òàžÝÀÏ¢’òØð«ÜJÙ0ün¨)íɭþÇ#oóüݾC6º ˆþäۆ×ʾØ3¶î»íËs,¯6UÔÜRÀ Åú >ÏÝ+»ô Ce + #g ÓO ^ ‡Ñ@s€6à +€Ra@M‚ÐU4н±ÐCç  QN¹júš¥÷–K+€&E+¥µø‘u¦PÂ@´qoÈîFm¼‡”(¨Þ3ñ"Ðf§ïG]ãC…Àu©2¼ü9"W²ß¦?£_\¨Øñþ +|ÑPܤ?w°J90Œþ˜V9ôº×°·?p„1œÍ…>>>õ|M|Óަ܍>€o95ejþÇƌgÜŔ$nž!lÅ{æ™+µËO8®÷U$K˞­ŠÒ»ùO­Ãþßq/îlü8XPH |Wow‡äÀåkÀ]0ËzÍ.@ôódŠ4JyÛ.Ô/¥¼°_ oÌÖo¨æþYµÁëýˆ?Íá4þúzœÌÞã81ŽI^NY›qLõ×)Á#ŽéN1eÞù_Ùé/Rý¿ãS¤œb´ÿéê%…8æ NlW…cŒïü׿s]ꤽÿEü‘EóBBýIœߣ8­ô‘]6e¡¥UVܔé%­²˜Å§£fÊõ׀œ~ÉPÿKÿŸþZí’u‹ñ÷z…Ã÷½ª}³3Þy¥Úzùm}1—Ï8ÚôI'ªZúîä>wˆ{yJñôülØ£Ó¿ˆ?;Ո?&¦ÆŸÆGJ÷«ÇÇñ•çÒ:¥QÊÛNëäö¿F]ßÿ$èn/-°@þvíûËã7µ£—ßdç/æ4^E›Î8ˆøÛ,-ÂðÏO)Ú=ŸYü}(Ÿfõ~¡Æð½ëG·;Ç,nƒí$¸FŸÝVz5p﫺îߜ'‘ÇĉN‹æré¯öVYı„mþIÐëùØ.pÍ7µ%{ѬÃÏ]¿B<V=Ü>”¸%Þ/DK¹k¬ßîClv¬±å5âGë+²Ó»<ÏßI®x¦îSôäCñTZ”õ#ÿyé‡LrÃý‡A¨ýø;×ÅGÊïعtÿæø´èNZy“4ãä¤:q¢î÷1aœî/?œ¾#áÇxØ(Þ{Õ|íùÇæãþÅÖ¿èùûü’gͳçBy0:±â`r”îô kÝì6Ÿýx:Xï®Eë¾ëiHs;Öd8GŠÊ&Y?G›åä6ڐݭü/âïyŸÖ»V¥´Þú0þòbúw]5=îS3­Ø]¾*ÈÇyœÖ“ìwsï7ùýu. ®l¿Î…gé{ ¯ÂaDï+ûSpmí;•Go§K/dûx¨-Œ•¹ðõ”£hs³<ÎÜMý^ÖCgV *ãõëNƒ÷”ú—sÏÊ.K ÜI{Åü‹€¯jUþoZnV~ ÆÔn4y*6%ß,J“.䳩ž*æiº?KÓ実Œ‚-’S!ÞÖo*[­=×É¢¡u©è•ƒõùÙ +ªÝwϗ¦9Ôo aÆSÖCÙ½TuÓ횏`uOÛiµIgiÃe×½¡MWê/òÛù‡˜^G 0Ú˱;ú5'=®ŽßÐÚ¹¡X¯ÅûÞqWy÷vfÝÂC›0„Mþ½Ð–f¾¬ž76&¡{Í;g·Çz•nçU?œÙ!®-0.‰eY$ŸVâYYr»Jçق½ŠÇ¹«³Q™C¬“È–š­b:ØôªTÐ?$¹\s’äê=íÑ:ÌśÛÈ©íý­³.íµh—ÅMy]f¿•·³Ž.W×ma3«‰ƒ +kIŽVŽížýµ]ìî Î<^çáëÍÅÌößZeÖ¢Á–u.°ÕáfÌTßÇÓ¾Éxæô]ÿ‹ªÑÕ?²‡êNÓBtòedƒ[<)ð’œ(˜Ïó–®ÔґÃ`kK·Z˜×¹õšÇ_þ¼'nÿVœÅèÑ_æ¾r±Â|»}Œg‡ã5­‚/Ûêö¯ÞÔ°YÛõt€N¦¥ÆûYK é—ôO³ó-8Oawâ9z°Ó¸ò˜Ô}67>ër]¹)BwôÔXX~PBúLÀ¡DÞ{¢è5Á±XT{¦À݇ß6è _kWî^s\˨µX5²—'ۙ}5æÆ)Ûsrmæ¦UÚÙ£ænË9Ù[ Ï¬¥@„Ýh³è,}Ǯ̏î,±GýlPÝêR«$—µª(—³r{¤™¨dὼؽš’œ:R¾ò@ÄR>Àž ~» D¾‘ UNaN{Þ$Û͕ŒÁ ïás£W‡– C¤?ÓïȺÐïU¦ãºÑÊhþøEªéöZH*êöódé }Ãà•½çA;l̪³+lͤ<ºhüñh«mEp•‹¦ç5ž¸I_sü}lTKƨ)TgboèÄ)O g/É°]Ì²NÆxpú0=Lì!²p·tÜM"ŸöK”óÖûµ%*/6)qÊL“¢nJʖ¯ÿá¼nãЋAÊï :°ãÂLg1Båª5åÇÙlÍpûäE=.ͅ€-“/å£ëQ,W +/¡–/æøf9WáÀÚ§ÅjÃw—¹¯?ÕrÔpF8:^Ç4Qį́•<\SùÓôFúê§@–îX—ؘ׬ƒ˜à]Hˆ#´Ô 6³vý?Ô~œ”¢£l„Zò ¿…,ƒҙ«¡P›Îï#@çø:îYìB¶_®%ù‘#¡ºåå§{çÆq˜%·¬öðŠŒùvjÃîCÔt´ýòp:’0ídҏn&YƊ!8ð‰¨QN:!r Þät;U;Õ¨/Þ¢FF=£–Qý‘],@]i-Ë/j•lÞ°½­º3£NÔL‡sZÝ®_GX­0©¯ñ{½8çT¤è³ºÐ?1=÷¾Î|nˆu• +½”•åª|v Œ kH–Vv»!‚kßëÏìƒ9‹L‡ zÕ½ªSö µe:'k$¨>ܤ¯jՌʏÝ"¹ 8ßS«\ï‰,f·gYÝ0¼—Ÿ´{­û/‡.\gü¡tVØ[˛2Ó»ã ç¯í–þð¹;MîZÊkJTQś$·E:ĶÃD}L‘øèÊóع®L°Ž²°QýrÛ!Ï~çÀÖ¤¿Ñ"ϓSÖÏ?÷7<¿³UøÝÿ¡òc›?ؼ÷Ø.)§èÞÐù$(õ¦v›hêB…,ŒÍæç.òÜuÁÞ\c4|ïpvÔÁŒò> JùřäLJl%rb{ò„dTkøáXjãm°:À&z›@oχ]Ä(»`[ÕÑJQv¥Ã“w`¶póàØ×M»öXë¹³9:-×(ti\yoðBЇœ‡—°Vƒ…Ù†è¯ A…Õ…°¯»Ð>±ÖÛÓ·× ŒK÷Äç ]p'õ;×Qgܹ2¿Eí\‘S©smŸÊ]Py¥0×ÒϪ$Ü2#ç=sMN(h£ÐVÞ½gQªŒ½ˆ}BPHq»­…w,„`‹Â&w5òš¨ _ö*Î/Ù=Xã¥Ï ²jû[šhôëÛë)•1Ö=K6×폓ŽÑ©:àS¢Ž Õ¸í·ŠtۋÎGn/zÍs{¸Åöü”Ûóý²ô‡•s 9»É`ٌÀšÏ”QÑ6°zsàˆ‚%¡ÝW¢á·îå´] ˆí«PI +ø~c9÷Æ9wÚk ~÷2F] ?;wÝütÌþ¾ÜòeŒ|ѲÀ´mÒT~É­wœ·V,rhåCçÓd °Y:žÅf)HNÍÒbZl–øiùopµôc¹ ]a®Û¤`zOiÊÔF”˜uA©º3JltÁ_Ô&*°GçöW=Zé½ëŠéx´"¶—£¢Ú&[𬠜U¿åN‚CkØ}=ZE 4W¬6¹¡ÛmVŠ/¼! +M¡Q¯™V}4ŠÂz«-%5U‹ÚµN!Ô:ðX_Ãì>éêU–«Wû/§ƒ+[xz¦Ñwå.¥š¸€È¬·þ£[ù¡ÚÉ qòg¿ÀíiÇê/G-Ï<³õCÄõ6Ê+µs²˜Ö&á;[†ºÖ•Zûê½1¼WãôSŒoÕJÔiõ*ˆ#R嘺ªe»@{e<ˆÒù"¯5J«Ú€-Q¶+9Çb¾äøýjəµþ‹™Eˆ²Y’ñ»ƒ@°Z¾À)fg+T!-¦ÊÀdŖèïN. ’Q †ÝeÊ$,rÅíµÈ•Zßby#Õ +¡p€ +b½Ÿ½Ùä÷ÊÜʏ@ð;éA>§¦o9µ90sj‹|åNÃg-ߜ~ê˜æ-Yo¢¯$+%µÏâ ¦N5&tCëô ªuê‡.d~ÝvaVÎn®ŸÖ}µò.óBÉkݙ"ßÝqyEÉ¹nƒƘրjÛ)ñ`Ô-ei§lI` Ó/ éLˆô¿À€’À€Æ'ÀŸÀ©Ô³ˆ²ŒįW$r!m¢BÊ%ë~PØ8(‚””mÑ)¯9€rþ @'~@5EJ9?FÅ׊á͞‹ ˳m‡ÍUÚÚz¾‹ÌÈç¯)º1 W¦_ª]¬7Š³œ(¿bæMq½ô‡Ï%€Ö>€’u@E,ëô]žôš<¬} s«6v¾^2l/w.¾+Þ (Çg '˜;€‹zʖüõÜJ遒!ôÊjÈ5s0þò ÌkµîLÚšû®q­¾涔·ý‚bèÞß9ô¯¦_ý§µ÷øfÌßßÓ4å€Ó§,î…þ˜õÿYÄÁÑÿY«÷·¶pÐÿgñjûϧ±)͔ô#Nü·'¬'Ʊޠ☬Ò)¸ð !IGcªå§,oqLWr)z;åÆñâþïøôÿ·‚_ÿ§«·5ŒíJhÅø®·ýu©Êæó¿òݼ*¼þwÒ[(¦¥ú[!Ž“ÇÄý§ÞIZùY¦uŽÒ§¦þZg¢–ÒêÊÔ_­½¬”bk)÷yZ[ËíÒ Œñ uü«UvU3^ïüÈú¾üÖ±ò*M¾ˆàTT¾§Ï2Üü‚ÜǑÿ<ú‹ô•u?ü¶ñÊIq­Ù8Ké^%V½”O«¤Ä¥±0%|þ“ OÁ\ø½ªì©w^:q/æx•£ ø˜Dü ˜FU£f?¥¨ö[ ®1ëmJ߻Þøs3KûúmÊÃë¬~Ô.ñ8¿L©®.vûë\ðË}ùãüÕvö¿ÂÝOc=L÷+ÇI¹DZ!i‰mæ¯CàO‚®Ÿßy‘|F›6ö}îzTù٘òÍG{Átï“/ßî4ß̂Á\#ή³Š£\bÉÓ/øq=;¯ÀÃêä÷Ïá©4«Ü;’)ÞùEªå +·o‡y§Õ>â®»¿ ÿ"þì*|ü‘Ödº_‘Aœy,Nf +•-±q,JòûËӈ?·íG{vñnwò¸»FÌåz‰…c”>Íù;Ú}ÎÔùT81÷°rÜ@aã°Ã\p¤¦½}۟#;­¼$·w1䷃ÃuÎÀò|c÷éݏjÅõ +e;ëürŒ¾®¡KŽÿM¶Ó¾Ý¶’Ö+eŸ"h éNöè´è5÷.(]þÙì¤Ç[äÎùów'ŽO¾ÊM;¿cïÇbÅÛiV}»5íâ1|•[ˆ믍½®6Ą*­W÷ß}ë$uvn þæã ýšô{òKt½æ™ø¸à7h¯tó;W0p¦óyߙîÀ¹iÿGü´èøÛy?Þ̘‚¢íÈï¾*ðºëâ2‹†.KèÝI§Í<´»ÚUb ·Jü&¹çǛ\¡:]+%;पç‡ÇFè×ÑÁÉ-‘»{®ó‰«ÌÂêÖ^ÕW}m×u,à‹;°GIËEɛÛNŸ{.<å÷Éå‹b’ëÌyâОWïÿ±õŸŠ2m×ø[0a@r ‚ŠEQ³"&õÿØÝïuÏ3óå@{ïޔÔY‹U«àÿƒäûjkÉwÍ«”‰©Ë}BQ>)çÃuȼBm¸{ì¯0ôÚò!PZ«€»ô.¿ìõ€´˜Ãï-ß^€™©o>^Î,©¦3Á©/½/Íí§ênL6PX™èÏ:áîy¹áB»“9>ÓÓÈâ¿yç¶gaÇ1ºCÓPݎŸyè?¼e•M‹÷´qùÔ*¬YíÚ~tª½·ïrÞ|wÎq]VÃåÉ*¼üÛ:WšsÔžåí¨š4mº˜>imɞ{¨1C×8*î8DÚþµºëх˜FÄ"ÌNhgTüäzCÖìIµKߣ‹>œ±Žo-ÚøË*<<È\­š©±­ª &b%Cù‡—VÑZ·‡ªKç +ES»DZ‚›’2OVµØ—á=\-ŸÏì<³÷œŒ¼Â›|O¶G©ìv-*=®UÑyTtÕaŒN۞„½Áðƒ™Î°1ŸzÜt^[Jð:™ër96µZì 1<¨õBÿȏì>¼o]{fý’ ]=,¼€Ýë`[ú›ˆ»«š~‘F¥ÆÁ鎰Ms(•Tf_~|ù`ð OyLýIÐ7ãóÔ¾¨ºýuXÌ+¿yJ̀²Ô¶Ÿ=÷4×G_6+H :Ö¦;€ˆÛ°ß}½Þ9©¬z¸H…Ý`¾º”²¸„Pۚw: 9;t„´(i›|±íƒXáÿà}Š­s%½L3?4àÀȪžä‹ ƒ’ÙBÃi«ýðÝÞþ;Qv0·=ôtʹøa•6·¯Y9<Áà~½h”VNø«Ðè:¨±_5 ®€ZdÕô:bÙÉTõ¶ßÙ\Úr½škƒ&Üjb‰ªoüëJo)ƒ—Þê^ zÞå3äôjq üpc—çÖÏ¿½)£Wx9üÆ¥y㽦»Â%tÑdî;ϲe ýš©ˆ Áàpa¿ãžuS€®óT@ãÉkuƒ›·ñÎ,ßeÒj­-¶³Ø[«ÜÐhêl¨oKO_¯¶ëGÍ86_Z½w¨4C®)6Ñ95k¢~ñ¡^ 5{L”m¿ùïßëûI÷άz¹iÝ…~Ñ[oü×)o3…·ã}t`¶^‹aPN{Äg¶é2Px1xôòê4È3Ð^ŒåÖÊ;g·Îxß!úvô õêë%h]1×l† ¸ß(ÚD½¬'•¬ÜïÊýÀ^Ñò3ñGòó=¾ÊÏO'³Ç'Ã;}›ûüŠ¤írŒp¤—IªóùÇ*N÷bðߨÉÙþ¼Ô…¹«Þû}LæéÁÊٝZœwr rß.ªÌ¥¥m”—Þ>H9í« ›j­9¸é˜šÅ(uÚ å-ÛJZ5åeƒB™Ÿ´ÏÒ쳤Æ^!¤\·Þ—r=$”rãõ7Ã'};gH~»•¼ºYËmj™^õYÐé—&ý®ó¹ýa4 pa9@Š«~—¹œ;Fbg =·‹‡ù¤U>ïVzív)`‰gnp>­¹êËݱRW ­CE†ôAhÕv7zUë8ûgõøáê11‡Õã;VCíþíÆí‡ì).”ä¤ñs5nØÚfϘØõ‰vç‹O¹ÕÛ®Õ+XaÃÈçry›ÚØa ·”€ˆÜ¯ƒˆÅB-Ëi@Ubߪíï_³f,Ùi­®v‚jXZžªýÍ#›']EÛx¾bõz…èùòeºez¶õÁ§$ßA7~Ö@nwANßíA×ÃiÿSKÐ*þÁd(֚¿nëxðÙ¾›¿ã¾.7ãD}É Dgcø»ž[2Jõ;&̓¼¿K©^&Otup¨befw¡Á—ˆà´Žj 6û¥ÏÀ—æ|”æ–_ûUÊù7°¸Tª¨wz±¸iL kñr.è¹nVCÊ'ÊiUÐιg!Ÿ½ +«Wú*Ã/÷d¸{CÁÍ4X#8*ˆN쐢Rx~Ÿ"Öz†l#¾®ÈžŽ6¦½®Q׶R5£ &f(ÉP˜ÙG ›íŠÏï—C1o¨+-_/=û¹Óusýv+¢£V/I•«)b °± 8¿ˆÊû Õ¹dùñÀãóû?8¥t”Uh./ýkùyñ81ûF!yR¥%šìˆQ½¥ÔŒª*8ƒ¡¸2@¦PC4p-µ9€libŠI ­w ‡ô8…ä<Ÿ-L“n{ß_ }[JÏ)ÌNñ<äxRH·ÉäD÷Òl$)ŽÕúÃ:ÚÓzoÇÚݍF¨Ÿ[mônu€Ùꃪ·_ô=²9…?_t•”Î]°±Ì7‹zŕó +5ž±µ¼4*¨êu’{»vŠÈè¾èúô +Ð +^èîèßLñtºïz`TZGäŸ@Ü*κM¦¿Ú>Ý©6~è?×±Òi?.lszÝ¡ôò@îÝö¿TWë^уo~¦èÊبY¥åC5 +{!i嬩´Í¥¸öu€þ8­Ÿƒ¸¼é ž·F`§cÚK€Y¿Ž“hO€år€uÓÏÅ®¸nŠ›°çy °QØ oì\ìîì>ö®÷0Ê;BÔÜ"™iÒ!Õy‹ÔQôsŸžþ˜¢ÙïhRj¶ÏÃBÝSis¼öš…%`»ö`GS÷¯¸úS}kð +àƒÀ Ã;ÀíÐ/À}¿P^àx€÷ò€ß,W¿U^Åp€ÿVû)â 9„<<øA§î#Nn]zÿ¢ Uµ&\à;t:%ûò¬rñ‹Û96ÉcÞrôtèŸÜûÿ¬½Ü{¸ý«ù6Ãã_Í7¬fI¾Æ è°#º÷ÿw]¶?ëÈmÿÂ8Yhù³ö²Çø_Lï•ý!yƒºš$­˜K1bÿɑ?—¬=H©èÿ4¾$‘ï¿$JUþ§þ\½¿ Þßnþ…8˜aŠõý_ˆCÚÍþuõ~„Ä+wû¯¯¬^~½yýOáý“‚ûCÉ®ÞÿØg3çlòîÛi;/¥¬ùۍ¸¡þµ÷g@¾fù Ê>EøL[ɀ Èò“ÿçêý…"lœÄ+FÓDX'‹—_IÖ/éP:<¸t~ªg*ݵÙbýæf +T\q¾Ì£óî'áåÿ„Ü;²€·H)îÿÄ#ü^ý¿·É;°åäÍQé^EMᦍOLÚD*sõ.í9?ù¼ø[oMX‘Õ—´#Ñgñô³ÔWÄX¿(J\ڏÎcлŸØuï%“ñ-g³›Vכr9\© p»¸U&%Ý Ý>û„5:KwgrΏ ÷‡Lëüo~HÞ±ÝHÞ.›~ñžSO[iÔÿÊҍR&û÷z/¿d»Ï º\Åø>öøùqï=×ï[ğ +כ´¯\©à_\ð„GIû”Í¿‰„ã‰?ûH$ŸóV¤…ê=îž6Ìwxì|oî¡_øûH—®{|ÿ…vNZ!lc³£þ‹Kʖ½QòH>É§Ç5&ï’UN’ȇÿœò;´OußL¯ª ÞÌ7Ø»:9t|a7uÿüíÖç¼ Nêr>v޳ˡŸ=ö‘:JöøfšÛ9Õiiwçµ-{^¢?2ë¯óÖÒ«üKµ +Í 6ò3 +ZÅn1¨¬CliTfèÚ‘ÿƒ?âî;®¤M]&p’òëi£#,=«Ÿµ«ý5 Q¢õêç|_¢Núƒ½ï7SÕ÷ø*îlãξ¿IúÁp#\6îÚ'÷óu~¼VjrÚ1 +ƒÊâv[é§_œZ…ü9Ô«¾‹Äüfzʜºãî,>|.3Ž•rÞ1AÏKz 'zjV ü¶?$Ÿù˜I>”@<µ…Q»]Aâsyž•ëŝ.çü‘ŽÐóôØÝNîwˑÃòÚß ÐU³Û¦ƒÖ´+. ¿­.Âú°³@£o]'Îü.-²És:X-fÏþ{?㮅țQõ§Jaª€Ãú´p-ˆMòlwªg·ÆGùqwîçÆpÇˍΐü‡ä[¾ +O½•à7êô¬žaû9ö–¿0“ýU6–{â.7oo¶^­¦£hy»¯ÅÀ6‹>Ù4¡933~l³Þ,7¼\k©M•Ãژ¬á9)›Ç‘»Ã?s·¶€·ã^‘9áõ0™øt®£Zv³qlå`ØcËÚ “ô>8ºñÛú§ĚŸƒ×x©'›»[Ӏ8¯Ône?å^[`×`é0vÏÏhٍ;#ŸÊéËÙÔꜼ|QLÖ7#» ¸û‚Uv!ͅLjí‘#3öØîî%Çoº·ã®íB{˜¸ìl(¼õõ-/–\û|Í ÏBf“{ȃÍî°TiñÞ7&Ü«_çÑç½ÓÌFÒ¿m¼›Âe¶j‡ëà\Ú,GãgÐC›‡ÅðÜõç̄W0˜6ëÎØÝïüÕå¼Óˆhïcû‰_›ó.àpÜ¡! <1KŽ +Œ¹"@ÑGÕì„lÎT§Ía¿[qgýúþ¶ï àʽ‡¾œR7­™.Y˹ƨ7 ;ÏdñèL¼Ñýÿà~9ªâ¹ðí·ß)® ›ðôã1zœÍŸpæå˜j¯xà&õÎè2¾ ¦z™ gÓËÊZ€Ð\½ªñ`û?ƒš ûÝ\é1éa6Ov¯T›ï’î@1Fï‰a0³‹Ó™æÁEûӗOí9ºù´W.{âÑZÊÈ ¥®»VñLÞõµY»e¸ê:ž»üp%ápëv‘õæwîρVá4m ?‹q$¦3VÊpcm«èÃÖ`7 ½~ObÖ=³¯d#‚îõÒ}t)rð6Æc;ßy%ãrGÇP{¾˜mI9r­åú¡´JÜÓ×÷îT¯0«­¶Kª j*ÍSMn6{±4wyùA¸qô¨™·Ñ2Üó;o_®¡å}¾q{zåzxrìná<1Çʯ v±­ô‘v§Ý½±¶mĭ弓tכŽðzœÛÒ÷|kòõÕjó9}£—@½²¯Ôµ½Áf׍…ßìc¦ÞD®ç¡jÑå…JFÅÑ>…Æ·‚߃™?„HvÓQîÿÁ¹²sùmÁ=CËá~_˜çz›çä¨mÃÑCœ/m –³<³ª}äžÕ¨†«GJG¤ãn[ÖK£V°Ç}}ód·z•—B͘«·f˜WŸÍ~`êt@•h{uå^‹(…îçeù‰J=™Ž§Ò[*%1è~%@ƒU'`ÊÓÆ¿RÄa†Ó_T¢ã1zיõv»„Lèäb´kړЙŽÆµæd»?è\ƒ[ûL{Q0ÄV3­œõªÛh]0˜4Ãö)+ šè1ÚªCävRîV|Uè{ò”ŸãjNæ´,½7.5ªž ‡¤ÓPjÜ(Dó¨5Ê/±œÛab9w„íª¿OáÅrÁ?eø½:îŸÊ*ûnVÝc¯æ ¼U˜î«ÎkìäGgÛ/Ú+³3äœî£¹TÚ _&ô6y§µn³ 71ì¨éÝt¨Œ/ð 4Éü¦#~?È õÚâÙ¿NÌ£‘U=m0buù½±Wxt AáU0vT•æÙí4™ ³î3Ü뗫Nτόnµ ”µèïTá<û’~®à¦ˆ6Ómâ‡ihã]QÞápZ*aᩤ`apöðú“ÜüE¯XÒȑð¶ö­îÚ9:sw;’<,X:yõÆ×ΩS‚ëó&U”:ҒxsܟCéèôV¥?õ L77šÎ ˆL)>Û¦ŠrÇ$×õå„ÔÂë’,›Å=ѾÕ"¢æ( Þ}š%ž\³€&lðÅdôjL†¨ ×7(yÞ¼‘‡µ‘G{³Ÿž&µ)îÉ¿žâ-üsõþ“Oÿà"A +uŸbýKp¨äþ¸z=pI%®¦½|h;åÕð§ë¦»yªWâñ~–ÙŸ|z½iëM’x7úŸhúƒ‡ÿk¯%8Çi™Í¿œ‰Zþ_xÃO–ӏ¤ˆ?£²°–{¯¯n _ÒÞ¿ò†3{u?x–Á.Þ`Ñ9Öoùø±§‰üšð½÷­èwğNnVá±ýÅÞþÚôYFÂÏ9ûÇ%ûóô²§hAÿäӀL[ ))Ææ?—ì L¼|˜¼|ðZxµk5Þ G8®XWòѹ_Ùû‰y4î½$×¼Eb®}ùÞõ¦Àö•Zc™%þëÊ2J m áä~öñxÎ; ),MžýÓF(اÊ<´ŽF~2ø@Á Ÿ¼¹|Ú¦¦­«RÈÕ7æ_~1ўê!Ÿ9!cý M{\ÚÜ{OötÃçÈõJÐóÂnKŸÈ«ùó·W-Ÿ¥¨ +…QEÃÒ¨J÷ü“9Bó·x@‚§º·Ê`wç@ug÷Õ–½BßtDáb!Ž³Ž`ísÿÿÉ»¥ÇУ³V€ímAq¥¯÷Þ£ÜpOã.±ÒnF^E랥°1býø~\©ùëzþ¶ÇqX²ZÀá$ÔÁ=¾*ÀÛ¸P¹§Ÿ•¸È«€9h«Ò44ý–{9´—Ðê2Yô˗¹uî+?½s³ÚYl£ÉŒM€žÇM°éw(S9¿™Oó+*ššþœ4ËB<)íðÇH>y{-D£rñsy®ùËy²ë°dŠÞ>jÌf[·ÚÖ_óçU_©OìTæðgqj– +~Ô.¥‡àXAæT”'f.‘g¼d”<áUR¦ß)ҚJ_ª? dÁ™”VúÌm•íÍxoï¢q½PþŽNá¡úÈt.ºvˆC?›®`ßGÆÅ1rô’#^¥PŽ¾Åð}<>:§Ý˜¯Î6„´6=›qÒ_œÑØ'ô8˜=•RèÍðÒcº KŸÉJ«'à®^uÛP={Ž.MŽëoš…³¦4ÂjVËöܾC"‘k¬ïrøʱáp²œ¾­X‚­ÆðÕ3—Ðheû‹ã`Í͎í=<ü‡g¥aWÜVŽa™ÌL[qu:¬ZÖl¶ì}ÆÿjYÊü~F5o܍i‘|ŽÜ,ÆÝGa?$…ȹ¶Ð§ýèV?6s®å‡S.ùo¶æ²BX¹U›3—ÚL5‹×Ko Ó…lÒÒ Rh­û-¸ö!œ{½ÔìFðqÖŽâθ ¯íØßóæ‡{´öñ35ÊÛ1~¬j®qX:?›½gøÀËAy¢·1n|\¤Î䲉˜öøVt†^ó-¿Œm̀"OfÉe®ýÍ?ûû¶ôšYêzv­‡DS¬y¾KäŠMãvÔLƒFf³Žë½®a|ÚoˆcÚâµüOgݒwzæOkÉsiõ®º…ìò¼°ÖMᱸ‘Üq6Ëóiùœ˜ãð}Pœ;>'‡Éa,¹‰È&HRÆ ªªN¿nõæ½þÝ^w­WooÜõqdŒ*묿é<õ»Ã…û|û=Í×ÚâÂۀ¯ +-¥>oë«ÁÕÖ5œ tð>´íb€h5Ä0›‡wiÝìzÉê/¬[ðC¤Ì«ØNèKù OWó$³ëfºÙå.²¿ ñx¢sšD ¶–‹÷ë¯Ó½ìûŠqzÝΫ¼q:|çäµg§[ÐÎqß}K™}ÃVQ‚îº ‰¶é¼Ö¾ôkÍ#é“Íîã+«ç¦ +U\ÎUìJFÊÕ~TªpÉÈ2üÖò15!T: ›& åbôLþ¾O“úñ±ѓ=”«Š:Øŕt\²®Ö &Ø¢þòˁjç–ïfKEѾ¾Ҏ^~ˆžÖQ[Aó¸1vM¤jœÔóÁ½©8ì'Êõõ.)”X…åhñòx±oK ‚¸Ò4šî%a&å_Ii6ü:è¥  ¿PÏÄûßö‡ƒý"¡Õ¡xËù“v{eúŽ¯¥s`¿?›‘¹…™f/Ú$d'¡V•v¾¦Ôõu¢Úh‹Í<ԛˆ9é©æwë(7ù0UœÂs)ÇÚ;«:e·R ¥Ä¡’G·¾’ð\Õ>ÿ¤rEnŠáÅ&ŒlÄÒëü6ÞC6ە+lf—¹Ðjlg^eØ%»O-¤Uì¼1â?bô˜Xfé<Ã%å]“Ñ»ôbO¶óo¥¨íõk¹Ù§¯ˆjñ/F¹ík²‡µ–ÌaX_J® G)e*ùá²!7'»Fü°ÃūƵ¾öⲍÍ#þ:÷˜q°lk6Ÿ=Rï¶!H ˜A„:qü2q°i±æ¼)¿7+P2û¬“Á¬@’Í!`NV‰ÍÑí­ÞÞ&ªHâáû7µÁë =ÂÂÜúƒ¡ÍR½€¦ˆvÎDîÔ(ë=ç©åçeiȁÆȽTýÁíõu|±˜¯Më[¢4zá£ÜpÝ>¼¦|<i´:PÃV^’'74“Á¸Ë▧gÜæA6#úIlE ª‹n¦âeâõsÈ`¡H؀@[z—èeáºèP9-Q²T9!£–ðDâT…'cœƒyvÝ«¿ß|PŸÍÁO}æÓj}æœFõ™±qêï}4ª¿ý½3 >Q6Oz‚5è²óÙO +Ö>¾ûÔdù–¿Ö{§öøí¸ömì˜Íƒ”r9=qØxÞ1lpOÐáõ“Gӎ²†ÇOÕmd°ÏÆSÍ;ãhP-Àoíý€À6v­ç×£Z÷à,6§ŠX&\AKª|QòÁÚàÝjXàˆH¿aúKÏqë]š°O¸Ä½-µøžCnq&]¯ÅSd‹3xÑ/¾•»]▀SâFOÛ¥¶îD.›\n†ö Ò{»|Zà®cô[{¹h§üUõ»LÎÖ¼†0ä5Ah-I>ÂpLO¯¥©6}–„òú[*ùrqn@HŠ[”ês¥(ÁÅ~1wV²þ¦°4W»Bñ^ˆóëѨ–/'1·³+W{@»\ê¹N½¦çvòÄɗÙŒf¹5l+(: ƒn­+çý|îÊü +î~¬Wuú侩dÊ-;²Þ,¦c…>_À8bâP8Þ M{žä«œþÎÃf.W' +Ðû(€²7@›’žbg(/S,®*𠀊€ „?PR?($üÒGÑB£“âàÈóâý`¯¢ mžÍ:ÞKÀn½Ýyâ95ÙÇ·Æ>Zl97îL©­ °û¸¦Â…mDUCÿÏǧPÊÝoA[ç^À™³ß6³2gJº J)’:€Í) +ÀvS9ŧ `{ÅMqÙØA~ØHeé¦? Ô €­j›|`³ªCkyëÑÀÄýá'F(¿Jv6ÓGæ¶Óèñò+m;­ ?š2Z;V¦¸ Þû°ZË5¤ä3à변‹Ëw¹’ß3ã"€Ç×@*…B5EN1%¢þ&5€`&&@¨à<…þ”ÛfHác¡©-€j‹÷@ˆ[ ÈÛ  ñ%Åãâóý+F?ÚèOŒ–W¯J"÷û™)¡Ç5n?1ˆn5r! ô¦D& ›ÁÏחå:@|Ç€ŽÐ?<€la4@Zm ½™šânäEä{T™½v+ÞcŠ€{)ž€"y€¢\ èñô'ã7@!Å@•H¬»ïTú§Ïue)á1í Dd ¯J¡]½t–m°Ál¤bY&ø¶Ôˆôÿò)Ô PË÷ÇCº›ÇEø9ˆ!Bhªßh)´Sòzoï¦ +¿†ØAÓhK#U€éÄ!Àû*ÀtçÀŒ‡ €qGy€™ˆl +Oý#FKT#؂pÏîiĐ]îáÕIôªÃ/l‚¹#Þ*tGùÓÕçÌvüÇßû ›Ð¢¿ +ë_ÕW¬²óv‰í.7ºœçnwÏÜ··Úwg}€{äb€Ï½€‡î&À׃ÀÃý"À³—âØU¿” §åR¿Ä.Ôæ›ÄìÆ)î¢UÕ^ÏÜRИ +u¢bô®¥ýç9þÉÝ?¹÷'<ßÏÞ_ÇñÿÉþ“ï;øUë õwº GÖÄ|9DèþÄúŠD&½ ˆ¬þVcûY{¹]úÏ<¦þKøO9ÍäH1擤¡vþ¹d«±ýB~«œ àK‡ý\½¿¬^×ü—àOG¸*µþcííÿ…8¼Þ‰BÅ×·-À/é8^ù¾2zè}ÿGÜý9x7pû9xê…=á‹_ÜÀ?oìO;ýágåÜP¿Ýü1 ÿ—3‘ÅôJïOÚÊFå,íìë«]¤—_~k¯¼Ï ^5ŸjHŒž¥èÅúU^Æ»¿{tbç|?qÁóŽÌÞ¥›•7²|¾B¬«S6—âo9·YîOßýIªäӿ⮘îZ¤Áÿ•OùÆÏ%û/¦WÙ¿|P¹>Õ#óŒõˆÍn¿P„û‰akwd* ·HЩîëÜÕ)è+µ2›·lw¢¤3DÂi>ú…"œóÃÏ>,¹ÌëT™]‰´%XóOBÔ.wþ ‹EØQg;›±Iœ,©ã^úSN@ÿÔ/iÍáϒ! +qe`´íXwÄõ¦×[ÃY^ܒ±¼jëtöaùrΛò#,9\rҟjÖ Ý­]DwÔ±Fo]„‘6‰Õîl„ûj¼–"\b®š9šZ•–(lT ZÅ7ñ’ÄBóÿ_í,±~ª&wd´ÊJŽ«ý—¢D˖²‚L:T/¦tܳ’v@PgwÓ¾ým܉‡[ö7{kŸ<ùëüø´Z©I´_•¼ä´rùÇr¯V>KhCƒ äÀÁ¾[Üüf&Ùc¢9u_ïgñ˜|§£I6ï%’û½úïm’lÄ⯁ÏR¼ß{wòx¥æ½ÕÙ¯•vÇ=ÝÚí­|ý¼Û…x“ôàüÚ'ʕUÀ”‘@ÿ¼2gÊÒÈ_™Å©ùÈö¡øVí¡Ïo½‡1§¢Ç`æ/ÇKÆ9Ï’r0õEò8Í/”û¤YœæݍþÁÜÊaÕï{b06?C‘sþat²Œð‡ìºÉÌÑOP[×{·{=/Pis4¤‹½Ç—¹ÞÆ«Ûæ* X'¨Ìðùâ¤"ߪBá܁¡ûÌÅ¡·çÑ`nú€¥©ô©Ö&“RP%ÜM“`ÝʖÎòlÆFMÔF§^«7B"gäXÄfaßFÉѦ6ºb„ ¹Ü¼g%AyfyͲo¥§áÿàU¸7+7r¾ÃuóxÞ=&Ä|“>ƒxùªË½Ed»ñ#m՘Åýæyä ?•’îhRZh3·U¬Ç><ŽNþä2B “‡c Vûv]çmšZƒC78ׇœV¤,ïJ6,€RZ¦Ììlþ´¹¨¿•¬€ê·™|»wX÷¦½®iÏ{0ޙý‡?btÞ<|vñþ{øÙx—ÈÎÌ÷¦<ãm…ðëAM@½C»S¡WÛ°ï=´tí yr™™ú¬Ùò¸³r¥sh*­óu°:œãÖý¤çqR)õk"^ï݃•©Üœ=ãJÀÃGƒ\*ÅÎåší×ì䶧`Üjþÿàꢫl´v¸HÅçz5÷K îÎgï-kNƒ/ªºð"Fçέìm òžŒ[¹nK0‹SG”÷^¿ß©Nï8‰Òþ‰–]SŠ6Æ5¸´.¿uWèÕa)"›$ÛNòÔšº5¿æՖdë–äρ®®º/½d­T-­r@ÿƒ¨Ðkÿ£vãùÔaü麇 ]¸ùn:#|IEÒȞ°›ª±(ôwŸQµ×;͈®ùÞ +†S»h¸÷ìvØwaØö Ûú.«ó–Œ «V>z“#¼Dk)‡¢V-HÓ°šB³Nì µ¿Ä=í=nÊ}dýb}f}…˜¯†ÿ'˜~×ëµôX89úè|ÑwObÞvâÚE6žcz°M¯™*¡_Ãñ^…×ý@mÑ+“-yQôÌ4uÐü…œj­›b6´â4»…ÑL µÑR”·{åbß/ʐ®¿âÙ­È#í@ÉL…Фçm3–xE8I¼ª£Šu³‹bý/¶¼¹K½ü +ò‘lêâOž¶æÅå˜0¾#[dö©ï:LÏdÀrçUº'­…οuŠZ[ÓëÍÃÎ$Õ0 êÀ]«Êå½k+dû:Pn$3ýÜTz¡X MÞÝSãӘd»iÌkŸB£qR0qÉmeQù–˜ÖD[amDUAg–š ³ESÐáÏà?l¿(•[Faþ1[ÀiR|繊ǵíôO'‰5Üò³ÒZŽ†™x¯µO׸ ÏÎ_[Þ@…ŒX“%Jz!AšªR³ñÙHí†TUûÜÁtÄåh7UæµÖ8ím[ݏP©^!~÷Pb·=î6î„õK\ï&e£µt»üÅ~Ùÿa4*¹ÅLbO“/§ñy¬ìŸLÌí}Ûí Q‰ïˆgM¯LÛO';Wù‘HO)š¹Æ·Ø,7$ÓBÄåÍ¥DÕÙd5´°)DjzV|;BE‡L~_\¾s³—܉^¹~±üäu¯ÌFVŽeñ»ÖanKÀO‘|§7GÓûzÁKÝuŽŸ¯mÓvfÁ˜L>;·‹§ƒ£²êuG[Ul‚ Ô<}ۉì"ȹñ5Òñ`>-Œ„V¬ò{­Žò&3ÜÉnŠ\Ÿ²šû±ÍZ4c ¬³cn×]Vª3´ égaLÒînӜ¹ð¨·è¼¨w#©·Dõ©7…ôþº«úôôW7ïñ‡óˆ¯›a‰ºyýók;0¦ ]Ò·—¤iå-¥c»ìÁŠ–H¨Bý;oô½/wº¬JJ ÖZÞqæ^z2ÌD%ƹ4[ =tMúو&ô$­iîd^©zÊQâ•Å(`~n’ Y›Jzm“ +ÒäR|³RTJq÷lÒ]^|˜)‰»çÏ!r¼êkgµòɼ¯C«3tíØÞ +3à?âÊØøn^ ¹þ½°Ãýbî½FŽ!ƒ +ý´†0=!ÙÀƒægzl–`“šõÄÕ@¬$·€\Ìð3YÌõ>Äê”G­oÊD™‡Çøös¿à;¤SlºøöîD™Øw‰r5è,uçŸhÞÙ^lôÈì<æ>Ì/z4~vòDZÖ4— Dúìȯ°«ßBöò.˜Ñ( éçë~§yøPŸjzY5ºNèy°À1øl´1xÝú‹^Ñêø¯‘›î‰´Ö¡©ðf”ÏqrßewRyŽÚ këªÃ®0IÚu +ü1ü^˜1fÏo¨9ÞÞS9g‘Kzñ$‹«sŽXë¹ +¡W`„(ß4ß9ÃÞ¡·-ì¸zšXOG§RéoÑó-‰QsdT‘ë+â{Ó T›Ü#T§"” jˆíÓY1b;hë‡ß╿$îîC0Ʌ¿ cæÜÇ­j4n+n’fÇyäÅÆ´\¶d‰fvD…ÇNxgÎÜpHj¿±´,a½ÓA.+ÑÃxÔü´›ÈMvºŒ*DWpñ56Ÿ‰1fӁ»SÒAG²Ó†ÔëÀŸÛ;„ÇýÚÎëé¯l…c׀2éŒ !Ï *ª¤…y †ÂÕþ$ŠÌ†h³ý<§jñ'ãQ©Tø£uÍ&¹åÞl'žci¶ˆ<'U1z8žÄr)ÑS¤/âfþ0 Ó)¤º€ åòNãþ šmÖ¨T{AÊ°DªÒ΋)BLPëF5@+Ê Æyhµ“4'ª1^m@c»ø9q€Nم½2 ®­o˜IRk±MûxC.?ÒÕ´‡¾~20,¦0ÖyiËféTêÝžÌ –Aڞ °ÖT» OÊ٦ʹ‚°öx êc ˜Añ˜–w‹qJ&È&›Ë™ÀÏfãZ­×)`:µ0G¦º7Só}ÀXvüœÚQõ…N‚1ºuÉÚ¨{͔ëÃÑ£ð)[cWCÇJÐ>ºßa­ê÷mÖ_› +¹xfH¬}F!äUÖéüýpð³Ø¯•{ÅñQ>#ÀcÄ'ˆƒ$=Æ 8íÅ诗fŸ1N,`Ÿ?ÿٗ9ì™xv­å»Éô;ÉÏ´Ah(!SYç-¸¨ +Ø5·a.µoÎÇRÅn¸œlq%ª4ü(Ø9{¡‘w#…¤Ó›V*U7çwÀ«Î5q;ñƒâÄx"€/a8à›&£'¾ÿ¶?/5cœF€_1^àãi:àGfðczxï¾v)¾þ™ÇoecÔ¯MiÍ~WÎbþ&JÙé˜Ë‘iò °Ê¢[~ÈõÜS3‰¿À"¡-#c©ÏÀe1…ƒ¶ÇC@¨J0Æ„µ“ù‹ „è* +ñ‚ Daòo€˜Ët€è3 v˜KŒ5DÏցØå< öà#ë'ˆEˆÍLj­D{Kü£ßz&?O3/íº¹³ör>çnýªŸd_`Þâó 9EòëLÆO.D~NÄïñ x¤¹?š/Sø†W¤?¨U õî …lH·F dÉh²Õúd»éÈNæ,ÈN EÝ±CÝ#D Þ?%¯â×g{=M(=SڏmácXïœÊ7¹k;¾ ˜Z–g¬ëw*Haæ¡:ûRÿt"ɾ¸žô?vãQ¾˜ iæoÞÄ?…ß9ã%=ÅJ¯€2u/êÈIw ¨ùq¨5g Ԟ‰Õ— @íã÷P ¨‹Vł2f´³ðW¶“gØé"ˆÌ|C£ cˆõòé‚(L%ul ¬ÐßnýȽ‰µ7­¸ÿwÄÄ¯à›˜|ÁW}%©½ÚÌ@§q +èµc>¾^÷z@÷s Ï8èÊú›Å8¼€þr` há¯|šˆ¦ ~Cûo5¶$d J$՟ü†$þ6qõþ†"”«ÿ€‹MbèËg€Ø»§¾è]c|ôz˜›[æÕuñnõ;âvg7ûz9ÿ–8ûJª_o,»å|/©Ðõ×›ˆ¦‰†Z$þ† $1½IÎDjô×}œ„7pégÈǧTáæª&ßC²iÜ­]R÷Ž4f•›}šÕ¯kqÖ¾:דÙ)—Ñ… ^óè˜?­¾Îr¢N·Š_9);hð{›(¼‰A6‰‘M4Ô¿ân&•¨}?Ö^ö?!‰‚nVžú´ç=ÆÈvr·6«Õ-¾ê®¤7ýO(ŠøÑ={Ў<݊»x5°Ü‰Ç€Ø)‡Oý˜;˜Ç¨¸…g5IDˆ›Ù® $Øì +úf}´oHÜ#G]yô¨”të'ᛂ07_¾šHªÿRN<Æi€ÞgI\ÓD¸0½‰ñÁÆ>K“Ó×5t|ڛîáSÝ ÷!ןì’;ß:¯ÂjÓHÉÛõÑk~!F+—Ë[Mþ,•ƒ‰,Þ&ç¯#Ρ~OŸYï³.ò…QˆÍ©×´Š¹ÔdW­Ð âf& *GM‚ø1Êþw/ÿj¨¥ÓY§.G}9ì­xµ»uº©ŠìšŸÙåÍôųÁæ·çP83ë áÂߓbЛVÓ ˜’s*œ40v5nSìa5ÕÛH:× ¡/M¨àÙÇsþŽ‚Á8oyxð@³ÖãÇ/ûüœÃO>|]£{8wÞ½ïÃ§¼¶¤¬ÊI/[1Ü[¿k»Ê{Ùjæ+h}fꦕGŸfXõf‘&[1Ì^9Hß­‹ÉÏ· +:K4[;o8¯<^ä´.WPq҈NÒ(rÒlðlυùè(þ"o›½u©^é6H«áõø$¸ö #]‰ë+μý œu;0:ß=ì­Ï¤µòéÞ£Úh"ëÚ(S7®¾naZŒÌr­‘x5æÁ­«í6MTcŸ¯ +®Ñp.¢Pwº)ö‘8¤ÞÛ]ªµ_Œ%x<ÝiÓÖ膷“"Ü#© ögõqé[àxs‡ãv/„ëW_BÛÐ^Zk¼¦ŠÍðÎV›™’Ún”Wj·¾‘òA½z«Nk{µº¨±KoWu‰ ª +ÛèãtU«Ü‡†Pшq²ùµÃÚåœÚ›—Sèµ'Q)oƓªÎw_Íùþ½R«ŸmXýÑèÞpÚlçK~UD¥.oÞЎÜ]?ÚêñjÎ:)ШÓX½æÒ_S_­Ù£åêÑ̪X.ØNwS¨:r­ÖªôÝ^ù­wƒrn= Ë©êek *ÍyöS*E.Y\å/jÑIç«Ö¶­ºA“i…ÃöQúA«~øÒÉÏĝˆÑqPSÑìøµ=e{—ùCv wŒµ¯|¯oëñÎMÐȹ¶ÐWå1–2å÷^§Ë&g‰ötT×ljåKóp`—0v^/:îükµ*’âµoÕ{ï‰ÅåM¡µ¬] ¼{EòÇç¥pV4}”í™>/ÝsÏ "垛N1Ôë«ûqz ·Æ6I î¯ÞëžßxÅ}¯I80ªxD½‰ªOç6~oËÉÚÚaƊJ ±þ.®-)’‹ þÐ +kÁb.‘Rh>f>šŠy¯LVÍۆi™~×<šå‚ùõ3ÊÚÇ_¦´‘ïÑß;l-]}–ñzñðzñÃ[‘…Ëܦuòc;„fâÔo”ùž§’™jÛº_ƒÇÉ!þ*OJ«M n+k÷Xl 'ìx)Õç7Þ0ï=¨Œy×YÒTÇ—{UËJÎؗhzE#öE}–džzfo­µes~Ó*º‚k¶ÕÔZM¬«µ»QiU Uºâ£]þß=_Ý|ì[Ôv°xÓaO˜~A­…kW³_î˜Êh Þñ07ˆ;8oÏò2œ]šý’±Ï ;ÅkÜ£Pì#F:³$õReÃé(qÉjËžÓ•ý.ØÕÍ+wf9öUºò™+͛~V8–Ï%3+w¸GU£É\–ÀÌ^§ 3,^Û?˜‘vG|×ß8Ĭ+ÓX߅_p£±ïòUÿPNâ?ŠD +™boŸ—£ü4—žB£0ݯôÒñrÔVÂ+>AW¨[KΨu¤@*‡r‰SZ¸++Üe“—ÏÝWEîXjG–’íµŸ‡¬"ôL=yi°ë}—Q’ÞÔ&’>èb’¨9Iogÿ…‘k’íïoèÜÓÈ V@³Á9ï¢3lµ/Ya¬ÛJs¬9Fe¦Ö •r˜7¿ÓA¥Õš=äs´rÇ»f²×ûƒÌö洐Uìœ&=ù~ID§¦¤O„@üü8fÈ·h>CV„†JQôH(Rt:ÆIÂZ&'„`$˜\ØÛwµÌƯ}ï\L/:#›¶œåÖÅÛ£T™|b‰z¼áü]윌°IMԝ JëˑN/ei,î³>,GÒ³¤=¤uR’~aâ§s`ÅqUÄ<,?i"´ïׅ°yñ…¢ž_ Èg÷à›2ÍãôÑäqe>àÖ¯CŠ[¿»2k{ƒÇ¹¥ž`|wwפ€aOʤ—ˆçÇÍ!xµÞ,U®¤£@.ríÔ÷n”9ìu"½|¦BE ~ö¶Z ¥çn:• vµ?§ÇQ̋ï«CÜGCŠ%dعÈ/Þ©_Éw†]nCÁs®z÷nì^8ÛÄ|ƒe7úwôdÙmóͲ;Mb›dWg›PSK0z§Ö·þ¶¹?t7µr‘13i2WµW}öéjÙ^¯5Kü¼3¹)Ó»jµNv!g÷_2ÂÖ@Ì/í‘0#ês¡¸}““ø%3=óåçõÉãCâ69 çjDç¨íTc÷~Êf›jÎeNËɔqê̈Ò¥/wC£»ýKËeúAw‡)!†¨Ò—“üƒQÊÿˆæ_1%È¡›$¹!XY¿ +8®nWó;£ LP<‡ ó‡zèT7Ùþƒ³¡Ôã+2à6 lÂÕÊʊ£…ú‘Ý_Fw¶ÙÝ–³ ”q$ÈeS¦¯Âè;HÓÝË#ž¹LK#êa]Ž”¶ÌÁäÛ}ÉäH +šdî>¿#yĒïÚ[I@i[T æ÷ùÕéÜoÓÛÖ&o-ê]¥8ù·Ü,5îG3L4Ú(³ÐwE òñA ÄOl±.ÛÂ=æ\]™õœ3âÛÒׁÑ=½þ¢c¦ÕIé4$’#GƒQ4ô€˜NJª§SÂôE|~ÊVq{d¿žø<2i|¾îe ›Ê„¥Ï埐–¬y¹tà)whîïöªÖ?–G‰í¸xÚ,sR(qzõDÂòZœÅ"_9fÊté޽ݥç¼Oé#oB~Ìð+“c(:æ º’PSDÈ50Â:‡¾0o^†¥2ŽÍâkQ•O/12ê¿Ð]WäPæ±´3Ç`½F™×Gœ"¡»’.aäÌÎ&‰áÞ+¼Ü\ÔÒ¾ûÖ禳©ŽÊÕIّJžumavnžnŠêé +¥³96¼ø¸²`.ŠäS€+{D±{øâ÷ñ²+Lq Ì6FÒ¨€T+ 5ÿ H] ÉÅÞh=CÚU M5¼MéYÄ“üïèI¼Uá5åúƦ²p”¾VÐÄe¢ØKyü¡&¤{«{ž¹¨^~Y ÃÕa?U>k}@ùh#7‹Ñߪ±¿ªÉ¥bt)@µ`-Fû{‡Pmlc~TÅÆåÐ& Ì{ü…ø LÉ», ,~Žr ¼ÄZlHÿ`8¨Ú¹ü©»|M\TlÚG5ž;G {¸)‚–¾¿ *®5¢½¢l!Ù!ØögC@Ÿ‡“›9 #°‘b´ß1N( /ª#é+ßôvzW¸zO°€žml@¼ø ‚h·“D¶Ò•s-A»Æ͈F÷Dd~20Zy.@Äf®·ÎNO6”#4ð‡Áè/!ÖÕŒzJî†ÔègRŸ5Ø]Œ°uX¹¼‰ác,.‰rkAï*ÃgbÉÜ1?\Wñ»!‡†âÏØʺꤋj9^lŠðNÕ¤ÕDÜb;`ä2éO핖tzºxd gn¦ΟI3‰í˜‚À?‘%¡&„|Bu+¡‹ê@˜Tl \^®nÈ=FHáîðÈM€ðd_@8Á2Vü(Æ#‘»…µ ÿ£·Ç”¹\õÑ*­%§ÎØgîÞ&wËBýBQN‡a—ý{‘Ï¿žãDðM¤ .Pö¯þ[Ê&bf’’r/©¡6€´;Avö ›F ¥WYejueÈrÙ Èòddt²D:ÃeK—•’É—äKëM^§,6\-8U«öÉ Í}ï°£êåh¦Ky\Iqu™ûӅD}®wå?roâïMð›3‘¨¿_kíÕ÷ÖrË +€’~¬€Rï?€jPö°•xnï»PÓÓ+P‘ÔŒÛ*ZÜË¢@ő|!½ñ ½ójܳ‹}nÏÝ»XHøÌC™–“¶ùqt¦}ùç8Ñz¿ÿeíM|Æò#þ:ÿä÷&Âï¿4ߟ$ßæh\æ +´~Ú#¾èétå<zqözs¨½åû@êЇ$tw¤þÏ¿ò$rä¿B’˜Þ¤ÊÙéñ·tXâêMBàÜ%8„gÞõŸúü6~|ÊÈ÷ÞÚÃÜ`ÛTÓ/wëà|îHkGÞ‚¿a="¸:OwŸ5$H\²‰Â»id´Ú*ª­ì¸O*úW1Å¡¿jj"KŒ$£÷ÇڛT9Kò†çg]ޏqæš~@•~·¶oæ¶`Sâ sSÊu-¹+Ù#¬ËN+&ÑѨt#~Òž½ôpqºÙûãIوÐ1`@îði7¾êàoòmbãMÔÔ${ )Óõ¿åÓDóMNóN~| +·Â*Cµ;RüÖâǗ]›GG ۞#:žnÖó{é<)‹Ïó>µ|38~€Ú8½·.”°³yë|2¹MΔÖm”j¬"§:\I{ä²ô¹5›˜v:öñwz"î&1²f/’ÿСÿvuð¹}îÖª™º:'ŽZ+v–ÆWî¤ÌÞêQ_§­Ôx;;ûºjlvF½µ>loÍÏíþÊÃìÑòVµÃ¥²·—‹€³·óOÇ9ÍÍ[ë;³™…ªfÈp…ØtÍN«Ęì*õæ„Ùåã6{Hÿ xâ4“àÇ%«ŸèÐæ¬ñø«¡NW‡O…ßììh¼Ý0£üwr»ŠŠÆcy« EÀhØܼpôÌzÐB¸Ð9eºÎ£ú”œ¡ùÉ®D—&̊vÆm’nŒ¢×I'y0ôÅÜ4xöj›@ö£ÁØ8§ây“Èö‘ÅÞñËDû«ÜúØ6:÷ÖõõéøZftèoZCÔº_WG}qn×Ò¤µ’æ‡ÆBß×[3ëÆ]²Ìp²³ÈùøX&·£¨Fž‡·vžôô;ü­3kpf`¾)²š8ÓGBJôËJé­+‚Ù#·ªÝm0å¦wlû}¿ìæO!#÷˜«¦Z•ºd‘÷¨õYœ‡ÉÑ=DÕÛ9j¾ñ¾H—ã¿ =µçŸÆZ +ž4à¥6òȒ<]¹8+\µ¢ë/ +œß[Ûô¨G®¹Y·A‰kïØ÷æN¨£Ý:ÒM{¹¾jBíçÐBÛFªžlÁ[¹-¶…f‘HÕ‹º6h`ÇÙ®^ût¼e‹µßhü —Æó~Ûφúrù \o†¢diÂF/y”%VX _˜Lßzñ޺跕v™mUðøcUíH—jÞUÕr;ÐõÖgÜh·òp£Û KAY5ƍ…ãÏØ.ØÔ«ìøXÛ¹ë{¹Þ¡j[ÅI'æe'› +J¿u+jf{*Nïû۔ƒ*aþÀ R¹Ç7/ŸW×}~2³»)wÜY,JÁÈifû¥‰÷âµÙËkËå«ëgÁ­­¿.ï4=¤‹òŠh`›W'+©Öà·Z‰®ßyZµ½–œ¨uOO5+·qÚ«¨”ƒ¦<³?ïæÁΛ³g)ܧ±R±YÉïK¥X^Ã">Yg¬MÝT¬M¯®[5ÅÒüˆÑÐ žLÚ«Õ·ZéÈ~Ù_/sJ—“„û˜DÏvŠ<훙:½«SÙΦzâ‘s1çïʽ±NWÔӑ(sO® ¦Oɞ4ÆOL¡4s•r MYbÅr¼"ŒFV­}þ~Ò +û+q)4{­tþŒ\…¼»¬ØyÑa'f÷NÁf>ʦ¼ßý«Ûن5a9iŞ×_FåJ×­‹šû*AT ù„ïú.UÛU;°VúÓãw:XΕå]èÒ`w+®°(ÝLƪ=pÒ¢W8èy¹Àóz¾CU­¼¸ªf[¸¦A£Ü ons:¼z£O&?7Ô¥âëÓ©÷Ñ­†ðµZ閯ŠÉƒ‹Ii·¸wX¢Óõ¸Xí<r®v ¶A݇ š-Ëûò˜¸ K6é‰oqs‹‚]¾Ó¡.æõÆ>͞ŸƒL¥è~ 0¹ÁÒ¥sze"£ëF3ÌÞËÒ§¯LU·–垶 Æ3;1 ˜ZEIE%ÏWW%/øCÙM6lŒÿ‹9jÛÑãS™°ºÕëz¨úÝ®àšÚl:½_Ï]¨’+pÇҒ¹M,æ¼ï奡Ö3•mn” ”æÒøݽ‘ýȀ6û—^¤)9¼Q­l ´†QTד’R»%ew8µ”F`|…ò ¹½`Yèí²Ù‹Zod»èð’íb:†Ëý"¬«ÕípLiÓïXë{þªØlk²Õ`žŸoZC7mÏ[ôÙ:€õ4ŸÝu;9@?:‰Ü͟}=“=µò<µÔp›Þ«Õ5©”Wz)»RØ~•Oڔ–]ô-g/UÔÌv³•Z6¯9¤ûÜØJ¿þˆ¯‹Á‰Ã)âˆÃP>ŠÃ=MÆÈ}ïxˆÃ™Ì&Htó œåf½“ ô;C)ßjUÒZ©.¸P¶ò¹MÐҚ—¯…Na=Ë O%WϬ{-uÓ´\•:;}¥)µ&ò),e13Úe/Ëm”íVßAV–Xºßt\Ҋu^|g¦š8<£1שtŔùZ …}ù)¤›/šŸë¡Íύó–ŸçæhŒ7“@HPv"]ÕÝ`‰Š³žÌÀ„F;I•øÞ¿‘ D©À^lT¹[ÞOGKÃÊÕºjmoÖåsêِÅâe»'2"3•´¿ߖ}GHë"æÓ·˜jßa*’´`¥EHo·%ÞfÓm}u¿n;n5ÂoœãÌHŽ¤Š»}´Vìöi#©lŽdæ4çÔÌè…P»þ¦ÃÍ»rMºéF±Ó8è¹Juâõ2šY’– ‹ÓÐw+ݾ6}…ç¤ZV~†µDî~SÆñ š‡`ñ»PHG·?ï"Þ.èwK7RÜê°&8§ ‰iXyvæ ¶¾•',Ó;]˜£ZÁ~› ¿ff ¿Á ¦wh¦ ’’{ÌÑèÑIwŸ6å¥7­qÛV«Ý•ªÎ{«äìÊëº}ù•ËGǍF)́,ùª8ºTÁdküü£¶y{\ŽgnpuÄ93ΑÍݎÝqŸït­¤ˌËæX]pL›F †Ôkt4x i¯ìž¨Û6…P~o¦SªŽ~ÛC§¨ÛA"é,mRCøö>ÒËÎh Œ[ëLÛÿSÌnj…®Òö óù*¾Ù9¨Me6Ϊ½! ÖæÖp8òì®ÏvYæ-Ìq”™¶ãm Ott{>i¯Ï¦él©ÁPwt­R~$9ä+Ûë“Ã4÷5‘“Æ|“ \Rˆ‰Xì©þ&ó$Hc¤1úšz†¸î@¶9m‘'P»­û­JX¯KÌÍê@úªËœ•³rŸIÃQ¯ÃWÒe‡eËï¦}ZÖ苸iÓ]ôélHM¨{Q]RýLõ@©§ðNÅ}ŠÌAI‚°œ%&c‰(pzŸuVk¼”·Ž¦Ó¶œß;Ør‰Üq43Æñ’âøÌß}óÄþ~ìö^ÜÆ-êõy“­Ú:^vÊK¤e‰Êšæ»‡èd׺)’J­Ä©9íqµC¹BwÝ®MiJ®L¾ž•:9 ú™+ï‡d +͈ɖÚ…^ñûÀgÏÆ/KG+¸€Å“†Fԏmt«: ´öN¿Pz4å3-ªÙÌ +ᥧE ­]Ë?è3¥×Ù \q×.G­eÃÍ­'Õ\vÓ-ãϑcu¥ü÷†d.|oq­ÿ>ÙçÚön5`y½Q£tÂ-NØø¼†:ñ%Uláè¡ÐÃVƒîsâF|î´^ÈÜQ†.¥3‡Ã„É´Ú#Ã~‰RÌ éLW_G"ã‹Bï,ÖÓ7¬!R™ÅN ü .QgBȇÖf=ÚÔ»×]èö{ߦƒU½ð<ÓX®Þ´rÔßR~‹ïxJ=Œè[´HhÛ-aUøú½YŒ2«©9:ÛZ¦M>Ü ¿GûHԔ§ˆÇUÖ16Dú©ôm\¡Ò~~¯¥U:_‡Ÿ‡híúú\!÷V%èsÏì`ƒÚ§á °Ý{|·’ü2­ZŒN;ƼÈãc È·Œážc< Ï*Æ^dT¬ÇøL¹Ý9µ@†t}aÈ…Çðåíu‡ƒ¡û½õ]3ޏ[…HA{«?ìs•x@Wåü© ¡B]àÄ¢¡ +Îé†Óô|“‘ãùQ:gQ}ÍÖ\@›©6 %ºC bT&1†Ë÷# ³Â#F?“(·Ô‹4]-š:1ñ«2ÚÐ(šÔ{ßT´>j €ššV «ø#F÷'£”3'¯Ró·ùôQiú±™µ·Àó¶$Òfíòm¯û÷Lo=Ú§Íág amc˜ÙrðýKüp€/cħ…ä1ü`æ/0 ƒŠ±P³”À çñÿâ—ŒÑ `¼Óû81*[õ+`Ô©Mk%Þã$¹fÒó´}¸Zׂ¹Â×ú±¹ +ä¼\nlŽ+0€Ý Uí£ÿYy¦óûU”ª!ÑpÀ_¯',6ÉÑ·?G WÀ‰Ò3F9¸Üœ ñ€sZyÀUÓmÀåÝp*~]áBN—§¶âç¸ÜpX?~ˆçÇq3Þ²®Wd¢¼Sßˠ¯ü`ìñæB1^R_Øï^u&Wí亜å2ˆÎ¤Ó¤è[ç +xÖº¾ØºÞ=þÂíð{ ‰¡€¿×Y Àr.ñC ò¾¥¸þ6±“€  ¾Õîj; bÑioc•µ×BŠj`=sŸ=(oéŠuÌï2£@¬õÞMËè£ /Œ7Úy$Éå²X +žE-ôGóý~±þÇî›HÀö™b@ @\Ôt >7E ±BHÅõH%ë ¤†ÅØæ€Ôîû@r½Fí$-Aòì6jnüŒ/b³×dVFã«ú˜»[‰´¤1k¤î.±[õJ£••á¥Úçÿt"iÿ+<ÿ#b"ñ÷&ø¯ð›È­¿Âïûز®@ž_7@AF(lAŠFՀbCËO(íw(îf”Îø ϗóè{i½-|–ÖîvÉ©ýñ7ˆ¤\#3œÜ +peŸQÿ„/'Ýú˜øiú+7këêü#]â?™Âß$ߟh‡1êÐÝ Å·¹Á6¨@;š= ½¸ÐQ‚:–©Åx®€Ž‡) ºð× ›ˆ¦‰š˜f¿ ?!ILïoxC’}ûS:ìO(BRêì¤üdài¶ôøجócjóa®Ëݟ\kïpwۛ}~^n˜gÀW羯ä`Ô¹4±ü­n–5$ +oÜLR—+Q)=²ÿ2ÈÒILob@NªœÓ§jۇ¹ÌEwk«=nöQü\ׂ’¾’]»ìd‹¾0‹Žz]þ:ˆùqË8GùQñ,ͦÎÉG·íãÓy Žúž˜Æ\ír€<™ß[÷“ó“Ñð5'QI¤<×ÿå’M4ô¯Üý)¹»µÎÊ7{Ÿ/\×\»v©ßs”3ú§›¥ŽÏ²0;|jÔê`¨Ý>ä©Óñ¨ëëÏ-9¼¿7Ô^‹i|Í/ vå²²ô™\añl÷¿žÛ…~¥æó± +Y˜ËggŔšMDÞÄ%û£¡úŠÿ«—¨T¼_×Ì鵕Çé–WÀQ_‘™ƒ¹ã™=â’Òf§/”u¾Æ±•‡zÖÒ'åųѨ-ôS£5‹ÕÎêUý™õ¬ÅÑClâ­§Õtpœììõc¬_éq›ؤtØðÖµ&Cåñ¾'ÁA` `ðÞIªìWR-Ÿè âýSCÍâ£u;Õ-oåÚ|ЕÝ܌ +Ñ̺—^!6RRS2”2“FF!Çm‚aFQäG#ÉÃ[›×†Ê…ÿnWž]Óô‡]ŒõzgÃ~Þ.ý2ú8÷ÖUê‘ûƒ¯Þ–ý.sÉn½¶ ¯=þ~_%èHïþü©wïD‡>ù2Ý-xÐYE…ùW@Mꭅ Å+Mv…ì×(Ë6G%ô†>—ú Ÿ Æ*»é‡9üÐG¦xä—üîc öÝ«âÔÝÕ¸L·Ak¤wlå8*J'^s\_VÛÏÑ¥×6`vžHª¥àÞ‚ÖžÚ kRû×û—,V_žŽÏ"2Þ0CººÐw‘÷' X£†·ú|º×uKöË°žë‘+¾ØmJÕk³Ò7¸¹¹J×½õ˜¾ë+ʸý ”YÛÒ²5.HÛV>m›¡mߛȺe*ÀêëæQ¨í:O£ÖȚµê±¿UùOíáxMŽ±´lzXúEÜÌ9[zo7ìøó‰×s¦Ô3¯ïfŠ|¼í»ŒÌWwW¾}<þ0L¹7¯‹¶­FµÆfMh†ÅŠÒD–µ\£LÔ¬úº^+×Éc­VÛµÝV¹¸^µ-»ßxÃ*ÿˆ¿üž¾YUnãû©¢¦ñWÙÀdÔþ¬'Y;OÃv)lùÃRQR%äÊ1”ì/ö¨(-#¥äM)¥½ÚŸ #ªGKmà Ýâלä*·n|nRÜ®±°Çz•:\k î𮶥ìDþs¤WDWü\ėŸÓ([Ž‡gÍþ,ž¦Ç?%ڒµR‘‘:ÅEÛ ŠØ¥³´ªòáRØ$\h½¯™?N‰J¾]¤¶ùvãžÎ Eþb-eÛa¸. ÞÈoߜr›èÝ£mÓ%'€Ö”¼•ÂaZkô¡‘õªAÅ7òÓrP0–öØVw6•¿kÏR1[}37UĹ~ÆZŸg¤E™®°‡îr-¾Œ|ûLÙy¡Sl™]h<Ì݋ÏM®Ï9/ã5ºÑÆ0ß²ŒÝ_)¤”Š1#~±;ìwOá¤ý¾vƒ½¨ööÃn®Ó§t¶3PƒnNÕNޙT´zѳ ð²S\š%ÏÚ4jC‹zõç…fn²ÍŸ¶›s^d67ór¼¼M9—Jç)ÏiÍo¦ôŒ\»–3RÂÒÑ Ý—§Í‘ü\+-vW ­äqµrýäU—*1»•˜•8phr4+?ïÓQ?œvû+=¬wÅ­›ÿÉã%p© ÓÍ¥bpöWè*Í/תCt-ïn5³û´s{ÕÏiëÃÄQ煑j^·ú”OôÂG|hó¼øÑlØÎhè¬C©7—T"Jå•zV®+ ¼É-ßË)¾xÄ ±¢»a]¯÷»Ù’ßva£_nìɎ^õ*]F&ûw‘a­ù¨Âßü4#žWÕê)ÈËíÏg½ (J÷4ìHªiŠ/^í‰AT‰ [… l„ülwàòâg¼‘á‹Ÿ1Ï-ó‘ÁUh»Éá‡ë”ÝSi’¥Iü;biJ:Æ[«îR Fúº9ëSJ'ðÔ³ç¶3›n¥~ò[†3ä Ö.wß©Bä:û܇¢F::?4Nlä¤~viˆCÎ͉`4, hRàpÿµÄó¥Ì¾ËgÎðˆ[vØ9W1Ë{Ž€ü+»ÙÝ!¶Ö(–֍ِ*ÃU;#ú,sí>¶8-C›—ÑŽî ñZ×};ú¬y`˜ÏÖæ>»h ;ÃQà}‡µJwX­‹Åžé€O‘/mêD:J{§4c'©Ÿ[Ùk¯jŠ¹fWãg;QçQ–3¹Š+–8B,ÔØZ¯Ðbi«ë³tý2elfÍ4_ùˆá†~Üjåõ•íèiÈÔÕËTO“”‚žäcÝBÉA·T$=oM>nÊ'¥ú'(ö óž[n:)3èþ`ôÔ¹U)Dm©D[2š×RƒÈÈhB¨2Ÿ÷÷V„ôT·‰Ý1r]Zµ!-áû%uÝÂGª×3žäãéfÈÁâ%’z¥X$>âÇ'F·Þž€JLÑ·‰‡8û5YPùö"Ì%ô&F/ä=¨ ¹E·{©]‹ ý&CošÕgf[ª ØZ-¶”a·Ó«^ÑÊKÅÜ7HäXáíw_cŽà ÐQzªÑ’=5©v°)¥zøš,ȧœvÉÁƒë“ú¼{¸%ÆüëF˜& É„ÃC‹*àÈ1ð°…+m°²xLa84Õ1¾Ï°rañÂÝõúµŽ¶ô“δ=¿­Öãôý¤Uö])ÛñÌ݊e¦¶×§¶Õ‚­|¥¡8)"u®ºš´WÛ*äs¬gIÖ5â³oYĸ9rˆ<·jÐùÑÃÃ17Á‹ùÒÏP³ Vn^†ë¹ï†2týY(UZ™=-3cýa‡¦’aGÝI¦·ÌžoOõåƒBä÷’Œψ‚g:L[Jz +ߜ†ûƒº)ž‡(µ|Ï3{Gz_ÛtòéÑ¢E©Ñ¸ž]P¾èFi_€ +Iº„±XmëÈEúú3Þq¥#A¯™;lelùF$´Ö[g3ûçBÍ4ñҏ«`ߝÅșšˆ»µ{1V!"úè>}U t/sÀÓòJVà‡³©Áª8…ÞÍè +xŸFÂփÞîäk+øPêAs;·8˜®šM ›%u÷*¨Ä}OZ‰“™R’.¡o*ߥè"íæœcSzz6á +Ø­0 é´})}½xJº×çbÜì´b‘ ø‰˜=x°èL`½|ØB‚¸AfÏA H9凔5Ôl°HmÀË'€i00¯; V1º70?öožáæíŠ}Þ5Ü7¿¬š@%žãb§àTÍiÖ´æÉÁ³¹âñÆoÆîŠé2JŸÌ¯2ß+4V¿MäÅ2ÕX+Ðç/5òzY‡ g¥ŠùÀIeà],æHpŒŸÇœ.0pŒpB,ŸÇÿJŽ#€SU +ài§âYÇ`Ï}âĞ—w§kF­:ö>Ö“_;Ö¤8µwR¿_xêJÕX=–ªÒëI¸8wwŽÛ77ÔHP†xe—ifÎ4]J÷w¦§(—ByÏe|Ñ.ÆX'%ñbXã«- úc„‚¥e@d& Ðòàì#â~9´~}]¾+¥cÔ2®-.M¾›Žj¤ï*‹‰¿( js‡aä{±ÑÚÕ¦šÍ Á7˜àI?;¥a?˜1ÚzQD䪰N‹`þäi?‹€4 rŒøÏGv'Æ(¤pR”1&@Jcb2«¶˜z.I/R€Dœ¸û¯BçöQ†Äg[;köJ20ªù]ýôã9Z¨oÔÄÐQÔ·¬Šø>"Yø²”‘»&C¤O>œjßfRøp^Ô´^Ž1mª·uc\»]ÈZ£»ñºª™Cbl@µŒbŒ§¨ro¨Š…ʤó€Ê‚! èlPéãù­óÈü:h/eëQ±{§&êÍ{jϖ%y¨œ•^³o¬¥¤ŽÈ „,`‹1F`Û¯y€As߈Ò÷¨ÒôÛ b̦1ös@À&Qn1#Š1€Áq*†§&…ÔbŒÆ€¾å®€¾Ó, ÷wÐóEü?‡üs;Æ£^à¸ZøȟÒy~;æ­z7Ô"Iò²Öyoóü£÷µ(Ra'°ãpÿFïp†‹&öµã“x¦“§;]cö_ÈÏcxÛ‹SŒè +Ø)ùŽQÎv €ÝYVŒk°³Ú°sö“•@lpŒŸv§GÀ: °ù™ Ø5ùÉÀ`*ƒGÁ|g·úqÿËùIèò§J¡D2Ï,ÎÁCîF¹ÕõÝxwbN€ÏèQbíþ‰̶€W×)À— ðM|ª~.:16àå#à‡™LŒ[ð£ÃðÞä øîL|ý8|Q?VȽô5ŽYFþ{c¸RÀË „æ>Ó¤§ÙA?J"2ò9 Z=¬Ô¹y·}z|€g ?‚ï/~'þ#‹Øù»o ˆ†¬±Ý·€¸¤Ú1ÂÏöˆñ7ˆŸ·ÄËi Äí&Ä]¿î‘Úñ0‚ŠêÂyåjEê ¼«©¹È`¡Ï˜‹R o3ßذΞ‡ªÝ$¸ùO¾­ÿhΉÏø§¨ö7[8 vHdÖÄî› ÿz~Ílñ§˜œŒ)C ëאNȕœäŽÐM<·c&ò„€¼%â—îÀÈ3@›•Õâ¦ZÍ­¸S” k˜T—`;£x¶¯*Ts]áŸ}Jzòmÿ×Úûã/Ž‘èÐÿN—@šÒÍ71ù&ÕÛÜáh¨ú÷⁦/ •{3 ¹h£nhãÆhå´-Dÿ hͤþç7_ ~“8‡Hý[å,ÉoH²oÝÃߒl‰«·B>õY{|JÝìÃ\uµäLò÷ÜØw¤±©Þì½}Ã:À¿®%á»`¿’~~s©¿¼kt̽Ш EvÄÏzãß²f?.ÙoÜ@2h¨ÿù4‘¥¿%ärŒõÞ¤ÎAâ ^fw¤6__×|o%½ÑåR¿ÑQ}"~4†Ï4FÏR¸¦N~fÍŸ•]ö¨o#ã0fžÅäbõ½uÕýýl-¶ääüÜ쬳þvû jøêÐß(„¤ƒ?Iߺ\ÿgWõ ž¹[«%vÃæ²'ò…é +gLÊǧݬ>՚»¹\o·ÄÁv­£Í.—úž´ 3yÏ×íô{½Šì÷~%mRÑÒ§ÑçâÙâá…™ä|œmI³PågȘè„å4|®í>õãàýæ!$ +obM2þe䍛ùÑP2±;ùÐüxñ…iK-Ù~ÖGóžYI˱T¶3n¡‡ÒܼtÕY(ws3dеBûãÚÓuÞ­Nəۜ4P·3aV³`Ü&7á(jÜ¿zÃ[¾•› úËý–Ë×ãœßýV óvI’d½c—Úüɔ€ýç•lWö?ª}¾¸k~J·Ïêԝ›çzo†øö(ĆÎw}3‰¯Û»ñ±lžGQM¿o-þ5T"!Y ô»ŠƚJ ‘Ê÷C³(÷‘°løåL»Ô[Wƍ¹=ú]æø™ymQ?{üõ‰w¤×¶êÞFµÐõÍRRfG…´é[v\^‰ZžèШVö×mð¨,ò“ íg&¾V̆jâ’*'Í|z¢3€±Õ×]›ÓA¯ŠqÓî®Ê-ºÌž^{mŽþ`<þ,ž;ž$Þܛ/¾\å¥@í gá­Ï´ÎµòÈTo†åG¥‰lÅn£Ì WõµÛ%êU©h×ɛßü‡K¶¡㵈œZï‘î-}Lÿ5ü?¾ÎsQU¥ÍÖWÐQ’sF@EEQÌ9ç¬÷9÷·Vïî>•É”Rª£ÆË|³†þy]¤;LCX4Ïõð6½°©ðP5…æ9ÐÕÆ­¥fÚÃ,™êԇñp¼MÕzÍÆ¥f ]šß¡õ~u囓ªÇ{«Ê¶*ÜuøðíøwÃ,àÊ·±ž)G…•ï<¥…cÒªôÙ^Ía?ì}F‹{•ò'ej’\ŠE¡Å­Cã_‰›¡Hžã×îZ·R­GÍFÛßsšïM¬ê±Uª²­×ù +wn*^ŸaÝs§nºÊ»ž/ßíRY‡ÚžÓ³»õÒg1‹JÃòc\œøȦˆ»=oŒq›¸á邧wªú=<æ·C‹Œ|­½yßrØäÅ긃;Óâ®î åµdvÇܛoW–+¸y…qoùi-ÇՕ§+¾@Ì<ñúY—o½í®¬ƒóÅ1‘í£4,m?%‹¸#ʼnw'Šèîþ5ŽÙó:,ÚÄV «7 ô]µó¾aW­Ã l[´æÂ"}Ê©xÍF‘Îê,Սñºfu.›ÏCJ0TíQ}K»½aËEôh/6o|øÝ7AŽ°.þ2ÅÎ+5úÓvUœžÕJ^ ‹è6Û±¾8*xrvV ¯åuÞ×*ëÐ+Ÿ­Àl1&#ûbØùi`Ü¡¤/°ÇJ_×L`´Ñ­tœÛÅjI³½Òrˆû«s­ˆ¥Ç¢Ü•‡íRÞëWl²ºtòÛK¦hõdì™;”zNõríl´+ô͗áNÌÞ»¹4ÛÝeFô윁ýåØêÈÀ©/܂¤“ÛvV«èªÆ¼ËÃônNi©`êñaÔZ_¨#òHð•TO<ûû{6êZ·j{ ÍÎy“®«UåOêÓսǺTx†Âf —­Æ%ce;ÍaÖÌòv.3êNI…U£X6õÅaéå`;Ô)ó3×*£Ï·­±ú˜®ÍÅ{Z|X=IsF•[Ï´Òzj%%=ßwäG£¼“ë–ÞÑ:'½§Ÿ™ôžU/ ä Ò¾/ËwÔ->nµV³|,6rêF¯QÏ!ë]sæ÷BàŒ:×­½–¢~^‚²ÕlwúÉd>¦êåý(­m2 Sc‡ëBºïÊiaúª©MUùÌt•k¨•¶ê,åÇ4<ÈÝâê!g •¡%H9ue‰ã™òý ˆ…Òr.¢Rù-Ì®iM(Mì0‡‰Ó ŒÉ&êÐâ¡F©‹ M¦z"Îín‹P©ø¾î µÑp”ëðF̈́>PNw×9]÷ IUä;`WÚM\W4E¶äî$ëÈ»\•>X«)åýŽÉ»±8¾•X˜ègµ[@(´@ ¬ ïAó*Oï +n[{ß9?³—9? w9¿¼:rÛþößËZŽ_v"n¸ š½ê±\wŠ§lU’¶Rù3i Ew˜:å›éÉ$ñò (¤©¨Dü›—3›± ¹±"AÁÌm°±Dtt- óRTh +Ä¡øíÙð« 3ã°ÞqÛ óäüjçxí•fƒ¾í²’ ™ Ý>3áÝåµÛj1áÓÞ1-8$èú³n;ðÎÍ&Ðî^Í{_­Ÿ +qV4"ìíPþÞ^µÚíÜ7j-}È%õÒÝ)2—¬h;9Vp*"/lFá½zÎàѵ¸ígPæüá¦Æñ•T›=²òˆ  +u×W¦ER£®}o“%ZF_¹›z-´#Õw!šê‡Ù&õºð[êµæw´Aêû®C{­p·j6àù¥âï–ï‚שTgêïh›óÏÜsÿ\eær§£íwWy8@—àëŒá×y‚ævÆ9ñÜòƒÏ6 ³ÂJ“Á\jbi 9—Qßí}_î{tÇÃç´¡–OÔë¾IQý™!P)b”'G+"ó­çŽ˜¡C‚˜a׉K2?;rô€w¯=øz9Â{çÐ +ŠÁË÷…)zƘ0\¿°…㪠r ôÙdHjÑOŸk¥ªü!ISÄÇ–Œ-Á\nÉ´¢ˆ¥ï¯H¤;ý¹Få[ŽzÓh‰êß25*Õ¿(*eï§ä§ödþT{3eO%¸œ#ðâ®­qêb¡8umWpW©Ìñes±%ðÓqí´Á ùÆ·íú2 ׫§¡\vUÎ,¹,äáÎæMúidTR—Q:ÜÍòÐq +‚»Å%¶YüPt—· j «•½Z<•*9. M²€nm9¢UbÖPB¢”mŽðåx¶Æ]Ÿ}à4ß&±Í[01.7 +Ðl~çx õ= £õCÎE|z†qvm“ }œw‡Íì)¾VÓÙ¨*žá¹P!c•hC’óíðŠ™3I;é{ˆœ©÷Ý£-ÃÁ¤Ìo·Fš‰D”¦ YÂITþƒBbödX‚0_]ÃݵoáteXƶég«>ãÑ2׫.уs½¡•ÃQñú0sÔ¨#¡Á/¿§•$Šˆ +®#$Ìf7ȹ_Þ¶®R{ÔžßóV½òa%²Êþ¯íø¤ªÖ³‚f)hßõzÎY«ÆžíI¸´­pǨ’¡{š!1Ê"qú³Æ±ípGa¾uç1žeÒèa¯gÑ î•PI֐óçó=np¤Íµ2¾ jUÁàè0HÃzC®@¯ì} +™ÿ ™ÓÀ€úH» ½4vëíô6|¬»“`®|þacFÞKm?žã`i떙˜Ì*ؼµ +¾½N"ð¾°im}¶õªd©Ñ*#àë±I ÇpG ÒnJ!-aÄƸ+ˆúaLø>4‹pNJ¯N¼Š ×ž›CY±p„Ày ¥òiQLÁŠf¶pðJT<õ’@Ñ¢[1ºs0 —«¤àb|DÐc_Ú}ì:ÍÛñee-0ª‰¦Ai]÷öÒÜǼ؝Ä=¹–' 8'cuÍ"‘6s$á.>úúl ]c ì¶/A)­§Æ\H!Ƴœ|>…v1Bð'ÆØ;Ÿ·†_Xw€TàÃR7Æu ð²oÂì~Ugî™y5]¿Áfn~ºh—*ϓ_hã7û']¢Q9@Ê(kD¦ƒŒÙè“;3›¡,¥»™ ,-9éÈˍ÷÷ž4=Ú C¢âTô²lšð«·’!xfɀœìD@FX¡Z€¬yåóu¢£¾Žñ~2¨’€là@–Gu@ºÞ +–2O}6€Ô² @r—' yÔ\8%^îpXü؎UðnæÐE`ë!ÿ–”Â΃…ú…<3n3#ÝfØƚ•Š‡dèA*Ȑ¨³©Ä2€ZEÉf¨ÕÜÔpëj„Öbä¢ã) ÆÔPí:T”âbtò€ê˜ñ_ëÐP¥ (³[”|ÜJi¡€¢Gd­~a/ñ®<Çþ™ù +ó 4hdü™O›ã™$1®Ž°/ãr¡œV{ŽKº×Az³N²íøP`84÷ ”³cäÜUÐÏzýׂü|ý2V1¦7@Ÿ(4Ñ¡O#Ðgµ èÕyèõøè±+:Š t-ŒW-é 3žâ«ã‘ÔÝûËsLb]ë즖\åD>݇Q·[¼±Ê-·ìoäCÅa?üހõÿFùZ¬‹7b¤£ù^ŒÚ(ÆtX>Æp>€µŽ `ó¶ãS¬߬î¦~㏠¬X %’*så ÀlÜbÕÈ7[ÜnîöÕ³W¹’„ôôë¡WUJ‘‘”æG¤çD ÆϚ|A>Em •žþp»Ý·èÜ¥xø5øAòò0Jtè?<âlc„Ç«;à9‹1‘Ïk%Àc›ðxm¸Oš<à‹€»|F€ÛB0বcÚñÆ_K»¨qg«0žÎŒsӍT;C~oEdi2öØâi€@ÈH}\ÿ 8þ:Ž³±sÞþ +¿ÿ1x¡]cTß@8Î ¼Qˆx;D‚M¼ê"±ž‘ôî@LI!ÚÂ=µÂa€p0[IÎÄWxå-ÁÞeŽ5Nãm(623}:!wF4š +ÆPjÓ\Þÿe7þ¯ÿDL$šïüäL|=¿‰œä ‡¹¯ú»äÿ ®Ù@–ÉVŒø˹²ª@N 9òdŽ;–‚ØIb‘½Ìðs5kÒh¥¥øê@v|À¬M4ז‚Lx™JùbúÝt²Õ¯Üü£õþX‹¿âê¿Ó%~Ӆñá71ÙBñþUÝù·Žœ8êðzêzÌõÚp@òg@½;P÷…PF¼Ê±Œf+‘~Ô2—ĶËYh§FJ<šCá\RÖ-UcôÿH9NäÞ?ÖÞ$X"A"ü&Nß?Åäþ¾ÿ)ݦ§ð Ðë3ÐÅÄ௯xè¨ ð8ƒz«Ç½ÀP;`¤Côj’‰µ7 X©ÿ”8KÂ’ìÛâúÇÕû›ˆ°‡Iuñ&îêÍÜÑê[¸Íy\½•ŽB溒ëê^³Îe«ý ׫„çt§s~·:)sþqŒÈ»rÔ6«ÆŸÄÛDHýqÉ~«p%êý·|¿‘ÈÒÿ3c±ü€®~›³ttuÏÐàÂE·é¹þz®Naê°=Þ +‡ãQ›®‡§ó|2ë;ØÙ;²‡ê¯owp‡†wn[zÀꆼ̵3Î*ÀÍæ2¤çËE$„d"î&¡IPφª\Ûèo)®ÿÙÎûGS+žM]ªWKĽ{¼YùYnŒ=䏭méZ-®·¦è¬yÂ[‰3¢¶ ¢¹¸yh{¡íÐÞ¼' £Ù§‰Îf¹½™NtåÏêxwcöÜöÞ4éÙ53ô—¯ŒÅ?ãF4QÚ@oŠ¢;z5¯¯GCórÙ©Æ@Ç[z;mñi¿4 Ó¾“YÅpwižÌmÇ\³Tí »z¡½K±_ÏmS÷?ôO`×.ÆG@ôKcââÛåìÆÊóÖ-ÞAGÏF¶”1{eÆÊ|6L1cq¼gL¾fؒÚ4ЋÕѝ´5Љ‡?Ó¼L°NoWÃSÚ÷nßYxêáÁjÐ åBs¦KӼͦŒÒAt„»)Z[>Dª§VJTæõÈOwu!‡ÎÓ ?‹kû«šxz” ã֟AxH•Ÿ ÞÖ4÷E0Li>z€B€µ÷¹ø˜dŠ“¯ÕaVé0iN‚QâÝ·øæ¸öùÍ֟Ç+ö^‚Å(þ{Y£oU=MGZ`ÑÚsîRÏÔ¤zå̐2åñ–û&-»Í‘0λ9LuŽø U+4›„=~‰É-õSÅ°ù‚ÈJ}‘΋Ù}ô¯e¤D¶q8~ÍNÙ¡jŽ ·ûÒMy˜—û»¼(bsáü¥öa ÷¤o—èCëéDõº-,Ǝ¥LV(@òrxñJ¤ÕšÔI¸õû[X0ûNÃÙ “ãM[ÛÅ«ücˆU$-ÀÖÁl€“‡ý°}X}¦¹åý:ùȖ*—WÉ,V–X\ÓX¾Å¿oY˜ñfú6 Bõ&ŸKrN]hBùà~{lÃUÞ´¾ö”9ӟäˆP?$fbª–I¾·x¢ßu›‘y|Qwª8ùFØzø™a•JõŠ±ì‡@w‡¶‰ÖúFˆ +Ù×iLv *T¸­Úß{òؖZh»1ŠÔz­2+–+éE5÷k;nIëSO³GKÝ?”»jÔ+ÒD}™ü&>N™kÓT¶½ˆéŠ|8¿ðŎ…pJplýÎÍ°XeÐP06·È¢{scx-´v?LQ¡«‘&1ǐ&éfùJ5àk{½†Ûz‡¯C‘õ!"ïÝA+@Q±Í†¿¯W<ïq~<ÇûMÿ»Ëx§?™%¼ÝjÇC¨ê§z Ù#Ëæ¹çC¢Ÿ¹! ùÞ §¶÷;VÅÖŒ=>ºoâZWäø»¹å%ä4é›HÓ¾8ˆ"¨Í“ |ýp'X³’ûžÐá4¨»ß×R)?K}dN}§e<´uWÚ ìì‰nPâíÐKßË,6%§ô¹™¶Øžò¹P‡3n»uÜk¦ôO³–H>ô"{1 +  É·(*á°ÃzÐ/wä,Hóºø Jû„ JDÑðÍÎËp„µLX;^ÊPOÁPæfSC{¾KY¸šw"t§”㏘Ǹ|z„ó1z!°±óW‡þ͸^8íj˜Yî°ÿpK« jÂö]ÎYøKÒ%Ò7Œ\ÊeñûŒî0Ñ#MNý…3³5@¥ÿ†£ñô½Ðþêöh<î>Q©áùžRV[ÖÁä™/{>­¬ ÷b„[€¹ ˆ±•浫«dg+°)€ÙV)Ƴ°¢8nŒ?Ü°¶]Ä}ú{æÕrá&^-1kÑÎß},ƒëÈwàaðéêS5Á})®øfÄ5‡ºK縔A¸ØCOâFÒÅ"e ×T +!»)€³U8ƘŒñÎ¥ÀyЈác<ࢨ%:´øNŽV§ZÀ¡yàp)^î.ƒùP›ÔøÅaT1$²“ØŽ‹µu©œïlm3‹8§µÄÌSž"»•Àgë]¦Wc­»U+ÇÛ9cous/q}­¹4WèQS«â;ëm¡jû£ÀfKgS˜Ò"©WèøôÙà‰µ„‹¸‰¯Kï$ó>~ ê1ž@| +›§ A5þ4W¼ãØÄ6ºbêð€èâÔ+tîµ½5ÞV7hñë9΍º…ˆíÖ²D˜Úª2òì}ûi|³VÛ0©‹6 ªÜ«†¶ñS`œ‘*Î,Pî‹”…I€Rùt Ýceÿ¸… ­î$Æõ(ԅ…¥d@¾:e@¾íq¢CŸ¹¸ù« +ÈqzÈ~ÒOÃ?ߺ{?QÇÁdÔ·`†®AØ2Tˤi‘çæoæs3¶¤'|˜r9ð'DÊ)'%æ=[ å¶>‰_ÔÏÿ¸ԉ!Vm1Æ}@gñUŒÆÐJŠˆÑ‰ÿCUk€f>K@#«¸ùÏnü ë – 41'‰çø¿þ‰:NlÇljè¦ûMA—*Å-ÍiçMQà½ÅZö|ˆd9ÐN• ¤ +ØT·ü’+smÇÏ6ãjŒS#Æ»˜-ۋQœ&Êív}Ì. 3r€™™ùŸ6`z³ø& ·¿‘嬓Žø$ô¸Ò¯ ÏòâåžítžeË÷z¨=ZdIv¥qš{u’ZN.Oìzî~Sâ‘\v5MÑÌ4œQi®Øh®Ö‰~‘¼ü £^Œãp%x¸º¾‹Ý`xŒ( ¸2çÅ؏—‹¿fΪ(‰@œ6Àq™à°® Ø·Pwgò**Äd—›ò#ý¦ÝŁZ6[)*í”v®jåb՚°#½Ù¯¿xdÇÏ.ÁâWõýßÍüµ$‰ŸøÁíY|!ëC@(x ¸Õ<ªc¯RiÁ@(xñ2ÛÁȾ ŽÊñÿÚ£’XÍ\­I^çÓà{!P±’î --•§m_ÄÓ +Ž ùŠðµ#ºÿÍ6~)§_Í×oßM¾žýDL̞?Æß¿”`†C’táÄs¾5 µ*e µÉ~ŒíHQÄ©S—uk+ õ*¾ $·»Ï[Åà9æ³³4|y¶E¹Ñ÷˜®™x»¶ãBpÅþ¶3ÐOÄD¢4ÿINÄÕ¥Kü+[81Ù&Á¾…F([Þ*4  ++  ²jú¤U[ÄËøIC­ +s¨â Téø0kÎn£¥ìîH;d k¼L(—@Cl»ÂýJÐìÆ´Þ?é_kñê›º›‰ô›læðû/Í7 vHü½×ô +è©ÅèJ‹ºå¸@¯@o0 GÅÐkúèuæ‘Mÿ±öþ©r†æþ[~ƒ<{f&ùÝ?¡éûmΥ߷ҡ_WR¿Æú²M»ü…ëV•sýSÕOg«iBxéoÅk㨭¨o¯óÐcÊÛýP¸Â»‰º°o‚¤jØOÒÀ7I6‘(ÿ™7‘¥Cþñɇê}BÙ[i痮tÓ©žë/õë:…)):F(Ó?ôHl¼ÿTàÙ>·‡W»‰¶Û¹r9lVúú¼¡û»Çš/>«=aËs9Å-nUJ[h‡biž¹LÛ³Ü3zN'YUŠa§'Äì(&­ûÊv‰†úŸj\×6ƒ£ç¨®O®Õ¸ŸšŸôóð,ÒÐþãrä Îìz›ñ…U[Ê2Äu}Ѽ9ïñ˜5û4°â,w…Ë3¨M~ƒ›§…'Læ&Ӟ#¾?ö}6ږœÝðàù·¡¸[£åü#uRí=»ãc…ØxÿrÉ~3þ +Cøª“§³1ž'%ÃâÍlÜÛ1Z‰ãbg‘lžÙãÓÔ|¯&¥×f?öRËËÈGgÏa@v?ƒs¥”}„õoõ!Õ×ÎC®×S{b/s_iÝÜ{bv&¹•ÝA'·jäàtÔ^¹…ï=é6½Ÿ[܉&Â@üŸ„o™°ÆmP›þ¸d-rÐý©möõò&IÿMCµô±°ì0Àûف²mØ}íØðz™k#èB½â×yß±A¥9H~Ô^•ò³¶GTÖ­­WÞµ¸]ñBþŠ§Ú«*õTãu‰†öšñA/û0êC/Õ¡E1¬ÙÔnáÏýî;ÂÄ­®šÛ ê)“zb7ãú¼ïdjèÐIY³Ôð´DCýã’í ƒ9Ñ^Ù!Ýò)‡ÎVš¡d(mZÁ³kƒÌÇtëCËôëÐTj“¢Õª¡K«›¸TikX]ùÖ´JuŗówhÏ?žøŠû5aÖÔÊQ!*;υ2vz®K%á±¹d-~l$ML¼¼“Òã. Îå%Þ˜¯ŸÄ%›ÈÝksßTÎàôôѹn¥j·šVÞ¾CºpÕc xe[/1î\¼@-Èî¹SÐÜð[±ç6(Ye*žízŽ‰u¥ayÖ-Nª›i="ۑ ß3taÕ^òOÏóہ·Íû–JäyØdþ`y®lœ‰SÕµš½R]h×}µéy°ÿUxŸA U‡UáFÞ¡q»¡6œ•#³·vzùęRúÌÂsÉ"Â{ Z ?E›éCö¼ÖÇlG˜R…UsÊèÛBÎÇ=O#ϽAÁ +r|5wž8œŠÍ—ÙÈ¥æs1f¯VõLSlLSB@æs¾’gñffð.SÊê1Ýͺµ»•>ûL=Ôaéï4wxLVÊQf]+}¦åZqâʁíðHXX5N~ÛzòÜã=±=|iIÙäÎ#ö˜S꒽Íäï,¼¬Nh)³çåðÌgçrKh§3ÐéQ4l5ÝÔçþLw2ÒC'>/I[é®æf‡Ëc‚qåz¶{ƒf+ÝÞì t³ÝPA½½ÕÊ~3q/‹è;³Ø1-!_´©f¶àI\.ÏÝϹÜy0)do“¨”Õ±È3{娖ùl¢ffXt2ÐaØ7&Ájb —ÕBŸ·n;x|.šgïôv¤bi?IêavË«ã~§c+çõi¡„Õ&PT~TTTÁÈ·S4‹ŸMæC%þ uæ~MÏ«  Û*ì{Øëì)^wê 4«YÄ ¹”¯O5º¤`>çS!3¬TDcRÏ+zÎgz鎚Ïj«N¾ Ñïl)½”+i?×ÔäÑR{ÔW΋ÅTQ©ãF¾m™›¬óEDê5¦¢d*jQüÜV‘h™heª’ƒ´£ßMÐ7Óþw|1¢Ñ쨡ŽÍ%´ŕ[¹7,ŠsÓj8wrmø¬™)tÍX!µÕ¶Ž¥·}ScšT%”f•Ð!E%EU¾] +¦¬§ y酴]É,u¿é<OqcÂ÷H„óÙ­`ÏZ~!¥(Þ¹4Lžl“WA'KŽYD8ǜÇ|ҝ=¸î”ZÇkÑld;©F6鵶ØÓÕöÛ[;]+´©¯-ÁüÃ(‘}FcÝ%ª\֟”|¯÷€ôòœ”dÆ£n t"ZÌã=^„—sE(Òs]ÀnÏ<¿èÐ.O¾Å:·^Ö{KçìîÎ^YÁ¨c̉` Fö:_[}eÕÝ:0îÓ6Ýz-[ôU?µ;‹•å„×j9Œªš‰s[”f™Ô¡PkEÃIJ™,?9nMyµi»)Ù؏_"¢?oB±qˆ¿˜ë6RÚâ6 ¸Ê‚dÙ=EŠlm£j¬Pu,¦ñŒ\Fîšt;…éô¦¾§>QÆ«©ïë‘9h4"SÓNŠÌ±›Ìq™9¨–šÑƲÝæãYü†j×KK7]G[þØY¨Dˆì9jm§¼¼Ÿ¿ÈŠv¬#D”®¼K…GŽë'¶NJæT‘L“ÍúZÏ"t[,“tú3©Çð¨SÝ<ö½éEeX§Fê½.™3‰51¹O¢P€8|vèñR#Ýà …yâ„eåðÒðYÇgçO½½ßY^33¯j«f]¯„•€/[z-z„qË+•ç"›Z4Zåe¾÷Ò2 +Òrïµ!…yX}pÕMxdf½¥5¡³£§Ñ‰Ê(ý+ù¾­ßä`òFÈ\‘¥IH(ÊÄøÔÏ…ÁË%PKoá¥]o†uú†¹Ÿ!Ñ£LÝæߛ^¨Ïo¨/Àt[›Ô0z·­·ÅšUùÉê`ríŒwOGb¶û„½ý”ŸVT Öfa±èêUËõÔ6*e¤QÿÊd8þ°A;:RÏÚhC!cMB¶ü……p ÐFñ£ ðyöDà„ð8±ÍØÊï—0úuo Û9F}÷|AyÆ#‘󐠻i#’Ù9#Rv­!Á ¬!‡÷°ÞRÞfõ'«£F¾]õÛq‘ŸRvMKoçö™yÿ2ÐÖ ¦O_ZÔ·RZç{ã²ÍÑ݉ˆY >`lCÞ 'ä´AäÌ,ÑäÒû _Iê ·ÖN·š4ôHoȘ#Vêíä«©ìeÚK¥ÚüäŸý@úº +äÇ8­2ŠŠÈhQHøÍä4~²:®wÄq!MùzKtQWò7’%s©ëûeTñh“¾J¡’‚ +PÁï«VÚeñŒ»gòŒÖûå=|=¤öÐcµÜCfvJ½ï×GjÐ% TêÃ`¼ªJeº€²xR7 +MwºÕ⦢Ú¨é5 + €Šl¼LÊÇë˘ PÊj6ò·°UãÒÇzEÛ ÞçØ7-™E6[¸‰)ƒ+ގiMZL¥™žiðBîø½…G¿öm‰ÄŠùCýŽ„ÑzÎåsʂ—G`ãí@—ã{Œg + +ŠÑ–zAò1*µ¯!@¯Á 7‹ñÌt7ht_‹—‰¤Š.œxÕŪ”ü(ò ½S«ÿ؎B˜±^fGÌbJӃ}U†lk*Ò2Ý`Ûö¢@åÏU¯ll•Uç wʗG*O7€MW€uÞI¼!Öe?1JXŒ°¢Ç(—b›ë[Ó·xýAH,Ôòká=€UŽñ2Ÿ4fZ‰"]÷ôU¿zÑôŽ¦†C¡3ÏnÔÎß/Íê÷îi“Ü6‰ô=÷¼Jó•1á%äÓ¤?i‘X1õ4zzZüص (µy½¾®¼>j€·ÚPŒðʉx••cÔr1.€ûf'Æ6IÅk¹'À‹Oख़p³2x֌ßH +grƒãUm§ƕûÓîÿxŽ«è£fË­œË_Žš!”5\Maó«°ë°SV?B +«öìð.|÷ õB²„Q|ý<\>€X¤`@ô)<†L¢‘fQÎ 1úñÁW~ـp­zŒí^fk›DޕQ«€ÐÁüþŒ›ý¹.¤OþIPÞ{ŽÛq‰ó³­Ÿ¢v´XQӏý“–U絩ë”Fjþ»Õh:W5áʀ‚úäÈۈävÍrr” r¢Ü&.䟋á»1Î-@Ös³û ÈrÊdvÚd.ÜRµãwcÝ + ÑÖ1‰Â¨¶™µóy™x˜;,³­zŒŠzhüÌ&²áÄ5sa `<#ª[»…¶÷y†x×tÆW-:Ê/+nùÇVuö¿~ä^.Ƽ¨ÕÁԚ®Ç¨÷5º®5.ǾIŠMŒÊ“þ׀luUç.€*}x@e‘ õ™x+¦âî]»mJþGšZ#±ÛÈðs¦ Ž´$Ö aÍÓîB2ÝÂ í¤˜6l ³>`ªZ!A¢Ü¶sö˜ÿ…&Æ/µB9F3^Ÿë16mÀðÂ4F灅ƒdÀ– ’<>qÿf£z»îº £Ièñ÷ê9ÊÍ.ÎzýÙŒlm`Vú?ý6Z9©òàöÝZÀä&kœâß/4ƒóO¾Ø%UìIûN7þF²ìßÈo}Ǐoñ»é䟺wÎ#Ƌì%4»á¾ÕîkÀN68`;#°õ(^ى¿\6;v\Üßì6£/³ËpßÑ5Ó¯Èî1¹§Ýã(–¿z¦÷GØN›ÿ1‘<ûßð;aÏ?šì¿þÜ¿±àð[·øûÕl?=ž?[ €Ÿ¯ê€ïv€o^UÀ{—vQɹ9Z›è·ˆÇ=–ùè\Ò©uæEc­ÿ‹Âàü«+›ÛÍßíÁ÷ÿ1¡»×_ðxòxw¹§ ñ5@B¥90bœ á§.?»'/Çx•-1³&Mþ;ëÛ¸à›ŠÍü@hµå"]ÞÌU¬KË8\bÏߎãDiNDæ?éI ÃŸ`‰?úïé·tbñõ•ëd€bcåQ(µÂ(uŽJ€”€Ò€ç@ib8PB4~Yaיc«²H#2×åãÑgJµf×âô“rücwö8Ñ¡Çq²õÄqüGdN\Å„ßKüGðýF<ü§„Ð҃>Ð +ìhí ´É:É Öv“hÙh‡™´~§ ´þ?äÓ$«7©rv3þ o7ŸÂ²ÿ€œåô6g»ËQì®îy|¾lÕÁw²ß…ë ^çú»Nç\9)“q¼Ù+î¨-Ê¡G=ÍýÇ'J{¨ÁÕvh»Ðßx ¹[ûhUüÉCøOâm7ðã’ý兩þmí%¡ÇÁÈ{aygo„”/[ymœÅ^?¼åΡG+ûÜN®í +'¶¹-ÝR­ ÝÛDk,{«C~9Z‰³ÙtËÕâæíãþÆîúý4óžH@³Ü%§#§NÑÁ̙ÓÚbìyAšžA-ÿ§~›žCÊ{0žÓSÁù¸P\ù[?LÊ1?èGrcÙëiÓK÷ÓÇÑ®•e:{5MöÕ:¿‰Èû#¤þÇ(›h¨I 5ÉCXžó×ʼÇTýÔ듹N´ÆøôFÜì<Æ;k1PvÛm_;M½ž2‰· ¿¨îPŸ¿»PšêØ©)Í S2"æ ®½rîjk[ye[܁wÃ@rZÍ0ݛ6n=úÞÐSœô +nR5,‰@øã’ý­fŒç» k~ÏÐÿÒP‡âR–úÚa/w?­Aº uÙ:ìÚíU±î¶ée³Öâ¶n# x7È4JÝf(×G[»:mhOw<{Ím`‚ö©>Ìuh¶úzÕkèêLûK§««º[ªÒçSTá•“wè /Èb®'Wù/—ì×½ÞêùêOZÑ݉‰ +endstream endobj 22 0 obj <>stream +†ÚªãW4Ï)ÏÖÖ9¿Ã€¦rn|-# í^#ëŸAž­[Pñ›)[L×ÐE1ã;TѪ®ªy»êqåre+îR¬{AºÜrÏÝZßU>Y9²Ö{ç9ƒ_¥Ï*M–†ÞÂ(A{3(ÚRõ•„Ç~]ª_{ìˆÇSJZ™xyGÜT {πNu +o햸d·feZÿô…eÍFN+ŸX 6•m­º¯p§úÅoîà u”o})ë)wz‡JÔA4àKCǗJÐÚO'•x î‡¶íˆ«JaÞÂýàÆyîS:Xµ…, )©¹Ð1Ú9•²ß‰76{Û´ÐItðÈWË\Ï$ÑTDŒߒ¡¸»,ƒžŽ ãfÚUz;=ñjµÊ‘ ZŽ ï:% Ÿö‹6ÝÛs¿?·‰c]X5‡}žóÛöúžçžë·˜›¸àŠçÂü›ÍÞ渒ÕIù;`7{•Š—ùìםŒ%ñë tYcÒ ÃÖ73}·ú| \'ä80û†ÂòQ¹x†›—uï¿8÷‰z‡㕣L±P²°‡mÏ«ÝbÁ“ +ߑtÞOk®d¸jî<䂜 +s­lTäºYW†fÏ'¦Ig–™¡ŸÙf cîdLՇ^#Hw´9¥­zUcR™bz;Þ´Ó<–^«‡ÅQ/î0HÌíf¢J,´J0”[˜ÑEæW¾%B$dì‹_¾ + ¯=#çU_¸ÅIÙÕ +ž¸•­ÀðԜ +ñªùœßәÏzgd ýÈ4lq”7ÐóÚÑuáéÄýøMÓ<ãjôûÕMû¹×0ÍÃÌB Šê^9/í»¢ÒD¾í`IÖ¯(=ÏPGꅃƒd¦g²øyv1^ƒýŒq4"ºµšÚ«‡ÕÑ¡ÿ¨8ù« ”»s|`Z^å\3w1tÎì9YF²È¼~Õ÷ŠºPޑóĸOZïµM ZŽqšT¼¢•^¥D‘þÍêXÕ|wØ8•<LjT-³’fMÇæ -¤£½‰ì×5$pÈ°Ê<ÊY“œÞQÛÍ.Ò2À ê£òØÓî`F{0¡{>8Ç8=FpHŒ*㤌4œë6À(sãù4”W“yÒèC^ô™¥z´«‰"]ó)³]¹»æ¯íø¢ ­œ“±Àº%e¼—ˆ¨/ÌÙKÄí1àB"ôiH²øfqãQùsGaãļRˆcü?öÞ«Iyi=«æ?¼Â€#9çœsÎ9ç\µköoߖ 8€xö·žõÍ:КŒZjK­îV_Ý €y16“…E½˜Z·˜ÂxèÎ-£›2A7;@÷.7Ýôâ=*t3˜ô’t‰[:Xd:lӟ5{Z€—9€&­­Dz¨Dƒmá'ÕñÔPˆú,ý±Í.a´Œ“|d˜ê´ÕNMå,9A(ÜÊes¦—ïó(!ómÔà¡üàÎÒà†ýOb$8AíؚÔÐMØJ7C?3›9C7ÝÀ¶Ö%À&3 `Ó²`Ý@ `Uà +`Yƒ `Ñ``žé(žoÖQYž¨„úµ|­hwBº~GÜCê™L–ú‘~5Q—f¾*‰Q(|7è¼½ð(ìʽ‘—Q Š´t!v üF9 lvZ/A7I5…ŒªFº9¸~tFèfPøÉÚø²¿ø*¨øóÓÍ¡ðÖàÀø¡Kc'Àӊ.͇Ì&VŽÏ:LØqˆêÏ«¾M~”v…dfunjÁ¾ò¤5%KJ©Æ«X*=O*ʑ¾Q gV@TºÛ&4€ŒlYÏmÕÒ£2эÓHzåÓM1@7û ÕîÝL'€ÔD@*@¢½ Ž¹ –!X/èD³7£9áRDë~|ý@zÜ«yäf= N²§m§YnШténý¨ò$Œc\kT•6K/øm P)N.nCMgŽsÃÆ#Ϝ€ê*ý€ªP!ºqÄé¦\TUÁd¡2É ²$¨Hƒ~>ÊÊkšÊJQ€ÒbQ@a‰ O]T^ŒÌCª]eàuiEÇdT‰XdˆÂªOÖ*¤Z¦WíñÉ®9TÚÃéÈå³@íš2ù¡áÿÏ9%®Ù%˜Ï˜Æ؏Þ5GXüNW¤›@n†# 6;t³Òµ%çjµÔZõö\åîrŒ»{å—ÕÈê“.ÓÜW:LZÎQÀ—µ:䇀!K™Õ'’À™bvÊòÄ=D‚]Oã_\j”ÎÅìDSLÐ Aüó û”‚h­::¦›Ö +h­6˜lblZm*´:Khq ´qâZBÜPJ ™xãþB41rãuÍfíRƨÖåÕTŠK#Æ[¯BYY)ÖHh¬Ýs|¾L& Nb 6»tÃ|ÃlÃÆÇ·@o[*€ÞnbB{õ…èƒù"Їœ3 T@ïÖǁޣ½×¢zk±ìîúÚ]Ûfã.šB4¦-9š.r8sê”GÍAÂýæš%Ⱥ™3ã\Þ,ŽŒKõšNB0±„ã6±ïMôoê#}3.@ ø80λ0§pêŒKŸWÞ0É¢;`B6ÆA±Ä5«$Ãuü2%ä˜ ßÀ2,åTXºê°05°b B7§°œö°‚cX֓®ˆ›—ÉڛP³.U&ƒÆ·;ùL±m‹Ðd6Á)^ZSÙ}mߜ`R„eo±t-G Ss6•ãÅlofŽáø0­«'²)’Zaß +°†c÷Ö5HÓcê/#!xÑ7M¢H¯¨×;™|LÆ[&ÝëC…)[…†Ê¸(·ÊH YGæjùJSÀˆÅÒ)Óέí…yZ§jö‰2t"{ +ÆÙ 5õo–oBýe`í›ú³D¯HÓÝ}bœï:æãr§n\6Û-ë¬×VV‘y oâû&ÕµaQ·Ôgqwº®Ÿ‡wl93ëފ0£cÒ 0Q²w~蝻Ø1u¹Ùc¡3=…ö­qWŸhãGyg on‡=ë°:íœR™U»eìZ]»ëÔ¸­òKý0YŸ…õêº~¤ÑÕrÊXݤ5p¥U­+«R±XƒåS9˜,»Oår©åYôŠÝ ¹.âƒUˆª‡Yƹ›OíÃËHéD»îUø»º|‚¬˜siMёÍҞÌ&Ÿ0.Õ]:’®8ñ´ã”K§êž\>…´Ó¥d+P©'•ýJ;¢ZÃø 1^Äƙå!¦Ùh‰hږ°Dr®A(¼iEšaV¦BûÑÃ47Q²u¢R¾ø¡™„ õY#*›N6Aø§Ùœ]d¬›É2uªV7ɖ/¶OtCYÆÊÆ51Í2nˆ¦ÍsdY +Ú"9{ÜÞÔhSنÄa¨½œjÉà©WË=ä¨h%°q@9ü!ãHå]^uŒ½ãºŸdÓÈÂÆ3k(fˆl,/“­)Åw…¨²2c¢dS§Ê´šTv"P‡ŽGUT=:Ë ê‘œµØ +ôh÷ô(äTäæÁz0½ +"ƒô.àW%Žå$øCº<êÇ Ê55´Þq±mòj§'í:Ý˖!ã6£é¦«Þ,œûqc\ªIG€ ”ebd¯ “=¸–#kh©e÷móš¡aD³ÏÒdS!D©z*²Ì¯"¡}= ÖöxÀO)~|6Mù¢†iÎ;ÎOK^Ín +gãI;¦-þ´î¹sžÅÐm–g®b`·tîûǝ³¥dŽÓĄ;<:ŸÎÞÊvåfµ…쮪uP£Õ³¨'CZUŠYÞ2îf§×¦>÷´e/ჳÉOZÖCÆv<Œ“¨%[‰%´žxxSNúƒußáiô6ï8·qxÒöŠÃmFüN— 5»•°-à8ÌaG=îI8™3mo¥ýy»rå/ÛºùDã’i =PVêÔ]ZžåÑ<ë¸Ù€‡Ì¦\t2™ÕÁª±˜:.ÅŒÝi´™Teºñ·˜¦jÏz E²Laٱߧ‰ö86ÅSõðvíI=%™Ç7HõžYÉï=]E_[åt1µ™êÔvåR¡µá›µÞµ­ÍVêp´[®Ë¢E~sÚ/ ™ (7åÂêŒq32–ŒÅx iØÏ2CƒÓÐ[ëëL©÷Xóf]«*èü®:Lž¥C‘¢L‡Ê§!m·cÌ3MÙgSò©N¤ëŠå1™OæQ“9Þ É*ª´?\“ù=ÏÀä²ù2¨™t€-d +Êè1Q2ó¬1“™–:b2㥱­0Ŷlª–ÚPI¶ô§n`Ö׳»ÞcÚxu­â)¬óÛõim·æ.k $ÛÕ Z»•F…ù0õ¸¿³«Ñ|šÖü$†š˜£ÝUkKê¦ÊÕ©\![#i½zÉb·Ù'm¡Ñ„¨¬KÂYPð†R¯À=³”—§G6, #CÚLæÑ° Pb^ÊaÖlRÆL›¸RµÝ͔jŔ6à4^{.ßUØҊšFϳsØTiÁ ƒ\øtÃYÛmO”rt ÷[M`2mMԀèãm?ªu¹X“²„5â0ó• ڐ*á /^ÅåSª‰µS¦pD¦z*¬ÑÞ`)CI5B(‡» ¼ÂSÆÊ}¿RíÔeÉa£§HŽÂ@¡£•ùÂ6NÈ3ÇþTž9•IùÂi´³¹:‚“1¶´Ø(&æ80Àu+ïR†÷]5¯hï㩈eÞ4،ۚÔû}¨CkÆÆÜD•Æ¤}Ý,ãŠè)öŽ¹,®åò(鮔•#¤ÛPÆÆû>½¸¨™bªsïÉc Uèj'|xäYÕ"%7îb¤à8ì+(ie»¦-$+û5ð6JVPJÙ®=²dNs&&‡9–óF5ç°cGxç5­M#—»Öìä©·›!—±Z2jõh—kÕýJeZÎ{DmÝ/cAÏ)§ŒSΔ"¹?$)Ô­5…nî¯ÐM¥-_dÆ#yÖMmä&ď …D]Xuˆ]¶;fã2‡{W'y~Ü)|èÑm„ ¡Lڌ»¹’*ÄgnÕisP¥p x¶d|æB&æ¦mì8fÌëuÝgtËKf]_'4:Ì} ¶!用÷í- š +J;‘‘/æDZn2ʳÈF¦-!…¦§‰X㹁l¯,dŽ*r'—‡îQ±HqTH)³HÙ¥H…$}j$‹(é&eL·bjO"1ŽØ£%KËȦ:N:ú2OÉÕY9Ûª\ϖH æ¢ñ6"ž­Cñ4]{#S¨Ò¬µÆۑ@Uy­%…)æ‘MF›•í 'sìEPw‚ð†.@†¡)@VË#@ÖNZÔÈf6 G|Q Wa º™liñ“ѹÒrÔÚÈÑÁÔXAŽS[µ}l‰À£b`fΓ3õØÃë­3àlÚn¬b..‚I£x|º(e7«³íFºAn…[®žR§ðUåyjY‘Ueæð”ç9 w¬˜rïr§ŠG(: ›ÁÈ3f„n*j ÏRNº©%€¼îmyƒ8y~bòB%äÅÂȓ5 IW*¬öãÆDÍ©Y;s¼èZ÷±¦†ûƉå•3ëB9lšíºNÎÐvÖÃZ­Mm¦öµ1F(½¹-ªA]…qšm"ö⦼q[ (”ڐïÍUú¯\—nfS @©-Ý$@¡=éé]÷…^–aüÐúý”Ás +£Öä&Ȕþ‘Baò]2)’‘غ8õGÆŒ´ýf_vŸT»kǸÜÑ_ùÖÖEËÐ7SŠ²žT‡BêU³õMÇ¢Á(tÞ+õóäDnM•Û2Ý7€RÖjźÛŠÑ C7û!PŒMKºÉÒ#o ˜¸Ít3 +Åԕ§›ýȬ-Š^Ô}ýYݸŠ|€þgþ=P‰i9‹ÑK,nù‚¾À¸]´{7³ªÎíÑu0&°ec3J¤YÔ¦psˆ:ZC[$ªD +sµ±@Þéå‘jåBOÿÕ·²feÖ7c<·Ùò–nör Ì9ÔtÓ±e^¡›^( ž)P (KPje t”ö@é\ù€ÒÊ%ôå^*Z)YâaÔW†1üc··¤9˜ÝžQcO ;P +˜Ft¨REua"‘>Gߊ©G RQ'RUW“×Ý6Gm7'-õçMŽ–t³Þ4ˆè&ˆÓMßАÎC7U˜CÛ ›1ƒ,FÝ + fk u (ê¡gsØTã¹®<¥X:öMcþ…‚ +xK›¨Ë…éÕZkÞá;ýÓá@kðé T=3 áÔ$eUšº!•ÜQª*@0Ù0¾NÂKwe\lh_¬áÝ,>,tSSÌ»PÌg±ÒM#0¿*G7­Àì&úaûI0ý(0¢D&+ÑóÚ,ӝĻ±RÚͨˆ"PÍi&¥ýÙX*æ‘Ím.{ +-PfW[¹×M¶Þžê°Üˆ°¦V®"n›¼ +¢ZÐCÂJ@h1Ûàûí à³ùàÝýÏ*̌‘!qº1RÌlÂaÝ ]btÓªjZ¨§yŽfÖ>O>³WY6è2~B¡’oJKl^×´UŸ¼ k±K& ºá¦˜Ńç¦ Ü5‘ SùŽñÜ6×9 jYtӛUɂÐÍÖ T©J¨ÒñP…齧r»è™Ó RwM¡Xl9öÉXÍ©ï×"éÖ§t'­Z6Í#xʇ͵p·%‹xzÌysSʎI1quü +¦˜øi®Y(’óДÍ#º©ï€¦b¦€&=sM¦L›1×Dšh@4^h¬‘5ÐhG^ß®¤ê¹(y³huÄÌC|5²«ë.Š)f§8M²SY4m­WÛ<Çs¾LNáKB Hæ&±óÓ0nákæáž{K7-úá¾ÕD7ëÐ - k$N@×L»€®•­]» ºò!îÆÓަͦaTÖü +T6ê¯÷7áÆ?Åì¾.ÕãØÐÞk: &È÷šX:~oKÜåy`븱™|7Y`>Å;ÀBØOÀBêl0‰Yi³i,«X¬ÆÒ7ýpV¢jÙ¶ŸòË3«|Yww“x«¸ðÎζ@mÈT8ªÕPj‡nàµe þ„{hå ½y‡æ­Ö¬¾’²k\͞cí\þÂÜäíMÌ[š[~Nì3£VŠzL¡ˆ¨ÇÀ6º‰—•iuÒ¤+øS3g£’‰Fº‹šùÆxç)Ú÷ PÚ`J¿®ÌÒ&´­Ù tèÉ6›à°íP¤ä6oí¥•ä@•é÷†½úä4öŽVƩâŒÍ6~²½H§´´ö_5ëÖ½;¼õ®õÝI]¬¸64Î'BÍˌ£»âݧ#x÷iÆÑd„x÷.ã`è”ÄE÷ã ïRâ¢{‡q4©‹NB¡Be¶Ñɂä“Óˆ|ahT”ê “–”ý2¬ë2é ¹óCöå©RxÐW­Uå½F7‹«´ñ¬Ë¥X´)ƒò€´ŒžÚbeªz;ËHã µ¥âÖª}¬#§N|yDhnN ðA +†Qû,-ïÀŸ ÚÚR‡¨ñÆ¥úéHÛXjCÖ®ãöŠOÜ[r©ÅҚî¼F3·5ËöÔ9y^> ®œ%X,[‰bi}Ø+úúèXMøjšÚKÂûÈéLӛÐwZ5½bÓÞ­ÖD×TìÙivãý‰,Rmû|©ã&L“ãdšYÓÍÒË89 jª![-Äzñ²¦eNÍÒ«vmlԅ^J—MIë’^–MÍ¥C¬©Ðâmz9b»ŽÕEª»9äàîÍ:ãô@åÊB5\‘3–K +k^5‘e VzYŽÓ=ð¥g…ýºJ¯Íä`aÀ˥֒4Ó±úsÆuØtrm0}< ٗÙ6±ê΍®z´¨ðÏ÷ååxÏ0žß¼ü4#i2B¼ü4#áJàå§ ª{^¾.{%4ÒԆ?2dþÈü‘ù#óGæÌ™?2dþÈü‘ù#óGæÌ™?2dþÓdÊ݅´çBFÉd¨õRŸìtþ½Lû#óGæÌ^c +š +Rž3˜KÇ&™è Ϟ/)þ +¦x~IL +Ž0ŠK›Í®8h¯ ®kùœidþÈü‘ù#ÃoŒ‹"%$£Èèzý`â”ÁŸ‰3c·â6vì…Á3ú‰:¬ò¢k•’¡åÌ"ë?x´”3Æò'l°Gâ¿Ô“÷U¹¬:hŠaj L+wu5•éûG¾›?2dþÈüW‘±ÈJ0VV“z"þjOïèC6>ìÑsÔª«=öl*k[½}:›†+hÑË º}¦žF\-õÚ êA$ èÿHGÍqû½iT ÜÃéՃI—Ô1º7§Y¶]ë}ç¦dÅ©dkív[†ÇÎ)1°‹¿òäÙƒ±¢K7Cší¦-ÚïL[Œ8`bצ„×_Nˆwô_³ÊþÈü‘ù¿€Ìr¤ ¯a½@÷£_Rá|uã¬[j[¯öásŽèV³€ÑÛȁòᣕ„VK™¡ˆÌ$•Oô᪯U×}ciE}4“ݤˆy§kè£Ùoš¤ ï/½€ðƒE¢J¾¿Ý“}7'ÒShU>õ7 Ù¤ØG1‹‘²Ñôð)¬{}ÆÖ•Š%O]l7Hƒ]H¸Ï²»ˆ¡^“÷¨øZŠ†¾÷ð5ÉP¹-É×¢ý#óGæÿ™ùT¾@½ÝfQlß3 •/¬ý» Vªþ„ 剭Œ¸Š%b0s)Âb]fãiCK÷mLø"-QڅE‚ì1¥|X"D›Ìd¸ŠÂ| ¦îÖPµ²ýúû;xXÕ Q廃ïo@öÍ">‹r¸(r¢"6-˜í6f80ãÙaJèÙ°ƒl¿¿ EUPñÞ; +’¦%Ç;¢¯²tŠ¸ËȼiÅŽµ\m÷ëv';VÅú£†‰Q%§bČC”f9t´Ðª™ýTŽDF¾KÂœ°5!ô=“¦”îò +¼*U¨5€$¨`ÎÌû}ÉbÈË3‚²HmhVŒ„„äU‚Ð‘ë¢ )mhqìïÆ)×-fˆe;™¼:EöþxUn°ü÷o?2ÿV2¥Y¿P:æf#ª‹‹>׋&µ'9TíDÊàԋ“¡òéNÂ}¶µ‹tGå£k“ùÈȑ1,Ð'¨>2•œyC©ÕA#²&}ÜÓ¾ÂXQ]Çoå‰SL'›‡– ?éæˌBye‘°ËùýftP3ËôfÙýfEey©/ºœ˜ro߬F¦±ÆyYçsàï‘*Âw”ý}¶ïlT䭟I“0Ù4ÏË bC(¥åáâ–?å¼ÜɌŠ>”¢I—À´*G'82[{>V:Êqšäž›7åØS{r¬ÑŸ§½£>>ü·Á™ÿ>2æ¸::·¶4\ŸÜMc®`ú'_fíéƒx)Ÿy”šVñ’Ù÷òDÌ°¤’±¥Ú@2Ë{u"ñ$`=\ DÚôÔ´{%¡¾2Îj—`T‘†àÆeP§ýGӚm}}-ï6™’¡&¤Uzò|]%«¨1²#Ý- ñ¸82±òA£ã“'§0RÙ½-p V +s×Ãßj‡Q^0½qX(° +^E@ àûG»âênLƒJ™ñ[D³’{šŒfGºç”ÐÊûìrçð&RQvº"ZPçCŒÄûöãÓ ßCQ2øóî¨ÇŠ= +ß:»:E}»õÃ0„ÿÖõGæÿg2T­›F”¯³Ó1ºèfj2ùWµ#Y£×pO,œªdeËڜYÈ°Ê×9‰…Ñ¦ÆÛG?ߏ‚Ó„јdG‡È¨s¦ñgE“ –,¶pû‘«²=¸áô‰υ¨Yº­I±äKÇBm~Þ«î| +jDp§zf%-÷º¾rð·¸3É L·œZ;VS#¹A/ì ÍYcJ] èü–@‘~?䃼‹pÔÝ .ScÖãO‰j°}›tX*§Ô7uR>vƒ5š„¿5G |×_¾È|0£_ ß5†’y¦XÙAé‡BÈd;GH$*ÉaðŠáp0´“³±ò?tèþ£vЙO’¡¦G¯m\ Ib‰¬³b­š#óˆL³džÓ&P¨âÁ„̈ttAê7 èTÙ§š™l-(bMØæHèMËfsÝç]·Ò›»8ƒ˜ ªÌF¬Hhð%j1¥:˃ܾ|Ú9Cg%Ø7îì(¹†S—ˆùmiΗèéœæG B¦Dda¿°d WÌ8<ªÆq­Ls¶ÆëÞR*ùêpa½;KUkn*ÃJ/A¯ÚAg†‹÷Û|”Õ¬ä=“à" Òl` CZØ[†[ö´½ùíM˜ýÚ“°½,ìj»£Q¶SÕÇjkR›óý*"Áº·;*Ŏá"= ÕS$¢qÈEʬnñîVå¹)#™wVÀ=UI}_…À=呧“Š%ƕ³ +Û7°e,M¡%\Ò5YŪ'è (D5-ZIE,ÜTtW”*V­\3:~4¼Šµ‚Ž€ÿŽÍ÷ Ë"q|ðór”(ë5DZ¸¦»‹ +Æ2ŒmZëà¼@•MA[-…GÜfvO +º˜fô +Ôùìý8ÄÙerÈØW àâíi 5=œ÷;Ÿv©qÑ\bš¹™ë:fD IµyafÀR _´$À‡Ê–fçí.`àfFSBÕõá2©TÝÙa´ @+Y¼©œ‚J¶_„žQ*%ÏZ‹P•‹mÈäKš¸¿UZì=$ªW-Šü©ræ @ +Ê]YÓ"σF(‹:ä|h¾³±ˆ“¬°v +Æ‘^ÖÆÒ֋-UK+ ¥6¼*¼óYÓÐä–m»ƒëÔÌ O1®úOØld`Svj™¢o··CÂÞdº1çAw%½¤àÂñG„zêFb +ŒÝƒ=¡ïTuÈz†¾‘$ÐpᛙM6Öf­‡ o«ÇåíyCÙQÖÒ +ºF¾Íù‰‹H½ì ד\ì + (ëç-ÎO͒‹Q°_~=™û>k&ƊLÍù K8²SñDŠþè÷Ÿ§Ò¼ÉùudPF:&´.‹Œ›~®ÃBåÏpÃRQÓE+‘ùP‰B|t–sÞw*†¡2—…~ÀPI¨ê,V¶,rø{EìÀ¿¡-ŒÖl߁ëV +VUqVB¤Œ%/¼„u¶ s 8rE˜?J¦Ö¢îøùÀ¼ÂÍúa_)`¨*¾^8âöÞk.¤Ç~þ'¡£Vl.–B‰Ú [£UÍ}híâðd~Nï1¿+leV~ÜՃ &]\63† êàöSBwë敷y–?´.^`ø±ä¥!ÜâßH&•àn6¶ü¼Ñ#/"Jȳ6"ã§'É+ÂN<×ó³oXŠ«1têÚº5v¶Ó¤êI®ô=¨cŽêz8×8:³9 ±QÈ£°Z­È1CЊeÂ'×.lÙ"ÓɆ1ª°è'ãKÿûø¿ƒŒ¹¹à?Kj(eärTmãŠ$¾6C²=OähZ„ZdïÍ=³uŒY²EI`Ôg·ç7/  ä +2ûو×°—»fzòQŠné¢ððýŒùVæ¬}öcóý…3$市ëðžøÕ¡Û'ÜäüL6»;yZ÷‹žØ2}Úz®±¶žìދցex“ªÙirÞʼ+:kI¡ïê&‘óœ`“Ë},…Æ320‡“uï(|§0ÝüvÁ+¼ºyÖÐCmȽ¬ÎywèÔ018 wL^ã'8)–ìbP +¢}ú²`Û—Š× –¬Aè7 +QåNªæ +.—5z¢¯¹™ÿëöÌrXÕË:Ci^ïnóúŠÞ–ᩰƽ +ÖÉ39ŒN™2æKº˜=Á[»øÚÇì ^`s±¦;{fªàöq~‡˜]ö8E’nŸŠJfsÖr¸š +3ñRe¶·ßsßì=äŽsO9©á¹7¬Ùã-†°‘{'8iaúÔªå5>ë3E“·%æ›ÐNêóžÙV +};Nƒ׃vÑ:Iqc „,`÷s6)¨¤¹\Ãñ%X…j[´À1fØç$„ÖÕ9F +VÌâ/žR-t–Ž‚N¿rG½?»˜FSƒoVˆÚ¾¿eûø¶é¥Ê˜`.¦ +©Ý!µÓÚh +%®³ú¿cƒý‘y¹¡Úý˜+æË)Û­B܎»!Êf`6Ø]ìI± ‹ŒYuýæ.D¥+ÍÝê¬*^ìñ9.Î) Ý]4ðº°âC…Øþ”HM`¢ ±Ÿ·8¯å,Ðûm÷ë¼÷ҕ̟½°@Yír¯8 rÁª2œ¾bØMÏ1̀byy[ûÙÚð¾J'¶¯©ZÿÑ@äü·SìÀ¨™ï5•ßk6ÔÔ®\X6gAoU»y·÷”jÎz†Ñ‘ºÄ¡;³{Ew™X¦¼f^i4m”ó|(ÅE§Ì× +NÕ ;ǹ™û0›EhT³áÈPÆZKm˦K¤eQþ/ÞhdDšÝ1Ñή†Z±Rcw_Ž¹<ŠX°£³‹'릃šlk’å9×À€d®*¡Æ»íÈ/¿ O6Î]uú❈ŽwA"ëUŠçmÏ'É­¬÷{þf¢g÷ŒÀ–ï•|êäù(ç.YûèY;™žBÝ{Éx{¹âޣő{oŽ¦ÔìÖxôç»)ßcZÊB¯Ž`PŒ]ÔÌõ3âr«õ1ë4óò³=”Üú‹ãKÄ͟ ôÂð` œf”se Tª|Þ:͌„A ¡~ˆ&­Á“ˆÕøó-P2Q”Á쟶3þÈü#ɬú§a°7=αFët0——r÷´feï~QƒªDè;¹çî%©@,Ù8›¬ªYÏÄuбž#ú·²±ž‡Q·ÝZ¶±‘-°°ã™?íCl ¢´ 2—÷r0Ùcr§?Íh­€C]i×»'=ΊöTÌ[p-G<ø,i´m:l"ÓÆÖÉ-áGdÈÊnR"›üÝå{ÁÔfeIÎÁ¿[•œ–U?{näÓ®? œï eh«bò¬MA0ؽAHžðzqîd.ÚìîØ[oÛxѦdÖ ·kKRAœmIÙ@C>ÒėȗÉ5 ¶åJL‘3p™¨7¾B.ôõô¤ÊHA¥^µ|×SMU¯…ƒC±ð´]µnaÛÐZìšÍûF˝´˜œ#NL! »Û¾`*‚ìzý#óGæ£dö³ġ¸Â¦œ:Vt~³•&“Jy:Æhm—Bƒº/;Ú÷~#ªo´U²T«äsÇô-(g˜8iVñȲ;¥ÏcpjåuùBwµ¶àᓨˆÉï‡Â¶)…êZùd鬁 ا£\E–È΁’Ôøn4?ÝcÖ¨µ3§-íA)$›÷4òÄ·|å-ªƒ³ŽHRk±eR›µG”î:°P/Êm?'–EUêY60öwãb¹·þEk÷Ì™ÿ,Ü›œ”cÀÛó!Ñvíf¶’šs®{(%#~EÄè³XG WkÔ£\íHÅ/N'ÄÉ؞¯'ÄÝðŒ×`µ5Ü̋)'uÞüÙÆåP)&t¾> `— T̹ïaÜ8ÐU® +µÍ€Tö[$&ÖZg/ÞûÌJ )å÷jU! «CjL¥Tk?X¸ÏÍFW%¾†ÕÞ!å8Éáu§(ÖW—¼žzÇNt7«€øK¬¨u”¡åÙôž«rÊãÁ¢û#óGæßE†*"ܾو/3u"Ù4›9·C(sM&Wkë]®Vܹµ¥Ô³ˆ¥ ×&\?;ˆF­Ë#æð’`íe~.€’Ïû-ª¿ˆ¬zEFÜÉËŒZíPœsÆ¥5BL(!Э‡”Ç)¾™^¡º±Ù¨:g€;i›Yr%=h4¡ “¤€î‹øü›T®–ÎPg-eçD£2wy<)—¶Ÿq'Ä5Àš²eêVS•.7ïÐ+,±ú$ÿêùGæÌ¿ŽLqî®LOÙ~±¬˜§J…¾JÖ>èÚÜNY2dٍ 3«1 +,f;Ø– 0ȅpυ©Ý3‚õêÅ%I b™ð%pÙªÁ=¶žƒÑ + ÝdiLë^Ԇ%ú™pÑJ†osÑÜ3E¯¶`OFu¾Ñ=•·ÆØ…k0¬Ç’ó±?êŒ`Òxñì+mƒ @d|%›÷?-À\ÊÈ6ÁÑ\Äý¯ZIdþÈü‘¹o,uynMŒ»ÖMP)òêÒl7[=×6ìѼí«IXÏJæ^DˆL\^´.ôN§y{ˆ™,ëz«ã/“{Ór²@1jn{Ok£@nWèö6ñ +”Æ2WtÙ+øzCá +N¦±bF÷To›º~¸¿Ðí“+`êûÀ¾-DÛÅlW—w˜5¬…ŒŽºJ| žmJÅÍ*¾2J)¬öOxõdþÈü‘ù“¡†ó¥;Ð^ôFå£x_êXGí!K]띕ôA×åH¡{2j«Y³ieÇsÚ5cܔ)Rô¶A}-Þ¶0?ñș~0ØS¤!‚+Œy·c÷ͪ±Qi:åcæiôrY…/g‚úÏx7dþñdö{§œÁš^þ;G™pþc®*þQÌÿë¦;è8þóÅtúÿ n§Õh}üßì~3ž-Gÿì{øÿRì3šôæ˜ 6ûáhxþŒn|1['´^~ +Á|ªÓuü£Él]ý?Ç˗_ÿ£_Ü~ô¿öÿÕø +XÌj +Ò}GLϤÛÔµžr_£Õ)ŠôLø—ÞèÌÙ ?_ä~þb¾p<Å£?8¶EQ$ïêÇښûç[=éʛ§7D]@¥Aóð҈t/œO×m€šÎèïºc5 Oö RÕ PiSz­ÆUÃú&Àsƃþ¢G\=™®Ûà·¬æºyUwªºá¥bЯßj£Ì ´ß»]}µMǽ ÛÁm:+êð¦n,‡öͺ6X׊a—Ï5Ð>ËúLÆ Ï‘‘§ &Íbf§¤6$m0|ŠÿTò°ß;Eš +ÓjŒv"×±¬ácYßÞ,”Ú¡RǐÎ\ûÝ·´'ݹõDº#@ÉL}7Á…Zs°FŒÖcNÿ3²¤^ ÞSmî[©fN˜jÄÒ6Ùcmµ Õ¶< £·8„¯TͳDD!LÕ °ýA§Ø SÍêšF™ÞN\©Òd®„(•R‰P5M±Z S5âMÒ©ŸÏUnÃ…Hi»L +MWö'¼"T͈|½Ç]"Tkmmxœ.\©ÂÙÜŽ§Rï©F¢ú¢(‡õuw±ËP¥Wd?tÿ^+pA7Oî$$Œó_-V34–:œ¦jÜðTRë?SÍ¢(‡ªÉ´êl¯To4K¸³oM×EªÞžÙ–멶=ݼU˜X@nÀMáé:Aë€LGyaª¹îÞÉWI!ª¤ciw_©Âws¿ Oݛ¦j¬Õ´a›6-HUžXäù•>#D•&£ ·Za‘éšÅb +ˆQíi#T·,L5¢õ¡#ÌRc¨Òd¸L>"”çLµ¦Â8Lö¤®3‡CÍEøŽjÝ©MZT:H•àP…g›,:ژó=•ž&lÙr—q²Qï‰P5#–Å0Ü£Ô¦ˆ–¡Ê¬4Îtc;»w¾O穨A”jbT0h…¨2±¡Ò:¸LhºY":J7ê8&HµŒ®'¢T Ó\·ÏP¥Éð§Ûˆhˉ­S˜jÒ (…½N—0Õm\&DJhH¸Ü‰ÈŽ"Lnd´O"(L5åuÚ¹VKj+³ˆ1T™ó†?ÝyÍ4 ‹PmZµ­ÃR%L5=ß®26«C’awbªµ(“÷Š D¨ÖJÚÐl¤jM«dÀÛRA™F¶ï¸›çÔ±tÎTûœ³yðz²G0Tõ¨‹ÞÏ5©ív¤J]©B20Ýï|w9\{.ÕÃFé:S=zHÎ\A³×ÀYªþš.v/©ý¡ä†ª'$¬æK¨˜Š™.M5päÉŨÌÌRõè*ŽP¤¶Æ4{òäö@‚¡Ê9–ï÷½þRÕr¨î÷¾Ñ沌ã€Cõ`šÛÏ'ÇžSs8,یºEV³¡ÚQ¯c¾V´¤loì¢ßÖrºUYìÛ©6ÚUœ®ßòZ•"?§ßƒ’ \6Y8ߚ­ºNñüíaaåoOóz*« +=ÀJÈlÌÞýÖª'ò]ño§½6zeÿŸ^Yˆ~›$×½ø·ýÌØqý–Ë43’‘ úQ‘Ÿ[£Ê¨³t`¿£;ç·%rvQ[Ç:™Ï´R?^X =ÀJ¼ ¹Ø‹~[Qô5@üÛfÐîúašÀ]EÛ"ýv~Ìn£¢ß.Êzîú-Ÿi«EØÝû9=¦œÃ$úm\otW0M1X÷ I±Ÿ+2Ö$D¿ ùRý‘è·q½G¦{À4ÐËq»È·¦¨6ä".³¶cηd1w𜿠¨¼í-v#„ïú€ñ`¤ò÷6Z@;D³(ê*–ðÛíÙd wL¬òoiö¯{™¦?Ê¡ª¸­F[¡ó"lÔð³0 ‚ùl*Œ‰÷cß±ÒâL°—÷_¤à^¦G]YÕYºÓvнžæF (ýËøŠÙ#кٚ”uÒÆnõDËY™’&8vþD43W§•,´?uÕª;Ù»—Ñd®„SH„ªvPC˜ª±V¥JŸ)sWO».c +‰R…gà@Œê𖪱-éÂÖ´¿pCu¨T"WªŒmðCÕÀá0´ ~æYÞQÅk¬‰{KøŽÉ.½(UÆ6¡J›Œ´mоR…³¹›nK”*ÍäƒQœ*´ D©Òd y0ž®¨QM¢¢TEãJ•‘w„¡¢Q¼{µ#ۅ>ó×ùeàúp%å¹öiµ¾“"š‘];TÍ<}Î4=¯¾³ÜðÓ³nú.¢“·‰»Ø +2(ãÌq‡Oû³œQ¼œ½¯™!vêÚ¸·Ø°x¶é¡x:ûÜ[ܹýécúpÛ¢ò93·-ÒÒB¬‚¤ W1u¦ï)Î •Úœ)0Úñ…ÂUë¤GDÏϵeŸâ8«hè×LGAÅO“¿Õ¦Ï>¶ÌÏÃAH&r;ánÜsñ@у.eéO”P×=±ZýY8ßÌ!«¼çᏋŽ±6nR(˜.Ë +njÖÂã ëvLJ¯à¥G=Ú¿ǁÈpŠÎÖɟxÆx؜‡Ïý3Dè á»ù™$ӈ¾ÆË;,Ȟ¿Cäg†Äe¥ Mêµ¥ü’þ7Ì*=ùõ 7ះE»bVÚÓeá—CõÒúº.®ûCš]_‘æîuî ²žVyê—ý6÷õþº-þ˜õ ÓDøu/…p¾j‡î¥AT +12íá 5cû[þ úŽ‡JV + ³¯b4›3“EFD…(¶9³O·f_MD…¸èödx‚“«É^ŸÜݱÆÌÏà)SÏØI(ÏW‚# ’œyÝk7óeÕÊóàÉÔM¦¼yiJ‚†^A´ÅW½áïÏ~¼]î]\I®yUÔVד£Qfç;‚_òF+~pO7¤ë²|n4ãîM'µ7¡®Öß^ü Ø K݀w<={²êéá EtTIGÁ¦AÞ\qðÖ-&±PBè•B¦Ý¾UØÐoõêÁæ/z†?"‘¿@2¹Ÿ1Ý ŒÍ1"86w¤›¦W;:–4<íŒÿZnŒÂÉ-ÃÈ3íLªZX¡Zô¤’ M^¦uœÆQô˜‚†Ç /9Ù}]©”ÃȽÔàWjs=‹Œé艋Ÿž™üyDRt=zLâŠÞåõ±§§„×h“?Ö6žZw¯q­x¨m¼ð#ÙÕµ«ó‚~£·ÂZÂÀàö”ÔÛýóêÀ~.‹Ï½Õ9¯LóVÛ{Ÿiý'™v/Ý^ؖã³éZö<ëöè>üRs¾¿¿¡G2Åt]Á3[ï¯NÁ3™v£} oÏ£Gö¹íé¯î䯙ÓìÍ.ïmFáKòÊÆ`A5™RªmrÕ:¹ r~Nê§þa1ÊÂûæù«r[œ‘\40O䁤‘pµÎ߱剸Éْ&EάIú¼/˜îìÝæ}üÒ5jHß:ôÕ7®pú¯\û¡(ˆ¸?h<Òl%‰ÈF‰=ÖEØ}#yXÈ/EGt½×:*ŸÔREAì* +$ûÄgˆJàúÙ«þ”ñw +ÄsÏWÍ¿ñÎcðj°ò‰¥<êB­Cä*#î£í-#ӝÞSƒÔUz¹ôzÄ/é›]Ô,bÍ(š_/nö;~ýlvæ¹m¡¹ßéqf6÷›]Ð8¯L¢3å‘Ó!Îuär‡óȑËu¦¬â÷ú½ˆéüܑKOîfC]–ÀË•8ŒtHIu„\Í(î`â§û“úŽz1ìô̔ØÞ+“þ¾8§¬ˆ“謧‰ùõVqxO\{ËI#Á;È +"¾È ³´}#Dï\Û;5Û{âªÙôb÷?^$´Mr:ÁU³_aßYOcF¤x<"©Žƒ§dA9ËâÖZ{éhLp´ä_î{<¹çË=q= ¯çÍ/ÜØÛ÷ ›{…'¶âét þFxJ +WOû%o:OüûÔÏSsiqN¾gçÒ­š{žÍÍáï»ÐÛ 8/ú3)+Bt÷Ý.è="õkÞrþ¬«¡ãs½*ù*“îMÌK+ä¢=b^ZØÛ »PØ ¢7Mæí+æÍ=>¯7…O;º76_Î冝íèÝ­Èöòcq^{ù‘ЯtôúAxõ ôvwÑøÚ±zˈ²*…Ý+£&"ö#×&ÌõçþæÑ~”püÀÞôê×o +E4 4JHâæbjßÝk\évXà<évXp¯%H7agJ€æw÷®t+]¥Û‰ûŠ~Ïíí¹t»úžÜAÁÞ~/Ý®Û3RÞ|@ºÑoNHº½.èŽ^—n|/ÛÑûÒ öò[\¦£×I”û¹ÒÜh6wž°ÛS©¼ydgßÞ@ ++.F*ω뤍"žW~öîUîÏy3Fwâ"I¢Æ w|æ(´«ÏÎûׄ.Ý[¼$qፇ˜Ðýe@Åý®.3÷½Áþµ…~sœ€)Qaó¼#iŠ¿h/¬Ï†îèý¨ +¦³›{‘ÿ¼£û;|‰ni¡«¦·O8¹Ùў!ɨ÷ç#ý±êíÿf©ödùÃûFaµ"Õùuëå=+/iÿO<·°·÷µÿæNèp|ùXƒoîu˜À±;zGû¿éåçp|ãXc:Ðþ…z¹š¸"I=Ž¬°iîÞ>ïÇ÷ʙ%Cü‘P'(Š£¼.§ç]hÖ5´CT?èì¼–[nRR®ðªÕwœÜÜ;º·w÷ùÍÀ6ù“èîL“¤ _Þ&CFÌd¢_¨ZҎp  YZ¾U±Ç“è²`£†žî3îIP«xÇT@­‘f{J8©ôþêP4P<4NÌ/@M/›6YÿðÁÐ^º7Ñ»Ÿ«kHj?ݛAîH$?âL¡™fyMï t„o³£–æ¹e{Ùöµ‡‘¾ì²`.‹™•!iX—o“]iv_8·)µ4<ÎïÁí&@µÎuUn‡€ÊghC_HË÷Å&šyÎw{¬ñ±|_ÐÒ¯á|±|¬„þœO”*ƒåû….¾ç{Œåûº….¾ç{Œå»W߀ó=Æò}ÝA߀ó=Æò}=€.¾ç{Œåûb ‹€ó=~îëŒú~ÎÇÛÁwX¾«áñ&œï1–ÕӞÃùî  ݲhXHy/FâÑH“°ƒ8ø&ATÖcG×£1 ÷˜Ù¼„ß“$vBœø’›¨¡×`\ǗâKÎñi‚!&¯»›Å|Ílb³·Ý[5òxr?ÖÚ3ØÝ}Àå«®DvAÓ/þ]O3 »»öá˜QÏ`wâFìãۊ[Ñzbrg¿>³RBÅ×€YZo÷^:þO_¿{ +Ĕ&¿zá—,cv{ŠÇ}ƒx¨æK ×/…—’ˆ|î ù%t1~ÕÓø¾¶g¾Æ…uËñ¨Ð¿- èþæÒ+"ªŽ‰‚Ñn(.í©:&Sxzyÿ¦°ÿƒÜù¸Ä1r⠜Çj¶@ä=êš"bÃò +aFÅßáóÈ{Éa ÃȽ×Sð~IÅZ÷Ï09V'$öö1Ìêþzo" +Œy¥·ç ÿ¦Ý»eßeÚSàªôi^¥Ûï˜vï/Öû«5Õ}U”Îÿ%(“¦æò\Å|;ìgÏçE|¡{œ>D:XÈ8‡´@]}[›îÃ}•`^Â'öà$*Ùë€ ù‹>žåq¡ßõ×Oúi¨½_½¥ŽVÂysQt„·Û=÷F|ýÏC_6„ljØy¼Õÿ­Ç‰|À‘Gú =¥ÇùY.ïFš†i?ð Xð(ë·+b z{Í$`K¨'X=ž‡eøßèi1©{ÿºñÅõ´yì5_8⏜ôkVMŸ¸$Îû“°^ôÞ܍éξÃÒ¿â)y0¦û]-áX{À*£Ô1= ‰Ï{4&^–5ÇoÌ¢>Ὁ3ޛwÃàh-Y.Á{s¹)|’ÛÕÊw¼7·~øûÞºìQÈÈ x¸ßxo¾xÐÅ÷½7ÇñÞp”[éXAãKÞá;‚¸€4tD ÒO‚–"‹”hïéÄU‘~«.E‘6xJ$"aE|=FHnŸ‰`ލ=‡~ÆDOΎ=‹ –‚‡ûeÔüÝy‘l⾨`l¼`ˆ/Aèâ3ˆß˺Á° ÄObLàCˆß ˜•£r¼v’x˜_ëfßjÃ³üüªð3‰'ße6¢AOŸAæ1d>¶÷™÷à÷“È<Á°ëìêÓȼw0/ óÃ~™Ç¸»ß܊y׋•çAˆo óîC­.?B?ÌûâæReÁyŸFæÝ\H>?Ì~Ì»¿ô’Òù;dÏZ»‚˜ºÿá‘÷±ÐKº«ûÐKQ­SJèey#)ôò©8, ïª&æBZÀå󎨧K@bGRP,¢½œõ4¦£Êx±"ïŸK7ˆów ñã«¿nªùˆ„X£;‚bîž¼ Îfw UËïìÇ+þéÖýðî~¤{{˜GP¦‰îÇÚVê~|¤ªCž¿fS +.·¥:f:zm ›¸LGÁe5µ§‰ç;K&ØÍÏwü4Û½7›s‹ÛÅ)¾Ë ¢àg¤zjvÿølÆ:ÙoÃNnf-–5ù7~hØ[G¬U*H¶'ëKñ-<~$ÛÜ}$ ;úHâÖÞÉÂ^>’…IKtͱ›c™"ž +öåø%\uY÷û±úö~ä€òDdÚ§Ay,Žàa¬Ð'@yÂïæã ¼7|÷L{lâ¿b{¾Ê»õ§±¸¼ÿ(OÈýðå‰øÓ$ZpµGã­PøºÍý}5 ‹•’ýž£§ÔOì&©qd°+“4'¤Ç3ìMçzîì~¸{ÔØLJê҈gÙç·iÒ, ¢¦Ì(wø´äž±|Îâ{ï•[r}žÍÝ-SV¹ù ¸HB0,×Á"^Ók'aL·wk†õ,öYðÈÙÄýdy=¡’+_`$ø¢•×{Ím×JŽÄ|Îd3\¾;ø¬²ÞãØAé«êIe=Ñòîo‚ +­H¡„ê +’ÿ¬Æ +7ÜEõ^Ø7‘‘x=&ÑÐZ©Uùž8ˆìû¥ÏæU`Ÿ•pqÛ}Ø'5ŸÍ›À>!/"oß¼ìBõ}ýˆ)ìrã‹ø¿ì»cÌyó^o +?ìêêëI2“_û~{H¿ìºç¹žžö ¡úîüŸö ¡ú¤F ½ìòÒ_LÜû„Þ0ë þ(°OH幋Rý °OÕ÷%’Zÿ `LSäõ[`ŸÚÊ0í³À>¡w(jõ&°ÛÕó +Ì¿ö‰jŸö½À´w€}œ®x7ìöýŽi/û#½>ìA}Ø'Ô$óa`ŸÐe 7òþÀ>!AÁ1q?ì{v±ò!`Ÿ„óæÀ>!vܨêŸö=”}Ø'„ê‰~ÄFT]mĦÍc¯åœ¯iƯáÉ1£$£¯vO¶ýÿ1•ã*~¼1™k¢OWñ{ rHcՑD_bՕO÷—$úTې¸î _"pl±aqÆ$U(üÜF=ÖýÝÖ¯ÆÄ0ÖKuªI86C\Ø<`Ճ:Õ"ò“9ÖîM&.~à˜L¹mû¤"ücWÞϱö°þßÛÅÿ¾nrtIÔ×SüOTØÜÕÿûíä~Ò¾}‰ʤaú$Å\<‰‡¾Öÿ{ï}EjÛ/)ev:µ$ÿ{¼y»øßE³y\ÿïíâ_, +ïIý?i×OÛÄ'rt<%ÝãùÆ#ñ±ð§m⪎ …óHžœ —ºJů‰`Ù¾§ŽÏV)ôAû±ó^¦OJ5$ó ï("ìÉ<n|!H 2HÔYÈYÐÒêÑ¤” i‚©`Egý%”ÕJìÂ(’]ý_vjE/­'1è’C­è®žÇ§Iµ¢{“Dþ8’š„Ÿb¾“k->Èz~Y;’TW¨—ÛÀ±Â'¶"Ó fÿ%`~Ž´gz“„ö­|ÁEûÖ|´oaýÁô†°·Ô}fW=^)‚íö0åfQˆ›ÂïæÖØ|µMðo‡!(²ýØ`‹ÚŸÆüdv~]½àw•}ý´UŹ8{u†Ww7ľ\‚RdL¼0Þ¾‘Ìø—bÀh2†%î_~mLPtŠ‡GċÃ刮PÓMÜ߄‡*ÆüÎÒ ;IHïýÌsÛ}*eM¸Âæ÷ˆ¨‡niÉ×DíÐ;)v¿®I^Þ»_Áî„ï¿oC%A瑾Re ‰ïf×Êw÷%Š[{fÕðóÝ=0Düi÷¡(—µ½ðK%›ðÇ,é^˜'l~{‡ÎbÿÄ64{éõ¼¨ßÝظwÏ}|_LBQŒqNjHXX÷¯+)";=¯ªøãk€6~7*Õ=FS}½„ô²½”ŠáfL\üÍ0òÈçüTU¿Ó Bàrõ}³_Ä%.ä°¥_·9ºàŸU€~òo.ò‡‘çP!É+‚SúK°ÌÎ ½=+$„ò ¿zãœ2o2í)šHú4ïo@ßeÚӒB¯1-ilŠôÆC1 ©¦ý’(ø ó¨& ø($^$Q*QÀý +$Q*ñ û+H¢T<"ëîþ5$ñn½<°By1·¯A¥â¦ý’xeéc òuôz’(xµ¤IxwïɎˆ?¯÷‹~I/R÷N±ÂÛÙü‹òÝÿ‘b…_ϊÔ}¦Xá±òXmy¿Xá×ÿ(ôŏ+ä»íþ#Å +C?_¬ðKR}ÏwŠÞ¹à°Ì¢Ã:sébY¼Úác`Ì »$žGÛI,x(-«ÕÛo&÷‰¬Vb_ŒúmÁÃÇÕ…œ¿*xø؅$b°¿^ðPx >Îjõ‹‚‡ô' +>7¹:ºÞ,xøPö!?ðÃj‡—óæ킇'ÇõrüºàáÝHxÕï|ï<|<%Á`Øß<G>Lß.7’Ñ»ÚÛç-»Þ°¿YððáÉ`µ<|ìMþz)yփ‚‡íaá°ë_<Bm^·àïW§àáã^¹^*xø¸æŽàßÇ\Ýo<| æýâ‚d[ðP@ ½©vxk­A©ñ낇œý¨½¯vx«Üþ£ý)xø‹û‘‚‡«þµ]gWKÒþ~Ïá?HŒ„`ÔÝӓÀ`¢È`“ml²ŒmrÚÝûåýíïSU“$ ˜äÝs|EMO‡êª§ÒÌt&Я<ððñG¼sÎíë<Ì^#+’È,™ò¼W.:<|œ‡âܾÁ‡èÜí©ûÄÒ÷Ÿ<|¼—ԁz큇O?§ðU¦½ªÑ³_%é8ðð‘W.þühoó¹>îæÓjÞäÀÇÌúfAAòe¯‘=Á×O ’ÒÇ?xøxíºí±„—xØÊðö€ò%®z၇÷’ÎæU>ÔËSß}⁇¯üÄDç Ï;¢°ã%Ù×xؒï8íP ++opàaú¾Ö£g¯¾úÀÃǝŸ‡$íÙ>~Úa׫?7xøÚìà<|Ê»¸opàáã§v=ûœÂ½Ü¾üUýÜi‡ùa^uàag +:ÚaŠÐ/ÕÇäÀÃǟk7k/>ððñ‡¨Ú3P/>ð°`or§>È´çxøŠ\g+ӞÿâÕC±ç+<Ì@¬è´Ã—?¢Øvàá£b‘?üäu>î1Æ!îë<|ü%ÝÄH¿úÀÃÖe¶ŸvØé§=ù+\­>ìŞÍ¾ÂõÄŸæÙ¼úÀÃünv€ŠßXyÁ‡ÛŠ‡"恇ÛŠØ¨˜‹¯ùn+ŏ‘´ë§|²Ýz‚üpFøñçýÛ^¢l©TÒ²òÏèÈUþ-}IeÅcUZl¦s™ñFÕWš~ÊÒå–hu‘^ó¹¹1·?Ë03óåÚÎrªoŸҊÞê*÷,Î9ªrQ®í\Y÷æç|côì{ôy£¿2x^훸žP³'ËãÝ×÷~ùÛÁ±‹_ûc½^8<û~iåzÕ»>ýBçxžcÂ¥Æ¶³àܔ½Å»?±zºññxmÉßú¹Þ\ö®7+Í=[ãU;õûÝúêÂéÐهíËæÇÊÅõ^pÝ{3vá/—·–?öõ¸•¿÷ÇÎÜ\õþg÷Ž½üÖJP€ß6ÝX_Û,;µÝ±²9¹Þ¬}pûÆTcbaB5~Í«ÿýêÍÍ~T¹¹ ·æn»wýÃ[ïpçSúæçzm¤>¸å¸‹Ñ»ä¼ßõ›Ûo—t_Ô-î`œ´¼ò:üuq/?ú|Eawz@&·y¿¯{ûÇÇç‹øÅìÀ‚ïÞóÞ¸=å—Ë/XVúšŸº7¿®ö\ÜÔï=¹ï>;.Ó»­óÉëªåû+»LÄ-]ð’åñÆúz¯êiK^àÓe«CÕ¦FXܧÉÜû{Y–6·8@\'FýÞIzvpêk£¹ÍGŒN~ŸYÝö—'ßÕï>̏Õo‡Q÷é§é­1wœ»9ÛÜþ6>ë—ÑÑæuÒ¯œ/ZѵӀ^¬ü²;6¼X¾áuŸ_²@/lmíÕ¦7·géÖüéÌ¡W‰$üõ¾Üph¥êwz¾aïNp¹î9}É/]áœ3x\àÏ ŸßEöÌ]áϑ›î>˜µP&äÎF½1m–Bô;«jS½÷Êìܜèûy>}tz©úhPå©Òì¾ëþI=<ùë ®qa¤–»pÐ39‚a’k“ƒÙ53ñuãcra.p!?à`ÏÜτ7ËU€Ç婞Y|wÒjYc*EÌì:GéµÁ\G3WCŠhõØmò–½ét®gýE™t?n”ŽŸÆúÓ)îqº´Æñ©1zs"I$†z!n_û>­ÔéuÍpóôiCóMnOt~‡?wÜúÒÚ©‹{×kµÑîÝtµ†œsUÿ²˜1f?7Ì>8✪|x?trÑ·Ñø0mçSä{fûsÞë- +™Ìb„y^L¶uŠa^Ýoò®;÷[?GáLc¬¯¹>5wZ¥‡ÞᘠlÞ$û|ÏùÇÆÐNa +øÇîØ·ÄÓè¡+ù} ÕVLˆîèC µ</Ö(£°0(8p2RŸšÿp©€¤L@¾{NÏ&ÎÞ]4ڑ”4·àÔ¡`¦wjª>3V£Í[bo@4½™i°¢Tc1šY¬+ïpác ¢4>@4ë<NñÉKÈKƒˆ×žeɌt« g[\Y›>VǽS77#GïóÞ dŽ]Ž [©{1k&×mæu2Îx^JúØïmëãæþðÓ5ü¤ð^È÷_Í|ΑŽ¿ËQ.|¡ç+VïÈÿÜhùèÅâ-}-áS¾ï²ÑÖGٝÛÉ:Xk=ÇØcæ’è5öúLõ|" g¸Sw¢ÈÍ­Æ´ƒëþ˜vú®f¾ßz©·(ï婬š?ÿ‘~âÃômõ`Ïk \sٟêüü;í•ìíÔáüžùšµá³ešç;ºð¥í»‰á}Ø._Ö§Åû™ø²“8wð {V¿AíLûiÞ$L»/Ó¨eᦽÝyO|*wÉw9¶ÙÓÍf”…ab>Œ¹µ–óÕ÷&ØzÆšÎiîÜ,úxiáÃÔíZʇoy>Üﬤ|hûËÀ˜àŽ}®Ð3·1>®t>ùN|ˆG-ç·|øä˜V‰êBWvÜ»7ûÝy÷{ã  ÷‰,+§1̽Î3áhe)†®ö#Åûä+2ssò¹X Zúhï€ß5o•È®ìÓ,JéN`íù“ÈGÒ}òE‘W,D^}*P-aړB _֎tªg~G^"ڕüŽä;N¤zó3*7^ÈǡӋ¤ƒþ6¹"½É˜Q4?s³’É·šZ;L?ƒsÑÁ´ªx'ò]Ÿõ‰t÷¿|oÛ ¬ÝË%-Á/“4X§¨ƒ6I{¬çë~§¤å™ñ"IËs¢³ƒLÒ•Öœî?(%ùÚ¥¤‹Ï)LU÷%;RypG²h5õQ}œžD•?3k/YHõ!ÝoßRâ©f;ò|Ñâ2ð Õ¼l!ù-ý£læ\Ž–>Ò]}áBÚŒ™öL©>AQË}Sß>ǘÛÝ#ÝÿZEíÏd3›„dn™G[/´KyèìϋçKÄ¢ÿAÙl…ÎÇLSÿk<…:ûyë¹\—ßï†æ³?ݞ¡É‰8›¿›õ8~ÎLâ€÷¦&¡s.×ØÛãX.I©&9›µ+ę'£SKòåôÃ·KŽKUœºÄÊ̓½Jüëw“>D2+¹;zh€bÙÙZüçPeP†™Œ)‹6îñó]oÏ©,¦U³‡sۜjÑêb? ;úóáñdïaza€/P–C®mèãôš“¿éd$pt17 ûqój"æÍÌ[yàl¥2”ÐƲ„ç.?½;ô!¹ÖÈòz»|h¸Äϒ¸˜YQ$Ð5y (Nîö¦ÎÏ5ÉS^irÂ?æE ÇôVèÒώ´:ò' ý©è Ø}4»ÂÆý}ÝÑñÎ}iÔÒtä_5U(e̺“£ª=¡2gk½ÓQuwlXmöäs<ûµøŒIf´æ;ڞTC¿uÐÖN1ÌkûU¹~u½ûöCmcøÆÝ°ËãÁ÷ã +§:ÈHW¿®•“\ãN–"Ûw{>|ؗ^õþø4áÃÖ@.O95;B™ö-Gø5õuN³¨š©£/þu¶AuÏøû]V@3]=؋™úØÞì}£.¿:š½³E%÷îݯƝïW·ÓÜÊWӒ2ûÃÇ¿Ók6÷s«Ùß*O’Æ“ X8sNúÇ?ýXœZ˜+¯e%ŽôáôÉô™¦÷­ŸiKj*nïý\3õ{â¾7’'sßïxñ¯©ƒ_i;7n·y>Þ>•Éuò:SgïŽÆW׿õMŽm%[»tÑZ5é‹k]ÆZµ}*˜ë½{+õëݧ÷ŒQ,Ðç6G"®8ÏïYñ⼗7TÓ³=¿ ñf²Œ!îؤZ¬Ãå]R^‡ÓâT} fë]í_µJ9›UL¦ ”¼½nÇ4IïµÂ™Ð6´#й€-6g'÷OǏ[j*‹*ÉÓ-è|)dâšJ©'+„8áË%–héßÆc3139 4ª1ØÌÌI+â×oI)Î6(´œï|ö㪋Êøÿvý„‘[ +‚@•ê«÷g͛•›_'¿.J]ÿ wýSŸÓzãâø²qÓl®7ÿw7uytÞ¼¸+ •êãk“ss¡7Õ<º;þuaêkcsm¬~§.%µ-•Ê–rEí‚"8<»÷åê‡e[¬÷mR-œž“,÷L…õò@ulŒÈóåÚçwË´Âeºð±<8î—–¶gËý×Ý7”E óE‰ÇüƒÌ9½ùKþAæð#æOð²ªÑ3Š”Y…’Š¯)ó©õá“ñäÂJV&ڍjf$«#î懆jåk¼»ùÑIÉÄð춿ÕDݾßþ¾Ç…U.&VŸZ¤Ì*”ò,Þ_*RfÅD*Œ?P¤L2øEÅÄ?Ö'Ûú‹ýž'wù„ÒdQ]2qß°4YT—äGe߶4YT—¤Õ¼qi²¨.™×›7*MÕ%[Þgy›ÒdQ]’|Ò7.MÕ%å)œ7-MÕ%åe†7-MÕ%¹\ù¶¥É¢º$Yo[š,ªKÆÐù`iòýóK“Euɖ§¥ß¦4YT—Ìå@Þª4YT—”§pÞ´4YT—Œ’{ËÒdQ]RŠ¯oZš,*Éuµ|êäMJ“EI²¶Ôþ[”&‹ê’òƛ–&‹ê’”;|ãÒdQ]òuÉðÂÒd‘Dæ“áoTš,ªK¾8þpi²Hµâdø[–&‹ê’/I†ÿ¡4ù¤ŠõëK“EuÉgV¬ŸRš,ªKæ˜öV¥É¢ºä+$íυ°¬ƒ‡$핺ß^—|‘¤=©×ÒA§¤½º4YT—,’´W–&ÿT±~£Òäë*ÖO.MmiRæÃÒd7ŸôlÄóJ“E%AJ¿qi²h\±~ÛÒdQ]òub–&‹&‘é7+MÕ%_ —&‹ì’ À›–&‹ê’,iÏ*M>#õ˜å% ù—RYޑ“+õ˜]àJþVê1Ë;f¯fü…Ôc–wd½ù[©Ç,OH‰®¿–zÌúë’o)üÔc–w¤Á_K=fyÇøù¿“zÌòŽÙjþBê1Ë'vñÇAþRêQ^qÌù’ŠÙ2òE€â9Îîc’ë[»Š›\¦ð›[¶’½¹•¾kÕÇ5@B&†"Ž=©®Ÿ§¸\‡˜n¬üùK¯ë0j›ï÷æ꿶ï©-þªqŽ 1=_ôñI÷ãæòBWü©“캶çېŒ%­ Äø…2àMŒÅSÉì ìi¥xAñj’JeÛSYrÛJé[ÏlT´R×=gN,1mىÓ{=cIzqfE1PñSŸBÎl˜¤˜vKÉaÊSÏi½7}qœ¯9‚Ü ÒZóîþŠ›x{͓_‹ÿ6`º$ÿWø?ýD%m’ñ<üáuñ°ëŸ +·.éjiñìÕÇoî¦~Ýýº¼8¸ù·4Ä´í¥Å¹©ÒPIZï¡õp©‚9©=4Ç¥*—;÷h¦{]ÿ¨Ò8ý³ýß®îéÇ +þq¢(Ð +óp?òCüךÐ.~¸¾Õ)RS™.îý—þšÇ¯ß ý·¤Ui©´ó]•Ž»pq«Sž„¾. zÖwðÃ-5pðÓ%ªvbÉ RÜÎ8&ŠÂÒÐÎDŽRA(T?Pà ?ô¨¡Á/cKÚӎ©P(‘gt Úª=ë؈‰‘cBŒ«#k0Dr=GE~Rˆ±üˆH¡ã©0¤[ÒŽ1¡'³‹t•ŒRŽïÚP–AýjüW¡ÅÄMäñ¨¸Áµ6¦.§]ë׳DRŽÑ`*˜¦]ƒnT@TíhÏGC8Ú_ĤָÀ:Ú ¹uTàš±4 =fMßF¥.c2?h?=/p]Û§UXÚGD¾‰ðCᮦ Õ®wiã[ÇÃ,x—\Tl9¨X>I$¦â„Qà <ôËۄUkðíع¼Ma¤1#ðÞ Æ¡}ÒSÉs|¶ò>¹Žë21G|jç9ÆZðLu¢À`Ÿ’F®2NhT(w&ý¹âð¨ÉD\í;Ò¸•öZ+&a" +ýÒ½$) +FÔ0 ¥uðàߘ‡OÑ ÚP(æ $#Ĉç /›ï»˜u?"QB'Nˆn˜ƒ˜O kÆÝ: XÀ‚Pŋv=ð’å\òHHhâžo½Ò™,Gù¦Ø9£³xAaàcc1 Š|^HèbŊD¿dE²lHΌ!óD( (k›‹ûí—!á²¢WÂË+"ÁµDÄz=EB`á֓fÐ`¿„9•÷¥±KñÞD´“õTG¤"À|Üj!$ž‡kŸð@Û‰E‚¨´ÿYÃÎUüû,ÕÀ~D:Œ¨Kht€¡û<5À¾Z¬™!‚ÅÑz‘ƒ 6Ä£ð²NTR=7  ðá) +¨YØ¦y5@ è>IŠõ ÐÉh`„Âe¾×õ”{q„ +$¨$$ÕÊL”O‚GŒ\,Û`¿ÜdÞ6S%’U¤á´8Ï¥x\P]awèX -r#š øa°E˜ +vÑ heØ0? +ÜdóLàÒ¾?ln“,.ñÛu¡$-5m¤Áx"‡©nXH· BÙ¬!ò=fN(ÁPj‚dÚE²FÓÑ!/%ú[ì-S÷‚€Wca14Q³ŠÅ„T(„¶ É =‚^ìÿâ{5ÐWÇ2ÐlÈ^°ð²¬k`“"¨,T™HbÝ$思~¤Y)ãÀ@€ÒÚpc—0åBï³:ÉÊ°š>áÚá]—,P ˆB+cX²{0.Ö Ä^j²°‰)´$!4eÏÇ.k[fØܬ¨Âà‚=e"Ñ<(B­&¥Õ$ +dn±‰Fy¾4Š”'cz‡n$šÀ§[4ÚFroÑY#±zà²ÐÊü°b+’äRßXVä’õp±!4¦T bâÀéP“yu PÎbMŽ² ,¼GðSâ…ÄU’-8Haç g¾˜3 $ð‚Ô‰¶pÔ€üœ„+áLÄÒÃäF†ÐÊkÙJa÷­ï²»˜Jû ¸†!'¶ ¦Z63µIÆ#dv ¦Œ£¯Á;è…õÙrLGANґÀ¯`µ$¢“Ï8°\û.±š @û¾8h.ˆlO„½X—1²&VAÈ09x‘ã„èhÃÜ;žz$•\GÁ‹‚úCphw!t.á>öèà „8l䊑ÄBAê©#F)È´ÉBç4 ½ÓÙÕ <SÓaì×ÙCjXÿgæY%QLß%µÐwñh~¬‘^H2 +ƒa•ø¦¹ìô%ºG×"“hûmì;› YY<ŸÑ;á+øj>ÉNd¥|ÆvEÊÆE!降Hؘ—ä2Xòk!W!­‹$ž!œ꓇Iû…ݍ„™ Ÿ0Ïž“Ë» +QÄTEx ~–µ" [8^„ÄX8d0 HL@çɄC2Ddíàï !!y„ 4$”#*uʑèç=…8ãWO÷£HjÈZ­a¯ƒØëH©Ð’· À 4ω*hm±bXOI,Xk¨L¾a*ÝIg)!ó(¯vÉ+åºÂè>©Tn̄t$qK<¹´a¶‚´»Î¥Æ^{]1;ÀVÒ}´!$ µ°#¥’³ì’´Pô÷V6ÎÀŸÃtâ>!uJb~@Z|æ*²=¤³Yw)—Y’Qi÷°í¹îHq(Xʍ›˜'éӆ¹Å%Ýu®÷èY^8lŽa†–ÊÄìʨ˜DäI°ÅòŽ%c j¨O;!ñ´aÜÉIÉ5„9Ó‹æºË‘âq™Õ® E¯YoØ|7 W!6!Å܊ç—6Ì­"î­sµÂ¬ Ài©R-moq”%h¥Ë<Ì?ó…0)$OÔühâ*¹Ð"QxpHy׸Bõr€Câ¹°ÌX —4̨U¼}>-ˆ4p°’ëA@A@LMmHé“ýãRé„ÿè.>ñʧÀ¹Ä~ŒâèŽ<8ûI cÌ3F÷¡Ô¹X±ˆš Œ¡@ù"9"pÞ"ø9*+’8†‰Ñw²?聩°6–l·’…½b* Šç2P“¥€ ܏<yÆÈÐ'Ä' öŒÜ®4yàV-ãÀ!’œæ‘ÅgÐegìLXî»<:™(G‰HËœ#̍9 ÇØ@ÖÉæ'w+HQ“ÀbOšÝ¥`?´ž0.Œ\¹W~¼Óžb§Ò’×cãÍ7ÊMŒŽáՁ·!(unC²=~Š¥¾¤BÎãy{<¶!ïÖ3ì½Jچá•“RƅU†BòHne’¬*/"aVîÅ^Ê$Ér»lB)åÄæá*gR@"P$»°“¦…¤¼PÜŠái‰KÛ)î51-¤ˆ]ŸÂùÀo»×'ç(ˆá0Ž¹àËz1n`äÞ6ƈž'†U!rÑâÖÁÿä𠁞r[#Y@Š«xðh£0Žd a”fX†ø‡ìy}ÖvKT[c\_³RHñ4ƒ”G  H|àOù>ŧDbàvèŒÏD‚i1¬F.›R—@ˆ8„†â+óü8µ‡îlèÅ$؆ø^șa ÅøʓéY«b’OٓÎÅ +ˊS§ò+áˆzÕR}íîæ×ÅI©211~tt¾zyw@m[s§´éÐk¶F’çBµ.*P‰ãi’ÊP  RLÃÒQ°QLJ<¨IŒÅ "0œãˆh;™¤ 9*D‚+&蘗 †sØcOP³*¹¶Ø C4*bǘD1ݑèŒÏÑÓ°Í5Ì9 ô¦T°Ø?0SÁF¨è©ÌÕâõP በî+W|@XSÎÚJnÕ°Ÿá5Aœ‚ð½Ø¾؈ÂTاIº3¢ßÜ.I2Rƅ‚H‰§µ’`ë G2ÄT¾PCŠ)@С+…°ÜºàÖÉ?ñNГù“7ç÷Oì(t £»G†{ .BK Ž–} •ÀYMjK­x § œØhãn"%K Ø#F|yÐ^KÊë²âEVò`š…7¢N…)Ä([Kyé3s."׈ 7 +X ²-1áw:J‚…pœKYŸ#ê5V š€ñ9AàR6¬€ÏIéZŠ‰¢ÄÅ £HH™¢µ’’7”&!8%0È"Ræ‘a”–ÀE¦…²1À’Cq þ¥=IHðĽÀgčLFçˆ3:{N*ÍÄjv©(–¤t]Ò"É\"š±„•ì¦ì«ŠT‡Ê dx8^hZéG’úT¹Ê$̄„ŒQ´`„ü‘$ÂÙG"®I|o°OZ‘D,  Z³Ý&l`KÄOü»€-EÄ2úœ Ä8ãJ÷¦’mrGaU Xð¬t Œ +•’ºy!$  ¡VJ]$*‰8Wƒàć2Kð"‰D¼Ž *”d5œ¿` ¥’DÉ\Øö~c÷ÙHtÏûDÙ@¨Ö&) ‚IËÀLÄPKöƒð‘–ˁ'N(Ñà¡aÁB&_°[ +Š¥ª¹@úDKR*v fÞ»Šë`ŽÃížïr.5!Ñô);¢Ÿ5¤êçéÒÞ2J2*ݚR‰•,Yoœ}¦${6lJbüHæ—R³E¤Ý¬¶#f'Ðãt'gH$¼)1n¨à’n…Êqª‰.ÒÜ8ÈH47ŠÔµÔA“†ØGc/ß]FJÆež¤Te¥—¬;¶’”lÌÆMI̓d‚)5·Œ¤»‚õ>'fw£Ô®SÏÙíÏSÎ~"Z—­,¹…”xÆ_À6Å ‰fPâŒ3siÀê†äA§½å(ñ¨|kJUˆ¨i?’¾,&„8Ì š’Ž¯evYÃl qg+}(^'ë÷"‰çÊ7ÉìsÀ%=NÛ³Œb‚ž«x± -Hm –æü¾/5&åX)6>>H¼+„Ï|"Í·S™‰"9 /€í;7´ºZ_‰;%eqÊÇ"šÁĤ¢ÉZðÒR±ƒ&ÆõtN"³“`¤j„ùp¹T°ffÀ\Ee̦,ê¹PUÈe,MQQžk]R"ÓãkÎ^XŠäÈK3ñ°ÄNÌEÑjøcµ ]©èÑ$i¯É(€ª%R£[UH¥î—Üb_¼m"yÆÈJBG‘P97Êó#øbÇÙ֏r¤ô^Py¢Lå'˜ \œ!RDU¹¾¼ .ta»T µ=JЋ·MòŒU†â3óSDÒ!+ 䙓ép[(¥J»­(ªurB„¿šëº\]‡ä‡¤^$í¸8J)å3ÌSoV*¸.IiR> >stream +%AI12_CompressedDataxœì½kœÙq&ø½þµ HÆ°æÜ/Æb€ªdÑ£YÊ$K#Á0šMÉ=æ¥ÁfK«ýõ—'âœ7³’ÍnÉï¢ë•ØU‘oƹÇ=âüÍÿñó_>¹ûâÝ¿¼z’oÃÍçŸýÍߜ޿zñáÝû¿»ðÍO^¿þæëïô£_üø&ÖÛÀoÝýdüoþúÕû¯¿|÷öïø³¨Ÿ>ãïÿèþÕÛßüèÇ øÇ/?¼~E _½ýÀ¿}ñ$þØÛ¢ï>}ñ>ÿ5þ×b¼—ËÍÏ*o¼xûÇ_ýåÿCŸÇ–Gfàý»oÞ~ñåÛ?Ü¿û¿é[éæI­ù¦Ì|ó$¥É/ü÷/ñêë³·n{KòjºM³MzŸ~é¥È—nK ¿ùôÝËoÞ¼zûáçïß½|õõקw¯ß½ÿúïnN~ñöæ§/þ@Ÿ¼¸ùí«×¯ßýéæþõ‹—ÿFß¹ûIýݳ/_¿¢A¿yñá&êÜý$¦ßÝóåë/þá›7ÿòŠæ#Oçß Ò_}MØ1ÿ.ðþ»Ÿ¼!Ð/_}ø@¦6e&O?ýíÿµ÷…fϏþé¯þð¥, Íà?ÿؐ¿÷՛ïÿÜ<%ގ1ÛMõ6oÞûÇWo¾zMÓ.³“渭7OJŠôŸý{™†'/†ÛPBÈS1Ï\«`•šxBö§}iMå«?~ùêOwóïÞ¾Â|ݽÿðK]ÓBøô_|ô‹o^¿zÿ«·_~ DM±Ÿ¾ûâÕkêëBñìõ ™(yâúoüã‹÷xõv»×ß|:¼Z”ç/þüêýÖÈϾzõößýZºú¤~G¡כ˜jºiq@ÚHæ?Mo7®Q1"kB¶ÖÏiuöþË?|ùöïž šÀرîÿþË/Ö²÷t3ôËíØþ?íÿè2MÀ‡¯ÞÚhǝ~ºm pûÓ_rËo¿8½{ÃkñµÚ7oiS½~÷|ºþÏÅ7_a(ø-ÝÏßù–þÙ?ègãw?ý }ø÷ïß}óÕOÞþþÝçŸýHiÆ?¾ñ’Þ¼ùÙ¿ü¯W/? `ýöËo¾üðêöŗ_ýø[PÑß¿ºÑOéëò'ý÷÷üßOùþÓW¿§c¹(ôáí_½~÷ՆØ!/Þ~qó?_¼ÿêSÿüõ‹·/ÞßÈŽûù—¤O^Ðd-ì öIhiÏ|E'_’wΚøÈ ÛGŸÔԋÿJ„ìÕÛ/¾vìúçYçø)(ùç7ÿòîõ—_¿q„;ÄÿÄÞ}xõþíÏÞj7ßóõ¿Þüã»w¯×Dè øh-òûúÿ4øˏ5@þçE~zñúõ—xÿâ«ýòåcøùܺòÝOÚE/eÖkñø‘7vùÿíðDÿþË·_ÐW„ê­™{÷æ+Qn~ù¯/¾b0¿ùl{sá­¿#"½á'O>Nžc¸¹»¿ò÷ï_|ñ%1’Áž½øâÕ͇w*¿þ33¸›û/>ÿìŸ>ÿŒ¸e¸ù›ßݿ׿6~GýäSæ1¿{ôÃû¯÷oEú ՛Ǿãñ7A[¿¯Œåïß¿zõö¿@"û/7?{ÿâí^ñ˜ÿ€è6¶ÿ“ºB )d’ijh¡‡f¸ ÷ឆ‡ð,’0S̱Ä[ìqÄïâ}<ŧñ!>K!ŔRN…$„–ˆŸ§‘fºK÷锞¦‡ô,‡sÊ9—\s˝ؙïò}>å§ù!?+¡Ä’J.¥ÔÒJ/£ÌrWîË©<-åÙçŸÕPcM5×Rkmµ×A×]½¯§ú´>Ôg-´ØRË­´ÚZëm´ÙîÚ};µ§í¡=ë¡Çžzî¥×Þ:õ±>û]¿ï§þ´?ôg#Œ8ÒÈ£Œ:Hî$0Ž»q?NãéxÏf˜q¦™g™$æÍ>ǜónÞÏÓ|:&õñ.ÜÅ»t—ïÊ]½kwýnÜÍ»»»û»ÓÝÓ»‡»g÷á>Þ§û|_îë}»ï÷ã~ÞßÝßߟîŸÞ?Ü?;…S<¥S>•S=µõñ4Nótwº?NOO§gOÃÓø4=ÍOËÓú´=íOÇS’þ›¬âý3Âñ@˜N÷üsG¸©óÔJ£Ö*µ™©íD=wϨ7Ô§õížz8©§ƒúۨߕzŸi$JÑhÂ|Fc{ žh¤÷4ÞIã4úF³@‹Dó‘h^â ãÍÒÍՉ›%„“f&™æ²ÒœÖYh~ióŒÐŸÑŒ?мŸhþïi&½È?V‡–ŸÖ‰¤KzB{F«÷@kx¢µ¤ÒªZÝNk\[ùü3ZïLëNÛ²…úŒvM í‰{íA;¥Ó~©´o +ížD»ˆ6yyF»Š&‘ö×=í³;ÈàfKûü3z‘2íÇHû2äg´CiÊi¯ÞӞ½£;hwÚǕö3ÿ$ÚÝt|Ò3Úë´<´ëïi÷ßÑr¨ƒt2 +Lç$Òy ñZL:C÷t–îd£šRdY?vоÏ1£~ä }ŸcF‹ð‘ƒö}ŽÙçŸ}ì }ŸcFÇc;hvdž%<ùêS®>õò!Œú[»òô«Ïxü!Œ4%WŸ»«Ïýµ‡0ž®>O¯>WšÍgۏÌí¶‹išŸN¢SèU¥#—é€Ä§Z{ šv"ÚvG4nœ:Q¼J”/Œ§ ÔLi™R2¥cBÅh1Š) S +¦ô Ô ”Ké–R-£YJ±”^)µ¢Ój¥´* R*¥4Ê(”Ò'¥NJ›Œ2)]ªÄ‰Å¢HJ”)-%R*¤4¨ ýõíÊóùg _áñxZâ÷4iÄûi`L"™ ‘\tAo£ž˜ËŸë;Þ뻊$üv}OÚsuGû#;Ÿ0^?w9Kö<~ÏõslÏ5 + aäÿ>BAΞëÔÇÐ)Âx†•KœÍd¿d¿d¿d¿d¿d¿ÿD²ßUé3o”ìHÇL<ʀG)ð‚~ц 2ßçôkìôë£ÔË$C• ©*žQ0•w¦²âNÃv*¶èm¡dLËTzdj¶èÙ¢hLÓT–dªº™’éS6¦mL +”¾- +Ç4ΨÓ9£tM¨Ó;£xLóŒê=ÊG´hS?¦÷N§ÐA–J»PB¦…L ("ÓD¦ŠQ)£ÐF¦ŽüFPɓPÊ{¥–"ÇN‘e‡È³úÈ’ŒREºÕGºžä˜(/ɼúä«Ïž§þœðÜûsçÏô‡èí÷§oO;<õð”³'˜CºòÄOx.~DÊû–Ÿ¿\ÊÿˆœïRþ§IúŸ ïÆ ÉÿŸ+ô”0~¢>ð ÐuÂøízÂwÒ 7|ÛóízÅ%×úKtÃC¿ã7–óøóQÝæ{=ßcºþlòÄ_éùŒçü–·£ÞÐ9voü¥‡âêpSÜözülÐÛ±ïîŠk¯†ÈÎùº¿ÐÊáû¾ ß~´w¥K÷K¿Úû>Úó>ÒëX¿¥×ô•^§qóÑ9—Ï¿£›ççß¼ÿêõ«›_àÅkvï„7»uT¹Wõ^|UñUÉ¿&÷T˜ß3áQXe†Â¯*F;E¹6|Æü½$MÂÎ ô“&,@K¹‘à]åAÄnêÔçŸ ‡N"VÑ\ªˆúËqä^´˜“ˆ)¬Ëˆ6„Ç'Ñh²ˆ7$‘XÓD·é"þLÑpîD(:‰žÃšÎƒˆðAô(:O‘ªˆæSEÐj¢<ªè5Eº]ˆµ¡“ˆh¬=@ä¢E•pDb’n"ýéò èLS w"²öt ê©hQPT’PéF&³Ë´ˆŠ\DجŠT ]´­!×­ëN4/}Nò<•ç)*½@šIR×E᷈¾¦OÃÓý±ŸéÏž{HÆ'Œ'yžúóàÏÆ:ç&_͸=éðÐÖ Á=ûSΞzñ´Gž~|£ý>>áù„Âxøë¿}£Û·™Ýª˜.,Øέ»ùí` s´l»u`Ù–…ÀlËJ`v³ÐΗ]çÖ³ìîŒ=Ý°“§[NسϰO,$i`?vì?Ûs'ì.ÛM;ÆöEóž°.°}á4‰‹ºøLì At ¶5dQ)«Xš,¶:°ÝáN”Ï“XžŠaí™Ø ‚h+I\Y¬E qU|»Ùx'Ö ¶O°…â©òX¨…Å0ȦA~hÔb"¬b&䇧H– â$Ýad'ýy*σ<ªè›–#Dü)õ‘íVO…¼>-x”ā(=éð£;ñÜá¹÷G#Œ§§ëça{–Q!lO<<éì¡múùgùð”GŸúéa\µídþU~ÀøÆ0þ%8™?`üãFŒê¶:‹4ý–ôê–ocíó,Îñ‘T…nˆêgÜ9®_®X1>éõï¨`ÿò›¯8êôÝï?hèͯ¿üÃÛW>H,åõ©Åì±¢·iÿ'n>½«Ÿè×nìÿ=ÚnCOó¦ö[6ÞocÿöwuJÏÞ»m5¦Ryòãíh!ßôyÛ{üêë_y¼…Y[«½õ—èWoß¾xóꋛ?tÃ)TA³†üèðÿÑ@Ñ1N¢K<}!‰@’;©†ƒ”¶;RšN¤`<<°O’–S<»Eü±]ü¨ì=‰7óÙ6aZVØ´-{Òáɇ§lOµ‡Æ²ô²¶égöŒÃ3ÏÝöÜÛC—&w:ht»^÷°ëwîÐÝüYÐõè!ÝL´¾Ã“·§žzxÚö˜NH+xÐ â®%žëŠ®/âñÂx®7>ÒáµGס?^×]_×Sñ?݉÷§‹G¥ˆý?> Ïh=¥É¾§=7iïuڃ•°ej/>êßõýDc»cç·ÌÎ_-ô‘ßtÿŠ¡ìêþü³¿fè#»²‰–ýCÙýùgÍÐGvOø¤ÐÇs!ç…ðqƒr¸¨ÒÊ5§Ì•ÿRޘʣ̑À‡ô–Û|Lp¹ÍҕGùÙ*déöùTÁñHÚã#i<’|äóú³»ÄNô3‡û…Cþà®'Œê9¹|ú•g\y`Ô&ŒóÊs÷ ÏýåCnÏé»>„ñão<ý®aüÎßùãŒ^‹]†^R4äh—¤U–Þ=*Q«L}BxϹѼˆuó"šñèI<‰èo¢û<Š ^Eõ+ªg±"˜ Ž4up¹ éÏ=óãÉE£%NìA‚‹pÄíI‡'¯çóÏÜ_¹ÿÔGžvåéLJ0!ã;<Ž3~Äûó—>wûCïþºÏÿ0n'+Ñjtšîè=Ð J´‰˜;:)|B"mè*'áNvþ3ÙåEv3ï]Þ¥¼y¯©¼Ëˆnéz¥i•®S~ªFIšd9xçvßܹg®B·ìð +›Wøå8ìÒýºæ¿5?íîŸcýS}tðÒÉó`ž:øê‚ÖY7Õ'»çŽ8ðŃ×܏×áͳgnýÆõsxNÏÓGŸ‡ãC÷¿¿CØÚ5ÖNbÕ·0ÿïúücŒßç‘°~þ½½ ®$ŒŸ‚ùž¿ãE(a¼>ú=Ÿ0þ€q}¾Yýã™ÞHýf»|“ø +[gŠ­ˆqžHã/}ðˆfù¿ +­ZÔјoJݕé êïÝ’3%õþ—j©9<ª¥øÜý¿U+0ê(ù>7ýo=fÿÑm+—O2¨n¹äfRÈèY™Œ’ÇóùggY<–Ãs=ƒÇsxðœY<÷´×W6ÏÝ!«çòܙƒ»-Üî2Ôî<Ðî2Ìîhwj·»q.]7÷ÛsþCëspÝ\sâ|ÒãdëÓØúœ8úïŠñ@&ÿÃÎ÷]~jJî'¸ƒé¤~[|êìðŒp±ÁÅ Ô,ð•¾2Á;cå߁ý}’ùýØÜ- rqïúÕOfs’Ÿ‘oiA÷;1º³ï¢ÍOéjJ—>”ïøÅ¿”±Öú(c%ðY94Ú1—ãîtÜݎ»ã1]T +¸Û+H8w›¬¸ Ý inÈÇrmÓ#™¶æ”äD‹ÇrmÅA‰Šê¢\5VՀU7@–’kK'ö™øŽ¿c¶í–k{–mK"óe¾m½–oëüùžûÓâÒÈ·˜ržq{ίÓGùõYÆ­$þÌG²nÛG²ny·çY·âz}¶ùðÖ.Ó²íίCîížyK?-ûö2ÿö"W'ú#¼õSiâGÃç¾ýçPÝãz@À·ÕBº @Rʸr:ŸŠpsYÅ#‹÷<^Î¥}{  Ðpö±ü÷Ï?Cüh·™d‹ãH³AЬVβ*Í;Œ3ޖÄwžAðvÃqhÁox÷7¤C»ö]ôê¬ãŒˆøÖHg‹g@ëp¥mERÜúö0*ÚWƒ<ï×IçÅZ²¿Cô—0 +Câï-9Ýñ±¢»çcºíè·s¤r­m £Ý’ +Ø×ßzƒù6¤‘}°#R?ézCøû0X ã0$þ÷֐ÃÐǁΏh•ÞbO‡SوL‘^k0šÀ™êðcàïgŀv  ‡8kçp*[!ZΧÏ^¢˜ü}hɁèŽ!AoÏt9ÒýTZ/³Aàtø@·d0œ1C¼ÝpZðAØ7¬ûRƒ¡]û.zuÖñGF´ŸJ€Öa;þ÷~VˆeHìÀYK‡SiÝô—0 +Gbï-9Ýñ±¢»çcºíáTZG h±ƒào‡Åa8PŽÎÚO¥õÓ_Â8‰ý½5ä0tÆq ³ç#Zcýé(`“Ø5HCg¦‡"ü($fˆÄò{Êë3÷‹ P‰›4ÂééÐÑïD‘éë­ðåZ4MÌ‚JÞèÆä"šu„$˜röŽ”AbOÙûQÚm‹¡<. YGH¢J­4ïHæDR‰¸ÍÂQ(³žôzC®Þú»öšö®ô|;b¨ËdÖ’¢J+ûB+ÙJn›x¾wezÎ&Z:×ù~¶Ø|½¤“L*÷õê$¨5史bg:’ô®Ó™Ìx±btðB¨ÓWì¬ñKeà°zÖ-[=ëÖ¾zÖ+[¿sYùÐ-[?떭ßwԚ¬_¶–Ö¯ÃZZÇl5υåCÇl5­c¶š×µ§_}þÙ´i¾”MuéﭒýLî)r\?ú‡Wò­â?7wlUø͟>ÿìþeWÁWÀUý~B†¯÷ÀÓgñ݇©Š6ý„ ã·e¿½§o??ࢿÞrÃ?ûÜï ú7¹Í觟Û[,dÔÑöfYÇê%mèk6×á@±µ½~¿ ™6åÈco‹¶×˜­^༠+Šç—XW[tÞç¬Ü Ò› +HGx¢½3ËåH®Áçùü4MÄ«å4.š&hÆ/v <çMoð‹¦Ih™5^6nÙzÙÄ58ð\4½à^éØÓoNL´>6±×àÀs1á ~Ñ4QýQËeÓý6çGZ¸–‹†œþÛoØøøt}w`ÏÆR/oð‹y$zs»lš?µsÙô‚›Xx®Á/šÎôb~dÂÓ-§"]6½àÇ&žkð‹¦YB‰ã²iRaZO—M/ø±‰…çü¢iÒI8Âè¼éNÚÉa—‡uÁM,<×àçM*ö­_6=nÙïyÙô‚éÍÂs ~Þô$á³´|Ñ4ÁS ý¢é ~<ï Ï5ø¡é¿%‰óWIÀ<ŠŠŸ$B¦¿\„l´„s\ˆ‘Éè=)P"<^‡Ãó œ*N:ó»&W’ ”o/5£3$±Ïf‡üÆ@¢.QlÓ$ÑL>A dêU1ÁqdQç>Y³k&ô…É/wbxYš#àL³ °Ü–ššrñ5(Ò?f¯ íDZôeZݤë™H#á+Ð ˜o_M-½m옞µY¡ô(Ú¸ l©¹b¦¬C»˜‡—ÎG£Œ5NmAtÌ[öZhÝa>띌L ícÐ73›îI›Di¦“Ê DÆØ¡£LÍ®  £Ñï½ÐØð…I“ú®ÓÏ{â9MG1ñ¦/‘R¤¬Ñ…‚…&ɱ¨üXoÿK?FJÌkÖ9e”Î磴p¤ð˜ia^;œç‡•ïLL㵑•Y*dÍ9¨¯¯`픋6b Ü@$!‘D£\4˜Äº,íÍÛΕçö~ª˜ÑFªÑ¶OŽâV# ôÒ¶ªìßHœŠ1Ÿl¶‰ŒDmqÆ1 sºÍU[ì<Œ¼àEOá)KP&x¨!+<Æf;§…!áÅN1fÌ +l‘4ò“ínã8Œ‘Nl#Âð¾$g‰fŠ‡N\\ð„¤<Ó ·ýCJ €lêV`jŀܽ“a¹ó\‘VV˜Ü>·ÓÁQ_†Ù•‚gú=á¾bsâUŽºHÌÔ¬-ÙÐ÷I8º!–j@à4'Ô߃- oÞÒª¢¡é6zI{¿݇4Û-g£)c½B)@šwW7èûYäÚÇ¡·´ð–&d'òŽŽÞ?ڊQŽUdƒHj N´½aÿ±R +'6%-¢«Ò®Øn›oO†!ôˆ%Ïe:fj'„¨pñØ:ÒAšm›w•æ”¬J4¥§M,L¨ÖÂ_ºÚÔ·¡'’€%Mńþ9±'±Ç¹;ۖ +0š’$¹C®Áè +q‘rËî|t¬¿uâBÜ¥6 ‰ïÁ[§d—›¦Nï‹ ˜{:{½Á8 î8 …µV.VÅ ¶ŠØ§À|ã©O®2;½,¦EKÆ)³¾¤êb@×,+8àÅøHör€$áYÂeizt“æåü,[íì)ËR˜íå¾layÈÊм‹Ýð‰è¸1ˆdV³K—=˜XÃ@Ò1Md ^@JØüT…èGîº Ù…€rÚ\V3:gA؁ÙõTss]_&ÂÊ"›£nÒÛsà+UY“î¦þˆÃ,ÍÀrw1ÎôY¯B‚ERcy–H\1•"¨f<ŠZÉDÖ&i±ØԖĒî’2‹ÙÖ + ²x—sÂ'„õã0³-[€c4‚O=Üµ9“xfˆŠéýŠBËXX÷ÃÎ^-€ƒ[³ØéE+j){"^ÞÐe{s_ã²·_LÎëmÞèèBŽam­áÆk6›©~Æ·”“ò4‘ÝÍ£ôæä7_ÚÌÇÙàõè‰zÕB5çOI$NÅq㔃m¦ }0¦È~¶”aþÎ6‰Å4(ˆÝ7Û裓ŠO³³o"PÊ2UþñM”ÔâGpð#ö06!µ5)yúµ½ ™»F•¦íƒØU‡pÍXUÁªAw€/wJ¶ÂòKMóƒ3k‚Ù…½–j½®œV2Ü«Ä¢vŸFt”‘ôn,“>Øàöç+ƒ>Ðkµ»W(ŠæS¢¯@“!j+SkxÄìF@Ûå|’SU%žg¤€;£V$–Nº2*~9ËV¬Ù$BÛ¦ò†¬óâH .‘ˆŠ1•­àÉ`)¢©ÝyGûd<±QÃ)óqÄ¿ÝNU­S6) Ç®ŽÑN*^.°CŽè®c6 MY%´–Ô1ùMaeo^¬ÙOl™jfN’‚鉍)šÝÆŽoîïaÌêôe'€½\M±Ë\yl“¶(Œ><Ýnl…ÆΞ¸¬Ø;̞Uf@ÀÌ©- âmšíŽóº½ìh‹‰n ducž[GLB5]ÌNša΁èDÈːºB1€­-³¸ÊUÅâÃ.‚ÞŒÌE %àˆyÉQĊ`@vªÌ|¨í„€fæäш¥¬ràK#´Y]QÒßlì¡vóv$SŠžLŠûþdü,ö€H1¶0îÀ?:‹Êör(&,áœf8Í!©õ”'w®ã9/7#mYZ›)0¹j±`× ä.³›±ÄXce#܇âhå€jg™Ý-Þ¢V=†Ã\ÄÜ©Ëîg óâvÃ`y®IW¸îæɪêÒ6ë#››näˆAê¹Mz@Äß2݁|n}ÒS.À\H|25ØþóÄÀd'Hœk›ÁÅpߨ¶ÿédÍhIª,Úï™7H“9j +Ž¶Òâ,šµ eÒìdâä§M|­jüoÎÑS´—%"…nÔÓï['7#%h'½¨ŸŽ=º!{1òÈó¸<<|Ü^.ʇã\“®r÷bÂÒÏ*Zé +4/·èBÓ¨ êNRµÙ1ÛçA©,Å@î0áS½ ÁN½ˆl;`Ö^áUˆÉ"«"Lt¾o^>¦f> QY½­ފ˜“ͦ=•b,½¢fô •b.mhͼjÐóØ!Èݨâ‰Oº/t…˜é8pnÀE^f†k™´JÛÔ1OpŸ.LŽÎ6VfÄáîvž=…ÌK5ç—y XKyc®°ˆõýe3D.ƒ{{#§ožD®[†—…Äa®+Q©µ³u ð÷:Ê:­DZïj lvê4‚õŽmDµar3Ÿ[Ÿt˜†ù¨À>*Àî@’|ÒÁIyí±B¢ËGØ/e¿hÇßÀÌZò"É0M°ÙHšŠY&2´l-ˆ0‹„àRâÙ؂o¼¸›±‹DµJ¼¦ž 'òI¯0®דؾ£ò5•ë0^Lº Újc1ö±Øîju#dE''ÛëšjÅÓ˜¹ù´[”kX±Å}ÐþÑtµ^+v0Èi'NA2&ÛêÄØmÎX]\Œ°TLOÁ„ÎiÖEÆìŽhi9+В…N¸·’æzBÀÕ8†¸<ÅÊ Ù}÷­.Ù%ê¹iÍY@Ó9[FJæ6š¤@@E׬CJ7q€#HÕ$Æ3ƒ ˜l!7LŽ[Þ¦<æ¡uNŽ‰y$;+$,ø”C.J 4:å0F²«Ë„Öäû”E°´ cðÎl‚~Rƒ!+:-˜NqTí4òòWŸ6o~ôã›ßüOשÕ,l"6ak°sÇÕ²nD0‘lâ'ߢF„í: ‹îÂ÷#~Csßù á3ÑJˆpÛBW™n!’9T5²?¹¼Áˆg—J2÷TB°íÔxì…`F˜£LSà.Ì;™Åwôè6°[yÍÂ3Z‚à zä@t¯s‡Ö Ì.¸ú€4ækîSoÇ[Ê^Mh+¸ƒwd´LGb3ãæ]&Kt@t34ÛÓ$"+VböT_s¤ú:0S*örŠOAÈ/âhè²ÓrÄN«íþì7Z,Vƒa^-è?ø~N‹¾:ÁíÇIKVW„$œ.Ù kê¤Ê°Ó3TjÈó(É0uë~æ¾Y{= +›7Ø–ý¡6Û¹‡î殼o(izéB{ñT„>LS‚eQ˜¸ HqD`Ul‘ób2Ǧk µ¤³ózdJ›Zwy!²«ù,¬"ó#-ՃMS!v•lrÛT +ïSn +ç4ˤÀâó ß´§ÒMuï-ý@þ‘xQu'g¶õ9Âl(ÁÝÝ ìšÑhf^\ZÄ]§ör×8sÒ<ƒZü0[@–†*¦îpü+Ip±s´g7ѯEcá¹vtVÒ5‡†Õô¢sCZ-‹`¦XÌ[Ç棱ACa²õÚVÒV‚úØ5lŒåèXX…Å,ÀiéÞ „üÊ _í¶˜œš†9íàÉc1‚Ѻ„„8`W($»À¼PºEjðPØ +‰Žti«Ê¹Ï Þ²Ù¼DÝtxŸž<Éaf€{!/Å6"¿R#½ƒ2 +ŽÝI&’m1ÄÞ^a*”\ˆçGôÑÙ^Zf gCKÁf„#V\0´XhŽy‰^ÜgŃ1&%yül-~Ñv–ºµØÆ| Ž !7€—0wMËP)ÉøœZžÌ *Ž‘‹ž~ѓ¡ñEύ;ôM•Ú᳘lÎX^²-éR…0.cÿ%¦Ëžü¼'qdÏ}?¸ßÿ ®19zéI3߶٬e,«LÔ#sbð‹žd aõ±' ²>ƒw³)HVfÊð>At%QhoÖÞ/Y/ªJ\¬ˆÏ=ŏÁ›¦õ^à¹ç ?‡ÿE Ð<™­1¯L`f´q°&ã“H·0 μZGÌâ¾%­|ÏIïuÐ9Žð¥]`fÊ£éÄG̕#g=îtªÖÈáƒÑâNMYb²Úmt›±O¿Ø'¨§ñ܈+2±Ïàl ±ªž‚R¶4ƑÁ^=,´'­ªéûó‚s˜êªÁÖª‰™œ 0ÔÔD@DÅʔ "ëBÂ-=˜aÁ½<^kÆeÑØŊàpd +qÈa°Äý¦&]Ž8„eœktw™2ÎaßËÉœ¶öÊå|þ*”³u ;°j͟‘¡ CSâzŽ¹ vÌU=¦¯ùÒ v*omQ=ÈÀ0$«ŒÓVhþßKÁp֔îŠë`ñ4xåXŒ>ßÐL¥<×Á]#©Ž¬ÉÛÊf¾R¾s ’eÓFè+×JX•.xªoà¹ÙQá÷¸ +gçðÜൊ¨ÅšgB x…”\fD5ה­u«þaðc‹%›? +/{>6;£„kq£æqáT|Q’¸{?%…¥u(nJXÐcs͌šWáV¸ŒYaÛGÝ*4¸Úžˆ•YC¼ã¶ Yðc‹Ó„‹«ð¦VS‡ÛÒt7ILší‘Ò쯫:uM¤IØøÐ ÇôyÙÁ ^5oÜá¥eÀa ”À¡¥mv÷ªE©±xš6G2²±ë\ÖÛayöu¥/±?¾i¼ÿT´û4g1;íÅÃàå,^”! ¡Ö¨Ë¢ èñð«jÊH– ˱ó%ú×µøR»U ØÔ(&?7¢¡äǗºdÉ—SåðÅâÅØ¢²ÁÛV k&|ꨂ OÅ#*<ÂBǖ×UšbX@çÙ-‘›“†p·ZöZ £ƒ«Js8‚Üø‹jªJ hù‡ìobúæœÈì9eÔ"²Z*»ªÓV -GQ¸kÓØd÷˜5Çrï‡K¹VIzŠÑ^-Õ¨vωf –˜¬CËÓ¬s¨5g83y-š|ßþ•ýŒIñ,‚Ï`¥œœ×†2<Ü;°ºéÕ¨x(†!Û|î!êP¦:¾Ô Öe^7DñÀLقŸVá ¿â”·amFj¸×`G#rX•[Jª÷#i" §ÒåU‚whÅ1sZ›º'sÝÚ7xÐb¼k«"3¬%Ï)HZLL`3ç¶oVYr‚§˜ç:3™á:6[ù‰dõM[Þj1YÒ²+ ‡ç« Ó0‹sF ¦òÐåæ`àVÁ]6kî ac…Ašj·Ç~&­èÁ]€'i’fGpí ’‡6ŐoWU›vYNfRD«G@ôåàZ)ÇiÀ ¯Cöа©… ZTkЍ\Ššá–Çã%ËLÌÑòëM) 4HbKÜD¢Œd{´/àl*ÎD‡³íÒ͋ÀGF]ŽUuÐ[dˆµÁx|Í<Ýw,ѕè=¬Ü°âH9«=À7YÑß-®Ò'YëI©^¸E"jj|•†¹³¾±(#O,XöK0g7'[îÊ°XfqË@ґz,_‘ÇN,uïÓÁãøA­ÂÒ0W‘p׋L€ìˆ=³1aãz”Q°À®T˜÷Ðv¥b¡[rWs9Ä2>ٕ¢ì7äåÿmVï’Ť<=²]ä¸:„¥¢E+%ÇBAõTz®±¦5ÚÊ"¤NS§•ºòT4oÜÿԦٌYp‚ҙOÇc¿Ú°:(|Lُ¿Â” ¶²òãFÉj±pˆ„Æð +É +[PàD*WL´¥oyZ€ûªa-¨`³b/¢åön~täÞV.ÒÌ}+R±ªbѓ5ؕ&~'Ôÿ>ÌU8¸(™kێ +ÌD.:w Œd›+ã."[òÁpnË@Ti.‘7&ãfTð:·‡ˆÕÃârYîÖ]&¹¥[u[ç2UmÕãĻהá—ÍkÏ@+ËË*%É ? +íÅÏ*Ç°&¯$fŽÚ-ÌV; ï@W7cMØút 5‚Çê•O˜Å·‚¢·•Oº”Ú±:Pù€ÒajRš{Ý3IÝKwº[Šð*GÅ¡^w%U±'?7ŒÁRhˆJ6Ó󋆃 LŒ¥{!)-’0,˜ YBï%ëAô2TS뻿4y¤ ³I³2(Õ,÷lsƒJ_4*)«$'Š«j,ví^¼ECaِ‰È2>È+Ѫ¸ã–Ëþ!n|¬z^ëYŠ¡z…Åâñâ¿yi†ô!u/–Àր¾‘°Ã¸#ØmÏ ••‘¬ˆ¨˜`Ôà\¼Œ÷l{J«pZ6Ög5¡öŸõͬ¡–%_”="öjl›c9‡LEU¸—ô:ãB±ÁB¨½^Î0ŝ{0¢—®Díù¶'†µn ¡ I °ærJ‚Þ´ª“H>µ@‚—fëH}잩ʊiµÊø¤†ù ¼C¯;Ù^€4dpاG†TOÐeÍ«Yú¡EÍ ;¶¿éǝ]ÕCwªFlq×:0t‹Ãæ\ €¡Yˆ)' *çÈւ5ñ4üV_æ;Õ YijüD ¿Ê¾ä®åi„ìÅgõߗfOεÁ¾ÝSܑÏRR3©¸•+lõRk âfð7÷1“¥|Œ”ÁD ¸’‡ù°iY#z¸ŠÞÔ@Ùó&¸`BT¦Æ–i-Ž‘Q„fyÒ5Õ#ÝË^„$s˜Ø4g~ê^’0øÙæ0l„À‚iØ\­jXêËÃß­*g=°R飐’°âi²¡™r¤;B€3W jˆà/.äi%‹9ÏEÙJ°É±ÙSJÖ´”*ÆPÍ7Ìç¥ãeÞ{VÄéŽluv¯«”€v—¢Eúe³6py%´GD “¡l]¢ã:UH!“ªÝÄ+"¼ÁTÕÌN7iVµà±—øP¼µ!Rðb LÏ5Ô7ÂÛpìÙЌ8Œl˜ƒ=äÁ +G5,G=FBw%oi9Žóº]&mi°LFÒ|Σ‹«¼^a+‚碨ìÑфe ~ÃaS:ÍÎu”ê(ÁªŒû¶y}» ‰y~¬ßÍÐi~@TWZ%ÍþÁÚ<ÆhzjµšaôâYÃNºù.OÖ"ªD}š-{ŠùôúÜ=˜ÓŠ»ìóÉ«$1ãŸVUt•Ž{¡®ÍÉÈÅ«4 +‚S]Q0Šküha_öiZÅ<Ž=-–:½’XÇÑrGǨhd ¡ñΦxÇPúÑ>ûpؚ¸¤#¦Ý>sœ×oØö Åú ÞDj6¼¥~N¡ß½¨Í# +¸¤*äD¶º£jlÑÍÉ­ÎÝ[ŠSÒ½/jm:8í2›ÅÔÐ\F ¥\ãÇ%æ‹Ùx¾M“r_Ëûæ.’;kk¦S@·â0 ¿uE6o!Ÿ®4¸úR-ð¬/ž#™‘ª@ó^V孊âKÝhó‚oçËWgÜ{֙±•Ú|Ñ\˜Nm«WáǦ/ð¯¦=î¬é?61½fñ5ø±é üÞtóBBǦ7ø¡ ÒÆQ‹þ*üÐô%þç[ùÌ:™ð ~l­WáǦ/虐YTϚ^ðclÅ…›¾À¿š–¢3¨yñf2ò喿S …,—õj…0í>Œ¹J)°c3B‡¬›5ßá&ÀÎvnjlBŽŸB\>›e4Š™`(SÿL|Úú>v÷Ÿ8{ÕèDžK¢Ý1ÔwQPÓè|à‹ b¸ØS÷ò—ËÍlðs÷3K}â_x®ÁžßŸ£*Zù¢i©/P]‡ ž‹®.øEӜ¾èòmð¤jÙE×àÀsÑô‚_4âÍMG½ò¢‰kpà¹hzÁ/ššhyÑtÐ4ы&®ÃÏEÓ ~Þ4ÛÇY 9ošÏß*j¾š¸ +žó¦7øEÓ}Ë©=€SwæßÜuΪª"±UBºŸÏáâ==ÞÜê'^֝tûE= 5#ŽÄmÁÄmá¹_xÐ4Û&f½lº©åþ¢é¯êC\ñ9šƒÈºo¬V‰·&»ŠÎâ¹.[t’³0$ÚÝ·á‚× eɟëše™ôÑU94ke"hDÂP÷[Vœq­ñŠ%éZ,xô;·¦ .·X›˜œuù´•€C Ž¢‰GoÎÁUE\±J~M/¹R ²Þʪ‘/õ6õ4 -ïâ骮­xÕ³,á«{ÙMâç]>]ž¾ˆ…ýcoΎÁϏc·~¤tnx.šæT ²ZÎc¶ö†‹Fjô”7ÍïÚܗºu±é5X§ó®³ùҝÜ[?®Á½#=¯šä]·X*ÀÓìŽ$‰}P‹ä·ê$¹çJŒÃ0wNc ~ÑÇÕâE'‹–Û^+ë!0¾æ½#^f3#“•2\]ÀæT iaŒ>ü¢“«Å‹N&½`Ùi5"ٟÜ܍Ê3-kys"³!@å¢3‡0–Ë÷ÎÐy±C¹®Yå&ԗÁE쇦ypÜÜЛš² +ûªê¹Ã W-[Uaߑ ‘$¡© Í9À„+-ȟpÃ8ŒlÁµböÝ®oäúþ¨%*uÐIIÎuo¦8<4®'Âkˆ­ªs49«zã[Æ×Ñ.2l’W‹év—ßÄ8V²’‚ÊᎲi&=ié¢ñß^Ò6â´K­Œ-suãvMC:ÏÁ¸-†ñŒ½=z¦› ®á\2@/ÎYÅ{·m%ÇrlÊ Ԙ¡r´ø;Îðæ}4Üwáµ»6øØïD¿lq_[°ŒÚÕGìk5¦¬â–µÔ3QÖ¶!ºC ûÚvuøÚµîX;À׺‡±Á³=f}˜zãáÅY {(¤ ÑYÜ¢iÙbe‹qØB ïùÒüùÖÜGÂNÚ׫+)4„«çÕ¹zú„Ý°psôÉc- +ÚçWš[ÖÈf\ØÒGÞ7ØäUͧJq#h¡f§¯+:äò²rŽ)/ Îö"Ö9n +Rד¬À¬ÈK÷šú͋Ü#â-¢Œõ1ærŒ>|Î×Ii·õ½1¸¹X›_©ÃÀdu[4,Ôº4Ú-á\›\óÿŠó?hÁ—=Ù;iiIw7­ÚG—‚ˆi.…”‘q:)|,D ãpW=‚žŠæ˜z绽a ¸0벿ö6¯y0±–f1Úg“à7aJìR·ë›F·[á#|¬|%C3;°¤ëxªÖ‚ïÓ¸zr ~n¤åª_%¶M¯_ˆ#nöi4gHñ°Ð‚²}ê{çTO†¡"F¬x´ýáå '›ùM6ßÎeßV·½„ÖÙÖ­Vñˆ-$MCq8{ÚeˆÛvx“sˆÄÉ0,ø>‡-®Î¯ÿŠû#½Ä€Ýa×ür+vÖ6Kø³T3¾[â¸ÿO—˜÷Î\´¸wõ¯9ºsµ½3›–]Í,~[.Çn@êã»:pC<ë€#ÄVQ 3d pÖqsšuš‹kúJ½U 'îÒFY•R8oß3&PPP`¢D®”³M^U‡w%"Ö¢š€ÒxŽ·â3âÜÕ,Ü¡ñ`Oԑ5=NÉo ›Ñ¯H[‘‡Õ¯܂Œj²@8¹sݹ¬ö—ªFw!Xȍ¤ŽhA ö?»øY³"”ÖhِU¯±Àôzi<ÎÁðY³ˆÖ44c>œÞXË®Ï±È†pÍ¢:ú²%é¢x«WlN]ØçW?ÚmsIã^ÔPÛüŠ(»Ú²k4ùK›²uåe‚q­-ë"#³ÂN ÷ ¥ŠA±d9,ÉÁ¥DmtÒË°ª2Á+»5YȦÕdg`±ðÔ-ƨL¿~|IÁŋûs¼"Á9(<š3S®Þð]2<|°]ÍÙ:Šˆ:ÑÅ ¹r¸Wó;¥™hixµD}‚ìÌBpôÄY(¨ðb?ÜRg^GBÑÙµŠ¼Le—Æ2)`Îx ycp„„ó†EhŸT4‰@n·³û#ú^%7ø1Mzµx Žž81È,ñ¢„£“¬˜×EĜÌÛýeT§•PUßK«Þɾwfoñ\z²:Yµ Î9cF¨ég¨ü˜v¾ð\ƒŸs³¼ªA›nfó=kzÁM°ùè1çuÕt5“’¨tgëHÕ}ºÒAíûßþJªýÍÝOÆïÞ~qÿþ›¯ÿõç/>|xõþ- ÷¯þðåÛ#üG¿zûöśW_Üänî8ê7²»BÂM¼ òüæÏü×ÿ ßþÁþtSn~zóOÿn¾ /ýæÔ­8Æê&“„-7]ñœñUwœ²Üøù˜“CҧţÀ…àíêÞÏø~âÍ¿)fŽÔ#•!Kí`v^ #Y‹ãg¿oBbzàh¬æ°1;ÎRK—­ê'и–bæ+{d"¯/×jh‰ ¢-„$xÒ̔¬¹=C›ã +G /Œð&ó,ÊŒŽAœ£Š9Â9¬H˜é +œdÕ¾àRž;kê¬-FfR$Bñ+"Nõ¼Z,˜·ªR»c¯ˆb6‡­ÀEæ×÷ËÄ|„⸥v“N×ÚU=§5͑­ —z`ò Üy´)âMIN¶ˆyeÀ%(_^–<´$Hɛ‰sï°)R¤zÃ4‹éRaÁ–„ˆ~¾yt·ÁÞ Mö:I/"Ô +shì˜ +¦ÿû¼‰ó#”Ég&¡{¦FÝ`ìüŒ¶Ü llÞµeÕ§ƒåß36òªRO֛Vêp”´vxò>°‡Ǥ'4×C·9Â^æ«æ{ÓÓkO[0M|¤8XGÇË"c°Å‚AH 7ïBäH+= »¢h0¥ök­izøú +txñOæߢۙ–몜Tà +…O›H ”S ˜((ñq + aàÜ0H ŽŽÔœJ4>v¬ +lÝNØàk/1d6y(0¹0‡¡»“ßHya¶íV¸Öˆ-¾í¾»*usëxSJ›ØÌ©ÔˆÔjïI}éÇ6û~ Î&óÃ‹oŸêhÇØÚ·ÒÇ_ÞÐ.àłj÷F°]<£æ¼1øÐÙ`8FÉl‰¯  =Èz‚Ý•'—.HÊù¸šo1’Ìðр¤ñ= +\ÝЊ Ìõ!@¯{"ð…TÌ ¾ JØ°¾\³õ-ԊQ”Š"¹ú2ËÈúr,¶[¤‚BDŸõ*6æaҜTÀ›ÊÊ&ßH’m‡3|訃j„À5$€àR6{%`TÀ‰‰¹Sì˜ÑŠ={¹PXÃB[¦::Øt ܸ–€«$¨ °ÎŒ~×P ØЋ ÷Rž ƒP(œëV8t$÷‘.¬ &5»ŽfÔ#¹&Q÷RÖ +pÏ Ø@#X‘ȯìQe„KÌÞ¨\P8†žÑ‚@;G€{ô]Ǝ¥=šnÞä\ß8â*ÌzÅ œ€ë܀i>Œ;paŽÉ0ÇÑý(Ó.šõØà|Ø3˜@0÷a3¸éò.rÇ@l„¢³§ÀÈ®6æj»z¢H(àJŠX…Ù %]Xk‚‰Ìš‡_M0íU³\³¦×'§œ Tñ¾TöV I +QQ %²ÞdPŒ'0|¨(Cs¡Øn­ùšÈ&x‘Ôë¼”¬"_-UÛêšÉ± çHzW iÅ +lšú“å¦KŽW ME4’ËCìg}#aM +³kŠÊ?y—ÆypMŽ× ¨ÊÎy.§Ê¨ª`V11éíÚ'[©Ö§Ÿ¦ï勅zn”&à®-&"‡®t“áyšæ"ðiâ…¾@Mfd1óQ̧½Q6ø¨‚ë··Y§ º5)Ù lÌNÓpLïD«j-54Þ8|F£âRÕX€]…—™\¾|”8}”Ðì‡Fkk¬ôj/$ý±®í½­ƒ\ Ïv^þ8OZ§=¨‰pqAvL œÎfqþ“ÀtshÖóWg† B VR'FÆ8«Ãôe¬Ä,È¥& g+†¬†*L!'ïê pꯞ¾15GQ0PGê5b„®…pôW£J¬³êQW¤ÐÛf]÷kςNPÓ[)8 ­ØÕí‚Vç¬éý5NN[h¬tUÐîy ä¯aXlÕYœqÃ]|2™L‹z+•–$9椂 §À50QûPºˆ:,Ö©„?¹–e’u˜Rˆ³°f‘9qªë}€´R]É`F‰O£”€ kE±l@æ)Ha ¥Žh]Uˆw ôb–ɵ`Tâ2»f’¨JÀ¶…ÙÖ]ãZe!Lxn.â2°)H¢ÈÖ·!ë5½tã¹­ú]a᜶ɂ5›Ðð‰b¾olzšWë^ÂÑi¾õ¨œd²•¸o‡ª0bLÛúµÚËÀ"@ýÛ«öË{2p´4m\ƒïé؋R匁]Um=dØ +¬);Pˆ>0s¸M‚¤(*0•òŗ٠¨™Ñ®#Í£´¥K1(§^[‹j³;\ufÝ0@œ0?0°šŽF;L!ÅO+ò®f~DNh.£sn9ó¢Ð‰½`,yÃ,ñEÂ1ôjŽ¤[<¡ì¯bHµn Ç1Œ8AذŖ¬ÁRNÈU"6S k¿¨Â§Å ã¨cAބUF.Á rW$xžÉíC®¥Ï0 ï&™.αï!ÀbßóõË +ì Agú–Õ-Sö¤²97”°òÝÉjdžU}ËÁ‚4QIß1H…ÂUÜC…q…™¦34!Q™^?ð¬#;} º¾<ûÍ5,¾Ìk`çHŒ¿{®xY&Àn=‘]x2 ½\S˜l“u]ô`‰]ohÔA²;þÃÁ=2"Ýì8rÃïś1µµ¤½5l÷i›’ÃQ{4  D×åð2̜‚Öº{óèÖàP"PğÙÂ&&²Ç–+)(Ö yë]*;Ž ˆ³.&Ž\Ìæ0¦Ë”.—I1´…<ß }ƒìØ!m§Þš UÅ.QÂR.6œ˜×;HMZ¡7g¢°0wq&¥y›K1pˆF¸° +ïšUf4=Ϻ¶ÔàbÊ»˜-ºõzº”yæÌ&|óû`*AkɘÝzRÒÍ£ˆwÕÛlR\Ti¶M÷N.Ù.ÍYŒQ²¥LTÜD=ºÓ„9n89¸£a¸uAä«i䣅”[¤`@·óª®¡ð¬0oòõë°äd.ö\¾å CçDøf\ӌkwh)ׄM++Kt®YÖè&Ž¼”¸5>2ÀÞ®©šŒ`žc“@0Uõ—ŒæDõø½Ëä$K6ëƒéøC¼´ÆKßFa2XB¥2¬gl´J6“1'¦¸Ñ¢¬ž8Æ 7‡LZF\Ïhªî 0öÅ•1«1éi­¡¹ˆÚ7Êx`ÍI,cõÇŒjӞAtø¦ºé¦7ð€©—èŒqé8ß«’ %kÔb0¥¢À@¼&G€ 4YԏMô]û!›0*&}}9%[ûŒ©o"îÙI|¾Ñë3õ0º-R +»(<9­œa½²“’ +ɏ‹›„Ò|À#ÏÃY”†¬kÄjÔºi\Ípo >z‡‚' ‹ ×0™ieaX€Â(ý²^κ.èVƒzÍÀ«5ú²¿X#ÎJËÙöØ\›œë.ÓåU+ê‰6e£jA•#o:S‹ã©Ùf6Y¤³šVž_¥6і_ë ¡x¢o¢ó(°ªšûl š: +'./v­™¢×¸)VU£³ 1»)—MP–X8…s€êÁd™ +šô«mª©lƒ€®[pW v ̒ïÁ nþ‘,Z@hY˜F†d;MëI~Ù4M‚OPÛêºJE +Ÿu3.ˆÁŒÇY?ËoÈ÷/T;.c'r±Ùû©ëzZ­SAlâCÇ •ùLã‚©Ñl„šä@IíL^rCð´°Är&À£Øn* +µ.®JŽæÀ ?m–´0º€R¼18,æ·/>7¸Ä½h‰-FýóɃ£èc.)—;â)„t½qx0Ç:‘™^¾®š_>à@µÑ­F—Â=ÊÅz#×Ë¥³X”Ë>¸ÍI§*›ŒƒÙ¸qõÛ\6ì&Åß Têa$¹*¥¹ÄìÖa…­0Ñõ8.»ª¢Öˆ*ö>·÷ƒÚ…DÓSü\™13 7Í<†Ù•*sÒ#·ñ¼q8üau%x)\¥T†ãp3PÝ <“ØÒ „c§®’&µè’§Ñ h¤°_Ð$£")5ˆ”€©\êÆٔ+Ge;/eŸœìë%Y¬DœÍ_V«+s5àYöÕ±“¤áµo®‡T+øÛ*äh®91é¿/²AO¾îJ(†Õ"T ªä L­^]ÇGûæSÊe'õpó}ãpGU@ ›DuÚ›Éä.`ðn«_ªSª0Þ<ڇuАԁ€™`ۏáÊN‰‰K}±VCmß ¬æ#—Spº‚Ùç„/®ÎÌ8Փ»À’½ڽÀ!% è¾ +,ÀÏ×ÃÑzù´-Dóý&Z”/ì¢|ãARŸ[ƒu‹A-Ûà;ü§E aø2´ippûV=vò€ó¬+:h¸Ã¶ë•µo nA €ˆMÂ@¥¬ižCÒmÜÕ±ôüJ‹¾:ÉcCÌsúÆá1"0_› +¼¸Ð™åú²i°¨Ô5B` †3#«û0¤g=ð™â{êT–[!l¢Œ‰ªi¦ÀÙá㌒`¼L¬H'Ô³Zà!€ˆããªŒï¢ k¥æ+ì ¢â¾1¸FÓ +^dÉ©ºú [7˂ˆ×'Çàš¶Y7¸¹2ÍWVsه½{gȽ{¦^1Óé֓¥®7RqñE ÜӉ[æ墹†î‰ýÒкÉ Gˆ¥e¯`Äû’§õÆá5+m%À<À=š‘„)ž#𠇧w‘UÁЬ1†³>œ¶c±âJ+üXž–Ùyr=\u‚=V•1{¬Ï7 àÓâJí@×ØÌÑÎ[/¸²ÇÅ¢îWJ(m ‡.Îr±ò= šÕý5pãºìH˜á"¹K.?¨‹·(¸À]û5&F jûâ> \j‹‰&Ün ôªeÚ)©TÄH“yÝå¨<F,¢™®OKšC7r)u(u’GrÝîbBm°0ÖnAÂöº-fG0%ëa[L ç­z Þs§~ê"­yßf°"Þu¨l¢0Kö×^D‹š˜ä²6„zúÚ7s•I°3BV¯Òåáq‹¼O8Bvh?4À~:F °0J ?CùNj±i9]¢æ¤böÇ0 íÂî!Ú¶nŸµx/”ˆ£ÎÙ)ç©h%ô¾ä‹e#ÐÊ,\ê£ÙŽ/1ï<¼@ªn¾Yp±ƒÜ9°EWȘÛ%ðˆyEÓqLŸY^ÄÙûfÁÍ‘,è-¸-»è5™v³n,G¸¼k†—ýÝܱº°D.®x\ wV֓ß,øp1WuxN‹¦3˜M•Ak¥8­àê.p›+XnÚȈmÏ^öá8yfŽØÅЮf¯¾ÇNZLÍ£#¿øþö²‡I&µÝ]v`i;S²†˜5ãÕ ŸÆ–Í(W傈âÄûµ½œºEŸ!´æðnLŽà¬µµ†Ñø³Í­| îpXÅ"Šö*w +„ÿ0ÚÄuîÌ.ýÁØ)Q®,sNö4­gN™Ü"úA@¸kaZÁ9Šl-rG–…WÂ9YŠ3ñ¬×œ<څÃ~:¥µ4"”©‹†‚‡Åƒ¨é=ž^²uh ­Eî沀秪šÍŠ=†ìiycp UxSᣮœ”锁ˆÍäƒæ¾š*N`¶bÁ Çnâ +ÆhÀìÆÂ˾ùŠË S=™éÁ‡5õZ!Hº™œC ¨,=°ËCÅõ|Tºe´AÓà¸\‘Ç6Ú&¨ìÁª6?Ý=uü²FbÈ©L)7î5 Ð- ¸ÚPÈ·xG½†Q:ˆ’a÷¼\¶©ko‡†Î8†îßïö&ò\&.„à¬8j}ÚmáÝn²b¥©¯jµ7æ?ÕS‰8¾« ƒïþvuñFãlczÜÚ£Ë 8b˜§»,ëJÂâx¢•x +µ‹WYc*x(هQN¢$oÝL§mŸm”µÏ<Ø"4_f Dbs©)%• èbŠÕáR0’þ¤Ãj ÷r_Û«è Úûs;¼+='hì6€ÑrR, ˆ ÀW EÏ&H Ãu %ªPùc¨Ù1(qºìÃ"|¬Ž²†îyÍæèÓ-mÁ\„œ"2Ì;^"eÖgqw×KRƒ478WJÂւ§þ°OÓ]¶ ‡‹./<ÏjhäÇO;Æ)+KUë)ˉñ0wr…A4bx.8/&´H݌nÀ©¡² ¬”8ƅ!Ny7sì3»Ìå(ö­n +†ä©¯ž\ÊlŽ“{Äb6ÑS%¾4Ä(òË=õ3{ËpãÂENÛìC¾rëæR†ÃÊ;=]Œ‹¨›Š#¼ +Ó˜¬ÙçËe4HEàÅ^†µ„1 xXªd iv fzŸJáМš>Æôý|9ŠeïgÎgHäx¼Ypã3 ¬C€s°[÷ÌH?=û 킺ðHìÁÔ8s­•¦ÃþlôÂýóAo×ãì–w–V°bà–˜g¶ÒV‹=ìÞ[¦Ø½[‚\t̖4y°Í–°ÂöÆÀ9ÊÂPG/Ãç&͍éh'vYŸÛà*rcÙáÛ¬ ˆ¾a`õ|IËò™Z +Ã1Ìn ‡fÁ¢ûz±è¾ÊY_O>òg~Ð y4t ˜Tî‘IÅ àåd8œI#\pƒ–xŒåõ=†yԌw=ˆ)›þ#‡‘ž^`âÒj`ÈfÆÎ1Ìj0Š¹u8@h‹/î.%ÖeA×Y#­^ò¬<—±»ueìA–L*7çv#:~YÍÉe¡G€Vø¢Ýï©«j0!„¬0³.æßoÝERën³È:îA¬Ý1XâkŠ+äƒo)Ï6¶σ׃j< +lÁxùæËÍÝËaU¥Ó°4 Ï ­Y˜nk6eÍB҇y…5³ÄW”«Æe쩄0"‘œmۑŸÎÎ&î +÷€.Ë` êiWàv a¦àå†=uj*³ôàÎui&&Šð®Àe[ +ËåÆ}GÄfôø3`é†õ“¸0;„eDO:bÜ´ALO…°’J ªëÑulqm…5Þí RcÌFfLH ã–y½9+g2FoÇÞÓ],  ¯&í@Ž˜¢P>‘Œ%u÷ù½ˆ‹õÀÚ4“í6„"1PMü°pÌâA Aëzsõ€Ëà6N‰óÆ‘Ð0½p÷-¢•Àkµ>˜iXâ¾¢3351ë‘cë2˹¹:ulH vadçŒ$Í’Â%ëhîœ/;3³b(’gb;¸¥V†âZµ'f¹ûzŸœ±õaã‘sZýÞ`5›D=§õm7ϱ1.Q€9™À#÷¯;fìøMš¢™«F`÷AŒœOç;“w˜»‚ÖX5Ý0m0V¤qŽ=AdzÜ)'u@á ÁÖ¡!ü&êÕ ½ÂÙ1La5q­„Àæ믨¢ +«fʐ0~F pӕ§FÅß[s§©ác ¨ã_†P!i™(9&ß·h"¹oÜÀÃp-Í_G²ÁÕJ(@3(‚z8Œ¤šëp5€ \‡Q•ˆ§,¢yxíØ¢‚¹[0Ó©f¡ §’;`B­bÎ ä¦b›ó‚ ±Ö袣| çgô6¶M‚П®¶|ì8–ºq† +ƒV·•l^,¨¯ +*ÍÝzÝ©lVª†Å뵚âòEB}×"{ò:(V«+oñ¬0µ êéAlPCü¢v`šãwX …ÂáµïxŽÝrÛQVI€DÒÐ1OΕ㞽 œOB±t'Vu°²:—³–ÔrÒ9ÕP»Zן%2½¡,ŒÒ²aźT;£•—p˜¼ŒˆiKDznðèHXÁÅ»Áª(iµ-EŒ»¦ñÙNè3êTu¤N‚­t«ä”µtN˜î&î+^rB(„µµi¡TÁKgÌìÑNÕ7oh[™»2ÁÙºT¯}'M‰UGVb^,ה¬¦çŸ O ς$¢ð]‡B€Eå >¥o̼Oßí̪ÍM;…ÁÆ|§Šˆáß7½£ˆ¯N¢@pŠmì°í2ÑEÁ‘­dIµ=%Qø +„XÞpߓA”q[Ò,Á«%&ÙÂ=7øZ)× "r%Kñ†`1½aÕ@.zWºubEfh°³eóꚼeQ'jTÃDT%¹ÉfaZ0‹EÌ*ÈÔuÕn©îÀ·<šìÌ5.–U]ª{‘K‘ NœƒS"fBê¤Î²|@œY0ÅLÄ:]ϖq'Óáw¯Lh[Bn[Ù}/¯iÉ"×#:…M=AiOæîÅs…nÁõCXL™YD–$3‡û©‹.ô“ÁNÀ-7o§ÕÃW-â‹Q]Õ1äfd¢%ÓóB±¨0Ë›Ý +UHRÞ 5]âþQï©»®©ÑŠi÷jœ+U“_V[âV¶‘UÛ`u| +“r=ŽiA𒽼0 €á®v[-Ç♰³ou8åÇ`e, ÛV0¬Ú¶²)µ¹ýÕW’—¤¢Y°b¤d‹6´à +Î&ŠL+Eò2,>Oȧ›Kf´8a·ŠÕÛaSŽìáêSõ nýºU0-ÐdÄd“·à1T¥á¨¯8=”ã! jÂú²ù9*_CXJ~âÛêBÖû€u­úJъàú²&@±Å¨ZDZŠëëÓir@ÑA ÅQʋy[—š&Âû÷Ë´@e 1ynðê…+E$87|1}A”/Ò¼gÈÅê´4ÏXÙ2'EÝ +˜œœ†Uò1vZÜaÈå"Ê°9e« Q}-TÓ\^ßzîÐ.ˆÎ%sÖaQJ™?Až±…–”ÆÜ-tqzqQƐ-Ú9ÂǦr¤›g‡Ûc.¸[ÌC@£°ì€¡™cQŠu%K%Ø +\·m6dO¡6ådˆ•JÎrËÁ•ü¸eð’MڜfG·ü£¢…LCHeké]c¯ ê•Rªç:¡cîM°‚ÊEc$ÜO1Š¥/ÉM£ +4‰©¬dÄâ)ǵ ÏnÍæ â6W3²Ç¸7 KiÅèÁžc•/®g¡ž5èçµóðu¯~$ñͼS:Ÿ5žõ‰ø±,ª´¨Šæþ-ÛOËä/›g|›Ü µÕ”­ºÆì@DÝâŽöç{°³Ü¥ðä±2îü/(£ÌËà.Ègí¡G$#.̏—oÌÝøv³ìéNt¾‰&]-ßøDÒçZJ6ð­UJŸòB:4ò${NŒ#°ÀÝ´’¸‡óªì„›Âh³JJ>cºYÝÃ>;Ù+Z:]ŸV+‡w¦%$Š™Àš¶r«È/gcõÁe°ò¤úæMD×8znI¡ÁjÑmð}ZÚ;g Crà~i‹”ÏsÙ£{®ƒUgñÁYmç¸'rŸ±LIb¦×ëåO¸[;`|°_KÕØj¬mw[„@º-–l±ù[ю`!œR?©mžjä~Œ­XEp™/«ÛTOg¥Íš“»ͨj™W½Â`¹ï ´Dù`ŽTÛN l=³}WuG,û™'iZ¯&ÝSlÕÈYœ7b†:sRM!YA);BY­YNΖ'káêç7µŽÉŸ/3“c˜²{ûxºµ²/áUř@ÒpB'í?[÷Ê6C}•C21$³xàªd¹¾ç0  ‰ånÀL¼JºWw)¶'…Þ.ï8¸o²¹m"8Pºzy.ɬ+k6Ç0šs"S\€ÕÈ-ƒEìXKÆKŒ­ÈWv-}+ۛø&Q;AëˆK\®Å†[´¬4b)² ÞÜÝài$_eʌ#¿@ª ¨Y!ì¹,Ã+ òá1†üE§^ „}'jÀˆˆÍe‰z•õ:ñ1/Õ+en¬8²‘®Þ¬¸„÷¨æÏ@—ÆbñÄn©ôàù`#ÚdNg Ák7˜o?ïî`»XY[ëVk¢À.’ÝÌÀ» ŠlÙsíùt³ñζOÔSàýÓÑ:†Mâæ= u¦x9žtlÞâEäxن¥l÷m§_~öÏfDNëÀw ,!¤óD ¬q‰RÙ³Gþ'Už|ï‰œ‚îõ…ßVÀÓc|ÓûÉìyF™ÕÓ2`[é|Uš!ÝL=ë¥Qúr³Æj±,r+ÄÅ@­;òÛÎðQÀà:J^Ðr?ô~.NK9߂ú*4‘W‰ñdUó¹¿È/d`5@.kp ¥XV±d›U¡K¡.«Å±´ÅÎõ;­š‡°4OxkÁôP‹H䗧ë鈧é àÊéª<Ì7†ƒÞ¸h¢[CWRR¦…Øî­`øÒùªK1|MúJEM*Zˍۦ¿[Ù!¾;9zÊé"r ·—òGßäbdÛjmh_ž J—÷:¡m’d·È­ÌVÙC~r%½ pj“Õ lÓ/NY2;ûʅ«[†›iaIëbÓE„I¿Œ“íìE|ø݁Od[zb±ôªw4¹Ã1X‘ì’Tß5›†Îa„¦7l强ǻ1+‘Ýþ”5|B`æÍêZûlÃã¶ƒÏ +=8Ü ^iJòâ¹ÛÄw¯Giù†Þ¢Ñä‘b‚Á„`×1“ŸOš~êºIòæKT¨··H +…I€n³–:ÅÉx^l;ÌQ‰å–½j‚HîN„£Ufb颇 n{—›¬s—\èí,½>ŸTK«v¢º!5ø†ÿ/{oÖçq¥ ß;Bÿ7Ž°¿h¢ßÜ3[W"½„g`[aÙÝꘘP@ (¡…E‚’Ù¿þËçl™…Å*6!  OÛäaV¾¹ž<ësœÊo!è U‹¢ãjŽ V.Ù@Ä g ‡;¨ŒÂU+¹qQ™Ys¯sÓDÖꇗ› ¸í3™¢rtQU]]¨- ÐÍo%ª|gU­(õ„‰*ˆV€å!tË!¢$ۚ} ô¦*­*ÅÙmiK›3ãRWϱNÒCf¬©`jµlÓÂáÏbE5 ǙÛÒC´,‘ %73°™“·HP»³7ïø|F9˜ªP¸9È9;sÛŠ2èuÌ¢'ñURv¯i‚oŸ1Ì0‡|ã‹EՔ9Ä={C ðì‘fb †œ3®]öÓÅ͂ؓç;ª9)Ù[ˆ§çRØ£T}Z¯Û$yf•ñ3àè¦Å+\0«ŠšF!ˀ Z)ŠÉªqI¹#ÝQϨ§$’GéBÙÀöQ9²a.'—£b³«­½F]sŸ­[ɟY]^ Ù¨ª Á•8QAŸ4†ê4é¤z=mBÁž?obÜ5\¸Ÿ€+bº?ó¢W†ï=k „^¤s ªçÖC—E”w 5§ÉÞèuã‡×An¸å¡ó³c6§I +t‹¢U{­íìEƒê +!g(O ’)“ ôA ށ"$ôftAf‘ÓÒC +»¢¹ |0M.”Ý¡TdË¢$t'ƒ|Ò' Zºq†,G.ëØ»Æf©5Gë(˜£=߇gÚ$H’Y‡—§¬¨XI¦^»AjgYAk\ǃ3úÐèB<㉝{rª"µÄlÂw +K(+.So7Y±iFýÝÄwÅÝËÁ"ĦYÃÅ3®ª±0ÉÐéÁ‚›zȒàƒgu¦’ëÉzqd^‘gÀš4SĬA:K(g÷NÃ7¸O'"VR#KÔ”)oSf1isyÑrÔX°Øš¡¢ZLS›ªq8wšÕ_Šœ#¥¤'”OVÃS3C ¢ÍêÁxÕ«xà1, º°×˜˜S[jf󪁼ö‰rãåëGd—¨Ñ5” J©"Ú恣Úì †0rúôxQ½ªA‹e«T2³ ǀ´<‘¦½W=>pá‹#] ÁÚ&¸;U+gXŒ¦‰ù`wµ é³0¦A‰ŠÓŠ×èŠV€í(Šý¦i4Xá¨I<öU\f¡`ŒÀ _Z5&5‹ ì”cb$d±3%©*,*¤Æ‰)"b2¸*¼P€ÚÅçôŒ0(Ç»£,Q¥½j´ÃÒA™酗¡!LO…! +¼9Òö‚n¢RՕé m8IY„*e +í{*ozþ“-ÅðEŠ)£Y;T·N#ÊQ¼F¶Ñ>@ÁµX4tiÊjOÞªÀIÕÖ³ 1k–è͝Ø0ÉD)¬‡ æ8õ¼Œ=åi;-ف#!!®hTb ëf¿MM”0ÁD ãùõfÀ #ŠG¶(?!×ñ uõŠ}QèNöp‘jšè.iƒy“ëƒDNSK)pK*r¤ØQéy±ªÃÑ›”xs"ºè\òp:Çj#8!Ö9ð‚ Ü‰!-m‹€¦ð+mª«ª¢ll†=)½B:hZõ£ŽªR¨vÀQ^ Ÿ2îAe(­gaCêÿLËì¥Tåd dø¡"Q l• ÅŒsŠFËñO(’´˜¡Í–tEL˜ñ¦åƒWÑÂä¦âLÉ +PÕ8pÏïÃb Úqvߧ…GÄtyjK‡‚2ê2 Ÿ&ÙÝ­ƒÅ°Buߛ–o!Íˈ’÷/ È(ЛÆäƒEŽVê“bvعcš4Ðp„«ù>ÁDëtȬbt•€XµN¹áœáŸ[$ç佊Åj‹½ëÈèmøÑJtå #"´•3F««×‰~m%c™å?hçÖm3ÞJ:áøœX; =ðÆØD÷ Ì#c°3R±ì‹ L^ŒE«xVqÝ +Ñ«ñiÒob6Ïuà€¢#¥ëÃØ=iôäôÁ“:f¶Õ‡gq&"A}ûSD9:ðj*˜ ˆ‹™T%Kl|Òcb6ûL`ë>‡SC5c¶ ¥‡4¹ÔsÓìho×O`Žè@5ãЌ~YüýX‹ƒ%D›Å@ V„­˜'üw*} D§¥|¨ÓÎ9[­!‚…´¬f.ì}°@ù!8ĬuÐ&æƒe7s¢ØÆl~®•â”q”“k'¶Kë¨`ân³*ÊL§€Ç`e`)ÅÆð¹¢þ²ÜzÓd)rÞéYPƒj6›AˆæºïÃÌöB0¨™8<¨±_T0ÕÄ,97˜ø éG•A†)" ž%ÊÅ´RjEF@túÆO…×qøMþÔx4.ªBSMgiiÉeôk#¨&jRGn±l×$˜ÃOò·­ Ê)—Ô«zJ4S*S%á$\¦E¼0Êg‚BAc×$D{ñš©AŒWa®Q¢„d!b4?ԌYè-ü.±iUŽ45+[hlðæªK‚xЉŽ—š{± Á™¶7²r<žÌƒܔ06agjԞ ãY‹†¿=Íb%þ4x8™8Œçäh>%âނg"Ë7փÊÐqvX?YkZµEÖ#E³)ñV)Ûü¡ÜM0ŒÁOÚ³Ê÷ØӬϛç >g1_“-Ìö‚&ˆ¦Á›+ 0’¯¥SU¢ûè–U§iaQœ6²OÉæßUAŒéS "u.†|û¢Õ ‹V®aJ"‹Åf'Æ ÏYM`¸Uè›Ì¥¨Ã’õÞS ƑÒ5.:Y1yߦ\k½‰è¡(ǞKQ„Å°U1iªÖ‡÷UaœH,6 ¸¯† ŽÝ·©†ˆ•©&mçɏŠ:…ƒx>½UìƒÈö¾ Vf@L願-%›=J=d‚ÄkßY ˆéj…Ïìå­nˆZ5¥úŠtk=¨–9›×jS¨] ’–åÉæ¸@ +Îß´À·ª1YÍcä²åN×XDpÒ¹µxŽ3Ô2èZυ‰Aä|`Ľ¤FS…ó™ª*ú:uK%{˜8P…`½lؚ¼ê•½Í65•t1 6*{ƒùi"bâøgÅŸî¼ox JÑ ØôÕ¢~=!³JˌÇÎn¬À?ب-zc›˜nª™Ëð +T…wyz1Tµ¨ì;²w@4²ÆkÉüLӁ›éÍÁÚ2Gâ’`àëpØRÀõ›Â–EÁþëœ =P69?@#ìˆè”jéoœ¢â‹i(\ ­@ ­4›Þ'Ãlœdq¯>Xž`-D° ¯EŒ °¸b²…W¨×6i€NExtz~ O_ʘ‚ÖôKaRÜŒ+Eúp¢ +n)21‹¨'ƘƼ͡T“Y´†ùbubH`qN÷l™Þ²WOØònU]2ÍCÉ®E‰SŠ˜ë& Z_Unθ¨. ZVÚ­ÒMãáÍz±'ÖÆk5c' ¢V¹[DÉÿ‰2râ ’lY_B]])«-'¤ê·Â0ˆyÃõĤ\I‰|Y†W+,ŠÌÜü +ÛÌ°XK–Až´‰ê YPËÇMq˜£€. ·èôüz+‘«?î¹bÚ^­BF!c¸,T7 Õ±:!º@B›”65g1^™Tøˆ¼LaE€v¦Ø¼IÁG¢–1$®(Ä¢Åӈ~D¶CZ¥2˜I¯6žcµuyGòVX:} à§&Ë QâažSÌԞjáy¤/n<»zÌëÃò®ÈÉ +Š¸c¹ƒ4k8z~ƒ ñÝõ5šÜ5„‘gÅZ¨7' óº©L¤)½EÀ¾ÃŠeÑ@z¨vxHãé…ë,Ž†L@t,&°ñŸ‚} aÀ¦Ç9ºeØû€ÿ,‰ï!NõÐÌÕi×✞¢½.‘¡«Í TìlWÁ$½Êjc©W4¤©äúĒ` +”åU1©#eatSžßM3®),²·èеì5 §æ=Ilqö®€Î­-˜´ÌɄ™õ ÿ»¶WQ«Áî'Œ# +4h€PÀ~Zœ³L‚%Ò¢"”ÚвU‡Ãž)q(è`¤Ù£­È%т_aŎZáÝXDQïE'RÞ¥ôP48Y E‘KhoX Åð`W\È¡ZMËÏ À#ñMÏ×l†¹^JFö©HMƒó§33ê`RRH3.V|5Η8.Ó Rù&.ðÒFxl4k‚ð²1DVå¸h\:f,M\4HÓh$¨ç’õ*25®M/ZÕ©)# œlcHôYyD¡ÁVÃîÔì%s2~yUž ò¥&ú”N:ltêÃÁk +Çé ³I +¢Ü"É8r§EnV¦uò¶Àe$‡Ú p#¹ŒTx•Ëgä͒˜/- kþ°&EkƒƤ)„à ê}ÏFˆ–µMîEeÁìü䨕…¼ˆ; Å>›œ42¯ŽÄZ´ ã;QLxôÚՀO·ê“áubQC§R¡^E©ÞáÙ*¿VäRpQ¥SÛ­Xÿ£”›sŒŽas¢"Àƒm–„ÖX&±†¬­æá—BŒZùwŠ)°‚Å“ã&ž¨rŒhر’°2V±j~.Òçîô!ǐDy¤t‰¼h£H8B7ä} +îŒ@ ‘€á>0% +7ßç‘.™&¦p ç`\Ì!Ž˜”‡ˆFQ0gӀé˜ö’Ó-Œµ$øŸ‚Ê*҃WcI˜ªl0Ď²¹Žï2E„ŠÛÖ"fAC’Û€€CU»¢·Šb¤¤‡hÊj _R»Z‰öC­’‚–ICsŠüÐIφò€1K „/ËëäMçEà¸ÔsŒZqÂ=Ô©”¬E*Æ4î¡V·[+ž)c€2¢=k}nÊiI¯†ÄŠ6…;¤›<"Á'¤ñM–š'”c Ën‘ÜMíØ´G#Zº)dT>iy.ãjyi‹Šœ˜É=€.umà†O–ö´(öÔ0¾òb%<‚åꤦ^Â&øL”€bÀ)ÎiŠ +)*NSm´D€g‰ ­(gŸLïèaQª¾5$ pº7KCvf8òV˜3ŽUØR°Ì'ⅧŠoL‹A؁F™«NïgÅMýdS‰ópZ›}‘âLëELm?†qBsb±–Vd°ˆþŸG _2ÕL*)Œ£U†]G5}­š-ÁÌgs>––^^8áwLÎ MlÃÙ[mÇÐL”BÒ@Él£*¯Ÿ*ºZ¦—¼Ð܃ÀÆ!-Wtߕê69hˆ8•´‘lNù˜ HSmºmøU‘Ãk{o¥f½mÅ«î½f¼)¿]×ÊÎìWƒ“S·*©©ËD»t“.zÔwŽjAXN¡3–k–– @LÐüH]‡0Ãc"·Öd™d.ølÞsÆNÕÔÍÅØϔÏ9žÚ<x8냬¨¿Hç ª¦¨žœ”‰x«O´ƒÈŒ±âU$³L)ʨó®=Xi€|xgŠE¸Ó ¸ÀwRl›£ÅÐt¢†»µjU]åØþR@%¸)®j"p[ %è勪ndƒ:oqäTW³²ráÛ$P‡JŒ’T¢ZPƒJY4ҝë,Mp@҂շ¥ªÒ^O øÜî,+-ôªÊFìs€’ž½(ÂC¶‚è“ÚV$oïVùt7•×Àâ²}u¸Å,5e‚IršÓ:½sÀžp:\µ#½Â«ìFá փ$™bÙ€ ,Vô)Xêq±˜dºœæ³+Nњ$° ±¨¥R1@òˆÊbê8$„ãÓTjQ 5¯•Ê§‡‹@|L{XfØ¢hr¦0o•p‚E_°&/£%¥!3M)2”7›E°Âp@JRÝ +zÉ­÷fÄãSE'2”h@BÅLim‚‹ò¦µA¢œLʸ¶b®,ˆ^T]•ˆÌb•!pN¦j®°iåªçÕ¸”¼gÑ`¤¹¥Ú=’ŸzP Àu{ƒ¬’¼?Òåå€1xùo¤‡hjû„ò:Ó´b‰Z7Yy—õŸhO±©6A5E…Xhœûl¨M™¥mÚÁ²D…ù҂ìavW 6j²zÜXb³‰M9Y4U{J^&甑Z:{‚U睐dKe2o4ó'N&S “‰¸èÆ(¢æ)iM×Æ øÅ4û’&[³7JœlÌ­Íu怠’&O„VÅçŒmØ9M‡Ê`&L²ù‰%™çHéMÙF™yæ“ «(MY8É41e`”Ëåh#(R‡1Y^°ä¤Œhbðg롋»ÒX‘A”g7± l8$ž’™dÇ ·_têzT@ðR&q׸ÜJ©ç`‰‹¢r3 R•Jaˆ‰¢»hñu顨OåÏ-Ã`b–2«@D–ÒÍÂüKÕèbr֚ÀQÚn ^J!ÍÂPÕ¿Zݸ`µ•¨±XBפXnMåÌ%‚‚fµñ CŠò I2”*Õu@ceX¡ÀS®Ó¨4§4‹b”â׶;Š^PW@ܪÁ”W h*rÂÃPd7”†©ãAéÒ/´Ü¬â°:¡ÔNbÕý¥0ïqrªVŸ=ÖK‚]¢M­À^`i+ŸªK¼Vù—wæJOMëeë¿0z²BÓ%k¨©00E92Ñ)1kKm,'¶XS;XV1nm<¸E*;C]´fS-Z`;[At„&Iو²X =Xãدø6«ð3Eª“4«eÁ GU¾æ´Æ›LÐâ5Èr³;qV«™â} š¬Y±:cÝ#_ ö •íFAðšË„Æ—%ÚlÔ¯ÍUåK,„ÂwT ¸,£â Ñûé–ÆZc%”ÄbS˜±$¨Žhxq÷ºiIph"R<¥Q*مê=jÌ^ŒC½EnšG][}ªSéKI–ÈղߛUíÍ# µ;'¥eêÔêè¤7E]c7ÐÐV¦ÀgN«‰ç‘LÜÕ£‹¡˜iÅOµb’¥0UkxA/ÞÑóÑÊiµâ”Bvat!ªH”­úhÕz.ƛ”—NR6j•em[’¡ôJ ‚j‡Æ¹G>èRq§šh‚ùm†²>znJÒâ³Ê).LЈÊø&˜´gmœH6l@úZ5^1:ðœK\mcêxæ—dûU´q*ZóöÑæ±ÔýºPºæÜUf›B”œ”ÈþŸÜt 84C¿¤´Q•”‹ØǤOW^‘˜4û–bì4ËQ`JpvŧÝS5)´5ã¶ÕZ4V’|Z–Q©ž*Çk420£^ÍŒ*TÀX­náx(­¦ºÔHÉÓæ°úcY8à¾9F`¢šCÎí°”‡Q4è‘RÕÑ1BYcP쓶Xb^ôšÖC!•#yÛkìUßx4a@Ñ$¢a_S_ûýșjKû¸"êÄ0‰aàđíS-%zK¥jSѝkã4y†JâŽìX§ÉÆML”LTåf¦>•"¦èßHþ»áAgP "õ‚9á8Þ@4ґhî&uNÃ=©±:4üe"¾P7§Ù nCl=‹ 3­(¨«·‡‚6Ô-ӒYÍB›ì!ÓçG›¹Mq£ÈŸ?Û4N¸ÃØ4·Îʵƒù‹ôK-uÜ(k„ží +ký Ðô­£Z‚00¯|™lTփ&†¶’64Ãui–š¶‘ój뀖£ + zJ?Í°ý6´è«¯èy˜rQNF(¼'ÚòèqÕzwXŠ õˆ-$ ‘:_b ’ÌWI¶gš"ATÔ sâ t{2üȃ‹ “TÄqà–j9Lˆ"’ÚEuTµ%úȵ »Ã3I Ž*¥.E¯•D©SõgS ¢³r9•ó[ìn*PnåX"&jÉ¥‘²þ™˜-¤Ú®Ì…Ò"³Z̈́4À= ?G…’S=Ùzq›%®ÍV •Ec£ +͖'ãŠ*9i$Æ6öàY`B4輸o¦lÐòÍvï`u‚NÊ + O¬ÆvÀs\Ū9s&ÖÉض%P¨ç-•-úÍM¾Á”͐î k%¯qukD%ºYžLy +oÐÀ¾T&Ž 0žkjí#A÷…®»ºGÖÖ݈ê÷D@Hm¡§Uk-Kc  ¦Ô{¿,Yg1ª¦’¡h,‘þÞÂ+15 ÁÖ`o´dcAó·ÖwŠä9Ÿ¬à µÏ +øç‡ 9(^6ÿïTDžO•ú'Åy•»Ö‰¨QX š—Õ Ë è“¿b[&È5 “4|¶d¦{oV“Y€Å¤T}Q ¹Æ5EÅИÒè[Õ? +2DL¢†å?Y9E|ÎÐƊ…PM¡Î¸Œö5­úF˜iêÓÕ#d!g ,„™çÄV§éÞÂRVŽY‰š÷á8Ndž0vS•›¥6E<`}™I47ð)áVÒãN°õ¬ñ2‹Å cѽ>ï*›¡mѐ¦yy¢Å¬.ævLÑb‡ñ~lY¡l±)L`)oÈÀΤìasöä#ÍkLÊ5™œÚ&‰[¤Î©IÕPV½"ᢱ¼î€Š$ËðIn–<¢ €žu~ÄRŒ.r*åkX™K¦–¦ØTšqˆÜCÏhšë$1®­É…4¶(«AE¨¬o†dÂsS°¥±;óèÖµaVO#©b±<‰ä =>Ö‹r\±Ê:‚š_“5D1Ú2·[ô ÅtqèøÎ îÑk’dWRµ±"µqÃn+xkì Y¦õˆå^´ãf0l&ª«i*Žœæ6WBÞ²×] ´†M­ãò¢dœ +v¥X è¦0, +6U B2iTXªÔ4_vÊîŽÅ²` ÊBLJÔ,ù(Öt&¢¢iš3‹+«Ôš¢«|<‡¥fÙoÆØãÀŠ!×&ÄaVñ£Œjˆ&Í\÷q8*×Å`¢¢ÍÔÙà?â„!_BX6¸­jÎ"•.b±|ø‘ú-‚-'Í­ø’ʆ܉Tdµ­«PnbLªV½<6Ëß/‡ÃŲà:S7&'0c…ã9„Èú þ# '-V;¢Ì¦‡4„ðBe"Œ)€qá3èâÞ*<üÁ1ŵ„5h†À(Ö§jª0"‹®ÑT;‹è͜…E{1mvÑØb-×PŠ|³š–ªï‰˜U§—ºŒÀ«-'˜ÕQrØõ7 ú­óƒzXƒVÇq +ºH¯ÊéÉLT°Ï:ÃÌÐ:´Y30TMÅ(ªVf5y³è ¾ŽÁ•i÷Ç슝cöà ç-.:7­Uæ$EÐ-ÙÆv™†ºW 'Œ2Ñ ,,œšÐ Á”®¯r‹žœÌ¾"› +Èt™C¶ S9u”iq²T F²0”÷àšvd͆²™¹zT¯ q³ZOa¾hz…&ò³b¦Q² ¬(yU–Á‚Z/ÁfØUê7Õ¡ˆQ9ae'ÉՈÜTÄ ‹£v!¡‚«¥Ú]1Íu-x(È^mJ„QÕx›ýdDÐJKÁ +ÕQÚ'Lº> qš«RY j“jÚ¨Ã}& + Qåø7ëAAD+k·á›:è¦>‡9ZCv$VãYiö£P0(¶6Ȑü>’¤B8Ô·v¨šYbÓV¤‹láRˆRºÞ¨*b>®¹ Õ(«S’ktëb¶ ¸cÅ7â&^³ÕƒäÛ#DׄEM·@1˜:„¯Q,¢¾ + ʦ0‹¤æ+ O†°ÚfHþœ Þ²"'Âq…q¡±RÉSô„IÔ8²z1Q@Kɖ_5$X P Paì€çTh¶EÃ]¯jÕc–-ªsa߃õ0‰Ýa›-Ãu1˜#›Æú~»œ=) ³­GøPÎV½Íø ¹h@ï|öŠUç’V.öÖK”õàEôi¢ù]5×Dµœš\ ^ªñG`´ÍMEª !4‹Jáô¬—I+" á‰ö †³uÉLiӈ+Ô@'Ì2ÛÿrmcbŒ6¶a4ÒÜxö‹¢*XfGÑÚ«Pa–iÙ5AÅÍ՗Î¥*Åã«oÓ¶>%ýÚ\YÅjáÒ¥Ëz$46Ú¬dÿuӉˆêNÄ5,:Q; úL¯Âi€IEuå©[!Ø_gÚغ@z,+•–üŠû³h­“á!\’•/s‹Þ +/r5Š +˜“ý¥³×82¼ÏÕҢטòû[‰Vl ‘fôTÕÙie_F}¶j)Yëߪ[¹Ä©, åÀ\Ý Þ5JŸˆVº'h„çÀùj;j¹ZŒéTg"È._¼chòÿýc8e¶Ñ4lˆ~{¡tÅ=+3&V¬*¨iÝR†°¡‹äBÓé@¦œˆ¯xKQaQ–x} &vø2éS»ltÉ»—ZDkâbJSÑp³£ù-"·LØðk<š†"¸öŒB¤ñ>«ø¡^&&ŽÃ› Ëà|äúB{Ð܌Â$]½£۝`vdE͵è‰Ô ¯pl,ZØ!‹îÐꮁÁÝᭊ¡„î#Öa €é­!¼ÐHÌ¥šõˆ+òI æ(S%¨ÂGL_,‚-pl<úhSÅÒ¿îêØö‘ +Aë¸QӅҗ¢tŸ(A‹ið-e»+äTx‰íE«cY2´oÄ`3ôoëaª¾¸>¶£iØÛèÙîhÖìÈ ‘Ðś°HºPL\D˜ÿ[òøh²ým’x‚‘¨²…=D+þX±|ñŽ±aÃâÙÔ]P퀇3Z²ß¨wŽö¶à‡=r­›ñ…j `=j¼Ó˜2A[Ùæ^K?‘ìuôŽ~Æ'Š•}|Mßó‰wÓoõ3¯“¬§´-Ç:iμ`5ðC3˜?òC×û™O22C—q‚†UŸäËùÒ ¬©«ØÊúœâbKø:áž`ÆÒoui¨„¦é¸VtìÖÏ!ZÆȱçB­l* : ·NÍ îÞ´“–Š£~gè¤VÄ95«QáF™½jbŠ›cɀåÀTv΀´Â«³ˆÕõIŒ³µÖù…ÒÕå,Ç/:H£.7àãr3~K̼Îìªá.TäÜùwNÐn¦F»!;·„‰o$Mò$¦4|†‹äš‰’ëýM;¬m7_~8-¯A‹y10_§Ì¥R€ sšê³¦¨¿7›…3ŽCʏvpk'ÓöTCÒ%ã¤mY ŠdÄK6ÈȬ¨s‹$ٍ¶\1w½A™¬~~¶O50¸Ì¬¤•ÙǼ¦¸Ö‘®™¥\»ˆma‚l5Í^ Uƒƒ–ÃÖQëcX +Þ;¹PK7¨/«Z%« ©ìÿ?º»—£ic)2*mŒFAŠXj–”L-Cì@@ÉT)³`€ú¢² (lS½³¦.ˆ£2иº”þiN£ãX}¬µ9ÌËw«o[?©¸H0ƒÆµœEúX$B3¸ÆÀ œ6?)¨Ü´ÌAy–Áà¢ïœÝ+µUiðÍ‘¦fËj¤2ñB´øYŸ°qKºãUm\-4Ê]Y›&N*Šñ5‹Ðu¤ík +‚ÄE”Uè +Ñ)BIWÿ ôÈÏÐ0Œݬ–T¶bx¿á ±¦*Œ[ÁëCžÁT¼rl´4)5K¹¹àÚsT\§4ªÑƒH½½&h© Ù[^Äú÷^LCO.5ºxß'“jnΰKA¹²Õ°^ëy|4°ÂÂ;J×Øȅw™(r'ºz¼†b1Õ|… ʂâ)UãÙ].¨;Ç`Ã2‡Hjž#ò,u²ŠSYâé,mQ%c?ûþ×û±PHjY)+ÈɎNJ ²rŠ¾f䬐 +âá“b +Gïè>«§Þ¤ê‚ÍNÁN£E åfUA!°³UsT°—¶<†R[‡‚…… Ô0ƒ‘†Ú4fnª¢ákîo}È6ΛQ)‘J$kT`»|ÂV$\Á@´ŠÛeA#϶­ÔhòK{y^UE#§´¾¹4\ÍNï"y®Õ,¼yý¨“*Ïn’¼!ÍM \³ÔÂ[ÔoÏö©I‡Â V÷M+¡œƒÙ[ÂH»®&P~ŠJÏx°ÖCe”¥Ž•”Ð:Ê@µ'²t0ÿP#ëÂ{Cñ©”4ꟳ5MO¹3 ªï!w¢YSuØ ›*¢ðr96—Ûï Îj㑽™$ìk¯Z‘ÆÍø~ÕÂn‰n"NµY0æbk£wœ¡³` +’.¶¾MEC²²vq¡¡(WAYU!œ¦¦“#àBëAKFQ56=ì"T Lbâ`$uÛ Ð¢Ï¼GvåD÷r”þ5ÈÅ£lX%L7ß8]ô Mš?Õù¹QHnŽ[ÐU/.yçmçª!™R´~RõM¤gë¥y!ªmªABÙ0,² +‚¦¥€¶³ ë6Š¼:A²Å+°>ÃCkI¡„p²%„ %{Æb‡±#7*+5©*¬@/ˆÑl`Þ0¯cãõnN€S„ðaL4#P¸ñb•F5áðcÆ#‹¼ø²È`YÖ³«Zœ,³ˆ‰” +ǚÞæÚñºUü#Gâ‘× /FÂ5möO-ÃÇ¡¢ú c®L²Ø£F +Œ>Aké¹ ¨ià?UOÆÖ¦‡Ç|õ Z-UÝÊ(,¶>|1²b%$ýÄ%´¢54 ä÷‰VbZ¯˜”³’õwJ &ø­?–ÆJ“ššÕÆF:‹6–Ø<ªM¦5±&´Lj¬õ!5D†ºuóçÞõ`¿R¢É¼ŽÁV.~’·P±Q} +¾õV:"¹«ã±$$_ˆ CÚdIâô˜i$WéÍÊÍ8´«Yw WœŠ7SIÓ W}Ô¹O5ÊÔR±È]Ѫ˜àú‡´ÉoOlc2*Ø; ªÓª±Ìó%p睂ÀOL†˜ñ¨É52E€®ìÅ4fálð?# Ê-}êyÈeçž÷z?³=@L)ÛȄhÁAzŠàg@ÌÔxÁ.C¥,Ÿí÷~¡µÐYý„: íU¸XÁ|)Õ® ¬v NÐ¥â̯AÏ +/Iÿ£wôcóoˆ@´z¨Þü­i1y°„Úšf/QZÖ&ÛÈë œÀøB{Ð×*˜ݚ5OóFÖÇ0ßû¥©‡jBUiEíô>Ê£™ :Ék ¤ aôI4:Ôsä•ñ µæ3X›‘ÕãÙödô"ø<Þ|ø¨í۔͈Gz]ØV&߯B@µQÿٛ´ÜŠEù±­ÁꡚöTƧUE¯R‡Äè©.ʽ$¥¹U¹½æ݀uÈjÍCl€Ó„Z;±ÔtºçàÃÀ&„DPc~üéÄSËÉW¬iòÔXT ÚÂuéälÂ5d7°]D:XØv†fÇ=°n^SŽ‰s‘nCåÆ¡•HQϱµGÚ³¦­H\û‘µgx\:º„¥·c¡h® 6pÞ¦âÒ­N›]kÕRӀ.ÍL¢k¢Á!S.CkÔ,P³™I£ ñ½ó¢É€úÕ/ي¥Nܺó>ÎÁ(Îö\„“2=©ÂNaGF/ Æª ­P6—漫çñÑbJDî&¢«§5 H{êJb )°¥ÍƒyÇ %€`><ø¨'ã +’LDuK¾/Þ1¹1ï•Ræ×ýx¡tµQ…“AüBaFàǝý̟¸Õ•}B¯æêþÍâÀ¡y £"Œ"}M…zÇØe,Ñ¢/¤҅Ò5íD­lDÌf’£×”‰ŠEàxúÅ;zž@SƒÂ˜nòü¢•ÍÞÑÓUQ›x´qA Ìïúâ‹i0·VÝ#™¯8#„CÄĪš +üŨögS.~b:wíó+ÕÃ4Ÿ™ ]¨â8 +M2%E /ëÀ‘L,æOš*«®u?D-gÕ"Ã,ÍiMö–HÁ¯fð]Sª, Ž?²ª›–­%”À 9Ÿ+ŠˆœÎ!Xõ°Œÿ9HèBéZ!™o—èYҖ’ÔbˆðLš YÈRÎ!ۉ]èLŒV›)·f–ƒ+Ÿàª@°ïdµ)ðÍk·^àÄq•lv:Ú$mI ã†Å%³¯1оHÖՙ¡æÚT=ŸÊߨm^ë@üĉÆւ£D-Ä£÷Œ½ìþ3c9+H²dBPT[”½ÉlÈ#;33^ë@§9•G6]NN6Týõ“0‰7ïgaÈÎpö¼ÅPó¨8uN»ÓE«B$G×Xa9®™îô*u­ÊØøµ!ŒÑëˆqÒĔ:åè7@Tj‰1àbµ2møç7©X{¤ôQ•UC~1 §¨u^ʟ¯m¶ À®ïûž3A͉næƙòV:]Y¡6PŽ,ôªÙI +$ÞÊTúTÑbÐ%ôt1ø="¦¬Ý&ëvu ã¡Hæôñ Cvat³ôrœÕjîŌMb‡¢øz®aýB{Pįé©I“§¬¨¾°6ž‹&˜Ö¯%à:MRkR+'Ó ç¦LO"ŽÇ“b@ïêx|sT8]p`-ÈÛ0J)î´Ð؝ÅmSÐi3¢8!­÷Zã"x»Uà «#äƒ;Çp2oµsžås‚âDÄfŠu°=õD)ø— XfYA\ì‘Ò'܈¹FWÆë¸Z© C^iÍYzǂôéüã“_µƒßüöàËÿøÉ?ÿú³?Õ¯~ùòùõ›×ß~~|ssz})Ôç§ßœ]®ÒóËËã‹Ó—D>èôƒ¸üö“åà3dË|ùã'¿zƒ?¸ƒ…þóå[üíõ?ýW§ýxþ|ðþïrð²ÿâË¿õ‰¾ä}ø¥d .’—…Á2ƒ~´J盛­öó.úÜÏ%†õWüþã¾Cª(A&F4Q?B ‹LîKÏýYg¸ˆ•ég û³Þ€ÌSÊät‡¡;z^ùQ(}“:ÿȁSvY'FJô§Æž3);1C§‰…¿¥i èW/d—à §iœ¸þ]Dܹ҉R鐈”¹|B= žGW¦˜Q8DÇæs"v®OC@àä@"z¹fԖ²†ˆ¼2#w@}VAò ’CÍ&"Æ&5chž:œ†2Vd§ƒˆi/“ª…6aIüÈ +t:ÌÿDïÒQ“Æ”ŽÑ‰sZPbò‰ 8Ñ:ï¥É,”Æ¡ +‘ B±3/úä2:菿ù=$bƒöCÄÅ'Xÿ#µ””%顱€KôbÕ`'bÂS.-íA³@‰L."»Xõk»C現ˆØµ·ÆDïs=ô}ú2¾F¦µþ‡ÆÙ+¼anÁN€H‹k'É9Œt¥gbY›/ˆ™3¾õ1v¢óƒLç&°ԉ•ã~é(ò+O7f¡§¥ê¹6]ŒIˆ)dm©õ«‰NÜŽÄ·Ä=HÑ"r•P"€)aŸ’!@´ÏBîª,¯j(dí ¾OðÁãîb¶/=ȝ¡U)ñ×:±òö°ÞLÄØÕ!9c(B/=Hr9^R¨Û O?ŸJ•1ô©|{0 é!³+‹èŒ¨×‰‰=ŽDìw9.†ˆ].º¨„Ò¤±×"6Éçøf£[(4°’¼m2ãÁˆd÷'ÎRsUy>•HËâ¤þuK° Ì›¿d> Uߓªü‘Ìõ®È“‚8T0ÆÎÄ,¤>}eª·Ó”ú'œ¼2T1Š7˜|´ô1öH±Ç,ÏòbW’òªõEÛ*·‚S‹e. +Ñsҁ:×ø4És«*³ *¶#ZE‹äŸµ$¨*›í+ѹ'»,+<(‰À@Á¼ŠˆP eZ°$²m¼ä"“àÚ7t@ºÔ#=PÎ =MdAb–·Èá…é¥d}#ìNè| H2;‘€Ø)Ì<ëñï[WVÅ1>$þVâðEé!óm$zFÞuo<¯9aÓӉ¦‡Ãn6Y%ä¤Ëç +GÑ#ÜJ¹KTbµ÷šQqõ9_ ô,Û­rʟú \›ø˜õ@ 7|/uÙ+‡Æó{à"Á!‹c¶$Šé5IÛþ$X[füϬl ù÷0ƒÀ…Íca‰‚‚šL˜+›± aŠ¹P F5òÊ%AÄV¼¿EDÀ’ò·¢8/H=c{"o›ç%#wZ’×:‹ Áªò‹"8g4†ºPÄ_Jôô±qUP1­-ž[Zy.j܏´HNr"+dßZäsó€–~º?^‘×ø¶,|JPçU'ª +] #„Ž +m"­‰qp7ñ,¢ñ gØZ m|Åá”çò= 4°˜UöêLØ49¨t\I–X,ùß;Ñé +ésž‰Z€•8g¨™È™Õ +YtEÓ䬌>ˆqúP„ªÍÁ-,‘Qõ´u‘ãû¼¢$Iv¢g /Bå8é€áiÅ·ÈSƒ/¯7.bcî-Å7ÖWc§¯§ +–Bê¿·]ƒ½$“l]‰”ëk»pÎw'f.Á=xØڂH5؈ƒÑBRq^y+["OMdÅ¡«üý:OǔŸ=´6’gú…é‡Hõ{d Gš.&4?R¥kÀÅ\dß(nÄÀõ“Y·ì¼Cz@‘ŒìHýI,VqÑóM1)ÒâøÆn:ºktFd P3Záh·ÐCBýœÄDÖGÐk… Š5綐}Cå<±¼Y½$GÓïÙvR½·¡úIfÀ®‘קo%Lx+ ?q¼ï"õ‰@*<rÆp±pòj¿3R~—¯pXH rTNÞ¯(·/s¡J{p© :ѹ)?ú!8&6gåUP¯‹INˆþ ¤Jà 2oöÙG…MÏ:*jæ?| +™¸0b¯ý°ëSé u’rQc4Y¨qYb^‚ç[Ð÷€ù +£̄EŠiE Rª>‰ú\WT4-‰pÌ@l‰WÀþ¬P [ãÍÍ#p½T@=_`r;¢IÑ#öڊã1$1hd8*´T¡ore:é’Lt€O&^ÌziE>˜˜ÇpÞ³“…âöhQJ—¡dúÚPš^æƒSæ†,ÊH×oôB¦¡ +¬«D>"ÿH±­…*ŽF>¡$ò¨¨%#è̂šŠÔ,kÌb¤G«ï,iÕ²ŽñZ»À^äႋdCð*ü:5}/|eÕû1BÜý>:‚ÇéÀDH÷ Pڙ8Ê6£–]2•˜î­£7ÀÌÙ=\ + £Mã`àô/tcRáyɲ<9ª²[.r.-Y4+k´`”‰lG%KýGáì‰ÁRa0’‡”¸©)Ƹ[x•IAÌT:×îac[B%/5éÁ5e1VVkð°ˆCÕjÑÏÃONw€à‘ ÜтÁ<ð.BL´‹HîâK¢„©é2:}Y'“fßSý £eYØhûB߶Z©1aOò !ZJT-FtIÇåªb¦;™DÖÓ8˜‰`ùFÌ:Ý0½Ð'`ÄËòÀ\ æNìù]Á, + 蘒ä¥*ÒƒÐ‰ÞL\´±\EéÙf¢ã$nõ8¤LŒ•ô»NLBñ‘´Tÿhq:HEAO}´ÆÄTQðDeµÄA/D¤¢ v踝Ï@„êJÿ‰ˆbŒE­›¨:9èå渨Ä¥±©œC–ÃN˜ é2 ä 7ÙvÏWŽˆ¢ÕpK'-X¢ Þâ@›F*"_‰Àš'jJñËPÀáš'¢¥ç½_Ô&t–÷ˆØŠô@ôD“+åvYlS¦ÄL†P¶ÐÐׂ +²ŽßƒÞJˆZ•¥^Œ7Šºã™qӌ¶Š“N7=B]0ˆÜ½tÆ8ˆµ°¥ oB$u‹$­€·˜'%Š-)¡¿ âw¡ê +ü9rYQ`R&ËQ€oޜ1°9ѲXÑ%##µÕ9T:±ñ‡lTæäŽ}V²¶‘ôÖàØñÂËXYŒ ŽÏ•ôãmæYÑhôÖ4&ŠúB-ّ;l ~! *)±L^"í{@€œèaž•‰´'v#Ÿƒ(•|x=[mžÏꄸ°ë†Ö¡æ¡Â='Ò?Ѥ}²zÏȖ ÂûD³ð~»1½jã%ó²W +µ­B¬¬JÖEMå Ã)R ºmøÜÂΠʧ$+«×B𤰖" iÞLe‰µgÍZ^IkLt=~…ËI¿ôqUÈÈÃgÇGIt`"¿€ðUŠž]MjôHê_ÜèAT ¯u¥Ù®ÅƒŒZ‘I‘WÍÈC,·Ó ^ÄDC?t’‹™HJ(í&™ƒ^h⸠AÙtÑ,J><1ª1¶&’LuÃÐe£ÊI«E ”KŠÒU²ãýéÚAfbS¡¦ma§ påö߄,'R-h¥ŠÂ78i•Ï,‘•••ªr !uÓT6*ûÆ]•›!‰ÎìT’ CDõwQ´HbKÞlÀ ¡å}Y¢öÀ&8™‚Ý!UŒ4ïŒÍWyKˆ91ûüïª08ӌT»£–KLÃ6Q1³«Yw¢O­ð‡œˆŽÕY›á*… +Á&sh•º4eÇD¥Pm¢¦a·RÜÈý”Ò$W•}ŸD—¸ý¨Ú…"èDgdh"R=¾”êp£“ÆךNŠyçK8^ž!.AS2#{#@„•×z a¢Gg'2¥‰¨<êuùÖ2,Ž…lpÂöªº€ +Ãa‘ ZÿˆðOˆH‚ ù•º+ 2.YÇ¥±›#ig‹²X3ZÂ1µdiË<ȽGH¦!êˆTx›‰nDD>-BWg¯ÜTÐÄ3æ4p_ +qrš“4ºÂÎ3…té°ä€ ̂]~˜—=u!0÷#>'f! pGØâÃ2mâFaÝ¿pÞý>Áœ/7ÿޑO(A¤d)Â/⟜"P„FH°Qò½ZÓ)JÆUöý¬)Ÿ—?“ƒÔ§›;Q-w„ÀœhHÑ;Ũ_ýåêòóë³Ë›³Ëož=:…Íÿòɯþò=ý›[ø¿ø÷?þáì¼wõɯþÕþ|ðoýo_þùè/W/OéÏ¿;;¹9»º<¾~ûžúôà7ÿ¼8¿ìÿø¬ðúìë77§¯{ð/½ág××Ƿۜ|{vþòúô’ZøƒýÓåÍøGü×ÍÛïOéã–å׿=ø×\žtú½ïËoVÛþp|þF{zöÍ·7?ÝÁTÔºGÛÿË.Lîdz—7ßn>7iþPSûìO_}vþý·Ç_¹'xö²7}ß´Ðè¡æ´ÅfýsóúçNLèíæzûpºúú¿NOnž_½¹|هøüê=Û0ÍïqÀÞöæõæ3]ùÑ¿l6±ÇÆ`oÞ\ýæüôòätãµâoºHö©›ÞÆ»>}ýæ|‹÷CÛ?ØýíbêƓûúøõé®Oÿߛ¾×[Üæ[?{¨©úçyùæâ¯'7Ç?œnq‘çß<Ô /¯¾¸9»9yÏ?Mô55ÿûÙù63]ùц,ë]óq?5Ÿ»Ÿò™ãžþ}f=ïøOïʃlØWo®ONÿx}üý·g'›K9—›oÖÙåŽ0γË÷ÜÏÕYù‡›Öû–šÔÕ÷§×Ç7WכÏlüâo֋«‹ï¯^ŸÝlv±îi$½ÿú»ÓWŸîõнzS3=4îõнº×C­úêú¸Kàç¹:{½×DwPÝÜηۊèæïÈ^Ý+¢{Et¯ˆîѽ"úuµø”Ñm&·sŠèóÓNÏ¿øöøåՏOÉ-úÌ?9…t«)m­’î¢zÆ2™Ržœ„ñõù›÷¼­;¬™m®¯¼¾yù»ÓΎ1¬mäøùW,nüñøÍë×gǗÏyGwO”ß|·^nÁI_> +ÝbF[0җh؊]ì +¼zõêõéÍóŸ‰>$ø+Ít'¹Ã9¤szž\_]ÿۏ߲bµ){{¾…±Tšï/ÙGœÔëïOOþúæ=Wf‡eÍƒ‘^¿¹~u|rúÅÉñVgråW¦¤.›O³oø›óãëßÿóû«ËÓË-¶rý—6Ý­gûâêòõÍñ‡ÌvürGÕ¤®8öÿ·ñŠý÷æKôߨ §mæ´#¾Ûj£îEÇ¿/ çó«³Ë›#±ü=˜Õõô ¹ÔG"µì¤Èµí“½+¢È‡ÙsvŹòÔ­½óèñsŽÍ—ïÞ#b͛ƒ¶_ün FñÝò‰-f¶˜Qx¸mqêÞc™[™Q|è—ê©F7l/_ìÊ|~vóùñÙû´À~„¯Ïn¾½8½ÙâTîãÝTë?À:þ è!·÷ϧ×ߜb]wRÖښ×<éݹ×Qì¹ö\LÎ=å@®WWçϯOOÿ{sïÛãâJ›o؎˜x·¹`û¼¢;fúòŠÜáæÐ×Ç/ÏÞl±>ÚþaU㧔·ùŒvNoÜîÑØt¯ðíxyv~¼E$ÊkÁ¾ºþþÛ«ó«oÞô”™áÓcO7]t‹„®= ܳÀ«<½€ä§Çù6wÌíëÛ2ók;Þ÷Œa‡«Ÿ<øÄ6§nWxÄ¢ì®ñˆÍ§¶+òѲ…æ±Û!›ÁïB~:eò‘6ì=±KóNm™ñ°™¿ìWmwB¾ÞüîÜS½ùÔvå©þls§Ù‹o//OÏ¿8=?=Ùʚ±þˇšíß6÷z~ðl×ùÀïÙïÎ^~|rzqzyóçãïwòQ»8îÝmîÝ%mm9Ðÿ¬ýÑ­üqãéÓ·¾´ý.ðÕ]yÚ7·<îÜ+¸%ºîîµ^ ÓþÏÊjvKn³3»r6×°wîm>µ]‘&·Hÿùð‡Û-}µ]0᫳ó󭢸Îwaÿ_]_]l1+jý`Ú{D©Ùš‰z{[X1¹ùCM,m>±—ïˆXñ¾y@ïøüÇ㷛O¬¿7Ç×Û=üƒÛµÍÕ «-” «‡›Ñõ))¨Ïëøå˳›³¶PñÆ/jŽ›?xóDu ¡¹l<Û՟=Ԕ/¯.·Øӓ“7oÞW³2Ïé75Éó³ËÓãÍ3ÅNŽÏOþ|õr‹IŽ_<¨vt|yvqü°Ðλøø¬î㑽Êyòt㑶˜ÚŽ™nöñH×½ͩÛñt㑶˜Ú®˜¥~A¥s·À«ÜG$í#’~– Û\èÝ­ˆ¤_ö»¶;I'O7"i‹©íÊc½Hº{¶ûˆ¤Gõ¨ý’"’Ü/."i¾º+OûӍHÚbj;fÖÚõˆ¤mvfWîÑӍHÚbj»"M>ʈ¤]ðíbdÕ6çw{nó;»ÛˆÛD:î÷剠èìζÜë(rO +Bõ³?}õ;ÂÝùjK›×GóۚlaØÜ1€¯§]` µg„æ=#”ùm¾{F¸g„{FøTáï¯;e/îÂ烧8Ç{6¸gƒÿ6¸÷âàž îÙà/– Îþ¯¯¶Œ xÂÜpó•ø%ú@÷wkû»UöwKæ·ùJìïÖþn½ãn}~öÏÓóÏϏß~µe~æcŽ¼IËAÚ<@”÷ôoÛĈN?y¨9îK´m½dקWïCîØQô£'‹䶘Ù(ÈL äܧ~9p©ÿ÷rÐÿïÓþçþ¿Ÿö8x²¡ûg—/O_]žmáVº>ýþôøæwۜÜé'5Ñ_j҆bÁ2i— “^Ф§ù‹€LzlbÚS®6ûõùû8ýçpl5¹]ÉâØ[Yv‰wlww„i|¨ãmg@®.¾¿zݥ濾y·Ûaæø¾Ãö4œ‹/t+w’{ln3üî=ÖÒysÐöÁôðÍg´·øî™Å3zODÚʌÂÃÍh‹S÷wêʌâŽ1ôÝz·UOvñ-~º`¤Ç×g7ß^œÞl!NíåÝtú|؁Þ'~è(öÎùûpÎo Œú˜ *{çüÞ9ǒíóÿ²wÎë¼öÎù{çÀpÏûåÓí¸ñÞ!÷†îò{‡üÞ!ÿ!“Ü×0º5àŸÞˆ²xí†5oïß;ä÷ùÇrw„i¼<{õêÍ“vol;¿]a›Ûe^\]v]ír‹­[ûáCÍõíéùùՏOøüì›oozƒg'€}Þ|¾·÷ø·–/×ە{Yùуé훿|o®_uupËI®þj×ï±=8{;â¿ìžq_ |íˆüÄ|úÍõééå§]Ð;ýôìòåÙ7WŸþpvu~zóéõéËO¯®/¿Ùü:î ŒwïôÞÀø³Ø¢6—öVƽ•qoeü¨B@ÝÜuüßgonÞS†såêêæÍ'wzÞÿ¶Íjúɬ~wFzïXéƒ#ýŽñ#áé;y%ž¤ñìõ÷§'ý9¸~ÊÉ]òýåX^~v³Ä£Ÿ¦œðßÿóû.\mc=\ÿåƒMwó÷J½½±tý—{£ÓÞè´7:íN?iq‰‰Nb"ÛÓÞè´7:íN{£ÓÞè´7:íNƒ·<¹(Ž½)í—ë¾ò…¨i;mKû³Ó®˜ÔžvJú/Á`¸G‡yüd ä‘A‡ÙydGÐa¶˜ÑæA_«§ZGhëØéy‡ÏÏn>?>{Ÿ}‡á=*Ìî<Æ{¨¶Çÿï¡Úÿc¼5SߕwøÃôý]{‹÷mûÇxç!Ú¶?Ì{x¶ÅCŽà©Á³}ñíñË«ŸRá´=nÙZ3öà;'`l©¸Ç‘xøk¶y!á—ïaZ+¡zÿ|¸ó·ÅŒÞn1£·;Â.v…^½zõúô÷æúôåvlþÀ’Wü•füKTDþ{ý¤5’ǶO?›iw¶h¯4î‚ÒèÂòëÏë·§ïߛϬ¶¨—ÒÅ-&÷ãÙËmB)¥ùCMm(ûOˆý™K›ï×BõÊÔ[Mi ©ú…ê½Ifo’ù¥˜dòÞ$³CRx}r&™-f´7ÉìM2{“Ì£Þë'­ï?¶}ڛdÖ¶ho’Ù“ Tû›ãmŒ½b¿W·^²W×Ç'7Çç¹:Û"tŸ¾é2ÙÇd‚'÷\õ0SÚÜ·kŠðSە¬íåps­¯_Ÿþáúôÿ½9½<ÙBѺõ³‡šéÐY—o.þÚùÎÛ ÏÌ¿y¨)^^}qsvsòþŠ½Íÿ~v¾ÍLW~´£ËSFÛâF¿º¾ºØb^Ôú¡æµÇÛE\°åpóÂP7W[ˆmW7§=Ð×;f¹‹@_[5{œ¯ç¹Çùz”8_÷eûúû›ë¯ßœ÷´›VÒmôºÑŸ6öЗçg»ÛOʪ얧è·Íäv.Ðo<1_½•`—|[ìØn„úm1¡} ßݶ£÷ÚÜÌÒàÓóÙ`zOÖű.¿‡Àæae{ÀÇöìÑÿ9kÙ«¢{Ut¯ŠîUѽ*úpªèæ²Ò^}ÄÚ«¢OT}ò„O\ݍe·uÑÍç¹×E÷ºèãã,{]t¯‹îuѝÕEÓSÖE·™ÜÎé¢ÿquõò›ëã-nþ£WDŸ¹'§Šn5¥½2úD•Ñ§]açIC lØ°#¹_›+{\—‡ç{¨Ý=®Ë®a}웿R@—{côÉ?\ÍÃØñÏ»žóìäêüêúß¾>?>ùîÓ&]}|rvóö߶1¿¾y{¾…_š?ԙ¤I?Ù·ÝìvìÂýGt'ïۖÛòô_²Ý1ÿ‚žë×þûâ¾YÈޖÿHlùK>IqÛJÉ»Æ4¶®½# cs$)YW—¯oŽßWctEµ¾ýǚëßn¾pToðl©fžîíß=þå»õÅÉñ6úÍʏjŽ›R¾~sýêøätËI®þjÃWï±½7.l¾LÇÿ}vñf_¦ýࡎ]·§‡°–7Ç;=ïÛÎÆ>ýäE¹ßÑ£p$Ñ™ÑB¯Ô‘pï½dùX$Ë©ý½kÒå/K2ùÙ_íǎ©Gü÷ÿüþêòtÙzý—_ÜÔ1o¯I¬ÿr/’=V‘l/‘í%²ÿÙ@¾Û¾Ó"هH/»"™=í°ø_‚ܹw<~²¹`õÝ{šÎ›ƒ¶uê6H¿Û‚Y|÷€¼b‹½†leFa'fôžš•Ň~­žjõÖþ©y‡ÏÏn>?>{Ÿš¸ÃðñõÙÍ·§ÛT-Ú?ƏŸ-îÈc¼…x±#ñ3Ú?Æ»ÂÔwåþ0}ÿïßâ]~‹wÑ¿/F»"×ÏñTìÎîÜë(vò|µR.@‹5Wð,æV|9¨‡ÅŐžùþ/Íçƒ|èúÂÁrØ|*Õœ|ò«gËa*ÙÐk KBŸ1Bo×\ïp9¬5×B=\ð»ýwî0»ä{«x¸,} +‡!ûÒ|í¿öîàßûl%özwX}ÀŸüª¦PS9pé0õNúœr©ƒõ%…vàÜaé]Çþu ¦Ìõ¯µZ¡1ԃþ÷úðêâñ¿ÿu9Œ9ôIa :­…r€…–ú¬KŸe_Hï]®k«Ý?óªïøWýN߬ò°_õ›ÞO*Kiy:ƒÏŸvròæâoW7Öúë¯pú¾²Ð7‡ Ï´,)ãë)æZ±µ.öï  ¹´D 1ç>Ôgõ0ÕØ26/径ÏÚaÊ>aZ}©\,½[úF—’ÇTóañü>ϼï=ôÍÁ֖֛Dô-¶ƒ£>È>ª˜Zÿi8L­/¶=Ѳ¹>ò˜°[ù°·‰£Àa}»úϋÃ8Ks‹¿s)×Ö{mCîÚ´Õm½½éw‹RûBõÿ‰­¤/éâÎ- çk k´,¡-™¾Cé,.äÞ!(ýpƒà}̎¡ŸKPBð «_4܉>°ô sÐ Ùõa=ëÁ XÛã“{9P‘TÅR`ûûÐ$úÂ‚¦>ž>¥a½yðÏúÕ뫃…åUxæC_çJÓZ?,GÄ?nªµƒwÇá\;ÀëGüŽ5Z[ǵ…¾k;úœú–wb:ì”ÎWú·Bô4žKĈo-ÑÇݏtæ|ð›ß|ùÂöçûÞOnn˜x_­¾nÛÓÇWº±³àÚÛæ’À!±ò‹Oñà?q#û]iýâ±ô[†íH¸tw;» 9±ؕ—ËÝ;ì͖Xj¢ ï]cEÓÒ|¥&Þ5ºcýápt×qNœÇB÷›Ù/@¢[Ÿ—±†Ñglé¥ß „Œ¯8g¯vè Jçø¹áQjôÊtJŒ±ÿð„Ú Gü"wžBç0-¾á38Üß[Ëu/¼³> º·'²>Ù»–¤¯ï`g|1áUå_±6…Žå3Wmh?Þt-i: õ¥Æθžù>ñ%÷ ÒG^G?‹xE;KG¦…ìîÛÛ֒é`÷ ¯}ßúkBç[ÿ‰6þXap˜A¦=íg§¡£»$F}#rêяSj±`ü©æ¾îýUKÍÔ¨Ï#ì}'W™,`ŽýÑý”c„¥F°gž)°֌Y‡Ãà£'.Û·¼â”¥>å@›½ÄÅêb£ª­ÏæÏ[ø˜^*ü9šk_º)ü+9bt®è½èد"Ý:,üvхh2ÙÞ>â{¥‹°©ð»à1'‹„׬µÆç6BZé_¦ï€â³N±¿âÕÀ]‚ÐASô‰D"ç!ôUpYD¢\uañÕþÖ_¹Q¥§´›è”Fí߯ý¸ËºÈð6ÓWeoú÷э.â¾Ò„?‘¸ùqÉ<:9éʼˆïë‡í^ä:×QÞwƒ~·«0ÑÎKè‘ŠÒYº~Ak +vêé±ÎÄ÷p&«[èîC8 ö…ã-çMŒ¸ý¡;Äv:HªÐV¢ç]ÀµÁñ •”žy; ]*h¥½ë"­ß·õ;yÇjÞ±èwl̝û·¶ÍëGáΓÁýi)µêÏB£ç$Ó{OÉaPwGÖï]¤‘¤k¢D~™\vàˆ4ÅF»~šÑ&Í|¿Pžïp¨‘Õ +Gcà÷Ûér^¼~±Õ>Ý>üÊ«Û9õ’ +/’¯ =“]tÂ'/bEçæà$–"8I_‡ä ìja¥†¥ë˜OƒàátqŸFŠ§ª-•Î[ô]sX?¨÷£äEa÷·YÚos¾uîx'íG¾6fx1šæ–ùh1·¹›®³Ì»Øê÷ý¹žEHêKâ‰A®%e8Á | O–Ä“´puº ÔA®,ÕâÈ^Ñi%4’ÒjŒøULÒî +}zaæÞ`ðX¾pxz°Ðôt! w³’4‡—"ÓKÑÇÚՍ2Þ¼8t èÅñ´ÕËV0§¡½nía᠍€€MÑO=öÁë6xâ2ø‘Or?ÁÍp^ˆ Ðyéw“Ö†˜ŽK¦ãB/3ô~Dhâ]Êòvwփžv|zá=±š2äˆ +QäH À­žŠN+ÒF—S^èW­ïM'@ìÃڀ€ó ;Rd΂ž\ ܨö3ëéVGꦯ$-{,žÅ™þ(³rØú¡áRÏÐø™Q÷î{~°v˜îíÕÃ}ô„é rtj‰ÅñNañ!œÚS}—T±éÁëo/KÏ"¶Î‘0…³åaâHͷ¶èhQ˜[Á¯úý 7Îñ5ïëYˆ\²óÒ~WÚढ़Ývq> »íïZçÉ]b”sœèZáòäÈ|v°ö†çXY;€èÊʀà …Åž ü*-e¼$Ø_â„Ó{CgÜçñ*Ð\ž7¦7=o¸÷>’æJ&n¿ÀòÐo°«)ÝÍ-n³”5¦s×aZ?q·Žä]Çvýl¯þ»¯H#W³J]uÄ1è'.ä¾y·à}Z˜ns¦ "­q¯[üí.&èeQñj‘µ¢y‘wm‰w³³5ž·Æ×9ç==`_º~ÿ$­Ííóñ¡ç çYèëZj„YÚ¥@’e`æú±îç=ª¥6fU!5UȜ@DÇbè-Aìߥ™OþV³•Þþóã|m'×eYQÑo‹¼ëbñ]Ò3¶Óù8¶ó˜©$ºŸw +Áë¢òº8}—ÔýQ7uéÑÿÒ¥‰p9g•’£.M͐±¬æØ3HKÎ3ú|x“`¥'"?exZ¢§‘&ô–õ¢Hw„Ø"Ä«ÎZXÔ0g‡È½uðtvJJ=‹l™Q¸Õ±~ÜÅiàw`¼}ðKŠäšë{=BýAîÃ;°S£„ˆ+°}ÁA÷,<ÐXaØêüÊoü¢ /ô4ô®~ [_{|æz´Ó¡±«Êõgµ¸¡ wBdn C[¥]‚Ç'Ð]é¼?ô'·¿bý‘à—Ó¹ÎèßëŠ%²¶Ûeóºï]aï×åjQ¢Øš +¹~ÎJKºéµH7Òj}gfBXbYí©ÿ!õ™$88~yȨø–F †Ëz;~ˆ¨§.4r9ˆ ¢–zaÞE¨.°0&zÆXHãÚÊ~Üm|‡1£Æ…µOçøa¶##ö®ñs0À67öF^tì |[aú%ãmþ^‹%|?°?ðç¼l_"»oõU.íەf²8+ÝÁ‰Ø?Möx\òCM{ˆfQlÔÑ-lzà‘Ò&é L¶å±‹°4”Fz7¶±‘¥!†´äyǺêPo/ôÇÝÇ5}²$½¦j]¿­46¢·.vt19AJM|"—'4Wæ¸,7<ƒ¿w![QÿÙRØ°ÔBƒL×)-óƒ“ÛBw$£Sß›“\cÉv}`ä;É|]i”]§ß…ÃìÀèaxpöVòe¬Íí^ 4·‡xA´Ô’">°ýÈt"Ñáa×hÂ%*̪ûS¿2uYøÔ¥@úWߒœF+ð›ØØý–ái#…¬ËAŽ ã}Á{vã•þ³;—äö²­/ì]Ë?"ßÚÉ¢ãØÏ g½šDgëå=Ü£þF›‚7âíÂ,žm“}„™¯ $c¹Î‹C.£÷©gŸˆ¾Ì&ñ–èקøq¥4š̀`ã Â.ÄŽxxY˜ïü¿‘Šåùœý r­ƒß +˜üJ¯vöÃG¬ƒ­Œ-´4ºFd¾„ÄTðiOV<±/)óõQùÌÖKß5„ƒµ~>î0ç3û¾ûs*=kÖ'ÁtwÆ×½ù %ë!vYww8[nÅÓAxX\¯‹ñ—|Hö8ü¬¸½9'~(ú'œX’^ÙpG-ȇCOWþñÿ^»Ä_õk£OJoøükºþôŸçß"4ò7ÿ¸Dã˃o®_ž^Þ­ß<×èÂ{øÏz;®4!¨¹ƒçßôè) Dy¦yÖg皰–®‘cüàùŽþÝç´mñàϟÐZ¾ì㿟í|ñæëµÍ\‘ü›.‰;øßwm²Ã&wíýŽm~+ì*´Æi!éö +pŠh+c݄Ñçþ^SdM>¤''S$G%Ú­þ:éëw­È"Q­ýŸþx}öòóóãËS¹?ýŸþvz|¾úoŠQ²Âµ*Þ?pEð%×9킬ô]h¥ð ¬EF[û[Fa@ËBqy¿AâîÏÙÑ]}Þû,\;ckeäÀ8$H‰,Ñކ\ž` 9i–ïܒ!®oGƒJÅᖋ±k{8]‹[Æ©ÅŒ6láHÀµNïÿ(uzéK\!JfN4 +ÄwbK¼rÈë’ǹAÔy?7]ŠdÚ­ï}­òý¬‹÷ýóY¢yAt¡pr8ß1ØE>ŸšÎÀœø¥Žîèð¾g ï=â~+¢7ÙW]ù© ãN¼>@oj4ÆUfš§ãCoE׌ˆñæÈs¼ÝåOÍÆ}„Ù€çÀ;‰÷5²UC ß& ‡Ec­‚ÙǚxZx ¤tz¯+1¢ÛýÝ÷ø!H4˜rÁõ'ƀ(I’ªÓ¡&°&ªJ ôC’@RŒ+Díí¾‡ßOyWgèJ’´€„Cw'|%óZ9UÞNJvb,AÝîîÞOïÊgW…rf¯Ã!tޏ{ ÿ©Œ”ô_:PÌ;£ahx¡owö3Ja,E8Rú0˜Ž1ˆhCMÙñ‘.<.ü4¶ìèœøb´Õîîýðô;  xw㬃3r?¿–Â7ç‰b¤,:®ê9)ç$p³ÛÝ÷àqÉÀß\L'gáqö„ƒŒ3õ;€qÆÊL/õÒÙ|NH™¢qÞêêþύ£ G©^к˜™h ‡ çÖ:Ï-óq]Ø£±B†]äàÜêï¾'l!…&„ã⧩6æA`÷”<vê]¯˜¶Aó=55š“Á¬© ò¨òò¬)­õzïó Q"¹!’˜’è¤Á—8‰¦h˜à‡˜Dصï}8ï¼êtzF‡tà4µ~²]ÿÏ¢ÿ~0[ÛÅÒÕþÍö}ÇôsÃ]òÖÝöèwAï°8|Ø¢ÿÞ©,°OˆÇB L.µ$þ06°Ÿ²C8žo7KæDÇÑüùÉvÝ?w÷¥6Ïé:«Ý¿gû>Š­åQû.çÎxçžÞµùïÚ¼”Þ·yptÛjE£ ­Å0ÐjÑ`°wpFõ­ö]C@nqÝh¯›·a÷Ï¢ûéî­tÿžÍûjÆ;=W½‡çWWèáO.|~|ssz}ùûK€¯ýñÍÙKs™Æ0µúç÷W×7W¤’_•Àáʁ_(>ìÀ#¥+÷É:ŽNÃjÐp¹\ ~²Òaûâüìäô‹“ãó³Ëo0›ÿ}úVºNëŸÿÛé7g¯o®É1; âƒåwa˜ˆsî›-}­Ö ¹Õ€<: &ƒg +Ixð_»Œ¬”Æî ÉÈ5DIsô €"ö{q’ …P{˜+ýeWÍÉ¢€U'Ë2QàÚ¤t›*‘Y VDš{ĝ4ù"£‘QGQ'¾é•®?UN&B&~–ñ$Ev[xpÅ®¿¶–8ì;7¢ôsÆZ.œ~I_‘Ý8òɉ¾&Ñ"«IvÁó3 ¹Ðd˜­ŸMfÕ?—–¯!Œ×s¢6'\·¾YÎtœÌ¯/sm/Ñ^XL +âvs=„җá>Ó6 < Á–à°q°¨wõˋôä@Je¤„†œ9;#ø…5Fìv„§vŽ«à ÀÂôÍñH× _9>wxx‡_ó‰ »¶’; %ï=°"'ḌНï!¶Q $‰zúìppé7]ÔÀÉNÀ·΂Ì*< ]S)]’îgü0ú{sKÖDp\jßEZI"ÔÚ'ÛZ?ÿ'¯"í̬ýÏè)¾e6 tBòÈ·j"çô³EQ‘²Ç¡?ÐC2øN2ûü]Èíª…³ÙÒÂb0¨Ä¡¨aù¸1 lyràG}µú6_§UŽðé÷»yìbm‹‚ çZp¼`Xë§?¤q«›ç+@gJiS¢ ÝU'H¾9.<Úô«¾CÀ. HFVE_0r yMò0°"¿¡Ó²°>E±‰a‰ gƒ õà=m!ßl¼îOûè»æÙµÑÞ>ÓIÊ`>h@Ø +}mO +W„žÂ*› ¾Ø»¤¦J;^a4‰+”-×* Á¥DfTÙ6F»ƒ(p)´}_‘㏎û"ÓjQ¾uDì±ÈUÕǂpeþUâåë´èS¥FÞnCÎD £ÇQmÁ2Ehۉ»^€´_Ʊ B¡c‚H3û<ߑqzpJ[þúZR–û‚’H?BŒ>/7ïœióÒi1eG?$àš~=ı6|Þqþ&‚ÈN‹0ÊÒzûˆVˆD¨ˆ‡é:ô'¼¬]Y¢1ñSÓ2ã®Ð®žj 1‚+Ÿ"ßÍ øXø6õâ`€­BȉÖÇ/¶>JËp¸ÎA?Ê°=Q¿*±ð¹èö-ˆÈƒªžÇç4ˆé +w ¤tX°la<Ét­SƒÃ‘ƒs¶äl;Ç;üŠ7„Y„ŽÆD€NtmE¬‡Bpút +M«ð­" õ@<á4B7x%'Êʗ*în~SßÆ~_)¶_X‚0\ +ÄDr"iN³!À.BkôbQP(žƒ”xrW÷@ès•_!†iµ,X.ÏqþèHÄkŽ !4¹lµñcW¥+^ÄLIˆ'+²6*ò)»³$š¾v>h[ÌhCì0н†oŒ~3\ì?êB‹~ŠÎRBVxáñPØ/t½ É÷ +ð<Û“ï_¸áÅà€Õ‰v¼öc›àJŇ¹À'ô:EÙ*ŠÜ, QÄ,q+dD$„ÖTÇŒSÕ K?“ü«>wz£úzÃӇ ǥę(7y +næגòú鱡…Ñ¥¿¸Ë#‰ y?[”ÍD?ê75ö½éG‰ŸX¼Ý`zé5!ƒUR¦qËú«´ÛäÔ$zÝ䈾­‰>M©"JÌ6¼ÒW¢åÁó=‰óá0>ú’'Lä„ÒþÐJ®8ÏIÎ-9åË$·3ã"7”Ph³'ÁAÛ1õŸyXª[Ú2¤ÒR9œ¿'*%2jdBxÂIAfp’(ùÚxq9çr-ßc,)D×Rþ:g\6Ø´Y¥È1ÜÅs†D y ò¬ª$¹Sä»g7ÿ‘¾$ws¾†4!¸IMˆ€Û€ß%Xî>õªË¢âºœWLµÚO¥B®ö?ô÷öP¢ß€\:¥Ÿª‚#I©¼AÒ&câëŒËþÜÂÕØÔ +P6Fqá€%ŸÅ²Üeh$ +” ÿ`ÂÈ«†*“(ï¨ÄÊHšbÍñR@Uj1^ˆ‚@É-¸’8Z¿‰`™8GŽ`:7èÜ!Ôt°¦2q°ù;uØß0@Zja‹”¾ÕÈήáBŠEÎ +X|ã’NEbBžÁ`€¸ŽEûR‘ø…ð—~ÉExR§>¡‹[$çðª óÁêgl:à‘¬œ‚^ÿÎwn‚—cK7 ŠO’·¯$fºäü!ú! i î•e2„îÍ :,j”Ø8ª|Z‚gɈX*4‡—"÷7+Ñ×kV±»\$£CGÒ|B^?”¹êøâB¹h•_iúkÁóùw,h`Ù-Ü{lø.Ш2ó BÝr—c8Ì-"ç3€Ûuy°‘Jk  /Ğ8IrXpú»ÀQ=‘’£}/ ½3ÛÆOefý9&ÖÒd˜PC=-‹#ĤEÏ©î$¡@ŒNŽìÀ_>Þùt¿ùìòêò ‹[TˆZ|&}I#Ã<Ôܙ +#ôÙ~û ‚[ t@ý"e¥ðz÷Õ2k!1 H¿êlÀùð”ÊXøœ6vø“@Ö>-ˆQ p£ò£‚)áý‰88xG33è $×%FHtXW„5Q*\¡¿TàÚýô.œ¢ã2ð/óÀ«èqž04(9¡ïËrpƒEùT ŒPû" ¶²¤þ›ØðÑïý˜¸tfŒ˜þn§XتB(F‰1•øêvE·¢Š-¦1€A†Î !øHXÍH¢@ `ÜÔØ袔C ›;‡© A†äB7ã+ˆXˆÞ~…ܲ)¨‚:† Ti,½,©¿=%pÛÖ¯féK‹˜O6uÆVñ~C|ÇP…ÆSäÁÂôuªà#°‡À؎§¹ªvµx– ++tÒÊ„ßÀDБ!`ÕIZªÈQEÌ/Œ(!¬¢‹Ð^̪+Sô-¼/ðRU¤Åàé"‘>Òh×B?Þ¢ŠíLôxÂj…vI_ŽüâvÂÿÏޛìL’d镯’›^ZBEDUD\±}Õ@.ˆÞô’`;‹ Ñ, Xõþmç|WÍcB¬pÅZEüâ¦6¨Êp‡ox‡S%%#„ß-e²±5½' +à " '¯;ԞšHääk&wæï»Sw‰+yS':Ór&àâÃ¥!¿ïûÖ¼ç,êùޖ¦êÃ_Ôý;±zÝkUs!ÞÁ÷Ùa½úÜ_Y +±ŒH,ò<§&*a¬ƒ#÷è̪W½Ó‘dsï¿Þñ™Fýïo­@K‡!ê|9fº'ú{/¾é¨ (“ý}7v…epkX¨lûêT¶ž\‡'5+×jÜg ¤… ð­I’Þ»Ñm•N]Ô÷nMÝdT^‚ìº{G^„×ʾ“„1ÛMP6ê†ûY!ÔêîRðágî÷í~ÿ­Ä” „mŠ§xޟUåÆw×¹ýCÆ<(n|šo´øÊ÷“ðl‚ü̜büš(ï"ÿ`JPMäÎ[´¤?@ï£ #»{òb¯ZyÊ·•¯§–˯hïSÇ\¥V<Êë³d\2¶k¯Úœ©Ô^EqпCÀñ©ó›ìÖüNènî[˖"Vô}O}ûºA7 ᓈñ$Ü3) Í‘G#ûdüõÌŽ÷—ÞUô˧.:ipրtFæJ¦WWyæ=ëÞJ»Š{ɔ›´MÞórœŠ”ôϋɻQä‡:‹ÙN9³¸ÉïÅq³Þÿ©•Ã¶ùþ"sgÃv)Q2Ÿ,Äy¹Þxè,È#¥[Ö¤ÑÛ4½]îh¨žÎ:+[­ØI©=Ÿänõ>ù]œ'lÙîx_ÙE,“­RöªžZÜûW©áþ…•Í¨™ß=»éb›]×g“{ïKà¶O¿Ï ’%ÚVò ÷…Ý#H^_PòÆ®¬‘_Aɑ0²5ôP÷ù“M CånÞ«IÂ¸Ï +–¦/Ø¥I| öÞ¤‚ÒáE§ vWƒg2xÌ@ØÖ®‹ÞÛßûXñX7c!ãÏF9ýý¸MåWõ†k‡£ oƒè ɇ'¥vÀ¨pÂÎPY£ʼ»^„ð +;9•WßöÈYþ”Yi¤¤€ +'‹èØÑ<˜T Ž+IùdÝUݖ`ƒ‰M@½ÜQ¨ +½¿õéväÞ¸..R¿q>ӏÔë¤âÁ1ÇÞgDü~@‘Ç=Bi£Ø[ݔ¶Ž”²zýbb*ÅW]b’w§}4è+fgU?}›@z +w~ …R"‰gÕ{ ]TÀ Ñ48ÇÍÂ/¢h¤“;y(ñe%äĜÎ?Â}ŠèT®†DƒÁþ½g´Õ¨±_!|ï–DQÏ†Àg©æ×áÊÚDºÖSf˜òQ¹g³{߅öù;$´!ð‰§Gâé/ ±SÈGÃńmVeÞQòæ¢VAø¤Èßé¡þêVŸù"×{«å 8¯Ú÷þÓ/£øï‘äþä3¯Êþ¿› ùì9†Gœo4@‰>è~Û‚CÍ4J‚K|NÅçL@dóãð„Ž=½¬ëˆ(Yr+vd‰ðKµ0nbŠ÷¢YóÌ¢V#iyGŸ¼Øpö=á·dše`ڌâv®w³½ÝÊÜúó-oùK(u-‡Ù$´?²×+ìæÿIß°hÎ`Ð;å/Û.4¿Üð»#ÿ¸°ÿFHÖé×\VZÜóÑ«Q‚zÔĈ(¾O6!qi¶™RÎ]͝blzƒæf³ 9ƒógµ®ßµå’ ’4Ö¬¦I½еEˆÚ‰%£\u õ#š{”Ø@¿³šê”Àè}I“ü].ŸIœ³°>Š‹C¸î`¢Z=B÷¼„AžQ$œvè°Wžp%ñ¯BqÅ,6½ïC÷¥SšãŸ9 ­{j*GYKäà§$Dé“rùûë¹ó¨ÉDìxÕ÷ånΊsf‰´ ¾æûµsç|yr༬4ÑB¼ê¢•žë •¥ÄNšG½¬E㔎ø}éŽ'Z=?ª„AFH¼{ʒçJŸZ«¡-5w¨EÕÀïÛqYaç#¶ep•S)„hxòþÒGªٝ`œó¶Êb‚µÎÈ÷S^§ÊD*ʃ«FäB.lÛ@«þ ý.jÂÀGxÅFÀjžÏE2²Út[uÏaõۅô²ĤŠxÍOXŸ€ÖJ—ŽƒÚT9ÓÏ%däzÅÞù*·Gš¶O +ï ô(PŒ¶÷̤n•eÑÄ槄bQ™— ށ–o¿Zé¾i$ 8™R,‡#š¥ïd0Iƽ#ǀ=÷Ò«qß_.6¡ Åp9>ï_Ä:çÃß{ýZQQñûm´+¦É¬“ÚʒW3ü™6¨|`ÜÕ%v¥è'¤z)ÝxÚ#×g!¡YÝ)n4ÚËDZ@Lj̈́:„= Saöëiþœ—u+%*ø[ã] ‘¼€ÔñNXI` +=~+ÐövjH÷ˆ?A}A¡-”‰øf Ä\v´zJH÷ý­ºÂl! d« ÿû÷ÝZ­Ð¢£Ùò|^âÖã=¬»!Ó{Xt³2`§Õn´ÆÇe+ì«öáûNÉÕO¨³PX[=]l³”3_Ü*cü qY«Ž¾Ímö%âCà(ïü^˵AÝ)ÁÝÏB™w^mO¶g˲JÃFúÄ÷³6ûP§îk;¹•3<}xnwUÃØ0ؤ‹XÍGÙvýzÔ^Ô +yÿ„¤©¬§;7BØ;¹äš¹{ uŸa.=«ØØ-<òÖµ"°ÉŒ£¨Í£B?`SóÈ¡ÅóTEœ%cDìâªd€ÙűqÝÏUsw£OÔR¾ËՇâÇÒõ¡`ýL +¢ð§{îœð"ôM8lיThC«Þ’Â÷?Þ3ôNnŽE`®šgší÷õm¶óôŽ¼ÈM¢SS"˜ƒÀNÚ­_¾ÿç&aª¤…ú2µ‘)`ûhÁ¸ß°Yj¿óª§ÅaǹLºJòÍ@J.=|Üwø)RÞ]·±q]{¯Ë26 ›Ü=֝J,} +šÖ"!fRo7½È1Oº¥ÍªO¿üiGz­÷‘ +ïk-ù>¢@ú5ŸeTÁcíþ´žMˆêe¬2P¨¹Jš1T«ø,ºZ äëذ͟Ûï¢Ìm]# ± 2çÈÁéOïÞÔE:ÒüÖüïC±É2鍟QH¾ð̝rï )SŒR"·…ó{e}ÐظèÀS‘vG¡ÿUaŠ2€xRçUÉeƒeÚH’ÃÛ\‘¯ÕæþάSi|ÍìO…ùžSì|֌Â\w¯Fÿºƒã¤Ðj…5C(ëqðœF+Mk +ӝ›µè-¥r}|7£ âœU8A¶ ŽLöž5#P̳ÇïvT\2)c=[¢î^3s•¿%¾¿^?ù\Û¶ yíg¥çÁS9R7v€|J€n¬„‡öóæg÷ÍTSbiûuœ„¢qî|a¸ ìÙí*Ùê)ÿS­Ù„mk$"»e:Úo°±*Ö[(qÎX)yßQEk+O0ÙیœUÖå 3p9‚Ÿà,´fbðf·Âtúΰ“êÐIauËñ¡h÷ÉîJeç™ß½Uêo d̺–hU~3†ïgÓÓY7 Dj§}Œ(rÍÒQBJÈö‹ê¸Â>øeÑê{”õý¡;Ø=vC±µDçéH–Þ;ŒªëLz¤‚‚^«Ìû3ç°.·r@?¡S®<ïjË)Mz¾o´ËÄöJCÊn‡Z}^“«°Éž)±³ÖÏäés¦Ùw<ˆž]i’HäËÝLl‚•AÊJIÑÞ¿›ÊáñA±Š‰ty3‚ìõtcQ*ùŠ&Hwe¹ÌævBúT&ßaÕEŸŸèLdŽ?ê9Ü×çã +)HcKêÄÚösH½·ô”Hƒˆ Æ â|׆ˆ>ÚÐ\fi€vç€3¢®o¿N½e~Íäãæt{¼Ïø +²É™–ÏW<¿Q<Ž,¥}r¦£Ô@«!òøŠaœªm\ÅÀ9ÝU­~)éèïU¤é÷å×%âãa÷€¤®Ñ²M±=•c +ï„óœùlv¨|6uÈÒž Ïëøs|gª¢ø´"¯Ea{¼|ºÏG'ÔÚ™8‘}˜ +}ÁQ±F·­\kNB£èNƒ€ªÀ°òœ#ˆJ‘+—ÖR¢Í»´Ð©tΑ¸ªüö¨­ä¶ž½Ø¿{j¦” Èô`H ™FmjՁ¸lÅËêÓå½î”Ž8™65~4Ó¨Ξ-Gð Œ{/+ˆ&™cç]Ñ Ì,½M/²Ù÷”Óõþ““«=%îÈó³D[.”àiÎ{n#o²¾+&šÆ<]+.JÁ€±,dI[.Øöý¼Ÿ”ŽÛû"4:¯OÌåøR™ZŒ¦ùH3Ê£‹~+Î30zŒºÍùŽü8‹ õâ_w¢¾‚þøð]í9¡êÄd$Þ$$u‡îkGH8Ƃ§}Á·­Ñ{ƒözº§Æ”ŽßYà¬/aÅXÐÅÁ€àE cÀ¹-s(µ¶àJ×i~Ç ²ôÛ±’ùwl[ù©ö¡µŽ* ¿–ñÎY@É[”!ŠFʁÀb÷éõÚ5ÚAT™:K3²^ö@¸eÒ?žöyíø ïÅIS®j3T¦pÌ ÕH³© +óéBþ ý»ìYBÌ>aš`‹ å¯.^“…²÷ÝÚÚ3p/æ€È5¹q¶Òàš’“ßoh¯‡|Œ|ÐÑ-Ù+ëýs•^×$¿XúüÞýˆÌ{Kŏ/ øˆ}RæSýÖ»ÆQ¿Í)êW“nIS… úôÞɑ’‡–BýäԓÕý`ŒðPȶּĿ|/{Ó¾Œ^:#e,ߒ8ya ×ÂAH0ª/Tƒ#ó(—Š8"^9Öö‡Œ‰ÿàMNOo`ñ{0ÞæP}GZìÏóhE¡@¯9äL6Ó7º <ßGVvsâ} &#ÊüÂX™)e“^gJÿs¡¶ ˜t±…™¤ÎMïçôõmz(­s²ØÏ»{<1Ö(Â‡AUîvÌÞØipªÁ-l’l,#›‹½_uV +ÕÆïÙ´8`‚ñïK÷Ìs£îwؒ}û¨mÓN­xNV§]-ݍ̒JJµGÛc¥ƒ¼¸«­-ñfV1äý”‚Áú°·t…ã5lLÙy(˜ð ÖFHÆz9$| ¿RmԏÀ?§”ñ°žò|:ǁÀ™•ý«õçÜÊ®ræ‰æý.vHH¡ +[Q'¯D´‡÷²]YTnG«bŒ”¸Ð¾±¶Ê÷Ã(ºÒ€ÄMÎ8Ê/¦?ÜYfÀboÝñ ¸Ë¦h#âÅ2–h~4øˆÒªßU%ºÚçHYFÐE}¾‚$*3—v.#ÊÝ.Þë,öâ:ƒú~ +íSꝺV]å„7±IÒ®¾Ä< ®ŽÄ_"É¿¤IìýfpdÙÂëY°EÚFr‘ì"ú¹«|ÈîìçæÝ©øŏ`¥Oè(K‰(Æ$ŸS´ÝŒÌô±!«O¬ΘÓi§V®>ÒV3´ið7c ýŽŒ¦=t#½Ì#íL]æ%ô)¨jT ;iãÊJíhއV[qK‘ 0ø)Réý‘ËV³1,/qDš¡³7)RÑ'Z'çÙ AÏê¯cšuKBƒ1ÏH—‚¸yµ¨Ã< àÏæ;q% Ý'IËeOá֚çOx®Õ¥iŒô«Û`¡©¿¨µ&Cla±ÆKè_¯_ +(œü¡ŠÖϲI£¡ˆ`™©ÙÏCßÍÓüD“4j +vé²£¼_ iDËeˆk”2ôè,^Énu+r¶ÐS/“^äh´?ý*¹üUž— !ufjVçL™‡ù(|e:ч'–@eµ#ê”ÜôLá=g¡¿T…ê"µŒ…Es[•N¡Êǐáa£úk¡è:è{`/§­ü7ΐF)‰¬Ùþ²j_U–ŽúÚ6Á§¾i®‹wªn»@Ý¥œZI‘¡?7&ÖU‡íkv=Õ¡f+02ªš›$Ó +ïrWŽh™bw¶é¦$¡Ëž£j§ b$…Ëm™șmšÃJe׃§£?fP3SpÞýÔHð\ž3V{bÀ=ž‚Ï®êg¬Ï¯ö½nØ+× áY¡ëº®º?jWl·©•Ý8E5“•}‘ÈKµ Óðñ‡2¹Îß*ĀwCïÕ?ŒNIRQnqJ¼¥V‹‹‹å‡M6” Kªœ½ò»Õò“ª¸È—îm3‚Ýcj—øPܪëi1˜Ä‹Û‡뚖” :0-v}B®ôÝáà +ˌ %”¢IÃúºgìaÑ«¨Ž&%È[—x=€R•ú¨eÐRR¢@j]V14ÕÍÎB9ÿœ4þ*òv R8w…v©É ,Ɉ¼ñjé_èVõ2ǃsTZq±¨rgi‰ x(ñ edpÿ6Ž‰—LJ®?Ù}†pöç½YDS·Ú#­ —”È.b‹¼äe70p#Ïé.`ýª¬rÙ`øFu¦ó™ǟY¬Cv‚ ±^›³ˆñv„‚b }]·`”5ŠôG£‚óŒ˜J††À҃´JPEº0¥ÒÀñh*7Kßê}…'ùx?āù¨­:nO;„·8À‡ÈËÎþõêLÒV3ŤÔîÔhŽ%æs–(#wiÙOcý8HßWN,ŠÅ<ñ–¡LÎOGÌî9º‰û¸ž¶¤jRj `Lë¡[¬'Û8JAiv“=MX·Á í,¡؜£ +ftªµ ”FqnS$›‘ؙڻ¢ììÆ:†ºG°$/€.$ªŒˆî¡Ð¦¯#úüyH¬I؟z\Oor\©r쿣êsõþ)²Ð¼"”qƒ Êـ˜^nF\àþ“QòŽâËPъ8 † Š‘<º•üq­ˆí¨ûÅ9I‡˜‚¿d(lìá X"ËJííÁ9Q–ñ{‰3¿l‚„HM±<ëڕǢÑWA#Wé?y–R²Ô©eQÏIÇ1« Ë ìg!Egq2Y¹˜½¦)ð[ŒÒ(ÀU-¼/V Xzƶ$Å/hð¢i1„o%” ¼Jâ >¦¡Ý²æ~šgD+ >L¯.qʙ¶¦ +v„ݸÝ1µï»¾3ÓY² §¸@ì/.˜à/:Ê…ö…M‚8Ý#¹B>¿{­ÕÒ¯Rƒ}fuFPÀæ<™óœ=^]"½ÛÀGî;‚ày ‘)Œ°4J;Ç#{‹áhŸrÉùë¶~ì» /{ ÐOX(ñjiÿèˆùÅ¢ÎðÈð2äú•;)ƒ‰†Q‚ì(V¬·çŽf‹£æ¢“¥ê¿¦Œ²V-JeócțL6߆Rgχè\ÇH˜= ¨ÕF;VP_ó•óý6B83¹êSϽ£µ¤C¢úêZ +ŽÐöȨ™?Ø\ěåƒn>ÜѪ‘=ýߺñ{«±|´Š+G(Ÿ< +¥7Z᫹̠ {lW`<öÈT4Ž&RŽ”y}uš"z Ba_’‡@ ݕø1)?ä2*Õ«¶t›®Öôõu ìŽÁa¬/í¶Æû©èZ&¤¶¬'Àf‡3!ül]ïA\Óç§AÅb5m!KášUÞiHÙ7яO,ÞYX!V¹åèÜ”­qCØiÔ'fïQo’ýèњc“RÈåå>T(# +nmCQ¾;Xû2½àx×]Ÿx²_2^c&ÿÐɘ#Òº$rÂRñ¾òV{õPš}KÃ+¬©áŸ#˜ÝûQúîªÂ=eUÁø‚dmž0<@!=g0“®Ì3çõÑþÚg¤¤L•¤½³Y$¢pr]Ÿ‡hœA-d²¬£e•’É +T<҇×e«¶ÎÍ4]Àœ\==US¸õ–e‚'a۟º¬— ÀítŸã÷¸fÀ›"ôìL(o¸>§_,,'þU›> $Wyø”2ÇWíÔ6ÕîlÌÆ΂Çn¯»²Ò™¢õ§°BuÀö÷}XZ[²—ùÜR¿ï×-ˆ¶ÄŠ ó*t³|+ߜIËpŸûÉì£ó_ËHEŠûˆé#jgS|—Š³:ª2éò·Ç^[ûpª”M#dÎë$n?-%›Æ*ß%uM_å2c*Ä« ™-t¡še©e%Ɩî{Dvú«èw*Ð0d9vŸ^—Á„tWÏ[”ñ)QB@+M!z3¬xh¼çÌ12)® KÕ캫í6²•Æ¢lHOºäwé)+yJ†º@(f̔|Pšâ«¢T´²VÏ S#|E¶…éŽ: 9[âñç§s6°ƒ’žfwiZ¦²ÚÎKÛ´Ë?Â-¸gœ+†¹V6¾Ãåtp;ò ŠäÊy…Qe[çðЦŸ1¯Pt?~'ƒy ¬:ô *ó¯ëÏQjWcÈ䡂ÙV½ Bî%”§èj'?ÝCå™ÖVú§ ZÃ^F›€¡aâ­­ö©»/ñt‹rŠ¥]šxü3µø»¼g/óA;6¼¬„YQ øªÙ]Š¸ÿß¿ý¿þÏ¿ûÿôÿå?ýÓ¥_ûïÿŸÿòÿñ?ÿ»øûÿô_~ø»ÿûï~ü»ÿß¿û‡¿ûÿî¿üý?ý×ü¦Ýß¿á þÃ?þç/?üýû§xÄvÿ†rÈû7üèïþÓÿo¥`œ/E…óg#ÿæ×W÷Ÿ_µý¯_0~~Ag¶ýõ+Ο_qÈþúŠóû7ïßþׯÿùïÿá¿ý~ùR—¾h:¼S¿¤mu@nö_£ôå~nŸ”ØaZýŒ¢ÂS5  ¼Fp”¹8ÝhƽëU6Ü´ÿ>EO óþ‡f–)¨å¢¢?™¨¸Ï̇a;ËW”Ç/š² Û· ²eŠ«ìic×ú€¤H׌ Aoäœð =xl>ÍÁ"ôûSTô‚¤©7¥pÏR9‰21Ò¼Qj¹”Ú?ÈÌ´ßÁ'ሦ §ú +-å~ãíêúT”Ï8)’Œâ_š1bàW--$ X¿‹íúׅü¿ìBþVÛ½~«¶{UÓáT'Þ"Ð(³\¥lÇn¯Ìýh£ X'°Z8`+™ÜíªwE2XþK¹ÅS2a·ísD¬×¾{ m`ÞZz¤ÄM©­4òé•Å:)ʱ‚ŽÀ¨¾…eIäIimÀÊYiZ„S…"¢àŸ®t¨…I +bN¼0O}êx,.-(Øt(ͧœ`;÷}TR92²¸TÊ #ºÐAK1[õ°Ï_¥Ìri<ïÔ©(c¸U|´Ò"±9µÚ@CThhô £Ž-Ē‘Ò¥ÓZëû–m·6÷ Ñ}B[,.&J§²šžÑ©Éõ,x¬lÕqðáÎ(èõÜk­"†fá›Þ‘©¤ +rA‰Í¯—ŠÑÃLl„g6˜M¯dȗ5±µ+EÍþà[¥à·ÔtG•p8#ZÍÙʵ¤áH]7²á³¾ßU£÷<²Gºõ5+€¾Ùn‘Ü.öÑ{•BåùTÁNKKHV#gª¤°ŒÉC–A¾Ýõ¬ºðUŽäFèmv:’$€oJ¶QÖnNítçž½ þä+õ8*}Í÷ÔSšßGIÞ_|¯|œE'FN}+¹nGK¶ "3`ªöò=Ÿ¤[O[†g¡Éê)ŠñÈtoƒ·[}Ýh P!i²Á‹P·OšÍaF‹Åªåb 0‚åšû!§Ï§~<£º­>‹3Íï;¥:&nÀ‡“¥»í,$â4©[òê#¹³ÛƗ‡éc@v. ú¾ Y0ÑÃc-. ºV»ˆŠ´$.Bê,®å~„‹­ ÊñK] Øᨠŋ>uùèV•#WÊC¾×Œ¸<ûÈҗBhjЂ—†ðïRžöÜJI¥¯t“ûžF¨6ˆ!I„nÓ·ìmŸÞ¼>ƒ]‰VÛËrUÎl,äFÇU½›ŠšÎÔ·I eÈRo‹á¥ê(6햼n幂­‡©¶g§PžÈkñ$Rd&†ó¼Q«Âú=ûá¤1®il5­ìF–)@s¿ªá·Flçޙ8Âc.;¿·ýì ¤Ó×DìõEÏnŠÿ<³R®: Ï|ɯ¿qPþ寧>ó_jÄ´Çœe€áSzêGÀnѳbŠA'±µí„@€,A+‡Þ×b5Ê^,ɽCÒ:Í«Ýl˜ó&ú—N$$÷õàFŠ£ZÂPÕèŠt¡DÓsò«Ä„h±‡d$+Ôy‰4D€óYÈÅ £‡6F^ïeS) •pz±bÙ9lešÌ]Ýçó ‘Í\ªÆ_ÓÿuÒýmñü­ˆxŒ)gߏ;ÖíXpé#›ˆºÞGã)Œ@x(ÁVJ|jN£…‰ÍW¢]Â:DkEáÿ¹:¤{ÊRÉE(8Z^c-—YÕ%'—†Ã—@¤$-ï:D”Ò7{ xªælOxçGY':~¼‚ØÒHyÜiÚ[¥ÂfïُºŠ¬ EÞ#2CC‹¡(5bŒ!dÂ3¡NԎðh;C"ŒQA«÷ü†‹ÆY)>b ¿¡+^]ëÛ»,{ŠJK•}”܏UÏhµA¨Ñ€¡ŽEpm?òiƒ&*ðÊ3¹*' p£IN‰ÿœë£1JJ}ʁ(ænévèÝp‡m¾BÝéˆÈ<ã«ÒI ´ËÃ>U\Ö…0]2| +𑀫Ô;aú©b áZi*èÌ`Ä¡¼´^d#_û*F,À)¶$ „ +<"{ÿ%ÀÂÈ"IÝçEÂUŠ!Ê9"Í3®BWàD©­¤!)pGpKeLkÅ1}|Í)ïu]¨vh‰\–òþÄq€8fÔCâ~MðQ»¤“Ú£¯øߧõ¸ïh¬­ŠWfn†ˆê¬P`ݝwZÍf^ó…xUKu‰6ÝÝ?'’O3þ2»Ø4ÉÅL,çiŠ(÷·i_–J”´ISv¥ŠÂlN•DBoAîª5Hž…èÜ¥“»µáõӍµUÜ +¿(†¶K6ëcÌmd¯^Ì©’°»fkÔæŒé9‚à DfA·äϗ™Ì#S ÷ž(r 5d½F4“]p«q¬ŠM¤å¡·‹†¶j†Â§'FT}fɎ45CÔæs…L¾*,º¥ô´áŒÒ{¤ÍIe1*“¹aNÉÝÒgàq‘5Š†9#‹6£ýJi§[YÏ÷³ð±Ùï§YEÏ>°µ-F×{|÷Rk€þ…Kë>ŽS`¥ +TJ6ƒÙDëK½Û7vû¡r2­˜»$…U±©il‚Ì\_¥ R_ÕGSìa2xxÃSg»ânÄcÙÙ’nÖ]š®¿À„’îºÃ¬Ü5¶«¦ G÷ox×úÀeÔOXQOÃCÎ9£"LØîRk`DgäÙ§ØVQúcmZ¹»«Ԕ¢³‰TM!bª«M +.€ÛF}t^i£ÓÓVênç) MLxãã1FBg/ªX$g 4|ÙÆÒƒ/åº AŽ ²ÊM‹;ªâ³”¶A^»ûžÉşÅÝ©«r¸«G…+Ȃëˆ_ ¾5Wõ¿ 08h¾a»JAb +,âä)߃,8gaÌ·¸t,¡J‹¯¶Œ ÔOkóžEÀCe3ä#ÛZKl¥1e01ZHNPf#©ˆKf´ƒ؝H'!Å u?YÞz.HE8-¦Ý#ÆY¤šSû‚á´(Uàò[ÎÊ.ó´DÆf?AR¤D,5öLpÕS(0࢜ˆ‡Åi^}$"€¸kÀ›6JÉ¸žáŸI(1Þ¥Ðĉ‚Þ µÊñçKâCe9!Á³qDªW1ÒøºxÞß~ÍØàÈÇ0  'ç{3å³ìñ¾ž÷ãý©ÔUêÞð=Ä}¿3 Øί"ØßéÒýó`ÛG/ÒPO7çÇñ>Ö4‚sR-1?ÜDè5jsÈc<>Àö!B Pò-ŠÀ(®cnÂø;.×֚Åÿ È R.úóŽ‚=Å7 +jœ׌ ìJÁVÙ.Ð˽"³héRîÖ M(22ÇӜ‘}*|=z‚17lAàGTG¯ú0äë!8¢¹5ãy¡& ÒCH³aæñ×½ÿˆ÷ú­¤ç ÅXžï¬ôL 0”ÁC þ‰“~…н.—qY`ºn½$` Ç ¾6×,V¨/u02ò`þàL]w‘GÃdŠ̍Dšç ¥ü6çÈ=Ÿ…>Ž»Õ lЕM’·Rèޖr±ŒŒ"¿øzÓ +endstream endobj 24 0 obj <>stream +¬÷ï!*àŽ%‰ïÁ¢€ßw°Fu_Ò,—üý’8Cü|‡¡:«ÀôJu¼=s>?‘tÎ;ä ÎÛ¨ú»À8¸kCW0žýÞük¦"õÒÄk[»j&Wڇ§C¨¢Z)Íø’ ÊÎb¥ZŽà)~ýTOÙË ÇÀ¡Þbjƒ5„ÊaE°B1όÐn@ö§ìÑ­´õ€bjŵ£Ý¤iBWY&Ž·1Êç. +$/¨²rWt ”\Oï÷Ö*F[Ì×ãÊÀ :C)Òʕ{yƪˆƒã,óþÛxí…]!X©C†sRïÛ󷄬ɏ˜¬Þ±`ÍE©"Ó:ò¢4w@;è£ú}Wÿ„EW>"¨)M¤¯Òµ·º†Xe܀+=–X”v­$ısÿi–\}g+¨ˆåç)ÎW8œ‡5ôg¦bŠÔ¨HEÀn¬§ÎU{¼ËŠªö“øÒ.ä}Û׳VPN¼ÂDÃ\B3úG¨i mÇVþR¬øÖx£¬ÝEf㪲Æ9ûŽŽ¦í^üâKT›áOmyQŸ¼§ìœ«´c¯M©"6vD{)¦ßýƒW%­°+PadʦXÆ»—¿ÁNþáE=U@~”Æ]í!öÌÍz/P5ûÕT÷î¯åMÏEz¿®,—w|ÀWË÷Û-åó ǘUÄ£/=‰£gx /õ²×Ͳa^h˜`ÒåðHÿ]3†;L/ûz©uºëp‘aX#2úéê‰2ÓZ°•JçÏlƒé.†]ô#ÑÀ‚y?D¾ ‹PçêEĄÙ>³j¤£³>¥xç*m:JQ|mÉ' ÑTÖ&¢–qF «*_¬G +÷ÖZùª×QO˒Ø0ŒXe—4¿¤£ŠPz D l?ÒüiéÑ2óª\vî!Æ,Ê)¿Ö³ø5Ë-²½¸å%Œ@Ù,ÒÌÑL&Ø] e~ÌùÍ9Pz:AÈ{.]iŠ‹:¤¦Æ­±«ÌëÒoÙy2R[ˆ9îæ!õ1‰– ñœ [1gÜ` w“‡PaKUXW%f?gt_O(a`qcêö\®™ÖÖõPžé—Û¡‹èö³ÍšgŸ§0yÊUæ%2÷j+ïÓv(ص•ÿf“Gåa¨KpÇ;³ÎuOÇþDþ$ï Þp91 ¤ÎÈ{Í~‹@º,ï^­HÝf+N™B{G]ãU­+kh*kDð;öštà èG¼%Ù­FÎÕ)Úøžµb?©& «zb¾U«(EÒ·w˜½‚™>'°ÏŒøpç}—Ü@Ÿõ«‚ªoÀ±qF'7dÜ;ÅíŠ/ÏÈÙyÆ·UaX_‚¿¤ŒâÃáÙÊÝ~d&¢m›–`DõëJmœÝ·ÛS7—?‘Xâºp<XÊöþÑôJ£’¶ªIé¹³g¿Dp&ÅÏd6}œut{éB .ÜYZÁÏÙã×aý¬ËƒP,á`ä¿˦¯¥²ÄšUÌóG Zn®ÔƒJá¥a¨Ò‡óù±°[¢þ9¾¹ˆ*։äovU‘@v¼æöy‡†Ä³€zÙ,Ïö}Ö“g\ßstFA³ï®U]趄Px’%0žÁ¬¸çÎ@ñ„#hÙæU2=cp'aÎAI_¨êfF‰• +gÀ %·o&ø€z~׺r®ePR€™ÉÜQüG¤šØk~3¡Øê­ä¦³‹¸ š„HQÊ ])æ¦inËY~q¸S|”#¢‚8%6ý\ë¸_3èjÉCÁÆÌ ´mVL±1­·¤²QSÖO¸<«‘–%ðŠø)jo¸€‚z>² „Ö~1hC´_é†ÈƒQöŒÓÀFQATÈµí¦!1×ΙxX‰TD¥aÅÌϒ8ª¯ZÔ%f‘`~UƒI'fÐýzCRÑ)+Å"P“Á³ƒ•*ÃQáÂÛWõ¡fÆõè¹²÷£šP%ëåw4ßä¢Qê×+ök箉¡D:2CHôý]uÊYÀ)ÃkÏÀŽ:““äVc¢HەÌs%፥t2PëEöùô©AÉ«’èC^#JGçun5tïhª +Êö|=¢¿¹Lҙnû6åF†s^wqÜíï#šDUò€—446ñ£E÷²oI ÅWyJÄςGiþ²½ÔüǪg­ÅÂ7e5=Ú~Êå×a‘lø‹ÍTþœ!’‰󽌉øÒ{Ô´ÜÅ(*I]Z++®W&û‘¥PÒFbpF‘v<^ʃã§g1´-ò#ϵ+¦LX]²º'\ê£üæ^)æW¥ÿxŠ­~y0yT”æß3ï.n‰Á‹ú7Ïòý(@uÍ"Z5<«Â£÷,g åײµö5Ø«R>¢|=jS‘lì=²§ê!ψfõÕ¼öóˆ(­#ëñŒG6q}×[¥$x +ÊÂ1âvtue×óùèEN?„N`åôªªYÉ ·ÔÞæÕÒC”Ïé=Ni’ÙÐ"°Fót Ù5£‚"`Êg»Ó°ðq÷šÄ‘yrr]÷g‡©çž‡¦RÒ¢$Ýx'€ËV0ƒLÇ*ÇksÆÇQÎxðsÚ.JiP…LûÏ%¡ÏÛéSÀRÙiÿ<‰—Cf±O’òQ–¥G÷Ì°#h½Š«w…•/èQB¾úP¿òøFXïj(c ²‹ f¢å1!-÷™Ï{¼%u¡,ËÖiQŽ0%a²ëÚ¾8ÏéÁ'6=2oU¹ŠÑ¸#è¯ÎK#„Äìy‡ÀØÓÙu›ÃzEW/VçÏøÈl +µ“f‡t¦&¤§v‰€Îe€ÇˆË¥î†þ%Ǚ|É­Þ#·ÍÁ«Ö2«ì×i|‹ˆšÞÙáðâTn–“;#Â18Ní×s3Ùä>á†çH§®H!k{ÏÈ\‚Z½>K"G3,Œ(îSŠ¯{KÿØ-‚Î#³¥bÈŒe! +bÔA)œô³‚*=”2ü¤÷£úÑQsXŠçهs UÝxÛ¨0ÌÏgPZ Bˆ3ùZ|Þh¹?Ú±4­ÜÄjáëßFñ­[úÅëéØÌCôK€lWÉP|ђìXwéòñ«Ìà?º\R>}îýؘ±Qê`çç(詼¥ÓP—Á¬Gm•¾@ž×y[vZÜ¥2H;3yE¨«–Vp ͟®pblN"; ”R+Æ ]ú(Ûؘ¦•"Ž-¾/J¿_áá"›‘uµh!^†,—„-J&jw²»°ñºJké:⽩ o bûVWÝâNx‘šotUì¡þ2Sù©+?FPù¥{µµ˜+áÕi’ÏåH›b2ˆÔ”c@î|„‰xèÈiPàÂLMÅ ÀÓ}Õåz„-Ò;‚,jvE뗍ɵR¹RÈZ±¸u…OY.óžÅ¡j+’ pöPeŠv•º,t¹Öø4ǞŸ ¿øV:«g¥"óØ¿bQy?*ˆÛ +ô³I0õ·zö»lÐظ´¼z¾+±L´…½e+ÐË1O˜6„2§^±oèdÂ|gü3N±û™Z¿Âz6¹çôõ`euq›2•Îq ¦Èߔªß«G­]½ë"½];È;âpòñ¥"^GC‚Ä:Ô¸Ó:F|7,ПæýÇLš-Ò] ’»ZR+Õêë*Võûû BÙHºíl”É®¼ã—4×EØCۗzÝïL_-ˆ?*uïŸÝ³Þ«¼F5‹:Ë»}>½¸“òî´Â¨eD@û¦¦˜Çœ!gE-fªƒã™«×§QÙë”s×þôôl¸Š%(ma¥v]Ñ9y:v)Š$0AwZ&ᎍ`L”«hs˜î„ +Èg“:q|qNSoC‘Q‚§}3¢ÊòEˆÕx +FïWþE'ƒâ¥v^MÀ„h~ȍR9§&¶KR•rt‹ ehH£ÇùÞ5¼` +;VÙû. ܴцbÓÆ’Êñ]’]ãL<©0Åõ¹¤Åñ±k!öî®Êè &¬6%¶~„ðî®sõ¸2ÈdžĈô=p²+´wõ¹#e¢dpK1³ËÆ÷o¥èýªóuTŸ‹Z šÍÈô¶/`hviüg[¥ØØÁ’HE^¾úهˆ³c_ÄLøûˆIÒ㽇òØßt"R20&tÿI%0!Z#ÆK­ö†îQ÷¯q©Ý_ájNŸåS¹Ê1Úe…¼¼D 0^@sAewÇTx_AŽbc(?±EÓÜ:ŠF(=Ü0ñ½(rÑSÐèî"Őßq¬Da€|•ËظôõDĨLDm”žÅ.HTO ”¨}˜\z>Ž26ÍU<6πtÀ~ì•ԏSF~Êæ +é±f +>«Hi¨,I8î„Q†áT¼h°«)l–Û è/‹@aî/;&ã\=†¥ì”A?6™`eÏTêΚ7¢éZ€h +ÔÇßs\Áx©pviüÕÏRzU$îuç[»8x¯å–÷5÷ÎU-ND>QÉJL™÷–ä*,tü†ß®Šæ?ƒê‹¾g~'Åþf^z3î°9ù>åZ >FÝ ¶5ÄiÁtŠn-gºmX ³#*pk&œW1úpG¯ÀˆSnã>ó£=£Lóct‡>ÜÖψšHWð ¢$£¥g鈟QÝÝe}hi€] UFd/®/:Ï(ª²ÇXæ ûêÊ”w) Æ ¶a$Ñãõ;ÖÃj^Då"œúø¼Ë==Þj¡é Â}¶‡ï1ËSÁ7à:Q÷•3Õ]åý%tÊ\‘ÁÐHp'iÊ.£êÖQhKRyÿæ:"ÑE®’ô>ÆidzÏB† `†?Šì€Ž˜Jz>E‚#Þ:_Êfg&^]â;>‹~Ô ƒ×†¥ÂU'‡ø"+Øv臝q¡õŽÑ£#…ià9Ÿý)n]Ð(!%Ÿxƒ»*Ì{>*! Þõb‰ðmÂWTÈÔÆ]Âc.×o¡ã .[Å]äOaqº"‡µî˜˜æFË%bG˜ô/QÚ¥âLN+ˆ•œ‚$ Ä%-¤©õ™¾&°àsu[’IJnOú¤.`Q’GLÛßِP;åiB®^’ñ +–¢¡×àÍÀ yÎVB#ò–ÁR…A¨5¢4ɤ0’¡µò¾cVPvGðbÕï@³ÀA€*Øsvp¿®rí4<#!‚`Ç-¬¨¶„![§¦E\«÷ ãû|‚MÊŶ”°V"úQ +û1p¨‰|½:C¥›©hìrQꌻÅÊ ¥•X®˜»Æ&3ª3È)mGôƒ˜!¯( +Â\^LྯBq¾'<ï qWÄ&µ?ä}´ç¢Ö褵Â@$AŽÑæ°Q“=šï­®I:É¿oB™kZ\-¼(Qå¡BN]"eTå¿#ŸÂÇQx5Þ¤~­šÅ×Ê=È&uHuÝyø¢%~Œu†~osodl÷ëHÀvÕ2>¼_A¦êþŒêìŸÏúYîó;ÄʹR›ÅAóo’¢0¹þ›¤(N@±ýŠë—â÷ïýŽùó+&Ëúe”2›[fyǏϨ–¬²¡v¯$Úsd¯atÉô=oè™üï’ûk}X0S‘õÞE›õw™tZ"û4 …ªÕ±v=HšíG´ÝR‰¦Ô•#‹¼’”“ú¥~~3øŽUÈ/!¡¦%³{Î5¸÷->µÏߣÜÙ½^¤ˆøŽë­í_Õ{ÝÓL3œ9ršßåAüþv3õíûŽ7 ÄüáÁÙ#6oOˆ´ŸKΙ¬:ç1A í +Þ`ϒª3(}îÂÿ†º4ÿºüs2}÷ñU7ôÂ)KM¤0O‘/|X»`;ÀÇØü Ë4,}¯ùäíï…Cc¢ÌD¢Sº×çšØ‡;f9 ^:5¯GÌmGz‰ä6õ ŠFóâ:Êõøõ”Ižו’2†¨ü ‚ÙRï®l)v^§µ¢}Ýw¬UÃ.™J‚à^zWÂ%©æCƗؽ¿˜d ï ¾VŽ½! Ï »‘bT|ÌE’ +Úë+p®¤—DBPí.oB! ¾=|v˜±b̏hwð +È¢¥o“Û“Ÿ*³ùî”èf†ÍßPUÙUˆ;ѽ>ã®Èw_ +Û!±¤< Oô°Æ@pÈO;’ÁýóU…“pCZêðü:oIÒ{šQïPŠç@0 +¾ùN•TÑ”¬HBAÊ|ê´û°«=›I4µ,XWT{ỲÑÞوt¥ôÐø"WڔI–[q{Q¶Ê³µRrÊ µCâ”ªD€nPDFËÁ'ÀXƒ]žªÎ²:yÈn¿,VÃYA?*ñ©ê¿Üö4  6ñ'þ®÷ɧ€<€öeüµM™\¥08Ðw"l9c¯‡ò Ót9Íd¦5³ ·#ìׁÞ3wÈ9Gðë “›»® ?®277l˜#§—ÌÎz[›6¤#²µâÂ;녌}ºÏ Ñé¡]پ՗þ·-\ œ˜E}>¤¡«œ5€¦èDó…™Uȁ¬*.}ºªÅ¯²¬ŸwB¸õðmËýXŠ=:Y^¤ä1dÙýàPÖå25ò¶48xª«¼ä9ôÊèw|-™%¼úNçBalZŸZNH¬yuHJ 1EÖc`±#™ÏÊàäó-꒲ÓÜ´y\ª|Æß:Õcµ°•)°{•ûg·_¾Xê÷‘†v +Çû'l(u³‡)Ó¸x$êå² Si­±YW+ÈpjÏ4P|€çN U\ 3çŽ^ðb×k›™S{xa°‹V˜oŠ…YìØTÁpúXçó€T¥GRÜÝ{ª—ôВ:ÒÒ2¯5Ócû!£É<óÿȜ`•)vwÄ9–&=p¤cå©Yz¡ŽÍߒ&(³Œ‡ìCM'Mx#€«*W)ïS¢Ú}Uú«WXq: ìË%wˆÑ×8R%֐Õ?ë ëjvÜ®]¯8¬a‰7p‡Ù»®øÙ¦ó;µ‚À8Š= ”V¼¹gº§ç „ é¬ZÊd;¹Åý‘ +ôIɜlŽ“˜š¶!Þ¶ ±›mQõø¤>LRÚ’·œ%ãðCP¹‰ Ë`jò¸<‰=f"sp Å) fÚ.x9R,.ì©ÿ¸ƒ£ÿÆÁ6wB¦Ýå‰ÚÕ|½“€ÓI©?Š±½Ÿ©M¶Ÿ¸ÓqŠRweGšÜ€ŽÎ¬F¹£lý»,æTŠ©1ötœéV½h]ÔæϲÂAXû(»ÅSö‰â“Hæ( ïLÎ`ÜÌ­|7¥žæ£ù8472dB]Ž5Y¶k=\d Oœ…ª« Ö¦àþÖÖE›£fç£+Ân3³}C›+N¯¨ãðþ~ü:ŠÌsDÌô-7¿„ítOðwê$x¤|ÛjÚ`'wúC­¼i[:'Ž½oÖÓÒ9¯ÖÀŽö«ŠÔ·rÝ*˜ï×\#aÏnkχٛƒêc]L½äæŒÿ;cBïé„Y§ â盘!eÇUJÚ´‰ë*I¯ªxë×%rêËrÓWàpˆÆ]¾%³ÀÀ3€{ï°Z +4dwÌ¡¥¡2ÎÊì»kñg¿Ø‡I`N^¬|f`ëMø_™'Açb©Å$P1"¦®Ì˜sË.a-çãʽTÀŒ› ûçÖÀF³8ª:Wîߗxe‚ãÔ¥ˆö^ZZ•³bH­ *ÿ-W8õŸ pµ*£ktEØÉźYJV,àô¯0¸»RG‹¬ ­§6Cßì\k†1¨óŽ]Z}0–®i©í05”3A‚†L::±¹ÿš«Ôôk…îí«Î9€ŸíCß#›ðC­oîñ&šGá©Áýã´è6I¦7oc­€ú³Â‹ì~íªX¿_i$Y¥Þ:U)Àœì®¥g¥æâºÓß*° rÄZCrëwˆé–¼f,Õd‰ß¥”ÿÇ>gOf>*¶Ñ ç–ò.7 + 2唓^.Ó´& 4x*¿‡ 96P犓—ØwJ  ÞIAzˆoßeu¤•eŽr¯Ýíz‡Øgî®CZü§Õ\ç*7">Df?<›VdZüµ]¨Ê–ªH4Q„Ý-e>›ÝÒʹ¿Íì^PIThXa]S‰ágÛðî½9<”Z¶N›Ã÷ú¤V=„Äpü·ËŸ }~'ìçGØ,:CÕT$]%°ºêå ªV‡2˜sÑ:àÁpÕ}úðKÜuÊð”ÞŽª—ÚkãÀ‚w$ÝÏüZ·k¼¢¨³Kì^QU–}Iƒ>ä1Re·¦9Î%&Àš´Å;2Ð+¬Ê&âSÛÈç5y<„º^|ÉTv;þÒó·7áP´Âwù÷‚‡ZY¡Œ!…íü×,qTҬɡVŽßÝ(¯¿±j~'Èÿ2kà šþж÷Ù­xüd+v{R4¬Þû̶t+]ÈҔL°ð·[…èl+Ê(Õa‚ÛÞti,-·á³Ò׿¾ÿëý›jû¿åYÚ?>\ñ¢âÉ04à&óIXrVwÒ©®žZK;î³MèÖé½£»ÐUæ·ì„lMÓiÁ×Y¹ÉQ͍zìç±­æ*Œ`ç]ž÷»­þa|õ¦p7²Ï(یS ª¬ô@g¯'*¡ PÚl¡`6â(F Ì#[ZEYuԅE¢ùó0_1­ÒƜRè]$µÌËô‹ÆEøÿ·5›2V[!)ÝKca¦Ò̝ïµkäôtùšo¡PæAµ®8(–§>!}F@ý¥×g*½—šÝ =B²«®Bª2f½Þ?½gé!ÔçI<³_¾üeîe*oéëÓÛø²nWnŎ‡-r`îGè†/.yçT™9ė%Íiè«®¸Š¶ÒVb6č”xã:>Q´b—ª ;÷H}N"ýƒ¬Ë!m:÷ú +¿µ?)6¶õPÎåø·ôg®G½† tÖÞÑEí*Ôs†ž;“×­D†[Ɋ2ƒ³^öÞ8μÌĕ3ÿôëè»lØ÷ã¶sþdÃæ‘Äކ®ý{çs*hå°‘«V®:+ëÝ±KkžÃVVá‹ÔÔŏ)@H‚K:/í GIŽI·ÜÉóm{VmA‹Óu/MÈÛ#M»’õg~£œ{>bëG),\ª_Ñf0Y oV;꺳XÉtR­ý²§Ò …4(ø¶³+©. –´"êq”„ß,…½.1‰]¼+ü™I0ô»ÊÐÉêäãr*eÀf_ª·%’µ— Èǝ}œ¥†ˆž:øð2Õ0¿MàO[@e$ZZ)ª¿t['x4âñü—wå½-ýԅ÷,ÇUÉŒDàOðŒ&>1Žngt¾æ›Fc`Ž§=1"JÎo–b­Q6M1’ù€@îèÌpŸ)€ý%±êTÍF8ý4è”ÐÀSÜÞÁ“ðÃßU£÷‚sdºÎ9)aèÌÒ/ó® þêQvuVEŠyª!¤Ì£VÖÒo=Ä4óÉ°BA%c–îÕZ)ß(àÏ ´~Œ8剜¬hµ2°á«¢§É”xuœÏÈ çk® >Þ"ڙ··Â¦¯Ƽ•Ü_gmž¿Z±ß£™ŸÙò嬏WLÚë;s/;IA»<ÍΟ¨êJñø šå*ùKRð˜®Á">Ÿ( +霱Ö¸7þ–$mC3\Ü>öd=ț†ÒA„zh0M}¥~•2™´K¹yŠÞÞg”wf¨oî«V³Ô½˜*E¤¦XÝÔAnxáj!V7<´ã§5¤ò·] ՕJ¡Šê’“æ%;“f .=&Åï›û~#Uõµ;^8!ƒÑ·¯{è={©IŽJN4ûàî“üV ,A(uÄ ¢é¡|F±cJ(R[ƒ¼þ¾>ŒaÅÊ¡›Í'G¼p…enÙRð»ÄʞØLsw©VÀ3UêäÝR%êžt¢+¡«oW>òGúF(ëë¤-+óöËêüáKܾæ7Ê3Êہn x™Þ÷g +>âE1ǽKt¸®Œ’‚ƒ—T•=—€Ö_/å…_/Éé1GàÍÖòàÂLJyõз0@ oñ~Û÷åýÕ`R µgd©–|{.LìȆݟ߹á¯rÝõH|^û3QÔèQǟFß>+þ³±ë kÖ­ù<&d/g¹4™·Š}hÏFC‰©-IÁ­US ƒñÇ gìÜÖYŠD¬³ÈCr~Ýåț”ÆÆWÈ2¾Õ¥™ªç½δãn:k͞†šâÄj‘QÙxиIXy“1#ë6Ës‘<› ‚³eäç»ËïDªÿbk²û·€ãÿœev'‚J9-·Úç§V2âòÆd*ßú+j•ÎBnÅkæÃ:`‰Òü{žÅ\ö¨]lzn¶ÿÅ_ãü½Öç¿>Þ¿­æþ[R’ôš•ü£pCSëý µT‘Qxªû +*›ÙÆþPà•õÙiî#|KÅ!P¸Ë±(ÃKy(ñ´2ÊZ +O°P< +ÀË_-´ÿC7i{àï´F½£ÊÒsª;6yÎÊÈÙKÁUƒk…]¸ ðÏàUÚ Q(ø¯°ÇÝC7/õŸ;E,/ñ®b0–NLfº©Uw>Ȉ«ëkìR"—DÛÓ;ÑJ…R=û!³+¤;JB¦.´f.7RSûv•må0b~‡(s™àk¬¢9JÎ/ŸºÙ(KFL±žõ5·&)÷‹æ+·4š;ߣñJO¾y»´áŸ©Ãÿ%‚X9^iåNYÌÐ|ÅŽÌ %\ð½ÌP™0T’Ê9$4™­h¥±»tsc(Õ]¯ö#&dz>w*“‚¥%¶C$Iôΐ9è6«XK•Rƒ¢³D#;ì¥Ϻ㨠Þû‹KËRcÊ ñ9ãVNHð ï«4Ó£ B íT’y†/—¬h?E¾_­áï‘Þˆ)»bû ¨Éâ~4ÞÉLøNJ÷YçCuˆ°²þØúÍý;žÕ}{*ã?:e°¾¯šÎ^hj@oÁ²“zí1¸±¶¢£n܅ž˜>„'ëR,Ú~7gÔªI÷*u¸A2Jµ‚{VêȎRe>+éðNœiÒ[UoZGôZTÄ«+`ñ¸qk¢Ã#á‡pÙnÁ©;GU¹ºußxÑ#gUðÈþ€IfòuFðê½½ìâ±õ%AôÇcí Ÿí슬Õcë +¬ÛªˆRµÃ«"ˆ pôî6+Ó8¾õÊUYÐ|Êp€ðÉ»W©Ó¥zÀ˜J“Œá2Â[Né.³ m€¿]T¾ÌŠÆüà˜žþ.Âb¹J½øØ"V=žGÓ2 hˆ¡šuUÚ«UÕKþ ˜Šâ¼èŽ(p¤úý¸¿¶¨‰}ÀFÔl]Ñn­€ìBQº! i<‚„@£ªˆ‡/Ê 1ð^îÊK©ôŠî¨ÏRUš±«Üp%v½Ëg¥ø| Ã^Tlè*ñDú,º³¨4º Úfk:êfx–¾¶G—/êÐðB‡êfê/¨@gê3½¤°AÃØ´˜b *ü­Œr¨°–•U?#÷ò_•&KŸ´§Šˆ>Ì-ÖuÍãQ2¿°©N! „:‰2EfYÊœj=QµŠq¨Ùš[„-¨€©Ó{ÀT¡p?Ò+@û íW‡µ0z +ìèÀÛ±ew ö@ù• ÁW~DŠÄѾIҨҏ9%»•¦Å`ä½æšé÷­èøéÐû.áùJ_(l²±ü·uHÀp¾ïÿÿÀ6 q™"m×~ヤÍɦ2m[`ZØ€©&UÍY}^¿¿Kþ­ßóÛ.ù[¼K`€6Y¡|ý£CÎ;XiàÂγ4Y0§ï"3–å#„Ô ±´0¢ƒB'Ìo°þâ˜NzS"’}„s–"~âtWdƒ!CÄÈÜ!‹ÓoTLWå™WþÚ}G[ÏÉYÉ-ï¸MçúùçžôñùR(Ú»¿Û+쇜êÜùg ݎ_N”+ØÎuRÙ~MÅ;´L9ýZ½%09bæQΜg@üM\é%QáQ‡ïk.¡ú4‹þåß¹¢—þÅ3ü]r¿ÂÈWš»‚S¶ª÷kÄQQõYþDÕÜí Âð?.ø-žÙȔ@kïNJ¤n¹nïƒÎÈîPŸÅ©>™Í,ZJÂC¿:C쨃 Gæ£U1!ñD”Ÿhð²±I«ŠHŸQr—+Äñ xf`ͦ2äÜ-K Cà¼+۞"`Rî¯~õ’oC×ÌKr‰m?ûû®+l0ÌRX±µÎܐCo±_ÞÃRëIphƒ©ÝÐÓ%{Ú ºm9a­ñæɟ¨Í™€:—Hg[Úُ¢:?¤V*êã +ã°çS‘çâÙ¢” îc΢k5C°qBTžù\‹»ü‰×ӆøÅù‹h•lß,{ñ+ÖÖŏÃPjÕϋZ¤?œ(³ô{¿ï2ºà–葯ÿXåÕ.^¦ þ֔ܖ–Ýz¦ŒÆ%ÇýñE&¡õ]P%lEå.)dN‡lTI¾¨» ÈIŽq¨Ì¯`²ýÜ%…½f0sŤ· ©šó—x6(®KyÇãȟ3!±#wD€)ü!=zfowIÏò7tEýønÿÞe/áPó›!뛆¿?ó½šø÷ôÐÁ0T?dp +Öw9Ëñ71ÿݒŸCÁÜë±k, *ÀRš2J!3Í'R)ÈÅI \—ïpûöŠ+Çè]\íç|ÍW=è©¢I·Ÿõ÷O&Â÷X/|&•=>s>¾_L/P™«'ëؕ±SË:‡X‹sD¸+¿|ûš¨3'GìȬS™]ëÑ¡_¡Í ðRԏ œ0æ73Q["%¶ ¢V¿”%’ÎÀÎýyìœC66}c kpëÛÊg nçá|îj¤‚{Ø& ÷§ LS#‰3D̺ꠞèØ{&Ör§T2âéV\w^sTCè§óç{,²|«Ì$iÇÉbø‘§_mìúQ¡I_ót[¤ÈοïRSN!Î&Õô£Ô¼µ!ëÑ«ˆ„òq¥æÍÀZy…œõ/^$N±yFƒ#Hë¤s«j!kD•² +Aé¢Åää@òD}@3GÅ|¡ÇLÍ µM¹a?d¨]R7ù,ìŸs†k9fý³Ý‰³* ¾I¤/†,QœemÕ$DåΞ?]ٗ³îTþ.—!….Ç K}4ƒ¿90†-’êåˆÎe…«ÉÒ¼óöý§_>ï1uú™ÄUq‚áÑÀ„Ù±ðšeÀ4Ša¨P`nùî×÷Þc’+ +9w¾àåî4»öKi`ûús9µр w±ºÄ[ՔV7t¹]f¡ 8u@Þ¬^ˆôø>ºÂzóšRnha$î3-èºH•+ƨWý1߀±ëÊ Je@*§Q¯·>J¢×·X»g Ì]Wþ¾×s‘½ђg½3›¼> +Ò?ˀ}—àk}i+õûJ7Íû3¢?[ÈvNaœ6Úy>7UÇvnªøJ®Bsèg*ï×_çéP©«=?‚´¡À'°hÍJ Ä{ó ;¨Y’¦„ œ7DŠ¸i; /ÞÍ;ºFÈÂCκªÇ?¹ +nB´ Ž °0 \Wõ´ÌÜÉØ{Ÿx „ñq(G¨À*B ­ÈÄÏ´À¾Ôo°`t˶gà¬È{G>30cN°Ÿ”À±Q†G]5Ê$ðR:á÷ô»Ì@ýwr»þ™€<ÊúEWçÌ» úÍmX¥² È«7øû•tɺCË–ýã3x†ˆ'Œ—‘°Wà}1¿Žbá¥p4J;`aUx811oþw™&wÑ `$dÄÂg0ò!ÊÇe_{оæ*é$¿vÞ=65˜Ûªû™0ð€ï窲ƒíÄôÍp‰Ž¨Yóø~FªEµ54mYýž`žˆÖ#§ŽÝ•"$îïr RÉ­ZÚ̌h‚4U$Nð$ +­áí»óª‰)|D @]2rœõdÖª2d°)­à`ÞÝ3"诞üwY&~³Qßì<«¿åïT´Bkã+wñ¬ç¡»†Ïz|çnò~æö¾Ã²ÿ±ýR¸Þò„+Gaľ«4_æ-¦»kMxE† š°`Fb˜eä%ßw•žÉ]­³º0tê¿û‘|» èňÁŒ#籟 ·,([šÄ J rP~ô²äÛSt@þí],mÚÄXĂC͏\õ™Ôr9ç‘ïÂôþæ™Ê Ú7ÜCCQ~¶ó†|WEs¦KîÈ +ÊÚÁà w@½Þy‘›¼j¿~@ߥ_Ë7sy¾Ç7éIÙ ¤ìÊc +Pü§·LU7îìþîáö +éʜ’µ?fÔÐÔQ ;¾Pò™îï4PªrDžöK½£[£µ20ó§ªÌPwyÁÝ;ZïÏuÖ[=ï÷3gH?Q‡LkŠ¸-äk?—ê‘A–×5:zµêpD%‡f}¦i@‡Uì ÇZ.½ó¹7¦5Ôón‰2„æö×(IY2qT)b††ÒK ù{:5Ԕ¿:ÊZˆÑ +`Ïhìý|H”CJNé©{Ìõ¹؇£s`*ÅçΠõáÏîÓ!…zóïo×Æs“Ç ‚Üj^™0vž£R§­¶¿ÝûðtO¿&ÏhÎ:†#I‹Ú£"X—ÎYïWåyÜåqê¤@[º†>l'+r͚œßÞª_jυ3%s-ÕeE†ŸÍϕýùEˆA|ýͅò=’ø|™»îÜlPŒÃÃ_rh¾+¯¦õ÷Ì÷]ïÛ}÷ãҎ²ÑˆìÇ”àe»œ2éÈÝië1ML¨q³„MFy2knŒ¡D•Ìȱ7î’ׄB×ÖçBE݊÷§†Ú¯òvè-–¸KÆã<ŠAdÏWc€–>·/k¤ÊÁïT”ƒ½ÞMÂï5(׌A$›‘î:åkäÃiìê·cù‰ð>ò"ÅfY>;â¹ËHAÌÑû¸þøí݇x×4EòfFÞ»Aÿö³ë'±ð8ŠœÉ]oÖÊÒPïÂrAXïw>ñ€Óܤ¹×£Î…˜Çï–;xœñäa0Ռ÷_êa+Á—UWž9ƒ#Ø»‘Éml…1³’Ž àØiÞæe€ˆœ’÷ª÷ÓM÷3è[ï'Æ׿hÿr$Z¿žàßcSðS9òu+Íô.Žzà:“óxm¸8/>s§da®ý½[³œ9[ +U‹R»¢¤p +×:…³ÏýwT…ß ?zH.µJ=tæVnJ ©üÑóµ͋¨¨×\ S_´/5Ø.z®ÑÏ1Ù4=õ5´7ìñZràÌ=eÌØرéGÎ܁¾2p?‰CÖ£…òþŸw~ª©UhÝ* \Z+>¿ò÷>7ÒËñNHÍՐ£ÑâǨVñêæo¨ ãjIäwz`*ÓëÍ+ìú9æ‡(o-h1" )ŽÉ‚é±’t€‚ʯžù÷X#ë‘Ü–×ó„ˆÊ/Ìè0ˆJd s Ÿ®w]rÏG•é;¯Qõ¾ûµýGÇVF2ýÎ0­¡ÚûÏöAØë·ÉäE¶„̤—ýïP4ÄÌxÕ,W?LÖî¼ÈV»””QŸ´Ã7‘Æå@ PSםòŒqo£´D¶!q%YØ]ž3_ý†÷óÖgDN>)ÿèF;í.û¾/z! +Ÿ³6ä4WLØú‘|«áÔ êVhEzU݆é9ª«tß璘x‡‚w­Ã¨ÿÜú ºÛ=«HÄbùåsú.sš­oα”)}–ª­,”) %-¦7I=©»ò„æwpвNnz¦:ñc¹ïÊe][ÅkíÓPpWýYô˜%‰þ%2è©kk KBßÁJÞQnG©iëÄ£¶tmüCï.ßléMì@„ØWx`èr—Fy5ñ¿F¬[>–ƒ8f䪘(™»FJ&€Á©¶ôTÓ¯µ•Ÿ×³«9"åЛp­Ð{4-l­åË"Ý¥ úêÞÁÊ°—º¬ƒ +¦0¸KDüô„áÂF¥È‘Y#Wœ©ñ|Ô~ÿÙÈüÕÈ÷¡Uýì©$Ÿ4Ÿû™û« ä¨X¨¦ujcœ›„G‚ÕwŽê1¦ ø‡”GO6¢ˆYù *h㋔:íÑ&c€ÓlßÑJíÊñ*høYXúOA©À®NûBè?½.šáèµj¡)ƒf»Ç㐁 ½&_Qqúcô\µêª;ï‚nÀûïZaò“Îú¨Ï2y4µ8ó}Ez"OÙCøš«äGtV?äÃCR"Ρ¼þ¸u0 Ö¡FzӁ6Ç|¾²¯Fƒ=/’DÏÀ€Â/of½ÁÚ×U½\,ÝÜ„Û¾FâÜÓ菺ÝU~#eµ¦]oQk!gáq®G¾eŸ†VK1㋤òÒ¯fÊwI üZ-_ë:çÃ¥ºRb>êªÉÍã7JQ…çæÃè1sü¾«ê.‰fžß{ +Hò=Þ剁Ÿ¼kWçἧ·Žz±gôn¿oîý,º+âa¨CŒE‚ø]Šçº­F}龊dtfÞ3`bºÙ•L£p²8áÜ3,vD÷{yÜ3Vw‚ßÞL¯@Ú1Ñ\XÎãú¦ÅçˆïÌI‡¿zIH–d³'¯0&iåòÓ¿¯¸ó:\“¡»šL"¢aè"‘¤åá†Ê»½V”Pì±·¨WÝ3ÅÆf§à®KÚ¼}$ »Æ;2¿ì–§SP;rnÙó€Â!)½U<ù%öRº¥¾Ý•Ôb¯Þq]זKm«–«ƒ³¢;Ü£|Ôð©QZgTWσdÖ÷›[¨daÔu–°ù©«ât€š·n—å p–BµÖڀC¢y]IÔ¹hþ\;á‚W]9¡Á§ÀLÇTWKHÛË«zúŠKJ?è·wM~…a¶ÎÍ Å€Ð7À²ž~oá;8ÕÁúöBiè±J«ƒ›ãN(ܶH£<çLjK†¹8¶à¸Wh›J~1"÷ª +[tOSõäB´7iv+cïy¹)5ékqÄÚz—ÿô×øv(\ƒ£3Ä¢ªqQß$$ÅùÇsùkàŠF£ß×øfӍNùòӂm`à: 7ÓÓ*\w±+FÁŸ×*Ïm>"Ü"ÁŸze÷b¸`_ ÙS  _.HÈÛ<Җó¢rBȃæ½XåØÒPª'ëEâã*£nT–6”ÉÇÙÌ(\¯"·©Ã4ÃfmuшŸ‘nÍû)~;ŠA~ÁÇ|´ROOÑ¥ Ûûf½ë×:t´TήÖ蝆kó Ã#¦Â·Nà¸Tæ\…ØP®…tƒ{œžÝ9nìì•ÝØ3Ô u~= +¡q°èúÏhaVD•Ë麋>î­Îù^Uû…§ÐNˆï¹*êý‰©«ŒO¯‰qà®l¯%þÛ9KãyÿDgõH´þ·9=–¢llyû¢-ÇÀÝݯ›¬Œñ‹K'“£ZCýj»ÿcñ +‰ñÿNÝð ×÷•…¿J±µÐá +SµE:¡çˆÝá¦áÎ'Ÿ§kké±g|DžÚÀY>¿ì÷¶_ܨµjìòdýë±ÁÿÆë[ó[žÞ@‘àoòÊk‹ž|a\ÑI± ³tø~?—è‘XRu}–>J.ÇUûI¿Bõðòû3ÆcÃBƒ·ˆè‹H¸q ±âÕ?¼]¥ ‚s_9·¾c»˜ÌñèÄQBkΫ°ŸM}Ý÷bÆ!é1ÖXPj"ƒ"{Œ¨žÜÑb¯2ÒB¤fǚŠ1)*»¬­ 8ÅΙð áVð>¦¶ »²â˜Ê‚ªÀ4[6=¾è C“šžBØm ¾ß‘Äý†»ÏÞ¥I~Ë¡røåï(¨êx,pZHÅö¾–š1œÒ0P®3àjG¤2Ä<U">«øq\QHmXÿ™¸:ªë€+°ý +ŠÞ šàã{‘4¦“ú½G L@®‡R-aq#H\¶YùÝYˆ#b*S!3Ö`4TfÒâýµîÛZŠÓ+CÜýNÖǘöÞO]c8õn¤B-FdÞþ}o×8á9[´’!äkd2 âoz†į‘£zB¦šýímíÖ`§sJòøÀ+T@ÐsɺêÁZ¦%ci„Z!Âë,󀐃Kiƒ>1O2ç YyÞD“v¾w(bž{‘Ú¸¢xż©òY{±’E#h|ìôZd +zhÌ3Ñ1›ûÝ/¼­¥Ã*}H'ó™žbúȳ$\‘w±C\}.À¶ôcXJ’ÝX[Êþ0Àš`õÑ´&h¦VÀÅUăG`Îxnß¾Ë`~ÖóÅ-|¶ˆkˆ! Ü4ç‹ àæÍ +Ôä¿zIô7V \‰ø8DÙ¡‰}y*üN(tþ/tºŽwHûdžB<"Ö=lîG„ø­ãWÁFD¿’‡ši' qWšZÆ3,'ýÑ.Ü-ˆ®î{ìƒÄ }ÄB.¼F8Ú¡¤¦2ª +xÂHØìsº¡²ýõêã‡ü-„ú-oúW•Ópy·Ö¶ÐV'_œ¸øŠàGSꥵ;”ŠS‘³h…ó±ÊáÐBw†ói +$<57Qöœ"¡Ùb‹ç1¸–&·Ö·{5uO +<Õpa«h6x¤D®n‚ýqãêQ×Õ³È[áP5ã³T¬Àh LEò(ËÌØ2܅ñƒ~ÇËA:ã_|§‚eôO•/jâàÕT_»ÊÔqZ1ÎþÍê‰; fpˆ;ß#‚WשXqØ%ïmº0ßÑ`gŠèU(æ§ZŠ²§êúe•Ðš͸¶²{É×à©€AG4ÞØ »½ÓÚ Ûu™H¿®¡¢ÓËËN_ù~ÐæwŸúXøíD·ÄZB:a1e–’‹‚ 8Eíø¹JÔ×n‹0< r÷¾Óäí=}qÆú&¯õ|å*Z_]ìu,¹ß‡Çs•d†lÝ«Hòz”¥{Q®sÃ÷£Ë^ö <”uç)íóg-Ž:'<䨒…ï’rè¿ÿÇ6Õåן©Y™fQÈW}~o‘YÁW®÷Ü{Grá}‰Yyßôä14+à~L᫅Jò,Zܳ8ςïBª$­…ò٘uÿb™ýz•½_VÙ{sê.OMۑ-†·R8µzj1å»*ùQfg'XyÔ&îêêáëŒÉ܅=„Üé?ñÄ(Ç½é}çõb9 {Y²Œ¬g±yþ§¸ÿ0äšôìn¤ûJhuø´FL—Ìí^M„Ðc2M“Y¿tAy~ƒC8¤ƒ¡@½(;Ê#꥟ó:õ†©wcI2bí÷˜„çó‹ÿÕ%‹d—ÖՋÃ۟ØKôùW‡Ã'”úÈáåç\®ÁTb‡•†÷(–žW4•ñýhþÍÈ[loV„Ñߗþ€-w±ƒs`mÜ3úáS!«<À·ï·l®1F6Ï$39ð.MÚHU9ÜЮóVhñJÉ^/#µ–ʳÈôS5µwBNñö; Œ´¼ÇsÉ>‘'Ý䗊Y£ëx8ùÕٝÞ²»µ¿ÏAëˆ=%LÐ1{äl¡MI¡}K ªœ5H|<9³ŠÆuDg >5Ã÷bÄÕƶ…¤/îÆäxUó¶-)ˆRÚ)£_íý<^ˆ뎪¾'ÿ±îȒµHÐ àὨsI¬±2‘¯ú¢LUó¦ú ¿ªç«’Ÿ—$œË7z‡/’³’<¾Ùÿâ* +ؐzÅ&RÅòE!fjÀ}x{ëg¾PæXg¾’æCP7ïúŽR ‚ˆó’ˆÏà»aYžە<ðæ +êNj¨•¯*äªfuÖÍí·¹œ4JA·|;*P\±7 ´«e»*—eæ*wðhž0^™N4øáÖ¹’ƒ¸5BfWÄÔ½”aò\ÔÞg¿ VÔ§·TgA©ÅÇqê]?’W‰ܱçk:²ûL­gƒ— Š¿â~Yžüésq]ÖÊH—Q'ވíxÄaÚ +_…½p·` sXH°Çä· 8ëŽ"ß1Rë -í¸«&ÜkÁ è¡h>¾³ÿÜ6rFpx(È+A„íÛáRëÝÍ<«1ڙâ.(ê.Úņ à-‘Uâÿ>i?¾µj×Iú‹È” +z•¼|")’áJÃ5 ŸóÙwÑ*½4BÆgÄXûŽG·|+Áè<³%¼3¹°W‹ïö{è\ lYEöŽ;ô3ÂyíSC%7 +#«ºüç£HîùNHÏÏ]Æ`Œê(j8Ê<€™¯}G> +ŸTrœøn ùH“Û¾ü°Xžò/•w.©Ž74Žý†®ÃCÕ7i¬|D ”·-›Cט#&Ÿ½ yúø +œÙ¤ßë?Å;ÜÊmº£'2ãrV+¯‘™‰y2–I&3¢Y%a´&Qæ€Y+£ÛHÀjŸxyÇÒҋJ[À ú8åfü.CB›÷'´8¯âÏӕZõ!ªÖšÀ¯4îhôqÍSÍv_Á¥jö;~~H¦•EïEžò[Eù 2ü—â4ž:=]Šh[°òÖxÿ(2?Q.ÍXF워ÀXdàžØwÚê¯kÎelO}ɹ¥>§_¢ aúñï<Áÿæqž=3ÀGŸ9üðYúß¾”zRãRåª¢•ëC“m#Ø7q¢€îà^a­ò˜$u ôuVccX¸Uî1¡$ÔDFú>=•Žßi'Ò +e±2«Ý0ÇVú“àk ‰Y¬gÂ>ؐ4Þ§]©ùµÊÖ]!$mÊ¿ÅW,{íKã½´ÒhI\J‚¸œ©Í]ª’l³åHÝÑÆsGÈî‡nýÉ w’EYgºUÞ³}‰(4óïqƒPÏç›WˆU%‹ðweïØċ?ïLÿjçô³ÍÏÞµ‹½C°;àûK«ñ™§…-¤&*û}W-j±–©Î·Ôì(Ò’ð®”Ñwµ{‹“,EŠª¹¬Gî1Ö¬¡­ï g×õМ¶mþ—Óyzéxõ¨­€sd’ð×ß´s”Êý Â$‹¦zìwÁñÑ;¢Ž (ð—umCÎ_,б`ͅs¼íK&¯Âï¤e¼®zâ UcnÍIŸ’ã(³6Ú͹l]MÄìÚT¦Yþ7¬ï÷tDú…ȾßÁæ¯Ø^€˜y-<;ÏUðCµ÷¿[DŠÆø| ZäόÒÄ`@ü’žÐlýà^È/õUWd³Ï¾®T?v£ü&µ×¿kû¢£« æŠ!Qœkd'øÈ{`€MÀ%‡1±÷#BÅþýgÔ1ù&-}ˆŸ±wÃôéô|èÕå]Ão*È¥ÎÉõ$>?|ԓø<Qÿ>¿>ó$ž{?t©¹>?j™¼…#?Aێud÷ßÖÁ¾Þ'íT~ø: Á)Ê£¡÷ꔠV:ÆoBzé;p~O¢¹SÓ±åÄz‡]°q¿ÈÒ ¬(Ráà çvè-€;—„úîá&ùŽ. +W1Cqúâ_?®Yg;F™ôÕæ-ú.ªjˌV é+8¹ ~Hy¸\uŅðŒ­ï™Û®a$‚6Æ%Š¿¬òµÙqµ¢ùXQž JØ-.'‰¦ äÒ:sK_]¹Ž7{Îñ_܁À†/€|ç%Q »"ýÜJq,èIù©Y݈ ™gh®/®kLægiÆ ìzLѼÆU¦©1Óµ©·0MYbœv•ûtO}(@aJ||gÛ@áʨ Êk¤>$¦”œ8÷Hç߫™ï¡;w¡"Ñ vßi.æ)©ù‚QsŽ)(›Œ#žzõÉ>20È=G2Qq.XÅÿª0t&t3ÀÒ“M:î²-àCà¦Géw1 .uÜIr~ËU +D<3]Ø@ô†ð¥‡}¨¾å*µ²F™ûå€Ù)e7”-Ç…†±2q¿å‡˜×ó—X\PåËÁ€¨fîæLöäØ{ +0„~IþýÊÝÎ'ˆ05|Øüöc~÷ۏˆOR6;V;±}?i"lžýÌS=B¿=ÒYŒiŒs Sj:ÿœ19zêÝèK1)Žrš‚P vžgÀï"9h*ìÉÄã{³{UOŽdúæõ¯wøz ¥1Ïæ{÷îÎÀÍ{Q¿gL*Q+¢ªŠdúûÿ¯Ó?}Ðïa‡µ÷­0óê.Θ!0àaÁ ¿ìKÿjÏ̟knX×KÖð +šÞ ðM·Ÿé³’oË#' ~W„(BL }d;xÅj5¢þr +jg‹z®~~Û×öý*µýLÃ[æÖYìÍåõÜì×}çýù@Ï~Jÿ÷þ¿ï +ŽZ¼!Ž¢¿Wz^/ÒršìTo”ÝMu«Uþ’Kë×&¬õ§ +_½L®_ÄÅ€ôeº$pG¹oöÛë¤þªË¸­TZe„"éú’-eæ@sÒ¦€ +6Žªt’ÁÇzIÔB£®«ô¢@-x'M:¢ví_$‡÷è +êÑÇö_–_#‘glMͯ|Áö“z©{}Ô r_ÌÃÈÁµ²URJ­ù”Õ}¯–Þx>É<_MKDj=œ9$_è?JÐ=ÕvðRLØô_•ç¼š’ªí¨ÝH• +Î1Ÿ‚¦õ¸£ÅÄàáoÝ +­÷Ìoù(á£×]É֏ ߃W¬wi‡˜¾GØe  ÉëÞ#ïã_Yïª[.ÌfGö¡ãÌN”vËʈ ˜.{v_ø¤Ö ª&ßø^¬_v=Ô?®ä Ù(ƒ·áá!NùºêV¯žó;*BÝü‚0­Œ¸Þc%3kD‹úÄ{ú§jbÈ €õ¤Ãò¥õœGÚcŸÂièìê ‡Ž–ð{„âððSØ××ø¬¤J‘ÀóÎrú¥²Û (ґ1Ý;ªÕ¥²ôc˜'«ï=!ž*.ô ß#ô@øg•Žß_V®5ï'zèÁ¾fšÒW Ð1¶.–r“Ã߃ëWéù+¨`¿P¾WŸÁËySjŠ©[£––¾´¸ª]ÁýPisÙK¸°IB<žpÔZÍïW.q-Eæö<%ÀÈqþÔµÄA8ƒÀÈ즗Ù/Ó ßuZïÊÂwéY­|j¾ }V‰ÀѦ­â}Z™—yó¤”Ôúïjÿò·t~à°”‡E|] ïˆà®¹(]Zûܼ¤[r“åÚg.œñ.vv˜ ìh$øcîç9sŽSF³ÎÏóé@z²j<O¸D$ÖFA0"u-¹|ñ\÷€#­ÕRÊ ªæ +„­úótݯbò8âŽòd<_7JåJó(?GüBuwŠøœ #3­ î n¨ Þ£~¡^FNïü2Ê#²Â](—]¥EñPúr@¾g»2bIƒåL@점†«*`¿× [²¿ñ¨§åÎs¸ëiQ]-Þ©ûi™˜¶Á9dÄP1ou$Ðæí|½Vú²óLú8ëûÔR!l£ž»¶Ëïú\h‰üª×ëcnl–ÜöÈăêþñY˜+^fìB^œ’÷JAoO\s*üëþÚêŽtôÂu X¹,§ I$B³Rú½¯›1–:J€P Mt§\ŒV ,´c~˜ûv/ÝWW¸r,WDU½oQúP ŽÏ´U­’±(–³£ø'hžÀüâÜç´ ûYâg‹mº¬4ß0ՊÒtÙQ˦Õfގ$#¤R\{;C®ä¬ +~g_¾æ-¤à…¶Þdƒ½G즶™\Ë[WpsžççN§dô'÷ȈÝ6a‡¨P⍁â/ Ž6ëBÚcҍ)DÎ:®,¢6]ljâ.Šåôê·Ã–o6=bŽۄ:‚Ä9k +Z7x±¤Ÿ}­’S¿aµè=Ôò¬_’Ó¹ßÏznƒx¿+ @8O›Tö^cÖ×ї¨8‡(S져×x‰9¸ ,{W\̌ۘ‚1µ†æçײDiõ0út^Òa¼ÿ¤í÷‚#ø̈ûY;èY·BLuæŒ÷ ­`‘ìÈ,” Äiî¥>Ñ㌰9CRáÞÿ#Lîí³PÜíÉSñ­½ (­(êÑ­71Ò뛳çèÚô‘f£¹ä ó'€ÕÁë¦;H%ŸÁȌ.ÝL‘Æ¿¦¾5§±òáŠðúäÏ_þšëýö¤'üV¡mBÖGU3ß)åiĵó‡ó*-žÙ±"]£4=d"Š˜ø–« eÕB$E#âò}•,ó£1î‹:Dbú@U}OŞÚ]Ò1§Ä}iXH.F3Ń`†-à_/üNÎ-vkŠ d4°íþ̸KeאzلÍׅû²¬lÈÎá †aä;Ÿ˜°3?Ïþ¥†èÕ,xÈ @úgµh9¥4¥èe0Y—aAUN±¾â¢¿H’´dA–m·ãÔ>¿³,Ù{™ z„ûDîö ‰ï•p§ŸŸKI^ãÝ©T¯ß*ùðº Ü`0ÈÒº*ðÙ÷{¥øHi=ۋ:;ô.àÔ«¨éö¾ž¿Q5ñ>Ϻ¢HEÒ9Œ ÍñrîƒóWÀ˜d’ÐNãà7²®D<ļF@Y. +è^ ãã@–¡ýƒ#\…è"1ê!µéÐùÞ°ïðþf6ì•çÎüÛźϒ…¼è9rj%Õ,ŒM7R¨i}î¸MqpÊTt³x*šõÙ©õJ²ãÁ>-n,Æë”ýA)ñNtü¢ó#Óª=å–Bi‡ïák÷)¡ÆÊJXa$†lÀCß+ôT4RÐ÷÷ Ü´ÁÖÔ }i/°–nï÷ƒ +^!ÊïcAEy¸’ØDVð: ¿Ú±tØÇÙ{Pêá}¤à2ae/ ÈyŸ=J½Îq~]ÈϕZvÕÇ +ì+%Û¿»}ݪ’sÀP-ñ‹,6®²Ðñ9¢}¯]»T’\•'¿P¥Íx•£§ÚÁIûh}*jGŽbŒ›ë} ïl2y5Â3–•¡„m'ŒI0‚pIµ™ ;d‚®*íXÀ3¤YE•Éu=ì ~Œ 'F"·t#/ç‚; ‚}w—ø9;ˆ|Z˜Ä÷“‰÷”hóÇ»É>ç¾P1?MҒ Üªò…[Þ_³±¸¹0ÌsÚü™ÛÏJmP ýåd;bû8¥DtރØyîh˜Ðô® ã ó•Ž(¥¬’8&á9‹¼ê¥;6Mñ»§ïàÈ;aUmõê¬)ý8¾ .µ:/D"2҂AYׇ¢î „ë5bçàˆ,Ƶù_q¿$B›Ý¡u¡Glö½t1§þc}ŠV7ôéÀªFžcòãÔ8Ýk΃@ÕX£;Öåudd_Úû÷´ Z‹x?@[8ÖÞ×½GngÍrÌú(‚iÚl<øÝOß%®cŎÑóª ٌ ÖV8½ùè¹µb9ÂfÅ7U%c·cÇ"ÒÎHÓ¥6ìQ†Šñë… ŒQmeŒEð{ÝĂ"¡:®Áÿ©Z¬#‚ê~ò˜Ÿ]Ã;Uà}$$_WÍ£¾.ßWñ²}ŸŒHÇÞóÁ‰¾f•ÀËZ@ôH5é,;iî²ÆY¼Öôá{ES‘Hú^»pͧ\zàún"y‚*+´jK|”€Ò=4/ŒéÔrb~Ž›ÊÕ,>{–\„†Ü”\˜Ár0õ½ —ÊYôkW¸)Ë×·ÌFÐÐΫ×+#f¿ðä57<Ÿ+ˁcÁ²[Ïûíºõ|·Ižé9ß%Ëçˆk]LËJ÷5pµRÖ¸?›]è$¹Ù^‹g¸ˆþϖ{°ï!äz>›Ýâü_*XôÚì€2£&dmm±çöÏf>i欫L¶x2&û Xf¶é¢i¬I¶\X‡äv‚pœ0£¨w~ËUò¯’ãòÏÀËée«â»8ӓYì‹þlü {“úÍÖµGe8ïQTëÌ_đn  ÷l™˜'"´M˟ø¾Òt¦ SßüÝn•«cgݝµI JÝz}’Ab!”õB¿w­&*úˆ@ά€'`ýûúœí^ù$ª_¥u–—=f­@¨²ýá5´z&RÝïã<£k•íôLJtòQgˆ%㸯²Â>´„ÛF>ïtã(¯=«nXù¶ûsüvé÷$5!õ* Øg¬þH_{Ï.€^Iš¥OŽA"í_W‰ê‘X!*¿{D%}gR/ë1šOjúØyûPun©cÖ]夼VϬWÓPü‹6ÚifzºÛIJ÷š¶\ +\ƶÃù¨àT;“§¦’rtã,¶hÙJ[ð,û£÷ˆ²³àY¡ÖYÉoR¹ß;Ú*o’š•ðÐØ~ýìBwA;ÔÁ³ªÙR‡”<~VJ3ž¡¾ÞY€¸›ƒ^­c›¾gÙº):SÚԑñ¤°£f‰!P´KEò¶mõh#Ä̃R¬ è0Ǩø~¶Ä>}{R´9£¡Mµ§Ûä¸OQð],Ü®þ–Öµ²NgSÖf¾Ù«ƒC +ã쪲g®£qwX·O‹ˆVg‡•|ÚÀî)Z¨½»Î3˜òEJâ0œräœAÕK€Ùý\ÙÖÑ “gs_ŨmDi¯‘õÛóÓë>Ëè‹ú™ü †RÎHQDfn3„©Ÿy+ÇÌ9ƒÇ{Eù é!®Á¸Ôýˆêylß3㠞ím±ÈR+,„ýÞ[%ž7Mdýlwe¤ œŽÒ²9Õ¯`ê b{ªvéˆ%FÍ¡}å߀3©T&ðPÊ`¬ÙÞ#W2(Õ¥£ù\‰¼î"OØwIIKÂ2yãeS±¹ÏÔÙGtbåt˔µ¿Fû.å{]ƶ]ºïñ P]F©ƒÙ‘nü2ä>Õ°¹r¶[#ðÍݕ“¹ƒjá0ÊpO[W»rK:Œ*Oíy¾.Œ2ݑሬVòÃcUÿð¦…FÈ_šY#ˆzPê=r§WtҞYìîXô¥~³ëW«ðRtú4Ûb•ú„T|Ó{š&+‡®ÕÁæ^JئqºG˜DhÃ¥„Å‹B‚ÚÑÞéØ@84ž•cû=Ò‘?«öh7âʒßk£žÃˆ‚§^¶–1ԇk{ÒD²r?÷VW<3=¾}³è,hY¨Œ#¯'j¥¹î‰W /á²3…É¡ím&ÌM)£²è;í¥GúHÛ>¢‡q÷Ô©¶=¾ç°ùÌ}k#L’6Ÿrk•µl¶àf‘9PÁáüì­ï”Ãʵ0"¿’y“)¨Âï{oÝ%™kWJ~½@K5êý¹¬jŠtÉ?…=«¦Jë"Šý½gùXª™÷Q²Ù# ¸Ïk-Ä7qGäÚÃ×w¹š&R÷O ×µz*ÒaÏñJÓºc—Ǽš¬:þTaޟû̍ƒªE‘J`ÄKZIÕÓF06›-g ]óµ›ê³îC‹ì()Pš² Û°Ãæ7<åÂh™æ +ì ²÷‹ÿvÚ3Ë\³LsZ7s|®²çbªoâGq§DN5 -Ú/fö·UCÐA÷iÙoçùL°ŒêˆÒ‹¥;¾/+ásyÇ´¿×Ãz'I¹‹î¦ Éõ֑åvÅ¢’Í|œ5€+Rà‚L†Ì/Ìú#õV=ƛYnDðÏcWÝga¹ÕÛ÷Äc‚(a@SlïæÚ£|ov·,Q¥ÇeJR²~lÑ×òzçÁgìÚ×I9‰Ý%=ìî;œp&+“·lIÅBÏ}J¢–M§ßýXŽ¸Ÿð_¨ônˌ¸TŽ´[÷…b ת: #ú®ƒQ{‚/4Á^3¦"{w%)gè©ÍÕVœê'Î.7×iIßúÝÞ\…©S¾ ËÓ)à×a{æÎBN>/1¨ª%"0oâ¦)Na7 ÔÖ ¶âÏ.bÀÌDuGEÍbxê›:yä•Ñ=ý»¦›4\\áhû=ËYÃà¡ö¹#à‰÷ 0Ž½!ߕ…© mî‡ӑ£C_ ç‚.*–㯯 5û‘]–lȶ'•Ýµ×Ù§áôÚ!¸¹žˆQ'Œö2Ǒ;çã倠¡ý⟵ò1¡¥žµ†¯Š•¦‹µZyV<ßU¢ˆ:Wî±|Ý8öƨ £ß™_«Bãö•|Œ +“;+ ‚Ž`ä‚5Æ™}_ø„³²ŠÿX›#gŒåíõäöDkãóƒôŒb[_+·êÓaÞs^økÌo踟[=C聹´Žk§v͎œE„qï34齡[ÖwТx¢Wµ É í¡¸ñQÀ3E°¶K/q©Ú8<ÜDêZ|e¦~@½:Ö«œùØJsQ{PAã¬/ÝÀúÆ-‡²W‰Q=éYR¼Z{?’}šœŽ¯¨ÛBª^×sﵤþm HÎ&ž¾Æ<Øíê¢L}áè"Ä©hô0Š¸¤Ÿ;Knϳåï‚òŠ Fý-®'¡úK?lnðkê“ì¬Ë‰‚¼’+)¼L ¶í¥¬Ðò2–/éŠÊìTvXï‚j*0ˀtgJv¦Çúµd \² •Œ}í\ß7ÐÐ؁¥-öv/^Er’ÐӮö”ÇÀKé®êá‹EyÉïûÕpR§6¥¬WÎ*µ‚Š!&Ç×ó¶&ÿ“Æu¦lCÐà{¬ªÒÊTFïáÇB*Eìf†lYèH-ã +£.5:#Üó&XwMÇhQy(qFÀ¶Ø9T],]ð*9ÚQ2 ܁lH>žTãCð +ž’ÂÀm˵Žòµ*²3cNÚ9ÒQ?>®Ua#…Ñ06zúU.ˆa•ÏÐoÀ¨Å½¿•Óhþéùþz/•Ác&gäy7ô÷UÞäóÐJÇÁù´ìªp|¥ú2âõ¤å4³/ú‘ +ӏá7„> ´ÃêOUJ]l‰³x]E¿úkݲe…gi NUúzÛD½Bûr‹Héáþ$$6´AÅ딊i¹IKBK-rê¤5;¿<¾Â $ ay Ìº4Š¾”ÐÀ×ꨪ‚&EãŠ]šE¿ü,‰I·~³ºþ AÁñHFý¶WÜÆßQªªIMVº®âƇB¦9|zñž8ËNûçZ> u5Ù{鵐ZaáR¼vQõ@jJLÂ) IÂ\éìˆ$ȎÎó¸Æ§s;k +ô½X‘RÒõRóF©\䠪ʿʋYCí«6Z.Á@` W/wíðe"œH¸IoFWf³=0-/™Ò£òå+j¼T§ûù }žt%‹.DßZ4„k?„ÔìÒè!|9¬r Øç—ÈšŠM±®äofÅj±¡|ÿŽhÆTšÍ„,v§ì ´ñՊîqڃéßá"ˆE-‰ªYÆÔ©Kb:c÷†°Z¿Bßõ½R6};±`€Jm–¡qˆ’„Ë’ïÙ‹˜:[ß*\H]–Ô9›ˆhȦ¾‚ê·IÚ¥^îKÏHCì?"Þv”4Ú‡tr3(<Ð0v m¨+ +/÷Ì0›ÓÎ!Q°„|%|‘ùÁÁLÀ™‘¸•‡Ö%ïþkä>õpX¥Mñ„–ô.~±²{boÃòÃÐøØ¢GŸæ¥ ܬ¬¤°’×öBÐ̒àÝ× +&‚ü*€ïð¬~ÙlÍm,Ic—aÙä%15ª4çSɉK +ú +%C—*Ãc“9EÏZžéñ»}uÔ¨¯àž¢ðº£_ ÔÜççµòY[¸Á„¼ ¯ª‹@?W´¯(j¼ÎÒ_ñZ#K!h «îù|ªÝ¡í…Agï‚î£-t†în{½…NéPx  C a‘Á'´Ùd¿;zƝ“шÒ3t«©Èq$‡¤Ëçrã;"¡ñÍk{ /¡~Îr«¥ŸR…ð’ó€õÛÙ>×Ê8ô‡À9õK +øÅAp+EÏî‘wÿV÷B"£B²QìPôø:g]{äØ÷)Lß|z?y¦Ê‚oµ<ü•¿¶]8òšî–÷¤þ|Þ{h çûˆ¬‡¯>`äóŽ¬$ͶÙk­Tt˜H>ÔL¤ž2ÙûPøˆVœT_*ªo³¢ +ÊU÷vmg.‘V"0ÎýlIÈb;õØYîìá–í¶©¡%_Ûz/ºî¡&ì¨vl¢ï)#£ ÜŸ"”Ôœ³ŒÝR“¸®=Ñï"·s†@$ÆfфeV.!WȄ‰Q:Qq‘!0Ù{×wèÇ饮ÜÀY{Iz/§>/Uðð‚öõŒ/æÝIo\è<ꤲˆÒ#ÿšAˆ†{×ó®S_‚MšM鉙­¨ÍÅÒÅöR–©}η[’çg×£…ŒÌÀµU!Û³«¿F#õ·j.+ù†ÒÄ}ïjŸæPç*6^šjցïÏùTÖ +Ô ÷!ha‹Èð|zmj½°†÷–ßĺ)Œ@2Âå;ì)ùÅζ;MƒˆD®©ý¾t¢u,¶SxÉ<Âf;t\ÔM±1œhº)*Ñ`„lèé9wQò#ˆ?ÏþUím‰=ZÔâÎÅÆJgj@¾veX_ö¶7ºžÂ÷BìÕGRªVÀ32{Ð[= §]ñ]Ã@󊙚y+é(QVÄ2,Ñ!"ÓZ`ü2ßÁ8)þJÐv9;†ÒwEwìíãNgüS*²!%±ÒÅÝW©VÀJɏ2…/ZX;FÓɟ:g e¤wB(;Ðþ˜=ÌRӒïG4z5–µ8¤ä5oZ%ªxù%í;~?‹Sy²Vh_ÈKª»[0‚Uh¤Ho¦Õî@ž[w…rÝxß©§•ð>Ö)pqà…u’Ó]éŠ]Ö7Î"³‚þqNZ–½MŸÖªžãõDꆘ št‚AAî(–t M@ŠŸø¨Gø‡Úœqø¦/¶a6Ð?­äR­Mî@ÑèW5ñÉëð–>hrnÏþÏoÈwßâpß?Á‚=€V€Pͺµ·Ôr{܇Éﵫ–4LÅ)ÔCPõ§¬×)9ÛE¦É™è«•N"“ãÉýùïnø-> $œÔVـhx/ºjüòçô÷·ŸP®â¶)bHØßÖóØÓðŒ§´‡îƒ)cÆå®e-CÎ#}K}a–QÂÖWbR(ÓٞªTÍb o»^Æ¢ÅH'ÔWêÜ·¡5PÉ33^éW’…ãþÐïHA×a8Þ~ 5˜Â¬S +A`C(Q¡¬b+­rHsÆJH!z÷[=¯ˆé]Ùu=֚åØ%‘JºÜo"Üä-‘¾äØ?¥s +Ü:býø­¸+5œ—éúQ”f¹«²0GªP!Ç=¹ìÞ8zo@RA0ïÅîÿ ­òØzñcVÿԫ֌Ž +»‹.ìa÷–ÞaÝÅt,äÆ@tݳ‘yúªµÈß ÚÍÄ $›~?!³þõ£™\Qß7ö&àû§~ÚuìøE~Gê©J>ÞúÐé•~Tdx¤Å¨ãq"*þ­õj‘¨Ã¬Øoh•qîg)Å 4¯AãyWðŒ)éYϦäA顊Վœ„ùÉ'(U…„ºyì”û¥ : ˆÓTN‘앁Ó­2W:~ýÄqè{<ì{ij +_ЇXi#(łºS)/¾ÔŸþ¨`îX)q3®Æ$ÈI*%g>ދ(˜á•Åtö˜»§vÄé}¤Óg÷ïr_g6øFÀ9{»ækU¿ão„¢zö´1_KŠîö1Ï'iZ—7”Ë<ÙÈö…·¦¸¡¸"4tTNùè-š„î<֊Y B wwÆ,ätvñDÕÖS!~‰¦-û¡¯N¯EKI u¢#AL”øOk0³oj6@7€ 8)µÝ¦•D"sï$3)àߦÐ÷"¨Åރ™Ì¹1Bm–XaÿcÐ×K_øšÊP*2›(É¶;¼@JEB-ìœñb Ã"Ù¤ò=Ö0I%ÑiÊí{—™o÷¼>8W/Å>P¯æ à+%rºpÂ}+Ô֜´lÚü€ ïj™é]qW[?A:€Ø‘rÛªªàHOd‡Æú¦¶(NŒ˜éHUNýl¿Uý¿Æ1¾’³$é2áÑ ý™YGdÐ!ÚâÿÔâ÷h\X±b0Ó¨VÅTç‡öTÕ->¯—ëÙQÅZ2™Å/R||k>pÆu Îî8-yþM%¼âËɊ&ßà»ífñ°{Ž¾ão9*,÷4¶™:?ñ*>z¢·Äìlcû Ê<ð&S7ÂÇ#TîúQƒïs =»µl¤ SÅÚ·‰EŽq}x¾K‚#—§ Ñ*¸ê©¹Á;§îmÙ`UŽlë*â¤:ÁÉ]g¶.güôÜ}Jò••òٟºÐÁ¬1?^Wǒ£§6ñâØ> "Ô\6. +—–ž Õ®ÍJiÅh¿4ßQsª©œ`W›áè„å¶vœ;fégùh9¸rq ñ¥açU€î*W»Yʁô Ÿf7‡]³µn찀úßkX‘ Ò^‹}þM•@U¨˜¡"ÓWƬi|«Çؗ4bøÜçS2 +úƒ¤æ†œŒ™c8†ÿZéW‘³µúhTx0Σ¼$S[¾ö˜‹ö[ÝzðÌ¢ZæS¨;ZŠGßrGËÛóq~a,DØT"™Ÿ0KtFEûÂD¦ùûùjžÕ!Þ·”G‡”$Ã[’ ސÙÓ·Ndž·Ût¹«¦-À•ÌûÚIa-U³­m­KçšZo–‚Z/~´¦dµÐsܹaî¬/6B ³.èsëæXâC;]RÓj{×/DZ¦p”þæýáÊär`Ár† ÍÄ)ø™ïì ‡q½Õ´]ÕP3¤ÂÅëZ@aûƒ›žÙ{Ž<³Î³®æâœ[ñŽƒ–ˆPdYÁ-Oò³T’ˆ5²1>ƒ•â6ê„%°ì¨|uk.î´Xr¬ªàœÙeÀ…*Si™gÃÃæª3\žÜS(ëÚôÏ*³#?bäÌ|ˆ¡Î]í㈔ižž“ö(üÆ.=ï>ƒ|z¯öA¯]©”j»ÜãЊaù>X‡¬©QQ¶gruZU…‘ öf˜ydõÈ<ãh9£ánØΩs¬`÷YÁæºvØÃÌ%Òâ•_<ÐKÒrŽøY%À´Ç®­ÂÒ1ËÚô”ZGÅ=w¬ ‚§¢Àdÿ`pç{-rkCa¬u£M`gUf„dŸY1w|4ãOùŠ®±Õ½_Ù5+xrh 1Ÿ±ÈËh ”á¤eu¯„‡Æ36>¬`bž,/ž¶²œæÒaº Ù÷ÎS’¸ðD¶§ï c„ |aG /;G.t^ÝEð¹ñ<|U¯ГBÃB†¼!>҉ì1␯ß\ÊJÏæ¿Ê²mÕ (ª%üìI´»2ŒŠ­iô¹Yûž-=kŽã>ÍJٜ/½8|éUË°Õæz©Ä)zõ‘¼¶#ÒôØÉUÆn£Cr 0Ôí” gœLëYNy„ûj¬HªÅM ¼àQœ½Y¸œ@i']gʖ*„žuÂЀר¤bÚÊS3Ÿ*€ÉiúâDŸÏ”èb§R¯¡×Ê#ËyQš’2¯H!­Á ™Q#xn¤¾Z: Xõà =G4DN-hÓ&ž:WUfZg +NùžòD$N!=›öˆè“.|hþÞ«swMýC3Mí°®_ã*ÆR…4åi<ñµ­ƒžð.ßQÞ ´EWVÀÞcUª¨TM †Ê™êtú,cQU5›ù²“:êýÖ«˜^>0!ï&ÕÅ"Q1XhÇ«ÿ¦þ÷üÿÁëü¿QÂù/Ú¢xµEÿþŠöÇ+à°üë ú/hlcÿúŠëW B£ÿœWûÝ,j—QÞý=›âfqÆ öÒ¶øü…®!ÿGfŠ‹`)n³Ýwe´E׆ԜÉliÄ·l"!ïöï+¸¤â4äv՛c£LîXbÌ^ÃU›Ñ#šúBÁ›:âúÜé(tAêÅFù«tgª2©ϓªá&÷â \…ß›‰PÉß´žøªkÆ önº×§Q5›AÁ ΓۮOðÕ]XÕø—7;óJ»m^Ñn)bBk}î<.£Í¸0€‹½Zòà½sÓ²Š?ø\þŸ•ý¿ÙÊþ*PÿÈepZd½C¦[e:žZÀâqÿK\Ñ:}ÆÌ`՘”Óž‡Ë¬ZÕ#%°œ§GI‘4b¢GŒ0w<"Ì ]¯™”?5ëØ çr,Uèc¶ZÄqÏO?šª³xKm}^ +v®çµÜÍk_vóNãU)/á2iÇôö/c"s|z8wJxˬ¿§D‰’ºÁ3ú:g‰wy-U“³FcèÊîI™|R`îK˜hE”xJo¢ˆC ¢Ã3cSû’h,Ø­}¡ŸÔ¡vpEžùgé…hŒÕ¦KsÀä +ÔieØá>£oŠ/—ÌCÏÂȺÿòûŸJʉ™+ř„¿wÝ£à.sË«O˜fÛó¥(q¢ M„BÞÛ €ït,0O•s Ň«´¶©£šp·ªÐt;p{3­ÎH‹|7#ü¹ ú–ô[4ô?j4ø6ÑØoH'5 %c}ÁPåé÷ÚfS@BäGÞþýÅ¡éL¹[¨ÁñÑ°4É7<åB«s£ò5ô„ðÅp£j‰ÏY—Zì"Á)Gï|)©Ë}¥7“»Ë´º"PáP€#·Ž O]Ël»óËú¿¤á͓æt`Hù#oøÞ@Úíƒë/뽞^)23¬o¨žIð'z‹Ü¾ÚöÅÕç…÷<–³D™‡µŠlßɑ™¢ë‡lÉ,SY& ùÛiä~ïVfë©èe]©s[î%k;°†û<»àÓ3×­¥òìzòµyԜêH4]à6!âMå²{Ù\×Wœ5éT¦%J)Ê"úYj•wyn~27’Í>+Ög %²€­È&g9HÑæÈdÖ¾Õ£ÐÿUëS›ÊÆGxeaäˆ —ŸOÚ= +{ªÖõQM²oR Np_ Ðúƒ8Š˜ ¼óûÞ÷Yή:¥tpî=záy¿*mÍ毞 nÓQ½šã2M•,5»ù«“ êVkÈýjt Ll%õʞ­(•jͧ)Ø(ÕæK­XAœi³N%jù·,k>‹ :XHL”9¦íîK˜å´ò l*þü]"úæFlV2¢¢,ÓòÏ'î¿É©æÿ®‘×êoúvFAIaÙðCáÏ(þú¥•š7¼d©¶ï¹cyÀ^ñ³á1}Fù'"F9à7lˆKa +\‰ +LØu!,EMÌbƒÊg²l³ÄfA+ß¹«” œ¶{‡/eÒmª´J¡ð5ET ²rfë`ÆÜä՗1½æÝZé/f4{»’?ÿ:ðÿ?Óï¿cÿȧ@1"8½L~ÞóÁ>qI¢âñXGœ`Î ±û2hWÊPDàˆ~F¦§=¥w¦ó€:3§~fþ°ý­œz½ ­06”Ë8@´•„—%Íߐ‰álO5LbMŒå@[D N)®›W9Εñ?A@“Û¯¤=…%¿¢JUïe@ÐÏ­™HÙ"-ÖB$ !ƒ‘Þù…IQ$µošñYÅE Gù œÑà{ŠYû‰£pO}†%C@üê‰ÑÒ9*&é##í"Y¦€Tèdê“8Ò¯FœJ̲àùK³Æ"óeՊ¨L{÷„Œ4 4O/ÁLšÆÍ©1?§ôm™-ä":úzùûFAM_š%Í|ȸb±ÚÒM¤öˆ(H™v~)ªµ>4¹ „™0Há45(-¦ó §V×¹èGYCüãHä3“áÞÚBxBɖêÈf¹í(Ù]ŠæŽ¨AèXNqOZu÷ýÕÐáâ|ò5RPå(<æö‹^ÿ©l¡“¹îŠq¶Ú<^×RY³üu$‰òÀ·ï§¹BZwal©"vx§>R˜Ù±[)“îë +Òò;"EÔ~ð#¼¹¬-iô”ÎߏvÌë)uqpÍ5hD9z´„ÆQ²†M±Ã ZUuXùõm<Ų{?j GIÔûsšN` Xl^g¤è¶â Ÿ~ô +Rg 3d{5|¬§Ñdº4Í8N£ˆR´ðUú¨¦$¬å‚U¾]öyž¨Y퓆(Óv)Ý¥ø°H´m¹Ž\¥Jýý„äVWI¸ÑGPA¦Î4?®kUqpmÈtÊiéþ +½Ö˜8•®š/ßâqgä_ëZ®PÜ¥?­ êö`æÁ+‘° +WèUOúD«lÉhÝ·•Jªº½EÚ¥0>ŠMå¨Þò1©Ð0Z³Œ‰¤U8úÊEZ¬ÙuÝʔDaÇcÞ-0#R6sm@7Mi{3f6vDOA Ftó>¿Ö +à5VÆìቻ,-ªaòO)œ,Oï\{M·@¡”VsÓ"8#‘|Z,$8ÒÀÈf N€ªç{π¢,…b2ÊpЊ¥{?>­¼³ÔÛ®|è ¹T.C°Š-Ú½¢$÷…¼ÒyVºê~§¥õÚÎ8hñ‘˜Õß*EÙ¥¸¸¶‚J#z¾Ùo{€·CÌúî>A™kˆ}V5VÖøUº‡ s‚®MáŒL¤sdÁ”zu÷šbq_w z`ª½µ¹qJàñ_DÙ¤ TNO€]#£3·ßN%ºÕ?Ñà„Œ A>U/>9w|~ðc1=Ä&”¢–)Héâz +gOâ|½+†p â*¦œ 4]ÕØ!QMíã£1ÚÝ7F ÃÀ¶ŠfQßVw.7„¡7”†Ž¿IÆV8’˜…ª‘1Lügg FߥjBÑÇÚ[úV"â@/„=¶'[+íù@´°Ù-ßñ}qßV=W$=74+ÒóóOdx{¥ÅT51ê……£T2·,OžX’i®oÍaTiï‚!½Þ>?„ǤMqé˜ö"tÄ5➦ëc‹ ó7¯°fƕ +WôèÞ¨}hVbŒÊ¿g°MºÖôž?Þzþxþt˜?GÃÿ&ÿýp +0$n±ö1u*áls:"§~q—kä’`øˆž/>²0(ŽÌ²{5ø‘éh«¹¤Û)͏ÄUØ¥Q{Tq4ï¦háûiåe>5údtw)€ßkbœlM£EK\i\@!ˆ…Ÿ’$Õ,z*/n\J¼‰¹?j›ÏÁ³´çRÔ»øŜ]Èt±ÛÌO +ìpÈÚÀº¿lÿ&@ýýƒ\JsÌ;]}…I¦žª>ëö>›Ø ¢×Õ²p»M˔¦ÞÁÈ]+´Íâj*&D¹PEýVIÕYü@Mîìmç¦äë9¬/Ü9ÎÔñ›Z;žC¯m©ñ¾„’|ó`Ï/µ¶… $• àþ.R¹V:lˆGæƒÞ [D±™6iӅõˆÔsµz2Ǭøqœ½ +?z‘Éej‘¢ã·f±,”¹ÕàØ«:UÎçC™Èmƒ‡~YbÛÏvTšáJ¬O b-¯«v8Xo/;‹¸pz<Çkn§šý|Q¯·à”–ΊÛÝ, <C±ÆD–R™íæpbΨ!1 *\‘¿ÐJuŸˆONÐ[Z‰ ­°ž–°Ê»Ê7ã»õ´ð ­Ê\P®ZºªŒ«0s_óǘðg¨êÅ·~ò×?ÞvFyàÕ*fåŸ+*Š?Ëä¼3IS´¡×>´Ê2‚±I|l—Ñ“3Ë©CÉÏø½QÇr߆÷/*W¦œä}+ X^çŒ×µ")ù’dª.ÂQ·ÚC0Ý-±^Œ¨1C a ֟ƒ]ZÓ¼rΪ(ñ÷e ë‡~Ÿ»fDÊÙǔ1Š…Lç´¤±b²uPÚs+1ÓJ7~E+A”A~—®û‘ÎCÔ ”J²åãx¢Á@zxÀÝ[PB€O‘#ÕNŸN ¥ó$r/@OV9PÂU<Òۊ¯gʽÖ0d—ñqMAšLv#ÔX’ïQÒT4G!~ƒ5Ïcl—¢ñ=ÊíQñ¦<êo+uì¹ï‚%N=lÄ6JÿN2ÐVÑþ8Z€aU®QwEX«Ì€IaGŒqï;s/Â÷¡æ«ÝÁT í¬Êâ¹Y¶}ÊøuOµv°éY©°‡©èu¦Ð™ +ýuñ6;ª=3 +0Ñ$¿²gž•ôwÍ*0U¸ŠSª¿óÞ3}Çè„8}ÖBfÏ4›Õmä±íÃÊ×jôºj³}¾J³†ý +ÛÖ m•ÎtNIÉY ¶^ëS8¹è§¹‹çúHfãeÔ$gNŽ 4åå*õØ÷J„¼kÍe¶5ö#= Yt’› m]rÄ%Ç­ÿqö/ô‡a­ðD¦â];þ¼ÊaIO+ˆ9~ýpâ² rRq²•ÇúSb©ÝÚ¨¡ÜøäkOÝ£É/½¨rÎ?rà<çïφ{X‡Hw}~îÚjÎÑA¿#®#´7ªˆl¼*úW­ùՍ gÚfßÛi×»…é¡pKç#dèž%–Æ`ò²ûý2Yl¹ñŽdÓ9+t+l(ÓZÚö]ìÏL£ÂQS˜ö?ÅW¤]…¹âBÀ_ ”tβ1»ë@ÓÔíüx†.7·‚Ö_+\½\^wPÔ\>Ú\÷±u`®êžC)6“'ºM•ŒBA‹?èº0BDÊ"rB4-ÅÆöHµæÞþٔ±Tê;xžŸ@ÙZT/QíŒæ9b‚ù…Ø=n¶OÌiÕÕ4q°å³s)gQàõ„åi‚¯³ÍQz¼ç½¬Éôg+Ɏ#XÙçy$V|¨³Ùßá3–d†ê¸eMzÖN:â´É@i åû—ÎóùDå™M§~Ž¥é¥`~“!g„ëIHO’òoqªDd½ÛÁÂh¿>:Ww+Äq¦Çí ô?U¨À@øõºf}䦴?ŠÇûl†Ã}—H€Òî6ïû‡ÝÈ[©õºu·AÎÒ¾ÂZgô:a§œašywÿjðJ[©Ø]+UŸñ•ÊøhÏþæg«ç®–Æ¡ŒË’Ú¹÷&{¸/h>7}VÀîŽ>ÔñümÁSµÒv:DnªÐ}üïKöŸLŽÿàÄ{ö„û#d³§ +̲mN<ßÔ¡C#àBûšw4m¬ùOp5è+œ³eêL©—œÆâ +Ãà´8@Y•ÐC¸l¯Ê«Ápü0’ +!@-Xì¡|ڋ]*&ÛÓvc툛)U~fVaž$žÏ(Åðh€žRô«kŒï° IÍðɳVKäIe[{pþµå«(;òÆî`ˆƒM˜.ô(´!ˆ‘Æ +nÅ¿â> +²{M‹”Ò¯t0¶¥i½®w¶ç×D˜ƒn;AHÕQœeÔu +ÛÒÔ4?8'êÑpµäTþWê±׈û±¡c#V¬É˜»ÀÓà€[2½“°íÖÃJ¬’ÞyG†àê9_¥œÉ¡9lc[ËQuNUÝ ˜ Ǥ˜á5ˆ…Ǚ.ñŒD¿HLDeîíý¤g¿oCeÁ³ Fó1|¾˜gý);ôÚûö¸Æ0(V\p¢òUÜ~¬å;„%BÆ+Þé "õáê ʧŽb$k2^fu§ŸëðÇBäd@Äí]ôå³Ç­¨çÑl÷…뎷œǾz^»|Öwý±0^Ž§Š¼À”¨AûÚ6)OÅaWâ.‚"ÄqÕå]NoÜÈ®3Â5dRQT¨mBpѤÓJ +õx¿V²Ým¹†¿5Í7¼Õ #HÇ]®÷'è¦{뀑BÞZ9žÑ M—„Åõ õÅ8][ð*Zü؈ÂtÐ 6X$ááU>ºZžÆ•`\W ÆX` Åã;š<äcWûèscüå^ 7lmý¬—=iωÂÝÄ̕j/ˆ­3mMW¥Í˜Û{T<ý˳±ãصVÐ;q}£Ü+ºˆMk`å´½½#«ÏãœÕ Õ,úTš¡3 È©Ÿu^ +vkfÛ^z×U—‘§¡æÑäù1W—VÎfzäJ®g,ş’k‡·O¥®šÿS‰Ç}v‹ˆõ+¥Zeôƞ”õ)¡/:âŸkév÷>3©üªkêÍF\YÏÏ'Zx!뮲|¨ãÏr;r =†I‘…Þ¥a{¿?MmËÐÀƒˆïQûGއÖÉÈ; K°ˆŸ‚rîi8\j6R&Y[ø†Çû®Éê~ð–Jüg·‚Š}sÓª$äää#BfºSò{Áaï ç ¤†ß´\˜§LêÌH‰>RÍ?˲Ç¿™ i·ß/ö™÷SUáô|#¼ª +̔8‹FƝ Ïx Ÿaòä¨A|á=YÐ̜9„š‚^ïÌ­18÷•ãJm´h AðÞe¸/vÉ?%N¿ýO ú琢PKþ[²"æ¢ÿ-Y‘‹"忾büYˆäùw¿cþñŠI¬ñ·²z»°@ç—+çŸ5hUB2Ç5ãéùÞ̦vÅ§Ÿ söÚHg-ҝN"âÈøkŒ¬ û?ÅLLJŸ2»#Ù¢R€“ºm¼øçAMlmJo´E«B_9£«T ³[ .vcƜ[öӗkáÕà…³M t4X_½üo}¹®|”D&VT¿ŠÑ²ŠcíÏäâH\öÀ½¯ûœiãF¨ 2 dؤ––³¥DL#éß6¼}^‰´¢<Í´-þð*d£Öý\þj ýŸMá?ɵ^Ǐ?6DßgOJüP¼¶C=¿[9^ŠŠÐíIõ‰/mËö‘P›àªÍ`ïÎö>ݑ£y‚à3ÌB¥ã,Dk+ó:õZZV 5¡{ªr±Œ"â[¹‡èG'gÓR=ߨáLßâ +aR”„‰ÓaÄ-¼†VHRºú՟y·ûe=éþRX|¼ÈÊù?*O‡b TYòt•;,»h¿³ e-zgÇ €kÌRÇ/ÒG-1˜qÅÑ-Y6u½ïp/OU½5V ÏS£&3êwöŠßýÉoOÝE?7#%½eÀ¾ )ý=ÁÕ£®¢v’rZ4¡ËëeÃÊ})…Ðs?Õ2%–‚<ë Zêù¨ñèQl&®tN/Š¥¨í­v<ÂVCK]Õc«;\EÅjû‘vÐ¥± U$øÝ sV–H]è.ã"&ÝõΘtîý•Øm[&¬´ñ=!ÁVÅÝݧý¢‘ìø@…¥m+Y Q=‹¤z¥3äÉ+ٔéŸ+Æ"_5ól­bZžY¶bÑ FkV‘Çæµ0ñü딬Ùcj€˜u¬_ »ÖµXŒ?-ôjþgZRü~°óÅ4)À¤çì/wøBÑU}Š$©{b‰Gä{ꄿ"TzË©‹<Rát$2¹…1Ä«8?Î'h‡N¶{ë)S'ûZù3ñ>+xœÿNâãÿE?f?_ö_­å¡ôRûdR9EYÉ®ÀÆ!ëWàU2¨œ|V)Lþ´iߢO+ü>Pë\ۑhæ’h«$£ÂQ`æF1@*}€ËDÒ‚2Fya°a_·ip”­o™î‹œoc4ï”ȕ”‹¾ï@uiðˆ  ɓ |0ŠMþNô÷¬"߸ƒj‰ð9§Ø£j•›r¥Ù€ŽË,x¦¨JĎKåËÿ0+ª­Î»ZT³DÚâ+Ь‡ù@àâV3¾PÊH<õé’ð¡^íV˙L÷'a ÍsJº~×ÈUÇÈw 㠐C·TËÆmóC¡7ÜÊÚ79ë¢÷q™¬gì‹Tq¬¤üï­8ñ@—ß^˜L»ÞíֵṐÂu*‚Âä1?®4G\Æå~·Úü°Š°dô°‚k2BÓV%ӛúïÑ}ë[H1ÂÛLà^ }3ž¢Ø ÚhÖìMyÑ3¬Üâ¹?AÃä(ZmßZk^¶Òz…·«f2á‡v­³Ô ¯‘%/ê®swWM‘„¡±ˆõ§ª@+’bŒøèvøÝ?ø…0 žrñÕºd]!´¯_Š§ã_•·ö[vù#Ž½oï÷ŒEfë)ÿ^û|§*|CÏýr°û–«¤]KÙ¡:2?9ŽÀì؈@¶¸­} •kGògõÍñߖ¿þ¸wý”C…§„];ÏZ‰OMqú¼A³×n*¢ÎxEŒF¶œ ¸È3I7•Z!€Eêß@A}xžÕŸýd©÷î°>é+ë +ÂXÕBV¨àȪ¼ÒÀ¹Å•f¬p†Ë\ù—+?v~åßwµFèË+ü#$ræ8j¶ò øŽ-ïKtÅH*Æ­]Š0"áµýOšVc^æ>ñÇÈ¡ÞûžbÉõÒÜ) 渽&#nñ§³^©é£°2¾/D#XWÄ»…3z! +|Òw¯2±hDÞ@ +ŽI@¹J0xs\“ˆŒheœ[¹ 5*w`fc?Őo?›'ö³*§šÜDkHX !P‰ØþzS;½Ë¹ z• &䑗<êY4?L6ìџ…Kυµ#£¢‘D ­–E÷عVÇÔ¾Ûî ,¤O,Å|ì«è[bD²Œ21øŽ‘õ7+§ÜEÇú ~ þ»« tn)u~.¼3ä”FwLùs1Œ¤¯M1Âl$1rðÌq¥qäs/›vGЅTõŠ[ÆJ}š*ÌÖyÕÞü+ÓMÓûˆ,¼U¦¼$Îï@x¾DÚkжUðEê9{ábsµaÞÞnΚËú}NVfÖùØô 1à 8ŠÓGܞJJdlåé ©M°¦,¤ž+$V¨PŸW²‰,•7wÖëH/|¤ÌÎt;\¬±¦ðþGǕHî +úv‚ðâǂÆþ¶ÈÕ·špËäßråî Z§~(ãl!zV£÷pf”Á¨\öËÕÉ2 EžwÛ²ûüä#)0cöôùÂ{Ô§4ãËæuÏæâžUùì_6²Ÿ‚Áó·[»»<,r6iせcswéö€\þJ6+Z¾h*Î56š­)—æ¼håžÓã셊SYœÊ¸ÿÖ£ÿ°‚$×=h+,/RB²K‡d–ûüI«y]#Õf%ŒõêBâäIÁ4x+ä9²´•îÏ5™ŒröÄÁ¼s$xÖvòÁ‰n0Ù\àPßœ€>y Ì3Àåàú†’Ô'˜*Ç4H(ÔÅõÜxœ`WHjýì¥à«;™9íïpùëʔ´³0`×Ã¥E’Ä +èè¦EdBE¡rŽŒ„…¶Î8šAI¨¹Ì4yíJÅl%;¼~Ñ@ºïeð¤NoQyՂù-ðBÐYXĶá½Q¢%ƒU'‡1;ëSdŽKž7cÆT'¢;ßíǬ~ç ߉ĂñáEtŠ'׊ +r^ଇ|´ãWEXp'º¤Ý[‚ê£êÑÂ)"t»Z™ù¼gcdF.sç&EÈ9VN©tðÊWYäÈuÂ8E°ÚêÉDloorþ'2J.ÞßkÐMHóؕKõçSröi®ßü·ºÊ~ºÈ?¦ô… Ò?¯¯d÷ÿ=ûäÀk«ÌíÞÝ¿ß»ìÔ*°KD>” Bã¤<ÁuN¶ƒL·6n èO“¹ô‡˜õ +÷ë¡å;ìÜW•!þõÖýÞì«ßñ#ƒa÷”"GÝEæ72 Uº‹¸ª[|t¢€é6–Ò güÜXS»å\KÏ[g••Ž`TˆØM …Ô+_Ÿôè(ÏQ‚.¥šJTQ·ß6¤±GÖ\3—\;HÉ#v±%¶txÞ8¢°ÖëŒÕ?YÙqè?¸u/ +uEúÒqV/4qZI_0j~õBK"RmûtϏ§5x«€³’rí,rçˆû´CÚg“?£†¨Ö¾.!yuˆµí‰{‰K©û èRÖ t˔\$¡îÇ%\æÅ*¹ç-‚¼/;9ùÒU†ö¢hÏþ¹òÔlÖø÷z9SÌëŸ +ƒýÓÙ2÷r×K»Ëøg?¾rEDqž³Ú$4JùðkCºŒæø<¾q„šGÍÉÉòá5¶í¨†é÷\RêGíQ\#¸<ÝSô¹#È]ÀTMuOU…?QNüØ o¼b¤¯žI=je”csˆçK!«ìž»²,½•’[V£,)>TËDrQâ`0~@4ã¯-CuÇX»mr퍆C½m:³ºƒQô¯I•fÁ+ ô—=৔­üVÁì<·¶›!<¼äMü´3ÓU +"ö´lVuOjzÊ\_ÿ#ۛWƒ›©ð¨^Þ¦û&q–ý ±«ÎI‘*¢(ƒ²Í“ô¹zʕ¶û +­ÜJÎ¥Ãǽœ•]±¨ú¤(‰3…#¯Í 쎀¾‡f`Åi7øó|êz6ñ(iRò‹'2cÞòÿÌ0ÚTöV@­Å¨2×^,·hJD¯ª» ÁxGl»³§-Ê©Wÿ,†Î*ÚѓRü£­Óø`\ѝ-ÌrâÕÓvhúúûTòá(U#½GFʤd/3éó”É°~P…¼Þ…Ý…þTšÀ`·×ÄÝ¡Ó½‚4Ë*<m KGrðoõµÉñ0sÉë@M݊1íòóÜ?í¾ó †ëßêw¤Ø•îrÿ<ƒ ©›!j õtö|~ZBˆ“^bN›.¨òh½Â¿-æúc·â-¯(¡ÛUU»¼ŽÌ`\¼sùU +¯Î•©!‡;Þ­çþ‹-±>£Ñ)a¦¥ü_h&¤@S&Z/bª37¬€³ö8ç·úE µVëài™ËOûXDß@ršžü^eås•©6§â +m|ì³R}ñíêÄj¾‚;Ÿa¸ì—ä`’̹]E.³c`j-ÔIîöÁÀ–úD/_ѐ¯ À°´ì뎓Z>(Uä‚yXûPÁ¯ˆV}®ížè10n 8’2ŠÕ9khåÙ¾~N5èَ4×÷[>{_ÏÞþÙÕ0Àú1&N¢À˜ô!ÔóÞþÞ=ÿG6 žà±IºVà¬éœ¥—§ÈqJ€eÞ£;°ÀsËvb¬…ñí‰C D±\Um5šÒn«t«ñØXò½Ý‹Ai(b7DìõËÁ‘Óº @¹êÐk^»´Ð@Öí~”+®­‰æï +„ªqÀÎàUïâBS ÷ ûZ£Hr4Èy‡7/Ñ~¥L%¿ê®£œç•Èt77Vs4q0 jI­H'=ê_õ’Y§AÕZ-€žf½M«ðÛоë[ f¤´8BÄuè,|£ÑÖ¦l TÇ;Ž&.þÚ ±?žK¯pÅöXQ–c àZ‹¦&¸¿D ŽmvÔDøK?ýž“tÐ2•øƒ-eTc{˧r%xtGÓ¬iÕrª¥õĪmŠàÎ~&Ë{¢eô<ª¦ýZ؊éœÛ×rôhôî9‹:…»ÆØmÛªí#÷FêˆTè8>×V5'¬ðd~Ôòž¢NéM¬«¬JIå¨.bŽÕù8V%fÔý¼È¡³´Yiwyvëzþ­.ÍQt©A_߬~ÂUbÞ?Xã?)^E ÃäƒÃií´%è›Õ’{ô²AÄÊ>G«ohõ£Ò²õ[†N¶*#èiYè˜W¾ùïÛU$ÈüéiQ*ðEGîýì—#ø©¯×TNîÝWUÄzr[g¢¥’.;̳ÍÝÀ| ÷ÿÃDœu›e›¤ôÌMm«´FÍ-ríL8¯A™·Àý”Š§w7Œ1Z ‚=[ýô\î^Cý–R퇈¥X«n#O )¿¦öíØlªýc×ÊáàÐ"ŽÕó!¾ß\ZB³sÛ*¥VéE±V‹1¸X¬ÀØù©òlX¶wá iJ½º—÷³D4€|«Nŵ!LwìBl^”.ðžÞ®÷õg%ÛúÚtø¾å¯Cÿ‡úª«õV¨Žüuų ŒzŠ*¸C=…b/㩕œCù‚«0ïh´ܾööŽ@‡!%Ä8âª0ö>’·֓|@©ŠšVšÂ}ƒ0Ôú´8K”v­»úcŠ´é&Sª]²#ÁWGr\¡ªk>šºÃÖ`Fõ„xáâúù]c …`«hB³µ¦yzT÷ÔÕ¬ cÔ0K͜ȹÉA}ÍpŒŸHžþ–M|FRÕ˞[ßOÿG«‘T6˜òù¼üÍÕzþjBñû£¹=µQFÚB.„§—tW†x•¢\™'!l¶,¨Q«vR{„ÅNýžÁ°=9Ȕ±nåÚ#†YjÜWÌZX 0IM¾¯Òöž³„‚á‹´™*Ոf"ùèÓö…éuèßJ7ð(òIž Á¶5bßTñ!Nçà“ çUÙkêFéu¡XÐoõۆ_ _†rµÌ„ÛZ”¯ÔWŒ +^¥®Ð3ZýµC•¸£fc„Pï’5p"ì摚ŠOþëÜo>bE¾÷–¿Pu¶•&gMB¡RµgîììXAS%’™½×sï ÃZ!‹¸Gépžª>Aìz‡úUŒ;Ò.5bcYE©NMÏ,¼ÈW%CÂú웳áà“AÌ6¯AƒVŠ7y$a‡R ³uÁðEÂsË-‹âÜJ€gE%ü¡ÇÉ~~w÷ù¹°LÛ~{ØKÚøóÈüIí_'þ3öÔlÈ÷-މŽ¹·zT®”(CسÀ ðsü{ñóC‚0Q “’Ê'¥Õª3-IE=1ª[©WáHu¯¸-^⿨ŠÓŸ(„ŠÐ܊T:oñ,¶Z¥ÿ^MÑV™y£Ì`¯ÐêÞe Ò)ÛñƒAuHDuÄlà ìFoWâÞß'tcäx!ÂêØ£†˜Ì¸q©D¥œ +5v÷©–×ce%ALi³ªûZ¢-¯ç;X ,g#Àg«‘ ÙïtÔ£Awô˜‘ÿ– Ÿu4LÁ9 + Yº]™q†«”†Ø¯õ +ÎâJ¡‡VbØ–D§©þxAO¿åєI(aZÚw¥¤‘ؕ߬â“:­4í÷7N¥¨AB…JðÑԹʚeò(b®v£VŽ½BftY¢쩒–¤˜è”óÿw¶cëW•~Ž¥’¥­ + +ïÀ¶e訹xݕíþ•¢‰½¢,MpaŸڂu¥etwMË42ë3ˆ“‹¾B], ¼Ãí½ uijlèÅ'1Çs&Ò©Än\ߞ5í£Úzc,ð/øGˆ¹²Hºñ0$oë®ïœ!ôuN-èÆ@lRø.£%Ö;)Ð7¿Ë ­Õ×óoEßmÄÅð.~F Œ¾/úãÆño;®œÏï_yÿ¿Ùe%´ã6ô¾ãÙ¿0œÉҐ —A””¯4nçO±Šô{ÿ~“ýïÞë×&ûC +0žºA°Ëÿ™1-äæQfF×O2·8?Њ'XÛ±K‹Lx¥»}r¡¨|*sMv¾ý·ž^_òQ”¨Çœ‹b}SÆ(©õÝ +V}ËUÖλʭKûf,ÇúUJµö¹Æ»O´]¼Ýp‚mä(:}³*Ÿ`MΨ2)ÀËsP^멪&Б;Üв`bˆ>ÝP¨¼ÕÂOd`Í œw”š”•«‹´¨š¹ló¢"%›2ŸèùIǖ¼´Op(°'%†}•öäþônJ´Á—ÎȔ½OÌlðäpo)1*?™Ô,Bޘ¯T*îßjü{HhŒl‡ê֒õL-¬Ï©¥n3´ +²Oeæ—6+1%‚“P/Ÿh#ÄÛ¦’QQgôÂfdâvÀÜÂT«²Iíµùòä?-½³Y¯º +\ ý»x4¶ø"Ïý1S…ìùø\£N<| Z‘ó#pß"óÈEGm¨Ž]wÆ®^êõ¡±Î|¯}U Ã*ö·ÂÜÐNƒ‘[ŒÔÇ-i1p÷ªñPÁÄ1&º˜ˆ–õ'z Bm3šYtϝL@Ž›µÒÍôƒU|ù9¯3uÛ$ 𘠶²îrŸgà*q{¥Ë%á=þóç§`|îŠzøR2áîh_2Sç<’DÚ$åcçê•Åyy}üôµöىñ2öόQ}¼·‰)Æ?sù™O JZ'ÿ!QÅèž{í0âÞ[úŸ¬uù+s~ ì3&êP[Ðw*F“Na 3’òØa¾ËU‚¿é­:rÀ%rLбž«f0Üt ŸË&D˜˜QD+Ò7.áû[Êw\¼ÁåßvK})Yœ{>KSþ½.|~*ØÔ㑣Eç|•åˆ%¬]©M‚NveÄú©ßª|öª‰ž~hÙ âõ©k3"[WÙÓd¬©¤:ÅîÍ~u`æ»ÊƒÕ¡;7­y®O&†rž)?åüâK)_zëÛ-Ðg…^#ïÉ@ÅWн·‚ +ykר/”§Ï›mÛ©Ìo¿¯/Ÿ²g”¦Í}Væ½àgTnÄ0—àçû™Üøóû)œ7‡CÀ¼"hP9;³¸¯=¯õO㥜×ÚÏãˆ&ÆqüP«/Hµ¨ ëÍ6cˆ¢É0ÓJ3!ÁÄO`õ (ãGºN ÄÅÝaŠÐvP¹UɟÚâ]%lĿ痃òqµ\åÉ¢¢©(Û{òÞДºò-—éâØ] SõgV!»rŽüõC—W>£»VcÛ=’Á»¯C …àüÉ× +ÜÎZ‡^€WûÜ|Ôӏ‘²²÷Ր@çá%ÝyäXûˆïçããl>éàù”²=1!ûó»ù9iQÕÂr»×>W®'ÆE>Y÷ ؒMìQ”sßÛùw²ì<—ÁòÒpB›îè?«á‚ÇF/xRú!·êÉO»ãÚÕtøÄUY.Í@zGèÈ«¬ã;›é°Žú,-ª]Øs‹cQ£}?"»Ë«ºdIú£”ñ׈ÖD²"rºÞ ]ÕÐzhÅ3`‰@/ô|•‰Æ·ôXÝ2ZÖ²:èÍ´èÔÞw•Äáæf +ò‹¢ +_Üô¬æ“ËÑæ,84½$~çnñ ‘¾óÛã5³å3 «™$‹çü4¬t!áe…½¦ãç¿×úå/oë§Lîü¾ûsëeÿt§åȨ†}>Íá͇„§Ìaށ˜ÂŸ<³AHw5¨ÂS1ùg ’dâÎ1£œ_²LkTS•õ¸V)[¼=·UËÈËvÄ`_èâUʌÕùùÜ_¾§Ô{¬GªHC9/4êŸ!FfäžUH×ÝñɅ÷]*fïÈúŒðky®¯ WîëC`°ÜX4%ìxC¬#F…s`\wûNÃκªÑ̈QÔR¦TÔ¥¬ÙŸós¡±(+L`*  3×>&À»Ø<: kµ\¹ëÆ,®ú·îCÏ;lçfã:Ö?cûíÿeàk:ü”µ“»¿Ÿüžv~GΤ›²va$/(šÎÇ:æž'—Oújóotóú_-ŸA=ìbèEüsÃ1¦…Ü[†WˆÁžG±vN/¼c™÷Úãù¬9L:=R¥ÔÚbjJø<̏J϶ ÑéÈ|¸=\wa©1„âo"Š)ú1$ý9’F»•§.[ùÓJs}«Ë®•»2z«‘¹2rÌ=’ßbàô¹u$*ý^ƒ¶çx8™ºW$E£vg„ì—JøGS Ž>ø =ÅCý/¹D¾ŸQOYß\8u©û¥hCÌÔó” S!/ÒIŸæš¹·}¡bR×ü¨²$çE¾÷ :©‡ÀÈüÒdQÒ±VÓAç‡kÛFgÄß"ùñÛ_æÖ/¯¿Ìµÿëç¬Ír +õ7®/®HOa§õÈ{7»”2d.Ýÿ…¶Îzmβ²Ùëd³êú^ÏG·aMLjdîy¾çňæ\éfÏÒÃeÌEˆƒSM+uá, ®öeVΘ‡ ƒ‘7VøÌ‚ŽÇ3ÏX—=Å5spÔ {Ÿ#}fÄ5çHk9ÚׅïôÙAbýßkP~¶æ½îóóŽQEÅS>Ú¬E#Àu›¼Íüó³i‡Œ¯0â:Ÿ¤>å÷[=eŸ ƒÑxà]P©d$š‚ÛˆÔ·sÖÆò‡Áö˟ÞaÿóÀÏ:Ÿ¶w/wOã¢ÖÀŒÂ†fOÄðŽhêlaö¬×­%ïûú·vÿùEpGD]»’kzឪºyØ;¢ê5+ö8kÄ.ŽRs×æiÎ(ç¸ò)áQÁ¼ž×wVLwm˜ ýy+wGoí)¹Eµiäº;E¡}v9b{“[ŸÂ +aNó Ÿ wp°]¬q0* çªs$¿Ø"ó·ºO¥™ŸÁ6Då´v×2à™t–5õ~.÷1ÂIãIñóU¼êÁ¸-J×Ý÷=BT9‹Ãë’EÀQfäÍûS§ïúNåËÁü¼³ªêŽéÒ¶™°ß*-aGVä8ÛþɅ*ŒÐáþÌÚ¥ ùýú9KŽ/… ®áø,95ŽgސŒµ¦3ùão’øšY“©¥mØÏ^q臈’³ _Œö#¶ð±¾È{wÈY é…÷¨>vÜ!Vç¨$îçv£ O΅ú)y›Ñ>rCO ×ÔZš¥µ§x¼€zÂg(®ñU +Èh¯Ñç\ûƒÔº`?DÑîû!MȾ®m"ŽÎXÈÝà#ú°eÈÜ ˆÖË##ù®G•àP“"²î•GM²„ss€=ꃲ5}Ê3vêHsH1PÞÐúhü­Tå «Ü¡»^åÝöµx»?g9´*€øµptÿùa„åϳæAÜæ—ý•¡Âä§ñ³—öˆD(‚Tz/ùš^¦j4ø›8 UrC͈b´ëÁJT=UU ÄúP½ùHX žŠŠHfôX¼Òçõ¹ÎÞƒmïšjXä“íóÇ€3Ff<‰Z°¿Ba®­†q¦„Ê—ê•în‚ܽ}Õ6–!ò‡×áK^Ś¨T\=Ɏ‹‘Ç tæŒÄöoŸ§•x» +)y¨>¿§×/}Ì?gjê}y?¹¯™éïÊëmÖË(ÍËT ƧïÓà•üPüê³$ò0WmÕžè±Ù™Ù§' ÜՂáÁÐÆ°4‰R#ÐûªaHóß[nQ%f`¯÷¸ýðÁkp[ ÂÊе%¦í¹Ö +E†>š%¾ÒlÏÐÖ´¸¿T8…ðý±í?·^BŸ… çæŽ/…ñÛhtü«˜-¶%+¤muù„`«ÅoŸw62ƒÌñè Øû¨¡Uïg}÷½•ú"{]Z†Búˬø9눯ï7 IóÏÏxl´g5¬Âò¬Vt=¨³ß™>šüìöûJÛMÚ8¬èèÃ$a%1*Й!­n_(÷»h²“ „![k¿Õµö×SÁ3SN^„cï¨ßÕÃ}¾3bqtd0ÒÃþ­§á9äÂpè,¶£Ç¾E¥ßk4BTφê1t‹ô›{²}ÝÒB{tßÌ©ñSÆ’¹í¹VŸž6åü¶çžûT6™_Üò¹a;e=>ɐLKè5®Ï¥YNëùH@³­ÝO½"1ã~i?e¢û­®4ïíƒ/ñ¹È›Z†âyð›ÿÊE°ù”×Ïïû¡fBØ»ŸîQÚ+Šï˜°#ÇâÓK‡w8ë+2Ÿ’(3(áÀfèµ?X#ñ™É7W°Ìð{ʶ +7êÐ|êÚiɑ±' ã)ê\ÝýÜr‚;,…ÚwG?d$½ÏX|øãk¾íÇÞÎ}9†ä;놮õìWáñâØ=ϯ«V÷I¹ã÷¯yÐóCCvvÂÈ­ñø¸œXw«‡ä/ß¿(MFso«_Ù?Ó(21¾´cÜ_÷=|ÈXó»Û¬·À$çsѪqnÝ_³0JƒÃ#ß¿Hêo†… g¬èï‘Ûúëšú)Q¾víßr~„œÑ>á†Ü“\³žyš,¾ÅGpéùù›¬Áó]òLbuJiïéïǕž¡&Á’¡h«Ë…—`ú||Å4Zr}¡Ôèú|}©ó:dÀdÈÙÏPð›`ž‡»Œ¡ÇŸ®M\ÉP»¥nhÑ1ßË¥(k +ôÍÜ´ +wŒ$T¦  CђCw4Í`^ $Þ8ò9t^…¸ˆîó¹¡O:BßêZñ(Žºy:ÔëGظɐŠ™ó ±üsmÑW}Ž¿ïŸ¡ *x‹Ì7ÁîþkÈÓëEi•ç¹ŸžÌæ@5\ž¼ I!8gDûI¹¬`÷«¼öïMÈY ñÆ{Vˆ¹redÌõu©ð7Ÿ©ØU&Úg +´[‰‡^¦Œ¾žMËè¬Éw–l³£˜„f²¹!04ëEw!³yϾ¹½ím®ýÁY3H!¸¿¬„ŸÊäGÔ38vîëÚê5Mß󠦩}Ÿ©alfUf?{ï@XÃ~~Àóîn=q,9WÎ{Häk†Æ½OÜáUü|÷õú‹%{³<íûL ³ŸÑœÚ—æ%3ºî:­Üw˜wÏ:¢¬‹’BMG¯^£«ÎäìÌ}ksgÈ#µÅ`_›ÓPYŒ^·œ½¨·*C¹åÇÛŖòÉò@>#v\ÝÏã^?#Ù¾¹FzÛëšÁӐã n#C-²Ë%I›7t\õ‹%••r9ú\a3±F_؁‘èÐYK@ šð £ ÁʛšòÅ R¬&Ž13œ+¯ñR+ÛáÉi²RáYòæ‚PJ Í3Ó(òõHͱ21¢W +ÐøGŸŸ\Ó.©œËé—ÝWŠ¢‘4Bݱ½p¡ +šüJ@{®™èEì)ç·á:°šXC÷PU*Ð ¥ÀçJ +dH‡¢Ò„œ†µÐùÑ.5«OŸ3J2Šž‰<ê.ÌÄ"®a©Q†¤hÍ<ø~é±Ûæ²9±Ö2fÂ)pK¦]>ï¡¢Æ[ʨœBÃH«ÌgøåjL…Õ) ™ §£”oñÍbU&R¥Ð"µ§6•N(óKØ0¤è “ÕûC® CípHWÐÝ^H]IÉE*eZEÝÇY£ëO!sXþñTNì¸Z2©õFS-¹ )âܨ ü]T"À@¨2šì¼ ˆeJ?ˆñ"¢€ñû• Rx3 `Î|Pµ¶B!H÷Ä]/ˆó…¸Zž "…Ps§T§Ï +öOáK¤DØ +’\ßæ{4Y¥ ³F¿B`:Ü_eŠn¯™ï +„^Qª¥$*Ғœ^)æ¿˜Ñ +"C„˜7:ÉďÃj°°“_ ] ¬ö$5¾j«Žª¤²\y6^Ü?Æ&×uŠ’$8§2è=ѶPô6ÌiîK&ˆN†ÅP˜´?6 Ï ‹$¬F­ðÊ,¼hŒÐIùPËÏI.PlÐ+E[1“¤&FZ2ŠFâ@É¥oºýstõø¯¦mԔ"²|¬ÕçJ”b n^† M,@ì4_°Rg”ِب4Ƙ^?ÐJjMV”>—®¢!Õøâ$$ %ÅzS¨-¦r° ÉŽÆ@‡…³œ¿PÃAɍ £'Š±R½U¦ Ò ›ÉƒN*Ç2Ò×ðc¢œ*‚.Ö-”ÒEÀNÑAՙéžcÎ"Ã` ížV˜U‚“° Jxqa³¢{F µŽR²\öH¥oL¶Ò£ÀÈ8jYá㎸aÛb¼ÆÉ®u†JZf° †€åuyó‡'•¨ÙÉzÅ eR¹Óº¹ +ÛÉ1a±×\ ¤KØyÔ´RD£áF*ɬk¡ÄõД'ˆmR(R½֒–J.f®'& ekÕ9ªM%ðÛ Dgêy¥¼Ð؟¦xLD|yèÆïå‚ ÔøƒåËÛ6þ<æâ0ØÓW±úµÒH(„'TÄPÁJ_åÁ¾›R0öç›•tqÇåy¬É@BºjJ1¡3–‘RžÜ?Vó%ä9 uçRð·lü´3êó•ŒÓ/§às¨ø„$9Œ:…`€Éâh +Ö-ãâÑ:AXpœ5¦†äþ¡h Ø»YË*“Œ"Á)šì©ÂÌ-g¬l¯Ì¢=ø‡œY+—¡:¹s@u(e|TVÎJåq¢íq×aBô ýÑw¥«Å‰ÅpXK)šr„‡çLF¦½:#둊Z@K§š·†·FUµÙ‚A)xjŨSIø.ªB¬Êò`#õªY¢^*Åñõ–Hgm²’(I¡v†x+‚ ê<Ø_ÌÀn"ž†ì8T§®E “Á¶žå$õY( q +vÄkÕ´û·ÊBQ{'7Š¯Xc( ’O ujÄŠJ¥¯¤ÈD¶–„YIf ´JêìîÎt›Q#B³A:/ƒº(ø[^3äpLé£=ÁÙNQŠ, 陈‘f Þ"×zé‚cÔ'˜’†à ëBö +XZöŒ1$¸;iŒ#HC’Δ÷RÕ(3ђJ‰0•¦jÓVH9H'–KøfŒ„§Æ±ú{)E Á®%êޗë#Wç-®0…|ÐURÔy´}]®;8¾0c¼(x€ˆ•„€Xæ ›ÉÌ+¶û!ce£•kä”;÷µ()pÆ:%Rð~çjN-‘AŒ¤ÆpxJ ©É 4]ÇyÖǼÓ>ØP™W¾ª'ÁڃÛĒ©"4±,¥å#Ä£uœQ¯{ˆÿΚuBT¾¶¶nlB,0à@„o;`)ԏÖN1` AqÍÄX–kUZQJ5ʕDªç´½å +}@dz‘@9ðÍB6ô#±Á<Ûs⨠IþiÊ̈õpõbßQ&@}0†I‰è×ÊMΪ‚‚:6,-æ¶ê#á•À»È#õ‡ «L¼¢-pՆZ·@8'«3‰ª V·:ׂP†ØbH?¯$[Qž+E•‡ÝUæ³½éOAå á]tÓ4ƒF£=³¤¹¿i¼?Àâ¬b|D±€Àú3J×Ê.KúžAõ%¢ÈùH?.}ít+H1Ä”yÍT¾dĘ;#ësÅ‘‰EFæZ­ÇŠE¾é§à¶¯ˆsÆ,_¯ÀQ?Åqçª–úy8±ÄË…âMUŠ“ÈP¢˜3ªGºÏ%@´e4Uò0 õ6C%¸RKP:£U«ÝʼàÈÐ\èˆzF!²ñõ”±, Y™^øb#ùpE³¶"ÝLíæÈCõ.ë$TйjÁÉYoGÂ2Xܤô…P ³nÆÉ.¤E¦ s§ÞˆZkàVZżÖ`0¼]RÝ ógٍ=&"6Ql¬Xˆð°i=a¬tM1®—ÚH v|ݜ"joеM°”ßWÔÂäY@U0²xh@£ ¹:/$PŒ§‘}Q¼¨Pø + †]å+Nâb±qç4;ÅÀKø”Z°çäNÅ.Ṷ6Tër¸¬²#åöX¡ÆDª¼8uIGÞIÉðdíÿðbw2Z±FFC”TAy™)áÒ }žÔyÕÆÔn‚BŠ–£\0«NXÂTI}Ú©´U0jÄZ#…C\x(ƒ,SHà` }bФHwZދ³hCn¡•‚RRi/«^À:÷·ÖKÌ»Lca˜ï:òJ$„Jâ?P®u ’b¾¿¾JdH"õj-IŒ©m’K„7 vP%a­(õº´šÁƒ…¿ªm ñ˜ Ú¡NË Ö>\N.)O +ȼx0ׄB Åæ×Nç…èñ®+]ƒécv4§‰¹… ÍÉ¡ÉäJxчÜâ‚ÉJLM¼¤b«e…˜nË´wµã‰Êd拂eˆ¡wU"#:ÎUbÃûBtµ·)­ÿ2¥\ ¨-Ìãmy@; !î°¶i®œzăfŒÖêˆÎ¥ÏÆJÏ¥ó³¦íŽ}Tþ¤”å‹è2¬%°(½h©"8¹+ÞòD;Ùÿ5k±³`ø¬ >W Ç;V¯Üq)ԖK¥8Vܨ G†Úoô­á1îûR"+­d yŒ$”#¢£1®NJ|šƒ–F#“R-Âöv[ +’ G¬b¾m˜°gFK|y»EY<ÉÔ +Jɉe2c!˸‡§tà03 ©ý?¿mÈL b,½J¤ ËÊõ‚ôÖÈ ŒBÍe°,é¨2¦˜Äíkí:-ê ‰˜)¿¬kUˆ,º-OA ֔UYa–KÉ¥œC=qÈ3°\ґ¼ Ñ]™åš+“ÉèâÆӍàN§ˆëHïd)3b—Zû9f¬}«^“œÊŀÙdÁ­Zý8ðN6KÅ7A‰iT/hPÂÐÒ8^(h2ª›”0Ñkîb[Âƪ]ºŸé¯¤¦òpXzgQª: ]hý­:c5Á¢‘ºg5ºW[p®œ*‹lc€d{Ё¸9`Ն7«¦^î-€n +[™;¿ª%Ú v¦œC£Rø=Æ "䳪Ցq£=×°CDD(&Ž5‰\Å7ÂX×jo´0ÝÁîËyaKQ¨%¸%ù{»…S#,½•T@zcŊÕöŒB@À6/¦ú&)HÄ4³¦`̀–W±è T¸ª–ãÎrâä¡Ð2.G‹…ÁïLÂÂ"Á¥ƒOoKÑi1JÍRŽ öš£”1Аæ‚Ù)9xU™Y~:SŸŽïʕ `¶ôε̧DŽb݁XÑ ‚^¡bQèÇÈ-ó(½ƒ¢ «LF/?GÎjs!D¬j47Ü©3)2VÁF/œÑäŒ!\ «rÃ@07¤jÐÏ%¶,e¶Ÿˆ×ı‚í¡Î€díg"öžÚbüY(å,8J•ä +Ô¹&­V à†Àó8qÁƄ…9ã ¢} +¨ßWÒkH¯ÃUqÁÒU6^:K0.Á@9¼/*Ñ¿®JQ;ñZújô”%p&Kbר&äo Ë6vr¦ ܶԝlÈúIj7ù¤‚á„ꆽ.–šn/֒u³Îë¢ÍçÄ]Úv‡`\U°ƒ±îc;×=f¸}{w¬ó*ØÞ… Y¾‚H„\Vȅ˜WFjÞ©&:'=_Âß:& ]¡b~a`670vŽ@•gäíÄ"/¤(ÕÖ2q¡£œUD±’$ÃgH™0"…ù9Û<<ô⢧]ýÔ_ò‚ #pXŒ(,*Z–UÁ¤Tð‹R:—`)*:¸µN/¥>—4̲>.ËéfŒ¿Í ˜¡¼ È’I€—ȍøJ‘õޒ‘+AVFj\ƒ' 0‚Qó¹ö óú‡—½ä ÛӘ9‘¢™Ü†@eš°(lA†]P,ñ™!f̜Æô¡òzQ¡IÔ ‹MAŠf"YN #'S!¸¤%•#µ²Ç‚>Jßؒ¨zª·U¸¯ág\g&¡XÛ2P©ÆÆ l¯‡®V&êAÆÜdJ`-p˜R?KƁbSé¢ʒxyŽ+Ïße¿ä9U`ˆA B}€óñI)f8°s¹ñ*­BlE:…È“i–RŽKÁŽµ‡É»ð…Jª ·4¢a:†$9)—ãwœBA¾F§uO ÆP¢ +Ý5(aýÙÐm„ƒ£µ‰á¯uéú€Ò);>£8Mb7P¨ Ù;‚'‰Œþ”sìÐƂ!FRш¸ßVÖ¤ ˆÆÂz²Ë©Q­2·Ö§U x¬Ë]ïa" ˑe>¿¹ÉXŒ%@d#± +‰‹j¨ä¥˜’K˜¨Ä]H0!–X3ÁøÜÏR\dÇW¢¾:„Ñ&I -c„Jêž4·éŒÔbɲàîöŒ1L‘ßy¹ñØS£ƒs—!V×9Ÿ)kh#Fó…jÁtÅêf•2ÍN"¸È´Ò 1ÓèDÉD¦)œÈtŒ`—ŠÛ TÇ*ˆL4Àï\ÿ‚u1”Ð4L{+Š[-ˆh… ‰ˆD€íÉ,š>¹þv’D§ã"ºX¥Ì¢Y%y Šë<«Î9 "ä"»bà”‘¸WµüÃA4——KȲ®òNß\A`υQGŸÌ TŠ”—Ân<atO[Öòeg“éàp˜+88ZAT"A].Õ« +çÝó®Ð0¯Òû*dØZ¦RÍiv\àÐa?•ªŠÃHÖrM)ijΨ…ÎN®6\~ÞJÅRp힧»„aïLBÅö.6h¿÷QôåQÀ¿Éç´âjKi¤.7ì]„H0u&؏¾~ü¶Ì­¢{—„Éz(‡Óò]ƒW[º}o³D¸a(œÓt:Prh›Nó«$¤•›H±>ú¶M¡‰«Hò9‡ ²( ]¹"j'8NáI¡¦ã= ­4ÏRåÀ|CÖþñiô€€uÏ¡ÑçŒÈÕ◧»É©jƒ9FŽ±Á$ˆ JSzòyÉ ò¹ZuR ®¦ZJ „'÷¬ŒÞ;҈{ëˆ DÝÀ$ º hŸþ9FàF³`ù3%ˆÆœ)K†ß% à£á£¥Û·ìf¹¹F˜,Oˆ¨ÃL”¯@Jzñàaµ¥…†X˞PD„Ö²) ÿB‰µzá3ÒۂAsõÏؚp5IÔU¡»V̈¨4ö›@™´!(ÝHH`N3µ•óBÜÄ`°T³Í†FçšZc݁K_0)@–gŠ^5ñ\‡øy'.\[‹!ûÐæ­GEÛ`¼R=ŠÚ¿抶_[ú‚D]iåp4löÜH3âª8㚟 ÅD˜ƒ€® Zÿ ³ƒ'dex0ai' d|ýðäT|3J¬FŽs¢Xhž`5…ò(T¿bÖJååT¦– ü^=bEa™ÉÃ:dÈ)â¢0’4çÕt¨²úä%%µõܟ(—Ñêk%ÕJ¾ís·?_Çöb`6o›üÞp¹ͧ7§ÃÝÉèÓ£ñþȇ µ‰[ýv8›/¾8õÃiÚFîÞø·ÑäÞhþd´·|ðâ`w6‘^Ÿ^ø.l§6%¸ƒê\|EˆDœ–13_Û¯ý O%ChLÆ{£{ÃI;ŸÎÇû_„ÞÝê€ïžŽË9§)vªÞiÉߜîË°…P<ÞjŸžzÒ¥öe£ËoeƒMlÎo~åíü÷#¬æN|MgïhÛ¼ÀoŸ·?ýÜÒ~ƒ/ßÿ˜ öß2ƒoî¿ÅT?‰&±‡*6 9IÊzµ’“Ç%ô³åéÓë?¸½®79K­Ö¦xNA‚ª”P,2ôLa"h#‚DbwRˆ`IǪ`!RˆÓÕa¤ +z¢—W°Dàö_(‚¾ƒy\àãF w¯BT/EJŽ† %h¶N‹¡]­­ÀÜà6jƒ JlÀQƒEN½‹ß´ò¦=D6 +—F3+¨¢A€¹ŽèŠV ˆÂÐã(Qmh4@ÉW«A³Œænx¯!…;M±!$²òFŠ<„÷  ‡*£Œëä- Ë!©j5±ð +€dý@Æ3¤³Ñâí¹F~â9‰ýåCp-éŒ_0ªÐFʞÑÀ-È (À‰{½ð°å3c×X&Ns‰çٝ¹X_åEˆt`åΕO”O‡I3Ï¥!Q¨F¸b±Bp;›Bõ([‹O)аZ,–vMÆ he@j7 v°ò*A.¹ÄW-kYð< ŒF>VÁ^Ïdû†n="Ä"S”™”Ž#¤ #gE mDŠ³gD´2u:}•ŒÀÑÞZÐÈÃëœÉµM†Œ*ì7ÜHRC”•©¼§JÂ?,í'ü`)F»ý•)5ýwè·gµˆê\N'̀øq̅@…ÕØ|†¥c¥éb„E¬¤œŸI%°<°o òÐLkúŠ%‡š> š<™ÍÃè£Z’hF^H±AŸ]¡9Š¦‘ê0’3ÈC@À—àבë"¶UB ¨¢Q T…ØÜÚ§ph¤l9#±ZÉÃ醀G, !Od~N*s´ƒ€è0ýCR-érh¸ÕÛ1@ bh$ ?’³£ 9f Otb5ݙZ +›±b.QW¹&º5Dá’à6šÅ‰+ÉíjX¢µç¤–Bt¬8}2µ@ž* (aBÚ$3÷èÄŽ@®Ò+ðó¥Ž҄)s"9ÐD¡x‘_x@q¬ôAcۏX:Ð|‰“œ…$ª$Jâ˜sh¦!¾(Ø ‘zB³„œèŒeaà“Ï+ƞŒæ-®xA½Œµ¹P¤\µß¥š– †«_òš‹€U©€Kükt1$ñQ"ë·5À­jdB¥Jœ©ääco4™Ì˜ðæaz/ rDŒ•Íe©©~á¼Ð†×(ßdF›ªÀÆ£pZÕs¹ÖÔåìORj•çbÞۓHQB-p>9J_!¥È}Q(ÈÆV⩽R¢/UÝBÂçÌ*, ñ÷m@•†Øù°FÇ2ÈgE£dœlaz*&öž]T?Ýø–ÅE$†Qà‡­ñ…Dc”K¼!/U^aô,Ö²~¼wpÁɝàU–œõ+$☛oD‚ÌýhßšF.A§·¡‚3ÂæœÉÝÇzÛò Ä#ÃãÈ !Ý>"ÏEŽ7‘“ ·šTPÏ¼Ø ¥"q¹~(ó(‘ÕZŸÄldk‰[•¢»$¸?áÊ c…”%×W!œ{"²:¥õÕCBZyŽh„ÐÁ±ä¹Nô1Låøå@”•;âpèíÁEÁL5S9ÜHËUM]£¡“0é0ù–oJ¡ +-+>W¾(ăˆÑ’ûÂ=âH [›’¢Ö0¢¯Óî´d-(œPÜ ÄQ,+½×])œ’Ïi b§‰¾ÃèPÊ°|0ô»2Z¿‰Þ$ ä(Ô"‚•à«LíqøM[%„PÓ(è_íëôÕÖCSJ8o­ç“X‚5“d +EsEþR£õÑÛÇ +Aåuš?[’ñŠíÉꠍ¯°UZžEÐЬýlmE3yà`˜2 ¸wE‚Ï@qˆF%°ÊÁ©–…2ãˆÞ!—ê”:yVԜ¢J*¦!º™8ÔNÐd%.¶—g;³Î=ƒ#^*~=eF”ÈPã)«Å¤¢»4/5ª Þ<"º[)|~;^‰LP»-«•Äü +„ ë¡J¯<9¶Ñµ-5Üb[$}k1PQø8j´Â‡Ü:€z—½¤šoË8i ü8C7œ·ÎUŽÀÐñr5'>M¨×-™ˆ€*”TýFñæ^( N¯‡+/åW £v˝"¹Ÿ‚KÉÚ~W¹À'…ˆ›†R€$K`yÉ£ ”ˆÌn÷¿@KŸµ‹S! —Õ¼jDli¤à#mE,DôœÌI{ŒœZ;ŠV&‡ù¾š×È ÖŽL˜ju&9 +@èBÜ#µ?„Pá~4šS‹3!fiÂv„Å5Ÿ×+Ð^9£ …Þ¯Ho‚oš·ª.Á4¦J›ZŒb¥ç*Yà Qè@—Ó³˜Qõ¬åÌó)'à'tŒƒó»Jpú‘ÀÌ´–Jv/“—UҁÙ_Û9‚_ Œƒ ¿‚¿ˆN8kªßpŸ²–S¥Iô¥·ƒ2JðX|غ+EŒÖÖN ¨rRaØ6Ro8Ó¼^=E#—¢3J;`ԝB.âë+åÔ͆Èl¦îè+¦ÿ¶ÒúAt/…Ð j8yÍdF·å’+`‹F¨$÷[&«ïr•‰„ºz­èJÀú†=£ÈKQAaáã½SJ\}ãHˆÎÄýø•ŠÏä0 Jô-ðj Õ®»2ˆÃßþ錌QDlnSøï¤Z„ò_„ÃfCÑÄÊ*¤14)ØóÁC¥fF#¶Iøa_Ü€¸]+/ÍTjÉŜJ¹è½ÎŠQˆO©ñö‘•ñ×Zd—&!$Ñwîse$ OZ#B±ì¬\Óy<ðxõ6­hh©¤ä,2‘ dFÖã½KõŽA£b-_ƼAL›ŒÐú iy—f%qÄ,àݲSúüâk £I˜)Êÿã&cJtñ Qt  3N_AŽø;PI¡¡'že”ÆQ¡Ç „±&` +C'p/A‚„ˇΣÓxЌ1È6‚߃¡Æ—›…s©Š¸ËqgŠ<À–9{Ûs…[P~ϭĔÕtM:ôBéæ4É$‚†ìÛ[¿kö6ø.v m:˜1ˆ‘ÄÅ ãl0ð> ø‚nl ‡Ï˜5ôPF-â$Öbý¦y f9$GCãlÅ>0.w‚!èj‰Š¿ÃÇ +䢕a²“£8ApM‰{]ÌâFí先€0j€¥ˆËN¸c!Möà˜è̺'Ø”Ø øÜÎF€¦ #ô[–«#VÛ' Ôt'‹u + .SIì*8¾¿HàKˆF +„þnK€ñê-ƒû!“ mä¡7«1*í+íÇ#d–x+œ(¥Dò&m¿GÞJŸƒd€fãwl$€iÄ^ )XW`€@„±[-ƒÌ5˜!qÖñ¨€f†ù ÷ &«(&É*³B=\GAt1\Ÿ6$X& µK‹ÖHÝXbc`¢SP;^¦°¨Òf<„Zeº2CF«2ù ÛïǶ7Nl9Hždq\„YXÿó95C¼ÁBRÿy„ûþˆÁ‚a¯%Ò©\6Vò«eŸ`^a9*½}'“¥ÙÃÉmÏ1¤Ø80ƒ±LA©Bš–á#ÈÞPäÆ=!w¡.05$»æ„|Ë³Pó!¢µÚ^®¶¾Z N†ws> å°’4ŵ,UYatg¡U_!þâÓ@[„áAQ¬ÄŽ‰‹\ +QösJÂ:š®p–R5EL€8Œ—&²aLCÆ\,ÂDæŒý`ü36ŽÖg¤1œÐ¹„˜@\{žË0¢:Ží«Á©N"’˜ŸN^*æËå"À•ÏBU€„,eÛ8&³6b{0†Ž’ó[‹ UV¾¢l&ðrí¢VôU»¯Vb©b6扫=$€ÛŒ¤³7¹fè‚q"8´ƒG¡t ò¦«aOL«Rñ1WqˆÄ~»Jå`Õ"«.€ù34I9`7¢ÛIãa;Vqϯ|Ö,ePª5·.%ñh[”IIêƒÃM1 µÃT Á¢W_¨)=$"‚‰kÊ§Áèè +½åÏ\ì\T<(EbÖÇ=íT„@ÎJE͌t^ ¶¢¬´§ÝVߨ#Y»ØªXs Š L¶ÔÚp¥Âó[_¹–Cuô}¬°Ríi¶Tÿ ¬Øp¥†•så]:ãÁ‡¨€-ØËƃßxP¡v•م›:óhHÔVkµ²n냴/ú‚f,öù¬Ùb«oô–|-ËÈJÄbƯE}F¼?Z³†y ¸—1ƒŒ[+Ox:»™ —kÎVNðhÿzëB`­!\λ¨@ü ÈdÌĬÞèdÈ?É%í]·Ù`ovp8;šîφ‡£ÁÁl¿ç·ý#<ێeº +k`|0k åeT´|}ýÔ÷gÃéàá||0ør8¾üp©¹ÊÑüp¹ï¾6ƒÍCüºs’Ûº]ï·Îè·nEPB5º’ïwôWþ뎴ŒîšMÕeÞnþséûx~¼Œq,h +Á æÇ |#eüO)ãÏlÿljõ}ßû†‘þ˪ëß?Ûï“mâŸÏÒ¿•þ™¢ýûgû}²MüóYúÏ¥1&IÿþÙ~ŸXý|–þ é?7]ÿþÙ~Ÿ¹éý|–þôo¢õÍ£õû4Mïç³ô_êþéº7ÑòÆ]Végé¼bçÑÒF+Ûu璟ÎÒoÍ~M7ènE»ÎL•þx–Žvl»É6݈£þl“þºÎÈ(<‡xŽl›áÊýWóç‰ÿ¹j´"]–þܘÐßý“ÏþæP~}ë?yÑBtÎÂh _¨Zc‘£ +ë_j½3T9M…¤‚Þ  ›$T{þY¦ÊZúG­èœÅ5DÂR’RJc¤ ‰ P+ ¹ …,ü8£ÌRိ¾UZ)ìR÷»÷àt$–2,Ґû¤uŽ!÷e7J‘¦AeðŠJ!Ñ:Ñ#5ÑÜtTIÿáÈ y+Mô¤Z–ÂXéÎbŠ@áJ¸”h«ÿh>÷¤°$ñ’†LˆçKèæV ¿ fŠîYNIU­Æã1”)«<©–É$\}x–h6˜Ñ¯ +#¢I¢}ߧEwC?ü³Lå¬CµcPüÄKŒ!‚LÞQäÉB1t’v\Q¾¾L[h Ƒk P¥ö|­7$1ڗs'U +;R!ú‹6P%uUºƒSiDÊHÕEçö’áYyԖVß!šHï:úõ$ùgÅ}5Dþ€•—ø¯ §P¬ú!9ñT:@pFXW¸ö…’¸bT1AR§PigŇdþd2P‰$ÛèHJW*ÉÕÝҖ4rƒªX6¹º0SY8ÔÖ<©;…í7ÌTÔªÀ €ÄJ'Aâ*H¢Ž]e¢Oɪn¦ÕÒ%½ùIv¶ño-tl±&Fs +ãn!ϚÀè¤F3H¹ë†,Y|AÕåėÚ]Vø³,1µB2…Ä +F5#¡u/ËOĂ4ºE3F+xRؐ†›*nèt¤ê7<Ýéçj¦‡,n­{YÂj‘è*÷Ï*Չ÷Uz˅;Š·G^[øÃÜt#V›ÓÍŏȔ=_!á¤t'(/’v€Ú°òÚ20tÆìÈå”uÇ@âßxVž;V¾;ºéW/Ù½ z%$Zù=¹ëñ³¯þƒ6ñÏUóŠÆ«½èåŒBï[ + ™7¤gÁ€;ñTÆ»€î)oªü1] $ÛD ‰ ÔÂsbϐ$¸”bªˆÔï¼é¨~4b_I§mN^’+ç’{¬R€Yߣ@Ör؞aHì¾­jz×t¬&­¿÷ ¤Lù‡äôU¹8/ÂWH¹FϚHr2Š¢¬¼€À;ѓ @¥†  ³Í»ERT³”ƈ%O•QK!ADiyùJ‚•Aê.0D`fâß7~R¦•?¿[:J¼æ*á$±L H•_4òöÊJPMx”Y¹,®Z¿ڙ¢ 䊅æIa§5-ì\€ã¤Kœ]ò)Ì¡˜:’t$fEacȺ5Ά°6))™€ŽZ:Ñë<1ÐC^juÅ2Ûͺ}&Ë£§/^DƁR˜²³þÐ2¯›¤ÔB°½Xó4œ¬¢ƒÆÓ°Që+ƒT”þ¶rº](únÍu­Ô,-,&Óz·ÐFR¡M’Vƒâ†Öô:³¾Z-sö;™²éNbrø ¥~£ÂÇ™Ò)cJæ%©æ°Ð<Ájž—ÉÂbè–å+‚Œ«ç-‹/röƒ\dEw +5l6!ÙX*õT¿ udD{¯5¦¿§ýåmþÂWñ펈·Œ§ç«ˆðÞ +ºmÜ=Nx‡Äü§g±õUžàe©¡ªÅ-J2Xê¼K ¢ˆYZ™>åj +,óä|yé&YF½Ý’óUh^k8WÊ£ —V­R™€3~Ÿ+Ý>9½F +ïg ×M˜úîNŠIÝÝSõŽ+$&¾ Á4ëݘ…¢uFW«"7G÷o!™¥½ë;œ¥äú.$ø"}\tíHFÀ‰³þúŽÖ½ÐÙ^è(D7E“Bc ûsÊ;w"YO¤½ ë•U'‚…êŽp͸NìŠnÛ¼š¬÷j/zc’DCfâZñ¢žfž*$Æhƒd¼ˆ,QÆ Å·”d!œ5\g¥Äeݕ×Qb ,P%<éMb“×R›êl:> H-¸TãšùµÆÛèøeÜ0lF·#㣗0ö¤?ŽG]¨Ž}[D2ñ¡ê¨¥Ô÷æg´oh:ó…@ýÇKD¬ç2YHœŠ*ïHÉe鉓‘…÷Ê|,%üûJD—ªàð*UØEG<Çà•BUFl‰¢h©q…BnŽ„¿&¤ø"먪ûû©ôÙ6s-PÕ=jõQ†¸)ÿÒñ‰‘T8jMêL ©~ +¤DÐ +5'èjÜiži\kÇL-³Ž8ÄhƒHl<¿Å3I¥ä{&ޑâ©é¨a ~™Î´(îý%aœA¼r"¨$«[˜,ZðŽ5—k¶ŒQ‡:—:H¤µß]S¯z®P™M½ßPÂsÁ’ê} +l¾Yã­h‚QÍLLJDÿ@ LŠ5dE¼EA€ÇË( D†W§k}„ß êMÞß^^…N7’OƒíSifJú$êSúfE0©N¸Tù”<Ѩ¢Í“â™é¨a +}oÝ<‡·& †ç×MB’µ•\¥toEì-Aqër‚GšR#.×»»Ëßô =Îuw²¿{ ó–º{8þÙ¹W¼ü_íE¯bè)ÀT4±' `ەՑT(òH…WIhIRçH*e“ToÆ×À¡&8ˆ +Mñ¤p{o;m˜ùáyY^̵~ ¿0„#¶^УȀÏÆk‰©ó'EÔ…GPrÿ­‚(±Î©äý ªS©Xw&[Õ­#5Ñ¥†åˆýjtŠ¢âIáÑó›4,*ߝfœzQÓï[¥3¨N%_§«¨ƒS)"EN¥@m¼SI‘ÝxÕ©äTØâQnº!‹õwJǚD’:‹"~‘x•Þ7,ߊ¤ÀÑ )$UÙBh×æ}Xù3Tøîr¯¥nçUÂÍ-rÕ›¸^„9ƒ‘Å®)Ùjp½H¾)¿Þ‹o‚¯ +R,æ1³N.RïzÉh)âÈÌùráž$ÏZÅËôԉ§Ú²ì=î¯M/sZMWç`ÂrÛ Q}Ô_K^æŒ(å&"ª•ËD@y¾ñï¬r½Aêè#Œòwo[³’ÒË(n1ÀYÕý<É?ªØàMl¿³¾°P[­BGö©â#öT!1Áš¼ÚéÛEþJÙ< Õʾ¼9ÓjÒ3S‚Ê>¥[ôˆê}/Vò6ä8ûU# IAV‘!IUË­U9±Ö]ë%‚:u¾d-EÞIˆŽžÎ5­;zE®úK¤h0CžÔà~Q:r¿Râ~é¨ÞÅÌA‚½ÊÔú­‰aËx&ܹ_LÇù¼V%iàžäg¯¡«;ݾ¦‰Ý ¹\¯’õy6¥è x§ú_rMôI=y'?Dþd¤”ÚÐøÈ*¹#Iòñ@‚#äI]†ÎE×ý½î߁ïÍ»÷z¡§Ÿ„‹ñ+Jý +æä„Ï ¾./§%S#p ýi”¬ÃjWÂÚ¨d[Ç6LUw˜\ò¸dK„¸9¿]½&&Åû+P»(,6Ù®¬C±²¯í/9UØ×á˜H°BzÈ +U$ÒSŠsՑ¦;<ÁԱމ/TЏnz5òÛ¼ ÆSL z‰P"£"ž…wê±KdXE«ª# 3Îâu,-¨wÆ|”Kº +…”H™uÑ] U@b£ hðøšÀL—+÷‰æF÷N˜û&rÁt¤Äý¨Ázgü-Ö¹` #7Ó«NS-´ÖY iW‹îáB—+½ÆÃajÒ +Vˆϵ¶k"+TUéïñ8žƒ"p"}Š,•Q$?„¾às'‰·I|0í6Öoa®’é,"ñÏEþŠf˜W{Ñ˛aœ:Ã{Ö }^¢Ì«XèCtUÕh¹/÷k¡*r} ?Hñ¹¬˜„ÎU¯!UTA +»¥”ú2U갓ÛÁSƒ›;«mïqÁ¸âK‚ç»R ¶dëJù:Ûïqæ%ÊÇù“Бâ#ÓQÃْàüdpðHãsšì Ôp ‹<“wÇ^¼ÜžÔ)¶#†) Ž ̚ÔÿSا"!:…’+àMàw¹Ñ͐2F-ì1ÐZ±r:.( 3öT/ôIM Rª.á&7€b•ÑU‘Ky¢2ºP$ÁѓÂ^£ÃS;'7øFòxͨžä%ŠnV¦ñ bºÈË(¡Ô¥2 +w¤4( P½SM`åA N5ñ­sæ#¯š€0$K¤g0^GÍÆ,Ó+IÔ½þ.“ R0ã蒆‚V^¦a7M­[Ƌ}­îJT¬r R'ö9)ø + ‰bI™*åƸˆäŸev^¯a­[ºëNL|oY hM(†%~F©Ÿ!öÿ½ÁtF§k:7-•aEéeU'·>1>é­¯“ÛbNjO'çöLurOJurOMuòäqÑɓ—ˆNލV")Vtòèã"ҝ¼›­¨·žNžN½×É£5ò:y²’ZK¢X£“{â¤Gä.Jtro?Juòjåo؞Nn݊NîT©NjO'ÇåÖÓÉi [ÑÉAíéä<¦©NÒªNN‰/ÕÉyÔRÜ“özS³F'_¡j­ÂœoNurqE'ç·¤:9¿8ÕÉÓ©‰©=<ši¯“§Kâuòhí¼N­°×É=)ÖÉÓí¡:9XÙªNÞoj|¥–5:yòv•^܊NÞÿêäÉG‹ªLMGZÕÉ9Ù©NÎ%Iur¯Ö¤:y²Èá+ú:y{‰Nžî$¯ö©•ŠÊ}®åþH +.§ß©ãR¦­×Nêæ˜<èãNãFð]>ª<êÕñ`7Ƀ:î|•êÍ%áƒþ‰P»l£[ÁƒlÔ.VÛ!5m±z¼'EŠN›jWàùQÃJ´ëN M·+=ÝÅçfbà.[˜wÕ^NKæF >LœÉÙ5Ä ­„¥Q¹6ÆíRÒîò:|äU+ý~•,†”o°@ív¢×££ýꯅtcK™Ää”ac‡s"VÞô˜'^ëñk×݂)µÒ‹° 4r/u7…˜ŸÞ•â´.{wõ„éÏ£ðÁŽ”DÎj4.KïE§5êÓ ƒ1z­†ðÁLTÞî>†»%hëñ)“óÔï’dÉèq_}7’ +-Dۓ-*& %Bˆ¨%±¤"ð×éôş•èAÛIڝ§Âª{5ÚVñw¢dµ0hºÕ Úe²'!Åë +櫎{*µóT„Þ:OExmäˆÆçVƒ‰£sjf4=åÞ¥‘sïÕHîb£€1‘§BŠü¥£É}!jy*Lã¹FðTR"QtT/y„Þ:ñÄx (cLᅛ ïHÆs"eþ¶HR0%N:=å5ñUˆ?‘ŠBl4º›SªÜ‰ydLVÝ҃ԒÄô&²ƒÈ˜¬×dY“ƒMª³&w¤ØšÜQkŸ])Ð^‰P\q¨/= &n"fKæD|§¾,æ&±7Þº”R­šz:s²€ F,Áz}3á ¨èÓ¤<Á[qùÉޞܑb{rG RJ\ESmÅ–.‰•BèñÚYõ­F+ gbmp̊þözÌÆƾ +ÛÛ2žÊ¢u«ÔJM¨ÝË¥pB2D½)zßâ +……oódf:R<…5°*`âŠÔ¾» vÎ +Hx¶¿Æá3º pQéö‚Å%[³½$¥O švèÓ_~Ὑñ¦àÎUaXáG>DD,£ÞáhkŤn^bªN`×[7Ëá­ÉrøíV­ÂÚ±Dç©£"|~²5‚¼9*"jÂç’[ðN‚p‰ðÁÍ<ÂþDÀË{ú¿_}U˜Ëÿàm¯F(l/ã$äy°•ˆq7; +âP H°èüxlÅh°›:m|$‹t)QðýšmÒdb!·Ê@xºvì/+C$žXlQêžíýÃr£R jICUFÐlcUȤ8^ YŒf©@î2÷Œë÷Pç®ÿ"Éæ˨˜(‰Ž/c¹H+fb0•Ò› O¦Íw×M®à¬¬B͂‚ézI Àt]%_6ÐÂ\PýXÙ¥|ã:*pè 'M’V¨ôPzªŒTŒÞà¡kD)ÏE1pr[R/æM`÷zg«ÞDƯðal2( ^ë”4D‰ͅ(è}Ý~0ä½~bÅ ©¤  s›yj8\ܐÉã*À‘y';œ…ulÈqÒ£ r`ˆÉèg/’9Ô.Dö¹·ÇCC9¹w÷!RÂ;Y![çýuT¡IIÁ"Wox~T7TÎC‘¨WIã\ÃV¨Z:¥6y^&ã‚)©¬“Ñçš[ŠÏ„ o"]Ñxã”Xd6œÎ^LJf7P%¼IºÓ…6ÁDÜè6‰5÷d·ú°%ëêû=¢†Ònâd‡å>7~ZCºmœ{7n²Ý!5Ëd•ˆ‡\ Ýáé(Ñ tÄNx…|ݘÂÛß^ã;^ §s-£Ä¤§Û+÷@·½í%™½Ÿy„kÌŸ [µSsª+©%^…˜µ:'뫚 vÿ&A)ÏP»6óænQÌ3~´G¡ ÇOýJõ8g.ÐÝ1CÆ´¡çcŠLïÞ,)v%e;ŽvŽÜB9óX Å·KG×z”½»¬ÔžØ¿×òp‚»+ÐãèÄ7e®qô½»²uS®Üµ¹DM¤ˆ¿/*Bu7bȀÄп`t¯äÎʊ®ŽüáAB4écÈd‰²šß¼ýÙ¨t4ñüJÊkÆR×Y§ÎJ:qÆs–Gܨ”¹RððÅÞ-whYx»$ +endstream endobj 25 0 obj <>stream +‚†3#{‹òsg@—«PZ™gÚ´=fÅ ²ë2Ö*\õ ––ø>ïÕM‹Äg‘aóÁ¯ƒbðå[ZKÔWÙå/R’ð~çam‰]TŽTõŒk”¶>Ðތ˓*¦­t5‰_Þ{wüêޛÓ¯¼·÷Ú5o=nr '®µ&+Än.®‡–÷^ Ú¹ô'mşöDÐ÷’ÿæù‚¶—_õ I¤Ghý”û^ó؅õ`+o²¬åÌŸb‰”#Á\éכ«tÝi¾:äþû0–_¾ÚÀº‹Ëˆ¶µ—_ýWó—®}øÉ·âOÞܛôP VÞ¾úԝoE}û¿¸®/£l¾‘ëë4ögÒMà_uïùt"³h"ÛÊA¤ƒ°`3ÉNH/ÞAéæJw^Xh¶‹÷@ºA⽓n«tυñéÑð[…Ã-㯍wMoÓē”.hºñFH÷HºÂ<³]¼”é:Ç[ ÝéÖ ã{™óÿbåÎzÜߤ~¹ó±ÐK2oY7oýÓ­Ë\vò ~¶GØ1VM¨m7þ—ä®èZp¡“e×þý…o—°ƒ²¨ý%¹5¢fÐߦÒtu$Ÿdêð{Ä÷¼¼äYŸÉ]Ú¤èML‘l•°šxàM4ð°| n‡d $“éÖm6<ÇýçQÿa¡E‘ôPô&æ%¤†‹±º#^J°øíœW7V¿~u®mžÎµMԛî‹úJöÑÊ6ëíՍšìãx“èuí«ÞëíÀ•-šìàxÌÝŖ|EٛÞÞ[Ýz½9M¶ÃÊném§•ý–lÇxuô& aeŸô6ÒÊNK6b<旕Z.Öüå›7|o¼¼¼³òÁ+SÛ±—UîòÕ[yçñµÍùrg¼‡7 ç/€f׶f³ÉàÒæm“ß.—£ùôæt¸;}z4Þ-.Þ×f·§Ë´Õo‡³ùòá‹Ã‘oÓTb³yûI&?Uї{íþh8ùr¸œCÛ¤§æÁd¼7z°7œŒ§O?÷¿½Ð>Ýê{㉊Þþ!þõÖ_šÁ¥Ëƒo¾niÉߜî?xq°;›àðûã̦÷æãé²}ÙÕ«Jßj;Æyë/ÿ8äßjùÛ½ÉQûï»»?ö–oýåÒæþlw4ؚ-ž ¾N‡OGóÁÝùþh~ù´?ä¯ÛÃÉdüt><|6ÞÓ¦Ûu¸6°ƒÃåÆàî/ÃöçÕ¦—WÑGü€;ñ5M¥[“áòÔr>pv4ÝOÛJkž¨Ž{bµ­~‹q«´õî´]ïgIßÛφ“烫ƒ{óñn»CÛÖÒÇ ÏܚÌæÃÉàÁrtà;ߗ¿‡VÒڎ'»£y˜Ýok:ÝíÍ°iWy†…m¿eCwK»ÃÒ½ò;ì»þL°±tôø1Ä3ÈÿòŒÔÓþ’6o?ޚ·çg2âÓwÆ»-+x¼ý mX?ƞx¼-óq4ÿeôÇ~Õ1ûïþŽ]ƒÿÂL»0þ+Q#ÙÉ£~ÅtÇRÞoñO9¨Šðnó»½;ï|Þþã?=úçwy¹ÌääkÆ‹q»µÙéšN,‡{Ï_ª“­áb¼—ô0Ÿ=½L–šÜë£è5°Ûi˜-ïcì·Û•†:ªÙàS)'! ÷Í ¼åóö§Ÿƒìħ;øþÇl°ÿVÛâ¾ +~³×ž >¼õ—Á¥¨ë˧Ä ô[6÷‘G»öFóEû“t³9Ÿ©,¨b«—”MÿÞ4eô»é~üïx4œ¡S|=Þ_>{øh89-ØoÿòoÖöƒÈª‰ϛºÿžíÑ´]¨Ñ>ß½Á†¯å_̎æ{2KícÏ7oo†GËñ“£‰ÌÄâÞp>ÏM9'Ø×kÈ>mVö¬—æ\¤MWÅA“½ø 2aUî.Ôó ùæ1È:»`çåþÎëüõ @ÏL*Ošªèɗõz9ðeýá¦)S.yl|e^$¿§O^ðÏ þù¦ðϋžó0_GÎÙ¸cBÄ_V”,òÄ j‹“ì¬ï‚õ½¬ï"5çOÍúPmã?f}©S¦È×+Ô\ï‚ë½)\ï"¡æÜ,ŠYáª×ҟmê:ñg7I:ો+M¨©ê4Ä(izÁ /ä›Â /jÎÏåTº×?&5ß5¹=—xqç\ÂË¢NHw¡6_ðÇ7œ?^$Ԝ_@dåª×2ã°ÈêÔ‚Pç™ ƒ¬j›òÇâ„×\ðÇ þøðNj|šsã(Nýz«c2_^–& †á>)Ðü‚^0À7€^d̜Ÿºß¯!ÿ+²,Eìɋs‰ÀqU–&ÞԽȟ–A^ðÇ þøFóNj”˜s YÌLýZê϶ï€9§8œ¢q ¬‘P™„’ç'dv_ðÇ þøðNjœ—s“›1̯!ƒ4eÞs×ç“ó’ÙD`¬P =~¯9&åú‚A^0È7„A69/çÆ ­«ÊòudEíRõIž‘³óǪI»u65@S È_ðÇ þøðNjœ–ó㏅}=!{š²<—:+’Lhk‹ ñ‚¾Ù ð"³åϜÙr.ž–ã!.‚¶/8ÞÈñ.²ZÎ fÌÕë‰òm] +¹ÝÔÅz.ö²(ßµ9†ÑôªÄTìñ‚=¾yìñ"§åü\*ÅkŠ’c²:É©×ç꽬GÅǃ|›Ä¹R•±÷ù‚?^ðÇ7…?^ä´ü™æȟƒ +zgLizâe^^àƒ]pÆ73^d³\HŽç.9&:uÒê‚5^°Æ7…5^ä¹\°ÆßA©¶&‰`,. +g]°Ç7Š=ޞLŽÆÓár4øv4™Ì~¼™Œò?ØççòQýñlîÏvGƒíád2~:>ï ¶æG‹gƒ‡í¦¿Ì¥?¶³KÇ<¶1¶«sorôtõ¬ûÓ»»?ßo7уKnp¸Üܚ ——§}©·}x„}Úî`Þq7ÏFV4®lçg#k\–å„ýÔyQ’Ù¦|Ñ¿šüÙ× Ççåï¥ð½÷±¦£Å‚×ÃÒ_8™rëq;ãíšíŒÛc¸¸›þ5<¼ògéÜ?öÌ浯¦ã½Ù~;´ùxú,'Ãòë1CMÆÀKßïúï_}àþ¨}{{ÒÎÒwðépÏvíüΜ“5‚~7æyÂwý·ä±ÌÙV +ÿ³) ~(kʂ‡¢*ªê÷8ë—úwd—wŸ\Îæ£ßFëÙbÒ_ÇOžÿ«Hxɼ˜wiöd±L$¶Ÿ§ËC¼ûäÒÁd|ðgãâjxå«¡ýOcòCnÖüpq7¼ÜÝ`ÿlwvGÑü!wÃïÂÿ+JÖÝãNÍ1š–á™ÙÚÅþ¹ôÕtÚnýA{Â÷Ç­¶;°¥Œùjƒ–Ò­ÿ÷ÖS<¿µõ²zÚ¿‰ª‹=ôí¡LÚz¶~?åÙem‘î&×¾9ûÉýŽÚþëf´9_~’óïÉNþkÓÔª»Uc å“ÕvJ]›ºt”iòÂԃç¯4›v°—²ƒÝi%œA+ÃN Š~ófÚÀþÊébŸ=›¾yaÑ>Ǔ,ÙÃùpºx2›œ‹–õvV;LÕÒ?Ûêèí¦Aa‘?/ö†“ѝq«É¤ºÇÁì—Ñgï-…ìýFÓ£ƒíÙáxÔë¤}Åþì`ü¿£Õ>…>y>[—£Ç÷ÛËg8 ýËß8œÏßîµÒ{‰°ŽoIÍu@‡ãé½Ùxº\û†ÑÓùHÇj²¬÷Ž{£ùÞHŸ4½—|³ö™Gýg’¿Ec~ ¢×ƒçSKlÏæÓÑ|7.wÆ¿þ@ —CÙëñ¬Ót»´=G‹—³^\aW؅Sö?gLž ÷g¿^¡Êü'3ùÈ?„ŽzÌݹ3Ÿü‰9ù挚ï0Iú;³@» x.͇{^ Ê/£yO’;Žçi›g³ùÿŠ»6\ÁûÃùs’|PÑ¥ÝÉÑ<yw'ӓ—ÆüçK³Ø›¤/Ý[Ì÷ÎȽÿϳò‡ãÅâh4¸7<ÄÇ]0ô †þš3ôfmÀÙ8þð_áì÷lîÛß’A?¾7]žê?“^D}¼ÑøGggð׶Æþ/›¶oß®ÝÎÎXü흿¶ÿùŸòÛÙ·ÿw{üQ~ ¿Þ¬=_îÈïÍÕ¿þÏÆÿû˜±ûÃå0½ žŠc›d¯hñÀ›+òÌ;cïÍG¿ìÌG'©d(­.œd¯(1AV0ÿ-¡éOp´.ýُVsq´þXŸã§óÑhú¾F@¿?¸;NŸŽÖ{ÏÑéø'8Š»ÿŽbñGÅÿr½zUé[£öÞNFËåH†soW^€.}¿ý;Om;?bé¾Yà{Sò[¹·—|Û¥¯Ÿ—£„N}¾øV« t㥉KÛ_~ûÅàþh?z$ù“08ý«éÿ•\0úcÿqûÅ°û›Iÿ¶59E£IþöåðéhÚ2ýó†¡ìC-C¾eû£–ôåGpg}ûQ“ ¾hìÆφµó=~Ô®!}ûQKû⣸a­:KÔ°f—ý†®ûj¶rh…קÍr·úæ–ÖóFƓƒqjC|Mø–®§û#›i«Þ‹7\ÒÌ׬JÛUî˜vø€ .X˜îZ¦;4î¦{î׶oøåa*óÞ ôÿzã¨ÒIªùþ–•vMëÌ£HÛB±0®ÛEUl‰©_ómqC~—3nhüeÝËñå_â{¾ýÈ%MD +ó_qSٞ­‹'ÀÄí6rQãf.;¦Y.g#wÑjå]Ÿ¹KWKFThêú»™`Óc„¯·½Mêü÷ÝVÅ,iãBtC'Wšè»p~.ÞÙü_Ï® '°ÌÒ¹u¾m)ÃÑöLÉö˜¢7ôBÛÇC/Bëh¦u,U2Õa,Uo¦s?–:{ÆR÷Æî‡!*™™Òy֐§í+]ͨmÕR—pž‘šÿMc†RùÖ*ßÞ¶2Ür6{ãT¹¶×¾ëÊßMªùà谕=̞,¥åàÑøéWà^qü³ÉÈ_Q2?æ¹c¿äÞѼ2Œú˜œ¡û´½t{éÎðéÑtx9yVþù>êèÇÁa×Ö³v¼Ãôüß{š^õrV=¯h7C*&lÔMûŸbMӦ߲jÖõš–u¿e‰>«5-«~K‡–ëZ®´\ÓÈõåÇ}LÑoiû˜¼ßÒ÷1¶ß2;îcÌJË☷»nE·æã§Ï–ÑšFbÚG§^<ª¾€R¹µíü½–t¹"ðDÀ1÷rOFהޑ«×T©Œ­Ÿ|#•kŸº·ÕIÐANîDçX¨~ë/ÿ8T œó2øVTN”„ÎS~L0Ïj\ç[k3žû~šUù_Þ}º +°ö;L&|ðâ`w6AWÿfêh ©=ùãþpk2›¡ä1á”-ù´­£ÝV«“<NÛ'Z¹zþ|1ø¡ÕºLÆ{£._öïj˜¼é„Që ïÌöŽZ)}§ÕÉ[úãkž… ¿Fº$ ß|yç0 ¬ÿs«ÿÿv0™¶ ®—Ëùx÷h© +}Û8+üQݜÓ[¢v{ÏƓýùhª­|b ÿ3þµ|q8Ò?_zwºxüËp¾ø°Õj}îVÜö`OøÆøÃ☆ˆ‹×v:šEúë?UÓÙtt–YšÌöž·ZîY¦É7}ÿµøÀÝñt¿°9ËG¶{æÁhù~Í>4n~ž›â?Ÿsò¤œm*Ör¦“q–•þ¯o„—g +ürv¶€¶¯Ç†Çwî-–³ƒ×€ýý®[ôƒÅ†JÜ¡í9<ûNý#ÎM; ×m<®£¼xòëk°¿ßN¾€°ú§YûÜڍº(ıŸýleðL ü»Èš gì©ß÷+@ÌÎôyÚòµøºÚnT¥=ýë~;ۉ}M¾êªsvÃ6•9õ»^œé»^¼&ß\ÉÇ~ÏîlÙ +wFO–wçãV¯=Óç­>ôÚÈd– ¸óÆë!T´wÝk1ŽƒÑr(qÿñ`šÿx0oï«ÉäL{.jMRˆqÙ¼Ý aƒ,ÆG“Z¥›04Η»³á|°7›hVߚªv_:îï÷_u0\<ÅáleHÃÉØïû.Lcÿp¼¡Dç£Âg“y÷…›·›GËÙàþp±Í}œGûª2¯óð%Þδ=œþ2\<èš]úþËÑþøè`p´˜MŽÔmÞGÀÙ¼mÌ ØªZ¡òèX9ËÑ´Á{óП"¸t.wÇNãÀ v»u¶°õñmmÜöÔ~磕éçØý6ŒÛ¯„Erם­.ý~9Z< 3ʽÍÏÉ/x>í=Ÿ-Oç³£Ãx=»îï-Û§¼àԉé>ÖF͘é{8lÏÜދvãýv‡ÿï™'û)CÎ8Ûqc“L·Äü—Ñàáè·åàæþx9ÜOÆKÅ¡¾²ö»º³î §O†OGƒ{³Ã0…a·&£Ñ>n‘G[ðÇe{>;ܜ†õ¿NrïŸÝK›þ«Ì꾏¶tø¾Û ÿ„ÚÇÓF2È{›÷•TÕM>¨ªJÇπ1²ºK÷&£yrvWœúÒ§¥´ëÖ¸ [gùàj]˜ºnʨ»û£ÉÃÙ}éIº¾7[Œñ•ü³ ½ggȬptÿÕ´nûqÝö0ÙàIàsîì«¿Œ =ØN†Ó½Qo¯>ß¼M¬]€a-¾~6Þ{vo>{2žŒ<înlj“¦7vGû+Mãӏ¤=‰“ñt4X¶ûÐ÷ÚƤãG»-»5›.÷q$“qHçI{„t¶Û|‘ÜkÚÝÛ¹…¦m—é8eÄ uO¨~Cå¼Ø¡ÿ<¢ËÁÑ/£‰gé¦ØÈ6²è~l‡sëh2ñÇLžÛ¿ž2”½Éø°=ì°¶üÖr›§íC‹S9ôöËh~'ˆÂv,ö^;€Ãè§-ƒzü٬傳ég±BŠ(­´ÞM&Û­”¶ Ìõ¤–Ñ]çê¦ö[ªß e+á'뻼5™ÍæwTÓ +ðÖöÊÖ÷›>~(÷ºíaK˜äºÖŸF¼÷Ô!D_V¸º:®_¶;>~À2Ɉ]}lëûX؛¿-;Aì„Æøº¤mUµwDm³ÂB×=úh8/žµû¾C„è8ëÊÀ:|{º?úíÖx¾ðÏðuQœíµ÷Z×*Pq^åÅF{³é~üæªy™7?œƯ=ûØ,‡éûùn\ûpnʳ¿'-Y³º¬Î¸fÜk­8–ཷ†{£óe>™oõ]/½¹?~Ø|¤?îâø“ðh<úµ“VXFèñ‡’ý§‡òØý‡¦[¨‹üŒkÞ}÷Ê¢ŸÄ‡øاÇH—kߏeùcù GÂxl^®ØÎ}¡p-ï:ñ¹«.[•×V©xìîå¸N˜Âõ°Ç<÷°Ó”W-´©©äÁhòÙpÙÞøwf{à DÔE,¸×ú6Š(ÜÞIÚƧ^½V*—ãËåXäïô%nò  ÎÀͳvlÊf"½ÓÿùÓɬ•P&‹D½‹žnxüì‡øcåß[Ž•,€Ø¦Ð^e7ï=Üí‹G±@e­VWåÀ‰˜×ìa$àv/“&ýw6Z¿×:ƒÜµŸg»­Þ7év©9¦_5œxq´CW¶:ž†žØáâùøp·=-Ï/Ÿ<¼y+Ï#|ÈüŒcô*­Ÿ™K«:`ÿQÿH<òƒÚ‹ü†Ïg»·§OfƒôœDÚ17ÀÚuëŒSÓY'BÆSŠáPÐVôQ¿ÊÛÖ·UX¿ŸëÇy"ë{8É¢kzl,ƋkDÅÛJT¼Äš"Í?õ “Ã龚WúöŽÄH"O‘lÐ*ž|Š¦„•§ÌÊ̞0«×Ÿ²øk¥ÝIŸ{úôJ'Ío:eÒþ¥çL;ä½ +8<œoH€Á g öÅ,[.üûMc M}\ËÄYwigô¤ýÈýÁî‹Áμåýó“-:ˆìÂÙº—ìõÇs|«d,릊­h‡;;[IÇ·Úåd¾qÐ>~âàæû³ùӍ“¿@ùÀ•ÈÒoFD»ÐÛ© 9iølu8Ùë›vVíM'ÎmÛhÙJLÁt»v¯>=x¾±ùr'4ÚÅí~Z£½ùìð„q?™.7ö'éê¬m´8Ú ß–¯{Ùbcr֎g±±ËÔѓÛLGO‡‘ô˜V­Ê¹d àI&fÖ«UŽÓk¸x6l/ÞQÄk×6ƒ­( æG¬6nöÛáFj4\7ím#¨N}Ûbv¸7;­Åâ¤`‹ý£“Yý g»}þ”£ÝŠí¬M÷ÎÆ,Ø|8Òz‹ÍNå×{1W¹ôÕƃÁ×£Ýöúlå¼ýÁ—|}÷Þ—¿Ø“Õös(&ٞ +ÓkÔ +3£N?JòPO꽕;G¼°R[ûÊˉ¿~(89ð”9Åsú@´Xgyèpó7™ž}\‡ûgï^Ö¯{dýÑk/›ñA+K·ÌãI`æØ[W/OݝÒz]y'ßÔÒ^œý§_¸³Ø”z•Ûo·Vªß-ÆO§±/wÝ6 òÿ®ºúOì“-ã}bÃábw¼<žÄ”ÐVÍ׸×^ü-Ÿ²œÆ' MƒÎ°+hÂcíq7élsxÚږOZV Ó:gt¿Ù¡:‘NAÚqN†‡gU´áIÒ/éѶ‰3.¹Öyº¢¥=ËCíò-ñÎY¨i¾Ú¶=òP.zRåúáC·ZãiíæQ&û©r ü´»ÃùâDöÄ öŒ%,äôÖ9Cãy*5ŸÖ<á å±ížÓùZw#?CãxäghžŒ|­–”|èÑb´3Û£™é¤Ó-RæáüÉlz" \×÷LÓ°e©=q¬‹<é 1ónE•u]Ó§gbl߄¯-WMWëŠKô4Q*ekÅP¹T_,Nx9qiî¼8ɵœ-Ÿ’`Úôí3¹.âÞø·ÑäÞhþdZ¾|ØDU¥–›Ïg»ƒ»‡XšÅ r¾ŠA`<}>Y,Ûµé\±þcoOŸe°½¬Øl§á¾kû ç£A+œ Ô1h? ]/¿>M‹á/˜‰át_³`åƒádo{ñ®ƒ¯ì²ýwÚًÙÑà°å¿ƒöœä øjéî)°ÇɋÞ´/ N[qÈ(m{£Á˜>°á`2|ØÚöËÚkExÈâhï†w{ºCõ¿ëFÞ6m÷L+bfOº×ƒ£és`¢mœí"n»Þ›£wÆ\Ç^œñÚnß³O5"'º9­;‰#ãyØ~W$г3N |5éæ ›±Ý$€Ɩû“&âÁr8ÝÎϨί™¾8ýìtHOžr^&½9?MÀxi^л±¢§Nº0nµWì×£]e`Ø Ãåèá³£ƒÝép<9ÑXàŸ +AØ'x3º¯Xüzl{é{»ûOHwIgŽñÍÎÇ«þztƛÌïÍùYZ‡H‹3ýþ)®ÄþÀOáüFyN¯é)ƒH.Ks¢4ÒI3Fú £á&ÞJŒPÇo]aN£†3yïêüÊG›w¼ûo|Àå~þ,o_S~øèǛӽ÷®|ôå‡×ªƒ>Wյœ|s¾wÛ\yþ ]îí|¾xÔÎ\õÞ¨ú:Ïö?o_¶‹l¾üèÒÕ÷G[“êށ|÷wÞ¹±}ûúÛ_ß|¿q€Yݹý}ùöÇÕöì_W®?Úÿþ»ûöì÷ãé;í'}\þým,Ë÷å×å?§˜ª·ž_.¯ê}´'3?¾ýåεáõwoýõÊws¼¦ÄþÅ^ؤ}M¶û?· þråã[×õ§ë_ßüBÚo¿ó'éÍ~ko·;ø›ìÊÇß|ßî|òô#íè돮¸ÿó?þÅÕ #nû»»åükÚV[Ÿ‡!üØ Á\úè>Z +ÒÜ_·vsº[aᓢü®üyoóáÎÏWvž\ûâß7‡Ã÷þ¶Uî~õÏæÞ;ß|µyw{ëÞΓãßø÷9xçé­í'7í~üSUÝߟu/¬üûà‹Í»wþþÅ­Ëû_Èìø¹–#€-°<Üøç•O ÿ-ŸôqYo|øpù?›?_­~\or£™ð‹ñÍü¯¾«í º»ʛßí¿óÔþtý“ìÖ7rîƒë?]¿µÓ¿ekÖü«¿^éäƋëC¶Ï'ÏGœ'|MürÿJËl>nv¶î|û|ÝxÙ4j÷é·Õ“öðÜ´™ý´øruû,ïݺ|oòá­÷½òñ§?4¬û´ö»öžÜº¹ãª­òêÝGä=æ³Gïó­;×~:üûÖÏËýƒ­ÉôÑlóá³oþÖöñŕÐÁáÍ÷gÿ°·Þ½Z}¿yÿɳ÷ÚÇ~|w«¼r癲ÎË;OÞû¬lÇ;{&,ñæ£o>ó½}Ã?>ÌoÝxúÑ7à÷?íìϾÞüꝽEÚîÝÍû¿ŸÔ?O®^'wëk0û<»¾õüÒáøÖõOÍ¥ˆÕwÿïÃxZÚ»%bÝ&Û=ºyé£ÝÝ<½¿bC_ZVOÛŽ¬4¨ºòá휖ï½í¶ÌÑäûÍ?}¾­m6ºqý³í¶ÉOZ~pçÝ-óÝÑãÍG‹î¯l žÖRnÌ÷>xW–,>¨×¾½þÉÝíiU}1|;û|ùýì‹K7Ûíoe_˜ýMùés`“~q雏[ÚðFL3O·ø^7ê“_\zºíŸü¹ýérsOÒÇý¤#éíðVÛî“ûíO?ïHm|¨¯ D«¸#¾æ`§ßG4üðÄçÏ÷wt82&ŒŽ½´ƒàkäKÙ%†uyëÐ´7~_ƒÇû³Ýëë:;mò5ß=þùòÿçî½»U¶õѯr3PQ1’s¢ ˜swŒóé/øvx{íÞçì_øëö«[XsÖ¬žgV¡J?¾ËÅùøwk~äì§!ûÚ7#|™t’—Ž࿍›ˆùsµþ¾¾ÿ«‹ñ•ø-¦žb~Ú+VõÇýþð§©þ°È×}¿ß~9ÍÇ}ÑÿªÄ¿›Í²,Ÿ9|½ú9䏫¼M|ã³6ÿÆ=þߘ¤Äïóúí/ÿj¯Ï…˜¿Ùëkºcü´È·Y'7ÿÕ®ù6ë6üm´N<þЁ¿ÆøSoÑú5aø‡Ôd¼/©îð+n~/ٟKûe¾dȯûccü-d~Dfò±$¾»êGÖáÇÚ$7ü¯šûtšÕݯÉ}ó´_«ÿûC_ñ¸ÿo9ãgY~LøËhŸ˜N¤[ÊÏWŸ)%ùšk~ú'&,á¦-\h,¿6c°©¯(~‰«çV¤ç’×¥S¥jRÖ uÔíüD•LŒgÈ#æÖv¼BŒZ﹯Úö c /õßӝïXt>t'ak2žªä¶R}aB•+N½?ø`v¾€Žwo}B +ø>%"\ãú…T0#xD ¸=agøO1à‡Zteèö+súúÏ«µtя‰ª}£–e³F´ÊõÊ7j і\—(ö7äú(þþ¶Ít6í(ßØÝwdóׄ£'úºù‚mÿ2€ÛŒ?V¹Ö$}Š'Š%*ÆòÈäÿ„¼üÌå þÉËÀ\~ÂÁ_ŽZI&÷E¬ÿ`ÈÁñ7ƒéœªöÇ:XÙãØäòÄáþ6Õï¡þG<>|û'ãb§¤@´ò±„bDh˜_"´ììõÊÏÀí¿˜ê;Uùxÿ°%TIîÐ^ü¶\B<ãýXü¶í“hâŠ%Än‡é—þÖäßqŽ/“[­Ò¯8`ˆSkë¸A,æ7=øWU× +ɳë8δ~ÒþXƯÊ/斎Pì5å?Çÿ ‡éç$7N|{‡—úH©cV +ýAgÍÒ:¶×±ù?4ê“#0ÞMSÝXã0üé³j<áj’ˆ£ÆDEÝ4J7á q¬R¿/üòy¨»:Ÿ d©ø?˜t‹ ûÔ´úk”6ÌJM]ÞIxÖ³è¹óå_åLÍﴗ"Oh*¦Ö‹ÞYþ¡êÛËâšlØ %ÿyÁ94~˜ùšƒÚÇw¤Bâ­zbžÊúñÑ?ÃóÒÿo‹ŽÅüòL{îþ-WÿK«ƒ­ü£4ÿáiÿê7)jøuë¯Hþc´ÿ,Œë-<÷)‰ŸžÍÿɍß}Êÿ>Œ¿i’„q̯›ñþ¹o}Ú?Ô}ü!ÿƒnÀ·qµT\̆qfÆÂésKî¤ä$ =õ… ¼úZˁ ¯ÈÕ-ÿtÁB:¦ó#ˆ³ÀWqª\SÃêWÃà«Ûæ îzž[ÿ0«ÖˆSU‡ãAË‹Äb¾dÊVgF…A֏Õߦ°;~•°Ý/ï‹sp+“rI ÚRQm²ÿÙ|ò·ÿ¡ø?J¸¸MTۑnƟõüëÖv¿A­©@‰Â±ô’ܳ)RKšâͪũÐé|áƒòÖY9’;ï}±Ý*®•Ô-®› ÄM–™µ‰#¼z|0_fP#9_,%DÿÜçê¾ñ7õ;f.cÐ!óÈMl2âÔɔI¾P,| Ïï,ðÛì1ö 4ÝÛdŒÝ_¤6㲪?)°ÔÚ|¯wÉzÝB"ÀìÌëõK´/ó6Õz‰tB + ĬVþ¸–OAœÏôŒñ«ä~úºÒa³éîóšc½2N“[úÛäþ¸c1½Ù՟þwwÙ¥¶¼ì)ÿ¸¥·ŠÇOß­+o{{ª|ÀqšD`Ü@ès~•òÉ}‡_Éæ_| xƵEÚ}Á›QËeÆòØýÃA~ì}k“øžr]ÞPiSƒq¥K X¸}‡å?të°G}'ÃÛ³•LnÐyš¬_¹˜=<òfŒ¿î”Rb´?]æŠú¼þV?VkÄ}s•á Õø›— Gœ2ñ6ªðdHn´gR¤¿²Æ}Y€ã³-=ƶ:›ÀŽÖŽøßoÁKÌ6¹Ý'_ßԉó2ÆºÎz‹unðÓÊü‹ª^,}Ö+ö%u÷ŸÎõ ÿý9JŸ9IgpØfؤÞÜ'=ï×j5â¬I=“¿ûÈ!‡Ùóýmða‹“U}UÁºòáø ¹Ç™­4}ÿغù·w¼žlEç¸þ±ùSm·æ?ͽn~·«¼I6x>ÉrDSýb&kÅé݉³2DþÕi´t\Ύ“€êÁ…8é5³1†3käÆ|Ä|ڜ¿…"÷œÍ™,°¼ÈÍõQý‹ß¢qÝ“Í!—oFßaô“ß$ˆ¡´o¿ q{¨Žw$3Ì®c܁¶¾:·K{òü5n.p+'! Ó$[¸äº$Dâ þ房¶‰¥B±ƒ'èïD™¤ÎdVƒ‚Vô#×ö@·ÿëþ¼‹OµVœ0['¬ín)¼Ã<_ÉFz….ð{ [çgoÝ͝ãYëÅ÷ó^~2ôh¹þ3u¾ñNtÛ~«Ÿô;Ñl ¯Poó^?þ™ˆ¯%²öí¿ö˜?ž“t9î0jÄ`Ü il;»ñ6Wÿ³·>Ìøc‰„%H±9õ¤ô%Ü(cñÚlK—?Ä||”Z¾Ó!Þ©TÓ TlýÃÉâútYÍãjÕ²­™ÝiÆìxç¯Ò Kc}­‚ÐOÿÚwþçÇœF/r֛Y1"mk T/ߗqҟã2¼¹áú qþHÉ {Ý4)ðØûâö·ìúó€:i›á;ùŠÈøÖñ€Ü"­t¿üžî[Ã{‰ŠiRéN÷éå§ü•«~¥©ŸééGN{þàj`í4ù9Œk2·ÕµŸ@õ[&¨üîˆvW«¥Ù­/J*qªÀ&ãNÜK¼6/âwÿïë9ˆÞô|öÞ%'8òòT¹”Íæg1¾/8ôùí¥¯ÙÔ*N¼úV¿DÛç¯<÷ǐAýü©ŠßÎmü1®ãÚàÛÐËÆ)N{ÿ¾úÃÓÜ´Úæoó¡Gì Ɠ?;´9Kϝ¸fÝ 'õåÛ·FêÇ^D¾o’¥}mÙ/{wÊ\2^nŸÌ浿pÒ¿³þÏúý¨cK\Ødßuë%–¨ÿ¡“–ŽkÅÚï-œë!¡¸5ꐥ)ôº§wgŹ§âýåþyËRüÏd#ÒÓ;8]|õ®Ô²UD©XÜ·/œ~û?ÛØZŒ$:{ufBU¼Î–h:Ê7Øå-n’ÏRë.,Fƒ˜AböՇÿøk”Ò ‰›¨{³½|s·_}è\ƒÎÿnŒ†6Þa« +ɝÆÎ?`Tצ]ˆN²6ê¤|ýf‚?:è­_9bŸpT„ŠL +ù&ÿ=IÀ»útº6S&è§ýòaÒ hõg¦K-æ‡2~¥Tz^˜Õ“ ˜’|jýVðçàaÐãVou]+Šg³¦`ÇØá~ä JÄ þ+Ʀßûü­.0ûN-!hRˆÆÑ–ãX2ŸÔrÈÆCY¹[µ(?ƒn„IǺ±IO¿àænùJ´L~ñüç#f>ÈFþüôäë|Qÿ:¤—<°{ýºïŸ_yô}ˆoDž¤ ·~Ir|ãïGò¾lúþrè7yÆåäÝ—ù.>üöõEşï‚ûç!ÂyNnwýÙý¯/kø~BþRº"¯t¶šò†ÃU¾å°OA›Ð‘b¬í°T»”°®‚½w—Pþëó‘ÿŠÿ¤RÅ9™J•òéTªÀ§ã!]úñ'ù•z0¦­ÛSüx&?RaƒãWÙArUdlÍ|´Ie÷ÉÿAG!šÆ/r…ø¿ð•¼ þ|;‹_­¿Þ¶:Iÿ8UVâ·He¼¯bþé×Ûø³æÎÿ¼ý¤ ċÛ½ùøãàø£ÛGÍ¿žÔ«<Üú¸»8Ë0œ»w³Š‡ù6ÇÿŠÿlð_qðÞvqdBé‰ÎO۝*‰’–˜;¾­× NÎbGn>ÆFŠ%ç©Øù «¡dÕ?Ñÿ•Fü±ëDŽßþMìÔï—2±¾y&ÝÇü4€ÓÜ3Óy L¶”Û9ÙSÚÉæœv·ž' y»PM+…ƒžZuKi–ºôí扷rŸ)kD®]éÍKÈÃBuîò5®ñt>§WüUº¶'!l¿S¥úpÖ9yvi,+ÏN“.Rç•rÑèfË¢a¦Ý— +Ó0Ë>;á@PÎÉÝjvãw÷DcÙS¶þ±ßêT_ýûÌ)Üj©‹§no”¦È(8²%Œl5žxQ¼lðåÒt öÞäƕӬ5ފÏ#)@&FUçÕµ…ÝÍSo©h€YóãËvY—+鵈[¤zOôñPd<¡Á‚'#šØí=(ñú6[’ªAYºškyíX¸BÞg5“ºâª[öZë~GµÃtn²­…(Ó7»áªkžC´„AË·‹àëhû7ç žrçÔËÐ._Œ/vÞdŠd&3Ӟ‰ˆõ¹eOsËÂzê±ó׬]%«³ý>? g-‡Ù„n¾Î‘Í¡8ßYFwA÷Z\¼/Vdg+β~BìXÌrµÛ+\¥ŒÕe”µ²°›r£2ÚÌÄSc‹š<°=©ÍŽfYcŸnî{ý\˪Áw˜ àØnMÇõDROÃeyz:1lp&yÌ=?.uà"aÒ ¹æ‘Ýâj©ÆýV¦Ò7 §ïñ:º]}ÔQáýp;aó™¸\ ótmÙӁb +y‡ºüʨ‡Ê!Û%‘Í\o9^Ýïò "8ùy'èF½ŒÅžÔI(ÚoúTêÜo÷ÒåW=E¬r- +Gåu¹V®PÓðQÍñ̦:å{óÚ`ÏjO£¨Æþ°!a¤möà#&·êâjÒiTk¬óȨI½!RŒäD^ ¿ +J o¯æm`á¼Û¾6kwr,HA헲è¢:tï„<ì™d8ë·Õ4пXzm ®ƒaý±—†‡¡ŒÄp|Çj \Å6VÇÙAE¶Ÿ S"œôÛclقÉÔ I用N´¹PÏ\ÒòåÉ0Ur0Ñuj²D_¨p)«1á¬ó摂1å÷5زïˆ9mw=έHmœI´¥Ëlþ•Ày%ûZ¥÷íµÕvJ–ÔÈ­4v(õÜCuw{¢ŒÉƾQ_›L³³²j°¼"Ùí}T·O2pºº`µqsçÌô0Ðè{o(Nìv˜lÁúí¶qñÏ~x›*J-3ƒÍ°>Ûu&.NVoûJ¸%朷'ÏEEÙôëU5ˆ8ą–åuÝ[®µ ´â˜I°® t½‘©ó†ßñʶֲê۝c1; º©{¸¶öûÂexVgëXEç»ãZc7¬ÎÎUa)žwؼˆ.r¸Bó*}Ýï÷M‚xì^Lì7vé1Î8ýÇëv’YH#©å€2W-<êûeÆCçëlÿ×²ÏõÉYÃt#ßJ{©ü!ôô7ƒÒň›e,/¦xÝ$”ÛËl®|ÊEFE `µ¤Tìj°=VkôäÖÅRr¦Ò: †X²¯ä·So¨4Å áHH»Ù.×Íãa9€[àÕº¶8kãs•ïļ©Ûq‹ûŠgôڛåºj¸Ï÷ê|½ÜÛ§ÉZŸw§Éfÿ “µÁ’µ˜!%CÆ(?Ý,â$Ê\1ìdñôŠ©âÞüÞ!z3'ꁛ½†B¶²šIžü½MÉ©«A×J{‰^—f$C©›ÓóEvZqÎ\_Ì»±î¾ q^[y9½‰°͎HÙì^Êí±äQهÜÙìEùÜpsŠˆŽZnâMu¾ëm5Lí³Ú›çªºn/F«7SvLIj;V­m…Ö†n%çrm®ÒBœ2nLœuµÛp9¼xUñ<óvïЙ(¥÷ÌG"óäß:4õ´­>ú”à–ì +£^¨äÔ¼ÛÝ Ànr‹(ë7#Ï=–M¾ç,8َŬ&ûæjM,§õM = +›MVu·bç4ÙÁσ±;ä`¯‚ýÓ¡1š4¹×? +r­z[µÙ)Ð[sO"oç[y´ºhå†q…ŠÁýUÇÛS·Rôb1÷vôîçL¾þ˜éö#ìåg‘/&'§¥+)öǝ,ÔÕ!CNóÙlFª¨Y‡¼/sHcrËmۗ[~‡Mþåµô‚Ú׬"ܧèâZÌïKcøž¥÷(›u¸’*׀æ»ÅÓR£kÛÆ%ך"70­ ºw[¹|ø©°…Ú*7p:5z_ê,%Ê@‰Y¡ØM-=£k=û…’9k‰{¦úL´$9*¿Lò84ìX¦2Í÷˜Æ4¤k6N¡`/Âa0X.¤–éîdßíù†‡z ©¼â¢fÃ_D·{\J]/®;Øô˜]; o½ò㍆Ì;۞µw¹a%á:» Š{í&/xzQ86 +÷Õ);¬ÓùÎéçÅí^œþ¾Jå´w#ºíÛYàËGÎ]çÇ\~<0Mä˗YŸÏS9[Sçæ9NâSÃñCOç­rÆ–ø\Å 1‘ÆÜdUªð]*«‚ó™åkáÉ9–p9tG3LjE]3¼¨å=K6.vS]€óJè˜Ë ÀEp_ºÅíªõBK&í¬Ð2¨:OÕ±Q7j4¥hà\ýƒ‹™üì)‹AÓæÚט“TÇx_Œˆ£Äp´P;˜T(8‹c)5^öÄ¥žì)ªûêhp6kÆc/°x©sHh¡ùi†q¹½Xc›Ì¨¡œ6ï×·æ<²:˜Œ-ón^­­nÄîzùœe²–²ŸÌ'ùl=P,dƒî «¶h´ÆБ}öÞÒ(×8êk!è\g‚¬Š%j˜p ùöî,ªÁ®ä“{­‚°t~ÙtK›Vèì8ÏÚcfØ·Q7ºdo¥§ÀƒËIOå{!>çƕßU¥ù’Ø“,r°¦áÊ¿ §hzB±·Ÿ¸€¢Fè’º«‡¬3ØZà:²×ó£^ °ME©. [yåg[ eïQf_õX°Êáù¯Y3³œ³}Îè[¼š;‘X·?-7ÃÜ~i=·Å¤ÁÏ:À¥{ÙNoän‡NglZµ¬°ìEÛè Q0›g;eù5Ùög׳Tgñι5Ì>ú§IõÎÝY¿çõòws~–we£(e£Áv}›“&GlåºH8¥Š­÷ªIYãÑ9+\”#M+H0à†»-X>©7—^}ÃM€\Fl¬1ù´¤o‘”±†ØduvÅæ¶Xê !´Zy¹uF¶ggÂø°Vv¦:JŠ”¬œ@ŽîLª% +¨XŸcÊê +?)e¾îñ‚µ.bVÈs†<Ì"e¡Õ/jÔ<ö ©ËÌ*BV=—›i-%ŠÚ^½#hGoZfá £ÑÓÛëk×]69b*€ƒZE¢2© +.Ê*þ}Gò¤[ìò;*Íç…ñ<+™*œ^f·¼­¥Ýª¢M¡€(+s Vj†g!~NÁ *uGNš ¡oú°Ý  +BrHF¹íSþy÷f‡Ày¨~·Í4…ò½öžf‚ÍÒ¹µ)ïß]Xt·Ù|ÇfˆkòÙïØHÑUíæóô¦²Ém‹ÓžœŸH®ÐñÕÔ²¸”ÖÓ{×ùv’^³Àé'¯>x¿øñX̒äÈ/Ù)»¼âÛ ÖP4NK£À³ânxHm,0ZdH‹ßw Ƚ%;¨¬¹+O0%æç5©å;_ «ÞÕ\œb´Wb1|味s£@MK‹÷2+dæµ ’² +´¼ÏÏ·@Đ¢û0̆ƛ¯n˜áøÕ̜ýROnðYò`Ö-XÛÙ¼‰ë‚³Úo‡—Ù=ö +õîâÞ{rN•ì1F«òpÙz—JìiI¼!ӞàïTi˜”?ϵœ´Aï|±s¯8¨ÏÜ mâËÜû’Ó‰]$(<íIš$fÆÈ:]ã)ŽI¬šd:ôÊKüyV>K +š‘7ÏQ4RÜê •'OIö¥·“;bZ“Ü¥©ðZ[C¤V°‡Åkùmu׬´eO|‰JÚõ²›:ŠÝe±*?%¤†•[AOy$§I;_œk™~©ˆyá¤ôhr~&ÈG¼zɲËÂFíÉÀœ ÄÅD6ùZ}³ûM®HyÒíϧšq `Zªî±%·\2¸¶­5l‘ ^f·Ù>&JÎÚbq—ôŽä%`äeùVƒó¶ƒ»+z•(ÿ¨+¶ý²Øç`#–Êá§ç:vŒÀ¤D W9Áà´ÒÕ¶/m.VWÃùºx̬×GKҚಠ“¶¢KèEgû-n+7‹ƒ^ó¹íWŽ%±¬®vèâ†fŸx„…Ë ™s܉‘ër‹@f:ÓÁº bReUÔFÛ>OîˆÛûÚ®€3ð¼é,ï•ä¨œ°HãKh%Ѭ¹‘õ…0?×Ut+Wæ 2‘´cûâ”Td>Z"’2cCàÒóŸv×~ÛAéÉdëeæ%ȯú0ãØǑhÖ¤›v¯ð´O >©SÛ@®FK^¾fÒUV¤55õ Ìov·E ùbœ(¨iinГU¥ßym¢Þ»¤ó~ÒÎí6k—Šc§¨+n–±.’›cO)U€äYƒŽµœ\xëʤdª;=fªi7#”f&¯3n¶ìËۗ²+© Ë˝ٽ ÕGtZ§æ–v…º(–䁌 ¾U›4ՕØ杪<6f« ;˜jI—CCcØoڗÔZíñ H™³šLßRk_~È*ëÔzÑÉéHz—ót«‚`…Â5@ooíÒ|­&ËNgnËPm—Ž3Iª‡zÎëÜä‹0ۏˆn!y~J¥_$"]ÇÛg­G=e'çÒì¼îÎÃBÖåe¤ªÇ/׸<õµnñO;Á%­’€!ìhI†ÙqÔÖ{÷¶“D’̐¼2$쁠é(”°µIùL'µz¶ªÜx(-^5yåÀÙåY6Ùçsx™×d3"NiIï¼ ÕÓCŒ\´;KM´Þ›C¦BTc¯š‹Dërô%Ú[)Ŧ6“FËÅRrKº{à«Ýš˜-›:Í" ™Ml4{õB_mûrÈq/;™Ón,ȸñ˜Lr¦ F$x=©Ë™Æd½!®4}·E¬¶sœ×í —Y ëw˱z» ͳtU˜¤ý¤Ÿf²9+SÌÇÊTô)8\\åì•V÷\ó€nÇ£éŽ'ƒÈ«o#W l£qyØžð4ÁU)ˆ ]•´U~ªd:ù«1V‹}ÝƂýdŸ¬Ožd£>JMß­&Ô ]ÜjJ­˜KØHx@e@æ`c_·±&ÙW¬I)ã‡ñ +JwMt ?]k{‰+~“u=ԬͳŒ¶Ó…ð¨ גj¸ïOÜh5Z)59ãÉ AÜx¸Uß{ÏH\±cxµ´BŒ¹;©Üê5H-œ£ñ”ö%“º}høKt-mŒa(öcM€U¬I¾îÓኒ`lzROÎI¹("ˆ Hœìn[|–Ù´ö}·.P 2z%ÿX ÆVªP”µ ÉëÑ°”2ãÏôq…mr)q²PT!vã}º๭»îäfm~ TŠ>kÍý”‘¹j¬LzÀ—óüœ¦!˜ßì"‹Ù¼ÀñôfD†Š9t@ڋÞݼ§Y„­Ý(Åî:{4«]×e7»uZµâÉE¾Ñm8sښ±–mä&ùjþêsúË&÷×MObMÉٓÀ7ÖŸ©`m?óNgülUFÓh¸†:8K$M6éC7¡¸ö‹ä.V?·}æF÷Ë@ŠR[^z2§‹à¥7sl x¼p"匟ŽỲSœv ¸;f§¦}²³>hÈ¥ˆ-UÉþ„{ê—X““kÒn,C`žœ§W71ËÝe¼î¡Û?ó$Äé¬GOÑ$À¯MsÂ!4õNh‰¦Ö¸Ì—*놄Bò +):àØXй°ŠôN×óÞÌ«½ð¶b¦Ðuo #˜èòZ‘0HdÞöºå\.VæçÛcë´Ìxچd¸$'9¬Å Ÿ4É$|ý€|eôÎ÷§ H¯ +^z Ô3©ƒŸkë†.ÑTæ.íNòô±†çÙù|• +4|3õAå|¯¦O^”Úòµf()V¼I+ÄÀ~”RXwÜÑ}ÒN4ñMƑHezzËiú9­ œŽûkî±ÒÆp#;¹pÓä 9ü>.iõE5B·ÇAëLg½Î‰£‡J|U ä3KÛèµçÝ<5Å÷˛P¦ÈM)S ÚVíY˜Xy¥×>\n¬ñõ¨æLôkrIŚ IK5*]Yˆöï°Ò‰ J×ý¤ªc¥U7Ï # z‰/vÍÙÙ­8ëŠ6Êb!Š00“’Í$aXæ1Ÿ\uœðÚ9Òø¥c\}F…ÓôæÙiϋL"Æéqª›‘ˆVÎúQU³Š)Ñi9)Q¦É—¯ÕkÍ»ý-v},Øbgl³;iÑtVfûÉ"ÜŠ+Ž;†{t"V5O>GT_Ý*ûÄ,Ïï' †¾´Æm@ˆ#Àd³â*¬¹+E(uª[VΉG¥Ÿ›fù™œöÙSvD ¹kcÃsM³Âu/E¿‰ãO¢b™±péºiÎ(Xž§ô1óý‰½? EInÉ;¬5zÒt'¢»Ñl>žÍE±±®gÈU‹xÎH¯£”!ë4”²Þ@«œXˆYMQ&£ìHáý҉mƒáv0¿æh¹p¢dvʍj…¶`&‡Ëĸš¯é[s=ˆaÉIJ$ݘî†)YG%CÙ&Ç0ó5RÇÉ6§Þ[‰EÈy±Y=¥9xYl¿•ž²Í¬<±¯È>–œÁ¬š½¬)§˜ŽßHÂS2šÈÆd§Ä˜YVsô Ø¯¾´>¦Ù„·ó²)œdUY´¸©–W½Az7¥W£:}Àzg«ÎnpA­çSÃªhñƒƒÊìp[o9ncÀ|NNK.3,w¾£TÔzû-ÛÒjÊú°1›æ$}yp;ñ g§Þ´ý0ôqwé›k«gãwSeöªHçÓ2r–ëÞ9C£ã2¹\L ÄRÁúmô)Ò©ªN¯3ISȐí]'‚Úumpz7ê֝²™ª/2äŽä÷&`ŒÌe‹B¯1Ñ|Îx䘅ZÊ +™u,M˜u7l?1ƒöï}zL¬ÌÖ þ¹}'… _ø¬Êeþ¥Çɤ¹º|¤©~րÛFxM‘<áÌϼ2xBdë²"ø†Ÿ7y©gÞëÏwKäaià +d†ïÄ£Êr·öàÉ=žØËvU" B҇æ©2üH®ˆZ&Wàá¥QéùkDÁà{מ“Ž$hÌ£Á㻶¨¥›­Ú¯¹gèê«2~Rã +s§GT Zޑ;ÓçîM6¬ím!qÞ,õàё;ߊeñjiŽMpQ·ëz¶8ٝ¦Br6S¿ó;IŸiÈ}r®Ï_{9P5ý8Ð¸åˆœÆ Î¶$ÆI£œG?ÊóöÆ ŒÚíÁI—C»KǦyuCŽ˜¡8±>‚¾.ùã…FÞzöJKyϹgôµ J8]d‹:7*øK÷ÈÃk¯WÄA®Î¿ÊüÌìáÌ^k|ÌÁûŪO9—}ŠÐ­ìŠË+”wd¶â1ñÞKI2éƒÙÓY-˜–’VØêÇFï¬4ñ,c'|UzÕ،S·Eã’f +\~e;¬Á<|)¯s×åuÕ²y¢Ü—${ö]{÷ø¼Ò8ˆþ®³§KyÆ]·°+¢# Z…ŽÆݳ¥XTµZf;÷Ê|Kl»’VµY¥ô¥æøóº¥Ñ‘âõxRó BDâÅy¶—à!¬$~‰–ÕļK6¹]fŽ¬eò.!®+ÖÎORQ‘åH§R“-Éù¡<€š¨0¹Ž^WWK»„·W Z›Lfè fbwˆëâ­!—¦­4›5F9k`­*¯‹ç½Æèç´`ao#}?¯´Ð@)âbË÷Sð6š}t"üp»O.9ouö·…4ׄàÜóYf|äQýћͅFSä:Ì(hµû,:o­oŠÕk‰2ºùêãv÷<ñü¢"Ëhõ°gù¹-4ƒ£::ô؄{tò!üé¢,k–\¨éúyÍñ‡÷Z¸ûºÌà™'¼E5§Gêæ—+a[èr=ú”œã´øËølur·:oM5žâ§YúÌêPxßÉ·ˆâ³Ð/ z ŝ·­ÄÇ¥ ¹Àv=moÓÿðk½·p^exç Fµ|½[:ìðÒ¾*‡£ÉxDGì#£†OûdTa·Å”Ö)]äՒº§£\‹”,¬§É1¸öx½Øb¿p•‹é© TRúŒËvR‘–¹TËSn~©ß”Y%pE¢Áž8³Ð¾ÈV: M|æqöNxK›f¾YU¬ +έí´´>_üã(¾øâ·Él”wõé¼Sˆ9d§Y—W•N›ê½Î0i7)iÿ˜³­]%ã8'&LgÞJﮇŒP¹ôeµÄ!¹G…ë ¬Èų0*'¹s9ҋ¼ ¯ã>I‘~g¤¦©¢ÕܣܑRé» ¾0T›m/ÈÛè¥Þ;ï5E-„&K§’\߃ÒFo5%#¨Ô߶3­Þ#ÈÈ'YÑŋ°’Óv¦ÝZv¦ìü%Ÿ õy{Y8œEeµpðO›ÊMßÛHg>äüìkô†™ŠËímRñƒ` :°± ãÏã±ë-ÓÌBIY§¶VZÊU'ۗ:ÒvÇzdAT9Óêl“>´x7±reXÇH G5Q€B+ÍÝ´P.¼.ŠR‡NŽðE_(j¹Õ£ÝT& ÷œ+ዖ£·ÖR'Ïâqzs+I.áx҅!Ï㑧8½À+ÄnÏ]lªK5=²{!WšK¦^^æ®0‡é©ÿöõ9¡Ãìkz†™¢5ˆ’}ÏÞeRŒmӖšzºÅ2ހêlµ~X+DœA'%ôPåX®.†:’WzûÁu9§ é™·MŒ §×]’yN/cñê{Î1'bªx!³LáùŽÉ«#,c.ey_=@''–iw|“æ'sš´.µ,hgâ¨Wnæ5Nᗌç›%•O h¼-.$Íaß¡R&êËÆL.¿U£ öeE-ÖRís¦Ç÷G~™½£4‘¦ÒXÒ· ú`Zæy+&GF¾,ºÒ» `M²dfp[€Ä`ÜÕªo|*µzøÂe;—®o“ݪv¸ ¦H]jî|ºÁTÈÊV°Cæø´Ñžó÷5—jPá79‡—¡ü ”BšÍäk(ø®tt-ô…o÷fˆ, ՓѺЗ0GN +QVFyfÓmÜoW7Ï¡Ü@3;°Þð_Z¦Tk‹WÀá­`›Ó£²êØnê )²ð¦§Ë÷4†ƒ@&3õ&Só +}V`ŠõJ š0Óik®÷ÚùVÒ`‘¸Î@Žp¿ŸÔ6ˆH\¶ VÝ3T<˜}Ëmԏ¯yg‹úg®ÜšÝ´¹7Ù-åPã°B*r¹™¦¬Fªs.¯³m½ýzÈ!pz}úhì¼ýcx”7ÿH¥H={mgàhðxó»ìÂÖÔãøó [ėO]Î>4:w%8B¾\x5Sï)Ò)ñ´V€¯tÓc¹ácqRȆZåˆ7Š8Nšârˆ·%a¡Ëæ¬wKiÞ-fÚ-ò€™wÔBu$½>šÒaìw-uÓ¤ÓƅiÛÊØ:¨wì|NÁg“X™VÞ&lo§´“·A‡ÍŠY.5²’ªúÚÂ*župµõ;ée­ªÊ½¡Æ2–Å:ˆ˜ŠvÚ0R†WëfWÚªN—MV¾M€œs'0+?d¶¦ŸŸil˜‚œÑâD+i†cZ®‹Û¢2Mȏ5ÙåbMêŽ]Ú)´|=gënÌttc ·¤ñ[x“}mºùvèUfV¡v;¨Ý=/ Åû8ôÄÀãmXÁ ǵ‡¹Ç…¦¡þw$I÷ªÑn°\¿‹.(Ÿ\õ}8å=Ûæc–Ôʍ„cMÖ ?}ÈڟÄf¥‡Òà Qtyh›ì­á‹¥Ñ¥Ã#°· ­€lÅâ'L %—&Ùp¹«BͶ»¤$zšêۃ;ì~ú$=þx¸ÓïVûÈÎìmÊ>w'Þ»åØ¥!4ÍÙmGÔú£1ž„F™Ö–o%f¹ÄÊìuMq•‚U¡†…¦³ydœÙ +|ظ -b‰¥‘µ³áyí0ñ ¿ÿ˜ærJãW$éˆó;*¨ž!rQ%î¡wÆicŸCO«<O»¥î°žÕ&¢T»£q±w¶µôL‰½ «üý”˜¥k²¦½÷è, r9g«95fÀ3öõ&_Kó²¹mšD¨¾ ï"Í(ì/IYËm|¼&9 …Šddj—Ú0ƒm¦îxu¹ÒM¬Âk««‘²V]”ï¡Ç}J•‡fhvùR=›±Ïµ/ÚÈ{bXÙȏ5‰XϪTÒB³ÁVu¦%…À>ÞÒ.6g`ÚšHÖ¤`GÐL¥¢÷·ØM׿–[ETξpD„6¬¼ž÷RçgàÁõ”N­Ö¨íÔ+°E:Z/÷FóJ¶gF£¯ØÕ(è'F3˜þ*§[…c9Vf~L:·58O®B¦P†'ʽUµ­ºˆbÊ\»¥U”2K¡ÐGÀiûb›[+¯w¥½˜[Ñ˕œF\^­Po Ùܹæ .cM¦X¬Iÿ==ï¦EF\”Švr`ƛZ™ÊÀÎêCóXYÎíÕ(íÔ§óLòL¨YZnÇføª½2ËMˆþ‘¢½ÓÅ€sn +~õ¶7ªw]PQ875ÐñNO©Úö|ä‹ßeþVši—N€šlm—¤}ʗ÷VÔK璃cd³†+4 ³Õà°¥®Ýý¡ ÐhHûÑ©.A0U?ÐÁ›ºOà뤋G²ÏZ/-T¼'ÇzcuÍâ,=˜#­ms䎅­.dz¬Ö3Èb“é°Ížœt &Eò%£6¸f™Uè¾ÔZ’Xœ{¢Lwaç!—l»k´nn<«ìàPëé¤4?¯‘Ž4ô Õ *ÿ8Յò•#X évH>Õ@ð…ÆHºc’¹Î§­És£cȔC“½5ãtA7EÃReMÔþlX±ûóµ˜(§¸ÃUžÃƒÂ,1Ó³[ižS9&LÝ(·¹Ûä˜?z°Àß Áº´6EâPv²A ¾ VÑì åÍ8i©ÓhI½ûí13LÜԚ^YZÞr5æ€Ò¦Dœy÷—%‹‰ÕÖ \̽˜¨“ÙËæÚ,´7‡' Ñý4Í0}o9¬jN./ÏLþ2O›“P9pG$'º¯ÏCTvBž8¶I#,Ÿ + ·›JsR ï³BCûéPK]ÈîÒh»Só­fu!’™¦@ßæϬ¨(´&Dæ•ÑÛMŸˆüŒÐš±*[VûZ~ÀI†æW(SÂÒã"hð‚ÔZ¿ÒõÆI7üTw!‡LB§‹ ’­õȓŒù€`”­Ñª¿§ùŠhé—)3¯v‰‰†Ó:À>%LŽÌDB¼ÎŠ…]_°÷äà˜3£=Uş8}£«d/hñWùþòE†{쐜V,©$l›äÁ·:‹¦GìËÿGÕy®+ +lÝúZD ˆŠ +’sÎɜsæþtïÞû;?W?káÛe1kÌY£fµš=Þ^×ëÎZ¿J^Óè £è¢°ª5Ù÷Wp SícO´~a2/t‰ÕõF:ìôµfô„å ]و—‹b©ñSSp•GüÄ}G|Ⴘ™®Æ ®;ïçO…B«\®?ç[ÝÕޜ²ÅÐ¥7.gkg)òÈè ;µ–šrŽŸèÁá¯zɼ‹G5p|b{ìñ“÷ +3ˆÂD 8JÙñv¸póÓrw}P_ÝǍ§†„¯Pûã79zY€ç!7š8.Š`(x¥Ožß”væe¨3¿8)A¥¾ÀÁfÄ_¿ª/ŸB?°mm6ÌI0“ó¹ÂÌ}Ñûr§TBRhß˯¯x#Îse TÕÝØÝÛ2€¼Ç2ÞÚΣ®ÝHåÂÍU§Ì±½‹ü`·;¹Šß نuÄ _^îñ+Z>Ê-½äˆ&L•¶i*ΙY}¯5ŽwXz€2o-´¤ZÙ—«ÈÓßóô 6ÎPÆ5´Õî§Í\u*öÈ«plÇÂpm¾ÛWN‹D¶wVטJ1,ù5³*—æN‚ÓA:_ζ²;gmy×<¹Ž…@©vRuYií¥â^œÌØ6(8Y¤Öó•¯7æn;Ú[+iߒ8{ÃÓýˆ…Ì>Öv¥ÙGRZÓ#HÍNϒ #z¼áëuð\" ñð6:¡Ü$ÏnTúð¾v¥Ÿ6ï;ä(K¥ñ¡¾ÀZN*Z†`åÞAÉÒg/ÐyþôºõáSÑ\dûirÀ›1pÙEâ´v9šP«bõ_Ü_“H¤bµÖv½æГúÊBo Ç·³ÐêKRP-­Oü÷8/•³ZBZ¢¿(­ÿ¬7îvŠ¾&⢠+#!~Lñ¹ç>Ã康÷.›Q,Õû% a¥³FñÜNÄÐóiŠúf1û>—"3ŸG†˜NºØ~n™2Õe…H(øïQvÞ y•Ž×³Ê5©6þ¢Ëm8Ÿòˆšh¼Vž—tþžH­°ÊZb³‹¼_wçêÔ_6‡Z¦Eì÷ÕEKÛOU¤-îÞTC/MÔmӗÔWûc]Že=…‘ZäIå˜Ë•ŒÊˆ- ü—CüþáêÞT†@€RCLb—€¼þ=wq3UãÓZ»7§¨½ìXR›zXþQ9Q®RÙQî72XúµÜv­Ä°|R^Óõ½(hª"3“JVÀr°kÑP+²®<—š¡@Ò5Lé* Ì-'oª­j ©+VuÚi^¤þû7)ZYG7iQ·AÀu‡†²½—ò:´óþŒšÖºàĊ´èöù³z&±š=•Ñû5´JgÓ@çáú÷ãy_¬“‹ŽêháIY©=):œž²çC ¢õž©Uͯãè]L©u‘Òd2»ÅÖîqÈO¯*À²„6ÅJÅ1_.¸Wêqm5—»!e¼TSˆÓi䌴ƒ™¿‘³ù ÁW†SÂJŸ|‚“zYŸÀNW¨†ònÖ÷›ÐV…âØQ˜KG#†’û®8’¿1ÐSu¹…G´kÈóM[#.Jûàçêá—KÕfÝSRç;:Xò4°ŒyuSc÷[SªP¶LGžÒø~&'/èÅyƒú9Æëõ/Çîaa6çJ°` ^–äb XC%¦Æǜ٠+p‘ó£òµg$øOÖ +÷=#ÁÈÒÏ®·!ŠQÖaK×Ç¡m7¨W ÙÙIÌÝiê)¾&fš•7æwzkaõ)*µÔ£«7>ËÆy§$îóôf¥=Ç ¡ù¦xÝÓÖP±`¶+X…%¥hÎ^Ôéswçê5™þpV“¸ëB*؍[lö2Taå¼Ü=†#Ä­‹Šjûüض[ŸoeÇVØn H./Îv¶EQ͝ ¼ˆ9€†™@ÍÚè£aš?uÙ˜EX¸“KݯnnøH~tþS¢\G··Aw)οVѺ—ËOÁ¦ƒ§øíàˆ™8çƨ°û”¥±äÆ} jÑ Yüñ;i_§O‘zsCm v÷­4ØûÊ ÜÍë¢Ö£Zú2Oظßëÿ¾<ÂéìšÇL©N•ÂbÞbûTêW‘°ÝÏ|kׇ[C¯”¸³…œ¨=ÿŠý‰Æ¦›®ñM}L¥¡L}N×h6d 6¾lLõ2¯µFåž.À“K[tvB-ê*©rU³·nÙf¯¾2IÿPºÝM 6:cqÚaW!§ÛÎ+՟EçYsnédJv‘ï –ZŽ»›ò¦¿]xòé.íÒÉÏ󃌻UÍÜD÷ªé·Ω®Ù¨pŒª;µÌ7wÉ2`+üV¹p¿ÙÇñ:iìj‹Œl eÖq³ÃH_+Y§r‡_öì-tvõýHâQ>hõë¤oMåIÏjn‹½hTñR[Ìî‘^(ÿÑTu£ò¡>äÄ\<”Ùnôî缃NªÝ´`}ÖüžØ2¦‘’Z浚ŠúìÅñÚÜ ½+æí[&c1¹d,é2>±Û{Yù„?aõò˜=ü`‚êÄüïlKêËíŒçn°vöÊÝg»™Ü惕9Üg´ŒwÒK 2`q{W-¢—9hnµÒjíWâ0'G÷Mêöv#‰›ñI4N§²sÄn&1œŠžxz©†M­Øf‹ö–Ôº’œ-kÝa^I°ù{&ø= Õ×ñù|&?¡éâ»è˜O›v.70ö±S´Þè?ÁD”×$½´ì,+§¹Äʲ誼½¯Ù/¡¼Ôv¸Ösï“]°¦!ÁzêÀi[Âw 5Tgai¥qÞ*s›‹*§Æ +Ïkãoå6~0ϵ猑lë,¦&8­Îœédá2}LµJ­a—ˆS·oÀ‡Î¥Å²ù¼už•$óc½¦—(åQ|mù¸î9 ·\ÊÌPQ€—ž•Ý<#°]Ôqºå‰æf™#î»7_˛ð#qùûåyõ•»Õ¸Älyäqöv5×£OIkà„ºX®j›ýnli´Ø˜œ?WÌ-œ{ { ŠÕÖîvÃÊà¨1uºn)^½ÄÚð÷Šw¯m£L@â`©ð:Ô½e®[†Ø»jæBDF™b9÷ܖìƏ亷GõýÓ.W2~žO¤S˜,s?4mv¼Yø‹ukÄËdïµ#{thã&\ðÙ +Q¡Pj_OŸ‘ѦªMŽ¬×wQmº¹-3âøÒÚáü×áˎz—[̯eôÿ8lli4ðãøϹµhV™çó¶øƒ1’è7ÚY½î3:(¿€5´¿¤]ŸA"­!ÏýM´â-V\¥>[#Ń­^”Y·1Ñïý" ûMš yÂS9åDZeötàüö£¤coÁ_Éô¾g» Xþ6ÜWï.‹÷uõË3/kØy YE}K°äÚti©·&kú¯Å’­];V9uܳۘuߗu¨"VuàXûyn-õŸ““ +»Õ¥‚[ê/†ûmìÆs,X”«åƒ~³×¾g»æ>ð¾Þ!0ÛY¬Rƒù²^ôì¿$`eNƋR§@õ^Þ°žuªžZܲç®é׃.T!( ɾž*T£Ña4'OmöSiþ#©N¦›¾¾à=˜ 8÷7 W^x·ÖÜðM–äÕz„ÛŒÀù-çÞÁÀÇÄ"p<ì3ÝÂ?0òBaz«f)t“4ºv­sYDʓ¶…‰‰‰è³Ô[µ«yCDÞhÚA¥]+ÿ#)?¦0|xñÝöó™V"ÖXLzG¼ +ÞÖµhRl«òŽzÁïÿÂl‹I§ÐByƯ†}¢3õ5_Ý|nit»ËnÔ†½D¥æ«–Ê ¤õ¡_ú¸ç>Á???‹;Ÿš@¶Zv`vGA;u¹Ó|èNðºAúœ-–ïr“©ôOFóT|†ü¤Ú)ÐCS¬„þ’L­äÀÅ 3½²%Ñ¢ßSëæC·ø0ÔoÝ96ÏÝv2L‚~V¥j›¨ÜÌl?½Ç4ÿ S™ÈrAq÷íé0…ÛIèK”cãÊ9B ü/Â$ƒªS`dðØÑ^a¿¼$Jú=ÌþäçÂnú +ËtםZ^ýC´×Ǻ/ gZÌةߝ?«™§§È:x\ô¬Šµ‹Y&KgMÃíHîX›—oxI/’ãM_?ÆOýgžºþ¹K,Cõ;K>!Pßk3qÍt: ‹içW‰5IE ¥ˆ?çå‚—w?ùZq3 +ŸÑ–Õ£äzå[W>·ŒÈ󩬭C“j8Nðô°ÓŠæ–r*­'ۇÚü.¶7 yýÙxÛRB4¸QôÂ,I9¶Í p‰øáõÅÒ]©ªôž +º¸µ‡^u¡Óö!o3)sÛîÒYû÷zkÅJ€Ùa7s“ÁiÆIï°!]êÁvËáŶ b3­U2wŸËEÅe§4ú”^\e&úï=@Qߑìtu‰Íi…Ë¿Ÿ$/$7+BMº• ÷Îå¶ðyﴎZûó$¶ÑÏzÊgÞk²ñƒè<ƒ_Ï#[è>75èñ.³ö;‰]iðAŒÀ«Á2÷}–9¬w¿â^qéox­‹ä5ð{öaípOH†Èz×é Ð*ósXÚ³“Æ1›£â4ùL‘77†‚šÁ(ôyâ»deВàÇÛckµ7ˆÃá¬@&k]"üˏ+Àˆ_؞äû7RLѤ˜ÍЄVMK. +k¬T®—‡=P²PkÄ Îd!sôºh¬ºhêQsLì™»øz7Ão¿‘ߊÁ$ü²Å)&B +Cia VõìåâVb†Š&3»ÚgUÅxNáQˆ»(Ñö64F+m;.Š‘”ñ"ªÞ ¥4üPR r–Cò6ò{‹Ê’Ê„4Oб¼†Ô Dw:1G÷‹ÎiWMøœàö&a«PÚä;#V£9¸‹c‹› ¥g“1kAŏ÷juÁªÁ.‚Ký¿Z_On…þø:§^ ƒú4äWø®ç’õ/'d4S…Ô–›Ý¾A“UQmŸ+ê—¯ü¸Áâ:X‰’fì1ü®=‘µÞ“`ÃÖø§Í‰Ú.š(½æÅs³ÑJ8:yR؜žÇ8•ç"ã&Ú¢pÅ ˆQ^h`©ãÞ4gó#™î~ ¿!«oAl8YÿY4ì 4a!ªñÍ"îÔËêL]-”ϨH†SZ³ç1þÇݽ^µ{ªSn¼¹û¡wPÒÇú9)ÏÊeþnÚÊbÍã͖Õw„"Á*±o§9Ú Zó)ãû¬cóYÍ‹çÞEA/P™ mv(ê6G)=VÝÿ’ÏW^R• +_UÄÕ¬I«"É̄“àËú‰µG,Ï×^KÞ}^9Lö_9Öçy=c!B(Òg9éǐ|žÍšårÄa ŸŒ¹iIn8Ú¡ò¤kæ7—XÎ>jôu!ÈD +ïÙë¹:V–È|Jw{4 TŒÎ²£h`„Ùª2?Öé…—<&²™ BzׯŽü ;žaOn‰ ¾¶¯OÝ|rœÜ ‡a£[fÚ:HTÞ²Õ#éðh/\™­¥G0sß zöu>/HIÆÙî¹Xøø\–¶ÔþÕ#übݬA«¹té qã•r›¤5‰=‚°Ïrfn»öW\“Ø‘ȓTÝ (ؒì²0Þß+öÚZl$ï¶ÔϳKÃòü + ž^=ÙÜ•¤êîÚ¾Ì!\,††?ÛJ]¶Š2Óô~ðw²•Èk-oU¾•”vùê[&Ã:AÙëpI‚”Ñ×/ìÐÕ´¢¡TžÕ9é2?ÇÑ­¢%ä̑ñIN£»RoiÃugzgì÷¼IÑxTÌ·Ä³À¾–7Óµ™êê­Î8dµÅ´‡8Êèû¶tæ[ý¨i¦¡ý@dø²e´io•ûFv5;÷§:98·Ý†yF·Ú|ÊÍÄ]Ù}O=)h½ƒÁàŸú° ©ß×+‚]͂Ľº]©Oª„ÏË!‘á/Lj&*ðú/+1ävupҀù+£±Â8•8W£hw—mې©N7R­i.ø“¾ë–FƒT¾ãÐ[Q?ÙPÕöY„t°©ê«¿¯ie㫶]¨¨";……»åwQªÛ©ò ‘IØéu7f,ÕYéªhVµÿ6ÈPsUôTظhº<“óLZyd¦;|H¼ö‹¥'åÎr·†“Ò4EB!eÏ»£¢F)©6ßöKà®ë™5&#XYÝÏö^n +fmÅ´ÜOíü´AÃ5ÒÂ(&kƒ¼.à‹t3PÛñ¨¾oÝM¤{Q™Þ.9¾gß,£¡0+Zï<âÕڕ=eÈ2ú´ÓU"T¬V'í~Px…æv)ËÓ-äœýö{¡|Sðì–oE`FC.¹ìã˜*¹ªÔ‚u}nE¢jþrÁøÖNÓSÛl(·õƒRÍÆ]¿vV&›&S‡‘Ün)`/~tüÆÂñnƒD—¯@þGÒÎ[OZU40QŒ"Yþ>ù˜«öæÆy÷v¾Â ˜q®I¯¡üܛ¼${ƒ˜70¨#ô%þå)=µŽlEw5¶!~èóx¸|L¿Wa"ïÚÆ)¥Æ%ÓóLZ¸ß¦Q-=ٶඖ"—0Z^^wâdê}ÍWØqi4“R²5®’ÀqŽõ•vc#5€jÓd'µ)}¦Q¤Ëø®^šÌYÊʛ…Ò—åüc\D濪¼,¦ÆçàIród©*"K¦°žA<`°®\/Ú^ J‹6÷Ee^,r:õUïÿ†¥¼1á¥ÊéÙôüùýÕ1j fÙâá¢kí.X.£Vò8*Z«âuª Všõ¨>ùKÒ9v°ÏÂý%\Ïc‚;L]{_±üjkü;ñ®<…­·ãd%ÇT‹[­¨@à¿\õ«øõpÖۇ]?Fû[\÷WF7©YpŠÞ´Æ¬l¢¿kÜ>õì?Õ½8ªÅš…söÇAœÃ˜ˆ,™$«¦.zKC¡gp{vSŒIû0ݵǺo‰ÜºÛN­…Ùœ7ïIñțîÍVlð‡Dà +å†Í° \:Ã/Áé@xSçTÏ”€GžimãÛ£ž`S¸µYȪT_r·þ”…{]Gÿ’4®ÂTjnW‡Múd»Â.Ò¸y¬Œ/<Æ5Ž$uŽÌë(²šÞëêH æÖè5DþVnÿ Kà;Ë'%)¸4+ «õµiÒ£Hr¶S4´Kš™ü Ðï8)*´±¾š½õôX®öùÍäíþ­€áäì­ äípÖòùî÷jhïð‘S¬~rFq5R4–œ Íæ¢ç4ñÃþ 5ȆnŽqóóÄA(&Rùp/óôšòVÿç¼,ÆsÂ]«h$Õ§üÙn Sؚ¥,‘sq«w›ü/LïØ+¹ð‘)ڍøzçŽD»eo÷ôÁœ›Òz4ØêGËô7]ÃkÔÅfív,Äy‹†¶~3ÿH̦=7ã•l\Jžß8 +Vÿ'Asw·Ž©5WP'Oã~€l”è—–Žˆua£œ¶ÙÒýxYèö ‰ÊqÙ~،Nõ¸f]ƅgø5#¸vŸŽÉ ­ öÙ?×>BُØ\6n0m8§÷(÷CëßwïøCâý®Š(x²E>žø<Úyv/˸¢ý]ºÛGwœá©Íݞ M¥K1-Ä ÖëÓ?$*¼®Ù<¼"tÿÛ2|§®y+0~Z%8¯qO_ÃNÃÃ]µí,>ý3üUk–jÂyŸ¶$í]`d2)¤PŠk÷ðô¼U8'ãySüÀiÉy)Ü!±f$u¦™íÔ°s~ø¢¸¦è·Ä͗ìe£‡ýŸ^$5¿~ÛCômѪ)à›wÜñâ­ Nég ¿æ›Ì¾Ýô+¼[÷ùqÍ{’á?’fÇ_;a0¹¨šqcó…À=×-ü(^êZ©fÒùEªòñrS—!ÚØ›w‰˜ªT%)ü%aŸÁÉdkÆÓYsCë-cnØ19vR¦ôè\³¤ÏhÇî†øŽ‘C¡õíæ‹Y©ŠŽþÁÀ#¿_]}ùצóËÚÏ¿w²˜º¸ö°»Öä'ìàtÇÚçIW6gï/gyâK/ž`¤•_ï/ ̯^ê¼ ^=br©NXpí¹aÅAÍív0ôÆC§Ü™֒«O`ƒñ—v©U̇RÿH ÉûÊTë +ÌC5¢[ìd#|¬g+ïõm%6Š©D;–³“û ’\ Xí¤Ò(žŽ%ä0bãî]™â°1)Oåç˜í­ïPh@µõ‹O®áÆ~PàýêKR[œâ‘mxBúÿJ=«w"ô=[¨..žÚëÁ.ÝQ¹½Øñn¸ÿiÇC /ʄjf[¾{j• ¡²4„y<ÐÿÏoT»|¤D—Áq4±ýÇK¤Ð&De‰C¿µÎM ªjìe—(ƒ¸6ti¸ëÔý/Ìâ{ÃVÆÌ!_’u»Ù G–xÇöȬ#sSôà@QCØQ’äþôŒdÎ¥Û^ž劐†¤¥YÞK5*+ÍIߪk Úþñ»öÑeÚ¯«XÉ<* ªß‹î©“¦ê9¶}ÿ‘̬èeï,FVo£~‚kAØuG˜)ؤ.ñÀ³Zm ß|WÿÅv×MM¦VZÙ¯>·¿0ÒéNXŸò– -sGMÊZgn÷ÔÇZf5…«9,Û5¸^ý~5ÁXn¤µë0ñ$ýD湐gk ¾ã÷ÎuµC‚ö—%0ºøa텝6¼J°1Úi~´IݲozH0Ê>ý-Ç Ä'æ‚rmk†è£Èß$T½´OÒޙvQUw й¸uKkÚ¯~=k³f—5ü_¼=“93„<²1/ˌ^ Ó»”ûò¦Ùñ»šÆ§ÇõYÇ~ÅÞì"þ"ɹP(¡%†ü<ùÇpœ¨sӓLÇÀb°ä.•Ö2!µŸî9PMŒ§‡Ó$šÖ¼Ji~R*<6hÝ©§þ‘àÍÙ,Ⲫh‰°.àDZ3nPßQːðÆëýhãÌs\Ÿ ±Ñ™¼"£gw0¦(Ýóü†y+ÑJÊ +À;}dtÉè…t¨]÷1c‘z{-nYépr¡¿æ;¥×ñY’vÃq漜±ðdÜú}Ìôèw“7Sª¥U©”ôJŸU_Ào¢²€æ·ð¼µ”ºPlL•¸Àš!]¾Ã?¹ªÔ÷öߥ™9^» îšÃ´³. £íÑ:hß qˆ|¿òmÏÐ^^LÑìðfKÕWË5f{ÖFTw鐝ׇe„NGXLNîç3Q»KÁî3wël¬¶‘]­.•Ø‡1´J )û_P*sÜÿHò™¶zÙ¬ƒáûn²(âF=Ùãçp•v§u;‰e×Ú‡zИѭr÷VxèñMtíWgùo :cIš¥]eò”’£×ÖÏAÜ8”Ÿ8Œ(·5Ëòm¢ U²n]†Ëˆ}«AŒ!œüàuùÌúûFïôùܹq\o%£=dû¨5ä…ð Iær8i×ZºT1kw–ùÅ]½‰õ™Ý/ñü,w¦íÖà/9í׬¿æÚkn€ê-³é“Aœ@ Ïm‹º¡¯‚XœHaÈÖôVÔ[zb2iÄJé}Z­jOúœY-åOf÷ŽôYܦZßæƒ&.7A.ÏÃ?þÌðÖhÛrkŒ²0ŽiðÆ,§2à)&½¤:…ÊRC{ÁV‹ËŠÑ†-[uÍ5Èaé|NՋ~¬6÷»ûo§UqhNYu§ùÐÌNËxÙóͬ¥>èç~:ñóÃÈØn®=*¡p‰²>ݯ`NÀ†ÞpЧmm‹G¾DN7 j÷,U¬Ô>,³ RþúNŸ"¦óÃ:†™y„¶nAØfå•E“\ ÎÍ ÃƜuXÄõàµÑKc^iAÎâV$ܚînÞ¡«¹=Ó[¬”€1Ú&. Ë»åèH¦°ë–mXI«;ç0Î[³€]±jãùçMõÙK9v,è#Ò ¡C|¶ÔbIzc°Ôcîaû4¹ºnàn^.Âdeô´ÚÐþ`î¥_jÖUÎó²Ø=Rû‚ÿuAÉ’Ù¡™ (¦<ûøøij¡ÔÁuvlï;?Iò¥üƨ&³3­P‹fðÐZ¯$˽­d䅛Œ™´†X^ô×Ú¸t²3d¸#ã'IÆU¹Ï¡t“P«ØhªpnNⳠړ;ý›5;lÁ÷­®BÕãf¿!—”°|ï<á =Aoßî"óðýTì|ë¨xC8§Ø«²èÊÛ_J$+œ]xV˜Ö‘?‰ü°ŸªžÍ­äã`ÖñÂ(èé À”ØÖÁwÓ¶Gé98̤¦L%ÓÃÂ(«É¼?çn"hÙÃ%¨Ø±Nñ ¶8õ‰fÊ«‘™bä>Ù€Ãd^ׇ ¼¬ªt`gÄ~v£[0—¨±a /îj¤âÎÆC=8 I>q–_ûcmß0Çq¶{äÝÓºá§%RɄI?©ëPXÆsÅى°ø–—Gë9ÚKÜ鉎صwœ™j°ðñjÊ÷Nö13ˆ›_æßíÝX„Å¡:N;à€^PìoÛÛ­¸újËw”œÍ”ñ¹±Þà«Ù°²y³Ï's5ïÑÕQÒ3?£z$7m˜òüˆŽkñKa•ÑúbžÆÍB‹þ’ÃîŸÛ5]ÒC«Ë'_×ÛPO< °#/V[®UÀ%]µ;ñÌð3ߏ+Ó´’!¹Q™LTæA8ŒÀö€ã4¤càĪ¸óµl×仓+×hT>gtÏ¢yt<«N492¹“½)ã+í&Ìi?Udʪn˜%þ['›v:=–Þ ¯pßGÀÑø©·Þ¨,š‘€!'Éý°â!íÍ»ÞAJ±T’Õtßø9+=6$2ÞÐUY¤o&£ž9¯äawÏ) bÑ;،ÅåÎöÄïÉÎOEèÇ¥J¥Aá…3å;֔H£I¶ã‚(_q)˜„ŽtÚE‚<ãdé}ãq0£+ßiå }э/xÉCñ&H|qCD +?¼ä‹´„5\¾ÁÐLéeSNº–U%2*ÆÙ¾7Ôqä±×قbŠøü±¢ çòÒÒæFçñ„ë^7­ÁOˆçÊ¥V 7ǦBO™…À À·£Á.K³æåbWØO¶Xo`SɖKÁº§‘½v útÃD}7qa=¬ïõÛ2\ÉÞèYÅë³â)Ð,ƚ6×Òr8ÇCs!$EóK­Ê™j#±}«“mîîî*o@4?GQËïõ±0<õ§ +Q@Cþ +¬1;ÛQ0K¸ÐWÙ¢àõ¥Š§6¤‹<ãÅ֔†>gáˀ7x L2ë‚~Þò ð&Pä}Js_'ÿ0ñ©ÖÙ4bIÌДÔ)¼oöý 4 QÁXv›õ è ±+(_éQ@hYÁ¶WBÍd‡´Ä‚/ÐïRWýÍâÆÏë¨Ì 6S…q@`lšä%UÎW²*Y=¨¯Žè%¦ ßÆ×{ú +õw€¦¶[ÓµòBä_g\KùÊ¥)é6ÿ©×-åVD¡°¿ +Éh2S{ñÿ#$a6«+‹ šûlÌE«U¹c1R ¥Vçt^wÛ ¨p–mOeKÈó°U„]u-ÉHxà;·{$z¥uõ¨Ÿ÷”Fk^‘?’UœW+B)£Û<¿‘_BmŸ½ F—‡Y×ø_9®Uþ ršµ]Ö>šåËîúpx£ñÖø–¯Ë†ÐƸBêsµ*ËÎpñ…x~ ©«ôõWf»&uË{ Y(0ñåÑԂem¤®Ì‘Ýú½Ýnù8Ao#Ç×O¹ã|”6?ÚôÀCÎ2BïzÿHj{¹¼œi¯EK' Ú=é}M÷ìÊ4¶6r…kÒ] ó˜6¸ö<Û|†_Jº· jU‹œqØ¿u'z€ðbWÚ­é·\\Ú¦g)ÄNJ;­2±)©‚³tÁTšæ•vmtNíãB£%ñòäþ‘TrÉ!¥§ÞÅ(ozˆ مdïIŠ˜Ø7¨•®‰$ÓFs`€fÛ÷ÖA’ ]©¾ˆËÜÔÄÎé‰u°Ì"]èxcC[ņhúöˆ‘üwª³ÖOÈW^¶c3¼¨³†ZBž8 r«¯27Úèø;[°í 6¨Ýç¦Át'à&÷ÅQ•õ‰ûå +ßëɁ^I[zŸqª{ä†}í¼¢¶Ô>ÉB«HÒ?’bÞ<Ë7³²¾5]ªÂ»_©‹ˆó¥µcu®â͖ù½ò Ð8øÉ"V{¶·iI;ü_þ¾\êƒßÿGpŸ–ÍJ ւ)ÿ¡ùû‘mMÍgš§O¡÷J/gÙ¼õVzðÀXdu¿±þcÎ]k¸5œjÊû…CÓT³WŸ¥F{OæoÕ¹²q~ƒ@úۍ®N«Îîeö•ÛKŠjët”«,Œ3>¿«çÙmEûnj€GMUI¯Çô̏ðÔÉbËS!Íü–ЊÐ6–Žý%AœãTŽZ_½ _E~çµ+Ö;oÕñ¥œÛƈöôÍuFW”ûl7ß>€™8ðz*ûÙùðoXB[ýšð]‘›¿ [©3•>Q$ů&/'þ7åÄTŠ½¦Ý×m횼ƒ¶åTúú7í˜ÿ*·ÆÅïbá+(µUó-y! +Û ìCåö¿£ý{4ô°×žUäA–6Óïç7HÕíWA{ìä e9¥Á"ïÇ6Ei{y['‰''öš7c®É0_I¹;Ãk,xpÃLhzŸçZõU^,ì4B÷¬uã–ÖãüŽÆ9¥ÖeÍK´?bêñøT›0G`¬<øë4 Ìà7þOå—¬o/3Äó|c +J¸*šᲟ° Þglm¼dWèÒ |/2“:e8akÚVGYL¼ü- ÚAº<ß5óÑòŠlaœðRvRr?tޛ]^b¤,C¥EÕh) ³¾ní_r£ºèÊþ·sPh,9q¤Ì•¿v6FÖÕYâ· žT¤ø~•°2îDt¬¼.~GO. jÆ2/©*+Cû[¹U‰´=4ú`ka"n¡Æ¨/m¯ÇUð` 8¥/TӋ VÖY ²¨›£nI;n)Co.¬ÿ»ªÉ“+_¸W5Å2 ôk0øøϽQ"·BMý³†uk +é¢64zy¡=ùò”¨+£ÉGYüKR`™½;‡hИ3ý ӂ +¸#½©ãìtø“wO»$Œv¥üA}¼î–+Xy⡱ûôßz)dV/³ïÜ?”$×("&ÑÒ¶×\Îö:°•ðŸlw8›’šÔžÝ@¶A5o”ÿH ñK'Â~'ód¸; Ês¿!È»5Xfú¸š|Y¤¡0â߈Zse<Ø-&NiJ¶ÿ’T–*ápäЛʳÉ𗾏& =„ 3 ÆÑZõJ+X}ëü/™Ø[,Ê 0¾*м#vaŠ•’Ä/·ˆèšM†"µ8ú}‚uj‡bØ/Åü]XðÒÇ®‰j§V^A[á'–òZ’ÿò÷ê>ªW‰ý¹ÜÁ£’2:ïü®¤°[Ë.X¹EÙME +bß³¦=â ð³--½"ü[¢ôº­½²J™¶âßÙïÉÅ[Ú6z?€½©ÍŠ8Ú6-´ö + Û÷’«N…½Öæ0ò0;Å-rŸ¥Mr¢CÓd»DIÂJÖpǐfÿ`:âÿêNl@úEú…ß gÇñ\©…ZqîÖ﫝€ÐufZÇäϓò‡žoÕhQ˜›'înþ#¡^Á £än;rv„:†‘ ÆõˆA¿ÿê÷Ñ­ä,PóÛÀä€Ö×h;ôú‹ýHêÃÿC";u¸²_ÛÔ¿cóL -á2¸ý—0ïµYÙ<T¾½j®õSù•h¶Ñ jm“¨[ÿÄí™tü»IMÈи¼ÝÉl⸟8£ð®Pq†Zr:ãÁ¨ÑYÕx[UnS{Ù{ z”FRÿ»Ý@±59ß&¢Šƒ»Ÿâ™0æZŽFda+ÑëˆLéÇ4væ4J¥C·˜ +¿èÓ(²EŽ/Ñ? ›f"ÂmNf˜åürŒï  ‡ò%ºÍêÅV5Ínž­ÕF~c_؃‰°Óì·p”‘L¤SæïNՈ[M.Ñr"¶ jè ’¯B× ¢ƒ,ú‰×ÏûKˆË£%XXÉ0¯m«-ÓúZÿöƒNY®’/Ltq +¾„7~Ö¢3×P,H×bSÅj!b×Úd bߥ­à€[R~×ïS>ž€Õò»¹r-+ıԭo‡ô¸Õ‘+E• +iµpCB{vÿc‰?†… ³]À֝b厬Ë³'þƒù¶’æê\ÄûPó¦bF5*ð¸Œ6yW‹0 `²s®Qõ¦| 1óîç=ɉÿ¯rKž¨^]Ÿª,Ú »Û!Ñç +ú`ýla#ΩkÏîúv¡“⻪õz‡–AKÕõ?’O+N¤,Ä»'_5W³Ó!dCøÖ+fݬ÷Ä<Åõ¥ÏÛªM.ÚȸL撷™•à¼ÿ¶ò?rý~—êf\"Â[Yà _íôÕsU/ˆà©=ˆàž·ÔH dŽeXjPϦtóâöƘ:¼£âv ¨¹^Yiƒµ˜Î;z\ì|¦$Œn—ìg'±«[„°½â‡£sUø6qÎSåK´šýý~?WÞ{°`–”r—*??_/¼€—tÎúʀW5R Ïs‡)•,š›¯°Ø%sŠ¼d½¾4bÛôó~~¨×ù«/ŠæüžFv'ì!‹w^Úqjå5¤iHÝÏ;/ ñ÷Ëç6ëS¾§ô÷Í¥Ô3۟Œ¥|ÃÚLùù1BB~-«+–[˜¯þVuòùzî³Ù¡‚çíîCŽ-.œd›í&‹òJ£L‰šŸ£rŸnóEZs:·€AIß'’ÊÃS߬ÈJƒÊ­9Y"U¼Àm~yËâép½<ص”“Œ¯¯¬Y»´0ÞòIðÆU=²d8AùƨÕ˹ß;;™nALÂܾ|ЊÊEbÔô5&•dcŠn”)ù ¥SÕ-{w5iš ]˜€ jk!ºÂÄ-ºÕø‚sÈì6gžPA;Í4A52üV?­Izöc î]"?£¹ç–ÂݑÆê·Xp‰ŸÒGŒêôŽ˜{²¢%3åY(FĪózfæj•úçéÇ”qÈÑèz‘åç5ëÏuZ2ž¬oSÏQ›E¦Úaú¤ûÇËá`Ï6&`T—LÜl{ ýç)æ¡Öókú¡ùð¯¨qbGåªÌ‚»çZXÃT¥§tZCNÝòˆHº¯0‰ñ6?)šwv݃ÞM‹Ë¬ OùéìäJmÆ5 +uøíC’Š»²Ì›šÆš>³0¶¢¿ÙîÊÙ.D1˜"…Ò#^-ô÷MsâqåüqÞ?^áhRQ‰•"3X;®{P¥ü“ÿ(ËO‰Äœðlº÷#§–3ÈB Ûêå'fe[×|ë$kWo#÷C6òLÛ2šÁ2ªïnµ¼5‹6 +¢Ë»“½ó€¦ºN•§DÒ-ßWÉbçÌ¥Õã ʓ·TލhJä|ëÐÍtÏÙO‡9ÉUtvRù·8Þ>¬Ù~Fc`·¤u{χ¹3¥¿·±^Îö/I7Ïð¾¨.ïZ¨¯k:¼«öiÜ6>èÖåû²Æ6òdg˜Èvß«Rˬ_œMïaá΅²jõSJn]c‡÷Ú¤ŸÜÜ?W¹,ø¥'OÅulhÄ\ΐ02oݧ½•Ï]vU„RøüË8,¾wö¤Ø­/Bƒq¿ñcÏT¨‡ç ´ä4º‡\Ó ™r5©%^ô¼×EJÙæ‚»þHÊ«ê®(°ó¢íÂ1:V”*ÏÄ!*•lò¶Ž)öØÖÅނ‚rf2"AXj6rT±Á>ë'ØLŠ›Ví6|Þ8ßu6ùq¯nêŒ7Ħ ‡ÿÜì·´I–=¦UD{j–ûsîÕ´aq=<;æaóWÕ¤æ/—ûož¹øø´ºY¶xWH +/ÂÈàüZuN¢ÈÂu И¶êŠâxAç÷xˆ\{جé%n,:@WÍ[õ¼ltc¤c8]üæR!S®·ÒP.¥Ÿ=“ÿÇÕun+ŽõÊg1`p"cãœs¶É9çÞÿâ>ßé¹3?{­†#lm©T*i‹Æ.Ùeƒ^½èéàÚ­_¶›=˜1E’þQ^7ÔÔ:”å­l5‹»]ìOz™<¨Ú£¸º–áaúop­óä »©^ ™’öFG®scºû?9¨ÓR9,Æsî×:àþX°Ié uç„M„™¾…e}æsY§°þJ²·{¨=^Tñ¿Ä`_ ÷ÛuX©\ÜY‚Æ7†‰ÆkV1¥vQG­oøþ–ú=Fž}ø˜Ïë.VàJ:ÉÓÕß,gbXu¨•öv»cÓ^²´4¥YìN]ÇWh2Ñaÿ#ÔûÚ)ºíž¨6G†¥_Kʂ +¶èSЯióž…%uk·@õÒÌŽ<«šç”Ãø晧YêÐÕ>C6„Û¤?Ÿ™ûcLü,2€Èõˆ¾ýtv++ړ=+ma'§R>ªbmet‹NN}Ù±j“õP?سå×O{×,x2aã«ÝŸ›ýPüš(Ïر™s•;°'5,‡¶…5uªê€^ýŒ›öLY¨¶ºzøÁƒ¯«\+qëE«zĪV<jæaAO àÔ7­Ø¸g¥îCÿO¾±>!Ù¯1H2ë£Èµ©4üñ[Û>LË斸=f¿žX_0ð´À] +(äæû϶€rÛÚÙäÐ6¶ÖfJ­¸"¥SwÓ´f÷ՏØ)òŒiVx¸(×áL5jÒ&´„ah&氄8ÑrPgùXçÌ7ç]«€Ÿ8íÙâl¾‡¿ ØrjlŽ¯½Û«a²¿_™ÙÀ®÷Ëc¿>^îLՔ²õ†duø{í^Ó5»Æ.¥uÇñZÆ#ø¡ãî"<Ž‹õŠctúîÐðbUŠJ»mѸ,¥2»;ì‘0Hcßøb5„G í‚Є0áŝ¦ÖŸfñsÝê肦ŠpŸöõaÊõãS xÆrX›ËžXˆÆ°›7îY/i¤{lõXþ±$}Ÿ^¾£ç2Pmh± vHÚòxxb-pÜûӖ“ª14hµÕ6—‰0Û²†GåǸNîÀ;€íƒ+Á—åéµ³ >š¯‰<ë䊾;§Änj9t=©¸Ú€^e±Sí±]圹€oN¥Å}<ՃÖçJU•jy;BU•aV(­IããÑM¤)ðM¶ªWßöÈ«ÄüϜM³áêgýfGǖŽWÖ­SBg¹‹þ,úY"psJÄ­r0ґ|r¡£¦‚r‘h‰‹×þ<osè0f°=g‚Ÿóê%ó ±ãû¾GÏÛ³Ä"±òűî^TNk;ÈÒ+îƙ:kïÿ1·âË!A|`á=Špòúr`a­s©:­¼Ú¯á„mì°ëÔ{XÉþL +G°õ˜´„<ýü^ý\”}¬ª¶í%í ª"¿RoQ.Kv‡Údٓ¦sÊÐ#ÀïQ™Ý¬—‹¯ºÝ'G…”lå{Œ:¤9%f“°}‹Ž¶ðb_e`vJ6Á”× µPdÛU-°| ŸÞEÎK¿Ì­»†î«dqîvUásʋýÜâ>w—­I['CËEÖ¥ö²n•Ü© N=4ÊYUÔº,æ)Êaç*·§©È„Ø~ΞëÔÃüuÔÈ:ì©82Öx\<5Ên‘˜™³Â¸¹óm•÷Ž +ø3©j' +usé· +¶ôÛ^þ&)]šU&Ø0‡Òø Tëc`UgJˆ5_…)È výî󗹵ò± IµšèRÄ +ó\ŠÇ{uNØ-NªÍ®ÿ8TêõN¯¼× sP +‡ /ÒÐ×7G=4úuìRÕk Â΃æd2’V=k¤£ø:P~‡”JT>¾7ôýRWýæ2Ðü( ã@øÄøü—Ž{rþk0 µÅÄ Ll ”}ïì~Z”Íp\Œ¼@Eõ–Òû˜‡{òÖç~7áx¶þÃB_üð‡twìÐv]Ò/c»„÷όÝ9‹c/&w²WlOìînÿñêË×ÙË nwæ©ä~Òô¯Þé"øyøpÓ¨Èâ¼b“ZxFšËXV’ ӝ%ýŒ£kôrg×òùĝMéY1’‚ îZȏ%`çª[jG{Ú¹ú·ñiÍœìnRcF6—æÑOr/ݕ}GBFŸ9ãûÝðÏn;È4þ²”ïï_ïšê£ÉäbăîáÕÛ²¹‰+G¥m¼p©-#ÕFï©-+rÞà>ÊÃÉíâF^ô3½k.ۏN»þ*çÜ÷+ˆÐÈzÒi1¥».kõæ3ñÅ0%gï/ˆS\Q¸0ÇáV¿~{L/)ä}ByñÁgbGºôâ×BªÑ8³ dL–qe»kWVñ싡'§S8Ÿ_vÃáË9÷¹4 ^—bé"$¶sªŠ_ºìÿž så Ÿù·ìž~D¼ÌÝÖ­Â?øà3ßÊL>_A.ßç½Í]3QŸÿl·Ÿ7Æ(Gt?«4ä(«ù^”BÖ(±œðý]a[z­ªq¸4ˆwõ\¶êÃo§Fi¥]½ >­<þûÜ~-ÑÓ05™¶Ä`P–Ö‡^œƒ¤/©½Úc}®üøiÞÊ·K¥ÝGŒæÓõU‚ä(•ÉvQNf'X{ZëÌ{×>gP|k¨,ÏËïé{ˆr @Ý6º\g Tá ök²óÝÀÝ°g½±uç…pO~[¹'²ÑSúíhÌÍoâ•@<Ñ©pšâX¢6ýц‘zFË?Sý‚zóKê¡Æ© neÏv¼¶én´\m±Ly‚gj×æÖ&µ¥‘Ìæ÷2˜#úSmT¨Ë¾W‹ÿRë°ß^`)Çk¡¿ÕתvI•æžj*=C1¨=•K(ߢV÷“U҆¿ ìÄß5²x8XÛAó±H{ sÍãusM£×–¦åa%g!%ú˜Ñg^ë'uÓ¢JûZœ> +ãŽEɗ»×W;-)ŠéS³ãÉÃǹéP8|M–-5¡âô[GwP9fñ'Šò ÖvЗÉÆ$e p9þ‡“B©÷öºÖµ’ +w”.o¯7On<Ʊ#XM›>öÔäþèÆçŠ +–šã–»Øä¦`âî¯1…JJî)Œ»P98؇øì£9⃟ UÈí¢¾g'(¶Á÷X}.d•Ëäùÿ,/BvJTà!„©ÇÉ»òÛí¬£_’ÿ0} á.2ð”#…¹V÷»'ËÀ‰Îd!ÎìÕkW̬…Wº›cLê +G¢ŠlvœÞ˟Ø?Æð:äö$ž9Múgn_#ÉChÊR?±{Ò~­•Û㯰#ôÈ òÈFi¢ø›EÍK«»ßu‡Q†:b7è½ïܕ۩_î9‘üÂá‡{Uû(£wɜBPù>RCÉ쌞Bæ*‹µå8ñHàkr¿¨Í;©×±Ã ”Þ3°w».6ó£²óngJH½C˜Ng3¸×s¦n'ú³yeݝZûMˆ‡Û{Rð˜nç×y–ã]W8Í¡úY.!&«¦½t-*L%“á¾0QâL¯;¢ÿÅÜrÏIµ`7ºú´;]#›æìÞE:Xâ.Ëʲ ÙM¶×owê%%׎rcÛ÷¯s·qü»æЛôêã̓¶‡ûÐ5­ý¼øD­¾N¶ŒÛdÏY§°]ekG©å·Uëܒ# Ô²ÕCñ?Æp›‘ó^5ìÂÀk®:1î;¹e¡­Ç×2àkŸ&Ófº!¿™v|ÒV.½rYgs81ÿ€ÛCw؝ãý=ójøjT÷í7)­ëËH5BÇ èÔ/CÅ#h3T?þØã¬;œæÿ±dÔØrc~gìA¹táG¼!â-HJL™vP¶ù”?øê´?͹œ¨}B¹i]ù5ÏWƇ@kW ±<|ï;ø"­ÉŸ¢Ig9?³S‚j«ê‰<+FºÅ¸á´Ïê¤Xí–ã€Ðò3+؍a®‰Þ·¬ 㑍«„à1OénžyJÇ!)+gʛŒFXŠ¤&7ß\Íüö±Q¾nÿÈ=5ý`¶_B“'‰é ]Úë/ðU9±ñ¾sVo±Ì˜[K-2Cé]Ý£ìS5k0؊ +»«=Ê¥'™³vÌqe¼|êïíÍÈUI‘áHD6\háZ¢ú²R‘}g-´re¡<‰¤ 8Äw2›÷̬Y¼Qv{§åË+v‡Ö›)º};D/þq¾ÖÍõ#¿óqæˆÛxf9_+{S«5kÀÅFï&âQŽ»2ë8,õs~OPjpäô(~øôMÚD3ÏÖæ“teC?´Cù%w>\xO• +’c ¹12]š«Õ™Ó  & ÛmˆT¾¤U“¢«$6A^øŒªs%6ºÍó=I˜R¦‹X–‹Þü˜Ò§{‘/¿ûó)xgçcyGüÅt)uyçç*\“ JCO_sµ/úÓjÈ¡î:qû·‘ȨÕB®›åÜfE((ãx8‰ß¥K]XUuѲ©oãÕÍ;ÒúræµÛg`1áZ:)=àÒҏ%ª‚&À‰V_ø-±õÏ®Øõæ%½xê©°.ž÷˜{P£7Qƒ…U”úOvª·¥¥Ößwn «M@:]2Ô©}Þù[;ÐÀßHSlΓD„·6zØ#óQns=k]UGúÞî"†Ö˜®4aӁÑʈ*×3ÙQ~Ó阱X35ßnJéž-¹ô®˜EhsJ®ÎŃ1Ÿ[UŽÔÖ'=àçݼkÙÀð[X#1À}ëZëíBRzö֓ ߀Úf‰ÎÕ¾£½n€òË4͔Ù¡ƒ{K-U?Ù¾Nd•7q§zí·íÞ´òu„.¾õw^ˆL)l}«ÈÙÍo°[YÚ%/M¬5's/|VD¥Ëɕ³Mpà€uiÛ/ªuð¶2ÝãífëC/Å4OGþiYïËö±ªê¥1¨it©(ñø¤_Æ#†Z]×oê:Ù袑ÖâôFG{œ¸K&m “Ü„qÕùµ“S×ì±oEVÑV^„jS×TùÄ+õQ_¹éq@kµPqoé#órþé¹uSôyhyO`›AuB§{Õ¯ÆÊv +½Ì(âSÍéÇ +WvóV`½*Ÿ<¨wͬ¢?+}#?ÈÅPwZ±÷ i)l§*™ÝEQ´¯9ØTe]¸sújاÆÇÑxx—ÝæS³ÐCÞ>L4H—Éð—L؍e$=7½Ê¹N{SGˆ¿ßf.èžã¼æ¤wmºåí¶@ØRü0ΘünãusP[ÑÂۓ“Ù8š0ã 9a¿h=хgã䤢ãj# ´¹kÿ¦ï©?ÓD„ymTluz˜ø¡oó9ôlKSÿ¡ãÎù§æ¾ÎüGã +üS{î.f­²Ìp¾VÊ[WÏ®zjadùåMN.Å/£rmL-‘3ÚN5N^Ï Ð Ò±Ã~qERÎכîv“X»4Q“C^ð›Úð¥cÓoh8Í.ˆÄõÇUºñâ¡®U7>Õ¤8G324Ü0Ú´3³«\ÂÎыµu•y–Çet’k¹§kÝàwüðÄ•µ"õÍO±·^KTS¼ +…ÓkS‘äÆôr¿Æº–úš§8áéŠÏwáÜ:3ÌÆyµP 8.«Š˜÷PQ«»[§ã½‚–Ü>mäêÚª9»AÕÇêx~®hìòáv{­Í­•¿úC{Úh†V.›Ò}~xÛkošòllU”o…ðGdq_Ü%ª;µsʤjÅ8Poõr LÒ : šc”£¹­ç2ߐ§Xg¯¾ý-fcÅNHó®®=¬ÇįÇ5zA‰£Z•³ýÞ¿ˆÿÇ܂+ ڐ޿¨°þX uKUˆËÓº‘ÊTÖΰGxQíÜM¸Âέõ¥¹Ê¯ÓÓÛ¤På‡ä·ù8øX̳›‰sˆ¿ieзº`cgî?KҔJ °µ%·‚ku´×L$ëüœÜ­™¹ËÃwß8±$¨ƒß§çpjâc°Í!¯ï\˜bZ¢R®±åٙ=ڊ-8?K ɟµö/sk­î~àoF5Åè–̍ä%*íKóé̸B,CÞèÒÞÛ}3µ‰.z*—·¼7}­æ^šþî9Þ£è'­ƒùw—Cç’;él;¤¥‡i M­sýí: ̈žÕ]~\…!÷9¨'?–˜„®§L¾Ñ1€‹Ñ–*©UMêAkdPÑ L¶‹¯^ 2Â0JøEǞՕËÁ¤JààÍíqºñ“x$)W¼Ä +„°)úµggÅ´ôok2ëç½K©ºä·'ÙK=Ëtm ës S;Yó Š!pâöƒV½DëøB°Ûße~de¯÷›Ø‘a•þmÚö„óS‚1«¨¨Ì"øxߘô³ÓþºVÏ½Ý ¸Â‘›@yus¡;Z z-ðK-_ ÷nüPŒª]~µÝÜ-¹÷Õ)æßè–ÕžòzýCÇé+±ÿОÍZÞE†Å_GÖVŸˆó¥ó4–1—5ƒ› ‰óì?ÐU$Ã}¿9oþn;LY'$R^aÎWïè{-õэ Ô³J»éÔá"º[E|fÑOKp¬Ò½ +¬ô¸g-'Ÿw0ËA¥ +o¿á÷•—=ש¯—},ñAßźƒ¢ïûÒH´*÷ !ŸÙñtÀ©ô— &vÌág™¢ïŽ×kè²íu‹Ö¾)®D[2_@å„]î^®ðhڄò:»13pÆ]rõÃÅmú]ë ù„­MÜ V‚lS_°ds»t}<ÑÙ k·žÍýŠ¿yË_¨¶ÍÂß䮬§¥!Òã®_|¹­+½[A—ñ£ö¡Ú¶&<V:ò5WüÃM&Ë7Àܝqý5ûàÛ÷:£/Â9,i•¦ÂVA*áºFÏðډ«KÊ,÷7±°o-Վ3²ëM¥õâÇU‡B¾x¶!ÜóuUªöÙús+¹®·wr!@p±>Ö¯´ªJp&áìºÌz²ó·fÏgö%x8ûÈý5úþç*Ål‘*¥<_s%Îýgý<²ºêE¤à ©x?ÑYZÓæžsÃêìï<^¬âÎ$¤5҆œ—]}~ےü¹8Ы¨ùÞdzÀ”¢é{d–ódLÂÜ\Œ;?Í)yøȋÆØüÀ~Š"YµÆP6Z7«bÄøPpë>nµL—pï:AÏàe®¦>‡ÊNäu~ºË©ÏîÙcy›ºp-o¯•g͘çíï³â=%(\1œÞm™b³.®÷=YF$vÿ 2n 7}~poØo‘ôiÂÂ߃Þ&½ê|Õkm•v[Þ©äïxn]gn]¸Ê>ûk B{ᒏøÎKÿÄëÁÚC`þ[Ԟ‰ÿw–•+&úÀ_D ×e®¹ãÿ>þ—Ž{ t”^ڈ‡°Ë +=|b‹(ot ×O¦T=¹–CmHjniÓÿ³QyyN%_ª©‹ÿoÌáH´!lϱyïñN±ôIË=~Ûèn˒ˆ²šœô¨›eC• R»¥ÄϨ¼¥¡áô‡,’Â,n«Íúö‚?TL.Ëw<}hD•›6tdÛu’¤Þϳy|¹ƒä¹¾8:üù+æ?lÆÉ@ 67%ò +ýì㥢 n9•uÄßc,qyXUW ©2(=‹!¼“%Žˆ6[Pþgé®P©m檻o±@ +éµF/ÑN4JíC¥»¬ څÁé¨;¢Jyö[¨éS˜epýN“˜ùü’eâÝÛ4JZaÙf/Áo³|Åð‚Y!ܝ.ÜØ1ÑÛ}ô7µÚÏ<©Óÿƒóɞ±°çr©ÔB'ì³”¾ã=\­H"ž³œI;«B~¹)æ¹ä!Zk{ý× šJ‘,Lg ù(bN`—ðêe¼ÇgÇÈMÙ`ÿ C¸d¼¾øb2A~¤ ÿqÞìa™PÙÛõÞx8t˜é.ô³×ý D°éqv£·¸§Œ;p`Ñ'#ϜƘ;&ä_–ŒëáÊôLé’/†Õ<8 ޗIwє Rá,ð'—ñipžFžA}ç¼|lRkýÇæÆPÎïO½Ú®GE¸3å‡W ê²ïÃ5ã¹)œÆ³{zo Ø?Òï J~©õƒ’‰úz5Õ£)íÙÂ3Ü »Åè>î#UÞk§ã÷­#8_ê¡ä~ÎÍ4í–o×åƒù±ÄZ&‰d[=¦sü 1u}TvօFû²ë(Ë™¢4òþ¡#Lfßâ´èèjáô*d Ì_)òA\v¦Þ‰¤Šeg¨æë'³ÝwºLun*êČ/í܁Àù Šª‹IkžY·á«¸%Úþ·LåÁîµ­S}´#Ǔò¨eêüq§(vž­õ.}駳VNŠÓ¢btZç_/ˆû~Vî÷ÉÕ'ç™åF©'§U£º~™ºþ΢@²„— ¸LZ¾)¾[ûȯóÓÿ¼ ú|¾‹vëÙ_¤]X\6Õðn+º‘ÄùÁÍêÄ6ÃybµNßÓ½ï\ìEåöÿœö‡¹eöéjÑwÉ.w:¸qõSL¦É®òÚµáÊÉ¢ŸÌ"NWÑ%/4´™žù_Kf¹añûð‰$ZûUM-ÈÕO»øÔ¬d…ò~½~< +Ô8VŸÐêM\‡ÛÕZÿÿ±œ“›Ð˜€«D¡W-ÍïRîqVMÁ_çEkõÈcXà˜O å>&ÞÔ +liÍY_]-ÛTu\`?Z±§óoY+à¨-”ýÝÅBÓΆþÄøxPƒZvÐ +d« íWíÞ>7÷ÜöâÍäëqÅéõv¢W¢êä4‡TEs{ÑÝ^¥û´q.ŏëÓÈåΣ‚!±”ƒŸ±è웡ž‹¡ê ÃqÞ`úB±«Ý„ +øâ{Å=pÄ¡+ÈùÛKà® ŠVu(û3~cLÆÓë Ӈ‘i­} l”Ö_GÚ⬟'Âç]èDh$a¼Ö‡»x¸>ŽÂš2EùQ+÷Εj³Ø9ƅ-ù:¯àMl‚NÅ=Pô"1²»‰´°ï8i“ñ8¶¨4ÔÊBø–rœõÌaö ¸ï! õçÕ®”Ŷ6’ï}£Qݸ`G}Ü¢e…–šãžúi¹§[ú<žôEX~—|µ¤6úÈÍ°W‘(%ƒ¥zrbbå (wM!Ą՛<6mÉ ³ô: ÷üþþn«Î—¦Õ‘ùÖꩵ40Jxq=•§ÙãÝzÎGO)Œ{¹Ú }À6ö!}éršýTÍöÞÉ÷Øú©z–³n¸å²,^lX1ÙÛ¥FÕ¦X½G>…šÃ£›k´S©2)‚0:Æ çÝ«þˆ¢Á‰8«öC`GUbgò˜†`+DøiašpS”}†¿k¢°L'µž¬f…‡·Åà­ø8›¿MÕÓzA¿É¸ê^âÑ÷Lc׈kž «ü*Ô¼(/°P¡Û=r"0V˜ÓAF,øJzÐ÷¶ñc Ñ5Îí»g嘕 d¡Ó¸ŽwŸ”(·m´ԋd \±uÚÝõ‚³¡I+]e&¦2Ô©µ]’Ô‹¤ˆ¥Oô}Am?là`(l›"Hç¹QÇ6]ipí¼ÕX©ì¤fäA\/µx4½TvtV'ƒÖ@§5ðê_$…ÆR¸|Žf,²N¡â$"?½o©·Ý®ºîžZË7vÍtS-h7ƒÚª7]—°|}§ó½Bo`@4Ê=m[/–$¶ô­ëØ£äè#¡²•'òúÊæ¨aè»Ü^9ÁL&T®<·ÌÞÌ ¦nŠýHi'[v)$ƒÓƶ§ÓÈÊí€ÔPŽWñuqlKÔ 9]Û͜B‚V÷L +ñéϊ^ô¬añüƒ“}é,œµ¸ÌÈ{a<><´Hu*Îìµ3%ÊÜIŒ¡ô—N²»S²mƒJÚwrη¶x(³¤ôw”X×ø +úV¬í5ûáu ßâ ÕÜÓñžs””H‰ôý)'ʼnÇôû]ºký|‘ô×1ª°Ï>¨‹)¦+²“Üçˆq/ùµt¨8Js†ï +à‚‚D`º^ÄaMÅ`W‰V š‘§>7âîX?=æÙõF¶ä)ém¿Æ.„TÑwÊò­¶, /dí#*]$ºñYµ¤2eS&å`÷2TýÄò¬Â,ó¨þŒ‡â:Ô|˜ìѸ‰Á wÕ+û¡!`bs.Óu鮿DJk´®¯’²æ?„ÈR˜´Xm=(2“t&ÎÍ´3®SÖ|µ«NÒêR Ú¤lû@ëûô¾Õ­©–ڂn aŠÍԂ«]”ÅÔXáÏÞE›Oå‹Mª†ö~µ9ËVU¦·yoõÎù[G‘Ò#c9ðÝ-Ý|ډµ6º§¥gxÐóÈ9 RÃMˆïÃòíPCåÙô93Û÷ÆKÍ£¿UZ¾Róßê‘!SLޓ=«YÞÜu¯ÛúöœÀ?ãqò,èÊß;Àë^’· r+mòqr7QnêáâåVr€™™ªôÈÜüFpŠ³àGµn«Ï'í-lԑÚ׸&W‚†î™½<)¯_®GÅ'5‹Ð^Á봔öµb˜|²Ý[¹9Ö:Ï¯VüÀ¢â‰¸Þ8¼Àº”nҫدëÅÀTßmy»º–ëo²bø§GǗgì)|‡ò,3b~Á­×¾ðQÔ|]œÓ%-ü6f–XMz0;‚"´u5ªk6%CÎB¹ŽÏvA³7~ý¯HïbÕsíšVhVoÜvÚ}[E(,³«£ˆd.`½‡×ZmGi²›Öíî<r¦Æd£&¾¾ßqdM¶ó?‹&C®1ܳT)£úúA±d)¨ò|9ÚYŒßk"Uça(Ó3q·Ã6ðW–`Ã¥[¢¿áž©ÒÝõSžžòs£ÃN#f‚ÉyµîfÜkb±<×`ÑM·Lsökßגíü»ü¬Í峨œ¿à€&fÇc¸AÇ®êÆ#·ÊnˆW¨/‘Ê”r½œö…H.lÿ73ûôsCÖc[¸§îç$?@ l\Á­^ê¹5ŸuÄ@‹Ên|¿uKÐî~”ÄÝöâրô‡/µתo¿»@^*äÏ©poԆN¹mU¨½ŠR#“ïùlDåáñ֖kzîÂt%»ú'β§Z§ªÙdA©§÷wS +ó͏EŒÝ!‰.ß×¥¼-¶°~ÐÑ¡Š¼¥«=xܒâ+¹Uk¿¾OÂÿ»“Í[9o½Yaã©)ß/YrτcT |´^Ö@Õ2ÛZKzýrý•Cóç£ S?ÝC%\5i=Iñ‹©‹'Ž-o´‹AíïsÙæʸ +8mcõ=pZ¿‹ËŽ©›jòç:Äo¸þKÇ5K†ƒÜ>„ß×-^™bÆóô‘ÓC}o%õ0›ç[® ÖÞCk²ù\L{þ?…’íaŸôÇ \{8£V +õKeȌK¦Lq&µ÷ˆ©ŽnYu’É'g d¶[ºwÌé.$ì_t\í¦«ç\G`;ÒÝÇÖÂXî‘:)½è¼7¹u£>j¬°Éè5ó’ôìš[ÿxÚ_b°oëQ¸LŠ‰.‰’?·~H|>”>ÓL >ÝqÐóì¡>¼[…¢CC®ßï´ÍÕïŸ4ÀüdÌõ‰ØçZ œUþYÙt‰MÅx oû–4‘¾=OE¿ÿËîí§u¢œFQX@Vœt@™oãlàƒÁj íNIäJØØ{r²ú¾"{i®˜u_`†Ý¬[™ NÆb¥ü}6ýkÌÍñʓF{û¡4r§œ*D¸~–_{Hǘ ÆbõTæUŠðœÙ"øqH ~šS"â<ïŠÈCe—ô YLkA:ÙPÕ@âÜ&F¸ÕØ6F¡uP×zQ¡H ¦&‰ÞwŸ_K¾¦èŚþª£cYpÜêpÞØʤ¯¾îx‚wDÐ×~f@M?£†œ¹º«þxKñÂþ$ߊSYšÕ„"í]GM¨øÜTÍvk‘³€x¨Ö¶½yPÆ{û¸MÀ߯¬ÒµOüëmh»‚§óöÐ,IÛÃuyk³‹Tn¨›oZœN÷/»%ð%øþ* í9E¶Áu +ÿq¡Œ”ž€°”µ?(Eùͽ4ÛSk÷Yo+ÏöZu×ÅÎêÑ¬Zˆ•Ž+ǃ꿌YRs¬5™)\{R¢ûVP}H |Ûþá–r–h–xƒ"¦?´ +Y,åÿXÂáæfÖ ‘µ"â:µŽ›ÚrPàfB块ÐÛu9¡%ÄøI}ã’CƄXïÙ¶†ü¯%E×ØnU²ÍŸYwaZt¬7}x"ªA#Ž`ēKàÁʮܓ +¢v„øG~¯w]Ÿüc Û>Õq‘žt¨Ÿšq¿È¬Ô½£) ÂÛ^îv®Ûp³Š] ÏÊ +±ÇõLs’üZbÛÁTb³‡Ö*Jwjå‰@žtm3ö|5ï1tÀ!©xוŠ4ÇïÌ*Ïjwéʏ%ð+î¨Ûà}õ7IáFh탫%ZMôvlc 4æô±ËÚ«þµ±KÄúüiþ‰Õ¿Øé ½ýæ{âP£ bÊîÖñóš…ÔԜ«d6ööÞcVœ§½½±ÜÁ[¯z°ÿKò3C©úgøB{IŠ×™fD‰j±Öpú9{¼×gÑ;×_X³‡šxbc%«ÞN·é²êþËUäØ« ›˜âÑÓY,g±Na¯†rQâ ^ñ»l]²]ô}Û?·‹ö†½ÿ#+A·+)äîî×EãD?ZÞ#2c×EW z9Þ(o^>¯]ì6½×^®î,8‰ù—%è‡>´šx|²ÈIÚØx•_~âf‹ÐoŸû¬Ÿ_å*$¯îm"\—š?)L/Ïܟ¢ŒºÒ ’coÅN»Ô‹õsküA[zépժèZÎÚ«Â^áGm2ÇdËi‹”ÌðÞ kêþîZ?”*©ílnÄ°8‹H~ûIžìàVv"`)5V“r +ö¨G~1Q)]ƒpPÚ³?R _pKy˜¬K±ÕƒvØ>ÖÁ`˱ZV³á ÚÐﱂ8½süèV²çp&4Õ³’s~-É»ñb7»M«ÙPÑúY‹9ê¶-Ãk¤§N} 1óA¶ù)¬ªêÙñ^Ð÷ÿyA¼4ÚÚuÌ"Ñ¥ëVj“±]ԍzn98¸‚ºùqMOˆO¾ÞzÆúΗV.Azÿan÷ rº^³qéW“¥jT®åî_7J¦“›#ás³oåg¶2›QÓí— î,!W'·g‹¤‡…א8֜ñrm;Œ„¦#d{9 Û `[ÇGç ÓU³¸Ôÿùøÿ¾mÿ܄í©ØkŒ¾áѝ•ÛP`ݶ8NžnxzžƒW?çgBtUä[ +Ƭô%¿à¶ ã6ÃäÎä^ݱî”i0Ḉ© <”ê^„™»%²}¡&Mۃîr-V5è¬s€í’†ª¦ ¯;ÁÀ”5A¾¾5.Ğ_(ð’³ì)Ùë¡,ôƒÖÆxIÑÐFS*œ&$˜ßØ1`m&¡•d©Š”ßæýXß®”E¥ìW=N…S mÐR»ºښ™Ô¯àXÒÆ,¼Ûp¦¶¼Q3âê8¤HSyùŽ¹9|­ H&G ¬ª[úBç-æt¾|£ÞhÜ2(ÀøeçÓF*~Õ4îÔG·›C¹‡dž1KÎ~My†Xèùò4#l”ÑÝ Yäø¨ìw- ÷®s&9:Ôµ YF.ùða·c!~lÁ¨ˆmðú†V—D–â䨏-*CÀý8ÄáC0=éæRŽ2eœÆNÙS:Páó¥Å4G˜{#‰k”Ð6뻨¬6Óâ´lZÇDònÄuÓê>›_(•EOãÈsÏ;@=ë¡<—‹§Å!—È£ó…K£uî©¡Ï¢^ÐIO9g£òJ³ÓÄÂ<ýviþŽSV6ÙFÛjðìÄ=üÛ§¢ØÕoM~ò–Žø҂ ÆGÓ,N¶T’Û6»”'È ·|˗h´Fûôµ[«‹GyÊ°{ï7 !óK'¨M¡ +Ìw×.§¬Ò)oÄŸ[É÷kÙäßó &›nX!Û·âG%Vñ +h¢qè$ŸE=[ËD…‹ÚóÎWÐɉ÷Ám Êûlï È\×Q)* ‡7N]™ž'éq뻵œé}”wî˗­òÓÊԏõΕùœÁ®³_w2­|Ý¿ r{Ž•ÞIl‰0ËadŽ§Ï谖j†ýJ¯.iÔ¿g{³ŠA>ªxWEæ°³½Û šÅ4¾|ʬ­#Ý:Î纈ãUGS_Í#Iíè? Áž„mKLŠ{{Þ̵Œ…eš¹ç®Ä4ÀÕ·nœ ùRû=lê7nfî®ô‚ß·.Hi\N þ–ß³\<øñ­-Ù2ÙµF/BÓvfùi÷ä}…­ÙšÍlNlOša‰ûœ—B=?39½³vºÈÃí_Þ”ä¶MÆÎå⃧:å-]'üPœÕ¿Ñà´>ëõ¹M³PߐîøÊzôxÏKc~£Ðrø“[½kR*†íÚ¨I!L’ùhì“‚Y£?¤×ƒý‘QBcàßÃ^íŽjHåö÷~»,ŒÄÚZü{„~¶â¦2‰OÇPøžÐ6,Ê,JGá̑•£b)†¹°'<êZþp-ɬ(kû' ys÷~d ÜZËåï‘PïR +pƒ[W\º9¥+`"–*„®ôú²¼gaIη_ NïÁŸ¤‡Œå§‡)šo–Í +v¡d,Β[Š%aê ­l"ù6Ӏƅ¥Öò=oo•´ÓZÉ5•¹\üBåãu£ãµ >0ÉÄerSÑÞ¢!'›‡'A9¡›•3 –Ê, ÈioÙ¸ }€N¶Å«Ÿ %¯• > yã‰6ÕƧ9¡„¶÷üãD>µäiÂâL“ê A¸‚ú7m%P@PÝ¡/ýbL3aOAu|¯Èê›ë>“ó°ï¨‚+µmÛ1¼ePâÂrÒJ0ÿb¢j{-²ywZÎí|ÚLˆ}EÙ,¿÷+à%½FO•Ó:”˜ƒ4>å› 4²KgïÌ_G_âÁjˆÊ3‰PóµlݯÛjU{Õ¸\ݾ°1eOåøYH]s}¨p,‹ø­bµQt ð}géc+bŒºõBWÓÊïäÔ©Ðh¡ûSvù‰žØþ6hº8Êt†õ ·®ØŒŽj .`®+Üʼч:w®MŠ Íkž¹Åˆÿ)w<æOx¥uö>†\#¢AÄM‚-·kUj†GXÈ*Ûڟ^:Œ1ÿã¾C¨5ê«eŠýU N•ó:?ÓÚ°ÂâJ©@¿phmhñK›jÏÜèQãOý~CÿZž¦„´ouÅìšË2ÀJF?pÛ}PrÐý#ñOò"\ŽiS%jLný"­›³—VIè3 +Ö^²‚\O+#üÌo!°HˆœkEr8tíêÊZ=Þ³z‘€ˆNJ'ˆ²{<êи¦¨ÜúÒPös•ÍSƒåA½h#£9¦ãsERûKÑ¡±²è +Áì[%^FÒs¥ïÈfØ@µ~-“¯ÂÝG@®®se&5Øâð/·È<7½£¨ÖNèLšƒ•Øxf²,@‡RÒĘZgå6S%U¥-Ä7ò\1µüãùçÉÓÃÍ{ù¼ã5®TÖ}f±鈥ÉÖkµ?(+>•]ñ®*ˆ6…rÖ²æ5 _Ý~îÙ`Jß tX;æó`¤LÕ¬øNÛ(ºÂ}‰~j¤—ðNT΢d[“<ž+ÐN*À‹_pkÂÆ×1>fO7|$°Û ñsÇÉ×QoD»IžÔŠI&'¨,~FêSñáõJŽeè§ökI÷Éàgy©TF€nâœc>‚IoÚi.¸édÆrðÓ5ÇUŸúæXg¯*÷í9ÿÍ}K7ŸÍ~:UZL~2Ý黒ôäõë­Áéø7Úï7L4f¼Ð^C“Ç&ˆÚŽ!ñô\ˆöj‰üÝsk¥ҕÁ¸{å»ÆIÓ×Ôo-êD,Æ{Wԗ°Vi×ù“\n´)ƒþx5€*€{¥,‘íÌñ}­±95EÜ¢j£_v¹ ±ä¥½ÖZhDDfm¢Æ(]敖œC´“:/–>oZVžåjüÁÿ¶|€í´-KØc)UQ1RL”…”Îa‹·`éë]vöV¿_T*Za©yÏNU«†ä`ރ@÷ +)ü nU±8³5#TéáÚìÕê„:S(³ +&¤Pgª°pyOæniiÕ¹Õ âޯضû;JÌņ DKôߦà7ò҈%9ʁÐl”Äœ÷ÏUyÐ÷gåMï›b +*ˆ*~cô¡eí)æg¡«2n—öÄZÉbõ®¡¬RVön³„${séà‹ìÙûÏIËOº-Åöüe?ä)fûTóÿí¹=RU¾½ÐnÂëq«zdï‰îB¸¾Ùî œêRmÓeã[»kÛå䘐B@v^GÙ`÷K˜y­œMAåo‹„gsW¢ȋZ–oĖdÍqe(žüM? E^^º%îœÃ|¾3ØÑyð÷±”E‹hø!º +M6¬ŽÖxُ›Ø3ø¦ÐKìpеd¢ß4D¬þ^¿üzšÜn3™Ð³$]Þaku¶]³Jµ¦ôœ®[™´ds¹ù¢k ×;‹O§±³øû!H›Kñb|ÊîÉiÿPX +âuÿR¼ñ¥É‰£•R2˜g>SÛ5ÙJù CçKkŠš¹ÉX)ƒNÕ|ťɏ`~^T2¼ŒSuX[Ah‰tº Xtëñ ΗF͊¨¹êv—5ýè&Váú9bêü0éÿ0·“_1ÿáYSkƒ˜ã8µòí\תÀ5O ênU{ =L[žDïþEw¢V{j[©6bÇ,ëàQ„ ^ا&fÒäf™ küJ‘gEæºÒ’]z³­µ¯­lÅüYßÕ®ª¶lû[̑$*IE@É9ƒ ˜sÀð²ýÕ9Ϻçîu_ÆøƃÃN§z«ÖªªW•^Ý.vÐÄw1]reâYmn|},U¯ `rîëÿ?r;:•¬½t‰Á­ç +{ßW¥iÈM¶S¸gPè'ù‰¸8[3>A9ÅmùaKïÿ +k2úCnw×;[šì~QŸa¯/Y‚KZ]¥LfAíM՟Zº“æ4uþµ’¡S4ÂPý§Bì‡~¢6sjÙlKŠgæX?cË¡ër´j¦QqÊvŽ`$P÷ohÏ_å+i²+ݎ#qKJâ`w2ÖЋîÅ)#·Woȳ/¡¯7¥íñ/O™¾ßµÿ©9‘ÜÖßÀà´Ç#`«ˆ—Kð»…×/ߊe:ޒD–y FbÎ*+í +T+Ù÷(2›Îw%áÿ!;EAÀ!!3‡i;ÑMø$‰ìK•7K’pM+þ©^ÄÔ:»U¼¹•ÆöþÖ¸ñ{ów1%÷4dõõ”OŸâzÏ3nÝ­G|n°ôjQ +&¤v¢‹ìÜLžÞî·'oꟕ¨éx]‡qCÒ9é©Yœìø:;Ø#8´¹óõxò´1ïԖxŠñ]/ ¯u†þëQÂaè 6ýYL^ fÚ=N†=áÎðÈT­_ÖíUڕĺ¹å§3±öìEqö5×ø7(öÿµqÂ-ùƒ·ÁP®€ádÉá~º%Iú˜óÕdÝ©35U\å2QM„•;'þ½’ÚîŨcûø“¸\ê’n× 7#5ùބ؜Ûmgx­«Å iMLÿó,2¯©¡Ôtî¿Ãq$ªkÕ[Þ£ëžlG¹.½,Ä`UnP¯l£¶z*ECþõ³ä±zÓ:‚ñ·M.w¿Îþ^Æ'ˆ¨ëQhȵµ¶Î;כ«ät£©Î†kªþÁ1ÆÔG½Ù/R´TÆm.ÿŐõŸ•trµÚºýFRôî+ß¡ö3Tûæ»®X^¤][¨a:_•w×6>®fŒÒYOÿ²t¡´þögÆfX¦½+ýVJ‡ñ³ÓïÐÎø —`³m¹Yfo&;?:¨„‘ñ£(¦ÊäÇéWv’þ³–6y©Û#É'ÃÒGZ—Û!8ÑaçàÆx$3b!/»Ç»Ä1Û¯>™C”ÒBØÌÿ®¤bÔþŽµ®íT«’N¶Éd«šCiدF¸õœMÛ½kþe»¿B)ÑØÿzAõ¾Ÿ&bwà y>˜âœ(z"ìK˘¿?£š¨¸Â/ãQ–NB*TAàá|lþe-˜³E1ZÁ +#„s^<$¯»prÏQc”¸ñX·âhÛù;?Bz‘ù×!—ÿ̍2'“YWp²Re&U˜¨0àÆ"*Ÿ¥" TÈ°,¡·º¼itÜÿ÷ãÿ¬¤·Ü–!œî&®]}•9(Ú&or¨ +[÷\õ1/ün}Sb!ÎíI#ü¥ü’N‹ûìwÛãŸ"–ÃöjµÜKÞ{¯ +EêÝ¤ÅàÅõ`Eå©]™9XáõîÃY㲑ãLWþ'9‘ØÈm¯°IñÁ̍'FÏÀãëD ï÷MÛDôG§:ê͑–sèôþ²vƒºáw%çôû!ÓõM"Èg4rÏVú­¢Í՗…üsÓ¸ÞN…ã¡»_–Îñ—eûˆˆ¾ôw[º’³ãYÚxh[+U@Œm<×y&z™:·«¥ˆý07 é}‰*˜ý}bbOþ¹9êì®<=/¸®½y¨Ÿãd×äô–›E­×Í…#·p'“Någó'ÿ_/ý4…Ï´Ò4újժ΀Ó§§âÓÈT +Ì~5·• ä¨Syh$J Uþ"¤4®°ÿŠÜ¡R»}øäò¡À!ëT1î Ò¬\îA¸EE}°za=õ/"&¿ò™Ê?ä þH2ècW^ñÆ0"ÌÉ®¢”ñxZ‰?´,™õ$’ýdãþëAþ÷Ï®× +ÿûcÎ.ü~èL8O¤Ph֊ÿùÏþëwa0h– …BM(Ƴb‰á¥WB¥Y=•K1¨TŒìÔX8Ãêm:ùØúÉ.l¶gt›$ÿx´jì‚iíõÐ¶Ø*l÷–jˆfa½Iè+€‘٦߱xøŸB³3J*ZÕÓº^ø÷™Ñ°×‘BïfñݾÇ#¿ô66Ðê ^J+/|q-õ©ê$XÙÍÈ#‹®)c?;ú8øäiІà÷ߎ’¢ËJÒ£çg±9žôÑÓPo;f½vCVÌ»\Ò>·W_牻¿VlS0Ó=â¼<ýD`á%a+s´(’b(5mh%- ÔJfÌB)éL¬DzÏRIê9Uï·¯™\Ñá»»Õ·Ç“Çðj– wÆ ëÊÑêçù¯pÏ:혹-Å{À©[º“ÔåÜ%Ò½Žê)ÃþÌo´Þg¶ «á1ýàB•ùPn¬‚¨vUQœôÊ1ø̮ęTŸúIu]ß&‘˜½S œü:W¥Çcm4‚­¾¨ Åù"ljowjdÏ!—<՗V¥ÏÍ[ù Xw.=½Ùsþ†1§ÎæEÆÖØÅ]è]ª^Ð=áÊ¥ýÉ)ì¼(:Çb÷øËjí+T9£atJ9§tÆúÉð¼5ó2Z·“ËEç׉<¯Ï[§tÓ؅x¯õË»g:ùŠÙ)æ(·]åsŸBùÍÓO‘q.…“~År'—ÙџꅻÃCÍ£Æo›éD˜^§¸Xµk 1‚«4Pk¡”/yF¶6QUAÔ(Vv-W§¾xÔ*%ŒÓ¢iå©ã»£ª_Ñ°j¨sõ—t4Û]¦kfjoÍh}d ´½Åþæô)ná\:Hàjxæ-¼ß¿ûÐïmƉƒ-H¢¡dMn¨^ÓèðY±Ñü¤³ÞʽÌò§ '‘µÿÝJ™9_Ÿ7‘~4?ÔijaÕõBF’‡ù²äw¥åª2뮦ú\we*X?™ ¶‰Ý͖]']“8+»]Å ÷*~‰Èëä.¥Éðh¶—JÇÝÓI§~!í³¢Cà¥Õ‡ÒËÜî?¯”6y\mzs³Ú¨s‡óü¾žçǐùL—^#ʹÜʯåZç9t‹Øs1àôWCn 0i‚x*•Î‡ ´47§ò$©ý¦ÂTÊ`V‚I¾®öÐøQÝc·Gû›Ú;êÛus`y d0å[µvlrÈâÝüЕbËF€B*u?íì4øíRîÇEÔZMj& ¥!Âäéü+܃¯¦¾E/vX­ßI˜¢†’niÞÊÔU¥‘Úk­Ko¾ÊÉþP§æý\ÙØ) âM|­M‚Më ²°ŽÒ{ êT¯|µ~¶Y«õ/ü3¬NkÛa\càî¹ÆèRY^hY¾£ãú¾ gûó’!ñ›¹è˜•‡ÃՋ[ƒ‹]6™àµÛnrèûTp£'_6öOÞǏw-œ/Âfq=ˆLýSdâsŒK–ÜrAN®%JÁÏfC9. 'uª±¾V`œfC=P˳‡>¿sƒ¼Æšqþà#S¬a«ÌxUËûŠs»3ßì À^ñÎK,þx²kq׃@CñV²ð™~ó?{¸ »¯¬žøÞ=Rš—uÜFw‹xµ,­g““'5J@“?÷R®@´æµ²˜gsQZL×E2k‰,ÛÉðèÔÚiÕEgËÕ#ÿºÒ0úúqr®lø2Úî•·³z¾§´v¨Ž€Ña'-Ô£õÐ×'¦¸¬ŸÑz¾¹TÅ»|ś}]>òÅí'«îZ»=Xûé˼·dÖÏj¸­=ÏÕ.ò|ŽÄô¶äšnëÚ²6“–m̖ çUÇ’,ùE°)WãüÌõ*0)-’}.c|킺'ƒšý’B©ŠœÔš jÉý6MòÀ̊çÖ(Q‘ø֖fÂޗwÕ×QÑ,j--~K>ڔ!¿#p ¢ÖÊíC³FïG*õÊgy·;/è£7‰jÍe›Ök%½Âj²¤¼3‡ÕŒRáW(¾˜:%i¨¢¥ö ”A÷ Š7­]9²‹£ä$:Qó}ùmÏÆÀ+µ¹vK®¡a`va%ñÝbJŽ§a¬µî×LÊ ‰~3 +][ +ÄîüzÙ.¡Pa<®ÕéŠëÅéfi£ChËTŸ”jø~ÊÜ¥¥1ë,¾›uoKÅêx¸“EQÏÞîÔÉãî›D…™ðÙ±)_­xqÄLú„}ýé”(5rÇ nÒÖ3Z,t•â”¿Ý-Ӌ—‰‰¤`V³ÁþøœÁ§RGœlî€yjê¤:Ö·â2õ: ÷!([྾¬gÃËNe ­ç>]±Sò×ûð±û•ºeóŠ89†Cìñ(ÏÄW+y¯U¯…5íO·ñB¶hõ)9⯬âóåý{͆xÝ º–Ÿ‡q)ZGzm°5q4sTÔ1~!õm-ïª7¹é£áR¹ªÕ!7QölƒÝD&˜¬ï/J=ürfEÙ¥£ÍÚòÜÎÔel7 ¤®UœäîUÕ;5ƨëé¤ZCÐSÈëí‡Ð;®ÞZ›z!†Àd•‡3å€úié3E^eóý¡¶j§“W†§Éü¦''h§(Qç»û¯Ö>­OÊüt!fE.PçP¬Tص‹\ûâ +zïw¡Oe_ÌgÂÜz;Kþ”ßʬ•±B±èÔÙ))•ÕGÞF[ÆJFÀ…×bâ³ åº,‡&\úrÎäÊù®¤º÷fÚQ®JÊ$XÀâþµÒfãO¯Õtª» Ìêír¯=?Û•%ӊà¹bIˆŒ…¹8è¨% ¹Ïý¸öƒ¨+‚òÖûë"W56·†)Ÿà~ Ôç“ÕbM Êóàs¯©ïÝ•¿_ZÖ«”šöº¥¤ÕØv'ÏÁ¹` ÔM,©7ÖhŸ,ÛGzÞHޑõýÇ ²÷aå«ÖÔ²qÑÐQ™Ã7.p_Ò˃Òçš2/9‹?ãU PµÕòŒô”™=™[®{Ç|: ¥Ò/W‰®H¶9ËqѺÚ#Ú‹xe•öZÅ$ßp½k\d¯§~b$VôzÅË+&?s0#ê¬Ü?–ܞú³¨Çl¶ÄÆ* žfÆE¥_…‡iPmDËñòUh߬”Ñ/_þZ=xAr`û<Ì S+â%éôI8Fõâ) š½¢¥__I&ö@7e )FgU´¾à¼œ)ÇjÁ1XÔ3žÊ¡þýþ½fê³½.G—íi+¾©A úìeȨªÕâAÙÕ`ÙOÛÓ`©w{¦{yyîó¥Ý ]ú}Qʖk‘ªQ .¶Z¤ó)•R٘2F“UZ{ª¯RÜ­m í_Î6•]É<³¥³OWðÂá8ґËqÌlÂil“,ˆ©gò¨õôÍú—<ÑÙsUÜzòɒ¦§ë"¸3G¸ÝpEwڍæL5.Óðì-@ø¡ñÒHÉ~]´Lm·Vù ‚’ò÷_v.l5ñŽ‹‰Ì'ÏK՘‚‡ßuxí#/‚(=†Ú–+ŒŸ ÷5¶05mF@mŒÆᙲŠpOºó);Ä)OœÜEö¾Ûáüòu9¯qÙÖÅ3Ègú®!¼·0=ÄÉUÅêHÀt÷ËÑèd  œ+Õäz£Ùôìø兽tÍʏeuˆvPµ¯Þ“Õï¾[H 3Æ*Cez’4Œöm¿ïf}”'T"©W=ÎSûó õª”žÝ&Ÿl`Nýr4êKÝcßàj<E¤ +Q”oÜŒŸ´‚¢ïQ;f6!k'QJayÅ÷»Ø`¯a–‡dËÎǽò` +¶n¦™fÎîé÷ñ®5O`¯'ã‡]>3j]¸ªª‰ ®ÉûÓ:I>99j–b$3ËY2K-mšî̕1+tqC)bYòëOm?KŸš|£îP{Õ(»Ï'vÝÑ{” +à!÷û/žf6 ^aü÷ÆÓaÏ$µW•ö-¿e"ÇÀÖG˜ÒïvaªÙf»¬’Ô­•ð¥héˆ:”1T¬Ò úТÍ[`þF§TÛè;McÒ5:•â“Xï°_í¦ñX2c­KH#¨ÑÞ^TÞÝ^]º(Ⱦ㬝¸ÿ¾î캫UåO+Ký_ý«Y-g=Š–¬½Ï +¬ÞìLÈ.ÚDt}×S1µU9rIQçå]uêÑø—Þ6cÚĆofž’è´àIW_FÈ^„çæ¿Ùv'­ºpÏPuÓÃÔKuÜ_[—sqÅ¿ŠèÝ»øHsKC§8G¶w”`èŒúÞ$WYïç¤ÍÕ` +¡‚ì$¥¾â´tÜ[EtÒäç×lÙzð¡º2WM9Wó –ó-æ!Ã2Ì[çVºÃ&÷åŽ;镨¸År£ ëÄ%'ƒtí¬£Ã:µâúÚöì ¼sx§© ]¼Ún1^)œQ,v^3±fI@‰~󠴔¯w$ö"Ü ÀDŽ¿Á_œMo¿¿ËI¢è†=”ƒgݪ&Ò·ÅJµ_Ë\œÞb+•û8š´”·—³B“ÝyðĹØÁ[­µÙç7T½®ÈÃXj¼É¡a˓Ûsh€ŠNµsÎ8: +nXub©¦¾æ·~8†koO¸ýqþhVZj3«·p +[{ìøè˜`7D94Ó.m~ÐHîÐN t’JP=t µØ„'^î_جùæíºÛÎÇëœÒrâõ¢gƒeâ[ö¼7ÑôK>®‚Öt2ÐÙê©fH^=óG½ïW?‡›Æd 8hYßÆò›Õ‘ñÂYH=Í\‚~†زj¢+ð ´3õVé®*u²Ljìwn\qОèØv-{rÕAÔÌFÅÊ [Øt_U§¼ZՍáç좥±æé[(«¨Ž®¼QæÆbûÒTcÑv +Ü'±…=ìg Sx5iqJV–æœ[hÒÏQ»,Oªnâ÷RH*MP.jèìŒB'³6D2†~¨¾ª—éÛòrI<^/tj}wžr‘-¿­Ã]têá-’{׬—ÆðÆÝ·ß?ï©57t]ÅÎQ>?Å¢ +~RÆw¾¸>Nû…š¢çüØ¡³B?+· JëGÆ +ǖÀa€`òõÍÍgT̍™5ý5K´‚·ÊøS0®šó|‰nºú†R¿è£º/Ô±FyHwÊJã¡$ãý[ó³ãJéd›n4`\–ÏrÅD–‡Øo­ßâ˜I[wOõ}”h¯o;ÐTkê÷«1n­3 WzuÅíx¿6ñC¢ÆèD ‘†³ÀÞHÃ) =«åé7—ÂÂ6Eú­¥QM Ö|s²SxŒ‡jþVlmԘ3.8“RÿÚè÷¢šuån¼è»ÍZµê­‹_³…âôÇ¡-ó'¶ÂÄí¾”sýÈço£Ò.ÁRAÓÕÖâà53ŒöœÔk÷¬XEQ¦ÍÝ`êÒÞ:q>•›IAÏâÕêÆâӌѕÒ)ÔVk-wEzNüÇbý3óëa•\ënÐ aXÚS†Xe\ìVnÁlL_ôû<õڛÁôõÓò>køPQå%][ŒœRQí +h)Ïä^É窂‰íÁú7”6ðŠç 1— Yôããّ¼²ßη—ijÊR_ÃSÑ|~.°ÌÝýzÚîWnB˜éA§§›»>lÒ®q%=\—/=¨ ¥7ŒSæív¹ÐPùsZ¤ŠûùÊK}µÓûjÏ#˜øV>\ØÃ*sµºuüO>kÆr* pV´ÏDOŸd«(Ÿ%^щÞÜ0³lE *'Öol0w_ZZFó0ö…_ävT9ífjêõŸnª>ˆ^ÊeWÍIÑÝ 6T”¾çýáÉV>^°6ÙÃŒc±žùüʒBpõEf³'&ôåПµk³´FˑÚFþhOí^ú¦Nðžc—ógÒ*íÇB÷,nbÃn¡óޒ´hȦ_v±Æï•_éVóŒa–fÔW:à²²Jw`z´́uCZª䊐6…NçϟKÊ-óKž]þ¢5PâªN t±5®ŸÉ¸pûãÄ"gtÌdTV×Jð?x®Æ¨ŸUyË&Kš«öf@nå­þ¾/ƒ>ãŠÉÝ3µ Â{)Q¹üijþ)Ôê¦{IÂyÙ0SM@µÈбsh[}¸(})3Þ_u¥jAZMm€f´žG ‹Éɀá+FÑØKñÜ:¹Tê?-¾Ø¿âøï'UN“ߦ}ý#VÊ#„W¦À_¶Ü{_œM-Ҋ¯"Icu\€Ö/c?!Tß 1ç~uõºXÍZÚh0@óu*Ýb¼<ëZ!iwË­ˆùœöÕÉèPøYšol'î1ç„ZàÙ¬·ŸCÏ£AÍÃ¥vŸ™S3š<€Vï²r^óû,ƒN]1¦wS%'YBz¤8®î¿"~ʈ“`ÝíÓXÆ~öSɾôƒN¸?6µî3´Çf¨«a.„‘Ùçæc¦åO¸Æfï{7:/gê\[{vå +ì=*-Ñcµ?0JòbmNF嬇gã‚èæ>’º¬…¿êzñb TBcI|ξæ/NbÇ^Lڇ¤I½; ÂÖRêMÏM¹9™"7ÚiÊ ×E\Å_‹yú*5OE×Úc¦¿YöåxØ´¥R˜Ižÿ¹f5­ë’šW*š!÷2^dB¼oÁ;³_u‡êŽÅ²€åÁ’ø´ñêEˆ"÷>‹a.§*ëwñµpæ„íoÊäšU¤Ùêa_alu²Ï™òøõçž'ÓÊÖ*U‘Gŕɹ¥ E| +oåc²÷jÕ¶&L:ÞÔßÖÊ%X¸}’ðøúp³º*þb¢~WŸD–/š|¼¤Ñói\ÐFÿ—˜V‹Æµt­ß˓º0ÅʼnQŒ²Ü™Žª±x &ã~5LM4ZHâdÄý Š:qwï|c3[é¿ã9SÝ\å?–Oø5µŸJ6m úH„QàkŽË GuÓ)>6fƈ™m¥™Xg~ˆ«uøÐx^ÒÛ®$ńuë­ê|ÿ¥>µ„•ý¸}€Öޕ²LÔP½0Ñ:sçY`én@ßÁ–›ôŒó‹dqñ´U¿”¬Ñð +’ó7öù‡mò ô¥„ ¶Cšç+$‹wúÜ;îÜîíWµ¥àEó‘@óvG8Ž_þ,a@/D±Øí>!y·\è¤0‰ëêԕ3ª>A cHÁÒäg$ÌWñ=#äl9uäq»¸›H®ÉŒ²ºÆ6¼Ü‚2Jî<ò@Þ5'é#ÀՐ­VÛü¤³ïEMž”ŽŸ½=4ŒE^r¯~È´þ"\ªcWd¤ßÙÐ՗zSœ#ّ1ƒÄÊiyC¶EÖ¿ÐË°!æ™dÒk3œkÅWÛK7s=œnw€ª-YÞMÃsö¬¢m¸%w&·Ù~#‘Äǖ´¦ŸBÌõû¸½´3T +¯«@•ÊìØÔÔÞ¯ÎIJå62ìJA§¹”’.Á¸ +_+w_Ùúý@Š½ˆÏÖV´ +5—¤Á¹ë4’\pK"/IÂ\^N_ÝZ@¶È%wb0¹QôêsٓîÈ3ٗ ç_'‘ÙyõJ ß~EñÇ]„ýì(aµ³«œ¤ãºìJ´Z=ŽZ\6oŸ -y•{ÏLrªúùƑƕ •Á澛V•;'7·•-´ ^îHÆüâ“Lï¾Ýñ¬¿’FCÀP»¹6Âc[•Ò›m팝Y_(IH`ñQŠ sã¥rÜäŏÈ|Iäè…,ÁPRkT. w›rÏo,-M1‡»eký^÷—ô҉ULÏ-C« +4yŒ4îT­pdËÂÜl±jœÕ Ùj>D\^1j „¬pò©’õÞÊ8ÜÍaP™‘_ˆ6Iïbpˆ8V®¬µŸö¿ôª”ęZšEùÎ­ô +­¶"ü%Ìñ"#Ìíª‰%y’®bÔ|¥æðn>[}DíK` "£ÅÍ® [qݑõýìJë•_O)_¥Òf~®µ¸À{æêR,¨‰]:Åá2zkf§ÚÒ\zÚ@»Úý\‘¹28zÛ¢ê_DU©\ + nù‚®3K=b?¹‰'ξTŠKµºùTÀ] æSïF‘ãáËÿm Vª¾Þïs[O=‘'ÏSò²Šwg2h·„ŠîBÛïŸóÐåË˹bxÂ@ì%ÄÚ~~Ee:àëÏq‘½ó .ì[º¿Ö>© +V¯žô—×Y²•2ÔÜЧ äÔq]i“Í2ëÏûe»bóè׋iV¿PõC]šªˆ,Åýªe¨pÊû +£ÜQjä¥t-ŒTgN)=ý)ñɹ§Ï™Xކ«Î ]¾­‰xve…½hÐåªÉj֝p*JʳÙn1ç Š +öÇF lÈ‘× +›ò’Ÿ,žË¡{–8XÖïv»·“‰®±Zù¿ö+ò`õ4· +ñ—'˜â}lº=÷d X:@+łHƒÂZ íQæ<Ê==¢rÍzê|›Iãæ+ÉSË´¹=[ў1×ҊìóÆÄíº ÌF +ØÙVGÞk‘Ñî㏔ì¾VÕ>½œ¤GWq•Ëá`/€Æû©ž>~ÕȀ"íxýiY­§¬¤‹óZ.ðE謨,=×FA!£À÷ÊU*S´ªöí?³!¡åKrørx³I•“¨¶J¢}ÕB5­gQ‰v÷Š]ÍÝç[¦Ðp_êþÔy«¦êïz%ú]Q揤÷Ue94çÛPhŸL,6€ y°/—ÙëËÏèÔngµËïH0ºöi¦žëK.sp£)>¤)çö» ã±bøgH“ +§JXpƒ¡&ë”·U‡ðM»§4lR“±Ö•bãœ-aéCVw³ÿü(‡6ÚU ¥×GÊéá«y¾ÊpQÖ7 Þµ­!â}~G3­‹Å©÷Ô>°`¦êÌ*#Å!p38QœHCýëŽUû,Ê£nçäùâ}6CD/N+ïŸA·‚óéüQ¯|J¡óçcǧ¢<°ý¼°Õ¦žtΆRV€S*ěÝ<.ýËt3ëƺ±Œ4 +ÚÙ¹Ó硾ðÛêz­R÷}›ìuŏôá_·Â­ êLö¬ºtڅ±éíïwŽ?ÑÈÌî¥./ïJÒRÅãŒ&Õʯ!‚ëàÝRPÅÇNܨ™_œÆ'6$ywÆíƒGÎLÿôH£«gÑ*àñ}²¿žy‰½‚¶IY‰àé&ùêã¦I䝓ݒ›¯ sd»|óøtSrÃö,Ë{9_Ÿyµ•qËaC¹q‡…»ü’•Þºž—_ÐÍ崔“&wU)†÷c¬C^zk·°Ñ͑5´¥j7ÞؘÃÖ&7ÀÔ[e>Ôo+#áÌRފXÖʐR£©„(¥sçdߔÖɍ›Dn•ž_äÖ*C#MŠ•¸npÓ*gPÍÔ À›ÖίJQ‹“mŽzk é(¯XÅ£ÔanBW8kY(]ôÏRîÙ²FƓ°cnÿ=s¹r¾²k§G¿ »@CyÕ#p¾²®”š¶Y·Wn‡Ë»~ãèf<äd =—D‡^éå#ÏQ“¿WLÿŒµQ¦’¨Ü,´ÈÉeþ:Õ"‚Æqç+,,I/ý’ź ÿf›¬Wó#'äÔ±ªkJ¯xr÷èÞѬª•OFÐ/‚¨:Dû {èçWçt/WfÅ.J˜ÂˆÈijf–ƒ’k×õÅE‡§FÛ¯ú‹rh`#òQ†F#}QŸ·«‘žýxºx-¤®Þ{ßx©Þ²\àOgé¸ng¡×tí9µzÆs‡%æ§/ҋqKŸ;ظí_²óG?'KÝ_ÂCjÎìÖWN¾þ\¥f¹ÚÍýà8XàV]$]ژdªcuºéB\0mY:<ˇ æwh-«ê‡s»&!$„ F/eËoA­¤—;–ñ ;Ãn 3Dì§ý™¹º-×8ááh±ÝýLÀ(Çb9§Å²g´&3\:G]=ßH@O›©¢nY¢îË«¹sÚäŒwˆéÇðªcYÄà‹Æ̵K¼ûêÅ [äÛ¸< +!ÖY¨æÝg .oßÓX¤\fçý|úBÄʳ¹uu«L¹IS™]±bÍUëeuôÐÙGA?_G*ànZCå·¥ÐÙQ5¤Þ÷°ðž ×¹Ÿ_O9ûùÛË_k℆V÷céFt„i„ˆÃ¹¶=­HÕ>A7}xܗùAiۘ­)¹:VŸ|f³¢+ÃÁ¨Â(¾4$0è.’—TãìŠé¾Í m—‡–Lz‘§}yæH¯Û²%zTÆDú93h9)ŠqãYñ!D#p$®Rq-ìї ÂÍ'’\iÛÕ[cÖÁíz¦”s4ƒ¢ô=Õà!KbÕ +iþ‹r f†oÊýÕqÞõa³ 6&%¹·EÆfa({íýÈÓ¬%ŽÝ&¥å{ÛR×5˜ŒØ{7þl´£ò&Iâ«äW(Ž›2íB{k¹pQ_]1ùÝjÿ2…Z¸&íuƒÇ†Ö‡óØö Õ)Á!YÆDPAWö@yõFZí}Si‰½t›b>Wkì ièW (jWZiם¤ÕÞ=$sKÏÌÓ1\‡îÐ ÇÛ¾ú»¡j u®å•êk5p¨Å½•e‘⪠Åç]€µ£ jƒ…¶\5ïΓibä´hO[îb­Ä|âû×d?`Èm¤BaêÛÊ¡[“D‹˜ o@öñ×dôK éP™miÒ&Oiè.?ÍvˆQ {<;õ+6ÈS7~fu¼þâSà ÙÀ|¾ËÌt¸‰VY  V7¦±æ¥ 4D²|ÝÓÍyZ-N¦^1xÿܚOU r0`ö¡õٗŒò +endstream endobj 26 0 obj <>stream +v·” ýö"ý1±< G‘µ°’ly‚–¼°9x.­dÉúŠ.G Éóü g²Ð}Uöýñ§Æ +óCpp ÁֆjCäÏ ºcúiÉ.dñMDM‹õ¹ÌÂ6;NšÈmGvÌҎ~‚ªå××q@¥¿¢ã¼#- (7ÚÈa”ÞO{“5·P‰$û"3Âu—4ÿWÎ3~ J.OV›à4› ûÌB6äR»^uG!l8ßÊhëãéDôìÊÒ.ܨkbúH×YmÌ~I¨\öºEóƒ$Hþ  ï‚Gö–ÇN’_;ò³ógæ€iÖ–Óþ]^|ŠîBXËž]s€Þ©—3~NÍGØ8%´º&çAgD'ߕLÑÉïGqâPa‡|A;¹-IžŒ?Mó~nŽSô±ÕÙA•þciĽ]Šê”£’xQ'´“uÈÝÅ+*tVŠVRu¶Í†ÙdÚIÐ0ê%á‹âI‚xúÊ+ÖµMâç {á-`iä$»óç×ݺ?ñðPo ϑÝÿìŠÒŽÆI ۖfMdBž‚–{1ûxrØÝvàD‘Í­c.Œ.œC’åýÒ¬^Mwœ¶‹ý¡ˆkûþÕ7ÖµÛ¶§ÌCAœ/^‘§ËÑ#¶ê/@{Û‘—|ns¥¬ã3=†ìK6âUx±ÞæòPn¬•MÒÆgÓ>w}È׏¯²0µ™{[*Ýžð4Aý ®¦Â v%Dã<îŽñ ö»#6–ÊBêOMäA1´ œ7ÞïÅz ®-É8|h¡cïxo6 f’h¹p˜ÅCÉûmIû¸WÑX)/|5óFÒ¬³}Hr¢œw³çiŖùIÿO\BÞk®J¥{LhÚë™^!Z‘쌞pä™%X©ºt$ÎaØEtlEÈÓ^LMýO5Yùµ2²&ðcm¸s³ZÑÒž¯ @Ù#y¹y25¸Pø¡€ð¹q†ŒË¼²;TÃAàp|6'nӈögØÊnÛ¥ +s㧧¥u>Û·ñ¬"o”Ä®œ–×G¦H6•é7Å@µò´¸ëË4ð~\À'ƒš7]ƒv윗¿¹oËëw· iºÝîçæüË:ëÕ±¸!µµæèb–ç‡zs’Ì:R%œ"…c3V©­ijãgú|B¤j„“ÀE·¹ÿéÉ9òŒL4=hG o£"…Öº«ŠYB·DU¼CamO º°ª¹bŠ^ù0™I³¿w#•Ð¨9”녝Šûû÷d ,oˆ|Ó¥LlØ]s^¼~ +vsÀ"ñ•êVýèäfO9c¢ÅtŠÜ¾ƒWt‘ÁBñsFÐ~ºžUãÐîJ.U~¬þá'qýñÃä„{æ÷¬ô“ßE0±2P¯Ö5¾ð3F†EgcêÈ5¤FŽ0á­8åt$›‚ÿ™ÒÁ÷4‡ÍÇí-쬄6§µ;ï>²#ÔâWýÀQBWµ›L‘ûӑ‚ëØ†3€_ãûfšÜäd"X£–îÏ@Š€æ³$lŠ5\òlõáõŽï–Øýìփ¸ YJè¦xxnLl4˪Wjý®Ç ̨VM®°˜¤ÏJÜôµR4"UŽhq¼Ž=M`ï`{èήí¡Èqýe¿ó¡#‚ˆ6.þ’Ø„ÚtlP•Ö#ÉóÌw‘o½r¡ê©(?L㯯FEQxv17ɪpÂM_¯7ô8¢‚![JiۘõÎF´œÏL‰{j4˕º¸¸|%>9îåìtAR‰{u”Bš+½Ó©GH-TåcÂüºôgú»ï+ñ<ª(R~ŒÜ|ŸøìV”z¸ØŠÂ[N厏åí«0¢ÎrÉÆd…Êa>²¡¬QÊäy3Q(ÞÝÇ0$u¢ü…—k±ð…q’½i=3ø“ñð2¹Ïì3à ²Ô—EÕû*„})ãÃZ”…–M,f ân=ÆwC^ çVGpǤú‹¿É®%,ѝ®§u‘‘ñ‡ú¤¦Ê¤¥µ¿P.÷rýW;¨KRÖõwv^ª  -Òüi4°Éñÿpt•kªC1ðY€EKK©-uoOÝqw·÷¿pî~»PÉIf"Ôj¨mCìës׎1²Ê59%»õýÒ©_Ój.±Ù¬ìô§9Ó‹mt”H«íÑDx_ê6\üRª:Îòihæ'Û<ϏP¿¶æ"ÈÓļG•Zëûu»º@–Tüƒfgú„a#2?2WrêàPHÿR¦d.ež®XájKJ3¹>&+Ë/ö÷GÝßȯyk¿kÓQÇ¿N»û±kÕú•gøÁÆ_øy‰9¹m†ÚZ°îɽØuÌTzד^3¿—ÍY{ˆ·”’°°óÃcè×;g쩪`8š» +$qvýCý15ú‹ŽÕÅ]ŠÀE',Õ°£IgIÄ;­gHh‚^|i4ªÏ ]{@wÎL¿FÒÿ´®ª¥23âRïe?NLcúpo– hΏÝ/m‡¼q„5§½å¦QÛN‡³çÎ:’ÞÛɪÍ;0÷ïŽå·‹'{5Efüšà[–-Ë?E½ÁPÜêÁ1({·¥íŒu>“i˙Õ¿­…ïsýü”y탈|þ1~Øt[»ÚuÕ¤¶ˆ_^øå ؐó“έÒ¯;wD'“7m|âÔðìwx¬z,ºÛnÛ_â™òT^5ݸ³À¹$Q׿è >Ëåƺ­‚ÊðU^щœöL˜<ýÖS/·xjÛò&•õ˜†½Ûø€,¡®”Ù읳¸ +@yð¤‘ÝtS8`py'J´›$¾^Àí |üuÛY=t‡„¯ 4ëƒPå.C”ôYV˚ã×øïéXMZa­ *’ ¾VIا'{“n=LÃv¶ ÎV»«VÄt«MÀ1»5…_·w_°¿Š‡µYׅ/^íªÓa%"©TÃúpÖàžvß®Ì㽶Mþ8ŽE$\4{•ÂSh‰ÖƒBëøòÕ_º¹É- ߌójûÑT®Š³ÂuyæÖKéOéŽ1ܯ c ó÷ÐRdÝq3O®ö@ÃyèãÖ£æ ò=DÐ¥šðúô +‹UŸÞì®ÞÝ×çcÄ*¥Üh1ÔË+v;Kº‘v®7'ZÌ¥¼fç&lí¦¦Y™¿¬,ûÒåü=햜°"¿¬Îśy¢,iÒyBÌ,ÈX·Ý ~õûš³ê™º¶“gCÐw–Yír_ºæ®²¶ÍÛ§Ýþ×dá-úë›Q๒ÝÂÀØW֕í!iø^Ýv*µÙ»¾!Çz¦½5?x5}äÓ6î£[úi?¢+殤þÊ]ª$ËëØñÆÌ1üåª{æ?ñ2[©¡N‚´ÛsT +ÝП¨¤lsׅ\÷ˆx@é¦R~3«¥ÎiÅߘËpÒpùšÝµÓ–ÝÆV$=°¿éˆ3y’ÚÞv÷õÓvß[ð/ËaƒÉ¢á­ëòZ2?ò—gÓ0rjPð ð;Èq•ÙxŽ )"mz•ƒ™Ãõ}‰9•õ¯rM7{q¯S¦ ×J¬¥¾êø«­ÉÄq9ðÏPáolkAغÎ¨½à²þ¥xH}¡íy÷ÁÚFBeœé(tëÈQÞßÃhºo{wž_ºfs<ôWròKåw%‹§œLd¬ z­žõ«{ªòFýTŽUÓ\jåøò ú³«ÞwGÈV¯Ä[Á#Æc¡½Ÿí·[)^폺"ç‚ut]ƍè–4«·/@úœŸ4‚ײ½ä:±2ÐVÁðžÑæÖ:vü<ë"C8ûa¶€=æšùå™ÆCgRv—ƒ¦f>J&r²W[÷ÞÀܺ—»ŸiÔµO¢èÇ<ÐÖM»‡S{>3‡V¡Þ²lsu?Gõ¤ªÛɪ¿ÞAºC”Í5Î5À»^õz¸òŸ‡[Zr,{4¨t¨©˜Xï7Qtسþ‚ýÚ«a­Æ,þs­ºÛ›vß_·[ŠÂb»¹VƑ™;¾æS~¥tÉèÛvðKÞÛ¹ÐµXi‰Æ€¶‚Úµ¸t Ë‹: Â—Lî“_"ú¼ùëÕ<ä³L|¸_ìQvï¸Õ³©Sø‹(û>{#pÂH ž¥Z”ü~¹Î¯ÓMQϝƒÈ{å +_Úó‚ÂO/#†5Îg¯X%gV]?ۉóüØ ˆÒÁæ*c!·tèFhò×¥YfJŒQÒÌ×óí†çûD3íÃÿR„?=äk*›îôt-Úù¬]€óÇr výò*gÑÂR :› û€Ë܅R0T¬Ï*‘'蜶à$šÃƟ 9ڐ?àLŽÆ +¤D9õB ÿép)Ã÷º’!•±¯=/«bâÅ ¸]ÙÓD®jZðtƒçF?ÇÊg¡Ç•ÞΫ©ќÑÁ„^ :G z HÁtv‰¯Ui‰ç×E}ÚAøt§¿á +ï–Ñ^_>ÑX0藳ÕÌƗÞ:Ô‘½þ ×Ìöá Í®6Ñ[ži!}+º>›-êü7†a@mßUbs¹9mV®åVùæ­ÞùXµªù+EdZ[·­s…vÀìvºÇG׸J%»aÕ'!|žT¡HgÖi,¼L*UѸ¶¯Y1ö!íº­ºï^›pUy ’c÷Biýû¥â¨Ë }=†ÄrŸ´øßҚ÷½?#&4‘‚ŒfÒ-¶­;\~TtëX‚£ô-QË[Ì¯…{/æUf/Žµ(w‡XÕÖ5cØÛ2Ø¡¬ðZÂFcúÞ§g•±Õ”Æ~&0F(jvçDoÕ3íÇÝ k¸nxÚ¡3úãÎß|ï}z¶L ¿™¾ÅxšN6Yta¤ëå@{á4jÍ%‹ç‚uLíB\¬QŒhM·h°ä_‚X~ߣ]ÿÓ=¹Ö Ýäh™g ‚Í[Œü |a(Vعےk; +õîÃø¤ù+E€ÃüɍB¿ÕÕG£ª<&#wI áÁUJ՝íޘ] švóôBpÜàxKo֗¥š†ûw,ýðîíYbîƒåXs½³÷Ši|ä~ ƒût½$ëë;ڍz¸ZÅñžŽô —¹î}á‹͸v½ƒW[÷ÇöÉDèÏ*ۍÙ1/’¤o¬vŽc-Œ»‡Z5…¹úZ£×ògÒÜ\õ_v ]ājù-`•-fðÇÇ¡,j‡Üzzµ]rFwå>´6I+Å0f?¼m uË|Y¾WZ¦]¯Ñ–ê›a÷Ñ:ÛºCD¦Ÿµ†I…‡Aí·v–¦ñ$zn†ûnýð`¼;~œ,ph—Ƽ¬¹ú[ÀÍnè FÁI¯ß_Vg4óTÉoîò·âBÌÚW#x©ëSIy.ð{ÞQüÜZsgö“·ouC²Ù¬ªß4ÓWÌˈœü•J’ ~zJ¾?ëlçiïDWZ‡>nÚ¥Ûٙ¨évTãý£»ò èQ™¿\™:Ⱦ¥àíMÛ?{x=Ÿ+ÿkИÖ)T˜gŅU#1l]2ŠÑ³.±'ŠØõFh|fﶰ»¡_…qhœ×p2Œ7!hûÅÂXçYž Û;ϖ‚ñdZÇØÏB{q]M±×ûßs‹üt)¨\7?ãu:™g'KóàÏÝðÙ°ùðaæËtº×Ì?iÇ÷·$ÞSºV‡È^aµßPÑPP-º7Þ:éáùE¢Ÿ)î&ee” Ä^`Ñÿ­—m¨þÊΓ繷7Ž=à»ëNt¾Oäöî<<ƒªvèx±Ýl4Û³ ³ÆaOàyÔTjYkîjŸ‘8°¯«?ƧÿÀü$«ü I¢¸_Ù}ÿp œ³ó‹7È®_"€D°§SgÊúª‡ÃA©FÏF0³ý§|ðŒçÕÍøK0êíªgÆy®‘{$ñãUû’%ۅöE¯½ë¨MaøEsø|6¯—p_©Ü%xï*¿t÷ Ö?v¯bïÃÝü3J€$ÞìV%äÀÅÓ +¹=&o›Þþ¦#}jx­¥µáj(Kâi¨ô÷Xú^ùBogCGïÿU£2zíûÁý}33ƽ׻qÓú¢Ö¿G:mïóýe)qei–{Ê"àÖx5~vWzªßՑñ·ÔF/퀸wŸLÒ×ï\Ý0¹LêmsnèqÑüí“ÛþV‚ ¶ôLÑ/èø£‰f[³;Áþnô@²Ò›b8°çEc~» †¼u@»ñ`¦¨3EÐÙêQ¹Yç֔SÕ²}sªŽ[ΞiÊy2Q‹#±ú¡÷_ئµ.øú6 òÍ·q¨ôçÇiTÝ°©ãŠÀ5_­Ó½cfåHA Z}²±ÝÐÁµD=ÊìƒÛ + ÷˜@?­®.º» ++!7œl.–ütÖ¶~ÐA3ÞáJÔ'ƒ`Ò¼Ô<½Õ‡ÕɄZ*l]Ý9§Â½«=ÏVÔ­/dÙFaäfèß÷µŽåN’(Éì$ÏÈ$;ǕBTÙ]îÊþµjXCuõöç¨îj•«ü«²ÚÒ#\9þt“¡ŠhZÐ]0XUéÊÈÁäóþ2ËDåïÏéùïU«Ó¶c¨ØM¼ËKjL=Ì{k~ÿ¨vÖàÕu µ=kÀ3|¿.ž¥Ú¸‘¬Z¦iõœQã™ÛyØSä>ËX ùºŽËõTRŒ­ùÀ¿H󇎡;j:ðζ>ÞGŠ“ùu‚ÆeBÎRûx䛧q'?è7W9ŽTCæÜ×o<.æ -Öz3‹íøE~îY„ÚÔìÒYZã‰*/ø ÿ¾ý‚šF[WÎâù,F·«yD{õõÙé³síOŠ:zˆø/X_D(mÊEcê<çzʒŸÿ5‚J:ÒeV3*ð¸å½–ª/«4n€*>–«àoaPï\2K8Öèô•çÃxpoÏ\aùK–·K1‡]³T²R‡u«Íÿô]mT1‘ý78–oã€2Ä5å0g­ÍÏù]6kùs‚V2f>AKzÔKɦÓ݆s6Ö¢W™ß²óÚMŸú¹¤f f¢¸1”¯“÷Ý+²Þ„;1¹B«5OµøÇÖüûük`÷,Ä{ÉÝy¶Ü:êUñu7”Á•tëP­¤/w¸×¿Ž¬ž=Öª¤‘çï¸ÕÌxlîšßhÖô]2j…Ÿ ëLÚÑú._xzhûûü©T[KMù€›ûþ½TkVl nᩚ¿¶çL+Ï­æ÷õY~V’6ë]Q V-5_O}™&U¹!¹‚á5Œ…åÕgyF&izø¨ùDA£Éo»XÕ°ëâ>þI%q“zq£;}²E‚þ´ˆå}¿ÞQÞ–Y÷”Ârß2m¥á}½ÅlÐòx¹¤ÔNƒ¨[”uÄʋÐ5-DŠVÌýdœˆ Ð÷Ç{fÍHö—UŸØë|ªe]¹jõ{´&ÓS¬· Í"ØÅIÛñîP_F£žE@£1½ë‰¡;+ËbéîE}Ö®ÉF÷Ô<ÂM¶ÅTܜ ëÜ\?Î'[?¦Ž9N‹?Ÿfn‹Ñ]p©oÎÉÆÁ¼#̜XPÈÜçzÕ"ät<õ?-û°M"St¦A°OÏ6iO†¦ MŽb.m¶Œé¡Ù“–š«¨9˜jn®ùÏ֞¿þ4K›¤YDè4}ûöÖã+l–´â ¯{Ņ·1g6ïhÌ¿Æ]ç·¸dÊÄnMØñ¤ †§wßÜ T2zO:×ðÝ5«ÆtÊm‚zïÝ2Kkóõ³4Õ•O%Ö5³ØÅ9º˜Ÿþ/˜uLùÍi­Zë‚¡\mV©ôpp–VޟÒ6™E¾Þï˜7¶‚^Ç6%ÉÈÿQ’ƒ0Dę@p”E@Ø/<ÔqvvûnMŠmV3Ö%u¶gÑGrÏÒҔðP¹Z µðê¡"9^s5·j·á.#½þeHöîœu¸ùTÿüFI²ú¸,¶Q[K†2êD¡?*Xå=Õ蕒ÛÍû4aÌ|»c¸Äµ¡Ö>÷#áûž6 ä5ž6cØ¥[7ƒ¸ ð.ŽãÎ* €ÌÞ¯î°`¬Ûù¹Õ˸á$fý$RfQåŽá½…éIë¥êLÌY;ìC’¶O1£Û›çqٟ´¹‘]Fp{”X-W,€>JGPoW¸hZhYþ&£r·œÐ¿*®¥4/‚ç4ó­SšOì=Ím€ždCWÐíŒ<²G³;`ÐÕ^²×äk£Ã¹+þý¤Nˆí%ŒOôÍalÚP{†ü}µã*oóï¿g_|w3wt1ã +Àø{ûSÈIÛÉkƒGhÄíM7­ Æ×££Uìkh´„Ï;W¼•?Çã =.z`]²›â§®'rPjмڝl0ê·ìÏnžlí<µ- œ?°—”šFqû+vÙÞaýæ‰ý7Ë¨à ±ÛíËáL9ÉýÆGÃ+ù«?’+î^ “êô`t— ®ôÐ3ã¿&ք»7Jµ«BÑ£‡à—³!½ã¬¯ÝÜÕñÄé ùЖc*½^Q½ÒlžíØҁì–ϲ%ÿAڜŽ'Þ²»Óe¨‰êÞaÜZ«ž´K›rj¤ÜìfsHSóM³€½ûà—¹ v½×׉N†ide«É:5 +ÆÒ%ÊnÔ/H~þî™mäÙ÷zgWñÃÎ\h½8ì”îøHôȁî§e})ÿ%×½eTö¯ì=j~Úÿg<˜JÃ1•?€¾>›»E<¨"8¨áÔûl^§ŸWoAO:·HS;˙énȇÛ<sÞÏr•DÇÐùöjk²·ˆÆÔJ’$—î¯L|Ø{z5Âü¿Æ¶,%ÚIsëøx뚫w…²‰paŸ!ia¿ËhˆÞC`TZ—zí$¤å‹ä§¢†ëºû“$x¥ƒÚa/ôåã>ûÙïn碦dy;œ–߬ڕ`—ÁÄûâ€îí·œ³ÂoA¯£Ù5"¼ÁÁ‰$æïóþ+¬àÖõ#Nõ*hÇké­£•š*z‰¬®½øM–ýÒ ¥Vî?óêo„ùù‹:މk©øD­î­â5ƒ¿iJÍPB~ æ0~—6(áã)ÝðÃ}›~ ¥D€)LýÁ¥wóêkð]ä¸F5[·Ž\±æcB¶‘Îì¿âX•í¶ÜKÿ¾‰r’í)•ŠÝpn­;üæõÇ:mØçemïõ_¥O#@sEŸ;õ)B5'¢l[‡Íh›gýdŒK÷‹U#ä³ý‘_åÔ+B•)ôÛË-Õ×ÃÛ17;Òù\7dëÑJp}y°7Ë 8'’çýˆjc@>:`qžÕõêÕ· °ðÀ =¹wÌ ðo\…œFöҋÍõùÉéáý8Åd/õã¬FÇNµž‡å;úàÇ´ ^ÏgêíÃʤ+PÔÇ Ú™Œ.á÷Jⶽ> { ]ð’Y;oi׉Û9á@w1kXU¥@–ìĻȿ‘_jOŸ‡j?+ÄaÔ]Ý0r5µµýDõ<àŒ/ÛƄQƒNkÑU…rÞWíÝ0J½ÙRa§×ÆY£ÛÛr4®–ä#¸Nݚ?yÔ4d÷G†Ýý ++ßjšÆÅ¿¡ºÁ­ê™ÝýtE.\}êæD<{UÇÔ|w ¶Öé›áÍÅzº¼6ö[4v‡ ¶ +}½‡9¬Ÿ\yN$µ±µx3Ò/™¿dßÙM~û‡LïÚ®†7ïF‘G6ŽÌáyPñîŸKyä˧y3Óà.cÛvJ+°ïót>É"áÊ% 0$.{*d¾ ê5Þ±<(×°®5~YC[Ì\h4ùõ 4±îŶ´ ÔÈ֓ ¦\Æw"&)&‚àlß4Gö”_Ða´?“Ë\'Áe¹_zr!nµJ­? @1k؊n"†ÙÈ~#ùÃÓnzhŠ•%¾sO_ó+áu{¡Ôéüîøª¶÷óD©|/&·ì¯vœ‰iYMÎýl@©¾jdŠxs”¥qbܦâÉ>~°­ýT÷ïJa< ‡‹ÖÔمòØ+ÄÉ»U› ÁÿsÓÛ6<5pƒç¡I o,7yn›ás¡ a}Ní"¨¿SܺayËæ¡àSäf‰u+¬è¸@ õüЛZÎ  +åñ@=\Åρ‘䎲å©ôúVèWsÇ( R>¥Èñ*ãïîŽT_Çñ%¤ˆ¤ ÏÎǽ>¥Mà6TI•ö­<Ĥ<< |³'û\MVçuæÖJÝ®¹n µ€Ôõh't˱}?ãØÞöXäY³M£ê¸8.oÄGCu´ñ.æ»BQ¦_Ü©£GŒ‡'Ôò‰ +ÆVŒ/“nVá׳ögÂýiÝ1ŸêÚáɍ¡ü–¸Ò‚“ ýä0ÿ.;(¦ì¢«™gÏÄ۞ý™&þNi˜>"/ÆÐèѱ­’ГFíkwùX7í~ʋqyJžþΊu;wy@TI¶Ôh6ó·bçW,Fà?²~ü²?áU%Ôä4ÍGaÀQ/‚c›œiËþ’|„r©+ä3˜ÎªÕPöú~žúéõ×nÞ&eèÚ¦Ö‰†ÃQ9áÄõrUtî¿dk¦íkzG͚Žú·£—ß=UëÏ°ùD×ý~y|DºqÿËsۏ·ý[1 "$´òŸ*½È/{çý½úÏs´Ñ#±Ñ?§+þ!=籓®Á‹û¯?âÿ¼§mâäRÜn–SÍ +/ ¥Ý‹·åð܋++³ØŽÞI‹žwCrä¿ÃQƒÔ²sÿ†ﵪ™k¶»Ž•¯¶Z{R+ùV;Ku +©*y¿ö+¬dø=6d—LjêBMK@-\¹«hQ;%GŸeœ}EӂqÁh©Û+:ÜL4ƒŠƒLW +ÅñuXy«· )ATXúV¸i‹Ô\!e;•>ºY~Z¯A»3\GC6â·1ªÞÍ%Yš³X‰ ™í‚qÊ(‹Ô,åôCɆ\lfhïe"N=W?hçȬæÎä/„§;] ¡ZýÞ0Ó5´•ÊÎÆmŒögX´ y $R?™[ ­ß®}Æò|ìÆ^éÝÆJ¿ðý³ø_Xé=Þ¢ÝJäH/ØÓÚÁ8ÞÚ*SZl=ê‡áuÕCE~Ëݸԝytɧ]AAÛ'R"üçÈÕû*Prh’ï´Í#<ÐwJɞ«Á¾ +wü§¥úu¢Á!e ‰nñv+CËWÑÀÒ Ä/*W“¥Ú?Y5Ö]¼U^K© 6Î[¬"¨(d_£òÒº“CüHðQã\„K×ñÕ›ò8W5q9mýÇÐyvî©Öäë~A´r›6ßԃB÷9/1µÁx»±‹­¤¸©tÉAiçw¤ÉG2ôùj•%U½k(²S+÷ƒ¢m>d5þtÒÐ6îÙ`4-&Ÿ¿©ˆÚ84¤ôÁOuòÌ:Î5M¥vÇÏúZvÄh«jØM0c`†”_%½WÏssÀTƒª² +_¬Ö»wÑH-Îiõóûß"®u]kÚÞa)ú&½>õ=•úêØ+«6ɵ2¿;3^ÅÚJíV µ<8îBÃ^û†Vÿ+oœZÁ²i\)kw¼óKÅÎÕ,BŸ~¿*$2¬îMÁ9oÌæmnNÌîø'l묨H6Cc<3~ä¶ÚÙÝiÖ²j½;?XlßýÀqºQ?˜— “¯`¯³¡b‚ x¥€6|i¾7öÏF™b·ÎÍø̨•©®Ûud¾®ëÿq†nt¹xìÄüc{·Ö]¡­/o`hØòwcà½i‘K¼ch Wç`¬GÚ_„DËj?ÍČÛ;/¿=¯3çÌ«:â'w‰ف}«®GäÿõÇ_â؃lØ]£•›f/Ïh²Æ½PŠ‘^¬(æZä4Qšª¿«† ½tœͪ°m»_. ê¾ÙÌ8Øí%Ž¾.ÛFo—-qŸš"à&Ø¿só¥S|)gžÕh»°æÛzBhð)È^xÄ Y|ª”÷xœ>”ÖioPƒO_$æõ ¿ß~#ÙŽz H­¶7^¼ fI(”ŸšœfFÏéîð=ˆGzcl>ØU×Öý<°ô[?×p…ݾ‰ñÆ[,ÈÙç,/jHÚKÎ2¢/©ß“›ZÚfráÑêE¸\}é\±ûè)¢tú‚ºèÏèW»?F€$&ì¿A~—‘~ F‹1*ñäel)€ôõ¼;‘ñþº›êm¿HIU¹ jãÛ.œ›NŒÚoPn6¼ä^R›Šþ9®4‡Nvð·ß©†¡þ<´uaøƒÔå4[Ó½lÍÓ +Þ]s ûǯwÃ&ü!ä·q'Xôû£ù ŠƒÙV)(²ÀMõôV+¿%³¿±ÄŽO˚nuæÏ= ñڒ +6×&§IӎëéÑ"NÞÜÇקcª¢Z´|Á融\ãÚêù°6^œrܽ֝t-©±ý‘BR¬½ëÑîÀB«~VÎôdèu¸öºôýÝ«,ÁýîÇoØGœWRŠNѽËᢷebC¥?ÊƉïDŽÒ£#¦cš·³é¾Å:¯jÊÏö[_ôtõ\8O•Öq¼fyæ³°Ô´Ú¸6qŽV0"Ôatn×ÙU˜4£’GHþ¾ˆv32çˆÄhËwÓñ¨ølˆ<½éëÂ×~ݪ“U{Á£ð›[3*o¸oñ ¥jӉq=¿0GêÞ§ÆËA—ž†é¦*t¾çê/Jn—éî˜åÈ,šÔÍB»CDǑ,ÓëL?àÓê÷šSýËÉN«õÈK³ø7Sh4a‚¾êU\¦ á ØDŽuØ õúØñdM¤cdw™ùí̺¥ý q8µoç…휝֗* ,L¹­Ï7§]9¶œèÔi0z¹z³ùÚù÷n~FÙ&  €;ýӁ#ÔþšÛS´³æÓðʤ´2ŽçÂÛ[xîܒ‹#xæêšËêÝÞ0Q·W{~¹:Tµ!°Æø7JL¦˜h*o]؟ôß݄yœÄ.ÓT %ƒm$(Ϲ¯˜iýA˜‡TµÝxª¢öŸó¢/›Ò̦¼4;%×â£zoŒÒ©µ·mRÍ3s´EOÂAs2–€b—´ñ¥üóªÙ§ýùÓÐU½#{åãyˆ­û¤fô;ÅØAèë­Yßw_¦à/óèoâZÙY‘†}Z×ö²œTÚ´E­¼p½J: pŠÌF‘i}ÿª,µH§f˜~ÿýWû×da‚acfWlš+ÕêËòpÿá×ÅMÿ•º–°A:®L›ÁÖêÁoÇÍm©ÙkŽ+ÞjÃ!K½-uüjøöŒeT0ª ¸ò±|²ÕÖo«{̕{n|?F\.üpˆZ=ê„[G9u´¦ÙÞßO« +Ü0q½ØݎïBžÏÊtyá–Hz.£éØp³½€Ï`~°Q +…›R‹þµóX‡ˆ8ç䪍=§þª…Z>-öx‡>&W×ä×íNÍގ×a"{ :z‹ž-pm[8è^±YØSÛÈ­¡ÿèIbÞҊÁ¤Y}y-þÝ u{/Ï!þþKlN±¸Æ¢Žhîîಙ\›Æj:l:™b6vr‹¯ÅcõKð±ãC`þé@Vù¿,\ûå&1眊Ö{ +¶R§½½þüÚG“!Mõ\NV/a#¹¿;>!ϗb” ŠTïñ•ªN•;ü™æ¾ÍE՝ŽlYÔem†,HQŒÃÕl¤Ñß}.=䬾ëf+f+Ëqÿ¢ìýÚ¤½‚KgÓ\ƒôT¾±^®nëµ6¦«ÖÊâsLCëxIß%D‹¼Ï3Ìôl@ü1ú2¨Öká®ü«ONvö cYK®¦3,¿úÐ,s1ªÉ˜j/¥Á”†Í‡[M#˘¸ýœ/æyÚ؍Ši^6Í»w}¹ùο _ÈC[åu½c·‹ªzS—»þ.é1½»œùzãÖ#Üÿ¥í‚ÆÝ{bëpY!¼½Kmý¤Ööìز7KÐõ>©ZFRL“/ø>KùƝíáà ÍûV_yÙ·ÆhåûIùAøÜvj£NèÂÔ¹‰hÞß/Ÿ^å¶ï¢®Îo_œÖJëXt84‡Ü³|ò½‚™ä«Â\÷òôy'”…׺Öù6¯é±Ý½WWö¢æŸ»Ök—£ñÆ9-$å*KÁyf¡GtÉû¾„Ú^´OÚ~“íX„-#ž3»à3g­à_tòÆàݒcqå/±Øcoáq“À§ô'£¯¤…)›JۛÞ)ëùP[ó0jÛUëH:’VoÔ8Íó¡Ô؏էÁ¶hØîgw~Ó×9ÛÎ[™Åî5eG„LÌ0í*v夂ÖMKŒm•3¸«=ºúý¸¸8 +ª8Ò±»½«_¤¦ç2\1® ýôÓÔë¢'úö;UaWÖö÷Ò(Ī÷3Z •þ!o¼»¸¨4Ô6k™I‡åþ€lôL>]OR]~^+)± +EÊI?Ô¶íHÙ,yìnNú€óŽ…Џ­ÁÆÈL*܉öFÅ^Ò›ÞLòG™µBŒðþ{š½Ãá‡{·×)_<®lj‡@lh=9|ÌIÑÿû¾îq Òõ¸mUëF'7‰‰Ë»ÂŸ êù7\žÌ"€P0:U¬U÷‰…ã&òÆô²üî´ëeÉ:¼[ªX¨Ú·¤XB(֘4=µ&W†¬rۑŒ{ôì±gòõ¨Àfà1þAà]´u}ý2P ]®ÃÎèK- t24¬ì¸\æßX𶷻Žb Ž) +Œ®£IÛcˆŽÓâ÷±„¦Í<"ΫԌ<¬ðu>k»r>Ÿ%w¯9þRѲÔÔg¿v†K…‰§ٔú _m×töÌ[öuæ5B1DqmÎŽØžûÐ|N³àOA’6֑Á[\Bb¥˜“òQÊ<—”¬’´ŸŸ*€†ø +¢äÓ臡µ¹.ä×{Úp֟áKSf…Áª"¡%-ñÄ}­+÷¡2°‹|‚Ð7Â#Rw»PRµ*ôÓNõ£WÏ~¬»Æ-õ/#÷aÉšù Ñ& #D¡)éË'êh +eëYuÕTjwò‹ëvµžÙ¾¯žúC‚+E'á35ŠŠR™œìóÀꈯðŽi1\C@¶ªÌ¼.M´ÑK*›/Ýo*.à]ý&Ö¬›÷R¡¥E6·hqi^G Ä[müžÝÖ Ü;µÈZҟíŽÉ¶‰(·¨ %Ìxÿµª£b"–“í÷dݘîH9~@ðÕÿz‰Ÿ¥ñoRX÷y +øâ¾u©j¬|ËÝ"%Œå}K^ÑŽNíDb¶ZCe¥Ö’€ª x=ò\Šùj†£Ö5ú«Ô}Á×Ú8:ªÿQÉF6uÜ¿Ú½½°•2Ž  ñò¡¦=õ·¸Gò˜»PÖ½ +ÏJù.'¨ûhq ’›Sw÷É.ØÌӏ–Þ«½WT]G]ҘßM–Kp†Ø„kö´ß@Yº%ƒ<‘Õ“Pí¨3 —×DŽ\´+R9ˆü¥ŠMƒ]Wažû´‰Õk1w[[0Õ ÓS{ýÖØוònˆ&—æJ’z’ªpóý•¶³TË+,ÐðÍIäãLii}Ät}›p„'G}vyEfñO- å¦ù+EhÊúàÊ7ŒÛøp%UôRþg«5èÍ+6ƒô|UÄ5¾èÛÔD&1C°þ0ý€?¶­ú`å™ä˜c¥ì|ãÓÕòÍp¢[ߏÄÁjªŠ¼Š{›_€/ZUÑØn¦CvC4šc.?ÓÀø4Ð$do¡KOZl—=(o&6Œ>–Jîô•>ÀàŸÊ‰0ÓÕÿ“š È–F:]¾lZ%ÁÏ,‰}ýº»Åd²<ÅUéuóÈ ‚É…ý#7-! ÝÊi£*Ú6ßsözÒ³ûOWƒ¤"‰Ÿ‡ÜÄB®ì¯/ÞÅå—p»‰ø.5h7|ÇAsCßeQ+Oå%ªýŽ§×ÊǟT¡PMßÚ9"ÈëìWAyþ/mӍ|wOēKrµ÷¨+‡tu;–¯aÅä Û‰ö6d‡P'7ÅÆgÇî4‡AߛË_3l.—ôk>|òÑfÅØmÍL)Ùփ­tuÿ>²Øp¸»áJ,þñ½ùo»1[“ZÒØ‘ûÅ€uTudXèWö¬p°Ù’~ܒ†ªÄFÙÁeXe`%ì¼âŒ樓ÍÚÂëáøè hƒwò´JežM7 ·–®éù©Ý Ôrú8Í(Ä°ŒëΚ«JÇ âªà5 ’Žà^§]Ó´KŠœÍæ͝# uù/Ð9R¦^nÕg° bOcþ µcSߏ¤©^rk5c˜¥ð¡¬¯“ÊÍètu/1úû¦Æ¸“äohãZÓÛêǶýŽïf#x2¿Ñë_ŒÔéÑ¡Ùó*O]*¯îåçâ@_æ ›'_-=s¹[M•)úÂüWµŽIw&¨A#Fõ:ÝFܹšYö6Ì*|ë–s=Òg#lûâ÷–Ósµ5㽁’„¸˜uwÉF=eÖy–Á¿6:FԔÄLq<eûVl¿6ŸÕ»‘ð8‚Ë`Ç¥Ÿ"½wlZóù•o¯2â =Îó?Ê>š÷¶¥oO¿ÌÇê+@ŒìçÎb×z=í2ØH.íúcÍù~ŋ÷c(+ÍÎäX}‡„6‹ŸÔ +svÅÞ'M}êˆ Z§"g]>Ý>ÜB{ê£Oòs6H¯xßëfe#òW~!û<ÒB¶^+R©»ÖZ!uªÄUUžÄšixªæ‹ h«:QÁü]t¸hs1´J_Œ$á×ùÕ3_~´°DØY‰ÓRë'c`•B(Ò{êÉ^Ü&,tRšw¦.¨îCÀ,c×I`'kµõ§ƒíÌ®ù^¹¡Û?Éü”œ™Â‰÷Uzìô•á+4Ìcv}µZýÓ*Û3O¥XlŸèúÏ è9>^Yâç¾ +MÝwTëIW¡öªŸ¥^Z +wYœºýuwáýo{îð±›Mf’Iâ¾;Ñ·goΗS[ª¿ªîí~¨ÍÝu3Ìx̺1öÜcÜêi3ð–ƒô‰¤Ù,÷0]8/ýÓ +÷5×w=O(»Œ7øMƒ3g…ï?¯NPÝíæWQ(›’åAÕZâ5Å¡A,³áâ[òŽ'„Oç~ɯB"åôØwꕱÅÜ[®à|Äð¦ô[} Œ.lðõ‡ë„ÁŸìÄùÕo×$øÌ8û*Þ|©ûÏÒT17±_fØµžVêš$§ûv0LM |¡_da'|¶y­íñßÓñÃѵ€äº}ߔý­Úl؇B³bìƒõÉ÷ŝtÂk‹¼d#Ÿ¢ðý´¸ŸAÛóãj䗷»5|P³•›n–/ N Œc²’túõ´(ë8¿iØö&;€ã¶ÛÄûÄ:úE™ƒ?®;Á‡ë$rý¹ÂQ;'WΌ#0ªü[â`“¢UwÑñÜ^9ó$O\݌ê@s»z>sú^•ëî€á‹ð³ÈdÞÀÐ Ð2Ö¨´ÄQ£  qÖ†è*ÌEú€‚ìÙܽ]‹®Öþ)ˆ+=^Â{•â4G` »Eø7¬^ƒË¤tô¶Õö֚uÆÛÀÚ+wo²®é$ÊÀßÊï7ÛÊ :7û>އ)ï6r¤H +.ð»Ç¢…µ×=ÿö:[³c–ÕZl: o/7ôŒ³Zçú‚Û æGbè%n&àñ=|¿†½{}Þ esXLÏg¸ä1ï–lI™Á$^VÝóâ*½n£å*ýx\)û­F¦Í]¨‡e|÷’õzT½†à#¥ ïAf÷[;&WϾ„šÜªÓ䞶ŽÆÍÏÌGŠ³âÞ£ÿT€û´ÉÆ°¼É¥ú&ö¤¨Œ{î/HGï™Ò4`‰jñ_%Œí«)ô ©hXcdҘRzTîYþ±" +•h0–Îg°êGÇõóå€êÔo½¶替—Ò›þL¡ÃTC ­Y©×üõßX{,+r—°„_”äµàýÞD„ÀaAçætâÂ#™´ “ì@ÖP©iay¾aÓÊíAô~b3YRíqíæ¬Ê_Øڛð}˜Ë©–Wÿ´”p$п.<û½Æ_Đoƒç´É*Äân;µ»˜òà…†ßà ò†ß­·},e…‚Gdƒš_i‰m &ÜKä›Bf¨ßBÂñ&1@,òkBáø&½…}ªþ“ö¦U„"JÜÐ;!ðËÜ_›½Ó Î;#XøÙËýÔ?¤„  +ÉÛVß÷í`UóB¸1Ïæø…M¶ù)Q±L|I +dПß_ëëÿđ›³ßí=½cLرŒ©fö‘Ÿµî£ ?Vuð™ÜïT#¸UüéM].#šp0'#0[8÷ 5W¬ïëËÈzË#¿¿\/å`Ê_¢é)©ø…žþKB23&z‡t: @F7E,½ö/þ"²·@fÿÎÞpSO³C÷Ñõ7ÐÝÖùÓá–ÒÓò¨PàÁ8ý‹Išø}zhSzvÉwk íy³êìé“Wô'êËøÙ¶kr¤yUÄ'Ú¬*•òÈ×ÕÙß=Ï·SËÝC SKaTˆ­uóéÁïÏ^oܱ°rQûD<…0¼¥v°ohÄzÏoÏO’2Ï:ۋxã!çº4±“m² ýúöû´£‚°kŠ¥]ɸ¹¥Ô{|Uòž¸œdkw̍(nÌ -%:Öí÷Ø…hpï£éŒ\a•×ýÒýݍS*r–ÝéΩ¤3]'££CÌöF´´”»Æ=çHl ¡SeKÄTݞÎÍô’›‡È´¼9—ؚ †W,°îûaޣ筎‰º‹Û–Ž~éîptÔ>}ž¹yC—Î{h_Ò´g”/Îî¸ÝׯÒµ{L<苲§2ۙ,`È8À(qÅíõޖ’«ñwopQž¿f4:}ÆÁíô³Ã sz~Çiûè$¯¢þoþ²ƒàoÖj˜Ó‡S¬ÍcÙZ7Gú«(®Æý}aòœyïªÑ¢÷ïD<ÕlÜ$ `9ÌډêS~ÒxOúW'ïôÆÝùKgÕc¿öÖõBÊÅóJôÐdœ˜I®‡L¤:m[Éð™—åÞI·Œá€Ö ú[]6VóÄ0.áíÒá?Dzä{‹y‡Ù^jÞÎSæñ5¢£X3Š!:ñÓqQ=lïÁ/Ýäø¨ä•„?¯Ó“}Z áÚÌVŽ™ž%å«WrjŠ8_Ra˜rÎC.ÖÂWu"z»péE¢Ï.º_º°]›f‚JhÎn.®;küz<¿#̤˜)î~p3¢·îã¾SV=@`´~Ó竨w†a¶*þTÆÏcÐêºQZCF£öÞ¾xý¨XL¦‰C9’^°‘ÏCq7þ ;¼÷Swl6Èýržéµ€ãZ~:ªjbÎ6Ëþe_:ÆÇE0áx\óUáF…â4ăÇÛwòÃ$©v›ÃpÓÀ¼{-á„Z7ŠáëºI»? T{l‘õ '9š"¥+%{î0(VœGC®E(÷Q­aøl•-•Š½H¸¥LèÌÅ+2ÅãÒ£¢Æ]©2nó ‡±âuÂ4œöððš¼b~û‰úü‹0Í%–à!Õ\l¥å¦uT›šéåÉ;g—“[A//¦ÝŽ¬¿EbÝ;&‘«DïU8¹:ª=™HíÐ-žËj˜Ü!M ÍJv_Rü_!ùµ.êÛAéØ¥Rœ£é37½ÄÁS½ôbð(m½ûªEN#&S‹Zº¡ñøp‚ÀIñ?Ï(w?çäĎ©ƒgÁ•XËÄh +GÎ?ÛñüþŽ½^ø+¯Â»dvsÑ%k³þÛV…WsnY qìõëý=ºocóÒÁ#tNw%ØiÐÓBâµ9ƨWÙ¥Jbý{F½r³ H™gÞûrŸb*ž¤4ʪÓݝ~é‡ÎçŒØÐdÊnÍpÅÔ·>qÄäš;ëèïvpîǖgYÃY€n +KfûKOñ¦rwy n¼~ÕpÏÃÁ3“/#˜î]'¸×9žûmsòߎ•Ca= apè6éÒ¨ šÈIíw’˜µ}óñE»Òi·’uÞÉœoÑ`0×1qjÞDÐ_=WŠH.Òì›ÀÝ´P]RæjkaìŽ»$Áý¯¨3ˆ.œ”®›ýˆÎ:ÖÀß:Ü+¦»ӐÛÓǍžÌ[-¥©×èÍkDâî‰WVŒö>Ûi"ÄÚYG•Ò†HÚÎB"N ¢ô¼úCáêݲPYûtî:~è5ÉÉýJ2ÕŒ´Œ›Ú)ëö5՘×x£uÙ0ÖË¿ózB,2«ˆôޛ¬¹—²SÖËåï[©›NÄ@±2¢qŸ€.¿è©KCn¥Åß·é‹Ø1ŽïåÃ0>ß ¼¼9ѲÖÄÛr/Y…þ³Ó!ã—æÜ`$/PrjžßX¦¬êè Ñ>µ?kI“om)Y}‹åBÅ/‹3ã´28¾Xøìœé.lØl±-aþ]9¸¯‰KKWžŽ{Ê.› Uµr¸QÀ±þT7.‚…Nù#MáÖéŽ + +lvÙºAÛõœò¤e9rÔjŽ†röå¥ýkŒ‘%§¿?c"~ zaj"Š¹Ýæ}0ë¹þ* §vÖ[O€óù֐%7˜eä3@.‡W1¿à.å¸ã¨®®òcåN¼ñ ÏBdø¹hü,.Ê«ø-Þ ¨Kgm*Uc°‡ŒWr*±ÝÀ>œû&–=~M²š8¢¾«¹z¸¯¾<ýA]Iäfð7ß7Øû³V5¬È ØMÕ&÷ôÝÉ´‹NÍêÙå NÕðKóž1+çÏ|GÜQ_ÞkK¯áwOŽ©¬¨Ÿ H}yzr +·ëÐÆۋ¥DæRÎfê*ñ¤Ô7Ï?'旍±±(¸¸eÖùX¦ßYª¦w•[Ó5nBÉ\Áô‚£ÕTro×iÕ¾Ò  °À‹ûÐOΣL_ª.̙ˆW`¢Gå‹W/û7ÐÃÎÛŸÖIj`â°õëز›XJ¡­û 6Üs."Òï% åöÔ©©ÖVz7¸RðT%íÑ.íõâ«úcÒîýAFÔkì ußz'E[c5t¿\¹GW»òˆ@OÉðŽ.âü¦æj‰ö)ž^¢‘R$ô„·Äه¹‡íNÔ5/šóGÞ Ì?œƉkç_›O¯x<•:Þ³)¼!ýþ l|ñhpÔZÓá^댞YµÝëJÛê÷µŒ,ünõ†Lt[ß[¤—$ξ½ð,ç¯P“\#S:öûù‡’Ðý¤yõÿ«Qîö[/FÞ16þôÇÉ5¼¨Pxy÷}j›lótTkMMñn‹mËZ»’IŠBß{þ­T'}|äžÏš (¼Kڟòe•““Y ‚Ïkf4nSÈL­ì‡lÞ#Ú3;ÄÈ*“í—¤Éa͖¾¡xÿÚ'¶³iÁÕOåW:.›Q"¥6ýÂ÷‰ÓA©…?Ãy6Q¥;€ÙP<ÃB˜wÎHIÑ è¡;ðþŠÅOÌ)€+ÌÕûô1)3LÒèy1uC(R&\\±ñá¬UœoøyÅDµ{®Y—wkF\.»F@KËmD-ÕI§{gfí¦e·ƒ=ÿ²m0ügiw •6´Ïûó77gÃ/`³9U”íÙ>DÝ"ò*~î~›Š[x_éÍß¾BÏõ¦«úªgØÃñUÓ§ÂÒ=-{*M£ÔèåË»nB4'÷ßgl„=ú@Kãe¼1˜žz½”lG•ë§Wqnz÷Ë œò²äIJ×&‡í*n÷b[¦r6Ԉ8l¹)‚<ëžË՝†ÝǪïh}Õl—šýܞÿéãÌnZ–ÒÎ\Òö|phÙc2bܬ°håÆ®íVOmÕ[”c3®«OÛ"ó£õ˜Yûz2ÏNóØyÙ3k¸”k#¡àlŒúÒüµ -’wÀϝ–ÖÈ,„v¤«gUÚkóÖKf`ž`3[±kå_.:ÃÑ-φš=-¿¶må9_x«h9Gº"ãÏÁfçm›WÚc¬Ú8RÌâ˟—#óŸ#›·¨kD³ +Ñ°Ö×ÒVêŠÞØǔVѾ.O>ýnÕu°VݎÛFz ¤Íx>P>¤h¼Aiˆ–ÆEð1ẆD,´uًÂVì­\_ÿµ«ÃۗeäËá·Áxà¨Vö¹ºW›¯‡·7é¤et$™ô„¬sªYñºð·µàgá*1´{‰˜U“±õØèm¹? f]vnÎr€ˆÉñk•ÏÉÐb¼ã@¹eÓsã'€1u‡65û½K’)]ó­€ÜRÜ€SÔaâ¢ýÔã5¾lÒÀ|f¡;úÒÆ@ÕW¤\?0!ùڐÚÞp'ە¾¨aw\w»ûèO!uOFÿiîOâ¦kóÏвձ·4SÆ5sm u܊àÊHQµìÂÊh1ê}ÌÈcŸY5†zyØãE±´Ùù`âoûþ‚QaCbõ»W›üÿúÌLÜ^ûoñ'|{dígæÌ뜩 µÌxÄ¡Œ/|®¦ÓÙâÎ=D…Ëž˜™3,m[À’ÄM=±®ÜÒíÍ©7Ô¹{Gª#v°¬XÎuÜù×ShòƒÝfÃÀ=hƒ€.e˯KhÇušÑÒ9RØè\ô¢»¦ —Nô‹Ð È«›ë©»8¬GT/¤^žE—#Ïñ•%NקÍFVlE¤ÔÒÚAõ‹ø3Ñ¦›‘´¥.*Y(8˜—ƒ³'Ð +ø;7É7f¸E^π½c©‚Žj®åÐ÷ô³ 5ŽäȽeÊ´Ç@Eo­êÖs.:löJ8’WÿinA3ËZ^¾k–U°ŠoW?ˆw[9¥v«‹é ™äÞ½>\šÜ@s$^÷%ŸO€àŸ«×—ü©±?l˜ ýÑ}¯ûŒaqQdSC^† ~Ä£öþš>3“€÷oô¡Z#°@÷(¨ný©'Ñhí?G¿ðwæÿµ¢·;ó a¥Pz=ùAœPù÷K±¡6H%‹KÄΛàgº¼¾ÃçÃøu:‰Ì=5šƒåjØDÙsÍßË«X¾¨oû×^h¨°®G Ïm…f~¿ëú ÓÞÚ¤ñå jž"² ìð€œŸfש˜›ª¿¯í~PÝéõƒžF÷ˆíïYÆ߶qß{qèLÛ&“¥¨Ü1è®ÖCüæÔ.ö+<¼üÝ2‘šfš.ݵþ\…ïψ×Äþ½e‰5¢¶ñ͎_ÛTù[¼£õçÄÒåjcï¨Ûõ·lF ö8q;—çÄ'³g’…cîT{ïnØ`ªéò sg؂?el–,{¤ —>ò‚¿ª†?ùšïÞÆ﷏Kƒc³×ðþ5þ§<¹"¦>š]×ÓÓÍ6P†H—w*ü؋Œ»éÏPmB= úʛ‚´â#p¦ å{\óÍÂ̝ޟ±‡zÀ7A9@g$eüòæSü{îOÍʯX̖Eò.çºâ7£Þ ¿˜ôa­¦J¯Ó\ jP‡AÀNª:Y”„D„¿ÈŠ8Ïü™µÀG+¿áUMjDžS¶ªÍÁ¨ê(Ôë®AþWý[`® „‘é6eæ{æ Kæâï}Qàø{h÷ó[XH=dŒn4„?((ªËÒ×±æªÁOOÙyZ“åS%˜ÊÇí-Iýp¨qËþê×·¦U¾d4~ÓqB¬€gQ[nnà+^nÚä]‚ƒin45ÿÓj!o?Óîíƒ s[Ê´åKÙ'¸Ú»µ¾©“Âׄ;X«„õýòÂڃz?,ìì_¼iì’ãÚeÊñ4Íó-ÓGU?ôm&ÔÄEG‚4ùÞssIºÎ²2ã‡b[""~œUžÌýç©XÐ û§8Çé¾? Z¢,ºÿª¸qÎ-u·ø ŒeÃÞúÚÀÆñ ê,g/&`˜Û¬û9î‘뉐(äñOFbdaOa·“ðÃåã*¶È§+y59@ƒcv7° þÙyþ¼êúcÐ4¹Ç>ö^³b‡) ¤K⁋Åd䶿º'Wy_s 'Q=Ä%3'…/m\úŽüw*xÜÖW†W ÛˆoœU jJ3Z“5kXß?-·‘0n×ýV5%º¾Õ¸ÂÜellÛxWÜSFXL‚›&B-@Pœ¬£œ:BÒ¢ÍÂϾ™‡¯î|ÁRŸ ޕ¼Œm:$Ûuuçç£ÍÁOÆâ ÑÔZßov[Ëï šÜekuÚIÑåÒ}`[¾]ƒF?]§2یì9VÇTpqî:T„Ф÷è QžÃs*³ˆ> ³Ùñsgjðl¯]ùS…ÞA!Õ ǎSŽ ý ô¯mE)Ó~·ð=1ýr³löŽ®ÇÒO¥ +ã9.Øù~ˆóâ֓«ø¶¡MKï¬ԂÛãcр·á!ݖò-e³Ï©¹«|QUrF3Ô©%s{*¾ÈP&%¹‘ҏûwcÝÎÛÆuAÚóS“ìýÛÀœµªý%SZÀ5ËÜnãÚ|_a{õžQÁî°ÑÂo®¶8”ƒJ{°‘v•eu÷Ü*ë¹—©KÓ¶ðÑ%ùÛK”œ-"G~ðÃhÄôZh$µË?âaiv=é­±7Õ¢ßúçìn÷ëBó*¸Î6]Ì+÷"Úcw÷XFN€Íz³n#ÙGFŸHI(ÐâSÁ­– èö¼µ'ܘÇ>š¦Í!¾Ý†6å_WD°µ„&<²Ö[î}Ö§ug,9¯dãî!eÙ~Îé^Í +ÀÃóc³`Š]Ö9QHnaÔà¶è`ïv|¸4Òü-º§›0,… cRœ|ììÙNhg¿áÀÒЇÿԃ™éY‘UÌ^ÓúåzóeðQ ýoÚé}ϝÛSŸ4¬XIa;ç¼gvõ‚« g*Ïèú8ª6ù—À²°z¿Ê‚‘íJ˜á=ÿn†ðAÉY+”ƒ“]âŠ/ nr#çÍŠè ¥Wö\bÄa*_:££ë1ˆhÌm )½‚$݅÷Â&y2¡qߥþÔÙÐY¶/¶Ã,€ØnúÀnþþé¡We¦ÖÖ&ooP¼¢Èñv­5_t½êðºÙà¢`D»â1¹Zœóz`ã žlÿmøèIg©Ñ+Oƒ¸ÀgNÿ8n{ænWSa„lHêµþ·^ºks’0* {¡·ma²½’ñYo8(L5ˆ·שFAÛþ­(à22X^u–†¯¾ÙYøZ+ûŽüHxWá›9;õ·XMø|qîþ°k£òûWJæGªÝÚR$´ÓÛ©Mø~¸;û +C¿51O²v0§0FLŠGJ9*s¿֟¶É(¥nގ™Þ¿^x¦>Úøë·vHæͪ ñû¾¯vw1.ÿ”÷jÿûjØÏ*NÂö˜¢Ò•°Ê£ ùú¬6ḏÐI„55ïÖ7wRp(i/x³‘®©¤ ¦8..Ž["ö¦W\§•Ã”b\h–ªCÚÆÞù¹û¥­¿¿µÝë ÝVæ÷³"?N+ڈÞìEë +]I³E÷bIëý˜M´eBC£îXW¢€¶hÙak¯«r[=üx;6Þ_tzOå8|‰`3ãõ×Yj§@úhE”¸Y2$”ͪgä,•›ö±\EíN½PÁFhwTýM:ʒ­1ró5h3UË«ÏÌJRhn„¦¯ó 6CqàLõ€2÷—üDº£ÊŸ;>»/Å=¦Y¿µÒÜÎc}û%<ŠÞ!·ëÎUÿ€BªÑ½ÕþEOõX1ª…ƈ¹ì1Ås”yÙzß Tô7sï¤È T3|+ß^„¶¼ ™šyÞÏ\®l‡»·{‚vÂú`W>oÌfWè‘Ò—P€pº/;Âþ%SÒk² #罈ŸŸ¾ˆé=èp€Åœê|®<¸Z'øcΆ.ºù„#}›å-¦•€=Ó; d]8…Ûè&Ýs HûwšŽd-âfo÷K ©IÁ? +ÕaõöâeôåØ [+k”÷†ì¯_Ç-鼦‹H$ÇôÔ=ûÉ#Í7ðí‹É´ŠÒ_5˜øÚZµ}ƒ¤À µpµ¦úºx>Qé2~A:¼ÕeÃÙ5®_¾½K³îùmëÁÉ,ÓU%EüÏz—>!ßå¡/™ß:Œ›|$¢T·z_õ4âÑN"7LYf!£ènº.µoš,¾"Ó¡g¿IJ½4æ ±Í ìJÀ$­ã¤T¶O-:Ï!¿CÂþ8y{ÑÓØvó|që@ÏGæ[?wsÃìm<ÓF{3ÂzWž2’§õX“¾í$µaW`ÖLäßݸ_î=Š{%‘·šMë¢Q+ôáXë9e× +P¬¿…‚ƕ›‹Åšùx=ìVfú{·XMy}ԑìíŒÕ¢•Ûkˆ¦~úäŠk͉–…mW¢IŠÔDMŽÅ‡M|† «s¾éþR»ëþÕZ?´p!ºš.ÀG=®Á±¿€£ž#к¤ï³ÊÉdØîϧ9—l˜Üãlˆðz+¹۞YÏ¢]£KOqs¾{úÞoV_øqïM’ãJ³n£³>OÖ T¾CzÞÒ0å#ÕiPŽŠ'³ßŽtö8Ž† Rñi;ê6~àoåh@ÏOâNz¦å£¿Bþ“k³Ýêe,Û4€ÉÀPˆzO˜¿Úw¿UªÍ˜º\ ܯÑ璣…')>U Nµÿ̃#÷oõ¨¿ù·~WGÅ®Ò ïNØyY㠋›¤q¼º»œ8WœZô¿„‚ÒW›Ø +&™V-Ss%\†´À“J§©ëó#¸×W=2.#Ë\Pþ‘šŸæÿ¶ù¬Õ +pª„ ÕI½áÃzmíªØ|e·ÝÇYZ.?©»,oRy1ü¢eê6¿zl%0 ÙY雼æz¨xÀUµ¬éí£ƒÅ¡µô´>5UênùkÃWBÿ—Láþ­¡¢©KKþ‹ÿPÓ@ÁÒ}˜ ãž`é­áÄ;(;†õUÕ-”ÜÔÖÖSÒêÝتnëo֋¹ÌÜ݊Y ‡ çNx<ã=¼¶52ô_‡¤{6Àc‡Í‘í%Tj«ž;¦ò’‰nŠõ^4mjo‹ßH5ûˆ± ƒŸ5ÛfÌ£s.½–ä4p"g"<)¯~º/áö±½ivúë·rr€‚“ÐÊ7ߪÝ_ a…‰wû§[—ð:±~1=4ïª[»÷Ù²u²J§¥Ô¬Ã8Ðõ=i»dmúÅXÓO¬ªç6^œƒ*g€é:Åõ“r¨›h9O1aWÙK•k\Ž㺶ÜòmmCüߒºOQbœ–øX«ÎŽü^a‹º6ºÙ”ßzˆA6ƒ{ül*£³¤Ê¯Vø¯¥p>Åu5w„›~ñRÌsÔ¥Mêûä}’ ·Mc_͝ÝI Ð¬ÿ’úr0ʳ š?ïYžãÉ^˱jðÏAox?6q4UAü>ÖÐÖ¸ÿÅÒ¤g€‹­t014‘÷¡‚+CArx腗WÊw55{Áä7íÚ;a×:¡¶;œíªO¤'\nœüâ&ûy䲋gI‡ÓrbòámáNºMð'jÓ +×`:o:5N}{—ñ¼7Tø;ʫÉÛnPS Wԛù&­ólJ“ÕÇÙò\îK û°?O]q”mØó®í8õš¸wWæn¿ÝHÎÚÞXÛÑÍ]­/yáµ*ڏc_Ðzí¦ëžâ$Š»jÄroìªäb…yôOÝ­#ºÇ^ä¥ûä¦T¦à±7ÝÒªwfê‘ ŠôúXÁÞÚB$3\®ƒ®Ôy9ö’Ù®40—,÷ËY5¢Å# æÂÛÏQó!ª[À¾vÝSML[gd0ˆæ}{]šüöB–‚rŸƒµ$hêE¾eå¬kkNˆªNVGûõËß´Mì=Š¢ëܱíæ½wÞ7ëU¶µª}ôŸ5®“hoésæóŠJ ˆÊøûÓqUgËÛ&Ø(µV8P׺rzÞi`€JHT‡·v¯÷·Pa)æÅJHէע¾¾W€YO„†Í¦µ¦Šÿþèü º`h!Ï +/èҁØ+q{u™Ž+¬_LËáûú}„Uü ¿›áU¨f[¼9ô;§ë¶Y`0Â-gÿüaYEÍF+m}©ü3QÚÜ֋ ßÚÿ&'ùN ÈO8!,Žîü/h9!êcË8։ƒ| ]÷µweÆØÔÒüê~Šµh˜žÒ ÀsŠíZoýò²«NìÏ{/ƒÛÄQ\îv~½ÚlÍÇ¿±W‚ÔСáT>7TÈ:¸*æ*q—G²¶—ŠD ¡rw +¯Î +IŠÀ2±q‰hä^èJtf«›Úñډw…–w!ýÊ7üÝ .Tx/½û³ôËܶþ²üév—(ÈR/2òÚ#› é{µiºšäíï_÷ËgÛ® Jì-ûHÑó¥ûƒë¼î_B#=Î^gòïô5ÚÇðÐõ¶ü‡D·GÔsüÕá" 6†ú(ø^m›_iÌ|¯› <òzÙ´2a#úU0¸z&¯‰xáQ;e³Wð6óc­\Ïãn¶| dv ÕBÇkžÜ«äm8'þ +’Aך?¼²ooÈá†üÕZp¾Áoô‡dºö ùeãÝäZñY¦!²ьŸhÎ× Ð\ž2¦:„N·{ë&VIxŸuQt٘®L*Oôàôvඡ*ṉ̃˜; –ûazWìh˜Fëۙaký¿žÖÅI¸o ÂÐ uã0dp¨ƒô둃Ýëò÷ Ð\jJ¡Õ0¼R‘=îí?uXú‚œîÏÂaÂè&ù¶MÔ±ÎÁJQèÁs÷6#mUÿÕFÈÆdœòn°’œ0G‰H$´ÍÞàÝêL¯È¬WÐÔ\à$Ø#ĕ¯ÛÒ½¶ô¯Þã÷‡×_Ê­ç¶â K“³ubšãÅK k²Ý–ü?Çú[ÈûÀ+cêчö¡; üÍwÐSw#¸õ±uö™pâ6î‡sÁÓÝÍ;øë(Œ°ò¾S»<Ӏïw~s9˜ ;è:KBÚú³ +²$Ø7]pCìdúØ7à/˗=¥—ÁNÇç2Y5wÆ¿ZA£¾9µkO)óʶè÷&ڞZ·;;OÌܒõ(½ÉÄڛÿu¬€yËe›õ:•;®ûûǀ’]ͽ‡Ýñ“֣͈wL ^,ùÕúG"°(]×a08ªðázi¥ÿÏ«m¤œ8To%Þ}Oˆî‘VÃڑùå.¬S«ÂDðíîšéfZBßùymyÊiyn’ ª B¢0ìµ|×¾;®)ѳ›˜^î}ž~#Õ«²Ú¦nҚæv}¯r}X}d‘3ˆ~šÛf¶¢(kWß/ƒÓ)åÅ7Läjy¹K_*¿gÛð°¦%ì–x#úIŠû£'í-O@¦°±~sÿÆÛì7àž›9¹šÒUú¸¶Cc¨’ÿÉy’äõéqgTՏÌþ0¹€]%ºbæÄýêÊíÖ<¶KGGdv\P~+®0цíó*©‰Ûo˜WõòÅz:ˆ±ôxs’ZX*›áhn”‘íÉý±5§=_Ñz5ì÷qç>+ÅSÂó’Õ&ù~Ïô‡Ålù½¦lZóã4¼za;·¡Ó|h£ Ú1¸dånoV~ø6…Œµ³ÜY‡5»‰yýmùeþ¬¥nOéÕ)j^=š¬¿§ÛIä`K^ÈEzîð&uü¡‚òÑ[‡¼ñ&«Ä9;r/,Ĝœy¢‘|Å»´ˆsm×+:ýòÿ¦Ø…¯^eþ +ÿ©»çF©Úݛ²‹¥_,·ºBs}®{áyiF~Õh1éœ-zSí\ ÍÙéN–ÈçËÛ¶˜$ ØœEîë딆¾OªµOc·:´ùð¤ÈK;!·-/’¥…‹ËäJ3‚È‚Û•Ö‚xxM±‹*s`LTÞ¾[}¸u…Uà§% Ìa§Úƒå\å»ú@–> óéïýúDò$6QÅuu­=ß/R•Õ[M¼?îÉ>Ӂchµù%aÞ]Œ×„ýhº¡ý%åIqû&äçþ~”®Ý±3JŒ4ºöè«Ã𠊽&¥‰Ì\Œ¿ó«—ÆÉƂq¨¡¸ïœûςš»Î¯{Uí]î̈́ÖÇÅÛPf[tOc^ƒ›©vGї"6r[”M1ÎÜÌWõ#ºÒ¢kó%×çϓènífæø3хõ­Z ¥¬u2š*å^‹•ÃüWa·_nS +œ<´¶OWPʞ=ÈéQö'Gs§åqp›&?kïc[gyœœÅn•Õþ]š¹ü“X©Ì¬Qfɚ(ºv24yñÐõ¨¿öæ&Z`_û¥†¢’Œ;$:<²”1«†Ö#@]§†´c6°0®ÝL@ꓚvt˜*9Ýã К¼f6ÕmMÓÏÕCö¶ë³½yóèizR +±÷ôº&ªDê>‚â=ûݍ¢?(Œ-4 +MßDù§±ìtÓ§}°æ?Wú ¿î¡Õ¬GqM]î= +žæ´4±#QÌæ⠝C‚î“tØÜ {o·t²/ì<ÿä²ëÙZÊ6Ï?õCv* &LdùœW”Nã´x¦t>I*¢ò)ÔÙ¸Íi‰¼ëïÏÌ -Å!pà?ÃùÛÍÐ-Ûoûq@ •¢{ Ã/ï&D¸<«¯óºhZ¦‡Ë¯žõxÿS¦ð9œ¿µÓ½bXÑƒ9µ ›¦¸ÒÓè¦å4M¥ùbݒGUrïsE-Ý1L}•º/Ň»c]"RÜ`4gXd`™ëí±cëVoŽ~Ø7ژ“B(jÀ:³¬D™÷õôë5 +£¼ßü›;hÃÖ¢¤W½ÑºÝÄq©„²ºý4E lãUł߾Ö;‚ï6.¦S0X¼:·¾ž7K%gèüiÊg¹Ÿðõ'ź²s†¥Äø8V< &"ã鯊[P¹—ZÝ/WB;¸™7¾iy>´déÕ½õ¿jä½:nM´fÝ{|èÄ*zŠVFÝÀbuÈaÈ~ 6Íç8 ή¥=Q÷}Añç\ô ò§’íÍPøÜ־䭗Ýó¨ŽÍ÷ÀÞ6!>Òk.à ýk·GšgG“°!ݚ.®¹žá_¶]u#|±ö6Ñ0Vÿ2·;N áÉ_ “åBÁÎòLá©ó¯ÍGÛjë³T¥Ìlý½I\Nz(—E»ú©Í¾|Ðo# ªT\£6$mq¹·Î\2ÞY•QVû¬¡¾ûô˜¾u֙ŽárIaXµ;S¸iUJ÷>®2Úìþ¸ÐódDÅgÇ2çV±+«Ÿ2f²4RÁb!QxŒJæN;þr6ŠÅÕa¥è·MMéËï‡Mí= +çØàcl|ҁEAËÛN¡`E¬(u­ÎRÿ i”Ĺ£\»Íºm;¶€l±‡ÞêÁ¹ÝfZ€âÍÊË\sÌ?u·èH ¦‹ØYŠ{OÍíÕÆ8c®á£ £/; –5Å<ž˜ÝËSgޟrË| öû¯ËqØpÿ<;HÄ=ÈàöžlrŠ~G.žz6ÁCçEë§~0Û¥ËY?ÎpŸ?uk4¯´¬ŠR)Ç+n&ˆn&¸¿WÜתߓ/\×µ¢†<²r­ÓÕª ’–Y9Ûg\ž‚\2£:Ôp¶ëöÔ:܊?8ˆõo]òËUIÎMúÕª›™_*Úì”? +9«ïµIòfÜxIûZ\EþëA<÷þ^~ÌE·ÈwbȞž´û%<7ä©÷llžß½éæëL]Á ¶‚Ke]ÑiçÜq¼û¼.ëÕcjm +—}ÙÂGï Ö¯| –;O÷?ÚÞtmQdiÛނo#œçyžDæAQDÿ¼[ÿ=¬îµºê©êªúsq‹wž@f$ˆÀ‘bý|"ãñ[ažân‡ÕðõX4µ–|è§FOѸã~³»73[m_ÎÁ'/0ª+½ ‘%®ÕÓj`{©=›vsÆ~½ Ãõœb§yоè3rÕi¶0دöÄêw΃6!Ê÷Ýژ‚Lƒ{úŽkJ¾·k¼"g¥IŠ*!±©‰s¥®’);¬Þ]Dj·¤µÏR¨¶‹6—y§žž·Y†DyŸ]WïÁ•ç +1ŒÖ{˜8µÈ±YÀłÁÃCø–­a¦ŒY;@g’$ï—Y.LW9èŠÄç{¼ÙÔEy!û(“I uŸ¹!?ĺÇíµ& + Íèâ/÷WÜû3 á¼áÝ¡ãÏÐtcºP'•*²tvÇ~`Pv…d&6gÓg“ìŸëã»éƣ쐯 *l›|8Ý4(`ºìZÛõR›u¸„‡©Ñ[_À®2~ Ž%;„<®Ågiû–­û¼vè¬ ¸`Ægãyn\l;LÎÐ@~ñC‡ òœ^!xrƒcisê \ŸéR[¨±à§ðûž_57Æj²¹§°=:Håô=âItwݛäv ÞÚ¥×wƙÆcWç="Ž%m“½Œ.{PLzÓŸ—sx€LÒHï\EkæLUí}?¥*» Ï¡º³û܍:ŽÒ¯E•@zhÖ¾õ×Sdºµ «|Ÿ†x~šK.·qXZï{]©Ÿ]>õÐÒIU7ëŪӜ“Ö#ósퟻŠQb7Ø +v&ñåòNÎ]®¡וD€8»†ÏÜH%ÛÕ êŽ)½“YÈ]/6\¹fíÜÆ ØMPöhqã'kt-e`áŽß GàÅöy0ɧ¥òLòCo9D¾—¥äݒ›>^àÅFolÑ Ü V812Æe>s>À #£á%Ÿ Çfs>Ç +V–ÍÀ‡o¯¥Ñ‚“€ÆÐÌõÙz-Ep¾åÌ:xdÕÚ£ÙMo%ï9­wg¢-€Õà…Vy² –hmm$ch,WðÙùÊJptGÕ—ÈŽ$§vC {؇«÷èÖíŸórU©+T5ž©nE‚¼:Î!ÕJ¿~¾¡¯–=Z¿_6mÌÙ4–7{ᦛÁw}¬&ëbY²!ÂÃwj ÈÀJ%@`¦× +eØÆ:r×AUH͙'Á×Ȇzõrf´o¾}±» t­níUañÕÀ[µ_ntøI;ò؁É2•9v1Ô¼.HƒŽÇ%™Ì£;­sÛ=¹Èš·Þ%7*ÌÃÁÇ•j«‰©ÈTo6VO“ÊU¤%*¿m¢ÕÐYÉËܧX׉­F͆½Ê XŒ—•¤bîˏNzë"«kWp‰4Xl×K-[ÜÞ·æå[y<Ü°Uš¸â-Óc„îkËTåÝÄ%“z÷B_*·^ GA¡ÜÓmn`³ >cÓjµ(ä'ŸVÆM|^’ËSŽEøUv(Q˜Ã#¹yáyàØ÷Pì’†m«Zâ×Ûæ›ÂέG½^=¨«4ìÃØ}_>•9| ^y£Þ½²½Û3<’b«J³äðì•6Õ·é-6èà»æ˜Ã†°*¶ +\µ»íúô_˜æ”ŽÓò+{…ÊHv‡Îw¹æÇÒ¦¬er¨„ Ù6OK!Ü$•'˜M«^ןcduL%Ë´a£~S-[¾£,£È&g/FÛBЇÁ]GSZYé^垏dæÔ ]f†ÝfIûȱW¬ fþ>¨ÎÐì¥Ö½­Üäï¯HT¨ÊÈ ÚGƒ +²KÏB»ÊvŒ8ÍY±½)É8Š² :”©Y½ gšè9uX¡Î&0ÊwQD±ZC«Á@¾³-t™ÇN3†ôÛ5gˆ±´ÛBô}­ÕìU ƒÇì£Nò¤Wuýx¦0ÀéXÊ4ñìe7Æüa™âÞÒú™K&5›67]q/ƒÖ"݃—SºÙ£²ëð]£{î>G¦åsµt˜m¦pg"¬i^|9ƒ; gGƒIÆÔ孇”õéå4Ÿ‘¾ËU)+ßýšO+Þ©ŒÍǦ_YâD}Û#Ó´9~Àñ¨{ÄõŸáF…ܝ$¿UtVi0£igÂÜY¥Z¡ã'Ï@"È+D&{/— ˊŒ˜ JªM SZÍ׈ìƒ,Û©gQØý<Án•zH#$üjê› +ތXƛ|=:£U¯]—"ôÊ$Y%¾Wöx}å4bxH?›aŒ!ÚJøaPn×jaO…—ëÃ4òò<ŸRkGÜ'²Ï[jPòžÔڛ4þ°ïöÁMAãï6ïõpÖqaa’ ^ìÖIt҈G¸9ìê£Qúà65 eáø]ÿôÿR`¢©T¹þÿïÿýmÿ«x[‹gÕ§÷ Ãg8{í(»|ýN¹XÒEcÖk—³Ù"P™ê®ºÝXf-¨‰ÏFë‚Õš3›µ¬A“ìä£Ì¡»¯·ž´Ô‹ý°À ‡] BF$6L–Æ;­ÊyZò_™À»¹2ރ‹WŠäWƒÃÒ˜u'/•Bª:÷yY&kÝ­†¦H€wÓÎÏ#ÂÏ¥Qªax2À‡ s¬³Y.ë­»üŒ$ƒ$A–…m=í]{zIøJnÈv‘X({A«K¼­äv· lô„ãøHMÌtÓðÞ.kcïBõœ£VS=÷å^ ËR·Û£O×K¼o5©Ÿ¼*Ø,JË»ž ™0}´çÙ=bC–s©Ý“ª%Öìgây×"ssC$KÛ6×ÚÝöùºYù“y¿%ÆM×ö½RÊ×ÝræþZ”÷>V¤FY¨ng{ýãæqÛ«wÙKªA6øzbîi v#´mPŽÜÍöäKo2ùÄÜ£!ÓÞScìÆUh\‰§àº8Äeݐ \àÑ#&6}òBÝ4¶ Üë¼\Ú&¥ñ aèǦR[{è¡j®YÒb+C}8«Ô 6͏Ý¡¬ÚŒQ+]N…w˜rrC®æ¦™Î06•žŸ©uេۋ°®bäûÍ‘òÝnª7s³¶lzïÙ½ØÆ6‰ùè‡ÚE¥p^¸Ãwðž¢ï<ĐɝÚ°åÏ6dréú[þlCÆÍü“-¿ÕQ#wêDuñ%<ãÿq 䕗ºV[AÅ¢—¾¥=àØ(ϒì¬OJ5½·¦/‡gm©¯W;§¨Ø.»×;匼Ù©ž~åŎ5ÿ¥$‘ö¥ï¾õ8ãf~õ8ãf~õ8¿f´oEýθ™_ìý¯õæ'zÿÃùïö]&M.¿Öûÿ>¾ß¤q3¿Øû_èÍÏöþ7ßeÒ¸™_ìý՛iÒ¸™_ìýÿíÍ/ñþ//rÆÍübïoo~Ĥq3¿ØûëͯóþÏ ¯sÆÍübïGo~ؤq3¿Øûôæ{ÿ§…Àœ!ÿ$ü༜TÌ ¾ÊîPñ»–Qˆ’'T˜AÓ•Ò:;¸]µ¡¯Dê›Xç”Cú]ܯ)¨(Õ¯`ft6oN&Ïdç«?ˆQÍvT7Ò±Ißñ$÷¼ß×*ñ*ºÂ¬Ô±óZmqt0›6.^ö ß*«¶ÍwSêÄrûõóP°í1õ™æ퐗‹²Çl”û³%jÔÏIéÁ¨Á5xg2¯+’«Ý»×kÛ _˜µy–<=V3èƒRˆù’œe3-úÕþC¹Á…Ëz]ûÚ?IRKó¥ï¾A>¨Q]£ô åüû„i¿®7+žûÖ:eugnÚ[$){7ëáÐ8DáÍÙ+ç«äؽǎ*ÂípwôøLñd1æî~ Z~Vþ—’d¿ô]ŒzjÿŽº«\ï¹ýô˺x¾™×–“Þ¬ç–yYQ:ßɊ¶-r ê9;Šp|±wŸúüO\~Î'éút3ö$?¶?[¢Æà›ô’KÞ<ò<õë}7†#º :œµÝÉ~°4ìSÕR‹•ÑáDÙQ®aŠýtžÆÃå3båȖ„µJ7ÐýŽì!Yዒ”Võ_”?PÓñ_ñwºüóV¸—óI=:çqºêCìî+³a;º¿·^ÿ°Í¿ç8‹Ë__:S=¶eŠÊíDâ¾(p?"Éí†Ø5–AŒúÌŨØòò!æ㦩üՑ­®]>ê}uE¼¦;ïMÁۇÜä…ȪBªã™ÜAŸél9£+4>«îH_dùOu}¿Ìþl‰9¯íß9ÕeR¸÷xìZ@µ¹sX€*—ÅkòÉk ¶è±fyá•Ž&óÙåVc ¿¨0µ&¶£.§Œ@²k–#dÄ~]>½ù?õ_5Р5ò9>jV+ð„Åe9°«ýVJÕÊݬ¼m!=¤Wœ†v“Ì9W»{löŒ] e?Â"E©yžìO†-¦ôKқ¿ï‰\£bu&j•C°²Óš£r–¡‹{ѓ¼fî)Ìi­Æ·îŒÝ¬ÓcÃW†A3Á–vGê–òfk¼ 3,ñhïãÊâ¿5o¢DSº[sŒ=B~ƜQ&¹Yìw%u²³Ú6…d<֚¶Š †šÌè+º¨(Ýjš4Õ­¬)’[5(â!ÞIbäï \êãß"É}€oüéG¢fºØŽZ¼:¯^ß¼ –͵(N¦æ–µù©ESÛkŠêøy/ˆc’ß0ɛã q5p¹}Yà3ßYaj]b9pº@õâhõs$¹±õ燨9«4õ͔l،/íÚ­îFïÁUñ;C‹H'"as#¦4œÇ÷ü¼ L 5úûZ"bµ€6R…›mØÉ:0vHu?’ÜtüóÃKȧ/'ç:ªžºäòïµWüfUIª¶è~ž¥ˆ9¬H˜Þ9X±1´¯>a¢¸zm¼yû½é©tFˆ½x¨³ëGYÉ}«$¥nßøS7µíoŒÑ)kÈ~u^֏æ˜Æ$@(uÇJ‘$ ÎÔávÿlB‰Ö¡P=­Ç—gr{”;— 8Sö0½ŒG qXŠˆÿ%) I¶ñ%Ÿ/Fõ‰ GõÒËiW~éÝ1ïa=½áÎÎÄÎm"øˆrcÞ È±®Óìà¬q`:8ÁÚWŸºQ'{ÜSämÙÛ«]åº_òÒS:ÚŤ>ð³ýaù:g2“þQÔooëÍ›4I¦ü(ê·õæ{ÿ§…À7pÆÍübï[o~ŽI“øµÞÿp~Bà—zÿg„À·š4 üZïÿŸ½ù‰T’OûµÞÿp~Bà—zÿCà»LšÜüµÞÿZo~öé4ɧýZï8ãf~±÷ÿ}üµ“¶Bú!?‚´qÌy'3h¸Ãú}l/_åÍñTÞpq^~nHÒÖØÕ8­õ8lgâ]Ý]27e¿€®{Õó¼}îÄÝå"µN‰ç"ãÿKI]ßó;êúŒDõöË ™¬úæ[ŒúzÕ]^͏lu;…ÌÊEa ²Žt¦ºŸ?㍪Ógõ®,*Øç%/K 4ú4C¨¡ ïçÈ_9§i3¼"çäYè`¾Šr×êºRwï³ÉÈ>d‘µ c7Æ8ےª_ÏÊYã4F}ßê [G{m!„²ñj¾¥Zã\xgøàÞeëòEI¦¸_ýÁIŒÊbÔSì}(£²×G ;å˜SlÕϽˆæokmZ½}lì"Õh«©¤ÎI»¯½çA|uÞõ³{}ÚÉJ(3Îl¹\ýÍí¥jÈ9öü#7óŸQý,ÿ@MáuĨ÷ræŠÔ—µ3+è£ÓÞȯ-ˆØ±GçŽh†×Üûú­«¤Q9WPp)/W—©´Ø½Ø?ƒõ-¤J˜¶Kˆ÷s䯜T.洂 xÃÓ$yµºv¾õ¡“âWk»`W9ÓÖ{¦YO/}0{dÕ,Ȥåêmò™{çÎËbÎcÌYþL'Ɲjõ!ÿëòIBþŸ¿úÈï¨ä5Ô]Ñx¶;¹U2~yj×/wwè¼Ziø”S_¢]Ï`ðãNe“5kd»qzì(Ð»í²º³>Rgrz ø¦kü¸ïý°$öd£òq ’çتFE¶¡JpŸñ´E©ÚåZWFnè+¨³G›³ÁöAntNûM/íî¼zÉÛޝŕϐE“¥ŒB2p$ⓠ+¸Ã^'.9§}¶?,Q=”“&Çþ¥¢=ÉË ¸ï4#ã…~²¢µGΚ“ó=`‰S|Èú·”½Y,ªRóÖ>Š}†= Ó©wâòf ÓØí"÷êƒÇÞé%ÍWËÝ7HқÿûWE}ÖÏËjÜ£Å3}å]íŠÝ/³Ë`¼b^J¥ÕÕZâ$ŠbÿŪÂ.Ê&ñÙÜÆ`KwY¡.¨µ%„LÄbïÍb™á˜û9ò@…bì}1ÔF£«F€óÛé0¬ÃúµÉΧ§"Út@26ã1q⌠‰_Øځ+´[j’˜”¨NÎà‰Ø ö¦%Ëð(û‘Äh~ø—5rjlR1ŽÒÆj°š3Í ¼™º•ÂUÙ}IVrcå؝ƒ½ÅV¦b`90ç¡(Ïȱ”$&÷ts6ܒ~èpĨߧ±·çQXæÄ}³|zóµDº£êAlRu¶‹šÞ͹g: ᄠ²[ºrÈ^n•;Ìw…y/»à@eƒ°›IfìùkËԄSiôx²OZ,1B OS$¶Øx?I¢ÆÀ,þvCòEÍ.!„ƒ8¯¸y:Ø°uð´wÿIžÀ¤…=Ø©s¥òfĜ&E©÷œ&“¡<šdÉÖ`ˆÇÚ¡ñhSøT›’ØþUþ‹$Fûûžï’¨±4 Qƒ¯Q3Ò¨›Ñ?cN>gÑz´rÝ}c0r¶)k•'±–AéK1hS׃:¥˜‚¼&ƒ.†a£à¯’㳅cÊv±Á²×Ú՘2ò]’$!¿ô]Ôà΅ؚÝñcÒ¨ÏÜt鏮GíÝQCÙÊv¨²(F¹t‡x¥ÈûA­‘C‰él2Áç“çSYcŠå\*ya0º.Ž¦ˆ9/L‘M͐ +ûI5ì ðô"4YOÈëœÎ¯£ï)Må´N“âÔqYóž[j =Ž„„Ó®¤çYì`”*¨ÁZ5Ä"ð:R5Guؙ7pƒ›KÃknȋÝÚ´!¥ý_òÿ%oÀþßÝß Q“ξn%·èZ G¸¨fÿÕ_¡q5ÿŒQ£2Âáª#)Ø: &#´2ÍÝáxtn›@þJ{/n?Gìã +mhû}•îÀçm±¼5zh¡^9û¹BíLJéÇB£í™÷ΜRIò·»´2Ћ²*é{eiMX5A[ÂoV_VYÄX8}Èü'‰›ùâw_”xÀ· £Ú›G5ë_[Ë9ïÁ™Pê¶Tè²WøŽ;h;K[™0óXÞ&‹eλ®Í~ÅÑ©¦yÖüÊÊÕz¹·{&÷ÀYìå0¨AWõ±J×BezzÜ¿K’,Çß÷|?ê7p&%Š?Šú œÉ ÉEýÎÿ5Ú÷£~g¿Öûÿۛ_âýg’RýµÞÿp&+üZïoüˆI“dʯõþßzóë¼ÿáLšùµÞÿp&c_ëýï6i’LùµÞÿ£7¿¡ÖKâ$F5ŨÞ)ƨ×õ붴¹²‡Þ͎Ëéυ­05Ô·ŽðŸ>U^ؼ.¸´Õ¯´U+kIRª~ø.ùj|h…|TN¡ßi½‚·É}H*w.)Í݇»I*ºœtu,Ÿrøözt-쮍Öo4àóîÌ4íím™|ê›É£€'ñÙ …ƒ)ƒjú·J’åø‡ÝÿÚȏíПv£ûtl•üãhÑõ¾¼<óíN–SÃÖ©›A»í«ªÔè³\KUOb{y “HcA¯mÐõ u$¯YÊ#n3[';´÷CÕÅM¥5ŽRòÅ’)™ýl³ç}ç>‹·Â]è^ëG¸°iŸw£Âĵ‚{ÕBÉ?+…×ണ܋)LË[52¼JcèE%™`Ã"pÁ·ªkâÀ;þG’Š®¿ïù‰QÁؤy’Ôž³Qc83ŸÔxÞ#´]¼iïLϯö{×!TÉMy|r†>RØÒ9dò%×Wçãvۃ4îp+L5Zɤ¿$\|¥ö؜÷ l>ŒNØ<ïYß%Ÿ”êßöüÕHǨx|^‚ãó1.¯ ŠŠYÈe w÷–m-Z”%µ½ùp51ôT!u,(ì±ÔR>Œ„°èsŸ TWâÐ<µ££ˆ1½~D¢ºŽ>ç|™¨¡¢I¤EM: +Á.݌Ùõºý<éԛ6¹+­@,»c(^ä ¾åÀ´cì~Z¦:Ë7OŒú#[T$ +ÍK:œŒ”nœò_7óO»¿(1ê&6éZÄÇR‘ŠšiN{zrö–¼±-}m›É4¦Gf®ÔßYí|LMêÓ™¡0TŠ±÷Žvsû©—Ä£>@aûãƒDÕ–B ˆæb‘¶ß/IoþüÕÏhŒJê1ꪎG͍¦„ÕvbŸ}WÞ<3&Պº‡¥ct¤}ê û;ãJ) dP¿ŽÒ„p¥©nzNòBâÂR˜R¬Ÿ´]úF"Çü16­¡±?"¿sêæ(jœÆhԌnb°RI­ú9G«á^žÚ<\å¥k­’ö¡ÊZS¥Ï4Ú­9uÅOkªKó(æK.í÷0žr!˚e-¨.‚lòG<—ü'IŒö¥ïþK¢FŽc9÷£æl³~ˆCó誊ZÎâ k +ÝeòÌú‚âë¹hyššÔ›TׇIù°‹Í‰I¾±ÄÓì~-ÝäUàfs‰˜éh‰T†ö +F) ŒEþ¥$—É6jÔ¹UM'%¨ÒÔG@¾g›oj¦ÏòYö6½ã6³ªÙ:fœ)®z‘#@-Óôº…ύRË/}´ÔZô®õ‘j&;€±¡;ܜwÚ8IB¶nô$nú#5–Û{›­ò=Ó>\¸zë¦Ìöä"d ¶ Ïن\•ÉP,˜Dº@øxV§QãíçËe‹°cNËp3S«n¨á£ºi_ÜĖ·5¨§Ðµ£®ùü²$u_ýÁG¢†¢ÜBî=Ü×t²7„z+Rz¾UY +g›“&w($à+A; &6;#¨ÜàV 6Ýj;¹ÃqÃ÷sý ¬h=²…¡\ +”rhœê›,˜š,óÀþ=þ!ùœ:Èò¨`EYi´W°±™çgȞ/ôš|ª(^@j ZKs2L¥Št/2ÆZÚøòò8O9 .÷g` + GâÞJ/×h-n«âb”Ì֖f¶üˆøUº·2[J·¯V4BߨùâªR§&æuŽ¯s~rêDë­¹¹Qv½{É,¸À'Ì2âÊà|yU:öKk-(K¤Ä–Õ=¢-œ¤'YÏã{@ö¢AŒ¬¯K’RýêâÁý:ä7¥önb32ç̨ µké9ܘMúh1V>nl=;W <ÐªÒm KtùÄ®è‹æ{ŸÜôš{¬@Ïé>ËÎ;.Âłó³3®ˆ‰ì~DâI^.y*"ž?¯Q áñø¯«öt÷¯Çýátr·ìyY÷ЂóÍ[?¯š×~ß5ÊÎ'e ‡>±ÿ¥|P¿3™Iÿ(ê7à|­7ߊú œI>íGQ¿ó¿Ôûÿ§Ñ~Ž÷?œq3¿Øû_ëÍOôþ‡3 _ëýçog_éýßoÒ¸™_ìý/ô&ª—*N ¸JP,ªù×CT/W÷03ÊÞr¹MÍCGêÀ½­ßÀiw;óŒ¶&”#Ôc•­›†Ÿlý¼O:qê9 gòŒ‡æ‰OO£KþM£ügҖðP¤Lóö/寜,&u‡O2eÚº? ”¹-©æ2áàÜmô€SDP˜eZrʱjuM£ŸO:9[ÇÖäŽF“Ž«uކw¸-v·û8DJjuóe­CŸÿ#Ÿ”êßö|]b¶bì}nFµ½ˆ&ŒjT§Áƒ/ +™›:õj×ʾÞ?Ó§õÒ÷-Ì^Ü;I^À„E9ÖJã£Ñ81*9“{;‡Û{>p Ö?ô]ö©¤0ï&—]wgƒ¡õ]òI©þñ!f«ÇVõ“@µd4©—Œg»ÁíÁ÷é íe«Wx²ìŸ¯´¼pÄTµáÌ#ô؝8ÍZÅÕÛ4éjÝð™dÎO}¸Ÿ×†+‘܏bʊ+ºŒhn½ÃÚø—òWN_E“bɘó²LÒvÀ½¤ƒ9>ª]͐ë]Ú£`áókì”&,ÎñÑþh£¶iàÖ,Fõäó!xf<5d"½¦¡¬]Žѕy{Ûm¶ua0ËþK>)ÕÿÝýOòWÔ·Ž$Eˆr<ó_^ÃÞ2Ÿ ö¤æ—8·¹,ÆK—Lü$+=ÁÒáC²D»YÙt,ƒh£ŽÆJâYXw¿‚S®\¼H×Ýi¹ „ P5ù1g¸×à |¿$)Õd£Vâ@}cq ¾U8)B”ã™?£¢ùT°ïQê–^³´]ûÅ.qzºh¯Îsā£w]K•ò%sŒû¦_PS§ïÓñ½z+àÂàZO#Ѕ6 Þ“eÝ*‹Œ¡÷Î^ij: U¹2îË"ÝìáÊËÜ~÷Þ³@ÝÐi«ß×é*ɔSxHÿR~ËCÿU‡’zI1j`ôùÙ~òéû.l×n›_OÍ7|aVÁI[eíH,ÊáésûýzW•vdå±Âl(p +ÐØ2ÇÁnG# RÍq-It‘ÔÌޓTזþ¥ü•sbBI±dÌÉsî³ÓSÑI^P,ErzÅÀ|¾ã=Ñ^ãšlt»¬.´(9ˆ#lùÁòi™g3尔ëx’³1¨¦ ¢Ïk +Ñ_mw_”¤ö«?ˆë§8F±FR€¼Žct£ž$çéUÓéÇvw­¹³>ñ.»QM§»µq€ ûM÷ʉ·"’¼æˆ+3š-z$uÖ)Š¶)+š€Í.G “v[‹Œ­ü/%¦ë:¿ÝJPÉsŒ:Q3­¢¦9H?ÄB¥~+‘ç‘×9ç'{ÊsÇN>Ç©ªÑa%âÉÓBä4I®°.’t³’Áˆ;;%°÷ƦЕAðÈÚޝû”ö¢K›Vþ¥|PçÏ@ 3>jÎ\ëI3ýè>Ÿ¾ŠW·œîòiâµN¥¥E ‘Ü#5—yeBð9êÑîÝDÉAîŽâ)¢‰¢€z$`붤áZ•6Ž®aX'_—$õ¥ïbÔVìý6£žƒUò?5¥‡ñ7ÿV +Oé Ÿ+¶OëMun›-¤‚ÝûFê0D˜_}„­æ¶0u™ÉòùÄV¼#˜v`´Àk0R¦8®¡(»ÁÏÒòڊþ/%vx÷ÃùÛB3ô2jVhúIӑ¬Úòº5.}<ߥ#s÷º‡Üc8”è-=Ä}Ì"©Ûœn×ÒK’¯Àk\ò [‚Ó5ZLG¤|Q`íh$\»E↨»ÉÉæ³ý~‰}>Ž½¿fê±ã‹Ó¨IKØcü¤¹+nÕwÎj¥žŽ¾e@‰LÊ$fÁ•„eÿ]ekÓ[›ò‘â€äò ]JslùÀçINrlÔÇ +Fw +¸qoÜfÓlñX\öä“üßÝQ]ŸÅ¨ºX‰Akøô½ÇxÎr€ÜYpWú?¯À7ä-ÍÅÔ_nܚ¿¬ÍÇâT,üE’$äß÷|]žžas'0­5tip#öí9zÞ®|*ÏøÑ%炸Â̵ƒ"“¥6ýۀY§æX².pðªPH=Å4p¤¥EîöK¤½;,«•¤O}g¡ã¢±]XóËxzš“×¾ó]’ä:ÿüpZ…·1€çÙ=É´¨í¡=9²m£'÷=¹ŠÅ“Ö1Bº{ + ÕV¸Š/í „,ë9[ƒ˜{û5§û=ï<(nv# dR8ãZ¤Oû& OóÑ¿£¿b\¥òz‡b†ÌÃìeUۑoü,8o-ýÒvñ:´>z`^WUA..•ùd~}f¦ó^Û_Ìx䰜 kpj»õT…ÍtüB6“— Á“ƒ`¹á“Ù ÿKâfþi÷?IT›ÃBT녯¨úèM£"³ñt:<=‰ìõuÍÒmA.[ž%ɓójlÜaÐ'($gh{¦Ð¼¥ècÉÊZ9ÅîçƒYTýhx|<}aö±`çcéÄß Ó#½Y^…ß%I¢+Ùþê7p&wØõ8“ Á¢~çFûÔoàLòi¿Öûôæ{ÿÃù _êýgRÚûk½ÿm!ðÔZv2û5°þ@­o Œ9jÌIµcέsâå˜ÓÞn?œI2Eƒ9F=ŽÇ¯!;¡ ï&¨—U Œê“jZ ¾_>œŸX¤ßQ­¿žÇ”:Õü—õt•bŒzèn‹h^ËÀyt¾\z Ûs-ò4:¼=/wVnݕM~©Ç#®jGÈcLÃNÏ-à +à‹¬Ö7ŠŸ»Q·ìû®Ž`Äû~‰j0¹ýs±ŽMjétR*k>Ý[åù̑üMá”d&}ÝÔrÃK[n¿æ`§‰ÓaíLù(Z9}©˜Åyx8nF¢nس•i §¹kԆ“«î\V¡ÖYæC%ê-®û…qs¿(q3_ü.ª1¼û¼”ŠŽQ}ŒêÓÊ1ªCã烻îòAºs«_Ö`p!º2ಷ8©:mñ" êâ¶{‡÷ÂÀ[¹™ÈJ¬Z¢vlŽ…¶ß IÁåß÷üõ͏“"D,¶æ2Få5ÿI­‚üc„2­›Vˏ=—g×ç~X ,C_QÉݨØƈ=˜]Rmˆ’bÛ5“0 ÷.û[.“»¨ÌºÖÙ1ÅG_¤ÍmGø~ùƒ³Iž<&ˆØ'™2\ÊQãd_Ÿ—{1P±éµüÐkñè¼Ú)ÂD¬®Ý'¦¨«*œ[DìØ9”ªCŒ[” ‚1& †¶ú#‘ÂŽ·-…I!–ˆÿHR ûç‡o¨v=ÅÑj ³Iíù0YZ*GÍ´wyv„\öž +™š_Ù¶FȯO9Nž^5<ü°9Lk­lú$^WÜZyËî.:Ch<]’’n<áŸl‘ðyM |Lã¾U’DןþŠÚÉ:˜pìxt5»Ñ%äFéT°Ôùòµ1žôΨ·¶àYÔ3Tѐ´Ú§³·¼÷–LeIT«%…c7‹g³Û!AcµÝá#ŠpaÇñß/pö2ñéIì'‹`B±×iñSœÄ”ÝÇÖxD·õZ.z¡÷ÝTù¾<^ê×åAn”²as±?/Ìøùã5càÝsFµÞÍ91ð¤&çǺ´[¢×7;t9˜ XŠùÿH2[ûûž/JT{]÷¿£®å^ u(jV”mÔ¼ŽÜ»<½Ý}¤tÊ]nçnß>N€±Ñ{3SEßkIÎfwí´'Â,oYHVǵ܏ˆ¡M°Ìj6CÖJ€áí Ý`VK€áöXD@}¹ý.I]É6ªã¡C͟ÄÞõn£- jn\> 2Y#X)žwmÚ¹´û’_ÓuS}mJ4²n†Ûðqpàm;¤[#x@ŒÞPËÒö)Cƒä‘ÚW²&$DÉ!²fÝ +Qý¥´Áö3ñûåÎalÒ³ÙNê:—Qóø`î/㘌:ýÚD1Ï"x{Úf¯|Wj«…ÀêìX'×á*Þ¦/íA‡ƒvËi£.|JýM‹×A)·ÃÌkŽÁ:D/TY÷‰¥ô_’õýÃîÿ’¨Þz)ña?OGúµFè< *.vƒr }hœb[eÓ;ö7­êÚ¤ 1Y·,,—ó +ãnÊɂdüUÏ¥&Z¡ÜhØ]èªlë€ìNÖ°ÅÚÇî–f&-¿üv7*§Æ1 +¾“…e«QSڎïóélîu³9àTš®9ã~7Nª,}‰y?Šھ²ÐO‘ãZ.ƒ/ÔU…‡2ìÀÍچ|ºñ +Mª#õe ßãä" Núƒðz o5æû%FLn='5ÝÍt¥[“h_«\=é—êð؟³ÉõF=¶‰ƒÄ [(äg¦ÏäØïøx®‚>Ѳå§`·d7”-@ý²TZ KºîÚÝ:ðF’¤b­;2`w¶:—à?IÜÌ¿ûH|¡/ÆÎw‹­9Ë«½9*j>Ž¬<êŠu”8~- +ÅLùÀtæ¼F¼× Ó魋œ:iÿSܙ7·C)©ët^`´$RàT³ÀÞ€l­RZ´JmU(VÚKC®¾_bk֕ÏÕófŸ!ú¸œ·;rwô½xþT\}‰Ÿ‰ˆP4 ӝ¤·dj`ì°ÒQ‘̘†mhpï¹ëñο€3n@ö=}¬À~3Z­ÔrÓ*&‹-Ëf±¸@«¹ê÷K| ¤¨éôksÆ`&5¢„¨ôŸé}¡´ÝLo&c2ÝmXYkrHsÅí »fJë]u¥€óÝû¨7ß\é:k®Šoè´4Y༬œô)ŽNä€%ùOb’ƧÔXmNÙ¯KÜÌ?í>¼‚"·¼šS"}†-Ik2ÇlL¹Òáž÷¼®©þceÁÛhq¡Û©9;xçgÂäRžîûÚä­ ÍÉ:“Œ‰'·‰ÆŒ*2çh >0A`5*ISàû%ª®„ETUµ¨ZÀ?ÕÝÕLjj5>ž ôÏîÕ÷ý.¥J·÷dÙösÑiâmžÃÕ¥^36®÷Q·ƒg)‡¥lö$ @ö4Ôg[ûÙîJ¶huU[Üώö¤¿tìI¾Yé×2)N:®…´ÿ]ò_¨ßÀ™Ì¤õÀþ·7ߏú œIVýGQ¿ó“Lù¥Þÿ‚Ñ~¶÷?œq3¿ØûÿۛßQ¶óîŠ1%¼Ž)ÅxÖº¸Æ¨['õèÊ1*¹iùùæuâÁx>gNy9·aD©-s–¨`?ÉñÎß­äõÇö©¬w¶nZ¯Çø ÷0ó½z`T!þò]U±ý2ªâC#£#±IYsû[>-8=ÝA&Fš…ÛûL4ý<Ž<ÃbÔÅvifŠ;\ãA„Û–³ŸárkOÞÉz#Ń%?҆5'ŠŽ5·±xםæ|ð~úH’RýóÃ×%ªòÆ*A=FÕÃ%FEH ÉõÆSÖ[.æDs±2@!˜¢JÃjÅ¡"p>۟ü]ú +áΠ1§‘ÍñöN‹ÖÛ*î­ù=Ô¬ ÚVf\Gr÷©;SÒ?°-ÇQž‡…ù­’\&ÛßQ…yü×ý]‰ I.“ÇøÙ¨^.Z± ¢ÇM +Ô‰bT¶Û÷®¼<_ÊUÄeÆ;êæ´)4o§&­µè{+#\æ¡$™Û˜²ø0¼~?øÛçEÙá}sŸMÙúwITUøôX[Q-›‰9÷Ì2žª1çô“댷³gØ_ +Aä5¾Ö{žåç—†1]fk§È2¶Äт¥”bÇg3WÕ +ºiæéóÕ°†úCëäòWe'Œlù`kº‰Kõ?’”Œü}Ï?É_QûjlMq‘<OGuª{Œê;ôÒa¾p Hã–Ëû×ò¶8¿4ðÆe³~òLá)<ÔbT›‹Q'-Ù,ŒdõXNæîPmW£y_yÞŽ|¸iÆÎ.ÕÑí…ûï’ÏÕóäƒQÕÁìø`oǨoqOY^TT7ÆzT¿Ððª¬Šwqn5oj¥6¸}nqqg׍ëÛUÂ~ +”©¯[Œa{kNož/ÛíËª 7J”Y$! S¶[±yÐåmÇ#wß%åd'µØñò,y:šHJeµ¨ÑP’‹ô³=‹÷g©Ôº­6ÀÀ;±Ûù™>]¡Óôº‡Mh€"FcDbZW?àê̒JJÝ2²ÖYŠÒ±>;ìjûôaëáò^à6«¿ÅJÛÿ’¤ÚîvÿG¢jð\ÇÇsŠQ‡•ØñɃÜF‘LJPQsï!›b²Á›y×ü’:ê^.µíÄ /&` 奁[éd¶v¸£wPy=j›}ŽGiÆخ^”i±•Eáv„÷ü–/‰œ¤û7#¿S>œŸø î'•ä™óqìó"5V´5ÔÛíqWÈtÍÜË×ÚpÔ:³[mbr½é½Ù3kb3åýFæ²Q¡»“Û+3‡îùFùííÉpÒÙO]¬òÞñlîÿ§íÏÛUÕ±poø³Ø7`ß Š +‚‚ˆ""bC/Hôû?0÷>U§êڵϬ·®÷Ÿ‹¬µ&÷IH2¡…ÝöR£·ÿ@-—[$:7Iíß°jÒ@/cÐ(¶ÐådÉfüÔÉ49pP’Â’»ÒMkdŠé /Û91ÒZq¨–Öù±ò4Z¨¼ý`¨}b‡ ع0­ÌØí¼F‹¼Ivžju¶ ú‰ä1ÿñïþZˉiDÿ´š!ŽÓ`Éhë‡\³y@×¾¶œ±¡±fÙPù9{Ýst~-¯ÜPƒ‹‰Tø˜ÆuÎË nÛý¤â +4»E†u Hâ¹NkšžYl!'2™ÂÖDž;¬¬¦l>¥º´§_õ]ù6ø»ÝinøÙ¡ÇFLkȪœÉ¬ZÔêT˜pŒrZn˜8Xÿg¤.Õ¿(þ¿¥¶©hމÔÇj šÛ’‚ƒî›þÚv‚ò1ó(zQÁðü^E;ù«ò±fTª²$êÕݹµ¯náÎNý۞³{hÒb²È»GëÑ¥®ÞcN-…ò†&+õõ*¿üwµ¼Lp±’¾´)þñ)"ÛMH^ÄzOUÚ2¶7ZÚeôxö̝ÊÖ ¨tñ[Q<¡Ëâöb¥¿GK¬R’+«éþS¦µo-Š.6ìvºh7ßܲ.½Óa‚úö¿¨am +Ô(ÛNúÒ6ŸÆuv@sy%ß1ØÆà*»Ý0Ÿ„ ½®|·“úÎù,õ98]/#}<:'˜…z–ã—¹{è—r«™F)Z°+ ÇÛ6æ;ï“Ïà3µ×d¸üpsÏ}¯ÿ©Kõ_K•C:yCe4ýq6©øV4݈1Tž{Maµ¶>ý|{Ø{7™Ò¹/õ¾¨D{IY½wÆ |»Çk¤nV$ð¿T¤ zÑ%Í)Ÿ™ÚìpÝô§§‡ˆO æÍNO³²0S´÷_Ô¶Xº#ªî€FýôMº‘~ÈO Ê÷|†ÖǬ“wx'î H¦6'»öa›w|)ÿ®Ûæé¬Aé® õø¦/,zw2G"æ§4ËÍu€.}¢Âx8~kÖÉ,S>¤ûsÁÏõ·µãœù#¦»±ºÇ yå+¯©ð)Ùï楒Hl`ÆhÄ Ú¢6>zÂS“ŠÕŸ„ÛèÝÖÇZõ¹ºÆ-‡j7Á<2œˆ<ÔéÏ W[ùél­†™mUâ·'1MàrØój)¿@êOûÇ ¨yÛu-{Í ¢÷´¹|nìÞ©›‘3FŽjUºK+Q%æ¥Rñ¾ßvr¢ºÆ¾3mE=Öª]{܃gÃ"ê¦>Épª ýtX#®d!KTÙ2¾ÊêxMª÷0kDb ÔP/kh –zÒ6û–[·ÔG¥=L'·ÆHŒrT”ȁgâU “_Œ(ør2 K_xÃãæB¯93Ñ~~LçIO"Ìþ(Àå|ˆ¯Ž¥/f½>9¬5ÊV&® 5'|Óíq‰Êna]<Ì+¶#ËMçA³9|™M!™ãvý»ÄÜï™Æº}ì֋ÍdPž ¨ŒõEtœ)ú*rÎꎮHfÙ¿ÿ©Kõ_Kþ +Ï솰 Ù<´ò¥¤™‰JUæ¥ZtK$ÖÃUã&–R¯ZŸçN«öôF½{Dã@ ð6ÓN¿ß`½ùw2âŽîeiŠ"-aŽ©ÙÁàÅ +ɞqv¬PnLt;.ð¨4ºtñÃ…´ßôÚçã銡'eäÆ Q9B•2».*ž’¨DnËáë쑳‡œZÿ†ä1UüO¨}¨¨Ó§T=?\’`¯ád(Ï÷ɟD+~˜ˆŸkÖ{s[›Dª~|Æϲø‰<Å-¼ÞíLJǎŸŸöF^ñëcî"¯’έLSÜ1öCªm캛ìú¡º·ìnM³ÖÎ5ÁÏ)XO¯!½“§Ÿlsš›< !:”Je¤|-³Ï¨åçÉz¥¶—i‰™õÇ'òK¥tEðzoƉԙ™HÕ°‘k|CܹÉǗ(e3ç*k7JÞ²ÉÚ@™£ÕÒJÆÓv¬D"û¾}ä»w7³Î쯅ôÕùŚßa-f,€ÜŠ à緑º{IPõz²ºÎ¿À»}Ãá`W &ÏWÇ/d©±{mljNKšÛOªOÛ 6ŸNÕ­ gm­vÆÚ?½•uzn àöäãÑë>Ž¬àz‘ ë¬(óì}âóo [G¯“Úv~VÒùJãOw¯`Jɟ<Ԉxwr³B8<]kÁQhuýÂd;v—í/îк0·Y¬C[Îl¬6zß=·+ýð쾯—ÇkØ÷÷.™…°å\˜•nZ:÷¨›® %Nû-þ”ªp›¤bnbÃvšn@œ¥Yp…Ÿ+¨êñ›3Õb(-3i,GpüN«^/‰T®‚;5=±j³×YY\ðÏíý >^6|ˆÈÁ| üèeN±±wy›ÇyëùÆ ¹vT Àá?" íý×íƒÿ#•¥¼Ä†H"õ& öõ¶i²‰+¨gÑÛ]‡…0jŽjÁ÷·ý)û»æ#œzþ¼°›Ôˆyúʝ{ ÷ƒô»çí[Ë*·,ðÎ洗µ.ÏÌæyîmD¥Û9g…Ãþ°h“ÒoÒ¸]àóÖO“õ?œ)Gԑê‹nòOËðí¾áB(Ïp€ïwMoQòÃ5&ÿYLïྜÝ𭹸|6nƒïæÂøOIwjáY 1ÅPÕI^;íÝA¡q(ÜîYÖ~‹?¥:J"õ)zi^ŒZº‹{’¦HãeÉKl/VA40ŸWvR+zW•€ÒW'ûÛV/2÷d;2ËØ~l¬º9LwÛìì,ȵ¥6Êޙßw*žqO‡B(ûgø‘dîz¤ »Ùþ=ҀËÜ$*ó?¤Ör— ͌PKwG§>Ôz"5^ß^@º!ÒÓÞþEÌdݺÞ-[A¼iÞq)ß¼ÞZ¯Öe3ÉuÏ;48ëi¬âNûñC òPmÙ+…ʲì–4Q +&A”m~6ßõoñ§Îø̃ZÏNó00¨ï_èϧˆx°¡¬Eá û|åØ­ïQïøã´I¢ü˜XNÙ\Veè±sø<Ü,ê'¬¤·Ž¤Qè*w}3دá6*ó¥Æ\ÚeۛDÌïó˜Ûe|g#}% ù¹þ‰ÊjóO©˜¤[y¡ô(™qšW”‰áéƗú-(•¶®Ë*¹Ø’°zþv9ré‘Æz_/žåL\:áµ|õXÖa¥1u™Åmñ]ú;ð¦'»ÌW W6[ÝbÙ-)³Ì¶<^üé‚=½þ!.Þ¶Iwʾ’n´©$ÖÌ&R™5·cY 3åîW[ËáÑÆû¡:'`Â3ø«¿(;«el%\ä¢ÒðͲܣréÐ5ACòé¬s{ƒo¶2SÚÖVÜKÀäJt +ê·H$6[n8éF“B¢s³¯¤qCÐÐvé\àÝGWÒ ÷³'oÅïöî^yÝK»Idp'>#Í%PËxû£¬µ¯Ü'‘ìîkajW«¼j³\v7f=Y{ΕNpO`è‹×?ºTÿqóñ§Ô¡ŸHõë‰Ôý±œÆu&R_':’3K! éìÁÝt·çG¾¹æjüñõðM¿Nç,ôsN!Ót"9øZ±8ɾ?B‰hfø,6\·UY÷œl“Þ³CF &^­–ìp·š'X/~‹ŸO~;yéçÄä%ÚJ¤^ŽÅ¤â»}ÐìZË𰚬}*Ÿ•+\ÅÜè~maš}Fo5÷xۛÞއ¤@üÈ«—@*ې¯—}°é¸“,+½½"“éïS—ê*ßÚwéÙÖ#èó Z¬ðvw¾Rçò·H¬‰v,wI·où þ6¢wÄÃôuzwÓcD=F‡[bçåf®±9œôsdš4cK±1rwE¬åñ 1ô7ݧ2ŸA¯z›£®Çviy—ڍe½´A—«‘7§Ï7I]óÙÿ ©Kõ_Kþ J}6Ĥ/ <ШÛyÐÌ.ÛïA‘GƒË~LºN´âž§ê\¹:;Y;Eãøè®Íý Õ~ˆùU&Ýï¹­_ÖF(mæÛmº«båRЧ¶T,Ì=¾XŸw_È(Áe¾hM.³…u}üžâŸÑƤ¤;MÐX}r ¹”›ág±ìûteŒ:ƒñŠ¹/ɯx‰ÚãÃɘŸ5ŋiò +¯Û»'_7ÁN¼±èÙx¬J¼½|ꤻèä 7)už™™2ðÓamúUàþôk˜ËY\Ôæ¤8ÕÈßÀÌ¢ûÇ©ú…´“Š/}c÷ C¯énPs;Q·ûÔ¤Bºð0[O…×3Ï·x´jôQVè÷iWY(gnËgöˆÌ/«òR¸.­oô˜ÞÒ!ÇÍz8=­Â ¡Ïà +Av>QÎxKBÏ<¨ÄF—Å¿!ýmþ¢øք>¨y4 +ëGҍšQ´/v>{¼­ìëßû6~Ù?j̉‚ö[e€åEqöÙïyî2RÖh·«®ùïàÒ²ú\Œ"sö…yk:]¢Òèeq¸ƒ@³Ûô°Æ´°À˜ÄâÐà³ú-üP >~ÿ„Ä7V4ݙÌ#ùaaYèa:¤Z¼ Pfxº^3%¬)”TÌ,7ۖÛ֟~I\]H¡ZeLË¨tž¦9-I®ß'×cã}vâ¢xÒy@i¶444\qÒvÖÜojÙÛ(©xHͪ¥…ŸýáhGΑ»5ôÞí‚*QñDŸ_mEΩJ4¸5Áû,¶Xc>ºZÁ ±^n-M ¿Íœ4+ÔA ¸7ZM kÃÕp²•3苇Êèà5n%8M·ÔÙ ïwø+¤þ´¿(µå b²]%ÓÔٍ Ïô%£p·S=gg”Ñ׀ÅeñÔãê2Yãï'¹ª"jÙ¿×bìôš‰‚Þ¨iÝà,Îj×ë<ÑpTòPÑm$îòÈþA@œúÂfðß"©xj’XsIù𤒦f¹C̽ž¨Ì3ªé·ýgn¾EHt˼XÉvÖ¯êú"i€ÎiNjå×rzušX BoÞҐN}!M= Ü?££YÓDbз´Û Æßšz9Æ*³*ŽñÆú-@£ÿšøfFoµÚ*¼ Ô¥¢n¨åfm4c÷„¾!?ÜwKë"¿iÒýL[Ú"–ªR{'Sj¶Åˆú«7ü¹¿˜¼ú5¬¹5*›ôùäp ™ŒF$ã¢ç1uŒq^ë?Fútæfñ,úH½ƒÿZIÒ0®v×ä¡6ã¼Ïm¦«›=«\¼Ž,֘ @¢R*,”á½BÎ +ƒú~^Z8a=¬·ÿ&Cበ{ëŒ#ß²”Ž7†Ñ‹±&áôxÚÄף˲Ϗæ*Ê~šÃ™>\Æ ó·¸AX=ר¢Öّ.Ÿ[~z¬Û®¡õgœÒâ·ì"ãi4W>H¼pfy¶9~cþHˆ‘G\© *É֐œ¹hg0Þ,:-š8:¼ñ#|HC#r?Pjðœ¢Ì a iäý ¡à»ßâü9œ6G«Jð2&tÁ!ô +‡xåa"q» ÛOg3W‘`;«˜c w¸Çqî§éžÂD`ÃDðRøŸ—¾;2˜³?ª8J˜ºOÁäLê9- ØÁ©Òwö2ÔçC2úž:=_½{~GþÉcþysd¢ý\ž°SJØ´ôçæËó¶rªÀ”Ðì·ç9uܝÂq˜Øž ñј%êËñ BÙÑ¢Ñä‡t'³<…H4"÷Ðwd÷Ôo®é@Ðów£'`÷[¯Ÿ³žÝðìº]iæøjE ¢Ïo*ϝ*Ñ  ªyk ÌُÃ?þ´ƒŠ'7 È9ƒªhXq­ºxG\ù“ ·g z‰Ëy3x‹H?+•±ÿ©æ0ÿpʑþ¤/ýŒþe½’Ûz§vïàáþÜðò´h;UqŸÝª”ÎlƒÁìñ üG©¿Ð™úÓþW©¿ø~›ÿEê/t¦“ÛÿUêŸ:ßHœt@µqê<]éD§{ÚÀ5Þhj úp췕I^lR.„ÛÐL¤òT+ØO{}ÿ³ÈýƒcþI?…´wZǏ¨äDÿöN^^˜ßܒ€g·:€åF2Ó^#B¢»èØsãzñGÜ{û° ñ’jûßb¥ïc•õ´þsæòyéꞺvIL\²¦ûoܒßíûö»Ó̾e{»«av>gÚ]Ô_T{V¢³¿ì& M4•†€ÏqãhiØb~†å­à2åÇu&Ž#~@ä_lCA|`Úþ1.üì7ļiÞ ÝKY \r+lÜ2|Þ;Wé©;Wyè?yEño“£~¿–ù¬®Ûsä ·ü†òƒt+É?nþ +JÅ×=¼ ÅÄšÔ ÔòpóÏ(䚘ȏŽ—Ä¸Ç ®‡0ˆøÓ:ÑI½¡@90-_¶ÓÜݞæû˜W°Ô¹Kzã˜9zë,Yáè@¥çݲNp;|®kù½èö9j¯³!iæ$þ Š?G‡Ué]?i£I ,m©ø0‘J3xOD›çDïË[æu9÷Š¾ ×mÛLJí¡W¤‰[)/HzvVvœÕZýãU ôûX~²Œ”•÷Eß =UYEVZi«bLþ7U +D *†rn2€ÃKj–¦–Ý':ov¢SýÉÚ7צõ›•ð…ìя¯Í´¢W.æ ‡ŽØ¶åhVïÙ;MF÷½éMnGv?3µ ³º^†ŒH|$ç=MŽ8YÅV@8•ÝæP¡Éõ?‘z9þµäŸHTæß ªê#}9Y£>Â4]s=Mي¥¹…9P¯¶ÎQpÜÞ_‡êÓõÏj5r©’±75¶ð܉×ÊÕ½t 0Ïg¬y­œžž #ݎPLo·ô¹³»ÓþŠïç‚%*ÉíÙÒ{µo¸¯ßàŸ:úÍð»O–©ŸÄªßM=Yþ{XšlbýöúŸC(‡ÓKP(÷>³<›ã²ïÇþ倽2×å Î_Ø÷¢¤wúX ‡ÖIi}U͌15G¬éƒÑæSÏ­[õìŒ$0 %õÓå/¨¬Æ ê[c³•D§ZŽ@½-ÂiºÔ×;`£—îÉ/¬ÔH•=sÎ^õõn?GÖƽÍ:øËx„ãH÷ˆÍG‹Â{愾5߶+Cß֕ۖêíŸÒ–Ø7€½–‘¢EÉèQ;%È-v¨’ÿ†tÖùÅ z«%R¿nRûç¶j~÷çÔ8MŠÆ¶1a½)òAqRÜ»Ìmq¶^ù~/ÀÅçµFÞ-]¨^\mü¾T ê¤ùl×”U«“Ýá­,U¥.Fuc(Ž¸b¢MõÂ)i`B^VÉ­>¦¿À:¡NIú¢üñ)¢&Õªi´ìøíW닗ÚÛ°~å•Û9͝Ç {6—ñùzá{«»¦\°§:uöšëþ~S.¼¤Wq‹òª™ÝM*ùŠ@äKí­Nâø¶ä-R£ñ×ãlÆC¹‘ ÿ$ßZTQPËaJRñ“DçåQICe‡Q¸+L_ù܆öjbek÷e4ýmîE]S û„ŸÏòµp9å·ßë&Àm¿‰–$Š¢³;¹@ ’—Û¶ÔÜLmcÈ< +mJ°xV0}¯Îçóƒ²~õRdµÝ©±¹l Ë1¹§4znÚ'×cE1ûH,¬¾c¯µ:~»èêÛ§_<dN  Èß@ü  Ÿ€Ú1™Ô÷+4¦…ÂÛwºÑzô¼úuƒÚC4·¼-ƒsÙ¡·Ÿ}ÒùæR<<ûI~9™½81 Çíõ«œE±ú:˜dn ¨,Ÿ+Uîô¬})CšÂÔböFé¢U@éiTÓç~ùHóϛ?¤Â :‘êىT;™W7´V>ŠÐr5 M³én\sôÄ,¸Úú‡:ê4«.³¯tšŽ !·«(ÌsÏÙkGYïÜґ9\þÈs›·ê7j yβf˜ïÅʕÍÇf°°º—ñ’>ØãåÍõF¿€ÚË €§ÂÔ˟hd4³ãôøÝð@ÛY†µŠÓŸhÝûk¢Fo«‘Ú´Ò§ÖÛcåÑKâv³õz˳f·{‚ÈOÄiùXz—EKÙ>æÝÝöEöçüì½èuɝ#"s~zL]sWÔF¿€U"U3ð¤Ö©ÄՊ¹G'z–þvó%gMXÍdk_GKCL¥Î¹©ûto”H((³­çZëMÿÒàÕE·ô‘Å%ۂszÑÈቹ͐=ãO1UÉNs«F{Ší¶è ÉlƳ}g;ú{¤1Pé@s> jY?8÷­h܃{]ܧ+ïlgмGw³ï”ÝjÙÖf÷ïøÀ-„¤–{¤×3‹Í‹ó(v¢æúúh®—kœßÎw½‚4;tŽêçÖޘÄì¶ñð…¥fðê¾ÑL`DÑQbúÞ"¿€ö§|Òía"©øÉ4;@³êNs;ÒÏ.¼Ç|‘µ¯^8ÊêYµPWëȹ/¥;Þ-´/Æùæuʪ¤oM‡Zn”êj>óÜìÈÖÅiáîqs~¹bLMs'ö:ÎL6՘´«­ÅÄò8Vûšéjíçú÷mAí“Lš«å.îf‚½»oöqÙÏù«¿m?tÌÆÁ ^2Ue8µÄyþÓ罪1^OF»ôÑUõ¶Á—|öFÎG§=÷§5a€å§Åš´î–9éã.›,Úç²-$Bï4Ú»¯(t{'–¿ÀÏjš/‚ºü˜ƒfudžY¿LZYá‹\ýÙÓ󅪡²ËA°õQN¬œ  +¿¹úJعVéMÄåJñZš­O…`K ŒùL»=ú~E,A°#‹§NŽ..J*ЈRÓ~Ë1LÆBuðPØë€éÖ ~7¢¾½º_à™é͏F÷¶µœß¶“ê%™åÞzBÛ¨-6ß-/²•ÓOn;ºm!Öü«,œÙ¢|õq‡‡^Xïý¨‚³YD%g¥ñ™êCãâ³ß-šýþðÆ÷‘!üêv8ZöeÄö¹.ôÛ÷پ篽çÉãþï࿔ü†{«ñ§KY<•]¯*‘+€êŠ¶Au— UôA%ÎÌAeq ’Ék |ê¸ñõ]ïûñ•{מJdÌFĺt{\Ԝ\†¡ó2'!Ç<È°S|­Â6€„— µ ÔÖï”ïn©,^-« _~әÿ«Ô_èL—¸ÿ¿HM–:e¾J9;Õ|èÜq‰Î{TU±ÔÕa-Ñ©ä· Ò©¥oP¾wœxiWã÷ÝÏ޵ЮFë’Öˆšü±º6 +9킇Æeþòóò¯ô&KϝñÃËçí›SÅ(óÉgíÉgnçC¥ú¯% l؉Uƒ7¨õabü Œáª–”%eâhªÅŽ*‹š*Uԍ©B¼WÇW>²ž(jºûfèNöý°#nÓ©ú+(nð—k˗ÀÙÜ«e•@bˆ‡§ªŸ§³82·§‹>õ؂Ã/ÊÎ+±ëuƒŠ<êé礥dYí$R—ý +€&t21̲¨2‹¨ýD*Š;1”Ö~}뢵tB÷ºo…Éênð +¦ úfúê/ÄUeÌ]¾Êš¢eË1>ÌÝZ—Ši¿¹¾Õ“™wIùåøHuÉOÒ@—É$03“ÿpKC.]ÐUMʖgT_ŠªÅ9itAÃõĪuóUˆZ¬‡<¿m¿¾v + "t:¤€aét‘ƒÑ´~wÏQÒä¬Yå~—‘šf͕b@Éjè?" ûÇ ¨”²(ƒÕTkë1€P.‘ +z€› +”ÀO¤ºá*1î3‘ª©zÒ¿8'†w(ˆló•½Ù»ËMçµc¦£ R<«X:O F;Š÷AýròTÿeÛ«\ïy—ç͋™Ä!yþCÒ[ô?{µ÷÷øCg¥´NtÒ§d¡ªœ¦?+iXr©r0ÙfäUöÂr×w2#zD½Âž´Í¼†Ýa9Ûߺ?Œ®w’¥±—7…©Kæ$Ú¹ŽŒS=¶ïA}fš…q¼ÜߚtöúÔŸvz/%ö•f!‘Ú3 zs'ÉrÚI¤ž÷aꖮ'À&Ž6¯™ã»+Z¸ÓÁ5,™Žž¾zúDÞÔç2îœl–èaÁv“ÛV‹XßÜ#«»¼[;Ù,4IíRŸ3Ò¹{ŽùÓø5cÚ<¢þiÀez•tǪ̈šÁƒæ –K}¨ôÏ9r"jøeý樶O¸©ƒæéÁÛt«*æØ,ÿ Ÿþ¢îqYÌÜ>O¬dj/t½œÖ‰ÇÆòÔ£.õ #kbÓàÕã´É ß;¥Pë ù €Ê¬e‚ÊÙKt.šxRáícšù¦lý#´÷¦¡qÓé0šÆ| ^š’7Åaæ{Ýâ¯Oó÷yKjÀ¹è10¨ . dõ¸—ÏÝ×½¥‰£ zzXî¨í#æP©­–ûÇ"åÍËK3Àü\ÿ‰ÔzbÒðHUF€Ãù ÔÔVœæA…ÓdH|¦äk‚ª´_2çXÙºhõ¬öáŽU@šBÏ,÷ ÝXU77ÝùøÏs¿´pO1S +Õ/òΨ¹š]>Ë^ë0§»„“Ý¥ìt_¤$·„(u0ìø=Ù®™tûB@Žƒ¼IÓ!ŽÓÃØ/P¼öía¸‡“ °ãHwõ¼ÒVpñ¸»ªq‚Y!WÒÅæÄÃùUöµ84 U}ë·c)?° +÷ÏéO2ú}㐫Ê\HBc3GÕ!¾SvðDPeù@Eß@¯çÜàPΨWˆÔú¨¼·ýcŸö:JőgÚ3ÌÙHõ8De.3¥õÅÑ>üY´+âé8B•£þ>¨‡jé{ö%^åα¤þ Š£v'»S®¹Ëäɐo‘íì(Œ·%Œþ õþãæ¯ð§Ta®QÕ¨mÍD*²|ºý.G¢¾mS'ìºÏÍbl…“õô^0ssò®´ÞçŽìIŔtGþq¾³…©•%ك¶iЩœw@6LásÎV/qïmiiUøEˆŽùês÷YÈÕÜÚàHúÒäöó5êF̜§ æ}ôÄ |r)TÊÓª¿@Ÿ Çm³ƒÇ×)£&%ž§—îq¹ÐF«¥&Ê(Ïùj#o¯ÚV| i7±ÎÇ­öÏür™OÊ?žÛE+·iu¬þÚ ~àö×üîÞû~¤‚êw•èÔ2=“1Ñy‘ý¸=·3/u;,xtpKwzفŠwî3A\ +ßçúôThçæ‡Ú)XÊAbÄXœ®w9ü¶ÝVr5‘{pºi]ø˺«ò6;Ðõóžw V½ëȪóO¤.Õ-ù'@åIÞÔޕÒdzÞY"õ}rß½Û!ôôu­»S´ÆëLýV•©îEXÕÆÆٓ#•;{~ ¥‘k¦±ƒ»|ûKo+ŸÅ†k®°ÞÚ¤Ìñ–¶ú|Ê÷†M"Z;_ª«\¾Õ]e£zg…Õºí_àOóSù¸ÎÊ<ÝÈ­ÆÀr¢QméûW6:Þ*Ì>´®\¹®©Fë Z÷¾jÛ±bz"½’ØÌ|º­ZʜkJyzÝ'VkF q•»>ŽtQ3¯TE±½4D‘†âò¶ô:T…÷ÚÔ|Z¿@ò&]Þ´¿—Ó=ü PßTÐØEÏ03n=¼GñíØ¢­½ïåxðße|X;a»ö±† ý}ïыغ>ٚܐàÖ=[Ð낙TZ+ZÙõ5+“Ƕ=äïR:ï(}÷à{ÉÌ.Ý|‘ π~lÌ̲ëUJägAC³Â<Ó$–çC³³:áÁÝÝÇ"ۄ2þ´åÛxrÊÄãìêÔg§4=F/€üH£Tÿqà Ž@£F5ž‡ýØ2÷ñ¼Èâç¥U'—öA°SçY~Wëë*');ÃB‡f§Õ×B"Ço2çœ3ÓE/áO¡ZÇÚÀí¢¡ö“»‰ }>þÞ¯›qîíîG3´dŽJU6wP.ÄçlT”Šì¨È|™¿¨Íגô÷Ŭ‹¹“®Ð·óiù‰ÓïžJ¤?’~ÀqaM_9n<*ÙrehÒ­®`/Æý«7ÓÏPH¬V"À[íEa²“kUt<MdÂf†c‚øˆ3ôpi$s GµÔwœÕ·NÜßéqïýÖu¸J€0{+Ï%sUÄóÇu·j²@“÷ {öEsYml=õ:Ý$ú֌yÙ(Ä×ù·Ú¼'o Ÿƒž‰úq±­m¾Ñ¸O}‘ãgTŸá>4š»¥æzå¶X%ú΢C÷ÛÁLè N톗ۣ*•(y'KPþHós½-Vøæü&´ +«ŸÕ~Ly¼/‚,Ò|k““ +Cö,ÕsoüÏäÅé"œëx§‰„P:òÕas|^†Vº}ßKCOÃÁs'}ûΞ/üxnÕ5Ü õU»+‘‡qwTvÉN|˳…Æ鿀>zegLJŒà2gÂÃö)~ø Þëi̤s[ÛËá«: gy!žŒ‰c 7Cì¹DrW–IŽ¸!ÝÉ ¶È}n|?öìtî†çÓ­;*ìŽ²Ô_zeÚ*ó)·ñ&ÔhçÜA¯uæWé°ösý{¨Ð(É +º ++5?Ú|dÏοšE·_oþÝwÂÙ¢tøâWÌO¤±PFÔY +½1¤ÛëÎOq4è÷Ûhô‡ûtT´S÷ékÑA«ÞŸžÓœí‰­3—ýÃiÚ4v­g³òîúÛžüüé¢0ÎT;òíõ·Ñê2t>w\†\I&g9H ž+qõ¢œŠ|5á2.ޛ·!Ýr­¾#ñnO˜L^]iÚzw”E´¿·o¶×ÂÄDk¿Ò*zO¸ilýt%ݬ„~¯q“¾H²hýõç±²¬7s¦æœ‡»_”v° J…Æ”Nï(ìd½ÒZó BF7PiWÁòV‡@ïA9¿¤@I^'ÿs|8ƒâG€¢é¾@Q-d@‘†J ˆj Ø'; Xۍ㋮ÏâJÙeߦÚ9D½£‡ín ¢#ëžZ(«îôc§KܟëÄÿ-õþI¤ºïQ¢RނÊ$R睤ì;€A™$:kË%(é¼JäI¥òÝEïh»¢šM¤ +õr¢wÒHô®zñ%Ú¡ñ|}"©÷¦ð¦5Z%ýµÕî_ÉL4÷<~©ÎÄíŸ1¥zOe¨‘•r!‘ª_P±kÉëù‚@!k‰]‰D*¾NLɉTùzIìêډ]£o…l"¶[þ ÏõA/žË«I\ëԛÚ©Û.zXÕs؞¸—`¨¬/^N~ŸœJÈ,ýʏĐC”ÃD礗è$»¨æ£¨ÖGP-°ßD¬Üøñ TÖ#PVe +”ûºJ–e€Ò:r@© ø­bƒ®Cñ"ßmǕuw𾕠üm~«7Œg¡ ¢KeÃSî,z[õéܟò=üö…¤.ÕÜü©½=(Ø%i£ó\bMU¢$‚êŽ}‚êJÏ$zõ:¨lNcPöåEÒ®bÒ^ÝĤrä‚’±q+§ÙâE¿ Ç«Õ}ßÆÝñ›òˆÙ¦äMĜ#íåwïW ºÇ8jg«Ù •ûˆ. ¦ +Üß”$1éjzùé7`›K ºF<Ói`·ªA””‰ùd"[“¤ܗ‰Þ@JÚA”H}ç½xñ‰â¸Š½ ošõàèy0[›¬B‡yO“·H} Yò Uº`w‹Ÿ‹n5ÑøxýÌîªC“±x˜¿(g°Dê‰1@etIƒPu @Յ Eì¤îó€ 4™ÅŠýŸèîJ\] +š—ÞùªGvoýŒZÍIv^xíŠÅ«ÏUà@:åÚ~ü.Ž}´Ý =UØîÜÙXK%úê퐋¤ëìÕå.«Êq¥7£d¬ûÒÐÞ-ù(Wç‡Dïþ +*’WL}¨‰TNÝ ý\ @© ®@Ä5¥JEŽ.óá6ì^Îw ƶøô'4â{§u#M:çåÕ¼[b¢Š³¸fZNuÒAlZãVO·cnèӒŒë4Ëék|¾Ò7\œdM˜ý=@¹ÃA5ͤÖË¥?>ET ÅáÀ³Mv—<Šûqý%áQ—/®¯‚Læ(xçvïàÎYçâPP2×5ÇjõAøLý{$±xü¶vC_öØÄÁ`cTß^ê:»V{uzCê\(âHÜö÷HTn©Ê+‘Šwó)ø,Q×Pü¼$:£J%f[¹^ÔSP䅴við å1w¯dãÔFêÎj;™ýcHNÔÛçñ¹˜Zg¿^ +”{-·§‘ÕðÜeEruݺå¦Ú«¯ÔCܟ“Ŧ˜äU s‚üÒY翖ü)”ï ªåĚÂÓ¬(pRñ¹Dªù9ƒ:²öÃ÷Ҏ‚½÷u™žœ·Ä‚Ýt¦S¿ÖZ­®¾ à†À£±JœvØáªfg + DJv‹pD. ‚#ˆiw +f˜‚:zú^¦«ÛYOéðƙkó‹Ù¢ÉWKxãï‘ô%M•pýLówÀI­·©4mcú7^—ÎëóØ»~eP ¶Ä~X­˜3¡¶U¹t´K]‹-§£N· ÚÐho7·¹;¬¢Œ+Ô5Gk!?*‰ÛR7â"js·XÏrôµßÚXP)¤7ì«ÔHQÿ{$RGP…e+éK¥¨aX³«½·ýúí•nžl]+¼ö£Û˜_ÃÆ¥sälÓõÍ)-‡ÛjÝÚ;°Ý—^öx÷¡¹‰pòš³m¹hÑÜ}·ã6Ö|­¬]ú`®ùz-^wÞ÷ìOµzŠëFò˜Ÿ+(éÖL·ÜèÔAmK%R7c5¥©á6Éï㉮,פ³›øÒkMrÚäÔ+¯lVšóAC +óÖî‹=aJŽÆ¼ÉX8Wßý³³ö*Ãîô쎑Íú™S‡×êÓ'j«Om% fŒ/ÿeçqÕm2̈́§h#i ÛDç…8„{pIã¡ýj§§ÚÁñy¹ëíÕóÚ,ö^ç¸WúªÒÉêhP–w½7$¢b£!Ìúl›§³AãT—Ⱥ‡”§Ìž½P«ãäÈÓÚô¡Ò…kÝ¡.ü¢ f¡J(uwӄW®ü=@9¶©f˜T\4Ò “Tl_ù…CÌεV9ђCîx[ö»æ%è} /^ßGêhd÷Ûú.=fGü4µ² oB˜§½Z}Ã)|› íúABmBŸ¡)I͍»¤Nˆ¼xŽ·Å³!––ðÔ¬,)Æ,/MÍþàgÊÑxkÉË4ïø%5Aôè÷ö–å‚™8d¯öåÚ²$^íÒK×ÇyÃ:•:»—â°s Å"»›BTԄò†]ˆ•‰AƒÉlí.]š ÃåÍ)¦Ãڂ¥czÎmŠ;Ò÷çWR852óNu[™;ܱ²h(Çòß#y“f5!MÔºF¢ó’¥£a¨QÞ}ãOmQ~¦Ÿ¾ïÉˀ3º/ñ¨<ú~¬Ù]wß_6B1g•À–rÚٍ÷Á ìÛ¸VWZ; QW@5–õF±7woá„܍ÅLÆ~ +ôÆyzX{ï)Øcå™ôž–È>ñ³`ÿ¹þG€Ê³{NÞP‹Ôø° …ò"Ì4§¸»þªã'žë fC¯tdіU“­^þ–µ¤I=ô……½9Ný¤K\6~Ö2«ó`Y n¹Gya¿Ú¼W Û³=©Ž¦XN˜ÖøeùUñ ¥½ð ŽT‰“U¦Xú{$¯'â'®«aÒFx}ˆ 8][ª·[À÷ŒþèEj³¼ÃœŽ¥Ê{éqەUÉâ[SÙ_[ǐÉ+aLÝÛãìÂ-™E2Œ{Õڏ[ę’ú¸1“Ò¼ƒØmi¬1øY…oP_[ÑC:ÏÏ#߯ÅqþÊ·“5ëiˆ¥‘÷jZ¬öÒ~)‰3ˆÑy§52×q†°˜iOô©q |TIùuÌβÕa™ ɸŽC¹gb]o8êjƒvK  ܇‹žVG;Çmu<þAò˜Þü4ŽLP›ôhô7Í'° ûFÉYûÚñƑ~,1ÕDû}ew-Íÿ?¾ÞtKU&kÛ=‚}*­}‡(b" ‚(`bƒ-Š€„žÿ²j¼ÏW52ëÏÅ"ÇZɽ¢Ÿ3fÌ0ûÊlvæתfwcg_q¥ëº{ÎÛ§äV’ÁªR‹8§tüöɑ„u¯d³ØQwyŠ¹Õ~Û¸¶ÇL\^®™å‡~2Ëo¥Ä,å´·ºïêÿȽ[WPÄWIÜ­Uqw§\‡rԁÜ;öYzXßBWa†­™Û½ÍÍÇb Lé(4&¨–²äbØu£{t§;·› Ã~öº +}Ç:5ShCƒ›bÀfÓc:™ Y ´ìA}ÓêW~ËV_•b§:­^Ïnýo€üëú¼Ïaq¾N‹½Ñh™[Çe­ÍÝq®Ëx!&v×j3o$-M]õIy|à{3iJŠ¦‹{v©Ä·ÞøºzuáØÿaÃfk¯Rõc¡4Íd‘kqþNmè”Õ¢ógsˆÉ¥&9½vh÷eõÿAâèúϟüàÕ¯3֙ÏNµ½>9*[¬ÔW֏ÑÀX¦ '4²û:«=ž5•}5{c1³’¥Úý6ÖLÅàñÕxÙ/ì1»«å¯n§ñø‰ëlCÚ©•˜b³’máw¥Ú«ë6=êÅÆmè E6ó†)êq!;ÿ—n­ j“‘hïÉmriкúQEs‹«êü^‰|>º¸²­qõÑEòz¢ÑD!½Œ8wh=µ/à”_³ËI¼kw뇃a+¯Efça3_ÔRt©½È6TëX§üèR”ZHŽ+ԍ/oԛÖáP‹GíwmU KÿÇRØᶈ/tV~ÚgMD7{³)+ÓöZ&‡Z—=éZÆF–`;1ú×qÀu}]ÙØ"Çm‹÷5†ÏYf‹ôäu3ÿê9téÝ86ªßڝš÷ZaÝ0éZì²56¯ÕªÖÄf«½r$V3ϖ^qfæî¿ðãRýŸl{I¯ž_7œETמ­]SÍ—»q~Ç]%Ê»ú‚Õnž<7¥ÈŽÉ +í¯“ähÈe©y1ôunwÞBã(#&ÓÕÈ ÆõÞÑj+±¿¬ZãζšñÄs{üòA_ÊäÛÅK§UºR’ÙJóc])Êff`—5­“+M8k_þñCã×Í0ž¿–üÏ-û“âvۅæé‘eÓþá³“gó¤–Cz·Fì¾T#½Dë-LÂk«¡”¯Z£v©š¹7k¾Ún•‡ ª[:-ÚÃRþÃ)År†Kb žcl SÞ=jøÓûß0»1¯=²Ï܄+À¥ÆS­t„ï‚qr¶)tý™%@u¸Àð¤-5åJgÒðL49EÍÙ»Q7ûûu%ÇVµW€¦Ž£´åìt.“!y+É-ìY¼®±°XNcŸÂ”Ñü|ˆdól­š3G­f6¾÷zٕ* ¿~柀) Ÿ© ÿôÝ|¦‘ž5A¥Ç€ÈÔ-€;}༑ؖ¶~²ë¢2À2Å9@¯Ì ÎèPs}èätN-”©“­(5€Vñ@I~ +á¬b¢an¢Ñ“Ý3ìlúË~G÷ÛEæoü¿:÷äà, ˆÎ¾ùãO›U@tû6ÀCJ5—i€—](õ˜H•©T]hر ^ŅzíÔûxT!¨·S€b4ÔY ¦z¼ó­Í;§ÈvX¹"IvžW3«/žéO0{l7íOl1WFÌ¡ÔwiK³”ÄúÙij£b£l¡ØõÀ† uò¨¼;Ûä~Ðb]ÚX~`C½Ú ê=úPoº(âPï õÛm·(Õ\¾ÝÂÔ +ïÝìæe ËçfIèž`ªšG¶„_?óóØ΄Rkpº{„ÚFñI3€¬ŒT@»Ô{ö‘¿d`;ÊgP(õYlÆ@]eÅ®¯Pìñł/@wŠ+?M`qëÄûjC}» v]Ö(ì¼y~ÑúÂۇp%1~}Õ«GŸ&`7k +Ëõº¸>vaiJÈ¿ÜÒäb7û±pda¡°Eˆ +ÀwõÔہÿü3ZÀòÕ¡Tiwƒ¢£(Þ_£o, P"&>•ò[¢˜ft1m9¼¯ozðÜ>6~{ÔYy‚3žßJv˜øÓÎÍ‘N«Ömø'þ-5ŠW€HmπėPÝmÔÙbJY´á&žþí>Å2U@4Ä>Àoš %¹›è}º2ÛwÐçè*ҏ¨´¥ß¡Wj§Ãê°M~Ö¨TÿÒócò£<¿tqá ×±q­ÞMõ´âò‘çáˆc•ÁŸøii‘3…O®Á^N€œ<áúºa÷@Vo˜I údûV Èûš„…«Õã܎]TŠ*ØS k¶±æ÷™ó +¿ãó«Uà<5à"¿ý™fže&GåŸÓ§؆’î'žš]æíáÔµÖëÑáàÂý]YázàÈIƒOmqL_@)ÂÅõ9Ń\6 A®ùןø´W @v׈e„)‡~îBÆp̽˜}^ö;]oúìã«ÅcWŸo87q½átx¿Ë£^x»îÅô­LîJ—¹òêž[T$»HN”÷òi?p¦ŸRώÆVrBÒ^4W̟xá +¥¾¸ÄáW¿‚¬<È'° ·‚7w,Ý@Nk£Çw‘d_,Û®<Êµõ&2çIélâî¾…óôú¸‰úE§ˆåy-ÞÓ:uqO)úùp{+â{Ü¥ŒÚax¿ôw“H෍àÔ±ÖC¶µé7@cƒ"ÑßxÃÿé7DMµ`Å÷o {Ò w˜A¾L&ÓÒí]mf¢à½c¿¯tÓ@Ÿø-Î{…V£z›w­‹±K³§ÏVåÜm¶$wÑW=ݓ¾?›«õ¾ð°;%w}üø¡'…Ìöµ¶h›)M;›~4×DeA-/º²]éêŸx/œbº±.’dÝç"ȗNbrßÝ:ž”Õkh¶¯IàØ«ëf£'™í|î÷î +¿Ò¨›Iy_tùEN‡Ù¥Vw§–Á©ÛÇіVuÍ^œ+k½[ì­4½6}Y+¬ 8,Ga½¶P±OŜÕܒYm’È”Ÿço¸üÿÛ5EŸ §‚ȏÃ䎦Ù:zåšÇ ՘_žCãñðJï\xm²ßÏ©}#G±Y%÷“Û¤¸«åñ:üÌÖÌjM»­Y«Ûýð®|­…ôV[‰ñfµ¼°ïó²¸U3‹Š÷¬=+ëï{» ·ÛÕüüó%sâ_:IìùssVzù çÊÚ¹Pªä®ÂEÛú;…ß? +ññ|kÌö“Óæ_GIÔ>ûÊÜÊ8tö:ÕÏ[TևɌ^I4åƇ ¿Pç¾lÎofóLrtÑh6f¾ÜSÅùÆÏägÛðaüŠL@ü €Û”ÚülaÅ_°âÙ +(Pmñý0gFЮ‹§èÖ6÷gíç8ö%u,¹n¶€{{5&§IP;ÍR›óÄWçV7¿œØqyQ#MÊl[_åqnnáøxžÙ医8—fÎIM29=‰=b*çZø4)c?€ŸùçåÀn_Òa_B×T9€/C©7Œ^€Ó^}ߚ=Æݬqk¢•õi ûûÃ/Nxrvw녁.|V£«^<^aò³ñ•s:da‰°ø¡ÎjCZNåöBS¯vj¯NF´Z.Â’÷†˜._häO"Û4é×Tïgë;¿C©®*„Ë49öI„yU#R/]i«/퉵{]Äã–]H·Ía:}®Æ®,fb:6ÞÂ$­w”6ÛZN³LuZX¢MµŽ³Î\ qÔ)½£8¾F©O=3êTè4“ óÿ 1<þó'p„’ TJ܃Ü~BýZ}?ó\ÿµ½[ÝG™Èv¯¬^ï»rï)1·éÓÛވF|\>–øÅli¹»Þ«JþL^4½b½ÄŸ¦V 21º³ì˜y´+£ô¸Ô’Ñ!%Hƒól.ãúâö•—OJÚgД´ Sß?‡§œÛ%íò¨ó-N²ZEÁ¤Äú·׼¿:7ú¼cîÐè ¯’³êçÖ>Ú¯W÷©ã,héìêöèy™ Uoz ̗âÛ©÷¤ù\¦GPÂdÎȔ$’¼RbñzñPR…»ï&9º†¥Ú&5³‹Ïð2µ?bλ}ÿ â%”êîŽ ß÷bPxb•p¹òég!J7†‹§\fLïur2ØöƚºÉ»’™ÄuRý¡elxm?'„;½=«òZ±1ì‚QÏì|¤ƒígD¹í䆥۴*TÝ9; ®§.„-.;ßÁ¿Bu¤}„jþ ð3ÿ¼Àʅ+âuyû @±’/Ýó¤ä=& ì‚Ê.vTŽdÕQ¹kÙúh5uªssÕ./uLìoµ±<>¨õàpúÈuԟ-|I줓î9¼©›¯ &Ä ±aËàY†c×Ó!—’Jk.%çbnåw¾|«Ú|‹¤ã?H#€Ë5{…\õWŽß¼?¼çýõ3zD§Ü§›ÞýCqÛD̦H§ÅE´úªú.óÒg…Rn£Î™¦3i¦‡V¹¤<Î܇*ýô<Žù%ÑC¹ŽÓ(öÑN™î ¶²Ð#øÌâ“’í ”jªìr ß‹*Ÿ?»=¥¾Ù(¬åTØRWöù>\ó};ø%7r6~ ·¤±N-ƒÍ²o¦ûÎhv~ìûF}Ys²Îc›N7¶R!o†µtñ<0ۗ÷U¤¨ïä[éžp,çà0W£:ãÐŒ ñ :¥.•îæÜÊ·›ÛÀRù‰ƒ8y‚쬿ùÑêÑm'¸®º’}Ê¥1ûXå¨ÃŽ-æ={Øz¤×ÕW¥l~ù63w}^˜Î¸ÁxòYlf£ÁÁ[HÅvy=¬·lgÀ”ŠGΖï÷>¾‘’(U¸$m;Jº•e§1[k¿X³ßÖs”ÑÖó• Ý0U¼í;Ý [ ¹¿r•Ý²¡3$Ò8 uÓ8h§žé|•Ÿ+ìa(»k +‡‹5±'õ¡SZ­’ê(l¶> 3ÜD*釙² þ›[l8nHï{îî}鎻î«SƇ¥ÒÙ¦c§Æ,;®õ¹¨zësù­ ÿL¢ZŸò…l}ð=ñ'`ÅgžÂÕ36j(-ÿPœnz4±ä¡¢¯ëúÃYl +ǧiM;M‹Êz{nŽŽËt_*?š‰JˆÔƒÊÛ>ãpn·ìÉçÑ®[ê'ö… ¶yüfuÅ&UnS­žfð-¤[1›;y5ÛˆhB»±Ôä‰QùO$CçœÒ7—Î+5<–ó ÉI£Á`sE¶â2’öªÉí:ŽžŸT¥n¿JwSȍ$[¬‰~æÎ +Ëm{Às½Ã¨ïn†³^ /,;Oûµe áxn/å£Ït+v«ÞÚΞ¹æ~‘n4…ÁhØ$«È’v}/¤]»Ó¹;[m\ÔVíOÜôf–wó’È;ì~ÖÙ\˜|gÙÂü¾Aо4óâK²€š¶Ôåsâ³/Ž¨9Þ¥\†ÿ‰£ë?U""Àþß>TܞÑá0@¬ß 6ÌÝÁà×Á༎ïs[ßë|úËÇ =ÞOú›˜8ö“˜Û·Û¯o1Ð^ïœqOGÅi+F… ê+šÑçŽüü¨9Åʂt+¡þDxçOô™•6˜j°4±´©ÝŸK¸‰GöQ©³š +ˆ§m"ñ9ã!\nà“g.j÷Æûd¸½w~µ£ñÙPB5ŒP]n¬àéoÁLvo¯`w_†PBý¥¬RÏnEí<8j–¬lî/3«ÇŸÚšÝ9:X½õ'`7*@©»”j7×° ‰; ùw;¥ q›RM9€$/¯»÷»XW“uZTöÚå°¦ç[Aƒ {/SòD?6OŠß>:úÓJ[ëg×8íÛ8¼?°N xÂvUºç‡sU÷rÿÜ\¤873îwä)`vFjü’€Ëÿ{_“ÿåî%²Ò8ódTσlïÖÙ~AÙ"»{_¥èU;ýW`´ãԋY˜¤Ÿ +¥'²Æ›ގºÞP=î'Ëß󑝑ßJO}yæ׻˷og3fNm@—Ý^ºÃC´³› ¤æÖ¾”mVÕ?°Jê”ãÙ¿ÃMÝYY)þ˝å@.5™¿ojÍç@;¼Vêóêg\ð¸(åål¼Ý¾•ÒUãŸÔ%Yž[«v÷ÄêUÁµöùñѱ°ùGšÛÃa·ñö²œÁwp~¨:µ.™\¿k·¦ÓÚÆ.Êë]å–ÿSxØ»ÏäšÓÏ-´ªÎ/õwÅäj>.§ÌYtÁòµ¾0ös€¨O6üÛÍý¸†.M~Ÿ>[qí¯“=8[‰Ýµ?O +íݍÜ®l¤d§¶ÂõíüÕpìˆöb ٍMªkܵ‹«l(æ–E¼Bþ†Ä`Ož°Ê#Xñ”›gn 4@•©äÚ«=ßìøõÅ×Ús¯~LoôlZחÝ;žÙÉàâòèþy8!Ô{?_é]ÅÓp§® +endstream endobj 27 0 obj <>stream +Óù--U›é~’Bk=y÷6¶ø–7ȵb®eûº»¹ôòìtò‹ +û&Íúh‹ú]Eÿl &Ô9ä N‡†:Oåä¼r)Vɪ3lúˆàóéþÈ»ö¶êjz‹sº»Xúó°¿!äyWK›­™-Dv[9­.¥¢ïæ׃ TY‰‡Ls9²¾ýÅ¥”EEXÚ¦v®GF@„¾$©Ä`Ÿæù̼›ù¦ÿÀÎ+I‡/A®Ê¿jé]}ñLÊ?zÏ,WÜkŒ ­bYu @›{Åç,G­dè´‹Ÿ­£yÌ©„«Sö–ãåY¨r/kέŠaPå–þ6yAgÀɜoº‚7O_½ÌŒkÒÚþ¸Ji‚¨~þÄÏÁù¥ÆF’ÿzq9u'>ÔRÁ¥¦¿k-Zž"|Ø _{îÁ½É‡’þԜ`—YØë¸fmv }¿ÎšèyyKm¼ÅTh‡&uwldþm.’¨y¦¦×gXqÑÕ5šhdÍ9MOéögšSõZ*uìaï?p˟²´:g;¨ó̋PSÕ§¨ ’xè{}¾©Ÿûì¤},˜Š°› ³‰ýíXs õÁj“êö²’5ö¦^%OFËg‡«¸\êå^öl{·Dþº4‹®‹èýc]ïoA£)[ÎXÖÖÒnm,«Ø3‰R5 ´m럼wœ÷ë½ó _¥Ósa©“Í8¥LM);™kãÚ8 .ܸÕê˜ãÖ ö +ÁžÒ öyLùÙÅݾ/¸€|?ü¼kÓîï3#üþ¼ïÑóör"ŽãJTßé—tǶØp“e “¥7ëÌLã53ôÏ󻞣kÞÖÄýk?-6Wåáö_½•ãÖë›xÕGëR¾"ÛµvGî½à\‹lw¹Ÿ)„r/Ä_Ù¿6¯2$V 'n ¿Í|ÂÈzdžR9—º™äœï_WîU)»²ý¨›–5Ð<~u“#iјªÁ…ùœ»šd6êÝZ;JýI»ã7÷¹Ö/7’ûê*# äU^<îü–˜« +1WëœEqzôEq¸{ŠÇÕù'[Bòü pj¢ÍWÖ ·oÝ@!]úëü~”Ø]p±&wßÍ¿é]Øì­%5ÖnÞ[֙µ`€Õs4w¾¤ªÉ"ŸÌžª§¾– +µÙãå5}eRˋ´_J¾(šŸá˜hÂ]š7„Ê-#A|Ž‚ZT|áÞמâ¾ø€8´¡N©oýlE Ã;(tšŸWÿYðïsš¾žñºt;L^ì°9‚°„U]©Ó^Û\RNïëi–Ë„õ1®iJc¾3ǬTYËÎt»•†¨t^{%OPq4˜]SIàÃr«Æ75gÀ7g‡7|Æçƒ/óPÕÎãO“Tu 6йéÕ¹36Üæ‚àUÛ-,Ãã.’¦í¼Ýd„^_ÝLyŽ²´‘)Wº3©Í ¦•£%+ôQÆFœÉ»Iz!emÃNüê~ðÂý+on·Z3\*—û=nÒï÷xÉî÷è³ÿ½Ÿ\;*>~?óÏË?€Ýޘ‚\åè€üùð¸k.i\2CÇpÏEsq¨ä­픻•õ•ïòÅY93E«óa=ݞz½j_1.“á¸Û»d!_W“–va/ú°¢rˁ~Ãî“>œ¸Tìø½¾úöðwTìŠ,Û銝æ +"ðºÇÎçÙã]ôoòrÑ@nö¾ó¾$fÔeÃö÷¤¦­‘ÒœO'ZلnŸÖ%šŸ,éx¨5½ÐJTþ²ãÞ°ÁÉÃÊZ'81üþ~6hÎÛ&·y|­>ǝÜ™ZyÝêò÷›ïïFb{öÄgwÚ-NJKöYÇví „Ý˜w­·>t/ÛZ¿=¦Õ9lVGc®­tN{·Råó'Þj>7»Yl/Ñuâ·ú}ÜeZ«™qb©š7Џí«:+»¦­.råûxWÐb¹Àùèð…ö +‰(I˜þÍõ»×…+v¦”:aç-uÑnܖiÇÒ­ÕKÍâ¦Ó÷²Më&±MìQ1šØñq£Ó•Hÿ‰»7º±®›~6w&Ú¦­cÙª¯fX2»ïls>jàÝi0ËJÊçX^Žòx”îÄCì55èœZ78>J½ ¦P]Åf:ºÚïL0f>x`´ìËÅj¡åô­IÔsoZ܎³tŽû´—òÍ sÌäÚÍæa£˜·Óÿø™^νGÐØ?Ï]Êæ[“òJS£¢™©,ʳ>¨«ËR‡™8ìKÉÕÝJô7ÌAX±wçIáݗ+8ÒõŒ[¾ÓHé5¶…* óµè“Ùý܈Ùž̼9¤D›–[£s㺶ÃF9ŸÆ)ï*6¨éAÄ.5ºAÝ·ºß?q¸³\}›1'¥ÕC8æÌô¦»ûsÁ†¾ËÒ8û:ËrÙ״ᢛ[ úµûžÛê­§ JaG_¿mðÒÐvՊ­Ý©_ko ÓÌUú<]ìƍ +?Ð)í¨Ùõ ~¾Õi3זx'[cŽç¤ T?3^©~æÕSuƒpþŸØn®ÃºÜÖ ³³!ðYÉ£ +ƈ|¹xYÑèõGB7Ÿžòp™föî§æ¦K1y—ms§ŸxèLÍ +[û÷ä۔NŒߘ\C}Ö+”ßešõ§»µXcÄZ;µªÕ\XÕÌáq©ð9<ª`B–Ƌ.[=±L‚xóþ¿äà?|®¯K7;õKfV¢«)…5·_¹èQß!£5iþÀm†ýI‘’»TxUX6-kŒ3¬™-ò6ôuvÞ7là¹ð<¬ä̑Ãf㻟8!³±WšfWSnù'æ9J4C¹H‚•)¿z +½{±ñŠFgpǛ§‰@4<#CRÔ÷¯­r©ÚË7*¾\ ~êæõj”òïc«Xú.څiOïæýÆç„2̙’2Ê®&â”ü>FÙ«ë6ềÅ/v/DŸÄ³i­ü'~|Ӆ M¿Æ•X kP¿ú†0‹µÂ.@ûp!‹¢] ûÙ Âþ öHÚ@HV ’2º ór‡ ¤U¹Ð ýç {ÆɆ +q+Ì.KƒÌmǎRcbìƒ3Q¡©Óá55~@ƨÓРÎ:€:7<Ôù¹îVåÀHç'¿–Âzµ›S¨W² ÞÍ ê½Ç™b8@†Í2@Øq µMŠ¾‹ÉS€¤™%ÄúLí 2¡ŽC¼à_FZL̝÷á™mG§àg5†j:Aý¨ry`C©³ìäßQÈÌ÷°¥ñ˜VƖúP,uÚÆŠuïPìÄ+9՟ºY TîrPù[ˆX™¤3XC]€PåÂ&cÞ|TßÃõŽäË­Æp¦…›~¤ÀŽÙúlê¿ [ñçD>š;B©Ï†°³Ø½yxÑÏ«Övèr›.g˺@Ïï@ǹoâéÏSá/Š·,Tþ䈎! kŊwã)Æ· H\ªÙu +—N),{*Ðjƒöë¥W1¸7ýV©ö@`mþ€\”þ¿<è3Tvó“4°âÛ +¡6Îmþ¥»Pêê[F§øXº›èvœ÷¥ÃYûí¦–ü[Ô·rt¾oÔh¤ÞQ‘ü8áíL߂ÇÝH½ôù2ë/vûê|\æÙéÎZÞ`ú¥nE•O•¯Š_.ýXñ”úÄÅEKãýÒ௻ˆº€C¸4 Òà&ª¼\9ÄÃzñù–âô'º|c"*ÂR¨ÂÄתãSàGÝ×+ܔ¾~õˆ7¿¹K퓗Ú}wý\¨üŽ8½zéÔÎ JGNr{iÑÅw—Oý °âÏ°·,z°Ð汈áÞ$.¾©9ˆK›©ÃgbxA»k¾˜V¸õS[ëúØeù—w¸—?ùÍa÷üõ¿Á³zUƒ=}™yKölœgü).î•S{šÞ¸]]|¹¥‘>ÖªÛ 9gšq;œÊÛ¬õ’ÔÏó¿ÐGÄ™J€H•f€InaÓ’ sñé¶`¢Z9Ýšï±äw'žúJìÂËÉÀ¹)’r¾¼4âq6ßûð´:Í‹Àµ<êfž½Ü‘Ï÷ª‡Ï3ò8ìå´3ÝMðÒљ֥p;oÎ;\Mq‹¥ È!Ω5/Í?¿`êìYòcòǙÂ׏Ðü 10×rÑcFׂÖkÓò‘^¦ç¶¼xóz7íÒl~ŒÓ†[nNŽ88\ÙËÜßV|¼›¼úgº¯[ÿ[/o ¦e› E°âO”„ZY©Âð¾A*óxÍÏ֙U–o}·Z/nÔ¯˜Ræn TÏ0y“<¨Ù(É:Ò&Z‚WóΏUó¦ÕRɹµ3Ë=—{SÊÁ Æ~\g×»Êì¶AÁ>ÛÑGyXàډ,Ô¿›^PÂ×»U^ãS©½¾.ã¥3»Åmhû‹òùñ5kïElÐd?Ò£þ~柗À߀R¿¡ Èæ} ²Ô"É/ʾ£ç€Î¼º5{Hr&w{nùÚ¹3«Ð.~–z‡B÷$îªAVÙ¾>·ÛL}eAãs·A§Û$5˚èï«\› –Åõ](–4î¤fÖóWÎЕñZ>ÁUgz¹h¾¾¡Ñ<Ý +™ .¯ß°ˆåÁb#@ŸÈnn?»Q9aò›õGü<éïݛK{ng]¡t©ŠÖv^ëgƒêB´zBÙ`Æv¾:¥º«åXŶ µë¹æ¬ìx†‘3C}‰ééù‡µóótÿ՚m13 µš¡Zé¨íë*lê[駷îs*•Ú¿ŽL<ˆiJ ‹h¨‚k<®ÊÑëË鯇,¤Ã[£ÓŽOѵâmƒýdκ·q¨?ߣx…‘£k0#6§$£ÀˆÍ#®ü½® ÎåËoøÉ’[j°Ž Ô{ëÄÇÅéQ¸ÛËúåXnŽÉž÷õ¬lÙë*³9ìϹՄ ’Ԃ¶F›°Úóm¹ÜŸ´-LG2=RËà£M^ãíb±3g´z gÙò…@F ++TâUŒ’ø1—øÃîÿô8C¼~pú/ÀÏüÍÕ]²Ëýs;8ïbña#îg-û:¾ð·h¬èLmîd†Í™ºÓqUä•ç -MôËr2f†Rr¦p”zW7ÒnŽÅ£‚=ŬÛJGy«2`ÓÑÌB? Ï£õßD;òrŸsvBô·7½ÄO.s#™=]¸|Ò÷3Ns¶Ïó¶qÓ¥xùØ1ˆ¹(-ózOñ+³a«Õ˜NP»­ø…JoÒì¸Âh3íÊ2‡’šDÀ)UÌM®{ážsnB… ?íÈÚ³=‚ø$žÛæ3îàñeŽB¥=pìöö¥´rÊÃñ®ëù貖âI léXâS'®Õ76–ßœ×Å»÷ZèŸbÚH§Úøì(­’íÕ魎Ôÿ+Òãø°#‹3xÓK¢x"|e86W†P­O·ª4½ðͬqËq*  +Ür²\qï[Îåéξ‡ßð³‘ï• T©hïóf~È#wÚ=üñrí{ê’m»ÑÅÜH {XÎNæÃø/0Ъ'rNy½¥1¸Õ©Q/Ø·¤c¶Ý Œ?¼«9ÌÅarþ†oa­5ǦØS¿ûæ_=§}&zkõ{NGX@<ý®›vûÝõûøYjK ûì˜w¯¸cÏv¥ÞqsÑÛÏ^ûîöû5’óžÖp&ÍVӑ¿1ã]ïªcS-ЮÄ7­Rõ2>i“ë¨ÿD+’xPÃÛcmæq|t”En͵¦ýÞ _ôøwùÐúg7;ßa3=lwÎͦÑ9—6Iì`whnw8¾ìKc9 jÒøjöè–{Üޙýó¬2KV[Ö±‚õÖe//ÕùÂ@$ä8+ô;u>1ÞZœ#.%ÉL$釪ÍÕÁçÛä—§Ëus“aoÏÆ]—ΝÑ7»cÇV6Ò~¶ÙfûÉRóö³¶tØ +{?±•šëþÍíÇð3Þ¸¯Ñg¤³§wvL;Ëϗ²¹²®”†ÍŻȌþ¢ ÍαmOëUâ2Y‹Âk„[ +³::¬ 7äÀÜ·Ë|*S}G[1½aiÈuóçƈõ„B²±Òöå†Ó¦vÃ;cVhäMh¦y†öIÜßl[1ý<1ÍQð+ÞJs,^ÍÌ»v<¯ÚÕ]³âWmìÑ+­Ë÷¨`~v»ŠeÎIÖÞÙå²M©bݜl&Ûýˆ8`7ñ>˜†BÐB¾Fßâœí·ó}¢WºçË¡ÙQ†Ó«õe©M“Ã9à ²ÝZœ{+uÂSM{~j4íÑfÖ콟v³çå’şçoð.}‘:ñãvi?Câ²íàüº,¬IóS¡IlmÊ¡ Ք?ܤG¹ª|2à4:m\‚I ¼UO½9LÝd?´tkݒ„Y»ÖÛaöÚa–û•Ðڜ­•)„v«bWzïOS´ —(Z0rMbýmÃ])ç†;Å%nmʇ›'ƒÍ¶Û*g××ýšX0Šê„·Å¦óv›˜ô ,?ÆCª)Ó¥áðuògàÎmy4Î}±=»7yw´Š„°k5Ûn=JU&e`L Yaƒæ EMií&n»ÆYX^£,™j^ªQ¸ØuãÀ–š<3Už‚_áf‡™‚³¤øÜFzëØb¿3:1RÓ9‰e&ˆf¡Ò}(“"Õ?$ (ayr8~ûœNú.h-z%.»ïø$¸³Æí¶Û³mšéšK²Åij©)l}¶|ãšu•FiôYSªG_¨êêø©ûâ Z÷»-¥>»N×uŠwÜZˆ[?QªÉó¿° *fÞ"i]Dø=¥,ý™ÎÜ}<Þ¥©XªÌAJXÝÍêiL.Ûmq½É£6éÌ߯9Û²ÎcWÇ֎ÒîÍcKIÎÐ玔¢ #Û({³ +¥Õ6L]§÷ƒZ´ÿh5&[·«àe?ªk#‡T;ܹ ƒ“i5u¼Z¡ó¬½½F—sþöÕl1I8ÍŒh̏—øD&¯Af҈9ñÆS=%,´;ˆð,sŒ˜mÏÖZ¡-š¹P´é"èÕ\ÿNÍƃ nL;ŸZœ’ðê•ŠÕ®`4+[ÿ>¨`4šœ,. û¾]&…£W:ÕèLIz를1™@¬´ß°ª:·¾cÑh:ëJÁ˜§OOQSjÏM·žr飝p’¢Ú_ûÈ0<©%®¡æIaô„*ʍjüQ¨F*˜×[èeQcÉ}’n`¹«8ÊÒ­`Ïͽ<¤öa%›*^×a.É K¦|—+Ôðš÷Ý´•ŸKk¾‘?óBûüÌ?/?0z‡\4}v»þØéb €+Ï µkÇ7Ç»öW2 ænñ¦\–² Ϩ©9‹ÕjñîDU¿®Õª8¹]>h½^™ X¾”kâO1[<»¦å¡µjädÍʙ2{Ì®þA~Ÿæ‡´f Oö­$@vÚ'œÅu Oƒ¦¸‚?ɌOÔ*)(‘%fTgÞâ-å÷ͼ·|4¦´ÖÍî7¨±ø5®f.«où0Ó%™®CMm/Ô2w"?ç/¹œ)nŠÙø²¬dْQ'{µ1M8ºÚ!°·1ÀÉïrŒ¬g²†Æ +(±C¯ûqèd˜Æ!Š¹ß2¾2ûO Í>Ö!^3€˜- Î)ˆ‚az4È|Ld\ïçÈofNÚ #sWéÈ4N)ˆ/2ÅRB€¿·¸é€ ú–@˜/dð†1ÿ‚LùEÄÛǏ±ºŽ&ÀނÑGÿAâü¿—K  +Tx€\Ž2@3Yb²‡#€D­@“&@' ÄWÚ0™Óø2Ö6‚²ý4\`$D»2ýŸØAøÜ÷@†CeˆÑdxäÁ‡±ƒ¯3ïCj#JÌð(?%Ðß2ꅆ¥Y:/Ðz4¨Ô3\ª³“ P™|´'çŠX @n1,sµd¤-ìBÈ|/oye +ÖÒY¨Bl±ïÈl‹cm;Z.x‹ ÎŠ—FDXoRH… +’I6‹Ãò®:ƒñ4¨¹ۏ&ïÛlrÑ3eb™GÏó‘2=!ÿšgngüþ€Œ‹PgGg¡D„Oâe§/Vm€ÓKïÇ¥ÊaÀ1ª°׍Ùñä-©œz%'Tñï9xv3~PÇñ+ÀäE‹xÖ§ eŸifëO³g‡ˆÏtÊÓ½WrïÇ3õºÔüçªH~â¼h“98ëZãí~Šà7ÀæIC©Çcdmðs–à¶äü<‘æ0€_ŒÚ[>ç™Ð{žÁ¼5W^fš_øK¯•Üì÷Ü؅ó3}Ï>‰¿½}H{ƒ¨HÜ]¦R¼çfuê6 +½ë½¬/³4؞ÞÃÇÙýô/7-Øѱ‡}£ìsÇçã7üô›ºØX9ꑇ?—ô$î>¹›ÑÄzƒ½‹pU¼>«ú«jí§>„//ToXw9ÃloãGνªöû~¡Ú[ÿlÌ·ñé}³2§6a%á£îFºVÝô ë¹Êlv 3înŸ—û®”Þ>•?¶O¯ëنõ½þ€jÔ© €Ë–%J @<_oZr%ŽIê&÷7“Zþ±§Ïû9¢;·rp. AK<ž¹ßðºr3ǕsäÓæép(Mîr8 ÷ù‘üݍ÷éxä±î¨çÚ`;»¯vsî­et½o¾ë?³éºòeͅµÓoèÆR£,Òo<‚†êv™¤luc¹¬ûaƒ ߚ ßi‡ä +—&ÆÕO…ÓrÑ̐;E<Ù#ØËﳺ›œ†ãEšµõŸƒý¶‘\m“¼¬x=NYlz“ÛX̀^;âH]c—›½"cp^žV¯ó²=žå¢xø °ÖÏ­Ÿ~Ó`»€–&€l>WI*ÔS4½¯/ö¦ÞÃ8ôojïs^»ˆËíV¹ƒëjû¢½n9Ïê€Ûê T´â]±Ö͍¾±³ãõéK»5Þæ.«á\HNH.O‘™^*^i1±Ô¡ù@Ó¬©õƒ1÷sG=ê~öú"óÜý€ñÀçrï_±h¤ƒ®@¶»>Ñþ~|$ìpWìi²¸=ƒÇâéò§;8òelWµµüÖ85ëóØ0VÚúë}–®ŽQ8Yž]g¶,„«Õ¢ü˜ïÌÚer1ô’éÑð…ë­ ߚ¯[™é¼ƒíyê8ÛÏúu!éž3$hÛ¿ŽK)àþŠKbѐÍTÖïÛ¤¿{uæ‚å]ÆëòÞ¶ Ý{[ˆ¹I¯‡FžX^-«¸˜lݤÌ£ÇY»7ÿ¼•á<}êLfèŽ64b–ÛLsf%qÛ©£G?PîõKVQ3¶ Tn5bjMž°MLf ¿þ /”ۀ ·—ÈnÄMHÛûÅCÒLõ+‹‘+¨¾WoR’Ébûök[ÍkQì€åMõ1óUid Óøÿé:Ó%•&L_ Šà¾ +ˆ("‹È*"¸â.®”Þÿ@ŸoΙèèùóTÑIQKæ[Yŵf1E0³.Þ1)כ„ j‡ÇBŸ/sWöîJ%r‡‹b1X¡ð§Pìސã,꥘ý Uÿ½øåÈÄÔd@…Gd¼OËÒôƗoã“YØöÙgIØV’)dED5/ð¡I8Oüë¬ºh¼§8gfìN fД‹Fßͧ+ìz±| &e`Óã‹- Ôې•g³ä˜Æ™öG'iþÚARw=§¥ì¤¥&Ü«LÿBҗ¸ÄÎA‘Ȥ*Ç݋nòÉð{́É'À&>óëÉNP³ÅÅñ‘u}5;Ö­ÓÔТ»í6`±—1ò¹*:Ùç²6FµÆ8ñQ(•"]À7QúF»‰”=îf#äúL›€¸1øX,¼ +„8äÞ²8ì œòôÿ €î$æGE‹+J89k¼u˜¡j·<¬ÛÛJ0bWä©< +¸ix»¤g¦¸¶·w(~µ²¥ïËšêwr 39­¡ÚEõ‘¡jÊTû2 /i‰‹ÌÁU‡ªX‡ÎP:ø[á„ÄA½î‚¢ Þ2V‚’#œ0ü¤û¿?HÆ{“e$=Ú“?Ù¾Ï.<,Nxr­ …ÎÂÓ7½s“Ù8»õœW-·±ü©p26Ôî>9VÉXÈ0£ÚbU:q6=QYZTœÆhõ‘Ú¢è´{CY¬KBÁ>d–ý{`^û–•û–Š ú÷ãÁLðvxöcÿ…¤Û;I•lù"k¹Æ•t…=ˍMýuk,ßå%ôޓװ2½_EÛöèóÂì‡Ø^¯0ÎUk §ê´­¯üå °Äû›â¨Ðֆ‡e…ÎÊŒê}Ø· wwá—×ûítöìÍ /¤7/^¸ÞGi æßñæ_ymþB8EÄ¢º[RXms"/µ•5ŸT½Ù˜š(íFÆJt:‡†aå¸y*wëûcv«é-î¨NË×»±ƒXêkߌ¸[™èP%Ȳ€]áfÿÙÛwx÷ëõ{óW0æÑÊåx³~ì®_A–CZ›.‡Ô05ÁÈäx^ù +]ÿ^€üûÙ½q«ypE¬¾—òºù‘J‹9 +üBõT™i«)9¥T±o-ÖÕ(}è©M6KÕ-Tvr¼«”¯5ž¢Ì…ájpðÀª‹?:tpªóíµzpE纛HWºÅòÊe¥1¼g+ /ÃV’·ÊVŠ…­@´ÉJŒð'’Áé^ªùCe—Œ”ùM},–MÇ|¡%gg¸”›¶³ùºÝ¿c'¹£ v,˜jܛÌåÅóµ…ñ(V¿ŸH0:î{Ð:2?/´×[o+ÜÀœÝRCfÙjyG[ÃA'wá¤GVÊ;PDž€¨wÖ¢N‡Q/âCü t|ÒbÍ¿n%©7êp°€ôÌLs¼·í»ï»QÍ ‰•ÅåIÚIÍӐöÜédf³´•wGזø5©ÀNÚˆóøÒÄ##îâÙ7«uд…νi;xÓn®úÍVpR±wëjü……7ó2^-»z; ’¹rƒ¿Ž]f“˜ÈÁ»!¹ÐÓIš_çò{®v¼ºØËÈ1ϹQ¥gªÝêp¸Æµ‘˜RÅâhҒdÍ%Um´ .7mO4¹ù'K¨é„—Èr c¦üƒ:«Áíð0ÁjÀò* <0UpÑþ¼Þc'Vòwcßé^ÆïÉî+…Ï®ùü`¾`-¶d:Î‡f»£|'‡ +ujûà[-yF±dC®¥Î-ke ·¾„Þ|sÔû 0c£nØX£k#·œëz)ÖÂQ¬•ž#¡zX>ìª2쪵üë[9߶Tå@ü_˜ÚjߘÃ$ +¿™ÙAÚ ü±²6ì€yn§§(§v¡]€ZÇ‚’Ú9®Æ÷ÛÄ©Ó³DÕã²Ç~£nÄúF?Žë…ÇŪ•ã[U™Ë²r â4¾)ß6Ù{Ùrp鹟ÕKŽüeKí¯ãËÁ+ÎtüXdð3ü,”4®šuÙå‚%&R­U/ìÌŒ½_N©sÕ[5¹œÖH˜4öÀÛpöÝdÐø‹e§\¹l µ¥—ªGwP­\üN£Ò„;DÙtÚ%gÔ`‹ñï™zG*p8kä—öxžGâíÝxÅ7:dÇi‚ì GvËJ*w'¥*ÿ… N]Ž²`€­ðª5–ÿXI%žUDWW¦fsÖ/XvÿÚÔ7Z°­I¤¼«ªÞ±2é¶.eÍD¥v1JßM‘©®Ÿ_[ąìm 呗™E‡§€ìæ³*"uDNí_˜\=_áɈ7áfy½ÊÞN¹KÖ³ K6´Ü_“¨ƒlAùIý(³î‡Ù.$°t^eÉ+Ȗô ÈÄ ›ËfP¥Fò£Üƒ‘bI~ rz&/ŸŠ)ïç—xzhSöôÀ:øéE¹ã_YZ©8%v*¥Ör{HBÎ\)M˜.3.Èeg!€©‚>m<76}ýÄÈîjn‚Ñdýù9æ_ö-F¦ëø½iì2o!zÞ³PíÈnûUžÚÂãÒ ¢µ[?òoOýÞ¨CtŒb%§¯=ú ^ö>ïùY§¾÷ÇåšDJ½ ?šx¿t7íIóNR—î­Íb“ªÑÞ.R›K¿‡ΛÕ÷pn‡Ó.ôw?HnóßÅ’ +]§Y½ÄTQnÜdàé Ø@êLñڜ•Þ£¼J¼ª*É>leøÀkðøn Qçö +Ðà6mU¶ЊiK‹<Œ¼GPâß]ƒÊ¾r'¯rYu^ÔyË1òIÎsöáÚ¯û»ˆn÷äþºÙMsÖr×^ËÀò£rx« rWJóe¾…Â7 Uz МqŽ 7åýªÍáìøì+wª¥ÑgÇ2QfŠ ×dŠ_ÖYܾäۍùYÔ««ÓþPڟªµFtïƒ.c™ýý,Tö-ìÑ ?¹Rš5´ üÌt›ƒóËM ƒõv;÷×¢hÌ×¥ÒÈû…¤YfS½ôãŽ* ZqFé‡m€îU\<Û§§ŽÆ×»sQߑïæá+r<¤±çy‡ÄI™ôQ“ ý‘JûÖs©íܺo…}9ÙÃr½] þ~›ï›u©˜Ýä•ac]šÅÃå¹õԗYa¾Àý<¤Í,°+3÷?¤¹ƒÿ^$Úhµp€¼ê,@ý‹ òMÁ‰ÃâzõԟßÕíC Ãëju¿œ÷ªü>^[_xstÅS.ÖÃn ¨-¿ßw7‚;ÖáÍRÖ办®­­”î.Ï¡µ\bÙé~aô÷à摀*´O×_ò¼Û-:Þbç¯¶‡ [ë/€œÞIìì8@¥T˜lß¸éy6¯óššÝiVr¯kÿ>?WŸ½Í¡å§]ý>·D‡6Eϯ+t¾¾¼Ä zA<ì~àÔ É‡†îӁ1ÏßöÒ[|݃Ç0Û䌆»+ „@¡:g÷hDÈú59×¢ž¹{¶òýÛz3B¸óê\éBþ' (xyê%[õ!ú؜Ãä²ãõ7ÛÌÑÝ9êØ-g:UñåʹØñÕÁ@±MöK[Ï#/[ŽªéV»­LÌðZŠñH¨´L^¼ÜHš'Lþh“ w•· +u'7ß«.Ih9<´'®ö»_sS^ôç+LzíT™½øóæã9ï¹Æ×H}t&vêW.CÍ鹶+sM•í{k+Ú¤¶ŸXmi?3gg(4M†¯Üsú*wëýóQM¡è¨¶”!yñ–¼ø&òZœfLjêóvŠå•ƒÔ³9Þõ½ëåjÂFÎxÕd i‡âÒÏÏ;o}Ö¢Yé•}ºÕí5ãD”ŽØb¯b½ÞUÌ·e²•‹ìGÜ~[ï}>cÎ;!b,ˆyE_£JsfzR¢F­ÚÔñؚ{ê5Î$õ7;U\åQڊÊ¿K)Fág+ÉñÔèW¥A© 7Ž“'½Þ­:J¶®+Nm}îseË} ~vÆÞvN]õVœð·viͯy¿˼õÖ×O>3 ·X^;, +µñY‹Ó5i5’n]å1¸”Ö®`ËnEØʝs-+}Ü%}f½ôÙèâ¿þ@³÷&ÈÓ3楝†ÌY=v‹‡Nk—ßõnfa[ŠÈô$‹Qd0—,n>xæåYµ§YS<ûôìö[šþíý~Ö Oü®‡o0¾´6Yõ†ÍJʳb6å÷GêH߬*H`NF ï»!Yí=B* +žàç*R- #¤Õø%@bª¶dnß[?5·YtŸ¡'È6œÖsëóq5húü¸Ãxe$§‘Fëöôê8W|cPY¥ —“=ï5u󸌛-û¡ùžÐc»–ÑËÀ• Ö0ÚËä6T/ƒ ½Ë×þDҗ˜æµRià±÷4lK`¯ˆ óü×õ1/.W牌өª|Ü´ô=ßîiWò$«¯2«+tžJ}LðG…²ñÍ^Ð.êu@ôš/þýÍezŸW¦ÔËD™t¿'—;æ{]¡ÞÓºùëkÓÍG/¤›ßIDW(ĽÁýÈ»ò¬:Ùì.×ýÆkí ½³zÌ·ÝÁՍ èìL¿g`õÂeºômˆ[Ÿ4†(«¾>úP®9Uä斸çhoX×/‹Á™lûNÐ>ñ3·þìqåח룏B·°8`¬„æ8æȶT¦¶X-˜Úr•ejÓv“Q^;ŽQN›ô;ì?å/Üc¤Q:¼äÑg;ªoÞËç¦ý +àéé1;]sgÇ¥…½Åwø§1RûÈ«¡Uõ}òZJæØéIùà,‰òW™Q±-e™fBò¨¿â¡7yàV&uÅú°réŒ2cä\§õâ‡éÜù†Ü±mбÐ-Ô1?\³cF>›`ÃuÌÐïþÂu˜çs»`‡üS›é_Þþ؋¦vu~´þ7ÔUdsÑnÖ¨±äe·Óí˜=¼ÐF_ ¦„ҏñ¯Áw‡æ´‡ä˜€Ëë‰sê€3söÀ›Žìw®c7ÏÕöÛΧß^mw.¬D}&×95Ç7j^æÔ<»d(ï¹áþÂir¹dþ©MgB¾|4òî®=ÎvW¢öúў¬Çλ*AŽdt^MólF•Ù£<Ôskr0…ùnê"ÃÞ2>Ž¹¡eZÝ +Æxl½R_1ÍFåØyÀ½oÞõ=ä*‡àTk9‹­~ žµG·¥Y'7í#Mnê·.¹Aiø)ÿÃ>S¨5¶Pß÷z=gãkõj¾ÂÁðÍvüêA 9ßîÌGÕdFŒü윆ôçºÎ÷Â2Ņµg¯+ï}‘mÃ1ƒK\º+‚n H¿Ó5Ã6Û¯\©žXÿ´J§Hn72I–Š{Ø?ú.!;ؓû—*Qù’0Ú(tñÓ(ËþB2tîâÅì^yy²ÃFÎû#àĶ¯¦ÄNIu°Xq_N ŸE@#»àJõ¥r¡ëÈ“ëø¬j›y×6\£^^,•`@ÿ¬ᕮv×ìô:ïlUvp_ŽjøÏ9·†M9qtúݸ«Ôz;ÖZRĬIõɉkßyáwÑË4_vPhvSó†÷V#°îl~ƒA}0,ªµí¾nÕJU.¨Ê®s¬Véï§2ÞsåJC>¦ùiåˆâµ²6e|{†Ë¸Ñ¨—ñQ£ñ ö· õãcªÞZ½åÿcbåbêt'Ü+­ð‘:20p»O†MW$ÏØÜfÒ­‹Å¬ýi E©ZƒR­L³µª²‰Ê¥"v*ØÔâËÆÇ•œòJ/ÆêÝ+ҟæ¾ð }Pà*P)M¥ÓÊfŸ}—ÿ㙑/pÍrêÙä—ÖÈ#oª…iCv¾-#÷qsÇug—àçÔ!^ÌՋ:‘«—àA‚úèÆS¹¾–J€õ3Óp9Y¹ÙO4òØz§bJ³Ý)sõóµòÓW.ÞÈ(ß]»ôÜ`‰ ´/x…ï)ö Ùè¸È#O…Û³-²óœ="±ËKî¸Ø~ž&üf´jq EÝ÷ÊÍI¯­ŸÓ^¥JÕ~ÊýÈJa?«hh?+`aýÈ1š†@VÊ «ÙT>§Avցìpúó4Ùæ} ²™údÒdû¤öU8©x•K*¾oJ ŽÈ´cd:µE~—À½ÆÁ'|Å=? ¿×0V}…yyÊîð1îø± û®?´tZ»ã¶`ßý'@æ†$¦ +tbêÙNªôb¦RYšòd#/d¯õ5ÈzR²â6²TÙ2ÓÙ¬9ˆù¶™~=.΁¥ñpúÎ?vþ+´o›×¨=¾J v{*,žµŒSx`ȓº%¤½ã‚ÑͲ}ýܳöµ[٘×.y´¯™ÓÌü¥‰Ÿ/0gÏJÀ­uÀ‹*àǔOÆ>’.€Iàöæà<œ{o¯ê»py‘¯òþÎ>ÕÜ]xÖfú˜@þÀ,tz7’¦w'Üææö¤¹ãò¥ta%Š¹}6¢×Íæ5kö¹ 2îKç‚14O£cÅ8k/ýX›¬´Ã¥9ýäMwó‰‰nbgp.ƒ+S §ßÓlifr†39b— +ÄoQœ\_•¸WGîwºT½½È¨öÜ°—Kõ´Ÿò’ +='¦^Åÿi¨R?1õv>îñ‰z£w÷,+]þÐÊÏF;È«ë[TX¹kiÌ®Võlþ°Ä.hAëw`¿7iˆë»7§0ÿ“ڼ;0Io17/÷t„™ÐÞhnèŞ;ê +çiÒäsÔ%ŒPºvôäYÛp(Æ6–]ö@nøɤ-VJV£Ð›Ù}Wíîm^͓çƒXÆöïé°ö.€Ûˆ®>Zy}q·C/˜B£•Ïhµýœë~#¯ß¾¼fq ¹;ÞCÝòÌ«N•»G8—ÖŠu0m?´;”ªêֳŭ-jCæ¬(ÕMzdŒ¯µc ¿åwþÈmK€,½@Íf뽑G+–‰«ÐåˇǗDÃÅãÞؔ«b{­2©«¼CñY«lÎáÏћmÕÉÊݳÌnz¢š‘s-BO§ÙËdl²¡–clFé´'yî¾ÇÙk»Yñêòú ‹vÛ®ùÙK­å¦Ëž«,Û#'º¿&¶Më–Õ9µæ&–ÖFÏ~ìõÁ$¼NĞýÒdz’ŸL³¤^§®6£MW±H$]Rȗ»–_k%#O…w]žND +ü/$=žML5@=Z42à„ÉåÔDõ¢x%ZŸ°ÓcI†nÆJTÉúÜUG\ê@97ljmÉæüÕÐ ž=غ@Íýɨ8ZkJŽ>ŒÇ_ì¦ê'(V!ò»\oH´Ù‘XQ•¤LñGé'ßGÁK«ŒðOÑüiÀþï@œ^ ;¨vQÊó@E~öõÊe#½·§Uó%^OÅÁ|@eó³ÊÉ©;÷6ܲÛòªgúfK4íY™ì(Mה=挵é×W ã–nóQluw–]ÑJsÞˎŒWå¬-)bTó3džìè9 GåR††òƒÆ/$#Ó}5p<Ÿ´Mì¾óæ¼-Z÷4’^]wòa1çO~Ž‰ž³Ca™›êóvٞO¸Ð=Ú@ûïþD²5Q«±±z›ÞLÅ!f®ÅµO쇹¾Y|ÖSÔ~!M¸LK€vƒâUÈÌ_ûxn^¶"Ž+Ý삏~^υfw=«aÄÙy|ØúÄWÔXk½êäÐZCQÕ +^Ÿ¥(j_­Øº)߯ÙPºÒù‚zÚ“¶zöÍåæŸ ªñm"O÷fŽ¬öfSéԛ¹•l/~ûµÕ¿Ðù½r)#£çÎ_rçM5·Mjó„‡þbñ³ñv„cjlž&¿gôÑ/kš6U{B·åÏê֕„)ŒWFK<¤ §ïv:¸ž¬ Ç;þµ£ð¨ÙZ‰ãâÅÁ^G•ÔOãà9Èp°ÉU8î¦VST~áy=äÓ¥HNkÓËèø…Ë)xÜl„"B.ɖøŒ˜àµfKýå—§Ír‚vå/$·¹e9p >þu³·îÇ%÷ö>8ogõØ ÞtÌþZèû|Ô®£×[}‰sX¢$¡#&JŽÚ&qnwp[¿„¾Ã +?kÈF¯{ħ¿­þÊ ,J'v4+½ÅÂúüVpZs?1«€Æp5¦µTHP©¤(ÿÂ5ÿX¼wœÓ¿¬ÚêÌ£ÒΓe=%åÜ\ɧ´{êÕÊx¦é¡µU§W9’ƒ þ‘ò•/*VËNU¸nû䠅À ü}Ÿ‡ÆºÈ­Êqw‹6lvŸ)Œê~vô$È=:·7‘됴†µÿÑo;ÁjÞvl3ݎÝvPh;}´ÜvÚPéN—&ý܊xñ¼¤*âÁGž™½;yc+›­=]¾Í±Í~Le>yø2’ûG#éñžÃeV Ða©ïòÅ4Wg¿wª—›NY.oÈ{¨ã2sÆ&ÕJóӘÛï\>¢>"K±’V§2ð›kç`Ú +fê£L^h+Ñò_Ø3]3¤× w +ü{œŠÆÖIºÐÒÌ+°«cܐù;&$ŒrÄÚ«»n¡r´Q*æ}¥˜ëõ ÷2WXÍn9œÒlm)óôÅÅΓoLÚ1“ŸRßV>mT×m][¼/@äú5¯’‚[ê’zo‘…æòN„8G„‹f™íJé¶[½yYÄý4:™ÃÔjk+§ý‰fNåk&â)I—W/}¢õÁb9ãƒáq×T7NÄ.ßnåµÍ3WC¯ÒwGNüo„­v«ß†f¸BÁVÕlõߝ€ÞØ#±'­˜¨Le\ývh| Á®Þã¯+LêÜ6¯È°Ô¼ÄÜo¬"ítö—óÎɽZZh³ËÝRWf§ÎFUK*ÊݱÐj«boðÝ +\étt«ß¢Ïjwdˆ<ó ©r/Ó¡ëlº°Òžëƒµ°ÙVk=k±­ÄÉÒ»¥ +-z¸Æé»f´Ú?›D¡”Ç»i³eRà ú‚µb3ƒµ.ÇRã=œaA¿¦—Ùi¦ —NÇ/lŒ‘Ícg O¥-³0„Gù¢ð¹ókÀj¶ß‰¯9±ý}”&ma-Úpíz¢ÐæýÙڙ ¹‹ó²ÂTëD½Wjá“u£Û¼c¹Išº…9¯}z^gÐpÔ`üA®qW¢TM¥ ƱÎM¢O.~Ñ: } ¿0/:¥“óƈ­Y(I ¬l=ÝDÖ÷ Ï+䈽ŒE¾ÃLÖéAKÄhŽhŒË¼e2þ˜ÔðZodÁhV_nÃmÅߗÚæYMÛZ±Og«{T)U+º‹UNø¹S©/sBYO<ûróºZ”,J­ì)NQì4–J±ƒ¹ûðßï°jÙ_°Îs3™0Å@­49ii#“_â³1{…÷b;†]²:Š©&Ūdÿ¼¢”V+‰”Y­Ú]¯2Ž…U9jû2~w¯¥‡¾JTî™)ºÂ7_øÜ˵B·GSùÅZáóvH}htu¨ìohAaóÈ®v¢Tdô¡Â‹Ç/èµ ¹P‚î`&6ΆÕÏzÇ {%_R23F=âl–iŒ¶¢6$WÊøŒ¶2ˆíò¤ôܬR»Xp‹Lå;/pÛ"¿4n›<ò¼íÑaûyA ä‰HÝÂ'w\6‘œÚ—jðeë·áfé)doGÞɚj´Ï<#<Î8†[Ì8f‰Ê´ÉA­ý”ÿAe>Ó¹x–C§ßO½[ß×ÕvÏËô Í$؆O1dUëõÒ}Ù¨ce ¾ +zù¥~òÈã$¢…Ø!3UrÇÀÒrjÏKuø²ž:ÙÛn<˒}‘i7ÆÛdŸÜcˆ!ÙB‚S bZýQ‚x1Ôè zCL»œý©Ý/€Ž* §™Iþšå~´ÎÄwPû†(_cão¤Hñ7<;ñ×,­â¯$žìAü•Kh‚A-Á”Lpbâoðñ—¯'¿àû“³i‚ç2þöéägê7ÇB:­ÅYcD½gľ†h·ûÕ}¼ÚŸÐRø‚LVK@ø)/áäòYЋ ´Òx*€è¼  Bo¿Aôó4ü¿÷N!ÕHpjÇßÌ%h + †j‚™™àæÅß'¶M`Dq\à7šùV_E!Ÿ¼Ì<Ž÷P­oùÉ=êÕc÷Émþ»HÌR> 3ZB clR\S}¢ +2¦ÑN|Ƴ2ÕÒ@ïTA_{;Í €&lª W”„*a:A»¥¾s5í71¬8Ö{UÛxïþå¹~mqäô*Úô81fù~•—Ľy¾toVaÖ½‘» ½¤a7šV˜ß™®Ø†I•~nÈb5di£ñ#©Òod‹ dî² 2Áv2 +tLôW\ä\œkZ•÷@¶š¯íyJ½DmÕ}• +ûÁS–ö£gµrק3l?ÆZÓ¿_oýÝ]÷/ï[K@‹×OM“ȯì¸É\‚¨È]zÄ]rø½{^=ö¿‘X¹þ€l#J !ÐÿßÜ0Òê‚ìE—Av¶·AVDWïõûu|¤ííyXÒ-Xó<Ì=Ï°tœwóŽƒu{öÖzføèíTG‘ÛîL®o0½ÎYouÍ¡è¼Ö;¹ShG¥Ùi´V¾³7:!µÇ?sj÷˜­ÿÜæ§üŸ•n$R€å°”ž‘ÐJÊÒöUÑáÞzU°žû˜ JË;™ÍìoTü¹E3<®~5†¯Y!.^–ÅBã‚ôâ¼ÉÕèsAÀÒ¤¾ÓhGˆÇ#LiÇÚ`ä´p±ÝÓü'Œ»µÒöÛÇðmw[nm–Å'¹á÷Grƒ$Íâþgbÿ8°a+å* 'êi¶ôµÿ£Co¦âã½G·×ÖÖ"&î:WØ¢–çmٝöÙïõxÏ×ab/¿ûÛ%ÈíÉ檴sä Æçδ+»ý&ñ疫Bê6{æ¼MŸ~Fëb®¯*…f{.ë•bsq9AÍÅD½c‹f}ßø}—S­ÁäššfxÖ@¬¨wxð؇1ŽØè³¥º—5}N‡†ª"´hì[­½»ë`ÛÔåيwØöòz´YuÇï ê(ÐzÛvóë¢nWVÒcŽ/Oµyg©^Â⊗&‹¦-/r ½ýö¡Q˜{µNcMò5/À>U»E•_øI"ïu’ +½¿ÿSýêã:@Ôkë‰íÍȯ}뗂¦âI¼t§vî^äÂd„mÖê[_‡ìÁ]jn°<µpÙèiç…î*àþÕ>A‹Tsþtj¦Ùvs™ØÜ3ŽÌz~E¯×é:³Õü}u·' +vK ¥:• ª2­µÒ_HÞùàrÌJLdKq¼ú»’aë·ÙAÏ»5”žA| ñúA¾¾Ù!µ.o•ÞR‹ËâÂØ}'ÕYÚ¾k,ƒù\57óÌ֊t¬–:¹¿rC+Nj³š½A8u>Výݾ3›®ÃE_nBâ±YFö<=h&p[ü{¾ +¹Y˜ ÊnµÙk:×u‰¶-âг¦õÅÈô2Ê؄¨‘eÀMÚÓû2½ž …ÄÏÛùÄ]«Àý̸ö–ÕË|×V›0&+·s~§˜š+$}†$Õ¤L‘ý…äÅq<¬—’Ú¤7ûƒõ¸®ÂE6áü0_·Ê"ˆ¡òn¾ˆ¾÷Y¸õ¿n5䣚¯[ïîš4½«@ÁKÓGõ•ö'[é¢jûÁÆÒ*óå|\wfurõϊùX¾åWíŠÊm½Ø”>JŒÓ]JÌ*÷”˜“KИϤýÈÅÛøq»åÓ쇳,9ûݜƒm¡ñž¯.uÁ]<)Äó»§ÝÚ+8æÙ­ÙÜÛ!¤OÖrçnÑìÖyÌÈ- +Ô$ÄvŒv¨8üøôé‹êõÙ֔ûµb+­R=;Hq'yÃvº&= +zÌ^[5q5D{bÒ9|q€»7q@ 8è–ÿ@j÷Odˆó1j´ÃïáþúH,fK⑵ú;³½Í|¸Ç-wüÑ¡7ŇOW_3«Òˆ¾É ÕI›aZ Rj4¯³ÊÁò{x’äNp2$Ö]¹£ž¿Ýˆ«×õ:ÜFW0,‘Iü´yŒ »ÒT7Ä%Áü“`‘6è´¿~º®(ä´+ûÕVX—üÕ¤=š w1çËcÌ*}x6mÚÐÖn›û«Éo}ãàIù¼,Œ/Ü°¦Ÿ:¡PÊ)•Tezt¥nÏŽxZTEìÙÃp,.…ÃhpªÇi<ÐÐs¡T?’ŠV?2Ÿ§~dñq‚4îÆoě~5{éËq7ŸXéJá¦>æKR¤§~Ppt¯¨ßÕéu¸²í—»ZYÐJ?¨ÓxL*røOv¢’zYŽ׆ä-r´lõhqƒáüpW)IÂ1Ÿ3„Z·ä°~cß7¼NÚÒøgÆFyŠŠˆ^Œ®&½8?Ùó”Px%Ào¯éßxN´Îû\åf‡·z‹Õå¸ð œù€”twÌë#§Õ+õ|c`àûzò¾¯k¨ä‹ÌÊþ*JÜfZ¡½.±5¬”?]¡ŽFÃA3s˜ôM*šñN3Úöf­ÏûNjYÎoº×}°×}6·œO â7÷5‘TOû)ÿÃmŒèhä™Ý¶àVƒ¥yUf~àƎW0ºóh¶†~Æƺ“›Müc3ŽzöImùݧì]¿_)W qôJý‹c˜x§)ñ½~`úVi!ðSÄ÷<ÈvzPk±æ`l}éöÍ/ÔE«|ÝÄ%‘Ý\¡uõÖEë»wŠ×/Dð‚¸ìiêºYw™`1eGé¡ÚóÁî踁Nl:—Œõr­L×Ò0Æ]ª” äù´p“r#GÍ1<¬ž[E¡áçêýG;Äù7îvzŸšÆ÷2EAâr9Þì¢_>`EÒ81ûé¤Ùv•o­BŸüÏTî§%SypS9¨OF.9¿qµï9\§ëÕäA†¢<¯ôò牜4éºý‰š!†c³Y֔x]ód®RH×oFñrËó)\z=h`ÜòhŸRå¤ͱ^—×(Žg®+´h‘a”Î(dwNk áЉFö«cTR?-¸~‚¾©_:z,½R<Ü濋“VYž¶…woµx]Á|=Á殩ŽÍ@ž¦WP¡?&…]Oa¦¾$­Ê{4¼nÃ儦ÅÝú/¬øÙñ‘MF¢°Èõy­Ö2|šÍJ-‚fTšè ‰i³¹íçˆÛÔÑ}R³ú·@ёËRôÎò¨T¿Pî½ÿ¤Ü=óø…=­BáºîWW{Я,gçŽÓ¯¤:´‰Ò-Uk°¾LÉÎHTѾXe›šÕo`íÿüƒ¡ç^p¼>¸Õvûín‹<+…23îQ}]w;»Oðí×S(`9Ýu‹óG 6²é —䊘wÈÌÈU®x$—ïþ“\ž™Ç/„È=Ø.[ý÷j¾Ž•åôÎfV]M½òü(jGûöE…ÚR‚![ÝE{#þ[Ù[|¶qOSâ¹õq»ëŽtïÊ*¶õf´‰’„‹–PèØUk¿ot‹úœˆ.• ±Q+w¤LR@GK"È(Ë9ü ®)ü0Þ:ønîñ6yâòŽ»§xü ÍRMËõ¸Àn‚.~XÏÔV!°AŸs QЍ±1$i½šññÚ|öy ¸ÍöÁuwǼҭ´{S¶ÎŠ+¦ÉË'šdz÷N»×mF r”¿£Ë­å +KcÏš§:d±L©?šàªhûÍËáqnNT>ÛlÖßD³™YØÍïﰛ4»c&¬þÆâ=Èm慍±ž’óo®àhѸ”TMKuh±öl÷úŒÖ¡º•U§ï÷B‹n%ý¥3]Ûãö‹fí ùXS=7sj­¾ùG+ϕ>diP@9¬Uðs™"›Qæš¸8’1ë°pïzfߘ^eÐèù4`O¼LH«*³mݛn.uo¼»¥¸ÿŸÚ½ ò`*Vú\Hv†¨ µÌOª„:lZЫ ´ð ¿¸´nÊõ@›Øõ¶ ê9(»¯­âVËW…Ou{þ9©¯Z¢oXåÝJµ§©ås-”9*El©PŠºP¿¤g^I_Æ»Þ)D¿àtˆã•Š7vò­ÿ«ê÷ÍQ/›öÂ^¤"$µ1¢>|•°N¡—¯­ó¹b¥V;Tʗz•,k×WƼ@*ÝD`–Ìr}^"žRX|:˨èô¿Ÿb»Á qä…™_ X±òþ9¿ÏsîÊÃL'Ý惮JmíÛþíóÏË/˜B‰ó5b%;Ò¶hL븑{‚p0ÄãÁPýñǯz1©Ã›¯†ú!WÆ&<\|yU¢ØIŸ<Äԇ.°Ôx”6S-y ÏBW÷»• ò‚ˆ ¥Ù«;° ™SJÇa®úfðy•¹ÀÚÀÈÁ†·a¬™ ^ÑÞ Aû?tý閪<Ûê **ö=­‚Š¢Ò +b‹ +zþ |ÞµêsìýçŠUsÖà–.ɝ‚Ñ.ËCOÇ÷›Â>ûќ:ĕ ¡È= +)m!¸×ëUšíœ9­Ö/¹c±Ú;9ˆ8óezV”œ"<,AKŒ. +À/Ôp +΢6o›ua‰ïÍ|àùn~Pÿ½’"‡v +/€4 +)z à“l² ²W€@¡\Š‘þ6äR¨É³ÂT9)¨-è" +DXž2³x÷9D;-ZÙ4êÍó-›ŸVA©f¾´ï«ŸâÑC*ÅÚ×hƒóÑ.Ü÷šŽ<š¤Uimu€èA£„MYÌSÎ*@ôvŠtKã¾)R3³’þ?ØQÒ`iï¿©½·ôÛ $ôñ7Â(AJÆ_ç’B8Qü­ +ñçI4⏥añg±ñgŒHñ•õ”ç1þ`½GÊ4N9d½µ´|Bñ¯6S°^Š˜þ%îÒñ‡„”Ñ*årˆ‡Vçù¦"÷bND9:£Z4yþÿ“Í8“þþ–1ÈÊßoâo%ñו⯤µãï0ÆßZŸ?ÑLŽ?—³®SÊ4LÙR>Åøsk×R¨vÊ +N9 ãÏ`ccٚÇd—ËVNzÓðÒ~±xDü(ݳE¥ނR-\ÈÉÿèôýI€y>Î.úÿc e?.³¬ºSM,ßO€2NÅ߇šM¸Œ¿ÆM¿BÙÊ2è×÷§`>6m(γÕÚۆzí7íaýwQ`°{Œ^¸™DJQͬÏæ^¸?ÑZ/=Ö¨[÷c]ªùÚp’ÍUÏÊÚ?$@Ô|$¹ZÇOiޓ\Ÿ’y)$¹Q§•ä +4’WƒI€Í{‘l{LìðoàóËy`W¥O½#/Zä¢:ºÈVçI›¬ÛÚs®Ú¡Ÿ;Â¥õÀÃîŠÛ˜ƒ‰¸y ³ðâCàu/ÐÕâmìT«iƒîY¹rÞ¹r­ôi`ý4DOC4Èß:·¹Ï1NòP–™†$ñ$§|Ø÷¡|›¿&kCŽ=Y{¶› ;”8ù„'ãÀ ëõØ,àAè'^Pñ‡õ¨é·bÿNujø½ðeÙ32²—]',蜯W08Irîë­ì|ñøŠÂq£i…#F,óÿH§¡~Ø[’Ƕ$¿?YZÊVòèÄ6þ!^üc1z.tˆ ž·KÖxl{錹I÷™gÝAÛ>Þؒw»‡Nx­Z^|™O¹óp‹çöîT;É ßñžl‚yjw49¾WÞÖ5¸âű¦øpX´ +‡rºõýQös{¾ïÙ¨´Ìý‘äË ?É3قЯO”`2KK§»»@½ÛѵÜi‡ƒ®Ò}¹Û…Ñ ²|îr!öósg;‘O}s¢yꋱŽ169q™É¦Z¹ß¾ºäz•8–/çZ:T‡ç­s€Ð¾÷JâܾԀƒµðK]Ð|w}µð1#øõ1Õ÷5ù‡4ÄmçõpO£ë½“B¸Íÿ¦ö·rtµ¿`°áº¿`èÅëi2iž»Þ»ë­?z$Ö ÊI<ïŒgôâà8¤z¨TXs/PôÁ¾è“Ý‚Xߺ›‹·Õ-¬s;…±+»AùÛ7×’UkF|}hú÷Û»ê…Â𭍙v¬•Êå÷­ã~^¤QžIaôy¤ÑM“$Žù÷äÆæ‚7 =ïŒQñϏFöbŒ}?çZy¨â”»—썘ûÓÍLÛœ´ü ÇîB™˜íÑH67-bk$tgèUîh4wÓGÎ<Òö•MNŸÂúÖm¶°-w¿,7Óâ®Å"¬[Îì¥ú©RyªR—ÌÚпòGR¨?ü¤pj¿¬ßSFéû#Œ\¼Vܳr 8ã£ÁüvÝ.ç‹m{?ïàâ=ã6  éë,¥š•éEÞ¢Nmv¹ysß8¡ÊAv÷dsq8që©íãõÙMBÅ(ÜO;mÒÐO›ëˆy¬»F#Y½šA^I«4Hþ¾•¦œ¸žT¼¢Ø’+¨…Gþ^î(^ÐúBlêƒí|ñ$ö³™ßg}ÍùN£a·5E¬Hâ¹l +±˜»–»f\þ!=ððãñ…µÃµ5ÜèÇ3“§»3µ¥m){iÐn³Ö9ƒšMDm²›hÑlÔ𓻮°¦*ÀŽM¤=Þ-,ÝA©²8•üÆ¢>¼öŲÃæË¥N͔•.L£ÛNž¢kšð:ñß[ëŏ:R…χD6è5±­¼–²8Mì³qÉ8ÿÃÞƹýéŕ×.Ã#˽.…Ý›wi37Áhmòýð›Eû³RŸóÇn… O¶ò.1ÛZ–åXVk÷xu7…¹¯2м{§Z³Á©×Ÿ¢·.èP›€QOä ¶Œ ÆáܼpܾZâ*i[Š=uÖköÔ­¹)}ïÿãøGÖ²áåǝumOªSv ¦±ÞÐ:Ûx›Û^eÔg$/Vøp¡É–†ï¥ò5=çf5ÛÛ:÷š÷T ˜ÁËjqŠžaÈÜÚüθ!“ýú=G^&g«<Óöú´ù±˜«Ô»3bÏÈ3­ƒÇþ¦.3íÂÝIùzÇxöÑþéVgëH‰ÆjÓ¢Å.†Z¼Aë µ=Yæv-?hz¥•È¹l7›ª ßÝbf˜®ØAç·ÙóÜ +¦[öõŒÑ9ÇS¾09ôuîØ¢»\uÂlƒ¦YFtÒøæ¸G=/ôÊé}h˜{tixr͏£WǹM¯Î1Ãý‡@¢ãEªîL—yÈ+[ÞÙ¢i֒‰ajÓÙ7û«Xý•ü)šH+‹9fjó`Íígëjݛâ‡WÖ²òƒMÈÛÓdÕð%‹½ž†TÚºÄÐØßÇìz,——¬8Ìk–¶6¡vÞ(ÙóžkDs²#?&b^†Â¾ºê0á)Ѻs)R ì5Feö‹’“a‡Ó7¹ Ä/¹Æ¥WßÀžî¢o²ŸÖüëNˆ õæ¶rƒÒ`w›ƒ21ÆúUXà~™Û­³êÞÈ튻mÜ­-Úçð²+Žu³ÛJVV·å‹»?ìÎk󍷛 ®Vù75_Îý;Óe89ÅÞxÛ'+$¿ĽÐÍÒvxÐu𾡠±uþΣZé¾D¾“xƒ—¼Û­¢7pzùûR‹QŸ¿Wr½KwPëÞa¢ßí¤7»Ž\¤v7÷mõmEm5V»m՟ˆíôÛim¤·ÏÖUÿ•üÆJ´¦hoUMK¹b6æ"L÷Y¡|ìlŸêõ(:é׈¥ÐÊ£„*H“ x|r»pI­.FùAÅQäþ´¢i½ëÔÎF +{­›wêJû£*qÒ¼+¥öGÛ­ÄTÈñºÌ[ÀÜ5wì#lR•m£9zN§ÍÂÌÝ4 t¸kØñÞøC÷€¦¹^¯ÑµR:HÒ¢7Ù +Y>xcnû8="oÝáŽkhâ†ùÁd¼{mãt{—[¹óÜ´»øCí÷QçÚ[Þ_´ñziÓú¼»Ebܹ•ûha“&½oã°ª –#õãÃ˚ƒu^A´Úùe]k³-[®Í–[›îªÖ}ã6ÁÃÖW…¿Z¶Åœ8#¹>ÿ¿|ù–BÉéï`›—PËŽ˜ë>>ûwËìýFØÎö™4*•"X÷BºYV[¤^‡oTíZ¬Nksg¨ÔZˍYõ»¾W•r­°Úµ¤BeÕ Û•?¢ —(–§½r²‡òåd[¥ËÉb£”ÜÕRüìø•?TÀl¥†Âȳos1û/e®Ã»!y.Ý`ìmޛ0„ø¥®R?-SïEÊ +ªƒ‡fC¯ò0>åœ;.—s¾×)YÒ+Ñ$’½U>-U±T¬½µâá…‹NáÙC»Tdo> +zÄxz“Úª‡¬]äAá %°¶Ù`MíJTkÅhrîg™Û¨:£ÛÏé}†<Ëã8l« üxr°í¿§ÌÕÇޛ×ÝÀ™èNBÔÿÈyðó@ÖnÐË}4G»ôGí˜ã,KÝB¾ñ×Ê¿o£{ÝøËɘ\Cܻ؍g/V…V¿ÌkÏsÙÏ٪wÿ.¶d<¾ä+Mþûˆ +sð¡îµêaî]ëå‰û·NÏnÖÇ2¯Níy¹ðþ-;Îóœú87­™ºÓ´Z‘û `9i¨g3 ÕR¬$—ûž“\¦˜ù°ƒZ<òãދsÖhT‡92=X(×Áô=Òí›_º{=2};wSN÷QO¹ßlU ocÄN®Ž“¥¹*Iý"Ìêƒó|9fN]ÊY_·w“Ats‰}ul}uÌÏüòi`Þᗇî]öInòu“Ü‘¼¥¨Q’3‚ü›ñ×¥ç­R€‚ð³o<°Ö´çO»îu+…ÔäZ¹Á³K=èÉgqoNþ3OÝvðV$æyp~r?nÆbV­¹‰»úºúäQuKv(ô$ÊÕÄÜW[•³=]¾ÎÖ5Ü{ÿ!®6ÿ‡4ºØIrz¼Oòeü”ä1ùžä™sô†Pò>‚ùóW“섾ƒ§-på;2t^´û ï¹.öŽïå=bÏ"åĹ¹eqæP!$9િ=0ï¾y(oiw?ùòWû<’Ÿö¬6·n,Ô´ÚÁÝõÞ¹µ §mc;*g}Oýc?œÿ0ÆÇÃéî+:i”E;ÉïÕK’Ýñ¸ma°%Ž>yÆöWþ•6‹”ÖÌ?Æ*›¸dØÍ;Åm½r€”RkÏ_KûÒ®dKÙM¾D[‹K…ß­º¸“Ýîʌª¨aªgî`ÄÍåÕÀ—æKÿö +%TçˆF»ùŖ=wŒ-4# w›šíÿ!É·›‡$¿Aö¿©½uãôô»óÝ#!w[ßt{ëË\,.=téhn];îªøöµÏ½­¥åvʹ]2_ÅvÃH€r× ¨*ªßí‘>Â{œf+홖vRW[g3I#ùHÙғ¡Ÿv/ëໞ3LS½{%~¼F›•²YïWln+ÑglýC’›V¢ì†áª»½3Ü{~¹ˆp +]MruÎ)C€d_?›œdõèëÑÜì67Cß®^:5`¾Ú^¤‹[—GªÛŠÝoo¦%^_‡}b-æhFõz¦foëZ­ÙP^ÔÁS6Eð)'[–‰sy$퐕"â0mji§¬µÜs®ùé1GìwÅè|jÍȗE‡<¼:§] O«˜c[ÙmãwH[d£jê ·Çñã¶9ÏÑú†X_õÑU +joºüÍ ^æ-åõú +6šã²¾™eೞIi¯–{;°–å2t]¸G%·˜8*ž^QlàU-¥mÌoPCÿ‡¤P˜9Áë]ÙÞªÏ\–ò¶þ…uœ.0Ü_ÊCÄî ÌÜÞ J· Æ\ƒÒþöfæ²»u‡î»jŸhÞV\|*x;Jdƒ ’5v! Ô÷%›sû‹#â⋪æ³â4|‰óRÉÒó¶FgÂyÍäê¼3}ΡÉTEÕMŠ¥MáDÝflþH +ÂñôÈñîú@òܵgKfÙë¸XŸ¾¯f}}\oâ[¬që»[̾ªPß­›Ž%7¦'çååM*Ž‰` Mñ‚·zyñ·¡ù-óÜÌäE›œ>ƒ¡0ESE؊º%àx=à S‡x’Æ<9+*|¾YÛdü^L“–ꯓÜwî‡õfíśÎÔ©èØîSÜL£k |k+èö`½¼›Ôê¯E –Š\h£[©TkÙ ÏIŽâew½ŠÍ÷)œw=›;8SêÛütݖ!!æ喀Û*›¥#Ãç'ïń¾4tÎiM/û $‡C2•eŠ·ÎP3V„O`nÞjClu ~¥JY–c÷º qƒj°­²^VÖþlÔY½v(® ¡+ퟸœä^«E]sõ¹‹Ö,ìPÇÙ@Þ¦(ÓÍh$¼iC>Ÿ@ÕÉxØïsŽŠ“¬§Ñ+‡¬Zc.è1sz 0­ÒcZíú<…[e(Ì\\®þ¶ j\–àGvÇç»`KŒO™º_Åô2Žt6â¤[RáNÒP†LKû(¤–ÕÞþ—¼¿ÞW˹4eÖ3jS¬î"yùÑópì›ÖsRZ¾\ej–Xá浙+¤áL‹ÜxyÃWtØÙ:´6Þ´òl )§)­D%CÎȆW叇Á¶ŒSäK§r×xkõ¸Ò†ÕËaÛ³Pëdo£°«I‡¾Ô]VÝÕP\)fÞÛÁ³é/˂ÝÖüηÌÉþ,8ס=®Zá³Æ-Ûñ7#â£ÂØ7…ú¸ûRz…9cêe|% ++àö(Ù?¢Qrx F‰#ò)¾œ‘þk1‘ÿði>Ñ=íÊ/öא›ì¶ý=­³Ô#[Òh³˜GíöÕ 2ø  e5©6ÄŬÌž!HM·âs’^f‘݅2)[ô–«:¸Å6vÍ##¾¡ëXz|Cú9(4,Ö+ÔæAôGŸš@†s{AîüoöN/’’値¹KR«—²‘È]¸ÿ—;4wµãèÑíLLL)¿Ýðu_²[²µæ–5ä–;SšEø¹7Å÷!äy#X™8¥Ù”ór´ÄδšÊ,”¯1~¼óý|g©Ý +o]’‘1 Ë£œ tHºÔ%‡‡áx:,[fZaûwâÈô[)ofX>L¥Œåلˬ¼Î‡âÖ-Eù¹õÜv'íNéí¼sÀWé©ß” ¹ ˆËÊô3[ãdQø^É&oË$<áP|ÄÕs}žmƵÓ ¾«qÿé4òðlJ«9§‘Ù2³gØGù‰ù&‹´YçÔ$< Á‰Ýð™&lð&ñ½àÍa\Û¤Eá3^à3¥÷Cüã<`?«Ã¹Ìw[¯4ѹÞd¼éŽT\qƒF–‡n5OßÙúFÂhäøÒ$®r'4ßc¯ChÈ,ß13V¾ÑŒ^¿.2¥}œíȌֻQ¡¥¸d©7¿ ¹Ù<"nà—Ó¦Ž·@Á–\CƒºBê’eÑAQ+£ÊX¡ +úž£Á¦º@ÿðˆ×VÞ·Cmf’Ñk¢Õil¬nÚ$&q¯°6_U6_ÊoƒÉ¤7KØë}^düPkŸ ‡Ñoè÷FLJ¿ÚÂhwT#0¿TÉrI0†Õ±'¦ô茋`þŠøbÝ·XEÔG6ƒëAo-Ö;kÖ»BÖ«8'ÃsZ# Ÿ"œôn³?²ÆíþÁËVÔPæF©åó_ë1«\B×Ǿ6ÕÃϤ:Á̃ËGc.ô–Ô(Cá#k#äÁ¸áqML‡Õd¬Í¡á µ1¹[?¢ÏU7;Pø6ˆ,–`£.váœx¢”WH;àÂrß?4ï¤|"–0›Çù?f­ârGtQ;Iþt ¯@F./xþœOªèõ²¥'™>ù4¾nT^֒QÑ>•H®]ê …~#æhÆïé~Á«¾Àúq}®‰–‰hpá·•+L­×€~Á`ßi3Í>$ïÉÿ*ˆ½Úfiu/x?«Öz5®ƒôj„Á÷jÝãülˆ$cüˆÛ¶êÎVdû8^6Â`ú­6*“ÚhM ÒÍ×/úފˆÖËáRS¬a¡æÐ×ÎÍÚÐ(ú,¢³¯9x‰S…×v°g{PòJ§~e_zÓrè^ùi£Ûº¸xG*¦îqi¦uZçÙ©f¿Â[¶‚‡Ù?숅™U¿ì¾ú)Af#y,öƒÁ@(ƹ*۝Ä9Š*Ä!jÉ}³Ò 1R„ä6‡k~G)£€5ÿô§¢t`Í:7ér|¨ý¥Sí¨Â¹"Çs¿ÒלŠ&@ZW» yÎár¬Ú£²†D|™(!«Ò×U³¬zÉL+çÒ¨¿Kù8(ÚûÝ´8f »Xª´rÅñ°FÇUvRç³?”}c#-üä8ZÂeÌ-‹/‚ɟþPDŠ t(%`ÿLqiÙͦYÄ;^mÞÒЫX±J»ºkìtÝ£'Bá™2Àj]‚RÂnáôî Óíœ/4Ø@-48ÒÉß*ç(ßVñjî<ɜ”Lå\ïØ:j-Éú7€ZWð”€ýcy+43’hNþK™ìÞr|5®ÚŸ­` ±gÃÙ.nU¿ä!4îîK`Ý݁“´+4û'ß뗜ì®~“aûÒ)Ö¹7 vµ ± QBh›h=Ö–oŠ4 J¿QoDӓ ]䓧 Ïý1ǑÙtr1æ—/ÏZ6 ý£ßú¥Õ¿z±­­¥¸QYj¯ô½”õ˜;Y¸à.åÓ!¬'6€«;L<•ö>€ê¯@­/€>Ä2€~ü6€AÀpO°%¹ý塵çÀ\5`Ç^À` +`_Ûp¼”¼Jöþàæ>ù¥ÌɳXÅ1­Òï÷/>Pmëµg®~:<£ŠZîø%ën^A"Îéfò÷cxÖ>µÐDrl|=ÿ±à؆xØ^ìuM7V/ŸåY·d òð j~üÿÎêíŽÿß)ȳKÊ3þ%ˆQ¤ôGü1¯füQvZü©3jœì{«8Áڛ8þ0û86ô[“aÇ£!”²ïÅ1U"SÆ|Š)¥DÛ8¦›v +yL‘³S -aŒ;ÖëmV¬Ï;?u +/úv©DN'îDЪI<=ø°|òqÙ /DÛ ç|þæ®qú‡øó}¥qî6 VRãO–™ÛëT“Íލ¶Ä 4øÆq UâØóÓPOÝ4ԝ0IñÒP­|ªÕ·bÁ}T~Ä·âå^¸x“ß›/Îó¦R?-‰u× v&ê @3m©²6sD¡‹àjÂ}áõ¯ê˜‹¼îŒpÄ9Ø&{;” +F²wnHËÌíؚïÏËÝòxXíº²µ2þº2•h¦üH7ó+Ó؈4ÀsKNr=EKrCÏJrUo5Êí±·ë{A„´Ë ¹ïORC;_Êüá&ûuâé^s¨š^9ìÇzóPrw½ý¤ºCö•óudO›~Ö)´ë>0³Ä^AÚùj]ÛI´àš¡c>ÌÕ¤ÕÆu]‹=W­)5d l\¤Hc«InÂ)Iε·¯ê7Y…¹·xlB6“¾º>:>õ”ëôˆOªc¡'ëP¶ôã¾êì|»qÚ½¬öÍv2´w=ïX5Õú¹m¼ÅÛÀض?„þáß´nÔ«i$b[Ò¨£k ±÷¶l¡oŽâ){0f}VJ̺ñB—êm?Xª ¦¾P;å‚øÇÿ¢L¼m´±é݆‹ä•ÆØù¦22hÎå¨=¾gÖª;¥ðؙëòóhhù[vëÔÍÒ1ÐóÃc¬ÑÖ%¯騼eµ ¾ñ€¨³á-[_ŠMzÝäA½W+µ3=X« Ùx¬úËsMA¬öP֊өŒßŹô]2³ø E¸ÚúUÓZ+Äm¹ËO3Ñ{XüI¾éJÂóëiÑa<,m@8Ìlí§4Y¾dƒ^æ†4;úNZãZ¹¨q›ÓNY¬Ev¾V¥ÑX_­0ÔV^qRнËzkð”iH£3\Xî›Ãêr|» ·«‹ÊêĉB Èó+Ús¸G3¦e‹œÎ¤4žuý?ë&È¿¼¹œ©ù;´Ô ÷-]Վˆ§@OÄFÝç¢x¬ÏüÇs0ëÕs£éJì̈́×g¥ ³r°QÒà?åˆ×o6÷ÿÁþñìÂì.psÃóìø9ä¡Æ V_ãÆ·­€:x¿|7ç­ªë´¹BÈ)"KSZÎç&üò Á‹ÅqUUÕwCAn7_Ô>îì1ÿ\f=÷NÕøÞc({ÆCÀÜ~‹7ª,ÆçfÛɄº?WPšœ¸IU86b[0['Ø æàŸÊå†Ó¼Kk¥¡}—Û3>á }\ƒÛEDj0hd«Œ(1VdòþéHÅÕ[x-^i‡æÞ>,fAMU¦Q‰ßL‘ ¿¶ëðß"åIbM¬Ý:7ßf•cñ{Ÿ=îŠ4[É%s><Ìly+¦WŽ˜MMËpüÿAÿñÐyI>=¯y΁LŸ°õÓ7Ìw³±–InÝy¼%ÖõXÎß…¥³Û6uhÑ[u•œGz<l„b½–=!ÉW_™'ßßíÄîÄ»Iq•÷8ö–÷Y¯SKؚ‚–˜Ù•ëŒïmm8îÈь¼E+ £•b¹Ÿ"ÑÔ?üFK~CÙs—ëžØ¡Î­¯3P¾±ií®¹Õz½ñåB³÷\r»ÆW¼všÐ|ùj¶g¹ˆLÑuq$Ý;“ö¨H³IlÏ}Ï íMñ¢ió4¬œ'¤dóØóuýeny·E?“Ý€Šs:Aáôn<" ‰'­$’à[R‡,¾Ùü@:âçÍ>ďG[ ªM¬ý’Fèc›ž?2nz¨Ü]CèCBÐ6ÛiXÛå‰?Ž¦þlI|ц5iÛ¦@”o',/kˆôš!dÇãé±ãx¯î²ÍMå:øÖH#ém"rÓîhTœ ¤M0äС†Ùå9„Ԍà¿C¿Œ»cÃÖ1D•#ý‹D軎¨ Gù$Âñ€sàÊ2+Â)}Aè&ö‡[š9¼'ZgÕ±ÄZÖ¿‘ǽ$.+X$qtä„NÁd–ó“M¿r;Jš~HÃ0Yí +9¾Ã¡[éÁÄ©ÑõEÁç^[ÀüzOºLoƒøž¬íáNJRÃc–~˜vŒÆ«é PîڃŽ‚)÷þ`ÔÍc“+þŠ0ù=` Õnïá*ÉyÝ¥w‚³õ!÷œ8¡s‡èF§µ½QÝށÜï¦Ù”ø¡{ÛÄÃ*þ(SóÓÄo ØÇPÇzä‡BWûÜy—AÁHpëvc7ØéÓÌ1¯>ƒlËýR½ɐáz²nö&ƒz®7©›Þ¤ ?²”ª;ˆÐ¶ ¢ƒN6ÌÆï¼GÊè¾ìˆþ,Lùrõ·æQŸêÔ ÷fX½¾müf<=¼So?1Y$¬UT5$ΟßHØpŸÙ)çsé€¦ßrÿà–Í>”k{µ"vgœZì6w¯³ ‡Lg1.éVüvm­ÝY”¬#~.è»mPçµSNdóÌ¥ ÕjÍaâ‘Ý¡yfm<™´qxÑ´h³ëq‹õ/´†Ä.@ˆžqƒ¿Ïw ÆÍ"\(эÁxÂ÷úÎy†õ¹™A÷¼»Å÷êÝó²;_=·û=wèt»ð£­¬ä´ ÷þM»n­—Cº…v_ëÚûÆ-4¿l¶èŽ¶‹‡dü>¡†½„m»9¬ri5¸X”“Ö”׬²Ozû.$t_0åhé𮯥¸hõ«@>[e¤w:ÑA¯Ñ˜%ÝëÛ+uÅí·ÙyÅ~GÚõ‰NbÙöê0›µÞÐvÕ„³ÕÔo¹Ks¸˜|»àÜhP«!Õá—Zßß/Ïú>moÔ÷’ ×÷ù‘¥T³R›¯Sõ½jp2ÔjçêÅmñÂ˜A‘|ÆÆèF´ÂÕÑ/Ö®¤óÛÎãÊ­ÛI˜­8¿<¶¶—{Ðü¶â¤i<ê`“4Æõfž\÷vÞËn6 Úþ²"Ó_ÔÙ#»­CüÑ«ñ×ò«VÕjuö-Õ¦²ZTî°p«Ü›ƒJå/Óîï}ü±éÅúL±ËOnq_݉éh(¶X¿Ýiàô#6æÄ}¤óàݎwÑZšÜZ5JÄi];5\³&ÜB§zínU@_ÙJR¹ŠOí*©ñêTº÷…KŽ…V]{ Á¹¦U~Yª_ÆJy°”¸r¶lNIçÓÒ°:¥aÁ/•ˆ[·["#ô•ÙÀ¦’0WÙù¦c''k·5"y¶ùÅ¢É(‚Ç£é­×R­c+ÙxfÝu^jU¼1Rù=g©¡’1ynJd ܕrØ+Zkñ‘rJŠ4–+ifÒÇ <€Ya¼¡AàŽo6.ð‹¨‘?‡ô(?SÁu~¶.½óçè”þîZ‚SêèìÖəàT\ѵ±À<Ò +<«]ªèvjxXo‚Óz÷D¹wo}àŽS?ŽGFµÓدËÛWY*ÚCkVš–š¿ò6?ß»|‹ºs~1wÏ-ïð;×].²µT°{l DSÄ 0° ›í ®cì¿008Xs`àL`àOŠ)a7%éÿXH“Åd +¦u4tWeÛÛ6!uÌ +B©z®×>N³wµŒÕâ\çms_Q/½ ¨u±4y+…is+å¤)ðY§ðo­>¾#Ž­<€´ÚMAu@Äî4ÅÑdKßD+–²™„¿Yªˆ>Yȱî¦x €xJ/ÅF~Ìr^Äü/en‚‹MÄ" ¥ÞbóJZdxók;8B/¤k—¨ºn€¹·Í/Š5€P³€ì¬Ío3§‡ φ 9æ ÕÍ@{þ@yPYo¨WÇôkO¬K)€ Õ"€ñ`BIJ1›v¢»œr¯ý˜ÌkD6µw ,l(žÙ.J2Ëzï>e +­Ñ¤Õ®#üaçƒ×¾p~èv®¯çtž)“¶ .sPêü/ë[º¦ÛÇêé¶Dî `°[¡ñ›A ÎQ§!ÀUk àê +à/°›D³¹O±B€hAù”&øã—/“+(ÆÉø(Äñ¤?Žã!?Mynã˜SNÑ/s;êS6í”ÇԀIYÎc 4•÷—57oòÌw^pì—]¿¸/ú]^EñëGNŠ"Hi~ŸÞ`Tzò/³^ðξ²6͇Ü)Ðû¥T ïcÐÙß܈?#JŽ?õêrZ×l˜(bý—üôz¡ú䟉ö¬­KV8K +‡°©·ÎÁ}H<‚Ž5~?”â¦ø軥¾¿®Î99ߕ{bäĞ|úœ]5j¬u&óÿ‡ø»]Íâ/Þ ÓOâïønw‹øËîå×áQ–Â\ý÷|-Ýs3b}-¯*æ¹aøï1vO^ÏGøé¿Ü-òœ›+:ƤQsrçFë`Í°ÁŒbФñ6‚ÍOOYµfך•5[r·Ý=WLùNÀFDhŒœæc=žŽéÿÐ(õ#þ¾W|ʄIx/ąŽ8}qè{#{x'—;ô›=Ò zoîˆø¹l„Ýù®>ۃÍ~ì½#¼{薻Ù^}Z³‘Xó’ßÝ÷xy·dø†g]SᷘEçqÚfÏÍÒ룭ê¿ru Žå¶ögÕٖHŸÜp—ÓhS™ï²ç=åúÔZ ¤ê“XùÓçUߒ¾¾!:·=­7®Î¬œ–srµ¸Ö=ìEb_1‹œu¡ÅΗkk3\×Ls4ÆfØ?ë‰Õ÷u¦³W#ë€C´·µÂi]Ýî§^w[ºÝÑ̈́(Ž7U€×Sj«¯ÅÞCmwϵ•d5PåY¬••“#þfŸø_ˆÑ¹Ðã|C°k­éggš÷[ŽȬ[.sSE–6ÓÁ` ë}XÖP¶Ûÿ‡P>Vù[…ÍSÇagÚÝO-¶²[]…l͈Çm|ÕÏ!šªT¥>ÊK£Ër²›µ¥ËÂËýˆ.K{–YT „§yDœ_ǸòÿÐu¦ÛŠ*K»¾DQQúiAEû{Qïÿ µö®=ÖøNýxp:g BÌ&âÍÈH·±#ÇË ±CÄÖ¦å§ÎÉ~ˆ£—ÍM÷%+‚@Âëër4§Ä±×lÜ¢¤™ŸI%s®ÍÉÿ‚ø‹s?­ÇÙâR?`x|©òxlÕ>£5$C©,ú×ëyïóÆñæM™Ó9§•Nsvù6èv+Ú3n;ވÎ)]ª)n¬V¿?síÇsÙ³ya3²"[Àã²k*x3ç4Ky5Vó`4 Ö5*De§o¯»¼Þ`u½KÄø_Iõ{=M’µîÊü¢ò.àSÖþÀÄÞßÁqú7q÷Æ°¼ò +CöØY[jÚvꍼÛ!MÄé±&ÑÙ÷5bhÑzwêŠ%]ˆf3®ÖÝf¡M|ånS?s‘±¦´¥Qqí£Þ:…/õ^e­}§ ›m,õ¬;sµ3µ‡ŸkÞØ¿§½æZz¾øY’;bᑖG6¤ʕ¾ ù½÷Q˜tÁ%î •ýÆ=¦—‹Ó›^Þ­ÁâU´G›j¢¯·Lç‚ih+ÕX¯¶–äVmÝQí¸|L5¼RÜ©=‡{¨äAÊ {%–l|uÆóŽ3¼ßç£SÍ0®Qû‹Ãv!›«ÂgÅÅ~-ÆÆà{ ëí駶óÔÞ'ê ÍnäâacÞº+½âæݚÐí\sÆ·¿ ’æ’Ò«&4 ñxZwn¼ %¬¤jx—·ÔÞUé*w¦5RÏÕº‘ +¯kCèW@ùô1Y^<Y^NF2Øì=dyMU2µÿýá»îyFîÚb“÷ØiÐ`QQáÁåS¾÷ÊyÓÙp“‘ÛeëA+P€©-âÀÚÀ©Y,U_f,FµX€õzùj]剫—Å›UérNV‚Æ[o¤‹Â×åhˆ0:ÈæúæBnT£“4ӏ€¤Á*.ý¨!.û¸¨÷ ),.ƒZM‚ö8ú[æ(ó½Þd'áÕÁF[®QìÁëÍ+ãu»^1¿GëþYy6€EaS›y3Ó\E{ÃÞÍoº›ÌßZ÷º€Tÿ9.+|TS8L5ÂG,4~¡Ê“÷­%穧/e3S,.ßÒA,Ëý·°¹ßÁž7E¡j俾€P5¡‹PH°Ãý¢úëOÎVf]‹dÆSFņm© +ùRqzílmkåøÉ÷¸‡¶ÞigL`l›èXo³ØJóD&Q¯ÛVª<ŽÖ·ÐŒÂÃV©ÙÚRV°/Í­NC*îM±Y=aëÇBuŸÛòWyòõÓæN½ +ÇyÔ¼Íyôæĝú.”:3ä¾¾ÝWXÍ ú[þ#ö÷&š/d< ™S¾W¨´.ív›ZÚ¯ÍcÐÔe´m´º·žv.¬‡ê >Δ'ýÞ+ü¨rkH“Ê[Žó8$t +‘ô5‹‰kD`Ċ+KBk%ëü±bµÊ­3rÞr±äÈfåÆöwÄ2Ιfžõ¶Ã<±îe ÌÐEXF°ËläW~XÂW@žré› ×0…÷ŸBv› zrnä}nø¾o´’ß¹¸Z¯`8ÊӗýÆ{n¹ó`-«òî,-f·T‚‹Ÿ¼hY ,ìöPM¨ÕaŠï4a;ï•£jT‹˜rŸyn{sfÔz^è÷ÏÓcsLÒr…±hᾩ½´ ^zÜhTè1͕ÿbîÎWÒ$W>2#‡†q_ÎK@½<“ŸdnZ”îkjØÊh5 v¥eåHp@ÍE»h„}spj»ñ7K•Oœ¤ÄãÉ¥Êùĝ`ïý”cÙT˜€,úÓÇ{´ü´bj†Ž”z…r䒱0rÉV ÒxWä²¾ÿËRµL.ÞE˜‚øzù‡ßjI´PÖJ³¬–uoq.~ÜÞ<>ZñՌõ¤NúŠpÁmY«Ï q³›¸‚=þTN&<1€6œŸâgŽ^Z/vXîæYn;C˜]b `ÌèÌåßHÔ¼z1¨bç·c…47ø˜ØV=anüSh†›Š»ÛÓ?ä‚ßß^%|¿{ü¦| K¡µXóý°&V;{uþj…”¼oÂG:Öü&ڗg¸%Vcû;Bó$P5ÙǓ谼¡ ™è.ÉOt\ï´² º`h%Jߘ(¹®º$ÙÀ!vÆÔ FöiýVEzÿËõþq>­÷—æ×¹­÷»+(áTâã8âåa² ½ÙäUiD+µóõÚÞp7ÅXy9…T)A.葉żç'Vå«KîµG®ßå1™5Ù5‰Xá™Ø#û¯:HÔÜ+ˆ'X±ŒwÎD»P"‹õî]¥~çf­:݃ZR«š0‹ŸèøõQyÜPyÒ¢r‹¾¢²2…P™™—þ"Ü Heðh[BwËO¿kwĞÍfù³×úÁcÖ(ï¡Ð‘á.;ºš-o Âõt'T½ù‰7Àèî6®?ˆ×¦>ÌїÚKÓZµÀš¸œVj@÷A S².¢ùAìÎÙÉרÃÏYIÎ )öÅʖS¹Šý®ô*[¼žù~“f¾bû^é/†§.ªùÓ=ĵ½€/ÙÓK)5ÚÏ䠌›Û¹„4n!wŸá}Z‰.qpWߍ1ÃV44Îïšh¡ýìTõKnP-ùäY7ZÄÊG'¤2?<+;#V˜¬TЋG•þ¡QƞE>Üî Ÿcé65ÁÒ@ùP%ŠÝóš'%f]ùz%f,Á¥þ»Yþa0Êß4¯r ç¹bÊMK;¦;Y&Y°ZñWìoßú†¿ +þJ¾=»ˆ±Ý±cê½ ,ãÔÜÔÀ¤ßFìEΆ¯š £Ö¾à¥YÐý½S(Ñw/¿z"a¾9æùŠàìÀígq[[іŠæÚǛú¹ïò*p&Ú#€ì¿9ˆ +éÒ @¶¡n†÷ ,%^þ‡_p'|Tó`¯+j”,AÉ¡fnôÜ&4üzoð+Ïj +H‘V«íÁýûú{x}QÎQfa1J´<Ҙ™9¼gÚЭ ¶P³MPsh‘A=Ôa÷¨'[Îӕb@C§@Ý#@—ˆb† Ðð  гè\î›ý]ùòmú™*vÉ8}Ð>×p<ðâæÃ7§~MãmMY/c½^‡0Û@=hVé88Ám°NoÌï|¢ôzâd¸ôú3°“ßm>ƒ5ÀÀ·Àü`Ì#’í:Ÿájgö¸Àlì·—{`®#`nL`s¯ À"þ `«åêö‚oH’·‹E£&\}»Äè¡ømy'Ï5†V•„$&¥ÐnæÝzy;u:ÀõpoÌðãÌïlõ–ŒV9ÏÖ)¬6VŽ»‹î–òGy5€³ËÀMfm€›²ßê<·}ÞîWîÞÔ>_e˜í¾€<3؅L<\ñÊì¾&D¯s©²…øP zãᣦ>;‡J×ë.¾§ Œ «16ÛÉ¢°¨œ}êþ(øÝæ'÷’…É? È3¸Hù +¿óÀ—ò7€ÇèÀëýì†# ðO_wA=ƀà¶o€0$‘ ³! ,Ù $‹g†øˆ³kúr×Vú*jšŠw>M%PÊ 73ìi*3Ë ÓKš6*`†6úG>M•ræ½/êæsÎSވÞcVåúõÐ= ¶=½/±îâ'©žƒÍî-“›ußÜ®{.y_w¾dã uéæ¡Öù¢ ÁÙ/ æF‹ÿ ékÎìÔ%MÍ={á2)=ï–jfe%Îà}åÓ×;æhé)¯Qô¡î+Ä}YǸ;ì‘òmCJú ðÍëžÕÝ«“¶¼K"¶—.à…ç‹âMÏ~aº:ݍÕáÄn$mñÅD8ž¾KÇ QµŽòÕô3øÃ#Ø·ƒ3¦1ø!}ƒÇ¯¸Ûk¤é ÌU÷ÎfVÂُ’ãdx†™‰Êæ)¯˜ì.Iî~³®¹ÏÕy‚Ð% o~ÚŸÀõ³Ÿ‡É35ǹSPÂ¥»fÕ$DX3öªsœÔÕîôŒÁ¨YÀv–;Ÿ¶.·µeÞ$æYÝtËïæߞÍõ¥µ6þâûÐÞÈZÍ­#¦¯@æ³Æ`Éÿ4ϲ2SþjáÁuOÝ'm,?9;Ƅl®½ñÒ×ÑS{çÂw©…ҝÄÃÜ ÃG±VÂþ"ý”ÎÂO‡ÆžââúÒ ¦ÙԁހÓpq+ìWñî³ñŽniÅÏÅú2×Ó¸¹Q•™U›±Ãjé14ûS°ÃÉyêǪ¬Æ·ãæ0fñý%zf£F$0ùï`~ +\%” “ŗP©þÇ.žF4„»Ø#@úViàõAmáÔ~è'†Šþ~Œ’ü0¹UôX4 ù]½r¼nzW$Y=Ïa²P£î÷T’™•¶‹Ó¤Õ®O|ÁcÇA£ßˆBÝ3ÂÏzè„ jÞ Áûa8Ò¸Ód½^‹¡)Ûa¬žÛåžAµÞÎ\/BúÉmKõ»3Bó¯ÅÀ÷éžzê Á仼꽴OՋŠÄW›Ê_ütóK_ØÓǒ:­n óYåö¼(ÎÄõls½n¦ÝÍô4–¦ïH¼¯Ka>Z×GÅݑ–“£´ˆ›>8ôŸß5‚Aýùl÷OaÁï“@iä_§äÌg +̺÷X´N=î?½Èß<‰)ÕºÓÏwãävæÛ¹}ïv3ËíŠHÀÿ½UŒåSnØý®°o)ý /Õíñ=sfËdÚC§³ Ó gQŽ|®Gúò}V008ŠP©VàšëÔhŸÉ|úÞ¨Š+Þ»žt¦/ד½®rWƒnM;úk´n¯¥Å7Ϧm¹—»sYØEOÒ9zoÝéÈÛië<o- +›3¬JöíÿâJ,ù`ÍÊäjŒJó*ÞyM‡ØGò›Ž±5fó\<èŒä¯žÖ§lëÞK1ð>” { çÖºYó ;˜Ïu`5h´­e g=É·\g:ë:Ia9pp#™´z›tÝ¢ZÔÅ<ݜ• +˪¸d Ûç ùqæç¦üª|GìJBÿÂY)yë·úØbEÊŘx¯¨q¹î†›ÛzÔ6¯ï—6a/Ô&s¯Q™º›<:¦x͵måZr]ãTu’Í•pˆüé;t¶|ý$´hÐìÀÎgcò¡Ø¶D¬4?gsÞlPÁÁœ›§©ñՒ±\û¬aÚ5×(£¹Qfƀ¾y.òÿB2«~¤uóõ9Z«}snÇïJòUJÍõÀ#ÔÐÎv§Ôé~W‹«Q§lV—î!ç$ЏֵÁ-z.íaI©Z/KÇ-q¦ÐÍiQšù¦®˜Ù°l™E'êf² õ- |K³èöM¼i¶Ÿ×Ü@hõÕÄROVo­žl4U½*›û/€›õL\å…Zì}îP¤¤Á=hß±•?\€Coª•ÝΪµê´«—~ß9Í£oùVß®ía°:[¯×)µr¹c®©°»¢9ˆYŽu£©œi};:òzKÌiÚaZjiXì«§…7WIxuTú­üGa¯Þx¤U½ñx!‹Æpµxdøä~’j Î5oøawªsÜbõ:¢ÓAcÖSîÚ¿…çE/×ÛÝqrÜDZRG»ö“B‡VôBg͸ÂìšG¿š¥®’Í«ê;T-êhGýúZûb`ꙶhÕ{ŒdåÆ/š +ÓÛuOº4nðs}/¿õí[–6$ÃV‘s­ÙTÎ Œ[†% çœñû/¶L.ÏΝܨ:Úh茀o4Ï»g÷Û訙Y9;j6[8Vn÷ÌE+ŽŒug±0*ŸÛAGNj– ÈOõ<¾çT +¼CÊ@K…-ÁxcdÕ¸†€¨šxô›'$Z›65½‡¥ ¡ Uà;)9ÿ@5RŸœmr~Ý.Éù»Q…Šöø‹ØwndT<ÐþЮ§íd°i=1üéåßÁætø¨( ˆ¥E¡MŠ•I“ÐCKá±s«Éõä©ÇQÈ+bíâ‚e1zόƍ #ÈnJgý<-k« +G[œ‚rž4´ªIÂÅšÉŠ@@ê›2‚ïf› +¾;,L|·.ð]˜¿•¤~ÿ‹ÉË\£˜ ~Ž{<ۘήliZ»ÚÍU™õ^•­-+86Fp—â“d0'2©VÒáÄ×oèOÔèFn:¥Áø´¦fnùDiuúA.= M² ›Á°N éŠÃ]âªáµ×úlyÌ/øV¿Da¹î˪Z¿øú¬~±Oçú¥ñÈ~AŸ®?|gÏoö~pö\Ä+Åí›3 ÀesÑ> õŽ¸vp©‰ÖqËs—!J1á W§Ý1GiÓ±L®Ð³EšIÉ#¶"9"Z€>#ªÛh‡Z‡ Þ®/¼ž`ß&€yÔ¯ý&Uï3+¥ö‹ÝÚPtcôÕߟЈm@hÄÕ$4ÂÐ •† ¾W74FÆ$AŒ2ñý4Hi{R|‹’+ec¬æݐ׺þ0ªM¶§>úKÎg šºs= ÚC€­¶¸%“ëۇƒ(OV¶ +ëõ.õÚèµgÐIe/¢òú†¸ÕWs«êKîW¡UoŒd_Ì1+Ï#ß±GeXùŠÍÅÕ +ò.peW–Ìr< ádÞØÃDi ”.*]¦Nã»ÒÆcåãþöà XC_º[¥°|K´'s[p—ê°Â åâCȦÈZ×bÆúJ%³EÄ.#‹Êf)Y-:V©ni¦ÜfD±\º:|Z,3—Õ¸÷a² K׫¼*õû½¤Ä0»¯ª^|¤p±8 ¼È‹GŠb҃$uµ„$Í|¦k/LÇ.ë-$•Ñ$Øã?Ÿ„¤{ Ï 5w³îùô²CX(ÖJªÏ¦bàRËñõIãÝ[E©E¶%Tuïď"‡—ú ƒ>à–d÷$Br»¬C Æ9…øÝígØO +ê\ †pÉ/ó7æw$Z›ØçœEt’òoG®&¾¤\MºG¹%l3 .?üꄷÞÊ4ŠpQ¾º–l€œrÐÒz!ðŒ;´ê|‚UCw外ð¥€ih2¾…bæe‚ö­ÿ݋›«‡’œÄ– +x@dÄôàĎgð7Ò@ìµB† ñ­5¢ı4ˆÅüKˆUUˆèÄx´Ïð¼ÿÐîMÜZ|œoD S){oeú iÉ(+cLÖàYPs‡NuÙGíò qôwMdHL!¿zäÙÜQš³™´… Q#ÃÁÈWÙÍ  ª8›T Üæ|ç€â?%€ Äœ™! +JÒ.%ËEÍ$€j8}€Rø ˜éç(n ³>4ŠÊtʾÄN‘>³ã‹¾#÷qoqÃI„Ó× |úü–¾‹ï¦`šGh»\¤‡P·“Ð`Qh¤aep]€¦f=€–?!@Û ýñ ·•À109”˜ÊÖD›L¾gHjƒv¾E€¦†æ[€©ë¹¬æ ¢´‘lTdëhçy®é¿èòcxÁžek–m\îM¿({§`B” Ö«3 {œ +Ðoßlf ¿±F¿»¿Ûtð>À,œ`Žñ `k¥Àª­Àn ÀÞÛÀUË +ÀÑÙ§áu pjápΑ8·ï\»>́,†üüðKÞn,#ª*Їúo’.™ÜgÒÛ…©ý¢La1_*ø…²3êæÈ|Ú˜öÝùG‚nõ»]þàU_rpž·¸Õépçâ౬SóFþ›ð‹‰ +ð©àôÞB=oр`Ðn†Ë ºê)ÃúóCšF¦â†þ~ò)kdˆ{i*£³ ý$M@öÇ ¥ü'µwJ¤Â|Å='¥­ü­ƒþ˜!û¹W÷¾Ä€ÞÝ8ƒÛ†Ê‡7ë^oH@¯®Î‹Û_³Ñãzéæ‚ÏŸÕ³_ôÕ3µ{§»%OO"Ä'v£µßõ/ÒWÿšâÿÁ×^ Q2ôÚÞQfjs—†àüþ”W1ðPwqñn$cä¶!bì†ôßTÙ£p­vò¥óÙi$Õsóì班35vOAéÙ?±›R”„Ut~ü´ùýQ>{ÏÌ. hؒ÷Æ{ÞÚmäyç‡=<>t³÷ÞéK2;Ãå×DÍ0!~ML³·%Õz~T§÷P·Ft7ŽÎòf]zÇkmh]/øØHÏ>肧 ¨AIÚÔÊIXqkǏcãG9±éÌ0¹ƒzífFãdEµÛÌÌÕÒ7ò± ™åéÞôñim»&Ýd/ÝñlìKØuLç:`tߍŠQ0üÒ7Xû ÖÒWœ¢âðÝ6÷öwHÂúè|Ð õ¹u ·öµmiő'lñI·Ì"l¥yÝj3³s°âÍåԎ«ô©7Ý?Á´Î?¢Iw“ŸO»ºû"ÓCûo/¾äi9÷¯ï.¼ÚÆH‘É(Y_‡ºç‡%‚Õ,üA³}ϧo„ÂÓû©_Μ$c˜¿ô¦ºÝmñÙjCôÊ«eD\“ù¼s}͚w1FK·êCnß=!¹'7îsè æôh8«Øá»Xi‡ÑŠé‡¹ +3Mo­Ù(Ò6Ãyº:Kæã4w%(¨8:6h¥¥”Ü°íÁÄïqàSÅл­¨Ïß4¸Ay§ï^‡¾âv¾œ€‹'°í²Öq5zÓe. ’Ùø:ŠwÔsþíɇñ€}>"¡üCýÀ#ÿԆ‹)L áÂëÕ˜ÒYïµµªÚùªƒÇÇ èãüxâŸßçµOÙ¥sop`Þ=v8®x£÷›õ„ÍÊëÊOnә“gGƒÃô M÷ùÃݺމ“m+ÛӘy­€'tœµ€áxÚµzßÛL.EʋR B°·K>Ÿz öC.×ϾÒbŸÅªï»&Ñ»ŸL¦x]ÑKo]Å “¦@ûNw²üÝ|žv4‡ÚtŠÙdÕ6Ã=Ø.7…ïDàn+·¦sàús§]*ߜúºúl¬üã/.W<$ÍP/¯Æâú9sêÚvüläFpÝÑ6­¡9otJõ½¢¹ôé›}ìq©{÷"Ñÿ~70 ®R˜V:óΪÞ)^Vd{å_ùvùq•Ýí¨hºÕOÕuÚ .p°j0oyíÍ¡E +øÛîO܊Í(°l ·ÈâÃVÒ|‹ýÛŒÖµ]õï^ÜS4׈Íí¼€pÇxL‚ÂcBd/V.¡3hŸjŸd§vo¸íw=i…]esXuôÃéØnžO7wG]_.¿çÚßB3|-òf\"M7\·ò8³HY¿ŽåYêÔD™€ŒX†½ç›tȉ}ZxmÖÔg̦Ôg“ÔgZñ©O¿?§…ëaó¶«u|^ +•0óM?~Úümöë ‘´ØyÅjB]HÒ’Ê S«Èl”ý Žª"|êá‚MŽ9ÞU +_‡ž6×õJGä½Üô˜¥ÙæŠy@ё –‡ý*?st¸Ã*t֌¾š 5IV•'‹=rvë.H-€žœÔÚ»©u”9[ô×1\k•r _½Ië¸v“A½o}V·¦±ñQõÙ9&OÚGX*"$ØõM‰çë^㺠K±WђXz;2™Gk×f¸ã¹O¿ÂҘŽDrAK€¾§¦JëBeS퇜Ç©—+±jé ¢‰:D9áfø¶»¿eSš›Íkˆåà[ýºêø¶Á¯ˆòD_e_ZMÄX º#ñéakáø£—ßœíbó'™7^„‡‰+¤Wª«Zó˜ È2øaxz_§ß™EKV¥¦Ù¢¿Ó¥ +õ·¼!¹ÈßbR_”6dÉ`NDs£<‰Š=‚ðÖáXÇÑ&bí‹çbX˜ÔÏL÷\?³\¥~® ­ú¹x×Ï¥ÒÃøÊŒó|Šô àÞ±øÜ~Ùóo®ºY-C½Z/OZšsÞôSøEõtnh—¨ÂÚ®’Rdé¾ KûRB|wVû¸ÓëDxŠØñ~;`aå^?¿Ù\½7îUkwðøݎ]Ìy»ÆêÛMa6¯:š~šèhÐ Ñçî¼ü‹°ImlXé_\OÚL-Ó»úa+Ê0 yII8­œ +ó\\ *>4rĆ*Ç4Ü-ËXâÕëX—ÔXŒÈÜÙº¯ÎšuJÚµû jÇNki­ÑôŸÑpð|£"ǖ«“¨GWrÎDf3}ˆhÚchúB4af Áfï•ßT+D:ó‚s…(uWi%i=k݉¹юæ=kFC:Õ±ò‘Hv°SZ¾$%~‹yìm>µG+‹L^£9‚F G¥rU¨N[u¥ª  «šßT+d>ڌ]HgH À÷•ÕÔºWšÊ¦P©Ô(¢ÜêÔ2Z)øða×_Ãm—àv[Tà6éǎ<‡†°øáWϼ}ôG;·¥Çš¾;Êóüù3Y܊b6В#²V\U/¼~§¡Ú˜çª1®äÒA‚+¯T+•·G–yȗkÈIƒÀ†;íºã˜–ÎïÙªÔ§§Õâ=?C‹ƒEí[JáAmÑ4š^ NYhäv{ÐH»L¡çYBÏ!´ðopku×4űv!nÝl a¿xHlðFjöüˆ]Ð:ó¢áj|œ*šù.Ã]é™/ÞÓ]©È™ç*ôªäˆ ¼…»–‰ƒ¹‰A~=-L^Ý]¡]ž…¼ÌÁù9¸dóÚ\pÀå{<Í sMÿ€æh¦cŽÀe¼üî[ˮɪSK£—=qk;c?¾Ž•WaíIeoÖä®W@¥c„§Õ¡ë˜`(x㪕ÍgÃÆCE¾…éu\Ì/Ðɗ:ã¸Æwؼ¼E°ÒG¿k¹Ö“qrè¨=ŽÆi`Ûâ1C°¸XÏ0Ól¦,xl¸(X'ÊÞë҃ ~ `f0wŠ”ZEÚkýz4–çY¼+`ñÆaÆó×· v‘i`´ÑËüÇׅªlƒÉùª +½÷$\ˆO¹RîŸ+¹Ú¦WðƒŠfèþ8 þ¬ht +Û  ú"Cpˆb9Ÿ!$¢Ä~wHf×÷ àè_ˆ\QðÛ%ð;»É`ZR‡G4sÖäÜ0yò·ËÐ|ÅÓçó”ÖcpˆŸ\¯&'-©–b¦#°M;ö?:t'×& +⠀b›Ô?Pç"@9/  ‚ºP3­ PûÉà§Cß?S€Î«;€¦o)@+ÐNIÌ0í´ÛXtþdH(€õ²a;¬DÝ2\ïFw Jþp¿ gñudâCnE$K*®‹ks„l·ÃïD3Á؆Tô£ç-ßW¾¢÷-Wÿh¾?¬M ÏÐï¤0x-AŽ¦/&ÁÎË󴀝u€=,‡{4¾kÒ@æ¥ÀÞ2À¾"`ßÕE?ûOïåC}»PQÚÃu€ cîAµxý„ñ}a…ì¼rXJó….¤ÞÜoîÍÌ9»Æ?ôjÿßßm~y¾¿¢ýQðð›+ÄGê[€kNO72ûí•^¨Ò?J,€_vÆ"/ÿzWþ=Wv‡€P·Œ{†Þ+MÅùG„ü¿äÓA'MåÂ$CkŸáôüS¼!Ì7Ñ礤OÐj²ußïËzS¹'ϼmȶ}³nýö D½«“FÁµ®Æ_I5¯‹ >}íÎ>T¾žî¦ž‚JžMRǶ“°– ÿÿõR1À2tkåÓ ñ?u&ÎÃ4Éoužç¤È'uGÞïFB~nÖµ–¿î¾$R½à;_8õ'Uö®³Ò)(Éj’Zò7UVn?®ãåSoxPoƒx¿dwûÝF*¼¶{u@lÝbî[Nw[[aö›¤Y²þâ?6Ê´ÊäÓ=óœö‡ºIìl„HýÒKÇ×ZðYž/Òew + e’„åÉõøiMžGù8ùŠ)‡ȏŠ{ã1,ï¬w»ºÝËml[›µ©M·èñëKs¨¬©ÝÜZµko™zÄl)Ü.ïÅ'h ‹ 7áþI•\öÏ«/Ò4´¿&sš]Ì`WŸ  7ëÔ¯_:Y,~¦¦z#I ¥yœTùöA=cþÎJƒ­ d±m·O×#^¬©Íx½ +ªãýŠ=,NË[ܖÂùøÊB± ¸ƒû÷X·¹úú ³¥ S3xÆʱ]ì9Ó½U™O]dú˜$îš$íJå_HÓ¥ø51ütñ’0­Ç)ÈÒ£¼[æöpß.mk“ßÉë‹^'Ww«Î/Ãz±±øxeck®¦€;[Š€73â Þ(Å0¶ õxº7êËimCì&Ý*}šà;ûX?Ý{«jÄ>6 yÓ}&à,Cï«@&ÅëùQúCöÏÎd¢A7»¶:Ÿ{ïÁ"Vðbg=ªñú¢NË´ÕÚ-&xë:WÍ÷Ìx;Plƒ2u‹F}’4-j‚ï,nì×~ÕàÆTÒQ£€è˜{9aȌº¡ð\£‰pœŒÀÉs5Ô +¥$Xä30áAi°é—¸­<úƒ*k¯úûtyî»ËÙ?¨›Á)}©ËÊ­%{À‰7øoF×~µƒâ4ì­8x×YÈßÃZÌz-˜îãÚlÒíâ»±?•oQpTßaxiäC a—G¹ŽòºO µµÏ ‹½¥˜÷¥”ƒ‹5°_÷vÿ`ÁA¿ßÀÃ?O¼â[ﺮ{ 2`¼Ç£Ùóxýºì¾ñzҍ.ÅãH½×áQb8øôÜïݾ28.?•S8/FN܊—Êô`úæø:j8O›A˜+¹ß|èQñwÃRÝ?)xZqôÐ귗ۊ&Nuß»¾¨Þyq=&dï)ÖMŸríºÒq³èÄxz쨀 ´Êo—’¸í®#fæ"ý»Fð»:»¿ùáŠË/ø°œDïÕK÷³*Cãû2µÂÿCôøQÁSUk¶5 Ýïã…þħðhÕø«£÷|l¯žÀÒîx}ËuAäö]úîd³]¥a¹Z{qF©6,ó¢»=ÓEÜU×qNÐ©ÅM«›u´~ û2B,›†Çãï6ŠµØ»Õ_œÂh +o®ñó1oõxŒ¾ûÖFsÃ6{Õä®r$úË˜ëÝÛ#Å å¸Õ¸Ç~<½'èö\´M­´w7«ÊÙÍü黳ߑo§^£ÀV’¨p‹š}Æ´M+kÉzÔ*¶Åuùïmš0œ5Å85§™Óº­šù1sY^üRóŽÅD*­¤ëà>=OË°ãÞàȺ߽ٟ—1OÃd7¯~¸öŠ„4·ÁßM²ÎÁ¤úNýjLZÄSžÛYßÙÚô§“XÃFçjñYomFú$ה° lN{iÍTècÌç†jèú¢­¯ÖïPoúͽ^¡Ÿ€¶+œD 5͞†v? õH\¾>´z,ïg?ì°á®°0Fê},øJì>ûÎ÷p'Փóc¦£ïöh»ÙuQEDëôiðö­êêÖë:?žõ›cp5sÚ~f*«ýÊ,4Ӄ¡ïÒß¹Q%~êÍ‘Ó+‘kN®‹ièî"ª:l©ØÉ(=i·T((T•$·c¾ÓtÌI7þ‹õón€3—†o¡VÊMú—a·íÉWò«Cw`™¥ÜZÙDZçáµh¨SÍŠ[²)WN¢©²/ÃXDE׀sU_·ÔúHG 1֜®¶ÒjD÷ vúݳŠ3³T鍶 B™åjc°å˜Û +49e¡¯Ÿ& Y‹’>æí*}šYd5Aú-iR-G’|(Oþ`R%¦+yUËM/¯Íå—ís2át–ó·ìÖÒÙ¢Պ5Úë`Sö”² ©|̀M‰Ö‘–òÖ4çé™j" ]ÏcåÒ؎j~˜6îúcÙ`/ù½œúÄUií-}æCXšèWB7UYœù¾+jôg"BOç$,—TEX®H+Ãv”á1–ÑéëÙü®Kèæ&\lŸ7q ­vÕ‹-:Á­Ð:ÀM0Bs†‰¾!¹œ+ZíqÆÔ,šàß.4÷CÅlpæÊé[ï袆 eôb©¡õ¿ž”/®Žâì <Ä"…æ…彉 +æì$e¶y{íøª2ÜK|µ3¸«|u0óUgý0ß<÷ÀëÇqeGݹ¹µ“k 6·°¿Ë«Í|½]4Êèö£¹“ º)tÏ©6¸ CÊákÀˀ4V¤F¼hJyõܵäé‹E¯ ++’™ Í\kÇoÕþ…oAG€¯ž0„;xËÕo'“=Ü7ç–õ´ý–õô {eŒ4Ö3Éë‰JôEøï>K8÷¯{ÿqø¦Òn¶®'YøéÐƊä³ÞþñÞʵ]y6†’—#*IÓ&R“ò;ê+ۉzM…UWՄòÕ°øc¸|KYiÜöÔ^%ãÛß¡2殞¼ÎV½;VÂzwR¾Ô»Ó:Uïö÷v=¹ A=ÙQƒBX ž½3˜»ã¶cɱ¡è{Œ¦~z¹¤Þñï¢Â7ç–õ­ý™N_5¹5®äÒ^dÑl‚„yVˆr…á[àðTmàÕ¥ØĦÛÁÚÄrX?õ“¸î±ð®N¤ê½v 7Å“ƒIôLt¨•†¶ßm>(_ÚâèPè6Ñ!~ñÑG ÿ­ólTT ·ôo)%HÎY(fÅ,æœ0ëÿ´ûÜsæÎ|yØ {7%BñÖbÕâî?Û½*¬Ý~–øò-*WƒE€Y®b!OÃDG‘ŒÖ˜[E›.ÉÎÈa9G¾œVœÜþ½9ÎQöŒý¬°ÍuSdÅhi0Wùî2í^f”¾Ö¢ûXiHëëé’z—³ 5¢Ý,•^<•iX.9ÎÒ¾–w$Üõ(ÒÞË>iϺ­t´2mÿБÉå¹N¡‹ïRÞ+~)zZöÙ¤_ }ŸÿdUù£>eðŠ/ +¡ŽÜ¡4Û±Rn|aTiø ûÝ   ÷QŸ\Ž¡F+E¦¬VÙ¤²ÒÐ''·Stzh—D<÷{Ýþª{ °ðùÆ×T@ãáþYÀÉz¥…íðÌ +«l¶Ëllœ”ò œ$ ­"`ꇪÐqûÅq-¹'oj†ÂPÈ/á5Û7HAÌKô‰ÁÏvÍø™•zãõ™êÒ5Å+±˜p"¨„3_ç,^¼Uœ2é¶Ï˜E¬:i71ÖÙs¾Î Í꽈/nU•«Ï*rçZ3¤›Xßι㞅ÜÁ¾ŠÊ"Ôú¡±¬¶e‡ºþfѝv+2-»Ü º:"UåqC$„#?üNí>ØÈF/t¾Õ;‘è0·Ãӎý”kÆ«kN,žèÎ~Uu´}T©û<òà[*ÒKV6Ò»D»ðÛ^ÎáB%°¹è!p¦H)Ð$3(Aö”!XÛ^!»÷V!»^¡ñ|߂Æý}TãjÖ*´gˎǵ¯ÖÖwU+¿ª—%­5ìÓ?É\(…l–½ä»ozè£wÒëö.8=ÉÑ뺵EŒZý [«ÖΆ£OŠ +M)Œ†œ½*AH-ÌgÜ$Èb­s#³–¹oɑ ïÍ-Øé—¨|Š `ÆÀL»ÛLEݦªÒ€qÀxt)…Y/÷+ÇyZå¶+)•²å45K?–Ò›Ü`ÒçÄà~$¸fWFéÝΐ~ÿöi8SlßÑۀ¸ ùÂö CÞöžÅ»áìMþ Ø­ RTs) `o˜šÂwRlk€½‹CÀAËà`3ý½Ç‰ì3 +{b)ÎgÀ®úß׺6.§«ãKØ1Ú§Â`î3Ór·ðYKå<¥²¶ÚãtMò‘çÎ ÃM ~Œb§‘E{Lû€‹ò„¼Þ㞩dûwÀ*/À½PŠä+?>GÒ),ðÜļSx-Àû—)àƒÂ)Å|±!>äˀ·Îé†BûxEa¯²•Óà™d^ĕƹ‹b×\ÖȪv„¯-;’g Ìx¥3/‘È¥S`±3´$Ѿ¤cðdpF ÌnAàXÊ|€@ed I’@(ôY ”ÊmÝÂxXÂêáÚX¦ø|•[ f»!^Oq®ðÔQTÂ+.áÎR¬öÞ)), Fõ–ÔRbÛ­ˆTu°½þÕ¦¼7oà|¾*£ÆyÏÁ®[f²¥-Lþ«C[ˆõ ÄA†â‚æSØ_+rÛâsã !Ø|Hîb¤ž´ÒlõÒÜ €tx€tìE@z•@z ¹·<>õ¯ +Ȟ¤hŸþÞݚ%ÁžjÚ®2ŠýAÄuš§Œ‰oL *ƒ<ìE²ž¥‡3ù¯íÔҟ¶ý¯à›¹çLÈj9ü›¹Õ­y´kþIžP°Ê (Aæ”ÅÊIšK?ˆÊMc •PóÔb®˜bØjˆ®€Ú*%÷ ±ÜÛ(:Ÿ üç9b +7ö[ܵ¹Ù@ßÃ0„}çfêoÊüÛ¢P°ÿʽ?Û±w,ÿÅWøUdý¿ªïøœ6âÊ-FÔ@+¾ž@[5q óÚ/êX7žu çû  ½Ð[¢œâUzœÞRôq6-¿ÇÆýÿ’Oøʧ&bý2ðoLïòúdßà£oô>%®ß9…w¤òH/ëã[º®…‡z ¯°y%;„s©‹s±xøTÊo7ǁ±O»˜ÂiÇþÎ,*Ûð³Ž6Uè8Z}~¿æ× ¶Jʎ¶’-÷ÿ‡´My,¥?ÚéÇø»³Ö¾qS×5Ç.;I+%õ—Ü)!Tf¼ dlÌl>nб9JX}$]V›á­#¾RTàaWu ñG‡þ§©F¼{_*ew|º•Ý©ï¶f$ïWJ]—êÿ,Œ#Î­ GϜ-LýON™¬ 9cBÎr…q5»ñ1Ìqƒ$*£¤š«"Vü>ޚÊpؽÙàÙ©mƳ—ôãüòÝÏN2xÏEÒÛ ²d£î¢/»ñ<§ø$ÿâ×Ä;¢—„ïm—‡O°lvZ»µìb‡æÜ:ûßïfºÐŒá¤”Qçã*bíãc^GI9|ou7;T d—÷ӏõ’Ð·Þ ¥7µFÏýÎô\¸qÐ Ðc­³.>;r‡ÛUVZGÇfåñ×ÝWl%ݎՊtºÕ’ÞåqŠÞü‡æmT›=²÷Å'6íd?kJ‹•¼kó‚{³¦þS3ÇUèb’péoÕS}0÷Ý~¬žÆ½i~ŸBãË®À—ïkD;kÿríëË3X¼A»JçèXÏáQƒç˜V)RKº›Fó6ëùM-·¬5è×?wyYg‹{2J\m†K¥ÚLXõk¸ŽkèxÿpÙïÜ}{—á¥?-žù nnp}x_éÜàÅf¤~ÜÉ=”Y]¼t-w¨~&j³qf5)zÖºÔ¸uK>sûfÏR’¦ž5k¾&Bõq±‚Õmqò}ammÖÙ*5Oƒíêr©WªQîTʝý¢BkÚ­¼C\™ §aé,3½RóNöK-ˆüð£7üQÝM×v.©›†Ûwº¶Ü]µ[Tg‹e±N¹„±?¹ûõ‘[íÉÇjöNX±ñNO#ã¨Ýº½0Fµ9nÍjÞ&\WWt¸¯ýKekô:ŽAùPØ¡env£K纤–Ä$tÎ<ª…*LÄž_> AùN¾>Ü ¬J5Juþ ˔ÚûE©ö\ŒsÝUÜÎvš}Ôz:¬r#Êͧ(gš}‡EŽ’uø‹5 òU’’½J¥T+ŒEåú¨ûµó”’l7.InwÞØõ&T›ëCñ)Þ®E£óyWËÖ2`ý©85|熄ÞÂõ»^À>6vîdÝuÜ,¸¥2ÔHÁ¶]ŠF£6Âäpn–à;¾f2X­SK¿Ã–Nù|£p°Úâ³5l_úTɑ —U›,%òX’3½|¨1C·ø<îËżpjñøÞ +i¿âOèÔwvå-6ÂÞ Ú¥›»~´¿·4¿“Χd§z‰<û¤›vq涰̼ +—æ[/\Zíj¡- ›ÿbùÆë—q îMz+cZ‰”£˜oÀa–­n.(Rárî»,L6—’ÜØ|Oèâ˞§u¦¿¥‚Bò–ü™’ËûhŸv½"¦”<|m×Ý2eGξæõtD1vØ÷le7­ÍÁÓn¦Ð®)pAázœuÿ@–¥—ܪù¦Ž±ùVFwsøì|ok¦9̅)ÌÆ¿X8°u2=êö…RÓ*œõ‰,˜ò¹¶Ã‡ žÅáÆ>ã¾r÷g±øñŠ5q7g‹vi«’–TӖaŸÑ¾c7—óïø¦p%Vé¹>¢‚ÒÍ ¬Þ‹˜XúÒޘ#¢|6Í똙.Gå'îÐÈÃË{hÌ[¥1˜³á+¤b¾ +×ÿÅ3Ôë`ò: ÚR úȵÔJ}Pá3[Ì3—áݟû¹“f·g·üZ=n;v‹Ùå +×Á‡-¨™¬dõÌ° DrÌQ ¦…;U3siEùI{>Ì#ðyn̹½á7Šß’&l1=œÐ²N:m_Û¡PGÛ±»£V9¯9­’„^ŠUí/֓ꔙÏý Ó﷞}P+‘–RºõY²h¸Œï÷Í«»½ÍN½ilmIU¿O + jž¿[ýM™ºŠ›V=bó“¤+åx—7ÐÑ1üÙ'40«ékÞêêdäÇÚ®0ßhU8s՘Cˆ¨ÇúAPyÓU°ï(ÉÄÝ*É´D+ɌùZ{Óe½ö/ÆÉ0:ö(Äï5ãAϯ²,)‡ƒÑ‹ËxdL\~èï +7û³²ØóhÆòóšŸê·WI½Fᄾö(V/qEÛµÜß{Ø«RÃ՘[\RÓ¤©6cŒ'†¤ÊmÍ~‰ÛZú˜«@à¶6®q[¥¤ˆBž(wÃ~‘ó–-p+4*§Û¼P¯ ¼G«Ü7hÆVtúiŽÒÑ rîR«MÁLñüPÚKéí7·’™Œq"/Ÿ¢}¿f…¹ŸÁãX!·6e~5M>”g>OÜï5n;—û\Åo,8Kö°É§`±õòNbyÕ)2ççcȜ_§'s>Ïd–çóËcù"[÷ƒ°»¿åæÙ‹ª—ۧР¼Ê:gãXoóñÈ{ì¨Õ³ÂRIGéSـõ‘dñÊTD î›g#ø5ýÀ¯Îö•GíOZs„«L·$ÇÔ2{ä8­Ÿm‡åG½2“X§6AԄ‘f#}ó^ºË7Z½dÓãs™ô©g§|¥Õ]M¢ÕéÝ¥»õí:éÎ :â`5­íe¥¤_¥¼O,OŒ}Ïˆ•Ù^ŸqU‰E—r3ž‰“1üÛuēË낫Šï-{ìfNlÃUžL²42LT sŒœÖNôízø>X¡»ÝŒ™ÖJb@½Ðf“,÷#* +; +ƒ7ï)†,Ôb›„x©MBBîDB"Á“…âÐ& æÒ'ãá)ˆ ؊«u¿V.Nú7Ý=l‡t¡?Áùùqòø^7ÇÜK|-YæL +Ę«ûVèô§ô=¨/éÞßQ¯öêB •ë‹Ê?ˆ‰ ÇAȓ6>ÒIhsv‰t S%<µÜ'Ðç~…/‡Ú/š›¯ÊÙ¼‰mÒî +ë­-¶éOhlÓàL_½~‘æi…˜+X!¯H²¬U˜Vµ õP“Öú$ƒ ´Q£¹à©¿"æ˜u rQ冯äþ/Þ×Nôž¶õy «`¾‰ÑëQ1w(½£\6§9î°IÐsCGіpÒPñT‘k—\"׃£âl¥£ÍGÎýáK|›sß«¦wá¹Q(¹^-ןJw7=‹3åµå˅â’m®23Z_ø#Ò¡>}=ú4ð ‹  úX¡£« ­«WIžh;X×¹dqي•Ç]V/¾õ”Á©û½{ +Åt`Ï5oM÷;ç99á/ånÃ\£Zí!w±:_•Æ2ÝmŠcçOÙ š,E—„ +×®AÄÊÎ4¦”u_õnfižW™bÖ~fðéûûi@émۀ½: ”Ü. ´P`CZ +«PR½¦OIÇîibÎü­s+zd¼’9W_'úš[r:8¯ð´ÂšçšÒg‚Ü_q ›“è{ +@ð ºÊ¬ly!æÂlýB*Xõ èõ ôgR”´Iè«ÕNq^úVNåÎq€Þo<@σ> ÒÐCFt³b¦˜ûE/¿zšÛì=‚\cKžiµ£fџBÆW™Á“éÎ^ +êzG|³yìrÍOeô=d[Åã<»`â%ؕÝ5`ùmŠê 0Å0O,’ÇSüÞY X±R„å×>`¹â°< R,%À +¥tM›Ù>›Ýª€¹+Å͆_a3uG9'®é+KUKÐ-+°.P¡³ +>”ƒo/€o‡µkNª?NHê`(çì³xå¹쥱8G`·üpbœçWü°€kjŠ‘ ¸˜h¤h7ÆO)fà&®¸)ù \w»\¯•þy]Q×@ÓßoC‚µÛùóêÊ0sEÎÒìµêâ?ë6¾«å@N®´_ˆ ÄäÕηLù&€GZx¼Ûú…2ðîü“~ð=üÌa¿ïK€¿?L Ðveß‚ª-€à$w ¸%i¥8§üáy‚ Œë’4w4ûÜ2ñáú›­)…“-ùlFçC•èB±ÁTr!sJKÏ!ò@ L©dAƒ¼¾ÿêÐi „uˆþERÏá3!(d æ ˆA1ý|±Ä%þSnÅW4RÛ‰}€Ä«\Š«¤ül$³q’ÄÒ)Žd§•â½´fɼ­Ÿ'IMÉÖ¡¢À‡1 •<±­,”\çñH²^TèuhÿLq‘cÄØâ_Í÷‡J[Rg¨þ•€oÐ?±RTr˜t€[3 ®g (¦¨¥x¯%́5~QÇJ[UR\Ë@©Øƒ›u¾ +]‡êàEvÄMRh°ýN³La³­E'¤€Œû{xzˆ9eȶzŸ^¶,ý€ð'ዴw¬Uÿ‘OYøüZ¾–Ÿƒ æ<¬Rº;&ºùit%#æë~¸0=r“ð#ìx–¦ÙËI]ÜîÇ~{>åKæ`Nð![¿cûôŠ¡v ùÎmÃ÷LØ쬍¶a¦{kÝ@_ÅUR͕´+M–]Ž|-Õó‚[<#ÒZ äì×5ô[þÁwõÿ’OÚô}š»×ðÔd’£êIç$_6O7»X¹zÈ֔æn!mø|ô7Up­öv²æçÛÅ*ÂVßykË[i¾[v©íiñ¬mÿÇ-{ƒæÙîŸ9oŒ›.,UŸbÓz0Y{¹Á„\íïã]IÇÇUʤþþ—vzÃ*÷ïSÜsbp×£±ì_÷ÎÑymà m˜Ç×üŒâ–·’Ï*0æŸÆ½0·.wo6Uîá é_*SÿsªO±øMJн7Þy÷ѸŠ¡óøXÂ71¿ӈË?’j« »Òž<{‚=0ÞÏQÿWNÿqÉþUöO+ûŸÛ盇S7«NvXD W‰cöÏr.ž[çë|æÜÞû©ÿÎ\'k‹øŽÖÆ;ƒãc1‹Åü6K’ +ɏ¤#& »¢Õ c +™îÿ!ýØP+}ëF½i¡>è!³Ñ¼ä¶ûκ?;%ªB´wuÚmWùM¿Í\ØutlS__çoùÃïX^ÉFq4Çá†ҥŀ"éB­:ãMyqÃ+£ˆbÛÃ.'ŒÏV~ÑÿtµmßzåO½©Y¸õÜLðê.œb¦ 5¤³ÊßÉ~Þ¤Ú»r›oWé±ëK3ⓓßJÚx½%=´~³kTg¼NyXÃêŸæÖã ÞJ:ÿÅ ›\’ã`¦çז¨Ì\³¡wïÛuŽ’fÏƄïÇJGéMQ¡@ ³ö&µ¹ÚvÚUò0ŒŽÕó4âOçe+i>¶-éz=4oÝÌ¥©>ß÷Æs˜û4ò®ÇOÔ H(Ö¦A'_C6«ïĘꢒkU±£7­”„ý¥B^Ç|…¼Ény×­VÿŹmגõb³œ®£Ë})ÀsNöÜý1=@RîK‰ŽŠl% VhÞڂÞTÚ÷õTA:«Ö¥Z½ 7¢zö>è×\½;ª!ï鬤G Š“É¡RªÞÒ¾Lg>åê(Ÿ+³á€/5vÇ|xљR½[½â½”Û{J†*öìq¡¨3P%xîßhýßòO¯ÇEæéµG׋[èÃ/˜ïЫ‰Ä!öjµÛ‹GKžwߍ!¤ƒúX¯µ™Õä«ËjO«â¯¥])›› BgîÕr͹7Ë‹vKÍ&:,‰"û5*‡íŽ° +µp(öÕ[Q–Ù`¸yQA†Tü>œ¶½y¦µõ¼]‹òr=ÂrWºü‹u`›I•›7ÙÕÝlë¦ù,ºP}ò©~KŽÚ¼{9Ö¼Óò\]^‡·Jy1åÚe…•š^³*ëw¾ø(nQ?Åà]«™ˆÍ ™]߁¼‘ÏÚ Ïύ÷îªu¹»¡,"ζW朊wù¾ÖÍ>$ùº]’¹]r6ï´ôB¼±¹êbÔ=‘•.ÕôôæK{’uÔ¸g*»3t-7To_Jøë²$QçC¨r‡KÑ°ŸÀrŸˆ?9c_;ï´TÑ›ß Íó»¾å®ÑŠç†ËNÉÙýºSÙÎÛöQ=ìú+·,$¦x,DDïcÝ:Òêj¶niè©l>WÁØDAÖÌۘ’¢âþ‹ï³µ" +¦›^”Ú"«õY'Â+û^ãSj3äø*¼·E çA!«®|•ö^@HwÝñ?.ùl N5‘ö1í)íFy§’Ã._ˆê7§ HhuÇÌ·€²4Û蘃Celæë«m~ à{¾0sy¨|•c†û| t˜¼ t5 tÍ8cö¤ÖŽ{ÅØ-¶ôh"׈†‹—®i‘U4ËÊɟ:ßûWDžwƒO'Î,íïm!Z_ mèö±î>@¬F‘æ«ÄræP.(&è¹ùüX¯:ùÂ{³pÝ0<òÓ7лµÔ‹zë¬XÒ6I]ÐÊÑû{Ð4Únw5ډîêÕ¸ë‚F»‰ýCÜþˆÃÎÁCýÆÄ ¥J]As¡þ¼?ý¹‘9z„«.Ú8Û§¹6(´KòÌêÕؕù:ËÓ´‚{~<-}oyÛí!Æl9$ ¯yâõåõ$ëÅ.Èë„F¹Úu+ZyÙm«ñ8Qk7fÿ{¢¯œk «´¸~A?b¤H€:+RbRDVŠnºáÚ°†ïéõûÄ£Ý*ž¼:F’Béú^"Ád3~x¡µ=8u1»(\ýÂÈzX¯ž9BOq~Blfy¸rÚÞñ~ÒW"¸ëĄÚÖQP­‚ؤz­!âûsïæÙÖޖ”ÝÜꗨ¯?Í̜z<|­õÜ³<ÖIà͵J¹¹S‡^¢òüð‘ÇV@iEWT¾Þ¤Ü™Ó‚¬ú¦.=ù¶+õ“ME2ÆTOü”£•ӟ»h=«¸˜|t1;ìcA…©e¯…iÁNWAºzŒ›?ô¿¹ÍO`ەc°àŠ±fC^ ÓovRtvÖӏçf–Ý÷E¦ÜÑÃÝ֘2¹¥"ÅÊAîBú7HSzzúCäŒdœG˜øim1.ÀŠX€”‚˜Ý7K´¶o ®!Ïä_øÅFÈ¥X«|P±*<Π>¨qXŠYºÎÛübvÉ÷È5¦vîÛ§•#»ÄÓ¡¹Õw+t+Ì֌K¥™±{=\БzŒ¶ %Òç]ù¶ÚŽ¤çn>•òìv-~N£XßWÊra:µÁ­¶(eç"¿8=ò|0¿§[µ&·!ï®´/œ¸Ò Õ¯Êì>Ÿ SfìÞ<#ìÞ*ÊÕ?tŽñ­õ³Ä—º}öƒö;ãîõb ŽÈ6ïÖä©N!vWmDׯó^‘½V]zIa$Í鉅¡ 3¢¾ÜíhÇ/™É™ž×'‘,·1%œ+ž£¶#ÝW®.[Ӕ:˾z#æ´ÂL3lg˜f‰‘ZôåàÁ‘é@ŒÈÒ"Ót=ý‡¶¬7êµÒh’ó1Jy¥ÃØòr{1ÇX²1‚35U¢#ß½QS¦'¼h£X]ðD¦Ë/;ä€'iʕcÍÑxøµ²ûËèÎÖÚ;ÀrÊeÎÏ0ͅ¯0b0²é«˜©Òí«Ù§•ÎrC=4ùMõÑGé+×¥ô53¤ô1ý¡úàÌS‘Ö~h½¬|­rr½MOßa”Ë&íOAÏô“¼GÅkºÞ'Š½;’iUš"̒5~ÖenK'{0Ž=–‹#æ\ƖŒx wô5EÑÞÒÊgQxGP};+Pm™äûÐÿØÉQýÝ!-Á[’™ËåAL&5š˜L)›pÜ]pô˘ô[,™9œÕš6 +*åv‘Ñü對;¢\þXÄ?ÅZ´VÏÈf"½õkW´wa‹_å?ß˓£Ý2sN¢}ƒ¢­z>Õ?&”ÑZ¯Èt;£;v#­YY¯š#¦¹)K8«§F ‘áã yÔÂýGn†cýö[ç +q#'…#§á·äÀÂ;Iakª"§;J½Xn‡á›>*^ybc…‡®¼ósœ?ét«°R®Áx"eVçžàk~ÄUÚ·:“ð +õì±e2N‡ldöÆvWcŠs|±l|Ku<(NÏ8NØú†CX©›'1J‹¤Üîu,äª+µ†žÈÎmì‰SŠm|EE.ؽŽ\ˆl‚ +æG-Fú¡ZKh¿h' É97ˆœ5²à_v÷ªŒ4>ûÍÁ» §¢Óz x²iµYþqkҚTÉø—ñ¥zªaeaÓÊíÛËN®¦\F9Áèi!ïÐfà&¨ˆwßÈe³G‘v‡âR4òˆ¢&ßç7ðýeôáÞð°‡uˇ`½S ×}X^ÁN W֑÷ܬ\î¸[×=V°;i‡m:•ëK¯ôž'Uªj)¦Û3۝‡l£#uèîg×"Ǟû-9ˆ\T0:è•PñP®#£ÙF”O¯?âåî—^kØ ñcŠà ½CÕ/4d ¬ +e. ?ë(Ç( ?­ef>¸¾2¾è3`Õ¹:™Ün3ÊøÔîkÍø0‹§¸ÐêX÷(Þyë㍐<֘<µFîv–E|#¢|yÎU_‡˜¾/ø•¡Öm"×*41úy¯¡’]+ÃO¿Ö€âR­“Öì^Ö劣̢UþJª™@êm2ØmsëxòM#)š ?ÀJQ­ +`ÓÛÇwv+Èírwr¶{r®‘)B€%OÓ¾-Ú¬9mÕƒÂçoåž]|§`IPü‘Ì™+±P†Æ­{Ó-´Qܛð`Þ«Ccle–ž×e’èê&Sg)†@g_  !í“bˆ†¤%'ÅçÛCé,*o@ç2bŠY PŸ mþŅRêyA´1ÁXë8BåeЇ‡¶÷Ó¡S'B½ Ïå> ß³IŠý0´ ¯ctŸ).0`Ië€)’aŠ~0¡¸Kq…Sj€±óuÀ(Ÿ%`Ô$ý ¶ÿ³(2ì;pÚa5oÛMÁ Ùû)^¢o®ßg:/y{b)\7‡Y äá>g°E &ÙùÓƒ]á5,ô–fg) +kÀ*Ñ°ö"lùùøéÐ!ØIìö&öfþ¸9ȧH9ûhc€}Ò /¬ ØÓ*ý?έtÝÚsSì¶> ÌüÊ0õzµÉٗ žUwúÕÇ¿}±BË ÆÃï#2€*;8{–¶YÜIÒmJ À ‹ à‚d¸Æs¸!vÜÒúZ‘[Ÿ?VdžËâ€× ðÞH|Ÿ?v¿ –)ϟ@¼ XÀ¯˜tÛê=|<¼¾­Ó€ï7EÜûãßnPº,ÇG‡¨÷gúø&ýH˜é=‘! nЬw¸þW‡vë7ÀOçvs;¿}üãB.0Y ”œ¢> „õU…Ѐˆ— æïµ'> ¶ºcUâ8“~ãý +ˆ“vˆS-]×݁Ø3¾ê`žrdGÕ9ÏCВ؛”p”[(ì4kbÈ»šA`ŸÃfM~­ÐXæ¯ý¯àûóÿp¤9 >Eþ¯Öú‹¨,¿¶ u!H»BÈäº䒵rt½yÜ"€¼U¬¯6o»#ïƒtÝÃH×=Î ?õX»6‚PFÂ¡Ë öÙ¤mÑðà*¡ÆjÉÂ([d¾ {8›õm̟&LfÚ_³ñOóý7lâ_õ÷ߨa/©enuJf@íØÇ¿ï‘#giQV¨~å •¥)Ð:ð+Å9]=V€6cG@ëU×ÿxcÆÓßÌýŸ«w§<Ÿ&ï¦è7žO+3zSnõȉÃmA¿“ëš<®dôø\*÷ç×p™õg.áG7✲ìYš~„ÓÍÃԓºÂòÇgÈ;Gc§†‡˜µêû©h}ß֚î°Áö´-eZôfçf +›*ª—ÿ“ˆð}‰ØòVÿä ü´I4ó3Êþ ÈkÞÐîH©jß°ZTº’­A+9jQÿe‚øÔEÜùq€k«ô¦ÀnÙ:{Ü; •ì2~Û®uðܒÃ×gSͼ¡õÑÍ|õ´5¿„éUDÐÒ²ËÐÆâÙ0ýÅ@˜EóOGÛέÈͳÒ2›šî_¸Mž!Vúß.Yk¶Ì^ÃS.“Ô+øt+ô‰ã ×ù&õ>á\ß;§Va>%w̑`ÍÏ>啴Jj¬²Ïê±³°·ÁüÓLâ¹uMfól糞9ÏÏ~º0‘Ë›¯I ѐñ.èq_ëñ±"Ucþ”Ùþd»f Œ"q‚Ž¤kùƒï?ÿmåÝY±×„ï×Gc©nvXTZ®ºYE(t^v ô¹04·.læÜßôÔŸ¹ÉÚ:KrzÖþHªsÌ,¯v|,¾ý˜ß¾KܲÒ) »"=ªW{>¨å]ÿ3Þúp†zSGä{.ŠÖº‹â`Ñ]„Øå?.Ùï?ÿmâW‡þF!ìxF8wêÇ:„ö­7Nô³#–I Vè!SMí¨–﬋…¯üÐ!·¥r{W™¶ÛÌñGÇ&¿‹økåي´,ے^×jó6²ãŸ7öº–7ýµò,*³ÍN³+‹ù1§Xÿ"ƍœ'»Ì[ ČُUø; 7Íçª=(ín‹ƒÎÚW&r­/ÛUJÙ´™½yˆœ~Žø³wo%­ò»%Ý*Ùæ­ÛÉ5Õ׈n<‡g¹‘Ïf¬zìra½€6;µiq?¯!;ùV]Ôدɢpq±ðÙV;ߚ?$G%³þµ2=—Z|ôrÄP=JÙ¾u?BÝ [‚;%4ÀÛU¢ÄE ¦¤´’Fdµ¤ËÀov•¸Üxö§†ñ‰£ú'^UŽz\8Æõìl7­M½ÛªæbÙ}uQʞ«Ø{TÖµù¡æMOu9ÅÄøa-º¯Þø–q}ûxfÚµ[#Óì=ª—úx7ÛÖ¡“·®¹Ü&ý&æ›JIžýÐ媷}”ŽçTd£Ʉ²§JÅîÙЊZË·‚—T÷‚|·R €;ªù…å$ò¡âyè¹·ÜÒC»öÙ-¢“Œ‹Ÿ Æ)KżCÝ.U{?›®íýaðó@ÕXZTý‡ù¤!¶†ýÞËèTúÙ4ÊÏwÍwOÇJEÍ-Ë\Æ¥3dMJ§žµÛ¿)öªê96ÕGÉY<‰0Fº´7[LÏk$ß^À]^Žy·Ø~:.¡b¡S5û€§7§Ú¦>)œéù®Ð<æžÖ5âVh–²-WÌGU^™}BStűüär®WûÈ´©µºî«-¢Æ·äøé»a—êϋFó3 ,µÔÌcuàOðêěӥ¥»âK{—ˆ»Wg[Xz¶‡íƒwÇí:1…s„‹…–,hÖµ'[VGw}ó±Šjf?Üõòï;ò}R˜õÂ$ŸÍí c²Vɾ(í±8½Œ¸,ŸBˆe–,wöZiÄ×Z©ž©{¨µ3ےø©·D}wmC-—ô–Mg»ÚôìÃmóU9l^», ­ákoݲ ±:;áe>Y%köOvÎ4†M:gš|ޚŒUcŠ,-Ã9¢4å¦d±Žm?m] Ò{ÿkǨ»‘e«»µ8T«eü•bü}~“.÷¼ºÛ܅a~¼£‹?kˇKmgs ìÜhíá‹ãØÙ+ZÏn¬fÍB²Ó+éeF–zåºæÀ1ÇùÏÂ[¦eCq—Ïnډ1mo^òØfôEÿú=Óô SÚzC Z©¬k¥´]µÚŸUT6ÀûÊ ¯®•Æåó”/N@ʱä6:ïÈmnÿÛ|‘JÑãå6ÖäúVð[º\ª´|‚ŠéÀ8ñsRý«C;µv7.\V÷ŽÕÓìº9į%(Ûj¾Þú 7Þöô%të¸w]hžØk¥D¹¨{Yy¨Õ»ŸQÙ^UNéÉ¢«­(_¢œ)·e;”hّzuü;OZÒùÆU|O15ÄáÄi‰Ã]-Œí BÎV|C6×#(ÊkŒÏ[>ëÃl0¡•¯¿˜_ÚbßY½Û¦cš&v‡NÑ@?Ôñ½UÓʜõ­©ûQØW¹l}¢œ¦£•"¢£|Yn¹Ý|?¥û-›‘z]“t7äÄ7;×Åáéí‰æÈnŠk3&”–ö~ƒ +p¿ òó|¶ÎÏÍÜY€‡L€G¹¯9é·ìԖK»î]¦Ô‘làÏëôÙ©›ØÒzÄìÐ4_í¶1‡}ù ‹Zy–uÕÚ +«(Íí§._™O$+Md =Df"é~)¾ÿ ŽúE4£¯Ê!f7D˜ˆ%8GàíÜáçU¸ÆûZsÌçÞàÄ­VM˜ K¨Ì‘Ԣʑôöȅ•šâÀp«IÚŠÛf¡ªk&44êã…áùh·Ú·…ùÐ¯G2v¤‡ü¤¢Ñ3ÒWÎ͵#_;‹¢ô ʒuqdO;bf>¿› +pr[ñó6rà}Û¸ó\Íð}$¸Õ¸pà[™Ÿ—Ù]úÕ²•íøë¹e™®’eŽÚFdêï ÄÔ?•sÌ«é†FŸþ¡õX(f•ªTÑj¼Þne·:ÔþtnfµËÀÀ%Ò¹RVZÍēU§aKFຢU.„‚Ó×¾A3b-ޏK=n •F\8ëÎ9²¶Û±;•ÿNÑȱÌzÇ1Ç2f0 ¥2üãÚ£“½¡£àþ¡e¢ÌQ·P·=¿¡eꓥ#Û¡~HwÓüà´YNhœÍæå4ÐÎÁ2’Æ, 7mg¼›JâYeY,<1´‚0U ‹_øxÀ­ÃWȑ»W•ÝõØ6˼…s¦L#Œ6Œ@NOt²K¾#i:êQPŠ*MËÞQ£îãSÝu§MimbE¾”á‹<9†Ìö™&Krðžòœä g¶ÒK·:NøØ¡ý´#Óߛ9˜ص×Wñù›m'ßVR9­®ª®àÚTÇ¹Mž£¤¥Ã²î,`§M…š—&]ï]Zî¢1uwµ%ÕCƒ=¥-»WòÕ¼dÈ¡„㤙-I$˜îbìñ ÂÎMf”è¿;”<(|Ön;ø¬3˜ÐΧØᄝMˆ:¶ji¿hw·Öï-=Õ~’¹¶{z=å­šÒ`—- ¨-;܆»Xlì噦Ö,ÐíbÓ§zïkç¡tµW'‡ƒ^Dšùå€Ì€Ë”oñ aW´33Õ>{îs¸7Äy᥌Ïm½ûp±‹çæí[Õ7K,ä_Œ¸°ßƒ–Û¶‹P®b/éƒà:zX4Jh½˜¢<Ñ:"牤8H«¶ çùàŠò‹ u5•/ÂMúE³Øòé|5¡u²ý£—_Æ\Oz­ZMa6HÊ?Ú`=¦yÛØԣ除Ådt|¾>˜Øºz¹· r•óµ’c"¸…e®Öïæågí ’x›‰0蓢H Òz£À·¶À]eуÓrx—âöâBÏf]ž-¯«k÷œâÁ]€cák À°õºŽ.Æro4NÝOäœëI©Þ⋗]…å! Uv搣«W F&•¨¾†6ZõMÃïÀ‘«0ŶßÙGÖZú2Eï½¤Ó Üé”ï•…lü^²…Xnf¡Ân™™ÁÎ+ãÎ?\ÆÌÃÌôµßd¦o푅¸!\„)ŠuÄRÿ;’þ¥²è[.Ú¨â`6‘Þu¸/Ì]§Å1ô¢Jßd!$?ÍÙ÷Iªç`¥øm¡'½“Ö>ÙJz£2‹~Ê•Jv¼í·²veÕÏ̎‡IÆk›LNT¾ž[PìT Ô- M×Sœ*€ÐS@ðÌ=EÂB€ †+@TºŽ,fi慾‰V·‚¢âã©8Y½¤Øæ=ëÝ×:€n '@7³, ‹Žaų7‘ÇY2«F vû¥²ð´\^1Êv;%2?ÂvᴏFC¹éËw’,}†­ QÓ€>s ÀäÌ`ôZ'Åx˜Úk˜>µÌ<¿Ì!Jó8¾ËÈ(`՘¬†Y):5Àêô$Åæ +X£Í6ÐVÄÆ?˜ØÞK®dÀB¢oΌ ¥sàÉÃ}ö! êÄܸڎœ6¶Kœê;s´ÝM&ðH쎳ó…<LoÜû«CÛlº›v~ر;ÿ+ý‚éöç ƟgÀ‰é5ÂýàšƒtÝ*Kî]џ{€ÇŠÀã`bð<ȀÏòõït4Ïîaˀ{â՟yû.ú+äÃ&—ü·‡¦ÆÖ8ÁË[ø€v¢ú¶Þü&‹«»Õuèaö¸—t<ë\þ«;໣àwÛàïÙ,( ÿ'vâ,acÚ@ûÚÏڛÉÇ)ng f£!Ã"LtS¼ <{8т„×®¦µ^NšÆ7ü—»ýË!H÷òBoGåíÌ-KXõäo›~-¹ß?kïOxŽä¯ãø ác'þ•€‚+RӀ¤ž UÙÒ/`ȐºJq~™îp@fôÈ>NñL×yëï„2 û–Ÿb)C V„òƒá˜§Ñiç²Árí‡ ™ÅΆ?ûWÿ¶éOK¾Ùÿəø™|¿ªïÂ&$Ôúíæñð?¯’[”âó¿/“«”/@íP§ûy>óxöµï—4ðÓNÿ¦öþÉoËÏAfÞyÄÈv|w6óå «w¶W2ªÿ¼?¬þç(k¼ÎÒ4øŸ—ˆ°ã€(Ñÿ¼D¬ªì§B#¿[( w»6¢òfW|/Ï 3{ÎÖ ,k~ã(«ˆyÿ¦ ü\²¿`Ùÿ×%›Ç1ÌRw$|qÿ‡¬÷\Wضv¯à\D ’sN‚ (f1aœsâþ:çÚs}{ÿy‡ÏÐ!}”ŠU­­ßÖÜC»î¤·se{tpÁ£~|gíC ¿{¨Þîr~¼]ëÒt³Ëa³ ;Í.×M$»] ò¸ + òº¼W˜×R;ÈÐ"L|ž„e~n?Æ,6n¥2. c?+¾c|¾dÿ5 +ûOë°ÿm”ýZPïŸ_Ïüý¤ÅçûaLΓ½{# +endstream endobj 28 0 obj <>stream +»â5¦7;³)¬…™./ïeZ_¼j°µ0Op~>–àÿ¤Ê>ßÕxa>¾VÙëwQ8]çAJÍáñ¤†‹ñ1àvcaoÝF—zÉç3ì)º=ԞÂ8z ·(²ð¿ðÿä HÛc„¼FÛòý1ø¹d¿FåWð‰æI#3›Cav;sü5ÆGÙçdçޒ »xeÇÂf‡ŽBfGŽäÅö„£0Ô.w%z…‰™Ä$ª8°¶Ò­Ý÷àƨ·(LW=|õüúlºëÀEºÔþcvvÓ SÝ°WeûÃo UìM³¿’ç oµ¢Ü4hn|,lœÑ¥¼/ ïµ}=zµö(’áñ`¬ƒy?¶_]àOØÀÂç>ߺk~u‚]ƒ;5†ÇÃcƒ§Ã¦—Ú—°b¶CeVlÝû×FKKèa3rüMÓÊ™F2OœÆØo‡ ‡ þ`쯾I}?/ïÞ=ˆtøp{º6gü($Gè é°x?6^dχvl7@wrgWº[EÃcM¨†ÂIh¶CIî¶î]aÐêiÚ¸ùŠä¸Y沑L´Mcœw¿Î”†“mÜëq±ý©{ø­-‚;[Ô^]7ÊÅ*uY…•]G]VjUØ×Þª°o½ò¿L‰Ÿ=ag<E"úȈ½uv~ïÒ¾¤+úï¢ð¦“gí¡BMó#a±cT‘ë±W7êȲåÔ¥~¡†oûåêº:©Uv٪욳N¥&î£ +{}Lƒ¦VðOåÐr^¥û¤ƒ–zù‡XÒëë¹õ#Üô-ÒÝ“Œ§Xi)nÖ«Ë6LvÉ^L€íì‘ãµ­§u3Ò³ã†n³:2Ÿ/k>¾ÚUz~®ìê‡×׃’ Ž!‚Âù.q˗>+”å%—î#A/õlÓö_±æú‘ç–| ­ÖŠãR;,:äjTˆ«·eÁ㤋·h5 ϗnœ‡ßóŽ»îƒ®—›˜žbÁÿ0›Õ…o?‚è}ϲý½˜4?8}¬c$9¯VÌò°R»_:ÁqØë•/]P–_Á¤Ô³Â•ÿšDßʎ¯Åqqü,:øâ`“-xô / û7ã-°àù­ºëûnHºâò»~PÍ× +ëžs\Cs§V¯Ž¨\²v87%;\d[i­­ ‡ÀVV(•‚ '¼oY½•j­?j«Riœƒô¿–â®ÿa¹†?ŒÐïEK¾µ~¤#Rï´ ñyyKh{„·\¹î}téÖûšßËè+_‡T(ÏÅyÌi¡9ÒO-Á¾¶&š­f6vîÃåœÁé¡õ>E±5ág+ù9‰ïß9´™¯wËf¾ÑߘY‹KR´ˆ†ƒÂ^ïòm Šx­ÍÌê'î‘k°Ç°ê‘#²è‘6¸›SÏïOX;ÏKÌÀiu¥©}Cr+»³¨|Å{[õ;×ܓ˜¼rFe +¬³E¬áóCY¹ˆÍ)t3?©xƜ™Õ ,‚‡úÊ +vzܝœz¬¶­Q¾Vå³Ë“·V5³hzëƒ ]•[¯Vð½ä·F—Òk?X‘coàîê›f¾ IÓ^L=G&ŠŽ#m¾­ÎÝ 7ªMë¶{VîÑY™þ|nNC:£óјÙ»Q¤™íͬ^æmB'?ƒï iU{nh,M–ÔF=ª‚qZ(çĺ+íõ•TäJÓQäîh¦È½Ü3Å(ûCÚÜÄ&ŒPEt;'ß¹s/Øøƒ¼Xî7í^ô,ç¢|ѵ’Bò}§Yvy³ èR0t]2ғbÃÀe¤«—{øP§t!Ö¶o{­U—£z$Wµ±½U¡{G”ö+¡yi*ò½4peíölH¯¸K‘÷¸H_ÇÄäB#&Wa,ð¹‹ÉMƒ$KráNs0êþzÊ}B=–çO ¢g÷9£ž•iɌ/ˆc¢Pl>çëúºTËëÔÔó4öè•Õc3lªÂ5ì(—NüU•0™)J6YËé™ø ë¢|—^W?NbB²ò/Q…œè4»UΑcaFO‚·ã­mt­#m´Ï‚wÄ¡B%t¹½“RŽÉ~ÕA¯â§N§}íærV3gªo” »£§ÀÐjS «'„°”Kò°Åyxrï²ÞàšÒ[л’ê‘œÚLœÀÑFtfë“7 —0”¬à%á×/À/µÎ—¹ÌÏUÄm"uÏU¬U†«”Z*ÇPA—«ö)Å.ÃmÆÇLkh Lå´Òß~¾þÜÿüÐv7ëXùΧf”B­¨3ÜÚѸ›¢+×Æò;”a_‘õÇĒ†ÆБÀhRóÐ$fÞ¬!Ð}G@Ïðˆ_¶¹9_²ÓÁ"¡ÞÛì®i%ušä£©²,ñÙúºÜcùà¹aÎjºXl½H‘i½éï̆9È!E#aùz4óҚ +nñ*båÑ6ßΆ“܈ëwLl°ªê•[üfÍØJgðPeé‹R®  +b¾¬jÂl'™ÆI_jIž”ò®ÒÍýiãvzS½NÙ‡®ÓE ufùaøaÎ¥+δ)Qb¤ûØ£o}*¤»ÆhEk¸ô¦žëO=7û­‘ë­Qò›îÚvÒ(tÇTy€\Ÿ2®nœ®é}÷o¬i©ä¥[ÑøÓÅSº¬nÉÆz£J™z^æRºBXiO™'£›ÆU‰§Å*—m°X‰97ÉÓ¶Œ0EgÄÈÄ~I߶à@w»ú“Ö´B½÷×/@ –ŽC™¥]“Läâ‚ݟOrôq¤=(äèUې ›<ɄÃ??÷~idÍó6×ö Gæ|ª¶u–.ª,­=yÐä,)óªBÑ&¾ìn¿ï4®Ú\‰l£3U™ós 3rqjÓwüP¤»ëg…z©ÙV +c@ ž•˜2çË™ß7r,æ`Ò¾Yê»aðP<&åà†/Ê2…/Ò' ÷¡&WéI™igf¦]u e¶Ãsѯ܀ó «G -è3kæúÊÃè6¥ rüÚ®…¥ª{ܾ<Ë1©QÃÃT&³)àeô΢‡mFڋ—í=Ž˜@ƒÍC̈́’FäBca]†ì˽‘‰U¨—ñ²fœAæÝ=ðñíàK1ÿf¦|›¯<†g)âô¾YMø Üx„-RŽ¿ÛzÉcSFcM¼J}ù=ª6%øx¯ð›¹R`[ñЦ-i®0UñÕޔ0¶•H¨¿;…Ù^3a«il:X¨ˆ:a¥°¼½jŠK a’¢»D3óDÔ&1Ä @´&u@¤‹{@„Tˆ`'¢²j­oSœ¾—•æ¯{ãmÍÖÉ^ßßᙪæùœ+·ÛŠ8V9~Mé穟§ Ïákg¤cf«H¸ƒä¬¾Xˆ0ØDr¦P 4@*ŠžÂ±é„nŠE äwE>Y1û)Fs@V3Ç¥$œd¯e²N´R7€lô`@úfúD%¾H½¤¨d~Ñ,féqÜkgí1SY>ú/½¼û ¾û7”“éx!’Æõ§Ò±]#kx¬M‰£šÁ¡Ȥ¦ƒôTèJ¸eáe@ùfPÍnPÑm¨!¿NѺ¦øÀ€U@›"úuÁ¢&îP]Kq¶UöUß€*DÎÕVOƒÅâ½&£`!C86üYÌY9éÕ©ñˆÒñ1^%=D]­òðg×v whÚ È^L@=ï?'$Ͳn +Ó´Ö¨ºš¾xt÷Ùt̏½«,}ß‹ïÿ¸i-Ÿ è—< š¹ú½e}®}±&€ÞXPŠ‹háþàÍÒ8¯Š¹Ù,DüþqbUëÑ9zÜ&VQÇЯ ZC-Ãc'SÊ,N£ô‰¦Å`2ƒ`¤U˜Ò­ +˜v¶˜‘Ú̪ýñ!³Øc Xó—œØFïؤ·ŸâåvXlv”§X¾¶dÀvœ:`«ø*Å+}°75ÍÀZ}Ôû}|’¼ùlÅóX&¦?¾9$q,îa‰ ½òÓlà<ÞoÍ'[Kë Ó'ç !`ëý`gË`×ÿ¸¿Á\ÞZ®ÓÛn²;î†?OúàsGðm[O±->Ì<ö€¯ ‘Ÿ@ìú9À×ìô×úçxcK^hyº8/¿åÉ0¼Ìx¹c^PvI.:ÕւŽcÄ(5Gpö(Au?ëÿ-§¢Ä0þãñï0KüøWiý?Q[%@˜á(. DzþMVݳ&«é³‰ÕˈµÄz¹Ä¢:¢>)&szA5.͌Xîö¾:4{ŸÎ”÷æ÷8ßl³À®`äv_ýQÆÿ”õ­äýžžãŸÉ÷ŸÓ÷¤ßÿR}ŸoÎpNýY{‘eÈWr¼yfïS$0çS ÈQ© 䡾rŀ©Q¥ã„ÝcØ5 kòâ—.û_.ÙÓïW¶CnN=h´?@Uh»ÃÃø°©~š×u +?+yY’j5ÏÇ"OÍb•äfÈûŸ`Ù¬1¥f™Ü¤†~òv•-Ž›Tök•ÍÖGò‰ì {’4Š^Ýü22_ó ‰ž™“Éñ(Vý¸mS¿Ÿ›¾‡™÷?@VÂí_œìén»ñooš+y>æI]«Ìî¥ãÑ=œh8Ù¹Ô||ô©í(¤_‡a¿\¢WûòˆÌûñ=ë{0°ß§_wì8·Gû^æAõî•íù(,w×%Ôè¤îuvÕ ÖI'»½°)^æ¡p³oíKbÚ¡‘©·åO+þ—%ûÃÏ%{Òbv²>æ²å9Ô +´ŸƒØ©p#yûä£Ws.þBÐ`j÷Ýdë÷‘ñ§ÞÃgÏ°K­ÎýήüwØÝ3›Üm +§Ï¦}igömùž9·î=ìÞÒÞä§ùjÙ¦•q©F2È?I98õ¸„UëYÖÕ÷±¶¨RÍçÁ—ìÿà—)±ºäçŸø|ˆiumd`?º¯îÚMž±û„¡Ú¡žaïá†iõ”÷÷0-íI[M3AódÌù ¦ƒz\ juãZud¥tk>%jøNWΚW©S°­Ô¤ðRao»$hê0oO)‡¹¸PV ¡[ºÇŸsé>û¥û¼þm XêKŒñÁ^H‡Êôðéñ6°ni÷ܬ1Α«zœÿlêÈ"s¬ùù¨®+LR ­ì6Ya/.ò4•†V¾ô«f94Ú߆Neù3(”î£yPÒ¡yÝÅ·®o¡ŸQ1YI«¢C•.Ehw€ OräÜϐ‹Ó÷ûâÅz‹.+ÿ0‹%Gý9»éÂíÔÒ©Â,-¬øÝ¿©á«K«²«Ã )Õ¾òi•åW3.Ý£xSÒÁâè¿&—»oe/ïb²Pqì£hÚÀD!®LÁc8¡€tÕóÝôðKà¹Ò \ê±ó»þí—g÷àÇ;à4óçˆÙsÁ‘ÇÒÑÞǾ,¯øãÝzþ§›´ Þ×JêjœzÇNY™Ւ^ì} 6JÅqÁ¨¡•Ñ,xT®ë-jù¯åù\}æá§áÆ ¤þÞ¥n³K~×Ý<ò5íôqŽÑršÖsÄ Fۗ©$Ú +’3r÷E§Ó‰MÃzm¹±U{ËâЌ™œ"ÉL΃¶9Ս™\6ßsZúó‘D9í@‡’uyÔ ËÒ:=2ðGˆØ,Ì¥’·\~\ØŽwýªº.ueóùš*øÎq W!ÑZöeìöìЩŽr÷Y5Îõ +íeNÇF;ëuÞ~¯[³¢öóiY•1Ç33z•7a~nÞ8ã¨SêêKú±Òýƒ÷ԉƛÑ6Öº¤mJó…¶)3—ùWo•°æH°.•†¹šùŸm¯ûw]æöüªêÎÙwsŽÔtû¿LûÚ9¹‡Ý³sú..ZCnQ±¬Ó¥eN¤K×ÌCÈȄc*6fž¼2 +\ñ` §ÆU/Ií—NfvYmC´ÆpšªîOƒ‚Zaß Iå •æJ+~Ü©Þ¡©”©iÏSl/)žNC^d¦èrw_œ„揲Øw±íæ³Ä´Få@¶2=‚·2:§˜““h˜Ùôu4 +]åûßè˗è¥Èkè¤Uëh[Ћ´Ê$žªf·Rë‡û^å›øM9‹Z¢H“.ß*GIV¸#=›†4Èecñ3-]ÄOLâÈ{ÄQá‹£†{?óê÷Kº­•ôLµz«ïýdÄN<êñn; +š)第™7c;6ŒÊI.î9½¬Ö½œJÚÖl)³Zjƒž¸*¿ß””sýZS¤óµ%ßB¸/wq"k°óÕl¤AÁßK&?¾‹Ÿóm‡£EnêÂô‚Ûh ùyò9ð 0Bøâ´dóÅØñ (Iãçæ˜y%Á%â·EÏ=ŽòÇϲ•{Û?â®A Þ÷‹@ÛM®¢ÆÎ+ŒÚ¸„*8$£´û˜ ß>YYÖl̐^ïHƒ8ç‹ š«ˆ£S½%Ú­a_„¤ÍDˆ!x- qäœÿæ‹ïï5#Zæ*,rÔùžlØ]°ek¦akVÖ`k9xÀî†ã]ŠÝ©á ‹O¹7þl +„ ÔjZ¦ëþnÓö$§ªÍùDPÂP¢å{o‹ÉÚi€I‘4gŤ:àEûØýJªBlM Á[G@&·"¿p³UÞg¥6·n.°Z3ŽËô¨[ôÁÖªù,Ëi9¡–Ç4—»#–í5}•@‡©J‡ÏY¾jΆ«á±NÐÁ×_²f«µGO‚èç‡6gÅbQ¯pãœzª¢ª¢¬+¼¬÷3”-G˜8žj°/4B@ ™æýŠÀq냜PÃ68Z(;ì.•ØÚxUc¹J¦Ëœþ;ëdšÏʚ³ }õIˆV6y†zt®6Õ×¼&¥¿îsò½l¿È÷ʕÈ÷ºRé˺¢ú–u¨îyåé;Ÿî*pýÜ°Å׍åÚ,jõRÍR:“"tþ»Ã.á–᪍h‚x"¼#\ðx‘ìÞ¸Ð,7ºðL ºÈŒ'}­ .Ýáí2­|ÚMê±:DT?ÈÎ)CÉÉ÷cò!‡s’"sŎIf¢NL®ñ÷’_brsŸD¾‡ðD¾O¶ˆÉc³ 3 º¯´È÷½X‹K皠}k²ÍÔô-LÔÖÖ³ä'¾Q¤\ç„Ù´KðËH@¸Š³Î°õB˜aN积÷¤;½Þ×yŸ~{Õ.4Ê(ÝmòC!Erx7ëd®Wí’oS,»#òçҋȶ·8>WT /§*ŽÍ½ ¶*¾®ØÊ_³Øªthàبã…Ï~¨ÈäZ uáëU·ŸòµgΙ[M;è/Oé"¢)}œ¾,æWǯ*ÁU6ò3H1ÒÈMh5v²”q²pòÓrÒº9™é21uÇá";øúðyKñ¢Tþ6 ÂñÌvƒ­bòŽ•½*‚Q|FA·çV­†Ä(Åú‚²j@¡¬Ö¨¢Õž4E·»ÎöçÞ÷ÒWmžûÔf]cUœWz¹üŒhSÊÌê²PÌÜXnë»ß0z–ß³t·d¨Aú£!š!!’Äé½h/Fº„ã–§ckÐt°òf]ƨʫ‰îX!B«¯Æe£Ã9ædi’+ iR…"ìÞCD؏¿Ål((döâÛDXf') +[šåOùseÿ¢Nôí¸]Qe2v¥ÏåmˆÙONú©åK¸$#;„ìœ 9zã á^/ îg¯Y,öº 7ßæ'hÍyó(—Eä8­µ"Òl,êˆ($}DÝE6ìtOÙpJAYÅí +ð% )6¸7Ò÷°n?Xw^¸7™GðýƬŠEìstºæԜos߯5í—ÿJær2„â('sÛלe…ŠFÒÝÏ%ǺžœÈŽßè.ég“2Dq6$RìÙl;IÙN˜Ye­¸ð#*)Ö¸¯R߸)X÷ÐМ¾¡ (LF¹ÌĕZ™<²_eà¡óÉ8ßÌLL-L1šþÒÌm3´&ƚ•Bõbhl.ü¼èî7¿–Uùª/?eŠ²¨ñ÷R">9Yܟ‚t~4ßä4BÙN¿ƒÂO¬CÀF¹ECj(@ÃÝFƒrµ‡ exÂÏLÎV#“µ›0‡ŽK€ðKŠXQÓR|ê³ús€åœß‚³E`Þ˜RÿÒÌsPŸë51ÓVz6R–ÂÊ ‹úÆäv=Ff.›.G½qœ"8Æñ©#ƒ9%³L¶ ³ðÀâM•ˆŒ«ç~NÈbŽgž1Ä-#ÅÞ8D×RÔú§^K€Óå{Š8ÓM‚¨M€£`b–اi,©öSܖ¿Ó/Fš¨l[r4}}uh1ÞX.¿>OLö„’ +ÝÏ6x +¬–ÀИĘªŽ!ç&Šf»Á&­r¿Á {5!ÁBϓ4À—৙šâmü,ú)ši%çËàsóÓ¡/«'À¯fúGכðÛ0øÎÚ|¦÷Î.9€Ïoc€/òûÜ8Ù­ º:ªJڒû +D´by?#<£’•Ê"QØãV•Æ4r~9äO‡4Gy˜€ Ï „^ áõY@Ô6" zo}ÂÄÌq±WR$@ìiŠùG)I1gqÊ9€8£=@¬ÖG@¬Ãô©&öwˆiiˆnúŸ ûp¥¢úP1°Q[ÊsPõd.Õú6õéb1·¬º‚äÒ]óÙ^r°5qØÌÌxS€„† åH‡–8 ÃZî§CÇ. ×÷2 ¯BP 1Hq^*c\R¬`@Aé„‚®E@Á½! Ÿö GœMñLÿlùØrÕFed-ÕQÉÃÕ(ü«—_Äomæ* æØnÖ֑«,¨Yýu‘¡É&’ÀJy@^DPé,PfMT16Õ¸ç¿1Ó> ŽvP¯vÐì¹h™ÚkíR¼_€.”ˆŸ@\xë€6k@ûr è\æhi%šª×M×ö€Îê¸Þ ô•ª^[)»kwxVÝÕmO—IÏ­xØÞù8ÈõœNt]9¹9<­ä?@Žæ±]Õ\@wmïúKßå¿Vd™ì¦\f4Œs~o‹{·°„§XçKº!`¡Lz/t@óèçsðz€Y°çŸQyÉ +Úùîld{›Ô²ÚcîIܤàñM9锑ۜ÷áľ3‹aÃû[Óϝ;Tþ¾ÌGmýU}Jç¯ôûõü²û÷qVYþMžè\nšßñ™ xˆÕSLÀÃÆpÇ7lbFî–·4§€ež)ΒòZŠ[Ñçfœxk©)¼ëâÕ×Bîåwë; ÌV#S*µtX²õ¿ýóÿ4ßÿ²÷Vÿ­þþ<¿'ö´ñ‚~„Ð—) <¦ +³|!Å$üiˆµ" +Þ «F — Âd¦ËðV<ðߙ=Z b"à“ªœjQ6ã*Q†¢géí÷џšþTò‹½ø©Îzùפî9Žÿ„Mü„ߟÖúKþÓ`îÌ©©ª›Ééz#Åzd£x²‰“@¶y ý!3ÁHwšKýiÂöh]™×¨²'Kà¼Á¤±»ÊÚÃd™Y£ÿŒÒwlþèà¿J~žãïñÿhÎ?Á÷×àîŸêû/bx:ÓÖޟÏ÷_ºÃçØj±8ê"³O1€€šž):BÓ;Ú»5PÇ ¨“ªÔΧöeÞ_‚Ã/¼a­<“üñë ~Bŋÿ@‚{ýV>Çí+Ûëõϗœ?<Ý]krÒÖühn¸åÁ>Àë},€Ýn!_Ûò{xÚìrÿMĄÅZɛ¾ì1a 7cžtÔ`n?7ß7ô,¶fð¿„xá¢Òd”˜±pºáÿ7¡ùºã5:¹²8·“vöԃ»ÔI›m¥Ã˜è»â56Õdm®…YÏ^É«Ú÷ ½ÔvNaqViž´ôÊܾ‰µY¬‰­™û²zñÂrF1>ñfÓ ÛÜ¥ëèð:>›ÌX8 Lzzl:Ã{§:Þ»F2Ô^ôë™É3ù—%ûÿý˜¸­Ùáñ§¡ Êx²©¾—ÑêâÖÇË»ßZ.µÍð°0ÃÛ,V +ϸøQ“i±Ðdç±è„]RĸIâßTY„…,% ïM\jWĈ"ÿêi‘ùÔJƒ±é6иÑï{ð|Þ[3ç¾.f»éb-× XqÚ¥Žá!½5>þný\²Ïĉß\²PÅï­Âì 0OW§ÆtmÑßV\g,¬6_ùaR×êHÞßLYn™wx:°_?nÙÿôå:»ëâþÒ ðÓ½K­ïN~f:ì!‹†M¤Û—P’Úò#oµzF§ÔÒ>ïn3r¬eӂ_ßÅF²@ÜÆ؟öÿWœìO-ßÏ×ÖÂÜ]¬_’ìB.ÙÞ‘÷Èn€ÆBgWZkùrÂ&{)´/Í{Ж¯÷z«§^Z$ÕWz`ó>hšÉkÔ;÷iÃÉBË4§vugϵE ½j>ÝDªëú‚«RȪìÂrµÂ>n“à8xfƒc´·ƒã þá(ñzt)­°~l¸.µhÚ!¿ùj¨“CÓ|·Nq®so@Óa’â‰Õ=äC×¥ŒP÷¥º®bF•:fs•]“t+ì5[Ž²4U©^¾ ¤v94óß´„Ò}\‰K=g¶ó_³Ç÷p)&ë¾TWh¿è0—iÑá,ÅHO15~˜'µµùÓ¡{~æuI«›,It֑¹Ð©Ô«_©qÇapl¿ZgД’Uù҃öåPg¯eùm¾K½œ•)éñ#×Á} ñéb²¨ñűÊEhÓÔ +qel,s½Ât›Ó±ÕÑz­Î7+*ޖES°9®ËßÉ­éðeшۣœá)Ùª<*C}Ñt߬úoY¦îçÜQŠ[ú;»v+öjLjõUpz }?ƒo*^©õtóõ¦l8-g-ÛWÃâì°L ¹{ ¨œž~wX¯%aYQIñ,‹tÊæ¸jUM‡õ[&t¬u¸F†'Ž§r]/õEç²Óñç뢭#ê­–‡ª»IWkùWNåb]9.nS¥Y*\”f™ÿº†”f ÔR¬ÇJ³BmÚ×k|«‘ùç¬dLý¶·2r¥Ÿ¸›{Ɗ5¼œ•a÷´9iS}΄™óc̕ËÊQ”O±ÕšÏ±¬©Ìá½°˜Æðâ1B™ªÒÊîÐíûhJ˳̞êaêW¹¥´óŠ"_¡j‘‘²iæәÉ yɱHó½m‘æ‡òú°LW¿NϾ¿³ÁO2×öBQ®x…“Þè +ÿ«ëÎ ¿«Oï#®üþ5zfwÒëŲÝ{Â4^§ #Do”Á›¤å-ÍS÷ª®R=­éPÚ+.‘¯EÒ"£’<$-©»&”y㸌Îwsæ;u<¾1î…ëîuvîU‹_Ã%oŸ£²­rÝÜ[<—%u±5® +òÃ1X ”F¸0CX˜÷Ç£ôµ[+íÎÌqÛ;җcx£1|Q÷k/¡tµ‘Ñ ƒ¦Ø3¤åƒï9gã«_ œNT#àü«ÏX{‰{ÇéG[‚-ss +Aj#âýÝ‚;º)65tcQUŒˆFÑ/wÛå ó³˜ë/Ωâó¡Hï>ùUnÅ|¦‹óK3¸àQ}³Ü¹3bw|¦•È9P}à\ÈwÞyÖ\\IçRBð™R"RLx¼_5ylÙð*XIˆ:X:œ3t3qOh¥rùu•gØ¢ŒìŸ2RoµFH½­ß^e¤¼*È~Sø°­Íòâjþ"D´ý°i)ª°”¥Ÿe„‚VĸM¸Ë°uÃ}3â풎á+<“ïx Á|¯Š ò&qÃgcøc4üƖ{ÂJuÇH¾À ›ÏPA+£}e¾±íµ‘ú>ž õ§|DøÁ8“=[‚˜mƒ•ŸmgJìÃço.+ÍÖålë©}7V +K-™Ú¸Õ21¼èk¼Xr=‘Å|éLóË£qŒ²ƒ˜ÓÙ|ӝîåN~ÿLLžèŸcû¶’÷çtê°¿£UtÿB™å ‡rA²D#ü=ÿ½*"ý94³çøS›YkŽR$;øv©&p7L8XSÛô|‘=èy\î¡A«‚AÏsàÁš€„^ÅZOr´Ô2HG.ªR×±¤\—„9yf¸-Á~EH¶¾_@ŒÔ6?Tÿµ¾“¹ÁçEøˆ­Ú›=º'GäðžÝ¡4{f/ä&ɶ··lz6ϒ) ¾séQG ½lkEÐx•IêÈ#3æÃï\ c¯+£ˆubƒ3Pp2vÖ\>~ƒÁ¥æ/êDQœ)NœÈ¯Ü)Í1e΅1D«;êM~¢õƒpUïŠãqFwÐò€õÉ7n*{iÍîð};yÁ:Ûÿ@¯ã‚¢æ‡,ñÃf’£dMJ+yU|/N!@Ibš¢w(¥ )^&@án YcP„„Šy€¼ƒšÓŕïÊ,fŸu¿ +²)¢¦˜=«"O¾4ÛÈã#cc˜ô„„„ˆÅ/Νº³ßgäØۜ²—Óì?ÈÙ"ýwf"V>¸S˜é±m2Åök‰hD¦Å,Z¥´Ô¥7Kq¹tÕĺ–sßÒ;&ý-@»y =¯âæ>»ÇÀ „m]¹gždWCÀeFäªÍ6͜ŸFkåðûñ$í%’à‹üø…Q‰~GN0zË^õë~´öwhX½2y¿ó#½¦–3ˏÐ7`.#§¨Ø«ž€Õô^Šx°º|Oq$V¬þ.ùM¿íÓû¬Ç`¹%0y>^1#ËNúÚQéÖä—y$óòÙ£Øfè{!ÁÉ$®e ¯ÄAX0S༲×÷„Ÿú„F™ý#“ú¿¼NlSOK½N!€ƒ3 +p£.å€ç†FŠ‡p[¯\î îP›ƒÀU–NqvÎö#€sÞ¤çà¸ÖX²ëj©§††ûµ]KcßwÿJæ5Lúá©h•Ä ­¡Ø¦ŠÂ(/,3ٛÒðÀ°Ȗá7˜¿fO€77 À‡™,À—<ðS>=ô»Å]*€àá ï׉0â Lj’¢½„•M!v9@HF2‘ÞAŸ€€#àÏià¯üVç,¾«èe¹*Á„ïý‚cØæ2#Óú¡Ê“ðýEãd®I ü‚øžþªå%’‰e5“>Ç#=ŒÎ@€ðÔ´ˆ^+ýFŠg, v T$mY€TBÁ«ȊÖû™¼ÒmÀôÒ÷éí@½ùO 6ƒ EA$ɤ‡ÀU½V²]ÙÚQUq&öü?sUÂ4r’”E¼Ì%*¸M:Û#D¶T”Ìx£!––SBÿŠÑö‰dX@Ž þw˜µž8 Í¿Vd3)ª©Uµè†€:~&€:å¶)–O@­$"ÅÆÔ:hj"¬5ÅÑÿ¸g  +ñGy<3=Ü͆@2þwQÈÜôŽý dÁ×pYAÅÌKÌöŽ±Mò–À¤¡\Z‰.þÕ|±þ~.ä¿Ò¯«}µÖjÐÓUÐ÷l0ra ˜òrõSn¡aL‡S‰<À¸Z0^ö ý̆ú€ùî%1 È*ý'9 o¡É ¸S¦’\Ç%ðä“C[XÛÌöc̀\pÑþjãóµñO‡þIÐ?Í÷Ÿ÷¸õ©ýõ·0vÏût¶€SãËßtánÄ®GY)æ ÀÕssÀáàÌÓϥʉãàHw8ˆE~‘'<ۅZôëaU‰¥;)¡g†)d탹ÿ[Ó¯œ_ÆO}þ Ï?“/ÿ%Nüó¿„ߟæzr@àv0ê„ÙTœ/¥ØD@ˆ¼#†4„ÖËBy5‚RºAeh!¨G¬rd{äìã·°Fóôf_óz òLõOmr9¾Vè?è9ŽÏžþ ¿Ußxþúo»ïÿ¾¾ýj½ùßk#½NE ½­0Å}¤O7ÒE“€´ÉրÔ9m€Ô¦ëéê¯U% {Œ×äñÑo\Î6AÿZÿ+ìŸýÇsü7êø··û™Óé§KüÓ|&ßo¹o¦PFT鵑žTŸ¹¥8P@͵\ ÊzT¿ÿâǎÊ¡èý_¥÷—ßàSÏ$o±O¨è(w]³ïxÝ/^«w18_¬wítÏ?ÚÇŸucºßßÇ|%Ú-äÜh[~cãÍ.—ýî⮏ùÛ|-ÌoëUº´Ø/µýö²ˆøçg>V t7CFå\ìÙpº.‚ç4À‡Ü”Z·ØÑ¥µÅ~ù¿~\ÿ¥ðŽáÞëgB½²üwcå,3×c„ο¡kp°· ¾[ˆ;fÎf¢on©m—ÂÂ<å¹}­«³X­3dPÊÅŤŸ®|aÀ•`²+ÔvÕꌅ]g4 +¹åjxo½¿ùCí®B‘ù±v\¼  Yãù3Èþ4ÔήìQ¿/ÇmuÑ`ÃÕÚò^<4æ¾ÑœùAËƒÉ éM—Ó SÝNjHñ{ÑÒ¸IØ×QÈ÷á½!¼‡Ú…J¢W(‘ùàÐÁØ ‰ýQØ~l+ÿ,ë9Ýu) ºÔv×íÔ8|[Õ[(ÜY®}éçºíИ-Ò[ûeK‡Œ¯l׌RÌl´atrÎ`êÁAʙãߊäßòõzxÉ×Êê#+ƒÆ[zàŏ¤;NF|Ãþ÷,1ڇ¤hÕǜø…$ŒÏ;MpƐ#ÀUäg´[ç½}·Ç-mÌù yàˆu+a7• ËV˜Vž¥hÈì›ÑšÙ·j³o»NŠm­Â‡î¨0W~r·Ó¶ŠöO‡ÖËù +¥6Êä7ž“ÃS2Õ«8Lؓ8¼h7qjO쩗G“·¯Ð ?k+ÞE’[öt–+éžÄ‘hÏd7˅ËVJ÷oÇ–‘…´˜{uÂðÞjGŸ1æM·Vš–BÉ¡nʲMužÎšR#NñÊQêЭ”»\2ðÊF)°µ¼3]”4¶¨’Šìµai°Í|D»Ø¸ Óðg²²ñnÏÞQŠåøÄc¹ñ•+M{÷t¾;~³•Å°Œ¿D˜q"™úæÍ1|—Sé³fåèÖ«éS7kÜ ºé²†RoÅ 9ЦÒx $ñÎ-bdßë= º.‰Ìl‰v6Ê6?«¹ËÊLÉJŒ»©¯Å‡  +cŒµeÇÙÃ[@ùÊãúñȕ[áŽÝNÅ[e‰5Ë,è=sð¹Ãoˆ }®ˆ_ç=-Ąº5rYª+”JM†<ùï5r‡ó¤ÉXbÔ¨uÛ¼Ï ˜ÜÍÇŽ°¶ŽÍç*VlUb¬XÖ¬ˆ6_/Ê>ôÿÓö¦‹Š"ÛÖè܇úV{ž±¥³AQìÅöÏ÷ô7`eí¬]§êœ¬ªÌú1VÉ"WŒ˜1…ˆÁ`ќ”/ÙGSFGn>òCw×b:¾™¤ŒdQxƒ˜=EzÉ]ãœéA+ïbª Öüùâ,ù?]s·½³ã²âtÏ>ÎΙ-¤Ìó¶oÆZ¼atê,Ë b%AÏϓ]µ®áj&Êñ!åòúœ¢ûÁ‘ô + +Nvš&9Gë~Ut?ûz~îš!¹©ÒŠ,ñ¥`°iˆÀÈgŽ«I<•ËíèD9K#¢kžqîõ¼ÄàzÏ_dX ‰Oy[—Ó±þ‚}æ+K¶`U6Œæ· ZKútu-ibX¿C˜Ê-žiª‰âqŠöáµØS&5²“»«$÷ÎY„¿ñ„ҁ·Ý8Lñ˜ÚÁG6´%àƒÁþZN +?nr¨ôvñ¹Õêy&ÞÉe…~!}L×½l×]j­Ç–d·¹ƒÕ?Ç6kì¦îvXæ²Ú£³´®Ðü}sCÞÓÛ± +Ž \:Ï;í¨ò«2À”ûbÚ¦Ï?ž(€Ÿ Uü\|óÞ|‹Ç LKÅאêå¶ú±¹áŽyãÅVS "º¯~øë.¸é@9³æ$~`*ùõ–¦¸úšÜ‘ìŠPÁ²ìîVx +?{èã³ñ‘¯ù*6ö jµÏ€(iGeŽ…ÐN¢ó¨¢ÕL?¯s@ô:@(qxBíXD]ÓQÈ!W$¯ºìLÎÝìþå–Sù±™’VȎÿæ.§Ú~2Þ¹|spùRõë›åŽb-8˜±ðUü|}»xªr[cÙÕÛGì´åƒE]ÝâÜ>âm]!œ_€ø„v ô! H&Y‡`ÉƗÜ ¹HL¨A¸€x˜ðß>ב˜BœäNjÌ:™2(%‹ûnRÜdgœp(ˆH·áÕçƒ-^•ë—ªß.­÷¤ëîi˜ßâ©ë¡O¸FFlïàƒÚt¶d}~dÿpä ‰ö"WYpy &-@žÀ‚âòL?¹YÀŽxjNÆäœ|Rgàɺ?Ìí:v:KÈÅDU¬$¿éå”äo–N Ø÷1x2ÕJçFm>ä™ë#!½&ìŽTöè++úˆ#ݶ€¼¯|@a3 bl¨Læ ¨®Šj²"å¼y@Í3)“„WP‹ÚÂŋâeï ¨-B¸u5pV€j5?€j+€*fY)/´’†‘¥Æ(“ü.™sO®ƒ²hóù¦éUçNÆyìJ$”{(•//¨©õÏž`Q3Ç’‰A–×úÐ`ò4³A]D(@·DÐfWôz›ô†©CPÐvi!@íh)@kEÐ +ïºvǝ¿T]8‡*GZgƒfÅÈe–Àëԅbm¥ƒÓÍɐÊGyI,÷üRˋ»uVƒÖÐ‰Ö DçÐÆò èãúÅâ€!ó¡y‹|ȑ½Ä²€¹×*ì`„¡·Ìáv̱GfMå \Gއ€+ `º&`ª-/% ‹F‚¸¿Šb'UÉ|YÌåѓeH³I’ûÃ+\{I{‰b³z ó{£õ]ŒÖ+`ü>˜`B–[²ß¬Èx +°v§ØË¢8úÓ\³=‚°³Wd·¦OÀ•’áJp©mp¼¢/]ûàß8!]Àn˜cÒ~z-É}eá3ÜkÖ™ºrá©ØNa‰”ÌÓXa¿%‘Z©…ãÑIm¹o:ô%=¿ù½ù»úOHuÀWG=Àk‡Ñ×æw1Î܀OÞ@ 뀀àFðÇÒðëØðæ;øÑzøŽqHVˆgT"œ¿*üƒesl•ž¥©žù‰4a|¹¶ÁÚ:ýFë»Jп3yŽC…•·¿Ù}#Õ÷«Øp+ªË!ÔOs ¬Ò[-® žc .Œã ç* N®&@8w@ðb¶X×BO½I­­ÛRè«þUê„Ǭ<‘ö¹ VÐ.ԒQt¾ëÐQ ŒˆLÄ#ž¿;Ž#…õ{‰Èîi­á½Ylû¯å¤øÒ´R#I-öÔ¸G±$ëO ±9 H¨Ð¢Xq¯¸zpûÜçtoÑ[9_#n⡂Y ­:Y´øX ˆS$©~÷ÿW‰°™?þmg¹o&ßïþZé-¤Ñ/‚ä t! LÜÀQÒò(«pIÔ-Î@²Ê\ARX²±œç} çi£É°‹}.™.Ø7íoÅ9"?ôäÞ¨ÎÅoe…¿iÎß G&ãï‚ohòýªêЛ|•˜ˆÊ9DÖÞ³«|sõ6Î>ÈÈmd’ldØS¤ƒñ¤—e¤§ŸìäÓGi©<Ÿ + î jO.·ðž¾µÏXh€¹¨ÏeåTºõ£AۇҞíî‰áMÙyY«¿õeuà+Ց'­JÚ&åIÓµÎK–kˆÜbe§èÍ +Õ¥ã’0 Ï=oóá%…•ZöQÉ£ê¡2Ü+,ÒP5¯ç~'Ÿ†oðG.Ù¨ê9eiëhë°ý"öÜùËñ´óÒÏǶ÷>Í˜b®!ÄðUéò —ÕûY4Þsnî•,!º3ÉQH-åk+gؙl]zVÕJWm3{]©†‘¹Íf#¶ž¡Nå:­áZw›ë¶Þd=?b7>Nøm´×๝H;6¹:>kDøêb´ÙÕ:ëIå:ôª 7;®/hCïÌ;`1tüŠ7µ´aY©½²0³çšk©ÚvöÑËûYé%Ÿ¦‹b6ÈwÝ­æ^:íæÍkÖIÛvù‰›„Δñ@2åÑe|mR¸6Ô º7́2>0ª#e éMTIVqUnÜóFþ Ú0,òòF…Z#ÝÏ zm|ö?Ñ: (Ý--OQobBxÐée¡<ñÛ\m|TˆÖX:½/·l0ùŒ†ÙG0ŸÕ4Êôk Þ‹ª/ºW¯Å˜x8$Rµ¦”Î×èK³Zí¤ÇÝHR½µŠRÜpC´[yP¡Ùr?ÔÊ 2q,'àÝ9‚¨È@¤–G1ŒÞ®¯t”vê1­Ãõÿ»Ø@×£\Ø©¥šÛ›ÕkMÁjÕèãF‰$Õ24«¤èT|-¶¬(Ùä¦"<ó~ùhTNåÜº• ÿ,]œRJãY V‡X1G¿Óòs›©Èrl¢>Gl^°ãk¡œLp4¨ è½~‰\ªéå+­CGՖWF$AG!-.Uå.z¼|œÆ¹²ôæ…Ò¸Ä'Ji4ž†P.ƒE³ Áhuxºü\/TÙhycYfÓÂgw‰,#vï9/”ãÄ:¿»|-)óÄ­ú̹šAäè§/d=S(d;EKÉò¨8Ïø‹mñ—ëTFifÆwG‡†Ù 3œÆÏâ,W=՗ÊÒë^ӊzµ…ËF“E +vgÿ)”ù7‘_ôô—|Z“Øxž¸ˆIõ|ÎwK¹fzXËzÓn#ÛÉ;Yî=íg|k9Î(¥ý,G_óôqÉ{éA½vI]6ãП·ï\*Í× +É`ô“ºª®’ú Š$õᴙÔGe;œõU”‘-}6mԚ»v¾t­—ã²ì¶Èü’¿!¹¦U|d½ùí’ídÏ·ŒoœŸE¾}2q„+‚ßäSMª)! +‰ÔÅ­fRãf»J3j9lg¤Þ]uÏÃf0ÔÇ4!'Ä¥ô¹v’=Ù¿¥r6“Ðç¾,.ÌÚX\Xœ/.ìRB\8b˜iÌYWñ½Q[ŠµòÉ{fdsþŠåáú‚ÈƸú;}roA:qSㇰO¥ÅÏ!lž§¤Þ~^’9î$ž{â!&Œ¾L&d±ÌHöHæ¥rªN%4PÒâB7d±–ój"ñúôâ®%MâÍRogÐÃAð–DèÔ §ëMg8gїÀs´ Aëµ3ˆ¬ÖXvS.>ÄA2¿]&ۅ·¼ôðD…Oq“X ”C¢Xòw àÛ;É!;;©Ü’} CÒ{q¡Åb-›¾ˆÄS¾Ç]£öŽ7å.gÀ<Çä„Ne- +<~ÏÆ|—¯Ä”f¹‹3Ƅ?îÐÐËÁ4õÆ'rÃ]N£w9'ÜåBúÜåÊ ìRÓtRé»UY¶¸´”kã:ªöŸ|L6÷Dñ"œ¤Šïùb}]ÛÄ7ïÆ[=lo À‹3³S¸Z¶Ò~'ðsÛcæ!¦,——X¼¾½ó'NˆŠàv†ã®åV‚›`fKï_Mö®æFì´°X°y \˜—³ ³šÊA¸õùÕwù=¤ù‚…3›ž¶ËÉ­P(T‰W<{¿É”Öbß KíÝ$Ü¿â›VÍvU°b³å<Ö¿ !xÓULL÷]þ´¬¸ü°^ÙpW+³å&¥âËpÝ+{÷'OvªÌ£%n>w£™×›Š3榒cŠm³Î ilH;÷朮L/gjù‘ ŸUwÔEUcKŠªÅpŠÊMµ˜iS? hN,#¥vDræ<^ÒÜ+\㛵Î:…^•YÇÔÂrÁŸÇ-›OîE“ÓDÊâ2æÛæ2#|Á>Ø÷’Í÷n.óÞ[Æ|±G¦h&o R¬¼é92"èÊn£VÂ#MÕO™*E™¦JnJ˜M²¾ºíˆ]#ˆž¨g‰ž”Uˆ˜w^±í'zl+Yí±ïºü>™—éóé”2ÃÖcó]Œ»Ä¹âÀ©³»ËÆÃ9§õc&û8=flÝÌ«ªÍ˜âS Ÿß0ˆ1²éy¢çи£®¨Ue¶¥øêHQ«s@nàml'J É^µ±s%¢WÍt p BˆË\n1\5Ó¸”útp‰Ÿ9Øù \D©¢VwáÞD2ÊuÒÙÞ¡ÅG’¹´´GÜË=ϑÍ_¤“ËiûŠÃÎθÉ|Ø͔A‰¶FWåԄƯ܄jdè)¹™~fd»€Z$GK+bç•vD¯Ó;½ñ.´ÄB%ð#^quepõȶqiÐ×±KÛbcdüÁR ^,rFÕÞ©ª}’O4Î±òȘU D-—Š,æI#Y@%ÂSqníŸb!·ã‚Ž~=Ùg=ï0ŸÖÛdЪ¦Ó„œS ‡“ŒH®~шÞƟÂ(°ðcê³ÀÕ;½ÁXã„KËÑ»ôvQÔ,–úêhà$Gh.f®ç1Ú 1Û"³¹2øì |»+"c#¶¤]ەh®}aÏ%¹_-! èû“w@ÙÞ_Vé²Ë2%þ`ñ9<&6Øbá ”rÜõª©àŽ° ˜ÓH¼Ó—‚Ø@#µœ5úÝ%cb½èm Ê´uŠ¾f5’»ƄR&øÀ:êؕ;XZ÷-T¹òjy+Äd/[DöÑprB¤§•_5 `¦ØF’!X]€yÂý +°­Ãl.W¶ ¦Ó€‘ŠËe‰(eã™}"ùŠ˜h)'ì).ூrü½T^ŠžеêΤ¦ª“|†›ʊÐðÁù¢á 5° ú±‘×ia!Ťng®/NèkÇÀãÒ‡Ä.–d€ço +À ]à æá‰)xR¯œ+˜ç3/€ãH²@¦ŽÅLB5¥È /2ãù'r—GÆröU¾oûÝZыw¨5±³Èζ:%ú¸¤ã'òLÒô ˤžòŽûa])Ú6Àµ1l}î® [€/„3„6lÕ?RßK+”¥cðë}XÂ.kw€¯؇uи5›ܞ¡ŸÀÐ6>.¤î㖘Àæ= +6ïò³Od0禉܁5ùë–)Ÿ».MêøœÜ6籟´ ütÈÎðdC‚,m²Ô̇ž dႽ¬Q¢=@´KG£‚ÑᢗˉŽšúM™n ÑðüžýD­™D=ÕDþíBzS€HœªÙ~²œO¾ö™¸¸v³äïôò<#Y°Üoé娻¦XY°r"ùÄrðä¡gcYº`!Œ€,_ Ã`‹†-œ [@¼Û{@Š«+„ې’„CèñÎY@&ò Û “å S萜—$6ŠTu¯ïñ¬ó€8åÚéÁäÎâ;@“Ì3ÕcÀ¾AùÄTúWŸÚ ­ 3ñ!Ç +Oe6Kô)õ戝Î: ÿX€¤è9 ó¥5 ëj´o9ݜ¹¼A–ØP±6 +aÎ@xK€*Eë âé Hw(ª‰ò#äyy¹]9_ +€\‡Qs©~;ľ,æ¡Ò¾±òÈ^î,ҕÏ4µÙïÉ^­µ%¤VÒûRË u·FÊui¥NÛä]ۊßù€ªàg@u“ œnèC^…•HÞ4 “IB?áe S9ÐÜÂ4Ÿ:;€Æ-؇gw +¨Sî +¨M: (»: +™‹íì*YÌ#­.ÒËéÕA¾’~êzŠ¤r<]ìP“ˆù`ÙY}ÉÝaq‘ob4u„Œ’gȨr´<¼º¹ eÖ7dyÊ0€!û`j§4`úñ`êÍ„ã0…ì +Âî˜DƒL2V ,À ÇÈ;Hïí4 ;A䇙oUY2IæLõ꿾Üåƒ=vÃîæöŠ{à  &Èá§HŒ˜@OoÈßT_%ÿ%³F:´?e‹^EÀ–ÓYÀÚã`/—&à@và Àì ÷»~»ˆIN-Àö%` +X¹T,ۚKô¦Ÿ÷ž‘f˖k +Amc§0ˆa§óÆùÄ Ev§Ç7<¢§oŒBúK‚Ž ȑÓ×ãÅo2«ÔLNµs€[}*€'ªÀWWCÀ/b&„a46¼~?í3€WÉà‹àåÞðÉ x”­.xÙC- ±+XIQ sºÕRhâÜöĖ8²(Ño¡Š8E:tH'ԟ#:Ò|W^ðø§ø,Wþðû»RÃ_šoq„ü>Ôzs; <Ž wœ‚É5ÐÚX@(õá/ÒE 8ӋŒÊ£ûý÷ÆW)ș¿¬Û9Fæ‘Úyû›W;*Îñ]‡þîïtÕ° ÃïÆCí{uáÈÚi¾áÎr_º¦| ­µ½ò( ¡š’x¨‰®O€HˆÛ5Ä^'¬)\˜±Žœb™S¿ÄÒ.G-!…O… …¬ðÎ×ÈEA‹ÚßåÞï¶ã¨œCD"*1i¾_ÂsX]"*˜ɬߵÞï¾ÚHaä³ ùÜ×#kï)=ɵç‚ä¨úÉ2‘Éô¡á$Üø‡CwÃouD­Ñê0õm ¿òˆX¤õFèˆNÄ$R!‰HîþƒÏø?&ßßvˆ6Ž‹¬½aéÞ/Wï¦Ó-3[¹ 3ÈÜAF>𠓜ÔA:ˆ ½n =Õ×d£—÷#÷é—|Ú>Ý»AÃÏ#7/^$oÜ°» +Z+yƒdöhPçü¡ä¯J¾›l”wœAW¶‚ý¬yÒÒolR»µÖ9£ëqEY}†Jøªü +՚ڒ0jæ¢ ”Õ¼ƒëG¡Ý§=ˆa¬uQÇ%+uo¢·‘ÂmÅùP¿äÓÆîtŽäÓóè­­¾$ÊÐ*뻒lm{¯}8åðÈzá PÒߌIìì1çº\¤ó·EãÍ>æy;~õƒ|m"6`ʺtŒ•:c¦.ù¢ñÓFáÈ3»€Ög¨-õ§Ä²jèMj¾Õ:<Š)¿ÿ'Â[¥û}i¨ýE·­G>ԈàoÜÀh­Ó…ʲzK§çœm&aiæì5•­KÛ©YcîÔ5õø~`næxVzN¦Ó…< ¿7SÂÎõ&Þ_i^£µÖ8¯¾øîa"컗ñ@ìÞG—Qÿ3J3r¨çvñÁӢ䁌ֻª]Û[*ºQîýEçXï‡Ô¤ë늿/¯V$ Fì`3_ådÃB­_"/:í=¢j­çaë¾!¼ð‰°Kóãc¯–‰ôPÏ09ÈÈêÇz•U»ŒÕUt ZýEìõ‰ ¦*n›+´Ï„Ûºõ<%íô¸SyÓU’Ê©sÔÜOGz1±ö¸¨ÛiT˜´‚eŠÇ6[Šê DBj´§Y´aXÄ.R'# 5òN*n#5Uštc5Ó©® h;‡KÛŸ]E<:ÇÑëHÁ‘l_ô€m§^—X+01²Ê6ŸóO®iÔèRã³æê »Uè5Ð]{R‡Ë‡E8±çZ3©â5:`â UoŠéÕN¡FV¹ê ”Ë÷»"¡ê¹Ñã®pJw¿4ÔȇúYÆ »žéB¨«¦„“Ý@7§å÷Jÿ_T²õt¨Ñ§û¥êÀ½ÚI‘ãHEÉÅȊðʇ•êÉr™Ê¥quß*¥É´^Ô[†WÌqÒG~úŸ¬ü<ô=ùyÌ Q}¨@«î–ˆk´“Y(w‡"oK/Ô«õE«­54i¨áÞËÇé8Säõ<·áÙ( +B¯t±…Ai\NMJi¬0+êõ”YÌQ…¹üÜT]Ùh÷v²Ìi§‚­Ì‚H¹û €žQ:¿•’y"˜Urî”åšyg“£?$ë9F'ëÍç>„ó9‚È©äM£L•jô!HDÞØb0òÓM¢²ÌàHÁîâDÔLŒe dbê„i¶€9_“Ìrž¸,ë9w¼mçšé“’£ï÷a֛-Û)0f–û¤—¥,o3ql|M—'$=h¤…t‚vË©Ë6;J»]$©öÞ|*-¦µÔ¸ï¯#ˆ†»•ýä+ËÒÅ<ѐ\ÛÖÄÊ=×Lá׬§ÎYî¹¹~ɧ¾ñþ|YO•¢@B(q™8҈§ó^22ÃVGÙt‚Ð +©‹;¯¤ÒŒUOÛM'©woƒdN`g‰ç±¸Lƒé!!'^oésë +’­cU©œ3t©œW¯R¹ð¨Hey9ƒ°þÒËë5¶”)'D&¬'†Esî¹òÈøÏÕ9=è +»ÔeyÙ¤ÒÔb 6¾ŸÔÛÇãoòéó–ÌñÜ BIý4žE™–>ç/Ù£Ž(•Sƒ”„vA\è~U¬å>¡¯S$Þ©qܵT'Þ,÷q+Á[ÞB§Ño fn.tZ:'tÚ£¶àmnÃæÓËTª|㙒_½%“[×W ÓÞAj’)¯‘ë%@-·”ìæHåÄɉ”Ûëu).&÷µ¸Ð°-~/Ö²ñ“H<Ó·¸kÈÏxS.â ha‚ç i¡SqÇ÷©˜ï9¦4ÓÍXœ ùãöâðƒœ%„ Á'âZž»œ3ám»\ÒgîrmføD’h7°Ú»\NÜõD¡"wél,Õý¤&Îìš0­À—*5e#ÂÉè"ފ™–°-T ÁûäM¡SfMÇXBró—ÉUL©g6±8U ÕAþ¸©ùA»uåÜðÉ]ü9ʍ•Í¥E\dƒs&Ái²ú³¹tgÅ<ïŸ;ó|,Æ0JuÆ0“sÆ°Z4óüð…Z‹µŠÅ©•sëEüG‡ÎÏJg©²Xìâ„Y ݕãÄúvÞàOwD燵۔O¬W†óweg7ÖÚ3šÍOuÎê†æ²ú`¾es‰Ý‘y^o7ƘÃõ‰\­Ò f¡ªNÛîM¦Ë­LÂÖ 1N>P‹Å §ËqŽZ¬ª#jáöï0íÄXe,䢄l÷¼ÃRs{$1q)³é ÝÇ~ÇE“ON‘)—ÎÆìƒM"å¶Z°y¡¤1/CÒ3AC`¸)º„A;1ΡËi¡±£1U=QKiþ jŸN‘N*ÁʓëÕ&[BJ2'Ì'¶C#¶ítšØ–‚pMlÓgx8¦‘Õ¼€7M.£¢#$™Œn‘¿8Îîâë˜*™s>¹ìc¸ÒØü®=bŠ.7`™Ò;€Ð¹ŒhóÇÔrêN¨z~¡QäÛ %Urm²Uzºd«“=,߈íÞFˆíƒ‹ÝY;GÄ·6~`ŠS¼¿=ùx7Áq±F¦!¸]\Ì«..ªhir÷3y¸Øe£j_‘^.R/#Ò¡¸ü¨\·¹Ìë6eÞóޘA Z¥+Ÿ§J­ÒnŸ¢úã>¹*ÙÚ4U’-É*±Cå!„ŽFtc“èúÇë£>~¥+ޏQ\´Ž<.Ú©ð;VÅ( K¦[^Çת±µªqÒÍøw1¤rì!IGÒ¾4·S—x»¥ìb’´^r·{ÑfgÃÔ) ¥]M *Õà +¹éë‘É‚ÝÀ%â®]î=4¡1Qðþó¥à*áâ©<ƒ0žcçábásÂF¥ì K¡c +½-. Të*hVÜ ‘Ç%ï"³ñõ…2}¼XÂ1ÚùÂΞr Í%²½FŒN>ü-iá"ôæò–yΒ}R”ÉXsM£çnvD­ì ŒáTWHö݁GeÈ.H(øAç\|¾zØy©Ø¨… ±K† Þni‚'Ӛí£Ùê3@fkE +Á>I¸ú±‚R”ôÛ y¸ØC  ÒµЄk”Õ^…jŽ‘2ªõ¦ŸÌù%Òµà; +q ÒÃПö¥–£YU£ xµ¡hÞë“íºÞ'v› d©ÜÇ ¾‡« +¯`ç¦`©PQíú"ÏÌi„̯)Rpy|šòØ ý J×Ë óáëíUtQèBxCªËå ³–P#Þ(œðt ùÆà.¦GÁŽL”»W¼ý:žb’Ëx\vß]DR9½ zZ¸ÍԐÜÜ=•äòö€èš}BHÉá“B\]$ìg Kë£Ùë]Ed|­[]@YÚj½Ü-€ôÂøáùÛá!< ãT`¼¸„p 7#šû+»è9*ʐko×ñ”Ÿ‘^P’ö‘O}îÖÈç_j9a44ªqåFd{>¥«„0êôq5H÷°‹y¦^|Í%1øº°‚©¬±Cx…sh€ Òsƒ-ÿ°a˜¹fIEx¾Ýr6áa&¯ Àz x¬¦íV×bQó¤Ñjãb³Ü~DN8}|Ú°²XY0èî.<(·YÕ(ÚáÆ$·ô„Bé}|*C–¾¬`é\BAsC¦€îþñŒ&vxNħd Â`pá¸xœ ~“¥Ÿ"ÀÅF à2ŒthÉ\œ©ÃÞ²é<À‘Ï`ÁökK¤/¼«–{),*ÈÂ_‰æË•÷ƶ’sz¡ÌHÕ';:ô½> úx¢=V±ô¢ÖG^C2¼B#`úǯ*À³ dÙ+Ï®)åÎ]B<€û Bû ðàBü^HBØÕ~ÈÃq¸ÃSŽkÈx=.Ü*éïVò)}‡(©æ¨ œéo’¹q_o˜ò(³ k½³E1‰ö”Øãô?åƒ1žØx#,ƒêCäõ’UàÜ0rbŽ<2˜‚]؀(>W€  ¬jäR%,íáa§XVۀàè€Ðr> t’„TQ_™€(,?‘"”OVd¼#YÌ¿ôry¿õ¬_RÍãÆ"ùmψth¼0ÓnŠ>RG ±âã1¨&Ë#H«6†´ † ÈrýtñV€ÛoVäé#äŒzA¨Vño•1ŒiCҀàž"¸ÝaY.Ô™‰Í)ÄÂêåvTÈ<ã]䏒9dV_x±¢ZxrհЇ'™ˆµ –ƒ`ºðÿ^O r¢£"§_Âï´ár?Û +»•‰€êÖ߀Únoî7²Y”Nªô9 úÂPõ ¨Âª¨Äd(vB +õ•¨Š¹ öðaqä2ÿ’Ìqq»£X%¿&ÔÄû7µ¼0Z 蒳I¡öoœª«ßÄè?S}»w@Ëpøè!BDe'"åö5M@¸Ë€>§[ /©  ½Ý ÐNO´–ïZ‰o ¥Â Þc²ô·ª, âÉ"“Ú%ªCÉÖî›T>;oÀ’WÝ(h{uý{Z¡ÔúM‡†÷–oä?¿ÅÐ–'ÃRÃM°c·Ø =l·g¶ò>6;£ Y +Œsöà +È6˜É¬÷UÈ|T÷pöýü¼¾ +²ÁõŒ×æ 5³ù¨oþW¨¾8E‚¯»}}£*N„Nߨ™Hdmß+ñIš‘æ;»”÷,´_݌_ÃMÀçZ[ÀǯOÀ‹ýà>dp—£8g®×N®–ï G¦Çs϶MDí…SÅ+?ðI¼¹¶¿¸…¡ú¢éБ÷8ÒUCõùËsüßÅ&¾Õ™eÖï‚ïW-…â$²öæO ¬Ê{ Ìì<ÙȁM©@@nkóçˆM»2ˆ©‰I,i Quð¨08~ë8(j+¿• MÑ¿Ó¡“T# ú?u&¾x|×|#!óûŽr‘Ìvø®õ‰°j¯‹)Ïq@¢zY ~ð.½©Än"Ò:ÅÌK¢àv@üÕ^rÅB[¢YÓ 7¨”Yôs1߄òÐÙ³¿dñˆS$©F5…#­7rG$þSS8d5#û»os¿Ë½QÕÜHaÄÕ&"~í˖<¾: ¹VLÁ>$S’X©+jêúÌÐéÞW̔íh}âQ1N5²_ƒ÷¥ÑGÊø¬½_¶çïrï÷“ïÂó÷Za‡/W¯ff#™7l&2ædfÂdñ\»ì d2ÉL¤o§H/H×ãèÿƒÿÙèĐûF­aÃëdgr»>K/ôs™•W÷ðÁ=w?£‡ØÐd\àbÑ«äF‰šRÚ¦À¬¦ä$›I†šŠóuÁë¬?ŚvJ•Á2èV¦Ç÷¢–‚‹Ìú1›rªÙ®íêvÜ;AoF bý”¨…Þ õ(;Æ°ÓvÏcrâ3Ç”õühӀ"öÆq"­Ž•—r[͝ ±]p[ñIv=(}nÖÛµ½ÿø•Ý5y(dˆî1¨±Ëó@?¯¼™Çâ¶öJ­{åV·¬s{e ü-ø“À…wÇ?‰ÝÏlæÏb÷³›ù³ØýŒÀÁ?ý#I÷o›øѤû7ƒÍühÒý›ÀÁf¢Ÿð>Á“Hn÷É “þ¡Ž—‡ƒ=ٞÕÊ-¦$èZ¾ 7myþÆÃU‡xìññÞ¨X½L\M/t‘,[çkʬ¬¨¯@&½f(ÃåÔ^ÖÌû"{éË…Ý'JNÞ®—ß@Õª™EÅ«‰WýȒ±&ç¥VSÝ ÚËätÆõÖË2­h%!׿àHw ¸' wq­ccl‚afiÅq¦¡Ï²Œ>½½ž[C²woS©Z‚µ¥úå0ÒÃyE‘V Kƒåãzcܔ¾ÎÃXë½ÍiÛ[f™?íêÍîÏ9Ú¿÷Çæ1;˜OOãÔpw>>jáó˜0ðñ[«LW‚þ=õÖ}:ƽs.Íÿ^µM„7àðËüûŸ¿t}V ņۮ†Ù#9IxQ£kq+ÏÀ{}ie›Ïä¥ÌWó[*¾{«íÔƉZ-µN:4õH½¶.“Q¶r˜¹ýÜá֛étñ"7e1\/—(–|iWò͕Qոɾv>´†0ÌIÍNš«µÜÇ{ÒÁÌý¦[,ÛÏ0‘y嶩U©›TJœ\ ½sp…ÙìQ“Jn–ÕÌO·£?æ²9KՅp±` 5ýÝ-e7ï÷¶³4iÆÚ"iôµ31;-r– Z¿OŸÄ¿ØÌŽ„T˧Á\ºC¾ãÖ^&»M×ïÆÜ¡¶T—÷îr7ÿÜ+HõIÛtB¦,ö¾%Ìî»NŽ‚Ÿ6K&Ø4£1íµ±ÃG;Ñϟ¾=œ”ŽãCp=ØfÓÿ¬#ïÿ¦‡CªŽºÌ†Û¹=ÍB ksMÀhN81µòð¾Ô; ³d³¦'ô¼8iÀ/<ÂÞüà©DT÷¯rópJhé:ühm6=ns“US]¼o^΋o‡èé/ž½ü$,c¨(fÃç²Ü&_úty~h¦¥Þ'Ø ½ýí¸ÿùà—‹ÃÒ^ÞçüÔ^}ôÖv7½Ô$¶šõþ¤óÞ}SoÛ\ÊjO8æVÌνëgz“[Oý‘ÁïÚ[œß&ŽŸ:)Æ=E›ùþá_ƒ!-yúñݾˆu »Zµ°ZôèéÞò’ÊtXÏ©o/»q4àÀßO¨¡–ïYòh>¦™m&ÐóËóECJÓxù|îG­ÉØÿQ€Íü詻żXð<¿õz2³u]zµO1n™Ï ÊÜA߇¸­–—h⦐7>³³=§šÜ ÇFÏßßg­xÖ\áv£ c{Ãî*·ù‰›‰~îj½|ÁÇÌûÆÇÎTzK¼…›Ü؅9=(s¬¶YÛ®6»[Ü$£i5_³”°ôYWkë>Å܎¼­WۖÐNl”~n¾Ì{%~Ž՞ݜgW¦ï gãX÷_Ó ûºè…Iå ¡ÔƯÙðÅÖQ[öçÃ^eà ÄiªÉ`mül€Íl™&žÙ¶²Ã•×Mp ÷2wœùœ x‡<Ñ=sO{ŽqÜ{ÇÙe4¸éÏæò •V”7vÑÞrÔ6>ΰ71¬:+›êh ¦}Mqô?læÏÿ-ð:—[ÊëÊâr¿/¤ås‚;N}nÄͽZkƒ}-´àÌÆVs;ՕÄQ³+uoBX;Èò%ÙÃÞõhÔCgªŽ.q­¯ù§‰òŒ;ÿ`3ÿû ›}ÚJmDl³t'¥¸4¯.RŽK¿b³«~ªO§ÈIÓ_Âk¥Ëòi;©ØåÈÓGÎPIÆ`[LÕ±T ›é~¬<•ÓH)¬Íáφõ*„«Ýɨ°\šÍ¡hs•Åb–©‰¬þÚU*:ÔUÍS[Ã2w̤ÎöÐ?U!Ën «c՘ô¯<êçøøP1j¯aï³Þþ ÂW þêw?nú¤—oÂ_Íëù³hŒ?µžŽ8Ë÷d9žç'äþѯ T´ñZÊ;#^Y™ƒÁŽÓÔñÊ÷ï´Yvš#ÅXÆŠ\g={}Wÿ!„½ù«ß-́’Yà™´k‰ë,¡Ïë|v¼Å‡öH¨7Ðᡤæ†{ßêŽxÿ¬N­ž®^«Ü¤/¸ƒ~Ϋ©Š¼”ÃfPOze ô6Üg™¢~L¬pžöÈLnýKKˆ6xÄ݃÷î­Fj±ÌÜÙËbFQŸ¹©5îs0ûNÙÖoöb™¸ÚÄz¶\vr¶ZëjÑD>07ƒäÓl3)ðÕÁ?9üðêð Eü[ª?ћ¿Eõx†+‚Kõx†+é_;úÿ<þ~HÃøµ£ÿ½ùÙ£ñ ›ùµ£ñ —Q¿vôÿQ +üІÓÁ_;úÿ³7¿dô#žÿüÒù·BÎ~íèÿÝø7! õ´_;úÿ՛_7úÿüÒù!Ík!Oðg6ñ#ž°™Õ¨[þ7ÕǨÿ¡z±Ü¤y…TëWsãŠ՗É^%ðöæÿ>ë>ƒsP3pT +¤ßoÚÛ3 é!m°aH©ó"¿~¿çæN}9ŽúyØË´Ødž SÀr××À¢wÛée+Ù6ħÉ%²èì°?¿Àfî<9†T'Ÿû£{†T«‰êApï®Fjl±Ìb±Ë"&À¼¨õÞN¥‰¾ì:¯<¬µÈÜ-¦¸½›Þn +Ù=‹OCÔÇœ,9­w°™ïþ!|ñ,Ɵû,¶é]Z½tÈsòD:'¾ ©²çE’Ð9ÒS?.}Þ6… ÞVKL¼Ímñú1ùÞäm(F ̎W Ÿ^4©ë©ÑûG!T9þׂ÷AC¨¿îùǼ ©&üMû +GÿÈàêL„!åÅËü}æ OMGìƒk}Ÿ‹¥2ˆÉßáäÖè 3lv¨T$ËêS¥4Yi~–Š‡Oqƒ÷£û†T­Î¥¥¥ý 7YÅ U¤ ©Ææjì<¿9ę÷ Ì^ÉqÌÚðKÌܾó¸q@q2’y§×m‰Ôs£'=)¿šà;„²Ýù[ ïÛ °fÅgð^iíKkžƒ< ýy®DÈ3-†[|Ì?”©Î=Ân$„ÕÆք%ñٙ˜£Ó(!útz~k (=ÇK“{—§1þ· \­ýÕïnÕÒ¼X«:¤z˜µ.­R]ñîQ¦ ÕCŽ~'sžòYԙßÚn4˔Ùû˜!Î`zKÔßú#Uv׊íöu¼tƒó¨Õ5Î#¶ò|þ¸6”F'(©Å°˜ +½¤šÛm¸íŠsM6¤št–Y»©ö H¨ 3V»‹Æa”GfIwòÐꦙïÙyRѹÃhl؝ɻÁ®ÿ‘žö?ÿ\ڦР+PI ‚R¡Q¿´n¹í¦“8@žƒäùÈ@žŸúiþÙ·Ñðîi¨½¾fçxM3×üU{÷wÇÉ •Eõ6ÿĂ¥KµK›-CªÍ¤jĚ«q,o/õ•yš£g„*Œæ{ð™ÞŽË›^ˆQG Ùh»ñªÆy£60B=m[åê¹t÷o5ç'ÁqtIÈ·ªG]oU;U —QídÙÛtgzòÍÕ ­…ñ©ìífV{š~†‘0©?A뤕ò‡ÝJëÑÆ–Ã^¦ã T‰±BuÎìk9Óú3ˆô´¿øÝ_ÂÞ §©«[z_®nš.]6§ñv³#Ô:^-Öݤp2œÅkµµx ƀZ„³Î©ö<µO&¹›TG³õ˜Žs‹ánkۃáf©g›õoþv¦­¡PэÔgjªôÒ¢ -¶šò$͟¾]l%Ágàœ•á uöÍN˜iÛ΀Õä‰älf ŒÁ^™ÏÆ£¦?ÍřƒVÆóë±[šÏG²`£=Àõ©z)”µ~P&'ý¬¾)³—3þKƒö¿žðØ-ª¬àÛ¯«¾/b-Úw(däq¢ü°×O#m y¾7½§0SűµÀÚ›Ô +±H‡öô‘j“³Áqr„,UESSyÒ×y2T'¯#¥pZÿ „½ùχ­;{ð»Úm:Ú--Û2N™WÉÒÕH¦Ì”þÒZM4ûÍÎüK˜l¶oΗ0yÜ¡âÊ«iº3îëÜ¸ŸÃ˜/uò›9ü9àyޜÞ2n¦ïue ¸k¬ÚytðØIæ=ª“e%9œÔEc¼¦“Ψ³Ø˜Ãx1«•çDÏã>Ì Q?W.cJªŠœÇ=Û<ý‰ÿçYlü{›ØôÓ;u¤:Àîú£¬Že·Ú„¦gȸÕ×òcæ¼éŽ¶íÛd´-SÖPyiÓABãBIU?ž“þ]²‡ýÜX(¯ts¨ÈÓô@"£öì3öï!ê ü¹NŒP´¥Á¼~HܦeYHŽwÍum8Ä*«ÁeÔF#]M FñYmj]5S•ºý|áÒU̱ÑQŠ¼ÒQÀ¾Ùí9õ\·W¡Ý¶á{Ýe „Fåè翆ÕTЩ%ÂtÔÙë~il¬- /»tY-ä[áØô‘xr£”oâKÁ„ÛuÇßñê¡ÃñvÏǤ֑ØK-Õ]'Z’l&›0I6Ï×Iº9šô`3?pÖ+þ\_ñó~ҙÖ]ïô‡‘±ÀÖ1lTwEj7] ;¸·¼îc·eúu¸-ô[õ2‚Ó¼à)¡4ä|øôÁ±¦äÑ)¾öi9'Û¹ ϶³›v¥j¾¬¥Qüßãø·T€g¸(ü·T€g¸’þ·T,hÿšêð Sà׎~Ä3J_:ú?´ŸÒp%ýkGÿÿìÍOüB…)ðkG?â¥À/ý™+¤a +üÚÑÿßzó³/§a +üÊÑ'_¯¸™_ó¹ëcRu]|ã5HU<„T‘Ír²d¯‹ûz,r»êun¬‚³ó±•“SZòG%¯G{>\žìÊ­¶ñjýjãÙþÓ¢™§ÙšPÁwEÈÿ>òð‰íø%’ ¤º.ŽaHSM]ÇÒ³ßxŽCž0¤‹©¹‹žF½æp5+ς«c;g2g»j®O6 ÏÖªW¿ZõgñnՏ=`ìøÇ}v­Ë߂ÐýðßGþU†450°oTógHÕc½åä».¦§Çó›Ö«7§<ÜìEŸ¹ÚÄp}ùãÓ¨ÌËØuñ÷L܌®Ós»wù7ð…=äç!ÏS%äÙÛÃf Õ0ªe+¤zÐWÉ1²^f–ÔõKî-VKÇi<ö’o6I›Õd͛E÷ê7³m$#™™©õÕsšBK]«I§?@8Uÿ“à ÿ¡ú„T‹Í{®Óð)ÃyÎjßxÚ8乇Yú­7üÞT +ϧ]Ç:kM‘‹a—³#T†/‹C˜HÄ4ÕVړäÎZ¡ù<ü}…®ÿ|xžŽÎð%æâê«Þ‚T«;HUG U­êŠõ3¤êáî—ÒÿMë€PëýØä½óÿÓvžÛnÛ\·¾õÞ{ïU콋EEJ÷@ÙNÞäs2¶““?“&´=øp"‰(Šf:â÷¶ôâœç.ÁՋý,h©8}”z£)or*YÞ¿‘§ÿ4ŽO?ʁ§@4!%vŽ{Û`±skT÷ˆ*r¡´vÑÔ~¥}ýn÷Êb*¶{“‚á" þ$äœK™i®~f lë´®Òáœ%E¾|'”ƒåˌèýLbò¯>û“çÅõxJ®šã[2̈́ÅE‚f/"%ºy#VÛBDäKƒØ‡>5늟šôåßȳ½!Ñïœþ$æ\ŸÜ†ÅœB¼ÆCoÜG­3*)j_œÔÕ(%)©TI0O•\졦XüÉ¿¾¥ &;‹€Xaç3~òögÜÎܞxµ©ßðʛ þRbwðoÿà#ßPÛ?|âxcqX;€ÊŨ¢¼ÐÑCþ¨Uí¿üv¡ô'_–·ÝSŠ½P÷xàÁô®“%äŸÌ, α4ß[˜W¨[XƒxZžà_bøo$Nç [8 +äåÿÇ>eñ½Â- ÔVü7r†a¼ ƝímÀû߇££é°éÓ¬”òm‰Œ™œv(R¨lR‡­Ä3Û¹zt\\<ýhÕ;,>¶O´³OÓH)‘0k$Øs +šB“8¯ósü‡rÍûÙñíåMìû(#ôïÌCœúèn•v‡¼2avC¡â)±™ÂµÄv;c›~ú —Jy=ƒØ”w¶;Ï Öú»}ª\‰8Ãñ‰ÉMåÕWäs7ñ™wK¹µ[ªY5oÓõºuÖ¨âQHÒÕú™a$ÈYŸ%ëwˆÈwŽæΑA‰oºðû%*àõdŠÁš1ö¡ÑÎ{I"ô¬~„Ÿt„ãè„Câ„Ç¡Y’üWâŽðI!°–Tœ¨|Õ»©J˜˜SQï³bI nlo€ôèIv¾¥¤BQéùA$—ì\9Z7“Ça~Ábù¦bc’DnÁGhb†ÃÏ{‡ÇÃÄwSq֖ÄAûíä—ÄV2—´óŽN;ß/-ӎÄ̇j²HØþ±åPó‘Ü"WoI«Wì›wž&ŠDIÄÝ:Ëb~{D¡×ê“@»¨uŒÝÉcìNâpT™að©ÜIÀ{I _•o&äÿ)>é#9açó…­âÑYcSã2ßi¯gTnãòàI„¼pïµpÄ9Îq`Ü¥¿%wRXKn(™MÈ}}>~2<ã‡M4ƒãLÏ gx¢”¯ƒ¨š9ô߈µï®"kÿ~Mô0Œ·˜0‹)Q:sâÇæa‡ÞÍ¡Ž–½'òħäنðëYÂÓæm-ÒØÊ0›ÉaõêNÀû¬2ݛÜl¿µïÓ} òg;;kÄrZü.à2*ù‚gãq3Àkt"ÚAŽ¡µ^=âð»>¯é5,ß椵&´Z´ï‡¢Ä]Ž}ÁÒ»ú´•Ýbt:· În~ClÔ¦›`Šë›D–×to[Z÷«Êꉫ@&µ_p™?•è]ˆºËy4Ñad3,›Lc¬0j#s’X@›[„îùÀíšÄCÝPÂÎX³Ë²½Æ·ó*yýeì[/3£Íu¡ãp±"ñ p‘¯ÔïsýÞí*÷R|ÿ‰ê­ÕÈéÕÂü(ª-ñôêu~í%œ»Xo{ÕFuؼˆš?ËÛZKÍ*Á³gµŽÎ +õ¸¹J¤xòCÜ»2›n92ãÖ=y¸Êåa#}‘"3J``ð”Ôéþ»Äã›?–ü½ü õ œ±™òoQ¿ ¸›ˆúÎØø·¨_à—ùkÿW›À¿ )¸Ì\û¸›ÿ®ö?œñeþÛÚÿpÆ#éÿ¶ö¡ üëÆMà¿­ýw(çû¨>vcTÐÏ«-ªÆ5#Õß³/¶ÊJ¨¯@ÝçOZëÞ¸ª„¯]”›Ý?+}ïæÉÏ ÷3WºOz g‰7|_âq7&%7öÓDi!=„UqüCˆ[ÒñɋêÉ<à„€óÔNÎ\[wlܳÑë¦Íixçõ±{¯j×Ð…¶§ù©Ý|™}ð^w%ayÒÄp})ٖ.R2©ÞD‰RŸBîÚ¸òÅûÃÿK‰ÝÁ¿ý@¹!Ýøç¨^*Tª£‚» €:d½~‰9?¶ô½Æ^o¨ äi slàKobÿ™ŠÜÊYJúîY”ÛüEœS‡@œCäCÈÛwîä^.,rDÝ(ñpø4 ¢ZÊjC¿f®­·Ý®-Ý]±°^Ù¬†™Ø–ÎÊ= +ïÊ ÜÝä1’¸ßøRj•öE™7.bF>‚V[Ý-‹¿9;†,bRqÐܙ:ÿPâvÕ±+i» +B*·õ@#s/ÀéN„…ôFãÂ~&$coòw»7²ww9±Bi6Û¢2L\Äl›¹ëþ<òú$âKdæÉ"/öÊ´•¾K÷Œ”õ÷[ªõ D@íc>i»4øŽ*_6¯¸-£r× ï¶tP2U*ݜ¯d$ó2ô”¤Qp“ÒÝM(fýëgaÌÚF®¼yîÝùÝx”dÑ¡ü`ڷхzpo‡%ÎÖ?€xˆC껟&ðAµ{¿¡žZF5­¾y¨ø»d¨T¥§öfÞ±ÝIófð—÷å]ÐýèÎ[ÐáΗ±Þ›«Í i¦ÓYߨGTðÉ×Õ±ÉiOŒûiŸã¯ËwTî +šì¤úá4g.úÎYÑö±JjÇB)|K˜åkIybs‰o©½9w—ø=â+}äÅÕÍ4C4œõ\ö落΄ü OÄ…/HڟŽë`füCˆÈÎmc7ZØûz;5êLÞèh5¢Š¶5µ?kÔU')§’ANÔ6ݬ°½KßvF`®×QŠâw蛔=GäÈçý¸aÅ nYßw»ÆGbò·“¯ÊwTý£Vûß9¯•—-¤N £º—W::ϵ£çˊ“¸Ë¡ŒÔE2öP‹b¡ØÍñÕË*Ͷ90êWð˒-UÅë±ÔϾðJ@\0·;s0X­›_•8Kõ%ÿ‹Š·àM5ԃ5™xÚBÇ­}÷PÉ ª™‰¬Òkò¢Œ»T*ÞÆ¡{¨ÉØC}Òl5s§ã~¼Óø2ˆUŒíÓÍ%v?o¨ï.Ï(Þ¨œþ¡Dpž£˜³ÑÏþIü½ ÖR:²…Ý©{“3ý<î!Zp%Eõ>ïsEHFŸµüŸò …1!5ÍË‘×oßíÓcÊU*gèHÈÌ|$\-}„4ëÎï[ª,ù{ùzÿâÛ1êP Ö§ôÓ~7%ÃÉ&'F½@:çYªT±ðÜ}¦ð> ä;p:¤G‡¡GfSkãXN(r¼Ö\@BZåᏠð¨$i0+tÏ0»ëz¿$KõÇ  $·QýÙQÝhwÁ3u¨ëkú錹ŒYó]ÐáðWJôhÓâÆ^<|H\óÂÝãUçg*5 M¢0hÊx­‡}_kÞ¯“Ô'w°½¢!šsÐtÁ¨Ð”N;ÿP"³¹àô{€s;Wƒ‚ÅÝA'Ú¬ßæIÙV4*۞ˆ^Ãxز6¸ÀsS—ϪsBï°Ê±ŒgÅo Î;D‘Ž†л} ¡)ú*òsÎ:.ýIâü´ŸÿL¢F–¨õÄ ðN*¿U¯¹Å2ðz¯ÒÍðnÔ´¢n¾l–x †V*ÍqQÜÒÈe3£-ñÚ)ø–×ùcÁù nIšÚâ ÔVä!ËmÙ_—ønâã³=Þ®Ÿí¡?ý¨×¡ÝÊá\-xޝv™6œÿºw™;ÚÓ|V¢èÄø:UDûžÜiŒØï«Î×ùÉ넟jú[&æDŽ,ñøAðã!{ÞÿPB95í?zÒAzP‰°òl·üæuÊÀïÏxÞ{ßú•¬v(iS]Qi²÷IîäÉÜz"ÿ!¹óM¡ÝQ¼ê|6Æ`N­`¿åu¢P:ià‡å‚ù©ÄAû«Ï~/¤‘ôíåµ¹û¨Jå®z·<µªgm*mßÕ3.O¤¶öʄ¡j3¢x±¡ɝþ“Ü?:±°C¡ÄãvŒWŸ¿%wr÷1úIî„ÄWì+âzPB÷ŸJü½y]£—>¸m˜%2ÑiF‘’«+c–åj ²xòyüÌîxs +U° }bÇ»Ž“;!´·¨íFOàèmíáIÛÁ‰û~IÈxÍÝÝA=ævqÐV¥hwÈÙ×ý?{’w'Î{ñÖ„šZ_ä~êÌ°Ðâc»y¥Ú*2ö{7X G9xÖï× ¬åT›4Wßï^ãú¾|ì6w“hìj‹ë'ͳµE9µý-ÍórÅ;›ãaÛýKùäuþÝXV¥q9›—ºúZ¦¶<Õê<©r©ÑÄ{%g‚ÌV×=´ŽVÔÁ´çæÞޔü¢RÁ?Žnrñ¾oºÏ[ƒ¤Vcv•^%FóìR z¹ålßÈÿC1k†¿4¦/f…V:½¤¬ÁÆÇo{¯„ÈFj™…ÍæPñ¯ØÓç̆^ÉÜzäôÅՔ{+Kù˜Ël†3K؋|°tæ&±<Ïw•?/¹Ý˼¤v¯3(_‰_k³Ã¥øø‡¢w³#[¬*ã½¾ÍàcÇÂtzk<à‚ô®j„2Ýw­¸¥­_óÞn©:Ðn±màù!sÆgn“#fõ=LOýôž›bÌR˜¶†3i\ʄ8vµ ±“nypߔ–ó÷.ó—ŸEµCf d«EµªYªlH>p}KóRvƒ€›Z +‡#ºc>d½^~YÚYyyZÓ`]5HŽõ¸ÈÚj[sâ\uµZ®r}Ó@,ÂSÈì+deQÈ4vSˆ;ÉapÿuùóӇþ—¨_àŒ-Õ‹úΏ™ò/Q¿Àôwóÿ±ö?œñˆà¿­ýgÜþÛÚÿ» ý¬ýgüLûokÿ/îP&?PµJTÕ^@…îAn§]B$bTÑá-êõn„ÔMN_œ¥)à„ +ŽÚöG ›œ£"üiä~ÿA½(]w(]u—ïÃÍSË÷ë¯KT#ó ¤äpöLÀyNÆ]õG{¸¾¹£ žÝûåÈʵ&° ž ×÷yKÃܼ¯µræY%’SWíôS€’µå›p•Þ~ãÉw·Dò„2“<¤±}¿‰i ÷?[ª¿|Ae„”ܪQmîÚ÷^䣽ÚÝ/ÆTœÄlh‰ÆA‡M×ëDÆÔðt#ÎRƒHû8Ӟr«¾]…Z+®üØ/ÝؑÂÔ}y˜ÏòàU)ý» Ž·~›É»_•O–ꏓ¨&åªtPª ¢úLþ†*”œû~Ð7bŒz±Y͟>t­BÛÒ¾Ú-­}…μ=ù`®ÌvǞK’ŽÓ¹U?NÅùBzñÛy2àªyÁeüÛ¢Ã\Çø%‰-Õø(K?PÉKŒš$¿£îؼsÆ]³h=6:2ô(͏3&¯÷Œ§ö†™{œ-Ȝö býò-Qz§qgú‡;¿%3qŠu_¬Ï\R ‡&ý‚I=ZOõ×åçAþÎY˃€óÈæ>’ïAÛ,¾_k‰½IÿQÕ°R:+Fæ¡ KÇÛ·léYe'JŸâém(ä¹Õ›õlÀෑG÷¸·E OŽN +UQù“ÄCܟÿIe~Õ®xR¯ P3 ¤Ã8¤›uÍqË,Ka¼£viæ5œU=屪Fò«$|º ö}·úDéძÞ/Ñïf4ù’t“œf8×°üëòé@]«?P¥°òuµ¾_̆s£AÃ,^ Ý«¼êº$«!ѨLã) %íýmljå}ùŠíӓs6£Ó9#j´¹Ééœ;Åέ¬a‘-lÔ£f-å_—œø—t!íçcNPûæÐÎ8to4cnÏ%€:{¡ÚEkˆj ]…eڑÙJà§&qÁ+³±9jÑÀ¦¢ap#-ÿºÄÆü3ñ 5Q]”È;Ձ¨ªaÊíÏá²iʽ±QÛô`½yEx­[•åù–ž’²«å…ò<—a‹ë“šÜJÄ C¬ñˆrC}uà¢þª?:Q̈4ïү @¬‚Ày}.ò ¤ÃQzɄK•’UØ®bW݀û۝î÷ï¬Fn+ŽœnäCÁÚìjÂý¸Î}Bƒkæ­ëñr{CE¨aÝC¨ÆÌGH¡h#ä$22é+)Kõ/>”íyŒ7Ù)T"î¡»»ëkýíÞÎ眥+RÛ¬îJ¿tZ”,Íòª`=g¾v?™Û2PSäí¸ÛrœÒÉÁ砗ÈðhšsàQ¹îÁC9²`†òµ_€Ø!mñò·&ð*E5ªJÜoôèÜ2òÈN'}R½AÍ´­åL™ IT8-j秭˜Ü•]I‡Ìî5Îëâñ4ÌòMCJÕ Jõ¯”ª§ã±'4yúƯ  lÔ±šl) 8å*ñ +æùº ­Çù²$Q€ŠêðíÅ.‡p:wžÞÐlw7ИÁ þIîԏÖr-~ò:?)ðˆ'ŸL̃’]1‡,†ˆ‡,盇ìæ~ú{ù˜ÿ·PöêF¨íd1ªÙ âÙê—ÜPN¯¯—zûý6°£‰% kríJqÍ0¥+AsO_¢E×$t+©àßaäu"t·rü–Í9K’ÇÃâ99²úÞoŠ¿/\ ý× '¦ŠQ}›)|š@²}|âÛ­XÈH?™&’k{aÃÝ©FóÔjNIãJ¥[–T3¸z<¥”mçY¯Óö8¤ÜMÏ©¹kæù<¯^-벚è`•Ì`ár¾^Æ}èeú=~,Tq-VÝz´È¹Å÷Ü@ªé_—Óz–w­Jz)rYæFR_!áäÇÀžˆYG²¥Ôä`wgÛ}£}ǶÝk︛ìq•®7Éår’b:‹‚§Ësk-ªó²k3§»Ôg;6g5dpšžó-gŠ +oڜփß\æO%)&ÄS¦2»;Gã‡<éLÒ8@œ›H–Ï&ÎÚi웮¾Ø°gw±’ÑÒrav˹]jÆë=gîãv˜5š2Åg:m§ bre`jB66̤kθñ}7ÆLj Ê@Eƒ®ñK.ó9*âjÌñí+/“ÎØhâ}7¿D²œ@ʵ½ Î{3zJ¹UV«–çÌÖgXiѝvØwBÁx̪ôt<‹‘pܬFÓÎf;J:³ýP^â-ôÀq‰ çÑø8Ìð3z µgü¯KT]5›Q•Í0Qu½KF•·°Š*{ÛºJ=Þ éš3µ³³èLœÛ +ƒNSýΘzWŒr7i赜pÒ¼íú¤!aßÖ¹ikZÖÑêϔ§Õµ÷YõG7_õ›Ï«êSwÕOÔ^ +á:ß%âþ±ägò÷¨_àŒý´‹úù˜ÿõ œ±5ôoQ¿À .ó×þךÀÿŸÆMà¿­ý¨Šô[Ÿ& åcÔu ²K€jš÷Ài¥¯© _;ÃýæÄ¡›Ã)…h³Àn5Ýéæm½60ÍÃw' MŽâ¢s¦ÕgWõ×Á‡3PýVêþiÅB¤\+ÁSg×_’*àÌÐQÝ%¢jA^G„” ‹©@±’Õs=›ËØO³µ³–Ež6ö…†ª×œ—£ã¨¢Û”k'õò¡ôn®Š,OÅ –¯¶Dýª¶öÖ :1â8”ËÄågòIíý‹Ï¢*3mGU/£®Þ5®}ñrºN%(—Wù\ïgG6wÌm­ì¡Œò»ªéõtÞÕÎqH›í…­^¨Z<ðPq/°Uµµõ=座/ʵ˅€ÒŠ}óñMJ,îayEœ_’¨ª®;ÎoSˆjSŽQ=€z«$µ,{~õ=°9!½1uiNêðî¡êõJÞÑ°ºéjÍ-䪹éªmÖq”ë›s•«Hœ² +q'î2ýZ>¢MP[¸Ço3=û—$F!}”@HÙ-éȵo’åàågïÖ³Çx´ŠÍ” 9$tøÊz}Vu5lyñÔ ½øfö+áZÿæó+½ôì¬tÝM(ßWðKJ@×Äf#6l®r¹˜)à2?+Žª.ÔùŽªbTmõµS{*Z*yþáÙµÇF´47Rï¨ÃB(i~%ck­Áå¬[ȋ~W¡š\ܾùü̪âËLcb Ba•Xù|QKÚ¬{” ÆWPí—äg-SýÆùik ¡}'w€Êæ ž/=Ûö8Šæf‘l`:| …8ý¤µ˜äE%¶èù›Óß{“ß“¢K"øi.rRã̝Ða‘)e28üYïI“xMþ%‰ª÷c –HÐZ‘÷wÎ÷p +#Àé•rÞ%™jړF 2N8-AGò^ó‰Ò÷Dô(t-u–YbóÉ<÷¥IÛ½ «bïʆ¦Ë6ʐŴ#îM² +ŜÞÒß ¸ÌŸJ¢ZšíEµjƒú +j¿ZxÚ7GÏ@Ë4rç^¨Hzb– HGÖIN󭒩^ÝR Ü·l¼ßT¿+ƒ³”ÄOq¯SœCꛫ6„3ƒ+£Mb®7•|õ,‰œhŠðKòƒ³ +BúÀ'j¯?M ù²îáp÷¼fÈIöÜð›5[¨´Æ斛t÷QbµK¡a¨a¥( ®ÝdJS·;҇;¸ö›bšSȉÇɄ<"Dbþ†ã¬¡Ïñ«òQAíWG/ó®v÷kæºÍœQxQµ…}w`šýÃV÷æíø™¦]Љ®†Äüª°ùÌKNœËq‰ÔoüNŸ¼h +®¤pà,BF7*‘ ÆÒQgâq= ÇBzÀ}Ab£ë·“¨V‘ûQ­× Ak%*ë­Axéö½_2}>—©ªýnî{V¡¤nŒZqNèÍ9©©·rQXušä‘¶ ’b['¨N(=nÇõ{fáV¥¢â;·"ã;µ"âåU‘ÇËÃ"÷Kò9mR.çu>:ávU²§´_»xàE(Ýz–¾*® ¸¦âúÙÏ©aׯê€kdÅõSɱí§z?WÑÅ«.Äà{×Æê܎ž»Œžq_@Ï[ŸÃj|Ä~$­ývò÷Õºæ ªÍ{h @Õ. ¤ç’ö8Z—0LÉQ҇ÙLÑer‹ÎI)só0Ü`fUëÄOh%ò®ž¸¡´ð³ƒ'5]…6†r"Òó¯'„|u=„œÜcÓÔUÂ6D$] l—ûªÄFW|üÚ& z«¨–­*`œ¼†³]+q9´˜’Gòm'U·¦Sl⊐Á±h£*ç§oCrgb­,äOJ'$PœDœ™½”´ ½j'Ö fjªßûÿKÕfÞ0ª† ¤=pzÀÙoHÏV¶¿¤oã»ðv©AÉoFݞ½¼·gêhŒ/…SXC¸–‹q í´ J$IëX6šrë&hJMˆÃB?ˆ‡Å9²²~· $fhÐdÈ¿!ùß%¾›?–üL¢Úþ£ö@H{Ì <ÂU¼D†‹ê¸ê߇\/ +,äYp_ÛVMï"³†¸[NGìõÞÝÑu7kŒ3'2×l(Ÿ5çOš†~Èr2v"…}áêšûõéd2WI=ÌO¤øKò™Ú{ öA¿4&Mൊê¥ýl·I3̒Ïc¢~h¢í]BÒÝKŽë4÷]z‘K*}šcßöÄ,N†ÉY*ö$1HÄOØaÙÇñ½Î1Ì7RwûÃIßí«èàöxå—$ªÀ)M'©N*3ê‰ß¦› uî :ñeÌó2r”y(zÜ5a¾é)nÔÉÕµ7%¶ëLœ9ù¢pw ³èµŸ">ËÌ?väA±ßœÈ³;%NÂÖͨÊFUýOûi?)þ]¢šÔÓ JêD³ÚP¥ÉÒÇS…‰§¨š®hÙM4z¦!aÛ…#´zôq¯c¯p„¶ã¾†oÑ#Ú}¦08ÚcÈ7;2½K£ßœÈÍùtÜ1ŸÞ&ia ? é—$ª¯þ·©ˆí1ª]xçžI-Ø ¹Syç×T ë¡FhZ^7YâPë:8†xI <èkhQC´Ÿ\/àú\Àɽ8¨¯Öâï¤—ûRÍXî¿ÞU‹Lœm·uO<´E¾mô"æ—$ª3ý¨Þ:à@üûmºÞ^íõÊq´I¶Ñ.pbғj4¢6¡IŒ¼û:)HˆŒñu©i Z¼ƒÆaíÍýNhµvuom½³ÑÙ6‹Los< ƒu¨M†kj=Ÿ¬Öd¾b÷‡íÏäcBþÅgQ}ÓDu ÷˜q '“om´Jx"*PmfÑ-.¤í°Aq†#©2ÃCÚdnCùþð¾?ÌÌç®nŽÀsAÉÅK~7ÄÙO­ïE)³Ìñ܊cçùåûÝ+.E¢]YÎ*úBAJÍŲÑîÿ’ÜøN¡՟Ÿ½lEžWõޅÊ¡Ï(ÍY‘@õáÒå%¬Žð 5©=\[ÉÛ âiJ€Ìõ¨^8­¦ Ë^Ê=Î[fн¿XYã`‘ŸuÃù–)Þç¥Fú9;]ò‰O^ç.Ÿžº &¿$î£(yŽ Ý#½k{Ññô@Li–m½°ÑEkÂZX˜ Ê>ni»K2Â6Ì¡­¤Š-—Fù:1grny:;¯h~战4«Ý—ÊôŒŒµ)֘YÓ¦9°'Á´åN:JÝßõð/å“×ù‹í¹•´ôι¦K¥#}f”¼²$°ŒO¡ïãЅ7‰wêP³ôÖövœ×b‘Ÿ,×Çp²(E»é¼v–³†v[Mñ·µ™„].þ]ÜI¡ñ££cÆÜàãátFŒ^©%=âé1;JD]a(á]å—D¿°:/©;ˈÍU<¾”H}ãá.H(¿Ç*Mwó¤ÄÛj™I?û2›œaíZfJô³¥ =ºÕÇÜÌjÞªÒ‰Cq4JáñP)ïgŲ\ ³ËÍf EËý`¡¾â 3ú;h@þ’Hëçf^Gˆ•*¶YȚ½»û¦#n6£gYê«9‡k~ +ºÆñÝLúïé °•Ï£”ñ¾—¥çs C÷ä pö3} »úûÖµÜsH·Öƒ{~«W{\{Ý3{v±Q4í¶¹õß ¸ÌŸJ¢òév*íç4ªt+ª¤ µ¨ÌŒÐ¨<„œÇ95N…Ç¡,êÞÀ/靥‡¨ÜÎm—ëˆ}çNÇS4_‘§1Ú`N‰B‰·fK<…g¥O±R´­™JÝ4M%wqͅúæBÈ܌µýxèeŽº~U~Æ¿þ-ê8ã!î¿Eý'¸Ì¿FýÝîæ?©ýç§ ü¬ýëûU¦)À9ÕNQ¥RkDeu}k‚÷@oƒTÈ>j­_†g[ï¯Ýˊ†Ò©àö°%‘§IfÎXR³*Xéi(šŠc+ær©éfÖgMCßR¶¡OdßÐÛvh¬ÃËSƒ[ëPme²Ÿ„Ëøø‰*Éì3ªì +³¨r¼8Q¥ÛiFeww"{¬eËƶ‹Žxé²Yj]½ÝÀÐÓTX+[Åã<Ã$2ªnC¯N–†,ʎ†d g­Že­>®=”kåù”¢Îø"JÙÈ–'òÄoã«o*ÛÑ;ª\¦5ȃÆ@,ꌨĠ¾ w8–Èâe£ØCßsûiŽ¡SŠóisí¾O¢Tý£¥yíŏy“Ï”I󪘔ú¶*â8 ęîzBî°=ñE¶apó¥}Uþ—ó]úÁI€Ó +O|Hśœ†“_¸lnfÓÃΩ©ý|÷§Ô٧̂¶’u§›”>kÇó'ñ|ÄÓUñ‚sQ±àý”ið¢áñForâ…¤Î"eMa|š•p™?•üI¢ +¾LD•×:6Mó öÅ5@ œ¾NßÕ¢çüÂeÛñê^+Lìh8ÛZŠnf᱒t¸›ÿÌFs²£5즭âl𙊔.C?ÅÙÙðùm¦}±¹lý&¨L;·“hrÛ¾*Q…ß'?&dZGÕBDU\€ïT ¡Qµ•4—´ù ùç=w1Þùºç‡£±3LÛSŠŽf±wux_:iXNsÕã¢ð™ð”®»¿‰RÍø¢–±Y¤#ÄcO_îšÄûõHÖj8s_•jTm7€³Bjí@HßU7yãِ’Qø¢+qjo×&õsƒ‡cé«Sú–FÍ¢„ó:lU ƒÃ³ÚY\ùQ™¥H¨G|Ñ}¹Œ¯¬u@W–)Fz +ä«zæÈ kqdr¤0’8µ÷'ʼn*–úŽÚl€ZñLJÓ¨\I{¢­êã6ê̲ÁúÀÔÏ(¬õÜ~¶¹>ɍ=jn±«»ìÖÐðJ;ødwײgIÈ'.ü¶ûº0íAÓ¤˜ÓY&ù‡"É5Çr“㈠3G­»¡¾*ß9‡ìö›]Q ♔‘}ˆªç†úôÎóǍ½`é@où5¿fµûîm+¯í©”B­õã ¨³´K“ ”¼½œxÐT.됓¡‹Â^:jû1w\WqЎy·Kã&R'´¾,QŧÓT@×! @íWÑË>ªe{JTƒÈû½¿e®Ëå î^*à]g«µ¤æBÍÚf¼PëxQ ˜ΡïCûtÔטïܜŒ—Wisòi³_iHŽÆìKŽR$&±Ëñ“âï¨+yP ¤o(žE}ì¢Z(E5[ +ï÷D?Î^A=( ¸±ß±ƒw벓b¹‹~™-ûuš­§„¶Wc!BUF‚ÐÐVÒåÐfè2hÓviK^) }â«U"p"æ>ª®{çoMàP¯MT£VBTo»Áƒì›éÛD:6®ÚÃ\ø~ÚĽá,cšnîj*bÒ2øvTI53P¢IpPjáëÐä Þ®ÑY’àNr0N2ðíÉ~‡½›•(„èäW%ªæ@Çx Y®ÛªÕjÉUT lTç#ïAÞ2Ép!ٕK]´ã9iE“˜U»”:v§´P;iúµY¢h58dÐà{}3!vy2÷I*éŠ Ð¤ÅðßÂ(“4<ؐä_Jœm÷ǒ¨Z·²ßQÑ@eÙjœÕ»ˆê†z¶'Wó–jñ „’®pì7­ښ©¢3êÃޒ~7ô™'U4ÞÀ‘Š7iü,ÇÎÕlg]%~ëx†±3¤²_gÂ!ÓÛ²‰<ÐP‚\‘_•ïœ*øUÙÉÔºVùXªa{Õ#¿ ܁»ÀACw“¡v5±aTT§è´*4*Ã:“H;]²0>MqoŸÙ¢arÀ“ô:,í+º/b.µu{'qã$}ëŒi·[¯ø}žÇS{õ±¢¿*QuyËGU7¨Úċ×râMúž¬ƒJ㲈 ÊlåiWM÷„¤€¢Äç§*A&¬ó©‚£A¦‹uròê©”i ÖûíÂÝîcÞº’Om|ö$¬É.¯m°ýAÚBÁVؕ söï%öl~;‰ªð»Uï€êͽ8M>5rdëªwµ¦;M¦º€rŒ«™âÝ0òí1ÉgÆ%ÐùŽ·Ðj¥rQÓ´èrý¹«ŒwUNšÆ&dãpXlpßoÚ¨¯{„ʬ†/¯˜ÆJXȐýª€Š/—¢Z5Zécî€h梛€ñœ´7Ä´ÐÄVÅ6 äq7P…I'™¨µßFz•3ÂÈ,ڋ"” ‚ê~÷šÕ?ËÌ7A‚é¬CoÞ_=‚ádÅîçËÕ¨ËÃK/yÇð 9µço>Ç/ˆf¿ê<žŸ®?ÛãÈñ[2ʛgX¹ÄyG8‚^*“ VYëKI:F܁‚VTïz(—h¿–Émk¥7ݖ”[ªHi5. «KqÖn.SL£·X¼Úc Èz‘5]t^ %ê .ó9Fµ.T‹j‡Ò.Îéæ¯Eƒ,è¶DÔù¦xŽ7­Ãd eC ׄ ÎoVˆ{°Je_+fìí±qô6=º|Y½b°J<àûr^G‹Uº÷ÓæÆ0“™ñWavê”ê³ý­ÝUèítêøÍW%ªx~ž›[RgÖ¡U*¨ó&ƒÄUìÊe‘hê`üÿrмBièpÈ'Ȧ¯¸ÏùÕnŠ«Ôø©.³UÅ\ +°=ß͖ç™Í ‚YõR¿OÑrñ5¹,3© ås“6ß®ŽÃö°õ‘Ø„üíä/%ª½/­O¢´Uvہ:ᴷЁB ,€8x¡ï£V‡ Tsz¨PlÅ{Xó^Zªô:΄\lod¾8ÄÌ-pô¬>Ãø)Ælâeñcðàݍ­oëÚéAË÷£Ámĵ[ÏÑ(œ§¿*ñÀCÊkWg 5Ñ=ëBs‰]i½ÃmŽÁÚgQ±3ñ k¤öX…¨oû·J"‘ÑÂJ™£9„¯§3tQžOÍórBU¸Íø±Âcæ#£Wg‰&p7öFÉú˜JÆXÎ'cu Êck°êϼ¯ÊiµœŠŠðJSü%AÒôºvʉªNCoí3»xnmßtkÞfôÜ_—úÊÏxûž5ÃBzrcƒüø)ê•Ñ[¥ë£Yk•Ý¾7\–áÑ@_.§ƒu4[ô­ÉxÓ߅ƒ}¿ žS[’=H_²¿ ¸ÌŸJþ$Êk‹@¼Ÿ¾ìél…3Š¥ß)œÕy°½áãõ:%2‡Å¾œDgX‹¥&ô¨ÉŽÇ©·4šåÎÚpYRâ…1ƒM s…3á÷÷-øÚsÈͽ÷ö¯^큤ºØèë6ßH©ˆd½C̤nû¦òïŠPCñÚ(:3~.ñž‘ÈâaڇšY7\oð\nrhbvF߹ɍáªpÙ*ÛÜp C‰Eß46=‡0 ^í.a]lȓ@ Ù1eÄöM!Õ6½dÌö 'Å.GëiAk\RoÍ·í¾›"ôÈ~U¢Ò0²¢ÒšLE%l¼‰JcëÃt1*•àK§·xNúQ—–ï[÷ø(^9j³ZmpYç©¿Ïr¿ÐØoλiw.ݺ¨g/+8èô)¯Š9¯ºíÊ®—›@hßEdý~b3 ߚ\x÷w‰ÝÁ?–ü._Eýgœ¥úoQ¿Àw þ-ê8cƒøŸ¢®Ó§¨„òé¨Ä-·Qis¶£R²XŠJ[œSrTšÖnwÿ„Äwޏ¯ò51Y·.Šžø:aÍÏÖp³:—wݝgßê°WËF¨ëqé¢EŸqÒUtTZsP×BÜOC.4åéÊ5ÖõŒý'‰®ŸÊ@ÕN ÉêûˆëÍ”³ZTòo‡¨tijO{×Üq€2D²H¨{Yꅉ_¬ˆ‹sù2Þxpªrpϵ(ÞÈE¹+á\Nå\HCpŽÕ“ê´5ßrÚzýz¶›)ïægÝäl[ƒ;ó •Ø +€õ\ÀyÆöŸ&À½½¨d`¨Ü(ÀQy¸6ž¶¹‹îí+Ÿ ‡b©Ì'hß76©)è›*kÞµvî™NÃn“;aÎñĐvø8°6µ^ 65"u»H®Ý»¦¦|œÇ¾€nꦣz¦¡ù§öÑl>®¹¨œ!Ȳ•sJ+*#}4*3”õtÂûÞûùëK¬6b3%³e‡þv“Ÿ+*½ñê»îÁmÕî¨C´$¦sÊüéñž«'Ð᳀¨¡•|moºùô|õœiž”ÎQ×徫?“Øüc h׉ʙ(•k:•¢æ%*/ƒNT¾CxlKԕüºw¸¨p}&­‹¶eG~ «­ £JºÙ‹½^4ªì=ãé¦/ѽ;(f¯"ºª_ÖÑg$ONlÜ £ÀéÔ¥„§Ä¨ÊZ³N(™ÊÀ4̅áyÆ4Zë•}ééÌNâl|Մ\•T8+¨ò\e–áþR>©½?N¢ru”€ +Ý@Ë\în€rя*¢ŒDë¡G•S)º“©Y6LTÉÚE§Ãþ΂gL>#öƒ®O¼„ÓÖ,Hrߦx²¾üyØl’öM=K«ô¼ÍA9I:_µ%®²OŠl¶9‹(æ 87 ¤P«•©7•é#à$Ö½«hPT-&U íÇýjÒÙp’ðk£’éž]ºÁþØÏԘ*Ô=,$ï,™Y41i’Èìiò¨Uàãqånbkèsü{‰ÊÕknàô}øš4é8»™'2Ğ9®ÓKê˜Wg$n®G|—¯c@Z_–Ï£“j×¢JªO‚6Z}FUT¨GµZ  Ê8ÕK‘÷èbê+œFÅË)zw¼pLÌO«âe¥7ÃôZ’¡Ú’s)dIE)|}4F0§Qç°Ú䓢ŽÕÚŽÕ: ¥ÃjåÄGÐ/ÈÎ}4Ð)UÞíGTÕäØík/¢zòã Dõcݹ½êýš×Y½,ZŽð ¯9(cq5á=¦Ùn8>nðmüè< ÓC"§tDˆš#DVŐ ÂÐ&äÇrE?.óûÉÏ$*Kz<vÖLTmï±á¯ïM¢úÖ'×[Ñåƒq¹8{9éÝwBÓ²h¾­õ羸Å?KåãŸgïúê¡G"7€’\u¶3GyüÉ¬((qX!îtÀáA‹ÄazÃc0ÝÂaø†IÈ$*Ÿ¬ÏÛ³R¢ëQeº‹HM¨Öó + Îã¨þ*â÷áó*\ žkûí^ýíd¶å²Ñ’«Uy™mÕ¹ËjRsÎhb>^nB³-Óڕï—Ñ:P.ðæœnл­U=ÆCÜÕ¨f9vJd&4î­¾"Qùz¾F•¶Øˆ*;”ßøyÕÈG.ªãÌàѓÍu“Aâ}¾ÞyÉM•ÉЪ5Aòo»(¸3¿D¿Ýwéi“2üÒ¬òήáõ5i†Ã%I"ËèØãÖÁ0Ol«÷¾+ÍJèΫÈ~ùn@{µÙûùXª(ù]¢Jâ^ô  +*~ïÑ_J?qœo† ©Ý÷ÛéêÂÉÖlÊĚ}W}÷Ó¡hË›*ù$Y¼”Içã¹µÃf&¶MN­­ïFo9mäW ùȰ˄ӠWô.\ºAë/x[E’hÔáî UŠoðöÄÏÍo’.ªÍI´Ý^çjÆÇSǬ­;=#¸œqu6¿+b-½éùÂj´ëËÔª4\(yæ0_+*¿È †ñ×s™XfðåS~ «[)<¬;%o÷Ÿ!5Þío+k'Éx„ÉÜùâ\Ú'[ӄРŽã¶¢üø×ãÂҌø‹„ó¨êè“t,H­b_i—ÍU)<ã­/“ËÙ¾š_,‡ùú|3mæŔÍʑÏÏLþ@ÏWÛ<º˜é/h!röîO]?)Ž*ÛÚ=ª¼ÊŸÕ<Çx~1ÌΪ”“ñ +¸Að·PY‘|GÀ}mÍÌ%Ü+΢ѶÆC:“öÞ3·íd¯‡\O-%m[¬*•×¼h&s³CªTŸºƒÞpŠäN‡‰?M³ÓšÍSS›ê¡³­\‚¿ šSðœŽúQMÆ úþ˜¯Ž¤n:ÏŽJ~^¿ ºÖ`3kF ˜ ¡/˜Åà\€‘{XfØÍM5ùõHé+Kù䘋uvç%µÌþioÚ­*µmÿ;zE±¡QP±AÅ{l@lèÿú®ªzªF­}×ï—a¯±9MB˜93 c4®—úé¬<:b”\i·8éIž´’jÎ¥G3;“Ëôiò?äA€Â~*‚¢m¨ç&’Kǹ4¹u³Kk9CÑ™8Ԅq®Üð;!“Ûô±8Óí\bÐf‰Æ¨µ¡:f-§ oaÛÊ¥ÛÝՃ–ä֙q-«ýüSšK)‰“e\\lÄCÅfs .úÁê¿!qÿý +(4w)@{oî¬âràÛ㠑Z 믆ßëæüo—¹ö)]ŒO¥r`« ?­)Ã3'Ö«â«.spø/‰X_WUÅÓ}ÉG~ÆÒµߚJãºîL’48®mžRIܐÿ~-^9£»dmtn>¶Ù·aOácV½ºmi°ãü¾qÑÄe§z Nš’ÊûMÜ]&®zƒ¾Uâú„}¥eî»CÄï¾OŠ +Ö/ MJ©ðN_xü¦(\—ä[Œ+{l/–F,m*³ZPîojÃÓÌ­1Æúò+’¼Îž 1Øh⻽ˆÆÃ¶Õ ÓËwñSÄæ +í:B›{ÍV3Ûî6.=X¿[ ª£—âwï„]Û9òNovN¼Ó€£úƒí³Í$’¥ßF*qN‘ê}mÕ‰2/W^û9W™µŽõ +=ô +£ýÿ›ý}¨,f½»l‘ïµjŠ·Â±¯}IâXçÞ»<µµ˜U¯­eæà2÷éÓâºY® +ÈéÁñ¸ª³—‰ÕdéhÔ®™‚aT﫶Y­eZVeÖl,ÊñQ^—ívëÀ|Ï­³î nŒBÏ£ÒÎÜ&ÙÝðè#ÿ/¤ÏNN^Š|·#¾×ÍĶOæfSG}%R™³…¨ üŽwŒì‰£Â£_ fVÒÒª÷¥W^ÛzªÂ#b®lëUŒùž˜<£¨"“ñ™j©ÉÐ| ¹sJQ¯U[E<ª´7ïiê3\@¶¼ÍÏà/rð™à¼ï#oµ4ˆÛྑ8q_D]€K(ü;‚bÒGãwaõD¢RK½FËqéù8«Õ§¥ªÂ#²¹úc^暏yJLÆ7~£ î€Nï0òÝÜm'} ³Šø§*w¾ŒÊŽ{¶XýðgüYg üÿ•ú?èLÖüïRYà»ðAJ=d€(,s€àR âàvq p]ßg?ÿ†Õ3ú£c*±TŸ•NùɪûˆbNz®ÜÁ†ÒîK–2î˂8¾K;K‹Õ!TÖ®èŸNp-Áé$0èÁ[Žo»?#)4"S‚v2,ÕkŽø|ÐD®èÂ8¡€˜ÂN—P%êmîbOjÞß=¿Š˜ª¿*`L?Ù³X~Ìcš¿ˆŒ|_n2Í»œÛ÷ÔþÛ7"ž £Â #®Ã ¾8GA ®.öOó!qtÍöÖÍ[ÿAU ÎKëðˆ$¾·:€h(ÿ°ÏaLôómÎæê8±g÷oÚ/¥_wêL<§#~,T¦zÿ˜ˆp_¥2{:´ÂÍüÒ ¥û(É`›‡Yø†»ík½ÀÏ¿2·Sô.ŸÜÍe°wÜÔ{å´7~²<îçø+Q ÔWÛD¶¥F{§Ù8"%å‰ +?y3¨<ðâ®3yF_ɾª—ùäFÒCäèĺ×ñX +·y§6æ»ömÚý[«no-ؗÞÐ+âDH‡gkÓô½tuî±vz{(,:ö~ð­Îÿ @Ô›ŸB£¬3 jBùk„ãr©çy 4@ºˆ Èzæçû™o6û|½Îù‡]QË÷UŒóáv}©‡¹½ÝºµÂ~÷†Õûfp¼˜ó ÝÜ탶€'»Œ\Fö$ôÒõ‘ë¸åp·÷áËoWy³ísæLÿ @tZX®s¨Siae€4¿‰-mӀ6 JÕ叫Š~\èÅ0¬Èɹç<’Ü©Þ3vF‘ÚZ¹i‚Ù܎>È~m쟀´ôÑÄ»¦ÎӓÝùÙq%ÿ°ŠÕõöyñQ–¬õ7]ÿÞæ_'ÿ@Œ ØZë› ºm²™ØÒw@Í^%@]ë]@í‡k@ ·˜Î0Ÿ¨b §@= T{X w6"ß´h¦þÌFù¶žå‡~a™^}²¸»¶fè}כ㚡»gp|³åxs±^Qk¥.Ž£".Í?«ÔÙÙ_~šÀÄ )%P³“ؽtäkÃ.Èñ  "7ˆ{;UËWì)¬1ú¾ÙÕ¾ràÁ·š©Ö Ÿ.¢ã됈ìKȡޙݠÏ#¿Ï»0Œ“÷ÍfqSìÕ.w²–ÚÝÙÝle`SûÂÿ@¸Ö–ëé +o^¤=›ê²zý•€žŸ,ÚÉ~#6<}&±@Üo¾Ñ%°§(Êô}‹º\ˆ´tç¦æÓ¢we¤Óä2fÛóSÏޏ‡æïîØ÷°þʄ½Bó©íu…ñ¢Ï¿sS^ó2ùÿ"q9þýÊ.÷°h¯Pê}Ã2ö,§ü(ɗ…ë{²5Ê÷³ùyùM5=2]üi³K¨s÷ao.R­ÿÌ \ƒKþç')Ƨåì´è²;¯Žµ{FË×ëJvµÔñÆtqÙ§Çss´Î&Û^!bw:s˜öŸˆÏêt> ¾ÇŸf(î5ùÎ'J2iPÃ(èÉ^zã—X2~E—>òØä6Tèô?• gRâåY-6¼MéÝ<ê2Ý9\o¼gÞn½–³Û[WfóƳÉYKVáMg1Ó³€”éX’w¬T7ÐÿŒ¿¥† $~­ÀÇŸ%nßJ\@‹ + + u£S4žIõL/«ß°íµ‘ ø\ÎöªYvµaºzð‰˜ÛÕ®)i#©†¶ÚY­‰¯åæ³G¥7žÎzh-™¸g¥Ö1id×íñ¾ejãý`öŸH,Õ¿Hìx€š½’¹Uae Ôoé +Ãm²³4©šMßã“px~ë‡ë];SQäG¹‹ð`0·MÌɪù­XËÒ«ÖâSþ™ñëÂ|„VÛÓ¨W[2 &Úº7Þï'Ý1†5Û££«è£v‡oAHÿYº:°4a¡’zª¨ºø+¯“}€‚Ÿì-̱u@o÷ãˆ/”VfáÞ®4^_åëi«Iê2¹ìV:˜¹~–ñSâòÓÑg&›{Y·æzäbJoDvŠóLºi\~”Á#¡™…>Úüð©(,R›`A¾Þ[€‚Öx:÷$’üSé}ýWJËMï$zØ£¸—¼oÎYgÿt;~íD~VÇù.ʓUÊú:d¬­N¤I“­ê Ž]ˆSg:§ö ´ÄÂ<5!n?Pÿ’,ÕžR¸A©L–jP„¥ºZ$†_;´šÆ@1m ќµGküÞüãs}k±çžÞ%?{÷ok§ñyØLÚ|M—ná=&™ï°,—’_ëÁ?¤õS{⻡÷ì\KëŬÑês†Ñ©ý©µüAãÏd+:R,ÃW­p ÿ9/’ý;n?y[2ßÈeí%lýNåsÝ`ÒÁì“Smîœqýìm +qYö½i0³Ëèmì:«p8ÎØQOÖöß.ÖɶÁ¥Ž¥µn³‹5Ì½¤õo¥a¬!‰ÓŒ¯(×ÿr˜r©ñ@õú|âÓËd‡kòûaé7K·òÃ‚¬…ÅZ«u]ª¾åöÍÈދËzÜ®Éãþ8>´g¡ƒýÙ,çÄkoMoÎ@ˆtù"­çYä´1yÖôëÑo¶Oü³ÑÑg¥ãì>õn3ÉäïH,ÕäÈêA½”z¶¡Ô!¶´u<ƒâ²ÿy­Ê…ìú’yÿ-´¤SûÍôÚ{dmÑ\¼´'Hc;U9o?\äC9AÜ.±íAM{$ãUÑ骺ÖíGo›Zeºmè%>÷×öYnw¾Ø>¡ùÏ䁀:]øö¬<|Ü SPLݜ·µ-&¶ÝŸïC~;~ϸ4­Ã×ZÛmks5PfÓyªö^Œ/–¾Ä2¹1p4ØéãÚÍk~úò½q@2i¥ýЪ +©¦{Ý㬫_i¥6ßÎJiYñBÖFS7ÙKUõ¶âŸH¿xä{öy—Í +cXšÙõsëV[ÄÖ§ÎÚ}k³´Ï -yÝÛö:‹E§<´Úî!q L/O{Í8m·Íóeݲıá,·úÅédäàÖä2½™Ô{HÁPÚ¹s«ÑdŠZß,êM±¼’šbjÈÿ?oÏTa—x“ У½ÙA?IAm(%3vfä¹C_gµ6ÿ®ò²EÍß-“³¼nOk[ý“ÝNZçµT±uíP÷;©P®Ü°œÄžÉĊľºSiÜÆ2#±ÝzAûhõ“æ6簒ˆ¿þ @±úPÖ €BäÊ h[ÚUBOø‰ªwy‡Ÿv“ÑÚ¶]þò1¥2s%Ì&W¶Äšüˆ’{N”ovÊR©£¥(µ¯êF0Sú5}+ßëù³ô*ßbLʘ(ªNûÎLŒŽ5Kª¥,C +¬&¼·"_ïÏ$Qùçø+e˜0Dj+)@ŸÒÂåc]Ÿî5;ˆ€=q›sic-Ùmú<ϵ¸ÏdpjÃß+÷\|'vFχªÉ‡\ò¾Q7±«\—a½¼×§RD7b ògQªHoaÝaB&ˆX!s{M…Ïrg‰ü“ˆ³†¥‹/c¤ý€zx?]g¡yÉ^çÆÙ¥+ãØCc¸iÖ^lÜÑL›WÝñèFÃÕËE{M—:w¡Ï' ä%Õ}¤FáÉ4êcÉëÖ_V⡾ãΤÄç4%ÕÆT¯s&•`ÔaêÕ¯Ivv'Š«ÐlÛ]³Ã–’ÉcgiÎuýÀž¥þ•5` Ó"Uó9§Îýúˆ=õ9ó‰;øϓÿÀc[Üì<Â2Ç»UeÐ_õ7¥áüó•më"ôh–·ƒŸÄZoݞUևÖN‰<•ºW…y<ïòL\ñ»o&]§˜q%B@.µ"ßŠ5ŽzëlŸãÛµÀ”Ìsj.ªwÃvª“\p«VbªZµ¦ò’¾âŸqÚéýÁ<Ìû=è4çi”Ñ'ÃÒñjÚE?Ûw$•1h÷U×m.Õl:-¶Ý ƒU¿^}scIÊÜçbæ¸ÛðN¯à<³yb/–tcé·ò®1_!U( ¼òÚ¥ +YüO^§{j•ínjP–òµ9ó½Î\çògì穧²*ïülý€c¦V”‡õgÚëyÊâޙÐ÷X«±”Ú%Õ¼Mý>ñpÉ®K(­òŽñ¹.³QX:2ZÙ§“zì¼vi…GË8§Æ…Qhëùcš–šå/!Ï\©èLe ¢­ü ð6ÿqå«Óq]­ÙleòËZ?}4 úh/´ï¼5jâÎa¢˜ =—âål-fþÈë…약Œ÷šÉ[ïêDî¥*3µžM¼Ód'òا SÚ éZ ¹3Râœ6ioÎué®Ð›.«ñ²Ð¯œB1ó +Ålîþg̾ÙSqtè>ÒÝ|hã¨i™¥«6èëZ”¹øÆ +;å¸nñ,Ԃé´QHv…Ïqý²„ÓcFÉ#³R³ø²‹Îè¾)âÏà@w¹‹W¸Ø޵Зî|°¹Çùrîš|ªF4ù:Õj$_h*]õϘ΍–ªÛ54 8ÐçVX]°Öل«>1€e <@¯­ŸŸGçsø÷ÂþPìä›ñ°,@Ö2vjl)Ö®l5Æ[²1×Þîç8xSµÔ2¢…ìá9>ï÷XjìÃÌü½ ð‹¶ü$.Ç¿_˜)B©ü„Z(µ—AVñ[+€¹·'À&9`Š B½FêÝÀ?œ<(6zÏ~¡Øëùã{,IQ|{Y{w’ a´ßTgiF½ÝcóbÚ'ç1CFÇ°}v^®¯}ýkÿ³Õ1ÀÊxëÍÐèIBu€Ó-€}æ€ãÙ`÷ +õ6$¨w>„zk€îog€á¿¢b!ëÝ4öövŸÂ»+¤+o*ÌñoÊ­¨Ñ¥Þ0¢Þk4yśó¬nçnøÝ’E²³Zì®}ó»:Exmúgü-U®zšÂRzVaM‡…8èøئ¡XC†b—P§òøù,— z âX¿çrïS承»ýgñGßµè²JKQ¿Š5#úÂö_AӘþwéÞc»qº5…Ãázøæ\* /ÕÜOþ’ìîžÌÑ T} Kõ±ð&w€ ­À©€7ÿÂOËÔ»-â{…Me“ÚŒEoñq‚÷©ó̽ó³3]Ñ3åû +·$T™j¨¿L¾0zÞGòú1ãZ§0ù®Ÿo2ûS$Öl/Õßώè¶0ú3ô Xs[$ážv\QßÏž‚å]@46iøéQ¸5¡Þh ðá@½µGLŠ©ïÛè¼±hPÜæ£âr[y™ç)ÿ*««ÆóºÏ‰þ™>^[Á כôÅOf"O‘V[» +0’’α—òßñàÏX<„Rí”Zöa}ÃÂ_^/±é{€xDY@œ‹, zµ6Àãòàzí»›Zr¼Ï–ŽüÌÝn‹â«üìTa|Փž5Sk>"b1|Ì6áò.éØ5 :êé-ø›½µ™ó'ûRlŸèËøIԙŽL-ØkØÞW€Ï±"TI Yv΀l—ˆ>HrÒÄÔ\@½ú1öåù¦±w**]\âUi÷JO«WgÿšâáO\çØNÒÒî ðtnhkìŸÙœâ¸YÐXŒÅÂڍ®Èpó–mc½¢ùöŸpn u.Ô9Jû€È +%@<ÔyÌ\F¨‰8¼rï²rYB½»Sܕôgˆ¹Ì+Lÿ)©27Í wðÀÕû’¥û÷”&Ú¡âo—‘´>¹9T^ +Zoº¢Þpý™JÆj«§’¹µ¥–·Ô?ઠ;€ØßÀ6J€èʀ´'#@ñ¢¨ÙÔ‡cƒ3ä‡Yÿe÷wcê<ü,({_.ùäHµüJ¼ËÊ«nZ±f'ÌÎÏ¿ÛÏ4ÉÞgÔù–½Ùæ:dåa½o۝A«µè1åÏø™ÂëaÛ£ß[ØFå÷}Pˆ7Ôezù‰×Rc®­Éhì-Ýc2…÷3C²y/û£•*ž ۍÚíEÏ%[óáù¬ÌÆñTþ3þÖɧwï‰Ûuö¾¯úa²õ“Ÿ¶^Õgzø6]uùšéŽó¨¯§°õÄÂÀP4p5·›ì)¸¨—Aéüñ`ĬÓþÞÕCáÀL7‹‘>Y!̾¿¸” +í¹™>7gÕ`ؘÎÊõºoªÉHúçø+> g°µ~`‘^–PªÖcr +Ց»p_ŠKùƒñš÷‘ÉCy+ː(Žö~ º—ó‚ë'¾€—ý žÎ)µˆ÷Á$•ÙUGsr³pZ•õj³o/µµÑ_ÐËg{6áÆ­)OTKb3òd=¿‹¥õàÛçÏn×x3·uz2®±°@;‰‡Êޓ {qP°11š–ÆÚ3mý°}/ZþíÙZŸ¥Q¼sµëñxðõíeÇV½p#mÑhÕTÆ)Ûëˆä¢v„Ù};Mž›)_¦U+•)e~‘Ç»ÏZ£õ>?:Ræÿ€Ÿ?sXñÔÙ ¸&Ô9^ÌAAl…É>¨Ø;ôüäw<ž_Š“ïÚÆiA>?¼_êMÅ>˜3r³™Ìa­¦Ñ“}º®ó[oñœF,Ÿ¶lO¢'k8žïK¶2:ÖuiDìxÁ<5˼i yÖ̉ڗãŸ'ÿ¿¥Î +{@¬³/ØFMäC?1& sŸ\4…Ç®O³·Ë{׸Â>¾ë>ÜÐD‘µã‹ÅJ§Ù=¯µ›=§½£µŒ‚ëx¿ëF£ve€™F•ÌB‘†3⇃QŠ–Ê;,Qmp;Ý*À_i¨sWùùù]â[~ê¼ãAIÛ à[×8 s©—Tê`wý†—‚›—ÎJÀªÇËôe칪1ÜäDfb_Ñtöº…¶U?ev#wW>}ãzT¼sºÏ¾Û\ZøFÁã’ïOsK®o½ç5ˆeµoùËʟˆ _:»Ò>ö|òä]€m“\º°9¿'â)zfÇÂ7,´é¤¸¾'fÍkwŸòáAôµmf”î.Ï;o0·¼i5u2ò>¦=,§®û^ܕ/F}UywՋÏ™Z5ê]–5V¡f|¼FÕø¬årO¸·ÿ$ñ¿_ù|Œ +6|ìÙ ‡úä;ˆ›gehëê¾@ÍðïÇWéÜÓÕÜy¦èãà3ävK-[_ìA[LÈfgZ +½1i!ɀ}X)¢VoÉÈË.*»N»kîz[¥Úùʙíà·w­ã”Ò•.ÒÂ*]u@–»Û}‰ù3þÖù’@ú³ø§ëta×Eç„Iln»çf.Bºˆ]|^Í}¼.2ÀÓ]Þ¨£`ßÖue&™©æ?ûíáÛ½•±t±yzªœÎ¦õÌi~óßіeŽkš“BÓûÓm¹Oûå¶×~3|ô.þ€¨–l¨·íŠ½|@¡”¸}FkE¢<¹»íç4˜,s»s+ËGsSH–üWXõFê|QÊ–?ÖÍÑSûR_×»:30t3}µ8K\ª«»xiì²ANÍäzlSØ «-––µ²³b4әõ"}øO$ßæ߯ÀÎI^bÞÔìP\(ú•sëÝO©w½© 8L§¦¦ý^Eý°=¦9·†¥Ví1¦ÿ (±±$vó@¾"¥“P=.oõî¡=ª¤$æïæ!N)‡­† +åhÒ³²%ÆW¢Iùb¥b8 +ζ‡!¶n£©ªRØSÈïx&…±+…“‘ƍ‚*j¡î­§Iש8ø¸ÒP™NIMkjáτ;ØòP<'{â@©Þ‡» +§Ç뤛©¯k¢eî ÞÆŸÉëå^ç«í$Iƒ›œÇZnø ¼×2>…N|Ëÿ(rêž)J÷\èÊæ#7—j‹ÊIä=7+€FÔ_…–*ö!/²‡Z=Ÿ2u/¯ÿÏæŸ'€øÌ·€2&(Ìbä:/g¯Ã»p [Oß÷J—-oò\¨Ù¯ou6ÛMõã¤/ÌïÃ؃žv¤;Ìd…kbïN«Ÿ¯*½Y¤Èãé2Yº(Æ©åBøÒ©«‘ˆi¿‚ÌÕºB|XªâtXÄgéY“F¥ógR€//g~u¿Zyd*^¦žd©î²ïÌi]ŒUzV2CÏÍÉø6˜ï†ËòùÚÓ_ñ«Svò_-Õ©¦Uý±Æ•âš/ÉF"è§tAy€ :E‡#“˜=m'§Ï¨!¯Òv‡ßèhÞF˜,,<–ý3ù&œ;¦æìZÞYv¶Èù:]•ŽÅý"Ý1óSršWƕýr4L/ӛ驗Nå¹N椵ôþ©b飔ÞNNæ²:%®:µªE…ëôŠ=¶CƒÚК]j MdªáÖjכØç`ˆÞå4}Ýâö§býW$YªÉ1¾<ºÎ¹n뽃U4:?ɝöCðû³ÝzãX´åGÜÞªTøf0.Ú*ñP/ûÖ®&jûR¿[ïPŠ×ãH̸åïô œ£QñgûПÅ Ú®ÖrÒ´ò:8^…'˜o…O3rezîu«!©ujW’iý×izf8æLnnZ­nWÏq}º¼´ñØ}$‹Ë‡ßÑ9××SJפY·¹|+Ù +µÓ ƒó@~-¸±øÝÝçB“œ­9ÏT¶Ï–añ}‰Gµ–-¤*].!wJø±M“ôQo^ïÑÔg¼øÛ4ͦÃ|°Sy³µÈçM­Tÿ3ìÛ,‡b©aä¯H£óqÄk8o·í´©ƒÝÏ4PYÌæ ΐM–~†êDZ *|®3a¾^u^Ú 2«¢3zíŠøóåÒ]îu-\ìøÎ)’ÊQÈ“¯ÏþØ¡Dì;"a›õd{ß㯘ªU7k 5¨J€êaTOsJõêó”•Fr^_Åjã•×zF•%L¢™Ì%_.:fT£=ëšD…Ëb#åƒõ¨ž/gG-jÒ´É—;è‘<5v4ÿ·ùW*{ÛMow¬É_ÔYV0ˆyåÏhÞüYSˆÌÍÈ}Ì9È­Ö{€,ì @‘*Pz5„Ÿ>@nì Ë! yË„|ë ÷"Ç w– ·3›-}ëÃÁX® ¾ '”0+ È1Ùä×|@oš;û}Œú˨0./Ÿ0œ€c¾‚`…u&=þ?R²Ÿ ‚ÍPì吷—h¯'AøðOšäÏ֓h± ÞEê %€ÔÓ€P% ê•×PïÀ…z77¨÷ƒÜ —¹KA,9‹]¨·?[k{KÒú9¦O‹ûÂhÌnÛÕy.ãŸ%XÉñ¿ µ ”z]›)Ù €ß#@ÙèyQ‡øL:+¹í¾P¬[„bß2@ƘŲS(¶½Hfþ“m—{PtR û¤@çí}”@Nã‡ëå»u7¯!•]ßßcf°§å»€3¯23øUlX0Ñîg…$"ìl€ [é*«–¦Ë´Î½¬RPoXh)§$¬  ^~¹ú¶ê>€z¯ÈEIi^+$;¨B±7äýYŒMúIúhT‹ÛÇÔ´VaFøÌ}¯XŸ\˜Ã¬zu‹_Ðî"ëÒrl€Ô”X'¶‚m s `ãå*>ÿl=‰Fi ƒBê•a=„Æ + «¥ÎéõF€ä @² XšÑ–¦1æIvtžóûg•;nÃú[úPµÎ¦9ð¤âµë*•þx›ü 8]ØZ/PêÀ[Ԛ^¶\P/ À…ý~7€y°¨0¥P†b…&@çlÁ%kÏé +ÅÞ^™¹ŸºQØ<@jƒZ|ØoÔû€Ñ›ÊÖvÏ{úqë~níS7zvšu‰«ÈÃÑí´~ð¾çÖ¯èڃ:kÔ}’a1Â÷ÿ²{ñýHø;»¸Ï?®ÉÀîr`]£°ì¶àù~`l}ûÇÖáx—½zæÐï놞¯é€°O”Ÿ7NµkÑ,vOs¼¼t`³n·»¾^|²ðyÈ%»¶¸E/SªÍ}õSþÿPꉂRÍí™ãÌ#ñz/& ú3 fAP͘y3tS|±ûMrÓò qÿyˁRL⠇?†ß N™…“µü™ +֘ìÛô‹OÙG¦Þ’o®1nú××½wŽÄ“é­ÛŸ©‹HÚÊéÀ!Ò¡°Û%s»°2‰¶Oúˆoޕfs•[ߚ‹óŠ•ç íóÓWjXµâÇXâ*M¾"^ü“ðÀRÕ¿miÂË¿Eëm1‘Q' ?É]ãAžK¿æœ‰=²ƒ GÜdÍg3´ê„Ô>öý*Þ'õҎŸ·ˆÝ\R‹›lF©.;~ƒŸ‡Çž<}‹f¥>|oŒ:·‰iäö›á • +7ãVŒ +§Â ìó'ªÿ“>­ÿÐö8ÄñwÌæ`‘:ã|–F r”:¦ ÔEiòŠÑÕìî˜Õup+½ÜKª°\j«ýÓ­ ›Í;“ÔÍò¤GÅE¹ú®Lmá'j‹—Gd°×‡ƒwcØæKvoîÊçž0i ˆn›ê J›ì µa@äÛدøyß8õ!|ìPª»9ªR°â9>ö…ás]Qa×ûN|¶n¯NèZ>9¦I½¶_5L¯Üñ]„9‹š‚å¸8iNìʈzFÂàÎ +^œñ;Fú9Nꦛ‹ÃcGkŸ±Îaô!»Ft!†w·X3Ò Q*!¿êç΋ÄEs{;PzÂ{ìžõG³‡'¶]p‹<ã’^–[à?Î~ž÷ šÄvP”2³·ÇbVN­R£Æݪõ¤Ž/v›µÙî–é¡Þ/h[-°«)½¯ˆ6¥ž‰¶{~bìùD;•Nþw´ôù Ô!À§o6iv$Ÿ…ù˜{ųºâZð9aÒ8á…ÍÀ©œÇëíÆÕ/«ü¢ð˜¿ž™µ+†I88:ß_Ø°òBó=ا»:fõ«™©kåë«×Œº™e“ÎQ3b5¢u?õ0-ÐW°ç1Wˆ~ŽÝœ~Ù_k]þÌF½r°T}þ +ò£nâM¸gVòJA8áéó®ՎRhïE™¯Ý&êؕÎû6K.Ñø”^~†“Ö,Ó[—7h¯†¤îŸëåÖ´vÔÏx×nlùW’yßÈ­¦0ùª¤ºÔT¼9{wÐVí!­»5ÌjÌiú;ŽôÌ¿¼^ª‘¸}è.ûž`}Œýã¼SK)/ß`“Ý®³åJÙ"WÏ\ÇÍìs{·Ö͑ÝzõeJ]ý=Èè7ÔÅZ3“.¨JÉc§i·ê]òbɗÙ4¬Ss•R´|h4&"ª¦<.§M˪€•“ãl£Ó >0"¦Áýù™L |\Ï州Û°‡Í ‘]Ö¡ØÕµÚì.x­5·œžx1ãü©ÿ͑7»U“¯o—<ýӚ?WµaU)¥Ý¹Wåëñ¢J£Þw,Uøð&>V«’\ÄzTD¬î8D9dÅl#—ÿÞ;L9’ÇÞ7v\â*=÷Ú©»í„‡ûf$ñ¼ËmÂﺰ·K‹·5¦­æ{8.Þ¿ËÁyì }ü<µÍ~kÅûæKÝq~Jé¼5\j\Uª®¸¦ÈíÆÁ.ɉÑ%ˆë'¼«~Q|Ô§”dv4Lî…*ŸC1÷+‘þ$;!ñGt{ =ÇÒGN¥–íêK0Ý´«ÝÊP`±ˆA!‰l߶<NÝ¡Xò¬vº­Û!4Á¤/êÞí†ÊéHù懘Äæe„¾*¤³ìŒo Sw>G<¯(žÿf+e>•±öÚâä5FÄÿ<ù6æÅ:ŒOÛM¶í”ûF{»EÒúêbaÛz–ólŠ¬n7GŽ&Ó±0XÏ_m£+£ÃöDf­µ:^©z.ã(}ÊIrnåI¥‹±É"ºѨðM¼ÝàœÉÃâˆÜ,`=ÛaY/å58ôâ¸Ý~Yá3B…æë¥õ+íç—7RԎ4|N?m£ë+c”?ãÚSÃV“Rfÿ6ç=dßÁ( J³Í2›^«QyŽ§8«ßÜx#E7Û—S3r„‘âŽþ Ϟ¾{¡ægQ ™æ¦:NM’¤¾j¥'ªµþ–nÔ.9[`I-_eÛ¥ó+‚þ²Ùr;¶¾“4Ž[Ú;v.¥š¼E2Š2š6åó°N—â>Åd—)6“JŽØ<¸¤Ú ¥i§^՘¡$öƒ©°KﶼæL<Ž²&Z Zéê$¿)Tf¥‡TŽ×Ò°,å¿'æÐef]6+¬£Õ«å€æ«eíÎþ É·ù÷+§œ H»xÁÔVùs­8•Gi’ŸµKÃÅ´Áöqåuƒå·gåUÈ©]ò@)̃cdîsçDí˼Ó+7¹n5X:ŠF?>ô꺨̚ÇCÙn?’ÕúŸTi7béòÜ4Š:ß\ñO3C{«€)!o®VÚ±\õWªF½¶ênÑü\¸Ž¨ñÅù$‘Í`…O)Ã8m´N5(εúg°P½vz­˜Ìô(ÏÆyêýÉ;† ¸.ÓÈւ9†U'òŸêWʱ奰UKÈ}Õ+âÑyNSß´Wè+B”ö?ûªçMmÐΗ Ý¥î§{üg¬‰4JÍçû>¾H[t ×(¤KOT·k‚Þԑ^K AS怤‰Jty=?OV᱗qê1[T^›ç¦lk‡YwçR³Ô ŠzU}Ñ]¾þ-ôå&–7Õn‰šè3™œ—ÉÓ̒°Í©OH!¤j¡…_­ÁÞæ_'óh^B&Ty˜H— ÝÚRºµ-̨ƥk–ä×ôV‚ᓉ_¶4K?ëpX!!Õr¼÷8fݙI¥f±©ñg±IS1ªè/0òåìm𓠋&ä¬óXvÿáàë°Ý,ÿÅÐΣÎò*¢z½Ø…°çñáWL\½“Hýŧ3”ðO+Kuãú]^&y’ø¾¼NÞµÀ¿+¯5þf¾Çõ»Ô¤›Ÿ"þ(¥ +—ù'›/gYª†1’'U‚°{õ<¾6«%<ó¨V±&Ë ¨³¨«(þÕ:HW|Ö_çú–ì;˜+â­ÂGsE"—ÿ w»ÖAN¾j ;=öAöELA®Ú߁ܚŠAΛ•@î”Ñ@Îg Ç&»FæüdœH"›¬-V@ÖÖAV?´AVzš [!p‘%7Èf*ðï2Ëȼ€2Q Þ+Ûí‚lmÖ{ë¾óÐûÖÃ2*ÿ†dÀžÿ_©ÛSª¬AEc{r_ñÜa’¡ԓ:‡z·¨÷ @¡I¨W­A±cŠuá­õ÷dەÈʆ Å\Žlµƒ,u¬‚l>߀*›F¢r7¯æ Ê¿RÝg…hkáó•_ràu¶oPçó1€›PÎ'p¢™?&$2Œ«ÑÅ@ˆ¡ róä¦é/ÈqUX#H‡zW-uBX#Kl²#a 1¿BÑÑd냐 ºšaAvr±¢ÓŠ>+’•L¯Þ…aZ»åšuåW ÞQ¤ÃÒÌB©aU".@ü] 1UHÐéÄ\-R~ú ÷¤ÒPl9u*þøÐôV|ü†+Ø {l9Pô&Ù–Ùñ6.фè Jgú&>MëYїƒð£åºÁW[×^a'ÿŠŸB+(u  ÔUyà»z·xú;}Úáªn{EÂ5@Žd™ƒß!݃-x»…5Ò{ ÇcÈå-È¡ÖdÁ–fÈb ë>¤Ÿ&°–z ëífïã~f?GÁu®Dlè»#¦}ap]ñÇ=ÿ+ °Ô¢m€`M ×W’+?<,]EVùY·°LzÐ]a P^¸ÀÈm+!}ØÒ/iX³ÊäúÆŠN&%Š‰Ó5`Á‰Ädcy{õ ¹Ç,¬cŸ‘O‘H÷4½¢ w%…æ8̇ûi¡ð^Ÿ ƒ‰eŽø°Â%¨óÚÿÙí+s“¿½I%’Iò¬ Ȳ}—³óó]ÏûF/€›ó™ uC‹WF3ØÓ{y¼e\oºÒ;¢a0qˆ·>ä—÷󾸫¥¶Ñ%™^]ËD[bز¼(4 …YXöÉYłÑ{è ¿ Ùf  yۘ©Y°4… ¼ò;ñz+ÉÞÆ;(WÏX‘’Å÷íyy½uòï§_⋩¨r^æYÏ5Ï+ή$ìKÁ£±}²óÎ捏ÆëOv¾Y§>·Û*—ŸÓ6Yo”ç%;,L§…a-Ä*6ùx:©Sqö‰;øϓJUší:Pj0´Q¹€»ªìÿì9`¼^ïµõȖÐÕ­«7œë½Þ»žVÿp±Jãs¸*fv_®¦¨-÷h%Îíúˤ¹•Ê/êKìÜéؤݙ, +›­3/9ZnúÜLiKdhrR¯ÇØXí;È)®³#mÔOÿ +Xš:ÔéÝ{pØøIí%Ɛ‹”º]WÞ¦óҞҷ;ەÛÔ¿Y¥Õ9EŽ‹÷×ÃPô_;¶6rJFVÍՁ²½eµ´ 7»çgétÕ5¬ÅngO¾Xç=ÉTƒ$²9¨‰Žð‘ž3;O>cRÓrzxá¨ï¯h­kÿûíÿ•ØM„· r—ȓA%bSŽrßGy-ðÕeÿ2WÉ"Y=t7N‘lvܼlҁùZºØñ»¸.ñܼ¼˜‘ÓÙ¾ÌL¾ç?ÞIûTt›žÞ½˜Ô³Œû*‘˜Ú#¥Ì×ÿB2ðø÷+°s2[°s¢ú¥ö’"z”ñýÆ×Ê«ü\ú +Â÷iݯêró¤¢ÔàX¨eûš“>l”zæ²ô +h¸6Ùh6Í-¾Ör&Áí${^æGúC¨ ¯xNܲ•~ÿmöýÉ}“í×&ót/ªY©^”7?³Oov5Á¯ø[gbKÿ$w’‹ò_«"ÎùÔ{¤Ú…‡ŠLTF•ów¾åݎµë*·µ••Õz¥Çkw¸›ËlF¼ïV]¡¢±FÎS¦qÊ¡ƒÛÇ-öÙâ˜7Àyªr‘\©O%m¤ÂJ’c¤Üòא>üǐÂZ !ýø,Í4€9\ÿ/|7ý$1õz—ËXèe6„_ã +Ä ¥¸Š »­ÝbÛHÜÁõAÐlûúÐ÷óÚep²Ö‡©?ÖÑàaÒf ªÂ!Û[4UÊHO©j§õ@m—ÎÚäøi»ôõÓÁ¸kÜiõ¢¸³ß¥Þý,ýKõŸ'ØÀ‘Î0ÉD\Š5ƒäSϕrùÞhÿ\RëqÊíÆ1}¨)ye›± ½åù…Xóç]OåQÅ»œg§}P«=žÆw'$¿‚ÕE¬Úîxë¢N ¶¤1Jf¨1†iþcþÑ +ÖÏú1n“æ1j·Ûïèz§\š€,í·€Úìn¯èn&¡úÖÛç V®Þñø~9#Ã$vÒmϯ‰ÚY_ÜÍÝpú­ž}oM_@œ+•O½”; +:Çòû¥_ñIF+ +Õ|½NÓSm÷}oδ֧U]4’„ËÖ=gDSDڐ<@ï”z>9‡è~ϟ®Ï2=+hÆöŽKqô¹Þm?ÿ¢ÙM«×¨,‹Ÿ¡:¬ž,Z²0Ú[,Ó³³í¥#pì¸Má¢û¬ÿhY{¨ŸLol–Ū²ßN:J«¹õÙ}¨©|á­Æž59¯òl¾ùñßoós˜à ¤šžÀÎ)ïø·ÑºwΤ”¡ë½uëXÒfö«ÞVmÚ`U¸¿ó vLjÓ^ÖG×);D7é)zßîxãÍF7IÒmM¿«@]…\ÒÒŠæêÊÈç`¢Ë½Ñê,ŸÇ¥oý’±²o•Þ e^x5¾Qáþ+à³Dwae§O»Zç4×+Ý §¼Û'ûÜî…ÛÑÜ63åÝêÒCï‹WkŠN·¯:î5oÊpÊ|Ú½mvɂd飦e·æ¹W•+¬•#¥¾êùv-+ݾ$>ˆuKœ<ý“8é«i¸+}äUH’Èëdýÿ£ë<ÛÔÕpý[èb¯ JÅv±€X•èÿ?aÖ>{3×ìùpG.yғ7oBæ%FÄãvMZdZ=çRéⲯ¥:ʾBU[®Zkšþ˜Ë¢,;³Ó::xýƹ²”í?7Ö¦›dŠkû§¡ß¿•~k¶X;ŠRɬ$£´ó„‹5 +ùj £÷`\l4"²Å}Üê‘AªÁÝúX“¡„O3,–Þ|_Í<ÿ'~zOtg…›ûI ³ÐÜ_É·àò}­¹jo ü<4šÚT(={mÖã¼Ü½ XîYr¥Z4;Y£®?d_iñۜ¡¨öb ™“Æ\¬ÐÏpï[c¾ “¦“[²EÏÌZu÷yêTªMוQ>Í¡‚‡s a„4¸¶ÿOÀÞµÎáeË{™ÍsçÍ,³Jƕy´êŽ$ëÉüfÜù΍a˜/¬ú³S|±Èúøk­Û ±Ò›W^I}$MÊÇ/K±k§ù^õÜƲ5¼qJv†Öµâ½Äz˶Îæ8`3—Åt– À¦kšÕN©dU'6ò?q§©œào‡»µwde¥ùÂ,*¿ +¶r_”G½â„탆?êáEgÝñcédTZ·6¿)„J•ý¬túð‰¿€ð žwŽ½‰”×}Î}-’“sGö˜oæ\*¥k7qÂ׆9}Z«ÌL¤ú ýB54¥l­Ÿ}Qµ³ÕBþ'‚ø•J|Õ÷¥G³º&LnöXMÒ6‰¥èá`íezB蕻í?6K:¾Ô§÷é¡%/Ø»’éG©4SëVòÍeÔÄì,Ô=iÛfƒÖaÈôkÇUmĽNUÛ(&Aå}*ÍFN+/ýÚ¹¼4CØ ¼®tœÇdÅÙrØÿÄ¡3W*k—b²óʸEلÃò»‰[²âfQìÖÚõñ"±Ü¶Ü,ë(Æ㾔ôÒœ’ro~Ý2hÇ^÷ûÛ k1Ã"›ƒzÁÚr•£:ä|»Œ]û’ZÏâޖÓE JÁ_Â45Å=úƒ¢¶œ%±ù ÿÂféJÙùÕ[îÎÐAØø|»Û¶ñi‡ýÕÄöHP|]lIƒÒ³-ԁÕi®nÈí͗]7KÇsu†»ÚXh%f»ª£÷ +Ÿ.½ËR¾€%dzfGÙjÁl(rÞí~îêF›\%%<²¡Ÿ*fǝÜ(Ëä=ÄÊûŸXX´€Ûën/yëâ°Ü¸ƒ®d_íZnÿVUW¥k/ NýVnJ„\áôÊ°§aÐdÊq_¬:r]­ð4Ý.c§°S"o§A‘Žöv!¯ù"2wsbuʎµë+ãtpêǶÏÕèo8×èՄvh‰õn4oÊ)w!ÿô>Ã~Ã{wÕÉ7Ò£©)ze{ìòâٔðàèSa SÒØÔj_­Ì[9¢Œp¶·¬3“íäó…/[ÌUð|5ˤ6Ãeލ4_¸KôjðÖSîäÓ§ösbJ¥Á#Myý"sd>MœöÓq:ä:„Õ÷?HLªÿ½øÃKcù캓0Ô£wÿQÉÃ&ùÀé™Oւês9÷Êßw,‘—#,ZLç˜/|ØS6t‰kÆу[šÏî´T֒}Ò)•©¿(½Q¤¿,¢d«¤Kåòøõ ÖðJƑ0¦°ï¢\å9EâHô‘¹½Œ¹SNýOÜÎ0'3<À`‰ÿ1t†&ÀëÇÀ9jaÝ^¼QO1u€yV`£Ó` é,'>†;(@_§4@ßÙ@/ŠÐÝÒèzÐù4èC´H€;ÉjÔOÐÛ: °â#»Ô«ø¦7Ãü+{mdÿÀ7ùÿ+5f€+S¨Ó~îTÖwÝÀ§ ðÏA±ó»æ…3€ËG€IÆ Šváw¹8°| Ɔè*PtÐhÜXôz¼AMU ‡^bšO$æ‰%8‘JWßt0-=-½Zˆf”ý|Ì¿?xPeaBæy˜-^;€ÀÒuˆløÎd¾µšoí»/“K€…ÍÀV6€Š¯)€u`›ˆÉb`ìLÿ‰M>¬ÐÚBEp¼ŽQüŽZ ΕDe`Ó"ûօû,VJåÓÛäCnidÿÀ#꬗ ÎͤˆÌãç|ÂàìÿXÐWô c3ÉA`}€ïê€ký+ÀéÝàóðQ¯ìØ!`›Œ 0»gŸN:†˜¤!^?êš?H–¾÷ތn•NS³òm­fó×VÅÏü@ °‘Ä»®¡ÔeÎÄDzYz&ôîe¿H„T±nŽ!~ö{„KÆî‹|^/\‡3XœßÀlP›*;xfê<Ë| Žð–\±1ÐÞûOQŽ†i¡y_}æÚҟ¥s¾Édƒáé˜úð1ÿ^Àd”¡T[1|hP ÔäԟòRó•|åk€Ükð¿ú Æ!}÷¤Þ€è6áÔû@;11Ÿ¿•`e<´W?Õóp;|É}bÊ]_Çöš{ží› ùŽrG³ýæ9È;Õ£MM3ÞRÉP‡àÕV¦fêüP: ·ã Xzþã=™Õ)@vPöÅTá3ä­td[€Ìôa¶Dk¤'¿½ÊÎx·—á+ ¢Å«³Ï{Ï "?¢án“~°ã;6¦ù&»†têÓ|2äð–6›ßïü ½ >Y|[žè_D{؀X‹€lU4@1~PmRq©Å’N»y« ž% ¬öåíGÕÄÊñ²š_êy•âR–®\TOÊÃv®ð} Ça3ó]ݗjáxGo'âªÕÃÒ%ó¸òA-—æJÿSܞJõô&T\bíT$t¯+È/$ö$„y>Ro7 /³ ¨#6©ç‚î€nYˆ¶èÒbð¬Æây'6»hbvïî^û†HᕺãȹtSóGîª}×òÅg¶æù”Z$VõsA4…îí,?3\Ȃtî(½‹Ùv7zv¼qø͕—pØw:^½´^:õ=ÝÔ0v=wäôBÍçYŒ÷¤ÒW;¨9l°ß·Dwç>ŸmáCf7LÁ/.W*½ ŒubšÁù +6í!0-®ï¿ˆÃº kPN”ï·Aê:²íÊœ­‚'HûÛü»”š4¢im…°êÞôöɹŽÅM`;l²ÇÃÿL‚«'ÅׁúPØ>¼2Û3¿.¹7vÑp+ÚVÛ0æk¼æúƒËŠ_#äB½3³U%œÛúŽÚÝäc³åv<™Ž«¯¿ðÓØܶPꋓAŠ~pè9 B©!÷Ž;þ1ûdOÕJ(¿“÷öÈÖy¨s½#ï”lO͏Ö{Ã}zÛK`]ÝQ:ýÜ°Ó;ºnˆz…ܺÅ%t?Æûý¬=ogò«Y§~ÓR:"ìÉn„Nãêg,8ï÷U߯цº<ÿÂ?:)FW`Ù¤M@o>3^ £ âר%'ûâü»~³rQW8 +÷¡~8¬g½õ wÜ­¬Ö±¹=¬Ä‘p]Â>ý5÷d™e‡žöÎVÙzŽhG9z4y—‚Ûøcf‘ц Àˆ8ì⡖%‰6ðºÊ#AøI¡TӄIz­waj– “Éë.WqÔ÷®Ë#â2ؒÙãwÔ<šËÈ»>]6]V0Gkd¼NÜà–ê¨äÎýùΟfµ‹気mè¤YXdÆbúÀŽ6JÎ7ò8¤Q-Ýæ«\³Q¿À“Þåû½÷.áóöÉ=~Ö=)®º`ô@ÚH¶÷sÁ»ïK‡TŸ>®g­Ÿ¦Õîí?½Â¾ðØ5]ûôÔ×è t—©†<™ç®Ëù´2˺¶ãºÇ ŸQocl^Œ‡ûuöãŸ}kéÌ{2­ãæñDóK%Z NïîÕ>’Ä|½¿x•«ûžÌ°5Á +‹\xc§ã'!Ù<ÛlIgl ³ìkÔ/㭙e×·óá7)÷µ‡‘Ê©X;“r’" wÆJWïL:gýx\\ÚéÇâÔn§È6høÛé/ÀjÏ °.euX@38*Csxy©Áb˜G…-ö½ì¸8ÛÕìG2÷Ü`t ,3JφçiÕ׀«÷XæÎ藿‹¾U¿çíŽ8_.ÝE<´³8}Ó.Ãï§uw¸|« +žZ«úMù­»&à +ЗíBLNÚùÒ9êyâçuˆ?á/Àj/ °.Õ T¯:¹eJ +€4”ü]ª×ò²âÄØW¨ÃÄåÓíÝJÇ¢hÞßçg6ŠbÒ¯O_ì•´nqçvòB§Žd߇†ÞÑfúiE»Zùv=©9*óô+-»cYþZÞ^™½ògµÎ”Nj´j­ªßð[ï|ü °Î`Þõ×-¶“ÇœÇt‹ó·Ú<!íÂ!¡º ^ê­Õ±ZX‹Ñuê˜7ÄƜ|v”mÖ*ýQÛlXð(wäeI72»«—èì¸5)úKt_^§Ç‘´%Ž”Déjâ/ QíåNRÛï³,~Ð@þ¶2Òl¾2›¦¼¿ReWitÔ¾eŽSöøAÕËÔwÜn´î7\¾)6×­\__æ±ÑtƒÙäÍåöº4xŽˆG*9¬`ÍëL­£œ¼‘­¿e½œ7ŒVûö•¥àÏeb`íÄöE½ pMð–kð—úÈòõÏULoÞ'qEGI­¾}Ém¼$±ùïÅ@jÊ = ÌsHWk>ewË»û¤Él¾Æ©²:WÕE/ +¥™þÔt7ã¶[¼ †³Îׇ=Ýi!TÉȍڬöH_5þŠIõT°[ؑôÂʳGÇå´uiŽñ-Ú¬],®ñÔíuãYMݛ÷!zå{ó{ 䮗£Ð!ïþ_€“î©Ê¤v\µûÅýùA'§%¸MÑ)¬t¡˜›ßöHaڔ)ÆVVŒ>Ί”=­×žõy¥¢ŽV0Ñö¥u µ ÈÕÅ{ÇÊÛsM2™o[èéû_%ÜUãåûgì„Ê+–ÒQ²C’CìVÄÍíÒ½QŸ|΍èÍê1ðþ #E½”éLÅKèü–½;¹Õ¾Š¤çƒï„v–)!¡4¼¡m¾ÿJw,k嗒Ó:itvl_ׅ§ÆaT£LZÖÂMI<•´†P¶²JóY¥ûÙ•\pâ¤pª+3ã['ùS'…Κ¥Éõƒm]Û·:~­žë«+z¬ßÿ_$&Õÿ^„øu];J¨˜ß ·ûÜZ"ôü¶Hg±øcCŸ‘¦id¬õ¹_é¶`×mæ…þ@2œ~³²]¨Oé8GQ±„Y~"ö«Íe$»¾ÈFéÔ·º6e™Ï¦ãԗÃ—éUí¬2÷Zqîµ?=3Y¤á3íGæð.¥/Q>äV×ìF¤ðÔ¢àW1gQýy¡Ó8s¬~ûÏåë¶2a\9ºÒ£5Y›§é®ê¦NŽlÜÌ­x­ó7¡¶Nƒf¬¡Tc•}—9åvoÖiû¢³ÙùgÂXhãPq­ Z•Zù³šWÇØ7é¤+6ð»­ß*ããX­¬·Þ_ðɘ̺3Œ¡'ºŠ: :ùŒ34î×]ãÕ9ÔÉw{ļm‘Yu˸’|-C*ÞôÞ·çVͅôò¸·½qÔóøa‹ Ŝ7»Rí¶‡åÊ+.Í* }z*/¢¸Æ»û¿°ÚuzØô9ì¼Ç‡ñýÙ¯s…ÐôCõ¢½«dd£Ð2{G…ÆÏùi©‰íZ §çª<{¡ +3¨ßÛ5ÙY•x7–¿~ZÆÎÝu‰¼‡"œB\ +YЏóEt•¸Ê~™lxPŒ,“ ™ç©÷Ì8½uR 3\™¥ã™üOÌF`øžPcïÑ·ÕìÝô}þ¬Mƒm g[ïϵknCMµAÝ·ês\±Ú¸¹§+ñÖʕWŸ´i%µ˜«õ*U/dß>_øžå\?èY&µífã0[o¼’{ç°ðÒ°ñ gCœNa0<Ñ׎NóPb½ãý#ɟ–LO8Œ+±[LZ貔^̊z95ÉÃYé47ìY–!Åy:>fWôª®SjÍYS:gº¤)ð;â´á}¢Hò| «6îHåÊ á9 qk <«[_Ç6v²ôð\–„0 +`š‘¨¯UúÕ֌€ñ©ÀÒÕ.@- “í  +þh¡•H|hä@º ÅêçÈVdñ=dYd4À Â@ÆMxëøÞȄAL÷çÓdý8MßZe1ѥ¿°~¿ðc  +T¹ƒRç„QÕ6h÷V™L†<|€• ö$E¿x€™„3(uÝ4U¸䣼!\ _¬að ?}€@"üžh ÀO™"üÔVß1±©¼_Fóý€ÍF˜š]¨sv‡:ã¼p²¥ÃO¨sžlñg +Ö"«ÞŠÃ*2@Oƒ>@Ýë SF¤'Âöf_ˆ' P­P†‰ÕóCˆÅÊÁ¯Rœƒš Áç½³™ï3‰[BTîÉÏ¿°Ý >Z[V¡@‚xW–nOÛðÓ±p+± «Nbé‘ûTj[š*À 0Û@(€åfïŸØàW`D&ü[a v +@ã*”ß<€æ1E³4o[ò­Ù2ñ,Œ=$|ŽòïÛ÷ºŒþÀ.K¨ór©ýØ:»%(5êI€Èۀ¨Çã- ²Ïà/†øv oi €—i`_å°pv˜ÿlMÓJ`“YâóÆnM³ô)v93þ±C CâeZ©Wv_MEåג¸Ïí÷÷ªNÄ×Ù¼_ÿ +endstream endobj 29 0 obj <>stream +°÷®pöSÚJ¬“[¨Óƒµ…L͓óFb_1ñ•_åLCfÈ‚-÷þ֖ß-€÷£ÀõŒ+¯ä!–l¬N–BL±‘ñÞ_ó“—ÿèyOk·}Fs‡&}:t<-u“ö'üÜI}Á‘E‘›'4{Éñ?á/<)ÿ³~òcH%SˆȞiòü]ò¢Àùë儲ÿ-’¯Ë€DúÃx'Û«8Õ_žÞi½:Ó9ö<{ãÄÜý,eW¥èæúõ¨®òã±,ô,Ö]ÞCïv[Û1rÝBúrèXäñtà¡åa¸OõˆË¶‹Úþ_€©y/Á¼nÀ$‡Ækï´¨*—˜{'Êbw”Å¥h•X×ùuꓝgÿyu¢Ñá´{ØÝù9œéÎëþ™Lлp™Ð·My]º恻î`ãMõÕɹóZÁðùóڃ#»h£~c“Aö©m)r/vÿ²©U²Áêýr÷àr¥¶[5@ªÆÜ…1HU–.HµówˆñîÌëÅç°õã>ú˜U5äíbÿŽ}_³ë¾µÞ]üÚä|>Qíèt‰ß`4ȒÇèXÈûïK½î7é®æ‰lj} ¾ìuçmŸmpøÄëgºp_~N°p³Œ7ßsÈîð1ÿ^üàAª ˆÛ„ÙM5ÿcCÕµä€á÷ÐÅ^ø.Ô«ŸÈžîép©2¥Û.ã/dz¬Ÿ‹AÔ˜‰3‡.o¼•z·}J¶ÇHÛïéÁÛÇsnÛ½"œ{­X½Íèî×’Vó\-Ô¬t™ùóÇqz:.Îõ"¸V£|Å5(†ááD56~\{㙠h‹Ý¿OCá=ýàbÏÚ÷êË[úÜßæ+ǙÞløhëÚ:´,ÓÚ§£œ½=7o+÷–Û6Ôô²~>{¯5W´ñŸYæ—++%-ÜÅq1ß»éäµn3ÿ†ßœÑ ìq˜9L^âg7á\oó!°Pªscµ2Ú×:púOl½½ÃóÁ¾½p݃ëq>N©„úßXLvzö¥yuÜ(~[z/´M$ɽõÔC'+¡î-—rzvX¨ïþe®‡Ý÷Ì<Éé¹3Óâx3r*»’g3aõ2îÝ#·Ù~$W5w¸µË«‘,äÿ÷‹V/¤¨¯#&†I+Ùw<s®ì>À·¿¹µƒp{¾Õàˆf†¯C÷ñ]QÍåÝڻǬ›îGXa¨­/v±?o¿1{–7üä1Ó·òœju~·ÙÂê;i¤o¹ñ¢ë´Ç¨¯Gr{ [vó0ðÈÂnÑâM? ¯Ë¿ h§«QºRÚUùaR¬&–ÛWµr™…„óµ/p‚7;.Ý­{ðtâ¶+*²y­ô‘Rå%…v¹¹™Æ¤éµä´‘Ãõl»s&÷k3FÇÇãˆè£aËÏP/·™ÙxÖt2±@õ.æ~×ë3®Û+½œµuïéó¿Hj¥š R»¯ +è`ׯÞ8jìÄÑ-[5­ îm{Þ¾ÚXî®ø2pëä÷½F59YñXvvvÖÉê´Ò4lÇJ+9›cLë †»Wc60F¥]¿«æ¯½~[A¬{ð®Y£)b[µÖØë>Sæ®k/¹u·.— æ¿ó’›B©+ž4YÐb³;³îÛ%ï¾Ð<9¹–tÄ1ÖØÃÆÇÙÖ>š·^!ûhIcdvQši'ÂWE»Ùñ:½FTSh üsÊê[Õ`òãA|ݬ»OytìĚ÷î4Í¢ùí +}óë¤÷æŠC\sUx­,Íy›ýX—ŽU@…*ÔY/·"ÎSÅó]Œ*As¸LÆGõ8/­ï”]ee7ó½]‘ý6ï‚-˜Öx’²=7–÷·ÊðpiqƒÜó-õ†»m1seÐù2|–ŸÝî¶þ0¨Ô)ÓÞû—N{ÿX¸í=œÇÂÇ´÷ëÉÒ Ó¹A‡Ó¿ÈÓ£' Jµ›­k§qÏïƒQð]E,C‰ÍÚ¾øn +î´Wë­ñ¹¿\˜~ñ4 ƒÖӞ3~²Ók¬8=4ä^¡1 ¦W],ùît_S;ìC­±Ÿ´ÛÔj£wÐÓU;«<©õJF[땫+í¬Ék=׺¹“gº9k8ág)Pjßá^•œÕ¸”ÄYöˆå¿™ƒï‡ù}ñ|*nY#äÖôd.3¬ê̆êñàpûü}‚—úŸ!lµÉþUkd­gqWê6±nņh¤–Ž®œ•XÕµ^ .[ý¨“ãUÙn¬¨“ç{¡FxjÕªæˆyk(¥¦­›IØPRš©‹ËÝ)Íïaö´¯Kï‹S'»eE5q²ØÀ¬­RW³5ï—scç- ݉lÞÏ£ô³öêßä)j½rhª‹ ý¼©¦ÉjÛo¸M½`Ijk´I[jÇ§J“-zòr6ÿÈ"¿—dQ°§òçp_*3êžÔå]¼8*«Þí¿ëÃ:6¯¹û2sDß{r:ëÔvbðép©æקöé`ÙÉ.G^os”æñÝzÓ\2êì" ÀMêÚÌ´Í×µ¤Ý²&ÛbÚI™Ï^†,1‰¤–ñ½¨3êK¤ßfSÔ š-î볅¤Ø³™ŒF3[Q{ü`cÏ%õæöŠÌ¹ª6a‚†crWYæ`B¶øŠ&ÚØ|cSSÇh³¶”aõ1í¿íAÿYw{õÎþÜÅðÜÓLEK¤?fI­ºœgÕ鍫((šÒvuÓÅv㜬I ¹çmÃ÷|Ä¿0‹Ú˜ï!ý…`F3Á¶¨]ñ_€í½Z½í_—ÌQ$\boµ*¸Û¨ßðUjWùÎûÏÛÇÕebO³ñÁ¥8NÏîÒàÖõzÜà;ïâ´y0üÅí¢_ò³õl…ˆÚtÇ)yU +]u!8ß¾oœûÍõX5lC +uF¯5êD}Ø`ߣEãñæ“6/vêÿhâÔ¸ôÄ~Ú£Mß2Á[íòÜw~ÅÎÀ‰#ù3ÐðBÓ©AµWc­O!nu¶—ñÐè´¨•>TÖ~kʖ’”²®yo™š˜h^‹¡ØÁ«ÍG +H Ç}ÁŽÌË-8$;¿×W/·Z—šÚ Ž…ö¼¾üפ›cîݬ ÿB(¥SÙã’Ý'«¸»ëÂ6hº‡,ºâ9žÖ#öùcÜkÍÐú¢…OwsÕs¦÷–íË+ÝÖ¢è8Q?öF!BԗŒâæ&\ºZÌÒ Ùd/Å÷1Ó íqf ’zöžß+,MßãÑÁ€i£9Óf6S–’FVÍ5ášóìôÁÏq˜Û ·è2ã=⩃V£ %Íîƒ;–½Z˵{5s8—œdÑ,¥¯ÎX‹bkLÅ}†œ.g&¢åD¡Rݛμ6xVürRSÏÔ)\gØtÊÑӈÚélœkÖ¬_ªYz{P½väYµ¼KM«ýÞeR½”úÉñ†?á/…÷ß>2tÕÚ¥Á¬ÖnD×ßÜ·à{¶Ä¼z4NÖã¨M Ó²ËËw%5 9³&ªb?õ…êéc5ßÃhÚXփäøN~ÌNõÔlôd3«9Áä·~¹V +I¥:b´QµF¤‚JtÍä+‘~3Ëoö攧»©]_aRvBbøöV‰B×ë£ú—‹Ä»Û–ÊÞ}XÂ0¨’à}Ã*®÷-0Èïd/åÄ +ž„qË x.Û-4¾·.ǹ›®Z×u­ËšÃa`zmkƒÕè\ogqåUŠ3eÀdëe~Ú5JëÔ'–¤ð—¤‘KxAUØ©4>)ìÇÇñ_؀ý™_œáÓ^5w·a/ó=Y›ñ ‹šîZ‹òg#Ùòœ‡íÑ¢)™Ä§Ai‚KU y6 Ó{ÄZu(Ö§­JãLÛåe£¾)mD1(î,88KÝüTÁË\>píN¾P*ms—/Kç.Ç"ìKóL/×{§»¹Ò ±~óïŁ¸}9s"ºrËìÙZæ9Ï(zÛ2öVRÞÍΛ͙4©V®Ëž*»˜.V«…nºZ¹¥ò×[ÕËØÉá‹û¡©|[O¶•²ñ`/"ƒi®BŒ7Y†vϧC!.?.§çý¯šæ+Ë9ý¢½r¦"ÄY£%nÛú Ózçs™}²>2ÿÄÄY]ÖbŸ#ç ÑO˜SÐèÖj#iS‰]ç\^µõ[I-pQQ¯0 }§Ð|ዒÙÐ R™çÁËg¸LPIó¯NK•@N©ìݤtPi¤ç“þOü¡ISY”ÉśÄÉ3nÄɯe FÕ¿0N— +§^c"yF ·êZÚ­Ä2…Í9·†µ™é”?´WRó‚]¤Ãü,r>‰Ù.7v«ìXYn3\ÚØÓßKÍ£±Rä »R4x†¤)|câäRQ¤*¼’áªS0%Ô„ÃÄAvÌí(Fx®[@øFÃ@ø¦zú?&Õÿ{K‡å§âdûŸ„tê+NÍ!£ZeNtJ²˜U ٧݃ÂH#óÜ ÔôÜTÛôªÇ˜)µ +`RÕÏ]ÒäqZOøu×áúçMK““çH|/­¾Öð !Â3) bRBx¶¨B\§_^…XVþ@ŐÈóš¨DçjÖËð“òsRòRšéu[IÍzñ÷þYÆ_¿uŽ¿ãÃ7þNJyˆ!qkÅ_;o±U'þv5Ä3ˆ¿Vý qÍÄß^³±Tão…÷ÍJ£Épð'Œ¿;vœ`ß­)@ˆÎì7~¤¢µo «Z ¾¥®º,Ô;â¡Ø¥íg ~ÃHsqH…À’nb“> +Añ6?„Ï!®;€`Ù D7†ˆ3Á“_Ãß|jcüŸçç‡ÿbvºŠ×ùÅ&Æg½õ¿Hb“„5žPꘆR¿Í<ÀÊý2Àè”z@ר P™µšŸîJ"O€\˜ûu D†à»Ž ái éCˆwù‰Í8›˜Ñ= “’1™%&óí±KÌ軿,v¯L.¿yv¦èú:Š¡Î°˜Ö-l¶©lÕ6 ~^„é­Ä‚¾] Å€¨½†ñ²p ª¤”s†á %Ʀ$ž!f/ˆ˜hY)´‚¶ zcˆÇ&–7éàÝÚ½wª9Mò“ðøÌO3ûG5š¹aTÖ¿³;±Í6Å À.³<Àó÷ +Àë©:À•ž?G§Òk€Ýô+À`£T“€eW?ŽÊö´†×\€¾ŒÄæÐsô襖†˜Õb¥)oeÇ/Cëlž¦wŒú=ö•S©ãcÔ¾û÷æ@Ü_•­¿¾h÷Áò~–"¾(õ2Ê\¾d*€@ÛM@T_& ²Œ ðç`p÷¼—#ÞЫO¹ +Àîq?vÍì<&ϵÝ{ßÏo8^¾Øÿ¾²îœzžÔ0qçy¼‚•Oö0t„Ùòzþ Žƒ›„4ƒ«Š½“¥7þV(ÎAì_€y.¦ÎnÇn´¡u’ÃQ>\bõãÚKxOf6„4HÇ©’U{]Izž‡œù,n¸Q4ˆ¥åãÁë‡3ÑÏá‹už!×_ ÷yx¤ïü¤ÈÞ`SݽRæi~>¦|(ìdúAE;ßyÿԛîÓ];#Ž·Çnvø °Pj4Àח,T™‡RÁ¤È^EävއHÌÒ³æ1¦ÍúóU¨ÞÐè¾?ä6;­‡ ¿­Ü…©Ûúޚ\·'ayMQÂþÒn·Îç㦝sñ=õø TɼâO'ÂÈʍõAf2î¾Åëí1ç›;}µ×ìT¬Þ ®ÿ °XÚ?çÙé”z“‹€´Î  r–(ó;LÌÒ«·ÏJ{u~pîu—Ròºçvŋ±1Øs¡R—ƒû3Ž¶xøo'œypj½ñ„àt¾öôt¼wþGª]<ÝÇûvZ&v¹Y¾àÞ²QâD¾ '®Ÿ­­â}¿·üN”ÉR¼ë…[žæûœÏé¾V™eaFM —êÔ¹ö3¶=½áıú½ñ|X6¿s=¢Ylå~Œ)YP)z.‚Ô>Û~w'X'üê@»úfË8 AßýÂü@go—äB·º\|ÖoJ¤V ›.Ày‹_[¨¯•0×½6;bãþôt3ç ¶N¥à'ó{<ä艳ù*p¯Çó›6­ÑB¸%®!¥ÍÛf|r$†5)ÀÔÌÕàœz/¾»c_}ÖFzãH +ed¨¾©æÚíûƒCÿ4ìÇV·ßaT³wž“Ç$¡ö €Xäau§y@…óî2wW^—ܥȕÓçÊ¢œ; +tX9´ksy{ëVzçµ]¬$5Xè„}r…÷´¿xàNœ$VõÉ{Ò(?Zž£RJnowsp¢É C¥¶ý|¦õÎÏÛ+5³Wj1}kèá«Ú~µ»Qæ¬%hý, Õ  °m–M)1¦„_ú>_÷>p ? +Íå¥|n×»1üæMßÌÕz$;‹6lgÖª8áÁØõXýŒ¿2AŒ6÷ ;ܹ³ÊÀº|¿[P´^éXïY#¢»ìÚt¸ótޝe±ó¶‡íÎL9X :F<ÑÍϼÓJ þ )! ¨Ú6·C¦r5¢è¼X%y£×÷ã¥T€î»Y$íÚò™]‹øäç}Ò)+5šßý•ópboõ2–&økD~–ÈÀ·´TßB³…^¹ÿd¬šʝ8uê˜_,tL±U??›16T ¢Õ5”IÃ0”NU39¯&HNçù ÿlœZPªqÈDѦ‘¹Iï{D–ñûàQn¼ÏG°Í'äúÛV—»;+Ï»ú¥?­†õ¹Ý®¶cY¯œ†‡Þá1È9¸wË`É^\k<ó3]Žq*æ×S›†«òz{/èã6mï÷ºI9¤n¦F’n–QS÷5¢­û¦û¥HI ÿ¬K¨Óù;Yª¡'¦#&f;o{ò_ûnuðގö•×fžÏ£+5W*.²ÁG˜†l¿cÏΘ3VêêzGs~ÿ’m]{Uþu_—Í·³Ì”)ݙ¢A©8« h§ï·n¿i 6Ùd#fkà–yˆ¥Ñºa^[+fw-­ˆ-å¿ÈÓ$ [¦béê×0äÈߟÏCf¨?¶÷¸mæÌ1\¹Ë-X˜‹]z6˜/9;³‰'ä;ø£¡_ÉÍû—Ït׫«§îLÂjŠoc—*í¶ýÊêùô¡Öºí֒úXºÊk +Jƒ^=•FúÄ)Ó¶ÑV^‹®®2CUÇ7Múð1ÿ^Àê4ͼz`šûÉxŸÀüçî²ánÝ¿Ý×xªw[9á9»uҙ²õêD:…ò(­¨ÝA‘NÁZënóL—î_ º‘ô ¸&‰¦•‘!¥F³VQy›rC^¦ä¶Œ‡™$Ÿ¥»$_Ƭ´)ÔàwõrK”‚"/ºYQ›ÂoJ\§Cô¥aÁ+_{Ú·A´­ ðÄÏf½Ú®ïË´“9φÍٙú!2Yßè=7¥tºÝc>ëQ—¿•àp·Ù¶ýW3Ћ™ðÖ +çóX­¿e\þš¥œä¦2¬¸ÇªšH«SG0¼ÊU0VRr& ¿ºàù±*jt,KÄ%B‹…_ø)£7Í+ þÚ¸þ“š›¹y —‡špÝŽË£ýgâÞ| N§ý:ÃôØ×-©ž]áԶ̔|Ÿ´;cc©Ýï ù[hΛ“Ç Ù܅ŠP—3B†m†Ó®œM& vLúyÊՎš\3ï´RË W©æ·]ž¡‡«æ/ÀÇÓ¼v}›ÖÒöø˜—øèl/͂7Ên¬mÏyW•šêÕ¯f«Ë{m¥bâ좐jˆHFàgÄÂ`Ïðaޑšvh™ÙYqâˆ_ÖGòYm(%ûÖÃ’µîüP­^Ñ¢^íñ¦Úߖ3•ûݖ*5¬.–#‡*UûËWªÊµù saþF¢EÇboά©G¾àî{/æµî¤ŠùdMZ5µ±Š ¯#ÑZs#¡2S—üC{^›¯Ni€>“m +‰©o[œÄ ÎdŽ?©‡ÒºVŒÆ—j%Þ+!],¿6¥<µÄeyÚ²S%0Š%ÞÝ$þ%„ëóÅÕMä‹R»Ðø…míÊ<—íZû>e/£`¬Ý®‡þøHm:-‹ë#­;Q±Åi ZǜÕωUOEòõ‚ó†5,æÆf¹mÒ{2ᘫõOx½‹Jå)pV¥¾Ñrs?ޗV•ç³„Ù]TI¿Y$Ƹ°­¿…}Ž­èV•Ï{‚Ïí ™Ïf6_XmÛ$ofÕupž(SÌë?à´³=É }Ôي;¼…›Œt‚Zj±Yâ¢×ñt^}ð‡]• ð[eZ¨€ò‚¨2²îJøeÈ[̓R8¬üñB9ù|ùçü´\oµåJ2—Ë/W9[ïVÙêðCg§*“y¸y&3Q 6ÃÄwææ¥!qµ±\Á æü¶Kd;K}4›9ŠÚGŻ܆*i?‰ÖìË®DŠe1ß^–6³É¾¸[MÏE:w|²;’/ˆ*×?}òÙч¨ežbžOÇV£n‚ɘ^ ¯=ôwʝR…ùqZÔ~5ó¨ýd—£tâžTOJ»ìʔ¶[–~Á^®šÇa±`1Yé!ÌuùÇ·ê»a^¯•Ç¢TúFóF1åfµBöù†3'pYæ*¨çfrçe¸ô2±u¦ù¼}£¥r?J¹cûCí§c‚¢?nŽ4Ő!NۂJSý~õS>>0w(^É·X,¼ê3l<Ô>§ô_ž6ÎÞBSǟö²Íu‰Mø(_ì×µ!kTk¯šTtcËÏ€ÍŽå½–q´±žæsz‡–Jœ•Rk¹>¥sȐôˆMœÖa)øèÈ›à„:}äð òý±Ü2½³iâä$>²p|ʼni„o”T„oòÄüþ ÖbúrÛýÉ{®¸Ÿ,lª:ê¨N·fřÖäç¹ìp4¬¤›Ï[Ò¦ÑØm¥ȈeHöaÈ‚6 KŠx¼’²›“Õx”+ÖE„¯ŀX!> „¯ ‰­÷A±ăƒbç(V„ÿ¨Ã©5ÏÍJÿ¸ö¾¿bí ŽGâ p€X~g¥âïÁÊÆߌYŽ?ËLJ4㏪Má ?8ğF)„!÷Lüifà}ÍV.TˆG'þð•IüÑW»øÓ®¿ \*þ4¼ÕК ÿæ$’Køi9’~J¬Cnâ*üœã?¶ÎgâëîÓPï*n5þ˜kJ/þb›yü9£Dû àñç’ÉCÈ5ˆ…ñÐãÏ5ׇ0gñ'a¼@7†ˆÓñç£0?±ùlàO¦.êÑJ ÁxZü-Eí_ˆÚüKŽ³¨¹@Å+ Ðluºa ½’å³Æpôúc þŽåÄÄßIž†è”!Íøk#‰éBXcˆÓ:þ:…bÇßi½±÷íòF¼ÒòX¢‰NŒyoˆåýç“õÒÕQr’ÅOø/r²(ЅR—W(ÕKl³+’èX¬T²€æ"xß%odÖÙD;ÜÂg`yá{9ˆ3 !-CHð>ÁþäMõ4H†÷‹Ý+DŒDšÕb¼Èojô6_i'°žGnÓ{š·¾• ¥÷¨\žæ/À„œC÷'°2‰L«Q?–Ûf3±Qï˜Ä]Ò°zœ.:y +{ €Ö'@ 2@‹ÊlC¸}ˆï,– lÙ²ÿޞ´û;Uœ#¯L +?ójS|Ü3ÍdmíQ튃p²'û!«Åýû›¾öo‹—Õ½Þþ˜' +à v5(õ­Ï{€×óÀ  `ña°µX›?LX%‹^±ÒÝÒïÝþ\~yÇ[óe(Hëì©î³N¢Ëº2Êç>î;ëôi§whO*Ù{³i6nnéW¥5\4±Ø;{` åÖ ÊlIóëÆLú|Ì¿KʼnÊ +pVÃ>™A©Q¦ ˆÌDú0~ÊMîèÛ·TN¯OEÑõbÐ{g ŽVC.…ò÷¹ˆªw+uo+•M¶ùÜ°Ec~u…ÞþJÇûeo±Ä9õØ üh(þsV2½xy7<[ꇯ;Ò÷äã+oýì/ÿÀƘ†MˆuDåMbñóJq@ÜɁÈL'Ö0nüÊwÓ¨*µÝpºlœïB1ÿºá‰_©=–»¤Wqõl¾¾üɺ‡J08ùí㣏Ìð;÷gáà®yˆA÷[ª ìô ›­y9iî¹ì¨nq¬Êë õâWÓêšû€]ò_˜Uz8TÇfÉm³tNŠµ;c<˓žÎNoë¶ vӋ·Ö¶ç|˜MzÏ zØGþ»>øzŸJ'å ^ñ k-f¿õ;â>…÷Ú»vk:Ø—Ûù6#G·×šâ›j 0k¶QÔV á¦,›…´Dɶ0ß>RÜÌÃ/ì¿HPI”ý™Á¿ @ªÃ O¯Ä,͋ÏÁ~(„¼ˆ×} ¶ÎÅ\Ü;:œäx«<Ø”Õ!ØÓ¥ác—Ív¾Û¥¥Ü~U,lFu‘]G1Ù³fZ{5ˏFˏæm–±.ä÷½8א¼43ð·4˜#qÚ-mšNëöHÍÖ~àêä= ÅÈç±()Ǿs‹CÒB‡‹Æ¨pmWâRðØJ¬/Pˆz f“ÞÎÜV§î5zï6c}sZ;ì(ZÍËÆw¹ú?Œý‰’ªÊÖê> *`߃҉"҈€tbƒbß ‚¼ÿZkÿµO}#nČ­²f’Ì‘IZ a7“ BPÔf%’¶ö7A°ª{aŠtX(NP4y7ÉúžzÚ®!´¨óèk„ç£ó%8ëü!.æÙÞ¼§¡J8íò‡Æó½TÀûKò·±‘¶­Bä–r¢×ô¹ EläMŽ[é†5_Æ’ ¬¸^;ï;ÌÚ?ÛuZ‚(æÉWˋ«>n.Ú®o ™Ñ5GÑ"¥°ÒˆÇ97§A²;Ïog„ºV$\…Xo6Aáά\(´ÿðÏPÄ*ƒÑ'—îP~št=ºËùûiÞZ܎Æ@zù\óãóz¥¼i#wÄûÅÑ2§ç§Îx¿6ì +&xæùØÜ/n6p5žÂí­¿Çû¼Ve hY1sš[‘*#ù™«›³r÷ùR„…ÚPjÌ“ÏÍg_–nDnª^GºuõÖþýàûqò9À=躻–®§9.×ökàœ7~@xMûn^äð­e~R"¾æ,‘!ÕÅ]›†QòÖ:nŽÅwoó!SÕq7θzTS¦¥•åz‰‘nì@•:Á÷(>õOEÔG\_ìAT–¹Í¶ÝéÛﶦæ¤ÒøC Ύéޔ*¹§‰?—úòz9°ßCž³÷b¸ß\Ï½Ë +“ºÉ²Ð‡ªN¹ô­Æ‹-ï<Õ£¶žMÓã–3!9_-úÛÓ¬âY¡RWÄDº×è¢é–Ø̨)Îø¢à쉭@ $PÚ·—9ôÞÎh +¹Ú±þ‡ôïÿ|QÀ‰ï`Žœâä¸_“»_k÷¶›Ùé³Y™¹m°û·Ã•ü’ÕtÉΝÅݶTN˟[3Õ§BsÆ_­•ÒöÒ=©^Å𔼧Ÿ]\¾k »KÈ9Œæ„Gþ’+îNy®¸Wº\ñnt2ÚÙÓWtùÚÒ4b¸ª¯{¹¬Wó°+ƒÜvsC¾«ÕÛ±<ˆÄÝÏ|èø´.\è ¸©;S× +>V'»¤œ¢¹&Ϧˆ-!ßh3ÁIH8ûɯ!)á|@.OöTÛçqÚߥ-¶Ñ}ÙÓî¤ mV\²64+.ú V”ÚÕ?ÄPãù}Í>zrËù[·oûí¹o×=xëy”H8nqš6JëAõjvïe@ÿÎÎ5 d¹žÊÉàP‘G/wžýlÐK4‹cJ.KV¥=Cè•+h̞¬:<¾jÝ6ó‡4£µbAžùƒ×&£QP›Ñ:Iƒypù:ó £ê~ЇÃ\²]§¹¹¼ì|ÏÙmT´¸ñ¾]Ãs·$dÛõ¯f›¶<„èGÚhª–Tžnu”‹z§¤$—_Ói®ºÖø3q8®QÛLjA|b››÷‹y"Çüèݼg‡À0FŠä\èê4ýא´fõ¡ý Zø~j £Ï²:ÂêëÊbhÝ+ÜÁ®쟃0ç­Ìªçª¡ïvc¢¼íèï¦ÏZØ]”,ÈPEê¹ÏºQSpû½ò|áò\v‰í:L›1#QÚm4[Ž0؝8•šr=›”GÝÑêwýôs–(­~ìU&}g”VÌNã õ¸YïÛq¹Öa¸‚aPœ­;ø³ý底×&ããÚ¨QÁZÝ÷Öl ­ `‡Zê!™Îå~ÎÖ &|•Ot®av¬–'žãþˍ–P¡2-oº„;u|qÙ*Š¤¢v§ÄÜèêx¿SYaD½~îÚÔ·7ª)µøi1èÖîøè–+€è8¬UÑñNY•^áù.þá„l®÷íù²9zî·u°Ï€˜7 <¿\Î÷àm¡ Ep6]—aÒÁšÃ1f4EƁ4g䕃㐹/º,xyêÜÒ«äì4ìÚmHâ˜Xc䬥ôéiÝê1 + {#‚¼*#5b˜u<ºg€^uOG4ߕútµÛðËånÃ.”º ö ÿa¿Ñ˺_ãŽnÚïMô›¬µm®iÏÚ5N‘!s§oÀ1±w£inÓ£Ó»œM¸¤.ƒ÷’¼á#òÍ7þ‘ºì«v«XN¬wûà¬NõŠz‹G+VOGêµîÊoçÑQ¿!Øé.e¬N5§öŤݛÌJ­÷+¶Ìin™ÃÂ?d)Õÿ{²m)›“—¿SgK­|#‡-<µÑ>[b²º«|MÉOǦÚÓ{zH‘ÈÈűebƒÏ^ê¯'u·Ï”åcoÒs^h` Èiy¬ ÍÂ'krt;Åï £ -±ý:sv+º{ljÂI (ìær»Ö›ËÙ6jæ½n¬ë3¨1ÚÒ`"š…?¬ˆÍôlŸÉU`|‘×F=^ Ždóõ¬ÉÁzDړ¸M¸a1ñF$b¬0,ÿPäŒÍÐÎ3”ÈŽn\…Né›ílíÚæíûh}H®åæÅJ+'mÑæðö5¶\mO;¿¾—±O½ò½5kÇà”} Ví8=ÞkÓ+ÖêÄ©P=?ì|U„Üܲžfmçû–~&ÅáB(æêøÃ,§ÃñdI$ É>c&Ҍ±f·ÎÍÆöýÓ#hL@”i”.ö¬.§^+#Aít5I¿æª7¨T­Î|¶_yv¶lE [‹ò{äËfsX(Ås/94á—ìw”Hù‘/‘ãS¾˜|íÜ/i1?[SߎöKI+ùµÑ-ëlµñgq’è ýžï|‘îÃV©×U¬Õ´7õzÐêVj­6<¨ªÆUBt¢TzælQ¶ŠëUé;JƒBéY\‘, YïB f— +mڟÄ[ÓTt+à©RæÀSU|‚¢t‚@[@±¹ÈÿA¥=Zå±|ºSøú1Øl¡:˜ÀvïøÓxÍlV/¾¥~cò3 yžÍBrˆrùŒÿFÉõõŠ’Y>*/_ÑwªEQüѳ:Š·ïFÏP<ŠÉÅT^Oa×)ûsŠï”A.Å(¥ÓÓ šBQ)NúCØHY£xTý¤Hé*Õÿ£öSLºýãÚøKbŸÂ€¢”f> 5Š²x¯ïèû\Gi¼çBômÀè Id_O|ߐ´Ô›»â{~Š¹…”K%Š`+ï§èԛÅOl‘ò:Eq8ŠSNå(~A­ø櫝ÿ£}«mäiˆÉϚ÷¥¡.¯ï€óï4Þ(Ž’´òŽ’Ü,ýóU0ˆ¾R)[·Ž_¤\¶Ñwܽ§ÈqÊŠ¾,XMÁÓ³*‘r`¢ï¤,¥HÖOš+£¯ºÎE.Õ?+ ê~@ÿÕÉè¾·“ÓÈÿâßOí0ÎåûÏxeËn,Úi°’THwóº%ß<ö“‡v&Jø¹%Èʼn´wˆ’šš<µ;%õ,7]·Rœ~”ôâa”ôQ!e6OyyQž*>ÐHʽ‚΢žzK$?6,y^ÙIVCgÛÞóJÐèSIPä—£DˆGœãGì3ŊS’RœC‘v ¼E*Ì-lN6¾Š’s‰2EËCŒè)—­–ðY_¦£8øÛxÃ÷D;s¯àýV^‚Õ´Âsi—ñªWJ[T÷x©…cklµêžmº<ÑôS©ôÐç\þç[VŠ¼Mل¯¸Ž +YZºç£\?Îû8óa?`6FðOÛYØæ\ëñ‚ŒÍ=æÇ[ám@XßëjéÃW¨pª_ØñµsÞ»Wì\ÍG£“8®ŠG…'¬Ã|q¹ýA¾°K`¨¹Ë—OM4]4¶Û Sßn·dV lö¸²áçqé—8_4ÒÍ}Êûþˆ S<Ž ‡”ò­Ç…#Õ×6.þ|bÈà×_“-ÊÅßk‹³À«“DMÇDÞ(€fµ@°R…}dá¥=‘ ›»%=íïè†ñ×ãXñ¡`²Ýæ5^KÈ»²ša»š÷pÔª§Q\ÅCsTi‰5Š°]¾Ð/q~¼J£+|žiˆÅŸunA@Ͳ”!ƒ\½öº |ía^íêm¨`íK‡‰£:S‡Áû2÷ŽÐÕwÞ¸µô7ƒÊ~›ö.Û²S|m„°š[ŸûíÒº9Cš«[GÄW}5ñ´ÌîñXšåÍÃ%/!äxíoÍ)hûŠÍ¼çŬÉ)Xe·šÿ%ΟÃ0. s4D<ŒÁÙˆÁ[þTAzX"]ٖ‡K ³ûn5wû~ñ&2›ã¨/®/d[_Ý{Õ¥¶ó¾× ËÒÜ@/÷[¬å\jÐ,9ޚì8…X ì1u’¬ÝÉ8š‡[,Î/¨¼h^Eãà HËRv½Ñõü’¹4ÔC僓ñó}¼ÔÃûôƒ+{®ùW¿695`zÜ/iêãOª x#•£öêÁú„g¼gã%1§%wÀttgD•]{k”³þ]¼Ö®VåPx™b½•_\Ø^uÑ +8Ԙ×v¬*Œ§÷žùF€dqþÝvà¹Ë–Áù äÕÕüü!ݛà3Ë­[ F»èžOûzi1—Zóé5¿ç^ÎÙÓóíz{ènïkÐo‘ÐÕ%Ђ»Îzu£ì éM,¡.˦T‹YòŒNíõÒ»é} 4k7‚æIÅhÍóã@]ÝÆÙÀÊlû‚o3víAJ˅Œ¼Âߦ9¥ªÒ‰|ê¢ß_â‚WOC%©Gˆ,øó%8ëÃ{V7÷ÞØÐwãj_ÛÔª½î’£‡³¥;džÙúöÎpšVí€÷7¤'òáõwó2ÓÒúd1O"c5§;ÖQeêóGژ^J ø¥º‰z²Tâ§ÒUž¤Y:P.Ÿ‘ÛçWÔØCôCրú¿'qáYO?xß|ßip½;ݸƒä +GÃßçu[Ÿœ”uW™i˯io]p½xؕÕ0åg¥¼èÊß®n®-BsTž™ÈT:Ûõ ,«®ZÉV>W£‹tƒ_o©3€!eÐöô Ÿ&SŒ_í„~ûÍ‚S“Œì) ¤I½ùùà?ûÃøuƒÛÚî`Îzö®8ç³Ïfs±_Ê*ÜÒS¨uTª6—v•êœMÅ.dž!ïa¨ÍùŠBzêøQ3.¸N”©¹”ey®’*Iž¨s“`jŽ&Á!§€x»OGµ´›ËA?³6ÜýÃmÒ¦^Jý›s¾øþÃ}ðÂݹaÎÚׄ¶F¦KÙ#–eÞ9;Ñ®ÚӜÕo±@7¡–ðb>KޏœFE-õD9kBVpf(ÍLfSâGÀ(ë¹á‡ÚíÌm>åïd÷è–'Ô!ØÃgá°SŸ Ù#tL2âŒOúIo_¿d)Õl›ÖKÓðaSÕãé¶6»íøhn”[Có"k&»kéÆÙBș3ÓwI÷u 8¾Ï¦õú£¨4‚YCzŒÉžh¼ +ÔÔº>ǂ{8HüÊr²..Ç¢òr·ä+VÕp|‘.ð¸uïõ™»ÖY0w½tOáãŒÏ¸õœ§ÄWFøKœ^…?wzø:> Ýóù¹k®‘g4_.&ëâ:eÎãÌ[é;2ÌâWѳâÍÇùÊyv ?¥©Ø ¤m°ªˆ ஐ\w¿žªCÎg9~ ¸ÊžZ=g|­ööÌÆ£WE,¤upˆ £æy>ŒZAv×÷0j7âQ_éG£>Û~ ÿ±3/ºÁJp¨gÏÝ6ü‹ÁÓÜeÞ¨l •3ރҁ—5Õ´»|ˆ.Òê­BI˜¬†žÆûrYðúçÏ<õWfqŠ=Šãñ5þJÌ#ü,F¯ëw;ŒŽ¹ø•„¦Ëó?E:šœhºšD4½ée*hPH'|òü%-&œ¿æ—Ëö{¬¸ëǎX,½örîTZMÅìΆœžCBÝw“™Øà 9ý”¶RïA\§n Š„áê r{@®N¦Þae¡‚»ð}ÈôrGaÛnvzÝõ育= `!=ù&—~*Ï@Ž*«Í#5Ù­?/ʏýp7ƒgÆã—'³—S—¶>¿;+3‡˜îXXh–’{ˆ5¬d·+¨{û…+ŠådDx)bDT½é`‘ùmè?9~fæØË/ïËbƒ1°;:ÂC—RWcBƒSVYÞ¡*´Ssû&ä%T!Zô‘!Z½çŽ -kÙ²(…Äy5{’µP{üáîåKðõÍõæzZ9pINe3Óa´“µÕ÷Â*í­Ô—°FN—sšÖë¥Å—+ rò¥+ÛI{vÙ´ë×,ŒlìR.»«6=º¦‡.{`GT•íOÉÝ7ˆ6>òñùÜxbá;_Âú¸Kcýöa‹“É3H:ÌH;!ïxן<~¹rÄ5ÂÛù`×[£;Åq·íIJ—ÖõDŸJj°¶Xi0˜ÀÕw˜l†“³Q˜±7»ãÑ°Åîû1ô°Ý—Þt]h0¹²UJ8]RºÑ·ç?™ÛAÕ·×Ö½ópæ]ªGÓçM®“a/íÍ>{Ëöè-ëûNó"lOAîŸáœŸˆEÚ¥œkp»%*ja¦ž‰f+ŽMZ·16JEœ±j½ÉèkšÆp5pÖô3O>'‡Ô4'dËëÃD×j4ðžVêa¸Yõ©yCê «Êم¯Â-\ áäóáX!DʏNÖñ@ÊAíŽL’æ_‚<él×:¶÷Ü­Ý_š¹dê´î©³³t$\IžÏ½1æóÝ6†×oÑ%ƒ'tϦrW,ò*¶¶ÄcÖÊÖÄ_ÓJˆEJ5×O´R¹Ÿ—ó­4/‘hIªòHU%]1tƒÎ+~;J|A;Êp:mZz´ïiWª}ß4SÌòõ~èm<*4²Ëš-ÕóKΛ‹y9ÎäފçhVÔþp½˜7ÉÙC€ñ·¬µqì~¢°x‰ˆU;7¶6½ ïžzðiÿBË· ‡L»JWîGHçæ4Fíçj”MNj£‘»n™\ëÝÂ+Ÿv /ÔÌf,Ûצý\›ä½4I¾ù—Ÿ‘'·d‹›ÅY8Ú¸wЕîî"MGZ2™Ì0x0Z>Š(u6YÇÇÝOt9ê»&"öË$ҀfÓ®2YëÝvZwæF;íîFDØîO´´‡vðëͤžàÍÁŒ«çÊi@ýú­îCßZ}ûíÌëì`y¬_Ú¹¶gÈlÛÚCXŽV{ßêŒ#OvËæL©Qs1Oö…ÉõDŽÀšƒ:5ïâVmQ할 Øy°Å\s¹3òÍBw_i¬_E´Á¬§Lfـd–Q·¾Ãµ ^vƒgí ÔòµimÖªžå]• Q¯Ü–ßCEáŠÊ”•JçfïÊOJ;”Ÿ]éP֎dð»9짠æÄQŒcdÍÁdäʜä.' Õ;Ðþ`8A_›hÐx;[É5éÝ8ª¬oTén ô¹_áÒ'IûLÖÒ JÖœ–}¼(&½Í¶˜ŒÐgqÙðÀâ î żd«ÁÁk^\Á ڋaÄIò™ Íì 䗅´}’Ç?ñÉ^Î+ۛ)ٕÏ?Y}Æ9˜8®“8q¨vQ©UÛo¢66ê4›ÑU½´ïïrçÃb^j¼á ZªÁð¦Ñ†v2O@\˃÷.ƒ‡·Á©æ…óûä-W,´f<'}5?¯(§\(!¥œQT5à#t.À­]r=ºœž?Û_´âªéÈý}]ûÉê3_ +› Ä͐ƒ'ÑCÎÍN½?p¸¾ï¹ÊýñKÄ]|Ã0œBf‘ÅÍ ]¸¶Fh¡íòD^ˋÙwHæM…ì®(D¸7âU÷Sœ Þ½2@‚ >Aú‹ÈzDì"‘Ô¶)× K¯ïd3]eUÆøNà'Ô̽pÒ^‘ˆÌíõ+µSnŸv ÑoR,TÙxè<ž9,Eù‡êù×qYì™ðéÓe'åÚÈnu˜Â +){ ‘îö?³dǕŸ”j¯9ÊV¾uÿ“9 1€$:›”(þ“‘žÂöQ$_¤«Ám‚“QH#òëÔkåÛçf­†¥’}Éç 3ˆÀz·ôɅ¬þÓ)ÿ_:Ðÿ+çûô#-¿ÛfþÍõ"à2[ÁážÆK•²)ÈtJâ¤Á^Þi°F qUJyšÿd՟æÑ÷‰£@ƒ”Î>úê…]ô-ÜvQ,ŽQä:×(<ã(¢‡•”ECl’b«)‰¥-Ê]Êü’²S¾ß(b¬S˜nÅZʉ¢q…NqfQÄv6)ö-%I_:ÿH:Lçdrˆ’ܧÁ6Ó8é·ÿ“¹=߂(Vàg·‡ù(z˜i©Ëw?Štlœ²LKÕ;Š ÂO™ŸSŽi¨â'Š"©]HaË)«vÉ ™"OÓèÊ^Š–¾/6ÊV€ù$ÚéûI–ä“1ðIž…|åÂ_[;EÉUKCõ…4Ô“î×gُ¾Cø}ëô+Š/N¶_hEñ,;€&K.Š9Hûy7ë¥lÓ>.÷½G1ߍRÄBʪœòIÿHèb)ê(%V¢xºÜ}¼vðx3o?~íƇük'ß +/?ÿþ!KÛeÛ(‰ìc 4ûm—>ü4^:}Dj×t'Qô]ŠÑw„µ£oߦ¢/ôâ£/Lè)î*å{Œ¾ÅÞ3Eþ¦ì¡è[ÊÕ"J³]Q®Öê†25ü€øF~í À*œîk—§|B?;FåsÏ=º»VîrEà#ÿÆz—boÓ§Òúߟ1Õ²ê0’Vîԋ¤4Š’üHJ¯Ý®åâíêå¶û7;º\ß%èûzñ\îûªV`(ýJØèó§bijM†Ü©ôí¨‡ëôÞ×<ëeck—ÑCM.Æ%g¥¾ÿÀ¾»ñ/1p|â\å±K9mÿi\â\•}ǹ|ÍBO10Fð³ÈßåNć§ËUy^ìô|vÐdõЬRp%ë£ÛáÍÞô¿7r<¯Ë½T¹ÒórY¿óôÆÅùI8mw‡Yh=2>û÷dôÞc‡ÆkO¡pÓÉó?yènz çæÐ>ιy?ÎÝÛéÓ¯xKÙGq.ÈCŸq|ª¾ê3¦ùT·ÍÞýS¨›³‹'WïTP.?Ö/Å +¼×Ó[í±žîàûº>‰o¿¤!fËUÛû8_,m⼬œâüæòŒóæçóšlÖñx>J~|'x*q•òy;GÅÜbdàƒ>fp{ËYÍvIîhí£ûÚ_ٗ½áuˎrïm B +~ÂÖ×ÇÖX7úSÃ{^°|‡ÐJÓìVy× +†w—z7'©Õ/H£ìâ<Žøi€ƒm\¨íÏq¡—{~&®õx¢}¸årp®õÛA[|â½½:wô$hú0h÷¶åÒrø3ƒ˜^rkil+««»\¬:yßóëWà!ñëº\  ÈÖ(ì’ð¬ë${D´× wcùNø°Ê¹ÕÝ VÆÕFâŬA£sÆé—4ÄAð3%~Ó_ÇÔÚ¿ÎâuuNãùu\þª·×ZÕbÛØ;´õ7~õ±­Ô¡d-óÏâJenM¯—ózK³¿¡]‡ô8Ð=Å¡?»…½iï<Önµ«ÿܽj••.` +imqFcÚ¸±¶ctÐE×kÑU{Ëþ9㤙-ûð‡ôCf÷q¡ úŸò}°»­òº~>N/ò!”"îÐS×Ü>GÒÙ¨-_bœµ‚3/\Óá’ÈÕ—Š*eÔ>M»(ßû·¿Óæ±úáø¢,ZÔea¨«ÏZƹ£Þ£Z/Í\‰°†39lNqž®z¯ÎA±Îy¶‰ËY:Ûfc2ö¿Äù·˜MeÜæ§ã\ª•úüÐ7Kü>?bFþöÓÛjë0YÍoÞ|i77?õζßv>V +fcЯ,ÚX#«:¹ÚÀtC„†ÚçZ4¢Ü˜Ï`ÉRW,â«àrp›±… ìÙ|K©Y{œ/×?æIºXòAºlõ {´ûCzXÎwüÞfï涚¿ÓæJÉUöùp=Ù +Â{°¾ºC|…ÄuÚM¢Šè0ӞcîÞl¶À»ñ8†_ýåŸ ÍÚõyb-ºó¼&*$3£»ŸˆJtùKžÜ ì¬IY=>âƪ"ÂCÜÔxm½ißÌ2ö» ?cûK\ WA؝,W—Ö̀ÄÛ¢_žMصZt(τ>è蹸k«,™bÕîG}¡bǍ†«³ætÄ÷ÜI@e–åâlb %¸=ùt¼‘ÒÕ?°R8Ë" +>­é‚|Á6|bMA~9¡iž®´>ZAÆ>#krdÛmÆ旸° O>[!µØm*Ñt#›cRË°GøÑGÍó½=\t™¢›!»Ô¨Ùà n.¥ûlç¾"eŠm +²Ü5³V§¤6¦-Q/ûSćBLP‚ ”ÆÓfzÜ3só2ñ_ßÜdbn°I™õMöPnì3üIyÒßfl2Ö¿Ä P¹Þ,æ^É1Ërø\ÿ4]w•Âxé6)Ê Ôª§ñEwu%u‹‚D-çC–Ê›YÅõÏòÓ^’Q¿vá©y¨Ôg›CxÏ I¾ðúN8øö™MÊǯÃN›½,g3>sj]ºrü.4´»F/7 t°Þ/G8’©R¹¤0 .Äi}…ˆÓˆ“µY’ÕÏ{EV/·%)Ôãðéd.³í·51Ùü ?mڝ«²¤ÑÚÔ®­äÉ¢WÛÓóqgҖU¦‰øðXœæڟ¿+4·oåÉôÜ3Ù_\1aã{}ʗÛð n£!üܺH޳ʾ ª|(²v[L‰æqmâj³tÄ;7¿€=ù=‹=驃w–ïhŽ‹ÏÏùÃ%x×Ö»ñ}®¯õ¥âÂ2,Z­¾še9tç« fÇ:ÚñÃÀ€Èq<>ªMÄù–`•Eȏê®2ýþÅ&ÀÖæ>ƉâsP<¾TåNÃdýD6‰ÖŽÄñ`=_ÓûV9Ú÷ñÕ,[t®÷e¬Qï‹­>.ë^Ënß4Uçǧ¡º[q1Ð= ­ÍìÖ½g›o%ß÷qKX]¶Ð¤áìã±Ö¿™uFÑq”5 †K›éµÎêßb—T ;òdö¯ÄuÞxã °—Z®ô#±Œô õIE×õÇ]•…T‹F¡e¢Puì¢PžrÐрKA†öi1?۟‘²µFUuwŒ +ªÕ +cEw/EnvêD¤I», ˜ÁìQ4¤/¥„—èÊ`',ûƒò;Sµ$/“­d*­p}0s”ÜúùÊ·}`ý‚ ·PØCÈä#ÉÝñX¥§ûêÖVÙ97{FçÎé†ÛÓ®kýágøÉsê‰aÇ͈:º4÷ùãD~|üìÆa““[¬ÚÀCï0øRõó æ]9GtÃ[7˜&Ž}v ‹•™ÒwEÛìç®þº>×”흞ß’îQª‹ÕÄ:­DâÛsúå´pþl…¾ÛÏ&ÆÜpÞ2rS§¥)«¥¯zY?bÞrÇÁiaÎO幞ÿ ¥™tYÑ$’«“݃ŸÅO”¾¸–ýür÷êAç{õ•n6-%2†Ë3‹ÓÚ¬{º V·Ù¦7™&œÚ·ýn£ø jat¡Ý´7̨ Ozcðç=UZ º?TyjÖם®Q_—ëI‹ñ¨bۍ±mdÚRTÈw*}Òc†ß +øØØæڴ߉JÄã}ÚÂî™Om}>[ïLZ抯¶ðÑm~›ÅQÓ¹Qb“rœE3G=׍áÎÒvõ-LFõñíP­í‘Y«,l¥zÄû»ê4ííV§\¬Ö{œQ9_zzå¼m¥Xígÿ,¹‹…Ô14ؚÎä°¢ðÂÖԆÿäËFÉV¸$gɬˆG-A¦¦ùl}fÛSLJAõԌ®ÕÆ<ÿª6\ ª\A³2«•ðJûÒ/a՞žŸ'rxúåçg¿Dɬ¹J)8QBœÑ7çÿû­9ËÓçV3ŒbV.DqûÜøÉC—kXÂ8%£8W2#{Õ_EDì>ôdpz¯ƒÛ®^¯‰Â~Ãà!a­¶¨=›­ ÿ˜iùþ,l—·7þ=ÞÌvîtþßÎ?dé‡ÿ{òC”\;˔‚%Û§%ée2 úm§»»¶¾zŠ¾Cé}ëg(úBÍV‚Õ;Å^¥?ówí¯Ï/aŸ#w»E‡îçºT¬ãqaÐvå\.¶ÛÇÓ©Ú?\o¥Að¡q ­iÿ†ó=6a­}W;Rߟüå' ýÙ·ÌáNlÊvK^×{úªCâëåij´%½§ z_‡ › Ë_kˆ„8âȬåŒéB­4ãêß=cƵÎúãh:Ú¤p ënäyz°YsÚ-2 ué;Ú/YÎ&ÛþDçÇÐòÍÇÊ¥üM‚wc;Oëµü ¼¯oØY© ?Xšô\r©ÖÊv +/wkíãd å¹8ÛâwÑ|J ¡ö´šþT´ŽŽ>ìl­!ͬ-™y,Ÿ¤9yO,ÕCÛ;•~»ïن´•}ç•ò¥»JEÏÐäi;7ÏP‰óX⾚¬ß +qQ>°=܍J›þæȳªsݚUKžnžj®óºöpžŸX< ÍÍúr;ûòõPx]ôÞæõÒp÷”ÌÝü žç°[]©2OJÙÅN©tkiùíIçhy•d‡.‰÷*’e9Ä®dÓ°©hjÆìqÞl¯žz!6ÎÇÞJÜ»+šÞVåqo5æeT8ÁnníRk›¢-ÐÆ£.‰ºñ Í:KY¢kîޅ@]èÛl»Cß³R® (U¨U”E²Û”.…‰w ‰Ýd*M Ô±„‹0óü÷0ò®XÒøA#¯fÌ2” ù—Ÿ¡ˆ7»½;sS;΄÷}¬gƒ:ºŒž£†³L@+(Ÿó‹+±«ÈûiQPææK¹¬ª R°g“F¼Q„òí(Kàî.ÍÒ«ªø W1W•iß]e+ÀÖëHñîíÈñyÔ¹ÑbèsÇÖ½“’0SRl5ãç‘ã‚þFÞ¡Ìs :nÖ[³JŽ¢ä³Oñ’:쪢Îv³,ÇÔ¤+ÁÁ¾ïuï7¾ ^Þ<;å'å©_f…íµ;–‚ˆfn`Ub:, ¼Ðé§;BÅÝ4å-gH#íT3¦¿<Ÿ–snô™ï_'ãÕÓÕ)×{{ÖôtªzZ+kÀÍyªEȔ#p¬Éò%}Ç]íËL?øG¾ÈÝཛëp›Ðò¹bÃ8O*eñÉÖÁÑw,³R‘Qi)[”aô4ÄðíÂ{çM:63íV‹vHŽKñ¤ ‘ŽÓëZÆô—‡y©ÙG$˜ËÛC‡{扣t{f붨i_a ¨Åžu<”º^¤»2(Š­t§–¼ +ƒªÁóàMQ¹â‘µ&ŸX±õŒ°}cÔ¤úéo¸0üà:ýEÐ>MIÂdàÝc"ȁڼûujó©°°'gçͬsÓÁpªþ ür§îo+°eDü…øIíÛ¼bõWN¨ÍGx-QêÏUBZûpU_y!Á‘¿Î÷ ·ì„?"+ú,Ë1V¼¼ÃÌ7‰?2Üëiøy]Ÿô÷$t.¼•£&€Pl¥<"÷âD%ùF²'+·¤BVîᘬõ)ɗzS’KZ<¹'ðÿâº]{æ¾@%YúgâŸì¾˜˜NøµÊ,¨<¿"»—)q\ù5ÇƜo¬+“À~ôؓ Ç×m2eˇ:zm®Ö0r×+:Y,ötÞÑnƒQ¸ˆ)öjÂ$ÿÜdckÄ©þ¦‰Æ Upå¹Þâmc ámiNãÊú;ÍðË;Çgp¿\ª*·ð¹†ÿÏ(„Æ]ÚìÔxl¾Öže¥ m¾BrêŸx¸d_I1¶Ñ‹=w0h|ÎÚ̓µÉÑ[°Ùa,Ûòàg:]`{À쟚¬è)ØXHHÞ0_?r{$CÑxÚ_X¯‘$Ð_¨ì ¿àöBÿµ»g-›þË9r‡ÿÅm_æ›KY–îëÌÚµF}h,¾í¾Z;%I{Ncž¹5ÎìٚíÇÝÚìÎôðu2Âùweè¼;=ÚûbÃÁ6ñƒ"†e_OEU¨Î‚¬÷ËKBž•÷¸ª×”¿ý÷cXíÅçi¿GµÎ|x0.êéÙ*S"A¡Þh% ^ßâz€è¦Œ ö—ùÙÁ…nNր2o³:£yÆ«§Èƒii†ßÉ!„.£ ûÃAîy GX9lwShPªlZ/ÞpRœ=âòŒ§øýóžãHûmc}ô¹é[r|î¥-°º’‹ +ÞÇÙ­ò‹ìØîÞìX]žÈ¿º|êwy@áºûÎ<¥,Nº{€ÿâsë’âAS°Óó_ôtp¹·gÃF¿Ý¾ˆ“vÛ°í¶ÒÏòmeKŒù…p7…ŽdµDoªZ{fÖ¨ è4ÉK“|‰G‘ÜåÆa?Ùܪï0[¿Ÿö‰®½!ÒúöÀü¼Œn֗.Zl²»w³&RA¨´*[p‹Î9Ö×í{Î9·»ý[ÜҝVµùÉédg +Jã _Ӗu’ï4â@™4´Ï4œZ;¥Pýâي¦Ø‡oM1>Ï¡0g_ólRŸŒ'Éì{Š ¸¯æªë=ý*º4ˉžw̔C|ŸÂÍþê'°Ÿ˜¯Dèô¾|EiÀà­àGýe¦Ó° ’ø{Íêok﷒ƒ¦ÿ.Øûuõ6‹q¼h+Ž³0ûì,­¶ÿà+Û=›ƒ_"¤ùîDѸӎ"Î0bìÝ(â~ŒeE’ȼCäÿ‘OëËÚ>ÆäãFQ«ŠÁ~¬½£ø7¥Tü›’eüvõN¯?®WH +1ü³õ¿ð®Hnô†NôZ¼Íè•iqˆ¤cdÇ!æ¿un#¾Ž£Ì€z%1 “ÿ!ŸâS³ÓLâBîcøñɉá+òr(bÖd)ü¨F8-]›aڔÜçÞ­žâµx}f»ÅÄ ùXaàöÿ"z÷œ8T¶ãx3FÜ®s%Ž2Ëÿn×Ћã”v1.áWA1Cãè î§]½LÏþ:ˆåò[o¦Û«ÅsQ9ožâ1:>VÈçöoµ×}‹S™»öôàÀ”¥ N‚ûAmúöo6nnõåiýÿ"z߆ý¯=åÅ?£E¯Ã¼Çë«qûî­(r®ÿt¯‚^JÇ°ªáGr°ç¢¬Ò¬6ïÛFS¾kwˤãF4ÜÎìlr³Ány½5/ÉÜÚó_×ËC¡Á…ÜÍà³WC¥3stOSt::¥ûíÁÿ‹èS:ѧ šq°y%zc{1zã™vÜ}‘¸G ¥qô¢Ç›ox·pښ…ÏVÊMÝ·Šœ Ì*_¹ÕouäŠ=køå±¹ •—[gOÓ´3[v;§é`îžÒ¯ÍäØ⮫ƒbf.ûíEN7¹½PR{‹^úΦϩɵÙ%Éþ…×ùƒè3Úu£OÇ1âxK­èýAâxoœG®wã û^ØÔ¸ù£Âu`1›ã5ºÁeÈwßçq«—95vé(‘f2½zX{=|¿›™ô¾š±…%”íå¶0·Nïán‚0;Û ¹_‡…3XM2é7oe)C#}±‘äöBË3Ú¿PÚÔÕ/¢Ox‰›ôd%h£O‹ñŽ£ÅᏭèà íg!µ±nWëa^F9»{šg©ÑaCT»“öÚn¯ÃÜusßT¢ Yn¤×£A³¸z¿TxÅ«¾J—–œ/ºyéÇýiYàŠÉ p±-™þ¢lœƒyml#ӛ±¦Xµ'v¥N(à)ãhfËášÏÎ c5ÞZjá²w7sO2w8[ã¯î%O¢ÎáûšùNf +7ãÞ^³Åw%Õ¹Ÿ+V·K¥Ï]íýœ ZjnnÝÂìR™Ôf¨åcӀ~sS|š—'O³'ÔҏÇÈë8½qÁƒü";ÊmQe¨V€4,‚$‡ì̝ø^`ö4^ џ%œP®ôöFüÒ >ìvHq¸jÐW …Õ ÍbËu§Ð\T+usŽÐü`Öдù”0µídxéœÇonòŒ3æ櫔7Ïns^sõ©üRå7ÜÔdmX²G½„ËA՝}\dMàýÆޒ{.ٔzDD´º¡þÂ+•ªt^©åÜH²›ħB·Mî0)¯?0–Z§ôÑËÏ 8˜Ÿ4ª2½¯j2šÇW„·Oì{Ñ®æÃÍg±–…íi`,÷AMÀíls¹þ­×úÝ¥@öy³Ù#µE¢@uGÏì¤Ë çÃOEÄ^T®-;kÍÅÎ +q› „Ž¼‘¹?x¥8¡{?-¹öy¡×›»^pÁ֐¹)-w™[jQ;DÁ¬»„å¼EgÈv#Eøa»“k`8®=,zýÞ$·è=ÓÅm¢Šç®7®<º E¤œé\-8éÈBì;c:«Y vŠYص¶«ÕÞ<Ü{e¦Òœq~eÃö">ARµ7ùdÿà•Z{ƒÛC+µ•ÉY؀Š.õ¹\œOù3yÊe<Ýån#eó|+ËFŽt›d¿ßÒ¥ÞPµŒîØ°zÎL‘F´S¶TÕÛug-ëçNqë<-½2Ì£äÇmî¸áTJ¢X’­÷‘תýìsm:£ÐÚË·ym,+ì?`´1#Ð_<ËõÀ¾‚Ú½½#8œñ7R)Q9æ]¶\˜¼'õ'Írçán¢¬?úýý$×£½ÚMéwÎÉtBÅÎ÷B«£þ¥_¯žyÂBßDÌûÎp.qê/§^:aÖòmÚÁm¼—Y-U›'š:»4¦jËÅO_EZB\6“€V¤Á‹úâQëíìsnÖU7“Zœ¥ÕWdáQÁó£ÃkX}ώ®ÝýÞ¨z¿tãñiœâgÄ$U· ƒ´öG­iž®šfÖ±Žm`°èê®#OÚá^^iï³xÔø¢|Wçz/­fN«Š"”¼Ñëª\:FÒÞv"Éà$Lª¥ÆlFªÞûT‚ÄœôýüâŽBkç¨weù¬©ùMô‘ÉÔºGå]/r±tèÅЅ3ßvvA…òäS4Ï­OݸiYF˜Y©9i½Íì>Ž6­e=5$™šmâG™Ÿ¾ÊÚ6û–Zj’‚µ:›•$Þ*å¾Ø=¥ë\³i&€»+ŽL@|q{"CgßXœ[þ¶2¤fÛEÆ­É*YCr`Ø°ç©Õ½³¨3óÎVªm-8& +›s‹šN‰[²Í*Û¦&4§ŠÚ’=KYM=y»´=¹ü¶—’É{ǖM âm|̊Ø ÍÅ +B4^$/É +o2j1BZðš*)xøÿƒ+û ;ۑ3—&­SÓ1èÖ½âÂ.¸ø´øìBÄ}×Ù.¢©yIVFï|;ëÔ<ýn³g<9MXTm…£(¶%ïpJ“Ž4nKð„¶ì5{tÛ|6„ IVZ`íq•Ÿî–Œ–Å-^…-·¸ÖÊ1æ!û/Êû؉¤š|^2¹jgû­æå r2Ó;èð¸fó½±yyØky³3/ÁXÚ¬=n*;m6Z…êrûÊ)ëË»[Ž”Ž‡'!¤´—)öW¿ù¼@ÉÊåÂk÷Z \ºÄ£éʇ[6¹—óÇ«!-î¶+¶¸Ùâ¡-Ý%à¬ò00v¹?8©ÁÝZg=X˜ã‡5^ždtà싹nÓß¿:4ÞÙêÏ3ëµSÐe¨.?¹µ²©P7yO[)é¤Í*rØa­ÆzɈni×jŽ²cMx+KGH5û¾éÏÜò³;²è²%&_`ô©DЧø¦F[¾]´µZäikL’ úxa°Ðøâp¹†¿ÝAÂôõÊSžVàý°³Ë8yW ÌnžÜ´SÂk¨æ'zOÞf é´N­ë£øja-)xˆ¤*ÁÍÑÞ"…ÉJâ…tQWøl†38Y–úìfªN™ýRß2Õ÷ðN×Óû Õ¥3(Õx;é +•1é6… 霼»…FºA5öåó,úE|˜ïkKx¸ã§)5CŒƒõ&Óq¦c(ÈMéµZȯ‡r­EôZÝ{c"jê¶é±ã»ð™]ӂM•ù…Rjp+=Os…SUdۅ’Ƙ•|‡>[H2`§ë§°ƒt%97EDjˆ́ñyø´PLáæ†ãŸú¡A0G ùŒþÁwbg\—Â؟½™ÁMÊ6ºYK‚Ì^Ûüj›¼® ›éþPè'§ +sW€ðӜoùÕ·®«/®ØåØöÓ¯1GúD0ðäÊÑöã*Q½×I'Ÿ\Ø'©AfN°ãêŸÞ›/"ý*Ö—8,ÇÝÆ:%¯Ça¹ÊÅrдeŸƒ:ÖÂ(Öªxõ/VÊÙVfôcØô´ðκTã€Úm¾š6(dsUW³Áªäô‘ Ü:6§Òe‹­–±c :kiÝÚÙ]€ºcL‘ê?Œ:R]Š¤W Æ÷‰†Ï¢‰gØÓ“úïmCõªt:TŸ'¥…³ãnýø:Dõ㦍ԏ­» +‚VâÝ?X"ú]ªrþ²Ä,¿…ž°j#–]SíYÙ½*ß\‹t©éqêRt諱2(²¸è‘ q˜Ÿl=¾ŸØڃH£‹4>%<+Ø*K2XeZ m&è!ã&ÒPý\˜/ëu=uCº'9‡`ò•€ÝÀ²`w¿xÀî Ãn«U‡]ŠE`Æá?˜…›—ì%¥vý^(:j†g0OiyظI6µšQ#!™Ó•ï‘‘2µðì ´Ûc¥ß¨ Ô=¼½=jNnwn£éú¥¢”êöÑC‘€>0Hï“UীÙ0µ4¦5ïík@(ƒê š£UH&ÚUH±¯•ÅNÊ´Us©,Ü +\Y¹ÚLӇ—6B²Rœ·¿GÍN'ÿ‚u.tÓòÉ­]›Ÿ|qÃiAuJ=¤‹/3f=Žm„U£öF¥nmŒ'5nöJ¨ZJDoÕyÍÕæy]¨fP¯øËV䔧Uòó[Örü¦\Z__%£Ì×JÕcJ.ž:ð±xbA¹x*‘â @Hñ¸ jà휋î†ýj"wwå…Ü4å ¢n+Xª5`³¯Áö+™³16jT{‚ƒ©¡^oßr¹Ü´KµÅÜ.ž[÷QÑF«býªž +·î,,ô„T¶€C4œ,‡L~ÐÉ% TžªÛã\.9¯¿*äXÑr §/²ŸžË1ïK=Çl–ð/LƵ/†]rmöù»b›j½© j‘ÑIjBÇǃE”ç‘äÓ¡•ÉZ²3òØ~uá9Vé˜ß«üRsàt²™Bdf–»B/†6ËHú|—‘Œü#“'µ ´Žö¤Ž*qãNzŸFý´¾8¿ÒUÉFS§‚ØIW•Ý+­ûÉ­3½» ÑôníÔ¡â«ÿƒþ´JëN{0QÌ!(u«‹*ãjØ!¢˜Óñ‚m×ᶎϲóêÒLº<ѝ|üÿ­eçbZÊ +[)]“mp+·’—ý@÷áõ68O¶Äv1F€Ê¹# `QC‰qñöò€½•*À>¤ +pп<Õ¯ì~¤ÿBW™ft«oÔÌÛI:HZï:¿=Šô0¤ð4 ê„ÒÝV¥‡9-Õ3c7Ϙ÷NV¼Ôf³Z +µ2À7q¨øæìüVü#/bø@ Hv’„C“ñ 8Hd;@LÌ ¶Ì»2ã­âö€x¶@„3F­óÇqµ¶o™‚ôÐ%BPÖ2L?ŸBWƒÊ W×SµÀßVÅ^õ9ÎM‡H" e”½ï¤á ÿ5é!¬Û€¬ò]@îz¸¤‹ì¹·®€J=?€ÂÔ2 Ú€Ôtjj'.µÏ„€º‡ @=Ž@C« 3gÄ»ÿÕ:áa¢ÈŽ7_è"¾mÉ=vÍkj‚2ÄtUÁ5»!Q‹¾W¶Óú¾ð$ÑE::chŸÎÁ}fôÙ îc@q¥ Td¨1·üŠ«ßÃä.g@ÓhhËJÅ£‰g0›ŒX7ãÞç€YÌBÀ,U0'Å̙ÙæEó&TÀ¨M ûü…b·*BSÂó$ã²Y„( rI։¼ÒËw¥ýé\ +Ãù`›•+/?}.ëó_±}ÃZKþ/¹× âÆXB§_‚ï׊,´ï€éyq$;(Øb»ú«jïO‡y÷«C—fÃó©ß«²\À’ó`)£ò«òOnj^fhE¯œ«þV"kb >ٝ8Qėæ1†—(ò©¯Æ#ø–lýßò)¹úºeÿÛ*«•WphÄ¿&ƒq ûy…Û+b¶ç÷_?íÕ·Z£쏾›ˆÑº‡ÊFLe¹£Á½ã?É뇤ÎD”Ô™(ÆX6âèrüoYÚ³c܆¿-È_«l÷”œ—áG™Gá´xN‡i=*>5fíöX5èñC¾Ïö‚»»Ü·äìüÝú_ø%î6rô‚.ŽsŸu<`ù6ÚOÓ~tzý +ºS‹§fëÈ[ì ݗå=ün¾7O”<­#iš˜aWi>,¶$ÍÎ}"?íuTtB :3öŽ3ٛ¾×¦iAÔ:¼ÆÃ5CåZÙv;jŽÊZz£U5-²…¯Í|ÄÀné}ÂÔÚϑÝiSŸÁ@ ‹¹†Û*¼£»²à´_6X^K¦\Üv†ÒN×CI'3e©†E©rºæÿAî‹ÓRêþB Éz•§ÂÚìÞ;gǙUï1°ȺfÊ£.ûÀ-{©âÃN)ËúVí]M¤¹úNPÐû@ÚÃç‹ÐÞ `5nš“Ô9TÔÕ ]tiäMšõåÕN^.—ôøzµN©W¥…´XF¼æ>]ÑÙ¦b£7)‰¶[HOBœ³'¸zäFÙ>÷€\¥yu:Z.²£2}W9ùÝTw;°%ûeZº¿K¼ê&2 ¦ú½íuâ#„m¦be4±Êê¼ÛGÕÌcL)25äÍx©È¥ûҔ rç¶Nöe&^û¯½ØˆÐ°é²V¡I‚%ŒD»#0¹îU`òd!“]ýÆr ²pŠyÃufø¢ãNj“)2Í Î ¸õ˜þÜ·es0°ŒêÌ0º‚ÔÑIÚµm½ÑøÁ+PÅM («r£ oáFM.;D¢uJƾA·Î5ZlÕm®-vwM§ù¨Zã&ٙm…Ñörç?Õj–ç;Î̓œÎÍïؙÝ[.F”ãælŒý'ó§5!ÊëÌÔÁ瘧%âý¸ÅÛ9·Çï®Î‚ց\£;åÚíÑëTsË÷UñE/¥dä­ßrÞ>#ÁàZjÅ7ŸºxóߤˆS|sÐLÉBä—:üg[ðDøÜB²Ï-—Ýœ VJu¶°\«ÌV>왭2ÈÄXdق·Êüè‹cå“mù›%‡Í¨¢\óŠžéS­þÅV„ÚÜ´ÅJ¿íÁoUKïG²¢°“d²Xn÷ïé˜mì[—"´Ð~'%öB7ß|2“Z“êM0Á{ÎЛ/t7m®5Ø÷ØÕ;5g‹rbڃxØtx]aڜX2 ½- 7[mö{ÙI.ÚÔMˆ>ì?ØÝၰ< 4>eû"<´À3ÝjóÜ©Xé¹þ¬= *íU¥Èb¢d†ŒÙr +Ú@ z¾/™Ô¥9”«‘ðڒ«ðe~f‰ÈWî¾j$'a†Àª°¬0;§k3•ýdL[µpO]âE¡÷Q… „HöiaCöëÅxtV@!2Ù žNúbˤ„ëþò1xÐÈ,א³4ª'óâfí±°î)EO“%ø5Å~÷¡5‡Ë´#¼~&p“сŸ§7w>ÓºNZG9vSNWْ™m0ú¥ÌЧxÜD#iPÎÙ‘ý»&Âê=)F Ïb£wcE—oü AP‚4Aã¹Ô¬E°sÜLáã|½ŽôÂìRýt0±7Õ2ˆÕ•¢&5C¬Ç ØlñbÊN’[Î7C.ÿ*¬ØÍZ¾°åR'd ÃèÓyZ ëè +¦ºýAÞÇ@’õFŒúµ>þ5çë~€Íûå<&>ƒe¢ÝË\–YÓXóuI}‘HªÍË|áoÛÇ÷þhß.×{ÜÿXÈÝ·'(;Q´4áˆ.“•ùùç89:²eÖ´ºô¹9˜Òñim©›½Q8ÀÞäc¦äH*c&Ï“{ ü30¸­dl!E–Ýbó†gt+Ý ´¼• ´¼sFhy®<Ѳ;K£ecPm>Žáö>_,.y‡™4gbX§nˆãoÀÛ¸_ùÄ2¢‰Mx"^y§ÉL³*W˜Wxú¼ÒTo9k‘ƒëZ'^4 Ƶ ØãàˆÏÅ®ñ5„zÅÖzµƚ¦ˆFq¢¨žöŒú±õðêð†9"Nz”èк$pСûpÀ¢w8(ª€ðoõFP´õùbö|H¬·9ù”KîíZç@Ž#9Ôvʖ“Ü~1¸© l|uoŠ!…IN>q©66)Úl¨óþ°Q2ÝÃÅ#ª¿ZO´:¦ëÔ¬PGæOéær |W)&ö·6ªE›}1^Õ –FªÜãnU¹åóZå:è§Êɕw•cr¯/\ò9M­ nTû̙T¬TÌ[Ð µÅ곓aì8i²£¹Ã×ç6՟¾D|^n02˜õºÜå¬çJð?Y°æ‡0éK~-’‡ÇšWž5&(%eÚªS‚(UùÐÁªéÑ¥YiØ.¯š½EYɖåÂj[-m¹^Úò»KI;f@Iï’f_¥Íáùþb\˜# è§¸¼” ꄄjqv؉Ïu?!y©7êÑWqª“a 5´K‰Cn#ƒ¬±æ£QiíÏlyMF­²òªåâÚ”vê|^ÒK÷]©òh܋ǁ‘*ZÔ¾R„ß%²àhŽVhTrã|pô.ù~‡úºTŸAº•'Rô!ï7 ÏgŸ<îßyÜp^_ŒàÒêsƒï ڸܞÝò‘te¼½0¥)[£;.é{&¦hµŽÎóÍÚ¸­1•|ã€;E*Ñ:ãçuŽÊz>F[Ë1ø¢›}?ãìÄÇ61FA–—£t6]dj™y°ç3¢Ë9qÛe²Ô2 É]–‚üÛf•É7•ÑI:#“-Ð_$Yg¨çån®q&IYµ ï#уì#×F› jp‡xîÔsê×8ß­½íŒTÞlH®X·=2Š,”>b²Þ1éö|È¥+âQIsP'e^\öWO³ïç+@h*Æ +èP”:Ê{1.@½Y  ãs Ýë =h»ž¨PN}Ñ'¾dé4ß^¸Êy;7i_è l®‰ÌXKæ=ÑN¯çÂÌ~ש3)­ˆš¤˜›YNQ +*µ8‘J†gq ±ÚÉ ±ÎY qibV ñ&oË2+ð¡°âx°’òX™Jƞ«`€U‡o€eH ¢þNÛte“úxœZE«p|W‚Ži?ÈtO:4`Òðá12WJ`Ü-ÜË{=—r³R&ÿñš©Ób¶ßÑßÃܟÀӔC1^^ôŽ§'ä-À{÷ÀwFà÷<cÜøƒª¿‘É& ÏÜ@ä¨ ò ð·-ÿEdӉüðS;B®_É,òÔ¸á}°*¢^áI¦¶*W …ª“]”:Ô®Tä•À7Šd¡‚Þ¶!Ý @tê}@ø ½H’8ÒX¾¿âWTúŪ2°Eð@‰µ4 ZPäÅøD€²y)Æ{(§1ÿ¢-çYNTiœß¥Êêõ†2˜QyEðd澦è¼×³’ +—qÆxí¦-”±~…u*w©w]@î6‰ùäý2ù~…_§¹ÔzyÔåu4¢¦-U@û=0Y¦ 8³ u‚#­9ÀtVɤ`ìI˜ñˆÌd6ÌÝ}!cAŸ”W·N »„€š†?ãRP†©Ã&Ï~‚YFí6F©.;wÿK‡þj½¹áæ[Ëá«Cÿ¥ùþø{½øг\°À„»z °Xiãø,>®–°Íÿ.Þ0ì|EkFü#BƟQÄ¥¹˜£kEŸšÄ°Ž¿‹ |åÓoñ†ÿ%Ÿ~+ üe•ýU°7† óãê]v#¯@m"f»x†ÓŠý üÑò=¸þ«ÈÀ+'6£H9¿•ÓC²õa4¾ˆ»ÆÇç›Û»Ç÷0B#û«~ƒ$e…áøL›mý· ù1Šÿ1 ?JÚù]v¦õÚù¹¨òϧxꥫúªüƒýSA‹ÿ¯bñaû/þe”}™8ÔW–Œ ¿‘ÄûÓ®_½ºø­ ƒOçuÅpš§á0­5ñ§xPÙÇ +ÖÅGÁÑ1å¾mô{Ù:Á\‚š·žÜÎlàßê³×þÚËVîWlåd/ƒR…9GFÏ<{µh|úØ[ï‹3s¾ÿBôZtøèE•ãÀ»úÓڕSôw?Ðôð#ŽaZÙ,ŸYýt¸oëû 8àû×íL [}r.\{é[õòh=Ð ¹~g¯ô`ÎÌ!+ž¦pA=¥²yïXÿ GdòÞ·¸Ù™?ڞ¾¾­ïæÍÍMßÈÿB¯:‘þ z§ÝD*-7¢Ècãëʲ…víÛ®Ïl›¢ïånQ¼©Šq½qxb½ ²èôÌìŠþ‰?÷Gñ…Áå¶/wϝ™Ú½·gñmë«kaÓ+Þ«ë‡þn¬És†^y(Òò?}Éòùp=].Øv´ÌΎ¥ÅJÌ5Jæ…~‘¸TÿÙù"z—e"zÒµè%®JÑ+ôEÑjZ{.ò—âõƌ2çH2*'þ c‡Uƒaw6+nmè£m°ÍÍZʏÞʃo#ÿãܦ>$ :ùéAv¿_…Ëbŕ %łùVTòóòªÏÌ▞žr{Z?ïýÉm,…¼äçǏûð^ÝeÁ •dÉ=,MyÔ¬“‹árFÃ\–ÌVâ~˜¡ŸÔ`2XgõqÔÜZ^z:u‡ +}ðìsqa©üê£]<Û맕j÷Ù2]ê2 —³j:\ê¬Ú3ñaÙÍ\yÐYªØ¼#5Ü£µv7O«øJgM“W°Ìj¹d|Üé΄zë ~µƒÿÂcûê0—Í¢[w2Ïú…Žüœ>ªÁzœZ»î(Ï ÚÃâ2§¸G­h÷9tÒ S­ó®ÙÉËN*Άìæî˜ïøÕ ÚÉ{fi G[¥*šF†ÒŒ“,tŒN}êé×Þy­7Âô¥í2ä§M|V5mÔ$[êûŒøêÄÞEj*†¿°sž_$†ËäóŽ¤dö¸9äÐuzMBó T{Ž\÷‡e¯ÜsëHEíÝ •ï†ÊÐpøÌص3Ÿã²S¨‚“UfŠOÓØrñˆ¸"º¥ÖôîUÇt¬;dڃô:jµnk£7è©ž©ü¢µWð"T²Ý\I^aS^. »3iË wIû Ï©<Íߥr/|q#VuvwÓõš¯ìk™é°±FÅn~Ñ C2Y܍æêð³F0t»&¸0êópf6øã²G±Ü7&•)# 2ƒNwxì¦>Ù±e4–îR¾¨Ã¡ø8‹ÊZ^á$ƒ÷´VÇ<ôÄëå3±8¿HÍ]0—&iv"at¤ùOÃ+ð¼áU¹ùyqYô̳²›n3›ˆtÍvWô>t”KÔéÕlS§·°±¸Q§«wù‚®å§ç/¶T8Nîi‹©•'i­}ýÛö*}ö̺<4یꊊ߳qi…ê­Î"G‹Ý Üj>¸v§IîžàÕÎ>ÿ§¼*|zŽ½¹V–Í°+E(±…]eÚ31YÐy!ÓµmÔ¥ì*¹¤ê'ÿNöÐz‘Äî™ÄÐ*FûJb‹Ö™ì¥Í Ù}(§/6©‚Õ˜wWrÅ[™pº‘}§óFú£-ZÚ›Ò!'gÓªÏwHs€1ÁÓw<ÿ‰r:/°xŸ[ìÚ3®¥O·ì*<\Xeô‰˜€RL¥Y,Ðæ¨R£Îœ PAÉÞraw4#(9ã/è–ŽӦ‰{«c’ÙàÞ½àžS9áÑ?ãÑ>~±òñfcFdeTA/ ;½w\R†moHŠÂ–ñ6Ð&ÅZ°ª4Â->MšËµ‡2«q9΋Ç=6_WLTsQÃß#™†l¨Uts’h äºaTzÈéÜ[#§ü‚¯÷_á¾.­ä _‡êAŽzŒ¥´ÿbö̞žÚýÔz\œ°X]_i³ã²/WÙ®&Ý©ÀùÕ>FŸ§éΙž”“ÇÕ,ŠeG$ÛX1¥¡ö6ºmß]mÈ-‡Í}ý0êu“Ù}ó4, h¦ŠÂ7ß`¼p±kZV£ÓêQõl»^õÔù êñܱꕑ}ÕK—vՈo쿘‚øÎ><™‡š#§†ÉØÓ öç¥*½ûýÖU—5aÒRxVëô +û0>U +¥†bõâ­lW‘ Õk NîÆ#覠ÂAWtà>æz0þØ,kÏÁûP£óÈ£úÚhéêXÛT«à˜Ižž•&¢èúš•%\¹•s!Z+çÎr¿œgåœýޗsÊ={ڕ[^¸ÿ–^wݽRéwoOVÓ¥¼H}Ñõù6ŸUY>÷t’` i¬ñ(ñ Ô-Í,ÔBô™­r§gµ2g¡FEWÉÌL¥ì7§VY®FÃrþ\_–6¶|(iì&,•S…\q?ï`ÅZö.Nëø™ÖÑrçüõ°,æ¯ËÈÎ_;£mñýd$]@F“}鸻/FÆ­ß¹¶Ï¢Ù#2–™KɆ9WðB›­ˆ¸HšÂ$¥ƒÖOtTƒÉ[¬ÌÃu¶Ô†¤\á<á*›×Ñšž1ùÛá•Ø®ó= ¶ò8ÒäWo‘LÓç%ðïì ÚV²žOrYV¾v³ hí2Ó}#“LEs$f“ù,µC–y1Žòþ‹A Ì9{‡ ºwÝܔ]ÆL´N‘šç]NEÒu¹Þ| jè&+¸²pár©=çóA7e_Ñ)›™×Jüp×3¡¡e$µb¬-HC#(ϱ«ô&5½¥K&¥ö¹v2öL雬 +New«Ë'ppÊÚcpŒ>‡”n–©Ý¢öƒ>×åYËÐùv“?=$§‡¯„ŒüÒ×ùÍ"øPåKC€Ÿõ]…Ög¬TE‹Iű8w—³³”ÏdÑk>]îLÊ óä+ >Ôê ¾<± îW•–ê§× ÔÏÊ)Æ€úÅD@ýZ¿{ § ¾=A}7ÆA}þˆnáÞc̓5$A}0z~ñ]´Ò×DQُ»¯›5¡û˜ôVŸ^c×Î!"R53”¹R­¶"óƒ ÜÈ +å1 ­.\5e†û"@o~5FØ €Ð1¤ïùâZR® s|úÆ@C(Ä?*l4Ðh:ñ7Dá -œ É]‚c¤clJÐ9÷Ïl»•y%œ4"^yÀGêùÉ$5!±˜Õ1 íV,§—ÌnWÊS»-—…>,ý£Cw³°Z³0RÅbŒ€‰ÏÄ`TÑ6Pl´G;Öևæw€WÉ|Œ+p²ÿ­Ú‹Slü=·˜,p¶48§–Îçâ]¾ÈaR·«Xík¥ÙܵÓuÐтˆ=Š*Ø¢Ö,³£’åsvž¾ZƝ[隄rÿèÐ8–‹ÿ†6Þ¥Äá¿4€¿o6 êõ! äΣðÈlÿ ÈQäà%r8péËg@®È2 ׍¤Ø¼ä­ 2ÿ(1¡©÷ Ù]70w8Mó˜›ï¢—Úœþø¥:±榹S'SˆH=…J¶ôoÚÏZ¿=Çrï—êûSq"Q}KÕäÚÄw/ë¨qpÿU`˜P@V2 WšèKãèw©˜BÅL1»L)]L¹ï–/~Œ`%‘~©Á·çé25ހLã4<†µy(ïKhŠJjÛ}ës@;ÃïþÛýèÌ8Žÿh¾ÿ-øzoÀô‹ÀƒÆ·VoŒÓ°˜súZ{VeûÖo¨-K¥>16`é™c׏"öFýM#çw—+1äöø–éý/íôÇÚûòéºe +Ëþ*⠗"/7Ç"fS•Ãiy7 ù#uù«Äí·úÁW;½Þ$õõ¤þˆ_}׫ÿF"G²gòwý†Mÿw‘ñõ·ù[ûöëêý› äˆñ©vø‘;ä·J?L·m﹨LOñø-žõX!çÓC¾¥÷-Ž¦ïÚs†Ôã³ßÎÍÌö_HÊ#|½±?’*ô†¿m±_Ò¬þÆ¢ñ»]»Ö÷l~týyéõ3œæö©ç¢´Ï?VµMåQ°÷õ»œˆà@œ˜Àßâí̼•[}úÖ¯·fɹb~upyÈÍù…ÜZ»3sßOŸN£tâoñ¸ Ðä É£âýcvTé}qX1P÷Ç7kæh=ze?I“ +Åxî÷Vþöƒpšy´ž‹bÖz¬ªõÑ}['—AmXØÞê“ÂùŠ-²ñ¿ãê“Ôî>{%(õnÙ\í˜í‡Â"÷åɋݙPNÚÚùœ¾¹i”»ÁÞz=@Z™5y}à+Os_«ìÏVÔ+ó½Äù6šRŒ¯* pÒ#”òC>XùàÐPá[Ýk’—A†Î^ÓNi éVX¾¿/{§á®6ÛO·u¾Øô +þfýhû‡5yô/+ÙÙò˜o>#Ãñw8\óù°…ûÁJ.Ý…›‘uÛzžr+$4ì›çÞ¡{«[ï¢,n=§8¸þÁWŒ~J:›Ì°_ÝxýÖþ´mXÐh5îÜ _ ±öBŽFM\Cì᝷VV©jÞfn'*kVÊCÙ8ۀ‘âX·'­­Žò‡°Ý[RíYÇLšž|õ%„;u ¶*;œ¬ÿ 8ûq?W"¿NͺI‡žu‰õÒkîkö@7Ÿbÿb”ÈÞíc ÝÇÒ –7Z¶`Î;œºYÊ#å›;ªt0+k"0¬Fó¥_\9­;d·ÐVs¸ÝW®„öܽymèrºúŠœdšHå؝¯ÌæśÒ4–yy¨r«Ï¤õCÜHê€\ÿ‚Y_}qâJ}{Ÿ¸Ðr[gãÀÍûÏ¡Ó»ïÇ¢ó&¸=GÕÎÒx`–Ê~k?˜U² ˆBöt'0¦í;á®Û„Qýt×èÛû­NˆlFMùµ’2—ùº’ÙŒì·}YÎߎ¤ÕÓÖ¾ç[F³ +µjÙ\Sì(Û±X/¥×Íëî‘ <š×ÙÙÿƒÿ£ë?·e® ðXJDrÎ ¨€¢(f1çœõüíy×7.”咡®ͮÃèÍs‹ëÀãúö‘wvԊµrØHò²]/ù¢PÃ2¤F[9Õ%hۑã÷º«š÷É}ºž`ãòø.®Êˆ¦Jó\ý+w—0¿ù)®ˆ9Z$Â-åV7Ñ¥›œíÔo¥Jᬎ{q™[Û7¿û±;dE³žuµ›b²°ú\gfõ±hú½O0Ù-Ûwvî +”ÜÍäÜ%«ãïLaóE0Õú|ú¶Â„ÊYV‰ ½<æ}½sç=ëÄXe2üÒ<ŒãvLÅÀÜΊdæ³uÃ;» #>¨aÀ…óÕÍâv‡³oϕn«&ä[ý±ò} Ì2œÙÂLøô½‡hÂĽeLvÆì/¦Òä/ºÌxÃU +ätM=¡¡‰ØÇvƒwú ûy¯„;±gTâõœ÷Ÿg€{6S̖]¡Å”òôà—ýôïEw‡3u—iÛ]'z–G?OV…V~²/HëóÍîR·õŠb xž²@ËULûÑ/SýÖ0Б8Ñ…åU÷&«ç­¦¶ö᩶6_“¾BW¾ Æ?¬::NLv½ܟ®á}K–é^}1êúՆ[5üW/ä<»3ÂJ \HK÷Ô(—Y˂Ӑvá2[»4ín ؚÌO­w6ØZf)ü™aG«øi‚lLwGÜÈq°¨{±ZÐq²S×*µçHÝ}J'µ6¢I•u„ºÊ*ëÉ_ÐÓ±Zs°Ä 7’ Ôóv»]ó­=»µÊ¬èýthOѽQ¢²%7Qw×;AN#Øc…V÷ÁÚÝUN³Þ’V´†p·neŠÓŽ9f_c3ƒ…1“˜½‘ëòW}©¹6rZšrêÞ½*»”ªÊɟ|¯4EØùZ;äå6÷åv¾1þƒ«ÑJÁ×F?̧ê µÉîRËƦ1¶æ°Žižÿ®"Z9Wƒw÷Ì!Žô2v/çg­¡Ø$­Ìdó̈́46S0fM*0J–ëËI­¯ûîhªÌe£U¯“F‹äK­w4D9½'nÅsùù~Ýäó<ÿ­:¹Õå¸Õ.q«íiÈ­&§„[u6é«p6à±í~8>Íu¼_Fh~Z›ExpটÃb‰˜†Š#´éB +¤Æò­1éàG¹`$ߥ“;÷ù×8&½ŠO]`tQ2Î¥Pq»%Ú÷á@„§ië?-á{]Éw~4>¿Û°\…Ã-v×"¶&Ã3æØ뿙c´u˜£×ì3G³=dŽB}À2^Štß·õì‘èn×É»áêÕYUâÖ yZŽ{Xª²ýEÚÈ«¬1­ñG‘ÎÜC„ϧ8¢Y1KH¤0Ý¢Sû&¿xʼ7„j<î+nCTÇ\e;þš“Ø=³9±µSîÜD‡d„ÎX£¯[¥åá`D=lãNõ²¡EuŸJ—êΕ>uêÿp{ÃÏ!ÚNzÔפ8M«ÈJ½´ÎsŽßHÙQ2ýï"¢´êõ4ØA¡x /<~ˆ? º»í(¶^ÍË,G6s:„#ý:}‡.Ý#Zqô-õ¤Ó®°=säG(ɤÕÞxÄø¥ gðúNˆ«„<ۄ#C}Â!Ÿ½?۟ޠˆATüš\náqpûðR¨ý,æAýd(õ„Ó¨ôŽË@˜5¶®ÚW/LœWZùäÕXôk†5È"M~v-‰LºG›´uØ#¡“$ì(ܟáó=tÂËu7“_çL>hé.¶},ÛXØ÷öc¶D,ôÃZ“¶mÎSøI +«Óý…š§¾g™Ú¥ò £¤ìM²5çʞ;cܽ +¥Rh$':]#ÃmäÉÄ-þFÃщ@Þ Ç3M_ÇhžB–$¶›¿E¬æQÆ +^9w¼Ž¢\£ýúÚàr‚ª®ÐË«C[KGDb ݝÒ@´Úc}so +ÑL´Žt=·‡tM£‹Üö´¯¯W üXy;)QÏw½Ð󷮉e§ŠÚ<.)1 üO¼oJ0s)'Êäà;‘s[l_ÍÐv¼¿"½éþ…ôfXÑë™b(e‡ç¥™^ð´nã,$/&ðøIa§ß…aÄd$¨4NS•qfù&¾ãŠ%¨TÎ÷¡YŸìÃÙó1¯s¡Ø¼Ò ºgþY¦ãj‡¤¡Êý͘<øF°‚J"Ԑje /ì 4îhÇȜo.°»\~m×P>l~2A:Œ;!ÁAx=ó€é`&í0Ól7Ec˜Yþ•bÁ¦_.fÀ%€ifž€‰ EÀTà>` +äè?ü­¬Vý¦Lbè¨ÐŸ ##¸†%¥[«bq>“ØÓð@SS ìÜB°h™É ê¡òJû‡ÔίwPG«OÀ.:™+°'ŒNáȀ}/À~ðpØ`øSnóä.Å7xÀXpÐf +8xû¸”{ØÎ{$é·!ûjšÍúÓ°zr/“Ëøy[8D„ˆµQ=õçÛ&<Úøz±Æt€#ïNÍ:Æ2 %1=àvó<Œ@)ô<àÉ: xi)¾5_ñ<À·vMÀIŠí ð;›â#~:«¾×X¾_@?(ç?\ÿÿ¡Ú2h¹Šëç‚eîfúAëuådÔ©ó5fàÑon_ |Ò°æÚ‘ÏpÍfQÆ£ÿêП6„Ò‰BýA!Ê0?º¯É@˜7L ÖE ¼Ð*™¨ Dõ9b­ybÈ§X@ì7b ܇ÄD €8=€Ø.²)ºòÒÛäÜNÄÝÌ5}ùÖЪfíǦ¾ê0OáøǍÅ/¢€Œê/IF§¶÷O‚n ^:2wH0ÿJ¿–QR3©iùlé£'@æ6[ GÞ×äΦX|Š@Áª ä}(x!Š܀"ML ÈâW Õeã…lÅúè¢Éœ¥t@¹þ“Бcòݼ°ÂëÈx,z0tœ_q~:´EÚ@Ú.s}ﯮZ»Uÿš|³J(…j돫VÙd&@Ž-P½ã ¨KÇ(@ÓÏ!ЌÞh^5´fÅZ\mäÿŒÊÚØׁ61;)ºcWoi3¬Ç¨2ªoþdi'j6<ÏòboÔE\a\‡Â5€_Õÿ§LÿyŽZ¯Mþٍ¿Á‹âìw˜ÿ£ùî˜ÐÓèúe«Chׁ!ÊóKÈÝÓ}ò­ eÿߘ^ýžðG;ý)¦?ÌÅÿ±öþ2 Ïÿe´þÿ‘Oÿ&8ÌãÏþóéГ¥uŠÞñÙG6§>ÿ@§kÓþÎü‹¿½¯ïΉ¿þâoø¹eúî¡O†åÓ?âîO>ýá'G~‹ÿ'dàoLï?÷ñ/¼AFÿX{¡Séñ)®‡µ\÷îÎö^½#5¸q›³dç†5™áu%³+Ñ)o/ÕW|½ÐƒrŽ P=sS±y:dz_Áþ$"üÞo‚ìÏ¥ +ukkzÁÿ¤]ÿg<ýɧ?WïπìWþ-t§-ւÚݑjîrâÜëê_høR}`¹óA'Èsý#r§³-J'q*~OÚñVt +Geé”}¯î?a½¹·ŽÃÁn"œ–;¤#?¶Øà!nˆ‰\ú©¹ÿaÅ­OåE‡³ +?5õ_éHøŸvú{~ûO!îÎÊÕoXÍ-^¶¢žjÐ>ÅwxTæêô ¯¥ÕÞÚ3»sFÛ¹”¿mü×å±Þš—Ïš?²«yç—g/C/Å .-:´`Ο‘çÏõËâ{Òf‰œgÐä§nF•þ3â̳ØìÈý+àÿâŽøöçR½ìÁIL|ø /Åü +En;8u½ÕŸÖ*‚_sÒR\&ÞBÙöÃyŸé7fŸF¿=³®ýþt¢$ã©ó\-&s㰛`£Ûed?¯11—н6è$¢:úð!µaÌ?vCñZ…ŁÿàÖ®føiéöùŒèO)õdû¾®èÁáÔ|·g{ký\¬·Z~¶Œ‘õz¡¬§Ù§¾xÍ x“Ìµq~¼²†ô˜˜Œ…QˆÎÔäàÍ̄Û̜aL/½¡x8}CNþ”+>è÷aÖûô »ž ÷AºÈœ;s/w°M¼l¯ª«ãÿ éý î©D¯é “ÁjíÝ eÆRⳠÌÐÈzÜ>„]Úì~!Cÿ ËÕf +•ˆUƒà< ¾.Õ@‚¢žÛÎ'¾ÊÌÞóõÜ{†ù¹x¢ße;´Ñ2Ìôْ;¸ÅDûÅò¤ÝuÓ¾ÙÆ NKÄÙIƒ¢SËò'íf·¦·þ¢öŠpÕûf¦,Ìuýš\{q×ǒj,ÏÓ!d¡ñ¡kžA"apÞÕíÉ•¨#£A|¬q~73н½(z Ëðj–á ?(iiRBŸÁºèᡈƒäî®×¯¯WÝ¥è<áÔ"[vX#=·1ÛW¤:·[ êcËMͱº·EËênGñÿbÒmn+­ 2›íK·Áp—¶ë]#hXöI«áτª²Ý\ æ;ððï‡ÅÝ{­÷py”6Œå,OI¥\A¶ŠÞÞóŠx½[w+ŸiÛ¥’ãЩ“¯™ÃîÉmáT7.á~ì¶=ÈÙ +üâ­^I²Í÷*®›Ã +21-yó2ÆýåWî6³ŽPhþ®5~X]›uh² ˆkìqyõÒ©®T¹–KŠX¼ayý(eó\*~ +Ÿ¢Oú¨»éŽYg¿Ü¨'¾ÂéÎ~³í +bQkØ·œ×µÛ§ÁØzŠÓ¥Õ»]æGw3əYò[Œál¦ÔÔP/’DÇb릭䒦ùÏ\#kþ!×ü‹y¦±ÔC óÌökííN½×ø<§åp;Qä S" Ï:²™Ò<[»—çìÉ­N³O§~"àB )¤} «’­Û¦õœ<ËÈ\Có³Å[fjC:šSc2hm 43ºèóñ;óSnQ–Ô¯¢j$~Ô04ú*Ãé‰8l֗bæ6> ŽzýÙ·Eó%klrË)^çüâb‘ŽúwG€¤œâùuwsøåœV‡ùÛŒ… ºÔ°²ŽfŒÚ¨´Ñ¶ý³n»uDÆì^NxÅ5vÐ6ÅÉV­‹öJiºö^n7Ê7é™éf$½ºÎ‹pâð%i¢5()"dvÁÙL"©Þzüœ!¦<ÖÐwÜJè=9¢ý̳՗¥±ôà2Tœ2ÜÔË1\Ï.2\½2õYÿzq5yt#¨ÝTs‹º/ Q ãÎw¡€’¯å9GÌgs–%æÞ:‘…Ž*gE[¹}D—’¾¾¬Dë N¤L>7_ȦwGƒäËòTà±ÇEçVs²Èe£Ê‘ù¨Å†•þeäϚ‰úâáäÛÞÐñ‘©táS>¢T?Qªw(Ur«T'(‡TǶÓW’ZZ¾š‰Ÿùý<t_¼˜Z&àÞ³6à>Ýth°€»Þ†€Ûö®)–ÏŸ Ù/¢úÁm©ÓÄ\ì¬H•×dIÄÜ`ŏ"‘ÓLðUnó5{£=ˆB³ãh“…ü™•¿uÅx Ë>Ö³€Oð+üyH!Ÿ€À *ŒŠ „ò.½ÞjÇó§Òg„Âgã ’Ÿ@| _@¸• ÜÛC <–é¾ÎüPÚ;ÐÁ·c–ÚÒd¦V¹†Y,Qc²iýLÑè³óY7l0™]ᝂ›á%è§ÀýßïaD§&±Ú’ÿª¿›Ä[ÞäV€$& Åt¤órdà@@Ƴ"…]Èbgd»ƒY®;@VS »wÈÅ8}[Ü®š‡¾sk&–Ê`ÒKêÓoӟꨆoß³rNË +Ùšõº«K²YkÕç¯Ö+ÂÒ_qõ¿°‰î'ü+³ÊÕ6P*§ñÏA¼Ñ6@Ž 6PÉêêÓêeZfC8րFnw@£é[嚾U‹‰=£Ä·vË '©¬åÖi}‰MHï˜ïaŠ”‹²sšó3‘fÿLä\Ðßbý +ó?Âóÿ3bâßbr_w·ڔ¿\Ã@o¹,ЯD¤£„0ˆÅ ÒèW r?†Ò>Cõ `h‚ =?ú'ŸþDÓ~oÿ 7ÿÅô6ö)|úÏÕû[ç,oÿþX{ãZŠUëÏúl}„˜>õ¹¸z$yýð°ÖÕû}B%ðÝ9 ì‰6Ám.Ô¦¿Œ†ÿ"n6ޟAv[zßZÿŠ»eâýÓPËÄßòþÉþÅôþ Èæò_öm.ó/A /ówg«)·9£·Ò±è\WB±|%ÚÞw±VóB÷»ÝóÁØ}›µ?¡gG½ŸÄù‚8vðÈ;*[¤x†XòŸýwù å,ÚÿtݟáÍü{õ+þÏ-­—Ÿú¸Þx$Èø;ïywÖÃÙ «·7—­T=žZézæ†þë$NÜÌñæ†èQY„ø¡‡ôþS„½uˆÕ݄ïX;¤5)oVz?Üɶ³¦gÈbadÅ­«ÚŸàqÿ[­ô·ýYfjꟐ§‘‡þ¯†ªøüÝY‰«ì²ºÝUÏ\ô ”]T}¬í¡šoç"ÛÝø¯Ì`‚ëhu(\¿ÝÁ7»®–1öØ/nÁã¼PvïǼÏ!™Ù'¦±™uW˜éD«jSd¸ô&eXŽW¥ü{`]zL¬0Ú•Dl&?Œ…1úŠø›#(º÷KõR<;Ðò¸·6Îe[ºÏuõ}ɬ"(í«‰‹ 3V×âì-´ÔYSç1r'¥O«<Á’QuÀ£h´-NÛ#z¹$ÿþuÂÛa̒ßÊf(ž*Ð@¹uÉþ³KZ}ýýIz‰]=ÿ¿\²ÝI±tÿ¯”·9þ:Ÿ¹îf±·ÖQwu0‹ñBYíã™uj÷¦H§9™`ƒÞw52ËˈžŸ ·î€aL%è ÃÅùrNè~_JøÞ§›È½D[=h¸uºët‘)Ñì”sÊ ƒ-›Ëv@l.­mFZôédőÔèÆÜý¾üáëRdxõþ+åI\6g¢S L/L'B¨‰0“(·( ÅíÔï?£¨÷iO»=ë¹w]°^tæ…㮃͎§v€o­mpüJC­|Cñ¡žÉÅGQÍs,ÍXòŒÆ­Û-7”÷:Šú6<¬¦ö¶ž”@¶­NmRqZ)üÎÿÁ†wàti5Î + †³QPÿV6£ËÃØÜ`ýgäã=ëA“]$Áøöªˆh­­O¸ñ!$‚˜;rQ3”NãÖև å©O¢¾¡/"”ÒãüSÝζµI)ÉÔ\ìœç„ËÔo´V]Õ{•*q~ô*¡ìí+ Rã‚Ã1_ +¢Z ¢…þ‡kÅj€½gŽs )ÄÉ) +í¾9ÁÙÎb íµï¿[Û +∁¦xä*¼þŽ"ƒ½¨uÛzj“êÕP¯‡‹œÛó¾ÛO/âδJv:ËÊÎ=+ÌâvŽ>ü­Lù-5Q}9‡y^×÷;å×=³+§C¶œáFå»Jitž~Åûßö‡SÛ$?«sDoÆanXï[§‹Ñ®î«Tóz´3 íѹEoL:G[JÛÿž©å q¦(T)¡¨Uj㆜®4æé÷šõüvþNä{z=„_—ßeãT6/Ñ»œi¥g­ð̋řá:ÅRþ»Ëª¿v}µI;›!^tÒ±jù/¬\é‡ýD_¼bô°óâÂN°ð´fg +}‚ú¤w5¬›¿„„PÛV7Ž¹¯ì íœ*~ƿΆ„÷X 9O—öZy8}ÊV)ç•Æg¶Vrb³UœÝ ýbiښº«Ühãúgps¶’;t·BÅ×÷(p+£fŸƒçÜϼu›Ï«S^–¬Ž1.þ‡_LÇd½Ó>ü˜ñåQ"øšà!9 ß¾:8ù·KfíwÈÙÒ{j›c9!–÷ÒÄý|5›râ¨bYTw5)énà6g{úNØØÔ Ç̵]ˆ&¹¤À»òŽ•£uFo«sËæË­hæ½WLà—GÆHŠQÃ~è–÷JE®[î_Iõ»]ޟËÛ¨ñhŒºx\öï`&‡^Å~ú®÷º˜Çò¨¸\—¦„8-¡ª¾-æ=çâ’ß$‘2Á +ÇòŠ.4H¶/cÚ²[Ž^²îs«bu£æWU·4~Ü3­ÍÄ4|gŒææÃÈæ{9}zÅe=§Ôw<’îë$Ø›· BRvÿÁ0ì }û\ºÄÓê4 ‹éTÎë>ëA¯B¶H|Ì{!6K_û¨õ¬Ï禵#¬û:¶¹Ïµ@EwêvÀ\U/å°iä^Ñòù¹åxš²äñE鎻UI­†±øRcÑ [˜þK°Ç[‚Ÿ¢¢Á»‹Í÷×ð¨?Øs rÊs‹lÞæQ™ü +µFq£slÑ®Ïx!¸S[Zd(Ø9ÂøÍV«Êδíp¦Ï—¡T=5ì·ÆJ´¬ä‹¼>Ê-ä¤)ÝË,uó&.©—/¾ZSUȗ‚æ°/ŒÊRC(äÃ?­L–Ù‡À†ø¸î›HÐK@~PÄ'¤8½“Ã'nB¥ s:aUY£³'„E”óÀ÷™Â@cZqcŽÈ‚¼«g̳yýIæJS…çâ°N „Xv9ÂSbæàm:æ±!-}Nu +ΖR©Þ•|î7²_"¤ÁÓ €/Éhhpvÿírà“9ÕÆÑ|ežŸ¯_÷|žölu„mŒ&=Œ?Y,6:¶Jö)⥖ÇV­uíŸf5ê1¨þ|ænÝ©Öû¤ÖEݟ’¬”/sÁYå¾].@Û]æ0æZÔ[5Hc:éöi’pó0ǧ6¶Ç‹°rÃÑié“÷ršÏŸ¶ ¶Ž«HV1·ë6빚ö¡Ç¤pDö;‡ +Ù®´ÊR iyñwn ¹4-å—%õ¢wÚ{îKãªhA³;Š#F&aN èDE¿*1íÄOk1çóp&a¯Ý§îé„»¸çD©UŽL7·7ùa®žq¿&ò;Žwèə_Ñ&š^ÄrmÒV&"߈JöÑ©÷²=-»Ëjïa~'²›÷u 6ŸÈÒ~»¢–Õ:ÊDeè9 ô×Ã+†¬ý•»í~!‡óÈhôC¹Iϗ½ÜÞ`Á1-ÓNŸ4ãgÏ ËMŒFA+‹¢ÌŽ½lŸ»$Yý‚.àOKÚ§ˆp"¯aØzÂ$41$rAç볁Ñ§™)#Î ¬Ê§ ƈ UD—_¢'ÀßO°ÊΕ V8¨á1ô<·=,;‚‘­dŸ%ôÕ ƒ©ù¹Š…Œ´ç*AmI_…Ó„´òú÷À1vÕÅèŽÝB%4³ýý:†íó®ŸYhµ¨@ò“â,ÅhÈúHá!)Ž ÷†b[ä¡4ä‘z¥¸ò€\*€L:@¶V¿ÈV²­;€¬Š…*]í”*¼S*tUX6§¥¥GgH2Ã۝÷žÌ‘i½59|.g8¶çF¹#4 wÏèfMí@ÓÏ¢6Z£¨e+I1ý=\NÁP㒢ótÆS”¥ç" ñR ÐDf•b–4ÙPU€zÒ@}P'¼–~[îüÂtÑvOW²Ç´GWÙ.¡ÚÞ6+”·s®Àg +@i½Y¾lV¹ãYŸ#Ý×jœÍl¢„ÌÐÓEÐ0JÁ/“ v€¡ú'ÀÈ·'`) ˜jŸL:ŽLÑ @zaŸ#H·£=`zE0}ÉLôé¦q½&Ð\ÀàAúhòCÙ÷mçº×}³T¹hªØÒ¢K&({¤€ÔÉî½s®Yßï}êlàI“Xÿtèy’ë-ËÏ׀5¶À–?À6¾ëÁªÀW`߸œ#N;9€ÓÍp¥ûpåè8O¢g~J€³®é>iG½Ê€c ÕO F•Ó¥ôì$ Ñ¦ ÚKÛ½ç­ãÅW’œƒÛ'b\¨;\¬né=ÄÿêÐaûþÇxüGõ…À“¼í`?qУŸ<$À¯Y`àA`:)Ò'ˆÖç_ØÄ© +Òog‘‚:O?Çe/@ÀzØνáõM<‡„J¼»‚]5F%¡ï³¸DùÉP¹kÎà y 0Vh ˆðõù4ß~&íÏsÌ_õÑx *5ˆÕ£ Ä ïñ7€$c Ùã*Nî§u¶q#Å¥¤Î*ÝÝ]q@êmҏòï/Hô÷ë(ÞH‹!.–PŽ¬°­*咳¢cbg>’‘dxááü ˜_ßJò'û¢ý{<î¯Üûó÷þr&~Âï/gâ?á÷g­íÑM PË1PÚò¨™7*Ñå€*¹>P ܨU"Ý×l vùPëL¨‘ósw«ýwÇØñ­…b†í„߯:mÚFº5œÎ<Ô¬œ ð2¬?bøô¯8?­÷?kï/]â'øþ—.ñOðýæ¿`‡Ÿ¿·k<€Q Wú*ÐÛNèa ôžî{E` â(§xÀȽ†ÿ?ù¿lÖßÛ¿!?IõäÓ_üíâú|Ú8”¢ˆ§ñ)îÚóY ÿ{;õ§>ëďOiÒ{X«ùè·åÝÙC‡Ûœ£·Ò9ÊÝ°¦]ýÇ/9éJô½íÉ·?!u‹ wÑ ê­î;ÿÄÝ_¾ÀO9ý™Q.ÙÿÜÇ¿ðvúG–îCëÇ#A—àyû¯µ÷ŽT—ø­tXÒ7,: WÿrR.[ùj^ªÏŒ{>Yÿ̍ðú)Î +BÏ ²9ôÉ×gÿ©¯õ}—?ï¿„ŸAvf½:êτúG‡þÏ#ûÃOîýä¹øÔGOûaÍ!ÿî¬±Æ «#½ËVüŒÏõ³<říæxsÇó<¿ôõü±O¨ùg7áЉG¹mZ}kè 1l±ëÈ«Y˳w –â–é,:Ìê06;ôÏ·;ût¶ú?oì/sৡþ?]²Î²®D#“9׿“v“ uT¦'é /ÖnÂ,‹ÿ©—ÖôˆVÜ —âòÓXtˆgkþ Ÿ½¹~|&³DøÌfPZÿK•ållÃã‰ÈѶ¼UGôF©&ƒg +î¸ÌύMî'íþ¼±ý¾€^bÏ^ÿSÊoÂÕ?4öß ½énB­æ뭆N—gg·ZÜʗÓüY¹?gŸúžN¤6)½ÇÄxe;zÚhëö„½è)I„÷ŒnÙYyp‹–ÕAzŸ5û}ùÑï}ú¹Y/1 +‡4ê¾».’¡:óò®Ò)ãé Æ6çÓÏûçU@'‡Ö6 +vÿ_úcO^—êEØì?åyu0³þ\ßÑ¥)Ҟ”Ç+£ô $Â:ƒaLv¦ƒÛY÷ûb|è}:k„®› ?]d܂;e¤•ë`óÙòS®µ­¬•Ÿ¤JƒB|ˆÈ æ.v«ynM¦Mñ‰œ£“o¨™^å-¶ïæ’ÿÁwߟ"nys»söiuõUx'sNÏÎT¦·ê‰íë—öwš¨õêjIš…N9ýÿÚAnµBb؎áxsÇñ¸™þió¦xÝle¹o(Ïë5ê×gdd0¸ž8^‡æŽPK½]C֏j8¯!vت°øv ªÄÍõ*ÛN¦¯:µÿp+Càr®3Ÿ¿ô¡7Úaq Ò>Ò³îíg§ q¯Ö¶üñ¡rGšçú‹lÜâ=»/5Ò?h¡žØùršþ,#57GF5dÉ·Â2Á÷BlkŒªcÏ«Ä1ÚUB¡ í]&ˆT’ôÏWñcsëy·‰Øó:Eá]~.÷Bù¹ìÿƒÓeÔ½¬Sô›54®Œç…¾ÙÉ2íõiÅ cumJu°i(·Á®þx‡:4ön5d^!¶®çªÕ¦*ÛúP¨Ðç¡âp÷¯üؽú¾ø¾†Þ-Éƞ +ãýòsWüŽÊÛ:”ÒÆïS²m™(Nv#½è֙Н>·|ù®—iên~ìkÿa?–²ÇÙ¸¯ÅƒÇ5ڛ™Ž7y×Ç8Ôrž¹ ½ÂuæKËïA•$««à˜kžü‹5{ûÒöŒx]æI”_CŒ/,N)ƒ­b–Fa©X‚_Õ 8 Å\fÖuÛÌÔÅa﬏­·C™¢P›hZuw¡}ÊÍw¶Ç_åÖºJgùÿ`C·ýÝOŒîÎÚڼui™„jõZÛÍd8õÛÒ÷[o$ñe ™•ß ´)gäœVáâ»8£]¤˜‹Â]òï•æ⣉âl +[Ó¡f·°J½ÐMûÔr¶ðh/­vézµ”¼…š½ÊX4ÞOÁ7†taX~>o@DYü_@¶°xÁÛÕ/ظnðï0*²Çe´.ћÏSÛòç¤OJ%镜HKÙµ1(æöÔ%°`ëTãþµ°¿OÞ®xDì3[Œóœu“xÙêÀeË|ÒÙÏ%¡ñiž;F"Ñ߁uý£î搎¬tN+“Ë¢†í#uÕ¡j`¢Â¬Œ¨®ya6íyTX±ô +?§qÐrÖן¸[\(Ÿ±Œì®³Þ›½\“, +qIìX}-¬Û’§ïêqjÞ÷”}í=Q꺼•O‰y–›Aã%‹ä–Úµ&)ڛJ{‰i ¸â Ãݱ-@9ã8¼ðˆ r\©¨fpMv•Ñì +Êq&âßÛó·å0"ˆG?Vœ–Vçsƾ(àn‰ÓѾɷ…9¼ç‡"ÔÚÚ²wª©Õ ^QêµRM>½ÛYôljÔÞn’ÒÍÄÞ;wõ¥„_ýöl„„è‘‚u;‰üD}¼óÊÜÜò\ZØUM:±Äie¶1/3ôýPgègîÎЇ ÄȉýƒêsÃôÁ¬×øš]åFUž˜YðÏýÓ¡‰†ÚJÑZ*ôBù¬)tó‰Šø숱h V_ø,êSÁ†ºîÏü¤ý~ò®ËÁ<Š:8Wö|–ËãC•]]ßE–T©¼Ø÷¯rKG“Dóî]¤âeT¥¤`x¦âQJÑf¨ó¥ÇÐ|~ÈtWŠÕN?›³‚ÛL"Keyñ.œíƒù9÷ç?ZÝÎå¶kNURE, çà vôùFñ“˧ͣ‘p D_påCóÀ®ùö• .³7KŽ>(³shŠ©!ŽDËu‹nð×*ui³=Jz6Öä}€RË´8â5QbPôOÄ@çâ•~–TgÎ÷‰ü߶Ã(®—‹'Óï¯`¢HꍗÝÙ8{cr/Ï´`<(Ñ:ےԦ +ö|îñî%,qÕ Ùu½ßdÉϼÇì’Û„a)hE÷ܑnÔ­;-èßºQ—Ï*Oµ’G>²´Nv÷uxs›a¶Ø‘‘/¼ÐhZ"˜Ð!Ÿ‰Ï®n™©­È2ݸKuêZTcª ”¼ìÏÈGó°%{t!Þ]ìE 55KX¹˜"2˃‚;$ââٝßȗØÍ[ÆòwQ̗NDnÓKÇÕU£³ÊmqÃ+ó^Û?h¾šAT叢ZFÝ|á2žfGv?É\i”+IÓ6-!Ë5¯ô¦ŽIeê:9º¤n®¿Ê-1Ü\"¢/-|üÊqg ÎqÄ,oóóLÿš/·Ÿ<’yÌ?¦w8Ñ蘹êõ\ÉÑgˆÖ_û#Ê «ÃY‰³Æi>™,r¦圐@ëi›¦¿à0èŽ>J±ÒÖrv÷”{Å´W÷3—[o(šÃq‹[zHÙÏâ +uƒÑ2©F.î"7ŸÅ +T¼:FR­v.¬†9†[ÏÐÃìШÅs P¾PƒKvM"ñ<¯ R9ò²wêe;›ö>«†’¶ K î/}¸¿ºdà0ȬÊÛd¶SvÉچj~¦>—]vNå,ózzèøt»SN!:—z²ù!…ì­×f«­[·BèËÃ'ãV[ç©z¬½KHË¿ˆLfê)äN¶[3“ÝeVcwGøuF_ð .ä`Sñé¨äeC=hd¦ÉmžÉeýï4XÌ ,™:X ù¯×ìˆgŠ¹ ž™–Qm¬WÆ`W,´ã+j"Èì¡Ñìj/__ðB„8jÈùG¿MŸ{ۈìOÕ*>ŏ>¶Ž¼z|dDn¾“Åð{rª@ãÆ8„²×a”™µ7LIyÀr[ß4O€Èt?€€²DŠ†˜ Sl§TŸêÀlðS¾]2EžxӁ>˜}â"=L´OqˆüRYTn8?Húå¸àËR6a¢±Þ!_AÒÀ§C¾†Uæ£mRrQ¸l þˆ§„ f@¬/ªõã6 ^™Q +-=$:ºü”Û\JÑ`‰ÁVŠNȼ²$Žd™Ù«€¸Z€xÀ ö³¹úƒ‡"ÿºÎsAUmÛÖOpbˆäœ£€(ŠYL˜sÎñý/R5÷\gÝ}þ´9«,¡K1>­ç½lX>Š6ôc& /µÓ ’7›.yîx1ݹùe\¶ð²GÔÑæeQ…#3SJ;¤üã²èÍ Ë©èÜ d Cµæ€‘/{À8ú3–> +—béx€É²­XN[Àxƒø£ä$€Øtú€'`Èr0©¶èk-Ÿ§GTÖyù#1ƒ6g„.îkoyÔ¨œ&讙Çx?¥²-mˆW¨NU2t î3—š °Á¾Ðøï/æm41Öè–_k‚`kú°½ð +ØÙ=؃Cÿº_Ù`§>`O`ÏnüÂE)üqÛ `»nõ¯ûØkÌ ÏÉø—ïÚdô¡¼û#Rˆsao¹þžšÌ+¼ŠËSTõc8s­ !œHGñ2F]À¥_À¹Üp-kú+ëh¸Ëùx’}^òà sðM*qBòƒž ø•ÔŒe=üÈ{~,J€ïàuÀwS{À×Ràë^xÿ°¼µZgÛyÊÏ`¾ªµ7YJšW˜ /þ“†¡Ñß»ï=ò¤‹Z²ÿæÐ ‚^àÿÛ{.èogü˜ÎR@¤{K˜ÄQ+âíÅ2Üý†MLÙø…^ª Ä$QÇb?­±™1À>I£;ǁž£¶ Åy6/vH&õ觉 +÷ú z”yÀ0œº§˜Iþü[ÉdöüωçøÇn\À„ˆÄAœÐß$y"¡¿C2ÒÏY>;AÈ;dËàäG‘ò“Ï¥§@Áh(8• +‘YùòugXëþ¹¤¾«SW܂å·ké«øR$Ƨk’08[¿¢)ö£A¿e%ñmljÝx<Õä9 úýë«MòòTÔY3ñCkÙÌh´ÉÂÚ®íQ‹÷¬ñ@G»  cÐñ› tP®òoÊóQâUôhìmf°[ËWá)u”R»k†· ÃÿÖtM¢õëH˜ó_Ÿq+œ˜|ð›¤K|¾ÿ0ù~¯®wÀ¨zo`Â4 LæàS€éµÀ¬¶T`ö&IÔ± âß4Ê0›Õð-öo¾ÀZqYOóO—³$¼!ɾmþ¸z“¬Þ*óۗÍy™?ÍÎ"X/$ +¯—CÜo>  èÞ³»úè6ç£å o®Ž×•BƒËÖ¸ ;Ô*çƒs%a·‰$ 5!¼?œòËPÿÀÝ¿LRD~j‚O¿ÙÂÁ‹¥]û“}›[?ÍIõô€ +îížÝ>·ü!›¾®Ä,v¥ZYêR~d¹óÁÌJga˜×OaºhŸäiÏ?jË^åQËöþSy­½{¨)wHçÊlóïFþ'£áë3N\²3¨_Ñ~êׇúßðé¥6G>÷€òŽrG‚À¹åwQp¥šaý|Ð+߃S˜rúGm.ŽÿôK¯vl·sùrØ_£Óº’êÞV‡lÿ½<û½ôR^Ïȅ¶_ +óHx˜³OK fPoôm6‚þ‘~ð•á¡J’ÿó›/=#6õ¯*ö´ò¸®ØÝõ,ôŒÛ±“†ŸûOáí¡ò“Øe”¸Þši%L=mq+ŠæüY¡Ù§‘öföøӉJS$J¼€p¼rÓ½15#Æ£ +.®†‡À;…]ø„ü‘êßBÝêwTm={§[Âu#óóø$VÙμˆ_ú¿84wMrvÆú⇣ìÍOµæænÍìÓi:ÍÞ®›Iþu=©ñæ>bç³÷PX¡«ì­6$ÿXe#¡÷éFÊ«ìÁëzгԙçð°ƒ/ÍQ; š_ÝÚVŸV…«-ö<ꆇ½þñÆ~ݲÍИηAuú'S½µ ;Z—_jinnÏ֏€:b§#cR9«¯3^I¥rïÓn…=(j|OÏ.2ªŽ:>ܘ·WùƺM­ûV…®žÂCµz …SõÕ<7{PS¾ñÆ­såÚÖ둭æjŸI£Qz¯IÍÁ:ê$ͪǍ*²—[ñÿìv"_ÖùýÍ}‚éñN†´ñòìÎò äÖÑ7E"ºÙw”îà“mm Ùb7ÖÙÐhžë‘Û¸µ:~C{DåzdFõÚgµjNºÓ­AÓÉ°êa“i²šåvUñ©ó¡‚ïðG9à•tiÛ ˜RE>˜Á¡ËAÝá3NC7gIJÈÿK.l‹\¯Ù£Qžàû—Ôמfº‹ Økkëû_GW(ìÑ]£#ïŽuóտԆ™Å»:É.ãõÏ÷dÅ'®|yUz(ejÿ0Jáa—Ø œ -&„S-ž{jX”?™¨Ðqr“‚žíü(wyønàùaÐývË; QÈCûÃ$7©ŸÑœ'eÕÉ~¤ç37ž=÷ïKƒo¯ÐTaçX^fV´š½Ê<Ÿ–Zž”¶UmšÚ>nöµêùoPáÖ¯À=UÁýç¸ÃøÒòŸùDÍ;ÄÄÌCëC67)}Š9ä€×=_”{~i/³zºf©§‰ºÛh£º\*Wuÿ䦋Hý•ïysJsѨz¨Ø]¬U$›êúð¨Î¸î¦Ìä{£àxGºÅK£Ò(†m«UèX å?GÄ ÿ™³¼#(ÛÜ$´Î94í=¼ù® yßE³«÷šÎƒ‹àîhð½áVvœãy½àÔߝ¦}±#»E›‡Ì½:Leº+X¯pV°ú¥ûÞê·§˜•ÑäôÛGj>ȖZý^÷e¶û†Õ²¡u-íŸØ²ðx#}ßF¬ï¨3ï®ÖåËtR[=¦jN3·ík–ÚêÁøb»Ì£^ÚgLкZïÑèe Ü}ÚJÍN¸9®cœ _صrŽÃý’^Ì_::EXK­\ÞÕý“£ÔZtöTÁN­U¡xBb¹¢ñ{$‘x–˜ý>*ßÞ^1¥6yÒéàÂ6Ž¾3Èξë֛ñÙzd`wˆ¶gk%ÛÍ<âó×úàåšeíŽ)û±™¾W&’'F~Å\ n_änvù– äKýNKɔÅQ»l‹®vªӅ:0rtà[ æIn­sëÓmÄ­ÏËOPúG +’î¡Ïo¤0êûLaIj:Ÿü ;í²üh5±É¢m¹c¸j,>ł^ªœ]mׯ[êqãÛÊåàçÕª—嘄²QÚFқùL¥þZK™È>I)«üÝQ˜áҖrûgBn±ºlñ…K¹ÈmÔ}—+#…»÷¯Ëo + +sªÔ#–ß5Ÿ,?Clõ¾ú‘Î&Íåk3òÆô•+Rƒ­síUF ‡6±Ù¾¢—i³ ñýùר¬Jmǒæ]“5çI†+H©žUÇù°+fñÉH˜ó¹Wž;{PW~ÙÓÞ|Ѭ Üf5á¸rð1Øý^öYAh·™f+µbdµõ¡Û)ÒZFüŽÓhÍfot»YIÑ×S¢¯ËzªÍ÷×Ùj‘0…÷áõòʕæ6ñC[ÙB£mPø¬¢ <î+×MǕ{>aJ¶²ÐÄñôî +³å1/äÃtYÀ1ä‹SëËx*L¸-ÖYqåÓáı!ôdkw:Í +]fB,RyùÉÑÚ©gu¹ Ì³ô$?áU ‡ê=$‡ìùB~*VŠ2'N,„×qË­°b…N|æñj²µEv“ù8úÈÄ˙_-7>¾Ü{®8¾/taŽUU~%—Lžšt=®Âõ {ÜÕØCãÕfë67dÎe΄ž·e.ºÒ·ãк pêy³א¥‡9\|ê¤S¬ÍˆÉ.õ P¾ÉâóU¡B ÄðLxüȤA€¦é«v¾Ï?WÞ°ë Ô%†¯IvµŠ¢]ϾO›?µ¾“Bž†2*ÇqŒÊŠÉf‘c”r¡Dßµ~“Ö£Q—zYÇ1ÕO%em”#ÊÁ“t]˜L×ï‘K)¾ÈvÊxeÇغ0¸bôV Ð].bôÌú&\bÁcõÁÖÌöGêúaÚé‚稳zstYÿ sŽ€CUáóÙÒV¾è¹´ÃÓvÃ`ºª1Êå$Ó|5©~ííRàüΓ£Y&]×ýƐ0\íÓÙhF`øbƒ/.é+^h)lý¨RX©wÑÑ=PŠ(ïNúÈ 1OHcþ$©p* ñvÙ!°òFŽçÎåñèSÃßc³ žøÌm ¾þ4cZ41x„¿È<ú‚¿'\ŽÛVM¦U 5ê Ïdrôi*DîÞÎàË\/‹“ËžmŠË +V¦-ŒÙ‘tßuhÍèQþ}|!MÃ9]ú`àëôž‡ÛùJÖü~¬çXÚd‹ñÁ-ӏ®÷Õÿ#ÎÓ4ß[ÐÄgnM•h©ï²£ªìö¡l݄Š˜#¢O¿_.sE mŒáï!@ŽÍB`wMÄXWQ¡Ãf³.g‘æË. r¿Vƒo™qî¤N#X›kXÛ¶îéˆ[¦Óæ‰á¡O³ëBööÕHMøÊ2…„Ð̕ƒžBÊä8–¤×wj¡o’‰wI¹Ü”\IÃ`ûu\ÌB®²ÔŽ‡þPéV÷-Éõت@ª•{’/Yº—q3ä¸wÒãQYSÅÊoVBÎ㧠wæ3]žNÚjC9høD¾Tr"¹¥­|/5ƒY +u7;àÏS@øy<–‡ˆB·ˆ¢3„ƒ|byê€ÐøI,—øï8$’ä³dOø>#µ‹QZzKõ*6¾”Cî¿7mk@U®&XFÓ×eU›ÀW{ã0[EÂ-$ÃúᬤÁåf¥rù(HÚùJ˜¤r®ReÛ±”DZœv€ÔŒW,Kº‘4t"õW Æd H!€)Ú ¥é +T) H¨‹'’_æâcZKâ.f/I*‹òˆçF?¼œU·U&>ÍÊ!û9‚Iã¦Ë Ò*¿06…< ‘bÐl¯è쵓pèŠ4t§µôäuô4‡º»Ýór€Ž n,› ûcÐÍFè`x´»•ãe° 5Üvoó—ñ(;mlKù»ò\ˆÑÕ _¿sO:£ÌC¢°E«èiT ­— Òõ.¤üF3^MÛö“ê#-¿Ñ§ +`Š| 0Í\˜åh˜Óe X\?V~kÑT,‘،P¬´L,Š¬ÜxV))€e¬`‘ì0¯™¿©%Þc§ª¼µ€Ê¨~Ø»4-;ž7˜=°ì±|Ï»è¹O‡pôX4ÒéUµJËT\Β¬–Ï…ÉjªÝίy·‹@|üÇ(sÀ¹áp¥Õpcü¸k<I±Ô<ÀÓX+–éðp! ¸§žÜKîd¦·•7r¦‰|-ñ)0•jCF•Ìy +eŸ>1%­IB-ÏÐKg5„©`å-ô‡fÒÃú̃Îò×x쟷€¯?w?è—É' på;¼m*qw)»2ÄôÃ"S(‘$²Ã3¹€"¦ù ž«¬€ ×(­}Nr&¬e­$kZY#\ËÞUñNa\á„5óË<äå/‡†üömõ[VRQR‡W»ýæ'Ì7 ›Hœ¾IØÄðû믍x H‡VÈ(¹¶\e×±R@Î×¾3i û¹øy$ÈöD ;͐Õ}Ȭ!¢RÒå©es¼TÑ1J.’£’Ò*œ–·_Ôä°Ð¯çø¯¿1’ÓóÇç›@֟ˆ‰ÿ¤;üƒù†  +x ¨³ñÄ°+P_p8a?ú†'e%QÇ }þOœððý›)üt‰ßÄڛ0ß$Óáu9£ÚJ£§«ñ”ˆ­ão‰Á0q¢ L‘ÝSÂãe¦üÇ ›øOEäõM\²I‹³$¼¡WOª c)lþ¸zaKÿâ°V~{ÍpCäP.ݳ;´þ'W]©ŽµJ²oÏõÔ=½•’—fÿx+æ¿H5 ½Mj҃ë'dà¿g´&™I½_,ýސdßî; –ŽGÙÒæ>!±Ã-¿\®Åóþ~)ßgßûžçƒ1O…Á9…Ðœ8Þ¼{ÔâIÒ!"ÏÆ~ÈÞ²»‰ø ¶s 7&ë +¼|­êDM_žKË|Šä ŒWùŸ0Ô… üpè¿õ*èÊ݉ۜZ37¼òR¯Åí^ØZøŠÐ¨í‡t)ÜeOFg‹w°Þ†ŠÞƒ5;ڏVux?[†ørµ¸›ýB۝®sótú¢¡™}{¢Ó‰Áò“¹m[|²¯lwS«ÐçÄƛdÊ&Ù®‡™·mҟ¤Úý±:j“önoo„ýv.|Îë­1ù¶ÙY³ƒ#´ ѶÐ6 jö©ç¸éDå…ÉÜÄä >Äôq†­Ñ6»#v ç‡õx0:8W˜Æ@>ª½~G*Ì¢Hkì{Ÿh÷î9)‰éA±ÚõÐç&©)aKᚸe[ÑÙþ H¼¼‰u?$¢ÞKöØþ j|Š“üs^`ÞmÝsÄÎ>³AHϗý?ÙEÏæäôc•µ_ïü¦;ɄŸ®—Ŭìïàó)Óˆ…ئÖ/³Uaé|x¨;õP¸DÃf¨~ö[ÔÁÌ¸ô¯,ÙÚg~ê×bÐK\²çƒšZÅ[| T\ nW攜 {"z֛Lo¨Ú\wbÚJgîØVÇO×ríU®Wnm‹Ízx¨”[¡p,÷š¡T6ní⤡=‹‹ú3ªmêhkC·}«A³ ¨Æ›Hêš•*>StË«øÊ˜[”©k•þë’ý‡Tt¯œ˜¢·ùÓ¥1³¡žÞÞ'ܼ;~êyn±ëàÜ<×ô[㊯†vÏ|.¯GFŽ¬›ï–Ps †ZõВY™JNÅ'[ùòªÜ(–¶_-mëÝF©".ºÁ¡µÂã8/ž#úXT€ó.tÜ>YÐT÷#¿Rò£B~å[TÍ¶×/LIþMÄ·èTæ`ÎýÙ§²2a<•H oXgÀªÑ‘ÝImhmUd֞TðUy^èÚ¦´­öÎ%ö4~‡æ*ž;+´êgªp럹‚ž:çžþsüÔüÈC2ùÏÉæ‡9ÈC³žóØb/‡– Ï—à‹‡_ËH6ЮJ6Чµ,õÞ^³Ô'dÜí°Î&ÿq«zèŒ*«µÔõv‡T³+_«U-]HË«å',U8§Ô%¥V”ŸDXèXhǏÜôÀ·`qžæõmZY§Ü$ðï9d翽yµ‘öðSÍ®š]*È ÁÝvÖª[Ñ_¶s§nûߑ}žL&v˜c϶‚ ÑL'ŒL§”gt–xÆ⦤S.Á ŒŽúí6¢Ï£sÕU‰wä¨ðˆ‡u~ó£4ŸÍC‹k.ç‘×¢7/_¿tÐÃï0HpänÛØØeŸØÜ9DüÆ©[ÆÑ>Œ«º¹—­ÀÍtæ6ßðÖs –ŨysXk4MG3ºTnƤMІç 5åᭁÕïéi ¹Ö+ùaÌd#§³Œ§õé]JûÚfZ0SQ;7s¦el¹liÖ$mq¸‡¢SuæÂääo¯Ù¹ð (žøS”à֘%st1òØʝúÞÂc¹î`ÍÔ?BŠG°ÅˆceËäÄÔ¯ós”ç–˜ï •Rºó)€éi“­ºAß6¸\ݜöš½¤Ïmõئ5åR[HŠfXYï¦()z“¢læ{ÿ&¾0K1]ÉåïU- h¿Ûà…]/¯1OléWâ”#G¿ê/¶š™¢Ìqü˜†ç¹ôe±mÒ*¥-¨neù¢ ¾§Q†°RÝzp¤îóʏīivi“+so땟.k·1sú™”Ä׌ÂÐöµj?²•Ë3­ÉÝ°!Jý*ʣ’¦í+Äc +™_Ìß&O’)—[_¥"Wj»5ŽÑªm¶:ïXÞ_ŸŠ`NÄkÇHeâF_µL«Ñ”£z©t†2Æa=¾ä@32Uh>‰1•Uˆ1ÝÄ dfdÉþÅ962<ÎWˆxæ–Pyå´>\dÁåTU/ÝÙ¼ÚLÕ¿ 0 ‚–2Ӝ(™+#`Ù6ɓõ"ŕ.M‘Ý»m•­Á³ ËÏN9¦)¼KŒt!ôµ¥vé¶[Ð<ÝP½üñB™“"­C¦k“ÈZb…@Àê;†ÆóYóŽ-ˆ-㹎½ï{|VC‰ÔaéÌ{Èå‘øÌmzõLl­j5É+í¬oKïáN³˜!òËò’áÊ¢M°5ǘÓÞä™øá;[£ÛC[§5§ìPOz\ z»}•2«ï9øÒf$䴎Dvºxás<…ãùsCÇVÊ«„Q½`„–Ïç3ʶ&ʶß´|[ìÑ-µÞc”/«ðLžñ(Ø {ËÖ +ì2cëë®A ›ªÚì?ór/R2”žjB¾È‹Üæ0`˜3Ãô͸aÔ³x¦(óöÈ¡þ”Ic-Zš1)“ |ޙuq_$ ó[,(–èv;CÑJ•‘‘é[@ê¡8@DåpÃZ……Ãú²ˆÜ耈hwÔõþ¾Â‡ô8wuåÒsaeû£nÂ˕›tÎKC@gD$×ýž7|q‹‰ñ´¬ÆзERQ󀓎b„׈X|‘Šñ4m¢bköÁ‚Ã'‡Ñ ¶Œî2ùZMõ†È1»\" » ⢘†/…«·¨B>}¯Ü{é._ÿrè´_,ÒúºXKwIw“¾gXi´%9wÇrÅ3sI|æ&>.ud.?Û«¼h[À—U«°o‘ Ke–zá8E:“ N }ÅJšB ñ×Ú÷6r¼è"ÒhyZ,‘ƒHî¹_¤·æf«~sž~ûcº»ôfk ”©?l(%5”[+0=öÓ)˜ÿ)XXNS®Oî ðT÷ÅH¡{K’,2ð>3hÄí$È\ú<‡y…Ó6«:[Ýy9rä@4¾"+µåë(_[k0-¤3QI÷òŽ½W¾ ‚N ²ém˜WŸ_Ïm*+È+0 ËW€Ý·ÀE `O¦Ë} °ã4 °Ó'Øy?ؚ<$âOØ ã“åM½™v¥Î?yù,íp\ÇÕªÿ½ã‘²<‘ë<¬t ”*8|½¤ñt½®6>Ñ7ŸÒÉsÒxÏ,<Êì^ïÞÉ­Õ7d¿ÚÅ£I,¹©zi‘¹/›U1BŸ§O‡i5â+hÿ±Tˆ™¢ X93g3âSp‡Étä¢$”Æ^, ôÖ×yo-ÅrQQål@tëÅX¶ @ôØA,í "øK“DŸÏÄro¢99" )@”z@”×x)<”H¶¶AÆõ…ƒ¾»¥¿€F3_òô +¨7 Ç2ŠßñÑ ±|†€ºì_€º.5@m× ¢f¨ÞPKĆ(òclvŸ£&sèB/ß_¾RMFOë%ÒkwóØ®»HkÐΤßۂð‰Ëɇ* öÐ,b:+|#+´, ÇÍb¡7›` ¬ 9ӌݝ&L3 Þ±ÄûU,À´¡j,Ë`:0Ֆ ˜|8L~CÉAÁš{0ØuQ,p_ +«Éõ{z²Jµ¨ôÛªa{±QDÚ5ÆO©S>EÙì?9tf_̎×õV€Å2MÀ¥`sÝ.`»÷1`÷Ê +ppý8÷ù\ÛÇb9'´\'Ÿ\î®:=®Ö¢gà2å à””¸ôº˽oùNÂD$t¶[sRf?¦Æ.ÔÃي"Ö±‘vÎ¥X¿áʏú[I¡úœ0ߒ2Üțý:}‰áê×îû~å à_íô„j–ÂôjaVªaŃÍ_@h„ +ŠÍ6‚ÖêÂN1ûY&/Qˆ1ù¤÷-~õr?¬wXª©õ€Ú;}q7P£j_U€ÚL׀B ¶p¨e¬ԊõjÕ·dtD1ÜUW0*?̤°p3zÃn‰¦X¨÷‡'¬7©éëyþAÏã©þ?ÿ‰˜HJø—Ï8a¾‰É—±›ÿô÷&ÛúÕ00ú ~Mà =`øå0…0šUÃÎëN²oŒÍ8û¿X_b™M\½I~Câ’ŝXÊåXNÝ?-ÙWïññ|:L:7~‡ÓåŸæ´+?†XW@Ånæ>¡߇/îHeÜðÆ¢v-^/ÝKùùšœë)bw +ïs¼,ûð,ÚIâí.ûPZ]²ãïs Cý?\²¿-Îþço÷8-Ë ñ4Çûþòg“Ûœi/®+¡¹½”ïöþ\{˧ÓٖoǛG=Ú‚‡ˆ¤áýEñ=Tç¸í\EåMñ“¶ÖìõWÂR—òvûõu.:ü–Oty˜0ÔČúßJ} ÓÃ÷)6àkñ(!¶ÍÓçƒVPNg«”9<󌻇*ûÜ6m~ۅ¬·–\X\¶¼<ç¡êR^AÍE‡ú´çw‹fŸÆs<³oÐrš}Aû‰ŸÂïãUÖAF[¿ÎØ ” +‡Çjpn̐|m#}í©AIŒlÇ'?ç6u÷ÿ‹Cÿ´äú& $>Ô݄éŒÖ[ý>\ÕSëéRžO׋N¼Ïæ³{Ì °û™Ì"4^ÙYt´õ4bÄ.dz(l(n²¸Ø¿Õqµ¯]¨/ˆ"UðzŸžYêٟr«ë¥Û£ÎC¿Z:•f šV:U ¢Ê¼XW|*Z–W•É¾LϏRE&àÐñ„@xÍÝây`·‹¡ã>‹ +ìšÿ0È*p?Wèä ÙãÍÎ~ç7KyVóF['Ç$·½ÊΏ¡°»,ëώ1« 3̪:ÉÂÛª‡ðçÊÜWŸŸ(¦Ë«R/mkyºÄžó|pkJ ÜËzñÜmfŠò»™-܃BA‡fß48?ò6-ßÂàQ~XT7yhÛxä&Õ™CNӛ‡bÛóU?åÍÛ¬ü/ILÑñN®²=¨[~$„·nÆãž*2Zå€ւCÃÿRõâ¹mµ‹òӊ +·¨2-è ¾òŸ£ÉÑ·àÉ5?ÌOžyߥr“`‡ä<úBä=`=_¢‡Ÿi=(¢ãn»NÑ­QèÏ©Sw²gû<Ý¢öyÖþö²C·´ÃB?Ëû+ 2" O…‡µµ«¥‰Í ´tjÅPæ ÚÇpóŸx:“‡o?瑏À›—UÏç°VvÕ £l ©wÛV‰Vs·Î!ÊœºU¸:"h¼ìÐm¦lc™ÛìÄft"¥Zϵ‘µ,¦U3?‡ôØtÄàlBW”0¡[2¡»º¥ûüG™¾Ý!åïm¢z†š®KÕ@èù¯ý«œ›VÏó¯53Ôn’» çŠËÞç†S7âÃ÷¬sp +Ë£|VDë‰y7»ÖÀö$s¬΄­iL×Uژ–¼á=J¢¾0KªN¬º¶V¢»žFߓ‡dÕ]÷RS«fº­WD_iÊT‘h#·ºáYVíGêӄd8¾*öw碘ÌHOVk„kÓª{•E,áJp;U»Œ}Ðj^_ï OŒúŽ¡½UzWsäúÀ³ï­aÌ^„¨/×}FÛôx\+cD+-߄Æ80«V§)A9a°ª4Nª­HÍ\^nÝr¬vuéá-ºR½ŒÄw3½²rSï ï÷ÕÇøYæ.ñØÄÊqKïÐáÈ¥½eË4„±e5Se˘±›61çÈ =›•0]ޒo_Ïý,{jU3‘›ÏšÈ6Ôõ€x‰ê!ïÒÊY¾bJ³Óþ6©‹‡pyH¾ö›„Ü–š´ôDÉDƚø>ÄgÑ ‘Ê‹©+\Æm¾!d³¹?›—Æ|Þ­¹åúxáŠm5Ínž-že­—ËÔÆ^“>#ç%Ý\ aZ.n¾óº¹êOè3¾˜2Bþ8kD)1UÒ&<‡‘s¾¹•Ädl\ k³”0`(¹ã-1éÙȧ“‘ŸøÑ(X´ë8.B–Æ +ّ) H©fòù}íëàñÚÀçVæ©Ê Õb·.9`+LnÉj#S®€>·xš–Ý Õ±Ð:ù…óø»ÄJ‘Z̓Q.3"ŸÓ҄Š¯;Óºƒ$E{kôì΋)Ç«1½îj;Iє‹ÐàЮÕèa¢Ã"4Û¿ä<ü<|â<~¿Q\ûðS*»]É[ ‹9æp/L½;h0bîÑá +žÑJ`ì©Î®ñ½ÃN¾ø=AZ¡j@ÙU §gMñÉçùƧ)9‡O¡Ô€pƄž2“Š¯>…è¾Ye+®“é‹ï’Q >n¡å{Xà%ë¸'Åt; +h‚x8ø~§qÁ4ûdw|³\3ę£ÑL:HôÅ;ët ýØ´r|êÞÌV)ýVn“¯ÉrLösð–KõN¸TçՔ†£§R +(`Œ÷É]÷Î.F<7IWùûá薙TÖéÊËwNµE’#bZ§’^ò¶ŽϾUéuÏð¢+ÍH}š(··)vWÍ¿˜ã€}0$ºU±Pê~Ô ªÛ8ÊÈtòšG6dó̑™ +U&FG¡I¸âŸ¥Æ+Ë^/صŒ,,´´UdÏ-†HõTy ÕÕÄAªñWÊø§1ZŠ®ã2·äùœœ_8­æ¥mN÷ã@«.&ß#MQóUJñ 'äÚ=’'E +aw÷IŠi ´­–owªû¼½Èw…ÉÌ&‘©6GîS8r4|懞'ælY:Ô°"‹t1ò™Ÿ£ekpBö£Ï7-©ek" dnúCX†”+,§–álnª½Â_ö“à²yÝs¤.Ìm£3jK¡$È\6VkUtO Ï/Ù&É1-aNF'E«[*®n~ø>½J¦.À#€çkSDž5ŽÃƒQnZF·0g¢å™ã¡l>,#áÜAjvŠ­Ún>¶–#“O߬k>­s=¨÷¼¡Þ•¡Þj¦µZóÛÊ%ÝÞ&E£Þ¿f÷Ög–ɼZ-}–ƒdn§»Š'ß·©I¶¦B(#½;eêø›„ÄíŸÃÁ +~œ'Z¡Ýrèæ¤n”ˆX¦<"b÷/ †Ï+ÃÀ* +6Ó·Ý!²×„-ô<—Ÿ¥œ©Ô°—µSÐçOÍ­_IÀ¤USЎ¦†Av\Hµ +·é®¦’rC­V +òãéØb6WýÂ{~¹yóKdIæ´{¢Ô“ + Ҏ>o|îŸX`zw”S¸;"VU+>¾Û*–îB.Ö' zySê£M¢’É^7•îtfÀ{ÝÎøßÌ€) á¾ ÐVw Ðöˆhe^hU›$’DÉØO<+„iªÍ^>–bÿ¸Ë©ì•gkë,E·ß[”ütü4áIi€­öÑ ­œýïõwâV15½!†RŒ¦`ñŠƒéf¦aR,¹L,ÓÀt"Œ%œÌ@α 1€™Y `ߘx?LÀh¶Ëx•È÷êY¾íû.ŽôŠ˜j*)þ"óAAå*ÈU`ä‡LQ–<LjÉс±5s(w®¿‰v^°ZÕßЀ"S)x~?ÄzË%®Oñ\,5!·©©p-Åt¾^ùÀéâ àépx¿Š4z{Y€½=`çÞ0^LÄ å½…bèH«‡×¦ŸÅ‹y`4V—߇/¨—ÀÒdº3'p⪠(oî DN¡ô£[Ð` ~Ày§ÞH!±q•}ƒø¢!üu1þær±Tª±œ#€ìu,û' @‘DŠñ@ !ÀoÛ'Àw[à>þ4óÅ3»;#¸î†ª2g‚ û „L» 2§»ê@$]‡bq²Ð!QþÀaðõüBÓ½û A! ðçý“¬F—¾0ºD¢2âÑ9J€˜¦5@ܐéa ÆRÞì‰Ø –‡H´_Ä۟âã¤q±@l{@LrH"ÖtxûrGFC¥›[†’‹º(³¢ªi¿.äÇÍ4+ç­@—gu@ORÀ@¥)`¨ã0´õLzÍö@?¡V,ûCˆÐËE5¾ú‰©øíT&1 ,6Ù©×ùe&!иÃÕfà +m¾.>AX¼‹Š§š ـàõAû­é/‡þ_úÚôãñw5?à·ñþuü2ïLXc:l-=ìÞߎ9?ÇZx,ñ"94öö´xv5Õ;štÛ~¦›“Êñ +¡~àÏÇ$|ûûÕ¹í׺Œ>œ4ˆÅøRJ"D`³xÊ¥æâMŽ‹¿•$:×hÿxŽÂ&þõMXk9~QKh½a@È¥XÌj"½qA@žs€¿íãÚîA>òz€¯ß¶jg;9‰þ§±`[ãސœUWLXÍĝZL¥ê¯:®)ÁÝIEmlj¿÷fãÿ€ß/fýw[¹s’H*@Šº.t=–ù HƒìH!%Éy'´¤¡ é´Äwm¿3›–ÝÅüƝvÝ- EË9v´Ÿ#8Þgߐ蟭´æ?5ýÄ^|éó?"&¾&ãàln¨d5ÿùþõ÷&ѹï[¨ùÚ¨>vª5#€*U³@…¬!Pî^(½x*óÆ +(‹ lÛÛ7cv¢t%¿4Åshá›ßڒ­”àÞ/ÿÁ½ÿ²öþ –HŠø›$ü—õ&ÖÞo~¯®ýÄÚ[àÇ@ÝÏÀÀâ¯:ýƒª±ÄåàôíwâA§C`0Ð,«ýÿ1²:ö' ! oøX²o“–lØèÇڛ[Ç2:Çòzÿ„8˜Sé·ß™½4„û„ʨw¤’1ú¯¹âe«UëçƒÕêÎît~¼ùéÛáY:ªû¡èՓ´†Ä%û'çvÄî$ê'­õËPÿқø‘ÿdß>3”›`éÇÉ7ïٵݻá5axÙ*Èô|П‹S˜š¯Ž$Úž~ôµŒì?¥ÊyÕüû ÷feHк1øªŽJü2$]s¡ªÅ¹y£™ý|¡ÓIÆS›T×û ÷ï¤ W’4ðϞfÃí; CøâîïSòWª¾¸Ÿj÷}j~ÊÐIΨc'}’öö¶¨lVêYY³ÃH_ž +endstream endobj 30 0 obj <>stream +s¾¹¸-{¡m-on¹ül(œ—‰†V¦HD4'>àzãæÆ£mÞÛAý빜« ´ µ¯=„a™WR`Âw[ìEÙüMø!¼ßžf×Û?$ 5Ik]³}£º¸åOõù3Ø´fŸê¦?³O×Y’ˆ¯f‚÷—‡Ñ6Û» ~í>8—ò¯þ­f¾vÖÓQ¤èXïÓUȞýÖ¹®)rgî9V_Ôýv@®š­ +û‡‡Fö +7Šmž»™öOúÁ×*[úË?ݸ’o`Cb”MښýÄÉ~êðÃȁ¼¹rѳ>"ó2S{ŸÖÃé 5²ÐE†§RŸîëmj9 [jÖ •Ùàoªì×5$_—ëFGÛêÏh­[àñ© ³8Vƒæ¶Xõˆ[™—áF?tWIœìßðØàÐ炠žA‹ÅóèèŸÎÆx¾Å›ëú jÚà\XbIŒl¼šv€D‡°Îpûf(ЗF¼—î í΃ú³ëbõÈh°µ¡]kФªU=´jýXeñMÁ+l¡PÚÖ åREl4‚C«Õ „GX Íõ²ps¡ãàÄ¥:ÛI¾EX…üg#/óÃJYˆecþtlë¹I£¬íN³WEékJoS>µfµO´ïWæy<,¯<*m+Ÿa©Âã³{’7Á¡™ÿš,áV|å—ý.t2TÐSæGYŸô-¤Îå‡~EÌ;DGËMJQ&ç1ñQ:¯=«~a{ÙU«¹ÊRÇÓ­XyÆåRŒï&•‹Ë¥-ú¯|Œùæ $Éýk§“¬†òVðå9Þ :(ʏnΏ5—ÿL ï`j%7)ªXª½œGõÇÞ¼2Zxø±¿Î®‹C–º..{¸í’ÕDØ©g0Ò>Þ³®ž¹Í[¹LÇ5­çƚZQù|·,.äÌÏiÙ1?çõ#–ûDzD$2ª¤ ºƒ§¤ÄxË•BÇÌeó:ø>·æÍ˔œ]Õ¢» ·šËÞW¦sè§n<óŽðÁËöy(4l%-´3·©ÙÏè˜6²žËì܊ŠåeQí£9¬ôn¦Ãm  ÜðdA0[ÛÑ}ýñ½zÆSÈÒT[ ‰§¸i] ²ö4–åñGVãÓ)ÑÍp–ޔׂÖ-èûcCûÛÝ 7Ùs +c+©>šéd»„õœ÷Y+òG‚ùY÷esXZ|?é0ׄÀ7&u´d ´¦Ï[t¨ûªÒÓñ‡7ÖV½úR£>½ºnïjÅ%`å0s8¥žß:òy­5å°´_Êay‰Ê +÷ªÈ +?™Ëau»H$^MÇ?ÕÞ5—Ë-Š—W¼K¦;×wyK02,­Œ¶¦L—È Æ”¾¦ /· ä4Cu_:~[2Úªs•´@kê¶ÿ¶ÔŠeUb|å0QˊˆßèIù¼(tå°ÐK·Íb-u*à"é\£ÆB-YÏ ŸÛ¡' »Í³à˜KSp¬FË"Š¿iýðx„R=Mü"Ö³åÔÕ³ÕÝA3Çì5°Vîë¼×6Ø>Ü¦Uw“ÌGÝyÙ´ÊpH9\!X5„ÏO–•Ã¹)IwÂԤΥlKz«_ê¬$öáGS´æL_êLp֍ÿÇڛn©ª¬ÛÚWp."¨ë¬ëëºÅZõϹú/ˆsæÜk­Ö¾}ÚÞãGi¦Âë+ñÐéqVW±PéqLV¶É}t»RÆ2=…뇾¼w(MÞ> ¹¦9Cyß*ŒÚÃWã^Sg•Ya]Ý72R=“L›%ÓaÁ\ŠKŸm]uÌ|”±ÐìÝwÙÛ?>f¯`Æsíá†Ãzр]ßBQOY¡ªƒeióµ™Ô²Å\^#ÙzE-T;-•±N#¥<ü¬>;ɵYû#ˆ‡(5×µŒxeŸ±½„‡­RJ.µ$ÝmŒ"/L¾H)ŽçR!<™ß—%®—ßwe{¯tÖ=1ԌävÇiù³@¨\uô‘ª§Iîay»çüIìÁž[ÏŸ+7g‰€Ëxܛ#ªή¬2ÇÒòÄl¡É”>ǽ¯‚]í6ul6¦TS Ž”r+adÛºé¤þª—‰û˜nÇ&z)ð%z&!îe›Ôw›v9|.¶9¥zɹÔ/Ùⶑ@È\Ÿ§œº-Q„"®*oéRÁñ^_ބ¡nŸøäó²ç²ÌpÇ®:«Ëàû;Sί¢Kß O?ôþJRt­£ +´d¦4ê´ª¹¼)µ ºd{—™Fes€ß|íCĚ3iñîTw#lrjØGÞ&p'_jáÃe·rd2÷ʪ“XµêÑ¥ï¸Êç¦c•5mÕo±Ê~vÃåf¡ò‘ , „çƽòï½~ⲅãeÌڎáå]{·¯Ô©Ü ¨? )õ°Ã)ÕÇ8²£2Ù±Ë6i¼'9¢Ÿ:FW<ˆ8.ñQ¾´Å>[/À҂ŃEÃKrïÒ3n€Ü—mÃè:X¤l·H/åUúé;N¹ªbFNwŒT3¦jL¼Å)’åãÒå“ûˆ½þ-œdõŠ8´ÄØ5sô™ +ÞÞÓÒ;µ§4#{&;‹Â4sµPí/Ñß,("^ºŠøèx¢o$±iX(axrعù}¨\æ¨<Á@ñӀr:@%šÑg(}ž”‘t¡”ºh¾ÊTªí¸víÈÌW Ø?ȜwÓ¬Ü|ú„dtá¿=ùÔ¾tãÈ}f*æܧe¥K,;²‹.„Mex’SQŒÁ¬Æ¿0ü$°l%h@Ýr" ¾» ”‡ÒsÑ (ã ñ ¨'•…rê´uáòP¼! ¶Þ({ æIr!¹qõŒwJO2+(ÁÐӁèYþ­gÌÝ70@7¸ >,h‹LœÍ̜ÝúÕ²l“7pqo#^.ŸöqN2™!Œڗ[ܗ/–m%tCx^‡VVÒ*·Ï„½Èž°yɸúùº†äŸ€‘œ`b-0Ù˜ºd@©¥ +€iX}(›-`š‰€ƒ0Å]0¥ù0©!3D0…±Ö?P:•‚‰-wM3̍ózî¸wT¡þÑ~y|º¤øôEl)¶|Ӎ®Pú°¦Uˆš>¿° \Ã!À/LxÀãð–|µ”ül™PêCÀßOÀ?R(/ð~>å˜é~‡¿Ç-À—ávÀ§WhN/ÞÜòñv²06ßÓº«¯ôAIi +äèÄv&·&…>Á‘9e–tŽH—Ùó‡ð{#6·‹™"KBt›ù¢I¦€H(k ¼p‘'߉õöى9ÙÁQ:ŸíV¤>ÝNó¹Ä.ŽRN¢ï÷4Ԓ2(WŽÊ،ñoÞãÛq±ðü"Ìúc÷•Ú@ú´Ç@vžk 2' ¯½77¶ä±ŸDžÛvÑršñ€l~ K  ¤òt¥á2°F¬Ÿ\-õõ Õ“olµ&d°^ž9»$ҁµqûO—PMÈ +}¨ÿd_ìxôõüq#æ‹Â&~¾(eYkkMQ7 n»h*Í#W%«@½õ¦nwÁŸLá¼ÐjÁx•]Á¿7¢fúT[ª +–è‹ÉU¾Éîϓ +Õ/2EoLó?µý4á^d€F• "WýuOðÓ¿_ÿ€"Âp+ò÷ÞÖ0’1ã} m{ŒòÍFzLêgA–—@?×h OÆu w¶Ï¤Öҋ*N¸ÝÔíÑx¶‰ybÒþñhÿÍ¡Qƒ +ÿ˜@u æŒâ~ç‘ûG°D”$ü›ä‹X/²öNÝÊWoî-cp¬½°x•RLµ°òÜhÍèÁmŽ’¢AC|Nþ|hÈsŒ"&PM¿1¿ÖÞz]Âûóý—L⋒ÐtmÈՋ{·Ãpý ìÏ^öwPö½²ö"G»Q€v'ï;ѕÿc¾rõþK~ʾí4¡„t#üÙcKã*ŸþIˆ@ê ¯•?.وú!/"¼®:߸c›AŠÙ¶ðsh.sÒ®$õ„2Â%®C×½Z‡¯ù­Š„¬²Ru­¢Y¹ sñJש§ÊÁ´ž+Ò£J)\.Z¥$}gfSÄý½°l<˜u-8ùM73Ηb>ϾB=WMlT”/€’¶A±˜C”6º#ÜA^|ÞÖ½ŠçV]ƒ¨Tº±{­Œž.Êh…ƒqR +çöª4Îæ½âw]:3léVXVóA:fÂüžÊäKj/Jèñ¹ª¹Rÿ$ 8 ƒêT¯et¼1LßV¸Ÿ¶˜– +¼x20ߣTù;i`Qù”ÖЎ±"¼•[ïX*%ñOªˆo;v~S—­œç +‰\U×¢Õä„{¼õ{¹*”Q;+¿FýÌy´žd´ïbžîfë´Eì¼T°ºžR6s½%Cƒû‘ªF$¾ÇŸ˜5GV¿^sβ›í:yë½w¨×„°7ã[ÍÞLÉè2ü_}ü +ÚÑ'zˆ o!ϧc9á6P2ç¡"¤o“ › ++>eS[%nözr\ºÄ’ã2J&y%Ÿ˜Õ•r"#[õ~NºÈ «'{u/íMÏ]Ø¥Øl÷F›S¼šŸqXd¬‘m(1…üf­ó¦Ó³Ü²ê[ºÀ‹–.ºCK—pÏrk ¢úè³®t{ÏJ6Z¹Í*™®šzb[6™Ô,‘çogÙl¿êÚÇíMgDÙ%sÊþ…OOZ¼j¿bqáƒ%bþ”ÏÆœ)Xç¥ZµÜ¼Ó²tºÜ7oÛáÌ´øÕÖ|pEfØFÓÃËJÑÇð³Ó“f0Ò¾ÏÅCû†RÊ{ª'mz†¤s;}]ìÂs’y¦PÌ6“l<嘜œ îm—™á7^ ¤gÌ××X#9º[çy?‚)–›½-ž•›·õ†„ò¦Å’ìqÝÔؘžØ„>niY=©¥ËÚ÷Öji³îz¨ebØZ]Žb5ŸX* b¦²™ßkJ)7X+}–Ž9D\@áX¬£”Š|׃ڶÒkw;ùrû•K÷Ž+‘Ï›/¼È˜š7Þæ¬fLÊ]ŒçH;ƒ~1lóvÕCß¿éãÆí©'•ð£}¯4¡eL‚Öð@Œ®I«Ë®¨y;c©Ô»‘T6“YAá0¿!{Kj Wóōäow©QIp’"%¹†ºtÌÁL“²³’rÔŶîõEýÁF7b +½xå&Xá—៓~‚·²ÅÛOpâÞ-BçÞ£e‰{¯ýJ]JtfE²»­gŒ»™D!ˆC›­ñÕ?§~ -ªìE]痾ÊLJžR†)兾G¸»nž².r­¤ÜdIO¾¤f/ù•ÔX™¯äÛë­*Åg\è퉌«ÙU~ør{¼3º­¸)Üx8,»dØìFsX²tr™5Ö>0…åPa +G;2'1k¢Tªvs’ß5kÕÔë…'V?*1-}¥Ñûè8[|¨ÅÆí¬Tʍƒ\Ïq[é4:®¤;_IÍï~'©ÝýA¼ZǓh ÷WáQ¡ÐgyLˆyFDÕù‘••xçÙ6¹©3Ir©Ï½Ä.2\›%Wù9Sd6gzWÕIº"žmêÐÊ5©ºnøTÝȪԡCä¡Ð…JìŽrõŠZN~Õ³c µ‰l™Ë­Ï¤GDnՍ¨Ý•Êvy’庽—´â}#vfÃ¥hZµ…ðX¥BœÉnù×®°çG•Ú‰O½;7LB.mp{¿X6—Æd–ྵبåVÙ7éJ‡žP‡ rPp¸ŠS²3Ž‘­™\'µÌkGj9^"[ýcÊ%_ú¥-‹ë7Åw¹ÁN’¶á<ќ­Ö€h.ùÐ1f|¢ý‰ÜÜ4À–p”ÎlÙ%ÍØÜV=³TÙy0£ùeØ~‡¤½øN¤+áǤü²‘¡|»Nɇç˜tû@j—# n’A˜AXÁƒæt…­‡n3E˜›U´ aµŸ17‡¢³iTã1ÍJ?ȜúNߊÈàwÉ͕Ž¢ù}î›®ù±“Zp³46åðÅaÌæá¹³q¯†Wöæ¯#]͑7Z¤T8¸<#¯:Õpû<¥è'ƒt{Ÿ$©ç²UâN­„U&¶ø“¼q»Á)Øx;(`@0§pxÝb°dVu°ñ¼/ïJ7ms‹¢ímí˜eeTQŸÒ¤ÊYõPnLÂ;‚÷aæ( fOÛkn65c3¸‰MÇôÔÇ´Xë/©cl½£”Ñtåz!Ýï# ۜ‰‘ú¾È÷ÚH%¬ÓÎƟ.SÄí{ªMb“Æš) &< ™ Âà +ˆé@qr(J&Èb>~䕘9xò¢¶’MR©‹¡ä>¼›h¹ö‘[jmͦ´`éÜcÆpîtBk•h ”W}A¶[ý-q¿µ<¢×퉘µ¾ãÏç)ć#œÀ>¬&`©jÚÀ0qšÙæ£H-;¤NÜ E@òÝ …ʐĂ$YÎâÕ+eϟmt¥0IùØ%,câ`"Bæò±ÿÐrN?òñ¾çæLsÃæiɔ©Çœï ¥J•)Ù^wVDïÛÚâ#1·Ã>ÍôK]'°0ÓwÃûhìI.}+YƒõgM6  ç€ÜØ@ni“sÓݐ=Rr„kÏz¦‡·]g[esÖ}}·ôyû$¨Ü÷KH—Š1j|àÀ7ºÙ«ãž]U +¦l“Kºæ^Ts¿˜“²¿ ú‰ÎOX•–.$<@ñß Líl)sñT†å T (×, ²©”ûP¹îPvREÚÑê€ÒH¸ ½fÁéM(™Nê}qZ("ÜzsS[=ւ"en„d¤åPx†³;?é)'ŽdV{fd·tí¬©÷X‘ìzIôGý%žèV¢¹ð0¼™Øx «Ü¥}@][@}/@}YJN€²¶Í©y(ó ykhìŸÁ÷ðlÁò_µ Î÷$ ¶³>"ÒÉlïÓø+"ܘŠ=SÝÅGBæâÃÔÞÂð¼|p R<³Lg~ ëŠ³£Ze~KšÙӚˆ¯×°‘ßÎ +,‡‰5 ÕôÐNËtswôðúd|¡Ôi(qè³ä@i—}!úPºðEW>ëFÅí½º€ž_n€dà»iÊ3ä‘vv­CùÌõœš5T>‰²z<“b_0?|tl1A_èC0?"çý¥p ͇ºÇÃÓc‡Ín‹-\Pbèc®ð¹ö#~®€ÉÆ^€©•¿€™/HÀ<0Šc@™¤ÐuÀø1`Ž8|ÅqIf]q³)£|f’Ó¹US=x€Éœñ3Q©™ ×NkÅiÊTênG”:Í3%$òò—£²Ý'#Ìà»uóÛTŽOd㈷ÇÖ´ÞÃE½Ž°æ ˜»qýáÐÍ`“;Ø҇ìÄàûîi€£ïà=r!Ó8öK- ô¯€½k ”O°‡û°Ë;|í(^¬[»Á¥´ƒ˜yÕª"§Èv­ÈîTã;F̖©¶ÜrŸ\@<·—žª·o¿eýÑîv¾|`%øC}óNdžˆ€ ÞàEÝ|uƒr«!r[K ¡ìv€Ï9!àãW ðö¤xµ»Ü·_~_×á2D¸ÜAŠ4߂PӗûdNõ¦m[êö: +? 6,³¯ÓÕîº_âU°?8öx†£¦¡²ûáý&xaÅtAàŸà7i!1KaL€ë@Œ_@TԔɈŒ…M¬, ÜJ ì ,Òč‚ çMAË?ùÛù}© _ò)[˜´ê[Þ.ê:"´.4–7³@þÊ‰*ùð<Ç"ùMÁJ4IÝøE¤!Í +E×Æ@VŸ 3 ÃýuK2çç€ô¨€ä; Zø0*(bÂL¥ëmµ6²‹â«œJrÅL%²(ÒÚÁW‰7W’1úzÿ/z´´ÿTô›3Q†‡š?NãÈä‹k” ðà‹&“»w#Ö+<€zÙ  +ꕕºƒÇu&µZÝ{@õ( Rn(—ú(ӓ”1֙‹ Ož2J9JˆÎеå kŒy ¬?­B¬Մ*“ú™r9ŽÿQÇßé›|\µ¿I¾ÈÚå÷:%8ô2Àhƒ&0R0á ô Ё¾:µ^<> N>m  ¹½r^h=a®Z æ +%r4}°Í¤õ—Mq興+1nþk￲^,€/ªä¯Ùã~s|i’~ µ\Á3YkV –dî ¦àØúQ+k`/UHÒÀbã%`Þ'ÉqãcNò]jPÛ»x!Svÿnڏµ +5(êÍOE¨˜ßÔ^ä/þ/b½‘µ7¦.+?©½?®Þ_ÌûnG(à¬pœ9 -“†ÀÞ`0Øù7|¾úýא×7³ù¼¾ð˜ŽAéo—,ʾES²­»ÈÕ %ëýX{‡—pŒoŸ¯=y¿ðò{RõÏöáé}é!ôFú]ì›6›f¯æjW»Äw¯Áé۔vÇ\ÐÇUÜ)lƒV%‡bdü§D­ÿ'šiéùÜýæ  ;øÑ òHàÃx¥á¾-LÌækFnRϜ7+<<µZ¹Ë½~½¥h÷dßÝó˜ÝöOéc{xÌ]˓ƒg3“}<"£ò_¸‡ýv ž®›±úú¬ÓOœ]å>qkÉ.§p”³Û>~ªŒrnQh.„(2ZÑtfܽiÃÃT$—øR[ qY€oüä{GÊůÇܹòÝËÓåg”­ïf,3ø:}{P«ÜóÀ.‹Ÿ…°ðÒSy!,§ú¼AOc3—ï'¦·ú47 Üie¿_»ãDH.Fàœ‡yrA"ÖÉ K}¯>öäE|÷'_1Ô(£A^2€Ì¿y¤.*ߣ5÷3÷äì\Øgfç"W¹¬ÝžM¢7Ûïè =šÅ÷Óá29_ 6ÙöjÀ®Û»~•mz~µyîÉÇö£ëª½hþ°Ù1ƒ«ô×Ôa…Jë»<Ž[ø®4—Õ[U‡¸n9X·ó¥Ð32ˆ¢¢¦•6ãŸHÞ¨@ÄPljÛã‹(e¿JÍ.=yß ºçÚìåNv]™:]PÛëmºá8­ïôžjeðK¶¹Ì_ŠÍ<ý¬66åg³ÁžÑ׳^UÀ¨.\”e­adüê¹ß}Vnã#S±0Û.rçV)Ü1Ÿ¸›QÎO¾Àß ¥5¬¨¾hŽCWÀ~/¨0!—l´¯öëŸÖü&µ€’ðàÃE”)ÛªZÐzWÌw ”©<ñ3)×8WŠßM5²ÊvÍ"¾8…eÍ˨SP˗tyðg>®8æ„pCg©f+«€@¶ØŸ|‹ŸÓ©àУÐÌk¨‡( +Q?” ‹BJáLÍgùC²ˆo¯ù²ü*òV‡bt +”ŸåKJ6r å¼vv•«5/ë÷Ë~¶o^2çqó‘q“Ãwú6ŸâénöÄ¥‚õGK JN*î{µä¸.ΓIyóHÌÚ%%‘1_K”*à,‡Í—“w +O$ÈÈíÎ5n²PÈ#›gOAämÈꔐÒÝ´¨§-\AÉ'¡ ò©`¹¬¤lzVOŽË37ñ=Œ»‰YžYgd–ÀÏÁÚÉëa„†ê!\íM?÷±Ù°ËĽqhÆ«©J).âä$æ/÷A¬Q¤³±F)½)\ÚÿäåýƒOa‰°i•x¶aå¼±Éq‰Ç³ê>‚) ü8ù8yuŠC91u½òu#{ӕL»dvܪÉxÕqrqá“-Åüi­Sðšk—Áåæ÷sKg€gv+ÊÍ´„aGB7ÍqÙ°µt´³ÑÃ{‚ÐÃÇ¥£‡½@bØf~‰6Jôq£Ffå§-¦l*EÀÂz¡]2É{¼__bþ¸uŠ) ~EøÔr³ýÊ@ (K§ðèŠÙ-~%Óâ(Íö‚e à9ºžÌŒ>nåJzRë4µïm7Ðf=r¥á/ç¬.G;\Í'³–JcDCÙ,Î{e³Ê9ÊfmôTšLõÕ|¶<@Ý,¯Uta%·§äXjÈ?ge}pÄw-÷^9›ÝÕwo×ñÆ°…êF}w¯ƒ”åUO*›”à­ÍÚw eŒ7©áÁªË(©yÛÒUꝷ•RªšAä›Udovåj>±”Ez}•ü]š••OJRÄíPRào%E1ËPru©Ñ¨7êÕNØ-fžF>ÓÎxfb>îqèÈlúîa [òIO 3OËÒv4öԈÒ{®.÷—¥šmW*õÚo•ÍhïAy•R\ЁìÍÅ·,’&ùë-5ŠQR؞!ž½cJtk\EÔ¥ROè¶6kÁÒ/>¸‡ +?è£dX~0XíùÁˆ³ ¸y>x Õ¶2ëäËåk™¢8PcbjÃùÃWå¦cæÙW “äV)÷žKyšÌäZ¢9“«ßÚB«Ù¥ä?¥ÔhJ+IQ]„†ÎWÇ݊su¡ðn~ó-tSB°ì—ÈÉäÓr†{ã“7^Ñc0Í8ŠÍd¼›É®Gl&ÏÐ,AÏøÓ>Qö­VNÊõÓÉԒVÚùPˆC멛|Q ow¯ð}b-K­É\R»©‰Ø>2#±½’¦b»©.DýC.„{û³zükÍ?ë?T°#o¿¥÷ž8!7IUp.…8^ÑåU6«ð)–¸ÔjLÁ؏:HémãBÐeÕµiÎÓÚÔ>› +©}Ž×¡8ñRªõnd:@K$Èñ^ŠµÌaŒ²ë§–¾g¥bd<éÔÚ.Åk·<M2:z +±ËiÀ¿Rë!?|LGüð°žòNn:ã>ÔbÉ¥JÓ ‡é‡;¿?.l¶O>Y2nbÌ*,² SiôŽ{¥h¾®V©ƒ<QR›>’'cN’Í i“j#Œ.‘jKzBy(¤êƜ"Y×Ò}1´æ>­N£…ëÓQ'PYzy”ëue'^½ÞBxcSþµ½ùÖïqÓ\½ÏaãxÃÜÜ×éé1›Ý'¦,ÙC³+0…WqË0£Î‘ÞwºÂ¾¾Ô¡FÑT]J«”tš&ɖö¨êÝ×Þ~Otâ ŒŸ&ÞOxßÝñ8ÑñØóËïœT9•P7q[Ê‚Ùߦ£Ä1mqË=”Êd|”Z°ÍLsÁ‡ 3á¾ØbÀ¥ãÅ.›KÊ–¼S¦h†y†}z7üŽèJŸR‡¾¤êU̓R¹P²8 ÉVÓ#H-A‰Äõ›ŽìDg¶(à‰uðx±°ÆBŽxc‰ÚP_Ê®‚é6wé4΂é´eæê&YL¦án?.cLÍùÄ›péþhÀæ\³ƒ®ÜÙÃZa‡® ½6å3›.UßùCJîÜ&d+8ÏÉ֓ڒÚP;7'}'ºÌàAÅcñ¸jØXÕRXâ:j€™EÎAú¹z¼•’î*€·+ˆràS„ҏeµø©È-󲚣û2—Îõ¼/Ý톫±97ã¯cv)w̆“a‰5–x<ïCÉ»e—tÓސ¸-—c¢›ß ±Eû+|Ðö¸mRl<_XÒÎ`6H€àB¥‘™‚Ø?ANt€‡ÕÀß;Xùµ£A¹&PŽŒS|ë¦eáNÇO/â呩O§’¾`‹ó ÷Ý©óPN‹}Ázt•;”ß<Ã*?›év¼>qǽþTÆcìjL° Ö]` ×݀ÌyæÂ=ßÑÖ1(͎MtFu@tc @ôè7 ju¯ ˆù„óˆ"!eRa¯’³E ¦mX ô¿™‹Ý±åóás²A¨œ]öOfãV´wה¿ºµ‡V}XåÎïwx?Ë6IUG`ÏWÚS(5 )ÿHš  T (gL" åÚ$Û\’K~‰‰q@âlÏ +|'¹íˆS³˜Ì$„ ²ÄÉɂE.sébÜîÂSW|>Ùìm¸LE]°ùÜaÂpzeH‹1¡G)Í~Ü¿CÜ;~6Æ}l²Œ×ž8OÙ/‡^Ü<@.… ”beCý…¥á…\K.”㐛 ÈI–ßÉÁU kû2 ³—Z‚®|3Ö½8×ubQgñØúüðr{ÏùˆC†[ŽHK¦´YLh±—RÊIíÞ'z3¬ÒŸu±ÔÖíÚ2°ÊGw(Þ_ÊønU‰¡ÔïPv_@UYJ݀òɪÖD:Que¨ÜTþGÆÎa(žýiÌnÛ5e–21«j •cÅ\ìå6wþ=Üܙìà~•_Ò5}:¥šµú„l¯c¢÷F¸œ£Û0ì=îòÜ ÊXåä «¼š;@3õ# ÕéÐÎãè„F@i‰PàÖG'³%(Ï! S]ø<3ÉZÔò€&Õ5ÆO໹lˆHGWq¯X)i`Ž¡ª|)ÎHW¦òýEæìj7ôèý›\QÍûפþœˆk¹öÙ È]¼\?Ô;œÂr´(b£K\-Ž|Ȓ\ªL¶ŽAY³€É‘”rŽq¬ÆÎLãàWÀ¨0ì´ 0ñýx€>&æpiŵ;+ Ü©š"íe¸Ôiî+ C/à²k℠ðˆC§È ¢åxX­°Œ˜XÀV±‘Ïڄµ­*XVëpø üª°Ê{-,·Ã›ÂÀ¶á¾’mOâ€íÀVJm(á +°ÕþëÌÆáâj°Šrü+ãå¡|fãËqIM>Í5¥²ðin°¬Æ]©³ÒŒŒåYSä¬DxÈ¢­íŸšzØ D)?:{ÿˀ¼ +ÿ¿$¸|™Ü`«îIÇOÀOxuÀ“Úp¯Åpç8Üæenrl®âÝþLÈ'÷ÎÈx¬/-oøޚ'xa”pÈB+"GÌïý ŸÔËÀd®>*ëOM¿úøþÿvúVžÒ_˜ÕEé£B1Ìá\l@Yô°eÖ@˜ÀÓoaªr@¨ìS@ȌG@úoÀ‡Ó4àwÉð7ܹ?ß)UðUS NqE ß6Ù[Ùo<Ý_£¦möï?eEÞ㟠Œó7óëOÎD\Èü3Ý!õ‰Xosà*šG.sÒmKin™@ªýPu©¾ØIéÓ@b&e zß.Žo謕“õ i ÀÓd¦vȳäûSxúZ#þ {ÄÆQM(ˆù×süëïå(êø‡ùþf #æûìe:¨`yj;÷êÖ£Út VE Š±1PŽÏ;PÖw(¥s(&ö…¯m6•ã ä„O‹>¶ÒÔtʄÃ|.éÒ#ÿiÕ߸÷§7QÄďÝE÷þ]Ä?LÆÈßûËzÿ¬ˆÜ"Èú]Àp (Û0Rðpa`Þè~ƒzÁÌ]‹m€Î¥8 -¼±Ô?%nãòiê^IÛDjüý΁>¹@¢ŽaM¿ÖÞÿ„{Qt/‚«ÿbíE1ÈÕ[ïÅþÀU„y  bëÎ ÄZpoÓë°šCÒêß{ÀR¼˜»e˜³ÓT :DQk±"ñ5OP]$r?†qdÏFVè"~‘/?5ý p4{]ñ*þ3Kâ/k/JþÛÕûØûKzï§ñÏll=Ü8 ~g8!SÔcÀтpÀîìÅTv~ØñOõô/ì®æŸ}â Ó$^é5'þ•}‹feë·þrõª+(5ÿõÍ.¯ô¶ðxæÎ+ØÈÎ7`Ýñ¨Ü̽þŠ‹·s"­_o™bâ2`ŠQjï9á·ÜÞ^/üâ[}ïÔ'‹"yQFš… ÁÝßy®~ð)²ÅF·ï£ä‘À‡êéá)ô÷¹džÂ3ç‰F°íhŸö:töÖ +/ÅKí•Ïc¶P;áM¦îëúÞOÞ9›pw·¢ÖÝUy´ÍÅ&q{ët»­¨I,¼ÜLžûe¹0;7œó$è×É~UžQuÿçO¾@ƒ½mÄP‚[>^x|BCEyÇ¥”ìûś8Ú˓I$÷å¾þIwææ~Þ$Níëji9åÆQ_ /Íç~î‹Íå͗‚«™iû;íJ7q´nê$~ cãÄó›ÍZu¸ÌäúƒMaºí{U2ìùÍOª'ßÅj +Eùˆ¡–m6•=©pŠà.2w¢)ÃàjP©Ó.¿`¦æá×u>“¢&¡ÔŠ£oߨ —I²>(×V¿Êì:=¿²ôd=îºÊzÞ¹µ×ëŽùX{%"<ž­ïü‹·2T\FM+MÓMêÀGyÛ#,ÐΠȋøîO¾õˆ[ùRœ2ÉE! s'BhÂ0ÿ²=0{^;¬ÎPî7(}tìTk––¸æ2ÏHMjËhOšu¯NÚuáŒ%k ËVÏ=²TÕ^L½ÒM¨Ýr0KMË6ÑۗƅgXJ²m¥8«‰¥"~®ø]¥Þg(·ÀyØ7ð ãü™Úüc~VŠß¶®Ÿ¶t€w¦ñ¥ˆºÕ ´¶ÔúQL›ì——gѼ]¶|â*Í~i9í~‹œ™KÕ§¥yÆõ©5è*Ñ ßUa _ÆJ+r!ŸT@Ÿc)(û& ·øä)þt'°]ý —pdTVü> éïTŸo?’Rë„d˜ìKp¸ä™íT̒:Î[hyl†±i~ Ëáóð —ƒÿ£å¬)·þW‰©‡8tæuLÏxæÞûVр5T °|-å^,žé&€Ûs„G#f]Ofܜ¦<¡c¥'( +C+dŸ:(²Xþ«_–åÊm¯(à¬f×?Œü` rPè1òÿ'à»ö¶ûqÕ"/Bši² ¤ëdå½Ò,ùRuÏ)–IIú@<@œ|b@̈s¸€™¡øyLmæËq´!âÔ¥[zÃ+ñëqó‡CGÈþ‡C£²PƒPE(ÎqՏþ|ÍT ÝŸ!-¼uâ ¶o(€V5ãPñk (ÃÚ(­Î*ùaî€<8¥¤{òeòYá+Ò§¸Åñ̑›ôWaÿÂz Gå J>1´ø –xÂÃ受ö×ßû‹{Q’Ão`.‚«®jþÉêM¾[ÀÀª+ /Ù7Е ´Ï¢4oþZöá!u:ĘÇÒÈA©$ý™R1 +‰þñCGÚO— G½Aå JPZ¯¿ø_X/"¬¥öþfå"¸͆†rqã±ÝÄNÄJN¿nWXývXtÒæ΀9K78öûIQ=3aã9pû“YbB~9lâÐ÷¢ e„ Qo~{Q’½¿®ÞßÚPxC3¨ÿóNR+àØÛ=pžÊ$ˆ-¬½'EN˯Gfi}HàÀÎ9¿Ëÿ ÿä¸*aÏ]+O´ï½<Û\¶æóìrpÍðÉõ³/<¯øIê–VdAŠ.u«^ÖîèùFzo‚Q·^t/ïhã–#§ۄWÝ~Sùþž|¬‚Zvxþ,ó&˅…³¡¨¥jÆ,Uò‡Â¬žÕ >¢\©iªý|뜜ÛÕÊæÚ¥{~d³îÍýWf{Ý uŸ]“žV§NrNï3Å<(îW ²E¬¥ߺ‰qÓÛ»í~;;~ýìánœ1ªvòüê궔ð.N,õ±õÒågöQ˜½¾D5ú:¾ãcü?Éÿãбþß{÷¿Ý¸™þ‡Þýo7®æ?õîÚ¸ÈòßÜèþ'ƒ«ùïntÿ“ÆÁÕüw7ºÿ÷ÆÁƒªHcöá]öÁ{ÍS…¸êó1%Œò³I™GL>j_O–½øG¡¬žë¢Rï¤RªSZ:õƗFfz½›“ìšùi¤á•ªv«Ÿ8¾ÊŸ’ìíwÁ†õôܙ2Ðêçbˬ—ïõwáÌÓRIðƒt¹ÔÚ¹••1\E}}ԝq’môӲݼ‘X͕7—)lîòÜÙJ]¢G\ŠF?Ս£87>ވZŒµÙá3iä¦òtÏ43Q§Û‹lC[/§¬^÷·1[¶{Pß±ÊlÏ­œË¡P’HwºÇÏñ\:ÇÝÅðÒ5ۇëù•ÿF]Wå › Öä+²N½°í~&ªãgQšßJÿ¼ó»ˆNX¢mòŸÿÿöú?5:raý/÷ú?5:âúÿ˽þO†«ùßîõo£a#9ŒC7 +[ŽjáÖ§•ÁïÇW•hïË]Rßg”ä—<8FîQSÜ´u»@Ÿ[4¹cøWÅÊñÊÆ©´ï|24w® +×ïîÇöpØÌuÕÁ‘%jÇ©Caò°A§–ìn¼ÆôêÌán[!¥úùå&³â֕i݅¦Ò +Ê0¬–À3[h¢ôݨwráªk +1ÐÝ9Ƒ³Ñ¯†Vr©×=rLÔè)ʗêÐTÇÁù!8gùðdh¯©}-¥ëâµiÄ=•#Ù۞ÊÞ¨òêøéâxšoheV¾wS·ðѸZ—ÇÚ=>þ²å¯6d˜™ø†-µ!Ã{•ß°å¯6dx»ú¶üː Ò îl–8ù/ Phú +(Üõôãê$i?†d7—m:8[ûL÷b¸,pôG<íjÑe%Ü6(éêä.ç£^l]ڏñ_-oÎpwò³¨à„Íü4ê8a3?úùQo~÷ߜ°™ßìý7g8~¯÷r|ʤá&é÷zÿG½ù…Þsþä¼ù¨IÃ!ð{½ÿ߇ÀçM +›ùÍÞÿNo~µ÷rÞ|ʤáø½ÞÿO½ù&…ÍüfïÿßÞüïÿ†!ð]Î÷ø­Þÿlo~ƤaMÙïõþ?zóû¼ÿk‡À9a3¿ÙûŸè L3_Qó·àÝD¼TPÌ3 +£=½RÕ.Eþ|>Fí’g±ÔÒ7„CÉ×Ûh3Ü@©É1äü÷WµEÚ[ôXð«åË*D½€ÕD¥SMPX#(ö¹{Ýui/…ô¶—R±ìô ó؝g‡§ pSSeí"cÛáaUo׬+îæ¬Qý·Àf¾uúSòwÎqöðM© +çúö!$ü\ÐîÈà6ô{†#¼Êþ~Øk?Œå yU·«Ú^žØŽ± Y]èé™Ä#Ya=+âç6óã@ŸçÙ¯¨KÜj@Ô{׸‹”ñ{'sä²GÁ>¯”Z`MæÛ«Þ­÷¬ »\këêµ!-{l"|f†·'1næ‚ñd-&¿Zޜ_†«ìÐ~üIv×;e’­d¼Á@]g¢r8&曋YF-5SÝn¤²ðZˆg5†Wžáœ›0šÖý9ŽõÄ·6óÝï> pl–ǐw®Ìë=A¡Àuï~±¢ûjOɸ^¢/ †93{œq­md@©Œ/«æ“›,Òµ<5Ÿ62ýiÐJµÇÊ®ÖdÌõ¦õ6óÝï j QU€ç&/P˜šý@ªÆ4/ÝdR×¢È O¯;ÐMÏB7ꎰk_‚¾'ÈɳÏsg¶Ø›õ‰LáfI/]¢{üË`ý䬭´÷z´>®S‡ð{¤«¸y9¢Ü Ùf~µÝ˜sa3í£Ì*’(}Û¶8~2®L›w±8N[ŒsùÑ´7F¿+°™ÿà»0¶½ß—5€ïn±{½+to£¨°vü¶ù:©Dœ´J&1Õ2ƒ÷_‚—jôª¿LñNcîlyúµ°I¬È!Œ%«:ïäÒC>¾ü) 3çß8 °ÅN¬Å~ Ç(žô» Ñºð|qԕˆoOe¯fD¬!±)^b-Q›jüé2)̦‰NÊ²Ãž¢£[|T”:aE-O‡Ø¯€íç38@ÑÝÝãñð='.s>UNÝÍbf]Æù‹ñÜ#˜ÊªÓòº=„cq™ã–D55j‰q›Å¶êFGº +Kdj½×6ó_ýK‘!ênb{zIçæ3ØxߝÓì hLº‹ëÔ2 öñyuPÓvÓØ>ógè6`°¶|]ÏåÇÐÛ\µÆ©Ç`̀Ÿ–°7ÿ<ðÒ~~_æûRŽmö¤VLi†V1IפÖqµ3”q›{\ɝöÇOwœ=c.ƒ‹wtËÅÝ¡hÈ.% Mw L£·Alw CÜ÷ç/€ËqÁµWìbã!‹Jø×*TŒ#‰µ‚çè%¢ç|åg=q• öp;ìh¾—܍jŦžDÉ¢:Rê0è û¹=­Nd:=:@Âäýú– •ßMÔÀé2qTÔ±”J¯_ã{~1‰)EN*ʵir“'Xl¿|¡È[À /ÒTL“¤ñ˜(¤Yj«d†E5‚>Ç ¡"Ö¯‘ÿ¾ûƒ©± ³qÀ;êxÖP¥ÖaçAʮǵ\<3Éò‹v§zj(5Ȥ+5Isé6s! ä´£úÇéžéO +ûIÏáÕi«¨ó·„LüyðÓòÍqäÓÆ ä‹ `õràôRÅ-çðW¯p¿M³Ìm‹zkÇaÊq=¼níA£­í˜Ys ÿ/±ÝVò¦¡Ý{èN`wT#‡•·I1çˏ6ó_½å»¨à„Íü4ê'zó3¨àü„Ñ~Ƥï!ð[½ÿ‰Þü´IÃdÊïõþ½ùÍÞÿeCàœá½µßëýõæט6ó›½ÿæ|ßêý_1>jÒ0’þ½ÞÿŸ½ù…*¼‘ÿ{½ÿæ|ßêýŸŸ2)læ7{ÿG½ù;j«flÜÉœn° ‰9 ÐâJ÷Ū:¹ jQÙá¤~ØÜ,Ó²RmӜ¼òæVUvÚ£5±ÔÍ$ï­)ý{Ý ¤þs}²ˆó¯‘¯œ…òTÓz'S–ƒÀùÞRbWP˜I•û2>áné~^uJ{Ñ:ÄögÛʁžm̅´­¯¢ØA}ÙäQ!dÕÙ¤Í`=}ҞèÕ_§o læ»ß}W@~Àw¿¢ÎúФ 9-fë.(œµû²§·ômdœ‹w2e¯ßî§Ýx×;n=&wÔäeæ¬Æòº1ŸèSF“VR\êE±Q¥Ó”°šñŸgþŽºív˜#¿rÕ àD{’ìn¶ÑêU”ç|*v7ŏ Ïw¦·6éTn6¥%Š4*Ð¥!·{•)A³k0Ëñ¿ò§W¨œðh^’\ÙWÂÄeµãÙñwÙâ9¢UÓßJ‚šÓ3ãuù“‹Ì%Ûâø£¾r}ò¿ÔN¥©4£c² -ïS£—O+q-9XWŠ)rƒ=Òo 3PüGXüN¹4ÜÀïî"ùËܾ‘Çäq®[óñûM»fóVl)øƪ¯b“UQȱüle¯²“¸6K2{T‰Óx7 +Ü4B5éùâ7Q26¡b•°7?ü¤L v;I²»»(ŦŽ„˜hY%Ò·Ú`v×<…®eõ‘[ D!ÍÕblB Ø›sä=½' Á¨L/ŸT0{ûIªÔðEl{è/8Ý Ôûê)7T¸µÏ§nnîYœAµ¶ýkFT¸ˆx”$ät_æNÅ«`çø€exÑ£¹và*gÖ£LÚ¼–?ˆ•ÇIŒ»€0Läo¦íþyæS°}t¯Jò9x<‹›jî¶/ëõÛGÇëØHfÑ-Iõ@F‘™DÄ&èæiß?ðò¡?®Èç_#~—Êwmö!‡Ïhn¥êT)*‚)û@(Y7HÄÇL’ÊÑîôUJ ©KŴހ4‡(Mfö© Áä#\ÿ8 „þ¤ˆ}ìH=®rQ Ú¿äKJõÿœþ€XÇmó¶í!çÌFˆÉ³uŒËm…¢©ëS½ÁnYÌ^Z£º÷8S1U ﰓà › S'±:…žÃ×ʽ¢_¨u]±Ðì +B§[…^Ǘ˃ŽØ)PŸ—ð‘„oœ¨ü(´‹ Z‹0F™û0ìÕæ—VIw€/ÕÀÇ +£õçô9_œ¶.Z“†dkµéÆÐWe—ݵ—û›Ì!i“™nmE<ëî çjKowüùçûBð“¨à ó?‹úΰ´÷gQ? ÿ·7¿ÚûoÎ0"ø½Þs¾#éßêýÿ4þ£Ia3¿Ùûÿ·7¿ÅûoÎp…þ½Þs¾‡Àoõþg‡ÀϘ6ó›½ÿÞü>ï¿9ÃÅ_é}º¯Uôª³U°ñ¼p¤½~o+æàh¼ˆX™¾%‘äҙnXñÔêÒ¾{IÉÕ*(»9SÍ|4¹5ðµdnK½ö^¦Õ«ÚrúEi×ìïJ˜üáÞòj‘(¿¨ÆÚPS§'2Œ©ýÀ…F;h£©;DŠÒùÊÏåƒÏ97Û%Ôs…^¨‡h+³µ²¬¬™˜¾þgšwR#Ú“³ƒña‹ï?2»º4’úÏÈß9¯g `‰Àõ9¯¦ + +ÅFü]ÚÛR_^ªÂ•Eýäóª±O¸1sÇÖVæÖôN¯¯E[}èYZ_!BruY¾l±–Õõe°—Ô læÇ?€€™ +@7]8PŸž °<€¨•HFþŽ +Ô0ù¸¶LÒßDoâ•å—æ©Aï,Ûx!{sz^ØÛêŽ +Sªšt~]Õ^Uºo(/¸KÇÈôµ¼·Íý¢³nk‹(ÕVFޜï!¢æÓÏ ÀˆìàÝTš/ 1ýà[GÊï"q隷,û6àdgÜâÉ,æOζv*ª*!Þ&K§\ Ïö¯«Êõì-º5Îæ !«ñT5–]¿?ÿ£üͤùbrŽq8ƒh´ ­ÓêÞÌÝ{ÙáæÖïò år¾zÇ£ì¢kŸ!\ÃÕځ¶‘¯îƊ‹g ¬ŽbÐ<„/D©;¼IMŽs„<©PnÊ$ŒÖ¾÷ÝWT‹‚|+ Q—µœKUˆºÆŒÇõlfîuŤ<½ÛV/U¸£nóòŵ¿mP«˜}–Î<U-XˈO[áӀ‡9ʐ§7Új3®³UFàØĪoÎ/{è¼W¨œìV»_1•™ž Úq‰òRH[»pëþíìá7sÔ]M­®Î4‚ìוq°[nwSHÏ3Æ<ßâv³kœ»L«š¬O«Ë•ú–°ÔêσOɨôþº©ìЇ&½’}èxbw¯»BÚï ò–Õa´æT•ôÅfR§Ëö.»'5î%îäXb;»2Ùèó1ëh3¾Gš“»Õ8egeŒeiª}TÂ*Õoœ†¨ôþ•†Þ7ú:\¡¦18í9âÁÏêFЮ“ùdÈë¹A'Y<ŸwŽ7=ê1Œ±ä3¦mW ¿¤,R…ûj>éd”ê¬b÷V“–|‘Yí!oYb¸³ØÄmaüŒÀé^¬~å¼³úûêY–ã 00÷¥‹~ï4Lº‡Êpp©”QíÖˆ½!¾î†‚ ¦Òê>PøEêœs—’CO•5îåšC†zYm81jÍÔTë/ÍüëÌä+ês6‚+éÊøhŸ…•3ð_º¯ÝvV)~-’=òôš©’5cÌ°7z|S\Ivž-æ~0ŸŠ­î´ñJÁ°;š®ÒŒÐ­ _§ªI©MUS†&cîSòN©þã Èê5È»„¨ý ðHޗ´Hxä\Ú\gõ âø GîíÝun´Æ{AÉg‡hVŒä‰AkV»ù•q_ܘ\âžM«Tøœ4µÈ9Ø !qE²­ +M2Ò;?# ßìÖ!솆s)bB¡õùJªÑ¹žÌÆêü`™û‘´ûõݍk±Zfå ¥Úf×_ì*vƒ˜tqÒ5l”±v»ÌèÌ%ÒÃòvœÜ+™ );G„è³RH$¸â¿$Ì@}ãôwäTä§gЪ}÷øRú–­õó=øCŸ_­2ÖŶ}šìÊî.Ù“ÑDø÷„øB‡Ä§2îeXÓ=&éã&•ºÜ F‰ñ{Œ|UèKaɾ¡ú™>ÕwsŸØÌ_ ¿š5àÆ$?øE:ú±á6â,N£ÂޞG'»ZÆ:n‰4—R¦÷&¶êÙUDÀìYz¶–ÐäØ(?c »ÈDFsš~ «×kXîE*¯lxC’ ÅC´?œ/ýlnüSò§°ö|¿šß½Ž´¿â|p9d†ãðe1»ªK±:UI·6ô×™ˆ,òeñÅ5¬<˜ýäƒ9’Ù`äæGÁp¹yT çïƒn®H"ÄÀ5_ýÑiëçƒè·$4Ú÷¾û— =w.§7³·—†qÐvՍŸÓÓ…’ýA°Xé儺8öè·^DNn +Ù|1ÞX¡K€¹ WùàBµ•éu }Ô­èLEÏ>‘y,ƒ>S?ûȍú¯ö&üØ"Ý ÖµýìU‹ý]•G4=­52²˜^ÔE³6î +ÅGqR)ÎO†±¾Ì85C-õזzzƒŠš¥Ý ¡›§aä‘£§NŸÕûá}ÏÞ ”oPjþÏÀ-uŒw¶é]uÔîjVŸÛBÄfD̬^ᚯìƒôToFÑ1“\ViwV$†Ñe¨˜ÆLI³'™}I$˜<*È_}‘Úö1;bö8$°{E=8u]òò}Íüøo9Æò'ß¼YÍ@£ãjO®ïVH¹ÞÍÅ|Ϛ˜ÎáPþébw*¦ž’¤Ií0‚A•þ¤0ª‡FsøA§ÇUFD¯è¨®+²tWh°ãn°³ŽØñPØÅÏH˜ë¬˜CKÈI’²F[¤b)#ÓÉ0ržÒîp”Ò.‰dÆR7ý >ÝõŠÞÈé +õé½ãKãHGlÏí‡J§ ð¹¶ÔçÑv;Á㭗Á—Z +µ Ÿñ€ŸëÚÏ@<2 Mi„pYP]wpóg¥–œ†G¶ïí ¨EA~Þ©‹7µN½R×猳Ôüt¹*‹ãÇׇ+Ëûv±¦ØJ/½µcϲ4à­dîæxø®„ÙÁþà¨à„Íü4ê8C£ý,ê8ÿ§Ñ~IßCà·zÿ_ãý7g˜Oû½Þs¾‡ÀoõþÇæͯ1)læ7{ÿG½ù…Þs†õi¿Åûh”É}å\¾ÆïdŠµa˜ê¥Fl‡›à&ÀƒÈ_؆G)ê—zÓ S)óç[”>)îÁ~+í#TmcÇcgÍ"ñ¹3Ëô~—!ºC•³Îó%ë-a|óçÁG 9ÈA‡¨ÇÌ ¯ät¢öß`pl[PÔÔÃIÉÍlÂ:w MgrÌ-þà±Ú?wqÙîÏj+¥oÔ]¶Sٚh·ŒIF?naÜ}SØj§(‘¾þQy§Tÿqæ+ªg7+N@¾X; +#ó#0¨€#—ìƒkœúÞ«gL¯ti(žçõçê ñºl y³³*‡wšW3ð™ލږª½. JWåÕÎY›äöªË™«¡üGhYøƒ³ÒÁ:x?fY€óæ àB}p'tè)‚Ç_‘¡(ŸÎ}³WQµ¨ûH3󗖺½ÜC_ YK èEÝx  cc}<֕5Nv7 læ_g~,_PѨÓh—€¨³Ñ`ã +ðnuüµª×m`÷Û45ôzû´x™”„0Ñu¼›OÍފŒ¾C3yÝ(v0C÷ ç¨×Ü£¯ÊÏö}³•VÞ'šxk»±ºw֟’°pìσ¿£Ò4Œ©ÅŽÑ9­INA!“¼€B‘)Á32òâ·Âú‚Ííq ò;;M2;sšéØ[A^Ÿµ–­ŸÍʞ7iG÷ÐÒ¡ß÷ÄZDÒà̬#þGhGB¿ròchÒ³ìÀpz‘'S6Ã黪÷1w‡… )ƒÑÍÈçÂ9æA™çl‹†³Þ˜+½&'3–B6«–L;¬µ>O{ÅÓÆyљU¡¯”$!Ñ+-ÿ%°™oþ–|E͹uÃC“Þ·Փ¡I¯Âì]Õû(Û¿¡#ô-}¨Î|—<ìõ›.6;lÔ³ôuêl¨q×6dFÛêk®ŸØŠ"B˖\Ü ·ªÍ­I°žÓ8X~^”jøù'*œSÖzÃéðÜøSâÞU½÷%CüX0.Òï¨çÚÞ´ììš7 !¶ZÔ«›\³ºYÏK5I¯ËÍB‘^Š@~)ðŸÓ§”ÎaY„²_þGèHÏáú€&½ja]çéðò¥ +;|S"(&–~ð¨‹áæŠy帙õŒÝI©kúã%+ +%eÖÒ,¬Ä{ü..T[ñ»š$Í›ÔfÎl§B]Ml¾ü–„)Õï}÷—@Tù‚šO j\>EP¸ü£BÑ^Ð +Èâm8¬ãZWioø7Å,O²ÖÛÖÂé)™£¸Zš‹Å2ºY +¼9 +ÜÉm,góA\žÖˆ9¥æj ²Å”÷Õó/ÔÂU€+T܅s)[…uL¸×í–ë÷í‚Ëâö,ú›•ÈÓÕv]EeÔñë[šá—/µ32d‹ãÎÇM½U„Ÿ4«å¸ó8…C€í÷kÛϗ—ÿQ:7á(íÆÚpя.áò„BÎkµüà[1!h£Åp±ñRV¿¸€=ªóîbWÂr‚¦9U^>×5^G|¶HQééÏÅÆS_hOǯўc sºd¨ýJ§éVA¦­Vyý] ³?üÁWT: Q×yNû† +é^ù^ïڜ§_œ“;ŽU N½¦Žö¹µ33¶5SìE„[/ÕÖd™@¸³™Ÿ|‹™†MÕBœfvÉ)K£5x%Áa3CÇe·C‡inþ£T>¾—N”G:p1­‰p:1þÚ¯ê+87q÷Képq8vŠ1ùþî =ѳ2÷\1K½+’ó³õlO›†Xc·;¹J³ÅkexPUªªgšƒ†œ$H0š…™ÛA°êÿQºs1¸’»pڏV—Íû½k”n¦×`.|i¸;·ó‹0(´ª±}-÷„2ž ÔJ–£=-Çk³úŽ.Œ“q¡ÇÉ|fXžéÁJs3d§-"Dü>,ô-±E$°.ýcy§T¿ó@/®P-ˆºØÊ z=üØ0À.ûDžºÖN³O¹ÎÓ ³¨eûå†T7Úõ…Õ¢ÊÜÍØcÅ£³Œ½ê¥ÂºÎð=¯X+NhÜ#Ù7Øc®g͎ŝqkÿQ +^8ÈÖÄûꙋ«÷šw \”š¦OÝn¹eOÞÚlV—ž>_RòíÈcb*µBøâ4™nzjŠÝ9tŒž6¥èp‘ — "¤b=#Inbýa™Jö¬žë¹÷ŸÉ{~^àʄA>¸S¿0ºGÜzÎé9W{ҟ5 y…-4º~¨ucülr ûka鏦xí¦SݓžÈ}@ÂÞ|ã4ÈO[%€íGLp£²sÓkk{‚žo†üK¾¤Tÿ~æÇ¢¿š¨¸9§â›•^pQˆÈ´f/¾ÜdT¦9ª{¥ö ¹õ ]tØj<Û©¿èp;ؖz3¹¥ h½ÕKóv+f-OM^_›$²¾A1îÍäÑ sbGCü˜€â§?%°™¿’¿DAÎIa 7,u"aÈÂ$\N_áúUjÂÀ:»²ªQ€&´ràânÛ»›%ê-Œ˜ë¶~˜\†‹:ç0‡?+¢xÆH&Œ=O³yC?smûȽëaYª>,Õ{>/ßå|'!õœ°™ŸFý'læ§Q? ôæ÷yÿ́ßëý7ç{üVïbü´Ia3¿Ùûôæ+êÅAŽ«BT½Q…Üí+j»QK2DÝâ­ªr;ޚÇ®úì³×AҘ^²5„s«)œ1Yf»’|*vªÆ‘£aqÒÁ3Qwß vž• ûÏ @jAș…&u†=€Æ(¯¸Mä¥\ä÷ÒåòDê1͟ë¾|âÖÝGØ+…ä¦Î~ߚŸñÈŸJÒêà«{ùP7ú~íŽ,ûïœìÍjú0G·Œ½=Oã[f¿÷Ý[BDbIâ8¢v—´&€ü£Y¶‡5Ž: é Â8Ýõ€ü¹$á.HýGÿ@E2•*ëpŒ¢ÐçñÀŸ¶ò(w_Oÿ™[”nƒEttÁM[8¼¤ûÂÊ] £Œ<­=³%¹ ÂU@Fڅåz60Ö«²O+bíBí„~/µä·'tÎV îóò•s<,´‚}©ëœ5·pŒ6!*÷@¡àk÷eìñô;Þ¢äÒqot¾ínŸJÐ3s¶¸Íô¦ÌϔA¼7•Ñ:;[OÖ\¬‹¿xeÝÕ"–p´ùè¢ +óœ|áæ9+íýù)ù•„&íúÎ>äÔú1€o½°ªW îº<‚˜–®ãé!ìÍ©9K­}¦8ÙúÔb¬jÆÊûk„Y—ö v ÇýxÑ˚SÞlõø¹]m¬ggo.ÌfK™ƒrš}@‚ËžÓ¨çҒVå»#8íY`Þ4ðëx—Ê­Éãy3ë«Ê¥ÈÏÈSéî»´ÞF #%St†ë+± Äfs9XÄ%'ŒoøáyÈrGLgœ|[N+Ñb"–úÜÄ.¦Ÿ—¿sn(Îù•ù%™²J|)A-¿bš¯4^O×vå³/Öû¶µk’ÆBžª®¤Œ&äªÞ_éó¹>Gr §‹Î‚™¬ês~ܾ VãH>ύÛýþô-a1쟀x$\ ®¤<°¼ºxg—…¦BÞëôKóôËëyfÙÒ©=u,l ŸÈןãRo³_κë* ¯ÁÝàÙáiéÑኙjoZ»ÈÄx“lÙþ¾0e x•aR¯èœdòӏ +l毈ZM|Aͧ7,À؋p¤eK"}—¤Û(ç>.evP<¤ ®n +”ÖҒ™KKº–ŠM±ƒ]šB–Þ49Ž5›“‡´Æ1¢¾Š¡ÔĀ¦Äx4¶ â(ï?…DgŸ€FÛФr6c8—"6\™Ð°®3¸ûLÏKå˜ÕuúЃs«˜Çì9Âu)’tíû©êÔã·éÁ$G¶ÅQfdãjÙ͌“ò«Î. ,)â³U<Ÿ']=3rêó$µÜZ òy¬§mCÞ壉#Þ³¨G½g Ç£¾¡ËÊ砝INûXPv +©ãÙ#nÂËYœa®ó@9Ï¡Uši[£½{xÊñʾÖ…§víŽpށÉNÔk:Å°è1:*‰ñØ$jQ²‡hQ"¹£=»žIwíd¾‹-°jS7ƒI˜úÆé @çbä ÝÀ#;!¸/'a êÍ9ufwË´[u÷Ú¨,±¥Õðê.w¤ýäK‚Ÿ*íj˜¶c-? 轆5}òþñ$ã/æI¤‚Z¬·yñ2ËÐÂ;óˆWÿ¼¼oEìÌ,ȼÆ_JâmW¥câ~VwîÓMmûs“P΋¬ 5AT¯ºÅ_ ò:ëеÛx”(zô%Õ¸ ýóêFµ‚„7ˆ6a&»¾7]½ÃénÕ{XzŸìc*Òá2þy(prۗ‰ •ØÍN›l‹Ø¹WLÝ&Êí”2Û£áb³VRijIÛȄç½Éj¦ÄoÆØÚEm¦`#ö¨6‡sF6ã§A¿*;ä Ý¿£XÞë3ÏïJÐÃY=Ò-QB²#(“ì·6óÝïÞg| KPGY«”võíMP•"³K¬cœ†,&1½8¯Ÿ/õ©ÞìcļNhw6^¥ÆK¢bc.,K$Û ÌÔR&¤÷VÜU½³¸pz³†ìu¯óù½[>°¯Î2IÄ>/³Ïaù1–Øy»y“}èåÔÛñ”¾ÒK5GpÈâmöÐûØ&º†CÝô¨î EJ鐭AÒÌdfÈé6éO +7¾çð'±Wô÷r×/z·öfǗ/aÀÞiD/—öC üÏËñ™èL!Y45#_9Éb*Ý[®!ESZͺþBbÔ&4Úȟ¿ ªîÉau![.ÒÇ®ét«¤ó+Q‚XÑZGl?[)ڃ-¤m‰ÈÑív²0m½Ìæ¢ÕËÖVߕ0¥ú½ïÌ+%®µT%µ–üùp/R¾]áÝ!ڛêõgqèG(ÕñÁ ¹]1ýã$?í +5Cèˆ-Ci?”³ÕnÇÏçÖkëÝޙÛÁóÑêe¢¯VÌNƛ:“I7IÉ5“' k˜Óz¹1,´êŸ-YïO¤Åôî–t›óy!³ÈN“‘aŠÇvšRZ£,a,´W¼ñNýéV[/Ýl·b;…l&"Ýbⴑq¡nsºXgJ¦\Gn¶Z;.ŽFmR;î <Ž5ì ßmWu¤¤÷y¹VÃÙ›Yf^9i2Ȥ»h<úhuـÿºÎb¤÷ï °˜{‚œRÄùÆ£̱^ß”`è‰Í9{“bå™ûJ>y·[:ˆnTµ6×þy³½&(ãpIWùË9dÜ}°ºYߕ°Úî§?…úΰ>ígQ?ÀígQ?Àù£} +õœïÞüVïgüjï¿9Ã!ð½¯ÈÓßo»Ft¢V±(@­ Ð~ndå@f­ȹõâ}z9¶ý›Y"<1PG7‰ïL\ófn¬¤-®D^] ªµ¹ ^ÄαªÄÙÉ Z·ÃíÖpl™Ÿ‡üäýùQ9ª €Ì< yOe€`6 ÐØÚ¨BÄúzvº«UÓ „åSc‘~—öò¥ç­ìuk?û¬Çγ‹É¶æ— [:¢KçqCÔÏù‹~8Íræí°¸¡7«?‰îL+²Q? a¢ëϐ›‘>ÈI(AFþ1Œü¤ä ?,ô@¾=•@>¢º÷€Ü›júKO$o›Þ‰¹nµûä2Üwçò´ßéõ©8ÂÃfŽü2k–¸ì×ÕS°Û>–¶ÁÞm[¸¾6Ÿ[3r +ä¸lz=9ÖŒ¾—Î|˂;W³O@Ù)úæƒ|.]¸s/¾ëIcnèÓÕä22׳óiê §Ù3Ò§ÍþÑb·ûV¯s°7ÓÎm—÷ÛóÀÜê•·Qï ·z l毃ËßQÍR :¾ÎÔÍ@~vM [ –¼© É>…Å Õó"õÉûVõd9'ƒ]¹2YV‘SXÎÝÔìi1ڜvéuÕ¯4¾ÕêxDQ6ûýj£'v‹ +læý rÆ¢R*D}´ë­ÈgjGwY€wa¡4º}œAéx†ùÍm½ë×%îÂÐáä&0ñ°Ùµ­¶Ê‹œú.ã;qºá“^ÛYà8j«4R6Ú½¹–)·°4?ÿ”üÁ†“žñÐëý4d!÷ÎCkˆê÷Ì»;BŸþ£¥nšüê]G{t·¬wþ !Œ`'Öe~—ÃgKcšpWú e6šÿ ³ú~ã(›…0Ӗk<µ™¯¸¹6ûK’‘žù–€ÜY¸ÃYµK¤Î@TžŸCÇOÏ#ú(Àc©°Pš³‚ š}zŠÀã.å9}gVXйé„CÀ2 Æ‹ëɶlèmµJÍԈ& ›m©¿–wùþ6LF¯V¥2&ˆÕqq¶\%ë“OÉûzóêX€«¼¥ o¬€-YˆZÁ™Ç<&ØA〾nÛ8_ŽÒ°}ZŽŸ¤=˜4Èð–8¹­bTøކ‘’X²Œ<îc)ŸÖøu!¶‘ÞćØj(‰[´_öd±ýñ§äîÒΪäÔô@ŸÈyß]vX½«ÃÞÜo:gùzü鎚-ÜáT´yˆõ[­{Ûµ·‹ßQ_/¦»1sóžt°=r]°ˆ¡¸x¼ØåêöàJùí +òƒ)9æÓ†þ—„ÙÁoœþK ªMºÞÁz0› Ÿ¾.–¿\Ýá·&“àŽw^ßÏ+kUðS0Ý×ìaúQ7®Æ¨®ÉpÞ¿IM# éhÚ+þÙm/I·¿è懁ȐžB™%wÈíÆÜ¡›e¹q §?%oÎ÷0.i€FÝ6œNQŽÑˆVË⠐ÖgA0»0D—’DÑØ ´;úRy[r513+r>º¨¬nU£¶”–º ÷ÉŸ¡AoŽÍat$Ü L¯æˆ^- å6ú”$¡<¾ræ8—rs‰Þ ãS¥G¹;ûy¦T]»9•º‹ì»f–ä*®) ßÐ=_ϝZa ®Ý¢°-‰•¹ýŠ×9—ÛSW‘ߜNƶÀBѓú~;ú–Àf¾ûÝWÔs—Ð$D5jk8F«t<^º/c“±§çH7à Äé1T2ցÝä¶+6@ÔTy–—fÏ8"®™k˜Z$Æ/l¾?—ðٜ”+“`\¨ål¢ÇªùÍè×+Ãö¨2ÍöZêS¼ àŠÉ~©ë,Âkü½¿xrÒd9¸¹ñÍ\¶·.¸ÜúïŠ-"­G[rfƒš™ÌJ\ªé…^Xgy¤¤çf|å„LÖ¹NU_× +3Xi-zw= Fûã!¬R¥GÕ4Cïzå᧠5$ÏÂå©Õƒs îEð‘<Ê|»äwåêÐeœ’ +]» oHÚ{Ä|õ SÓA3.•™cr©¶GI~£Ò3× Ó“Önšf‰õ¡­Óº0Óãúp6á ê +îÜ°p¹³Ãs!=ú®Àf¾uú+jÍÁi?#ƪ2ÀwÇ{°&ãØmHÄÉË|Ÿ•OQ}àî.»a ÷æ›çÛ$"«V‹ +V¾åæódt"WSákAYò0JÑhïr<§ª ¢:htÆ}D¯ÓAÝ{NK?Ê|JÒw ç²9Úà}õ¼Êc.ûwOÏîs—‹°j[ƒÓjô­ƒ±®g]5ûhùëÛ>æ{̋ôå1yÞO–J=^tž«Å†åé9=Xy”쌨2¡zZŸHԟS¢ß¨… PSùé§ ¬ àòÄ¡ º¡ã«Z°&$÷z|5ã§çµYÝ#û·«±­fl˜³‘ùêã"öÙ¾Ëãû£ Nj챦­4}Ê_ô£ƒ–›Hzãœï›ås­gׯ½"çÆ=ú²•zÖ|¾ø±„ÙÁž—¦Œ–æG`ý2 +)A¿™µìáÜÜ©·=¢ŽKfPEX]à덣]·+¥Âí…c¦épõ:v›$®xÀŒ³£çÐCø×@^ßïØö +‘~vnÅ»'ŒÏtñáïp{«Ñ) tçRÉʟ€xhP¤ðȜ šwnn›˜÷ˆpuÌUÌ)èédƒÚ\6åéº}GÄžŒjóêª`Oã¥ú™exɹ‹­G=zé`ËÑw‚j½@?wR#½¼5Ov b?יƒQ±í•­vmy +çÍûó£×ûj:~V¸&.΃=­dXˆØ:ëéqߔ¯ýÖJËWˆÅ²ó…+¿¾èkžÂ­=×Íãp5F*"¬.$iå]"[?ø}´´=ðz…QçÑ-¹gg!eí{CÚÍRø”€üÉzª˜ÌÛ Ú¿™õæ=©—p…–Åtü$šµ´Ï»£˜)ÕB|lã,Ãå3¥QÝ×۔Òᆃ¤Y“™=.È9µîcW ö¸ +0»®ÝÊåvéø£›×©kÐ^?αvKºgÞíσ‹×+ež6Üâ˜[E,=PYIÊåX‘ +Ö2_Ù3ÊToÌ·ì$cX#ŸÇJiëþ i,·%63E÷µ{ß©C¶Z·[µAǗ;L§íÌÚm°hKÄTn½Ì©ÞR†2Œ³»ËGåKJuw±wrFÞ¶٥’©ÍZI ؒÇî\Doƒ‰Ù>SLñø ‡­Gc:Hn÷Bÿ8é¬zE/¯w+ü±#¶Ë·öC-ƒv;Q‰µ^F+ÝR(*ߊÙD˜èjê ]k’è¬ÕLžÖDÜZLcX¸Î>%ې'›£š¯6ô_L"·Ä¼~à“ŒZ Ÿñ +—Ržê¾æEÂ=«=®4kvÄÒm·ã±a«—zM›dÎå›ÉcLj ±—ÚÈ\’fݞ#‡:S.:uÄ«{µã²u¯Mêd¤†=&ɪ#‰È_ò%¥ú÷3ßAgÄJ&RÀ—3k]æޘ‰/½‘Xnƒ¤.ßúØùtüÕìÙzéx¬Ifo©Æ0AëLqސ¬…]­†»VÕYí{Õâs7¨¸›ý¨"tOãJ5v™•}ýƗE¬ÊtJR5?%áÕ3ÛU ãx)v Š0j½÷Á0º~"mÛ<ÈUf;=j W´lʯ‚ÌîÕ c…º9† ΋ê4˜%J‚má’_fRá[­nÁe¥¹@ëo¯½[ÂrvéÍáŒ6bÆGåœïˆà'Q?À ›ùiÔpÂf~õœ¡Ñ~¯÷ߜa|ós¨òdc'ȹ¦AÖ Z ')sˆH2yÀèºYï|³Èñ›=È!‡'Èê d¯æñ”þ“zT0Sñ±ÝÎ/_OKÏëž6^m²3Üg´o^Uê¹»¤V›Ãiâ8ÖA¸7ÔIxëû§ß²ôöø5ϧA®”mÃÀ‡{,qí$À²9ñ@¦Ö + iï rJb£™ÒÝ9ÀyôHß]DÂdŠç7Õ©Wï²ümMÖD÷9/¨nGËÛ×þì~rv«ñùx +{ð[ÕRIVþ¨€,¿?ÁkÓåýG¸³½NökU/™YÄ·€ö( Uk¡ï@fé+@2•ÌãPÅj÷BNêû‹H|è5 +SæÖ:æ¦n—;/®Úb½¾&Öcí2°Çg´ê^S¸¼óÐôÔØ ÚOÉÌå ñ£²›D­w8@G¹/U½ˆ^_´r¿Ô^cUžpËÕÏ+ï¬ú½æA^ +y`q¤é{u’ðšñíè©&W}¸™_ÌD}éX›‡ì䎮qfïœ +cónw*…Ý.]2#O+ýZÍðߒ°j觿¢ö"pŽ¸  ˜Øhl,}-”ÎpÏ€ÞF[€²óÇÝQ\À_̆w7«aM7Ë^IG›^2÷w3çcEZÎ—¶r¼j%ûXvÚ¾¥¼½9R»úöÜÊȚ71êº3á>* kÝΠˤ`$Q‘·Ñ“„]Êu;>ÈSÏ"Èsƒ1È·åÝýbôAUtrž4î5n±ênpø‰‰³_Ôçg¼+ŠG!{[ï×JacoVù¥ñ…‹q¨Å G&²zß5ÂÍ­Ò%R܆ n“ +D½@“2ñȵö(Œýœð¸Öä‹Ó;țù2À’êì1+m­`ñ*?Ây#ÏŜ»Í€úÅîÂ=謣«¡JÙÊõ:´’—.»Ë,‘¹q̸¢õc†æª²YÈË 1›Ïå 3šHt0b¿+aiï?πì5€V²Ðªk‡Ó(FôúÔ@~¦¾ ¥«ó{…]ìüV5q¿%–döK'WMÖ÷iÛ´£e²åXw{É Ã'½tašjb'˜ªR=•î~»€Q^B¶ÑÙʑ=fUÊy£ +Ⱦ"ÎWÎðÉùZיIka2€”‹Úƒ«ó ~gM/6ñîWzOŸçš…íÅ­Ì,Z4Î2RѽL»¦‚ÚTÔd­»!QJNŸÉvËҊët§¢°$Æ˛…kÚ²ÁQÔGå+ª‚?¿”É£Ýúä[ Z3õ®>nÜoI0÷Û³‘éš—óÝqªj2\¡Ÿ $kí†jÎpŽ3T_ž9Lí¦¶…Í`ý,Iûí¬¶ž"ÅöjžÂ(ñÖiÁËFQgmÛ¡‘El(¨}„ú±Àfþ:€3)uY»ô|×JÃ1JÑ ¿aUﻹÃÓÌëgF敍®ýs5ݏíO)nžîµÿOÚyv«Šëú·˜Èæ ˆˆŠ(A0€s@A˜úÿÏÄîÛ=ºGï}Ö¸çËCÃX»çk1SE8¯‚­ÛÙ4±Ä9ÊʽF¹ù؏â=ô¬ÎZõ en’xh}Ó-ô.-‰:†YÝñÎs…ŸêLßþÔùÍ>Þ«¼ëÊöG|2º'ý¢‰£ú쮺î]錞gvúûÁ™MlüÁ5i'®VzÙ_LÒVþ±ÇæÕA +Ÿ2e)kØLº¨o©g}¼/&:Úðtµáík¹YM€âÍ÷ø²D@“>šŸ?SPßq²dfáÆ©²©¨l:hM6òcPã··ŠÖðŽÝÄ0poÖ'ž¦©€UwÕx[J>û™×ºLròqŒÑ¹Äx,²ÚH+ª:RZŠ®Áå©J,ºŠÞE þˆöøø§Ô ­zš•A®¸|=®×YY§ÃIçÕðùp>òFÚ¹„küv 3Eo[ãgϵCƒÅ¨p æ>þŒ¦­¤ ”/$ÆYjžQµJ1ö=•ê-S”ÇLsdÕ»âˆÙ¶„‘•YðÇöO'тÅö? ›t* ×õãïÅ¿ö 0~Æãæ5¿ÝëÏíu3ºkź}²=ã°S<ÿê,Jì}…‡žg>ÈÙsúÞ(¾Ñµô`œÃ@-ß[I¹iî3£Dͤ†é¢Y‘ÝïH‚D +’³âùaê1澈£ƒüPjöÈÞ8²•[ Ž¥¤G<ºîc –ì±úðùàVã2‹#>+o·¾3=ڙtâ¼(ê÷;…‘[»N®xøÆC­œ`ô®?£!/é©ÁnYÅÄ£ÃŪ·Ä,ðñØÍñbÞjÿß]g¯|äv“Y1‚Râ +o<{ ýä3åÛÏcٓkñ²hœæ{¹ÿ\9ŸJi»"w›ƒY§§iZ'=›_Õª]GŸV͓¶‡‰? ߕw_mDéo2lùo˜ÍнjÒë÷¼j²Ó/ŠíŸjîâ2w¨sOÕaå5PXhÇYïÇÁǞômr™ 'ŒgÆî$3±läz[-JîvÆ%?®~|¯wêsmîeö|>In”¸ˆç‹òè=œL؝±AJ°øÕù¸ÕFçsó%ÁŒBAˆÐdûoÄÉ°ÿ¼ò/À%”õâ¤Òp,uh_OÆÑxl}dÈú÷JºŽm'ÃîÕÁm´iIEcyiÖnwõ_ˆãiÿqù @åf>È¡ + š–=^¼ÒÃA•ùٖÕp}4ÆÙEíÖ«ÌӁ1äm·§‚dg$£iːòÑqÞ¶­Ø÷ì~/Éé•?ô;A[ÎÕœú!ЖþJçØ©—¨2QµÆ3fp›2 êš? &çÈ]˜8:º[þœN*ÐÇÚô6áÎfëáC¬°¡§fÝ¥FE~RÔhÁ£eŒ@:\u†âÎV½…¹³º™´âtv{þÄåŠ×VD2âƝTª5)‘¸WÅÓm^>5fQbz {0õŸdÇÜ1=®åS§$z»{±îoøҎ^]—`n™öâ6ËöK××»8Zå„kf´¿1y©DŸýÚ=nTÛÇSí æ»?ZnÖíu?qtw窭ͫÕhÌ?¬©Mæý´sÌr6˜ä-Ãÿâ ä\9'ʜž¿s¾qø:uZ>REÆ\å1c:xœñ,'¸JLNC÷<1Й°÷Y¤‘.²Ýå:iQãÏʤվéÊ7‰ü1‡\(qeÖɂìŖµ:Ç3óq/¦M<“:å0Úµ +?Å¥YÔ®W’f¶3HÄ þ oL8s§DU'çÖc EÊE’û _‘JJï3QÖE6`ա΋]û6žÜ¹ÇtqÕÈL·f¬I°ÑzY`ٌ—Vݶ˜6î÷iG +eZÈa\+qÝÁf¿Ôr›øC<ÿ;G»Ó G‹ò&”gÂá¸3´ÌR?:YQ[¼$c¶ÖK­tç0Èŋt[+ÛÝ֌á$Öjs:³ê2“Ús-PœG·¦+Oƒ&~Ÿ¾‡±‹4¤ÊjPþ§T—›©F=ªÚmÁô‰oHõWl^Ýv¬‡žoO·åOW¯î_•ó‡`(cƒ¨M´Hp…Ý›ÏßJ)®úºa,›’³´#–‹MwT¨7Ê4¨'Ú©Ëu´_χ…8É¢¦1Ùq­ô©ÍªU{U5ڒ[­¥S%ج¼Ê¬{+Mì™ø)%òМnêmz\£-¥nãEI#MoE¯íŽDx6÷0ØÓZ·íôåKã ÷úÙH5­yÕÇ⚬֒'¤2ëì‰J¹æÊV_,³ÄµZú}º´¾¹R;ŸJ©9(:Z=ž:‹B¹eüo&€ÝÉ ÀÆõàJ& ˆÚ‘ÄZ˜2AàÄb€˜®Z€hDc€ƒÒ7@Œ/:O€·´4ÀI'°“[ØôÖ˜œê¬™W +p=<ã%„iPž×–~mX?,wn{ízݹ;&iÿ°™¿Oþ?¥þ@gükþ¯R óOû?JýÎígR±3Àv-(õRÉBºC“>å9 [ôH™„b]£ˆBcðûè›gƒgPOëPxòFC½A`³Ô`BވÈr0{]LiÜ¥šåׯõä玷:қ›»?97‚2W¿G¼ëŒ2P*\Qœ¯ ²<”ú$º€d ;î ȅ›ƒ¢?@ù) f½ šæ÷œƒbÏ5€Wího?é:Jx*;“0Ç[ñÔŒ%bá×ÀqýX䕝—æ±ý¨¶ç;-OÏÜÊü.“(±r…ŠohM¥%¶û€t£åw;ˆŽ|ˆ^Þç¡|Ž3¡ÞÑêuÓPo­yZÑÀ?tÑÖ¼®kV{·…Y0~d×~½¹Û<úö¾©ùÇ«ääw°éþò°È&f‡„|‰ä¿Àg9(µP‡RËzþë8QZªP²%oC@)TPŎŪK(véA±g$:6ñ×|¢lÅm‡ù[_|•†è(¨cZ]˜ÏP˜C•'zï¥Þé:LåÏÇ“°‰ÙÜÜ¡§âØݍrÚðíiNe {këðàù$~R#GŠsº@!Ùt¯ +¨9½w ÞÓ3¼¢òºÛlùUÖP6¨e}¿±ÊOF õÇRL.<;wÝzƋŸI_Ëªwlzëí>½ËY®X?Å)›b­7úþŸNú +G<–¤†BMH†§[m?ßä$ɬƒlÍW£³âoCÕQŸ?M§ýßž š¦íζíužœxï©)å6 œÉux×V—b§<ΕÍq×eO«íPíLñ%¥®Ã–+­ÍäJü"Níýëä¿ðsJø8àW‰KÔâdJYîºÙú‚¿ ²ÇÜ8,ëö&˜‰yïù)ÍSþR÷VŠ#P·,­5.roà~Ž;¼»{HŽ§£=ïŸæ»îÍw7Ê>˜ÛSt¦¯ÞÓæpi÷‰þ2óLwxÃ[¬7²¥>ºi@!í8™Qã\éȕlè_iE6ôrØ8xUÇO #Ïs»‰÷ídáÈ¥RÄq‘~S‡TÐ)ìÜrTq¦EoG’ÌoÔ®ˆ +0˽òD*Uûž›§Kíá=Ž&ù;ªÚ ·Åµwh§^}&×쩘^¥KW|áÎ՜uÐG5ó,ëüü6^g{ڟ7]˜€„ÊM¬õˆýA‰Pgð-§ =ÿ(?®ëíõ8«÷ò:ö +&9ÚoW·²'e‚åUwû#? Ž;ió¼nýÓÝ6—e“åp±;Œ5Ĩ¤Y˜>ðٓX姯ŒÓ˜ÎnÕ8=aO×XgRm#ÝCX}ƒ§èੵ{òúŒó:?-+†Èg.·èÖàñ +“':[ƙ)÷BÉ1ÏfÄoöûÆy·sÊÁ™Áyå´ÛbÐۍ–ôM·ßÑѽďwºÅ‰À¢!Ü6ó_—QUö€àîO8–P*‡C©=l +òõ×-|¸4$ºaýA¢Séúlk³#ô4–»÷ØÛOVåêYß¾W÷1…–}õ:M|OKâ²?©Te½‰Ç <¾XÙ· ´P(Õ¨8¯“‡7~<îɾ´x2õ ƒSñäÂsǒ[ASšÝ–cI­ª³¹K˜ÓÖ>¹ÐwGj¥]ôoÁse’xîá8¼ Û4ù„*ù¸³^vÐW2- MóŒ„\†u Ù «?¼ñó=œI p»äËÙ8¯Sø>Š˜lÌðÙi^}þšþxù™W¸0Ÿ µMêý ½^V;±®Yåf`̘ÇejôFۙvUn–2KÆh±l¤Íœ< DÒ¿‹Y÷õÁûI÷/ƒLÖÇry4Qʍ–Ç—%õjõ•x}·_´ôS×çõ [ߞ!Ô:µ®/$Ù^¥™©÷*…Lõ—ˆÄb¹9üñêIv|+ÀÉ) ¥ŠY+àèÁ“¹ËóJ÷Ø!{FK2[«Cèšþa)Ny·=ÔsTEVkג:ZÝÙ±Ôï­§¢\$ã·"zFÞ¶…ˆï:ŸÞèÙIIVŠwê¥rgE„\ç“C&@ìw@åœdßHÞuº>Oé8¯óÙ»ììëë.NxO¸~yµ7­|m¡-6­ÙŠæ:UO÷Tß}ää ’$qš•ÅbV÷ê©äLX°Ûu'mÂ= +j¨^[LßRܱW-µE$Ói»ÛÍðÈ5lü€ð.G@­?oS¸2(”'b°d&ê½l¿ÕŽÛöîQíD®×ÂWÃ0(™t¾Û˜ô<ÎLÑï;/¯†×®th>D±¤e‡ÝSTŠS~»×ísÚsùôéÑR{HªU*™å–ª ­+Qç[—g®õ{Àf¾G@b¯ì£ÍÈgÍj4f½–­Ž1ÀW›vN~®Î¢š²sšöx¬4öú†Ò’×̐ÄmN·¢nLÊ¢Ö +ß¿+SÄþMë^¦ì³Þõٚi#Ì«_¯3/1«1Áz×g«ëu÷€´vYà ÿk¦RG­§wµJ;ö¤M®`®äûüj5m4uoó”^¦¦¤òÙ:åᡵ«Jk’ëEœÞœdjØÁgÜmd‹+ „m«*÷¯lc¬ÆJÞIú#”›ôªˆOé%i©ôâ$Ç¡¡ïñ÷ÔdåA¿”Â/ó¡r=PÂûêNt:t°ôš_Þ?5«í~J"ÎuüÜ}e=ô?Ããœ%ãÆ%ÞC÷é ßìò©°Ýى¶ÈóºÚ.<s®œV×/ì\²Cf¡œ¦ÅT+ôúp’h>“™Óéîiú|WÏEõu­¥={"©õ¶ñ 6v/ÃݾåµÌäaªOFÃrÜÀ^[%㓧a>ÝóDߎ޽åpŒv3V¾3èæêüh@¶Û¥ü»ÏUˡښN3&!•x!`>DýÊp“aĤê'œîXdFú@oº$:ÿî'3´ý§3ݘ͗¾&:÷¹õ¢ñ×Ì­á¬që8ñJc¼£&ãë÷tðPòVŸ‰fNWÈԎƒ„>y¹ðN´KþåªÑ>ך±×­ýóÙz=¦¿&u,Îi!Gohä:¾4û¥MØğõ\ã0™4¿€Íü}ò_8 +eIÙÌ¢´üùz‡Útà‚¤þè½Ê*`õṗoŠÁXæz©ÕEè­Aû¦½®ÆgºX6½=0«îþΤö§í ¢$\Rx³_ċMÜk4RµÃ7 '9¬Ÿg§I=ÿN:•Ã°­-È8ed5HwÚf³µ'>Ç3êõR:—n)շꋴà +oŒ—ój +DŠ¬ÅjLµXZ gB³Ÿ×¤ÆA3´õ4¦õóÄYÕó¡ëÖnæãR+}"6S}¬©OÕàY¬lûùʬg5 ì°ÚmRM³áÊ ãø@›*¸ÙeìÓÀÈ»÷>î;Iž¾Á{C¿BˆÇ¤Üó«ÙÏiï†Tfêr­KÔ4šÎUËz©ZKÕk•™Pg*M”ï”-‘ï—YRQJ«ÑdRjç7ËRêöt‹B%q…È>þÆ7¤ú+Üö eãHMJ*Ó©TF”ãNÅYé9é"¶¯¶o*®´@Cu褉_Öóº\Wµ¨8•ÀNBGtëË,îÅ{èÒJºz¥Ôå…â>*"Þ-YèWϙdþ0OòMUsç%EçdŽé@ôz?Àʝ9@×ûë\ÛW€; €£ï"À» +ô²Í´!{g.À‰2 °£$lrX¬“º¬Ñˆ†ôáÿ šeêjµ ýˆh”äŒð`~âÔK®9Ó@+Ês¿zÎÎQÿòü-õ:¿qÿ£Ô茳T-õ8púÜC©»Qà4Vø|Þø•€RÃÕàV‚8Ûl<¡)PìÍØ¿lÄA—®!cP¬õ­¢ˆF·&Ôµª}zmᣈhà“0‹ßfÁmc˜¾ÁÕ¬g#zYÞg½þ Æö Î§ºñ tAƒš)€oè + Òõö +ü-’¥îöÛï;:4n°˜ŸÌRP¯FA Ckbù€(HõºÃå¨ÿüèa¶w6m.X~­JÄ{‡Õ_,½v®»¼#ŸÊâXdB©#`bòpᔆE¸m¢C@¬ '$Ĩ]€bµoÜ=L ÞÏà•jõ +¨×(@½Nꍺ+PJ´§ ÊílÜký8nž^?XVY{©°âÜÜCru9ƒéü¿›ù×€iª °„­º+Âþè„q±‰5tŸ¬Hâ°d¥ +ák%¨×é"Ì~ϟ.ŠWdŠ5ÊP¬ÓŠÄÛ*~葬«†Ã¡3îFÙôk‹'T©‰›»sÅÜ«$÷–gmý™›+müü©“˜ÆaéÖÙÜ7%žx¼h@²š +Híãr§%)ª€L°GÌð +Õkt«ŸðœOãa¾ô*¾®Æ“~ç;>ï7RP©^&~ÝA‰7~wG»×ÃE¶¢õñUjϾqh%¡ïºÉµü̚ÂÞZ^ƁÉáZ“F¡Ä H÷  +e GÐ<¤ùNÕ©çGÑPÆãg¡’8Ÿ_š9‹#K#þt÷Î>ÃÓµú¤o6ûX<§=omöd/}™wt³¿œž¹¦}`Ï»ùnÓu—¸a£"]Å_6ó÷ À\3X6”êÌ¡ÔLJ* +DâœîéPԜc¢|5/¿¼þaԙæñ ägðøø£¤çà쾝Ïò71(T®Cíûž…ßuÏc梞êÔÞ·AÅr‰p?†MFN…®Šëù)à€Ýl8ª,zü©c\cC +1¾ÉI”ÃÌ@6u‚;í6‡Eò|À¾ŒF0ô£\ßz&g»×mdn·Ã‹{]nãsò_^êhr*7إ잷©ÊnU¹VÉÛ\‰™Ø>z}#Ì«ÖMŠöefÝlý‹¶Pê-„R¹”ª>)@Î¥Ôyœ(}pÉ%_Ïe•öëHÇHÌïp/?ôº*êpš—ÑËaµ¤ï{ÄÚûî>ä¢íéPHoÔ& OO—m_Îrëp,k«¤•[éÒ±Ý gŽàvÜé ú—€Í|HÅÑLòA_q¶lP§Ï7ÙÙOË ½ôÌT¾ùäyY¼QE¿–V=ëøv «ýÆkmÝ#«¶&uqŒ¦ìÙ ;ûZ3Z2ù͇–ÞIJÓËTۃص¨b½kæ¹b{^’1zV]dê?À‘ÓŽ¥ÊvÐB—iþfõÆ5…ÃÅ7µ·7y¾üyõ9©{{¦Ö»ÞmR=±âÁØ÷6“™›»ÙËM…l» šîjîŽK¡Ý½-ð}Æ·('•0ó „˜kÉ^sfä—ütVÖÙI´ž6'lά~Cªðø{<…RgôöÑv–-‚ì€ëÅY½«H-́¹¯fžˆTïùZ¢s™ýð€Z5ٕ¹â7ó>ȕ¦ëe“5—›ëd¹ ^äƼTìý\s·Y­^ +¦ÍR-5± £8I¤?¬ÑVqZwHM ª¤£5äÁw½É_áÝ?w€ìI ®×ù͖㲫P_=Uͧ¼ÃÑ-]Â¥}´•jw7”^ÒƸmGëÏÒՖÛçkb¤â|î‘úbV/ãÎÌݽ±¦´x‘Ö7¨ê¨x'Æ;Î`ƄcÔµ£°ªjCÔ-þoøФMjoMºÃìȅãõk–î^ã`Šs¦÷K}U¸4+ +sÀ[¿¿•®½v+´ÀŽ¬so¨Îõ­OC7?›´6ÖBß5g,ŠéøR駪ô+iUYMµX)Ԕ»_+)ãi;ÿEüëä¿ð‡T‚C“^Oœ×§ zÈ××ëÀRèóc×̼o㞜=µ]¬¶“ƒÙ4(š_g¤»’éx†ž?Ә4¦e’jtOe§Ú¨|\ªÅíx«TV“»\ßì>£PåKrýz¯ŽÂÞ³4 +ûh>Fî÷x'ü>Åý¾xDe.‰8¯³ +róp•¶ó•¿zWŽÞñž ¯u£‰vÒ¶´}<› {½Ùå€:ðæ=ܳæ}ߟ¤KIÇß}UË»wN¢)7ÚE{ø~c§o2lªþ’lçD SY±<äÚëҐ«]ò1r¿ÇW* ôÍéjòÙ=矒RXÃEó¹Ñ‹»»Jø±·v^ + ³ÏѽÜfžA«käh7­+ØYhð܄õ::q±zZa––”?TF–AN‡©Ýi9p;ön€[ÞC”È6À½JeÐ{ó…Ao/R6ó¯+àrî?½ç9®Ó‚}´Qy¾5|5Öô!ž3έ:ñîÇ­·*z +Á„w,-¥í fVýrsÊ)9VßkÕxYӊz»£ÔÙ]Ô‹CI[M<æ;³þ…è8½{N¿õÊV*Ý/8Xµ_2…¾,W²?œž2+8=¥¿Þ¤ü&œ?»ƒÈÇ£ qÉé^>ï/.–©öç>lÂ茬1YÌZã6Uš±æ«jô+^C»ñ)ViYn”¼Š sBQžFrÏ#ª“îdK­„ù‰ßÂhiÿBÖ¯uëe¿ÐT’ÙîJȸVáWkE@îb6Âg¦%>» ”o†¶Ÿœ„WÊޕk—øٚ“šÈ‰ežÄ°¹‰Þr“n{Q+ȲªÌ<§>j·Œ„hNÌ/öB¯ª1’`^‘qgyÀ—¼}©y¤hÞÉ\ëØ÷Ke.Ìý °™ÿº g¨Š ÈP¸ìÎÁ@¾}m¾h<#x#Ô¹,úð«æ,Åóš`J‘U…«ëÔö-BϽŬZ_÷ +#^–Ê™¹ÄÇúw…¤»¯ŽÙØ5'òÎWÛýÙÇäïƁË숓×z›Àßµvïá~8æ» †ÎäšÑ÷iTÈÑ~ÆÕ/‰K¿xÉ3Ám¨ao änqwΏyB#[n¦Õ`VÄäT¯JITK(ô½Ç¦Ü5dCHº'Žï†ƒwj7”Ö•fÌVq9=°z6¿®ÀêõdõrÅfKɑ•åßïÍdIäòi†ºS8ºø<Ø_dõŽœíR-m©nu{þö帧MÄw+Ð&óy❒†i +ë?m²k]v…Žs¦«}Îtz6x77]*N»n +ïý°‰êèË[vâ"gìŽ9 Úöi¢-/ÚÑ2ߊƒÎ°q»jWOA]’ÒhÏ0ã'Îfß8ô3½îòÞúØÙ7‡>gW@»xc°–?Éç[õ°ZgéOµÍpYnHÛÊhJg¼¥Óìqï{O÷ҍýµÂ6½ +±Óþ qHõ¯“KÝ·F»·ؼyí.ns{0_Rž>9¯Œ^5vUÅɇÍáè“çÄYÅè÷RëÄHÀ÷sÏßi‹{L‹n+°Š76Zç^Ìg‹'˜6ž‡'íH"\:t³_T»ƒ¾TR5´êçyn_—éÉ«žÿt«bí÷ØKغg¯{jk¡Ž?ìl]vÛF>ªÆ¿F‹ä×GvY&#i”†õ™pG +n·Xàåü¶ÊuŽf£Î3Ÿ 2`Rû”F#§Ï¼Ù/ vã0Æ ©Òðêç)ýQZ@c­|­œ¸5ªïTN'® [­!žó8¬Ê5Š¯UgíZÕÕÔ«©r“íf$¥{§Aõ¶ºôRËç­#‘­g»ôðÂVã­A£¡ÙLl4äˆ&~}ÔãR‰+ Ð5Þµã"ýªÁ¥lÒÓJ#VåhÏÊ,%=JŸóê]ZÉO¬Ô.Jåò/Ç:ããâ2-fÜ|SÐ  U”Ü/ eÔµú‘qœ +®œ¶o*7k͚ÓFúë¦;Ìn”w?Ôn³õµúXL•À¾*Mdø)[ýAªô9 ˆÜ GnuT*"½Yè×Ìv]¥¼DûZžúVî¼êî~€Ù{3ÉêÖ'eÛгÏ,²½éw¨#G ¸jÀr̊ߵ›ýl½S?ëI±VŠ¶Ãʌ(e«Çé¥vŸ…B4/¸ãhYÀý‡—·mîl¹Bâ|ÉjüÙ˖3QDýD’ª‚œ k²™“âúißãïЬ«d~˜d‹l:\Þê—Ò#—€U±À(ÅX:átC#U5€ö=€–jߏ £¸¼ÈÇ9äx9æß õ­ +)ÒȨÔH‡¤1P#¼\Ò^§W Wo¥¥ªö¿àÛÌRÝ@Âü ë½U2€µöU€ Š}ˆÅ`5âÐWƒz7u€ª±Ôk”™9P¬{‚b£'@µ$@žŞk±ñoÎ-2m  ÞŽõ܆RíH{åig”8M÷«BSý=Z;@›ó ¹ê` ÿ0q€l÷®Ìû~l ï+€­šÀÚÚ÷Òè•tۇÿRµà/ìÝ®e‘ e¸wD #Eßh€øù>ÔË(Q/*CÊôàVœ¾´'Ï)(LQ+1þÆ¡áñ—hû¦äò0áï@©•ä`÷% +ðb±1¼G8Ç¥`‡]`à °\y°Œ¶€ŠÝÃ÷ޘØ=4üÐ> Ï%(úÖh²4ŠÜ)c„M‚[טúU§0}6v‰™÷™'ÎÇ¿ÇWç÷Þ\nq]ßlQñ^8aWxà›» +ð+»¸j€—^€= <À&‚°ºm»]~^u³i€Zí,«Á¾Ìžã C¥^?÷Œãæs¿d͇Uޘ^;3žß…’8»õÛEý÷¨ô€&}q ÕÞ ðÀçéE 9TD]Þ}ÂÌíp7[8Ë +q°ßØځ÷?ß ÞÏ;ÚYi4 4y´J×B;Ìöd5¸½$뉥÷9*«»c¶–7"›4/òžœË†òEì­ýuò/Ԉ i눰þõpa"ÛÊÂxµ±n€8àünҀh´«¿É}€÷­YDeú›p„·o¯k¶×~xé\*sI<(Ÿ±’?AIƯiñÙM,oµn9·þà´¾ZÙñUrµÃ"-öë"+ý]} ÎIÉúŽ7Üü¼‹‹8Œs€$ÊBœÓ=¤ˆ_ْ@øV3Êöñu3ÓFð¨mß¿OÏpTñž´†G«vK{kÚ!½ôÀ©Ü…Ù¡}ëë©ñ5[øˆ¡@azH(èx×MîF.qSÄm.Ñêþ°o"° <¹ì›9h¹Z"®Œp/R“z€¼},@‚Î â€ãБPž—W×oÎxõñ9†Ö#ÅLÝûV¡Î7Ѷ¼ë°ß/J.—:—IâTÛdÊÇæ¾Î‚¢ïP»®n‡lr¸)fO}ûùÖùu˜âØ¿g©þóÊP%»[y´„î4 ¥®ê‰8¹ (Ä%4–€šmŸ¡–4Ð`zÌ֞ËꐤŸ§Ñ¨¥Œ«œl[gÝXÛÇpYßX9,ÿ¼_?·Ýf;în5C\âu(n³Ÿ†èŒçUi’‘°z7ní¥MÌèefb4~¨×aաγøý€ ‰ãó±U(05T ¯£BÁ~¯¼y®º›¢×ÓBö–3R½ósšÙnQÝ;åt‡óù…KaÁfs•½ãµú7Ûo¡]×ÆÈzî'꫖[û3]h[{Ðé=k戻W~8Õç¡IÝí +Ôä ÈÞ"þ2—ñ-<ÙÁÕ~=Eýæ·àHõv”ºnrNmœ¶uà7õÎNÌ«ƒí%(›rJÐíYâ>[›×õjŵEwÙ)¶®‹í`Y{yKZä›o™ùj—ž—š•êLßÕËÓ R)þ °™]“S Z5:A©ƒ7ÛKœÕë@©ƒÑ(R¸Ðæ§Ñå™"Ÿ{͑—šAUNiSßQÉ=»ñ²Þ~9…Þš]/†«Ô§ÏЋ>ºŸXß\š#wäÎÕµz›=2·ä¬ªM›ÓÆqY›X¹ii„ۂ±bÌìïñ‡N<ﯱÝâüÓïÓ¨lòÑYo«„y»ô[Qãè ºçðª'|ô¸åìNRê¥Í£\ªÙæ@`VvbÝ^¢¬kI`:˜ßJ™Ò٘κîrbU½ñ™}£Yy#õùºQºÐÆ :š­æÇî¥Jýp,5 €wÞPê'}ôìã¨ÐÍ-zÊ«Ló‰”)÷ž_:þÙ4õÔ~}³T·÷V˜wšÙ¨¼²£Wm±W+´y-è­y%Ÿ¦óš!NØ=«é&:ÕÑ +jû£æU;D—Œv,̊št_å´ìØ%ÕKå@ü`3ŸŒe Ô¶d){ë`âñ'ãéèÊ$•€Õé?â›ëã,ߏN»Üa—ÙÔó& ­(ç–øq^2oÔµ6óO%zJ,ÎX{…xÜèh´hÇÉd¬^zŠ¥Ü¥õAçÊoeÜ!òͬRAÚ„Œÿê<m@ªìP¾D€ì»gۅÞò:ô9`xYY_f y9à÷}°õ^“”½L0èr'«Ð«çfÁ¢Wœ|zGÝ&=ä7œ–›ð]ÅÃs²<Ùd¦£ù¾¸¾©y0šŽ9!Gó'Šè þp†êLà°o9p,õŸ KjÈÑ*û +¨íà‰æêí>¬ÓzxßïξúØ4öµ÷:sùÄEN9¸yOª!9e§ùœ!ÔäÒXJ>kꍥÊ`‘)ï¥!—Ô5ÉîœÖRfWñ¤Íg%[™“G\²»䗀Í|ÓzP*'n•™ +:Èm¶Ð-nŽºÞ‘MI×Éû09b¥¡ã–ÝÒÕþh¸ì S¯/ÒÓwÁFPcÉ#²ªfKrpÍ5†Ÿ™ùýt˜Cvº¸}VÄÁš3ûçÜé,J©\VuB<¤ºè¯Ž3¿œIÕ) –“- øà dw7 +äÓWÖo‹¥8íú®¬nÝó;è+ûá‹\l^pý\ îîiÝfƒp•„ϤSQ3ãSÍÂÔñôBÈs¾ž®«Û²„¶˜¦(Yß/dR¯\JM»†ÑÙõÊý-ÞÓ¢wÛãɦŸ­ÿG–³?¢hÔ:ŠàˆOeÃm6Ÿè)Eߪ5§ut‰{ßõv§™“ìζË!ß½šµE߶ke›ATM¨Þ»–ÍþÚ¥$9Ø£jAÌ5òõÞX:³Ý:抝:Œ; ¥êvf)%̇>)¼¦¬[³ÉÌïñ}Õ9ÁÍýÜÁ> +µÜ¼” ¢€*z9S+œ?ïBi6E~uãuk¯-)žf-þs7úšvL9:gC‡fƒóíߒ\×eÁT¾ït8jÕã3;Kmoõü¦ÝãÂ7ß)])ÞƯX'Yò‘ßà¶?ƒc){Œ_8G× “õ†Ågêœj$À‘Ðøxêt lÚÎê3\æ]0Ÿ›gϝôJç˸8Ýx +ÝÝûÍEéSþôµ»éÎÜ.$ÒA‘ª³zF‡“*µuvJvK–È˦½w¨…d¯…qÖÐ÷øK¢Z´UïŸA®°J^‚¿=n‚Óaîb÷]…Þ¦6Éd¯¼­®ùªÏÇS¡¥.õüEÛ)Qyx!Ô4.l6ÕÏ~咍ºôÉNvìƒñ“ÊsÇàQo)ã3ώ§‘ÂøhgÍLöXÈVzÅ2{W‹ùVAÍQ¿ <å[Ø,›8ßojÛ^7h~¹»òŸõv¦•öŽ=μ×ä'Ê[¾\cg¼Qê·:UçÕÚz$lëîà Ôs¿V:Ü»l‘}uäønxáò&Ç>ºù q”ƒŽäJ[ß¡¸(Ò³©Ó¾®2 |Qú=9¿Û> †ëçZãRj¦ ´íå­Í„Vã\ˆgèYçºaŒ¼xí©Qú£¶ t>¸u»_?©p÷Þ.Œ“žíá" Z÷ÐË°“Õ)ÇÌ7׽ؿ{t2[ћü|í63½I¦É[íFsm͸æš`›_Ä!Õ¿Nþ@Mj›Kýd ÷Yì9tÞÉú`kueQɉs3Ñ°^Ó¾)’º¶ók*;ĹQ(÷šºP{ћ4»©Èv:D†‹¿ãÑ>¯¨WFœŽÝ.yúó¼7éTøê6…~Mo¸GcÓèO«Q£?£j¾ w}t$ü7] xw—1Ø4׿ڷՎU«rý¦ãIŽAÃñdç‘ +?¡ŠÃ\³Y'ÛM«—,æºÖ¸*üpmÎÚŞê´ülçĆEîÁ¼«Ü‡I +}œÎˆR©Ù=Y­Æ¾ąÍä"?¯ŸÄí¥>¢Fx=w~7ë¹y‘ÿ=ŽükÎo‚ã’Y‰BÐ0ƒ¼EO»9­­—o˅ƈ ãµ(-•6žúŒ¹Éw‘n½ÊŸó'†{Ô{|«±* XæÒ0Ϋ.h§Ê횮й5ñÝ lHä,S?OoÅz>úÐq½±VNê“êÃI°OUn±ð7âê?¯|ᖬ³Ú¬²é[åòÄݯKãÊ}ÑP:á~?êlj=ÀÂ`Òº°ì½ÐkÚÚ¬™Ñon¢¾ÁžÃÅ}†Ý~‡”§`ߔxjQ +nÝD×7¨„òœ!`ê}&›éÝé Ç7רŒ®’àõ®Yt/ü™ ¼ñN˜ì,¶Kž.l>ßԋ_à²~MO ¤3À{ëÀ>÷r4Hßùp¸œ_g„`B¸×è°½gÂüfXxÁi•õ}͋›y†Ðy€Ggþ`_UÛ[½ñÃÝ9·;=Â[Ÿx!×èV¹ämáô¸ÎFÇÙÃQ ¥/í6ÕïŠÈ‚v wÜø%þx!K•"`–½¸£Üâä8QúY$Ѳ|XEÃIpkäÿ¢’¹'óìÕ)<Åß·Mcp§Yí:,]f—ÂîJŸUz{|Á_}d%Nµ:°#Ù·û~c'Øõ®»ëLÛì³.8÷MÈÚOÏ®Ù}Zþ%þÔyÄ è£úvü¹g£€ì€t¿ïFE'í³zéŒqöée"zð‡ÞûºU¸ž[éæÙ{ðÜ1ﻇE4î×ÇÆx·1ñ¹»DëíQÛìyn””A:ㇶŸïQg=?7ØÕPÍ¥¸Å™K~í~ €¼4 `DöC! ¥‰' {‘Dªñ‘ÃÒä¼ð­tóðètÖÁT©Ë˜$t3…CÊîÄ飻ÞêF»ä[â7W¹ :^ù%Û~î2Y¿>›åš®Ý«…YŽ–ëÕ6}ì3‹nÈÖ¬^.›'£P0G54÷K4=~§ÎotÊÉA©¬È[šÔÈe"¹‰‚™9›=ÓŬ{—Þ»è3[‡JzžÌͶ­ÜF㈲ôµy¥¹ÕÒÈt—ô4\l+{ÝÚç÷qî EŽ±‹™›š¨™OkóRaXšé 17 ’< Ñý5àX²†°ƒ&€Hµ6€d„²Fʏذ¬E’Ÿ0ÚñS\O¬¼ì«vÍ\Ž+Þyîqt¶×Ò#íL(¶ì0»jÓaq‰8Óºu¨0¬92£Î\5‚áLW‚ÉÔ?P›i#» §É¾8±2§Ü„Ùz”±*y8„oÕ¿Çÿ@Ûî`7} +NqijPêT @–Ë·‚×ÚíÁýPM½]ó›Å™¦¦û½ûh^Ýü´î;S¥ó^·,%¹ÜÌßñÔ¹ fʔ×Qa^ÆgÕi0o³“hP©VÓÔ;§óUw$<« 5†Ò‘‡ût#ÁüpÌFp,™ß7$‰åzÈÐРF6R¨<ë/Bƒ÷EbxÕû“ù‘_ä]ÖÇM­äß׫dà/{uÄ>NÎïϙÕ>9]¢h¬Nǚ.ôçܸ_WúšÄ¬ã©ç5ºÓ²-Õ²âW/ä Uå\‘åSú%ººþˆ÷Þq¨Ü!ي“ + ñìàmöž_½³’ñÃbè¯Ü–Ûñxáڋôô¼Bn³»uƎÁÜۑ`öä䤥$}3“c‘ KZÖÌ4Ԃ‘”²‚ɲá ×òS½¤”r$`òӒˆY +Âú°™¿Oþ€¯ ð©7$ö<j½Avä_uË©r½ô„Eu¸Ägä­W›fguR@ØˏÏ?9Ï«‹P@N+X@ ++Ð÷ð› úIõT”’bèÿYßøúJi•‚[õ\ñ¬i¶q¼6QÆéÖ2éü…R÷õ¶¶Þ^^jæüñ–ÇR=˜_žÚC +­Ì[ìÜ×Ù©™ëä´•ùB!h±žãRl¥PœOüðíqE†„¹bwœáxQù$Ðþ?H‚ùŸo@~^“bß܀"Â$R¹á÷Ýô6ù­Ý¿Ý îñ.—Mä0ØYYkjµåj½<Ï·ª!®%/ïNóë-ò¤Ç¦›±“¶žSJ|øÃ9NÄ|7ø$ÐÅú8\*ƒ1EéËÃ8|"ð¤‘-g&s¼ ôÿFR= “(5Æ(ÒJJ7%]|­]èvÎ?Þ®·}ŸÊv½àè!Ûµr=Ù܊½¹ûÌz….ÆÖb¦È{™È^γÏ»NBºó—±×õ!3i\Ù<óâ»Õ`¨Þ(Ã)†íÁÑþäòˆÆÞíƙ†1=ã´þºAi³¦Â +¶Z–:øZVÆ=KìÚaŠ’3_¬Ò>[Güp¬¶f1CžZð(ËTËÔ¯v¨ülÎ OÕ¢Aí)#KÓsæK[&ÿƒ$˜o’b¿_\ºÙïù^¸^U¾ ž™y¼9MwuG¼ge˜¼·*nˆÚžÔ²Ö…]z¹³,?\Oº™æ¦ÔŽ»BNÒNÙáÉÇ¡?0ü£$•hõàߎ®x¶3ìüxíuÓz¯–ªm:Ûb53Ü6eTûÚ£¦âÖEj¾Ü-xѐÖò4¿¹¬8¿^ÝLž¹íŽù µãˆnyW긔ŸÃi•É ªO +ï7–è­î¤×ÎΌÞj¨§å¦ßÛXîÖÐ~ðmÿ €Úê3Þ|Vއ-q§âý:u^Çét7%S®›m³ürõ­ä|V\æ[Z4ôjWÊ`ÍÔjÊe Vî|¢•ªcâŽ1Bû¤CñúÇÐ)ì/·Æ·§ª6N®7A«ûÍÖÙ®á=Í®qy}É¥—È5eÉ·°ÅCj N¯IÂKªßØU·_0û—gvHÝÝàׯÓGÑvú`¿â™v´Xöì¼4x>êSnÜ Œ˜ Y7†®54W9ëÃ딳‹úÀí·®åÔWKüKf4ïR@îtœÁïŒ‹ºÝËlÇ¡±R¦[Õ.Ü®–ÿÄ}iã3­ûõú;X©“[÷õÍ&Híj^-ŠË`ãçÚÄx‰6ŸÉ +—éçˆË¾1þÎ:U"–..Ei(ƒ–: v˜Õ‹{¯ù¥@HB“l¦‹*µRgòâºm—< m¡ ìÚB†É¶ùÇ%u‰oóÚüÿÇåÕ³ÇJÅ'w[I¥zϪ¶V˜‹õ-‹ÐäA÷f\3 +ùÛª³$ä!Œ3ëé³¥—Tõc÷[cû:'H½íLÐIkÎîºÎJ¸tóˆùîà…#ҞN3õÖõMÑ-i)­{ +[µA!nž\%n;¹ö'Ò.çùÝwy©o¯£\Yû\·eEÐèªüžµ[â^)ZÓJÖ=qê´ëO²Ññ1âGM@ÉJŒ TCÃ{ßUëAx¿K¢†éúÔ´Ã[¬Ò¾ ŠÕ®ÈnÚH·êJa»„Ä^¨7£I@7;¡Òì<Ë~#ž­¡{ôOØq-ª¥ö×>cSŠÁ“ÉžŒMÝ×»Ã+•nºÜ䫟 †Í‘]ñïî Ò'×~ª–¼¾9m~ëßI¯JU¶5jV\}9¬?§iùbæµ²HÑûrÖýR°G2 šèŸÐ_Òτ¤Â÷g´¹ì¿Â¬Be&}¿ŠŒ„Â…†Ën»ßÏl ukíŽPMióŽJ­Ìd܈÷u.)ùЬf‹¡T=,ÜeµðtõJ16·e±oÚ¥À²OÅpoú?–ÛÂåk€±Ø¯V°,t±~Ýf +ßð+¾tñ'”SƒüJñe „ò$~Í!ó¢üÅ4ۏ7å,Éä ¸S¼ៜö¶‘¦F±¹ú÷TÂjLåŠWنS©ßR½˜íF©7[ÅV>ßÅ5écñ¡ ßà=)P··Õì"Æø:ÇöÛêZéü=½}¡Â(‹ %4›ÎIÿ\@ðÕÀêŠÈ0'ä>_4Z¨‡ù΀¸!U'ydºÓ2J†ÏHeüºC’ËV š?VLi߬$Úî%µK…»Ùž ¨øµÿ/Zñ¸uiü‰ÿèô¶“ñ¹7¯%R'è)Áè ОKD©Ô@{ö7Ù5/™-@"Ú/¤›¯' {©.˜W ùœ–€±ÄO€(8Yþ ¦·‚Uú?ˆ3Ú{¯‡ö¯Í› Í-ljýþ±¡Ž€î+‰N_}%Ÿ¢@Ùоúc@±÷ ÙÁ Þö›ˆ~ãÑjɋhÓ!@D+yæ&d\M^i,BÆ@zl>›¼RM^©ßcâ±U ßœãö_ӓЎüb«ùƒ´×ùߛ•HÜØl¨¨n@.ùOk{1ÈuêE€Æ£.@oÐmmPNº´éeZÄ+…è.@¢U›Iõ'Òl Äi™ÑçIFÑã7@d¡˜àҊóÊeðæ^áø5ýh£Èç…áó.–ºÏfð"þÄt ’²ø±Üþ˜{WË3ÈyÈ'_9u×9‘A®:v +œgjìGºl×ÊK€Ûä]‹·9@aXOÐßä¥ñ^º€÷IÁJ/O*µ"YM]Fžw­4~¹Üè¡Î_ÃpmYäý‹L[ œ“Hý”x€¾©*a$£@ÿ +òÜ$›àTùa~òEz r—íkoN|½AŽ¬aýЭøÀOé¸`O…·[•ï"7Õ_—ìÊ~ÍTNjüàEõf{•¾ä z<¾oi|‡&4uCœ &ѳõ/RßÁÿû @G + d‹¹V°HTÎLßâÈ…|¾òŸñäO[äù×9>^sŸ÷yñÁ^׎×xUûû~Ô(/ÇÏp­ŠO"TÓ±çCƒe#ŒIù®ïûûý[Œ¡ÛîT¬ûhØ÷ݪ<ò‹Ç%}³Pë¬)ZõOd{¥“¼É + gA©õdÿØ¡»Óô¤+8\;Á™9³~{Ñõüª=§ÑóÙ¨À×5.‡`yh‡™î|x‡³Ýɍ©4¤àÐ/©Aaš3ü¢\r¯³.uÉÂÏäÔÝØÁÈ“ê¸Eº²Û9:Ù[õÀ8ìOäx£AV„ÿx"¢'õ>ŽÖF;£sÂ[4®Z¤pÜá±þÞS_Ž0{}nû*œ8zUñKn»u¹%M˜§x{æ¬m–¼»YÍ槯¿\Ÿ¨úéx´§5p`ë|ï&Ãßý4Ón;×)^·oú½¸{ËÜÿ æߛ¤ÄgF GÙÓd8=JÝûÚÇô¹À\8V꽯>ÌGíêtùÈÈwóžË÷¼ 8מ×zɜߋ!âný?єY;ŽólëÀAýÔ£k/ܒxÅ¢S±k{~0Ý]k–ËX¯Ù¡d½¢a‘ Q1óoÁ°.ü'’ú³Ä€œyItƪ +0hzJ‘úÙ"Ÿ¼Š±ÇR½èiœÇa¶)ÝN°¼ö¥ÎåèuyËs©,÷á,>à8ëø#+oß1®´{¼Û ëÖz&p’qß ß” kÈm¶ÛñØA·ã=“NäoN=ª¸ÁͺžAÑ÷OTo$R¿ñ :邼ã¼'¦çÆ7Êï:k=¾ÌtpŸøoޗ—••GîsÆÉY”Ó=ˆ‚Ùóœ`ëÞmbÓ}Y1üΘ¯¢Æ®;)nÇ^±¶9¡ríe*̺ÜÍuiíôÚÜùè5 áÚý¨4¢9…Ôç“úü†tà‘^zí'»_H¤ªO==í.‘º·¿ 8bÊÉÐåÖ®Ý DÅ`¼x®ˆ§½=USß0p]wSõLSßÞ Ô®Eó?kïm¢º,0éhM[’­šú\RýÕ[d¹y»èÊçtz¬Öþ=¿êm¼b|ýŒ24÷ŸHÊ“èœWQ~ðBæŠÈåW‚V̳oX•Ûy–m\:?tmã—¾pˆRE·>¾iÂ/ë°e£²·¾fŒ@ŸOz‘F\âÏ*X°ò­,pÂÍåhz-ö‡Ü|1Ù¢þâ0.d‰O{ ¶FS¼ÿDR‰ + È:"Àˆ¶‘äÍÒgpæõÈdr¡#’…@òïoëEfœ™}£|šíÖ PL$|¥›mq¾i®%vwÐrý¬vµC°ÊàB´´7ÕÏâ0Ersw‚Tå •'劓 µ‚I÷(‹³¯É¢ýÈÕÑ3ú?퍠Œ“Êi"%y”6“„ï&R½R&ÒKtçŽì…uÁÝ7ØúA§C[ûÎx òæò–wôÕZ}¶šŠô¬Õ§x9(t“:/s›Ìm~.9/Y4äÔÐ%͵.* ™˜EÏûxÖí.L±eÆ/qՐ¿â +SAŠçŸHŠý&Ñّå$ƒ.¬$áYÿÇ0ù,¸U2ç4C_zR!{âéFeß\Ôº»Ìµ26ØCw¶ z¡E C[}îߍ‚lkÁíûy¹¥_’š‚~ˆ«.fÝǝö´&X%Pϼ>ÍÜÙpºÝÁt»®§•Mr%žäÂÃfë9ÀóŽ Š´v‹«j<>÷ðÃ6ž™¬ŽIÇ·×ô0S›«8]¹”%µ_ž¤¦!et9è ^-²onm©yoŸfo&L·ÓK å ď³Ä}¨Ïáõå‚Ï‹¹¿'Ü8Aôþûø _~N],xÞàä9‘jÙ·èe²÷ûiw .ñýy>¹‡Î3M/ÐÝPÞ5 Ü3ûë…sdTpx +ŠS¨ÌÇ(r ?ÖáL­Ùú’=L¡ÌÚã÷ëكãK4mØY¾Mäâ¼=©]‹³‰^]Xï&¼¹bnq8؄ä'_î+®ƒý«U|œüŽ¢yßÎwï9Ǫ¦­§ƒfƛ(å݂‰©Ž:n¿µÌãðt6l~ûþ#SîË+…îË»]Æö1,Ö10ä{¹çÒ·ùïÍ¿Xv7{öÊEÎ×;ñD“Ú·2>µ³&*eò-u¼­/OŠ¾É®*Z.D ÿ8@äv¨–gôî@x뱷˔ž´³HêÅô¿ªH;µú’b½ïfXb“Þê­ÜzBø!_e¬Hj¾M‘ZpÚõZ¢ö¥è7ZXô'¶½Oý€>öÜ1÷Nìû[“;Ó-vŒ3»b õ MÕ\£`,«Eå"w‘G<³ÉNNHº~6,dZãõ‘ë3Ù8;¢'­0ô–£ù@®Ö×ý泸﵃b@’Î·k´7颥nvS »ÙmÙîdæÙýHԇ$&þÏø0òúR¶u,ëöîkDMã<`jëç¦ßÒ ¿J*åRu´XÔR&%'-7ãÖâÎ_gÏ»*³ùqÿòªoÚ¦ÎXy8¬Ž½Iÿ­¥žv”5r³“®yXû|úvr•B¹}ˆ½qûn‡N®&F\ÞþtòþEê;ø¿ñ夷yâF˦烚‰5åõÊ=–Ô‘!U—"˜¶äµjÑÔx,¦§¯eñõaٝĘÿbv.Ó§#À© +ºm –Ó1Ùïj?þПk~Ffï¸ÖE¢šÓÉ2hóƒe¦åyŸZk¦mÙÖLÒ­Ù}´f=*ùAfÿƍ}óõ­™,ãë‡"¥3ìêˆÀ ‹à|Â¥m¸«ÍXkË US؁c+³?ŽX·çSâíû<:g¸¯=t¼×ß/š$å.]æº`;ì}!·Ï„c´®Ýó©U=a/âÆ/0¢ñʤèæÉôæCž]›ž7uü‰ƒt.֬ѱ„oÂUiÏGóò-1„…Ù.*r*Ü&ï½dò«¥NùT%ô6ïйOÆæÜÑLÔÝOÆÙÎIá𶧏kíòG"[uHbˆ¥èHÍçíµmvˆ’ÛXÛ«ÑcXý[›êF8ÚÔ ÷~©þü$Áü{³ƒr%l3š°JÏÖمì3"u“?¼Ü/|&Ÿ­ÜgXtÍÓŸ‡D/ûýìF'm–±º¿th_”Ì¥h¯··w3ÚùÙf½§iÓèc÷jzW§e¦Æ4Æóêa¥U¶“¹T 1󩸛G¥" L¾" +úŸØVÜ&¤ev‹ïB–ž@„›õwéZÜ1tiE´XÚ´† +Ñíôû™+I2iØq%rÒ®DYž7w©©Ñ»ec3Qµº)ÈF͖&v ½ónµüŠÐEeq0ϖ‚],5и] ½IQáÖËœa?;<ºÐA‚'ô'´þŽ _òÞ"5¨Dܽ40£øq.öÖ3QWFI&ïå;BuThÍ;P±™n¥±kÿìýPdÛ5ôÖèV OlP)¾U®|oãR>rEe|–ðètU°ørÞ`ýêk_ ˆŒŸ·µÈ3]Ë£àAäF•J +¿! æ纜^½—hÐw»öoÌ(¸ÞÊe"GFöÞ*FЪ¿;a³ ºÉ‰4¢Š»ÊÄe‘<J hñ-¶rïâ=ëW*ù‚9/ây{¥Ug}CÛC;¨k)´wxDóK¤šß›ðœ{ð\ #¸Q’³Àȧ `´–Úzc€d_"@Š àüXn/ö ÀN)ù$‰M“àzGpamèûôœi¾ô˜@ vÅí>€<‰ÐÖ‡n +š<übà‘“\¡Ù¿W€;íDêӚ„È$RyJÈPÛ'·Q¸›ðuCXÿN,Vžœî#·Ÿ·éÓ7–h¿ `<›<Š“ƒ:àbNK ¹ â€K­L1ùËÒ<ÿ´´|l¿DôOüó#u6?Nþã0}×¹‡'€˜Å ‚HëÒRáü^êöŸGšIЛYôæ„xþ®8¾˜Ó œ€yLÿ †·¯ +q&¹Mzÿ1s—ÞG’Áßì§[xcF5÷'’ØÌ':½)î–èüôe€ÖÌ @{…s‚ø±Ü~Í@ÎP «É So NÞH…NýkÀ±_0À[¾¥±y[±  ŸªF7ÉCn#ç®­DÓ½Q~•¢L9ºî@1’F·tYiT«\óÀ#¼ó±¹Ã,@ÇBj–Ž¶}O® .€®¿%€²½>@†ÐÌLj×ö²[}¢ú?›g!"RÓ&ÒåF 1vn×UÒÕÇvoNì¯éBøF’ºÈ?›EùñÄ•G{5.†ï6‰…k¤×åAá7$©^ûñ þ µÁôeÏAŽ&,[íS‹ȍF5C—C€ï@·M'µ ‡ñþidãjào¾oÔßøãD¾få=ý*ï}>’¾¾Õ¬üöyoÓé2ŸÇê«BR_¢÷ÁÉ(ÝvÃSå6*î‹Á^S Á„YæþD’ðd’¤·[¢Óa¸dì-@>£: ßD’AVs‚€<¾oþؼçä´¶cƒ²óºìß~(÷8ª;ú$–vé¡Ú›æ£Óµ{áza3÷Ïn#܇¨»ºg·¨sKº‘bçðÕ³øÅ»E/,Ìs¡0ð9¢¨ôˆ×s$°Ùߐfºp€„i+͹De]ù¹ùýyàåAþžoÅ<„_>æ/¢fß>^ᆛgÞ͍û½Ùô*µuÞPY*Šlú¼Nö®Þ}À\ü 9õî7N;?Ÿ×‹»Þ€÷Éx6¡Óð¹Êí™™Î4sÌ¡ìçp8ôãߐ¤ºžèÔK?;Àä›OTÎ4P¨Ö\P­(85,æ?íö«>ߟÞp@ Ýœ oØõá]¯Ä*¼ÌpŽÞ_ȍÝKÁíÃnå4¼oˆ£MGT øÃä^Ok=Q¯ÎES­Í`û–—3öü>vÃà¢Ýc8xþ†$á}ƒ©$]¿a¢3Þ­AÁæÎ+eb€QSü՘Ýk¤zM3ô©ÆI¨%ùZû$±ôîŸLw0Oðò¹mð<`3ó³/õ%ÄWRўË\cº‹þ®UºN-Mf3þ&i±ÍðsYs€í^†µZ†)ґôÏõÐܙ9J<[˜&ÀÏ`„u˜Ûÿ¼kù2ú$ûjñ>F ´£†^ôL\³±–ûS¼:à·¹áøÆÁ^˜·t"·’¬Ð҇ÒÛÜv'™áF˜†õ-sP‡›#Ž,6˜ê¸,žœÞ|=×Ó¤ Káÿ€2¯șòAOü1¦D5`ÆíðÞü©ø3ŽÊ=4˜UͲ÷.­>ì†÷Nœ`ÑmB>¯¬÷‹ÛšÆ0ïtà¹Û±µ6œÌGë©Àdô«#`zõ³ii +Jm6êÃÙYê³¼ +´¦W4"Û¨Ï]ÃWÕæý†$f©¡Éüãà…¤ ð|}ûB÷õøVô÷¿??WBmåݏ§æî#N÷ºÎ¢+Ð;Í?s¦)•EcôôVÛBŸß¬=¿bëþ2rµeÕT5«D«wg )Ÿ†SVjn°´âƒ¦dmï¬ )é¡®uS†Êö’ÂûAjèúïÍzÍõ@¾~' o̓ؔÒ&×Á¼î!ƒµï~­Ÿç¯keŽ.ºÇ»4wú3×3é9Úñ¿)a„¤ÏÉ`¥)’î£vÝݪ7*•ìܖÈõ/&õ|a~Ä÷3òœW+ÇEûÜ“O3XN5/…û’²Tíƒü$Jtzþ`ëg6 +3þ3^l/·3|?_^‹ÊÕ͑­÷¡ò˜äìŽ8¯š»É¶½=å‘áúz˜ŒµÇøÀ©Ú…‘VýAn¥@þy»DMݙ»µ±'_ŠôS +r£¬T¬+âòÒN§¾¥º9ßIÁ†÷åjåôW +ãø@®ÕJ¤ +,ÀŠÙÀÉ«ÏÖÝ˃5Aõ>Úy™·y:&uÀÃQöÈ2t‘¬Qh k_]wµg+ªäPœ(—–Œ¯Ë Œ¨òåž7¤`÷>ŠJßógZۏ§ñ¦ˆOû™õ`ßÀf¦]£³Ø²&קًîþE:`ÿïMÒ*QéݕDêW.=œgÌ5­;îŒëʋuwlvíC­ãÜv`é}Mf–)l.R­¦/“–ÚËoHeW-QË|̧ۚB{*WÁgñãA<Ûé³WiO7oþ"˜! pÉÎñ̚èòÊi‚5œ»ÓA½¤8¦8ü†¤Ø ä,u¸$ƒ¶µè¹y§ö©~zØÖEg3/»j͏žø253ð,ËVãí¹g!ëÆà^Tc«ÒXAC±³,`þ|V¤û8ˋ+o-ÎH–W§™wÝà=rG©²g¾±Ó¢ÛdÏV>5sÇ[éÀmÛKñóiÿ’ú~C%eiÂìNª· Æ-<2gZڲÍõæBß}®Ÿƒ™_t›Z‹ËjzÇHûi+JªK¶Û"æ"²íJa©œÈœ&Sc>„RXðùe°f½ªíL|üàïhð/nb}¼ø¨òD.[6;kRgÖ[‡ûÿAj N¯I±·©ÞRx5YY¼†“Eïl՚ƒÓ‰hŽ3›f5ÆÖÈ0vÛúsÜê`.ç–Ç¥Yš_¹ºô(LÛ³øvïM)t6ÐU…ãø“›ÖÐl¥«¨ãû“µ˜g x£÷cÖjµQ;S0f†+·ë°g{Z‡_ʤ\É.ʚˆIOäZk³9¥³§.l ‡\iO&sM™Ž[8µŇƖþZ-—†ölDÙP¤,ähS¯¥‹dG}êêŽ@>Œâ8¿äý˜ŽÏÍ]RSÈ$q†{â8=¨'Bz©@m“=UØÍ ‹Õd4ÄVLå..µÏG&tÒkö WøÙ~ª<, ÖGŠ½I“8Ќ¾`¹ÑmÌiØÊ­©Ü¾qbfÿ98S×Â`Š&C¿o¨Ü}u¢鼧açêü†ŸÖ³ƒR¡eÃI„Š^ý„Ãú¾ù.4wfÑ®›ÇÔ6·ƒBéº,Ê*|ÊYKáÁ]dÅ^?Å~'—¢W.ÇU¿ÈÖW£úX=Åm¦×5ôN¥ÆÔ¤ÑH76â>¦Êni߯]ûaï.Ýò½eÝ÷åÊ};(G+wà-ÏǁÇ;ûߐdÐÞ((ï› ×Þ +‡Ú­í¾E¥bbÙ\q“dٟý>Ò££"ڋ[zG—Ÿud/£`š ÝwåkÙɃÝçÇÝu¯<2£¸Içp¥;tÌh ҍiÞki½ÜrHm¬„ÝØÍä|Çd»¯Éè(¥.#=¥kRìÃó5f{—Ž¸«§T¶ß†R2Ù À6óPÊkÛOSÜ\­¶¬¨4%Gí²$Ec+œ‚‰“ÇÊ}¢vséæÀŒÑ^C#Dé`Ô©†Ö†åÙ¡Ó¿cóaï‰ÌRwÅUwë(v7›îZèç:ôj2éX^mÓÍf­Sw08ºƒ¦ãü†ÀCšéJ/Ñâ¾)Ù% m<ò› £ÚvûI½ýTtÞª0©¯Oš3’Ç‚°#–\ƒ +¬1€¨3g@H³½ígxÑ{È`NŠ}"Ž›d¼ºô»ßuÀu!%L«Îº†ìöä;¼· î·Ðr§o®]ØYF» Á§öä’;´'vfÿ¼õqR:H-·¸ËÞ2ùm%$amÛÜefähC3g`¦vÞg•"wŸ†ýÉ[°ùqv9WGyÛQSÿuÜKú£¿:¿=RìäÈÁ¢SëÒ3‚ìŒçq›[M–­é~½k•Ù|HHuÒ£y:!ÙÕ !i⁐D1m= ‰a÷¿á„ÕCÜ&/ÂöR'!½»°¾ +wƁê{Æì*1w§@vïÅژ*‰ýKôYJäæƒp[÷5á|èõkVê IBIÿ®‹‚%ÔÁ²Ëb[DKd÷œß"Ñ贍¦²Y]›-®7^øƒlh¶©641Þ5´1züÎêÄb/“é4‘®-V@9ž³oYµ‡Ïéáí†\Sbc(ÚÂ#nÜhRר:<3¯IŸœEÒº.”îؘœìÛenpmIÞ8"1Ÿm>ûK¼ñ¦×Íé?éºÑ(§skõaFßÕvô+¨*z¡†Üæl 9~W5„'v :öo0'í)´&n«x• ?/ùyé=¦‡ýæÆ®N°?Ú?Æ%ã[lu^éšÂޗ¶zäȝÒ݂ÎñmjÊ­úQâ™ß6;qÖiô1Ä«›Óü½fËù¸††u¤Zxõ*\ö*ÅÏS(‹TM+Wáí9uÍ”‚C©Wš³1›öl~®ÿƒuØÝÆ+&¼?å§V¹Ok%`Ûͳ7š¬Èó@±cÒaFr$zò°NñƗZ:¬­L¡Õˆ¸WÿžBªf‹f2\hiϦâªs±RŒ¥\͈ëҜVvEe¢ñȽDx·Œ¡Xì‹Ml#‡#¬ßèÌ ßÇÎ.˜*'Ø¡¿A…{ïç| ‰Ä ›Ná±mÜ9 +íšÛ׸¢Õ Sû2_‡D¸îEÍ.ô}Õ¿Ç˧fÏ,¨Ê6¦h¥ø& åÊ·Œ—0R)¶rï:ÞÅ}ÛÌîdÁœ{Tz<¹<ú~Ïsl¿œnʀºwFú£ÂˆÄЪÈåð¢‘ËcÃü^¬ßf¨Ì\ØvvëÒ§wþÔï6 Vû<†UB©mö “3ëÐùæTÙº”6k•â‹<”#ï•Ñó‚w±õë—g~ªoy¦UäzýºFრ+Ãä.vCª9ª +7p¦)3Éjs[Ì&am3ñstÊlÔÝ#ÿþAÌ¿7?P¯h²##=W£ !¹uÀ@‹þ @ PN†Ø!ÈFî d¯¨–`¸K°ö@Öñî »G҆ ¹S= d=yþ’çÝäùÛ&yþf^þ ï¿8ÿŠt®OD¢OtθŸÃ¶àÙVðè±p5épA@ t¼!Z6Î)¡ ±Pi¶Opº¨œt2 ä<€Sòçh¹ŸÀ‘T­nˆÇ—ŸÊ jxÿA¼Á-ÞÝÜ -ÌëoP}–üÛûÙJÔµ©ÞŠðó:ðKºN¶p°èF&±€óB @w÷ç0aÈ-.dNŒ{@Ê; uU‹ðɯ«ÔŒ>}74#‡ K‰ý$Ä$!ŠbtDo6»y¼ »ùýåŽØ[Šà_$Áü{“$¼Zp'›HõR?ç¦Ãd˜™„g7É'÷ ¤øÚ/X7;Y÷†I„××v‚÷ÀXù™`’pFÍ'¸ÿœgËÝRÒì>_JlkÌá}8Γ ½y]æUÕÇó–)…ϹßSÜ~€üSÀ»Zû“²½1?féèüÁȽÄ~"hE€´" ‘䍷ú_ zùà N¯¯ÿƒ$˜Ÿ+€§ŸD*7m´úH¤^äZñ*ÝÂ#N½ä:( И¨Å,6¢_—:*D ©Ïû-Ú=ž»ËùÑÜ{¸ÆñýCáû`ínVè¤YàF nàøäësýzN_¤“ë{MûžÕª¸ïíÜsלxv{8sü Iá)':oz¢S‡û G™<È=:鑇^º3,È7“ ˜ÏNÐ÷´Q¬DóÏ¡ûxåØq¸™U¥û0|鷑s¶ƒ ¿:û<3½_½í4¾øê(ëÝçüù¹êUÏmÒu×õ=2Úe㸛ŒOGä뇉²M¤8(ÝÝ»¥ÕqÏ_§ÎoH²g»Ðî9Ýú¼;¹0JýeÓsänøäôz—ã:ô|Žµ|¸½aõ›³¶ú¦·'WqwO^xž©g­GîOf.¾œ Aü8¢K|˜Ìoðþt¥}±Ò"Ùü2·å]ÅڅÙÝ)ÃݵÐÝÁŠÃI±û ÿLEŒ›Õ‰TE @>i‡@MϒÇÞû2 Ãg$œÞ!Ää²ÁÉ_¯rîÙ<¿±"éjæèt©éá˜Å{7ܝ‹{Ýفãœìú}ìˆË*õ´´ê6cîY1{—e˜] Нµ 8ï¶öçbo|hmZlþ†$á¥Dç î‚ÜפA>æåtsQ`îEÊþžZCÊ ‚À}˜¯K¨=a×ø~ñã~IÕøôi¿ÙÍRßµ>YÙêz¾fö7†aP«e"ÂWým®°Ž6¬¢kw_iêw?Ó¯Øb«Kpt© §#i]`É7\uó’b´%’TíþÇà×Qç‰Ê¦ñ¾véãc+Ìö7nt9^›…jàZhù},|(h_Ù\K6Ñk6¬5sJ­êf2€¤ zCpÛ|)7ØÇUÖSÂ5t)·Ùk ÜôÕÇè«­c _éÙÃh¥׫•n’»•îÒÛÕ»§ÿ@ÿ e⟩ˆ>ùÁ¯°ó–©s§=Oó¾Ï}7¾ÜÌóàÈŽeܝÛ(úì´u 1¿Ú¾lŒvææä^ºkO×(].öYmJ¢º:e¥ï†²5oéØSɼÀ}I÷HxᘏîÂyòáÔíÙz›å¨†¬—#×~C’AÏI”†b?ɛ°ì[Ø}a>É=¯ÞŠÙù‹óÇôˆ×Ó¤“µöÒ§sÙ½3ÊË´?»=<‰ü¦øu+ú<ßmhÄìÕU;ý#­||n¢d]ZZ"zS]ä—esÎ]HOžÞ¦o¹¼ÌWå²[Ê³^¬É^0\ϋ£Ÿƒ7çř¡þ€^È”Dêh"lˆ(O}_‘î{í úõ5à\»[“—ú~k?#ȵ~+4òÕX_åÖR¿ jê-È_õ±ESÖMr‰ +=?—½çn.ùUïçÝA$çc¦²ÃüL]Œ‘XETàPÃ)º’êBù gZ ßÓz?Æ•ç£Ö5d}¹Ðî\¢R³çmÆÍá Ëxü¾þª»ÞÁÞ{ãqÝ̲ÍHoRòWÕù\n•™¯ð%³ÎWXÑ#æE ö¤@ŒÅíÌfM¨Ó¸G¤•ðm ¯‚ñ +aa¸¿…ïî5Ÿn–smìÕ¬;•ß”%¬ òëC¥OU¸qô yy^žÄÙl-×öNd³üØÖNP:¾1ícm‹Úö¬ßýç]}ë#°ÊvŽÐrL·óóóÒ/ÊRN®I •èˆ-&²¾ww.@—Ë–Go_c‰Ñ‡c[“ŸkH"ï䪪@]„•`›Ô3åçú?9¡šHõ/ýèk_:Ý«ç/>ªºhÜkύá<”ÚeT[4Ø}u»ŽÓ“Öq 5äÑh9iˆß¹×Ë"rMTS“ªøÌv*3]þÓl÷ؘùœÈŠÆ :[šiljxƒÞ“ê"j±¥=>eÏ«ëŠãؒ;»‹ßrf« +åxpwtºHöòå’kWŠå£`ÆÕýMw«6Ùݐ¦s§›ëò¦é-µl¯¾/þ¼<Œ.áüRnÅr8eE•æfd •„]I«ñcƒêpœÖ¥Ù2žã'5[›X+ñ`VÓ̓iWæ4w%¿ÉÛÕDz_—¿ýšÿ†¤¾g: 0+ ƒ)é—Οg;¾Aq+Eû]¤ŠÖï¶ |Uš¬›Œ”n1¡n姩0Ÿ^2¼í+IVÏE¢Ö]}¦ßYFæ¡Àjl…õìjk"2ƒqÓ?O˜¶{]ŒÈ+°h£NÝèÁ£Qõr27z_ÛKFU‹1Q?ΐú@ý÷æIqÚ¯Ìv¯wHÆÝÑþ’?ˆŽXpÚDÛe緜Á÷ŽµM=oQÚzÐWˆ°ÖçräÍx¢N<©…Ó±«‡Îu”ŸÍ«P£8ç¯:£•Ï½Ñúké¡®KÔÈ8n)”jÃãÔÈ#Æ4´Ì.h³ÖžÓ_“CR–æ­{ŽÎ–¼uÍ]å'ç±lävƒÍ1NûAvS×ÛE½c“äÊFÞܒ—ø•|?\,q]¯ž¦»œðǸüäÊ¥=˜Ü ·n™ÂLÏÚ*l;”ýZÐCÖXˆ7:n%K;PýËç–”Xˆb#><k *ǓòoäB¥»‘Ħl¢‡ê¸î>è6ó>™ÙÈÑí£ÅÏSN…1ŸXºîz4o@…´%Æ+m3µK›w³Ò™õÃÏmBä—ó¶û™ÑàñBiDvJÃSiE ¼übؗliÚ»çΛ^“/yä³xC{Má;êݱÜ—ŽÙyßÏáò¿Hßæ¿7O­y¬_žÕNá(”ÄiC0bîÛtf@W¨¤ßÊqšý,KßziÞø{"ظÜÔ©w—¼päß*UwÖ ÀgnyèÜziñMö&9¤;°Jg4Æ:í ße[§‹¢¶ŠÕ¯Û*’Q®U,œèV1Ӕ[øãHÿƒ$˜Ÿ«;šhˆ³*f’œ)çÀzy›¾T¸~,¤eç&~ÎÚEJ¥ëä5s‚ñ–½†® ÅQî'èÚ{<¸i'©¿jªZ¯ó;r™x]êÝ ;Ì÷ǦÍÁ ֚æç-âÊ»c¢z-¬š‹š|j.zr¾¹ÀtÒw\͚ÕVn6¦+é7ìƒ{²èõÝÔ»‹—j®ßÅ5é6ÿHL›µâåqš¼FSw4Þ#53ÛÑPvfè€àåZ/î®äw`p]UÓ­êÔmÛ-/­K}é·*Šñ&êúm.?ßF#z£Fçº^Ôc¹|¨ozÏL}ƒÝÒE²õÞ®4­};Õyí[Áäß°Ûn¶Ùoë/õ»öïËÒ½“¨´æÞ?»AÍ¡Oùµ=Pr²Û×óÍO¯ $¼íÕ:Ç‘úª·§:ݒÚužXô*óæÃn“,Úsd÷ë[Èk–íæjô¸BTûrRÍOµr‚—Ê Ñ+nS®OÍ*\£?ý I0[?¿µ ò¼/…áKäCITÚ×ãÌó6¼ÙW϶NҞ÷èæão¦í¿ù–@Ub©D­fgô=þ2ªµ _ہp^=à‘V-̾V¥¸-¤]e1Ûy–‚‘‚–êAÔ(†‹Ñ¸¨ žj±IW<ºNËx¤ƒ®ÕKìoÐ;ÓÏ]ÁÆ=_Zgæç%R?1{뷐®Åí°¼j«IH(½Î«Ù…+ßú÷Ãuè’Áª‡ùµTqWÇzù²¶Z¥À\uK X§Š­üj‚k¼%bÑQ ßÛË.PD㖷µE6ϐ™zý£ÜÁˆ•gXsͱtþ Êá:ò¥wC9 |tûÊ12É錄j—šS©©v,µþ=fv5{ú8VÙºåVŠ/éR®|¸[© R·k<:â/,>âÂ׿ T=BòL+Àr=¬ ®¨@‡ÈÅ +H5o¬áÀÅSÙ€çS¤7ÊãúÇÉoW›Mš6‚ ]cÀfwÔlÈ[¤Ù£Ô–¸ˆõíx’ôüæª";¹l'‹¢2"V¸Æ¢*Ö/zºkë<±›\t Ttä²kqD]à9Û½Aá™JÝ®³‘Og2…Ìeú­m#Óo—F 6ËL¿St,o žŸß²DŒƒ¬[/¨.×ÔÛµ’O~dÃ÷dWå9ÈÒӟíÛ³Èñ2é&O™ƒ„ƒÌæÖ™mc”@œ&8( ³ˆ6 ³¬8 &^‚ýd”2æ¾2>L0— *Ȝö/Ò`þùúdPaXÐd™Ú|ý6€äÏ@}| ŒS@ölí@VÍ ;¢3 [±J [ÅHÍ1ÉÛäL)AüL6_·LŽ vÈ|ž/- Ñwd±“ÀJžÇ3z‚ª[ϒÓ*¼ý¦`ý@Ö,`‰ÄYåÇrûc L½¦¡O¤c@‡£ .sP³(»…AÖUµûIÄk— Z€¬^ß&à÷ +©çþdeP«ž¼Mib%0’GKÏ€Êå@ÈN°K²Šwc4œ¼ m}õ*ö¶FT¡tç);cëY“æ³.Ñæ#¬µÓ­'ÓëöDèOTî©;$‘úl·‚oi€Ø EÖðeãX‹c»ÉÃ5%‰õO0PX”̌ØÔC̔öi³£Ž¾Ù¼¿ .¿\(¾Š×I+k>÷¬GÏåƒød° eûfv·ïýÊɺ}ã½y37ëíoH|YðêYIÔÕêÿØÓÔ 9u˜–É'wòBu¾ç%_/äûÈƯ3c‹¯ÒÖÕ"ñéšQuŸó ò, “&ý•3&¿ˆsÏW§×K㔷̓Ÿ|Ú1’c´86#ïdïÞ3ù}xv£ÁõžSâOPìjðµAåsëj4Ž=èì[qx€ÀÜȃ?¡²çÏÅî0]É¼í¤€_ì~7õëºêâ,ëÜ®uÑPœ(wÔóºŸ:fx‘r¹ÿE ã`9Îהڟ¼rLOhTh¤qZ¦Öyëñuö-=&wWIÃá‘ÿ™H/Mk- +ûb…ªíÊI¥³­^¾Ô¦áÝyW{'k=p5'j,‡”ü½mð݆Š$´b¤O×Ú祑ÅGÏ©UBÙ*Ā”1úKºš¿/Ò3¨’†*/ÓPÅ&‘Ž©\6'¢ü¹üüuUíÆ·Úuz©['²Ao½n]vg öÞÖÑà>å1º^‚ÕŠcù n;ÇiCá%»·¶Êß7¢%”73ó(+³ìE‡¥\&B#ßu£ñŒfM¾#éÏ>ҟdÿ1|ëaqþâÕcä!’1ºÏóÙSçوàýPé¾YÜ¿V¯ŒOý¯z|ìX»jÙoZè2X›Hé퀝#¸Ú:byJ3Oã"¾¼awYSCÆhJ7QŸïžÚÂpžö<†k—¹µ;åæ@Síþ¤Tg„0ïÇúxN!6?Owû/ÒÓhˆÅHùوÑƜŒ ù*6®¦l >êä¹0ÔÑÞÒ®FÔæî{»Z; [Êz6vžÖ¸]M)~Ëúd‘7pAªèN_ôõޜÊÁŒ¶î¡ÒlKWôb wªŸBµxØâꈷXu4}óê!]uÆP=T[Ì_²”j¶Œóì¬#㸣S‡|k_¬ï6v!$vyz|ýcb_ADnÓ~\§k …›«ýÚÜZe§|^N=çf´ö³øœP`þ]¾Ð9¨*ÌêÙã +3”šöÕ1᧕ædª(’mË· äÙ +¬È÷ZH+õ­È)SÌb”i{3P¦ƒãoâ¼±Lãtrõè0uz7¡>A®j\@Oñg“M|I§è•l¡¹Å]d°^]g’ÍU?º…M {Ùìî÷ºÁt/ ò>æPoù™íÞ ¨¼:=ëPUñ§Q[¾‹ïÁäŽÅIçX]J&¦Åï”.H&ÃeOHJŸ7ÀNº6œè‡ý/Òct›žK¤öÖVۚy—sç^ÅȇN?w@¯íünÊ檮ɧ½VØÆë ˜³åL„L}Y²Ìíhčåf×Yá?³‰íc%èì!ùÑ°J“wNnHŸ¯H¦í,ˆ`lhc†Jvã<äÆîãKˆ°bD:¸D§ Pbbé_ü\:!¯š£íƝ¹jùkÓº€Çõ£ x%lô碸†ÚT{5ž¼³î“²þénô˜¯Ù‡mwꩅŸ¦òþ(͎þš¼L"EÛf^Ll,막Q$ÆùY‘&5EsW(Ïè¯pä´Ö¨ðé Gûõb0FŠõ/b¤uM㜊­à8®BçÜ;ù¦!:ß­±Y2e˜õ¼½çJM«jÙ´¡óã…=’g÷¸-Õ3*m¦õêדŸkû2Y6è‡ÔßB¡8XŹ1BœJ£bÓk XÅ£ùZá*qªTK›îÊûÍïrƒ—`ÖÞð×N âG¡2ú¿HÏ¥+N»×š/O"ðª±WŠ÷ÑöA‘k‰ñÛaÇwh…á‡êr.Ñ=|ü<Ï´•YÛêÓ„gý4Y/žÉŸ$+ã­¼G#ÂH©9+ðJEip³‚Òg¹Å˜ ¹ÐdºGùƄê¥Æ.X—âpèKq3±Bþ‹±ŸÙ7Æí⥘3é›õ¡å:,†ô¥©_,5½ ®#9l Õ œu‘m0öè¨@;A7'¾¡²û®ÔB&*” ¡m|ÊwöiÑ;£ÄÒh<Ò¨ƒœh4i—èݾÜ0Ì$ûîՁ{¶{ÿ"kƒ +Ðn½?»éY ]k ¼lo,Ý­zÿu5zÇÉm1üª€6Š…ŠZ·BþÔìˆaID|m6’°–ù“‡^½]nÈەÚW¦Ïc¯!ô~&ô~v.PljSåÊô«/jFz|ìWC¬Ø¿Ì£.U~¶HêhMèýâI6|äòìo²D—7®í?›·ÕL÷ùòú²®q)0>Óñi¾»=Ž³KþýV“\AŽ°msA%¢Ï×hT9ò +¯¡ùû!,‹Y=ÙÍp8­œˆ<èb|úW}—'o–ŸuÕÉæ ôÄpÚkǀ×k‹…Þ¢wéÍO«OÎ:tï_ÜóÊ>I!ú³5ûëb¸:]†÷¥^±/ FŽ<5Øw7ÊûÓÏêläþ€$–ÆËc±ÿéÁÔro¥1fÉóCe Á2{˜]ÓãyqOM–HÐoàá‡lU_p(~ë]²Z¡ [U‚Æ‹{‚.caâë”Én/ie A¶ìþ¯1 äØãgc¨íÐA©/_§Eâ4»èêNénOŽÄu±n_£ëÞÏóϝ^ãz9ºË¬é<;D¬½DŸ:rvo’]³¯^k²­eÏÊÀ«Û 1˜TªV¥ÈÒ<ÉíýKصy€´÷[¨ÓArt¿“‰î¿8Qd#Þ5t!\Â0;o,åV¹é߄?k"¾÷”p¸'w,A#M‹×Å׉#hĂaòxÔ”¢€¤ü…Ãõ5R•ÉN؝÷z߶ݥÞ5ÆÍ[‡{µ“ö(âÊ­sm´VÅE$Üg6Üg÷ëd÷Ñq¿~â_¤—ÎÍǵžX¸’ ên||û:ä8]Íín͜QÞ-Y§×X‹Õ(K¦ Äq¥e}ò¥š}¹ÐoçÍ^\ɐc¹nÈRbm°ic8{iÉõƒ«ê¶Ð|¼ræÜ5¤f›%¶ÍvDïû®ÝxÛç^Ãh™ÄYJõ_ü°mçُíÙËçòµ~‹ü²|R›–°Ÿ µÕz4•î&ëp…ùSÕ9&È¢gcM§.­ ;ü¾b7ÀʝWÃ;¥û€jWރ쁲ִ+ª¸FÉVóå:‡Æg|6HË׿/£]§‰dT‡[¿ç|ÍÑfÍmwÈÚp ÿÂÙ*··©¿ÁbƒgU ğÇ|†öÖM‹u–-¾ +ì”\Þo +Á$µ#Ž±mûrøíZ׊[Mj‹àíÉ©Ò4‚g»ãÝdTìkjm[¬jÈÂ:U…ÏûS-î…rE*^²Kg;3*v5¨våJv­:˜| ˆaÕW¥›NÏéó¬Æž Öo›ÑÔW¬³% :mr՞]^ˆñâ÷ðêÖÂ1’U?4ÍR-hØÕfØ-ªÃk®XCýQ­:n(íÊd0£0»ä°Fý:-ksÀ,½sƒS‰àœO1j´+ErnQ…dH/ +N¾÷.ØÑ+Ø^½] )ôéjþ¾Ð“Âä2»¼ö™Râí(K6;Pƒ®7ÅY¼,¤öÄ?pÍn¯8)ìº}¶Ëóáž/u ýa!¹" º™=ùŸt·¾òGk6Êc€$Âòp$炧Bco¾¯uˆî¥ÐoÕ·)3?%ŒôrQLyv~G–>‘_§LÓíB@JúKöi²e \Œ\ ¶.ùGh Šùr ¶«õØZ1ÐkÑ1€ê“(¹¿Ì(q:Ç(¯”o.J$ª’²ìDÉðDE “ãSºrŠ:O9f%ŠQ–)ú;J”F1EÃS^éßOKÜÿ/19iœãŽÁc>óXM㜷j1ˆíŸq¨³1°ô§1ÀWV1ÐPÎQ’\?1àHÊ¢%Ï%/„IéŽST5希’7”îú7“¾ã}£$dÊ1ó‰€ëé +KR4à;Y­z”+TFùlŽ°ð‹tkn ÎÁÓŸeŽ[)£¬}ýóœ4ÅV ­š‡©ï¯éç*cY ºØÒ“K÷‰3ùðÔFû éŽÇÄe–¢äð>¯ªÁ» +ÒÑËw7…§&Dă òìì—'7ÛI&7zðȦf Üë~œ1 +Å~C|9—Fɧ¡J&çN/,†K£nʉa¨8‹s›¾çdãçjAôÙ»[8ÿ-¯b¹-^äZn|Vû'þôX/ØÓ|( 3¿ˆ!Ÿüù朤Á1 øh ðZ {[2†ïE!†‚ÃÚÆýx±xx_÷Hðš sßgû~ÏßcyW¹÷½sç6pÝ~°‰\.@š®äæ+¾y§ŸíEž³‚ËsðÁ?§¹£aÇ.çv}íÎzkèÎy9Öî·5“Þ³·iÌxòq®3N7éÓMã¾h–ëmÄy¡âüRӟö‹ð‚´³+ôK›n‡Éq‡;hTnwºG~‰L[•k¨–ϳq·~Z°µÎ1ôڃclò‡Uz\«;÷†kï·Cë¼çò…ï®xë[ì³!7 + ÝÛcC¹3ÇÉÊà\|0ïf¿ˆs -ÃýÃq§”•#â1’kgiigüÁhVy¾? å>¨ƒZP؛öµ:mx§7²ñ$Á¾à K<Øü™W}Ï=ÀÊntyáÛsíÓÛ¦×f£¸Ÿ±{Gà™‹:ÎúUZΩ NoµjÛv)¤mP?õlнuW.ãµWîäú›tkÚiœŠþ”Ä˳JŒ`¹vVÚKG#Ìà_â’¹ç.w֗òŒxnێzJ˜éåëíîÈI—íä?7SŽ]mÁkÝ JÎçq©;$v!l› vzWL.Ÿ5Ò֎£·zøÄæ¸=­.Ï×Owyþ Ýåd·—¿ÔZV§`ó1Ü<§!"õtÇ¿·Õ4Äf'F Îà}/Ýzw=·üŠ”´NËû ë§àâs´Kqus£^¦;Ï +›»Cþl'ò݆®P´bâ´ +endstream endobj 6 0 obj [5 0 R] endobj 31 0 obj <> endobj xref +0 32 +0000000000 65535 f +0000000016 00000 n +0000000144 00000 n +0000051617 00000 n +0000000000 00000 f +0000056418 00000 n +0001085563 00000 n +0000051668 00000 n +0000052034 00000 n +0000446586 00000 n +0000056717 00000 n +0000056604 00000 n +0000055034 00000 n +0000055856 00000 n +0000055904 00000 n +0000056488 00000 n +0000056519 00000 n +0000056752 00000 n +0000446659 00000 n +0000447034 00000 n +0000448097 00000 n +0000463363 00000 n +0000528952 00000 n +0000560851 00000 n +0000626440 00000 n +0000692029 00000 n +0000757618 00000 n +0000823207 00000 n +0000888796 00000 n +0000954385 00000 n +0001019974 00000 n +0001085586 00000 n +trailer +<]>> +startxref +1085769 +%%EOF diff --git a/resources/FreeRDP_Logo_Icon.svg b/resources/FreeRDP_Logo_Icon.svg new file mode 100644 index 0000000..eac8885 --- /dev/null +++ b/resources/FreeRDP_Logo_Icon.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/FreeRDP_OSX.icns b/resources/FreeRDP_OSX.icns new file mode 100644 index 0000000000000000000000000000000000000000..88bd44ca05621268824d56bc4e14371c27402c52 GIT binary patch literal 60681 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 + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +tool to preconvert an icon file to a x11 property as expected +by ewm hints spec: +width, length, [argb pixels] +""" + +import PIL +import PIL.Image + +import os +import sys + +def usage(): + print "convert_to_ewm_prop " + return 1 + +def main(argv): + if len(argv) != 3: + return usage() + + im = PIL.Image.open(argv[1]) + fp = open(argv[2], 'w') + + var_name = os.path.basename(argv[2]) + if var_name.endswith('.h'): + var_name = var_name[:-2] + + fp.write("static unsigned long %s_prop [] = {\n" % var_name) + fp.write(" %d, %d\n" % im.size) + + i = 0 + for pixel in im.getdata(): + r,g,b,a = pixel + pixel = b + pixel |= g << 8 + pixel |= r << 16 + pixel |= a << 24 + fp.write(" , %du" % pixel) + + i += 1 + if i % 8 == 0: + fp.write("\n") + + fp.write("};\n") + +if __name__ == '__main__': + sys.exit(main(sys.argv)) + diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..b6d6596 --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,33 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Servers +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Servers + +if(NOT WIN32) + + # Build Test Server + add_subdirectory(test) + + # Build X11 Server + find_suggested_package(X11) + if(WITH_X11) + add_subdirectory(X11) + endif() + +endif() diff --git a/server/X11/CMakeLists.txt b/server/X11/CMakeLists.txt new file mode 100644 index 0000000..7b33d86 --- /dev/null +++ b/server/X11/CMakeLists.txt @@ -0,0 +1,69 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP X11 Server cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include_directories(${X11_INCLUDE_DIRS}) + +add_executable(xfreerdp-server + xf_peer.c + xf_event.c + xf_input.c + xf_encode.c + xfreerdp.c) + +find_suggested_package(XShm) +if(WITH_XSHM) + add_definitions(-DWITH_XSHM) + include_directories(${XSHM_INCLUDE_DIRS}) +endif() + +find_suggested_package(Xext) +if(WITH_XEXT) + add_definitions(-DWITH_XEXT) + include_directories(${XEXT_INCLUDE_DIRS}) + target_link_libraries(xfreerdp-server ${XEXT_LIBRARIES}) +endif() + +find_suggested_package(Xdamage) +if(WITH_XDAMAGE) + add_definitions(-DWITH_XDAMAGE) + include_directories(${XDAMAGE_INCLUDE_DIRS}) + target_link_libraries(xfreerdp-server ${XDAMAGE_LIBRARIES}) +endif() + +find_suggested_package(Xfixes) +if(WITH_XFIXES) + add_definitions(-DWITH_XFIXES) + include_directories(${XFIXES_INCLUDE_DIRS}) + target_link_libraries(xfreerdp-server ${XFIXES_LIBRARIES}) +endif() + +find_suggested_package(XTest) +if(WITH_XTEST) + add_definitions(-DWITH_XTEST) + include_directories(${XTEST_INCLUDE_DIRS}) + target_link_libraries(xfreerdp-server ${XTEST_LIBRARIES}) +endif() + +target_link_libraries(xfreerdp-server freerdp-core) +target_link_libraries(xfreerdp-server freerdp-codec) +target_link_libraries(xfreerdp-server freerdp-utils) +target_link_libraries(xfreerdp-server freerdp-gdi) +target_link_libraries(xfreerdp-server freerdp-kbd) +target_link_libraries(xfreerdp-server ${X11_LIBRARIES}) + diff --git a/server/X11/rfx_test.pcap b/server/X11/rfx_test.pcap new file mode 100644 index 0000000000000000000000000000000000000000..768c3960fb5cd1408eb3d2d6eb9afe4bcbf9558e GIT binary patch literal 994948 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

    sh#MaU@ky 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 z

    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�yEAq8h`n>z-1$B265khY+tq39J7P&^;?-SviNJo@scg) zdaQ!yHpolg-^fkt;13&%wF7hqbkz715HLt-1U zZivz;GF%c$U&(NtHzFf?_e7}I6uRON8|HKIQU+S(p}Bpo)Z{eReI)20 zDU7{?HMlPMv!Q(U*o$OU2w4MPsUhj4Im>^2^#5Ntxb=x{07D}IyG~k2<(?Yvft5W@ zVIeZjt%pQSh86Wtzu?cxuERfd@?Q*EC1wL#)jFjxbwD#qg>@UnD&HAX2wT;ObX-ZJ z9tj|ocqoCTwOF-|lGIk~>blf@O};L^o(qT1P0W~F+;g-0#GY9f9I-4#EBdAQ7N1ok z(opggQ)(M1x>vLV?2aHyQ1BBxLKkpI$Vp}JkU$q?cdiRP_W@`0jk&YJ|XA% zb0*j3-Wj&>Tm81AJ3L4S}M~A<_8K?!)+l04jX2m|@!gH`GxJvzR*e_X2EPJQoZp!DU*tE+Ts`~x-Xaq7yDf}u z!DLQmAnI;^>tBQ5mePhMu!snwl5z3}UcQ?pJ%$$x6)AsQ!d9JF6*rWD^nUvAWqqlz z7S$f_4HpC7Zyp>b*#LTwpP&R&emT<`eoeq9AExDsQ}Wp`VzhOm|#Ct4;tGC+NeFH&iglnU`m? z9{Ou+J+i-5k(nfXm3~z+-$&FmLb@*^r@Hc^cOLgWpuo}3ojCxA0QZrL8$8Dh zP9&h}UY2|f>YtQ1v9-v4iVMyW;fYymGNuJ0n>c~^rD+t7O!25X?V6a4U5^{J$yl=6 zEK)3WN5+1n)B|0chbtKpCSPaTssD9|ltD1V&Uk+Z<4GXL*tpa8LW}>MGEP7bSCkBQ z`FW?(o#zjE>s38rDE+t`ngo0#twPka8~dD2j$F#G&Nlc~#pny@lt6|<=G+oemx000 zmERI&i|h83IpU0_{qMTNGSX)-%aWIm4ctFagF+7lp!fE;rB!>E8R89xX@3f|Iz=mg zwf9$Z#K@x{&)UTMFK`#WE@#A|*Zy|$-mnKZbD@Cn3;K0WL`l%^OKrE`S)*6^SH8t> zh7$6Ad_4}nx`L|MH%Gr1CXT|@5xq9FIqbH^WY<$(Qshq}*6iE+0Q$kHNuS$IM*6NUXT=3=@8=$O#%aGUM_O+}< zci#eT$%!8u&MHj;-op}ZHLAHla<}0RT}yeWO;h84t(yQ1)TSN5QbANP z^6q{s?RTTEE%Q6o@ko|o&DEXSD;QCvA48IG=i)0m){T5``g_WhlvCYjG}Vc(i&0XS&@0T54ibVUkbs4CkQ z{o8L3*lx2@oNk}o-c6<3=m-{W$Eo8Ea<6$5cVEKnt;lcxjEtzLdR#7hInoBcC{<*& zn68{cRUW#_Y}j-DnNl-(InxgOeZRyj(1;X8>Rp#-E>ww+?~OD$cI^{E+jh!v)S^#0 zaC3C@4ASvFx1w5K0++aQ7wJ4(A+YxSOx80#ox1cZjOR$(%SV zOke0p1oEh|S(#`UttBG==0#zqHEqY{>WOq$k6}cM4HC=j7S1vk%3@;3iuihEt6Ju! z3U2Mnu5+-Mbz&0oF6ze05=twjBQ~TFvvqk&GeM2+#0FW}=-3(LyV4H;(+#qI{)jX8 zRm&zb77N2lA$xk9qbu*YSY?X_v0-lfX2O#j+1U9vwS&JKV35oG|5Btwl&Oljm=f??4E8%Ud2Bc z_SymlF1BOKfmuvyzd9{2o=BEc}8vVmAzxrv$-p`yt1K& zYcWamo&N7qMmr@=6;$3z63t&Cvpd~3Hxij`hGiVjP7~TM16hP}ovqk4_n6W@kaLuf ziiH((ji;Sj6QF%(ko%{YB#j5XUnCr8>!0tzCma5l@qH6kA=86ZOhKq2hoeDFUY7^@ z(3#~kU%51+=*^EfwTV0LD-W#vrk-e+g}0EAtf3c_sgYl1VNe}CnW@Fr_!<6L>buUh zZSXc`dlRQ)Zu-*;ufz8&QeuOahUcVii0sylx}%35=>G9qGjzj6{o=<)uguD+iPmR& z%XKd<2+R20ZLNH3lV!=~?SBU+)W(0P4!D_^N3PQ(ISt#oFX9v}LByah@}f#K#@mdp z*Cd|l*Ke8~%?=K&xtP7_>7Jg|gSJ`Zj!L`1!H4TLE1t(LxVEP7=(Yov15HtFx3|`c z$W!Zsms&3$b?*OqbH!G>h}HLae}|j<9@LCP5s|zxIv4CCs_6@NV&z@JU^Ueo1qB-1 zRqJ_70{f-PEYdo;n?T<&mrd{XSK`r&$6>V4POYFh7L?RYwZ}dS7fm& z`C=cZ9Gn{&&2+d9+^t?LMW)WuOnX&lMtA$SSWJ72ub$a4G=i9tdS@x>&PtwoM+y}7qPn35(_54@IAQMe&dn3EE7HZZ#;?H2lP#KT3_zw!y z;^1Ag>Ii7~(97VDCyGycs-6$ulyh&Sy6w8si23w!0lKY36^jz*LNX{B%KMVT@es|k zgysq7<@| zyURFnk*GON@Hn#CbZm6@OTyDoQUd>zY9=jLx-bqnMu_r+q4L_4iGbpw}@@O8@go0iY6#_HaZ4TnH#JE z^O*wyDbmu!%%B{7KXjA{%Rs%b`XCH9v{uc7lz*)l;=vq=8{`nqg?s-_zUU(ru+S)H zt|cU-l3;Ttt3hcFCE&5ju+fF~bGs5&zs|(9OgyWA?HdY?EB*XbmulLf7paS|hkl2? zUP6kXf%GX=>&HD%;K5A`u>MFt8GCcyD&o-@>4xPL4c{{lFe{Ed-!F-pcL0B0`UbL+ z-sdu3X@)@qA>NMYirwURA{C0|GrDTVa=aA_DGURuQCJ-6)7v67XQ%V6tTT{vDw0QO zE+yx6g(R+f3=1Tl@2Hr+?SdwJVY7Z*BUx>r&cup{BVU1hw&;2!c(NPTQ-_>3KBL)C8ns^*XD{=+1G6T+u zm*>N5Wm~1n_8JKO*1Q?`qy!7{7Qs8*F{{ADlce-Pe64=*Y7mA25SU+v!#Nbrp{PZA z8VBdtVs`9ct}{^UjAEsamG8|GP|9L1fQ?aOvc#!`{Yo`E_tK)M(M6jY6Hqc*j<*_K zcnM<{ZZfB;g8>TIjrWq**;c78r_%?d+A;~|Z>$pGA7njVD>NwlJ)IhH1nE$0{}~Av zCyN=ixsspEoG~f0q>3cY7oMKZ{=4vH7csv;iKfZ^ugp>`b1{zn#1pA-UEXAh!BfoQ zbalt?SfBJ<@gvQPX{^8@t%EH<4q&up;)RA1064vr?)BFN95Mbyw?Sj|;~ylxmMgG{ zxw2z1@J|`&H5m)?ne%+r(b<+O_~V@ndSqN&LL-^xUYoeX)--~^C5stB`UI=JMA?h) z{+=4SII1I8XLJ$Y3_99&h*i)^CT)&+h%6d!NA1Y|rNxr0T^+10!)+;R-yBaC+s%so z62tWt&I{3D}OB`cJ+W~*C#@GYgm8-=mT{0B}(4n;G|3(@!wNUCR2f05(r#yA%Tn$OkSTTZDfq;0^dR$Sm(sF#oz%1f5t3!*@;<&)D z`^wF_$>#RE$1DGAO5tf@SNVHQZoZ?j@xh(AqXf`P#l@ceydO(LaVsxV9{T9Z3~BZ$vHjX~ZEuzBqBPIDFZb(f}3 zb2-r^)A=f9Q)LXWP~)Kx{F_5Rk4P@{m)nHZ{E0AOo`lbFXs**y?$-a zfePIB`853wrA7?N?=FIL{jn$yRCx7J0C5Mk{^62_oBK9Wz%{$vdiC!`mkeSq=WbDF z8@;slM9jChW`Y?2dm6~}s=a-1;_h1Of7)f+gyPtFfGjUUc!WT{vRmD^-`X2{m^cLT z0okLE6muIxiAydPPo1m`KIEG5Mq?<*KdwyADNqv-NzgdrEsS)6h>4Re^F@&Emxq3I zT*#&n^$LEBkO{>)hM4#)Pvp=5$tV(OOyzp_Fli)*lJEj*NAKC%iUi~0^$XtCWZnq+ zdJ8_=|M{aS?2%)E^t^+)A-Hr^$`QTwL~NtIc@*;r`2bVDrlujIE6FL7s8BH%W{N4N z2w=s?ibwmDO=*AseocGl&sl6?GdGtUS$bx=*~48&2Y2I1LEC&W>%_+C;B}kK{_#l$ zoJhAw46&|1byM@=@{G^OgH69x+!<4=FmWslc?}gY1mF2vwND2ppfHAQkoSk)(`Ys9u}nuBcDefosayORN1cbJ({m*lMeDfnOX(tiPXy6D z-jS>+2Kg%<4(Xh=kT9u~s;RQ-bqZ4E3-90?kgo-z5x=?#VA95)Z-6^W@R40>crG#- z^?nrZ=CD`E_1*Er{Rq!k;5MTDOSTC$YyXyU&D>KRd|V&g%;9lW9q>qG+|EtCUBbu_ zpAtG0|6#sqi^?J-ywQ465-$yk^PSN{e(E_YkhGu&)@`nhC$wUhKUkwpa^36oN1Xd= zlK+WFOi=`TD^7FhskoQz^6ccGGR?bmZf^p&C5#@o&VV276O3PJ6X)mKT*hTP8XkDm zsnA$FhpvjN@gfi5>}A7r6B0kANi`zJ{-P(mp7%3|YIt z8GL)8Ilk~inCL>7t&54c(8rorLBX2fPVEO_z~hYXY=QhRZs0(_Dr9){j86-A7G^g@ zR%TwB_Ym*&ywFhV-R@6COMJ^ZEdcM1gKYyzO>tHqY=HFb!*$lv8?W9Y0pp*AN+uQ% zuBzhu<7j;KpN1b_;TC!}m@NPO)p!TcY4}#Xedg+BN1P^g)p0|o6DPQUSga;)QBLEI zXu?vA);oxE&>y*Z{f`NNL+=aOOUSQ2@WaDf0ASF`L|41$Pd_n!kMe%8C6d)1RF|{pV+V{R1=hC}%_`WF%7j|onbiBO0$^q<#F_&eDIuKMm8DF~E z`uht-W;Wf;@H&OHYx>Al>lfn?^|y}2wBJhssLDPHcf;YUN#?PMSxD-tj=JHZsp7tz zcnDI6#&dYh$8n2JqvK|B5AhUqyFTk|hXX_+X+i?!CC}MC`C%4*U+q4#{KXNZ;1Rhb z=bE!nKj`zR{MH=G#7-U{ZIBj-mF{MKQN2t^bx)SG&42mfCHzWBLWEp!k#Xj88oc8^ z;Vfvwwj$Q_<(mLC{7G~4VwRSx?2IA@1wJd5#Pko^#p$-?mUX)N-@2zm97S$tNcV=& z*j83nt)UTzF812wl;#?hIuAqQoQ~a_$v2JZdr$q0_!@fcPHXCA2xrKq%^_GL|5TxO zF|D{;|K)3keZu?3jgg7B!)?y14IN$2-uzvqeE>J_^3w~|n(5aEBvef=*uCJ)k7?Kt zmunXttb;47-qeFHfCGcLRSm+mL6XqDZI9ZV|A~N7>yCJ&-C1-a*K}^}s(og+Z9rA7 z_GpP8+{ED=2ufU3erN93J`0c@`&pIn`gJbeZ$X`tZ-WTHSHOOWq(B3K>+>I%H*j&< zRA_snOZnPsutyzK$sz8~s$Y-t-0jYe;x%1ey^Y&%^e$Hbajd{b|AXSU!6zohdqsMS zP8s7v;?I=paLz4+K^O{;%U!lFE-c5(M+P+qHrW7#90(cJ*8sJ%BOe5{_d`+4m$A~M z%eyURZJ2fG<~=t$z)p~&)$$h`XZ87Ft={p9NU9{vpm?A@za4EZRl#ZA8yDW_fU(?$Tz;+omZTBKG2FTPhv~HA}TO-TzoR@O>^XHRx zRafXJ>-gsmJ!)OSZygTjdIi6A5!E}JDsY;pJ3Q~dH6@556vx3^DCUKe>JBS9GjqU& zwHVGL(Y9!dhjykS)Dweta1ogd^Fs>uvuwhBvT&VUP=H#{z{NA|!EjhFj zdtZ-Xw~)Pz!gCMK?9-%ojBqH97e7}TH=U?vxb<5GjN6s}o6WBP(4&&OY65f$&-SXzpYZ1n+7 zRo<GsA};C9uTQ8;%+V5V_vZb;+4 zVDkK-f$;SMZ}~pU>%gHSoj2xCw8{Iti-)(#lh5EK7n23|@frLnWx_ldag@_ki5t!FwG)VB;QrMQ<5igS>{( zuzpLq{IkpuUD3%6#&yrNLJw^#v%cx!h%m5(4JtW!%(79kA*VK!P~xR&axKx;t0?5< zo$dQ;2(~7oP%6t<=I5b#G)9(7cMK9LG$i9M)>4hQpAwuXd5Fmi|>RBSw=W_Jd z1VvT`a^nu)Y~_cJ=hI79FFvsO=7ZkT^DYiwccmTA4s~x?u(X)%N3pARo)U<=^$hd3 zEj_d3zq>-lnWr#;n%JC3zL#1{!zI9hV3VI;!r0chU8|_x(rH0p&gsfE>9;OjI{zzA zHuW&Sj38C|C4_17w>gv3Zhw}z5Su0b3<{o-Sbg#F%&EK=-K*M8lI*xuh1-h*cevZf zYZrRNd;H0LMdt7zPgFmi`!I0viHTK*r>p!Otd6U`=BPDwVsvZE7hI^ZJ@i!h6rD8> z|C==!bk;1zyaEaVt$c`_D-SR;^AmseJ)vUq`%Ypcd9O&hN0Wrh*kN%sVv6!Q<_mVgZurR{7+HRwh7ZPH_Va{lKwX>lU-Q_UZjOB4$@bK?@6JwIztEF^SFTk zS0gIBidm4Pt?lMNcyf(z$ti7p*J1SvZX*!z>`xrJB!$j80s^*GBu_{|Au7PTg7$&yN+o9uW{`xpZ_KhOQud0?{i*r-(7eY#O`-dWBDyaQd;{4L7Ny+0K8xV9a!+pzC z%rGrb;{t18{S{-e$q1T@^3)u&0~j^T+R!R4@D-2L?+PtRU}$Z zU?{g1p$uzZJ*q5iuHo|Un|?-n{HKzLp^(~NFlhpkZi*^|D~LQl#1WkD7VS(z-@Xm3 zVh-x>Rwxarr-R@v$Nu^O-C6Mao>85U!jn%@SlP>LvbOH^u))6Tgm(MkZHl%rukmqA z3op-63?umPh=v^aLrNOVR_?NiF7c@zbQ5w7vhfqily&+Sx>#H zb{PE72MtMT?UfTuQet1}ykp4ov^$mUs^^at5if^M1e*|J@j7G0pSXRtxCgLZc9p&1 zrZs&ZoA-v{UEDrum_82H#osEg&K~N32`XC>u<^;NSGgGms>e*)-=!3lV*&2E&GG}faCiQBJ3oqL|X=HM0|vd3Yg z*JD={1&CQbMUe}}M*HCVMZ&5|Tu8&%rrih!o4w(@$>bv~deMV%9KFO=Z5I$RK~ywc zhO=BR0`nj@(R|3&8#v{P64Wnu zOz-fFS&GWu4^506X;&qph4jnv7Z(VUZ7fR8i~i`v=%+a3EaI84{#g5S0yeR_{nJ9D z3D|Kv_Kz<>n(FM`zh43jYCNZ#h~iJR9$BzcK>-)nX9)~8fmaxy|3c<6Z*8$rxCn=GrNZdV2dzXp!) za3PVBtf#e^1S8KWq6NhW^5!@I zWfuE0HRpa!$;TAzoc+s(E6!Ffs7o+ApSj2sxKsLEMPr^pxM zO_A`YLD4jS5lIB$HbSIQ5EQQOuT;bQg%?;sS+-W$wspYP|If3mR2v6fF((UWf6}w8DlfLltX!L}sEb%|9AbKSYiOE6JYKG_54_mb ztH(cfKPO{)Xn=0B=Q!b0%;Jo<@QstR*^S0*%U0^=*@v(3)SppOyFZ*IVW*9###f>c zTEU#MV{aI!!RoMr` z{fS8iq5>eIv7rpwWW5Cl*BTV(k;1Z0*HF1wlUB(aTSVsPk-!^DP6DIru zJ3o_*VZ)ay$_Y4cRj()OI0Ciq3*EW6dR@e-y;_&Lu4o~9MwuaxDc@zY%RZ=ttXCq; z-}yZMNE;&`W~FZi@_MCyw2#@-7>x}-GY}>kKSS)x6Y=KfhIk(A)i6Mh_0IP>Vn4KD zl4Fpz%Ht%(YPAWkt1lTu9V7s?Z8)GE@CB9u+1i+qo$fT{(IU(O%G~D61*Ex(8h>EP z2Fzh*s^%Zex)jQG79oYYR*@M%1*|Z;mMlASMv0d~o~WNRR)ga&Y831sq`-lSNZr3k z!JU;8%wFsx7(#z?*Nump8Te*<0H>#=yww>qSxU+U$HOUd<($H9G8ZuB8uGH8kdBNp z0J{TJfu7&Hx^%9W4!Hv8tVPSG1pY@@6TmA--2ebn830Ve;K58emCNBmY(pHVD0T;c zB{((i3ZAdTo7Oat#1We7a$XsPWwRQ`sDokl08c)%5V~5RGXyFXL|+jl33ExCV^C|EOu=Ek zObneW7+X+{y6*qr z7kIS2VJrlG2DItR=N?0lVOT4lY?3kg=ea~c(Og0xBC}1?0FO@RE*p3an^3vjf9=i0 z5Ee+LQvgV1bc+GZOxEVSQCvj&x4#Tvr~O zfOw7;V#Ee8q)^x03%DhaUe}02rup}&*pb!W=oc1oUKffDc=mlg=lUl=wy>H znFQJ7VRDaaDh#6U5T9w#vN{(MdaES$_UC-#&W&YP8N8iS#d_b)oS91IG*8T1Z~p!N zarGw9P_}RU`18zWW^6NKFl3n-gR#VrN@aOwY(rv3wzMG?+Egle)hq^MDMPkaLkOvm z_Qlw;v`wOYL3%@*q>?bdr|g0)t7q z-%FKCNyhGZs_t9byk7Vv{-8MqYID=zjwR;4s!<_n4hVt!mFgtb9B$U?P&*SlHD%=W(|E;vcEX;* z>jUAgW-Dd>hT#Ww-jZe>i6qs-5o&78qP*62s{Nw-aI6Q)5IGYpXm4uK>i%<0E3*r^ z&cOcEo*X>agdu)R^-8q-(?37mmI%CWS2h2i!NegD$0XBe(l>XntW=Fog3(UlO2;}kL^-=60-|XgGQ}9(Iis6 zQusm!oLIv#TM_BvDem`Bh@ia^P3n}eii{HS@M`i;M0!D$Nsb^RoN^Z>T^>RBSS7Zp zQdrmQay|N6-Q!cNIbNOf7>q~t_7MFC4w(g8=Wg-PotOoR9w}35ag~czWunb~nkP=@ ztIXfBYmzZl8jJ!>l$6Ac{5+VBX;BBS#mW@8hh!(F&5GTt;DDP526pEj`M&8v(tK?> z7aR34?IHO=j(3WcpKkm3k$TqX58)xo=cu>#j%Y#e%Eq$5!yYtbtNZ^ZQ8f-EIL>$e zA*0qT>$iuVt6zJ61*41FHd!{JP968c7$bg1q+%rwwh81T&j18fuatdoDh+tgdIb+2 zp@SiU&J8BVBKS!#6{7aPPq0~ej_MDQ!KpE+tT*a;2Zd9~Nn!}re#e!%09Q_Yq)RR7 z%5$~GX_d>5*}Nd-JQN18J=4wl)6Qp}ag=hS2BFG2F)@>2GQs^iV_Cf#AhOZ6Q;ZwI+}Y=v=+rCn(iyI)cpo~A_H5p2WH z?b7;8nMEH4Ev=sHM?G);ufwXhLLtr8`7n#XcF;T^2Pw3OF*-S7*Quzk^p$s6*smL3 zINweC83mp!|BI;$XTbg~7+8n@L14i#fNgu5<)j*47sS%o5@M-*Z(MG$xymjvRTAR|mRWFgm{rj6y3O~n1g^DM`Vs4@!+z_7Dyim^ z1=9*o*0JZK=&MVZ9sI|?Y~z+|tx<^XIHTem?WjL{ggX}sQit{fc*pKO4cg;%Di@)} zPQaC6Iud&|l3MWNYg@ZSf^2tHz3+VsIBR8agxoT|4PxM?h)!D?^^7BG$9fs!7V3U~ z;=Gf^NOrkd|CUe^sfW)qwlFveiX{;QU`Y&8>8_+O66exi93=fQ$+nJpD*xZKjMl%# z0c`*;m={77WmtRbrTwe1DTfCJ9RXUte9|5keusK*Kg*7AiuKGx=5@R6PQa6Gb=QN0 zxx{B2-|lTsG&s7mkE`nhVx*R$D63;;+m0BcgpM7Z{8dpM(--;n7O?}(vwlep$}T-8 z>dky2@wVfDe{tB>7A*I+3h6HOZl2!aJ|hfHqZGM^stxv?AjMImat z%UL<)wCOe0gjG}X&MfG*ZB0*q&Ph|Tv2R+B^n9Sm>Zn(Q>#Jwsj_*)HTrO9aE##_? z9M_iw7B2LG$YJ>s`56elJ;8{%|!cI8$gG&D%Ui|vviWs~_I zwO;xB@{?P<%@@x_CJm$_{M4J68`5wgv7na$SG&n1RaMsIdG*5)l`7}ZvfYsl)hAbC zmp<(P%I~E)-l0Fcc`R>*kDz0>s^y-G-bpw?S&MaXG_8j@@Psm~W2|Z3{lDe+En?HQ z?+cmL-27XtfUJAJmYU`zf37IQl!|&p;t?#Ie4X>wf!r9XfB|v!j&fiy&p4B;opdB(z%R;pya|*SI z-G0J+)iVNS?op%$t~`IgOG;CuiLEN!1++X?fwj^eQ`<<_J1h7B?(mrz@T)ww#Pm)E zhN#iObE(hgk(C$NbEkyv7mAR61G~lCQS?epp5EhhpN_KX+iTfK_x}lW?dC%eTBRGggzt?o4P{n!%KXqgFCDV=Tvt78v4`R^>?3uRPD#kQ?pXG=v+sPvyG6N zx>7?jV z&xbKceC+;3H-;$<*8-DJvN*L%!;24DRH8!C@=I)>Z6Gx!nl>MFlBB($OMzoXHl~vX zJIu~{`Z`NR&$TtpHe8tJ zT3z8oBh;?rOU|@zMwbDn*vefofzZFa8Lq5@H&3&VYiA-au`xB*tWLLL=+X7)9mr4U z7Mv1&4kex_@XwMTO?VY>^>ucP<$ z=}x%z#n9^k=51m7vNqKyo+c{`{)Tsxn5ljuJPeFY%zd=0VTZO#Mb!R@l+cw4Acb|^ zCPBaabylyo0ni?gOo*nhQ0%4$gZIow{mQArww?|D88%p0u=NmO;5%3_oL6~vJ)4k{ zWgP{9_(P!;y5^DGvt63m47_zZ_MCN8i^cVoWNgh^m9mv{_-r$L=mjnp2ksYMvI%VF zrD?4Wyxe7M>eC--UF+6BWgFL2I|NSZenSqgoJO?73%E_;INiWc@2Gf(Sv0n^o@6;e z_-341g1iMR)~i8tHi)BF2%BJr3N4!U!9;?CHZP_;ShFUQ>S+^03$Es5%9N9gMJ{S> zM2VSPT#pbP0F-1yG(v>RPt(gv|2n-jFLl?|o9mk8uRNpeRgohb{S17ba1zL9)wjic zK{BFPm6|+B1b8s2DtU!zq&G9V=*|69~>j?k!b-lhc02upCEDB1Qp`XH*I| zsa)GgWb7E$y~}dhyXnk+6XS!X4=|K_s-e(Se3(?5hF!DkRd1iBP4^hV4slZJ>B4z? z34SLSS17i5Ii1D#OPqxvG*LpCJWq#)RbEQydsLRII(=97(a5W^9@Q{+e(2z=t-}`N z++Z6{OMhm_Tmjin9Fri_nr&-vM${i2Oee2s{UZUDv&Ke^)xFrrhrEHLm6mhmlrYeS zTZgSdF#OMZWA~Mu*hVsp<>(m?t~=rhFYo`#%wZDO%#fAYvP%?2U$S*I{SALDX%V^n zK)^PvSD1$P*AtD8J^R#XnWMIaOJa7=4*h$U5!+|sab)l;C!BhaDW?D~2tVhoy8KQF zl93dbJ3_`02dms6M<2OvY-V- z**74*dI54!xRO9+*L_=kSyl5YYO$plVNr`ROyfUeEmw1AV(X2s_}u*_xm!GMcF-P$ z4)-6YqnqGdmQHw}bCzP4&r?dTJw#1zPrUd@%_sidwWpRb-Wf|C_@R9}Tu@<4Z`7|N zCI$w<2pGp|kIL^r3gjy6Lhab7v%r0gE+4s}cC5!bVeI^}THG{v4r(pWvR#x@p{X@; zac-4H*{O8FL#nQ_@+(^l6T4aE?5XYW&rf9N%8|p` zvyhzblJj?oDtQnkR7_AKp{p^H>ceu~R9U`o2dN8-9z4L!L<|Dai4Hb2w6L6j{*B18 z6%sb9lpu<#fj4xDH=E<@jjCo>k%V_*97v=Csvc@W=j=O@NYa>RD-ledeAI*ZvrHwy zP&HqzABa2-ES8!o^R@shV5jnwHC-apzz$g6Zkfisji(?Yigp; z9YXGG`n#;>Qd=0@@2ycgpr4V>zve`%N>Fvp3y;NWQQeO2m;o`x-ip{gR{;jAzc<|V zl|j=9#!RbLNdJ__PlY__EKPP!Bhe&Jm@pH<|MJf}o%~{EBX0&(LEf)a=)!0TIAq9x zyXp`8J$(m;s^Ze>bIb5q$Qay3# zqtF3SglY9CKxDVQC8zR{rM({j+m5#dWNy@s2C6)N)M%CdTC<)L`UIx!2SYgmh9%Ms zG-oG!B&HLA7ioCIlW&)+x{h2BChTfXqw@tjoj0l`spY^s&OD-1i%L~-%!I%cbO|CH zViED?-qj!F^Rgn_&EuHM4Yn-MyTEUBpDgV^OlhW3%ah2S6=;cSwzB7>ZeQo04N=Ub zVI$QME1CHogR)aqoQ-()K+Uz!%B|*0_$GRvv{9ZKJ7^6$1&3c2zzKsT+v>P#aeeK zZfGV;g_L_3sR&9)755z8oG}waR{cRD-9LFyHqQ-H|IC`> zp$j6B6VyGaHWK)VYvYqHU!`Bo^2luJqv(Yz{oRP19oNs2deIyK87VmQiY zetGKGcfQb;z<-o?@te}D(lQPe9YGWvhe$pw*tKAOW?>4~Z(I+`UR9P?Xg5GNSJFwv<35WK*rr@v{XAKDo7=^7!M z6YR5vd}pca=$ow@*3jyN?{2;~h$(1b_Y}9rFWd(SsnMmihX~T**3rJ-GU6Q8$&=9b z_{&nO5Y79uY7L95mA$3Kep_C=AKchy%S~IS#l}D7_w;F7-!N#Be%YByNbSqrVkB<( zu%f6dhQz7Y+O+3>R9#W+MZa068pk@xn%z}y?9PLS7h2e--7T_IjXA)~Jjn!c5OIQ< z*=}Oa)r$2zxTqk>%J!q{23pl~*ZEa%uZ%Hr;!19R&pr^g%XCbOtgh|$nd29;p@t`fLFJ*=?1L$BpW$(}G}$Bl#j40N|8CZOM5^F2u?tygp-uq=O$E`VM1A zeT*qfqjn^Q7VK9JoN>?!`>lx=$P4xeW*FO0`;*>ot15fUkUM=S6M9v*#FLmSp&sv> zdbaUv)K=-n=GSWB>TNt|;a3CXVApwZzBqK(i&@iA^DS=!ZjZJ7k+@Tj*X+ovcV3#x zk<~d~6GVSKU)g-Q#HmrnfS?Ap7cw4S zXV`+o@W{~|B4sRtGUGisX#0TzdI_r)+_em$5FWz}zKg zu+9phB>5r4XdY27a;wDw>N|uOF~UGIdHAy+4XIn0kwm?~XH_7+#plJ7W<;U!$$(*K+Re&66JtQjofs zjc0CqwVsw*?EdcFNV5pvz=LnkT8`%3fx)U?*BD#Tsw}y(y0f(JdCYjHY|J;cH=&w0 zdUVApTl4Sw%voK-rsI~i7x{VHD{c%kSGY<_a#pLJSt;*%tNTm{#zlJN$UI~JV8Zq2 z!ruqtWCI(rM!Yt3!#(W=4Z$xu9;~mb(GFadiM)Ysyj=Bfni3Zjt;HL23+)(i+V3d{ zKwe_44D(+8@r^kU-Q-}bnv0XO8cD{7%Mz9(iivwualMp**9L6PuyV;M(;3K`Pf2qh z*JFx8rksm*(UK_iBgF{aOz(7v%^iYcdn}HXyZEcq{Pz$ z7) z!8(gwQDlCKRvtthaT1laSIZ+s3D-9|8NviTCZ$NxlFaWd&gP9sl!#|#W8vHgROpo! zr$@3;B#~Ue_L$Y;zHe47nA;}NbsQ>mXL+TJ0h?`KA%-;?Zl{@joz)1kd0qFp?LgCf z?$KNL8VaH0nDrg z3i~q0MwwOQ$B?YM=hw##*orKlcb&8Tbmf=PsOUIr&8XF&LF8=X7qyWm4&qg(5WALD zQLIuir$`j1=g9|_iLyQPsa7;bGfX|a7S^u^FvlLWT50S%Ab={GxhZF5gxyom^PLM< zgpex3_3Ze$~GOeu^DgEC3Rd*N)246R3sIy zMt4_#SrZ#yaBzqhC2viy;;Wvyx0+Shd8|T32-&c)_h^fAOLg26n{l)K{rE{G6-U2aekN)2+qs zQ!PDQUuSD`hcdJ+gPUWb-qVZ4Kb+?W@*~uMXY-a{5Veh%K61#rd_Q-yO7&hnynKO? z_vNiFYos4`qw;2+c#modz3R?M@I4w*PX47#tg)IPB;fP1yWVo2;czu|IsNa*!3ARJ zvEt~9%F;`7SUWEbCGyYrCGey_q2V3K*pGT5}pxzi-&JAp(8QK5+oOINR_oftFT)OsG4P(ew8-g zB8O@>_!As3v_pRfY1&6nk0BW)Y<@r9uD!Gm7Zi5~WkKNX{@^9K&5AO-LNB;GtT}HD z%V63W1X*&EH?I;R6T;_gy29b3(o67vTZIO^ReS@s0r3DsY04&;dtnhy1noy`fXcH6 zR_nh$@U>S36?0yq)hm|bUN|LKmJ35q0^F>`NEFE`60t5)|5qPwhzy*k>Jjm2eYgQY zvT|}Np;~(tn_VWIHPArC3Y`Q8W~a;Xv%-DEh7;{~I8aX^WKI(@BtpW45iOP6xSRrQ z4iFYkeikC7H&g7OohHjh;K)YA2U{3Qx_aMJ!EfQhIB-cA)2uyjP!Yr+QRCpKl?$vg zPArV+V(|VY*sN;(J0iq;ou(ruPDp=(H&q>^r2$kj9`JP0kGuIvU-jO-)3F|Cwo%>K ziW0)dMHV6wF%($(bwsTiOi{QOD*==}HYGI{1pJjYE&JDf&7PQ~EBlFTf?jDW9*Y~> ziF_QpY|#Ac#MnfTt-Q=4n^+mdH8Ttx ze0>`*0-O*#lR*BNum7q~-Hg)D?t&2d8Zg{2o+VtvMtv3(U+MZV*br;_R_fJ<1&E%i zD&GDt&2PC_+3~G1VzyhB6G6*u|ErL{L_?|>e^7{L-~b{VYN$zpVxE`aRBu%ucyJKF zj5<8EjsKfjINufpW7NzCV1!q|h{J{>dgRHm4Gh&TPIw` zAQAwP6jUmdp+FHm76ehRv2||lY^c_P%nt{52{{V5o~=-YNvRo@5gf~B38zB;kc{Jl08fd1usLzm2K}&SMq518BXwca)}o z3CPsY06_+!t>?ynE!Kit>T<_N?(Ff z-<5ZGSY-(thwbfhz)bMBM!0waLOmb|1nzVZ&_-4yi8IMTlZ+zlv8uw6IjHhrZXWO7 zEfzzoi3|Q#8xIxui>TWQys&&?o4gS~%T};1H{anFs;=qKbn>XdyMb(~s)cLls>YQF%HmMB#Kt zoRvDk*tW9l8SJq}{MR}7N>v) zHCpQ3bvi&s@y>c1__taAUwP1WvEli%PoMVgUH1RV-o2kbKYzJ$>4!am3IIt3PzMpN z2mn1mfPP}xfCigt0P?tWb%V?>1hAie7-AF(6e!;*)O%xoNxwTqgnS63=U(L(=PqqRCtQJhx%ya?)@D)@VfF-^1Dpd)l z;f#BVKnn$ZZ;-xe?x2%6BN~8xu}JWaroFprUdw@bw-lT19RxjEATn?wkqw{D z;4%z=hybHoL#wEOf){`EFV@;;6b-B-9D&*p(!?^0mg}$N07WFm|8`$n=E}?FneZV3 zLk27)|A2D=%sE*hs~+s8+;PY?W&!~9I^K(i-S?r|6ewB?jR~bKKZGv&Ji9Dk>)XL< z0|cud?HZ@$!7<}ZPQW3|c{rY>vOn=b(1Jok7NK#o6OUUncC|B4-9CC-#w+JaV6zRDvrQ-^&A6jEy zM0)T*TMy#DOA!!WVj9SW;CY|}3(3m%kZ?zg7>zy@{QM{C=vXX)OdH0_sy5DCv{0IR z#Uc+mf2Z*MoWtYrh3xX0u+nvaFv{-SDv!R1rKR&FqCWGWa@|y%-|wXSCCHk6MU?Ae z8YZk*H4|K;lo420X2};0c^jcZ`c<|R0yVy>qeDA-fl5_Kph1JS?%xJTBQLS2XUE!Z zW^NU&SbCdOAn)=}lX1GBPzUfJOQchc= z#N4MI`1u3*jEQltO4!L0DYVSj$w5sqa5yTCB_P?zm7 zLpE?sd70_zXQ0$6Q;*eP7RDOD z3+i#tzMBWlr->)-c@CHo4gBtel2}Ax3S->?7~mb$MEq2TWUdGq9l`P-WR-C7dC_DI z%sKQ~bdNce>bby69SIXG_vSAMZ(f3LbDy&d$5#7cSE)XdqS3VVisU9NQB|J5 zhq~%V^W@H55WC@CioDu8YP~8rh=UCav)n!=^)OvjBWq=C6X<81%I3y|NT1P zfbSH5Rg7a1K!6sOLcqxKU^dNn!&t-1O^Yt%J}x1fF*HV#x=6PUNY#_smqSyUr#o?T zWm=$W7I|WU@-{NsHaYjZM$|pojX}AB*)x>0vrlHBJwBhWeH)c{^doz3qMpC;iYdi1 z8-Jtov~Ane>Dsb!$D~w4GjeZSbLRW}64#p^_Np;D$wjNM^ZlxEW`|RFusz&F)pxoh zi)UBd9}v5khMu`a+Ox^d!Rq@ZjirXJ#2+cQIN95$US*yiH}xm^Fkm=9ksm{SYJzK6=3Dp0;hDSodjk%RS6j()b(s}{hY(+In6 zc8rD=4{ah#5QS+u66vD>ZPbC!ckEjNC;RqQytCj0143x*H?w}?t4C`KB!mrkL_ zft7MuUuRa#?yP+))V&Tk)%o02D*cFDdh?@D^E-x5Pf4=9fZLOYytC(LP-<5ZPxQXH z?tRtUr77^F`QQo^sdt#!@*qpcui5<@9FwZ;*92(3do&2h6C4QYN-t~A{?4_;p{LAG zKXn7gF4&gpVYXNpE^($ z;_$Zc5KbXSpSAUdkishkgenOyCQ&4e!)*U0*nAve>@M`=*!$aPu`PKJ@08rBEPW*;} z^tj=4e82O2LvU+JAw#ys;;?T3c`e95A-rn6OxCRlzeWZS&YZk3npdFD{R^t^Ww`JS zWQ(*kBUu{jp9`hRQafKiZ>>g8;X84}hvwLtd+)Z2HC1zGYsqz2ln#<+J4(nA#&C^@qmjg5I)ka}2L!w9`utAQ$xudUbN5Yx99wd$gcqR`gP zEkmTtGVW9b%};8Q85JMukkRa}9eb#G$LKQ(YRR~kW?a3~wv^+Nm_;Xbd=3K0aZKb` z3?b9EKvJ(d9Yq*_*IsvMoY7q!Yr|+0 z&5i9TKd$SL=y-;ZigV5iEBN$&U@XG8c#Qd1uHmv!L~!8d&=aW=REXvF@Je#WF=<(T z*WG=FTK1au@OhHr_B0^T{6om?lkl3<0nm@2VW5zz!?csFt*QY%8=E5QL*53S7qrh< zdJUgAk{|8wo9STw@b7Pbcx9%F)KJO|cz$1sBMbd+q}XApIW2|{_GdaMt_Rf>T)l}goR`I0TFllgIH3`YU7qm2m)rjHI!*!WfLEpfF*zgc@U-9$f;+Wd&?%Tqslf zv_Yj(OaOr0LsBIYkTVTYVvc8~W&6xFOHGT@z7+-W3nBr)1E`l!AQZ2FO5+^ecyX<} zmB*cqY+Mi(K$t)}Sg-e)x)vUIKK{&Ee`Qhgl@D6$XaF+59S8e65s{9k@$W~}QqudslP?1%qZ2}oE*u*h{I!Himkz`iX+i|Y4w=6@xmG0a*qef!1CT36TmTo*QWHWGojmNfuYsERHM@gM4&{xWW#qOh{;p) zHJg3-+mOeRc$4*fN(WR`_woyRflx1zHeD@cO_IO*{314a{)cOsyxzZVT@z}Q9 zhO64o&cC11ufBg~hx`5+kDvPiH6fY`ssKsq92S5iKs1726b*=cXe4bb(~qh?VS>oy zf*sOZD=|&?$+d!1vp4Sb%!)JLaWOYjhHciT8^mCAC-&yqo!;iiuzLF#oq9;H?kfdP z`8>OVh*P)vv`?00^ZSqbnXwY`?%pqT7^5HV5%pxkO4CV0IhP$!I#(D=(btbFk0rRS zog=CSepdiIAJl7uc|Y_lvIt(Z#ZJ5H?8y%F8*G=hj}QqdUO_!+e@RHi&zthk)(t`P znkU>lPV8WkQa$6=4bAx$WmcMe3!sk2=Qe)VueqkQH#bAT9KUE@Sn8d)S>Yvf#QSx$Mf|GS!23uZ^@D ze!rf5fEpS{TsS8`+5bUD?9d++{~|8Q--A6aWP<%pG>z~2VB34C_s{B^(00i zBG!CwlXj(Hr-2OHg|eGJHVfQk_Ct+M{g7B38JuQ?)Sv;+Sq+BJNmNjMJv;97%v10M z-&f&vbX1MxFeWb#IiOM<8FV&94woFEZ(4Kr=x#gDd)JETov^|Zl>w*(MGc$AIY;%= zqn5Fb$*?Y(?&!0imul8`c-c_}@l11*s|&TivU5Hn9$c_jO*(HzFL(?wulQ9ImV5cZ(+;A(U8S+Q2zqm}P#$+1PhJvz!pc zUWxHskE$sbPF$YD5{f@m5rqTyUYM+n@ph>9;$K*r(75DJK%xb;Y?e;mE^#$jFGFUuqekrVm(X+1TM zb%Ul0U=GuT&lXPP;ro_NWi;m?nqgNA(S%85ZvJyvy|5s6KNYvlbT|!M8vbove@XN@ zK^9)M@z~FepoYkXi%MjwHHCgc zn)(-Vamo9e`qY|!qfHMg5=yp8Nabc6V|npoC%;?BwM&LZd6(SrT?11}z^on7EZ_GB zZ7)0XiSt}*+PMX5d6LJ?vv|~Vh-!95_1hI@ zIvW1f^mFv{^U`ku~1pojk2q7>U1S$uxmjIC($bn5*2Dl%9 zq;Q&9GVm1)s8D_TPuj;Jh21KOZYtZ%HmkRsl}ivBf`++`&Aq3Rl$#fh8GL z>Ib??rFl{4pRtO@#a~rlt^x@d1Vc4(a^o?&kcKwOXn*)wd&8~6FZLi#?y-vy0yu&~ z?L9KVDv*)|2&?o_nPb&vlR2&ex~zxhO?V0i=_qYR_kD|{3U1h2FB;RGL~lJ-2%r!m zfDi>^Y&C3QB)-`n2@ zPvj=cyB|Khd-rYsG;(CxK~Jitz>hBpvA!ISd02Zlz$dY`sd+P6zbz!Wf>> zo6O)ow`xGQJe?x9@fuvd-pStT^!`M;;F9L&@Yx>Z%mCQX2DfLk<;P#YzJHsdHcQcP zB3BNi(~ifRO|pZ;X;`1%E`cPnErZD`fyegh@}+G(g%2J7|y%( zR61Le5}k7J1UbREc$W3FkMvx9bH{SI$EK@iCY@VyOGIW)P+8iD4%vKeE+ONK$XCV= z%(oNSo^)HWS6!!)JUep-s9^eM0B1%k$zSK>dYk>Ne*ICXdn_ZnF2LY)2KMBW5|%U? z@m$Y{ge9BAju^2MGFT&n=VAy)9H)(Fdv7m~)aGe>Gua1)>x4fgi_73R4qi-(aXe`#c|&k@u;^ML^eefsK7B7D7c=FhGFzudiX6-Hd!pWXG>n*o3@WS_bM zU5%wsA{E*L3T=g$hF08!Ow&;uGrpCKaF-E`S+5$Q%<(dS@e32$e{xJopvg|bLDJ%Z z9YKOW6(mIxMyZ0*SB}rSzwbLKL^yv0x%fn!Yjos6XCW>RO!5s#0JzMo1IMll!3YSu zUiF6)4&XONY2Bhl0C~4tGZs!OfsIjU?OC<40>J8WRCa>U>4KMj0uTR-H#9Xr?}T24 zNkm}ma`*GZlkV>rrd*rTRy>c*7YnqM^NnQ~=_wBi z>$3EJ!t}q7#cH`30T}^OANESLo>l??JHgjrs1$&KfY~p{9RVH|6@$}72(?jIN4c|e z<9KAdfaPL=&9s~z*#L*A&qTtE)@T-^WO1}R1=$F`*G+>db zQ*`)Myxg;Juo;L&&mMgB3@lq&EVV@gZ>k6Q1op&IibwqL5>R)!Il%nxJGgf!hpNB! z?mH}&_{r_iwdo_SwH!b6wYUKB$d-?=h#`-M7$q4d&NMm`^)et13V zMp`PWFVPIzw5Siz0F%Ll*P#4&fgx7=IOHs~O>Lq%MB8TMLo~ z37MTBUlbE;stf5JpJxhr0I4Tv2zhKG45nFW_h7?a2*5EfR^yQ#Ft|g{gwoO5lZ~Hp zamlHP^^K1#bh`41di{*5p0>es3Xxu&X=Rjt2}%E`?!XG?2CJ8GsRg1e(K@QT;pq_p zn_Bo){C3~x6kfD;JA%}QI3SrT@f642arg!&&Avu3)%|O{Y7K_>I3QZj1*(Qj|IS0; z8NCoQt$CEe2Tk7h*6ltX#GP)Mb(H;NPiGUhA}6kxgX3!oa{vsuprw1l9NcAA$1o+3 znq-N+9CH#wpRVJEy5vFDI<9$A^A0ypU!S16M#m_(XQiPIda5T9AVmRGECK`(D1vli zq9Y3e5Tq_Gc9#=kdv-+N*4BE9T*W8DwC)=uNolfy%kiHS$K2{ijCcQrihHd*EL(eW zp{s6ogyT2EmuRJ$u^t$i)76x!a-TfH@|gz!*6m5zV&ZrH`e7k|HIFELhC1zO;Q#y; z2i@VJ<;BNNoGA-FxFV1M=R@%s@DXlW@=NurbT$1Z_3NLkL^c7N_I6F*9ovR{aJyr~ zt1q%0t7_8f^C^)f6&_4Eob2-EKj#Mq)`pshkHBMq!t>{Q=HpCwDb^cNX{b}I`sXne z`IXFyqH1s9)OCWf4qLR-q45w)7U|2;pq^GVloi~KC_#qhIzRzXa86I#S)V@K&LNj0 zqJz|Bxt-F4N5&NEKu?^WdZDMOIJuC3VwgpBU-K=x$CK3>wV);2op$;eirVte2o{OA zdOPHHVOl*!NBwXb#tauIUr0NRV1(u8P9oZwaLx+|DVeBgP}`RAxgRduRc9qiQ_ z3i50Tj5KoK5X3C+dS7)s!*|7j;FV`o-!SGDu%f7?Ym@g7C|w!U&pWwGu6#&m^pVN;W)Nbll(Az zh8?_T$Xi(BY}I3NMYTt4qb5O{ERz*vyOi!lP0K5E zQS&&d#>#g)VQUh~xr&Vrwq{oXbDH+5?lYF~R=vk{+^qA2=Og??THuRn8Q=5V(I4%I zBXu3O=yc-cU#Tfx!S2#UhJH?LFR7-s*SYWs zFh&wlBTC@SU)xZTUwgW6VU7*ERV*Tc^t@!XmFo`*^oK?h8$;yq_XyYX)>G;~5sHV( z_lGHbHWf*nD^|lG`z_#0nXY%hZ^7Y@=xc@{q>LHlb5qr~(1d6CXe+7ohvh>lq*F_6 zp1Su}@W)9$!l}#h+_SWbGdzy7DM26p{9yR=pm%1WH~os zC^(!=YuLF5b!;9K#nO0)Q+kLC5)iIGaAU^g=I)`S5`P8+;2n}84^aI@g%2wjO(!R+ zY#KIRitx+m`rMV(f4GnpIeehns&HY+E$oHHK+z1TY=464op`gJQe5MT=h;?FXJvU#T4Mu@oi2c zXs#Tm12IGyy!Yz*6Y!g^V1ih(e-dH4M?VWpwyvVBPhA6P9%RFnxHK ztvgFNmXxwd*uH8jaHt27YKhE$+~p$}ooT-NbYfr4n={ELn?9d`067Xm?#0@QiD-_4 zRH@-E+Yb@q@lovWYA{Y#6PaUc`cS&v( zjX{P0WgwXBA^6|8{`WCrcE=W21axlq%a))h_=>l&S7{cawU_Z*B8`wL3$e6X8~A*I z|3%Y9^UqJ;1FbRi3-_=3F;Q$R1%Pm&h(US|VM_h42|l=sI7E|QT?3dul$!`A zHAPfedDj0mzUu)L62fYU{FOX2hZT5D4n*~4=Iqw%xcDlvel%{ST5=ZsKCpf3RJKg(i?{eXFu9nCc@4$bYb|m_MmwN@1c3hngO#fd zu}7!2LGw*>dD>nBHc!9)AIjc4s);S?8=jf;5Fmj70Vzoc7@7pcf+9>p3q=T3M3hie zz;Xdmfs2xa&_M%&A{GMDM7^S-Vh=?HDiI2B`+_0XqXHdTC3-mmpNLQfKhTH24O12nMw!YoD;o0d?heXgpn-k`mbtKq~aT4Dln3XPhRp`0n;X{MjS{yP=&uEEAJgHPZd++Cj*wI&Gs1PI1 z^U`I~)>SI;k?{qN@_uo2dV!i-R_n3WPchMy-zDsx|IKQ6MDM$i_3bkN&IYX@ZOqN7 zKPSUoFgKj+RBh(PnZQ}OB{_yKv3`xwHGs7!pM-8)y}cs4bKSR8PHR3a(4)LptQBc* z6?W}wBybc%M^$>>zhZ~Dw{6X_D>@OgCn`gD^)~R4W<5NRg5S$aTg1Z*01|74gG*Y@ zb~8k!W>#%_ap~2Zn)2kggfALR_nLnkta`M2<*~=$6FNcx4WbBRY-hA}J7_#7c7gAm z&!|(*OZ(Zn)7vso0%eW43&`-D^qP4S(3BqE3xN^W(O;X^@$h1XXUiWcENteLefAU0H-(^obHD<&XLF z`D24Sv70t+#sG386NfORle4A_=aH4=dL{h#!@y6B1KYJPRUc5ciXu=-d$1p~@M)k8 zm~JT*t$EvD04D3P2&$++7mn^@=lSLu&oUWnu5qREbJm6fy|I{uc-Px(W|idQ*UX5S zGJJak?&DJ)J$-&D;Hy-hTam`HX_=8P9I!MwAjSD$65|fLFrs=zVdo+90{j4QCP$4K zs5+>~{lX8GEO1Cx_0YSKnEeMGM`(F}urV;zmsG>kwX-3-fD@Q76F z?U}(f>sRj!5u9_5!4Z1u7dvNFYuheCmPa4HFG}@Q&ecoGn7*M^Uj%=zt!u8locJ|I z?e%#%VOgm68Nfj=R$)~ju$7dk6!XN1c1(q!l>VMA;P5TB0iRh$ZChjLcqeft7%y+`~ zNpq3ppbG#;iBd3Wwv;Z13ig=D1lfX@fbT8XQ8a`TCaO7; z+rwUMQ|69-`T6Inc_NX~`@9;Wm1bag@- zf+=Tf)#-m{bgWtLu)pN6T}?YFuc!9Rfya+3NmnP@S%I-337L8}>A&y!f11J!U}1qg zfNTW{D0E9j|5hRx(}Bwd#4@Jff`xGa`Pw>(zQz_2l3zg5kbojmK?Ux0KY=}M*e??}A8+GMyg59Hq_-`4H?rAYu)J@sQmc!1kbLp^2_7; ztpQKohIwlgO0K4lNeDlG-fE8Q4y^I zleAsvTylo4!1!p+Q>gzkFPVD8*s|h_xs4MttkW__7p&;`iI=P}Sf=SzcAVP6b{$nx z4e(i|$M01t;u7}8#{L>0l&n+&{!5^YbzjF^P1NT*4{V4@g6w;KK$qje36ouF_How$ z(gQ6cPU${V7Sl-C*KhU}+}cVQ8g))zy}_&5p^E(MnPijb7aN22qDK@TR~|Jq-Xruo zB~|shDbe2NZv2t>*No}mgm*Lq+@G8w%Kni+)L89bjZY6c@Dw&XZ?I?6NwuRD8{L9_ zOgX$ioH3cY>eAQwec!EpV5o&}YU_+bhaA($;vx9t-tzNV`uqDs@8T=B@8MWnkG?}B z`gC2iN>_#mb5j-~cdgiBu>JKnVXW$0?EWbq>YHs@FLLgeMSoo4z~+QpyYyA{Du=f{ zL2&15rOWC(-E9uNq7^-dDF%I0wB4IEhpaYon+kqSFN{g6T5@-BOX`98Z%@~f-22x~ zRrzkh5F0}^G>6vFnqwZQ-)PO9D`x4s%pb^RR$IFp%?nhYh=0C0^WJ19w(ZdE{N=TG z)HKgFsk8^~lk9u)y7N&l4HJIwQE{Vdnbr}K1WGyC)n87#yDMyV51s9hb!MC)zfT5) zTJrvg#Tw`wmNi@-EDhU6ksX75xsr^LEKF{>0o_t|hFpZsRMFX;39MeOiXwbMM=6#HQ)rht*(iO>7(t+E=Rk?Nx5Mn-j5&BeD zLVpodfD(rykR5g?JD^q+EcyzV$+fXf(7CA~PfoJR#{OtEbDTVtl*J`E+|-%3aE)o_ z7xAQWAPLvFRb*0_(SbNVlez>8+jbY_)LHdv1|j{^9a|tLtJq2=$wQL=bP{IQ6bUdWpUV~XePZy zC5Ee#ijL`}xR};lbd#IrY{W|C`$qVSBnG!l@Ynl41kq0K=m@n*p?LkA4_^?7WO}*g zU}IJGG0`KrbX|uN>Ush$xJWYo^-Ltt^9?7QrwX>Z@6uM11p zZ}*G+xJuXB!R5|^=VW8jCJj3X`wcq$5cHw9@4X>^^oNOaN^uYzCJ)2k6Q+Iui{ zZ>?afUfIlI^SkZCSd-}9oD~T*17?R&%GpCvjeXbAK9ZfoSqmKs$=!2LQTMJr#@QCU zx^u=fJ}f3Jw^-a6X(!(%c@tV6zS`DpYxO98=Q*2AjDtWtbu~($q6M?d(Q=1UVSmD+ z7Px0^1|aX;aiWvq>>Mpv1u}07s2-J*kco<^_->}a-a;RqRHcp&5Ki*2a^4+DR6(r< zgMR?j&00h?Pbr(EHEuT*b?Wg(v_iV$5vCnI9^3YWAS7jcAy4XWg$^c}vQ4w&mN#Sw zlFxa8^&??cI3hb`Y%>X(YQA4;$?L+ z-<9Jdes$eH!%c51027gZV}!GdDdwoi()_-*Q5#*}^R3`<2~_i^yMnB8uG3mdrJt2e zL3-&elricH$%+DrN7A1J2k}Ma$?7Z{RLAY}PMnLVL(`naL84>Qm0D^;vi)m1L>Dyg z^;P+gWXPKPDmH6MKdzU$h>lX$pvHJoGQ9ct^^xKejz&1bi?j+&a} zuG?0VGf?T0IhOPIo}7p|X@H3@*f93L#R~dIt`N~%G)V=+Falmv%+IAo8{phE`w4kSFyLUc+UQ^>T*09fX z6nK|^RyVoL*${=eAf?FS9BC@ZO!^wS1M~yx7|m>1Oe5FMum851|wRkD0{ZZFZgV(D@z5X8z7gLDf0ZI%jJ3ZgQb-?S`5CF_|mJbPil|Bq$3ND zl(*rP6`!^|_+#sbf!E(@tayC5Q^KpqZ_^1RTk3Za0Jw`-LftVskby3Rm%CLm76Lw1 zlK2A2^nivfsP2#}BuxjTk;40?p)zRg8|)P3U?{CpX88|FcZ%q%zz_L6cB{hS(?^Pu zV2=&k982K`DYWZejq>)ytEaCl>GWaTykE`dij!o9?MFB6sPMp?Gb+1g^C;xwx|7-! z+U>Jbd!rtL^swbOL>kV@mOrU{6bNT4yShCgvD(vg&BRTkJerC5n$tCZFk>YZ$c$%j z`Yq*0!}~GA_d84hU`P{E$YiiKRX|gXrLV_R>Wc~ORvvs1%)ZG(fJT%ej%s2d2CV#0sd{B1R| zTZ}L8{m|(s%UIt1F)WO{$$GMqYqFe9FOb09z!yg-eTJ8qzbpAPaO(}Fzgv*MV35@D zB7tV4T*oP%8$T*@j5HOz!S9)IvR?o-pdMNNV@>T|j{^lXZ^N5zJI=xDqMn`V)OK?! z%uMUG{1{=p?Td|u?ezr2;RMY2m|mzCC%-CMA|fIM8W13YVOT;g-2DCh`#PUvD}(?D z;vJnkrVV}1(37rm9*M5fcUdok*8?IENhQa(JG6^Jw+Q4Mfy{#?iXtRe>4ONuRg#^& zyt9AGka9r!?LbGGgjTS>f#@7k_N45w^{4pM2D=2*Rfh;Qt3FN-7F}OGc*-?BfOOV7bsTPs;_^X{uUA%9c7`KpjmQQX{Ku$7e_Y zRdMq54ao>xUQbSplQvU@@9Z~7>0#6ZU&z!^Xi{2hz%g^xe$9gwT`sdFqP+)OiC@jEZHlI-rv4qXMj1 z+_oGsN=N@QN(f#nKt)|bz-6j9af9j|Q&1 zSDOW*Gv{Thnpgg6N!(&Bq(`uKE9WCcWO`{px>9+MjjW?sS1!rJ=WgkQ&#UY@I9@h! z_~Byug`*$)jX$rvw0rB{FWy|Zyhj9}8!>o8F&Ph}f&dLn#si@m8DmLkaY)R91FDBr z>oZShy+^y9&c^2|tC!Txdn3tr3uPK7^B(A%zS~a*BNsgXu7D()Zaq+_&}Nmr3LA?z zBz?Q|>a;3=CA>Z6CrZdrmO7ru0vc<)?%j9+2;t0O7g0*ax%u7S9gwP+bN1f@K@uO)w^DS-nc2+!=8yd{99K*n z^ogoOvPy)6yCc{Z1nfwT24_X#LgLw7N8HQUu345J2?%^z?1 zCz?+*R{qoGB6E)CpRP=0sF0mmA8+V4H`e&+jjF+=QXH|)k2k7RUgW7arYqS8#kl!8 zesA2O-H-7|8uLe)$LgvEg@5+U`9o_fKE14mfulUt4lZOZa~&d6d06~)W`>(v{r?1% zZgu965h5pVQ%wRHF;o=id(b1Y?f37RxrGe|cb=-6>S^-&FVa0F#VQy!N^*j#L0h2h zU@lQ4OYrW#-y?6+0kU;e*{b?1{_1^Qky8s-M;m{R_xdF4&3iC$w>>%2eUH^n#vk87 z6WT#(_9kQb*Z(n6Pefo=WQnTCesPy7iR-)W_LZVi#rx~InK3&YHD&oq&CCFN@NVlq zxa}VNU(7}ou}yhMIoBG*c}lBL_Ti>QsfumlORA0Avie>veR%2JhuyP}W*&V#_UeD1 z!)xwB007&8rbnV<(1;E4W?PvI0{-PJ++)@z1QRBbZeIbQu02k|@7ia{hghru8< zEx(5yNkkz7sGo8w2Flgk}Y6I4PCkWb&FouDbh>AJb!~^jOtl zEdm=}btnuGe_9ssZv^c(ZR2lxt>2@9mT>7Z7yz8;A~XP#(GY}Z7;f+fp#CE6cG*OZ z9yNdtB6$zWE}RNeKT>erkyP_5dz`0Qf)4uW5Jm zht7uwj=0ki`Az$XeEz@kd!CATusIwMFebKwSR8R9BVXHEIW}K-?w11qYAU_N<17N! z)fQ&eMkxWU3fzOF%|O*)De3pg|Nlfb@mpj_j5E(H@F9RRf$B@m%>X3EH#7bN=*xiA zXHL8Seac5OU{_?}J@5ZZQPBl-&2Dp-Vlw=1p<0^b^23XgVm+oaOX}KPQtG+L&XW3n zJ4@<_jOKxKwFD-2}OB!X4If5_+uy&gzOFw&wC_ z1V7N&m{a0&P5SLHd7$&}&;Kch{{5krdmwQ4K?w3u5NJh8-TVX~ECf~|e{b5fJEyGe-dzmx zFaNctC>X2&a9h`&n-}Utc^^DYV6YLUHrDZi>Rk|_`>f;B`yxZj?E7mr(ZN=J^0bve zf0M_nsJgErp~Oh}D1r=h7B(+3hlv3v{`i8o_@rhP3gW30Hrq2ugI-!};{e33)lkTMKJR+4_Vd^#y zU#2ILCU;jT%{eWWuCYiJnep>auQWWUCFhLC#}*SUY!oJ16OT{5s2?AUF=f_GzG`TuA?7l)x0UKBhSh674=?BRQqMrZI6%kWb z1r@kPIrU=8e(gP8zk^Jz3!lD{QBK+!E%eO^XaQ}VMV4&kF35H1&iO1#VUjg4G9`DDoEj{@y|S4<3hAYx$jMnk8G z&MhbN-Wr%Va==%d$@ARy;(E1{<|w;^@@)hVik7J?bkI?63At_|H@I5@BDL^piLbgR zs?P4)yI(naRaCPhijL0vW98RAwX5cP3!qG+$$O*oiJE9{w)w~86FXJ$ zJ~X;|DxGAUH8x+l|fxCPr*>;Kw1FcGQ~*}`l)q7|9{{f&Wcea(#F-&<`< zl5T1p*`XqY3Il2MBjIDP2G8loJ>0UDmZ}%t^?%P3!9`y$)!c{nuVWv)Sb-`%dWCH= zp1Lx7MU`WdlUaTd%CzsF4KL2E;}=aN-g{Hq^Y+vZ-fo0{``SBgX%x48NAQ=ea98ee zudfN3Q?*$>!(a9`b44_ArGRY8{~NG+L4>?4okvp)Gl-u%?$93cy1u&L*By3i`f#Oh^Wc-FvxBSWN{hVW0?rRc1eFKR z*|mfmxD{|ITBN^>4*Hf2bMscdSls?$d0tLyO7!K%4#QZ|vz8og^2^MgMRrQ%=_GyP z(y$->a>tHm6dE*;9)!R*5pxf6!Zu-hBX$1Y7-SShO8nC2XfDVJp)}twkJ_n{Y6LViKSwUB*Suk*gNq4u ze@?!k?9J6bMd_^Hx$(%NbwO(GwkzHVSWUZ%<{h$o{_*`|=Fb{}r-4qn|M`~qzn?fw zIw*ZDy^r{7)9-*6LOzo?2a$bdlyj#ty}m%%e>wT?24jti4z}pN|*R5K(;5QQ)dhAUGLu3%hP~>klN&c8472oP^C-ZFM6$tg_2`@e=%q zmzrE;vPk0R)@2`qDJE%}CdV}At%g20qqTAU%r3STKj!b)H|g#}QSp+^%Gs=Pt%9sWMT5zU1Gc)Un2Ac> z4aiv9nl2JK|HqDy**|O{ zbmp8~nbGqq^{(O?@9c5tW3@+3n?0d=NuP~B?1Gy#>wcUGy7hh@1|5x~u?P?3#Awf)mi4mfO(5Rt`u z+rf5RE90W)e7dp+YOL^a{fX}MhNk_NzX}Nc=%?Z2%PtdDMS&(S16y*?nfcYt+_uw>y~FC8&Kfqur`UsiPZ#cVDCF*1$4F)yC}GQ|BitDB`7-k=m?g4xqrdyK)yii3IVgJ@t3sg%;$4CDJ+{X-xi8 z2PQuM{wp>oo2H*!!j56NFjn{bTks<()wC+4#?<8a2ACr??m+eW@ijp^2H7|6369~C zwUN#%BZq*bL?KTDMyJZ{mZ-u4ZR-f0j9y}pNjsyWok1*26GRp5J4O4`#e#I_+=+$j zxs?o`(C|f-r~N#eD$O$vbDVX@kdSfx@gATF@#}dT<@V|mcV9m|s<|G&z~oG` z)-)e7JdxVte6yFW!*u%moxFq-5RW_W1Jzb-`am@%QwT2hmcr60g4a_?{h`GnQOYqR zWrJK;ko`2P`~6uIy))yLeq^lXXD=+t##K%qzs zyrI^>X*y&UfLcx0qrm|kJum5(ZdAK$@IVMLfO68VomG;y9D!}M|40hgq<+U$0+$EY z3fhB>%W4}l@^Tzv6d9uCKm=)8w6CEfKX~Vop&zQt6PGaF)@V#fK56}R!Slkyim9rd zt$v?s{qEdN6N>LWOs;w!(0R43yUIdG`AvDDAmi(SW2ayKp;;0aQ+}0}DsA60* z&tU$u+cp|N7J>hzS^ZuL9z%FSb^^fSyFJ{HwVozfEd{$>cp_nWi=O;wsK{qAe{^h0 z?{JkRho>NxO&<|e(r*vt zk})5%ThT6`vpxo_<-_TD6}i)0SYV_U%M7ss>Zs zFywzR-)9BxhdKF~{fZM{P|_`>(s190M#96hxc=)J0tLf!9b>_+$o3DmPT~8+xC{9Q zm=bdF;0Fu)>wWHrN^lt~dNJM_NkR!FoB3%d^4JhHu4&k7zvaz)Xb9yZGWRYq(DSO% z3%>eE?{)Ka*If6oYfRX|p?J+;$Itg0)9qNdomly&gDW|7<}*!2%=^rxkw&P5ta}PU zGlFu;Al7!~dIe-g4*r-(|Mvmr`B#Ut`}xdR58KG)g~C;;DHV(I7%0J*s$U^wk6Cf_ zyAQvl@17W!lOX_51nbX(lQua?R683BKF>~V$@(<$kZ}hZRg{QVDYT-i2;JX3GEMAz zNoAsE0q-W;Ql>dor&R^vjw5hb#V&^q(rR#OH~w%UpnqK7YY?Qto|x3SX6PT~7@i-o zbH{LwzS|-f3p<$EMiazBL@vv(RUdPTp(OWcdwnkH5}triobD@cI9a5 zF8|&+h(?J?)3=D#%W^L{vx0U;KhkD6bR_t!$G>;@Z#R!dd#hc?(}_?u9_-SmEd#nn zC}b;qK0QFnxZRW_jV<(`bcFd7DxU6P#UbjL(GG~r$T=f^+9Ke%8QuW{C@Vh5LNQo~%#hj0r z6vvnFGdEsMCdfR&pnyn6x_^mS!!8&?$1v56VJ*4BL{CNF9uwOVN2Ab|YPovQmzqOLe{S^bsKV6D#a*d1ox);d zDaG2&hHV#bveX16r?kQ^|B%I-*CzZE(GEqhdUCnd6|h5)mk=-D$5s|axVYVk>4da9 zjdb~FJ2f2dC%u>aIbyFw9%*nVkPru;FYcAh17b3D1!#pkT}+5pW;XGDjn0Eu)~sr? zDkoq+!1};A?d@l#*zfL8R56UEx$(}hcn*J^Gm7-XYACyUTx^`FZi#j=JqA0KAHKHo zMDBT%y^HR*pz&1h4bf|Pkz`??^5sb^W~pE6#F!pC{Nz;>y2c{M;^599O5&n|VEuv} zNoB`CNPEa2G??ScHDBRyRol-M=9H=jHqT`oilNpPt+CsD<7jUgFM<^gH{c zVOwVU_=(J-c~230H}0M+gIbNv!%HKK&5^D0|5uyEtFl(ewj+tq;C9ubZG>KUYc~JE z@%N~1e;a8_U)8fWtK08g>$LYgfA6HvSZMX2wFrtQ{QPmd<0>9AqE2Dqi`3lcp%SA1 z{fN+9cT0wSP!n0s&J*)S;wkcMkVp&y8()x1DEaUC;Ec=`%Bu<@cP))9XH-&LEr#%N zTk#?cv^!YD=b!9q^JGc4?+wshY=(3L4&<&67fEb9zeKGHhCsN^NY&DJ7xw#@;K}2El-29t@#!*md29F!8(TgTlk57`v&fpeox>b{gu0ou-v`%bxv2N5;7$DD>`mgT9%)pZ|dKup~>ya{D=T0zjeoqpJ+mf^Km zYlG7aVEOP>)1AK@0PW3$7mNdKi2Kga@Ou0p6Ae0B1lwTd$&7RCng?RTq{RLyg<5tmq)h$fkFG>VY20xV`68L%}mgW1SlC@Nd7!lZLN=rb5O(LBtt z-}@ec2R2!;z+N-N#_BRx>_KNq+}$3M@24v#Gf7EeZDkeV0uy!X(n`BR!NPe5=ekRf zmokTWe~G(t3L@J^6~ObU?4PGOm>oVw;_G(k!)qQZJM=;9{#TW;ufY8uZr=T@s}--d ze7U>*r(Z6>arVusFKXXN9KUxA?qDYe;+!6tPGo|Cud{|ox)FbTmFPuXP%7bmaX%S^ zDwOwk==VYRHzFl7Q6_ZZ1ySD2SL=eBuDtnsKa)6rpRRTqJnsz@W#;$o-msm9Gcw=! zYuS$i4tlZUDdX2hcOqfT{N{v%pS?$~jzE^H9&h;;SCx`Sd5L8xpDqo_;SOqeL~UBW zhyx;QAWG$?J=@Xrj2toXciFUP+!^y#lp{@7-n|NOGk4+a%wBFT-h+*sRAOwQb=?<^ zVebu^k?iN2#=UUYoLX)KKM>yAVT3tDMdeo+R~ zZrv_VT0?dJMpbn-oaX*@kH1y>#aGKFj`AZr-R4~fX5?UTF}o1&c0qq4*TQ&{X9EDj0)LzWv#=_~Um zDCny>8^kRK#LWtd%-3I4y$Cu_xl{I2rllt9CUv<6VvEb2E}{sl!;!#KAVg$T;rVz! zf51n^&xw&}KrT?PX6SWMm7w2YUtyr3XKb$?r~FoVAHE~-(JE5aYFL|o5k!eCp0q2P&0eS!YloO_P2wDcyk+JYYlwZj{O4&)>%iU(dd@v#u>ZlC%&IE+4=lg=v$MV zwpnT6Uq|tb0*PMR?)^n^ldnVV6c@Q`utwxVfgTa%Sgdxmgn6M(ce*h2?r5HSx^gA%FzJg6vkN?K@_BSv8{#Awi zkf;U6WjbK}s$7Lj^Yjo@QLi7U`X{4(is?&?`n~+?i19{C;Y-5HrE= zb8m#&l`gqPpTJ`X#Fs*~Gpg|m@VA$?5Y0-iB-@POiu7jE9QdaDYWmq$HJb10i5kl$ zH$M3RSn~b$sF%*wiP(I{3>IOF7Rf0372YEx;2S&9sgy z$3=Jzs0VmK9{&BpmyPhm@tMGvaGs+p#MR{b+XX5T*kDc#h8rqhz-PXM5ppCN~q5KTh1G;*195Y~4Kyg3))jK+R|i+es$MA_u)vKc{*Yqx=+Q&??&qWRE(m zAzK1+M$l0DOIJXky+x^PwHko{j`_Ts0EJltm?WO*pz0iOx?%{Sh|0;oV^kO$oaUF0 zQ5W4h1|-Cj(h=WfD-95@0wmdkC;NwEl7H_$&N-4mfe9rBt9&p$jT+0T%=SwRIMSiu zs?Dc+FUkZ_DpTbhFo(u%R?d3>^yMg(4WU>@@>%8fC@h)wu44Y^Svp!399j9t{I_h8 zz9Fq{cEQ|sLx66#P-DaWDF+(JgOe@I(Rz0|Ds_MDxS*#z$`FL^?k(k>`bXIy5oKLf zK0vLt>cQ$%&W($2zW}6LgC##^&GI=3*9*+*Mk;(A5rGxh&$O5BiRVeGnIY;vdMY?z&=MAsIV~ zM`MJ&8~=R!V4^yG1XHT)6z`|C9Y&Yw@r*z1R(?V2*c7LaO!S{n{ul-<^;HA4ov%kG z4seHZeE*(KSIkiad-9n~yYPuJ>KN`VCxfEg3E}iHQN0$6(qf zohMOA$bk+~Q7mAQ$%CmkHpm&P0e*fLuIM5#q0#S94%g!l3c>b5PUljn+F!x+k+a=b z11xzt43LlE{bsnneMWzGtzMB~w3=7Cdj=?UfVXj@8$h(2otdbi$4^_!K=POC==38u z#pRze6lh#mWaNakQl2bVo>N_XRDeHq_YjcrQ*VUcj-wxOK)}n6y@l-TElH{C4&%zzB= zBak9f)93}OL(w^B03VU}9MD3AX27ecyS*66Bt>7RN@WB)ian`MlADvOBj{JvHlj|t z6+kCZV5;AkP6lWI%mI^;Hn5X?L6<6Ws2mc6%%H0Arn00>Ia*zEimlwDQgwvxc3h>~ ze$}e@WjvMB{kw8XPLOpyqk`(79|VC`mV6t%j9j3eg?mpyb2&Mt6ubiOj{#CR2pOi4 z+-U}15_3wUVx|{-Xq$c#!Q;L-x0~MPsEaK&{$~yb}z| z^QcWh$oyVL1T7+-F7Qo?!E681KP9!Z5|3aud$?tKUvyd|B)gMjN43_FDmg&}L7o=x zDypPJd_PvKfr0&yu!+;*0xxFN>{D6w!cSS-nQM1UH#jhNxIMA}htk4C_{(^UHD~HY z`-|rr^YnHP?xLY>%bh+Hr2m>g$H5jJ`r;Ikfc5$NlFjM;19bC>)3EVMrmd{(_(Q{A z+VYRCQ97-nE@LvXcksUr#>gAj&~%~>8`l)%jbLc4G<2^qW_a7%$x4kR{i1lX`NJ6v?g7SAnpX61RIA zXDH8j;U=%Nm>CUCrhUPB_m+K;;4CHK^NOOg|6pOmq9ubkb^oc3op;LG01KPxinj^s zO3_^R*8W4&!0|9ov|%&17Jp>vX346@+p5ZdzT7~Y_stZhOuOHb$_FAvx^Vqj882zC z#7BUq6yM}pGjy1geA)ioO#WeSZEu+6vfO1UmmUb{-iKEiz%hECh!***CHy$qJqxZx zTg3`=$-a9aOFXRm$-P*QA6FK4bV(iTw=n*p{V7FOJ;gnYk6JJpNg?D;a*N8u7O)0Zy{w~l1s~Y`9BG$)oaju<*dr4Zw&#;c|W|t@gdzk=XJiv!=v{Wkp0aV+Xh_U zT?Q_ER#=QzG&-o>7oEaXD=&|~V|D`wK5TlR|UI64so>_M5K*A@ah6vq-&K0}FSTVKbdW{%#ME#va zmLWn*)&vx?w@biOK2#zQX;jHW^JM4-04)qBW9C4#(#vS%#0a=(pBoa_`?45J#LirZ zhIpxoTVe0uis~{b`uOhO8a(gqfSmIhAeUsJ`KDY99dimYWkwVHD3WM`iIY z?N@#{GRE>?i6?IjR2%~!uA_83SLCaG z8L!JV8@G9WAd(J_LW>~Ed_RFqsP^(!Mu~|C30y{dN~3y3^BgJX=)4mSLCc5hi08`7Q?ahE7S>I~MqV_Wg^ zN(XC|gJp1}Mx_^2b8FJm|D$qsI~t#Udq4xIM3CNGb-5=K|JSM@6?YJC3}NXKLH=Vb zKwZQz!iwx*0>)XWE)r>IfCybgP7aVz+(E`kKQ}-UWE4ZrJHoLOs?(%th|y{WRkxi> z#8(q#B9N5i1Z&n~UP8T?eR6I2B5OD)Oy~)2le~qW@raU-{io!=bGP1u2|zAD3kR1P*|ecb zw%)})qj&GmdO?nHE4;*htFtv?45@bCLXNrHwl!~=*Lk}s$D)=?u6mR;gd2KG7}d$k zkLsk_ZHr8%$h%gb=<27B{17kEa~0=Yp-fGaEf}gDZVNNe#_i5=j4H-?owdCc{W0_opCz=P&aSW1liGepn00Rx=hBf;+VeG5M^iY>>U z?^~P-_XMNOx-{Jy{bkR}Vi|c!=#d{St5*T#EBgJ2$PP}{yYKY~z`J@9P*Msy^AV8> z$wDBf#7?MdqUT$^!b-mDxZVh`$tM14G zjg-#>1%TOQm%V^<`d58``AWc!5~47Da;5l!?dw2nNXOjEP#cadeqe@O_fc?BoGzO1VtJnX)kA6c$Kc6Yo;#rMY_FG`;H-^Ee zm8tQlY}4%k#xQi|rJ8!zzQ1_bk5mq#@5cY>I|0#mA20-nL#Xx|dF0mm2S$hfo{?Bp zD#!nJcJ@!L>^{??s_{zA62D*wD9g%`rjS(D+W6}eR3_+wE_#jqMA?GG(=~MU7#v?f zYDK+7bxc|;)ozwmLf!p<8G7>g*$Us5OB-tC9zp1ml-GrD7TZtFFh?P3l3Ge=dXFU~ z>Bx1zrUGoW@BP4jq^9P*Il$qBPIT#$RX)Vn36{;{+4|(={|{U58P-%5wGE#%QV5WQ z&>|%X0YeW63W}110HGSHfFND512%9JPC^S!LKUzjG!ali(NRZ7x_~V-+c=7dil`$X zI)Fgl<2JY*^E?sb|5Ozvl>577b&=sLC5dbPDFyYJI?uTL~Fz(dg`gSODRcQ60jNsLzA zC{u9}tGRWKJqzEoN%NdCh}?uDrLSZUcB6fyx66Cv6tfAm09$=rrS7+erB~;Hxp z3eM2-OrM8ob!G?>fwakwu+^~!j!mQaenrRN;O#$uLzCu@_}_wT-2l%3#nb(^V+W@a z28d+m*7Z{XMGbvV1E{>wyWd;MP(W3zgIwg+e+d{ISz=%$8|$cPPOF3o~p<@EJ<-3cFQ7OKUbc47bqSz=si2DYgDNi zn{W>S2Dho|cP>9b#9}a%koXmYm3B>vf4qjRNPJoG5{V=QWQgb^FO6_B8IGwuSCYLFF1Pt-(`C|{2{GF z(RY;50C*v55NKFS4&c!U+v3M2c<+;Is4A-!ieN9@ASG}FD5e{&{hT zw5*WZr~^Vi@h6*eXYTP8c<%B2)W1iSZ@N^7Pacsh_xYqJ*xfbL^_3Qh6-BoueXGmT zy3;tfMQQ}t)G9;mj9_6WOnWqcW;kfZm=F+I5HThO6xS(g+i z`&RehP?*`1lY4Dl(M!o}*{bG(=%BfORG6&e-0oWI&a8$O%VQNS)pQe=v|lqz(Ra$g zDwxM!EFQ*9*u!cs~20hnPf@zBDh)M&;0*%+^BW&#$k$q?B|1JH>#L4+gkS7>zv#-KZjP2Q#8K}q87AFu62wurZI=a> z7E8pdZSAv5?-PHSih&Tw?xlwhn$f0m+-*omBoSCV)=0k0vAq`aKV;)Wd4KPq_xz&RnBBQ+7<;gKq)0glRd*fJR+Hy%t9! z*Cf&fE=Nw9?1)$Ao)A(y%cC&TGkC(--V-!hlEdqT}_&jRRh1~3;jo)yZW zjtC)FTI0MBkXrtsPW=Vo)$ulVEUw+lx#vNtlrUBpb?&k_ti7r5swITCLMV zJTXV_%Q}b}%3E5pRIXVV`vT`DJ3a+E4GbsWwFeh2??36oX33!xFC(2AaTIJs6dj_C z_&J`FhPFt?<)ohYNDX0G@(0B-I?+1kACaOzaGL{qiMF;txIfAsxniS>GDI9qxE-CB zwqWyazhV!gCH2950$WqW6{Y7|+B5Qx>V8;A=JY46m(JG(z@-UeX#Q%P)rVj14XrxG zhP)wFX))-F{ny#MjTM`@#!2H)i^`plE_i8Fep>-1h#8B4B`C4}XxYq4p>@K&*Ja zFPs@eEI-poh++_$F`UMO<5QCzK6N{Q^uTvbb=K6*1};&?X`}mfl>TAVD32`F;Ai;m zIkN7unHt}M>sTHZ!)c;iYetcBcBL3aiuTO(OuFJ7w7X}+b-`TXx2NF;0n7GKO!CJx8E5e~D)7|g@@^HFwRWAI#K#P5iV4!ZSOEsS!9Mme-+EscWlm*~p zxALc8Fz3nCf*jnVwBN%n8YFmc%=U53({77RD)YTK2N(&Ea6)T;aKwMIStBTsWZCuA?Vs%KsBI)B#dw{}D|QZB4E8cozbda$O*&Iyv# z5=WhSaX0fVN@r|=M6TaGs%k9e26kTxAPi5-YQ=?`%}fZH!maE4V|H{)wid$~vo>Z9 z^EBVSFUz>t`YF%I+^^RoxHZbeXrI&ln?=o_(q;lyli=KXj}7gaBwit2`SCi8ok&CJ zrm_~-6KTt7^?p|tH{&1TEPq`3S)%bnlH{p`{Dh#Ftvd6dh_2(Vz1QG%*2L%0#?ArC zSWJ1q-K=O#J@>g%n(6p3!(%e2Yckb)X;|gZACE(7@YI~uK|Iq+QBesf99y)>6N{Sy z%#Fu>Z66d0b?2Hh!OHe)iTE z+7MbszkWuxzW5yB&GA~}Bz^bw8{(0nNXzYq{YcCT+hV8C!z|k(Vp5cJ?H#<#-nlZZ zzYS|tMeRO_D=^lzZM!MES57l{nWBU{GCTp#lm?E46%({PB{})WU`7%K*Gg#kxO2Qu zmVjY0G~?eriSn(d{r<1ED5NseQ}OmjQj!Qs&ZX2eaec>>&jd!;*7R#vEm7HTUPQX6 zmv`gic0l%G>rkk@pJSDc%4Z3`&nRW84|n*X)ECoO!EMzm6$IPb!;EVXlPbV)7Q9pV zTu3j$Y)mEvQ&VEfO`xtld3?)&0Lf?A1b9?1+-=$ESd#z;Iys4%c!^quR->-x@NJvm z582ts7yLMTtYDbnmsRZdnmwo4vu0jS$dmi)leJ95i`i6PreV5^n5K!Usvc5&1Ln2m zSd1W>>~_K&N0c(@S(52a=Sk%n=+uj(%!8N>$Umt9wZ}yU=H=&Kzg{$$9b~g>IYjz2HcMH!U<66WSsr%kCsHwb(Ypj2LG5_*UDStsTb%DL3jJvENPy}G#!50s_(I4 zF_KN#Tv8TC#HnUNtKQt03QU@iid?GO<$HD7Mh1s#j4GB14@oj-w@z_X=_q|51TUM9K8^Y}4b6u?^O0?;7~rb?cL5d!TXY1*xR9C2TNer`k_~ zCbQ?NtUISp@go~Y4pTPfleCR(%D1gQD}!&dPnvees+uGOCJZ=T`!xfWtVm%?RMcwK z=3IjN&Nmk*YG|M{zJ73)^-XxWA>+uwU4l2?oR{7Soqhk5*cj1hPD_(<+oS*T%OOUt zG99VojVC;& z46r?#whCho5mVE=*5thwBsO%|_pbd8g>-dooKDE$6~L8v>`T3celdT*esP90>wNFl ziPV=Y_CW{rDz~qh5b5~yk8iVdJ@j~zoo)A|7mU|Y?5FR$R)YXUS$Mo3Kn_XaR5v-Y z7>kM&Vz_&*78&_WL zfEEL3_%D?008Y55o?~Hn1cV2b>$tpf>m=U0u5j}2rmznLs2I6zoYsuh+r*jGms1b8295+v$l=E z44I0Z6rh-LkVr41V*YG5@y4jt(!nscDyW5)n!R3xv-2`Gb@jn^8W;jn-eW_+rzTNM z^)Rfckb*)?v_$Lvj!L+8EqPa>2b4W1%mxG!ed^k6&V2y)o@qCBVsEf;!zvp9c7vU5 zm&VSIwS{AH!Dx^H_`d>&?@nqWr+OdcXyWSjD@G!H(aYtLNl zy|-w2P_p*_UMnD08z2H=q;oREaQYxUMQHho;}V_Z|QJ1I=J#2)I}YWTQCKCQsp1)I-p5L3?K`ebZW`gMXy4 z&5b9SW8#tC`lpa+B0L)=fEA{@fY4YekN{{-0F<6^$$&&kHevd4g?&?q_H77TP_QjP zguEEIuk7n)yN9ja^qBsufN|Q8B#q;bxwn4#ZlA~Pi|bwYO`{M#Q-VvKS63$WWm|&UsT^PIEJm|V*2o2DHvx$w?+Ha zLX@UGc_c8Pxal-1{@_lwW5#R6ip%)m$A=%U1X2nhifO*NWbBF@Mv&B3f&hBGraC|% z?M1;e50V=`ywB_+Nnur4nOAV5r~Y>p*qOQ8&4Ff;JlL7own?e^ce|G!s0Bp8MQ_}V}aG7_KwSm2Gd z7_k|(MMQmV&2GLWfIqTa@JgfVc8chk3^_#P)(!wac|bKS7&GbXV)_W8dk+=sUV+rd z1jLgv?!~uNcHE-NR_1Wk28S@xChmc!TL9SC@Xj!h!;qQ!RP9dr@a-PZYt9BX#uDl2 zK2`WF5lc=*{@7qVuwG5^fd{X~@q0Gks@Qt()a<5aR=Nr_vakP(D{9cl_QJ}5L;#*3 z(*iS|g~fY`ql=w;(odYmP=@E@$K7q(Z$>ti{Bm*km`Y)HF20L&n1iutb{y?`T~zGyZL zZ?$B@rW2I33uv&V4L-5x0BmLssElSy;>{(K=RF!8T}bZs>)9)a+(&{y9-K1tR%_H8t-f9@9yK`-$7(_e z?8%cYb3YO{EWTDK&~U73f#Llx+Q;UEiz-=*@kk(9$W2eb765bQsp#27ZN96x*;(3wrrN)I7HzW$L@8%k$IQ`!*9?wAnIDv68Abd~>t>Pcm!^EoAPUlT_;BxO*6b#^#e5D&S;@)gFWPulWXJwgWi|BSqIbf}<-hwW;H}mO z-<5oB|F|coizE)JdTFG;C0e^yPXYfu0Pxeaj!u>p|K}^lNU~ONG&yb=xh32yVmCB zIX#r_gEH{!?GfMH-HOv|^jXBfyRBCG0!Aa25On9AHt7U)AUfh(`|%*ZBKe1zdwr2Y z9-(c>sq2BVTCVKHmLgNqPpDbk$WY~4UP{9`*qjSWqCQ%j_3H%Id19Z#u<_)HOC-qR7YtO zE^N8A<(}r@`?#f!D|DMZDzjWW?iVn<@Al>%MCHK_*U>IA{*H2GjC0yz_DkEB-`rq| z>pb2GSXP+Plj}J^q}R%nP;C43il6mS{m~36UQKTE3}lx6hx7HSO~~OHEQA-)cUfM;4m>DE#iSm7!EKO7y&Q z?`k!p_c`*nHRsbn{q40CZeix8N|`47tAwd(PUXhH0o1_t{0dL%+3;+_RBO5TgM9;V zgo)=ojEidD+il2q*NXcUO+J6T@U*>l_n{gv(cyS;hoEslwks(!ggxPP6nE^frZy@1 zq~>m&RNJ-t63$L2-L~@9cePLLDT!W9xxqdmxLPXIk~ zQVJ46_GzPbucGd5heU%bW;fG-#I+~bLTA1Sevrc>AH=bPIoJeuj>ZZ9^zs5ERvS#D zS54t4g5bB#yQ|)S>g_h&sA-PliH3ay277HzPNW9spf0A^o1zQAl;m`rPzuqyd8KQd z$k5wmS8@je5$k>}gTOnFwHUk|X5PDh%yuL5f+~Gn&O~%=?xnf6dqrP6(DymT!!Ot< zsJ)G_3HMDFs-9s9VYq)kD(t?f4Gc&rdIEeJ<;b&T@(h2?Q8Wn%8 zv;OAd&V%ecuaR`td*Ia<@k1k}t&)EaJ^cGs)G58|TV(H;7Y%a1n|w{VW)-v!!m4CT z?*|7&^6)4|zfcft`G-p8oBWLuP=9Eb(2^hkv21WK1D*)n79NHqx?FWCG%r+<`;_%P z%lkc-hY8t%q)a>9d! zzb$JII^|iTb3@#lgKG&%G`I_0{E329C<4{4w$1jp>NdD|C*FwGo-Rg*BN9Bkz1E;!l9!USwG?++3&eT8UD;sP$~} zBvm9T@n8~d>%*esr9DmC!nC8VO!76D{yb8`wNmf7F12X8Y@K$IrbY2YN=TDc2}jGY z+0L9|hcUg~f~mbClW2I78O&>bsvmWaQylI+{63O?v9Spm_zsy9z!;d*%?MkJ%&wk05_*pzZhU&b&%|fT+z86>^s#OR z#(hL*(>;n^CO*MM{G^mIIH4Sx-p}lU@V5UXd^n8FgE9R$lk4rCEGr_`PUI9IcVD;r zt4^W$z|`M=ze~m;+XHGZ{r-Y^U&zVQ5%p0A9$&Wq5;_qUCVxG?Q?&29b}Vnbb~F*k zb=jup8SyJJ{I3gu@5cuz`KZ>?!^p5}*^iuqG~du&1tsFzU8gveq}7$KzY*7;wg}0? zRloF)Cjg(NDTo*`Taft1|3nZ^^o|p4A)tiNgf69gjGUcZ;&OYH@5E_Bk{X(SS`up% zf3Uc{NPUW6+!{^!B#m#U@yw$TG$bqZsRu-$%wcbWWD#PCkgwkFLtx z5SnBpcppC<#niSyIz0MBzLY!YLAWk)A6PldcE=5-!wzSlksnZ48Ud8|&t<-##2<>< zp3PP#hOM>xLTisGAW-M_~Q)!0pzRyH?(@$sCCX?U$gH=DT$ z&rgD5tRMXzy7`wKSKOO#d>i_09igPoewaexj(nNQo$xVR*Zr^}ax`C)zjRv6ZiiFI z>;`ebF#|N*xBUis4z`U6&mxeOByO%bHOk7&_E8O(lGHsOTx7K&*&DDTD9eV{JSUtc>ekX@uW;Dbr(Na0WpcE~Lo~zCgfsgnA;s{#1JK4W zGXSEbVopr-KPURTQU`ae(JW;%T5gWg0aXK*ADqKe{md>^b?|ER9fHY^t;{)Wcn-{b3-=cDW%Dv+p5MKj{Hek8 zQ;*R$bHDBr_cJj;riMlf`iw%~i7T z8yUz@cJGgN(0^Gl+Qlf;u^uP7lK4X&)NwghJk%ZriWfRB2uMmFol$wVC8JSFRDf7Y z!Qm`W8(C*c)Xy4Nv$ljut`c9Dj9&2z>`Ecf`Y%L3BaB$@x;GxhdKSs2c8SnxOuxF$ z>i_R&OOe{@0{tu>G>kn*%xAOmZS?XBi@obV?p4cqrNcb6y)J&#p&mMJ5*}^oW(V~* zJfvc5zl(#IoYi@(BD$F8OW({R{d4GOiX$lLdm~CyOs-A7k*j^U{km&`_qJ1)d*~$x zy-IezEI7>Ibq#d>=M@l42{;6M3d8`wEWw*M)oWFR5zu>;$QN~)jG=Tds%a88OKj`m zVILSCGr;TU*pNe}P9J1x-QceJ^Uzq3zB(#{5e-Xjy|K@)8Y3X=6f^d+mH8edEm74s z;Zbpwr6b~xT2w~8T*=Uy4>}2-d(-T>0LB#*AfxPyGmj(BX2#sVe@fyJ&ZTqDOqXp| zc%)nDbN1Lalj0oE0q6QI?$&aAu%`Vh_jGMSUjEFcBwdSEXUWDz4}-d1prr#Y;t^u5 zb=` zRb8D+?%aajanm$Y4O~TZ$&D^X?BgT{Cv0j#Va!JYMnuWP2VR)?XYj!TT#%vBc*FTG zls_M|Q<;VL^%4z{{caOfeu$Sv%KXv4A{Ku|hJ|#Ekn1vY!}Zsre=Df;ekyn;y49C| zp-ab=eGJRGNzDKL+LJ$_Rfa$8dUGVJf&~EjhAl0J1b#s=fB^oXOzuh?ED%7Bi{Vaj9LV-l0fPJlp*P~fQ>aG8)`T?o*g#s z8Lu*F(f#-a6H2s(`K3d|KcD$D%vpl~Kvd=Myt3#4rk}2JulUYF6bkIgee2Gs;sgLA z9vN^DCu0hRL*La93rvsu*#6V`X8{LI9rVFbQ-C5v2xqw1?CQ_l@Ra7AljZ(*ujac; zGbV6@YY&OGO&3??x%p!vy9V$|&}8@p!G!@&5$j=-fZ$q6qBJm-Q8eD5`O(gN_7mU} zYPoW-jGc8h?@zOZ7XWi}IZc-XSJ-Dm%xCHCFG!suC44P!z33shvfI|+g+4U)+BXYe zEyPt@E3Ji}F}myX7nqKce?2$bqXTrGO}MvosX=A^mh(X_RIQu)eVWB6%%ua(RkiTh zRar82qh$?2m+MrnI|n=E@AnabyVP_kf?%3^dDF3~0kGJ2=~zPcVQ{1AjN)6|>tHhK z!IMty#NFD|&gy3$ww-6`yKCnZI-c{Rs+eecZ-^LT{~hr4FRii|Jb1`ucav8>j`7d+ zwBM(?0Dc+0c;R?>9VCy)z}2m6vKnayszf6Gvi$;%O}DL0yvQchi7z4h26K?a)vhR_ z$Ns5fHZZzJxyPzlC6BH9r#wet#r&0R8iRTJfH$bqTdp(vROroVmh{%0FqaJxOOiS! zoS_kJ;Rj0+Jbg@7XP3sI0_;?AGIX_#$TrVec+pUxA|p3@?_h`XW4BOCw0qDa<^Ex! zzQ95A1yP^o!?Xb;VJgKe-l9BqZniVEot0I0aZ&=GkYjIj!a9&r-K=lbKnvTB5SX(S zBcK$l;!tbiQTi$(q~U~fiSKlqtqxf{$d~s|KVwT|L%crKkAqJX9VG~8n(d6_wo%$u z4c;|m|Hj|}3=7oND$@+On&U|_)^a6CvqkmY^=B1IKaTz3@eC(+THYH@K;`O9e%r3J z3Az5c3+(H%#{RNuZH(2S+b1sa5O){MzNj8DN{}k;w?683?J=R9nRsxUv#<;_kG#8F z^}N>_#A#$2{K#(fZwL4ZTE?k+dgU-`jhg@XkcX+3H96fT-d&Lt(dq+I-ah!~R9QfD z-uvT%?|G1&J)8Cq^A*r}@$!8`6f!Pw;ICU~y{orRvEUERs@+)dk5qL~Q@uI$REiC# z-%=KonK5W9dwC%IyN-R1m!3v>1^KULcM`cFtV*DIQLI|@saP=3jpKv@59ss z5sJw@Eu_T1KQWOv#lx4TmVZN2WOaOq&?Fp9yt8G-&Qlcw&y0tvO0on~c)~qYQj|_o(nwE6`&V zF&W8PGmJGD>i+qcinjc~a$tGtNq_C_DCKwKsqRaf(#s1DcXUtx3+#CO*3=hEh8?;6 z<9L)krSLmM>l}GJWA&SDrhNGLb~bb_0X4eKNZyhPeX;I!Zyg^c%kbY zkI5(sG}JsrevrlFcxXpwPGaW*a|s^Ivk4a)+Pz7U17BwX`Kw(%!93dpoTI@rl9<=S zRP(J)D+l1XfjONV2b_PvF1$nO*jiUa`M`ZW}$Ce5fU2+uLb|^RsrnUV~$m6ekAGPRHHm-2GAr zh$AhojYLmjfBwHtrw&VJW?x#wr z8Yc%>$)KTOzog?>GU!n9IYGL%g>AkixC?P`@}w9aP_SR3EL*?P={-=Jqf(dl4d9<* z{JHVZ78t$^spX>#elB`1Nc6h&XBK-vBMUz1*-4yJ3i}8Kxx|BvQtQ4rWI53_58jWX zzp?xHmdVl5P+UUk;^;X__8a)_Q4d*Hx|mPf2*KfchehdC33SfUjqLcwI4f8zq42U| zNea(Go{o3{oORx#u@I)}mzSSr4?d^dYKy~DE$RwaZYMxm)1AO(rgO#vKbQzNyV&ud zqKA55^_zs`Q@Bfr^|&od?Tjj&V@^f>Xoz4`2l1tKcTNxt7BBMg*{nM6GZK;QsFlm1C5?mPq)Pt(m^g*)=WPCR6zwJ&Dl1YvfYGF z4EWBcL#mr)e6%R;^$)P@^!g(ORE*N7=j6sA zk7>8IZ=$X0{A%9Ra{YSOJt9K#qw(@PhZki|J<{G&%gpOz#McGIECsAIfN#fU}f@1L}Rx7_mue6`&@F(b>2k=AP>3wqL-ebkFie060Wky zbJvaucH9GtilnRY)_wq>gVcK4Z6b7m3f(1+-X zBYpuI#af8EK{(Vout2C(r|B^KQ2bgAs62OUAJ9RZ{l6fLUqFmL9l~Zw#*TKF=FndK z$z_=Ij8N){%H7GYE~f}oOq$QWJNz?eWuC>ccLi?3-7t|vUE7tc(S zx2{BHYqCSUUYhSUQ1loo>R(W`yWlDzk=BYuA~=!c*buttx>B33Xnj4v6918lumoI^bL`r+v2)oU+FGB4GaQgiUuOpu<4V!ROFBrOL>B zDFkn)9yHhp(R-yj;17c61c^&*6LP=P=AOyglrMw=b@50{Mp$F ziAp+IpxjA@K0b&@%mubvNp%cBWP@xG=0;eLdOuVFX3q}Bbc3d`6`}eX07)9yOS^tF80&w!WBCU4qB{PnT+U}>&rO&J2pHIV+RcPl}0_zGYS&>)nEo0_#-q;((i06@IHQx)Ce z>+w;JZ?(c!*Ni{g6iiXBl`DvLcdsNd>c&xr@1>|18B5Yryc&G?_g z3)F=RsDfj+II9t{XuuKttPDtc0WJP6N@l$zR-BPrj+9h6z(vS60ev0>^kJ-N0){M5%B5)~_!B0qkf~kHx7lb1dEFGo8Kx} zB$`Sha6^P+_tZ&!3IUylJ|}s6qMs8~(KnCI$oIU0x_tM4n^1&s1Q~EpfTHSvk->0w z6hzedSyv5>%7o)|HR$~OflzXMM{3VC&^}peALT_TL_jHs|GDG`p_95t!dS1qwGS}odM&MLKX}k|)+N@YONY$ET5)7&{VC$)X!%pBJ zs)k8YV;^R#pEezEqX53}6X|{t>S>%C?r}{%AIzVY^bO(VDrj<qrUDiQ#8pX7O6iqRL{={Ux6CV?DIgfd33ayC+y zjdMMefV=>vb480=6f00;SQ)_i>m?Nj1Ed5$m5RXm$wG*$?ZJPE6bv-LCt*bpT`8P@ z%xz^A08zM*jO0|a)g%6YWx!zajle}Uw;E$Mx_@rMX(ks~>j{x5P+DMv#z~jwcd~(J z*Q_JnB>S?_VGnxGoo51-nfD*Btb_Xli1A=VyI}^LRSn-Wd>qFG;Hpvs$fprlnTVA^ z^X&gug3h?F_iz;Q; zC>D=2d}L|^W5Nl80jC_&6McX|#wn*QS^+2#900{do!bd(8v<_(JKmfS26r%<7i`}v zyV%rDMulB!pkd|gou;$WTwid&AJEyjZc!y&X_e9Pd>WnTx39aC_OCJil=c*lgQCV+mcnS3nKRLbbf zFMd#5kPpDQv>N~f+}bQR#^E3wQvj%5T?^DP1n`3a89)K~0tJQvOjC>eWU)1qdN8GT zMxQ*F9@v#ErE2BFmG1BBJV9X~W~exv9qecvMwZTvC1iZQdhdtgZH8NZYhI8%pQ;&p*SrN={kBB{ z94_ceJ-<4|3~w#+T-IByP~^0{E>)hpID%5e5`2)BwG2NMx3Cd#PU<^TJ1i!b zMpyp}Nu1wW{SgNTnjc_Q{C1P|V!Z4yP_U{&Lh}xQ8g(FUefV48BcSvX2M#GM!bC@% zh;(UF8AuNq2cVw)6WK5j)YM@R-pqm_zeh~WWDiiTm`+N_LcpI!lyhX(EE zTlToK&yVog@ntK;zyR5(PX}T*3WrZBw!bA4C+N$m=a zMW^9E(sH8C0<5Ub@Q1IbQ=6Cw-nn^y*FDED(-^PHdtNbX3t78%tqb;UmGaI1(q3HSy#0`11DCzMr{NBn-k z(sRzS-?y{;E)~91g^A#g70<|2f0$zMo75NS^C-F4Jzre>_4)5=vPTf*F%al(OB8tG4D?)BR5?ymHr!l}24WG+wRIoG~WYMypx ztWor857LipXv-+*k;W$Gp!{?U%%fRbJVc>P#q$1@lZp>i?8xhlJLQHmh_!L5$*#d% z+-_Sc0E3$;e!L_g5Q?c6KwJIi)tx-VwJ~dExnkjzYWu!|($rP&R==?mW_9rx!FCCM zWMsJ=)aIw%STH8xW#1${@U4q@*Ebo_*V%MxmxHx^b{ZFHI4{6hr70B8QPs5tx11Kr zH#aw)c-Wo=%)g<52X37>IHRFMN!e1CIc}KTH`*E^>Coo+dKmJh zooYcTINt3W_W{88l~4}17dGxB+vp8MKWg5Asr6o+UAoGkM_m`yhkImuRFXHy&Cxy@ zo`2qZ#Tdu9Jk$EGqC6fLQGG83`m=+>) z8P*-2HK{U)9e#TE9yKKB^&;%?TZo~ThMobTX4%N#22_uZirO%3^UvaJMfrx%-p#qu-QkM_3 zXE=+%SL}tn9DXRqHG@Kyv|SxO`3)^Ov_^Y6l*@syl?Hp8&%JZ@^t)^I9>&$Ii?=<` zq0AxGz11Viz^0<7>Pt}Y2p#(L1-QUHilP#$b6@l}ynWQX=#WifzF6<=>lH*=JYWG6VmxMJYpU_=+qDiXT5xI_$bIUQg!WBXGC7M zlqhG8P^(KOb-5q!_FX}z7`(1<4!?FZkgQ36?sVb037Zok1|80iD3H_oQ4p;d0PoaU z!)os#EUoFhz-J}(M?SGg|0Nsqw6T$Xjaxx{(i!|mwBMo3O}J-c2WeCH2_|q@taG<_ z%E3Fzobjefyy>yv^mU4VpTlBEi-BOVrqhxsJU8eHF|be07VQfmhd*fm$Q))iIMEWC_eTTln1p1F=u zzdrPb>x%$PXPhyyO8L9T{&{27<&)Re@`mwai8Gs)|6;~(I9MHZEzs$g|1F^?o!QS@ zzD&^Wbzxn@SwFWa1=)Y^T7ERGE*n%?OH+;hyVfPE(n;mwf(hS|**Y`i^Vjz4r5JuB zK!qpl;cld9(4F+?6#6PBX&AR(_RK5NkqESKOd zsNkNI7AE&Xw^SmW89+p0<7OwBY0CgR(lmSSD`U(1x|Q5W6T-#A%0T)Z++MMFsL{99 zB{&Y*neW!>|Kh#dNoq9P5-LQCH^<)|N>k+4E_xSlUY=5Je}Q>_X?sW3snPICoJFo& z|5cx9&a2M_)p&pb5)iv!Uw}ROa%H(1N{Tq(7LQR8%0_?_a?0W>QP`1x@}HkD|W8#&=SHoIE++=xndo4OV;C0Q0~3s|?NG0=O@*4yZ2H zKUrt}_nNxHhY|)+0i>sayfxSAcda}VWza~w&*?;WP~YS4(eFu^wdCDb-mdfS(=SvO znr;o2bINj7+l^>?Rz7h&Yh$0`@NUBzkqL6kqt*pwZ(^0JrDGFjO!X>~_Gn?jlN4HF z`gZ85cK_Ic;HEr0qfa}ijBz(xYU*p+8T4T1C~wW_Pal~!&OEK^g{1h)C#VeW^DpC` zJ)Io!vYjLYdtBR5d^f^`vMo!Q@O38I40YOBE<6<2lGBt)Q}1|DepB1EXm;0IIG&P| z64Oy`oolr3+D68UKqKCUP@XNV?}=?Ak69mgNwhf%m|;h|Vq8#trICA#l{KY%cYsA> z@|W#5wk?dkBUaNSl>tCjPoSu#+C{0m+i=YrfrT`6PDS6^PXQ7r@JT&*hLAJp z@jP(OXC?EHTi7b6*(McJF)q|*z9|1zJM)VtJ_QZ9daBc;;0tay^_48LZVrZ;J@m(vX2a@*8eW_EMkZ5|& zGe3Z)TDeUlrSni#CqdHm%AwRuY4f6;h)}BQFY~uNc0#0=o@KfrLQO-5Jtz)@U%y9C z@iQg{%y5tt$FW;(7e?6jw<7L7Rw!!zdAjgN%C*Yqy^;&6=qQ^UpHi1^uJW0%DQVlN z&a)mJ&FZn>wU0_ei?-c6R%RX)(e=TUS(@dzN+X%CsU%V5xWst)#>>L7rCHI;e&=?- zo{{!rj3?P{56fAKIDx38=Ir)zcxGW(cLTek*vSHm7kh&`>vKA zJwsuA-cdtwtIt1KYaF&OQ@rt#4?Pmv`|8r$k*Y#!JQB$)VRVwSc6jNNM@`=ht-NM)rfJC$Dj$jJLu zq0}X@W8s-n{#wTQ?N}`hbr!Npzi^OdH491FIPF~hO8l_%E1ehq)@0-XCo!tPWT|ia zc4(cG{&%dzL-WJ{&IT-jER=%==3<)S0hO(x^)ec*TJv;?K&70-L@37LN~}cu@GZ?Q z6%k%(8#7(h?1-ywjYE}LY7ya{dbgk%0E=w)|wn` z>RMmgoX`d>>N`QuJcHtWC3~g=m2(AIrA&-m`^pz%p5d)Ued7 z4v30VA&!}qQ{_~tnQ2)9f+QlZ;SK3Vr%_RQ5_bpc&u81iN zk2}3AW_^8GUNOSYW*|tjuz<-g@5cdTCP(8~%8HUh`AU)UJPG}kGa?t&AL zaRgfb5Q{4?U8tN4eB61?+n+V}UpI7I0{{;_p2{;0Oe=E5-)d)u!pwLdpokxjXC6eo zxl)p?i_as5>P31#Do;ps(1q|B{Kt=LK=|~6=K!eyFs^rKOD5iVezu*e0-U?^+Fzj~ z)1qwn6j92StsP&n^gGBgVHkPZEj?mH6V^!>mhoy2PaDfhv(<@FD}OT@h^D^0?pj9_ zhE$`=P!-gSPw?_$0*MyyJOfekS-z)JPP|A;F|UjCr~*sm^A2_CL~$snEgPRz9j*~~ zll4x!FeSac8s7ZCLJP(>R77lQ=5hT%Oc{aN^E~SG5mXx_{2Y4W9MG;Uu(qaVb~ve9 z$}FwT*h@&d$ZO1T3<4QI6T^Av0M&)awYUv@F?nmYR2yNbfrQ7JwI}|k&%+}ki`FTl zRJC+B{JU5SL)ud@E&T9fH6EH{YN)y?e@F0;@VBbRw=ZANJ1X&D z+k7i%fCA(RpoG*p-osk|8N>e>i~sOCRY29geDW4hp|)Z7WtG+0B{=(kS2-7_smV>}--`Nrw8AaU zi~mJX^Qh>*cD8#)3g~trXE-GOizJ*K5bS40`x~*o<=TL0=^ru0JlR6l0Q?7n$XzeUo7~ zc4i!L3_!gMc{w#1(Knp;$LniCR#gv61vUbJiT85!z?8GIixpVPV5)2jpQMs=^LXJs zsqF)%GW`yJM85SBOX^C0h9Vz>C@AL7I6syrwWn_pooj`8vu>0leR9b)@!`ypVjF#% zC_!9suIG{1FQzd5ctd-2U2?-sxIC_!rdDY{rDcMfU(|L?y`g8s1Dq{Af$BIMZPd4c znZpyKOf;G;6LZkm(~yY6fL1Z8oeZE@5Q$5JSir|%N#$NBq7?6NjXp9{&FN*@4KjBDpTaBHns3*Q0SRTlc zi8mH6r9Gdd41bt7fDP#_&lWW3=cao+auc4dE}Od`49Y=M*GIMnoV`a3T;}Qk_q6!j zGdAn7@xPZ!`Tt@VdX54p9vjyEyc^;=v8IrSB6EeKiZCeq7-p)C zN%26}+)wDQ;c`bh$i|b`9Bb zjWHGQE6vTLl`!Iqmz(z9@;tLNwOe|j-VE+qagkz=KVr=_2tk7>OZ*6KJ{N+9}}wlTB6A)g(JsnQ&$^pG`OQnq8O$Bcmg|%4EJvcv2CkTx)Jk&PaF|m zX+D3dY-U&Bn}mSq0?57V|8ehH5D-UU?a(nB%?~5buLrlkLG|EUW}%eJQX47A#cppX-S;XOZwGE~V{uaje;mwMS2)aBDb`m33`swTTwLD*JWy+e17`sed_YfrVMre<6Ph{z^sY@GFKL7v5uR};svrXG>{iFfKQ#5ESaa5VMzn(;VdBeZAKwL)qRI9^K9X2*0 zLo`lO1N=q=V1N7h_YKZSr{@PjjR<(hXojYY-38NZ4^ucAdUqBxcHMKrG6(O_K9V|y zgA2w~WstvVpw13B$a`RAuhl6)TAu%NG|1Aq9Ll;F!`}}ehO|JIqS^c3+Qq*QcmFLk zG!PtsX%3PsBmqFFS@c_d3oxZEZ{}sv<&vCcg2Do2(Db)!u@!Q-^ZM)E_e<694h4=Y zJ5TS$P98}OZaD7i@*pHNaPTpDApYDH8$$rFFCLgoCqv0G@*8+H$|S0-aCI)uu9K^y zu=Cf!bVSi2BzL9RJd^!P$Z*U7LBE@OX(-?&vFH$6bL-b-em<2Kq~*&jB}6KWnI2ZY zxZ3m`o zv`vXzt=*CKW`A9bwTp4y2EM+=LvL~{8^GrQvW|7&Pq-!8{GI95L5B3Ba-qN8hMw$# zpr~9SMXO%@(N;%~5_#Xf=Ej{)!8Pv>Nu7eTgB28$@p?+py#u%cOWG|cl~(&~WILnv zd;5)YT+L_O>pBRX`&>1JW^kU%S*YtDhG@n>O2B*m-a^V4I_4F;FZAP=)rKeP_3i8p z)q$FT%+RC@^=bJv%SVsS%=d39OSrP!HqY3gA-YWw;iRAJ^=Q3kEj%FKIzLAHL72mq z$`_i)^Im6^jkAW%Y`HcV?;M?&f-gdp|2#5N_O9!HO#p<^vcF-d%t=-RUpvlgH`MNuGn`J#F@k zGtobiZd#>tf3C2Zs(bV%o!dDYk@$f0x9=R&4<+BMT1+(&FlT|~y2AUdu@rohSF>Bu zr!&{NwlgJ(sKx$Hr!7JIos*LDhoo~ys{HO_yN*5gH*vUTY#r7tY-E3i8cAhA^V6Nf z-(j;PEYV{N*~MkojemZst_L;>zIQEL5Aj-caCbowuPH){A9|5876&g0%Y~;BQ6!F2 zx2<-5_ma}o^8f`6lOU1ql7?B%9oM$!@H(*cp-fj*dyK%+Ww@2gc&a=aDiG>4RO-dP zyN;ozYZFE&8i?woyJio|bKF`AB6;ReyPy0t_Q>Dg3-0eC>T~3NrEA=pcO}|1q}*{% z6G3UzwSOWX7-Uzjuoi#;B&qd&8CQETuEGMFw1?bl�H-?6OCxAS?GXfg7x{t&VqW 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 g)b7B~J&xwdWiQYcDhu$|7J(0sc& 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�XNevTWm%F*#{kzBLY}f}`=L4O` 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

    K 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 O-)n>TujPM7PW=xmQ@u?9 literal 0 HcmV?d00001 diff --git a/server/X11/server.crt b/server/X11/server.crt new file mode 100644 index 0000000..7ce931c --- /dev/null +++ b/server/X11/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV +BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw +DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY +hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb +o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f +eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN +MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi +ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL +BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr +nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa +nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9 +3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb +hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco +iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA= +-----END CERTIFICATE----- diff --git a/server/X11/server.key b/server/X11/server.key new file mode 100644 index 0000000..5c2f2c8 --- /dev/null +++ b/server/X11/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz +XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S +XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL +d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj +gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy +mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR +1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC +5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi +LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB +AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s +mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i +vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36 +SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC +1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz +XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7 +LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ +CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf +dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko +YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH +a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k +B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY +9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ +i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH +YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR +vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ= +-----END RSA PRIVATE KEY----- diff --git a/server/X11/xf_encode.c b/server/X11/xf_encode.c new file mode 100644 index 0000000..bfbdffa --- /dev/null +++ b/server/X11/xf_encode.c @@ -0,0 +1,171 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RemoteFX Encoder + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "xf_encode.h" + +XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height) +{ + XImage* image; + xfInfo* xfi = xfp->info; + + if (xfi->use_xshm) + { + pthread_mutex_lock(&(xfp->mutex)); + + XCopyArea(xfi->display, xfi->root_window, xfi->fb_pixmap, + xfi->xdamage_gc, x, y, width, height, x, y); + + XSync(xfi->display, False); + + image = xfi->fb_image; + + pthread_mutex_unlock(&(xfp->mutex)); + } + else + { + pthread_mutex_lock(&(xfp->mutex)); + + image = XGetImage(xfi->display, xfi->root_window, + x, y, width, height, AllPlanes, ZPixmap); + + pthread_mutex_unlock(&(xfp->mutex)); + } + + return image; +} + +void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height) +{ + XRectangle region; + xfInfo* xfi = xfp->info; + + region.x = x; + region.y = y; + region.width = width; + region.height = height; + +#ifdef WITH_XFIXES + pthread_mutex_lock(&(xfp->mutex)); + XFixesSetRegion(xfi->display, xfi->xdamage_region, ®ion, 1); + XDamageSubtract(xfi->display, xfi->xdamage, xfi->xdamage_region, None); + pthread_mutex_unlock(&(xfp->mutex)); +#endif +} + +void* xf_frame_rate_thread(void* param) +{ + xfInfo* xfi; + xfEvent* event; + xfPeerContext* xfp; + freerdp_peer* client; + uint32 wait_interval; + + client = (freerdp_peer*) param; + xfp = (xfPeerContext*) client->context; + xfi = xfp->info; + + wait_interval = 1000000 / xfp->fps; + + while (1) + { + event = xf_event_new(XF_EVENT_TYPE_FRAME_TICK); + xf_event_push(xfp->event_queue, (xfEvent*) event); + freerdp_usleep(wait_interval); + } +} + +void* xf_monitor_updates(void* param) +{ + int fds; + xfInfo* xfi; + XEvent xevent; + fd_set rfds_set; + int select_status; + int pending_events; + xfPeerContext* xfp; + freerdp_peer* client; + uint32 wait_interval; + struct timeval timeout; + int x, y, width, height; + XDamageNotifyEvent* notify; + xfEventRegion* event_region; + + client = (freerdp_peer*) param; + xfp = (xfPeerContext*) client->context; + xfi = xfp->info; + + fds = xfi->xfds; + wait_interval = (1000000 / 2500); + memset(&timeout, 0, sizeof(struct timeval)); + + pthread_create(&(xfp->frame_rate_thread), 0, xf_frame_rate_thread, (void*) client); + + pthread_detach(pthread_self()); + + while (1) + { + FD_ZERO(&rfds_set); + FD_SET(fds, &rfds_set); + + timeout.tv_sec = 0; + timeout.tv_usec = wait_interval; + select_status = select(fds + 1, &rfds_set, NULL, NULL, &timeout); + + if (select_status == -1) + { + printf("select failed\n"); + } + else if (select_status == 0) + { + //printf("select timeout\n"); + } + + pthread_mutex_lock(&(xfp->mutex)); + pending_events = XPending(xfi->display); + pthread_mutex_unlock(&(xfp->mutex)); + + if (pending_events > 0) + { + pthread_mutex_lock(&(xfp->mutex)); + memset(&xevent, 0, sizeof(xevent)); + XNextEvent(xfi->display, &xevent); + pthread_mutex_unlock(&(xfp->mutex)); + + if (xevent.type == xfi->xdamage_notify_event) + { + notify = (XDamageNotifyEvent*) &xevent; + + x = notify->area.x; + y = notify->area.y; + width = notify->area.width; + height = notify->area.height; + + xf_xdamage_subtract_region(xfp, x, y, width, height); + + event_region = xf_event_region_new(x, y, width, height); + xf_event_push(xfp->event_queue, (xfEvent*) event_region); + } + } + } + + return NULL; +} diff --git a/server/X11/xf_encode.h b/server/X11/xf_encode.h new file mode 100644 index 0000000..82b68cf --- /dev/null +++ b/server/X11/xf_encode.h @@ -0,0 +1,32 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 RemoteFX Encoder + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_ENCODE_H +#define __XF_ENCODE_H + +#include +#include "xfreerdp.h" + +#include "xf_peer.h" + +XImage* xf_snapshot(xfPeerContext* xfp, int x, int y, int width, int height); +void xf_xdamage_subtract_region(xfPeerContext* xfp, int x, int y, int width, int height); +void* xf_monitor_updates(void* param); + +#endif /* __XF_ENCODE_H */ diff --git a/server/X11/xf_event.c b/server/X11/xf_event.c new file mode 100644 index 0000000..5dd84b1 --- /dev/null +++ b/server/X11/xf_event.c @@ -0,0 +1,198 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Server Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "xf_event.h" + +int xf_is_event_set(xfEventQueue* event_queue) +{ + fd_set rfds; + int num_set; + struct timeval time; + + FD_ZERO(&rfds); + FD_SET(event_queue->pipe_fd[0], &rfds); + memset(&time, 0, sizeof(time)); + num_set = select(event_queue->pipe_fd[0] + 1, &rfds, 0, 0, &time); + + return (num_set == 1); +} + +void xf_signal_event(xfEventQueue* event_queue) +{ + int length; + + length = write(event_queue->pipe_fd[1], "sig", 4); + + if (length != 4) + printf("xf_signal_event: error\n"); +} + +void xf_set_event(xfEventQueue* event_queue) +{ + int length; + + length = write(event_queue->pipe_fd[1], "sig", 4); + + if (length != 4) + printf("xf_set_event: error\n"); +} + +void xf_clear_event(xfEventQueue* event_queue) +{ + int length; + + while (xf_is_event_set(event_queue)) + { + length = read(event_queue->pipe_fd[0], &length, 4); + + if (length != 4) + printf("xf_clear_event: error\n"); + } +} + +void xf_event_push(xfEventQueue* event_queue, xfEvent* event) +{ + pthread_mutex_lock(&(event_queue->mutex)); + + if (event_queue->count >= event_queue->size) + { + event_queue->size *= 2; + event_queue->events = (xfEvent**) xrealloc((void*) event_queue->events, sizeof(xfEvent*) * event_queue->size); + } + + event_queue->events[(event_queue->count)++] = event; + + xf_set_event(event_queue); + + pthread_mutex_unlock(&(event_queue->mutex)); +} + +xfEvent* xf_event_peek(xfEventQueue* event_queue) +{ + xfEvent* event; + + pthread_mutex_lock(&(event_queue->mutex)); + + if (event_queue->count < 1) + event = NULL; + else + event = event_queue->events[0]; + + pthread_mutex_unlock(&(event_queue->mutex)); + + return event; +} + +xfEvent* xf_event_pop(xfEventQueue* event_queue) +{ + xfEvent* event; + + pthread_mutex_lock(&(event_queue->mutex)); + + if (event_queue->count < 1) + return NULL; + + event = event_queue->events[0]; + (event_queue->count)--; + + memmove(&event_queue->events[0], &event_queue->events[1], event_queue->count * sizeof(void*)); + + pthread_mutex_unlock(&(event_queue->mutex)); + + return event; +} + +xfEventRegion* xf_event_region_new(int x, int y, int width, int height) +{ + xfEventRegion* event_region = xnew(xfEventRegion); + + if (event_region != NULL) + { + event_region->x = x; + event_region->y = y; + event_region->width = width; + event_region->height = height; + } + + return event_region; +} + +void xf_event_region_free(xfEventRegion* event_region) +{ + xfree(event_region); +} + +xfEvent* xf_event_new(int type) +{ + xfEvent* event = xnew(xfEvent); + event->type = type; + return event; +} + +void xf_event_free(xfEvent* event) +{ + xfree(event); +} + +xfEventQueue* xf_event_queue_new() +{ + xfEventQueue* event_queue = xnew(xfEventQueue); + + if (event_queue != NULL) + { + event_queue->pipe_fd[0] = -1; + event_queue->pipe_fd[1] = -1; + + event_queue->size = 16; + event_queue->count = 0; + event_queue->events = (xfEvent**) xzalloc(sizeof(xfEvent*) * event_queue->size); + + if (pipe(event_queue->pipe_fd) < 0) + printf("xf_event_queue_new: pipe failed\n"); + + pthread_mutex_init(&(event_queue->mutex), NULL); + } + + return event_queue; +} + +void xf_event_queue_free(xfEventQueue* event_queue) +{ + if (event_queue->pipe_fd[0] != -1) + { + close(event_queue->pipe_fd[0]); + event_queue->pipe_fd[0] = -1; + } + + if (event_queue->pipe_fd[1] != -1) + { + close(event_queue->pipe_fd[1]); + event_queue->pipe_fd[1] = -1; + } + + pthread_mutex_destroy(&(event_queue->mutex)); +} diff --git a/server/X11/xf_event.h b/server/X11/xf_event.h new file mode 100644 index 0000000..aca8017 --- /dev/null +++ b/server/X11/xf_event.h @@ -0,0 +1,75 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Server Event Handling + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_EVENT_H +#define __XF_EVENT_H + +typedef struct xf_event xfEvent; +typedef struct xf_event_queue xfEventQueue; +typedef struct xf_event_region xfEventRegion; + +#include +#include "xfreerdp.h" + +#include "xf_peer.h" + +enum xf_event_type +{ + XF_EVENT_TYPE_REGION, + XF_EVENT_TYPE_FRAME_TICK +}; + +struct xf_event +{ + int type; +}; + +struct xf_event_queue +{ + int size; + int count; + int pipe_fd[2]; + xfEvent** events; + pthread_mutex_t mutex; +}; + +struct xf_event_region +{ + int type; + + int x; + int y; + int width; + int height; +}; + +void xf_event_push(xfEventQueue* event_queue, xfEvent* event); +xfEvent* xf_event_peek(xfEventQueue* event_queue); +xfEvent* xf_event_pop(xfEventQueue* event_queue); + +xfEventRegion* xf_event_region_new(int x, int y, int width, int height); +void xf_event_region_free(xfEventRegion* event_region); + +xfEvent* xf_event_new(int type); +void xf_event_free(xfEvent* event); + +xfEventQueue* xf_event_queue_new(); +void xf_event_queue_free(xfEventQueue* event_queue); + +#endif /* __XF_EVENT_H */ diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c new file mode 100644 index 0000000..ad3938f --- /dev/null +++ b/server/X11/xf_input.c @@ -0,0 +1,125 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Server Input + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "xf_input.h" + +void xf_input_synchronize_event(rdpInput* input, uint32 flags) +{ + printf("Client sent a synchronize event (flags:0x%X)\n", flags); +} + +void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + unsigned int keycode; + boolean extended = false; + xfPeerContext* xfp = (xfPeerContext*) input->context; + xfInfo* xfi = xfp->info; + + if (flags & KBD_FLAGS_EXTENDED) + extended = true; + + keycode = freerdp_kbd_get_keycode_by_scancode(code, extended); + + if (keycode != 0) + { +#ifdef WITH_XTEST + pthread_mutex_lock(&(xfp->mutex)); + + if (flags & KBD_FLAGS_DOWN) + XTestFakeKeyEvent(xfi->display, keycode, True, 0); + else if (flags & KBD_FLAGS_RELEASE) + XTestFakeKeyEvent(xfi->display, keycode, False, 0); + + pthread_mutex_unlock(&(xfp->mutex)); +#endif + } +} + +void xf_input_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); +} + +void xf_input_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + int button = 0; + boolean down = false; + xfPeerContext* xfp = (xfPeerContext*) input->context; + xfInfo* xfi = xfp->info; + + pthread_mutex_lock(&(xfp->mutex)); +#ifdef WITH_XTEST + + if (flags & PTR_FLAGS_WHEEL) + { + boolean negative = false; + + if (flags & PTR_FLAGS_WHEEL_NEGATIVE) + negative = true; + + button = (negative) ? 5 : 4; + + XTestFakeButtonEvent(xfi->display, button, True, 0); + XTestFakeButtonEvent(xfi->display, button, False, 0); + } + else + { + if (flags & PTR_FLAGS_MOVE) + XTestFakeMotionEvent(xfi->display, 0, x, y, 0); + + if (flags & PTR_FLAGS_BUTTON1) + button = 1; + else if (flags & PTR_FLAGS_BUTTON2) + button = 3; + else if (flags & PTR_FLAGS_BUTTON3) + button = 2; + + if (flags & PTR_FLAGS_DOWN) + down = true; + + if (button != 0) + XTestFakeButtonEvent(xfi->display, button, down, 0); + } +#endif + pthread_mutex_unlock(&(xfp->mutex)); +} + +void xf_input_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + xfPeerContext* xfp = (xfPeerContext*) input->context; + xfInfo* xfi = xfp->info; + + pthread_mutex_lock(&(xfp->mutex)); +#ifdef WITH_XTEST + XTestFakeMotionEvent(xfi->display, 0, x, y, CurrentTime); +#endif + pthread_mutex_unlock(&(xfp->mutex)); +} + +void xf_input_register_callbacks(rdpInput* input) +{ + input->SynchronizeEvent = xf_input_synchronize_event; + input->KeyboardEvent = xf_input_keyboard_event; + input->UnicodeKeyboardEvent = xf_input_unicode_keyboard_event; + input->MouseEvent = xf_input_mouse_event; + input->ExtendedMouseEvent = xf_input_extended_mouse_event; +} diff --git a/server/X11/xf_input.h b/server/X11/xf_input.h new file mode 100644 index 0000000..34cda06 --- /dev/null +++ b/server/X11/xf_input.h @@ -0,0 +1,34 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Server Input + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_INPUT_H +#define __XF_INPUT_H + +#include + +#include "xfreerdp.h" + +void xf_input_synchronize_event(rdpInput* input, uint32 flags); +void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void xf_input_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code); +void xf_input_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void xf_input_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y); +void xf_input_register_callbacks(rdpInput* input); + +#endif /* __XF_INPUT_H */ diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c new file mode 100644 index 0000000..d80f0ca --- /dev/null +++ b/server/X11/xf_peer.c @@ -0,0 +1,710 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Peer + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char* xf_pcap_file; +extern boolean xf_pcap_dump_realtime; + +#include "xf_event.h" +#include "xf_input.h" +#include "xf_encode.h" + +#include "xf_peer.h" + +#ifdef WITH_XDAMAGE + +void xf_xdamage_init(xfInfo* xfi) +{ + Bool pixmaps; + int damage_event; + int damage_error; + int major, minor; + XGCValues values; + + if (XShmQueryExtension(xfi->display) != False) + { + XShmQueryVersion(xfi->display, &major, &minor, &pixmaps); + + if (pixmaps != True) + { + printf("XShmQueryVersion failed\n"); + return; + } + } + else + { + printf("XShmQueryExtension failed\n"); + return; + } + + if (XDamageQueryExtension(xfi->display, &damage_event, &damage_error) == 0) + { + printf("XDamageQueryExtension failed\n"); + return; + } + + XDamageQueryVersion(xfi->display, &major, &minor); + + if (XDamageQueryVersion(xfi->display, &major, &minor) == 0) + { + printf("XDamageQueryVersion failed\n"); + return; + } + else if (major < 1) + { + printf("XDamageQueryVersion failed: major:%d minor:%d\n", major, minor); + return; + } + + xfi->xdamage_notify_event = damage_event + XDamageNotify; + xfi->xdamage = XDamageCreate(xfi->display, xfi->root_window, XDamageReportDeltaRectangles); + + if (xfi->xdamage == None) + { + printf("XDamageCreate failed\n"); + return; + } + +#ifdef WITH_XFIXES + xfi->xdamage_region = XFixesCreateRegion(xfi->display, NULL, 0); + + if (xfi->xdamage_region == None) + { + printf("XFixesCreateRegion failed\n"); + XDamageDestroy(xfi->display, xfi->xdamage); + xfi->xdamage = None; + return; + } +#endif + + values.subwindow_mode = IncludeInferiors; + xfi->xdamage_gc = XCreateGC(xfi->display, xfi->root_window, GCSubwindowMode, &values); + XSetFunction(xfi->display, xfi->xdamage_gc, GXcopy); +} + +#endif + +void xf_xshm_init(xfInfo* xfi) +{ + xfi->fb_shm_info.shmid = -1; + xfi->fb_shm_info.shmaddr = (char*) -1; + + xfi->fb_image = XShmCreateImage(xfi->display, xfi->visual, xfi->depth, + ZPixmap, NULL, &(xfi->fb_shm_info), xfi->width, xfi->height); + + if (xfi->fb_image == NULL) + { + printf("XShmCreateImage failed\n"); + return; + } + + xfi->fb_shm_info.shmid = shmget(IPC_PRIVATE, + xfi->fb_image->bytes_per_line * xfi->fb_image->height, IPC_CREAT | 0600); + + if (xfi->fb_shm_info.shmid == -1) + { + printf("shmget failed\n"); + return; + } + + xfi->fb_shm_info.readOnly = False; + xfi->fb_shm_info.shmaddr = shmat(xfi->fb_shm_info.shmid, 0, 0); + xfi->fb_image->data = xfi->fb_shm_info.shmaddr; + + if (xfi->fb_shm_info.shmaddr == ((char*) -1)) + { + printf("shmat failed\n"); + return; + } + + XShmAttach(xfi->display, &(xfi->fb_shm_info)); + XSync(xfi->display, False); + + shmctl(xfi->fb_shm_info.shmid, IPC_RMID, 0); + + xfi->fb_pixmap = XShmCreatePixmap(xfi->display, + xfi->root_window, xfi->fb_image->data, &(xfi->fb_shm_info), + xfi->fb_image->width, xfi->fb_image->height, xfi->fb_image->depth); +} + +xfInfo* xf_info_init() +{ + int i; + xfInfo* xfi; + int pf_count; + int vi_count; + XVisualInfo* vi; + XVisualInfo* vis; + XVisualInfo template; + XPixmapFormatValues* pf; + XPixmapFormatValues* pfs; + + xfi = xnew(xfInfo); + + //xfi->use_xshm = true; + xfi->display = XOpenDisplay(NULL); + + XInitThreads(); + + if (xfi->display == NULL) + { + printf("failed to open display: %s\n", XDisplayName(NULL)); + exit(1); + } + + xfi->xfds = ConnectionNumber(xfi->display); + xfi->number = DefaultScreen(xfi->display); + xfi->screen = ScreenOfDisplay(xfi->display, xfi->number); + xfi->depth = DefaultDepthOfScreen(xfi->screen); + xfi->width = WidthOfScreen(xfi->screen); + xfi->height = HeightOfScreen(xfi->screen); + xfi->root_window = DefaultRootWindow(xfi->display); + + pfs = XListPixmapFormats(xfi->display, &pf_count); + + if (pfs == NULL) + { + printf("XListPixmapFormats failed\n"); + exit(1); + } + + for (i = 0; i < pf_count; i++) + { + pf = pfs + i; + + if (pf->depth == xfi->depth) + { + xfi->bpp = pf->bits_per_pixel; + xfi->scanline_pad = pf->scanline_pad; + break; + } + } + XFree(pfs); + + memset(&template, 0, sizeof(template)); + template.class = TrueColor; + template.screen = xfi->number; + + vis = XGetVisualInfo(xfi->display, VisualClassMask | VisualScreenMask, &template, &vi_count); + + if (vis == NULL) + { + printf("XGetVisualInfo failed\n"); + exit(1); + } + + for (i = 0; i < vi_count; i++) + { + vi = vis + i; + + if (vi->depth == xfi->depth) + { + xfi->visual = vi->visual; + break; + } + } + XFree(vis); + + xfi->clrconv = freerdp_clrconv_new(CLRCONV_ALPHA | CLRCONV_INVERT); + + XSelectInput(xfi->display, xfi->root_window, SubstructureNotifyMask); + +#ifdef WITH_XDAMAGE + xf_xdamage_init(xfi); +#endif + + xf_xshm_init(xfi); + + xfi->bytesPerPixel = 4; + + freerdp_kbd_init(xfi->display, 0); + + return xfi; +} + +void xf_peer_context_new(freerdp_peer* client, xfPeerContext* context) +{ + context->info = xf_info_init(); + context->rfx_context = rfx_context_new(); + context->rfx_context->mode = RLGR3; + context->rfx_context->width = context->info->width; + context->rfx_context->height = context->info->height; + + rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_BGRA); + + context->s = stream_new(65536); +} + +void xf_peer_context_free(freerdp_peer* client, xfPeerContext* context) +{ + if (context) + { + stream_free(context->s); + rfx_context_free(context->rfx_context); + xfree(context); + } +} + +void xf_peer_init(freerdp_peer* client) +{ + xfInfo* xfi; + xfPeerContext* xfp; + + client->context_size = sizeof(xfPeerContext); + client->ContextNew = (psPeerContextNew) xf_peer_context_new; + client->ContextFree = (psPeerContextFree) xf_peer_context_free; + freerdp_peer_context_new(client); + + xfp = (xfPeerContext*) client->context; + + xfp->fps = 24; + xfp->thread = 0; + xfp->activations = 0; + xfp->event_queue = xf_event_queue_new(); + + xfi = xfp->info; + xfp->hdc = gdi_CreateDC(xfi->clrconv, xfi->bpp); + + pthread_mutex_init(&(xfp->mutex), NULL); +} + +STREAM* xf_peer_stream_init(xfPeerContext* context) +{ + stream_clear(context->s); + stream_set_pos(context->s, 0); + return context->s; +} + +void xf_peer_live_rfx(freerdp_peer* client) +{ + xfPeerContext* xfp = (xfPeerContext*) client->context; + + if (xfp->activations == 1) + pthread_create(&(xfp->thread), 0, xf_monitor_updates, (void*) client); +} + +static boolean xf_peer_sleep_tsdiff(uint32 *old_sec, uint32 *old_usec, uint32 new_sec, uint32 new_usec) +{ + sint32 sec, usec; + + if (*old_sec == 0 && *old_usec == 0) + { + *old_sec = new_sec; + *old_usec = new_usec; + return true; + } + + sec = new_sec - *old_sec; + usec = new_usec - *old_usec; + + if (sec < 0 || (sec == 0 && usec < 0)) + { + printf("Invalid time stamp detected.\n"); + return false; + } + + *old_sec = new_sec; + *old_usec = new_usec; + + while (usec < 0) + { + usec += 1000000; + sec--; + } + + if (sec > 0) + freerdp_sleep(sec); + + if (usec > 0) + freerdp_usleep(usec); + + return true; +} + +void xf_peer_dump_rfx(freerdp_peer* client) +{ + STREAM* s; + uint32 prev_seconds; + uint32 prev_useconds; + rdpUpdate* update; + rdpPcap* pcap_rfx; + pcap_record record; + + s = stream_new(512); + update = client->update; + client->update->pcap_rfx = pcap_open(xf_pcap_file, false); + pcap_rfx = client->update->pcap_rfx; + + if (pcap_rfx == NULL) + return; + + prev_seconds = prev_useconds = 0; + + while (pcap_has_next_record(pcap_rfx)) + { + pcap_get_next_record_header(pcap_rfx, &record); + + s->data = xrealloc(s->data, record.length); + record.data = s->data; + s->size = record.length; + + pcap_get_next_record_content(pcap_rfx, &record); + s->p = s->data + s->size; + + if (xf_pcap_dump_realtime && xf_peer_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, record.header.ts_usec) == false) + break; + + update->SurfaceCommand(update->context, s); + } +} + +void xf_peer_rfx_update(freerdp_peer* client, int x, int y, int width, int height) +{ + STREAM* s; + uint8* data; + xfInfo* xfi; + RFX_RECT rect; + XImage* image; + rdpUpdate* update; + xfPeerContext* xfp; + SURFACE_BITS_COMMAND* cmd; + + update = client->update; + xfp = (xfPeerContext*) client->context; + cmd = &update->surface_bits_command; + xfi = xfp->info; + + if (width * height <= 0) + return; + + s = xf_peer_stream_init(xfp); + + if (xfi->use_xshm) + { + width = x + width; + height = y + height; + x = 0; + y = 0; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + image = xf_snapshot(xfp, x, y, width, height); + + data = (uint8*) image->data; + data = &data[(y * image->bytes_per_line) + (x * image->bits_per_pixel)]; + + rfx_compose_message(xfp->rfx_context, s, &rect, 1, data, + width, height, image->bytes_per_line); + + cmd->destLeft = x; + cmd->destTop = y; + cmd->destRight = x + width; + cmd->destBottom = y + height; + } + else + { + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + + image = xf_snapshot(xfp, x, y, width, height); + + rfx_compose_message(xfp->rfx_context, s, &rect, 1, + (uint8*) image->data, width, height, width * xfi->bytesPerPixel); + + cmd->destLeft = x; + cmd->destTop = y; + cmd->destRight = x + width; + cmd->destBottom = y + height; + + XDestroyImage(image); + } + + cmd->bpp = 32; + cmd->codecID = client->settings->rfx_codec_id; + cmd->width = width; + cmd->height = height; + cmd->bitmapDataLength = stream_get_length(s); + cmd->bitmapData = stream_get_head(s); + + update->SurfaceBits(update->context, cmd); +} + +boolean xf_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount) +{ + xfPeerContext* xfp = (xfPeerContext*) client->context; + + if (xfp->event_queue->pipe_fd[0] == -1) + return true; + + rfds[*rcount] = (void *)(long) xfp->event_queue->pipe_fd[0]; + (*rcount)++; + + return true; +} + +boolean xf_peer_check_fds(freerdp_peer* client) +{ + xfInfo* xfi; + xfEvent* event; + xfPeerContext* xfp; + HGDI_RGN invalid_region; + + xfp = (xfPeerContext*) client->context; + xfi = xfp->info; + + if (xfp->activated == false) + return true; + + event = xf_event_peek(xfp->event_queue); + + if (event != NULL) + { + if (event->type == XF_EVENT_TYPE_REGION) + { + xfEventRegion* region = (xfEventRegion*) xf_event_pop(xfp->event_queue); + gdi_InvalidateRegion(xfp->hdc, region->x, region->y, region->width, region->height); + xf_event_region_free(region); + } + else if (event->type == XF_EVENT_TYPE_FRAME_TICK) + { + event = xf_event_pop(xfp->event_queue); + invalid_region = xfp->hdc->hwnd->invalid; + + if (invalid_region->null == false) + { + xf_peer_rfx_update(client, invalid_region->x, invalid_region->y, + invalid_region->w, invalid_region->h); + } + + invalid_region->null = 1; + xfp->hdc->hwnd->ninvalid = 0; + + xf_event_free(event); + } + } + + return true; +} + +boolean xf_peer_capabilities(freerdp_peer* client) +{ + return true; +} + +boolean xf_peer_post_connect(freerdp_peer* client) +{ + xfInfo* xfi; + xfPeerContext* xfp; + + xfp = (xfPeerContext*) client->context; + xfi = (xfInfo*) xfp->info; + + /** + * This callback is called when the entire connection sequence is done, i.e. we've received the + * Font List PDU from the client and sent out the Font Map PDU. + * The server may start sending graphics output and receiving keyboard/mouse input after this + * callback returns. + */ + printf("Client %s is activated", client->hostname); + if (client->settings->autologon) + { + printf(" and wants to login automatically as %s\\%s", + client->settings->domain ? client->settings->domain : "", + client->settings->username); + + /* A real server may perform OS login here if NLA is not executed previously. */ + } + printf("\n"); + + printf("Client requested desktop: %dx%dx%d\n", + client->settings->width, client->settings->height, client->settings->color_depth); + + /* A real server should tag the peer as activated here and start sending updates in mainloop. */ + + client->settings->width = xfi->width; + client->settings->height = xfi->height; + + client->update->DesktopResize(client->update->context); + xfp->activated = false; + + /* Return false here would stop the execution of the peer mainloop. */ + return true; +} + +boolean xf_peer_activate(freerdp_peer* client) +{ + xfPeerContext* xfp = (xfPeerContext*) client->context; + + rfx_context_reset(xfp->rfx_context); + xfp->activated = true; + + if (xf_pcap_file != NULL) + { + client->update->dump_rfx = true; + xf_peer_dump_rfx(client); + } + else + { + xf_peer_live_rfx(client); + xfp->activations++; + } + + return true; +} + +void* xf_peer_main_loop(void* arg) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + rdpSettings* settings; + char* server_file_path; + freerdp_peer* client = (freerdp_peer*) arg; + + memset(rfds, 0, sizeof(rfds)); + + printf("We've got a client %s\n", client->hostname); + + xf_peer_init(client); + settings = client->settings; + + /* Initialize the real server settings here */ + + if (settings->development_mode) + { + server_file_path = freerdp_construct_path(settings->development_path, "server/X11"); + } + else + { + server_file_path = freerdp_construct_path(settings->config_path, "server"); + + if (!freerdp_check_file_exists(server_file_path)) + freerdp_mkdir(server_file_path); + } + + settings->cert_file = freerdp_construct_path(server_file_path, "server.crt"); + settings->privatekey_file = freerdp_construct_path(server_file_path, "server.key"); + + settings->nla_security = false; + settings->rfx_codec = true; + + client->Capabilities = xf_peer_capabilities; + client->PostConnect = xf_peer_post_connect; + client->Activate = xf_peer_activate; + + xf_input_register_callbacks(client->input); + + client->Initialize(client); + + while (1) + { + rcount = 0; + + if (client->GetFileDescriptor(client, rfds, &rcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + if (xf_peer_get_fds(client, rfds, &rcount) != true) + { + printf("Failed to get xfreerdp file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("select failed\n"); + break; + } + } + + if (client->CheckFileDescriptor(client) != true) + { + printf("Failed to check freerdp file descriptor\n"); + break; + } + if ((xf_peer_check_fds(client)) != true) + { + printf("Failed to check xfreerdp file descriptor\n"); + break; + } + } + + printf("Client %s disconnected.\n", client->hostname); + + client->Disconnect(client); + freerdp_peer_context_free(client); + freerdp_peer_free(client); + + return NULL; +} + +void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +{ + pthread_t th; + + pthread_create(&th, 0, xf_peer_main_loop, client); + pthread_detach(th); +} diff --git a/server/X11/xf_peer.h b/server/X11/xf_peer.h new file mode 100644 index 0000000..6e15cdb --- /dev/null +++ b/server/X11/xf_peer.h @@ -0,0 +1,54 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * X11 Peer + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XF_PEER_H +#define __XF_PEER_H + +#include +#include +#include +#include +#include +#include +#include + +typedef struct xf_peer_context xfPeerContext; + +#include "xfreerdp.h" + +struct xf_peer_context +{ + rdpContext _p; + + int fps; + STREAM* s; + HGDI_DC hdc; + xfInfo* info; + int activations; + pthread_t thread; + boolean activated; + pthread_mutex_t mutex; + RFX_CONTEXT* rfx_context; + xfEventQueue* event_queue; + pthread_t frame_rate_thread; +}; + +void xf_peer_accepted(freerdp_listener* instance, freerdp_peer* client); + +#endif /* __XF_PEER_H */ diff --git a/server/X11/xfreerdp.c b/server/X11/xfreerdp.c new file mode 100644 index 0000000..b8dd6a0 --- /dev/null +++ b/server/X11/xfreerdp.c @@ -0,0 +1,124 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP X11 Server + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xf_peer.h" +#include "xfreerdp.h" + +char* xf_pcap_file = NULL; +boolean xf_pcap_dump_realtime = true; + +void xf_server_main_loop(freerdp_listener* instance) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + + memset(rfds, 0, sizeof(rfds)); + + while (1) + { + rcount = 0; + + if (instance->GetFileDescriptor(instance, rfds, &rcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("select failed\n"); + break; + } + } + + if (instance->CheckFileDescriptor(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + } + + instance->Close(instance); +} + +int main(int argc, char* argv[]) +{ + freerdp_listener* instance; + + /* ignore SIGPIPE, otherwise an SSL_write failure could crash the server */ + signal(SIGPIPE, SIG_IGN); + + instance = freerdp_listener_new(); + instance->PeerAccepted = xf_peer_accepted; + + if (argc > 1) + xf_pcap_file = argv[1]; + + if (argc > 2 && !strcmp(argv[2], "--fast")) + xf_pcap_dump_realtime = false; + + /* Open the server socket and start listening. */ + if (instance->Open(instance, NULL, 3389)) + { + /* Entering the server main loop. In a real server the listener can be run in its own thread. */ + xf_server_main_loop(instance); + } + + freerdp_listener_free(instance); + + return 0; +} + diff --git a/server/X11/xfreerdp.h b/server/X11/xfreerdp.h new file mode 100644 index 0000000..3609923 --- /dev/null +++ b/server/X11/xfreerdp.h @@ -0,0 +1,75 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP X11 Server + * + * Copyright 2011 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __XFREERDP_H +#define __XFREERDP_H + +#include + +#ifdef WITH_XSHM +#include +#endif + +#ifdef WITH_XFIXES +#include +#endif + +#ifdef WITH_XTEST +#include +#endif + +#ifdef WITH_XDAMAGE +#include +#endif + +typedef struct xf_info xfInfo; + +#include "xf_event.h" + +struct xf_info +{ + int bpp; + int xfds; + int depth; + int width; + int height; + int number; + XImage* image; + Screen* screen; + Visual* visual; + Display* display; + int scanline_pad; + int bytesPerPixel; + HCLRCONV clrconv; + boolean use_xshm; + + XImage* fb_image; + Pixmap fb_pixmap; + Window root_window; + XShmSegmentInfo fb_shm_info; + +#ifdef WITH_XDAMAGE + GC xdamage_gc; + Damage xdamage; + int xdamage_notify_event; + XserverRegion xdamage_region; +#endif +}; + +#endif /* __XFREERDP_H */ diff --git a/server/test/CMakeLists.txt b/server/test/CMakeLists.txt new file mode 100644 index 0000000..eb93023 --- /dev/null +++ b/server/test/CMakeLists.txt @@ -0,0 +1,26 @@ +# FreeRDP: A Remote Desktop Protocol Client +# FreeRDP Test Server cmake build script +# +# Copyright 2011 O.S. Systems Software Ltda. +# Copyright 2011 Otavio Salvador +# Copyright 2011 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +add_executable(tfreerdp-server + tfreerdp.c) + +target_link_libraries(tfreerdp-server freerdp-core) +target_link_libraries(tfreerdp-server freerdp-utils) +target_link_libraries(tfreerdp-server freerdp-codec) +target_link_libraries(tfreerdp-server freerdp-channels) diff --git a/server/test/rfx_test.pcap b/server/test/rfx_test.pcap new file mode 100644 index 0000000000000000000000000000000000000000..768c3960fb5cd1408eb3d2d6eb9afe4bcbf9558e GIT binary patch literal 994948 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

    sh#MaU@ky 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 z

    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�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�H-?6OCxAS?GXfg7x{t&VqW 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 g)b7B~J&xwdWiQYcDhu$|7J(0sc& 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�XNevTWm%F*#{kzBLY}f}`=L4O` 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

    K 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 O-)n>TujPM7PW=xmQ@u?9 literal 0 HcmV?d00001 diff --git a/server/test/server.crt b/server/test/server.crt new file mode 100644 index 0000000..7ce931c --- /dev/null +++ b/server/test/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyzCCAbOgAwIBAgIJANbqtAWwlQZuMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV +BAMTB0ZyZWVSRFAwHhcNMDkxMDI5MDA0MTQ5WhcNMDkxMTI4MDA0MTQ5WjASMRAw +DgYDVQQDEwdGcmVlUkRQMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +q7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1TptzXTcmfDrDslTGwcEY +hTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2SXvTiaV26VPPxddGb +o6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJLd2SU4ItWHj8zjz1f +eGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsjgvz4yP7I3TL8+GsN +MjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdymrulJSIhoOVfKkwi +ptTe43FgwxVRIygJP9HjHQIDAQABoyQwIjATBgNVHSUEDDAKBggrBgEFBQcDATAL +BgNVHQ8EBAMCBDAwDQYJKoZIhvcNAQEFBQADggEBAIOdEDhOX2kbl02znltd9hCr +nV4kRPKm979RKwBNkrEuwYSlcsjAHg5MZ5itH3wFOUo2s5pjt7/vMOAg+6rOBbIa +nqr22/gKBtOmuaJLG1yjxDC2vfez7f3B26pKgxa/krM8oxiFdT9n8QbdxdkN7/D9 +3RLU/aCfgrMzXxRus7eq3kR00jnSs6ggnAfE1E9gric3vFgr1wCzdcriRXmXDfUb +hRq+4VG+ZWk16TwCofV5GVU39XWCv5HNO2swAdjkNXgI5e3tQbV3wWLZLqqYzBco +iWulAXtoCGmE81+u1Ms7hLLzpXitLZSGPu1r+sDdkKPLCmOvkAaljDQ4nBz7fIA= +-----END CERTIFICATE----- diff --git a/server/test/server.key b/server/test/server.key new file mode 100644 index 0000000..5c2f2c8 --- /dev/null +++ b/server/test/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAq7mxFgRbS2FYJZX7BzpNd4T/n4nEVDBY6YaObLjGpaB1Tptz +XTcmfDrDslTGwcEYhTFAC4ZvY6yOURExqbph4LSgvkoa6J722RjVPfshGa4mlh2S +XvTiaV26VPPxddGbo6fbs2u029lbtBlpIVbhx5RN9vstNkll26oSZ6wfEdBNHQJL +d2SU4ItWHj8zjz1feGxjgChHihUlwcBYKDJsKFkzHZmLrMgB37KsGlXi/WV+eEsj +gvz4yP7I3TL8+GsNMjV8fRGVEKTbKSmgunO67d5u+IaqUQb0Ad1ha1jzDQ+a6hdy +mrulJSIhoOVfKkwiptTe43FgwxVRIygJP9HjHQIDAQABAoIBAAVv5K54xtc1JtBR +1lfdPbSqDlnjx8aOnVIPg5TnqMp3sR8jBt0NsPc/+RA9ZOmfjoIxFAEJaZ9zSDJC +5BqmnxC5R1mfCQkSd2haQ+4pdFvWyrv4Bblh8YU6hXrJGn0LfO0KlIcywtAvKpsi +LtTyZkWmaW2HeF/+pO32jYygw38R1wd8Tl6GwjOXwTF6lFACJXOT4YAzcfp3FKSB +AiKBIGuMzozoSND7KPFNRrhGhNumJpdS5A8Fb8D2c/ZMv6Cq5IbwOgTfKun+Bz+s +mFbnzeb1uWRqQbsVXOBBW/zHfuG3SU5qeZsaAyuu4DTy+LE1oAHF9uhBSHuT5C6i +vCJ8A8ECgYEA1iaOmiEJYBrs25iAc4SjCKqhY0mwR3wtu3I06vmgUoML5fhPMv36 +SvYQIqDyNw3p7TE6mZtw9+G+kK3PqhuJhogwSwg0a6o51RdKnhXH3/68oNWtKCLC +1AmR8q/Gd3FwAR3b49CuOIZ9uOiJrc/ejzKdFEJTDR1/TX1frWfZznECgYEAzUiz +XxFf7YrGel7JgmfRD2eZRYngOoteFlg5Tee42UjeAY2Pt2aiDLk+2TqQEdI9+Xg7 +LcFdBqcSNd8bh33xSzgNthIkX+lTDzx0SmKGfyxfFBJcY8nzsLvvnNt3YeuMeaJQ +CPszwoZ0jcD46jTCjbrKhaLyEWmUkDp1O71NTW0CgYAXKF49Xpsz8FVyvcAOPeaf +dkwzf3F3mX8ciRId4taqdY9g1AREgGCDoK5IAF2RBIkqZCtxFvUVaS0BWjpdq9Ko +YKvQQVfh2KueVoF0LOjLWTGutsydzXyCD3Lf6pAstHCnPkJcFWHxrOGFkGfrCtKH +a7K+0RlIDsuIZqllCBjukQKBgA31+MTpYJW+D1t5IMkumEgs6n6RLt+sZLyuSU9k +B+03CGogn3qAj1rAKmcJlYywuKhDpfqpoNL3/8QMJUokpYlRCZWtTC39pzltCheY +9b6mXNz3lrLupBUL4vLO9iKBq28GO90wgEelbz3ItuTuq6CJ6IYIG+BVRtY8M4bZ +i+1NAoGANXZjYnJYDnh8Je9SDxDSc5byzK7ddkQoId64RCIfNHqNKH63P81vjgnH +YBIPtagY75ZVVNxujCF7m8Rety+d8tEFwfQKDin2EVI7PD2rOJra385/izp7HuBR +vqxvLzG9Xv3cNOU2l7PttVw4Pa2i5E37atKi3V3Zp2kMW+KaKPQ= +-----END RSA PRIVATE KEY----- diff --git a/server/test/test_icon.ppm b/server/test/test_icon.ppm new file mode 100644 index 0000000..bcc4a0e --- /dev/null +++ b/server/test/test_icon.ppm @@ -0,0 +1,5572 @@ +P3 +# CREATOR: GIMP PNM Filter Version 1.1 +29 64 +255 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +159 +159 +160 +135 +154 +160 +85 +141 +160 +82 +141 +160 +159 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +112 +148 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +155 +158 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +114 +148 +160 +74 +139 +160 +74 +139 +160 +75 +140 +161 +91 +143 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +136 +154 +160 +76 +140 +160 +74 +139 +160 +74 +139 +160 +75 +140 +161 +137 +154 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +152 +158 +160 +79 +141 +160 +75 +140 +161 +74 +139 +160 +74 +139 +160 +83 +141 +160 +159 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +90 +143 +160 +75 +140 +161 +74 +139 +160 +75 +140 +161 +75 +140 +161 +105 +147 +160 +159 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +125 +151 +160 +74 +139 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +74 +139 +160 +111 +154 +167 +158 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +154 +158 +160 +88 +143 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +138 +160 +99 +170 +189 +134 +171 +180 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +126 +151 +160 +74 +139 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +73 +137 +158 +63 +124 +147 +108 +181 +198 +152 +163 +165 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +80 +141 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +73 +138 +159 +21 +72 +99 +78 +143 +164 +126 +180 +192 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +129 +152 +160 +74 +139 +160 +75 +140 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +73 +138 +159 +25 +77 +104 +12 +60 +88 +105 +176 +194 +145 +167 +172 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +98 +145 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +27 +80 +106 +6 +53 +82 +57 +117 +140 +121 +182 +195 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +83 +141 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +76 +141 +162 +30 +83 +109 +6 +53 +82 +28 +81 +107 +108 +180 +197 +154 +162 +164 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +155 +158 +160 +80 +140 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +74 +139 +160 +74 +138 +159 +73 +138 +159 +75 +140 +161 +37 +92 +118 +2 +48 +78 +19 +69 +96 +100 +171 +189 +147 +165 +170 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +149 +157 +160 +79 +140 +160 +74 +139 +160 +74 +139 +160 +76 +142 +163 +82 +149 +169 +96 +165 +184 +106 +178 +196 +111 +185 +202 +114 +188 +205 +114 +188 +205 +97 +168 +186 +107 +179 +196 +150 +164 +168 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +146 +156 +160 +80 +141 +160 +74 +139 +160 +86 +154 +173 +102 +173 +191 +111 +184 +200 +111 +184 +201 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +111 +184 +201 +110 +183 +200 +113 +179 +195 +138 +170 +177 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +146 +156 +160 +77 +139 +159 +93 +162 +182 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +182 +199 +109 +182 +199 +110 +183 +200 +138 +169 +177 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +146 +156 +159 +99 +165 +182 +112 +185 +202 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +150 +165 +168 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +138 +168 +175 +110 +182 +199 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +182 +199 +107 +180 +197 +107 +168 +183 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +156 +161 +162 +117 +179 +194 +109 +182 +199 +109 +182 +199 +110 +183 +200 +109 +182 +199 +109 +182 +199 +109 +182 +199 +109 +182 +199 +109 +182 +199 +110 +183 +200 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +111 +185 +201 +83 +149 +168 +7 +52 +81 +101 +119 +130 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +144 +167 +172 +110 +183 +200 +110 +182 +199 +110 +183 +200 +109 +182 +199 +61 +125 +148 +47 +91 +116 +58 +95 +118 +43 +88 +112 +64 +128 +151 +108 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +112 +185 +202 +98 +168 +186 +125 +165 +175 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +126 +175 +187 +109 +182 +199 +110 +182 +199 +111 +184 +201 +55 +119 +143 +108 +136 +153 +230 +234 +237 +186 +198 +205 +234 +233 +221 +51 +89 +113 +68 +133 +155 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +109 +182 +199 +110 +183 +200 +123 +176 +188 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +114 +179 +195 +110 +183 +200 +110 +183 +200 +103 +175 +193 +66 +114 +136 +247 +248 +249 +240 +243 +244 +57 +95 +118 +22 +66 +93 +40 +80 +106 +64 +113 +135 +108 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +119 +177 +191 +156 +161 +162 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +110 +182 +199 +110 +183 +200 +110 +183 +200 +100 +172 +190 +106 +143 +161 +249 +250 +250 +251 +252 +252 +132 +155 +170 +51 +89 +113 +145 +165 +178 +79 +121 +142 +108 +181 +198 +110 +183 +200 +109 +182 +199 +110 +184 +200 +113 +187 +203 +103 +175 +193 +104 +177 +194 +117 +180 +195 +154 +162 +164 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +112 +180 +196 +110 +183 +200 +110 +183 +200 +107 +180 +197 +74 +124 +145 +250 +251 +251 +254 +254 +254 +250 +251 +251 +238 +241 +243 +220 +226 +230 +67 +122 +144 +109 +182 +199 +110 +183 +200 +110 +183 +200 +101 +171 +189 +38 +91 +116 +154 +176 +179 +94 +128 +141 +99 +165 +182 +153 +164 +166 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +120 +177 +190 +109 +182 +199 +110 +183 +200 +110 +184 +200 +81 +152 +172 +113 +144 +161 +242 +244 +245 +242 +244 +245 +235 +239 +241 +92 +129 +148 +87 +157 +177 +110 +183 +200 +110 +183 +200 +115 +189 +206 +37 +91 +116 +8 +55 +84 +0 +46 +77 +55 +117 +140 +118 +186 +201 +152 +163 +165 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +134 +171 +180 +109 +182 +199 +109 +181 +198 +109 +182 +199 +113 +187 +203 +88 +159 +179 +83 +140 +160 +105 +152 +169 +76 +134 +155 +88 +159 +179 +112 +185 +202 +109 +182 +199 +110 +183 +200 +110 +183 +200 +109 +182 +199 +81 +147 +167 +61 +122 +144 +113 +187 +204 +113 +179 +195 +153 +163 +165 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +152 +163 +166 +110 +183 +200 +109 +182 +199 +110 +183 +200 +109 +182 +199 +110 +183 +200 +109 +182 +199 +108 +180 +198 +109 +183 +200 +110 +183 +200 +109 +182 +199 +109 +182 +199 +110 +183 +200 +109 +182 +199 +110 +183 +200 +106 +178 +195 +74 +138 +159 +110 +183 +200 +117 +178 +192 +155 +162 +163 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +157 +161 +161 +121 +177 +190 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +95 +164 +183 +77 +142 +163 +110 +183 +200 +123 +175 +188 +158 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +139 +169 +176 +110 +182 +199 +110 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +70 +133 +154 +103 +173 +191 +109 +181 +198 +136 +171 +179 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +159 +160 +160 +115 +179 +194 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +108 +181 +198 +95 +164 +183 +110 +183 +200 +110 +182 +199 +156 +161 +162 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +149 +164 +168 +109 +182 +199 +109 +182 +199 +110 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +111 +183 +200 +109 +182 +199 +136 +170 +177 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +137 +169 +177 +110 +183 +200 +109 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +119 +178 +192 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +157 +161 +162 +120 +176 +189 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +181 +198 +148 +165 +169 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +143 +167 +172 +110 +181 +198 +109 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +181 +198 +109 +182 +199 +126 +175 +186 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +116 +180 +194 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +182 +199 +109 +182 +199 +153 +162 +164 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +132 +172 +181 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +124 +175 +187 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +138 +169 +176 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +115 +165 +178 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +134 +171 +180 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +184 +201 +96 +165 +184 +133 +152 +158 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +119 +177 +190 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +107 +179 +197 +90 +141 +158 +156 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +156 +161 +163 +111 +181 +197 +109 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +82 +149 +169 +127 +151 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +143 +167 +172 +111 +182 +199 +109 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +96 +166 +184 +77 +138 +160 +158 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +131 +172 +182 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +103 +174 +191 +77 +142 +163 +99 +145 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +157 +161 +162 +121 +176 +189 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +82 +149 +168 +74 +140 +160 +126 +152 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +154 +162 +164 +111 +180 +196 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +111 +184 +201 +91 +160 +178 +74 +139 +160 +82 +141 +160 +148 +157 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +145 +166 +171 +128 +173 +184 +122 +176 +189 +129 +174 +184 +160 +160 +160 +160 +160 +160 +160 +160 +160 +144 +166 +171 +109 +182 +199 +110 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +103 +174 +192 +74 +139 +160 +74 +140 +160 +94 +144 +160 +156 +159 +160 +160 +160 +160 +160 +160 +160 +152 +163 +165 +120 +177 +190 +109 +182 +199 +109 +182 +199 +109 +181 +198 +153 +163 +165 +160 +160 +160 +160 +160 +160 +160 +160 +160 +128 +173 +184 +110 +183 +200 +110 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +184 +201 +74 +139 +160 +75 +139 +160 +75 +140 +161 +95 +144 +160 +160 +160 +160 +158 +160 +161 +114 +180 +196 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +151 +164 +167 +160 +160 +160 +160 +160 +160 +160 +160 +160 +115 +179 +194 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +112 +185 +202 +77 +143 +163 +74 +139 +160 +75 +140 +160 +74 +139 +160 +104 +145 +159 +134 +169 +177 +110 +183 +200 +109 +181 +198 +110 +183 +200 +110 +182 +199 +109 +182 +199 +122 +176 +188 +160 +160 +160 +160 +160 +160 +160 +160 +160 +110 +183 +200 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +112 +185 +202 +79 +144 +165 +74 +139 +160 +75 +140 +161 +74 +139 +160 +74 +138 +160 +92 +155 +174 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +109 +181 +198 +110 +183 +200 +160 +160 +160 +160 +160 +160 +160 +160 +160 +110 +183 +200 +109 +181 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +112 +186 +202 +75 +141 +162 +74 +139 +160 +75 +140 +161 +75 +140 +160 +74 +139 +160 +74 +139 +160 +87 +154 +173 +111 +184 +201 +110 +183 +200 +110 +183 +200 +109 +181 +198 +110 +183 +200 +160 +160 +160 +160 +160 +160 +160 +160 +160 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +93 +162 +181 +110 +183 +200 +109 +182 +199 +109 +181 +198 +109 +182 +199 +160 +160 +160 +160 +160 +160 +160 +160 +160 +113 +181 +196 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +104 +176 +194 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +76 +141 +162 +103 +174 +192 +110 +182 +199 +110 +183 +200 +109 +182 +199 +160 +160 +160 +160 +160 +160 +160 +160 +160 +121 +176 +189 +109 +182 +199 +110 +183 +200 +109 +182 +199 +119 +187 +203 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +97 +167 +186 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +80 +145 +165 +111 +185 +202 +109 +182 +199 +143 +167 +173 +160 +160 +160 +160 +160 +160 +160 +160 +160 +133 +172 +181 +109 +182 +199 +110 +182 +199 +109 +182 +199 +140 +198 +211 +111 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +111 +184 +201 +87 +156 +175 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +138 +160 +117 +157 +169 +159 +161 +161 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +147 +165 +169 +110 +183 +200 +109 +182 +199 +110 +183 +200 +161 +208 +219 +113 +184 +201 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +105 +177 +194 +77 +142 +163 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +94 +144 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +154 +162 +164 +114 +181 +196 +109 +182 +199 +109 +182 +200 +181 +218 +227 +114 +185 +201 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +110 +183 +200 +95 +163 +183 +50 +106 +130 +75 +141 +162 +74 +139 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +81 +140 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +158 +160 +161 +125 +175 +187 +109 +182 +199 +108 +182 +199 +201 +228 +235 +116 +186 +202 +109 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +183 +200 +77 +141 +162 +36 +88 +115 +48 +104 +128 +69 +133 +154 +74 +139 +160 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +83 +141 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +139 +169 +176 +110 +182 +199 +107 +180 +197 +204 +230 +236 +137 +196 +210 +108 +182 +199 +110 +183 +200 +110 +183 +200 +110 +183 +200 +109 +182 +199 +110 +184 +200 +46 +101 +126 +38 +90 +116 +48 +103 +128 +61 +120 +143 +69 +133 +154 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +97 +145 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +158 +160 +161 +113 +181 +197 +107 +181 +198 +191 +223 +230 +176 +215 +225 +105 +180 +198 +110 +183 +200 +110 +183 +200 +110 +183 +200 +112 +185 +202 +81 +146 +166 +35 +87 +114 +57 +116 +139 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +127 +152 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +140 +169 +175 +107 +181 +199 +171 +212 +222 +218 +237 +241 +101 +178 +196 +110 +183 +200 +110 +183 +200 +110 +183 +200 +105 +177 +195 +42 +96 +122 +44 +98 +124 +71 +134 +156 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +75 +140 +161 +88 +143 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +120 +176 +189 +144 +200 +213 +251 +252 +252 +108 +182 +199 +109 +182 +199 +109 +182 +199 +109 +182 +199 +53 +110 +135 +37 +90 +116 +46 +101 +127 +72 +135 +157 +74 +139 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +161 +75 +140 +160 +74 +139 +160 +82 +141 +160 +146 +156 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +158 +159 +159 +146 +160 +164 +108 +179 +196 +248 +252 +253 +151 +203 +215 +107 +182 +199 +108 +181 +198 +69 +132 +153 +5 +52 +81 +5 +52 +81 +11 +59 +87 +45 +102 +126 +73 +138 +159 +75 +140 +160 +75 +140 +161 +75 +140 +161 +75 +140 +161 +74 +139 +160 +81 +140 +160 +142 +155 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +141 +147 +150 +70 +98 +115 +41 +77 +99 +41 +95 +119 +120 +157 +173 +157 +187 +198 +67 +131 +154 +46 +103 +127 +4 +50 +79 +6 +53 +82 +6 +54 +83 +6 +53 +82 +3 +50 +79 +28 +81 +108 +52 +111 +135 +61 +123 +145 +77 +132 +151 +94 +139 +154 +116 +146 +157 +154 +158 +159 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +155 +156 +157 +61 +91 +110 +19 +62 +89 +6 +53 +82 +6 +53 +82 +10 +55 +83 +19 +62 +89 +44 +81 +104 +47 +82 +103 +11 +56 +84 +6 +53 +82 +10 +56 +84 +28 +68 +93 +50 +83 +104 +71 +98 +115 +97 +116 +128 +126 +137 +144 +145 +152 +155 +150 +155 +157 +155 +157 +158 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 +160 diff --git a/server/test/tfreerdp.c b/server/test/tfreerdp.c new file mode 100644 index 0000000..3548360 --- /dev/null +++ b/server/test/tfreerdp.c @@ -0,0 +1,699 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * FreeRDP Test Server + * + * Copyright 2011 Marc-Andre Moreau + * Copyright 2011 Vic Lee + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char* test_pcap_file = NULL; +static boolean test_dump_rfx_realtime = true; + +/* HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3 */ +static const unsigned int test_quantization_values[] = +{ + 6, 6, 6, 6, 7, 7, 8, 8, 8, 9 +}; + +struct test_peer_context +{ + rdpContext _p; + + RFX_CONTEXT* rfx_context; + STREAM* s; + uint8* icon_data; + uint8* bg_data; + int icon_width; + int icon_height; + int icon_x; + int icon_y; + boolean activated; + WTSVirtualChannelManager* vcm; + void* debug_channel; + freerdp_thread* debug_channel_thread; +}; +typedef struct test_peer_context testPeerContext; + +void test_peer_context_new(freerdp_peer* client, testPeerContext* context) +{ + context->rfx_context = rfx_context_new(); + context->rfx_context->mode = RLGR3; + context->rfx_context->width = client->settings->width; + context->rfx_context->height = client->settings->height; + rfx_context_set_pixel_format(context->rfx_context, RFX_PIXEL_FORMAT_RGB); + + context->s = stream_new(65536); + + context->icon_x = -1; + context->icon_y = -1; + + context->vcm = WTSCreateVirtualChannelManager(client); +} + +void test_peer_context_free(freerdp_peer* client, testPeerContext* context) +{ + if (context) + { + if (context->debug_channel_thread) + { + freerdp_thread_stop(context->debug_channel_thread); + freerdp_thread_free(context->debug_channel_thread); + } + stream_free(context->s); + xfree(context->icon_data); + xfree(context->bg_data); + rfx_context_free(context->rfx_context); + if (context->debug_channel) + { + WTSVirtualChannelClose(context->debug_channel); + } + WTSDestroyVirtualChannelManager(context->vcm); + xfree(context); + } +} + +static void test_peer_init(freerdp_peer* client) +{ + client->context_size = sizeof(testPeerContext); + client->ContextNew = (psPeerContextNew) test_peer_context_new; + client->ContextFree = (psPeerContextFree) test_peer_context_free; + freerdp_peer_context_new(client); +} + +static STREAM* test_peer_stream_init(testPeerContext* context) +{ + stream_clear(context->s); + stream_set_pos(context->s, 0); + return context->s; +} + +static void test_peer_draw_background(freerdp_peer* client) +{ + testPeerContext* context = (testPeerContext*) client->context; + rdpUpdate* update = client->update; + SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; + STREAM* s; + RFX_RECT rect; + uint8* rgb_data; + int size; + + if (!client->settings->rfx_codec) + return; + + s = test_peer_stream_init(context); + + rect.x = 0; + rect.y = 0; + rect.width = client->settings->width; + rect.height = client->settings->height; + + size = rect.width * rect.height * 3; + rgb_data = xmalloc(size); + memset(rgb_data, 0xA0, size); + + rfx_compose_message(context->rfx_context, s, + &rect, 1, rgb_data, rect.width, rect.height, rect.width * 3); + + cmd->destLeft = 0; + cmd->destTop = 0; + cmd->destRight = rect.width; + cmd->destBottom = rect.height; + cmd->bpp = 32; + cmd->codecID = client->settings->rfx_codec_id; + cmd->width = rect.width; + cmd->height = rect.height; + cmd->bitmapDataLength = stream_get_length(s); + cmd->bitmapData = stream_get_head(s); + update->SurfaceBits(update->context, cmd); + + xfree(rgb_data); +} + +static void test_peer_load_icon(freerdp_peer* client) +{ + testPeerContext* context = (testPeerContext*) client->context; + FILE* fp; + int i; + char line[50]; + uint8* rgb_data; + int c; + + if (!client->settings->rfx_codec) + return; + + if ((fp = fopen("test_icon.ppm", "r")) == NULL) + return; + + /* P3 */ + fgets(line, sizeof(line), fp); + /* Creater comment */ + fgets(line, sizeof(line), fp); + /* width height */ + fgets(line, sizeof(line), fp); + sscanf(line, "%d %d", &context->icon_width, &context->icon_height); + /* Max */ + fgets(line, sizeof(line), fp); + + rgb_data = xmalloc(context->icon_width * context->icon_height * 3); + + for (i = 0; i < context->icon_width * context->icon_height * 3; i++) + { + if (fgets(line, sizeof(line), fp)) + { + sscanf(line, "%d", &c); + rgb_data[i] = (uint8)c; + } + } + + context->icon_data = rgb_data; + + /* background with same size, which will be used to erase the icon from old position */ + context->bg_data = xmalloc(context->icon_width * context->icon_height * 3); + memset(context->bg_data, 0xA0, context->icon_width * context->icon_height * 3); +} + +static void test_peer_draw_icon(freerdp_peer* client, int x, int y) +{ + testPeerContext* context = (testPeerContext*) client->context; + rdpUpdate* update = client->update; + SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command; + RFX_RECT rect; + STREAM* s; + + if (client->update->dump_rfx) + return; + if (!client->settings->rfx_codec || !context) + return; + if (context->icon_width < 1 || !context->activated) + return; + + rect.x = 0; + rect.y = 0; + rect.width = context->icon_width; + rect.height = context->icon_height; + + if (context->icon_x >= 0) + { + s = test_peer_stream_init(context); + rfx_compose_message(context->rfx_context, s, + &rect, 1, context->bg_data, rect.width, rect.height, rect.width * 3); + + cmd->destLeft = context->icon_x; + cmd->destTop = context->icon_y; + cmd->destRight = context->icon_x + context->icon_width; + cmd->destBottom = context->icon_y + context->icon_height; + cmd->bpp = 32; + cmd->codecID = client->settings->rfx_codec_id; + cmd->width = context->icon_width; + cmd->height = context->icon_height; + cmd->bitmapDataLength = stream_get_length(s); + cmd->bitmapData = stream_get_head(s); + update->SurfaceBits(update->context, cmd); + } + + s = test_peer_stream_init(context); + rfx_compose_message(context->rfx_context, s, + &rect, 1, context->icon_data, rect.width, rect.height, rect.width * 3); + + cmd->destLeft = x; + cmd->destTop = y; + cmd->destRight = x + context->icon_width; + cmd->destBottom = y + context->icon_height; + cmd->bpp = 32; + cmd->codecID = client->settings->rfx_codec_id; + cmd->width = context->icon_width; + cmd->height = context->icon_height; + cmd->bitmapDataLength = stream_get_length(s); + cmd->bitmapData = stream_get_head(s); + update->SurfaceBits(update->context, cmd); + + context->icon_x = x; + context->icon_y = y; +} + +static boolean test_sleep_tsdiff(uint32 *old_sec, uint32 *old_usec, uint32 new_sec, uint32 new_usec) +{ + sint32 sec, usec; + + if (*old_sec==0 && *old_usec==0) + { + *old_sec = new_sec; + *old_usec = new_usec; + return true; + } + + sec = new_sec - *old_sec; + usec = new_usec - *old_usec; + + if (sec<0 || (sec==0 && usec<0)) + { + printf("Invalid time stamp detected.\n"); + return false; + } + + *old_sec = new_sec; + *old_usec = new_usec; + + while (usec < 0) + { + usec += 1000000; + sec--; + } + + if (sec > 0) + freerdp_sleep(sec); + + if (usec > 0) + freerdp_usleep(usec); + + return true; +} + +void tf_peer_dump_rfx(freerdp_peer* client) +{ + STREAM* s; + uint32 prev_seconds; + uint32 prev_useconds; + rdpUpdate* update; + rdpPcap* pcap_rfx; + pcap_record record; + + s = stream_new(512); + update = client->update; + client->update->pcap_rfx = pcap_open(test_pcap_file, false); + pcap_rfx = client->update->pcap_rfx; + + if (pcap_rfx == NULL) + return; + + prev_seconds = prev_useconds = 0; + + while (pcap_has_next_record(pcap_rfx)) + { + pcap_get_next_record_header(pcap_rfx, &record); + + s->data = xrealloc(s->data, record.length); + record.data = s->data; + s->size = record.length; + + pcap_get_next_record_content(pcap_rfx, &record); + s->p = s->data + s->size; + + if (test_dump_rfx_realtime && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, record.header.ts_usec) == false) + break; + + update->SurfaceCommand(update->context, s); + } +} + +static void* tf_debug_channel_thread_func(void* arg) +{ + void* fd; + STREAM* s; + void* buffer; + uint32 bytes_returned = 0; + testPeerContext* context = (testPeerContext*) arg; + freerdp_thread* thread = context->debug_channel_thread; + + if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &bytes_returned) == true) + { + fd = *((void**)buffer); + WTSFreeMemory(buffer); + thread->signals[thread->num_signals++] = wait_obj_new_with_fd(fd); + } + + s = stream_new(4096); + + WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test1", 5, NULL); + + while (1) + { + freerdp_thread_wait(thread); + if (freerdp_thread_is_stopped(thread)) + break; + + stream_set_pos(s, 0); + if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), + stream_get_size(s), &bytes_returned) == false) + { + if (bytes_returned == 0) + break; + stream_check_size(s, bytes_returned); + if (WTSVirtualChannelRead(context->debug_channel, 0, stream_get_head(s), + stream_get_size(s), &bytes_returned) == false) + { + /* should not happen */ + break; + } + } + stream_set_pos(s, bytes_returned); + + printf("got %d bytes\n", bytes_returned); + } + + stream_free(s); + freerdp_thread_quit(thread); + + return 0; +} + +boolean tf_peer_post_connect(freerdp_peer* client) +{ + int i; + testPeerContext* context = (testPeerContext*) client->context; + + /** + * This callback is called when the entire connection sequence is done, i.e. we've received the + * Font List PDU from the client and sent out the Font Map PDU. + * The server may start sending graphics output and receiving keyboard/mouse input after this + * callback returns. + */ + printf("Client %s is activated (osMajorType %d osMinorType %d)", client->hostname, + client->settings->os_major_type, client->settings->os_minor_type); + if (client->settings->autologon) + { + printf(" and wants to login automatically as %s\\%s", + client->settings->domain ? client->settings->domain : "", + client->settings->username); + + /* A real server may perform OS login here if NLA is not executed previously. */ + } + printf("\n"); + + printf("Client requested desktop: %dx%dx%d\n", + client->settings->width, client->settings->height, client->settings->color_depth); + + /* A real server should tag the peer as activated here and start sending updates in mainloop. */ + test_peer_load_icon(client); + + /* Iterate all channel names requested by the client and activate those supported by the server */ + for (i = 0; i < client->settings->num_channels; i++) + { + if (client->settings->channels[i].joined) + { + if (strncmp(client->settings->channels[i].name, "rdpdbg", 6) == 0) + { + context->debug_channel = WTSVirtualChannelOpenEx(context->vcm, "rdpdbg", 0); + if (context->debug_channel != NULL) + { + printf("Open channel rdpdbg.\n"); + context->debug_channel_thread = freerdp_thread_new(); + freerdp_thread_start(context->debug_channel_thread, + tf_debug_channel_thread_func, context); + } + } + } + } + + /* Return false here would stop the execution of the peer mainloop. */ + return true; +} + +boolean tf_peer_activate(freerdp_peer* client) +{ + testPeerContext* context = (testPeerContext*) client->context; + + rfx_context_reset(context->rfx_context); + context->activated = true; + + if (test_pcap_file != NULL) + { + client->update->dump_rfx = true; + tf_peer_dump_rfx(client); + } + else + { + test_peer_draw_background(client); + } + + return true; +} + +void tf_peer_synchronize_event(rdpInput* input, uint32 flags) +{ + printf("Client sent a synchronize event (flags:0x%X)\n", flags); +} + +void tf_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + freerdp_peer* client = input->context->peer; + rdpUpdate* update = client->update; + testPeerContext* context = (testPeerContext*) input->context; + + printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code); + + if ((flags & 0x4000) && code == 0x1F) /* 's' key */ + { + if (client->settings->width != 800) + { + client->settings->width = 800; + client->settings->height = 600; + } + else + { + client->settings->width = 640; + client->settings->height = 480; + } + update->DesktopResize(update->context); + context->activated = false; + } + else if ((flags & 0x4000) && code == 0x2E) /* 'c' key */ + { + if (context->debug_channel) + { + WTSVirtualChannelWrite(context->debug_channel, (uint8*) "test2", 5, NULL); + } + } +} + +void tf_peer_unicode_keyboard_event(rdpInput* input, uint16 flags, uint16 code) +{ + printf("Client sent a unicode keyboard event (flags:0x%X code:0x%X)\n", flags, code); +} + +void tf_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y); + + test_peer_draw_icon(input->context->peer, x + 10, y); +} + +void tf_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y) +{ + printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y); +} + +static void* test_peer_mainloop(void* arg) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + testPeerContext* context; + freerdp_peer* client = (freerdp_peer*) arg; + + memset(rfds, 0, sizeof(rfds)); + + test_peer_init(client); + + /* Initialize the real server settings here */ + client->settings->cert_file = xstrdup("server.crt"); + client->settings->privatekey_file = xstrdup("server.key"); + client->settings->nla_security = false; + client->settings->rfx_codec = true; + + client->PostConnect = tf_peer_post_connect; + client->Activate = tf_peer_activate; + + client->input->SynchronizeEvent = tf_peer_synchronize_event; + client->input->KeyboardEvent = tf_peer_keyboard_event; + client->input->UnicodeKeyboardEvent = tf_peer_unicode_keyboard_event; + client->input->MouseEvent = tf_peer_mouse_event; + client->input->ExtendedMouseEvent = tf_peer_extended_mouse_event; + + client->Initialize(client); + context = (testPeerContext*) client->context; + + printf("We've got a client %s\n", client->hostname); + + while (1) + { + rcount = 0; + + if (client->GetFileDescriptor(client, rfds, &rcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + WTSVirtualChannelManagerGetFileDescriptor(context->vcm, rfds, &rcount); + + max_fds = 0; + FD_ZERO(&rfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("select failed\n"); + break; + } + } + + if (client->CheckFileDescriptor(client) != true) + break; + if (WTSVirtualChannelManagerCheckFileDescriptor(context->vcm) != true) + break; + } + + printf("Client %s disconnected.\n", client->hostname); + + client->Disconnect(client); + freerdp_peer_context_free(client); + freerdp_peer_free(client); + + return NULL; +} + +static void test_peer_accepted(freerdp_listener* instance, freerdp_peer* client) +{ + pthread_t th; + + pthread_create(&th, 0, test_peer_mainloop, client); + pthread_detach(th); +} + +static void test_server_mainloop(freerdp_listener* instance) +{ + int i; + int fds; + int max_fds; + int rcount; + void* rfds[32]; + fd_set rfds_set; + + memset(rfds, 0, sizeof(rfds)); + + while (1) + { + rcount = 0; + + if (instance->GetFileDescriptor(instance, rfds, &rcount) != true) + { + printf("Failed to get FreeRDP file descriptor\n"); + break; + } + + max_fds = 0; + FD_ZERO(&rfds_set); + + for (i = 0; i < rcount; i++) + { + fds = (int)(long)(rfds[i]); + + if (fds > max_fds) + max_fds = fds; + + FD_SET(fds, &rfds_set); + } + + if (max_fds == 0) + break; + + if (select(max_fds + 1, &rfds_set, NULL, NULL, NULL) == -1) + { + /* these are not really errors */ + if (!((errno == EAGAIN) || + (errno == EWOULDBLOCK) || + (errno == EINPROGRESS) || + (errno == EINTR))) /* signal occurred */ + { + printf("select failed\n"); + break; + } + } + + if (instance->CheckFileDescriptor(instance) != true) + { + printf("Failed to check FreeRDP file descriptor\n"); + break; + } + } + + instance->Close(instance); +} + +int main(int argc, char* argv[]) +{ + freerdp_listener* instance; + + /* Ignore SIGPIPE, otherwise an SSL_write failure could crash your server */ + signal(SIGPIPE, SIG_IGN); + + instance = freerdp_listener_new(); + + instance->PeerAccepted = test_peer_accepted; + + if (argc > 1) + test_pcap_file = argv[1]; + + if (argc > 2 && !strcmp(argv[2], "--fast")) + test_dump_rfx_realtime = false; + + /* Open the server socket and start listening. */ + if (instance->Open(instance, NULL, 3389)) + { + /* Entering the server main loop. In a real server the listener can be run in its own thread. */ + test_server_mainloop(instance); + } + + freerdp_listener_free(instance); + + return 0; +} + -- 1.7.10.4